# CSS Moderno — Ejemplos y Patrones Completos

Referencia extendida de la skill `css-moderno`. Contiene ejemplos de código completos
para Container Queries, CSS Layers, Nesting, Custom Properties, View Transitions,
animaciones y dark mode.

---

## Container Queries — Ejemplo completo

```css
/* Definir el contenedor */
.card-wrapper {
  container-type: inline-size;
  container-name: tarjeta;
}

.card {
  display: grid;
  grid-template-columns: 1fr;
}

@container tarjeta (min-width: 400px) {
  .card {
    grid-template-columns: auto 1fr;
  }
}

@container tarjeta (min-width: 600px) {
  .card {
    grid-template-columns: 200px 1fr 100px;
  }
}
```

### Container Query con unidades de contenedor

```css
.card-titulo {
  /* cqi = 1% del inline-size del contenedor */
  font-size: clamp(1rem, 4cqi, 2rem);
}
```

---

## CSS Layers (@layer) — Ejemplo completo

```css
@layer reset, base, componentes, utilidades, overrides;

@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  * { margin: 0; }
}

@layer base {
  body { font-family: system-ui, sans-serif; }
  a { color: inherit; }
}

@layer componentes {
  .btn {
    padding: 0.5rem 1rem;
    border-radius: 0.25rem;
    background: var(--color-primario);
  }
}

@layer utilidades {
  .mt-4 { margin-top: 1rem; }
  .text-center { text-align: center; }
}
```

### Importar estilos de terceros en capas

```css
@import url('normalize.css') layer(reset);
@import url('bootstrap.css') layer(frameworks);

@layer componentes {
  .btn { /* Sobrescribe Bootstrap sin lucha de especificidad */ }
}
```

---

## CSS Nesting Nativo — Ejemplos

```css
.nav {
  display: flex;
  gap: 1rem;

  & a {
    text-decoration: none;
    color: var(--color-texto);

    &:hover {
      color: var(--color-primario);
    }

    &.activo {
      font-weight: bold;
    }
  }

  @media (max-width: 768px) {
    flex-direction: column;
  }
}
```

### Nesting con pseudo-elementos

```css
.card {
  position: relative;

  &::before {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(to bottom, transparent, rgb(0 0 0 / 0.5));
  }

  & > .card-content {
    position: relative;
    z-index: 1;
  }
}
```

---

## Custom Properties Avanzadas

### Design tokens completos

```css
:root {
  /* Primitivos */
  --azul-500: oklch(56% 0.2 250);
  --azul-600: oklch(46% 0.2 250);

  /* Semanticos */
  --color-primario: var(--azul-500);
  --color-primario-hover: var(--azul-600);
  --color-superficie: #ffffff;
  --color-texto: #0f172a;

  /* Espaciado */
  --espacio-1: 0.25rem;
  --espacio-2: 0.5rem;
  --espacio-4: 1rem;

  /* Tipografia */
  --fuente-base: 'Inter', system-ui, sans-serif;
  --tamano-sm: 0.875rem;
  --tamano-base: 1rem;
  --tamano-lg: 1.125rem;
}
```

### Custom Properties con @property (tipadas)

```css
@property --porcentaje {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 0%;
}

.barra {
  background: linear-gradient(to right, var(--color-primario) var(--porcentaje), #e2e8f0 var(--porcentaje));
  transition: --porcentaje 0.3s ease;
}

.barra:hover {
  --porcentaje: 75%;
}
```

---

## Funciones Matemáticas — Ejemplos extendidos

### round(), mod(), rem()

```css
.grid {
  grid-template-columns: repeat(auto-fill, minmax(round(down, 100%, 150px), 1fr));
}
```

### color-mix()

```css
.boton-hover {
  --color-base: var(--color-primario);
  background-color: color-mix(in oklch, var(--color-base) 80%, black);
}

.overlay {
  background: color-mix(in srgb, var(--color-primario) 20%, transparent);
}
```

---

## Propiedades Lógicas

```css
/* Fisico — mal para internacionalizacion */
.elemento {
  margin-left: 1rem;
  padding-right: 2rem;
  border-top: 1px solid;
}

/* Logico — correcto para cualquier direccion */
.elemento {
  margin-inline-start: 1rem;
  padding-inline-end: 2rem;
  border-block-start: 1px solid;
}

/* Atajos logicos */
.caja {
  margin-inline: auto;
  padding-block: 1rem;
  inset-inline: 0;
  border-start-start-radius: 8px;
}
```

---

## View Transitions API

```css
::view-transition-old(root) {
  animation: salir 0.3s ease-in;
}

::view-transition-new(root) {
  animation: entrar 0.3s ease-out;
}

.hero-imagen {
  view-transition-name: hero;
}

::view-transition-old(hero),
::view-transition-new(hero) {
  object-fit: cover;
}
```

```javascript
document.startViewTransition(() => {
  actualizarDOM();
});
```

---

## Dark Mode — Patrón completo

```css
:root {
  color-scheme: light dark;

  --color-fondo: #ffffff;
  --color-texto: #0f172a;
  --color-borde: #e2e8f0;
  --color-superficie: #f8fafc;
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-fondo: #0f172a;
    --color-texto: #f1f5f9;
    --color-borde: #1e293b;
    --color-superficie: #1e293b;
  }
}

/* Con toggle manual */
[data-tema='claro'] { /* custom props de light */ }
[data-tema='oscuro'] { /* custom props de dark */ }
```

### Imágenes adaptadas

```css
.logo {
  content: url('/logo-claro.svg');
}

@media (prefers-color-scheme: dark) {
  .logo {
    content: url('/logo-oscuro.svg');
  }
}
```

---

## Anti-patrones extendidos

### Layout thrashing en JS

```javascript
// MAL: leer y escribir el DOM alternadamente
for (const el of elementos) {
  const altura = el.offsetHeight;
  el.style.height = (altura * 2) + 'px';
}

// BIEN: separar lecturas de escrituras
const alturas = elementos.map(el => el.offsetHeight);
elementos.forEach((el, i) => {
  el.style.height = (alturas[i] * 2) + 'px';
});
```

### Unidades fijas para tipografía

```css
/* MAL: ignora las preferencias de zoom del usuario */
body { font-size: 16px; }

/* BIEN: relativa a la preferencia del usuario */
body { font-size: 1rem; }
```
