From 86ca9275f271d75093fe4ca9be4d42118df2a2d7 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Mon, 20 Apr 2026 18:56:51 +0000 Subject: [PATCH 01/10] update landing per convo with dave --- .../docusaurus-theme/css/product-picker.css | 7 +- .../NavbarItem/types/ProductPicker/index.tsx | 2 +- packages/test-site/docusaurus.config.ts | 41 ++-- packages/test-site/src/pages/index.module.css | 177 ++++++++++++++++-- packages/test-site/src/pages/index.tsx | 95 +++++++--- unified-doc/docusaurus.config.ts | 38 ++-- unified-doc/src/pages/index.module.css | 2 +- unified-doc/src/pages/index.tsx | 50 +++-- 8 files changed, 302 insertions(+), 110 deletions(-) diff --git a/packages/docusaurus-theme/css/product-picker.css b/packages/docusaurus-theme/css/product-picker.css index b884b6ac..8773fabd 100644 --- a/packages/docusaurus-theme/css/product-picker.css +++ b/packages/docusaurus-theme/css/product-picker.css @@ -170,11 +170,10 @@ /* ── Column headers ─────────────────────────────────────────────────────── */ .picker-header { - font-size: 0.7rem; - font-weight: 900; + font-size: 0.82rem; + font-weight: 800; color: #94a3b8; - text-transform: uppercase; - letter-spacing: 0.1em; + letter-spacing: 0.12em; border-bottom: 2px solid rgba(148, 163, 184, 0.2); display: block; padding-bottom: 0.5rem; diff --git a/packages/docusaurus-theme/theme/NavbarItem/types/ProductPicker/index.tsx b/packages/docusaurus-theme/theme/NavbarItem/types/ProductPicker/index.tsx index fce0d48d..2dc6e3c6 100644 --- a/packages/docusaurus-theme/theme/NavbarItem/types/ProductPicker/index.tsx +++ b/packages/docusaurus-theme/theme/NavbarItem/types/ProductPicker/index.tsx @@ -26,7 +26,7 @@ type Props = { className?: string; }; -const HEADER_CLASSES = ['picker-header--nf-tertiary', 'picker-header--nf-secondary', 'picker-header--nf-primary']; +const HEADER_CLASSES = ['picker-header--nf-tertiary', 'picker-header--nf-primary', 'picker-header--nf-secondary']; const NF_LOGO_DEFAULT = 'https://raw.githubusercontent.com/netfoundry/branding/refs/heads/main/images/svg/icon/netfoundry-icon-color.svg'; const buildDefaultColumns = (img: string, consoleLogo: string): PickerColumn[] => [ diff --git a/packages/test-site/docusaurus.config.ts b/packages/test-site/docusaurus.config.ts index f479cf79..57fd1e2b 100644 --- a/packages/test-site/docusaurus.config.ts +++ b/packages/test-site/docusaurus.config.ts @@ -107,6 +107,9 @@ export default { '@zlan': path.resolve(__dirname, `${zlan}/docusaurus`), '@zrok': path.resolve(__dirname, `${zrokRoot}`), '@zrokroot': path.resolve(__dirname, `${zrokRoot}`), + '@netfoundry/docusaurus-theme/ui': path.resolve(__dirname, '../docusaurus-theme/dist/src/ui.js'), + '@netfoundry/docusaurus-theme/plugins': path.resolve(__dirname, '../docusaurus-theme/dist/src/plugins.js'), + '@netfoundry/docusaurus-theme/node': path.resolve(__dirname, '../docusaurus-theme/dist/src/node.js'), }, }, }; @@ -133,7 +136,7 @@ export default { ], productPickerColumns: [ { - header: 'Managed Cloud', + header: 'Cloud SaaS', links: [ { label: 'NetFoundry Console', @@ -150,7 +153,24 @@ export default { ], }, { - header: 'Open Source', + header: 'Self-Hosted Licensed', + links: [ + { + label: 'Self-Hosted', + to: '/docs/selfhosted', + logo: 'https://netfoundry.io/docs/img/onprem-sm-logo.svg', + description: 'Deploy the full stack in your own environment.', + }, + { + label: 'zLAN', + to: '/docs/zlan', + logo: 'https://netfoundry.io/docs/img/zlan/zlan-logo.svg', + description: 'Zero-trust access for OT networks.', + }, + ], + }, + { + header: 'Self-Hosted Open Source', links: [ { label: 'OpenZiti', @@ -167,23 +187,6 @@ export default { }, ], }, - { - header: 'Your own infrastructure', - links: [ - { - label: 'Self-Hosted', - to: '/docs/selfhosted', - logo: 'https://netfoundry.io/docs/img/onprem-sm-logo.svg', - description: 'Deploy the full stack in your own environment.', - }, - { - label: 'zLAN', - to: '/docs/zlan', - logo: 'https://netfoundry.io/docs/img/zlan/zlan-logo.svg', - description: 'Zero-trust access for OT networks.', - }, - ], - }, ], resourcesPickerSections: [ { diff --git a/packages/test-site/src/pages/index.module.css b/packages/test-site/src/pages/index.module.css index 9f71a5da..39d44e7e 100644 --- a/packages/test-site/src/pages/index.module.css +++ b/packages/test-site/src/pages/index.module.css @@ -1,23 +1,166 @@ -/** - * CSS files with the .module.css suffix will be treated as CSS modules - * and scoped locally. - */ +.nf-hero-stage { + position: relative; width: 100%; min-height: 370px; + display: flex; align-items: center; justify-content: center; + overflow: hidden; text-align: center; background: #020617; z-index: 4; +} +.nf-hero-stage::after { + content: ''; position: absolute; bottom: 0; left: 0; right: 0; + height: 220px; background: linear-gradient(to bottom, transparent 0%, #0f172a 100%); + pointer-events: none; z-index: 1; +} +[data-theme='light'] .nf-hero-stage::after { + height: 80px; + background: linear-gradient(to bottom, transparent 0%, #020617 100%); +} +.nf-hero-overlay { display: none; } +.nf-hero-content { + position: relative; z-index: 2; padding: 2.5rem 3.5rem; + background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; +} +.nf-hero-title { + font-size: 4rem; font-weight: 900; color: #ffffff; margin-bottom: 0.75rem; + letter-spacing: -0.02em; line-height: 1.05; + text-shadow: 0 0 20px rgba(34, 211, 238, 0.8), 0 2px 12px rgba(0, 0, 0, 0.9); +} +.nf-green-text { + color: #22c55e; + font-family: inherit; font-weight: inherit; font-size: inherit; + text-shadow: 0 0 20px rgba(34, 197, 94, 0.75), 0 2px 12px rgba(0, 0, 0, 0.9); +} +.nf-hero-subtext { + color: rgba(203, 213, 225, 0.95); font-size: 1.15rem; max-width: 560px; + margin: 0 auto 2rem; line-height: 1.65; text-shadow: 0 1px 8px rgba(0, 0, 0, 0.95); +} +.nf-hero-ctas { display: flex; gap: 1rem; justify-content: center; } +.nf-btn-primary { + display: inline-flex; align-items: center; padding: 0.65rem 1.75rem; + background: #0076FF; color: #ffffff; border-radius: 8px; font-weight: 700; + font-size: 0.95rem; text-decoration: none; transition: all 0.25s ease; border: 2px solid #0076FF; +} +.nf-btn-primary:hover { + background: #005ce6; border-color: #005ce6; transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(0, 118, 255, 0.4); color: #ffffff; text-decoration: none; +} +.nf-btn-ghost { + display: inline-flex; align-items: center; padding: 0.65rem 1.75rem; + background: transparent; color: #ffffff; border-radius: 8px; font-weight: 700; + font-size: 0.95rem; text-decoration: none; transition: all 0.25s ease; + border: 2px solid rgba(255, 255, 255, 0.25); +} +.nf-btn-ghost:hover { + background: rgba(255, 255, 255, 0.06); border-color: rgba(34, 211, 238, 0.5); + transform: translateY(-2px); color: #ffffff; text-decoration: none; +} +[data-theme='dark'] .nf-btn-primary, +[data-theme='dark'] .nf-btn-primary:hover, +[data-theme='dark'] .nf-btn-ghost, +[data-theme='dark'] .nf-btn-ghost:hover { color: #ffffff; text-decoration: none; } + +.nf-features-section { width: 100%; background: #0f172a; padding: 5rem 0 2.5rem; } +[data-theme='light'] .nf-features-section { + background: linear-gradient(to bottom, + #020617 0px, #020617 80px, #404350 18%, #7d808a 28%, + #b8bbc1 38%, #e4e7ea 48%, #f8fafc 100%); +} + +.nf-bento-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; } + +.nf-bento-divider { + grid-column: 1 / -1; display: flex; align-items: center; gap: 1rem; + padding: 1.5rem 0 0.65rem; color: #94a3b8; font-size: 0.82rem; font-weight: 800; + letter-spacing: 0.12em; white-space: nowrap; +} +.nf-bento-divider::before, .nf-bento-divider::after { + content: ''; flex: 1; height: 1px; background: rgba(148, 163, 184, 0.2); +} +.nf-divider--top { padding-top: 0; } +.nf-divider--managed { + color: #22d3ee; font-size: 1.05rem; letter-spacing: 0.15em; + text-shadow: 0 0 18px rgba(34, 211, 238, 0.5); +} +.nf-divider--managed::before, .nf-divider--managed::after { background: rgba(34, 211, 238, 0.4); height: 2px; } +[data-theme='light'] .nf-bento-divider { color: #64748b; } +[data-theme='light'] .nf-bento-divider::before, +[data-theme='light'] .nf-bento-divider::after { background: rgba(100, 116, 139, 0.25); } +[data-theme='light'] .nf-divider--managed { color: #0891b2; text-shadow: none; } +[data-theme='light'] .nf-divider--managed::before, +[data-theme='light'] .nf-divider--managed::after { background: rgba(8, 145, 178, 0.35); height: 2px; } -.heroBanner { - padding: 4rem 0; - text-align: center; - position: relative; - overflow: hidden; +.nf-pair { display: flex; flex-direction: column; } +.nf-pair-connector { + display: flex; align-items: center; gap: 1rem; padding: 0.5rem 0; + font-size: 0.7rem; font-weight: 800; letter-spacing: 0.12em; + text-transform: uppercase; color: #94a3b8; +} +.nf-pair-connector::before, .nf-pair-connector::after { + content: ''; flex: 1; height: 1px; background: rgba(148, 163, 184, 0.2); } +[data-theme='light'] .nf-pair-connector { color: #64748b; } +[data-theme='light'] .nf-pair-connector::before, +[data-theme='light'] .nf-pair-connector::after { background: rgba(148, 163, 184, 0.35); } -@media screen and (max-width: 996px) { - .heroBanner { - padding: 2rem; - } +.nf-bento-wrap { display: flex; flex-direction: column; } + +.nf-bento-card { + position: relative; display: flex; flex-direction: column; flex: 1; + padding: 1rem; border-radius: 12px; text-decoration: none; + background: #1a1b2e; border: 1px solid rgba(148, 163, 184, 0.1); + border-top: 2px solid #22d3ee; + box-shadow: 0 1px 3px rgba(0,0,0,0.3), 0 6px 20px rgba(0,0,0,0.3), 0 16px 40px rgba(0,0,0,0.2); + transition: transform 0.2s ease, box-shadow 0.2s ease, border-top-color 0.2s ease; +} +.nf-bento-card:hover { + transform: translateY(-4px); border-top-color: #22c55e; color: inherit; text-decoration: none; + box-shadow: 0 2px 6px rgba(0,0,0,0.4), 0 12px 32px rgba(0,0,0,0.45), + 0 24px 60px rgba(0,0,0,0.25), 0 0 0 1px rgba(34,197,94,0.12); +} +[data-theme='light'] .nf-bento-card { + background: #edf3f8; border-color: rgba(0,0,0,0.08); + box-shadow: 0 1px 3px rgba(0,0,0,0.06), 0 4px 14px rgba(0,0,0,0.05); +} +[data-theme='light'] .nf-bento-card:hover { + box-shadow: 0 2px 6px rgba(0,0,0,0.09), 0 8px 24px rgba(0,0,0,0.07), 0 0 0 1px rgba(34,197,94,0.18); } +.nf-bento-card--accent-cyan { border-top-color: #22d3ee; } +.nf-bento-card--accent-green { border-top-color: #22c55e; } +[data-theme='light'] .nf-bento-card--accent-cyan { border-top-color: #0068f9; } +[data-theme='light'] .nf-bento-card--accent-green { border-top-color: #16a34a; } +.nf-bento-card--featured { padding: 1.25rem; border-top-width: 3px; } +.nf-bento-card--featured .nf-card-logo { width: 48px; height: 48px; } +.nf-bento-card--featured .nf-card-header h3 { font-size: 1.25rem; } -.buttons { - display: flex; - align-items: center; - justify-content: center; +.nf-card-badge { + position: absolute; top: 1rem; right: 1rem; display: inline-flex; width: fit-content; + background: rgba(34,197,94,0.1); color: #4ade80; border: 1px solid rgba(34,197,94,0.2); + font-size: 0.6rem; font-weight: 800; letter-spacing: 0.1em; + padding: 2px 8px; border-radius: 4px; text-transform: uppercase; +} +[data-theme='light'] .nf-card-badge { color: #15803d; border-color: rgba(34,197,94,0.25); } + +.nf-card-header { + display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem; padding-right: 3rem; +} +.nf-card-header h3 { margin: 0; } +.nf-bento-card h3 { color: #f1f5f9; font-weight: 900; font-size: 1.05rem; line-height: 1.3; letter-spacing: -0.02em; } +[data-theme='light'] .nf-bento-card h3 { color: #0f172a; } +.nf-bento-card p { color: #94a3b8; font-size: 0.875rem; line-height: 1.65; flex-grow: 1; margin: 0 0 0.5rem; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } +[data-theme='light'] .nf-bento-card p { color: #475569; } + +.nf-bento-features { list-style: none; padding: 0; margin: 0 0 0.5rem; display: flex; flex-direction: column; gap: 0.25rem; } +.nf-bento-features li { display: flex; align-items: center; gap: 0.4rem; font-size: 0.775rem; color: #64748b; } +.nf-bento-features li::before { content: '✓'; color: #22c55e; font-weight: 800; font-size: 0.75rem; flex-shrink: 0; } +[data-theme='light'] .nf-bento-features li::before { color: #16a34a; } + +.nf-card-link { color: #22d3ee; font-size: 0.8rem; font-weight: 700; margin-top: auto; padding-top: 0.5rem; letter-spacing: 0.03em; } +[data-theme='light'] .nf-card-link { color: #0284c7; } +.nf-card-logo { width: 40px; height: 40px; object-fit: contain; flex-shrink: 0; } + +@media (max-width: 996px) { + .nf-hero-title { font-size: 2.2rem; } + .nf-hero-content { padding: 2rem 1.25rem; } + .nf-hero-ctas { flex-wrap: wrap; } + .nf-btn-primary, .nf-btn-ghost { padding: 0.55rem 1.25rem; font-size: 0.9rem; } +} +@media (max-width: 640px) { + .nf-bento-grid { grid-template-columns: 1fr; } } diff --git a/packages/test-site/src/pages/index.tsx b/packages/test-site/src/pages/index.tsx index 8c4367f0..86b5db0e 100644 --- a/packages/test-site/src/pages/index.tsx +++ b/packages/test-site/src/pages/index.tsx @@ -2,7 +2,9 @@ import React, {JSX} from 'react'; import Layout from '@theme/Layout'; import Link from '@docusaurus/Link'; import clsx from 'clsx'; -import styles from './landing.module.css'; +import styles from './index.module.css'; + +const DOCS_BASE = '/docs/'; const CYAN = '#22d3ee'; const GREEN = '#22c55e'; @@ -10,12 +12,66 @@ const IMG = 'https://netfoundry.io/docs/img'; const NF_LOGO = 'https://raw.githubusercontent.com/netfoundry/branding/refs/heads/main/images/svg/icon/netfoundry-icon-color.svg'; const products = [ - { id: 'console', title: 'NetFoundry Console', logo: NF_LOGO, tag: 'Managed', accent: CYAN, link: '#', features: ['Fully managed SaaS', 'Global edge fabric', 'No infra to operate', 'Policy-based access'], description: "The cloud-managed control plane for NetFoundry's global zero-trust fabric. Orchestrate identities, policies, and edge routers — no infrastructure to run." }, - { id: 'openziti', title: 'OpenZiti', logo: `${IMG}/openziti-sm-logo.svg`, tag: 'Open Source', accent: GREEN, link: '/docs/openziti', description: 'The open-source zero-trust networking framework at the heart of the NetFoundry platform. Embed dark, app-native security directly in your code — no VPN, no perimeter.' }, - { id: 'frontdoor', title: 'Frontdoor', logo: `${IMG}/frontdoor-sm-logo.svg`, tag: 'Managed', accent: CYAN, link: '/docs/frontdoor', features: ['No agent or VPN required', 'Zero firewall rules', 'Identity-based access', 'Any app, any browser'], description: 'Secure, clientless access to any application — without a VPN or firewall rule. Expose nothing to the internet while giving authorized users instant access.' }, - { id: 'zrok', title: 'zrok', logo: `${IMG}/zrok-1.0.0-rocket-purple.svg`, tag: 'Open Source', accent: GREEN, link: '/docs/zrok', description: 'Geo-scale secure sharing built on the OpenZiti mesh. Share services, files, or HTTP endpoints peer-to-peer — no open ports, no NAT traversal tricks.' }, - { id: 'selfhosted', title: 'NetFoundry Self-Hosted', logo: `${IMG}/onprem-sm-logo.svg`, tag: 'Self-Hosted', accent: CYAN, link: '/docs/onprem', features: ['Full infrastructure control', 'Air-gap compatible', 'On-prem or any cloud', 'Enterprise SLA'], description: 'Deploy the full NetFoundry control plane and fabric in your own environment. Full sovereignty over your zero-trust infrastructure — on-prem, air-gapped, or any cloud.' }, - { id: 'zlan', title: 'zLAN', logo: `${IMG}/zlan-logo.svg`, tag: 'OT Security', accent: CYAN, link: '/docs/zlan', features: ['Deep OT/IT traffic visibility', 'Identity-aware micro-segmentation', 'Centralized zero-trust policy', 'Built on NetFoundry Self-Hosted'], description: 'Identity-aware micro-segmentation firewall for operational technology networks. Deep traffic visibility, centralized policy, and zero-trust access control for OT environments.' }, + { + id: 'console', + title: 'NetFoundry Console', + logo: NF_LOGO, + tag: 'SaaS', + accent: CYAN, + link: `${DOCS_BASE}platform/intro`, + features: ['Enterprise-grade support (24×7)', 'Fully managed by NetFoundry with 99.95% uptime SLA', 'Guidance for resilient, scalable production architecture', 'FIPS compliant'], + description: "NetFoundry's fully managed control plane for zero-trust networking. Orchestrate identities, policies, and edge routers." + }, + { + id: 'openziti', + title: 'OpenZiti', + logo: `${IMG}/openziti-sm-logo.svg`, + tag: 'Open Source', + accent: GREEN, + link: `${DOCS_BASE}openziti/learn/introduction`, + features: ['Community support', 'Self-deployed and managed, self-orchestrated'], + description: 'The open-source zero-trust framework behind NetFoundry. Embed app-native security in your code—no VPN, no perimeter.' + }, + { + id: 'frontdoor', + title: 'Frontdoor', + logo: `${IMG}/frontdoor-sm-logo.svg`, + tag: 'SaaS', + accent: CYAN, + link: `${DOCS_BASE}frontdoor/intro`, + features: ['Enterprise-grade support (24×7)', 'Fully managed by NetFoundry with 99.95% uptime SLA', 'Guidance for resilient, scalable production architecture', 'FIPS compliant'], + description: 'Secure, clientless access to any application—without a VPN or firewall rule. Expose nothing to the internet while giving authorized users instant access.' + }, + { + id: 'zrok', + title: 'zrok', + logo: `${IMG}/zrok-1.0.0-rocket-purple.svg`, + tag: 'Open Source', + accent: GREEN, + link: `${DOCS_BASE}zrok`, + features: ['Community support', 'Self-deployed and managed, self-orchestrated'], + description: 'Geo-scale secure sharing built on the OpenZiti mesh. Share services, files, or HTTP endpoints peer-to-peer—no open ports, no NAT traversal tricks.' + }, + { + id: 'selfhosted', + title: 'NetFoundry Self-Hosted', + logo: `${IMG}/onprem-sm-logo.svg`, + tag: 'Self-Hosted', + accent: CYAN, + link: `${DOCS_BASE}selfhosted/intro`, + features: ['Enterprise-grade support (24×7)', 'Self-deployed and managed, self-orchestrated', 'Guidance for resilient, scalable production architecture'], + description: 'Run the full NetFoundry stack in your own environment. On-prem, air-gapped, or any cloud. You own the infrastructure.' + }, + { + id: 'zlan', + title: 'zLAN', + logo: `${IMG}/zlan/zlan-logo.svg`, + tag: 'OT Security', + accent: CYAN, + link: `${DOCS_BASE}zlan/intro`, + features: ['Deep OT/IT traffic visibility', 'Identity-aware micro-segmentation', 'Centralized zero-trust policy'], + description: 'Identity-aware micro-segmentation for OT networks. Deep traffic visibility, centralized policy, and zero-trust access control.' + }, ]; type Product = (typeof products)[number]; @@ -25,7 +81,7 @@ function BentoCard({product, featured = false}: {product: Product; featured?: bo const accentMod = product.accent === CYAN ? styles['nf-bento-card--accent-cyan'] : styles['nf-bento-card--accent-green']; return (
- + {product.tag}
{product.logo && {product.title}} @@ -49,9 +105,9 @@ export default function Home(): JSX.Element {

NetFoundry Docs

-

Secure, high-performance networking for the modern era.

+

Secure Your Workloads with Identity-First Connectivity™

- Get Started + Get Started Request Demo
@@ -59,20 +115,15 @@ export default function Home(): JSX.Element {
-
Managed Cloud
-
- -
open-source counterpart
- -
-
- -
open-source counterpart
- -
-
Run on your own infrastructure
+
Cloud SaaS
+ + +
Self-Hosted Licensed
+
Self-Hosted Open Source
+ +
diff --git a/unified-doc/docusaurus.config.ts b/unified-doc/docusaurus.config.ts index 85c4910f..331b92ad 100644 --- a/unified-doc/docusaurus.config.ts +++ b/unified-doc/docusaurus.config.ts @@ -430,7 +430,7 @@ const config: Config = { ], productPickerColumns: [ { - header: 'Managed Cloud', + header: 'Cloud SaaS', links: [ { label: 'NetFoundry Console', @@ -447,7 +447,24 @@ const config: Config = { ], }, { - header: 'Open Source', + header: 'Self-Hosted Licensed', + links: [ + { + label: 'Self-Hosted', + to: '/docs/selfhosted/intro', + logo: 'https://netfoundry.io/docs/img/onprem-sm-logo.svg', + description: 'Deploy the full stack in your own environment.', + }, + { + label: 'zLAN', + to: '/docs/zlan/intro', + logo: 'https://netfoundry.io/docs/img/zlan/zlan-logo.svg', + description: 'Zero-trust access for OT networks.', + }, + ], + }, + { + header: 'Self-Hosted Open Source', links: [ { label: 'OpenZiti', @@ -464,23 +481,6 @@ const config: Config = { }, ], }, - { - header: 'Your own infrastructure', - links: [ - { - label: 'Self-Hosted', - to: '/docs/selfhosted/intro', - logo: 'https://netfoundry.io/docs/img/onprem-sm-logo.svg', - description: 'Deploy the full stack in your own environment.', - }, - { - label: 'zLAN', - to: '/docs/zlan/intro', - logo: 'https://netfoundry.io/docs/img/zlan/zlan-logo.svg', - description: 'Zero-trust access for OT networks.', - }, - ], - }, ], }, navbar: { diff --git a/unified-doc/src/pages/index.module.css b/unified-doc/src/pages/index.module.css index ff73e7a4..ab1631e3 100644 --- a/unified-doc/src/pages/index.module.css +++ b/unified-doc/src/pages/index.module.css @@ -141,7 +141,7 @@ .nf-card-header h3 { margin: 0; } .nf-bento-card h3 { color: #f1f5f9; font-weight: 900; font-size: 1.05rem; line-height: 1.3; letter-spacing: -0.02em; } [data-theme='light'] .nf-bento-card h3 { color: #0f172a; } -.nf-bento-card p { color: #94a3b8; font-size: 0.875rem; line-height: 1.65; flex-grow: 1; margin: 0 0 0.5rem; } +.nf-bento-card p { color: #94a3b8; font-size: 0.875rem; line-height: 1.65; flex-grow: 1; margin: 0 0 0.5rem; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } [data-theme='light'] .nf-bento-card p { color: #475569; } .nf-bento-features { list-style: none; padding: 0; margin: 0 0 0.5rem; display: flex; flex-direction: column; gap: 0.25rem; } diff --git a/unified-doc/src/pages/index.tsx b/unified-doc/src/pages/index.tsx index 7d998606..95d10a0d 100644 --- a/unified-doc/src/pages/index.tsx +++ b/unified-doc/src/pages/index.tsx @@ -15,11 +15,11 @@ const products = [ id: 'console', title: 'NetFoundry Console', logo: NF_LOGO, - tag: 'Managed', + tag: 'SaaS', accent: CYAN, link: `${DOCS_BASE}platform/intro`, - features: ['Fully managed SaaS', 'Global edge fabric', 'No infra to operate', 'Policy-based access'], - description: "The cloud-managed control plane for NetFoundry's global zero-trust fabric. Orchestrate identities, policies, and edge routers — no infrastructure to run." + features: ['Enterprise-grade support (24×7)', 'Fully managed by NetFoundry with 99.95% uptime SLA', 'Guidance for resilient, scalable production architecture', 'FIPS compliant'], + description: "NetFoundry's fully managed control plane for zero-trust networking. Orchestrate identities, policies, and edge routers." }, { id: 'openziti', @@ -28,17 +28,18 @@ const products = [ tag: 'Open Source', accent: GREEN, link: `${DOCS_BASE}openziti/learn/introduction`, - description: 'The open-source zero-trust networking framework at the heart of the NetFoundry platform. Embed dark, app-native security directly in your code — no VPN, no perimeter.' + features: ['Community support', 'Self-deployed and managed, self-orchestrated'], + description: 'The open-source zero-trust framework behind NetFoundry. Embed app-native security in your code—no VPN, no perimeter.' }, { id: 'frontdoor', title: 'Frontdoor', logo: `${IMG}/frontdoor-sm-logo.svg`, - tag: 'Managed', + tag: 'SaaS', accent: CYAN, link: `${DOCS_BASE}frontdoor/intro`, - features: ['No agent or VPN required', 'Zero firewall rules', 'Identity-based access', 'Any app, any browser'], - description: 'Secure, clientless access to any application — without a VPN or firewall rule. Expose nothing to the internet while giving authorized users instant access.' + features: ['Enterprise-grade support (24×7)', 'Fully managed by NetFoundry with 99.95% uptime SLA', 'Guidance for resilient, scalable production architecture', 'FIPS compliant'], + description: 'Secure, clientless access to any application—without a VPN or firewall rule. Expose nothing to the internet while giving authorized users instant access.' }, { id: 'zrok', @@ -47,18 +48,18 @@ const products = [ tag: 'Open Source', accent: GREEN, link: `${DOCS_BASE}zrok`, - description: 'Geo-scale secure sharing built on the OpenZiti mesh. Share services, files, or HTTP endpoints peer-to-peer — no open ports, no NAT traversal tricks.' + features: ['Community support', 'Self-deployed and managed, self-orchestrated'], + description: 'Geo-scale secure sharing built on the OpenZiti mesh. Share services, files, or HTTP endpoints peer-to-peer—no open ports, no NAT traversal tricks.' }, { - id: - 'selfhosted', + id: 'selfhosted', title: 'NetFoundry Self-Hosted', logo: `${IMG}/onprem-sm-logo.svg`, tag: 'Self-Hosted', accent: CYAN, link: `${DOCS_BASE}selfhosted/intro`, - features: ['Full infrastructure control', 'Air-gap compatible', 'On-prem or any cloud', 'Enterprise SLA'], - description: 'Deploy the full NetFoundry control plane and fabric in your own environment. Full sovereignty over your zero-trust infrastructure — on-prem, air-gapped, or any cloud.' + features: ['Enterprise-grade support (24×7)', 'Self-deployed and managed, self-orchestrated', 'Guidance for resilient, scalable production architecture'], + description: 'Run the full NetFoundry stack in your own environment. On-prem, air-gapped, or any cloud. You own the infrastructure.' }, { id: 'zlan', @@ -67,8 +68,8 @@ const products = [ tag: 'OT Security', accent: CYAN, link: `${DOCS_BASE}zlan/intro`, - features: ['Deep OT/IT traffic visibility', 'Identity-aware micro-segmentation', 'Centralized zero-trust policy', 'Built on NetFoundry Self-Hosted'], - description: 'Identity-aware micro-segmentation firewall for operational technology networks. Deep traffic visibility, centralized policy, and zero-trust access control for OT environments.' + features: ['Deep OT/IT traffic visibility', 'Identity-aware micro-segmentation', 'Centralized zero-trust policy'], + description: 'Identity-aware micro-segmentation for OT networks. Deep traffic visibility, centralized policy, and zero-trust access control.' }, ]; @@ -79,7 +80,7 @@ function BentoCard({product, featured = false}: {product: Product; featured?: bo const accentMod = product.accent === CYAN ? styles['nf-bento-card--accent-cyan'] : styles['nf-bento-card--accent-green']; return (
- + {product.tag}
{product.logo && {product.title}} @@ -113,20 +114,15 @@ export default function Home(): JSX.Element {
-
Managed Cloud
-
- -
open-source counterpart
- -
-
- -
open-source counterpart
- -
-
Run on your own infrastructure
+
Cloud SaaS
+ + +
Self-Hosted Licensed
+
Self-Hosted Open Source
+ +
From 74cb5bb4e67f44571dc1ce1951bf1c7cb61985dc Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Wed, 22 Apr 2026 17:14:00 +0000 Subject: [PATCH 02/10] updates --- packages/test-site/docusaurus.config.ts | 1 + packages/test-site/src/custom/custom.css | 24 +++++- .../test-site/src/theme/DocSearch/index.tsx | 77 +++++++++++++++++++ .../src/theme/DocSearch/styles.module.css | 12 +++ .../test-site/src/theme/Navbar/Logo/index.tsx | 74 ++++++++++++++++++ 5 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 packages/test-site/src/theme/DocSearch/index.tsx create mode 100644 packages/test-site/src/theme/DocSearch/styles.module.css create mode 100644 packages/test-site/src/theme/Navbar/Logo/index.tsx diff --git a/packages/test-site/docusaurus.config.ts b/packages/test-site/docusaurus.config.ts index 57fd1e2b..165efb6e 100644 --- a/packages/test-site/docusaurus.config.ts +++ b/packages/test-site/docusaurus.config.ts @@ -80,6 +80,7 @@ export default { staticDirectories: [ 'static', + '../../unified-doc/static', `${frontdoor}/docusaurus/static`, `${onprem}/docusaurus/static`, `${openziti}/docusaurus/static`, diff --git a/packages/test-site/src/custom/custom.css b/packages/test-site/src/custom/custom.css index ca8a8153..25a6d819 100644 --- a/packages/test-site/src/custom/custom.css +++ b/packages/test-site/src/custom/custom.css @@ -1,6 +1,8 @@ @import '@netfoundry/docusaurus-theme/css/tabs-v8-float.css'; @import '@netfoundry/docusaurus-theme/css/layout.css'; +@import '@netfoundry/docusaurus-theme/css/legacy.css'; +@import '@docsearch/css'; :root { --ifm-navbar-height: 60px; @@ -36,8 +38,15 @@ body, justify-content: end; min-width: 185px; } +.navbar__logo_nf { /* squeeze whitespace */ + margin-right: 0; + height: var(--ifm-navbar-height); +} .navbar__logo { /* squeeze whitespace */ margin-right: 0; + height: 40px; + width: 40px; + margin-left: 10px; } .clean-btn svg { /* @@ -49,9 +58,22 @@ body, } .DocSearch-Button { - background: #ebedf0; + background: rgba(0, 0, 0, 0.06); color: var(--ifm-color-primary); } +.DocSearch-Button-Key { + background: rgba(0, 0, 0, 0.08); + color: rgba(0, 0, 0, 0.5); + border-color: rgba(0, 0, 0, 0.15); +} +[data-theme='dark'] .DocSearch-Button { + background: rgba(255, 255, 255, 0.08); +} +[data-theme='dark'] .DocSearch-Button-Key { + background: rgba(255, 255, 255, 0.1); + color: rgba(255, 255, 255, 0.6); + border-color: rgba(255, 255, 255, 0.2); +} .main-wrapper { diff --git a/packages/test-site/src/theme/DocSearch/index.tsx b/packages/test-site/src/theme/DocSearch/index.tsx new file mode 100644 index 00000000..b7954905 --- /dev/null +++ b/packages/test-site/src/theme/DocSearch/index.tsx @@ -0,0 +1,77 @@ +// src/theme/DocSearch/index.tsx +import React, { useMemo, useState, useEffect } from "react"; +import OriginalDocSearch from "@theme-original/DocSearch"; +import type { Props } from "@theme/DocSearch"; +import { createPortal } from "react-dom"; +import styles from "./styles.module.css"; + +const PRODUCTS = ["frontdoor", "openziti", "selfhosted", "zlan"] as const; + +function Pills({ + product, + setProduct, + }: { + product: string; + setProduct: (v: string) => void; +}) { + const [host, setHost] = useState(null); + + useEffect(() => { + const el = + document.querySelector(".DocSearch-Modal .DocSearch-Form")?.parentElement ?? + null; + setHost(el || null); + }, []); + + if (!host) return null; + + return createPortal( +
+ + {PRODUCTS.map((p) => ( + + ))} +
, + host + ); +} + +export default function DocSearchWrapper(props: Props) { + const [product, setProduct] = useState(""); + + const transformSearchParameters = useMemo( + () => + (params: any) => ({ + ...params, + facetFilters: [ + ...(params.facetFilters ?? []), + ...(product ? [`product:${product}`] : []), + ], + }), + [product] + ); + + return ( + <> + + + {/* "Search by Algolia" is already shown in the modal footer */} + + ); +} diff --git a/packages/test-site/src/theme/DocSearch/styles.module.css b/packages/test-site/src/theme/DocSearch/styles.module.css new file mode 100644 index 00000000..f1410c93 --- /dev/null +++ b/packages/test-site/src/theme/DocSearch/styles.module.css @@ -0,0 +1,12 @@ +/* src/theme/DocSearch/styles.module.css */ +.pills{ + display:flex;gap:.4rem;align-items:center;margin-top:.4rem; + padding:.25rem .25rem .35rem .25rem;flex-wrap:wrap +} +.pill{ + padding:.35rem .7rem;border:1px solid var(--ifm-color-emphasis-300); + border-radius:999px;background:transparent;cursor:pointer;font-size:.85rem +} +.active{ + background:var(--ifm-color-primary);color:#fff;border-color:var(--ifm-color-primary) +} diff --git a/packages/test-site/src/theme/Navbar/Logo/index.tsx b/packages/test-site/src/theme/Navbar/Logo/index.tsx new file mode 100644 index 00000000..68d34bb4 --- /dev/null +++ b/packages/test-site/src/theme/Navbar/Logo/index.tsx @@ -0,0 +1,74 @@ +import React, {JSX} from 'react'; +import Link from '@docusaurus/Link'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import {useLocation} from '@docusaurus/router'; +import type {DocusaurusConfig} from "@docusaurus/types/src/config"; +import ThemedImage from "@theme/ThemedImage"; + +const mapTitle = (p: string) => { + // Extract the root project segment, skipping optional /docs/ prefix + const segments = p.split('/'); + const rootSegment = segments[1] === 'docs' ? segments[2] : segments[1]; + const checkPath = (segment: string) => rootSegment === segment; + + if (checkPath('frontdoor')) return {includeNFLogo: true, to: '/docs/frontdoor', alt:'Frontdoor', logoLight: `/img/frontdoor-sm-logo.svg`, logoDark: `/img/frontdoor-sm-logo.svg`}; + if (checkPath('selfhosted')) return {includeNFLogo: true, to: '/docs/selfhosted',alt:'Self-Hosted', logoLight: `/img/onprem-sm-logo.svg`, logoDark: `/img/onprem-sm-logo.svg`}; + if (checkPath('openziti')) return {includeNFLogo: true, to: '/docs/openziti',alt:'OpenZiti', logoLight: `/img/openziti-sm-logo.svg`, logoDark: `/img/openziti-sm-logo.svg`}; + if (checkPath('zlan')) return {includeNFLogo: true, to: '/docs/zlan', alt:'zlan', logoLight: `/img/zlan/zlan-logo.svg`, logoDark: `/img/zlan/zlan-logo.svg`}; + if (checkPath('zrok')) return {text: '', includeNFLogo: true, to: '/docs/zrok', alt:'zrok', logoLight: `/img/zrok-1.0.0-rocket-purple.svg`, logoDark: `/img/zrok-1.0.0-rocket-green.svg`}; + return { + includeNFLogo: false, + to: '/', + alt:'NetFoundry', + logoLight: '', + logoDark: '' + }; +}; + +function navbarpoke(cfg:DocusaurusConfig) { + // console.log("A:" + JSON.stringify(cfg?.themeConfig?.navbar)); +} + +export default function NavbarLogo(): JSX.Element { + const {siteConfig} = useDocusaurusContext(); + const {pathname} = useLocation(); + const title = mapTitle(pathname); + navbarpoke(siteConfig); + + const nfLogoLight = useBaseUrl('/img/netfoundry-name-and-logo.svg'); + const nfLogoDark = useBaseUrl('/img/netfoundry-name-and-logo-dark.svg'); + const logoLight = useBaseUrl(title.logoLight); + const logoDark = useBaseUrl(title.logoDark); + + return ( + <> + + + + {(title.logoLight || title.text) && ( + + {title.logoLight && ( + + )} + {title.text && {title.text}} + + )} + + ); + +} From b3dcd0cae48b9bdb1d31f3aea9717e20728e2901 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Wed, 22 Apr 2026 18:18:31 +0000 Subject: [PATCH 03/10] revert unified-doc --- unified-doc/docusaurus.config.ts | 61 +++++++++++--------------- unified-doc/src/pages/index.module.css | 2 +- unified-doc/src/pages/index.tsx | 50 +++++++++++---------- 3 files changed, 53 insertions(+), 60 deletions(-) diff --git a/unified-doc/docusaurus.config.ts b/unified-doc/docusaurus.config.ts index 331b92ad..8d036667 100644 --- a/unified-doc/docusaurus.config.ts +++ b/unified-doc/docusaurus.config.ts @@ -14,7 +14,9 @@ import {pluginHotjar, pluginReo} from "@netfoundry/docusaurus-theme/node"; import {PublishConfig} from 'src/components/docusaurus' import {zrokDocsPluginConfig, zrokRedirects} from "./_remotes/zrok/website/docusaurus-plugin-zrok-docs.ts"; import {onpremRedirects} from "./_remotes/selfhosted/docusaurus/docusaurus-plugin-onprem-docs.ts"; -import {platformDocsPluginConfig} from "./_remotes/platform/docusaurus/docusaurus-plugin-platform-docs.ts"; +import {platformDocsPluginConfig, platformRedocSpecs} from "./_remotes/platform/docusaurus/docusaurus-plugin-platform-docs.ts"; +import {frontdoorRedocSpecs} from "./_remotes/frontdoor/docusaurus/docusaurus-plugin-frontdoor-docs.ts"; +import {openzitiRedocSpecs} from "./_remotes/openziti/docusaurus/docusaurus-plugin-openziti-docs.ts"; // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) const frontdoor = `./_remotes/frontdoor`; @@ -430,7 +432,7 @@ const config: Config = { ], productPickerColumns: [ { - header: 'Cloud SaaS', + header: 'Managed Cloud', links: [ { label: 'NetFoundry Console', @@ -447,24 +449,7 @@ const config: Config = { ], }, { - header: 'Self-Hosted Licensed', - links: [ - { - label: 'Self-Hosted', - to: '/docs/selfhosted/intro', - logo: 'https://netfoundry.io/docs/img/onprem-sm-logo.svg', - description: 'Deploy the full stack in your own environment.', - }, - { - label: 'zLAN', - to: '/docs/zlan/intro', - logo: 'https://netfoundry.io/docs/img/zlan/zlan-logo.svg', - description: 'Zero-trust access for OT networks.', - }, - ], - }, - { - header: 'Self-Hosted Open Source', + header: 'Open Source', links: [ { label: 'OpenZiti', @@ -481,6 +466,23 @@ const config: Config = { }, ], }, + { + header: 'Your own infrastructure', + links: [ + { + label: 'Self-Hosted', + to: '/docs/selfhosted/intro', + logo: 'https://netfoundry.io/docs/img/onprem-sm-logo.svg', + description: 'Deploy the full stack in your own environment.', + }, + { + label: 'zLAN', + to: '/docs/zlan/intro', + logo: 'https://netfoundry.io/docs/img/zlan/zlan-logo.svg', + description: 'Zero-trust access for OT networks.', + }, + ], + }, ], }, navbar: { @@ -525,22 +527,9 @@ const config: Config = { [ 'redocusaurus', { specs: [ - { - id: 'openapi', - spec: `${frontdoor}/docusaurus/static/frontdoor-api-spec.yaml`, - }, - { - id: 'core-management', - spec: `${platform}/docusaurus/static/console-api-spec.yaml`, - }, - { - id: 'edge-client', - spec: 'https://get.openziti.io/spec/client.yml', - }, - { - id: 'edge-management', - spec: 'https://get.openziti.io/spec/management.yml', - }, + ...frontdoorRedocSpecs(`${frontdoor}/docusaurus`), + ...platformRedocSpecs(`${platform}/docusaurus`), + ...openzitiRedocSpecs(), ], // Theme Options for modifying how redoc renders them theme: { diff --git a/unified-doc/src/pages/index.module.css b/unified-doc/src/pages/index.module.css index ab1631e3..ff73e7a4 100644 --- a/unified-doc/src/pages/index.module.css +++ b/unified-doc/src/pages/index.module.css @@ -141,7 +141,7 @@ .nf-card-header h3 { margin: 0; } .nf-bento-card h3 { color: #f1f5f9; font-weight: 900; font-size: 1.05rem; line-height: 1.3; letter-spacing: -0.02em; } [data-theme='light'] .nf-bento-card h3 { color: #0f172a; } -.nf-bento-card p { color: #94a3b8; font-size: 0.875rem; line-height: 1.65; flex-grow: 1; margin: 0 0 0.5rem; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } +.nf-bento-card p { color: #94a3b8; font-size: 0.875rem; line-height: 1.65; flex-grow: 1; margin: 0 0 0.5rem; } [data-theme='light'] .nf-bento-card p { color: #475569; } .nf-bento-features { list-style: none; padding: 0; margin: 0 0 0.5rem; display: flex; flex-direction: column; gap: 0.25rem; } diff --git a/unified-doc/src/pages/index.tsx b/unified-doc/src/pages/index.tsx index 95d10a0d..7d998606 100644 --- a/unified-doc/src/pages/index.tsx +++ b/unified-doc/src/pages/index.tsx @@ -15,11 +15,11 @@ const products = [ id: 'console', title: 'NetFoundry Console', logo: NF_LOGO, - tag: 'SaaS', + tag: 'Managed', accent: CYAN, link: `${DOCS_BASE}platform/intro`, - features: ['Enterprise-grade support (24×7)', 'Fully managed by NetFoundry with 99.95% uptime SLA', 'Guidance for resilient, scalable production architecture', 'FIPS compliant'], - description: "NetFoundry's fully managed control plane for zero-trust networking. Orchestrate identities, policies, and edge routers." + features: ['Fully managed SaaS', 'Global edge fabric', 'No infra to operate', 'Policy-based access'], + description: "The cloud-managed control plane for NetFoundry's global zero-trust fabric. Orchestrate identities, policies, and edge routers — no infrastructure to run." }, { id: 'openziti', @@ -28,18 +28,17 @@ const products = [ tag: 'Open Source', accent: GREEN, link: `${DOCS_BASE}openziti/learn/introduction`, - features: ['Community support', 'Self-deployed and managed, self-orchestrated'], - description: 'The open-source zero-trust framework behind NetFoundry. Embed app-native security in your code—no VPN, no perimeter.' + description: 'The open-source zero-trust networking framework at the heart of the NetFoundry platform. Embed dark, app-native security directly in your code — no VPN, no perimeter.' }, { id: 'frontdoor', title: 'Frontdoor', logo: `${IMG}/frontdoor-sm-logo.svg`, - tag: 'SaaS', + tag: 'Managed', accent: CYAN, link: `${DOCS_BASE}frontdoor/intro`, - features: ['Enterprise-grade support (24×7)', 'Fully managed by NetFoundry with 99.95% uptime SLA', 'Guidance for resilient, scalable production architecture', 'FIPS compliant'], - description: 'Secure, clientless access to any application—without a VPN or firewall rule. Expose nothing to the internet while giving authorized users instant access.' + features: ['No agent or VPN required', 'Zero firewall rules', 'Identity-based access', 'Any app, any browser'], + description: 'Secure, clientless access to any application — without a VPN or firewall rule. Expose nothing to the internet while giving authorized users instant access.' }, { id: 'zrok', @@ -48,18 +47,18 @@ const products = [ tag: 'Open Source', accent: GREEN, link: `${DOCS_BASE}zrok`, - features: ['Community support', 'Self-deployed and managed, self-orchestrated'], - description: 'Geo-scale secure sharing built on the OpenZiti mesh. Share services, files, or HTTP endpoints peer-to-peer—no open ports, no NAT traversal tricks.' + description: 'Geo-scale secure sharing built on the OpenZiti mesh. Share services, files, or HTTP endpoints peer-to-peer — no open ports, no NAT traversal tricks.' }, { - id: 'selfhosted', + id: + 'selfhosted', title: 'NetFoundry Self-Hosted', logo: `${IMG}/onprem-sm-logo.svg`, tag: 'Self-Hosted', accent: CYAN, link: `${DOCS_BASE}selfhosted/intro`, - features: ['Enterprise-grade support (24×7)', 'Self-deployed and managed, self-orchestrated', 'Guidance for resilient, scalable production architecture'], - description: 'Run the full NetFoundry stack in your own environment. On-prem, air-gapped, or any cloud. You own the infrastructure.' + features: ['Full infrastructure control', 'Air-gap compatible', 'On-prem or any cloud', 'Enterprise SLA'], + description: 'Deploy the full NetFoundry control plane and fabric in your own environment. Full sovereignty over your zero-trust infrastructure — on-prem, air-gapped, or any cloud.' }, { id: 'zlan', @@ -68,8 +67,8 @@ const products = [ tag: 'OT Security', accent: CYAN, link: `${DOCS_BASE}zlan/intro`, - features: ['Deep OT/IT traffic visibility', 'Identity-aware micro-segmentation', 'Centralized zero-trust policy'], - description: 'Identity-aware micro-segmentation for OT networks. Deep traffic visibility, centralized policy, and zero-trust access control.' + features: ['Deep OT/IT traffic visibility', 'Identity-aware micro-segmentation', 'Centralized zero-trust policy', 'Built on NetFoundry Self-Hosted'], + description: 'Identity-aware micro-segmentation firewall for operational technology networks. Deep traffic visibility, centralized policy, and zero-trust access control for OT environments.' }, ]; @@ -80,7 +79,7 @@ function BentoCard({product, featured = false}: {product: Product; featured?: bo const accentMod = product.accent === CYAN ? styles['nf-bento-card--accent-cyan'] : styles['nf-bento-card--accent-green']; return (
- + {product.tag}
{product.logo && {product.title}} @@ -114,15 +113,20 @@ export default function Home(): JSX.Element {
-
Cloud SaaS
- - -
Self-Hosted Licensed
+
Managed Cloud
+
+ +
open-source counterpart
+ +
+
+ +
open-source counterpart
+ +
+
Run on your own infrastructure
-
Self-Hosted Open Source
- -
From 208d84e3235f32692a4f56198766be93d7b08e3c Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Wed, 22 Apr 2026 18:29:25 +0000 Subject: [PATCH 04/10] fix color --- packages/test-site/src/pages/index.module.css | 5 +++++ packages/test-site/src/pages/index.tsx | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/test-site/src/pages/index.module.css b/packages/test-site/src/pages/index.module.css index 39d44e7e..ff15c297 100644 --- a/packages/test-site/src/pages/index.module.css +++ b/packages/test-site/src/pages/index.module.css @@ -85,6 +85,11 @@ [data-theme='light'] .nf-divider--managed { color: #0891b2; text-shadow: none; } [data-theme='light'] .nf-divider--managed::before, [data-theme='light'] .nf-divider--managed::after { background: rgba(8, 145, 178, 0.35); height: 2px; } +.nf-divider--open-source { color: var(--nf-secondary); } +.nf-divider--open-source::before, .nf-divider--open-source::after { background: rgba(78, 219, 63, 0.4); height: 2px; } +[data-theme='light'] .nf-divider--open-source { color: #16a34a; } +[data-theme='light'] .nf-divider--open-source::before, +[data-theme='light'] .nf-divider--open-source::after { background: rgba(22, 163, 74, 0.35); height: 2px; } .nf-pair { display: flex; flex-direction: column; } .nf-pair-connector { diff --git a/packages/test-site/src/pages/index.tsx b/packages/test-site/src/pages/index.tsx index 86b5db0e..8347d37a 100644 --- a/packages/test-site/src/pages/index.tsx +++ b/packages/test-site/src/pages/index.tsx @@ -121,7 +121,7 @@ export default function Home(): JSX.Element {
Self-Hosted Licensed
-
Self-Hosted Open Source
+
Self-Hosted Open Source
From d59c8966ff83e8cc27e420bcd43886bf169c5799 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Wed, 22 Apr 2026 19:40:03 +0000 Subject: [PATCH 05/10] Css --- packages/test-site/src/custom/custom.css | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/test-site/src/custom/custom.css b/packages/test-site/src/custom/custom.css index 25a6d819..39039008 100644 --- a/packages/test-site/src/custom/custom.css +++ b/packages/test-site/src/custom/custom.css @@ -36,7 +36,6 @@ body, display:flex; align-items:center; justify-content: end; - min-width: 185px; } .navbar__logo_nf { /* squeeze whitespace */ margin-right: 0; From 7851ae602814d14b93096e351ae38154bdd79058 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Wed, 22 Apr 2026 20:22:48 +0000 Subject: [PATCH 06/10] revert heading style --- packages/docusaurus-theme/css/product-picker.css | 7 ++++--- packages/test-site/src/pages/index.module.css | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/docusaurus-theme/css/product-picker.css b/packages/docusaurus-theme/css/product-picker.css index 8773fabd..b884b6ac 100644 --- a/packages/docusaurus-theme/css/product-picker.css +++ b/packages/docusaurus-theme/css/product-picker.css @@ -170,10 +170,11 @@ /* ── Column headers ─────────────────────────────────────────────────────── */ .picker-header { - font-size: 0.82rem; - font-weight: 800; + font-size: 0.7rem; + font-weight: 900; color: #94a3b8; - letter-spacing: 0.12em; + text-transform: uppercase; + letter-spacing: 0.1em; border-bottom: 2px solid rgba(148, 163, 184, 0.2); display: block; padding-bottom: 0.5rem; diff --git a/packages/test-site/src/pages/index.module.css b/packages/test-site/src/pages/index.module.css index ff15c297..ae8031c5 100644 --- a/packages/test-site/src/pages/index.module.css +++ b/packages/test-site/src/pages/index.module.css @@ -67,8 +67,8 @@ .nf-bento-divider { grid-column: 1 / -1; display: flex; align-items: center; gap: 1rem; - padding: 1.5rem 0 0.65rem; color: #94a3b8; font-size: 0.82rem; font-weight: 800; - letter-spacing: 0.12em; white-space: nowrap; + padding: 1.5rem 0 0.65rem; color: #94a3b8; font-size: 0.7rem; font-weight: 900; + text-transform: uppercase; letter-spacing: 0.1em; white-space: nowrap; } .nf-bento-divider::before, .nf-bento-divider::after { content: ''; flex: 1; height: 1px; background: rgba(148, 163, 184, 0.2); From 8d7227367a9d36096f54847d79d5dca861e83454 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Wed, 22 Apr 2026 22:03:24 +0000 Subject: [PATCH 07/10] revert round 1 --- packages/test-site/src/pages/index.module.css | 172 +----------------- packages/test-site/src/pages/index.tsx | 132 +------------- .../test-site/src/theme/DocSearch/index.tsx | 77 -------- .../src/theme/DocSearch/styles.module.css | 12 -- .../test-site/src/theme/Navbar/Logo/index.tsx | 74 -------- unified-doc/src/pages/index.module.css | 28 ++- unified-doc/src/pages/index.tsx | 80 ++++---- 7 files changed, 59 insertions(+), 516 deletions(-) delete mode 100644 packages/test-site/src/theme/DocSearch/index.tsx delete mode 100644 packages/test-site/src/theme/DocSearch/styles.module.css delete mode 100644 packages/test-site/src/theme/Navbar/Logo/index.tsx diff --git a/packages/test-site/src/pages/index.module.css b/packages/test-site/src/pages/index.module.css index ae8031c5..b2cf34da 100644 --- a/packages/test-site/src/pages/index.module.css +++ b/packages/test-site/src/pages/index.module.css @@ -1,171 +1 @@ -.nf-hero-stage { - position: relative; width: 100%; min-height: 370px; - display: flex; align-items: center; justify-content: center; - overflow: hidden; text-align: center; background: #020617; z-index: 4; -} -.nf-hero-stage::after { - content: ''; position: absolute; bottom: 0; left: 0; right: 0; - height: 220px; background: linear-gradient(to bottom, transparent 0%, #0f172a 100%); - pointer-events: none; z-index: 1; -} -[data-theme='light'] .nf-hero-stage::after { - height: 80px; - background: linear-gradient(to bottom, transparent 0%, #020617 100%); -} -.nf-hero-overlay { display: none; } -.nf-hero-content { - position: relative; z-index: 2; padding: 2.5rem 3.5rem; - background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; -} -.nf-hero-title { - font-size: 4rem; font-weight: 900; color: #ffffff; margin-bottom: 0.75rem; - letter-spacing: -0.02em; line-height: 1.05; - text-shadow: 0 0 20px rgba(34, 211, 238, 0.8), 0 2px 12px rgba(0, 0, 0, 0.9); -} -.nf-green-text { - color: #22c55e; - font-family: inherit; font-weight: inherit; font-size: inherit; - text-shadow: 0 0 20px rgba(34, 197, 94, 0.75), 0 2px 12px rgba(0, 0, 0, 0.9); -} -.nf-hero-subtext { - color: rgba(203, 213, 225, 0.95); font-size: 1.15rem; max-width: 560px; - margin: 0 auto 2rem; line-height: 1.65; text-shadow: 0 1px 8px rgba(0, 0, 0, 0.95); -} -.nf-hero-ctas { display: flex; gap: 1rem; justify-content: center; } -.nf-btn-primary { - display: inline-flex; align-items: center; padding: 0.65rem 1.75rem; - background: #0076FF; color: #ffffff; border-radius: 8px; font-weight: 700; - font-size: 0.95rem; text-decoration: none; transition: all 0.25s ease; border: 2px solid #0076FF; -} -.nf-btn-primary:hover { - background: #005ce6; border-color: #005ce6; transform: translateY(-2px); - box-shadow: 0 8px 24px rgba(0, 118, 255, 0.4); color: #ffffff; text-decoration: none; -} -.nf-btn-ghost { - display: inline-flex; align-items: center; padding: 0.65rem 1.75rem; - background: transparent; color: #ffffff; border-radius: 8px; font-weight: 700; - font-size: 0.95rem; text-decoration: none; transition: all 0.25s ease; - border: 2px solid rgba(255, 255, 255, 0.25); -} -.nf-btn-ghost:hover { - background: rgba(255, 255, 255, 0.06); border-color: rgba(34, 211, 238, 0.5); - transform: translateY(-2px); color: #ffffff; text-decoration: none; -} -[data-theme='dark'] .nf-btn-primary, -[data-theme='dark'] .nf-btn-primary:hover, -[data-theme='dark'] .nf-btn-ghost, -[data-theme='dark'] .nf-btn-ghost:hover { color: #ffffff; text-decoration: none; } - -.nf-features-section { width: 100%; background: #0f172a; padding: 5rem 0 2.5rem; } -[data-theme='light'] .nf-features-section { - background: linear-gradient(to bottom, - #020617 0px, #020617 80px, #404350 18%, #7d808a 28%, - #b8bbc1 38%, #e4e7ea 48%, #f8fafc 100%); -} - -.nf-bento-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; } - -.nf-bento-divider { - grid-column: 1 / -1; display: flex; align-items: center; gap: 1rem; - padding: 1.5rem 0 0.65rem; color: #94a3b8; font-size: 0.7rem; font-weight: 900; - text-transform: uppercase; letter-spacing: 0.1em; white-space: nowrap; -} -.nf-bento-divider::before, .nf-bento-divider::after { - content: ''; flex: 1; height: 1px; background: rgba(148, 163, 184, 0.2); -} -.nf-divider--top { padding-top: 0; } -.nf-divider--managed { - color: #22d3ee; font-size: 1.05rem; letter-spacing: 0.15em; - text-shadow: 0 0 18px rgba(34, 211, 238, 0.5); -} -.nf-divider--managed::before, .nf-divider--managed::after { background: rgba(34, 211, 238, 0.4); height: 2px; } -[data-theme='light'] .nf-bento-divider { color: #64748b; } -[data-theme='light'] .nf-bento-divider::before, -[data-theme='light'] .nf-bento-divider::after { background: rgba(100, 116, 139, 0.25); } -[data-theme='light'] .nf-divider--managed { color: #0891b2; text-shadow: none; } -[data-theme='light'] .nf-divider--managed::before, -[data-theme='light'] .nf-divider--managed::after { background: rgba(8, 145, 178, 0.35); height: 2px; } -.nf-divider--open-source { color: var(--nf-secondary); } -.nf-divider--open-source::before, .nf-divider--open-source::after { background: rgba(78, 219, 63, 0.4); height: 2px; } -[data-theme='light'] .nf-divider--open-source { color: #16a34a; } -[data-theme='light'] .nf-divider--open-source::before, -[data-theme='light'] .nf-divider--open-source::after { background: rgba(22, 163, 74, 0.35); height: 2px; } - -.nf-pair { display: flex; flex-direction: column; } -.nf-pair-connector { - display: flex; align-items: center; gap: 1rem; padding: 0.5rem 0; - font-size: 0.7rem; font-weight: 800; letter-spacing: 0.12em; - text-transform: uppercase; color: #94a3b8; -} -.nf-pair-connector::before, .nf-pair-connector::after { - content: ''; flex: 1; height: 1px; background: rgba(148, 163, 184, 0.2); -} -[data-theme='light'] .nf-pair-connector { color: #64748b; } -[data-theme='light'] .nf-pair-connector::before, -[data-theme='light'] .nf-pair-connector::after { background: rgba(148, 163, 184, 0.35); } - -.nf-bento-wrap { display: flex; flex-direction: column; } - -.nf-bento-card { - position: relative; display: flex; flex-direction: column; flex: 1; - padding: 1rem; border-radius: 12px; text-decoration: none; - background: #1a1b2e; border: 1px solid rgba(148, 163, 184, 0.1); - border-top: 2px solid #22d3ee; - box-shadow: 0 1px 3px rgba(0,0,0,0.3), 0 6px 20px rgba(0,0,0,0.3), 0 16px 40px rgba(0,0,0,0.2); - transition: transform 0.2s ease, box-shadow 0.2s ease, border-top-color 0.2s ease; -} -.nf-bento-card:hover { - transform: translateY(-4px); border-top-color: #22c55e; color: inherit; text-decoration: none; - box-shadow: 0 2px 6px rgba(0,0,0,0.4), 0 12px 32px rgba(0,0,0,0.45), - 0 24px 60px rgba(0,0,0,0.25), 0 0 0 1px rgba(34,197,94,0.12); -} -[data-theme='light'] .nf-bento-card { - background: #edf3f8; border-color: rgba(0,0,0,0.08); - box-shadow: 0 1px 3px rgba(0,0,0,0.06), 0 4px 14px rgba(0,0,0,0.05); -} -[data-theme='light'] .nf-bento-card:hover { - box-shadow: 0 2px 6px rgba(0,0,0,0.09), 0 8px 24px rgba(0,0,0,0.07), 0 0 0 1px rgba(34,197,94,0.18); -} -.nf-bento-card--accent-cyan { border-top-color: #22d3ee; } -.nf-bento-card--accent-green { border-top-color: #22c55e; } -[data-theme='light'] .nf-bento-card--accent-cyan { border-top-color: #0068f9; } -[data-theme='light'] .nf-bento-card--accent-green { border-top-color: #16a34a; } -.nf-bento-card--featured { padding: 1.25rem; border-top-width: 3px; } -.nf-bento-card--featured .nf-card-logo { width: 48px; height: 48px; } -.nf-bento-card--featured .nf-card-header h3 { font-size: 1.25rem; } - -.nf-card-badge { - position: absolute; top: 1rem; right: 1rem; display: inline-flex; width: fit-content; - background: rgba(34,197,94,0.1); color: #4ade80; border: 1px solid rgba(34,197,94,0.2); - font-size: 0.6rem; font-weight: 800; letter-spacing: 0.1em; - padding: 2px 8px; border-radius: 4px; text-transform: uppercase; -} -[data-theme='light'] .nf-card-badge { color: #15803d; border-color: rgba(34,197,94,0.25); } - -.nf-card-header { - display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem; padding-right: 3rem; -} -.nf-card-header h3 { margin: 0; } -.nf-bento-card h3 { color: #f1f5f9; font-weight: 900; font-size: 1.05rem; line-height: 1.3; letter-spacing: -0.02em; } -[data-theme='light'] .nf-bento-card h3 { color: #0f172a; } -.nf-bento-card p { color: #94a3b8; font-size: 0.875rem; line-height: 1.65; flex-grow: 1; margin: 0 0 0.5rem; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } -[data-theme='light'] .nf-bento-card p { color: #475569; } - -.nf-bento-features { list-style: none; padding: 0; margin: 0 0 0.5rem; display: flex; flex-direction: column; gap: 0.25rem; } -.nf-bento-features li { display: flex; align-items: center; gap: 0.4rem; font-size: 0.775rem; color: #64748b; } -.nf-bento-features li::before { content: '✓'; color: #22c55e; font-weight: 800; font-size: 0.75rem; flex-shrink: 0; } -[data-theme='light'] .nf-bento-features li::before { color: #16a34a; } - -.nf-card-link { color: #22d3ee; font-size: 0.8rem; font-weight: 700; margin-top: auto; padding-top: 0.5rem; letter-spacing: 0.03em; } -[data-theme='light'] .nf-card-link { color: #0284c7; } -.nf-card-logo { width: 40px; height: 40px; object-fit: contain; flex-shrink: 0; } - -@media (max-width: 996px) { - .nf-hero-title { font-size: 2.2rem; } - .nf-hero-content { padding: 2rem 1.25rem; } - .nf-hero-ctas { flex-wrap: wrap; } - .nf-btn-primary, .nf-btn-ghost { padding: 0.55rem 1.25rem; font-size: 0.9rem; } -} -@media (max-width: 640px) { - .nf-bento-grid { grid-template-columns: 1fr; } -} +/* placeholder — landing page styling lives in unified-doc */ diff --git a/packages/test-site/src/pages/index.tsx b/packages/test-site/src/pages/index.tsx index 8347d37a..3bbdb9f0 100644 --- a/packages/test-site/src/pages/index.tsx +++ b/packages/test-site/src/pages/index.tsx @@ -1,132 +1,18 @@ import React, {JSX} from 'react'; import Layout from '@theme/Layout'; import Link from '@docusaurus/Link'; -import clsx from 'clsx'; -import styles from './index.module.css'; - -const DOCS_BASE = '/docs/'; - -const CYAN = '#22d3ee'; -const GREEN = '#22c55e'; -const IMG = 'https://netfoundry.io/docs/img'; -const NF_LOGO = 'https://raw.githubusercontent.com/netfoundry/branding/refs/heads/main/images/svg/icon/netfoundry-icon-color.svg'; - -const products = [ - { - id: 'console', - title: 'NetFoundry Console', - logo: NF_LOGO, - tag: 'SaaS', - accent: CYAN, - link: `${DOCS_BASE}platform/intro`, - features: ['Enterprise-grade support (24×7)', 'Fully managed by NetFoundry with 99.95% uptime SLA', 'Guidance for resilient, scalable production architecture', 'FIPS compliant'], - description: "NetFoundry's fully managed control plane for zero-trust networking. Orchestrate identities, policies, and edge routers." - }, - { - id: 'openziti', - title: 'OpenZiti', - logo: `${IMG}/openziti-sm-logo.svg`, - tag: 'Open Source', - accent: GREEN, - link: `${DOCS_BASE}openziti/learn/introduction`, - features: ['Community support', 'Self-deployed and managed, self-orchestrated'], - description: 'The open-source zero-trust framework behind NetFoundry. Embed app-native security in your code—no VPN, no perimeter.' - }, - { - id: 'frontdoor', - title: 'Frontdoor', - logo: `${IMG}/frontdoor-sm-logo.svg`, - tag: 'SaaS', - accent: CYAN, - link: `${DOCS_BASE}frontdoor/intro`, - features: ['Enterprise-grade support (24×7)', 'Fully managed by NetFoundry with 99.95% uptime SLA', 'Guidance for resilient, scalable production architecture', 'FIPS compliant'], - description: 'Secure, clientless access to any application—without a VPN or firewall rule. Expose nothing to the internet while giving authorized users instant access.' - }, - { - id: 'zrok', - title: 'zrok', - logo: `${IMG}/zrok-1.0.0-rocket-purple.svg`, - tag: 'Open Source', - accent: GREEN, - link: `${DOCS_BASE}zrok`, - features: ['Community support', 'Self-deployed and managed, self-orchestrated'], - description: 'Geo-scale secure sharing built on the OpenZiti mesh. Share services, files, or HTTP endpoints peer-to-peer—no open ports, no NAT traversal tricks.' - }, - { - id: 'selfhosted', - title: 'NetFoundry Self-Hosted', - logo: `${IMG}/onprem-sm-logo.svg`, - tag: 'Self-Hosted', - accent: CYAN, - link: `${DOCS_BASE}selfhosted/intro`, - features: ['Enterprise-grade support (24×7)', 'Self-deployed and managed, self-orchestrated', 'Guidance for resilient, scalable production architecture'], - description: 'Run the full NetFoundry stack in your own environment. On-prem, air-gapped, or any cloud. You own the infrastructure.' - }, - { - id: 'zlan', - title: 'zLAN', - logo: `${IMG}/zlan/zlan-logo.svg`, - tag: 'OT Security', - accent: CYAN, - link: `${DOCS_BASE}zlan/intro`, - features: ['Deep OT/IT traffic visibility', 'Identity-aware micro-segmentation', 'Centralized zero-trust policy'], - description: 'Identity-aware micro-segmentation for OT networks. Deep traffic visibility, centralized policy, and zero-trust access control.' - }, -]; - -type Product = (typeof products)[number]; -const byId = Object.fromEntries(products.map(p => [p.id, p])) as Record; - -function BentoCard({product, featured = false}: {product: Product; featured?: boolean}): JSX.Element { - const accentMod = product.accent === CYAN ? styles['nf-bento-card--accent-cyan'] : styles['nf-bento-card--accent-green']; - return ( -
- - {product.tag} -
- {product.logo && {product.title}} -

{product.title}

-
-

{product.description}

- {product.features && ( -
    - {product.features.map(f =>
  • {f}
  • )} -
- )} -
Explore →
- -
- ); -} export default function Home(): JSX.Element { return ( - -
-
-

NetFoundry Docs

-

Secure Your Workloads with Identity-First Connectivity™

- -
-
-
-
-
-
Cloud SaaS
- - -
Self-Hosted Licensed
- - -
Self-Hosted Open Source
- - -
-
-
+ +
+

Theme Test Site

+

+ This is the dev sandbox for @netfoundry/docusaurus-theme. + Navigate using the navbar above to test theme components. +

+ Browse test docs → +
); } diff --git a/packages/test-site/src/theme/DocSearch/index.tsx b/packages/test-site/src/theme/DocSearch/index.tsx deleted file mode 100644 index b7954905..00000000 --- a/packages/test-site/src/theme/DocSearch/index.tsx +++ /dev/null @@ -1,77 +0,0 @@ -// src/theme/DocSearch/index.tsx -import React, { useMemo, useState, useEffect } from "react"; -import OriginalDocSearch from "@theme-original/DocSearch"; -import type { Props } from "@theme/DocSearch"; -import { createPortal } from "react-dom"; -import styles from "./styles.module.css"; - -const PRODUCTS = ["frontdoor", "openziti", "selfhosted", "zlan"] as const; - -function Pills({ - product, - setProduct, - }: { - product: string; - setProduct: (v: string) => void; -}) { - const [host, setHost] = useState(null); - - useEffect(() => { - const el = - document.querySelector(".DocSearch-Modal .DocSearch-Form")?.parentElement ?? - null; - setHost(el || null); - }, []); - - if (!host) return null; - - return createPortal( -
- - {PRODUCTS.map((p) => ( - - ))} -
, - host - ); -} - -export default function DocSearchWrapper(props: Props) { - const [product, setProduct] = useState(""); - - const transformSearchParameters = useMemo( - () => - (params: any) => ({ - ...params, - facetFilters: [ - ...(params.facetFilters ?? []), - ...(product ? [`product:${product}`] : []), - ], - }), - [product] - ); - - return ( - <> - - - {/* "Search by Algolia" is already shown in the modal footer */} - - ); -} diff --git a/packages/test-site/src/theme/DocSearch/styles.module.css b/packages/test-site/src/theme/DocSearch/styles.module.css deleted file mode 100644 index f1410c93..00000000 --- a/packages/test-site/src/theme/DocSearch/styles.module.css +++ /dev/null @@ -1,12 +0,0 @@ -/* src/theme/DocSearch/styles.module.css */ -.pills{ - display:flex;gap:.4rem;align-items:center;margin-top:.4rem; - padding:.25rem .25rem .35rem .25rem;flex-wrap:wrap -} -.pill{ - padding:.35rem .7rem;border:1px solid var(--ifm-color-emphasis-300); - border-radius:999px;background:transparent;cursor:pointer;font-size:.85rem -} -.active{ - background:var(--ifm-color-primary);color:#fff;border-color:var(--ifm-color-primary) -} diff --git a/packages/test-site/src/theme/Navbar/Logo/index.tsx b/packages/test-site/src/theme/Navbar/Logo/index.tsx deleted file mode 100644 index 68d34bb4..00000000 --- a/packages/test-site/src/theme/Navbar/Logo/index.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import React, {JSX} from 'react'; -import Link from '@docusaurus/Link'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import useBaseUrl from '@docusaurus/useBaseUrl'; -import {useLocation} from '@docusaurus/router'; -import type {DocusaurusConfig} from "@docusaurus/types/src/config"; -import ThemedImage from "@theme/ThemedImage"; - -const mapTitle = (p: string) => { - // Extract the root project segment, skipping optional /docs/ prefix - const segments = p.split('/'); - const rootSegment = segments[1] === 'docs' ? segments[2] : segments[1]; - const checkPath = (segment: string) => rootSegment === segment; - - if (checkPath('frontdoor')) return {includeNFLogo: true, to: '/docs/frontdoor', alt:'Frontdoor', logoLight: `/img/frontdoor-sm-logo.svg`, logoDark: `/img/frontdoor-sm-logo.svg`}; - if (checkPath('selfhosted')) return {includeNFLogo: true, to: '/docs/selfhosted',alt:'Self-Hosted', logoLight: `/img/onprem-sm-logo.svg`, logoDark: `/img/onprem-sm-logo.svg`}; - if (checkPath('openziti')) return {includeNFLogo: true, to: '/docs/openziti',alt:'OpenZiti', logoLight: `/img/openziti-sm-logo.svg`, logoDark: `/img/openziti-sm-logo.svg`}; - if (checkPath('zlan')) return {includeNFLogo: true, to: '/docs/zlan', alt:'zlan', logoLight: `/img/zlan/zlan-logo.svg`, logoDark: `/img/zlan/zlan-logo.svg`}; - if (checkPath('zrok')) return {text: '', includeNFLogo: true, to: '/docs/zrok', alt:'zrok', logoLight: `/img/zrok-1.0.0-rocket-purple.svg`, logoDark: `/img/zrok-1.0.0-rocket-green.svg`}; - return { - includeNFLogo: false, - to: '/', - alt:'NetFoundry', - logoLight: '', - logoDark: '' - }; -}; - -function navbarpoke(cfg:DocusaurusConfig) { - // console.log("A:" + JSON.stringify(cfg?.themeConfig?.navbar)); -} - -export default function NavbarLogo(): JSX.Element { - const {siteConfig} = useDocusaurusContext(); - const {pathname} = useLocation(); - const title = mapTitle(pathname); - navbarpoke(siteConfig); - - const nfLogoLight = useBaseUrl('/img/netfoundry-name-and-logo.svg'); - const nfLogoDark = useBaseUrl('/img/netfoundry-name-and-logo-dark.svg'); - const logoLight = useBaseUrl(title.logoLight); - const logoDark = useBaseUrl(title.logoDark); - - return ( - <> - - - - {(title.logoLight || title.text) && ( - - {title.logoLight && ( - - )} - {title.text && {title.text}} - - )} - - ); - -} diff --git a/unified-doc/src/pages/index.module.css b/unified-doc/src/pages/index.module.css index ff73e7a4..7d0c2bef 100644 --- a/unified-doc/src/pages/index.module.css +++ b/unified-doc/src/pages/index.module.css @@ -67,8 +67,8 @@ .nf-bento-divider { grid-column: 1 / -1; display: flex; align-items: center; gap: 1rem; - padding: 1.5rem 0 0.65rem; color: #94a3b8; font-size: 0.82rem; font-weight: 800; - letter-spacing: 0.12em; text-transform: uppercase; white-space: nowrap; + padding: 1.5rem 0 0.65rem; color: #94a3b8; font-size: 0.7rem; font-weight: 900; + text-transform: uppercase; letter-spacing: 0.1em; white-space: nowrap; } .nf-bento-divider::before, .nf-bento-divider::after { content: ''; flex: 1; height: 1px; background: rgba(148, 163, 184, 0.2); @@ -85,19 +85,11 @@ [data-theme='light'] .nf-divider--managed { color: #0891b2; text-shadow: none; } [data-theme='light'] .nf-divider--managed::before, [data-theme='light'] .nf-divider--managed::after { background: rgba(8, 145, 178, 0.35); height: 2px; } - -.nf-pair { display: flex; flex-direction: column; } -.nf-pair-connector { - display: flex; align-items: center; gap: 1rem; padding: 0.5rem 0; - font-size: 0.7rem; font-weight: 800; letter-spacing: 0.12em; - text-transform: uppercase; color: #94a3b8; -} -.nf-pair-connector::before, .nf-pair-connector::after { - content: ''; flex: 1; height: 1px; background: rgba(148, 163, 184, 0.2); -} -[data-theme='light'] .nf-pair-connector { color: #64748b; } -[data-theme='light'] .nf-pair-connector::before, -[data-theme='light'] .nf-pair-connector::after { background: rgba(148, 163, 184, 0.35); } +.nf-divider--open-source { color: var(--nf-secondary); } +.nf-divider--open-source::before, .nf-divider--open-source::after { background: rgba(78, 219, 63, 0.4); height: 2px; } +[data-theme='light'] .nf-divider--open-source { color: #16a34a; } +[data-theme='light'] .nf-divider--open-source::before, +[data-theme='light'] .nf-divider--open-source::after { background: rgba(22, 163, 74, 0.35); height: 2px; } .nf-bento-wrap { display: flex; flex-direction: column; } @@ -121,7 +113,9 @@ [data-theme='light'] .nf-bento-card:hover { box-shadow: 0 2px 6px rgba(0,0,0,0.09), 0 8px 24px rgba(0,0,0,0.07), 0 0 0 1px rgba(34,197,94,0.18); } -[data-theme='light'] .nf-bento-card--accent-cyan { border-top-color: #0891b2; } +.nf-bento-card--accent-cyan { border-top-color: #22d3ee; } +.nf-bento-card--accent-green { border-top-color: #22c55e; } +[data-theme='light'] .nf-bento-card--accent-cyan { border-top-color: #0068f9; } [data-theme='light'] .nf-bento-card--accent-green { border-top-color: #16a34a; } .nf-bento-card--featured { padding: 1.25rem; border-top-width: 3px; } .nf-bento-card--featured .nf-card-logo { width: 48px; height: 48px; } @@ -141,7 +135,7 @@ .nf-card-header h3 { margin: 0; } .nf-bento-card h3 { color: #f1f5f9; font-weight: 900; font-size: 1.05rem; line-height: 1.3; letter-spacing: -0.02em; } [data-theme='light'] .nf-bento-card h3 { color: #0f172a; } -.nf-bento-card p { color: #94a3b8; font-size: 0.875rem; line-height: 1.65; flex-grow: 1; margin: 0 0 0.5rem; } +.nf-bento-card p { color: #94a3b8; font-size: 0.875rem; line-height: 1.65; flex-grow: 1; margin: 0 0 0.5rem; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } [data-theme='light'] .nf-bento-card p { color: #475569; } .nf-bento-features { list-style: none; padding: 0; margin: 0 0 0.5rem; display: flex; flex-direction: column; gap: 0.25rem; } diff --git a/unified-doc/src/pages/index.tsx b/unified-doc/src/pages/index.tsx index 7d998606..3c845732 100644 --- a/unified-doc/src/pages/index.tsx +++ b/unified-doc/src/pages/index.tsx @@ -15,50 +15,31 @@ const products = [ id: 'console', title: 'NetFoundry Console', logo: NF_LOGO, - tag: 'Managed', + tag: 'SaaS', accent: CYAN, link: `${DOCS_BASE}platform/intro`, - features: ['Fully managed SaaS', 'Global edge fabric', 'No infra to operate', 'Policy-based access'], - description: "The cloud-managed control plane for NetFoundry's global zero-trust fabric. Orchestrate identities, policies, and edge routers — no infrastructure to run." - }, - { - id: 'openziti', - title: 'OpenZiti', - logo: `${IMG}/openziti-sm-logo.svg`, - tag: 'Open Source', - accent: GREEN, - link: `${DOCS_BASE}openziti/learn/introduction`, - description: 'The open-source zero-trust networking framework at the heart of the NetFoundry platform. Embed dark, app-native security directly in your code — no VPN, no perimeter.' + features: ['Enterprise-grade support (24×7)', 'Fully managed by NetFoundry with 99.95% uptime SLA', 'Guidance for resilient, scalable production architecture', 'FIPS compliant'], + description: "NetFoundry's fully managed control plane for zero-trust networking. Orchestrate identities, policies, and edge routers." }, { id: 'frontdoor', title: 'Frontdoor', logo: `${IMG}/frontdoor-sm-logo.svg`, - tag: 'Managed', + tag: 'SaaS', accent: CYAN, link: `${DOCS_BASE}frontdoor/intro`, - features: ['No agent or VPN required', 'Zero firewall rules', 'Identity-based access', 'Any app, any browser'], - description: 'Secure, clientless access to any application — without a VPN or firewall rule. Expose nothing to the internet while giving authorized users instant access.' - }, - { - id: 'zrok', - title: 'zrok', - logo: `${IMG}/zrok-1.0.0-rocket-purple.svg`, - tag: 'Open Source', - accent: GREEN, - link: `${DOCS_BASE}zrok`, - description: 'Geo-scale secure sharing built on the OpenZiti mesh. Share services, files, or HTTP endpoints peer-to-peer — no open ports, no NAT traversal tricks.' + features: ['Enterprise-grade support (24×7)', 'Fully managed by NetFoundry with 99.95% uptime SLA', 'Guidance for resilient, scalable production architecture', 'FIPS compliant'], + description: 'Secure, clientless access to any application—without a VPN or firewall rule. Expose nothing to the internet while giving authorized users instant access.' }, { - id: - 'selfhosted', + id: 'selfhosted', title: 'NetFoundry Self-Hosted', logo: `${IMG}/onprem-sm-logo.svg`, tag: 'Self-Hosted', accent: CYAN, link: `${DOCS_BASE}selfhosted/intro`, - features: ['Full infrastructure control', 'Air-gap compatible', 'On-prem or any cloud', 'Enterprise SLA'], - description: 'Deploy the full NetFoundry control plane and fabric in your own environment. Full sovereignty over your zero-trust infrastructure — on-prem, air-gapped, or any cloud.' + features: ['Enterprise-grade support (24×7)', 'Self-deployed and managed, self-orchestrated', 'Guidance for resilient, scalable production architecture'], + description: 'Run the full NetFoundry stack in your own environment. On-prem, air-gapped, or any cloud. You own the infrastructure.' }, { id: 'zlan', @@ -67,8 +48,28 @@ const products = [ tag: 'OT Security', accent: CYAN, link: `${DOCS_BASE}zlan/intro`, - features: ['Deep OT/IT traffic visibility', 'Identity-aware micro-segmentation', 'Centralized zero-trust policy', 'Built on NetFoundry Self-Hosted'], - description: 'Identity-aware micro-segmentation firewall for operational technology networks. Deep traffic visibility, centralized policy, and zero-trust access control for OT environments.' + features: ['Deep OT/IT traffic visibility', 'Identity-aware micro-segmentation', 'Centralized zero-trust policy'], + description: 'Identity-aware micro-segmentation for OT networks. Deep traffic visibility, centralized policy, and zero-trust access control.' + }, + { + id: 'openziti', + title: 'OpenZiti', + logo: `${IMG}/openziti-sm-logo.svg`, + tag: 'Open Source', + accent: GREEN, + link: `${DOCS_BASE}openziti/learn/introduction`, + features: ['Community support', 'Self-deployed and managed, self-orchestrated'], + description: 'The open-source zero-trust framework behind NetFoundry. Embed app-native security in your code—no VPN, no perimeter.' + }, + { + id: 'zrok', + title: 'zrok', + logo: `${IMG}/zrok-1.0.0-rocket-purple.svg`, + tag: 'Open Source', + accent: GREEN, + link: `${DOCS_BASE}zrok`, + features: ['Community support', 'Self-deployed and managed, self-orchestrated'], + description: 'Geo-scale secure sharing built on the OpenZiti mesh. Share services, files, or HTTP endpoints peer-to-peer—no open ports, no NAT traversal tricks.' }, ]; @@ -113,20 +114,15 @@ export default function Home(): JSX.Element {
-
Managed Cloud
-
- -
open-source counterpart
- -
-
- -
open-source counterpart
- -
-
Run on your own infrastructure
+
Cloud SaaS
+ + +
Self-Hosted Licensed
+
Self-Hosted Open Source
+ +
From 8ee481fabb5e06e02621eccf441b3e640e14ad5f Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Thu, 23 Apr 2026 16:11:16 +0000 Subject: [PATCH 08/10] update bento descriptions --- packages/test-site/src/custom/custom.css | 7 ------- unified-doc/src/pages/index.tsx | 14 +++++++------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/packages/test-site/src/custom/custom.css b/packages/test-site/src/custom/custom.css index 39039008..058ead0a 100644 --- a/packages/test-site/src/custom/custom.css +++ b/packages/test-site/src/custom/custom.css @@ -37,15 +37,8 @@ body, align-items:center; justify-content: end; } -.navbar__logo_nf { /* squeeze whitespace */ - margin-right: 0; - height: var(--ifm-navbar-height); -} .navbar__logo { /* squeeze whitespace */ margin-right: 0; - height: 40px; - width: 40px; - margin-left: 10px; } .clean-btn svg { /* diff --git a/unified-doc/src/pages/index.tsx b/unified-doc/src/pages/index.tsx index 3c845732..c4fc9eeb 100644 --- a/unified-doc/src/pages/index.tsx +++ b/unified-doc/src/pages/index.tsx @@ -19,7 +19,7 @@ const products = [ accent: CYAN, link: `${DOCS_BASE}platform/intro`, features: ['Enterprise-grade support (24×7)', 'Fully managed by NetFoundry with 99.95% uptime SLA', 'Guidance for resilient, scalable production architecture', 'FIPS compliant'], - description: "NetFoundry's fully managed control plane for zero-trust networking. Orchestrate identities, policies, and edge routers." + description: "Cloud-managed zero-trust networking platform. Manage identities, policies, services, and routers from the console—or automate everything through the API." }, { id: 'frontdoor', @@ -29,7 +29,7 @@ const products = [ accent: CYAN, link: `${DOCS_BASE}frontdoor/intro`, features: ['Enterprise-grade support (24×7)', 'Fully managed by NetFoundry with 99.95% uptime SLA', 'Guidance for resilient, scalable production architecture', 'FIPS compliant'], - description: 'Secure, clientless access to any application—without a VPN or firewall rule. Expose nothing to the internet while giving authorized users instant access.' + description: 'Expose any HTTP service through a hardened, authenticated frontend—no firewall changes, no port forwarding. End users authenticate via their existing IdP and access from any browser, no client install required.' }, { id: 'selfhosted', @@ -49,7 +49,7 @@ const products = [ accent: CYAN, link: `${DOCS_BASE}zlan/intro`, features: ['Deep OT/IT traffic visibility', 'Identity-aware micro-segmentation', 'Centralized zero-trust policy'], - description: 'Identity-aware micro-segmentation for OT networks. Deep traffic visibility, centralized policy, and zero-trust access control.' + description: 'Software-defined micro-segmentation for OT networks. Deploy firewall agents on Linux machines, observe traffic flows, and enforce consistent policy from a central console.' }, { id: 'openziti', @@ -58,8 +58,8 @@ const products = [ tag: 'Open Source', accent: GREEN, link: `${DOCS_BASE}openziti/learn/introduction`, - features: ['Community support', 'Self-deployed and managed, self-orchestrated'], - description: 'The open-source zero-trust framework behind NetFoundry. Embed app-native security in your code—no VPN, no perimeter.' + features: ['Community support', 'Full overlay mesh: controller, routers, and SDKs', 'Embed zero-trust in any application'], + description: 'The open-source zero-trust networking framework behind NetFoundry. Add zero-trust to existing apps with tunnelers, or embed it directly with the SDK for the strongest posture.' }, { id: 'zrok', @@ -68,8 +68,8 @@ const products = [ tag: 'Open Source', accent: GREEN, link: `${DOCS_BASE}zrok`, - features: ['Community support', 'Self-deployed and managed, self-orchestrated'], - description: 'Geo-scale secure sharing built on the OpenZiti mesh. Share services, files, or HTTP endpoints peer-to-peer—no open ports, no NAT traversal tricks.' + features: ['Community support', 'Self-host or use zrok.io', 'No open ports or firewall rules'], + description: 'Secure peer-to-peer sharing built on the OpenZiti mesh. Share services, files, or HTTP endpoints—no open ports, no NAT traversal tricks.' }, ]; From fc0834b5d82707a78a3d4452291fcfc1c9e20bc7 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Thu, 23 Apr 2026 16:33:40 +0000 Subject: [PATCH 09/10] trim frontdoor --- unified-doc/src/pages/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unified-doc/src/pages/index.tsx b/unified-doc/src/pages/index.tsx index c4fc9eeb..c222f85b 100644 --- a/unified-doc/src/pages/index.tsx +++ b/unified-doc/src/pages/index.tsx @@ -29,7 +29,7 @@ const products = [ accent: CYAN, link: `${DOCS_BASE}frontdoor/intro`, features: ['Enterprise-grade support (24×7)', 'Fully managed by NetFoundry with 99.95% uptime SLA', 'Guidance for resilient, scalable production architecture', 'FIPS compliant'], - description: 'Expose any HTTP service through a hardened, authenticated frontend—no firewall changes, no port forwarding. End users authenticate via their existing IdP and access from any browser, no client install required.' + description: 'A hardened frontend for any HTTP service—no firewall changes, no client installs. Users authenticate via their existing IdP and access from any browser.' }, { id: 'selfhosted', From e37ff2f0ed2ea4b79950894803bbfdac26d8fd17 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Thu, 23 Apr 2026 16:46:52 +0000 Subject: [PATCH 10/10] style edits --- unified-doc/src/pages/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unified-doc/src/pages/index.tsx b/unified-doc/src/pages/index.tsx index c222f85b..375548ae 100644 --- a/unified-doc/src/pages/index.tsx +++ b/unified-doc/src/pages/index.tsx @@ -19,7 +19,7 @@ const products = [ accent: CYAN, link: `${DOCS_BASE}platform/intro`, features: ['Enterprise-grade support (24×7)', 'Fully managed by NetFoundry with 99.95% uptime SLA', 'Guidance for resilient, scalable production architecture', 'FIPS compliant'], - description: "Cloud-managed zero-trust networking platform. Manage identities, policies, services, and routers from the console—or automate everything through the API." + description: "Cloud-managed zero-trust networking platform. Manage identities, policies, services, and routers from the console, or automate through the API." }, { id: 'frontdoor', @@ -59,7 +59,7 @@ const products = [ accent: GREEN, link: `${DOCS_BASE}openziti/learn/introduction`, features: ['Community support', 'Full overlay mesh: controller, routers, and SDKs', 'Embed zero-trust in any application'], - description: 'The open-source zero-trust networking framework behind NetFoundry. Add zero-trust to existing apps with tunnelers, or embed it directly with the SDK for the strongest posture.' + description: 'The open-source zero-trust networking framework behind NetFoundry. Add zero trust to existing apps with tunnelers, or embed it directly with the SDK for the strongest posture.' }, { id: 'zrok',