‹ volver al sitio
lab de temas

componentes

Biblioteca de componentes

Todo en este sitio está hecho con estas piezas. Los átomos se combinan en moléculas, las moléculas en organismos, y los organismos llenan las plantillas de página. Cambia de tema arriba y mira cómo cambia todo.

Fundamentos

tokens.*.css

Design tokens

Los componentes nunca tocan un color directo. Un tema define los tokens base, los tokens semánticos les dan un rol y los tokens de componente ajustan cada pieza. Cambia un valor abajo y fluye hasta arriba.

  1. base --color-primary lo define el tema
  2. semántico --primary qué significa
  3. componente --btn-primary-bg dónde va
  1. base --color-base-000 lo define el tema
  2. semántico --surface-sunken qué significa
  3. componente --tag-bg dónde va
  4. Tag
global.css

Capas de cascada

Los estilos se apilan en tres capas, así un componente siempre puede reestilizar los átomos que contiene con una clase simple.

  1. @layer basereset + utilidades
  2. @layer uiátomos + moléculas
  3. (unlayered)componentes + páginas, sin capa, así que siempre ganan

Átomos

Las piezas más pequeñas. Cada una hace una sola cosa y solo lee tokens.

ui/Button.astro

Button

Enlaces y acciones. Su superficie viene de los tokens de controles, así que un solo ajuste del tema vuelve todos los botones planos, biselados o redondos.

Props

PropTipoPor defecto
variant?default (outlined), primary (filled), portal (glowing accent, for the loft), danger (destructive) 'default' | 'primary' | 'portal' | 'danger' 'default'
size?md for page CTAs, sm for dense tool UIs, icon for a single glyph 'md' | 'sm' | 'icon' 'md'
block?fill the container's width boolean –
icon?a pixelarticons name, drawn before the label string –

Además, todos los atributos nativos de <button> / <a>.

Tokens que lee

componente
--fs-* --sp-* --ctl-border --ctl-radius --btn-bg --btn-fg --ctl-shadow --ctl-lift-hover --ctl-shadow-hover --btn-hover-border --btn-hover-fg --ctl-press --ctl-shadow-active --btn-primary-bg --btn-primary-fg --btn-primary-hover-bg
semántico
--font-pixel --error --accent --foreground --secondary

Uso

<Button variant="primary" icon="mail" href="#contact">email me</Button>
<Button size="sm" block data-save>save</Button>
ui/Tag.astro

Tag

Etiquetas pequeñas en un hueco hundido: la tecnología de una tarjeta, o un conteo.

React 19 WebRTC Rust 25 8

Props

PropTipoPor defecto
variant? 'label' | 'count' 'label'
hot? boolean –

Además, todos los atributos nativos de <span>.

Tokens que lee

componente
--sink-border --sink-radius --tag-fg --tag-bg --sink-shadow --fs-* --sp-*
semántico
--font-pixel --warning --on-warning

Uso

<Tag>WebRTC</Tag>
<Tag variant="count" hot>8</Tag>
ui/Badge.astro

Badge

Un estado en un color sólido, con el texto legible propio de ese color encima.

Publicado Fallido En revisión En vivo

Props

PropTipoPor defecto
tone 'success' | 'error' | 'warning' | 'info' –

Además, todos los atributos nativos de <span>.

Tokens que lee

componente
--fs-* --sp-* --sink-radius
semántico
--font-pixel --success --on-success --error --on-error --warning --on-warning --info --on-info

Uso

<Badge tone="success">shipped</Badge>
ui/Chip.astro

Chip

Una palabra en un hueco hundido, más grande y sencilla que una etiqueta. Las que se pueden quitar llevan una ×.

TypeScript WebRTC AT Protocol atproto webrtc

Props

PropTipoPor defecto
removable? boolean –

Además, todos los atributos nativos de <span>.

Tokens que lee

componente
--fs-* --sp-* --sink-border --sink-radius --sink-shadow --tag-bg
semántico
--foreground-dim --surface-sunken --font-pixel --foreground --foreground-faint

Uso

<Chip>TypeScript</Chip>
<Chip removable>atproto</Chip>
ui/Field.astro

Field

Un campo de texto con un glifo dentro del borde. Un error pone el borde en rojo.

Props

PropTipoPor defecto
icon string –
type? 'text' | 'search' | 'password' | 'email' | 'url' 'text'
placeholder? string –
name? string –
inputDir? 'ltr' | 'rtl' | 'auto' –
error? boolean –

Además, todos los atributos nativos de <label>.

Tokens que lee

componente
--sp-* --fs-* --sink-border --sink-shadow --sink-radius
semántico
--foreground-faint --foreground --surface-sunken --primary --error

Uso

<Field icon="@" placeholder="handle.bsky.social" />
<Field icon="⚿" type="password" error />
ui/Switch.astro

Switch

Un interruptor hecho sobre una casilla real, así que el teclado y los formularios funcionan sin más.

Props

PropTipoPor defecto
label? string –

Además, todos los atributos nativos de <input>.

Tokens que lee

componente
--sp-* --fs-* --ctl-radius
semántico
--foreground-dim --surface-sunken --border-strong --foreground-faint --primary --on-accent --foreground

Uso

<Switch label="Scanlines" data-fx="--fx-scanline" />
ui/Segmented.astro

Segmented

Unas pocas opciones donde solo una puede estar activa. La elegida sobresale del hueco.

Props

PropTipoPor defecto
options Option[] –
label string –

Además, todos los atributos nativos de <div>.

Hecho con

Tokens que lee

componente
--sink-border --ctl-radius --fs-* --sp-*
semántico
--surface-sunken --foreground-faint --surface --foreground --shadow-color

Uso

<Segmented label="Billing" options={[
  { label: 'Monthly' },
  { label: 'Yearly', pressed: true, badge: { text: '-20%', tone: 'warning' } },
]} />
ui/Eyebrow.astro

Eyebrow

La pequeña etiqueta // encima del título de una sección.

trabajo destacado

Props

No tiene props propias.

Tokens que lee

componente
--fs-* --sp-*
semántico
--font-pixel --primary --foreground-faint

Uso

<Eyebrow>selected work</Eyebrow>

Moléculas

Átomos combinados en una forma: una barra de ventana, una superficie elevada.

ui/TitleBar.astro

TitleBar

La franja en la parte superior de una ventana: puntos, un título y un espacio al final. AIM la convierte en el clásico degradado azul.

protoimsg.app 2025
now_playing.mod
// atproto · en vivo ● en línea

Props

PropTipoPor defecto
size?md on cards, sm on dense tool windows and dialogs 'md' | 'sm' 'md'
dots? boolean –

Además, todos los atributos nativos de <div>.

Tokens que lee

componente
--sp-* --titlebar-bg --fs-* --titlebar-fg --ctl-radius --titlebar-accent
semántico
--border --font-pixel --foreground-faint
del padre
--ac

Uso

<TitleBar dots>
  protoimsg.app
  <span slot="end">2025</span>
</TitleBar>
ui/Panel.astro

Panel

La superficie elevada sobre la que se apoyan todas las tarjetas y ventanas. Raised para lo que se usa, flat para el contenido de apoyo, lift para los enlaces.

raised
flat
lift · pasa el cursor
window.txt

Panel + TitleBar

Props

PropTipoPor defecto
as? 'div' | 'article' | 'section' | 'aside' 'div'
elevation? 'raised' | 'flat' 'raised'
lift? boolean –

Además, todos los atributos nativos de <div>.

Tokens que lee

componente
--card-bg --raise-border --raise-radius --raise-pad --raise-shadow --raise-shadow-static --lift-hover --raise-shadow-hover --card-border-hover

Uso

<Panel as="article" lift>
  <TitleBar dots>window.txt</TitleBar>
  …
</Panel>

Organismos

Partes enteras y reconocibles del sitio, hechas de moléculas y átomos.

ProjectCard.astro

ProjectCard

Un Panel con una TitleBar, una descripción, Tags y enlaces. Toda la tarjeta lleva a su primer enlace.

protoimsg.app 2025

protoIM

Fundador e Ingeniero Principal · 2025–actualidad

proto Instant Messenger — videollamadas open source y multiplataforma sobre el AT Protocol: llamadas gratis y sin obligación de crear cuenta, como alternativa al encierro de FaceTime. Un monorepo TypeScript de 8 paquetes (~65K LOC) que lleva una sola plataforma en tiempo real a web (React 19), escritorio (Tauri v2 / Rust) y móvil (Expo). Señalización WebRTC hecha a mano con credenciales TURN temporales en coturn autoalojado, LiveKit SFU para llamadas grupales, Lexicons propios app.protoimsg.chat.*, un indexador de Jetstream y 5 servicios en Fly.io — incluido un PDS autoalojado y traducción en vivo con NLLB-200 en ~17 idiomas.

React 19 WebRTC Tauri v2 Rust Expo LiveKit PDS Fly.io

Props

PropTipoPor defecto
project Project –

Hecho con

Tokens que lee

componente
--sp-* --fs-*
semántico
--primary --font-body --font-display --font-pixel --foreground-faint --foreground-dim --foreground

Uso

{featured(m).map((project) => <ProjectCard project={project} />)}
MiniCard.astro

MiniCard

Un Panel plano para los proyectos más pequeños.

nosky

Creador e Ingeniero Principal · 2026

Cliente social de ATProto (Expo/RN) que evita el AppView centralizado — consulta directamente los servidores PDS seguidos y fusiona/ordena en el cliente, sobre el stack de Microcosm (Slingshot, Constellation, Spacedust).

Props

PropTipoPor defecto
project MiniProject –

Hecho con

Tokens que lee

componente
--sp-* --fs-*
semántico
--font-display --info --font-pixel --foreground-faint --foreground-dim --warning

Uso

<MiniCard project={project} />
ArcadeCabinet.astro

ArcadeCabinet

Un Panel disfrazado de máquina arcade, con una pantalla jugable o bloqueada.

FAST HOPPER
0
RÉCORD 0

HOPPER

Diseñador e Ingeniero · ya disponible

Un juego de plataformas vertical — salta por una escalera infinita de plataformas y persigue el récord. Funciona con una simulación determinista, así que cada partida es verificable. Tablas de clasificación globales por dificultad (fast / faster), y tus mejores marcas se guardan directamente en tu repo de ATProto como registros actor.rpg.stats.

TypeScript Canvas Deterministic Sim ATProto Records Leaderboards

Props

PropTipoPor defecto
game Game –

Hecho con

Tokens que lee

componente
--cabinet-from --cabinet-to --sink-shadow --screen-star --screen-bg --fs-* --screen-shadow --platform-from --platform-to --platform-edge --platform-hi --player-glow --sp-* --locked-from --locked-to
semántico
--primary --border --scanline-color-screen --font-pixel --foreground --foreground-dim --font-display --foreground-faint

Uso

<ArcadeCabinet game={game} />
AtStatusCard.astro

AtStatusCard

Mi estado de Bluesky en vivo, leído de mi repo de AT Protocol al cargar la página.

Props

No tiene props propias.

Hecho con

Tokens que lee

componente
--fs-* --titlebar-accent --sp-* --sink-radius
semántico
--success --primary --surface-sunken --shadow-color-soft --font-display --foreground --info --border --font-pixel --foreground-faint

Uso

<AtStatusCard />
FeedbackForm.astro

FeedbackForm

Un Button que abre un cajón: una TitleBar sobre un formulario, y en el móvil una hoja que se desliza para cerrar.

déjame una nota

Props

No tiene props propias.

Hecho con

Tokens que lee

componente
--sp-* --fs-* --sink-border --sink-shadow --sink-radius
semántico
--foreground --surface-sunken --foreground-faint --primary --foreground-dim --success --error

Uso

<FeedbackForm />

Plantillas

Los marcos donde las páginas vierten su contenido.

Section.astro

Section

Cada sección de la página de inicio: un Eyebrow, un título y luego lo que vaya dentro.

trabajo destacado

Proyectos.

Esta caja es una Section.

Props

PropTipoPor defecto
id? string –
eyebrow? string –
title? string –

Hecho con

Tokens que lee

Ninguno propio. Sus átomos traen los suyos.

Uso

<Section id="work" eyebrow="selected work" title="Things I've built">
  …
</Section>