/* QA & Test Automation, built from Web & App Development v2 (page-web-development-v2.css): its shell, header strip, hero
   base, buttons, email form, reveal, hover icons, client wall and responsive rules are carried over unchanged. Header and
   footer are the site's own (page-seo-1/2.css, site-header.css, site-footer.css); everything here scopes to .v9 or
   body.v9-page. Page-specific rules (qa-*) follow the shared ones. Built one section at a time, the hero first */

@font-face{font-family:'Sailec';src:url('assets/fonts/type_dynamic_-_sailec-webfont.woff2') format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Sailec';src:url('assets/fonts/type_dynamic_-_sailec_medium-webfont.woff2') format('woff2');font-weight:500;font-display:swap}
@font-face{font-family:'Sailec';src:url('assets/fonts/type_dynamic_-_sailec_bold-webfont.woff2') format('woff2');font-weight:700;font-display:swap}

/* ---------- page shell: white header strip, then the page ---------- */
body.v9-page .top-wrap{background-color:#fff;background-image:none}
body.v9-page .top-wrap-inner{background:none;min-height:0;padding-bottom:0}
body.v9-page .top-wrap::after,body.v9-page .top-wrap::before{display:none}
body.v9-page .content-area{padding:0}
body.v9-page .logo-white{display:none}
body.v9-page .logo-dark{display:block}
body.v9-page .menu_trigger{color:#232834}
body.v9-page .slicknav_icon-bar{background-color:#232834}
body.v9-page .header-wide{margin-bottom:0;padding-bottom:0}
body.v9-page .header{margin-bottom:0;padding-top:14px;padding-bottom:14px}
/* the site's menu button is 33px wide: its tap area is widened to 44px towards the page, with nothing moving */
body.v9-page .menu_trigger::after{content:"";position:absolute;top:-3px;bottom:-3px;left:-11px;right:0}
/* header, right side, as the reference reads: a quiet help link, then the icons (the menu's search and the menu), then the
   call button last, at the edge. The logo side is the site's own, set smaller. The row runs the full width of the window,
   and is a flex line centred on the logo; the menu's injected search button (.wbm_search) and the menu button drop their
   float offsets here. The link goes under 700px and the button under 521px, where the hero's form sits just below */
body.v9-page .header .logo{width:118px;max-width:none}
@media (max-width:765px){body.v9-page .header .logo{width:108px}}
body.v9-page .header{display:flex;align-items:center;max-width:none}
@media (min-width:1025px){body.v9-page .header{padding-left:40px!important;padding-right:40px!important}}
@media (min-width:1280px){body.v9-page .header{padding-left:56px!important;padding-right:56px!important}}
body.v9-page .header::after,body.v9-page .header-right::after{display:none}
body.v9-page .header-right{float:none;display:flex;align-items:center;gap:6px;margin-left:auto;padding:0}
body.v9-page .hp-hd{order:1;display:flex;align-items:center;gap:14px;margin-right:14px}
body.v9-page .hp-hd-sep{display:block;width:1px;height:14px;background:#C2C5CC}
body.v9-page .hp-hd-l{display:inline-flex;align-items:center;min-height:44px;font-family:'Sailec',sans-serif;font-weight:500;font-size:13.5px;line-height:1.2;color:#4f5565;text-decoration:underline;text-decoration-color:#C2C5CC;text-decoration-thickness:1px;text-underline-offset:4px;transition:color .2s cubic-bezier(.65,0,.35,1),text-decoration-color .2s cubic-bezier(.65,0,.35,1)}
body.v9-page .hp-hd-l:hover,body.v9-page .hp-hd-l:focus-visible{color:#232834;text-decoration-color:#232834}
/* the menu's injected search is not shown in this header: search stays inside the menu itself */
body.v9-page .header .wbm_search{display:none}
body.v9-page .wbm_search{order:2;float:none;width:44px;height:44px;margin:0;color:#4f5565;transition:color .2s cubic-bezier(.65,0,.35,1)}
body.v9-page .wbm_search svg{top:50%;width:20px;height:20px;transform:translate(-50%,-50%);stroke-width:1.9}
body.v9-page .wbm_search:hover{color:#232834}
body.v9-page .hp-hd-cta{order:4;height:40px;margin-left:18px;padding:0 16px 0 20px;gap:4px;font-family:'Sailec',sans-serif;font-size:14.5px}
body.v9-page a.hp-hd-cta,body.v9-page a.hp-hd-cta:hover,body.v9-page a.hp-hd-cta:visited{color:#fff;text-decoration:none}
body.v9-page .hp-hd-cta::after{content:"";position:absolute;left:0;right:0;top:-2px;bottom:-2px}
body.v9-page .hp-hd-cta svg.arr{display:block;flex:none;width:14px;height:14px;stroke:currentColor;stroke-width:2.4;fill:none;transition:transform 150ms cubic-bezier(.4,0,.2,1)}
@media (hover:hover){body.v9-page .hp-hd-cta:hover svg.arr{transform:translateX(2px)}}
body.v9-page .menu_trigger{order:3;float:none;height:38px;margin:0 0 0 8px}
/* the menu's three bars are drawn a little smaller here, scaled about their own centre so they stay level with the row */
body.v9-page .menu_trigger .slicknav_icon{transform-origin:100% 19px;scale:.82}
body.v9-page .hp-hd-l:focus-visible,body.v9-page .wbm_search:focus-visible,body.v9-page .hp-hd-cta:focus-visible,body.v9-page .menu_trigger:focus-visible{outline:2px solid #232834;outline-offset:3px}
@media (max-width:699px){body.v9-page .hp-hd{display:none}}
@media (max-width:520px){body.v9-page .hp-hd-cta{display:none}}
@media (prefers-reduced-motion:reduce){body.v9-page .hp-hd-cta svg.arr{transition:none}}
/* the dark menu marks the current page by file name only in its page list, which doesn't include this page: markMenu() marks
   its Build something new route (and its tile, once it has one), in coral with the menu's own small dot */
body.v9-page #wb_menu .rt[aria-current="page"] b,body.v9-page #wb_menu .tile[aria-current="page"] b{color:#FA5478}
body.v9-page #wb_menu .rt[aria-current="page"] b::after,body.v9-page #wb_menu .tile[aria-current="page"] b::after{content:'';display:inline-block;width:7px;height:7px;margin-left:12px;border-radius:50%;background:#FA5478;vertical-align:middle}

/* ---------- base ---------- */
.v9{font-family:Sailec,Helvetica,Arial,sans-serif;font-weight:500;color:#232834;-webkit-font-smoothing:antialiased;text-wrap:pretty}
.v9 *{box-sizing:border-box}
.v9 :where(h1,h2,h3,p,ul,ol,li){margin:0;padding:0;background:none;font-family:inherit;color:inherit;font-size:inherit;line-height:inherit;text-align:left;font-weight:inherit}
.v9 :where(ul,ol,li){list-style:none}
.v9 :where(li)::marker{content:""}
.v9 a{color:inherit;text-decoration:none}
.v9 a:hover{color:#d33d5c}
.v9 svg{display:block;width:100%;height:100%;stroke:currentColor;fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
/* the page runs a little wider than the sister pages (1360px, not 1240px), but narrower than the header, which spans the
   window: from 1280px the side space is 56px, so on wider screens the content sits inset from the logo and the call button */
.v9-wrap{max-width:1360px;margin:0 auto;padding:0 40px;position:relative}
@media (min-width:1280px){.v9-wrap{padding:0 56px}}
.v9-eyebrow{display:block;font-weight:700;font-size:11.5px;letter-spacing:.22em;text-transform:uppercase;color:#d33d5c;margin:0 0 14px}
.v9-h2{font-weight:700;font-size:clamp(30px,3.4vw,44px);line-height:1.1;letter-spacing:-.03em}
.v9-sec{padding:88px 0}
.v9-bone{background:#F1EEEA}
.v9-head{margin-bottom:48px}
.v9-head .v9-sub{margin:18px 0 0;max-width:640px;font-size:18px;line-height:1.6;color:#4f5565}

/* ---------- reveal: sections ease in once as they reach the viewport ---------- */
.v9-rv{opacity:0;transform:translateY(20px);transition:opacity .8s cubic-bezier(.2,.7,.2,1),transform .8s cubic-bezier(.2,.7,.2,1)}
.v9-rv.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){.v9-rv{opacity:1;transform:none;transition:none}}

/* ---------- hero: copy on the left, the animation on the right ---------- */
.v9-hero{background:#fff;color:#232834;padding:24px 0 64px}
.v9-hero-grid{display:grid;grid-template-columns:minmax(0,6fr) minmax(0,6fr);gap:48px 72px;align-items:center}
.v9-hero h1{font-weight:700;font-size:clamp(40px,4.6vw,64px);line-height:1.1;letter-spacing:-.03em;margin:0 0 24px}
.v9-hero .v9-lead{font-size:18px;line-height:1.65;color:#3a3f4b;max-width:520px;margin:0 0 36px}
.v9-hero .v9-lead b{font-weight:700;color:#232834}
/* the one marked word: coral type on a blush marker that sweeps in once */
.v9-hl{position:relative;z-index:0;color:#d33d5c;white-space:nowrap}
.v9-hl::before{content:"";position:absolute;z-index:-1;left:-.07em;right:-.09em;top:.32em;bottom:.12em;background:#FDE0E6;border-radius:.06em .18em .08em .2em;transform:rotate(-1deg);transform-origin:left center;animation:v9Hl .9s cubic-bezier(.65,0,.35,1) .35s both}
@keyframes v9Hl{from{transform:rotate(-1deg) scaleX(0)}to{transform:rotate(-1deg) scaleX(1)}}
@media (prefers-reduced-motion:reduce){.v9-hl::before{animation:none}}
.v9-hero-form{display:flex;flex-wrap:nowrap;gap:10px}
.v9-hero-email{flex:0 1 262px;width:262px;min-width:0;height:48px;padding:0 22px;border:1.5px solid #CFC9C1;border-radius:24px;background:#fff;font:inherit;font-size:16px;color:#232834;outline:0;transition:border-color .2s,box-shadow .2s}
.v9-hero-email::placeholder{color:#6b7180}
.v9-hero-email:focus{border-color:#232834;box-shadow:0 0 0 4px rgba(250,84,120,.22)}
.v9-hero-go{flex:none;width:178px;height:48px;padding:0;border-radius:24px;font-family:inherit;font-size:16px}
@media (max-width:480px){.v9-hero-form{flex-wrap:wrap}.v9-hero-email,.v9-hero-go,.em-email{flex:1 1 100%;width:100%}}
.v9-illo{position:relative;width:100%;max-width:720px;margin:0 auto;aspect-ratio:1920/1805;pointer-events:none}
.v9-illo-art{position:absolute;inset:0}
.v9-illo-art svg{display:block;fill:#000;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter}
/* the hero swaps files by laying the next over the last: each pass has its own box, stacked in one place */
.qa-hero .v9-illo-art > div{position:absolute;inset:0}
@media (min-width:1101px){
.v9-illo{max-width:none;width:112%;margin:-24px -6% -4% -6%;transform:translateY(-7%)}
.v9-hero .v9-hero-grid{grid-template-columns:minmax(452px,5.2fr) minmax(0,6.8fr);gap:48px}
.v9-hero h1{font-size:clamp(44px,4.2vw,60px);margin-bottom:24px}
.v9-hero .v9-lead{max-width:480px}
}

/* ---------- buttons: a coral pill that lifts on hover onto a soft blush step ---------- */
.v9-btn{--btn-step:#FBC0CC;--btn-ease:cubic-bezier(.5,2.5,.7,.7);position:relative;display:inline-flex;align-items:center;justify-content:center;gap:12px;height:48px;padding:0 26px;border:1px solid transparent;border-radius:9999px;background:#FA5478;color:#fff;font-family:inherit;font-weight:700;font-size:15px;line-height:20px;white-space:nowrap;text-decoration:none;cursor:pointer;box-shadow:0 0 0 0 var(--btn-step);transition-property:transform,translate,box-shadow;transition-duration:150ms;transition-timing-function:var(--btn-ease)}
.v9 a.v9-btn,.v9 a.v9-btn:hover,.v9 a.v9-btn:visited,.v9 button.v9-btn{color:#fff}
.v9-btn::before{content:"";position:absolute;left:0;top:0;z-index:-1;width:100%;height:100%;background:transparent}
.v9 .v9-btn svg.arr{display:block;flex-shrink:0;width:14px;height:14px;margin-left:6px;stroke:currentColor;stroke-width:2.4;fill:none;transition:transform 150ms cubic-bezier(.4,0,.2,1)}
@media (hover:hover){
.v9-btn:hover{translate:0 -5px;box-shadow:0 5px 0 0 var(--btn-step)}
.v9-btn:hover::before{transform:scaleY(1.4)}
.v9 .v9-btn:hover svg.arr{transform:translateX(2px)}
}
.v9-btn:active{translate:0 -3px;box-shadow:0 3px 0 0 var(--btn-step)}
.v9-btn:focus-visible{outline:2px solid #232834;outline-offset:2px}
.v9-btn:disabled{pointer-events:none;opacity:.5}
.v9-btn.v9-btn-ghost{--btn-step:#E4DFD9;background:#fff;border-color:#232834}
.v9 a.v9-btn.v9-btn-ghost,.v9 a.v9-btn.v9-btn-ghost:hover,.v9 a.v9-btn.v9-btn-ghost:visited{color:#232834}
.v9-hero-go{padding:0;font-size:16px}
@media (prefers-reduced-motion:reduce){.v9-btn,.v9 .v9-btn svg.arr{transition:none}.v9-btn:hover,.v9-btn:active{translate:none}}
.em-center{display:flex;flex-direction:column;align-items:center;text-align:center}
.em-center .v9-h2{text-align:center;max-width:760px}
.em-center .v9-sub{text-align:center;max-width:560px;margin:18px auto 34px;font-size:18px;line-height:1.6;color:#4f5565}
/* ---------- closing: the hero's email and call button, centred ---------- */
.em-cta{border-top:1px solid #E4DFD9;padding-bottom:104px}
.em-cta .v9-sub{margin-bottom:30px}
.em-cta .v9-hero-form{justify-content:center}
.em-cta .em-talk{justify-items:center}
.em-cta .em-status{text-align:center}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

/* ---------- email and call: a valid email shows a check in the field; on send the button narrows to a spinner,
   then the form fades away and a thank-you settles in its place ---------- */
.em-talk{display:grid}
.em-talk>*{grid-area:1/1}
.em-email{position:relative;flex:0 1 262px;width:262px;min-width:0}
.em-email .v9-hero-email{width:100%;padding-right:52px;transition:border-color .35s cubic-bezier(.65,0,.35,1)}
.em-email-check{position:absolute;top:50%;right:10px;display:flex;align-items:center;justify-content:center;width:30px;height:30px;margin-top:-15px;border-radius:50%;background:#FDE0E6;transform:scale(0);transition:transform .45s cubic-bezier(.34,1.56,.64,1)}
.v9 .em-email-check svg{width:15px;height:15px;stroke:#d33d5c;stroke-width:2.6;fill:none;stroke-linecap:round;stroke-linejoin:round}
.em-demo.sending .em-email-check,.em-talk.done .em-email-check{transform:scale(1)}
.em-demo.sending .v9-hero-email,.em-talk.done .v9-hero-email{border-color:#FA5478}
.em-email .v9-hero-email:not(:placeholder-shown):valid{border-color:#FA5478}
.em-email .v9-hero-email:not(:placeholder-shown):valid ~ .em-email-check{transform:scale(1)}
.v9 .v9-btn .em-spin{display:none;width:20px;height:20px;margin-right:10px;stroke:currentColor;stroke-width:2.4;fill:none;stroke-linecap:round;animation:emSpin .8s linear infinite}
.em-demo .v9-btn{transition-property:transform,translate,box-shadow,background-color,width;transition-duration:150ms,150ms,150ms,.35s,.5s;transition-timing-function:var(--btn-ease),var(--btn-ease),var(--btn-ease),cubic-bezier(.65,0,.35,1),cubic-bezier(.65,0,.35,1)}
.em-demo.sending .v9-btn,.em-talk.done .v9-btn{width:100px;background:#FCA3B6}
.em-demo.sending .em-btn-lbl,.em-talk.done .em-btn-lbl{display:none}
.v9 .em-demo.sending .em-spin,.v9 .em-talk.done .em-spin{display:block}
.em-demo.sending .v9-btn:disabled{opacity:1}
.em-demo.sending .v9-btn:hover{translate:none;box-shadow:none}
@keyframes emSpin{to{transform:rotate(360deg)}}
.em-demo{transition:opacity .45s cubic-bezier(.65,0,.35,1),transform .55s cubic-bezier(.65,0,.35,1)}
.em-talk.done .em-demo{opacity:0;visibility:hidden;transform:translateY(-8px);pointer-events:none;transition:opacity .45s cubic-bezier(.65,0,.35,1),transform .55s cubic-bezier(.65,0,.35,1),visibility 0s linear .55s}
.em-talk-done{display:flex;align-items:center;gap:12px;min-height:48px;margin:0;font-size:16px;line-height:1.5;color:#232834;opacity:0;visibility:hidden;transform:translateY(10px);transition:opacity .5s cubic-bezier(.65,0,.35,1),transform .6s cubic-bezier(.65,0,.35,1),visibility 0s linear .6s}
.em-talk.done .em-talk-done{opacity:1;visibility:visible;transform:none;transition:opacity .55s cubic-bezier(.65,0,.35,1) .3s,transform .65s cubic-bezier(.65,0,.35,1) .3s,visibility 0s}
.em-talk-ic{flex:none;display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background:#FA5478}
.v9 .em-talk-ic svg{width:14px;height:14px;stroke:#fff;stroke-width:2.6;fill:none}
.em-status{min-height:22px;margin:12px 0 0;font-size:14px;line-height:1.5;color:#c62d4f}
@media (prefers-reduced-motion:reduce){.em-email-check,.em-demo,.em-talk.done .em-demo,.em-talk-done,.em-talk.done .em-talk-done{transition:none}.v9 .v9-btn .em-spin{animation-duration:2.4s}}

/* ---------- responsive ---------- */
@media (max-width:1100px){
.v9-hero-grid{grid-template-columns:minmax(0,1fr)}
.v9-hero .v9-lead{max-width:620px}
}
@media (max-width:820px){
.v9-wrap{padding:0 22px}
.v9-sec{padding:64px 0}
.v9-hero{padding:20px 0 48px}
}

/* ---------- text links: ink with a tint underline that darkens on hover, and an arrow that steps forward ---------- */
.v9 .qa-go{display:inline-flex;align-items:center;gap:8px;min-height:44px;margin-top:10px;font-weight:700;font-size:17px;line-height:1.3;color:#232834;text-decoration:none}
.qa-go-l{text-decoration:underline;text-decoration-color:#C2C5CC;text-decoration-thickness:1.5px;text-underline-offset:6px;transition:text-decoration-color .25s cubic-bezier(.65,0,.35,1)}
.qa-go-a{display:inline-block;transition:transform .3s cubic-bezier(.65,0,.35,1)}
@media (hover:hover){.v9 .qa-go:hover{color:#232834}.qa-go:hover .qa-go-l{text-decoration-color:#232834}.qa-go:hover .qa-go-a{transform:translateX(3px)}}
.v9 .qa-go:focus-visible{outline:2px solid #232834;outline-offset:4px;border-radius:4px}
@media (prefers-reduced-motion:reduce){.qa-go-a{transition:none}}

/* ---------- hover icons, as on the AI Chatbots page: ink outline over a white body, warm shade for depth, and one coral part
   that arrives once, in one direction, with its section. A hover Lottie sits exactly over each icon; its first frame is the
   icon, so the swap on first hover is invisible ---------- */
.cb-ic-box{grid-row:1/3;position:relative;display:block;width:72px;height:72px;margin:-6px 0 0 -4px}
.v9 svg.cb-ic{width:100%;height:100%;overflow:visible;fill:none;stroke:#232834;stroke-width:1.75px;stroke-linecap:round;stroke-linejoin:round}
.cb-ic-lt{position:absolute;inset:0;display:block;pointer-events:none;visibility:hidden}
.cb-ic-lt svg{display:block;fill:#000;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter}
.cb-ic-box.lt-on .cb-ic-lt{visibility:visible}
.cb-ic-box.lt-on svg.cb-ic{visibility:hidden}
.cb-ic *{vector-effect:non-scaling-stroke}
.cb-ic .w{fill:#fff}
.cb-ic .s{fill:#E4DFD9;stroke:none}
.cb-ic .so{fill:#E4DFD9}
.cb-ic .tn{fill:#C2C5CC;stroke:none}
.cb-ic .wn{fill:#fff;stroke:none}
.cb-ic .c{fill:#FA5478;stroke:#C43A5C}
.cb-ic .dc{stroke:#C43A5C}
.cb-ic .ik{fill:#232834;stroke:none}
.cb-ic .tk{stroke:#C2C5CC}
.cb-ic .a{transform-box:fill-box;opacity:0;transition:transform .8s cubic-bezier(.2,.7,.2,1) var(--d),opacity .5s cubic-bezier(.65,0,.35,1) var(--d)}
.v9-rv.in .cb-ic .a{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){.cb-ic .a{opacity:1;transform:none;transition:none}}

/* ---------- clients: a wall of twelve cells; one cell swaps its logo at a time (out, then in), the rest hold still ---------- */
.ai-clients{border-top:1px solid #E4DFD9}
.ai-clients-head{display:flex;align-items:flex-end;justify-content:space-between;gap:20px 56px;flex-wrap:wrap;margin-bottom:44px}
.ai-clients-head .v9-sub{margin:0;max-width:420px;font-size:17px;line-height:1.6;color:#4f5565}
.ai-wall{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));border-top:1px solid #E4DFD9;border-left:1px solid #E4DFD9}
.ai-lg{position:relative;height:120px;border-right:1px solid #E4DFD9;border-bottom:1px solid #E4DFD9;overflow:hidden}
.ai-lg img{position:absolute;inset:0;margin:auto;display:block;width:min(170px,90%);height:auto;filter:grayscale(1) opacity(.62);opacity:0;transition:opacity .9s cubic-bezier(.65,0,.35,1),filter .3s ease}
.ai-lg img.on{opacity:1}
@media (hover:hover){.ai-lg:hover img{filter:none}}
@media (max-width:820px){.ai-wall{grid-template-columns:repeat(3,minmax(0,1fr))}.ai-lg{height:96px}.ai-clients-head{margin-bottom:32px}}
@media (prefers-reduced-motion:reduce){.ai-lg img{transition:none}}
/* this page's heading and line sit centred over the wall; the heading is balanced so no line holds one word alone */
.qa-clients-head{display:flex;flex-direction:column;align-items:center;gap:14px;margin-bottom:44px;text-align:center}
.qa-clients-head .v9-h2{margin:0;text-align:center;text-wrap:balance}
.qa-clients-head .v9-sub{margin:0;max-width:520px;font-size:18px;line-height:1.6;color:#4f5565;text-align:center;text-wrap:balance}
@media (max-width:820px){.qa-clients-head{margin-bottom:32px}}
@media (max-width:560px){.qa-clients-head .v9-sub{font-size:17px}}

/* ---------- the email form from 821px up: the field and the button share one row at the same width and height, 262px
   each ("Book a 20-minute call" needs 255px). The button keeps that width while sending, so nothing shifts; a closing
   form centres the pair ---------- */
@media (min-width:821px){
.v9 .em-talk .v9-hero-form{display:grid;grid-template-columns:repeat(2,262px);gap:10px;justify-content:start}
.v9.em-cta .em-talk .v9-hero-form{justify-content:center}
.v9 .em-talk .v9-hero-form .em-email,.v9 .em-talk .v9-hero-form.em-demo .v9-hero-go{width:100%;min-width:0}
.v9 .em-talk .v9-hero-form.em-demo .v9-hero-go{padding:0 16px}
}
/* ---------- the email form on phones and small tablets: the field and the button are always the same size. Up to 560px
   they stack at the full width; from 561px to 820px they share one row in equal halves, 560px at most. The button keeps
   its size while sending, so the pair never shifts, and the closing form stays centred ---------- */
@media (max-width:820px){
.v9 .em-talk{justify-items:stretch}
.v9.em-cta .em-talk{width:100%;max-width:560px}
.v9.em-cta .em-talk-done{justify-content:center}
.v9 .em-talk .v9-hero-form{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));width:100%;max-width:560px}
.v9 .em-talk .v9-hero-form .em-email,.v9 .em-talk .v9-hero-form.em-demo .v9-hero-go{width:100%;min-width:0}
.v9 .em-talk .v9-hero-form.em-demo .v9-hero-go{padding:0 16px}
}
@media (max-width:560px){
.v9 .em-talk .v9-hero-form{grid-template-columns:minmax(0,1fr)}
}


/* ================= QA & TEST AUTOMATION (this page's own) ================= */

/* ---------- this page's hero, as on AI Security & Governance: the eyebrow, then a headline that holds two lines at every
   width. Each option is sized from its longer line, measured in Sailec Bold at -.03em on the woff2 itself (5 October 2026):
   A "pace with your code" 9.31em, B "Tests your team" 7.34em, C "Smaller releases," 7.69em, D "Testing that keeps" 8.54em,
   E "on every change" 7.56em. Up to 1100px the size follows the viewport, so that line takes 92% of the column at most, 56px
   at the largest; from 1101px, where the copy column is 560px, A runs from 48px to 54px (503px at most, 90% of the column),
   D from 50px to 56px (478px) and B, C and E from 52px to 58px (C's 446px at most). The form is sized as CLAUDE.md sets it
   for heroes: "Book a call" at 172px beside a 262px field, stacked at full width on phones ---------- */
.v9-hero.qa-hero h1.qa-h-a{font-size:min(56px,calc((100vw - 44px) / 10.15))}
.v9-hero.qa-hero h1.qa-h-b{font-size:min(56px,calc((100vw - 44px) / 8))}
.v9-hero.qa-hero h1.qa-h-c{font-size:min(56px,calc((100vw - 44px) / 8.4))}
.v9-hero.qa-hero h1.qa-h-d{font-size:min(56px,calc((100vw - 44px) / 9.3))}
.v9-hero.qa-hero h1.qa-h-e{font-size:min(56px,calc((100vw - 44px) / 8.25))}
@media (min-width:821px){.v9.qa-hero .em-talk .v9-hero-form{grid-template-columns:262px auto}}
@media (min-width:561px) and (max-width:820px){.v9.qa-hero .em-talk .v9-hero-form{grid-template-columns:minmax(0,1fr) auto}}
@media (min-width:561px){.v9.qa-hero .em-talk .v9-hero-form.em-demo .v9-hero-go{width:172px;padding:0}}
@media (max-width:560px){.v9-hero.qa-hero .v9-lead{font-size:17px}}
@media (min-width:1101px){
.v9-hero.qa-hero .v9-hero-grid{grid-template-columns:minmax(560px,5.4fr) minmax(0,6.6fr);gap:48px}
.v9-hero.qa-hero h1.qa-h-a{font-size:clamp(48px,4vw,54px)}
.v9-hero.qa-hero h1.qa-h-d{font-size:clamp(50px,4.2vw,56px)}
.v9-hero.qa-hero h1.qa-h-b,.v9-hero.qa-hero h1.qa-h-c,.v9-hero.qa-hero h1.qa-h-e{font-size:clamp(52px,4.4vw,58px)}
.v9-hero.qa-hero .v9-lead{max-width:520px}
/* the drawing is enlarged a little into the page margin, not into the column gap */
.qa-hero .v9-illo{width:106%;margin:0 -6% 0 0;transform:none}
}
/* the drawing's canvas is 1600 x 1320 (art/qa/qa-hero-1.json), and the box keeps that shape reserved from the first paint. On
   phones it sits below the form and runs to the window's edges (the canvas carries its own margin, so the hand and the cards
   are never cropped), so the words in the drawing are as large as they can be */
.qa-hero .v9-illo{aspect-ratio:1600/1320}
@media (max-width:560px){.qa-hero .v9-illo{width:calc(100% + 44px);max-width:none;margin:0 -22px}}
/* the landing view, as on the sister pages: on desktop the hero's top space follows the window's height, so the headline, form
   and drawing hold the middle of the first view and the client wall still shows below */
.v9-hero.qa-hero{padding:40px 0 64px}
@media (min-width:1101px){.v9-hero.qa-hero{padding:clamp(32px,7vh,84px) 0 72px}}
@media (max-width:560px){.v9-hero.qa-hero{padding:28px 0 48px}}

/* ---------- tap areas and the legacy menu, as CLAUDE.md sets them. The logos in the header and footer are widened to 44px tap
   areas with padding cancelled by margin, so nothing moves. The site's old hidden menu sits off to the side until its script
   marks it loaded; until then it is held to no width, so it can't cause sideways scroll ---------- */
body.v9-page .header-wide.wb-hd .header .logo{padding:7px 0;margin:-7px 0}
body.v9-page .wb-ft .wb-ft-logo{padding:8px 0;margin:-8px 0}
body.v9-page #main_menu:not(.loaded){left:0;right:auto;width:0;max-width:0;overflow:hidden}

/* ---------- the closing: the email form, centred, sized and behaving as the hero's at every width. Nothing follows it: urgent
   help is reached from the header, the menu and the footer ---------- */
.qa-cta .v9-h2{text-wrap:balance}
.qa-cta .v9-sub{text-wrap:pretty}


/* ---------- when testing holds releases back: the copy, and one still drawing of batch size from its words, with no figures.
   Checked by hand: one large release card (bone, in the family's ink line) holding a heap of small change chips. Checked on
   every change: a row of small release cards, one chip each. The one coral part is a change that breaks something: buried
   among the others in the large release, on its own in a small one, and named in the key beneath. Not Cloud, DevOps &
   Security's hairlines of evenly spaced marks: nothing here runs along a line. Side by side from 1024px, the drawing on the
   right; stacked below. On phones the row shows four small releases and the large one fewer chips, rather than squeezing them
   (checked 5 October 2026 against DORA's capability pages on working in small batches, test automation and continuous
   integration, and martinfowler.com, "Eradicating Non-Determinism in Tests", 2011) ---------- */
.qa-prob{border-top:1px solid #E4DFD9}
.qa-prob-grid{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,6fr);gap:48px 80px;align-items:center}
.qa-prob-copy .v9-h2{margin:0 0 22px;text-wrap:balance}
.v9 .qa-prob-copy p{margin:0;max-width:560px;font-weight:500;font-size:18px;line-height:1.6;color:#4f5565;text-wrap:pretty}
.qa-batch{display:grid;gap:30px;margin:0}
.qa-batch-row{display:grid;gap:12px}
.v9 .qa-batch-cap{margin:0;font-weight:700;font-size:16px;line-height:1.4;color:#232834}
.qa-rel{box-sizing:border-box;display:flex;align-items:center;justify-content:center;border:1.75px solid #232834;border-radius:14px;background:#F1EEEA}
.qa-rel-big{flex-wrap:wrap;justify-content:flex-start;align-content:flex-start;gap:12px 8px;padding:24px;border-radius:20px}
.qa-rels{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:12px}
.qa-rels .qa-rel{height:66px}
.qa-chip{display:block;flex:none;box-sizing:border-box;width:46px;height:18px;border:1.75px solid #232834;border-radius:9px;background:#fff}
.qa-chip.w1{width:34px}.qa-chip.w2{width:46px}.qa-chip.w3{width:58px}.qa-chip.w4{width:72px}
.qa-chip.bad{border-color:#C43A5C;background:#FA5478}
.v9 .qa-batch-key{display:flex;align-items:center;gap:12px;margin:-6px 0 0;font-weight:500;font-size:16px;line-height:1.4;color:#4f5565}
@media (max-width:1023px){.qa-prob-grid{grid-template-columns:minmax(0,1fr)}.qa-batch{max-width:600px}}
@media (max-width:560px){.qa-batch{gap:26px}.qa-rel-big{padding:20px}.qa-rels{grid-template-columns:repeat(4,minmax(0,1fr))}.qa-rels .qa-rel:nth-child(n+5),.qa-rel-big .qa-chip:nth-child(n+12){display:none}}


/* ---------- tests in the right places: the copy comes first in the page (so the heading is read before the drawing); from
   1024px the drawing sits on its left (the section above has it on the right), and below 1024px it follows the copy. Three bands on one centre line, each in the family's ink line, with no triangle
   drawn: Full journeys at the top, holding Sign-up, Login and Checkout; Between services in the middle; Small tests at the
   base. They start upside down, full journeys widest, and when the drawing is well in view they rebalance once into the
   right shape and hold: the base widens and warms to blush, where most checks belong, and the top narrows to just its three
   journeys. It starts only once the whole drawing has risen above 60% of the window's height, so it plays where the reader
   is looking rather than as it enters at the bottom. Only widths change, so the drawing keeps its height and nothing below it moves; with reduced motion it is shown
   in its final shape. Every label fits inside its band at every width: the top band never narrows past its three journeys,
   measured in Sailec Medium (263px at 14px, 220px at 13px on phones, 5 October 2026), so none has to sit beside it. Checked 5 October 2026 against the Google Testing Blog, "Just Say No to More End-to-End
   Tests" (22 April 2015), and martinfowler.com, "The Practical Test Pyramid" (Ham Vocke, 2018) ---------- */
.qa-bal{border-top:1px solid #E4DFD9}
.qa-bal-grid{display:grid;grid-template-columns:minmax(0,6fr) minmax(0,5fr);gap:48px 80px;align-items:center}
.qa-bal-copy .v9-h2{margin:0 0 22px;text-wrap:balance}
.v9 .qa-bal-copy p{margin:0;max-width:560px;font-weight:500;font-size:18px;line-height:1.6;color:#4f5565;text-wrap:pretty}
.qa-pyr{margin:0;order:-1}
.qa-pyr-art{display:grid;justify-items:center;gap:10px;max-width:600px;margin:0 auto}
.v9 .qa-pyr-cap{margin:0 0 2px;font-weight:700;font-size:16px;line-height:1.4;color:#232834}
.qa-band{box-sizing:border-box;display:flex;align-items:center;justify-content:center;gap:6px;height:58px;padding:0 10px;border:1.75px solid #232834;border-radius:14px;background:#F1EEEA;overflow:hidden;transition:width 1.1s cubic-bezier(.65,0,.35,1),background-color .6s cubic-bezier(.65,0,.35,1)}
.qa-band.b-top{width:100%;background:#fff}
.qa-band.b-mid{width:76%}
.qa-band.b-base{width:max(40%,150px)}
.qa-pyr.go .qa-band.b-top{width:max(40%,276px)}
.qa-pyr.go .qa-band.b-base{width:100%;background:#FDE0E6;transition-delay:.12s,.9s}
.v9 .qa-band-l{font-weight:700;font-size:16px;line-height:1.2;color:#232834;white-space:nowrap}
.qa-jn{flex:none;box-sizing:border-box;display:inline-flex;align-items:center;height:30px;padding:0 10px;border:1.5px solid #232834;border-radius:15px;background:#fff;font-weight:500;font-size:14px;line-height:1;color:#232834;white-space:nowrap}
@media (prefers-reduced-motion:reduce){.qa-band{transition:none}.qa-pyr.go .qa-band.b-base{transition-delay:0s}}
@media (max-width:1023px){.qa-bal-grid{grid-template-columns:minmax(0,1fr)}.qa-pyr{order:0}.qa-pyr-art{max-width:560px;margin:0}}
@media (max-width:560px){.qa-band{height:52px;padding:0 8px}.qa-band.b-mid{width:88%}.qa-jn{height:28px;padding:0 6px;font-size:13px}.qa-band.b-top{gap:4px}.qa-pyr.go .qa-band.b-top{width:max(40%,232px)}}


/* ---------- what we set up with your team: the heading and its line, then the items in a grid separated by space alone (not
   Platform Engineering's hairlines, Web & App Development's index or AI Security & Governance's cards): four across from
   1101px, two from 600px, one on phones. Each item is its icon, its title and its line; the icon is drawn for this page
   (tools/qa-icons-scene.js) and plays its hover Lottie (art/qa/qa-ic-*.json, under 3 KB each) as the pointer rests on the
   item, from 821px with a mouse or trackpad, never with reduced motion. The items aren't links, so there is nothing to
   focus. People exploring the product is hidden until it's confirmed; if it goes in, set the grid to three across
   (.qa-setup-grid.n9). Beneath, under one hairline, the three hand-off lines to the sister pages, each link 44px tall ---------- */
.qa-setup{border-top:1px solid #E4DFD9}
.qa-setup-head{max-width:720px;margin:0 0 56px;text-align:left}
.qa-setup-head .v9-h2{margin:0 0 16px;text-wrap:balance}
.v9 .qa-setup-sub{margin:0;font-weight:500;font-size:18px;line-height:1.6;color:#4f5565;text-wrap:pretty}
.qa-setup-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:56px 40px;margin:0;padding:0;list-style:none}
.qa-setup-grid.n9{grid-template-columns:repeat(3,minmax(0,1fr))}
.qa-setup-grid > li{display:block;margin:0;padding:0;min-width:0;--d:0s}
.qa-setup-grid > li:nth-child(2){--d:.06s}.qa-setup-grid > li:nth-child(3){--d:.12s}.qa-setup-grid > li:nth-child(4){--d:.18s}.qa-setup-grid > li:nth-child(5){--d:.24s}.qa-setup-grid > li:nth-child(6){--d:.3s}.qa-setup-grid > li:nth-child(7){--d:.36s}.qa-setup-grid > li:nth-child(8){--d:.42s}.qa-setup-grid > li:nth-child(9){--d:.48s}
.qa-setup-grid .cb-ic-box{grid-row:auto;margin:0 0 18px -4px}
.v9 .qa-setup-grid h3{margin:0 0 8px;font-weight:700;font-size:20px;line-height:1.3;letter-spacing:-.01em;color:#232834;text-wrap:balance}
.v9 .qa-setup-grid p{margin:0;font-weight:500;font-size:17px;line-height:1.55;color:#4f5565;text-wrap:pretty}
.qa-more{display:grid;margin:64px 0 0;padding:24px 0 0;border-top:1px solid #E4DFD9;list-style:none}
.v9 .qa-more li{display:flex;flex-wrap:wrap;align-items:center;column-gap:8px;min-height:44px;margin:0;padding:0;font-weight:500;font-size:17px;line-height:1.4;color:#4f5565}
.v9 .qa-more a{display:inline-flex;align-items:center;min-height:44px;font-weight:700;color:#d33d5c;text-decoration:none}
.v9 .qa-more a:hover,.v9 .qa-more a:focus-visible{color:#d33d5c;text-decoration:underline;text-decoration-thickness:1.5px;text-underline-offset:4px}
@media (max-width:1100px){.qa-setup-grid,.qa-setup-grid.n9{grid-template-columns:repeat(2,minmax(0,1fr));gap:48px 40px}}
@media (max-width:599px){.qa-setup-head{margin-bottom:40px}.qa-setup-grid,.qa-setup-grid.n9{grid-template-columns:minmax(0,1fr);gap:40px}.qa-setup-grid .cb-ic-box{width:64px;height:64px;margin-bottom:14px}.qa-more{margin-top:48px}.v9 .qa-more li{display:block;padding:10px 0 0}.v9 .qa-more li span{display:block}}


/* ---------- coverage isn't the whole story: the copy, then the page's one interaction under it (checked 5 October 2026
   against the Google Testing Blog, "Code Coverage Best Practices", 7 August 2020, and Petrović and Ivanković, "State of
   Mutation Testing at Google", ICSE SEIP 2018). Two separate cards side by side, in plain words, never code (not Legacy
   Modernisation's one card of three bands): the rule on white, the tests on bone, each test with an ink tick (passes) or an
   ink cross (fails), never green or red. Beneath, the result, then three real buttons, only the next step's active. 1, Make
   a deliberate mistake: the rule changes to "Anyone can approve a refund", the section's one coral part ("Anyone", and the
   Changed tag), the test runs again (its tick redraws) and still passes. 2, Add the missing test: "Staff can't approve a
   refund" joins, runs and fails (its cross draws in): caught. Every state is stacked in place (the rule's two wordings, the
   two tests, the three results), so the box holds the height of its tallest state at every width and nothing below it
   moves. With reduced motion each step changes at once. Below 560px the cards stack and the buttons go full width ---------- */
.qa-cov{border-top:1px solid #E4DFD9}
.qa-cov-copy .v9-h2{margin:0 0 22px;text-wrap:balance}
.v9 .qa-cov-copy p{margin:0;max-width:720px;font-weight:500;font-size:18px;line-height:1.6;color:#4f5565;text-wrap:pretty}
.qa-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.qa-mut{max-width:980px;margin:48px 0 0}
.qa-mut-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}
.qa-mut-card{box-sizing:border-box;min-width:0;padding:22px 28px 26px;border:1.75px solid #232834;border-radius:20px;background:#fff}
.qa-mut-tests{background:#F1EEEA}
.v9 .qa-mut-k{display:flex;align-items:center;flex-wrap:wrap;gap:10px;min-height:28px;margin:0 0 14px;font-weight:700;font-size:14px;line-height:1;letter-spacing:.14em;text-transform:uppercase;color:#4f5565}
.qa-mut-tag{display:inline-flex;align-items:center;height:26px;padding:0 10px;border-radius:13px;background:#FDE0E6;color:#C43A5C;font-size:13px;letter-spacing:.08em;opacity:0;visibility:hidden;transform:translateY(4px);transition:opacity .2s cubic-bezier(.65,0,.35,1),transform .2s cubic-bezier(.65,0,.35,1),visibility 0s linear .2s}
[data-step="1"] .qa-mut-tag,[data-step="2"] .qa-mut-tag{opacity:1;visibility:visible;transform:none;transition:opacity .4s cubic-bezier(.65,0,.35,1) 0.2s,transform .4s cubic-bezier(.65,0,.35,1) 0.2s,visibility 0s linear 0.2s}
.v9 .qa-mut-rule-t{display:grid;margin:0;font-weight:700;font-size:24px;line-height:1.3;letter-spacing:-.015em;color:#232834;text-wrap:balance}
.qa-mut-rule-t > span{grid-area:1/1}
.qa-mut-rule-t b{font-weight:700;color:#d33d5c}
.qa-mut-rule-t .v0{opacity:1;visibility:visible;transform:none;transition:opacity .4s cubic-bezier(.65,0,.35,1) 0.1s,transform .4s cubic-bezier(.65,0,.35,1) 0.1s,visibility 0s linear 0.1s}
.qa-mut-rule-t .v1,[data-step="1"] .qa-mut-rule-t .v0,[data-step="2"] .qa-mut-rule-t .v0{opacity:0;visibility:hidden;transform:translateY(4px);transition:opacity .2s cubic-bezier(.65,0,.35,1),transform .2s cubic-bezier(.65,0,.35,1),visibility 0s linear .2s}
[data-step="1"] .qa-mut-rule-t .v1,[data-step="2"] .qa-mut-rule-t .v1{opacity:1;visibility:visible;transform:none;transition:opacity .4s cubic-bezier(.65,0,.35,1) 0.2s,transform .4s cubic-bezier(.65,0,.35,1) 0.2s,visibility 0s linear 0.2s}
.qa-mut-list{display:grid;gap:10px;margin:0;padding:0;list-style:none}
.v9 .qa-mut-list li{display:flex;align-items:center;gap:14px;min-height:44px;margin:0;padding:0;font-weight:500;font-size:18px;line-height:1.35;color:#232834}
.qa-mut-mk{flex:none;display:block;width:28px;height:28px}
.qa-mut-mk svg{display:block;width:28px;height:28px;overflow:visible}
.qa-mut-mk circle{fill:#232834}
.qa-mut-mk path{fill:none;stroke:#fff;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:30;stroke-dashoffset:0}
.qa-mut-list .t2{opacity:0;visibility:hidden;transform:translateY(4px);transition:opacity .2s cubic-bezier(.65,0,.35,1),transform .2s cubic-bezier(.65,0,.35,1),visibility 0s linear .2s}
[data-step="2"] .qa-mut-list .t2{opacity:1;visibility:visible;transform:none;transition:opacity .4s cubic-bezier(.65,0,.35,1) 0s,transform .4s cubic-bezier(.65,0,.35,1) 0s,visibility 0s linear 0s}
[data-step="1"] .qa-mut-list .t1 .qa-mut-mk path{animation:qa-rerun .9s cubic-bezier(.65,0,.35,1) .65s both}
[data-step="2"] .qa-mut-list .t2 .qa-mut-mk path{animation:qa-draw .45s cubic-bezier(.65,0,.35,1) .55s both}
@keyframes qa-rerun{0%{stroke-dashoffset:0}35%{stroke-dashoffset:30}45%{stroke-dashoffset:30}100%{stroke-dashoffset:0}}
@keyframes qa-draw{0%{stroke-dashoffset:30}100%{stroke-dashoffset:0}}
.v9 .qa-mut-res{display:grid;margin:24px 0 0;font-weight:700;font-size:20px;line-height:1.4;color:#232834;text-wrap:balance}
.qa-mut-res > span{grid-area:1/1;opacity:0;visibility:hidden;transform:translateY(4px);transition:opacity .2s cubic-bezier(.65,0,.35,1),transform .2s cubic-bezier(.65,0,.35,1),visibility 0s linear .2s}
.qa-mut-res .r0{font-weight:500;color:#4f5565}
[data-step="0"] .qa-mut-res .r0{opacity:1;visibility:visible;transform:none;transition:opacity .4s cubic-bezier(.65,0,.35,1) 0.1s,transform .4s cubic-bezier(.65,0,.35,1) 0.1s,visibility 0s linear 0.1s}
[data-step="1"] .qa-mut-res .r1{opacity:1;visibility:visible;transform:none;transition:opacity .4s cubic-bezier(.65,0,.35,1) 1.55s,transform .4s cubic-bezier(.65,0,.35,1) 1.55s,visibility 0s linear 1.55s}
[data-step="2"] .qa-mut-res .r2{opacity:1;visibility:visible;transform:none;transition:opacity .4s cubic-bezier(.65,0,.35,1) 1.1s,transform .4s cubic-bezier(.65,0,.35,1) 1.1s,visibility 0s linear 1.1s}
.qa-mut-btns{display:flex;flex-wrap:wrap;gap:10px;margin:20px 0 0}
.v9 .qa-mut-btn{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;min-height:48px;margin:0;padding:0 22px;border:1.75px solid #232834;border-radius:999px;background:#232834;color:#fff;font-family:inherit;font-weight:700;font-size:16px;line-height:1.2;cursor:pointer;transition:background-color .2s cubic-bezier(.65,0,.35,1),border-color .2s cubic-bezier(.65,0,.35,1),color .2s cubic-bezier(.65,0,.35,1)}
@media (hover:hover){.v9 .qa-mut-btn:hover{background:#3a3f4b;border-color:#3a3f4b}}
.v9 .qa-mut-btn:focus-visible{outline:3px solid #d33d5c;outline-offset:3px}
.v9 .qa-mut-btn:disabled,.v9 .qa-mut-btn:disabled:hover{background:#fff;border-color:#E4DFD9;color:#8E939E;cursor:default}
@media (prefers-reduced-motion:reduce){.qa-mut *{transition:none!important;animation:none!important}}
@media (max-width:560px){.qa-mut{margin-top:36px}.qa-mut-cards{grid-template-columns:minmax(0,1fr);gap:14px}.qa-mut-card{padding:18px 20px 20px}.qa-mut-btns{display:grid;gap:10px}.v9 .qa-mut-btn{width:100%;height:48px}}


/* ---------- tests that fail for a reason: the copy, and one result card drawn from its words (checked 5 October 2026 against
   the Google Testing Blog, "Flaky Tests at Google and How We Mitigate Them", John Micco, 27 May 2016, and martinfowler.com,
   "Eradicating Non-Determinism in Tests", Martin Fowler, 14 April 2011). The card, bone in the family's ink line, reads "A test
   failed" beside an ink cross, never red. When the drawing is well in view the run plays once and holds: its Run again button
   presses and warms to coral, the section's one coral part; the cross leaves and an ink tick draws; the result turns to "All
   tests passed"; then a short ink tie draws out from the card and the note beside it types, one letter at a time: "Same code,
   different result". No hand, which the hero uses. Not Systems & API Integration's queue, SEO & AI Search's checks running as
   rows or AI Security & Governance's circular arrow: one card, one press. Every state is stacked in place and the note's
   letters hold their space, so nothing moves; scrolled past, or with reduced motion, it shows its last frame. Side by side
   from 1024px, the drawing on the right with the note beside the card; stacked below; on phones the note moves below the card.
   Measured in Sailec (5 October 2026): "All tests passed" 181px at 24px Bold, so the card never narrows past 285px; the note's
   longer line, "different result", 157px at 22px Medium, and the whole note 260px at 20px on phones ---------- */
.qa-flaky{border-top:1px solid #E4DFD9}
.qa-flaky-grid{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:48px 80px;align-items:center}
.qa-flaky-copy .v9-h2{margin:0 0 22px;text-wrap:balance}
.v9 .qa-flaky-copy p{margin:0;max-width:560px;font-weight:500;font-size:18px;line-height:1.6;color:#4f5565;text-wrap:pretty}
.qa-flk{margin:0}
.qa-flk-art{display:grid;grid-template-columns:minmax(285px,360px) 40px max-content;align-items:center;pointer-events:none;-webkit-user-select:none;user-select:none}
.qa-flk-card{min-width:0;padding:22px 28px 28px;border:1.75px solid #232834;border-radius:20px;background:#F1EEEA}
.qa-flk-res{display:flex;align-items:center;gap:14px;min-height:44px}
.v9 .qa-flk-t{display:grid;margin:0;font-weight:700;font-size:24px;line-height:1.25;letter-spacing:-.01em;color:#232834;white-space:nowrap}
.qa-flk-t > span{grid-area:1/1}
.qa-flk-t .s1{opacity:0;transform:translateY(4px)}
.qa-flk-mk .t{stroke-dasharray:17;stroke-dashoffset:17}
.v9 .qa-flk-btn{display:flex;align-items:center;width:max-content;height:40px;margin:20px 0 0;padding:0 18px;border:1.75px solid #232834;border-radius:20px;background:#fff;font-weight:700;font-size:15px;line-height:1;color:#232834}
/* the tie and the note's first line sit level with the result (its centre is 87.75px below the card's top edge: border 1.75,
   padding 22, label 28 + 14, half the 44px row), so the note reads as a remark on the result */
.qa-flk-tie{display:block;align-self:start;width:30px;height:1.75px;margin-top:86.9px;border-radius:1px;background:#232834;transform:scaleX(0);transform-origin:0 50%}
.v9 .qa-flk-note{align-self:start;margin:73.4px 0 0;font-weight:500;font-size:22px;line-height:1.3;color:#232834;white-space:nowrap}
.v9 .qa-flk-note i{font:inherit;font-style:normal;opacity:0}
.qa-flk-l{display:block}
.qa-flk.go .qa-flk-btn{background:#FA5478;border-color:#C43A5C;color:#fff;animation:qa-press .36s cubic-bezier(.65,0,.35,1) .5s both;transition:background-color .3s cubic-bezier(.65,0,.35,1) .55s,border-color .3s cubic-bezier(.65,0,.35,1) .55s,color .3s cubic-bezier(.65,0,.35,1) .55s}
@keyframes qa-press{0%{transform:none}45%{transform:translateY(2px)}100%{transform:none}}
.qa-flk.go .qa-flk-mk .x{opacity:0;transition:opacity .25s cubic-bezier(.65,0,.35,1) 1s}
.qa-flk.go .qa-flk-t .s0{opacity:0;transform:translateY(-4px);transition:opacity .25s cubic-bezier(.65,0,.35,1) 1s,transform .25s cubic-bezier(.65,0,.35,1) 1s}
.qa-flk.go .qa-flk-mk .t{stroke-dashoffset:0;transition:stroke-dashoffset .45s cubic-bezier(.65,0,.35,1) 1.4s}
.qa-flk.go .qa-flk-t .s1{opacity:1;transform:none;transition:opacity .4s cubic-bezier(.65,0,.35,1) 1.4s,transform .4s cubic-bezier(.65,0,.35,1) 1.4s}
.qa-flk.go .qa-flk-tie{transform:none;transition:transform .35s cubic-bezier(.65,0,.35,1) 2.2s}
.v9 .qa-flk.go .qa-flk-note i{opacity:1;transition:opacity .12s linear 2.6s}
.qa-flk.end .qa-flk-art,.qa-flk.end .qa-flk-art *{transition:none!important;animation:none!important}
@media (prefers-reduced-motion:reduce){.qa-flk .qa-flk-art,.qa-flk .qa-flk-art *{transition:none!important;animation:none!important}}
@media (max-width:1023px){.qa-flaky-grid{grid-template-columns:minmax(0,1fr)}.qa-flk{max-width:600px}}
@media (max-width:560px){.qa-flk-art{grid-template-columns:minmax(0,1fr);justify-items:start}.qa-flk-card{width:100%;padding:18px 20px 22px}.qa-flk-tie{width:1.75px;height:24px;margin:0 0 0 20px;transform:scaleY(0);transform-origin:50% 0}.v9 .qa-flk-note{margin:8px 0 0 20px;white-space:normal}.qa-flk-l{display:inline-block}.qa-flk-l + .qa-flk-l{margin-left:.28em}}


/* ---------- when AI writes the code, and the tests: the copy, then its one line pulled out beneath it in large, quiet type
   (Sailec Medium in ink under a short ink rule; no quotation marks, since the line is our own, and nothing coral). From 1024px
   it is indented by about a third of the column, so the eye moves from the paragraph down to its point; below, it follows the copy at
   the left. Never larger than a section heading: 42px at most on desktop, the phone scale's 26px on phones. Checked 5 October
   2026 against DORA, "Balancing AI tensions" (dora.dev, Jessica Baolin and Nathen Harvey, 10 March 2026): the 2025 DORA report
   found higher AI adoption associated with higher software delivery throughput and higher instability, and testing is one
   of the four uses Google engineers most often described (1,110 survey comments, Q3 2025), with drafting and boilerplate
   among its gains and verification overhead among its costs ---------- */
.qa-ai{border-top:1px solid #E4DFD9}
.qa-ai-copy .v9-h2{margin:0 0 22px;text-wrap:balance}
.v9 .qa-ai-copy p{margin:0;max-width:720px;font-weight:500;font-size:18px;line-height:1.6;color:#4f5565;text-wrap:pretty}
.v9 .qa-ai-pull{max-width:900px;margin:64px 0 0 31%;font-weight:500;font-size:clamp(30px,3.1vw,42px);line-height:1.22;letter-spacing:-.02em;color:#232834;text-wrap:balance}
.qa-ai-pull::before{content:"";display:block;width:56px;height:1.75px;margin:0 0 24px;border-radius:1px;background:#232834}
@media (max-width:1023px){.v9 .qa-ai-pull{max-width:760px;margin:48px 0 0}}
@media (max-width:560px){.v9 .qa-ai-pull{margin-top:36px}.qa-ai-pull::before{margin-bottom:18px}}


/* ---------- start with what you check by hand: the copy on the right, and on the left one bone sheet drawn from its words,
   "Checked by hand before each release", with five checks on faint rules. When the sheet is well in view it plays once and
   holds: the first three checks (sign-up, login and payment, the journeys the page names) are struck through in ink, one at
   a time, each strike following its words across a wrapped line; then an ink bracket draws down beside them and a note types,
   one letter at a time: "Automated first". Ink only, no coral. Not AI Security & Governance's checkboxes or AI Agents' struck
   figure: a sheet someone works through by hand, with the checks that go first marked off. Every state is in place from the
   first paint and the note's letters hold their space, so nothing moves; scrolled past, or with reduced motion, it shows its
   last frame. The sheet sits on the left from 1024px and below the copy on smaller screens; on phones the note takes two
   lines beside the bracket. Measured in Sailec Medium (5 October 2026): the longest check, "Log in and reset a password",
   240px at 18px; the note 136px at 18px; the strike sits on the middle of the x-height, .8em below the top of its line's box ---------- */
.qa-start{border-top:1px solid #E4DFD9}
.qa-start-grid{display:grid;grid-template-columns:minmax(0,min(540px,52%)) minmax(0,1fr);gap:48px clamp(64px,7vw,112px);align-items:center}
.qa-start-copy{grid-column:2;grid-row:1}
.qa-start-copy .v9-h2{margin:0 0 22px;text-wrap:balance}
.v9 .qa-start-copy p{margin:0;max-width:560px;font-weight:500;font-size:18px;line-height:1.6;color:#4f5565;text-wrap:pretty}
.v9 .qa-start-copy p + p{margin-top:20px}
.v9 .qa-start-copy a{padding:11px 0;font-weight:700;color:#d33d5c;text-decoration:none;white-space:nowrap}
.v9 .qa-start-copy a:hover,.v9 .qa-start-copy a:focus-visible{color:#d33d5c;text-decoration:underline;text-decoration-thickness:1.5px;text-underline-offset:4px}
.qa-chk{grid-column:1;grid-row:1;margin:0}
.qa-chk-sheet{box-sizing:border-box;max-width:540px;padding:24px 30px 16px;border:1.75px solid #232834;border-radius:20px;background:#F1EEEA;pointer-events:none;-webkit-user-select:none;user-select:none}
.v9 .qa-chk-h{margin:0;padding:0 0 16px;border-bottom:1px solid #E4DFD9;font-weight:700;font-size:20px;line-height:1.3;letter-spacing:-.01em;color:#232834;text-wrap:balance}
.qa-chk-rows{display:grid;grid-template-columns:minmax(0,1fr) 12px max-content;column-gap:16px}
.v9 .qa-chk-r{grid-column:1;margin:0;padding:13px 0;border-bottom:1px solid #E4DFD9;font-weight:500;font-size:18px;line-height:1.4;color:#232834}
.qa-chk-r.r1{grid-row:1}.qa-chk-r.r2{grid-row:2}.qa-chk-r.r3{grid-row:3}.qa-chk-r.r4{grid-row:4}.v9 .qa-chk-r.r5{grid-row:5;border-bottom:0}
.qa-chk-s{background:linear-gradient(#232834,#232834) 0 calc(.8em - .875px)/0% 1.75px no-repeat;-webkit-box-decoration-break:slice;box-decoration-break:slice}
.qa-chk-br{grid-column:2;grid-row:1/4;align-self:stretch;box-sizing:border-box;margin:14px 0;border:1.75px solid #232834;border-left:0;border-radius:0 8px 8px 0;clip-path:inset(0 0 100% 0)}
.v9 .qa-chk-note{grid-column:3;grid-row:1/4;align-self:center;margin:0;font-weight:500;font-size:18px;line-height:1.3;color:#232834;white-space:nowrap}
.qa-chk-l + .qa-chk-l{margin-left:.28em}
.v9 .qa-chk-note i{font:inherit;font-style:normal;opacity:0}
.qa-chk.go .qa-chk-s{background-size:100% 1.75px;transition:background-size .6s cubic-bezier(.65,0,.35,1) .3s}
.qa-chk.go .r2 .qa-chk-s{transition-delay:1s}
.qa-chk.go .r3 .qa-chk-s{transition-delay:1.7s}
.qa-chk.go .qa-chk-br{clip-path:inset(0);transition:clip-path .4s cubic-bezier(.65,0,.35,1) 2.45s}
.v9 .qa-chk.go .qa-chk-note i{opacity:1;transition:opacity .12s linear 2.95s}
.qa-chk.end .qa-chk-sheet,.qa-chk.end .qa-chk-sheet *{transition:none!important}
@media (prefers-reduced-motion:reduce){.qa-chk .qa-chk-sheet,.qa-chk .qa-chk-sheet *{transition:none!important}}
@media (max-width:1023px){.qa-start-grid{grid-template-columns:minmax(0,1fr)}.qa-start-copy,.qa-chk{grid-column:1;grid-row:auto}.qa-chk{max-width:560px}}
@media (max-width:560px){.qa-chk-sheet{padding:20px 18px 10px}.v9 .qa-chk-h{padding-bottom:14px}.qa-chk-rows{grid-template-columns:minmax(0,1fr) 10px max-content;column-gap:10px}.v9 .qa-chk-r{padding:11px 0}.qa-chk-br{margin:12px 0}.qa-chk-l{display:block}.qa-chk-l + .qa-chk-l{margin-left:0}}

/* ---------- questions worth asking: one narrow reading column, centred on the page, with the heading and every question
   left-aligned inside it; each answer beneath its question, and a hairline between them. Every answer is visible, with no
   accordion and no FAQ structured data. Not SEO & AI Search's two columns, Application Security's rows with the answer to
   the right, or AI Security & Governance's groups by who's asking. "Do we still need people to test?" is hidden
   (style="display:none") until testers are confirmed, like its item in What we set up. Checked 5 October 2026 against DORA,
   "Test automation" (dora.dev, last updated 17 July 2025): manual regression testing as a bottleneck, a few acceptance tests
   for the high-value functionality first on an existing system, testers doing exploratory and usability testing beside
   developers, faster unit tests before slower acceptance tests, vulnerability scans in the pipeline; martinfowler.com,
   "Eradicating Non-Determinism in Tests" (14 April 2011): a bare sleep slows tests, so use a callback or polling, and
   isolated tests can run in parallel; and the Google Testing Blog, "Code Coverage Best Practices" (7 August 2020) ---------- */
.qa-faq{border-top:1px solid #E4DFD9}
.qa-faq-col{max-width:720px;margin:0 auto}
.v9 .qa-faq-h{margin:0 0 36px;text-wrap:balance}
.qa-faq-q{padding:28px 0}
.qa-faq-q:first-child{padding-top:0}
.qa-faq-q:last-child{padding-bottom:0}
.qa-faq-q + .qa-faq-q{border-top:1px solid #E4DFD9}
.v9 .qa-faq-q h3{margin:0 0 8px;font-weight:700;font-size:20px;line-height:1.35;letter-spacing:-.01em;color:#232834;text-wrap:balance}
.v9 .qa-faq-q p{margin:0;font-weight:500;font-size:18px;line-height:1.6;color:#4f5565;text-wrap:pretty}
.v9 .qa-faq-q a{padding:11px 0;font-weight:700;color:#d33d5c;text-decoration:none;white-space:nowrap}
.v9 .qa-faq-q a:hover,.v9 .qa-faq-q a:focus-visible{color:#d33d5c;text-decoration:underline;text-decoration-thickness:1.5px;text-underline-offset:4px}
@media (max-width:560px){.v9 .qa-faq-h{margin-bottom:28px}.qa-faq-q{padding:24px 0}}

/* ================= THE PHONE TYPE SCALE: written 5 October 2026 by tools/phone-type.js. Up to 560px: h1 34px, section headings 26px, titles 18 to 20px, body 16px; nothing gets larger. To be run again as each section is added ================= */
@media (max-width:560px){
.v9-h2{font-size:26px;line-height:1.18;letter-spacing:-.025em}
.v9-head .v9-sub,.em-center .v9-sub,.v9 .qa-go,.ai-clients-head .v9-sub,.qa-clients-head .v9-sub,.v9 .qa-prob-copy p,.v9 .qa-bal-copy p,.v9 .qa-setup-sub,.v9 .qa-setup-grid p,.v9 .qa-more li,.v9 .qa-cov-copy p,.v9 .qa-mut-list li,.v9 .qa-flaky-copy p,.v9 .qa-ai-copy p,.v9 .qa-start-copy p,.v9 .qa-chk-r,.v9 .qa-chk-note,.v9 .qa-faq-q p{font-size:16px}
.v9-hero h1{font-size:min(34px,clamp(40px,4.6vw,64px));line-height:1.12}
.v9-hero .v9-lead{font-size:17px}
.v9-hero.qa-hero h1.qa-h-a{font-size:min(34px,min(56px,calc((100vw - 44px) / 10.15)));line-height:1.12}
.v9-hero.qa-hero h1.qa-h-b{font-size:min(34px,min(56px,calc((100vw - 44px) / 8)));line-height:1.12}
.v9-hero.qa-hero h1.qa-h-c{font-size:min(34px,min(56px,calc((100vw - 44px) / 8.4)));line-height:1.12}
.v9-hero.qa-hero h1.qa-h-d{font-size:min(34px,min(56px,calc((100vw - 44px) / 9.3)));line-height:1.12}
.v9-hero.qa-hero h1.qa-h-e{font-size:min(34px,min(56px,calc((100vw - 44px) / 8.25)));line-height:1.12}
.v9 .qa-setup-grid h3,.v9 .qa-mut-res,.v9 .qa-chk-h,.v9 .qa-faq-q h3{font-size:18px}
.v9 .qa-mut-rule-t,.v9 .qa-flk-t,.v9 .qa-flk-note{font-size:20px}
.v9 .qa-ai-pull{font-size:26px}
}
