1<!doctype html> 2<html lang="en"> 3<head> 4<meta charset="utf-8" /> 5<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover" /> 6<title>Notabium · AI Meeting Notetaker, Transcription & Bot</title> 7<meta name="description" content="AI meeting notetaker that records and transcribes Zoom, Meet, and Teams calls, then writes summaries and action items. Send the Notabium Notetaker to join, or record in your browser." /> 8<meta name="theme-color" content="#FBFAF8" /> 9<link rel="alternate" hreflang="en" href="https://notabium.com/" /> 10<link rel="alternate" hreflang="sk" href="https://notabium.com/sk" /> 11<link rel="alternate" hreflang="cs" href="https://notabium.com/cs" /> 12<link rel="alternate" hreflang="x-default" href="https://notabium.com/" />
13<script src="/lang-redirect.js"></script>
13 14<style>.nav-lang{display:inline-flex;gap:9px;align-items:center;font-family:var(--nb-font-mono);font-size:12px;}.nav-lang a{color:var(--nb-ink-dim);}.nav-lang a:hover{color:var(--nb-ink);}.nav-lang a[aria-current="page"]{color:var(--nb-ink);font-weight:600;}</style> 15<link rel="canonical" href="https://notabium.com/" /> 16<link rel="icon" href="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2032%2032'%3E%3Crect%20width='32'%20height='32'%20rx='8'%20fill='%23FF5C1A'/%3E%3Cg%20fill='%23fff'%3E%3Crect%20x='6.5'%20y='11'%20width='3'%20height='10'%20rx='1.5'/%3E%3Crect%20x='11.8'%20y='6'%20width='3'%20height='20'%20rx='1.5'/%3E%3Crect%20x='17.1'%20y='9'%20width='3'%20height='14'%20rx='1.5'/%3E%3Crect%20x='22.4'%20y='13'%20width='3'%20height='6'%20rx='1.5'/%3E%3C/g%3E%3C/svg%3E" /> 17 18<meta property="og:type" content="website" /> 19<meta property="og:site_name" content="Notabium" /> 20<meta property="og:title" content="Notabium · AI Meeting Notetaker, Transcription & Bot" /> 21<meta property="og:description" content="Record and transcribe Zoom, Meet, and Teams calls, then get AI summaries and action items. The Notabium Notetaker joins for you, or record in your browser. Web app + Chrome extension." /> 22<meta property="og:url" content="https://notabium.com/" /> 23<meta property="og:image" content="https://notabium.com/media/notabium-notetaker.png" /> 24<meta name="twitter:card" content="summary_large_image" /> 25<meta name="twitter:title" content="Notabium · AI Meeting Notetaker, Transcription & Bot" /> 26<meta name="twitter:description" content="Record and transcribe Zoom, Meet, and Teams. AI summaries and action items. The Notabium Notetaker, web app, and Chrome extension." /> 27<meta name="twitter:image" content="https://notabium.com/media/notabium-notetaker.png" /> 28 29<link rel="stylesheet" href="notabium.css?v=2" /> 30
31<script type="application/ld+json"> 32{ 33 "@context": "https://schema.org", 34 "@type": "SoftwareApplication", 35 "name": "Notabium", 36 "url": "https://notabium.com/", 37 "operatingSystem": "Web, Chrome", 38 "applicationCategory": "BusinessApplication", 39 "description": "AI meeting notetaker that records and transcribes Zoom, Google Meet, and Microsoft Teams calls, then writes AI summaries and action items. Record in your browser, use the Chrome extension, or send the Notabium Notetaker to join calls for you.", 40 "featureList": [ 41 "Record and transcribe Zoom, Google Meet, and Microsoft Teams", 42 "AI meeting summaries and action items", 43 "AI notetaker that joins calls for you", 44 "Speaker-labelled transcripts", 45 "Shareable video links", 46 "Web app and Chrome extension" 47 ], 48 "offers": [ 49 {"@type":"Offer","price":"19.99","priceCurrency":"EUR","name":"Pro","description":"Per month. Record in your browser or send the Notabium Notetaker to Zoom, Meet, and Teams, with transcript, AI summary, action items, chat with the meeting, calendar auto-join, video, and unlimited usage. 7-day free trial, card required."}, 50 {"@type":"Offer","price":"39.99","priceCurrency":"EUR","name":"Team","description":"From â¬39.99/mo for 3 seats (â¬15.99 base + â¬8 per seat, minimum 3 seats). Everything in Pro per seat plus a shared team workspace."} 51 ] 52} 53</script>
vendor: 1 bytes, line 53
53
54<script type="application/ld+json"> 55{ 56 "@context": "https://schema.org", 57 "@type": "Organization", 58 "name": "Notabium", 59 "url": "https://notabium.com/", 60 "logo": "https://notabium.com/media/notabium-notetaker.png", 61 "description": "Notabium is an AI meeting notetaker that records, transcribes, and summarizes Zoom, Google Meet, and Microsoft Teams calls.", 62 "email": "[email protected]", 63 "sameAs": ["https://app.notabium.com"] 64} 65</script>
65 66 67<style> 68/* Page-specific layout on top of brand tokens. 69 * Type scale (locked): H1 clamp(44,7vw,84) · H2 ~36 · H3 ~20 · lede 18-19 · body 16-17 · labels 12 mono. 70 * Hierarchy from size + family + color. Mono headings, one weight (700), tight tracking, lh ~1.05. */ 71body { 72 background: var(--nb-paper); 73 color: var(--nb-ink); 74 font-size: 16px; 75 line-height: 1.6; 76} 77 78/* Nav (shrinks on scroll) */ 79.nav { 80 position: sticky; 81 top: 0; 82 z-index: 60; 83 background: rgba(244,244,243,0.82); 84 backdrop-filter: blur(14px); 85 border-bottom: 1px solid var(--nb-divider); 86 transition: background .2s ease; 87} 88.nav-inner { 89 display: flex; 90 align-items: center; 91 justify-content: space-between; 92 height: 68px; 93 transition: height .2s ease; 94} 95.nav.is-shrunk { background: rgba(244,244,243,0.9); } 96.nav.is-shrunk .nav-inner { height: 56px; } 97.nav-links { 98 display: flex; 99 gap: 30px; 100 align-items: center; 101 font-family: var(--nb-font-mono); 102 font-size: 12px; 103 color: var(--nb-ink-muted); 104} 105.nav-links a { transition: color .15s; } 106.nav-links a:hover { color: var(--nb-ink); } 107.nav-cta { display: flex; gap: 8px; align-items: center; } 108.nav-burger { 109 display: none; 110 width: 40px; height: 40px; 111 align-items: center; justify-content: center; 112 border: 1px solid var(--nb-divider); 113 border-radius: var(--nb-radius-md); 114 color: var(--nb-ink); 115} 116.nav-burger span, 117.nav-burger span::before, 118.nav-burger span::after { 119 content: ""; display: block; width: 16px; height: 1.5px; background: currentColor; position: relative; 120} 121.nav-burger span::before { position: absolute; top: -5px; } 122.nav-burger span::after { position: absolute; top: 5px; } 123 124/* Mobile drawer */ 125.nav-drawer { 126 position: fixed; 127 inset: 0; 128 z-index: 70; 129 background: var(--nb-paper); 130 display: none; 131 flex-direction: column; 132 padding: 20px var(--nb-gutter) 48px; 133} 134.nav-drawer.is-open { display: flex; } 135.nav-drawer-top { display: flex; align-items: center; justify-content: space-between; height: 68px; margin-bottom: 24px; } 136.nav-drawer-close { width: 40px; height: 40px; border: 1px solid var(--nb-divider); border-radius: var(--nb-radius-md); color: var(--nb-ink); font-family: var(--nb-font-mono); font-size: 20px; } 137.nav-drawer a.drawer-link { 138 font-family: var(--nb-font-mono); 139 font-size: 22px; 140 letter-spacing: -0.03em; 141 color: var(--nb-ink); 142 padding: 16px 0; 143 border-bottom: 1px solid var(--nb-divider); 144} 145.nav-drawer .nb-btn { margin-top: 28px; justify-content: center; } 146@media (max-width: 820px) { 147 .nav-links { display: none; } 148 .nav-cta .nb-btn--link { display: none; } 149 .nav-burger { display: inline-flex; } 150} 151 152/* Hero */ 153.hero { padding: 88px 0 72px; position: relative; } 154@media (max-width: 720px) { .hero { padding: 56px 0 56px; } } 155.hero-prompt { 156 font-family: var(--nb-font-mono); 157 font-size: 12px; 158 color: var(--nb-ink-muted); 159 margin-bottom: 28px; 160 letter-spacing: -0.005em; 161} 162.hero-prompt .accent { color: var(--nb-accent); } 163h1 { 164 font-family: var(--nb-font-mono); 165 font-size: clamp(44px, 7vw, 84px); 166 font-weight: 700; 167 letter-spacing: -0.05em; 168 line-height: 1.04; 169 color: var(--nb-ink); 170 margin: 0 0 26px; 171 max-width: 16ch; 172} 173h1 .accent { color: var(--nb-accent); } 174.lede { 175 font-family: var(--nb-font-sans); 176 font-size: clamp(18px, 1.4vw, 19px); 177 color: var(--nb-ink-muted); 178 line-height: 1.55; 179 letter-spacing: -0.01em; 180 max-width: 58ch; 181 margin: 0 0 36px; 182} 183.lede strong { color: var(--nb-ink); font-weight: 500; } 184.cta-row { 185 display: flex; 186 gap: 10px; 187 flex-wrap: wrap; 188 align-items: center; 189} 190.cta-row .nb-btn { padding: 13px 22px; font-size: 13px; } 191@media (max-width: 560px) { 192 .cta-row { gap: 8px; } 193 .cta-row .nb-btn { width: 100%; justify-content: center; } 194} 195 196/* Hero two-column, balanced: copy left, interactive sample call right */ 197.hero-grid{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:52px; align-items:start; } 198.hero-copy{ text-align:left; align-self:start; padding-top:48px; } 199.hero-copy .hero-prompt{ justify-content:flex-start; margin-bottom:0; } 200.hero-copy h1{ margin:14px 0 0; font-size:clamp(40px, 4.4vw, 62px); letter-spacing:-0.045em; line-height:1.06; max-width:14ch; } 201.hero-copy .lede{ margin:20px 0 26px; max-width:34em; } 202.hero-copy .cta-row{ justify-content:flex-start; margin-bottom:0; } 203.hero-show{ align-self:start; } 204@media (max-width:980px){ 205 .hero-grid{ grid-template-columns:1fr; gap:32px; } 206 .hero-copy h1{ font-size:clamp(36px, 9vw, 52px); max-width:18ch; } 207} 208 209.rec-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--nb-accent); flex: 0 0 auto; } 210 211/* ===== INTERACTIVE SAMPLE CALL (hero, right column) ===== 212 * A recorder mock: the notabium notetaker joins a Meet-style call, a live 213 * transcript types out with word-level highlighting, then the summary forms. 214 * Tabs (Transcript / Summary) are real, clickable, focusable buttons. 215 * Autoplays + loops; pauses on a chosen tab; static + composed for 216 * prefers-reduced-motion. One accent (ember), no green. */ 217.sim { 218 width: 100%; 219 text-align: left; 220 background: var(--nb-card); 221 border: 1px solid var(--nb-divider); 222 border-radius: var(--nb-radius-lg); 223 box-shadow: 0 1px 2px rgba(26,25,21,.04), 0 10px 30px rgba(26,25,21,.06); 224 overflow: hidden; 225 display: flex; 226 flex-direction: column; 227} 228 229/* --- Header bar: REC + live + timer + source --- */ 230.sim-callbar { 231 display: flex; align-items: center; gap: 8px; 232 padding: 13px 16px; border-bottom: 1px solid var(--nb-divider); 233 font-family: var(--nb-font-mono); font-size: 11px; color: var(--nb-ink-muted); 234 letter-spacing: -0.005em; 235} 236.sim-callbar .rec-dot { box-shadow: 0 0 0 3px var(--nb-accent-soft); } 237.sim-callbar-label { color: var(--nb-accent); text-transform: uppercase; letter-spacing: 0.04em; } 238.sim-clock { color: var(--nb-ink-muted); font-variant-numeric: tabular-nums; } 239.sim-callbar-meet { margin-left: auto; color: var(--nb-ink-dim); } 240 241/* --- Participant tiles --- */ 242.sim-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; padding: 14px 16px; } 243@media (max-width: 1080px) { .sim-tiles { grid-template-columns: repeat(2, 1fr); } } 244@media (max-width: 380px) { .sim-tiles { grid-template-columns: repeat(2, 1fr); } } 245.sim-tile { 246 position: relative; 247 aspect-ratio: 1 / 1; 248 background: var(--nb-surface); 249 border: 1px solid var(--nb-divider); 250 border-radius: var(--nb-radius-md); 251 display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; 252 overflow: hidden; 253} 254.sim-ring { 255 position: absolute; inset: 0; 256 border-radius: inherit; 257 border: 2px solid transparent; 258 transition: border-color .25s ease; 259 pointer-events: none; 260} 261.sim-tile.is-speaking .sim-ring { border-color: var(--nb-accent); animation: sim-ring-pulse 1.1s ease-in-out infinite; } 262@keyframes sim-ring-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } } 263.sim-avatar { 264 width: 40px; height: 40px; 265 display: flex; align-items: center; justify-content: center; 266 border-radius: var(--nb-radius-md); 267 background: var(--nb-ink); color: var(--nb-paper); 268 font-family: var(--nb-font-mono); font-weight: 700; font-size: 13px; letter-spacing: -0.04em; 269} 270/* notetaker mark: white waveform on a rounded ember square */ 271.sim-avatar--bot { background: var(--nb-accent); color: #fff; } 272.sim-avatar--bot .nb-glyph { height: 18px; } 273.sim-avatar--bot .nb-glyph i { background: #fff; } 274.sim-name { font-family: var(--nb-font-mono); font-size: 11px; color: var(--nb-ink-muted); letter-spacing: -0.01em; text-align: center; }
275/* the notetaker tile starts hidden, then "joins" */ 276.sim-tile--bot { opacity: 0; transform: scale(0.96); transition: opacity .45s ease, transform .45s ease; } 277.sim-tile--bot.is-joined { opacity: 1; transform: none; } 278.sim-joinpill { 279 position: absolute; top: 7px; right: 7px; 280 font-family: var(--nb-font-mono); font-size: 9px; letter-spacing: 0; 281 color: #fff; background: var(--nb-accent); padding: 2px 6px; border-radius: var(--nb-radius-pill); 282 opacity: 0; transition: opacity .3s ease; 283} 284.sim-tile--bot.is-joining .sim-joinpill, 285.sim-tile--bot.is-rec .sim-joinpill { opacity: 1; } 286.sim-tile--bot.is-joined .sim-joinpill { opacity: 0; } 287.sim-tile--bot.is-rec .sim-joinpill { display: inline-flex; align-items: center; gap: 4px; } 288.sim-tile--bot.is-rec .sim-joinpill::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: #fff; } 289 290/* --- Tabbed panel (transcript <-> summary) --- */ 291.sim-panel { background: var(--nb-surface); display: flex; flex-direction: column; border-top: 1px solid var(--nb-divider); } 292.sim-panel-head { 293 display: flex; gap: 18px; padding: 0 16px; align-items: stretch; 294 border-bottom: 1px solid var(--nb-divider); 295 font-family: var(--nb-font-mono); font-size: 11px; letter-spacing: -0.005em; 296} 297.sim-tab { 298 appearance: none; background: none; border: 0; cursor: pointer; 299 color: var(--nb-ink-dim); position: relative; padding: 12px 2px; 300 font: inherit; letter-spacing: -0.005em; 301 transition: color .15s ease; 302} 303.sim-tab:hover { color: var(--nb-ink-muted); } 304.sim-tab.is-on { color: var(--nb-ink); } 305.sim-tab.is-on::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--nb-accent); } 306.sim-tab:focus-visible { outline: 2px solid var(--nb-accent); outline-offset: 2px; border-radius: var(--nb-radius-sm); } 307/* the summary tab pulses to draw attention once the transcript ends */ 308.sim-tab.is-nudge { color: var(--nb-accent); animation: sim-tab-nudge 1s ease-in-out 2; } 309@keyframes sim-tab-nudge { 0%,100% { opacity: 1; } 50% { opacity: 0.45; } } 310/* Fixed height + reserved scrollbar gutter so switching tabs never resizes the 311 * panel (no layout shift / no padding jump in the section). */ 312.sim-panel-body { padding: 16px; height: 296px; overflow-y: auto; scrollbar-gutter: stable; } 313@media (max-width: 980px) { .sim-panel-body { height: 260px; } } 314 315/* [hidden] must beat the display rules below when toggled in JS */ 316.sim-transcript[hidden], .sim-summary[hidden] { display: none !important; } 317.sim-transcript { display: flex; flex-direction: column; gap: 11px; } 318.sim-line { 319 font-family: var(--nb-font-sans); font-size: 13px; line-height: 1.5; color: var(--nb-ink); 320 opacity: 0; transform: translateY(5px); transition: opacity .35s ease, transform .35s ease; 321} 322.sim-line.is-in { opacity: 1; transform: none; } 323.sim-line .ts { font-family: var(--nb-font-mono); font-size: 10px; color: var(--nb-accent); opacity: 0.7; margin-right: 8px; letter-spacing: -0.005em; } 324.sim-line .spk { font-family: var(--nb-font-mono); font-size: 11px; color: var(--nb-ink-muted); margin-right: 6px; letter-spacing: -0.005em; } 325.sim-line .spk::after { content: ":"; } 326.sim-line .w { transition: background-color .15s ease, color .15s ease; border-radius: 3px; padding: 0 1px; } 327/* word-level "spoken" highlight */ 328.sim-line .w.on { background: var(--nb-accent-soft); color: var(--nb-accent-deep); } 329.sim-line .w.said { color: var(--nb-ink); } 330.sim-line .w.ahead { color: var(--nb-ink-dim); } 331 332.sim-summary .sim-sum-label { 333 font-family: var(--nb-font-mono); font-size: 10px; letter-spacing: 0.02em; text-transform: uppercase; 334 color: var(--nb-ink-muted); margin: 0 0 8px; 335} 336.sim-summary .sim-sum-label + ul { margin-bottom: 16px; } 337.sim-summary ul { list-style: none; padding: 0; margin: 0; } 338.sim-summary li { 339 font-family: var(--nb-font-sans); font-size: 13px; line-height: 1.5; color: var(--nb-ink); 340 padding: 4px 0 4px 22px; position: relative; 341 opacity: 0; transform: translateY(5px); transition: opacity .3s ease, transform .3s ease; 342} 343.sim-summary li strong { color: var(--nb-ink); font-weight: 600; } 344.sim-summary li.is-in { opacity: 1; transform: none; } 345.sim-summary li::before { content: "\203A"; position: absolute; left: 0; top: 4px; font-family: var(--nb-font-mono); color: var(--nb-ink-muted); } 346.sim-summary li.act::before { content: "\2713"; color: var(--nb-accent); font-size: 11px; top: 5px; } 347.sim-summary li .who { font-family: var(--nb-font-mono); font-size: 10px; color: var(--nb-accent); margin-left: 6px; } 348.sim-summary li .who::before { content: "\2014 "; color: var(--nb-ink-dim); } 349 350/* Reduced motion / no-JS: show a fully composed static frame */ 351@media (prefers-reduced-motion: reduce) { 352 .sim-tile.is-speaking .sim-ring { animation: none; } 353 .sim-tab.is-nudge { animation: none; } 354} 355.sim.is-static .sim-tile--bot { opacity: 1; transform: none; } 356.sim.is-static .sim-tile--bot .sim-joinpill { opacity: 0; } 357.sim.is-static .sim-line, 358.sim.is-static .sim-summary li { opacity: 1; transform: none; } 359.sim.is-static .sim-line .w { color: var(--nb-ink); background: none; } 360 361/* Works-with strip */ 362.workswith { 363 border-top: 1px solid var(--nb-divider); 364 border-bottom: 1px solid var(--nb-divider); 365 padding: 26px 0; 366} 367.workswith-inner { 368 display: flex; 369 align-items: center; 370 justify-content: space-between; 371 flex-wrap: wrap; 372 gap: 18px 32px; 373} 374.workswith .ww-label { 375 font-family: var(--nb-font-mono); 376 font-size: 12px; 377 color: var(--nb-ink-muted); 378 letter-spacing: -0.005em; 379 white-space: nowrap; 380} 381.workswith .ww-logos { 382 display: flex; 383 align-items: center; 384 gap: 28px; 385 flex-wrap: wrap; 386 font-family: var(--nb-font-mono); 387 font-size: 15px; 388 letter-spacing: -0.03em; 389 color: var(--nb-ink-muted); 390} 391.workswith .ww-logos span { transition: color .15s; } 392.workswith .ww-logos span:hover { color: var(--nb-ink); } 393 394/* Section base */ 395.section { 396 padding: 92px 0; 397 border-top: 1px solid var(--nb-divider); 398} 399@media (max-width: 720px) { .section { padding: 64px 0; } } 400.section--plain { border-top: 0; } 401/* All section heads centered for a consistent, calm rhythm down the page. */ 402.section-head { 403 margin-bottom: 52px; 404 text-align: center; 405} 406.section-head .kicker { 407 font-family: var(--nb-font-mono); 408 font-size: 12px; 409 color: var(--nb-accent); 410 margin-bottom: 16px; 411 letter-spacing: -0.005em; 412} 413.section-head h2 { 414 font-family: var(--nb-font-mono); 415 font-size: clamp(30px, 3.4vw, 38px); 416 font-weight: 700; 417 letter-spacing: -0.04em; 418 line-height: 1.08; 419 color: var(--nb-ink); 420 margin: 0 auto 16px; 421 max-width: 24ch; 422} 423.section-head .sub { 424 font-family: var(--nb-font-sans); 425 font-size: 17px; 426 color: var(--nb-ink-muted); 427 line-height: 1.6; 428 max-width: 62ch; 429 margin: 0 auto; 430} 431 432/* Demo / how it works */ 433.section--demo .section-head { margin-bottom: 40px; } 434 435/* Demo 3-step strip */ 436.demo-steps{ display:grid; grid-template-columns:1fr auto 1fr auto 1fr; align-items:stretch; gap:14px; 437 max-width:1000px; margin:34px auto 0; } 438.dstep{ background:var(--nb-card); border:1px solid var(--nb-divider); border-radius:var(--nb-radius-lg); 439 box-shadow:0 1px 2px rgba(26,25,21,.04), 0 10px 30px rgba(26,25,21,.05); padding:22px 22px 24px; text-align:left; } 440.dstep-num{ font-family:var(--nb-font-mono); font-size:12px; color:var(--nb-accent); margin-bottom:10px; } 441.dstep h3{ margin:0 0 8px; font-size:18px; } 442.dstep p{ margin:0; font-size:14px; line-height:1.55; color:var(--nb-ink-muted); } 443.dstep-arrow{ display:flex; align-items:center; color:var(--nb-ink-dim); font-size:20px; } 444@media (max-width:820px){ .demo-steps{ grid-template-columns:1fr; } .dstep-arrow{ display:none; } } 445 446/* Modes (3-up grid with hairlines) */ 447.modes { 448 display: grid; 449 grid-template-columns: repeat(3, 1fr); 450 gap: 1px; 451 background: var(--nb-divider); 452 border: 1px solid var(--nb-divider); 453 border-radius: var(--nb-radius-lg); 454 overflow: hidden; 455} 456@media (max-width: 880px) { .modes { grid-template-columns: 1fr; } } 457.mode { 458 background: var(--nb-card); 459 padding: 32px 28px; 460} 461.mode-head { 462 display: flex; 463 justify-content: space-between; 464 align-items: center; 465 margin-bottom: 16px; 466} 467.mode-head .num { 468 font-family: var(--nb-font-mono); 469 font-size: 11px; 470 color: var(--nb-accent); 471} 472.mode-head .tier { 473 font-family: var(--nb-font-mono); 474 font-size: 10px; 475 color: var(--nb-ink-muted); 476 letter-spacing: -0.005em; 477} 478.mode h3 { 479 font-family: var(--nb-font-mono); 480 font-size: 22px; 481 font-weight: 700; 482 letter-spacing: -0.04em; 483 color: var(--nb-ink); 484 margin: 0 0 12px; 485 line-height: 1.15; 486} 487.mode p { 488 font-family: var(--nb-font-sans); 489 font-size: 14px; 490 color: var(--nb-ink-muted); 491 line-height: 1.6; 492 margin: 0; 493} 494 495/* Tenets */ 496.tenets { 497 display: grid; 498 grid-template-columns: 1fr 1fr; 499 gap: 1px; 500 background: var(--nb-divider); 501 border: 1px solid var(--nb-divider); 502 border-radius: var(--nb-radius-lg); 503 overflow: hidden; 504} 505@media (max-width: 720px) { .tenets { grid-template-columns: 1fr; } } 506.tenet { 507 background: var(--nb-card); 508 padding: 28px 28px; 509} 510.tenet-head { 511 display: flex; 512 align-items: baseline; 513 gap: 12px; 514 margin-bottom: 10px; 515} 516.tenet-num { 517 font-family: var(--nb-font-mono); 518 font-size: 11px; 519 color: var(--nb-accent); 520} 521.tenet-title { 522 font-family: var(--nb-font-mono); 523 font-size: 18px; 524 font-weight: 700; 525 letter-spacing: -0.04em; 526 color: var(--nb-ink); 527} 528.tenet p { 529 font-family: var(--nb-font-sans); 530 font-size: 14px; 531 color: var(--nb-ink-muted); 532 line-height: 1.55; 533 margin: 0; 534} 535 536/* Features grid (3-up cards) */ 537.features { 538 display: grid; 539 grid-template-columns: repeat(3, 1fr); 540 gap: 1px; 541 background: var(--nb-divider); 542 border: 1px solid var(--nb-divider); 543 border-radius: var(--nb-radius-lg); 544 overflow: hidden; 545} 546@media (max-width: 880px) { .features { grid-template-columns: 1fr; } } 547.feature { 548 background: var(--nb-card); 549 padding: 32px 28px; 550} 551.feature-head { 552 display: flex; 553 justify-content: space-between; 554 align-items: center; 555 margin-bottom: 18px; 556} 557.feature-num { 558 font-family: var(--nb-font-mono); 559 font-size: 11px; 560 color: var(--nb-accent); 561} 562.feature-tier { 563 font-family: var(--nb-font-mono); 564 font-size: 10px; 565 letter-spacing: 0; 566 padding: 3px 8px; 567 background: var(--nb-surface); 568 border-radius: var(--nb-radius-md); 569 color: var(--nb-ink); 570} 571.feature h3 { 572 font-family: var(--nb-font-mono); 573 font-size: 19px; 574 font-weight: 700; 575 letter-spacing: -0.04em; 576 color: var(--nb-ink); 577 margin: 0 0 10px; 578 line-height: 1.2; 579} 580.feature p { 581 font-family: var(--nb-font-sans); 582 font-size: 14px; 583 color: var(--nb-ink-muted); 584 line-height: 1.6; 585 margin: 0; 586} 587 588/* Pricing */ 589.price-grid { 590 display: grid; 591 grid-template-columns: repeat(3, 1fr); 592 gap: 1px; 593 background: var(--nb-divider); 594 border: 1px solid var(--nb-divider); 595 border-radius: var(--nb-radius-lg); 596 overflow: hidden; 597 max-width: 1000px; 598 margin: 0 auto; 599} 600@media (max-width: 900px) { .price-grid { grid-template-columns: 1fr; max-width: 460px; } } 601.price { 602 background: var(--nb-card); 603 padding: 32px 26px; 604 position: relative; 605} 606.price.featured { 607 background: var(--nb-accent-wash); 608 border: 1px solid var(--nb-accent-line); 609 outline: 1px solid var(--nb-divider); 610 border-radius: var(--nb-radius-lg); 611} 612.price-tier { 613 font-family: var(--nb-font-mono); 614 font-size: 11px; 615 color: var(--nb-ink-muted); 616 margin-bottom: 16px; 617 letter-spacing: -0.005em; 618} 619.price-tier.featured { color: var(--nb-accent); } 620.price-amount { 621 font-family: var(--nb-font-mono); 622 font-size: 44px; 623 font-weight: 700; 624 letter-spacing: -0.04em; 625 color: var(--nb-ink); 626 line-height: 1; 627 margin-bottom: 6px; 628} 629.price-amount--custom { font-size: 36px; } 630.price-amount sup { 631 font-size: 14px; 632 font-weight: 500; 633 color: var(--nb-ink-muted); 634 letter-spacing: 0; 635 vertical-align: top; 636 margin-left: 2px; 637} 638.price-cents { 639 font-family: var(--nb-font-mono); 640 font-size: 11px; 641 color: var(--nb-ink-muted); 642 margin-bottom: 28px; 643 line-height: 1.6; 644} 645.price-cents .save { color: var(--nb-accent); } 646.price ul { 647 list-style: none; 648 padding: 0; 649 margin: 0 0 28px; 650 font-family: var(--nb-font-sans); 651 font-size: 13px; 652 color: var(--nb-ink); 653 line-height: 1.55; 654} 655.price li { 656 padding: 8px 0; 657 border-top: 1px solid var(--nb-divider); 658 display: flex; 659 gap: 10px; 660 align-items: flex-start; 661} 662.price li:first-child { border-top: 0; padding-top: 0; } 663.price li::before { 664 content: "âº"; 665 color: var(--nb-accent); 666 flex-shrink: 0; 667 font-family: var(--nb-font-mono); 668} 669.price li.x { opacity: 0.45; color: var(--nb-ink-muted); } 670.price li.x::before { content: "-"; color: var(--nb-ink-muted); } 671.price-cta { 672 width: 100%; 673 justify-content: center; 674 text-align: center; 675} 676 677/* Terminal block (for manifesto-style copy) */ 678.term-block { 679 background: var(--nb-card); 680 border: 1px solid var(--nb-divider); 681 border-radius: var(--nb-radius-lg); 682 padding: 24px 28px; 683 font-family: var(--nb-font-mono); 684 font-size: 13px; 685 line-height: 1.85; 686 color: var(--nb-ink); 687 letter-spacing: -0.005em; 688} 689.term-block .accent { color: var(--nb-accent); } 690.term-block .muted { color: var(--nb-ink-muted); } 691.term-block .kv { 692 display: grid; 693 grid-template-columns: 180px 1fr; 694}
695.term-block .kv span:first-child .key { color: var(--nb-ink); } 696.term-block .kv .marker { color: var(--nb-accent); } 697 698/* FAQ */ 699.faq { max-width: 760px; margin: 0 auto; } 700.faq details { 701 background: var(--nb-card); 702 border: 1px solid var(--nb-divider); 703 border-radius: var(--nb-radius-lg); 704 padding: 18px 22px; 705 margin-bottom: 8px; 706} 707.faq summary { 708 cursor: pointer; 709 font-family: var(--nb-font-mono); 710 font-weight: 500; 711 font-size: 15px; 712 letter-spacing: -0.02em; 713 color: var(--nb-ink); 714 list-style: none; 715 display: flex; 716 justify-content: space-between; 717 align-items: center; 718} 719.faq summary::-webkit-details-marker { display: none; } 720.faq summary::after { 721 content: "+"; 722 font-family: var(--nb-font-mono); 723 font-size: 18px; 724 color: var(--nb-accent); 725 transition: transform .15s; 726} 727.faq details[open] summary::after { transform: rotate(45deg); } 728.faq details p { 729 margin: 14px 0 0; 730 font-family: var(--nb-font-sans); 731 font-size: 14px; 732 color: var(--nb-ink-muted); 733 line-height: 1.65; 734} 735 736/* ===== BEFORE / AFTER transformation ===== */ 737.ba-grid { 738 display: grid; 739 grid-template-columns: 1fr 1fr; 740 gap: 1px; 741 background: var(--nb-divider); 742 border: 1px solid var(--nb-divider); 743 border-radius: var(--nb-radius-lg); 744 overflow: hidden; 745} 746@media (max-width: 820px) { .ba-grid { grid-template-columns: 1fr; } } 747.ba-card { background: var(--nb-surface); padding: 30px 28px; } 748.ba-card.after { background: var(--nb-card); } 749.ba-head { 750 display: flex; align-items: center; gap: 10px; 751 font-family: var(--nb-font-mono); font-size: 11px; 752 letter-spacing: -0.005em; margin-bottom: 20px; 753} 754.ba-card .ba-head .tag { color: var(--nb-ink-muted); } 755.ba-card.after .ba-head .tag { color: var(--nb-accent); } 756.ba-head .badge { margin-left: auto; color: var(--nb-ink-muted); } 757/* Raw transcript: legible dark text on the light theme (the "before"). */ 758.ba-raw { 759 font-family: var(--nb-font-mono); 760 font-size: 13px; 761 line-height: 1.9; 762 color: var(--nb-ink-soft); 763 margin: 0; 764} 765.ba-raw .spk { color: var(--nb-ink-muted); } 766.ba-summary { margin: 0; } 767.ba-summary .ba-sub { 768 font-family: var(--nb-font-mono); font-size: 10px; letter-spacing: 0.02em; 769 color: var(--nb-ink-muted); text-transform: uppercase; margin: 0 0 12px; 770} 771.ba-summary .ba-sub + ul { margin-bottom: 22px; } 772.ba-summary ul { list-style: none; padding: 0; margin: 0; } 773.ba-summary li { 774 font-family: var(--nb-font-sans); 775 font-size: 14px; line-height: 1.55; 776 color: var(--nb-ink); 777 padding: 7px 0 7px 24px; 778 position: relative; 779} 780.ba-summary li::before { 781 content: "âº"; position: absolute; left: 0; top: 6px; 782 font-family: var(--nb-font-mono); color: var(--nb-ink-muted); 783} 784.ba-summary li.act::before { 785 content: "â"; color: var(--nb-accent); font-size: 12px; top: 8px; 786} 787.ba-summary li .who { color: var(--nb-ink-muted); font-family: var(--nb-font-mono); font-size: 11px; } 788 789/* ===== HOW IT WORKS (3 numbered steps) ===== */ 790.how { 791 display: grid; 792 grid-template-columns: repeat(3, 1fr); 793 gap: 1px; 794 background: var(--nb-divider); 795 border: 1px solid var(--nb-divider); 796 border-radius: var(--nb-radius-lg); 797 overflow: hidden; 798} 799@media (max-width: 820px) { .how { grid-template-columns: 1fr; } } 800.how-step { background: var(--nb-card); padding: 32px 28px; } 801.how-step .hn { 802 font-family: var(--nb-font-mono); font-size: 13px; font-weight: 700; 803 color: var(--nb-accent); letter-spacing: -0.02em; margin-bottom: 16px; 804 display: flex; align-items: center; gap: 10px; 805} 806.how-step .hn::after { content: ""; height: 1px; flex: 1; background: var(--nb-divider); } 807.how-step h3 { 808 font-family: var(--nb-font-mono); font-size: 18px; font-weight: 700; 809 letter-spacing: -0.03em; color: var(--nb-ink); margin: 0 0 8px; line-height: 1.2; 810} 811.how-step p { 812 font-family: var(--nb-font-sans); font-size: 14px; color: var(--nb-ink-muted); 813 line-height: 1.6; margin: 0; 814} 815 816/* ===== BENTO features ===== */ 817.bento { 818 display: grid; 819 grid-template-columns: repeat(4, 1fr); 820 grid-auto-rows: minmax(150px, auto); 821 gap: 1px; 822 background: var(--nb-divider); 823 border: 1px solid var(--nb-divider); 824 border-radius: var(--nb-radius-lg); 825 overflow: hidden; 826} 827@media (max-width: 980px) { .bento { grid-template-columns: repeat(2, 1fr); } } 828@media (max-width: 560px) { .bento { grid-template-columns: 1fr; } } 829.cell { 830 background: var(--nb-card); 831 padding: 26px 24px; 832 display: flex; 833 flex-direction: column; 834} 835.cell.col2 { grid-column: span 2; }
836.cell.row2 { grid-row: span 2; } 837@media (max-width: 560px) { .cell.col2 { grid-column: span 1; } } 838.cell.focal { background: var(--nb-accent-wash); border: 1px solid var(--nb-accent-line); border-radius: var(--nb-radius-lg); } 839.cell-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; } 840.cell-num { font-family: var(--nb-font-mono); font-size: 11px; color: var(--nb-accent); } 841.cell-badge { 842 font-family: var(--nb-font-mono); font-size: 10px; letter-spacing: 0; 843 padding: 3px 8px; border: 1px solid var(--nb-divider); border-radius: var(--nb-radius-md); color: var(--nb-ink-muted); 844} 845.cell h3 { 846 font-family: var(--nb-font-mono); font-weight: 700; letter-spacing: -0.035em; 847 color: var(--nb-ink); margin: 0 0 10px; line-height: 1.2; font-size: 19px; 848} 849.cell.focal h3 { font-size: 24px; } 850.cell p { 851 font-family: var(--nb-font-sans); font-size: 14px; color: var(--nb-ink-muted); 852 line-height: 1.6; margin: 0; 853} 854.cell.focal p { font-size: 15px; } 855.cell .spacer { flex: 1; } 856 857/* ===== DEV / API / MCP ===== */ 858.dev-grid { display: grid; grid-template-columns: 0.85fr 1.15fr; gap: 1px; background: var(--nb-divider); border: 1px solid var(--nb-divider); border-radius: var(--nb-radius-lg); overflow: hidden; } 859@media (max-width: 880px) { .dev-grid { grid-template-columns: 1fr; } } 860/* let grid tracks shrink so the code block scrolls instead of widening the page */ 861.dev-grid > * { min-width: 0; } 862.dev-copy { background: var(--nb-card); padding: 34px 30px; } 863.dev-copy h3 { font-family: var(--nb-font-mono); font-size: 22px; font-weight: 700; letter-spacing: -0.04em; color: var(--nb-ink); margin: 0 0 14px; line-height: 1.15; } 864.dev-copy p { font-family: var(--nb-font-sans); font-size: 15px; color: var(--nb-ink-muted); line-height: 1.65; margin: 0 0 18px; } 865.dev-tags { display: flex; flex-wrap: wrap; gap: 8px; } 866.dev-tags .t { font-family: var(--nb-font-mono); font-size: 11px; color: var(--nb-ink-muted); border: 1px solid var(--nb-divider); border-radius: var(--nb-radius-md); padding: 5px 10px; } 867.code-card { background: var(--nb-surface); padding: 0; display: flex; flex-direction: column; } 868.code-bar { 869 height: 38px; display: flex; align-items: center; gap: 8px; padding: 0 16px; 870 border-bottom: 1px solid var(--nb-divider); font-family: var(--nb-font-mono); 871 font-size: 11px; color: var(--nb-ink-muted); 872} 873.code-bar .d { width: 9px; height: 9px; } 874.code-bar .d.r { background: var(--nb-accent); } 875.code-bar .d.m1, .code-bar .d.m2 { background: var(--nb-divider); } 876.code-bar .fname { margin-left: 8px; letter-spacing: -0.01em; } 877.code-body { 878 font-family: var(--nb-font-mono); font-size: 12.5px; line-height: 1.85; 879 padding: 20px 22px; color: var(--nb-ink); overflow-x: auto; margin: 0; 880 letter-spacing: -0.01em; 881} 882.code-body .c { color: var(--nb-ink-muted); } 883.code-body .k { color: var(--nb-accent); } 884.code-body .s { color: var(--nb-ink); opacity: 0.85; } 885.code-body .p { color: var(--nb-ink-muted); } 886 887/* Dev credibility row (REST / MCP / SQL) */ 888.dev-points { 889 display: grid; 890 grid-template-columns: repeat(3, 1fr); 891 gap: 1px; 892 background: var(--nb-divider); 893 border: 1px solid var(--nb-divider); 894 border-radius: var(--nb-radius-lg); 895 overflow: hidden; 896 margin-bottom: 1px; 897} 898@media (max-width: 880px) { .dev-points { grid-template-columns: 1fr; } } 899.dev-point { background: var(--nb-card); padding: 26px 24px; } 900.dev-point .dp-num { 901 font-family: var(--nb-font-mono); font-size: 11px; color: var(--nb-accent); 902 letter-spacing: 0; margin-bottom: 14px; 903} 904.dev-point h4 { 905 font-family: var(--nb-font-mono); font-size: 16px; font-weight: 700; 906 letter-spacing: -0.03em; color: var(--nb-ink); margin: 0 0 8px; line-height: 1.2; 907} 908.dev-point p { 909 font-family: var(--nb-font-sans); font-size: 13.5px; color: var(--nb-ink-muted); 910 line-height: 1.6; margin: 0; 911} 912.dev-point p code { 913 font-family: var(--nb-font-mono); font-size: 12px; color: var(--nb-ink); 914 background: var(--nb-surface); padding: 1px 5px; 915} 916 917/* ===== SECURITY / TRUST grid ===== */ 918.trust { 919 display: grid; 920 grid-template-columns: repeat(3, 1fr); 921 gap: 1px; 922 background: var(--nb-divider); 923 border: 1px solid var(--nb-divider); 924 border-radius: var(--nb-radius-lg); 925 overflow: hidden; 926} 927@media (max-width: 880px) { .trust { grid-template-columns: 1fr 1fr; } } 928@media (max-width: 560px) { .trust { grid-template-columns: 1fr; } } 929.trust-card { background: var(--nb-card); padding: 28px 26px; } 930.trust-ico { 931 width: 26px;
931 height: 26px; margin-bottom: 16px; 932 display: flex; align-items: center; justify-content: center; 933 color: var(--nb-accent); 934} 935.trust-ico svg { width: 22px; height: 22px; display: block; } 936.trust-card h3 { 937 font-family: var(--nb-font-mono); font-size: 15px; font-weight: 700; 938 letter-spacing: -0.025em; color: var(--nb-ink); margin: 0 0 8px; 939} 940.trust-card p { 941 font-family: var(--nb-font-sans); font-size: 13.5px; color: var(--nb-ink-muted); 942 line-height: 1.6; margin: 0; 943} 944 945/* ===== MID-PAGE CTA BAND ===== */ 946.cta-band { 947 background: var(--nb-accent-soft); 948 border-top: 1px solid var(--nb-accent-line); 949 border-bottom: 1px solid var(--nb-accent-line); 950 padding: 64px 0; 951 text-align: center; 952} 953.cta-band h2 { 954 font-family: var(--nb-font-mono); font-size: clamp(26px, 3.2vw, 36px); font-weight: 700; 955 letter-spacing: -0.04em; line-height: 1.1; color: var(--nb-ink); margin: 0 0 14px; 956} 957.cta-band p { font-family: var(--nb-font-mono); font-size: 12px; color: var(--nb-ink-muted); margin: 18px 0 0; letter-spacing: -0.005em; } 958 959/* ===== Terminal close card ===== */ 960.close-card { 961 background: var(--nb-card); 962 border: 1px solid var(--nb-divider); 963 border-radius: var(--nb-radius-lg); 964 overflow: hidden; 965} 966.close-bar { 967 height: 40px; display: flex; align-items: center; gap: 8px; padding: 0 16px; 968 border-bottom: 1px solid var(--nb-divider); font-family: var(--nb-font-mono); 969 font-size: 11px; color: var(--nb-ink-muted); 970} 971.close-bar .d { width: 10px; height: 10px; } 972.close-bar .d.r { background: var(--nb-accent); } 973.close-bar .d.m { background: var(--nb-divider); } 974.close-bar .t { margin-left: 8px; } 975.close-body { padding: 56px 40px 60px; text-align: center; } 976@media (max-width: 560px) { .close-body { padding: 40px 22px 44px; } } 977.close-body .kick { font-family: var(--nb-font-mono); font-size: 12px; color: var(--nb-accent); margin-bottom: 20px; } 978.close-body h2 { 979 font-family: var(--nb-font-mono); font-size: clamp(28px, 4vw, 44px); font-weight: 700; 980 letter-spacing: -0.045em; line-height: 1.06; color: var(--nb-ink); 981 margin: 0 auto 28px; max-width: 18ch; 982} 983.close-body .close-cta { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; align-items: center; } 984.close-body .reassure { font-family: var(--nb-font-mono); font-size: 11px; color: var(--nb-ink-muted); margin-top: 22px; } 985 986/* ===== FOOTER - showpiece ===== */ 987footer.site-foot { 988 position: relative; 989 border-top: 1px solid var(--nb-divider); 990 margin-top: 0; 991 padding: 80px 0 0; 992 font-family: var(--nb-font-mono); 993 font-size: 13px; 994 color: var(--nb-ink-muted); 995 background: var(--nb-paper); 996 overflow: hidden; 997} 998.foot-grid { 999 display: grid; 1000 grid-template-columns: 1.4fr 1fr 1fr 1fr 1fr; 1001 gap: 40px; 1002 margin-bottom: 88px; 1003} 1004@media (max-width: 880px) { .foot-grid { grid-template-columns: 1fr 1fr; gap: 36px 28px; } } 1005.foot-brand .nb-wordmark { font-size: 22px; color: var(--nb-ink); margin-bottom: 16px; } 1006.foot-brand p { 1007 font-family: var(--nb-font-sans); font-size: 13px; color: var(--nb-ink-muted); 1008 line-height: 1.6; max-width: 30ch; margin: 0 0 18px; 1009} 1010.foot-social { display: flex; gap: 10px; } 1011.foot-social a { 1012 width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; 1013 border: 1px solid var(--nb-divider); border-radius: var(--nb-radius-md); color: var(--nb-ink-muted); transition: color .15s, border-color .15s; 1014} 1015.foot-social a:hover { color: var(--nb-ink); border-color: var(--nb-accent-line); } 1016.foot-social svg { width: 16px; height: 16px; } 1017.foot-col h5 { 1018 color: var(--nb-ink-muted); 1019 font-family: var(--nb-font-mono); 1020 font-size: 12px; 1021 font-weight: 500; 1022 letter-spacing: -0.005em; 1023 margin: 0 0 18px; 1024} 1025.foot-col a { 1026 display: block; 1027 padding: 6px 0; 1028 font-size: 13px; 1029 color: var(--nb-ink-muted); 1030 transition: color .15s; 1031} 1032.foot-col a:hover { color: var(--nb-ink); } 1033.foot-legal { 1034 border-top: 1px solid var(--nb-divider); 1035 padding: 22px 0 26px; 1036 display: flex; 1037 justify-content: space-between; 1038 flex-wrap: wrap; 1039 gap: 12px; 1040 font-size: 12px; 1041 position: relative; 1042 z-index: 2; 1043} 1044.foot-legal .accent { color: var(--nb-accent); } 1045.foot-legal a { color: var(--nb-ink-muted); } 1046.foot-legal a:hover { color: var(--nb-ink); } 1047/* The signature move: GIANT ghosted wordmark sitting as a watermark behind 1048 * the whole footer. The full word reads, centered + contained, content above. */ 1049footer.site-foot { isolation: isolate; } 1050.foot-watermark { 1051 position: absolute; 1052 inset: 0; 1053 display: flex; 1054 align-items: center; 1055 justify-content: center; 1056 z-index: 0; 1057 pointer-events: none; 1058 user-select: none; 1059 overflow: hidden; 1060} 1061.foot-watermark span { 1062 font-family: var(--nb-font-mono); 1063 font-weight: 700; 1064 letter-spacing: -0.07em; 1065 /* Sized so the full word spans the footer width without clipping */ 1066 font-size: min(15.5vw, 248px); 1067 line-height: 1; 1068 color: var(--nb-ghost); 1069 white-space: nowrap; 1070 opacity: 0.9; 1071} 1072/* Footer columns + legal float above the watermark */ 1073.foot-grid, .foot-legal { position: relative; z-index: 1; } 1074@media (max-width: 720px) { .foot-watermark span { font-size: 22vw; } } 1075 1076/* ===== STICKY CTA BAR ===== */ 1077.sticky-cta { 1078 position: fixed; 1079 left: 0; right: 0; bottom: 0; 1080 z-index: 55; 1081 height: 60px; 1082 background: rgba(244,244,243,0.9); 1083 backdrop-filter: blur(14px); 1084 border-top: 1px solid var(--nb-divider); 1085 transform: translateY(110%); 1086 transition: transform .3s cubic-bezier(.2,.7,.2,1); 1087} 1088.sticky-cta.is-shown { transform: translateY(0); } 1089.sticky-cta-inner { 1090 height: 100%; 1091 display: flex; align-items: center; justify-content: space-between; gap: 16px; 1092} 1093.sticky-cta .msg { font-family: var(--nb-font-mono); font-size: 12px; color: var(--nb-ink-muted); letter-spacing: -0.005em; }
1094.sticky-cta .msg b { color: var(--nb-ink); font-weight: 500; } 1095@media (prefers-reduced-motion: reduce) { .sticky-cta { transition: none; } } 1096@media (max-width: 560px) { .sticky-cta { display: none; } } 1097</style>
1098<script> 1099 // Confirm JS is running before hiding any content for the scroll-reveal. 1100 // If this never runs (JS off/error), .nb-reveal stays visible (see CSS). 1101 document.documentElement.classList.add('js-reveal'); 1102 // Safety net: if the reveal observer never runs, force everything visible 1103 // after 3s so content can never be permanently invisible. 1104 setTimeout(function () { 1105 var els = document.querySelectorAll('.nb-reveal:not(.is-in)'); 1106 for (var i = 0; i < els.length; i++) els[i].classList.add('is-in'); 1107 }, 3000); 1108</script>
1108 1109</head> 1110<body> 1111 1112<header class="nav" id="nav"> 1113 <div class="nb-wrap nav-inner"> 1114 <a href="/" class="nb-wordmark" style="font-size:20px; color: var(--nb-ink);"> 1115 <span class="nb-name">notab<span class="nb-i">ı</span>um</span> 1116 </a> 1117 <nav class="nav-links"> 1118 <a href="#features">product</a> 1119 <a href="#pricing">pricing</a> 1120 <a href="/docs">docs</a> 1121 <a href="/blog">blog</a> 1122 <a href="/contact">contact</a> 1123 <span class="nav-lang" aria-label="Language"> 1124 <a href="/" data-lang="en" aria-current="page">EN</a> 1125 <a href="/sk" data-lang="sk">SK</a> 1126 <a href="/cs" data-lang="cs">CS</a> 1127 </span> 1128 </nav> 1129 <div class="nav-cta"> 1130 <a href="https://app.notabium.com/signin" class="nb-btn nb-btn--link" style="font-family:var(--nb-font-mono);">sign in</a> 1131 <a href="https://app.notabium.com/signin" class="nb-btn nb-btn--ember">start free trial <span style="opacity:0.6;">â</span></a> 1132 <button class="nav-burger" id="navBurger" aria-label="Open menu" aria-controls="navDrawer" aria-expanded="false"><span></span></button> 1133 </div> 1134 </div> 1135</header> 1136 1137<!-- MOBILE DRAWER --> 1138<div class="nav-drawer" id="navDrawer" role="dialog" aria-modal="true" aria-label="Menu"> 1139 <div class="nb-wrap nav-drawer-top" style="padding-left:0;padding-right:0;"> 1140 <a href="/" class="nb-wordmark" style="font-size:20px; color: var(--nb-ink);"> 1141 <span class="nb-name">notab<span class="nb-i">ı</span>um</span> 1142 </a> 1143 <button class="nav-drawer-close" id="navClose" aria-label="Close menu">×</button> 1144 </div> 1145 <a class="drawer-link" href="#features">product</a> 1146 <a class="drawer-link" href="#how">how it works</a> 1147 <a class="drawer-link" href="#pricing">pricing</a> 1148 <a class="drawer-link" href="/docs">docs</a> 1149 <a class="drawer-link" href="/blog">blog</a> 1150 <a class="drawer-link" href="https://app.notabium.com/signin">sign in</a> 1151 <a class="nb-btn nb-btn--ember" href="https://app.notabium.com/signin">start free trial <span style="opacity:0.6;">→</span></a> 1152</div> 1153 1154<section class="hero"> 1155 <div class="nb-wrap"> 1156 <div class="hero-grid"> 1157 <!-- LEFT: copy only --> 1158 <div class="hero-copy"> 1159 <div class="hero-prompt"><span class="accent">//</span> ai meeting notetaker</div> 1160 <h1>Meetings that take their <em class="nb-em">own notes</em>.</h1> 1161 <p class="lede">Live transcript with speaker names. AI summary, next steps, and a ready-to-send follow-up email. Record in your browser, use the Chrome extension, or send the notetaker to calls you can't attend. <strong>Works in Slovak and 100+ languages.</strong></p> 1162 <div class="cta-row" id="start"> 1163 <a href="https://app.notabium.com/signin" class="nb-btn nb-btn--ember">start free trial <span style="opacity:0.6;">↵</span></a> 1164 <a href="https://chromewebstore.google.com/detail/notabium-ai-meeting-notes/lmbgmkmopdbcpbdmebjeplbnjlokkedg" target="_blank" rel="noopener" class="nb-btn nb-btn--ink">get the Chrome extension <span style="opacity:0.6;">→</span></a> 1165 </div> 1166 </div> 1167 1168 <!-- RIGHT: interactive, animated sample call (client kickoff) --> 1169 <div class="hero-show"> 1170 <!-- INTERACTIVE SAMPLE CALL: the notabium notetaker joins a Meet-style call, 1171 a live transcript types with word-level highlighting, then the summary 1172 forms. Tabs are real clickable buttons. Loops; honors 1173 prefers-reduced-motion (composed static frame). --> 1174 <div class="sim nb-reveal" id="sim" 1175 aria-label="A sample meeting: the Notabium notetaker joins a Google Meet style call, transcribes it live with timestamps, and writes a summary with action items."> 1176 <div class="sim-callbar"> 1177 <span class="rec-dot nb-pulse" aria-hidden="true"></span> 1178 <span class="sim-callbar-label">live</span> 1179 <span class="sim-clock" id="simClock">00:00</span> 1180 <span class="sim-callbar-meet">Google Meet</span> 1181 </div> 1182 <div class="sim-tiles"> 1183 <div class="sim-tile" data-spk="P"> 1184 <span class="sim-ring" aria-hidden="true"></span>
1185 <span class="sim-avatar">PR</span> 1186 <span class="sim-name">Priya</span> 1187 </div> 1188 <div class="sim-tile" data-spk="M"> 1189 <span class="sim-ring" aria-hidden="true"></span> 1190 <span class="sim-avatar">MA</span> 1191 <span class="sim-name">Maya</span> 1192 </div> 1193 <div class="sim-tile" data-spk="S"> 1194 <span class="sim-ring" aria-hidden="true"></span> 1195 <span class="sim-avatar">SA</span> 1196 <span class="sim-name">Sam</span> 1197 </div> 1198 <!-- The notetaker tile that "joins" partway through --> 1199 <div class="sim-tile sim-tile--bot" data-spk="N"> 1200 <span class="sim-ring" aria-hidden="true"></span> 1201 <span class="sim-avatar sim-avatar--bot"> 1202 <span class="nb-glyph" aria-hidden="true"><i></i><i></i><i></i><i></i></span> 1203 </span> 1204 <span class="sim-name">notabium</span> 1205 <span class="sim-joinpill" id="simJoin">joining…</span> 1206 </div> 1207 </div> 1208 <div class="sim-panel"> 1209 <div class="sim-panel-head" role="tablist" aria-label="Sample call view"> 1210 <button type="button" class="sim-tab is-on" id="simTabT" role="tab" aria-selected="true" aria-controls="simTranscript">transcript</button> 1211 <button type="button" class="sim-tab" id="simTabS" role="tab" aria-selected="false" aria-controls="simSummary">summary</button> 1212 </div> 1213 <div class="sim-panel-body"> 1214 <!-- Live transcript view --> 1215 <div class="sim-transcript" id="simTranscript" role="tabpanel" aria-labelledby="simTabT"></div> 1216 <!-- Summary view (revealed after transcript) --> 1217 <div class="sim-summary" id="simSummary" role="tabpanel" aria-labelledby="simTabS" hidden> 1218 <p class="sim-sum-label">Summary</p> 1219 <ul> 1220 <li>Lumen website rebuild kicked off. Design is locked before build begins.</li> 1221 <li>Target soft launch in <strong>5 weeks</strong>.</li> 1222 </ul> 1223 <p class="sim-sum-label">Action items</p> 1224 <ul> 1225 <li class="act">Wireframes for 5 core pages by Friday + send the client a content/logins form <sp
1225an class="who">Maya</span></li> 1226 <li class="act">Stand up the staging environment this week <span class="who">Sam</span></li> 1227 <li class="act">Book the Thursday check-in <span class="who">Priya</span></li> 1228 </ul> 1229 </div> 1230 </div> 1231 </div> 1232 </div> 1233 </div> 1234 </div> 1235 </div> 1236</section> 1237 1238<!-- WORKS-WITH STRIP --> 1239<style> 1240/* === interactive polish: marquee, demo flow, mode hover-reveal, seat calc === */ 1241.ww-marquee{ flex:1 1 300px; min-width:0; overflow:hidden; 1242 -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent); 1243 mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent); } 1244.ww-track{ display:inline-flex; align-items:center; gap:28px; white-space:nowrap; will-change:transform; animation:ww-scroll 26s linear infinite; } 1245.ww-track span{ font-family:var(--nb-font-mono); font-size:15px; letter-spacing:-0.03em; color:var(--nb-ink-muted); transition:color .15s; } 1246.ww-track span:hover{ color:var(--nb-ink); } 1247.ww-track i{ color:var(--nb-divider); font-style:normal; font-size:12px; } 1248.ww-marquee:hover .ww-track{ animation-play-state:paused; } 1249@keyframes ww-scroll{ from{transform:translateX(0)} to{transform:translateX(-50%)} } 1250 1251.dstep-num{ display:inline-flex; align-items:center; gap:7px; } 1252.dstep-num::before{ content:""; width:6px; height:6px; border-radius:50%; background:var(--nb-accent); box-shadow:0 0 0 3px var(--nb-accent-soft); } 1253.dstep-arrow{ color:var(--nb-accent); animation:dstep-flow 1.9s ease-in-out infinite; } 1254.dstep-arrow:nth-of-type(4){ animation-delay:.6s; } 1255@keyframes dstep-flow{ 0%,100%{ transform:translateX(0); opacity:.4 } 50%{ transform:translateX(5px); opacity:1 } } 1256 1257.mode{ position:relative; } 1258.mode-reveal{ margin-top:14px; font-family:var(--nb-font-mono); font-size:12px; letter-spacing:-0.01em; 1259 color:var(--nb-accent); display:flex; align-items:center; gap:8px; 1260 opacity:0; transform:translateY(6px); transition:opacity .25s ease, transform .25s cubic-bezier(.2,.7,.2,1); } 1261.mode-reveal::before{ content:""; width:14px; height:1px; background:var(--nb-accent); flex:none; } 1262.mode:hover .mode-reveal, .mode:focus-within .mode-reveal{ opacity:1; transform:none; } 1263 1264.seatcalc{ display:flex; align-items:center; gap:10px; margin:4px 0 2px; } 1265.seatcalc-step{ width:30px; height:30px; border-radius:9px; border:1px solid var(--nb-divider); background:var(--nb-card); 1266 font-size:18px; line-height:1; color:var(--nb-ink); cursor:pointer; display:inline-flex; align-items:center; justify-content:center; 1267 transition:border-color .15s, color .15s; } 1268.seatcalc-step:hover:not(:disabled){ border-color:var(--nb-accent); color:var(--nb-accent); } 1269.seatcalc-step:disabled{ opacity:.4; cursor:not-allowed; } 1270.seatcalc-seats{ font-family:var(--nb-font-mono); font-size:13px; color:var(--nb-ink-muted); min-width:62px; text-align:center; } 1271.seatcalc-total{ margin-left:auto; font-family:var(--nb-font-mono); font-size:15px; font-weight:700; color:var(--nb-ink); font-variant-numeric:tabular-nums; } 1272 1273.bill-switch{ text-align:center; margin:-8px 0 30px; } 1274.bill-toggle{ display:inline-flex; align-items:center; gap:3px; padding:3px; border:1px solid var(--nb-divider); border-radius:999px; background:var(--nb-card); } 1275.bill-toggle button{ appearance:none; border:0; background:transparent; cursor:pointer; font-family:var(--nb-font-mono); font-size:13px; letter-spacing:-0.01em; color:var(--nb-ink-muted); padding:8px 16px; border-radius:999px; display:inline-flex; align-items:center; gap:8px; transition:color .18s, background .18s; } 1276.bill-toggle button:hover{ color:var(--nb-ink); } 1277.bill-toggle button.is-on{ background:var(--nb-accent); color:#fff; } 1278.bill-toggle .save-pill{ font-size:10px; padding:2px 7px; border-radius:999px; background:var(--nb-accent-soft); color:var(--nb-accent); } 1279.bill-toggle button.is-on .save-pill{ background:rgba(255,255,255,.24); color:#fff; } 1280.price-amount sup .perseat-y{ display:none; } 1281 1282@media (prefers-reduced-motion: reduce){ 1283 .ww-track{ animation:none; } .ww-marquee{ -webkit-mask-image:none; mask-image:none; } 1284 .dstep-arrow{ animation:none; opacity:.6; } 1285 .mode-reveal{ transition:none; } 1286} 1287 1288/* ===== ENHANCED MOTION (taseful, ember brand) ===== 1289 * Staggered bento / feature card reveals, hover-lift glow on cards + CTAs, 1290 * and a gentle float on the hero sample-call mockup. 1291 * All motion gated behind prefers-reduced-motion. */ 1292 1293/* Staggered reveal: bento cells and feature cards pick up a delay from their 1294 * data-stagger attribute (set via JS below). The reveal itself is the existing 1295 * .nb-reveal / .is-in fade+rise, we just offset when each card becomes "in". */ 1296.bento .cell, 1297.modes .mode, 1298.features .feature, 1299.trust .trust-card, 1300.how .how-step { 1301 transition-property: opacity, transform; 1302 transition-timing-function: cubic-bezier(.2,.6,.2,1); 1303 transition-duration: .55s; 1304} 1305/* Stagger delay is applied inline via JS */ 1306 1307/* Hover-lift + ember glow on cards */ 1308.cell.nb-lift:hover, 1309.mode.nb-lift:hover, 1310.feature.nb-lift:hover, 1311.trust-card.nb-lift:hover, 1312.dstep.nb-lift:hover { 1313 transform: translateY(-4px); 1314 box-shadow: 0 8px 28px rgba(255, 92, 26, 0.10), 0 2px 6px rgba(26,25,21,.06); 1315 border-color: var(--nb-accent-line) !important; 1316} 1317 1318/* Ember glow on primary CTA buttons */ 1319.nb-btn--ember { 1320 box-shadow: 0 2px 10px rgba(255, 92, 26, 0.18); 1321 transition: background .15s, box-shadow .2s ease, transform .15s ease, opacity .15s; 1322} 1323.nb-btn--ember:hover { 1324 box-shadow: 0 4px 20px rgba(255, 92, 26, 0.32); 1325 transform: translateY(-1px); 1326} 1327.nb-btn--ember:active { 1328 transform: translateY(0); 1329 box-shadow: 0 1px 6px rgba(255, 92, 26, 0.18); 1330} 1331 1332/* Hero sim card: gentle float when visible */ 1333.hero-show .sim { 1334 animation: nb-float 5s ease-in-out infinite; 1335} 1336 1337/* Smooth transitions on section/card border-color */ 1338.cell, .mode, .trust-card, .dstep { 1339 transition: transform .18s ease, box-shadow .2s ease, border-color .2s ease, background .15s ease; 1340} 1341 1342@media (prefers-reduced-motion: reduce) { 1343 .cell.nb-lift:hover, 1344 .mode.nb-lift:hover, 1345 .feature.nb-lift:hover, 1346 .trust-card.nb-lift:hover, 1347 .dstep.nb-lift:hover { 1348 transform: none; 1349 box-shadow: none; 1350 } 1351 .nb-btn--ember { 1352 box-shadow: none; 1353 transition: background .15s, opacity .15s; 1354 } 1355 .nb-btn--ember:hover { transform: none; box-shadow: none; } 1356 .hero-show .sim { animation: none; } 1357 .cell, .mode, .trust-card, .dstep { transition: none; } 1358} 1359</style> 1360<section class="workswith">
1361 <div class="nb-wrap workswith-inner"> 1362 <div class="ww-label">records the calls you already run</div> 1363 <div class="ww-marquee"> 1364 <div class="ww-track"> 1365 <span>Zoom</span><i>/</i><span>Google Meet</span><i>/</i><span>Microsoft Teams</span><i>/</i><span>Chrome extension</span><i>/</i><span>Google Calendar</span><i>/</i><span>Outlook</span><i>/</i><span>audio upload</span><i>/</i> 1366 <span>Zoom</span><i>/</i><span>Google Meet</span><i>/</i><span>Microsoft Teams</span><i>/</i><span>Chrome extension</span><i>/</i><span>Google Calendar</span><i>/</i><span>Outlook</span><i>/</i><span>audio upload</span><i>/</i> 1367 </div> 1368 </div> 1369 </div> 1370</section> 1371 1372<!-- DEMO / SEE IT WORK --> 1373<section class="section section--demo" id="demo"> 1374 <div class="nb-wrap"> 1375 <div class="section-head nb-reveal" style="text-align:center; margin-left:auto; margin-right:auto;"> 1376 <div class="kicker">// see it work</div> 1377 <h2 style="margin-left:auto; margin-right:auto;">Sixty seconds, start to finish.</h2> 1378 <p class="sub" style="margin-left:auto; margin-right:auto;">Record a call, watch the transcript and summary appear, then share it or send the notetaker to the next one. No install required.</p> 1379 </div> 1380 </div> 1381 1382 <div class="nb-wrap"> 1383 <div class="demo-steps nb-reveal"> 1384 <div class="dstep nb-lift"> 1385 <div class="dstep-num">01</div> 1386 <h3>Record</h3> 1387 <p>Hit record in the browser, add the extension, or send the notetaker to a call you can't attend.</p> 1388 </div> 1389 <div class="dstep-arrow" aria-hidden="true">→</div> 1390 <div class="dstep nb-lift"> 1391 <div class="dstep-num">02</div> 1392 <h3>Transcribe & summarize</h3> 1393 <p>Live transcript with speaker labels, then a clean summary with every decision and action item.</p> 1394 </div> 1395 <div class="dstep-arrow" aria-hidden="true">→</div> 1396 <div class="dstep nb-lift"> 1397 <div class="dstep-num">03</div> 1398 <h3>Ask or share</h3> 1399 <p>Ask any meeting a question and get a cited answer, or share a watchable link. No account needed to view.</p> 1400 </div> 1401 </div> 1402 </div> 1403</section> 1404 1405<!-- THREE WAYS TO CAPTURE --> 1406<section class="section" id="features"> 1407 <div class="nb-wrap"> 1408 <div class="section-head nb-reveal"> 1409 <div class="kicker">// 01 · capture</div> 1410 <h2>Three ways to capture a call.</h2> 1411 <p class="sub">In your browser, via the Chrome extension on Meet, Teams, or Zoom, or by sending the Notabium Notetaker to a call you can't attend. You pick the mode per meeting. Every one lands in the same library.</p> 1412 </div> 1413 1414 <div class="modes nb-reveal"> 1415 <div class="mode nb-lift"> 1416 <div class="mode-head"> 1417 <span class="num">01</span> 1418 <span class="tier">chrome extension</span> 1419 </div> 1420 <h3>Live transcript, no bot, no captions</h3> 1421 <p>Install the Chrome extension once and a record button appears straight on Meet, Teams, and Zoom. It captures a live transcript with speaker names without sending a bot and without asking you to turn on captions.</p> 1422 <div class="mode-reveal">live transcript in-call, no bot, tab-audio fallback</div> 1423 </div> 1424 <div class="mode nb-lift"> 1425 <div class="mode-head"> 1426 <span class="num">02</span> 1427 <span class="tier">notetaker bot · pro</span> 1428 </div> 1429 <h3>The notetaker that attends for you</h3> 1430 <p>Can't make it? Paste the meeting link or let calendar auto-join handle it. The Notabium Notetaker joins your Zoom, Meet, or Teams call, names itself in the participant list, records, and delivers the notes when it ends.</p> 1431 <div class="mode-reveal">joins Zoom, Meet & Teams · auto-join from Google or Outlook calendar</div> 1432 </div> 1433 <div class="mode nb-lift"> 1434 <div class="mode-head"> 1435 <span class="num">03</span> 1436 <span class="tier">upload</span> 1437 </div> 1438 <h3>Drop in an audio or video file</h3> 1439 <p>Already have a recording? Upload an audio or video file and Notabium transcribes, labels speakers, and produces a summary with action items - the same output as a live call.</p> 1440 <div class="mode-reveal">MP3, MP4, M4A, WAV and more · same pipeline, same output</div> 1441 </div> 1442 </div> 1443 </div> 1444</section> 1445 1446<!-- FEATURES (bento) --> 1447<section class="section"> 1448 <div class="nb-wrap"> 1449 <div class="section-head nb-reveal"> 1450 <div class="kicker">// 02 · features</div> 1451 <h2>What it actually does.</h2> 1452 <p class="sub">Live transcript with speaker names, AI summary, follow-up email, in-call AI tips, emoji highlights, calendar auto-join, and one-tap sharing. It all ships with Pro, no add-ons.<
1452/p> 1453 </div> 1454 1455 <div class="bento nb-reveal"> 1456 <!-- SCREENSHOT: bento focal cell showing the live transcript overlay with speaker names and emoji highlights --> 1457 <div class="cell col2 row2 focal nb-lift"> 1458 <div class="cell-head"><span class="cell-num">01</span><span class="cell-badge">cited answers</span></div> 1459 <h3>AI chat, live and after the call</h3> 1460 <p>Mid-call, ask the AI assistant for suggested next steps or a quick briefing on what was just decided. After the call, ask any question and get the answer with the exact transcript moment cited - across your whole library, not one file at a time.</p> 1461 <div class="spacer"></div> 1462 <!-- SCREENSHOT: chat panel showing a mid-call AI assistant tip --> 1463 <p style="font-family:var(--nb-font-mono);font-size:12px;color:var(--nb-ink-muted);margin-top:18px;">$ "what action items came up so far?"</p> 1464 </div> 1465 <div class="cell col2 nb-lift"> 1466 <div class="cell-head"><span class="cell-num">02</span><span class="cell-badge">speaker labels</span></div> 1467 <h3>Live transcript with speaker names</h3> 1468 <p>Every word labelled with who said it and when - while you stay in the conversation, not in a notes doc.</p> 1469 <!-- SCREENSHOT: live transcript rail with speaker avatars and timestamps --> 1470 </div> 1471 <div class="cell nb-lift"> 1472 <div class="cell-head"><span class="cell-num">03</span><span class="cell-badge">no setup</span></div> 1473 <h3>Summary and next steps</h3> 1474 <p>Every recording becomes a clean AI summary with decisions, next steps, and action items with owners.</p> 1475 </div> 1476 <div class="cell nb-lift"> 1477 <div class="cell-head"><span class="cell-num">04</span><span class="cell-badge">one tap</span></div> 1478 <h3>Follow-up email, ready to send</h3> 1479 <p>A draft follow-up email with a subject line, written from the summary. Copy it, send it, done.</p> 1480 </div> 1481 <div class="cell col2 nb-lift"> 1482 <div class="cell-head"><span class="cell-num">05</span><span class="cell-badge">highlights</span></div> 1483 <h3>Emoji highlights and in-call screenshots</h3> 1484 <p>Tag moments mid-call as a decision, action, question, or idea with a single emoji. Take in-call screenshots that save straight to the meeting record. Review everything in one place after.</p> 1485 <!-- SCREENSHOT: highlight rail showing emoji tags and a captured screenshot thumbnail --> 1486 </div> 1487 <div class="cell nb-lift"> 1488 <div class="cell-head"><span class="cell-num">06</span><span class="cell-badge">calendar</span></div> 1489 <h3>Calendar auto-join</h3> 1490 <p>Connect Google or Outlook and the notetaker joins your scheduled meetings on time - no copy-pasting links.</p> 1491 </div> 1492 <div class="cell nb-lift"> 1493 <div class="cell-head"><span class="cell-num">07</span><span class="cell-badge">multilingual</span></div> 1494 <h3>Slovak-first, 100+ languages</h3> 1495 <p>Slovak is the primary language. Auto-detect handles the rest - transcript and app adapt to the meeting language.</p> 1496 </div> 1497 <div class="cell nb-lift"> 1498 <div class="cell-head"><span class="cell-num">08</span><span class="cell-badge">audio only</span></div> 1499 <h3>No video stored</h3> 1500 <p>Audio is kept for playback. No video is stored. The transcript is yours and always exportable.</p> 1501 </div> 1502 <div class="cell col2 nb-lift"> 1503 <div class="cell-head"><span class="cell-num">09</span><span class="cell-badge">sharing</span></div> 1504 <h3>Share with one tap</h3> 1505 <p>Generate a public link - the recipient sees the summary, transcript, and audio. No Notabium account needed to view. Revoke the link anytime.</p> 1506 <!-- SCREENSHOT: share dialog with public link toggle and preview --> 1507 </div> 1508 </div> 1509 </div> 1510</section> 1511 1512<!-- SECURITY / TRUST --> 1513<section class="section"> 1514 <div class="nb-wrap"> 1515 <div class="section-head nb-reveal"> 1516 <div class="kicker">// 03 · trust</div> 1517 <h2>Built for conversations that should stay private.</h2> 1518 <p class="sub">Therapists, lawyers, founders, recruiters - the people who use Notabium have meetings that should not live on a vendor's server. So they don't have to.</p> 1519 </div> 1520 1521 <div class="trust nb-reveal"> 1522 <div class="trust-card nb-lift"> 1523 <div class="trust-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M12 3l7 3v5c0 4.5-3 7.5-7 9-4-1.5-7-4.5-7-9V6l7-3z"/></svg></div> 1524 <h3>Your data, your control</h3> 1525 <p>Export it, delete it, or self-host it. Your meetings belong to you, and you decide where they live.</p> 1526 </div> 1527 <div class="trust-card nb-lift"> 1528 <div class="trust-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="10" width="16" height="10"/><path d="M8 10V7a4 4 0 018 0v3"/></svg></div> 1529 <h3>Encrypted in transit and at rest</h3> 1530 <p>Everything moves over TLS and is encrypted on disk. No plaintext recordings sitting on a server.</p> 1531 </div> 1532 <div class="trust-card nb-lift"> 1533 <div class="trust-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M5 7h14M9 7V5h6v2M7 7l1 13h8l1-13"/></svg></div> 1534 <h3>You decide what's deleted</h3> 1535 <p>Set retention, or wipe any meeting on demand. When it's gone, it's gone for good.</p> 1536 </div> 1537 <div class="trust-card nb-lift"> 1538 <div class="trust-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M5.6 5.6l12.8 12.8"/></svg></div> 1539 <h3>No training on your meetings</h3> 1540 <p>Your recordings and transcripts are never used to train models. Full stop.</p> 1541 </div> 1542 <div class="trust-card nb-lift"> 1543 <div class="trust-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M9 12l2 2 4-4"/></svg></div> 1544 <h3>Recording consent built in</h3> 1545 <p>A consent reminder fires on your timezone, and the notetaker always names itself in the participant list.</p> 1546 </div> 1547 <div class="trust-card nb-lift"> 1548 <div class="trust-ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 6h16M4 12h16M4 18h10"/></svg></div> 1549 <h3>GDPR-ready and self-host-friendly</h3> 1550 <p>Run it in the cloud, or bring it in-house. Built to fit how your team handles data.</p> 1551 </div> 1552 </div> 1553 </div> 1554</section> 1555 1556<!-- MID-PAGE CTA BAND --> 1557<section class="cta-band"> 1558 <div class="nb-wrap"> 1559 <h2>Stop taking notes. Start being in the room.</h2> 1560 <a href="https://app.notabium.com/signin" class="nb-btn nb-btn--ember">start free trial <span style="opacity:0.6;">âµ</span></a> 1561 <p>7-day free trial, cancel anytime</p> 1562 </div> 1563</section> 1564 1565<!-- PRICING --> 1566<section class="section" id="pricing"> 1567 <div class="nb-wrap"> 1568 <div class="section-head nb-reveal"> 1569 <div class="kicker">// 04 · pricing</div> 1570 <h2>The AI notetaker that joins your calls. €19.99/mo.</h2> 1571 <p class="sub">Record in your browser or send the Notabium Notetaker to Zoom, Meet, and Teams. Every meeting comes back as a transcript with an AI summary, action items, and a chat. Pro is for you; Team brings it to your whole company. Start with a 7-day free trial of Pro, card required.</p> 1572 </div> 1573 1574 <div class="bill-switch nb-reveal"> 1575 <div class="bill-toggle" role="group" aria-label="Billing period"> 1576 <button type="button" class="bill-opt is-on" data-bill="monthly" aria-pressed="true">Monthly</button> 1577 <button type="button" class="bill-opt" data-bill="annual" aria-pressed="false">Annual <span class="save-pill">save 30%</span></button> 1578 </div> 1579 </div> 1580 1581 <div class="price-grid nb-reveal"> 1582 <div class="price featured"> 1583 <div class="price-tier featured">// pro · recommended</div> 1584 <div class="price-amount">â¬<span id="proAmt">19.99</span><sup>/ mo</sup></div> 1585 <div class="price-cents"><span id="proBill">7-day free trial · card required</span><br><span class="save">cancel anytime</span></div> 1586 <ul> 1587 <li>Record in your browser</li> 1588 <li>The notetaker that joins your calls</li> 1589 <li>Works on Zoom, Meet & Teams</li> 1590 <li>Transcript, AI summary & action items</li> 1591 <li>Chat with the meeting</li> 1592 <li>Calendar auto-join</li> 1593 <li>Video recordings</li> 1594 <li>Shareable recordings & links</li> 1595 <li>Unlimited usage · priority support</li> 1596 </ul> 1597 <a href="https://app.notabium.com/signin" class="nb-btn nb-btn--ember price-cta">start free trial âµ</a> 1598 </div> 1599 1600 <div class="price"> 1601 <div class="price-tier">// team</div> 1602 <div class="price-amount">â¬<span id="teamBase">
160215.99</span><sup>/ mo + â¬<span id="teamSeat">8</span> / seat</sup></div> 1603 <div class="seatcalc" data-min="3" 1604 data-base-monthly="15.99" data-seat-monthly="8" 1605 data-base-annual="11.19" data-seat-annual="5.60"> 1606 <button type="button" class="seatcalc-step" data-d="-1" aria-label="Remove a seat">−</button> 1607 <span class="seatcalc-seats"><span id="seatN">3</span> seats</span> 1608 <button type="button" class="seatcalc-step" data-d="1" aria-label="Add a seat">+</button> 1609 <span class="seatcalc-total" aria-live="polite">â¬<span id="seatTotal">39.99</span>/mo</span> 1610 </div> 1611 <div class="price-cents"><span id="teamBill">billed monthly</span> · <span class="save">minimum 3 seats</span></div> 1612 <ul> 1613 <li>Everything in Pro, per seat</li> 1614 <li>Shared team workspace</li> 1615 <li>Notetaker, auto-join & unlimited per seat</li> 1616 <li>Shared recordings & libraries</li> 1617 <li>Centralized team billing</li> 1618 <li>Admin & member roles</li> 1619 <li>Add or remove seats anytime</li> 1620 <li>Priority support</li> 1621 </ul> 1622 <a href="https://app.notabium.com/signin" class="nb-btn nb-btn--ghost-night price-cta">start team â</a> 1623 </div> 1624 1625 <div class="price"> 1626 <div class="price-tier">// enterprise</div> 1627 <div class="price-amount price-amount--custom">Custom</div> 1628 <div class="price-cents">for organizations at scale<br><span class="save">talk to sales</span></div> 1629 <ul> 1630 <li>Everything in Team</li> 1631 <li>SSO & SCIM provisioning</li> 1632 <li>Custom data retention & residency</li> 1633 <li>Self-hosted or private cloud</li> 1634 <li>DPA, security review & audit support</li> 1635 <li>Volume seat pricing</li> 1636 <li>Dedicated onboarding</li> 1637 <li>Priority SLA & named contact</li> 1638 </ul> 1639 <a href="/contact-sales" class="nb-btn nb-btn--ink price-cta">talk to sales â</a> 1640 </div> 1641 </div> 1642 1643 <p style="text-align:center; margin-top:24px; font-family:var(--nb-font-mono); font-size:11px; color:var(--nb-ink-muted);"> 1644 Team example: 3 seats = â¬15.99 base + 3 à â¬8 = <span style="color: var(--nb-ink);">â¬39.99/mo</span> · minimum 3 seats · need more? <a href="/contact-sales" style="color: var(--nb-ink); border-bottom:1px solid var(--nb-divider);">talk to sales</a> 1645 </p> 1646 </div> 1647</section> 1648
1649<script> 1650 /* Billing toggle (monthly / annual, 30% off) + live Team seat calculator. 1651 Annual rates are 0.70 à monthly: Pro 19.99â13.99/mo; Team 15.99â11.19 base, 1652 8â5.60 per seat (3 seats = 39.99/mo monthly vs 27.99/mo billed annually). */ 1653 (function(){ 1654 var PRICES={ 1655 monthly:{ pro:'19.99', proBill:'7-day free trial · card required', teamBase:'15.99', teamSeat:'8', base:15.99, seat:8, teamBill:'billed monthly' }, 1656 annual: { pro:'13.99', proBill:'billed â¬167.88/yr · 7-day free trial', teamBase:'11.19', teamSeat:'5.60', base:11.19, seat:5.60, teamBill:'billed annually' } 1657 }; 1658 var mode='monthly', n=3; 1659 var calc=document.querySelector('.seatcalc'); 1660 var min=calc?parseInt(calc.dataset.min,10):3; 1661 var seatN=document.getElementById('seatN'), seatTotal=document.getElementById('seatTotal'), 1662 minus=calc?calc.querySelector('[data-d="-1"]'):null; 1663 var proAmt=document.getElementById('proAmt'), proBill=document.getElementById('proBill'), 1664 teamBase=document.getElementById('teamBase'), teamSeat=d
1664ocument.getElementById('teamSeat'), 1665 teamBill=document.getElementById('teamBill'); 1666 function render(){ 1667 var p=PRICES[mode]; 1668 if(proAmt) proAmt.textContent=p.pro; 1669 if(proBill) proBill.textContent=p.proBill; 1670 if(teamBase) teamBase.textContent=p.teamBase; 1671 if(teamSeat) teamSeat.textContent=p.teamSeat; 1672 if(teamBill) teamBill.textContent=p.teamBill; 1673 if(seatN) seatN.textContent=n; 1674 if(seatTotal) seatTotal.textContent=(p.base+p.seat*n).toFixed(2); 1675 if(minus) minus.disabled=(n<=min); 1676 } 1677 if(calc) calc.addEventListener('click',function(e){ var b=e.target.closest('.seatcalc-step'); if(!b) return; 1678 n=Math.max(min, Math.min(200, n+parseInt(b.dataset.d,10))); render(); }); 1679 var opts=document.querySelectorAll('.bill-opt'); 1680 Array.prototype.forEach.call(opts,function(btn){ 1681 btn.addEventListener('click',function(){ 1682 mode=btn.dataset.bill; 1683 Array.prototype.forEach.call(opts,function(o){ var on=(o===btn); 1684 o.classList.toggle('is-on',on); o.setAttribute('aria-pressed',on?'true':'false'); }); 1685 render(); 1686 }); 1687 }); 1688 render(); 1689 })(); 1690</script>
1690 1691<!-- FAQ --> 1692<section class="section"> 1693 <div class="nb-wrap"> 1694 <div class="section-head nb-reveal" style="text-align: center; margin-left: auto; margin-right: auto;"> 1695 <div class="kicker">// 05 · faq</div> 1696 <h2 style="margin-left:auto; margin-right:auto;">The honest answers.</h2> 1697 </div> 1698 1699 <div class="faq nb-reveal"> 1700 <details open> 1701 <summary>Do I have to tell people I'm recording?</summary> 1702 <p>That's your call, and the law depends on where you are - most places allow one-party consent, some require everyone to agree. Notabium surfaces a consent reminder based on your set timezone so you're never caught out. When you send the notetaker, it always identifies itself in the participant list, so nobody is recorded in secret.</p> 1703 </details> 1704 <details> 1705 <summary>Does the notetaker show up with a name in the call?</summary> 1706 <p>Yes. The Notabium Notetaker appears in the participant list with a clear name, never speaks, and never hides. It never acts on your behalf. People can see it's there. It joins, records, and delivers the notes to your library when the call ends.</p> 1707 </details> 1708 <details> 1709 <summary>What happens to my data, and can I delete it?</summary> 1710 <p>Your meetings are yours. Everything is encrypted in transit and at rest, never used to train models, and you can export or delete any meeting on demand. Set a retention window, or wipe a recording whenever you want. Notabium is GDPR-ready and self-host-friendly if you'd rather keep it in-house.</p> 1711 </details> 1712 <details> 1713 <summary>How accurate is it, and which languages does it handle?</summary> 1714 <p>Transcripts are speaker-labelled with exact timestamps and work across 100+ languages, detected automatically. Accuracy is strongest with clear audio, and the AI summary pulls the decisions and action items rather than padding the text. You always have the full transcript to check against.</p> 1715 </details> 1716 <details> 1717 <summary>Do I need to install anything?</summary> 1718 <p>No. Notabium runs in your browser - sign in at app.notabium.com, hit record, and you're going. The Chrome extension is optional and adds a record button straight onto Zoom, Meet, and Teams. The notetaker needs no install at all.</p> 1719 </details> 1720 <details> 1721 <summary>What does it cost, and can I cancel?</summary> 1722 <p>Pro is €19.99/mo and includes everything: record in your browser or send the Notabium Notetaker to Zoom, Meet, and Teams, transcripts, AI summaries, action items, chat with the meeting, calendar auto-join, video, and unlimited usage. It starts with a 7-day free trial (card required), and you can cancel anytime - Pro stays active until the end of the period and you're not billed again. Team is €15.99/mo base plus €8 per seat, minimum 3 seats, so from €39.99/mo.</p> 1723 </details> 1724 </div> 1725 </div> 1726</section> 1727 1728<!-- FINAL CTA - terminal window card --> 1729<section class="section section--plain"> 1730 <div class="nb-wrap"> 1731 <div class="close-card nb-reveal"> 1732 <div class="close-bar"> 1733 <span class="d r"></span><span class="d m"></span><span class="d m"></span> 1734 <span class="t">notabium · start free trial</span> 1735 </div> 1736 <div class="close-body"> 1737 <div class="kick">// ready when you are</div> 1738 <h2>Ready for meetings that take their own notes?</h2> 1739 <div class="close-cta"> 1740 <a href="https://app.notabium.com/signin" class="nb-btn nb-btn--ember">start free trial <span style="opacity:0.6;">âµ</span></a> 1741 <a href="#demo" class="nb-btn nb-btn--ghost-night">see it work</a> 1742 </div> 1743 <p class="reassure">no card to explore the demo · 7-day free trial · cancel anytime</p> 1744 </div> 1745 </div> 1746 </div> 1747</section> 1748 1749<!-- FOOTER - showpiece --> 1750<footer class="site-foot"> 1751 <div class="nb-wrap"> 1752 <div class="foot-grid"> 1753 <div class="foot-brand"> 1754 <div class="nb-wordmark"> 1755 <span class="nb-name">notab<span class="nb-i">ı</span>um</span> 1756 </div> 1757 <p>The intelligent record. A notetaker that listens, transcribes, and quietly understands.</p> 1758 <div class="foot-social"> 1759 <a href="https://app.notabium.com" aria-label="Open the app"> 1760 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M5 12h14M13 6l6 6-6 6"/></svg> 1761 </a> 1762 <a href="/download" aria-label="Get the Chrome extension" title="Get the Chrome extension"><svg viewBox="0 0 24 24" fill="currentColor"><path d="M20.5 11H19V7a2 2 0 0 0-2-2h-4V3.5a2.5 2.5 0 0 0-5 0V5H4a2 2 0 0 0-2 2v3.8h1.5a2.2 2.2 0 1 1 0 4.4H2V19a2 2 0 0 0 2 2h3.8v-1.5a2.2 2.2 0 1 1 4.4 0V21H17a2 2 0 0 0 2-2v-4h1.5a2.5 2.5 0 0 0 0-5z"/></svg></a> 1763 </div> 1764 </div> 1765 <div class="foot-col"> 1766 <h5>Product</h5> 1767 <a href="#features">Record</a> 1768 <a href="#features">Notetaker</a> 1769 <a href="/download">Extension</a> 1770 <a href="#pricing">Pricing</a> 1771 </div> 1772 <div class="foot-col"> 1773 <h5>Company</h5> 1774 <a href="/about">About</a> 1775 <a href="/blog">Blog</a> 1776 <a href="mailto:[email protected]">Careers</a> 1777 </div> 1778 <div class="foot-col"> 1779 <h5>Resources</h5> 1780 <a href="/download">Docs & download</a> 1781 <a href="/security">Security</a> 1782 <a href="https://app.notabium.com/signin">Sign in</a> 1783 <a href="/contact">Contact</a> 1784 </div> 1785 <div class="foot-col"> 1786 <h5>Legal</h5> 1787 <a href="/privacy">Privacy</a> 1788 <a href="/terms">Terms</a> 1789 <a href="/credits">Credits</a> 1790 </div> 1791 </div> 1792 <div class="foot-legal">
1793 <span><span class="accent">©</span> Notabium 2026</span> 1794 <span><a href="/privacy">privacy</a> · <a href="/security">security</a> · <a href="/terms">terms</a> · <a href="mailto:[email protected]">[email protected]</a></span> 1795 </div> 1796 </div> 1797 <div class="foot-watermark" aria-hidden="true"><span>notabium</span></div> 1798</footer> 1799 1800<!-- STICKY CTA BAR --> 1801<div class="sticky-cta" id="stickyCta" aria-hidden="true"> 1802 <div class="nb-wrap sticky-cta-inner"> 1803 <span class="msg"><b>Meetings that take their own notes.</b> 7-day free trial.</span> 1804 <a href="https://app.notabium.com/signin" class="nb-btn nb-btn--ember">start free trial <span style="opacity:0.6;">âµ</span></a> 1805 </div> 1806</div> 1807
1808<script> 1809(function () { 1810 var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; 1811 1812 /* Nav shrink + sticky CTA reveal on scroll */ 1813 var nav = document.getElementById('nav'); 1814 var sticky = document.getElementById('stickyCta'); 1815 var hero = document.querySelector('.hero'); 1816 function onScroll() { 1817 var y = window.pageYOffset || document.documentElement.scrollTop; 1818 if (nav) nav.classList.toggle('is-shrunk', y > 12); 1819 if (sticky) { 1820 var past = hero ? (y > hero.offsetHeight - 80) : (y > 600); 1821 sticky.classList.toggle('is-shown', past); 1822 sticky.setAttribute('aria-hidden', past ? 'false' : 'true'); 1823 } 1824 } 1825 window.addEventListener('scroll', onScroll, { passive: true }); 1826 onScroll(); 1827 1828 /* Mobile drawer */ 1829 var burger = document.getElementById('navBurger'); 1830 var drawer = document.getElementById('navDrawer'); 1831 var closeB = document.getElementById('navClose'); 1832 function setDrawer(open) { 1833 if (!drawer) return; 1834 drawer.classList.toggle('is-open', open); 1835 document.body.style.overflow = open ? 'hidden' : ''; 1836 if (burger) burger.setAttribute('aria-expanded', open ? 'true' : 'false'); 1837 } 1838 if (burger) burger.addEventListener('click', function () { setDrawer(true); }); 1839 if (closeB) closeB.addEventListener('click', function () { setDrawer(false); }); 1840 if (drawer) drawer.querySelectorAll('a').forEach(function (a) { 1841 a.addEventListener('click', function () { setDrawer(false); }); 1842 }); 1843 document.addEventListener('keydown', function (e) { if (e.key === 'Escape') setDrawer(false); }); 1844 1845 /* Scroll-reveal */ 1846 var reveals = Array.prototype.slice.call(document.querySelectorAll('.nb-reveal')); 1847 if (reduce || !('IntersectionObserver' in window)) { 1848 reveals.forEach(function (el) { el.classList.add('is-in'); }); 1849 } else { 1850 var io = new IntersectionObserver(function (entries) { 1851 entries.forEach(function (en) { 1852 if (en.isIntersecting) { en.target.classList.add('is-in'); io.unobserve(en.target); } 1853 }); 1854 }, { rootMargin: '0px 0px -8% 0px', threshold: 0.06 }); 1855 reveals.forEach(function (el) { io.observe(el); }); 1856 } 1857 1858 /* Staggered child reveals: bento cells, mode cards, trust cards. 1859 * When the parent .nb-reveal enters view, each child gets a CSS transition-delay 1860 * proportional to its position in the group, so cards cascade in left-to-right. */ 1861 if (!reduce && 'IntersectionObserver' in window) { 1862 var staggerSel = '.bento, .modes, .trust, .features, .how'; 1863 var staggerParents = Array.prototype.slice.call(document.querySelectorAll(staggerSel)); 1864 var childSel = '.cell, .mode, .trust-card, .feature, .how-step'; 1865 var sio = new IntersectionObserver(function (entries) { 1866 entries.forEach(function (en) { 1867 if (!en.isIntersecting) return; 1868 var children = Array.prototype.slice.call(en.target.querySelectorAll(childSel)); 1869 children.forEach(function (c, i) { 1870 c.style.transitionDelay = (i * 60) + 'ms'; 1871 c.style.opacity = '0'; 1872 c.style.transform = 'translateY(14px)'; 1873 // trigger in next frame so initial state is applied first 1874 requestAnimationFrame(function () { 1875 requestAnimationFrame(function () { 1876 c.style.opacity = ''; 1877 c.style.transform = ''; 1878 }); 1879 }); 1880 }); 1881 sio.unobserve(en.target); 1882 }); 1883 }, { rootMargin: '0px 0px -5% 0px', threshold: 0.04 }); 1884 staggerParents.forEach(function (p) { sio.observe(p); }); 1885 } 1886 1887 /* ===== Interactive sample call (hero) ===== */ 1888 (function initSim() { 1889 var sim = document.getElementById('sim'); 1890 if (!sim) return; 1891 1892 var tiles = { 1893 P: sim.querySelector('.sim-tile[data-spk="P"]'), 1894 M: sim.querySelector('.sim-tile[data-spk="M"]'), 1895 S: sim.querySelector('.sim-tile[data-spk="S"]') 1896 }; 1897 var botTile = sim.querySelector('.sim-tile--bot'); 1898 var joinPill = document.getElementById('simJoin'); 1899 var clockEl = document.getElementById('simClock'); 1900 var tabT = document.getElementById('simTabT'); 1901 var tabS = document.getElementById('simTabS'); 1902 var transEl = document.getElementById('simTranscript'); 1903 var bodyEl = transEl.parentNode; 1904 var sumEl = document.getElementById('simSummary'); 1905 var sumItems = Array.prototype.slice.call(sumEl.querySelectorAll('li')); 1906 1907 // The call, in order. ts = displayed timestamp; t = ms from call start. 1908 var SCRIPT = [ 1909 { spk: 'P', who: 'Priya', ts: '0:02', t: 2000, text: "Thanks everyone, this is the kickoff for the Lumen website rebuild. Let's lock scope and a timeline." }, 1910 { spk: 'M', who: 'Maya', ts: '0:09', t: 9000, text: "I have the brand assets from the client. I can have wireframes for the five core pages by Friday." }, 1911 { spk: 'S', who: 'Sam', ts: '0:16', t: 16000, text: "Once wireframes are signed off, build is about three weeks. I'd want design locked before I start." }, 1912 { spk: 'P', who: 'Priya', ts: '0:24', t: 24000, text: "So wireframes Friday, client review early the week after, then build starts once they approve." }, 1913 { spk: 'M', who: 'Maya', ts: '0:31', t: 31000, text: "I'll send the client a short form for their content and logins before review, so we're not blocked." }, 1914 { spk: 'S', who: 'Sam', ts: '0:37', t: 37000, text: "And I'll stand up the staging environment this week so we have somewhere to ship to." }, 1915 { spk: 'P', who: 'Priya', ts: '0:43', t: 43000, text: "Perfect, let's target a soft launch in five weeks. I'll book the next check-in for Thursday." } 1916 ]; 1917 1918 function buildLine(item, withSpans) { 1919 var line = document.createElement('div'); 1920 line.className = 'sim-line'; 1921 var ts = document.createElement('span'); ts.className = 'ts'; ts.textContent = item.ts; 1922 var spk = document.createElement('span'); spk.className = 'spk'; spk.textContent = item.who; 1923 line.appendChild(ts); line.appendChild(spk); 1924 var words = item.text.split(' '); 1925 words.forEach(function (w, i) { 1926 var s = document.createElement('span'); 1927 s.className = 'w' + (withSpans ? ' ahead' : ''); 1928 s.textContent = w; 1929 line.appendChild(s); 1930 if (i < words.length - 1) line.appendChild(document.createTextNode(' ')); 1931 }); 1932 return line; 1933 } 1934 1935 // Static composed frame for reduced-motion / no-rAF.
1936 function renderStatic() { 1937 sim.classList.add('is-static'); 1938 botTile.classList.add('is-joined'); 1939 clockEl.textContent = '00:48'; 1940 transEl.innerHTML = ''; 1941 SCRIPT.forEach(function (l) { 1942 var line = buildLine(l, false); 1943 line.classList.add('is-in'); 1944 transEl.appendChild(line); 1945 }); 1946 sumItems.forEach(function (li) { li.classList.add('is-in'); }); 1947 // Both views are reachable via the tabs; rest on transcript. 1948 showTab('T', false); 1949 } 1950 1951 // Tab switching (used by autoplay AND clicks). 1952 function showTab(which, focusIt) { 1953 var onT = which === 'T'; 1954 tabT.classList.toggle('is-on', onT); 1955 tabS.classList.toggle('is-on', !onT); 1956 tabT.setAttribute('aria-selected', onT ? 'true' : 'false'); 1957 tabS.setAttribute('aria-selected', onT ? 'false' : 'true'); 1958 tabS.classList.remove('is-nudge'); 1959 transEl.hidden = !onT; 1960 sumEl.hidden = onT; 1961 if (focusIt) (onT ? tabT : tabS).focus(); 1962 } 1963 1964 if (reduce || typeof window.requestAnimationFrame !== 'function') { 1965 renderStatic(); 1966 // Tabs still work statically. 1967 tabT.addEventListener('click', function () { showTab('T', false); }); 1968 tabS.addEventListener('click', function () { showTab('S', false); }); 1969 return; 1970 } 1971 1972 var timers = []; 1973 function after(ms, fn) { var id = setTimeout(fn, ms); timers.push(id); return id; } 1974 function clearTimers() { timers.forEach(clearTimeout); timers = []; } 1975 1976 function speak(spk) { 1977 tiles.P.classList.toggle('is-speaking', spk === 'P'); 1978 tiles.M.classList.toggle('is-speaking', spk === 'M'); 1979 tiles.S.classList.toggle('is-speaking', spk === 'S'); 1980 } 1981 1982 // Type one transcript line word-by-word, stepping a highlight across the 1983 // words (the "word-level timestamps" feel). Calls done() when finished. 1984 function typeLine(item, done) { 1985 var line = buildLine(item, true); 1986 transEl.appendChild(line); 1987 bodyEl.scrollTop = bodyEl.scrollHeight; 1988 requestAnimationFrame(function () { line.classList.add('is-in'); }); 1989 var spans = Array.prototype.slice.call(line.querySelectorAll('.w')); 1990 var i = 0; 1991 (function step() { 1992 if (paused) return; 1993 if (i > 0) { var prev = spans[i - 1]; prev.classList.remove('on'); prev.classList.add('said'); } 1994 if (i < spans.length) { 1995 var cur = spans[i]; cur.classList.remove('ahead'); cur.classList.add('on'); 1996 bodyEl.scrollTop = bodyEl.scrollHeight; 1997 i++; 1998 after(95, step); 1999 } else { done && done(); } 2000 })(); 2001 } 2002 2003 var clockT = null; 2004 function fmt(s) { var m = Math.floor(s / 60), r = s % 60; return (m < 10 ? '0' + m : m) + ':' + (r < 10 ? '0' + r : r); } 2005 function startClock() { 2006 var s = 0; clockEl.textContent = '00:00'; 2007 clockT = setInterval(function () { s++; clockEl.textContent = fmt(s); }, 1000); 2008 } 2009 function stopClock() { if (clockT) { clearInterval(clockT); clockT = null; } } 2010 2011 function runCycle() { 2012 clearTimers(); stopClock(); 2013 transEl.innerHTML = ''; 2014 // Don't yank the tab / blank the summary once the user has taken control. 2015 if (!userPicked) showTab('T', false); 2016 if (!userPicked) sumItems.forEach(function (li) { li.classList.remove('is-in'); }); 2017 botTile.classList.remove('is-joined', 'is-joining', 'is-rec'); 2018 joinPill.textContent = 'joiningâ¦'; 2019 speak(null); 2020 startClock(); 2021 2022 // The notetaker joins ~1.4s in, then flips to a "rec" pill. 2023 after(1400, function () { botTile.classList.add('is-joining'); }); 2024 after(2600, function () { 2025 botTile.classList.remove('is-joining'); 2026 botTile.classList.add('is-joined', 'is-rec'); 2027 joinPill.textContent = 'rec'; 2028 }); 2029 2030 var idx = 0; 2031 function next() { 2032 if (paused) return; 2033 if (idx >= SCRIPT.length) { 2034 speak(null); 2035 // Auto-reveal the summary as the payoff, but ONLY while the user has 2036 // not taken manual control (a click must never fight the loop). Hold 2037 // the full transcript ~3.4s first so it can be read. 2038 if (!userPicked) { 2039 after(2400, function () { if (!userPicked) tabS.classList.add('is-nudge'); }); 2040 after(3400, function () { 2041 if (userPicked) return; 2042 showTab('S', false);
2043 sumItems.forEach(function (li, k) { after(170 * k, function () { li.classList.add('is-in'); }); }); 2044 }); 2045 } 2046 // Hold the payoff, then loop, the transcript keeps cycling forever, 2047 // even while the user is reading the summary tab. 2048 after(3400 + sumItems.length * 170 + 3500, function () { runCycle(); }); 2049 return; 2050 } 2051 var item = SCRIPT[idx++]; 2052 speak(item.spk); 2053 typeLine(item, function () { after(520, next); }); 2054 } 2055 after(800, next); 2056 } 2057 2058 // Clicking a tab is a PEEK: switch the view WITHOUT stopping the live 2059 // transcript. Once a tab is picked, autoplay stops auto-switching tabs 2060 // (userPicked) but the transcript keeps typing + looping underneath, so 2061 // clicking back to it is always live. Clicking summary never stops it. 2062 var paused = false; // legacy flag, always false (kept for guards) 2063 var userPicked = false; 2064 function pick(which) { 2065 userPicked = true; 2066 // Summary is always composed so it reads instantly when picked. 2067 sumItems.forEach(function (li) { li.classList.add('is-in'); }); 2068 showTab(which, true); 2069 } 2070 tabT.addEventListener('click', function () { pick('T'); }); 2071 tabS.addEventListener('click', function () { pick('S'); }); 2072 2073 // Only animate while visible; pause when scrolled away (saves cycles). 2074 var running = false; 2075 function start() { if (!running && !paused) { running = true; runCycle(); } } 2076 function stop() { if (running) { running = false; clearTimers(); stopClock(); } } 2077 2078 if ('IntersectionObserver' in window) { 2079 var sObs = new IntersectionObserver(function (ents) { 2080 ents.forEach(function (e) { if (e.isIntersecting) start(); else stop(); }); 2081 }, { threshold: 0.2 }); 2082 sObs.observe(sim); 2083 } else { 2084 start(); 2085 } 2086 })(); 2087})(); 2088</script>
vendor: 1 bytes, line 2088
2088
2089<script defer src="/waitlist.js"></script>
2089 2090 2091</body> 2092</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.