This is an automated email from the ASF dual-hosted git repository. visoar pushed a commit to branch clean-rebuild in repository https://gitbox.apache.org/repos/asf/bifromq-sites.git
commit c3d2e16a5b2901be48412b54933d5f43010ca592 Author: Visoar <[email protected]> AuthorDate: Mon Jan 12 13:31:36 2026 +0800 style: complete UI/UX overhaul with Bifrost design system --- src/components/HomepageFeatures/index.tsx | 96 ---- src/components/HomepageFeatures/styles.module.css | 24 - src/css/custom.css | 547 ++++++++++++++++++++-- src/pages/index.module.css | 501 +++++++++++++++++++- src/pages/index.tsx | 237 ++++++++-- static/img/logo.svg | 2 +- 6 files changed, 1202 insertions(+), 205 deletions(-) diff --git a/src/components/HomepageFeatures/index.tsx b/src/components/HomepageFeatures/index.tsx deleted file mode 100644 index 1e6c3766..00000000 --- a/src/components/HomepageFeatures/index.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import type {ReactNode} from 'react'; -import clsx from 'clsx'; -import Heading from '@theme/Heading'; -import styles from './styles.module.css'; - -type FeatureItem = { - title: string; - kicker: string; - Svg: React.ComponentType<React.ComponentProps<'svg'>>; - description: ReactNode; -}; - -const FeatureList: FeatureItem[] = [ - { - title: '100% MQTT Support', - kicker: 'MQTT 3.1-5.0', - Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, - description: ( - <> - Supports MQTT 3.1, 3.1.1, and 5.0 over TCP, TLS, WS, and WSS with full - protocol feature coverage. - </> - ), - }, - { - title: 'Built-in Storage Engine', - kicker: 'Full compliance · Zero deps', - Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, - description: ( - <> - Optimized for critical load targeting, no third-party middleware - dependencies. Deploy anywhere with confidence. - </> - ), - }, - { - title: 'Native Multi-Tenancy', - kicker: 'Self-contained · Multi-tenant', - Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, - description: ( - <> - Built-in support for multi-tenancy resource sharing and workload - isolation. Perfect for SaaS platforms and enterprise environments. - </> - ), - }, - { - title: 'Extensible Mechanisms', - kicker: 'Resource isolation · Plugin-ready', - Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, - description: ( - <> - Supports extensions, including Authentication/Authorization, Event, and - System/Tenant Monitoring. Rich plugin architecture. Highly extensible. - </> - ), - }, -]; - -function Feature({title, kicker, Svg, description}: FeatureItem) { - return ( - <div className={clsx('col col--3')}> - <div className="text--center"> - <Svg className={styles.featureSvg} role="img" /> - </div> - <div className="text--center padding-horiz--md"> - <p className={styles.featureKicker}>{kicker}</p> - <Heading as="h3">{title}</Heading> - <p>{description}</p> - </div> - </div> - ); -} - -export default function HomepageFeatures(): ReactNode { - return ( - <section className={styles.features}> - <div className="container"> - <div className={styles.intro}> - <Heading as="h2">What is BifroMQ?</Heading> - <p> - BifroMQ is a high-performance, distributed Apache MQTT broker - implementation that seamlessly integrates native multi-tenancy - support. It is designed to support building large-scale IoT device - connections and messaging systems. - </p> - </div> - <div className="row"> - {FeatureList.map((props, idx) => ( - <Feature key={idx} {...props} /> - ))} - </div> - </div> - </section> - ); -} diff --git a/src/components/HomepageFeatures/styles.module.css b/src/components/HomepageFeatures/styles.module.css deleted file mode 100644 index 8ad8a0a7..00000000 --- a/src/components/HomepageFeatures/styles.module.css +++ /dev/null @@ -1,24 +0,0 @@ -.features { - display: flex; - align-items: center; - padding: 2rem 0; - width: 100%; -} - -.intro { - text-align: center; - margin-bottom: 2.5rem; -} - -.featureKicker { - text-transform: uppercase; - letter-spacing: 0.08em; - font-size: 0.75rem; - font-weight: 600; - margin-bottom: 0.5rem; -} - -.featureSvg { - height: 200px; - width: 200px; -} diff --git a/src/css/custom.css b/src/css/custom.css index 2bc6a4cf..57e31ac0 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -1,30 +1,523 @@ -/** - * Any CSS included here will be global. The classic template - * bundles Infima by default. Infima is a CSS framework designed to - * work well for content-centric websites. - */ +/* ====================================================== + DESIGN SYSTEM 2026 - PRECISION HARMONY + Aesthetic: Refined Engineering, Balanced Innovation + Focus: Structural Integrity, Clear Hierarchy, Sophisticated Negative Space + ====================================================== */ + +/* Font Import */ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap'); -/* You can override the default Infima variables here. */ :root { - --ifm-color-primary: #2e8555; - --ifm-color-primary-dark: #29784c; - --ifm-color-primary-darker: #277148; - --ifm-color-primary-darkest: #205d3b; - --ifm-color-primary-light: #33925d; - --ifm-color-primary-lighter: #359962; - --ifm-color-primary-lightest: #3cad6e; - --ifm-code-font-size: 95%; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); -} - -/* For readability concerns, you should choose a lighter palette in dark mode. */ -[data-theme='dark'] { - --ifm-color-primary: #25c2a0; - --ifm-color-primary-dark: #21af90; - --ifm-color-primary-darker: #1fa588; - --ifm-color-primary-darkest: #1a8870; - --ifm-color-primary-light: #29d5b0; - --ifm-color-primary-lighter: #32d8b4; - --ifm-color-primary-lightest: #4fddbf; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); + /* Bifrost Palette - Distinct Solid Colors */ + --bifrost-red: #FF3B30; + --bifrost-orange: #FF9500; + --bifrost-yellow: #FFCC00; + --bifrost-green: #34C759; + --bifrost-teal: #5AC8FA; + --bifrost-blue: #007AFF; + --bifrost-indigo: #5856D6; + --bifrost-violet: #AF52DE; + + /* Colors - Ultra Premium Light Palette */ + --color-bg: #FFFFFF; + --color-wash: #FBFBFA; + --color-surface: #FFFFFF; + --color-border: #EFEFEF; + --color-border-strong: #111111; + --color-text-primary: #111111; + --color-text-secondary: #666666; + --color-text-tertiary: #999999; + --color-accent: var(--bifrost-blue); + --color-signal: var(--bifrost-orange); + + /* Typography */ + --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; + --font-mono: 'JetBrains Mono', monospace; + --font-display: 'Inter', sans-serif; + + /* Spacing - Extreme Breathing Room */ + --space-3xs: 0.25rem; + --space-2xs: 0.5rem; + --space-xs: 1rem; + --space-sm: 2rem; + --space-md: 4rem; + --space-lg: 8rem; + --space-xl: 12rem; + --space-2xl: 16rem; + + /* Layout */ + --container-max: 100%; + --content-max: 1800px; + /* Wider content for full-width feel */ + --radius-none: 0px; + --radius-sm: 6px; + --radius-md: 12px; + --radius-lg: 24px; + + /* Docusaurus Overrides */ + --ifm-color-primary: var(--color-accent); + --ifm-font-family-base: var(--font-sans); + --ifm-font-family-monospace: var(--font-mono); + --ifm-navbar-height: 80px; + --ifm-container-width: 100%; + --ifm-navbar-background-color: var(--color-bg); + --ifm-footer-background-color: var(--color-bg); + --ifm-navbar-link-hover-color: var(--color-text-primary); + --ifm-navbar-item-padding-horizontal: 1.5rem; +} + +/* Dark Mode - Technical Obsidian */ +html[data-theme='dark'] { + --color-bg: #000000; + --color-wash: #0A0A0A; + --color-surface: #000000; + --color-border: #1A1A1A; + --color-border-strong: #FFFFFF; + --color-text-primary: #FFFFFF; + --color-text-secondary: #A0A0A0; + --color-text-tertiary: #505050; + --color-accent: var(--bifrost-blue); + + --ifm-background-color: var(--color-bg); + --ifm-background-surface-color: var(--color-surface); +} + +/* ====================================================== + GLOBAL RESETS + ====================================================== */ +* { + box-sizing: border-box; +} + +html { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +body { + font-family: var(--font-sans); + color: var(--color-text-primary); + background: var(--color-bg); + line-height: 1.6; + /* Increased for better flow */ + letter-spacing: -0.01em; +} + +.container { + max-width: var(--content-max) !important; + margin: 0 auto; + padding: 0 var(--space-lg); +} + +/* Specific docs layout adjustments to prevent massive gaps */ +.theme-doc-container { + padding: 0 40px !important; +} + +.theme-doc-sidebar-container { + padding-top: 2rem; +} + +.theme-doc-markdown { + max-width: 900px !important; + margin: 0; + /* Aligned to left of content column, not centered in the whole viewport */ +} + +.row { + --ifm-spacing-horizontal: 1.5rem; + /* Tightened from var(--space-md) which was 4rem */ +} + +/* ====================================================== + NAVBAR - BIFROST PRECISION + ====================================================== */ +.navbar { + background: var(--color-bg); + border-bottom: 1px solid var(--color-border); + box-shadow: none; + height: var(--ifm-navbar-height); + padding: 0 40px !important; + /* Fixed padding for both sides */ + position: relative; +} + +/* The Bifrost Line - A nod to the name origins */ +.navbar::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + background: linear-gradient(to right, + var(--bifrost-red) 12.5%, + var(--bifrost-orange) 12.5%, + var(--bifrost-orange) 25%, + var(--bifrost-yellow) 25%, + var(--bifrost-yellow) 37.5%, + var(--bifrost-green) 37.5%, + var(--bifrost-green) 50%, + var(--bifrost-teal) 50%, + var(--bifrost-teal) 62.5%, + var(--bifrost-blue) 62.5%, + var(--bifrost-blue) 75%, + var(--bifrost-indigo) 75%, + var(--bifrost-indigo) 87.5%, + var(--bifrost-violet) 87.5%); + z-index: 10; +} + +.navbar__inner { + max-width: 100% !important; + margin: 0 !important; + width: 100%; +} + +.navbar__brand { + margin-right: 4rem; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +.navbar__title { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; +} + +.navbar__logo { + height: 18px !important; + /* Even smaller to ensure it looks balanced */ + width: auto !important; + max-height: 18px !important; + margin-right: 0; + display: block; +} + +/* Force override any inherited styles that might blow up the logo */ +.navbar__brand img { + height: 18px !important; + width: auto !important; +} + +.navbar__item { + font-family: var(--font-sans); + font-size: 0.875rem; + font-weight: 600; + color: var(--color-text-secondary); + transition: color 0.2s ease; +} + +.navbar__item:hover { + color: var(--color-text-primary); +} + +.navbar__link--active { + color: var(--color-text-primary) !important; + font-weight: 700; + position: relative; +} + +.header-github-link::before { + content: ''; + display: inline-block; + width: 20px; + height: 20px; + vertical-align: middle; + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.5 [...] + background-repeat: no-repeat; + background-size: contain; +} + +html[data-theme='dark'] .header-github-link::before { + filter: invert(1); +} + +/* ====================================================== + DOCS SIDEBAR - FLOW & PRECISION + ====================================================== */ +.theme-doc-sidebar-container { + border-right: 1px solid var(--color-border) !important; +} + +.menu__link { + font-size: 13px; + padding: 12px 20px; + border-radius: var(--radius-none); + color: var(--color-text-secondary); + transition: all 0.1s ease; + font-weight: 500; +} + +.menu__link:hover { + background: var(--color-wash); + color: var(--color-text-primary); +} + +.menu__link--active { + color: var(--color-text-primary) !important; + background: var(--color-wash) !important; + font-weight: 700; +} + +/* ====================================================== + MARKDOWN - INDUSTRIAL CLARITY + ====================================================== */ +.markdown { + font-size: 17px; + /* Sightly larger for readability */ + line-height: 1.8; + /* Expansive line height for focus */ + color: var(--color-text-secondary); + letter-spacing: -0.01em; +} + +.markdown h1, +.markdown h2, +.markdown h3, +.markdown h4 { + font-family: var(--font-display); + color: var(--color-text-primary); + letter-spacing: -0.04em; + font-weight: 800; + line-height: 1.2; +} + +.markdown h1 { + font-size: clamp(3rem, 5vw, 4.5rem); + margin-bottom: 4rem; + line-height: 1; } + +.markdown h2 { + font-size: 2.25rem; + margin-top: 6rem; + padding-bottom: 1.5rem; + border-bottom: 1px solid var(--color-border); + margin-bottom: 2rem; +} + +.markdown h3 { + font-size: 1.5rem; + margin-top: 4rem; + margin-bottom: 1.5rem; +} + +.markdown p, +.markdown li { + margin-bottom: 1.5rem; +} + +.markdown code { + font-family: var(--font-mono); + font-size: 0.85em; + background: var(--color-wash); + padding: 0.2rem 0.5rem; + border: 1px solid var(--color-border); + border-radius: var(--radius-sm); + color: var(--color-signal); +} + +a { + transition: color 0.3s ease, opacity 0.3s ease; +} + +button, +.button { + transition: all 0.3s cubic-bezier(0.2, 0.8, 0.2, 1); +} + +:focus-visible { + outline: 2px solid var(--color-signal); + outline-offset: 4px; +} + +.markdown pre { + background: var(--color-wash) !important; + border: 1px solid var(--color-border); + padding: 2.5rem; + border-radius: var(--radius-none); + margin: 3rem 0; +} + +.markdown img { + border: 1px solid var(--color-border); + padding: 1rem; + background: var(--color-wash); +} + +/* ====================================================== + FOOTER - BIFROST INTEGRATION + ====================================================== */ +.footer { + background: var(--color-bg) !important; + border-top: 1px solid var(--color-border); + padding: 80px 40px !important; + color: var(--color-text-primary); + position: relative; +} + +/* Subtle rainbow bridge accent at the top of footer */ +.footer::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(to right, + var(--bifrost-indigo), + var(--bifrost-blue), + var(--bifrost-teal), + var(--bifrost-green), + var(--bifrost-yellow), + var(--bifrost-orange), + var(--bifrost-red)); + opacity: 0.2; +} + +.footer__links { + max-width: var(--content-max); + margin: 0 auto; + margin-bottom: 60px; + display: grid; + grid-template-columns: 2fr repeat(3, 1fr); + gap: 40px; +} + +.footer__title { + font-family: var(--font-sans); + font-size: 0.85rem; + font-weight: 800; + text-transform: uppercase; + letter-spacing: 0.15em; + color: var(--color-text-primary); + margin-bottom: 24px; +} + +.footer__link-item { + font-size: 0.9rem; + color: var(--color-text-secondary); + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + line-height: 2; + text-decoration: none !important; +} + +.footer__link-item:hover { + color: var(--bifrost-blue); + transform: translateX(4px); +} + +.footer__bottom { + max-width: var(--content-max); + margin: 0 auto; + padding-top: 40px; + border-top: 1px solid var(--color-border); + display: flex; + flex-direction: column; + align-items: center; + text-align: center; +} + +.footer__logo { + margin-bottom: 32px; + display: block; +} + +/* Specific handling for the Incubator Logo SVG to ensure visibility in all themes */ +.footer__logo img { + height: 48px !important; + width: auto !important; + filter: grayscale(1) opacity(0.8); + transition: all 0.4s ease; +} + +html[data-theme='dark'] .footer__logo img { + filter: invert(1) grayscale(1) brightness(1.5) opacity(0.8); +} + +.footer__logo:hover img { + filter: grayscale(0) opacity(1); +} + +.footer__copyright { + font-size: 0.8rem; + color: var(--color-text-tertiary); + max-width: 900px; + line-height: 1.8; + font-weight: 400; +} + +.footer__copyright a { + color: var(--bifrost-blue); + text-decoration: none; + font-weight: 600; +} + +.footer__copyright a:hover { + text-decoration: underline; +} + +@media (max-width: 996px) { + .footer__links { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (max-width: 500px) { + .footer__links { + grid-template-columns: 1fr; + } +} + +/* ====================================================== + UTILITIES & OVERRIDES + ====================================================== */ +.container { + max-width: var(--content-max) !important; + padding: 0 5vw !important; +} + +/* Handled by targeted classes above */ + +.theme-blog-post-page .container { + max-width: 1000px !important; + /* Keep blog posts readable but well-padded */ +} + +::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +::-webkit-scrollbar-thumb { + background: var(--color-border-strong); + border-radius: 10px; +} + +::-webkit-scrollbar-track { + background: var(--color-bg); +} + +/* Buttons Styling */ +.button--primary { + background-color: var(--color-text-primary); + border-color: var(--color-text-primary); + color: var(--color-bg); + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.1em; + padding: 12px 24px; + border-radius: var(--radius-sm); +} + +.button--primary:hover { + background-color: var(--bifrost-blue); + border-color: var(--bifrost-blue); +} \ No newline at end of file diff --git a/src/pages/index.module.css b/src/pages/index.module.css index 44aa75a2..622b2a40 100644 --- a/src/pages/index.module.css +++ b/src/pages/index.module.css @@ -1,33 +1,496 @@ -/** - * CSS files with the .module.css suffix will be treated as CSS modules - * and scoped locally. - */ +/* ====================================================== + LANDING PAGE - BIFROST VISION + Aesthetic: Super-wide, Airy, Premium, Energetic + ====================================================== */ -.heroBanner { - padding: 4rem 0; - text-align: center; +.main { + width: 100%; + background: var(--color-bg); + overflow-x: hidden; +} + +/* --- ANIMATIONS --- */ +@keyframes fadeIn { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +@keyframes slideUp { + from { + opacity: 0; + transform: translateY(60px); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes bifrostPulse { + 0% { + opacity: 0.6; + } + + 50% { + opacity: 1; + } + + 100% { + opacity: 0.6; + } +} + +.reveal { + opacity: 0; + transform: translateY(40px); + transition: all 1s cubic-bezier(0.16, 1, 0.3, 1); +} + +.revealActive { + opacity: 1; + transform: translateY(0); +} + +/* --- HERO SECTION --- */ +.hero { + min-height: 90vh; + display: flex; + align-items: center; + justify-content: center; + padding: var(--space-xl) 5vw; position: relative; - overflow: hidden; + background: var(--color-bg); } -.heroEyebrow { - text-transform: uppercase; - letter-spacing: 0.12em; - font-size: 0.75rem; +.heroContent { + max-width: var(--content-max); + width: 100%; + display: grid; + grid-template-columns: 1.2fr 0.8fr; + gap: var(--space-xl); + align-items: center; +} + +.heroText { + z-index: 10; +} + +.heroBadge { + display: inline-flex; + align-items: center; + gap: 12px; + padding: 8px 16px; + background: var(--color-wash); + border: 1px solid var(--color-border); + border-radius: 100px; + font-family: var(--font-mono); + font-size: 12px; font-weight: 600; - margin-bottom: 0.75rem; + text-transform: uppercase; + letter-spacing: 0.1em; + color: var(--color-text-secondary); + margin-bottom: var(--space-md); + animation: fadeIn 1s ease-out; } -@media screen and (max-width: 996px) { - .heroBanner { - padding: 2rem; +.heroBadgeDot { + width: 8px; + height: 8px; + background: var(--bifrost-orange); + border-radius: 50%; + box-shadow: 0 0 10px var(--bifrost-orange); +} + +.heroTitle { + font-size: clamp(2.5rem, 5vw, 3.5rem); + line-height: 1.1; + font-weight: 800; + letter-spacing: -0.04em; + color: var(--color-text-primary); + margin-bottom: var(--space-md); + animation: slideUp 1s cubic-bezier(0.16, 1, 0.3, 1) 0.2s backwards; +} + +.heroTitle span { + display: block; + font-weight: 900; +} + +.heroDesc { + font-size: clamp(1.1rem, 2vw, 1.4rem); + line-height: 1.5; + color: var(--color-text-secondary); + max-width: 700px; + margin-bottom: var(--space-lg); + font-weight: 400; + animation: slideUp 1s cubic-bezier(0.16, 1, 0.3, 1) 0.4s backwards; +} + +.heroCta { + display: flex; + gap: 24px; + animation: slideUp 1s cubic-bezier(0.16, 1, 0.3, 1) 0.6s backwards; +} + +.heroCtaPrimary { + background: var(--color-text-primary); + color: var(--color-bg); + padding: 20px 48px; + border-radius: var(--radius-sm); + font-weight: 700; + font-size: 1.125rem; + text-decoration: none; + transition: all 0.3s ease; + border: 1px solid var(--color-text-primary); +} + +.heroCtaPrimary:hover { + background: var(--bifrost-blue); + border-color: var(--bifrost-blue); + color: #fff; + transform: translateY(-4px); +} + +.heroCtaSecondary { + background: transparent; + color: var(--color-text-primary); + padding: 20px 48px; + border-radius: var(--radius-sm); + font-weight: 700; + font-size: 1.125rem; + text-decoration: none; + border: 1px solid var(--color-border); + transition: all 0.3s ease; +} + +.heroCtaSecondary:hover { + border-color: var(--color-text-primary); + transform: translateY(-4px); +} + +.heroVisual { + position: relative; + display: flex; + justify-content: flex-end; + animation: fadeIn 2s ease-out 0.8s backwards; +} + +.bifrostRing { + width: 500px; + height: 500px; + border: 40px solid var(--color-wash); + border-radius: 50%; + position: relative; + display: flex; + align-items: center; + justify-content: center; +} + +.bifrostRing::before { + content: ''; + position: absolute; + inset: -1px; + border-radius: 50%; + border: 2px dashed var(--color-border); + animation: spin 60s linear infinite; +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(360deg); } } -.buttons { +/* --- TRUST SECTION --- */ +.trust { + padding: var(--space-md) 5vw; + border-top: 1px solid var(--color-border); + border-bottom: 1px solid var(--color-border); + background: var(--color-bg); +} + +.trustInner { + max-width: var(--content-max); + margin: 0 auto; + display: flex; + align-items: center; + justify-content: center; + gap: 24px; +} + +.apacheBrand { + font-family: var(--font-mono); + font-size: 14px; + letter-spacing: 0.1em; + color: var(--color-text-tertiary); + text-transform: uppercase; + font-weight: 600; +} + +/* --- FEATURE WRAPPER --- */ +.sectionContainer { + padding: var(--space-2xl) 5vw; + max-width: var(--content-max); + margin: 0 auto; +} + +.sectionHeader { + margin-bottom: var(--space-xl); + max-width: 900px; +} + +.sectionLabel { + display: inline-block; + font-family: var(--font-mono); + font-size: 13px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.2em; + color: var(--bifrost-blue); + margin-bottom: 16px; +} + +.sectionTitle { + font-size: clamp(2rem, 4vw, 3rem); + /* Reduced from 4.5rem max to 3rem max */ + line-height: 1.2; + font-weight: 800; + letter-spacing: -0.03em; + color: var(--color-text-primary); +} + +/* --- GRID SYSTEM --- */ +.bifrostGrid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 32px; +} + +.bifrostCard { + background: var(--color-bg); + padding: var(--space-md); + border: 1px solid var(--color-border); + border-radius: var(--radius-md); + transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1); + position: relative; + display: flex; + flex-direction: column; +} + +.bifrostCard:hover { + transform: translateY(-12px); + border-color: var(--color-text-primary); + box-shadow: 0 30px 60px rgba(0, 0, 0, 0.05); +} + +.cardIcon { + width: 60px; + height: 60px; + background: var(--color-wash); + border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center; - gap: 1rem; - flex-wrap: wrap; + font-size: 28px; + margin-bottom: 32px; + transition: all 0.3s ease; } + +.bifrostCard:hover .cardIcon { + background: var(--color-text-primary); + color: #fff; +} + +.cardTitle { + font-size: 1.75rem; + font-weight: 700; + letter-spacing: -0.02em; + margin-bottom: 20px; + color: var(--color-text-primary); +} + +.cardDesc { + font-size: 1.125rem; + line-height: 1.6; + color: var(--color-text-secondary); +} + +.bifrostCardBorder { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 4px; + opacity: 0; + transition: opacity 0.3s ease; + border-radius: var(--radius-md) var(--radius-md) 0 0; +} + +.bifrostCard:hover .bifrostCardBorder { + opacity: 1; +} + +/* --- TERMINAL --- */ +.quickstart { + background: #000; + border-radius: var(--radius-lg); + padding: 60px; + position: relative; + overflow: hidden; + box-shadow: 0 50px 100px rgba(0, 0, 0, 0.3); +} + +.terminalOutput { + font-family: var(--font-mono); + font-size: 1.25rem; + line-height: 1.8; + color: #fff; +} + +.prompt { + color: var(--bifrost-green); + margin-right: 16px; +} + +.cursor { + display: inline-block; + width: 10px; + height: 24px; + background: var(--bifrost-orange); + vertical-align: middle; + animation: blink 1s step-end infinite; +} + +@keyframes blink { + 50% { + opacity: 0; + } +} + +/* --- STATS --- */ +.statsGrid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 1px; + background: var(--color-border); + border: 1px solid var(--color-border); + border-radius: var(--radius-md); + overflow: hidden; +} + +.statCell { + background: var(--color-bg); + padding: 60px; + text-align: center; +} + +.statVal { + display: block; + font-size: 4rem; + /* Reduced from 6rem */ + font-weight: 900; + line-height: 1; + letter-spacing: -0.06em; + color: var(--color-text-primary); + margin-bottom: 16px; +} + +.statLab { + font-family: var(--font-mono); + font-size: 14px; + font-weight: 700; + color: var(--color-text-tertiary); + text-transform: uppercase; + letter-spacing: 0.15em; +} + +/* --- CTA --- */ +.finalCta { + padding: var(--space-2xl) 5vw; + background: var(--color-wash); + text-align: center; + position: relative; +} + +.finalCtaTitle { + font-size: clamp(2.5rem, 6vw, 4rem); + /* Reduced from 8rem max to 4rem max */ + font-weight: 900; + letter-spacing: -0.05em; + line-height: 1.1; + margin-bottom: var(--space-lg); + color: var(--color-text-primary); +} + +.finalCtaPrimary { + display: inline-block; + background: var(--color-text-primary); + color: var(--color-bg); + padding: 32px 80px; + font-size: 1.5rem; + font-weight: 800; + text-decoration: none; + border-radius: var(--radius-sm); + transition: all 0.3s ease; +} + +.finalCtaPrimary:hover { + transform: scale(1.05); + background: var(--bifrost-blue); + color: #fff; +} + +/* --- RESPONSIVE --- */ +@media (max-width: 1200px) { + .heroContent { + grid-template-columns: 1fr; + } + + .heroVisual { + display: none; + } + + .bifrostGrid { + grid-template-columns: repeat(2, 1fr); + } + + .statsGrid { + grid-template-columns: 1fr; + } +} + +@media (max-width: 768px) { + .bifrostGrid { + grid-template-columns: 1fr; + } + + .heroTitle { + font-size: 3rem; + } + + .sectionTitle { + font-size: 2.5rem; + } + + .statVal { + font-size: 4rem; + } + + .quickstart { + padding: 30px; + } + + .terminalOutput { + font-size: 1rem; + } +} \ No newline at end of file diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 15494424..0be43843 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,50 +1,211 @@ -import type {ReactNode} from 'react'; -import clsx from 'clsx'; +import React, { type ReactNode, useEffect } from 'react'; import Link from '@docusaurus/Link'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import Layout from '@theme/Layout'; -import HomepageFeatures from '@site/src/components/HomepageFeatures'; -import Heading from '@theme/Heading'; - import styles from './index.module.css'; -function HomepageHeader() { - const {siteConfig} = useDocusaurusContext(); +/** + * BifroMQ Landing Page - Bifrost Redesign + * Inspired by the Rainbow Bridge, emphasizing connectivity and architectural elegance. + */ +export default function Home(): ReactNode { + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + entry.target.classList.add(styles.revealActive); + } + }); + }, + { threshold: 0.1 } + ); + + const reveals = document.querySelectorAll(`.${styles.reveal}`); + reveals.forEach((el) => observer.observe(el)); + + return () => observer.disconnect(); + }, []); + return ( - <header className={clsx('hero hero--primary', styles.heroBanner)}> - <div className="container"> - <p className={styles.heroEyebrow}>Apache Incubating Project</p> - <Heading as="h1" className="hero__title"> - Apache BifroMQ (Incubating) - </Heading> - <p className="hero__subtitle">{siteConfig.tagline}</p> - <div className={styles.buttons}> - <Link - className="button button--secondary button--lg" - to="/docs/get_started/intro"> - Get Started - </Link> - <Link - className="button button--outline button--lg" - href="https://github.com/apache/bifromq"> - View on GitHub + <Layout + title="Apache BifroMQ | High-Performance Multi-tenant MQTT Broker" + description="The definitive high-performance, multi-tenant MQTT broker for massive scale IoT. Industrial-grade reliability meets architectural precision."> + <main className={styles.main}> + + {/* --- HERO SECTION --- */} + <section className={styles.hero}> + <div className={styles.heroContent}> + <div className={styles.heroText}> + <div className={styles.heroBadge}> + <div className={styles.heroBadgeDot} /> + <span>Now an Apache Incubator Project</span> + </div> + <h1 className={styles.heroTitle}> + The Bridge to <span>Massive Scale IoT.</span> + </h1> + <p className={styles.heroDesc}> + Apache BifroMQ (Incubating) is a Java-based, high-performance MQTT broker + messaging middleware that adopts a native multi-tenant architecture. + Built for the next generation of industrial connectivity. + </p> + <div className={styles.heroCta}> + <Link to="/docs/get_started/intro" className={styles.heroCtaPrimary}> + Get Started + </Link> + <Link to="https://github.com/apache/bifromq" className={styles.heroCtaSecondary}> + View on GitHub + </Link> + </div> + </div> + <div className={styles.heroVisual}> + <div className={styles.bifrostRing}> + <div style={{ fontSize: '120px', fontWeight: 900, letterSpacing: '-0.1em' }}> + BIFRO<span style={{ color: 'var(--bifrost-blue)' }}>MQ</span> + </div> + </div> + </div> + </div> + </section> + + {/* --- TRUST SECTION --- */} + <section className={styles.trust}> + <div className={styles.trustInner}> + <span className={styles.apacheBrand}>Supported by the Apache Software Foundation</span> + </div> + </section> + + {/* --- STATS SECTION --- */} + <section className={`${styles.sectionContainer} ${styles.reveal}`}> + <div className={styles.statsGrid}> + <div className={styles.statCell}> + <span className={styles.statVal}>10M+</span> + <span className={styles.statLab}>Connections per Cluster</span> + </div> + <div className={styles.statCell}> + <span className={styles.statVal}><1ms</span> + <span className={styles.statLab}>Latency Precision</span> + </div> + <div className={styles.statCell}> + <span className={styles.statVal}>v5.0</span> + <span className={styles.statLab}>Full Protocol Support</span> + </div> + </div> + </section> + + {/* --- FEATURES SECTION --- */} + <section className={`${styles.sectionContainer} ${styles.reveal}`}> + <div className={styles.sectionHeader}> + <span className={styles.sectionLabel}>Capabilities</span> + <h2 className={styles.sectionTitle}>Engineered for the Connected Future</h2> + </div> + + <div className={styles.bifrostGrid}> + <FeatureCard + icon="🏢" + title="Multi-tenancy" + desc="True SaaS architecture with hard resource isolation and independent governance for millions of tenants." + color="var(--bifrost-indigo)" + /> + <FeatureCard + icon="⚡" + title="Elastic Scaling" + desc="Horizontally scalable compute and storage layers, enabling seamless growth without downtime." + color="var(--bifrost-blue)" + /> + <FeatureCard + icon="🧩" + title="Extensible Core" + desc="Rich plugin system for auth, governance, and custom enterprise integrations." + color="var(--bifrost-teal)" + /> + <FeatureCard + icon="📊" + title="Full Telemetry" + desc="Deep visibility into cluster health and tenant behavior with native monitoring support." + color="var(--bifrost-violet)" + /> + </div> + </section> + + {/* --- QUICK START SECTION --- */} + <section className={`${styles.sectionContainer} ${styles.reveal}`}> + <div className={styles.sectionHeader}> + <span className={styles.sectionLabel}>Deployment</span> + <h2 className={styles.sectionTitle}>Launch in Seconds</h2> + </div> + <div className={styles.quickstart}> + <div className={styles.terminalOutput}> + <div><span className={styles.prompt}>$</span> docker pull apache/bifromq:latest</div> + <div><span className={styles.prompt}>$</span> docker run -d --name bifromq -p 1883:1883 apache/bifromq:latest</div> + <div style={{ opacity: 0.6, marginTop: '20px' }}># BifroMQ node starting up...</div> + <div style={{ opacity: 0.6 }}># Cluster established. Ready for massive connectivity.</div> + <div><span className={styles.prompt}>$</span> <span className={styles.cursor} /></div> + </div> + </div> + </section> + + {/* --- USE CASES SECTION --- */} + <section className={`${styles.sectionContainer} ${styles.reveal}`}> + <div className={styles.sectionHeader}> + <span className={styles.sectionLabel}>Solutions</span> + <h2 className={styles.sectionTitle}>Bridging the Industrial Gap</h2> + </div> + <div className={styles.bifrostGrid}> + <UseCaseCard + tag="Automotive" + title="Connected Vehicles" + desc="Managing millions of high-frequency telemetry streams with strict latency budgets." + /> + <UseCaseCard + tag="Manufacturing" + title="Smart Factories" + desc="Reliable message bus for thousands of industrial sensors and actuators." + /> + <UseCaseCard + tag="Energy" + title="Smart Grids" + desc="Securely aggregating distributed energy data across vast geographies." + /> + <UseCaseCard + tag="Logistics" + title="Asset Tracking" + desc="Maintaining connectivity for mobile assets moving across global networks." + /> + </div> + </section> + + {/* --- FINAL CTA SECTION --- */} + <section className={`${styles.finalCta} ${styles.reveal}`}> + <div className={styles.finalCtaTitle}> + Ready to Build? + </div> + <Link to="/docs/get_started/intro" className={styles.finalCtaPrimary}> + Get Started Now </Link> - </div> - </div> - </header> + </section> + + </main> + </Layout> ); } -export default function Home(): ReactNode { - const {siteConfig} = useDocusaurusContext(); +function FeatureCard({ icon, title, desc, color }: { icon: string, title: string, desc: string, color: string }) { return ( - <Layout - title="Apache BifroMQ (Incubating)" - description={siteConfig.tagline}> - <HomepageHeader /> - <main> - <HomepageFeatures /> - </main> - </Layout> + <div className={styles.bifrostCard}> + <div className={styles.bifrostCardBorder} style={{ background: color }} /> + <div className={styles.cardIcon}>{icon}</div> + <h3 className={styles.cardTitle}>{title}</h3> + <p className={styles.cardDesc}>{desc}</p> + </div> + ); +} + +function UseCaseCard({ tag, title, desc }: { tag: string, title: string, desc: string }) { + return ( + <div className={styles.bifrostCard} style={{ background: 'var(--color-wash)' }}> + <span className={styles.sectionLabel} style={{ fontSize: '11px', color: 'var(--color-text-tertiary)' }}>{tag}</span> + <h3 className={styles.cardTitle} style={{ fontSize: '1.5rem' }}>{title}</h3> + <p className={styles.cardDesc} style={{ fontSize: '1rem' }}>{desc}</p> + </div> ); } diff --git a/static/img/logo.svg b/static/img/logo.svg index f86f75ab..7c65e817 100644 --- a/static/img/logo.svg +++ b/static/img/logo.svg @@ -1 +1 @@ -<svg data-v-423bf9ae="" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 309.53325174225495 60" class="font"><!----><!----><defs data-v-423bf9ae=""><linearGradient data-v-423bf9ae="" gradientTransform="rotate(25)" id="4b5fe519-1853-46c4-931c-4d99816540c8" x1="0%" y1="0%" x2="100%" y2="0%"><stop data-v-423bf9ae="" offset="0%" style="stop-color: rgb(233, 13, 202); stop-opacity: 1;"></stop><stop data-v-423bf9ae="" offset="100%" style="stop-color: rgb(21, 54, 241); stop-opacity: 1;"></stop></ [...] \ No newline at end of file +<svg data-v-423bf9ae="" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 309.53325174225495 60" class="font"><!----><!----><g data-v-423bf9ae="" id="e095d4e9-0924-4fc2-b82a-50d763874c48" fill="#000000" transform="matrix(5.958291572597482,0,0,5.958291572597482,-5.42204863630468,-3.3962253789031607)"><path d="M1.67 5.85C2.84 5.85 3.85 5.85 5.03 5.85C6.34 5.85 7.73 6.40 7.74 7.92C7.74 9.48 6.16 9.77 4.93 9.77L1.67 9.77ZM1.67 1.34L4.93 1.34C6.15 1.34 7.43 1.95 7.43 3.37C7.43 4.77 6.20 5.14 5. [...]
