/* JOSHTML v2 — estilos base. Todo cuelga de variables --jos-*, que applyBrand()
   sobrescribe con la marca del documento. Móvil primero: los sitios de restaurante
   se ven en el teléfono. Sin @import, sin fuentes remotas: la CSP del hosting manda. */

:root {
  --jos-bg: #0a0a0b;
  /* Segunda superficie. Ocho pantallas del mismo plano se leen como una sola cosa
     barata; alternar el fondo le da al ojo dónde apoyarse y marca dónde acaba una
     sección. Se deriva de la marca (no es un gris fijo) para que applyBrand() la
     arrastre sola: quien cambie --jos-bg no tiene que acordarse de esta. */
  --jos-bg-2: color-mix(in srgb, var(--jos-bg) 96%, var(--jos-ink));
  --jos-ink: #f4f1ea;
  --jos-accent: #c8102e;
  --jos-accent2: #d4a437;
  /* La tinta que va ENCIMA del acento (botones). No se puede fijar en #fff: un acento
     claro —un dorado, un ámbar, un lima— deja el rótulo del botón en 2:1 y el botón
     principal del sitio se vuelve el elemento menos legible de la página. Se declara
     en la marca (`brand.onAccent`) porque sólo quien eligió el acento sabe qué tinta
     lo contrasta; el valor por omisión conserva el blanco de los acentos oscuros. */
  --jos-btn-ink: #fff;
  --jos-panel: rgba(255, 255, 255, .05);
  --jos-line: rgba(255, 255, 255, .12);
  --jos-radius: 14px;
  /* Tres papeles, no dos. Separarlos es lo que permite que --jos-display sea
     una blackletter sin volver ilegible la interfaz. */
  --jos-display: ui-sans-serif, system-ui, "Helvetica Neue", sans-serif;  /* titulares grandes */
  --jos-ui: ui-sans-serif, system-ui, "Helvetica Neue", sans-serif;       /* nav, botones, etiquetas */
  --jos-body: ui-sans-serif, system-ui, "Helvetica Neue", sans-serif;     /* texto corrido */
  --jos-tenue: color-mix(in srgb, var(--jos-ink) 58%, transparent);
  --jos-ancho: 1080px;
  --jos-aire: 22px;   /* aire lateral */
  /* MEDIA ración de aire vertical: el bloque pone la mitad arriba y la mitad abajo,
     así el hueco entre dos secciones contiguas es UNA ración, no la suma de dos.
     Antes eran 82px + 82px = 164px de negro muerto entre la carta y lo siguiente.
     Y va en clamp() porque 82px fijos son un lujo para un bloque de tres líneas:
     el aire debe crecer con el viewport, no con la terquedad del CSS. */
  --jos-aire-b: clamp(34px, 4.6vw, 52px);
}

.jos-root *, .jos-root *::before, .jos-root *::after { box-sizing: border-box; }
.jos-root { color: var(--jos-ink); font: 400 16.5px/1.65 var(--jos-body); }
/* Aquí vivía `-webkit-font-smoothing: antialiased`. Se quitó el 5 sep 2026 y no es
   cosmética de gusto: en FONDO OSCURO esa regla apaga el subpixel y adelgaza cada
   trazo, y una tipografía de display pesada —Alfa Slab One en shrimp, Anton en
   california— se ve lavada y borrosa. Medido en /carta de shrimp-lighthouse: mismo
   ancho de caja, bordes visiblemente más definidos con el subpixel de vuelta.
   La regla nació del tópico «texto más limpio en Mac», que es cierto sobre fondo
   CLARO. De los 8 documentos publicados, 6 son oscuros: josfox, kii-bucerias,
   old-manchester, shrimp-lighthouse, tao-franquicias y aceptacion-v1. Sólo
   california-krispy-chicken (#fffdf6) y tao-comida-oriental (#faf4e6) son claros,
   y ahí quitarla sólo devuelve el render por omisión del navegador. */
.jos-root img { max-width: 100%; display: block; }
/* El :where() es lo que hace que estos reset SEAN reset. Escritos como
   `.jos-root p` pesaban (0,1,1) y le ganaban a cualquier `.jos-clase` (0,1,0):
   el `margin: 12px auto 22px` de .jos-band__desc computaba 0px y la caja se iba
   contra el borde izquierdo. Con :where() pesan (0,1,0) y las clases de abajo,
   por ir después, mandan. Lo mismo destapa .jos-b__title, .jos-hero__sub,
   .jos-menu__catname y .jos-plan__feats, que llevaban tiempo con el margen muerto.

   El ancla es el caso que más caro salió, y por eso va aquí y no suelta. Los 14
   bloques no emiten un solo <button>: todo CTA, todo enlace de fila y todo enlace
   de nav es un <a>. Mientras esta regla pesó (0,1,1) se comió el `color` de TODAS
   las clases que se le montan encima, que pesan (0,1,0):
     · .jos-btn        → tiraba --jos-btn-ink a la basura y heredaba --jos-ink.
                         En /s/kii-bucerias los tres CTA median 1.82:1 (ink claro
                         sobre acento dorado) aunque la marca SÍ declaraba
                         `brand.onAccent: "#0b0a06"`, que da 8.85:1. Es decir: el
                         motor publicaba ilegible el fallo que `onAccent` existe
                         para evitar (SPEC §1), teniendo el valor bueno en la mano.
     · .jos-rows__link → perdía --jos-accent2 y el enlace de contacto quedaba
                         indistinguible del texto: sin más pista que el subrayado
                         del :hover, que en un teléfono no existe.
     · .jos-nav__link  → perdía --jos-tenue y nacía ya en --jos-ink, así que su
                         propia regla de :hover/[aria-current] (0,2,0) pintaba el
                         color que el enlace ya tenía: la página actual no se
                         marcaba en ningún lado.
   Con :where() el ancla pesa (0,1,0), sigue siendo el valor por omisión de
   cualquier <a> sin clase, y deja de pisar al que sí trae tinta declarada. */
.jos-root :where(a) { color: inherit; text-decoration: none; }
.jos-root :where(h1, h2, h3) { font-family: var(--jos-display); line-height: 1.1; margin: 0; }
.jos-root :where(p, ul, dl) { margin: 0; }
.jos-root :focus-visible { outline: 2px solid var(--jos-accent2); outline-offset: 3px; }

/* ── cabecera ─────────────────────────────────────────────────── */
.jos-header {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 14px;
  padding: 12px var(--jos-aire); min-height: 62px;
  background: color-mix(in srgb, var(--jos-bg) 92%, transparent);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--jos-line);
}
.jos-header__marca { font-family: var(--jos-ui); font-weight: 700; font-size: 17px; letter-spacing: .02em; }
.jos-header__marca img { height: 34px; width: auto; }
.jos-nav { display: none; gap: 22px; margin-left: auto; }
.jos-nav__link {
  font-family: var(--jos-ui); font-size: 13px; font-weight: 500;
  letter-spacing: .09em; text-transform: uppercase; color: var(--jos-tenue);
}
.jos-nav__link:hover, .jos-nav__link[aria-current="page"] { color: var(--jos-ink); }
.jos-header .jos-btn { margin-left: auto; }
.jos-nav + .jos-btn { margin-left: 0; }

/* ── botones ──────────────────────────────────────────────────── */
.jos-btn {
  display: inline-block; font-family: var(--jos-ui); font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; font-size: 13px;
  padding: 12px 20px; border: 1px solid var(--jos-accent); border-radius: 3px;
  background: var(--jos-accent); color: var(--jos-btn-ink); cursor: pointer;
  transition: filter .15s, transform .15s; white-space: nowrap; text-align: center;
}
.jos-btn:hover { filter: brightness(.88); }
.jos-btn:active { transform: translateY(1px); }
.jos-btn[disabled] { opacity: .55; cursor: progress; }
.jos-btn--sm { padding: 9px 14px; font-size: 12px; }
.jos-btn--full { display: block; width: 100%; margin-top: 6px; }

/* ── secciones ────────────────────────────────────────────────── */
.jos-main { display: block; }
.jos-b {
  /* La MEDIDA la pone el padding, no un max-width. El bloque ocupa todo el ancho de la
     página y la columna de texto sigue valiendo --jos-ancho, pero ahora el fondo de la
     sección llega a sangre solo, sin trucos. Se probaron los dos trucos habituales y
     los dos se caen: un ::before a 100vw cuenta como overflow y saca barra horizontal
     cuando hay scrollbar, y `box-shadow: 0 0 0 100vmax` + clip-path pinta una capa de
     ~2900×2900 que Chromium no rasteriza — la carta larga se truncaba a media página.
     El max() protege el móvil: cuando la resta da negativo, gana --jos-aire. */
  padding-block: var(--jos-aire-b);
  padding-inline: max(var(--jos-aire), (100% - var(--jos-ancho)) / 2);
  /* Qué superficie pisa este bloque. Lo declara el bloque y lo heredan sus hijos,
     que es la única forma de que una tarjeta opaca (.jos-stat) sepa sobre qué
     fondo está sin que nadie se lo pase a mano. */
  --jos-surface: var(--jos-bg);
}
/* El primero no tiene vecino arriba: sin esto arranca pegado a la cabecera.
   El hero se excluye porque trae su propio aire y su propio degradado. */
.jos-main > .jos-b:first-child:not(.jos-b--hero) { padding-top: calc(var(--jos-aire-b) * 1.35); }

/* Alternancia de superficie: una sección sí y una no cambian de fondo. El hero y la
   franja de acción quedan fuera porque ya traen superficie propia — pintarlas otra vez
   sería la cebra que no queremos; con ellas fuera el ritmo queda en dos o tres cambios
   por página, que es lo que el ojo necesita para saber dónde acaba cada cosa.
   Los :not() van encadenados porque :not(a, b) es Selectors 4 y no lo entienden los
   Safari viejos que todavía visitan estos sitios. */
.jos-main > .jos-b:nth-of-type(even):not(.jos-b--hero):not(.jos-b--cta-band):not(.jos-b--unknown) {
  --jos-surface: var(--jos-bg-2);
  background: var(--jos-surface);
}
.jos-b__title {
  font-weight: 700; text-transform: uppercase; letter-spacing: -.2px;
  font-size: clamp(24px, 5.4vw, 36px); margin-bottom: 10px;
}
.jos-b__desc { color: var(--jos-tenue); margin-bottom: 26px; max-width: 62ch; }

/* ── hero ─────────────────────────────────────────────────────── */
/* El hero pide más aire que un bloque cualquiera y más arriba que abajo, para que el
   título respire bajo la cabecera y el degradado no se corte en seco. Hasta ahora esta
   línea no servía de nada: el `.jos-b { padding: 82px }` del @media iba después y con
   la misma especificidad, así que le ganaba. */
.jos-b--hero {
  position: relative; text-align: center; overflow: hidden;
  /* padding-block y no el atajo `padding`: el atajo pisaría el padding-inline que le da
     la medida a .jos-b y el hero se iría a los bordes. */
  padding-block: calc(var(--jos-aire-b) * 1.45) calc(var(--jos-aire-b) * 1.25);
}
.jos-b--hero::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(900px 420px at 50% -8%, color-mix(in srgb, var(--jos-accent) 22%, transparent), transparent 70%),
    radial-gradient(700px 360px at 50% 110%, color-mix(in srgb, var(--jos-accent2) 12%, transparent), transparent 70%);
}
.jos-b--hero > * { position: relative; }
.jos-b--hero[data-align="left"] { text-align: left; }
.jos-b--hero[data-align="left"] .jos-hero__img, .jos-b--hero[data-align="left"] .jos-hero__sub { margin-left: 0; }
.jos-hero__img { margin: 0 auto 26px; max-height: 108px; width: auto; }
.jos-hero__kicker {
  font-family: var(--jos-ui); letter-spacing: .26em; text-transform: uppercase;
  font-size: 11.5px; color: var(--jos-accent2); margin-bottom: 16px;
}
.jos-hero__title {
  font-weight: 700; text-transform: uppercase; letter-spacing: -.5px;
  font-size: clamp(30px, 8vw, 58px); line-height: 1.06;
}
.jos-hero__sub { color: var(--jos-tenue); max-width: 600px; margin: 18px auto 0; font-size: 17px; }
.jos-hero__actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; margin-top: 28px; }
.jos-b--hero[data-align="left"] .jos-hero__actions { justify-content: flex-start; }

/* ── texto ────────────────────────────────────────────────────── */
.jos-prose { display: grid; gap: 15px; max-width: 68ch; color: var(--jos-tenue); }
.jos-prose p { font-size: 16.5px; }

/* ── rejilla de tarjetas ──────────────────────────────────────── */
.jos-grid { display: grid; grid-template-columns: 1fr; gap: 16px; }
.jos-card, .jos-quote, .jos-plan {
  background: var(--jos-panel); border: 1px solid var(--jos-line);
  border-radius: var(--jos-radius); padding: 24px;
}
.jos-card { border-top: 3px solid var(--jos-accent); transition: transform .18s, border-color .18s; }
.jos-card:hover { transform: translateY(-3px); border-top-color: var(--jos-accent2); }
.jos-card__icon { font-size: 26px; line-height: 1; margin-bottom: 12px; }
.jos-card__title {
  font-family: var(--jos-ui); font-weight: 600; text-transform: uppercase;
  letter-spacing: .05em; font-size: 18px; margin-bottom: 9px;
}
.jos-card__desc { color: var(--jos-tenue); font-size: 15px; }

/* ── carta ────────────────────────────────────────────────────── */
.jos-menu { display: grid; grid-template-columns: 1fr; gap: 0 48px; }
.jos-menu__catname {
  font-weight: 700; text-transform: uppercase; letter-spacing: .1em; font-size: 14px;
  color: var(--jos-accent2); margin: 26px 0 6px; padding-bottom: 8px;
  border-bottom: 1px solid var(--jos-line);
}
.jos-menu__item { padding: 13px 0; border-bottom: 1px dashed var(--jos-line); }
.jos-menu__item.is-86 { opacity: .45; }
.jos-menu__item.is-86 .jos-menu__name { text-decoration: line-through; }
.jos-menu__row { display: flex; gap: 10px; align-items: baseline; }
.jos-menu__name { font-family: var(--jos-ui); font-weight: 500; font-size: 16.5px; letter-spacing: .02em; }
.jos-menu__dots { flex: 1; border-bottom: 1px dotted var(--jos-line); margin-bottom: 5px; }
/* Un guía de puntos que no lleva a ningún precio promete una columna que no
   existe: la fila queda con una línea punteada que muere en el borde derecho.
   Pasa con `menu.showPrices: false`, que el SPEC §2 permite y que sirve
   cuando la carta del cliente todavía no está cotejada — enseñar el platillo
   sin inventarle precio. Con `:has()` la regla se aplica sola y degrada a lo
   que había en un navegador que no lo soporte (INVARIANTE 7). */
.jos-menu__row:not(:has(.jos-menu__price)) .jos-menu__dots { display: none; }
.jos-menu__price { font-family: var(--jos-display); font-weight: 600; color: var(--jos-accent2); white-space: nowrap; }
.jos-menu__desc { color: var(--jos-tenue); font-size: 14px; margin-top: 4px; max-width: 58ch; }
.jos-menu__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.jos-tag {
  font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase;
  border: 1px solid var(--jos-line); border-radius: 999px; padding: 3px 9px; color: var(--jos-tenue);
}
.jos-tag--86 { border-color: var(--jos-accent); color: var(--jos-accent); }

/* ── galería ──────────────────────────────────────────────────── */
.jos-gallery { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
.jos-gallery__fig { margin: 0; overflow: hidden; border-radius: var(--jos-radius); }
.jos-gallery__img { width: 100%; height: 100%; aspect-ratio: 4 / 3; object-fit: cover; transition: transform .3s; }
.jos-gallery__fig:hover .jos-gallery__img { transform: scale(1.04); }
/* La imagen que SÍ lleva a algún lado tiene que parecerlo antes del clic: el zoom
   del :hover no existe en un teléfono, así que la pista permanente es el borde,
   que se enciende al acento. `display: block` evita la línea base que le deja al
   <a> tres píxeles de hueco bajo la figura. */
.jos-gallery__a { display: block; border-radius: var(--jos-radius); border: 1px solid var(--jos-line); transition: border-color .2s; }
.jos-gallery__a:hover, .jos-gallery__a:focus-visible { border-color: var(--jos-accent); }
.jos-gallery__hueco {
  display: grid; place-items: center; aspect-ratio: 4 / 3; color: var(--jos-tenue);
  background: var(--jos-panel); border: 1px solid var(--jos-line); border-radius: var(--jos-radius); font-size: 13px;
}

/* ── horarios y datos ─────────────────────────────────────────── */
.jos-hours { display: grid; grid-template-columns: auto 1fr; gap: 0; max-width: 460px; }
.jos-hours__d, .jos-hours__h { padding: 12px 0; border-bottom: 1px solid var(--jos-line); }
.jos-hours__d { font-family: var(--jos-ui); text-transform: uppercase; letter-spacing: .08em; font-size: 13px; color: var(--jos-tenue); }
.jos-hours__h { margin: 0; text-align: right; }
.jos-rows { max-width: 560px; }
.jos-rows__row { display: flex; gap: 14px; padding: 14px 0; border-bottom: 1px solid var(--jos-line); }
.jos-rows__k {
  font-family: var(--jos-ui); text-transform: uppercase; letter-spacing: .1em;
  font-size: 12px; color: var(--jos-tenue); flex: 0 0 96px; padding-top: 3px;
}
.jos-rows__link { color: var(--jos-accent2); }
.jos-rows__link:hover { text-decoration: underline; }
.jos-map {
  width: 100%; min-height: 300px; margin-top: 24px; border: 1px solid var(--jos-line);
  border-radius: var(--jos-radius); filter: grayscale(1) invert(.92) contrast(.9);
}

/* ── testimonios ──────────────────────────────────────────────── */
.jos-quote__text { margin: 0 0 12px; font-style: italic; font-size: 16px; }
.jos-quote__author { font-family: var(--jos-ui); text-transform: uppercase; letter-spacing: .08em; font-size: 12px; color: var(--jos-accent2); }

/* ── franja de acción ─────────────────────────────────────────── */
/* Ya no necesita `max-width: none` para ir a sangre: desde que .jos-b se mide por
   padding, todos los bloques van a sangre y la franja sólo aporta su superficie. */
.jos-b--cta-band {
  text-align: center; background: var(--jos-panel);
  border-top: 1px solid var(--jos-line); border-bottom: 1px solid var(--jos-line);
}
/* El `auto` de los márgenes es lo que centra LA CAJA; el text-align sólo centra el
   texto dentro de ella. Ahí estaba el descuadre: el reset le anulaba el margen al
   .jos-band__desc, así que su caja de 54ch se quedaba pegada al borde izquierdo con
   el renglón pulcramente centrado dentro — centrado respecto a nada. */
.jos-band__title { font-weight: 700; text-transform: uppercase; font-size: clamp(22px, 5vw, 32px); }
.jos-band__desc { color: var(--jos-tenue); margin: 12px auto 22px; max-width: 54ch; text-align: center; }

/* ── formulario ───────────────────────────────────────────────── */
.jos-form { display: grid; gap: 14px; max-width: 520px; }
.jos-form[data-layout]{max-width:none;grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
.jos-field { display: grid; gap: 6px; }
.jos-field__label { font-family: var(--jos-ui); text-transform: uppercase; letter-spacing: .1em; font-size: 11.5px; color: var(--jos-tenue); }
.jos-input {
  width: 100%; font: inherit; font-size: 16px; color: var(--jos-ink);
  background: var(--jos-panel); border: 1px solid var(--jos-line);
  border-radius: calc(var(--jos-radius) / 2); padding: 12px 13px;
}
.jos-input:focus { border-color: var(--jos-accent2); outline: none; }
textarea.jos-input { resize: vertical; min-height: 96px; }
.jos-form__note { min-height: 20px; font-size: 14px; color: var(--jos-tenue); }
.jos-form__note.is-ok { color: var(--jos-accent2); }
.jos-form__note.is-err { color: var(--jos-accent); }

/* ── canales de reparto ───────────────────────────────────────── */
.jos-canales { display: grid; grid-template-columns: 1fr; gap: 12px; }
.jos-canal {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 18px 20px; background: var(--jos-panel); border: 1px solid var(--jos-line);
  border-radius: var(--jos-radius); font-family: var(--jos-ui);
  text-transform: uppercase; letter-spacing: .06em; font-size: 15px; transition: border-color .15s;
}
.jos-canal:hover { border-color: var(--jos-accent2); }
.jos-canal__go { color: var(--jos-accent2); font-size: 12px; letter-spacing: .1em; }

/* ── precios ──────────────────────────────────────────────────── */
.jos-plan { display: flex; flex-direction: column; text-align: center; }
.jos-plan__name { font-family: var(--jos-ui); text-transform: uppercase; letter-spacing: .06em; font-size: 17px; }
.jos-plan__price { font-family: var(--jos-display); font-size: 34px; font-weight: 700; color: var(--jos-accent2); margin: 14px 0; }
.jos-plan__per { font-size: 13px; font-weight: 400; color: var(--jos-tenue); margin-left: 4px; }
.jos-plan__feats { list-style: none; padding: 0; margin: 0 0 20px; text-align: left; flex: 1; }
.jos-plan__feats li { padding: 9px 0; border-bottom: 1px solid var(--jos-line); font-size: 14.5px; color: var(--jos-tenue); }

/* ── preguntas ────────────────────────────────────────────────── */
.jos-faq { display: grid; gap: 0; max-width: 760px; }
.jos-faq__item { border-bottom: 1px solid var(--jos-line); padding: 4px 0; }
.jos-faq__q {
  cursor: pointer; padding: 15px 0; font-family: var(--jos-ui);
  font-size: 16px; letter-spacing: .02em; list-style: none;
}
.jos-faq__q::marker, .jos-faq__q::-webkit-details-marker { display: none; content: ""; }
.jos-faq__q::after { content: "+"; float: right; color: var(--jos-accent2); }
.jos-faq__item[open] .jos-faq__q::after { content: "−"; }
.jos-faq__a { color: var(--jos-tenue); padding: 0 0 16px; font-size: 15px; max-width: 62ch; }

/* ── números ──────────────────────────────────────────────────── */
.jos-stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px; background: var(--jos-line); border: 1px solid var(--jos-line); border-radius: var(--jos-radius); overflow: hidden; }
/* --jos-surface y no --jos-bg: la rejilla de números es opaca (el borde de 1px son
   los huecos del grid), así que si el bloque cae en una sección alterna tiene que
   pintarse del color de ESA sección o se ve un parche del fondo base. */
.jos-stat { background: var(--jos-surface, var(--jos-bg)); padding: 22px 14px; text-align: center; }
/* EL ÚLTIMO ESTIRA SI SE QUEDÓ SOLO EN SU FILA. Un número que sobra no deja un
   espacio en blanco: la rejilla pinta `background: var(--jos-line)` y usa los 1px
   de `gap` como bordes, así que lo que ningún `.jos-stat` cubre se ve como un
   recuadro RELLENO del color de la línea. Con 3 números en dos columnas —un
   teléfono— eso era una celda muerta al lado de la última.
   `:nth-child(odd)` es la condición exacta en dos columnas: el último es impar si
   y sólo si abrió fila. Con 4 no aplica, y arriba de 720px se anula porque ahí la
   rejilla es auto-fit y da tantas columnas como números haya. */
.jos-stats > :last-child:nth-child(odd) { grid-column: 1 / -1; }
.jos-stat__v { display: block; font-family: var(--jos-display); font-size: 28px; font-weight: 700; color: var(--jos-accent2); line-height: 1; }
.jos-stat__l { display: block; font-size: 12.5px; color: var(--jos-tenue); margin-top: 7px; }

/* ── html crudo y avisos ──────────────────────────────────────── */
.jos-raw { max-width: 100%; overflow-x: auto; }
.jos-raw__escapado { overflow-x: auto; padding: 14px; background: var(--jos-panel); border-radius: var(--jos-radius); font-size: 13px; }
/* El aviso de bloque roto sí se queda en caja: ahora que .jos-b va a sangre, sin este
   max-width el recuadro punteado cruzaría la pantalla de borde a borde. */
.jos-b--unknown { border: 1px dashed var(--jos-accent); border-radius: var(--jos-radius); max-width: var(--jos-ancho); margin: 16px auto; padding: 22px; }
.jos-unknown__tag { display: block; font-family: var(--jos-ui); text-transform: uppercase; letter-spacing: .1em; font-size: 12px; color: var(--jos-accent); }
.jos-unknown__type { display: inline-block; margin-top: 8px; font-size: 15px; background: var(--jos-panel); border-radius: 4px; padding: 3px 8px; }
.jos-unknown__hint { color: var(--jos-tenue); font-size: 13.5px; margin-top: 8px; }

/* ── pie ──────────────────────────────────────────────────────── */
.jos-footer {
  border-top: 1px solid var(--jos-line); padding: 34px var(--jos-aire);
  color: var(--jos-tenue); font-size: 14px;
  display: flex; flex-wrap: wrap; gap: 14px; align-items: center;
  max-width: var(--jos-ancho); margin: 0 auto;
}
.jos-footer__links { display: flex; gap: 16px; flex-wrap: wrap; margin-left: auto; }
.jos-footer__link:hover { color: var(--jos-ink); }

/* ── de tableta hacia arriba ──────────────────────────────────── */
@media (min-width: 720px) {
  :root { --jos-aire: 28px; }
  .jos-nav { display: flex; }
  /* Aquí vivía `.jos-b { padding: 82px }`. Se fue al clamp() de --jos-aire-b: un salto
     de 52 a 82px en el píxel 720 era el origen de los huecos muertos, y de paso le
     ganaba por orden de fuente al padding propio del hero. El aire ahora es continuo. */
  .jos-grid { grid-template-columns: repeat(auto-fit, minmax(272px, 1fr)); }
  .jos-menu { grid-template-columns: 1fr 1fr; }
  .jos-gallery { grid-template-columns: repeat(3, 1fr); gap: 12px; }
  .jos-canales { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
  /* auto-fit y no repeat(4): la rejilla la decide el bloque, no el CSS. Con `repeat(4)`
     un `stats` de 3 números dejaba una celda vacía —un cuadro del color de la sección
     con un borde alrededor— y nadie podía arreglarlo sin tocar el motor. auto-fit
     colapsa las pistas sobrantes, así que 4 números siguen dando 4 columnas idénticas
     a las de antes (los 5 sitios de TAO) y 3 dan 3. */
  .jos-stats { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
  .jos-stats > :last-child:nth-child(odd) { grid-column: auto; }
  .jos-stat__v { font-size: 32px; }
}

@media (prefers-reduced-motion: reduce) {
  .jos-root * { transition: none !important; animation: none !important; }
}

/* ── hero con fotografía a sangre ─────────────────────────────────────
   `hero.backdrop` (SPEC §2) llega como --jos-hero-backdrop desde blocks.js.
   Va DETRÁS del degradado de marca, no en lugar de él: la foto da lugar y
   materia, el degradado sigue garantizando que el titular se lea. Sin ese
   velo, un hero sobre foto es una ruleta de contraste. */
.jos-b--hero[data-backdrop] {
  background-image: var(--jos-hero-backdrop);
  background-size: cover;
  background-position: center;
  min-height: min(78vh, 620px);
  display: flex; flex-direction: column; justify-content: center;
}
.jos-b--hero[data-backdrop]::before {
  background:
    linear-gradient(to bottom,
      color-mix(in srgb, var(--jos-bg) 78%, transparent) 0%,
      color-mix(in srgb, var(--jos-bg) 55%, transparent) 45%,
      color-mix(in srgb, var(--jos-bg) 92%, transparent) 100%),
    radial-gradient(900px 420px at 50% -8%, color-mix(in srgb, var(--jos-accent) 20%, transparent), transparent 70%);
}
/* El borde inferior duro delata el recorte. Se difumina hacia la sección que sigue. */
.jos-b--hero[data-backdrop]::after {
  content: ""; position: absolute; inset: auto 0 0 0; height: 96px; pointer-events: none;
  background: linear-gradient(to bottom, transparent, var(--jos-bg));
}

/* El velo de arriba se calculó pensando en marcas oscuras. En una marca clara
   (`--jos-bg` crema) el mismo color-mix LAVA la foto y deja el kicker de acento
   amarillo casi invisible sobre crema. El velo no puede ser uno solo: tiene que
   concentrarse donde de verdad va el texto, y dejar respirar el resto. */
.jos-b--hero[data-backdrop]::before {
  background:
    radial-gradient(120% 68% at 50% 52%,
      color-mix(in srgb, var(--jos-bg) 88%, transparent) 0%,
      color-mix(in srgb, var(--jos-bg) 62%, transparent) 42%,
      transparent 78%),
    linear-gradient(to bottom,
      color-mix(in srgb, var(--jos-bg) 62%, transparent) 0%,
      transparent 34%,
      color-mix(in srgb, var(--jos-bg) 88%, transparent) 100%);
}
/* Sobre foto, el kicker abandona el acento decorativo y usa la tinta de marca:
   un amarillo de acento sobre crema no alcanza contraste legible en ningún caso. */
.jos-b--hero[data-backdrop] .jos-hero__kicker { color: var(--jos-ink); opacity: .82; }
.jos-b--hero[data-backdrop] .jos-hero__sub { color: var(--jos-ink); opacity: .78; }

/* ── panel (SPEC §2) — el único bloque que depende de quién mira ──────────── */
.jos-panel__yo{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  padding:14px 16px;border:1px solid var(--jos-line);border-radius:var(--jos-radius);
  background:var(--jos-panel);margin-bottom:18px}
.jos-panel__foto{width:38px;height:38px;border-radius:50%;object-fit:cover}
.jos-panel__quien{display:flex;flex-direction:column;flex:1;min-width:160px}
.jos-panel__mail{font-size:12.5px;opacity:.6}
.jos-panel__etq{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;
  padding:3px 9px;border-radius:999px;border:1px solid var(--jos-line);opacity:.8;cursor:help}
.jos-panel__grupo{margin:22px 0}
.jos-panel__gt{font-size:13px;text-transform:uppercase;letter-spacing:.06em;opacity:.6;margin:0 0 10px}
.jos-panel__lista{display:grid;gap:10px}
.jos-panel__ficha{display:flex;gap:12px;align-items:center;flex-wrap:wrap;
  padding:14px 16px;border:1px solid var(--jos-line);border-radius:var(--jos-radius);background:var(--jos-panel)}
.jos-panel__txt{flex:1;min-width:170px;display:flex;flex-direction:column;gap:2px}
.jos-panel__sub{font-size:12.5px;opacity:.55;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
.jos-panel__chips{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px}
.jos-panel__chip{font-size:11.5px;padding:3px 8px;border-radius:7px;border:1px solid var(--jos-line);opacity:.75}
.jos-panel__acc{display:flex;gap:8px;flex-wrap:wrap}
.jos-panel__lnk{font-size:13px;padding:8px 13px;border-radius:9px;border:1px solid var(--jos-line);
  text-decoration:none;color:inherit;opacity:.8;display:inline-flex;align-items:center;min-height:38px}
.jos-panel__lnk:hover{opacity:1;border-color:var(--jos-accent)}
.jos-panel__vacio{opacity:.5;font-size:14px;border:1px dashed var(--jos-line);
  border-radius:var(--jos-radius);padding:18px;text-align:center;margin:0}
/* Un hueco NUNCA se ve como un vacío: vacío y «no te dejaron» significan lo contrario. */
.jos-panel__hueco{display:flex;flex-direction:column;gap:4px;padding:14px 16px;
  border:1px solid var(--jos-accent2);border-radius:var(--jos-radius);opacity:.95}
.jos-panel__err{font-size:12.5px;opacity:.7;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;word-break:break-word}
.jos-panel__puerta{text-align:center;padding:26px 18px;border:1px dashed var(--jos-line);border-radius:var(--jos-radius)}
.jos-panel__vt{margin:0 0 6px;font-size:20px}
.jos-panel__vb{margin:0 0 16px;opacity:.7}
@media(max-width:520px){
  .jos-panel__ficha{flex-direction:column;align-items:flex-start}
  .jos-panel__acc{width:100%}
  .jos-panel__lnk{flex:1;justify-content:center}
}
.jos-panel__salir{font-size:13px;padding:7px 13px;border-radius:9px;border:1px solid var(--jos-line);
  text-decoration:none;color:inherit;opacity:.7;min-height:36px;display:inline-flex;align-items:center}
.jos-panel__salir:hover{opacity:1}

/* ── chat (SPEC §2) — FOXTANA en la página ────────────────────────────────── */
.jos-chat{display:flex;flex-direction:column;gap:10px;border:1px solid var(--jos-line);
  border-radius:var(--jos-radius);background:var(--jos-panel);padding:14px}
.jos-chat__log{display:flex;flex-direction:column;gap:10px;max-height:46vh;overflow-y:auto;overflow-x:hidden}
.jos-chat__msg{padding:10px 13px;border-radius:12px;max-width:88%;font-size:14.5px;line-height:1.5}
.jos-chat__msg p{margin:0;white-space:pre-wrap}
.jos-chat__msg--fox{align-self:flex-start;border:1px solid var(--jos-line)}
.jos-chat__msg--yo{align-self:flex-end;background:var(--jos-accent);color:var(--jos-onAccent,#fff)}
/* Un error del proveedor se pinta ENTERO (INVARIANTE 3): tragarlo deja a quien
   pregunta sin saber si falló la red, el permiso o la llave. */
.jos-chat__msg--err{align-self:flex-start;border:1px solid var(--jos-accent2)}
.jos-chat__msg--err .jos-chat__crudo{display:block;margin-top:6px;font-size:12px;opacity:.75;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;word-break:break-word;white-space:pre-wrap}
.jos-chat__meta{font-size:11.5px;opacity:.5;margin-top:6px}
.jos-chat__sug{display:flex;gap:6px;flex-wrap:wrap}
.jos-chat__chip{font:inherit;font-size:12.5px;cursor:pointer;padding:6px 11px;border-radius:999px;
  border:1px solid var(--jos-line);background:none;color:inherit;opacity:.75;min-height:34px}
.jos-chat__chip:hover{opacity:1;border-color:var(--jos-accent)}
.jos-chat__fila{display:flex;gap:8px}
/* `min-width:0` NO es opcional: un <input> flexible conserva su ancho
   intrínseco (~180px) y en 390px empuja la fila fuera de la pantalla. Medido:
   scroll horizontal en los tres casos hasta poner esta línea. */
.jos-chat__input{flex:1;min-width:0;font:inherit;padding:11px 13px;border-radius:10px;min-height:44px;
  border:1px solid var(--jos-line);background:transparent;color:inherit}
.jos-chat__input:focus{outline:none;border-color:var(--jos-accent)}
.jos-chat__enviar{font:inherit;font-weight:600;cursor:pointer;padding:11px 16px;border-radius:10px;
  min-height:44px;border:1px solid var(--jos-accent);background:var(--jos-accent);color:var(--jos-onAccent,#fff)}
.jos-chat__enviar[disabled]{opacity:.5;cursor:default}
@media(max-width:520px){ .jos-chat__msg{max-width:94%} }

/* ── deliverables ─────────────────────────────────────────────────────
   Una entrega no es una reja de tarjetas: es una LISTA con destino. Cada
   renglón lleva su enlace a la derecha y su estado como etiqueta, y por eso
   reusa `.jos-tag` en vez de inventar otra pastilla. El separador punteado es
   el mismo de `.jos-menu__item`: las dos son listas de cosas enumeradas. */
.jos-entregables { margin-top: 18px; }
.jos-entregable {
  display: grid; grid-template-columns: 1fr auto; gap: 4px 16px; align-items: center;
  padding: 15px 0; border-bottom: 1px dashed var(--jos-line);
}
.jos-entregable__n { font-family: var(--jos-ui); font-weight: 500; font-size: 16.5px; letter-spacing: .02em; }
.jos-entregable__d { grid-column: 1; color: var(--jos-tenue); font-size: 14px; max-width: 58ch; }
.jos-entregable .jos-tag { grid-column: 1; justify-self: start; margin-top: 4px; }
.jos-entregable__a {
  grid-row: 1 / span 3; grid-column: 2; align-self: center;
  font-family: var(--jos-ui); text-transform: uppercase; letter-spacing: .08em;
  font-size: 12px; font-weight: 600; color: var(--jos-accent2); white-space: nowrap;
}
.jos-entregable__a:hover { color: var(--jos-ink); }

/* ── tienda: la ficha `catalogo` (SPEC §2). Sello, versión, chips y botón
   usan .jos-plan__price, .jos-plan__per, .jos-tag, .jos-btn. */
.jos-ficha { padding: 0; overflow: hidden; }
.jos-ficha__portada { display: grid; place-items: center; aspect-ratio: 16 / 9; border-bottom: 1px solid var(--jos-line); background: linear-gradient(140deg, color-mix(in srgb, var(--jos-accent) 26%, transparent), var(--jos-panel)); }
.jos-ficha__foto { width: 100%; height: 100%; object-fit: cover; }
.jos-ficha__cuerpo { display: grid; gap: 8px; padding: 20px 22px 22px; }
.jos-ficha__h { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.jos-ficha__k { font-family: var(--jos-ui); font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--jos-accent2); margin-top: 6px; }
.jos-ficha__l { list-style: none; padding: 0; margin: 0; display: grid; gap: 5px; font-size: 13.5px; color: var(--jos-tenue); }
.jos-ficha__l--chips { display: flex; flex-wrap: wrap; }
.jos-ficha__l--cmd li { font-family: ui-monospace, monospace; font-size: 12.5px; overflow-wrap: anywhere; }

/* ── QUIÉN ERES, EN LA CABECERA ────────────────────────────────────────────
   `shell.sesion` (SPEC §1). Vivía dentro del área de trabajo, entre las cosas
   que la persona viene a hacer; el correo y «Salir» no son una tarea, son el
   estado de la ventana. Arriba se ven siempre y no ocupan el sitio del trabajo. */
.jos-yo { display: flex; align-items: center; gap: 9px; margin-left: 12px; }
.jos-yo__foto { width: 26px; height: 26px; border-radius: 50%; object-fit: cover; }
.jos-yo__mail {
  font-family: var(--jos-ui); font-size: 12.5px; color: var(--jos-tenue);
  max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.jos-yo__salir {
  font-family: var(--jos-ui); font-size: 12px; text-transform: uppercase;
  letter-spacing: .07em; color: var(--jos-tenue); padding: 6px 10px;
  border: 1px solid var(--jos-line); border-radius: 8px; transition: color .15s, border-color .15s;
}
.jos-yo__salir:hover { color: var(--jos-ink); border-color: var(--jos-accent); }

/* EL DORADO ES DATO, NO ADORNO: marca la sesión que puede TODO, en todos los
   nodos. Se declara aquí y no en la marca del documento porque no es identidad
   del sitio — es un estado de quien mira, y tiene que verse igual en cualquier
   documento que use `shell.sesion`. Contra el fondo oscuro da 8.9:1. */
.jos-yo--master { --oro: #e6c15a; }
.jos-yo--master .jos-yo__mail { color: var(--oro); font-weight: 600; }
.jos-yo--master .jos-yo__foto { box-shadow: 0 0 0 2px var(--oro); }
.jos-yo--master .jos-yo__salir { border-color: color-mix(in srgb, var(--oro) 45%, transparent); }
.jos-yo--master .jos-yo__salir:hover { color: var(--oro); border-color: var(--oro); }

/* En el teléfono el correo SE QUEDA: la cabecera sólo lleva la marca y «Salir»,
   así que hay sitio, y saber con qué cuenta estás es justo lo que se pregunta en
   un móvil, donde las sesiones se mezclan más. Se estrecha y se trunca por el
   PRINCIPIO —`direction: rtl`— porque lo que distingue dos cuentas es el dominio,
   no las primeras letras: `jos@…` y `jose@…` truncados por el final se ven igual.
   Debajo de 380px sí se va: ahí el rótulo de «Salir» ya no cabe al lado. */
@media (max-width: 719px) {
  .jos-yo { margin-left: auto; gap: 7px; }
  .jos-yo__mail { max-width: 15ch; direction: rtl; text-align: right; font-size: 11.5px; }
  .jos-yo__salir { padding: 6px 8px; }
}
@media (max-width: 379px) { .jos-yo__mail { display: none; } }

/* ── LAS PUERTAS COMO TARJETAS ─────────────────────────────────────────────
   Eran una fila de enlaces chiquitos con el aspecto de una nota al pie, debajo
   de tres párrafos de texto. Lo que la persona viene a hacer —crear un sitio,
   abrir su galería— tiene que ser lo más grande de la pantalla, no lo más
   pequeño. La rejilla es auto-fit: la decide cuántas puertas abran tus permisos,
   no un número escrito en el CSS. */
.jos-panel__acc--puertas { display: grid; grid-template-columns: 1fr; gap: 10px; }
@media (min-width: 720px) {
  .jos-panel__acc--puertas { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
}
.jos-panel__acc--puertas .jos-panel__lnk {
  display: block; padding: 18px 16px; border-radius: var(--jos-radius);
  background: var(--jos-panel); opacity: 1; font-size: 15px; text-align: left;
}
.jos-panel__acc--puertas .jos-panel__lnk:hover { border-color: var(--jos-accent); }
.jos-puerta__t { display: block; font-family: var(--jos-ui); font-weight: 600; letter-spacing: .01em; }
.jos-puerta__d { display: block; margin-top: 5px; font-size: 13px; color: var(--jos-tenue); line-height: 1.45; }

/* ── FOXTANA COMO CAJÓN INFERIOR — `chat.position: "drawer"` ───────────────
   En un teléfono el chat inline queda al final de la página, y lo que está al
   final es lo que nadie usa: para preguntarle algo había que bajar hasta el
   fondo. Como cajón está siempre a un dedo del pulgar.

   Es un `<details>`: el estado de abierto lo lleva el navegador, sobrevive a que
   el motor repinte, y trae teclado y lector de pantalla sin ARIA escrito a mano. */
.jos-b--chat[data-pos="drawer"] { padding: 0; }
.jos-drawer {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  background: color-mix(in srgb, var(--jos-bg) 94%, transparent);
  backdrop-filter: blur(16px);
  border-top: 1px solid color-mix(in srgb, var(--jos-oro, #e6c15a) 30%, transparent);
}
.jos-drawer__tira {
  display: flex; align-items: center; gap: 10px; cursor: pointer; list-style: none;
  padding: 14px var(--jos-aire); padding-bottom: calc(14px + env(safe-area-inset-bottom));
  font-family: var(--jos-ui);
}
.jos-drawer__tira::-webkit-details-marker { display: none; }
/* El oro es de FOXTANA y no de la marca del documento: es la misma agente en
   todos los sitios, y cambiar su color por cliente la volvería otra cosa. */
.jos-drawer__marca {
  font-weight: 700; letter-spacing: .1em; text-transform: uppercase; font-size: 13px;
  color: var(--jos-oro, #e6c15a);
}
.jos-drawer__pista { font-size: 13px; color: var(--jos-tenue); }
/* La flecha gira al abrir. Es la única pista de que la tira es un control. */
.jos-drawer__tira::after {
  content: "▲"; margin-left: auto; font-size: 10px; color: var(--jos-tenue);
  transition: transform .2s;
}
.jos-drawer[open] .jos-drawer__tira::after { transform: rotate(180deg); }
.jos-drawer__cuerpo {
  padding: 0 var(--jos-aire) calc(16px + env(safe-area-inset-bottom));
  max-height: 70vh; overflow-y: auto;
}
.jos-drawer[open] .jos-drawer__tira { padding-bottom: 10px; }
/* El cajón tapa el pie: se le devuelve el aire por debajo para que el último
   bloque no quede escondido detrás. */
.jos-root:has(.jos-drawer) .jos-footer { padding-bottom: 90px; }

/* DE TABLETA HACIA ARRIBA el cajón no hace falta —hay sitio de sobra— pero se
   queda anclado abajo a la derecha, como una ficha, en vez de cruzar la pantalla
   entera: una barra de borde a borde en un escritorio es un banner. */
@media (min-width: 720px) {
  .jos-drawer {
    left: auto; right: 24px; bottom: 24px; width: min(420px, calc(100vw - 48px));
    border: 1px solid color-mix(in srgb, var(--jos-oro, #e6c15a) 30%, transparent);
    border-radius: var(--jos-radius); overflow: hidden;
  }
  .jos-root:has(.jos-drawer) .jos-footer { padding-bottom: 34px; }
}

/* La versión desplegada, en el pie. Discreta a propósito: es un dato de
   diagnóstico, no una firma. Sale de `/version.json`, que sella el despliegue —
   si el archivo no está, este elemento no existe y no hay hueco visible. */
.jos-footer__ver {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px; color: var(--jos-tenue); opacity: .6;
  margin-left: 14px; letter-spacing: .02em;
}
