/* ─────────────────────────────────────────────────────────────
   HW_OS — Tokens canónicos
   Reemplaza los bloques :root inline de cada Blade.
   Cargar UNA vez en app.blade.php, antes de cualquier vista.

   Corrige tres derivas detectadas en producción:
     --hw-dark   #272727 → #262320  (tinta cálida del sistema)
     --hw-green  #0d7400 → #1a8c3e  (verde de marca)
     --hw-purple #5b4be8 → eliminado (Fases usa --hw-blue)
   ───────────────────────────────────────────────────────────── */
:root {
  /* Tinta de respaldo para TODO el sistema.
   *
   * `--app-ink` se definía sólo dentro de `.hw-micro`, y el escritorio
   * (`body.hw-nucleo`) no la lleva: ahí el color de `.hw-lbl` queda sin valor y
   * el rótulo hereda el de quien lo contenga —bien por casualidad casi
   * siempre, mal el día que lo contiene un pleno—. Las mini
   * apps y cada `.hw-app-*` la siguen pisando con la suya, así que esto no
   * cambia nada de lo que ya funcionaba. */
  --app-ink: #262320;

  /* ── Marca ── */
  --hw-blue:   #1d2385;
  --hw-yellow: #fac23c;
  --hw-pink:   #fe2696;
  --hw-red:    #f50538;
  --hw-green:  #1a8c3e;

  /* ── Neutros cálidos ── */
  --hw-dark:   #262320;
  --hw-white:  #fdfcfa;
  --hw-cream:  #f6efe4;
  --hw-sand:   #ece1d0;
  --hw-paper:  #fffdf8;
  --hw-gray-1: #efe9df;
  --hw-gray-2: #ddd3c4;
  --hw-gray-3: #8f877b;

  /* ── Tipos de acción (significado fijo) ── */
  --type-gestion:     var(--hw-yellow);
  --type-produccion:  var(--hw-green);
  --type-publicacion: var(--hw-pink);

  /* ── Estados de acción (ciclo de 3) ── */
  --est-iniciada-bg:   transparent;
  --est-iniciada-fg:   var(--hw-dark);
  --est-pausada-bg:    rgba(38,35,32,.14);
  --est-pausada-fg:    var(--hw-dark);
  --est-completada-bg: var(--hw-dark);
  --est-completada-fg: var(--hw-paper);

  /* ── Geometría: registro producto (neobrutalista) ── */
  --bd-w:      3px;
  --radius-sm: 0;
  --shadow:    4px 4px 0 var(--hw-dark);
  --shadow-sm: 2px 2px 0 var(--hw-dark);
  --shadow-lg: 6px 6px 0 var(--hw-dark);

  /* ── Tipografía ── */
  --font-display: 'Space Grotesk', sans-serif;
  --font-mono:    'Roboto Mono', monospace;
  --fs-micro: 7.5px;
  --fs-label: 8.5px;
  --ls-tag:   .1em;
  --ls-label: .14em;

  /* ── Motion ── */
  --dur:      140ms;
  --ease-out: cubic-bezier(.2,.9,.3,1);
}

/* ─────────────────────────────────────────────────────────────
   Registro MICROGRAPHIC — para las mini-apps móviles.
   Se activa poniendo .hw-micro en el contenedor raíz de la app,
   más --app-ink con el color de esa app.
   Aplana la geometría y redirige el duotono.
   ───────────────────────────────────────────────────────────── */
.hw-micro {
  --hw-dark:  var(--app-ink);
  --hw-white: var(--hw-paper);
  --hw-red:   var(--app-ink);

  --hw-gray-1: color-mix(in srgb, var(--app-ink) 6%,  transparent);
  --hw-gray-2: color-mix(in srgb, var(--app-ink) 20%, transparent);
  --hw-gray-3: color-mix(in srgb, var(--app-ink) 50%, transparent);

  --bd-w:      1.5px;
  --radius-sm: 0;
  --shadow:    none;
  --shadow-sm: none;
  --shadow-lg: none;

  /* Tinta por defecto. Sin esto, una app sin su clase `.hw-app-*` deja
     `--app-ink` sin definir y todo lo que la usa se cae en silencio: los
     `background` quedan transparentes y —peor— cada `color-mix()` que la
     nombra se vuelve inválido, así que desaparecen las líneas de sección.
     La pantalla renderiza igual y sólo se ve rota en el teléfono. */
  --app-ink: #262320;

  background: var(--hw-paper);
  color: var(--app-ink);
  font-family: var(--font-display);
}

/* Color por mini-app · F1-R4 — LA TINTA SOSTIENE, EL COLOR DECLARA.
   
   Cada app tenía UNA tinta que pintaba todo —bordes, texto, fondos y banda— y
   con el magenta de Press o el verde de Rutinas la pantalla entera quedaba
   teñida: el sistema se leía como ocho productos distintos. Ahora `--app-ink`
   es la tinta que SOSTIENE (#262320, o índigo si la app es del eje del tiempo)
   y `--app-acento` es el color que DECLARA, y vive sólo en la banda del
   encabezado (en trama, nunca plena) y en la pestaña activa.
   
   La tabla que manda es `Registro::MINI`; esto la refleja. Si una app aparece
   allá y falta acá, `--app-ink` queda sin definir y la pantalla pierde bordes y
   fondos sin dar un solo error. */

/* Del eje del tiempo: índigo o tinta, sin acento. */
.hw-app-working { --app-ink: #1d2385; }
.hw-app-ideas   { --app-ink: #262320; }

/* COM-040 · El acento NO es decoración: aparece sólo en lo que urge y en lo
   que está cerrado. Si se usa para otra cosa, deja de avisar. */
.hw-app-comunicador { --app-ink: #1d2385; --app-acento: #f50538; }

/* Familia magenta */
.hw-app-press     { --app-ink: #262320; --app-acento: #fe2696; }
.hw-app-pantallas { --app-ink: #262320; --app-acento: #fe2696; }
.hw-app-radio     { --app-ink: #262320; --app-acento: #fe2696; }
.hw-app-captura   { --app-ink: #262320; --app-acento: #fe2696; }

/* Familia verde */
.hw-app-medios     { --app-ink: #262320; --app-acento: #1a8c3e; }
.hw-app-documentos { --app-ink: #262320; --app-acento: #1a8c3e; }
.hw-app-protocols  { --app-ink: #262320; --app-acento: #1a8c3e; }

/* Familia ámbar */
.hw-app-brand   { --app-ink: #262320; --app-acento: #fac23c; }
.hw-app-rutinas { --app-ink: #262320; --app-acento: #fac23c; }

/* ── Primitivas micrographic ── */
.hw-lbl {
  font-family: var(--font-mono); font-weight: 700; font-size: var(--fs-label);
  text-transform: uppercase; letter-spacing: var(--ls-label); line-height: 1;
  color: var(--app-ink);
}
.hw-lbl--dim { opacity: .55; }
.hw-lbl--on  { color: var(--hw-paper); }

.hw-ref {
  font-family: var(--font-mono); font-weight: 500; font-size: 8px;
  letter-spacing: .1em; color: var(--hw-gray-3);
}

/* Filete con label:  ── LABEL ────────── */
.hw-rule { display: flex; align-items: center; gap: 9px; padding-bottom: 7px; }
.hw-rule__line { flex: 1; height: 1px; background: var(--hw-gray-2); }

/* Fila de ficha técnica con línea punteada */
.hw-spec { display: flex; align-items: baseline; gap: 10px; padding: 7px 0;
  border-bottom: 1px solid var(--hw-gray-2); }
.hw-spec__k { flex-shrink: 0; min-width: 74px; }
.hw-spec__dots { flex: 1; border-bottom: 1px dotted var(--hw-gray-2); transform: translateY(-3px); }
.hw-spec__v { font-family: var(--font-mono); font-weight: 700; font-size: 11.5px;
  color: var(--app-ink); letter-spacing: .02em; flex-shrink: 0; }

/* Botón de estado — ciclo de 4: Pendiente → Iniciada → Pausada → Completada */
.hw-est {
  width: 40px; height: 40px; flex-shrink: 0; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: var(--bd-w) solid var(--app-ink); border-radius: var(--radius-sm);
  background: var(--est-iniciada-bg); color: var(--app-ink);
  cursor: pointer; transition: background var(--dur) var(--ease-out);
}
/* Sin iniciar: contorno tenue, sin peso visual */
.hw-est[data-estado="Pendiente"]  { border-color: var(--hw-gray-2); color: var(--hw-gray-3); background: transparent; }
.hw-est[data-estado="Pausada"]    { background: color-mix(in srgb, var(--app-ink) 14%, transparent); }
.hw-est[data-estado="Completada"] { background: var(--app-ink); color: var(--hw-paper); }
/* ACC-32 · Descartada: se decidió no hacerla. Ni contorno de pendiente ni
   pleno de logro — achurado, que es como el registro dice «resuelto que no». */
.hw-est[data-estado="Descartada"] {
  border-color: color-mix(in srgb, var(--app-ink) 45%, transparent);
  color: var(--hw-gray-3);
  background-image: repeating-linear-gradient(45deg,
    color-mix(in srgb, var(--app-ink) 32%, transparent) 0 1px, transparent 1px 5px);
}
.hw-est:active { transform: scale(.94); }

/* Título de acción que se corrige en la fila (ACC-38).
   El display vive acá y NO en el style en línea: `x-show` pisa el display
   inline al ocultar y lo devuelve vacío al mostrar, así que un `display:block`
   escrito en el atributo desaparece la primera vez que el campo se abre. */
.hw-titw { display: block; min-width: 0; }
.hw-tit  { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hw-tit-edit {
  display: block; width: 100%; box-sizing: border-box;
  background: var(--hw-paper); border: 1px solid var(--app-ink);
  padding: 2px 6px; outline: none; color: var(--app-ink);
}

/* Prioridad — tres puntos redondos */
.hw-prio { display: inline-flex; gap: 3px; align-items: center; flex-shrink: 0; }
.hw-prio i {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--hw-gray-2); border: 1px solid var(--hw-gray-3);
}
.hw-prio[data-nivel="1"] i:nth-child(1),
.hw-prio[data-nivel="2"] i:nth-child(-n+2),
.hw-prio[data-nivel="3"] i { background: var(--app-ink); border-color: var(--app-ink); }

/* Cuadro de ícono */
.hw-icobox {
  flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border: 1.5px solid var(--app-ink);
  transition: background var(--dur) var(--ease-out);
}
.hw-icobox--active { background: var(--app-ink); color: var(--hw-paper); }

/* Regla graduada */
.hw-ruler { display: flex; align-items: flex-end; height: 7px; }
.hw-ruler i { flex: 1; height: 3px; border-left: 1px solid var(--hw-gray-2); }
.hw-ruler i:nth-child(5n+1) { height: 7px; border-left-color: var(--hw-gray-3); }

/* Trama diagonal para placeholders de asset */
.hw-hatch {
  background: repeating-linear-gradient(45deg,
    color-mix(in srgb, var(--app-ink) 13%, transparent) 0 4px,
    transparent 4px 10px);
}

/* Fila activa — jerarquía dinámica */
.hw-row { border-left: 4px solid transparent; transition:
  opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out); }
.hw-row--active { border-left-color: var(--app-ink); }
.hw-row--muted  { opacity: .55; transform: scale(.985); transform-origin: left center; }

/* Safe area iOS — ver Archivo/handoff-mini-apps-v2/PWA-iOS.md

   Arriba no hay nada que compensar: con `apple-mobile-web-app-status-bar-style:
   black` iOS reserva la franja del reloj y `env(safe-area-inset-top)` vale 0
   dentro de la web. La regla queda por si alguna vista corre en Safari normal.

   Abajo, reservar los 34px enteros de la zona segura se ve como espacio perdido
   en una app instalada; reservar cero pone los botones bajo el indicador de
   inicio y el sistema se queda con el toque. Un cuarto fue el punto medio,
   medido en el aparato. */
.hw-safe-top    { padding-top: env(safe-area-inset-top); }
.hw-safe-bottom { padding-bottom: max(8px, calc(env(safe-area-inset-bottom) * .25)); }

/* ─────────────────────────────────────────────────────────────
   Teclado en pantalla — iOS / iPadOS
   Tres reglas que hay que aplicar juntas; con una sola no alcanza.
   ───────────────────────────────────────────────────────────── */

/* 1 · El marco NO se mide: se clava.

      Medir el alto falla de tres maneras y las tres dejaban una franja al pie:
      `100vh` no cuenta la zona segura, `100dvh` es el viewport DINÁMICO —iOS
      informa un alto en la primera pintada y otro tras el primer gesto, así que
      la barra salía alta y bajaba sola al deslizar— y medir con JS llega tarde.

      `position: fixed; inset: 0` es una afirmación, no un cálculo: el marco
      llega abajo porque se lo decimos. La única excepción es el teclado, más
      abajo: ahí el alto disponible cambió de verdad y sí hay que medirlo. */
.hw-app-shell {
  position: fixed;
  inset: 0;
  height: auto;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}

/* 2 · La barra de captura queda al final del flujo, no fixed.
        Un elemento fixed al fondo lo tapa el teclado en iOS. */
.hw-capture { flex-shrink: 0; }

/* 3 · Cuando el teclado está arriba, la lista cede el alto.
        Se activa desde JS con el visualViewport (ver más abajo). */
.hw-kb-open .hw-scroll   { min-height: 0; }
.hw-kb-open .hw-hide-kb  { display: none; }   /* home indicator, reglas de pie */

/* Compensación del inset inferior cuando NO hay teclado — un cuarto, no entero */
.hw-capture { padding-bottom: max(8px, calc(env(safe-area-inset-bottom) * .25)); }
.hw-kb-open .hw-capture { padding-bottom: 0; }

/* ──────────────────────────────────────────────────────────────
   JS que acompaña (poner en el layout de la mini-app):

   const vv = window.visualViewport;
   if (vv) {
     const sync = () => {
       // Alto real disponible, descontando el teclado
       document.documentElement.style.setProperty('--vvh', vv.height + 'px');
       // El teclado ocupa más de 120px → estado abierto
       const open = (window.innerHeight - vv.height) > 120;
       document.body.classList.toggle('hw-kb-open', open);
       // iOS desplaza la página al enfocar; lo devolvemos a cero
       if (open) window.scrollTo(0, 0);
     };
     vv.addEventListener('resize', sync);
     vv.addEventListener('scroll', sync);
     sync();
   }

   …y en el shell usar var(--vvh) con respaldo:
     .hw-app-shell { height: var(--vvh, 100dvh); }
   ────────────────────────────────────────────────────────────── */

/* La excepción a «no medir»: con el teclado arriba el alto disponible cambió de
   verdad, y ahí `--vvh` es el único dato correcto. `bottom:auto` suelta el clavo
   de abajo para que el alto medido mande. */
.hw-kb-open .hw-app-shell { bottom: auto; height: var(--vvh, 100dvh); }

/* COM-042 · `x-show` borra el `display` escrito en el atributo `style` al
   ocultar y devolverlo: todo elemento con x-show lleva el flex en ESTA clase,
   nunca en línea. (La trampa de Alpine que ya rompió pantallas tres veces.) */
.hw-flex { display: flex; }

/* SYS-23 · Recuadro de papel dentro de una banda con trama.
 *
 * La banda le pone su propio fondo de papel a lo que va adentro, para que se
 * lea sobre la trama. Pero las pantallas que llenan ese hueco escriben sus
 * rótulos con `on` —color papel, pensado para fondo pleno— y el resultado era
 * papel sobre papel: el texto existía y no se veía.
 *
 * Forzar `inherit` en los descendientes lo resuelve de una vez y para todas
 * las pantallas, que es lo que el componente ya prometía: «ninguna página
 * tiene que enterarse». */
.hw-sobre-papel * { color: inherit !important; }

/* SYS-26 · Lo que se abre con pulsación larga no se puede seleccionar.
 *
 * En el teléfono, mantener el dedo sobre un texto le dice al sistema «quiero
 * seleccionar»: aparecen los manijas azules y la barra nativa de Copiar ·
 * Consultar · Traducir JUSTO ENCIMA del menú que acaba de abrirse. Dos menús
 * peleando por el mismo gesto, y el nuestro debajo.
 *
 * `touch-callout` es lo que apaga la barra de iOS; `user-select` lo que evita
 * los manijas. Van juntos: cada uno sin el otro deja la mitad del problema.
 *
 * Se pone en el elemento que ESCUCHA la pulsación, no en el contenedor: el
 * texto que uno sí quiere poder copiar —el cuerpo de una idea— no debe
 * heredarlo. */
.hw-presionable,
.hw-presionable * {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}


/* ── MIN-14 · Piso de 9px en las mini apps ──
 *
 * En el escritorio un rótulo de 7,5px se lee: la pantalla está a medio metro y
 * es grande. En un teléfono en la mano, no — y menos con sol encima, que es
 * donde se usa Captura. El piso se aplica SÓLO bajo `.hw-micro`, que es el
 * cuerpo del layout de las minis: el núcleo (`.hw-nucleo`) conserva su escala.
 *
 * Se sube el piso, no la jerarquía: los tamaños siguen escalonados, sólo que
 * el escalón más bajo pasa a ser legible. */
.hw-micro {
  --fs-micro: 9px;
  --fs-label: 9px;
}

.hw-micro .hw-ref { font-size: 9px; }
