Skip to content
Merged
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
8 changes: 4 additions & 4 deletions web/components/Hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export default function Hero() {

return (
<section
className="relative min-h-[88vh] flex flex-col items-center justify-center text-center px-6 pt-28 pb-16 overflow-hidden"
className="relative min-h-[88vh] flex flex-col items-center justify-center text-center px-6 pt-28 pb-32 sm:pb-36 overflow-hidden"
id="hero"
>
<div className="absolute w-[700px] h-[700px] top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-[radial-gradient(circle,var(--color-accent-dim)_0%,transparent_70%)] blur-[80px] pointer-events-none z-0 animate-pulse-glow" />
Expand All @@ -55,7 +55,7 @@ export default function Hero() {
>
<Sparkles className="size-3.5 text-accent-bright" aria-hidden />
<span className="ml-1.5 font-[family-name:var(--font-mono)] text-[0.7rem] uppercase tracking-widest">
v0.10 · MCP-native · AGPL-3.0
v0.11 · MCP-native · AGPL-3.0
</span>
</Chip>

Expand Down Expand Up @@ -163,9 +163,9 @@ export default function Hero() {

</div>

<div className="absolute bottom-6 flex flex-col items-center gap-2 text-text-dim text-xs uppercase tracking-widest animate-bob-down">
<div className="pointer-events-none absolute bottom-4 left-1/2 z-2 flex -translate-x-1/2 flex-col items-center gap-1.5 text-text-dim text-[0.65rem] uppercase tracking-widest animate-bob-down">
<span>scroll</span>
<Mouse className="w-4 h-6" aria-hidden />
<Mouse className="w-4 h-5" aria-hidden />
</div>
</section>
);
Expand Down
34 changes: 26 additions & 8 deletions web/components/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export default function Nav() {
className="bg-bg-deep/85 backdrop-blur-xl backdrop-saturate-[1.2] border-b border-border"
>
<Navbar.Header>
<Navbar.MenuToggle className="md:hidden" />
<Navbar.MenuToggle className="!text-text-primary hover:!text-accent-bright md:hidden" />

<Navbar.Brand>
<NextLink
Expand Down Expand Up @@ -143,13 +143,31 @@ export default function Nav() {
</Navbar.Content>
</Navbar.Header>

<Navbar.Menu>
{NAV_ITEMS.map((item) => (
<Navbar.MenuItem key={item.href} href={item.href}>
{item.label}
</Navbar.MenuItem>
))}
<Navbar.MenuItem href="https://github.com/I4cTime/quantum_ring">
<Navbar.Menu className="!bg-bg-deep/95 backdrop-blur-xl">
{NAV_ITEMS.map((item) => {
const isCurrent = item.href.startsWith("/")
? pathname === item.href || pathname?.startsWith(`${item.href}/`)
: false;
return (
<Navbar.MenuItem
key={item.href}
href={item.href}
isCurrent={isCurrent}
className={
"text-lg hover:!bg-accent-dim hover:!text-text-primary data-[hovered=true]:!bg-accent-dim data-[hovered=true]:!text-text-primary data-[pressed=true]:!bg-accent-dim " +
(isCurrent
? "!text-text-primary !bg-accent-dim font-semibold"
: "!text-text-secondary font-medium")
}
>
{item.label}
</Navbar.MenuItem>
);
})}
<Navbar.MenuItem
href="https://github.com/I4cTime/quantum_ring"
className="!text-text-secondary text-lg font-medium hover:!bg-accent-dim hover:!text-text-primary data-[hovered=true]:!bg-accent-dim data-[hovered=true]:!text-text-primary data-[pressed=true]:!bg-accent-dim"
>
GitHub
</Navbar.MenuItem>
</Navbar.Menu>
Expand Down
68 changes: 33 additions & 35 deletions web/components/TrustStrip.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { KPI, KPIGroup } from "@heroui-pro/react";
import { KPI } from "@heroui-pro/react";
import { Code2, Layers, Plug, Sparkles } from "lucide-react";

const STATS = [
Expand Down Expand Up @@ -51,48 +51,46 @@ export default function TrustStrip() {
</h2>
</div>

<div className="rounded-2xl border border-border/60 bg-bg-card/40 backdrop-blur p-1">
<KPIGroup className="bg-transparent">
{STATS.map((stat, idx) => (
<Stat key={stat.title} stat={stat} isLast={idx === STATS.length - 1} />
{/*
KPIGroup forces flex-1 equal columns which clips long labels at narrow
widths. Use a custom grid that stacks 2x2 on small screens and flips
to 1x4 on lg+ instead, with manual divider borders.
*/}
<div className="rounded-2xl border border-border/60 bg-bg-card/40 backdrop-blur overflow-hidden">
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 divide-y sm:divide-y-0 lg:divide-y-0 divide-border/60 sm:[&>:nth-child(odd)]:border-r sm:[&>:nth-child(odd)]:border-border/60 sm:[&>:nth-child(-n+2)]:border-b sm:[&>:nth-child(-n+2)]:border-border/60 lg:[&>:not(:last-child)]:border-r lg:[&>*]:border-b-0">
{STATS.map((stat) => (
<Stat key={stat.title} stat={stat} />
))}
</KPIGroup>
</div>
</div>
</div>
</section>
);
}

function Stat({
stat,
isLast,
}: {
stat: (typeof STATS)[number];
isLast: boolean;
}) {
function Stat({ stat }: { stat: (typeof STATS)[number] }) {
const { title, value, Icon, status, trend, trendLabel } = stat;
return (
<>
<KPI className="bg-transparent shadow-none">
<KPI.Header>
<KPI.Icon status={status}>
<Icon className="size-4" strokeWidth={2} aria-hidden />
</KPI.Icon>
<KPI.Title className="text-text-secondary text-xs uppercase tracking-widest">
{title}
</KPI.Title>
</KPI.Header>
<KPI.Content>
<KPI.Value
className="text-text-primary text-3xl md:text-4xl font-extrabold"
locale="en-US"
maximumFractionDigits={0}
value={value}
/>
<KPI.Trend trend={trend}>{trendLabel}</KPI.Trend>
</KPI.Content>
</KPI>
{!isLast ? <KPIGroup.Separator /> : null}
</>
<KPI className="bg-transparent shadow-none rounded-none">
<KPI.Header>
<KPI.Icon status={status}>
<Icon className="size-4" strokeWidth={2} aria-hidden />
</KPI.Icon>
<KPI.Title className="text-text-secondary text-[0.7rem] uppercase tracking-widest leading-tight">
{title}
</KPI.Title>
</KPI.Header>
<KPI.Content>
<KPI.Value
className="text-text-primary text-3xl md:text-4xl font-extrabold"
locale="en-US"
maximumFractionDigits={0}
value={value}
/>
<KPI.Trend trend={trend} className="text-[0.7rem] text-right">
{trendLabel}
</KPI.Trend>
</KPI.Content>
</KPI>
);
}
6 changes: 4 additions & 2 deletions web/lib/data/changelog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ export type ChangelogEntry = {

export const CHANGELOG: ChangelogEntry[] = [
{
version: "Unreleased",
date: "",
version: "0.11.0",
date: "2026-04-25",
highlights: [
{ type: "changed", text: "Marketing site overhauled — the `web/` landing, docs, and changelog were rebuilt on HeroUI v3 + HeroUI Pro with Tailwind v4 and `lucide-react`. New surfaces include a hero with the social-card art and install picker, locale-stable TrustStrip KPIs, the WhyQRing comparison, IntegrationsCarousel, LiveDemo terminal, a global ⌘K command palette, AgentMode, the CursorPlugin showcase, FAQ, FreeCallout, and FinalCta" },
{ type: "changed", text: "Docs page gains a pinned floating table of contents with manual scroll-spy and a copy-to-clipboard MCP prompt cookbook; navbar contrast was lifted and same-page hash navigation + home-link scroll-to-top now work correctly under the App Router" },
{ type: "changed", text: "Status dashboard rebuilt — `qring status` now serves a denser page with a KPI strip (secrets, env, protected, approvals, hooks, 24h reads/writes, denied actions, anomalies), a sortable + searchable secrets table, and dedicated panels for manifest gaps, governance policy, active approvals (with tamper / expiry state), registered hooks, and agent memory" },
{ type: "changed", text: "Audit feed gained action chips (read/write/delete/export), source chips (cli/mcp/hook/agent), and a free-text filter; top bar adds pause / refresh / JSON controls plus a relative `updated Ns ago` timestamp that keeps ticking while paused" },
{ type: "changed", text: "Snapshot payload (`/api/status` + SSE) now also includes version, projectPath, scopes, protectedCount, manifest, policy, approvals, hooks, memoryKeys, and auditMetrics (action / source counts, top read keys, total events in the last 24h)" },
Expand Down
Loading