diff --git a/src/components/ArchDiagramSection/index.js b/src/components/ArchDiagramSection/index.js new file mode 100644 index 0000000..eeed05a --- /dev/null +++ b/src/components/ArchDiagramSection/index.js @@ -0,0 +1,205 @@ +import React from 'react'; +import styles from './styles.module.css'; + +function ArrowDown() { + return ( + + ); +} + +function ClusterConnectors() { + return ( + + ); +} + +function StorageConnectors() { + return ( + + ); +} + +function DatabaseIcon() { + return ( + + ); +} + +function StorageIcon() { + return ( + + ); +} + +const features = [ + { + label: 'High Availability', + description: 'Automatic Failover & Self-Healing', + icon: ( + + ), + }, + { + label: 'Backups', + description: 'Continuous Backups', + icon: ( + + ), + }, + { + label: 'PITR', + description: 'Point-in-Time Recovery', + icon: ( + + ), + }, + { + label: 'Monitoring', + description: 'Built-in Metrics & Alerting', + icon: ( + + ), + }, + { + label: 'Upgrades', + description: 'Zero-Downtime Upgrades', + icon: ( + + ), + }, + { + label: 'Scaling', + description: 'Cluster Scaling with read replicas', + icon: ( + + ), + }, +]; + +/* ── Reusable diagram JSX ────────────────────────────────────────────── */ +function DiagramInner() { + return ( +
+
+
+
Users
+
+ Developers + | + SRE + | + DBA +
+
+
+
+
+
+
+ + Autobase Platform +
+
+ Provisioning + | + Maintenance + | + Scaling +
+
+
+ +
+
+
PostgreSQL
Cluster 1
+
PostgreSQL
Cluster 2
+
PostgreSQL
Cluster N
+
+ +
+
+
+
+ +
+
Database Storage / Backup Storage
+
Local NVMe, SSD, EBS for data / S3, MinIO, etc. for backups
+
+
+
+
+
+ ); +} + +export default function ArchDiagramSection() { + return ( +
+
+ + {/* ── Architecture Diagram ── */} + + + {/* ── Divider ── */} +
+ + {/* ── Features Grid ── */} +
+ {features.map((f) => ( +
+
{f.icon}
+
{f.label}
+
{f.description}
+
+ ))} +
+ +
+
+ ); +} diff --git a/src/components/ArchDiagramSection/styles.module.css b/src/components/ArchDiagramSection/styles.module.css new file mode 100644 index 0000000..0509c20 --- /dev/null +++ b/src/components/ArchDiagramSection/styles.module.css @@ -0,0 +1,300 @@ +/* ─── Section — full viewport width ──────────────────────────────── */ +.section { + --diagram-line: #8f8f8f; + --diagram-border: #b7b7b7; + width: 100vw; + min-height: 100vh; + background: var(--color-surface); + border-bottom: 1px solid var(--color-border); + display: flex; + align-items: center; + justify-content: center; + position: relative; + left: 50%; + margin-left: -50vw; +} + +.inner { + width: 100%; + max-width: 1200px; + margin: 0 auto; + padding: 60px 80px; + display: flex; + flex-direction: column; + align-items: center; +} + +/* ─── Diagram ─────────────────────────────────────────────────────── */ +.diagram { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; +} + +/* ─── Row ─────────────────────────────────────────────────────────── */ +.row { + width: 100%; + display: flex; + justify-content: center; +} + +/* ─── Box ─────────────────────────────────────────────────────────── */ +.box { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 28px 0; + border: 2px dashed var(--diagram-border); + border-radius: 2px; + font-size: 20px; + font-weight: 400; + color: var(--color-text); + background: transparent; + width: 80%; +} + +.muted { + color: var(--color-text-muted); + margin-left: 8px; +} + +.usersBox { + flex-direction: column; + gap: 12px; + width: 48%; +} + +.usersTitle { + font-size: 22px; + color: var(--color-text); +} + +.userRoles { + display: flex; + align-items: center; + justify-content: center; + gap: 12px; + flex-wrap: wrap; + font-size: 16px; + color: var(--color-text-muted); +} + +/* ─── Arrow down ──────────────────────────────────────────────────── */ +.arrowRow { + display: flex; + justify-content: center; + height: 48px; + align-items: center; + color: var(--diagram-line); +} + +.arrowDown { display: block; } + +/* ─── Platform ───────────────────────────────────────────────────── */ +.platform { + flex-direction: column; + gap: 14px; + padding: 32px 0; + border-color: var(--color-primary); + border-style: dashed; + border-width: 2px; + width: 80%; +} + +.cpHeader { + display: flex; + align-items: center; + justify-content: center; + gap: 12px; +} + +.cpTitle { + font-size: 24px; + font-weight: 700; + color: var(--color-primary); +} + +.cpPills { + display: flex; + align-items: center; + gap: 12px; + flex-wrap: wrap; + justify-content: center; + font-size: 16px; + color: var(--color-text-muted); +} + +.sep { color: var(--color-border); } + +.clusterConnectors { + width: 80%; + height: 72px; + color: var(--diagram-line); +} + +.storageConnectors { + width: 80%; + height: 72px; + color: var(--diagram-line); +} + +.mobileConnector { + display: none; +} + +/* ─── Clusters ────────────────────────────────────────────────────── */ +.clustersRow { + display: flex; + align-items: center; + gap: 56px; + width: 80%; +} + +.clusterBox { + display: flex; + flex-direction: column; + align-items: center; + gap: 14px; + padding: 32px 0; + border: 2px dashed var(--diagram-border); + border-radius: 2px; + font-size: 16px; + color: var(--color-text); + text-align: center; + line-height: 1.5; + flex: 1; + background: transparent; +} + +.clusterBoxOptional { + opacity: 0.72; +} + +.diagramIcon { + color: var(--diagram-line); +} + +/* ─── Storage ─────────────────────────────────────────────────────── */ +.storageRow { + display: flex; + align-items: center; + gap: 20px; + text-align: left; +} + +.storageTitle { + font-size: 20px; + color: var(--color-text); +} + +.storageSub { + font-size: 15px; + color: var(--color-text-muted); + margin-top: 6px; +} + +/* ─── Divider ─────────────────────────────────────────────────────── */ +.divider { + width: 80%; + border: none; + border-top: 1px solid var(--color-border); + margin: 48px auto; +} + +/* ─── Features Grid ───────────────────────────────────────────────── */ +.featuresGrid { + width: 100%; + display: grid; + grid-template-columns: repeat(6, 1fr); + border: 2px solid var(--color-border); + border-radius: 8px; + overflow: hidden; +} + +.featureCard { + display: flex; + flex-direction: column; + gap: 12px; + padding: 32px 24px; + border-right: 2px solid var(--color-border); + transition: background 0.2s ease; +} + +.featureCard:last-child { border-right: none; } +.featureCard:hover { background: var(--color-surface); } + +.featureIcon { + color: var(--color-text); +} + +.featureIcon svg { + display: block; + width: 48px; + height: 48px; +} + +.featureLabel { + font-size: var(--fs-sm); + font-weight: var(--fw-bold); + color: var(--color-text); +} + +.featureDesc { + font-size: 16px; + color: var(--color-text-muted); + line-height: 1.5; +} + +/* ─── Responsive ──────────────────────────────────────────────────── */ +@media (max-width: 1100px) { + .inner { padding: 0 48px; } + .box, .controlPlane, .clusterConnectors, .storageConnectors, .clustersRow { width: 90%; } + .usersBox { width: 64%; } + .featuresGrid { grid-template-columns: repeat(3, 1fr); } + .featureCard:nth-child(3) { border-right: none; } + .featureCard:nth-child(n+4) { border-top: 2px solid var(--color-border); } +} + +@media (max-width: 768px) { + .inner { padding: 40px 24px; } + .section { min-height: auto; } + .box, .controlPlane, .clusterConnectors, .storageConnectors, .clustersRow { width: 100%; } + .usersBox { width: 100%; } + .box { font-size: 15px; padding: 20px 12px; } + .usersTitle { font-size: 18px; } + .userRoles { font-size: 13px; gap: 8px; } + .cpTitle { font-size: 18px; } + .cpPills { font-size: 13px; gap: 8px; } + .clustersRow { gap: 24px; } + .clusterBox { padding: 20px 8px; font-size: 13px; gap: 8px; } + .storageTitle { font-size: 15px; } + .storageSub { font-size: 13px; } + .featuresGrid { grid-template-columns: repeat(2, 1fr); } + .featureCard:nth-child(n) { border-right: 2px solid var(--color-border); border-top: none; } + .featureCard:nth-child(2n) { border-right: none; } + .featureCard:last-child { border-right: none; } + .featureCard:nth-child(n+3) { border-top: 2px solid var(--color-border); } + .featureDesc { font-size: 13px; } + .divider { margin: 32px auto; } +} + +@media (max-width: 480px) { + .inner { padding: 32px 16px; } + .featuresGrid { grid-template-columns: 1fr; } + .featureCard { border-right: none; border-bottom: 2px solid var(--color-border); } + .featureCard:last-child { border-bottom: none; } + .featureCard:nth-child(n) { border-top: none; border-right: none; } + .clustersRow { flex-direction: column; gap: 0; } + .clusterConnectors, + .storageConnectors { display: none; } + .mobileConnector { + display: flex; + justify-content: center; + height: 48px; + color: var(--diagram-line); + } + .clusterBox { width: 100%; border-radius: 0; } + .clusterBox:first-child { border-radius: 2px 2px 0 0; } + .clusterBox:last-child { border-radius: 0 0 2px 2px; } +} diff --git a/src/components/CLISection/index.js b/src/components/CLISection/index.js new file mode 100644 index 0000000..d5d69ae --- /dev/null +++ b/src/components/CLISection/index.js @@ -0,0 +1,155 @@ +import React, { useState, useEffect, useRef } from 'react'; +import styles from './styles.module.css'; + +/* ── Getting-started workflow (inline terminal) ─────────────────────── */ +const SEQUENCES = [ + { + command: '$ curl -fsSL https://autobase.tech/platform.yml \\\n --output ./docker-compose.platform.yml', + result: '✓ Downloaded', + detail: ' ./docker-compose.platform.yml', + }, + { + command: '$ docker compose \\\n -f docker-compose.platform.yml up -d', + result: '✓ Autobase Console started', + detail: ' http://your-server-address', + }, +]; + +const CLEAR_CMD = '\n$ \\! clear'; +const CHAR_SPEED = 28; +const CLS_SPEED = 90; +const HOLD_MS = 2600; +const FLASH_MS = 420; + +/* ── Inline terminal body (cycles SEQUENCES) ──────────────────────── */ +function InlineBody({ typed, clsTyped, phase, seq }) { + const showResult = phase === 'showing' || phase === 'typing_cls' || phase === 'flash'; + const showCls = phase === 'typing_cls' || phase === 'flash'; + const isFlashing = phase === 'flash'; + const displayText = typed.startsWith('$ ') ? typed.slice(2) : typed; + + return ( +
+      $
+      {' '}
+      {displayText}
+      {phase === 'typing' && _}
+      {showResult && (
+        <>
+          {'\n\n'}
+          {seq.result}
+          {'\n'}
+          {seq.detail}
+        
+      )}
+      {showCls && (
+        <>
+          {'\n'}
+          {clsTyped}
+          {phase === 'typing_cls' && clsTyped.length < CLEAR_CMD.length && (
+            _
+          )}
+        
+      )}
+    
+ ); +} + +export default function CLISection() { + /* ── Inline cycling state ── */ + const [seqIdx, setSeqIdx] = useState(0); + const [typed, setTyped] = useState(''); + const [clsTyped, setClsTyped] = useState(''); + const [phase, setPhase] = useState('typing'); + const timer = useRef(null); + + const seq = SEQUENCES[seqIdx]; + + /* ── Inline typewriter ── */ + useEffect(() => { + if (phase !== 'typing') return; + clearTimeout(timer.current); + const cmd = seq.command; + if (typed.length < cmd.length) { + timer.current = setTimeout(() => setTyped(cmd.slice(0, typed.length + 1)), CHAR_SPEED); + } else { + timer.current = setTimeout(() => setPhase('showing'), 300); + } + return () => clearTimeout(timer.current); + }, [phase, typed, seq.command]); + + useEffect(() => { + if (phase !== 'showing') return; + timer.current = setTimeout(() => { setClsTyped(''); setPhase('typing_cls'); }, HOLD_MS); + return () => clearTimeout(timer.current); + }, [phase]); + + useEffect(() => { + if (phase !== 'typing_cls') return; + clearTimeout(timer.current); + if (clsTyped.length < CLEAR_CMD.length) { + timer.current = setTimeout(() => setClsTyped(CLEAR_CMD.slice(0, clsTyped.length + 1)), CLS_SPEED); + } else { + timer.current = setTimeout(() => setPhase('flash'), 180); + } + return () => clearTimeout(timer.current); + }, [phase, clsTyped]); + + useEffect(() => { + if (phase !== 'flash') return; + timer.current = setTimeout(() => { + setTyped(''); setClsTyped(''); + setSeqIdx(i => (i + 1) % SEQUENCES.length); + setPhase('typing'); + }, FLASH_MS); + return () => clearTimeout(timer.current); + }, [phase]); + + const bar = ( +
+ +
+ ); + + return ( +
+
+
+ +
+ {bar} + +
+ +
+ + > + +
DOWNLOAD PLATFORM
+
Enterprise Edition · Free Trial 14 Days
+
+
+ + > + +
GET A DEMO
+
Use token 'demo' to access
+
+
+
+ +
+
+
+ ); +} diff --git a/src/components/CLISection/styles.module.css b/src/components/CLISection/styles.module.css new file mode 100644 index 0000000..a39ab08 --- /dev/null +++ b/src/components/CLISection/styles.module.css @@ -0,0 +1,183 @@ +/* ─── Section ─────────────────────────────────────────────────────── */ +.section { + background: var(--color-bg); + padding: var(--section-pt) 0 var(--section-pb); +} + +.inner { + max-width: 1200px; + margin: 0 auto; + padding: 0 80px; +} + +/* ─── Two-column layout ───────────────────────────────────────────── */ +.layout { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 40px; + align-items: center; +} + +/* ─── Terminal (inline) ───────────────────────────────────────────── */ +.terminal { + background: #0d0d0d; + border-radius: 10px; + overflow: hidden; + box-shadow: 0 8px 40px rgba(0, 0, 0, 0.15); +} + +.terminalBar { + display: flex; + align-items: center; + gap: 8px; + padding: 14px 18px; + background: #1a1a1a; +} + +.dot { + width: 12px; + height: 12px; + border-radius: 50%; + background: #3a3a3a; +} + +/* ─── Terminal code block ─────────────────────────────────────────── */ +.terminalCode { + font-family: 'Courier New', Courier, monospace; + font-size: 14px; + line-height: 1.7; + color: #c8c8c8; + padding: 24px 28px; + margin: 0; + white-space: pre; + overflow-x: auto; + background: transparent; + border: none; + min-height: 220px; +} + +/* CRT phosphor flash */ +.terminalFlash { + animation: crtClear 0.42s ease-in forwards; +} + +@keyframes crtClear { + 0% { opacity: 1; filter: brightness(1) blur(0px); } + 25% { opacity: 1; filter: brightness(3.5) blur(1px); } + 55% { opacity: 0.15; filter: brightness(0.4) blur(2px); } + 100% { opacity: 0; filter: brightness(0) blur(0px); } +} + +.prompt { + color: var(--color-primary); + font-weight: bold; +} + +.caret { + display: inline-block; + color: #c8c8c8; + animation: caretBlink 1s step-end infinite; + user-select: none; +} + +@keyframes caretBlink { + 0%, 100% { opacity: 1; } + 50% { opacity: 0; } +} + +.success { + color: #4caf50; + font-weight: bold; +} + +.dimmed { + color: #666666; +} + +/* ─── CTAs column (original) ──────────────────────────────────────── */ +.ctas { + display: flex; + flex-direction: column; + gap: 16px; +} + +.ctaPrimary, +.ctaSecondary { + display: flex; + align-items: center; + gap: 20px; + padding: 24px 28px; + border-radius: 2px; + outline: 1.5px solid transparent; + outline-offset: 0px; + background: transparent; + box-shadow: 6px 6px 0 rgba(0, 0, 0, 0.05); + text-decoration: none; + transition: border-color 0.18s ease, outline-color 0.18s ease, + background 0.18s ease, + transform 0.18s ease, + box-shadow 0.18s ease; +} + +.ctaPrimary:hover, +.ctaSecondary:hover { + text-decoration: none; +} + +.ctaPrimary { + border: 1.5px solid var(--color-primary); +} + +.ctaSecondary { + border: 1.5px solid var(--color-border); +} + +.ctaPrimary:hover, +.ctaSecondary:hover { + border-color: var(--color-primary); + outline-color: var(--color-primary); + background: var(--color-surface); + opacity: 1; + transform: translate(3px, 3px); + box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.1); +} + +.ctaArrow { + font-family: monospace; + font-size: 20px; + font-weight: bold; + color: var(--color-primary); + flex-shrink: 0; +} + +.ctaTitle { + font-family: var(--font-base); + font-size: var(--fs-body); + font-weight: var(--fw-bold); + color: var(--color-text); + text-transform: uppercase; + letter-spacing: 0.3px; +} + +.ctaSubtitle { + font-family: var(--font-base); + font-size: var(--fs-sm); + font-weight: var(--fw-regular); + color: var(--color-text-muted); + margin-top: 4px; +} + +/* ─── Responsive ──────────────────────────────────────────────────── */ +@media (max-width: 900px) { + .inner { padding: 0 48px; } + .layout { grid-template-columns: 1fr; } + .ctas { flex-direction: row; flex-wrap: wrap; gap: 12px; } + .ctaPrimary, .ctaSecondary { flex: 1; min-width: 200px; padding: 20px 20px; } +} + +@media (max-width: 600px) { + .inner { padding: 0 20px; } + .terminalCode { font-size: 12px; padding: 16px; min-height: 160px; } + .ctas { flex-direction: column; } + .ctaPrimary, .ctaSecondary { width: 100%; } +} diff --git a/src/components/ClickEffect/index.js b/src/components/ClickEffect/index.js new file mode 100644 index 0000000..4acbc46 --- /dev/null +++ b/src/components/ClickEffect/index.js @@ -0,0 +1,108 @@ +import React, { useEffect, useRef } from 'react'; + +// Digits pool — mix of decimal + hex for a pg/terminal data feel +const DIGITS = '0123456789ABCDEF01234567890123456789'; + +// Weighted color pool — mostly dark, rare orange spark +const COLORS = [ + { color: '#111111', weight: 5 }, + { color: '#555555', weight: 3 }, + { color: '#999999', weight: 2 }, + { color: '#ff5722', weight: 1 }, +]; +const TOTAL_WEIGHT = COLORS.reduce((s, c) => s + c.weight, 0); + +function pickColor() { + let r = Math.random() * TOTAL_WEIGHT; + for (const c of COLORS) { + r -= c.weight; + if (r <= 0) return c.color; + } + return COLORS[0].color; +} + +function pickDigit() { + return DIGITS[Math.floor(Math.random() * DIGITS.length)]; +} + +export default function ClickEffect() { + const canvasRef = useRef(null); + + useEffect(() => { + const canvas = canvasRef.current; + if (!canvas) return; + const ctx = canvas.getContext('2d'); + let particles = []; + let raf; + + function resize() { + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + } + resize(); + window.addEventListener('resize', resize); + + function spawn(x, y) { + const count = 8 + Math.floor(Math.random() * 7); + for (let i = 0; i < count; i++) { + const angle = Math.random() * Math.PI * 2; + const speed = 1.2 + Math.random() * 4; + const fontSize = 10 + Math.floor(Math.random() * 8); // 10–17px + particles.push({ + x, y, + vx: Math.cos(angle) * speed, + vy: Math.sin(angle) * speed - 2, // bias upward + alpha: 0.9 + Math.random() * 0.1, + decay: 0.025 + Math.random() * 0.025, + color: pickColor(), + digit: pickDigit(), + fontSize, + font: `${fontSize}px "Courier New", monospace`, + }); + } + } + + function animate() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + particles = particles.filter(p => p.alpha > 0); + for (const p of particles) { + p.x += p.vx; + p.y += p.vy; + p.vy += 0.18; // gravity + p.vx *= 0.97; // drag + p.alpha -= p.decay; + + ctx.globalAlpha = Math.max(0, p.alpha); + ctx.fillStyle = p.color; + ctx.font = p.font; + ctx.fillText(p.digit, Math.round(p.x), Math.round(p.y)); + } + ctx.globalAlpha = 1; + raf = requestAnimationFrame(animate); + } + animate(); + + function onClick(e) { spawn(e.clientX, e.clientY); } + document.addEventListener('click', onClick); + + return () => { + cancelAnimationFrame(raf); + document.removeEventListener('click', onClick); + window.removeEventListener('resize', resize); + }; + }, []); + + return ( + + ); +} diff --git a/src/components/ContactSection/index.js b/src/components/ContactSection/index.js new file mode 100644 index 0000000..e1052d8 --- /dev/null +++ b/src/components/ContactSection/index.js @@ -0,0 +1,37 @@ +import React from 'react'; +import styles from './styles.module.css'; + +const links = [ + { label: 'GitHub', href: 'https://github.com/autobase-tech/' }, + { label: 'X', href: 'https://x.com/autobase_tech' }, + { label: 'LinkedIn ', href: 'https://www.linkedin.com/company/autobasetech/' }, + { label: 'YouTube', href: 'https://youtube.com/@autobasetech' }, + { label: 'Telegram', href: 'https://t.me/pavel_kovcheg' }, + { label: 'Email', href: 'mailto:info@autobase.tech' }, + { label: 'Support', href: '/docs/support' }, +]; + +export default function ContactSection() { + return ( +
+
+

Contact

+ +
+
+ ); +} diff --git a/src/components/ContactSection/styles.module.css b/src/components/ContactSection/styles.module.css new file mode 100644 index 0000000..468b860 --- /dev/null +++ b/src/components/ContactSection/styles.module.css @@ -0,0 +1,66 @@ +/* ─── Section ─────────────────────────────────────────────────────── */ +.section { + background: + linear-gradient(to right, transparent 10%, var(--color-border) 10%, var(--color-border) 90%, transparent 90%) no-repeat 0 0 / 100% 1px, + var(--color-bg); + padding: 32px 0 48px; + margin-top: 0; +} + +.inner { + max-width: 1200px; + margin: 0 auto; + padding: 0 80px; + display: flex; + align-items: baseline; + gap: 28px; +} + +.title { + font-family: var(--font-base); + font-size: var(--fs-body); + font-weight: var(--fw-semibold); + color: var(--color-text); + margin: 0; + flex-shrink: 0; +} + +.links { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 0 14px; + font-family: var(--font-base); + font-size: var(--fs-sm); + color: var(--color-text-muted); +} + +.link { + color: var(--color-text-muted); + text-decoration: none; + transition: color 0.15s ease; +} + +.link:hover { + color: var(--color-text); + text-decoration: none; +} + +.separator { + color: var(--color-border); +} + +/* ─── Responsive ──────────────────────────────────────────────────── */ +@media (max-width: 900px) { + .inner { + padding: 0 48px; + flex-direction: column; + gap: 12px; + } +} + +@media (max-width: 600px) { + .section { padding: 28px 0 40px; } + .inner { padding: 0 20px; } + .links { gap: 2px 10px; } +} diff --git a/src/components/FeaturesGridSection/index.js b/src/components/FeaturesGridSection/index.js new file mode 100644 index 0000000..cd18afe --- /dev/null +++ b/src/components/FeaturesGridSection/index.js @@ -0,0 +1,95 @@ +import React from 'react'; +import styles from './styles.module.css'; + +const features = [ + { + icon: ( + + ), + label: 'HA', + title: 'High Availability', + description: 'Automatic High Availability', + }, + { + icon: ( + + ), + label: 'Failover', + title: 'Failover', + description: 'Automatic Failover & Self-Healing', + }, + { + icon: ( + + ), + label: 'Backups', + title: 'Backups', + description: 'Continuous Backups', + }, + { + icon: ( + + ), + label: 'PITR', + title: 'PITR', + description: 'Point-in-Time Recovery', + }, + { + icon: ( + + ), + label: 'Monitoring', + title: 'Monitoring', + description: 'Built-in Metrics & Alerting', + }, + { + icon: ( + + ), + label: 'Upgrades', + title: 'Upgrades', + description: 'Zero-Downtime Upgrades', + }, +]; + +export default function FeaturesGridSection() { + return ( +
+
+
+ {features.map((f) => ( +
+
{f.icon}
+
{f.label}
+
{f.description}
+
+ ))} +
+
+
+ ); +} diff --git a/src/components/FeaturesGridSection/styles.module.css b/src/components/FeaturesGridSection/styles.module.css new file mode 100644 index 0000000..a12fb70 --- /dev/null +++ b/src/components/FeaturesGridSection/styles.module.css @@ -0,0 +1,93 @@ +/* ─── Section ─────────────────────────────────────────────────────── */ +.section { + background: + linear-gradient(to right, transparent 10%, var(--color-border) 10%, var(--color-border) 90%, transparent 90%) no-repeat 0 0 / 100% 1px, + var(--color-bg); + padding: var(--section-pt) 0 var(--section-pb); +} + +.inner { + max-width: 1200px; + margin: 0 auto; + padding: 0 200px; +} + +/* ─── Grid ────────────────────────────────────────────────────────── */ +.grid { + display: grid; + grid-template-columns: repeat(6, 1fr); + gap: 0; + border: 1px solid var(--color-border); + border-radius: 8px; + overflow: hidden; +} + +/* ─── Card ────────────────────────────────────────────────────────── */ +.card { + display: flex; + flex-direction: column; + gap: 12px; + padding: 32px 24px; + border-right: 1px solid var(--color-border); + transition: background 0.2s ease; +} + +.card:last-child { + border-right: none; +} + +.card:hover { + background: var(--color-surface); +} + +/* ─── Icon ────────────────────────────────────────────────────────── */ +.icon { + color: var(--color-text); + display: flex; + align-items: center; +} + +/* ─── Label ───────────────────────────────────────────────────────── */ +.label { + font-family: var(--font-base); + font-size: var(--fs-sm); + font-weight: var(--fw-bold); + color: var(--color-text); +} + +/* ─── Description ─────────────────────────────────────────────────── */ +.description { + font-family: var(--font-base); + font-size: 13px; + font-weight: var(--fw-regular); + color: var(--color-text-muted); + line-height: 1.5; +} + +/* ─── Responsive ──────────────────────────────────────────────────── */ +@media (max-width: 1200px) { + .inner { padding: 0 80px; } +} + +@media (max-width: 1100px) { + .inner { padding: 0 48px; } + .grid { grid-template-columns: repeat(3, 1fr); } + .card:nth-child(3) { border-right: none; } + .card:nth-child(n+4) { border-top: 1px solid var(--color-border); } +} + +@media (max-width: 768px) { + .inner { padding: 0 20px; } + .grid { grid-template-columns: repeat(2, 1fr); } + .card:nth-child(3) { border-right: 1px solid var(--color-border); } + .card:nth-child(2n) { border-right: none; } + .card:nth-child(n+3) { border-top: 1px solid var(--color-border); } +} + +@media (max-width: 480px) { + .inner { padding: 0 16px; } + .grid { grid-template-columns: 1fr; } + .card { border-right: none; border-top: none; border-bottom: 1px solid var(--color-border); } + .card:last-child { border-bottom: none; } + .card:nth-child(n) { border-right: none; border-top: none; } +} diff --git a/src/components/HeroSection/index.js b/src/components/HeroSection/index.js index d08bfb5..63ee467 100644 --- a/src/components/HeroSection/index.js +++ b/src/components/HeroSection/index.js @@ -1,126 +1,68 @@ -import React, { useEffect, useRef, useState } from 'react'; -import Link from '@docusaurus/Link'; +import React, { useState, useEffect } from 'react'; +import TrustedByCarousel from '@site/src/components/TrustedByCarousel'; import styles from './styles.module.css'; -const TYPEWRITER_TEXT = 'DBaaS Platform'; -const CHAR_SPEED = 58; +const LINE1 = 'DATABASE PLATFORM'; +const LINE2 = 'FOR POSTGRESQL'; +const SUBTEXT = 'Self-Hosted DBaaS [Database as a Service]'; +const SPEED = 60; // ms per character +const H1_TOTAL = LINE1.length + LINE2.length; +const SUB_DELAY = H1_TOTAL * SPEED + 200; // starts after headline + 0.2s pause export default function HeroSection() { - const postgresRef = useRef(null); - const bodyRef = useRef(null); - const [typed, setTyped] = useState(''); - const [cursorVisible, setCursorVisible] = useState(false); + const [h1Count, setH1Count] = useState(0); + const [subCount, setSubCount] = useState(0); + const [subStarted, setSubStarted] = useState(false); + // headline typing (left → right) useEffect(() => { - let mounted = true; + if (h1Count >= H1_TOTAL) return; + const id = setTimeout(() => setH1Count(n => n + 1), SPEED); + return () => clearTimeout(id); + }, [h1Count]); - import('gsap').then(({ gsap }) => { - if (!mounted) return; + // subheading delay trigger + useEffect(() => { + const id = setTimeout(() => setSubStarted(true), SUB_DELAY); + return () => clearTimeout(id); + }, []); - // 1. "PostgreSQL." — scale + opacity entrance - gsap.fromTo( - postgresRef.current, - { opacity: 0, scale: 0.88, y: 10 }, - { - opacity: 1, - scale: 1, - y: 0, - duration: 0.95, - ease: 'expo.out', - onComplete() { - if (!mounted) return; - setCursorVisible(true); - let i = 0; - const tick = setInterval(() => { - if (!mounted) { clearInterval(tick); return; } - i++; - setTyped(TYPEWRITER_TEXT.slice(0, i)); - if (i >= TYPEWRITER_TEXT.length) { - clearInterval(tick); - setTimeout(() => { if (mounted) setCursorVisible(false); }, 800); - } - }, CHAR_SPEED); - }, - } - ); + // subheading typing (right → left: rightmost chars appear first) + useEffect(() => { + if (!subStarted || subCount >= SUBTEXT.length) return; + const id = setTimeout(() => setSubCount(n => n + 1), SPEED); + return () => clearTimeout(id); + }, [subStarted, subCount]); - // 2. Body + CTAs fade up slightly after - gsap.fromTo( - bodyRef.current, - { opacity: 0, y: 18 }, - { opacity: 1, y: 0, duration: 0.9, ease: 'expo.out', delay: 0.55 } - ); - }); + const c1 = Math.min(h1Count, LINE1.length); + const c2 = Math.max(0, h1Count - LINE1.length); - return () => { mounted = false; }; - }, []); + // reverse: slice from the right, so last chars appear first + const subDisplayed = SUBTEXT.slice(SUBTEXT.length - subCount); return ( -
- - +
-
- - {/* Text column */} -
-
-

- - PostgreSQL - - - {typed} - {cursorVisible && ( - - )} - -

+

+ + {LINE1.slice(0, c1)} + + + {LINE2.slice(0, c2)} + +

-
-

- Get the managed database experience inside your own infrastructure. - Deploy, operate, scale and manage PostgreSQL with one unified platform and full infrastructure control. -

-
- - Get started - - - Chat on Telegram - - -
-
-
-
+

+ {subStarted && ( + <> + {subDisplayed} + _ + + )} +

- {/* Image column */} -
- PostgreSQL server illustration -
- -
+
- - -
); } diff --git a/src/components/HeroSection/styles.module.css b/src/components/HeroSection/styles.module.css index 2d7d547..bedd7c0 100644 --- a/src/components/HeroSection/styles.module.css +++ b/src/components/HeroSection/styles.module.css @@ -1,236 +1,91 @@ -/* ─── Keyframes ───────────────────────────────────────────────────── */ -@keyframes heroFadeIn { - from { opacity: 0; transform: translateY(24px); } - to { opacity: 1; transform: translateY(0); } +/* ─── Section ─────────────────────────────────────────────────────── */ +.hero { + background: var(--color-bg); } -@keyframes cursorBlink { - 0%, 49% { opacity: 1; } - 50%, 100% { opacity: 0; } -} - -/* ─── Section shell ───────────────────────────────────────────────── */ -.heroSection { - position: relative; - overflow: hidden; - border-bottom-left-radius: 48px; - border-bottom-right-radius: 48px; - background: linear-gradient(98.84deg, #000000 2.84%, #290a00 42.32%, #1a0600 95.10%); -} - -/* ─── Background texture ──────────────────────────────────────────── */ -.bgTexture { - position: absolute; - bottom: -288px; - left: 0; - width: 1600px; - height: 1600px; - opacity: 0.08; - pointer-events: none; - object-fit: cover; - z-index: 0; -} - -/* ─── Max-width centering wrapper (Bootstrap row lives inside) ────── */ .inner { - max-width: 1540px; - margin: 0 auto; - padding: 0 160px; position: relative; - z-index: 1; -} - -/* ─── Left content column ─────────────────────────────────────────── */ -.content { + width: 100%; + max-width: 1200px; + margin: 0 auto; + padding: 60px 80px 48px; display: flex; flex-direction: column; - gap: 50px; + gap: 24px; } -/* Body + CTAs wrapper (animated together by GSAP) */ -.bodyWrap { - display: flex; - flex-direction: column; - gap: 50px; +.inner::after { + content: ''; + position: absolute; + right: 80px; + bottom: 0; + left: 80px; + height: 1px; + background: var(--color-border); } -/* ─── Heading — type.hero.900 ─────────────────────────────────────── */ +/* ─── Heading — Quantico Bold ─────────────────────────────────────── */ .heading { - font-family: var(--font-base); - font-size: var(--fs-hero); - font-weight: var(--fw-black); + font-family: 'Quantico', sans-serif; + font-size: clamp(36px, 5vw, 64px); + font-weight: 700; line-height: 1.05; + color: var(--color-text); + letter-spacing: -1px; margin: 0; - padding: 0; -} - -.headingWhite { - color: var(--color-white); - display: block; } -/* Second heading line — block container for gradient text + cursor */ -.headingLine2 { +.line { display: block; min-height: 1.05em; } -.headingGradient { - display: inline; - background: linear-gradient(to right, var(--color-primary-alt), var(--color-gradient-end)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -/* Blinking cursor during typewriter */ -.typingCursor { - display: inline; - color: var(--color-primary-alt); - -webkit-text-fill-color: var(--color-primary-alt); - font-weight: var(--fw-light); - animation: cursorBlink 0.6s step-end infinite; - margin-left: 2px; +/* ─── Terminal cursor ─────────────────────────────────────────────── */ +.cursor { + display: inline-block; + color: var(--color-text); + animation: blink 1s step-end infinite; user-select: none; } -/* ─── Body copy — type.body.200 ───────────────────────────────────── */ -.body { - font-family: var(--font-base); - font-size: var(--fs-body); - font-weight: var(--fw-light); - line-height: 1.6; - color: var(--color-white); - margin: 0; -} - -/* ─── CTA row ─────────────────────────────────────────────────────── */ -.ctaRow { - display: flex; - align-items: center; - gap: 12px; - flex-wrap: wrap; +@keyframes blink { + 0%, 100% { opacity: 1; } + 50% { opacity: 0; } } -/* ─── CTA buttons — type.btn.700 ─────────────────────────────────── */ -.ctaPrimary, -.ctaSecondary { - display: inline-flex; - align-items: center; - justify-content: center; - height: 54px; - padding: 0 20px; - border-radius: 6px; +/* ─── Subheading ──────────────────────────────────────────────────── */ +.subheading { font-family: var(--font-base); - font-size: var(--fs-btn); - font-weight: var(--fw-bold); - text-decoration: none; - cursor: pointer; - white-space: nowrap; - transition: opacity 0.2s ease, transform 0.15s ease; -} - -.ctaPrimary { - min-width: 165px; - background: var(--color-primary); - color: var(--color-white); - border: none; -} - -.ctaPrimary:hover { - opacity: 0.88; - transform: translateY(-1px); - color: var(--color-white); - text-decoration: none; -} - -.ctaSecondary { - gap: 6px; - background: transparent; - color: var(--color-white); - border: 1px solid var(--color-primary); -} - -.ctaSecondary:hover { - opacity: 0.88; - transform: translateY(-1px); - color: var(--color-white); - text-decoration: none; + font-size: clamp(20px, 2.5vw, 24px); + font-weight: var(--fw-regular); + color: var(--color-text-muted); + margin: 0; } -/* ─── Hero image ──────────────────────────────────────────────────── */ -.heroImage { - width: 100%; - max-width: 714px; - height: auto; - object-fit: contain; - pointer-events: none; - display: block; - animation: heroFadeIn 0.8s ease-out 0.15s both; -} +/* ─── Responsive ──────────────────────────────────────────────────── */ +@media (max-width: 1100px) { + .inner { padding: 48px 48px 32px; } -/* ─── Decorative grid dots ────────────────────────────────────────── */ -.gridDotsLg { - position: absolute; - right: 120px; - bottom: 80px; - width: 81px; - height: 81px; - pointer-events: none; - z-index: 1; - opacity: 0.7; + .inner::after { + right: 48px; + left: 48px; + } } -.gridDotsSm { - position: absolute; - right: 490px; - top: 245px; - width: 31px; - height: 31px; - pointer-events: none; - z-index: 1; - opacity: 0.7; -} +@media (max-width: 768px) { + .inner { padding: 40px 28px 28px; } -/* ─── Responsive ──────────────────────────────────────────────────── */ -@media (min-width: 1920px) { - .inner { - max-width: 1660px; - padding: 0 128px; + .inner::after { + right: 28px; + left: 28px; } - - .heroImage { max-width: 620px; } } -@media (max-width: 1680px) { - .heroImage { max-width: 480px; } -} - -@media (max-width: 1440px) { - .inner { padding: 0 96px; } - .heading { font-size: 56px; } - .heroImage { max-width: 420px; } -} +@media (max-width: 480px) { + .inner { padding: 32px 20px 24px; } -@media (max-width: 900px) { - .heroSection { - border-bottom-left-radius: 32px; - border-bottom-right-radius: 32px; + .inner::after { + right: 20px; + left: 20px; } - .inner :global(.row) { - --bs-gutter-x: 0; - margin-left: 0; - margin-right: 0; - } - .inner { padding: 120px 48px 80px; } - .heading { font-size: 52px; } - .gridDotsLg, .gridDotsSm { display: none; } -} - -@media (max-width: 600px) { - .inner { padding: 100px 24px 60px; } - .heading { font-size: 40px; } - .body { font-size: var(--fs-sm); } - .ctaRow { flex-direction: column; align-items: stretch; } - .ctaPrimary, .ctaSecondary { justify-content: center; width: 100%; } } diff --git a/src/components/ProductHighlightsSection/index.js b/src/components/ProductHighlightsSection/index.js new file mode 100644 index 0000000..e051149 --- /dev/null +++ b/src/components/ProductHighlightsSection/index.js @@ -0,0 +1,58 @@ +import React from 'react'; +import styles from './styles.module.css'; + +const highlights = [ + { + icon: ( + + ), + title: 'Open Source', + description: 'MIT License', + }, + { + icon: ( + + ), + title: 'Self-Hosted', + description: 'Full control. No vendor lock-in.', + }, + { + icon: ( + + ), + title: 'Production Ready', + description: 'Battle-tested. Built for reliability.', + }, +]; + +export default function ProductHighlightsSection() { + return ( +
+
+
+ {highlights.map((h, i) => ( + +
+
{h.icon}
+
+
{h.title}
+
{h.description}
+
+
+ {i < highlights.length - 1 &&
} + + ))} +
+
+
+ ); +} diff --git a/src/components/ProductHighlightsSection/styles.module.css b/src/components/ProductHighlightsSection/styles.module.css new file mode 100644 index 0000000..4af81d0 --- /dev/null +++ b/src/components/ProductHighlightsSection/styles.module.css @@ -0,0 +1,108 @@ +/* ─── Section ─────────────────────────────────────────────────────── */ +.section { + background: + linear-gradient(to right, transparent 10%, var(--color-border) 10%, var(--color-border) 90%, transparent 90%) no-repeat 0 0 / 100% 1px, + linear-gradient(to right, transparent 10%, var(--color-border) 10%, var(--color-border) 90%, transparent 90%) no-repeat 0 100% / 100% 1px, + var(--color-bg); + padding: var(--section-pt) 0 var(--section-pb); +} + +.inner { + max-width: 1200px; + margin: 0 auto; + padding: 0 80px; +} + +/* ─── Row ─────────────────────────────────────────────────────────── */ +.row { + display: flex; + align-items: center; + justify-content: center; + gap: 0; +} + +/* ─── Item ────────────────────────────────────────────────────────── */ +.item { + display: flex; + align-items: center; + gap: 20px; + flex: 1; + justify-content: center; + padding: 0 40px; +} + +/* ─── Icon ────────────────────────────────────────────────────────── */ +.icon { + color: var(--color-primary); + flex-shrink: 0; +} + +/* ─── Text ────────────────────────────────────────────────────────── */ +.text { + display: flex; + flex-direction: column; + gap: 4px; +} + +.title { + font-family: var(--font-base); + font-size: var(--fs-body-lg); + font-weight: var(--fw-bold); + line-height: 1.1; + color: var(--color-text); +} + +.description { + font-family: var(--font-base); + font-size: var(--fs-sm); + font-weight: var(--fw-regular); + color: var(--color-text-muted); +} + +/* ─── Divider ─────────────────────────────────────────────────────── */ +.divider { + width: 1px; + height: 60px; + background: var(--color-border); + flex-shrink: 0; +} + +/* ─── Responsive ──────────────────────────────────────────────────── */ +@media (max-width: 900px) { + .inner { padding: 0 48px; } + .row { + flex-direction: column; + align-items: center; + gap: 28px; + } + .divider { + width: 88px; + height: 1px; + } + .item { + display: grid; + grid-template-columns: 64px minmax(0, 1fr); + align-items: center; + gap: 18px; + width: min(100%, 420px); + padding: 0; + justify-content: initial; + } + .icon { + justify-self: center; + } +} + +@media (max-width: 600px) { + .inner { padding: 0 20px; } + .item { + grid-template-columns: 56px minmax(0, 1fr); + gap: 14px; + width: min(100%, 360px); + } + .icon svg { width: 40px; height: 40px; } +} + +@media (max-width: 480px) { + .inner { padding: 0 16px; } +} diff --git a/src/components/SideNavbar/index.js b/src/components/SideNavbar/index.js new file mode 100644 index 0000000..0ef1634 --- /dev/null +++ b/src/components/SideNavbar/index.js @@ -0,0 +1,94 @@ +import React, { useState, useEffect } from 'react'; +import Link from '@docusaurus/Link'; +import styles from './styles.module.css'; + +function DocsIcon() { + return ( + + ); +} + +function GitHubIcon() { + return ( + + ); +} + +export default function SideNavbar() { + const [visible, setVisible] = useState(false); + + useEffect(() => { + // Show side nav after top navbar (72px) has fully left the viewport + const THRESHOLD = 80; + let ticking = false; + + const onScroll = () => { + if (!ticking) { + requestAnimationFrame(() => { + setVisible(window.scrollY > THRESHOLD); + ticking = false; + }); + ticking = true; + } + }; + + window.addEventListener('scroll', onScroll, { passive: true }); + return () => window.removeEventListener('scroll', onScroll); + }, []); + + return ( + + ); +} diff --git a/src/components/SideNavbar/styles.module.css b/src/components/SideNavbar/styles.module.css new file mode 100644 index 0000000..b118ccc --- /dev/null +++ b/src/components/SideNavbar/styles.module.css @@ -0,0 +1,120 @@ +/* ─── Sidebar shell ────────────────────────────────────────────────── */ +.sidebar { + --font-base: 'Quantico', sans-serif; + --color-bg: #ffffff; + --color-surface: #f9f9f9; + --color-text: #111111; + --color-border: #e0e0e0; + --color-primary: #ff5722; + position: fixed; + left: 0; + top: 0; + height: 100vh; + width: 64px; + z-index: 190; + background: var(--color-bg); + border-right: 1px solid var(--color-border); + + display: flex; + flex-direction: column; + align-items: center; + padding: 28px 0; + gap: 20px; + + /* Hidden by default — slides in from left */ + transform: translateX(-100%); + opacity: 0; + transition: + transform 0.38s cubic-bezier(0.34, 1.46, 0.64, 1), + opacity 0.22s ease; + +} + +.visible { + transform: translateX(0); + opacity: 1; +} + +/* ─── Logo ─────────────────────────────────────────────────────────── */ +.logoLink { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: 8px; + transition: opacity 0.15s ease; + text-decoration: none; +} + +.logoLink:hover { + opacity: 0.72; + text-decoration: none; +} + +.logoImg { + display: block; +} + +/* ─── Divider ──────────────────────────────────────────────────────── */ +.divider { + width: 28px; + height: 1px; + background: var(--color-border); + flex-shrink: 0; +} + +/* ─── Icon links ───────────────────────────────────────────────────── */ +.iconLink { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: 8px; + color: hsl(0, 0%, 55%); + text-decoration: none; + transition: color 0.15s ease, background 0.15s ease; +} + +.iconLink:hover { + color: var(--color-text); + background: var(--color-surface); + text-decoration: none; +} + +/* ─── Demo button ──────────────────────────────────────────────────── */ +.demoBtn { + display: flex; + align-items: center; + justify-content: center; + width: 44px; + height: 32px; + border: 1px solid var(--color-border); + border-radius: 4px; + text-decoration: none; + transition: border-color 0.15s ease, color 0.15s ease; +} + +.demoBtn:hover { + border-color: var(--color-primary); + text-decoration: none; +} + +.demoBtn:hover .demoBtnText { + color: var(--color-primary); +} + +.demoBtnText { + font-family: var(--font-base); + font-size: 10px; + font-weight: 600; + letter-spacing: 0.8px; + color: hsl(0, 0%, 48%); + transition: color 0.15s ease; +} + +/* ─── Mobile: never show ───────────────────────────────────────────── */ +@media (max-width: 768px) { + .sidebar { display: none; } +} diff --git a/src/components/SocialProofSection/index.js b/src/components/SocialProofSection/index.js new file mode 100644 index 0000000..606542a --- /dev/null +++ b/src/components/SocialProofSection/index.js @@ -0,0 +1,114 @@ +import React from 'react'; +import styles from './styles.module.css'; + +function CalendarWithClockIcon() { + return ( + + ); +} + +function StopwatchIcon() { + return ( + + ); +} + +export default function SocialProofSection() { + return ( +
+
+
+ + {/* Left — text */} +
+

1 Month of Infrastructure Work

+

10 Minutes in Autobase

+ +
+ + {/* Right — visual */} +
+ +
+ + 1 MONTH +
+ + {/* Arrow */} + + +
+ +
+ + 10 MINUTES +
+ +
+
+
+
+ ); +} diff --git a/src/components/SocialProofSection/styles.module.css b/src/components/SocialProofSection/styles.module.css new file mode 100644 index 0000000..2cd8d02 --- /dev/null +++ b/src/components/SocialProofSection/styles.module.css @@ -0,0 +1,120 @@ +/* ─── Section ─────────────────────────────────────────────────────── */ +.section { + background: var(--color-bg); + padding: 0 0 16px; + margin-bottom: 0; +} + +.inner { + max-width: 1200px; + margin: 0 auto; + padding: 0 80px; +} + +/* ─── Banner card ─────────────────────────────────────────────────── */ +.banner { + display: flex; + align-items: center; + justify-content: space-between; + gap: 60px; + padding: 40px 52px; + border: 1px solid var(--color-border); + border-radius: 2px; + background: var(--color-bg); + box-shadow: 8px 8px 0 rgba(0, 0, 0, 0.05); + transition: + border-color 0.16s ease, + box-shadow 0.16s ease; +} + +.banner:hover { + border-color: var(--color-primary); + box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.1); +} + +/* ─── Text block ──────────────────────────────────────────────────── */ +.text { + display: flex; + flex-direction: column; + gap: 6px; +} + +.before { + font-family: var(--font-base); + font-size: clamp(22px, 2.5vw, 30px); + font-weight: var(--fw-bold); + color: var(--color-text); + margin: 0; + line-height: 1.2; +} + +.after { + font-family: var(--font-base); + font-size: clamp(22px, 2.5vw, 30px); + font-weight: var(--fw-black); + color: var(--color-primary); + margin: 0; + line-height: 1.2; +} + +.underbar { + display: block; + width: 40px; + height: 3px; + background: var(--color-primary); + border-radius: 2px; + margin-top: 10px; +} + +/* ─── Visual block ────────────────────────────────────────────────── */ +.visual { + display: flex; + align-items: center; + gap: 28px; + flex-shrink: 0; +} + +.timeBlock { + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; +} + +.timeLabel { + font-family: var(--font-base); + font-size: 12px; + font-weight: var(--fw-bold); + color: var(--color-text); + letter-spacing: 1.2px; +} + +.accentLabel { + color: var(--color-primary); +} + +.arrow { + flex-shrink: 0; +} + +.divider { + width: 1px; + height: 80px; + background: var(--color-border); + flex-shrink: 0; +} + +/* ─── Responsive ──────────────────────────────────────────────────── */ +@media (max-width: 900px) { + .inner { padding: 0 48px; } + .banner { flex-direction: column; gap: 32px; text-align: center; padding: 36px 40px; } + .underbar { margin: 10px auto 0; } +} + +@media (max-width: 600px) { + .inner { padding: 0 20px; } + .banner { flex-direction: column; gap: 24px; padding: 28px 24px; } + .visual { gap: 16px; } + .divider { display: none; } + .before, .after { font-size: clamp(18px, 5vw, 24px); } +} diff --git a/src/components/TrustedByCarousel/index.js b/src/components/TrustedByCarousel/index.js new file mode 100644 index 0000000..a54f67a --- /dev/null +++ b/src/components/TrustedByCarousel/index.js @@ -0,0 +1,59 @@ +import React from 'react'; +import styles from './styles.module.css'; + +const sponsors = [ + { name: 'Axiom', img: '/img/sponsors/axiom.png', href: 'https://axiom.trade' }, + { name: 'Awarebuildings', img: '/img/sponsors/awarebuildings.png', href: 'https://www.awarebuildings.com' }, + { name: 'Antistock', img: '/img/sponsors/antistock.png', href: 'https://antistock.io' }, + { name: 'Codefloe', img: '/img/sponsors/codefloe.png', href: 'https://codefloe.com' }, + { name: 'Edclub', img: '/img/sponsors/edclub.png', href: 'https://www.edclub.com' }, + { name: 'Fera', img: '/img/sponsors/fera.png', href: 'https://fera.ai' }, + { name: 'GS Labs', img: '/img/sponsors/gs-labs.png', href: 'https://gs-labs.ru' }, + { name: 'New Byte', img: '/img/sponsors/newbyte.png', href: 'https://newbyte.net.br' }, + { name: 'Optiwise', img: '/img/sponsors/optiwise.png', href: 'https://optiwise.nl' }, + { name: 'Postgres.AI', img: '/img/sponsors/postgresai.png', href: 'https://postgres.ai' }, + { name: 'Staffery', img: '/img/sponsors/staffery.png', href: 'https://www.staffery.com' }, + { name: 'Toncarton', img: '/img/sponsors/toncarton.png', href: 'https://www.toncarton.com' }, + { name: 'We-Manage', img: '/img/sponsors/we-manage.png', href: 'https://we-manage.de' }, +]; + +function LogoSet({ hidden = false }) { + return ( +
+ {sponsors.map((sponsor) => ( + + {hidden + + ))} +
+ ); +} + +export default function TrustedByCarousel() { + return ( +
+
+ // + Trusted by teams running Autobase in production +
+
+
+ +
+
+
+ ); +} diff --git a/src/components/TrustedByCarousel/styles.module.css b/src/components/TrustedByCarousel/styles.module.css new file mode 100644 index 0000000..f2c82f5 --- /dev/null +++ b/src/components/TrustedByCarousel/styles.module.css @@ -0,0 +1,135 @@ +.trustedBy { + width: 100%; + max-width: 920px; + margin-top: 2rem; + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + overflow: hidden; +} + +.label { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + margin-bottom: 10px; + font-family: var(--font-base); + font-size: clamp(12px, 1vw, 14px); + color: var(--color-text-muted); + text-transform: uppercase; +} + +.prompt { + color: var(--color-primary); +} + +.strip { + position: relative; + width: 100%; + max-width: 100%; + overflow: hidden; +} + +.strip::before, +.strip::after { + content: ''; + position: absolute; + top: 0; + bottom: 0; + z-index: 1; + width: 64px; + pointer-events: none; +} + +.strip::before { + left: 0; + background: linear-gradient(to right, var(--color-bg), transparent); +} + +.strip::after { + right: 0; + background: linear-gradient(to left, var(--color-bg), transparent); +} + +.track { + display: flex; + width: max-content; + animation: marquee 48s linear infinite; +} + +.strip:hover .track { + animation-play-state: paused; +} + +.logoSet { + display: flex; + align-items: center; + flex-shrink: 0; +} + +.logoLink { + display: flex; + align-items: center; + justify-content: center; + width: 160px; + height: 58px; + padding: 12px 26px; + flex-shrink: 0; +} + +.logoImg { + display: block; + max-width: 100%; + max-height: 34px; + width: auto; + height: auto; + object-fit: contain; + filter: grayscale(100%) contrast(115%); + opacity: 0.68; + transition: filter 0.15s ease, opacity 0.15s ease; +} + +.logoLink:hover .logoImg { + filter: grayscale(40%) contrast(110%); + opacity: 0.9; +} + +@keyframes marquee { + from { transform: translateX(0); } + to { transform: translateX(-50%); } +} + +@media (max-width: 768px) { + .trustedBy { + margin-top: 4px; + } + + .logoLink { + width: 132px; + height: 52px; + padding: 12px 22px; + } + + .logoImg { + max-height: 30px; + } +} + +@media (max-width: 480px) { + .strip::before, + .strip::after { + width: 32px; + } + + .logoLink { + width: 118px; + } +} + +@media (prefers-reduced-motion: reduce) { + .track { + animation: none; + } +} diff --git a/src/components/ValuePropsSection/index.js b/src/components/ValuePropsSection/index.js new file mode 100644 index 0000000..f4877d0 --- /dev/null +++ b/src/components/ValuePropsSection/index.js @@ -0,0 +1,85 @@ +import React, { useRef, useEffect } from 'react'; +import styles from './styles.module.css'; + +const props = [ + { + icon: ( + + ), + title: 'Your Infrastructure', + description: 'Deploy anywhere. Stay in control.', + }, + { + icon: ( + + ), + title: 'Your Data', + description: 'Your data never leaves your infrastructure.', + }, + { + icon: ( + + ), + title: 'Your Security', + description: 'Your network. Your rules.', + }, +]; + +export default function ValuePropsSection() { + const gridRef = useRef(null); + + useEffect(() => { + let ctx; + import('gsap').then(({ gsap }) => + import('gsap/ScrollTrigger').then(({ ScrollTrigger }) => { + gsap.registerPlugin(ScrollTrigger); + ctx = gsap.context(() => { + gsap.fromTo( + gridRef.current?.querySelectorAll(`.${styles.card}`), + { opacity: 0, scale: 0.6, y: -10 }, + { + opacity: 1, + scale: 1, + y: 0, + duration: 0.55, + ease: 'back.out(1.4)', + stagger: 0.12, + scrollTrigger: { + trigger: gridRef.current, + start: 'top 85%', + once: true, + }, + } + ); + }); + }) + ); + return () => ctx?.revert(); + }, []); + + return ( +
+
+
+ {props.map((p) => ( +
+
{p.icon}
+

{p.title}

+

{p.description}

+
+ ))} +
+
+
+ ); +} diff --git a/src/components/ValuePropsSection/styles.module.css b/src/components/ValuePropsSection/styles.module.css new file mode 100644 index 0000000..cb32821 --- /dev/null +++ b/src/components/ValuePropsSection/styles.module.css @@ -0,0 +1,92 @@ +/* ─── Section ─────────────────────────────────────────────────────── */ +.section { + background: var(--color-bg); + padding: var(--section-pt) 0 var(--section-pb); +} + +.inner { + max-width: 1200px; + margin: 0 auto; + padding: 0 80px; +} + +/* ─── Grid ────────────────────────────────────────────────────────── */ +.grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px; +} + +/* ─── Card ────────────────────────────────────────────────────────── */ +.card { + display: flex; + flex-direction: column; + gap: 16px; + padding: 32px; + border: 1px solid var(--color-border); + border-radius: 2px; + background: var(--color-bg); + box-shadow: 8px 8px 0 rgba(0, 0, 0, 0.05); + transition: + border-color 0.16s ease, + box-shadow 0.16s ease, + color 0.16s ease; + opacity: 0; + will-change: transform, opacity; +} + +.card:hover { + border-color: var(--color-primary); + box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.1); +} + +/* ─── Icon ────────────────────────────────────────────────────────── */ +.icon { + color: var(--color-text); + transition: color 0.16s ease; +} + +.card:hover .icon { + color: var(--color-primary); +} + +/* ─── Title ───────────────────────────────────────────────────────── */ +.title { + font-family: var(--font-base); + font-size: var(--fs-body-lg); + font-weight: var(--fw-bold); + line-height: 1.1; + color: var(--color-text); + margin: 0; + transition: color 0.16s ease; +} + +.card:hover .title { + color: var(--color-primary); +} + +/* ─── Description ─────────────────────────────────────────────────── */ +.description { + font-family: var(--font-base); + font-size: var(--fs-sm); + font-weight: var(--fw-regular); + color: var(--color-text-muted); + line-height: 1.6; + margin: 0; +} + +/* ─── Responsive ──────────────────────────────────────────────────── */ +@media (max-width: 900px) { + .inner { padding: 0 48px; } + .grid { grid-template-columns: 1fr 1fr; gap: 16px; } +} + +@media (max-width: 600px) { + .inner { padding: 0 20px; } + .grid { grid-template-columns: 1fr; gap: 12px; } + .card { padding: 24px 20px; gap: 12px; } +} + +@media (max-width: 480px) { + .inner { padding: 0 16px; } +} diff --git a/src/css/custom.css b/src/css/custom.css index b269b16..00607fe 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -1,4 +1,5 @@ @import url('https://fonts.googleapis.com/css2?family=Zalando+Sans+SemiExpanded:ital,wght@0,200..900;1,200..900&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Quantico:ital,wght@0,400;0,700;1,400;1,700&display=swap'); @import 'bootstrap/dist/css/bootstrap-grid.min.css'; /** @@ -100,8 +101,8 @@ html.docs-wrapper[data-theme='light'] .theme-doc-toc-desktop { } .landingPage { - --ifm-background-color: #ffffff !important; - --ifm-background-surface-color: #ffffff !important; + --ifm-background-color: #F9FAFB !important; + --ifm-background-surface-color: #F9FAFB !important; --ifm-font-color-base: #000000; --ifm-heading-color: #000000; --ifm-color-primary: #0366d6; @@ -112,15 +113,77 @@ html.docs-wrapper[data-theme='light'] .theme-doc-toc-desktop { --ifm-color-primary-lighter: #69b0e3; --ifm-color-primary-lightest: #a8d1ef; --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); - background-color: #ffffff; - color: #000000; + + --font-base: 'Quantico', sans-serif; + --fw-light: 200; + --fw-regular: 400; + --fw-medium: 500; + --fw-semibold: 600; + --fw-bold: 700; + --fw-black: 900; + + --fs-hero: clamp(48px, 6vw, 86px); + --fs-h2: clamp(32px, 4vw, 58px); + --fs-h3: clamp(22px, 2.8vw, 38px); + --fs-navbar: clamp(18px, 2.2vw, 33px); + --fs-body-lg: clamp(18px, 2vw, 29px); + --fs-body: clamp(16px, 1.7vw, 24px); + --fs-btn: clamp(14px, 1.4vw, 22px); + --fs-sm: clamp(13px, 1.2vw, 19px); + + --color-primary: #ff5722; + --color-primary-alt: #fc6902; + --color-gradient-end: #be987d; + --color-white: #ffffff; + --color-black: #000000; + --color-muted: #c7c7c7; + --color-bg: #F9FAFB; + --color-bg-alt: #f5f5f5; + --color-surface: #f9f9f9; + --color-text: #111111; + --color-text-muted: #555555; + --color-border: #e0e0e0; + + --section-pt: 64px; + --section-pb: 64px; + + background-color: var(--color-bg); + color: #111111; + font-family: var(--font-base); +} + +.landingPage h1, +.landingPage h2, +.landingPage h3, +.landingPage h4, +.landingPage h5, +.landingPage h6 { + font-family: var(--font-base); + font-weight: 700; +} + +.landingPage p { + font-family: var(--font-base); + font-weight: var(--fw-light); } .landingPage main { - background-color: #ffffff; + background-color: var(--color-bg); +} + +@media (max-width: 900px) { + .landingPage { + --section-pt: 48px; + --section-pb: 48px; + } } @media (max-width: 768px) { + .landingPage { + --section-pt: 36px; + --section-pb: 36px; + } + html:has(.landingPage), body:has(.landingPage) { overflow-x: hidden; diff --git a/src/pages/index.js b/src/pages/index.js index 95a3244..354ee73 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -1,46 +1,38 @@ import React, { useEffect } from 'react'; import Layout from '@theme/Layout'; import HeroSection from '@site/src/components/HeroSection'; -import AboutSection from '@site/src/components/AboutSection'; -import ProblemSection from '@site/src/components/ProblemSection'; -import WhatIsAutobaseSection from '@site/src/components/WhatIsAutobaseSection'; -import ExplainSection from '@site/src/components/ExplainSection'; -import HowItWorksSection from '@site/src/components/HowItWorksSection'; -import FeaturedSection from '@site/src/components/FeaturedSection'; -import CloudProviders from '@site/src/components/CloudProviders'; -import VideoSection from '@site/src/components/VideoSection'; -import WhatYouGetSection from '@site/src/components/WhatYouGetSection'; -import PricingSection from '@site/src/components/PricingSection'; -import ComparisonSection from '@site/src/components/ComparisonSection'; -import Sponsors from '@site/src/components/Sponsors'; +import ArchDiagramSection from '@site/src/components/ArchDiagramSection'; +import ValuePropsSection from '@site/src/components/ValuePropsSection'; +import ProductHighlightsSection from '@site/src/components/ProductHighlightsSection'; +import CLISection from '@site/src/components/CLISection'; +import ContactSection from '@site/src/components/ContactSection'; +import SocialProofSection from '@site/src/components/SocialProofSection'; -function HomepageContent() { +export default function Home() { // GSAP scroll reveal — blur + fade from below, fires once per section useEffect(() => { - if (typeof window !== 'undefined' && window.matchMedia('(max-width: 768px)').matches) { - return undefined; - } - let ctx; Promise.all([import('gsap'), import('gsap/ScrollTrigger')]).then( ([{ gsap }, { ScrollTrigger }]) => { gsap.registerPlugin(ScrollTrigger); ctx = gsap.context(() => { document.querySelectorAll('main section').forEach((section) => { - gsap.from(section, { - y: 48, - opacity: 0, - duration: 1.0, - ease: 'expo.out', - immediateRender: true, - scrollTrigger: { - trigger: section, - start: 'top 88%', - once: true, - invalidateOnRefresh: true, - toggleActions: 'play none none none', - }, - }); + gsap.fromTo( + section, + { y: 32, opacity: 0, filter: 'blur(6px)' }, + { + y: 0, + opacity: 1, + filter: 'blur(0px)', + duration: 0.85, + ease: 'expo.out', + scrollTrigger: { + trigger: section, + start: 'top 90%', + once: true, + }, + } + ); }); }); } @@ -48,34 +40,20 @@ function HomepageContent() { return () => ctx?.revert(); }, []); - return ( - <> - -
- {/* */} - {/* */} - - - - - - - - - {/* */} - -
- - ); -} - -export default function Home() { return ( - + +
+ + + + + + +
); } diff --git a/src/pages/index.module.css b/src/pages/index.module.css index e635b07..71c44aa 100644 --- a/src/pages/index.module.css +++ b/src/pages/index.module.css @@ -67,7 +67,7 @@ } /* Adaptive style for mobile devices */ -@media (max-width: 1440px) { +@media (max-width: 1200px) { .heroBanner_description, .heroLead, .heroBenefits { diff --git a/src/theme/Footer/index.js b/src/theme/Footer/index.js index 489b131..b7dff0d 100644 --- a/src/theme/Footer/index.js +++ b/src/theme/Footer/index.js @@ -1,26 +1,9 @@ import React from 'react'; import useBaseUrl from '@docusaurus/useBaseUrl'; import { useLocation } from '@docusaurus/router'; -import Link from '@docusaurus/Link'; import OriginalFooter from '@theme-original/Footer'; -import clsx from 'clsx'; import styles from './styles.module.css'; -const navGroups = [ - { - title: 'Docs', - links: [{ label: 'Introduction', href: '/docs/' }], - }, - { - title: 'Support', - links: [{ label: 'Support Packages', href: '/docs/support' }], - }, - { - title: 'Source code', - links: [{ label: 'GitHub', href: 'https://github.com/autobase-tech/autobase', external: true }], - }, -]; - function normalizePath(pathname) { if (!pathname || pathname === '/') { return '/'; @@ -39,125 +22,26 @@ export default function Footer(props) { } return ( -
-
- - {/* Decorative vector — absolutely positioned, clips on right edge */} - - -
- - {/* ── Hero area: hero text + CTAs ── */} -
-
- - {/* type.hero.900 */} -

- Run PostgreSQL
- as a system. -

+
+
- {/* type.body-lg.500 */} -

Not as a set of servers.

+
- {/* CTAs */} -
- - Start a Free trial now - - - Chat on Telegram - - -
- -
-
- - {/* ── Footer bottom: nav + social + copyright ── */} -
- - {/* Nav groups + social */} -
- {navGroups.map((group) => ( -
-
- {group.title} - {group.links.map((link) => - link.external ? ( - - {link.label} - - ) : ( - - {link.label} - - ) - )} -
-
- ))} +
+ + Autobase +
- {/* Social links */} - -
+

+ Copyright © 2019 - 2026. All rights reserved. +

- {/* Copyright */} -
-
- - autobase -
-

- Copyright © 2019 - 2026. All rights reserved.
-

-

- Payments are processed by NovaBridge Tech OÜ, which acts as the authorized payment and billing partner for Autobase.
- NovaBridge Tech OÜ. Reg. nr 17390133 · Võru tn 11, Lasnamäe linnaosa, Tallinn 13612, Harjumaa, Estonia -

-
+

+ Payments are processed by NovaBridge Tech OÜ, which acts as the authorized payment and billing partner for Autobase.
+ NovaBridge Tech OÜ. Reg. nr 17390133 · Võru tn 11, Lasnamäe linnaosa, Tallinn 13612, Harjumaa, Estonia +

-
-
-
-
+ + ); } diff --git a/src/theme/Footer/styles.module.css b/src/theme/Footer/styles.module.css index 31eb8c6..deb0bc0 100644 --- a/src/theme/Footer/styles.module.css +++ b/src/theme/Footer/styles.module.css @@ -1,251 +1,76 @@ -/* ─── Footer wrapper ─────────────────────────────────────────────── */ -.footerSurface { - background-color: #ffffff; -} - +/* ─── Footer ──────────────────────────────────────────────────────── */ .footer { - display: flex; - flex-direction: column; - position: relative; - overflow: hidden; - border-top-left-radius: 48px; - border-top-right-radius: 48px; - background-color: #f7f5f3; - min-height: 100vh; + --font-base: 'Quantico', sans-serif; + --fw-regular: 400; + --fs-sm: clamp(13px, 1.2vw, 19px); + --color-bg: #F9FAFB; + --color-text: #111111; + --color-text-muted: #555555; + --color-border: #e0e0e0; + background: var(--color-bg); } -/* ─── Inner — constrained width, full height ──────────────────────── */ -.inner { - flex: 1; - display: flex; - flex-direction: column; - max-width: 1540px; +.divider { width: 100%; - margin: 0 auto; - padding: 0 160px; - position: relative; - z-index: 1; -} - -/* ─── Decorative vector — right-anchored, bleeds off edge ─────────── */ -.vectorLine { - position: absolute; - right: -100px; - top: 36px; - width: 820px; - height: 717px; - pointer-events: none; - z-index: 0; -} - -/* ─── Hero area — fills remaining height, centers content ────────── */ -.heroArea { - flex: 1; - display: flex; - align-items: center; - padding: 80px 0; -} - -.heroContent { - display: flex; - flex-direction: column; - gap: 25px; - max-width: 535px; -} - -/* type.hero.900 */ -.heroHeading { - font-family: var(--font-base); - font-size: var(--fs-hero); - font-weight: var(--fw-black); - color: var(--color-black); - line-height: 1.05; + height: 1px; + background: var(--color-border); margin: 0; } -/* type.body-lg.500 */ -.heroSubtext { - font-family: var(--font-base); - font-size: var(--fs-body-lg); - font-weight: var(--fw-medium); - color: var(--color-black); - margin: 0; -} - -.orange { color: var(--color-primary); } - -/* ─── CTAs ───────────────────────────────────────────────────────── */ -.ctaRow { - display: flex; - align-items: center; - gap: 12px; - flex-wrap: wrap; -} - -.ctaPrimary { - display: inline-flex; - align-items: center; - justify-content: center; - height: 54px; - padding: 0 28px; - background: var(--color-primary); - color: var(--color-white); - border-radius: 6px; - font-family: var(--font-base); - font-size: var(--fs-btn); - font-weight: var(--fw-bold); - text-decoration: none; - transition: opacity 0.15s ease; -} - -.ctaPrimary:hover { - color: var(--color-white); - opacity: 0.9; - text-decoration: none; -} - -.ctaSecondary { - display: inline-flex; - align-items: center; - gap: 6px; - height: 54px; - padding: 0 20px; - border: 1.5px solid var(--color-primary); - color: var(--color-black); - border-radius: 6px; - font-family: var(--font-base); - font-size: var(--fs-btn); - font-weight: var(--fw-bold); - text-decoration: none; - transition: opacity 0.15s ease; -} - -.ctaSecondary:hover { - color: var(--color-black); - opacity: 0.85; - text-decoration: none; -} - -/* ─── Footer bottom ──────────────────────────────────────────────── */ -.footerBottom { - padding: 60px 0 44px; - border-top: 1px solid rgba(0, 0, 0, 0.08); -} - -.navRow { - margin-bottom: 40px; -} - -/* ─── Nav groups ─────────────────────────────────────────────────── */ -.navGroup { - display: flex; - flex-direction: column; - gap: 10px; - margin-right: 80px; - margin-bottom: 24px; -} - -/* type.body-lg.600 */ -.navTitle { - font-family: var(--font-base); - font-size: var(--fs-body-lg); - font-weight: var(--fw-semibold); - color: var(--color-black); -} - -/* type.caption.400 */ -.navLink { - font-family: var(--font-base); - font-size: var(--fs-sm); - font-weight: var(--fw-regular); - color: rgba(0, 0, 0, 0.6); - text-decoration: none; - transition: color 0.15s ease; -} - -.navLink:hover { color: var(--color-black); text-decoration: none; } - -/* ─── Social links ───────────────────────────────────────────────── */ -.socialGroup { - display: flex; - flex-direction: column; - gap: 10px; - margin-bottom: 24px; -} - -.socialItem { - display: flex; - align-items: center; - gap: 10px; - font-family: var(--font-base); - font-size: var(--fs-sm); - font-weight: var(--fw-regular); - color: rgba(0, 0, 0, 0.6); - text-decoration: none; - transition: color 0.15s ease; -} - -.socialItem:hover { color: var(--color-black); text-decoration: none; } - -/* ─── Copyright row ──────────────────────────────────────────────── */ -.copyrightRow { +.inner { + max-width: 1200px; + margin: 0 auto; + padding: 48px 80px 56px; display: flex; flex-direction: column; - gap: 10px; + gap: 20px; } +/* ─── Logo ────────────────────────────────────────────────────────── */ .logoMark { display: flex; align-items: center; gap: 10px; + margin-bottom: 4px; } -/* type.navbar.400 */ .logoText { font-family: var(--font-base); - font-size: var(--fs-navbar); + font-size: 20px; font-weight: var(--fw-regular); - color: var(--color-black); + color: var(--color-text); + line-height: 1; } -/* type.caption.400 */ +/* ─── Copyright ───────────────────────────────────────────────────── */ .copyright { font-family: var(--font-base); font-size: var(--fs-sm); font-weight: var(--fw-regular); - color: rgba(0, 0, 0, 0.6); + color: var(--color-text); margin: 0; + line-height: 1.6; } -.billingInfo { +/* ─── Legal text ──────────────────────────────────────────────────── */ +.legal { font-family: var(--font-base); - font-size: 14px; + font-size: clamp(12px, 1vw, 16px); font-weight: var(--fw-regular); - color: rgba(0, 0, 0, 0.6); - line-height: 1.45; + color: var(--color-text-muted); margin: 0; + line-height: 1.7; } -/* ─── Responsive ─────────────────────────────────────────────────── */ -@media (min-width: 1920px) { - .inner { - max-width: 1700px; - padding: 0 112px; - } -} - -@media (max-width: 1440px) { - .inner { padding: 0 96px; } +/* ─── Responsive ──────────────────────────────────────────────────── */ +@media (max-width: 900px) { + .inner { padding: 40px 48px 48px; } } -@media (max-width: 900px) { - .inner { padding: 0 48px; } - .heroHeading { font-size: var(--fs-h2); } +@media (max-width: 600px) { + .inner { padding: 32px 20px 40px; } } -@media (max-width: 768px) { - .inner { padding: 0 24px; } - .heroHeading { font-size: var(--fs-h3); } - .vectorLine { display: none; } - .navGroup { margin-right: 0; } +@media (max-width: 480px) { + .inner { padding: 28px 16px 36px; } } diff --git a/src/theme/Navbar/index.js b/src/theme/Navbar/index.js index 1145411..b4f5bfd 100644 --- a/src/theme/Navbar/index.js +++ b/src/theme/Navbar/index.js @@ -1,13 +1,17 @@ import React from 'react'; import useBaseUrl from '@docusaurus/useBaseUrl'; import { useLocation } from '@docusaurus/router'; -import { useThemeConfig } from '@docusaurus/theme-common'; -import { useHideableNavbar } from '@docusaurus/theme-common/internal'; import Link from '@docusaurus/Link'; import OriginalNavbar from '@theme-original/Navbar'; import clsx from 'clsx'; import styles from './styles.module.css'; +const navLinks = [ + { label: '/docs', to: '/docs' }, + { label: '/github', href: 'https://github.com/autobase-tech/autobase' }, + { label: '/demo', href: 'https://demo.autobase.tech' }, +]; + function normalizePath(pathname) { if (!pathname || pathname === '/') { return '/'; @@ -18,14 +22,8 @@ function normalizePath(pathname) { export default function Navbar(props) { const { pathname } = useLocation(); - const { - navbar: { hideOnScroll }, - } = useThemeConfig(); const homePath = useBaseUrl('/'); const isHomepage = normalizePath(pathname) === normalizePath(homePath); - const { navbarRef, isNavbarVisible } = useHideableNavbar( - isHomepage && hideOnScroll - ); if (!isHomepage) { return ( @@ -36,15 +34,7 @@ export default function Navbar(props) { } return ( -