/* ==========================================================================
   Alcavo Solutions — paletas y temas

   El color de la marca es ORO: grafito calido y oro viejo. Es la unica familia
   que queda; las veintisiete que se probaron y se descartaron estan guardadas
   en ../paletas-descartadas.css, que no se carga.

   Se conserva el eje data-palette aunque solo haya un valor: el tema claro y
   el oscuro siguen siendo dos, el panel de ?paletas sigue funcionando para la
   tipografia, y recuperar una familia es volver a pegar su bloque.

     data-palette  familia de color (oro)
     data-theme    claro u oscuro

   Todo el color del sitio vive aquí; site.css no tiene ni un valor de color
   suelto, y el dibujo del hero lee estos tokens en tiempo de ejecución, así
   que también cambia con el tema.

   Cómo se usa:
     - Por defecto: los atributos data-palette y data-theme del <html>.
     - Probar tipografías: abrir con ?paletas. Con ?paletas&tipo=NOMBRE se
       abre una directa, que es la forma de pasarle a alguien la pantalla
       exacta.
     - El botón de tema respeta la preferencia del sistema la primera vez y
       recuerda la elección del visitante a partir de ahí.

   Tokens (semánticos, no descriptivos, para que sirvan en claro y en oscuro):
     --bg / --bg-alt   fondo y fondo de secciones alternas
     --fg / --fg-2     texto principal y secundario
     --mut             texto apagado
     --line / --line-2 líneas finas y bordes con presencia
     --line-3          bordes que tienen que leerse como objetos, no como
                       separadores (los marcos de las capturas)
     --surface         superficies elevadas (marcos de ventana, maquetas)
     --acc             acento; --acc-fg es el texto que va encima
     --inv-*           bloque invertido (la sección de contacto)
     --ok / --wait     estados dentro de las maquetas
   ========================================================================== */

/* ============================================ ORO — grafito calido y oro viejo */
[data-palette="oro"][data-theme="dark"] {
  --bg: #070706;      --bg-alt: #181713;   --surface: #14130f;
  --fg: #f1eee5;      --fg-2: #cbc6b8;     --mut: #969084;
  --line: #22201a;    --line-2: #322f26;    --line-3: #4a4433;
  --acc: #dcb264;     --acc-fg: #100f0c;   --acc-hover: #eecb8c;
  --acc-soft: #1d1810; --acc-line: #3d331d;
  --inv-bg: #f1eee5;  --inv-fg: #100f0c;   --inv-mut: #55524a;
  --inv-line: #d9d4c7; --inv-acc: #7a5b16;
}
[data-palette="oro"][data-theme="light"] {
  --bg: #f4f1e9;      --bg-alt: #e8e4d8;   --surface: #fffdf7;
  --fg: #14120d;      --fg-2: #38352b;     --mut: #5c5749;
  --line: #ddd8c8;    --line-2: #c8c2ae;    --line-3: #a79f86;
  --acc: #7a5b16;     --acc-fg: #ffffff;   --acc-hover: #5d450f;
  --acc-soft: #f6ebcf; --acc-line: #dcc389;
  --inv-bg: #14120d;  --inv-fg: #f4f1e9;   --inv-mut: #969084;
  --inv-line: #262319; --inv-acc: #dcb264;
}

/* Estados de las maquetas: los mismos en todos los temas, porque son
   etiquetas de color fijo dentro de una interfaz de ejemplo. */
:root {
  --ok-bg: #14553a;   --ok-fg: #e9fff5;
  --wait-bg: #6b4a06; --wait-fg: #ffeec4;
}

/* Respaldo: si faltan los atributos o traen un valor desconocido, no se queda
   sin color. Copia de oro en oscuro. */
:root {
  --bg: #070706;      --bg-alt: #181713;   --surface: #14130f;
  --fg: #f1eee5;      --fg-2: #cbc6b8;     --mut: #969084;
  --line: #22201a;    --line-2: #322f26;    --line-3: #4a4433;
  --acc: #dcb264;     --acc-fg: #100f0c;   --acc-hover: #eecb8c;
  --acc-soft: #1d1810; --acc-line: #3d331d;
  --inv-bg: #f1eee5;  --inv-fg: #100f0c;   --inv-mut: #55524a;
  --inv-line: #d9d4c7; --inv-acc: #7a5b16;
}

/* =========================================================================
   Cambio de tema: la ola circular

   Se apoya en la View Transitions API. El navegador toma una foto del antes y
   del después; aquí solo se anulan las animaciones que trae por defecto (un
   fundido cruzado) y se ordenan las dos capas, para que la vieja se quede
   quieta debajo mientras la nueva la va tapando.

   El crecimiento del círculo se anima desde site.js con la API de animaciones,
   porque el centro tiene que ser el del botón y ese valor solo se conoce al
   pulsarlo. Con @keyframes y propiedades personalizadas el centro no llegaba
   de forma fiable al árbol de la transición y la ola salía del medio de la
   pantalla.

   Donde la API no existe, o con prefers-reduced-motion, el tema cambia igual
   y sin ola.
   ========================================================================= */

/* ======================================================= ola de cambio de tema

   La ola descubre la página real ya con los colores nuevos: se anima el
   clip-path de la capa nueva de la transición, no una pantalla de color
   puesta por encima.

   Sin aislamiento en el par de capas y con las dos como bloque: sin esto la
   capa nueva puede no quedar disponible para animar en la primera transición,
   que es justo cuando la ola salía incompleta. */

/* Estas reglas son SOLO para la ola del tema, de ahi el [data-ola]: lo pone el
   propio codigo mientras dura su transicion. Sin acotarlo se aplicarian tambien
   al cambio de idioma y le anularian el fundido, que es lo unico que hace. */

html[data-ola]::view-transition-image-pair(root) { isolation: auto; }

html[data-ola]::view-transition-old(root),
html[data-ola]::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
  display: block;
}
html[data-ola]::view-transition-old(root) { z-index: 1; }
html[data-ola]::view-transition-new(root) { z-index: 2; }

/* ==================================================== cambio de idioma (ES/EN)

   Los dos idiomas son dos documentos distintos, asi que pasar de uno a otro es
   una navegacion de verdad. Con esto el navegador la anima el solo: se queda
   con una foto de la pagina que se va y otra de la que llega y funde una en
   otra, en vez del parpadeo en blanco de una recarga. No hace falta ni tocar el
   HTML ni cargar nada: las dos paginas comparten esta hoja, y las dos tienen
   que declararlo para que funcione.

   Donde no este soportado (Firefox hoy), el enlace navega como siempre. */

@view-transition { navigation: auto; }

html:not([data-ola])::view-transition-old(root) {
  animation: alcavo-idioma-sale 260ms cubic-bezier(0.4, 0, 1, 1) both;
}
html:not([data-ola])::view-transition-new(root) {
  animation: alcavo-idioma-entra 380ms cubic-bezier(0, 0, 0.2, 1) 90ms both;
}

/* La que se va sube un pelo y la que llega sube desde un pelo mas abajo: el
   texto parece relevarse en su sitio en vez de aparecer de golpe. */
@keyframes alcavo-idioma-sale {
  to { opacity: 0; transform: translateY(-8px); }
}
@keyframes alcavo-idioma-entra {
  from { opacity: 0; transform: translateY(10px); }
}

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* ============================== copia viva del dibujo del hero durante la ola

   La transicion congela la pagina: anima entre dos fotos fijas. El top layer
   es la unica capa que se pinta por encima de ellas, y a el se llega con
   popover, asi que ahi se monta una copia del lienzo que si sigue dibujando.
   El lienzo real se esconde antes de las fotos para que no se vea doble.

   Los estilos de agente de usuario de un popover son position: fixed con
   width y height en fit-content: sin forzar el tamano, la capa sale de cero. */

.eco-hero {
  position: fixed;
  top: 0; left: 0;
  width: 100vw; height: 100vh;
  max-width: none; max-height: none;
  margin: 0; padding: 0; border: 0;
  background: transparent;
  overflow: hidden;
  pointer-events: none;
}
.eco-hero::backdrop { background: transparent; }

/* ============================================== panel de comparacion (interno)
   Solo aparece con ?paletas en la URL. No forma parte del sitio publico.

   Con casi treinta familias de color y una veintena de sistemas tipograficos
   la lista entera ya no cabe en pantalla. El panel se queda de alto acotado y
   son las dos listas las que ruedan por dentro, cada una por su lado: los dos
   grupos siguen visibles a la vez y el titulo de cada uno no se pierde al
   bajar. El panel en si nunca desborda, de ahi el overflow: hidden. */

.pal-panel {
  position: fixed; right: 16px; bottom: 16px; z-index: 900;
  display: flex; flex-direction: column;
  background: var(--inv-bg); color: var(--inv-fg);
  border: 1px solid var(--inv-line);
  padding: 12px; width: 234px;
  font-family: var(--f-mono); font-size: 11px;
  /* Alto de verdad, no solo un tope: con max-height las listas se quedaban
     en su min-height y el panel salia de un palmo aunque hubiera sitio. */
  height: 74vh; max-height: calc(100vh - 32px); overflow: hidden;
}
/* Asa de arriba: se arrastra para estirar o encoger el panel. Sale de los 12px
   de padding con margenes negativos, para que la franja sensible llegue a los
   bordes y no quede una tira muerta a los lados. touch-action: none porque si
   no, en tactil el arrastre lo interpreta el navegador como desplazamiento. */
.pal-panel .asa {
  flex: 0 0 auto;
  height: 15px; margin: -8px -12px 5px;
  display: flex; align-items: center; justify-content: center;
  cursor: ns-resize; touch-action: none;
}
.pal-panel .asa::before {
  content: ''; width: 36px; height: 2px; background: var(--inv-line);
}
.pal-panel .asa:hover::before { background: var(--inv-mut); }
.pal-panel .asa-medio { height: 17px; margin: 8px -12px 0; }

.pal-panel h6 {
  flex: 0 0 auto;
  margin: 0 0 8px; font-family: var(--f-mono); font-size: 9px;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--inv-mut); font-weight: 500;
}

/* flex: 1 1 0 con min-height es lo que reparte el alto sobrante entre las dos
   listas. Sin bajarle el minimo, una caja flexible no se deja encoger por
   debajo de su contenido y el scroll no llegaria a activarse nunca.

   position: relative para que sea ella el offsetParent de sus botones: site.js
   usa offsetTop para dejar a la vista el que esta puesto, y sin esto el
   offsetParent seria el panel y la cuenta saldria corrida. */
.pal-panel .lista {
  position: relative;
  flex: 1 1 0; min-height: 62px;
  overflow-y: auto; overscroll-behavior: contain;
  padding-right: 4px; margin-right: -4px;
  scrollbar-width: thin;
  scrollbar-color: var(--inv-line) transparent;
}
/* La de una sola opcion se queda del alto de su boton: no compite por el
   espacio ni deja un hueco vacio debajo. */
.pal-panel .lista.corta { flex: 0 0 auto; min-height: 0; overflow: visible; }

.pal-panel .lista::-webkit-scrollbar { width: 6px; }
.pal-panel .lista::-webkit-scrollbar-track { background: transparent; }
.pal-panel .lista::-webkit-scrollbar-thumb { background: var(--inv-line); }
.pal-panel .lista:hover::-webkit-scrollbar-thumb { background: var(--inv-mut); }

.pal-panel button {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: none; border: 1px solid transparent; color: inherit;
  padding: 6px 7px; margin-bottom: 2px; cursor: pointer; text-align: left;
  font-family: inherit; font-size: 11px; letter-spacing: 0.04em;
}
.pal-panel button:hover { border-color: var(--inv-line); }
.pal-panel button[aria-pressed="true"] { border-color: currentColor; }
.pal-panel .lista + h6 { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--inv-line); }
/* Cuando hay divisor, la raya la pone el propio divisor. */
.pal-panel .asa-medio + h6 { margin-top: 7px; padding-top: 0; border-top: 0; }
.pal-panel .sw { display: flex; flex: 0 0 auto; }
.pal-panel .sw i { width: 9px; height: 15px; display: block; }
.pal-panel small {
  flex: 0 0 auto;
  display: block; margin-top: 10px; padding-top: 9px;
  border-top: 1px solid var(--inv-line);
  color: var(--inv-mut); font-size: 9px; line-height: 1.5;
}
