/* Paleta inspirada en Material Design 3 (decisión de Requirements Analysis) */
:root {
  --md-primary: #6750a4;
  --md-on-primary: #ffffff;
  --md-primary-container: #eaddff;
  --md-on-primary-container: #21005d;
  --md-surface: #fffbfe;
  --md-on-surface: #1c1b1f;
  --md-surface-variant: #e7e0ec;
  --md-outline: #79747e;
  --md-success: #2e7d32;
  --md-present: #f9a825;
  --md-absent: #79747e;
  --md-error: #b3261e;
  --md-radius: 12px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --md-surface: #1c1b1f;
    --md-on-surface: #e6e1e5;
    --md-surface-variant: #49454f;
    --md-primary-container: #4f378b;
    --md-on-primary-container: #eaddff;
  }
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  margin: 0;
}

body {
  font-family: 'Roboto', system-ui, sans-serif;
  background: var(--md-surface);
  color: var(--md-on-surface);
}

/* App shell: header (app bar) fijo arriba, body flexible en el medio, FAB
   flotante encima de todo. #app es el unico contenedor con scroll -- eso es
   lo que permite que la fila compacta del app bar quede "sticky". */
#app {
  max-width: 480px;
  margin: 0 auto;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  /* espacio de sobra para que el ultimo contenido del body no quede tapado por el FAB */
  padding-bottom: 88px;
}

/* Top app bar Large Flexible (M3): fila compacta sticky + fila de titulo
   grande que se desplaza con el contenido. Boton de menu a los lados: sin
   iconos todavia (huecos reservados para el futuro), titulo centrado. */
.app-bar {
  flex: 0 0 auto;
}

.app-bar-compact {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  height: 64px;
  padding: 0 4px;
  background: var(--md-surface);
}

.app-bar-leading-slot,
.app-bar-trailing-slot {
  width: 48px;
  flex: 0 0 auto;
}

.app-bar-compact-title {
  flex: 1;
  text-align: center;
  font-size: 1.1rem;
  font-weight: 500;
  margin: 0;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 160ms ease, transform 160ms ease;
}

#app.is-scrolled .app-bar-compact-title {
  opacity: 1;
  transform: translateY(0);
}

.app-bar-large-title-row {
  padding: 0 16px 20px;
}

.app-bar-large-title {
  text-align: center;
  font-size: 2rem;
  font-weight: 400;
  line-height: 1.2;
  margin: 0 0 8px;
}

.app-bar-status-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.attempts-counter {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--md-primary-container);
  color: var(--md-primary);
  font-weight: 500;
}

.app-body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 0 16px;
}

/* El wrapper reparte el alto/ancho sobrante del body al grid (crece/mengua
   segun el espacio). container-type:size habilita las unidades cqw/cqh de
   abajo, que hacen que el grid encoja por el minimo entre ancho y alto
   disponibles para entrar siempre entero, sin scroll. */
.crossword-grid-wrapper {
  container-type: size;
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px 0;
}

.crossword-grid {
  display: grid;
  gap: 2px;
  width: 100%;
  aspect-ratio: var(--cols) / var(--rows);
}

@supports (width: 100cqw) {
  .crossword-grid {
    width: min(100cqw, 100cqh * var(--cols) / var(--rows));
    height: min(100cqh, 100cqw * var(--rows) / var(--cols));
  }
}

.grid-cell {
  position: relative;
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--md-outline);
  border-radius: 4px;
  font-size: 1.1rem;
  font-weight: 600;
  text-transform: uppercase;
  background: var(--md-surface);
  cursor: pointer;
}

/* Triangulo que marca el inicio de una palabra (BR: siempre visible, coloreado por categoria) */
.word-start-triangle {
  position: absolute;
  width: 0;
  height: 0;
}

.word-start-triangle.triangle-across {
  top: 2px;
  left: 1px;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  border-left: 6px solid var(--triangle-color);
}

.word-start-triangle.triangle-down {
  top: 1px;
  right: 2px;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 6px solid var(--triangle-color);
}

.grid-cell.active-word {
  border-color: var(--md-primary);
  border-width: 2px;
}

.grid-cell.active-cell {
  background: var(--md-primary-container);
}

.grid-cell[data-state='correct'] {
  background: var(--md-success);
  color: white;
  border-color: var(--md-success);
}

.grid-cell[data-state='present'] {
  background: var(--md-present);
  color: white;
  border-color: var(--md-present);
}

.grid-cell[data-state='absent'] {
  background: var(--md-absent);
  color: white;
  border-color: var(--md-absent);
}

/* Banner de la pista activa: cita con emoji + color de categoria (estilo
   Trivial). Alto minimo fijo, pero crece con el largo de la pista para que
   el texto siempre se vea completo (nunca se trunca). */
.clue-banner {
  flex: 0 0 auto;
  min-height: 72px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border-radius: var(--md-radius);
  background: var(--clue-bg, var(--md-surface-variant));
  color: var(--clue-fg, var(--md-on-surface));
}

.clue-banner-emoji {
  flex: 0 0 auto;
  font-size: 1.4rem;
  line-height: 1;
  align-self: flex-start;
}

.clue-banner-text {
  flex: 1;
  min-width: 0;
  font-style: italic;
  font-weight: 500;
}

.clue-banner-length {
  font-size: 0.8rem;
  opacity: 0.85;
  white-space: nowrap;
  align-self: flex-start;
}

/* Input real oculto que recibe el foco al seleccionar una celda. En movil,
   enfocar un div (aunque tenga tabindex) no abre el teclado virtual: solo
   los elementos de formulario reales lo hacen. font-size:16px evita el
   auto-zoom de iOS Safari al enfocar. top/left son solo el valor inicial:
   main.js los reescribe en cada render para que el input siempre quede
   superpuesto a la celda activa (ver positionCellInput en render()) -- si
   quedara fijo en una esquina, el navegador movil scrollea la pagina hacia
   ahi cada vez que este input (que es el que de verdad tiene el foco)
   cambia de valor o de cursor al tipear. */
.cell-input-proxy {
  position: fixed;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: 0;
  border: none;
  outline: none;
  opacity: 0;
  font-size: 16px;
  background: transparent;
  color: transparent;
  caret-color: transparent;
  pointer-events: none;
}

button {
  font-family: inherit;
  font-size: 1rem;
  padding: 10px 24px;
  border-radius: 999px;
  border: none;
  background: var(--md-primary);
  color: var(--md-on-primary);
  cursor: pointer;
}

button:disabled {
  background: var(--md-surface-variant);
  color: var(--md-outline);
  cursor: not-allowed;
}

/* FAB (M3): boton flotante compacto fijo en la esquina inferior, NO ocupa
   todo el ancho -- por diseno, un FAB nunca lo hace. */
.fab-submit {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 20;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 56px;
  padding: 0 20px;
  border-radius: 28px;
  background: var(--md-primary-container);
  color: var(--md-on-primary-container);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3), 0 4px 10px rgba(0, 0, 0, 0.15);
}

.fab-submit:disabled {
  background: var(--md-surface-variant);
  color: var(--md-outline);
  box-shadow: none;
}

/* FR38-FR41: FAB secundario de pistas, mismo tamano que el de "Comprobar"
   pero del lado opuesto de la pantalla. */
.fab-hint {
  position: fixed;
  left: 16px;
  bottom: 16px;
  z-index: 20;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 56px;
  padding: 0 20px;
  border-radius: 28px;
  background: var(--md-secondary-container, var(--md-surface-variant));
  color: var(--md-on-secondary-container, var(--md-on-surface));
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3), 0 4px 10px rgba(0, 0, 0, 0.15);
}

.fab-hint:disabled {
  background: var(--md-surface-variant);
  color: var(--md-outline);
  box-shadow: none;
}

/* FR40: marca visual sutil para distinguir una letra revelada por pista de
   una revelada por cruce (BR27) -- mismo color de letra, borde punteado. */
.grid-cell.hinted-cell {
  border-style: dashed;
  border-color: var(--md-primary);
}

/* #app ya no tiene padding propio (el app bar y el FAB necesitan ir de
   borde a borde) -- estos son los unicos hijos directos de #app que
   siguen necesitando el inset de 16px que #app les daba antes. */
.error-banner,
.result-screen,
.loading-state {
  margin: 16px;
}

.error-banner {
  background: var(--md-error);
  color: white;
  padding: 12px;
  border-radius: var(--md-radius);
}

/* CR2, FR23: repaso de preguntas y respuestas tras una derrota. */
.qa-review {
  margin-top: 16px;
}

.qa-review-heading {
  font-size: 1.1rem;
  font-weight: 500;
  margin: 0 0 8px;
}

.qa-review-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.qa-review-item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 10px 12px;
  border-radius: var(--md-radius);
  border-left: 4px solid var(--qa-item-color, var(--md-outline));
  background: var(--md-surface-variant);
}

.qa-review-emoji {
  flex: 0 0 auto;
  font-size: 1.1rem;
}

.qa-review-clue {
  flex: 1;
  min-width: 0;
  font-style: italic;
}

.qa-review-answer {
  flex: 0 0 auto;
  text-transform: uppercase;
}

/* Skeleton mostrado en qa-review-slot mientras se espera la respuesta de
   GET /api/attempts/state (ver mountQaReview en main.js). */
.qa-review-skeleton-bar {
  border-radius: 4px;
  background: var(--md-outline);
  animation: qa-review-skeleton-pulse 1.2s ease-in-out infinite;
}

.qa-review-skeleton-emoji {
  flex: 0 0 auto;
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 50%;
}

.qa-review-skeleton-clue {
  flex: 1;
  min-width: 0;
  height: 0.9rem;
}

.qa-review-skeleton-answer {
  flex: 0 0 auto;
  width: 56px;
  height: 0.9rem;
}

@keyframes qa-review-skeleton-pulse {
  0%,
  100% {
    opacity: 0.15;
  }
  50% {
    opacity: 0.35;
  }
}

/* CR5: los 3 botones de compartir (texto + Instagram + TikTok) conviven en
   el mismo slot -- se envuelven en varias lineas en pantallas angostas en
   vez de desbordar. */
[data-testid='share-button-slot'] {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.share-image-button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--md-primary-container);
  color: var(--md-on-primary-container);
}

.share-image-button svg {
  width: 1.2rem;
  height: 1.2rem;
  flex: 0 0 auto;
}

.onboarding-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}

/* FR42: modal de anuncio placeholder -- mismo patron visual que
   .onboarding-overlay/.onboarding-card, z-index mayor para quedar por
   encima de .result-screen. */
.ad-overlay {
  position: fixed;
  inset: 0;
  z-index: 150;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}

.ad-card {
  background: var(--md-surface-variant);
  border-radius: var(--md-radius);
  padding: 24px;
  max-width: 400px;
  width: 100%;
  text-align: center;
}

.ad-card-label {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  opacity: 0.7;
  margin: 0 0 8px;
}

.ad-card-body {
  font-size: 1.1rem;
  margin: 0 0 20px;
}

/* FR43: animacion de flip estilo Wordle, acotada a la palabra recien
   enviada (ver renderGrid.js/main.js). El color final ya esta aplicado al
   montar el nodo (data-state), asi que rotar la celda alcanza para el
   efecto de "revelar" sin necesidad de sincronizar un cambio de color a
   mitad de la animacion. */
@keyframes cell-flip {
  0% {
    transform: rotateX(0deg);
  }
  50% {
    transform: rotateX(90deg);
  }
  100% {
    transform: rotateX(0deg);
  }
}

.grid-cell.flip-in {
  animation: cell-flip 0.5s ease both;
}

@media (prefers-reduced-motion: reduce) {
  .grid-cell.flip-in {
    animation: none;
  }
}

.onboarding-card {
  background: var(--md-surface);
  border-radius: 16px;
  padding: 24px;
  max-width: 400px;
  max-height: 85vh;
  overflow-y: auto;
}

.onboarding-card h2 {
  margin-top: 0;
}

/* CR7: contenido del onboarding reorganizado en secciones cortas (una por
   tema) en vez de un bloque unico de parrafos, para que se lea de un
   vistazo pese a ser mas largo que la version original. */
.onboarding-section {
  margin: 0 0 16px;
}

.onboarding-section:last-of-type {
  margin-bottom: 20px;
}

.onboarding-section h3 {
  margin: 0 0 4px;
  font-size: 1rem;
}

.onboarding-section p,
.onboarding-section ul {
  margin: 0;
  font-size: 0.92rem;
  opacity: 0.9;
}

.onboarding-legend {
  list-style: none;
  padding: 0;
  margin: 0 0 8px;
}

.onboarding-legend li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 0;
}

.legend-swatch {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  border-radius: 4px;
}

.legend-swatch-correct {
  background: var(--md-success);
}

.legend-swatch-present {
  background: var(--md-present);
}

.legend-swatch-absent {
  background: var(--md-absent);
}
