1<!doctype html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8" /> 5 <link rel="icon" type="image/svg+xml" href="/assets/favicon.svg" /> 6 <link rel="icon" type="image/png" sizes="48x48" href="/favicon-48.png" /> 7 <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png" /> 8 <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16.png" /> 9 <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" /> 10 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 11 <meta name="theme-color" content="#f7f3ee" /> 12 13 <title>Signals. An AI CRO audit that ranks a falsifiable backlog.</title> 14 <meta name="description" content="Signals reads your page and your GA4, then returns a ranked, evidence backed A/B test backlog. Every hypothesis is put through an adversarial pass." /> 15 <link rel="canonical" href="https://abtestly.com/signals" /> 16 <meta property="og:title" content="ABTestly Signals. From your URL to a ranked, falsifiable backlog." /> 17 <meta property="og:description" content="An AI CRO audit for teams that test. It reads your page and your GA4, ranks a test backlog, and puts every idea through a pass that argues against it." /> 18 <meta property="og:url" content="https://abtestly.com/signals" /> 19 <meta property="og:type" content="website" /> 20 <meta property="og:logo" content="https://abtestly.com/assets/favicon.svg" /> 21 <meta name="twitter:card" content="summary_large_image" /> 22 <meta property="og:image" content="https://abtestly.com/assets/og/index.png" /> 23 <meta property="og:image:width" content="1200" /> 24 <meta property="og:image:height" content="630" /> 25 <meta name="twitter:image" content="https://abtestly.com/assets/og/index.png" /> 26 27 <!-- Fonts. Same families as the app: Plex Sans + Plex Mono. --> 28 <link rel="preload" href="/assets/fonts/ibm-plex-sans-400.woff2" as="font" type="font/woff2" crossorigin /> 29 <link rel="preload" href="/assets/fonts/ibm-plex-sans-500.woff2" as="font" type="font/woff2" crossorigin /> 30 31 <!-- Theme with no flash. Runs before first paint. --> 32
32<script> 33 (function () { 34 try { 35 var stored = localStorage.getItem('abtestly-theme'); 36 var prefers = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; 37 var theme = stored || 'light'; 38 if (theme === 'dark') document.documentElement.setAttribute('data-theme', 'dark'); 39 var meta = document.querySelector('meta[name="theme-color"]'); 40 if (meta) meta.setAttribute('content', theme === 'dark' ? '#09101b' : '#f7f3ee'); 41 } catch (e) {} 42 })(); 43 </script>
43 44 45 <link rel="stylesheet" href="/consent.css" /> 46
46<script> 47 window.CONSENT_CONFIG = { 48 version: '1.0.0', 49 policyUrl: 'https://abtestly.com/privacy', 50 expiryDays: 180, 51 cookieDomain: location.hostname === 'localhost' ? undefined : '.abtestly.com', 52 scripts: { 53 analytics: [ 54 // ABTestly self-experiment snippet â variant assignment + impression tracking. 55 { src: 'https://cdn.abtestly.com/s/1yi1kvrr1h.js' }, 56 // The exposure bridge, which reports our own experiments to GA4. 57 // /ga4-init.js is deliberately NOT in this list any more: the Google 58 // tag loads from <head> on every page under Consent Mode v2 with 59 // denied defaults, so it stores nothing until a category is granted. 60 { src: '/gtm-bridge.js?v=9c1e3a69' }, 61 ], 62 // The marketing category loads no script of its own. It drives the 63 // three Consent Mode ad signals in /ga4-init.js instead: the Google 64 // Ads tag is a consent STATE there, not a second snippet here. 65 marketing: [], 66 }, 67 }; 68 </script>
68 69
69<script src="/ga4-init.js?v=1d6db3f3" defer></script>
69 70
70<script src="/consent.js?v=99bdab09" defer></script>
70 71 72
72<script type="application/ld+json"> 73 { 74 "@context": "https://schema.org", 75 "@type": "BreadcrumbList", 76 "itemListElement": [ 77 { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://abtestly.com/" }, 78 { "@type": "ListItem", "position": 2, "name": "Signals", "item": "https://abtestly.com/signals" } 79 ] 80 } 81 </script>
81 82 83
83<script type="application/ld+json"> 84{ 85 "@context": "https://schema.org", 86 "@graph": [ 87 { 88 "@type": "Organization", 89 "@id": "https://abtestly.com/#organization", 90 "name": "ABTestly", 91 "url": "https://abtestly.com/", 92 "logo": { 93 "@type": "ImageObject", 94 "url": "https://abtestly.com/assets/logo.svg" 95 } 96 }, 97 { 98 "@type": "WebSite", 99 "@id": "https://abtestly.com/#website", 100 "name": "ABTestly", 101 "url": "https://abtestly.com/", 102 "publisher": { 103 "@id": "https://abtestly.com/#organization" 104 } 105 }, 106 { 107 "@type": "SoftwareApplication", 108 "@id": "https://abtestly.com/signals#software", 109 "name": "ABTestly Signals", 110 "description": "Signals reads your page and your GA4, then returns a ranked, evidence backed A/B test backlog. Every hypothesis is put through an adversarial pass.", 111 "url": "https://abtestly.com/signals", 112 "applicationCategory": "BusinessApplication", 113 "operatingSystem": "Web", 114 "isPartOf": { 115 "@id": "https://abtestly.com/#website" 116 }, 117 "publisher": { 118 "@id": "https://abtestly.com/#organization" 119 } 120 }, 121 { 122 "@type": "WebPage", 123 "@id": "https://abtestly.com/signals", 124 "url": "https://abtestly.com/signals", 125 "name": "ABTestly Signals", 126 "isPartOf": { 127 "@id": "https://abtestly.com/#website" 128 }, 129 "description": "Signals reads your page and your GA4 and returns a ranked, evidence backed A/B test backlog. Every idea is labeled with the evidence it rests on and goes through an adversarial pass. The argument arrives attached when the pass returns one.", 130 "dateModified": "2026-09-19" 131 } 132 ] 133} 134 </script>
134 135 136 <style> 137 /* ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 138 Signals page â section chrome. 139 These section styles (hero, differentiator spine, honesty floor, 140 learning-loop flywheel) are written against the site's own tokens 141 from src/style.css, so light and dark follow the page automatically. 142 The interactive pipeline below is token-aliased instead (see the 143 `.audit, .pmodal` block) and kept structurally verbatim. 144 ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ */ 145 146 /* Scroll reveal â pure CSS progressive enhancement. Non-supporting or 147 reduced-motion visitors get the static, fully visible layout. */ 148 @supports (animation-timeline: view()) { 149 @media (prefers-reduced-motion: no-preference) { 150 .sig-reveal { animation: sigReveal linear both; animation-timeline: view(); animation-range: entry 0% entry 52%; } 151 } 152 } 153 @keyframes sigReveal { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } } 154 155 /* ââ Hero âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ */ 156 .sig-hero { position: relative; padding: clamp(64px, 9vw, 116px) 0 clamp(48px, 7vw, 88px); overflow: hidden; } 157 .sig-hero::before { 158 content: ''; position: absolute; inset: 0; pointer-events: none; 159 background: radial-gradient(52% 42% at 50% -12%, var(--accent-soft) 0%, transparent 70%); opacity: 0.7; 160 } 161 .sig-hero::after { 162 content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none; 163 background-image: 164 linear-gradient(to right, var(--hair) 1px, transparent 1px), 165 linear-gradient(to bottom, var(--hair) 1px, transparent 1px); 166 background-size: 56px 56px; 167 -webkit-mask-image: radial-gradient(115% 78% at 50% -6%, #000 26%, transparent 72%); 168 mask-image: radial-gradient(115% 78% at 50% -6%, #000 26%, transparent 72%); 169 opacity: 0.5; 170 } 171 .sig-hero .container { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; text-align: center; } 172 .sig-hero .eyebrow { display: inline-flex; } 173 /* Sonar beacon on the hero eyebrow â a filled dot with two concentric 174 rings that expand outward and fade on a loop, signalling Beta live 175 status. The dot itself is static; only the rings animate. */ 176 .sig-hero .eyebrow .sonar { position: relative; display: inline-block; width: 6px; height: 6px; margin-left: 2px; border-radius: 50%; background: var(--accent); flex: none; } 177 .sig-hero .eyebrow .sonar::before, 178 .sig-hero .eyebrow .sonar::after { 179 content: ''; position: absolute; inset: 0; border-radius: 50%; 180 border: 1px solid var(--accent); opacity: 0; 181 } 182 @media (prefers-reduced-motion: no-preference) { 183 .sig-hero .eyebrow .sonar::before, 184 .sig-hero .eyebrow .sonar::after { animation: sigSonar 2.6s var(--ease) infinite; } 185 .sig-hero .eyebrow .sonar::after { animation-delay: 1.3s; } 186 } 187 @keyframes sigSonar { 0% { transform: scale(1); opacity: 0.55; } 100% { transform: scale(4.2); opacity: 0; } } 188 .sig-hero h1 { 189 font-size: clamp(38px, 5.6vw, 66px); line-height: 1.03; letter-spacing: -0.03em; 190 color: var(--ink); max-width: 18ch; margin: 22px auto 0; font-weight: 600; text-wrap: balance; 191 } 192 .sig-hero h1 .grad { font-style: normal; } 193 .sig-hero .sig-sub { font-size: clamp(17px, 1.8vw, 20px); line-height: 1.55; color: var(--ink-2); max-width: 60ch; margin: 22px auto 0; } 194 .sig-hero .hero-cta { justify-content: center; margin-top: 32px; } 195 .sig-hero-proof { margin-top: 22px; font-family: var(--font-mono); font-size: 12.5px; color: var(--muted); display: inline-flex; align-items: center; gap: 9px; } 196 .sig-hero-proof .pulse { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); position: relative; flex: none; } 197 .sig-hero-proof .pulse::after { content: ''; position: absolute; inset: -4px; border-radius: 50%; border: 1px solid var(--accent); opacity: 0.4; animation: sigRing 2.4s var(--ease) infinite; } 198 @keyframes sigRing { 0% { transform: scale(0.6); opacity: 0.5; } 100% { transform: scale(1.6); opacity: 0; } } 199 .sig-hero-strip { display: flex; margin-top: 48px; padding-top: 26px; border-top: 1px solid var(--hair); width: 100%; max-width: 760px; align-items: center; justify-content: center; gap: 10px 12px; flex-wrap: wrap; } 200 .sig-hero-strip .pl { font-family: var(--font-mono); font-size: 12px; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3); } 201 .sig-hero-strip .sep { color: var(--hair-strong); display: inline-flex; } 202 .sig-hero-strip .sep svg { width: 15px; height: 15px; } 203 @media (max-width: 640px) { 204 .sig-hero-strip { margin-top: 36px; gap: 8px; } 205 .sig-hero-strip .pl { font-size: 11px; letter-spacing: 0.05em; } 206 .sig-hero-strip .sep svg { width: 12px; height: 12px; } 207 } 208 @media (prefers-reduced-motion: reduce) { 209 .sig-hero-proof .pulse::after { animation: none; } 210 .sig-hero .eyebrow .sonar::before, .sig-hero .eyebrow .sonar::after { display: none; } 211 } 212 213 /* ââ Hero background scene · Converge âââââââââââââââââââââââââââââââââ 214 Ported from the Hypothesisly marketing hero (HeroScene.tsx + 215 .scene-converge in its marketing.css): ten evidence streams flow 216 inward, dashes animating toward a pulsing core. Recolored to the 217 ABTestly accent and driven entirely by this page's own tokens, so it 218 tracks light/dark automatically. Purely decorative and sits behind 219 .sig-hero .container: that element carries z-index:1, which the CSS 220 stacking rules always paint above this scene's implicit z-index:0, 221 regardless of DOM order, so headline/subhead/CTA stay unaffected. */ 222 .sig-hero-scene { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; } 223 .sig-hero-scene svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; } 224 .sig-scene-converge .sig-cv line { stroke: var(--accent); stroke-width: 1.2; opacity: 0.16; stroke-dasharray: 3 11; } 225 .sig-scene-converge .sig-cv-ring { fill: none; stroke: var(--accent); stroke-width: 1.4; opacity: 0.26; transform-box: fill-box; transform-origin: center; } 226 .sig-scene-converge .sig-cv-core { fill: var(--accent); opacity: 0.45; } 227 html[data-theme="dark"] .sig-scene-converge .sig-cv line { opacity: 0.2; } 228 html[data-theme="dark"] .sig-scene-converge .sig-cv-ring { opacity: 0.32; } 229 @media (prefers-reduced-motion: no-preference) { 230 .sig-scene-converge .sig-cv line { animation: sigCvFlow 2.4s linear infinite; } 231 .sig-scene-converge .sig-cv-ring { animation: sigCvRing 3.4s ease-out infinite; } 232 .sig-scene-converge .sig-cv-core { animation: sigCvCore 3.4s ease-in-out infinite; } 233 } 234 /* No prefers-reduced-motion: reduce override needed: the animation 235 property above is scoped inside the no-preference query only, so a 236 reduced-motion visitor simply gets the static rest state (dashed 237 lines, resting ring and core opacity) with zero motion. */ 238 @keyframes sigCvFlow { to { stroke-dashoffset: -14; } } 239 @keyframes sigCvRing { 0% { transform: scale(0.4);
239 opacity: 0.44; } 100% { transform: scale(3.2); opacity: 0; } } 240 @keyframes sigCvCore { 0%, 100% { opacity: 0.38; } 50% { opacity: 0.68; } } 241 242 /* ââ Wide pipeline wrapper (spans near the viewport, with side padding) â */ 243 .sig-wide { max-width: min(1600px, 94vw); margin: 40px auto 0; padding: 0 clamp(16px, 4vw, 40px); } 244 .sig-pipe-more { text-align: center; margin-top: 28px; font-size: 15px; color: var(--ink-3); } 245 .sig-pipe-more a { color: var(--accent-ink); font-weight: 500; } 246 .sig-pipe-more a:hover { color: var(--accent); } 247 248 /* ââ Differentiators â flowing spine timeline âââââââââââââââââââââââââ */ 249 .sig-diff { position: relative; max-width: 880px; margin: 0 auto; } 250 .sig-diff-item { position: relative; display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: clamp(24px, 4vw, 56px); padding: 0 0 clamp(40px, 5vw, 64px) 46px; align-items: start; } 251 .sig-diff-item:last-child { padding-bottom: 0; } 252 .sig-diff-item::before { content: ''; position: absolute; left: 6px; top: 14px; bottom: -2px; width: 2px; background: linear-gradient(180deg, var(--accent) 0%, var(--accent-ring) 70%, transparent 100%); opacity: 0.5; } 253 .sig-diff-item:last-child::before { background: linear-gradient(180deg, var(--accent) 0%, transparent 92%); } 254 .sig-diff-node { position: absolute; left: 0; top: 7px; width: 14px; height: 14px; border-radius: 50%; background: var(--surface); border: 2px solid var(--accent); z-index: 1; } 255 .sig-diff-node::after { content: ''; position: absolute; inset: 2px; border-radius: 50%; background: var(--accent); opacity: 0.85; transform-origin: center; } 256 @media (prefers-reduced-motion: no-preference) { 257 .sig-diff-node::after { animation: sigNode 3.6s ease-in-out infinite; } 258 .sig-diff-item:nth-child(2) .sig-diff-node::after { animation-delay: 1.2s; } 259 .sig-diff-item:nth-child(3) .sig-diff-node::after { animation-delay: 2.4s; } 260 } 261 @keyframes sigNode { 0%, 100% { transform: scale(1); opacity: 0.85; } 50% { transform: scale(1.35); opacity: 0.5; } } 262 .sig-diff-term { display: flex; flex-direction: column; gap: 10px; } 263 .sig-diff-term .k { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.07em; text-transform: uppercase; color: var(--accent-ink); display: inline-flex; align-items: center; gap: 8px; } 264 .sig-diff-term .tag { font-family: var(--font-mono); font-size: 12px; color: var(--muted); } 265 .sig-diff-body h3 { font-size: clamp(20px, 2vw, 27px); line-height: 1.22; letter-spacing: -0.02em; margin: 0 0 12px; text-wrap: balance; color: var(--ink); font-weight: 600; } 266 .sig-diff-body p { font-size: 16px; line-height: 1.65; color: var(--ink-2); margin: 0; max-width: 56ch; text-wrap: pretty; } 267 .sig-diff-body p b { color: var(--ink); font-weight: 600; } 268 @media (max-width: 760px) { 269 .sig-diff-item { grid-template-columns: 1fr; gap: 14px; padding-left: 38px; } 270 .sig-diff-term { flex-direction: row; align-items: center; justify-content: space-between; gap: 12px; } 271 } 272 273 /* ââ Honesty floor â editorial divided manifesto ââââââââââââââââââââââ */ 274 .sig-floor { display: grid; grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.7fr); gap: clamp(36px, 6vw, 84px); align-items: start; } 275 .sig-floor-head { position: sticky; top: 96px; } 276 .sig-floor-head .eyebrow { display: inline-flex; margin-bottom: 16px; } 277 .sig-floor-head h2 { margin: 0 0 16px; font-size: clamp(28px, 3.6vw, 40px); letter-spacing: -0.022em; line-height: 1.1; color: var(--ink); } 278 .sig-floor-head p { font-size: 16.5px; line-height: 1.62; color: var(--ink-3); max-width: 32ch; margin: 0; text-wrap: pretty; } 279 .sig-floor-list { display: flex; flex-direction: column; } 280 .sig-floor-item { display: grid; grid-template-columns: auto 1fr; gap: clamp(20px, 3vw, 40px); padding: clamp(24px, 3vw, 34px) 0; border-top: 1px solid var(--hair); align-items: baseline; } 281 .sig-floor-item:first-child { border-top: 0; padding-top: 4px; } 282 .sig-floor-n { font-family: var(--font-mono); font-size: clamp(30px, 3.4vw, 46px); font-weight: 500; line-height: 0.9; color: var(--hair-strong); font-variant-numeric: tabular-nums; letter-spacing: -0.03em; transition: color 0.25s var(--ease); }
283 .sig-floor-item:hover .sig-floor-n { color: var(--accent); } 284 .sig-floor-body h3 { font-size: clamp(19px, 1.6vw, 23px); letter-spacing: -0.015em; margin: 0 0 9px; text-wrap: balance; color: var(--ink); font-weight: 600; } 285 .sig-floor-body p { font-size: 16px; line-height: 1.65; color: var(--ink-2); max-width: 60ch; margin: 0; text-wrap: pretty; } 286 .sig-floor-body p b { color: var(--ink); font-weight: 600; } 287 @media (max-width: 860px) { 288 .sig-floor { grid-template-columns: 1fr; gap: 28px; } 289 .sig-floor-head { position: static; } 290 } 291 292 /* ââ Learning-loop flywheel âââââââââââââââââââââââââââââââââââââââââââ */ 293 .sig-loop { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px; max-width: 960px; margin: 0 auto; } 294 .sig-loop-node { font-family: var(--font-mono); font-size: 12.5px; color: var(--ink-2); background: var(--surface); border: 1px solid var(--hair); border-radius: var(--r-pill); padding: 8px 16px; box-shadow: var(--shadow-sm); } 295 .sig-loop-node--accent { color: var(--accent-ink); background: var(--accent-soft); border-color: var(--accent); } 296 .sig-loop-arrow { font-family: var(--font-mono); color: var(--muted); font-size: 14px; } 297 .sig-loop-arrow--back { color: var(--accent); font-size: 17px; } 298 @media (max-width: 620px) { .sig-loop { flex-direction: column; } .sig-loop-arrow { transform: rotate(90deg); } } 299 .sig-note { display: flex; align-items: flex-start; gap: 14px; max-width: 760px; margin: 40px auto 0; padding: 18px 22px; border: 1px solid var(--hair); border-radius: var(--r-4); background: var(--surface-2); } 300 .sig-note-k { font-family: var(--font-mono); font-size: 11px; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--accent-ink); flex: 0 0 auto; margin-top: 2px; } 301 .sig-note p { font-size: 14.5px; line-height: 1.6; color: var(--ink-2); margin: 0; } 302 303 /* ââ Pricing â free in Beta, priced by scans after ââââââââââââââââââââ */ 304 .sig-pricing .plan-grid { grid-template-columns: repeat(3, 1fr); max-width: 900px; margin: var(--s-7) auto 0; } 305 .sig-pricing .plan-desc { min-height: 0; margin-bottom: 0; } 306 .sig-pricing .plan-price { margin-top: var(--s-2); } 307 @media (max-width: 760px) { 308 .sig-pricing .plan-grid { grid-template-columns: 1fr; max-width: 420px; } 309 } 310 311 /* ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 312 Pipeline token aliases. 313 The interactive pipeline below is ported structurally verbatim; it 314 uses its own internal token names. Here we map those onto the site's 315 tokens so the diagram inherits the page's own light and dark. Tokens 316 whose names already match the site (--ink, --ink-2, --ink-3, --warn, 317 --warn-ink, --warn-soft, --shadow-md, --font-sans, --font-mono, 318 --t-base, --ease) are intentionally NOT re-declared: they inherit 319 straight from :root, and a self-referential alias (e.g. --ink: var(--ink)) 320 would be a cyclic, invalid-at-computed-value declaration. The block is 321 scoped to BOTH roots because the modal (.pmodal) is a sibling of the 322 diagram, not a descendant of .audit. 323 ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ */ 324 .audit, .pmodal { 325 --canvas: var(--bg); 326 --paper: var(--surface); 327 --paper-2: var(--surface-2); 328 --well: var(--surface-3); 329 --line: var(--hair); 330 --line-2: var(--hair-soft, var(--hair)); 331 --line-strong: var(--hair-strong); 332 --ink-4: var(--muted); 333 --ink-5: var(--hair-strong); 334 --brand: var(--accent); 335 --brand-600: var(--accent-hover); 336 --brand-700: var(--accent-ink); 337 --brand-soft: var(--accent-soft); 338 --brand-soft-2: var(--accent-soft-2); 339 --brand-ring: var(--accent-ring); 340 --scrim: rgba(0, 0, 0, 0.5); 341 --shadow-xs: var(--shadow-sm); 342 343 /* Falsification accent: no site token exists, so define it literally. */ 344 --neg: #c2410c; 345 --neg-soft: #f6e4d9; 346 347 /* Structural tokens the pipeline needs that the site does not name. */ 348 --r-xs: 5px; 349 --r-sm: 7px; 350 --r-md: 9px; 351 --r-lg: 11px; 352 --r-xl: 14px; 353 --r-2xl: 18px; 354 --r-pill: 999px;
355 --ease-spring: cubic-bezier(0.34, 1.32, 0.46, 1); 356 } 357 [data-theme="dark"] .audit, [data-theme="dark"] .pmodal { 358 --neg: #e79457; 359 --neg-soft: rgba(231, 148, 87, 0.18); 360 } 361 362 /* ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 363 Pipeline diagram â structure and rule set ported verbatim. Only the 364 palette resolves through the aliases above. 365 ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ */ 366 367 /* ââ Audit canvas (the pipeline sits on a bordered card) âââââââââââââââ */ 368 .audit { 369 container-type: inline-size; 370 border: 1px solid var(--line); 371 border-radius: var(--r-2xl); 372 background: 373 radial-gradient(130% 90% at 0% 0%, var(--brand-soft-2) 0%, transparent 44%), 374 var(--paper); 375 box-shadow: var(--shadow-md); 376 padding: 30px 30px 32px; 377 overflow: hidden; 378 } 379 380 /* ââ Full pipeline diagram (three streams converge â refine) âââââââââââ */ 381 .pipe-cap { display: flex; justify-content: space-between; gap: 16px; margin-bottom: 20px; flex-wrap: wrap; } 382 .pipe-cap span { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--brand-700); display: inline-flex; align-items: center; gap: 7px; text-wrap: pretty; } 383 .pipe-cap .r { color: var(--ink-4); } 384 .pipe-cap .r::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--ink-5); } 385 386 .pipe-diagram { display: flex; align-items: stretch; } 387 .pipe-inputs { flex: 0 0 232px; display: flex; flex-direction: column; gap: 10px; } 388 .pipe-inputs .pnode { flex: 1; flex-direction: row; align-items: flex-start; gap: 11px; padding: 13px; }
389 .pipe-inputs .pn-ic { margin-top: 1px; } 390 .pipe-inputs .pn-col { display: flex; flex-direction: column; gap: 7px; min-width: 0; } 391 .pipe-inputs .pn-n { margin-top: 2px; } 392 .pipe-merge { flex: 0 0 50px; align-self: stretch; color: var(--line-strong); } 393 .pipe-merge svg { width: 100%; height: 100%; display: block; } 394 .pipe-merge path { fill: none; stroke: currentColor; stroke-width: 1.5; } 395 .pchain { flex: 1 1 0; min-width: 0; display: flex; align-items: center; } 396 .pipe-arrow { display: flex; align-items: center; justify-content: center; color: var(--ink-5); padding: 0 7px; flex: 0 0 auto; } 397 .pipe-arrow svg { width: 19px; height: 19px; } 398 399 .pnode { background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 14px; box-shadow: var(--shadow-xs); display: flex; flex-direction: column; gap: 9px; width: 100%; } 400 .pn-head { display: flex; align-items: center; gap: 9px; } 401 .pn-ic { width: 30px; height: 30px; flex: none; border-radius: var(--r-sm); background: var(--brand-soft); color: var(--brand); display: grid; place-items: center; } 402 .pn-ic svg { width: 16px; height: 16px; } 403 .pn-n { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-4); } 404 .pn-t { font-size: 13.5px; font-weight: 500; color: var(--ink); letter-spacing: -0.01em; line-height: 1.25; } 405 .pn-d { font-size: 11.5px; line-height: 1.45; color: var(--ink-3); } 406 .pnode.is-hub { border-color: var(--brand-ring); background: linear-gradient(180deg, var(--brand-soft-2), var(--paper) 72%); } 407 .pnode.is-fals .pn-ic { background: var(--neg-soft); color: var(--neg); } 408 .pn-tags { display: flex; flex-wrap: wrap; gap: 5px;
408 margin-top: 1px; min-width: 0; } 409 .audit .pchain, .audit .pnode, .audit .pn-col, .audit .pn-head { min-width: 0; } 410 .audit .pn-t, .audit .pn-d { overflow-wrap: anywhere; text-wrap: pretty; } 411 .pn-tag { font-family: var(--font-mono); font-size: 9.5px; line-height: 1.45; letter-spacing: 0.01em; color: var(--ink-3); background: var(--well); border: 1px solid var(--line-2); border-radius: var(--r-xs); padding: 2px 6px; white-space: normal; max-width: 100%; overflow-wrap: anywhere; } 412 .pn-tag.b { color: var(--brand-700); background: var(--brand-soft); border-color: transparent; } 413 .pn-tag.q { color: var(--warn-ink); background: var(--warn-soft); border-color: transparent; } 414 415 .pipe-foot { display: flex; justify-content: space-between; align-items: center; gap: 14px 28px; flex-wrap: wrap; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line-2); font-family: var(--font-mono); font-size: 11px; color: var(--ink-4); } 416 .pipe-foot span { display: inline-flex; align-items: center; gap: 7px; } 417 .pipe-foot span::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--brand); flex: none; } 418 .pipe-foot b { color: var(--ink-3); font-weight: 500; } 419 420 @container (max-width: 980px) { 421 .pipe-diagram { flex-direction: column; gap: 10px; } 422 .pipe-inputs { flex: none; flex-direction: row; } 423 .pipe-inputs .pnode { flex: 1 1 0; } 424 .pipe-merge { flex: none; height: 24px; width: 100%; } 425 .pipe-merge svg { display: none; } 426 .pipe-merge::after { content: ''; display: block; width: 1.5px; height: 100%; margin: 0 auto; background: var(--line-strong); } 427 .pchain { flex: none; } 428 .pipe-arrow { padding: 2px 0; } 429 .pipe-arrow svg { transform: rotate(90deg); } 430 } 431 @container (max-width: 620px) { 432 .pipe-inputs { flex-direction: column; } 433 } 434 435 /* ââ Pipeline looping explainer (animations) âââââââââââââââââââââââââââ */ 436 @media (prefers-reduced-motion: no-preference) { 437 .audit .pipe-merge path { stroke: var(--brand); stroke-dasharray: 5 9; animation: pipeMergeFlow 1.4s linear infinite; } 438 .audit .pnode { position: relative; } 439 .audit .pnode::after { 440 content: ''; position: absolute; inset: -2px; border-radius: 13px; 441 box-shadow: 0 0 0 1.5px var(--brand-ring), 0 12px 36px -6px var(--brand-ring); 442 opacity: 0; pointer-events: none; transform-origin: center; 443 animation: pipeBeat 8.5s cubic-bezier(0.37, 0, 0.34, 1) infinite; 444 } 445 .audit .pnode.is-fals::after { box-shadow: 0 0 0 1.5px var(--neg), 0 12px 36px -6px var(--neg-soft); } 446 .audit .pipe-inputs .pnode:nth-child(1)::after { animation-delay: 0s; } 447 .audit .pipe-inputs .pnode:nth-child(2)::after { animation-delay: 0.13s; } 448 .audit .pipe-inputs .pnode:nth-child(3)::after { animation-delay: 0.26s; } 449 .audit .pipe-diagram > .pchain:nth-child(3) .pnode::after { animation-delay: 1.05s; } 450 .audit .pipe-diagram > .pchain:nth-child(5) .pnode::after { animation-delay: 1.95s; } 451 .audit .pipe-diagram > .pchain:nth-child(7) .pnode::after { animation-delay: 2.85s; } 452 .audit .pipe-diagram > .pchain:nth-child(9) .pnode::after { animation-delay: 3.75s; } 453 .audit .pipe-arrow svg { animation: pipeArrowGlide 8.5s cubic-bezier(0.37, 0, 0.34, 1) infinite; will-change: transform, opacity; } 454 .audit .pipe-diagram > .pipe-arrow:nth-child(4) svg { animation-delay: 1.5s; } 455 .audit .pipe-diagram > .pipe-arrow:nth-child(6) svg { animation-delay: 2.4s; } 456 .audit .pipe-diagram > .pipe-arrow:nth-child(8) svg { animation-delay: 3.3s; } 457 } 458 @keyframes pipeMergeFlow { to { stroke-dashoffset: -14; } } 459 @keyframes pipeBeat { 460 0% { opacity: 0; transform: scale(0.965); } 461 6% { opacity: 0.9; transform: scale(1.004); } 462 11% { opacity: 1; transform: scale(1.012); } 463 18% { opacity: 0.55; transform: scale(1.022); } 464 26% { opacity: 0; transform: scale(1.032); } 465 100% { opacity: 0; transform: scale(0.965); } 466 } 467 @keyframes pipeArrowGlide { 468 0% { opacity: 0.4; transform: translateX(-3px); color: var(--ink-5); } 469 7% { opacity: 1; transform: translateX(2px); color: var(--brand); } 470 16% { opacity: 0.6; transform: translateX(3px); color: var(--brand); } 471 26% { opacity: 0.4; transform: translateX(-3px); color: var(--ink-5); } 472 100% { opacity: 0.4; transform: translateX(-3px); color: var(--ink-5); } 473 } 474 475 /* ââ Clickable stage cards + expand badge + tap hint âââââââââââââââââââ */ 476 .audit .pipe-diagram .pnode { cursor: pointer; padding-right: 30px; transition: transform 0.16s var(--ease), box-shadow 0.16s var(--ease), border-color 0.16s var(--ease); } 477 .audit .pipe-diagram .pnode:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--brand-ring); } 478 .audit .pipe-diagram .pnode:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; } 479 .audit .pn-more { position: absolute; top: 8px; right: 8px;
479 width: 20px; height: 20px; border-radius: 6px; display: grid; place-items: center; color: var(--ink-4); background: var(--well); border: 1px solid var(--line-2); transition: color 0.15s var(--ease), background 0.15s var(--ease), border-color 0.15s var(--ease); } 480 .audit .pn-more svg { width: 11px; height: 11px; } 481 .audit .pipe-diagram .pnode:hover .pn-more { color: #fff; background: var(--brand); border-color: transparent; } 482 .audit .pipe-hint { display: flex; width: fit-content; margin: 18px auto 0; align-items: center; gap: 7px; font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.03em; color: var(--brand-700); background: var(--brand-soft); border-radius: var(--r-pill); padding: 6px 13px; } 483 .audit .pipe-hint svg { width: 13px; height: 13px; color: var(--brand); } 484 485 /* ââ Feedback loop: 07 Output â logged outcomes â 01 Intake ââââââââââââ */ 486 .audit .pipe-loop { position: relative; height: 54px; margin: 16px 8px 2px; } 487 .audit .pl-bracket { position: absolute; left: 10px; right: 10px; top: 13px; bottom: 8px; border: 2px dashed var(--brand); border-top: 0; border-radius: 0 0 18px 18px; opacity: 0.55; } 488 .audit .pl-arrow { position: absolute; left: 4px; top: 1px; width: 0; height: 0; border-left: 7px solid transparent; border-right: 7px solid transparent; border-bottom: 11px solid var(--brand); } 489 .audit .pl-dot { position: absolute; bottom: 4px; left: calc(100% - 18px); width: 9px; height: 9px; border-radius: 50%; background: var(--brand); box-shadow: 0 0 0 4px var(--brand-soft); opacity: 0; z-index: 2; } 490 .audit .pl-from, .audit .pl-to { position: absolute; top: 2px; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-4); background: var(--paper); padding: 0 6px; } 491 .audit .pl-from { right: 12px; } 492 .audit .pl-to { left: 24px; } 493 .audit .pl-tag { position: absolute; left: 50%; top: 46px; transform: translate(-50%, -50%); display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-family: var(--font-mono); font-size: 11.5px; color: var(--brand-700); background: var(--paper); border: 1px solid var(--brand-ring); border-radius: var(--r-pill); padding: 6px 14px; box-shadow: var(--shadow-xs); white-space: nowrap; transition: border-color var(--t-base); } 494 .audit .pl-tag:hover { border-color: var(--brand); } 495 .audit .pl-tag:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; } 496 .audit .pl-tag svg { width: 14px; height: 14px; color: var(--brand); } 497 @container (max-width: 980px) { 498 .audit .pipe-loop { height: auto; margin-top: 16px; text-align: center; } 499 .audit .pl-bracket, .audit .pl-arrow, .audit .pl-dot, .audit .pl-from, .audit .pl-to { display: none; } 500 .audit .pl-tag { position: static; transform: none; } 501 } 502 @media (prefers-reduced-motion: no-preference) { 503 .audit .pl-bracket { animation: plLoopBeat 8.5s ease-in-out infinite; } 504 .audit .pl-dot { animation: plLoopDot 8.5s cubic-bezier(0.45, 0.05, 0.3, 1) infinite; } 505 } 506 @keyframes plLoopBeat { 0%, 50%, 100% { opacity: 0.45; } 60% { opacity: 0.95; } 82% { opacity: 0.95; } 90% { opacity: 0.45; } } 507 @keyframes plLoopDot { 508 0%, 52% { left: calc(100% - 18px); opacity: 0; } 509 57% { left: calc(100% - 18px); opacity: 1; } 510 80% { left: 9px; opacity: 1; } 511 86%, 100% { left: 9px; opacity: 0; } 512 } 513 514 /* ââ Stage detail modal ââââââââââââââââââââââââââââââââââââââââââââââââ */ 515 .pmodal[hidden] { display: none; } 516 .pmodal { position: fixed; inset: 0; z-index: 120; display: grid; place-items: center; padding: 24px; } 517 .pmodal-scrim { position: absolute; inset: 0; background: var(--scrim); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); animation: pmFade 0.2s ease; } 518 .pmodal-panel { position: relative; width: min(560px, 100%); max-height: 86vh; overflow: auto; background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-2xl); box-shadow: var(--shadow-md); padding: 26px 26px 24px; animation: pmRise 0.3s var(--ease-spring); } 519 @keyframes pmFade { from { opacity: 0; } } 520 @keyframes pmRise { from { opacity: 0; transform: translateY(14px) scale(0.985); } } 521 .pmodal-x { position: absolute; top: 14px; right: 14px; width: 32px; height: 32px; border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--paper); color: var(--ink-3); display: grid; place-items: center; cursor: pointer; transition: color 0.15s, background 0.15s; } 522 .pmodal-x:hover { background: var(--paper-2); color: var(--ink); } 523 .pmodal-x svg { width: 16px; height: 16px; } 524 .pmodal-head { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 16px; padding-right: 30px; } 525 .pmodal-head > div { display: flex; flex-direction: column; gap: 3px; padding-top: 2px; } 526 .pmodal-ic { width: 44px; height: 44px; flex: none; border-radius: var(--r-md); background: var(--brand-soft); color: var(--brand); display: grid; place-items: center; } 527 .pmodal-ic.neg { background: var(--neg-soft); color: var(--neg); } 528 .pmodal-ic svg { width: 22px; height: 22px; } 529 .pmodal-eyebrow { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-4); } 530 .pmodal-title { font-size: 21px; letter-spacing: -0.02em; color: var(--ink); line-height: 1.15; margin: 0; font-weight: 500; } 531 .pmodal-lead { font-size: 15px; line-height: 1.6; color: var(--ink-2); margin: 0 0 16px; } 532 .pmodal-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 11px; } 533 .pmodal-list li { display: flex; gap: 10px; } 534 .pmodal-list li::before { content: ''; flex: none; width: 6px; height: 6px; margin-top: 7px; border-radius: 50%; background: var(--brand); } 535 .pmodal-list li span { font-size: 14px; line-height: 1.5; color: var(--ink-2); } 536 .pmodal-list li span b { color: var(--ink); font-weight: 500; } 537 .pmodal-note { margin-top: 18px; padding: 13px 15px; border-radius: var(--r-lg); background: var(--well); border: 1px solid var(--line-2); font-size: 13px; line-height: 1.55; color: var(--ink-3); display: flex; gap: 9px; } 538 .pmodal-note svg { width: 15px; height: 15px; flex: none; margin-top: 2px; color: var(--ink-4); } 539 .pmodal-note.warn { background: var(--warn-soft); border-color: transparent; color: var(--warn-ink); } 540 .pmodal-note.warn svg { color: var(--warn); } 541 </style> 542
542<script type="module" crossorigin src="/assets/modulepreload-polyfill-B5Qt9EMX.js"></script>
542 543
543<script type="module" crossorigin src="/assets/main-CRu3pe50.js"></script>
543 544 <link rel="stylesheet" crossorigin href="/assets/main-C0jWISLR.css"> 545</head> 546<body> 547 548 <!-- =================== HEADER =================== --> 549 <header class="site-header"> 550 <nav class="nav" aria-label="Primary"> 551 <a class="brand" href="/" aria-label="ABTestly home"> 552 <svg class="brand-mark" viewBox="0 0 220 92" aria-hidden="true" focusable="false"><rect class="brand-mark-top" x="0" y="0" width="132" height="34" rx="17"/><path class="brand-mark-win" d="M17 58 A17 17 0 0 0 17 92 L196 92 L208 58 Z"/></svg><span class="brand-word">ABTestly</span> 553 </a> 554 <ul class="nav-links" role="list"> 555 <li><a href="/#how-it-works">How it works</a></li> 556 <li><a href="/signals" aria-current="page">Signals</a></li> 557 <li><a href="/compare">Compare</a></li> 558 <li><a href="/#developers">Developers</a></li> 559 <li><a href="/pricing">Pricing</a></li> 560 <li><a href="https://docs.abtestly.com" target="_blank" rel="noopener noreferrer">Docs</a></li> 561 </ul> 562 <div class="nav-actions"> 563 <button class="theme-toggle" type="button" data-theme-toggle aria-label="Toggle dark mode" title="Toggle theme"> 564 <svg class="icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></svg> 565 <svg class="icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 12.79A9 9 0 1 1 11.21 3a7 7 0 0 0 9.79 9.79z"/></svg> 566 </button> 567 <a class="btn btn-ghost" href="https://app.abtestly.com/sign-in">Log in</a> 568 <a class="btn btn-primary" href="https://app.abtestly.com/sign-up">Start free trial</a> 569 </div> 570 </nav> 571 </header> 572 573 <main> 574 575 <!-- =================== 1 · HERO =================== --> 576 <section class="sig-hero"> 577 <div class="sig-hero-scene" aria-hidden="true"> 578 <svg class="sig-scene-converge" viewBox="0 0 1200 600" preserveAspectRatio="xMidYMid slice"> 579 <g class="sig-cv"> 580 <line x1="-60" y1="40" x2="600" y2="300"/> 581 <line x1="300" y1="-50" x2="600" y2="300"/> 582 <line x1="700" y1="-60" x2="600" y2="300"/> 583 <line x1="1260" y1="30" x2="600" y2="300"/> 584 <line x1="1290" y1="300" x2="600" y2="300"/> 585 <line x1="1260" y1="560" x2="600" y2="300"/> 586 <line x1="760" y1="660" x2="600" y2="300"/> 587 <line x1="320" y1="650" x2="600" y2="300"/> 588 <line x1="-70" y1="560" x2="600" y2="300"/> 589 <line x1="-90" y1="300" x2="600" y2="300"/> 590 </g> 591 <circle class="sig-cv-ring" cx="600" cy="300" r="14"/> 592 <circle class="sig-cv-core" cx="600" cy="300" r="5"/> 593 </svg> 594 </div> 595 <div class="container"> 596 <span class="eyebrow">Signals · Beta<span class="sonar" aria-hidden="true"></span></span> 597 <h1>AI powered hypothesis generation, <span class="grad">ranked and falsifiable.</span></h1> 598 <p class="sig-sub"> 599 ABTestly is a code first A/B testing platform. Signals is its optional CRO audit add on: it reads your page and your GA4, then generates a ranked, evidence graded backlog of A/B test hypotheses. Every idea is graded on its evidence and put through a pass that argues against it. 600 </p> 601 <div class="hero-cta"> 602 <a class="btn btn-primary btn-lg" href="https://app.abtestly.com/sign-up">Start your free trial <span class="arrow" aria-hidden="true">→</span></a> 603 <a class="btn btn-secondary btn-lg" href="https://docs.abtestly.com/signals/overview" target="_blank" rel="noopener noreferrer">Read the docs</a> 604 </div> 605 <div class="sig-hero-proof"> 606 <span class="pulse" aria-hidden="true"></span>In beta. It runs on the Anthropic commercial API, whose terms do not use your data to train models. 607 </div> 608 <div class="sig-hero-strip" aria-hidden="true">
609 <span class="pl">Evidence</span> 610 <span class="sep"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span> 611 <span class="pl">Payload</span> 612 <span class="sep"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span> 613 <span class="pl">Generation</span> 614 <span class="sep"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span> 615 <span class="pl">Falsification</span> 616 <span class="sep"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span> 617 <span class="pl">Ranked backlog</span> 618 </div> 619 </div> 620 </section> 621 622 <!-- =================== 2 · HOW A SCAN WORKS (pipeline) =================== --> 623 <section class="section" id="how-it-works" style="border-top:1px solid var(--hair); background: var(--surface); padding-top: var(--s-11); padding-bottom: var(--s-11);"> 624 <div class="container"> 625 <div class="section-head center sig-reveal"> 626 <span class="eyebrow" style="display:inline-flex;">how a scan works</span> 627 <h2>Three evidence streams. <em class="grad">One ranked backlog.</em></h2> 628 <p>Seven stages with a shape. Three evidence streams converge into one multimodal payload, then Signals generates hypotheses, argues against its own work, and ranks what it found. Tap any stage to see inside it.</p> 629 </div> 630 </div> 631 632 <div class="sig-wide sig-reveal"> 633 <div class="audit"> 634 <div class="pipe-cap"> 635 <span>Evidence in · three parallel streams</span> 636 <span class="r">Reasoning · narrowed to a ranked backlog</span> 637 </div> 638 <div class="pipe-diagram"> 639 <div class="pipe-inputs"> 640 <div class="pnode" data-stage="1" role="button" tabindex="0" aria-haspopup="dialog"> 641 <span class="pn-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v18M3 8h6M3 16h6M15 8h6M15 16h6"/></svg></span> 642 <div class="pn-col"><span class="pn-n">01 · Intake</span><div class="pn-t">Site & business context</div><div class="pn-tags"><span class="pn-tag">URL plus context</span><span class="pn-tag">connect GA4</span><span class="pn-tag b">sets what a scan can read</span></div></div> 643 <span class="pn-more" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h6v6"/><path d="M9 21H3v-6"/><path d="M21 3l-7 7"/><path d="M3 21l7-7"/></svg></span> 644 </div> 645 <div class="pnode" data-stage="2" role="button" tabindex="0" aria-haspopup="dialog"> 646 <span class="pn-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="14" rx="2"/><path d="M3 8h18M8 21h8"/></svg></span> 647 <div class="pn-col"><span class="pn-n">02 · Capture</span><div class="pn-t">DOM, renders, funnel walks</div><div class="pn-tags"><span class="pn-tag b">20 plus DOM signals</span><span class="pn-tag">desktop and mobile</span><span class="pn-tag">throttled view</span></div></div> 648 <span class="pn-more" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h6v6"/><path d="M9 21H3v-6"/><path d="M21 3l-7 7"/><path d="M3 21l7-7"/></svg></span> 649 </div> 650 <div class="pnode" data-stage="3" role="button" tabindex="0" aria-haspopup="dialog">
651 <span class="pn-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3v18h18"/><rect x="7" y="11" width="3" height="6"/><rect x="13" y="7" width="3" height="10"/></svg></span> 652 <div class="pn-col"><span class="pn-n">03 · Behaviour</span><div class="pn-t">GA4 funnel and drop off</div><div class="pn-tags"><span class="pn-tag">device CVR and channels</span><span class="pn-tag">funnel drop off</span></div></div> 653 <span class="pn-more" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h6v6"/><path d="M9 21H3v-6"/><path d="M21 3l-7 7"/><path d="M3 21l7-7"/></svg></span> 654 </div> 655 </div> 656 <div class="pipe-merge" aria-hidden="true"><svg viewBox="0 0 50 100" preserveAspectRatio="none"><path d="M2 16 C 28 16 24 50 48 50" vector-effect="non-scaling-stroke"/><path d="M2 50 H 48" vector-effect="non-scaling-stroke"/><path d="M2 84 C 28 84 24 50 48 50" vector-effect="non-scaling-stroke"/></svg></div> 657 <div class="pchain"><div class="pnode is-hub" data-stage="4" role="button" tabindex="0" aria-haspopup="dialog"> 658 <div class="pn-head"><span class="pn-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7h6l6 5"/><path d="M4 17h6l6-5"/><circle cx="18" cy="12" r="2" fill="currentColor" stroke="none"/></svg></span><span class="pn-n">04 · Payload</span></div> 659 <div class="pn-t">Multimodal payload assembled</div><div class="pn-d">Three image blocks plus structured evidence, combined into one prompt.</div><div class="pn-tags"><span class="pn-tag">3 images + text</span><span class="pn-tag">vision reconciled</span></div> 660 <span class="pn-more" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h6v6"/><path d="M9 21H3v-6"/><path d="M21 3l-7 7"/><path d="M3 21l7-7"/></svg></span> 661 </div></div> 662 <div class="pipe-arrow"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg></div> 663 <div class="pchain"><div class="pnode" data-stage="5" role="button" tabindex="0" aria-haspopup="dialog"> 664 <div class="pn-head"><span class="pn-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l2.4 4.9 5.4.8-3.9 3.8.9 5.4L12 15.6l-4.8 2.5.9-5.4L4.2 8.7l5.4-.8z"/></svg></span><span class="pn-n">05 · Generation</span></div> 665 <div class="pn-t">Grounded hypotheses</div><div class="pn-d">Each tied to a behavioral mechanism and a citation; thin evidence is labeled, not inflated.</div><div class="pn-tags"><span class="pn-tag b">structured fields</span><span class="pn-tag b">8 yes or no answers</span><span class="pn-tag">5 CRO pillars</span><span class="pn-tag">two signal gate</span></div> 666 <span class="pn-more" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h6v6"/><path d="M9 21H3v-6"/><path d="M21 3l-7 7"/><path d="M3 21l7-7"/></svg></span> 667 </div></div> 668 <div class="pipe-arrow"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg></div> 669 <div class="pchain"><div class="pnode is-fals" data-stage="6" role="button" tabindex="0" aria-haspopup="dialog"> 670 <div class="pn-head"><span class="pn-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 9v4M12 17h.01"/><path d="M10.3 3.9 2 18a2 2 0 0 0 1.7 3h16.6a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"/></svg></span><span class="pn-n">06 · Falsification</span></div> 671 <div class="pn-t">Argued against itself</div><div class="pn-d">Failure mode, confounder, alternative, and the test that settles it.</div><div class="pn-tags"><span class="pn-tag q">adversarial second pass</span></div>
672 <span class="pn-more" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h6v6"/><path d="M9 21H3v-6"/><path d="M21 3l-7 7"/><path d="M3 21l7-7"/></svg></span> 673 </div></div> 674 <div class="pipe-arrow"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg></div> 675 <div class="pchain"><div class="pnode is-out" data-stage="7" role="button" tabindex="0" aria-haspopup="dialog"> 676 <div class="pn-head"><span class="pn-ic"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 4h11l3 3v13H5z"/><path d="M9 9h6M9 13h6M9 17h4"/></svg></span><span class="pn-n">07 · Output</span></div> 677 <div class="pn-t">Structured hypotheses, ranked</div><div class="pn-d">Ordered by PXL, each with its evidence tier, effort and a tracking spec.</div><div class="pn-tags"><span class="pn-tag b">PXL ranked</span><span class="pn-tag">4 evidence tiers</span><span class="pn-tag">ready to build</span></div> 678 <span class="pn-more" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h6v6"/><path d="M9 21H3v-6"/><path d="M21 3l-7 7"/><path d="M3 21l7-7"/></svg></span> 679 </div></div> 680 </div> 681 <div class="pipe-hint"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 9l5 12 1.8-5.2L21 14 9 9z"/></svg>Tap any stage to see what happens inside it</div> 682 <div class="pipe-loop" aria-label="Feedback loop: experiment outcomes feed back as priors for the next scan"> 683 <span class="pl-to">into 01 · Intake</span> 684 <span class="pl-from">from 07 · Output</span> 685 <div class="pl-bracket"></div> 686 <span class="pl-arrow"></span> 687 <span class="pl-dot"></span> 688 <span class="pl-tag" data-stage="loop" role="button" tabindex="0" aria-haspopup="dialog"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/><path d="M3 21v-5h5"/></svg>Outcomes feed back as priors for the next scan</span> 689 </div> 690 <div class="pipe-foot"><span><b>A few minutes</b> · end to end</span><span>It produces the backlog · <b>it never runs your test</b></span></div> 691 </div> 692 693 <p class="sig-pipe-more"><a href="https://docs.abtestly.com/signals/overview" target="_blank" rel="noopener noreferrer">Read how each stage works in the docs →</a></p> 694 695 <div class="hero-cta" style="justify-content:center; margin-top:24px;"> 696 <a class="btn btn-secondary btn-lg" href="https://chromewebstore.google.com/detail/abtestly/lneegoiabmnanlpehinpnhndihfigfcl" target="_blank" rel="noopener noreferrer">Add to Chrome</a> 697 </div> 698 <p class="sig-pipe-more" style="margin-top:12px;">The browser extension captures a page from your own logged in session · free during beta, within your monthly scan allowance.</p> 699 </div> 700 </section> 701 702 <!-- =================== 3 · WHY IT IS DIFFERENT =================== --> 703 <section class="section" style="border-top:1px solid var(--hair);"> 704 <div class="container"> 705 <div class="section-head center sig-reveal"> 706 <span class="eyebrow" style="display:inline-flex;">why it is different</span> 707 <h2>Three things a best practice checklist will not do.</h2> 708 <p>Anyone can print a list of ideas. The work is deciding what is worth your traffic, and being honest about how sure it is.</p> 709 </div> 710 711 <div class="sig-diff"> 712 <div class="sig-diff-item sig-reveal">
713 <span class="sig-diff-node"></span> 714 <div class="sig-diff-term"> 715 <span class="k">Behavioral grading</span> 716 <span class="tag">The two signal rule</span> 717 </div> 718 <div class="sig-diff-body"> 719 <h3>A structural finding reaches your backlog, but it is never Test ready on its own.</h3> 720 <p>Signals grades on <b>two signals</b>, a structural finding on the page plus evidence that agrees with it: a behavioral pattern in your GA4, or customer voice you paste into your brand context. A structural finding alone leaves an idea labeled Needs evidence, however good it looks. A second signal puts it in contention, and it reaches <b>Test ready</b> only once its score also clears the threshold for its evidence tier; short of that it reads Needs evidence or Below threshold. A small mobile CTA is a flagged finding on its own, and a confirmed issue once your mobile conversion rate agrees. The <a href="https://docs.abtestly.com/signals/evidence-contract" target="_blank" rel="noopener noreferrer">evidence contract</a> lists every threshold, and the <a href="https://docs.abtestly.com/signals/read-a-scan" target="_blank" rel="noopener noreferrer">idea board guide</a> shows the badges in place.</p> 721 </div> 722 </div> 723 <div class="sig-diff-item sig-reveal"> 724 <span class="sig-diff-node"></span> 725 <div class="sig-diff-term"> 726 <span class="k">Adversarial falsification</span> 727 <span class="tag">The second pass</span> 728 </div> 729 <div class="sig-diff-body"> 730 <h3>Before a test slot is spent, the agent argues against itself.</h3> 731 <p>A second pass names the strongest <b>failure mode</b>
731, the likeliest confounder, the alternative explanation, and the <b>single test that would tell them apart</b>. When it comes back with one, you get the argument against the recommendation, attached to the recommendation.</p> 732 </div> 733 </div> 734 <div class="sig-diff-item sig-reveal"> 735 <span class="sig-diff-node"></span> 736 <div class="sig-diff-term"> 737 <span class="k">The closed loop</span> 738 <span class="tag">It owns both ends</span> 739 </div> 740 <div class="sig-diff-body"> 741 <h3>A standalone audit guesses once. Signals hears back.</h3> 742 <p>Because Signals runs inside ABTestly, the audit and the test engine are one system. Once a linked experiment concludes, its outcome feeds back <b>automatically</b> as a prior for the next scan of that domain. The learning is in context, not model training.</p> 743 </div> 744 </div> 745 </div> 746 </div> 747 </section> 748 749 <!-- =================== 4 · HONESTY FLOOR =================== --> 750 <section class="section" style="border-top:1px solid var(--hair); background: var(--surface);"> 751 <div class="container"> 752 <div class="sig-floor"> 753 <div class="sig-floor-head sig-reveal"> 754 <span class="eyebrow">the honesty floor</span> 755 <h2>Test ready is earned, never assumed.</h2> 756 <p>The point of Signals is telling you what it does not know. These behaviors are built in, not bolted on.</p> 757 </div> 758 <div class="sig-floor-list"> 759 <div class="sig-floor-item sig-reveal"> 760 <span class="sig-floor-n">01</span> 761 <div class="sig-floor-body"> 762 <h3>The qualification gate</h3> 763 <p>It tells you when your traffic <b>cannot reach significance</b>, and refuses to fake confidence about it.</p> 764 </div> 765 </div> 766 <div class="sig-floor-item sig-reveal"> 767 <span class="sig-floor-n">02</span> 768 <div class="sig-floor-body"> 769 <h3>Evidence tier, set per idea</h3> 770 <p>Every hypothesis carries one of <b>four evidence tiers</b>: Verified, Full evidence, Structural plus qualitative, or Structural. The tier is derived from which evidence questions were credited on that idea, so two ideas from the same scan land in different tiers when your GA4 speaks to one and not the other.</p> 771 </div> 772 </div> 773 <div class="sig-floor-item sig-reveal"> 774 <span class="sig-floor-n">03</span> 775 <div class="sig-floor-body"> 776 <h3>It never invents a number</h3> 777 <p>Thin evidence is <b>labeled, not inflated</b>. When a claim rests on page structure alone, Signals says so and names the cheapest action that would confirm it.</p> 778 </div> 779 </div> 780 </div> 781 </div> 782 <div class="vs-table-wrap sig-reveal"> 783 <table class="vs-table"> 784 <caption class="sr-only">What earns each evidence tier, the PXL score it needs for Test ready, and the highest score that tier can reach</caption> 785 <thead> 786 <tr><th>Evidence tier</th><th>What earns it</th><th>Score it needs</th><th>Highest it can reach</th></tr> 787 </thead> 788 <tbody> 789 <tr><th scope="row">Verified</th><td>Your GA4 and a first party heatmap both credited</td><td>9 or more</td><td>10, or 12 with customer voice</td></tr> 790 <tr><th scope="row">Full evidence</th><td>Your GA4 credited</td><td>7 or more</td><td>8, or 10 with customer voice</td></tr> 791 <tr><th scope="row">Structural + qualitative</th><td>Customer voice credited, no analytics</td><td>6 or more</td><td>8</td></tr> 792 <tr><th scope="row">Structural</th><td>Page structure alone</td><td>No score reaches Test ready</td><td>6</td></tr> 793 </tbody> 794 </table> 795 </div> 796 797 <div class="sig-note sig-reveal"> 798 <span class="sig-note-k">Both, not either</span> 799 <p>Clearing the score is necessary and not sufficient. An idea reads Test ready only when a second independent signal agrees with the structural finding <b>and</b> the score clears its tier. Miss either one and it reads Needs evidence, with the board naming the specific thing that would move it, down to "Connect GA4 so the scan can check this idea against funnel data."</p> 800 </div> 801 </div> 802 </section> 803 804 <!-- =================== 4b · WHAT COMES BACK =================== --> 805 <section class="section" style="border-top:1px solid var(--hair);"> 806 <div class="container"> 807 <div class="section-head center sig-reveal">
808 <span class="eyebrow" style="display:inline-flex;">the output</span> 809 <h2>What one idea looks like <em class="grad">when it comes back.</em></h2> 810 <p>Not a paragraph of advice. Every hypothesis in the backlog carries the same structured fields, so two ideas from different scans can be compared without rereading them.</p> 811 <p>To see these fields filled in, read <a href="/signals-sample-scan">an illustrated scan of a product page</a>.</p> 812 </div> 813 814 <div class="vs-table-wrap sig-reveal"> 815 <table class="vs-table"> 816 <caption class="sr-only">The fields carried by every hypothesis Signals returns</caption> 817 <thead> 818 <tr><th>On every idea</th><th>What it holds</th></tr> 819 </thead> 820 <tbody> 821 <tr><th scope="row">Observation and proposed change</th><td>What it found on the page, and the specific change to make. One of five CRO pillars: Trust and Credibility, Offer Clarity, Friction, Urgency and Motivation, or Page Flow and Hierarchy</td></tr> 822 <tr><th scope="row">Mechanism</th><td>Why the change should work, tagged with up to four named frameworks rather than left as intuition</td></tr> 823 <tr><th scope="row">Research citation</th><td>Every idea carries one. None ship uncited</td></tr> 824 <tr><th scope="row">Expected lift and effort</th><td>Effort is Low, Medium or High, and it feeds the rank, so a cheap idea is not buried under an expensive one</td></tr> 825 <tr><th scope="row">Statistical note</th><td>What the numbers behind the idea do and do not support</td></tr> 826 <tr><th scope="row">Tracking spec</th><td>The events to record so the test can actually be measured</td></tr> 827 <tr><th scope="row">Interaction spec</th><td>How the variant should behave once it is built</td></tr> 828 <tr><th scope="row">Data source</th><td>Where the evidence came from, which is what sets the evidence tier</td></tr> 829 </tbody> 830 </table> 831 </div> 832 833 <div class="sig-note sig-reveal"> 834 <span class="sig-note-k">Conditional</span> 835 <p>A recommended run time in weeks arrives when your traffic supports computing one, capped at eight. Customer voice appears on an idea only where your brand context spoke to it. And when the falsification pass returns, four more fields come with it: the strongest failure mode, the likeliest confou
835nder, the alternative explanation, and the single test that would tell them apart.</p> 836 </div> 837 </div> 838 </section> 839 840 <!-- =================== 5 · THE CLOSED LOOP =================== --> 841 <section class="section" style="border-top:1px solid var(--hair);"> 842 <div class="container"> 843 <div class="section-head center sig-reveal"> 844 <span class="eyebrow" style="display:inline-flex;">the learning loop</span> 845 <h2>Every linked experiment that concludes <em class="grad">sharpens the next scan.</em></h2> 846 <p>Signals does not hand off a backlog and forget it. Ship a hypothesis in ABTestly, and when the experiment concludes its result returns as a prior for the next scan. Nothing to log by hand.</p> 847 </div> 848 849 <div class="sig-loop sig-reveal"> 850 <span class="sig-loop-node">Scan the page</span> 851 <span class="sig-loop-arrow">→</span> 852 <span class="sig-loop-node">Ranked backlog</span> 853 <span class="sig-loop-arrow">→</span> 854 <span class="sig-loop-node">Ship the test in ABTestly</span> 855 <span class="sig-loop-arrow">→</span> 856 <span class="sig-loop-node">Exact ledger verdict</span> 857 <span class="sig-loop-arrow">→</span> 858 <span class="sig-loop-node sig-loop-node--accent">Outcome returns as a prior</span> 859 <span class="sig-loop-arrow sig-loop-arrow--back">↷</span> 860 </div> 861 862 <div class="sig-note sig-reveal"> 863 <span class="sig-note-k">Note</span> 864 <p>Signals runs on the Anthropic commercial API, whose terms do not use your data to train models. So this is a data feedback loop, not model fine tuning. Signals produces the backlog and the test plan; you stay in control of what ships.</p> 865 </div> 866 </div> 867 </section> 868 869 <!-- =================== 5b · WHAT IT NEEDS, WHAT IT CANNOT SEE =================== --> 870 <section class="section" style="border-top:1px solid var(--hair); background: var(--surface);"> 871 <div class="container"> 872 <div class="sig-floor"> 873 <div class="sig-floor-head sig-reveal"> 874 <span class="eyebrow">before you point it at a page</span> 875 <h2>What it needs from you, and what it cannot see.</h2> 876 <p>None of this is a caveat buried in the docs. It changes what a scan can return, so it belongs next to the promise.</p> 877 </div> 878 <div class="sig-floor-list"> 879 <div class="sig-floor-item sig-reveal"> 880 <span class="sig-floor-n">01</span> 881 <div class="sig-floor-body"> 882 <h3>GA4, or a lower ceiling</h3> 883 <p>Without analytics connected, <b>no idea can reach Verified or Full evidence</b>. The best available is Structural plus qualitative, and only when you paste customer voice into your brand context. Page structure on its own has no threshold to clear, so it never reaches Test ready however good the finding looks.</p> 884 </div> 885 </div> 886 <div class="sig-floor-item sig-reveal"> 887 <span class="sig-floor-n">02</span> 888 <div class="sig-floor-body"> 889 <h3>The GA4 it reads is the last 90 days</h3> 890 <p>A scan pulls a <b>90 day window</b>. If you redesigned the page inside that window, some of the behaviour being weighed belongs to the design you replaced. Signals cannot detect that for you, and it is worth knowing before you act on a funnel number.</p> 891 </div> 892 </div> 893 <div class="sig-floor-item sig-reveal"> 894 <span class="sig-floor-n">03</span> 895 <div class="sig-floor-body"> 896 <h3>The counter argument can be absent</h3> 897 <p>Every idea goes through the falsification pass, and <b>the argument arrives attached when the pass returns one</b>. When the pass cannot complete, the idea still reaches you without it rather than being held back. So read a missing argument as missing, not as an idea that survived one.</p> 898 </div> 899 </div> 900 </div> 901 </div> 902 </div> 903 </section> 904 905 <!-- =================== 6 · PRICING (free in Beta, priced after) =================== --> 906 <section class="section sig-pricing" style="border-top:1px solid var(--hair); background: var(--surface);"> 907 <div class="container"> 908 <div class="section-head center sig-reveal">
909 <span class="eyebrow" style="display:inline-flex;">pricing</span> 910 <h2>Signals is free for every paid plan, <em class="grad">while it is in Beta.</em></h2> 911 <p>No extra charge and nothing to switch on. If your <a href="/pricing">ABTestly plan</a> is paid, Signals runs today at no cost, within a monthly scan allowance.</p> 912 </div> 913 914 <div class="sig-note sig-reveal" style="margin-top: var(--s-6);"> 915 <span class="sig-note-k">During Beta</span> 916 <p>Each account gets a monthly scan allowance: 5 scans on Starter, 25 on Pro, 100 on Business and 100 on Enterprise. Every site in the account draws on it, and it resets on the 1st of each month (UTC). Unused scans do not carry over. A scan that fails does not count. When the allowance runs out, new scans are refused until it resets or you move to a plan with a larger one.</p> 917 </div> 918 919 <div class="sig-note sig-reveal" style="margin-top: var(--s-4);"> 920 <span class="sig-note-k">After Beta</span> 921 <p>Signals will be priced by scans per month. One scan is one full audit run. These prices are not live yet, Signals stays free until Beta ends.</p> 922 </div> 923 924 <div class="plan-grid sig-reveal"> 925 <article class="plan"> 926 <div class="plan-name">Lite</div> 927 <div class="plan-price"><b>$49</b><span class="per">/mo</span></div> 928 <p class="plan-desc">5 scans per month · page heatmaps included.</p> 929 </article> 930 <article class="plan"> 931 <div class="plan-name">Growth</div> 932 <div class="plan-price"><b>$149</b><span class="per">/mo</span></div> 933 <p class="plan-desc">25 scans per month · page heatmaps included.</p> 934 </article> 935 <article class="plan"> 936 <div class="plan-name">Scale</div> 937 <div class="plan-price"><b>$399</b><span class="per">/mo</span></div> 938 <p class="plan-desc">100 scans per month · page heatmaps included.</p> 939 </article> 940 </div> 941 942 <div class="sig-note sig-reveal" style="margin-top: var(--s-6);"> 943 <span class="sig-note-k">Heatmaps</span> 944 <p>Experiment heatmaps are live and included with Pro and Business at no extra cost, covering the pages your tests run on. Signals reads that behaviour as evidence when it writes hypotheses, including on pages where the test has already finished. On Starter, where experiment heatmaps are not included, Signals brings heatmaps with it. The heatmap corroborates GA4 funnel data rather than replacing it, so it counts toward an idea's evidence tier only on a scan where GA4 also contributed.</p> 945 </div> 946 </div> 947 </section> 948 949 <!-- =================== 7 · CLOSING CTA (dark band) =================== --> 950 <div class="container"> 951 <section class="cta-band"> 952 <span class="eyebrow" style="margin-bottom:var(--s-4); display:inline-flex">see it on your site</span> 953 <h2 style="max-width:22ch; margin-left:auto; margin-right:auto;">See what Signals finds on your own site.</h2> 954 <p style="max-width:52ch; margin:var(--s-4) auto 0; color:rgba(255,255,255,0.72);">Point it at a page, connect GA4, and read the backlog it returns. Signals is free while it is in Beta, on any paid plan, within a monthly scan allowance.</p> 955 <div class="hero-cta" style="justify-content:center; margin:var(--s-7) auto 0;"> 956 <a class="btn btn-primary btn-lg" href="https://app.abtestly.com/sign-up">Start your free trial <span class="arrow" aria-hidden="true">→</span></a> 957 <a class="btn btn-secondary btn-lg" href="https://docs.abtestly.com/signals/overview" target="_blank" rel="noopener noreferrer">Read the docs</a> 958 <a class="btn btn-secondary btn-lg" href="/switch-one-experiment">Switch one experiment</a> 959 </div> 960 </section> 961 </div> 962 963 </main> 964 965 <!-- Stage detail modal (opened by the pipeline stage cards) --> 966 <div class="pmodal" hidden> 967 <div class="pmodal-scrim" data-close></div> 968 <div class="pmodal-panel" role="dialog" aria-modal="true" aria-labelledby="pmodal-title" tabindex="-1"> 969 <button class="pmodal-x" data-close aria-label="Close"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M18 6L6 18M6 6l12 12"/></svg></button> 970 <div class="pmodal-head">
971 <span class="pmodal-ic"></span> 972 <div><span class="pmodal-eyebrow"></span><h3 class="pmodal-title" id="pmodal-title"></h3></div> 973 </div> 974 <p class="pmodal-lead"></p> 975 <ul class="pmodal-list"></ul> 976 </div> 977 </div> 978 979 <!-- =================== FOOTER =================== --> 980 <footer class="footer"> 981 <div class="container"> 982 <div class="footer-inner"> 983 <div> 984 <a class="brand" href="/" aria-label="ABTestly home"> 985 <svg class="brand-mark" viewBox="0 0 220 92" aria-hidden="true" focusable="false"><rect class="brand-mark-top" x="0" y="0" width="132" height="34" rx="17"/><path class="brand-mark-win" d="M17 58 A17 17 0 0 0 17 92 L196 92 L208 58 Z"/></svg><span class="brand-word">ABTestly</span> 986 </a> 987 <p class="footer-tag">A/B testing for teams who ship experiments in code.</p> 988 </div> 989 <div> 990 <h2>Product</h2> 991 <ul role="list"> 992 <li><a href="/#product">Overview</a></li> 993 <li><a href="/code-first-ab-testing">Code first testing</a></li> 994 <li><a href="/revenue-ab-testing">Revenue testing</a></li> 995 <li><a href="/signals">Signals</a></li> 996 <li><a href="/pricing">Pricing</a></li> 997 <li><a href="https://app.abtestly.com/sign-up">Start free trial</a></li> 998 </ul> 999 </div> 1000 <div> 1001 <h2>Developers</h2> 1002 <ul role="list"> 1003 <li><a href="/browser-ab-testing-runtime">Browser runtime</a></li> 1004 <li><a href="/#code-check">Code check</a></li> 1005 <li><a href="https://docs.abtestly.com/developer/window-abtestly-api" target="_blank" rel="noopener noreferrer">Browser API</a></li> 1006 <li><a href="https://docs.abtestly.com/preview/dev-debugger" target="_blank" rel="noopener noreferrer">Dev debugger</a></li> 1007 <li><a href="/ab-test-calculator">A/B test calculator</a></li> 1008 </ul> 1009 </div> 1010 <div> 1011 <h2>Methodology</h2> 1012 <ul role="list"> 1013 <li><a href="/#how-it-works">How it works</a></li> 1014 <li><a href="https://docs.abtestly.com/results/exact-ledger" target="_blank" rel="noopener noreferrer">Exact ledger</a></li> 1015 <li><a href="https://docs.abtestly.com/methodology/overview" target="_blank" rel="noopener noreferrer">Guides</a></li> 1016 <li><a href="/#faq">FAQ</a></li> 1017 <li><a href="/experiment-walkthrough">One experiment, built</a></li> 1018 <li><a href="/evaluate-one-experiment">Evaluate one experiment</a></li> 1019 </ul> 1020 </div> 1021 <div> 1022 <h2>Company</h2> 1023 <ul role="list"> 1024 <li><a href="/terms">Terms</a></li> 1025 <li><a href="/privacy">Privacy</a></li> 1026 <li><button class="footer-link" type="button" data-consent-settings aria-haspopup="dialog">Cookie settings</button></li> 1027 <li><a href="/refund">Refunds</a></li> 1028 <li><a href="/cdn-cgi/l/email-protection#82eae7eeeeedc2e3e0f6e7f1f6eefbace1edef">Contact</a></li> 1029 </ul> 1030 </div> 1031 </div> 1032 1033 <!-- The comparison pages sit in a wrapped strip rather than a column. 1034 As a column they were 14 long against neighbours of 4 to 7, which 1035 made the whole footer as tall as that one list and left everything 1036 beside it empty. A row uses the width instead, and the next 1037 comparison page joins it rather than making the footer taller. --> 1038 <div class="footer-strip"> 1039 <h2>Compare and switch</h2> 1040 <ul role="list"> 1041 <li><a href="/compare" class="footer-strip-lead">All comparisons</a></li> 1042 <li><a href="/optimizely-alternative">Optimizely alternative</a></li> 1043 <li><a href="/vwo-alternative">VWO alternative</a></li> 1044 <li><a href="/abtasty-alternative">AB Tasty alternative</a></li> 1045 <li><a href="/convert-alternative">Convert alternative</a></li> 1046 <li><a href="/posthog-vs-abtestly">PostHog vs ABTestly</a></li> 1047 <li><a href="/optimizely-pricing">Optimizely pricing</a></li> 1048 <li><a href="/vwo-pricing">VWO pricing</a></li> 1049 <li><a href="/abtasty-pricing">AB Tasty pricing</a></li> 1050 <li><a href="/convert-pricing">Convert pricing</a></li> 1051 <li><a href="/vwo-vs-optimizely">VWO vs Optimizely</a></li> 1052 <li><a href="/abtestly-vs-optimizely-vwo-convert">Four tools compared</a></li> 1053 <li><a href="/switch-one-experiment">Switch one experiment</a></li> 1054 </ul> 1055 </div> 1056 <div class="container footer-bottom">
1057 <span>CODE FIRST / EDGE SERVED / EXACT RESULTS</span> 1058 <span>Built for CRO developers and technical teams.</span> 1059 </div> 1060 </div> 1061 </footer>
vendor: 112 bytes, lines 1061-1063
1061 1062 1063 <script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
1063<script> 1064 (function () { 1065 var IC = { 1066 intake: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v18M3 8h6M3 16h6M15 8h6M15 16h6"/></svg>', 1067 capture: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="14" rx="2"/><path d="M3 8h18M8 21h8"/></svg>', 1068 behaviour: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3v18h18"/><rect x="7" y="11" width="3" height="6"/><rect x="13" y="7" width="3" height="10"/></svg>', 1069 payload: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7h6l6 5"/><path d="M4 17h6l6-5"/><circle cx="18" cy="12" r="2" fill="currentColor" stroke="none"/></svg>', 1070 generation: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l2.4 4.9 5.4.8-3.9 3.8.9 5.4L12 15.6l-4.8 2.5.9-5.4L4.2 8.7l5.4-.8z"/></svg>', 1071 falsification: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 9v4M12 17h.01"/><path d="M10.3 3.9 2 18a2 2 0 0 0 1.7 3h16.6a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"/></svg>', 1072 output: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 4h11l3 3v13H5z"/><path d="M9 9h6M9 13h6M9 17h4"/></svg>', 1073 loop: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/><path d="M3 21v-5h5"/></svg>' 1074 }; 1075 var NOTE_IC = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 16v-4M12 8h.01"/></svg>'; 1076 1077 var STAGES = { 1078 "1": { 1079 eyebrow: "01 · Intake", title: "Site & business context", icon: IC.intake, 1080 lead: "You give ABTestly a page URL plus optional business context, and what you connect decides how far the audit can go. Connect neither GA4 nor customer voice and every idea stays in the Structural tier; each source you add raises the tier an idea it speaks to can reach.", 1081 points: [ 1082 "<b>The page and context:</b> the URL you want audited, plus optional context like niche, average order value, primary goal and device split.", 1083 "<b>The browser extension</b> captures the page from your own logged in session, so the scan reads what a real visitor actually sees.", 1084 "<b>Connect GA4</b> for the behavioral signal, or paste customer voice into your brand context for the qualitative one. With neither, ideas stay in the Structural tier and never reach Test ready; with either, an idea that source speaks to can promote.", 1085 "<b>It sets what a scan can read</b>, and checks the page is on your own site before it runs. The evidence tier is then set idea by idea, from which evidence questions were credited on each one." 1086 ] 1087 }, 1088 "2": { 1089 eyebrow: "02 · Capture", title: "DOM, renders, funnel walks", icon: IC.capture, 1090 lead: "The ABTestly browser extension captures the page from your own logged in session, so the model reads the real thing a shopper sees, never a bare URL.", 1091 points: [ 1092 "<b>20 plus DOM signals:</b> page type, framework, heading hierarchy, form fields, CTA inventory, schema markup, review counts, trust badges, image alt coverage and HTTPS.", 1093 "<b>Three screenshots</b> on desktop, mobile and a throttled mobile view, read by a vision pass and reconciled against the DOM.", 1094 "<b>Funnel walks</b> let you capture several steps of a journey, so the scan sees more than a single page." 1095 ], 1096 note: { text: "It captures pages from your own logged in session. It never submits payment and never tries to evade a site's bot protection." } 1097 }, 1098 "3": { 1099 eyebrow: "03 · Behaviour", title: "GA4 funnel and drop off", icon: IC.behaviour, 1100 lead: "If you connected GA4, the agent can read where real visitors drop off, the behavioral half of the two signal rule.", 1101 points: [ 1102 "From GA4: funnel drop off, conversion by device, and revenue by channel, plus new versus returning and your top pages.", 1103 "This is what lets a structural finding become actionable. A DOM observation promotes once a second signal agrees with it: behavior here, or customer voice you paste into your brand context." 1104 ] 1105 }, 1106 "4": { 1107 eyebrow: "04 · Payload", title: "Multimodal payload assembled", icon: IC.payload,
1108 lead: "Everything captured so far is assembled into one multimodal prompt, so the model reasons over real evidence, never a bare URL.", 1109 points: [ 1110 "<b>Three image blocks:</b> the desktop, mobile and throttled mobile renders.", 1111 "<b>One structured text block:</b> business context, DOM signals, the live GA4 snapshot, and prior tested outcomes on this domain fed back automatically.", 1112 "It is framed as evidence of substance, not a list of claims, so the model weighs what is actually there." 1113 ] 1114 }, 1115 "5": { 1116 eyebrow: "05 · Generation", title: "Grounded hypotheses", icon: IC.generation, 1117 lead: "The model proposes test ideas that address your stated problem, each grounded in a mechanism and gated on evidence. AI evaluates the evidence. ABTestly computes the score.", 1118 points: [ 1119 "<b>Structured fields</b> on every hypothesis: observation, the change, the behavioral mechanism, expected lift, a <b>PXL score</b> with the answer behind every point, effort, a research citation, data source, statistical note, tracking spec and interaction spec, plus an opportunity size range and a recommended run time when the scan can support them.", 1120 "<b>The model answers eight yes or no questions</b> about the idea, each with a short rationale. ABTestly turns those answers into the score, the evidence tier and the readiness badge, and overrides any answer the evidence on that scan cannot support.", 1121 "Tagged to one of <b>five CRO pillars:</b> Trust and Credibility, Offer Clarity, Friction, Urgency and Motivation, Page Flow and Hierarchy.", 1122 "Framed through a named model: Fogg, Cialdini, prospect theory, cognitive load, Hick's Law or Jobs to be Done.", 1123 "<b>The two signal gate:</b> thin evidence ideas are not dropped. They are surfaced and labeled with the single cheapest action that would validate them." 1124 ] 1125 }, 1126 "6": { 1127 eyebrow: "06 · Falsification", title: "Argued against itself", icon: IC.falsification, neg: true, 1128 lead: "Before a recommendation reaches you, a second pass tries to break it, and the argument it makes arrives attached to the idea. If that pass cannot complete, the idea still reaches you without one.", 1129 points: [ 1130 "It names the strongest <b>failure mode</b>, the most likely <b>confounder</b>, an <b>alternative explanation</b> for the same evidence, and the <b>discriminating test</b> that would tell them apart.", 1131 "When the pass comes back with one, you get the argument against the recommendation, attached to the recommendation itself." 1132 ], 1133 note: { text: "It runs as an adversarial second pass over the scan's generated ideas, before they reach your backlog." } 1134 }, 1135 "7": { 1136 eyebrow: "07 · Output", title: "Structured hypotheses, ranked", icon: IC.output, 1137 lead: "The result is a prioritized backlog you can act on, each item carrying everything needed to run it well.", 1138 points: [ 1139 "Ranked by <b>PXL score</b>, then by how much evidence backs the idea; ties break on effort, cheapest first. Each card reads its score against <b>that scan's own maximum</b>, so a point the scan could never have awarded is never in the denominator.", 1140 "Every hypothesis carries its <b>Evidence tier</b>, effort and a tracking spec for what to instrument, plus an opportunity size range and a recommended run time when the scan can support them.", 1141 "<b>Four evidence tiers:</b> Verified, Full evidence, Structural plus qualitative, and Structural. They tell you how much weight each recommendation can bear." 1142 ], 1143 note: { text: "It produces the backlog and the test plan. It never runs your experiment. You stay in control of what ships." } 1144 }, 1145 loop: { 1146 eyebrow: "The learning loop", title: "How it gets context over time", icon: IC.loop, 1147 lead: "Once a linked experiment concludes, its outcome feeds back automatically into the next scan of that domain. The Anthropic commercial API does not use your data to train models; the learning is in context, so past results become priors in the next scan's payload.", 1148 points: [ 1149 "<b>Automatic outcomes:</b> when a linked experiment concludes, its result, won, lost, or inconclusive with the actual lift, feeds back as a prior for the next scan on that domain.", 1150 "<b>Prior scan memory:</b> it confirms what looks resolved, evolves what did not land, and avoids proposing the same thing again." 1151 ], 1152 note: { text: "Submitted data is processed via the Anthropic commercial API and is not used to train models, so this is a data feedback loop, not model fine tuning." } 1153 } 1154 }; 1155 1156 var modal = document.querySelector('.pmodal'); 1157 var panel = modal.querySelector('.pmodal-panel'); 1158 var icEl = modal.querySelector('.pmodal-ic'); 1159 var eyebrowEl = modal.querySelector('.pmodal-eyebrow'); 1160 var titleEl = modal.querySelector('.pmodal-title'); 1161 var leadEl = modal.querySelector('.pmodal-lead'); 1162 var listEl = modal.querySelector('.pmodal-list'); 1163 var lastFocus = null; 1164 1165 function open(key) { 1166 var s = STAGES[key]; 1167 if (!s) return; 1168 lastFocus = document.activeElement; 1169 1170 icEl.className = 'pmodal-ic' + (s.neg ? ' neg' : ''); 1171 icEl.innerHTML = s.icon; 1172 eyebrowEl.textContent = s.eyebrow; 1173 titleEl.textContent = s.title; 1174 leadEl.textContent = s.lead; 1175 listEl.innerHTML = s.points.map(function (p) { 1176 return '<li><span>' + p + '</span></li>'; 1177 }).join(''); 1178 1179 var existing = panel.querySelector('.pmodal-note'); 1180 if (existing) existing.remove(); 1181 if (s.note) { 1182 var note = document.createElement('div'); 1183 note.className = 'pmodal-note' + (s.note.warn ? ' warn' : ''); 1184 note.innerHTML = NOTE_IC + '<span></span>'; 1185 note.querySelector('span').textContent = s.note.text; 1186 panel.appendChild(note); 1187 } 1188 1189 modal.hidden = false;
1190 document.body.style.overflow = 'hidden'; 1191 panel.focus(); 1192 } 1193 1194 function close() { 1195 modal.hidden = true; 1196 document.body.style.overflow = ''; 1197 if (lastFocus && typeof lastFocus.focus === 'function') lastFocus.focus(); 1198 } 1199 1200 var triggers = document.querySelectorAll('[data-stage]'); 1201 for (var i = 0; i < triggers.length; i++) { 1202 (function (el) { 1203 el.addEventListener('click', function () { open(el.getAttribute('data-stage')); }); 1204 el.addEventListener('keydown', function (e) { 1205 if (e.key === 'Enter' || e.key === ' ' || e.key === 'Spacebar') { 1206 e.preventDefault(); 1207 open(el.getAttribute('data-stage')); 1208 } 1209 }); 1210 })(triggers[i]); 1211 } 1212 1213 var closers = modal.querySelectorAll('[data-close]'); 1214 for (var j = 0; j < closers.length; j++) { 1215 closers[j].addEventListener('click', close); 1216 } 1217 1218 document.addEventListener('keydown', function (e) { 1219 if (!modal.hidden && e.key === 'Escape') close(); 1220 }); 1221 })(); 1222 </script>
1222 1223 1224
1224<script src="/chat-widget.js" defer></script>
vendor: 1 bytes, line 1224
1224
1225<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"570edb9dca1c47c9a1c87507836899b9","r":1,"spa":2}' crossorigin="anonymous"></script>
1225 1226</body> 1227</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.