/* Celosía — capa de componentes, Fase D (sdd/celosia-componentes).
   Fichero NUEVO, project-owned — no existe en .claude/celosia/celosia.css
   (vendored, ADR-006, no se edita). Design #348 AD-1: `.ce-btn`/.ce-notice`
   son componentes vendored con deltas intencionadas frente a esa versión;
   `.ce-tag`/`.ce-card`/`.ce-hero` son huecos reales del sistema de diseño
   vendored (proposal #346), rellenados aquí con valores reales de Mística
   (github.com/Telefonica/mistica-web), nunca inventados en el sitio de uso
   (hard rule 1 — nada fuera de var(--ce-*)).

   === Cascade (design #348 AD-2, non-negociable) ===
   celosia.css → preset-{id}.css → celosia-bootstrap.css →
   celosia-componentes.css → site.css
   Este fichero se enlaza DESPUÉS de celosia-bootstrap.css y ANTES de
   site.css (ver inc_menu.php). Gana a Bootstrap .card/.badge/.alert-* por
   orden de aparición a igualdad de especificidad (0,1,0) — cero
   `!important`. La migración retira siempre la clase Bootstrap del
   elemento migrado; nunca co-clasea (R6, AD-2).

   === Qué SÍ entra (a fecha de esta unidad — W6) ===
   - .ce-btn / .ce-btn--secondary / .ce-btn--icon — botón vendored
     (.claude/celosia/celosia.css:149-166) traído aquí con dos deltas
     intencionadas (AD-1): (1) `.ce-btn--icon` (nueva, no existe en el
     vendored) hace visible el borde que `.ce-btn` YA declaraba transparente
     (`border: var(--ce-size-border-width-strong) solid transparent`, línea
     159 del vendored) fijando solo `border-width`/`border-color` — nunca un
     `border` shorthand nuevo, para no perder `border-style: solid` ni
     reintroducir opacidad — con `var(--ce-size-border-width-medium)`
     (1.5px, token nuevo de esta unidad, ver celosia.css). Overrule de
     design #348 AD-4, que reutilizaba `--ce-size-border-width-strong`
     (2px): spec #347 exige 1.5px literal, que es la constante real de
     Mística (`button.css.ts`, `const borderSize`), no un fallback. Radio
     SIN CAMBIOS: `.ce-btn--icon` hereda `var(--ce-size-radius-md)` (4px)
     de `.ce-btn`, no se vuelve circular — Mística no publica una variante
     de radio distinta para el botón de icono, y hard rule 1 prohíbe
     inventar uno nuevo solo para "verse redondo" como hacían los
     dialectos vendored que sustituye (52px/42px/40px con `border-radius:
     50%` + `box-shadow`, ver site.css). CERO box-shadow (D1, spec
     celosia-component-adoption). (2) `:disabled` además de
     `[aria-disabled="true"]` en la regla de estado inactivo: el vendored
     solo contempla `aria-disabled` (asume que el proyecto gestiona el
     enfocable manualmente), pero los tres adoptantes reales de cita-previa
     usan el atributo HTML nativo `disabled` con JS que ya lo alterna —
     cambiar a `aria-disabled` habría exigido tocar ese JS, fuera de
     alcance de esta unidad; se añade el selector nativo sin retirar el de
     aria-disabled (ambos caminos quedan cubiertos). Primeros adoptantes
     reales: cita-previa/index.php (3 botones de navegación del asistente,
     `.ce-btn`/`.ce-btn--secondary`) y widgets/widget-custom.php (CTA circular
     del banner, `.ce-btn--icon`, dentro del propio `.ce-hero` — ver más
     abajo).
   - .ce-tag — pastilla de solo lectura: fondo surface-sunken, borde
     subtle, radio var(--ce-size-radius-tag) (24px, Mística
     defaultBorderRadiiConfig.tag — distinto del "chip", 16px, sin punto de
     uso en este sitio). Formaliza el dialecto de pastilla ya coherente en
     el sitio (categoría de novedades, filtros, paginación) y sustituye
     `badge bg-secondary` (Bootstrap, nube de etiquetas del detalle de
     novedades) y el texto plano sin estilo de `widget-oferta-educativa-tipo`
     (spec celosia-tag). Sin box-shadow/transform (D1). Adoptado en W3 en la
     nube de etiquetas y el dialecto de categoría del cluster de novedades
     (novedades/index.php, widgets/ultimas-novedades.php) y en
     widgets/oferta-educativa.php.
   - .ce-card / .ce-card--flush — superficie plana: background-color +
     1px de borde + var(--ce-size-radius-container), sin sombra ni
     transform en ningún estado (spec #347 celosia-card). Fuente: Mística
     card-internal.css.ts / boxed.css.ts — la tarjeta es plana por
     diseño; la afordancia de interacción es un cambio de
     background-color (touchableCardOverlay), nunca una elevación.
     Definida en W1, adoptada por primera vez en W2.
   - .ce-notice / .ce-notice__icono / .ce-notice__contenido — superficie
     SIEMPRE neutra (surface-sunken), 1px border-subtle, radio
     var(--ce-size-radius-container). La severidad NUNCA se codifica en
     background-color: vive solo en la FORMA del icono del slot
     .ce-notice__icono (círculo/triángulo/círculo-tachado, distintos
     entre sí incluso en escala de grises) más la palabra de severidad en
     el texto (hard rule 5, spec celosia-component-adoption). Design #348
     AD-6: se retira a propósito la barra izquierda de 3px coloreada por
     severidad del .ce-notice vendored (.claude/celosia/celosia.css:215-
     219) — esa barra es justo lo que D2 elimina. Adoptado en W8 en
     aviso-legal/index.php (--info) y accesibilidad/index.php
     (--warning); --success/--danger quedan definidos para adoptantes
     futuros sin uso real todavía.
   - .ce-hero — contrato ESTRECHO en este fichero, a propósito (AD-3 solo
     sumó 6 tokens en total para toda la fase, 3 de ellos de geometría de
     hero — no hay tokens de tipografía/espaciado de hero en Mística
     todavía). Aquí vive lo que spec #347 exige con esos tokens: SIN
     border-radius, min-height var(--ce-size-hero-min)/-lg (400/460px) en
     el breakpoint de escritorio ya existente en el proyecto (768px).
     var(--ce-size-hero-measure) (75%) YA NO se aplica como max-width de
     .ce-hero__contenido (corrección posterior a petición expresa: era
     redundante sobre la columna de texto del grid de 2 columnas, que ya
     mide ~42% del hero por sí sola — ver el comentario junto a la
     definición de .ce-hero__contenido más abajo). NO reutiliza .ce-card/.ce-card--flush (spec,
     explícito) — familia de componente distinta, igual que .ce-notice
     frente a .ce-card en AD-6. El resto del marcado interno del hero
     (.ce-hero__meta/-fecha/-titulo/-resumen/-flecha/-imagen/
     -indicadores — SIN box-shadow/transform en ningún elemento,
     incluido el CTA circular, que en los dos dialectos que sustituye
     llevaba sombra + scale-on-hover vendored, ambos retirados, no
     trasladados) vive en site.css, igual que .novedades-card-titulo/
     -resumen viven en site.css encima de .ce-card en vez de aquí.
     Consolida DOS dialectos independientes que llevaban el mismo
     marcado duplicado desde antes de esta fase — widgets/hero-
     noticias.php y novedades_render_destacada() en public/novedades/
     index.php — en una única definición (W9). El banner de cita-previa
     (radio 14px, .widget-custom-banner), diferido aquí en W9, se
     adopta en W6: es el caso "hero SIN imagen" (un solo hijo directo,
     `.ce-hero__contenido`, sin `.ce-hero__imagen-wrap`) — sin ese
     segundo hijo, la rejilla de dos columnas (5fr/7fr) dejaría un hueco
     vacío del 7fr en escritorio. Se resuelve con un override de
     `grid-template-columns` en site.css, con más especificidad de
     selector (`.ce-hero.widget-custom-banner`) que gana sin
     `!important` — ni aquí ni en site.css se redefine `.ce-hero` en sí
     (instrucción explícita de esta unidad: reusar, no redeclarar). El
     resto del contrato (min-height 400/460px, sin radio, fondo
     `--ce-color-semantic-surface`) se hereda sin cambios, igual que
     cualquier otro adoptante de `.ce-hero`.

   === Qué NO entra todavía (AD-5 — cada componente se define en la
   misma unidad que su primer adoptador, no todos de golpe) ===
   (ninguno pendiente tras W6 — .ce-btn/.ce-btn--icon quedan definidos
   más abajo)

   === Constante de diseño de todo el fichero (D1, spec celosia-component-tokens) ===
   CERO tokens de sombra/elevación (--ce-shadow-*) y CERO uso de
   `box-shadow`/`transform` como afordancia de interacción en cualquier
   componente de este fichero. Mística no tiene sistema de elevación
   (sprinkles.css.ts / skin-contract.css.ts, verificado en proposal #346);
   esto es una decisión, no un olvido — grep-verificable. */

/* ---------- Tarjeta (celosia-card) ---------- */
.ce-card {
  display: block;
  position: relative;
  background-color: var(--ce-color-semantic-surface);
  border: var(--ce-size-border-width) solid var(--ce-color-semantic-border-subtle);
  border-radius: var(--ce-size-radius-container);
  padding: var(--ce-space-4);
  transition: background-color var(--ce-duration-fast);
}

/* position: relative es el contexto de posicionamiento que necesita
   .stretched-link (utilidad de Bootstrap, vendorizada, sin CSS propio aquí)
   cuando el enlace del título de una tarjeta la usa para hacer clicable
   toda la superficie -- sin esto, su ::after se posicionaría contra el
   ancestro posicionado más cercano en vez de contra la propia tarjeta. Los
   demás usos de .ce-card sin stretched-link no se ven afectados: relative
   sin desplazamiento no cambia el flujo. Ver novedades_render_card() y
   widgets/ultimas-novedades.php.
   El position/z-index que mantiene el .ce-tag de categoría clicable POR
   ENCIMA del ::after del stretched-link NO vive aquí a propósito: un
   ".ce-card .ce-tag" genérico también engancha a widgets/oferta-educativa.php
   (su .ce-tag de tipo vive dentro de un .ce-card, sin relación con
   stretched-link) y le pisaba su position:absolute propio con este
   position:relative -- regresión real detectada en producción. Vive en
   site.css, acotado a los dos selectores concretos que sí usan
   stretched-link (.novedades-card-meta .ce-tag /
   .widget-ultimas-novedades-meta .ce-tag). */

/* Sin afordancia de :hover (a petición expresa, retirada tras probarla).
   :focus-within se mantiene aparte y NO se toca: es el indicador de foco
   por teclado de una tarjeta que envuelve un enlace/control interno
   (WCAG 2.4.7, foco visible) -- quitarlo sería una regresión de
   accesibilidad, no una preferencia visual. Ningún box-shadow, ningún
   transform. */
.ce-card:focus-within {
  background-color: var(--ce-color-semantic-surface-sunken);
}

/* .ce-card--flush es un MODIFICADOR (se añade junto a .ce-card, nunca la
   sustituye): permite media a sangre dentro del mismo contrato de borde
   y radio. overflow:hidden recorta la media al border-radius de la
   tarjeta en vez de que la media lo desborde en las esquinas. */
.ce-card--flush {
  padding: 0;
  overflow: hidden;
}

.ce-card--flush > :first-child {
  display: block;
  width: 100%;
}

/* ---------- Aviso (celosia-notice) ---------- */
/* Contenedor SIEMPRE neutro: fondo surface-sunken, borde subtle, radio
   container. A propósito no hay variante de background-color por
   severidad (spec: "no CSS rule MAY key background-color to a severity
   class") ni box-shadow/transform (D1, igual que .ce-card). */
.ce-notice {
  display: flex;
  align-items: flex-start;
  gap: var(--ce-space-3);
  background-color: var(--ce-color-semantic-surface-sunken);
  border: var(--ce-size-border-width) solid var(--ce-color-semantic-border-subtle);
  border-radius: var(--ce-size-radius-container);
  padding: var(--ce-space-4);
  color: var(--ce-color-semantic-text-primary);
}

/* Slot de icono: decorativo (aria-hidden en el marcado), la severidad se
   apoya en su FORMA + la palabra de severidad en .ce-notice__contenido,
   nunca solo en el color (hard rule 5). El color del icono es una ayuda
   adicional, no el único portador. */
.ce-notice__icono {
  flex-shrink: 0;
  font-size: var(--ce-font-size-lg);
  line-height: var(--ce-font-leading-tight);
}

.ce-notice__contenido {
  flex: 1 1 auto;
}

/* Estas cuatro reglas SOLO tocan el color del icono. Ninguna toca
   background-color del contenedor — verificable con
   grep -E "ce-notice--(info|success|warning|danger)" que no aparezca
   junto a background-color en este fichero. */
.ce-notice--info .ce-notice__icono {
  color: var(--ce-color-state-info);
}

.ce-notice--success .ce-notice__icono {
  color: var(--ce-color-state-success);
}

.ce-notice--warning .ce-notice__icono {
  color: var(--ce-color-state-warning);
}

.ce-notice--danger .ce-notice__icono {
  color: var(--ce-color-state-danger);
}

/* ---------- Etiqueta de solo lectura (celosia-tag) ---------- */
/* Formaliza el dialecto de "pastilla" ya coherente en el sitio (categoría
   de novedades, filtros, paginación): fondo surface-sunken, borde subtle,
   texto en el color de enlace de marca. La diferencia deliberada frente a
   esos dialectos (que siguen usando 999px, literal de site.css, capa de
   página) es el radio: var(--ce-size-radius-tag) — 24px, la etiqueta de
   solo lectura de Mística, no el "chip" (16px, sin punto de uso, ver
   celosia.css). Sustituye `badge bg-secondary` y el texto plano sin
   estilo de `widget-oferta-educativa-tipo` (spec celosia-tag). Sin
   box-shadow/transform (D1). */
.ce-tag {
  display: inline-block;
  background-color: var(--ce-color-semantic-surface-sunken);
  border: var(--ce-size-border-width) solid var(--ce-color-semantic-border-subtle);
  border-radius: var(--ce-size-radius-tag);
  padding: var(--ce-space-1) var(--ce-space-3);
  font-size: var(--ce-font-size-xs);
  font-weight: var(--ce-font-weight-bold);
  color: var(--ce-color-semantic-link);
  text-decoration: none;
  white-space: nowrap;
}

/* Igual que los dialectos que sustituye: la afordancia de interacción es
   el subrayado, no un cambio de color ni de fondo (D1, coherencia con
   .novedades-card-cat / .widget-ultimas-novedades-cat, ya retirados). */
.ce-tag:hover {
  text-decoration: underline;
}

/* ---------- Hero (celosia-hero) ---------- */
/* Contrato ESTRECHO, a propósito (a diferencia de .ce-card/.ce-tag/
   .ce-notice, que son componentes de sistema completos): AD-3 (design
   #348) solo añadió 6 tokens en total para toda esta fase — 3 de radio
   y 3 de geometría de hero — no hay tokens de tipografía/espaciado
   propios de hero en Mística para esta unidad. Por eso .ce-hero define
   AQUÍ solo lo que el spec #347 exige literalmente con esos tokens: sin
   border-radius, min-height 400/460 y ancho de contenido ~75%. El resto
   del marcado interno (título, fecha, flecha, imagen — antes duplicado
   en dos dialectos) se consolida en site.css bajo el MISMO prefijo
   .ce-hero__*, igual que .novedades-card-titulo/-resumen siguen viviendo
   en site.css encima de .ce-card en vez de dentro de este fichero. */
.ce-hero {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  min-height: var(--ce-size-hero-min);
  background-color: var(--ce-color-semantic-surface);
  overflow: hidden;
}

@media (max-width: 767px) {
  .ce-hero {
    /* minmax(0, 1fr), no 1fr a secas: un 1fr suelto hereda un mínimo
       implícito "auto" (= min-content del item, p.ej. la palabra más
       larga del título), que puede desbordar la caja del hero con texto
       largo. El 0 en el minmax elimina ese suelo. */
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (min-width: 768px) {
  .ce-hero {
    min-height: var(--ce-size-hero-min-lg);
  }
}

/* var(--ce-size-hero-measure) (75%) RETIRADO como max-width de
   .ce-hero__contenido (spec #347/design #348 original, corregido a
   petición expresa tras verlo en producción). En escritorio .ce-hero ya
   es un grid de 2 columnas (minmax(0,5fr) minmax(0,7fr)) -- la columna
   de texto ya mide ~42% del hero antes de que este max-width actuara.
   Un 75% ADICIONAL sobre esa columna ya angosta (75% de ~465px ≈ 349px)
   la encogía todavía más sin necesidad real: la medida de lectura que
   --ce-size-hero-measure pretendía garantizar ya la da el propio grid.
   El token sigue definido (otros consumidores futuros podrían necesitar
   una medida de una sola columna real, sin split de grid) pero deja de
   aplicarse aquí. */

/* ---------- Botón (celosia-btn) ---------- */
/* Traído del vendored (.claude/celosia/celosia.css:149-166) con las dos
   deltas documentadas en la cabecera (AD-1): soporte de `:disabled`
   nativo además de `[aria-disabled]`, y la nueva variante `--icon`. Cero
   box-shadow en cualquier variante (D1). */
.ce-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ce-space-2);
  min-height: var(--ce-size-touch-comfortable);
  min-width: var(--ce-size-touch-min);
  padding: var(--ce-space-2) var(--ce-space-4);
  font: inherit;
  font-weight: var(--ce-font-weight-medium);
  border: var(--ce-size-border-width-strong) solid transparent;
  border-radius: var(--ce-size-radius-md);
  cursor: pointer;
  background: var(--ce-color-semantic-action);
  color: var(--ce-color-semantic-text-on-brand);
  transition: background-color var(--ce-duration-fast);
}

.ce-btn:hover {
  background: var(--ce-color-semantic-action-hover);
}

/* aria-disabled cubre el caso vendored (control enfocable, JS decide);
   :disabled cubre el caso real de esta unidad (cita-previa/index.php usa
   el atributo HTML nativo, ya alternado por su propio JS — no se toca). */
.ce-btn:disabled,
.ce-btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
}

.ce-btn--secondary {
  background: var(--ce-color-semantic-surface);
  color: var(--ce-color-semantic-action);
  border-color: currentColor;
}

/* Variante de icono (nueva, W6, AD-4 override — ver cabecera del fichero
   para el porqué de 1.5px en vez de los 2px de design #348). `.ce-btn` ya
   declara su borde transparente arriba: aquí solo se cambian el GROSOR
   (nuevo token) y el COLOR (para hacerlo visible) como propiedades
   independientes, nunca un `border` shorthand nuevo — así no se pierde
   `border-style: solid` ni se reintroduce sin querer la opacidad. Radio
   SIN CAMBIOS (hereda --ce-size-radius-md, 4px): no hay token de radio
   circular para botones en Mística, y hard rule 1 prohíbe inventar uno
   solo para esta variante. Cero box-shadow (D1) — sustituye los cinco
   valores de sombra de los dialectos vendored (52px/42px/40px con
   border-radius:50%, ver site.css), no los traslada. */
.ce-btn--icon {
  border-width: var(--ce-size-border-width-medium);
  border-color: currentColor;
}
