/* Portal B2B lejan™ — sistema de diseño "Premium editorial".
   Lienzo crema cálido, verde profundo de marca + terracota de acento, display
   serif (Fraunces) sobre cuerpo Inter, tablas silenciosas y layout contenido.
   Rediseño 2026-08 (ver tag v1-paridad-lejan para el estado de paridad con lejan). */

:root {
  /* ── Rediseño "Modernist" (handoff 2026-08): Archivo, acento ROJO único,
        radio 0 en todo, reglas divisorias fuertes, fondo gris claro, tinta casi
        negra. Se conservan los nombres de token (--blue*, --accent*, --r…) para
        que las 100+ reglas existentes tomen los valores nuevos sin reescribirse. */
  /* ── Marca configurable (tokens de /api/portal/branding, ver js/branding.js) ──
     Cada token llega como variable --brand-* en el style inline de <html>; aquí solo
     se lee con var(--token, <valor de MITO>). SIN tokens el valor por defecto es el de
     siempre, así que el portal de MITO PROJECTS no cambia ni un píxel. */
  --ink:var(--brand-ink,#201e1d); --ink-2:#605d5d; --ink-3:#7d7979;
  --paper:var(--brand-paper,#f3f2f2); --surface:var(--brand-surface,#eae9e9);
  /* --line se queda como literal A PROPÓSITO: son 69 hilos de 1px casi invisibles donde la
     temperatura del gris no se nota, y abrirlo a un token invita a ponerlos en rojo, lo
     que dejaría ilegible la retícula de GESTIÓN (/manage carga este mismo app.css). */
  --card:var(--brand-card,#f8f4f4); --line:#d3cfcf;
  --gutter:clamp(1.25rem, 5vw, 4rem); --maxw:1240px;
  /* Ancho AMPLIO para superficies de rejilla (catálogo): casi a sangre en pantallas
     grandes, con solo --gutter de canal lateral. Cap alto para no volverse absurdo en
     monitores 4K. Las páginas de LECTURA siguen usando --maxw (1240). */
  --maxw-wide:2400px;
  /* ══ SISTEMA DE ANCHOS DEL PORTAL ═══════════════════════════════════════════
     Hasta aquí había UN ancho (--maxw, 1240) y dos fugas sueltas (catálogo y
     portada). Con eso, en un monitor de 2560 la tabla de Pedidos se leía en una
     franja central con 660 px de desierto a cada lado, y en uno de 3440, con
     1100. El ancho no es una propiedad de cada pantalla: es una propiedad de lo
     que la pantalla ENSEÑA. Tres familias, tres topes, y cada vista se adscribe a
     una — nunca una excepción suelta con su número a mano.

     1) LECTURA Y FORMULARIO (--w-read, 1240): perfil, empresa, contacto, alta de
        cliente, pago. Una línea de texto de 2000 px no se lee y un formulario
        estirado obliga a barrer la cabeza de un lado a otro para emparejar rótulo
        y campo. Aquí ANCHO NO ES MEJOR: se queda como está.
     2) REJILLA DE DATOS (--w-grid, 2000): pedidos, albaranes, facturas, SAT,
        clientes, solicitudes, selecciones, análisis, estadísticas, previsión,
        carritos, tableros y TRAMITACIÓN. Son tablas y cuadrículas de 8-12
        columnas: el ancho es literalmente información que hoy no se ve. Se para
        en 2000 porque un renglón de tabla más largo que eso ya no se sigue con la
        vista: pegar la tabla al canto es tan malo como encajonarla.
        La tramitación empezó en la familia 1 y cambió de sitio a propósito: desde
        que cada artículo del pedido se corrige con SU matriz de tallas entera, lo
        que se pinta ya no es un formulario de seis campos, sino una cuadrícula de
        cantidades por talla junto al resumen. A 2000 px vivía en una banda central
        con medio monitor en blanco a los lados y el campo «Entregas» partido en
        ocho renglones. Lo que sí sigue siendo lectura dentro de ella (las notas,
        la dirección) se frena por dentro, en su propia regla.
     3) EDITORIAL (--w-bleed, 2400): portada, lookbook, catálogo y ficha de
        producto. Mandan la imagen y el ritmo, no el renglón, así que van casi a
        sangre y solo se frenan para que un 4K no pinte una fila de 30 prendas.

     El canal lateral NUNCA baja del margen del cromo (--rail-min, el mismo
     clamp de #chrome-nav): así el contenido de cualquier familia arranca a plomo
     con el logo, y en móvil las tres se comportan igual. */
  --rail-min:clamp(1rem, 4vw, 2.4rem);
  --w-read:var(--maxw);
  --w-grid:2000px;
  --w-bleed:var(--maxw-wide);
  /* El 100 % de estas dos se resuelve contra el contenedor donde se USAN
     (sustitución diferida de las custom properties): por eso valen como margen
     fluido y no hay que repetir la media query en cada familia. */
  --rail-grid:max(var(--rail-min), calc((100% - var(--w-grid)) / 2));
  --rail-x:max(var(--rail-min), calc((100% - var(--w-bleed)) / 2));
  /* Medida de LECTURA dentro de una superficie ancha: cuando lo que se pinta es una
     fila de texto (el Listado del catálogo) el ancho no puede ser el del raíl, porque
     un renglón de 2400px no se lee. 96rem es el valor que ya fijaba el informe de marca. */
  --read-w:96rem;

  /* ── CONTROLES DE FORMULARIO (desplegable · fecha · texto · grupo de botones) ──
     Un único alto y un único filete para los cuatro, para que una fila mezclada
     (Origen + Fecha de inicio + Fecha de fin + «Últimos 12 meses») quede a plomo.
     Antes no lo estaba: el envoltorio .tb-select medía 43px y los botones de
     .tb-seg 39px, y esos 4px de escalón son la mitad de la sensación de «crudo»
     que se ve en Análisis y en Estadísticas. */
  --ctl-h:2.6rem;
  --ctl-pad-x:.72rem;
  --ctl-bg:#fff;
  --ctl-line:var(--line-control);
  /* --muted a #6a6666: el #7d7979 original daba 3,85:1 sobre --paper
     (#f3f2f2), por debajo de AA. #6a6666 llega a ~5,1:1 sin dejar de leerse como
     "texto secundario" (oscurecido sutil, misma temperatura). */
  --muted:#6a6666; --muted-2:#9b9797; --line-control:#bab6b6;
  /* Texto de AYUDA (hints, crumbs, labels de simulador): --hint sigue un punto
     más oscuro (~5,8:1) que --muted para las piezas más pequeñas. */
  --hint:#5f5b5b;
  /* --blue* = ahora el ROJO de marca (acento único). Rojo a tamaño de párrafo
     usa --accent-deep (#c94b39 ≈ accent-700), no el base, por contraste. */
  --blue:#ec3013; --blue-deep:#dd2b0f; --blue-soft:#ffe0d9;
  /* Rojo para TEXTO PEQUENO (pestanas activas, recuentos, lookups): #b8230c da >=4,5:1
     sobre --paper; --blue-deep se queda para fondos y texto grande (D-M7). */
  --blue-text:#b8230c;
  /* Rojo para texto pequeño SOBRE SU PROPIO TINTE (--blue-soft: píldora de unidades, tag de
     panel). --blue-deep (#dd2b0f) es un oscurecido fijo del 10 % que sobre #ffe0d9 se queda
     en 3,8:1; #ae1800 da 5,8:1. branding.js lo deriva midiendo contra el tinte cuando la
     marca tiene otro color (una marca negra sigue dando negro). */
  --blue-soft-text:#ae1800;
  --accent:#e15b47; --accent-deep:#ae1800; --accent-soft:#fff2ef;
  --ok:#1f7a45; --low:#b07d18; --out:#ec3013;
  --r:0px; --r-sm:0px;
  /* Filete de CAPÍTULO (los 2px que abren cada bloque: cabecera de tabla, KPI, precio,
     resumen del pedido…; NO los hilos de --line): color y grosor de marca. Sin tokens
     resuelve a «2px solid var(--ink)», que es exactamente lo de hoy. Los sitios cuyo
     filete iba en gris (--line / --line-control) conservan ese gris como respaldo. */
  --rule:var(--brand-rule,var(--ink)); --rule-w:var(--brand-rule-w,2px);
  --shadow:0 1px 2px color-mix(in srgb,#2d2b2b 14%,transparent);
  --shadow-card:0 3px 10px color-mix(in srgb,#2d2b2b 16%,transparent);
  --ease:cubic-bezier(.16,1,.3,1);
  --header-h:66px;
  /* Cabecera NEGRA modernist con tinta clara. --header-bg/--header-ink son tokens de
     marca: branding.js los pisa en el style inline de <html> cuando la instancia los
     configura. --header-ink-2 y --header-veil (velos, filetes y focos de la cabecera)
     salen de la tinta, para que sigan viéndose si la cabecera pasa a ser clara. */
  --header-bg:#201e1d; --header-ink:#f3f2f2;
  --header-ink-2:color-mix(in srgb, var(--header-ink) 62%, transparent);
  --header-veil:#fff;
  /* Titulares: la familia de display si la instancia la configura (fontFamilyDisplay), si no
     la de texto (fontFamily) y si no Archivo: sin tokens, exactamente lo de siempre. */
  --display:var(--brand-display-font,var(--brand-font,"Archivo")), system-ui, -apple-system, sans-serif;
}

* { box-sizing:border-box; }
/* Barra de scroll (Windows/Firefox) en los grises del sistema: el #c9bfab era el beige de
   la paleta crema anterior y cualquier instancia lo heredaba aunque su papel fuera blanco. */
html { scrollbar-color:var(--line-control) var(--surface); }
body { margin:0; min-height:100vh; background:var(--paper); color:var(--ink);
  font:15px/1.55 var(--brand-font,"Archivo"),system-ui,sans-serif; font-variant-numeric:tabular-nums;
  -webkit-font-smoothing:antialiased; display:flex; flex-direction:column; }
::selection { background:var(--blue); color:#fff; }
:focus-visible { outline:2px solid var(--blue); outline-offset:2px; border-radius:0; }
button { font:inherit; cursor:pointer; border:none; background:none; padding:0; color:inherit; }
input, select, textarea { font:inherit; color:inherit; }
a { color:inherit; }
main { flex:1; outline:none; }
[hidden] { display:none !important; }

.skip { position:absolute; left:-9999px; top:0; background:var(--blue); color:#fff;
  padding:.6rem 1rem; z-index:100; }
.skip:focus { left:0; }

.brand { font-family:var(--display); font-weight:800;
  letter-spacing:var(--brand-tracking,-.03em); text-transform:var(--brand-caps,none); }
.brand sup { font-size:.42em; letter-spacing:0; vertical-align:.95em; }
/* Marca configurable: si el despliegue sube logo, sustituye al texto en .brand */
.brand img { display:block; height:28px; width:auto; max-width:220px; object-fit:contain; }
.sheet .card .brand img { margin:0 auto; height:34px; }
.login-hero .brand img, .cred-hero .brand img { height:34px; }

/* ══════════════ Header verde de marca ══════════════ */
#chrome-header { position:sticky; top:0; z-index:20; background:var(--header-bg); color:var(--header-ink);
  display:flex; align-items:center; gap:1.1rem; padding:0 clamp(1rem,4vw,2.4rem); height:var(--header-h);
  /* El COLOR toma el token del filete (rule); el grosor solo cambia con headerRuleWidth
     (--header-rule-w, la banda de marca de POLO CLUB): sin él, el hilo de 1px de siempre. */
  border-bottom:var(--header-rule-w,1px) solid var(--brand-rule,rgba(0,0,0,.14)); }
/* Wordmark serif en crema; el italic de Fraunces le da carácter editorial */
#chrome-header .brand { font-size:1.7rem; font-style:normal; color:var(--header-ink); text-decoration:none; line-height:1; }

/* Caja BLANCA sobre el header negro: es el elemento de mayor contraste de la
   franja superior en la referencia (01-dashboard.png), con la lupa a la derecha. */
.h-search { position:relative; width:min(20rem,32vw); }
.h-search input { width:100%; background:#fff; border:1px solid #d6d5d0; border-radius:var(--r-sm);
  padding:.62rem 2.6rem .62rem .85rem; color:var(--ink); transition:border-color .15s var(--ease); }
.h-search input::placeholder { color:var(--muted); opacity:1; }
.h-search input:focus { border-color:var(--blue); }
/* Sobre el header negro el azul de marca no contrasta: el foco se marca en blanco */
.h-search input:focus-visible, #chrome-header button:focus-visible, #chrome-header a:focus-visible {
  outline:2px solid var(--header-veil); outline-offset:2px; }
.h-search button { position:absolute; right:.4rem; top:50%; translate:0 -50%; padding:.35rem;
  color:var(--ink); border-radius:6px; display:grid; place-items:center; }
.h-search button:hover { color:var(--blue); }
/* La lupa vive DENTRO de la caja blanca: el anillo blanco del header sería
   invisible ahí, así que aquí se marca en azul (y con más peso que esa regla). */
#chrome-header .h-search button:focus-visible { outline:2px solid var(--blue); outline-offset:1px; }

#chrome-header .spacer { flex:1; }

.h-user { display:flex; align-items:center; gap:.6rem; position:relative; }
.h-user > button { display:flex; align-items:center; gap:.6rem; padding:.3rem .4rem; border-radius:var(--r-sm);
  transition:background .15s var(--ease); }
.h-user > button:hover { background:color-mix(in srgb, var(--header-veil) 12%, transparent); }
.avatar { width:2.1rem; height:2.1rem; border-radius:50%; background:var(--accent); color:#fff; flex:none;
  display:grid; place-items:center; font-weight:700; font-size:.85rem; text-transform:uppercase; }
.h-user .who { text-align:left; line-height:1.35; font-size:.8rem; }
.h-user .who .l1 { color:var(--header-ink); white-space:nowrap; }
.h-user .who .l2 { color:var(--header-ink-2); }

.h-menu { position:absolute; top:calc(100% + .6rem); right:0; min-width:15rem; background:#fff; color:var(--ink);
  border-radius:var(--r-sm); box-shadow:var(--shadow-card); padding:.4rem; z-index:30; }
.h-menu a, .h-menu button { display:block; width:100%; text-align:left; padding:.55rem .75rem; border-radius:6px;
  font-size:.88rem; text-decoration:none; transition:background .12s var(--ease); }
.h-menu a:hover, .h-menu button:hover { background:var(--surface); }
.h-menu hr { border:none; border-top:1px solid var(--line); margin:.35rem .3rem; }
.h-menu .out { color:var(--out); }
/* Idioma y vista sin distracciones solo cuelgan del menú cuando el header los oculta */
.h-menu .m-only { display:none; }
.h-menu .m-title { display:block; padding:.5rem .75rem .15rem; font-size:.72rem; font-weight:700;
  letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }

.h-icon { color:var(--header-ink); padding:.45rem; border-radius:var(--r-sm); display:grid; place-items:center;
  transition:background .15s var(--ease), color .15s var(--ease); }
.h-icon:hover { background:color-mix(in srgb, var(--header-veil) 12%, transparent); }
.h-icon[aria-pressed="true"] { background:var(--header-ink); color:var(--blue); }
#chrome-header .sep { width:1px; height:1.6rem; background:color-mix(in srgb, var(--header-veil) 22%, transparent); }

.h-lang { display:flex; align-items:center; gap:.35rem; border-radius:999px;
  border:1px solid color-mix(in srgb, var(--header-veil) 30%, transparent);
  padding:.45rem .6rem .45rem .8rem; font-size:.82rem; font-weight:600; color:var(--header-ink); text-transform:uppercase;
  transition:border-color .15s var(--ease), background .15s var(--ease); }
.h-lang:hover { border-color:var(--header-ink); background:color-mix(in srgb, var(--header-veil) 8%, transparent); }

/* Carrito: acento terracota, el único botón "acción" del header verde */
.h-cart { display:flex; align-items:center; gap:.55rem; background:var(--accent); color:#fff;
  border-radius:999px; padding:.68rem 1.25rem; font-weight:600; font-size:.83rem; letter-spacing:.02em;
  transition:background .15s var(--ease), transform .15s var(--ease); white-space:nowrap; }
.h-cart:hover { background:var(--accent-deep); transform:translateY(-1px); }

/* ══════════════ Barra de navegación ══════════════ */
/* El padding con max() alinea el contenido con la columna centrada de .page sin
   necesitar un wrapper (el nav pinta <a> directo desde chrome.js). */
/* El nav se alinea con el catálogo (superficie ancha): así las pestañas quedan bajo
   la cabecera negra sin el salto visual del contenido centrado a 1240. En páginas de
   lectura el nav queda algo más ancho que el texto, lo cual es habitual en app chrome. */
#chrome-nav { background:var(--card); border-bottom:1px solid var(--line);
  padding:0 max(clamp(1rem,4vw,2.4rem), calc((100% - var(--maxw-wide)) / 2)); }
#chrome-nav a { display:inline-block; padding:.95rem .2rem; margin-right:1.6rem; font-size:.9rem;
  letter-spacing:.01em; text-decoration:none; border-bottom:2px solid transparent; transition:border-color .15s var(--ease), color .15s var(--ease); }
#chrome-nav a:hover { border-bottom-color:var(--blue); color:var(--blue); }
/* La referencia no marca "Catálogo" como activo (m11): el estado sigue expuesto en
   aria-current, pero sin subrayado ni negrita. */

/* ══════════════ Footer ══════════════ */
/* Banda de tinta cálida con el bloque centrado — copyright + 5 iconos sociales. */
#chrome-footer { background:var(--header-bg); color:var(--header-ink); margin-top:4rem;
  display:flex; align-items:center; justify-content:center; gap:1.5rem; padding:1.8rem; flex-wrap:wrap; }
#chrome-footer > span:first-child { font-size:.82rem; letter-spacing:.05em; text-transform:uppercase; opacity:.9; }
#chrome-footer .social { display:flex; align-items:center; gap:.9rem; }
#chrome-footer .social a { padding:.25rem; border-radius:6px; color:var(--header-veil); opacity:.92;
  display:grid; place-items:center; transition:opacity .15s var(--ease), background .15s var(--ease); }
#chrome-footer .social a:hover { opacity:1; background-color:color-mix(in srgb, var(--header-veil) 16%, transparent); }
#chrome-footer .social a:focus-visible { outline:2px solid var(--header-veil); outline-offset:2px; }

/* ══════════════ Vistas con chrome ══════════════ */
/* La referencia va casi a sangre: ~1,5 % de canal lateral, sin contenedor centrado.
   La cabecera negra de las tablas llega prácticamente al borde de la ventana. */
/* Familia por DEFECTO: lectura y formulario. Que sea el defecto es deliberado —si
   una vista nueva no se adscribe a ninguna familia, el error seguro es quedarse
   estrecho, no invadir la pantalla. */
.page { max-width:var(--w-read); margin:0 auto; padding:2.4rem var(--gutter) 4.5rem; }

/* ── Familia REJILLA DE DATOS ──────────────────────────────────────────────────
   Dos formas de adscribirse, y las dos a propósito:
   · por CLASE, para las vistas que ya la traen (.docs = pedidos/albaranes/facturas/
     SAT; .cl = clientes/solicitudes/selecciones; .ms-add; .page-analysis; .page-plan;
     .page-stats);
   · por CONTENIDO, con :has(), para las que se pintan con `class="page"` a secas.
     `table.grid` es LA tabla de datos del portal (ui/table.js y carritos) y
     `.bd-kpis` el tablero de indicadores: si una página las contiene, es una
     rejilla, se llame como se llame. Así una vista nueva que use la tabla común
     entra en la familia sin tener que acordarse de poner la clase. */
.page:is(.docs, .cl, .ms-add, .page-analysis, .page-plan, .page-stats, .page-sellthrough, .checkout),
.page:has(table.grid),
.page:has(.bd-kpis) { max-width:none; margin:0; padding-inline:var(--rail-grid); }

/* ── Familia EDITORIAL ─────────────────────────────────────────────────────────
   .catalog-top y .lookbook traen además su propio padding vertical, así que se
   declaran ellas; aquí quedan .product y .dash, que solo necesitan el raíl. */
.page:is(.product, .dash) { max-width:none; margin:0; padding-inline:var(--rail-x); }
.crumbs { color:var(--muted); font-size:.8rem; letter-spacing:.02em; margin:0 0 .7rem; text-transform:uppercase; }
.crumbs a { text-decoration:none; }
.crumbs a:hover { color:var(--blue); }
.crumbs span { color:var(--ink); }
h1.title { font-family:var(--display); font-weight:500; font-size:clamp(2.2rem,4.2vw,3.2rem);
  letter-spacing:var(--brand-tracking,-.015em); line-height:1.04; margin:0 0 2rem; }
.cat-headline { display:flex; align-items:baseline; gap:.8rem; flex-wrap:wrap; }
/* Vista sin distracciones: se va el H1 y las migas se quedan en "Inicio" (20-header-ojo.png) */
body[data-focus="on"] .crumb, body[data-focus="on"] h1.title { display:none; }

.panel { background:var(--card); border-radius:var(--r); box-shadow:var(--shadow); padding:2.6rem 2rem;
  text-align:center; color:var(--muted); }
.panel b { display:block; color:var(--ink); font-size:1.05rem; margin-bottom:.35rem; }
/* Texto de marca dentro de su propio tinte: --blue-soft-text está medido contra --blue-soft
   (ver :root); --blue-deep sobre el tinte no llegaba a AA. */
.panel .tag { display:inline-block; margin-top:.9rem; background:var(--blue-soft); color:var(--blue-soft-text);
  border-radius:999px; padding:.28rem .8rem; font-size:.75rem; font-weight:700; letter-spacing:.04em; }
.panel .cta { display:inline-block; margin-top:1.1rem; background:var(--blue); color:#fff; font-weight:700;
  border-radius:var(--r-btn,var(--r-sm)); padding:.7rem 1.3rem; text-decoration:none; }
.panel .cta:hover { background:var(--blue-deep); }

/* ══════════════ Portada: carrusel + tarjetas de acceso ══════════════ */
/* Contenido servido por el CMS (portal_content). Las medidas siguen 01-dashboard.png:
   carrusel ~3.4:1 a ancho de página y dos tarjetas-imagen bajo el H1. */
/* La portada va sobre el papel crema; el carrusel y las tarjetas son piezas
   editoriales con radio y sombra suave (antes iban a sangre y sin marco). */
body:has(#hero) { background:var(--paper); }

/* Hero a sangre estilo editorial de moda (ref. thehoffbrand.com): vídeo o imagen a
   pantalla completa, título grande superpuesto y CTA mínimo. */
.hero-full { position:relative; width:100%; height:clamp(26rem, 74vh, 46rem); overflow:hidden; background:var(--ink); }
.hero-media { position:absolute; inset:0; }
.hero-media .carousel { position:absolute; inset:0; aspect-ratio:auto; height:100%; border-radius:0; box-shadow:none; }
.hero-media .c-track, .hero-media .c-slide { height:100%; }
.hero-media .c-slide img, .hero-media .c-video { width:100%; height:100%; object-fit:cover; }
.hero-media .hero-skeleton { position:absolute; inset:0; aspect-ratio:auto; border-radius:0; }
/* Movimiento cinematográfico lento en las imágenes hasta que haya vídeo real */
.hero-media .c-slide img { animation:kenburns 20s ease-in-out infinite alternate; }
@keyframes kenburns { from { transform:scale(1); } to { transform:scale(1.09) translate(-1.5%,-1%); } }
/* El texto per-slide del CMS se calla en el hero a sangre: manda el rótulo grande */
.hero-media .c-caption { display:none; }
.hero-media .c-dots, .hero-media .c-arrow { z-index:4; }
.hero-media .c-dots { bottom:1.3rem; }
/* Velo para que el título blanco lea sobre cualquier imagen o vídeo */
.hero-full::after { content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(to top, rgba(16,18,14,.74), rgba(16,18,14,.12) 46%, rgba(16,18,14,.30)); }

.hero-overlay { position:absolute; left:0; right:0; bottom:0; z-index:2; color:#fff;
  max-width:var(--maxw); margin:0 auto; padding:0 var(--gutter) clamp(2rem,5vw,3.6rem);
  display:flex; flex-direction:column; align-items:flex-start; gap:.3rem; }
.hero-kicker { font-size:.82rem; letter-spacing:.16em; text-transform:uppercase; opacity:.92;
  font-style:italic; font-family:var(--display); }
.hero-title { font-family:var(--display); font-weight:500; font-size:clamp(2.6rem,7vw,5.5rem);
  line-height:.98; letter-spacing:var(--brand-tracking,-.02em); margin:.1rem 0 .8rem; text-wrap:balance;
  text-shadow:0 2px 30px rgba(0,0,0,.35); }
.hero-cta { display:inline-flex; align-items:center; gap:.6rem; color:#fff; text-decoration:none;
  font-weight:600; font-size:.92rem; letter-spacing:var(--brand-cta-tracking,.02em); border:1px solid rgba(255,255,255,.6);
  border-radius:999px; padding:.72rem 1.5rem; transition:background .18s var(--ease), color .18s var(--ease), border-color .18s var(--ease); }
.hero-cta:hover { background:#fff; color:var(--ink); border-color:#fff; }
.hero-cta:focus-visible { outline:2px solid #fff; outline-offset:3px; }

.hero-full + .page { padding-top:2.8rem; }

/* ── Portada: la banda de ventanas sale al raíl ANCHO ─────────────────────────
   Las dos tarjetas son el ACCESO al catálogo (elegir con qué ventana se pide), y
   eran la pieza MÁS ESTRECHA de la pantalla: cabecera, cinta de pestañas, hero y
   pie van casi a sangre, y la banda se quedaba en la columna de lectura con casi
   400px de papel muerto a cada lado. Es un problema de ANCHO, no de tamaño: se
   ensancha el CONTENEDOR con el mismo max() del nav para que el borde de la banda
   caiga donde el de las pestañas, y lo demás (los KPI) vuelve a la columna de
   lectura, con su borde a plomo con el titular del hero.
   Nada de 100vw ni de márgenes negativos: la barra de scroll clásica metería
   scroll horizontal en toda la portada. */
.page.dash { max-width:none;
  padding-inline:max(clamp(1rem,4vw,2.4rem), calc((100% - var(--maxw-wide)) / 2)); }
.page.dash > :not(.tiles) { max-width:calc(var(--maxw) - 2 * var(--gutter)); margin-inline:auto; }
.hero-full + .page.dash { padding-top:2.2rem; }
/* .kpis lleva display:grid y gana al display:none del navegador para [hidden]: sin
   esto, cuando la API de KPI falla queda una rejilla vacía con su margen. */
.kpis[hidden] { display:none; }
@media (prefers-reduced-motion:reduce) { .hero-media .c-slide img { animation:none; } }
@media (max-width:48rem) { .hero-full { height:clamp(22rem,82vh,34rem); } }

/* ── Portada: saludo editorial + bento de KPIs ── */
.dash-greet { font-family:var(--display); font-weight:500; font-style:italic;
  font-size:clamp(1.5rem,3vw,2.1rem); color:var(--ink); letter-spacing:var(--brand-tracking,-.01em); margin:0 0 1.3rem; }
/* Los KPI van DEBAJO de la banda (ver dashboard.js): el margen deja de ir abajo */
.kpis { display:grid; grid-template-columns:repeat(3,1fr); gap:1.1rem; margin:3rem 0 0; }
.kpi { display:flex; flex-direction:column; gap:.35rem; background:var(--card); border:1px solid var(--line);
  border-radius:var(--r); padding:1.3rem 1.4rem; text-decoration:none; color:var(--ink);
  box-shadow:var(--shadow); transition:transform .18s var(--ease), box-shadow .18s var(--ease), border-color .18s var(--ease); }
.kpi:hover { transform:translateY(-3px); box-shadow:var(--shadow-card); border-color:var(--line-control); }
.kpi-label { font-size:.72rem; font-weight:600; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
.kpi-value { font-family:var(--display); font-weight:500; font-size:2.1rem; line-height:1; letter-spacing:var(--brand-tracking,-.01em);
  font-variant-numeric:tabular-nums; }
.kpi-sub { font-size:.82rem; color:var(--muted); }
/* Tarjeta de aviso (deuda vencida): superficie terracota */
.kpi-accent { background:var(--accent-soft); border-color:#e6c8b2; }
.kpi-accent .kpi-value { color:var(--accent-deep); }
.kpi-accent .kpi-sub { color:var(--accent-deep); font-weight:600; }
@media (max-width:52rem) { .kpis { grid-template-columns:1fr 1fr; } }
@media (max-width:34rem) { .kpis { grid-template-columns:1fr; } }

.carousel { position:relative; overflow:hidden; border-radius:var(--r); background:var(--ink-2);
  aspect-ratio:3.4/1; box-shadow:var(--shadow-card); }
.c-track { display:flex; height:100%; transition:transform .55s var(--ease); }
.c-slide { position:relative; flex:0 0 100%; display:block; color:#fff; text-decoration:none; }
.c-slide img { width:100%; height:100%; object-fit:cover; display:block; user-select:none; }

.c-caption { position:absolute; left:0; right:0; bottom:0; padding:2.4rem 2.2rem 3.2rem;
  display:flex; flex-direction:column; align-items:flex-start; gap:.35rem;
  background:linear-gradient(transparent, rgba(13,13,13,.72)); }
.c-caption strong { font-family:var(--display); font-size:clamp(1.3rem,2.6vw,2.2rem);
  letter-spacing:var(--brand-tracking,-.03em); line-height:1.1; }
.c-caption span { font-size:clamp(.9rem,1.2vw,1.05rem); color:#e9e9ee; }
.c-caption .c-cta { margin-top:.7rem; background:var(--blue); color:#fff; font-weight:700;
  border-radius:var(--r-sm); padding:.6rem 1.15rem; letter-spacing:var(--brand-cta-tracking,.02em); }
.c-slide:hover .c-cta { background:var(--blue-deep); }

.c-arrow { position:absolute; top:50%; translate:0 -50%; width:2.6rem; height:2.6rem; border-radius:50%;
  background:rgba(255,255,255,.9); color:var(--ink); display:grid; place-items:center;
  opacity:0; transition:opacity .2s var(--ease), background .15s var(--ease); }
.c-arrow.prev { left:1rem; rotate:90deg; }
.c-arrow.next { right:1rem; rotate:-90deg; }
.carousel:hover .c-arrow, .c-arrow:focus-visible { opacity:1; }
.c-arrow:hover { background:#fff; }

/* Los dots miden 24×24 para el dedo; el punto visible es el ::before interior */
.c-dots { position:absolute; left:0; right:0; bottom:.7rem; display:flex; justify-content:center;
  align-items:center; gap:.15rem; }
.c-dots button { width:24px; height:24px; border-radius:50%; display:grid; place-items:center; }
.c-dots button[data-go]::before { content:""; width:.6rem; height:.6rem; border-radius:50%;
  background:rgba(255,255,255,.55); transition:background .15s var(--ease), scale .15s var(--ease); }
.c-dots button[data-go]:hover::before { background:#fff; }
.c-dots button[aria-current="true"]::before { background:var(--blue); scale:1.15; }
.c-dots .c-play { width:24px; height:24px; color:#fff; opacity:.8; }
.c-dots .c-play:hover { opacity:1; }
.c-dots button:focus-visible { outline:2px solid #fff; outline-offset:1px; }

.hero-skeleton { aspect-ratio:3.4/1; border-radius:var(--r); background:var(--surface); }
/* Sin aspect-ratio: la altura la pone la fila de la rejilla, así el esqueleto mide
   EXACTAMENTE lo que medirá la tarjeta y la banda no salta al pintarse. */
.tile-skeleton { border-radius:var(--r); background:var(--surface); }
.hero-skeleton, .tile-skeleton { background-image:linear-gradient(100deg,transparent 20%,rgba(255,255,255,.65) 50%,transparent 80%);
  background-size:220% 100%; animation:sheen 1.4s var(--ease) infinite; }
@keyframes sheen { from { background-position:180% 0; } to { background-position:-80% 0; } }

/* ── La banda: ALTURA DE FILA fija, columnas automáticas ──────────────────────
   El CMS decide cuántas ventanas hay, así que la PROPORCIÓN no puede ser fija: con
   aspect-ratio la portada cambiaba de alto cada vez que el cliente añadía o quitaba
   una. Con grid-auto-rows la banda pesa siempre lo mismo y lo único que cambia es el
   encuadre. El alto es ~la mitad del hero a propósito: la banda debe ser grande pero
   SUBORDINADA; a 16/9 y ancha serían dos losas compitiendo con la campaña.
   El suelo de 22rem apila las tarjetas solas en pantallas estrechas, sin media query. */
.tiles { display:grid; gap:clamp(.8rem, 1vw, 1.2rem);
  grid-template-columns:repeat(auto-fit, minmax(min(22rem,100%), 1fr));
  grid-auto-rows:clamp(15rem, 22vw, 25rem); }
/* Solo los extremos necesitan matiz: una sola sería un buzón y cuatro saldrían casi
   cuadradas. Si faltara data-count, la regla de arriba ya sostiene la banda. */
.tiles[data-count="1"] { grid-auto-rows:clamp(17rem, 27vw, 30rem); }
.tiles[data-count="4"] { grid-auto-rows:clamp(13rem, 17vw, 20rem); }
/* Sin ningún catálogo publicable (una instancia recién montada, o el hueco entre dos
   campañas) la banda no pinta dos tarjetas que llevarían al mismo sitio: dice la verdad.
   La rejilla deja de imponer alto de tarjeta para que el texto no quede flotando. */
.tiles[data-count="0"] { grid-auto-rows:auto; }
.dash-empty { grid-column:1 / -1; margin:0; padding:clamp(1.2rem,3vw,2rem);
  border:1px dashed var(--line); border-radius:var(--r);
  color:var(--muted); font-size:.95rem; text-align:center; }


.tile { position:relative; display:block; overflow:hidden; border-radius:var(--r);
  container-type:inline-size;   /* el rótulo se mide contra LA TARJETA, no contra la ventana */
  background:var(--ink); color:#fff; text-decoration:none; box-shadow:var(--shadow); }
/* Sobre la foto el acento se pierde: el foco se marca en blanco por dentro y con el
   halo de marca por fuera. Ese halo vive FUERA de la caja, así que la banda conserva
   canal lateral y nunca debe llevar overflow oculto. */
.tile:focus-visible { outline:3px solid #fff; outline-offset:-3px; box-shadow:0 0 0 3px var(--blue); }
.tile img, .tile .t-art { position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  transition:scale .5s var(--ease); }
/* 1.04 sobre una tarjeta de 900px era un tirón de 36px; a este tamaño 1.02 se lee mejor.
   Solo con puntero real: en táctil el :hover se queda pegado tras el toque y la tarjeta
   tocada quedaba ampliada hasta tocar otra. */
@media (hover:hover) { .tile:hover img, .tile:hover .t-art { scale:1.02; } }
/* Sin imagen en el CMS, la tarjeta se sostiene con el color de marca. Planos, no
   degradados: los tres rojos y los tres grises literales eran los de MITO y una instancia
   de otro color los heredaba tal cual en su portada. */
.tile[data-window="replenishment"] .t-art { background:var(--blue); }
.tile[data-window="scheduled"] .t-art { background:var(--ink); }
/* Se retira el velo diagonal a inset:0: oscurecía la foto ENTERA para proteger un
   texto que vive abajo y, aun así, no llegaba a contraste AA sobre una foto clara.
   Además el hover lo ACLARABA, bajando la legibilidad justo al interactuar. Ahora el
   ::after es solo la respuesta al puntero, y oscurece.
   Capas: imagen (auto) · velo de hover (1) · rótulos (2). */
.tile::after { content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:rgba(13,13,13,.16); opacity:0; transition:opacity .3s var(--ease); }
.tile:hover::after, .tile:focus-visible::after { opacity:1; }

/* ── Rótulos: un bloque abajo a la izquierda, con su propio velo ──────────────
   El velo va en el BLOQUE DE TEXTO, no en la tarjeta: cubre exactamente el texto —una
   línea o dos, en cualquier idioma— y se desvanece dentro de su padding, sin depender
   del alto de la caja. Sobre una foto reventada de blanco mantiene el contraste AA del
   rótulo y del subtítulo. El casi-negro es fijo a propósito: es un velo FOTOGRÁFICO,
   no una superficie de marca. A cambio, los dos tercios de arriba quedan limpios.
   A la izquierda porque es donde arranca todo el texto de la página, y así los rótulos
   forman una línea continua a lo largo de la banda con 2, 3 o 4 tarjetas. */
.t-body { position:absolute; left:0; right:0; bottom:0; z-index:2;
  display:flex; flex-direction:column; align-items:flex-start; gap:.35rem;
  padding:3.6rem 1.5rem 1.3rem;
  background:linear-gradient(to top, rgba(13,13,13,.84), rgba(13,13,13,.80) 62%, rgba(13,13,13,0)); }
/* cqw y no vw: con cuatro tarjetas el rótulo se dimensionaba con la VENTANA y salía
   enorme dentro de una caja estrecha. La declaración en vw va delante como respaldo:
   si el navegador no entiende cqw, invalida la segunda y sobrevive la primera. */
.t-label { font-size:clamp(1.25rem,2.2vw,2.4rem); font-size:clamp(1.25rem,4.4cqw,2.4rem);
  font-weight:500; line-height:1.1; text-wrap:balance;
  letter-spacing:var(--brand-tracking,-.02em); text-transform:var(--brand-caps,none); }
/* El carrito baja al bloque de texto: un icono de interfaz flotando sobre una foto de
   campaña es lo más "plantilla" de la pieza, y obligaba a un segundo velo arriba. */
.t-foot { display:inline-flex; align-items:center; gap:.5rem; }
.t-cart { color:#fff; opacity:.95; display:inline-flex; }
.t-cart svg { width:20px; height:20px; }
/* Fuera el resplandor de 18px del rótulo: a este tamaño ensuciaba el trazo sin aportar
   contraste, que ahora lo da el velo del bloque. */
.t-sub { font-size:.85rem; letter-spacing:.02em; color:#e6e6ec; }

@media (prefers-reduced-motion:reduce) {
  .c-track { transition:none; }
  .hero-skeleton, .tile-skeleton { animation:none; }
  .tile img, .tile .t-art, .tile::after { transition:none; }
  /* Sin esto el zoom seguía ocurriendo al pasar el ratón, solo que de golpe */
  .tile:hover img, .tile:hover .t-art { scale:1; }
}

/* ══════════════ Pantallas sin chrome (login / credenciales) ══════════════ */
/* Modernist: LOGIN split — cartel rojo con display XXL + formulario sobre papel */
body[data-chrome="off"] { background:var(--paper); }
body[data-chrome="credentials"] { background:var(--ink); }
.login-split { min-height:100vh; display:grid; grid-template-columns:1.05fr 1fr; }
.login-hero { background:var(--blue); color:#fff; display:flex; flex-direction:column; justify-content:space-between;
  gap:2rem; padding:clamp(2rem,5vw,3.5rem); }
.login-hero .brand { color:#fff; font-size:1.9rem; }
/* Foto del acceso (bloque login.background, la inserta ui/access-photo.js). En la base no se pinta:
   el cartel de color de MITO y ALMA sigue como está; cada marca decide en su bloque cómo la compone. */
.access-photo { display:none; }
/* Mayúscula por defecto, pero el token caps=false (--brand-caps:none) la retira: una tagline
   serif en caja de frase (POLO CLUB). Sin token la variable no existe y queda en uppercase. */
.login-display { font-family:var(--display); font-weight:800; text-transform:var(--brand-caps,uppercase); letter-spacing:var(--brand-tracking,-.03em);
  line-height:.96; font-size:clamp(2.6rem,6.4vw,5.4rem); margin:0; color:#fff; }
.login-panel { display:grid; place-items:center; padding:2rem clamp(1.5rem,5vw,4rem); }
.login-panel .login-card { width:min(25rem,100%); background:none; box-shadow:none; padding:0; }
.login-h { font-family:var(--display); font-weight:800; font-size:2rem; margin:0 0 1.4rem; letter-spacing:var(--brand-tracking,-.02em); }
@media (max-width:52rem) {
  .login-split { grid-template-columns:1fr; }
  .login-hero { min-height:36vh; }
}
/* Selección de credencial: tarjeta centrada sobre negro */
.sheet { min-height:100vh; display:grid; place-items:center; padding:2rem 1rem; }
.sheet .card { background:var(--card); border-radius:var(--r); box-shadow:var(--shadow-card); padding:2.8rem 2.4rem; }
.sheet .card .brand { display:block; text-align:center; font-style:normal; font-weight:800; font-size:2.6rem; color:var(--ink); margin:0 0 1.9rem; }

/* Login (00-inicio.png) */
.login-card { width:min(29rem,100%); }
/* El borde va por el token de control (era un #ccc literal, 1,6:1: la caja de Contraseña casi
   no existía frente a la de Email en foco), así sigue a --line-control de cada instancia. */
.login-card .field { width:100%; border:1px solid var(--line-control); border-radius:4px; padding:.85rem 1rem;
  margin-bottom:.9rem; transition:border-color .15s var(--ease); }
.login-card .field:focus { border-color:var(--blue); }
/* Un solo marco de 2px al enfocar (borde + sombra interior pegada), no borde + hueco
   blanco + anillo: el doble marco se leía como un error de dibujo. Sigue siendo foco
   visible (WCAG 2.4.7): la sombra va en el color de marca y ocupa el ancho del borde. */
.login-card .field:focus-visible { outline:none; box-shadow:inset 0 0 0 1px var(--blue); }
.login-card .field::placeholder { color:var(--muted); }
.login-card .forgot { display:block; text-align:right; font-size:.85rem; color:var(--blue); margin:.1rem 0 1.4rem; }
.login-card .submit { width:100%; background:var(--blue); color:#fff; font-weight:700;
  letter-spacing:var(--brand-tracking,.04em);
  border-radius:var(--r-btn,4px); padding:.95rem; transition:background .15s var(--ease); }
.login-card .submit:hover { background:var(--blue-deep); }
.login-card .submit[disabled] { opacity:.6; cursor:progress; }
.login-card h2 { font-size:.95rem; font-weight:700; margin:1.6rem 0 .7rem; }
.login-card p { margin:0 0 .9rem; color:var(--ink-2); }
.login-card .create { color:var(--blue); font-weight:600; }
.login-card .legal { font-size:.8rem; color:var(--hint); line-height:1.5; margin:1rem 0 0; }
.login-card .err { color:var(--out); font-size:.85rem; min-height:1.3em; margin:.7rem 0 0; }

/* Activación / recuperación de contraseña (Fase 2). Reutiliza la tarjeta del login */
.activate-card h1 { font-family:var(--display); font-size:1.5rem; margin:0 0 .5rem; color:var(--ink); }
.activate-card .activate-lead { color:var(--ink-2); margin:0 0 1.2rem; }
.activate-card .activate-form .field { width:100%; border:1px solid var(--line-control); border-radius:4px;
  padding:.85rem 1rem; font-size:1rem; margin:0 0 .9rem; }
.activate-card .activate-form .field:focus { border-color:var(--blue); }
.activate-card .activate-form .field:focus-visible { outline:2px solid var(--blue); outline-offset:1px; }
.activate-card .activate-hint { font-size:.82rem; color:var(--muted); margin:-.3rem 0 1rem; }
.activate-card .submit { width:100%; background:var(--blue); color:#fff; font-weight:700;
  letter-spacing:var(--brand-tracking,.04em);
  border:none; border-radius:var(--r-btn,4px); padding:.9rem; font-size:.95rem; cursor:pointer; }
.activate-card .submit:hover { background:var(--blue-deep); }
.activate-card .submit[disabled] { opacity:.6; cursor:progress; }
.activate-card .activate-ok { color:var(--blue-deep); font-size:.9rem; margin:.8rem 0 0; }
.activate-card .forgot { display:block; text-align:center; font-size:.9rem; color:var(--blue); margin:1.2rem 0 0; }

/* Selección de acceso — "split" (hero rojo + panel de tarjetas), coherente con el login.
   El hero rojo lleva SOLO display grande (marca + saludo + nombre), como el login: el
   texto pequeño en blanco sobre el rojo de marca no llega a AA, así que la guía de lectura
   vive en el panel claro (tinta sobre papel), que además es donde se decide. */
.cred-split { min-height:100vh; display:grid; grid-template-columns:1.05fr 1fr; background:var(--paper); }
.cred-hero { background:var(--blue); color:#fff; display:flex; flex-direction:column; justify-content:space-between;
  gap:2rem; padding:clamp(2rem,5vw,3.5rem); }
.cred-hero .brand { color:#fff; font-size:1.9rem; }
.cred-hero-mid { display:flex; flex-direction:column; }
.cred-hero-mid .hero-kicker { font-size:.9rem; font-weight:700; letter-spacing:.22em; text-transform:uppercase;
  color:#fff; margin:0 0 .7rem; font-style:normal; }
.cred-hero-name { font-family:var(--display); font-weight:800; text-transform:var(--brand-caps,uppercase); letter-spacing:var(--brand-tracking,-.03em);
  line-height:.94; font-size:clamp(2.4rem,5.8vw,4.8rem); margin:0; color:#fff; text-wrap:balance; }

.cred-panel { display:grid; place-items:center; padding:2rem clamp(1.5rem,5vw,4rem); }
.cred-wrap { width:min(30rem,100%); }
.cred-h { font-family:var(--display); font-weight:800; font-size:2rem; letter-spacing:var(--brand-tracking,-.02em); margin:0;
  padding-bottom:1rem; border-bottom:var(--rule-w) solid var(--rule); }
.cred-lead { color:var(--ink-2); font-size:.95rem; line-height:1.5; max-width:30rem; margin:1.1rem 0 0; }
.cred-cards { display:flex; flex-direction:column; gap:.8rem; margin-top:1.5rem; }

.cred-card2 { display:flex; align-items:center; gap:1rem; width:100%; text-align:left; background:var(--card);
  border:1px solid var(--line); border-left:3px solid transparent; padding:1rem 1.1rem; cursor:pointer;
  transition:border-color .15s var(--ease), transform .15s var(--ease), box-shadow .15s var(--ease); }
.cred-card2:hover { border-color:#cfcaca; border-left-color:var(--blue); transform:translateX(3px); box-shadow:var(--shadow-card); }
.cred-card2:focus-visible { outline:2px solid var(--blue); outline-offset:2px; }
.cred-av { flex:none; width:2.9rem; height:2.9rem; background:var(--blue); color:#fff; display:grid; place-items:center;
  font-family:var(--display); font-weight:800; font-size:1.15rem; }
.cred-meta { flex:1; min-width:0; display:flex; flex-direction:column; gap:.2rem; }
.cred-meta b { font-size:1.02rem; letter-spacing:-.01em; }
.cred-sub { font-size:.82rem; color:var(--muted); }
.cred-type { font-weight:700; letter-spacing:.05em; text-transform:uppercase; color:var(--blue); font-size:.72rem; }
/* Acción explícita: el propio botón dice qué pasará ("Entrar" / "Elegir cliente") */
.cred-action { flex:none; display:flex; align-items:center; gap:.55rem; color:var(--muted);
  transition:color .15s var(--ease); }
.cred-action-label { font-size:.72rem; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-2); transition:color .15s var(--ease); }
.cred-go { display:flex; transition:transform .15s var(--ease); }
.cred-card2:hover .cred-action, .cred-card2:focus-visible .cred-action { color:var(--blue); }
.cred-card2:hover .cred-action-label, .cred-card2:focus-visible .cred-action-label { color:var(--blue); }
.cred-card2:hover .cred-go, .cred-card2:focus-visible .cred-go { transform:translateX(3px); }

/* Credencial única: la tarjeta gana presencia (más aire, avatar y nombre mayores) */
.cred-cards.single .cred-card2 { padding:1.5rem 1.4rem; border-left-width:4px; }
.cred-cards.single .cred-av { width:3.4rem; height:3.4rem; font-size:1.35rem; }
.cred-cards.single .cred-meta b { font-size:1.18rem; }

/* Salida discreta y accesible bajo las tarjetas */
.cred-exit { margin:1.4rem 0 0; font-size:.86rem; color:var(--muted); }
.cred-exit-link { color:var(--ink); font-weight:600; text-decoration:underline; text-underline-offset:3px;
  text-decoration-thickness:1px; background:none; border:none; padding:0; cursor:pointer; }
.cred-exit-link:hover { color:var(--blue); }
.cred-exit-link:focus-visible { outline:2px solid var(--blue); outline-offset:2px; }

.cred-empty { color:var(--ink-2); border:1px solid var(--line); padding:1.2rem; line-height:1.5; margin-top:1.5rem; }
.cred-empty a { color:var(--blue); font-weight:600; text-underline-offset:3px; }

@media (max-width:52rem) {
  .cred-split { grid-template-columns:1fr; }
  .cred-hero { min-height:30vh; }
  /* En apilado, el nombre gigante ya no necesita empujar al fondo: pega al saludo */
  .cred-hero { justify-content:flex-start; gap:1.4rem; }
}
/* En móvil la tarjeta ya es full-width y evidentemente pulsable, y el "lead" ya comunica
   el siguiente paso: la etiqueta de acción se reduce a la flecha para que el nombre (que
   puede ser largo) no compita ni envuelva. El aria-label del botón conserva la acción. */
@media (max-width:30rem) {
  .cred-action-label { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden;
    clip-path:inset(50%); white-space:nowrap; }
  .cred-meta b { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
}
@media (prefers-reduced-motion:reduce) {
  .cred-card2, .cred-card2:hover, .cred-go, .cred-action { transition:none; transform:none; }
  .cred-card2:hover .cred-go, .cred-card2:focus-visible .cred-go { transform:none; }
}

/* ══════════════ Piezas comunes (Fase 2) ══════════════ */
.sr-only { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden;
  clip-path:inset(50%); white-space:nowrap; }

.btn-primary, .btn-ghost, .btn-danger { display:inline-flex; align-items:center; justify-content:center;
  gap:.5rem; border-radius:var(--r-btn,var(--r-sm)); padding:.72rem 1.15rem; font-weight:700; font-size:.82rem;
  letter-spacing:var(--brand-tracking,.045em); text-transform:uppercase; white-space:nowrap;
  transition:background .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease); }
.btn-primary { background:var(--blue); color:#fff; }
.btn-primary:hover:not([disabled]) { background:var(--blue-deep); }
.btn-ghost { background:#fff; color:var(--ink); border:1px solid var(--line-control); }
.btn-ghost:hover:not([disabled]) { border-color:var(--ink); }
.btn-danger { background:#fff; color:var(--out); border:1px solid var(--out); }
.btn-danger:hover:not([disabled]) { background:#fdf1f0; }
/* Deshabilitado por tokens, no por grises literales: el #e6e5e0/#75746e eran los grises
   CÁLIDOS de MITO y sobre un papel frío se veían beige. --surface/--muted dan 4,6:1 en MITO
   y 4,9:1 en BLOCCO, y siguen la temperatura del papel de cada instancia. */
.btn-primary[disabled], .btn-ghost[disabled], .btn-danger[disabled] {
  background:var(--surface); color:var(--muted); border-color:transparent; cursor:not-allowed; }
.block { width:100%; }
.link { color:var(--blue); text-decoration:underline; text-underline-offset:3px; }

.skeleton { height:11rem; border-radius:var(--r); margin-bottom:.9rem; background:#eeede9;
  background-image:linear-gradient(100deg,transparent 20%,rgba(255,255,255,.7) 50%,transparent 80%);
  background-size:220% 100%; animation:sheen 1.4s var(--ease) infinite; }
.skeleton.short { height:6rem; }

.notice { display:flex; gap:.7rem; border-radius:var(--r-sm); padding:.9rem 1rem; margin-bottom:1rem; }
.notice b { display:block; font-size:.92rem; }
.notice span { font-size:.85rem; }
.notice svg { flex:none; margin-top:.1rem; }
/* La columna de texto del aviso puede llevar un botón (p. ej. "Quitar artículos no
   disponibles"): sin min-width:0 el hijo ancho empujaba el aviso fuera del panel. */
.notice > div { min-width:0; }
/* El aviso de error va en el segundo acento, como los chips y avisos de deuda: --accent-deep
   se mide contra su propio tinte en branding.js, así que el par siempre cumple AA. */
.notice-error { background:var(--accent-soft); color:var(--accent-deep); }
.notice-ok { background:#e8f6ed; color:#0f6b34; }
/* Aviso que no es un fallo del comprador: la marca cambio algo (una ventana que se
   acorta y recorta el dia de servicio ya elegido). Ni rojo de error ni verde de OK. */
.notice-warn { background:#fdf3e2; color:#7a4d05; }

/* Diálogo del portal (js/ui/dialog.js): sustituye a confirm()/prompt() del
   navegador, que no se pueden traducir ni vestir. <dialog> nativo: Esc cierra y
   el foco vuelve solo al botón que lo abrió. */
.dlg { border:none; padding:0; background:transparent; max-width:min(28rem,92vw); }
.dlg::backdrop { background:rgba(13,13,13,.45); }
.dlg .panel { text-align:left; padding:1.5rem 1.6rem 1.3rem; box-shadow:var(--shadow-card); }
.dlg h2 { font-family:var(--display); font-size:1.15rem; letter-spacing:-.02em;
  margin:0 0 .5rem; color:var(--ink); text-transform:uppercase; }
.dlg p { margin:0; color:var(--ink-2); font-size:.95rem; }
.dlg label { display:block; margin-top:1rem; }
.dlg label span { display:block; font-size:.72rem; font-weight:700; letter-spacing:.07em;
  text-transform:uppercase; color:var(--ink); margin-bottom:.35rem; }
.dlg input { width:100%; border:1px solid var(--line-control); border-radius:var(--r-sm);
  padding:.55rem .7rem; background:#fff; }
.dlg input:focus { border-color:var(--blue); }
.dlg .dlg-actions { display:flex; justify-content:flex-end; gap:.6rem; margin-top:1.4rem; flex-wrap:wrap; }

/* Alta de dirección de envío (js/ui/address-form.js). Es el diálogo del portal con
   dos columnas de campos: entra por el checkout y por «Empresa», y en las dos tiene
   que caber sin obligar a hacer scroll dentro del modal. */
.dlg-address { max-width:min(36rem,94vw); }
.addr-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:0 1.1rem; }
/* La calle ocupa la fila entera: es el campo largo del formulario */
.addr-field.wide { grid-column:1/-1; }
.dlg .addr-hint { display:block; margin-top:.3rem; font-style:normal; font-size:.75rem;
  font-weight:400; letter-spacing:0; text-transform:none; color:var(--hint); }
.dlg .addr-error { margin-top:1.1rem; color:var(--blue-text); font-weight:700; }
.dlg .addr-form input.bad { border-color:var(--blue); }

/* Tabla de listado — editorial "silenciosa": sin cabecera negra. La cabecera es
   una tira crema con tinta apagada y un filete inferior; las tarjetas de tabla
   flotan sobre el papel con radio y sombra tenue. */
table.grid { width:100%; border-collapse:separate; border-spacing:0; background:var(--card);
  border:1px solid var(--line); border-radius:var(--r); overflow:hidden; box-shadow:var(--shadow); }
/* nowrap: en móvil la tabla desborda su .grid-scroll y sin esto las cabeceras se partían
   en dos líneas («N. DE / PEDIDO»); mejor una columna algo más ancha con scroll lateral. */
table.grid th { background:var(--surface); color:var(--muted); text-align:left; font-size:.7rem; letter-spacing:.08em;
  text-transform:uppercase; padding:.95rem 1.1rem; font-weight:600; border-bottom:1px solid var(--line); white-space:nowrap; }
table.grid td { padding:1rem 1.1rem; border-bottom:1px solid var(--line); font-size:.9rem; }
table.grid tbody tr:last-child td { border-bottom:none; }
table.grid tbody tr:hover td { background:var(--paper); }
table.grid .grid-empty td { text-align:center; color:var(--muted); padding:1.6rem 1rem; }
table.grid .grid-empty:hover td { background:transparent; }
.grid-actions { width:3.5rem; text-align:right; }
.grid-link { font-weight:600; text-align:left; }
.grid-link:hover { color:var(--blue); text-decoration:underline; text-underline-offset:3px; }
.grid-drop { color:var(--muted); padding:.3rem; border-radius:6px; }
.grid-drop:hover { color:var(--out); background:#fdf1f0; }

/* La tabla no encoge por debajo de sus columnas: en pantallas estrechas se
   desplaza dentro de su caja en vez de estirar el documento entero. */
.grid-scroll { overflow-x:auto; overscroll-behavior-x:contain; }

/* Paginación «‹ 1 ›» + Mostrar N.
   "Mostrar N" era absoluto y se superponía a los números en cuanto había muchas
   páginas: ahora es un ítem flex más. Los dos extremos crecen por igual, así que
   los números siguen centrados y el selector se va a la derecha (o baja de línea). */
.pager { display:flex; align-items:center; justify-content:center; gap:.3rem;
  padding:1.6rem 0; flex-wrap:wrap; }
/* El pseudoelemento equilibra el peso de "Mostrar" para que los números queden
   centrados; sin ese selector (carritos favoritos, M9) sobra y desplazaría todo. */
.pager:has(.pg-size)::before { content:""; flex:1 1 0; }
.pager button { min-width:2.1rem; height:2.1rem; border-radius:var(--r-sm); display:grid; place-items:center;
  color:var(--ink); font-size:.86rem; transition:background .15s var(--ease); }
.pager button:hover:not([disabled]) { background:#eceae5; }
.pager .pg-num.on { background:var(--blue); color:#fff; }
.pager button[disabled] { color:#c3c2bc; cursor:default; }
.pager .pg-gap { color:var(--muted); padding:0 .2rem; }
.pager .pg-size { flex:1 1 auto; display:flex; justify-content:flex-end; }
.pager select, .toolbar select, .doc-tools select { appearance:none; background:#fff; border:1px solid var(--line-control); border-radius:var(--r-sm);
  padding:.5rem 2rem .5rem .7rem; font-size:.86rem; cursor:pointer; }

/* ══════════════ Catálogo (17-catalog-catalog.png) ══════════════ */
.page.catalog { display:grid; grid-template-columns:13.5rem minmax(0,1fr); gap:2.4rem; align-items:start; }
.cat-main { min-width:0; }

.rail { position:sticky; top:calc(var(--header-h) + 1rem); align-self:start; max-height:calc(100vh - 6rem);
  overflow-y:auto; overscroll-behavior:contain; padding-bottom:1rem;
  /* Barra de scroll fina y discreta (no la gorda del sistema); sólo se ve al pasar */
  scrollbar-width:thin; scrollbar-color:transparent transparent; scrollbar-gutter:stable; }
.rail:hover { scrollbar-color:var(--line) transparent; }
.rail::-webkit-scrollbar { width:6px; }
.rail::-webkit-scrollbar-track { background:transparent; }
.rail::-webkit-scrollbar-thumb { background:transparent; border-radius:0; }
.rail:hover::-webkit-scrollbar-thumb { background:var(--line); }
.rail section { margin-bottom:1.7rem; }
.rail h2 { font-size:.78rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  margin:0 0 .7rem; color:var(--ink); }
.rail-line { display:block; width:100%; text-align:left; padding:.24rem 0; font-size:.92rem; color:var(--ink-2); }
.rail-line:hover { color:var(--blue); }
.rail-line.on { font-weight:700; color:var(--ink); }
.rail-model { display:flex; flex-wrap:wrap; align-items:center; gap:.7rem; }
.rail-model h2 { margin:0; }
.rail-model input { flex:1; min-width:6rem; border:1px solid var(--line-control); border-radius:var(--r-sm);
  padding:.5rem .7rem; background:#fff; }
.rail-model input:focus { border-color:var(--blue); }

.rail-check { display:flex; align-items:center; gap:.6rem; padding:.27rem 0; cursor:pointer; font-size:.92rem; }
.rail-check input { appearance:none; width:1.15rem; height:1.15rem; flex:none; border:1.5px solid var(--line-control);
  border-radius:3px; display:grid; place-items:center; background:#fff; transition:all .12s var(--ease); }
.rail-check input:checked { background:var(--ink); border-color:var(--ink); }
.rail-check input:checked::after { content:""; width:.5rem; height:.28rem; border-left:2px solid #fff;
  border-bottom:2px solid #fff; rotate:-45deg; translate:0 -1px; }
.rail-check span:first-of-type { flex:1; }
.rail-count { color:var(--muted); font-size:.78rem; }
.rail-more { margin-top:.35rem; font-size:.86rem; color:var(--ink); text-decoration:underline;
  text-underline-offset:3px; }
.rail-more:hover { color:var(--blue); }
/* Vista sin distracciones (20-header-ojo.png): se van LÍNEAS y MODELO con el H1 */
body[data-focus="on"] .rail-lines, body[data-focus="on"] .rail-model { display:none; }

/* "Catálogo · 99 artículos" a la izquierda y la toolbar a la derecha, en la misma
   línea. Con el ojo activo desaparece el H1 y el recuento ocupa su sitio. */
.cat-bar { display:flex; align-items:flex-end; justify-content:space-between; gap:1.5rem;
  flex-wrap:wrap; margin-bottom:1.4rem; }
.cat-title { min-width:0; }
.cat-title .cat-headline { min-height:2.9rem; margin-bottom:.4rem; }
.cat-title h1.title { margin:0; }
/* "Catálogo · 99 artículos": el punto solo tiene sentido si el H1 está delante */
.cat-count { color:var(--muted); font-size:1rem; white-space:nowrap; }
.cat-count::before { content:"· "; }
body[data-focus="on"] .cat-count::before { content:none; }

.toolbar { display:flex; align-items:flex-end; gap:.9rem; flex-wrap:wrap; }
.tb-export { display:inline-flex; align-items:center; gap:.5rem; padding:.5rem .4rem; font-size:.95rem;
  border-radius:var(--r-sm); }
.tb-export:hover:not([disabled]) { color:var(--blue); }
.tb-export[disabled] { color:var(--muted); cursor:progress; }
/* Las descargas (CSV de stock, catálogo PDF) son de escritorio: en 390px eran dos de los
   siete controles que había que pasar antes de ver el primer producto. */
@media (max-width:48rem) { .tb-export { display:none; } }
/* ══════════════ CONTROLES DE FORMULARIO · sistema único ══════════════════════
   Cuatro piezas y un solo tratamiento: RÓTULO (.tb-legend) + CARCASA (.tb-select,
   que envuelve un select, un input de fecha o uno de texto) y GRUPO DE BOTONES
   (.tb-seg). Antes había tres verdades: la base pintaba una etiqueta flotante
   sobre el borde —el único material-ismo que quedaba en el portal—, y «paper» y
   «photo» la habían corregido cada una por su cuenta con dos bloques calcados al
   final de la hoja. El tratamiento bueno era el de las marcas, así que sube AQUÍ
   y los dos parches se borran: una marca nueva ya no nace con el defecto.

   El rótulo va ENCIMA en versal pequeña, que es como el portal rotula el sub-nav,
   el pie y los kickers editoriales. La carcasa lleva el filete y el alto; el
   control de dentro es transparente y sin borde, para que nunca se vea la caja
   del sistema operativo dentro de la nuestra (que es lo que se veía en las
   fechas de Análisis: doble marco). */
.tb-field { display:grid; gap:.35rem; }
.tb-legend { font-size:.7rem; font-weight:500; letter-spacing:.10em; text-transform:uppercase;
  color:var(--muted); }
.tb-select { display:flex; align-items:center; gap:.5rem; border:1px solid var(--ctl-line);
  border-radius:var(--r-sm); padding-left:var(--ctl-pad-x); background:var(--ctl-bg);
  height:var(--ctl-h); transition:border-color .12s var(--ease); }
.tb-select svg { color:var(--muted); flex:none; }
/* El foco vive en la CARCASA, no en el control desnudo: el filete lo dibuja ella, así
   que un anillo sobre el <select> se pintaba por dentro del marco y casi no se veía.
   :focus-within lo saca al borde real del control (WCAG 2.4.7 con teclado). */
.tb-select:focus-within { border-color:var(--blue); outline:2px solid var(--blue); outline-offset:1px; }
.tb-select :is(select, input) { background-color:transparent; border:none; height:100%;
  padding-block:0; min-width:0; font:inherit; color:var(--ink); }
.tb-select :is(select, input):focus { outline:none; }   /* el anillo lo pone la carcasa */
.tb-select select { padding-right:1.6rem; min-width:8.5rem;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236b6b74' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right .55rem center; }

/* ── CAMPO DE FECHA: nativo por fuera de la vista, nuestro por dentro ──────────
   No se sustituye por un calendario a mano A PROPÓSITO: el <input type="date">
   trae de serie el teclado (flechas para subir día/mes/año), el selector del
   sistema en móvil, el formato y el idioma del usuario y el rol para lectores de
   pantalla. Todo eso se pierde el día que se pinta un calendario propio.
   Lo que sí se puede vestir es TODO lo que el navegador dibuja: la caja (ya la
   quita la regla de arriba), el texto y —la pieza que cantaba— el botón del
   calendario, que en Chromium venía con su glifo azulado de sistema. Se le pone
   NUESTRO icono como background-image (eso tapa el glifo por defecto) sin dejar
   de ser el botón nativo que abre el desplegable del navegador. */
.tb-select input[type="date"] { padding-right:.45rem; min-width:8rem; }
.tb-select input[type="date"]::-webkit-calendar-picker-indicator {
  width:1.05rem; height:1.05rem; padding:0; margin:0; cursor:pointer; opacity:.55;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23201e1d' stroke-width='1.7' stroke-linecap='round'%3E%3Crect x='3' y='5' width='18' height='16'/%3E%3Cpath d='M3 10h18M8 3v4M16 3v4'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:center; background-size:contain;
  transition:opacity .12s var(--ease); }
.tb-select input[type="date"]:hover::-webkit-calendar-picker-indicator,
.tb-select input[type="date"]:focus::-webkit-calendar-picker-indicator { opacity:1; }
/* El campo vacío enseñaba «dd/mm/aaaa» a la misma tinta que una fecha de verdad */
.tb-select input[type="date"]::-webkit-datetime-edit-text,
.tb-select input[type="date"]:invalid::-webkit-datetime-edit { color:var(--muted); }
/* Firefox no tiene indicador propio: sin este relleno la fecha quedaba pegada al filete */
@supports (-moz-appearance:none) { .tb-select input[type="date"] { padding-right:var(--ctl-pad-x); } }
/* Vista: mientras solo exista Listado el selector entero va deshabilitado (con
   title explicativo) en vez de dejar una única opción elegible que no hace nada. */
.tb-select:has(select[disabled]) { background:#f1f0ec; border-color:#c9c8c2; color:var(--muted); }
.tb-select select[disabled] { background-color:transparent; cursor:not-allowed; color:var(--muted); }

/* Filtrar recarga el listado: mientras llega la respuesta las filas se apagan y
   dejan de aceptar clics, y #count anuncia "Cargando…" (role="status"). */
.cat-list.is-loading { opacity:.45; pointer-events:none; transition:opacity .15s var(--ease); }

/* ── Catálogo con filtros ARRIBA (barra de lookups desplegables) ──
   Lenguaje propio, distinto del rail lateral del original: la cuadrícula ocupa todo
   el ancho y los filtros son menús desplegables (details/summary) en una barra. */
/* Padding lateral = el del header (clamp…2.4rem) para que el catálogo arranque justo
   bajo el logo y aproveche el ancho (gutter menor que el genérico --gutter). */
/* El catálogo cuelga del RAÍL (el margen del logo), no de una columna centrada: en
   una marca de moda la foto es el argumento de venta y el blanco lateral no vende
   nada. Con --rail-x el contenido llega al mismo borde que la cabecera y solo se
   frena en --maxw-wide (2400), para que un 4K no dibuje una fila de 30 prendas. */
.page.catalog-top { max-width:none; margin:0; padding:2.4rem var(--rail-x) 4.5rem; display:block; }
/* …salvo en LISTADO. Ahí cada artículo es un RENGLÓN (nombre, referencia, atributos y
   matriz de tallas en línea): a 2400px de ancho el ojo pierde el renglón y la última
   casilla de talla queda a medio metro del nombre. La vista de listado conserva por
   eso la medida de lectura, y la conservan CON ella la cinta, el titular y los
   filtros: si solo se capase la lista, la barra de filtros mediría el doble que las
   filas y la página parecería rota. El interruptor es la clase que ya ponía
   catalog.js al conmutar la vista (#list.is-grid), leída con :has(). */
.catalog-top:has(#list:not(.is-grid)) > * { max-width:var(--read-w); margin-inline:auto; }
/* ── BARRA DE FILTROS · banda editorial ────────────────────────────────────────
   Eran seis cajas con filete y chevron puestas en fila: leídas juntas no decían
   «afina el catálogo», decían «rellena un formulario», y encima repetían el gesto
   de la cinta de familias que va justo encima, que sí está en el idioma del
   portal (versal pequeña sobre un hilo).
   La barra pasa a ser UNA banda entre dos hilos, con los rótulos como TIPOGRAFÍA
   y no como controles: separadores de 1px en vez de seis marcos, y el estado
   activo dicho con el rojo de marca y un filete de 2px debajo —el mismo signo que
   ya usa la pestaña activa de la cinta—. Menos tinta, misma función.
   Se diferencia de la cinta a propósito: la cinta NAVEGA (versal, es el «dónde
   estoy») y la barra AFINA (caja baja, es el «qué quito»). Dos registros. */
.cat-filters { display:flex; flex-wrap:wrap; align-items:stretch; gap:0 .2rem; margin:0 0 1.8rem;
  border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
/* Buscador: campo de HILO, no de caja — es el mismo tratamiento que la búsqueda de
   la cabecera, así el comprador reconoce el gesto. El filete se enciende al foco. */
.cat-search { position:relative; flex:1 1 14rem; max-width:20rem; display:flex; align-items:center;
  padding-inline:.85rem; }
/* Hilo en reposo (no transparente): sin él, dentro de la banda el buscador se leía
   como un rótulo más y no como un sitio donde escribir. Es el mismo campo subrayado
   que la búsqueda de la cabecera, así que el gesto ya se reconoce. */
.cat-search input { width:100%; border:none; border-bottom:1px solid var(--line-control); border-radius:0;
  background:none; padding:.42rem .2rem .42rem 1.6rem; font-size:.9rem;
  transition:border-color .15s var(--ease); }
.cat-search svg { position:absolute; left:.95rem; top:50%; translate:0 -50%; color:var(--muted); }
.cat-search input:focus { outline:none; border-bottom-color:var(--blue); }
.cat-search input:focus-visible { outline:2px solid var(--blue); outline-offset:2px; }
/* La entrega abre la banda y el buscador viene detrás: el hilo va entre los dos. */
.cat-lookup-window + .cat-search { border-left:1px solid var(--line); }

/* Cada faceta: rótulo + valor + chevron, sin marco. El hilo vertical de la
   izquierda es lo único que las separa. */
.cat-lookup { position:relative; display:flex; }
.cat-lookup + .cat-lookup > summary,
.cat-search + .cat-lookup > summary { border-left:1px solid var(--line); }
.cat-lookup > summary { list-style:none; cursor:pointer; display:inline-flex; align-items:center; gap:.4rem;
  border:none; background:none; padding:.72rem .85rem; font-size:.88rem; color:var(--ink-2);
  white-space:nowrap; user-select:none; border-bottom:2px solid transparent; margin-bottom:-1px;
  transition:color .12s var(--ease), border-color .12s var(--ease); }
.cat-lookup > summary::-webkit-details-marker { display:none; }
.cat-lookup > summary:hover { color:var(--ink); }
.cat-lookup[open] > summary { color:var(--ink); border-bottom-color:var(--line-control); }
/* Faceta CON valor puesto: el rojo de marca y el filete de 2px, como la pestaña
   activa de la cinta. Es la única tinta de color de toda la barra, así que lo que
   está filtrado se ve de un vistazo sin leer los chips. */
.cat-lookup.active > summary { color:var(--blue-text); font-weight:600; border-bottom-color:var(--blue); }
.cat-lookup .lk-count { color:var(--blue-text); font-weight:700; }
.cat-lookup > summary svg { color:var(--muted); transition:rotate .15s var(--ease); }
.cat-lookup[open] > summary svg { rotate:180deg; }
/* Anillo INTERIOR: el summary llega al borde de la banda y con offset positivo el
   anillo se comía el hilo de la faceta vecina. */
.cat-lookup > summary:focus-visible { outline:2px solid var(--blue); outline-offset:-2px; }
.cat-lookup-panel { position:absolute; z-index:15; top:calc(100% + .35rem); left:0; min-width:14rem; max-width:22rem;
  background:#fff; border:1px solid var(--line); box-shadow:var(--shadow-card); padding:.5rem; }
.cat-lookup-panel.scroll { max-height:19rem; overflow-y:auto; overscroll-behavior:contain; }
.lk-line { display:block; width:100%; text-align:left; padding:.44rem .6rem; font-size:.9rem; color:var(--ink-2); }
.lk-line:hover { background:var(--surface); color:var(--ink); }
.lk-line.on { color:var(--blue-text); font-weight:700; }
.cat-check { display:flex; align-items:center; gap:.55rem; padding:.36rem .6rem; cursor:pointer; font-size:.9rem; color:var(--ink-2); }
.cat-check:hover { background:var(--surface); color:var(--ink); }
.cat-check input { appearance:none; width:1.1rem; height:1.1rem; flex:none; border:1.5px solid var(--line-control);
  background:#fff; display:grid; place-items:center; }
.cat-check input:checked { background:var(--blue); border-color:var(--blue); }
.cat-check input:checked::after { content:""; width:.44rem; height:.24rem; border-left:2px solid #fff;
  border-bottom:2px solid #fff; rotate:-45deg; translate:0 -1px; }

/* Opción que con los filtros puestos daría CERO resultados. Se enseña —esconderla se lee
   como un filtro roto: «he filtrado Sudaderas y ha desaparecido el rojo»— pero no se puede
   marcar. El input va `disabled` de verdad (catalog.js), así que esto es el aviso visual.
   Estaba en --muted (#6a6666) contra el --ink-2 (#605d5d) de una opción viva: 1,13:1 entre
   las dos, imperceptible. El único indicio real era `cursor:not-allowed`, que en táctil no
   existe y en escritorio solo aparece si el ratón se para encima, así que se pinchaba
   «Camisas» y el portal no reaccionaba — un botón que no responde se lee como aplicación
   colgada. Ahora baja a --muted-2, que es el gris de deshabilitado del portal (el mismo de
   .product-doc[disabled]), y el recuento «0» de al lado explica POR QUÉ está apagada: el
   estado se entiende sin ratón y sin depender del color. El contraste de texto ya no tiene
   que sostener él solo el mensaje —y WCAG no se lo pide a un control inactivo. */
.cat-check.is-dead, .lk-line.is-dead { color:var(--muted-2); cursor:not-allowed; }
.cat-check.is-dead:hover, .lk-line.is-dead:hover { background:none; color:var(--muted-2); }
/* Recuento de la sección, a la derecha de su nombre (mismo lenguaje que .rib-count de la
   cinta). Solo las líneas de SECCIÓN se vuelven flex: las de ENTREGA apilan su nombre y
   sus fechas (.lk-line-sub) y ahí el bloque es lo correcto. */
.lk-line[data-family] { display:flex; align-items:baseline; justify-content:space-between; gap:.8rem; }
.lk-line-n { font-size:.72rem; font-weight:600; color:var(--muted); font-variant-numeric:tabular-nums; }
.lk-line.on .lk-line-n { color:var(--blue-text); }
.lk-line.is-dead .lk-line-n { color:var(--muted-2); }
.cat-check.is-dead input { border-color:var(--line); background:var(--surface); }

/* ── ENTREGA · el primer filtro de la fila ─────────────────────────────────────
   Es UNA faceta más (misma banda, mismo hilo, mismo chevron) porque desde el
   carrito multi-entrega elegir entrega ya no cambia de carrito: solo decide para
   cuál estás comprando ahora. Pero no es una faceta cualquiera —decide la fecha de
   servicio y el precio de lo que añades—, así que se distingue por POSICIÓN y por
   PESO, no por forma: va la primera, nunca se pliega en móvil, lleva su rótulo
   («Entrega») siempre visible delante del valor y el valor va en tinta plena.
   Las fechas largas NO caben en un control y no se meten: van en el panel, bajo
   cada nombre, y en la nota de condición que queda bajo la barra. */
/* Va la primera EN EL DOM (no con `order`, que descolocaría el tabulador respecto a
   lo que se ve) y por eso no lleva hilo a su izquierda: abre la banda. */
.cat-lookup-window > summary { color:var(--ink); font-weight:600; border-left:none; }
/* Un solo control por decisión: donde aparece el filtro de entrega se retira el
   conmutador de la barra de herramientas, que hacía lo mismo. En las dos marcas con
   portada propia ya estaba oculto (l. ~3344); esto lo extiende a la marca sin
   heroStyle en vez de dejarle dos mandos para la misma cosa. */
.catalog-top:has(.cat-lookup-window) .tb-window { display:none; }
/* En móvil el hueco de la entrega vive fuera del plegado de «Filtros», encima del
   buscador y a ancho completo. */
.cat-window-slot:empty { display:none; }
.cat-window-slot { flex-basis:100%; }
.lk-label { font-size:.68rem; font-weight:600; letter-spacing:.10em; text-transform:uppercase;
  color:var(--muted); }
.cat-lookup-window[open] > summary .lk-label,
.cat-lookup-window > summary:hover .lk-label { color:var(--ink-2); }
/* Entrada de dos líneas del panel de entregas: nombre corto arriba, fechas debajo.
   Aquí SÍ hay sitio para la ventana de servicio y la fecha de corte. */
.lk-line-sub { display:block; margin-top:.15rem; font-size:.75rem; font-weight:400; color:var(--muted);
  white-space:normal; }
.lk-line.on .lk-line-sub { color:var(--blue-text); }
.cat-lookup-window .cat-lookup-panel { min-width:19rem; }
.cat-lookup-window .lk-line { padding:.55rem .6rem; }

/* Chips de filtros activos: segundo piso de la banda, bajo un hilo propio */
.cat-active { display:flex; flex-wrap:wrap; align-items:center; gap:.4rem; flex-basis:100%;
  border-top:1px solid var(--line); padding:.55rem 0; }
.cat-active:empty { display:none; }
.cat-chip { display:inline-flex; align-items:center; gap:.35rem; border:1px solid var(--line-control);
  background:var(--surface); padding:.3rem .55rem; font-size:.8rem; color:var(--ink);
  transition:border-color .12s var(--ease), color .12s var(--ease); }
.cat-chip:hover { border-color:var(--out); color:var(--out); }
.cat-chip svg { color:var(--muted); }
.cat-chip:hover svg { color:var(--out); }
.cat-clear { color:var(--blue); font-size:.82rem; text-decoration:underline; text-underline-offset:3px; padding:.3rem .3rem; }
.cat-clear:hover { color:var(--blue-deep); }
.cat-lookup-panel { max-width:calc(100vw - 1.5rem); }
/* Vista sin distracciones (ojo del header): oculta los filtros como antes ocultaba el rail */
body[data-focus="on"] .cat-filters { display:none; }
/* Móvil: los filtros pasan a acordeón a ancho completo — el panel fluye BAJO su lookup
   (position:static) en vez de flotar y salirse del viewport por la derecha. */
@media (max-width:48rem) {
  /* En vertical la banda se apila: cada faceta es una fila entre hilos horizontales
     (el hilo vertical no tiene sentido cuando no hay fila). */
  .cat-filters { flex-direction:column; align-items:stretch; gap:0; }
  .cat-search { flex-basis:auto; max-width:none; border-bottom:1px solid var(--line); }
  .cat-lookup { width:100%; display:block; }
  .cat-lookup + .cat-lookup > summary, .cat-search + .cat-lookup > summary { border-left:none; }
  .cat-lookup > summary { width:100%; justify-content:space-between; border-bottom:1px solid var(--line);
    margin-bottom:0; padding-block:.85rem; }
  .cat-lookup.active > summary { border-bottom-color:var(--blue); }
  .cat-lookup-panel { position:static; box-shadow:none; border:1px solid var(--line); border-top:none;
    min-width:0; max-width:none; }
  .cat-lookup-panel.scroll { max-height:14rem; }
  /* La ENTREGA nunca se pliega dentro de «Filtros»: el comprador tiene que saber
     para qué fecha de servicio está metiendo unidades sin abrir nada. Por eso vive
     fuera del desplegable de móvil (lo coloca catalog.js) y aquí solo se asegura de
     que se lea como una fila completa. */
  .cat-lookup-window > summary { padding-block:.9rem; }
  .cat-active { padding:.6rem 0; }
}

/* ── Cinta de navegación del catálogo (banda bajo CATÁLOGO|LOOKBOOK) ──
   Pestañas editoriales sobre una regla fina: MAYÚSCULAS pequeñas, activo con la
   regla de 2px en el rojo de marca (mismo lenguaje que el nav del chrome pero un
   peso por debajo: la cinta es sub-navegación, no compite con CATÁLOGO|LOOKBOOK).
   El recuento va como numeral diminuto y apagado, a lo índice de revista. */
/* gap:0 — la regla inferior del raíl y la de las flechas forman UNA línea continua */
.cat-ribbon { position:relative; display:flex; align-items:stretch; gap:0; margin:-.6rem 0 1.9rem; }
.cat-ribbon[hidden] { display:none; }
/* Hueco reservado mientras llega el catálogo, con la altura exacta de la cinta ya
   pintada: al aparecer no empuja nada de lo que hay debajo (UX-M4). */
.cat-ribbon.is-pending { min-height:2.6rem; border-bottom:1px solid var(--line); }
.rib-rail { flex:1; min-width:0; display:flex; align-items:stretch; gap:1.9rem;
  overflow-x:auto; scroll-snap-type:x proximity; overscroll-behavior-x:contain;
  scrollbar-width:none; border-bottom:1px solid var(--line); }
.rib-rail::-webkit-scrollbar { display:none; }
.rib-chip { scroll-snap-align:start; flex:none; display:inline-flex; align-items:baseline; gap:.32rem;
  padding:.6rem .1rem; font-size:.8rem; font-weight:600; letter-spacing:.07em; text-transform:uppercase;
  color:var(--ink-2); border-bottom:2px solid transparent; margin-bottom:-1px; white-space:nowrap;
  transition:color .12s var(--ease), border-color .12s var(--ease); }
.rib-chip:hover { color:var(--ink); }
/* Anillo INTERIOR (offset negativo), obligatorio aquí: `.rib-rail` es contenedor de
   scroll (overflow-x:auto ⇒ overflow-y calculado auto) y los chips, estirados por
   align-items:stretch, miden justo el alto del raíl; con offset POSITIVO el anillo
   cae fuera del scrollport y se recorta entero (WCAG 2.4.7). El activo no pierde
   nada: su regla de 2px es del mismo --blue que el anillo. */
.rib-chip:focus-visible { outline:2px solid var(--blue); outline-offset:-2px; }
.rib-chip.on { color:var(--blue-text); border-bottom-color:var(--blue); }
.rib-count { font-size:.68rem; font-weight:600; color:var(--muted); letter-spacing:.02em; translate:0 -.32em; }
.rib-chip.on .rib-count { color:var(--blue-text); }
/* Pestaña que con los filtros puestos daría cero: la cinta es una segunda superficie de
   filtro sobre el mismo `query`, así que se apaga igual que la opción del desplegable de
   abajo (y su recuento vivo, ya a 0, dice por qué). Antes se quedaba encendida prometiendo
   «12 artículos» y al pulsarla la pantalla aparecía vacía. */
.rib-chip.is-dead, .rib-chip.is-dead:hover { color:var(--muted-2); cursor:not-allowed; border-bottom-color:transparent; }
.rib-chip.is-dead .rib-count { color:var(--muted-2); }
/* Cambio de plano (familias, y luego cada atributo de /manage): separador fino */
.rib-sep { flex:none; width:1px; background:var(--line); margin:.55rem 0 .7rem; }
/* Flechas: solo si el raíl desborda, SUPERPUESTAS a los extremos — así no roban
   ancho y "TODO" queda a plomo con el H1 (D-M1). El desvanecido del propio raíl es
   lo que insinúa que hay más; la flecha anterior no existe hasta que hace falta. */
.rib-arrow { display:none; }
.cat-ribbon.has-nav .rib-arrow { position:absolute; top:0; bottom:1px; z-index:1;
  display:inline-flex; align-items:center; justify-content:center; width:1.75rem;
  color:var(--ink); transition:color .12s var(--ease); }
.cat-ribbon.has-nav .rib-prev { left:0; justify-content:flex-start; }
.cat-ribbon.has-nav .rib-next { right:0; justify-content:flex-end; }
/* NINGUNA flecha apagada se queda flotando sobre las pestañas: al estar superpuestas,
   una <button disabled> no despacha el clic NI lo deja pasar al chip de debajo (28px
   de zona muerta) y su chevron se dibuja encima del recuento. */
.cat-ribbon.has-nav .rib-arrow[disabled] { display:none; }
.cat-ribbon.has-nav .rib-rail {
  /* Las flechas van superpuestas: sin este relleno de scroll el snap deja pestañas
     aparcadas DEBAJO de ellas (1,75rem de texto que se lee pero no recibe el clic). */
  scroll-padding-inline:1.75rem;
  -webkit-mask-image:linear-gradient(to right, transparent, #000 2rem, #000 calc(100% - 2rem), transparent);
  mask-image:linear-gradient(to right, transparent, #000 2rem, #000 calc(100% - 2rem), transparent); }
.cat-ribbon.has-nav.at-start .rib-rail {
  -webkit-mask-image:linear-gradient(to right, #000 calc(100% - 2rem), transparent);
  mask-image:linear-gradient(to right, #000 calc(100% - 2rem), transparent); }
.cat-ribbon.has-nav.at-end .rib-rail {
  -webkit-mask-image:linear-gradient(to right, transparent, #000 2rem);
  mask-image:linear-gradient(to right, transparent, #000 2rem); }
.cat-ribbon.has-nav.at-start.at-end .rib-rail { -webkit-mask-image:none; mask-image:none; }
.rib-arrow:hover:not([disabled]) { color:var(--blue); }
/* pointer-events:none es cinturón y tirantes del display:none de arriba: si alguna vez
   una flecha apagada volviese a verse, no puede robarle el clic al chip que tapa. */
.rib-arrow[disabled] { opacity:.45; cursor:default; pointer-events:none; }
.rib-arrow svg { flex:none; }
/* Línea de contexto (<=1 entrada): "Tu surtido: Calzado · 38 artículos", mismo hueco */
.cat-context { flex:1; min-width:0; display:flex; align-items:center; gap:.45rem; margin:0; padding:.62rem 0;
  font-size:.8rem; font-weight:600; letter-spacing:.06em; text-transform:uppercase; color:var(--ink-2);
  border-bottom:1px solid var(--line); }
.cat-context svg { flex:none; color:var(--muted); }
.cat-context span { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* "Catálogo adaptado a tu cuenta": junto al recuento, en cuanto hay reglas que aplicar */
.cat-adapted { display:inline-flex; align-items:center; gap:.3rem; margin-left:.7rem; vertical-align:middle;
  font-size:.7rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--hint);
  border:1px solid var(--line-control); padding:.14rem .5rem; white-space:nowrap; }
.cat-adapted[hidden] { display:none; }
.cat-adapted svg { flex:none; }
/* Huecos reservados de la barra de herramientas y de los filtros mientras carga (UX-M4).
   Van atados a la MISMA señal de "primera carga en vuelo" que la cinta (.is-pending, que
   catalog.js retira tanto al pintar como al fallar): si el catálogo da error, tools y
   filtros se quedan vacíos para siempre y sin esto dejaban 5,4rem de bloques fantasma
   colgando sobre el panel de error. */
.catalog-top:has(.cat-ribbon.is-pending) .cat-bar #tools:empty { min-height:2.6rem; }
.catalog-top:has(.cat-ribbon.is-pending) .cat-filters:empty { min-height:2.8rem; }
/* Vista sin distracciones (ojo del header): la cinta se va con los filtros */
body[data-focus="on"] .cat-ribbon { display:none; }
@media (max-width:48rem) {
  .cat-ribbon { margin:-.4rem 0 1.5rem; }
  .cat-ribbon.has-nav .rib-arrow { display:none; }   /* táctil: dedo + snap */
  .cat-ribbon.has-nav .rib-rail, .cat-ribbon.has-nav.at-start .rib-rail,
  .cat-ribbon.has-nav.at-end .rib-rail { -webkit-mask-image:none; mask-image:none; }
  .rib-rail { gap:1.4rem; scroll-snap-type:x mandatory; }
  .rib-chip { padding:.72rem .1rem; }                /* área táctil más generosa */
  .cat-adapted { margin-left:0; margin-top:.3rem; }
}

/* Fila de artículo */
.item { display:grid; grid-template-columns:17rem minmax(0,1fr);
  grid-template-areas:"photo info" "photo matrix"; column-gap:2.4rem; row-gap:1.6rem;
  /* El divisor entre filas toma el COLOR del filete de marca (como el hilo de la cabecera):
     con `rule` configurado, un solo lenguaje de regla en toda la sesión; sin él, el gris. */
  align-items:start; padding:2.4rem 0; border-bottom:1px solid var(--brand-rule,var(--line)); }
.item-photo { grid-area:photo; }
/* En filas anchas el bloque de texto (título + ref + atributos + precio) se acota a
   una medida legible para que el corazón no flote lejos del nombre; la matriz de
   tallas sí aprovecha todo el ancho de la fila (ver .item-matrix). */
.item-info { grid-area:info; min-width:0; max-width:52rem; }
.item-matrix { grid-area:matrix; min-width:0; align-self:end; }
.item:first-child { padding-top:.6rem; }
.item-photo { aspect-ratio:4/5; background:var(--surface); border-radius:var(--r); display:grid;
  place-items:center; overflow:hidden; }
.item-photo img { width:100%; height:100%; object-fit:cover; transition:scale .5s var(--ease); }
@media (hover:hover) { .item:hover .item-photo img { scale:1.04; } }   /* táctil: sin :hover pegado */
.item-art { color:var(--ink); opacity:.2; }

.item-title { display:flex; align-items:flex-start; gap:1rem; }
/* Nombre de artículo en serif, peso medio y sin forzar mayúsculas (el dato ya viene
   en mayúsculas): editorial, no lápida. */
.item h2 { font-family:var(--display); font-weight:500; font-size:1.35rem; line-height:1.15;
  letter-spacing:var(--brand-tracking,0); margin:0; text-transform:var(--brand-caps,none); flex:1; }
.item-fav { color:var(--ink); padding:.15rem; border-radius:6px; flex:none;
  transition:color .15s var(--ease), scale .15s var(--ease); }
.item-fav:hover { scale:1.1; }
.item-fav[aria-pressed="true"] { color:var(--accent); }

.item-ref { margin:.85rem 0 0; font-size:.92rem; color:var(--ink-2); }
.item-ref b { font-weight:600; color:var(--ink); }
/* En rejilla los pares dt/dd quedan alineados entre artículos, en vez de bailar
   según la longitud del valor anterior (flex + wrap) */
.item-attrs { display:flex; flex-wrap:wrap; gap:.4rem; margin:.9rem 0 0; }
.item-attrs .tag { display:inline-flex; align-items:center; font-size:.68rem; font-weight:700;
  letter-spacing:.05em; text-transform:uppercase; color:var(--ink); background:none;
  border:1px solid var(--line-control); border-radius:0; padding:.24rem .55rem; }
/* En la ficha el rótulo PVD va encima del precio; junto a la matriz, en línea */
.item-price { display:flex; align-items:baseline; gap:.7rem; margin:1.1rem 0 0; }
.item-info .item-price { flex-direction:column; align-items:flex-start; gap:.1rem; }
.item-price span { font-size:.9rem; color:var(--ink-2); }
.item-price b { font-family:var(--display); font-size:1.7rem; letter-spacing:-.02em; }
.item-pvp { margin:.2rem 0 0; color:var(--muted); font-size:.85rem; }
.item-matrix .matrix-price { margin-top:1rem; }
.item-matrix .matrix-price b { font-size:1.35rem; }
.item-units { background:var(--blue-soft); color:var(--blue-soft-text); border-radius:999px;
  padding:.2rem .7rem; font-size:.75rem; font-weight:700; }

/* Matriz de tallas: 8 celdas por fila con cabecera negra */
/* El ancho mínimo lo marca la celda más ancha posible: "0" + "(+99)" */
/* Matriz en UNA fila (36→46): las celdas reparten el ancho de la fila hasta un tope
   (no se estiran con 1 sola talla), a la izquierda; sólo hay scroll si no cupieran. */
/* Suelo de 3.4rem por columna: con minmax(0,…) las columnas implícitas se ENCOGÍAN a 0
   antes de que actuara el overflow-x (tallas de 8px sin poder teclear, WCAG 2.5.8). Con
   suelo, muchas tallas desbordan con scroll en vez de aplastarse. */
.matrix { display:grid; grid-auto-flow:column; grid-auto-columns:minmax(3.4rem,4.4rem); gap:.4rem;
  justify-content:start; max-width:none; overflow-x:auto; padding-bottom:.15rem; }
.matrix.wide { grid-auto-columns:minmax(3.6rem,5rem); }
.sz-cell { display:flex; flex-direction:column; gap:.28rem; min-width:0; }
/* Disponibilidad SIEMPRE debajo del cuadro, centrada y legible (no dentro) */
.sz-cell .sz-stock { display:flex; justify-content:center; align-items:center; gap:.25rem;
  width:100%; text-align:center; font-size:.74rem; font-variant-numeric:tabular-nums;
  color:var(--ink-2); white-space:nowrap; overflow:visible; }
/* Precio por talla (kids): el importe va ENCIMA de la caja; la cabecera negra sólo
   lleva la talla, así no se recorta ni se pisan talla y precio. */
.sz-price-top { display:block; width:100%; text-align:center; font-size:.62rem; font-weight:700;
  color:var(--ink-2); font-variant-numeric:tabular-nums; white-space:nowrap; line-height:1.15;
  overflow:hidden; text-overflow:ellipsis; }
.sz-head .sz-size { margin:0; }
/* La cantidad va centrada y ocupando la celda (antes salía a la izquierda/recortada) */
.sz-body { padding:.28rem .15rem; }
.sz-qty { width:100%; text-align:center; }
.sz { border:1px solid var(--line); background:#fff; overflow:hidden;
  transition:border-color .12s var(--ease), box-shadow .12s var(--ease); }
.sz:focus-within { border-color:var(--blue); box-shadow:0 0 0 3px color-mix(in srgb,var(--blue) 14%,transparent); }
/* m9: la cifra de talla va pegada a la izquierda de la cabecera negra, como en la
   referencia; el precio por talla (kids) se va al extremo contrario. */
/* Cabecera de talla "silenciosa": tinte arena con tinta oscura; sólida (verde) solo
   cuando la talla está seleccionada (.sz.has). Antes era un muro casi-negro. */
.sz-head { background:var(--surface); color:var(--ink); display:flex; align-items:center; justify-content:center;
  gap:.35rem; padding:.28rem .4rem; font-size:.76rem; font-weight:700; border-bottom:1px solid var(--line); }
.sz-size { margin-right:auto; }
.sz-price { font-weight:600; font-size:.72rem; white-space:nowrap; }

/* F-02: artículo sin stock en ninguna talla → "Consultar" bajo la matriz */
.matrix-consult { margin:.6rem 0 0; max-width:45rem; }
.matrix-consult a { color:var(--blue); font-weight:700; font-size:.9rem; text-underline-offset:3px; }
.matrix-consult a:hover { color:var(--blue-deep); }
.sz-body { display:flex; align-items:center; justify-content:center; gap:.2rem; padding:.28rem .25rem; }
.sz-qty { width:2.1rem; border:none; background:transparent; padding:.1rem 0; font-weight:600;
  -moz-appearance:textfield; }
.sz-qty::-webkit-outer-spin-button, .sz-qty::-webkit-inner-spin-button { appearance:none; margin:0; }
/* El teclado tiene que ver DÓNDE está dentro de la matriz: el foco se marca en la
   celda (halo azul) y en el propio campo, sin desbordar la caja de la talla. */
.sz-qty:focus-visible { outline:2px solid var(--blue); outline-offset:-2px; border-radius:3px; }
.sz:has(.sz-qty:focus-visible) { border-color:var(--blue); box-shadow:0 0 0 2px var(--blue); }
.sz-stock { display:inline-flex; align-items:center; gap:.22rem; font-size:.76rem; color:var(--muted); }
.sz-stock i { width:.42rem; height:.42rem; border-radius:50%; flex:none; }
.sz.low .sz-stock i { background:var(--low); }
.sz.out .sz-stock i { background:var(--out); }
.sz.out .sz-qty { color:var(--muted); background:transparent; }
.sz.inf .sz-stock { color:var(--blue); font-weight:700; }
.sz.has { border-color:var(--blue); box-shadow:0 0 0 1px var(--blue); }
.sz.has .sz-head { background:var(--blue); color:#fff; border-bottom-color:var(--blue); }
.sz.has .sz-qty { color:var(--blue); font-weight:700; }

/* ── Cuadrícula del catálogo (referencia thehoffbrand.com) ──
   Tarjetas limpias con foto 4:5 protagonista y mucho aire; 2–4 columnas según ancho.
   Toda la tarjeta navega a la ficha con un enlace estirado; el corazón queda encima. */
/* ── ESCALA DE COLUMNAS ────────────────────────────────────────────────────────
   El número de columnas se DECIDE, no se deja a `auto-fill minmax()`. Con auto-fill
   la retícula reparte el sobrante entre las columnas que quepan, así que la tarjeta
   crecía o encogía según el resto de la división: a 1920 y a 2560 daba lo mismo (4
   columnas de 359) porque la página estaba capada, y en 390 una marca podía dejarla
   en UNA columna sin que nadie lo hubiera decidido.
   Aquí la escala es explícita y el ancho de la tarjeta es la consecuencia. Está
   calibrada para que la foto se mantenga en una banda de ~290-365 px, que es donde
   una prenda se lee sin lupa y sin ocupar media pantalla:
     390 → 2 col · 175px   768 → 3 col · 230px   1280 → 4 col · 295px
    1440 → 4 col · 335px  1920 → 5 col · 362px   2560 → 7 col · 348px
   Los gaps son tokens para que una marca pueda apretar o airear la retícula SIN
   volver a declarar grid-template-columns (que es lo que rompía el móvil: la regla
   de marca tenía más especificidad que la media query de 48rem y se la comía). */
.cat-grid { --cols:2; --cat-gap-x:1.6rem; --cat-gap-y:2.2rem;
  display:grid; grid-template-columns:repeat(var(--cols),minmax(0,1fr));
  gap:var(--cat-gap-y) var(--cat-gap-x); }
@media (min-width:48rem)  { .cat-grid { --cols:3; } }
@media (min-width:80rem)  { .cat-grid { --cols:4; } }
@media (min-width:105rem) { .cat-grid { --cols:5; } }
@media (min-width:140rem) { .cat-grid { --cols:6; } }
@media (min-width:160rem) { .cat-grid { --cols:7; } }
.pcard { position:relative; display:flex; flex-direction:column; }
.pcard-media { position:relative; aspect-ratio:4/5; background:var(--surface); border-radius:var(--r);
  overflow:hidden; display:grid; place-items:center; }
.pcard-media img { width:100%; height:100%; object-fit:cover; transition:scale .5s var(--ease); }
@media (hover:hover) { .pcard:hover .pcard-media img { scale:1.05; } }   /* táctil: sin :hover pegado */
.pcard-media .item-art { color:var(--ink); opacity:.2; }
/* El corazón flota sobre la foto, en una pastilla crema translúcida */
.pcard-fav { position:absolute; top:.7rem; right:.7rem; z-index:2; width:2.2rem; height:2.2rem;
  border-radius:50%; display:grid; place-items:center; color:var(--ink); background:rgba(255,253,248,.88);
  box-shadow:var(--shadow); transition:color .15s var(--ease), scale .15s var(--ease), background .15s var(--ease); }
.pcard-fav:hover { scale:1.08; background:#fff; }
.pcard-fav[aria-pressed="true"] { color:var(--accent); }

.pcard-body { display:flex; flex-direction:column; padding:.95rem .15rem 0; }
.pcard-name { margin:0; font-family:var(--display); font-weight:500; font-size:1.12rem; line-height:1.2;
  letter-spacing:var(--brand-tracking,0); text-transform:var(--brand-caps,none); transition:color .15s var(--ease); }
.pcard-name a { text-decoration:none; }
/* Enlace estirado: cubre toda la tarjeta sin robar el clic al corazón (z-index 1<2) */
.pcard-link::after { content:""; position:absolute; inset:0; z-index:1; border-radius:var(--r); }
.pcard:hover .pcard-name { color:var(--blue); }
.pcard-ref { margin:.3rem 0 0; font-size:.82rem; color:var(--muted); }
.pcard-ref b { color:var(--ink-2); font-weight:600; }
.pcard-price { display:flex; align-items:baseline; gap:.5rem; margin:.6rem 0 0; }
.pcard-price span { font-size:.78rem; color:var(--muted); }
.pcard-price b { font-family:var(--display); font-size:1.3rem; letter-spacing:-.02em; }
.pcard-cta { display:inline-flex; align-items:center; gap:.4rem; margin-top:.7rem; font-size:.74rem;
  font-weight:700; letter-spacing:.09em; text-transform:uppercase; color:var(--ink);
  transition:gap .15s var(--ease), color .15s var(--ease); }
.pcard:hover .pcard-cta { gap:.7rem; color:var(--blue); }
.pcard-cta svg { flex:none; }
.pcard-link:focus-visible::after { outline:2px solid var(--blue); outline-offset:3px; }
/* Un solo anillo de foco por card: el del ::after estirado (el outline nativo del
   enlace dibujaba un segundo anillo pegado al nombre). */
.pcard-link:focus-visible { outline:none; }

/* ══════════════ Ficha de producto (estilo thehoffbrand.com) ══════════════ */
/* Foto protagonista a la izquierda (pegajosa al hacer scroll) y ficha aireada a la
   derecha con la MISMA matriz de tallas del catálogo. Mucho aire, filetes finos. */
.page.product { padding-top:2rem; }
.product .crumbs { margin-bottom:1.7rem; }
.product .crumbs a { text-decoration:none; }
.product .crumbs a:hover { color:var(--blue); }

.product-grid { display:grid; grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);
  gap:clamp(1.6rem,4vw,3.6rem); align-items:start; }
.product-media { margin:0; position:sticky; top:calc(var(--header-h) + 1.5rem); }

/* ── Visor multi-ángulo (giro 360 con fotogramas + zoom) ── */
.viewer { display:flex; flex-direction:column; gap:.8rem; }
.viewer-stage { position:relative; aspect-ratio:4/5; background:var(--card); border:1px solid var(--line);
  border-radius:var(--r); overflow:hidden; display:grid; place-items:center; }
.viewer-spin .viewer-stage { cursor:grab; touch-action:pan-y; }
.viewer-spin.dragging .viewer-stage { cursor:grabbing; }
.viewer-frame { grid-area:1 / 1; width:100%; height:100%; object-fit:contain; display:block;
  opacity:0; transition:opacity .08s var(--ease); user-select:none; -webkit-user-drag:none; }
.viewer-frame.on { opacity:1; }
.viewer-empty { aspect-ratio:4/5; background:var(--surface); border-radius:var(--r); display:grid; place-items:center; }
.viewer-empty .item-art { color:var(--ink); opacity:.2; }

.viewer-badge { position:absolute; top:.8rem; left:.8rem; z-index:2; display:inline-flex; align-items:center; gap:.35rem;
  background:var(--blue); color:#fff; font-size:.72rem; font-weight:700; letter-spacing:.04em;
  padding:.28rem .6rem .28rem .5rem; border-radius:999px; }
.viewer-badge svg { display:block; }
.viewer-zoom { position:absolute; top:.8rem; right:.8rem; z-index:2; width:2rem; height:2rem; display:grid; place-items:center;
  background:rgba(255,255,255,.92); color:var(--ink); border:none; border-radius:50%; box-shadow:var(--shadow-card);
  cursor:pointer; opacity:.55; transition:opacity .2s; }
.viewer-stage:hover .viewer-zoom, .viewer-zoom:focus-visible { opacity:1; }
.viewer-hint { position:absolute; bottom:.8rem; left:50%; translate:-50% 0; z-index:2; font-size:.74rem; color:var(--ink-2);
  background:color-mix(in srgb,var(--paper) 90%,transparent); padding:.25rem .75rem; border-radius:999px; pointer-events:none; transition:opacity .3s; }
.viewer-hint.gone { opacity:0; }

.viewer-controls { display:grid; grid-template-columns:auto minmax(0,1fr) auto; gap:.5rem; align-items:center; }
.viewer-nav { width:2.2rem; height:2.2rem; flex:none; display:grid; place-items:center; border:1px solid var(--line);
  background:var(--card); border-radius:50%; color:var(--ink-2); cursor:pointer; transition:border-color .15s, color .15s; }
.viewer-nav:hover { border-color:var(--blue); color:var(--blue); }
.viewer-thumbs { display:flex; gap:.5rem; overflow-x:auto; padding:.15rem; scrollbar-width:thin; min-width:0; }
.viewer-thumb { flex:none; width:3.4rem; aspect-ratio:1/1; padding:0; border:1px solid var(--line); border-radius:var(--r-sm);
  overflow:hidden; background:var(--card); cursor:pointer; opacity:.65; transition:opacity .15s, border-color .15s, box-shadow .15s; }
.viewer-thumb img { width:100%; height:100%; object-fit:contain; display:block; }
.viewer-thumb:hover { opacity:1; }
.viewer-thumb.on { opacity:1; border-color:var(--blue); box-shadow:0 0 0 1px var(--blue); }

.viewer-lightbox { position:fixed; inset:0; z-index:100; background:rgba(23,20,16,.9); display:grid; place-items:center;
  padding:clamp(1rem,4vw,3rem); opacity:0; transition:opacity .2s; cursor:zoom-out; }
.viewer-lightbox.on { opacity:1; }
.viewer-lightbox img { max-width:100%; max-height:100%; object-fit:contain; border-radius:var(--r-sm); }
.viewer-lightbox-close { position:absolute; top:1.2rem; right:1.4rem; width:2.6rem; height:2.6rem; border:none;
  background:rgba(255,255,255,.16); color:#fff; border-radius:50%; font-size:1.05rem; cursor:pointer; }
.viewer-lightbox-close:hover { background:rgba(255,255,255,.3); }

/* Badge 360° en las tarjetas del lookbook + quick-view modal */
.pcard-360 { position:absolute; top:.6rem; left:.6rem; z-index:3; display:inline-flex; align-items:center; gap:.25rem;
  background:var(--ink); color:#fff; border:none; border-radius:0; padding:.2rem .55rem;
  font:inherit; font-size:.7rem; font-weight:700; letter-spacing:.02em; cursor:pointer; transition:background .15s; }
.pcard-360:hover { background:var(--blue-deep); }
.viewer-modal { position:fixed; inset:0; z-index:100; background:rgba(23,20,16,.6); display:grid; place-items:center;
  padding:clamp(1rem,4vw,2.5rem); opacity:0; transition:opacity .2s; }
.viewer-modal.on { opacity:1; }
.viewer-modal-box { position:relative; background:var(--card); border-radius:var(--r); box-shadow:var(--shadow-card);
  width:min(30rem,95vw); max-height:90vh; overflow:auto; padding:1.2rem; }
.viewer-modal-close { position:absolute; top:.7rem; right:.7rem; z-index:4; width:2rem; height:2rem; border:none;
  background:var(--surface); color:var(--ink); border-radius:50%; cursor:pointer; font-size:.9rem; }
.viewer-modal-close:hover { background:var(--line); }
.viewer-modal-name { font-family:var(--display); font-size:1.1rem; margin:0 2rem .8rem 0; color:var(--ink); }

/* ── Cuadros de mando ── */
/* Barra de filtros del cuadro de mando: es la MISMA de la tienda (.cat-filters con
   sus lookups y sus chips), a propósito. El comprador ya sabe filtrar en el catálogo;
   no tiene por qué aprender otro gesto para filtrar sus cifras. */
.bd-filters { margin-bottom:1.6rem; }
.bd-filters .cat-lookup-panel { min-width:15rem; }
.bd-kpis { display:grid; grid-template-columns:repeat(auto-fit,minmax(9rem,1fr)); gap:1rem; margin-bottom:1.6rem; }
.bd-kpi { background:var(--card); border:1px solid var(--line); border-radius:var(--r); padding:1rem 1.1rem; }
.bd-kpi-label { display:block; font-size:.72rem; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); }
.bd-kpi-value { display:block; margin-top:.3rem; font-family:var(--display); font-size:1.7rem; letter-spacing:-.02em; color:var(--ink); }
.bd-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:1.4rem; }
.bd-panel { background:var(--card); border:1px solid var(--line); border-radius:var(--r); padding:1.1rem 1.2rem 1.3rem; min-width:0; }
.bd-panel.bd-wide { grid-column:1 / -1; }
.bd-panel h2 { font-family:var(--display); font-size:1.1rem; margin:0 0 1rem; color:var(--ink); }
.bd-panel-body { min-width:0; }

.ch { width:100%; height:auto; display:block; overflow:visible; }
.ch-tick line { stroke:var(--line); stroke-width:1; }
.ch-tick text { fill:var(--muted); font-size:13px; }
.ch-bar rect { fill:var(--blue); transition:fill .15s var(--ease); }
.ch-bar:hover rect { fill:var(--blue-deep); }
.ch-xlab { fill:var(--ink-2); font-size:13px; }
.ch-empty { fill:var(--muted); font-size:15px; }

.ch-hbars { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:.75rem; }
.ch-hbars li { min-width:0; }
.ch-hbar-top { display:flex; align-items:baseline; gap:.6rem; margin-bottom:.28rem; }
.ch-hbar-label { flex:1; min-width:0; font-size:.86rem; color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ch-hbar-label em { color:var(--muted); font-style:normal; font-size:.76rem; }
.ch-hbar-val { font-family:var(--display); font-size:.95rem; color:var(--ink); white-space:nowrap; }
.ch-hbar-track { height:.5rem; background:var(--surface); border-radius:999px; overflow:hidden; }
.ch-hbar-track span { display:block; height:100%; background:var(--accent); border-radius:999px; }
.ch-na { color:var(--muted); font-size:.9rem; padding:1.5rem 0; text-align:center; }

.ch-donut { display:flex; align-items:center; gap:1.2rem; flex-wrap:wrap; }
.ch-donut-svg { width:11rem; height:11rem; flex:none; }
.ch-donut-total { font-family:var(--display); font-size:18px; fill:var(--ink); }
.ch-donut-cap { font-size:11px; fill:var(--muted); text-transform:uppercase; letter-spacing:.05em; }
.ch-legend { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:.45rem; flex:1; min-width:9rem; }
.ch-legend li { display:flex; align-items:center; gap:.5rem; font-size:.85rem; color:var(--ink-2); }
.ch-legend b { margin-left:auto; color:var(--ink); font-family:var(--display); }
.ch-dot { width:.8rem; height:.8rem; border-radius:3px; flex:none; }

@media (max-width:52rem) { .bd-grid { grid-template-columns:1fr; } }
.product-skeleton { aspect-ratio:4/5; height:auto; }

.product-panel { min-width:0; }
.product-head { display:flex; align-items:flex-start; gap:1rem; }
.product-name { flex:1; margin:0; font-family:var(--display); font-weight:500;
  font-size:clamp(1.9rem,3.6vw,2.8rem); line-height:1.05; letter-spacing:var(--brand-tracking,-.015em); }
.product-fav { flex:none; color:var(--ink); padding:.3rem; border-radius:8px;
  transition:color .15s var(--ease), scale .15s var(--ease); }
.product-fav:hover { scale:1.1; }
.product-fav[aria-pressed="true"] { color:var(--accent); }
.product-ref { margin:1rem 0 0; font-size:.95rem; color:var(--ink-2); }
.product-ref b { color:var(--ink); font-weight:600; }

/* ── "También en:": la gama como selector de variantes premium ──
   Miniaturas de los hermanos cross (otros colores del modelo) a la vista al decidir,
   como los selectores de color de una PDP. Las pinta product.js cuando llegan los
   relacionados; sin cross la fila NO existe. Entrada con fundido suave.
   ENCUADRE: las fotos de producto son verticales (4:5) con el zapato en una banda
   horizontal centrada y mucho aire blanco; el marco APAISADO 4:3 + cover + zoom
   (scale) recorta ese aire y el zapato LLENA la miniatura. Pie con el nombre del
   color (uppercase, --hint) para leer la variante sin depender de la foto. */
/* Zoom de encuadre como TOKEN: cada instancia (fotos ya recortadas de otro cliente)
   puede ajustarlo o desactivarlo (1) sin tocar código. El hover suma +.04. */
:root { --alsoin-zoom:1.32; }
/* Slot reservado: existe desde el PRIMER render de la ficha con la altura de la fila
   (esqueleto de 2 marcos fantasma). Con gama se rellena DENTRO —el precio y la matriz
   no se mueven—; sin gama se pliega con transición de altura y desaparece. */
/* min-height = alto real de la fila con pie de 2 líneas (label 12 + hueco 13 +
   marco 87 + pie 31 ≈ 145 / móvil con marco 69 ≈ 127): así el relleno tardío
   no mueve NI UN PÍXEL el precio ni la matriz. */
.product-alsoin-slot { margin:1.1rem 0 0; min-height:145px;
  transition:height .25s var(--ease), min-height .25s var(--ease),
    margin .25s var(--ease), opacity .2s var(--ease); }
.product-alsoin-slot.alsoin-collapse { overflow:hidden; height:0 !important;
  min-height:0; margin-top:0; opacity:0; }
.alsoin-skel-bar { display:block; width:6rem; height:.72rem; margin:0 0 .8rem;
  border-radius:3px; background:#eeede9; }
.alsoin-skel-pics { display:flex; gap:.7rem; }
.alsoin-skel-pic { width:116px; height:87px; border-radius:var(--r-sm);
  border:1px solid var(--line-control); background:var(--card); }
.product-alsoin { display:flex; align-items:flex-start; flex-wrap:wrap;
  gap:.8rem .7rem; margin:0; opacity:0; transition:opacity .45s var(--ease); }
.product-alsoin.on { opacity:1; }
.alsoin-label { flex-basis:100%; font-size:.72rem; font-weight:700; letter-spacing:.07em;
  line-height:1; text-transform:uppercase; color:var(--hint); }
.alsoin-thumb { display:block; flex:none; width:116px; text-decoration:none; }
.alsoin-pic { display:block; width:100%; height:87px; overflow:hidden;
  border:1px solid var(--line-control); background:var(--card); border-radius:var(--r-sm);
  transition:border-color .15s var(--ease), box-shadow .15s var(--ease); }
a.alsoin-thumb:hover .alsoin-pic { border-color:var(--blue); box-shadow:0 0 0 1px var(--blue); }
.alsoin-thumb:focus-visible { outline:2px solid var(--blue); outline-offset:2px; }
.alsoin-thumb img { width:100%; height:100%; object-fit:cover; display:block;
  transform:scale(var(--alsoin-zoom)); transform-origin:50% 56%; transition:transform .25s var(--ease); }
a.alsoin-thumb:hover img { transform:scale(calc(var(--alsoin-zoom) + .04)); }
@media (prefers-reduced-motion: reduce) { a.alsoin-thumb:hover img { transform:scale(var(--alsoin-zoom)); } }
/* El color ACTUAL (primer swatch): marcado con el marco de tinta, no navega */
.alsoin-current { cursor:default; }
.alsoin-current .alsoin-pic { border:2px solid var(--ink); }
/* Agotado: la foto se atenúa y el pie lo dice en vez del precio */
.alsoin-thumb.is-out .alsoin-pic { opacity:.55; }
.alsoin-color { display:block; margin-top:.35rem; font-size:.66rem; font-weight:600;
  letter-spacing:.06em; line-height:1.2; text-transform:uppercase; color:var(--hint);
  text-align:center; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  transition:color .15s var(--ease); }
a.alsoin-thumb:hover .alsoin-color { color:var(--ink); }
/* Segunda línea del pie: PVD del hermano solo si difiere, o AGOTADO sin stock */
.alsoin-sub { display:block; margin-top:.15rem; font-size:.66rem; font-weight:500;
  letter-spacing:.02em; line-height:1.2; color:var(--ink-2); text-align:center;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.alsoin-sub.alsoin-outlbl { text-transform:uppercase; letter-spacing:.06em; color:var(--hint); }
.alsoin-art { width:100%; height:100%; display:grid; place-items:center; color:var(--ink); opacity:.3; }
/* "+N": mismo marco que un swatch; baja al raíl "Completa la gama" */
.alsoin-more { flex:none; width:116px; height:87px; display:grid; place-items:center;
  border:1px dashed var(--line-control); border-radius:var(--r-sm); background:none;
  font:inherit; font-size:1rem; font-weight:700; color:var(--ink-2); cursor:pointer;
  transition:border-color .15s var(--ease), color .15s var(--ease); }
.alsoin-more:hover { border-color:var(--blue); color:var(--blue); }
.alsoin-more:focus-visible { outline:2px solid var(--blue); outline-offset:2px; }
@media (max-width:48rem) {
  .product-alsoin-slot { min-height:127px; }
  .alsoin-skel-pic { width:92px; height:69px; }
  .alsoin-thumb, .alsoin-more { width:92px; }
  .alsoin-pic, .alsoin-more { height:69px; }
  .alsoin-more { font-size:.9rem; }
}

.product-attrs { display:grid; grid-template-columns:repeat(auto-fit,minmax(7rem,1fr)); gap:1rem 1.6rem;
  margin:1.6rem 0 0; padding:1.5rem 0 0; border-top:1px solid var(--line); }
.product-attrs dt { font-size:.7rem; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
.product-attrs dd { margin:.3rem 0 0; font-size:.9rem; font-weight:700; letter-spacing:.02em; text-transform:uppercase; }

.product-price { display:flex; align-items:baseline; gap:.7rem; margin:1.6rem 0 0; padding:1.5rem 0 0;
  border-top:1px solid var(--line); }
.product-price span { font-size:.9rem; color:var(--ink-2); }
.product-price b { font-family:var(--display); font-size:2.1rem; letter-spacing:-.02em; }

.product-buy { margin:1.9rem 0 0; }
.product-buy .matrix, .product-buy .matrix.wide { max-width:none; }
.product-buy .matrix-consult { max-width:none; }
.product-order { display:flex; align-items:center; justify-content:space-between; gap:1.2rem;
  flex-wrap:wrap; margin-top:1.5rem; }
.product-total { font-size:.95rem; color:var(--ink-2); }
.product-total b { font-family:var(--display); font-size:1.25rem; letter-spacing:-.01em; }
.product-hint { color:var(--muted); }
.product-order :is(.btn-primary, .btn-ghost) { padding:.85rem 1.9rem; }

.product-docs { display:flex; flex-wrap:wrap; gap:.8rem; margin:2rem 0 0; padding:1.6rem 0 0;
  border-top:1px solid var(--line); }
.product-doc { display:inline-flex; align-items:center; gap:.5rem; font-size:.82rem; font-weight:600;
  letter-spacing:var(--brand-cta-tracking,.02em); color:var(--ink); border:1px solid var(--line-control); border-radius:var(--r-sm);
  padding:.62rem 1rem; background:var(--card);
  transition:border-color .15s var(--ease), color .15s var(--ease); }
.product-doc:not([disabled]):hover { border-color:var(--ink); }
.product-doc[disabled] { color:var(--muted-2); border-style:dashed; cursor:not-allowed; }
.product-doc svg { flex:none; }

/* ══════════════ Checkout (16-checkout.png) ══════════════ */
/* La referencia no enseña el H1 "Checkout" (las migas y "Cliente: …" ya sitúan la
   página), pero el documento necesita su encabezado: se oculta solo visualmente. */
.page.checkout > .cat-headline > h1.title { position:absolute; width:1px; height:1px; padding:0;
  margin:-1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }

.ck-grid { display:grid; grid-template-columns:minmax(0,1fr) 22rem; gap:1.6rem; align-items:start; }
.ck-head { display:flex; align-items:center; justify-content:space-between; gap:1rem; flex-wrap:wrap;
  margin-bottom:1.1rem; }
.ck-client { font-size:1.25rem; font-weight:400; margin:0; }
.ck-client b { font-weight:700; }
.ck-actions { display:flex; gap:.6rem; flex-wrap:wrap; }

.ck-card { background:var(--card); border:1px solid var(--line); border-radius:var(--r-sm); padding:1.4rem 1.6rem; }
/* Los cuatro campos de la ficha NO llevan lo mismo, así que no se reparten a partes
   iguales: FECHA son diez cifras y ENTREGAS es el nombre de cada entrega con sus fechas de
   servicio («pedidos hasta el 30/09/2026 · entrega del 01/10/2026 al 31/10/2026»), que en
   una cuarta parte del ancho se partía en ocho renglones y descuadraba la fila entera
   mientras las otras tres columnas se quedaban medio vacías. El peso va con el contenido.
   FECHA lleva mínimo en rem, no 0: es la columna más liviana y a 1024 su peso la dejaba en
   57 px, con «07/09/2026» cortado. Un dato que no se puede partir necesita su suelo. */
.ck-row { display:grid; gap:1.4rem; margin:0;
  grid-template-columns:minmax(6rem,.55fr) minmax(0,.95fr) minmax(0,1.05fr) minmax(0,1.75fr);
  padding-bottom:1.2rem; border-bottom:1px solid var(--line); }
.ck-row.two { grid-template-columns:repeat(2,minmax(0,1fr)); padding-top:1.2rem; }
.ck-row.one { grid-template-columns:1fr; padding-top:1.2rem; padding-bottom:0; border-bottom:none; }
.ck-field dt { font-size:.72rem; font-weight:700; letter-spacing:.07em; text-transform:uppercase; color:var(--ink); }
.ck-field dd { margin:.45rem 0 0; color:var(--ink-2); font-size:.95rem; min-height:1.2rem; }
.ck-field input, .ck-field select, .ck-field textarea { width:100%; border:1px solid var(--line-control);
  border-radius:var(--r-sm); padding:.5rem .65rem; background:#fff; }
.ck-field input:focus, .ck-field select:focus, .ck-field textarea:focus { border-color:var(--blue); }
/* La tramitación es ancha (familia REJILLA), pero lo que se ESCRIBE y se LEE dentro sigue
   teniendo medida de lectura: unas notas de 1500 px de ancho son un renglón de 200 caracteres
   que nadie sigue con la vista, y la dirección se lee mejor en bloque que estirada. */
.ck-row.one .ck-field textarea { max-width:48rem; }
.ck-addr-list, .ck-addr-one, .ck-addr-empty { max-width:34rem; }

/* Dirección de envío del pedido (D1/D3/D4). La elección está a la vista y es explícita:
   una lista de opciones con el ALIAS delante —que es como el comprador distingue sus
   tiendas— y la línea completa debajo. El <select> anterior recortaba la dirección justo
   donde se lee, así que aquí el texto se parte en varias líneas en vez de cortarse.
   La columna de envío es más ancha que la de facturación porque tiene que contener esa
   lista sin apretarla. */
.ck-row.two.ck-ship-row { grid-template-columns:minmax(0,1.65fr) minmax(0,1fr); }
.ck-addr-list { display:grid; gap:.5rem; margin:.5rem 0 0; }
.ck-addr { display:flex; align-items:flex-start; gap:.65rem; padding:.6rem .75rem;
  border:1px solid var(--line-control); background:#fff; cursor:pointer; }
.ck-addr:hover { border-color:var(--ink); }
/* La elegida se marca con el filete de la marca, no solo con el punto del radio */
.ck-addr.on { border-color:var(--ink); box-shadow:inset 0 0 0 1px var(--ink); }
/* El radio NO es un campo de la ficha: `.ck-field input` los pone al 100 % del ancho
   (es lo que quieren la referencia y las notas) y aquí eso empujaba la dirección fuera
   de su tarjeta, una letra por línea. */
.ck-addr input[type=radio] { flex:none; width:auto; margin:.2rem 0 0; padding:0;
  border:none; background:none; }
.ck-addr-body { display:block; min-width:0; }
.ck-addr b, .ck-addr-one b { font-size:.72rem; font-weight:700; letter-spacing:.07em;
  text-transform:uppercase; color:var(--ink); }
/* overflow-wrap: una calle larga se parte antes que desbordar la tarjeta */
.ck-addr-body > span, .ck-addr-one > span { display:block; margin-top:.2rem;
  color:var(--ink-2); font-size:.9rem; overflow-wrap:anywhere; }
.ck-addr-tag { margin-left:.5rem; font-style:normal; font-size:.62rem; font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; color:var(--blue-soft-text);
  background:var(--blue-soft); padding:.1rem .35rem; }
.ck-addr-one { margin:.45rem 0 0; }
.ck-addr-empty { margin:.45rem 0 0; color:var(--muted); }
/* La petición de elegir, en el sitio donde se elige (el aviso del resumen la repite
   junto a TERMINAR PEDIDO, que es donde se descubre que falta algo) */
.ck-addr-ask { margin:.45rem 0 0; color:var(--blue-text); font-size:.85rem; font-weight:700; }
.ck-addr-add { margin-top:.6rem; font-size:.8rem; padding:.4rem .7rem; }
.ck-addr-note { display:flex; align-items:flex-start; gap:.4rem; margin:.6rem 0 0;
  color:var(--ok); font-size:.85rem; }
.ck-addr-note svg { flex:none; margin-top:.15rem; }

/* Buscador de direcciones (solo con más de nueve). El icono va dentro del recuadro para
   que se lea como un campo de búsqueda y no como un campo más de la ficha del pedido. */
.ck-addr-search { display:flex; align-items:center; gap:.5rem; max-width:34rem;
  margin:.5rem 0 0; padding:0 .65rem; background:#fff; border:1px solid var(--line-control);
  border-radius:var(--r-sm); }
.ck-addr-search:focus-within { border-color:var(--blue); }
.ck-addr-search svg { flex:none; color:var(--muted); }
/* `.ck-field input` pone todos los campos de la ficha al 100 % CON su recuadro: aquí el
   recuadro es el contenedor, así que el input se queda desnudo dentro. */
.ck-addr-search input { flex:1; min-width:0; border:none; background:none; padding:.5rem 0; }
.ck-addr-search input:focus { border:none; outline:none; }
.ck-addr-count { max-width:34rem; margin:.55rem 0 0; color:var(--muted); font-size:.8rem; }
.ck-addr-more { margin:.6rem .5rem 0 0; font-size:.8rem; padding:.4rem .7rem; }
/* La marca de «esta es la que tienes elegida», que es por lo que la ficha sigue en
   pantalla cuando el filtro no la casa */
.ck-addr-tag.on { color:var(--ok); background:#e8f4ec; }

/* ── Ventana «Ver más»: todas las direcciones, paginadas (ui/address-picker.js) ── */
.dlg-addr-pick { max-width:min(52rem,94vw); width:52rem; }
.addr-pick-search { display:flex; align-items:center; gap:.5rem; margin:0 0 .2rem;
  border:1px solid var(--line-control); border-radius:var(--r-sm); background:#fff; padding:0 .65rem; }
.addr-pick-search:focus-within { border-color:var(--blue); }
.addr-pick-search input { flex:1; min-width:0; border:none; background:none; padding:.55rem 0; }
.addr-pick-search input:focus { outline:none; }
.addr-pick-search button { flex:none; color:var(--muted); padding:.3rem; }
.addr-pick-count { margin:.7rem 0 .6rem; color:var(--muted); font-size:.8rem; }
/* Dos columnas en escritorio: veinte direcciones en una sola columna son doce pantallas
   de rueda dentro de una ventana que ya tiene su propio desplazamiento. */
.addr-pick-list { list-style:none; margin:0; padding:0; display:grid; gap:.5rem;
  grid-template-columns:repeat(auto-fill,minmax(15rem,1fr)); }
.addr-pick-item { display:block; width:100%; text-align:left; padding:.6rem .75rem;
  border:1px solid var(--line-control); background:#fff; border-radius:var(--r-sm); }
.addr-pick-item:hover { border-color:var(--ink); background:var(--paper); }
.addr-pick-item.on { border-color:var(--ink); box-shadow:inset 0 0 0 1px var(--ink); }
.addr-pick-head { display:block; }
.addr-pick-head b { font-size:.72rem; font-weight:700; letter-spacing:.07em;
  text-transform:uppercase; color:var(--ink); }
.addr-pick-line { display:block; margin-top:.2rem; color:var(--ink-2); font-size:.88rem;
  overflow-wrap:anywhere; }
.addr-pick-pager .pager { padding:.9rem 0 0; }

.ck-lines-head { display:flex; align-items:center; justify-content:space-between; gap:1rem;
  flex-wrap:wrap; margin:2rem 0 .9rem; }
.ck-lines-head h2 { font-family:var(--display); font-size:1.4rem; letter-spacing:-.02em; margin:0; }
.ck-empty { background:var(--card); border:1px solid var(--line); border-radius:var(--r-sm);
  padding:1.3rem 1.5rem; margin:0; font-size:1.05rem; font-weight:700; }

.ck-group { background:var(--card); border:1px solid var(--line); border-radius:var(--r-sm);
  padding:1.1rem 1.4rem; margin-bottom:.9rem; }
.ck-group header { display:flex; align-items:baseline; gap:1rem; flex-wrap:wrap; margin-bottom:.6rem; }
.ck-group h3 { font-size:1rem; text-transform:uppercase; margin:0; letter-spacing:-.01em; }
.ck-group header p { margin:0; color:var(--muted); font-size:.85rem; }
.ck-group-total { margin-left:auto; font-weight:700; font-size:.9rem; }
/* La tabla de respaldo (artículo que ya no está en catálogo) se desplaza DENTRO de su
   bloque, como la matriz de tallas: a 390 px sus cinco columnas movían la página entera de
   lado. Con el teclado se recorre igual: los campos de cantidad de dentro arrastran el
   desplazamiento al recibir el foco. Y tampoco se estira con la página: cinco columnas
   repartidas en 1.300 px dejan «3 uds.» y «23,70 €» a un palmo de distancia, y el ojo
   pierde la fila. */
.ck-table-wrap { overflow-x:auto; max-width:52rem; }
.ck-table { width:100%; border-collapse:collapse; }
.ck-table th { text-align:left; font-size:.7rem; letter-spacing:.07em; text-transform:uppercase;
  color:var(--muted); padding:.35rem .5rem; font-weight:700; border-bottom:1px solid var(--line); }
.ck-table td { padding:.45rem .5rem; border-bottom:1px solid var(--line); font-size:.9rem; }
.ck-table tr:last-child td { border-bottom:none; }
.ck-size { display:inline-block; min-width:2rem; text-align:center; background:var(--ink); color:#fff;
  border-radius:4px; padding:.1rem .4rem; font-size:.76rem; font-weight:700; }
/* Objetivo táctil mínimo de 24×24 CSS aunque el icono mida 14 */
.ck-drop { color:var(--muted); border-radius:5px; min-width:24px; min-height:24px;
  display:inline-grid; place-items:center; }
.ck-drop:hover { color:var(--out); }

/* Un ARTÍCULO por bloque en la tramitación: foto a la izquierda, ficha y matriz de tallas
   en el centro, y el botón de quitar el artículo entero en la esquina. La tabla de una fila
   por talla queda de respaldo para lo que ya no está en catálogo. La foto va a 4:5 como en
   el catálogo, para que el comprador vea la misma imagen que eligió. */
.ck-item { display:grid; grid-template-columns:6.5rem minmax(0,1fr) auto; gap:.2rem 1.2rem;
  align-items:start; }
.ck-photo { aspect-ratio:4/5; overflow:hidden; border-radius:6px; background:var(--surface);
  display:grid; place-items:center; }
.ck-photo img { width:100%; height:100%; object-fit:cover; display:block; }
/* Foto y nombre van a la ficha del artículo (mismo destino que en el catálogo): en la
   tramitación se corrigen cantidades, y para eso hay que poder volver a ver el producto.
   La foto está fuera del tabulador (repite el destino del nombre), así que solo necesita
   decirle al ratón que es clicable; el nombre usa el subrayado y el foco de siempre. */
.ck-photo[href] { cursor:pointer; }
.ck-photo[href]:hover { outline:1px solid var(--ink); outline-offset:1px; }
.ck-item-link { color:inherit; text-decoration:none; }
.ck-item-link:hover { text-decoration:underline; text-underline-offset:.18em; }
.ck-item-body { min-width:0; }
.ck-item-body header { margin-bottom:.4rem; }
.ck-item-body header p b { color:var(--ink); }
/* La matriz del catálogo tal cual; con muchas tallas se desplaza dentro del bloque en vez
   de romper la página. El hueco de abajo deja sitio al anillo de foco de la última fila. */
.ck-item-body .matrix { margin-top:.35rem; overflow-x:auto; padding:.15rem .15rem .4rem; }
.ck-drop-group { align-self:start; }
@media (max-width:48rem) {
  .ck-item { grid-template-columns:4.5rem minmax(0,1fr); }
  .ck-drop-group { grid-column:2; grid-row:1; justify-self:end; }
  .ck-item .ck-item-body { grid-column:2; }
}

.ck-side { background:var(--card); border:1px solid var(--line); box-shadow:var(--shadow);
  border-radius:var(--r); padding:1.4rem; position:sticky; top:calc(var(--header-h) + 1rem); }
/* El CTA cierra el panel (bajo el desglose y las condiciones) */
.ck-side .btn-primary.block { margin-top:1.2rem; padding-top:.9rem; padding-bottom:.9rem; }
.ck-totals { margin:1.2rem 0 0; }
.ck-totals > div { display:flex; align-items:center; justify-content:space-between; gap:1rem;
  padding:.6rem 0; border-bottom:1px solid var(--line); }
.ck-totals dt { color:var(--ink-2); font-size:.92rem; display:flex; align-items:center; gap:.4rem; }
.ck-totals dd { margin:0; font-weight:600; }
/* Las líneas de impuesto (una por tipo) van juntas, apretadas, justo encima del total con
   impuestos: el filete del transporte las separa de lo que no lleva impuesto y el del total
   las cierra. */
.ck-totals .ck-tax { border-bottom:none; padding:.35rem 0; }
.ck-totals .ck-tax + .ck-grand { margin-top:.25rem; }
.ck-totals .ck-grand { border-bottom:none; border-top:1px solid var(--line); padding-top:.9rem; }
.ck-totals .ck-grand dt { font-weight:700; font-size:1.05rem; color:var(--ink); }
.ck-totals .ck-grand dd { font-weight:700; font-size:1.05rem; }
.ck-terms { display:flex; align-items:flex-start; gap:.6rem; margin-top:1rem; font-size:.88rem; cursor:pointer; }
.ck-terms input { appearance:none; width:1.15rem; height:1.15rem; flex:none; border:1.5px solid var(--line-control);
  border-radius:3px; background:#fff; display:grid; place-items:center; }
.ck-terms input:checked { background:var(--ink); border-color:var(--ink); }
.ck-terms input:checked::after { content:""; width:.5rem; height:.28rem; border-left:2px solid #fff;
  border-bottom:2px solid #fff; rotate:-45deg; translate:0 -1px; }

/* ══════════════ Listados de documentos (03/04/05-*.png) ══════════════ */
/* Pedidos, Albaranes y Facturas comparten el mismo esqueleto: título a todo lo
   ancho, rail de estados a la izquierda separado por un filete vertical, y a la
   derecha toolbar + tabla + paginación. */
.page.docs { display:grid; grid-template-columns:12rem minmax(0,1fr); gap:0 2.2rem; align-items:start; }
.docs-head { grid-column:1 / -1; }
.docs-rail { border-right:1px solid var(--line); padding:.3rem 1.2rem 3rem 0; }
.docs-main { min-width:0; }

.srail { display:flex; flex-direction:column; gap:.15rem; }
.srail-item { display:flex; align-items:center; gap:.7rem; width:100%; text-align:left;
  padding:.5rem .75rem; border-radius:var(--r-sm); border:1px solid transparent; font-size:.92rem;
  color:var(--ink-2); transition:background .12s var(--ease), border-color .12s var(--ease); }
.srail-item:hover { background:#efeee9; }
/* Activo enmarcado en azul, como en la referencia */
.srail-item.on { border-color:var(--blue); color:var(--ink); font-weight:700; }
/* "Pendiente De…" no debe partirse en dos líneas: el rail mide lo que mide */
.srail-label { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.srail-count { color:var(--muted); font-size:.78rem; font-weight:400; }
.srail-item.on .srail-count { color:var(--ink); }

/* El punto de color nunca es la única pista: la etiqueta va escrita al lado */
.srail-dot { width:1.05rem; height:1.05rem; border-radius:50%; flex:none;
  box-shadow:inset 0 0 0 1px rgba(13,13,13,.16); }
/* Escala de estados en paleta cálida: verde/oliva/ocre/teja/teal, sin azul eléctrico */
.srail-dot.tone-none { background:var(--card); box-shadow:inset 0 0 0 1.5px #b7ad98; }
.srail-dot.tone-blue { background:#2f6f6a; }
.srail-dot.tone-lime { background:#6f9f3f; }
.srail-dot.tone-amber { background:#c69214; }
.srail-dot.tone-red { background:#bb3b2a; }
.srail-dot.tone-green { background:#1f7a45; }
.srail-dot.tone-orange { background:#c4633a; }

/* Chip de la columna ESTADO: mismo tono que el punto, en versión legible sobre
   blanco (fondo tintado + texto oscuro, ≥4,5:1) */
.chip { display:inline-flex; align-items:center; border-radius:999px; padding:.22rem .65rem;
  font-size:.72rem; font-weight:700; letter-spacing:.03em; text-transform:uppercase; white-space:nowrap; }
.chip.tone-none { background:var(--surface); color:#5a5348; }
.chip.tone-blue { background:#dcecea; color:#1f5551; }
.chip.tone-lime { background:#e8f0d8; color:#41611f; }
.chip.tone-amber { background:#f6e8c8; color:#785204; }
.chip.tone-red { background:#f7e0da; color:#992e20; }
.chip.tone-green { background:#dcefe1; color:#155e37; }
.chip.tone-orange { background:#f8e5d5; color:#8a3f1c; }

/* Toolbar: Buscar... + selects + botón azul de exportar */
.doc-tools { display:flex; align-items:flex-end; gap:.9rem; flex-wrap:wrap; margin-bottom:1.2rem; }
/* La toolbar va empaquetada a la izquierda, como en las capturas: el buscador
   crece hasta un tope y el espacio sobrante se queda a la derecha. */
.doc-search { position:relative; flex:1 1 20rem; min-width:11rem; max-width:32rem; }
/* CAMPO DE TEXTO: la tercera pieza del sistema de controles. Medía 45px junto a un
   desplegable de 42 y un botón de 43, y esa fila de tres alturas distintas es la que
   se ve en Pedidos, Albaranes, Facturas, SAT y Clientes. Ahora los tres toman
   --ctl-h y el filete y el papel de la carcasa .tb-select. */
.doc-search input { width:100%; height:var(--ctl-h); background:var(--ctl-bg);
  border:1px solid var(--ctl-line); border-radius:var(--r-sm);
  padding:0 2.7rem 0 var(--ctl-pad-x); transition:border-color .15s var(--ease); }
.doc-search input:focus { border-color:var(--blue); }
.doc-search input::placeholder { color:var(--muted); }
.doc-search button { position:absolute; right:.4rem; top:50%; translate:0 -50%; color:var(--muted);
  padding:.35rem; border-radius:6px; display:grid; place-items:center; }
.doc-search button:hover { color:var(--ink); }
/* El botón de acción de la barra iguala el alto en vez de fijar su propio padding */
.doc-tools .btn-primary { height:var(--ctl-h); padding:0 1.3rem; display:inline-flex;
  align-items:center; justify-content:center; }

/* Las cifras no se parten de línea; la alineación de la tabla es la de la
   referencia (todo a la izquierda), y tabular-nums ya cuadra los dígitos. */
table.grid .num { white-space:nowrap; }

/* ── Reparto de columnas cuando la tabla crece ─────────────────────────────────
   Con `table-layout:auto` y `width:100%`, el sobrante se reparte PROPORCIONALMENTE
   entre todas las columnas: al pasar Pedidos de 1240 a 2000 px, «Fecha» engordaba
   de 120 a 217 px para seguir enseñando «05/09/2026», y «Importe» de 110 a 199.
   El ancho se convertía en relleno, no en información.
   Las columnas de DATO CERRADO —importes y unidades (.num), y las de acción
   (descargar, seleccionar, menú)— tienen un ancho natural que no mejora por
   crecer, así que se les pide el mínimo con el clásico `width:1%`: en el algoritmo
   de tabla eso significa «lo justo para tu contenido». Todo el sobrante cae
   entonces en las columnas de TEXTO (nombre, referencia, cliente), que son las que
   de verdad se cortaban. */
table.grid :is(th, td):is(.num, .grid-actions, .doc-dl-col, .cl-pick-col) {
  width:1%; white-space:nowrap; }
/* Las columnas de ESTADO se reconocen por su contenido (llevan la insignia .chip) y
   se pinan igual, sin que la vista tenga que declarar nada: en `auto` el ancho de la
   columna es el máximo entre lo que pide la cabecera y lo que piden las celdas, así
   que basta con que las celdas pidan el mínimo. */
table.grid td:has(> .chip) { width:1%; white-space:nowrap; }
/* Y dos clases MÁS para las que sí hace falta que la vista las declare, ya listas
   para usar: `date` (fechas: ancho fijo, no ganan nada creciendo) y `wide` (la
   columna de texto que debe quedarse TODO el sobrante). Se dejan puestas porque las
   vistas que las necesitan —pedidos, albaranes, facturas, SAT— las declara otro
   equipo: con esto, adscribir una columna es añadir `className:'date'` y nada más. */
table.grid :is(th, td).date { width:1%; white-space:nowrap; }
table.grid :is(th, td).wide { width:100%; }

.doc-track { display:inline-flex; align-items:center; gap:.4rem; color:var(--blue);
  text-decoration:underline; text-underline-offset:3px; }
.doc-track:hover { color:var(--blue-deep); }
.doc-track svg { flex:none; }

/* ── Descarga del documento (js/ui/doc-download.js) ──
   Octava columna del listado de pedidos: un icono por fila, no un botón con rótulo,
   porque la fila ya lleva siete datos y un octavo con texto la parte en móvil. */
.doc-dl-col { width:1%; white-space:nowrap; text-align:center; }
.doc-dl { display:inline-flex; align-items:center; justify-content:center; width:2rem; height:2rem;
  border:1px solid var(--line-control); border-radius:var(--r-sm); background:#fff; color:var(--ink-2);
  cursor:pointer; transition:border-color .15s var(--ease), color .15s var(--ease); }
.doc-dl:hover { border-color:var(--blue); color:var(--blue); }
/* Sin origen de documento: apagado PERO enfocable (aria-disabled, no disabled), para que
   el title que lo explica se pueda leer también con el teclado. */
.doc-dl.off { color:var(--muted); border-style:dashed; cursor:not-allowed; opacity:.75; }
.doc-dl.off:hover { border-color:var(--line-control); color:var(--muted); }
.doc-dl.busy { cursor:progress; color:var(--blue); }
.doc-dl.busy svg { animation:doc-dl-spin .9s linear infinite; }
@keyframes doc-dl-spin { to { transform:rotate(360deg); } }

/* Botón con rótulo al pie de la ficha del documento */
.doc-modal-actions { display:flex; justify-content:flex-end; margin-top:1.4rem; }
.doc-modal-actions .btn-primary { display:inline-flex; align-items:center; gap:.5rem; }
.doc-modal-actions .btn-primary.off { background:var(--surface); color:var(--muted);
  border-color:var(--line-control); cursor:not-allowed; }

/* Tarjeta «Documento preparado»: dos líneas y un botón, así que estrecha */
.dlg-doc { max-width:min(30rem,92vw); width:30rem; }
.dlg-doc .doc-modal { padding:1.3rem 1.4rem 1.2rem; }
.dlg-doc .doc-modal-head { margin-bottom:.9rem; }
.doc-ready-hint { margin:0; color:var(--ink-2); font-size:.95rem; }
.doc-ready-error { margin:.7rem 0 0; color:var(--blue-text); font-weight:700; font-size:.9rem; }
.doc-ready-actions { display:flex; justify-content:flex-end; margin-top:1.3rem; }
.doc-ready-actions .btn-primary { display:inline-flex; align-items:center; gap:.5rem; }

/* ── Modal de detalle del documento (ui/modal.js) ── */
.dlg-wide { max-width:min(62rem,94vw); width:62rem; }
/* La ficha del PEDIDO lleva cinco columnas más que la del albarán y la de la factura (la
   traza de cada línea): a 62 rem se quedaban fuera de la ventana el nº de factura y su
   fecha, que es lo que se viene a mirar. En una pantalla normal ahora cabe entera. */
.dlg-lines { max-width:min(76rem,96vw); width:76rem; }
.doc-modal { padding:1.4rem 1.6rem 1.5rem; text-align:left; color:var(--ink); }
.doc-modal-head { display:flex; align-items:flex-start; justify-content:space-between; gap:1rem;
  margin-bottom:1.2rem; }
.doc-modal-head h2 { font-family:var(--display); font-size:1.25rem; letter-spacing:-.02em;
  margin:0; text-transform:uppercase; }
.doc-modal-head p { margin:.25rem 0 0; color:var(--muted); font-size:.88rem; }
.doc-modal-close { color:var(--muted); padding:.35rem; border-radius:6px; flex:none; }
.doc-modal-close:hover { color:var(--ink); background:var(--surface); }
/* Acciones de la cabecera del modal (descargas del pedido) + el aspa, en una línea */
.doc-modal-tools { display:flex; align-items:center; gap:.5rem; flex:none; flex-wrap:wrap;
  justify-content:flex-end; }
.doc-modal-act { display:inline-flex; align-items:center; gap:.4rem; padding:.42rem .7rem;
  border:1px solid var(--line); border-radius:7px; background:var(--card); color:var(--ink-2);
  font-size:.78rem; font-weight:600; letter-spacing:.01em; }
.doc-modal-act:hover:not(:disabled) { border-color:var(--ink); color:var(--ink); background:var(--surface); }
.doc-modal-act:disabled { opacity:.5; cursor:progress; }
.doc-modal-act svg { flex:none; }
/* En móvil el texto de los dos botones no cabe junto al título: quedan los iconos,
   que ya llevan el nombre en el title/aria del botón. */
@media (max-width:640px) {
  .doc-modal-act span { position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); }
  .doc-modal-act { padding:.42rem; }
}
.doc-modal-body { max-height:70vh; overflow-y:auto; }

.doc-facts { display:grid; grid-template-columns:repeat(auto-fit,minmax(9rem,1fr));
  gap:.9rem 1.4rem; margin:0 0 1.4rem; }
.doc-facts dt { font-size:.7rem; letter-spacing:.07em; text-transform:uppercase; color:var(--muted); }
.doc-facts dd { margin:.32rem 0 0; font-size:.92rem; }

.doc-lines th.num, .doc-lines td.num { text-align:right; }
.doc-line-ref { display:block; margin-top:.1rem; color:var(--muted); font-size:.78rem; font-weight:400; }

/* ── Banda de ENTREGA dentro de la tabla de líneas ──
   Un pedido de programación reparte sus líneas en varias entregas, y sin rótulo la tabla
   enseña dos «S» del mismo artículo que parecen una fila duplicada. La banda es la misma
   separación que ya hace el PDF del pedido, con el nombre y las fechas de cada tramo. */
.doc-lines-band th { text-align:left; font-size:.72rem; letter-spacing:.06em;
  text-transform:uppercase; color:var(--ink-2); background:var(--card);
  border-top:1px solid var(--line); padding:.5rem .7rem; white-space:nowrap; }

/* ── Traza por línea del pedido: ESTADO · ALBARÁN · ENVÍO · FACTURA · F. FACTURA ──
   Cinco columnas más no caben en un móvil de 390 px, ni siquiera en el escritorio con el
   nombre del artículo delante. La tabla NO se encoge hasta ser ilegible: se le pone una
   anchura mínima y se desplaza DENTRO de su .grid-scroll, nunca moviendo la página de lado.
   El ancho mínimo se declara aquí y no en la tabla de siempre, que sí cabe. */
.doc-lines.traced { min-width:58rem; }
.doc-lines th.trace, .doc-lines td.trace { white-space:nowrap; }
/* El nombre del artículo es lo único que puede partirse: sin esto una descripción larga se
   come el ancho y empuja la traza a tres pantallas de desplazamiento. */
.doc-lines.traced td:first-child { min-width:12rem; max-width:18rem; white-space:normal; }
/* Varios albaranes (envíos parciales) se apilan en su celda, y las fechas se apilan en la
   suya en el MISMO orden: cada número queda a la altura de su fecha. */
.doc-line-doc { display:block; font-weight:600; color:var(--ink); }
.doc-line-doc + .doc-line-doc, .doc-line-when + .doc-line-when { margin-top:.25rem; }
.doc-line-doc:hover { color:var(--blue); text-decoration:underline; text-underline-offset:3px; }
.doc-line-when { display:block; color:var(--ink-2); }
/* Sin albarán todavía: una raya, no un hueco que parezca un fallo de carga */
.doc-line-none { color:var(--muted); }
/* En el modal la tabla es lo ancho: su desplazamiento propio no puede convertirse en el de
   la ventana entera (cabecera y totales se irían de lado con ella). */
.doc-modal-body { overflow-x:hidden; }
/* Y la pista de que la tabla SIGUE a la derecha. Sin ella, en un móvil la traza parece
   cortada y nadie descubre que se puede arrastrar. Es CSS puro y se apaga sola: la tapa
   viaja con el contenido (`local`) y la sombra va fija a la caja (`scroll`), así que al
   llegar al final la tapa cubre la sombra. Sin desbordamiento no se ve nunca. */
/* La tapa es OPACA a lo ancho de toda la sombra (1.2rem > 1rem) y solo se difumina
   después: si empezara a difuminarse antes, asomaría una banda vertical permanente
   justo donde la tabla no se desborda. */
.doc-modal-body .grid-scroll {
  background:
    linear-gradient(to left, var(--card) 0 1.2rem, transparent 2.4rem) 100% 0 / 2.4rem 100% no-repeat,
    linear-gradient(to left, rgba(13,13,13,.16), transparent) 100% 0 / 1rem 100% no-repeat;
  background-attachment: local, scroll;
}

.doc-totals { max-width:20rem; margin:1.3rem 0 0 auto; }
.doc-totals > div { display:flex; align-items:center; justify-content:space-between; gap:1rem;
  padding:.45rem 0; border-bottom:1px solid var(--line); }
.doc-totals dt { color:var(--ink-2); font-size:.9rem; }
.doc-totals dd { margin:0; font-weight:600; }
.doc-totals .grand { border-bottom:none; border-top:1px solid var(--line); padding-top:.75rem; }
.doc-totals .grand dt, .doc-totals .grand dd { font-weight:700; font-size:1.02rem; color:var(--ink); }
.doc-error { margin:0; color:var(--muted); }

/* ══════════════ Carrito ══════════════ */
#cart-drawer { position:fixed; inset:0 0 0 auto; width:min(24rem,94vw); z-index:40; background:var(--card);
  box-shadow:-18px 0 50px -30px rgba(13,13,13,.45); translate:100% 0; transition:translate .3s var(--ease);
  display:flex; flex-direction:column; }
/* El panel existe en todas las páginas, solo desplazado fuera de la ventana. Sin
   `visibility:hidden` su botón de cerrar y sus papeleras seguían siendo enfocables
   con el tabulador, al final del documento y fuera de la pantalla. El retardo de la
   visibilidad conserva la animación de salida. */
#cart-drawer[hidden] { display:flex !important; visibility:hidden; }
#cart-drawer:not(.on) { visibility:hidden; transition:translate .3s var(--ease), visibility 0s .3s; }
#cart-drawer.on { translate:0 0; visibility:visible; }
#cart-drawer .top { background:var(--ink); color:#fff; padding:1.05rem 1.2rem; display:flex; align-items:center; gap:.7rem; }
#cart-drawer .top h2 { font-family:var(--display); font-size:1rem; margin:0; text-transform:uppercase; }
#cart-drawer .top .win { color:var(--muted-2); font-size:.78rem; }
#cart-drawer .top button { margin-left:auto; color:var(--muted-2); }
#cart-drawer .top button:hover { color:#fff; }
#cart-drawer .body { flex:1; overflow-y:auto; padding:1.2rem; }
#cart-drawer .body.is-empty { display:grid; place-items:center; color:var(--muted); text-align:center; }
#cart-drawer .foot { border-top:1px solid var(--line); padding:1rem 1.2rem 1.2rem; }
.cart-group + .cart-group { margin-top:1.1rem; padding-top:1.1rem; border-top:1px solid var(--line); }
.cart-group h3 { font-size:.9rem; text-transform:uppercase; margin:0; letter-spacing:-.01em; }
/* Con foto, el grupo se ordena en dos columnas: la foto ocupa las dos filas de nombre y
   referencia, y las líneas de talla siguen debajo a todo lo ancho. */
.cart-group.has-photo { display:grid; grid-template-columns:3.2rem minmax(0,1fr); column-gap:.7rem;
  align-items:start; }
/* La foto es un ENLACE a la ficha (el mismo destino que el nombre, para el ratón): el
   contenedor manda el hueco de la rejilla y la imagen lo rellena. */
.cart-photo { grid-row:1 / span 2; display:block; width:3.2rem; aspect-ratio:4/5; overflow:hidden;
  border-radius:4px; background:var(--surface); }
.cart-photo img { width:100%; height:100%; object-fit:cover; display:block; }
.cart-photo:hover { outline:1px solid var(--ink); outline-offset:1px; }
.cart-link { color:inherit; text-decoration:none; }
.cart-link:hover { text-decoration:underline; text-underline-offset:.18em; }
.cart-group.has-photo h3, .cart-group.has-photo .cart-ref { grid-column:2; }
.cart-group.has-photo .cart-line { grid-column:1 / -1; }
.cart-ref { margin:.1rem 0 .5rem; color:var(--muted); font-size:.78rem; }
.cart-line { display:flex; align-items:center; gap:.55rem; padding:.3rem 0; font-size:.85rem; }
.cart-size { background:var(--ink); color:#fff; border-radius:4px; padding:.1rem .4rem; font-size:.72rem;
  font-weight:700; min-width:1.9rem; text-align:center; }
.cart-qty { color:var(--muted); flex:1; }
.cart-amount { font-weight:600; }
.cart-drop { color:var(--muted); padding:.15rem; border-radius:5px; }
.cart-drop:hover { color:var(--out); }
.cart-total { display:flex; justify-content:space-between; font-size:1.05rem; margin-bottom:.9rem; }
.cart-total b { font-family:var(--display); letter-spacing:-.02em; }
.cart-note { margin:.6rem 0 0; text-align:center; color:var(--muted); font-size:.78rem; }

/* ══ ENTREGAS DENTRO DEL CARRITO Y DEL PEDIDO ═════════════════════════════════
   Desde el carrito por CLASE DE COMPRA, un mismo carrito de programación lleva
   líneas de varias entregas. Cada tramo se abre con una banda que dice de cuál es.
   No se inventa un lenguaje nuevo: se usa el «filete de capítulo» que el portal ya
   emplea para abrir bloque (cabecera de tabla, KPI, resumen del pedido) —los 2px de
   --rule, que además es token de marca— y el mismo par «nombre corto arriba, fechas
   debajo» que el filtro de entrega del catálogo. Así el comprador reconoce la misma
   entrega en los tres sitios donde la ve: catálogo, panel y tramitación. */
.cart-window, .ck-window-band { display:flex; align-items:baseline; flex-wrap:wrap; gap:.15rem .6rem;
  border-top:var(--rule-w) solid var(--rule); padding:.7rem 0 .5rem; margin:1.4rem 0 .2rem; }
/* La primera banda no necesita separarse de nada: abre la lista */
.cart-window:first-child, .ck-window-band:first-child { margin-top:0; }
.cart-window > b, .ck-window-band > b { font-size:.78rem; font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink); }
/* Las fechas de servicio responden a «¿esto cuándo me llega?»: van SIEMPRE, en tinta
   secundaria, y saltan de línea antes que recortarse (son la información que el viejo
   selector cortaba a la mitad). */
.cart-window-dates, .ck-window-dates { font-size:.78rem; font-weight:400; color:var(--muted);
  white-space:normal; }
/* Sustituye al style= en línea que llevaba suelto en la ficha de tramitación. En las
   BANDAS las fechas son un elemento flex más y van en línea con el nombre; en el campo
   «Entrega» de la ficha (un <dd>) van en su propio renglón, bajo el nombre. */
dd > .ck-window-dates { display:block; }
/* «12 unidades · 480,00 €» de ESE tramo: a la derecha y con cifras de ancho fijo, para
   que los subtotales de varias entregas se comparen en columna. */
.ck-window-total { margin-left:auto; font-size:.85rem; font-weight:600; color:var(--ink);
  font-variant-numeric:tabular-nums; white-space:nowrap; }
/* Campo ENTREGA de la ficha del pedido con varias entregas: lista sin viñetas, una
   por renglón, con el mismo par nombre/fechas. */
.ck-windows { list-style:none; margin:0; padding:0; display:grid; gap:.45rem; }
.ck-window { display:grid; gap:.05rem; }
/* Entregas en la ficha de un pedido: una por renglón, con sus fechas. Un pedido de
   programación puede servirse en dos o tres veces y en una sola línea no se leen. */
.doc-delivery { display:block; }
.doc-delivery + .doc-delivery { margin-top:.15rem; }
.ck-window > b { font-weight:600; }

/* Aviso de carrito EN LA OTRA CLASE: reposición y programación son dos carritos vivos
   que nunca se mezclan en un pedido, así que es fácil dejarse género apartado en el que
   no se está mirando y no enterarse hasta el mes siguiente. Se dice en el pie del panel,
   pegado al total, y NO como alarma roja —no hay nada roto— sino como nota con filete al
   margen: información que hay que ver, no un error. */
.cart-other { display:flex; align-items:flex-start; gap:.45rem; margin:.7rem 0 0;
  border-left:var(--rule-w) solid var(--line-control); padding:.1rem 0 .1rem .55rem;
  text-align:left; color:var(--ink-2); font-size:.78rem; line-height:1.45; }
.cart-other svg { flex:none; color:var(--muted); margin-top:.15rem; }
#veil { position:fixed; inset:0; z-index:39; background:rgba(13,13,13,.35); opacity:0;
  pointer-events:none; transition:opacity .3s var(--ease); }
#veil.on { opacity:1; pointer-events:auto; }

/* ══════════════ Cuenta y empresa ══════════════ */
/* Las dos pantallas se rediseñaron enteras (bloques .co-* y .pf-* más abajo). Lo que
   queda arriba son las piezas COMPARTIDAS —cabecera de bloque, campo de formulario,
   fila de acciones y la tarjeta de GESTIÓN—: las usa medio portal y todo el
   back-office, así que no se tocan al cambiar estas dos vistas. */

.acc-head { display:flex; align-items:center; justify-content:space-between; gap:1rem;
  margin-bottom:1rem; min-height:2.6rem; }
.acc-head h2 { font-family:var(--display); font-size:1.35rem; letter-spacing:-.025em;
  margin:0; display:flex; align-items:center; gap:.6rem; }

/* Campo de formulario: rótulo en versalitas sobre el control */
.acc-field { margin:0 0 1rem; }
.acc-field span, .acc-field > label > span { display:block; font-size:.74rem; font-weight:700;
  letter-spacing:.06em; text-transform:uppercase; color:var(--ink); margin-bottom:.4rem; }
.acc-field input, .acc-field select, .acc-field textarea { width:100%; border:1px solid var(--line-control);
  border-radius:var(--r-sm); padding:.6rem .7rem; background:#fff; font:inherit; color:var(--ink); }
/* Los select de formulario comparten alto y flecha propia para alinear con los
   inputs (el ancho de la flecha nativa descuadraba la rejilla). */
.acc-field select { appearance:none; -webkit-appearance:none; cursor:pointer; padding-right:2rem;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23726f68' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right .7rem center; }
.acc-field input:focus, .acc-field select:focus, .acc-field textarea:focus { border-color:var(--blue); }
.acc-actions { display:flex; justify-content:flex-end; gap:.6rem; flex-wrap:wrap; margin-top:1.2rem; }

/* ── Tarjeta y rejilla que comparten GESTIÓN y el alta de cliente ── */
.biz-section { margin-bottom:2.4rem; }
.biz-head h2 svg { color:var(--ink); flex:none; }
.biz-card { background:var(--card); border:1px solid var(--line); border-radius:var(--r-sm);
  padding:.2rem 1.5rem; }
.biz-grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:0 2rem; }
.biz-hint { display:flex; align-items:flex-start; gap:.6rem; margin:0 0 1.2rem; color:var(--muted);
  font-size:.85rem; }
.biz-hint svg { flex:none; margin-top:.1rem; }
.biz-none { margin:0; color:var(--muted); }

/* Casilla de marcar del portal (recargo de equivalencia, condiciones del alta) */
.biz-check { margin:0; padding:1.15rem 0 1.3rem; }
.biz-check label { display:flex; align-items:flex-start; gap:.7rem; font-size:.92rem; color:var(--ink-2); }
.biz-check input { appearance:none; width:1.15rem; height:1.15rem; flex:none; margin-top:.1rem;
  border:1.5px solid var(--line-control); border-radius:3px; background:#fff; display:grid; place-items:center; }
.biz-check input:checked { background:var(--ink); border-color:var(--ink); }
.biz-check input:checked::after { content:""; width:.5rem; height:.28rem; border-left:2px solid #fff;
  border-bottom:2px solid #fff; rotate:-45deg; translate:0 -1px; }
.biz-check input:disabled { background:#f1f0ec; }
.biz-check input:disabled:checked { background:var(--muted); border-color:var(--muted); }

/* ══════════════ Empresa · ficha de la cuenta ══════════════ */
/* Rediseño de diferenciación (docs/plan-diferenciacion-diseno.md): en vez de tres
   paneles iguales con su EDITAR, la página tiene CUATRO texturas distintas que se
   leen de identidad a logística — tira de hechos sin caja, dos carriles de filas
   etiqueta/valor EN LÍNEA (el original las apilaba), tarjetas de punto de entrega y
   el registro de cambios en curso. */
.co { display:grid; gap:2.6rem; }

/* 1 · Tira de identidad: filete de capítulo, hechos en fila y la ÚNICA acción */
.co-id { border-top:var(--rule-w) solid var(--rule); padding-top:1rem; }
.co-id-top { display:flex; align-items:center; justify-content:space-between;
  gap:1rem; flex-wrap:wrap; margin-bottom:1.2rem; }
.co-kicker { margin:0; font-size:.7rem; font-weight:700; letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted); }
.co-facts { display:grid; grid-template-columns:repeat(auto-fit,minmax(11rem,1fr));
  gap:1.2rem 2rem; margin:0; }
.co-fact dt { font-size:.68rem; font-weight:700; letter-spacing:.09em; text-transform:uppercase;
  color:var(--muted); }
.co-fact dd { margin:.3rem 0 0; font-size:1.05rem; line-height:1.35; color:var(--ink);
  overflow-wrap:anywhere; }
.co-none { color:var(--muted); }

/* 2 · Dos carriles de lectura, sin caja: el título manda y las filas van en línea */
.co-lanes { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:1.8rem 3rem; }
.co-lane { min-width:0; }
.co-lane h2 { display:flex; align-items:center; gap:.5rem; margin:0;
  font-family:var(--display); font-size:1.15rem; letter-spacing:-.02em; }
.co-lane h2 svg { flex:none; color:var(--blue); }
.co-lane-note { margin:.25rem 0 .9rem; color:var(--muted); font-size:.83rem; }
.co-rows { margin:0; border-top:1px solid var(--line); }
.co-row { display:grid; grid-template-columns:minmax(7rem,10rem) minmax(0,1fr); gap:.2rem 1.2rem;
  padding:.8rem 0; border-bottom:1px solid var(--line); }
.co-row dt { font-size:.8rem; font-weight:700; color:var(--ink-2); }
.co-row dd { margin:0; color:var(--ink); font-size:.95rem; overflow-wrap:anywhere; }

/* 3 · Puntos de entrega: tarjetas, no renglones dentro de un panel */
.co-drops-head { display:flex; align-items:flex-end; justify-content:space-between;
  gap:1rem; flex-wrap:wrap; margin-bottom:1rem; }
.co-drops-head h2 { display:flex; align-items:center; gap:.5rem; margin:0;
  font-family:var(--display); font-size:1.15rem; letter-spacing:-.02em; }
.co-drops-head h2 svg { flex:none; color:var(--blue); }
.co-drops-head .co-lane-note { margin:.25rem 0 0; }
.co-drop-list { list-style:none; margin:0; padding:0; display:grid;
  grid-template-columns:repeat(auto-fit,minmax(16rem,1fr)); gap:.9rem; }
.co-drop { background:var(--card); border:1px solid var(--line); border-radius:var(--r-sm);
  border-left:var(--rule-w) solid var(--rule); padding:.9rem 1rem 1rem; display:grid; gap:.3rem; }
.co-drop b { font-size:.72rem; font-weight:700; letter-spacing:.07em; text-transform:uppercase;
  color:var(--ink); }
.co-drop span { color:var(--ink-2); font-size:.92rem; overflow-wrap:anywhere; }
/* Misma etiqueta «Principal» que el checkout: la lista se lee igual en los dos sitios */
.co-drop-tag { font-style:normal; font-size:.62rem; letter-spacing:.08em;
  color:var(--blue-soft-text); background:var(--blue-soft); padding:.1rem .35rem; }
.co-empty { margin:0; color:var(--muted); }

/* 4 · Cambios en curso */
.co-pending { border-top:1px solid var(--line); padding-top:1.2rem; }
.co-pending h2 { margin:0; font-size:.8rem; font-weight:700; letter-spacing:.09em;
  text-transform:uppercase; }
.co-pending ul { list-style:none; margin:.4rem 0 0; padding:0; }
.co-pending li { display:grid; grid-template-columns:6.5rem minmax(0,1fr); gap:.3rem .9rem;
  padding:.6rem 0; border-bottom:1px solid var(--line); font-size:.9rem; }
.co-pending li:last-child { border-bottom:none; }
.co-pending-when { color:var(--muted); }
.co-pending-what b { display:block; font-size:.72rem; letter-spacing:.07em; text-transform:uppercase; }

/* Formulario único de propuesta: tres apartados dentro de una sola tarjeta */
.co-form { background:var(--card); border:1px solid var(--line); border-radius:var(--r-sm);
  padding:1.4rem 1.5rem 1.5rem; }
.co-hint { display:flex; align-items:flex-start; gap:.6rem; margin:0 0 1.4rem;
  color:var(--hint); font-size:.85rem; }
.co-hint svg { flex:none; margin-top:.1rem; }
.co-set { border:0; margin:0 0 1.2rem; padding:1rem 0 0; border-top:1px solid var(--line); }
.co-set legend { padding:0 .6rem 0 0; font-size:.7rem; font-weight:700; letter-spacing:.12em;
  text-transform:uppercase; color:var(--blue-text); }
.co-grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:0 1.6rem; }
.co-grid .co-wide { grid-column:span 2; }
.co-field-hint { display:block; margin:.35rem 0 0; font-style:normal; font-size:.75rem;
  line-height:1.35; color:var(--hint); }

/* ══════════════ Mi cuenta · dos carriles ══════════════ */
/* Rediseño de diferenciación: a la izquierda quién eres y cómo entras (identidad,
   nombre y contraseña — la banda gris a sangre del original desaparece), a la derecha
   los ajustes del portal como lista de ajustes, con los controles a la vista y sin
   botón EDITAR: «Guardar» se enciende solo cuando hay algo que guardar. */
.pf { display:grid; grid-template-columns:19rem minmax(0,1fr); gap:2.2rem 3.2rem; align-items:start; }
.pf-side { display:grid; gap:2rem; min-width:0; }
.pf-main { min-width:0; }

.pf-card { background:var(--card); border:1px solid var(--line); border-radius:var(--r-sm);
  border-top:var(--rule-w) solid var(--rule); padding:1.1rem 1.2rem 1.2rem; }
.pf-card-top { display:flex; align-items:center; gap:.85rem; }
.pf-avatar { flex:none; width:2.9rem; height:2.9rem; display:grid; place-items:center;
  background:var(--ink); color:var(--paper); font-family:var(--display); font-size:1.25rem;
  border-radius:var(--r-sm); }
.pf-card-kicker { margin:0; font-size:.64rem; font-weight:700; letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted); }
.pf-card-name { display:block; font-family:var(--display); font-size:1.25rem;
  letter-spacing:-.02em; overflow-wrap:anywhere; }
.pf-card-facts { margin:1rem 0 0; border-top:1px solid var(--line); }
.pf-card-facts > div { padding:.6rem 0; border-bottom:1px solid var(--line); }
.pf-card-facts > div:last-child { border-bottom:none; padding-bottom:0; }
.pf-card-facts dt { font-size:.66rem; font-weight:700; letter-spacing:.09em;
  text-transform:uppercase; color:var(--muted); }
.pf-card-facts dd { margin:.15rem 0 0; font-size:.9rem; color:var(--ink); overflow-wrap:anywhere; }

.pf-block { border-top:var(--rule-w) solid var(--rule); padding-top:1rem; min-width:0; }
.pf-block h2 { display:flex; align-items:center; gap:.5rem; margin:0;
  font-family:var(--display); font-size:1.15rem; letter-spacing:-.02em; }
.pf-block h2 svg { flex:none; color:var(--blue); }
.pf-lead { margin:.25rem 0 1rem; color:var(--muted); font-size:.83rem; }

.pf-name .acc-field { margin-bottom:.8rem; }
.pf-name button, .pf-password button { width:100%; }
.pf-password .acc-field { margin-bottom:.8rem; }

/* Lista de ajustes: nombre, qué cambia y el control, cada uno en su renglón */
.pf-sets { border-top:1px solid var(--line); }
.pf-set { display:grid; grid-template-columns:minmax(0,1fr) 14rem; gap:.3rem 1.5rem;
  align-items:center; padding:1rem 0; border-bottom:1px solid var(--line); }
.pf-set-text label { display:block; font-size:.95rem; font-weight:700; color:var(--ink); }
.pf-set-text p { margin:.15rem 0 0; color:var(--muted); font-size:.82rem; }
.pf-set select { width:100%; border:1px solid var(--line-control); border-radius:var(--r-sm);
  padding:.6rem 2rem .6rem .7rem; background:#fff; font:inherit; color:var(--ink);
  appearance:none; -webkit-appearance:none; cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23726f68' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right .7rem center; }
.pf-set select:focus { border-color:var(--blue); }
.pf-save { display:flex; align-items:center; justify-content:flex-end; gap:.6rem;
  flex-wrap:wrap; margin-top:1.2rem; }
.pf-save-note { margin-right:auto; font-size:.82rem; font-weight:700; color:var(--blue-text); }

/* ══════════════ Estadísticas (11-statistics.png) ══════════════ */
.stat-tools { margin-bottom:1.6rem; }
/* La fecha de Estadísticas ya la viste el sistema de controles (borde, fondo, alto y
   botón del calendario): este parche local forzaba `background:#fff` dentro de una
   carcasa que en dos de las tres marcas NO es blanca, y dejaba un rectángulo claro
   flotando dentro del control. */
.stat-title { font-family:var(--display); font-size:1.7rem; letter-spacing:-.03em;
  margin:0 0 1.2rem; }

/* M7: en la referencia el gráfico va a sangre, sin tarjeta ni borde */
.stat-chart { background:none; border:none; border-radius:0; padding:0; }
.stat-chart svg { width:100%; height:auto; display:block; }
.stat-tick line { stroke:#eceae5; stroke-width:1; }
.stat-tick text { fill:var(--muted); font-size:13px; }
.stat-axis { stroke:var(--ink); stroke-width:1.5; }
.stat-bar rect { fill:var(--blue); transition:fill .15s var(--ease); }
.stat-bar:hover rect { fill:var(--blue-deep); }
.stat-bar.negative rect { fill:var(--out); }
.stat-month { fill:var(--ink-2); font-size:13px; }
.stat-na { fill:var(--muted); font-size:14px; }

/* ══════════════ Contacto (07-contact.png) ══════════════ */
.ct-lead { margin:0 0 1.8rem; font-size:1rem; color:var(--ink-2); }
.ct-row { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:1.2rem 2rem; }
.ct-field { margin:0 0 1.2rem; }
.ct-field label, .ct-label { display:block; font-size:.92rem; font-weight:700; color:var(--ink);
  margin-bottom:.45rem; }
.ct-req { color:var(--out); margin-left:.1rem; }
.ct-field input[type="text"], .ct-field input[type="email"], .ct-field textarea { width:100%;
  border:1px solid var(--line-control); border-radius:var(--r-sm); padding:.7rem .9rem; background:#fff; }
.ct-field input:focus, .ct-field textarea:focus { border-color:var(--blue); }
.ct-field input::placeholder, .ct-field textarea::placeholder { color:var(--muted); }
.ct-message textarea { min-height:7rem; resize:vertical; }

/* El <input type=file> nativo no se puede vestir: se oculta y su <label> es el
   botón negro de la referencia, que sigue abriendo el selector sin JavaScript. */
/* Gana a ".ct-field label" (que pinta las etiquetas en negro sobre el papel): sin
   el selector completo el rótulo salía negro sobre el botón negro. */
.ct-field label.ct-file { display:flex; align-items:center; justify-content:center; gap:.6rem;
  background:var(--card); color:var(--ink); border:1px solid var(--line-control); border-radius:var(--r-sm);
  padding:.72rem 1.1rem; font-weight:600; font-size:.85rem; letter-spacing:.03em; text-transform:uppercase;
  cursor:pointer; margin:0; transition:border-color .15s var(--ease), background .15s var(--ease); }
.ct-field label.ct-file:hover { border-color:var(--ink); background:var(--surface); }
/* El input real está oculto: su foco de teclado se marca sobre el botón visible */
.ct-file:has(+ input:focus-visible) { outline:2px solid var(--blue); outline-offset:2px; }
.ct-filename { display:inline-flex; align-items:center; gap:.4rem; margin-top:.45rem; color:var(--muted);
  font-size:.82rem; overflow-wrap:anywhere; }
.ct-file-drop { color:var(--muted); border-radius:5px; min-width:22px; min-height:22px;
  display:inline-grid; place-items:center; }
.ct-file-drop:hover { color:var(--out); }
.ct-actions { display:flex; justify-content:flex-end; }

/* ══════════════ Devoluciones (08-sat.png) ══════════════ */
.sat-img { width:4rem; }
.sat-thumb { width:2.6rem; height:2.6rem; border-radius:var(--r-sm); object-fit:cover; display:block; }
.sat-thumb-empty { background:#f0efec; color:var(--muted-2); display:grid; place-items:center; }
.sat-pending { color:var(--muted); }
.sat-block { font-size:.74rem; font-weight:700; letter-spacing:.07em; text-transform:uppercase;
  color:var(--muted); margin:1.3rem 0 .4rem; }
.sat-text { margin:0; font-size:.95rem; color:var(--ink-2); }
.sat-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:0 1.4rem; }
.sat-wide { grid-column:1 / -1; }
.sat-error { margin:0 0 1rem; color:var(--out); font-size:.9rem; }
.sat-form .acc-actions { margin-top:.4rem; }

/* ══════════════ Asistente (chat flotante) ══════════════ */
#assistant-fab { position:fixed; right:1.5rem; bottom:1.5rem; z-index:45; width:3.5rem; height:3.5rem;
  border-radius:50%; background:var(--accent); color:#fff; display:grid; place-items:center;
  box-shadow:0 10px 30px -8px rgba(34,29,23,.5); transition:transform .18s var(--ease), background .18s var(--ease); }
#assistant-fab:hover { background:var(--accent-deep); transform:translateY(-2px) scale(1.03); }
#assistant-fab:focus-visible { outline:2px solid var(--ink); outline-offset:3px; }

#assistant-panel { position:fixed; right:1.5rem; bottom:1.5rem; z-index:46; width:min(23rem,calc(100vw - 2rem));
  height:min(34rem,calc(100vh - 3rem)); background:var(--card); border:1px solid var(--line);
  border-radius:var(--r); box-shadow:var(--shadow-card); display:flex; flex-direction:column; overflow:hidden; }
.as-head { background:var(--header-bg); color:var(--header-ink); padding:1rem 1.1rem .9rem;
  display:grid; grid-template-columns:1fr auto; gap:.2rem .5rem; }
.as-title { font-family:var(--display); font-style:italic; font-size:1.15rem; display:flex; align-items:center; gap:.45rem; }
.as-sub { grid-column:1 / -1; margin:0; font-size:.78rem; color:var(--header-ink-2); }
.as-close { color:var(--header-ink); padding:.25rem; border-radius:6px; }
/* Hover y anillo de foco en el color del velo de la cabecera, no en blanco fijo: sobre una
   cabecera CLARA (token headerBg) el blanco era invisible y el foco no se veía (WCAG 2.4.7).
   Con la cabecera negra por defecto el velo ES blanco, así que no cambia nada. */
.as-close:hover { background:color-mix(in srgb, var(--header-veil) 14%, transparent); }
.as-close:focus-visible { outline:2px solid var(--header-veil); outline-offset:1px; }

.as-log { flex:1; overflow-y:auto; overscroll-behavior:contain; padding:1rem; display:flex; flex-direction:column; gap:.7rem; }
.as-msg { max-width:85%; padding:.6rem .8rem; border-radius:14px; font-size:.9rem; line-height:1.5; white-space:normal; }
.as-msg strong { font-weight:700; }
.as-assistant { align-self:flex-start; background:var(--surface); color:var(--ink); border-bottom-left-radius:5px; }
.as-user { align-self:flex-end; background:var(--blue); color:#fff; border-bottom-right-radius:5px; }
.as-typing { display:inline-flex; gap:.25rem; padding:.1rem 0; }
.as-typing i { width:.4rem; height:.4rem; border-radius:50%; background:var(--muted); animation:as-bounce 1s infinite; }
.as-typing i:nth-child(2) { animation-delay:.15s; } .as-typing i:nth-child(3) { animation-delay:.3s; }
@keyframes as-bounce { 0%,60%,100% { opacity:.3; transform:translateY(0); } 30% { opacity:1; transform:translateY(-3px); } }

.as-suggest { display:flex; flex-wrap:wrap; gap:.4rem; padding:0 1rem .6rem; }
.as-chip { font-size:.78rem; color:var(--blue); background:var(--blue-soft); border:1px solid transparent;
  border-radius:999px; padding:.35rem .7rem; text-align:left; transition:border-color .12s var(--ease); }
.as-chip:hover { border-color:var(--blue); }

.as-form { display:flex; align-items:flex-end; gap:.5rem; padding:.7rem; border-top:1px solid var(--line); }
.as-form textarea { flex:1; resize:none; border:1px solid var(--line-control); border-radius:12px;
  padding:.6rem .8rem; background:var(--card); font-family:inherit; font-size:.9rem; max-height:120px; }
.as-form textarea:focus { border-color:var(--blue); outline:none; }
.as-send { flex:none; width:2.4rem; height:2.4rem; border-radius:10px; background:var(--blue); color:#fff;
  display:grid; place-items:center; transition:background .15s var(--ease); }
.as-send:hover { background:var(--blue-deep); }
.as-send:focus-visible { outline:2px solid var(--ink); outline-offset:2px; }
@media (max-width:34rem) {
  #assistant-panel { right:0; bottom:0; width:100vw; height:100dvh; border-radius:0; }
}
@media (prefers-reduced-motion:reduce) {
  #assistant-fab, .as-typing i { transition:none; animation:none; }
}

/* ══════════════ Responsive ══════════════ */
@media (max-width:70rem) {
  .h-search { display:none; }
  .h-user .who { display:none; }
}
@media (max-width:62rem) {
  /* Las columnas ya las decide auto-fit con su suelo de 22rem: la banda se apila
     sola. Aquí solo se sube la fila, porque una tarjeta a todo el ancho con la
     altura de escritorio quedaría como un buzón. */
  .tiles, .tiles[data-count="1"], .tiles[data-count="4"] { grid-auto-rows:clamp(14rem, 30vw, 22rem); }

  /* El rail de facetas y el panel de totales dejan de ser columnas: el catálogo y
     el checkout se apilan. Sin esto la columna de contenido se quedaba sin ancho
     (la matriz colapsaba a 0) y el panel del checkout se montaba encima. */
  .page.catalog { grid-template-columns:1fr; gap:1.2rem; }
  .rail { position:static; max-height:none; overflow:visible; }
  .ck-grid { grid-template-columns:1fr; }
  .ck-side { position:static; }

  /* Ficha: la foto deja de ser columna y se apila arriba, ya sin pegajosidad, con
     un ancho contenido para no comerse la pantalla en tabletas. */
  .product-grid { grid-template-columns:1fr; gap:1.8rem; }
  .product-media { position:static; width:100%; max-width:26rem; }

  /* Cuenta, empresa y contacto: las columnas de fichas se apilan mucho antes que
     el resto del layout, porque cada campo necesita su ancho para leerse. */
  .pf { grid-template-columns:1fr; gap:2rem; }
  .co-lanes { grid-template-columns:1fr; gap:1.8rem; }
  .biz-grid, .co-grid, .ct-row { grid-template-columns:repeat(2,minmax(0,1fr)); }
  .co-grid .co-wide { grid-column:span 2; }

  /* Los listados de documentos también se apilan: el rail de estados deja de ser
     columna y pasa a ser una tira horizontal que se desplaza sobre la tabla. */
  /* minmax(0,1fr) y no 1fr: el mínimo automático de un track deja que una tabla
     ancha (las 10 columnas de /sat) estire la página en vez de desplazarse dentro
     de su .grid-scroll. */
  .page.docs { grid-template-columns:minmax(0,1fr); }
  .docs-rail { border-right:none; border-bottom:1px solid var(--line);
    padding:0 0 1rem; margin-bottom:1.2rem; }
  .srail { flex-direction:row; overflow-x:auto; overscroll-behavior-x:contain; padding-bottom:.2rem; }
  .srail-item { flex:none; width:auto; }
}
@media (max-width:48rem) {
  /* Una sola fila: marca · usuario · carrito. Idioma y vista sin distracciones
     se van al menú de usuario (.m-only), que en móvil los muestra. */
  #chrome-header { gap:.7rem; padding:0 1rem; height:var(--header-h); flex-wrap:nowrap; }
  #chrome-header .brand { font-size:2rem; }
  #chrome-header .sep, .h-lang, .h-icon { display:none; }
  .h-menu .m-only { display:block; }
  /* Anclado al avatar el menú se sale por la izquierda: en móvil ocupa el ancho */
  .h-menu { position:fixed; top:var(--header-h); left:1rem; right:1rem; min-width:0; }
  .h-cart { padding:.6rem .8rem; font-size:.8rem; }
  .hero { padding:1rem 1rem 0; }
  .hero + .page { padding-top:2rem; }
  .carousel, .hero-skeleton { aspect-ratio:16/9; }
  .c-arrow { display:none; }
  .c-caption { padding:1.4rem 1.2rem 2.4rem; }
  /* Móvil: la banda es lo único en pantalla, así que la foto va algo más alta */
  .tiles, .tiles[data-count="1"], .tiles[data-count="4"] { grid-auto-rows:clamp(12rem, 56vw, 19rem); }
  .t-body { padding:2.8rem 1.1rem 1.1rem; }
  /* El FAB del asistente (fijo abajo-derecha) tapaba el pager en móvil (P3):
     se reserva hueco inferior para que el último control quede por encima. */
  .page { padding:1.2rem 1rem 6rem; }
  /* El FAB (56×56 fijo abajo-derecha) tapaba controles en TODAS las pantallas de móvil:
     desplegables de facetas, chips de la ficha, «Añadir» del lookbook, campos del checkout.
     En móvil el asistente se abre desde el menú de usuario (entrada «Asistente», que
     dispara el mismo toggle); el panel ya ocupa la pantalla entera a ese ancho. */
  #assistant-fab { display:none; }
  h1.title { font-size:1.9rem; }
  .sheet .card { padding:1.8rem 1.3rem; }

  /* Artículo del catálogo: miniatura + datos arriba, matriz a lo ancho debajo.
     Las tres columnas de escritorio no caben en 390 px sin dejar la matriz en 0. */
  .item { grid-template-columns:5.5rem minmax(0,1fr); gap:1rem;
    grid-template-areas:"photo info" "matrix matrix"; }
  .item-photo { grid-area:photo; aspect-ratio:1; }
  .item-info { grid-area:info; }
  .item-matrix { grid-area:matrix; }
  .item h2 { font-size:1.05rem; }
  /* En filas: con grid-auto-flow:column heredado, las tallas que no cabían en las columnas
     explícitas caían en columnas implícitas de 0px (tres tiras de 8px). Ahora envuelven. */
  .matrix, .matrix.wide { grid-auto-flow:row; max-width:none; grid-template-columns:repeat(auto-fill,minmax(4.6rem,1fr)); }

  /* Cuadrícula del catálogo: dos columnas caben en 390 px con la foto aún grande.
     Las COLUMNAS las fija ya la escala (--cols:2 es el valor base); aquí solo se
     aprietan los gaps, que en móvil roban ancho a la foto. */
  .cat-grid { --cat-gap-x:1rem; --cat-gap-y:1.5rem; }
  .pcard-name { font-size:1rem; }
  .pcard-price b { font-size:1.15rem; }

  /* Ficha en móvil: la foto ocupa el ancho y el pedido se apila con el CTA a lo ancho */
  .product-media { max-width:none; }
  .product-order :is(.btn-primary, .btn-ghost) { flex:1 1 auto; }
  /* Bocabarra: el rótulo derecho ("Elige tallas…" / total) medía 240px fijos y sacaba
     la página 67px del viewport (crítica A1). En móvil el botón envuelve en dos filas
     y el rótulo puede partir línea; el clip del contenedor es el cinturón de seguridad. */
  .product-order :is(.btn-primary, .btn-ghost) { display:flex; flex-wrap:wrap; align-items:center;
    gap:.35rem .8rem; white-space:normal; text-align:left; }
  .product-total, .product-hint { max-width:100%; white-space:normal; }
  .page.product { overflow-x:clip; }
  /* Header: "REPOSICIÓN (0)" desbordaba 47px en TODAS las páginas (crítica M2). El
     texto de la ventana se oculta solo VISUALMENTE (clip accesible: el lector de
     pantalla sigue oyendo el nombre completo) y queda icono + contador. */
  .h-cart .label { position:absolute; width:1px; height:1px; overflow:hidden;
    clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; }
  .h-cart { gap:.4rem; }

  /* Checkout: los campos en una columna y los botones de la cabecera repartidos */
  .ck-row, .ck-row.two, .ck-row.two.ck-ship-row { grid-template-columns:1fr; gap:.9rem; }
  .addr-grid { grid-template-columns:1fr; }
  .ck-card { padding:1.1rem 1rem; }
  .ck-group { padding:1rem; }
  .ck-actions { width:100%; }
  .ck-actions .btn-ghost, .ck-actions .btn-danger { flex:1 1 auto; }

  /* Una sola columna: en 390 px un par etiqueta/valor por línea es lo único legible */
  .biz-grid, .co-grid, .ct-row, .sat-grid { grid-template-columns:1fr; }
  .co-grid .co-wide { grid-column:auto; }
  .biz-card, .co-form { padding-left:1rem; padding-right:1rem; }
  .acc-head { flex-wrap:wrap; }
  /* Etiqueta encima del dato: en 390 px una fila de dos columnas parte las dos */
  .co-row, .pf-set, .co-pending li { grid-template-columns:1fr; }
  .pf-set select { max-width:none; }
  .stat-title { font-size:1.25rem; }
  .ct-actions button { width:100%; }

  /* Carritos: PROPIETARIO/A es el dato prescindible cuando no cabe la tabla.
     En albaranes lo es DIRECCIÓN, que además es la columna más larga. */
  .grid-owner, .grid-hide-sm { display:none; }
  table.grid th, table.grid td { padding:.75rem .6rem; }
}

/* ══════════════ Modo agente ══════════════ */
/* Territorio del agente: cartera de clientes, suplantación y el chrome que cambia
   cuando actúa "a nombre de" un cliente. Todo con los tokens del portal. */

/* Header suplantando: al lado del badge, "Deseleccionar cliente" en terracota para
   que la salida del contexto de compra del cliente destaque sobre el verde. */
.h-release { display:flex; align-items:center; gap:.4rem;
  border:1px solid color-mix(in srgb, var(--header-veil) 28%, transparent);
  border-radius:999px; padding:.42rem .8rem; font-size:.78rem; font-weight:600; color:var(--header-ink);
  white-space:nowrap; transition:background .15s var(--ease), border-color .15s var(--ease); }
.h-release:hover { background:var(--accent); border-color:var(--accent); color:#fff; }
.h-release svg { flex:none; }
/* Suplantando, la identidad doble ("agente — cliente") lleva un filete terracota a
   la izquierda del badge: recuerda de un vistazo que se compra por otro. */
.h-user.acting > button { box-shadow:inset 3px 0 0 var(--accent); padding-left:.7rem; }

/* Megamenú del agente: cuatro grupos en dos columnas, cada uno con su rótulo. */
.h-menu-agent { min-width:min(32rem,88vw); padding:.7rem; }
.h-menu-agent .h-groups { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:.4rem 1rem; }
.h-group { display:flex; flex-direction:column; }
.h-group-title { padding:.35rem .75rem .2rem; font-size:.68rem; font-weight:700; letter-spacing:.09em;
  text-transform:uppercase; color:var(--accent-deep); }
.h-menu-agent a[aria-current="page"] { background:var(--blue-soft); color:var(--blue-deep); font-weight:600; }
.agent-deselect { display:flex; align-items:center; gap:.45rem; color:var(--accent-deep); font-weight:600; }
.agent-deselect:hover { background:var(--accent-soft) !important; }
.agent-deselect svg { flex:none; }

/* ── Vista de clientes ── */
/* La cartera del agente tiene 12 columnas (hasta SELECCIONAR): a 1240px el ancho
   máximo estándar recorta la última columna y el botón de suplantar queda fuera de
   vista sin scroll (P2-1). Se ensancha la página para que quepan todas. */
/* El ancho de .cl lo pone ya la familia REJILLA DE DATOS (--w-grid): era una de las
   excepciones sueltas —1560 px a mano— que este sistema viene a retirar. */
.cl-requests { margin:-1.2rem 0 1.4rem; font-size:.88rem; }
.cl-requests a { color:var(--blue); text-decoration:underline; text-underline-offset:3px; }
.cl-requests a:hover { color:var(--blue-deep); }

/* La toolbar reutiliza .doc-tools; el botón "Crear nuevo cliente" se va a la derecha */
.cl-tools .cl-new { margin-left:auto; text-decoration:none; }
/* Campos de texto (Ciudad, Segmento) con el mismo marco que los selectores */
.cl-text { padding-left:0; }
.cl-text input { border:none; background:transparent; min-width:8rem; padding:.62rem .7rem; font:inherit;
  color:var(--ink); }
.cl-text input::placeholder { color:var(--muted-2); }
.cl-text:focus-within { border-color:var(--blue); }

/* Booleanos de la tabla: check verde de marca o guion apagado, ambos rotulados */
.cl-yes { display:inline-flex; color:var(--blue); }
.cl-no { color:var(--muted-2); }

/* Columna SELECCIONAR, alineada a la derecha como en la referencia */
table.grid th.cl-pick-col, table.grid td.cl-pick-col { text-align:right; width:6rem; white-space:nowrap; }
.cl-pick { display:inline-grid; place-items:center; width:2.15rem; height:2.15rem; border-radius:var(--r-sm);
  border:1px solid var(--line-control); background:#fff; color:var(--blue);
  transition:background .15s var(--ease), color .15s var(--ease), border-color .15s var(--ease); }
.cl-pick:hover { background:var(--blue); color:#fff; border-color:var(--blue); }
.cl-selected { display:inline-flex; align-items:center; gap:.4rem; color:var(--blue-deep); font-weight:600;
  font-size:.82rem; }
.cl-release { display:inline-grid; place-items:center; width:1.7rem; height:1.7rem; border-radius:50%;
  color:var(--accent-deep); transition:background .15s var(--ease); }
.cl-release:hover { background:var(--accent-soft); }

/* ── Registro de una tienda (new-client) y bandeja de solicitudes (requests) ── */
/* Rediseño de diferenciación (docs/plan-diferenciacion-diseno.md): lo que había eran
   cinco tarjetas iguales apiladas, la misma caja repetida cinco veces. Ahora es un
   PARTE numerado: cada capítulo lleva su cifra en un cuadro, su filete de capítulo y
   una línea que dice para qué es, y los campos van sueltos sobre el papel en vez de
   dentro de una caja. La ficha se lee de arriba abajo sin volver atrás. */
.rg-lead { max-width:44rem; margin:.2rem 0 2.2rem; color:var(--ink-2); font-size:.95rem;
  line-height:1.5; }
.rg-form { display:grid; gap:2.6rem; }
.rg-step { border-top:var(--rule-w) solid var(--rule); padding-top:1rem; }
.rg-step-head { display:flex; align-items:flex-start; gap:.9rem; margin-bottom:1.3rem; }
/* La cifra del capítulo: cuadrada y sólida, como la numeración de un parte */
.rg-num { flex:none; display:grid; place-items:center; width:1.8rem; height:1.8rem;
  background:var(--ink); color:var(--card); font-size:.85rem; font-weight:800;
  font-variant-numeric:tabular-nums; }
.rg-step-title { min-width:0; }
.rg-step-title h2 { display:flex; align-items:center; gap:.5rem; margin:0;
  font-family:var(--display); font-size:1.2rem; letter-spacing:-.02em; color:var(--ink); }
.rg-step-title h2 svg { flex:none; color:var(--blue); }
.rg-note { margin:.25rem 0 0; color:var(--muted); font-size:.83rem; }

/* Rejilla de tres columnas, con campos que ocupan dos o las tres */
.rg-grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:0 1.6rem; }
.rg-grid .rg-w2 { grid-column:span 2; }
.rg-grid .rg-w3 { grid-column:1 / -1; }
.rg-hint { display:block; margin:.35rem 0 0; font-style:normal; font-size:.75rem;
  line-height:1.35; color:var(--hint); }

/* Teléfono: prefijo y número son UN campo con dos controles pegados. Hay que deshacer
   el `.acc-field span` del formulario compartido, que pondría el envoltorio en
   versalitas y en bloque. */
.acc-field .rg-phone { display:grid; grid-template-columns:5.6rem minmax(0,1fr); gap:.4rem;
  font-size:inherit; font-weight:400; letter-spacing:normal; text-transform:none;
  color:inherit; margin:0; }
.rg-check { padding:.2rem 0 1.1rem; }
/* La explicación del recargo, alineada bajo el rótulo de la casilla (1,15rem de caja
   + 0,7rem de hueco): colgando del margen izquierdo se leería como otro párrafo. */
.rg-check .rg-hint { padding-left:1.85rem; }
.rg-add { margin-top:.4rem; }
.rg-empty { margin:0 0 .4rem; color:var(--muted); font-size:.9rem; }

/* Punto de entrega: ficha con filete a la izquierda, como las del resto del portal */
.rg-drop { background:var(--card); border:1px solid var(--line);
  border-left:var(--rule-w) solid var(--rule); padding:1rem 1.1rem .2rem; margin:0 0 1rem; }
.rg-drop-head { display:flex; align-items:center; justify-content:space-between;
  gap:.8rem; margin-bottom:.8rem; }
.rg-drop-head b { font-size:.72rem; font-weight:700; letter-spacing:.07em;
  text-transform:uppercase; color:var(--ink); }
/* Buzón: nombre, correo, para qué es… y el «quitar» en la misma línea, no debajo */
.rg-mailbox { grid-template-columns:minmax(0,1fr) minmax(0,1fr) minmax(0,1fr) auto;
  align-items:end; }
.rg-mailbox-x { display:flex; align-items:end; }
.rg-actions { display:flex; gap:.8rem; justify-content:flex-end; flex-wrap:wrap;
  border-top:1px solid var(--line); padding-top:1.4rem; }
.rg-actions .btn-ghost { text-decoration:none; display:inline-flex; align-items:center; }
@media (max-width:62rem) {
  .rg-grid { grid-template-columns:repeat(2,minmax(0,1fr)); }
  .rg-grid .rg-w2, .rg-grid .rg-w3 { grid-column:1 / -1; }
}
@media (max-width:40rem) {
  .rg-grid { grid-template-columns:1fr; }
  .rg-step-head { gap:.7rem; }
}
.requests .cl-tools { display:flex; gap:.8rem; align-items:center; margin-bottom:1.2rem; }
.requests .cl-tools .btn-ghost { text-decoration:none; }
.requests .cl-new { margin-left:auto; text-decoration:none; }
.req-badge { display:inline-block; padding:.18rem .6rem; border-radius:999px; font-size:.78rem; font-weight:600; }
.req-pending { background:#fdf0d5; color:#8a5a00; }
.req-approved { background:#dcefe4; color:var(--blue-deep); }
.req-rejected { background:var(--accent-soft); color:var(--accent-deep); }
/* La tienda ya está creada en el ERP pero le falta la cartera: es lo accionable de la
   bandeja, así que no se pinta como un «pendiente» más ni como un alta terminada. */
.req-waiting { background:#e4e9f5; color:var(--blue-deep); }
.req-hint { display:block; margin-top:.3rem; max-width:26rem; font-size:.76rem; line-height:1.35; color:var(--muted); }

/* ── Vistas agregadas del agente (documentos con columna cliente) ── */
.ag-client { display:inline-flex; flex-direction:column; align-items:flex-start; gap:.05rem; text-align:left; }
.ag-cnum { font-size:.72rem; color:var(--muted); font-weight:400; }

/* Top clientes de estadísticas del agente */
.stat-top { margin:1.8rem 0 0; }
.stat-top h3 { font-size:1rem; font-weight:600; margin:0 0 .7rem; color:var(--ink-2); }
.stat-top-list { list-style:none; margin:0; padding:0; display:grid; gap:.4rem; counter-reset:top; max-width:40rem; }
.stat-top-list li { display:flex; align-items:center; justify-content:space-between; gap:1rem;
  padding:.6rem .8rem; background:var(--surface); border-radius:var(--r-sm); }
.stat-top-list li::before { counter-increment:top; content:counter(top); font-variant-numeric:tabular-nums;
  color:var(--muted-2); font-weight:600; margin-right:.6rem; }
.stat-top-name { flex:1; display:flex; flex-direction:column; }
.stat-top-amount { font-weight:600; font-variant-numeric:tabular-nums; }

/* Intro de "Pedidos de selección" */
.ms-intro { display:flex; align-items:center; justify-content:space-between; gap:1rem; flex-wrap:wrap;
  margin:0 0 1.2rem; }
.ms-intro p { margin:0; color:var(--ink-2); max-width:44rem; }
.ms-intro .btn-primary { text-decoration:none; white-space:nowrap; }

/* ── Calendario de citas ── */
.cal-grid { display:grid; grid-template-columns:24rem 1fr; gap:1.8rem; align-items:start; }
.cal-form-wrap { padding:1.5rem 1.5rem 1.7rem; position:sticky; top:calc(var(--header-h) + 1rem); }
.cal-form-wrap h2 { font-family:var(--display); font-size:1.2rem; margin:0 0 1.1rem; }
.cal-form .acc-field { margin:0 0 .85rem; }
.cal-row2 { display:grid; grid-template-columns:1fr 6rem; gap:.7rem; }
.cal-row2 .acc-field { margin:0; }
.cal-form textarea { width:100%; border:1px solid var(--line-control); border-radius:var(--r-sm);
  padding:.6rem .7rem; font:inherit; resize:vertical; }
.cal-form input[type=datetime-local], .cal-form input[type=number], .cal-form input[type=text] {
  width:100%; border:1px solid var(--line-control); border-radius:var(--r-sm); padding:.62rem .7rem; font:inherit; }
.cal-list { list-style:none; margin:0; padding:0; display:grid; gap:.7rem; }
.cal-item { display:grid; grid-template-columns:9rem minmax(0,1fr) auto; gap:1rem; align-items:start;
  background:var(--card); border:1px solid var(--line); border-radius:var(--r-sm); padding:.9rem 1.1rem; }
.cal-item.cal-canceled { opacity:.6; }
.cal-when { display:flex; flex-direction:column; gap:.3rem; min-width:0; }
.cal-when time { font-weight:600; font-size:.9rem; }
.cal-kind { font-size:.7rem; font-weight:700; text-transform:uppercase; letter-spacing:.03em;
  padding:.12rem .5rem; border-radius:999px; width:fit-content; }
.cal-kind-cita { background:#e2ecff; color:#274b8f; }
.cal-kind-parte { background:#e6f0e9; color:var(--blue-deep); }
/* Título y notas son texto libre (hasta 200/2000 chars): un token sin espacios
   (email/URL/referencia) no debe estirar la fila ni empujar scroll horizontal. */
.cal-body { min-width:0; }
.cal-body b { display:block; overflow-wrap:anywhere; word-break:break-word; }
.cal-client { display:inline-flex; align-items:center; gap:.25rem; font-size:.82rem; color:var(--muted); margin-top:.2rem;
  overflow-wrap:anywhere; word-break:break-word; }
.cal-notes { margin:.35rem 0 0; font-size:.85rem; color:var(--ink-2); overflow-wrap:anywhere; word-break:break-word; }
.cal-actions { display:flex; flex-direction:column; align-items:flex-end; gap:.35rem; }
.cal-status { font-size:.75rem; font-weight:600; }
.cal-status-pending { color:#8a5a00; }
.cal-status-done { color:var(--blue-deep); }
.cal-status-canceled { color:var(--accent-deep); }
.cal-actions .btn-ghost { padding:.3rem .6rem; font-size:.8rem; }
.cal-empty { text-align:center; color:var(--muted); padding:3rem 1rem; }
.cal-empty p { margin:.6rem 0 0; }
@media (max-width:60rem) {
  .cal-grid { grid-template-columns:1fr; }
  .cal-form-wrap { position:static; }
  .cal-item { grid-template-columns:1fr; gap:.5rem; }
  .cal-actions { flex-direction:row; align-items:center; }
}

/* ── Pedido de selección: listado + builder ── */
.ms-tools { display:flex; margin-bottom:1.2rem; }
.ms-tools .cl-new { margin-left:auto; text-decoration:none; }
/* Detalle de una selección (al pulsar una fila del listado) */
.ms-detail .ms-actions { display:flex; gap:.6rem; align-items:center; margin-left:auto; }
.ms-detail .ms-back { text-decoration:none; }
.ms-facts { display:flex; flex-wrap:wrap; gap:1.6rem; margin:.4rem 0 1.8rem; }
.ms-fact { display:flex; flex-direction:column; gap:.3rem; }
.ms-fact-l { font-size:.7rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }
.ms-h { font-family:var(--display); font-weight:800; font-size:1.15rem; letter-spacing:-.01em; margin:1.5rem 0 .8rem; }
.ms-chips { display:flex; flex-wrap:wrap; gap:.5rem; }
.ms-chip { display:inline-flex; align-items:center; border:1px solid var(--line); padding:.42rem .75rem; font-size:.9rem; background:var(--card); }
.ms-chip.miss { color:var(--out); border-color:var(--out); text-decoration:line-through; }

.ms-add .ms-name { max-width:34rem; margin:0 0 2rem; }
.ms-section { margin:0 0 2.2rem; }
.ms-section > h2 { font-family:var(--display); font-size:1.25rem; margin:0 0 1rem; }
.ms-shead { display:flex; align-items:baseline; gap:1rem; margin:0 0 1rem; flex-wrap:wrap; }
.ms-shead h2 { font-family:var(--display); font-size:1.25rem; margin:0; }
.ms-link { background:none; border:none; color:var(--blue); font:inherit; font-weight:600; cursor:pointer;
  text-decoration:underline; text-underline-offset:3px; padding:0; }
.ms-link:hover { color:var(--blue-deep); }
.ms-empty { color:var(--muted); margin:.4rem 0; }

/* Modelos elegidos: miniaturas con papelera */
.ms-models { display:grid; grid-template-columns:repeat(auto-fill,minmax(9rem,1fr)); gap:1rem; }
.ms-model { position:relative; border:1px solid var(--line); border-radius:var(--r-sm); overflow:hidden; background:var(--card); }
.ms-model-img { aspect-ratio:1; background:var(--surface); display:grid; place-items:center; overflow:hidden; }
.ms-model-img img { width:100%; height:100%; object-fit:cover; }
.ms-model-mono { font-family:var(--display); font-size:2rem; color:var(--muted-2); }
.ms-model-info { padding:.5rem .6rem; }
.ms-model-info b { display:block; font-size:.85rem; overflow-wrap:anywhere; }
.ms-model-info span { font-size:.75rem; color:var(--muted); }
.ms-del { position:absolute; top:.4rem; right:.4rem; display:grid; place-items:center; width:1.9rem; height:1.9rem;
  border:none; border-radius:50%; background:rgba(255,255,255,.9); color:var(--accent-deep); cursor:pointer; box-shadow:var(--shadow-card); }
.ms-del:hover { background:var(--accent); color:#fff; }

/* Selección de clientes: tabla + panel */
.ms-clients { display:grid; grid-template-columns:1fr 20rem; gap:1.5rem; align-items:start; }
.ms-cfilters { display:flex; gap:.8rem; align-items:end; flex-wrap:wrap; margin-bottom:1rem; }
.ms-cfilters .doc-search { flex:1 1 14rem; }
.ms-seg { margin:0; min-width:11rem; }
.ms-seg span { display:block; font-size:.74rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase; margin-bottom:.4rem; }
.ms-ctable th.ms-add-col, .ms-ctable td.ms-add-col { width:3rem; text-align:center; }
.ms-plus { display:inline-grid; place-items:center; width:2rem; height:2rem; border-radius:50%;
  border:1px solid var(--line-control); background:#fff; color:var(--blue); cursor:pointer; transition:all .15s var(--ease); }
.ms-plus:hover { background:var(--blue); color:#fff; border-color:var(--blue); }
.ms-plus.on { background:var(--blue); color:#fff; border-color:var(--blue); }
.ms-ctable tr.ms-on { background:color-mix(in srgb, var(--blue) 6%, transparent); }
.ms-selected { padding:1.1rem 1.1rem 1.3rem; position:sticky; top:calc(var(--header-h) + 1rem); }
.ms-selected-head { display:flex; align-items:baseline; justify-content:space-between; gap:.6rem; margin-bottom:.8rem; }
.ms-selected-head b { font-size:.95rem; }
.ms-chip { display:flex; align-items:center; justify-content:space-between; gap:.5rem; padding:.45rem .6rem;
  background:var(--surface); border-radius:var(--r-sm); margin:0 0 .4rem; font-size:.85rem; }
.ms-chip button { border:none; background:none; color:var(--muted); cursor:pointer; display:grid; place-items:center; }
.ms-chip button:hover { color:var(--accent-deep); }

/* Realizar envío */
.ms-send .ms-sendtext { font-size:1rem; color:var(--ink-2); margin:0 0 1rem; }
.ms-send-actions { display:flex; gap:.8rem; flex-wrap:wrap; align-items:center; }
.ms-send-actions .btn-ghost { text-decoration:none; display:inline-flex; align-items:center; }
.btn-strong { border:1px solid var(--blue); color:var(--blue); font-weight:600; }
.btn-strong:hover:not([disabled]) { background:var(--blue); color:#fff; }
.ms-send-actions [disabled] { opacity:.45; cursor:not-allowed; }
.ms-errors { list-style:none; margin:1rem 0 0; padding:0; color:var(--out); font-size:.88rem; display:grid; gap:.3rem; }
.ms-errors li::before { content:"• "; }

/* Modal selector de modelos */
.dlg-models { max-width:min(64rem,96vw); width:64rem; }
.mp-panel { padding:0; display:flex; flex-direction:column; max-height:88vh; }
.mp-head { display:flex; align-items:center; gap:1rem; justify-content:space-between; flex-wrap:wrap;
  padding:1.2rem 1.4rem; border-bottom:1px solid var(--line); }
.mp-head h2 { font-family:var(--display); font-size:1.2rem; margin:0; }
.mp-search { flex:1 1 16rem; max-width:24rem; }
.mp-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(10rem,1fr)); gap:1rem;
  padding:1.4rem; overflow-y:auto; }
.mp-card { border:1px solid var(--line); border-radius:var(--r-sm); overflow:hidden; background:var(--card);
  display:flex; flex-direction:column; transition:border-color .15s var(--ease); }
.mp-card.on { border-color:var(--blue); box-shadow:0 0 0 1px var(--blue) inset; }
.mp-img { aspect-ratio:1; background:var(--surface); display:grid; place-items:center; overflow:hidden; }
.mp-img img { width:100%; height:100%; object-fit:cover; }
.mp-info { padding:.5rem .6rem; flex:1; }
.mp-info b { display:block; font-size:.85rem; overflow-wrap:anywhere; }
.mp-info span { font-size:.75rem; color:var(--muted); }
.mp-pick { border:none; border-top:1px solid var(--line); background:#fff; padding:.55rem; font:inherit;
  font-size:.78rem; font-weight:700; letter-spacing:.03em; text-transform:uppercase; color:var(--blue); cursor:pointer; }
.mp-pick:hover { background:var(--surface); }
.mp-card.on .mp-pick { background:var(--blue); color:#fff; }
.mp-empty, .mp-error { grid-column:1 / -1; text-align:center; color:var(--muted); padding:2rem; }
.mp-foot { display:flex; align-items:center; justify-content:space-between; gap:1rem; flex-wrap:wrap;
  padding:1rem 1.4rem; border-top:1px solid var(--line); }
.mp-foot-actions { display:flex; gap:.7rem; }

/* ── Pago con tarjeta: botón en facturas + página de resultado ── */
.inv-debt { display:inline-flex; flex-direction:column; align-items:flex-end; gap:.35rem; }
.inv-pay { display:inline-flex; align-items:center; gap:.3rem; border:1px solid var(--blue); color:var(--blue);
  background:#fff; border-radius:999px; padding:.22rem .7rem; font-size:.76rem; font-weight:600; cursor:pointer;
  white-space:nowrap; transition:background .15s var(--ease), color .15s var(--ease); }
.inv-pay:hover:not([disabled]) { background:var(--blue); color:#fff; }
.inv-pay[disabled] { opacity:.6; cursor:progress; }
.inv-paid { display:inline-flex; align-items:center; gap:.3rem; color:var(--blue-deep); font-size:.82rem; font-weight:600; }

.pay-page .pay-panel { max-width:34rem; margin:2rem auto; text-align:center; padding:2.6rem 2rem 2.2rem; }
.pay-icon { width:4.4rem; height:4.4rem; border-radius:50%; display:grid; place-items:center; margin:0 auto 1.1rem; }
.pay-paid .pay-icon { background:#dcefe4; color:var(--blue-deep); }
.pay-canceled .pay-icon, .pay-failed .pay-icon, .pay-error .pay-icon { background:var(--accent-soft); color:var(--accent-deep); }
.pay-pending .pay-icon { background:#fdf0d5; color:#8a5a00; }
.pay-panel h2 { font-family:var(--display); font-size:1.45rem; margin:.2rem 0 .5rem; }
.pay-amount { color:var(--ink-2); margin:0 0 .8rem; }
.pay-body { color:var(--muted); margin:0 auto 1.7rem; max-width:26rem; }
.pay-actions { display:flex; gap:.8rem; justify-content:center; flex-wrap:wrap; }
.pay-actions .btn-ghost { text-decoration:none; display:inline-flex; align-items:center; }

/* ── Lookbook "Colecciones lejan" (barefoot editorial) ── */
.page.lookbook { max-width:none; padding:0 0 4rem; }
.lb-hero { width:100%; margin:0 0 2.6rem; }
.lb-hero-fallback { min-height:40vh; display:grid; place-items:center; background:var(--surface); }
.lb-hero-fallback h1 { font-family:var(--display); font-size:2.4rem; }
/* ── Las historias, a sangre ───────────────────────────────────────────────────
   Iban en la columna de LECTURA (--maxw, 1240): a 1920 dejaban 340 px de blanco a
   cada lado y a 2560, 660 —más de la mitad de la pantalla vacía para enseñar un
   lookbook—. Una marca de moda enseña el lookbook a sangre; el blanco lateral no
   es aire editorial, es una foto que no se ve.
   La proporción 7:5 (foto : texto) y la escala del raíl de producto ya estaban
   probadas en BLOCCO 5, que había resuelto esto por su cuenta con un bloque de
   marca al final de la hoja. Sube aquí para las TRES marcas y el parche de BLOCCO
   se queda solo con lo que de verdad es suyo (el margen del índice). */
.lb-stories { max-width:none; margin:0; padding:0 var(--rail-x); }
@media (min-width:52.0625rem) {
  .lb-story { grid-template-columns:7fr minmax(28ch,5fr); column-gap:clamp(3rem,4vw,5rem); padding:3.2rem 0; }
  .lb-story.lb-right { grid-template-columns:minmax(28ch,5fr) 7fr; }
  /* La MEDIDA del párrafo sí se acota (38em ≈ 75 caracteres): lo que va a sangre es
     la historia, no el renglón. El titular crece con la ventana. */
  .lb-story-text { max-width:none; }
  .lb-story-text h2 { font-size:clamp(2rem, 2.2vw, 2.75rem); max-width:16em; }
  .lb-story-text p { font-size:clamp(1.02rem, .9vw, 1.15rem); max-width:38em; }
}
.lb-empty { text-align:center; color:var(--muted); padding:3rem 1rem; }

.lb-story { display:grid; grid-template-columns:1fr 1fr; gap:2rem 3rem; align-items:center;
  /* Entre capítulos, el color del filete de marca si lo hay (mismo patrón que .item). */
  padding:2.6rem 0; border-top:1px solid var(--brand-rule,var(--line));
  grid-template-areas:"media text" "shop shop"; }
.lb-story.lb-right { grid-template-areas:"text media" "shop shop"; }
.lb-story:first-child { border-top:none; }
.lb-story-media { grid-area:media; }
.lb-story-text { grid-area:text; }
.lb-shop { grid-area:shop; }
.lb-story-media { border-radius:var(--r); overflow:hidden; background:var(--surface); aspect-ratio:4/3; }
.lb-story-media img { width:100%; height:100%; object-fit:cover; }
.lb-story-text { max-width:34rem; }
.lb-kicker { display:inline-block; font-size:.74rem; font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; color:var(--accent-deep); border-bottom:var(--rule-w) solid var(--lb-accent);
  padding-bottom:.15rem; margin:0 0 .8rem; }
.lb-story-text h2 { font-family:var(--display); font-size:2rem; line-height:1.1; margin:0 0 .7rem; color:var(--ink); }
.lb-story-text p { color:var(--ink-2); font-size:1.02rem; line-height:1.6; margin:0; }

/* "Compra el look": raíl horizontal de tarjetas (a lo ancho de la historia) */
.lb-shop { grid-column:1 / -1; margin-top:1.6rem; min-width:0; }
.lb-shop-title { font-family:var(--display); font-size:1.15rem; margin:0 0 1rem;
  display:inline-flex; align-items:center; gap:.5rem; }
/* Grosor por token (ruleWidth): sin él, los 2px de siempre. */
.lb-shop-title::before { content:""; width:1.6rem; height:var(--rule-w); background:var(--lb-accent); display:inline-block; }
/* Tres tarjetas EXACTAS por página del raíl: con 21rem fijos en la columna de 1112px asomaban
   45px de una cuarta («BUN», «PVD 4», medio botón «Añadir»), un control partido que no se leía
   como peek sino como error. Las flechas .lb-prev/.lb-next ya paginan; ≤52rem sigue con su
   minmax (una tarjeta y media, ahí sí es un peek). */
.lb-rail { display:grid; grid-auto-flow:column; grid-auto-columns:calc((100% - 2 * 1.2rem) / 3); justify-content:start; gap:1.2rem; min-width:0;
  overflow-x:auto; scroll-snap-type:x mandatory; padding:.2rem .2rem 1rem; }
.lb-rail .pcard { scroll-snap-align:start; }
/* «Referencias del look»: con la historia a sangre, tres tarjetas dejaban dos tercios
   del raíl vacíos. Las columnas suben con el ancho, igual que la cuadrícula del
   catálogo. Va DESPUÉS de la declaración de arriba a propósito: misma especificidad,
   así que manda la última. Los ≤52rem se quedan con el «peek» de móvil de más abajo. */
@media (min-width:52.0625rem) {
  .lb-rail { --lb-cols:4;
    grid-auto-columns:calc((100% - (var(--lb-cols) - 1) * 1.2rem) / var(--lb-cols)); }
}
@media (min-width:81.25rem)  { .lb-rail { --lb-cols:5; } }
@media (min-width:106.25rem) { .lb-rail { --lb-cols:6; } }
/* En el lookbook la tarjeta NO es un enlace estirado: tiene su propia acción
   "Añadir", así que solo el nombre navega a la ficha (si no, el enlace tapa el botón). */
.lb-pcard .pcard-link::after { content:none; }
.lb-pcard .pcard-body { display:flex; flex-direction:column; gap:.35rem; }
.lb-add { position:relative; z-index:2; }
.lb-rail .pcard { transition:transform .2s var(--ease), box-shadow .2s var(--ease); }
.lb-rail .pcard:hover { transform:translateY(-4px); box-shadow:var(--shadow-card); }
.lb-add { margin-top:.4rem; display:inline-flex; align-items:center; justify-content:center; gap:.35rem;
  border:1px solid var(--blue); background:transparent; color:var(--blue-text); border-radius:var(--r-sm);
  padding:.5rem .7rem; font:inherit; font-size:.85rem; font-weight:600; cursor:pointer; width:100%;
  transition:background .15s var(--ease), color .15s var(--ease); }
.lb-add:hover { background:var(--blue); color:#fff; }
.lb-add.on { background:var(--blue); color:#fff; border-color:var(--blue); }

.lb-close { text-align:center; padding:3rem 1rem 1rem; }
.lb-close p { font-family:var(--display); font-size:1.4rem; color:var(--ink); margin:0 0 1.2rem; }
.lb-close .btn-primary { text-decoration:none; display:inline-flex; align-items:center; gap:.4rem; }

/* Barra flotante "Tu selección" */
.lb-selbar { position:fixed; right:1.5rem; bottom:6rem; z-index:44; }
.lb-selbar-toggle { display:inline-flex; align-items:center; gap:.5rem; background:var(--blue); color:#fff;
  border:none; border-radius:999px; padding:.75rem 1.3rem; font:inherit; font-weight:700; cursor:pointer;
  box-shadow:var(--shadow-card); }
.lb-selbar-toggle:hover { background:var(--blue-deep); }
.lb-selpanel { position:absolute; right:0; bottom:calc(100% + .6rem); width:min(24rem,90vw);
  background:var(--card); border:1px solid var(--line); border-radius:var(--r); box-shadow:var(--shadow-card);
  padding:1rem 1.1rem 1.2rem; }
.lb-selpanel-head { display:flex; align-items:baseline; justify-content:space-between; margin-bottom:.7rem; }
.lb-sellist { list-style:none; margin:0; padding:0; display:grid; gap:.6rem; max-height:50vh; overflow-y:auto; }
.lb-sellist li { display:grid; grid-template-columns:2.6rem 1fr auto; gap:.6rem; align-items:center; }
.lb-selthumb { width:2.6rem; height:2.6rem; border-radius:var(--r-sm); overflow:hidden; background:var(--surface); }
.lb-selthumb img { width:100%; height:100%; object-fit:cover; }
.lb-selinfo { display:flex; flex-direction:column; min-width:0; }
.lb-selinfo b { font-size:.85rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lb-selinfo span { font-size:.75rem; color:var(--muted); }
.lb-selacts { display:flex; align-items:center; gap:.3rem; }
.lb-sizes { padding:.35rem .6rem; font-size:.78rem; text-decoration:none; }
.lb-selremove { display:grid; place-items:center; width:1.7rem; height:1.7rem; border:none; background:none;
  color:var(--muted); cursor:pointer; border-radius:50%; }
.lb-selremove:hover { background:var(--accent-soft); color:var(--accent-deep); }
.lb-selhint { font-size:.8rem; color:var(--muted); margin:.8rem 0 0; }
.lb-selpdf { width:100%; margin-top:.7rem; display:inline-flex; align-items:center; justify-content:center; gap:.4rem; }

@media (max-width:52rem) {
  .lb-story, .lb-story.lb-right { grid-template-columns:1fr; gap:1.2rem;
    grid-template-areas:"media" "text" "shop"; }
  .lb-story-text h2 { font-size:1.7rem; }
  .lb-rail { grid-auto-columns:minmax(11rem,72%); min-width:0; }
  .lb-selbar { right:1rem; bottom:5.5rem; }
}

@media (max-width:60rem) {
  .ms-clients { grid-template-columns:1fr; }
  .ms-selected { position:static; }
}

/* ── Modal de suplantación (dlg-select) ── */
.dlg-select { max-width:min(40rem,94vw); width:40rem; }
.sel-panel { padding:1.6rem 1.7rem 1.4rem; }
.sel-head { border-bottom:1px solid var(--line); padding-bottom:1rem; margin-bottom:1.1rem; }
.sel-kicker { margin:0; font-size:.72rem; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:var(--muted); }
.sel-panel h2 { font-family:var(--display); font-weight:500; font-size:1.7rem; letter-spacing:-.02em;
  text-transform:none; margin:.2rem 0 .5rem; }
.sel-country { margin:0; color:var(--ink-2); font-size:.9rem; }
.sel-country b { color:var(--ink); }
.sel-actions-title { margin:0 0 .7rem; font-size:.72rem; font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; color:var(--muted); }
.sel-actions { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:.7rem; }
.sel-card { display:flex; flex-direction:column; gap:.4rem; text-align:left; text-decoration:none;
  border:1px solid var(--line-control); border-radius:var(--r-sm); padding:.95rem .9rem; background:#fff;
  transition:border-color .15s var(--ease), background .15s var(--ease), transform .15s var(--ease); }
.sel-card:hover:not([disabled]) { border-color:var(--blue); background:var(--blue-soft); transform:translateY(-2px); }
.sel-card[disabled] { opacity:.55; cursor:progress; }
.sel-card-title { font-weight:700; font-size:.82rem; letter-spacing:.02em; text-transform:uppercase;
  color:var(--blue-text); }
.sel-card-desc { font-size:.8rem; color:var(--muted); line-height:1.35; }
.sel-error { margin:1rem 0 0; color:var(--out); font-size:.86rem; }

@media (max-width:52rem) {
  .h-menu-agent { min-width:min(20rem,88vw); }
  .h-menu-agent .h-groups { grid-template-columns:1fr; }
  .h-release span { display:none; }
  .sel-actions { grid-template-columns:1fr; }
  .cl-tools .cl-new { margin-left:0; width:100%; }
}

/* ═══════════════════ Rediseño MODERNIST — capa de ajustes ═══════════════════
   Se aplica al final (gana por cascada): radio 0, nav MAYÚSCULAS + rojo, titulares
   800, checkbox/celda de talla en su color, fotos de catálogo en B/N. */

h1,h2,h3,h4,h5,h6,.title,.card-title { font-weight:800; letter-spacing:var(--brand-tracking,-.02em); }

/* Radio 0 en lo que quedaba redondeado (avatar y cart = rectos). El 0 sale ahora de
   --r, el radio GENERAL: sin token vale 0px (Modernist de MITO, idéntico a antes) y
   con el token `radius` estas piezas dejan de ser la excepción recta del portal. */
.item-units,.chip,.viewer-badge,
.viewer-hint,.pcard-360,.ch-hbar-track,.ch-hbar-track span,.login-card .field,
.activate-card .activate-form .field,
.grid-drop,.ck-drop,.h-menu a,.h-menu button,
.viewer-thumb { border-radius:var(--r,0) !important; }
/* Los controles con forma de botón tienen su propio radio (token radiusButton);
   si no se configura, caen en el general. */
.avatar,.h-lang,.h-cart,.cta,.btn-primary,.submit,.login-card .submit,
.item-fav,.product-fav,#chrome-footer .social a,.c-arrow,
.viewer-zoom { border-radius:var(--r-btn,var(--r,0)) !important; }

/* Nav de cabecera: MAYÚSCULAS, activo/hover en rojo, regla inferior = filete de CAPÍTULO
   (sin tokens, 2px de tinta como siempre; con rule/ruleWidth, el filete de la marca: antes
   el 2px negro pisaba el filete rojo de 1px de la cabecera y había tres acentos en 55px). */
#chrome-nav { border-bottom:var(--rule-w) solid var(--rule); }
#chrome-nav a { text-transform:uppercase; font-weight:700; font-size:.82rem; letter-spacing:var(--brand-tracking,.05em); }
/* El texto del activo va en --blue-text (el rojo medido para texto pequeño, 5,9:1 en MITO);
   el subrayado se queda en 2px y en --blue: con el filete del nav a 1px, un subrayado de 1px
   caería sobre la misma línea y el estado activo desaparecería. */
#chrome-nav a[aria-current="page"], #chrome-nav a.active { color:var(--blue-text); border-bottom-color:var(--blue); }

/* Controles nativos en rojo */
input[type=checkbox], input[type=radio] { accent-color:var(--blue); }
/* Facetas y términos: marca en ROJO (era tinta negra) */
.rail-check input:checked, .ck-terms input:checked { background:var(--blue); border-color:var(--blue); }

/* Matriz de tallas: cabecera de celda en NEGRO con número claro (referencia 03) */
.sz-head { background:var(--ink); color:#fff; }
.sz-price { color:rgba(255,255,255,.72); }

/* Solo el HERO de campaña va en B/N (foto de ambiente); los PRODUCTOS en color
   para que el comprador vea la tonalidad real (decisión del cliente sobre el handoff). */
.hero-media .c-slide img, .hero-media .c-video { filter:var(--hero-filter,grayscale(1) contrast(1.05)); }

/* ── Marca configurable: MAYÚSCULAS de los titulares (token caps) ──
   Solo las piezas de display que hoy van en caja normal: nav, botones, chips y
   etiquetas ya están en mayúsculas, así que el token no tiene nada que hacer ahí.
   Sin token el valor es «none», que es exactamente lo que heredan hoy. */
h1.title, .hero-title, .dash-greet, .kpi-value, .c-caption strong, .login-h, .cred-h,
.cred-meta b, .product-name, .item h2, .pcard-name, .brand { text-transform:var(--brand-caps,none); }

/* Hero de portada: título pesado, saludo sin itálica, CTA recto */
.hero-title { font-weight:800; letter-spacing:var(--brand-tracking,-.02em); }
.dash-greet { font-style:normal; font-weight:700; }
.hero-cta { border-radius:var(--r-btn,var(--r,0)) !important; }

/* KPIs de portada: cifra sobre REGLA superior de 2px (sin tarjeta ni sombra) */
.kpi { background:none; border:0; border-top:var(--rule-w) solid var(--rule); border-radius:0; padding:.9rem 0 0; }
.kpi:hover { transform:none; box-shadow:none; }
.kpi-accent { background:none; border-top-color:var(--blue); }
.kpi-value { font-weight:800; }
.kpi-accent .kpi-value { color:var(--accent-deep); }

/* ── Auditoría Modernist: paleta vieja → rojo/neutro, tablas planas, B/N ── */
/* Tablas de documento: sin caja ni sombra; cabecera con regla 2px (no barra gris) */
table.grid { background:none !important; border:0 !important; box-shadow:none !important; }
table.grid th { background:none !important; border-bottom:var(--rule-w) solid var(--rule) !important; color:var(--muted); }

/* Puntos de estado (rail) → rojo (activo/negativo) o neutro (cerrado); fuera semáforo */
.srail-dot.tone-blue, .srail-dot.tone-lime, .srail-dot.tone-amber,
.srail-dot.tone-orange, .srail-dot.tone-green { background:var(--ink-3) !important; }
.srail-dot.tone-red { background:var(--blue) !important; }
/* Chips de estado → rojo-tenue (activo/cancelado) o neutro (servido/facturado) */
.chip.tone-blue, .chip.tone-lime, .chip.tone-amber,
.chip.tone-orange, .chip.tone-green { background:var(--surface) !important; color:var(--ink-2) !important; }
.chip.tone-red { background:var(--blue-soft) !important; color:var(--accent-deep) !important; }
.cal-kind-cita { background:var(--blue-soft) !important; color:var(--accent-deep) !important; }

/* Terracota (#e15b47) → rojo único en piezas de marca */
.avatar, .h-cart, #assistant-fab { background:var(--blue) !important; }
#assistant-fab:hover { background:var(--blue-deep) !important; }
#assistant-fab { border-radius:var(--r-btn,var(--r,0)) !important; }


/* Cuadros de mando: KPI como cifra sobre regla superior de 2px (igual que portada) */
.bd-kpi { background:none; border:0; border-top:var(--rule-w) solid var(--rule); border-radius:0; padding:.9rem 0 0; box-shadow:none; }
.bd-kpi-value { font-weight:800; }

/* Semáforo de disponibilidad de la matriz: solo rojo/neutro (fuera el ámbar) */
.sz.low .sz-stock i { background:var(--ink-3) !important; }
.sz.out .sz-stock i { background:var(--blue) !important; }

/* Banda "MODO AGENTE" (referencia 14): franja roja a todo el ancho bajo la cabecera */
.agent-band { background:var(--blue); color:#fff; font-weight:700; text-transform:uppercase;
  letter-spacing:.05em; font-size:.8rem; padding:.7rem var(--gutter); }

/* Reglas 2px entre grupos de facetas (referencia 03) */
.rail section + section { border-top:var(--rule-w) solid var(--brand-rule,var(--line-control)); padding-top:1.4rem; }

/* Conmutador de vista segmentado del catálogo (Listado / Cuadrícula), activo rojo */
/* Sin overflow:hidden: el raíl del foco global (:focus-visible, outline-offset:2px) se
   dibuja 4px POR FUERA del padding box del contenedor, así que un clip lo borraba
   entero en el conmutador (WCAG 2.4.7). El redondeo del token va en los propios
   botones, que es lo único que el clip pretendía recortar. */
/* Cuarta pieza del sistema de controles: el grupo de botones. Toma el MISMO alto
   (--ctl-h) que la carcasa .tb-select para que la fila de Análisis —desplegable,
   dos fechas y «Últimos 12 meses · Este año · Año anterior»— quede a plomo. Antes
   medía 39px contra los 43px de los otros tres y el escalón se veía. */
.tb-seg { display:inline-flex; border:1px solid var(--ink); border-radius:var(--r,0);
  height:var(--ctl-h); }
.tb-seg-opt { display:inline-flex; align-items:center; gap:.4rem; padding:0 .9rem; font:inherit;
  font-size:.85rem; font-weight:600; background:var(--card); color:var(--ink); border:0; cursor:pointer; }
.tb-seg-opt:first-child { border-start-start-radius:var(--r,0); border-end-start-radius:var(--r,0); }
.tb-seg-opt:last-child { border-start-end-radius:var(--r,0); border-end-end-radius:var(--r,0); }
.tb-seg-opt + .tb-seg-opt { border-left:1px solid var(--ink); }
.tb-seg-opt.on { background:var(--blue); color:#fff; }
.tb-seg-opt svg { display:block; }

/* Listados de documentos: rail de estados vertical → TABS horizontales (ref. 04/09) */
.page.docs { display:block; }
.docs-rail { border-right:0; padding:0; margin:.2rem 0 1.6rem; }
.srail { flex-direction:row; flex-wrap:wrap; gap:0; border-bottom:var(--rule-w) solid var(--brand-rule,var(--line-control)); }
.srail-item { border:0; border-bottom:2px solid transparent; border-radius:0; padding:.6rem 1rem;
  font-size:.8rem; font-weight:700; text-transform:uppercase; letter-spacing:.03em; color:var(--muted); width:auto; }
.srail-item:hover { background:none; color:var(--ink); }
.srail-item.on { border-bottom-color:var(--blue); color:var(--blue); }
.srail-item.on .srail-count { color:var(--blue); }
.srail-item .srail-dot { display:none; }

/* ── Auditoría final Modernist: pulido pixel ── */
/* Buscador de cabecera: relleno gris sin borde (foco rojo) */
.h-search input { background:var(--surface); border-color:transparent; }
.h-search input:focus, .h-search input:focus-visible { border-color:var(--blue); }
/* Migas en Título, no MAYÚSCULAS */
.crumbs { text-transform:none; }
/* Faceta de línea activa en rojo */
.rail a.on, .rail-link.on, .rail li.on > a, .rail .on { color:var(--blue); }
/* Botones anchos con la etiqueta a la IZQUIERDA (regla Modernist) */
.login-card .submit, .ck-side .btn-primary, .ck-side .btn-primary.block,
.docs-main .btn-primary, .cta.block, .btn-primary.block { justify-content:flex-start; text-align:left; padding-left:1.1rem; }
/* Checkout: resumen con borde 2px sin sombra; h1 visible */
.ck-side { border:var(--rule-w) solid var(--rule) !important; box-shadow:none !important; }
.page.checkout > .cat-headline > h1.title { position:static !important; width:auto !important; height:auto !important;
  clip:auto !important; clip-path:none !important; overflow:visible !important; white-space:normal !important;
  margin:0 !important; padding:0 !important; }
/* El nombre de cliente pasa a subtítulo del H1 */
.page.checkout .ck-client { font-size:1rem; color:var(--ink-2); font-weight:400; }
/* Hero del lookbook en B/N editorial */
.lb-hero .c-slide img, .lb-hero .c-video { filter:var(--hero-filter,grayscale(1) contrast(1.05)); }
/* Píldora de panel y lift de tarjetas del lookbook: coherencia radio 0 / sin sombra flotante */
.panel .tag { border-radius:var(--r,0); }
.lb-rail .pcard:hover { transform:none; box-shadow:none; }
/* Banda MODO AGENTE: solo "MODO AGENTE" fuerte, resto normal */
.agent-band { text-transform:none; font-weight:400; }
.agent-band strong { text-transform:uppercase; font-weight:800; letter-spacing:.05em; }

/* ── Ficha de producto (cap. 05): chips de atributo, PVD+PVP, botón ancho ── */
.product-attrs { display:flex; flex-wrap:wrap; gap:.5rem; align-items:center;
  margin:1.6rem 0 0; padding:1.5rem 0 0; border-top:var(--rule-w) solid var(--brand-rule,var(--line)); }
.product-attrs .tag, .product-sizes-head .tag { display:inline-flex; align-items:center; font-size:.72rem; font-weight:700;
  letter-spacing:.06em; text-transform:uppercase; color:var(--ink); background:none;
  border:1px solid var(--line-control); border-radius:var(--r,0); padding:.3rem .7rem; }
.tag-avail { border:var(--rule-w,2px) solid var(--blue); color:var(--accent-deep); }
/* PVD y PVP recomendado, uno al lado del otro, cifra sobre etiqueta */
.product-price { display:flex; align-items:flex-end; gap:2.6rem; margin:1.6rem 0 0; padding:1.5rem 0 0;
  border-top:var(--rule-w) solid var(--brand-rule,var(--line)); }
.pp-col { display:flex; flex-direction:column; gap:.2rem; }
.pp-col span { font-size:.7rem; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-2); }
.pp-col b { font-family:var(--display); font-size:2rem; line-height:1; letter-spacing:-.02em; }
.pp-col:nth-child(2) b { font-size:1.4rem; color:var(--ink-2); font-weight:700; }
/* Encabezado "CANTIDAD POR TALLA" sobre la matriz */
.product-sizes-h { font-family:var(--display); font-size:.8rem; font-weight:800; letter-spacing:.06em;
  text-transform:uppercase; color:var(--ink); margin:0 0 .9rem; padding-bottom:.55rem;
  border-bottom:var(--rule-w) solid var(--rule); }
/* Botón "Añadir a REPOSICIÓN" a ancho completo: etiqueta izquierda + total derecha */
.product-order { display:block; margin-top:1.6rem; }
.product-order :is(.btn-primary, .btn-ghost) { display:flex; width:100%; align-items:center; justify-content:space-between;
  gap:1rem; text-align:left; padding:.95rem 1.4rem; }
.product-order :is(.btn-primary, .btn-ghost) .product-total { color:#fff; font-size:.95rem; }
.product-order :is(.btn-primary, .btn-ghost) .product-total b { color:#fff; font-family:var(--display); }
/* El hint («Elige tallas y cantidades») heredaba el .95rem del total y el uppercase/700 del
   botón: salía MÁS grande que el rótulo real y, en blanco al 75 %, a 3,0:1 sobre el rojo.
   Blanco puro (4,7:1) y tamaño/peso de nota, en caja normal. */
.product-order :is(.btn-primary, .btn-ghost) .product-hint { color:#fff; font-size:.82rem; font-weight:500; text-transform:none; letter-spacing:.02em; }

/* ── Calendario (cap. 10): tarjeta a la izquierda + tipo segmentado + agenda plana ── */
.cal-form-wrap { text-align:left; color:var(--ink); }
.cal-form-wrap h2 { text-transform:uppercase; font-weight:800; font-size:.95rem; letter-spacing:.05em; color:var(--ink); }
.cal-form .acc-label { display:block; font-size:.7rem; font-weight:700; letter-spacing:.06em;
  text-transform:uppercase; color:var(--ink-2); margin:0 0 .35rem; }
.cal-form .tb-seg { display:inline-flex; width:100%; }
.cal-form .tb-seg-opt { flex:1; }
/* Agenda: lista plana con reglas 1px, sin recuadro por fila; el tipo, chip cuadrado neutro */
.cal-list { gap:0; }
.cal-item { background:none; border:0; border-bottom:1px solid var(--line); border-radius:0;
  padding:1.1rem 0; }
.cal-kind { border-radius:0; background:var(--surface); color:var(--ink-2);
  border:1px solid var(--line-control); padding:.12rem .45rem; }
.cal-kind-cita { background:var(--surface); color:var(--accent-deep); border-color:var(--blue); }
.cal-kind-parte { background:var(--surface); color:var(--ink-2); }

/* ── Cuadros de mando (cap. 09): paneles sin tarjeta, título sobre regla 2px ── */
.bd-panel { background:none; border:0; border-radius:0; padding:0; }
.bd-panel h2 { text-transform:uppercase; font-weight:800; font-size:.85rem; letter-spacing:.05em;
  padding-bottom:.6rem; border-bottom:var(--rule-w) solid var(--rule); margin:0 0 1.1rem; }
.bd-grid { gap:2.2rem 2rem; }
/* Cifra encima de cada barra (modo minimalista) */
.ch-val { fill:var(--ink); font-family:var(--display); font-weight:800; font-size:15px; }
.ch-min .ch-xlab { fill:var(--ink-2); font-weight:600; }

/* ══════════════ Productos relacionados (cross/up-selling de BC) ══════════════ */
/* Raíl horizontal compartido: la ficha ("Completa la gama", a lo ancho, regla de
   capítulo en tinta) y el checkout (".related-compact", bajo las líneas y discreto
   para no estorbar la compra). Sin relacionados la sección no se pinta (JS). */
.related { margin:3.6rem 0 0; padding-top:2rem; border-top:var(--rule-w) solid var(--rule);
  opacity:0; translate:0 14px;
  transition:opacity .5s var(--ease), translate .5s var(--ease); }
.related.on { opacity:1; translate:0 0; }
.related-head { display:flex; align-items:flex-end; justify-content:space-between;
  gap:1.2rem; margin-bottom:1.5rem; }
.related-title { margin:0; font-family:var(--display); font-size:1.5rem; letter-spacing:-.02em; }
.related-sub { margin:.4rem 0 0; font-size:.9rem; color:var(--muted); }
/* Flechas: solo cuando el raíl desborda (JS pone .has-nav); apagadas en los extremos */
.related-nav { display:none; gap:.5rem; flex:none; }
.related.has-nav .related-nav { display:flex; }
.related-arrow { width:2.6rem; height:2.6rem; display:inline-flex; align-items:center;
  justify-content:center; border:1px solid var(--line-control); border-radius:0;
  background:var(--card); color:var(--ink); cursor:pointer; padding:0;
  transition:border-color .15s var(--ease), opacity .15s var(--ease); }
.related-arrow:hover:not([disabled]) { border-color:var(--ink); }
.related-arrow[disabled] { opacity:.3; cursor:default; }
.related-arrow svg { flex:none; }
/* El raíl: columnas fijas (4 a la vista en escritorio), snap y barra oculta —
   se navega con las flechas, con el dedo o tabulando por las cards */
.related-rail { display:grid; grid-auto-flow:column; justify-content:start; gap:1.4rem;
  grid-auto-columns:clamp(12.5rem, calc((100% - 3 * 1.4rem) / 4), 19rem);
  overflow-x:auto; overscroll-behavior-x:contain; scroll-snap-type:x mandatory;
  padding:.3rem .3rem .5rem; scroll-padding-left:.3rem; scrollbar-width:none; }
.related-rail::-webkit-scrollbar { display:none; }
.related-cell { scroll-snap-align:start; min-width:0; display:flex; }
.related-cell .pcard { flex:1; }
/* Up-selling: etiqueta "De la colección" sobre la foto (los otros colores van sin etiqueta) */
.rel-badge { position:absolute; top:.7rem; left:.7rem; z-index:2; font-size:.64rem;
  font-weight:800; letter-spacing:.08em; text-transform:uppercase; color:#fff;
  background:var(--ink); padding:.34rem .6rem; }

/* Checkout: variante compacta — título menor, cards de 5 a la vista, regla fina */
.related-compact { margin:2rem 0 0; padding-top:1.5rem; border-top:1px solid var(--line); }
/* En el checkout el bloque es hija DIRECTA de .ck-grid (no de .ck-main): en
   escritorio se ancla a la columna de las líneas (misma posición de siempre) y en
   columna única el flujo del documento lo deja el ÚLTIMO — después del resumen y
   de TERMINAR PEDIDO, para que las sugerencias nunca se interpongan ante el CTA. */
.ck-grid > .related-compact { grid-column:1; min-width:0; }
.related-compact .related-head { margin-bottom:1rem; }
.related-compact .related-title { font-size:1.15rem; }
.related-compact .related-sub { font-size:.82rem; margin-top:.25rem; }
.related-compact .related-arrow { width:2.2rem; height:2.2rem; }
.related-compact .related-rail { gap:1rem;
  grid-auto-columns:clamp(9.5rem, calc((100% - 4 * 1rem) / 5), 12rem); }
.related-compact .pcard-body { padding-top:.7rem; }
.related-compact .pcard-name { font-size:.95rem; }
.related-compact .pcard-ref { font-size:.76rem; }
.related-compact .pcard-price { margin-top:.4rem; }
.related-compact .pcard-price b { font-size:1.05rem; }
.related-compact .pcard-cta { font-size:.7rem; margin-top:.5rem; }
/* El badge nunca debe partirse en dos líneas ni salirse de la card (crítica: EN
   "From the collection" envolvía sobre la card compacta de 152px). */
.related-compact .rel-badge { font-size:.62rem; padding:.28rem .45rem; letter-spacing:.04em;
  max-width:calc(100% - 1.4rem); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

@media (max-width:48rem) {
  .related { margin-top:2.6rem; padding-top:1.6rem; }
  .related-title { font-size:1.25rem; }
  .related-rail { grid-auto-columns:70%; gap:1rem; }
  .related-compact .related-rail { grid-auto-columns:11rem; }
  /* En táctil manda el dedo: el snap ya pagina y las flechas solo estorban */
  .related.has-nav .related-nav { display:none; }
}
@media (prefers-reduced-motion:reduce) {
  .related, .product-alsoin, .product-alsoin-slot { transition:none; opacity:1; translate:none; }
}

/* Alineación del raíl: el nombre reserva SIEMPRE dos líneas (y recorta a dos),
   así referencia, precio y CTA quedan a la misma altura en todas las cards
   aunque un nombre ocupe una línea y el vecino dos. */
.related-rail .pcard-name { display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2;
  overflow:hidden; min-height:2.4em; }
/* Las cards compactas del checkout son más estrechas: tres líneas de nombre para
   no amputar referencias largas (y se reservan las tres, alineación intacta). */
.related-compact .related-rail .pcard-name { -webkit-line-clamp:3; min-height:3.6em; }

/* ── 14c: suplantación, líneas bloqueadas, agente en pedidos, surtido del selector ── */
.ck-managed { display:flex; align-items:center; gap:.4rem; margin:-.6rem 0 1.1rem; font-size:.84rem; color:var(--muted); }
.ck-managed svg { flex:none; color:var(--hint); }
/* Grupo que el servidor rechazó: se ve cuál es sin leer el aviso lateral */
.ck-group.is-blocked { border-color:var(--accent-deep); background:var(--accent-soft); }
.ck-blocked { display:inline-flex; align-items:center; gap:.3rem; margin-left:.6rem; vertical-align:middle;
  font-size:.68rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  color:var(--accent-deep); background:var(--accent-soft); border:1px solid var(--accent-deep); padding:.14rem .5rem; }
.ck-drop-blocked { margin-top:.55rem; max-width:100%; white-space:normal; text-align:left; }
.ck-pay-note { display:block; margin-top:.35rem; font-size:.76rem; line-height:1.45; color:var(--hint);
  font-weight:400; text-transform:none; letter-spacing:0; }
.doc-agent { display:block; margin-top:.15rem; font-size:.72rem; font-weight:400; color:var(--muted); }
/* Es una ANOTACIÓN del título del modal, no un tercer control: el margen auto se come
   el espacio libre que si no repartiría el justify-content:space-between de .mp-head a
   ambos lados (79px de deriva), y deja el distintivo pegado al h2 con el gap de 1rem.
   nowrap + elipsis (mismo patrón que .rel-badge) para que en anchos estrechos no parta
   la cabecera en dos líneas. */
.mp-scope { display:inline-flex; align-items:center; gap:.3rem; font-size:.7rem; font-weight:700;
  letter-spacing:.06em; text-transform:uppercase; color:var(--hint);
  border:1px solid var(--line-control); padding:.14rem .5rem;
  margin-inline-end:auto; white-space:nowrap; max-width:100%; overflow:hidden; text-overflow:ellipsis; }

/* ══════════════ Análisis (tabla dinámica) ══════════════
   NI UN LITERAL DE COLOR: todo sale de los tokens de :root, que las tres marcas vivas
   reescriben (`html[data-hero-style="paper"|"photo"]`). Un `#333` aquí rompería ALMA EN
   PENA y POLO CLUB en la primera pantalla que abrieran.
   La rejilla HEREDA de `table.grid`: mismas cabeceras, mismos hilos, mismo silencio; lo
   único propio es lo que un pivote necesita y un listado no —sangría por nivel, cabecera
   y pie fijados, y una columna de concepto que no se va con el scroll horizontal—. */

/* La tabla dinámica es una superficie de REJILLA, no de lectura: se le da el ancho
   amplio del catálogo en vez de la medida de 1240 px de las páginas de texto. */
/* Ídem: Análisis se adscribe a REJILLA DE DATOS por su clase, no con su propio tope.
   Baja de --maxw-wide (2400) a --w-grid (2000) A PROPÓSITO: la tabla dinámica es una
   tabla, y su panel de campos ya se lleva 272 px fijos de la izquierda. */

.an-shell { display:grid; grid-template-columns:17rem minmax(0,1fr); gap:2rem; align-items:start; }
.an-main { min-width:0; }
.an-side { min-width:0; position:sticky; top:calc(var(--header-h) + 1rem); }
.an-notice { align-items:flex-start; }
.an-notice-soft { background:var(--surface); color:var(--ink-2); }
.an-fixes { display:flex; flex-wrap:wrap; gap:1rem; margin-top:.4rem; }
.an-fixes .link { font-size:.85rem; }

/* Recalculando: el tablero anterior NO se vacía —quien compara necesita seguir viéndolo—,
   baja de opacidad y una barra fina de 2px dice que hay algo en camino (mismo lenguaje que
   `.cat-list.is-loading` en el filtrado de listados). */
.an-board { position:relative; }
.an-board.is-busy .an-scroll { opacity:.45; pointer-events:none; transition:opacity .15s var(--ease); }
.an-board.is-busy::before { content:""; position:absolute; inset:0 0 auto; height:2px; z-index:4;
  background:linear-gradient(to right, transparent, var(--blue), transparent);
  animation:an-progress 1.1s linear infinite; }
@keyframes an-progress { from { background-position:-40% 0; } to { background-position:140% 0; } }
@media (prefers-reduced-motion:reduce) { .an-board.is-busy::before { animation:none; } }

/* El scroll —los dos ejes— vive SOLO aquí: la página nunca desborda de lado, y acotar la
   altura es lo que permite que la cabecera y el pie se queden fijados dentro de la caja. */
.an-scroll { overflow:auto; overscroll-behavior-x:contain;
  max-height:calc(100vh - 18rem); min-height:16rem; }

/* `overflow:hidden` (lo hereda de table.grid, que lo lleva para recortar su radio) crea
   un contenedor de recorte y ANULA el `position:sticky` de la cabecera y de la columna
   de concepto: el pivote no tiene radio que recortar, así que lo suelta. */
table.an { --an-indent:1.15rem; border-radius:0; overflow:visible; }
table.an th, table.an td { border-bottom:1px solid var(--line); }

/* Cabecera fijada. La segunda fila (medida por medida, cuando hay columnas Y varias
   medidas) se cuelga justo debajo de la primera con la altura REAL que mide el módulo.
   El `!important` del fondo NO es un capricho: la capa Modernist declara
   `table.grid th { background:none !important }`, y una celda fijada TRANSPARENTE deja
   pasar por debajo el texto de lo que se está desplazando. Se usa --paper, que es el
   color que ya se ve hoy detrás de la tabla, así que el aspecto no cambia. */
.an thead th { position:sticky; top:0; z-index:3; white-space:nowrap;
  background-color:var(--paper) !important; }
.an thead tr:nth-child(2) th { top:var(--an-head-h, 2.4rem); z-index:2; }
.an-colgroup { text-align:center; }
/* Con cabecera de dos pisos, el filete de capítulo va bajo el SEGUNDO: si no, la banda de
   los meses y la de las medidas quedan separadas por una regla de 2px que las divorcia. */
.an thead tr:first-child:not(:last-child) th { border-bottom:1px solid var(--line) !important; }
.an-dim-text, .an-col-text { display:inline-block; vertical-align:middle; }

/* La columna de concepto no se va con el scroll horizontal: sin ella, a la tercera columna
   de meses ya no se sabe de qué fila es el número que se está mirando. */
.an .an-dim, .an .an-cell-dim { position:sticky; left:0; min-width:14rem; }
.an .an-dim { z-index:4; }
/* La celda de concepto es un `th` de FILA, y `table.grid th` (más la capa Modernist) la
   viste de CABECERA: versalitas de .7rem, tinta apagada y el filete de 2px de capítulo
   debajo. En un pivote eso es falso —el nombre del modelo es contenido, no un rótulo— y
   además dejaba la columna de la izquierda con un subrayado grueso que las de cifras no
   tienen. Se le devuelve el tamaño y el hilo de una celda normal. */
.an .an-cell-dim { z-index:1; background-color:var(--paper) !important; text-align:left;
  font-size:.9rem; font-weight:400; letter-spacing:0; text-transform:none; color:var(--ink);
  padding-top:.8rem; padding-bottom:.8rem; border-bottom:1px solid var(--line) !important;
  padding-left:calc(1.1rem + var(--an-indent) * var(--lvl, 0));
  /* Guías verticales de la sangría con UNA sola trama, sin un solo nodo extra en el DOM */
  background-image:repeating-linear-gradient(to right, var(--line) 0 1px, transparent 1px var(--an-indent));
  background-repeat:no-repeat; background-position:1.1rem 0;
  background-size:calc(var(--an-indent) * var(--lvl, 0)) 100%; }
/* En una rejilla ancha, seguir una fila con la vista es la mitad del trabajo: el pivote sí
   marca la fila bajo el puntero (en el listado normal el realce cae en --paper, que bajo
   Modernist es el propio fondo y no se ve). */
.an tbody tr:hover td, .an tbody tr:hover .an-cell-dim { background-color:var(--surface) !important; }
/* Un nombre de modelo largo no puede llevarse media pantalla de ancho: se recorta con
   puntos suspensivos y el texto completo queda en el `title`. */
.an-label { display:inline-block; max-width:22rem; overflow:hidden; text-overflow:ellipsis;
  white-space:nowrap; vertical-align:middle; }
.an-group .an-label { font-weight:600; }
/* «Otros» es un grupo real con su importe (Σ hijos == bucket del padre), no un hueco:
   se distingue en apagado, pero sigue siendo una fila con su número. */
.an-other .an-label { color:var(--muted); font-style:italic; }
.an-children { margin-left:.4rem; font-size:.7rem; color:var(--muted); vertical-align:middle; }

.an-twist-slot { display:inline-block; width:1.1rem; }
.an-twist { width:1.1rem; color:var(--muted); vertical-align:middle; }
.an-twist:hover { color:var(--ink); }
.an-twist[aria-expanded="false"] svg { rotate:-90deg; }
.an-twist svg { transition:rotate .12s var(--ease); }
@media (prefers-reduced-motion:reduce) { .an-twist svg { transition:none; } }

/* El «⋯» solo aparece cuando la fila está bajo el puntero o el foco: veinte puntos
   suspensivos permanentes convierten la rejilla en ruido. Sigue siendo alcanzable con el
   tabulador (opacidad, no display) y en pantalla táctil se ve siempre. */
.an-more { margin-left:.45rem; padding:0 .25rem; color:var(--muted); opacity:0; vertical-align:middle; }
.an tr:hover .an-more, .an th:hover .an-more, .an-more:focus-visible,
.an tr:focus-within .an-more { opacity:1; }
.an-more:hover { color:var(--blue); }
@media (hover:none) { .an-more { opacity:1; } }

.an-num { text-align:right; white-space:nowrap; min-width:7.5rem; }
.an-sort { width:100%; text-align:right; font:inherit; color:inherit; letter-spacing:inherit;
  text-transform:inherit; }
.an-sort:hover { color:var(--blue); }
.an th[aria-sort="descending"] .an-sort::after { content:" ↓"; }
.an th[aria-sort="ascending"] .an-sort::after { content:" ↑"; }
/* La columna TOTAL se separa de las de detalle con un hilo, no con un color */
.an .an-tot { border-left:1px solid var(--line); }

/* EL TOTAL GENERAL SE DISTINGUE POR CUATRO COSAS A LA VEZ —filete, mayúsculas, tipografía
   de titulares y pie fijado—, no solo por el peso: en una tabla con tres niveles de
   sangría el negrita se pierde entre los subtotales. */
.an tfoot th, .an tfoot td { position:sticky; bottom:0; z-index:3;
  background-color:var(--surface) !important;
  border-top:var(--rule-w) solid var(--rule); border-bottom:none !important;
  font-family:var(--display); font-size:.85rem; text-transform:uppercase; letter-spacing:.04em;
  color:var(--ink); }
.an tfoot th { left:0; z-index:4; text-align:left; }
.an-foot { margin:.7rem 0 0; font-size:.78rem; color:var(--muted); }

/* Fantasma de la primera carga: la CABECERA es la de verdad (los rótulos ya han llegado
   con /fields) y solo las celdas son bloques grises, para que al llegar el dato la tabla
   no salte y quien estaba leyendo no pierda el sitio. */
.an-ghost { display:block; height:.85rem; width:70%; margin-left:auto; background:var(--surface);
  background-image:linear-gradient(100deg,transparent 20%,rgba(255,255,255,.7) 50%,transparent 80%);
  background-size:220% 100%; animation:sheen 1.4s var(--ease) infinite; }
.an-cell-dim .an-ghost { width:60%; margin-left:0; }
.an-empty .cta { margin-top:1.1rem; }

/* Menú «⋯»: FIJO al viewport y colgado del <body>. Dentro de `.an-scroll`, que es un
   contenedor de scroll, un menú absoluto se recorta contra el borde de la rejilla. */
.an-menu { position:fixed; top:0; left:0; min-width:13rem; }

/* ── Panel de campos ────────────────────────────────────────────────────────── */
.an-panel { display:grid; gap:1.4rem; }
.an-zone-title { display:block; font-size:.7rem; font-weight:700; letter-spacing:.07em;
  text-transform:uppercase; color:var(--hint); margin-bottom:.5rem; }
.an-zone-empty { margin:0 0 .5rem; font-size:.82rem; color:var(--muted); }
.an-chips { list-style:none; margin:0 0 .5rem; padding:0; display:grid; gap:.35rem; }
.an-chip { display:flex; align-items:center; gap:.15rem; border:1px solid var(--line-control);
  padding:.35rem .3rem .35rem .6rem; font-size:.85rem; background:var(--card); }
.an-chip:focus-visible { outline:2px solid var(--blue); outline-offset:1px; }
.an-chip-text { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.an-chip-btn { flex:none; width:1.5rem; height:1.5rem; display:grid; place-items:center;
  color:var(--muted); font-size:.9rem; line-height:1; }
.an-chip-btn:hover:not([disabled]) { color:var(--ink); }
.an-chip-btn[disabled] { opacity:.35; cursor:default; }
.an-chip-off:hover { color:var(--out); }
.an-add { margin-bottom:.2rem; }
.an-add .tb-select { padding:0 .5rem; }
.an-add select { min-width:0; width:100%; padding:.4rem 1.6rem .4rem .2rem; font-size:.82rem; }

.an-filter-values { list-style:none; border:1px solid var(--line); border-top:none;
  margin:-.35rem 0 .5rem; padding:.5rem .6rem; background:var(--surface); }
.an-filter-mode { font-size:.72rem; font-weight:700; letter-spacing:.05em; text-transform:uppercase;
  color:var(--muted); margin-bottom:.4rem; }
.an-filter-mode[aria-pressed="true"] { color:var(--blue-text); }
.an-filter-list { list-style:none; margin:0; padding:0; max-height:12rem; overflow-y:auto; }
.an-filter-list label { display:flex; align-items:center; gap:.4rem; padding:.15rem 0; font-size:.84rem; }
.an-filter-text input { width:100%; border:1px solid var(--line-control); border-radius:var(--r-sm);
  padding:.35rem .5rem; background:#fff; font-size:.84rem; }

.an-search { width:100%; border:1px solid var(--line-control); border-radius:var(--r-sm);
  padding:.45rem .6rem; background:#fff; margin-bottom:.6rem; font-size:.85rem; }
.an-list { list-style:none; margin:0; padding:0; max-height:22rem; overflow-y:auto; }
.an-list ul { list-style:none; margin:0 0 .6rem; padding:0; }
.an-list-title { display:block; font-size:.68rem; font-weight:700; letter-spacing:.06em;
  text-transform:uppercase; color:var(--muted); margin:.5rem 0 .25rem; }
.an-field { display:flex; align-items:center; gap:.45rem; padding:.18rem 0; font-size:.86rem; }
.an-field span { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* PREVENCIÓN, no explicación: el recuento de valores se ve ANTES de marcar la casilla del
   campo que haría estallar el resultado, no en un aviso después del recorte. */
.an-heavy { margin-left:auto; font-size:.7rem; color:var(--muted); white-space:nowrap; }

/* ── Cinta de análisis guardados ────────────────────────────────────────────── */
/* Reutiliza `.cat-ribbon/.rib-rail/.rib-chip` con marcado propio (ver views/analysis.js) */
.an-ribbon { margin:-.4rem 0 1.4rem; }
.an-rib-add { font-size:1rem; letter-spacing:0; }
.an-tools { align-items:flex-end; }
.an-tools-end { display:flex; align-items:center; gap:.6rem; margin-left:auto; flex-wrap:wrap; }
.an-detail-actions { display:flex; justify-content:flex-end; margin-top:1rem; }

/* ── El gráfico que abre Análisis ───────────────────────────────────────────── */
/* Estadísticas se fundió aquí y su gráfico es hoy la cabecera de la rejilla. Va DENTRO de
   la columna principal (.an-main), no encima de la pantalla entera, para que el panel de
   campos le quede AL LADO: quien solo quiere mirar, mira; quien quiere cruzar, cruza sin
   cambiar de sitio.
   Hereda `.stat-chart` y `.stat-title` de la pantalla de la que viene —mismo dibujo,
   mismos colores, mismo eje—, y solo cambia dos cosas: el rótulo baja de tamaño porque
   aquí cuelga de un H1 que en Estadísticas no tenía encima, y el lienzo se topa en 62rem.
   El SVG mantiene su proporción 3.49:1, así que a ancho completo (1.500 px en 1920) el
   gráfico mediría 430 px de alto y empujaría la tabla bajo el pliegue: 62rem lo dejan en
   los ~287 px de su lienzo, que es como se dibujó. */
.an-chart { margin:0 0 1.6rem; max-width:62rem; }
.an-chart .stat-title { font-size:1.15rem; margin:0 0 .7rem; }
/* Sin gráfico (demasiados grupos): se dice por qué en una línea en vez de desaparecer */
.an-chart-note { margin:0 0 1.2rem; color:var(--muted); font-size:.85rem; }

/* Puerta desde el cuadro de mando hacia el análisis */
.bd-panel h2 { display:flex; align-items:baseline; justify-content:space-between; gap:.8rem; }
.bd-analyze { flex:none; font-family:var(--brand-font,"Archivo"),system-ui,sans-serif;
  font-size:.72rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  color:var(--blue-text); text-decoration:none; white-space:nowrap; }
.bd-analyze:hover { text-decoration:underline; text-underline-offset:3px; }
.stat-title .bd-analyze { margin-left:.8rem; vertical-align:middle; }

/* ── Móvil (≤52rem) ─────────────────────────────────────────────────────────── */
@media (max-width:52rem) {
  .an-shell { grid-template-columns:1fr; gap:1rem; }
  .an-side { position:static; }
  .an-fields-btn { justify-self:start; }
  .an-scroll { max-height:calc(100vh - 14rem); }
  .an .an-dim, .an .an-cell-dim { min-width:11rem; }
  .an-num { min-width:6.5rem; }
  /* El panel pasa a hoja modal a ancho completo: el <dialog> ya trae velo, Escape,
     trampa de foco y devolución del foco; no hace falta inventar una capa. */
  .an-sheet { max-width:100vw; width:100vw; margin:auto 0 0; }
  .an-sheet .panel { padding:1.1rem 1.2rem 1.6rem; max-height:88vh; overflow-y:auto; }
  .an-list { max-height:none; }
  .an-tools-end { margin-left:0; width:100%; }
}

/* ══════════════ Previsión y objetivos del comercial ══════════════
   Base de la pantalla `views/plan.js` y de `ui/plan-grid.js`. Deliberadamente con la
   MISMA silueta que la rejilla de análisis —cabecera fijada, columna de sujeto pegada a
   la izquierda, fila de totales al pie con filete—: las dos funciones tienen que leerse
   como un solo producto y no como dos módulos pegados. */
.pl-tools { align-items:flex-end; }
.pl-thermo { margin:0 0 1.6rem; }
.pl-thermo svg { width:100%; height:auto; display:block; }
.pl-thermo-bar { fill:var(--blue); }
.pl-thermo-committed { fill:var(--blue-text); }
.pl-thermo-rest { fill:var(--surface); }
.pl-thermo-target { stroke:var(--ink); stroke-width:2; }
.pl-thermo-label { fill:var(--ink-2); font-size:12px; }

.pl-kpis { display:grid; grid-template-columns:repeat(auto-fit,minmax(9rem,1fr)); gap:1rem;
  margin-bottom:1.8rem; }
.pl-kpi { border-top:var(--rule-w) solid var(--rule); padding:.9rem 0 0; }
.pl-kpi-label { display:block; font-size:.72rem; text-transform:uppercase; letter-spacing:.05em;
  color:var(--muted); }
.pl-kpi-value { display:block; margin-top:.3rem; font-family:var(--display); font-size:1.6rem;
  letter-spacing:-.02em; color:var(--ink); }
/* «Sin objetivo» NO es un 0 %: un cero que en realidad es falta de dato es una mentira */
.pl-kpi-none { color:var(--muted); font-size:1.05rem; text-transform:none; }
.pl-kpi-note { display:block; margin-top:.2rem; font-size:.72rem; color:var(--muted); }

.pl-scroll { overflow:auto; overscroll-behavior-x:contain; max-height:calc(100vh - 20rem); }
table.pl { width:100%; border-collapse:separate; border-spacing:0; background:var(--card);
  border:1px solid var(--line); }
.pl thead th { position:sticky; top:0; z-index:3; background:var(--surface); color:var(--muted);
  font-size:.7rem; letter-spacing:.08em; text-transform:uppercase; font-weight:600;
  padding:.8rem .7rem; white-space:nowrap; border-bottom:1px solid var(--line); }
.pl tbody th { position:sticky; left:0; z-index:1; background:var(--card); text-align:left;
  font-weight:400; padding:.5rem .8rem; border-bottom:1px solid var(--line); min-width:13rem; }
.pl td { padding:.35rem .4rem; border-bottom:1px solid var(--line); text-align:right; }
.pl-cell { position:relative; min-width:6.5rem; }
/* Micro-barra apilada de fondo (facturado + comprometido): el dato real detrás de la cifra
   que se está escribiendo, sin robarle sitio ni contraste al número. */
.pl-bar { position:absolute; inset:auto 0 0; height:3px; background:var(--surface); }
.pl-bar span { display:block; height:100%; background:var(--blue); }
.pl-bar span + span { background:var(--blue-text); }
.pl-input { width:100%; text-align:right; border:1px solid transparent; border-radius:var(--r-sm);
  padding:.35rem .45rem; background:transparent; font-variant-numeric:tabular-nums; }
.pl-input:hover { border-color:var(--line-control); }
.pl-input:focus { border-color:var(--blue); background:#fff; outline:none; }
.pl-input[readonly] { color:var(--muted); cursor:default; }
.pl-locked { display:inline-flex; align-items:center; gap:.3rem; color:var(--muted); font-size:.8rem; }
.pl-suggest { display:block; font-size:.7rem; color:var(--muted); white-space:nowrap; }
.pl-manual .pl-input { border-color:var(--line-control); }
.pl tfoot th, .pl tfoot td { position:sticky; bottom:0; z-index:3; background:var(--surface);
  border-top:var(--rule-w) solid var(--rule); border-bottom:none;
  font-family:var(--display); text-transform:uppercase; letter-spacing:.04em; }
.pl tfoot th { left:0; z-index:4; text-align:left; }
.pl-actions { display:flex; gap:.6rem; flex-wrap:wrap; margin-top:1.2rem; }

@media (max-width:52rem) {
  /* Objetivo táctil de 44 px en la celda editable, que es donde se escribe de verdad */
  .pl-input { padding:.7rem .5rem; }
  .pl tbody th { min-width:10rem; }
  .pl-scroll { max-height:calc(100vh - 16rem); }
}

/* ═══════════ Marca configurable: peso de los TITULARES (token displayWeight) ═══════════
   Los titulares de página van a 500 y los de acceso/hero a 800 por reglas con clase
   (h1.title, .product-name, .item h2… especificidad 0,1,1) que ganan a la regla Modernist
   «h1,h2,h3{font-weight:800}» (0,0,1): una marca cuyo peso ES la identidad (Archivo Black
   en BLOCCO 5) no podía subirlos sin tocar CSS. El token llega como --brand-display-weight
   y cada grupo conserva su valor de hoy como respaldo, así que sin token MITO y ALMA no se
   mueven. Va al final del fichero a propósito: gana por cascada a las reglas de igual
   especificidad de arriba (.kpi-value, .hero-title, .bd-kpi-value…). */
h1.title, .product-name, .item h2, .pcard-name, .t-label, .sel-panel h2 { font-weight:var(--brand-display-weight,500); }
.hero-title, .login-display, .login-h, .cred-h, .kpi-value, .bd-kpi-value, .lb-story-text h2, .related-title { font-weight:var(--brand-display-weight,800); }
.c-caption strong { font-weight:var(--brand-display-weight,700); }

/* ═══════════ Marca configurable: ANCHURA de los titulares (token displayStretch) ═══════════
   El wordmark de BLOCCO y toda su referencia van en Archivo Expanded, y en la misma cabecera
   convivían el logotipo expandido y un «Catálogo» estrecho. El token llega como
   --brand-display-stretch (porcentaje, 50 %..200 %); sin él vale 100 %, que es exactamente el
   «normal» que heredan hoy, así que MITO y ALMA (Gill Sans no tiene eje wdth) no se mueven.
   Es la lista de DISPLAY: los nombres de producto (.product-name, .item h2, .pcard-name) quedan
   fuera a propósito porque en la referencia van en anchura normal. La webfont tiene que traer
   el eje: con Google Fonts, family=Archivo:wdth,wght@62..125,400..900. */
h1.title, .hero-title, .login-display, .login-h, .cred-h, .cred-hero-name, .lb-story-text h2, .t-label, .kpi-value,
.c-caption strong, .related-title { font-stretch:var(--brand-display-stretch,100%); }

/* ═══════════ Marca configurable: MAYÚSCULAS de los botones secundarios (token ctaCaps) ═══════════
   .btn-primary ya va en mayúscula con tracking (INICIAR SESIÓN, AÑADIR A PROGRAMACIÓN); estos
   otros botones y enlaces de acción iban en caja de frase: dos voces de botón en la misma
   pantalla. El token `caps` no sirve porque pondría en mayúscula también h1 y nombres de
   producto. Sin token text-transform vale «none» y el tracking conserva el valor de hoy de cada
   pieza (.02em en .hero-cta/.c-cta/.product-doc, que lo leen en su propia regla; normal en el
   resto), así que nada cambia en MITO ni en ALMA. */
.hero-cta, .c-cta, .lb-add, .product-doc, .tb-export, .tb-seg-opt, .lb-selbar-toggle { text-transform:var(--brand-cta-caps,none); }
.lb-add, .tb-export, .tb-seg-opt, .lb-selbar-toggle { letter-spacing:var(--brand-cta-tracking,normal); }

/* ═══════════ Marca configurable: hero sobre PAPEL (token heroStyle = "paper") ═══════════
   branding.js pone <html data-hero-style="paper"> cuando la instancia lo configura; sin
   token el atributo no existe y NADA de este bloque se aplica (ALMA y MITO intactos).
   La receta Modernist —foto a sangre, velo negro y titular blanco encima— es la de MITO;
   una marca de papel blanco pone la foto SOBRE el papel y el titular en tinta DEBAJO, de
   modo que el contraste del texto deja de depender de la foto (el saludo blanco itálico
   medía 2,5:1 sobre una foto clara). Portada, banda de ventanas y hero del lookbook. */
html[data-hero-style="paper"] .hero-full { height:auto; display:grid; overflow:visible; background:var(--paper); }
/* La foto va a todo el ancho y su alto sale del ancho, no de la ventana: con un tope en
   vh la caja se encogía y dejaba papel a la derecha. 2,4:1 es la proporción de los
   recortes de campaña; en móvil sube a 16:9 para que no quede una tira. */
html[data-hero-style="paper"] .hero-media { position:relative; inset:auto; width:100%; aspect-ratio:2.4/1; max-height:none; }
@media (max-width:48rem) { html[data-hero-style="paper"] .hero-media { aspect-ratio:16/9; } }
html[data-hero-style="paper"] .hero-full::after { display:none; }
html[data-hero-style="paper"] .hero-overlay { position:static; color:var(--ink); padding:1.6rem var(--gutter) 0; width:100%; }
html[data-hero-style="paper"] .hero-kicker { font-style:normal; opacity:1; color:var(--ink-2); }
html[data-hero-style="paper"] .hero-title { color:var(--ink); text-shadow:none; }
html[data-hero-style="paper"] .hero-cta { background:var(--blue); border-color:var(--blue); color:#fff; }
html[data-hero-style="paper"] .hero-cta:hover { background:var(--blue-deep); border-color:var(--blue-deep); color:#fff; }
html[data-hero-style="paper"] .hero-cta:focus-visible { outline-color:var(--blue); }
/* Banda de ventanas: foto arriba (fila flexible) y rótulo en tinta bajo un filete de
   capítulo, sin velo. .t-art es un <span>: en flujo normal necesita display:block para que
   width/height le apliquen (en absoluto se blockificaba solo). El zoom del hover se apaga:
   la foto ya no vive en una caja recortada propia y el 2 % pisaría el filete del rótulo. */
html[data-hero-style="paper"] .tile { display:grid; grid-template-rows:minmax(0,1fr) auto; background:var(--paper); color:var(--ink); box-shadow:none; }
html[data-hero-style="paper"] .tile img, html[data-hero-style="paper"] .tile .t-art { position:relative; inset:auto; display:block; min-height:0; }
html[data-hero-style="paper"] .tile:hover img, html[data-hero-style="paper"] .tile:hover .t-art { scale:1; }
html[data-hero-style="paper"] .tile::after { display:none; }
html[data-hero-style="paper"] .tile:focus-visible { outline:2px solid var(--blue); outline-offset:2px; box-shadow:none; }
html[data-hero-style="paper"] .t-body { position:static; background:none; padding:.9rem 0 0; border-top:var(--rule-w) solid var(--rule); }
html[data-hero-style="paper"] .t-label { color:var(--blue); }
/* Solo con puntero: en táctil el subrayado se quedaba fijo en la última tarjeta tocada. */
@media (hover:hover) { html[data-hero-style="paper"] .tile:hover .t-label { text-decoration:underline; text-underline-offset:.12em; } }
html[data-hero-style="paper"] .t-sub { color:var(--ink-2); }
html[data-hero-style="paper"] .t-cart { color:var(--ink); }
/* Hero del lookbook (carrusel con pie por diapositiva): el pie va en tinta sobre una
   ETIQUETA de papel línea a línea (box-decoration-break), no en blanco sobre velo: así
   lee igual sobre plata que sobre negro sin reconstruir el carrusel. El CTA sigue rojo. */
html[data-hero-style="paper"] .lb-hero .carousel { aspect-ratio:auto; background:var(--paper); }
html[data-hero-style="paper"] .lb-hero .c-track, html[data-hero-style="paper"] .lb-hero .c-slide { height:auto; }
html[data-hero-style="paper"] .lb-hero .c-slide img, html[data-hero-style="paper"] .lb-hero .c-video { height:auto; aspect-ratio:2.4/1; object-fit:cover; }
html[data-hero-style="paper"] .lb-hero .c-caption { position:static; background:none; color:var(--ink); max-width:var(--maxw); margin:0 auto; padding:1.4rem var(--gutter) 0; }
html[data-hero-style="paper"] .lb-hero .c-caption strong, html[data-hero-style="paper"] .lb-hero .c-caption span:not(.c-cta) { background:none; padding:0; }
html[data-hero-style="paper"] .lb-hero .c-caption span:not(.c-cta) { color:var(--ink-2); }
html[data-hero-style="paper"] .lb-hero .c-dots { position:static; max-width:var(--maxw); margin:.6rem auto 0; padding:0 var(--gutter); justify-content:flex-start; }
/* Centro de la FOTO (2,4:1 a ancho de ventana), no del bloque foto + pie */
html[data-hero-style="paper"] .lb-hero .c-arrow { top:calc(100vw / 4.8); }
@media (max-width:48rem) { html[data-hero-style="paper"] .lb-hero .c-slide img, html[data-hero-style="paper"] .lb-hero .c-video { aspect-ratio:16/9; object-fit:contain; } }
/* Visor de la ficha: las fotos de producto traen la placa gris horneada; con el token
   `card` en blanco quedarían enmarcadas, así que el escenario toma --surface (el mismo
   gris que ya leen .item-photo, .pcard-media y .viewer-empty). */
html[data-hero-style="paper"] .viewer-stage { background:var(--surface); }
/* Cabecera: el rojo es TINTA, no superficie de utilidades. El único bloque de color debe
   ser la acción (carrito): monograma a contorno y FAB en la superficie de la cabecera con
   su tinta (blanco con icono negro en BLOCCO). Gateado aquí y no global porque en ALMA
   —cabecera blanca, marca negra— se vería (monograma a contorno y FAB negro). */
html[data-hero-style="paper"] .avatar { background:none !important; border:1px solid currentColor; color:var(--header-ink); }
html[data-hero-style="paper"] #assistant-fab { background:var(--header-bg) !important; color:var(--header-ink); border:1px solid var(--header-ink); }
html[data-hero-style="paper"] #assistant-fab:hover { background:var(--surface) !important; }

/* ── Ronda 2 de crítica de BLOCCO 5: todo cuelga del mismo atributo (sin token, nada de esto existe) ── */

/* Bordes de control: el #bab6b6 de :root da 2:1 sobre papel blanco, por debajo del 3:1 que
   pide WCAG 1.4.11 para el límite de un campo (buscador, selects, chips, casilla de
   condiciones). #8a8686 = 3,6:1 sobre blanco y 3,1:1 sobre la placa #f0efed. Se sube aquí y
   no en :root porque el papel de MITO/ALMA es otro y esa subida es decisión de sus dueños. */
html[data-hero-style="paper"] { --line-control:#8a8686; }

/* Un solo rojo, sin tintes: con el token accentSoft en el papel, el aviso y los chips pierden
   el fondo rosa y se delimitan con el filete de 1px de p02. El resumen del checkout deja el
   marco por los cuatro lados (la «danger card» de framework) y se queda con el filete
   superior, como abre cualquier otro capítulo del portal. */
html[data-hero-style="paper"] .notice-error { border-top:var(--rule-w) solid var(--rule); padding-top:1rem; }
html[data-hero-style="paper"] .ck-side { border-width:var(--rule-w) 0 0 !important; }
html[data-hero-style="paper"] .item-units, html[data-hero-style="paper"] .chip.tone-red { border:1px solid var(--blue); border-radius:0; }

/* Carrusel de portada sobre papel: los mandos salen de la foto. Los puntos van DEBAJO (el
   activo, rojo, caía sobre el producto) y en tinta: el blanco al 55 % y la pausa blanca al
   80 % eran invisibles sobre papel blanco, y la pausa es la única forma de parar una rotación
   automática (WCAG 2.2.2). .carousel lleva overflow:hidden para tapar las diapositivas
   vecinas: se cambia por overflow-x:clip (no crea contenedor de scroll ni ensancha el
   documento, cosa que un clip-path sí dejaba pasar) con overflow-y:visible, para que la fila
   de puntos, a top:100 %, asome por abajo. El kenburns se apaga: sobre una retícula de
   producto el zoom recorta los pares exteriores durante 20 s. */
html[data-hero-style="paper"] .hero-media { margin-bottom:2.6rem; }
html[data-hero-style="paper"] .hero-media .carousel { overflow-x:clip; overflow-y:visible; clip-path:none; }
/* A plomo con el titular: el overlay es una columna de --maxw centrada con --gutter de
   sangría, así que el primer punto cae bajo la primera letra del H1 a cualquier ancho. */
html[data-hero-style="paper"] .hero-media .c-dots { top:100%; bottom:auto; margin-top:.6rem; justify-content:flex-start;
  padding-left:max(var(--gutter), calc((100% - var(--maxw)) / 2 + var(--gutter))); }
html[data-hero-style="paper"] .c-dots button[data-go]::before { background:var(--line-control); border-radius:0; }
html[data-hero-style="paper"] .c-dots button[data-go]:hover::before { background:var(--ink); }   /* el #fff base desaparecería */
html[data-hero-style="paper"] .c-dots button[aria-current="true"]::before { background:var(--blue); }
html[data-hero-style="paper"] .c-dots .c-play { color:var(--ink); opacity:1; }
html[data-hero-style="paper"] .c-dots button:focus-visible { outline-color:var(--blue); }
html[data-hero-style="paper"] .c-arrow { color:var(--ink); background:var(--paper); border:1px solid var(--ink); border-radius:0; }
html[data-hero-style="paper"] .hero-media .c-slide img { animation:none; }

/* Hero del lookbook: la misma proporción 2,4:1 que la portada. A 3,4:1 el recorte «cover»
   decapitaba la placa y el pie caía sobre el producto; ALMA y MITO siguen en 3,4:1. */

/* Las etiquetas de los filtros («Ordenar por», «Temporada», «Fechas») ya no se corrigen
   aquí: el kicker sobre el control es AHORA el tratamiento de la hoja base (ver el bloque
   «CONTROLES DE FORMULARIO · sistema único»). La marca solo conserva su peso de rótulo,
   que es más marcado que el de la base porque en el libro los antetítulos van en negrita. */
html[data-hero-style="paper"] .tb-legend { font-weight:700; letter-spacing:.07em; color:var(--hint); }

/* Radios literales que se saltan el token: en p12 no hay un solo círculo. Gateado y no por
   var(--r-sm) porque MITO tiene --r-sm:0 y luce esos círculos precisamente por el literal
   50 %: sustituirlo le cuadraría también los puntos y las flechas de su carrusel. */
html[data-hero-style="paper"] :is(.item-fav, .product-fav, .h-search button, .h-menu a, .h-menu button, .item-units,
  .lb-selbar-toggle, .doc-modal-close, .cart-size, .cart-drop, .req-badge, .as-msg, .as-form textarea, .as-send,
  .c-arrow, .c-dots button, .sz-qty:focus-visible, .ck-size, .ck-drop, .lb-selremove) { border-radius:0; }

/* ══════════════ Marca sobre papel · acceso = la doble página del metro (p22) ══════════════
   p22 es papel con el texto en rojo en la página IZQUIERDA y la foto a sangre por el corte exterior
   en la DERECHA; la modelo mira hacia el interior del pliego, es decir, hacia el formulario. El
   acceso es esa doble página, en ese orden: columna de papel a la izquierda (marca arriba, donde
   la lleva todo el portal; formulario o tarjetas centrados; el rojo grande —el claim en el login,
   HOLA + nombre en el acceso— abajo, el hueco «Collection / VAGUE» de p22) y la foto
   (login.background, la inserta access-photo.js) a la derecha a 100 vh. TODO el texto va sobre
   papel (medido sobre la foto: blanco 2,5:1 de media y 1,2:1 en lo peor, tinta 1,06:1 en las
   sombras; nada llega a 3:1, así que ni el logo ni el claim se posan sobre ella, y sin gradiente:
   el libro no tiene uno). Entre foto y papel NO hay filete: en p22 la foto corta a sangre y el
   papel empieza limpio (y sobre el naranja del tren un filete rojo de 1 px no se ve). El filete
   solo existe en el ::before, el papel de la columna cuando el CMS no trae foto. El aside pasa a
   display:contents y sus hijos se colocan por áreas. El logo es el de tinta: onDarkBrand() ya es
   false sobre papel.
   heroStyle="photo" (POLO CLUB) comparte SOLO este bloque del acceso —de aquí hasta la media query
   de 52rem inclusive— con html:is([data-hero-style="paper"],[data-hero-style="photo"]) (misma
   especificidad 0,1,1, así que la cascada de paper no se mueve). El resto del bloque de papel
   (portada, ventanas, lookbook, matriz…) sigue siendo solo de paper: con photo la portada es la
   fotográfica a sangre de la base. */
html:is([data-hero-style="paper"],[data-hero-style="photo"]) :is(.login-split, .cred-split) { --access-pad:clamp(2rem,5vw,3.5rem);
  grid-template-columns:1fr 1.05fr; grid-template-rows:auto 1fr auto;
  grid-template-areas:"brand photo" "main photo" "display photo"; }
html:is([data-hero-style="paper"],[data-hero-style="photo"]) :is(.login-hero, .cred-hero) { display:contents; }
html:is([data-hero-style="paper"],[data-hero-style="photo"]) :is(.login-split, .cred-split)::before { content:""; grid-area:photo; border-left:var(--rule-w) solid var(--rule); }
html:is([data-hero-style="paper"],[data-hero-style="photo"]) .access-photo { display:block; grid-area:photo; position:relative; min-height:0; overflow:hidden;
  background:var(--surface); }
html:is([data-hero-style="paper"],[data-hero-style="photo"]) .access-photo img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:50% 0; }
html:is([data-hero-style="paper"],[data-hero-style="photo"]) :is(.login-hero, .cred-hero) .brand { grid-area:brand; color:var(--ink); padding:var(--access-pad) var(--access-pad) 0; }
/* min-width:0 y la pista interior en minmax(0,1fr): sin ellos la tarjeta única de credenciales (nombre
   en nowrap a 390px, min-content 391) ensanchaba la pista del split a 439px y luego la del panel a 415;
   con la pista acotada la tarjeta encoge y el nombre va a puntos suspensivos, como quiere la base. */
html:is([data-hero-style="paper"],[data-hero-style="photo"]) :is(.login-panel, .cred-panel) { grid-area:main; min-width:0; grid-template-columns:minmax(0,1fr); }
/* 3.5vw y no 4.2vw: «OWN YOUR CODE.» mide 11,25 em y la columna de papel es el 48,8 % del ancho menos
   dos --access-pad; con 4.2vw se partía en dos líneas en los 16:10 (1440×900, 1536×864, 1280×800).
   Medido: 1920×1080 64,8 px, 1440×900 50,4, 1366×768 46,08, 1280×800 44,8, 2560×1440 86,4; una
   línea en todos. */
html:is([data-hero-style="paper"],[data-hero-style="photo"]) .login-display { grid-area:display; align-self:end; color:var(--blue);
  padding:0 var(--access-pad) var(--access-pad); font-size:clamp(2rem, min(3.5vw, 6vh), 5.4rem); }
html:is([data-hero-style="paper"],[data-hero-style="photo"]) .cred-h { color:var(--blue); }
html:is([data-hero-style="paper"],[data-hero-style="photo"]) .cred-hero-mid { grid-area:display; align-self:end; padding:0 var(--access-pad) var(--access-pad); }
/* «HOLA» es el «Collection» de p22 (≈ un cuarto de la caja de «VAGUE»): parte del titular, no una
   etiqueta de tabla. .95rem sobre un nombre de 56 px a 1920 (antes .74rem, proporción 0,21). */
html:is([data-hero-style="paper"],[data-hero-style="photo"]) .cred-hero-mid .hero-kicker { color:var(--blue-text); font-size:.95rem; font-weight:800; letter-spacing:.14em; margin:0 0 .35rem; }
/* La base lo pinta en #fff (para el cartel de color): sobre papel era invisible. */
html:is([data-hero-style="paper"],[data-hero-style="photo"]) .cred-hero-name { color:var(--blue); font-size:clamp(1.8rem, min(3.4vw, 5.2vh), 4rem); }
@media (max-height:50rem) {
  html:is([data-hero-style="paper"],[data-hero-style="photo"]) :is(.login-split, .cred-split) { --access-pad:2rem; }
  html:is([data-hero-style="paper"],[data-hero-style="photo"]) :is(.login-panel, .cred-panel) { padding-block:1rem; }
}
@media (max-width:52rem) {
  html:is([data-hero-style="paper"],[data-hero-style="photo"]) :is(.login-split, .cred-split) { grid-template-columns:1fr; grid-template-rows:auto auto auto 1fr;
    grid-template-areas:"brand" "photo" "display" "main"; }
  html:is([data-hero-style="paper"],[data-hero-style="photo"]) :is(.login-split, .cred-split)::before { display:none; }
  html:is([data-hero-style="paper"],[data-hero-style="photo"]) .access-photo { min-height:36vh; }
  html:is([data-hero-style="paper"],[data-hero-style="photo"]) :is(.login-hero, .cred-hero) .brand { padding:1.3rem var(--gutter) 1.1rem; }
  html:is([data-hero-style="paper"],[data-hero-style="photo"]) :is(.login-display, .cred-hero-mid) { align-self:start; padding:1.4rem var(--gutter) 1.5rem;
    border-bottom:var(--rule-w) solid var(--rule); }
  html:is([data-hero-style="paper"],[data-hero-style="photo"]) .login-display { font-size:2.6rem; }
  html:is([data-hero-style="paper"],[data-hero-style="photo"]) .cred-hero-mid .hero-kicker { font-size:.8rem; }
  html:is([data-hero-style="paper"],[data-hero-style="photo"]) .cred-hero-name { font-size:2.2rem; }
}
/* El aviso del resumen es el primer hijo del panel: dos filetes a 24px uno de otro */
html[data-hero-style="paper"] .ck-side > .notice-error:first-child { border-top:0; padding-top:0; }
/* Matriz de tallas: bordes de control a 3:1, las agotadas se distinguen de las abiertas y la
   cifra de stock (el dato que decide cuántos pares pedir) deja de ir a 11px */
html[data-hero-style="paper"] .sz { border-color:var(--line-control); }
html[data-hero-style="paper"] .sz.out .sz-head { background:var(--ink-3); }
html[data-hero-style="paper"] .sz.out .sz-body { background:var(--surface); }
html[data-hero-style="paper"] .sz.out .sz-qty::placeholder { color:transparent; }
html[data-hero-style="paper"] .sz-cell .sz-stock { font-size:.8rem; font-weight:500; }
/* Rótulo de la fila de disponibilidad: las cifras bajo las tallas no llevan palabra y una tienda
   nueva las lee como precio o como cantidad ya puesta. Solo cuando HAY fila de stock (en la ventana
   programada no se pinta): un «STOCK» rojo pequeño como último asiento de la rejilla, a la altura
   de las cifras. Pseudoelemento porque size-matrix.js es compartido: en ALMA no cambia nada. */
html[data-hero-style="paper"] .matrix:has(.sz-stock)::after { content:"stock"; align-self:end; justify-self:start;
  font:800 .62rem/1.5 var(--display); letter-spacing:.1em; text-transform:uppercase; color:var(--blue-text);
  font-stretch:var(--brand-display-stretch,100%); padding:0 0 .15rem .1rem; white-space:nowrap; }
/* Nombres con raya («Bund Fantasy — Silver»): las dos líneas se equilibran y la raya no queda colgada. */
html[data-hero-style="paper"] .product-name { text-wrap:balance; }
/* La ventana de pedido se elige en las dos cajas de la portada (PROGRAMACIÓN SS27 | REPOSICIÓN) y
   el carrito de la cabecera dice cuál está activa: el conmutador de la barra de herramientas del
   catálogo se oculta en esta marca. Solo CSS: catalog.js lo sigue pintando y enlazando
   (paintWindowSwitch), state.prefs.window lo siguen escribiendo los tiles y state.alignWindow
   sigue corrigiendo la preferencia al cargar; ALMA y MITO lo conservan. Vale para las dos
   marcas con portada propia (papel y fotografía): la puerta de entrada al catálogo es la caja. */
html:is([data-hero-style="paper"], [data-hero-style="photo"]) .tb-window { display:none; }
/* Sin conmutador, la ventana activa se lee junto al título: en escritorio la decía solo el carrito
   (a 1700 px del h1) y en móvil, con su etiqueta clipada por la base a ≤52rem, nadie. Antetítulo
   rojo en mayúscula, el mismo de «HOLA» y de las cajas de la portada; el nombre lo deja catalog.js
   en data-window-name (dato sin CSS en la base: ALMA y MITO no cambian). */
html:is([data-hero-style="paper"], [data-hero-style="photo"]) .cat-title .cat-headline[data-window-name]::before { content:attr(data-window-name); flex-basis:100%;
  font-size:.74rem; font-weight:800; letter-spacing:.12em; text-transform:uppercase; color:var(--blue-text); line-height:1.3; }
/* El estado de un conmutador no es una acción: en tinta, y el carrito queda como único
   bloque rojo de la cabecera */
html[data-hero-style="paper"] .tb-seg-opt.on { background:var(--ink); color:#fff; }
/* Quince botones rojos en el lookbook, donde la referencia no tiene ni uno: en tinta */
html[data-hero-style="paper"] .lb-add { border-color:var(--line-control); color:var(--ink); }
html[data-hero-style="paper"] .lb-add:hover, html[data-hero-style="paper"] .lb-add.on { background:var(--ink); border-color:var(--ink); color:#fff; }
/* Una sola etiqueta en toda la página: mayúscula con tracking y filete, como el kicker */
html[data-hero-style="paper"] .lb-shop-title { font-size:.74rem; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--accent-deep); border-bottom:var(--rule-w) solid var(--lb-accent, var(--blue)); padding-bottom:.15rem; }
html[data-hero-style="paper"] .lb-shop-title::before { display:none; }
/* La marca no tiene líneas discontinuas */
html[data-hero-style="paper"] .alsoin-more { border-style:solid; }
/* Chips del listado con su etiqueta delante (la ficha ya la lleva): sale del title que ya
   se pinta, así el comprador sabe si «PU/TEXTIL» es corte o forro sin pasar el ratón */
html[data-hero-style="paper"] .item-attrs .tag[title]::before { content:attr(title); font-weight:500; letter-spacing:.04em; color:var(--ink-2); margin-right:.45em; }

/* ══════════════ Marca sobre papel · apertura del lookbook = ÍNDICE (p02) ══════════════
   El lookbook de la marca no abre con una foto: abre con estructura —seis entradas numeradas
   entre filetes rojos a sangre— cerradas por la línea de estado y la acción (p02 «Index»). El
   title del bloque lookbook.hero (la temporada, «SS27») solo da nombre a la apertura para
   lectores de pantalla; la línea de estado es su subtitle, la acción su ctaText/ctaHref, y cada
   entrada del índice ancla a su historia. Cuelga del atributo como
   el resto de la marca: lookbook.js solo pinta .lb-index bajo data-hero-style="paper", así
   que ALMA y MITO conservan su carrusel byte a byte. */

/* El aire tras el índice lo pone el padding-top de la primera historia (3.5rem, más abajo), no
   el hero: su filete inferior ES el borde superior de la historia 01 (que nace sin border-top). */
html[data-hero-style="paper"] .lb-hero-index { margin-bottom:0; }
/* Mientras llega el CMS: papel, sin brillo y a la altura del índice (≈340px medidos a 390 y
   a 1920), para que la página no salte cuando se pinta. Nada de placa gris: después no hay foto. */
html[data-hero-style="paper"] .lb-hero-index .hero-skeleton { aspect-ratio:auto; min-height:min(21rem,60vh); border-radius:0;
  background:var(--paper); background-image:none; animation:none; }

/* Orden VISUAL = orden del DOM: cabecera de página (solo si el CMS trae kicker), h1 solo para
   lectores («Lookbook SS27»), índice, línea de estado + acción: el lector de pantalla oye el título
   antes que las seis entradas, y el tabulado (entradas → acción) coincide con lo visible. El
   filete inferior es el borde de página del índice.
   --ix-x es EL MISMO padding de #chrome-nav (misma expresión, definida en .page.lookbook —bloque
   «historias a página», más abajo— para el índice y las historias a la vez; si cambia allí,
   cambiar aquí): el «01» y el pie caen a plomo con el logo y la pestaña CATÁLOGO. p02 abre a
   página y p03 en adelante lleva márgenes: los filetes sangran y el texto va al margen de página,
   no a una columna centrada dentro de ellos. */
html[data-hero-style="paper"] .lb-index { display:grid; grid-template-areas:"head" "nav" "foot";
  background:var(--paper); color:var(--ink); border-bottom:var(--rule-w) solid var(--rule); }

/* Cabecera de página SOLO si el CMS trae kicker (p03-p22 llevan «LOOKBOOK 2027SS» arriba a la
   izquierda, en rojo y expandido). Sin él no se pinta: la pestaña LOOKBOOK del chrome ya rotula la
   página y su filete rojo hace de primer filete del índice (p02: el asiento 01 viene inmediatamente,
   sin rótulo). Con kicker es una cabecera corrida con aire, no un séptimo asiento de 55px. */
html[data-hero-style="paper"] .lb-ix-head { grid-area:head; display:flex; flex-wrap:wrap; justify-content:space-between;
  align-items:baseline; gap:.4rem 1.5rem; width:100%; padding:2.4rem var(--ix-x) 1rem; }
/* --blue-text, no --blue: es la variante del rojo que branding.js garantiza legible para texto
   PEQUEÑO sobre el papel de la instancia (con #e70917 sobre blanco, 4,72:1, es el mismo rojo). */
html[data-hero-style="paper"] .lb-ix-kicker { margin:0; font-size:.74rem; line-height:1.3; letter-spacing:.12em; text-transform:uppercase;
  color:var(--blue-text); font-weight:800; font-stretch:var(--brand-display-stretch,100%); }

/* Entradas: el <li> ocupa TODO el ancho y lleva el filete (a sangre, como p02); el <a> sangra su
   texto hasta el margen de página (--ix-x). El primer filete del índice es el de las pestañas del
   chrome (con el suyo habría doble línea); solo con cabecera el asiento 01 recupera el suyo. */
html[data-hero-style="paper"] .lb-ix-nav { grid-area:nav; }
html[data-hero-style="paper"] .lb-ix-list { list-style:none; margin:0; padding:0; }
html[data-hero-style="paper"] .lb-ix-list li { border-top:var(--rule-w) solid var(--rule); }
html[data-hero-style="paper"] .lb-ix-list li:first-child { border-top:0; }
html[data-hero-style="paper"] .lb-ix-head ~ .lb-ix-nav li:first-child { border-top:var(--rule-w) solid var(--rule); }
html[data-hero-style="paper"] .lb-ix-list li:last-child { border-bottom:var(--rule-w) solid var(--rule); }
html[data-hero-style="paper"] .lb-ix-list a { display:grid; grid-template-columns:3.5rem 17rem minmax(0,1fr); column-gap:1rem;
  align-items:baseline; padding:.7rem var(--ix-x); color:var(--ink); text-decoration:none; }
/* Número: rojo, expandido y tabular (los «01…06» de p02 son numerales negros expandidos en rojo). */
html[data-hero-style="paper"] .lb-ix-num { font-size:.9rem; font-weight:800; letter-spacing:.04em; color:var(--blue-text);
  font-stretch:var(--brand-display-stretch,100%); font-variant-numeric:tabular-nums; }
/* Nombre del capítulo (kicker de la historia) y titular, los dos en TINTA: una sola voz por fila
   (p02 es numeral rojo + nombre en negro; ningún gris de «texto de ayuda» que se active al pasar
   el puntero). El nombre comparte cuerpo con el numeral, en regular y con poco tracking. */
html[data-hero-style="paper"] .lb-ix-name { font-size:.9rem; font-weight:500; letter-spacing:.04em; text-transform:uppercase; line-height:1.35; }
html[data-hero-style="paper"] .lb-ix-title { font-size:1rem; line-height:1.4; color:var(--ink); }
/* Un kicker o título sin espacios no invade la columna vecina ni ensancha el documento. */
html[data-hero-style="paper"] :is(.lb-ix-name,.lb-ix-title,.lb-ix-kicker,.lb-ix-sub) { overflow-wrap:anywhere; min-width:0; }
/* Solo con puntero: en táctil el subrayado se quedaría pegado a la última entrada tocada. */
@media (hover:hover) {
  html[data-hero-style="paper"] .lb-ix-list a:hover .lb-ix-name { text-decoration:underline; text-underline-offset:.14em; text-decoration-color:var(--blue); }
}
html[data-hero-style="paper"] .lb-ix-list a:focus-visible { outline:2px solid var(--blue); outline-offset:-2px; }

/* Pie del índice = su colofón: la línea de estado del CMS («Abierta a pedidos.») y la acción como
   ENLACE rojo en mayúscula, no como botón: la referencia no tiene un solo bloque de color. El botón
   relleno queda para el cierre de la página. Misma rejilla que los asientos (numeral · nombre ·
   titular): la línea de estado ocupa numeral + nombre y la acción nace A PLOMO con la columna de
   titulares (antes, con flex + gap, caía en x=272, en ninguna columna de la tabla). Algo más alto
   que un asiento (58px frente a 46) para leerse como pie y no como séptimo asiento; lo cierra el
   filete inferior de .lb-index, el borde de página. */
html[data-hero-style="paper"] .lb-ix-foot { grid-area:foot; display:grid; grid-template-columns:3.5rem 17rem minmax(0,1fr); column-gap:1rem;
  row-gap:.6rem; align-items:baseline; width:100%; padding:.95rem var(--ix-x) 1.05rem; }
/* La línea de estado ocupa numeral + nombre; la acción nace a plomo con la columna de titulares. */
html[data-hero-style="paper"] .lb-ix-sub { grid-column:1 / 3; margin:0; font-size:1.05rem; font-weight:500; color:var(--ink); }
/* padding-block compensado con margen negativo: área táctil de 36px (44 en móvil; WCAG 2.5.8) con
   la misma línea base y sin mover nada del layout. */
html[data-hero-style="paper"] .lb-ix-cta { grid-column:3; justify-self:start; display:inline-flex; align-items:center; gap:.4rem; font-size:.8rem; font-weight:800;
  letter-spacing:.1em; text-transform:uppercase; color:var(--blue-text); text-decoration:none; font-stretch:var(--brand-display-stretch,100%);
  padding-block:.5rem; margin-block:-.5rem; }
html[data-hero-style="paper"] .lb-ix-cta:hover { text-decoration:underline; text-underline-offset:.16em; }
html[data-hero-style="paper"] .lb-ix-cta:focus-visible { outline:2px solid var(--blue); outline-offset:3px; }

/* Las entradas del índice llevan a la historia por JS (scrollIntoView): que el kicker no quede
   bajo la cabecera pegajosa (66px). Gateado: en ALMA nadie salta a una historia. */
html[data-hero-style="paper"] .lb-story { scroll-margin-top:calc(var(--header-h) + 1rem); }
/* Aire entre el filete que cierra el índice y la placa de la historia 01 (88px, casi dos asientos):
   en el libro cada historia es un pliego nuevo; con 56px la placa parecía un séptimo asiento. La
   placa sigue entera en la primera pantalla a 1080 (y=541) y asoma 227px a 768. */
html[data-hero-style="paper"] .lb-story:first-child { padding-top:5.5rem; }

/* Móvil (390px): p02 literal —un asiento = una línea (el titular ya lo dice la historia). El margen
   del texto es el del logo (--gutter = 20px). Bloque ≈365px: placa de la historia 01 en y≈534, dentro
   de la primera pantalla. */
@media (max-width:48rem) {
  html[data-hero-style="paper"] .page.lookbook { --ix-x:var(--gutter); }
  html[data-hero-style="paper"] .lb-ix-head { padding-top:1.2rem; }
  html[data-hero-style="paper"] .lb-ix-title { display:none; }
  html[data-hero-style="paper"] .lb-ix-list a { grid-template-columns:2.4rem minmax(0,1fr); padding-block:.7rem; }
  /* Sin columna de titulares no hay plomo que guardar: dos líneas seguidas, como hasta ahora. */
  html[data-hero-style="paper"] .lb-ix-foot { display:flex; flex-wrap:wrap; gap:.6rem 2.5rem; }
  html[data-hero-style="paper"] .lb-ix-cta { padding-block:.75rem; margin-block:-.75rem; }
  html[data-hero-style="paper"] .lb-story:first-child { padding-top:3.2rem; }
}

/* ══════════════ Marca sobre papel · historias a PÁGINA ══════════════
   Las historias (texto + foto + raíl «Referencias del look») iban en la columna de lectura de la
   base (--maxw = 1240) y a 1920 dejaban 340 px vacíos a cada lado. En el libro cada historia es un
   pliego (p03-p22: texto en una columna, la foto en la otra, hasta el margen de página), así que
   aquí usan los MISMOS márgenes que el índice y el cromo (--ix-x, que se define en .page.lookbook
   para el índice y las historias a la vez): a 1920 el contenido mide 1843 px, a 1366 1289. Texto y
   foto crecen en proporción 5:7 (texto minmax(28ch,5fr) · foto 7fr): a 1920 la foto mide 1030×773
   y la columna de texto 736; a 1366, 720×540 y 514. La medida del párrafo se acota a 38em (unos 75
   caracteres) y el titular sube con la ventana (2.2vw, 42 px a 1920). Las fotos del CMS miden de
   1246 a 1867 px: a 1x ninguna se estira por encima de su tamaño (a 2560 la más pequeña queda al
   109 %). El raíl toma todo el ancho con más tarjetas por fila (4 → 5 a partir de 1300 px → 6 a
   partir de 1700 px); la tarjeta sigue en 4:5 (object-fit:cover) y el paso de las flechas se
   calcula a partir de la tarjeta (bindRails), así que no cambia. Solo a partir de 52 rem + 1 px:
   el apilado móvil de la base queda byte a byte. */
/* Todo lo que este bloque hacía —historias a sangre, proporción 7:5, medida del
   párrafo y escala del raíl— es AHORA la hoja base, para las tres marcas (ver «Las
   historias, a sangre»). Aquí solo queda --ix-x, que es el margen del ÍNDICE del
   libro, propio de esta marca; se define como el raíl común para que índice,
   historias y cromo sigan colgando del mismo borde. */
html[data-hero-style="paper"] .page.lookbook { --ix-x:var(--rail-x); }

/* ══════════════ Marca sobre papel · film de portada ══════════════
   El vídeo del hero es una PLACA sobre el papel, como las páginas de producto del libro (p14-p21):
   nunca más alta que el 60 % de la ventana (a 1920×1080 el titular, «Explorar el catálogo» y el
   arranque de las ventanas entran en la primera pantalla; a sangre 2,4:1 el H1 caería bajo el
   pliegue). En móvil, 16:9 a todo el ancho, como hasta ahora. El film NO se recorta: sigue a 2,4:1
   (object-fit:cover de la base, l. 223, no tiene nada que cortar). El ancho de la placa, el margen
   único y el pliegue en apaisado corto van en el bloque «ronda 4» de abajo. */
/* ══════════════ Marca sobre papel · film de portada, ronda 4 (juez) ══════════════
   UN solo margen de contenido: el borde de la placa. El cromo (logo, pestañas) sigue en su margen
   de página (clamp(1rem,4vw,2.4rem), el de #chrome-nav); la placa, sus puntos, el saludo, el H1,
   el CTA, las ventanas y los KPI cuelgan del mismo borde, como el pie de cada placa en p14-p21.
   La placa mide --hero-h de alto (60 vh; 56 vh en apaisado de ≤ 768 px, para que «Explorar el
   catálogo» entre entero a 1366×768 y 1280×720) y nunca es más ancha que el margen del cromo ni
   que el raíl ancho (--maxw-wide). Sustituye a la regla de width de la ronda anterior. */
html[data-hero-style="paper"] { --hero-h:60vh; --hero-w:min(calc(100% - 2 * clamp(1rem,4vw,2.4rem)), calc(var(--hero-h) * 2.4), var(--maxw-wide)); }
html[data-hero-style="paper"] .hero-media { width:var(--hero-w); justify-self:center; }
html[data-hero-style="paper"] .hero-overlay { width:var(--hero-w); max-width:none; padding-inline:0; justify-self:center; }
/* Los puntos nacen en el borde de la placa (antes: sangría de la columna de lectura) */
html[data-hero-style="paper"] .hero-media .c-dots { padding-left:0; }
/* Ventanas y KPI: el 100 % aquí es el contenido de .page.dash, que ya descuenta el margen del cromo */
html[data-hero-style="paper"] .page.dash .tiles,
html[data-hero-style="paper"] .page.dash > :not(.tiles) { max-width:min(100%, calc(var(--hero-h) * 2.4), var(--maxw-wide)); margin-inline:auto; }
/* Mientras llega la imagen de la diapositiva 2: placa gris, no el --ink-2 de la base (#605d5d) */
html[data-hero-style="paper"] .hero-media .carousel { background:var(--surface); }
/* Anillo de foco de la diapositiva por dentro: overflow-x:clip se comía los lados */
html[data-hero-style="paper"] .hero-media .c-slide:focus-visible { outline-offset:-3px; }
/* Apaisado corto (portátil 1366×768 / 1280×720, iPad apaisado): ritmo vertical más prieto bajo la placa */
@media (min-width:48rem) and (max-height:60rem) {
  html[data-hero-style="paper"] .hero-media { margin-bottom:2.2rem; }
  html[data-hero-style="paper"] .hero-overlay { padding-top:.5rem; }
  html[data-hero-style="paper"] .hero-title { font-size:clamp(2.6rem, min(7vw, 9vh), 5.5rem); margin-bottom:.5rem; }
}
@media (min-width:48rem) and (max-height:48rem) {
  html[data-hero-style="paper"] { --hero-h:56vh; }
}
@media (max-width:48rem) {
  html[data-hero-style="paper"] .hero-media { width:100%; }
  html[data-hero-style="paper"] .hero-overlay { width:100%; padding-inline:var(--gutter); }
  /* ventanas al margen del texto (20 px), no al del cromo (16 px) */
  html[data-hero-style="paper"] .page.dash .tiles { max-width:none; margin-inline:calc(var(--gutter) - clamp(1rem,4vw,2.4rem)); }
}
/* Mientras llega el póster: placa gris, no negro. Ancho/alto/cover ya vienen de la base (l. 223);
   el filtro B/N de la l. 2220 lo anula el token heroFilter:'none' de la instancia. */
html[data-hero-style="paper"] .hero-media .c-video { display:block; background:var(--surface); }

/* ══ POLO CLUB (html[data-hero-style="photo"]) ═══════════════════════════════
   Capa de marca de la instancia fotográfica. Todo va gateado por el atributo del
   <html>, que solo escribe la instancia con heroStyle:'photo': ALMA EN PENA no manda
   heroStyle y BLOCCO 5 manda 'paper', así que ninguna de las dos entra aquí.

   1) El rojo vuelve a ser ACENTO. Con `rule` a #1f262e los 26 usos de var(--rule)
      dejan de ser rojos; el filete de la fila del catálogo y el de la cabecera se
      redirigen a mano porque leen --brand-rule directamente (l. 100 y l. 896). */
html[data-hero-style="photo"] { --line:#e1e1e1; --line-control:#c9c9c9; }
html[data-hero-style="photo"] #chrome-header { border-bottom-color:var(--accent); }
html[data-hero-style="photo"] .item { border-bottom-color:var(--line); }

/* 2) El precio, dato más leído del portal, en la sans y a peso real: Newsreader solo
      trae 400–500 y <b> pedía 700, así que el navegador sintetizaba la negrita. */
html[data-hero-style="photo"] :is(.item-price b,.pcard-price b,.product-price b,
  .matrix-price b,.product-total b,.cart-total b) {
  font-family:var(--brand-font,inherit); font-weight:400; letter-spacing:0;
  font-variant-numeric:tabular-nums; }

/* 3) Rejilla de fotos a 2:3, que es el original y la firma de la marca (a 4:5 se
      recortaba el 17 % inferior de cada prenda). El visor deja de ser caja bicolor. */
html[data-hero-style="photo"] :is(.item-photo,.pcard-media,.viewer-stage,.viewer-empty) { aspect-ratio:2/3; }
html[data-hero-style="photo"] .viewer-stage { border:0; background:var(--surface); }
/* La fila del listado conserva su ALTURA: 17rem a 4:5 daba 21,25rem de alto, y 14rem a 2:3
   da 21rem. Sin esto la foto más alta empujaba la fila a ~470 px y en el Listado —vista por
   defecto y diferencial B2B— solo cabían dos artículos por pantalla. */
html[data-hero-style="photo"] .item { grid-template-columns:14rem minmax(0,1fr); }
/* Cuadrícula menos densa: 6 columnas de 286 px eran lenguaje de cuadro de mando.
   Se expresa ya SOLO con los gaps —la marca junta mucho las fotos en horizontal,
   como su web real, y airea en vertical—; el número de columnas lo pone la escala
   común. Antes esta regla redeclaraba grid-template-columns con un suelo de 20rem
   y, al tener más especificidad que la media query de móvil, dejaba el catálogo de
   390 px en UNA sola columna: una prenda por pantalla. */
html[data-hero-style="photo"] .cat-grid { --cat-gap-x:.5rem; --cat-gap-y:1.6rem; }
@media (max-width:48rem) { html[data-hero-style="photo"] .cat-grid { --cat-gap-x:.6rem; --cat-gap-y:1.4rem; } }

/* 4) Cabecera de la matriz de tallas: la capa Modernist (l. 2223) la dejó como un muro
      negro; la marca la quiere silenciosa, con filete y letra de peso medio. */
html[data-hero-style="photo"] .sz { border-color:var(--ink); }
html[data-hero-style="photo"] .sz-head { background:var(--paper); color:var(--ink); font-weight:500;
  border-bottom-color:var(--line); }
html[data-hero-style="photo"] .sz-price { color:var(--muted); }
/* Talla AGOTADA: el input ya nace disabled, pero las cinco casillas se veían iguales y el
   chip decía DISPONIBLE aunque faltasen M y L, que son las de más rotación. */
html[data-hero-style="photo"] .sz.out { border-color:var(--line-control); }
html[data-hero-style="photo"] .sz.out .sz-head { background:var(--surface); color:var(--muted); }
html[data-hero-style="photo"] .sz.out .sz-body { background:var(--surface); }
html[data-hero-style="photo"] .sz.out .sz-qty::placeholder { color:transparent; }
/* Rótulo de la fila de disponibilidad: las cifras bajo las tallas iban desnudas y una tienda
   nueva las lee como precio o como cantidad ya puesta. Solo cuando HAY fila de stock (en la
   ventana programada no se pinta). Pseudoelemento, porque size-matrix.js es compartido. */
html[data-hero-style="photo"] .matrix:has(.sz-stock)::after { content:"Stock"; align-self:end;
  justify-self:start; font:400 .7rem/1.5 var(--brand-font,inherit); letter-spacing:.06em;
  color:var(--muted); padding:0 0 .1rem .1rem; white-space:nowrap; }

/* 5) Kickers sin cursiva y nav/botones en frase: la serif de la marca no se usa en
      cursiva (informe §9.4) y el nav pedía caja alta pese a ctaCaps:false. */
html[data-hero-style="photo"] :is(.hero-kicker,.lb-kicker,.pcard-cta,.kpi-label,.tag) {
  font-family:var(--brand-font,inherit); font-style:normal; font-weight:400; letter-spacing:.10em; }
html[data-hero-style="photo"] .lb-kicker { color:var(--ink); border-bottom:0; padding-bottom:0; }
html[data-hero-style="photo"] #chrome-nav a { text-transform:none; font-weight:400; font-size:.9rem; letter-spacing:0; }
html[data-hero-style="photo"] :is(.btn-primary,.btn-ghost,.submit,.cta,.ck-group h3) {
  text-transform:none; font-weight:500; letter-spacing:.01em; }

/* 6) Detalles: favorito de la cuadrícula al radio 0 y sin sombra de la marca, y la
      cinta conserva su degradado también en móvil (donde no hay flechas). */
html[data-hero-style="photo"] .pcard-fav { background:#fff; border-radius:0; box-shadow:none; }
/* Acceso: la tagline colgaba en el borde inferior de la pagina, a 64,8 px y separada del
   wordmark por todo el formulario. Pasa a ser la linea que sigue al logotipo —que es donde
   la marca la pone— y baja a ~44 px. Solo el acceso: la pantalla de credenciales
   (.cred-split) mantiene su composicion. */
html[data-hero-style="photo"] .login-split { grid-template-rows:auto auto 1fr;
  grid-template-areas:"brand photo" "display photo" "main photo"; }
html[data-hero-style="photo"] .login-display { align-self:start;
  padding:1.1rem var(--access-pad) 0; font-size:clamp(1.7rem, min(2.5vw, 4vh), 2.75rem); }
@media (max-width:48rem) {
  /* Miniatura del listado a 7,5 rem: a 88 px no se distinguía un jersey trenzado de uno liso */
  html[data-hero-style="photo"] .item { grid-template-columns:7.5rem minmax(0,1fr); }
  html[data-hero-style="photo"] .cat-ribbon.has-nav:not(.at-end) .rib-rail {
    -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 24px),transparent);
            mask-image:linear-gradient(90deg,#000 calc(100% - 24px),transparent); }
}

/* 7) Insignias del visor: «Multi-ángulo» y «Arrastra para girar» prometen una
      rotación 360° que no existe (3–4 fotos por modelo, no ángulos). */
html[data-hero-style="photo"] :is(.viewer-badge,.viewer-hint,.pcard-360) { display:none; }

/* Descripción de la ficha (composición y país): la marca la usa como argumento de
   venta, pero ALMA y BLOCCO no la han diseñado, así que nace oculta. */
.product-desc { display:none; }
html[data-hero-style="photo"] .product-desc { display:block; margin:.9rem 0 0; font-size:.875rem;
  line-height:1.55; color:var(--ink-2); max-width:44rem;
  display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:3; overflow:hidden; }

/* Nombre del artículo enlazado en el Listado: hoy la vista por defecto no tiene ni un
   enlace a la ficha. Aditivo y sin gatear: ninguna instancia pintaba este enlace. */
.item-link { color:inherit; text-decoration:none; }
.item-link:hover { text-decoration:underline; }

/* Sello del pie (token footerBadgeUrl): la marca lo lleva en su propia web y aquí va
   junto al copyright. Sin token no se pinta el <img> y la regla no llega a aplicarse. */
#chrome-footer .foot-brand { display:flex; align-items:center; gap:1.1rem; }
#chrome-footer .foot-badge { height:2.6rem; width:auto; flex:none; }
@media (max-width:48rem) { #chrome-footer .foot-badge { height:2.1rem; } }

/* ══ POLO CLUB · ronda 3 (lote «CSS de marca») ═══════════════════════════════
   Todo va bajo html[data-hero-style="photo"] salvo las tres reglas de NEUTRALIDAD
   del final (.cat-window-note, .item-pvp, .item-margin), que nacen ocultas en la
   hoja base —mismo precedente que .product-desc— para que ALMA EN PENA (sin
   heroStyle) y BLOCCO 5 (paper) no cambien un píxel.
   NO se tocan .tb-window ni .cat-headline[data-window-name]: son orden del dueño.
   /manage carga esta misma hoja y también lleva data-hero-style="photo", así que las
   dos reglas que allí serían un error —neutralizar .btn-danger (en el back-office el
   rojo de «Eliminar» es correcto) y pasar .submit a frase— se acotan con
   body:not([data-app="manage"]). El resto de la capa de marca sí es común, como ya lo
   era el bloque de la ronda 2. */

/* R3-1 · El botón que cierra la venta era INVISIBLE. Medido: «Terminar pedido»
   nace deshabilitado y pintaba --surface (#f3f3f3) dentro de una .ck-side que
   pinta --card (#f3f3f3): el mismo color, cero contraste. Aquí el deshabilitado
   pasa a leerse como botón ESPERANDO (papel + filete a ≥3:1) y no como hueco,
   tanto si el lote de datos sube el token card a #ffffff como si no. */
html[data-hero-style="photo"] :is(.btn-primary, .btn-ghost, .btn-danger)[disabled] {
  background:var(--paper); color:var(--muted);
  border:1px solid color-mix(in srgb, var(--ink) 42%, var(--paper)); }

/* R3-2 · «ELIMINAR CARRITO» era la acción más visible del portal (#EC3013, caja
   alta, peso 700, primer botón de la pantalla de tramitar). El token --out NO se
   toca (es el rojo por defecto de MITO, común a las tres): aquí el botón queda en
   contorno neutro y el rojo solo aparece en hover, con #C40000 (6,27:1 sobre
   papel), que es el rojo de texto pequeño que fija el informe de marca §2. */
html[data-hero-style="photo"] body:not([data-app="manage"]) .btn-danger { background:var(--paper);
  color:var(--ink); border-color:var(--line-control); text-transform:none; font-weight:500;
  letter-spacing:.01em; }
html[data-hero-style="photo"] body:not([data-app="manage"]) .btn-danger:hover:not([disabled]) {
  background:var(--paper); color:#c40000; border-color:#c40000; }

/* R3-3 · La MISMA talla se dibujaba de dos maneras dentro de la misma compra: en
   la ficha, casilla de papel con filete de tinta y radio 0; en el checkout, una
   píldora negra redondeada (el «muro negro» que se mató en la matriz). Y quedaban
   círculos literales en una marca de radio 0 (flechas del visor, puntos del
   carrusel…). Se copia a photo el bloque que paper ya tiene en la l. 2638. */
html[data-hero-style="photo"] .ck-size { background:var(--paper); color:var(--ink);
  border:1px solid var(--ink); border-radius:0; font-weight:400; }
html[data-hero-style="photo"] :is(.viewer-nav, .c-dots button, .c-arrow, .ck-drop, .cart-drop,
  .cart-size, .as-chip, .as-msg, .as-send, .as-form textarea, .chip, .item-units, .item-fav,
  .product-fav, .req-badge, .h-search button, .h-menu a, .h-menu button, .doc-modal-close,
  .lb-selbar-toggle, .lb-selremove, .sz-qty:focus-visible) { border-radius:0; }
html[data-hero-style="photo"] .c-dots button[data-go]::before { border-radius:0; }
/* La flecha del visor era además un bulto gris: papel con filete de tinta. */
html[data-hero-style="photo"] .viewer-nav { background:var(--paper); border-color:var(--ink);
  color:var(--ink); }
html[data-hero-style="photo"] .viewer-nav:hover:not([disabled]) { border-color:var(--ink);
  background:var(--surface); color:var(--ink); }

/* R3-4 · El sello B Corp del pie era una mancha: 91×42 px para un lockup de
   217,74×100 que lleva un párrafo de tres líneas, o sea el párrafo a ~2 px. El
   asset es el correcto (la web real de la marca usa este mismo lockup CON el
   párrafo): lo que fallaba era el TAMAÑO. Sube a 4,8 rem de alto (≈167 px de
   ancho, como en el pie real) con más aire respecto al copyright. */
html[data-hero-style="photo"] #chrome-footer .foot-brand { gap:1.6rem; }
html[data-hero-style="photo"] #chrome-footer .foot-badge { height:4.8rem; }

/* R3-5 · La descripción de la ficha se cortaba a media frase («…abertura trasera
   central para») sin forma de abrirla: scrollHeight 87 contra clientHeight 65 con
   clamp de 3 líneas. Es el argumento de venta de la prenda. */
html[data-hero-style="photo"] .product-desc { -webkit-line-clamp:6; }

/* R3-6 · El precio gritaba más que la prenda: en el Listado el nombre iba a
   21,6 px y el precio a 27,2; en la ficha el precio a 32. En la web real de la
   marca el precio va a 16 px y en la ficha a 16-18. El PVD manda sobre el PVP
   recomendado con la misma proporción de antes (0,7). */
html[data-hero-style="photo"] .item-price b { font-size:1.25rem; }
html[data-hero-style="photo"] .product-price b { font-size:1.5rem; }
html[data-hero-style="photo"] .product-price .pp-col:nth-child(2) b { font-size:1.05rem; }

/* R3-7 · El kicker sobre el control que esta ronda estrenó aquí es AHORA el
   tratamiento de la hoja base (bloque «CONTROLES DE FORMULARIO · sistema único»),
   así que el parche de marca desaparece: lo hereda todo el portal. La marca solo
   se queda con su papel de fondo, que es más cálido que el blanco de la base. */
html[data-hero-style="photo"] { --ctl-bg:var(--paper); }

/* R3-8 · La fila del Listado desperdiciaba el ancho: .item medía 1843 px y la
   última casilla de talla acababa en 678, o sea el 63 % de la fila en blanco.
   Aquel arreglo capó la PÁGINA a 96rem, y con ello capó también la CUADRÍCULA,
   que es justo la que quiere el ancho: a 2560 el catálogo entero se quedaba en
   1536 px con 512 px de blanco a cada lado. El cap se ha movido de la página a la
   vista de LISTADO (ver `.catalog-top:has(#list:not(.is-grid))` en el bloque del
   catálogo), que es donde el renglón largo era el problema. */

/* R3-9 · La pantalla de credenciales estaba descuadrada: el tipo más grande de la
   página («Hola / Comercial Levante», 56 px) quedaba pegado al borde inferior, a
   ~350 px de la única tarjeta que hay que pulsar. Es el mismo defecto que ya se
   arregló en .login-split; se le aplica la misma reordenación por áreas.
   Va en min-width para no pisar la media query de 52 rem, que apila. */
@media (min-width:52.0625rem) {
  html[data-hero-style="photo"] .cred-split { grid-template-rows:auto auto 1fr;
    grid-template-areas:"brand photo" "display photo" "main photo"; }
  html[data-hero-style="photo"] .cred-hero-mid { align-self:start;
    padding:1.1rem var(--access-pad) 0; }
  /* Con una sola credencial la tarjeta caía a 638 px, con ~310 px de blanco entre
     el saludo y ella: el panel deja de centrarse en vertical y arranca arriba,
     como el formulario del acceso. */
  html[data-hero-style="photo"] .cred-panel { align-content:start; padding-top:3rem; }
  /* Idéntico blindaje para el acceso: la regla de la l. 2994 va DESPUÉS de la
     media query de 52 rem y con su misma especificidad, así que en móvil le
     reponía la retícula de dos columnas. */
  html[data-hero-style="photo"] .login-split { grid-template-rows:auto auto 1fr;
    grid-template-areas:"brand photo" "display photo" "main photo"; }
}
/* Y la contrapartida: en ≤52 rem manda el apilado. Sin esto el acceso de Polo Club
   se quedaba en móvil con la retícula de dos columnas y la foto a 0 px de ancho
   (medido: .access-photo 0×844 en 390 px), es decir, SIN foto de acceso. */
@media (max-width:52rem) {
  html[data-hero-style="photo"] :is(.login-split, .cred-split) { grid-template-columns:1fr;
    grid-template-rows:auto auto auto 1fr; grid-template-areas:"brand" "photo" "display" "main"; }
  html[data-hero-style="photo"] :is(.login-display, .cred-hero-mid) { align-self:start;
    padding:1.4rem var(--gutter) 1.5rem; border-bottom:var(--rule-w) solid var(--rule); }
}

/* R3-10 · Los dos fallos de móvil (390×844), que se enseña.
   (a) Los puntos del carrusel se comían el CTA del hero: .hero-cta ocupaba
       y=586..634 y .c-dots y=621..645, 13 px de solape sobre el botón.
   (b) La cabecera perdía la ventana de servicio —solo quedaba «🛒 (0)»— porque
       el rótulo se recorta a 1×1 px desde la l. 1777. Aquí vuelve a verse, pero
       como banda fina en el borde inferior de la propia cabecera (no cabe en la
       fila: la marca ocupa 220 px de los 358 útiles). --header-h sube con ella,
       así que los sticky que lo leen (.ck-side, .h-menu, .rail) siguen cuadrados. */
@media (max-width:48rem) {
  html[data-hero-style="photo"] .hero-full .hero-cta { margin-bottom:2.6rem; }

  html[data-hero-style="photo"] { --header-h:86px; }
  html[data-hero-style="photo"] #chrome-header { padding-bottom:1.35rem; }
  html[data-hero-style="photo"] .h-cart .label { position:absolute; left:0; right:0; bottom:0;
    width:auto; height:auto; clip:auto; clip-path:none; overflow:visible;
    padding:.28rem clamp(1rem,4vw,2.4rem) .3rem; text-align:left;
    font-size:.64rem; font-weight:500; letter-spacing:.16em; line-height:1.25;
    color:var(--header-ink); background:var(--header-bg);
    border-top:1px solid color-mix(in srgb, var(--header-veil) 22%, transparent); }
  html[data-hero-style="photo"] #chrome-footer .foot-badge { height:3.4rem; }
}

/* R3-11 · La primera pantalla de la demo mezclaba las dos convenciones de caja:
   «¿Problemas para entrar?» en frase junto a «¿NO TIENES CUENTA?» e «INICIAR
   SESIÓN» en caja alta, con el mismo peso. Las cadenas llevan la mayúscula dentro
   y son compartidas con ALMA y BLOCCO, así que se resuelve desde CSS. Ninguna de
   esas cadenas lleva un nombre propio dentro (verificado en es/en/fr/it), y
   ::first-letter arrastra el «¿» inicial. */
html[data-hero-style="photo"] body:not([data-app="manage"]) :is(.submit, .login-panel h2) { text-transform:lowercase; }
html[data-hero-style="photo"] body:not([data-app="manage"]) :is(.submit, .login-panel h2)::first-letter { text-transform:uppercase; }

/* R3-12 · El raíl del lookbook no alineaba: con el nombre a una línea el precio
   subía 22 px respecto a las tarjetas de dos líneas y los «Seleccionar» quedaban
   a distinta altura. El nombre reserva dos líneas y el CTA se empuja abajo. */
html[data-hero-style="photo"] .lb-pcard .pcard-body { flex:1; }
html[data-hero-style="photo"] .lb-pcard .pcard-name { min-height:2.4em; }
html[data-hero-style="photo"] .lb-pcard .lb-add { margin-top:auto; }

/* R3-13 · Detalles sueltos de la capa de marca.
   (a) La caja de búsqueda era un rectángulo gris de 320×45 dentro del carbón; la
       web real no tiene campo en la cabecera y sus inputs van sin borde, con
       subrayado al 55 %. La lupa iba en --ink, invisible sobre fondo transparente.
   (b) El CTA del hero iba a peso 600 y con una flecha «→»; los botones de la
       marca son de peso normal y sin icono.
   (c) El filete de los chips era #C9C9C9 sobre papel: 1,66:1, casi invisible. */
html[data-hero-style="photo"] .h-search input { background:transparent; color:var(--header-ink);
  border:0; border-bottom:1px solid color-mix(in srgb, var(--header-veil) 55%, transparent);
  border-radius:0; padding-left:0; }
html[data-hero-style="photo"] .h-search input::placeholder {
  color:color-mix(in srgb, var(--header-veil) 65%, transparent); }
html[data-hero-style="photo"] .h-search input:focus,
html[data-hero-style="photo"] .h-search input:focus-visible { border-bottom-color:var(--header-ink); }
html[data-hero-style="photo"] .h-search button { color:var(--header-ink); }
html[data-hero-style="photo"] .h-search button:hover { color:var(--header-ink); opacity:.75; }
html[data-hero-style="photo"] #chrome-header .h-search button:focus-visible {
  outline:2px solid var(--header-veil); outline-offset:1px; }

html[data-hero-style="photo"] .hero-cta { font-weight:500; }
html[data-hero-style="photo"] .hero-cta span[aria-hidden="true"] { display:none; }

html[data-hero-style="photo"] :is(.item-attrs, .product-attrs, .product-sizes-head) .tag {
  border-color:color-mix(in srgb, var(--ink) 42%, var(--paper)); }

/* R3-14 · En Facturas, «Pagar con tarjeta» contradice la forma de pago que sale a
   su lado («Transferencia a 30 días») en una marca que cobra a 30 días. El lote de
   front-end ya no lo pinta en esta instancia (invoices.js, canPayByCard); esta línea
   es la red de seguridad por si el botón vuelve por otra vía. */
html[data-hero-style="photo"] .inv-pay { display:none; }

/* R3-15 · NEUTRALIDAD de las piezas nuevas que pinta el lote de front-end (la
   condición de la ventana en catálogo y ficha, y el PVP + margen en la fila del
   Listado). Nacen ocultas en la hoja base —precedente de .product-desc— y solo se
   ven en Polo Club, que es la instancia que ha redactado esos textos. */
.cat-window-note, .item-pvp, .item-margin { display:none; }
/* La nota de la entrega quedaba pegada a la barra de filtros y las dos líneas se leían
   como una sola: sube separándose del titular y respira antes de la barra. */
html[data-hero-style="photo"] .cat-window-note:not([hidden]) { display:block; margin:.55rem 0 1.35rem;
  font-size:.8rem; line-height:1.5; color:var(--ink-2); max-width:52rem; }
html[data-hero-style="photo"] .product-window-note { margin-top:.45rem; font-size:.78rem; }
html[data-hero-style="photo"] :is(.item-pvp, .item-margin) { display:block; }
html[data-hero-style="photo"] .item-margin { margin:.15rem 0 0; color:var(--muted); font-size:.8rem; }

/* R3-16 · INSIGNIAS DE ESTADO (petición del lote de front-end al de CSS). El bloque
   «Auditoría Modernist» de la l. 2255-2261 aplana con !important los cinco tonos que
   `statusChip()` sí emite bien, así que en Pedidos ABIERTO, ENVÍO PARCIAL, ENVIADO,
   FACTURADO y CANCELADO salían del mismo gris. Aquí se les devuelve tono, gateado y
   con !important (única forma de ganarle a un !important de menor especificidad).
   Paleta apagada de temporada —nada de semáforo— y el rojo reservado a lo que el
   juez pidió: CANCELADO y factura VENCIDA. Texto oscuro sobre lavado claro, todos
   por encima de 4,5:1. */
html[data-hero-style="photo"] .chip.tone-green  { background:#dfe9e1 !important; color:#235c3c !important; }
html[data-hero-style="photo"] .chip.tone-lime   { background:#e9ecd9 !important; color:#4c5a24 !important; }
html[data-hero-style="photo"] .chip.tone-amber  { background:#f2e7cf !important; color:#7a5410 !important; }
html[data-hero-style="photo"] .chip.tone-blue   { background:#dee5ea !important; color:#294a5e !important; }
html[data-hero-style="photo"] .chip.tone-orange { background:#f3e5da !important; color:#7d4423 !important; }
html[data-hero-style="photo"] .chip.tone-red    { background:#f4e0dc !important; color:#8f1d0f !important; }
html[data-hero-style="photo"] .srail-dot.tone-green  { background:#235c3c !important; }
html[data-hero-style="photo"] .srail-dot.tone-lime   { background:#6b7c31 !important; }
html[data-hero-style="photo"] .srail-dot.tone-amber  { background:#a8761a !important; }
html[data-hero-style="photo"] .srail-dot.tone-blue   { background:#3a5f77 !important; }
html[data-hero-style="photo"] .srail-dot.tone-orange { background:#a15b2e !important; }
html[data-hero-style="photo"] .srail-dot.tone-red    { background:#b03018 !important; }
/* R3-17 · ESTADO «ELIGE UN CLIENTE» de las pantallas de cliente a las que llega el AGENTE
   por su menú (Datos empresa, Cuadros de mando). El CTA va en carbón sólido, el mismo
   lenguaje que el de terminar pedido: el acento rojo está reservado a la banda de marca. */
html[data-hero-style="photo"] .agent-pick { display:grid; justify-items:start; gap:.35rem; }
html[data-hero-style="photo"] .agent-pick .cta { background:var(--ink); color:var(--paper);
  border-radius:var(--r,0); }
html[data-hero-style="photo"] .agent-pick .cta:hover { background:#000; }

/* R3-18 · LA FILA DEL LISTADO llenaba poco más de la mitad del ancho: el texto se acota a
   una medida legible (.item-info, max-width 52rem) y la matriz de tallas caía DEBAJO, así
   que en pantalla ancha sobraba casi el 47 % de la derecha. A partir de 1200 px las dos
   columnas van una al lado de la otra —foto | ficha | tallas— y la fila argumenta de un
   vistazo. Por debajo se conserva el apilado de siempre (móvil y tableta no se tocan). */
@media (min-width:1200px) {
  html[data-hero-style="photo"] .item { grid-template-columns:14rem minmax(0,24rem) minmax(0,1fr);
    grid-template-areas:"photo info matrix"; }
  html[data-hero-style="photo"] .item-matrix { align-self:start; }
}

/* ── Ficha con VARIAS ENTREGAS (views/product.js, matricesHtml) ──────────────
   Con el catálogo en «todas las entregas» la ficha apila una matriz por entrega. Cada
   tramo abre con una banda que la nombra y da sus fechas, con el mismo filete de capítulo
   que ya separa los tramos del carrito y del PDF del pedido: el comprador tiene que
   reconocer que son el mismo concepto en los tres sitios. Sin banda, dos rejillas de
   tallas seguidas se leen como una sola tabla partida. */
.buy-window + .buy-window { margin-top: 1.9rem; }
.buy-window-head { display:flex; flex-wrap:wrap; align-items:baseline; gap:.2rem .7rem;
  padding-bottom:.45rem; margin-bottom:.85rem; border-bottom:var(--rule-w,1px) solid var(--ink); }
.buy-window-head b { font-size:.82rem; letter-spacing:.09em; text-transform:uppercase; }
.buy-window-dates { color:var(--ink-2); font-size:.78rem; letter-spacing:.01em; }

/* Cambiar de entrega un tramo entero del carrito, desde su propia banda: antes había que
   borrar las líneas y volver a teclearlas en la otra entrega, talla por talla. */
/* DÍA DE SERVICIO del tramo. La entrega publica un rango ("del 01/10 al 31/10") y aquí se
   pide el día dentro de él: el campo lleva min/max, así que el calendario del navegador ya
   apaga lo que la marca no sirve. Va con su rótulo delante —un campo de fecha suelto en una
   banda no dice qué fecha es— y en la banda se queda a la derecha, antes del subtotal. */
.ck-when { display: inline-flex; align-items: center; gap: .4rem; margin-left: auto; }
.ck-when-label { font-size: .72rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); }
.ck-date { font: inherit; font-size: .78rem; font-variant-numeric: tabular-nums;
  padding: .18rem .4rem; border: 1px solid var(--line-control, #c9c4c4);
  background: transparent; color: var(--ink); }
.ck-date:hover { border-color: var(--ink); }
.ck-date:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
/* En el campo «Entrega» de la ficha (un <dd>) el nombre y las fechas van en renglones
   propios: ahí el campo baja a su propia línea en vez de pegarse al margen derecho. Y el
   campo ocupa la FILA ENTERA de la ficha: en una de las cuatro columnas (106 px a 1024) el
   rótulo caía en tres renglones y la fecha se salía de la tarjeta, cortada a «31/10/202». */
dd .ck-when { display: flex; margin: .35rem 0 0; }
.ck-row .ck-field:has(.ck-when) { grid-column: 1 / -1; }
.ck-row .ck-field .ck-date { max-width: 14rem; }
.ck-window-band .ck-when + .ck-window-total { margin-left: 1rem; }
/* La cantidad se corrige donde se ve el pedido, no volviendo al catálogo */
.ck-qty { width: 3.6rem; font: inherit; font-variant-numeric: tabular-nums; text-align: right;
  padding: .2rem .35rem; border: 1px solid var(--line-control, #c9c4c4); background: transparent; }
.ck-qty:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }


/* ── El CATÁLOGO ACTIVO, sobre la parrilla ─────────────────────────────────────
   Dónde y por qué AQUÍ. El catálogo NO es una faceta al lado de la entrega: la entrega
   es «un filtro más» porque no cambia de carrito, y el catálogo SÍ lo cambia. Y no puede
   colgar del rótulo del botón del carrito, porque en móvil ese `.label` está oculto (el
   header desbordaba con «REPOSICIÓN (0)»). Así que vive aquí, visible en las dos
   anchuras, y el botón del carrito conserva icono y contador. */
.cat-catalog { display:flex; flex-wrap:wrap; align-items:center; gap:.5rem;
  margin:0 0 .6rem; font-size:.88rem; color:var(--muted); }
.cat-catalog .cc-name { display:inline-flex; align-items:center; gap:.4rem;
  padding:.25rem .7rem; border:1px solid var(--line); border-radius:999px;
  background:var(--surface); color:var(--fg); font-weight:600; }
.cat-catalog .cc-other { padding:.25rem .7rem; border:1px solid transparent;
  border-radius:999px; background:none; color:var(--muted); font:inherit;
  cursor:pointer; }
.cat-catalog .cc-other:hover, .cat-catalog .cc-other:focus-visible {
  border-color:var(--line); color:var(--fg); }
.cat-catalog .cc-units { font-variant-numeric:tabular-nums; }

/* ══════════════ Sell-through (acción 36 · F2) ══════════════
   La tabla del cliente: temporada › tipo de pedido › modelo › talla. El SUBTOTAL ES LA FILA
   DEL GRUPO (convención de `ui/pivot.js`), así que la jerarquía se lee por sangría y peso, no
   por filas de total repetidas. La sangría va por variable (--st-indent) para que un nivel
   nuevo no obligue a escribir otra regla.

   El panel de la derecha es el hueco RESERVADO al bloque de sell-out: hoy explica qué es y
   cómo se empieza. Con una tabla en blanco o treinta y seis columnas de ceros, nadie abriría
   esta pantalla una segunda vez. */
.page-sellthrough .st-board { display:grid; grid-template-columns:minmax(0,1fr) 20rem;
  gap:1.6rem; align-items:start; }
.page-sellthrough .st-table-wrap { overflow-x:auto; }

.st-headline { margin:0 0 1.4rem; }
.st-client { margin:0 0 .6rem; font-size:1.05rem; font-weight:700; }
.st-code { margin-left:.5rem; font-size:.8rem; font-weight:600; color:var(--muted);
  font-variant-numeric:tabular-nums; }
.st-chips { display:flex; flex-wrap:wrap; gap:.7rem; list-style:none; margin:0 0 .7rem; padding:0; }
.st-chip { display:flex; align-items:baseline; gap:.45rem; padding:.55rem .9rem;
  border-top:var(--rule-w,2px) solid var(--rule,var(--ink)); background:var(--card); }
.st-chip-season { font-weight:700; text-transform:uppercase; letter-spacing:.04em; font-size:.78rem; }
.st-chip-figure { font-weight:700; font-variant-numeric:tabular-nums; }
.st-chip-label { font-size:.72rem; color:var(--muted); }
.st-chip-pct { margin-left:.3rem; font-weight:700; font-variant-numeric:tabular-nums; }
.st-basis { margin:0; font-size:.8rem; color:var(--muted); }

.st-note { margin:0 0 .7rem; padding:.6rem .9rem; font-size:.82rem;
  border-left:3px solid var(--line); background:var(--card); }
.st-note-warn { border-left-color:var(--blue); }
.st-quality { margin:0 0 1rem; padding:.7rem .9rem; background:var(--card); font-size:.8rem; }
.st-quality ul { display:flex; flex-wrap:wrap; gap:.2rem 1.4rem; list-style:none;
  margin:.4rem 0 0; padding:0; }
.st-quality b { font-variant-numeric:tabular-nums; }

.st-table { width:100%; border-collapse:collapse; font-size:.86rem; }
.st-table th, .st-table td { padding:.5rem .7rem; text-align:left; vertical-align:baseline;
  border-bottom:1px solid var(--line); }
.st-table thead th { font-size:.72rem; text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted); border-bottom:var(--rule-w,2px) solid var(--rule,var(--ink)); }
.st-table .num { text-align:right; font-variant-numeric:tabular-nums; }
.st-table tbody th { font-weight:400; padding-left:calc(.7rem + var(--st-indent,0) * 1.25rem); }
.st-row.st-level-season > th { font-weight:700; text-transform:uppercase; letter-spacing:.04em; }
.st-row.st-level-season > * { border-top:var(--rule-w,2px) solid var(--rule,var(--ink)); }
.st-row.st-level-orderType > th { font-weight:700; }
.st-row.st-level-model > th { font-weight:600; }
.st-row.st-level-variant { color:var(--muted); }
.st-toggle { border:0; background:none; font:inherit; cursor:pointer; padding:0 .4rem 0 0;
  color:var(--muted); }
.st-toggle:hover, .st-toggle:focus-visible { color:var(--ink); }
.st-toggle-space { display:inline-block; width:1.1rem; }
.st-none { color:var(--muted); font-style:italic; }
.st-badge { font-size:.75rem; color:var(--muted); }
.st-empty { margin:1.6rem 0; color:var(--muted); }

.st-sellout { border-top:var(--rule-w,2px) solid var(--rule,var(--ink));
  background:var(--card); padding:1rem; }
.st-sellout h2 { margin:0 0 .6rem; font-size:.86rem; text-transform:uppercase; letter-spacing:.06em; }
.st-sellout p { margin:0 0 .7rem; font-size:.82rem; line-height:1.45; }
.st-sellout-empty { font-weight:700; }
.st-sellout-note { color:var(--muted); font-size:.76rem; }
.st-sellout h3 { margin:1.1rem 0 .5rem; font-size:.78rem; text-transform:uppercase;
  letter-spacing:.06em; }
/* Las dos plantillas, una al lado de la otra: la elección entre «por talla» y «por modelo»
   es la del FORMATO del fichero, y verlas juntas es lo que la hace evidente. */
.st-sellout-tpl { display:flex; gap:.4rem; flex-wrap:wrap; margin-bottom:.8rem; }
.st-sellout-tpl .btn-ghost { font-size:.74rem; padding:.35rem .7rem; }
.st-sellout-field { display:block; margin-bottom:.6rem; }
.st-sellout-field > span { display:block; font-size:.72rem; font-weight:700; color:var(--muted);
  text-transform:uppercase; letter-spacing:.04em; margin-bottom:.25rem; }
.st-sellout-field select { width:100%; font-size:.8rem; padding:.35rem .5rem;
  border:1px solid var(--line-control); background:var(--paper); color:var(--ink); }
.st-sellout-check { display:flex; gap:.45rem; align-items:flex-start; font-size:.78rem;
  margin:.5rem 0 .7rem; }
.st-sellout-list { margin:0 0 .9rem; padding-left:1.1rem; font-size:.76rem;
  color:var(--muted); line-height:1.6; }
.st-sellout-list em { display:block; font-style:normal; font-size:.72rem; }
/* El error y la confirmación NO se distinguen solo por el color: llevan filete y peso. */
.st-sellout-error, .st-sellout-ok { font-size:.78rem; line-height:1.45; padding:.5rem .7rem;
  border-left:3px solid currentColor; font-weight:600; }
.st-sellout-error { color:var(--out, #c0392b); }
.st-sellout-ok { color:var(--in, #1e7a4a); }

/* ── EL BLOQUE DE SELL-OUT, a la derecha del de sell-in ──────────────────────────────────
   El contraste entre los dos bloques usa TRES canales y ninguno de ellos es solo el color:
     1. un filete vertical de 2 px en la costura, y otro entre las dos fechas;
     2. una superficie propia con un token NEUTRO (--paper-2). No un lavado del acento de
        marca: un rojo al 5 % sobre papel se lee como estado de error, y el acento cambia por
        marca (--brand-accent), así que en una marca verde el bloque cambiaría de significado;
     3. una cabecera de dos pisos con la fecha abarcando sus tres columnas.
   --paper-2 se deriva de --surface, que YA es el token de superficie de la marca: así el
   bloque sigue a la marca sin tocar el acento, y sin un valor literal que se quede atrás. */
:root { --paper-2:color-mix(in srgb, var(--surface) 55%, var(--card)); }

.st-table-so th, .st-table-so td { border-bottom:1px solid var(--line); }
.st-so { background:var(--paper-2); }
.st-so-edge { border-left:2px solid var(--rule,var(--ink)); }
.st-table thead .st-so { color:var(--ink); }
.st-table thead th.st-so-primary { font-weight:700; }
.st-so-pct { white-space:nowrap; }

/* La micro-barra va DENTRO de la celda del porcentaje y solo en la columna primaria: doce
   barras repartidas por una banda que se desplaza no comparan nada. Es decorativa —el número
   está al lado— y por eso lleva aria-hidden en el HTML. */
.st-bar { display:inline-block; width:2.6rem; height:.45rem; margin-right:.4rem;
  vertical-align:middle; background:var(--surface); }
.st-bar::before { content:""; display:block; height:100%; width:var(--st-bar,0%);
  background:var(--ink); }

.st-sort { border:0; background:none; font:inherit; color:inherit; cursor:pointer;
  padding:0; text-transform:inherit; letter-spacing:inherit; }
.st-sort:hover, .st-sort:focus-visible { text-decoration:underline; }

.st-tools { display:flex; flex-wrap:wrap; align-items:flex-end; gap:.8rem 1.2rem;
  margin:0 0 .9rem; }
.st-tools-primary { margin:0; font-size:.8rem; font-weight:700; }
.st-tools-field { display:flex; flex-direction:column; gap:.2rem; font-size:.74rem; }
.st-tools-field > span { font-weight:700; color:var(--muted); text-transform:uppercase;
  letter-spacing:.04em; }
.st-tools-field select { font-size:.8rem; padding:.3rem .5rem;
  border:1px solid var(--line-control); background:var(--paper); color:var(--ink); }
.st-tools .btn-ghost { font-size:.74rem; padding:.35rem .7rem; }

/* EL FILTRO POR TEMPORADAS. Botones de dos estados, no un desplegable múltiple: con dos o
   tres temporadas la elección se ve entera sin abrir nada, y un <select multiple> obliga a
   saber que hay que pulsar Ctrl. El estado NO se distingue solo por el color —invierte el
   fondo y engorda el filete—, que es la misma regla que ya gobierna el error y la
   confirmación de la carga. */
.st-seasons-chips, .st-tree-buttons { display:flex; flex-wrap:wrap; gap:.35rem; }
.st-season { display:inline-flex; align-items:baseline; gap:.4rem; cursor:pointer;
  font:inherit; font-size:.76rem; padding:.3rem .6rem; color:var(--ink);
  border:1px solid var(--line-control); background:var(--paper); }
.st-season:hover, .st-season:focus-visible { border-color:var(--ink); }
.st-season[aria-pressed="true"] { background:var(--ink); color:var(--paper);
  border-color:var(--ink); font-weight:700; }
.st-season-label { text-transform:uppercase; letter-spacing:.03em; }
.st-season-units { font-variant-numeric:tabular-nums; opacity:.75; }
.st-tools-note { margin:-.4rem 0 .9rem; font-size:.78rem; color:var(--muted); }
.st-outside-note { grid-column:1 / -1; margin:0; }

.st-low-caption { text-align:left; font-size:.82rem; font-weight:700; padding:0 0 .6rem; }

/* Lo que no cabe en ninguna línea. Va DEBAJO de la tabla y con su propio rótulo: fuera del
   porcentaje, pero no fuera de la pantalla. */
.st-outside { display:grid; gap:1rem; margin-top:1.6rem;
  grid-template-columns:repeat(auto-fit,minmax(16rem,1fr)); }
.st-outside-block { border-top:var(--rule-w,2px) solid var(--rule,var(--ink));
  background:var(--card); padding:.8rem .9rem; }
.st-outside-block h3 { margin:0 0 .3rem; font-size:.78rem; text-transform:uppercase;
  letter-spacing:.06em; display:flex; justify-content:space-between; gap:.6rem; }
.st-outside-units { font-variant-numeric:tabular-nums; }
.st-outside-list { list-style:none; margin:.5rem 0 0; padding:0; font-size:.78rem; }
.st-outside-list li { display:flex; justify-content:space-between; gap:.8rem;
  padding:.2rem 0; border-bottom:1px solid var(--line); }
.st-outside-list b { font-variant-numeric:tabular-nums; }
.st-chip-sold { color:var(--ink); }

/* La cuarta tarjeta del modal de clientes va SOLA en su fila y con su propio rótulo: es la
   única que no suplanta, y mezclarla con las tres de compra sería invitar a pulsarla
   creyendo que hace lo mismo que las de al lado. */
.sel-actions-title-look { margin-top:1.1rem; }
.sel-actions-look { grid-template-columns:1fr; }

/* Por debajo del umbral de la casa la tabla no cabe a dos columnas: el panel de sell-out baja
   debajo y la tabla se desplaza DENTRO de su caja, nunca la página entera. */
@media (max-width:60rem) {
  .page-sellthrough .st-board { grid-template-columns:minmax(0,1fr); }
}

/* ══════════════ Evolución de temporadas (acción v2-8) ══════════════
   OCHO COLUMNAS FIJAS, den igual dos temporadas que cuatro: la temporada va en FILAS y lo que
   crece hacia abajo son filas, no columnas. Por eso esta tabla cabe a 1024 px sin defender
   nada y el PDF sigue siendo A4 vertical como los otros tres documentos del producto.

   La tabla vive igualmente dentro de `.st-table-wrap` con `overflow-x:auto`: si una marca
   configura cuatro niveles con rótulos largos, el desplazamiento es del BLOQUE y nunca de la
   página. */
.page-seasonevo .st-table-wrap { overflow-x:auto; }

.se-back { display:flex; flex-wrap:wrap; align-items:center; gap:1rem; margin:0 0 1.2rem;
  font-size:.84rem; }
.se-headline { margin:0 0 1.4rem; }
.se-client { margin:0 0 .3rem; font-size:1.05rem; font-weight:700; }
.se-range { margin:0 0 .5rem; font-size:.9rem; font-weight:700; text-transform:uppercase;
  letter-spacing:.05em; }
.se-cut, .se-grouping { margin:.15rem 0 0; font-size:.8rem; color:var(--muted); }

/* ── El selector: la PRIMERA pantalla del informe, no un modal ──
   La evidencia va delante de la decisión. Cada temporada enseña lo que tiene —pedidas,
   servidas, vendidas— y lo que le falta, con el aviso escrito debajo y no en un emergente. */
.se-picker { max-width:44rem; border-top:var(--rule-w,2px) solid var(--rule,var(--ink));
  background:var(--card); padding:1.1rem 1.2rem; }
.se-picker-title { display:flex; flex-wrap:wrap; justify-content:space-between; gap:.6rem;
  margin:0 0 .9rem; font-weight:700; }
.se-picker-count { font-size:.8rem; font-weight:600; color:var(--muted);
  font-variant-numeric:tabular-nums; }
.se-picks { list-style:none; margin:0 0 1rem; padding:0; }
.se-pick { padding:.6rem 0; border-bottom:1px solid var(--line); }
.se-pick label { display:flex; flex-wrap:wrap; align-items:baseline; gap:.6rem; cursor:pointer; }
.se-pick-off label { cursor:default; color:var(--muted); }
.se-pick-label { font-weight:700; }
.se-pick-figures { font-size:.8rem; color:var(--muted); font-variant-numeric:tabular-nums; }
/* El aviso incómodo, DELANTE de generar el informe: es lo que impide que alguien lance el
   informe estrella y se encuentre una columna de guiones. */
.se-pick-warn { margin:.35rem 0 0 1.6rem; font-size:.78rem; color:var(--muted);
  line-height:1.45; }
.se-picker-reason { margin:0 0 .8rem; font-size:.82rem; color:var(--muted); }
.se-picker-actions { display:flex; flex-wrap:wrap; gap:.6rem; align-items:center; }

/* ── Las tablas ── */
.se-tools { display:flex; flex-wrap:wrap; gap:1rem; align-items:center; margin:0 0 1.2rem;
  font-size:.82rem; }
.se-only { display:flex; align-items:center; gap:.4rem; }
.se-level { margin:0 0 2.2rem; }
.se-level-title { display:flex; flex-wrap:wrap; align-items:baseline; gap:.6rem;
  margin:0 0 .3rem; font-size:.9rem; text-transform:uppercase; letter-spacing:.06em; }
.se-level-num { display:inline-flex; align-items:center; justify-content:center;
  min-width:1.5rem; height:1.5rem; border-radius:999px; background:var(--ink); color:var(--paper);
  font-size:.72rem; font-weight:700; }
.se-level-count { font-size:.72rem; font-weight:600; color:var(--muted);
  letter-spacing:.03em; text-transform:none; font-variant-numeric:tabular-nums; }
.se-level-note { margin:0 0 .7rem; font-size:.76rem; color:var(--muted); }

.se-table { width:100%; border-collapse:collapse; font-size:.86rem; }
.se-table th, .se-table td { padding:.45rem .7rem; text-align:left; vertical-align:baseline;
  border-bottom:1px solid var(--line); }
.se-table thead th { font-size:.72rem; text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted); border-bottom:var(--rule-w,2px) solid var(--rule,var(--ink)); }
.se-table .num { text-align:right; font-variant-numeric:tabular-nums; }
/* El nombre del miembro abarca sus filas de temporada con `rowspan`: un lector de pantalla
   anuncia «Polos · SS 26 · 78 %» y no un «78 %» suelto repetido dos veces. */
.se-member { vertical-align:top; font-weight:700; }
.se-member-label { display:block; }
.se-row-first > * { border-top:var(--rule-w,2px) solid var(--rule,var(--ink)); }
.se-season { white-space:nowrap; }
.se-none { color:var(--muted); font-style:italic; }

/* El movimiento y la brecha llevan SIGNO Y PALABRA, nunca solo color: el papel se imprime en
   blanco y negro y quien no distingue el rojo del verde tiene que leer lo mismo. */
.se-move { display:block; margin-top:.2rem; font-size:.75rem; font-weight:600; }
.se-move-down { color:var(--blue,#7a2b2b); }
.se-move-up { color:var(--muted); }
.se-move-flat, .se-move-none { color:var(--muted); font-weight:400; font-style:italic; }
.se-gap-value { font-weight:700; }
.se-market { font-weight:600; }
.se-market-n, .se-market-flag { display:block; font-size:.7rem; color:var(--muted); }
.se-short { color:var(--muted); font-size:.78rem; font-style:italic; }

.se-single { margin-top:1rem; }
.se-single summary { cursor:pointer; font-size:.82rem; font-weight:700; }
.se-single-help { margin:.5rem 0 .8rem; font-size:.78rem; color:var(--muted); line-height:1.5; }
.se-foot { margin:.5rem 0 0; font-size:.76rem; color:var(--muted); line-height:1.5; }

/* La entrada al informe, con el motivo escrito al lado cuando no se puede abrir. */
.st-tools-evo { display:inline-flex; align-items:center; gap:.5rem; flex-wrap:wrap; }
.st-tools-why { font-size:.74rem; color:var(--muted); max-width:22rem; }

/* Por debajo de ~700 px la tabla deja de ser una cuadrícula: cada miembro pasa a ser una
   tarjeta con su lista de temporadas, y la página sigue sin desbordarse a lo ancho. */
@media (max-width:44rem) {
  .se-table, .se-table tbody, .se-table tr, .se-table td, .se-table th { display:block; }
  .se-table thead { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }
  .se-table tr { border-bottom:1px solid var(--line); }
  .se-table .se-member { border-top:var(--rule-w,2px) solid var(--rule,var(--ink)); }
  .se-table td { display:flex; justify-content:space-between; gap:1rem; border:0;
    padding:.25rem .7rem; text-align:right; }
  /* CADA DATO CON SU RÓTULO DELANTE. Sin esto la tarjeta es una columna de números sueltos:
     la cabecera de la tabla está oculta en esta anchura y nadie sabe cuál es cuál. */
  .se-table td[data-th]::before { content:attr(data-th); font-size:.7rem; font-weight:600;
    color:var(--muted); text-transform:uppercase; letter-spacing:.04em; text-align:left; }
  .se-table td.se-season { font-weight:700; text-align:left; }
}

/* ── Los paneles de movimiento ──
   Van ARRIBA porque son la respuesta a la pregunta con la que se abre el informe; la tabla
   completa va debajo porque es lo que pidió el encargo y porque es lo que hace que esto siga
   siendo un informe cuando el mercado no está listo. */
.se-panels { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:1.2rem;
  margin:0 0 .6rem; }
.se-panel { border-top:var(--rule-w,2px) solid var(--rule,var(--ink)); padding:.8rem 0 0; }
.se-panel-title { margin:0 0 .6rem; font-size:.78rem; text-transform:uppercase;
  letter-spacing:.06em; font-weight:700; }
.se-panel-list { list-style:none; margin:0; padding:0; }
.se-panel-row { display:flex; justify-content:space-between; align-items:baseline; gap:1rem;
  padding:.3rem 0; border-bottom:1px solid var(--line); font-size:.84rem; }
.se-panel-what { font-weight:600; }
.se-panel-pp { font-weight:700; font-variant-numeric:tabular-nums; white-space:nowrap; }
.se-panel-figures { color:var(--muted); font-size:.78rem; font-variant-numeric:tabular-nums;
  text-align:right; }
.se-panel-more, .se-panel-empty { margin:.4rem 0 0; font-size:.76rem; color:var(--muted); }
.se-panels-help { margin:0 0 1.4rem; font-size:.76rem; color:var(--muted); }
.se-panels-none { margin:0 0 1.4rem; padding:.6rem .9rem; font-size:.82rem;
  border-left:3px solid var(--line); background:var(--card); }
.se-panel-only { margin:0 0 1.6rem; }

/* La sparkline es DECORATIVA (`aria-hidden` en la vista): si no se pintara, la fila diría
   exactamente lo mismo, porque los números están escritos al lado. Dos polilíneas dibujadas a
   mano, sin librerías y sin CDN. */
.se-spark { display:block; margin-top:.35rem; width:6rem; height:1.5rem; overflow:visible; }
.se-spark polyline { fill:none; stroke-width:1.5; vector-effect:non-scaling-stroke; }
.se-spark-own { stroke:var(--ink); }
.se-spark-market { stroke:var(--muted); stroke-dasharray:3 2; }

@media (max-width:44rem) {
  .se-panels { grid-template-columns:minmax(0,1fr); }
}
