# OpenGlass UI: guía definitiva de la librería Liquid Glass para React

> Arquitectura e integración de OpenGlass UI: 40 componentes nativos, renderizadores CSS, SVG SDF y WebGL2, tokens de diseño, SSR en Next.js y accesibilidad WCAG 2.2.

OpenGlass UI es una librería moderna de componentes para React y la web orientada a materializar la estética del «cristal líquido» (Liquid Glass) en interfaces de usuario. Superando con creces las soluciones CSS simplistas basadas únicamente en `backdrop-filter: blur()`, OpenGlass UI integra modelos físicos de refracción óptica, campos de distancia con signo (SDF, Signed Distance Fields), lentes aceleradas por WebGL2 y accesibilidad nativa conforme a WCAG 2.2.

Esta guía desglosa su arquitectura técnica: desde los tres motores de renderizado y la integración con Next.js App Router hasta la gestión de tokens de diseño y la optimización del rendimiento en GPU.

---

## 1. Concepto de Liquid Glass y capacidades clave de OpenGlass UI

### 1.1. Filosofía del cristal líquido: unión entre DOM nativo y efectos ópticos

El glassmorphism convencional suele presentar problemas de legibilidad del texto y un consumo excesivo de CPU. OpenGlass UI resuelve esta limitación separando responsabilidades:
- **Base semántica:** Sus 40 componentes se estructuran sobre etiquetas HTML nativas (`<button>`, `<input>`, `<dialog>`), conservando el foco por teclado y la compatibilidad con lectores de pantalla.
- **Materiales ópticos:** La capa visual se adapta dinámicamente al fondo mediante contraste adaptativo, tintado, biseles (bevel) y reflejos especulares.
- **Degradación elegante (Graceful Degradation):** Si el dispositivo carece de aceleración o el usuario tiene activada la reducción de transparencia en el sistema operativo, la interfaz conmuta a superficies CSS opacas de alto contraste sin alterar la estructura.

### 1.2. Matriz comparativa de los tres renderizadores: CSS, refracción SVG y WebGL2

OpenGlass UI articula tres pipelines de renderizado en función de la naturaleza de la superficie:

```mermaid
flowchart TD
    A["Petición de renderizado GlassSurface"] --> B{"Tipo de origen y geometría objetivo"}
    B -->|"DOM arbitrario / Controles / Texto"| C["1. Renderizador CSS (Por defecto: desenfoque rápido, bordes, sombras)"]
    B -->|"Geometría cerrada (Rectángulo redondeado, cápsula)"| D["2. Renderizador SVG / SDF (Refracción física con mapa de desplazamiento)"]
    B -->|"Medios dinámicos (Vídeo, Canvas, Imágenes)"| E["3. Renderizador WebGL2 (Lentes de dispersión cromática e IOR en tiempo real)"]
```

| Motor de renderizado | Capacidades ópticas | Carga en GPU | Compatibilidad | Caso de uso idóneo |
| :--- | :--- | :--- | :--- | :--- |
| **CSS (Auto)** | Tintado, desenfoque, bordes y sombras | Mínima | 99.8% (Navegadores modernos) | Botones, campos de formulario, tarjetas, navegación |
| **SDF / SVG** | Refracción luminosa en bordes (IOR) | Moderada | Navegadores con soporte de filtros SVG | Ventanas modales, barras Dock, pestañas |
| **WebGL2** | Dispersión cromática y lentes reales | Alta | Requiere compatibilidad con WebGL2 | Reproductores de vídeo, lentes interactivas sobre 3D |

---

## 2. Arquitectura de paquetes e instalación

### 2.1. Estructura modular: el facade open-glass-ui y paquetes internos

El paquete público `open-glass-ui` unifica cuatro espacios de trabajo internos bien delimitados:

```mermaid
flowchart LR
    A["open-glass-ui (Facade público en npm)"] --> B["@open-glass-ui/core (Geometría, cálculo SDF, tokens sin React)"]
    A --> C["@open-glass-ui/renderers (Materiales CSS, shaders WebGL2, utilidades SVG)"]
    A --> D["@open-glass-ui/react (Proveedores de estado, hooks, ciclo de vida SSR)"]
    A --> E["@open-glass-ui/recipes (40 recetas UI sobre DOM nativo)"]
```

> [!WARNING]
> La importación directa desde paquetes internos (como `@open-glass-ui/core`) está desaconsejada por tratarse de detalles de implementación privados. Utilice siempre los subcaminos públicos:
> - `open-glass-ui` — componentes principales de React, proveedores y hooks.
> - `open-glass-ui/webgl` — subsistema de superficies aceleradas mediante WebGL2.
> - `open-glass-ui/core` — utilidades matemáticas puras para contraste y temas en Server Components.

### 2.2. Instalación de dependencias y configuración global de estilos

Instale la librería con su gestor de paquetes habitual:

```bash
npm install open-glass-ui
# o
pnpm add open-glass-ui
```

Importe la hoja de estilos global en el punto de entrada de la aplicación (`src/app/layout.tsx` o `src/main.tsx`):

```typescript
// Importación obligatoria de estilos base:
import "open-glass-ui/styles.css";
import { Button, Glass, GlassSystemProvider } from "open-glass-ui";

export function RootApplication() {
  return (
    <GlassSystemProvider
      renderer="auto"
      quality="auto"
      motion="system"
      theme={{
        appearance: "system",
        defaultAppearance: "dark",
        theme: { preset: "neutral", contrast: "high", radius: "balanced" },
      }}
    >
      <main className="min-h-screen bg-slate-950 p-8">
        <Glass material="regular" interactive>
          <Button variant="primary">Empezar ahora</Button>
        </Glass>
      </main>
    </GlassSystemProvider>
  );
}
```

---

## 3. Configuración del sistema de temas: paletas, contraste y tokens CSS

### 3.1. Orquestación de temas: presets, modos de apariencia y radios de curvatura

La configuración visual en OpenGlass UI se estructura en tres ejes:
1. **Modo de apariencia (Appearance):** Valores `light`, `dark` o `system`. En `system`, el servidor genera un marcado determinista con `defaultAppearance`, sincronizándose tras la hidratación con `prefers-color-scheme`.
2. **Presets cromáticos:** Opciones integradas (`neutral`, `cobalt`, `teal`, `violet`, `coral`, `amber`) o colores personalizados vía `accent`, `secondary` y `tertiary`.
3. **Radios de borde (Radius):** Selección entre `sharp` (recto), `balanced` (estándar de 12–16px) y `soft` (curvatura orgánica de 24–28px).

### 3.2. Matriz de tokens semánticos (--ogui-*) y validación de contraste (WCAG)

Todos los componentes exponen sus estilos mediante variables CSS normalizadas:

```css
/* Superficies base y bordes */
--ogui-color-background: #090d16;
--ogui-color-surface: rgba(15, 23, 42, 0.65);
--ogui-color-border: rgba(255, 255, 255, 0.12);
--ogui-color-text: #f8fafc;
--ogui-color-muted: #94a3b8;

/* Estados de acento e indicador de foco */
--ogui-color-accent: #38bdf8;
--ogui-color-accent-ink: #031525;
--ogui-color-focus: #0284c7;

/* Radios y parámetros ópticos del material */
--ogui-radius-control: 8px;
--ogui-radius-surface: 16px;
--ogui-material-blur: 16px;
--ogui-material-bevel: 1px;
```

> 💡 **Verificación de contraste:** Emplee la función `contrastRatio(colorA, colorB)` exportada desde `open-glass-ui/core`. El ratio debe alcanzar al menos 4.5:1 en texto regular y 3:1 en encabezados grandes conforme a la pauta WCAG 2.2 AA.

---

## 4. Catálogo de componentes: análisis de 40 recetas sobre DOM nativo

### 4.1. Taxonomía de componentes: controles, overlays, navegación y formularios

La librería provee 40 recetas preparadas para producción sobre marcado nativo:

| Categoría | Componentes disponibles |
| :--- | :--- |
| **Acciones y controles** | `Button`, `IconButton`, `ToggleButton`, `SegmentedControl`, `Switch`, `Slider`, `Stepper` |
| **Navegación y disposición** | `Toolbar`, `Dock`, `Tabs`, `Breadcrumbs`, `Pagination`, `Menu`, `MenuItem` |
| **Capas superpuestas** | `Dialog`, `Drawer`, `Popover`, `Tooltip`, `Toast`, `Alert`, `Banner` |
| **Entrada de datos** | `TextField`, `Textarea`, `NumberField`, `SearchField`, `Select`, `Checkbox`, `RadioGroup`, `FileDropzone` |
| **Visualización y métricas** | `Card`, `Stat`, `Badge`, `Avatar`, `AvatarGroup`, `Accordion`, `Progress`, `Meter`, `Spinner`, `Skeleton`, `MediaControls` |

### 4.2. Estándares de accesibilidad (a11y): enlaces ARIA, gestión del foco y estados

Garantice la accesibilidad de la aplicación respetando las siguientes directrices:
- **Etiquetas obligatorias en botones con icono:** `IconButton` y `SegmentedControl` exigen un atributo `aria-label` descriptivo para lectores de pantalla.
- **Restitución del foco:** `Dialog` y `Drawer` devuelven el foco al activador de forma automática al cerrarse.
- **Doble codificación de estados:** No indique selecciones o errores únicamente con cambios de color o transparencia; acompañe siempre el cambio con un icono o texto explícito.

---

## 5. Trabajo con renderizadores: de CSS universal a WebGL2 acelerado

### 5.1. Refracción declarativa mediante SVG/SDF para geometrías cerradas

En paneles flotantes o tarjetas destacadas es posible activar refracción óptica mediante campos de distancia con signo (SDF):

```typescript
import React from "react";
import { Glass, SdfFilterDefinition, useSdfFilter } from "open-glass-ui";

const panelGeometry = {
  kind: "rounded-rect",
  width: 360,
  height: 200,
  cornerRadius: 24,
} as const;

export function RefractedControlPanel({ children }: { children: React.ReactNode }) {
  const filter = useSdfFilter({
    id: "main-panel-filter",
    width: 360,
    height: 200,
    geometry: panelGeometry,
    quality: "medium",
  });

  return (
    <div className="relative inline-block">
      <SdfFilterDefinition filter={filter} />
      <Glass 
        renderer="sdf-svg" 
        filterId={filter.filterId} 
        geometry={panelGeometry}
        material="regular"
      >
        <div className="p-6 text-slate-100">
          {children}
        </div>
      </Glass>
    </div>
  );
}
```

### 5.2. Lentes ópticas aceleradas en WebGL2 sobre vídeo dinámico y canvas

Al presentar vídeo en directo, canvas dinámicos o entornos 3D, el módulo `open-glass-ui/webgl` proyecta lentes con índice de refracción (IOR) aceleradas por GPU:

```typescript
"use client";

import React, { useRef } from "react";
import { GlassProvider } from "open-glass-ui";
import { WebGLGlassSurface } from "open-glass-ui/webgl";

const opticalMaterial = {
  thickness: 0.62,
  ior: 1.48,           // Índice de refracción
  dispersion: 0.015,   // Dispersión cromática en bordes
  edgeStrength: 0.5,
  bevel: 0.7,
  frost: 0.2,
};

export function InteractiveVideoLens() {
  const videoRef = useRef<HTMLVideoElement>(null);

  return (
    <GlassProvider>
      <div className="relative overflow-hidden rounded-2xl">
        <video 
          ref={videoRef} 
          src="/ambient-flow.mp4" 
          autoPlay 
          loop 
          muted 
          playsInline 
          className="w-full h-auto block"
        />
        <WebGLGlassSurface
          sourceRef={videoRef}
          continuous
          maxDevicePixelRatio={2}
          lenses={[
            {
              x: 180,
              y: 120,
              width: 240,
              height: 120,
              radius: 0.4,
              material: opticalMaterial,
            },
          ]}
        />
      </div>
    </GlassProvider>
  );
}
```

---

## 6. Integración en Next.js App Router y renderizado en servidor (SSR)

### 6.1. Hidratación determinista: delimitación de componentes cliente y utilidades core

OpenGlass UI se adapta a la perfección al App Router de Next.js. El servidor jamás intenta acceder a `window`, `document` o contextos de WebGL.

Aisle el proveedor raíz en un componente cliente:

```typescript
// src/components/providers/GlassRootProvider.tsx
"use client";

import React from "react";
import "open-glass-ui/styles.css";
import { GlassSystemProvider } from "open-glass-ui";

export function GlassRootProvider({ children }: { children: React.ReactNode }) {
  return (
    <GlassSystemProvider
      renderer="auto"
      quality="auto"
      theme={{
        appearance: "system",
        defaultAppearance: "dark",
      }}
    >
      {children}
    </GlassSystemProvider>
  );
}
```

Las funciones matemáticas para calcular temas pueden importarse en Server Components directamente desde `open-glass-ui/core`:

```typescript
// src/app/page.tsx (Server Component)
import { createGlassTheme } from "open-glass-ui/core";
import { GlassRootProvider } from "@/components/providers/GlassRootProvider";

export default function Page() {
  const staticTheme = createGlassTheme({ preset: "neutral", contrast: "high" });

  return (
    <GlassRootProvider>
      <h1 className="text-2xl font-bold">SSR configurado correctamente</h1>
    </GlassRootProvider>
  );
}
```

### 6.2. Prevención de parpadeos de diseño y sincronización con prefers-color-scheme

Para eliminar discordancias durante la hidratación (Hydration Mismatch):
- Evite ramificaciones condicionales basadas en `window.innerWidth` en el renderizado inicial.
- Indique `defaultAppearance="dark"` para generar un marcado inicial uniforme entre cliente y servidor.

---

## 7. Rendimiento técnico y optimización del pipeline gráfico

### 7.1. Minimización de la carga en GPU: límite de DPR y uso selectivo del cristal

La sobrecarga de capas con desenfoque de fondo puede saturar las GPUs domésticas. Siga estas buenas prácticas:
- **Limite el Device Pixel Ratio:** Fije siempre `maxDevicePixelRatio={2}` en las superficies WebGL. Renderizar a DPR 3+ cuadruplica el consumo de memoria gráfica sin mejora visual perceptible.
- **Adopción selectiva:** Aplique efectos de cristal exclusivamente en elementos de primer nivel (encabezados, modales, barras Dock). Los listados densos de datos deben emplear fondos planos.
- **Actualizaciones por puntero:** Para efectos que sigan el cursor, actualice variables CSS o transformaciones de matriz mediante `ref`, evitando estados de React en cada frame de animación.

### 7.2. Caché de campos de distancia con signo (SDF) y control del redimensionamiento

El cálculo de mapas SDF supone una carga computacional apreciable. El hook `useSdfFilter` almacena en caché los mapas generados según las dimensiones de la figura. Al redimensionar la ventana, la librería baja automáticamente la calidad gráfica, recuperando la máxima definición cuando cesa el movimiento.

---

## 8. Matriz de resolución de problemas y preguntas frecuentes (FAQ)

### 8.1. Diagnóstico de artefactos visuales, fallos de contraste y fugas de memoria

| Síntoma o Error | Causa Raíz | Solución Técnica |
| :--- | :--- | :--- |
| Ausencia del efecto de cristal (fondo plano) | Falta importar la hoja de estilos global | Añada `import "open-glass-ui/styles.css";` en el layout raíz |
| Texto ilegible sobre fondos brillantes | Se utiliza el material `clear` con excesiva transparencia | Cambie a `material="regular"` o `material="frosted"` para ganar opacidad base |
| Caída de frames al hacer scroll en móviles | Exceso de superficies anidadas con renderizador `sdf-svg` | Mantenga `renderer="auto"` (CSS) en los elementos habituales |
| Advertencia `WebGL context lost` | Se sobrepasó el límite de contextos canvas activos | Limite a un máximo de 6 lentes activas por superficie `WebGLGlassSurface` |

### 8.2. Preguntas frecuentes de desarrolladores al integrar OpenGlass UI

> ❓ **¿Es compatible la librería con Tailwind CSS?**  
> Sí. OpenGlass UI coexiste perfectamente con clases de utilidad de Tailwind. Es totalmente seguro combinar clases como `className="flex items-center gap-4 p-6"` con propiedades como `material` e `interactive`.

> ❓ **¿Está lista OpenGlass UI para proyectos en producción?**  
> Actualmente se encuentra en estado pre-release. Su arquitectura y API pública están consolidadas, aunque se recomienda revisar el registro de cambios (Changelog) antes de actualizar versiones menores.

> ❓ **¿Cómo reacciona la interfaz ante el modo de alto contraste de Windows?**  
> La librería detecta la media query `forced-colors: active` de manera automática, anulando cualquier transparencia y aplicando bordes sólidos y colores de sistema para asegurar el cumplimiento estricto de accesibilidad.