You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bifromq.apache.org by vi...@apache.org on 2026/01/12 07:50:22 UTC
(bifromq-sites) 02/02: redesign footer section
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 02c87d41487702fc22dbf2a7762dfea19252e142
Author: Visoar <vi...@gmail.com>
AuthorDate: Mon Jan 12 15:45:53 2026 +0800
redesign footer section
Update docusaurus.config.ts
---
docusaurus.config.ts | 60 ++++---
src/css/custom.css | 101 +++++++----
src/pages/index.module.css | 436 ++++++++++++++++++++++++++++-----------------
src/pages/index.tsx | 159 +++++++----------
4 files changed, 431 insertions(+), 325 deletions(-)
diff --git a/docusaurus.config.ts b/docusaurus.config.ts
index c27ae7af..1560f165 100644
--- a/docusaurus.config.ts
+++ b/docusaurus.config.ts
@@ -213,43 +213,48 @@ const config: Config = {
items: [
{
html: `
- <div style="margin-bottom: 2rem;">
- <div style="font-weight: 800; font-size: 1.25rem; letter-spacing: -0.02em; margin-bottom: 0.5rem;">BifroMQ</div>
- <p style="font-size: 0.9rem; line-height: 1.6; color: var(--color-text-secondary); max-width: 300px;">
- Next-generation high-performance, multi-tenant MQTT broker for industrial-scale IoT.
+ <div style="margin-bottom: 1.5rem;">
+ <p style="font-size: 0.9rem; line-height: 1.6; color: var(--color-text-secondary); max-width: 320px; margin-bottom: 2rem;">
+ High-performance Apache MQTT broker with enterprise-grade reliability. Applicable to IoT, IM and other scenarios.
</p>
+ <div style="display: flex; gap: 24px; align-items: center;">
+ <a href="https://github.com/apache/bifromq" target="_blank" rel="noopener noreferrer" style="color: var(--color-text-tertiary); transition: color 0.3s; display: flex;" onmouseover="this.style.color='var(--bifrost-blue)'" onmouseout="this.style.color='var(--color-text-tertiary)'">
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path 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-.54-1.523.105-3.176 0 [...]
+ </a>
+ <a href="https://discord.gg/Pfs3QRadRB" target="_blank" rel="noopener noreferrer" style="color: var(--color-text-tertiary); transition: color 0.3s; display: flex;" onmouseover="this.style.color='var(--bifrost-blue)'" onmouseout="this.style.color='var(--color-text-tertiary)'">
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515a.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0a12.64 12.64 0 0 0-.617-1.25a.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057a19.9 19.9 0 0 0 5.993 3.03a.078.078 0 0 0 .084-.028a14.09 14.09 0 0 0 1.226-1.994a.076.076 0 0 0-.041-.106a1 [...]
+ </a>
+ <a href="mailto:dev@bifromq.apache.org" style="color: var(--color-text-tertiary); transition: color 0.3s; display: flex;" onmouseover="this.style.color='var(--bifrost-blue)'" onmouseout="this.style.color='var(--color-text-tertiary)'">
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
+ </a>
+ </div>
</div>
`,
},
- { label: 'Introduction', to: '/docs/get_started/intro' },
- { label: 'Downloads', to: '/download' },
- { label: 'Changelog', href: 'https://github.com/apache/bifromq/releases' },
],
},
{
- title: 'Development',
+ title: 'Resources',
items: [
{ label: 'GitHub', href: 'https://github.com/apache/bifromq' },
+ { label: 'Releases', href: 'https://github.com/apache/bifromq/releases' },
{ label: 'Issues', href: 'https://github.com/apache/bifromq/issues' },
- { label: 'API Docs', to: '/docs/user_guide/api/openapi' },
],
},
{
- title: 'Community',
+ title: 'Apache',
items: [
- { label: 'Discord', href: 'https://discord.gg/Pfs3QRadRB' },
- { label: 'Mailing List', href: 'mailto:dev@bifromq.apache.org' },
- { label: 'Blog', to: '/blog' },
- { label: 'Contribution', to: '/community' },
+ { label: 'Apache Incubator', href: 'https://incubator.apache.org/' },
+ { label: 'Code of Conduct', href: 'https://www.apache.org/foundation/policies/conduct.html' },
+ { label: 'Apache 2.0 License', href: 'https://www.apache.org/licenses/LICENSE-2.0' },
],
},
{
- title: 'Apache',
+ title: 'Others',
items: [
- { label: 'Foundation', href: 'https://www.apache.org/' },
- { label: 'License', href: 'https://www.apache.org/licenses/LICENSE-2.0' },
- { label: 'Sponsorship', href: 'https://www.apache.org/foundation/sponsorship.html' },
- { label: 'Security', href: 'https://www.apache.org/security/' },
+ { label: 'Thanks OpenSource@Baidu', href: 'https://opensource.baidu.com/' },
+ { label: 'MQTT v3.1.1', href: 'http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html' },
+ { label: 'MQTT v5.0', href: 'https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html' },
],
},
],
@@ -258,19 +263,18 @@ const config: Config = {
src: '/img/apache-incubator.svg',
href: 'https://incubator.apache.org/',
alt: 'Apache Incubator',
+ className: 'footer__incubator-logo',
},
copyright: `
- <div style="font-size: 0.85rem; line-height: 1.8; color: var(--color-text-tertiary); margin-top: 2rem;">
- <p>
- Copyright © ${new Date().getFullYear()} The Apache Software Foundation.
- Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0" style="color: var(--bifrost-blue); text-decoration: none;">Apache License, Version 2.0</a>.
+ <div style="font-size: 0.8rem; line-height: 1.8; color: var(--color-text-tertiary); text-align: center; border-top: 1px solid var(--color-border); padding-top: 3rem;">
+ <p style="margin-bottom: 1.5rem; max-width: 1100px; margin-left: auto; margin-right: auto;">
+ Apache BifroMQ is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is not necessarily a reflection of the completeness or stability of the code, it does indicate that [...]
</p>
- <p>
- Apache BifroMQ, BifroMQ, Apache, the Apache feather logo, and the Apache BifroMQ project logo are either
- registered trademarks or trademarks of The Apache Software Foundation.
+ <p style="margin-bottom: 1.5rem;">
+ Copyright © 2026 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.
</p>
- <p style="margin-top: 1.5rem; font-style: italic; font-size: 0.8rem;">
- Apache BifroMQ is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator.
+ <p style="max-width: 1200px; margin-left: auto; margin-right: auto;">
+ Apache, the names of Apache projects, and the feather logo are either registered trademarks or trademarks of the Apache Software Foundation in the United States and/or other countries.
</p>
</div>
`,
diff --git a/src/css/custom.css b/src/css/custom.css
index a98d7038..3a254a59 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -66,20 +66,26 @@
--ifm-navbar-item-padding-horizontal: 0.75rem;
}
-/* Dark Mode - Technical Obsidian */
+/* Dark Mode - Sophisticated Slate 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-bg: #0C0D0F;
+ /* Deep Obsidian Slate */
+ --color-wash: #14161A;
+ /* Slightly lighter for depth */
+ --color-surface: #1A1D23;
+ /* Surface for cards/modals */
+ --color-border: #242830;
+ /* Subtle slate border */
+ --color-border-strong: #3D4452;
+ --color-text-primary: #F0F2F5;
+ --color-text-secondary: #94A3B8;
+ --color-text-tertiary: #64748B;
--color-accent: var(--bifrost-blue);
--ifm-background-color: var(--color-bg);
--ifm-background-surface-color: var(--color-surface);
+ --ifm-navbar-background-color: var(--color-bg);
+ --ifm-footer-background-color: var(--color-bg);
}
/* ======================================================
@@ -377,7 +383,7 @@ button,
.footer {
background: var(--color-bg) !important;
border-top: 1px solid var(--color-border);
- padding: 80px 40px !important;
+ padding: var(--space-lg) 40px !important;
color: var(--color-text-primary);
position: relative;
}
@@ -398,34 +404,35 @@ button,
var(--bifrost-yellow),
var(--bifrost-orange),
var(--bifrost-red));
- opacity: 0.2;
+ opacity: 0.15;
}
.footer__links {
max-width: var(--content-max);
margin: 0 auto;
- margin-bottom: 60px;
+ margin-bottom: var(--space-md);
display: grid;
- grid-template-columns: 2fr repeat(3, 1fr);
- gap: 40px;
+ grid-template-columns: 1.5fr repeat(3, 1fr);
+ gap: 60px;
}
.footer__title {
- font-family: var(--font-sans);
- font-size: 0.85rem;
- font-weight: 800;
+ font-family: var(--font-mono);
+ font-size: 0.75rem;
+ font-weight: 700;
text-transform: uppercase;
- letter-spacing: 0.15em;
+ letter-spacing: 0.2em;
color: var(--color-text-primary);
margin-bottom: 24px;
}
.footer__link-item {
- font-size: 0.9rem;
+ font-size: 0.875rem;
color: var(--color-text-secondary);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
- line-height: 2;
+ line-height: 2.2;
text-decoration: none !important;
+ display: inline-block;
}
.footer__link-item:hover {
@@ -433,50 +440,68 @@ button,
transform: translateX(4px);
}
+/* Smaller and coordinated external link icons */
+.footer__link-item svg {
+ width: 12px !important;
+ height: 12px !important;
+ margin-left: 4px;
+ vertical-align: middle;
+ opacity: 0.6;
+}
+
.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;
+ /* Center everything in the bottom section */
text-align: center;
+ padding-top: 0;
}
.footer__logo {
- margin-bottom: 32px;
- display: block;
+ margin-top: 40px;
+ /* Space after links */
+ margin-bottom: 0px;
+ /* Minimal space before copyright div (which has internal padding) */
+ display: flex;
+ justify-content: center;
+ order: 2;
+ /* Move below links */
}
-/* Specific handling for the Incubator Logo SVG to ensure visibility in all themes */
-.footer__logo img {
- height: 48px !important;
+/* Clear visibility for Incubator Logo */
+.footer__logo img,
+.footer__incubator-logo {
+ height: 56px !important;
width: auto !important;
- filter: grayscale(1) opacity(0.8);
+ filter: grayscale(1) brightness(0) opacity(0.5);
+ /* Strong black in light mode */
transition: all 0.4s ease;
}
-html[data-theme='dark'] .footer__logo img {
- filter: invert(1) grayscale(1) brightness(1.5) opacity(0.8);
+html[data-theme='dark'] .footer__logo img,
+html[data-theme='dark'] .footer__incubator-logo {
+ filter: invert(1) brightness(2) opacity(0.6);
+ /* Bright white in dark mode */
}
-.footer__logo:hover img {
- filter: grayscale(0) opacity(1);
+.footer__logo:hover img,
+.footer__logo:hover .footer__incubator-logo {
+ filter: none !important;
+ opacity: 1 !important;
}
.footer__copyright {
- font-size: 0.8rem;
- color: var(--color-text-tertiary);
- max-width: 900px;
- line-height: 1.8;
- font-weight: 400;
+ width: 100%;
+ order: 3;
+ /* Copyright area is at the very bottom */
}
.footer__copyright a {
color: var(--bifrost-blue);
text-decoration: none;
- font-weight: 600;
}
.footer__copyright a:hover {
diff --git a/src/pages/index.module.css b/src/pages/index.module.css
index 24c36a8b..da4d0538 100644
--- a/src/pages/index.module.css
+++ b/src/pages/index.module.css
@@ -56,134 +56,212 @@
transform: translateY(0);
}
-/* --- HERO SECTION --- */
+/* Bifrost Divider */
+.bifrostDivider {
+ width: 100%;
+ height: 1px;
+ background: linear-gradient(to right,
+ transparent,
+ var(--color-border) 20%,
+ var(--bifrost-blue) 45%,
+ var(--bifrost-indigo) 55%,
+ var(--color-border) 80%,
+ transparent);
+ opacity: 0.3;
+ margin: 0 auto;
+ max-width: var(--content-max);
+}
+
+/* --- HERO SECTION - PRECISION REFACTOR --- */
.hero {
- min-height: 90vh;
+ min-height: 95vh;
display: flex;
align-items: center;
justify-content: center;
- padding: var(--space-xl) 5vw;
+ padding: 0 5vw;
position: relative;
background: var(--color-bg);
+ overflow: hidden;
+}
+
+/* Technical Backdrop */
+.hero::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image:
+ linear-gradient(var(--color-border) 1px, transparent 1px),
+ linear-gradient(90deg, var(--color-border) 1px, transparent 1px);
+ background-size: 60px 60px;
+ background-position: center center;
+ mask-image: radial-gradient(circle at center, black, transparent 90%);
+ opacity: 0.3;
+ pointer-events: none;
+}
+
+/* Bifrost Bridge Glow */
+.hero::after {
+ content: '';
+ position: absolute;
+ bottom: -200px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 150%;
+ height: 400px;
+ background: radial-gradient(ellipse at center,
+ rgba(0, 122, 255, 0.15) 0%,
+ rgba(88, 86, 214, 0.1) 30%,
+ transparent 70%);
+ filter: blur(80px);
+ z-index: 1;
+ pointer-events: none;
}
.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;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
}
.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;
+ padding: 6px 14px;
+ background: var(--color-bg);
+ border: 1px solid var(--color-border-strong);
font-family: var(--font-mono);
- font-size: 12px;
+ font-size: 11px;
font-weight: 600;
text-transform: uppercase;
- letter-spacing: 0.1em;
- color: var(--color-text-secondary);
+ letter-spacing: 0.15em;
+ color: var(--color-text-primary);
margin-bottom: var(--space-md);
+ position: relative;
+ overflow: hidden;
animation: fadeIn 1s ease-out;
}
+/* Subtle Rainbow Edge for badge */
+.heroBadge::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 2px;
+ background: linear-gradient(to right, var(--bifrost-blue), var(--bifrost-indigo), var(--bifrost-violet));
+ opacity: 0.6;
+}
+
.heroBadgeDot {
- width: 8px;
- height: 8px;
- background: var(--bifrost-orange);
- border-radius: 50%;
- box-shadow: 0 0 10px var(--bifrost-orange);
+ width: 6px;
+ height: 6px;
+ background: var(--bifrost-blue);
+ border-radius: 0;
+ box-shadow: 0 0 10px var(--bifrost-blue);
}
.heroTitle {
- font-size: clamp(2.5rem, 5vw, 3.5rem);
- line-height: 1.1;
+ font-size: clamp(2.5rem, 6vw, 4.5rem);
+ line-height: 1;
font-weight: 800;
- letter-spacing: -0.04em;
+ letter-spacing: -0.05em;
color: var(--color-text-primary);
margin-bottom: var(--space-md);
- animation: slideUp 1s cubic-bezier(0.16, 1, 0.3, 1) 0.2s backwards;
+ max-width: 1000px;
+ animation: slideUp 1.2s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}
.heroTitle span {
display: block;
- font-weight: 900;
+ color: var(--color-text-tertiary);
+ font-weight: 300;
+ font-size: 0.7em;
+ margin-top: 8px;
}
.heroDesc {
- font-size: clamp(1.1rem, 2vw, 1.4rem);
+ font-size: clamp(1.1rem, 2vw, 1.35rem);
line-height: 1.5;
color: var(--color-text-secondary);
- max-width: 700px;
+ max-width: 800px;
margin-bottom: var(--space-lg);
font-weight: 400;
- animation: slideUp 1s cubic-bezier(0.16, 1, 0.3, 1) 0.4s backwards;
+ letter-spacing: -0.01em;
+ animation: slideUp 1.2s cubic-bezier(0.16, 1, 0.3, 1) 0.2s backwards;
}
.heroCta {
display: flex;
- gap: 24px;
- animation: slideUp 1s cubic-bezier(0.16, 1, 0.3, 1) 0.6s backwards;
+ gap: 16px;
+ animation: slideUp 1.2s cubic-bezier(0.16, 1, 0.3, 1) 0.4s backwards;
}
.heroCtaPrimary {
background: var(--color-text-primary);
color: var(--color-bg);
- padding: 20px 48px;
- border-radius: var(--radius-sm);
+ padding: 24px 56px;
font-weight: 700;
- font-size: 1.125rem;
+ font-size: 1.25rem;
text-decoration: none;
- transition: all 0.3s ease;
+ transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1);
border: 1px solid var(--color-text-primary);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: var(--radius-none);
}
.heroCtaPrimary:hover {
- background: var(--bifrost-blue);
- border-color: var(--bifrost-blue);
- color: #fff;
- transform: translateY(-4px);
+ background: var(--color-bg);
+ color: var(--color-text-primary);
+ transform: translateY(-2px);
}
.heroCtaSecondary {
background: transparent;
color: var(--color-text-primary);
- padding: 20px 48px;
- border-radius: var(--radius-sm);
+ padding: 24px 56px;
font-weight: 700;
- font-size: 1.125rem;
+ font-size: 1.25rem;
text-decoration: none;
border: 1px solid var(--color-border);
- transition: all 0.3s ease;
+ transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: var(--radius-none);
}
.heroCtaSecondary:hover {
border-color: var(--color-text-primary);
- transform: translateY(-4px);
+ transform: translateY(-2px);
}
.heroVisual {
- position: relative;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 100%;
+ height: 100%;
+ pointer-events: none;
+ z-index: -1;
display: flex;
- justify-content: flex-end;
- animation: fadeIn 2s ease-out 0.8s backwards;
+ justify-content: center;
+ align-items: center;
+ opacity: 0.15;
}
.bifrostRing {
- width: 500px;
- height: 500px;
- border: 40px solid var(--color-wash);
+ width: 800px;
+ height: 800px;
+ border: 1px solid var(--color-border);
border-radius: 50%;
position: relative;
display: flex;
@@ -191,28 +269,22 @@
justify-content: center;
}
-.bifrostRing::before {
+.bifrostRing::before,
+.bifrostRing::after {
content: '';
position: absolute;
- inset: -1px;
+ inset: -150px;
+ border: 1px solid var(--color-border);
border-radius: 50%;
- border: 2px dashed var(--color-border);
- animation: spin 60s linear infinite;
}
-@keyframes spin {
- from {
- transform: rotate(0deg);
- }
-
- to {
- transform: rotate(360deg);
- }
+.bifrostRing::after {
+ inset: -300px;
}
/* --- TRUST SECTION --- */
.trust {
- padding: var(--space-md) 5vw;
+ padding: var(--space-xs) 5vw;
border-top: 1px solid var(--color-border);
border-bottom: 1px solid var(--color-border);
background: var(--color-bg);
@@ -224,85 +296,153 @@
display: flex;
align-items: center;
justify-content: center;
- gap: 24px;
}
.apacheBrand {
font-family: var(--font-mono);
- font-size: 14px;
- letter-spacing: 0.1em;
+ font-size: 11px;
+ letter-spacing: 0.25em;
color: var(--color-text-tertiary);
text-transform: uppercase;
font-weight: 600;
}
+/* --- STATS SECTION --- */
+.statsGrid {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 0;
+ border-bottom: 1px solid var(--color-border);
+ max-width: var(--content-max);
+ margin: 0 auto;
+}
+
+.statCell {
+ background: var(--color-bg);
+ padding: var(--space-lg) var(--space-md);
+ text-align: center;
+ border-right: 1px solid var(--color-border);
+}
+
+.statCell:last-child {
+ border-right: none;
+}
+
+.statVal {
+ display: block;
+ font-size: clamp(3rem, 5vw, 5.5rem);
+ font-weight: 800;
+ line-height: 1;
+ letter-spacing: -0.06em;
+ color: var(--color-text-primary);
+ margin-bottom: 16px;
+}
+
+.statLab {
+ font-family: var(--font-mono);
+ font-size: 11px;
+ font-weight: 600;
+ color: var(--color-text-tertiary);
+ text-transform: uppercase;
+ letter-spacing: 0.25em;
+}
+
/* --- FEATURE WRAPPER --- */
.sectionContainer {
- padding: var(--space-2xl) 5vw;
+ padding: var(--space-xl) 5vw;
max-width: var(--content-max);
margin: 0 auto;
}
.sectionHeader {
- margin-bottom: var(--space-xl);
- max-width: 900px;
+ margin-bottom: var(--space-lg);
+ max-width: 1000px;
}
.sectionLabel {
display: inline-block;
font-family: var(--font-mono);
- font-size: 13px;
+ font-size: 11px;
font-weight: 700;
text-transform: uppercase;
- letter-spacing: 0.2em;
+ letter-spacing: 0.4em;
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-size: clamp(1.75rem, 4vw, 3rem);
+ line-height: 1.1;
font-weight: 800;
- letter-spacing: -0.03em;
+ letter-spacing: -0.04em;
color: var(--color-text-primary);
}
+.introContent {
+ max-width: 900px;
+}
+
+.introDesc {
+ font-size: clamp(1.1rem, 2vw, 1.35rem);
+ line-height: 1.6;
+ color: var(--color-text-secondary);
+ margin-top: var(--space-sm);
+ font-weight: 400;
+ max-width: 800px;
+}
+
/* --- GRID SYSTEM --- */
.bifrostGrid {
display: grid;
grid-template-columns: repeat(4, 1fr);
- gap: 32px;
+ gap: 1px;
+ background: var(--color-border);
+ border: 1px solid var(--color-border);
}
.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);
+ transition: all 0.5s cubic-bezier(0.16, 1, 0.3, 1);
position: relative;
display: flex;
flex-direction: column;
+ overflow: hidden;
+}
+
+html[data-theme='dark'] .bifrostCard {
+ background: rgba(26, 29, 35, 0.4);
+ backdrop-filter: blur(10px);
+ border: 1px solid rgba(255, 255, 255, 0.05);
}
.bifrostCard:hover {
- transform: translateY(-12px);
- border-color: var(--color-text-primary);
- box-shadow: 0 30px 60px rgba(0, 0, 0, 0.05);
+ background: var(--color-wash);
+ z-index: 10;
+ transform: translateY(-8px);
+}
+
+html[data-theme='dark'] .bifrostCard:hover {
+ background: rgba(26, 29, 35, 0.6);
+ border-color: var(--bifrost-blue);
}
.cardIcon {
- width: 60px;
- height: 60px;
- background: var(--color-wash);
- border-radius: var(--radius-sm);
- display: flex;
+ height: 32px;
+ padding: 0 12px;
+ background: var(--color-bg);
+ border: 1px solid var(--color-border-strong);
+ display: inline-flex;
align-items: center;
justify-content: center;
- font-size: 28px;
- margin-bottom: 32px;
+ font-family: var(--font-mono);
+ font-size: 11px;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ margin-bottom: var(--space-md);
transition: all 0.3s ease;
+ width: fit-content;
}
.bifrostCard:hover .cardIcon {
@@ -311,9 +451,9 @@
}
.cardTitle {
- font-size: 1.75rem;
- font-weight: 700;
- letter-spacing: -0.02em;
+ font-size: 1.5rem;
+ font-weight: 800;
+ letter-spacing: -0.03em;
margin-bottom: 20px;
color: var(--color-text-primary);
}
@@ -329,10 +469,10 @@
top: 0;
left: 0;
width: 100%;
- height: 4px;
+ height: 2px;
+ background: var(--bifrost-blue);
opacity: 0;
transition: opacity 0.3s ease;
- border-radius: var(--radius-md) var(--radius-md) 0 0;
}
.bifrostCard:hover .bifrostCardBorder {
@@ -342,22 +482,21 @@
/* --- TERMINAL --- */
.quickstart {
background: #000;
- border-radius: var(--radius-lg);
- padding: 60px;
+ padding: var(--space-lg);
position: relative;
overflow: hidden;
- box-shadow: 0 50px 100px rgba(0, 0, 0, 0.3);
+ box-shadow: 0 40px 80px rgba(0, 0, 0, 0.2);
}
.terminalOutput {
font-family: var(--font-mono);
- font-size: 1.25rem;
+ font-size: 1.125rem;
line-height: 1.8;
color: #fff;
}
.prompt {
- color: var(--bifrost-green);
+ color: var(--bifrost-blue);
margin-right: 16px;
}
@@ -365,7 +504,7 @@
display: inline-block;
width: 10px;
height: 24px;
- background: var(--bifrost-orange);
+ background: var(--bifrost-blue);
vertical-align: middle;
animation: blink 1s step-end infinite;
}
@@ -376,59 +515,37 @@
}
}
-/* --- 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);
+ padding: var(--space-xl) 5vw;
+ background: var(--color-bg);
+ border-top: 1px solid var(--color-border);
text-align: center;
position: relative;
+ overflow: hidden;
+}
+
+.finalCta::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background-image: radial-gradient(circle at center, var(--color-wash) 0%, transparent 70%);
+ opacity: 0.5;
}
.finalCtaTitle {
- font-size: clamp(2.5rem, 6vw, 4rem);
- /* Reduced from 8rem max to 4rem max */
+ font-size: clamp(2.5rem, 8vw, 5rem);
font-weight: 900;
- letter-spacing: -0.05em;
- line-height: 1.1;
+ letter-spacing: -0.06em;
+ line-height: 1;
margin-bottom: var(--space-lg);
color: var(--color-text-primary);
+ z-index: 10;
+ position: relative;
+ background: linear-gradient(to bottom, var(--color-text-primary), var(--color-text-secondary));
+ -webkit-background-clip: text;
+ background-clip: text;
+ -webkit-text-fill-color: transparent;
}
.finalCtaPrimary {
@@ -436,29 +553,23 @@
background: var(--color-text-primary);
color: var(--color-bg);
padding: 32px 80px;
- font-size: 1.5rem;
+ font-size: 1.75rem;
font-weight: 800;
text-decoration: none;
- border-radius: var(--radius-sm);
- transition: all 0.3s ease;
+ transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1);
+ z-index: 10;
+ position: relative;
+ border: 1px solid var(--color-text-primary);
}
.finalCtaPrimary:hover {
- transform: scale(1.05);
- background: var(--bifrost-blue);
- color: #fff;
+ background: var(--color-bg);
+ color: var(--color-text-primary);
+ transform: translateY(-4px);
}
/* --- RESPONSIVE --- */
@media (max-width: 1200px) {
- .heroContent {
- grid-template-columns: 1fr;
- }
-
- .heroVisual {
- display: none;
- }
-
.bifrostGrid {
grid-template-columns: repeat(2, 1fr);
}
@@ -466,6 +577,11 @@
.statsGrid {
grid-template-columns: 1fr;
}
+
+ .statCell {
+ border-right: none;
+ border-bottom: 1px solid var(--color-border);
+ }
}
@media (max-width: 768px) {
@@ -474,11 +590,11 @@
}
.heroTitle {
- font-size: 3rem;
+ font-size: 3.5rem;
}
.sectionTitle {
- font-size: 2.5rem;
+ font-size: 3rem;
}
.statVal {
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index f8180419..21c96dc0 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -34,35 +34,31 @@ export default function Home(): ReactNode {
{/* --- 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 className={styles.heroVisual}>
+ <div className={styles.bifrostRing}>
+ <div style={{ fontSize: '200px', fontWeight: 900, letterSpacing: '-0.1em', opacity: 0.1 }}>
+ BIFRO<span style={{ color: 'var(--bifrost-blue)' }}>MQ</span>
</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 className={styles.heroContent}>
+ <div className={styles.heroBadge}>
+ <div className={styles.heroBadgeDot} />
+ <span>Apache Incubating Project</span>
+ </div>
+ <h1 className={styles.heroTitle}>
+ Apache BifroMQ<span>(Incubating)</span>
+ </h1>
+ <p className={styles.heroDesc}>
+ Java-based high-performance Apache MQTT Broker messaging middleware that adopts Multi-tenancy architecture.
+ </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>
</section>
@@ -74,59 +70,51 @@ export default function Home(): ReactNode {
</div>
</section>
- {/* --- STATS SECTION --- */}
+ {/* --- WHAT IS BIFROMQ --- */}
<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 className={styles.introContent}>
+ <span className={styles.sectionLabel}>Overview</span>
+ <h2 className={styles.sectionTitle}>What is BifroMQ?</h2>
+ <p className={styles.introDesc}>
+ 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>
</section>
+ <div className={styles.bifrostDivider} />
+
{/* --- 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)"
+ tag="Full compliance"
+ title="100% MQTT Support"
+ desc="Fully supports MQTT 3.1, 3.1.1 and 5.0 features over TCP, TLS, WS, WSS. Complete protocol implementation with all advanced features."
+ icon="MQTT 3.1-5.0"
/>
<FeatureCard
- icon="⚡"
- title="Elastic Scaling"
- desc="Horizontally scalable compute and storage layers, enabling seamless growth without downtime."
- color="var(--bifrost-blue)"
+ tag="Self-contained"
+ title="Built-in Storage Engine"
+ desc="Optimized for critical load targeting, no third-party middleware dependencies. Deploy anywhere with confidence."
+ icon="Zero deps"
/>
<FeatureCard
- icon="🧩"
- title="Extensible Core"
- desc="Rich plugin system for auth, governance, and custom enterprise integrations."
- color="var(--bifrost-teal)"
+ tag="Resource isolation"
+ title="Native Multi-Tenancy"
+ desc="Built-in support for multi-tenancy resource sharing and workload isolation. Perfect for SaaS platforms and enterprise environments."
+ icon="Multi-tenant"
/>
<FeatureCard
- icon="📊"
- title="Full Telemetry"
- desc="Deep visibility into cluster health and tenant behavior with native monitoring support."
- color="var(--bifrost-violet)"
+ tag="Highly extensible"
+ title="Extensible Mechanisms"
+ desc="Supports extensions, including Authentication/Authorization, Event, and System/Tenant Monitoring. Rich plugin architecture."
+ icon="Plugin-ready"
/>
</div>
</section>
+ <div className={styles.bifrostDivider} />
+
{/* --- QUICK START SECTION --- */}
<section className={`${styles.sectionContainer} ${styles.reveal}`}>
<div className={styles.sectionHeader}>
@@ -144,35 +132,7 @@ export default function Home(): ReactNode {
</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>
+ <div className={styles.bifrostDivider} />
{/* --- FINAL CTA SECTION --- */}
<section className={`${styles.finalCta} ${styles.reveal}`}>
@@ -189,23 +149,24 @@ export default function Home(): ReactNode {
);
}
-function FeatureCard({ icon, title, desc, color }: { icon: string, title: string, desc: string, color: string }) {
+function FeatureCard({ tag, title, desc, icon }: { tag: string, title: string, desc: string, icon: string }) {
return (
<div className={styles.bifrostCard}>
- <div className={styles.bifrostCardBorder} style={{ background: color }} />
+ <div className={styles.bifrostCardBorder} />
+ <span className={styles.sectionLabel} style={{ fontSize: '10px', color: 'var(--color-text-tertiary)', marginBottom: '8px', letterSpacing: '0.1em' }}>{tag}</span>
+ <h3 className={styles.cardTitle} style={{ fontSize: '1.25rem', marginBottom: '16px' }}>{title}</h3>
<div className={styles.cardIcon}>{icon}</div>
- <h3 className={styles.cardTitle}>{title}</h3>
- <p className={styles.cardDesc}>{desc}</p>
+ <p className={styles.cardDesc} style={{ fontSize: '0.95rem' }}>{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 className={styles.bifrostCard} style={{ background: 'var(--color-wash)', border: 'none' }}>
+ <span className={styles.sectionLabel} style={{ fontSize: '10px', color: 'var(--color-text-tertiary)', marginBottom: '12px' }}>{tag}</span>
+ <h3 className={styles.cardTitle} style={{ fontSize: '1.25rem', marginBottom: '12px' }}>{title}</h3>
+ <p className={styles.cardDesc} style={{ fontSize: '0.9rem' }}>{desc}</p>
</div>
);
}