/* ════════════════════════════════════════════════════════════════════
   Milpa — layouts (la parcela) · @milpa/design
   Estructura de página: el shell de docs versionadas (mui-docs) +
   vocabulario de marketing/media (hero, sections, pricing, footer…).
   Requiere: dist/milpa-tokens.css + motion/milpa-motion.css +
   primitives/milpa-primitives.css + components/milpa-components.css +
   artifacts/milpa-artifacts.css (compone toc, search, prose,
   version-switcher/banner).
   Sigue el molde de primitives/milpa-primitives.css — mismas convenciones.
   Cascada: este archivo vive en @layer — el CSS del consumidor/plugin
   gana sin !important (THEMING.md).
   ════════════════════════════════════════════════════════════════════ */

@layer milpa.tokens, milpa.motion, milpa.primitives, milpa.components, milpa.artifacts, milpa.layouts;

@layer milpa.layouts {

/* ---------- Docs · .mui-docs ----------
   La parcela de lectura: topbar sticky (hermano ANTERIOR al grid) +
   grid de 3 columnas nav / artículo / toc. REUSA el idioma del shell
   admin — off-canvas con scrim en móvil, barra-grano en el item
   actual — pero acá todo vive SOBRE var(--bg): la elevación la siguen
   definiendo los bordes (regla 1). Compone los artefactos de contenido
   (mui-prose, mui-toc, mui-search-trigger, mui-breadcrumbs,
   mui-version-*) — no los redeclara. El body del consumidor pone el
   lienzo: background var(--bg) + color var(--text). */
.mui-docs,
.mui-docs__topbar {
  --_topbar-h: 3.5rem;
  --_max-w: 90rem;
  --_pad-inline: clamp(var(--space-4), 3vw, var(--space-8));
}

/* el grid — minmax(0,1fr) en la columna del artículo: el código ancho
   scrollea adentro (overflow del .mui-code), nunca revienta la parcela */
.mui-docs {
  display: grid;
  grid-template-columns: minmax(15rem, 17rem) minmax(0, 1fr) minmax(13rem, 15rem);
  gap: clamp(var(--space-6), 3vw, var(--space-10));
  width: 100%;
  max-width: var(--_max-w);
  margin-inline: auto;
  padding-inline: var(--_pad-inline);
}

/* topbar — velo del lienzo: color-mix + blur (idioma del proof y la
   landing). Full-bleed, hermano ANTERIOR al grid; el padding-inline se
   estira para que su contenido alinee con la parcela centrada de 90rem. */
.mui-docs__topbar {
  position: sticky; top: 0; z-index: var(--z-sticky);
  display: flex; align-items: center; gap: var(--space-4);
  height: var(--_topbar-h);
  padding-inline: max(var(--_pad-inline), calc((100% - var(--_max-w)) / 2 + var(--_pad-inline)));
  background: color-mix(in srgb, var(--bg) 85%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border-subtle);
}

/* brand — slot del símbolo Grano (SVG) + wordmark; la voz de la sidebar */
.mui-docs__brand {
  display: flex; align-items: center; gap: var(--space-2); flex: none;
  font-family: var(--font-display); font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-tight);
  color: var(--text); text-decoration: none;
}
.mui-docs__brand:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* nav del topbar — links que componen .mui-btn mui-btn--ghost mui-btn--sm;
   en ≤880px se oculta (el consumidor duplica los links como primer
   grupo del drawer — ver contrato) */
.mui-docs__topbar-nav {
  display: flex; align-items: center; gap: var(--space-1);
  min-width: 0;
}

/* acciones — search-trigger + version-switcher + toggle de tema, al final */
.mui-docs__topbar-actions {
  display: flex; align-items: center; gap: var(--space-2);
  margin-inline-start: auto;
}

/* hamburguesa — compone .mui-btn mui-btn--ghost mui-btn--icon; solo ≤880px */
.mui-docs__nav-toggle { display: none; }

/* nav (col 1) — sticky bajo el topbar, scrollea por su cuenta. El
   padding-inline space-1 deja vivir al anillo de foco dentro del scroll
   container (precedente .mui-toc); el respiro block (space-8) alinea
   con el padding-block del main. Scrollbar sutil, tokens y nada más. */
.mui-docs__nav {
  align-self: start;
  position: sticky; top: var(--_topbar-h);
  max-height: calc(100dvh - var(--_topbar-h));
  overflow-y: auto; overscroll-behavior: contain;
  padding: var(--space-8) var(--space-1);
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}

/* grupo — heading mono (la voz de la máquina), como .mui-sidebar__section-label */
.mui-docs__nav-group { margin-block-start: var(--space-5); }
.mui-docs__nav-group:first-child { margin-block-start: 0; }
.mui-docs__nav-heading {
  display: block; margin: 0;
  padding: var(--space-2) var(--space-3) var(--space-1);
  font-family: var(--font-mono); font-size: var(--text-2xs);
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
}

/* item — <a>. El estado actual es aria-current="page", nunca una clase.
   OJO hover: mui-docs vive SOBRE var(--bg), así que el item se hunde a
   var(--surface) — no a var(--bg) como en la sidebar del admin
   (text/surface y text-secondary/surface verificados en el gate). */
.mui-docs__nav-item {
  position: relative;
  display: block;
  padding: var(--space-1_5) var(--space-3);
  font-family: var(--font-display); font-size: var(--text-sm);
  line-height: var(--leading-snug);
  color: var(--text-secondary); text-decoration: none;
  border-radius: var(--radius-sm);
  transition:
    background-color var(--dur-fast) var(--ease-standard),
    color            var(--dur-fast) var(--ease-standard);
}
.mui-docs__nav-item:hover { color: var(--text); background: var(--surface); }
.mui-docs__nav-item:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.mui-docs__nav-item[aria-current="page"] {
  color: var(--accent-text); background: var(--accent-subtle);
  font-weight: var(--weight-medium);
}
/* la firma: el grano que germina — barra oro en el arranque del item
   (lenguaje exacto de .mui-sidebar__item del admin).
   accent/accent-subtle ≥3:1 en ambos temas (9.29 dark · 3.56 light). */
.mui-docs__nav-item[aria-current="page"]::before {
  content: ""; position: absolute;
  inset-inline-start: 0; top: 50%;
  width: 3px; height: 1.25rem;
  transform: translateY(-50%);
  border-radius: var(--radius-full);
  background: var(--accent);
}

/* main (col 2) — el artículo. El consumidor apila adentro:
   .mui-version-banner → .mui-breadcrumbs → article.mui-prose → __pager */
.mui-docs__main {
  min-width: 0;
  padding-block: var(--space-8);
}

/* aside (col 3) — el mismo sticky que el nav; adentro vive .mui-toc
   (el scroll-spy y el aria-current="location" son de su contrato) */
.mui-docs__aside {
  align-self: start;
  position: sticky; top: var(--_topbar-h);
  max-height: calc(100dvh - var(--_topbar-h));
  overflow-y: auto; overscroll-behavior: contain;
  padding: var(--space-8) var(--space-1);
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}

/* toc inline — <1100px la columna del toc se cae y el consumidor mueve
   el índice a un <details> arriba del artículo: summary "En esta
   página" + el MISMO nav .mui-toc adentro (el toc no tiene variante
   inline — esto es marco del layout, no un toc nuevo). Oculto en
   desktop; el estado abierto es [open], nunca una clase. */
.mui-docs__toc-inline {
  display: none;
  margin-block-end: var(--space-6);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}
.mui-docs__toc-inline > summary {
  padding: var(--space-2) var(--space-3);
  font-family: var(--font-mono); font-size: var(--text-2xs);
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
  cursor: pointer; user-select: none;
  border-radius: var(--radius-md);
  transition: color var(--dur-fast) var(--ease-standard);
}
.mui-docs__toc-inline > summary:hover { color: var(--text-secondary); }
/* anillo por dentro — el summary es edge-to-edge del marco redondeado
   (precedente .mui-search__input) */
.mui-docs__toc-inline > summary:focus-visible {
  outline: 2px solid var(--focus); outline-offset: -2px;
}
.mui-docs__toc-inline[open] > summary {
  color: var(--text-secondary);
  border-block-end: 1px solid var(--border-subtle);
  border-end-start-radius: 0; border-end-end-radius: 0;
}
.mui-docs__toc-inline > .mui-toc { padding: var(--space-2) var(--space-3) var(--space-3); }

/* pager — prev/next al pie del artículo. Cards silenciosas (borde
   sutil, regla 1); el hover afirma el boundary (border-strong ≥3 sobre
   --bg). Sin prev, --next se ancla solo a la columna 2. */
.mui-docs__pager {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
  margin-block-start: var(--space-10);
}
.mui-docs__pager-link {
  display: block;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  text-decoration: none;
  transition: border-color var(--dur-fast) var(--ease-standard);
}
.mui-docs__pager-link:hover { border-color: var(--border-strong); }
.mui-docs__pager-link:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.mui-docs__pager-link--next { grid-column: 2; text-align: end; }
.mui-docs__pager-dir {
  display: block; margin-block-end: var(--space-1);
  font-family: var(--font-mono); font-size: var(--text-2xs);
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
}
.mui-docs__pager-title {
  display: block;
  font-family: var(--font-display); font-size: var(--text-sm);
  font-weight: var(--weight-medium); line-height: var(--leading-snug);
  color: var(--accent-text);
}

/* scrim — velo del drawer móvil; existe solo con [data-nav-open] ≤880px */
.mui-docs__scrim { display: none; }

/* ---------- responsive ≤1100px ----------
   Dos columnas: la del toc se cae y el índice reaparece plegado arriba
   del artículo (.mui-docs__toc-inline). */
@media (max-width: 1100px) {
  .mui-docs { grid-template-columns: minmax(15rem, 17rem) minmax(0, 1fr); }
  .mui-docs__aside { display: none; }
  .mui-docs__toc-inline { display: block; }
}

/* ---------- responsive ≤880px ----------
   Una columna; el nav se vuelve drawer off-canvas — patrón EXACTO del
   shell admin: cerrado = fuera del lienzo Y fuera del teclado/árbol de
   a11y. visibility flipa al TERMINAR el slide-out (delay
   --dur-moderate); al abrir flipa al instante para que el slide-in sea
   visible. El JS del consumidor además alterna `inert` (cinturón y
   tirantes). El hook de layout es [data-nav-open] en .mui-docs; la
   semántica la lleva aria-expanded en el toggle. */
@media (max-width: 880px) {
  .mui-docs { grid-template-columns: 1fr; }

  .mui-docs__nav {
    position: fixed; inset-block: 0; inset-inline-start: 0;
    width: 17rem; max-height: none;
    padding: var(--space-4) var(--space-3);
    background: var(--bg);
    border-inline-end: 1px solid var(--border-subtle);
    z-index: var(--z-drawer);
    transform: translateX(-100%);
    visibility: hidden;
    transition:
      transform  var(--dur-moderate) var(--ease-grano),
      visibility var(--dur-instant) var(--ease-linear) var(--dur-moderate);
    /* reduce → transform a 1ms (contrato global): 1 frame estático */
  }
  .mui-docs[data-nav-open] .mui-docs__nav {
    transform: none; visibility: visible; box-shadow: var(--shadow-md);
    transition:
      transform  var(--dur-moderate) var(--ease-grano),
      visibility var(--dur-instant);
  }

  /* scrim — cubre el topbar (z-backdrop > z-sticky) y queda bajo el
     drawer; clickearlo cierra (JS del consumidor) */
  .mui-docs[data-nav-open] .mui-docs__scrim {
    display: block;
    position: fixed; inset: 0;
    z-index: var(--z-backdrop);
    background: color-mix(in srgb, var(--bg) 55%, transparent);
    animation: milpa-fade var(--dur-moderate) var(--ease-standard) both;
  }

  /* los links del topbar migran al drawer (los duplica el consumidor) */
  .mui-docs__topbar-nav { display: none; }
  .mui-docs__nav-toggle { display: inline-flex; }
}

/* ════════════════════════════════════════════════════════════════════
   cluster · page
   ════════════════════════════════════════════════════════════════════ */
/* ---------- Page · .mui-page / .mui-container / .mui-section ----------
   El lienzo de marketing/contenido — los ld-* de la landing formalizados.
   .mui-page pinta el fondo y estira a 100svh (flex column: un footer con
   margin-block-start auto cae al pie solo). El ancho lo pone
   .mui-container (la parcela de 72rem); el ritmo vertical, .mui-section
   (respiro clamp + costura border-subtle entre hermanas — regla 1:
   estructura por bordes, nunca sombras). Las secciones van full-bleed
   hijas de .mui-page y el container vive ADENTRO de cada una. */
.mui-page {
  display: flex; flex-direction: column;
  min-height: 100svh;
  background: var(--bg); color: var(--text);
  font-family: var(--font-display);
  font-size: var(--text-base); line-height: var(--leading-normal);
  /* el fundido del flip de tema — idioma exacto del body de la landing */
  transition:
    background-color var(--dur-moderate) var(--ease-settle),
    color            var(--dur-moderate) var(--ease-settle);
}

/* container — la parcela centrada: 72rem, padding-inline fluido */
.mui-container {
  width: 100%;
  max-width: 72rem;
  margin-inline: auto;
  padding-inline: clamp(var(--space-5), 4vw, var(--space-8));
}
.mui-container--narrow { max-width: 48rem; } /* prosa: ~65ch a text-base */
.mui-container--wide   { max-width: 90rem; } /* la parcela ancha de mui-docs */

/* section — respiro fluido; la costura entre hermanas es un borde sutil */
.mui-section { padding-block: clamp(var(--space-16), 10vw, var(--space-24)); }
.mui-section + .mui-section { border-block-start: 1px solid var(--border-subtle); }
.mui-section--tight { padding-block: clamp(var(--space-10), 6vw, var(--space-16)); }
.mui-section--flush { padding-block: var(--space-0); }

/* kicker — mono 2xs uppercase olivo: la voz de la máquina que abre cada
   sección. La MISMA voz sirve al hero (selector agrupado: cero drift). */
.mui-section__kicker,
.mui-hero__kicker {
  margin: 0;
  font-family: var(--font-mono); font-size: var(--text-2xs);
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
  color: var(--secondary-text);
}

/* título de sección — el h2 de la landing; balance evita viudas. La MISMA
   voz sirve al cierre (.mui-cta-band__title, selector agrupado). */
.mui-section__title,
.mui-cta-band__title {
  margin: var(--space-2) 0 var(--space-3);
  font-size: clamp(var(--text-2xl), 4vw, var(--text-4xl));
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-snug);
  text-wrap: balance;
}

/* lede — el párrafo que abre la sección; 62ch de medida cómoda */
.mui-section__lede {
  margin: 0;
  color: var(--text-secondary);
  max-width: 62ch;
}

/* ---------- Hero · .mui-hero ----------
   El momento firma: dos columnas asimétricas (el texto manda, el media
   acompaña) que se apilan ≤880px. Compone .mui-btn en __cta y .mui-badge
   en __meta — no los redeclara. Vive dentro de .mui-section +
   .mui-container (--flush si el hero administra su propio respiro).
   El primer hijo es el bloque de texto (un <div> anónimo); el segundo,
   .mui-hero__media. */
.mui-hero {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(var(--space-8), 6vw, var(--space-16));
  align-items: center;
}

/* título — el clamp grande de la casa; tracking-display, como el wordmark */
.mui-hero__title {
  margin: 0;
  font-size: clamp(var(--text-3xl), 6vw, var(--text-6xl));
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-display);
  line-height: var(--leading-tight);
  text-wrap: balance;
}
.mui-hero__kicker + .mui-hero__title { margin-block-start: var(--space-4); }

/* tagline — la línea mono bajo el título ("Siembra módulos, cosecha…") */
.mui-hero__tagline {
  margin: var(--space-5) 0 0;
  font-family: var(--font-mono);
  font-size: clamp(var(--text-sm), 2vw, var(--text-lg));
  color: var(--text-secondary);
}

/* sub — apoyo en voz baja; 46ch, más angosto que un lede */
.mui-hero__sub {
  margin: var(--space-4) 0 0;
  color: var(--text-muted);
  max-width: 46ch;
}

/* cta — botones compuestos (.mui-btn); UN primario por vista */
.mui-hero__cta {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-3);
  margin-block-start: var(--space-8);
}

/* meta — badges compuestos (.mui-badge): versión, licencia, estado */
.mui-hero__meta {
  display: flex; flex-wrap: wrap;
  gap: var(--space-2);
  margin-block-start: var(--space-5);
}

/* media — ilustración/captura; nunca revienta su columna */
.mui-hero__media { justify-self: center; }
.mui-hero__media img,
.mui-hero__media svg { display: block; max-width: 100%; height: auto; }

/* --center: una columna con todo centrado (lanzamientos, portadas cortas) */
.mui-hero--center {
  grid-template-columns: 1fr;
  text-align: center;
}
.mui-hero--center .mui-hero__title,
.mui-hero--center .mui-hero__sub { margin-inline: auto; }
.mui-hero--center .mui-hero__cta,
.mui-hero--center .mui-hero__meta { justify-content: center; }

/* responsive ≤880px — una columna (breakpoint compartido con docs/shell).
   El media queda DESPUÉS del texto; --media-first lo sube (order -1):
   variante de LAYOUT documentada, como la M de granos en la landing móvil. */
@media (max-width: 880px) {
  .mui-hero { grid-template-columns: 1fr; gap: var(--space-10); }
  .mui-hero--media-first .mui-hero__media { order: -1; }
}

/* ---------- Feature grid · .mui-feature-grid ----------
   Las tres hermanas formalizadas: grid fluido de cards silenciosas.
   El __item habla el idioma de .mui-card pero es pieza propia — sin
   fill, sin sombra: borde border-subtle + radius-lg sobre var(--bg).
   Interactivo SOLO como <a> completo (hover afirma el boundary,
   precedente .mui-docs__pager-link). */
.mui-feature-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: var(--space-4);
  margin-block-start: var(--space-10);
}

.mui-feature-grid__item {
  display: block;
  padding: var(--space-6);
  background: transparent;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  color: inherit;
  text-decoration: none;
}
/* interactiva solo como <a>: el hover afirma el boundary (border-strong
   ≥3 sobre --bg). El borde en reposo ya dibuja la card — sin hover
   (touch/reduced) no se pierde nada. */
a.mui-feature-grid__item {
  transition: border-color var(--dur-fast) var(--ease-standard);
}
a.mui-feature-grid__item:hover { border-color: var(--border-strong); }
a.mui-feature-grid__item:focus-visible {
  outline: 2px solid var(--focus); outline-offset: 2px;
}

/* icon — 2.25rem, olivo por defecto; --oro para la hermana núcleo */
.mui-feature-grid__icon {
  display: block;
  width: 2.25rem; height: 2.25rem;
  color: var(--secondary-text);
}
.mui-feature-grid__icon--oro { color: var(--accent-text); }

/* rol — "maíz · el núcleo": mono 2xs uppercase, la voz de la máquina */
.mui-feature-grid__rol {
  margin: var(--space-4) 0 0;
  font-family: var(--font-mono); font-size: var(--text-2xs);
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
}

.mui-feature-grid__title {
  margin: var(--space-1) 0 var(--space-2);
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  line-height: var(--leading-snug);
}

.mui-feature-grid__body {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--text-sm);
}

/* ---------- CTA band · .mui-cta-band ----------
   La franja de cierre: sube UN paso a var(--surface) y se marca con
   border-block sutil (regla 1 — nada de sombras). Centrada; compone
   .mui-btn en __actions. Va full-bleed, hermana de las .mui-section;
   el consumidor mete su .mui-container adentro. Sobre --surface leen
   text / text-secondary / accent-text (pares del gate).
   El __title comparte la voz de .mui-section__title (selector agrupado
   arriba, junto a Page). */
.mui-cta-band {
  padding-block: clamp(var(--space-12), 8vw, var(--space-20));
  background: var(--surface);
  border-block: 1px solid var(--border-subtle);
  text-align: center;
}

.mui-cta-band__sub {
  margin: 0 auto;
  color: var(--text-secondary);
  max-width: 52ch;
}

.mui-cta-band__actions {
  display: flex; flex-wrap: wrap;
  justify-content: center; align-items: center;
  gap: var(--space-3);
  margin-block-start: var(--space-8);
}

/* ════════════════════════════════════════════════════════════════════
   cluster · sections (pricing, faq, testimonial, footer)
   ════════════════════════════════════════════════════════════════════ */

/* ---------- Pricing · .mui-pricing ----------
   La feria de planes: grilla equal-height donde cada plan es una card
   silenciosa (precedente .mui-docs__pager-link — idioma de card sin
   redeclarar .mui-card) y el CTA ancla al fondo con margin auto. El
   plan destacado se marca con [data-featured] (hook de layout
   documentado): borde var(--accent) — la semántica "recomendado" la
   lleva el TEXTO del flag, que compone .mui-badge--accent. */
.mui-pricing {
  display: grid;
  /* min(16rem, 100%): bajo 16rem de lienzo la columna cede, no desborda */
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  gap: var(--space-4);
  align-items: stretch;
  margin-block-start: var(--space-10);
}

/* el plan — flex column: el CTA baja solo hasta el fondo */
.mui-pricing__plan {
  display: flex; flex-direction: column; gap: var(--space-1);
  padding: var(--space-6);
  background: var(--surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
}

/* destacado — borde oro (accent/surface ≥3, gateado); refuerzo
   decorativo: el significado va en el flag, nunca solo en el borde */
.mui-pricing__plan[data-featured] {
  position: relative;
  border-color: var(--accent);
}

/* flag "Recomendado" — compone .mui-badge mui-badge--accent, a caballo
   del borde superior; inset-inline + margin auto centra RTL-safe */
.mui-pricing__flag {
  position: absolute;
  top: 0; inset-inline: 0;
  width: fit-content; margin-inline: auto;
  transform: translateY(-50%);
}

.mui-pricing__name {
  margin: 0;
  font-family: var(--font-display); font-size: var(--text-lg);
  font-weight: var(--weight-medium); line-height: var(--leading-snug);
  color: var(--text);
}
.mui-pricing__desc {
  margin: 0;
  font-size: var(--text-sm); line-height: var(--leading-normal);
  color: var(--text-muted);
}

/* el precio — mono display: la cifra es el dato, el período la escolta */
.mui-pricing__price {
  margin-block: var(--space-4);
  font-family: var(--font-mono); font-size: var(--text-4xl);
  font-weight: var(--weight-bold); line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--text);
}
.mui-pricing__period {
  font-size: var(--text-sm); font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-normal);
  color: var(--text-muted);
}

/* features — checklist. Glifos con alt vacío (ornamento): la semántica
   incluido/no-incluido va en el texto (componer .mui-sr-only) */
.mui-pricing__features {
  display: flex; flex-direction: column; gap: var(--space-2);
  margin: 0; padding: 0; list-style: none;
}
.mui-pricing__features li {
  display: flex; align-items: baseline; gap: var(--space-2);
  font-size: var(--text-sm); line-height: var(--leading-normal);
  color: var(--text-secondary);
}
.mui-pricing__features li::before {
  content: "✓";
  content: "✓" / ""; /* alt vacío — patrón del cluster steps/file-tree */
  flex: none;
  font-weight: var(--weight-bold);
  color: var(--success);
}
/* feature ausente — [data-off]: glifo — y texto apagados */
.mui-pricing__features li[data-off] { color: var(--text-muted); }
.mui-pricing__features li[data-off]::before {
  content: "—";
  content: "—" / "";
  font-weight: var(--weight-regular);
  color: var(--text-muted);
}

/* CTA — wrapper que ancla abajo (margin auto en flex column); el
   .mui-btn compuesto se estira al ancho del plan (column stretch) */
.mui-pricing__cta {
  display: flex; flex-direction: column;
  margin-block-start: auto;
  padding-block-start: var(--space-6);
}

/* ---------- FAQ · .mui-faq ----------
   Preguntas frecuentes con <details>/<summary> nativos: el estado es
   [open] y el plegado lo trae gratis la plataforma — cero JS. Filas
   separadas por hairlines: la definición la dan los bordes (regla 1).
   Vive sobre var(--bg) o var(--surface) — mismos pares del gate. */
.mui-faq {
  width: 100%;
  max-width: 48rem;
}
.mui-faq__item { border-top: 1px solid var(--border-subtle); }
.mui-faq__item:last-child { border-bottom: 1px solid var(--border-subtle); }

/* la pregunta — summary sin marcador del UA; chevron propio ::after */
.mui-faq__q {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-4);
  font-family: var(--font-display); font-size: var(--text-base);
  font-weight: var(--weight-medium); line-height: var(--leading-snug);
  color: var(--text);
  cursor: pointer; list-style: none;
  -webkit-tap-highlight-color: transparent;
  transition: color var(--dur-fast) var(--ease-standard);
}
.mui-faq__q::-webkit-details-marker { display: none; }
.mui-faq__q:hover { color: var(--accent-text); }
.mui-faq__q:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* chevron — dibujado con bordes, hereda currentColor; rota 180°
   (45°→225°) al abrir. Reduced-motion lo deja congelado en 1 frame:
   OK — el estado lo cuenta la respuesta visible, no la flecha. */
.mui-faq__q::after {
  content: "";
  flex: none;
  width: 0.5em; height: 0.5em;
  border-inline-end: 2px solid currentColor;
  border-block-end: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform var(--dur-fast) var(--ease-standard);
}
.mui-faq__item[open] > .mui-faq__q::after { transform: rotate(225deg); }

/* la respuesta — prosa contenida a 62ch; aparece sin animar (1 frame:
   idéntico bajo reduced-motion, nada que neutralizar) */
.mui-faq__a {
  margin: 0;
  max-width: 62ch;
  padding-block: 0 var(--space-4);
  line-height: var(--leading-relaxed);
  color: var(--text-secondary);
}
/* respuestas de varios párrafos (__a como <div> con <p> adentro) */
.mui-faq__a p { margin-block: 0 var(--space-3); }
.mui-faq__a p:last-child { margin-block-end: 0; }

/* ---------- Testimonial · .mui-testimonial ----------
   Coro de voces: grilla de cards sutiles; cada item ENVUELVE un
   blockquote.mui-quote (cluster content de artifacts) sin
   redeclararlo — acá solo viven la parcela, la card y los seams. */
.mui-testimonial {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
  gap: var(--space-4);
  margin-block-start: var(--space-10);
}
.mui-testimonial__item {
  display: flex; flex-direction: column;
  padding: var(--space-6);
  background: var(--surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
}
/* seams: el quote llena la card y su atribución asienta al fondo
   (equal-height entre vecinos); la variante --pull pierde barra y
   sangría — el marco de la card ya define (regla 1, sin doble borde) */
.mui-testimonial__item > .mui-quote { flex: 1 1 auto; }
.mui-testimonial__item .mui-quote__attr { margin-block-start: auto; }
.mui-testimonial__item > .mui-quote--pull {
  border-inline-start: 0;
  padding-inline-start: 0;
}

/* ---------- Footer · .mui-footer ----------
   El mega footer — la línea de tierra que cierra la página.
   margin-block-start auto lo empuja al fondo cuando el wrapper
   (.mui-page o el body) es flex column con min-height 100dvh.
   La grilla: tracks auto-fit de 9rem y la marca ocupa 2 — el spec
   de grid no admite fr junto a repeat(auto-fit) en una misma lista
   de tracks, así que "brand 2fr" se logra con grid-column: span 2
   (mismo resultado: la marca = dos columnas de links). */
.mui-footer {
  --_max-w: 90rem;
  --_pad-inline: clamp(var(--space-4), 3vw, var(--space-8));
  margin-block-start: auto;
  padding-block: var(--space-16) var(--space-10);
  padding-inline: var(--_pad-inline);
  font-family: var(--font-display);
  background: var(--bg);
  border-top: 1px solid var(--border-subtle);
}

.mui-footer__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: var(--space-8);
  max-width: var(--_max-w);
  margin-inline: auto;
}

/* brand — wordmark (slot svg) + mantra; doble de ancho que cada columna */
.mui-footer__brand {
  grid-column: span 2;
  display: flex; flex-direction: column; align-items: flex-start;
  gap: var(--space-3);
}
.mui-footer__mantra {
  margin: 0;
  font-family: var(--font-mono); font-size: var(--text-2xs);
  line-height: var(--leading-normal);
  color: var(--text-muted);
}

/* rótulo de columna — la voz de .mui-docs__nav-heading */
.mui-footer__heading {
  margin: 0; margin-block-end: var(--space-3);
  font-family: var(--font-mono); font-size: var(--text-2xs);
  font-weight: var(--weight-regular);
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
  color: var(--text-muted);
}

/* links — silenciosos en reposo; el hover nunca es solo color: sube a
   var(--text) Y aparece el subrayado (ambos pares ≥4.5 sobre --bg) */
.mui-footer__links {
  margin: 0; padding: 0; list-style: none;
}
.mui-footer__links li { margin-block: var(--space-2); }
.mui-footer__links a,
.mui-footer__legal a {
  color: var(--text-muted);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-standard);
}
.mui-footer__links a { font-size: var(--text-sm); }
.mui-footer__links a:hover,
.mui-footer__legal a:hover { color: var(--text); text-decoration: underline; }
.mui-footer__links a:focus-visible,
.mui-footer__legal a:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* legal — hairline + fila que envuelve: © a un lado, meta al otro */
.mui-footer__legal {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
  max-width: var(--_max-w);
  margin-inline: auto;
  margin-block-start: var(--space-10);
  padding-block-start: var(--space-6);
  border-top: 1px solid var(--border-subtle);
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.mui-footer__legal p { margin: 0; }

/* ≤880px — una columna: la marca arriba, columnas apiladas (mismo
   breakpoint que el drawer de mui-docs) */
@media (max-width: 880px) {
  .mui-footer__grid { grid-template-columns: 1fr; }
  .mui-footer__brand { grid-column: auto; }
}

/* ════════════════════════════════════════════════════════════════════
   cluster · media
   ════════════════════════════════════════════════════════════════════ */
/* ---------- Media Grid · .mui-media-grid ----------
   La parcela de imágenes: grid uniforme auto-fill (celdas 4/3, --square
   1/1) o masonry por columnas (variante). Cada item es un <a> o <button>
   envolvente (idioma de .mui-card--interactive) que puede abrir el
   lightbox. La caption es un velo inferior SIEMPRE visible — regla
   touch/reduced-motion: nada de opacity 0→1 en hover; el hover solo
   intensifica el velo, y el zoom de la imagen es decorativo (bajo
   reduce el contrato global lo congela y no se pierde nada). */
.mui-media-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  gap: var(--space-3);
}
/* guard: el display de arriba pisaría el [hidden] del UA (precedente .mui-alert) */
.mui-media-grid[hidden] { display: none; }
.mui-media-grid__item[hidden] { display: none; } /* mismo guard para la pieza (filtros) */

/* item — <a> o <button> envolvente; el reset sigue a .mui-card--interactive */
.mui-media-grid__item {
  position: relative; display: block;
  width: 100%; padding: 0;                /* reset de <button> */
  font: inherit; text-align: start;
  text-decoration: none; cursor: pointer; /* reset de <a> */
  -webkit-tap-highlight-color: transparent;
  aspect-ratio: 4 / 3;
  color: var(--text);
  background: var(--surface);             /* suelo mientras carga la imagen */
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: border-color var(--dur-fast) var(--ease-standard);
}
/* el hover nunca depende solo del borde: lo acompañan el zoom y el velo */
.mui-media-grid__item:hover { border-color: var(--border); }
/* el outline se dibuja FUERA de la caja: el overflow:hidden no lo recorta */
.mui-media-grid__item:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* el puente que llena la celda — <figure> en el camino <a>; en el camino
   <button> el content model (solo phrasing) prohíbe <figure>: ahí el
   puente es span.mui-media-grid__figure (mismo contrato, ver a11y) */
.mui-media-grid__item figure,
.mui-media-grid__item .mui-media-grid__figure {
  display: block; margin: 0; height: 100%;
}
.mui-media-grid__item :is(img, svg, picture) {
  display: block; width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--dur-moderate) var(--ease-settle);
}
/* zoom sutil — decorativo: bajo reduced-motion queda congelado en 1 frame */
.mui-media-grid__item:hover :is(img, svg, picture) { transform: scale(1.03); }

/* caption — velo inferior SIEMPRE visible (color-mix + blur, idioma del
   topbar de docs): el texto lee sobre --bg efectivo (par text/bg del
   gate). En hover el velo solo gana densidad — nunca aparece/desaparece:
   touch y reduced-motion ven lo mismo, quieto. */
.mui-media-grid__caption {
  position: absolute; inset-inline: 0; inset-block-end: 0;
  margin: 0;             /* reset de <figcaption>; inocuo en el span del camino <button> */
  padding: var(--space-3);
  font-family: var(--font-display); font-size: var(--text-sm);
  line-height: var(--leading-snug);
  color: var(--text);
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  transition: background-color var(--dur-fast) var(--ease-standard);
}
.mui-media-grid__item:hover .mui-media-grid__caption {
  background: color-mix(in srgb, var(--bg) 88%, transparent);
}

/* square — celdas cuadradas (catálogo, avatares) */
.mui-media-grid--square .mui-media-grid__item { aspect-ratio: 1 / 1; }

/* masonry — columnas CSS: cada pieza conserva su proporción natural.
   El ritmo vertical lo pone el margin del item (las columnas no conocen
   el gap del grid); --_cols es override documentado del consumidor. */
.mui-media-grid--masonry {
  --_cols: 3;
  display: block;
  columns: var(--_cols);
  column-gap: var(--space-3);
}
.mui-media-grid--masonry .mui-media-grid__item {
  aspect-ratio: auto;
  break-inside: avoid;
  margin-block-end: var(--space-3);
}
.mui-media-grid--masonry .mui-media-grid__item :is(img, svg, picture) { height: auto; }

@media (max-width: 880px) { .mui-media-grid--masonry { --_cols: 2; } }
@media (max-width: 560px) { .mui-media-grid--masonry { --_cols: 1; } }

/* ---------- Lightbox · dialog.mui-lightbox ----------
   Visor de media a pantalla: se aplica JUNTO a .mui-modal
   (<dialog class="mui-modal mui-lightbox">) — hereda el contrato nativo
   (top layer, focus trap del UA, Esc) y el ::backdrop SIN redeclararlos;
   la capa layouts gana la cascada. Acá solo se desnuda el marco: la
   media ES la superficie — radio y sombra viven en ella. La entrada
   milpa-scale-in se MUDA del dialog a la media: un dialog con transform
   es containing block de sus fixed, y al asentar el keyframe en
   transform:none counter/nav/close brincarían del borde del dialog a
   las esquinas reales del viewport — con el dialog quieto nacen
   clavados. Todo texto/control flota sobre el scrim traslúcido (debajo
   puede haber cualquier cosa): por eso llevan chip SÓLIDO
   var(--overlay) — pares del gate, no composites. Sin --z-*: el top
   layer del dialog ya vive encima de toda la escala. */
.mui-lightbox {
  width: fit-content;
  max-width: min(92vw, 70rem);
  max-height: 92vh;
  padding: 0;
  background: transparent;
  border: none;
  box-shadow: none;
}

/* entrada — el dialog NO se anima (neutraliza el milpa-scale-in del
   modal): mientras el keyframe porta transform, el dialog es containing
   block de los controles fixed y al terminar saltarían de golpe. La
   misma entrada vive en la media; counter/nav/close acompañan con el
   fade del backdrop (mismo pulso) — bajo reduce todo cae a 1 frame. */
.mui-lightbox[open] { animation: none; }
.mui-lightbox[open] .mui-lightbox__media {
  animation: milpa-scale-in var(--dur-moderate) var(--ease-grano) both;
}
.mui-lightbox[open] .mui-lightbox__counter,
.mui-lightbox[open] .mui-lightbox__nav,
.mui-lightbox[open] .mui-lightbox__close {
  animation: milpa-fade var(--dur-moderate) var(--ease-standard) both;
}

/* media — la figura protagonista: el marco (radio + sombra) es suyo */
.mui-lightbox__media { margin: 0; min-height: 0; }
.mui-lightbox__media :is(img, svg, picture),
.mui-lightbox__media video {
  display: block;
  max-width: 100%;
  max-height: 80vh;
  margin-inline: auto;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
}

/* caption — chip centrado con fondo sólido: sobre el scrim el composite
   no es par gateable; text-secondary sobre var(--overlay) sí (4.5) */
.mui-lightbox__caption {
  width: fit-content; max-width: 100%;
  margin-block-start: var(--space-3); margin-inline: auto;
  padding: var(--space-1_5) var(--space-3);
  font-family: var(--font-display); font-size: var(--text-sm);
  line-height: var(--leading-snug); text-align: center;
  color: var(--text-secondary);
  background: var(--overlay);
  border-radius: var(--radius-sm);
}

/* counter — "3 / 12": mono, mismo chip overlay, anclado al arranque */
.mui-lightbox__counter {
  position: fixed;
  inset-block-start: var(--space-4); inset-inline-start: var(--space-4);
  padding: var(--space-1) var(--space-2);
  font-family: var(--font-mono); font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  color: var(--text-secondary);
  background: var(--overlay);
  border-radius: var(--radius-sm);
}

/* nav — banda fixed a lo ancho del viewport: prev a un lado, next al
   otro, centrados en el eje de bloque SIN transform (el hover del
   .mui-btn ya usa translateY y chocaría). pointer-events:none deja
   pasar el click al backdrop (light-dismiss del consumidor); cada botón
   VIVO lo reactiva — el guard :not() preserva el pointer-events:none
   que primitives da a [disabled]/[aria-disabled]/[aria-busy] (esta capa
   gana la cascada: sin guard, el botón muerto recuperaría hover y
   bloquearía el click que debe caer al backdrop). */
.mui-lightbox__nav {
  position: fixed; inset-inline: 0; inset-block: 0;
  display: flex; align-items: center; justify-content: space-between;
  padding-inline: var(--space-4);
  pointer-events: none;
}
.mui-lightbox__nav .mui-btn:not([disabled], [aria-disabled="true"], [aria-busy="true"]) {
  pointer-events: auto;
}

/* close — el botón compuesto (.mui-btn mui-btn--icon), arriba al final */
.mui-lightbox__close {
  position: fixed;
  inset-block-start: var(--space-4); inset-inline-end: var(--space-4);
}

/* los controles compuestos ganan chip sólido: flotan sobre scrim y
   fotos — el fill var(--overlay) asegura los pares del gate
   (text-secondary reposo / text hover, ambos 4.5). El borde
   var(--border) es decorativo: la definición la dan fill + sombra
   (idioma exacto del toast). */
.mui-lightbox__nav .mui-btn,
.mui-lightbox__close {
  background: var(--overlay);
  border-color: var(--border);
  box-shadow: var(--shadow-base);
}

/* focus de los chips — con el offset estándar (+2px) el anillo caería
   sobre el scrim compuesto (no gateable: ver notes del cluster);
   precedente del drawer: offset negativo y el anillo vive íntegro
   sobre el fill var(--overlay) (focus/overlay ≥3, par del gate). */
.mui-lightbox__nav .mui-btn:focus-visible,
.mui-lightbox__close:focus-visible { outline-offset: -2px; }

/* <560px — prev/next dejan los lados y pasan a fila centrada bajo la
   media (el dialog ya es flex column vía .mui-modal[open]) */
@media (max-width: 560px) {
  .mui-lightbox__nav {
    position: static;
    justify-content: center; gap: var(--space-3);
    margin-block-start: var(--space-3);
    padding-inline: 0;
  }
}

/* ════════════════════════════════════════════════════════════════════
   cluster · header  (la plaza — el header público / marketing)
   Tercer header del sistema, distinto de mui-topbar (admin) y
   mui-docs__topbar (docs). Barra sólida sticky + off-canvas móvil
   (patrón EXACTO del shell docs: [data-nav-open] en el root, aria-expanded
   en el toggle) + variante overlay sobre hero.
   ════════════════════════════════════════════════════════════════════ */
.mui-header {
  position: sticky; top: 0; z-index: var(--z-sticky);
  background: color-mix(in srgb, var(--bg) 85%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-block-end: 1px solid var(--border-subtle);
}
.mui-header__row {
  display: flex; align-items: center; gap: var(--space-4);
  min-height: 3.5rem;
}
.mui-header__brand {
  display: inline-flex; align-items: center; gap: var(--space-2);
  color: var(--text); text-decoration: none;
}
.mui-header__brand:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.mui-header__nav {
  margin-inline-start: auto;
  display: flex; align-items: center; gap: var(--space-1);
}
.mui-header__actions {
  display: flex; align-items: center; gap: var(--space-2);
}
.mui-header__toggle { display: none; }
.mui-header__scrim { display: none; }

/* overlay — transparente sobre el hero; se solidifica con [data-scrolled] */
.mui-header--overlay {
  background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none;
  border-block-end-color: transparent;
  transition:
    background var(--dur-moderate) var(--ease-standard),
    border-color var(--dur-moderate) var(--ease-standard);
  /* reduce → dur colapsa a 1 frame por el contrato global */
}
.mui-header--overlay[data-scrolled] {
  background: color-mix(in srgb, var(--bg) 85%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-block-end-color: var(--border-subtle);
}

/* ---------- responsive ≤880px: nav → drawer off-canvas ----------
   Mismo mecanismo que mui-docs: cerrado = fuera del lienzo y fuera del
   árbol de a11y (visibility flipa al terminar el slide-out). El hook de
   layout es [data-nav-open] en .mui-header; la semántica la lleva
   aria-expanded en el toggle. El JS del consumidor alterna inert. */
@media (max-width: 880px) {
  .mui-header__toggle { display: inline-flex; margin-inline-start: auto; }
  .mui-header__nav {
    position: fixed; inset-block: 0; inset-inline-end: 0;
    width: 16rem; margin-inline-start: 0;
    flex-direction: column; align-items: stretch; gap: var(--space-1);
    padding: calc(3.5rem + var(--space-3)) var(--space-3) var(--space-4);
    background: var(--bg);
    border-inline-start: 1px solid var(--border-subtle);
    z-index: var(--z-drawer);
    transform: translateX(100%);
    visibility: hidden;
    transition:
      transform  var(--dur-moderate) var(--ease-grano),
      visibility var(--dur-instant) var(--ease-linear) var(--dur-moderate);
  }
  .mui-header[data-nav-open] .mui-header__nav {
    transform: none; visibility: visible; box-shadow: var(--shadow-md);
    transition:
      transform  var(--dur-moderate) var(--ease-grano),
      visibility var(--dur-instant);
  }
  .mui-header[data-nav-open] .mui-header__scrim {
    display: block;
    position: fixed; inset: 0;
    z-index: var(--z-backdrop);
    background: color-mix(in srgb, var(--bg) 55%, transparent);
    animation: milpa-fade var(--dur-moderate) var(--ease-standard) both;
  }
}

} /* @layer milpa.layouts */
