/* ==========================================================================
   Chatper · components.css
   Estilos de los componentes autocontenidos (assets/js/components/*).
   Solo usan los tokens de base.css (SPEC §6.2). Todo en rem/em.
   Excepción deliberada: el visor (lightbox) es siempre oscuro, en ambos temas.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Común
   -------------------------------------------------------------------------- */
:where(.emoji-picker, .emoji-popover, .lightbox, .tag-input, .tag-input__suggestions,
       .audio-player, .voice-recorder, .color-swatches, .file-drop-overlay) [hidden],
:where(.emoji-picker, .emoji-popover, .emoji-popover-backdrop, .lightbox, .tag-input,
       .tag-input__suggestions, .audio-player, .voice-recorder, .color-swatches)[hidden] {
  display: none !important;
}

.cp-icon {
  width: 1.25em;
  height: 1.25em;
  flex: none;
  display: block;
}

.cp-icon-text {
  display: inline-block;
  font-size: 1.125em;
  line-height: 1;
}

.cp-sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@keyframes cp-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes cp-pop-in {
  from { opacity: 0; transform: translateY(var(--cp-pop-shift, 6px)) scale(.98); }
  to { opacity: 1; transform: none; }
}

@keyframes cp-sheet-in {
  from { transform: translateY(100%); }
  to { transform: none; }
}

@keyframes cp-spin {
  to { transform: rotate(360deg); }
}

@keyframes cp-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: .35; transform: scale(.8); }
}

@keyframes cp-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-4px); }
  40% { transform: translateX(4px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(2px); }
}

@keyframes cp-flash {
  0% { box-shadow: 0 0 0 0 var(--accent); }
  100% { box-shadow: 0 0 0 6px transparent; }
}

@keyframes cp-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}

/* --------------------------------------------------------------------------
   1. Selector de emojis
   -------------------------------------------------------------------------- */
.emoji-picker {
  --ep-cell: 2.375rem;
  --ep-emoji-size: 1.5rem;
  --ep-emoji-font: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Twemoji Mozilla",
    "Segoe UI Symbol", "Android Emoji", sans-serif;
  display: flex;
  flex-direction: column;
  width: 22.5rem;
  max-width: 100%;
  height: 26.5rem;
  min-height: 0;
  color: var(--text);
  background: var(--surface);
  border-radius: var(--radius-lg);
  overflow: hidden;
  font-family: var(--font-sans);
  font-size: 1rem;
}

/* Búsqueda */
.emoji-picker__search {
  position: relative;
  flex: none;
  margin: .75rem .75rem .5rem;
}

.emoji-picker__search-icon {
  position: absolute;
  left: .625rem;
  top: 50%;
  width: 1.0625rem;
  height: 1.0625rem;
  transform: translateY(-50%);
  color: var(--text-subtle);
  pointer-events: none;
}

.emoji-picker__search-input {
  display: block;
  width: 100%;
  height: 2.25rem;
  padding: 0 2.25rem 0 2.125rem;
  font: inherit;
  font-size: .9375rem;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid transparent;
  border-radius: var(--radius);
  outline: none;
  transition: border-color var(--dur) var(--ease), background-color var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
  -webkit-appearance: none;
  appearance: none;
}

.emoji-picker__search-input::placeholder { color: var(--text-subtle); }
.emoji-picker__search-input::-webkit-search-cancel-button { display: none; }

.emoji-picker__search-input:focus {
  background: var(--surface);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.emoji-picker__search-clear {
  position: absolute;
  right: .25rem;
  top: 50%;
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  padding: 0;
  transform: translateY(-50%);
  color: var(--text-muted);
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.emoji-picker__search-clear .cp-icon { width: 1rem; height: 1rem; }
.emoji-picker__search-clear:hover { color: var(--text); background: var(--surface-3); }

/* Pestañas de categoría */
.emoji-picker__tabs {
  display: flex;
  flex: none;
  gap: .125rem;
  padding: 0 .5rem;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  scrollbar-width: none;
}

.emoji-picker__tabs::-webkit-scrollbar { display: none; }

.emoji-picker__tab {
  position: relative;
  flex: 1 0 auto;
  display: grid;
  place-items: center;
  min-width: 2rem;
  height: 2.375rem;
  padding: 0;
  color: var(--text-subtle);
  background: none;
  border: 0;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  cursor: pointer;
  transition: color var(--dur) var(--ease), background-color var(--dur) var(--ease), opacity var(--dur) var(--ease);
}

.emoji-picker__tab .cp-icon { width: 1.125rem; height: 1.125rem; }
.emoji-picker__tab:hover { color: var(--text); background: var(--surface-2); }

.emoji-picker__tab[aria-current="true"] { color: var(--accent); }

.emoji-picker__tab[aria-current="true"]::after {
  content: "";
  position: absolute;
  left: 22%;
  right: 22%;
  bottom: -1px;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
}

.emoji-picker__tabs.is-dimmed .emoji-picker__tab { opacity: .55; }
.emoji-picker__tabs.is-dimmed .emoji-picker__tab:hover { opacity: 1; }

/* Cuadrícula */
.emoji-picker__scroll {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  padding: 0 .5rem .5rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  scroll-padding-top: 2.125rem;
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--accent) 30%, var(--border-strong)) transparent;
}

.emoji-picker__scroll::-webkit-scrollbar { width: 8px; }
.emoji-picker__scroll::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border: 2px solid var(--surface);
  border-radius: var(--radius-full);
}

.emoji-picker__heading {
  position: sticky;
  top: 0;
  z-index: 1;
  margin: 0;
  padding: .625rem .25rem .375rem;
  font-size: .75rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: .01em;
  color: var(--text-muted);
  background: var(--surface);
}

/* Rendimiento (SPEC §9.9): cada sección solo se maqueta, pinta y rasteriza si está cerca de la vista.
   El alto estimado (cabecera + filas; --rows lo calcula el JS con las columnas reales) mantiene el
   tamaño del desplazamiento; con «auto» se recuerda el alto real una vez pintada. */
.emoji-picker__section {
  content-visibility: auto;
  contain-intrinsic-size: auto 18rem auto calc(1.9rem + var(--rows, 4) * var(--ep-cell));
}

/* Elemento invisible con la fuente, el tamaño y el color con los que se pintan las hojas de emojis
   (emoji-picker.js · probe). */
.emoji-picker.emoji-picker--warm {
  position: fixed;
  top: 0;
  left: 0;
  z-index: -1;
  display: block;
  width: 20rem;
  height: auto;
  overflow: hidden;
  visibility: hidden;
  pointer-events: none;
  contain: layout paint style;
  font-family: var(--ep-emoji-font);
  font-size: var(--ep-emoji-size);
  background: none;
}

.emoji-picker.emoji-picker--warm[data-sheet] { --ep-emoji-size: 1.625rem; }

/* Durante la búsqueda las categorías se ocultan sin perder su diseño (volver es inmediato). */
.emoji-picker.is-searching .emoji-picker__sections {
  content-visibility: hidden;
}

.emoji-picker__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--ep-cell), 1fr));
}

.emoji-picker__grid[data-pending] {
  min-height: calc(var(--rows, 4) * var(--ep-cell));
}

/* Bloque con line-height = alto de la celda (no grid/flex): maquetar cientos de botones cuesta
   2-3 veces menos y el emoji queda igual de centrado. */
.emoji-picker__emoji {
  display: block;
  width: 100%;
  height: var(--ep-cell);
  padding: 0;
  overflow: hidden;
  font-family: var(--ep-emoji-font);
  font-size: var(--ep-emoji-size);
  line-height: var(--ep-cell);
  text-align: center;
  white-space: nowrap;
  color: var(--text);
  background: none;
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background-color 120ms var(--ease), transform 120ms var(--ease);
  -webkit-user-select: none;
  user-select: none;
}

/* Emoji pintado como imagen (SPEC §19.4, emoji-picker.js): su celda de una hoja de 16 × 16 (cada celda mide
   1,25 veces el emoji). --ep-c / --ep-r: columna y fila; .ep-sN lleva la imagen de la hoja N. */
/* §37: la imagen Noto 3D del emoji */
.emoji-picker__img {
  display: block;
  width: calc(var(--ep-emoji-size) * 1.15);
  height: calc(var(--ep-emoji-size) * 1.15);
  margin: calc((var(--ep-cell) - var(--ep-emoji-size) * 1.15) / 2) auto 0;
  pointer-events: none;
}
.emoji-picker__preview-img { display: block; width: 2rem; height: 2rem; }
.emoji-picker__emoji.has-img { position: relative; }
.emoji-picker__emoji.has-img::before {
  --ep-g: calc(var(--ep-emoji-size) * 1.25);
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--ep-g);
  height: var(--ep-g);
  margin: calc(var(--ep-g) / -2) 0 0 calc(var(--ep-g) / -2);
  background-repeat: no-repeat;
  background-size: calc(var(--ep-g) * 16) calc(var(--ep-g) * 16);
  background-position: calc(var(--ep-g) * var(--ep-c, 0) * -1) calc(var(--ep-g) * var(--ep-r, 0) * -1);
  pointer-events: none;
}

.emoji-picker__emoji:hover { background: var(--surface-2); }
.emoji-picker__emoji:active { transform: scale(.88); }

.emoji-picker__emoji:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  background: var(--accent-soft);
}

.emoji-picker__empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .25rem;
  padding: 2.5rem 1rem;
  text-align: center;
}

.emoji-picker__empty-icon {
  margin-bottom: .25rem;
  font-family: var(--ep-emoji-font);
  font-size: 2rem;
  line-height: 1;
  opacity: .8;
}

.emoji-picker__empty-title { font-weight: 600; color: var(--text); }
.emoji-picker__empty-text { font-size: .875rem; color: var(--text-muted); overflow-wrap: anywhere; }

/* Pie: vista previa + tono de piel */
.emoji-picker__footer {
  display: flex;
  flex: none;
  align-items: center;
  gap: .5rem;
  min-height: 3rem;
  padding: .375rem .5rem .375rem .75rem;
  background: var(--surface);
  border-top: 1px solid var(--border);
}

.emoji-picker__preview {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  gap: .625rem;
  min-width: 0;
}

.emoji-picker__preview-emoji {
  flex: none;
  width: 2rem;
  font-family: var(--ep-emoji-font);
  font-size: 1.75rem;
  line-height: 1;
  text-align: center;
}

.emoji-picker__preview-name {
  min-width: 0;
  overflow: hidden;
  font-size: .8125rem;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.emoji-picker__preview.is-empty .emoji-picker__preview-emoji { display: none; }
.emoji-picker__preview.is-empty .emoji-picker__preview-name { font-weight: 400; color: var(--text-subtle); }

.emoji-picker__tone-toggle,
.emoji-picker__tone {
  display: grid;
  flex: none;
  place-items: center;
  padding: 0;
  font-family: var(--ep-emoji-font);
  line-height: 1;
  background: none;
  border: 0;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.emoji-picker__tone-toggle {
  width: 2.25rem;
  height: 2.25rem;
  margin-left: auto;
  font-size: 1.3125rem;
  border-radius: var(--radius);
}

.emoji-picker__tone-toggle:hover,
.emoji-picker__tone-toggle[aria-expanded="true"] { background: var(--surface-2); }

.emoji-picker__tones {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  justify-content: flex-end;
  gap: .125rem;
}

.emoji-picker__tone {
  width: 2rem;
  height: 2rem;
  font-size: 1.25rem;
  border-radius: var(--radius-full);
}

.emoji-picker__tone:hover { background: var(--surface-2); }
.emoji-picker__tone[aria-checked="true"] { box-shadow: inset 0 0 0 2px var(--accent); background: var(--accent-soft); }

.emoji-picker__tone-toggle:focus-visible,
.emoji-picker__tone:focus-visible,
.emoji-picker__tab:focus-visible,
.emoji-picker__search-clear:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* Popover */
.emoji-popover {
  --cp-pop-shift: 6px;
  position: fixed;
  z-index: calc(var(--z-modal) + 10);   /* también por encima de un modal abierto */
  display: flex;
  flex-direction: column;
  max-width: calc(100vw - 1rem);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  outline: none;
  animation: cp-pop-in var(--dur-in) var(--ease);
}

.emoji-popover[data-side="bottom"] { --cp-pop-shift: -6px; }

/* Cerrado: el popover se reutiliza (SPEC §9.9). Queda invisible, inerte y con content-visibility:
   hidden, que conserva el diseño ya calculado para que la siguiente apertura no vuelva a maquetar. */
.emoji-popover.is-parked {
  visibility: hidden;
  content-visibility: hidden;
  pointer-events: none;
  animation: none;
}

.emoji-popover > .emoji-picker {
  flex: 1 1 auto;
  max-height: 100%;
  min-height: 0;
}

.emoji-popover-backdrop {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-modal) + 9);
  background: var(--overlay, rgba(15, 18, 25, .45));
  animation: cp-fade-in var(--dur-in) var(--ease);
}

/* Hoja inferior en móvil */
.emoji-popover--sheet {
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  max-width: none;
  padding-bottom: env(safe-area-inset-bottom, 0px);
  border-width: 1px 0 0;
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  animation: cp-sheet-in var(--dur-in) var(--ease);
}

.emoji-popover--sheet::before {
  content: "";
  flex: none;
  width: 2.5rem;
  height: .25rem;
  margin: .5rem auto 0;
  border-radius: var(--radius-full);
  background: var(--border-strong);
}

.emoji-popover--sheet > .emoji-picker {
  --ep-cell: 2.625rem;
  --ep-emoji-size: 1.625rem;
  width: 100%;
  height: min(62vh, 27rem);
  border-radius: 0;
}

/* --------------------------------------------------------------------------
   2. Visor (lightbox) — siempre oscuro
   -------------------------------------------------------------------------- */
.lightbox {
  --lb-bg: rgba(8, 9, 12, .95);
  --lb-fg: #f4f5f7;
  --lb-muted: rgba(244, 245, 247, .68);
  --lb-btn: rgba(255, 255, 255, .08);
  --lb-btn-hover: rgba(255, 255, 255, .16);
  --lb-ring: rgba(255, 255, 255, .55);
  position: fixed;
  inset: 0;
  z-index: var(--z-lightbox);
  display: flex;
  flex-direction: column;
  color: var(--lb-fg);
  background: var(--lb-bg);
  -webkit-backdrop-filter: blur(12px) saturate(.7);
  backdrop-filter: blur(12px) saturate(.7);
  font-family: var(--font-sans);
  font-size: 1rem;
  outline: none;
  -webkit-user-select: none;
  user-select: none;
  animation: cp-fade-in var(--dur-in) var(--ease);
}

.lightbox__bar {
  position: relative;
  z-index: 2;
  display: flex;
  flex: none;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 3.5rem;
  padding: .5rem .625rem .5rem 1.25rem;
}

.lightbox__meta {
  display: flex;
  align-items: baseline;
  gap: .75rem;
  min-width: 0;
}

.lightbox__counter {
  flex: none;
  font-size: .875rem;
  font-variant-numeric: tabular-nums;
  color: var(--lb-muted);
}

.lightbox__title {
  min-width: 0;
  overflow: hidden;
  font-size: .9375rem;
  font-weight: 500;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.lightbox__tools {
  display: flex;
  flex: none;
  align-items: center;
  gap: .25rem;
}

.lightbox__tool {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  color: var(--lb-fg);
  text-decoration: none;
  background: transparent;
  border: 0;
  border-radius: var(--radius-full);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), opacity var(--dur) var(--ease);
}

.lightbox__tool:hover { background: var(--lb-btn-hover); }
.lightbox__tool:disabled { opacity: .35; cursor: default; background: none; }

.lightbox__zoom {
  display: flex;
  align-items: center;
  gap: .125rem;
  margin: 0 .25rem;
  padding: 0 .125rem;
  background: var(--lb-btn);
  border-radius: var(--radius-full);
}

.lightbox__zoom .lightbox__tool { width: 2.25rem; height: 2.25rem; }

.lightbox__zoom-level {
  min-width: 3.75rem;
  height: 2rem;
  padding: 0 .25rem;
  font: inherit;
  font-size: .8125rem;
  font-variant-numeric: tabular-nums;
  color: var(--lb-fg);
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.lightbox__zoom-level:hover:not(:disabled) { background: var(--lb-btn-hover); }
.lightbox__zoom-level:disabled { cursor: default; opacity: .6; }

.lightbox__tool:focus-visible,
.lightbox__zoom-level:focus-visible,
.lightbox__nav:focus-visible,
.lightbox__file-download:focus-visible {
  outline: 2px solid var(--lb-ring);
  outline-offset: 2px;
}

.lightbox__stage {
  position: relative;
  display: grid;
  flex: 1 1 auto;
  place-items: center;
  min-height: 0;
  overflow: hidden;
  touch-action: none;
}

.lightbox__stage.is-zoomed { cursor: grab; }
.lightbox__stage.is-panning { cursor: grabbing; }

.lightbox__img {
  /* Centrada con left/top 50 % y márgenes negativos (los pone el JS con su tamaño): así sigue
     centrada cuando el zoom la hace más grande que el escenario. */
  position: absolute;
  top: 50%;
  left: 50%;
  display: block;
  max-width: none;
  border-radius: 2px;
  box-shadow: 0 1.25rem 3.75rem rgba(0, 0, 0, .45);
  opacity: 0;
  transform-origin: center center;
  /* Sin will-change fijo: con una capa permanente el navegador reutiliza el dibujo a la escala de
     «ajustar» y al ampliar se ve borroso. Solo se activa mientras se arrastra o pellizca. */
  transition: opacity 200ms var(--ease);
  -webkit-user-drag: none;
}

.lightbox__img.is-loaded { opacity: 1; }
.lightbox__img.is-smooth {
  transition: opacity 200ms var(--ease), transform 220ms var(--ease), width 220ms var(--ease), height 220ms var(--ease),
              margin 220ms var(--ease);
}
.lightbox__img.is-moving { will-change: transform; }
/* Miniatura que se ve mientras llega el original (debajo; el original aparece encima al cargar). */
.lightbox__img--placeholder { filter: blur(0.5px); box-shadow: none; }
.lightbox__spinner--over {
  align-self: end;
  margin-bottom: 1.25rem;
  width: 1.75rem;
  height: 1.75rem;
  border-width: 2.5px;
  box-shadow: 0 0 0 0.5rem rgba(0, 0, 0, .35);
  background: rgba(0, 0, 0, .35);
}

/* Vídeo (SPEC §9.16): centrado en posición absoluta, así max-width/max-height se resuelven contra el
   escenario (el área libre entre la barra y el pie). Antes, como celda de la rejilla, la fila crecía
   hasta el alto natural del vídeo y el escenario lo recortaba por abajo. El JS (fitVideo) le da el
   tamaño exacto con su proporción, sin ampliarlo, al llegar los metadatos y al cambiar el escenario;
   object-fit: contain por si el navegador aún no sabe sus dimensiones. */
.lightbox__video {
  position: absolute;
  inset: 0;
  display: block;
  width: auto;
  height: auto;
  max-width: calc(100% - 3rem);
  max-height: calc(100% - 3rem);
  margin: auto;
  object-fit: contain;
  background: #000;
  border-radius: var(--radius);
  outline: none;
  box-shadow: 0 1.25rem 3.75rem rgba(0, 0, 0, .45);
}
/* Con el tamaño ya calculado (incluye el margen), el CSS no debe volver a recortarlo. */
.lightbox__video.is-fitted { max-width: 100%; max-height: 100%; }

.lightbox__spinner {
  grid-area: 1 / 1;
  width: 2.5rem;
  height: 2.5rem;
  border: 3px solid rgba(255, 255, 255, .18);
  border-top-color: var(--lb-fg);
  border-radius: 50%;
  animation: cp-spin .8s linear infinite;
}

.lightbox__error,
.lightbox__file {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .875rem;
  max-width: min(26rem, calc(100% - 2rem));
  padding: 2rem 2.5rem;
  text-align: center;
  color: var(--lb-muted);
}

.lightbox__error .cp-icon,
.lightbox__file-icon { width: 3rem; height: 3rem; opacity: .8; }

.lightbox__file {
  color: var(--lb-fg);
  background: var(--lb-btn);
  border-radius: var(--radius-lg);
  -webkit-user-select: text;
  user-select: text;
}

.lightbox__file-name { font-weight: 500; overflow-wrap: anywhere; }
.lightbox__file audio { width: min(20rem, 100%); }

.lightbox__file-download {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .5rem 1rem;
  font-weight: 500;
  color: var(--lb-fg);
  text-decoration: none;
  background: var(--lb-btn-hover);
  border-radius: var(--radius-full);
}

.lightbox__file-download .cp-icon { width: 1.125rem; height: 1.125rem; }

.lightbox__nav {
  position: absolute;
  top: 50%;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  padding: 0;
  color: var(--lb-fg);
  background: var(--lb-btn);
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transform: translateY(-50%);
  transition: background-color var(--dur) var(--ease);
  backdrop-filter: blur(6px);
}

.lightbox__nav:hover { background: var(--lb-btn-hover); }
.lightbox__nav .cp-icon { width: 1.5rem; height: 1.5rem; }
.lightbox__nav--prev { left: 1rem; }
.lightbox__nav--next { right: 1rem; }

.lightbox__caption {
  flex: none;
  max-height: 6.5rem;
  padding: .625rem 1.25rem .375rem;
  overflow-y: auto;
  font-size: .875rem;
  line-height: 1.5;
  text-align: center;
  color: var(--lb-muted);
  white-space: pre-line;
  -webkit-user-select: text;
  user-select: text;
}

/* Información del archivo (SPEC §16.9): nombre completo · dimensiones · peso, al pie y seleccionable. */
.lightbox__info {
  display: flex;
  flex: none;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  column-gap: .5rem;
  row-gap: .125rem;
  padding: .25rem 1.25rem 1rem;
  color: var(--lb-muted);
  font-size: .8125rem;
  line-height: 1.45;
  text-align: center;
  font-variant-numeric: tabular-nums;
  -webkit-user-select: text;
  user-select: text;
}
.lightbox__caption[hidden] + .lightbox__info { padding-top: .625rem; }
.lightbox__info[hidden], .lightbox__info > [hidden] { display: none; }
.lightbox__info-name { color: var(--lb-fg); font-weight: 500; overflow-wrap: anywhere; }
.lightbox__info > span:not([hidden]) ~ span:not([hidden])::before { content: "·"; margin-right: .5rem; color: var(--lb-muted); }

@media (max-width: 640px) {
  .lightbox__bar { padding: .375rem .25rem .375rem .875rem; gap: .5rem; }
  .lightbox__zoom { display: none; }
  .lightbox__tool { width: 2.375rem; height: 2.375rem; }
  .lightbox__nav { width: 2.5rem; height: 2.5rem; }
  .lightbox__nav--prev { left: .5rem; }
  .lightbox__nav--next { right: .5rem; }
  .lightbox__video { max-width: 100%; max-height: 100%; border-radius: 0; }
}

/* Móvil en horizontal: el escenario es bajo; sin margen (= stageMargin() de lightbox.js). */
@media (max-height: 520px) {
  .lightbox__video { max-width: 100%; max-height: 100%; border-radius: 0; }
}

@media (pointer: coarse) {
  .lightbox__nav { background: rgba(0, 0, 0, .35); }
}

/* --------------------------------------------------------------------------
   3. Campo de tags
   -------------------------------------------------------------------------- */
.tag-input {
  position: relative;
  width: 100%;
}

.tag-input__control {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .3125rem;
  min-height: 2.5rem;
  padding: .3125rem .5rem;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  cursor: text;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.tag-input__control:hover { border-color: var(--text-subtle); }

.tag-input.is-focused .tag-input__control {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.tag-input.is-limit .tag-input__control { animation: cp-shake 320ms var(--ease); border-color: var(--danger); }

.tag-input__chip {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  height: 1.75rem;
  padding: 0 .125rem 0 .5rem;
  font-size: .8125rem;
  font-weight: 500;
  line-height: 1;
  color: var(--text);
  background: var(--accent-soft);
  border-radius: var(--radius-full);
  cursor: default;
}

.tag-input__chip.is-flash { animation: cp-flash 600ms var(--ease); }

.tag-input__chip-hash {
  margin-right: .125rem;
  font-weight: 600;
  color: var(--accent);
}

.tag-input__chip-text {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.tag-input__chip-remove {
  display: grid;
  flex: none;
  place-items: center;
  width: 1.375rem;
  height: 1.375rem;
  margin-left: .125rem;
  padding: 0;
  color: var(--text-muted);
  background: none;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.tag-input__chip-remove .cp-icon { width: .875rem; height: .875rem; }
.tag-input__chip-remove:hover { color: var(--text); background: var(--surface-3); }

.tag-input__field {
  flex: 1 1 6rem;
  min-width: 6rem;
  height: 1.75rem;
  padding: 0 .25rem;
  font: inherit;
  font-size: .9375rem;
  color: var(--text);
  background: transparent;
  border: 0;
  outline: none;
}

.tag-input__field::placeholder { color: var(--text-subtle); }

/* La lista se monta en <body> (position: fixed) para que no la recorte un modal. */
.tag-input__suggestions {
  position: fixed;
  z-index: calc(var(--z-modal) + 10);
  max-height: 15rem;
  padding: .25rem;
  overflow-y: auto;
  font-family: var(--font-sans);
  font-size: .9375rem;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  animation: cp-fade-in var(--dur-in) var(--ease);
}

.tag-input__option {
  display: flex;
  align-items: center;
  gap: .25rem;
  min-height: 2rem;
  padding: .25rem .5rem;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.tag-input__option[aria-selected="true"] { background: var(--surface-2); }

.tag-input__option-hash { flex: none; color: var(--text-subtle); font-weight: 600; }

.tag-input__option-text {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.tag-input__option mark {
  padding: 0;
  font-weight: 600;
  color: var(--accent-text, var(--accent));
  background: none;
}

/* --------------------------------------------------------------------------
   4. Reproductor de audio
   Variables para adaptarlo a otros fondos (p. ej. burbuja propia del chat):
   --ap-bg, --ap-fg, --ap-muted, --ap-accent, --ap-btn-fg, --ap-track, --ap-chip
   -------------------------------------------------------------------------- */
.audio-player {
  --ap-bg: var(--surface-2);
  --ap-fg: var(--text);
  --ap-muted: var(--text-muted);
  --ap-accent: var(--accent);
  --ap-btn-fg: var(--accent-contrast);
  --ap-track: var(--border-strong);
  --ap-chip: var(--surface-3);
  display: flex;
  align-items: center;
  gap: .75rem;
  width: 100%;
  max-width: 26rem;
  min-width: 13rem;
  padding: .5rem .75rem .5rem .5rem;
  color: var(--ap-fg);
  background: var(--ap-bg);
  border-radius: var(--radius-lg);
}

.audio-player--compact {
  gap: .5rem;
  max-width: 20rem;
  min-width: 11rem;
  padding: .3125rem .5rem .3125rem .3125rem;
  border-radius: var(--radius-full);
}

.audio-player__play {
  position: relative;
  display: grid;
  flex: none;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  color: var(--ap-btn-fg);
  background: var(--ap-accent);
  border: 0;
  border-radius: 50%;
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: transform 120ms var(--ease), filter var(--dur) var(--ease);
}

.audio-player--compact .audio-player__play { width: 2.125rem; height: 2.125rem; }
.audio-player__play:hover:not(:disabled) { filter: brightness(1.08); }
.audio-player__play:active:not(:disabled) { transform: scale(.92); }
.audio-player__play:disabled { cursor: default; }

.audio-player__play .cp-icon { width: 1.125rem; height: 1.125rem; }
.audio-player--compact .audio-player__play .cp-icon { width: 1rem; height: 1rem; }
.audio-player__icon-play { transform: translateX(1px); }
.audio-player__icon-pause { display: none; }
.audio-player.is-playing .audio-player__icon-play { display: none; }
.audio-player.is-playing .audio-player__icon-pause { display: block; }

.audio-player.is-loading .audio-player__play::after {
  content: "";
  position: absolute;
  inset: -4px;
  border: 2px solid transparent;
  border-top-color: var(--ap-accent);
  border-radius: 50%;
  animation: cp-spin .9s linear infinite;
}

.audio-player.has-error .audio-player__play { background: var(--danger); color: #fff; opacity: .75; }

.audio-player__body {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: .25rem;
  min-width: 0;
}

.audio-player__name {
  overflow: hidden;
  font-size: .8125rem;
  font-weight: 500;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.audio-player__row {
  display: flex;
  align-items: center;
  gap: .5rem;
  min-width: 0;
}

.audio-player__wave {
  --p: 0;
  position: relative;
  flex: 1 1 auto;
  min-width: 4.5rem;
  height: 1.75rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  outline: none;
  touch-action: none;
}

.audio-player--compact .audio-player__wave { height: 1.5rem; }

.audio-player__wave:focus-visible {
  box-shadow: 0 0 0 2px var(--ap-bg), 0 0 0 4px var(--ap-accent);
}

.audio-player__bars {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: clamp(1px, 1%, 2px);   /* nunca desborda: en anchos pequeños las barras adelgazan */
  overflow: hidden;
  pointer-events: none;
}

.audio-player__bars > span {
  flex: 1 1 0;
  min-width: 0;
  height: calc(var(--h, .5) * 100%);
  background: var(--ap-track);
  border-radius: var(--radius-full);
}

.audio-player__progress {
  position: absolute;
  inset: 0;
  clip-path: inset(0 calc((1 - var(--p)) * 100%) 0 0);
  pointer-events: none;
}

.audio-player__bars--done > span { background: var(--ap-accent); }

.audio-player__wave:hover .audio-player__bars:not(.audio-player__bars--done) > span,
.audio-player.is-seeking .audio-player__bars:not(.audio-player__bars--done) > span {
  background: color-mix(in srgb, var(--ap-track) 70%, var(--ap-accent));
}

.audio-player__time {
  flex: none;
  min-width: 2.25rem;
  font-size: .75rem;
  font-variant-numeric: tabular-nums;
  color: var(--ap-muted);
  text-align: right;
  white-space: nowrap;
}

.audio-player__speed {
  flex: none;
  min-width: 2.375rem;
  height: 1.375rem;
  padding: 0 .375rem;
  font: inherit;
  font-size: .6875rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ap-fg);
  background: var(--ap-chip);
  border: 0;
  border-radius: var(--radius-full);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.audio-player__speed:hover { filter: brightness(.96); }
.audio-player.is-fast .audio-player__speed { color: var(--ap-btn-fg); background: var(--ap-accent); }

.audio-player__play:focus-visible,
.audio-player__speed:focus-visible {
  outline: 2px solid var(--ap-accent);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   5. Zona de soltar archivos (overlay)
   -------------------------------------------------------------------------- */
.file-drop-overlay {
  position: fixed;
  z-index: calc(var(--z-modal) + 5);
  display: flex;
  padding: .625rem;
  pointer-events: none;
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter: blur(3px);
  animation: cp-fade-in var(--dur-in) var(--ease);
}

.file-drop-overlay__inner {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .75rem;
  padding: 1rem;
  text-align: center;
  background: var(--accent-soft);
  border: 2px dashed var(--accent);
  border-radius: var(--radius-lg);
}

.file-drop-overlay__icon {
  display: grid;
  place-items: center;
  width: 3.5rem;
  height: 3.5rem;
  color: var(--accent-contrast);
  background: var(--accent);
  border-radius: 50%;
  box-shadow: var(--shadow);
  animation: cp-float 1.4s ease-in-out infinite;
}

.file-drop-overlay__icon .cp-icon { width: 1.625rem; height: 1.625rem; }

.file-drop-overlay__text {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--text);
}

.file-drop-overlay__hint {
  margin: 0;
  font-size: .875rem;
  color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   6. Grabadora de notas de voz
   -------------------------------------------------------------------------- */
.voice-recorder {
  display: flex;
  align-items: center;
  gap: .5rem;
  width: 100%;
  min-height: 3rem;
  padding: .375rem;
  color: var(--text);
  background: var(--surface-2);
  border-radius: var(--radius-full);
}

.voice-recorder__btn {
  display: grid;
  flex: none;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease),
    opacity var(--dur) var(--ease), transform 120ms var(--ease);
}

.voice-recorder__btn .cp-icon { width: 1.125rem; height: 1.125rem; }
.voice-recorder__btn:active:not(:disabled) { transform: scale(.92); }

.voice-recorder__btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.voice-recorder__cancel { color: var(--text-muted); background: transparent; }
.voice-recorder__cancel:hover { color: var(--danger-text, var(--danger)); background: var(--danger-soft); }

.voice-recorder__send { color: var(--accent-contrast); background: var(--accent); }
.voice-recorder__send:hover:not(:disabled) { background: var(--accent-hover); }
.voice-recorder__send:disabled { opacity: .45; cursor: default; }

.voice-recorder__status {
  display: flex;
  flex: none;
  align-items: center;
  gap: .5rem;
  padding: 0 .25rem;
}

.voice-recorder__dot {
  width: .625rem;
  height: .625rem;
  background: var(--danger);
  border-radius: 50%;
  animation: cp-pulse 1.2s ease-in-out infinite;
}

.voice-recorder__time {
  min-width: 2.75rem;
  font-size: .875rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.voice-recorder.is-near-limit .voice-recorder__time { color: var(--warning-text, var(--warning)); }

.voice-recorder__meter {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  gap: clamp(1px, 1%, 2px);
  min-width: 3rem;
  height: 1.75rem;
  overflow: hidden;
}

.voice-recorder__meter > span {
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
  background: var(--accent);
  border-radius: var(--radius-full);
  opacity: .9;
  transform: scaleY(var(--level, .08));
  transition: transform 90ms linear;
}

.voice-recorder--no-meter .voice-recorder__meter > span { transform: scaleY(.08); }

.voice-recorder__message {
  display: none;
  flex: 1 1 auto;
  align-items: center;
  gap: .5rem;
  min-width: 0;
  padding: 0 .25rem;
  font-size: .8125rem;
  line-height: 1.35;
  color: var(--text-muted);
}

.voice-recorder__message-icon { display: none; width: 1rem; height: 1rem; }

.voice-recorder[data-state="idle"] .voice-recorder__dot,
.voice-recorder[data-state="requesting"] .voice-recorder__status,
.voice-recorder[data-state="requesting"] .voice-recorder__meter,
.voice-recorder[data-state="error"] .voice-recorder__status,
.voice-recorder[data-state="error"] .voice-recorder__meter,
.voice-recorder[data-state="error"] .voice-recorder__send {
  display: none;
}

.voice-recorder[data-state="stopping"] .voice-recorder__dot,
.voice-recorder[data-state="done"] .voice-recorder__dot { animation: none; opacity: .4; }

.voice-recorder[data-state="requesting"] .voice-recorder__message,
.voice-recorder[data-state="error"] .voice-recorder__message { display: flex; }

.voice-recorder[data-state="error"] {
  background: var(--danger-soft);
  border-radius: var(--radius-lg);
}

.voice-recorder[data-state="error"] .voice-recorder__message { color: var(--danger-text, var(--danger)); }
.voice-recorder[data-state="error"] .voice-recorder__message-icon { display: block; }

/* --------------------------------------------------------------------------
   7. Muestras de color
   -------------------------------------------------------------------------- */
.color-swatches {
  --cs-size: 1.75rem;
  --cs-gap-color: var(--surface);   /* color del hueco del anillo: el fondo donde se coloca */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
}

.color-swatches__item,
.color-swatches__custom {
  position: relative;
  display: grid;
  flex: none;
  place-items: center;
  width: var(--cs-size);
  height: var(--cs-size);
  padding: 0;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.color-swatches__item {
  color: #fff;
  background: var(--swatch);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .08);
}

.color-swatches__item:hover,
.color-swatches__custom:hover { transform: scale(1.1); }

.color-swatches__item[aria-checked="true"] {
  box-shadow: 0 0 0 2px var(--cs-gap-color), 0 0 0 4px var(--swatch);
}

.color-swatches__item[aria-checked="true"]:hover { transform: none; }

.color-swatches__check {
  width: 58%;
  height: 58%;
  stroke-width: 3;
  opacity: 0;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .3));
  transform: scale(.5);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}

.color-swatches__item[aria-checked="true"] .color-swatches__check { opacity: 1; transform: none; }

.color-swatches__item:focus-visible,
.color-swatches__custom:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 5px;
}

.color-swatches__custom-wrap {
  position: relative;
  display: inline-grid;
}

.color-swatches__custom {
  color: var(--text-muted);
  background: var(--surface-2);
  box-shadow: inset 0 0 0 1.5px var(--border-strong);
}

.color-swatches__custom:hover { color: var(--text); }
.color-swatches__custom .cp-icon { width: 1rem; height: 1rem; }

.color-swatches__native {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  opacity: 0;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   9. Editor de recorte (image-cropper.js · SPEC §9.10)
   Va por encima de los modales de la app (el z-index lo pone el JS). La máscara fuera del recorte
   es un oscurecido fijo, como el visor: tiene que verse igual sobre cualquier foto y en ambos temas.
   -------------------------------------------------------------------------- */
.image-cropper {
  --ic-mask: rgba(10, 12, 16, .58);
  --ic-frame: rgba(255, 255, 255, .9);
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-modal) + 20);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: var(--overlay);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  font-family: var(--font-sans);
  color: var(--text);
  animation: cp-fade-in var(--dur-in) var(--ease);
}
.image-cropper.is-leaving { opacity: 0; transition: opacity 150ms var(--ease); pointer-events: none; }
.image-cropper.is-static, .image-cropper.is-static .image-cropper__dialog { animation: none; }
.image-cropper [hidden] { display: none !important; }

.image-cropper__dialog {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 27rem;
  max-height: calc(100vh - 3rem);
  max-height: calc(100dvh - 3rem);
  overflow: hidden;
  border-radius: var(--radius-xl);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  outline: none;
  animation: cp-pop-in var(--dur-in) var(--ease);
}
:root[data-theme="dark"] .image-cropper__dialog { box-shadow: var(--shadow-lg), 0 0 0 1px var(--border); }

.image-cropper__head {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: 1rem .9rem .5rem 1.4rem;
}
.image-cropper__title { flex: 1; min-width: 0; margin: 0; font-size: 1.125rem; font-weight: 650; }

.image-cropper__body {
  display: flex;
  flex-direction: column;
  gap: .75rem;
  min-height: 0;
  padding: .35rem 1.4rem 1.1rem;
  overflow: auto;
  overscroll-behavior: contain;
}

/* Zona de recorte: cuadrada, con damero para ver la transparencia */
.image-cropper__stage {
  position: relative;
  align-self: center;
  width: min(100%, 22rem, 46vh);
  width: min(100%, 22rem, 46dvh);
  aspect-ratio: 1;
  flex: none;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background-color: var(--surface-2);
  background-image: conic-gradient(var(--surface-3) 25%, transparent 0 50%, var(--surface-3) 0 75%, transparent 0);
  background-size: 1rem 1rem;
  cursor: grab;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  outline: none;
}
.image-cropper__stage.is-dragging { cursor: grabbing; }
.image-cropper__stage.is-failed { cursor: default; }
.image-cropper__stage:focus-visible { box-shadow: var(--focus-ring); }
.image-cropper__canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

.image-cropper__window {
  position: absolute;
  inset: 1.25rem;
  overflow: hidden;
  pointer-events: none;
  box-shadow: 0 0 0 200vmax var(--ic-mask);
  outline: 2px solid var(--ic-frame);
  outline-offset: 0;
}
.image-cropper__window.is-rounded { border-radius: 30%; }
.image-cropper__window.is-circle { border-radius: 50%; }
.image-cropper__stage:not(.is-ready) .image-cropper__window { opacity: 0; }
/* Rejilla de tercios mientras se arrastra */
.image-cropper__grid {
  position: absolute;
  inset: 0;
  opacity: 0;
  background:
    linear-gradient(to right, transparent calc(100% / 3 - .5px), rgba(255, 255, 255, .55) calc(100% / 3 - .5px) calc(100% / 3 + .5px), transparent calc(100% / 3 + .5px) calc(200% / 3 - .5px), rgba(255, 255, 255, .55) calc(200% / 3 - .5px) calc(200% / 3 + .5px), transparent calc(200% / 3 + .5px)),
    linear-gradient(to bottom, transparent calc(100% / 3 - .5px), rgba(255, 255, 255, .55) calc(100% / 3 - .5px) calc(100% / 3 + .5px), transparent calc(100% / 3 + .5px) calc(200% / 3 - .5px), rgba(255, 255, 255, .55) calc(200% / 3 - .5px) calc(200% / 3 + .5px), transparent calc(200% / 3 + .5px));
  transition: opacity var(--dur) var(--ease);
}
.image-cropper__stage.is-dragging .image-cropper__grid { opacity: 1; }

.image-cropper__loading {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  color: var(--text-muted);
  font-size: .875rem;
}
.image-cropper__spinner {
  width: 1.75rem;
  height: 1.75rem;
  border: 2.5px solid var(--border-strong);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: cp-spin .8s linear infinite;
}

.image-cropper__hint { margin: 0; color: var(--text-muted); font-size: .8125rem; line-height: 1.45; text-align: center; }

/* Herramientas: zoom, girar y restablecer */
.image-cropper__tools { display: flex; flex-direction: column; gap: .5rem; }
.image-cropper__zoom-row { display: flex; align-items: center; gap: .4rem; }
.image-cropper__tool-buttons { display: flex; flex-wrap: wrap; justify-content: center; gap: .35rem; }

.image-cropper__zoom {
  --fill: 0%;
  flex: 1;
  min-width: 0;
  height: 1.5rem;
  margin: 0;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  cursor: pointer;
}
.image-cropper__zoom::-webkit-slider-runnable-track {
  height: .375rem;
  border-radius: var(--radius-full);
  background: linear-gradient(to right, var(--accent) var(--fill), var(--surface-3) var(--fill));
}
.image-cropper__zoom::-moz-range-track { height: .375rem; border-radius: var(--radius-full); background: var(--surface-3); }
.image-cropper__zoom::-moz-range-progress { height: .375rem; border-radius: var(--radius-full); background: var(--accent); }
.image-cropper__zoom::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 1.15rem;
  height: 1.15rem;
  margin-top: -.39rem;
  border: 2px solid var(--accent);
  border-radius: 50%;
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}
.image-cropper__zoom::-moz-range-thumb {
  width: 1.15rem;
  height: 1.15rem;
  border: 2px solid var(--accent);
  border-radius: 50%;
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}
.image-cropper__zoom:focus-visible { outline: none; }
.image-cropper__zoom:focus-visible::-webkit-slider-thumb { box-shadow: var(--focus-ring); }
.image-cropper__zoom:focus-visible::-moz-range-thumb { box-shadow: var(--focus-ring); }
.image-cropper__zoom:disabled { opacity: .5; cursor: default; }

/* Botones */
.image-cropper__icon-btn,
.image-cropper__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  flex: none;
  border: 1px solid transparent;
  background: none;
  color: var(--text-muted);
  font: inherit;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.image-cropper__icon-btn { width: 2.25rem; height: 2.25rem; padding: 0; border-radius: var(--radius-full); }
.image-cropper__icon-btn .cp-icon { width: 1.15rem; height: 1.15rem; }
.image-cropper__icon-btn:hover:not(:disabled) { background: var(--surface-2); color: var(--text); }
.image-cropper__btn {
  min-height: 2.375rem;
  padding: 0 1rem;
  border-color: var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font-size: .9rem;
  font-weight: 600;
}
.image-cropper__btn .cp-icon { width: 1.05rem; height: 1.05rem; }
.image-cropper__btn:hover:not(:disabled) { background: var(--surface-2); }
.image-cropper__btn--ghost { min-height: 2.125rem; padding: 0 .75rem; border-color: transparent; background: none; color: var(--text-muted); font-size: .85rem; }
.image-cropper__btn--ghost:hover:not(:disabled) { color: var(--text); }
.image-cropper__btn--primary { border-color: transparent; background: var(--accent); color: var(--accent-contrast); }
.image-cropper__btn--primary:hover:not(:disabled) { background: var(--accent-hover); }
.image-cropper__btn.is-busy { cursor: progress; }
.image-cropper__btn:disabled,
.image-cropper__icon-btn:disabled { opacity: .5; cursor: default; }
.image-cropper__btn:focus-visible,
.image-cropper__icon-btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }

/* Vista previa del resultado */
.image-cropper__result {
  display: flex;
  align-items: center;
  gap: .9rem;
  padding: .65rem .8rem;
  border-radius: var(--radius);
  background: var(--surface-2);
}
.image-cropper__previews { display: flex; align-items: flex-end; gap: .6rem; flex: none; }
.image-cropper__preview {
  display: block;
  width: 4rem;
  height: 4rem;
  background-color: var(--surface);
  background-image: conic-gradient(var(--surface-3) 25%, transparent 0 50%, var(--surface-3) 0 75%, transparent 0);
  background-size: .5rem .5rem;
  box-shadow: 0 0 0 1px var(--border);
}
.image-cropper__preview.is-small { width: 1.75rem; height: 1.75rem; }
.image-cropper__preview.is-rounded { border-radius: 30%; }
.image-cropper__preview.is-circle { border-radius: 50%; }
.image-cropper__result-text { min-width: 0; }
.image-cropper__result-title { margin: 0; font-size: .875rem; font-weight: 600; }
.image-cropper__size { margin: .15rem 0 0; color: var(--text-muted); font-size: .8rem; line-height: 1.4; }

.image-cropper__error {
  display: flex;
  align-items: flex-start;
  gap: .5rem;
  padding: .65rem .8rem;
  border-radius: var(--radius);
  background: var(--danger-soft);
  color: var(--danger-text);
  font-size: .875rem;
  line-height: 1.45;
}
.image-cropper__error .cp-icon { width: 1.1rem; height: 1.1rem; margin-top: .1rem; }

.image-cropper__foot {
  display: flex;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: .5rem;
  padding: .85rem 1.4rem;
  border-top: 1px solid var(--border);
}

@media (max-width: 640px) {
  .image-cropper { align-items: flex-end; padding: .75rem; }
  .image-cropper__dialog { max-height: calc(100dvh - 1.5rem); }
  .image-cropper__head { padding: .9rem .6rem .4rem 1.1rem; }
  .image-cropper__body { padding: .3rem 1.1rem 1rem; }
  .image-cropper__foot { padding: .75rem 1.1rem; }
  .image-cropper__foot .image-cropper__btn { flex: 1 1 0; }
  .image-cropper__hint { display: none; }
}

/* --------------------------------------------------------------------------
   8. Movimiento reducido
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .emoji-popover,
  .emoji-popover-backdrop,
  .lightbox,
  .tag-input__suggestions,
  .file-drop-overlay,
  .file-drop-overlay__icon,
  .tag-input.is-limit .tag-input__control,
  .tag-input__chip.is-flash {
    animation: none;
  }

  .lightbox__img.is-smooth,
  .emoji-picker__emoji,
  .color-swatches__item,
  .color-swatches__check,
  .voice-recorder__meter > span {
    transition: none;
  }

  .voice-recorder__dot { animation-duration: 2.4s; }

  .image-cropper,
  .image-cropper__dialog { animation: none; }
  .image-cropper__grid { transition: none; }
}

/* ==========================================================================
   «Acerca de» y «Licencias de terceros» (about-dialog.js, SPEC §40)
   ========================================================================== */
.about { display: flex; flex-direction: column; align-items: center; gap: 0.35rem; text-align: center; padding: 0.25rem 0 0.5rem; }
.about-logo { width: 72px; height: 72px; border-radius: 18px; margin-bottom: 0.35rem; }
.about-name { margin: 0; font-size: 1.25rem; font-weight: 700; }
.about-tagline { margin: 0; color: var(--text-muted); max-width: 30ch; }
.about-meta { margin: 0.25rem 0 0; font-size: 0.8125rem; color: var(--text-subtle); font-variant-numeric: tabular-nums; }
.about-credits { margin: 0.75rem 0 0.35rem; font-size: 0.875rem; color: var(--text-muted); max-width: 34ch; }

.licenses { display: flex; flex-direction: column; gap: 1.25rem; }
.licenses-intro, .licenses-footer { margin: 0; color: var(--text-muted); font-size: 0.9rem; }
.licenses-group-title { margin: 0 0 0.25rem; font-size: 0.8125rem; font-weight: 650; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); }
.licenses-note { margin: 0 0 0.5rem; font-size: 0.8125rem; color: var(--text-subtle); }
.licenses-list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.licenses-item { padding: 0.6rem 0.85rem; }
.licenses-item + .licenses-item { border-top: 1px solid var(--border); }
.licenses-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 0.5rem; }
.licenses-name { font-weight: 600; color: var(--text); }
a.licenses-name:hover { text-decoration: underline; }
.licenses-version { font-size: 0.8125rem; color: var(--text-subtle); font-variant-numeric: tabular-nums; }
.licenses-badge { margin-left: auto; padding: 0.05rem 0.5rem; border-radius: 999px; background: var(--surface-2); font-size: 0.75rem; font-weight: 600; color: var(--text-muted); white-space: nowrap; }
.licenses-use, .licenses-copy { margin: 0.15rem 0 0; font-size: 0.8125rem; color: var(--text-muted); overflow-wrap: anywhere; }
.licenses-details { margin-top: 0.3rem; font-size: 0.8125rem; }
.licenses-details > summary { cursor: pointer; color: var(--accent-text, var(--accent)); width: max-content; }
.licenses-text { margin: 0.4rem 0 0; max-height: 16rem; overflow: auto; padding: 0.6rem 0.75rem; border-radius: var(--radius-sm); background: var(--surface-2); font-size: 0.75rem; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
.licenses-error { margin: 0; color: var(--text-muted); }

/* «Política de privacidad» y «Términos de uso» (about-dialog.js openLegalDialog, SPEC §45) */
.legal-doc { max-width: 46rem; color: var(--text); font-size: 0.9375rem; line-height: 1.55; }
.legal-doc h3 { margin: 1.4rem 0 0.4rem; font-size: 1rem; }
.legal-doc h3:first-child { margin-top: 0.2rem; }
.legal-doc p, .legal-doc ul { margin: 0 0 0.7rem; }
.legal-doc ul { padding-left: 1.3rem; }
.legal-doc li { margin: 0.2rem 0; }
.legal-doc .legal-meta { color: var(--text-subtle); font-size: 0.8125rem; }
.legal-doc .legal-draft { padding: 0.55rem 0.75rem; border-radius: var(--radius); background: var(--surface-2); color: var(--text-muted); font-size: 0.8125rem; }
.legal-doc a { color: var(--accent-text); }
.legal-missing { color: #b45309; font-style: italic; }
:root[data-theme="dark"] .legal-missing { color: var(--warning-text); }   /* el de arriba, 2,5:1 en oscuro; este ≥ 7,8:1 */

/* «Borrar mi cuenta» (settings-dialog.js, SPEC §48) */
.settings-actions-start { justify-content: flex-start; flex-wrap: wrap; gap: 0.5rem; }
.delete-account { display: flex; flex-direction: column; gap: 0.85rem; }
.delete-account .form-alert p { margin: 0; }
.delete-account .form-alert p + p { margin-top: 0.4rem; }
.delete-account-list { margin: 0; padding-left: 1.2rem; color: var(--text-muted); font-size: 0.9rem; }
.delete-account-list li + li { margin-top: 0.3rem; }
.delete-account-also { display: flex; align-items: flex-start; gap: 0.6rem; padding: 0.6rem 0.7rem; border: 1px solid var(--border); border-radius: var(--radius); cursor: pointer; }
.delete-account-also > span { display: flex; flex-direction: column; gap: 0.15rem; }
.delete-account-also.is-disabled { opacity: 0.6; cursor: default; }
.delete-account-download { margin: 0; color: var(--text-muted); font-size: 0.875rem; }
