new landscape styling & scripting for gameroom #id_tray apparatus, & some overall scripting & styling like wobble on click-to-close; new --undUser & --duoUser rootvars universally the table felt values; many new Jasmine tests to handle tray functionality

This commit is contained in:
Disco DeDisco
2026-03-28 21:23:50 -04:00
parent d63a4bec4a
commit c08b5b764e
7 changed files with 680 additions and 85 deletions

View File

@@ -371,9 +371,9 @@ $seat-r-y: round($seat-r * 0.5); // 65px
width: 160px;
height: 185px;
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
background: rgba(var(--priUser), 0.8);
background: rgba(var(--duoUser), 1);
// box-shadow is clipped by clip-path; use filter instead
filter: drop-shadow(0 0 8px rgba(var(--terUser), 0.25));
filter: drop-shadow(0 0 8px rgba(var(--duoUser), 1));
display: flex;
align-items: center;
justify-content: center;
@@ -678,6 +678,7 @@ $inv-strip: 30px; // visible height of each stacked card after the first
}
}
}
}
// ─── Significator deck (SIG_SELECT phase) ──────────────────────────────────
@@ -781,7 +782,8 @@ $handle-r: 1rem;
transition: left 0.35s cubic-bezier(0.4, 0, 0.2, 1);
&.tray-dragging { transition: none; }
&.wobble { animation: tray-wobble 0.45s ease; }
&.wobble { animation: tray-wobble 0.45s ease; }
&.snap { animation: tray-snap 0.30s ease; }
}
#id_tray_handle {
@@ -865,6 +867,15 @@ $handle-r: 1rem;
80% { transform: translateX(3px); }
}
// Inverted wobble — handle overshoots past the wall on close, then bounces back.
@keyframes tray-snap {
0%, 100% { transform: translateX(0); }
20% { transform: translateX(8px); }
40% { transform: translateX(-6px); }
60% { transform: translateX(5px); }
80% { transform: translateX(-3px); }
}
#id_tray {
flex: 1;
min-width: 0;
@@ -872,10 +883,10 @@ $handle-r: 1rem;
pointer-events: auto;
position: relative;
z-index: 1; // above #id_tray_grip pseudo-elements
background: rgba(var(--secUser), 1);
border-left:2.5rem solid rgba(var(--terUser), 1);
border-top: 2.5rem solid rgba(var(--terUser), 1);
border-bottom: 2.5rem solid rgba(var(--terUser), 1);
background: rgba(var(--duoUser), 1);
border-left:2.5rem solid rgba(var(--quaUser), 1);
border-top: 2.5rem solid rgba(var(--quaUser), 1);
border-bottom: 2.5rem solid rgba(var(--quaUser), 1);
box-shadow:
-0.25rem 0 0.5rem rgba(0, 0, 0, 0.75),
inset 0 0 0 0.12rem rgba(255, 255, 255, 0.12), // bright bevel ring at wall edge
@@ -884,6 +895,98 @@ $handle-r: 1rem;
inset 0 -0.6rem 1.5rem -0.5rem rgba(0, 0, 0, 0.3) // bottom wall depth
;
overflow-y: auto;
max-height: 85vh; // cap on very tall portrait screens
// scrollbar-width: thin;
// scrollbar-color: rgba(var(--terUser), 0.3) transparent;
}
// ─── Tray: landscape reorientation ─────────────────────────────────────────
//
// Must come AFTER the portrait tray rules above to win the cascade
// (same specificity — later declaration wins).
//
// In landscape the tray slides DOWN from the top instead of in from the right.
// Structure (column-reverse): tray panel above, handle below.
// JS controls style.top for the Y-axis slide:
// Closed: top = -(trayH) → only handle visible at y = 0
// Open: top = gearBtnTop - wrapH → handle bottom at gear btn top
//
// The wrap fits horizontally between the fixed left-nav and right-footer sidebars.
@media (orientation: landscape) {
$sidebar-w: 4rem;
$tray-landscape-max-w: 960px; // cap tray width on very wide screens
#id_tray_wrap {
flex-direction: column-reverse; // tray panel above, handle below
left: $sidebar-w;
right: $sidebar-w;
top: auto; // JS controls style.top for the Y-axis slide
bottom: auto;
transition: top 0.35s cubic-bezier(0.4, 0, 0.2, 1);
&.tray-dragging { transition: none; }
&.wobble { animation: tray-wobble-landscape 0.45s ease; }
&.snap { animation: tray-snap-landscape 0.30s ease; }
}
#id_tray_handle {
width: auto; // full width of wrap
height: 48px; // $handle-exposed — same exposed dimension as portrait
}
#id_tray_grip {
// Rotate 90°: centred horizontally, extends vertically.
// bottom mirrors portrait's left: grip starts at handle centre and extends
// toward the tray (upward in column-reverse layout).
bottom: calc(48px / 2 - 0.125rem); // $handle-exposed / 2 from handle bottom
top: auto;
left: 50%;
transform: translateX(-50%);
width: 72px; // $handle-rect-h — narrow visible dimension
height: 10000px; // $handle-rect-w — extends upward into tray area
}
#id_tray {
// Borders: left/right/bottom are visible walls; top edge is open.
// Bottom faces the handle (same logic as portrait's left border facing handle).
border-left: 2.5rem solid rgba(var(--quaUser), 1);
border-right: 2.5rem solid rgba(var(--quaUser), 1);
border-bottom: 2.5rem solid rgba(var(--quaUser), 1);
border-top: none;
margin-left: 0; // portrait horizontal gap no longer needed
margin-bottom: 0.5rem; // gap between tray bottom and handle top
// Cap width on ultra-wide screens; center within the handle shelf.
width: 100%;
max-width: $tray-landscape-max-w;
align-self: center;
box-shadow:
0 0.25rem 0.5rem rgba(0, 0, 0, 0.75), // outer shadow (downward, below tray toward handle)
inset 0 0 0 0.12rem rgba(255, 255, 255, 0.12), // bright bevel ring
inset 0 -0.6rem 1.5rem -0.5rem rgba(0, 0, 0, 0.45), // bottom wall depth (inward from bottom border)
inset 0.6rem 0 1.5rem -0.5rem rgba(0, 0, 0, 0.3), // left wall depth
inset -0.6rem 0 1.5rem -0.5rem rgba(0, 0, 0, 0.3) // right wall depth
;
min-height: 2000px; // give tray real height so JS offsetHeight > 0
}
@keyframes tray-wobble-landscape {
0%, 100% { transform: translateY(0); }
20% { transform: translateY(-8px); }
40% { transform: translateY(6px); }
60% { transform: translateY(-5px); }
80% { transform: translateY(3px); }
}
// Inverted wobble — wrap overshoots upward on close, then bounces back.
@keyframes tray-snap-landscape {
0%, 100% { transform: translateY(0); }
20% { transform: translateY(8px); }
40% { transform: translateY(-6px); }
60% { transform: translateY(5px); }
80% { transform: translateY(-3px); }
}
}