:root {
  /* Paleta actualizada -- --bg, --line,
         --user-bubble, --ok y --warn cambian de valor; el resto de
         esta lista (--panel, --ink, --ink-soft, --accent, --accent-ink,
         --assistant-bubble, y las --cover-* de más abajo) se quedan
         igual, el usuario las repasó una a una y coinciden. */
  --bg: #fff9f0;
  --panel: #ffffff;
  --ink: #1c1a17;
  --ink-soft: #6b6459;
  --line: #fff3e0;
  --accent: #1c1a17;
  --accent-ink: #ffffff;
  --user-bubble: #fff3e0;
  --assistant-bubble: #ffffff;
  --ok: #20ad53;
  --warn: #ff6329;

  /* Paleta/tipografía de la interfaz nueva
       (diseño en Figma, frame "Inicio") — variables aparte de las de
       arriba a propósito: las de arriba las siguen usando el resto de
       pantallas (login, revisar respuesta, mis proyectos, elegir
       color...), que NO se tocan en este cambio; reutilizarlas aquí
       habría cambiado también su aspecto sin que el usuario lo pidiera.
       --cover-* son solo el valor por defecto antes de que cargue el
       color real de la sesión — updateCoverCard() lo sobrescribe inline
       en cuanto se conoce (ver más abajo, cover_color por sesión). */
  --cover-contrast: #343232;
  --cover-cream: #fff9f0;
  --cover-peach: #fff3e0;
  --cover-hint: #9e8788;
  --font-display: "Cormorant Garamond", Georgia, serif;
  --font-ui: "Jost", "Helvetica Neue", Arial, sans-serif;
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

/* Letra un poco más grande en toda la
       aplicación, a petición directa -- 110% del tamaño base del
       navegador. Puesto en <html> y no en <body>: casi todos los
       tamaños de esta hoja están en "rem", que siempre se calcula
       sobre el tamaño de letra de <html> (la raíz del documento),
       no el de <body> -- poniéndolo solo en body, la letra de casi
       todo (botones, textareas, menús...) se habría quedado igual. */
html {
  font-size: 110%;
}

body {
  margin: 0;
  font-family: "Cormorant Garamond", Georgia, serif;
  background: #fff;
  color: var(--ink);
  display: flex;
  flex-direction: column;
}

/* --- Cabecera ------------------------------------------- */
#app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0;
  padding: 18px 40px;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-ui);
  flex-wrap: wrap;
}

.header-side {
  display: flex;
  align-items: center;
  gap: 28px;
  flex: 30%;
}

.header-right {
  flex-direction: row-reverse;
}

.header-link {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--cover-contrast);
  text-decoration: none;
  font-size: 0.85rem;
}

.header-link:hover {
  opacity: 0.7;
}

.header-link svg {
  display: block;
  flex-shrink: 0;
}

.icon-badge {
  width: 20px;
  height: 27px;
  border-radius: 1px 4px 4px 1px;
  background: var(--cover-contrast);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

/* Bug real reportado por el usuario: el
       enlace de administración le aparecía a CUALQUIER cuenta, no solo
       a la id 1 -- mismo motivo exacto que el aviso de más
       abajo (#kit-stream-status[hidden]) y el de
       (#work-chat-formula-pill[hidden]): el `display: flex` fijo de
       `.icon-badge`/`.icon-circle` (dos líneas más abajo) gana en
       especificidad al `[hidden] { display: none }` del navegador, así
       que `linkAdminUsers.hidden = true` (JS, ver renderUserBadge en
       app.js) dejaba de tener efecto real. Con esta regla, más
       específica (id + atributo), el estado oculto vuelve a ganar --
       la comprobación real de todos modos siempre ha sido el 403 del
       servidor (`_require_admin` en main.py); esto es solo para no
       enseñar un botón que cualquier otra cuenta no puede usar. */
#link-admin-users[hidden] {
  display: none;
}

#header-logo {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.7rem;
  letter-spacing: 0.02em;
  color: var(--ink);
  margin: 0;
}

#user-badge {
  font-size: 0.85rem;
  color: var(--ink);
}

#link-logout.icon-circle {
  width: 33px;
  height: 27px;
  border-radius: 5px;
  background: var(--cover-contrast);
}

/* --- Portada + panel de la pregunta activa -------------------------- */
#main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  align-items: center;
  padding: 0 24px 32px;
}

.hero {
  width: 100%;
  max-width: 900px;
  position: relative;
  margin-top: 44px;
}

.cover-icons {
  position: absolute;
  right: 0;
  z-index: 3;
}

.icon-circle {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}

.icon-circle-accent {
  background: var(--cover-accent, #38ad1b);
}

.icon-circle-dark {
  width: 34px;
  height: 34px;
  align-self: flex-end;
  background: var(--cover-contrast);
  text-decoration: none;
  margin: 10px auto;
}

.icon-circle:hover {
  opacity: 0.85;
}

.cover-card {
  position: relative;
  z-index: 2;
  background: var(--cover-accent, #38ad1b);
  border-radius: 10px 10px 0 0;
  padding: 40px 32px 56px;
  text-align: center;
  margin: 0 10vh;
}

#cover-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.4rem, 3vw, 2rem);
  color: var(--cover-title-fg, var(--cover-contrast));
  margin: 0 auto 0;
  display: inline-block;
  min-width: 55%;
  padding-bottom: 14px;
  background-image:
    linear-gradient(currentColor, currentColor),
    linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-size:
    100% 1px,
    100% 1px;
  background-position:
    top 32px center,
    bottom 20px center;
}

#cover-title.placeholder {
  opacity: 0.75;
}

.qa-panel {
  background: var(--cover-cream);
  border-radius: 10px;
  padding: 40px;
  display: flex;
  flex-direction: column;
  min-height: 260px;
}

#q-progress {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  font-family: var(--font-ui);
}

#q-progress-label {
  font-size: 0.95rem;
  color: var(--ink);
  min-width: 4.5em;
  text-align: center;
}

.q-nav-btn {
  border: none;
  background: none;
  color: var(--ink);
  font-family: var(--font-ui);
  font-weight: 200;
  width: 30px;
  height: 30px;
  padding: 0;
  font-size: 1.7rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.q-nav-btn:disabled {
  opacity: 0.25;
  cursor: default;
}

.q-nav-btn:hover:not(:disabled) {
  opacity: 0.6;
}

#q-meta {
  display: none;
}

/* dato de depuración (id · página), no forma parte de este diseño */
#q-text {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2.4vw, 1.5rem);
  text-align: center;
  margin: 22px auto 0;
  max-width: 46em;
  line-height: 1.3;
}

#q09-hint {
  font-family: var(--font-ui);
  font-size: 0.82rem;
  color: var(--cover-hint);
  margin-top: 14px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  justify-content: center;
}

#q09-hint span {
  white-space: nowrap;
}

/* Colaboración: aviso de que otra persona
       tiene esta pregunta abierta ahora mismo -- ver showQuestion() en
       el script. Usa el mismo color de acento del
       proyecto que .cover-card (--cover-accent) y el mismo criterio de
       contraste que el título (--cover-title-fg), en vez de un peach fijo,
       para que siga el color elegido en cada proyecto -- ver
       applyCoverColor() en el script. */
#q-lock-banner {
  margin: 14px auto 0;
  max-width: 46em;
  text-align: center;
  font-family: var(--font-ui);
  font-size: 0.85rem;
  color: var(--cover-title-fg, var(--cover-contrast));
  background: var(--cover-accent, #38ad1b);
  border-radius: 8px;
  padding: 10px 16px;
}

/* Bug real reportado por el usuario: #chat no
       tenía altura acotada, así que una conversación larga estiraba
       .qa-panel/#main entero -- y como .workspace-page (el ancestro,
       #workspace-chat) es el único con overflow-y:auto, navegar entre
       preguntas acababa haciendo scroll de LA PÁGINA COMPLETA (cabecera,
       portada, composer incluidos) en vez de solo del propio chat.
       max-height + overflow-y:auto propio hace que solo esta zona se
       desplace -- portada, pregunta y campo de respuesta se quedan
       siempre a la vista. chatScrollEl (ver script) pasa a apuntar a
       este mismo div en vez de a #workspace-chat, para que el
       autoscroll al llegar un mensaje nuevo baje DENTRO de esta caja. */
#chat {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 26px;
  max-height: 46vh;
  overflow-y: auto;
  padding-right: 6px;
}

/* min-width: 0, bug real reportado por el
       usuario: un prompt de imagen es típicamente UNA línea larga sin
       saltos -- dentro de un <pre> (white-space por defecto del
       navegador), esa línea no se parte, y como .bubble-wrap/.bubble
       son elementos flex, sin min-width:0 un hijo no puede encogerse
       por debajo del ancho de su propio contenido (min-width:auto es
       el valor por defecto de un flex item) -- así que en vez de
       quedarse dentro de sus 640px y hacer scroll horizontal (que es
       lo que se pretendía con overflow-x:auto en .bubble.assistant
       pre), toda la burbuja empujaba el ancho de la conversación entera
       y se salía de la interfaz. Con min-width:0 aquí, el <pre> ya
       puede rendirse: ver el white-space:pre-wrap añadido en
       .bubble.assistant pre más abajo, que además parte la línea en
       vez de solo scrollear. */
.bubble-wrap {
  display: flex;
  flex-direction: column;
  max-width: 640px;
  min-width: 0;
}

.bubble-wrap.user {
  align-self: flex-end;
  align-items: flex-end;
}

.bubble-wrap.assistant {
  align-self: flex-start;
  align-items: flex-start;
}

.bubble {
  padding: 18px 22px;
  border-radius: 10px;
  line-height: 1.5;
  white-space: pre-wrap;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.1rem;
  min-width: 0; /* ver el comentario en .bubble-wrap más arriba */
}

.bubble.assistant {
  background: var(--cover-peach);
}

/* Petición explícita del usuario: el aviso de
       "esperando respuesta" era un texto pequeño debajo del campo y
       pasaba desapercibido -- ahora es esta burbuja (ver addTypingBubble
       en app.js), en el propio hilo de la conversación y justo donde va
       a aparecer la respuesta real, mucho más evidente. */
.bubble.typing {
  display: flex;
  align-items: center;
  padding: 20px 24px;
}

.typing-dots {
  display: inline-flex;
  gap: 7px;
}

.typing-dots span {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--cover-contrast);
  opacity: 0.35;
  animation: typing-bounce 1.2s infinite ease-in-out;
}

.typing-dots span:nth-child(2) {
  animation-delay: 0.2s;
}

.typing-dots span:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes typing-bounce {
  0%,
  80%,
  100% {
    transform: translateY(0);
    opacity: 0.35;
  }

  40% {
    transform: translateY(-5px);
    opacity: 1;
  }
}

/* Bug real reportado por el usuario: las
       respuestas del Centinela en el chat de trabajo llegan en
       Markdown (**negrita**, encabezados con #...) pero se pintaban
       como texto plano -- salían los símbolos literales. Se
       renderizan ahora con la misma renderMarkdown() que ya usa el
       Mapa (ver addWorkChatBubble en app.js), así que hacen falta
       estilos mínimos para sus etiquetas dentro de la burbuja.
       Deliberadamente más discretos que los de #kit-content -- esto es
       una burbuja de chat, no un documento completo. Solo aplica a
       .bubble.assistant: los mensajes del usuario siguen en texto
       plano tal cual los escribe la persona, así que estas reglas no
       tienen nada que afectar ahí. */
.bubble.assistant p {
  margin: 0 0 0.6em;
}

.bubble.assistant p:last-child {
  margin-bottom: 0;
}

.bubble.assistant h1,
.bubble.assistant h2,
.bubble.assistant h3 {
  font-style: normal;
  margin: 0.8em 0 0.4em;
}

.bubble.assistant h1:first-child,
.bubble.assistant h2:first-child,
.bubble.assistant h3:first-child {
  margin-top: 0;
}

.bubble.assistant ul {
  margin: 0 0 0.6em;
  padding-left: 20px;
}

.bubble.assistant ul:last-child {
  margin-bottom: 0;
}

.bubble.assistant code {
  font-family: "SFMono-Regular", Consolas, monospace;
  font-style: normal;
  background: rgba(0, 0, 0, 0.06);
  padding: 1px 4px;
  border-radius: 3px;
  font-size: 0.85em;
}

/* Bug real reportado por el usuario: un
       prompt de imagen es típicamente una única línea larga sin
       saltos -- con el overflow-x:auto de antes (pensado para bloques
       de código con saltos de línea reales) esa línea no se partía y
       se salía de la interfaz (ver también min-width:0 en .bubble/
       .bubble-wrap más arriba, la otra mitad de esta misma corrección).
       pre-wrap + overflow-wrap la parte donde haga falta, como
       cualquier párrafo normal, en vez de obligar a hacer scroll
       horizontal dentro de la burbuja. */
.bubble.assistant pre {
  background: rgba(0, 0, 0, 0.06);
  padding: 10px 12px;
  border-radius: 6px;
  margin: 0 0 0.6em;
  max-width: 100%;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  word-break: break-word;
  box-sizing: border-box;
}

.bubble.assistant pre code {
  background: none;
  padding: 0;
}

.bubble.assistant table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 0.6em;
  font-size: 0.85em;
  font-style: normal;
}

.bubble.assistant th,
.bubble.assistant td {
  border: 1px solid rgba(0, 0, 0, 0.15);
  padding: 4px 8px;
  text-align: left;
}

.bubble.assistant blockquote {
  margin: 0 0 0.6em;
  padding: 6px 12px;
  border-left: 3px solid var(--cover-accent, #38ad1b);
  font-style: normal;
}

.bubble.assistant hr {
  border: none;
  border-top: 1px solid rgba(0, 0, 0, 0.15);
  margin: 0.8em 0;
}

.bubble.user {
  background: #ffffff;
}

.bubble.system {
  align-self: flex-start;
  background: var(--cover-peach);
  color: var(--cover-hint);
  font-family: var(--font-display);
  font-style: italic;
  font-size: 0.95rem;
}

.suggestion-actions {
  display: flex;
  gap: 8px;
  margin-top: 10px;
  font-family: var(--font-ui);
}

.suggestion-actions button {
  font-size: 0.82rem;
  padding: 7px 14px;
  border-radius: 20px;
  border: 1px solid var(--cover-contrast);
  background: transparent;
  color: var(--cover-contrast);
  cursor: pointer;
}

.suggestion-actions button.primary {
  background: var(--cover-contrast);
  color: #fff;
}

.suggestion-actions button:hover:not(:disabled) {
  opacity: 0.8;
}

/* --- Campo de respuesta --------------------------------------------- */
#composer {
  width: 100%;
  max-width: 900px;
  margin: 28px auto 0;
  font-family: var(--font-ui);
}

.composer-input-row {
  display: flex;
  align-items: stretch;
  gap: 18px;
}

/* Agrupa dictado + enviar para que se comporten como una
       unidad al lado de la textarea (y, en columna en móvil, como una
       fila propia debajo de ella en vez de apilarse los tres sueltos). */
.composer-buttons {
  display: flex;
  gap: 18px;
  flex-shrink: 0;
}

#composer textarea {
  flex: 1;
  min-height: 96px;
  /* Antes "resize: vertical" (arrastrar a
         mano); ahora la caja crece sola con lo que se escribe (ver
         autoGrowTextarea en app.js) -- dejar el arrastre manual a la
         vez confundiría, porque el siguiente carácter que se escriba
         volvería a fijar la altura calculada, deshaciendo el ajuste a
         mano. overflow-y:hidden es el estado de reposo (nada que
         desbordar todavía); el propio JS lo cambia a "auto" solo si el
         texto llega a su altura máxima. */
  resize: none;
  overflow-y: hidden;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.1rem;
  padding: 18px 22px;
  border: none;
  border-radius: 10px;
  background: var(--cover-cream);
  color: var(--ink);
}

#composer textarea::placeholder {
  color: var(--cover-hint);
  opacity: 1;
}

/* Campo deshabilitado mientras otra persona tiene la
       pregunta bloqueada -- ver showQuestion(). */
#composer textarea:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* Botón de dictado por voz, ver setupDictation()
       en app.js -- usa el reconocimiento de voz nativo del navegador
       (Web Speech API), sin pasar por la API de Anthropic. Mismo botón
       en ambos chats (composer-input-row), tamaño cuadrado a juego con
       la altura mínima de la textarea. Si el navegador no lo soporta
       (p.ej. Firefox de escritorio), setupDictation() lo oculta solo. */
.mic-btn {
  font-family: var(--font-ui);
  font-size: 1.3rem;
  line-height: 1;
  width: 54px;
  flex-shrink: 0;
  border-radius: 10px;
  border: none;
  background: var(--cover-peach);
  color: var(--cover-contrast);
  cursor: pointer;
}

.mic-btn:hover {
  opacity: 0.85;
}

.mic-btn.recording {
  background: var(--warn);
  color: #fff;
  animation: mic-pulse 1.4s ease-in-out infinite;
}

@keyframes mic-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.6;
  }
}

#btn-send {
  font-family: var(--font-ui);
  font-size: 0.9rem;
  padding: 0 34px;
  border-radius: 10px;
  border: none;
  background: var(--cover-contrast);
  color: #fff;
  cursor: pointer;
  flex-shrink: 0;
}

#btn-send:disabled {
  opacity: 0.4;
  cursor: default;
}

#btn-send:hover:not(:disabled) {
  opacity: 0.85;
}

.composer-note {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 14px;
  font-size: 0.82rem;
  color: var(--ink);
}

.composer-note .note-icon {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.3rem;
  line-height: 1;
  color: var(--ink);
}

#status-msg {
  font-size: 0.8rem;
  color: var(--cover-hint);
  margin-top: 10px;
  min-height: 1em;
  font-family: var(--font-ui);
}

/* #project-intro-panel comparte selector con
       #done-panel a propósito -- pedido explícito del usuario, "que se
       vea del mismo modo que cuando has respondido todas las
       preguntas". Un único juego de reglas para los dos, así nunca
       pueden desincronizarse visualmente. */
#done-panel,
#project-intro-panel {
  display: none;
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  padding: 48px 32px;
  text-align: center;
  background: var(--cover-cream);
  border-radius: 10px;
  font-family: var(--font-ui);
}

#done-panel h2,
#project-intro-panel h2 {
  margin-bottom: 8px;
  font-family: var(--font-display);
  font-weight: 700;
}

#done-panel p,
#project-intro-panel p {
  color: var(--cover-hint);
  margin-bottom: 24px;
}

#done-panel button.primary,
#project-intro-panel button.primary {
  font-family: var(--font-ui);
  border: none;
  border-radius: 10px;
  background: var(--cover-contrast);
  color: #fff;
  padding: 12px 28px;
  cursor: pointer;
}

#done-panel button + button {
  margin-left: 12px;
}

/* --- Kit Centinela --------------------------
     Panel de resultado como "segunda pantalla" junto al chat, con un
     efecto de desplazamiento horizontal para pasar de una a otra (idea
     del usuario) en vez de un modal que tape la conversación. #workspace
     medía el doble del ancho del viewport y contenía dos páginas al 50%
     cada una; deslizar es solo mover su transform — #workspace-viewport
     recorta lo que no se ve.

     Se añade una TERCERA página (el chat de
     trabajo) con el mismo mecanismo — #workspace pasa de 200%/50% a
     300%/33.3333%, y la clase booleana .showing-kit se convierte en dos
     estados (.showing-kit / .showing-work-chat) que mueve el mismo
     transform un tercio o dos tercios en vez de solo la mitad. */
#workspace-viewport {
  flex: 1;
  overflow: hidden;
  min-width: 0;
}

#workspace {
  display: flex;
  width: 300%;
  height: 100%;
  transition: transform 0.45s cubic-bezier(0.4, 0, 0.2, 1);
}

#workspace.showing-kit {
  transform: translateX(-33.3333%);
}

#workspace.showing-work-chat {
  transform: translateX(-66.6667%);
}

.workspace-page {
  flex: 0 0 33.3333%;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}

#kit-panel {
  background: var(--cover-cream);
  padding: 24px 24px 48px;
}

#kit-panel-header {
  display: flex;
  align-items: center;
  gap: 16px;
  max-width: 760px;
  width: 100%;
  margin: 20px auto 24px;
  font-family: var(--font-ui);
}

#kit-panel-header h2 {
  flex: 1;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.4rem;
}

#kit-panel-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

#kit-panel-actions button {
  font-family: var(--font-ui);
  border: none;
  border-radius: 8px;
  padding: 9px 16px;
  cursor: pointer;
  background: transparent;
  color: var(--ink-soft);
  border: 1px solid var(--line);
}

#kit-panel-actions button.primary {
  background: var(--cover-contrast);
  color: #fff;
  border: none;
}

#kit-content {
  max-width: 760px;
  width: 100%;
  margin: 0 auto;
  background: #fff;
  border-radius: 10px;
  padding: 36px 40px;
  line-height: 1.6;
}

/* Streaming — mientras el kit se está
     escribiendo se ve el texto en crudo, monoespaciado, creciendo en
     tiempo real (sin intentar renderizar Markdown a medias, que
     quedaría roto con una tabla o un bloque de código sin cerrar
     todavía) — en cuanto termina, este bloque se sustituye por
     #kit-content ya con el formato final. */
#kit-stream-live {
  max-width: 760px;
  width: 100%;
  margin: 0 auto;
  background: #fff;
  border-radius: 10px;
  padding: 28px 32px;
  font-family: "SFMono-Regular", Consolas, monospace;
  font-size: 0.85rem;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--ink);
  max-height: 70vh;
  overflow-y: auto;
}

#kit-stream-status {
  max-width: 760px;
  width: 100%;
  margin: 0 auto 16px;
  font-family: var(--font-ui);
  font-size: 0.85rem;
  color: var(--ink-soft);
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Bug real reportado por el usuario: al
       terminar de generar el kit/skill, este aviso ("Generando el
       Skill de Claude…") se quedaba en pantalla aunque el JS pusiera
       `kitStreamStatusEl.hidden = true` en el evento "done" -- el
       `display: flex` fijo de la regla de arriba (necesario para
       alinear el puntito animado con el texto) gana en especificidad
       al `[hidden] { display: none }` que aplica el propio navegador,
       así que el atributo `hidden` dejaba de tener efecto real aquí.
       Con esta regla, más específica (mismo id + atributo), el estado
       oculto vuelve a ganar. Solo recargar la página lo "escondía"
       porque entonces el div vuelve a su innerHTML vacío inicial, no
       porque `hidden` estuviera funcionando. */
#kit-stream-status[hidden] {
  display: none;
}

#kit-stream-status .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--cover-accent, #38ad1b);
  animation: kit-pulse 1.1s ease-in-out infinite;
}

@keyframes kit-pulse {
  0%,
  100% {
    opacity: 0.25;
  }
  50% {
    opacity: 1;
  }
}

#kit-panel-actions button:disabled {
  opacity: 0.5;
  cursor: default;
}

#kit-content h1 {
  font-family: var(--font-display);
  font-size: 1.7rem;
  margin-top: 0;
}

#kit-content h2 {
  font-family: var(--font-display);
  font-size: 1.3rem;
  margin-top: 2em;
  border-top: 1px solid var(--line);
  padding-top: 1em;
}

#kit-content h3 {
  font-size: 1.05rem;
  margin-top: 1.6em;
}

#kit-content blockquote {
  margin: 1em 0;
  padding: 10px 16px;
  border-left: 3px solid var(--cover-accent, #38ad1b);
  background: var(--bg);
  color: var(--ink-soft);
}

#kit-content table {
  width: 100%;
  border-collapse: collapse;
  margin: 1em 0;
  font-size: 0.9rem;
}

#kit-content th,
#kit-content td {
  border: 1px solid var(--line);
  padding: 6px 10px;
  text-align: left;
}

#kit-content pre {
  background: var(--bg);
  padding: 12px 14px;
  border-radius: 6px;
  overflow-x: auto;
  font-size: 0.85rem;
}

#kit-content hr {
  border: none;
  border-top: 1px solid var(--line);
  margin: 2em 0;
}

#kit-readiness-body ul {
  padding-left: 20px;
  margin: 10px 0 0;
}

#kit-readiness-body li {
  margin-bottom: 4px;
}

#kit-readiness-body .actions {
  display: flex;
  gap: 10px;
  margin-top: 18px;
  justify-content: flex-end;
}

#kit-readiness-body button.primary {
  font-family: var(--font-ui);
  border: none;
  border-radius: 8px;
  background: var(--cover-contrast);
  color: #fff;
  padding: 10px 20px;
  cursor: pointer;
}

#kit-readiness-body button.secondary {
  font-family: var(--font-ui);
  border: 1px solid var(--line);
  border-radius: 8px;
  background: transparent;
  color: var(--ink);
  padding: 10px 20px;
  cursor: pointer;
}

@media (max-width: 720px) {
  #kit-panel-header {
    flex-wrap: wrap;
  }

  #kit-content {
    padding: 24px 20px;
  }
}

/* --- Chat de trabajo --------------------------
       Tercera pantalla del carril deslizante. Mismo fondo/cabecera que
       #kit-panel; el cuerpo se divide en dos columnas: barra lateral fija
       (categorías + lista de conversaciones) y la conversación activa. */
#work-chat-panel {
  background: var(--cover-cream);
  padding: 0;
}

#work-chat-header {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 20px 24px;
  font-family: var(--font-ui);
  flex-shrink: 0;
}

#work-chat-header-text {
  flex: 1;
  min-width: 0;
}

#work-chat-header-eyebrow {
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 2px;
}

#work-chat-header-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.4rem;
}

#work-chat-body {
  flex: 1;
  display: flex;
  min-height: 0;
}

#work-chat-sidebar {
  min-width: 300px;
  max-width: 30%;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--line);
  padding: 0 16px 20px;
  overflow-y: auto;
}

#work-chat-categories {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-bottom: 16px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-ui);
}

#work-chat-categories button {
  text-align: left;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  color: var(--ink);
  padding: 10px 12px;
  font-size: 0.85rem;
  cursor: pointer;
}

#work-chat-categories button:hover {
  border-color: var(--cover-contrast);
}

#work-chat-list {
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--font-ui);
}

#work-chat-list li {
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 4px;
  cursor: pointer;
  font-size: 0.85rem;
  display: flex;
  align-items: center;
  gap: 8px;
}

#work-chat-list li:hover {
  background: var(--cover-peach);
}

#work-chat-list li.active {
  background: var(--cover-contrast);
  color: #fff;
}

/* Envuelve título+etiqueta para poder poner
       el botón de borrar (ver .wc-delete más abajo) al lado, en vez de
       debajo -- min-width:0 es lo que permite que el título largo se
       trunque con "..." en vez de empujar el botón fuera de la barra
       lateral (ver overflow/text-overflow en .wc-title). */
#work-chat-list .wc-info {
  flex: 1;
  min-width: 0;
}

#work-chat-list .wc-title {
  font-weight: bold;
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#work-chat-list .wc-meta {
  font-size: 0.75rem;
  opacity: 0.75;
}

/* Pedido explícito del usuario -- hasta ahora no había
       forma de borrar una conversación desde la interfaz (el endpoint
       ya existía, ver DELETE /api/sessions/{sid}/chats/{cid} en
       main.py, solo le faltaba un botón). `color: inherit` a propósito
       -- así hereda el blanco de .active sin necesitar una regla
       aparte para ese caso. */
#work-chat-list .wc-delete {
  flex: none;
  font-family: var(--font-ui);
  font-size: 0.8rem;
  line-height: 1;
  border: none;
  background: transparent;
  color: inherit;
  opacity: 0.5;
  cursor: pointer;
  padding: 4px 7px;
  border-radius: 5px;
}

#work-chat-list .wc-delete:hover {
  opacity: 1;
  background: rgba(0, 0, 0, 0.08);
}

#work-chat-list li.active .wc-delete:hover {
  background: rgba(255, 255, 255, 0.18);
}

#work-chat-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* Corrección estética (petición del usuario): antes ocupaba flex:1
       centrado en toda la columna (medio alto de pantalla para una sola
       frase). Ahora se comporta igual que el aviso ".bubble.system" del
       chat de preguntas (ver addBubble('system', ...) en app.js) --
       arriba, del tamaño de su propio texto, mismo padding que el resto
       de la conversación. */
#work-chat-empty {
  padding: 20px 28px 0;
}

/* Secuencia de carga artificial al crear una
       conversación -- pedido explícito del usuario para "poner en
       valor" lo que hace el chat al prepararse, pintando cada paso en
       pantalla de forma sucesiva (ver playWorkChatLoadingSequence() en
       app.js) en vez de abrir la conversación al instante. Mismo
       padding que #work-chat-empty a propósito, para que no haya salto
       visual entre uno y otro. */
#work-chat-loading {
  padding: 20px 28px 0;
}

/* Mini-formulario de "Preparar un encargo" --
       mismo padding que #work-chat-empty/#work-chat-loading a propósito,
       para que no haya salto visual entre las tres vistas. */
#work-chat-encargo-form {
  padding: 20px 28px 0;
}

#encargo-form-body {
  max-width: 520px;
  margin-top: 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

#encargo-form-text {
  min-height: 110px;
  resize: none;
  overflow-y: hidden;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.05rem;
  padding: 16px 20px;
  border: none;
  border-radius: 10px;
  background: #fff;
  color: var(--ink);
}

#encargo-audience-row {
  display: flex;
  gap: 8px;
  font-family: var(--font-ui);
}

.encargo-audience-btn {
  flex: 1;
  text-align: center;
  font-size: 0.85rem;
}

#btn-encargo-form-create {
  align-self: flex-start;
  font-family: var(--font-ui);
  font-size: 0.9rem;
  padding: 10px 34px;
  border-radius: 10px;
  border: none;
  background: var(--cover-contrast);
  color: #fff;
  cursor: pointer;
}

#encargo-form-status {
  font-size: 0.82rem;
  color: var(--ink-soft);
  min-height: 1.2em;
}

#work-chat-loading-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

#work-chat-loading-steps li {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-ui);
  font-size: 0.85rem;
  color: var(--ink-soft);
  opacity: 0;
  animation: wc-loading-step-in 0.25s ease-out forwards;
}

#work-chat-loading-steps .wc-step-icon {
  width: 14px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  font-size: 0.8rem;
  color: var(--cover-accent, #38ad1b);
}

#work-chat-loading-steps .wc-step-icon .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--cover-accent, #38ad1b);
  animation: kit-pulse 1.1s ease-in-out infinite;
}

/* El paso ya completado pasa de punto pulsante a "✓" (ver
       markWorkChatStepDone() en app.js) y de color atenuado a color de
       texto normal, para distinguir de un vistazo lo ya hecho de lo que
       está en marcha ahora mismo. */
#work-chat-loading-steps li.wc-step-done {
  color: var(--ink);
}

@keyframes wc-loading-step-in {
  from {
    opacity: 0;
    transform: translateY(4px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

#work-chat-conversation {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 20px 28px;
}

/* Bug real detectado al verificar la
       secuencia de carga del chat de trabajo (antes pasaba desapercibido:
       #work-chat-conversation quedaba oculto solo una fracción de
       segundo, entre abrir el panel y pintar la conversación) -- mismo
       problema ya documentado para #kit-stream-status más arriba:
       el `display: flex` fijo de la regla de arriba gana
       en especificidad al `[hidden] { display: none }` del navegador
       (id contra atributo), así que con la conversación oculta más
       tiempo de por medio (mientras se ve la secuencia de pasos) el
       composer (caja de texto + "Enviar") se quedaba asomando por
       detrás. Esta regla, más específica (mismo id + atributo), hace
       que el atributo `hidden` vuelva a ganar. */
#work-chat-conversation[hidden] {
  display: none;
}

#work-chat-messages {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding-bottom: 16px;
}

/* Fila de acciones bajo cada respuesta del
       Centinela -- "Copiar", y 👍/👎 cuando aplica.
       Pedido explícito del usuario: se ha quitado de aquí el
       botón "Aprobar" (bubble-approve) -- no debía convivir con la
       valoración 👍/👎, que cubre el mismo propósito. */
#work-chat-messages .bubble-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  align-self: flex-start;
  margin-top: 6px;
}

#work-chat-messages .bubble-copy {
  font-family: var(--font-ui);
  font-size: 0.78rem;
  border: 1px solid var(--cover-contrast);
  border-radius: 20px;
  padding: 5px 12px;
  background: transparent;
  color: var(--cover-contrast);
  cursor: pointer;
}

#work-chat-messages .bubble-copy:hover {
  opacity: 0.8;
}

/* Botones 👍/👎, en la misma fila de
       acciones, solo para respuestas que vienen de "cuatro caminos" o
       del modo experto (ver ratable en app.js). */
#work-chat-messages .bubble-rate {
  display: inline-flex;
  gap: 4px;
}

#work-chat-messages .bubble-rate-btn {
  font-size: 0.95rem;
  line-height: 1;
  border: 1px solid var(--cover-contrast);
  border-radius: 20px;
  padding: 4px 10px;
  background: transparent;
  color: var(--cover-contrast);
  cursor: pointer;
  opacity: 0.55;
}

#work-chat-messages .bubble-rate-btn:hover:not(:disabled) {
  opacity: 0.85;
}

#work-chat-messages .bubble-rate-btn.active {
  border-color: var(--cover-contrast);
  background: var(--cover-contrast);
  opacity: 1;
}

#work-chat-messages .bubble-rate-btn:disabled {
  cursor: default;
}

/* Tarjetas de "cuatro caminos" -- solo título + muestra,
       ver renderPathCards() en app.js. Reutiliza el ancho de las
       burbujas del asistente (misma columna), en grid de 2 por fila en
       pantallas normales y 1 sola en móvil (media query más abajo). */
.work-chat-paths {
  max-width: 640px;
}

.work-chat-paths-intro {
  font-family: var(--font-ui);
  font-size: 0.86rem;
  color: var(--ink-soft);
  margin-bottom: 10px;
}

.work-chat-paths-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.work-chat-path-card {
  text-align: left;
  font-family: var(--font-ui);
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  padding: 14px 16px;
  cursor: pointer;
}

.work-chat-path-card:hover {
  border-color: var(--cover-contrast);
}

.work-chat-path-card-title {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.05rem;
  color: var(--ink);
  margin-bottom: 6px;
}

.work-chat-path-card-sample {
  font-size: 0.82rem;
  color: var(--ink-soft);
  line-height: 1.4;
}

/* Biblioteca expresiva del modo experto (/formas) --
       tres filas de chips (arquitectura/recurso/tono), como mucho una
       marcada por fila (ver showExpressiveLibrary() en app.js). */
.work-chat-library {
  max-width: 640px;
}

/* Cabecera con el texto de siempre + botón para cerrar
       el bloque sin elegir nada (ver clearActiveFormula() en app.js). */
.work-chat-library-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
}

.work-chat-library-intro {
  font-family: var(--font-ui);
  font-size: 0.86rem;
  color: var(--ink-soft);
}

.work-chat-library-close {
  flex-shrink: 0;
  border: none;
  background: transparent;
  color: var(--ink-soft);
  font-size: 0.9rem;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
}

.work-chat-library-close:hover {
  color: var(--ink);
}

.work-chat-library-dim {
  margin-bottom: 12px;
}

.work-chat-library-dim-title {
  font-family: var(--font-ui);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  margin-bottom: 6px;
}

.work-chat-library-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.work-chat-library-chip {
  font-family: var(--font-ui);
  font-size: 0.78rem;
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 5px 12px;
  background: #fff;
  color: var(--ink);
  cursor: pointer;
}

.work-chat-library-chip:hover {
  border-color: var(--cover-contrast);
}

.work-chat-library-chip.active {
  border-color: var(--cover-contrast);
  background: var(--cover-contrast);
  color: #fff;
}

/* Pastilla que muestra la fórmula activa del modo
       experto, junto al campo de texto -- el próximo envío la usa
       directamente (ver renderActiveFormulaPill()/clearActiveFormula()
       en app.js). */
#work-chat-formula-pill {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-family: var(--font-ui);
  font-size: 0.8rem;
  color: var(--ink);
  background: var(--cover-peach);
  border-radius: 8px;
  padding: 8px 12px;
  margin-bottom: 8px;
}

/* Bug real reportado por el usuario: la
       regla de arriba, al llevar un selector de id (más específico que
       el `[hidden] { display: none }` que trae el navegador por
       defecto), GANABA siempre a `hidden` -- el atributo se ponía y
       quitaba bien desde app.js (ver renderActiveFormulaPill()), pero
       la pastilla nunca llegaba a desaparecer visualmente porque su
       propio `display: flex` seguía mandando. Con esta regla, más
       específica todavía (id + atributo), `hidden` vuelve a ganar. */
#work-chat-formula-pill[hidden] {
  display: none;
}

#work-chat-formula-pill-text {
  overflow-wrap: anywhere;
}

#btn-work-chat-formula-clear {
  flex-shrink: 0;
  border: none;
  background: transparent;
  color: var(--ink-soft);
  font-size: 0.9rem;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
}

#btn-work-chat-formula-clear:hover {
  color: var(--ink);
}

#work-chat-stale-banner {
  font-family: var(--font-ui);
  font-size: 0.82rem;
  color: var(--ink-soft);
  background: var(--cover-peach);
  border-radius: 8px;
  padding: 12px 16px;
  margin-bottom: 12px;
}

#work-chat-composer {
  flex-shrink: 0;
  font-family: var(--font-ui);
}

#work-chat-composer textarea {
  flex: 1;
  min-height: 80px;
  /* Mismo criterio que #composer textarea -- crece sola,
         ver autoGrowTextarea en app.js. */
  resize: none;
  overflow-y: hidden;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.05rem;
  padding: 16px 20px;
  border: none;
  border-radius: 10px;
  background: #fff;
  color: var(--ink);
}

#btn-work-chat-send {
  font-family: var(--font-ui);
  font-size: 0.9rem;
  padding: 0 34px;
  border-radius: 10px;
  border: none;
  background: var(--cover-contrast);
  color: #fff;
  cursor: pointer;
  flex-shrink: 0;
}

#btn-work-chat-send:disabled {
  opacity: 0.4;
  cursor: default;
}

#work-chat-status-msg {
  margin-top: 8px;
  font-size: 0.82rem;
  color: var(--ink-soft);
  min-height: 1.2em;
}

@media (max-width: 720px) {
  #work-chat-body {
    flex-direction: column;
  }

  #work-chat-sidebar {
    width: 100%;
    border-right: none;
    border-bottom: 1px solid var(--line);
  }

  /* En móvil, una tarjeta de camino por fila -- 2 por fila
         quedaría demasiado apretado y forzaría scroll horizontal, lo
         que el usuario pidió explícitamente evitar. */
  .work-chat-paths-grid {
    grid-template-columns: 1fr;
  }

  #work-chat-formula-pill {
    align-items: flex-start;
  }
}

/* Rango de pantalla estrecha: la cabecera y la portada pasan a una
     sola columna en vez de mantener el ancho fijo de 1440 del lienzo de
     Figma — esta app es responsive de antes, y esta pantalla no debe
     dejar de serlo por el rediseño. */
@media (max-width: 720px) {
  #app-header {
    padding: 14px 20px;
    gap: 12px;
  }

  .header-side {
    gap: 16px;
  }

  .header-link span:not(.icon-badge) {
    display: none;
  }

  #header-logo {
    font-size: 1.3rem;
  }

  .hero {
    margin-top: 30px;
  }

  .cover-card {
    padding: 28px 20px 44px;
  }

  .qa-panel {
    padding: 60px 20px 28px;
  }

  .composer-input-row {
    flex-direction: column;
  }

  #btn-send {
    padding: 12px;
  }

  /* En columna, dictado + enviar quedan como una fila
         propia debajo de la textarea (ver .composer-buttons), en vez
         de apilarse los tres campos sueltos a lo ancho. */
  .mic-btn {
    width: auto;
    flex: 1;
  }

  .composer-buttons #btn-send {
    flex: 2;
  }
}

button {
  font-family: inherit;
  font-size: 0.85rem;
  padding: 9px 16px;
  border-radius: 6px;
  border: 1px solid var(--ink);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}

button.primary {
  background: var(--accent);
  color: var(--accent-ink);
}

button:disabled {
  opacity: 0.4;
  cursor: default;
}

button:hover:not(:disabled) {
  opacity: 0.85;
}

.overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(255, 243, 224, 0.53);
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 10;
}

.panel {
  background: var(--panel);
  border-radius: 10px;
  padding: 28px;
  max-width: 640px;
  width: 100%;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  position: relative;
}

/* Botón "×" opcional en la esquina de un panel
     de overlay — de momento solo lo usa #cover-color-overlay (ver arriba,
     necesario para poder cancelar el cambio de color de un proyecto ya
     creado sin elegir nada). */
.overlay-close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  color: var(--ink-soft);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 6px;
  padding: 0;
}

.overlay-close:hover {
  background: var(--bg);
  color: var(--ink);
}

.panel h3 {
  margin: 0 0 6px;
  font-size: 1.1rem;
}

.panel .hint {
  color: var(--ink-soft);
  font-size: 0.85rem;
  margin-bottom: 14px;
}

#review-text {
  flex: 1;
  min-height: 160px;
  resize: vertical;
  font-family: inherit;
  font-size: 0.97rem;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg);
  color: var(--ink);
}

.panel .actions {
  display: flex;
  gap: 10px;
  margin-top: 14px;
  justify-content: flex-end;
}

#project-list {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
  overflow-y: auto;
}

/* El panel genérico de overlay (.panel, más
       arriba) está pensado para confirmaciones cortas -- max-width
       640px. El SKILL.md puede ser largo, así que este overlay concreto
       necesita un panel más ancho y con el cuerpo scrolleable dentro,
       dejando fijos el título, el aviso y el botón de descarga. */
#skill-preview-overlay .panel {
  max-width: 760px;
}

#skill-preview-body {
  overflow-y: auto;
  line-height: 1.6;
}

#skill-preview-body pre {
  white-space: pre-wrap;
  word-break: break-word;
}

/* Bug real reportado por el usuario: el
       panel de administración de usuarios no tenía NINGÚN estilo
       propio -- era una <ul> a pelo (viñetas y sangría por defecto,
       nombre/input/botón amontonados uno debajo del otro) y sin
       scroll, así que con varios usuarios la lista se salía del panel
       sin forma de verla entera. Mismo patrón que #skill-preview-body
       (ver su comentario) y #project-list (más abajo): .panel
       ya trae display:flex/flex-direction:column/max-height:80vh, así
       que basta con overflow-y:auto en el bloque largo para que el
       navegador le reparta el espacio que sobra tras el título y el
       aviso, y ESE bloque sea el que scrollea -- el título, el aviso y
       el botón "Cerrar" quedan fijos. */
#admin-users-list {
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
  overflow-y: auto;
}

#admin-users-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 12px 0;
  border-top: 1px solid var(--line);
}

#admin-users-list li > div:first-child {
  flex: 1 1 200px;
  min-width: 0;
}

#admin-users-list .name {
  font-weight: bold;
}

#admin-users-list .meta {
  font-size: 0.78rem;
  color: var(--ink-soft);
}

#admin-users-list input {
  flex: 0 1 220px;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg);
  color: var(--ink);
  font-family: inherit;
  font-size: 0.85rem;
}

#admin-users-list button {
  flex-shrink: 0;
  padding: 5px 10px;
  font-size: 0.78rem;
}

#admin-users-error {
  color: #a33;
  font-size: 0.85rem;
}

#project-list li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  padding: 15px 0px;
  border-top: 1px solid #fff3e0;
  /* border-radius: 8px; */
  margin-bottom: 8px;
}

#project-list .name-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Mismo color de portada del proyecto (el que
       se elige en "Elige el color de portada", ver .cover-swatch más
       abajo), en miniatura junto al nombre en "Mis proyectos" -- para
       identificar cada proyecto a golpe de vista sin tener que abrirlo. */
.project-color-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  flex-shrink: 0;
}

#project-list .name {
  font-weight: bold;
}

#project-list .meta {
  font-size: 0.78rem;
  color: var(--ink-soft);
}

#project-list .row-actions {
  display: flex;
  gap: 6px;
}

/* Pantalla de acceso — cuentas de usuario a
     través de WordPress, ver wp_auth.py. Reutiliza .overlay/.panel. */
#login-overlay {
  z-index: 20;
}

#login-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

#login-form input {
  padding: 10px 12px;
  border: 0;
  border-radius: 8px;
  background-color: var(--cover-cream);
  color: var(--ink);
  font-family: inherit;
  font-size: 0.95rem;
}

#login-error {
  color: #a33;
  font-size: 0.85rem;
  display: none;
}

#project-list .row-actions button {
  padding: 5px 10px;
  font-size: 0.78rem;
}

/* Panel de colaboradores -- reutiliza
       .overlay/.panel/.overlay-close, con listas y filas de acciones
       en el mismo estilo que #project-list. */
#collaborators-list {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
  max-height: 40vh;
  overflow-y: auto;
}

#collaborators-list li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  padding: 12px 0;
  border-top: 1px solid #fff3e0;
}

#collaborators-list li:first-child {
  border-top: none;
}

#collaborators-list .name {
  font-weight: bold;
}

#collaborators-list .role-tag {
  font-size: 0.72rem;
  color: var(--ink-soft);
}

#collaborators-add-row {
  display: flex;
  gap: 8px;
  margin-bottom: 10px;
}

#collaborators-add-row input {
  flex: 1;
  padding: 8px 10px;
  border: 0;
  border-radius: 8px;
  background: var(--cover-cream);
  color: var(--ink);
  font-family: inherit;
  font-size: 0.9rem;
}

#collaborators-error {
  color: #a33;
  font-size: 0.82rem;
  min-height: 1.2em;
}

/* Fase 12.2: q09 vuelve a ser conversación libre como el resto de
     preguntas (ver más abajo por qué) — lo único distinto es su
     ventana de revisión al guardar: en vez de un texto libre editable,
     muestra los 9 ejes ya interpretados por el modelo a partir de la
     conversación, como interruptores editables, para confirmar o
     corregir antes de guardar nada. */
#q09-review-draft {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 12px;
  font-size: 0.88rem;
  color: var(--ink-soft);
  white-space: pre-wrap;
  max-height: 120px;
  overflow-y: auto;
  margin-bottom: 16px;
}

#q09-review-rows {
  overflow-y: auto;
}

.q09-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}

.q09-row .axis-n {
  font-size: 0.75rem;
  color: var(--ink-soft);
  width: 18px;
  flex-shrink: 0;
}

.q09-row button {
  flex: 1;
  text-align: center;
}

.q09-row .sep {
  color: var(--ink-soft);
  font-size: 0.8rem;
}

/* 29 ago 2026: elección de color de portada al empezar sesión — ver
     cover_colors.py. Paleta de muestras + un botón discreto aparte para
     color personalizado, como pidió el usuario. */
#cover-color-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  padding: 4px 0 18px;
}

.cover-swatch {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  padding: 0;
  border: 2px solid var(--line);
  cursor: pointer;
  flex-shrink: 0;
}

.cover-swatch:hover {
  border-color: var(--ink-soft);
  opacity: 1;
}

#cover-color-custom-row {
  border-top: 1px solid var(--line);
  padding-top: 14px;
  display: flex;
  align-items: center;
  gap: 10px;
}

/* 30 ago 2026: el <input type="color"> ya no se esconde con
     display:none — con eso, el navegador no tiene ninguna posición
     real de la que anclar su selector nativo y lo abre en cualquier
     sitio de la pantalla, lejos de este panel (bug real reportado por
     el usuario). Ahora vive en un envoltorio del tamaño exacto del
     botón que lo dispara y se superpone a él (invisible, opacity:0) —
     así el navegador lo ancla justo ahí. pointer-events:none porque
     quien recibe el clic de verdad es el botón, que llama a
     coverColorCustomInput.click() por JavaScript. */
#cover-color-custom-wrap {
  position: relative;
  display: inline-block;
}

#cover-color-custom-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  pointer-events: none;
  padding: 0;
  border: none;
}

/* Vista previa en vivo + botón explícito para confirmar — antes
     había que cerrar el selector nativo del sistema operativo "bien"
     (o pulsar Intro) para que se diera por elegido el color; ahora, en
     cuanto se mueve el selector, aparecen los dos y basta un clic. */
#cover-color-custom-preview {
  display: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid var(--line);
  flex-shrink: 0;
}

#btn-cover-color-custom {
  border: none;
  background: none;
  color: var(--ink-soft);
  font-size: 0.8rem;
  text-decoration: underline;
  padding: 2px 0;
  cursor: pointer;
}
