/* B-SIDE. Pure black, system type, frosted-glass chrome in the manner of iOS. One object on screen at a time:
   a foil pack (drawn in WebGL, see pack.js), then the card it held. The only colour on the page is light from the card. */
:root {
  --bg: #000;
  --label: #fff;
  --label-2: rgba(235, 235, 245, .62);
  --label-3: rgba(235, 235, 245, .32);
  --sep: rgba(255, 255, 255, .12);
  /* materials: a translucent fill, a blur of whatever is behind it, and a hairline of light along the top edge */
  --glass: rgba(118, 118, 128, .2);
  --glass-2: rgba(118, 118, 128, .34);
  --glass-bar: rgba(34, 34, 38, .62);
  --frost: blur(30px) saturate(190%);
  --edge: inset 0 0 0 .5px rgba(255, 255, 255, .13), inset 0 1px 0 rgba(255, 255, 255, .1);
  --danger: #ff453a;
  --ok: #30d158;
  --gold: #e6c675;
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "PingFang SC", "PingFang TC", "Hiragino Sans", "Apple SD Gothic Neo", "Helvetica Neue", "Microsoft YaHei", "Microsoft JhengHei", "Yu Gothic UI", "Malgun Gothic", "Segoe UI", sans-serif;
  --display: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Helvetica Neue", "Arial Black", "PingFang SC", "Hiragino Sans", "Apple SD Gothic Neo", "Microsoft YaHei", "Malgun Gothic", sans-serif;
  --spring: cubic-bezier(.32, .72, 0, 1);
  --glitter: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 8 -3.9'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  color-scheme: dark;
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }
/* no scrollbars anywhere: the page and the sheets still scroll, the bar itself is not drawn */
* { scrollbar-width: none; }
*::-webkit-scrollbar { display: none; }
html { background: var(--bg); overflow-x: clip; -webkit-text-size-adjust: 100%; }
body { margin: 0; overflow-x: clip; background: var(--bg); color: var(--label); font: 17px/1.5 var(--font); font-variant-numeric: lining-nums; -webkit-font-smoothing: antialiased; }
button, input, textarea { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }
:focus-visible { outline: 2px solid #fff; outline-offset: 3px; border-radius: 6px; }
h1 { font: 700 34px/1.2 var(--display); letter-spacing: -.02em; margin: 0; }
p { margin: 0; }

/* ---------- chrome ---------- */
.top { max-width: 600px; margin: 0 auto; display: flex; justify-content: space-between; align-items: center; padding: calc(12px + env(safe-area-inset-top, 0px)) max(20px, env(safe-area-inset-right, 0px)) 0 max(20px, env(safe-area-inset-left, 0px)); position: relative; z-index: 8; }
.mark { font: italic 900 19px/1 var(--display); letter-spacing: -.02em; }
.top-acts { display: flex; gap: 8px; }
.icon-btn { width: 36px; height: 36px; border: 0; border-radius: 50%; background: var(--glass); -webkit-backdrop-filter: var(--frost); backdrop-filter: var(--frost); box-shadow: var(--edge); display: grid; place-items: center; cursor: pointer; padding: 0; transition: transform .12s ease-out, background .2s; }
.icon-btn:active { transform: scale(.92); background: var(--glass-2); }
.icon-btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.menu { position: absolute; right: max(20px, env(safe-area-inset-right, 0px)); top: calc(100% + 8px); min-width: 190px; border-radius: 14px; overflow: hidden; background: var(--glass-bar); -webkit-backdrop-filter: blur(40px) saturate(190%); backdrop-filter: blur(40px) saturate(190%); box-shadow: var(--edge), 0 18px 44px rgba(0, 0, 0, .55); transform-origin: 100% 0; animation: pop .3s var(--spring); }
.menu button { width: 100%; min-height: 44px; padding: 0 16px; border: 0; background: none; display: flex; justify-content: space-between; align-items: center; gap: 16px; cursor: pointer; text-align: start; }
.menu button + button { border-top: .5px solid var(--sep); }
.menu button:active { background: var(--glass-2); }
.menu .tick { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; display: block; }
@keyframes pop { from { opacity: 0; transform: scale(.86); } }
main { max-width: 600px; margin: 0 auto; padding: 16px max(20px, env(safe-area-inset-right, 0px)) calc(120px + env(safe-area-inset-bottom, 0px)) max(20px, env(safe-area-inset-left, 0px)); position: relative; z-index: 2; }
/* a floating bar of frosted glass: content scrolls underneath it */
.tabbar { position: fixed; left: 50%; bottom: calc(14px + env(safe-area-inset-bottom, 0px)); translate: -50% 0; z-index: 10; display: flex; gap: 2px; padding: 5px; border-radius: 999px; background: var(--glass-bar); -webkit-backdrop-filter: blur(34px) saturate(200%); backdrop-filter: blur(34px) saturate(200%); box-shadow: var(--edge), 0 10px 30px rgba(0, 0, 0, .5); }
.tabbar a { min-width: 76px; padding: 7px 8px 6px; border-radius: 999px; display: flex; flex-direction: column; align-items: center; gap: 2px; color: var(--label-2); font-size: 10.5px; font-weight: 500; line-height: 1.2; white-space: nowrap; transition: background .25s, color .25s, transform .12s ease-out; }
.tabbar a:active { transform: scale(.94); }
.tabbar a[aria-current="page"] { color: #fff; background: rgba(255, 255, 255, .16); }
.tabbar svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- shared pieces ---------- */
.view { display: flex; flex-direction: column; gap: 14px; }
.title-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding-top: 6px; }
.count, .lead, .caption { color: var(--label-2); }
.count { font-size: 15px; }
.lead { font-size: 17px; line-height: 1.55; }
.caption { font-size: 13px; line-height: 1.4; padding: 0 16px; }
.caption.center { text-align: center; }
.sec { font: 600 13px/1.3 var(--font); color: var(--label-2); margin: 14px 16px -6px; letter-spacing: .01em; }
.btn { border: 0; background: #fff; color: #000; min-height: 50px; padding: 0 28px; border-radius: 14px; font-weight: 600; cursor: pointer; display: inline-grid; place-items: center; text-align: center; transition: transform .12s ease-out, opacity .2s; }
.btn:active { transform: scale(.97); opacity: .85; }
.btn.wide { width: 100%; }
.btn:disabled { opacity: .35; cursor: not-allowed; }
.text-btn { border: 0; background: none; padding: 0; color: var(--label-2); font-size: 15px; cursor: pointer; white-space: nowrap; }
.text-btn:active { opacity: .5; }
.text-btn.danger { color: var(--danger); }
.text-btn.strong { color: #fff; font-weight: 600; }
.group { list-style: none; margin: 0; padding: 0; border-radius: 16px; overflow: hidden; background: var(--glass); -webkit-backdrop-filter: var(--frost); backdrop-filter: var(--frost); box-shadow: var(--edge); }
.cell { display: flex; align-items: center; gap: 12px; min-height: 48px; padding: 9px 16px; position: relative; }
.cell + .cell::before, .group > li + li::before { content: ""; position: absolute; left: 16px; right: 0; top: 0; border-top: .5px solid var(--sep); }
.group > li { position: relative; }
.cell.plain { width: 100%; border: 0; background: none; text-align: start; cursor: pointer; }
.cell .k { flex: none; min-width: 4.2em; white-space: nowrap; }
.cell input { flex: 1; min-width: 0; border: 0; background: none; padding: 4px 0; outline: none; }
.cell .main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.cell .t { overflow-wrap: anywhere; }
.cell .s { font-size: 13px; line-height: 1.4; color: var(--label-2); overflow-wrap: anywhere; }
.cell .acts { display: flex; gap: 16px; flex: none; align-items: center; }
.cell.link { cursor: pointer; }
.cell.link:active, .cell.plain:active { background: var(--glass-2); }
.cell .chev { flex: none; width: 8px; height: 13px; fill: none; stroke: var(--label-3); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; display: block; }
input::placeholder, textarea::placeholder { color: var(--label-3); }
.area { display: block; width: 100%; border: 0; background: none; padding: 12px 16px; resize: vertical; outline: none; line-height: 1.6; }
.flag { color: var(--danger); }
.msg { font-size: 14px; min-height: 1.3em; padding: 0 16px; color: var(--label-2); }
.msg.bad { color: var(--danger); } .msg.good { color: var(--ok); }
.chips, .seg-scroll { display: flex; flex-wrap: wrap; gap: 8px; }
.seg-scroll { flex-wrap: nowrap; overflow-x: auto; margin: 0 -20px; padding: 0 20px; scrollbar-width: none; }
.seg-scroll::-webkit-scrollbar { display: none; }
.chip { flex: none; border: 0; background: var(--glass); -webkit-backdrop-filter: var(--frost); backdrop-filter: var(--frost); box-shadow: var(--edge); color: #fff; border-radius: 999px; padding: 7px 15px; font-size: 15px; cursor: pointer; transition: transform .12s ease-out, background .2s, color .2s; }
.chip:active { transform: scale(.95); }
.chip[aria-pressed="true"] { background: #fff; color: #000; box-shadow: none; }
.empty { display: flex; flex-direction: column; align-items: center; gap: 16px; padding: 28px 0; color: var(--label-2); text-align: center; }
.form { display: flex; flex-direction: column; gap: 12px; }
.search { display: flex; align-items: center; gap: 8px; height: 40px; padding: 0 12px; border-radius: 12px; background: var(--glass); -webkit-backdrop-filter: var(--frost); backdrop-filter: var(--frost); box-shadow: var(--edge); }
.search svg { width: 18px; height: 18px; flex: none; fill: none; stroke: var(--label-2); stroke-width: 1.8; stroke-linecap: round; }
.search input { flex: 1; min-width: 0; border: 0; background: none; outline: none; -webkit-appearance: none; appearance: none; }
.results img, #picked img { width: 44px; height: 44px; border-radius: 6px; object-fit: cover; flex: none; background: var(--glass-2); }
.results .t, .results .s, #picked .t, #picked .s { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ---------- draw stage ---------- */
.stage { display: flex; flex-direction: column; align-items: center; gap: 18px; }
/* the whole band across the screen is one handle: press anywhere in it to turn the pack or the card */
.zone { width: 100vw; margin-inline: calc(50% - 50vw); display: grid; place-items: center; padding: clamp(8px, 5vh, 52px) 0 22px; touch-action: none; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent; cursor: grab; }
.zone:active { cursor: grabbing; }
.slot { position: relative; width: min(300px, 70vw, 36vh); aspect-ratio: 5 / 8.2; perspective: 1300px; }
.slot:has(.pack-btn:focus-visible) { outline: 2px solid #fff; outline-offset: 16px; border-radius: 12px; }
.pack-btn { position: absolute; inset: 0; opacity: 0; pointer-events: none; border: 0; background: none; }
.pk { position: absolute; left: 50%; top: 50%; width: 260%; height: 200%; translate: -50% -50%; pointer-events: none; transition: opacity .3s; }
.slot.off .pk { opacity: .35; }
.scene { position: absolute; inset: 0; transform-style: preserve-3d; }
.slot.charging .pk { animation: shake .09s linear infinite; }
@keyframes shake { 0% { translate: calc(-50% - 1.5px) calc(-50% + .5px); } 50% { translate: calc(-50% + 1.5px) calc(-50% - 1px); } 100% { translate: calc(-50% - 1px) calc(-50% + 1px); } }
.pk-shadow { position: absolute; inset: 10% 2% -5%; border-radius: 40%; background: conic-gradient(from 120deg, #ff2d78, #ffb02d, #3dffa8, #3db8ff, #8d5bff, #ff2d78); filter: blur(42px); opacity: .2; transition: opacity .6s; pointer-events: none; }
.detail-wrap { width: 100%; }
.fx { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 6; }
/* light from the revealed card's cover, held behind everything. The frosted panels below pick it up; the page itself stays black. */
.aura { position: fixed; left: 50%; top: -12vh; width: max(130vw, 900px); height: 125vh; translate: -50% 0; background-size: cover; background-position: center; filter: blur(90px) saturate(1.9); opacity: 0; transition: opacity 1.6s; pointer-events: none; z-index: 0; -webkit-mask: radial-gradient(ellipse 50% 46% at 50% 38%, #000 10%, transparent 100%); mask: radial-gradient(ellipse 50% 46% at 50% 38%, #000 10%, transparent 100%); }
.aura.on { opacity: .5; }
.rays { position: absolute; left: 50%; top: 50%; width: 300%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%; background: repeating-conic-gradient(from 0deg, rgba(255,255,255,0) 0 6deg, rgba(255,255,255,.2) 8.5deg, rgba(255,255,255,0) 11deg 18deg); -webkit-mask: radial-gradient(circle, #000 0, rgba(0,0,0,.55) 22%, transparent 58%); mask: radial-gradient(circle, #000 0, rgba(0,0,0,.55) 22%, transparent 58%); opacity: 0; pointer-events: none; }
.rays.on { animation: rays 2.4s ease-out forwards; }
@keyframes rays { 0% { opacity: 0; transform: scale(.5) rotate(0); } 14% { opacity: 1; } 100% { opacity: 0; transform: scale(1.1) rotate(38deg); } }

/* ---------- the card: cover on the front, lyrics on the back. Five rarities of every song. ---------- */
.cardbox { position: absolute; left: 0; right: 0; top: 50%; aspect-ratio: 5 / 7.4; translate: 0 -50%; transform-style: preserve-3d; }
.card3d { position: absolute; inset: 0; transform-style: preserve-3d; }
.cface { position: absolute; inset: 0; container-type: inline-size; overflow: hidden; border-radius: 6% / 4.05%; background: #0a0a0b; color: #fff; text-align: start; backface-visibility: hidden; -webkit-backface-visibility: hidden; box-shadow: 0 0 0 1px rgba(255,255,255,.12); }
.cface.b { transform: rotateY(180deg); }
.c-bg { position: absolute; inset: -22%; background-size: cover; background-position: center; filter: blur(9cqi) saturate(1.6) brightness(.5); }
.c-frame { position: absolute; inset: 2.6cqi; border-radius: 3.8cqi; border: 1px solid rgba(255,255,255,.18); pointer-events: none; z-index: 5; }
.c-hot { position: absolute; inset: 0; background: #fff; opacity: 0; pointer-events: none; z-index: 9; }
/* front */
.cf-top { position: absolute; left: 6.5cqi; right: 6.5cqi; top: 5.8cqi; z-index: 2; display: flex; justify-content: space-between; align-items: baseline; font: 600 3cqi/1 var(--display); letter-spacing: .22em; color: rgba(255,255,255,.9); text-shadow: 0 1px 4px rgba(0,0,0,.7); }
.cf-top b { font: italic 900 4.8cqi/1 var(--display); letter-spacing: -.02em; }
.cf-info { position: absolute; left: 0; right: 0; top: 89cqi; bottom: 0; z-index: 2; padding: 0 6.5cqi 5.4cqi; display: flex; flex-direction: column; }
.cf-pills { display: flex; gap: 2cqi; margin-bottom: 3.2cqi; }
.cf-pill { font: 600 3.1cqi/1 var(--font); padding: 1.7cqi 2.8cqi; border-radius: 99px; color: #fff; background: rgba(255,255,255,.18); -webkit-backdrop-filter: blur(12px) saturate(180%); backdrop-filter: blur(12px) saturate(180%); box-shadow: inset 0 0 0 .5px rgba(255,255,255,.2); white-space: nowrap; }
.cf-ttl { font: 700 8.6cqi/1.18 var(--display); letter-spacing: -.02em; margin: 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; text-shadow: 0 1px 6px rgba(0,0,0,.5); }
.cf-ttl.long { font-size: 6.4cqi; }
.cf-who { font-size: 4.4cqi; line-height: 1.45; color: rgba(255,255,255,.7); margin: 1.2cqi 0 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cf-foot { margin-top: auto; padding-top: 3cqi; border-top: 1px solid rgba(255,255,255,.16); font-size: 3.3cqi; line-height: 1.4; color: rgba(255,255,255,.56); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cf-holo { position: absolute; inset: 0; z-index: 4; pointer-events: none; mix-blend-mode: color-dodge; opacity: 0;
  background: linear-gradient(115deg, transparent 20%, rgba(255,45,120,.75) 35%, rgba(255,190,60,.75) 43%, rgba(120,255,170,.75) 50%, rgba(70,170,255,.75) 57%, rgba(150,100,255,.75) 65%, transparent 80%) var(--gx, 50%) 0 / 300% 100%;
  -webkit-mask-image: var(--glitter), linear-gradient(rgba(0,0,0,.22), rgba(0,0,0,.22)); mask-image: var(--glitter), linear-gradient(rgba(0,0,0,.22), rgba(0,0,0,.22)); }
.cf-glare { position: absolute; inset: 0; z-index: 4; pointer-events: none; background: radial-gradient(circle at var(--gx, 50%) var(--gy, 10%), rgba(255,255,255,.3), transparent 52%); opacity: var(--ga, 0); mix-blend-mode: soft-light; }
.c-play { position: absolute; z-index: 6; right: 6cqi; top: 78cqi; width: 17cqi; height: 17cqi; padding: 0; border: 0; border-radius: 50%; background: rgba(0,0,0,.4); -webkit-backdrop-filter: blur(12px) saturate(180%); backdrop-filter: blur(12px) saturate(180%); cursor: pointer; display: grid; place-items: center; transition: transform .2s var(--spring), background .2s; }
/* the target reaches past the disc you see, and the disc grows when the pointer is near: a press meant for it lands on it, not on the card */
.c-play::after { content: ""; position: absolute; inset: -30%; border-radius: 50%; }
.c-play.near, .c-play:hover { transform: scale(1.18); background: rgba(0,0,0,.6); }
.c-play:active { transform: scale(1.04); }
.c-play svg { width: 100%; height: 100%; display: block; }
.c-play .ring-bg { fill: none; stroke: rgba(255,255,255,.26); stroke-width: 1.5; }
.c-play .ring { fill: none; stroke: #fff; stroke-width: 1.5; stroke-linecap: round; stroke-dasharray: 113.1; stroke-dashoffset: 113.1; transform: rotate(-90deg); transform-origin: 50% 50%; }
.c-play path { fill: #fff; }
.c-play .i-pause, .c-play.on .i-play { display: none; }
.c-play.on .i-pause { display: block; }
.c-play.nudge { animation: nudge 1.4s ease-in-out infinite; }
@keyframes nudge { 50% { box-shadow: 0 0 0 2.4cqi rgba(255,255,255,.16); } }
@keyframes spin { to { rotate: 360deg; } }
/* back */
.cb-head { position: absolute; left: 7cqi; right: 7cqi; top: 7cqi; z-index: 2; display: flex; align-items: center; gap: 3.4cqi; }
.cb-head .txt { min-width: 0; flex: 1; }
.cb-ttl { font: 700 5.8cqi/1.25 var(--display); margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cb-who { font-size: 3.7cqi; line-height: 1.45; color: rgba(255,255,255,.62); margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cb-head .c-play { position: relative; inset: auto; flex: none; width: 12.5cqi; height: 12.5cqi; }
.ly-view { position: absolute; left: 7cqi; right: 7cqi; top: 25cqi; bottom: 8cqi; z-index: 2; overflow: hidden; -webkit-mask-image: linear-gradient(180deg, transparent, #000 20%, #000 76%, transparent); mask-image: linear-gradient(180deg, transparent, #000 20%, #000 76%, transparent); }
.ly-lines { will-change: transform; }
.ly { margin: 0 0 4cqi; font: 700 5.4cqi/1.4 var(--display); color: rgba(255,255,255,.3); transform-origin: 0 50%; transition: color .5s, transform .5s; overflow-wrap: anywhere; }
.ly.on { color: #fff; transform: scale(1.06); }
.ly.gap { height: 2.5cqi; margin: 0; }
.ly-note { margin: 0 0 5cqi; font-size: 3.4cqi; color: rgba(255,255,255,.5); }
.ly.say { font-weight: 500; font-size: 4.8cqi; line-height: 1.7; color: rgba(255,255,255,.88); }

/* ---------- under the card ---------- */
.detail { display: flex; flex-direction: column; gap: 12px; width: 100%; animation: rise .6s var(--spring) both; }
@keyframes rise { from { opacity: 0; transform: translateY(14px); } }
.d-head { text-align: center; padding: 2px 0 6px; }
.d-head h2 { font: 700 28px/1.2 var(--display); letter-spacing: -.02em; margin: 0; overflow-wrap: anywhere; text-wrap: balance; }
.d-head p { color: var(--label-2); margin-top: 3px; }
.d-head .badge { display: inline-block; margin-top: 10px; font-size: 13px; font-weight: 600; padding: 4px 11px; border-radius: 999px; background: var(--glass); -webkit-backdrop-filter: var(--frost); backdrop-filter: var(--frost); box-shadow: var(--edge); }
.d-head .badge.new { background: #fff; color: #000; box-shadow: none; }
.story { font-size: 17px; line-height: 1.75; white-space: pre-wrap; overflow-wrap: anywhere; padding: 14px 16px 6px; }
.sig { text-align: end; color: var(--label-2); font-size: 14px; padding: 0 16px 14px; overflow-wrap: anywhere; }
.embed { width: 100%; border: 0; border-radius: 16px; display: block; background: var(--glass); }
.embed.video { aspect-ratio: 16 / 9; height: auto; }
.note { padding: 11px 16px; display: flex; flex-direction: column; gap: 3px; }
.note .txt { white-space: pre-wrap; overflow-wrap: anywhere; }
.note .meta { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; font-size: 13px; color: var(--label-2); }
.note .meta .text-btn { font-size: 13px; }
.report { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; justify-content: center; }
.report .chip { font-size: 13px; padding: 5px 12px; }
.composer .send { flex: none; border: 0; background: #fff; color: #000; width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; cursor: pointer; padding: 0; transition: transform .12s ease-out, opacity .2s; }
.composer .send:active { transform: scale(.9); }
.composer .send:disabled { opacity: .3; }
.composer .send svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.d-foot { display: flex; justify-content: center; padding: 10px 0 0; }

/* ---------- shelf ---------- */
.shelf { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 22px 16px; padding-top: 6px; }
.thumb { border: 0; padding: 0; background: none; cursor: pointer; display: flex; flex-direction: column; gap: 6px; text-align: start; min-width: 0; transition: transform .15s ease-out; }
.thumb:active { transform: scale(.96); }
.thumb .t { font-size: 15px; font-weight: 500; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.thumb .s { font-size: 13px; line-height: 1.3; color: var(--label-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- sheet (a card opened from the shelf) + toast ---------- */
.scrim { position: fixed; inset: 0; z-index: 20; background: rgba(0, 0, 0, .4); opacity: 0; transition: opacity .4s; }
.scrim.on { opacity: 1; }
/* thick glass: the shelf stays visible, blurred, behind it */
.sheet { position: fixed; left: 50%; bottom: 0; z-index: 21; width: min(100%, 560px); height: calc(100dvh - 28px - env(safe-area-inset-top, 0px)); margin-left: max(-50%, -280px); border-radius: 24px 24px 0 0; background: rgba(28, 28, 32, .66); -webkit-backdrop-filter: blur(50px) saturate(200%); backdrop-filter: blur(50px) saturate(200%); box-shadow: var(--edge), 0 -10px 40px rgba(0, 0, 0, .5); transform: translateY(104%); transition: transform .55s var(--spring); display: flex; flex-direction: column; overflow: hidden; }
.sheet.on { transform: translateY(var(--pull, 0px)); }
.sheet.dragging { transition: none; }
.grab { flex: none; height: 30px; display: grid; place-items: center; cursor: grab; touch-action: none; }
.grab::before { content: ""; width: 36px; height: 5px; border-radius: 3px; background: var(--label-3); }
.sheet .x { position: absolute; top: 12px; right: 14px; z-index: 2; width: 30px; height: 30px; }
.sheet .x svg { width: 12px; height: 12px; stroke-width: 2.4; }
.sheet-body { flex: 1; overflow: auto; overscroll-behavior: contain; padding: 0 max(20px, env(safe-area-inset-right, 0px)) calc(40px + env(safe-area-inset-bottom, 0px)) max(20px, env(safe-area-inset-left, 0px)); display: flex; flex-direction: column; align-items: center; gap: 18px; }
/* inside the sheet the panels are plain translucent fills: glass on glass would turn to mud */
.sheet .group, .sheet .chip, .sheet .badge, .sheet .icon-btn { -webkit-backdrop-filter: none; backdrop-filter: none; background: rgba(255, 255, 255, .09); }
.hero { width: calc(100% + 40px); margin: 0 -20px; display: grid; place-items: center; padding: 6px 0 4px; touch-action: none; user-select: none; -webkit-user-select: none; cursor: grab; }
.hero:active { cursor: grabbing; }
.pslot { position: relative; flex: none; width: min(270px, 66vw); aspect-ratio: 5 / 7.4; perspective: 1300px; }
.pslot .cardbox { top: 0; translate: none; }
.segctl { display: flex; padding: 2px; border-radius: 9px; background: rgba(255, 255, 255, .09); max-width: 100%; }
.segctl button { border: 0; background: none; padding: 5px 12px; border-radius: 7px; font-size: 13px; font-weight: 500; cursor: pointer; white-space: nowrap; transition: background .25s; }
.segctl button[aria-pressed="true"] { background: rgba(255, 255, 255, .2); box-shadow: 0 1px 3px rgba(0,0,0,.3); }
.toast { position: fixed; left: 50%; bottom: calc(96px + env(safe-area-inset-bottom, 0px)); translate: -50% 0; background: var(--glass-bar); -webkit-backdrop-filter: blur(30px) saturate(190%); backdrop-filter: blur(30px) saturate(190%); box-shadow: var(--edge); color: #fff; padding: 10px 18px; border-radius: 999px; font-size: 15px; z-index: 50; max-width: min(88vw, 440px); text-align: center; }
.toast.show { animation: toast .4s var(--spring); }
@keyframes toast { from { opacity: 0; transform: translateY(10px) scale(.96); } }

/* ---------- rarity. Five tiers, and the whole card takes the shape of a medium: a download, a cassette, a CD in
   its jewel case, an LP in its sleeve, a gold record. The cover stays large on all of them. A song that was released
   with other covers shows a different one on its rarer cards (--cv is set per rarity by app.js). The extra pieces
   of each medium live in .fmt (five <i>). No card has a frame. Each tier also gets a little more
   from the printer: plain, matt paper, the gloss of the case, holographic foil on the sleeve, gold foil over all. ---------- */
.v0 { --tier: #c3c6d1; } .v1 { --tier: #4fdc8c; } .v2 { --tier: #4da6ff; } .v3 { --tier: #b684ff; } .v4 { --tier: #f2cb62; }
.art { position: relative; display: block; aspect-ratio: 1; overflow: hidden; background: #0c0c0e; }
.art > span { position: absolute; inset: 0; }
.a-face { display: grid; place-items: center; background: var(--cv) center / cover; }
.a-face b { font: 800 40cqi/1 var(--display); color: rgba(255, 255, 255, .9); }
.a-foil { opacity: 0; pointer-events: none; }
.cf-art { position: absolute; left: 0; right: 0; top: 0; }
.cf-art::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: linear-gradient(180deg, rgba(0, 0, 0, .4), transparent 15%, transparent 70%, rgba(10, 10, 11, .92) 100%); }
.cface.f > .c-bg { background-image: var(--cv); }
.fmt { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.fmt i, .fmt::before, .fmt::after { position: absolute; display: block; }
.card3d .c-frame { display: none; }
.cf-pill.var { background: var(--tier, #fff); color: #000; box-shadow: none; }
/* whatever turns, turns while its song plays */
.card3d.playing .fmt i { animation-play-state: running !important; }
.card3d.v1 .cf-foot, .card3d.v2 .cf-foot, .card3d.v3 .cf-foot, .card3d.v4 .cf-foot { display: none; }
.card3d.v1 .cf-ttl, .card3d.v2 .cf-ttl, .card3d.v3 .cf-ttl, .card3d.v4 .cf-ttl { -webkit-line-clamp: 1; font-size: 7.6cqi; }
.card3d.v1 .cf-ttl.long, .card3d.v2 .cf-ttl.long, .card3d.v3 .cf-ttl.long, .card3d.v4 .cf-ttl.long { font-size: 6.4cqi; }
.card3d.v1 .cf-pills, .card3d.v2 .cf-pills, .card3d.v3 .cf-pills, .card3d.v4 .cf-pills { margin-bottom: 2.2cqi; }

/* Uncommon: a cassette from the seventies. A dark shell with a screw in each top corner; a cream paper label
   carrying the cover and three stripes; a window cut into the label, with two reels turning behind the glass. */
.card3d.v1 .f > .c-bg { display: none; }
.card3d.v1 .cface.f { box-shadow: 0 0 0 1px rgba(255, 255, 255, .14), inset 0 0 0 .6cqi rgba(255, 255, 255, .05), inset 0 .6cqi 0 .6cqi rgba(255, 255, 255, .09); background:
  radial-gradient(circle at 3.4cqi 3.4cqi, #b9b3a4 0 .75cqi, #0e0d0c .85cqi 1.35cqi, transparent 1.45cqi),
  radial-gradient(circle at calc(100% - 3.4cqi) 3.4cqi, #b9b3a4 0 .75cqi, #0e0d0c .85cqi 1.35cqi, transparent 1.45cqi),
  linear-gradient(180deg, #38342f, #211f1c 55%, #141312); }
.card3d.v1 .fmt::before { content: ""; left: 4.5cqi; right: 4.5cqi; top: 4.5cqi; height: 115cqi; border-radius: 2.6cqi; box-shadow: inset 0 0 0 .3cqi rgba(90, 70, 40, .28), inset 0 0 3.5cqi rgba(130, 96, 40, .28), 0 .5cqi 1.2cqi rgba(0, 0, 0, .55);
  background: linear-gradient(180deg, transparent 0 82.3%, #e3b23c 82.3% 85.4%, transparent 85.4% 86.4%, #e8762d 86.4% 89.5%, transparent 89.5% 90.5%, #c93a2e 90.5% 93.7%, transparent 93.7%), linear-gradient(180deg, #f4ebd8, #e8dec6); }
.card3d.v1 .fmt::after { content: "STEREO  ·  SIDE B  ·  NORMAL POSITION"; left: 8cqi; right: 8cqi; top: 93.6cqi; font: 700 2.2cqi/1 "Courier New", ui-monospace, monospace; letter-spacing: .16em; color: #7d6c4c; text-align: center; white-space: nowrap; overflow: hidden; }
.card3d.v1 .cf-art { z-index: 2; left: 7.5cqi; right: 7.5cqi; top: 7.5cqi; border-radius: 1cqi; box-shadow: 0 0 0 .3cqi rgba(60, 45, 20, .4); }
.card3d.v1 .cf-art::after { background: linear-gradient(180deg, rgba(0, 0, 0, .36), transparent 16%); }
.card3d.v1 .cf-top { z-index: 3; left: 11cqi; right: 11cqi; top: 11cqi; }
.card3d.v1 .f > .c-play { right: 10.5cqi; top: 72.5cqi; }
/* the window: tape wound on both reels, more on the left */
.card3d.v1 .fmt i:nth-child(1), .card3d.v1 .fmt i:nth-child(4) { left: 23cqi; right: 23cqi; top: 97.5cqi; height: 16.5cqi; border-radius: 3cqi; }
.card3d.v1 .fmt i:nth-child(1) { box-shadow: 0 0 0 .5cqi #d7cdb5, 0 0 0 .85cqi rgba(60, 45, 20, .5); background:
  radial-gradient(circle at 10.5cqi 50%, transparent 0 4.25cqi, #22140a 4.35cqi, #724a2a 5.9cqi, #3a2312 7.8cqi, transparent 8cqi),
  radial-gradient(circle at calc(100% - 10.5cqi) 50%, transparent 0 4.25cqi, #22140a 4.35cqi, #6a4326 5cqi, #3a2312 5.5cqi, transparent 5.7cqi), #0b0a09; }
/* the reels: a pale ring with six lugs pointing in */
.card3d.v1 .fmt i:nth-child(2), .card3d.v1 .fmt i:nth-child(3) { top: 101.5cqi; width: 8.5cqi; height: 8.5cqi; border-radius: 50%; animation: spin 3.4s linear infinite paused;
  background: radial-gradient(circle closest-side, #0b0a09 0 34%, transparent 35%), repeating-conic-gradient(from 8deg, #f2eee4 0 20deg, transparent 20deg 60deg), radial-gradient(circle closest-side, transparent 0 66%, #f7f3ea 67% 100%); }
.card3d.v1 .fmt i:nth-child(2) { left: 29.25cqi; } .card3d.v1 .fmt i:nth-child(3) { right: 29.25cqi; }
/* the glass over them: a shadow under the top edge, a streak of light across, a rim of shade around each reel */
.card3d.v1 .fmt i:nth-child(4) { box-shadow: inset 0 1.5cqi 2.4cqi rgba(0, 0, 0, .9), inset 0 -.3cqi .6cqi rgba(255, 255, 255, .1), inset 0 0 0 .3cqi rgba(0, 0, 0, .5); background:
  linear-gradient(112deg, rgba(255, 255, 255, .3) 0 8%, rgba(255, 255, 255, .04) 9% 33%, rgba(255, 255, 255, .15) 34% 40%, transparent 41%),
  radial-gradient(circle 4.3cqi at 10.5cqi 50%, transparent 55%, rgba(0, 0, 0, .4) 100%, transparent 0),
  radial-gradient(circle 4.3cqi at calc(100% - 10.5cqi) 50%, transparent 55%, rgba(0, 0, 0, .4) 100%, transparent 0); }
.card3d.v1 .cf-info { top: 121cqi; padding-bottom: 2.6cqi; }
.card3d.v1 .cf-pills { margin-bottom: 1.8cqi; }
.card3d.v1 .cf-ttl { font-family: "Courier New", ui-monospace, "PingFang SC", "Microsoft YaHei", monospace; font-weight: 700; letter-spacing: 0; font-size: 7cqi; color: #f1e8d4; }
.card3d.v1 .cf-ttl.long { font-size: 5.8cqi; }
.card3d.v1 .cf-who { margin-top: .4cqi; font-size: 4cqi; color: rgba(241, 232, 212, .62); }

/* Rare: a CD in its jewel case. The hinge runs down the left edge and the cover is the booklet, its corners rounded
   and set in from the edge of the case. The disc slides out from under it and the title is printed on the disc. */
.card3d.v2 .f > .c-bg { display: none; }
.card3d.v2 .cface.f { background: linear-gradient(180deg, #1c1e23, #0c0d10); box-shadow: 0 0 0 1px rgba(255, 255, 255, .32), inset 0 0 0 .5cqi rgba(255, 255, 255, .14); }
.card3d.v2 .cf-art { z-index: 2; left: 10.6cqi; right: 3.4cqi; top: 3.4cqi; border-radius: 2.4cqi; box-shadow: 0 0 0 .3cqi rgba(255, 255, 255, .25), 0 1.6cqi 5cqi rgba(0, 0, 0, .8); }
.card3d.v2 .cf-art::after { background: linear-gradient(180deg, rgba(0, 0, 0, .36), transparent 15%); }
.card3d.v2 .cf-top { z-index: 3; left: 14.5cqi; right: 7.4cqi; top: 7.4cqi; }
.card3d.v2 .f > .c-play { right: 6.6cqi; top: 69cqi; }
.card3d.v2 .fmt i:nth-child(1) { left: 0; top: 0; bottom: 0; width: 7.6cqi; box-shadow: inset -.4cqi 0 0 rgba(255, 255, 255, .26);
  background: linear-gradient(180deg, transparent 0 6%, rgba(0, 0, 0, .6) 6% 9%, transparent 9% 91%, rgba(0, 0, 0, .6) 91% 94%, transparent 94%), repeating-linear-gradient(180deg, rgba(255, 255, 255, .2) 0 .35cqi, transparent .35cqi 1.6cqi), linear-gradient(90deg, #17181c, #363840 70%, #1c1d21); }
.card3d.v2 .fmt i:nth-child(2) { left: 9.6cqi; top: 44.4cqi; width: 88cqi; height: 88cqi; border-radius: 50%; box-shadow: 0 0 0 .35cqi rgba(255, 255, 255, .7), 0 0 4cqi rgba(160, 200, 255, .18); animation: spin 9s linear infinite paused;
  background: radial-gradient(circle closest-side, #0b0c0e 0 7%, rgba(255, 255, 255, .95) 7.5% 8.5%, rgba(176, 183, 197, .75) 9% 18%, rgba(255, 255, 255, .9) 18.5% 19.5%, transparent 20%),
    conic-gradient(transparent 0 6%, rgba(255, 110, 170, .5) 9%, rgba(255, 214, 110, .5) 12%, rgba(120, 255, 180, .5) 15%, rgba(110, 180, 255, .5) 18%, transparent 21% 56%, rgba(255, 110, 170, .5) 59%, rgba(255, 214, 110, .5) 62%, rgba(120, 255, 180, .5) 65%, rgba(110, 180, 255, .5) 68%, transparent 71%),
    conic-gradient(#eceff4, #c9cfda 10%, #f8f9fb 21%, #b7bfcc 33%, #eef1f5 46%, #c8ced9 58%, #f8f9fb 71%, #bac2ce 84%, #eceff4); }
.card3d.v2 .cf-info { top: 100.5cqi; left: 9.6cqi; right: 2.4cqi; padding: 0 9cqi; align-items: center; text-align: center; z-index: 3; }
.card3d.v2 .cf-ttl { color: #14151a; text-shadow: 0 1px 0 rgba(255, 255, 255, .55); }
.card3d.v2 .cf-who { color: rgba(20, 21, 26, .72); }
.card3d.v2 .cf-pill:not(.var) { background: rgba(0, 0, 0, .6); -webkit-backdrop-filter: none; backdrop-filter: none; }
/* printing: the gloss of the case, a bar of light that crosses the booklet as the card turns */
.card3d.v2 .a-foil { opacity: calc(var(--ga, .5) * .85); background: linear-gradient(115deg, transparent 36%, rgba(255, 255, 255, .3) 47%, rgba(255, 255, 255, .5) 50%, rgba(255, 255, 255, .3) 53%, transparent 64%) var(--gx, 50%) 0 / 300% 100%; }

/* Epic: an LP. The cover is the sleeve, edge to edge, and the record slides out from under it. */
.card3d.v3 .f > .c-bg { display: none; }
.card3d.v3 .cface.f { background: #09090b; }
.card3d.v3 .cf-art { z-index: 2; box-shadow: 0 1.6cqi 5cqi rgba(0, 0, 0, .85); }
.card3d.v3 .cf-art::after { background: linear-gradient(180deg, rgba(0, 0, 0, .4), transparent 15%), radial-gradient(circle closest-side, transparent 88%, rgba(255, 255, 255, .07) 91%, transparent 95%); }
.card3d.v3 .f > .c-play { top: 79cqi; }
.card3d.v3 .fmt i:nth-child(1) { left: 2cqi; top: 49cqi; width: 96cqi; height: 96cqi; border-radius: 50%; box-shadow: 0 0 0 .3cqi rgba(255, 255, 255, .2); animation: spin 7s linear infinite paused;
  background: repeating-radial-gradient(circle closest-side, rgba(255, 255, 255, .085) 0 .5%, rgba(0, 0, 0, 0) .5% 1.6%),
    conic-gradient(rgba(255, 255, 255, .42), transparent 10%, rgba(255, 255, 255, .16) 27%, transparent 42%, rgba(255, 255, 255, .42) 50%, transparent 60%, rgba(255, 255, 255, .16) 77%, transparent 92%, rgba(255, 255, 255, .42)), #0b0b0d; }
.card3d.v3 .fmt i:nth-child(2) { left: 35cqi; top: 82cqi; width: 30cqi; height: 30cqi; border-radius: 50%; background: var(--cv) center / cover; box-shadow: 0 0 0 .5cqi #000, 0 0 0 1cqi rgba(255, 255, 255, .1); }
.card3d.v3 .cf-info { top: 113.5cqi; z-index: 3; align-items: center; text-align: center; }
.card3d.v3 .cf-top { z-index: 3; }
/* printing: holographic foil on the sleeve, light enough that the cover is still the thing you look at */
.card3d.v3 .a-foil { opacity: calc(var(--ga, .5) * .4); mix-blend-mode: color-dodge; background: linear-gradient(115deg, transparent 18%, rgba(255, 45, 120, .8) 34%, rgba(255, 190, 60, .8) 42%, rgba(120, 255, 170, .8) 50%, rgba(70, 170, 255, .8) 58%, rgba(150, 100, 255, .8) 66%, transparent 82%) var(--gx, 50%) 0 / 300% 100%;
  -webkit-mask-image: var(--glitter), linear-gradient(rgba(0, 0, 0, .26), rgba(0, 0, 0, .26)); mask-image: var(--glitter), linear-gradient(rgba(0, 0, 0, .26), rgba(0, 0, 0, .26)); }

/* Legendary: the gold record, and the largest disc of all. It is wider than the card and sits centred behind the
   cover, so its rim shows above and below (the sides run off the card, which is why the two visible parts are broad
   and shallow: the disc itself is a true circle). No frame. The wordmark is engraved on the rim above the cover, the
   title and the artist on the rim below it. Three points of light twinkle and a sheet of gold foil light crosses
   everything. Like every other disc it turns while its song plays. */
.card3d.v4 .f > .c-bg { display: none; }
.card3d.v4 .cface.f { background: radial-gradient(circle at 50% 50%, #17100a, #060403 70%); }
.card3d.v4 .cf-art { z-index: 2; top: 18cqi; box-shadow: 0 0 6cqi rgba(0, 0, 0, .9); }
.card3d.v4 .cf-art::after { background: none; }
.card3d.v4 .f > .c-play { top: 96cqi; }
.card3d.v4 .fmt i:nth-child(1) { left: -22cqi; top: -2cqi; width: 144cqi; height: 144cqi; border-radius: 50%; box-shadow: 0 0 0 .4cqi rgba(255, 246, 206, .9), 0 0 9cqi rgba(255, 200, 90, .35); animation: spin 11s linear infinite paused;
  background: repeating-radial-gradient(circle closest-side, rgba(110, 72, 0, .2) 0 .4%, rgba(255, 250, 220, .1) .4% 1.3%),
    conic-gradient(rgba(255, 255, 255, .6), transparent 8%, transparent 42%, rgba(255, 255, 255, .6) 50%, transparent 58%, transparent 92%, rgba(255, 255, 255, .6)),
    conic-gradient(#fdf0b8, #e2bb55 12%, #c99a34 24%, #f6dd90 37%, #fff3c4 50%, #dcb24a 62%, #c6952f 75%, #f3d681 88%, #fdf0b8); }
/* three points of light */
.card3d.v4 .fmt i:nth-child(n + 3) { z-index: 5; width: 6cqi; height: 6cqi; background: #fff8dc; clip-path: polygon(50% 0, 59% 41%, 100% 50%, 59% 59%, 50% 100%, 41% 59%, 0 50%, 41% 41%); animation: twinkle 2.8s ease-in-out infinite; }
.card3d.v4 .fmt i:nth-child(3) { left: 7cqi; top: 23cqi; }
.card3d.v4 .fmt i:nth-child(4) { right: 8cqi; top: 84cqi; width: 4.4cqi; height: 4.4cqi; animation-delay: -1s; }
.card3d.v4 .fmt i:nth-child(5) { left: 16cqi; top: 121cqi; width: 5cqi; height: 5cqi; animation-delay: -1.9s; }
@keyframes twinkle { 0%, 100% { opacity: 0; transform: scale(.3) rotate(0deg); } 50% { opacity: 1; transform: scale(1) rotate(24deg); } }
/* engraved lettering: dark, with a line of light under it */
.card3d.v4 .cf-top { z-index: 5; left: 21cqi; right: 21cqi; top: 6.4cqi; color: #2b1d05; text-shadow: 0 1px 0 rgba(255, 246, 206, .5); }
.card3d.v4 .cf-top b { color: #2b1d05; }
.card3d.v4 .cf-info { top: 108.5cqi; z-index: 5; padding: 0 13cqi; align-items: center; text-align: center; }
.card3d.v4 .cf-pills { margin-bottom: 5.4cqi; }
.card3d.v4 .cf-ttl { color: #2b1d05; text-shadow: 0 1px 0 rgba(255, 250, 220, .65); }
.card3d.v4 .cf-who { color: rgba(43, 29, 5, .8); font-weight: 600; }
.card3d.v4 .cf-pill.var { background: linear-gradient(135deg, #fbe8ae, #c9962b); }
.card3d.v4 .cf-pill:not(.var) { background: rgba(0, 0, 0, .6); -webkit-backdrop-filter: none; backdrop-filter: none; }
/* printing: gold foil, a sheet of light that crosses the whole card */
.card3d.v4 .cf-holo { opacity: calc(var(--ga, 0) * .32); background-image: linear-gradient(115deg, transparent 22%, rgba(255, 214, 110, .9) 40%, rgba(255, 255, 255, .95) 50%, rgba(255, 200, 90, .9) 60%, transparent 78%); }

/* ---------- a small flat card for grids (the shelf, a ten-pack): the same face as the real one, without its controls ---------- */
.card3d.mini { --th: 0px; --ga: .55; --gx: 38%; --da: 30deg; position: relative; inset: auto; display: block; width: 100%; aspect-ratio: 5 / 7.4; text-align: start; }
/* no blur here: with dozens of these on screen it would cost too much. A corner of the cover, enlarged, does the same job. */
.mini.v0 .f > .c-bg { inset: 0; filter: saturate(1.5) brightness(.42); background: var(--cv) 50% 88% / 420%; }
.mini .a-foil { -webkit-mask-image: none; mask-image: none; }
.mini.v3 .a-foil { opacity: .2; mix-blend-mode: screen; }
.mini .cf-pill { -webkit-backdrop-filter: none; backdrop-filter: none; }
.mini.v0 .cf-pill { font-size: 4.6cqi; padding: 2cqi 3.4cqi; }
.mini.v0 .cf-ttl { font-size: 9.4cqi; }
.mini.v0 .cf-who { font-size: 6.2cqi; }
/* nothing turns or twinkles in a grid */
.mini .fmt i { animation-play-state: paused !important; }
.mini.v4 .fmt i:nth-child(n + 3) { opacity: .9; animation: none; }

/* A card has a little thickness: the two faces sit apart, and between them is the cut edge of the board,
   pale card stock with a line of the tier's colour through its core. */
.card3d { --th: 5px; }
.cface.f { transform: translateZ(calc(var(--th) / 2)); }
.cface.b { transform: rotateY(180deg) translateZ(calc(var(--th) / 2)); }
.c-edge, .c-wall { position: absolute; pointer-events: none; background: #d3d4da; }
.c-edge { inset: 0; border-radius: 6% / 4.05%; transform: translateZ(var(--z)); }
.c-edge.mid { background: var(--tier, #8d8e96); }
.c-wall.l, .c-wall.r { top: 4.05%; bottom: 4.05%; width: var(--th); background: linear-gradient(90deg, #d3d4da 0 28%, var(--tier, #8d8e96) 28% 72%, #d3d4da 72%); }
.c-wall.t, .c-wall.b { left: 6%; right: 6%; height: var(--th); background: linear-gradient(180deg, #d3d4da 0 28%, var(--tier, #8d8e96) 28% 72%, #d3d4da 72%); }
.c-wall.l { left: 0; transform: translateX(-50%) rotateY(90deg); }
.c-wall.r { right: 0; transform: translateX(50%) rotateY(90deg); }
.c-wall.t { top: 0; transform: translateY(-50%) rotateX(90deg); }
.c-wall.b { bottom: 0; transform: translateY(50%) rotateX(90deg); }

/* ---------- under the pack: which kind, how many are left, the daily check-in ---------- */
.hud { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 10px; width: 100%; margin-top: -4px; transition: opacity .3s; }
.hud.busy { opacity: .35; pointer-events: none; }
.hud .segctl { padding: 3px; border-radius: 999px; background: var(--glass); -webkit-backdrop-filter: var(--frost); backdrop-filter: var(--frost); box-shadow: var(--edge); }
.hud .segctl button { min-height: 34px; padding: 0 15px; border-radius: 999px; font-size: 15px; transition: background .25s, color .25s, transform .12s ease-out; }
.hud .segctl button:active { transform: scale(.95); }
.hud .segctl button[aria-pressed="true"] { background: #fff; color: #000; box-shadow: none; }
.hud .segctl button.gold { color: var(--gold); }
.hud .segctl button.gold[aria-pressed="true"] { background: linear-gradient(135deg, #fbe8ae, #c9962b); color: #000; }
.meter, .checkin { display: inline-flex; align-items: center; gap: 7px; min-height: 40px; padding: 0 15px; border: 0; border-radius: 999px; background: var(--glass); -webkit-backdrop-filter: var(--frost); backdrop-filter: var(--frost); box-shadow: var(--edge); font-size: 15px; white-space: nowrap; }
.meter { font-variant-numeric: tabular-nums; }
.meter span:first-child { display: grid; }
.meter svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; display: block; }
.meter b { font-weight: 600; }
.meter .of { color: var(--label-3); margin-left: -3px; }
.meter .next { color: var(--label-2); font-size: 13px; min-width: 2.4em; }
.meter .next:empty { display: none; }
.checkin { cursor: pointer; transition: transform .12s ease-out, background .2s, color .2s; }
.checkin:active { transform: scale(.95); }
.checkin.due { background: #fff; color: #000; font-weight: 600; box-shadow: none; }
.checkin:disabled { color: var(--label-2); cursor: default; }

/* ---------- ten at once: ten small cards face down, turning over one after another ---------- */
.ten { width: 100%; display: flex; flex-direction: column; gap: 22px; padding-top: clamp(6px, 3vh, 30px); }
.ten-grid { display: flex; flex-wrap: wrap; justify-content: center; gap: 14px 10px; perspective: 1100px; }
.tile { position: relative; flex: none; width: calc((100% - 40px) / 5); border: 0; padding: 0; background: none; cursor: pointer; transform-style: preserve-3d; transform: rotateY(180deg); transition: transform .62s var(--spring); -webkit-tap-highlight-color: transparent; }
.tile.on { transform: none; }
.tile .t-back { position: absolute; inset: 0; border-radius: 6% / 4.05%; transform: rotateY(180deg); backface-visibility: hidden; -webkit-backface-visibility: hidden; display: grid; place-items: center; background: linear-gradient(135deg, #1b1b20, #0c0c0f 55%, #18181c); box-shadow: inset 0 0 0 .5px rgba(255, 255, 255, .18); font: italic 900 20px/1 var(--display); color: rgba(255, 255, 255, .3); }
.tile.new::after { content: ""; position: absolute; right: -3px; top: -3px; width: 10px; height: 10px; border-radius: 50%; background: #fff; box-shadow: 0 0 0 2px #000; opacity: 0; transition: opacity .3s .5s; }
.tile.new.on::after { opacity: 1; }
/* on a phone, three across: all ten still fit on one screen and each cover stays big enough to read */
@media (max-width: 540px) { .tile { width: calc((100% - 20px) / 3); } }

/* ---------- small pieces that came with rarity ---------- */
.row-card { flex: none; width: 46px; }
.tier-name { font-weight: 600; color: var(--tier); }
.odds { flex: none; color: var(--label-2); font-variant-numeric: tabular-nums; }
.d-head .badge:not(.new) { color: var(--tier, #fff); }
.story.quiet { color: var(--label-2); font-size: 15px; line-height: 1.6; padding-bottom: 12px; }
.about-p { padding: 13px 16px; font-size: 16px; line-height: 1.65; }
.about .caption { padding-top: 2px; }

/* ---------- what is playing: a bar of glass above the tabs, on every screen ---------- */
.np { position: fixed; left: 50%; translate: -50% 0; bottom: calc(84px + env(safe-area-inset-bottom, 0px)); z-index: 9; width: min(calc(100vw - 32px), 420px); display: flex; align-items: center; gap: 8px; padding: 7px 8px 8px 7px; border-radius: 16px; overflow: hidden; background: var(--glass-bar); -webkit-backdrop-filter: blur(34px) saturate(200%); backdrop-filter: blur(34px) saturate(200%); box-shadow: var(--edge), 0 10px 30px rgba(0, 0, 0, .5); animation: np-in .45s var(--spring); }
@keyframes np-in { from { opacity: 0; transform: translateY(12px); } }
.np-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; border: 0; padding: 0; background: none; text-align: start; cursor: pointer; }
.np-main:active { opacity: .6; }
.np-cover { flex: none; width: 40px; height: 40px; border-radius: 7px; background: var(--glass-2) center / cover; }
.np-txt { min-width: 0; display: flex; flex-direction: column; }
.np-txt .t { font-size: 15px; font-weight: 600; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.np-txt .s { font-size: 13px; line-height: 1.3; color: var(--label-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.np .c-play { position: relative; inset: auto; flex: none; width: 38px; height: 38px; background: none; -webkit-backdrop-filter: none; backdrop-filter: none; animation: none; }
.np-x { flex: none; width: 30px; height: 30px; border: 0; border-radius: 50%; background: none; color: var(--label-2); display: grid; place-items: center; cursor: pointer; padding: 0; }
.np-x:active { opacity: .5; }
.np-x svg { width: 11px; height: 11px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; }
.np-line { position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: rgba(255, 255, 255, .1); }
.np-line i { display: block; height: 100%; background: #fff; transform-origin: 0 50%; transform: scaleX(0); }
body.has-np main { padding-bottom: calc(184px + env(safe-area-inset-bottom, 0px)); }
body.has-np .toast { bottom: calc(156px + env(safe-area-inset-bottom, 0px)); }

/* ---------- favourites, the shelf's rarity chips ---------- */
.d-acts { display: flex; justify-content: center; gap: 10px; margin-top: 12px; }
.fav { display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 0 15px; border: 0; border-radius: 999px; background: var(--glass); -webkit-backdrop-filter: var(--frost); backdrop-filter: var(--frost); box-shadow: var(--edge); font-size: 15px; cursor: pointer; transition: transform .12s ease-out, background .2s, color .2s; }
.fav:active { transform: scale(.95); }
.fav svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round; display: block; }
.fav.on { background: #fff; color: #000; box-shadow: none; }
.fav.on svg { fill: #ff375f; stroke: #ff375f; }
.sheet .fav { -webkit-backdrop-filter: none; backdrop-filter: none; background: rgba(255, 255, 255, .09); }
.sheet .fav.on { background: #fff; }
.chip.tier:not([aria-pressed="true"]) { color: var(--tier); }
.chip.play-all { margin-left: auto; }
/* the bar that shows what is playing now sits at the top, under the wordmark, and the page makes room for it */
.np { top: calc(56px + env(safe-area-inset-top, 0px)); bottom: auto; }
@keyframes np-in { from { opacity: 0; transform: translateY(-12px); } }
main { transition: padding-top .45s var(--spring); }
body.has-np main { padding-top: 78px; padding-bottom: calc(120px + env(safe-area-inset-bottom, 0px)); }
body.has-np .toast { bottom: calc(96px + env(safe-area-inset-bottom, 0px)); }
/* lyrics are a sheet to read: every line equally clear */
.ly { color: rgba(255, 255, 255, .82); }

/* ---------- the shelf on every width ---------- */
/* On a wide screen the shelf gets a wider page, so a row holds more than three cards. */
.top, main { transition: max-width .45s var(--spring), padding-top .45s var(--spring); }
body[data-view="shelf"] .top, body[data-view="shelf"] main { max-width: 1120px; }
.shelf { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 20px 16px; }
@media (max-width: 480px) { .shelf { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 12px; } }
/* Filter rows scroll sideways on a phone and fade out at the edges, so a chip is never sliced in half; where there
   is room they simply wrap. */
.seg-scroll { margin: 0 calc(-1 * max(20px, env(safe-area-inset-right, 0px))) 0 calc(-1 * max(20px, env(safe-area-inset-left, 0px))); padding: 2px max(20px, env(safe-area-inset-right, 0px)) 2px max(20px, env(safe-area-inset-left, 0px));
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 20px, #000 calc(100% - 28px), transparent); mask-image: linear-gradient(90deg, transparent, #000 20px, #000 calc(100% - 28px), transparent); }
@media (min-width: 700px) { .seg-scroll { flex-wrap: wrap; overflow: visible; margin: 0; padding: 0; -webkit-mask-image: none; mask-image: none; } }

/* ---------- posters: the picture of a draw, and the two things to do with it ---------- */
.poster { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.poster img { width: min(100%, 400px); border-radius: 18px; display: block; box-shadow: 0 0 0 .5px rgba(255, 255, 255, .16), 0 14px 40px rgba(0, 0, 0, .5); }
.poster .btn { max-width: 400px; }
.btn.ghost { background: rgba(255, 255, 255, .13); color: #fff; }

/* ---------- the dock: what is playing and the tabs, one piece of glass at the foot of the screen.
   The pack and the shelf sit together on the left; putting a song in is on its own on the right. ---------- */
.dock { position: fixed; left: 50%; translate: -50% 0; bottom: calc(14px + env(safe-area-inset-bottom, 0px)); z-index: 10; width: min(calc(100vw - 28px), 400px); border-radius: 30px; overflow: hidden; background: var(--glass-bar); -webkit-backdrop-filter: blur(34px) saturate(200%); backdrop-filter: blur(34px) saturate(200%); box-shadow: var(--edge), 0 10px 30px rgba(0, 0, 0, .5); }
.dock .tabbar { position: static; translate: none; width: 100%; padding: 5px; border-radius: 0; background: none; -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none; }
.dock .tabbar a[data-v="share"] { margin-left: auto; }
.dock .np { position: relative; left: auto; top: auto; bottom: auto; translate: none; width: 100%; padding: 9px 10px 10px 10px; border-radius: 0; background: none; -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none; animation: np-open .4s var(--spring); }
@keyframes np-open { from { opacity: 0; } }
body.has-np main { padding-top: 16px; padding-bottom: calc(186px + env(safe-area-inset-bottom, 0px)); }
body.has-np .toast { bottom: calc(160px + env(safe-area-inset-bottom, 0px)); }
@media (prefers-reduced-transparency: reduce) { .dock { -webkit-backdrop-filter: none; backdrop-filter: none; background: #1c1c1e; } .dock .tabbar, .dock .np { background: none; } }

/* with a song in the dock, the pack and the card give up some height so nothing under them hides behind it */
body.has-np .slot { width: min(300px, 70vw, 30vh); }

/* ---------- the first-visit guide ---------- */
.guide { position: fixed; inset: 0; z-index: 40; display: grid; place-items: center; padding: 20px; background: rgba(0, 0, 0, .55); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); opacity: 0; transition: opacity .4s; }
.guide.on { opacity: 1; }
.guide-card { width: min(100%, 400px); max-height: calc(100dvh - 40px); overflow: auto; display: flex; flex-direction: column; gap: 18px; padding: 18px 22px 22px; border-radius: 26px; background: rgba(28, 28, 32, .78); -webkit-backdrop-filter: blur(50px) saturate(200%); backdrop-filter: blur(50px) saturate(200%); box-shadow: var(--edge), 0 20px 60px rgba(0, 0, 0, .6); transform: translateY(16px) scale(.97); transition: transform .5s var(--spring); }
.guide.on .guide-card { transform: none; }
.guide-top { display: flex; justify-content: space-between; align-items: center; min-height: 28px; }
.guide-dots { display: flex; gap: 6px; }
.guide-dots i { width: 6px; height: 6px; border-radius: 3px; background: var(--label-3); transition: background .3s, width .3s var(--spring); }
.guide-dots i.on { width: 18px; background: #fff; }
.guide-body { display: flex; flex-direction: column; gap: 12px; min-height: 268px; }
.guide-body > * { animation: rise .45s var(--spring) both; }
.guide-body h2 { font: 700 26px/1.2 var(--display); letter-spacing: -.02em; margin: 0; text-wrap: balance; }
.guide-body p { font-size: 16px; line-height: 1.65; color: var(--label-2); }
.guide-art svg { width: 54px; height: 54px; fill: none; stroke: #fff; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; display: block; }
.guide-art .dash { stroke: var(--gold); stroke-dasharray: 3 4.5; }
.guide-langs .chip { font-size: 14px; padding: 6px 12px; -webkit-backdrop-filter: none; backdrop-filter: none; background: rgba(255, 255, 255, .1); }
.guide-langs .chip[aria-pressed="true"] { background: #fff; }

/* the share sheet: a smaller picture, and a grid of places to send the link */
.poster img.small { width: min(58%, 230px); border-radius: 14px; }
/* A chosen chip looks chosen everywhere, sheets included: a white, slightly frosted pill with black lettering, the
   same as the main button. (Inside a sheet the plain-chip fill used to win, leaving black lettering on dark.) */
.chip[aria-pressed="true"], .sheet .chip[aria-pressed="true"], .guide .chip[aria-pressed="true"] { background: rgba(255, 255, 255, .92); color: #000; font-weight: 600; box-shadow: inset 0 0 0 .5px rgba(255, 255, 255, .6), 0 2px 10px rgba(0, 0, 0, .25); -webkit-backdrop-filter: blur(12px) saturate(180%); backdrop-filter: blur(12px) saturate(180%); }
.chip.tier[aria-pressed="true"] { color: #000; }
.share-apps { width: 100%; max-width: 400px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.share-apps .chip { padding: 10px 4px; border-radius: 14px; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ---------- two things that used to flicker ----------
   1. Panels in the page (groups, chips, small buttons) no longer blur what is behind them. A blurred backdrop inside
      content that is sliding in or being scrolled gets painted in the wrong place for a frame, which showed as a
      pale rectangle across the panels. They are plain translucent fills now, and the light of the cover still
      shows through. Frosted glass is kept for what floats above the page: the dock, sheets, menus, the guide.
   2. The pack and the card keep one size whether or not a song is in the dock; they used to shrink the moment a
      song began, which is the moment the card appears. */
:root { --frost: none; --glass: rgba(128, 128, 140, .2); }
.slot, body.has-np .slot { width: min(300px, 70vw, 32vh); }

/* ---------- the dock as one pill that changes width ----------
   Nothing playing: the three tabs, nothing else. A song starts: the pill widens and the song takes the middle,
   between the shelf and the submit tab, with its cover, its name and a play button whose ring is the progress.
   The preview ends: it closes up again. The bar is never taller with a song than without one. */
.dock { width: auto; max-width: calc(100vw - 20px); display: flex; align-items: center; padding: 5px; border-radius: 999px; }
.dock .tabbar { display: contents; }
.dock .tabbar a { order: 1; flex: none; min-width: 0; width: 76px; transition: width .5s var(--spring), background .25s, color .25s, transform .12s ease-out; }
.dock .tabbar a[data-v="share"] { order: 3; margin-left: 0; }
.dock .np { order: 2; flex: none; position: relative; width: 0; min-width: 0; height: 52px; margin: 0; padding: 0; gap: 8px; opacity: 0; overflow: hidden; border-radius: 999px; background: rgba(255, 255, 255, .1); animation: none;
  transition: width .55s var(--spring), margin .55s var(--spring), padding .55s var(--spring), opacity .35s; }
.dock .np.on { width: clamp(150px, calc(100vw - 232px), 250px); margin: 0 4px; padding: 0 7px; opacity: 1; }
body.has-np .dock .tabbar a { width: 60px; }
/* on a phone there is no room for both: while a song is in the dock the tabs are icons only, and the song gets the space */
@media (max-width: 430px) {
  body.has-np .dock .tabbar a { width: 46px; min-height: 52px; justify-content: center; }
  body.has-np .dock .tabbar a span { display: none; }
  .dock .np.on { width: calc(100vw - 20px - 10px - 138px - 8px); }
}
.dock .np .np-cover { width: 38px; height: 38px; border-radius: 50%; }
.dock .np .np-txt .t { font-size: 14px; }
.dock .np .np-txt .s { font-size: 12px; }
.dock .np .c-play { width: 34px; height: 34px; }
.dock .np .np-x, .dock .np .np-line { display: none; }
body.has-np main { padding-bottom: calc(120px + env(safe-area-inset-bottom, 0px)); }
body.has-np .toast { bottom: calc(96px + env(safe-area-inset-bottom, 0px)); }

/* ---------- arrivals by rarity ---------- */
.fx-layer { position: fixed; inset: 0; z-index: 5; pointer-events: none; overflow: hidden; }
.fx-ring { position: absolute; width: var(--rs); height: var(--rs); margin: calc(var(--rs) / -2) 0 0 calc(var(--rs) / -2); border-radius: 50%; border: 2px solid rgba(var(--rc), .9); box-shadow: 0 0 26px rgba(var(--rc), .6), inset 0 0 26px rgba(var(--rc), .35); opacity: 0; animation: fx-ring 1.15s cubic-bezier(.2, .7, .2, 1) both; }
@keyframes fx-ring { 0% { opacity: 0; transform: scale(.22); } 14% { opacity: 1; } 100% { opacity: 0; transform: scale(1); } }
.fx-flash { position: absolute; inset: 0; background: radial-gradient(circle at 50% 42%, rgba(255, 255, 255, .95), rgba(var(--rc), .75) 34%, rgba(var(--rc), 0) 76%); opacity: 0; animation: fx-flash .9s ease-out both; }
@keyframes fx-flash { 0% { opacity: 0; } 12% { opacity: 1; } 100% { opacity: 0; } }
.rays { background: repeating-conic-gradient(from 0deg, rgba(var(--rc, 255, 255, 255), 0) 0 6deg, rgba(var(--rc, 255, 255, 255), .22) 8.5deg, rgba(var(--rc, 255, 255, 255), 0) 11deg 18deg); }
.rays.long { animation: rays-long 7.5s ease-out forwards; }
@keyframes rays-long { 0% { opacity: 0; transform: scale(.5) rotate(0); } 7% { opacity: 1; } 62% { opacity: .8; } 100% { opacity: 0; transform: scale(1.2) rotate(140deg); } }
.aura.gold { filter: blur(90px) saturate(2.2) sepia(.8) hue-rotate(-12deg); }
.aura.gold.on { opacity: .75; }
/* before an epic or a legendary card shows, the rest of the page steps back */
.top, .dock { transition: opacity .5s, max-width .45s var(--spring); }
body.hush .top, body.hush .hud, body.hush .dock { opacity: .08; }
.slot.charging.hard .pk { animation: shake-hard .07s linear infinite; }
@keyframes shake-hard { 0% { translate: calc(-50% - 4px) calc(-50% + 2px); } 33% { translate: calc(-50% + 4px) calc(-50% - 3px); } 66% { translate: calc(-50% - 2px) calc(-50% + 3px); } 100% { translate: calc(-50% + 3px) calc(-50% - 1px); } }
/* the preview buttons that ?fx adds */

/* ---------- a ten-pack's results: rarity as light ----------
   Once a tile has turned over, its card glows in its tier's colour: nothing for common, a faint rim for uncommon,
   stronger for rare and epic, and a gold glow that breathes for as long as a legendary card is on the page. */
.tile .mini .cface { transition: box-shadow .7s .3s; }
.tile.on .mini.v1 .cface { box-shadow: 0 0 0 1px rgba(79, 220, 140, .6), 0 0 14px rgba(79, 220, 140, .3); }
.tile.on .mini.v2 .cface { box-shadow: 0 0 0 1px rgba(77, 166, 255, .8), 0 0 22px rgba(77, 166, 255, .5); }
.tile.on .mini.v3 .cface { box-shadow: 0 0 0 1.5px rgba(182, 132, 255, .95), 0 0 30px rgba(182, 132, 255, .65), 0 0 60px rgba(182, 132, 255, .25); }
.tile.on .mini.v4 .cface { box-shadow: 0 0 0 1.5px rgba(242, 203, 98, .95), 0 0 30px rgba(242, 203, 98, .7); animation: gold-glow 2.6s ease-in-out .9s infinite; }
@keyframes gold-glow { 50% { box-shadow: 0 0 0 1.5px rgba(255, 236, 170, 1), 0 0 48px rgba(255, 214, 110, .95), 0 0 96px rgba(242, 180, 60, .5); } }
.tile.t3, .tile.t4 { z-index: 1; }
/* a card not owned before in this rarity: a small label on the corner, where there used to be a white dot */
.tile.new::after { content: "NEW"; right: -6px; top: -8px; width: auto; height: auto; padding: 3px 6px 2px; border-radius: 99px; background: #fff; color: #000; font: 800 9px/1 var(--display); letter-spacing: .06em; box-shadow: 0 2px 8px rgba(0, 0, 0, .55); }

/* people who ask for less transparency get solid surfaces */
@media (prefers-reduced-transparency: reduce) {
  :root { --glass: #1c1c1e; --glass-2: #2c2c2e; --glass-bar: #1c1c1e; --frost: none; }
  .tabbar, .menu, .toast, .sheet, .np, .meter, .checkin:not(.due), .hud .segctl { -webkit-backdrop-filter: none; backdrop-filter: none; background: #1c1c1e; }
}
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } }

/* ---------- a shelf shown to others ---------- */
.title-row #tally { margin-inline-start: auto; }
.share-shelf { align-self: center; flex: none; }
.guest { width: 100%; display: flex; flex-direction: column; gap: 16px; padding-top: 4px; }
.guest .d-head h2 { font-size: 26px; }
.guest .shelf { grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 16px 12px; padding-top: 0; }
.guest .thumb { position: relative; }
.guest .seg-scroll { flex-wrap: wrap; overflow: visible; margin: 0; padding: 0; -webkit-mask-image: none; mask-image: none; justify-content: center; }
.guest .back { align-self: flex-start; }
.guest .picker { align-self: center; }
.share-link { width: 100%; }
.share-link .cell { font-size: 14px; color: var(--label-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block; }
.share-foot { display: flex; justify-content: space-between; gap: 16px; width: 100%; padding: 0 4px; }
.share-link, .share-foot { width: min(100%, 500px); align-self: center; }
.share-link input { display: block; width: 100%; border: 0; background: none; color: #fff; font: inherit; font-size: 16px; padding: 14px 16px; outline: none; }
.share-link input::placeholder { color: var(--label-3, rgba(235, 235, 245, .3)); }
.share-link .cell { padding: 14px 16px; }
.poster .msg:empty { display: none; }

/* ---------- the shelf's header: count, style menu, play-all, share ---------- */
.shelf-head { align-items: center; gap: 8px; }
.shelf-head h1 { margin-inline-end: 4px; }
.shelf-head #tally { margin-inline-start: 0; margin-inline-end: auto; align-self: baseline; padding-top: 14px; }
.shelf-head .icon-btn { flex: none; color: #fff; }
/* the name of a shared shelf: one plain field */
.share-name { display: block; width: min(100%, 400px); border-radius: 14px; background: var(--glass); box-shadow: var(--edge); }
.share-name input { display: block; width: 100%; box-sizing: border-box; border: 0; background: none; color: #fff; font: inherit; font-size: 16px; text-align: center; padding: 13px 16px; outline: none; border-radius: 14px; }
.share-name input:focus-visible { box-shadow: 0 0 0 2px rgba(255, 255, 255, .5); }
.share-name input::placeholder { color: rgba(235, 235, 245, .38); }
.share-foot { width: min(100%, 400px); padding-top: 6px; }

/* the reminder under every place where people write */
.caption.safe { padding: 0 4px; text-wrap: pretty; }

#shelfNone { padding: 40px 16px; }

/* ---------- one control system ----------
   Every capsule on the site (chips, segmented controls, round buttons, the check-in, favourites) has the same
   edge, the same chosen state and the same press. They are set here, once, after everything else. */
:root { --on-bg: rgba(255, 255, 255, .92); --on-edge: inset 0 0 0 .5px rgba(255, 255, 255, .6), 0 2px 10px rgba(0, 0, 0, .25); --press: .95; }
.segctl { padding: 3px; border-radius: 999px; background: var(--glass); box-shadow: var(--edge); }
.segctl button { min-height: 34px; padding: 0 15px; border-radius: 999px; font-size: 15px; font-weight: 500; color: #fff; transition: background .25s, color .25s, transform .12s ease-out; }
.segctl button[aria-pressed="true"], .hud .segctl button[aria-pressed="true"], .chip[aria-pressed="true"], .checkin.due, .fav.on {
  background: var(--on-bg); color: #000; font-weight: 600; box-shadow: var(--on-edge); }
.icon-btn:active, .chip:active, .fav:active, .checkin:active, .segctl button:active, .hud .segctl button:active, .tabbar a:active, .dock .tabbar a:active, .float-filter:active { transform: scale(var(--press)); }
.icon-btn, .chip, .fav, .checkin, .float-filter { transition: transform .12s ease-out, background .2s, color .2s, opacity .25s; }

/* the shelf: the segmented control at the top, and under it at most one row of chips */
.shelf-seg { align-self: stretch; }
.shelf-seg button { flex: 1 1 0; min-width: 0; padding: 0 8px; overflow: hidden; text-overflow: ellipsis; }
@media (min-width: 700px) { .shelf-seg { align-self: flex-start; min-width: 460px; } }
/* the same choices, floating, once that control has scrolled away */
.float-filter { position: fixed; left: 50%; top: calc(12px + env(safe-area-inset-top, 0px)); z-index: 9; display: inline-flex; align-items: center; gap: 8px; min-height: 40px; padding: 0 18px 0 14px; border: 0; border-radius: 999px; color: #fff; font-size: 15px; font-weight: 500; white-space: nowrap; cursor: pointer;
  background: var(--glass-bar); -webkit-backdrop-filter: blur(34px) saturate(200%); backdrop-filter: blur(34px) saturate(200%); box-shadow: var(--edge), 0 10px 30px rgba(0, 0, 0, .5);
  translate: -50% -18px; opacity: 0; pointer-events: none; transition: translate .5s var(--spring), opacity .25s, transform .12s ease-out; }
.float-filter.on { translate: -50% 0; opacity: 1; pointer-events: auto; }
.float-filter .ic { display: grid; }
.float-filter svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; display: block; }
.filter-sheet { width: 100%; display: flex; flex-direction: column; gap: 14px; }
.filter-sheet .sec { margin: 6px 0 -4px; }
@media (prefers-reduced-motion: reduce) { .float-filter { transition: opacity .2s; translate: -50% 0; } }
@media (prefers-reduced-transparency: reduce) { .float-filter { -webkit-backdrop-filter: none; backdrop-filter: none; background: #1c1c1e; } }

/* ---------- the home page ----------
   One size rule for the pack and the card, taken from the height of the screen: whatever is on the table, the thing
   under it (the pack's controls, or the song's name and "open another") ends above the bottom bar.
   Wider and taller screens get a larger pack, up to 340px. */
.stage { gap: 0; }
.zone { padding: clamp(8px, 4.5vh, 64px) 0 0; }
.slot, body.has-np .slot { width: clamp(170px, calc((96dvh - 300px) / 1.64), min(340px, 70vw)); }
.hud { margin-top: clamp(30px, 7vh, 60px); row-gap: 12px; }
.ten { padding-top: clamp(6px, 3vh, 30px); }
/* the card stands a twentieth of the slot above its lower edge, so the name needs no more room than this */
#drawDetail { margin-top: -8px; }
.d-head { padding: 0 0 2px; }
.d-acts { margin-top: 0; }
.detail .btn.again { margin: 2px 0; }

/* ---------- how things move ----------
   Press is quick; release springs back. Under a mouse, whatever can be pressed answers before it is pressed:
   capsules brighten and grow a little, the white button lifts with a glow, cards rise. Touch screens get none of the
   hover rules, so nothing sticks after a tap. */
.icon-btn, .chip, .fav, .checkin, .btn, .segctl button, .tabbar a, .thumb { transition: transform .5s var(--spring), background .2s, color .2s, opacity .25s, box-shadow .3s; }
.text-btn { transition: color .2s, opacity .2s; }
.cardbox { transition: scale .5s var(--spring); }
.tile .mini { transition: translate .5s var(--spring), scale .5s var(--spring); }
.cell.link, .menu button { transition: background .2s; }
@media (hover: hover) and (pointer: fine) {
  .icon-btn:hover, .chip:not([aria-pressed="true"]):hover, .fav:not(.on):hover, .checkin:not(.due):not(:disabled):hover { background: rgba(150, 150, 164, .36); }
  .icon-btn:hover, .chip:hover, .fav:hover, .checkin:not(:disabled):hover { transform: scale(1.06); }
  .float-filter:hover { background: rgba(58, 58, 64, .78); }
  .segctl button:not([aria-pressed="true"]):hover { background: rgba(255, 255, 255, .1); }
  .tabbar a:not([aria-current="page"]):hover { color: #fff; background: rgba(255, 255, 255, .08); }
  .btn:not(:disabled):hover { transform: scale(1.015); box-shadow: 0 8px 30px rgba(255, 255, 255, .18); }
  .btn.ghost:not(:disabled):hover { background: rgba(255, 255, 255, .2); box-shadow: none; }
  .thumb:hover { transform: translateY(-6px) scale(1.035); }
  .tile.on:hover .mini { translate: 0 -6px; scale: 1.05; }
  .cardbox:hover { scale: 1.03; }
  .cell.link:hover { background: rgba(255, 255, 255, .06); }
  .menu button:hover { background: rgba(255, 255, 255, .09); }
  .text-btn:hover { color: #fff; }
  .text-btn.danger:hover { color: var(--danger); opacity: .8; }
}
/* the press comes after the hover rules, so it wins while the button is held */
.icon-btn:active, .chip:active, .fav:active, .checkin:active, .segctl button:active, .hud .segctl button:active, .tabbar a:active, .dock .tabbar a:active, .float-filter:active { transform: scale(var(--press)); transition-duration: .09s, .2s, .2s, .25s, .3s; }
.btn:active { transform: scale(.97); opacity: .85; transition-duration: .09s, .2s, .2s, .25s, .3s; }
.thumb:active { transform: scale(.96); transition-duration: .09s; }

/* the white pill of a segmented control slides */
.segctl { position: relative; }
.segctl.slides::before { content: ""; position: absolute; top: 3px; bottom: 3px; left: 0; width: var(--sw, 0); transform: translateX(var(--sx, 0)); border-radius: 999px; background: var(--on-bg); box-shadow: var(--on-edge); transition: transform .5s var(--spring), width .5s var(--spring); pointer-events: none; }
.segctl.slides.still::before { transition: none; }
.segctl.slides button { position: relative; }
.segctl.slides button[aria-pressed="true"], .hud .segctl.slides button[aria-pressed="true"] { background: none; box-shadow: none; }

/* arriving */
@keyframes view-in { from { opacity: 0; transform: translateY(10px); } }
@keyframes fade-in { from { opacity: 0; } }
@keyframes pop-in { from { opacity: 0; transform: scale(.9) translateY(-6px); } }
.view:not([hidden]) { animation: view-in .45s var(--spring) both; }
.stage:not([hidden]) { animation: fade-in .35s ease-out both; }
#shelfChips:not([hidden]) { animation: view-in .4s var(--spring) both; }
.menu:not([hidden]) { animation: pop-in .3s var(--spring) both; transform-origin: top right; }

/* on a wide screen the wordmark and the three buttons go to the two edges */
@media (min-width: 900px) { body .top, body[data-view] .top { max-width: none; padding-left: 32px; padding-right: 32px; } }

/* ---------- the home page, structure A ----------
   What you have is at the top: the count of packs and the time to the next one, beside the three buttons.
   What you do is at the bottom: single or ten and the check-in, just above the bar, as one group with it. */
.top { gap: 8px; }
.top .mark { margin-inline-end: auto; }
.top .meter { min-height: 36px; padding: 0 12px 0 7px; gap: 6px; font-size: 14px; flex: none; }
.meter .ring { position: relative; width: 22px; height: 22px; display: grid; place-items: center; flex: none; }
.meter .ring > span:first-child { position: absolute; inset: 0; display: block; }
.meter .ring svg.r { width: 100%; height: 100%; display: block; transform: rotate(-90deg); }
.meter .ring .bg { fill: none; stroke: rgba(255, 255, 255, .16); stroke-width: 2; }
.meter .ring .fg { fill: none; stroke: #fff; stroke-width: 2; stroke-linecap: round; stroke-dasharray: 56.55; stroke-dashoffset: calc(56.55 * (1 - var(--p, 1))); transition: stroke-dashoffset 1s linear; }
.meter .ring .pki { display: grid; }
.meter .ring .pki svg { width: 11px; height: 11px; stroke-width: 2.6; }
.meter .next { font-size: 12.5px; }
@media (max-width: 400px) { .top { gap: 6px; } .top-acts { gap: 6px; } .top .icon-btn { width: 34px; height: 34px; } .top .meter { padding-right: 10px; gap: 5px; } }
.hud { position: fixed; left: 50%; translate: -50% 0; bottom: calc(88px + env(safe-area-inset-bottom, 0px)); z-index: 10; width: max-content; max-width: calc(100vw - 24px); margin: 0; flex-wrap: nowrap; gap: 8px; }
.hud:not([hidden]) { animation: fade-in .35s ease-out both; }
.hud .segctl { background: var(--glass-bar); -webkit-backdrop-filter: blur(34px) saturate(200%); backdrop-filter: blur(34px) saturate(200%); box-shadow: var(--edge), 0 10px 30px rgba(0, 0, 0, .5); }
.hud .checkin { min-height: 40px; background: var(--glass-bar); -webkit-backdrop-filter: blur(34px) saturate(200%); backdrop-filter: blur(34px) saturate(200%); box-shadow: var(--edge), 0 10px 30px rgba(0, 0, 0, .5); }
.hud .checkin.due { background: var(--on-bg); box-shadow: var(--on-edge), 0 10px 30px rgba(0, 0, 0, .5); }
@media (prefers-reduced-transparency: reduce) { .hud .segctl, .hud .checkin:not(.due) { -webkit-backdrop-filter: none; backdrop-filter: none; background: #1c1c1e; } }

/* ---------- messages ----------
   At the top of the screen, under the top bar: nothing else is ever there, whatever is at the bottom. */
.toast, body.has-np .toast { top: calc(60px + env(safe-area-inset-top, 0px)); bottom: auto; display: flex; align-items: center; gap: 11px; width: max-content; max-width: min(calc(100vw - 32px), 440px); padding: 11px 18px; border-radius: 22px; text-align: start; font-size: 15px; line-height: 1.35; box-shadow: var(--edge), 0 12px 36px rgba(0, 0, 0, .55); }
.toast[hidden] { display: none; }
.toast .ok { flex: none; width: 26px; height: 26px; margin-inline-start: -5px; border-radius: 50%; background: #fff; color: #000; display: grid; place-items: center; }
.toast .ok svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; display: block; }
.toast .tx { display: flex; flex-direction: column; min-width: 0; }
.toast .tx b { font-weight: 600; }
.toast .tx b + span { font-size: 13px; color: var(--label-2); }
@keyframes toast { from { opacity: 0; transform: translateY(-14px) scale(.96); } }

/* a phone on its side: the screen is short, so the pack is smaller and its controls stand at the right edge */
@media (max-height: 520px) and (orientation: landscape) {
  .zone { padding-top: 0; }
  .slot, body.has-np .slot { width: clamp(100px, calc((100dvh - 180px) / 1.64), 340px); }
  .hud { left: auto; right: max(16px, env(safe-area-inset-right, 0px)); top: 50%; bottom: auto; translate: 0 -50%; flex-direction: column; align-items: flex-end; }
}
