diff --git a/src/components/OryHeroDemo.jsx b/src/components/OryHeroDemo.jsx index c42c861b19..ec3a4bb6bf 100644 --- a/src/components/OryHeroDemo.jsx +++ b/src/components/OryHeroDemo.jsx @@ -7,68 +7,7 @@ const OryHeroDemo = () => { const terminalRef = useRef(null) const script = [ - // CLI setup - { type: "comment", text: "# One-time project setup via Ory CLI", delay: 0 }, - { type: "command", text: "brew install ory/tap/cli", delay: 300 }, - { type: "output", text: "Installing ory...", delay: 500 }, - { type: "success", text: "✓ Installed", delay: 600 }, - { type: "command", text: "ory auth", delay: 400 }, - { - type: "output", - text: "Opening browser to create your Ory developer account...", - delay: 500, - }, - { type: "success", text: "✓ Authenticated as ", delay: 700 }, - { type: "command", text: 'ory create project --name "MyApp"', delay: 400 }, - { type: "output", text: "Project slug: myapp-abc123", delay: 600 }, - { type: "success", text: "✓ Project created", delay: 200 }, - - // API registration - { type: "comment", text: "# Register a user via Ory API", delay: 600 }, - { - type: "note", - text: "Note: Traits depend on your identity schema. This sample uses Ory's 'username' preset schema.", - delay: 400, - }, - { type: "command", text: "curl -s -X GET \\", delay: 300 }, - { - type: "command-cont", - text: ' "https://.projects.oryapis.com/self-service/registration/api"', - delay: 100, - }, - { - type: "output", - text: '{ "id": "", "type": "api", "expires_at":"...","issued_at":"...","request_url":"/self-service/registration/api","ui":{"action":".projects.oryapis.com/self-service/registration?flow=","method":"POST", ... } }', - delay: 500, - }, - { type: "command", text: "curl -s -X POST \\", delay: 400 }, - { - type: "command-cont", - text: ' -H "Content-Type: application/json" \\', - delay: 100, - }, - { - type: "command-cont", - text: ' -d \'{"traits":{"username":""},"password":"","method":"password"}\' \\', - delay: 100, - }, - { - type: "command-cont", - text: ' "https://.projects.oryapis.com/self-service/registration?flow="', - delay: 100, - }, - { - type: "output", - text: '{"identity":{"id":"...","schema_id":"preset://username","schema_url":".projects.oryapis.com/schemas/cHJlc2V0Oi8vdXNlcm5hbWU","state":"active", ... } }', - delay: 600, - }, - { type: "success", text: "✓ User registered!", delay: 400 }, - { - type: "link", - text: "Create your free project via Ory Console →", - url: "https://console.ory.sh/", - delay: 300, - }, + { type: "command", text: "npm install @ory/elements-react @ory/nextjs", delay: 300 }, ] const runDemo = async () => { @@ -255,8 +194,7 @@ const OryHeroDemo = () => { {/* Initial prompt when empty */} {lines.length === 0 && !isRunning && (
- $ From zero to registered user - in minutes! Click 'Run'. + ${" "}
)} @@ -320,21 +258,10 @@ const OryHeroDemo = () => { ...(isRunning ? styles.runButtonDisabled : styles.runButton), }} > - {isRunning ? "Running..." : hasRun ? "Run Again" : "Run"} + Try it - {hasRun && !isRunning && ( - - )} - - {/* Caption */} -

From zero to registered user in minutes.

) } diff --git a/src/components/welcomePage/DeploymentAndFrameworkSection.tsx b/src/components/welcomePage/DeploymentAndFrameworkSection.tsx new file mode 100644 index 0000000000..a11fa65c44 --- /dev/null +++ b/src/components/welcomePage/DeploymentAndFrameworkSection.tsx @@ -0,0 +1,804 @@ +import React, { useState } from "react" +import Link from "@docusaurus/Link" +import Mermaid from "@theme/Mermaid" +import IconTerminal from "@site/src/static/img/icons/terminal.svg" +import IconTypescript from "@site/src/static/img/icons/typescript.svg" +import IconNextjs from "@site/src/static/img/icons/nextjs.svg" +import IconVue from "@site/src/static/img/icons/vue.svg" +import IconGo from "@site/src/static/img/icons/go.svg" +import IconCopy from "@site/src/static/img/icons/copy.svg" +import { StepBadge } from "./StepBadge" +import { colors, radius, spacing, typography } from "./tokens" + +const MermaidAny = Mermaid as any + +export function DeploymentAndFrameworkSection() { + type FrameworkValue = "typescript" | "nextjs" | "vue" | "go" + const [selectedFramework, setSelectedFramework] = + useState("nextjs") + + const cards = [ + { + label: "Ory Network", + description: + "Managed identity, OAuth2/OIDC, and permissions. Best choice for new projects.", + to: "/network/getting-started", + tags: ["Cloud", "Multi-region", "Production ready"], + }, + { + label: "Ory Enterprise License", + description: + "Self-host Ory with enterprise support, SLAs, and advanced compliance options.", + to: "/oel/getting-started", + tags: ["Self-hosted", "Enterprise"], + }, + { + label: "Open Source", + description: + "Use the individual Ory projects directly and run everything yourself.", + to: "/oss/getting-started", + tags: ["Open Source", "Multi-region"], + }, + ] + + const langs: Array<{ + value: FrameworkValue + label: string + Icon: React.ComponentType> + snippet: string + }> = [ + { + value: "typescript", + label: "Typescript", + Icon: IconTypescript as React.ComponentType< + React.SVGProps + >, + snippet: `npm install @ory/elements-react @ory/nextjs`, + }, + { + value: "nextjs", + label: "Next.js", + Icon: IconNextjs as React.ComponentType>, + snippet: `npm install @ory/elements-react @ory/nextjs`, + }, + { + value: "vue", + label: "Vue", + Icon: IconVue as React.ComponentType>, + snippet: `npm install @ory/elements-react @ory/nextjs`, + }, + { + value: "go", + label: "Go", + Icon: IconGo as React.ComponentType>, + snippet: `npm install @ory/elements-react @ory/nextjs`, + }, + ] + + const selectedLang = langs.find((l) => l.value === selectedFramework) ?? langs[1] + const selectedSnippet = selectedLang.snippet + const snippetPrefix = selectedSnippet.startsWith("npm install ") + ? "npm install " + : "" + const snippetRest = snippetPrefix + ? selectedSnippet.slice(snippetPrefix.length) + : selectedSnippet + + return ( +
+
+
+ {/* Choose a deployment option */} +
+
+ +

+ Choose a deployment option +

+

+ Choose the deployment option that fits your organization and + build secure IAM into your apps. You can switch later — the core + concepts stay the same. +

+
+ +
+ {cards.map((card) => ( +
+
+
+

+ {card.label} +

+

+ {card.description} +

+
+
+ {card.tags.map((tag) => { + const isCloud = tag === "Cloud" + const isEnterprise = tag === "Enterprise" + return ( + + {tag} + + ) + })} +
+ + Learn more + + → + + +
+
+ ))} +
+
+ + {/* Design your Ory solution */} +
+
+ +

+ Design your Ory solution +

+

+ The following steps will help us tailor a better developer + experience for you +

+
+ +
+
+
+
+ API Endpoint 2" } + +User --> Devices +Devices --> Oathkeeper +Oathkeeper -->|protects| API +Oathkeeper -->|authenticates credentials with| Hydra +User -->|Registers, log in,
manages profile via API| Kratos +User -->|Registers, logs in,
manages profile via prebuilt UI| Elements +Elements --> Kratos +Elements --> Hydra +Oathkeeper -->|checks session with| Kratos +Oathkeeper -->|checks permissions with| Keto +Devices --> API +API -->|OAuth2| Hydra +API -->|Checks session with| Kratos +API -->|Checks permissions with| Keto +Kratos -->|OIDC| Polis + +style Kratos fill:transparent,stroke:none +style Hydra fill:transparent,stroke:none +style Keto fill:transparent,stroke:none +style Polis fill:transparent,stroke:none +style Oathkeeper fill:transparent,stroke:none +style Elements fill:transparent,stroke:none`} + /> + + +
+
+
+ +
+
+ + Step 1 out of 6 + +
+ +
+
+

+ Do you need identity management (user registration, profile + management)? +

+
+ +
+
+ {[ + { + value: "yes", + label: "Yes, I need an identity system", + key: "1", + }, + { + value: "no", + label: "No, I have an existing identity system", + key: "2", + }, + { value: "idk", label: "I don’t know", key: "3" }, + ].map((option) => ( + + ))} +
+
+
+
+ +
+ + Create a architecture diagram based on your requirements + + +
+
+
+ + {/* Select your framework or language */} +
+
+ +

+ Select your framework or language +

+

+ Drop Ory into an existing app. Pick your stack and follow the + step-by-step integration guides. +

+
+ +
+
+
+ +
+ +
+ {langs.map((lang) => { + const active = lang.value === selectedFramework + const LangIcon = lang.Icon + const iconStroke = active + ? colors.brandOnTertiary + : colors.textPrimary + return ( + + ) + })} +
+ + +
+ +
+ + 1 + + + {snippetPrefix ? ( + <> + + {snippetPrefix} + + + {snippetRest} + + + ) : ( + + {selectedSnippet} + + )} + +
+
+
+
+
+
+ ) +} + diff --git a/src/components/welcomePage/HowToUseSection.tsx b/src/components/welcomePage/HowToUseSection.tsx new file mode 100644 index 0000000000..310c596768 --- /dev/null +++ b/src/components/welcomePage/HowToUseSection.tsx @@ -0,0 +1,176 @@ +import React from "react" +import Link from "@docusaurus/Link" +import { colors, spacing, typography } from "./tokens" +import styles from "@site/src/pages/welcome.module.css" + +export function HowToUseSection() { + const guides = [ + { + title: "Want to learn more about a specific product suite or solution?", + description: "Go directly to product and solution specific information.", + links: [ + { label: "Products", to: "/products/products-overview" }, + { label: "Solutions", to: "/solutions/solutions-overview" }, + ], + }, + { + title: "Want to start coding and need an example?", + description: "Want to start coding and need an example?", + links: [{ label: "Quickstarts", to: "/getting-started/overview" }], + }, + { + title: "Want to find the right API to use?", + description: "Go directly to the REST API, SDKs, or CLI references.", + links: [{ label: "Reference", to: "/reference/reference-overview" }], + }, + ] + + return ( +
+
+
+

+ How to use the Ory Developer Portal +

+

+ Not sure where to start? Follow our guided paths—structured journeys + that walk you through Ory's products and solutions so you can learn + and build faster. +

+
+ +
+ {guides.map((guide, index) => ( +
+
+

+ {guide.title} +

+

+ {guide.description} +

+
+
+ {guide.links.map((link, linkIndex) => ( + + {link.label} + + → + + + ))} +
+
+ ))} +
+
+
+ ) +} + diff --git a/src/components/welcomePage/OtherGuides.tsx b/src/components/welcomePage/OtherGuides.tsx new file mode 100644 index 0000000000..5a2cceff13 --- /dev/null +++ b/src/components/welcomePage/OtherGuides.tsx @@ -0,0 +1,224 @@ +import React from "react" +import Link from "@docusaurus/Link" +import { colors, radius, spacing, typography } from "./tokens" + +export function OtherGuides() { + const guides = [ + { + label: "Installl from green-field", + to: "/getting-started/overview", + description: "What Ory Identities (Kratos) is and when to use it", + }, + { + label: "Migrate to Ory", + to: "/kratos/self-service/flows/user-login-user-registration", + description: "Day 1 essentials for browser-based authentication", + }, + { + label: "Ory Architecture", + to: "/kratos/self-service/flows/user-login-user-registration", + description: "What Ory Identities (Kratos) is and when to use it", + tags: ["Ory / Kratos", "Tutorial"], + }, + ] + + return ( +
+
+
+

+ Other guides +

+

+ Not sure where to start? Follow our guided paths—structured journeys + that walk you through Ory's products and solutions so you can learn + and build faster. +

+
+ +
+
+ {guides.slice(0, 2).map((guide) => ( +
+
+
+
+

+ + {guide.label} + +

+

+ {guide.description} +

+
+
+ ))} +
+
+ {guides.slice(2).map((guide) => ( +
+
+
+
+
+

+ + {guide.label} + +

+ {guide.tags?.map((tag) => ( + + {tag} + + ))} +
+

+ {guide.description} +

+
+
+ ))} +
+
+
+
+ ) +} + diff --git a/src/components/welcomePage/StartHeading.tsx b/src/components/welcomePage/StartHeading.tsx new file mode 100644 index 0000000000..fb18eb14d7 --- /dev/null +++ b/src/components/welcomePage/StartHeading.tsx @@ -0,0 +1,39 @@ +import React from "react" +import OryHeroDemo from "@site/src/components/OryHeroDemo" +import backgroundPattern from "@site/src/static/img/background-pattern.png" +import { colors, spacing } from "./tokens" +import styles from "@site/src/pages/welcome.module.css" + +export function StartHeading() { + return ( +
+
+
+
+

Welcome to the Ory Developer Portal

+

+ Ory gives you authentication, authorization, and user management + APIs designed for modern applications. Start fast, scale to + millions, and keep security best practices baked in. +

+
+
+ +
+
+
+
+ ) +} + diff --git a/src/components/welcomePage/StepBadge.tsx b/src/components/welcomePage/StepBadge.tsx new file mode 100644 index 0000000000..7d87eea4e2 --- /dev/null +++ b/src/components/welcomePage/StepBadge.tsx @@ -0,0 +1,35 @@ +import React from "react" +import { colors, radius, typography } from "./tokens" + +export function StepBadge({ step }: { step: number }) { + return ( +
+ + {step} + +
+ ) +} + diff --git a/src/components/welcomePage/tokens.ts b/src/components/welcomePage/tokens.ts new file mode 100644 index 0000000000..cb6539d1b9 --- /dev/null +++ b/src/components/welcomePage/tokens.ts @@ -0,0 +1,70 @@ +// Shared tokens for `src/pages/welcome.tsx` sections + +export const colors = { + textPrimary: "#0f172a", + textSecondary: "#334155", + textTertiary: "#64748b", + textTertiaryAlt: "#94a3b8", + brandPrimary: "#383bca", + brandPrimaryAlt: "#6366f1", + brandOnPrimary: "#eef", + brandOnTertiary: "#2e3081", + backgroundPrimary: "#ffffff", + backgroundSecondary: "#f8fafc", + backgroundSecondaryHover: "#e2e8f0", + backgroundTertiary: "#e2e8f0", + backgroundDark: "#0f172a", + backgroundDarkSecondary: "#1e293b", + backgroundBrandTertiary: "#e0e1ff", + borderPrimary: "#cbd5e1", + borderDark: "#334155", + borderBrandTertiary: "#6366f1", + borderInfoTertiary: "#0ea5e9", + infoPrimary: "#0ea5e9", + infoSecondary: "#bae6fd", + infoTertiary: "#e0f2fe", + infoOnTertiary: "#0c4a6e", + disabled: "#e2e8f0", + disabledBorder: "#cbd5e1", + disabledText: "#94a3b8", +} as const + +export const spacing = { + size0: "0px", + size0_5: "2px", + size1: "4px", + size1_5: "6px", + size2: "8px", + size2_5: "10px", + size3: "12px", + size4: "16px", + size5: "20px", + size6: "24px", + size8: "32px", + size12: "48px", + size16: "64px", +} as const + +export const typography = { + fontFamily: "Inter, sans-serif", + fontFamilyMono: "JetBrains Mono, monospace", + fontSizeXs: "12px", + fontSizeSm: "14px", + fontSizeBase: "16px", + fontSizeLg: "20px", + fontSizeXl: "24px", + fontSize2xl: "40px", + lineHeightTight: "1.25", + lineHeightNormal: "1.5", + lineHeightRelaxed: "1.65", + fontWeightNormal: "400", + fontWeightMedium: "500", +} as const + +export const radius = { + badge: "6px", + keyboard: "6px", + buttons: "4px", + general: "4px", +} as const + diff --git a/src/css/theme.css b/src/css/theme.css index d5647d7020..61c1799040 100644 --- a/src/css/theme.css +++ b/src/css/theme.css @@ -358,6 +358,321 @@ "calt" 1; /* fix for Chrome */ } +/* ---------------------------- + Navbar (Figma node 5046:5330) + Exact styling from Figma design +----------------------------- */ +:root { + --ory-navbar-height: 48px; + --ory-navbar-bg: #ffffff; + --ory-navbar-border: #cbd5e1; + --ory-navbar-text: #0f172a; + --ory-navbar-link: #0f172a; + --ory-navbar-link-hover: #383bca; + --ory-navbar-font-size: 14px; + --ory-navbar-gap: 24px; + --ory-navbar-left-width: 312px; + --ory-navbar-left-padding-x: 16px; + --ory-navbar-content-padding-left: 32px; + --ory-navbar-right-width: auto; + --ory-navbar-right-gap: 24px; + --ory-search-width: 200px; +} + +.navbar { + height: 48px !important; + min-height: 48px !important; + max-height: 48px !important; + background: var(--ory-navbar-bg); + border-bottom: 1px solid var(--ory-navbar-border); + box-shadow: none; + padding: 0; +} + +.navbar__inner { + height: 100%; + max-width: 1920px; + margin: 0 auto; + display: flex; + gap: 0; + align-items: center; + padding: 0 8px; +} + +/* Left logo section - 312px with borders */ +.navbar__brand { + width: var(--ory-navbar-left-width); + max-width: var(--ory-navbar-left-width); + border-left: 1px solid var(--ory-navbar-border); + border-right: 1px solid var(--ory-navbar-border); + padding: 0 var(--ory-navbar-left-padding-x); + height: 100%; + display: flex; + align-items: center; + flex-shrink: 0; + position: relative; +} + +.navbar__logo { + display: flex; + align-items: center; + gap: 6px; + height: 24px; + flex: 1 0 0; + padding: 4px; +} + +.navbar__logo img { + height: 14.6px; + width: 40.15px; + display: block; + flex-shrink: 0; +} + +.navbar__logo::after { + content: "/ Documentation"; + display: inline-block; + font-family: Inter, sans-serif; + font-size: 20px; + font-weight: 400; + line-height: 1; + flex-shrink: 0; + margin-left: 6px; + white-space: nowrap; + background: linear-gradient( + to right, + #383bca 0, + #383bca 1ch, + var(--ory-navbar-text) 1ch, + var(--ory-navbar-text) 100% + ); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + color: var(--ory-navbar-text); +} + +/* Dropdown icon after logo area */ +.navbar__brand::after { + content: ""; + display: block; + width: 16px; + height: 16px; + background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath stroke='%230f172a' stroke-width='1.5' fill='none' d='M4 6l4 4 4-4'/%3E%3C/svg%3E") no-repeat center; + background-size: contain; + margin-left: 4px; + flex-shrink: 0; +} + +/* Middle nav links */ +.navbar__items { + flex: 1 0 0; + gap: var(--ory-navbar-gap); + font-size: var(--ory-navbar-font-size); + font-weight: 400; + line-height: 1; + color: var(--ory-navbar-text); + padding-left: var(--ory-navbar-content-padding-left); + display: flex; + align-items: center; +} + +.navbar__link { + color: var(--ory-navbar-link); + font-weight: 400; + font-size: 14px; + line-height: 1; + white-space: nowrap; +} + +.navbar__link:hover, +.navbar__link--active { + color: var(--ory-navbar-link-hover); +} + +/* Ensure all navbar items have consistent width */ +.navbar__item { + flex-shrink: 0; + min-width: fit-content; +} + +.navbar__item .navbar__link { + display: inline-block; + width: auto; + min-width: fit-content; +} + +/* Right section - Links and Search */ +.navbar__items--right { + gap: var(--ory-navbar-right-gap); + display: flex; + align-items: center; + flex-shrink: 0; +} + +/* Search input styling from Figma node 5211:5845 */ +.navbar .DocSearch-Button, +.navbar__items--right .DocSearch-Button, +.DocSearch-Button { + width: var(--ory-search-width) !important; + max-width: var(--ory-search-width) !important; + height: auto !important; + min-height: 32px !important; + border: 1px solid var(--ory-navbar-border) !important; + background: #fff !important; + border-radius: 0 !important; + box-shadow: none !important; + color: var(--ory-navbar-text) !important; + font-size: 16px !important; + font-family: Inter, sans-serif !important; + font-weight: 400 !important; + line-height: 1.25 !important; + padding: 0 !important; + padding-left: 4px !important; + padding-right: 12px !important; + display: flex !important; + align-items: center !important; + gap: 0 !important; + flex-shrink: 0 !important; + margin: 0 !important; +} + +.navbar .DocSearch-Button-Placeholder, +.navbar__items--right .DocSearch-Button-Placeholder { + color: #64748b !important; + font-size: 16px !important; + font-family: Inter, sans-serif !important; + font-weight: 400 !important; + padding: 8px !important; + flex: 1 0 0 !important; + overflow: hidden !important; + text-overflow: ellipsis !important; + white-space: nowrap !important; +} + +/* Search icon wrapper - DocSearch uses SVG */ +.navbar .DocSearch-Button .DocSearch-Search-Icon, +.navbar__items--right .DocSearch-Button .DocSearch-Search-Icon, +.navbar .DocSearch-Button svg, +.navbar__items--right .DocSearch-Button svg { + padding: 8px !important; + flex-shrink: 0 !important; + width: 16px !important; + height: 16px !important; + color: var(--ory-navbar-text) !important; + margin: 0 !important; +} + +/* ⌘K keyboard shortcut badge - Figma node 5211:5845 */ +/* Container for keyboard keys */ +.navbar .DocSearch-Button-Key, +.navbar__items--right .DocSearch-Button-Key, +.navbar .DocSearch-Button-Keys, +.navbar__items--right .DocSearch-Button-Keys, +.DocSearch-Button-Key, +.DocSearch-Button-Keys { + background: #e2e8f0 !important; + color: #64748b !important; + border-radius: 6px !important; + box-shadow: none !important; + border: none !important; + height: 20px !important; + min-width: 20px !important; + padding: 0 4px !important; + display: flex !important; + align-items: center !important; + justify-content: center !important; + font-family: Inter, sans-serif !important; + font-size: 12px !important; + font-weight: 500 !important; + line-height: 1.25 !important; + margin-left: auto !important; + gap: 2px !important; + opacity: 1 !important; + visibility: visible !important; +} + +/* All text content inside keyboard badge - ensure visibility */ +.navbar .DocSearch-Button-Key *, +.navbar__items--right .DocSearch-Button-Key *, +.navbar .DocSearch-Button-Keys *, +.navbar__items--right .DocSearch-Button-Keys *, +.DocSearch-Button-Key *, +.DocSearch-Button-Keys * { + color: #64748b !important; + opacity: 1 !important; + visibility: visible !important; +} + +/* Individual key elements (kbd tags) inside the badge */ +.navbar .DocSearch-Button-Key kbd, +.navbar__items--right .DocSearch-Button-Key kbd, +.navbar .DocSearch-Button-Keys kbd, +.navbar__items--right .DocSearch-Button-Keys kbd, +.DocSearch-Button-Key kbd, +.DocSearch-Button-Keys kbd, +.navbar .DocSearch-Button-Key > kbd, +.navbar__items--right .DocSearch-Button-Key > kbd, +.navbar .DocSearch-Button-Keys > kbd, +.navbar__items--right .DocSearch-Button-Keys > kbd { + background: transparent !important; + border: none !important; + box-shadow: none !important; + padding: 0 !important; + margin: 0 !important; + font-family: Inter, sans-serif !important; + font-size: 12px !important; + font-weight: 500 !important; + line-height: 1.25 !important; + color: #64748b !important; + min-width: auto !important; + height: auto !important; + display: inline !important; + opacity: 1 !important; + visibility: visible !important; +} + +/* Text/span elements inside the keyboard badge */ +.navbar .DocSearch-Button-Key span, +.navbar__items--right .DocSearch-Button-Key span, +.navbar .DocSearch-Button-Keys span, +.navbar__items--right .DocSearch-Button-Keys span, +.DocSearch-Button-Key span, +.DocSearch-Button-Keys span, +.navbar .DocSearch-Button-Key > span, +.navbar__items--right .DocSearch-Button-Key > span, +.navbar .DocSearch-Button-Keys > span, +.navbar__items--right .DocSearch-Button-Keys > span { + font-family: Inter, sans-serif !important; + font-size: 12px !important; + font-weight: 500 !important; + line-height: 1.25 !important; + color: #64748b !important; + display: inline !important; + opacity: 1 !important; + visibility: visible !important; +} + +/* Direct text content and any other elements */ +.navbar .DocSearch-Button-Key, +.navbar__items--right .DocSearch-Button-Key, +.navbar .DocSearch-Button-Keys, +.navbar__items--right .DocSearch-Button-Keys { + text-align: center !important; + white-space: nowrap !important; + color: #64748b !important; +} + +/* Ensure text nodes are visible */ +.navbar .DocSearch-Button-Key::before, +.navbar__items--right .DocSearch-Button-Key::before, +.navbar .DocSearch-Button-Keys::before, +.navbar__items--right .DocSearch-Button-Keys::before { + display: none !important; +} + + + @supports (font-variation-settings: normal) { :root { --ifm-font-family-base: InterVariable, var(--ifm-font-family-base-fallback); @@ -564,3 +879,110 @@ svg[class*="iconExternalLink"] { transform: scale(0.667) !important; transform-origin: center center !important; } + +/* Code sample tabs styling for welcome page */ +.tabs-container[data-group-id="language-quickstarts"] .tabs { + display: flex; + gap: 0; + margin-bottom: 16px; + padding-left: 0; +} + +.tabs-container[data-group-id="language-quickstarts"] .tabs__item { + background: #ffffff; + border: 1px solid #cbd5e1; + border-right: none; + border-radius: 0; + padding: 10px 16px; + display: inline-flex; + align-items: center; + gap: 12px; + font-family: Inter, sans-serif; + font-size: 14px; + font-weight: 400; + line-height: 1; + color: #0f172a; + cursor: pointer; + transition: none; + border-bottom: 3px solid transparent; +} + +.tabs-container[data-group-id="language-quickstarts"] .tabs__item:last-child { + border-right: 1px solid #cbd5e1; +} + +.tabs-container[data-group-id="language-quickstarts"] .tabs__item:hover { + background-color: #ffffff; +} + +.tabs-container[data-group-id="language-quickstarts"] .tabs__item--active { + background: #e0e1ff; + border-color: #6366f1; + border-right: 1px solid #6366f1; + color: #2e3081; + border-bottom-color: #6366f1; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + z-index: 1; + position: relative; +} + +.tabs-container[data-group-id="language-quickstarts"] .tabs__item--active:hover { + background-color: #e0e1ff; +} + +/* Override CodeBlock background in code sample tabs */ +.tabs-container[data-group-id="language-quickstarts"] ~ * [class*="theme-code-block"], +.tabs-container[data-group-id="language-quickstarts"] [class*="theme-code-block"], +.tabs-container[data-group-id="language-quickstarts"] pre, +.tabs-container[data-group-id="language-quickstarts"] code { + background: #ffffff !important; + border: none !important; +} + +.tabs-container[data-group-id="language-quickstarts"] .tabs__item > div > div:last-child { + background: #ffffff !important; + border: none !important; +} + +.tabs-container[data-group-id="language-quickstarts"] .tabs__item > div > div:last-child code { + background: transparent !important; + border: none !important; +} + +.tabs-container[data-group-id="language-quickstarts"] .tabs__item > div > div:last-child span { + background: transparent !important; + border: none !important; +} + +.tabs-container[data-group-id="language-quickstarts"] .tabs__item > div > div:last-child * { + border: none !important; +} + +/* Override Docusaurus styles for code sample body in framework selection section */ +.code-sample-body { + background: #ffffff !important; + border: 1px solid #cbd5e1 !important; +} + +.code-sample-body code { + background: transparent !important; + border: none !important; + padding: 0 !important; + font-family: "JetBrains Mono", monospace !important; + font-size: 14px !important; + line-height: 1.65 !important; + color: #0f172a !important; +} + +.code-sample-body code span { + background: transparent !important; + border: none !important; + padding: 0 !important; +} + +.code-sample-body span { + background: transparent !important; + border: none !important; + padding: 0 !important; +} diff --git a/src/navbar.ts b/src/navbar.ts index 2ff779fe1b..839aa25b36 100644 --- a/src/navbar.ts +++ b/src/navbar.ts @@ -7,11 +7,11 @@ export const navbar: Navbar = { hideOnScroll: false, logo: { alt: "Ory", - src: `/docs/img/logos/logo-docs-2023-02-15.svg`, - srcDark: `/docs/img/logos/logo-docs-dark-2023-02-15.svg`, + src: `/docs/img/logos/ory-logo.svg`, + srcDark: `/docs/img/logos/ory-logo.svg`, href: `https://www.ory.com`, - width: 63, - height: 32, + width: 44, + height: 16, }, items: [ @@ -27,129 +27,36 @@ export const navbar: Navbar = { position: "left", }, { - type: "dropdown", - to: "products/products-overview", + type: "doc", + docId: "products/products-overview", label: "Products", position: "left", - items: [ - { - type: "doc", - docId: "network/getting-started/index", - label: "Ory Network", - }, - { - type: "doc", - docId: "oel/getting-started/index", - label: "Ory Enterprise License", - }, - { - type: "doc", - docId: "oss/getting-started/index", - label: "Ory Open Source", - }, - ], }, { - type: "dropdown", - to: "/docs/solutions/solutions-overview", + type: "doc", + docId: "solutions/solutions-overview", label: "Solutions", position: "left", - items: [ - { - type: "doc", - docId: "solutions/solution_CIAM", - label: "CIAM", - }, - { - type: "doc", - docId: "solutions/solution_B2B", - label: "B2B IAM", - }, - { - type: "doc", - docId: "solutions/solution_agentic", - label: "Agentic IAM", - }, - ], }, - { - type: "dropdown", - to: "/docs/reference/reference-overview", + type: "doc", + docId: "reference/reference-overview", label: "Reference", position: "left", - items: [ - { - to: "/docs/reference/api", - label: "REST API", - }, - { - to: "/docs/category/ory-cli-reference", - label: "Ory CLI", - }, - { - to: "/docs/sdk", - label: "Ory SDKs", - }, - { - to: "/docs/category/operations-reference", - label: "Operations", - }, - ], }, { - label: "Change Log", + label: "Change log", + to: "/docs/ecosystem/changelog", position: "left", - items: [ - { - to: "https://changelog.ory.com/?categories=cat_6MGGeXN7WohDH", - label: "Ory Network", - }, - { - to: "https://changelog.ory.com/?categories=cat_s3C6qgDr7FEyo%2Ccat_n9fSarZSCxDTl%2Ccat_ZTXuym1ZfOYZx%2Ccat_YZLKJTlx35HVW", - label: "Ory OEL", - }, - - { - to: "/docs/oss/changelog", - label: "Ory OSS", - }, - ], }, { - label: "Need Support?", + label: "Need support?", + href: "https://www.ory.com/support", position: "right", - items: [ - { - to: "https://www.ory.com/support", - label: "Enterprise Support", - }, - { - to: "https://www.ory.com/docs/search", - label: "Search the docs", - }, - { - to: "https://www.ory.com/chat", - label: "Ory Community Slack", - }, - { - to: "https://github.com/orgs/ory/discussions", - label: "GitHub Discussions", - }, - { - to: "https://stackoverflow.com/questions/tagged/ory", - label: "Stack Overflow", - }, - { - to: "https://www.ory.com/contact", - label: "Schedule a discovery call", - }, - ], }, - { - href: `https://github.com/ory`, - label: "GitHub", + label: "Github", + href: "https://github.com/ory", position: "right", }, ], diff --git a/src/pages/welcome.module.css b/src/pages/welcome.module.css new file mode 100644 index 0000000000..beadfa3760 --- /dev/null +++ b/src/pages/welcome.module.css @@ -0,0 +1,213 @@ + :root { + /* Local page tokens from Figma node 4994:5842/6425 */ + --home-text-primary: #0f172a; + --home-text-secondary: #334155; + --home-text-tertiary: #64748b; + --home-text-tertiary-alt: #94a3b8; + --home-brand-primary: #383bca; + --home-brand-primary-alt: #6366f1; + --home-brand-on-primary: #eef; + --home-brand-on-tertiary: #2e3081; + + --home-bg-primary: #fff; + --home-bg-secondary: #f8fafc; + --home-bg-secondary-hover: #e2e8f0; + --home-bg-tertiary: #e2e8f0; + --home-bg-dark: #0f172a; + --home-bg-dark-secondary: #1e293b; + --home-bg-brand-tertiary: #e0e1ff; + + --home-border-primary: #cbd5e1; + --home-border-dark: #334155; + --home-border-brand-tertiary: #6366f1; + --home-border-info-tertiary: #0ea5e9; + + --home-info-primary: #0ea5e9; + --home-info-tertiary: #e0f2fe; + --home-info-on-tertiary: #0c4a6e; + + --home-disabled: #e2e8f0; + --home-disabled-border: #cbd5e1; + --home-disabled-text: #94a3b8; + + --home-radius: 6px; + + --home-s0: 0px; + --home-s0_5: 2px; + --home-s1: 4px; + --home-s1_5: 6px; + --home-s2: 8px; + --home-s2_5: 10px; + --home-s3: 12px; + --home-s4: 16px; + --home-s5: 20px; + --home-s6: 24px; + --home-s12: 48px; + --home-s16: 64px; +} + +.container1024 { + max-width: 1024px; +} +.heroTop { + padding-top: var(--home-s16); + padding-bottom: 0; + background-size: auto auto, 208px 112px; + background-position: top left; +} +.heroRow { + display: flex; + gap: var(--home-s6); + align-items: center; + margin-bottom: var(--home-s6); +} +.heroCopy { + flex: 1 0 0; + display: flex; + flex-direction: column; + gap: var(--home-s6); +} +.h1 { + font-family: Inter, sans-serif; + font-size: 40px; + font-weight: 400; + line-height: 1.25; + color: var(--home-text-primary); + margin: 0; +} +.pBase { + font-family: Inter, sans-serif; + font-size: 16px; + font-weight: 400; + line-height: 1.5; + color: var(--home-text-secondary); + margin: 0; +} +.sectionTitle { + font-family: Inter, sans-serif; + font-size: 24px; + font-weight: 400; + line-height: 1.5; + color: var(--home-text-primary); + margin: 0; +} +.sectionSubtitle { + font-family: Inter, sans-serif; + font-size: 16px; + font-weight: 400; + line-height: 1.5; + color: var(--home-text-secondary); + margin: 0; +} +.guidesGrid { + display: flex; + gap: var(--home-s6); + margin-bottom: var(--home-s6); +} +.guideCard { + flex: 1 0 0; + background: var(--home-bg-primary); + border-radius: var(--home-radius); + padding: var(--home-s6); + display: flex; + flex-direction: column; + justify-content: space-between; + min-height: 325px; +} +.guideTitle { + font-family: Inter, sans-serif; + font-size: 16px; + font-weight: 500; + line-height: 1.25; + color: var(--home-text-primary); + margin: 0; +} +.guideDesc { + font-family: Inter, sans-serif; + font-size: 16px; + font-weight: 400; + line-height: 1.5; + color: var(--home-text-tertiary); + margin: 0; +} +.linkArrow { + display: inline-flex; + gap: var(--home-s1); + align-items: center; + text-decoration: none; + color: var(--home-brand-primary); + font-family: Inter, sans-serif; + font-size: 16px; + line-height: 1.5; +} +.deploymentSection { + padding-top: var(--home-s16); + padding-bottom: var(--home-s16); +} +.deployGrid { + display: flex; + gap: var(--home-s3); +} +.deployCard { + flex: 1 0 0; + background: var(--home-bg-primary); + border: 1px solid var(--home-border-primary); + overflow: hidden; + display: flex; + flex-direction: column; +} +.deployBody { + display: flex; + flex-direction: column; + gap: var(--home-s6); + padding: var(--home-s6); +} +.badge { + background: var(--home-bg-tertiary); + padding: var(--home-s0_5) var(--home-s2); + border-radius: var(--home-radius); + font-family: Inter, sans-serif; + font-size: 12px; + line-height: 1.5; + color: var(--home-text-secondary); +} +.deployFooter { + background: var(--home-bg-secondary); + border-top: 1px solid var(--home-border-primary); + padding: var(--home-s3) var(--home-s6); +} +.setupSection { + padding-top: var(--home-s16); + padding-bottom: var(--home-s16); + background: var(--home-bg-secondary); +} +.uxContainer { + background: var(--home-bg-primary); + border: 1px solid var(--home-border-primary); + overflow: hidden; +} +.tabsPanel { + background: var(--home-bg-secondary-hover); + border: 1px solid var(--home-border-primary); + display: flex; + flex-direction: column; +} +.tabsPanelHeader { + display: flex; + justify-content: space-between; + align-items: center; + padding: var(--home-s2) var(--home-s4); +} +.tabsPanelBody { + background: var(--home-bg-secondary); + border-top: 1px solid var(--home-border-primary); + padding: var(--home-s6); +} +.infoBox { + background: var(--home-info-tertiary); + border: 1px solid var(--home-border-info-tertiary); + padding: var(--home-s6); + display: flex; + gap: var(--home-s6); + align-items: center; +} diff --git a/src/pages/welcome.tsx b/src/pages/welcome.tsx index 481e0419c1..7d102a963a 100644 --- a/src/pages/welcome.tsx +++ b/src/pages/welcome.tsx @@ -1,566 +1,18 @@ -// src/pages/welcome.tsx - import React from "react" import Layout from "@theme/Layout" -import Link from "@docusaurus/Link" -import CodeBlock from "@theme/CodeBlock" -import Tabs from "@theme/Tabs" -import TabItem from "@theme/TabItem" -import OryHeroDemo from "@site/src/components/OryHeroDemo" -import heroBg from "@site/src/static/img/background_image2.png" -import { ProductSelectorStepper } from "./_assets/product-selector-stepper" - -function StartHeading() { - const guides = [ - { - to: "/products", - }, - { - to: "/quickstarts", - }, - { - to: "/reference", - }, - ] - - return ( -
-
-
-

Welcome to the Ory Developer Portal

-
- - {/* Intro text and demo in two columns */} -
-
-

- Ory gives you authentication, authorization, and user management - APIs designed for modern applications.{" "} -

-

- Start fast, scale to millions, and keep security best practices - baked in. -

-
-
- -
-
- -
-

- How to use the Ory Developer Portal -

-
-
-

- Not sure where to start? Follow our guided - paths—structured journeys that walk you through Ory's products and - solutions so you can learn and build faster. -

-
- -
- {guides.map((guide, index) => ( -
-
- {index === 0 && ( -
-

- - Want to learn more about a specific product suite or - solution? - {" "} - Go directly to product and solution specific information. -

-
- )} - {index === 1 && ( -
-

- Want to start coding and need an example?{" "} - Take a look in the Quickstarts to find the framework and - language you want to use. -

-
- )} - {index === 2 && ( -
-

- Want to find the right API to use? Go - directly to the REST API, SDKs, or CLI references. -

-
- )} - {index === 0 && ( -
-

- Click on - - Products - {" "} - or{" "} - - Solutions - -

-
- )} - {index === 1 && ( -
-

- Click on - - Quickstarts - -

-
- )} - {index === 2 && ( -
-

- Click on - - Reference - -

-
- )} -
-
- ))} -
-
-
- ) -} - -function Hero() { - const cards = [ - { - label: "Ory Network", - description: - "Managed identity, OAuth2/OIDC, and permissions. Best choice for new projects.", - to: "/network/getting-started", - meta: "Cloud · multi-region · production-ready", - }, - { - label: "Ory Enterprise License", - description: - "Self-host Ory with enterprise support, SLAs, and advanced compliance options.", - to: "/oel/getting-started", - meta: "Self-hosted · enterprise", - }, - { - label: "Ory Open Source", - description: - "Use the individual Ory projects directly and run everything yourself.", - to: "/oss/getting-started", - meta: "Open source · fully self-managed", - }, - ] - - return ( -
-
- {/* Heading row above cards */} -
-
- Choose a deployment option -

- Choose the deployment option that fits your organization and build - secure IAM into your apps. You can switch later — the core - concepts stay the same. -

-
-
- - {/* Product cards - 3 columns */} -
- {cards.map((card) => ( -
-
-
-

- {card.label} -

-
-
-

- {card.description} -

-

- {card.meta} -

- - Learn more - -
-
-
- ))} -
-
-
- ) -} - -function ProductQuickstarts() { - return ( -
-
- Design your Ory solution - -
-
- ) -} - -function LanguageQuickstarts() { - const langs = [ - { - value: "javascript", - label: "JavaScript / TypeScript", - docs: "/getting-started/integrate-auth/react", - snippet: `npm install @ory/client`, - }, - { - value: "nextjs", - label: "Next.js", - docs: "/getting-started/integrate-auth/nextjs-app-router-quickstart", - snippet: `npx create-next-app my-app`, - }, - { - value: "vue", - label: "Vue", - docs: "/getting-started/integrate-auth/vue", - snippet: `npm create vue@latest`, - }, - { - value: "go", - label: "Go", - docs: "/getting-started/integrate-auth/go", - snippet: `go get github.com/ory/client-go`, - }, - ] - - return ( -
-
-
-
- - Select your framework or language - -

- Drop Ory into an existing app. Pick your stack and follow the - step-by-step integration guides. -

-
-
- - - {langs.map((lang) => ( - -
-
- {lang.snippet} -
-
-
-

- Follow the full guide for{" "} - {lang.label}. -

-
    -
  • Set up Ory SDK and environment variables
  • -
  • Protect routes with login and sessions
  • -
  • Handle logout, recovery, and verification flows
  • -
-
-
-
-
- ))} -
-
-
- ) -} - -function OtherGuides() { - const guides = [ - { - label: "Install from green-field", - to: "/getting-started/overview", - description: "Replace your home-grown IAM system.", - }, - { - label: "Migrate to Ory", - to: "/kratos/self-service/flows/user-login-user-registration", - description: "Plan your migration to Ory from an existing system.", - }, - { - label: "Ory architecture", - to: "/kratos/self-service/flows/user-login-user-registration", - description: "Understand the core building blocks and architecture.", - }, - ] - - return ( -
-
-
-
-

Other guides

-

- Opinionated, end-to-end walkthroughs to help you ship real - features, not just hello-world demos. -

-
-
- -
- {guides.map((guide) => ( -
-
-
-

- {guide.label} -

-
-
-

{guide.description}

-
-
-
- ))} -
-
-
- ) -} - -function ComponentsTools() { - const items = [ - { - label: "Ory Console", - to: "/cli/ory", - description: - "User interface to manage projects, configurations, and more.", - }, - { - label: "Ory Account Experience", - to: "/reference/api", - description: - "User interface for all self-service screens like login, registration, or consent.", - }, - { - label: "Ory Elements", - to: "/docs/elements", - description: - "Pre-built UI components for login, registration, and account flows.", - }, - { - label: "Ory Actions", - to: "/docs/kratos/hooks/configure-hooks", - description: - "Define custom business logic, automating system behavior in response to events, and integrating with third-party services.", - }, - { - label: "Changelog", - to: "/ecosystem/changelog", - description: "See what shipped recently across Ory products.", - }, - { - label: "Status & SLA", - to: "https://status.ory.com/", - description: "Monitor uptime and incident history for Ory services.", - }, - ] - - return ( -
-
-
-
-

Components & tools

-

- Everything around the core APIs: observability, tooling. -

-
-
- -
- {items.map((item) => ( -
-
-
-

- {item.to.startsWith("http") ? ( - {item.label} - ) : ( - {item.label} - )} -

-
-
-

{item.description}

-
-
-
- ))} -
-
-
- ) -} - -function SectionDivider() { - return ( -
- ) -} - -function StepHeading({ - step, - children, -}: { - step: number - children: React.ReactNode -}) { - return ( -

- - {step} - - {children} -

- ) -} - -function StepHeading2({ - step, - children, -}: { - step: number - children: React.ReactNode -}) { - return ( -

- - {step} - - {children} -

- ) -} +import { StartHeading } from "@site/src/components/welcomePage/StartHeading" +import { HowToUseSection } from "@site/src/components/welcomePage/HowToUseSection" +import { DeploymentAndFrameworkSection } from "@site/src/components/welcomePage/DeploymentAndFrameworkSection" +import { OtherGuides } from "@site/src/components/welcomePage/OtherGuides" export default function WelcomePage() { return ( - + - - - + + - ) } + diff --git a/src/static/img/background-pattern.png b/src/static/img/background-pattern.png new file mode 100644 index 0000000000..5897445c69 Binary files /dev/null and b/src/static/img/background-pattern.png differ diff --git a/src/static/img/icons/copy.svg b/src/static/img/icons/copy.svg new file mode 100644 index 0000000000..c08819c26d --- /dev/null +++ b/src/static/img/icons/copy.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/static/img/icons/go.svg b/src/static/img/icons/go.svg new file mode 100644 index 0000000000..63c9a6013e --- /dev/null +++ b/src/static/img/icons/go.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/static/img/icons/nextjs.svg b/src/static/img/icons/nextjs.svg new file mode 100644 index 0000000000..2183cd6eba --- /dev/null +++ b/src/static/img/icons/nextjs.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/static/img/icons/terminal.svg b/src/static/img/icons/terminal.svg new file mode 100644 index 0000000000..3e77aabd70 --- /dev/null +++ b/src/static/img/icons/terminal.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/static/img/icons/typescript.svg b/src/static/img/icons/typescript.svg new file mode 100644 index 0000000000..5d84bacc8f --- /dev/null +++ b/src/static/img/icons/typescript.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/static/img/icons/vue.svg b/src/static/img/icons/vue.svg new file mode 100644 index 0000000000..a995964517 --- /dev/null +++ b/src/static/img/icons/vue.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/static/img/logos/ory-logo.svg b/src/static/img/logos/ory-logo.svg new file mode 100644 index 0000000000..8c80577c2c --- /dev/null +++ b/src/static/img/logos/ory-logo.svg @@ -0,0 +1,7 @@ + + + + + + +