Files
heos/static/panel.css
T
franzzandClaude Opus 5 a1fb7a318a Stop the input sheet covering the whole panel
`hidden` is only a UA stylesheet rule, so .sheet-wrap's display:flex beat
it and the sheet was never hidden: a full-screen scrim sat over the app
from the moment it loaded, blurring it and swallowing every tap, with an
empty option list because openSheet() had never run to fill it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 21:30:41 +02:00

201 lines
7.1 KiB
CSS

/* A remote lives in the dark next to a TV, so the panel is dark too --
and every control is sized for a thumb, not a cursor. */
:root {
color-scheme: dark;
--bg: #0a0d14;
--card: #151a25;
--edge: #232b3b;
--raised: #1e2634;
--ink: #eef2f9;
--muted: #8d98ad;
--accent: #5b8def;
--live: #3ddc97;
--warn: #ff7a6b;
--radius: 22px;
}
* { box-sizing: border-box; }
/* Must beat every display rule below it. `hidden` is a plain UA style, so
any author rule -- .sheet-wrap's display:flex, say -- silently wins, and
an overlay that never hides sits over the whole panel eating taps. */
[hidden] { display: none !important; }
html { background: var(--bg); }
body {
margin: 0;
background: var(--bg);
color: var(--ink);
font: 16px/1.4 -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", system-ui, sans-serif;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
user-select: none;
overscroll-behavior-y: contain;
}
button {
font: inherit;
color: inherit;
border: 0;
background: none;
cursor: pointer;
touch-action: manipulation;
}
svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.app {
max-width: 520px;
margin: 0 auto;
padding: max(12px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right))
max(24px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
display: flex;
flex-direction: column;
gap: 14px;
}
/* --- header ---------------------------------------------------------- */
.top { display: flex; align-items: center; justify-content: space-between; padding: 6px 4px 0; }
.top h1 { margin: 0; font-size: 22px; font-weight: 650; letter-spacing: .02em; }
.icon-button {
width: 44px; height: 44px; border-radius: 50%;
display: grid; place-items: center;
color: var(--muted); background: var(--card);
}
.icon-button:active { background: var(--raised); color: var(--ink); }
.icon-button.spin svg { animation: spin .7s linear; }
@keyframes spin { to { transform: rotate(360deg); } }
/* --- cards ----------------------------------------------------------- */
.card {
background: var(--card);
border: 1px solid var(--edge);
border-radius: var(--radius);
padding: 16px;
display: flex;
flex-direction: column;
gap: 14px;
}
.card.offline { opacity: .5; }
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.card-head h2 { margin: 0; font-size: 17px; font-weight: 600; }
.level { color: var(--muted); font-size: 13px; }
.level b {
color: var(--ink);
font-size: 26px;
font-weight: 640;
font-variant-numeric: tabular-nums;
}
.pill {
font-size: 11px; text-transform: uppercase; letter-spacing: .08em;
color: var(--muted); background: var(--raised);
padding: 4px 9px; border-radius: 999px;
}
.pill.on { color: var(--live); }
/* --- volume ---------------------------------------------------------- */
.volume { display: flex; align-items: center; gap: 14px; }
.step {
flex: 0 0 auto;
width: 78px; height: 62px;
border-radius: 18px;
background: var(--raised);
font-size: 30px; font-weight: 500; line-height: 1;
display: grid; place-items: center;
}
.step:active { background: var(--accent); transform: scale(.96); }
.step:disabled { opacity: .4; }
.meter { flex: 1; height: 8px; border-radius: 999px; background: #0c111b; overflow: hidden; }
.meter i { display: block; height: 100%; width: 0; border-radius: 999px; background: var(--accent); transition: width .12s ease-out; }
/* --- join / leave the AVR -------------------------------------------- */
.toggle {
height: 52px; border-radius: 16px;
background: var(--raised);
display: flex; align-items: center; justify-content: center; gap: 10px;
font-size: 15px; font-weight: 550;
color: var(--muted);
}
.toggle .dot { width: 9px; height: 9px; border-radius: 50%; background: currentColor; opacity: .6; }
.toggle[aria-pressed="true"] { background: var(--accent); color: #fff; }
.toggle[aria-pressed="true"] .dot { background: #fff; opacity: 1; }
.toggle:active { transform: scale(.985); }
.toggle:disabled { opacity: .5; }
.toggle.busy { opacity: .6; }
/* --- source card ------------------------------------------------------ */
.source-button {
display: flex; align-items: center; gap: 12px;
width: 100%; min-height: 64px;
padding: 10px 14px;
border-radius: 16px;
background: var(--raised);
text-align: left;
}
.source-button:active { transform: scale(.985); }
.source-button .eyebrow { font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }
.source-button .value { flex: 1; font-size: 19px; font-weight: 600; }
.source-button .chevron { color: var(--muted); }
/* --- misc ------------------------------------------------------------- */
.wide { width: 100%; height: 50px; border-radius: 16px; font-size: 15px; }
.ghost { background: transparent; border: 1px solid var(--edge); color: var(--muted); }
.ghost:active { background: var(--card); color: var(--ink); }
.foot { margin: 2px 4px 0; min-height: 18px; font-size: 12px; color: var(--muted); text-align: center; }
.foot.bad { color: var(--warn); }
/* --- input sheet ------------------------------------------------------ */
.sheet-wrap { position: fixed; inset: 0; z-index: 10; display: flex; flex-direction: column; justify-content: flex-end; }
.scrim { position: absolute; inset: 0; background: rgba(4, 6, 11, .6); backdrop-filter: blur(3px); }
.sheet {
position: relative;
background: var(--card);
border: 1px solid var(--edge);
border-radius: 28px 28px 0 0;
padding: 10px 16px calc(16px + env(safe-area-inset-bottom));
max-height: 82vh;
display: flex; flex-direction: column; gap: 12px;
animation: rise .22s cubic-bezier(.22, .68, .3, 1);
}
@keyframes rise { from { transform: translateY(14%); opacity: .4; } }
.grabber { width: 38px; height: 4px; border-radius: 999px; background: var(--edge); margin: 2px auto 4px; }
.sheet h3 { margin: 0 4px; font-size: 14px; font-weight: 600; color: var(--muted); }
.options { display: flex; flex-direction: column; gap: 8px; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.option {
display: flex; align-items: center; justify-content: space-between; gap: 10px;
min-height: 58px; padding: 0 16px;
border-radius: 16px; background: var(--raised);
font-size: 17px; text-align: left;
}
.option:active { transform: scale(.985); }
.option[aria-current="true"] { background: var(--accent); color: #fff; }
.option .code { font-size: 12px; color: var(--muted); }
.option[aria-current="true"] .code { color: rgba(255, 255, 255, .8); }
/* --- toast ------------------------------------------------------------ */
.toast {
position: fixed; left: 50%; transform: translateX(-50%);
bottom: calc(22px + env(safe-area-inset-bottom));
z-index: 20; max-width: 90vw;
padding: 12px 16px; border-radius: 14px;
background: #2b1f24; border: 1px solid #52303a; color: #ffd9d4;
font-size: 14px; box-shadow: 0 10px 30px rgba(0, 0, 0, .45);
}
@media (prefers-reduced-motion: reduce) {
* { animation: none !important; transition: none !important; }
}