diff --git a/app/docs/[[...slug]]/page.tsx b/app/docs/[[...slug]]/page.tsx index e523b75b..b535153e 100644 --- a/app/docs/[[...slug]]/page.tsx +++ b/app/docs/[[...slug]]/page.tsx @@ -55,7 +55,7 @@ export default async function DocsPage({params}: PageProps) { - + ); } diff --git a/app/globals.css b/app/globals.css index a60569ac..bb11166d 100644 --- a/app/globals.css +++ b/app/globals.css @@ -26,6 +26,8 @@ --radius: 0.5rem; --primary-highlight: 331.2 97.3% 55.9%; --primary-highlight-foreground: 0 0% 100%; + --docs-logo-accent: 186 100% 35%; + --docs-logo-accent-color: hsl(var(--docs-logo-accent)); /* Root page */ --paragraph-color: hsl(0, 0%, 15%); @@ -58,6 +60,8 @@ --ring: 240 4.9% 83.9%; --primary-highlight: 331.2 97.3% 55.9%; --primary-highlight-foreground: 0 0% 100%; + --docs-logo-accent: 180 100% 50%; + --docs-logo-accent-color: hsl(var(--docs-logo-accent)); /* Root page */ --paragraph-color: #d4d4d8; @@ -68,6 +72,26 @@ } } +.inner-docs-nav .zero-alpha-logo { + color: hsl(var(--foreground)); +} + +.inner-docs-nav .zero-alpha-logo .logo-accent { + color: var(--docs-logo-accent-color); +} + +@media (color-gamut: p3) { + .dark { + --docs-logo-accent-color: color(display-p3 0.07 0.93 0.93); + } +} + +@media (color-gamut: rec2020) { + .dark { + --docs-logo-accent-color: color(rec2020 0.07 0.93 0.93); + } +} + .theme-toggle-group { margin-top: 1rem; display: flex; @@ -565,3 +589,1842 @@ html.dark { overflow-y: auto; } } + +/* =================================== + Introduction Landing Page Styles + =================================== */ + +@property --hero-byline-angle { + syntax: ''; + inherits: true; + initial-value: 0turn; +} + +.intro-landing-page { + width: 100%; + max-width: 100%; + --header-height: 128px; +} + +.intro-main { + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-start; + width: 100%; + padding-top: calc(var(--header-height) + 3rem); +} + +.intro-landing-page .section { + text-align: left; + max-width: clamp(320px, 90vw, 1000px); + width: 100%; + padding: clamp(1.5rem, 4vw, 2rem); + margin: clamp(1rem, 3vw, 1.5rem) auto; +} + +.intro-landing-page .section-hero { + position: relative; + overflow: visible; + text-align: center; + padding-top: 1.5rem; +} + +.intro-landing-page .section:first-child { + margin: 0; +} + +/* Hero section */ +.intro-landing-page .hero-title { + margin-bottom: 0; + line-height: 1.1; + text-align: center; + position: relative; + display: block; + opacity: 1; + transform: scale(1) translateY(0); + cursor: default; + max-width: 720px; + margin-left: auto; + margin-right: auto; +} + +.intro-landing-page .hero-title__text { + display: inline; + font-weight: 900; + line-height: 1.1; + font-size: clamp(3.25rem, 8vw + 0.5rem, 6rem); + background: linear-gradient( + 175deg, + hsl(var(--foreground)) 0%, + hsl(var(--foreground) / 0.8) 100% + ); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.intro-landing-page .hero-title__text em { + display: inline; + font-weight: 900; + font-style: italic; + font-size: inherit; + background: none; + -webkit-background-clip: initial; + -webkit-text-fill-color: currentColor; + background-clip: initial; + animation: heroBylineEmColor 14s linear infinite; +} + +.intro-landing-page .hero-gradient-clouds { + position: absolute; + inset: 15% 28% 32%; + pointer-events: none; + filter: blur(50px); + opacity: 0.32; + z-index: 0; +} + +.intro-landing-page .hero-cloud { + position: absolute; + width: 260px; + height: 260px; + border-radius: 50%; + animation: heroCloudDrift 20s linear infinite; +} + +.intro-landing-page .hero-cloud--1 { + background: rgba(255, 153, 0, 0.45); + top: 5%; + left: 12%; + animation-duration: 24s; +} + +.intro-landing-page .hero-cloud--2 { + background: rgba(255, 94, 94, 0.38); + top: 15%; + left: 46%; + animation-duration: 28s; +} + +.intro-landing-page .hero-cloud--3 { + background: rgba(193, 87, 255, 0.4); + top: 40%; + left: 24%; + animation-duration: 26s; +} + +.intro-landing-page .hero-cloud--4 { + background: rgba(76, 107, 255, 0.35); + top: 10%; + left: 66%; + animation-duration: 30s; +} + +.intro-landing-page .hero-cloud--5 { + background: rgba(0, 194, 255, 0.35); + top: 36%; + left: 38%; + animation-duration: 22s; +} + +.intro-landing-page .hero-cloud--6 { + background: rgba(0, 217, 139, 0.38); + top: 48%; + left: 58%; + animation-duration: 26s; +} + +@keyframes heroCloudDrift { + 0% { + transform: translate3d(0, 0, 0); + } + 50% { + transform: translate3d(40px, -30px, 0); + } + 100% { + transform: translate3d(-20px, 20px, 0); + } +} + +.intro-landing-page .hero-byline { + display: inline-flex; + align-items: center; + position: relative; + padding: 0.4rem 1rem; + margin: 0 auto 2rem; + font-size: clamp(0.9375rem, 0.9rem + 0.18vw, 1.0625rem); + font-weight: 400; + color: hsl(var(--foreground)); + text-align: center; + border-radius: 2.5em; + background: hsl(var(--background)); + --hero-byline-angle: 0turn; + isolation: isolate; + gap: 0.35rem; +} + +.intro-landing-page .hero-byline::before { + content: ''; + position: absolute; + inset: -4px; + border-radius: inherit; + padding: 1.5px; + background: conic-gradient( + from var(--hero-byline-angle), + #ff9900 0deg, + #ff5e5e 60deg, + #c157ff 120deg, + #4c6bff 180deg, + #00c2ff 240deg, + #00d98b 300deg, + #ff9900 360deg + ); + z-index: -1; + animation: heroBylineOrbit 3.8s linear infinite; + -webkit-mask: + linear-gradient(#000 0 0) content-box, + linear-gradient(#000 0 0); + -webkit-mask-composite: xor; + mask: + linear-gradient(#000 0 0) content-box, + linear-gradient(#000 0 0); + mask-composite: exclude; + pointer-events: none; +} + +@keyframes heroBylineOrbit { + 0% { + --hero-byline-angle: 0turn; + } + 100% { + --hero-byline-angle: 1turn; + } +} + +.intro-landing-page .hero-byline__icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 16px; + height: 16px; + margin-right: 0.25rem; + animation: heroBylineEmColor 14s linear infinite; +} + +.intro-landing-page .hero-byline em { + display: inline-block; + position: relative; + left: -2px; + animation: heroBylineEmColor 14s linear infinite; +} + +@keyframes heroBylineEmColor { + 0% { + color: #ff5e5e; + } + 20% { + color: #c157ff; + } + 40% { + color: #4c6bff; + } + 60% { + color: #00c2ff; + } + 80% { + color: #00d98b; + } + 100% { + color: #ff5e5e; + } +} + +.intro-landing-page .section-intro p, +.intro-landing-page .section p { + font-size: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem); + line-height: 1.6; + margin-bottom: 1.5rem; +} + +.intro-landing-page .section p:last-child { + margin-bottom: 0; +} + +.intro-landing-page .subheading { + font-size: clamp(2rem, 1.5rem + 2vw, 3rem); + font-weight: 800; + line-height: 1.2; + margin-bottom: 2rem; +} + +.intro-landing-page h3 { + font-size: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem); + font-weight: 700; + margin-bottom: 0.75rem; + color: hsl(var(--foreground)); +} + +/* Feature Grid */ +.intro-landing-page .feature-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 1.5rem; + margin: 2rem 0; +} + +.intro-landing-page .feature-grid--two { + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.intro-landing-page .feature-card { + background: hsl(var(--background)); + border-radius: 1rem; + padding: 2rem; + position: relative; + overflow: hidden; + cursor: default; + box-shadow: + 0 1px 3px rgba(0, 0, 0, 0.05), + 0 4px 12px rgba(0, 0, 0, 0.03), + inset 0 1px 0 rgba(255, 255, 255, 0.3); + border: 1px solid rgba(255, 255, 255, 0.2); + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.1) 0%, + rgba(255, 255, 255, 0) 50%, + rgba(0, 0, 0, 0.03) 100% + ), + hsl(var(--background)); + transform: perspective(1000px) rotateX(0) rotateY(0) translateZ(0); + transform-style: preserve-3d; + transition: + transform 0.1s ease-out, + box-shadow 0.2s; +} + +.intro-landing-page .feature-card:hover { + box-shadow: + 0 8px 24px rgba(0, 0, 0, 0.12), + 0 16px 40px rgba(0, 0, 0, 0.08), + inset 0 1px 0 rgba(255, 255, 255, 0.4); +} + +.intro-landing-page .feature-card--link { + display: block; + text-decoration: none; + color: inherit; + cursor: pointer; +} + +.intro-landing-page .feature-card--with-icon { + display: flex; + flex-wrap: wrap; + align-items: flex-start; +} + +.intro-landing-page .feature-card--with-icon h3 { + flex: 1; + margin-bottom: 0.75rem; +} + +.intro-landing-page .feature-card-icon { + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + margin-left: 1rem; + color: hsl(var(--foreground) / 0.7); +} + +.intro-landing-page .feature-card-icon svg { + width: 2rem; + height: 2rem; + display: block; +} + +.intro-landing-page .feature-card--with-icon p { + flex-basis: 100%; + margin-top: 0.75rem; +} + +.intro-landing-page .feature-card--icon-left { + display: flex; + align-items: flex-start; + gap: 1.25rem; +} + +.intro-landing-page .feature-card-icon-left { + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + color: hsl(var(--foreground)); +} + +.intro-landing-page .feature-card-icon-left svg { + width: 28px; + height: 28px; + display: block; +} + +.intro-landing-page .feature-card-content { + flex: 1; + min-width: 0; +} + +.intro-landing-page .feature-card-content h3 { + margin-bottom: 0.5rem; +} + +.intro-landing-page .feature-card-content p { + margin-bottom: 0; +} + +.intro-landing-page .feature-card h3 { + font-size: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem); + font-weight: 700; + margin-bottom: 0.75rem; + color: hsl(var(--foreground)); +} + +.intro-landing-page .feature-card p { + font-size: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem); + line-height: 1.5; + margin-bottom: 0; + opacity: 0.85; +} + +.intro-landing-page .section-get-started { + margin-top: clamp(3rem, 6vw, 6rem); + margin-bottom: clamp(3rem, 6vw, 6rem); +} + +/* Dark theme adjustments */ +.dark .intro-landing-page .feature-card { + border-color: rgba(255, 255, 255, 0.1); + box-shadow: + 0 1px 3px rgba(0, 0, 0, 0.3), + 0 4px 12px rgba(0, 0, 0, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.1); + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.05) 0%, + rgba(255, 255, 255, 0) 50%, + rgba(0, 0, 0, 0.1) 100% + ), + hsl(var(--background)); +} + +.dark .intro-landing-page .feature-card:hover { + box-shadow: + 0 2px 6px rgba(0, 0, 0, 0.4), + 0 8px 20px rgba(0, 0, 0, 0.3), + inset 0 1px 0 rgba(255, 255, 255, 0.15); +} + +/* Video section */ +.intro-landing-page .section-video { + margin-top: 0.75rem; +} + +.intro-landing-page .video-container { + width: 100%; + border-radius: 1rem; + overflow: hidden; + background: hsl(var(--background)); + box-shadow: + 0 1px 3px rgba(0, 0, 0, 0.05), + 0 4px 12px rgba(0, 0, 0, 0.03), + inset 0 1px 0 rgba(255, 255, 255, 0.3); + border: 1px solid rgba(255, 255, 255, 0.2); + position: relative; + cursor: pointer; + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.1) 0%, + rgba(255, 255, 255, 0) 50%, + rgba(0, 0, 0, 0.03) 100% + ), + hsl(var(--background)); +} + +.intro-landing-page .video-player { + width: 100%; + height: auto; + display: block; +} + +.intro-landing-page .video-controls { + position: absolute; + bottom: 0; + left: 0; + right: 0; + padding: 1.5rem; + background: linear-gradient( + to top, + rgba(0, 0, 0, 0.7) 0%, + rgba(0, 0, 0, 0.4) 50%, + rgba(0, 0, 0, 0) 100% + ); + display: flex; + align-items: center; + gap: 0.75rem; + opacity: 0; + transition: opacity 0.3s ease; + pointer-events: none; +} + +.intro-landing-page .video-container:hover .video-controls { + opacity: 1; + pointer-events: auto; +} + +.intro-landing-page .video-control-btn { + background: rgba(255, 255, 255, 0.95); + border: none; + border-radius: 50%; + width: 44px; + height: 44px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: + transform 0.2s ease, + background 0.2s ease; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); + color: #1e1e1e; + padding: 0; +} + +.intro-landing-page .video-control-btn:hover { + transform: scale(1.1); + background: rgba(255, 255, 255, 1); +} + +.intro-landing-page .video-control-btn:active { + transform: scale(0.95); +} + +.intro-landing-page .video-icon { + width: 24px; + height: 24px; + display: block; +} + +.intro-landing-page .video-play-pause .video-icon-play { + display: none; +} + +.intro-landing-page .video-play-pause .video-icon-pause { + display: block; +} + +.intro-landing-page + .video-player:not([autoplay]) + ~ .video-controls + .video-play-pause + .video-icon-play, +.intro-landing-page + .video-player[paused] + ~ .video-controls + .video-play-pause + .video-icon-play { + display: block; +} + +.intro-landing-page + .video-player:not([autoplay]) + ~ .video-controls + .video-play-pause + .video-icon-pause, +.intro-landing-page + .video-player[paused] + ~ .video-controls + .video-play-pause + .video-icon-pause { + display: none; +} + +.intro-landing-page .video-fullscreen { + margin-left: auto; +} + +.intro-landing-page .video-caption { + text-align: center; + font-style: italic; + font-size: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem); + margin-top: 1rem; + opacity: 0.7; +} + +.dark .intro-landing-page .video-container { + border-color: rgba(255, 255, 255, 0.1); + box-shadow: + 0 1px 3px rgba(0, 0, 0, 0.3), + 0 4px 12px rgba(0, 0, 0, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.1); + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.05) 0%, + rgba(255, 255, 255, 0) 50%, + rgba(0, 0, 0, 0.1) 100% + ), + hsl(var(--background)); +} + +/* Demo container */ +.intro-landing-page .section-try-it { + margin: 3rem auto; +} + +.intro-landing-page .demo-container { + width: 100%; + border-radius: 1rem; + background: hsl(var(--background)); + box-shadow: + 0 1px 3px rgba(0, 0, 0, 0.05), + 0 4px 12px rgba(0, 0, 0, 0.03), + inset 0 1px 0 rgba(255, 255, 255, 0.3); + border: 1px solid rgba(255, 255, 255, 0.2); + position: relative; + isolation: isolate; + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.1) 0%, + rgba(255, 255, 255, 0) 50%, + rgba(0, 0, 0, 0.03) 100% + ), + hsl(var(--background)); + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transform: perspective(1000px) rotateX(0) rotateY(0) translateZ(0); + transform-style: preserve-3d; + transition: + transform 0.1s ease-out, + box-shadow 0.3s ease; +} + +.intro-landing-page .demo-container::before { + content: ''; + position: absolute; + inset: -4px; + border-radius: inherit; + padding: 1.5px; + background: conic-gradient( + from var(--hero-byline-angle), + #ff9900 0deg, + #ff5e5e 60deg, + #c157ff 120deg, + #4c6bff 180deg, + #00c2ff 240deg, + #00d98b 300deg, + #ff9900 360deg + ); + z-index: -1; + animation: heroBylineOrbit 3.8s linear infinite; + -webkit-mask: + linear-gradient(#000 0 0) content-box, + linear-gradient(#000 0 0); + -webkit-mask-composite: xor; + mask: + linear-gradient(#000 0 0) content-box, + linear-gradient(#000 0 0); + mask-composite: exclude; + pointer-events: none; +} + +.intro-landing-page .demo-container:hover { + box-shadow: + 0 8px 24px rgba(0, 0, 0, 0.12), + 0 16px 40px rgba(0, 0, 0, 0.08), + inset 0 1px 0 rgba(255, 255, 255, 0.4); +} + +.intro-landing-page .demo-prompt { + padding: 4rem; + max-width: 36rem; + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; + text-align: center; +} + +.intro-landing-page .demo-prompt-title { + font-size: clamp(1.5rem, 2vw, 2rem); + font-weight: 700; + margin: 0; +} + +.intro-landing-page .demo-intro-text { + font-size: clamp(1rem, 1.5vw, 1.25rem); + line-height: 1.4; + margin: 0; +} + +.intro-landing-page .load-demo-btn { + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.18) 0%, + rgba(255, 255, 255, 0.06) 40%, + rgba(0, 0, 0, 0.12) 100% + ), + #27252b; + color: hsl(var(--background)); + border: 1px solid rgba(255, 255, 255, 0.16); + font-family: inherit; + font-size: clamp(1rem, 1.5vw, 1.25rem); + font-weight: 600; + padding: 1rem 2.5rem; + border-radius: 1rem; + cursor: pointer; + transition: + transform 0.2s ease, + box-shadow 0.2s ease, + opacity 0.2s ease; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.32); + backdrop-filter: blur(10px); +} + +.intro-landing-page .load-demo-btn:hover { + transform: translateY(-1px) scale(1.02); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.38); + opacity: 0.95; +} + +.intro-landing-page .load-demo-btn:active { + transform: translateY(0) scale(0.98); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.26); +} + +.dark .intro-landing-page .demo-container { + border-color: rgba(255, 255, 255, 0.1); + box-shadow: + 0 1px 3px rgba(0, 0, 0, 0.3), + 0 4px 12px rgba(0, 0, 0, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.1); + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.05) 0%, + rgba(255, 255, 255, 0) 50%, + rgba(0, 0, 0, 0.1) 100% + ), + hsl(var(--background)); +} + +.dark .intro-landing-page .load-demo-btn { + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.25) 0%, + rgba(255, 255, 255, 0.12) 40%, + rgba(255, 255, 255, 0.05) 100% + ), + #e8e6f0; + color: #1e1e1e; + border: 1px solid rgba(255, 255, 255, 0.3); + box-shadow: + inset 0 0 0 1px rgba(255, 255, 255, 0.4), + 0 2px 8px rgba(0, 0, 0, 0.3); +} + +.dark .intro-landing-page .load-demo-btn:hover { + box-shadow: + inset 0 0 0 1px rgba(255, 255, 255, 0.5), + 0 4px 12px rgba(0, 0, 0, 0.4); +} + +/* Demo Modal */ +.intro-landing-page .demo-modal { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1000; + display: flex; + align-items: center; + justify-content: center; + padding: 2rem; +} + +.intro-landing-page .demo-modal-backdrop { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + cursor: pointer; +} + +.intro-landing-page .demo-modal-content { + position: relative; + width: 100%; + height: 100%; + z-index: 1; + display: flex; + flex-direction: column; + gap: 1rem; +} + +.intro-landing-page .demo-modal-pill { + position: absolute; + top: -1.4rem; + left: 50%; + transform: translateX(-50%) scale(0.8); + z-index: 2; + padding: 0.6rem 1rem; + border-radius: 2rem; + background-color: #fc218a; + color: #fff; + font-size: 1.25rem; + text-align: center; + user-select: none; + border: none; + opacity: 0; + width: fit-content; + white-space: nowrap; +} + +.intro-landing-page .demo-modal-pill.pop-in { + animation: popIn 0.2s cubic-bezier(0.68, -0.55, 0.265, 1.55) forwards; +} + +@keyframes popIn { + 0% { + opacity: 0; + transform: translateX(-50%) scale(0.8); + } + 70% { + opacity: 1; + transform: translateX(-50%) scale(1.15); + } + 100% { + opacity: 1; + transform: translateX(-50%) scale(1); + } +} + +.intro-landing-page .demo-iframe-wrapper { + position: relative; + width: 100%; + height: 100%; +} + +.intro-landing-page .demo-iframe { + width: 100%; + height: 100%; + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 1rem; + background: hsl(var(--background)); + box-shadow: + 0 8px 32px rgba(0, 0, 0, 0.2), + 0 16px 64px rgba(0, 0, 0, 0.15), + inset 0 1px 0 rgba(255, 255, 255, 0.3); +} + +.intro-landing-page .demo-exit-card { + display: flex; + align-items: center; + gap: 1.25rem; + width: fit-content; + max-width: min(100%, 520px); + text-align: left; + cursor: pointer; + outline: none; + margin: 0 auto; + padding: 1.5rem 2rem; +} + +.intro-landing-page .demo-exit-card__icon { + flex-shrink: 0; + width: 56px; + height: 56px; + border-radius: 16px; + display: inline-flex; + align-items: center; + justify-content: center; + background: rgba(233, 30, 140, 0.1); + color: var(--pink, #fc218a); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4); +} + +.intro-landing-page .demo-exit-card__icon svg { + width: 28px; + height: 28px; +} + +.intro-landing-page .demo-exit-card__content h3 { + margin-bottom: 0; +} + +/* Code blocks */ +.intro-landing-page .step-section { + margin-bottom: 6rem; +} + +.intro-landing-page .step-section:last-child { + margin-bottom: 0; +} + +.intro-landing-page .glass-panel { + padding: 2rem; + border-radius: 1rem; + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.1) 0%, + rgba(255, 255, 255, 0) 50%, + rgba(0, 0, 0, 0.03) 100% + ), + hsl(var(--background)); + border: 1px solid rgba(255, 255, 255, 0.2); + box-shadow: + 0 1px 3px rgba(0, 0, 0, 0.05), + 0 4px 12px rgba(0, 0, 0, 0.03), + inset 0 1px 0 rgba(255, 255, 255, 0.3); +} + +.intro-landing-page .code-block { + position: relative; + overflow-x: auto; + margin: 2rem 0; +} + +.intro-landing-page .code-block pre { + margin: 0; + padding: 0; + overflow: visible; +} + +.intro-landing-page .code-block code { + display: block; + font-family: 'Menlo', 'Consolas', 'SFMono-Regular', 'Courier New', monospace; + font-size: 0.9rem; + line-height: 1.6; + color: hsl(var(--foreground)); + white-space: pre; +} + +.intro-landing-page .code-block-tabbed { + margin: 2rem 0; +} + +.intro-landing-page .code-block-tabbed .code-group { + margin: 0; +} + +.intro-landing-page .code-block-tabbed pre { + margin: 0; + padding: 1.5rem; + overflow-x: auto; +} + +.intro-landing-page .code-block-tabbed code { + display: block; + font-family: 'Menlo', 'Consolas', 'SFMono-Regular', 'Courier New', monospace; + font-size: 0.9rem; + line-height: 1.6; + color: hsl(var(--foreground)); + white-space: pre; +} + +.dark .intro-landing-page .glass-panel { + border-color: rgba(255, 255, 255, 0.1); + box-shadow: + 0 1px 3px rgba(0, 0, 0, 0.3), + 0 4px 12px rgba(0, 0, 0, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.1); + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.05) 0%, + rgba(255, 255, 255, 0) 50%, + rgba(0, 0, 0, 0.1) 100% + ), + hsl(var(--background)); +} + +/* How it Works section */ +.intro-landing-page .section-how-it-works { + margin-top: clamp(3rem, 6vw, 6rem); +} + +.intro-landing-page .how-it-works-illustration { + width: 100%; + margin: 3rem 0; + aspect-ratio: 732 / 175; +} + +.intro-landing-page .how-it-works-svg { + width: 100%; + height: 100%; + object-fit: contain; + display: block; +} + +.light .intro-landing-page .how-it-works-svg, +html:not(.dark) .intro-landing-page .how-it-works-svg { + filter: invert(1) hue-rotate(180deg); +} + +.intro-landing-page .how-it-works-description { + margin-bottom: 2rem; +} + +.intro-landing-page .how-it-works-description p { + font-size: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem); + line-height: 1.6; + margin-bottom: 1.5rem; +} + +.intro-landing-page .how-it-works-description p:last-child { + margin-bottom: 0; +} + +/* Testimonials */ +.intro-landing-page .section-testimonials { + margin-top: clamp(3rem, 6vw, 6rem); + margin-bottom: clamp(3rem, 6vw, 6rem); +} + +.intro-landing-page .testimonials-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); + gap: 1.5rem; + margin: 4rem 0; +} + +.intro-landing-page .testimonial-card { + background: hsl(var(--background)); + border-radius: 1.25rem; + padding: 2rem; + position: relative; + overflow: hidden; + cursor: default; + display: flex; + flex-direction: column; + gap: 1.5rem; + background: + linear-gradient( + 225deg, + rgba(252, 33, 138, 0.03) 0%, + rgba(255, 255, 255, 0.08) 30%, + rgba(255, 255, 255, 0) 70%, + rgba(0, 0, 0, 0.02) 100% + ), + hsl(var(--background)); + box-shadow: + 0 2px 8px rgba(0, 0, 0, 0.04), + 0 8px 16px rgba(0, 0, 0, 0.02), + inset 0 1px 0 rgba(255, 255, 255, 0.4); + border: 1.5px solid rgba(252, 33, 138, 0.08); + transform: perspective(1000px) rotateX(0) rotateY(0) translateZ(0); + transform-style: preserve-3d; + transition: + transform 0.1s ease-out, + box-shadow 0.3s, + border-color 0.3s; +} + +.intro-landing-page .testimonial-card:hover { + box-shadow: + 0 12px 32px rgba(0, 0, 0, 0.1), + 0 20px 48px rgba(0, 0, 0, 0.06), + inset 0 1px 0 rgba(255, 255, 255, 0.5); + border-color: rgba(252, 33, 138, 0.15); +} + +.intro-landing-page .testimonial-quote { + flex: 1; +} + +.intro-landing-page .testimonial-quote p { + font-size: clamp(1rem, 1.5vw, 1.25rem); + line-height: 1.6; + font-style: italic; + font-weight: 400; + color: hsl(var(--foreground)); + margin: 0; + position: relative; + padding-left: 1.25rem; +} + +.intro-landing-page .testimonial-quote p::before { + content: '"'; + position: absolute; + left: -1rem; + top: -1rem; + font-size: 2.5rem; + line-height: 1; + font-weight: 700; + color: hsl(var(--foreground)); + opacity: 0.3; +} + +.intro-landing-page .testimonial-author { + display: flex; + align-items: center; + gap: 1rem; + padding-top: 1rem; +} + +.intro-landing-page .testimonial-avatar { + width: 48px; + height: 48px; + border-radius: 50%; + object-fit: cover; + border: 2px solid rgba(252, 33, 138, 0.15); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); + flex-shrink: 0; +} + +.intro-landing-page .testimonial-info { + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +.intro-landing-page .testimonial-name { + font-size: clamp(1rem, 1.5vw, 1.25rem); + font-weight: 700; + color: hsl(var(--foreground)); + line-height: 1.2; +} + +.intro-landing-page .testimonial-title { + font-size: clamp(0.875rem, 1.25vw, 1rem); + font-weight: 500; + color: hsl(var(--foreground)); + opacity: 0.6; + line-height: 1.3; +} + +.dark .intro-landing-page .testimonial-card { + background: + linear-gradient( + 225deg, + rgba(252, 33, 138, 0.06) 0%, + rgba(255, 255, 255, 0.03) 30%, + rgba(255, 255, 255, 0) 70%, + rgba(0, 0, 0, 0.1) 100% + ), + hsl(var(--background)); + border-color: rgba(252, 33, 138, 0.12); + box-shadow: + 0 2px 8px rgba(0, 0, 0, 0.2), + 0 8px 16px rgba(0, 0, 0, 0.15), + inset 0 1px 0 rgba(255, 255, 255, 0.1); +} + +.dark .intro-landing-page .testimonial-card:hover { + border-color: rgba(252, 33, 138, 0.25); + box-shadow: + 0 12px 32px rgba(0, 0, 0, 0.4), + 0 20px 48px rgba(0, 0, 0, 0.3), + inset 0 1px 0 rgba(255, 255, 255, 0.15); +} + +.dark .intro-landing-page .testimonial-avatar { + border-color: rgba(252, 33, 138, 0.25); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4); +} + +/* Cloud Zero Section */ +.intro-landing-page .section-cloud-zero { + margin-top: clamp(3rem, 6vw, 6rem); + margin-bottom: clamp(3rem, 6vw, 6rem); +} + +.intro-landing-page .cloud-zero-header { + display: flex; + align-items: center; + gap: 1rem; + flex-wrap: wrap; + margin-bottom: 2rem; +} + +.intro-landing-page .cloud-zero-header .subheading { + margin-bottom: 0; +} + +.intro-landing-page .coming-soon-badge { + display: inline-flex; + align-items: center; + position: relative; + padding: 0.4rem 1rem; + font-size: 0.875rem; + font-weight: 500; + border-radius: 2em; + background: hsl(var(--background)); + color: hsl(var(--foreground)); + white-space: nowrap; + isolation: isolate; +} + +.intro-landing-page .coming-soon-badge::before { + content: ''; + position: absolute; + inset: -2px; + border-radius: inherit; + padding: 1.5px; + background: conic-gradient( + from var(--hero-byline-angle), + #ff9900 0deg, + #ff5e5e 60deg, + #c157ff 120deg, + #4c6bff 180deg, + #00c2ff 240deg, + #00d98b 300deg, + #ff9900 360deg + ); + z-index: -1; + animation: heroBylineOrbit 3.8s linear infinite; + -webkit-mask: + linear-gradient(#000 0 0) content-box, + linear-gradient(#000 0 0); + -webkit-mask-composite: xor; + mask: + linear-gradient(#000 0 0) content-box, + linear-gradient(#000 0 0); + mask-composite: exclude; + pointer-events: none; +} + +.intro-landing-page .cloud-zero-preview { + margin-bottom: 2rem; +} + +.intro-landing-page .cloud-zero-image { + width: 100%; + height: auto; + border-radius: 1rem; + border: 1px solid rgba(255, 255, 255, 0.1); + box-shadow: + 0 4px 16px rgba(0, 0, 0, 0.2), + 0 8px 32px rgba(0, 0, 0, 0.15); +} + +.intro-landing-page .cloud-zero-pricing-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 1.5rem; +} + +.intro-landing-page .cloud-zero-tier-card { + --tier-color-text: #fc218a; + background: hsl(var(--background)); + border-radius: 1rem; + padding: 1.75rem; + position: relative; + overflow: hidden; + box-shadow: + 0 1px 3px rgba(0, 0, 0, 0.05), + 0 4px 12px rgba(0, 0, 0, 0.03), + inset 0 1px 0 rgba(255, 255, 255, 0.3); + border: 1px solid rgba(255, 255, 255, 0.2); + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.1) 0%, + rgba(255, 255, 255, 0) 50%, + rgba(0, 0, 0, 0.03) 100% + ), + hsl(var(--background)); + display: flex; + flex-direction: column; + transition: box-shadow 0.2s ease; +} + +.intro-landing-page .cloud-zero-tier-card:hover { + box-shadow: + 0 8px 24px rgba(0, 0, 0, 0.12), + 0 16px 40px rgba(0, 0, 0, 0.08), + inset 0 1px 0 rgba(255, 255, 255, 0.4); +} + +.intro-landing-page .cloud-zero-tier-card--saas { + --tier-color-text: var(--docs-logo-accent-color); +} + +.intro-landing-page .cloud-zero-tier-card--byoc { + --tier-color-text: #fc218a; +} + +.intro-landing-page .cloud-zero-tier-header { + margin-bottom: 0.25rem; +} + +.intro-landing-page .cloud-zero-tier-label { + display: block; + font-size: 0.75rem; + font-weight: 800; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--tier-color-text); + margin-bottom: 0.25rem; +} + +.intro-landing-page .cloud-zero-tier-name { + font-size: clamp(1.125rem, 1rem + 0.4vw, 1.25rem); + font-weight: 700; + margin: 0; + color: hsl(var(--foreground)); + white-space: nowrap; +} + +.intro-landing-page p.cloud-zero-tier-subtitle { + font-size: 1rem; + color: inerhit; + opacity: 0.5; + line-height: 1.3; + margin: 0 0 2rem 0; +} + +.intro-landing-page .cloud-zero-tier-card .cloud-zero-list { + flex: 1; +} + +.intro-landing-page .cloud-zero-tier-price { + display: flex; + flex-direction: column; + gap: 0.25rem; + margin-top: 1.5rem; + padding-top: 1.25rem; + border-top: 1px solid rgba(128, 128, 128, 0.2); +} + +.intro-landing-page .cloud-zero-tier-price-row { + display: flex; + align-items: baseline; + gap: 0.25rem; + margin-top: auto; + line-height: 1; +} + +.intro-landing-page .cloud-zero-tier-price .cloud-zero-price-secondary { + font-size: 0.875rem; + opacity: 0.5; + margin-left: 0.25rem; +} + +.intro-landing-page .cloud-zero-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 1.5rem; +} + +.intro-landing-page .cloud-zero-card { + background: hsl(var(--background)); + border-radius: 1rem; + padding: 2rem; + position: relative; + overflow: hidden; + box-shadow: + 0 1px 3px rgba(0, 0, 0, 0.05), + 0 4px 12px rgba(0, 0, 0, 0.03), + inset 0 1px 0 rgba(255, 255, 255, 0.3); + border: 1px solid rgba(255, 255, 255, 0.2); + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.1) 0%, + rgba(255, 255, 255, 0) 50%, + rgba(0, 0, 0, 0.03) 100% + ), + hsl(var(--background)); +} + +.intro-landing-page .cloud-zero-card h3 { + font-size: clamp(1.25rem, 1.1rem + 0.5vw, 1.5rem); + font-weight: 700; + margin-bottom: 1.25rem; + color: hsl(var(--foreground)); +} + +.intro-landing-page .cloud-zero-list { + list-style: disc; + padding-left: 1.25rem; + margin: 0; +} + +.intro-landing-page .cloud-zero-list li { + font-size: clamp(0.9375rem, 0.9119rem + 0.1136vw, 1rem); + line-height: 1.6; + margin-bottom: 0.75rem; + opacity: 0.85; +} + +.intro-landing-page .cloud-zero-list li:last-child { + margin-bottom: 0; +} + +.intro-landing-page .cloud-zero-card { + display: flex; + flex-direction: column; +} + +.intro-landing-page .cloud-zero-list { + flex: 1; +} + +.intro-landing-page .cloud-zero-pricing { + margin-top: 1.5rem; + padding-top: 1.25rem; + border-top: 1px solid rgba(128, 128, 128, 0.2); + display: flex; + align-items: baseline; + flex-wrap: wrap; + gap: 0.25rem; +} + +.intro-landing-page .cloud-zero-price { + font-size: clamp(1.75rem, 1.5rem + 1vw, 2.25rem); + font-weight: 800; + color: hsl(var(--foreground)); + letter-spacing: -0.02em; +} + +.intro-landing-page .cloud-zero-price-unit { + font-size: clamp(1rem, 0.9rem + 0.3vw, 1.125rem); + font-weight: 500; + color: hsl(var(--foreground)); + opacity: 0.7; +} + +.intro-landing-page .cloud-zero-price-secondary { + font-size: clamp(0.875rem, 0.8rem + 0.2vw, 1rem); + font-weight: 500; + color: hsl(var(--foreground)); + opacity: 0.5; + margin-left: 0.5rem; +} + +.intro-landing-page .cloud-zero-cta-container { + width: 100%; + margin-top: 2.5rem; + border-radius: 1rem; + background: hsl(var(--background)); + box-shadow: + 0 1px 3px rgba(0, 0, 0, 0.05), + 0 4px 12px rgba(0, 0, 0, 0.03), + inset 0 1px 0 rgba(255, 255, 255, 0.3); + border: 1px solid rgba(255, 255, 255, 0.2); + position: relative; + isolation: isolate; + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.1) 0%, + rgba(255, 255, 255, 0) 50%, + rgba(0, 0, 0, 0.03) 100% + ), + hsl(var(--background)); + display: flex; + align-items: center; + justify-content: center; +} + +.intro-landing-page .cloud-zero-cta-container::before { + content: ''; + position: absolute; + inset: -4px; + border-radius: inherit; + padding: 1.5px; + background: conic-gradient( + from var(--hero-byline-angle), + #ff9900 0deg, + #ff5e5e 60deg, + #c157ff 120deg, + #4c6bff 180deg, + #00c2ff 240deg, + #00d98b 300deg, + #ff9900 360deg + ); + z-index: -1; + animation: heroBylineOrbit 3.8s linear infinite; + -webkit-mask: + linear-gradient(#000 0 0) content-box, + linear-gradient(#000 0 0); + -webkit-mask-composite: xor; + mask: + linear-gradient(#000 0 0) content-box, + linear-gradient(#000 0 0); + mask-composite: exclude; + pointer-events: none; +} + +.intro-landing-page .cloud-zero-cta-prompt { + padding: 4rem; + max-width: 36rem; + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; + text-align: center; +} + +.intro-landing-page .cloud-zero-cta-buttons { + display: flex; + gap: 1rem; + flex-wrap: wrap; + justify-content: center; +} + +.intro-landing-page .cloud-zero-cta-buttons .load-demo-btn { + display: inline-flex; + align-items: center; + gap: 0.5rem; + text-decoration: none; +} + +.intro-landing-page .cloud-zero-cta-buttons .load-demo-btn svg { + width: 1.25rem; + height: 1.25rem; + flex-shrink: 0; +} + +.dark .intro-landing-page .cloud-zero-cta-container { + border-color: rgba(255, 255, 255, 0.1); + box-shadow: + 0 1px 3px rgba(0, 0, 0, 0.3), + 0 4px 12px rgba(0, 0, 0, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.1); + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.05) 0%, + rgba(255, 255, 255, 0) 50%, + rgba(0, 0, 0, 0.1) 100% + ), + hsl(var(--background)); +} + +.dark .intro-landing-page .cloud-zero-card { + border-color: rgba(255, 255, 255, 0.1); + box-shadow: + 0 1px 3px rgba(0, 0, 0, 0.3), + 0 4px 12px rgba(0, 0, 0, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.1); + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.05) 0%, + rgba(255, 255, 255, 0) 50%, + rgba(0, 0, 0, 0.1) 100% + ), + hsl(var(--background)); +} + +.dark .intro-landing-page .cloud-zero-tier-card { + border-color: rgba(255, 255, 255, 0.1); + box-shadow: + 0 1px 3px rgba(0, 0, 0, 0.3), + 0 4px 12px rgba(0, 0, 0, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.1); + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.05) 0%, + rgba(255, 255, 255, 0) 50%, + rgba(0, 0, 0, 0.1) 100% + ), + hsl(var(--background)); +} + +.dark .intro-landing-page .cloud-zero-tier-card:hover { + box-shadow: + 0 2px 6px rgba(0, 0, 0, 0.4), + 0 8px 20px rgba(0, 0, 0, 0.3), + inset 0 1px 0 rgba(255, 255, 255, 0.15); +} + +@media (max-width: 992px) { + .intro-landing-page .cloud-zero-pricing-grid { + grid-template-columns: 1fr; + } +} + +@media (max-width: 768px) { + .intro-landing-page .cloud-zero-grid { + grid-template-columns: 1fr; + } +} + +@media (max-width: 768px) { + .intro-landing-page .feature-grid { + grid-template-columns: 1fr; + } + + .intro-landing-page .feature-grid--two { + grid-template-columns: 1fr; + } + + .intro-landing-page .testimonials-grid { + grid-template-columns: 1fr; + } + + .intro-landing-page .demo-modal { + padding: 1rem; + } +} + +/* Landing page header (from zero-landing-v2) */ +.landing-header { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + padding: 2.5rem 0; + margin: 0; + position: fixed; + top: 0; + left: 0; + z-index: 100; + background: hsl(var(--background)); +} + +.landing-header-inner { + max-width: clamp(320px, 90vw, 1000px); + width: 100%; + padding: 0 clamp(1.5rem, 4vw, 2rem); + display: flex; + justify-content: space-between; + align-items: center; +} + +.landing-logo { + position: relative; + display: flex; + align-items: center; + cursor: pointer; +} + +.landing-logo img:not(.landing-wordmark) { + width: 48px; + height: 48px; + display: block; +} + +.landing-logo img:not(.landing-wordmark):hover { + animation: logo-spin 1.2s cubic-bezier(0.4, 0, 0.2, 1); +} + +.landing-logo .landing-wordmark { + position: absolute; + left: calc(48px + 1.5rem); + width: 107px; + height: 24px; + min-width: 107px; + clip-path: inset(0 100% 0 0); + opacity: 0; + transition: + clip-path 0.3s ease-in-out, + opacity 0.3s ease-in-out; + pointer-events: none; +} + +.landing-logo:hover .landing-wordmark { + clip-path: inset(0 0 0 0); + opacity: 1; +} + +/* Dark mode - invert logo colors */ +.dark .landing-logo img:not(.landing-wordmark) { + filter: invert(1); +} + +.dark .landing-logo .landing-wordmark { + filter: invert(1); +} + +/* Landing page footer */ +.landing-footer { + display: flex; + justify-content: center; + align-items: center; + padding: 4rem 0; + width: 100%; +} + +.landing-footer-link { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; + cursor: pointer; + text-decoration: none; +} + +.landing-footer-logo { + width: 130px; + height: auto; + color: hsl(var(--foreground)); +} + +.landing-footer-text { + font-size: 0.875rem; + color: hsl(var(--foreground)); + white-space: nowrap; + letter-spacing: 0.05em; +} + +@keyframes logo-spin { + 0% { + transform: rotate(0deg); + } + 5% { + transform: rotate(0deg); + } + 65% { + transform: rotate(1080deg); + } + 100% { + transform: rotate(1080deg); + } +} + +.landing-nav { + display: flex; + align-items: center; + gap: 1rem; +} + +.landing-nav-link { + color: hsl(var(--foreground)); + text-decoration: none; + font-size: 1rem; + font-weight: 500; + height: 48px; + display: flex; + align-items: center; + padding: 0 1rem; + transition: opacity 0.2s; +} + +.landing-nav-link:hover { + opacity: 0.7; +} + +.landing-nav-button { + text-decoration: none; + font-size: 1rem; + font-weight: 600; + height: 48px; + display: flex; + align-items: center; + padding: 0 1.75rem; + border-radius: 10px; + transition: + transform 0.2s ease, + box-shadow 0.2s ease, + opacity 0.2s ease; + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.18) 0%, + rgba(255, 255, 255, 0.06) 40%, + rgba(0, 0, 0, 0.12) 100% + ), + #27252b; + color: #ebe9f0; + border: 1px solid rgba(255, 255, 255, 0.16); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.32); + backdrop-filter: blur(10px); +} + +.landing-nav-button:hover { + opacity: 0.95; + transform: translateY(-1px) scale(1.02); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4); +} + +.landing-nav-button:active { + transform: translateY(0) scale(0.98); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.26); +} + +.dark .landing-nav-button { + background: + linear-gradient( + 135deg, + rgba(255, 255, 255, 0.25) 0%, + rgba(255, 255, 255, 0.12) 40%, + rgba(255, 255, 255, 0.05) 100% + ), + #e8e6f0; + color: #1e1e1e; + border: 1px solid rgba(255, 255, 255, 0.3); + box-shadow: + inset 0 0 0 1px rgba(255, 255, 255, 0.4), + 0 2px 8px rgba(0, 0, 0, 0.3); +} + +.dark .landing-nav-button:hover { + box-shadow: + inset 0 0 0 1px rgba(255, 255, 255, 0.5), + 0 4px 12px rgba(0, 0, 0, 0.4); +} + +@media (max-width: 768px) { + .intro-landing-page { + --header-height: 96px; + } + + .intro-main { + padding-top: calc(var(--header-height) + 2.5rem); + } + + .landing-header { + padding: 1.5rem 0; + } + + .landing-logo img:not(.landing-wordmark) { + width: 40px; + height: 40px; + } + + .landing-logo .landing-wordmark { + left: calc(40px + 1rem); + width: auto; + height: 20px; + } +} + +@media (max-width: 480px) { + .intro-landing-page { + --header-height: 80px; + } + + .intro-main { + padding-top: calc(var(--header-height) + 2rem); + } + + .landing-header { + padding: 1rem 0; + } + + .landing-logo img:not(.landing-wordmark) { + width: 36px; + height: 36px; + } + + .landing-nav-link, + .landing-nav-button { + font-size: 0.875rem; + height: 40px; + padding: 0 1rem; + } +} diff --git a/app/layout.tsx b/app/layout.tsx index d0369ca1..5ab61d1e 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -43,7 +43,7 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - + {/* Hidden element for LLMs - not visible to users or screen readers */} case 'connected': return
Connected
case 'disconnected': return
Offline
case 'error': return
Error
case 'needs-auth': return
Session expired
default: return null } }import {useConnectionState} from '@rocicorp/zero/solid' function ConnectionStatus() { const state = useConnectionState() return (
Connecting...
Connected
Offline
Error
Session expired
) }zero.connection.state.subscribe(state => { switch (state.name) { case 'connecting': console.log(`Connecting... ${state.reason}`) break case 'connected': console.log('Connected') break case 'disconnected': console.log(`Disconnected ${state.reason}`) break case 'error': console.log(`Error ${state.reason}`) break case 'needs-auth': console.log('Session expired') break default: return null } }) Details Connecting Zero starts in the connecting state. Once the connection is established, it transitions to connected. While connecting, Zero repeatedly tries to connect to zero-cache for 1 minute by default. This timeout can be configured with the disconnectTimeoutMs constructor parameter: const opts: ZeroOptions = { // ... disconnectTimeoutMs: 1000 * 60 * 10 // 10 minutes } Reads and writes are allowed to Zero mutators while connecting. The writes are queued and will be sent when the connection succeeds. This is intended to paper over short connectivity glitches, such as server restarts, walking into an elevator, etc. \\Connecting... case 'connected': return
Connected
case 'disconnected': return
Offline
case 'error': return
Error
case 'needs-auth': return
Session expired
default: return null } }import {useConnectionState} from '@rocicorp/zero/solid' function ConnectionStatus() { const state = useConnectionState() return (
Connecting...
Connected
Offline
Error
Session expired
) }zero.connection.state.subscribe(state => { switch (state.name) { case 'connecting': console.log(`Connecting... ${state.reason}`) break case 'connected': console.log('Connected') break case 'disconnected': console.log(`Disconnected ${state.reason}`) break case 'error': console.log(`Error ${state.reason}`) break case 'needs-auth': console.log('Session expired') break default: return null } }) Details Connecting Zero starts in the connecting state. Once the connection is established, it transitions to connected. While connecting, Zero repeatedly tries to connect to zero-cache for 1 minute by default. This timeout can be configured with the disconnectTimeoutMs constructor parameter: const opts: ZeroOptions = { // ... disconnectTimeoutMs: 1000 * 60 * 10 // 10 minutes } Reads and writes are allowed to Zero mutators while connecting. The writes are queued and will be sent when the connection succeeds. This is intended to paper over short connectivity glitches, such as server restarts, walking into an elevator, etc. \\ track + .related('album') + .related('artist') + .orderBy('playcount', 'asc')) + .where('id', id) + .one() + ); + + const onStar = (id: string, starred: boolean) => { + zero.mutate.track.update({id, starred}); + }; + + // render playlist... +}`, + queries: `import {defineQueries, defineQuery} from '@rocicorp/zero' +import {z} from 'zod' +import {zql} from './schema.ts' + +export const queries = defineQueries({ + albums: { + byArtist: defineQuery( + z.object({artistID: z.string()}), + ({args: {artistID}}) => + zql.albums + .where('artistId', artistID) + .orderBy('createdAt', 'asc') + .limit(10) + .related('artist', q => q.one()) + ) + } +})`, + mutators: `import {defineMutators, defineMutator} from '@rocicorp/zero' +import {z} from 'zod' + +export const mutators = defineMutators({ + updateIssue: defineMutator( + z.object({ + id: z.string(), + title: z.string() + }), + async ({tx, args: {id, title}}) => { + if (title.length > 100) { + throw new Error(\`Title is too long\`) + } + await tx.mutate.issue.update({ + id, + title + }) + } + ) +})`, +}; + +export function IntroductionLanding() { + const videoRef = useRef(null); + const [showDemoModal, setShowDemoModal] = useState(false); + const [isPlaying, setIsPlaying] = useState(true); + const mainRef = useRef(null); + + useEffect(() => { + // Handle escape key for demo modal + const handleEscape = (e: KeyboardEvent) => { + if (e.key === 'Escape') { + setShowDemoModal(false); + } + }; + + if (showDemoModal) { + document.addEventListener('keydown', handleEscape); + document.body.style.overflow = 'hidden'; + } + + return () => { + document.removeEventListener('keydown', handleEscape); + document.body.style.overflow = ''; + }; + }, [showDemoModal]); + + const toggleVideoPlayPause = () => { + if (videoRef.current) { + if (videoRef.current.paused) { + videoRef.current.play(); + setIsPlaying(true); + } else { + videoRef.current.pause(); + setIsPlaying(false); + } + } + }; + + const toggleFullscreen = () => { + const videoContainer = videoRef.current?.parentElement; + if (!videoContainer) return; + + if (!document.fullscreenElement) { + videoContainer.requestFullscreen(); + } else { + document.exitFullscreen(); + } + }; + + const scrollToTop = () => { + const start = window.scrollY; + const duration = 300; + const startTime = performance.now(); + + const animateScroll = (currentTime: number) => { + const elapsed = currentTime - startTime; + const progress = Math.min(elapsed / duration, 1); + const easeProgress = 1 - (1 - progress) * (1 - progress); + + window.scrollTo(0, start * (1 - easeProgress)); + + if (progress < 1) { + requestAnimationFrame(animateScroll); + } + }; + + requestAnimationFrame(animateScroll); + }; + + return ( +
+ +
+
+
+ Zero Logo + Zero Wordmark +
+ +
+
+
+
+ + + Build absurdly fast web applications with Zero + +

+ + Instant Queries by Default + +

+
+ +
+
+ +
+ + +
+
+

+ Try Gigabugs, our 1.2 million row bug tracker. +

+
+ +
+

+ Sync engines enable instant UI by downloading data to the client + before it's needed. All read and writes are local and synced + with the server in the background. +

+

+ But there's a catch: almost all realistic apps have + way too much data to download ahead of time. There are usually + complex permissions too — not all users can read and write all + data. +

+

+ We created Zero to solve these problems and bring the performance of + sync to the entire web. +

+
+ +
+
+
setShowDemoModal(true)} + > +
+

Try it out right now.

+

+ Our Gigabugs demo has 1.2 million rows, and loads in less than + 2 seconds. +

+ +
+
+
+
+ +
+

How it Works

+ +
+ Zero Architecture Diagram +
+ +
+

Zero has two parts: a client and a server.

+

+ The server runs in the cloud and maintains a sync-optimized + replica of your Postgres database. +

+

+ On the client, you get an API that looks like an embedded + database, but to which you can issue arbitrary “hybrid queries” + that span the entire database, including the server. +

+

+ Behind the scenes, Zero synchronizes query results continuously to + a client-side persistent cache. This cache is used automatically + for future queries whenever possible. +

+
+ +
+ +
+                
+                
+              
+
+                
+                
+              
+
+                
+                
+              
+
+
+
+ +
+

Features

+ +
+ +
+ + + + + + + +
+
+

Instant Reads

+

+ This is a placeholder description for a feature block that + should be replaced. Keep it to two to three lines if possible. +

+
+ + +
+ + + + + + + +
+
+

Instant Writes

+

+ This is a placeholder description for a feature block that + should be replaced. Keep it to two to three lines if possible. +

+
+ + +
+ + + + + + +
+
+

Automatic Reactivity

+

+ This is a placeholder description for a feature block that + should be replaced. Keep it to two to three lines if possible. +

+
+ + +
+ + + +
+
+

Fast Startup

+

+ This is a placeholder description for a feature block that + should be replaced. Keep it to two to three lines if possible. +

+
+ + +
+ + + + + + +
+
+

Server Authority

+

+ This is a placeholder description for a feature block that + should be replaced. Keep it to two to three lines if possible. +

+
+ + +
+ + + + +
+
+

Easy Integration

+

+ This is a placeholder description for a feature block that + should be replaced. Keep it to two to three lines if possible. +

+
+ +
+
+ +
+

Our Users Say

+

Check out what our users have to say about Zero.

+ +
+
+
+

+ Zero completely changed how we think about real-time. The + query-driven sync is genius — our app feels instant now. +

+
+
+ Matt Wonlaw +
+
Matt Wonlaw
+
+ Engineering Lead, Streamline +
+
+
+
+ +
+
+

+ We tried building our own sync layer. Should've just used + Zero from day one. Saved us months of development time. +

+
+
+ Marcus Rodriguez +
+
Marcus Rodriguez
+
CTO, Catalyst Labs
+
+
+
+ +
+
+

+ The permission system is incredibly powerful. We can finally + give users real-time collaboration without worrying about data + leaks. +

+
+
+ Priya Patel +
+
Priya Patel
+
+ Senior Developer, Nexus +
+
+
+
+ +
+
+

+ Local-first with Zero means our app works offline and syncs + seamlessly. Our users don't even notice when their + connection drops. +

+
+
+ Alex Kumar +
+
Alex Kumar
+
Founder, TaskFlow
+
+
+
+ +
+
+

+ The developer experience is top-notch. Write queries, get + reactive updates. It's that simple. +

+
+
+ Jamie Taylor +
+
Jamie Taylor
+
+ Full-Stack Developer, Velocity +
+
+
+
+ +
+
+

+ Zero handles the hard parts of sync so we can focus on + building features. The performance gains are unreal. +

+
+
+ Taylor Morgan +
+
Taylor Morgan
+
+ Product Engineer, Orbit +
+
+
+
+
+
+ +
+
+

Pricing

+
+ +
+ Cloud Zero Dashboard +
+ +
+
+
+ Traditional SaaS +

Hobby

+
+

+ zero-cache runs in Rocicorp's AWS account. +

+
    +
  • 10 GB storage
  • +
  • 3 shared vCPU
  • +
  • Support via public Discord
  • +
  • Additional storage: $0.20 / GB
  • +
  • Dedicated vCPU: $50 each
  • +
+
+
+ $30 + /mo +
+
+
+ +
+
+ Traditional SaaS +

Professional

+
+

+ zero-cache runs in Rocicorp's AWS account. +

+
    +
  • 100 GB storage
  • +
  • 6 dedicated vCPU
  • +
  • Shared Slack channel
  • +
  • Additional storage: $0.20 / GB
  • +
  • Additional vCPU: $50
  • +
+
+
+ $300 + /mo +
+
+
+ +
+
+ BYOC +

Bring Your Own Cloud

+
+

+ zero-cache runs in your own AWS account. +

+
    +
  • Data stays in your AWS account
  • +
  • Rocicorp has limited privileges
  • +
  • AWS infra billed to your account
  • +
  • Shared Slack channel
  • +
  • Includes 10 vCPU
  • +
  • Additional vCPU: $20
  • +
+
+
+ $1000 + /mo + + AWS +
+
+
+
+ +
+
+

Get in Touch

+

+ Hosting is in private beta. Message us and we'll get you + onboarded. +

+ +
+
+
+ +
+

Run Zero Yourself

+ +
+ +
+ + + +
+
+

View the Docs

+

+ Get started with Zero and learn how it fits into your stack. +

+
+ + +
+ + + +
+
+

Join Discord

+

+ Connect with the team and other builders in our community. +

+
+
+
+
+
+ +
+ + + Made by Rocicorp + +
+ + {/* Demo Modal */} + {showDemoModal && ( +
+
setShowDemoModal(false)} + >
+
+
+ +
+ +
+
+ )} +
+ ); +} diff --git a/components/logos/Rocicorp.tsx b/components/logos/Rocicorp.tsx index fb1424c7..ca242848 100644 --- a/components/logos/Rocicorp.tsx +++ b/components/logos/Rocicorp.tsx @@ -8,44 +8,12 @@ function RocicorpLogo(props: RocicorpLogoProps) { return ( - - - - - - - - ; function ZeroAlphaLogo(props: ZeroAlphaLogoProps) { + const {className, ...rest} = props; return ( ); diff --git a/components/toc.tsx b/components/toc.tsx index 86e86a14..96ef0a63 100644 --- a/components/toc.tsx +++ b/components/toc.tsx @@ -6,12 +6,14 @@ import {ArrowUpRightFromSquare} from 'lucide-react'; export default function Toc({ tocs, path, + className, }: { tocs: {level: number; text: string; href: string}[]; path: string; + className?: string; }) { return ( -
+