Layout: dock the set-list panel beside the metronome (push, not overlay)

- App is now a flex shell (#app): the set-list panel docks as a sticky side
  column that pushes the metronome instead of floating over it.
- Collapses via the header 'Set Lists' toggle; falls back to an overlay drawer
  below 820px. Defaults open on desktop, closed on mobile.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Me Here 2026-05-24 17:17:44 -05:00
parent c087f11637
commit c0b6628488

View file

@ -47,7 +47,8 @@
h1 { font-size:18px; font-weight:600; letter-spacing:.5px; margin:0 0 2px; } h1 { font-size:18px; font-weight:600; letter-spacing:.5px; margin:0 0 2px; }
.sub { color:var(--muted); font-size:12px; margin-bottom:18px; } .sub { color:var(--muted); font-size:12px; margin-bottom:18px; }
.kbd-legend { color:var(--muted); font-size:11px; font-family:"Courier New",monospace; text-align:right; } .kbd-legend { color:var(--muted); font-size:11px; font-family:"Courier New",monospace; text-align:right; }
.device { max-width:1000px; margin:0 auto; background:linear-gradient(180deg, var(--panel), var(--bg)); #app { display:flex; gap:18px; max-width:1400px; margin:0 auto; align-items:flex-start; justify-content:center; }
.device { flex:1 1 auto; min-width:0; max-width:1000px; background:linear-gradient(180deg, var(--panel), var(--bg));
border:1px solid var(--edge); border-radius:16px; padding:18px; box-shadow:0 18px 50px rgba(0,0,0,.5); } border:1px solid var(--edge); border-radius:16px; padding:18px; box-shadow:0 18px 50px rgba(0,0,0,.5); }
.row { display:flex; gap:18px; flex-wrap:wrap; } .row { display:flex; gap:18px; flex-wrap:wrap; }
.card { background:var(--panel-2); border:1px solid var(--edge); border-radius:12px; padding:13px; flex:1; min-width:240px; } .card { background:var(--panel-2); border:1px solid var(--edge); border-radius:12px; padding:13px; flex:1; min-width:240px; }
@ -104,9 +105,18 @@
.log-head { font-weight:600; font-size:13px; margin-bottom:3px; } .log-head { font-weight:600; font-size:13px; margin-bottom:3px; }
.log-seg { font-size:12px; color:var(--muted); margin:2px 0 0 12px; font-family:"Courier New",monospace; } .log-seg { font-size:12px; color:var(--muted); margin:2px 0 0 12px; font-family:"Courier New",monospace; }
.practice { border-top:1px solid var(--edge); margin-top:16px; padding-top:4px; } .practice { border-top:1px solid var(--edge); margin-top:16px; padding-top:4px; }
#routineToggle { position:fixed; top:16px; right:16px; z-index:40; background:#2c3a4d; border-color:#3b5168; color:#cfe3ff; font-weight:600; } #routineToggle { background:#2c3a4d; border-color:#3b5168; color:#cfe3ff; font-weight:600; }
#routineTray { position:fixed; top:0; right:0; height:100%; width:380px; max-width:92vw; background:linear-gradient(180deg, var(--panel), var(--bg)); border-left:1px solid var(--edge); box-shadow:-12px 0 40px rgba(0,0,0,.45); transform:translateX(102%); transition:transform .25s ease; z-index:60; padding:18px; overflow:auto; } /* docked side panel: pushes the metronome (no overlap); sticky so it stays in view */
#routineTray.open { transform:translateX(0); } #routineTray { display:none; flex:0 0 340px; align-self:flex-start; position:sticky; top:18px;
max-height:calc(100vh - 36px); overflow:auto; background:linear-gradient(180deg, var(--panel), var(--bg));
border:1px solid var(--edge); border-radius:14px; padding:16px; box-shadow:0 10px 30px rgba(0,0,0,.25); }
#routineTray.open { display:block; }
/* narrow screens: fall back to an overlay drawer */
@media (max-width: 820px) {
#app { display:block; }
#routineTray { position:fixed; top:0; right:0; height:100%; max-height:none; width:min(360px,92vw);
border-radius:0; border:none; border-left:1px solid var(--edge); box-shadow:-12px 0 40px rgba(0,0,0,.45); z-index:60; }
}
.tray-head { display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; } .tray-head { display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; }
.practice-col { border-left:1px solid var(--edge); padding-left:18px; } .practice-col { border-left:1px solid var(--edge); padding-left:18px; }
#themeBtn, #helpBtn { padding:4px 11px; } #themeBtn, #helpBtn { padding:4px 11px; }
@ -142,11 +152,13 @@
</style> </style>
</head> </head>
<body> <body>
<div id="app">
<div class="device"> <div class="device">
<div class="row" style="align-items:baseline; justify-content:space-between; gap:14px; margin-bottom:12px"> <div class="row" style="align-items:baseline; justify-content:space-between; gap:14px; margin-bottom:12px">
<h1 style="margin:0">Stackable Metronome <span class="lane-meta" id="appVersion" title="build version">v0.0.1-dev</span></h1> <h1 style="margin:0">Stackable Metronome <span class="lane-meta" id="appVersion" title="build version">v0.0.1-dev</span></h1>
<div style="display:flex; align-items:center; gap:10px"> <div style="display:flex; align-items:center; gap:10px">
<span class="kbd-legend">Space play · T tap · ↑↓ tempo (⇧×10) · A add · R set&nbsp;lists · N next · ? help</span> <span class="kbd-legend">Space play · T tap · ↑↓ tempo (⇧×10) · A add · R set&nbsp;lists · N next · ? help</span>
<button id="routineToggle" title="show / hide set lists (R)">☰ Set Lists</button>
<button id="themeBtn" title="toggle light / dark theme"></button> <button id="themeBtn" title="toggle light / dark theme"></button>
<button id="helpBtn" title="keyboard shortcuts (?)">?</button> <button id="helpBtn" title="keyboard shortcuts (?)">?</button>
</div> </div>
@ -206,8 +218,7 @@
<div class="sub" id="statusLine">Stopped.</div> <div class="sub" id="statusLine">Stopped.</div>
</div> </div>
<!-- Routine slide-out tray (from the right) --> <!-- Set-list panel: docked beside the metronome; drawer on narrow screens -->
<button id="routineToggle">☰ Routine &amp; Log</button>
<aside id="routineTray"> <aside id="routineTray">
<div class="tray-head"> <div class="tray-head">
<h2 style="margin:0">Set Lists</h2> <h2 style="margin:0">Set Lists</h2>
@ -242,6 +253,7 @@
<div id="logView" style="margin-top:18px"></div> <div id="logView" style="margin-top:18px"></div>
</aside> </aside>
</div><!-- /#app -->
<div id="shortcutsOverlay" class="overlay" hidden> <div id="shortcutsOverlay" class="overlay" hidden>
<div class="overlay-box"> <div class="overlay-box">
@ -889,6 +901,7 @@ renderSetlists();
renderLog(); renderLog();
updateCtx(); updateCtx();
$("appVersion").textContent = "v" + APP_VERSION; $("appVersion").textContent = "v" + APP_VERSION;
if (window.innerWidth > 820) $("routineTray").classList.add("open"); // docked-open on desktop, closed on mobile
requestAnimationFrame(drawLoop); requestAnimationFrame(drawLoop);
</script> </script>
</body> </body>