Something went wrong. Try again.
A decentralized music tracking and discovery platform built on AT Protocol 🎵 rocksky.app
spotify atproto lastfm musicbrainz scrobbling listenbrainz
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671@import "tailwindcss";/* Older Chromecast engines ignore Tailwind v4's cascade layers. Keep the receiver's essential layout utilities outside layers so clock labels don't run together and the footer/queue retain their alignment on those TVs. */.flex { display: flex;}.items-center { align-items: center;}.justify-between { justify-content: space-between;}@font-face { font-family: RockfordSansLight; src: url("/fonts/RockfordSans-Light.otf") format("opentype"); font-display: swap;}@font-face { font-family: Rockford; src: url("/fonts/RockfordSans-Regular.otf") format("opentype"); font-weight: 400; font-display: swap;}@font-face { font-family: Rockford; src: url("/fonts/RockfordSans-Medium.otf") format("opentype"); font-weight: 500; font-display: swap;}@font-face { font-family: Rockford; src: url("/fonts/RockfordSans-Bold.otf") format("opentype"); font-weight: 700; font-display: swap;}:root { font-family: Rockford, system-ui, sans-serif; color: #f0e8f5; background: #130825; font-synthesis: none; -webkit-font-smoothing: antialiased;}* { box-sizing: border-box;}body { margin: 0;}button { font: inherit;}button:focus-visible,[role="slider"]:focus-visible { outline: 3px solid #ff84b0; outline-offset: 8px;}#receiver-audio { position: fixed; width: 1px; height: 1px; opacity: 0; pointer-events: none;}button:disabled { cursor: default;}.tv-shell { /* Storybook sets its own body font; keep receiver typography self-contained. */ font-family: Rockford, system-ui, sans-serif; position: relative; isolation: isolate; min-height: 100svh; height: 100vh; overflow: hidden; padding: 4.7vh 3vw 3.3vh; background: #10091d; display: flex; flex-direction: column;}.ambient { position: absolute; inset: 0; z-index: -2; background: linear-gradient(#130825eb, #130825eb), radial-gradient(ellipse at 16% 44%, #6f39a5 0%, transparent 52%), radial-gradient(ellipse at 91% 3%, #653453 0%, transparent 55%), linear-gradient(130deg, #271235, #130825 56%, #0e0918); background-size: cover; background-position: center; background-repeat: no-repeat; contain: strict; pointer-events: none;}.tv-header { flex-shrink: 0;}.brand { /* Match the web navbar and landing-page wordmark exactly. */ font-family: RockfordSansLight, sans-serif; font-size: 26px; font-weight: 700; font-synthesis: weight; line-height: 1.5; letter-spacing: normal; color: oklch(95.07% 0.028 338.58);}.cast-badge { gap: 0.7vw; color: #c9b9cf; letter-spacing: 0.22em; font-size: 0.7vw;}.cast-badge svg { width: 1.15vw; height: 1.15vw;}.listening-layout { display: grid; grid-template-columns: minmax(0, 50vh) minmax(0, 1fr); gap: 2.5vw; align-items: center; flex: 1; min-height: 0; padding: 6.5vh 0 4vh;}.artwork { overflow: hidden; flex-shrink: 0; background: #2c1c3e; border-radius: 0; aspect-ratio: 1;}.artwork img { width: 100%; height: 100%; object-fit: cover;}.hero-art { width: 100%; max-width: 50vh; justify-self: end; box-shadow: 0 0 0 1px #ffffff10;}.artwork-fallback { height: 100%; display: grid; place-items: center; background: radial-gradient(circle at 30% 20%, #af526e, #572668 55%, #291140);}.artwork-fallback svg { width: 36%; height: 36%; opacity: 0.65;}.track-details { min-width: 0; padding-right: 0;}.eyebrow { color: #efb4c6; letter-spacing: 0.23em; font-size: 0.78vw; font-weight: 500; gap: 0.7vw; margin: 0 0 2.25vh;}.equalizer { height: 1vw; display: flex; align-items: flex-end; gap: 0.16vw;}.equalizer i { background: #ff568f; display: block; width: 0.16vw; height: 70%; border-radius: 2px;}.equalizer i:nth-child(2) { height: 100%;}.equalizer i:nth-child(3) { height: 55%;}.equalizer.animated i { animation: equalize 1s steps(3) infinite alternate;}.equalizer.animated i:nth-child(2) { animation-delay: -0.4s;}.equalizer.animated i:nth-child(3) { animation-delay: -0.65s;}.equalizer.animated i:nth-child(4) { animation-delay: -0.2s;}.track-title,.track-artist,.track-album { width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;}.track-title { font-weight: 700; font-size: clamp(30px, 4.5vw, 96px); letter-spacing: -0.05em; line-height: 1.07; margin: 0 0 2.4vh; overflow: hidden;}.track-artist { font-size: 1.65vw; color: #eee4ee; margin: 0 0 0.8vh; line-height: 1.3; overflow: hidden;}.track-album { font-size: 1.08vw; line-height: 1.4; color: #b4a3b8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin: 0;}.playback-timeline { margin-top: 4.5vh; width: 100%;}.timeline-bar { height: 4px; border-radius: 4px; background: #ffffff20; position: relative; cursor: pointer;}.timeline-bar:before { content: ""; position: absolute; inset: -12px 0;}.timeline-fill { height: 100%; border-radius: inherit; background: #ff528b; position: relative; width: 100%; transform-origin: left center; will-change: transform;}.time-labels { display: flex; justify-content: space-between; width: 100%; line-height: 1.5; color: #c6b6ca; font-size: 0.85vw; letter-spacing: 0.04em; margin-top: 1.2vh; font-variant-numeric: tabular-nums;}.time-labels > span { flex: 0 0 auto; white-space: nowrap;}.playback-caption { margin-top: 2.3vh;}.playback-caption > .source-caption { margin-left: 1.6vw;}.play-toggle { border: 1px solid #ffffff30; background: #ffffff0b; color: #f6ecf7; border-radius: 50%; width: 2.65vw; height: 2.65vw; display: grid; place-items: center; cursor: pointer;}.play-toggle svg { width: 1.2vw; height: 1.2vw;}.source-caption { display: flex; align-items: center; gap: 0.5vw; font-size: 0.78vw; color: #baabc3;}.source-caption svg { width: 1vw; height: 1vw;}
.error-message { color: #ffb6c7; font-size: 1vw; line-height: 1.4; max-width: 32vw;}.queue-section { flex-shrink: 0; padding: 2.35vh 0 2.6vh; border-top: 1px solid #ffffff12;}.queue-heading { font-size: 0.72vw; letter-spacing: 0.2em; color: #d9ccdf; margin-bottom: 2.1vh;}.queue-heading > span:last-child { font-size: 0.7vw; letter-spacing: 0.03em; color: #a491af;}.queue-rail { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2.2vw; min-height: 5.7vh;}.queue-track { display: flex; flex-direction: row; align-items: center; min-width: 0; gap: 1vw; padding: 1vh 0;}.queue-rank { font-size: 0.75vw; color: #a48cab; letter-spacing: 0.06em; font-variant-numeric: tabular-nums;}.queue-track > .artwork { /* Title line (0.94 × 1.3), line gap, artist line (0.75 × 1.5). */ width: calc(1.222vw + 0.25vw + 1.125vw); height: calc(1.222vw + 0.25vw + 1.125vw);}.queue-copy { min-width: 0; flex: 1;}.queue-copy h2 { font-size: 0.94vw; line-height: 1.3; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin: 0 0 0.25vw;}.queue-copy p { font-size: 0.75vw; line-height: 1.5; color: #a999b0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin: 0;}.queue-duration { font-size: 0.72vw; color: #a999b0; font-variant-numeric: tabular-nums;}.queue-empty { color: #af9abb; font-size: 0.9vw; grid-column: 1/-1; margin: 0.9vh 0;}.tv-footer { font-size: 0.72vw; color: #85738e; letter-spacing: 0.02em; padding-top: 1vh; flex-shrink: 0;}.footer-device { gap: 0.45vw;}.footer-device svg { width: 0.9vw; height: 0.9vw;}.idle-scene { display: flex; flex: 1; flex-direction: column; justify-content: center; align-items: center; text-align: center; min-height: 0;}.idle-orbit { position: relative; width: 24vh; height: 24vh; margin-bottom: 4vh; border: 1px solid #ffffff0e; border-radius: 50%; display: grid; place-items: center;}.idle-record { width: 19vh; height: 19vh; border-radius: 50%; box-shadow: 0 3vh 6vh #0006; background: repeating-radial-gradient( circle at center, #251a2c 0 2px, #39273d 3px 4px ); display: grid; place-items: center;}.idle-record-label { width: 8vh; height: 8vh; border-radius: 50%; display: grid; place-items: center; background: linear-gradient(145deg, #ffa6a6, #da4985, #7545ab);}.idle-record-label svg { width: 3vh; height: 3vh;}.orbit-star { position: absolute; right: -0.7vh; top: 2vh; color: #ff92bc; font-size: 3vh;}.idle-scene .eyebrow { font-size: 0.73vw; margin-bottom: 1.9vh;}.idle-scene h1 { font-size: 4.2vw; font-weight: 700; letter-spacing: -0.045em; margin: 0 0 2vh; line-height: 1.1;}.idle-description { font-size: 1.15vw; color: #b5a2c1; max-width: 38vw; margin: 0; line-height: 1.5;}.idle-instruction { gap: 0.8vw; font-size: 0.8vw; color: #d1bedb; margin-top: 4vh; padding: 1.8vh 1.6vw; border-radius: 4vw; border: 1px solid #ffffff12; background: #ffffff04;}.idle-instruction svg { width: 1.15vw; height: 1.15vw;}.idle-instruction svg:nth-of-type(2) { color: #776182; width: 0.75vw; margin: 0 0.2vw;}@keyframes equalize { from { transform: scaleY(0.35); } to { transform: scaleY(1); }}@media (prefers-reduced-motion: reduce) { *, *:before, *:after { animation: none !important; transition: none !important; }}@media (max-aspect-ratio: 4/3) { .tv-shell { height: auto; min-height: 100svh; overflow: auto; } .listening-layout { grid-template-columns: 1fr; gap: 4vh; padding: 6.5vh 0 5vh; } .hero-art { max-width: 42vh; justify-self: center; } .track-details { width: 100%; text-align: center; } .eyebrow, .playback-caption { justify-content: center; } .track-title { font-size: 6vw; } .track-artist { font-size: 3vw; } .track-album { font-size: 2.2vw; } .playback-timeline { max-width: none; width: 100%; margin: 4vh auto 0; } .time-labels, .source-caption { font-size: 1.7vw; } .play-toggle { width: 5vw; height: 5vw; } .play-toggle svg { width: 2vw; height: 2vw; } .queue-rail { grid-template-columns: 1fr; gap: 2vh; } .queue-track > .artwork { width: calc(2.6vw + 0.25vw + 2.25vw); height: calc(2.6vw + 0.25vw + 2.25vw); } .queue-copy h2 { font-size: 2vw; } .queue-copy p, .queue-duration { font-size: 1.5vw; } .queue-heading, .tv-footer, .cast-badge { font-size: 1.3vw; } .idle-scene { min-height: 80vh; } .idle-description { font-size: 2vw; max-width: 65vw; }}
.artwork-fallback { position: relative; isolation: isolate; overflow: hidden; background: linear-gradient(145deg, #281544 0%, #854477 45%, #e69c92 100%);}.fallback-glow { position: absolute; width: 130%; height: 100%; background: radial-gradient(ellipse, #ffce9a80, transparent 65%); left: 10%; top: -35%;}.fallback-orbit { position: absolute; inset: 11%; border: 1px solid #ffd3e038; border-radius: 50%; transform: translate(18%, -13%) rotate(-25deg); box-shadow: 0 0 0 1.4vw #ffffff05, 0 0 0 2.8vw #ffffff04;}.fallback-vinyl { position: absolute; width: 64%; height: 64%; top: 14%; left: 18%; border-radius: 50%; background: repeating-radial-gradient(circle, #2a173c 0 2px, #3c264e 3px 4px); box-shadow: 0 1.2vw 2.8vw #190c3b60; display: grid; place-items: center; transform: rotate(-20deg);}.fallback-vinyl > span { display: grid; place-items: center; width: 34%; height: 34%; border-radius: 50%; background: linear-gradient(140deg, #ffbea3, #d95f9a 55%, #8864cc); box-shadow: 0 0 0 2px #0d051d80;}.fallback-vinyl svg { width: 42%; height: 42%; color: #fff4f0; opacity: 0.9;}.fallback-brand { position: absolute; left: 9%; bottom: 12%; font-weight: 700; letter-spacing: 0.32em; font-size: 1.1vw; color: #fff1e9;}.fallback-caption { position: absolute; left: 9%; bottom: 7%; font-size: 0.55vw; letter-spacing: 0.04em; color: #ffe7e1b0;}.queue-track .fallback-brand,.queue-track .fallback-caption { display: none;}.queue-track .fallback-orbit { box-shadow: none;}.queue-track .fallback-vinyl { box-shadow: 0 2px 5px #190c3b60;}
.queue-position { margin-left: auto; font-size: clamp(18px, 1.4vw, 36px); font-weight: 600; line-height: 1.3; color: #c9b9cf; letter-spacing: normal; white-space: nowrap; font-variant-numeric: tabular-nums;}