From c0fc31cbc350da4bd4184428b76473a46f15dba5 Mon Sep 17 00:00:00 2001 From: Parikshit Deshmukh Date: Fri, 29 May 2026 16:14:16 +0530 Subject: [PATCH] docs: redesign /projects page Centers the hero around the OpenClaw OS type scale, drops the side stats panel in favor of a single-column layout, and adds a Discord secondary CTA next to "Submit a project". The directory now sits in the shared gray contentSection between two GradientDividers (new `compact` prop to skip the two tallest bars without affecting other pages). Project cards: type-driven accent colors via a TYPE_ACCENT map, filled squircle type chips, "by Official/Community" as muted meta text, hover-only arrow on link buttons, subtle shadow tokens (--openui-shadow-s / -m) matched to the home page card style. Submit section: drop the "CONTRIBUTE" eyebrow, replace the verbose paragraph with a tighter intro and a numbered checklist of what to include, and add the Share-on-Discord CTA. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/app/(home)/projects/page.module.css | 236 ++++++++++++------ docs/app/(home)/projects/page.tsx | 199 ++++++--------- .../GradientDivider/GradientDivider.tsx | 11 +- 3 files changed, 248 insertions(+), 198 deletions(-) diff --git a/docs/app/(home)/projects/page.module.css b/docs/app/(home)/projects/page.module.css index d4543901a..5253edc9f 100644 --- a/docs/app/(home)/projects/page.module.css +++ b/docs/app/(home)/projects/page.module.css @@ -5,7 +5,7 @@ } .heroSection { - padding: 8rem var(--home-section-padding-inline, 1.25rem) 4rem; + padding: 6rem var(--home-section-padding-inline, 1.25rem) 4rem; } .heroInner, @@ -24,10 +24,11 @@ display: flex; max-width: 46rem; flex-direction: column; - align-items: flex-start; + align-items: center; + margin-inline: auto; + text-align: center; } -.eyebrow, .sectionKicker { margin: 0; color: var(--openui-text-neutral-secondary); @@ -38,17 +39,18 @@ } .title { - max-width: 40rem; - margin: 1rem 0 0; + margin: 0; font-family: "Inter Display", sans-serif; - font-size: clamp(2.75rem, 6vw, 5rem); + font-size: clamp(40px, 10vw, 52px); font-weight: 600; line-height: 1; + letter-spacing: -1px; + color: var(--openui-text-neutral-primary); } .subtitle { max-width: 40rem; - margin: 1.5rem 0 0; + margin: 1.5rem auto 0; color: var(--openui-text-neutral-secondary); font-size: 1.125rem; line-height: 1.65; @@ -57,6 +59,7 @@ .heroActions { display: flex; flex-wrap: wrap; + justify-content: center; gap: 0.75rem; margin-top: 2rem; } @@ -69,37 +72,45 @@ justify-content: center; gap: 0.5rem; min-height: 2.5rem; - border-radius: 999px; + border-radius: var(--openui-radius-full, 999px); text-decoration: none; transition: - transform 0.18s ease, - background-color 0.18s ease, - border-color 0.18s ease; + transform 0.2s ease, + background-color 0.2s ease, + border-color 0.2s ease, + box-shadow 0.2s ease; } -.primaryAction { +.primaryAction, +.secondaryAction { + height: 3rem; + min-height: 3rem; padding-inline: 1.25rem; + font-weight: 600; + border: 1px solid transparent; + box-shadow: var(--openui-shadow-l); +} + +.primaryAction { background: var(--openui-text-neutral-primary); color: var(--openui-foreground); - font-weight: 600; } .secondaryAction { - padding-inline: 1.25rem; - border: 1px solid var(--openui-border-default); + border-color: var(--openui-border-default); + background: var(--openui-foreground); color: var(--openui-text-neutral-primary); - font-weight: 600; } .primaryAction:hover, -.secondaryAction:hover, -.cardLink:hover { - transform: translateY(-1px); +.secondaryAction:hover { + transform: scale(0.99); + box-shadow: none; } -.secondaryAction:hover, .cardLink:hover { - background: var(--openui-highlight); + border-color: var(--openui-border-interactive, var(--openui-text-neutral-primary)); + box-shadow: var(--openui-shadow-m); } .actionIcon, @@ -113,6 +124,7 @@ display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); width: min(100%, 31rem); + margin: 1rem auto 0; gap: 0.75rem; } @@ -213,8 +225,13 @@ font-size: 0.8125rem; } +.contentSection { + position: relative; + background: var(--openui-background); +} + .directorySection { - padding: 4rem var(--home-section-padding-inline, 1.25rem) 2rem; + padding: 2rem var(--home-section-padding-inline, 1.25rem) 2rem; } .sectionHeader { @@ -232,11 +249,13 @@ } .sectionDescription { - max-width: 34rem; margin: 0; color: var(--openui-text-neutral-secondary); - font-size: 1rem; - line-height: 1.65; + font-size: 0.875rem; + font-weight: 500; + line-height: 1; + text-align: right; + justify-self: end; } .grid { @@ -247,13 +266,13 @@ .card { --card-accent: var(--openui-text-neutral-primary); display: flex; - min-height: 17rem; + min-height: 18rem; flex-direction: column; border: 1px solid var(--openui-border-default); - border-radius: 8px; - padding: 1.125rem; + border-radius: var(--openui-radius-4xl); + padding: 1.25rem; background: var(--openui-foreground); - box-shadow: 0 1px 0 rgb(0 0 0 / 3%); + box-shadow: var(--openui-shadow-m); } .card[data-accent="blue"], @@ -281,68 +300,59 @@ --card-accent: #475569; } -.cardTop { +.cardHeader { display: flex; - align-items: center; - justify-content: space-between; + align-items: flex-start; gap: 1rem; } -.iconFrame { +.cardHeaderContent { display: flex; - width: 2.25rem; - height: 2.25rem; - flex-shrink: 0; - align-items: center; - justify-content: center; - border-radius: 8px; - background: color-mix(in srgb, var(--card-accent) 12%, transparent); - color: var(--card-accent); -} - -.cardIcon { - width: 1.125rem; - height: 1.125rem; + flex-direction: column; + gap: 0.75rem; + min-width: 0; } .tags { display: flex; flex-wrap: wrap; - justify-content: flex-end; - gap: 0.375rem; + align-items: center; + justify-content: flex-start; + gap: 0.5rem; } -.typeTag, -.statusTag { +.typeTag { display: inline-flex; - height: 1.5rem; + height: 1.625rem; align-items: center; - border-radius: 999px; - padding-inline: 0.625rem; + gap: 0.3rem; + border-radius: 8px; + padding-inline: 0.5rem; + background: color-mix(in srgb, var(--card-accent) 14%, transparent); + color: var(--card-accent); font-size: 0.75rem; font-weight: 600; line-height: 1; } -.typeTag { - border: 1px solid var(--openui-border-default); +.statusMeta { + display: inline-flex; + align-items: center; color: var(--openui-text-neutral-secondary); -} - -.statusTag { - background: var(--openui-highlight); - color: var(--openui-text-neutral-primary); + font-size: 0.75rem; + font-weight: 500; + line-height: 1; } .cardTitle { - margin: 1.125rem 0 0; + margin: 0; font-size: 1.0625rem; font-weight: 650; line-height: 1.3; } .cardDescription { - margin: 0.875rem 0 0; + margin: 1.75rem 0 0; color: var(--openui-text-neutral-secondary); font-size: 0.9375rem; line-height: 1.65; @@ -353,16 +363,37 @@ flex-wrap: wrap; gap: 0.5rem; margin-top: auto; - padding-top: 1.25rem; + padding-top: 1.5rem; } .cardLink { min-height: 2rem; - padding-inline: 0.75rem; + padding-inline: 0.875rem; border: 1px solid var(--openui-border-default); + background: var(--openui-foreground); + box-shadow: var(--openui-shadow-s); color: var(--openui-text-neutral-primary); font-size: 0.875rem; - font-weight: 600; + font-weight: 500; +} + +.cardLinkArrow { + width: 0.875rem; + height: 0.875rem; + margin-inline-start: -0.125rem; + max-width: 0; + opacity: 0; + transform: translateX(-4px); + transition: + opacity 0.18s ease, + transform 0.18s ease, + max-width 0.18s ease; +} + +.cardLink:hover .cardLinkArrow { + max-width: 1rem; + opacity: 1; + transform: translateX(0); } .submitSection { @@ -378,6 +409,63 @@ max-width: 42rem; } +.submitDescription { + margin: 0.75rem 0 0; + color: var(--openui-text-neutral-secondary); + font-size: 1rem; + line-height: 1.6; +} + +.submitSteps { + margin: 1.25rem 0 0; + padding: 0; + list-style: none; + counter-reset: submit-step; +} + +.submitSteps li { + position: relative; + margin-top: 0.625rem; + padding-inline-start: 2rem; + color: var(--openui-text-neutral-primary); + font-size: 0.9375rem; + line-height: 1.5; + counter-increment: submit-step; +} + +.submitSteps li:first-child { + margin-top: 0; +} + +.submitSteps li::before { + content: counter(submit-step); + position: absolute; + left: 0; + top: 0; + display: inline-flex; + width: 1.375rem; + height: 1.375rem; + align-items: center; + justify-content: center; + border: 1px solid var(--openui-border-default); + border-radius: 999px; + background: var(--openui-highlight); + color: var(--openui-text-neutral-primary); + font-size: 0.75rem; + font-weight: 600; + line-height: 1; +} + +.stepDetail { + color: var(--openui-text-neutral-secondary); +} + +.submitActions { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; +} + @media (min-width: 720px) { .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); @@ -391,16 +479,12 @@ @media (min-width: 1024px) { .heroSection { - padding-top: 9rem; + padding-top: 7rem; } - .heroInner { - grid-template-columns: minmax(0, 1.05fr) minmax(23rem, 0.75fr); - align-items: end; - } - - .heroPanel { - padding-top: 0; + .title { + font-size: 6rem; + letter-spacing: -2px; } .grid { @@ -416,11 +500,7 @@ @media (max-width: 640px) { .heroSection { - padding-top: 6rem; - } - - .title { - font-size: 2.875rem; + padding-top: 4rem; } .heroPanel { diff --git a/docs/app/(home)/projects/page.tsx b/docs/app/(home)/projects/page.tsx index 9b695a281..af61c7cd4 100644 --- a/docs/app/(home)/projects/page.tsx +++ b/docs/app/(home)/projects/page.tsx @@ -1,26 +1,37 @@ import { + ArrowUpRight, BookOpen, Bot, - Boxes, Code2, - ExternalLink, Github, MonitorSmartphone, Package, PlugZap, + Plus, Server, Sparkles, - Users, Wrench, } from "lucide-react"; import type { Metadata } from "next"; import type { ComponentType } from "react"; import { PillLink } from "../components/Button/Button"; import { Footer } from "../sections/Footer/Footer"; +import { GradientDivider } from "../sections/GradientDivider/GradientDivider"; import styles from "./page.module.css"; type ProjectStatus = "Official" | "Community"; +const TYPE_ACCENT: Record = { + Tool: "purple", + Plugin: "blue", + Provider: "green", + Extension: "blue", + Package: "purple", + Framework: "orange", + Example: "slate", + Article: "purple", +}; + interface ProjectLink { label: string; href: string; @@ -224,23 +235,7 @@ const projects: ProjectItem[] = [ }, ]; -const highlights = [ - { - label: "Community projects", - value: projects.filter((item) => item.status === "Community").length.toString(), - accent: "purple", - icon: Users, - }, - { label: "Featured projects", value: projects.length.toString(), accent: "slate", icon: Boxes }, - { - label: "Discord", - value: "Share your projects with the community", - accent: "blue", - icon: DiscordIcon, - kind: "cta", - href: "https://discord.gg/suzHfJnpw", - }, -]; +const DISCORD_URL = "https://discord.gg/suzHfJnpw"; export const metadata: Metadata = { title: "OpenUI Projects", @@ -259,20 +254,7 @@ export const metadata: Metadata = { }, }; -function ExternalIndicator({ external }: { external?: boolean }) { - if (!external) return null; - return