/* ============================================================================
   Anime Studio - editor.css
   ARMAZON del editor (`editor.php`, contrato §39): rejilla general, barras
   densas, columna de herramientas, lienzo, reglas, HUD, separadores
   redimensionables, barra de estado y pantalla de arranque.

   Reglas de convivencia con el resto de hojas:
   - Se carga DESPUES de `tokens.css` y `main.css` y ANTES de `panels.css`,
     `timeline.css` y `mobile.css`. No redefine ningun control de `main.css`:
     solo los coloca y, como mucho, ajusta su tamano dentro del armazon.
   - Ningun color literal: todo sale de `tokens.css`.
   - `main.css` §20 ya fija `position:relative` y `touch-action:none` en
     `#canvas-host`. Aqui se CONSERVAN de forma explicita: si se pierden, las
     reglas y el HUD se posicionan respecto al viewport y cada trazo con el
     dedo dispara el pan/pinch nativo del navegador.

   Indice:
     1.  Raiz del documento y rejilla de #app
     2.  Estados globales (.ui-hidden, .is-drawing, .is-playing, colapsos)
     3.  Separadores redimensionables (#dock-resizer, #timeline-resizer)
     4.  #menubar
     5.  #topbar y #tool-options (controles de `ui/optionsBar.js`)
     6.  #workspace y #toolbar
     7.  #canvas-host: lienzos, reglas, HUD y cursores
     8.  #right-dock (contenedor; el contenido lo estila panels.css)
     9.  #statusbar
     10. #mobile-bar (base; `mobile.css` la despliega)
     11. #boot-splash
     12. Puntero grueso, movimiento reducido y colores forzados
   ========================================================================== */


/* ---------------------------------------------------------------------------
   1. RAIZ DEL DOCUMENTO Y REJILLA DE #app

   `main.css` da a <body> `min-height:100%`, que no resuelve a nada util
   mientras <html> mida `auto`. El editor necesita una altura REAL para que la
   fila del workspace (1fr) tenga contra que calcularse, asi que se fija aqui.
   ------------------------------------------------------------------------ */
html,
body.app-body {
  height: 100%;
  overflow: hidden;              /* el editor nunca desplaza la pagina entera */
}

/* CORRECCION NECESARIA: `main.css` declara `img, svg, video { display: block }`
   y una regla de AUTOR gana siempre a la `[hidden] { display: none }` de la
   hoja del navegador, tenga la especificidad que tenga. Sin esto, todo icono
   que un modulo oculte con `el.hidden = true` (el par reproducir/pausa, los
   iconos alternativos de los conmutadores) seguiria viendose. */
img[hidden],
svg[hidden],
video[hidden] {
  display: none;
}

#app {
  /* --- Metricas locales del armazon (evitan numeros magicos repetidos) ---- */
  --splitter-size: 2px;          /* grosor VISIBLE del separador */
  --splitter-grab: 5px;          /* ampliacion INVISIBLE de la zona de agarre */
  --bar-pad: var(--sp-3);        /* relleno lateral comun de las barras */
  --tool-btn-size: calc(var(--toolbar-w) - var(--sp-5));
  --opt-gap: 6px;                /* = CONTROL_GAP de ui/optionsBar.js */
  --opt-track-h: 6px;            /* >= MIN_TRACK_HEIGHT (4) de optionsBar.js */
  --opt-track-w: 104px;
  --hud-gap: var(--sp-4);

  position: relative;
  display: grid;
  grid-template-columns: 100%;
  grid-template-rows: auto auto minmax(0, 1fr) auto auto auto auto;
  grid-template-areas:
    "menubar"
    "topbar"
    "workspace"
    "tl-resizer"
    "timeline"
    "statusbar"
    "mobilebar";

  /* 100vh primero como respaldo; 100dvh (Chrome 108+, Safari 15.4+, FF 101+)
     lo sustituye donde exista y evita el salto de la barra del navegador. */
  height: 100vh;
  height: 100dvh;
  width: 100%;
  overflow: hidden;
  background: var(--s-0);
  color: var(--fg);

  /* Muescas y barras del sistema (el shell declara viewport-fit=cover). */
  padding-top: env(safe-area-inset-top, 0px);
  padding-right: env(safe-area-inset-right, 0px);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  padding-left: env(safe-area-inset-left, 0px);
}

#menubar   { grid-area: menubar; }
#topbar    { grid-area: topbar; }
#workspace { grid-area: workspace; }
#timeline-resizer { grid-area: tl-resizer; }
#timeline  { grid-area: timeline; }
#statusbar { grid-area: statusbar; }
#mobile-bar { grid-area: mobilebar; }

/* Las barras comparten caja: alto fijo por token y contenido centrado. */
#menubar,
#topbar,
#statusbar {
  display: flex;
  align-items: center;
  min-width: 0;
  background: var(--s-1);
  user-select: none;
  -webkit-user-select: none;
}


/* ---------------------------------------------------------------------------
   2. ESTADOS GLOBALES DE #app

   `.ui-hidden`   modo lienzo limpio (accion view.toggleUi del §41).
   `.is-drawing`  hay un trazo en curso: la interfaz deja de recibir punteros
                  para que un roce con la palma o un segundo dedo no active un
                  boton a media pincelada.
   `.is-playing`  reproduccion en marcha.
   ------------------------------------------------------------------------ */

/* Modo limpio: solo queda el lienzo. Se conservan las raices de superposicion
   (dialogos, toasts, menus) porque viven fuera de #app. */
#app.ui-hidden > #menubar,
#app.ui-hidden > #topbar,
#app.ui-hidden > #timeline-resizer,
#app.ui-hidden > #timeline,
#app.ui-hidden > #statusbar,
#app.ui-hidden > #mobile-bar,
#app.ui-hidden #toolbar,
#app.ui-hidden #dock-resizer,
#app.ui-hidden #right-dock {
  display: none;
}

/* Mientras se dibuja, TODO el cromo es inerte. No se usa `visibility` ni
   `opacity`: la interfaz debe seguir viendose, solo deja de responder. */
#app.is-drawing #menubar,
#app.is-drawing #topbar,
#app.is-drawing #toolbar,
#app.is-drawing #right-dock,
#app.is-drawing #dock-resizer,
#app.is-drawing #timeline-resizer,
#app.is-drawing #timeline,
#app.is-drawing #statusbar,
#app.is-drawing #mobile-bar {
  pointer-events: none;
}

/* Durante un trazo el HUD tapa justo la zona de trabajo; se atenua. */
#app.is-drawing #canvas-hud,
#app.is-playing #canvas-hud {
  opacity: 0;
}


/* ---------------------------------------------------------------------------
   3. SEPARADORES REDIMENSIONABLES

   `#dock-resizer` (vertical) y `#timeline-resizer` (horizontal) son los
   tiradores reales de `editor.php`. `.splitter` se acepta como alias generico
   por si otro modulo lo usa. La LOGICA del arrastre es de `ui/ui.js`: aqui
   solo se define el aspecto, el cursor y la zona de agarre.

   La franja visible mide `--splitter-size`; el pseudoelemento la amplia con
   `--splitter-grab` SIN pintar nada, para que sea comoda de agarrar con el
   raton y con el dedo. La ampliacion es asimetrica a proposito: invade menos
   el lienzo que el panel, porque robar pixeles de dibujo se nota enseguida.
   ------------------------------------------------------------------------ */
.splitter,
#dock-resizer,
#timeline-resizer {
  position: relative;
  z-index: 2;
  flex: 0 0 auto;
  background: var(--bd-soft);
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  transition: background var(--t-fast);
}

#dock-resizer {
  grid-area: dock-resizer;
  width: var(--splitter-size);
  cursor: col-resize;
}

#timeline-resizer {
  height: var(--splitter-size);
  cursor: row-resize;
}

/* Zona de agarre ampliada, invisible. */
.splitter::before,
#dock-resizer::before,
#timeline-resizer::before {
  content: "";
  position: absolute;
  inset: 0;
}

#dock-resizer::before {
  left: -3px;
  right: calc(var(--splitter-grab) * -1);
}

#timeline-resizer::before {
  top: -3px;
  bottom: calc(var(--splitter-grab) * -1);
}

.splitter:hover,
#dock-resizer:hover,
#timeline-resizer:hover,
.splitter.is-dragging,
#dock-resizer.is-dragging,
#timeline-resizer.is-dragging {
  background: var(--accent);
}

/* Foco de teclado: el separador es operable con las flechas (role=separator). */
.splitter:focus-visible,
#dock-resizer:focus-visible,
#timeline-resizer:focus-visible {
  outline: var(--focus-w) solid var(--accent-ring);
  outline-offset: 0;
  background: var(--accent);
}

/* Colapso del dock: desaparecen panel y tirador. */
#right-dock.is-collapsed,
#app.dock-collapsed #right-dock,
#app.dock-collapsed #dock-resizer {
  display: none;
}

/* El tirador va ANTES del dock en el DOM, asi que el hermano adyacente no
   sirve para ocultarlo. Esta variante con :has() va en una regla APARTE a
   proposito: mezclada con las de arriba, un navegador sin :has() descartaria
   tambien los selectores validos y el colapso dejaria de funcionar. */
#workspace:has(> #right-dock.is-collapsed) > #dock-resizer {
  display: none;
}


/* ---------------------------------------------------------------------------
   4. #menubar
   Barra densa: rama de menus, marca, nombre del proyecto y acciones rapidas.
   ------------------------------------------------------------------------ */
#menubar {
  gap: var(--sp-2);
  height: var(--menubar-h);
  padding: 0 var(--bar-pad);
  border-bottom: 1px solid var(--bd-soft);
}

/* Boton hamburguesa: solo en las disposiciones estrechas. */
.menubar-burger {
  display: none;
  flex: 0 0 auto;
}

#app[data-layout="tablet"] .menubar-burger,
#app[data-layout="mobile"] .menubar-burger {
  display: inline-flex;
}

#app[data-layout="mobile"] #menubar-items {
  display: none;
}

.menubar-brand {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex: 0 0 auto;
  height: 100%;
  padding-right: var(--sp-3);
  color: var(--fg);
  text-decoration: none;
}

.menubar-brand:hover {
  text-decoration: none;
}

.menubar-brand:hover .menubar-brand-text {
  color: var(--fg);
}

/* La marca es puramente decorativa: un rombo de acento, sin imagen externa. */
.menubar-brand-mark {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  border-radius: var(--r-sm);
  transform: rotate(45deg);
  box-shadow: var(--sh-1);
}

.menubar-brand-text {
  color: var(--fg-dim);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.04em;
  white-space: nowrap;
  transition: color var(--t-fast);
}

/* Estrechando, la marca cede el sitio antes que los menus. */
@media (max-width: 1100px) {
  .menubar-brand-text {
    display: none;
  }
}

#menubar-items {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  height: 100%;
  min-width: 0;
}

/* Ancla del desplegable: `main.css` coloca `.menu-dropdown` en
   `position:absolute; top:100%`, asi que la entrada DEBE ser el contenedor
   posicionado o el menu se colgaria del <body>. */
.menubar-entry {
  position: relative;
  display: flex;
  align-items: stretch;
}

.menubar-button {
  display: inline-flex;
  align-items: center;
  height: 100%;
  padding: 0 var(--sp-4);
  background: none;
  color: var(--fg-dim);
  border: 0;
  border-radius: var(--r-sm);
  font-size: var(--fs-md);
  line-height: 1;
  white-space: nowrap;
  transition: background var(--t-fast), color var(--t-fast);
}

.menubar-button:hover {
  background: var(--s-3);
  color: var(--fg);
}

.menubar-button[aria-expanded="true"] {
  background: var(--s-4);
  color: var(--fg);
}

/* Titulo del proyecto: ocupa el hueco central y se centra de verdad. */
#menubar-title {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  flex: 1 1 auto;
  min-width: 0;
  padding: 0 var(--sp-4);
}

.project-name-input {
  width: min(320px, 100%);
  min-width: 0;
  height: var(--ctrl-h-sm-cur);
  padding: 0 var(--sp-3);
  background: transparent;
  color: var(--fg-dim);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  text-align: center;
  text-overflow: ellipsis;
  transition: background var(--t-fast), border-color var(--t-fast),
              color var(--t-fast);
}

.project-name-input:hover {
  background: var(--s-2);
  border-color: var(--bd);
  color: var(--fg);
}

/* Al editar pasa a alineado a la izquierda: con el texto centrado, el cursor
   salta de sitio con cada pulsacion y es incomodo corregir. */
.project-name-input:focus {
  background: var(--s-2);
  border-color: var(--accent);
  color: var(--fg);
  text-align: left;
  outline: none;
}

/* Punto de "cambios sin guardar" junto al nombre. */
.project-dirty {
  width: 6px;
  height: 6px;
  flex: 0 0 auto;
  background: var(--warn);
  border-radius: var(--r-full);
}

.project-dirty[hidden] {
  display: none;
}

#menubar-right {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  flex: 0 0 auto;
}

/* Estado de guardado: punto de color + etiqueta. `ui/ui.js` mueve data-state. */
.save-state {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex: 0 0 auto;
  max-width: 160px;
  padding: 0 var(--sp-3);
  color: var(--fg-mute);
  font-size: var(--fs-xs);
  white-space: nowrap;
  overflow: hidden;
}

.save-dot {
  width: 7px;
  height: 7px;
  flex: 0 0 auto;
  background: var(--fg-mute);
  border-radius: var(--r-full);
  transition: background var(--t-fast);
}

.save-label {
  overflow: hidden;
  text-overflow: ellipsis;
}

.save-state[data-state="dirty"]  .save-dot { background: var(--warn); }
.save-state[data-state="saving"] .save-dot { background: var(--info); }
.save-state[data-state="saved"]  .save-dot { background: var(--ok); }
.save-state[data-state="error"]  .save-dot { background: var(--err); }

.save-state[data-state="error"] {
  color: var(--err);
}

/* El punto late mientras se guarda: senal de progreso que no cuesta un hilo. */
.save-state[data-state="saving"] .save-dot {
  animation: save-pulse 1.1s var(--ease) infinite;
}

@keyframes save-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

/* En pantallas estrechas solo queda el punto. */
@media (max-width: 900px) {
  .save-label {
    display: none;
  }
}


/* ---------------------------------------------------------------------------
   5. #topbar Y #tool-options

   `ui/optionsBar.js` construye aqui los controles de `tool.optionsSchema`
   (§18.1) y comprueba por `getComputedStyle` que esta hoja ya los maqueta: si
   `#tool-options` es `display:flex` y `.opt-track` mide al menos 4px de alto,
   el modulo NO aplica su respaldo en linea. Por eso ambas cosas son
   obligatorias y `--opt-track-h` nunca puede bajar de 4px.
   ------------------------------------------------------------------------ */
#topbar {
  gap: var(--sp-3);
  height: var(--topbar-h);
  padding: 0 var(--bar-pad);
  border-bottom: 1px solid var(--bd-soft);
}

#tool-options {
  display: flex;
  align-items: center;
  gap: var(--opt-gap);
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  /* Si los controles desbordan antes de que optionsBar los mueva al popover
     "mas", la fila se desplaza en horizontal en lugar de recortarse. */
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-behavior: smooth;
  scrollbar-width: none;         /* Gecko: barra oculta, no el desplazamiento */
}

#tool-options::-webkit-scrollbar {
  width: 0;
  height: 0;
}

.opt-bar {
  display: flex;
  align-items: center;
  gap: var(--opt-gap);
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
}

/* Un control: etiqueta + mando + valor. */
.opt {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex: 0 0 auto;
  min-width: 0;
  height: var(--ctrl-h-sm-cur);
}

.opt-label {
  flex: 0 0 auto;
  color: var(--fg-dim);
  font-size: var(--fs-sm);
  white-space: nowrap;
  user-select: none;
  -webkit-user-select: none;
}

/* La etiqueta de un deslizador es tambien un "scrub": arrastrarla cambia el
   valor. El cursor lo anuncia antes de tocarla. */
.opt-label-scrub {
  cursor: ew-resize;
}

.opt-label-scrub:hover,
.opt-label-scrub.is-scrubbing {
  color: var(--fg);
}

/* Raya del deslizador. `.opt-fill` recibe `width:%` y `.opt-thumb` `left:%`
   desde el modulo, asi que la pista tiene que ser el contexto posicionado. */
.opt-track {
  position: relative;
  flex: 0 0 auto;
  width: var(--opt-track-w);
  height: var(--opt-track-h);
  background: var(--s-3);
  border: 1px solid var(--bd);
  border-radius: var(--r-full);
  cursor: pointer;
}

.opt-fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  background: var(--accent);
  border-radius: var(--r-full);
  pointer-events: none;
}

.opt-thumb {
  position: absolute;
  top: 50%;
  width: 13px;
  height: 13px;
  background: var(--fg);
  border: 2px solid var(--s-1);
  border-radius: var(--r-full);
  box-shadow: var(--sh-1);
  transform: translate(-50%, -50%);
  pointer-events: none;
}

.opt-track:hover .opt-thumb,
.opt-track:focus-visible .opt-thumb {
  background: var(--accent-ring);
}

.opt-track:focus-visible {
  outline: var(--focus-w) solid var(--accent-ring);
  outline-offset: 3px;
}

.opt-value {
  width: 58px;
  flex: 0 0 auto;
  text-align: right;
}

.opt-unit {
  flex: 0 0 auto;
  color: var(--fg-mute);
  font-size: var(--fs-xs);
  user-select: none;
  -webkit-user-select: none;
}

.opt-number-input {
  width: 66px;
  flex: 0 0 auto;
  text-align: right;
}

.opt-select-input {
  max-width: 150px;
  flex: 0 1 auto;
  min-width: 0;
}

.opt-color {
  gap: var(--sp-3);
}

.opt-color-swatch {
  width: var(--ctrl-h-sm-cur);
  height: var(--ctrl-h-sm-cur);
}

.opt-color-text {
  width: 84px;
  flex: 0 0 auto;
  text-align: center;
}

.opt-seg,
.opt-more {
  flex: 0 0 auto;
}

.opt-toggle-label,
.opt-more-label {
  white-space: nowrap;
}

/* Separador vertical entre grupos de opciones. */
.opt-sep {
  width: 1px;
  height: 18px;
  flex: 0 0 auto;
  margin: 0 var(--sp-2);
  background: var(--bd);
}

/* Columna de controles desbordados (dentro de `.popover` o de `.sheet`). */
.opt-extra {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--sp-5);
  min-width: 0;
}

.opt-extra .opt {
  width: 100%;
  height: auto;
  min-height: var(--ctrl-h-sm-cur);
}

.opt-extra .opt-label {
  flex: 0 0 auto;
  min-width: 78px;
}

.opt-extra .opt-track {
  flex: 1 1 auto;
  width: auto;
}

.opt-extra .opt-sep {
  width: 100%;
  height: 1px;
  margin: var(--sp-1) 0;
}

#topbar-right {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex: 0 0 auto;
}

.zoom-value,
.rotation-value {
  min-width: 54px;
  padding: 0 var(--sp-3);
}

/* Con poco ancho la rotacion de vista estorba mas de lo que aporta: se retiran
   por accion y no por posicion, que es lo unico estable si alguien reordena la
   barra. Las mismas ordenes siguen en el menu Ver y en los atajos. */
@media (max-width: 820px) {
  #topbar-right [data-action="view.rotateLeft"],
  #topbar-right [data-action="view.rotateRight"],
  #topbar-right [data-action="view.resetRotation"],
  #topbar-right [data-action="view.flipViewH"] {
    display: none;
  }
}


/* ---------------------------------------------------------------------------
   6. #workspace Y #toolbar

   Columnas: [herramientas] [lienzo 1fr] [tirador] [dock]. El tirador es un
   item mas de la rejilla porque en `editor.php` va ENTRE el lienzo y el dock.
   ------------------------------------------------------------------------ */
#workspace {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  /* DOS filas: la de arriba es la barra de pestanas (§47.20.3) y mide `auto`, o
     sea CERO mientras la barra este `hidden`. Con un solo documento la rejilla se
     comporta exactamente como la de una fila que habia antes. */
  grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas:
    "toolbar doctabs dock-resizer dock"
    "toolbar canvas  dock-resizer dock";
  min-width: 0;
  min-height: 0;
  overflow: hidden;
}

#toolbar {
  grid-area: toolbar;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: var(--toolbar-w);
  min-width: var(--toolbar-w);
  background: var(--s-1);
  border-right: 1px solid var(--bd-soft);
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  user-select: none;
  -webkit-user-select: none;
}

/* `ui/toolbar.js` reconstruye la columna dentro de `.toolbar-inner`; el
   marcado estatico de `editor.php` cuelga los grupos directamente de
   `#toolbar`. Las dos formas tienen que verse igual. */
.toolbar-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  flex: 1 1 auto;
  width: 100%;
  min-height: 100%;
  padding: var(--sp-3) 0;
}

#toolbar > .toolbar-group:first-child {
  margin-top: var(--sp-3);
}

#toolbar > .toolbar-group:last-of-type {
  margin-bottom: var(--sp-3);
}

.toolbar-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  flex: 0 0 auto;
  width: 100%;
}

.toolbar-sep {
  width: calc(100% - var(--sp-5));
  height: 1px;
  flex: 0 0 auto;
  margin: var(--sp-3) 0;
  background: var(--bd-soft);
}

.toolbar-spacer {
  flex: 1 1 auto;
  min-height: var(--sp-5);
}


/* ---------------------------------------------------------------------------
   6.b DISPOSICION PARA ZURDOS (ajuste `leftHanded`)

   `settingsDialog.js` publica `data-left-handed` en `#app`. Con las areas de
   rejilla nombradas el volteo es una linea: se invierte el ORDEN de las
   columnas sin tocar el marcado ni el orden de tabulacion, que sigue siendo el
   de `editor.php` (herramientas primero). Los bordes de separacion cambian de
   lado con ellas, porque un borde a la derecha del dock cuando el dock esta a
   la izquierda deja el lienzo sin linea que lo cierre.

   El SENTIDO del arrastre de `#dock-resizer` tambien se voltea; eso no se puede
   hacer con CSS y lo resuelve `ui/ui.js` leyendo este mismo atributo.
   ------------------------------------------------------------------------ */
#app[data-left-handed="true"] > #workspace {
  grid-template-columns: auto auto minmax(0, 1fr) auto;
  grid-template-areas:
    "dock dock-resizer doctabs toolbar"
    "dock dock-resizer canvas  toolbar";
}

#app[data-left-handed="true"] #toolbar {
  border-right: 0;
  border-left: 1px solid var(--bd-soft);
}

#app[data-left-handed="true"] #right-dock {
  border-left: 0;
  border-right: 1px solid var(--bd-soft);
}

/* Boton de herramienta: cuadrado, sin relleno hasta que se usa. */
.tool-btn {
  position: relative;
  width: var(--tool-btn-size);
  min-width: var(--tool-btn-size);
  height: var(--tool-btn-size);
  padding: 0;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--fg-dim);
  transition: background var(--t-fast), color var(--t-fast), box-shadow var(--t-fast);
}

.tool-btn:hover:not(.is-active) {
  background: var(--s-3);
  color: var(--fg);
}

/* La herramienta activa se marca con el acento y un halo tenue en lugar de un
   relleno plano: destaca sin convertir la barra en un bloque de color. */
.tool-btn.is-active,
.tool-btn[aria-pressed="true"] {
  background: var(--accent-soft);
  color: var(--accent-ring);
  box-shadow: var(--accent-glow);
}

.tool-btn .icon {
  width: 20px;
  height: 20px;
}

/* Estado activo: `main.css` ya lo tine de acento; aqui se refuerza con una
   marca lateral para que se lea sin depender SOLO del color. */
.tool-btn[aria-checked="true"],
.tool-btn.is-active {
  background: var(--accent-soft);
  color: var(--accent-ring);
  box-shadow: inset 2px 0 0 var(--accent);
}

.tool-btn[aria-checked="true"]:hover,
.tool-btn.is-active:hover {
  background: var(--accent-soft-hover);
}

/* Esquinita de "manten pulsado para ver los preajustes". */
.tool-btn-corner {
  position: absolute;
  right: 3px;
  bottom: 3px;
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-bottom: 4px solid var(--fg-mute);
  pointer-events: none;
}

.tool-btn[aria-checked="true"] .tool-btn-corner,
.tool-btn.is-active .tool-btn-corner {
  border-bottom-color: var(--accent-ring);
}

/* Cierre del cajon de herramientas (solo movil). */
.toolbar-close {
  align-self: flex-end;
  margin: 0 var(--sp-2) var(--sp-2) 0;
}

.toolbar-close[hidden] {
  display: none;
}

/* --- Cuadros de color al pie de la columna ------------------------------- */
.toolbar-colors {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  flex: 0 0 auto;
  width: 100%;
  padding: var(--sp-4) 0 var(--sp-3);
  border-top: 1px solid var(--bd-soft);
}

/* Los dos cuadros se solapan como en un editor clasico: el primario delante,
   el secundario asomando por detras en diagonal. */
.color-stack {
  --slot-size: calc(var(--tool-btn-size) - var(--sp-4));
  position: relative;
  width: calc(var(--slot-size) + var(--sp-5));
  height: calc(var(--slot-size) + var(--sp-5));
  flex: 0 0 auto;
}

.color-slot {
  position: absolute;
  width: var(--slot-size);
  height: var(--slot-size);
  border: 1px solid var(--bd-strong);
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
}

.color-slot.color-secondary {
  right: 0;
  bottom: 0;
}

.color-slot.color-primary {
  left: 0;
  top: 0;
  z-index: 1;
}

.color-slot:focus-visible {
  outline: var(--focus-w) solid var(--accent-ring);
  outline-offset: 2px;
  z-index: 2;
}

.color-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1px;
  flex-wrap: wrap;
}


/* ---------------------------------------------------------------------------
   7. #canvas-host: LIENZOS, REGLAS, HUD Y CURSORES

   OJO: `position:relative` y `touch-action:none` vienen de `main.css` §20 y se
   repiten aqui A PROPOSITO. Esta hoja se carga despues; si un ajuste futuro de
   este bloque las diera por sobreentendidas y las perdiera, el dibujo tactil
   dejaria de funcionar y las reglas se irian al viewport.
   ------------------------------------------------------------------------ */
#canvas-host {
  grid-area: canvas;
  position: relative;            /* origen de reglas, HUD y overlays */
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  /* Fondo NEUTRO y plano, distinto del lienzo: cualquier textura o degradado
     falsearia la percepcion del color que se esta pintando. */
  background: var(--canvas-bg);
  touch-action: none;            /* el gesto es del InputManager */
  outline: none;                 /* el foco se marca con el anillo interior */
}

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

/* ---------------------------------------------------------------------------
   7.b #doc-tabs: LAS PESTANAS DE DOCUMENTO (§47.20.3)

   `hidden` mientras haya un solo documento, y entonces su fila de la rejilla mide
   cero: quien nunca abra un segundo documento no pierde ni un pixel de lienzo.
   Ojo: hace falta `display:none` explicito, porque `display:flex` en un elemento
   con el atributo `hidden` GANA al valor por defecto del atributo y la barra se
   veria siempre.
   ------------------------------------------------------------------------ */
#doc-tabs {
  grid-area: doctabs;
  display: flex;
  align-items: stretch;
  gap: 2px;
  min-width: 0;
  padding: 3px 4px 0;
  background: var(--s-1);
  border-bottom: 1px solid var(--bd-soft);
  /* Muchas pestanas: se desplazan en lugar de encogerse hasta ser ilegibles. */
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
}

#doc-tabs[hidden] { display: none; }

.doc-tab {
  display: flex;
  align-items: center;
  gap: 6px;
  max-width: 220px;
  min-width: 0;
  padding: 4px 6px 4px 10px;
  border: 1px solid var(--bd-soft);
  border-bottom: 0;
  border-radius: 6px 6px 0 0;
  background: var(--s-2);
  color: var(--fg-dim);
  font-size: 12px;
  line-height: 1.5;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}

.doc-tab:hover { color: var(--fg); }

.doc-tab.is-active {
  background: var(--canvas-bg);
  color: var(--fg);
  /* El borde inferior del contenedor se tapa: es lo que une visualmente la
     pestana activa con el lienzo y hace que se lea como «esto es lo de delante». */
  margin-bottom: -1px;
  padding-bottom: 5px;
}

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

.doc-tab-name {
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

/* El punto de «sin guardar», DELANTE del nombre: detras, un nombre largo lo
   empuja fuera de la pestana y justo entonces es cuando hace falta verlo. */
.doc-tab-dot {
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

.doc-tab-close {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  padding: 0;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: inherit;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  opacity: 0.55;
}

.doc-tab-close:hover {
  background: var(--accent-soft);
  opacity: 1;
}

.doc-tab-new {
  flex: 0 0 auto;
  align-self: center;
  width: 22px;
  height: 22px;
  margin-left: 2px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--fg-dim);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}

.doc-tab-new:hover {
  background: var(--accent-soft);
  color: var(--fg);
}

/* En pantalla estrecha caben menos: se dejan mas cortas antes que apiladas. */
@media (max-width: 720px) {
  .doc-tab { max-width: 130px; }
}


#view-canvas {
  z-index: 0;
}

#overlay-canvas {
  z-index: 1;
  pointer-events: none;          /* quien captura el gesto es #canvas-host */
}

/* --- Reglas del documento ------------------------------------------------
   Se dibujan SOBRE el lienzo (no lo desplazan) porque el renderer fija el
   tamano CSS de #view-canvas al host completo.
   Nacen ocultas: el boton `view.rulers` de `editor.php` arranca con
   aria-pressed="false". `#app.rulers-on` las muestra y `#app.rulers-off`
   vuelve a ocultarlas pase lo que pase.
   ------------------------------------------------------------------------ */
#ruler-h,
#ruler-v,
#ruler-corner {
  position: absolute;
  z-index: 2;
  display: none;
  background: var(--s-1);
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
}

/* Las medidas van EXPLICITAS, no con `right: 0` / `bottom: 0`.
   Un <canvas> es un elemento REEMPLAZADO: colocado en absoluto con `left` y
   `right` puestos pero `width: auto`, el navegador NO lo estira de canto a
   canto, sino que le da su tamano intrinseco (el de sus atributos width/height,
   ajustado a la altura impuesta) y descarta `right`. Medido: la regla salia de
   15x18 px en vez de ocupar todo el ancho. Con `calc()` el tamano es explicito
   y deja de depender de la relacion de aspecto del bitmap. */
#ruler-h {
  top: 0;
  left: var(--ruler-size);
  width: calc(100% - var(--ruler-size));
  height: var(--ruler-size);
  border-bottom: 1px solid var(--bd);
}

#ruler-v {
  top: var(--ruler-size);
  left: 0;
  width: var(--ruler-size);
  height: calc(100% - var(--ruler-size));
  border-right: 1px solid var(--bd);
}

#ruler-corner {
  top: 0;
  left: 0;
  width: var(--ruler-size);
  height: var(--ruler-size);
  border-right: 1px solid var(--bd);
  border-bottom: 1px solid var(--bd);
}

#app.rulers-on #ruler-h,
#app.rulers-on #ruler-v,
#app.rulers-on #ruler-corner {
  display: block;
}

#app.rulers-off #ruler-h,
#app.rulers-off #ruler-v,
#app.rulers-off #ruler-corner {
  display: none;
}

/* Visibles, las reglas SI aceptan el puntero: de ahi se arrastran las guias. */
#app.rulers-on #ruler-h,
#app.rulers-on #ruler-v {
  pointer-events: auto;
  touch-action: none;
}

#app.rulers-on #ruler-h { cursor: ns-resize; }
#app.rulers-on #ruler-v { cursor: ew-resize; }

/* --- HUD flotante (zoom, coordenadas, medidas de seleccion) --------------- */
#canvas-hud {
  position: absolute;
  left: var(--hud-gap);
  bottom: var(--hud-gap);
  z-index: 3;
  max-width: calc(100% - var(--hud-gap) * 2);
  padding: 3px var(--sp-4);
  background: var(--s-2);
  color: var(--fg-dim);
  border: 1px solid var(--bd);
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;          /* nunca se interpone en el dibujo */
  user-select: none;
  -webkit-user-select: none;
  transition: opacity var(--t-fast);
}

/* Sin texto no debe quedar una caja vacia flotando sobre el lienzo. */
#canvas-hud:empty,
#canvas-hud[hidden] {
  display: none;
}

/* Con las reglas visibles, el HUD se aparta del canto izquierdo. */
#app.rulers-on #canvas-hud {
  left: calc(var(--ruler-size) + var(--hud-gap));
}

/* --- Cursores por herramienta --------------------------------------------
   `tools/toolManager.js` escribe `host.style.cursor = tool.cursor` (un cursor
   NATIVO) al activar una herramienta, y ese estilo en linea gana a cualquier
   clase. Estas clases son el segundo camino: sirven para cualquier elemento y
   para #canvas-host cuando no hay cursor en linea. Nunca llevan !important,
   porque eso romperia el cursor temporal que `tool-navigate.js` pone mientras
   dura un arrastre.

   Los cursores SVG llevan SIEMPRE un cursor nativo de respaldo tras la coma:
   si el navegador no admite `url()` en `cursor` (o la imagen no carga), cae al
   nativo en lugar de quedarse sin cursor.
   ------------------------------------------------------------------------ */
.cursor-default     { cursor: default; }
.cursor-crosshair   { cursor: crosshair; }
.cursor-move        { cursor: move; }
.cursor-text        { cursor: text; }
.cursor-pan         { cursor: grab; }
.cursor-pan:active,
.cursor-panning     { cursor: grabbing; }
.cursor-zoom-in     { cursor: zoom-in; }
.cursor-zoom-out    { cursor: zoom-out; }
.cursor-wait        { cursor: progress; }
.cursor-blocked     { cursor: not-allowed; }
.cursor-none        { cursor: none; }

/* Pincel: anillo blanco perfilado en negro para que se lea sobre cualquier
   color. Punto activo en el centro (11 11). */
.cursor-brush {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22'%3E%3Ccircle cx='11' cy='11' r='7.5' fill='none' stroke='%23000000' stroke-opacity='.7' stroke-width='3'/%3E%3Ccircle cx='11' cy='11' r='7.5' fill='none' stroke='%23ffffff' stroke-width='1.4'/%3E%3Ccircle cx='11' cy='11' r='1' fill='%23ffffff'/%3E%3C/svg%3E") 11 11, crosshair;
}

/* Borrador: cuadrado, mismo doble perfilado. */
.cursor-eraser {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22'%3E%3Crect x='3.5' y='3.5' width='15' height='15' rx='2' fill='none' stroke='%23000000' stroke-opacity='.7' stroke-width='3'/%3E%3Crect x='3.5' y='3.5' width='15' height='15' rx='2' fill='none' stroke='%23ffffff' stroke-width='1.4'/%3E%3C/svg%3E") 11 11, crosshair;
}

/* Cuentagotas: la punta activa es la esquina inferior izquierda (3 18). */
.cursor-eyedropper {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22'%3E%3Cpath d='M3 19l4-1 10-10-3-3L4 15z' fill='%23ffffff' stroke='%23000000' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E") 3 18, crosshair;
}

/* Relleno: cubo con la punta activa tambien abajo a la izquierda. */
.cursor-fill {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22'%3E%3Cpath d='M4 18l8-8 6 6-4 4z' fill='%23ffffff' stroke='%23000000' stroke-width='1.4' stroke-linejoin='round'/%3E%3Ccircle cx='4' cy='18' r='1.6' fill='%23000000'/%3E%3C/svg%3E") 4 18, crosshair;
}


/* ---------------------------------------------------------------------------
   8. #right-dock (contenedor)
   El interior de cada panel lo estila `panels.css`.
   ------------------------------------------------------------------------ */
#right-dock {
  grid-area: dock;
  display: flex;
  flex-direction: column;
  width: var(--dock-w);
  min-width: var(--dock-w-min);
  max-width: var(--dock-w-max);
  min-height: 0;
  background: var(--s-1);
  border-left: 1px solid var(--bd-soft);
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
}


/* ---------------------------------------------------------------------------
   9. #statusbar
   ------------------------------------------------------------------------ */
#statusbar {
  gap: var(--sp-2);
  height: var(--statusbar-h);
  min-height: var(--statusbar-h);
  padding: 0 var(--sp-4);
  border-top: 1px solid var(--bd-soft);
  color: var(--fg-dim);
  font-size: var(--fs-xs);
  line-height: 1;
  white-space: nowrap;
  overflow: hidden;
}

.status-item {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  height: 100%;
  white-space: nowrap;
}

/* Los `.status-item` que ademas son boton no deben convertir la barra de
   estado en una barra de botones: se rebajan al alto disponible. */
.status-item.btn {
  height: calc(var(--statusbar-h) - 4px);
  min-width: 0;
  padding: 0 var(--sp-3);
  font-size: var(--fs-xs);
}

.status-hint {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--fg-mute);
}

#statusbar .divider-v {
  height: 12px;
  min-height: 0;
  margin: 0 var(--sp-2);
}

#statusbar .input {
  height: calc(var(--statusbar-h) - 4px);
  min-height: 0;
  padding: 0 var(--sp-3);
  font-size: var(--fs-xs);
}

/* En pantallas estrechas se sacrifican los datos secundarios, nunca el aviso
   de la herramienta activa. */
@media (max-width: 760px) {
  #status-mem,
  #status-doc,
  #status-pos {
    display: none;
  }
}


/* ---------------------------------------------------------------------------
   10. #mobile-bar
   Oculta por defecto. `mobile.css` la despliega en su media query; aqui solo
   se deja el comportamiento minimo para que el editor siga siendo usable
   aunque esa hoja no llegue a cargarse.
   ------------------------------------------------------------------------ */
#mobile-bar {
  display: none;
  align-items: stretch;
  justify-content: space-around;
  height: var(--mobile-bar-h);
  background: var(--s-1);
  border-top: 1px solid var(--bd);
}

#app[data-layout="mobile"] > #mobile-bar {
  display: flex;
}

.mobile-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
  padding: 0 var(--sp-1);
  border-radius: 0;
}

.mobile-btn .icon {
  width: 20px;
  height: 20px;
}

.mobile-btn-label {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-xs);
  font-weight: var(--fw-regular);
}


/* ---------------------------------------------------------------------------
   11. #boot-splash

   El CSS critico de `editor.php` ya lo pinta antes de que existan las hojas.
   Esto solo lo afina: pasa el z-index al token, da tipografia de marca y anade
   una animacion sutil. El OCULTADO (`.is-hidden`, `[hidden]`, `data-booted`)
   se define alli y NO se toca: duplicarlo abriria la puerta a dos verdades.
   ------------------------------------------------------------------------ */
#boot-splash {
  z-index: var(--z-boot);
  gap: var(--sp-6);
  background: var(--s-0);
}

#boot-splash .boot-logo {
  font-size: var(--fs-2xl);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.24em;
  text-indent: 0.24em;           /* compensa el hueco de la ultima letra */
  text-transform: uppercase;
  color: var(--fg);
  /* Respiracion muy lenta: se nota que la aplicacion esta viva sin distraer. */
  animation: boot-breathe 2.8s var(--ease) infinite;
}

#boot-splash .boot-claim {
  font-size: var(--fs-sm);
  letter-spacing: var(--ls-wide);
  text-indent: var(--ls-wide);
  text-transform: uppercase;
  color: var(--fg-mute);
}

#boot-splash .boot-bar {
  width: 168px;
  height: 2px;
  background: var(--s-3);
  border-radius: var(--r-full);
}

#boot-splash .boot-bar i {
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
}

#boot-splash .boot-error {
  color: var(--err);
  font-size: var(--fs-md);
}

@keyframes boot-breathe {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.68; }
}


/* ---------------------------------------------------------------------------
   12. PUNTERO GRUESO, MOVIMIENTO REDUCIDO Y COLORES FORZADOS
   ------------------------------------------------------------------------ */
@media (pointer: coarse) {
  #app {
    /* Con el dedo hace falta mas raya y mucha mas zona de agarre. */
    --splitter-size: 3px;
    --splitter-grab: 10px;
    --opt-track-h: 8px;
    --opt-track-w: 120px;
  }

  .opt {
    height: var(--ctrl-h-cur);
  }

  .opt-thumb {
    width: 18px;
    height: 18px;
  }

  /* El nombre del proyecto necesita un objetivo tactil real. */
  .project-name-input {
    height: var(--ctrl-h-cur);
  }

  /* Los separadores se localizan peor sin cursor: se refuerzan. */
  #dock-resizer,
  #timeline-resizer {
    background: var(--s-hi);
  }
}

@media (prefers-reduced-motion: reduce) {
  #boot-splash .boot-logo,
  .save-state[data-state="saving"] .save-dot {
    animation: none;
  }

  #tool-options {
    scroll-behavior: auto;
  }
}

/* Alto contraste de Windows: el color desaparece, asi que los estados se
   apoyan en los bordes y en los colores del sistema. */
@media (forced-colors: active) {
  #dock-resizer,
  #timeline-resizer,
  #menubar,
  #topbar,
  #statusbar,
  #toolbar,
  #right-dock,
  #canvas-hud {
    border-color: CanvasText;
  }

  .tool-btn[aria-checked="true"],
  .tool-btn.is-active {
    forced-color-adjust: none;
    background: Highlight;
    color: HighlightText;
    box-shadow: none;
  }
}
