1 parent
5d57ba5d8f
commit
6c76121863
3 files changed
+40
-61
No files matched your search
+2
-2
@@ -114,7 +114,7 @@ els('.card[data-room]').forEach((node) => {
|
||||
avr: node.classList.contains('avr'),
|
||||
level: el('[data-role="level"]', node),
|
||||
meter: el('[data-role="meter"]', node),
|
||||
actions: el('[data-role="actions"]', node),
|
||||
navigation: el('[data-role="navigation"]', node),
|
||||
toggle: el('[data-role="group"]', node),
|
||||
toggleLabel: el('[data-role="group-label"]', node),
|
||||
prev: el('[data-role="prev"]', node),
|
||||
@@ -188,7 +188,7 @@ function paintTransport(room) {
|
||||
room.play.disabled = !room.available || !state;
|
||||
room.play.setAttribute(
|
||||
'aria-label', `${room.node.querySelector('h2').textContent}: ${playing ? 'pause' : 'play'}`);
|
||||
room.actions.hidden = room.avr
|
||||
room.navigation.hidden = room.avr
|
||||
? !state
|
||||
: !(room.onSpotify && room.spotifyAccount && !room.grouped);
|
||||
if (room.prev) room.prev.disabled = !room.available;
|
||||
|
||||
+35
-56
@@ -108,16 +108,14 @@ button {
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
border: 0;
|
||||
background: none;
|
||||
background: var(--raised);
|
||||
border-radius: var(--radius-lg);
|
||||
cursor: pointer;
|
||||
touch-action: manipulation;
|
||||
box-shadow: var(--lift);
|
||||
}
|
||||
button:active { transform: scale(.96); }
|
||||
button[aria-pressed="true"], button[aria-current="true"] { box-shadow: none; }
|
||||
|
||||
/* For a keyboard, including the one on an iPad, and VoiceOver's cursor. */
|
||||
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
||||
button[aria-pressed="true"], button[aria-current="true"] { background: var(--accent); color: var(--ink-bright); box-shadow: none; }
|
||||
|
||||
svg { width: 22px; height: 22px; fill: currentColor; }
|
||||
|
||||
@@ -132,7 +130,7 @@ svg { width: 22px; height: 22px; fill: currentColor; }
|
||||
}
|
||||
|
||||
.wide { width: 100%; min-height: 50px; border-radius: var(--radius-lg); font-size: var(--text-sm); }
|
||||
.ghost { background: transparent; border: 1px solid var(--outline); color: var(--muted); box-shadow: none; } /* nothing to lift */
|
||||
.ghost { background: transparent; border: 1px solid var(--outline); color: var(--muted); box-shadow: none; }
|
||||
|
||||
@keyframes spin { to { transform: rotate(360deg); } }
|
||||
@keyframes rise { from { transform: translateY(100%); opacity: .4; } }
|
||||
@@ -161,6 +159,8 @@ header .logo { height: 44px; width: auto; display: block; margin: var(--space-xs
|
||||
background: linear-gradient(135deg, var(--playing) 0%, var(--card) 70%);
|
||||
}
|
||||
|
||||
/* Card - Header */
|
||||
|
||||
.card-head { display: flex; align-items: center; justify-content: center; gap: var(--space-md); }
|
||||
.card-head h2 {
|
||||
display: flex; align-items: center; gap: var(--space-md);
|
||||
@@ -196,6 +196,7 @@ header .logo { height: 44px; width: auto; display: block; margin: var(--space-xs
|
||||
.track span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.song { font-size: var(--text-md); font-weight: 600; }
|
||||
.artist { font-size: var(--text-sm); color: var(--muted); }
|
||||
|
||||
.progress { display: flex; align-items: center; gap: var(--space-md); }
|
||||
.progress-line { position: relative; flex: 1; height: 3px; border-radius: 2px; background: var(--muted); }
|
||||
.progress-fill {
|
||||
@@ -212,8 +213,7 @@ header .logo { height: 44px; width: auto; display: block; margin: var(--space-xs
|
||||
transform: translateY(-50%);
|
||||
transition: left .12s ease-out;
|
||||
}
|
||||
.progress-time,
|
||||
.progress-total {
|
||||
.progress-time, .progress-total {
|
||||
display: none;
|
||||
font-size: var(--text-xs); line-height: 1; color: var(--muted);
|
||||
font-variant-numeric: tabular-nums; white-space: nowrap;
|
||||
@@ -226,34 +226,30 @@ header .logo { height: 44px; width: auto; display: block; margin: var(--space-xs
|
||||
}
|
||||
.progress-time.elapsed { bottom: 9px; }
|
||||
.progress-time.remaining { top: 9px; }
|
||||
/* Room for the labels above and below the cursor: what they need at 13px,
|
||||
plus whatever a larger Dynamic Type size adds to them. */
|
||||
.progress.known { padding: calc(var(--space-md) + max(0px, var(--text-xs) - 13px)) 0; }
|
||||
.progress.known .progress-cursor,
|
||||
.progress.known .progress-time,
|
||||
.progress.known .progress-total { display: block; }
|
||||
.progress.seekable .progress-cursor,
|
||||
.progress.seekable .progress-time { cursor: grab; touch-action: pan-y; }
|
||||
/* The cursor is 7px; this grows what a finger can grab to the 44pt Apple asks for. */
|
||||
.progress.seekable .progress-cursor::before { content: ''; position: absolute; inset: -19px; }
|
||||
.progress.dragging .progress-cursor,
|
||||
.progress.dragging .progress-time { transition: none; cursor: grabbing; }
|
||||
.progress.dragging .progress-cursor { background: var(--ink); transform: translateY(-50%) scale(1.6); }
|
||||
.progress.dragging .progress-time { color: var(--ink); }
|
||||
.progress.dragging .progress-cursor { transition: none; cursor: grabbing; background: var(--ink); transform: translateY(-50%) scale(1.6); }
|
||||
.progress.dragging .progress-time { transition: none; cursor: grabbing; color: var(--ink); }
|
||||
|
||||
/* Card - Volume */
|
||||
/* Card - Volume & Navigation */
|
||||
|
||||
.volume { display: flex; align-items: center; gap: var(--space-md); }
|
||||
.navigation { display: flex; align-items: stretch; justify-content: center; gap: var(--space-md); }
|
||||
|
||||
.control-btn {
|
||||
flex: 0 0 auto;
|
||||
width: 72px; height: 62px;
|
||||
border-radius: var(--radius-lg);
|
||||
background: var(--raised);
|
||||
width: 62px; height: 62px;
|
||||
display: grid; place-items: center;
|
||||
}
|
||||
.control-btn svg { width: 20px; height: 20px; }
|
||||
.control-btn:disabled { opacity: .5; }
|
||||
.control-btn .icon-pause { display: none; }
|
||||
.control-btn.playing .icon-play { display: none; }
|
||||
.control-btn.playing .icon-pause { display: block; }
|
||||
|
||||
.meter { position: relative; flex: 1; height: 8px; border-radius: 4px; background: var(--track); }
|
||||
.meter i {
|
||||
@@ -261,6 +257,9 @@ header .logo { height: 44px; width: auto; display: block; margin: var(--space-xs
|
||||
border-radius: 999px; background: var(--accent);
|
||||
transition: width .12s ease-out;
|
||||
}
|
||||
.meter.dragging i,
|
||||
.meter.dragging .knob { transition: none; }
|
||||
.meter.dragging .knob { cursor: grabbing; transform: translateY(-50%) scale(1.12); }
|
||||
|
||||
.knob {
|
||||
position: absolute; top: 50%;
|
||||
@@ -283,54 +282,36 @@ header .logo { height: 44px; width: auto; display: block; margin: var(--space-xs
|
||||
position: absolute;
|
||||
inset: calc(var(--space-md) * -1) calc(var(--space-sm) * -1);
|
||||
}
|
||||
.meter.dragging i,
|
||||
.meter.dragging .knob { transition: none; }
|
||||
.meter.dragging .knob { cursor: grabbing; transform: translateY(-50%) scale(1.12); }
|
||||
|
||||
/* Card - Navigation */
|
||||
|
||||
.actions { display: flex; align-items: stretch; justify-content: center; gap: var(--space-md); }
|
||||
|
||||
.control-btn .icon-pause { display: none; }
|
||||
.control-btn.playing .icon-play { display: none; }
|
||||
.control-btn.playing .icon-pause { display: block; }
|
||||
|
||||
/* Card - Sources */
|
||||
|
||||
.sources { display: flex; gap: var(--space-md); }
|
||||
.sources-btn {
|
||||
|
||||
.source-btn {
|
||||
flex: 1; min-width: 0;
|
||||
min-height: 50px; border-radius: var(--radius-lg);
|
||||
background: var(--raised);
|
||||
min-height: 50px;
|
||||
display: flex; align-items: center; justify-content: center; gap: var(--space-sm);
|
||||
font-size: var(--text-sm); font-weight: 600;
|
||||
}
|
||||
.sources-btn:disabled { opacity: .5; }
|
||||
.sources-btn svg { flex: 0 0 auto; }
|
||||
.sources-btn span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.sources-btn .spinner { display: none; }
|
||||
button.sources-btn.loading .icon { display: none; }
|
||||
.sources-btn.loading .spinner { display: block; animation: spin 1s steps(8) infinite; }
|
||||
|
||||
.spotify[aria-pressed="true"] { border: 2px solid var(--ink); }
|
||||
.source-btn:disabled { opacity: .5; }
|
||||
.source-btn svg { flex: 0 0 auto; }
|
||||
.source-btn span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.source-btn .spinner { display: none; }
|
||||
.source-btn.loading .icon { display: none; }
|
||||
.source-btn.loading .spinner { display: block; animation: spin 1s steps(8) infinite; }
|
||||
|
||||
.toggle .leave { display: none; }
|
||||
.toggle[aria-pressed="true"] { background: var(--accent); color: var(--ink-bright); }
|
||||
|
||||
/* AVR */
|
||||
|
||||
/* AVR - Input */
|
||||
/* Card - AVR Input */
|
||||
|
||||
.input-select {
|
||||
display: flex; align-items: center; gap: var(--space-md);
|
||||
width: 100%; min-height: 50px;
|
||||
padding: var(--space-md) var(--space-md);
|
||||
border-radius: var(--radius-lg);
|
||||
background: var(--raised);
|
||||
padding: var(--space-md);
|
||||
text-align: left;
|
||||
}
|
||||
.input-select .eyebrow { font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }
|
||||
.input-select [data-role="input-icon"] { flex: 0 0 auto; height: 18px; width: 18px; fill: currentColor; color: var(--muted); }
|
||||
.input-select .eyebrow { font-size: var(--text-2xs); text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }
|
||||
.input-select .value { flex: 1; font-size: var(--text-lg); font-weight: 600; }
|
||||
.input-select .chevron { color: var(--muted); }
|
||||
|
||||
@@ -351,15 +332,13 @@ button.sources-btn.loading .icon { display: none; }
|
||||
.grabber { width: 38px; height: 4px; border-radius: 999px; background: var(--outline); margin: var(--space-xs) auto var(--space-xs); }
|
||||
.sheet h3 { margin: 0 var(--space-xs); font-size: var(--text-xs); font-weight: 600; color: var(--muted); }
|
||||
|
||||
.options { display: flex; flex-direction: column; gap: var(--space-sm); overflow-y: auto; -webkit-overflow-scrolling: touch; }
|
||||
.options { display: flex; flex-direction: column; gap: var(--space-sm); }
|
||||
.option {
|
||||
display: flex; align-items: center; justify-content: space-between; gap: var(--space-md);
|
||||
min-height: 58px; padding: 0 var(--space-md);
|
||||
border-radius: var(--radius-lg); background: var(--raised);
|
||||
border-radius: var(--radius-lg);
|
||||
font-size: var(--text-md); text-align: left;
|
||||
}
|
||||
.option[aria-current="true"] { background: var(--accent); color: var(--ink-bright); }
|
||||
.option[aria-current="true"]:focus-visible { outline: none; }
|
||||
.option[aria-current="true"] .option-label svg { color: var(--ink-bright); }
|
||||
.option[aria-current="true"] .code { color: var(--ink-bright); }
|
||||
.option-label { display: flex; align-items: center; gap: var(--space-md); min-width: 0; overflow: hidden; }
|
||||
@@ -367,7 +346,7 @@ button.sources-btn.loading .icon { display: none; }
|
||||
.option-label span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.option .code { font-size: var(--text-xs); color: var(--muted); flex: 0 0 auto; }
|
||||
|
||||
/* AVR - Grouped Room */
|
||||
/* Card - AVR Grouped Room */
|
||||
|
||||
.joined { display: flex; flex-direction: column; gap: var(--space-md); }
|
||||
.joined .card.room { background: none; border-color: var(--ink); border-radius: var(--radius-lg); padding: var(--space-md); gap: var(--space-md); }
|
||||
@@ -394,4 +373,4 @@ footer.bad { color: var(--warn); }
|
||||
background: var(--toast-bad-bg); border: 1px solid var(--toast-bad-edge); color: var(--toast-bad-ink);
|
||||
font-size: var(--text-sm); box-shadow: 0 10px 30px var(--shadow);
|
||||
}
|
||||
.toast.ok { background: var(--toast-ok-bg); border-color: var(--toast-ok-edge); color: var(--toast-ok-ink); }
|
||||
.toast.ok { background: var(--toast-ok-bg); border-color: var(--toast-ok-edge); color: var(--toast-ok-ink); }
|
||||
@@ -33,7 +33,7 @@
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro host_toggle() -%}
|
||||
<button class="sources-btn toggle" data-role="group" aria-pressed="false">
|
||||
<button class="source-btn toggle" data-role="group" aria-pressed="false">
|
||||
<svg class="cinema icon" viewBox="0 0 512 512" aria-hidden="true"><path d="M256 512a256 256 0 1 0 0-512 256 256 0 1 0 0 512zM128 192c0-17.7 14.3-32 32-32l128 0c17.7 0 32 14.3 32 32l0 38.4 61-36.6c1.9-1.2 4.2-1.8 6.4-1.8 6.9 0 12.5 5.6 12.5 12.5l0 102.9c0 6.9-5.6 12.5-12.5 12.5-2.3 0-4.5-.6-6.4-1.8l-61-36.6 0 38.4c0 17.7-14.3 32-32 32l-128 0c-17.7 0-32-14.3-32-32l0-128z"/></svg>
|
||||
<svg class="leave icon" viewBox="0 0 512 512" aria-hidden="true"><path d="M502.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-128-128c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L402.7 224 192 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l210.7 0-73.4 73.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l128-128zM160 96c17.7 0 32-14.3 32-32s-14.3-32-32-32L96 32C43 32 0 75 0 128L0 384c0 53 43 96 96 96l64 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-64 0c-17.7 0-32-14.3-32-32l0-256c0-17.7 14.3-32 32-32l64 0z"/></svg>
|
||||
<svg class="spinner" viewBox="0 0 512 512" aria-hidden="true"><path d="M208 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm0 416a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM48 208a48 48 0 1 1 0 96 48 48 0 1 1 0-96zm368 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM75 369.1A48 48 0 1 1 142.9 437 48 48 0 1 1 75 369.1zM75 75A48 48 0 1 1 142.9 142.9 48 48 0 1 1 75 75zM437 369.1A48 48 0 1 1 369.1 437 48 48 0 1 1 437 369.1z"/></svg>
|
||||
@@ -47,7 +47,7 @@
|
||||
<div class="sources">
|
||||
{% for account in accounts %}
|
||||
{% if loop.index0 == split %}{{ host_toggle() }}{% endif %}
|
||||
<button class="sources-btn spotify" data-target="{{ target }}" data-account="{{ account.key }}"
|
||||
<button class="source-btn spotify" data-target="{{ target }}" data-account="{{ account.key }}"
|
||||
aria-label="Resume {{ account.label }}'s Spotify" hidden>
|
||||
<svg class="brand icon" viewBox="0 0 496 512" aria-hidden="true"><path d="M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm100.7 364.9c-4.2 0-6.8-1.3-10.7-3.6-62.4-37.6-135-39.2-206.7-24.5-3.9 1-9 2.6-11.9 2.6-9.7 0-15.8-7.7-15.8-15.8 0-10.3 6.1-15.2 13.6-16.8 81.9-18.1 165.6-16.5 237 26.2 6.1 3.9 9.7 7.4 9.7 16.5s-7.1 15.4-15.2 15.4zm26.9-65.6c-5.2 0-8.7-2.3-12.3-4.2-62.5-37-155.7-51.9-238.6-29.4-4.8 1.3-7.4 2.6-11.9 2.6-10.7 0-19.4-8.7-19.4-19.4s5.2-17.8 15.5-20.7c27.8-7.8 56.2-13.6 97.8-13.6 64.9 0 127.6 16.1 177 45.5 8.1 4.8 11.3 11 11.3 19.7-.1 10.8-8.5 19.5-19.4 19.5zm31-76.2c-5.2 0-8.4-1.3-12.9-3.9-71.2-42.5-198.5-52.7-280.9-29.7-3.6 1-8.1 2.6-12.9 2.6-13.2 0-23.3-10.3-23.3-23.6 0-13.6 8.4-21.3 17.4-23.9 35.2-10.3 74.6-15.2 117.5-15.2 73 0 149.5 15.2 205.4 47.8 7.8 4.5 12.9 10.7 12.9 22.6 0 13.6-11 23.3-23.2 23.3z"/></svg>
|
||||
<svg class="spinner" viewBox="0 0 512 512" aria-hidden="true"><path d="M208 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm0 416a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM48 208a48 48 0 1 1 0 96 48 48 0 1 1 0-96zm368 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM75 369.1A48 48 0 1 1 142.9 437 48 48 0 1 1 75 369.1zM75 75A48 48 0 1 1 142.9 142.9 48 48 0 1 1 75 75zM437 369.1A48 48 0 1 1 369.1 437 48 48 0 1 1 437 369.1z"/></svg>
|
||||
@@ -95,7 +95,7 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="actions" data-role="actions" hidden>
|
||||
<div class="navigation" data-role="navigation" hidden>
|
||||
{% if not avr %}
|
||||
<button class="control-btn" data-role="prev" aria-label="{{ room.label }}: previous track">
|
||||
<svg viewBox="0 0 320 512" aria-hidden="true"><path transform="matrix(-1 0 0 1 320 0)" d="M52.5 440.6c-9.5 7.9-22.8 9.7-34.1 4.4S0 428.4 0 416L0 96C0 83.6 7.2 72.3 18.4 67s24.5-3.6 34.1 4.4l192 160L256 241l0-145c0-17.7 14.3-32 32-32s32 14.3 32 32l0 320c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-145-11.5 9.6-192 160z"/></svg>
|
||||
|
||||
Reference in new issue
Block a user