/* ============================================================================
   Anime Studio - timeline.css
   LINEA DE TIEMPO (`#timeline`, contrato §39): barra de herramientas, regla,
   columna de nombres, area de celdas y controles de reproduccion.

   Como se reparte el trabajo con `ui/timelineUI.js` (leerlo antes de tocar
   nada de aqui):
   - El modulo construye la regla y las pistas y fija EN LINEA toda la
     geometria que depende del estado: `left` de la rejilla y del canvas de la
     regla (= ancho de la columna de nombres), `width`/`height` de los canvas
     (con la relacion de pixeles del dispositivo), el `transform` que sincroniza
     el desplazamiento y el alto de cada fila de nombre.
   - Por eso esta hoja NUNCA fija ancho ni alto a `.tl-grid-canvas` ni a
     `.tl-overlay-canvas`: estirarlos al 100% romperia la virtualizacion del
     §46.5 (los canvas miden lo VISIBLE y se trasladan, no miden el documento
     entero).
   - Las celdas, el playhead, los marcadores y el sombreado del rango de
     reproduccion se PINTAN en el canvas con los tokens de `tokens.css` que lee
     el propio modulo. Lo que hay aqui es el marco: fondos, separaciones,
     tipografia, cursores y estados.
   - Se lee `--tl-row-h`, `--tl-gutter` y `--tl-cell-w` de `tokens.css` con
     `getComputedStyle(#timeline)`: cambiarlos aqui cambia la maquetacion real
     del canvas, no solo su aspecto.

   Ningun color literal: todo sale de `tokens.css`.

   Indice:
     1. Contenedor #timeline y estados
     2. #timeline-toolbar
     3. Cuerpo, regla y esquina
     4. Pistas: columna de nombres y area de celdas
     5. Filas de nombre de capa y de audio
     6. #playback-controls
     7. Modo compacto (movil) y variantes
     8. Puntero grueso, movimiento reducido y colores forzados
   ========================================================================== */


/* ---------------------------------------------------------------------------
   1. CONTENEDOR #timeline Y ESTADOS
   ------------------------------------------------------------------------ */
#timeline {
  /* Metricas locales. El alto total sale de `--timeline-h` (tokens.css), que
     `ui/ui.js` reescribe en linea al arrastrar `#timeline-resizer`. */
  --tl-toolbar-h: 30px;
  --tl-playback-h: 42px;
  --tl-names-shadow: 6px;

  display: flex;
  flex-direction: column;
  height: var(--timeline-h);
  min-height: var(--timeline-h-min);
  min-width: 0;
  background: var(--s-1);
  border-top: 1px solid var(--bd-soft);
  overflow: hidden;
  user-select: none;
  -webkit-user-select: none;
}

/* --- Plegado --------------------------------------------------------------
   Plegada, la linea de tiempo conserva su barra de herramientas: es la unica
   forma de volver a desplegarla sin ir al menu. Se admiten los dos enganches
   habituales: la clase en la propia seccion y la clase de modo en `#app`.
   ------------------------------------------------------------------------ */
#timeline.is-collapsed,
#app.timeline-collapsed #timeline {
  height: auto;
  min-height: 0;
  flex: 0 0 auto;
}

#timeline.is-collapsed .timeline-body,
#timeline.is-collapsed #playback-controls,
#app.timeline-collapsed #timeline .timeline-body,
#app.timeline-collapsed #timeline #playback-controls {
  display: none;
}

/* Sin cuerpo que redimensionar, el tirador sobra. */
#app.timeline-collapsed #timeline-resizer {
  display: none;
}

/* --- Arrastre del cabezal / del rango -------------------------------------
   Mientras se arrastra hay que congelar el cursor en TODA la linea de tiempo:
   si cambiara al pasar por encima de un boton, el gesto pareceria haberse
   soltado. */
#timeline.is-scrubbing,
#timeline.is-scrubbing * {
  cursor: ew-resize;
}

#timeline.is-scrubbing {
  user-select: none;
  -webkit-user-select: none;
}

/* --- Reproduccion ---------------------------------------------------------
   Durante la reproduccion se apaga el resalte de hover de las filas: con el
   cabezal corriendo, un fondo que cambia bajo el raton solo distrae. */
#timeline.is-playing .tl-name:hover,
#app.is-playing #timeline .tl-name:hover {
  background: none;
}


/* ---------------------------------------------------------------------------
   2. #timeline-toolbar
   ------------------------------------------------------------------------ */
#timeline-toolbar {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  flex: 0 0 auto;
  min-width: 0;
  height: var(--tl-toolbar-h);
  padding: 0 var(--sp-3);
  background: var(--s-2);
  border-bottom: 1px solid var(--bd-soft);
  /* Con muchos botones y poca anchura, la barra se desplaza en vez de
     recortar los ultimos controles. */
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}

#timeline-toolbar::-webkit-scrollbar {
  width: 0;
  height: 0;
}

#timeline-toolbar .divider-v {
  height: 14px;
  min-height: 0;
  margin: 0 var(--sp-2);
}

#timeline-toolbar .grow {
  flex: 1 1 auto;
  min-width: var(--sp-4);
}

/* --- FPS y duracion ------------------------------------------------------ */
.timeline-fps,
.timeline-duration {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex: 0 0 auto;
  color: var(--fg-dim);
  font-size: var(--fs-xs);
  cursor: pointer;
}

.timeline-fps-label,
.timeline-duration-label {
  text-transform: uppercase;
  letter-spacing: var(--ls-wide);
  user-select: none;
  -webkit-user-select: none;
}

.timeline-fps-input,
.timeline-duration-input {
  width: 54px;
  flex: 0 0 auto;
  height: var(--ctrl-h-sm-cur);
  padding: 0 var(--sp-2);
  text-align: right;
}

/* --- Zoom de la linea de tiempo ------------------------------------------ */
.timeline-zoom {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  min-width: 0;
}

.timeline-zoom-slider {
  width: 104px;
  flex: 0 0 auto;
}


/* ---------------------------------------------------------------------------
   3. CUERPO, REGLA Y ESQUINA
   ------------------------------------------------------------------------ */
.timeline-body {
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  background: var(--s-0);
}

/* El modulo fija `position/height/flex/overflow` en linea; aqui van el fondo y
   la separacion con las pistas. */
#timeline-ruler {
  background: var(--s-2);
  border-bottom: 1px solid var(--bd);
  cursor: ew-resize;              /* toda la regla arrastra el cabezal */
}

/* Esquina fija de la regla, sobre la columna de nombres. Va por encima del
   canvas de la regla para que su fondo tape el borde del desplazamiento. */
.tl-ruler-corner {
  z-index: 2;
  background: var(--s-2);
  border-right: 1px solid var(--bd);
  cursor: default;
}

.tl-ruler-corner-label {
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--fg-mute);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
}

/* El canvas de la regla ya recibe tamano y cursor en linea. Solo se blinda
   frente a cualquier reset de imagenes que le cambiase la caja. */
.tl-ruler-canvas {
  display: block;
  max-width: none;
}


/* ---------------------------------------------------------------------------
   4. PISTAS: COLUMNA DE NOMBRES Y AREA DE CELDAS
   ------------------------------------------------------------------------ */
#timeline-tracks {
  background: var(--s-0);
  outline: none;
}

#timeline-tracks:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 var(--focus-w) var(--accent-ring);
}

/* --- Columna fija de nombres ---------------------------------------------
   Queda quieta mientras el area de celdas se desplaza en horizontal. La sombra
   hacia la derecha es lo que comunica "esto no se mueve, lo de al lado si";
   sin ella, con el canvas desplazado, la separacion no se lee.
   El modulo le pone `hidden` cuando el ancho es 0 (tira compacta de movil).
   ------------------------------------------------------------------------ */
.tl-names {
  background: var(--s-1);
  border-right: 1px solid var(--bd);
  box-shadow: var(--tl-names-shadow) 0 var(--tl-names-shadow)
              calc(var(--tl-names-shadow) * -1) var(--canvas-shadow);
}

.tl-names[hidden] {
  display: none;
}

/* Capa interior que el modulo traslada para seguir al desplazamiento
   vertical. `will-change: transform` ya va en linea. */
.tl-names-inner {
  min-width: 0;
}

/* --- Area de celdas -------------------------------------------------------
   `.tl-grid` es el unico elemento con desplazamiento real; `.tl-grid-content`
   solo aporta el tamano virtual del documento y los dos canvas se trasladan
   dentro. Sus medidas las fija el modulo: aqui SOLO fondo y proteccion de
   caja.
   ------------------------------------------------------------------------ */
.tl-grid {
  background: var(--s-0);
}

.tl-grid-canvas,
.tl-overlay-canvas {
  display: block;
  max-width: none;               /* el tamano CSS lo fija timelineUI.js */
}

/* El canvas de celdas es el objetivo de todos los gestos de la rejilla. */
.tl-grid-canvas {
  cursor: pointer;
}

#timeline.is-scrubbing .tl-grid-canvas {
  cursor: ew-resize;
}


/* ---------------------------------------------------------------------------
   5. FILAS DE NOMBRE DE CAPA Y DE AUDIO

   El modulo pone en linea la caja (flex, alto, relleno, recorte) y recicla los
   nodos por id (§46.6). Aqui van color, tipografia y estados.
   ------------------------------------------------------------------------ */
.tl-name {
  color: var(--fg-dim);
  border-bottom: 1px solid var(--bd-soft);
  font-size: var(--fs-sm);
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast);
}

.tl-name:hover {
  background: var(--s-2);
  color: var(--fg);
}

/* Capa activa: banda de acento a la izquierda, como en el panel de capas, para
   que las dos listas hablen el mismo idioma. */
.tl-name.is-active {
  background: var(--accent-soft);
  color: var(--fg);
  box-shadow: inset 3px 0 0 var(--accent);
}

.tl-name.is-active:hover {
  background: var(--accent-soft-hover);
}

/* Capa oculta: se atenua, pero sigue siendo legible y pulsable. */
.tl-name.is-hidden {
  opacity: var(--op-muted);
}

.tl-name.is-hidden .tl-name-label {
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}

/* Capa bloqueada: cursiva, para que se distinga tambien en escala de grises. */
.tl-name.is-locked .tl-name-label {
  font-style: italic;
}

.tl-name:focus-visible {
  outline: var(--focus-w) solid var(--accent-ring);
  outline-offset: -2px;
}

.tl-name-icon {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  color: var(--fg-mute);
}

.tl-name.is-active .tl-name-icon {
  color: var(--accent-ring);
}

.tl-name-label {
  font-size: var(--fs-sm);
}

/* Contador de fotogramas clave de la capa: insignia discreta. */
.tl-name-count {
  min-width: 16px;
  padding: 0 4px;
  background: var(--s-3);
  color: var(--fg-mute);
  border-radius: var(--r-full);
  font-variant-numeric: tabular-nums;
  line-height: 15px;
  text-align: center;
}

.tl-name.is-active .tl-name-count {
  background: var(--accent);
  color: var(--accent-fg);
}

.tl-name-count:empty {
  display: none;
}

/* --- Fila de audio --------------------------------------------------------
   Se distingue de una capa de dibujo por el fondo y por el color del icono: la
   forma de onda la pinta el canvas con `--accent-2`.
   ------------------------------------------------------------------------ */
.tl-name[data-kind="audio"] {
  background: var(--s-2);
}

.tl-name[data-kind="audio"] .tl-name-icon {
  color: var(--accent-2);
}

.tl-name[data-kind="audio"].is-muted {
  opacity: var(--op-muted);
}

.tl-name[data-kind="audio"].is-muted .tl-name-icon {
  color: var(--fg-mute);
}

/* Los dos botones de la pista de audio solo aparecen al acercarse a la fila:
   con el dedo no hay hover, asi que en tactil se dejan siempre visibles
   (§8, bloque de puntero grueso). */
.tl-name-mute,
.tl-name-remove {
  flex: 0 0 auto;
  width: 22px;
  min-width: 22px;
  height: 22px;
  opacity: 0;
  transition: opacity var(--t-fast);
}

.tl-name:hover .tl-name-mute,
.tl-name:hover .tl-name-remove,
.tl-name-mute:focus-visible,
.tl-name-remove:focus-visible,
.tl-name-mute[aria-pressed="true"] {
  opacity: 1;
}

.tl-name-mute[aria-pressed="true"] {
  color: var(--warn);
}

.tl-name-mute .icon,
.tl-name-remove .icon {
  width: 13px;
  height: 13px;
}

/* Grupo de capas: cabecera de arbol, un punto mas marcada. */
.tl-name[data-kind="group"] {
  font-weight: var(--fw-medium);
}

.tl-name[data-kind="group"] .tl-name-icon {
  color: var(--fg-dim);
}


/* ---------------------------------------------------------------------------
   6. #playback-controls

   Los botones de transporte van CENTRADOS y el tiempo se queda a la derecha.
   Se consigue con dos cajas flexibles del mismo peso (un pseudoelemento a la
   izquierda y el propio `#playback-time` a la derecha), sin posicionamiento
   absoluto: asi el centrado aguanta aunque cambie el numero de botones.
   ------------------------------------------------------------------------ */
#playback-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  flex: 0 0 auto;
  min-width: 0;
  height: var(--tl-playback-h);
  padding: 0 var(--sp-4);
  background: var(--s-1);
  border-top: 1px solid var(--bd-soft);
}

#playback-controls::before {
  content: "";
  flex: 1 1 0;
  min-width: 0;
}

/* Boton de reproducir: el unico destacado de toda la linea de tiempo. */
#btn-play {
  width: var(--ctrl-h-lg);
  min-width: var(--ctrl-h-lg);
  height: var(--ctrl-h-lg);
  flex: 0 0 auto;
  margin: 0 var(--sp-2);
  border-radius: var(--r-full);
  box-shadow: var(--sh-1);
}

#btn-play .icon {
  width: 18px;
  height: 18px;
}

/* CORRECCION NECESARIA: `main.css` declara `svg { display:block }`, y una regla
   de AUTOR gana siempre a la `[hidden]{display:none}` de la hoja del
   navegador. Sin esto, los iconos de play y de pausa se verian los dos a la
   vez en cuanto el modulo alternase su atributo `hidden`. */
#playback-controls svg[hidden] {
  display: none;
}

#playback-controls .divider-v {
  height: 16px;
  min-height: 0;
}

/* Tiempo y fotograma actual. Equilibra el pseudoelemento de la izquierda. */
#playback-time {
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--fg-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

#timeline.is-playing #playback-time,
#app.is-playing #playback-time {
  color: var(--accent-ring);
}


/* ---------------------------------------------------------------------------
   7. MODO COMPACTO (MOVIL)

   `timelineUI.js` pone `.is-compact` cuando la disposicion es movil y
   `.is-expanded` cuando el usuario despliega la tira a pantalla completa. En
   compacto el modulo vacia la columna de nombres y le da ancho 0 (le pone
   `hidden`), asi que la tira queda solo con la regla y las miniaturas.

   Aqui esta la version COMPACTA. La desplegada a pantalla completa la cubre
   `mobile.css`, que se carga despues.
   ------------------------------------------------------------------------ */
#timeline.is-compact {
  /* Alto justo para la regla + una fila de miniaturas + el transporte. */
  height: auto;
  min-height: 0;
}

#timeline.is-compact #timeline-toolbar {
  /* En la tira compacta la barra solo estorba: los botones utiles estan en la
     barra movil y en el transporte. Queda el boton de desplegar, que el modulo
     deja visible quitandole el atributo `hidden`. */
  gap: var(--sp-2);
  padding: 0 var(--sp-2);
}

#timeline.is-compact .timeline-fps,
#timeline.is-compact .timeline-duration,
#timeline.is-compact .timeline-zoom,
#timeline.is-compact #timeline-toolbar .divider-v {
  display: none;
}

#timeline.is-compact .timeline-body {
  /* Una fila de miniaturas (THUMB_ROW_H = 64) mas la regla (RULER_H = 26). */
  height: 90px;
  flex: 0 0 auto;
}

#timeline.is-compact .tl-names,
#timeline.is-compact .tl-ruler-corner {
  display: none;
}

#timeline.is-compact #playback-controls {
  height: var(--mobile-bar-h);
}

/* Desplegada a pantalla completa: recupera el alto flexible. El resto del
   tratamiento (posicion, capa, cierre) es de `mobile.css`. */
#timeline.is-compact.is-expanded {
  height: 100%;
  min-height: 0;
}

#timeline.is-compact.is-expanded .timeline-body {
  height: auto;
  flex: 1 1 auto;
}

#timeline.is-compact.is-expanded .timeline-fps,
#timeline.is-compact.is-expanded .timeline-zoom {
  display: flex;
}


/* ---------------------------------------------------------------------------
   8. PUNTERO GRUESO, MOVIMIENTO REDUCIDO Y COLORES FORZADOS
   ------------------------------------------------------------------------ */
@media (pointer: coarse) {
  #timeline {
    --tl-toolbar-h: 40px;
    --tl-playback-h: 52px;
  }

  /* Sin hover no hay forma de descubrir los botones de la pista de audio. */
  .tl-name-mute,
  .tl-name-remove {
    width: 30px;
    min-width: 30px;
    height: 30px;
    opacity: 1;
  }

  .timeline-fps-input,
  .timeline-duration-input {
    width: 62px;
  }

  .timeline-zoom-slider {
    width: 120px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .tl-name,
  .tl-name-mute,
  .tl-name-remove {
    transition: none;
  }
}

@media (forced-colors: active) {
  #timeline,
  #timeline-toolbar,
  #timeline-ruler,
  .tl-names,
  .tl-ruler-corner,
  #playback-controls {
    border-color: CanvasText;
  }

  .tl-name.is-active {
    forced-color-adjust: none;
    background: Highlight;
    color: HighlightText;
    box-shadow: none;
  }

  .tl-name.is-active .tl-name-icon,
  .tl-name.is-active .tl-name-count {
    color: HighlightText;
  }

  /* La sombra de la columna no existe en alto contraste: la separacion pasa a
     ser un borde solido. */
  .tl-names {
    box-shadow: none;
    border-right: 2px solid CanvasText;
  }
}
