/* ============================================================================ TOKENS — el único archivo de diseño ---------------------------------------------------------------------------- Aquí vive TODO lo que se puede ver: colores, tamaños, tipografía, tiempos, curvas, sombras y los parámetros del cielo. Ningún otro archivo (ni CSS ni JS) puede escribir un color, un tamaño o una duración literal. Hay dos capas, y el orden importa: 1. PRIMITIVOS — la paleta cruda. Nombres de cosas: "noche", "teal". No dicen para qué sirven. Solo se usan dentro de este archivo. 2. SEMÁNTICOS — nombres de función: "superficie-carta", "texto-tenue". Es lo ÚNICO que pueden usar los componentes. Por qué dos capas: si un componente usa --c-noche directamente, el día que quieras cambiar el estilo entero tendrías que ir componente por componente. Con la indirección, cambias a qué apunta cada semántico aquí y el resto del proyecto se entera solo. Para cambiar el estilo completo: reescribe el bloque SEMÁNTICOS. Para retocar un color: cambia su primitivo. AURORA GLASS — la piel actual. Noche profunda, vidrio esmerilado, y tres acentos de aurora (teal, violeta, rosa) que reaparecen en el cielo (js/aurora.js) y en el acento de la acción principal. Ya no hay carta de hueso: todo lo que antes vivía sobre claro ahora vive sobre vidrio, con tinta clara encima. ========================================================================== */ :root { /* ── 1. PRIMITIVOS ──────────────────────────────────────────────────── */ /* Noche: el cielo, de arriba abajo */ --c-noche: #070b1f; --c-noche-2: #0d1336; --c-noche-rgb: 7 11 31; --c-noche-2-rgb: 13 19 54; /* Los tres acentos de la aurora */ --c-teal: #2de2c4; --c-teal-claro: #9cf3e3; --c-teal-rgb: 45 226 196; --c-violeta: #7b5cff; --c-violeta-rgb: 123 92 255; --c-rosa: #ff6fa8; --c-rosa-rgb: 255 111 168; /* Tinta: el texto, sobre vidrio o sobre noche, siempre claro */ --c-tinta: #eef0ff; --c-tinta-rgb: 238 240 255; /* El texto oscuro que va DENTRO del botón teal (necesita contraste sobre un acento claro, no sobre vidrio). */ --c-tinta-profunda: #061018; --c-blanco: #fff; --c-sombra: 0 0 0; --c-estrella: 255 255 255; /* Espacio */ --e-0: 0px; --e-1: 4px; --e-2: 7px; --e-3: 9px; --e-4: 12px; --e-5: 14px; --e-6: 16px; --e-7: 24px; --e-8: 30px; --e-9: 34px; --e-10: 40px; --e-11: 56px; /* Tipografía */ --f-familia: "SF Pro Display", "Helvetica Neue", "Segoe UI Variable Display", "Segoe UI", "Avenir Next", "Nimbus Sans", "Liberation Sans", Arial, sans-serif; --f-peso-titulo: 200; --f-peso-claro: 300; --f-peso-normal: 400; --f-peso-medio: 500; --f-xs: 10.5px; --f-s: 12.5px; --f-sm: 13.5px; --f-m: 15px; --f-md: 15.5px; --f-l: 17px; --f-xl: 46px; --f-alto-apretado: 1.22; --f-alto-normal: 1.6; --f-espaciado-titulo: -0.035em; --f-espaciado-ancho: 0.04em; /* Radios */ --r-s: 4px; --r-m: 8px; --r-l: 16px; --r-xl: 30px; --r-pastilla: 27px; --r-circulo: 50%; /* Cortes responsivos. Ojo: CSS no admite var() dentro de @media, así que en los componentes el número va escrito. Se declaran aquí igualmente porque son una decisión de diseño, y tests/tokens.test.js comprueba que ningún @media use un corte que no esté en esta lista. */ --corte-estrecho: 900px; --corte-movil: 640px; /* Medidas de pieza */ --m-carta-ancho: 1104px; --m-carta-alto: 716px; --m-panel-ancho: 220px; --m-simbolo: 70px; --m-simbolo-estrecho: 58px; --m-simbolo-movil: 52px; --m-escenario-estrecho: 45dvh; /* En móvil el lienzo es la puerta de entrada. Tiene un alto fijo para que no salte al elegir una foto, pero ya no queda subordinado al formulario. */ --m-escenario-movil: 45dvh; --m-margen-ventana-movil: 26px; --m-miniatura-alto-movil: 54px; --m-simbolo-dibujo: 32px; --m-numero: 19px; --m-miniatura-ancho: 54px; --m-miniatura-alto: 62px; --m-accion-alto: 54px; --m-anillo: 360px; --m-difuminado-alto: 180px; /* cuánto abarca la banda de luz */ --m-trazo-simbolo: 1.35; --m-icono: 44px; --m-menu-imagen: 224px; --m-visor-maximo: 92dvh; --m-intencion-minima: 54px; --m-intencion-abierta: 132px; --m-modal-intencion: 520px; --m-modal-texto: 236px; --giro-imagen: 0deg; /* Tiempo */ --t-instante: 0.2s; --t-retardo-2: 0.15s; --t-retardo-3: 0.3s; --t-rapido: 0.22s; --t-medio: 0.45s; --t-entrada: 0.7s; --t-lento: 1.2s; --t-respiracion: 6s; --t-parpadeo: 7s; --t-aplicando: 2800ms; /* lo lee el JS: cuánto dura el aplicar */ /* Curvas */ --curva-suave: cubic-bezier(0.25, 0.46, 0.45, 0.94); --curva-calma: ease-in-out; /* Resorte: un rebote breve, para lo que responde a un toque. */ --curva-resorte: cubic-bezier(0.34, 1.56, 0.44, 1); /* Planeo: entra rápido y frena largo, para lo que se desliza. */ --curva-planeo: cubic-bezier(0.22, 0.8, 0.24, 1); /* Cielo (lo lee el JS al generar las estrellas) */ --cielo-lejanas: 462; --cielo-cercanas: 77; --cielo-semilla: 7; --cielo-alfa-lejana-min: 0.14; --cielo-alfa-lejana-max: 0.4; --cielo-alfa-cercana-min: 0.5; --cielo-alfa-cercana-max: 0.9; --cielo-estrella-lejana: 1px; --cielo-estrella-cercana: 2px; --cielo-horizonte-alto: 220px; /* El cielo gira como una bóveda: todo el campo rota despacio alrededor de un eje que queda por debajo de la pantalla, así que cada estrella describe un arco y las de cerca del eje se mueven menos que las de arriba. No es una traslación: nada se desplaza en línea recta. Para que se mueva más: sube el giro o baja el tiempo. */ --cielo-eje-x: 50vw; --cielo-eje-y: 140vh; --cielo-giro: 5deg; --cielo-deriva: 189s; --cielo-giro-cercanas: 11deg; --cielo-deriva-cercanas: 117s; /* Destellos: de tanto en tanto, una estrella al azar entre estas brilla de golpe y con fuerza. El JS elige cuál y cuándo (sin período fijo); acá solo el tamaño, el resplandor y cada cuánto puede tocarle a alguna. */ --cielo-destellos: 14; --cielo-estrella-destello: 2.5px; --cielo-destello-resplandor: 5px; --cielo-destello-duracion: 0.5s; --cielo-destello-espera-min: 0.12s; --cielo-destello-espera-max: 0.9s; /* Aurora (lo lee el JS: color de cada cinta y cuánto deforman la imagen durante la magia — ver js/aurora.js y js/distorsion.js). La forma de las cintas (frecuencias, fases, alto) no es un valor de diseño en el mismo sentido que un color o una duración: vive en el propio módulo. */ --aurora-cinta-1: var(--c-teal); --aurora-cinta-2: var(--c-violeta); --aurora-cinta-3: var(--c-rosa); /* Cuánto se difumina el velo de la magia sobre la imagen. */ --aurora-velo-difuminado: 40px; /* Cuánto se deforma la imagen en el pico de la magia, como fracción de su lado corto (0.06 = empuja hasta un 6 %). 0 la deja quieta. */ --aurora-distorsion: 0.06; /* El velo de la zona de la imagen, sin nada de magia encima. */ --velo-escenario-alfa: 0.28; /* ── 2. SEMÁNTICOS ──────────────────────────────────────────────────── */ /* Lo único que pueden usar los componentes. */ /* Fondos y superficies */ --fondo-umbral: linear-gradient( 180deg, var(--c-noche) 0%, var(--c-noche-2) 100% ); --fondo-velo-bajo: radial-gradient( 120% 80% at 50% 108%, rgb(var(--c-teal-rgb) / 0.12) 0%, rgb(var(--c-teal-rgb) / 0) 62% ); --fondo-velo-alto: radial-gradient( 90% 60% at 78% -10%, rgb(var(--c-violeta-rgb) / 0.22) 0%, rgb(var(--c-violeta-rgb) / 0) 60% ); /* El punto de rosa. Súbele o bájale el alfa para que se note más o menos. */ --fondo-velo-rosa: radial-gradient( 70% 50% at 22% 82%, rgb(var(--c-rosa-rgb) / 0.16) 0%, rgb(var(--c-rosa-rgb) / 0) 65% ); /* ── El vidrio: la receta que comparten la carta, los iconos de la imagen, los menús, los círculos de energía y el botón secundario. Cada componente la vuelve a escribir con estos mismos tokens (no hay mixins en CSS), pero el valor nace acá una sola vez. */ --vidrio-fondo: linear-gradient( 150deg, rgba(255, 255, 255, 0.095), rgba(255, 255, 255, 0.028) 48%, rgba(255, 255, 255, 0.055) ); --vidrio-desenfoque: blur(22px) saturate(165%); --vidrio-sombra: inset 0 1px 0 rgba(255, 255, 255, 0.2), inset 0 -1px 0 rgba(255, 255, 255, 0.035), 0 40px 90px -42px rgba(0, 0, 0, 0.7), 0 2px 8px rgba(0, 0, 0, 0.18); /* El borde de 1px: un degradado recortado con mask, no un `border` plano. */ --vidrio-borde-degradado: linear-gradient( 158deg, rgba(255, 255, 255, 0.52), rgba(255, 255, 255, 0.09) 26%, rgba(255, 255, 255, 0.02) 58%, rgba(255, 255, 255, 0.24) ); --vidrio-grano-tamano: 180px; --vidrio-grano-opacidad: 0.075; /* El ruido en sí lo pone js/cielo.js al arrancar (un lienzo 128×128 al azar, una sola vez): acá solo el valor por defecto, sin ruido. */ --grano: none; --superficie-carta: var(--vidrio-fondo); /* La zona de la imagen es translúcida y oscura: el cielo se ve también dentro de la carta. */ --superficie-escenario: rgb(var(--c-noche-rgb) / var(--velo-escenario-alfa)); --superficie-simbolo: var(--vidrio-fondo); /* Texto sobre la noche */ --texto-noche: var(--c-tinta); --texto-noche-tenue: rgb(var(--c-tinta-rgb) / 0.56); --texto-noche-apunte: rgb(var(--c-tinta-rgb) / 0.76); /* Texto sobre la carta: ya no es de vidrio claro sobre hueso, es tinta clara sobre vidrio oscuro. Misma escala de alfas que el texto de la noche, porque ahora es la misma superficie. */ --texto-principal: var(--c-tinta); --texto-tenue: rgb(var(--c-tinta-rgb) / 0.56); --texto-apagado: rgb(var(--c-tinta-rgb) / 0.56); --texto-secundario: rgb(var(--c-tinta-rgb) / 0.76); --texto-marcador: rgb(var(--c-tinta-rgb) / 0.32); /* Bordes */ --borde-carta: rgb(var(--c-tinta-rgb) / 0.14); --borde-panel: rgb(var(--c-tinta-rgb) / 0.12); --borde-sutil: rgb(var(--c-tinta-rgb) / 0.14); --borde-simbolo: rgb(var(--c-tinta-rgb) / 0.16); --borde-simbolo-hover: rgb(var(--c-tinta-rgb) / 0.32); --borde-marcado: rgb(var(--c-tinta-rgb) / 0.24); /* La zona de la imagen es translúcida y oscura: lo que va encima de ella se escribe en tinta clara. */ --borde-hueco: rgb(var(--c-tinta-rgb) / 0.32); --texto-escenario: rgb(var(--c-tinta-rgb) / 0.76); --texto-escenario-tenue: rgb(var(--c-tinta-rgb) / 0.56); --texto-escenario-fuerte: var(--c-tinta); --borde-hueco-fuerte: var(--c-tinta); --superficie-herramientas: var(--vidrio-fondo); --superficie-menu: var(--vidrio-fondo); --borde-menu: rgb(var(--c-tinta-rgb) / 0.14); --texto-herramientas: var(--c-tinta); --superficie-barra-imagen: var(--vidrio-fondo); --texto-barra-imagen: var(--c-tinta); --borde-barra-imagen: rgb(var(--c-tinta-rgb) / 0.14); --velo-visor: rgb(var(--c-sombra) / 0.82); --velo-modal: rgb(var(--c-sombra) / 0.5); /* Acción principal: la pastilla teal, con el anillo teal cuando resplandece */ --accion-fondo: linear-gradient(120deg, var(--c-teal), var(--c-teal-claro)); --accion-texto: var(--c-tinta-profunda); --accion-fondo-hover: linear-gradient(120deg, var(--c-teal-claro), var(--c-teal)); --accion-secundaria-borde: rgb(var(--c-tinta-rgb) / 0.24); --accion-umbral-fondo: var(--c-tinta); --accion-umbral-texto: var(--c-noche); --accion-umbral-hover: var(--c-blanco); /* Símbolos */ --simbolo-trazo: currentColor; --simbolo-color: rgb(var(--c-tinta-rgb) / 0.56); --simbolo-color-activo: var(--c-teal); /* El anillo y el resplandor de la energía elegida. */ --anillo-activo: 0 0 0 2px rgb(var(--c-teal-rgb) / 0.85), 0 0 16px rgb(var(--c-teal-rgb) / 0.55); /* Sombras */ --sombra-carta: 0 60px 120px -50px rgb(var(--c-sombra) / 0.85); --sombra-imagen: 0 30px 60px -40px rgb(var(--c-sombra) / 0.6); /* El momento de aplicar */ --aplicando-anillo: rgb(var(--c-estrella) / 0.32); /* La banda de luz que recorre la imagen de arriba abajo. Es una campana: la opacidad sube y baja siguiendo una gaussiana, muestreada en 21 paradas. Con tres paradas (transparente → luz → transparente) el degradado es recto y se le ven los bordes, porque la pendiente cambia de golpe; así no hay ningún borde que ver. Para subir o bajar la intensidad, toca --revelado-fuerza. */ --revelado-fuerza: 0.55; --revelado-difuminado: linear-gradient( 180deg, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.0132)) 0%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.0301)) 5%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.0628)) 10%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.1201)) 15%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.2107)) 20%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.3391)) 25%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.5006)) 30%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.6775)) 35%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.8411)) 40%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.9577)) 45%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 1.0000)) 50%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.9577)) 55%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.8411)) 60%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.6775)) 65%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.5006)) 70%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.3391)) 75%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.2107)) 80%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.1201)) 85%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.0628)) 90%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.0301)) 95%, rgb(var(--c-estrella) / calc(var(--revelado-fuerza) * 0.0132)) 100% ); --revelado-suavizado: 18px; /* desenfoque extra, remata los extremos */ --aplicando-cielo-intensidad: 1.55; /* Horizonte del cielo */ --cielo-horizonte: linear-gradient( 180deg, rgb(var(--c-noche-rgb) / 0) 0%, rgb(var(--c-noche-2-rgb) / 0.9) 100% ); }