Lo que resuelve «¿dónde va cada cosa?». La app llena RANURAS y el paquete decide dónde aterriza cada una — no hay prop para mover el menú de usuario a la izquierda, así que no se puede equivocar.
AppShell emite <header>, <nav> y <main>, y esta página ya vive dentro de los tres. Montarlo aquí anidaría los landmarks — un <main> dentro de otro es marcado inválido — landmarks anidados es justo el defecto que este chasis existe para evitar. La demo lo produciría en vez de prevenirlo.
📏 Dónde se mira de verdad: en cualquier pantalla de una app que lo haya adoptado — ahí el catálogo se abre dentro del chasis, y esa es su prueba de fuego. Lo que falta es poder tocarlo aquí, y eso queda listado como hueco en la portada — a propósito.
La app llena ranuras; el paquete decide dónde aterriza cada una. No hay prop para mover el menú de usuario a la izquierda, así que no se puede equivocar. Lo que antes era una convención escrita en un documento es ahora la firma de una función.
brandCabecera · extremo de iniciobreadcrumbCabecera · pegada a la marcanavRiel, al lado del contenidosearchCabecera · extremo finalactionsCabecera · extremo finaluserCabecera · arriba a la derecha, SIEMPRE de últimolabels—collapsed + onCollapsedChange—El título de la pantalla y sus acciones. Emite un <h1> y el nivel NO es prop: el chasis no emite ningún encabezado —medido: cero en los cuatro archivos de src/shell/—, así que hoy una pantalla puede no tener ninguno, y quien navega por encabezados aterriza sin punto de partida. Si el nivel fuera configurable, la primera pantalla copiada de otra traería el nivel de su vecina.
Los que tienen al menos un contrato activo. La descripción va atada al título con aria-describedby, no suelta a su lado.
📏 Estrecha la ventana por debajo de 768 px: las acciones se apilan y pasan a ancho completo. El corte es la variante mobile: de la casa, y su número lo lee también el JavaScript del chasis — por eso no se escribe sm: aquí.
⚠️ Hueco declarado: nada impide todavía montar dos PageHeader en la misma ruta ni escribir un <h1> a mano al lado. Eso es trabajo de la compuerta de conformidad, no del componente, y no está escrito.
La pantalla de elegir empresa, antes de entrar al portal. El nombre es prestado y la pieza es nuestra: ningún sistema de diseño envía esto — ni Carbon, ni Primer, ni Polaris, ni el catálogo público de Atlassian. Donde existe es como flujo de identidad, y Auth0 lo bautiza así: “Users in multiple Organizations are directed to the Organization Picker after the login flow”. De ahí sale el nombre, y nada más — el diseño de abajo es de esta casa.
Elige la empresa con la que quieres trabajar:
Todavía no has elegido ninguna.
🔴 Prueba la última fila con el teclado. «Agropecuaria Los Santos» no se puede elegir, y aun así recibe el foco y dice por qué. Lo que reemplaza es un <div aria-disabled> con opacity-50: no era enfocable —o sea, invisible para quien navega con teclado o lector—, el aria-disabled no significaba nada sobre un div, y la opacidad apagaba justo el texto que explica el motivo, que es la única señal que no es color (SC 1.4.1).
📏 El filtro aparece a partir de 6 empresas — es el umbral que ya usaba la app real, no un número inventado. Y el componente no sabe de HTTP: recibe un state ya interpretado. La razón está pagada: el 2026-07-31 el servicio de permisos respondió 500, la lista llegó vacía y la pantalla culpó a la cuenta de quien sí tenía acceso. Por eso empty es una ranura obligatoria y aparte.