Primitives
Los siete primitives de brand — qué es cada uno, cuándo usarlo, y el ejemplo canónico.
Todos los primitives viven en apps/client/components/brand/ y se barrelean a través de @/components/brand. Importá el símbolo; nunca copies y pegues el markup.
import {
BrandMark,
VersionChip,
GridGlowBackground,
NoiseOverlay,
MonoLabel,
AuthCard,
BrandCard,
} from '@/components/brand';BrandMark
El wordmark UseDeploy. Renderiza como <Link href="/"> por default; pasá href={null} para un span inline no-link. Los children se renderizan al lado (uso típico: un <VersionChip>).
Source: apps/client/components/brand/BrandMark.tsx
| Prop | Tipo | Default | Notas |
|---|---|---|---|
size | 'sm' | 'md' | 'lg' | 'md' | Mapea a text-base / text-lg / text-2xl. |
href | string | null | '/' | null renderiza un <span> inline en lugar de un link. |
children | ReactNode | — | Renderizados después del wordmark dentro de la misma fila flex. |
className | string | — | Mergeado con el outer del link / span. |
aria-label | string | — | Nombre accesible. |
<BrandMark>
<VersionChip />
</BrandMark>Cuándo usarlo. Donde sea que tipearías la palabra "UseDeploy" en markup estilizado — nav de landing, header del dashboard, título de auth card.
VersionChip
Pequeño chip mono en mayúsculas mostrando la versión de la app. Default a process.env.NEXT_PUBLIC_APP_VERSION (cae a v0.1.0). Override pasando children.
Source: apps/client/components/brand/VersionChip.tsx
| Prop | Tipo | Default | Notas |
|---|---|---|---|
children | ReactNode | versión derivada de env | Override del string mostrado. |
className | string | — |
<BrandMark>
<VersionChip />
</BrandMark>
<BrandMark>
<VersionChip>BETA</VersionChip>
</BrandMark>Cuándo usarlo. Pegado al wordmark para surfaces de producto. Mantenelo chico — es una señal de metadata, no un badge.
GridGlowBackground
Dos capas apiladas — un radial glow violeta y un grid de líneas blancas de 64 px enmascarado por detrás — que le dan a cada surface UseDeploy su signature ambient depth sin apoyarse en una imagen hero. CSS puro, server-rendered, cero JS.
Source: apps/client/components/brand/GridGlowBackground.tsx
| Prop | Tipo | Default | Notas |
|---|---|---|---|
intensity | 'subtle' | 'default' | 'bold' | 'default' | Tunea opacidad de glow y de grid. |
className | string | — | Aplicada a la capa de glow. |
<div className="relative min-h-screen bg-background">
<GridGlowBackground intensity="subtle" />
{/* contenido de la página acá, position relative o z-10 */}
</div>El container necesita position: relative porque el primitive usa absolute inset-0. Envolvé tu contenido en otro elemento por encima (relative z-10) para que se apoye arriba.
Cuándo usarlo. Toda surface fullscreen — landing, auth, marketing pages. Salteá en pantallas de data densa (tablas del dashboard, settings) donde competiría con el contenido.
NoiseOverlay
Noise estático SVG turbulence, fixed across the viewport. Agrega textura de film-grain para que las surfaces oscuras no se vean planamente digitales. Data URI inline, cero network requests.
Source: apps/client/components/brand/NoiseOverlay.tsx
| Prop | Tipo | Default | Notas |
|---|---|---|---|
opacity | number | 0.03 | Tuneá con cuidado — 0.05 ya es demasiado. |
className | string | — |
<>
<GridGlowBackground />
<NoiseOverlay />
{/* contenido */}
</>Es position: fixed; z-index: 1; mix-blend-mode: overlay. Contenido con z-index más alto se apoya arriba; contenido en z: auto por default no.
Cuándo usarlo. Junto con <GridGlowBackground> en hero surfaces. No lo apiles dos veces a través de layouts anidados — una instancia por página.
MonoLabel
El patrón recurrente de metadata uppercase tracked-wide — texto pequeño mono usado como section eyebrows, KPI labels, list section headers. Envuelve la utility class .label-mono.
Source: apps/client/components/brand/MonoLabel.tsx
| Prop | Tipo | Default | Notas |
|---|---|---|---|
as | 'span' | 'div' | 'p' | 'span' | El elemento renderizado. |
className | string | — | Mergeado con label-mono. |
children | ReactNode | — | El texto del label. |
<MonoLabel as="div">Members</MonoLabel>
<div className="text-3xl font-semibold">42</div>Cuándo usarlo. Cualquier metadata uppercase — captions de KPI, "Step 01", "Section", section eyebrows. No re-rolles los estilos inline.
AuthCard
Glass card usada por toda página (auth). Centraliza el markup wrapper para que las páginas dejen de divergir en estilos de shell y sólo declaren el contenido de su form.
Source: apps/client/components/brand/AuthCard.tsx
| Prop | Tipo | Notas |
|---|---|---|
title | ReactNode | Renderizado en <h1 class="text-2xl font-semibold">. |
subtitle | ReactNode | Renderizado como body copy muted bajo el título. |
footer | ReactNode | Bajo el form, separado por una hairline — típico "¿Ya tenés cuenta? Sign in". |
children | ReactNode | El form. |
className | string | Mergeado en el div de card. |
<AuthCard
title="Sign in to UseDeploy"
subtitle="Welcome back."
footer={<Link href="/register">Create an account</Link>}
>
<SignInForm />
</AuthCard>Cuándo usarlo. Toda página de auth: sign-in, register, forgot password, reset password, magic-link. El (auth)/layout.tsx ya monta el <GridGlowBackground> y centra la card; las páginas son dueñas sólo del form.
BrandCard
La surface de card del dashboard / marketing. Border hairline, glass surface sutil, gradient-sweep hover opcional que espeja las feature cards de landing. Token-driven así trackea el tema oscuro automáticamente.
Source: apps/client/components/brand/BrandCard.tsx
| Prop | Tipo | Default | Notas |
|---|---|---|---|
label | ReactNode | — | Eyebrow mono uppercase sobre el título (ej. "01", "MEMBERS"). |
title | ReactNode | — | Bold, tracking apretado. Más grande cuando hay label o action. |
action | ReactNode | — | Slot top-right — típico: un ícono. |
interactive | boolean | false | Suma el sweep hairline card-glow + shift de bg en hover. Usar para cards clickeables. |
className | string | — | |
children | ReactNode | — | Contenido body bajo el título. |
<BrandCard label="MEMBERS" title="42">
<p className="text-muted-foreground">3 invited last week</p>
</BrandCard>
<BrandCard interactive label="01" title="Add a project" action={<ArrowUpRight />}>
Spin up a workspace and invite your team.
</BrandCard>Cuándo usarlo. KPIs del dashboard, list rows, feature cards de marketing. Usá interactive sólo cuando el user puede clickear toda la card — si no, el hint de hover engaña.
Qué no está acá (y por qué)
Vas a notar que no hay Button, Input, Dialog, etc. — esos son primitives derivados de shadcn en apps/client/components/ui/, ya token-aware. El namespace brand/ es sólo para las surfaces y motivos únicos de UseDeploy. Si algo es genérico (un botón, un checkbox), vive en ui/. Si es específico de la identidad del producto (un wordmark, una glass auth card, un grid-and-glow background), vive en brand/.