Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docusaurus.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { themes as prismThemes } from 'prism-react-renderer';
import type { Config } from '@docusaurus/types';
import type * as Preset from '@docusaurus/preset-classic';
import path from 'path';

// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)

Expand Down Expand Up @@ -135,6 +136,10 @@ const config: Config = {
],


clientModules: [
path.join(__dirname, 'src/clientModules/gtagGuard.ts'),
],

themeConfig: {
announcementBar: {
id: 'release_v1_0_0',
Expand Down Expand Up @@ -168,6 +173,7 @@ const config: Config = {
},
{ to: '/modules', label: 'Modules', position: 'left' },
{ to: '/blog', label: 'Blog', position: 'left' },
{ to: '/enterprise', label: 'Enterprise', position: 'left' },
{
type: 'docsVersionDropdown',
position: 'right',
Expand Down
10 changes: 10 additions & 0 deletions src/clientModules/gtagGuard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Defines a no-op window.gtag if the Google Analytics script was blocked
* (e.g. by an ad blocker), preventing "window.gtag is not a function" errors
* thrown by @docusaurus/plugin-google-gtag on route changes.
*/
if (typeof window !== 'undefined' && typeof window.gtag !== 'function') {
(window as typeof window & { gtag: (...args: unknown[]) => void }).gtag = () => {};
}

export {};
157 changes: 157 additions & 0 deletions src/pages/enterprise.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
.root {
padding-top: 2rem;
padding-bottom: 2rem;
}

.root section.margin-bottom--lg {
padding-bottom: 3rem;
}

/* ============================
OFFERING CARD
============================ */
.offeringCard {
background: var(--ifm-color-gray-100);
border-radius: 12px;
padding: 2.5rem;
max-width: 820px;
margin: 0 auto;
}

[data-theme='dark'] .offeringCard {
background: var(--ifm-background-color);
}

.offeringHeader {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 0.5rem;
margin-bottom: 1.25rem;
}

.providerLogo {
height: 32px;
width: auto;
flex-shrink: 0;
}

.offeringHeaderText {
font-size: 1.25rem;
font-weight: 700;
color: var(--ifm-heading-color);
line-height: 1.3;
}

.offeringTagline {
font-size: 1rem;
color: var(--ifm-color-emphasis-700);
margin-bottom: 2rem;
line-height: 1.6;
}

.featureList {
list-style: none;
padding: 0;
margin: 0 0 2rem;
display: flex;
flex-direction: column;
gap: 0.875rem;
}

.featureItem {
display: flex;
align-items: flex-start;
gap: 0.75rem;
font-size: 0.975rem;
color: var(--ifm-font-color-base);
line-height: 1.6;
}

.featureIcon {
flex-shrink: 0;
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--ifm-color-primary-lightest);
color: var(--ifm-color-primary-darkest);
display: flex;
align-items: center;
justify-content: center;
font-size: 0.75rem;
font-weight: 700;
margin-top: 2px;
}

[data-theme='dark'] .featureIcon {
background: rgba(43, 140, 247, 0.2);
color: var(--ifm-color-primary-light);
}

.featureLabel {
font-weight: 600;
color: var(--ifm-heading-color);
}

/* ============================
BUTTONS — same as marketplace
============================ */
.buttonGroup {
display: flex;
justify-content: center;
align-items: center;
gap: 0.75rem;
margin-top: 2rem;
flex-wrap: wrap;
}

.cButton {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.75rem 2rem;
font-size: 1rem;
line-height: 1;
font-weight: 600;
border-radius: 6px;
border: 2px solid var(--ifm-color-primary);
background: var(--ifm-color-primary);
color: #fff;
text-decoration: none;
cursor: pointer;
box-sizing: border-box;
transition:
background-color 0.2s ease,
color 0.2s ease,
border-color 0.2s ease,
box-shadow 0.2s ease,
transform 0.1s ease;
}

.cButton:hover {
color: #fff;
opacity: 0.9;
transform: translateY(-1px);
}

.cButton:focus {
outline: none;
}
Comment on lines +137 to +139
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Do not remove keyboard focus visibility on the CTA button.

Line 137-Line 139 removes focus outline with no replacement, which is an accessibility regression for keyboard users.

💡 Proposed fix
-.cButton:focus {
-  outline: none;
-}
+.cButton:focus-visible {
+  outline: 2px solid var(--ifm-color-primary);
+  outline-offset: 2px;
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.cButton:focus {
outline: none;
}
.cButton:focus-visible {
outline: 2px solid var(--ifm-color-primary);
outline-offset: 2px;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/enterprise.module.css` around lines 137 - 139, The current CSS rule
.cButton:focus { outline: none; } removes keyboard focus visibility and must be
replaced with a visible, accessible focus style; update the selector to use
.cButton:focus-visible (or keep :focus for broader support) and add a clear
high-contrast focus indicator (for example a 2px solid outline or visible
box-shadow and outline-offset) that uses an accessible color token (e.g.,
--focus-color) so keyboard users can see focus on the CTA button; ensure you
remove the outline:none rule and add the new focus style to the .cButton
ruleset.


/* ============================
RESPONSIVE
============================ */
@media (max-width: 768px) {
.offeringCard {
padding: 1.75rem 1.25rem;
}


.buttonGroup {
flex-direction: column;
}

.cButton {
width: 100%;
}
}
98 changes: 98 additions & 0 deletions src/pages/enterprise.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import type {ReactNode} from 'react';
import React from 'react';
import Layout from '@theme/Layout';
import useBaseUrl from '@docusaurus/useBaseUrl';
import SectionHeader from '@site/src/components/common/SectionHeader';
import styles from './enterprise.module.css';

const features = [
{
label: '24/7 incident support.',
detail: 'Global, round-the-clock support with aggressive SLAs for production-stopping issues.',
},
{
label: 'Proactive security monitoring.',
detail: '',
},
{
label: 'Dedicated onboarding support',
detail: 'to help you move from legacy CI/CD to a modern IDP.',
},
{
label: "Direct access to OpenChoreo's core engineers and WSO2's customer success team",
detail: 'for architectural advice, tuning, and best practices.',
},
];

/**
* Enterprise page (/enterprise)
*
* Lists enterprise support offerings for OpenChoreo.
* Currently features the WSO2 Developer Platform for OpenChoreo offering,
* including a feature list and a CTA linking to the WSO2 product page.
*/
export default function Enterprise(): ReactNode {
return (
<Layout
title="Enterprise"
description="Enterprise support options for OpenChoreo, originally created by WSO2 and a CNCF Sandbox Project."
>
<div className={styles.root}>
<main className="container margin-vert--xl">

{/* HERO */}
<section className="margin-bottom--lg">
<SectionHeader title="Enterprise OpenChoreo Offerings">
<p>
OpenChoreo was originally created by WSO2 and is a CNCF Sandbox Project.<br />
You can find enterprise support options for the project below.
</p>
</SectionHeader>
</section>

{/* OFFERING CARD */}
<section>
<div className={styles.offeringCard}>
<div className={styles.offeringHeader}>
<img
src={useBaseUrl('/img/logos/tech-logo-wso2.webp')}
alt="WSO2"
className={styles.providerLogo}
/>
<span className={styles.offeringHeaderText}>Developer Platform for OpenChoreo</span>
</div>
<p className={styles.offeringTagline}>
Get open source flexibility with enterprise platform reliability. Direct access to
architects and developers from the creators of OpenChoreo.
</p>

<ul className={styles.featureList}>
{features.map((f, i) => (
<li key={i} className={styles.featureItem}>
<span className={styles.featureIcon}>✓</span>
<span>
<span className={styles.featureLabel}>{f.label}</span>
{f.detail && ` ${f.detail}`}
</span>
</li>
))}
</ul>

<div className={styles.buttonGroup}>
<a
href="https://wso2.com/engineering-platform/openchoreo/"
target="_blank"
rel="noopener noreferrer"
className={styles.cButton}
>
Learn More
</a>
</div>
</div>
</section>

</main>
</div>
</Layout>
);
}