/* ==============================
   PANEL DEL EQUIPO DE ARTE — css/arte.css
   ==============================
   Usa las variables de css/inicio.css, que es donde vive el sistema de
   colores del sitio. Nada de colores sueltos acá. */

.arte-main {
  max-width: 1100px;
  margin: 0 auto;
  padding: 28px 20px 80px;
  font-family: var(--font-body);
  color: var(--texto, #e8edf2);
}

.arte-cabecera { margin-bottom: 28px; }

.arte-cabecera h1 {
  font-family: var(--font-display);
  font-size: clamp(24px, 4vw, 34px);
  margin: 0 0 8px;
}

.arte-cabecera p {
  margin: 0;
  opacity: .78;
  max-width: 62ch;
  line-height: 1.55;
}

/* ---------- aviso de acceso ---------- */

.arte-aviso {
  background: var(--bg-panel);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  padding: 20px 22px;
  margin: 24px 0;
}
.arte-aviso.malo { border-left-color: var(--danger); }
.arte-aviso h2 { margin: 0 0 8px; font-size: 18px; font-family: var(--font-display); }
.arte-aviso p { margin: 0 0 6px; opacity: .8; line-height: 1.55; }

/* ---------- secciones ---------- */

.arte-seccion {
  background: var(--bg-panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 22px;
  margin-bottom: 24px;
}

.arte-seccion > h2 {
  font-family: var(--font-display);
  font-size: 19px;
  margin: 0 0 6px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.arte-seccion > .arte-ayuda {
  margin: 0 0 18px;
  opacity: .72;
  font-size: 14px;
  line-height: 1.55;
  max-width: 68ch;
}

/* ---------- controles ---------- */

.arte-campo { display: flex; flex-direction: column; gap: 5px; }

/* Los textos apagados de Arte y del Taller llevan el color apagado del tema,
   no una opacidad, que los dejaba por debajo de 4,5:1 (de 2,32:1 a 4,39:1 en
   el claro; punto 124, specs/047-contraste-segunda-pasada). Los botones que
   no se pueden usar (:disabled) siguen apagados con su opacidad. */
.arte-campo label {
  font-size: 11.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.arte-main select,
.arte-main input[type="text"],
.arte-main input[type="number"] {
  background: var(--control-bg);
  border: 1px solid var(--control-border);
  color: inherit;
  border-radius: 6px;
  padding: 7px 9px;
  font-family: inherit;
  font-size: 14px;
  min-width: 0;
  width: 100%;
}

.arte-main select:focus-visible,
.arte-main input:focus-visible,
.arte-main button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.arte-main input[type="file"] {
  color: inherit;
  font-family: inherit;
  font-size: 14px;
}

/* ---------- "aplicar a todas" ---------- */

.arte-comunes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  align-items: end;
  background: var(--bg-panel-alt, rgba(255,255,255,.03));
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 14px;
  margin: 16px 0;
}

/* ---------- filas de subida ---------- */

.arte-fila {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: 14px;
  padding: 14px 0;
  border-top: 1px solid var(--line);
  align-items: start;
}

.arte-fila-datos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}

.arte-fila-nombrearchivo {
  grid-column: 1 / -1;
  font-size: 12.5px;
  opacity: .65;
  word-break: break-all;
  display: flex;
  justify-content: space-between;
  gap: 12px;
  align-items: baseline;
}

.arte-quitar {
  background: none;
  border: 0;
  color: var(--danger);
  cursor: pointer;
  font-size: 12.5px;
  padding: 0;
  flex: none;
}

/* ---------- previsualización sobre el personaje ---------- */

.arte-vista {
  position: relative;
  width: 96px;
  aspect-ratio: 327 / 504;
  background: var(--control-bg);
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
  flex: none;
}

/* Apoyado abajo, como el marco que compone el servidor
   (specs/010-personajes-oficiales, research D10): un personaje de otra forma
   pisa el suelo y deja vacío lo de arriba. Lo de 327x504 lo llena entero, y
   para eso da igual. */
.arte-vista img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: 50% 100%;
}

.arte-medidas { font-size: 11px; color: var(--text-muted); margin-top: 4px; text-align: center; }
.arte-medidas.ojo { color: var(--gold); opacity: 1; }

/* ---------- resultados ---------- */

.arte-resultados { margin-top: 18px; display: grid; gap: 6px; }

.arte-resultado {
  display: flex;
  gap: 10px;
  align-items: baseline;
  font-size: 13.5px;
  padding: 8px 10px;
  border-radius: 6px;
  background: var(--control-bg);
  border-left: 3px solid var(--green);
}
.arte-resultado.malo { border-left-color: var(--danger); }
.arte-resultado .que { opacity: .65; word-break: break-all; }
.arte-resultado .dice { margin-left: auto; text-align: right; }

/* ---------- catálogo ---------- */

.arte-filtros {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
  margin-bottom: 18px;
}

.arte-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 14px;
}

/* La ficha de un personaje (.arte-personaje) se ve como la tarjeta de una
   prenda, pero con su propia clase: las tarjetas del catálogo se cuentan,
   y un personaje no es una prenda. */
.arte-tarjeta,
.arte-personaje {
  background: var(--control-bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Una prenda retirada se apaga en su dibujo, no en sus textos ni en sus
   botones, que se siguen usando. */
.arte-tarjeta.retirada { border-style: dashed; }
.arte-tarjeta.retirada .arte-vista { opacity: .58; }
.arte-personaje.escondido { border-style: dashed; }

.arte-tarjeta .arte-vista,
.arte-personaje .arte-vista { width: 100%; }

.arte-tarjeta .nom,
.arte-personaje .nom {
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.3;
  word-break: break-word;
}

.arte-tarjeta .meta,
.arte-personaje .meta { font-size: 11.5px; color: var(--text-muted); line-height: 1.45; }

.arte-etiqueta {
  display: inline-block;
  font-size: 10.5px;
  letter-spacing: .05em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 4px;
  background: var(--chip-bg);
}
.arte-etiqueta.precio { color: var(--gold); }
/* Un personaje en adelanto: llega pronto, pero todavía no se ve (spec 010). */
.arte-etiqueta.adelanto { color: var(--accent-color); }
/* La rareza, con el color de su marco en el Bazar (css/bazar.css). */
.arte-etiqueta.rareza-comun { color: #a3a7b0; }
.arte-etiqueta.rareza-rara { color: #5598e7; }
.arte-etiqueta.rareza-epica { color: #a78bfa; }
.arte-etiqueta.rareza-legendaria { color: #f0a92e; }
.arte-etiqueta.apagada { color: var(--danger); }
/* En el claro, los mismos colores, más oscuros: sobre las pastillas claras se
   quedaban entre 2:1 y 3:1 (punto 116; specs/047-contraste-segunda-pasada). */
html[data-tema="claro"] .arte-etiqueta.rareza-comun { color: #5b6170; }
html[data-tema="claro"] .arte-etiqueta.rareza-rara { color: #1d5fb8; }
html[data-tema="claro"] .arte-etiqueta.rareza-epica { color: #6d28d9; }
html[data-tema="claro"] .arte-etiqueta.rareza-legendaria { color: #8a5a09; }
/* «Sin precio», con el rojo del claro un paso más oscuro: el de --danger, sobre
   la pastilla de la paleta Clásica, se quedaba en 4,34:1 (punto 227;
   specs/076-sin-precio-en-el-claro). */
html[data-tema="claro"] .arte-etiqueta.apagada { color: #b91c1c; }

/* Los botones de un personaje (Publicar, Esconder), los mismos que los de
   una prenda: sin esto salían con el estilo del navegador, blancos en el
   tema oscuro. */
.arte-tarjeta button,
.arte-personaje button {
  background: var(--control-bg);
  border: 1px solid var(--control-border);
  color: inherit;
  border-radius: 6px;
  padding: 6px;
  font-family: inherit;
  font-size: 12.5px;
  cursor: pointer;
  margin-top: auto;
}
.arte-tarjeta button:hover,
.arte-personaje button:hover { background: var(--control-hover); }
.arte-tarjeta button[disabled],
.arte-personaje button[disabled] { opacity: .45; cursor: default; }

/* Editar y Retirar, lado a lado, al pie de la tarjeta. */
.arte-tarjeta-acciones { display: flex; gap: 6px; margin-top: auto; }
.arte-tarjeta-acciones[hidden] { display: none; }
.arte-tarjeta-acciones button { flex: 1; margin-top: 0; }
.arte-tarjeta button.primario,
.arte-personaje button.primario { border-color: var(--gold); color: var(--gold); }

/* El formulario de editar, dentro de la propia tarjeta; y el de la hora de
   un personaje, dentro de su ficha (spec 010, research D15). */
.arte-edicion,
.arte-programar { display: flex; flex-direction: column; gap: 8px; margin-top: auto; }
.arte-edicion input,
.arte-programar input { width: 100%; box-sizing: border-box; }
.arte-programar .arte-tarjeta-acciones { flex-wrap: wrap; }
/* Las filas de botones de un personaje (sus estados, Marcar la cara,
   Programar, Borrar y su orden) bajan de línea en una ficha estrecha, en
   vez de salirse de ella; cada herramienta, del ancho de su texto. */
.arte-personaje .arte-tarjeta-acciones { flex-wrap: wrap; }
.arte-personaje-herramientas button { flex: 1 1 auto; }
/* Juntas al pie de la ficha: solo la primera fila empuja hacia abajo; si
   no, el hueco de una ficha más corta se reparte entre ellas. */
.arte-personaje .arte-tarjeta-acciones + .arte-tarjeta-acciones { margin-top: 0; }
.arte-edicion-error { margin: 0; font-size: 12px; color: var(--danger); }

/* ---------- personajes (specs/010-personajes-oficiales) ---------- */

/* La lista reutiliza la rejilla y las tarjetas del catálogo; un escondido
   se ve como lo retirado. El formulario de crear va debajo, en columna,
   y en el móvil ocupa el ancho entero. */
.arte-crear-personaje {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  display: grid;
  /* Una columna que puede encoger: el selector de archivo pide de por sí
     unos 360 px, y en el móvil estiraba el formulario fuera del panel. */
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
  max-width: 420px;
}

.arte-crear-personaje h3 {
  font-family: var(--font-display);
  font-size: 15px;
  margin: 0;
}

.arte-crear-personaje .arte-ayuda { margin: 0; font-size: 13px; opacity: .72; }
.arte-crear-personaje input[type="file"] { max-width: 100%; }
.arte-crear-personaje button { justify-self: start; }

/* El cuerpo elegido, en su marco de 327x504, antes de crearlo. El marco es
   una caja con la forma de 327x504 y el dibujo dentro, en porcentajes que
   pone js/arte.js con la cuenta del servidor. El cuadriculado deja ver lo
   que queda vacío. */
.arte-crear-vista { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; }
.arte-crear-vista[hidden] { display: none; }
.arte-crear-vista .arte-ayuda { flex: 1 1 180px; }

.arte-marco {
  position: relative;
  width: 163px;
  aspect-ratio: 327 / 504;
  flex: none;
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
  background-color: var(--control-bg);
  background-image:
    linear-gradient(45deg, var(--line) 25%, transparent 25%, transparent 75%, var(--line) 75%),
    linear-gradient(45deg, var(--line) 25%, transparent 25%, transparent 75%, var(--line) 75%);
  background-size: 16px 16px;
  background-position: 0 0, 8px 8px;
}

.arte-marco img { position: absolute; display: block; }

/* ---------- la cara de un personaje nuevo (spec 010, research D13) ---------- */

.arte-cara-editor {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  display: grid;
  /* Una columna que puede ser más estrecha que el marco: si no, la rejilla
     se estira a sus 327 px y en el móvil el marco se sale del panel. */
  grid-template-columns: minmax(0, 1fr);
  gap: 10px;
}
.arte-cara-editor[hidden] { display: none; }
.arte-cara-editor h3 { font-family: var(--font-display); font-size: 15px; margin: 0; }
.arte-cara-editor .arte-ayuda { margin: 0; font-size: 13px; opacity: .72; max-width: 60ch; }

.arte-cara-trabajo { display: flex; gap: 18px; flex-wrap: wrap; align-items: flex-start; }

/* El marco a su tamaño de verdad, 327x504, salvo que no quepa: en el móvil
   se encoge con la pantalla, y la cuenta de arrastrar lo tiene en cuenta. */
.arte-cara-marco { width: 327px; max-width: 100%; touch-action: none; }

.arte-cara-cuadro {
  position: absolute;
  box-sizing: border-box;
  border: 2px solid var(--accent);
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, .35);
  cursor: grab;
  touch-action: none;
}
.arte-cara-cuadro:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.arte-cara-cuadro.arrastrando { cursor: grabbing; }

.arte-cara-mandos { display: grid; gap: 10px; flex: 1 1 200px; max-width: 320px; }

/* La foto como saldrá: 96x96, el tamaño de la de verdad. */
.arte-cara-foto {
  position: relative;
  width: 96px;
  height: 96px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
}
.arte-cara-foto img { position: absolute; display: block; max-width: none; }

.arte-cara-numeros { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.arte-cara-numeros input { width: 100%; box-sizing: border-box; }
.arte-cara-mandos input[type="range"] { width: 100%; margin: 0; }
.arte-cara-botones { display: flex; gap: 8px; flex-wrap: wrap; }

/* ---------- la galería de un personaje nuevo (spec 013) ---------- */

/* Como el editor de la cara: debajo de la lista, en una columna que puede
   encoger, y en el PC la imagen y la historia lado a lado. */
.arte-galeria-editor {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 10px;
}
.arte-galeria-editor[hidden] { display: none; }
.arte-galeria-editor h3 { font-family: var(--font-display); font-size: 15px; margin: 0; }
.arte-galeria-editor .arte-ayuda { margin: 0; font-size: 13px; opacity: .72; max-width: 60ch; }
.arte-galeria-editor input[type="file"] { max-width: 100%; }

.arte-galeria-trabajo { display: flex; gap: 18px; flex-wrap: wrap; align-items: flex-start; }
/* Sus rejillas, de una columna que puede encoger: si no, se estiran al
   selector de archivo, y en el móvil la imagen y su ayuda se salen del panel
   (lo mismo que arregló bc8184f en el formulario de crear). */
.arte-galeria-imagen { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; flex: 1 1 240px; max-width: 340px; min-width: 0; }
.arte-galeria-texto { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; flex: 2 1 320px; min-width: 0; }

/* La imagen sobre blanco, como sale en la galería: un JPG aplanado. */
.arte-galeria-vista {
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  background: #fff;
  max-width: 100%;
}
.arte-galeria-vista[hidden] { display: none; }
.arte-galeria-vista img { display: block; width: 100%; height: auto; }

.arte-galeria-texto textarea {
  width: 100%;
  box-sizing: border-box;
  min-height: 220px;
  resize: vertical;
  font: inherit;
  line-height: 1.5;
}

/* «Así se lee»: los párrafos como en la galería, con sus saltos sueltos, y
   sin salirse aunque lleve una palabra larguísima. */
.arte-galeria-lectura {
  max-height: 260px;
  overflow: auto;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--control-bg);
  font-size: 14px;
  line-height: 1.6;
}
.arte-galeria-lectura p { margin: 0 0 10px; white-space: pre-line; overflow-wrap: anywhere; }
.arte-galeria-lectura p:last-child { margin-bottom: 0; }
.arte-galeria-lectura .arte-galeria-sin { color: var(--text-muted); font-style: italic; }

.arte-galeria-botones { display: flex; gap: 8px; flex-wrap: wrap; }
.arte-personaje-galeria button { flex: 1 1 auto; }

.arte-vacio { color: var(--text-muted); padding: 20px 0; }

.arte-contador { font-size: 12.5px; color: var(--text-muted); font-weight: 400; }

@media (max-width: 560px) {
  .arte-fila { grid-template-columns: 72px 1fr; }
  .arte-vista { width: 72px; }
}

/* El personaje y la ranura a los que va a parar cada archivo. Va
   destacado porque equivocarse acá archiva el dibujo donde nadie lo
   busca: el editor solo enseña la ropa del personaje que uno lleva
   puesto, así que una prenda en el personaje equivocado es invisible. */
.arte-destino {
  color: var(--accent-color);
  font-weight: 600;
}

/* ==============================
   EL VESTIDOR
   ==============================
   El maniquí donde se prueban las prendas antes de publicarlas.
   Mismas variables que el resto del panel: nada de colores sueltos. */

.vest-barra {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  flex-wrap: wrap;
  padding: 12px 0 14px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  background: var(--bg-panel);
  z-index: 2;
}

.vest-barra .arte-campo { max-width: 180px; }
.vest-derecha { margin-left: auto; }

.vest-grupo {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

/* Los interruptores son botones con aria-pressed y NO casillas: la regla
   de los controles de arriba lleva width:100% y padding 7px 9px, y un
   input[type=checkbox] ahí sale como una caja deforme del ancho de la
   columna. Las pocas casillas que hay llevan su propia regla, más abajo. */
.vest-tecla {
  background: var(--control-bg);
  border: 1px solid var(--control-border);
  color: inherit;
  border-radius: 6px;
  padding: 6px 10px;
  font-family: inherit;
  font-size: 13px;
  cursor: pointer;
}
.vest-tecla:hover:not(:disabled) { background: var(--control-hover); }
.vest-tecla:disabled { opacity: .45; cursor: default; }
.vest-tecla[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--chip-bg);
}

.vest-dato {
  font-size: 12.5px;
  opacity: .75;
  margin: 6px 0 0;
  font-variant-numeric: tabular-nums;
}

.vest-titulo {
  font-family: var(--font-display);
  font-size: 13px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0 0 10px;
}

.vest-vacio {
  font-size: 13px;
  color: var(--text-muted);
  line-height: 1.5;
  margin: 0;
}

/* ---------- la disposición ---------- */

.vest-panel {
  display: grid;
  /* minmax(0, ...) y no 290px a secas: una pista de rejilla tiene por
     mínimo automático el min-content de lo que lleva, así que un
     <select> ancho o un dibujo a escala la empujaban y la columna se
     salía. Con el 0 delante, manda la columna y no su contenido. */
  grid-template-columns: minmax(0, 290px) minmax(0, 1fr) minmax(0, 320px);
  gap: 18px;
  align-items: start;
}

/* El overflow-x va DICHO. Si se deja en visible mientras el otro eje
   es auto, el CSS lo convierte en auto por su cuenta y aparece la barra
   horizontal en cuanto algo sobresale un píxel. Acá abajo, además, se
   arregla lo que sobresalía; esto es la red. */
.vest-rail {
  min-width: 0;
  max-height: 72vh;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-gutter: stable;
  padding-right: 4px;
}

.vest-escena {
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Un solo punto de quiebre para tableta y móvil: se apila, el escenario
   sube al principio y los raíles dejan de tener scroll propio. */
@media (max-width: 1180px) {
  .vest-panel { grid-template-columns: 1fr; }
  .vest-rail { max-height: none; overflow: visible; }
  .vest-escena { order: -1; }
}

/* ---------- el escenario ---------- */

.vest-marco {
  width: calc(327px * var(--vest-zoom, 1));
  height: calc(504px * var(--vest-zoom, 1));
  flex-shrink: 0;
}

/* LA CAJA CLAVADA. 327x504 px de CSS, sin aspect-ratio y sin porcentajes:
   dentro de acá, un píxel de CSS es un píxel del PNG que se va a subir, y
   pasar de coordenadas del ratón a píxeles del dibujo es dividir por el
   zoom y nada más.

   Si en vez de esto se usara un ancho en porcentaje -como hace
   .preview-capas del editor de perfil-, cada una de las 15 capas
   resolvería su porcentaje y redondearía a píxel de dispositivo por su
   cuenta, y dos capas podrían quedar a subpíxeles una de otra. Con la
   caja clavada y un único transform:scale, toda la pila comparte una sola
   matriz y no puede desincronizarse a ningún zoom.

   Y el 504, no el 505: el editor de perfil usa aspect-ratio 327/505 en
   cuatro sitios, pero la medida de la mayoría del catálogo es 327x504 y
   es la que este panel usa desde siempre (LIENZO, en js/arte.js). Copiar
   el 505 falsearía en un 0,2 % justo la cifra que el artista se lleva a
   su programa de dibujo. */
#vestLienzo {
  position: relative;
  width: 327px;
  height: 504px;
  transform: scale(var(--vest-zoom, 1));
  transform-origin: top left;
  overflow: hidden;
  touch-action: none;
  user-select: none;
  cursor: grab;
  border: 1px solid var(--line);
  border-radius: 4px;
  background-color: var(--control-bg);
  background-image:
    repeating-conic-gradient(rgba(255, 255, 255, .06) 0% 25%, transparent 0% 50%);
  background-size: 16px 16px;
}

#vestLienzo.vest-arrastrando { cursor: grabbing; }

/* Fuera del paso de colocar el lienzo es para mirar. Sin esto seguiría
   ofreciendo la mano de agarrar sobre algo que ya no se mueve. */
#vestLienzo.vest-quieto { cursor: default; }

/* A partir de 2x se cuentan los píxeles en vez de mirar una mancha
   interpolada, que es justo lo que hace falta para decidir si sobra uno. */
#vestLienzo.vest-nitido img { image-rendering: pixelated; }

/* Encontrar un borde blanco sobre fondo blanco es media hora perdida. */
#vestLienzo.vest-fondo-blanco { background-color: #fff; background-image: none; }
#vestLienzo.vest-fondo-negro { background-color: #000; background-image: none; }
#vestLienzo.vest-fondo-magenta { background-color: #f0f; background-image: none; }

/* object-fit:fill y no contain: el rectángulo que calcula la ZONA A YA es
   el encaje cuando toca serlo, y dejar que el navegador lo aplique otra
   vez lo aplicaría dos veces. */
.vest-capa {
  position: absolute;
  object-fit: fill;
  pointer-events: none;
}

.vest-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.vest-recuadro {
  position: absolute;
  border: 1px dashed var(--accent);
  pointer-events: none;
}

/* ---------- los números ---------- */

.vest-numeros {
  display: flex;
  gap: 10px;
  align-items: flex-end;
  flex-wrap: wrap;
  margin-top: 14px;
  width: 100%;
  max-width: 340px;
}
.vest-numeros .arte-campo { width: 74px; }

.vest-casilla {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  cursor: pointer;
  padding-bottom: 7px;
}

/* Las casillas NO entran en la regla de los controles de arriba: ahí
   saldrían con width:100% y padding, o sea deformes. */
.vest-check {
  width: 16px;
  height: 16px;
  accent-color: var(--accent);
  flex-shrink: 0;
  margin: 0;
}

.vest-instruccion {
  font-size: 13px;
  line-height: 1.5;
  margin: 8px 0 0;
  max-width: 44ch;
  border-left: 2px solid var(--accent);
  padding-left: 10px;
  opacity: .85;
}

/* ---------- el rail de prendas en prueba ---------- */

.vest-prueba {
  display: grid;
  grid-template-columns: minmax(0, auto) 48px minmax(0, 1fr);
  gap: 8px;
  align-items: center;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  margin-bottom: 8px;
  background: var(--bg-panel-alt);
}
.vest-prueba.vest-activa { border-color: var(--accent); }
.vest-prueba.vest-rota { border-color: var(--danger); }

/* Las miniaturas del vestidor y del taller, apoyadas abajo como el marco que
   compone el servidor (specs/010-personajes-oficiales, research D22). */
.vest-prueba img {
  width: 48px;
  height: 74px;
  object-fit: contain;
  object-position: 50% 100%;
  background: var(--control-bg);
  border-radius: 4px;
}

.vest-prueba .nom {
  font-size: 12.5px;
  font-weight: 600;
  word-break: break-word;
}

.vest-chip {
  display: inline-block;
  font-size: 11px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--chip-bg);
  margin-top: 3px;
  font-variant-numeric: tabular-nums;
}
.vest-chip.ojo { background: var(--gold); color: #1a1205; }
.vest-chip.mala { background: var(--danger); color: #fff; }

/* ---------- el guardarropa ---------- */

.vest-ranuras {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-bottom: 12px;
}

.vest-ranura {
  background: var(--control-bg);
  border: 1px solid var(--control-border);
  color: inherit;
  border-radius: 999px;
  padding: 4px 10px;
  font-family: inherit;
  font-size: 12px;
  cursor: pointer;
}
.vest-ranura[aria-pressed="true"] { border-color: var(--accent); background: var(--chip-bg); }
.vest-ranura.ocupada { font-weight: 700; }
.vest-ranura:disabled { opacity: .45; cursor: default; }

.vest-buscar {
  background: var(--control-bg);
  border: 1px solid var(--control-border);
  color: inherit;
  border-radius: 6px;
  padding: 7px 9px;
  font-family: inherit;
  font-size: 14px;
  width: 100%;
  margin-bottom: 10px;
}

.vest-rejilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
  gap: 8px;
}

.vest-opcion {
  background: var(--control-bg);
  border: 2px solid var(--line);
  border-radius: 8px;
  padding: 5px;
  cursor: pointer;
  font-family: inherit;
  font-size: 10.5px;
  color: inherit;
  text-align: center;
}
.vest-opcion:hover { border-color: var(--control-hover); }
.vest-opcion[aria-pressed="true"] { border-color: var(--accent); }

.vest-opcion img {
  width: 100%;
  aspect-ratio: 327 / 504;
  object-fit: contain;
  object-position: 50% 100%;
  display: block;
  background-color: var(--bg-deep);
}

.vest-opcion span {
  display: block;
  margin-top: 3px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  opacity: .8;
}

/* ---------- el pie ---------- */

.vest-pie {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}
.vest-pie .arte-aviso { width: 100%; margin: 0 0 8px; }

/* Mientras se arrastra un PNG por encima de la sección. */
#arteVestidor.vest-soltando { border-color: var(--accent); }

/* ==============================
   EL TALLER
   ==============================
   Los seis pasos, encima del maniquí que ya existía. Sólo lo que el
   vestidor libre no necesitaba. */

/* ---------- el carril de pasos ---------- */

.taller-carril {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 14px 0 4px;
}

.taller-hito {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  color: var(--text-muted);
  background: none;
  border: 0;
  padding: 2px 4px;
  font-family: inherit;
  cursor: pointer;
}
.taller-hito:disabled { cursor: default; }

.taller-bolita {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  border: 1px solid var(--line);
  background: var(--control-bg);
  flex-shrink: 0;
}
.taller-hito[aria-current="step"] { color: var(--texto, #e8edf2); }
/* El paso en curso y «Seguir», con el acento claro del oscuro (o el oscuro del
   claro) y el texto de los botones encima: el blanco sobre el acento fuerte se
   quedaba en 2,17:1 con Clásica, 2,43:1 con Neon y 3,67:1 con Arcade en el
   oscuro (punto 226, specs/070-medalla-y-dorados-del-oscuro). */
.taller-hito[aria-current="step"] .taller-bolita {
  background: var(--accent-color);
  border-color: var(--accent-color);
  color: var(--text-on-accent);
}
.taller-hito.hecho .taller-bolita {
  background: var(--chip-bg);
  border-color: var(--green);
  color: var(--green);
}
.taller-raya { width: 22px; height: 1px; background: var(--line); }

/* ---------- el paso 1: personajes y plantillas ---------- */

.taller-personajes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: 8px;
}

.taller-personaje {
  background: var(--control-bg);
  border: 2px solid var(--line);
  border-radius: 8px;
  padding: 10px 6px;
  font-family: inherit;
  color: inherit;
  cursor: pointer;
  text-align: center;
}
.taller-personaje:hover { border-color: var(--control-hover); }
.taller-personaje[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--chip-bg);
}
.taller-personaje .nom {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
}
/* Dentro de un botón, con el color del botón: lo distingue su tamaño. */
.taller-personaje .cuantas { font-size: 10.5px; margin-top: 2px; }
.taller-personaje .cuantas.escondido { color: var(--danger); opacity: 1; }

.taller-plantilla {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  border-left: 3px solid var(--gold);
  padding-left: 12px;
}

.taller-descarga {
  display: block;
  width: 100%;
  text-align: left;
  padding: 10px 12px;
  margin-bottom: 7px;
  line-height: 1.4;
}
.taller-descarga .que { display: block; font-weight: 700; font-size: 13px; }
.taller-descarga .como { display: block; font-size: 11.5px; }

/* ---------- el paso 2: traer ---------- */

.taller-soltar {
  border: 1px dashed var(--line-hover);
  border-radius: 10px;
  padding: 22px 16px;
  text-align: center;
  margin-bottom: 12px;
}
.taller-soltar.encima { border-color: var(--accent); background: var(--chip-bg); }
.taller-soltar-texto { font-size: 14px; font-weight: 600; margin-bottom: 4px; }
.taller-soltar input[type="file"] { margin-top: 10px; font-size: 12.5px; }

/* El dibujo del archivo contra el lienzo, a escala. Es el aviso que de
   verdad se entiende: cinco de cinco prendas subidas por el panel
   llegaron con otro lienzo, y un numero en una linea no lo evito. */
.taller-comparar {
  display: flex;
  align-items: flex-end;
  /* Las dos cajas suman hasta 14+45+18+260+14 = 351 px dentro de un
     rail de 320: se salían siempre que un archivo no medía el lienzo,
     que según la historia del panel es casi siempre. El JS ya las
     dibuja al ancho que quepa; esto las apila si aún así no caben. */
  flex-wrap: wrap;
  gap: 18px;
  margin-top: 12px;
  padding: 14px;
  border: 1px solid var(--gold);
  border-radius: 8px;
  background: var(--warning-bg, rgba(240, 180, 41, .10));
}
.taller-caja { border: 2px solid; border-radius: 2px; }
.taller-caja.lienzo { border-color: var(--green); background: rgba(53, 212, 136, .10); }
.taller-caja.archivo { border-color: var(--gold); background: rgba(240, 180, 41, .10); }
.taller-comparar figcaption { font-size: 10.5px; opacity: .65; margin-top: 6px; text-align: center; }

/* ---------- el paso 3: fichar ---------- */

.taller-comunes {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.taller-comunes select { width: auto; min-width: 110px; }

.taller-ficha {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px;
  margin-bottom: 8px;
  background: var(--bg-panel-alt);
  cursor: pointer;
}
.taller-ficha.elegida { border-color: var(--accent); background: var(--chip-bg); }
.taller-ficha.avisa { border-color: var(--gold); }
.taller-ficha .arch {
  font-size: 12.5px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.taller-campos {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 7px;
  margin-top: 8px;
}

/* ---------- el paso 4: los mandos ---------- */

.taller-mandos {
  display: flex;
  gap: 16px;
  align-items: flex-start;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

/* La cruceta es el control preciso de verdad en el telefono, donde el
   dedo no acierta un pixel, y en el ordenador resulta mas comodo que el
   teclado para mucha gente. 44 px es el minimo para tocar con el dedo. */
.taller-cruceta {
  display: grid;
  grid-template-columns: repeat(3, 46px);
  grid-auto-rows: 44px;
  gap: 4px;
}

.taller-flecha {
  background: var(--control-bg);
  border: 1px solid var(--control-border);
  color: inherit;
  border-radius: 8px;
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  font-family: inherit;
}
.taller-flecha:hover { background: var(--control-hover); border-color: var(--accent); }
.taller-flecha:active { background: var(--chip-bg); }

.taller-cruceta .vest-dato {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  font-size: 11px;
  color: var(--text-muted);
}

.taller-finos {
  flex: 1;
  min-width: 190px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.taller-finos input[type="range"] {
  width: 100%;
  accent-color: var(--accent);
  height: 30px;
}

/* ---------- el paso 5: la rejilla de conjuntos ---------- */

.taller-conjuntos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 10px;
}

.taller-conjunto {
  position: relative;
  width: 100%;
  aspect-ratio: 327 / 504;
  overflow: hidden;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: var(--bg-deep);
}
/* contain y apoyado abajo, como el marco del servidor: todas las capas de un
   personaje miden su lienzo, que puede tener otra forma que esta caja
   (specs/010-personajes-oficiales, research D22). Con 327x504 llena la caja
   igual que el fill de antes. */
.taller-conjunto img {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: 50% 100%;
}

/* ---------- el paso 6: el resumen ---------- */

.taller-linea {
  display: grid;
  grid-template-columns: minmax(0, auto) 34px minmax(0, 1fr) minmax(0, auto);
  gap: 10px;
  align-items: center;
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  margin-bottom: 7px;
  background: var(--bg-panel-alt);
  font-size: 12.5px;
}
.taller-linea img { width: 34px; height: 52px; object-fit: contain; object-position: 50% 100%; }
.taller-linea .sera { font-variant-numeric: tabular-nums; font-size: 11px; opacity: .7; }

/* ---------- la barra de abajo ---------- */

.taller-nav {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.taller-nav .vest-dato { margin: 0; margin-right: auto; }

.taller-primario {
  background: var(--accent-color);
  border-color: var(--accent-color);
  color: var(--text-on-accent);
  font-weight: 600;
  padding: 9px 18px;
  font-size: 14px;
}
/* Al pasar por encima, el mismo par, un poco más claro (hasta la spec 070 era
   este par el del hover, y el blanco sobre el acento fuerte, el de siempre:
   specs/047-contraste-segunda-pasada). */
.taller-primario:hover:not(:disabled) { filter: brightness(1.08); }
.taller-primario:disabled { opacity: .4; }

/* Lo de "publicar tal cual" va deliberadamente pequeño y sin caja: la
   idea es que se use el lienzo, no que las dos salidas pesen igual. */
.taller-secundario {
  background: none;
  border: 0;
  padding: 4px 2px;
  font-size: 11.5px;
  opacity: .7;
  text-decoration: underline;
  cursor: pointer;
}
/* Al pasar por encima, el morado de acento: el lila suave, en el claro, se
   quedaba en 2,3:1 (specs/047-contraste-segunda-pasada). */
.taller-secundario:hover { opacity: 1; color: var(--accent-color); }

/* ---------- telefono ---------- */
/* El maniqui cabe a tamaño real: 327 px entran en los 343 utiles de un
   movil de 375. En el paso de colocar eso significa que un pixel de la
   pantalla es un pixel del PNG. En el resto se encoge para dejar sitio. */

@media (max-width: 1180px) {
  .taller-carril { gap: 5px; }
  .taller-hito span:not(.taller-bolita) { display: none; }
  .taller-raya { width: 10px; }
  .taller-hito[aria-current="step"] span:not(.taller-bolita) { display: inline; }
}

@media (max-width: 720px) {
  .vest-escena { position: sticky; top: 0; z-index: 3; background: var(--bg-panel); padding-bottom: 8px; }
  .vest-marco { transform: scale(.62); transform-origin: top center; height: 313px; }
  .vest-escena.a-tamano .vest-marco { transform: none; height: auto; }
  .taller-cruceta { grid-template-columns: repeat(3, 56px); grid-auto-rows: 50px; }
  .taller-nav { position: sticky; bottom: 0; background: var(--bg-panel); padding-bottom: 10px; }
  .taller-nav .vest-dato { flex-basis: 100%; margin-right: 0; }
  .taller-campos { grid-template-columns: 1fr; }
}

/* ==============================
   EL TALLER COMO PAGINA
   ==============================
   Dentro de arte.html el taller nunca iba a verse como se diseno: le
   sobraban encima una navbar, un titulo, un parrafo de ayuda y el
   formulario viejo. En su propia pagina el alto entero es suyo, que es lo
   que necesitan el maniqui a tamano real y las tres columnas. */

body.taller-pagina {
  margin: 0;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--bg-base);
  color: var(--texto, #e8edf2);
  font-family: var(--font-body);
}

.taller-barra-sitio {
  height: 56px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 0 24px;
  border-bottom: 1px solid var(--line);
  background: var(--navbar-bg);
}
.taller-barra-sitio .nav-logo { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.taller-barra-sitio .nav-logo img { height: 24px; width: auto; }
.taller-titulo { font-family: var(--font-display); font-size: 18px; font-weight: 700; margin: 0; }

body.taller-pagina > .arte-aviso { margin: 24px; }

.taller-main {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 0 24px 18px;
}

.taller-pagina #vestPanel {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* Las tres columnas se comen el alto que queda, y cada rail rueda por su
   cuenta: el maniqui no se va de la pantalla al bajar por la cola. */
.taller-pagina .vest-panel {
  flex: 1;
  min-height: 0;
  align-items: stretch;
}
.taller-pagina .vest-rail { max-height: none; overflow-y: auto; overflow-x: hidden; }
.taller-pagina .vest-escena { overflow-y: auto; overflow-x: hidden; scrollbar-gutter: stable; }

/* ---------- que nada se salga de su columna ---------- */

/* Las barras horizontales del taller no salían de un sitio: salían de
   varios, y todos son controles o dibujos que traen su propio ancho y no
   lo sueltan por su cuenta.

   La más dura es el <input type="file">. Un file mide lo que mide su
   texto -en español, «Seleccionar archivos · Ningún archivo seleccionado»
   pasa de 350 px- y no se encoge por nada. En un rail de 320 se salía
   siempre, en el paso 2, que es por donde pasa todo el mundo.

   Y en esta página no había NADA que estilara los controles: las reglas
   compartidas cuelgan de .arte-main, que es la clase de arte.html, y el
   taller usa .taller-main. Así que cada select y cada input salían con su
   ancho de fábrica. */
.taller-pagina select,
.taller-pagina input[type="text"],
.taller-pagina input[type="number"],
.taller-pagina input[type="file"] { max-width: 100%; }

.taller-soltar input[type="file"] { width: 100%; }

/* Un nombre de archivo no trae espacios donde partir: sin esto, un
   «Captura_de_pantalla_2026_09_15_113043.png» estira lo que lo lleve. */
.taller-comparar figcaption,
.taller-descarga .que,
.taller-descarga .como { overflow-wrap: anywhere; }

.taller-comparar figure { min-width: 0; max-width: 100%; margin: 0; }
.taller-caja { max-width: 100%; }
.taller-pagina .vest-barra { position: static; padding-top: 4px; }
.taller-pagina .taller-nav { flex-shrink: 0; }

@media (max-width: 720px) {
  /* En el teléfono la página entera rueda, así que los raíles dejan de
     tener scroll propio. Pero «visible» a secas devolvía la barra
     horizontal: clip en un eje y visible en el otro es la única pareja
     que el CSS NO convierte en auto, así que corta de ancho sin volver a
     convertir la caja en un contenedor con scroll. */
  body.taller-pagina {
    height: auto;
    min-height: 100dvh;
    overflow-x: clip;
    overflow-y: visible;
  }
  .taller-main { padding: 0 16px 16px; }
  .taller-pagina .vest-rail,
  .taller-pagina .vest-escena { overflow-x: clip; overflow-y: visible; }
}

/* La invitacion que queda en arte.html en lugar del taller. */
.taller-invitacion { border-left: 3px solid var(--accent); }
.taller-invitacion .boton { margin-top: 6px; display: inline-block; }
