Commit Graph
2 Commits
Author SHA1 Message Date
Esa Kataja f33f4fa4d6 Apply the theme: tokens, Oswald, song cards, toasts
The theme handoff encoded as CSS custom properties rather than a Tailwind
config, since there is no Tailwind here. Palette, spacing, radii, shadows and
motion follow it as written; docs/theme.md lists what differs and why.

- Oswald vendored as a 21KB variable woff2, latin subset, no CDN. Its phantom
  weight 900 resolved to 700 — loading a weight you don't have is what made
  the brand render differently per platform
- color-scheme: dark makes the native audio element fit the palette, which
  was the handoff's complaint about it
- Songs are text cards rather than artwork tiles, because there is no
  artwork. The unreviewed state keeps its red-brown border and gains a badge,
  so it is never carried by colour alone
- Nav is the three-column grid; the mobile menu is <details>, no JS
- Flash messages became bottom-right toasts

Favicon carried over from the Nuxt project.
2026-07-31 22:16:29 +03:00
Esa Kataja 80d3e36679 Add the submission pipeline and the review loop
Steps 3 and 4 of the build order. A member can now upload a song, watch it
convert, publish it, and review what everyone else has published.

Pipeline:
- ffprobe reads tags synchronously at submit so prefill never races typing;
  ffmpeg converts to Opus in the background, two at a time
- ffmpeg succeeding is the validation — no container sniffing
- publish moves the file inside the transaction, so a song row and its .ogg
  appear together or neither does
- five submissions per rolling 24h, failures excluded

Reviews and the reveal rule:
- the queue is unreviewed songs only, oldest first, never your own
- other people's reviews and the average are withheld in the query, not the
  template — a hidden average is never sent
- 30 minutes to edit or delete your own review, enforced in the WHERE clause
- deleting the last review unlocks the song for its submitter again

The waiting page has one button: the metadata form autosaves after a pause in
typing, and Julkaise submits it and publishes in the same request, so nothing
is lost without JS.

Genres store an English code and render a Finnish label.
2026-07-31 21:42:49 +03:00