tray apparatus scales w. fluid rem; sig-select 9×2 middling breakpoint — $handle-exposed was 48px fixed while #id_tray_btn is 3rem, so on big-rem viewports (clamp(14px, 2.4vmin, 22px) → up to 22px on tall screens, btn=66) the btn's flex parent (#id_tray_handle) shrank the btn from 66×66 → 48×66 via default flex-shrink:1 in portrait (elongated tall ellipse), and in landscape the btn overflowed the 48px-tall handle vertically (extending 9px past viewport top in closed state); fix: $handle-exposed: 3rem matches the btn so it fills the exposed area at every rem; $handle-rect-h: 4.5rem (was 72px) gives the visible rail thickness a touch of breathing room around the btn at every scale; landscape rules in the same partial that hard-coded 48px / 72px (#id_tray_handle { height: 48px }, #id_tray_grip { bottom: calc(48px/2 - 0.125rem); width: 72px }) now reference the variables so they track in sync — tray.js _computeBounds() swapped from _btn.offsetWidth/Height → _handle.offsetWidth/Height for the same reason: even with the SCSS fix, measuring the btn would re-introduce the offset when btn and handle drift (which they shouldn't now, but the handle is the layout-defining element so measure it directly); id_kit_btn added as fallback for id_gear_btn (which no longer renders on the room page) so the open-state landscape wrap height anchors to the bottom-right kit btn instead of the full viewport — id_tray_handle cached on the module via _handle ref alongside _btn and cleared in reset() ; sig-select grid jumped straight from 6 cols (narrow landscape) → 18 cols × 3rem at min-width: 900px, but 18×3rem + 7rem modal margins needs ~1376px to clear at rem=22 so the cards spilled off the sides on common 1280-wide laptops + the previous-era 9×2 middling layout had simply been dropped; new cascade in _card-deck.scss mirrors the comment's documented intent: 6 cols default landscape (row layout, stage beside grid) → 9 cols × 3rem at min-width: 900px (column layout, stage above grid) → 18 cols × 3rem at min-width: 1400px → 18 × 5rem at min-width: 1800px (unchanged) — verified in Claudezilla across iphone-14 portrait (rem=14, btn=42 square, handle right edge at viewport right), 816×826 portrait near-landscape (rem=19.6, btn=58.75 square no longer elongated), 1149×751 landscape mid (rem=18, btn=54 square at viewport top, 9×2 grid), 1789×1111 desktop XL (rem=22, btn=66 square at viewport top, 18×1 grid)
Code architected by Disco DeDisco <discodedisco@outlook.com> Git commit message Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,10 +9,11 @@ var Tray = (function () {
|
||||
var _dragStartTop = null;
|
||||
var _dragHandled = false;
|
||||
|
||||
var _wrap = null;
|
||||
var _btn = null;
|
||||
var _tray = null;
|
||||
var _grid = null;
|
||||
var _wrap = null;
|
||||
var _handle = null;
|
||||
var _btn = null;
|
||||
var _tray = null;
|
||||
var _grid = null;
|
||||
|
||||
// Role code → scrawl SVG name mapping for tray card display.
|
||||
var _ROLE_SCRAWL = {
|
||||
@@ -99,12 +100,20 @@ var Tray = (function () {
|
||||
// meets the gear button when open. Tray is flex:1 and fills the rest.
|
||||
// Open: wrap top = 0 (pinned to viewport top).
|
||||
// Closed: wrap top = -(gearBtnTop - handleH) = tray fully above viewport.
|
||||
var gearBtn = document.getElementById('id_gear_btn');
|
||||
// Anchor: id_gear_btn historically; id_kit_btn is the live fallback so
|
||||
// the open-state handle bottom lands at the bottom-right anchor instead
|
||||
// of overlapping it (no id_gear_btn renders on the room page today).
|
||||
var gearBtn = document.getElementById('id_gear_btn')
|
||||
|| document.getElementById('id_kit_btn');
|
||||
var gearBtnTop = window.innerHeight;
|
||||
if (gearBtn) {
|
||||
gearBtnTop = Math.round(gearBtn.getBoundingClientRect().top);
|
||||
}
|
||||
var handleH = (_btn && _btn.offsetHeight) || 48;
|
||||
// handleH = #id_tray_handle's height (48px CSS), NOT _btn.offsetHeight.
|
||||
// The 3rem btn can be larger than the 48px handle on big-rem viewports
|
||||
// (clamp(14px, 2.4vmin, 22px) → btn=66 at rem=22); using btn here would
|
||||
// push the handle's bottom that far below y=0 in closed state.
|
||||
var handleH = (_handle && _handle.offsetHeight) || 48;
|
||||
|
||||
// Pin wrap height so handle bottom = gear btn top when open.
|
||||
if (_wrap) _wrap.style.height = gearBtnTop + 'px';
|
||||
@@ -116,7 +125,11 @@ var Tray = (function () {
|
||||
_maxTop = -(gearBtnTop - handleH);
|
||||
} else {
|
||||
// Portrait: wrap width = full viewport; handle parks at right edge.
|
||||
var handleW = _btn.offsetWidth || 48;
|
||||
// handleW = #id_tray_handle's width (48px CSS), NOT _btn.offsetWidth —
|
||||
// same rationale as landscape: btn can be wider than handle on big-rem
|
||||
// viewports, which would leave a visible gap between the handle's right
|
||||
// edge and the viewport right edge in closed state.
|
||||
var handleW = (_handle && _handle.offsetWidth) || 48;
|
||||
if (_wrap) _wrap.style.width = window.innerWidth + 'px';
|
||||
_minLeft = 0;
|
||||
_maxLeft = window.innerWidth - handleW;
|
||||
@@ -398,10 +411,11 @@ var Tray = (function () {
|
||||
}
|
||||
|
||||
function init() {
|
||||
_wrap = document.getElementById('id_tray_wrap');
|
||||
_btn = document.getElementById('id_tray_btn');
|
||||
_tray = document.getElementById('id_tray');
|
||||
_grid = document.getElementById('id_tray_grid');
|
||||
_wrap = document.getElementById('id_tray_wrap');
|
||||
_handle = document.getElementById('id_tray_handle');
|
||||
_btn = document.getElementById('id_tray_btn');
|
||||
_tray = document.getElementById('id_tray');
|
||||
_grid = document.getElementById('id_tray_grid');
|
||||
_roleIconsUrl = (_grid && _grid.dataset.roleIconsUrl) || null;
|
||||
if (!_btn) return;
|
||||
|
||||
@@ -572,10 +586,11 @@ var Tray = (function () {
|
||||
delete el.dataset.role;
|
||||
});
|
||||
}
|
||||
_wrap = null;
|
||||
_btn = null;
|
||||
_tray = null;
|
||||
_grid = null;
|
||||
_wrap = null;
|
||||
_handle = null;
|
||||
_btn = null;
|
||||
_tray = null;
|
||||
_grid = null;
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
|
||||
Reference in New Issue
Block a user