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
26 changes: 26 additions & 0 deletions apps/docs/app/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,32 @@
@theme {
--font-sans: var(--font-karla), ui-sans-serif, system-ui, sans-serif;
--font-display: var(--font-fraunces), ui-serif, Georgia, serif;
--font-heading: var(--font-sans);

--color-background: oklch(1 0 0);
--color-foreground: oklch(0.145 0 0);
--color-card: oklch(1 0 0);
--color-card-foreground: oklch(0.145 0 0);
--color-popover: oklch(1 0 0);
--color-popover-foreground: oklch(0.145 0 0);
--color-primary: oklch(0.205 0 0);
--color-primary-foreground: oklch(0.985 0 0);
--color-secondary: oklch(0.97 0 0);
--color-secondary-foreground: oklch(0.205 0 0);
--color-muted: oklch(0.97 0 0);
--color-muted-foreground: oklch(0.556 0 0);
--color-accent: oklch(0.97 0 0);
--color-accent-foreground: oklch(0.205 0 0);
--color-destructive: oklch(0.577 0.245 27.325);
--color-border: oklch(0.922 0 0);
--color-input: oklch(0.922 0 0);
--color-ring: oklch(0.708 0 0);
--color-chart-1: oklch(0.646 0.222 41.116);
--color-chart-2: oklch(0.6 0.118 184.704);
--color-chart-3: oklch(0.398 0.07 227.392);
--color-chart-4: oklch(0.828 0.189 84.429);
--color-chart-5: oklch(0.769 0.188 70.08);
--color-sidebar: oklch(0.985 0 0);
}

/* Campfire palette, sampled from the logo: ember flame, espresso logs,
Expand Down
16 changes: 2 additions & 14 deletions apps/docs/components/registry/slide-frame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,13 @@ import { type ReactNode, useEffect, useRef, useState } from "react";
const CANVAS_WIDTH = 1280;
const CANVAS_HEIGHT = 720;

// Default campfire theme, matching the init template. Previews keep the
// slide's own (light) theme and typography regardless of the docs color
// scheme and brand fonts.
const SLIDE_FONT = "ui-sans-serif, system-ui, sans-serif";

const SLIDE_THEME = {
"--color-background": "oklch(1 0 0)",
"--color-foreground": "oklch(0.15 0 0)",
"--color-primary": "oklch(0.55 0.2 260)",
"--color-muted": "oklch(0.55 0.02 260)",
"--font-sans": SLIDE_FONT,
"--font-display": SLIDE_FONT,
"--font-heading": SLIDE_FONT,
} as React.CSSProperties;

/**
* Renders registry items on the same fixed 1280x720 logical canvas the
* campfire shell uses, scaled down to fit the docs column. Items can rely
* on slide-scale typography (text-8xl etc.) and still preview correctly.
*/
export function SlideFrame({ children }: { children: ReactNode }) {
const containerRef = useRef<HTMLDivElement>(null);
const [scale, setScale] = useState(0);
Expand All @@ -45,7 +33,7 @@ export function SlideFrame({ children }: { children: ReactNode }) {

return (
<div
className="cf-slide-frame not-prose relative aspect-video w-full overflow-hidden rounded-xl border bg-(--color-background) text-(--color-foreground)"
className="cf-slide-frame not-prose relative aspect-video w-full overflow-hidden rounded-xl border bg-background text-foreground"
ref={containerRef}
style={SLIDE_THEME}
>
Expand Down
3 changes: 2 additions & 1 deletion apps/docs/content/docs/theme.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ slides/* content
```

The slide canvas uses `--color-background` / `--color-foreground` as its
base colors, so dark decks are one token away.
base colors and `--font-sans` as its base typeface, so dark decks and
custom fonts are one token away.

Multiple switchable themes are intentionally out of scope for v1.
4 changes: 2 additions & 2 deletions apps/docs/public/r/agenda.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
"files": [
{
"path": "items/agenda.tsx",
"content": "import type { ComponentProps } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport type AgendaLayoutProps = ComponentProps<\"main\"> & {\n /** From the slide's `title` frontmatter. */\n title?: string;\n};\n\n/** What the talk covers. Pair with the AgendaItem component:\n *\n * ```mdx\n * <AgendaItem number=\"01\" heading=\"The problem\" />\n * <AgendaItem number=\"02\" heading=\"What we built\" />\n * ```\n */\nexport default function AgendaLayout({\n title,\n className,\n children,\n ...props\n}: AgendaLayoutProps) {\n return (\n <main\n className={cn(\n \"flex h-full flex-col justify-center gap-14 p-24\",\n className\n )}\n data-slot=\"agenda-layout\"\n {...props}\n >\n {title ? (\n <h1 className=\"font-bold text-6xl tracking-tight\">{title}</h1>\n ) : null}\n <div\n className=\"flex max-w-4xl flex-col gap-8\"\n data-slot=\"agenda-layout-items\"\n >\n {children}\n </div>\n </main>\n );\n}\n",
"content": "import type { ComponentProps } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport type AgendaLayoutProps = ComponentProps<\"main\"> & {\n /** From the slide's `title` frontmatter. */\n title?: string;\n};\n\n/** What the talk covers. Pair with the AgendaItem component:\n *\n * ```mdx\n * <AgendaItem number=\"01\" heading=\"The problem\" />\n * <AgendaItem number=\"02\" heading=\"What we built\" />\n * ```\n */\nexport default function AgendaLayout({\n title,\n className,\n children,\n ...props\n}: AgendaLayoutProps) {\n return (\n <main\n className={cn(\n \"flex h-full flex-col justify-center gap-14 p-24\",\n className\n )}\n data-slot=\"agenda-layout\"\n {...props}\n >\n {title ? (\n <h1 className=\"font-bold font-heading text-6xl tracking-tight\">\n {title}\n </h1>\n ) : null}\n <div\n className=\"flex max-w-4xl flex-col gap-8\"\n data-slot=\"agenda-layout-items\"\n >\n {children}\n </div>\n </main>\n );\n}\n",
"type": "registry:file",
"target": "layouts/agenda.tsx"
},
{
"path": "items/agenda-item.tsx",
"content": "import type { ComponentProps } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport type AgendaItemProps = ComponentProps<\"div\"> & {\n /** The item marker, e.g. 1 or \"01\". */\n number: number | string;\n /** What this part of the talk covers. */\n heading: string;\n};\n\n/** A numbered row for agenda slides. Pairs with the agenda layout. */\nexport default function AgendaItem({\n number,\n heading,\n className,\n children,\n ...props\n}: AgendaItemProps) {\n return (\n <div\n className={cn(\"flex items-baseline gap-8\", className)}\n data-slot=\"agenda-item\"\n {...props}\n >\n <span\n className=\"font-mono font-semibold text-(--color-primary) text-2xl tabular-nums\"\n data-slot=\"agenda-item-number\"\n >\n {number}\n </span>\n <div className=\"flex flex-col gap-1\">\n <span\n className=\"font-semibold text-4xl tracking-tight\"\n data-slot=\"agenda-item-heading\"\n >\n {heading}\n </span>\n {children ? (\n <div\n className=\"text-xl leading-relaxed opacity-70\"\n data-slot=\"agenda-item-detail\"\n >\n {children}\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n",
"content": "import type { ComponentProps } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport type AgendaItemProps = ComponentProps<\"div\"> & {\n /** The item marker, e.g. 1 or \"01\". */\n number: number | string;\n /** What this part of the talk covers. */\n heading: string;\n};\n\n/** A numbered row for agenda slides. Pairs with the agenda layout. */\nexport default function AgendaItem({\n number,\n heading,\n className,\n children,\n ...props\n}: AgendaItemProps) {\n return (\n <div\n className={cn(\"flex items-baseline gap-8\", className)}\n data-slot=\"agenda-item\"\n {...props}\n >\n <span\n className=\"font-mono font-semibold text-2xl text-primary tabular-nums\"\n data-slot=\"agenda-item-number\"\n >\n {number}\n </span>\n <div className=\"flex flex-col gap-1\">\n <span\n className=\"font-heading font-semibold text-4xl tracking-tight\"\n data-slot=\"agenda-item-heading\"\n >\n {heading}\n </span>\n {children ? (\n <div\n className=\"text-xl leading-relaxed opacity-70\"\n data-slot=\"agenda-item-detail\"\n >\n {children}\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n",
"type": "registry:component",
"target": "components/agenda-item.tsx"
}
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/public/r/callout.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"files": [
{
"path": "items/callout.tsx",
"content": "import type { ComponentProps } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport type CalloutTone = \"default\" | \"primary\" | \"warning\";\n\nconst toneStyles: Record<CalloutTone, string> = {\n default: \"border-(--color-foreground)/15 bg-(--color-foreground)/[0.04]\",\n primary: \"border-(--color-primary)/40 bg-(--color-primary)/10\",\n warning: \"border-amber-500/40 bg-amber-500/10\",\n};\n\nexport type CalloutProps = ComponentProps<\"aside\"> & {\n /** Visual emphasis of the aside. */\n tone?: CalloutTone;\n};\n\n/** An emphasized aside with tone variants. */\nexport default function Callout({\n tone = \"default\",\n className,\n ...props\n}: CalloutProps) {\n return (\n <aside\n className={cn(\n \"rounded-xl border-2 px-8 py-6 text-2xl leading-relaxed\",\n toneStyles[tone],\n className\n )}\n data-slot=\"callout\"\n data-tone={tone}\n {...props}\n />\n );\n}\n",
"content": "import type { ComponentProps } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport type CalloutTone = \"default\" | \"primary\" | \"warning\";\n\nconst toneStyles: Record<CalloutTone, string> = {\n default: \"border-foreground/15 bg-foreground/[0.04]\",\n primary: \"border-primary/40 bg-primary/10\",\n warning: \"border-amber-500/40 bg-amber-500/10\",\n};\n\nexport type CalloutProps = ComponentProps<\"aside\"> & {\n /** Visual emphasis of the aside. */\n tone?: CalloutTone;\n};\n\n/** An emphasized aside with tone variants. */\nexport default function Callout({\n tone = \"default\",\n className,\n ...props\n}: CalloutProps) {\n return (\n <aside\n className={cn(\n \"rounded-xl border-2 px-8 py-6 text-2xl leading-relaxed\",\n toneStyles[tone],\n className\n )}\n data-slot=\"callout\"\n data-tone={tone}\n {...props}\n />\n );\n}\n",
"type": "registry:component",
"target": "components/callout.tsx"
}
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/public/r/closing.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"files": [
{
"path": "items/closing.tsx",
"content": "import type { ComponentProps } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport type ClosingLayoutProps = ComponentProps<\"main\"> & {\n /** From the slide's `title` frontmatter. */\n title?: string;\n};\n\n/** Centered thank-you slide. */\nexport default function ClosingLayout({\n title,\n className,\n children,\n ...props\n}: ClosingLayoutProps) {\n return (\n <main\n className={cn(\n \"flex h-full flex-col items-center justify-center gap-8 p-28 text-center\",\n className\n )}\n data-slot=\"closing-layout\"\n {...props}\n >\n {title ? (\n <h1 className=\"font-bold text-8xl tracking-tight\">{title}</h1>\n ) : null}\n <div\n className=\"max-w-3xl text-2xl leading-relaxed opacity-70\"\n data-slot=\"closing-layout-body\"\n >\n {children}\n </div>\n </main>\n );\n}\n",
"content": "import type { ComponentProps } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport type ClosingLayoutProps = ComponentProps<\"main\"> & {\n /** From the slide's `title` frontmatter. */\n title?: string;\n};\n\n/** Centered thank-you slide. */\nexport default function ClosingLayout({\n title,\n className,\n children,\n ...props\n}: ClosingLayoutProps) {\n return (\n <main\n className={cn(\n \"flex h-full flex-col items-center justify-center gap-8 p-28 text-center\",\n className\n )}\n data-slot=\"closing-layout\"\n {...props}\n >\n {title ? (\n <h1 className=\"font-bold font-heading text-8xl tracking-tight\">\n {title}\n </h1>\n ) : null}\n <div\n className=\"max-w-3xl text-2xl leading-relaxed opacity-70\"\n data-slot=\"closing-layout-body\"\n >\n {children}\n </div>\n </main>\n );\n}\n",
"type": "registry:file",
"target": "layouts/closing.tsx"
}
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/public/r/metric-card.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"files": [
{
"path": "items/metric-card.tsx",
"content": "import type { ComponentProps } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport type MetricCardProps = ComponentProps<\"div\"> & {\n /** The headline number, e.g. \"42%\". */\n value: string;\n /** What the number measures. */\n label: string;\n /** Optional change indicator rendered beside the value, e.g. \"+18%\". */\n delta?: string;\n};\n\n/** A headline number with label and optional delta. */\nexport default function MetricCard({\n value,\n label,\n delta,\n className,\n ...props\n}: MetricCardProps) {\n return (\n <div\n className={cn(\n \"inline-flex flex-col gap-1 rounded-2xl border border-(--color-foreground)/10 bg-(--color-foreground)/[0.03] px-8 py-6\",\n className\n )}\n data-slot=\"metric-card\"\n {...props}\n >\n <span className=\"flex items-baseline gap-3\" data-slot=\"metric-card-value\">\n <span className=\"font-bold text-6xl tracking-tight\">{value}</span>\n {delta ? (\n <span\n className=\"font-medium text-(--color-primary) text-xl\"\n data-slot=\"metric-card-delta\"\n >\n {delta}\n </span>\n ) : null}\n </span>\n <span className=\"text-lg opacity-60\" data-slot=\"metric-card-label\">\n {label}\n </span>\n </div>\n );\n}\n",
"content": "import type { ComponentProps } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport type MetricCardProps = ComponentProps<\"div\"> & {\n /** The headline number, e.g. \"42%\". */\n value: string;\n /** What the number measures. */\n label: string;\n /** Optional change indicator rendered beside the value, e.g. \"+18%\". */\n delta?: string;\n};\n\n/** A headline number with label and optional delta. */\nexport default function MetricCard({\n value,\n label,\n delta,\n className,\n ...props\n}: MetricCardProps) {\n return (\n <div\n className={cn(\n \"inline-flex flex-col gap-1 rounded-2xl border border-foreground/10 bg-foreground/[0.03] px-8 py-6\",\n className\n )}\n data-slot=\"metric-card\"\n {...props}\n >\n <span className=\"flex items-baseline gap-3\" data-slot=\"metric-card-value\">\n <span className=\"font-bold font-heading text-6xl tracking-tight\">\n {value}\n </span>\n {delta ? (\n <span\n className=\"font-medium text-primary text-xl\"\n data-slot=\"metric-card-delta\"\n >\n {delta}\n </span>\n ) : null}\n </span>\n <span className=\"text-lg opacity-60\" data-slot=\"metric-card-label\">\n {label}\n </span>\n </div>\n );\n}\n",
"type": "registry:component",
"target": "components/metric-card.tsx"
}
Expand Down
Loading
Loading