diff --git a/src/uix/eidos/components/_layout/index.ts b/src/uix/eidos/components/_layout/index.ts
index 315bc7535..b806f104e 100644
--- a/src/uix/eidos/components/_layout/index.ts
+++ b/src/uix/eidos/components/_layout/index.ts
@@ -1,5 +1,5 @@
/**
- * Layout namespace — re-exports the 8 layout primitives as a single
+ * Layout namespace — re-exports the layout primitives as a single
* group for consumers who prefer the dotted style:
*
* import { Layout } from '$uix/eidos/components/_layout';
@@ -19,6 +19,10 @@ export { default as Group } from '../group';
export { default as Wrap } from '../wrap';
export { default as Container } from '../container';
export { default as Section } from '../section';
+export { default as AspectRatio } from '../aspect-ratio';
+export { default as AutoGrid } from '../auto-grid';
+export { default as Banner } from '../banner';
+export { default as Float } from '../float';
export type { BoxProps } from '../box';
export type { FlexProps } from '../flex';
@@ -28,6 +32,16 @@ export type { GroupProps } from '../group';
export type { WrapProps } from '../wrap';
export type { ContainerProps, ContainerSize, ContainerAlign } from '../container';
export type { SectionProps, SectionSize } from '../section';
+export type { AspectRatioProps, AspectRatioValue } from '../aspect-ratio';
+export type { AutoGridProps } from '../auto-grid';
+export type {
+ BannerProps,
+ BannerCloseProps,
+ BannerIntent,
+ BannerVariant,
+ BannerSize
+} from '../banner';
+export type { FloatProps, FloatSide } from '../float';
export type {
LayoutSpaceValue,
diff --git a/src/uix/eidos/components/aspect-ratio/README.md b/src/uix/eidos/components/aspect-ratio/README.md
new file mode 100644
index 000000000..4957f498e
--- /dev/null
+++ b/src/uix/eidos/components/aspect-ratio/README.md
@@ -0,0 +1,114 @@
+# Eidos AspectRatio
+
+Constrains its inner content to a fixed width/height ratio. Eidos-native:
+the recipe writes a single `--aspect-ratio` custom property on a
+`
` shell (composed through ``) and
+the CSS `aspect-ratio` property does the rest. Useful for video / image /
+iframe containers that must hold their shape regardless of inline size.
+
+## Superficie
+
+```svelte
+
+
+
+
+
+
+
+
+
+
+```
+
+## Baseline
+
+Origen: `air/components/layout/aspect-ratio` (rama `morfo-runtime`).
+
+Adaptaciones aplicadas durante el port:
+
+- Drop del prefijo `air-` y de la dependencia de Terra. Air delegaba la
+ geometría en `TerraAspectRatio.Provider`, que envolvía el contenido en
+ un `
` posicionado con el truco padding-bottom y posicionaba el
+ hijo en absoluto. Eidos usa directamente CSS `aspect-ratio`, soportado
+ por todos los navegadores modernos.
+- Selectores `[data-box][data-aspect-ratio]` en lugar de la clase
+ `air-aspect-ratio`.
+- Variable renombrada de `--air-aspect-ratio-radius` (que no se mapeaba
+ contra nada de la receta) a `--aspect-ratio` (el ratio en sí mismo).
+ El `border-radius` no es propio de aspect-ratio: si el consumidor lo
+ necesita, lo pasa vía `style` o componiendo otro primitive.
+- Resolución reactiva del prop `ratio` vía `ActiveEidos.require().resolve()`
+ para soportar `ResponsiveProp`.
+- El componente compone a través de ``, así que hereda todas las
+ props del box-model (padding, maxWidth, gridColumn, …).
+
+## Comparativa
+
+| Capacidad | UIX (eidos) | Radix Themes | Chakra UI | Mantine |
+| --- | --- | --- | --- | --- |
+| `ratio` numeric | Sí (`ratio={16 / 9}`) | Sí (`ratio={16 / 9}`) | Sí (`ratio={16 / 9}`) | Sí (`ratio={16 / 9}`) |
+| `ratio` string fraction | Sí (`ratio="16/9"`) | No (sólo number) | No | No |
+| Implementation | CSS `aspect-ratio` | CSS `aspect-ratio` | CSS `aspect-ratio` | CSS `aspect-ratio` |
+| Composes through Box | Sí (hereda padding/maxWidth/etc.) | Box ancestor | Box ancestor | Box ancestor |
+| `maxWidth` / sizing props | Sí (vía Box) | Sí | Sí | Sí |
+| Stretches lone child to fill | Sí (`> * { 100% × 100% }`) | Sí | Manual | Manual |
+| Responsive `ratio` prop | Sí (`ResponsiveProp`) | Sí | Sí (objeto breakpoint) | Sí (`{ base, sm, md }`) |
+
+## Decisiones
+
+- **`ratio` acepta number y string** — los tres referentes sólo soportan
+ number. UIX añade la forma string (`"16/9"`) porque deja el valor
+ intacto en DevTools (`aspect-ratio: 16 / 9` se lee literal) y evita el
+ cálculo en JS para ratios canónicos. Las dos formas tipadas como
+ `AspectRatioValue` quedan en `types.ts`.
+- **CSS `aspect-ratio` puro, sin padding-bottom** — air vía Terra usaba
+ el truco padding-bottom + child posicionado en absoluto. Esa técnica
+ era necesaria antes de 2021; hoy `aspect-ratio` es baseline. Eliminamos
+ la complejidad del DOM (un wrapper menos, sin position:absolute en el
+ hijo).
+- **Compose through ``** — patrón consistente con Flex/Grid: el
+ shell `[data-box]` da el box-model y AspectRatio sólo añade la propiedad
+ `aspect-ratio` en su capa.
+- **`object-fit: cover` por defecto en el hijo** — replicated images,
+ videos e iframes se ajustan al box sin estirarse. Si el consumidor
+ quiere `contain`, lo override en el hijo.
+- **No `borderRadius` específico** — diferencia con air, que exponía
+ `--air-aspect-ratio-radius` sin proporcionar prop ni control. UIX
+ delega border-radius a la cascada normal (se aplica desde un `style=`
+ o desde la clase del consumidor).
+
+## Eventos Sema
+
+AspectRatio declara 0 eventos. Es una primitiva pasiva: ajusta la
+geometría de su único hijo y nada más — sin commit, sin emerge, sin
+keyboard. Componentes que animan al cambiar de ratio (raros) componen
+AspectRatio con un primitive interactivo (popover, drawer, collapsible)
+que sí posee los verbos sema relevantes. Misma justificación que Box,
+Flex y Grid.
+
+## Gaps
+
+| Gap | Disposición | Detalle |
+| --- | --- | --- |
+| `as` prop para semantic tag (`figure`, `picture`) | diferir | Hoy se envuelve AspectRatio en el tag semántico. Reconsiderar si llegan ≥2 casos reales. |
+| Per-instance `object-fit` prop sobre el hijo | descartar | Hereda de la cascada normal del hijo (img/video/iframe). Si se necesita override one-off, va vía `style` en el hijo. |
+| `borderRadius` shorthand | descartar | Border-radius no es propio de aspect-ratio. Se aplica desde fuera, igual que en Box. |
+| Detección automática del intrinsic ratio del hijo | diferir | Mantine ofrece esto vía `data-ratio="auto"`. Bajo prioridad: el consumidor casi siempre sabe el ratio. |
+| Documentación per-prop con ejemplos visuales | implementar | Pasada de docs final. Hoy la demo cubre los casos comunes. |
+
+## Referencias
+
+- Radix Themes AspectRatio: https://www.radix-ui.com/themes/docs/components/aspect-ratio
+- Chakra UI AspectRatio: https://chakra-ui.com/docs/components/aspect-ratio
+- Mantine AspectRatio: https://mantine.dev/core/aspect-ratio/
+- CSS `aspect-ratio`: https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio
+
+## Passive justification
+
+Visual-only primitive (`scope: ['eidos']` en el morfo). Una sola
+part Provider que emite el marker `[data-aspect-ratio]`, sin estados,
+sin data-attrs específicos, sin ARIA, sin keyboard. El recipe consume
+la variable `--aspect-ratio` que el componente escribe inline. No hay
+nada que animar, ningún ciclo de vida que enviar a sema, ningún evento
+en el sentido de Morfo. La superficie expuesta es geometría pura.
diff --git a/src/uix/eidos/components/aspect-ratio/aspect-ratio.css b/src/uix/eidos/components/aspect-ratio/aspect-ratio.css
new file mode 100644
index 000000000..eb337ac3d
--- /dev/null
+++ b/src/uix/eidos/components/aspect-ratio/aspect-ratio.css
@@ -0,0 +1,26 @@
+/*
+ * AspectRatio recipe — sets `aspect-ratio` on the Box shell and stretches
+ * the direct child to fill the box. The element itself is laid out by the
+ * cascade (block-level by default) and shrinks the ratio to its inline
+ * size, so combining with `maxWidth`, `width` or grid placement on the
+ * Box works without extra plumbing.
+ *
+ * Why not the legacy padding-bottom hack? CSS `aspect-ratio` ships in
+ * every modern browser and avoids the absolute-positioning of children
+ * that the padding-bottom trick requires. Cleaner DOM, fewer caveats
+ * around overflow / scrollbars.
+ */
+
+[data-box][data-aspect-ratio] {
+ aspect-ratio: var(--aspect-ratio, 1);
+ overflow: hidden;
+}
+
+/* Stretch the lone child (img / iframe / video / picture / inner div) to
+ fill the box without disturbing replaced-element intrinsic ratios when
+ they happen to match. */
+[data-box][data-aspect-ratio] > * {
+ inline-size: 100%;
+ block-size: 100%;
+ object-fit: cover;
+}
diff --git a/src/uix/eidos/components/aspect-ratio/aspect-ratio.svelte b/src/uix/eidos/components/aspect-ratio/aspect-ratio.svelte
new file mode 100644
index 000000000..f71225c25
--- /dev/null
+++ b/src/uix/eidos/components/aspect-ratio/aspect-ratio.svelte
@@ -0,0 +1,53 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/uix/eidos/components/aspect-ratio/index.ts b/src/uix/eidos/components/aspect-ratio/index.ts
new file mode 100644
index 000000000..e2c0ccc00
--- /dev/null
+++ b/src/uix/eidos/components/aspect-ratio/index.ts
@@ -0,0 +1,12 @@
+// AspectRatio — constrains inner content to a width/height ratio.
+//
+// import { AspectRatio } from '$uix/eidos/components/aspect-ratio';
+//
+//
+//
+//
+import AspectRatio from './aspect-ratio.svelte';
+
+export { AspectRatio };
+export default AspectRatio;
+export type { AspectRatioProps, AspectRatioValue } from './types';
diff --git a/src/uix/eidos/components/aspect-ratio/types.ts b/src/uix/eidos/components/aspect-ratio/types.ts
new file mode 100644
index 000000000..5bd81ab28
--- /dev/null
+++ b/src/uix/eidos/components/aspect-ratio/types.ts
@@ -0,0 +1,27 @@
+import type { ResponsiveProp } from '$uix/eidos/lib/types';
+import type { BoxProps } from '../box/types';
+
+/**
+ * Aspect-ratio value. Accepts:
+ * - a number: `ratio={16/9}` → CSS `aspect-ratio: 1.7777…`.
+ * - a fraction string: `ratio="16/9"`, `ratio="4 / 3"`.
+ * - a unitless string: `ratio="1.5"`.
+ *
+ * The string form is preferred when the consumer wants the value to read
+ * verbatim in DevTools (`aspect-ratio: 16 / 9`); the number form is easier
+ * to compute (`ratio={width / height}`).
+ */
+export type AspectRatioValue = number | string;
+
+export type AspectRatioProps = Omit & {
+ /**
+ * Width / height ratio for the box. @default 1 (square).
+ *
+ * Examples:
+ * - `ratio={1}` — square (1:1)
+ * - `ratio={16 / 9}` — widescreen video
+ * - `ratio="4/3"` — standard video
+ * - `ratio="21/9"` — ultrawide
+ */
+ ratio?: ResponsiveProp;
+};
diff --git a/src/uix/eidos/components/auto-grid/README.md b/src/uix/eidos/components/auto-grid/README.md
new file mode 100644
index 000000000..1c8404ef6
--- /dev/null
+++ b/src/uix/eidos/components/auto-grid/README.md
@@ -0,0 +1,118 @@
+# Eidos AutoGrid
+
+Responsive grid container that fits as many columns as its inline size
+allows — no media queries required. Wraps `` (which wraps ``)
+and computes `grid-template-columns: repeat(auto-fill, minmax(MIN, 1fr))`
+in JS based on the `minChildWidth` prop. Falls back to a fixed
+`repeat(N, minmax(0, 1fr))` when `columns` is passed instead.
+
+## Superficie
+
+```svelte
+
+
+
+
+
+
+
+
+
+ …
+
+
+
+
+ …
+
+```
+
+## Baseline
+
+Origen: `air/components/layout/auto-grid` (rama `morfo-runtime`).
+
+Adaptaciones aplicadas durante el port:
+
+- Resolución reactiva (`ActiveEidos.require().resolve()`) en lugar de
+ `getAir().dom.resolve()`.
+- Marker propio `[data-auto-grid]` además del `data-grid` heredado de
+ ``, para que consumidores puedan estilar el primitive específico
+ cuando lo necesiten.
+- Cambio de `auto-fit` a **`auto-fill`** en el template — `auto-fill`
+ preserva las pistas vacías cuando hay menos hijos que columnas
+ disponibles, lo que da un grid más predecible y consistente con la
+ expectativa del consumidor (Chakra `SimpleGrid`, Mantine `SimpleGrid`).
+ Si se quiere `auto-fit` (stretch a las pistas pobladas), el consumidor
+ puede usar ``
+ directamente.
+- Drop del prefijo `air-` y eliminación de la dependencia de `getAir()`.
+
+## Comparativa
+
+| Capacidad | UIX (eidos) | Radix Themes | Chakra UI SimpleGrid | Mantine SimpleGrid |
+| --- | --- | --- | --- | --- |
+| Fluid fit (`minChildWidth`) | Sí (`minChildWidth={240}`) | No (sólo via raw `templateColumns`) | Sí (`minChildWidth`) | Sí (`minChildWidth`) |
+| Fixed columns (`columns`) | Sí (`columns={3}`) | Sí (`columns="3"`) en Grid | Sí (`columns={3}`) | Sí (`cols={3}`) |
+| Responsive `columns` | Sí (`ResponsiveProp`) | Sí (`{ initial: 1, sm: 2 }`) | Sí (`{ base: 1, md: 3 }`) | Sí (`{ base: 1, sm: 2 }`) |
+| Responsive `minChildWidth` | Sí (`ResponsiveProp<…>`) | n/a | Sí | Sí |
+| `gap` shorthand | Sí (vía Grid → Box) | Sí | Sí | Sí (`spacing`) |
+| Per-axis gap (`rowGap`, `columnGap`) | Sí (vía Grid) | Sí | Sí | Sí (`verticalSpacing`, `horizontalSpacing`) |
+| `auto-fill` vs `auto-fit` | `auto-fill` (preserva tracks vacíos) | n/a | `auto-fit` | `auto-fit` |
+| Composes through `` | Sí | n/a | n/a | n/a |
+
+## Decisiones
+
+- **`minChildWidth` gana sobre `columns`** — cuando se pasan ambos, el
+ template fluido es la primitiva específica de AutoGrid; `columns` queda
+ como modo "shortcut" para grids fijos sin necesidad de saltar a
+ ``.
+- **`auto-fill` por defecto** — divergencia de Chakra/Mantine, que usan
+ `auto-fit`. Razón: `auto-fill` deja tracks reservados cuando hay menos
+ hijos que columnas, lo que evita que el primer hijo se estire hasta
+ ocupar todo el inline-size cuando hay sólo uno. Si el consumidor
+ necesita el comportamiento de `auto-fit`, usa ``
+ directamente.
+- **Composición sobre ``** — el primitive es prácticamente puro
+ `templateColumns` computado; no duplica la lógica del recipe de Grid.
+ Cualquier mejora futura del recipe Grid (alignContent, place-items, …)
+ llega "gratis".
+- **`minChildWidth` resuelve con `formatLayoutLength`** — números van a
+ px, strings pasan tal cual (`"15rem"`, `"min(20rem, 50%)"`).
+- **No exponemos `templateColumns`** — entra en colisión con el propio
+ cálculo del primitive. Si se necesita un template custom, se usa
+ `` directamente.
+
+## Eventos Sema
+
+AutoGrid declara 0 eventos. Es una primitiva pasiva: ajusta el template
+de columnas según la geometría del contenedor — sin commit, sin emerge,
+sin keyboard. Componentes que animan items al entrar/salir del grid
+componen AutoGrid con un primitive interactivo (popover, drawer) que sí
+posee los verbos sema relevantes. Misma justificación que Box, Flex,
+Grid y AspectRatio.
+
+## Gaps
+
+| Gap | Disposición | Detalle |
+| --- | --- | --- |
+| `auto-fit` mode prop | diferir | Hoy se usa `` directamente cuando se quiere el comportamiento de auto-fit. Subir a prop si llegan ≥2 casos reales. |
+| `breakpoints` config (Mantine-style array de fallbacks) | descartar | Lo cubre `ResponsiveProp` sobre `columns` y `minChildWidth`. Duplicaría la API. |
+| `spacing` alias para `gap` (Mantine ergonomics) | descartar | Mantenemos `gap` consistente con Box/Flex/Grid. Aliases sólo añaden ruido. |
+| Slot para divider entre filas | diferir | Stack tiene `divider` pending; vendría después de Stack. |
+| `equalChildHeight` toggle | diferir | Posible utility si surge una necesidad real — hoy se logra con `align="stretch"` heredado de Grid. |
+
+## Referencias
+
+- Chakra UI SimpleGrid: https://chakra-ui.com/docs/components/simple-grid
+- Mantine SimpleGrid: https://mantine.dev/core/simple-grid/
+- CSS `grid-template-columns`: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns
+- Smolnar / Heydon "Every Layout" Grid: https://every-layout.dev/layouts/grid/
+
+## Passive justification
+
+Visual-only primitive (`scope: ['eidos']` en el morfo). Una sola
+part Provider que emite el marker `[data-auto-grid]` sobre el shell
+`[data-box][data-grid]`. Sin estados, sin data-attrs específicos, sin
+ARIA, sin keyboard. Toda la lógica se reduce a computar
+`grid-template-columns` y delegar a ``. No hay nada que animar
+ni ciclo de vida que enviar a sema.
diff --git a/src/uix/eidos/components/auto-grid/auto-grid.css b/src/uix/eidos/components/auto-grid/auto-grid.css
new file mode 100644
index 000000000..dd6449e13
--- /dev/null
+++ b/src/uix/eidos/components/auto-grid/auto-grid.css
@@ -0,0 +1,15 @@
+/*
+ * AutoGrid recipe — AutoGrid is a thin compositional layer over Grid.
+ * It computes its `templateColumns` in JS (either `repeat(auto-fill,
+ * minmax(MIN, 1fr))` or `repeat(N, minmax(0, 1fr))`) and forwards every
+ * other prop to ``. The recipe only needs to declare the
+ * `[data-auto-grid]` marker so callers can target the primitive
+ * specifically (e.g. to add a section-scoped override).
+ */
+
+[data-box][data-grid][data-auto-grid] {
+ /* No own properties — every visible style comes from the Grid recipe
+ reading the `--grid-template-columns` variable that AutoGrid emits.
+ The marker exists so external consumers can write
+ `:where([data-auto-grid]) { … }` selectors. */
+}
diff --git a/src/uix/eidos/components/auto-grid/auto-grid.svelte b/src/uix/eidos/components/auto-grid/auto-grid.svelte
new file mode 100644
index 000000000..e38deb821
--- /dev/null
+++ b/src/uix/eidos/components/auto-grid/auto-grid.svelte
@@ -0,0 +1,38 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/uix/eidos/components/auto-grid/index.ts b/src/uix/eidos/components/auto-grid/index.ts
new file mode 100644
index 000000000..c93a5886b
--- /dev/null
+++ b/src/uix/eidos/components/auto-grid/index.ts
@@ -0,0 +1,11 @@
+// AutoGrid — responsive grid that fits columns to inline size.
+//
+// import { AutoGrid } from '$uix/eidos/components/auto-grid';
+//
+// …
+// …
+import AutoGrid from './auto-grid.svelte';
+
+export { AutoGrid };
+export default AutoGrid;
+export type { AutoGridProps } from './types';
diff --git a/src/uix/eidos/components/auto-grid/types.ts b/src/uix/eidos/components/auto-grid/types.ts
new file mode 100644
index 000000000..1e4a5f78d
--- /dev/null
+++ b/src/uix/eidos/components/auto-grid/types.ts
@@ -0,0 +1,28 @@
+import type { ResponsiveProp } from '$uix/eidos/lib/types';
+import type { GridProps } from '../grid/types';
+import type { LayoutLengthValue } from '../_layout/shared';
+
+/**
+ * AutoGrid props.
+ *
+ * Either pass `minChildWidth` (auto-fill: as many columns as fit) or
+ * `columns` (fixed N). When both are passed, `minChildWidth` wins — the
+ * fluid template (`repeat(auto-fill, minmax(MIN, 1fr))`) is the AutoGrid
+ * usecase; the numeric form is included for parity with consumers who
+ * already know `` and just want the AutoGrid prop
+ * surface (no extra Box props, simpler defaults).
+ */
+export type AutoGridProps = Omit & {
+ /**
+ * Minimum inline size per item before wrapping to a new row. Maps to
+ * `repeat(auto-fill, minmax(MIN, 1fr))`. Use this for fluid responsive
+ * grids that need no breakpoints. Number → px.
+ */
+ minChildWidth?: ResponsiveProp;
+ /**
+ * Number of fixed columns. Maps to `repeat(N, minmax(0, 1fr))`. Use
+ * when the layout has a strict column count regardless of viewport.
+ * Ignored when `minChildWidth` is set.
+ */
+ columns?: ResponsiveProp;
+};
diff --git a/src/uix/eidos/components/banner/README.md b/src/uix/eidos/components/banner/README.md
new file mode 100644
index 000000000..396a4d6c5
--- /dev/null
+++ b/src/uix/eidos/components/banner/README.md
@@ -0,0 +1,141 @@
+# Eidos Banner
+
+Full-bleed announcement strip with intent / variant / size visual
+treatment. Renders as `` so the
+landmark works reliably across layouts — HTML spec only grants
+`role="banner"` to a `` when it is a top-level child of ``;
+nesting it inside ``, `` or `` strips the role.
+The explicit role stabilises the announcement intent.
+
+## Superficie
+
+```svelte
+
+ Your changes have been saved.
+
+
+
+
+{#if show}
+
+ Connection lost — reconnecting…
+ (show = false)} />
+
+{/if}
+```
+
+## Baseline
+
+Origen: `air/components/layout/banner` (rama `morfo-runtime`).
+
+Air shipped a single-prop Banner — `` + a small
+spacing/padding recipe and no variants. The task brief asked for a full
+announcement primitive with intent variants and an optional dismiss
+button, modelled after Chakra / Mantine / MUI `Alert`. The current shape
+keeps air's landmark contract (explicit `role="banner"`) and adds:
+
+- `intent` mapped to the canonical UIX `ColorRole` (8 values:
+ `primary | secondary | neutral | affirm | fulfill | risk | threat | loss`).
+- `variant` from the shared `ChipVariant` vocab (`soft | solid | outline | ghost`).
+- `size` narrowed from canonical `Size` to `sm | md | lg` — smaller
+ doesn't read; larger turns the strip into a hero (out of scope).
+- Optional `Banner.Close` part. The dismiss is **composition-driven**:
+ the consumer wraps Banner in `{#if show}` and wires onclick — Banner
+ itself does not own the visibility state. See "Decisiones" below.
+
+Air's CSS prefix (`air-banner`) is dropped; selectors target
+`[data-banner]` directly. CSS variables renamed from `--air-banner-*` to
+`--banner-*` (public) and `--_banner-*` (internal recipe-local).
+
+## Comparativa
+
+| Capacidad | UIX (eidos) | Chakra UI Alert | Mantine Alert | MUI Alert |
+| --- | --- | --- | --- | --- |
+| Intent / status vocabulary | UIX 8 (`primary, secondary, neutral, affirm, fulfill, risk, threat, loss`) | Chakra 4 (`info, warning, success, error`) | Mantine 6 (`blue, gray, red, …` semantic colors) | MUI 4 (`success, info, warning, error`) |
+| Variants | `soft / solid / outline / ghost` | `subtle / left-accent / top-accent / solid` | `filled / light / outline / default / transparent` | `standard / filled / outlined` |
+| Sizes | `sm / md / lg` | Single size + custom | Theme spacing scale | Single size + custom |
+| Landmark `role="banner"` | Sí (explicit) | No (uses `role="alert"`) | No (`role="alert"`) | No (`role="alert"`) |
+| Dismissible | Sí (`Banner.Close` composition) | Sí (`CloseButton` slot) | Sí (`withCloseButton`) | Sí (`onClose`) |
+| Icon slot | Composition (consumer's ``) | `AlertIcon` shorthand | `icon` prop | `icon` prop |
+| Title + description structure | Composition (consumer's markup) | `AlertTitle` / `AlertDescription` | `title` prop | `AlertTitle` |
+| ARIA live region | No — Banner is a landmark, not a live region | `role="alert"` (assertive) | `role="alert"` | `role="alert"` |
+| Responsive props | Sí (`ResponsiveProp` on intent / variant / size) | Sí (`useColorMode`) | Sí (responsive sx) | Sí (`sx`) |
+
+## Decisiones
+
+- **`role="banner"`, not `role="alert"`** — Banner is a landmark for
+ page-level announcements (site header, persistent notice, system
+ status bar). Transient feedback that interrupts the screen reader
+ belongs to ``, which already declares the proper
+ `role="status"` / `aria-live="polite"` contract. Forcing
+ `role="alert"` on a static strip would be aggressive overreach.
+- **Composition, not boolean `dismissible`** — pattern matches the rest
+ of UIX (DatePicker, Dialog, Drawer all dropped `*Button` boolean
+ props 2026-05-21). The consumer wraps Banner in `{#if show}` and
+ includes ` (show = false)} />` to render
+ the dismiss button. Banner doesn't own visibility, doesn't reset its
+ own state, doesn't fire a sema event when closed. The
+ `feedback_user_design_overrides_canon_vocabulary` rule applies: a
+ generic landmark strip doesn't carry an intrinsic commit semantic.
+- **`intent` uses UIX 8-role vocab, not Chakra's 4** — keeps the
+ vocabulary consistent with the rest of the system (SearchField,
+ Toast, Toggle, etc. all use the same `ColorRole`). The mapping from
+ conventional `info / success / warning / error` is documented in the
+ intent canon (`src/uix/intent.ts`).
+- **`variant` = `ChipVariant`** — reuses the canonical 4-value vocab
+ instead of inventing a new union per component (Chakra ships 4,
+ Mantine 5, MUI 3 — none with the same names). The same vocab powers
+ Chip / Tag / Avatar.
+- **No icon / title / description slots** — composition over
+ configuration. The consumer puts an Icon + heading + body inside
+ Banner's children; flex/gap from the recipe handles the spacing.
+- **Close is eidos-only** — meets the four rules in
+ `eidos/components/README.md` (no behavior, no aria contract beyond
+ the user-supplied `aria-label`, no event-target role, no keyboard
+ beyond a plain `