Había dos listados: una tabla ordenable para el catálogo y una lista
aparte para los discos. Cada arreglo había que hacerlo dos veces y el
resultado era que la portada estaba en una y el año en la otra. Ahora es
un solo componente, y lo que cambia son las columnas de contexto, que se
encienden por props: dentro de un disco, la columna «Álbum» diría diez
veces lo mismo.
Solo recibe canciones. El estilo, el disco y la portada los resuelve
contra el catálogo que ya baja en `page.data`, así que quien la usa no
tiene que armar filas a mano, que era lo que obligaba a repetir código.
Cada fila lleva su portada —con la ampliada al pasar el ratón—, y debajo
del título van los géneros y las etiquetas en vez del primer verso: la
letra está entera en la ficha, y aquí lo que sirve para elegir es de qué
está hecho el tema. Las etiquetas se cortan por número, con un «+2» al
final: recortarlas con un degradado dejaba «Autoengaño» en «Autoeng», que
no parece una elección sino algo roto.
La cola ya se puede llenar. Hasta ahora solo se podía sustituir —cada
play la vaciaba y la llenaba con su contexto—, así que no había forma de
armar una escucha cogiendo temas de discos distintos. `encolar()` es la
otra mitad, y con la cola vacía arranca, porque un botón que no hace nada
es peor que no tenerlo.
Los géneros de una canción entran en el modelo: `cancion_genero` existía
en la base y no llegaba a la web. Son cosa distinta del estilo —el estilo
es cómo se ordena la obra aquí y es uno solo; los géneros son de qué está
hecha la canción y pueden ser varios— y llevan al glosario.
De paso: las letras largas van a dos columnas de 37ch, que es el mínimo
que deja caber dos y a la vez el verso más largo del catálogo —importa
afinarlo, porque en una letra dónde acaba cada verso es parte del texto—;
la página baja de 2808 a 2023 píxeles. Contacto sale de la barra de menú
y se queda solo en el pie. Y el titular pasa a «Letrista y creador
musical».
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Detrás de la cuenta hay compras y facturación, y un código por correo apoya
toda esa puerta en el buzón: quien entre ahí, entra aquí. Delegar la
identidad en un proveedor que ya tiene doble factor la sostiene mejor.
Es el flujo de código de autorización con PKCE, escrito a mano porque son
cien líneas y las partes que importan son tres, mejor a la vista que
detrás de una dependencia: comparar el `state`, mandar el `code_verifier`
y exigir que el correo venga verificado antes de enlazar nada.
Lo que NO hace, a propósito: verificar la firma del `id_token`. La
identidad no se saca de lo que trae el navegador, sino de una llamada
nuestra al proveedor por TLS, así que no hay firma ajena que comprobar.
Y no guarda ningún token: se usa una vez para preguntar quién es y se
tira.
El enlazado por correo verificado es lo delicado, y por eso está separado
en `usuarioParaPerfil` con su explicación: sin exigir la verificación,
cualquiera podría poner la dirección de otro en un perfil suyo y quedarse
con su cuenta y sus compras.
El código por correo se queda debajo, como alternativa. Sin credenciales
puestas, los botones no se pintan y la ruta contesta 503: un botón que
solo lleva a un error es peor que no tenerlo.
Y los textos legales al día, que ahora sí hay terceros: qué se manda a
Google y a Facebook, cuándo, qué se guarda y cómo revocarlo.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
El acceso deja de ser un salto de página: «Entrar» abre un diálogo con la
imagen de marca a la izquierda y el formulario a la derecha, y al entrar
se vuelve a donde se estaba en vez de aterrizar en /cuenta. `/entrar`
sigue existiendo con el mismo formulario y la misma estampa, para quien
llegue por un enlace directo o sin JavaScript.
Tres cosas que salieron de probarlo, no de suponerlo:
- `showModal()` enfocaba el campo trampa contra envíos automáticos: está
fuera de pantalla y fuera del recorrido de tabulación, pero se puede
enfocar. Ahora el campo se enfoca a mano.
- Una regla de `display` en el diálogo le gana a la del navegador, que es
hoja de usuario. El diálogo cerrado se pintaba igual: una pantalla de
vacío al final de todas las páginas del sitio.
- Los enlaces legales navegaban por debajo del modal. Van en pestaña
aparte: se consultan y se vuelve con lo escrito intacto.
Y aparte, el carrusel de la portada. Cada lámina lleva su fondo con
`z-index: -1`, pero con `opacity: 1` la lámina no crea contexto de
apilamiento, así que ese fondo se escapaba y se pintaba detrás del
carrusel entero. Al pasar de lámina asomaba la foto de la de al lado y el
fondo de la que entraba saltaba hacia atrás al terminar el fundido.
Parecía que el shader se desincronizaba; lo que se movía era el orden de
pintado.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
El pack pasa de cinco a diez canciones por el mismo 1,50 €: diez canciones por
lo que cuesta un café. Es la propuesta, así que el número y el importe se leen
juntos en todas partes.
Las pruebas de la tienda estaban escritas con el cinco metido a mano y hubo que
reescribirlas enteras. Ahora dicen la regla en términos del propio tamaño del
pack, y el helper de las pruebas de extremo a extremo añade lo que haya a la
venta hasta llenarlo en vez de nombrar los temas uno a uno: así cambiar el
tamaño otra vez no obliga a tocar nada.
Las dos láminas de llamada estrenan foto propia con su velo, más cubriente que
el de la textura: sobre una imagen clara el texto blanco no se lee.
Y el dorado deja de ser plano en los botones. Un metal refleja, y lo que lo hace
parecer metal es la banda de luz que lo cruza; el fondo se pinta más alto que el
botón para que al acercar el puntero la luz recorra la pieza en vez de
limitarse a aclararla. El acento sube un punto de croma y baja uno de claridad,
que es lo que lo separa de un amarillo de rotulador.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Tres piezas estaban copiadas en varios sitios y ahora se escriben una vez: el
fondo a sangre de la portada, las migas de pan y la pastilla de una etiqueta.
El fondo ya había divergido entre la cabecera y las láminas de llamada: el
degradado era distinto por descuido y no por decisión, que es lo que pasa con el
marcado duplicado.
Las migas pasan a ser una lista ordenada, que es su marcado correcto: un lector
de pantalla anuncia cuántos escalones hay y en cuál se va, y el último deja de
ser un enlace a donde ya estás.
Tres cosas salieron de hacerlo, ninguna cosmética:
- Con el texto como clave del bucle, un disco y un tema que se llaman igual
—«Como si nada» es las dos cosas— daban claves duplicadas y tumbaban la ficha
al hidratar. El SSR salía bien, así que solo se veía en el navegador.
- Al compartir el fondo, las tres láminas montaban el clip de vídeo. En tema
claro eso eran tres copias del mismo vídeo en la portada. Ahora lo pide solo
la cabecera.
- La lista de temas de un disco no tenía nombre, así que no se distinguía de
ninguna otra lista de la página. Ahora se llama «Temas».
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sitio del letrista y compositor, con SvelteKit 2 y Svelte 5.
El catálogo es contenido, no base de datos: estilos, álbumes, canciones y
capítulos son Markdown en `src/content/`, validados al compilar y compilados
dentro del bundle, así que recorrer la música no hace ni una consulta. La base
de datos guarda solo lo que generan las personas: cuentas, carritos, pedidos,
compras, valoraciones y favoritos.
Lo que hay:
- Música agrupada por estilos, con página propia para cada estilo, álbum y
tema, buscador y tabla ordenable.
- Reproductor persistente que sobrevive a la navegación. Suena un fragmento;
el archivo completo solo se obtiene comprando.
- Taller de letras: los principios del oficio y una ficha de creación por
estilo hispanoamericano.
- Blog con feed RSS, y etiquetas que cruzan blog y catálogo.
- Tienda con cuentas por código de correo, carrito, Stripe y descargas
protegidas.
- Panel de contenido en `/admin` que escribe los mismos Markdown.
- Tema oscuro de marca y su inversión clara, aplicado antes de pintar.
Lo que falta y no es código: las claves de Stripe y de correo, el tratamiento
del IVA, las páginas de condiciones y privacidad, y el material real. Las
canciones de ejemplo son inventadas y están para sustituirse; el audio son
marcadores salvo un tema.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>