XL landscape: revert tray to landscape style; fix sig-stage stretch
- Remove _tray.scss XL (≥1800px) portrait override block entirely - _isLandscape() no longer returns false at ≥1800px — tray uses landscape slide-from-top at all wide landscape widths - sig-stage: align-self: stretch (was center) so JS sizeSigCard() measures correct stage width; card size no longer collapses - Position strip: horizontal row at top (was vertical column-reverse) - sig-overlay/sig-stage/sig-deck-grid layout polish at 1100px/1800px Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -40,9 +40,6 @@ var Tray = (function () {
|
|||||||
|
|
||||||
function _isLandscape() {
|
function _isLandscape() {
|
||||||
if (_landscapeOverride !== null) return _landscapeOverride;
|
if (_landscapeOverride !== null) return _landscapeOverride;
|
||||||
// ≥1800px uses portrait-style tray (slides from right) to match the
|
|
||||||
// doubled sidebar widths and XL tray CSS reset.
|
|
||||||
if (window.innerWidth >= 1800) return false;
|
|
||||||
return window.innerWidth > window.innerHeight;
|
return window.innerWidth > window.innerHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,10 +94,7 @@ var Tray = (function () {
|
|||||||
// Closed: tray hidden above viewport, handle visible at y=0.
|
// Closed: tray hidden above viewport, handle visible at y=0.
|
||||||
_maxTop = -(gearBtnTop - handleH);
|
_maxTop = -(gearBtnTop - handleH);
|
||||||
} else {
|
} else {
|
||||||
// Portrait (and XL landscape, which uses portrait-style tray):
|
// Portrait: wrap width = full viewport; handle parks at right edge.
|
||||||
// Wrap width = viewportW so the closed right edge reaches the viewport boundary.
|
|
||||||
// The footer sidebar (z-100) is above the wrap (z-95) and has a solid background,
|
|
||||||
// so the handle parks behind it and slides out from under it when opened.
|
|
||||||
var handleW = _btn.offsetWidth || 48;
|
var handleW = _btn.offsetWidth || 48;
|
||||||
if (_wrap) _wrap.style.width = window.innerWidth + 'px';
|
if (_wrap) _wrap.style.width = window.innerWidth + 'px';
|
||||||
_minLeft = 0;
|
_minLeft = 0;
|
||||||
|
|||||||
@@ -234,6 +234,16 @@
|
|||||||
black 99%,
|
black 99%,
|
||||||
transparent 100%
|
transparent 100%
|
||||||
);
|
);
|
||||||
|
margin-left: 1rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
@media (orientation: landscape) and (min-width: 900px) {
|
||||||
|
margin-left: 2rem;
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
@media (orientation: landscape) and (min-width: 1800px) {
|
||||||
|
margin-left: 4rem;
|
||||||
|
margin-top: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
section {
|
section {
|
||||||
@extend %applet-box;
|
@extend %applet-box;
|
||||||
|
|||||||
@@ -193,6 +193,16 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (orientation: landscape) and (max-width: 1100px) {
|
||||||
|
body .container {
|
||||||
|
.navbar {
|
||||||
|
h1 {
|
||||||
|
font-size: 1rem !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (orientation: landscape) {
|
@media (orientation: landscape) {
|
||||||
$sidebar-w: 5rem;
|
$sidebar-w: 5rem;
|
||||||
|
|
||||||
@@ -265,12 +275,12 @@ body {
|
|||||||
.navbar-label { opacity: 0.7; }
|
.navbar-label { opacity: 0.7; }
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-primary {
|
// .btn-primary {
|
||||||
width: 4rem;
|
// width: 4rem;
|
||||||
height: 4rem;
|
// height: 4rem;
|
||||||
font-size: 0.875rem;
|
// font-size: 0.875rem;
|
||||||
border-width: 0.21rem;
|
// border-width: 0.21rem;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Login form: offset from fixed sidebars in landscape
|
// Login form: offset from fixed sidebars in landscape
|
||||||
.input-group {
|
.input-group {
|
||||||
@@ -300,17 +310,23 @@ body {
|
|||||||
padding: 0 0.5rem;
|
padding: 0 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Header row: compact in landscape
|
// Header row: h2 rotates into the left gutter (just right of the navbar border).
|
||||||
|
// position:fixed takes h2 out of flow; .row collapses to zero height automatically.
|
||||||
body .container .row {
|
body .container .row {
|
||||||
padding: 0.25rem 0;
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
.col-lg-6 h2 {
|
}
|
||||||
font-size: 1.5rem;
|
body .container .row .col-lg-6 h2 {
|
||||||
margin: 0 0 0.25rem;
|
position: fixed;
|
||||||
letter-spacing: 0.4em;
|
left: 5rem; // $sidebar-w — flush with the navbar right border
|
||||||
text-align: center;
|
top: 50%;
|
||||||
text-align-last: left;
|
transform: translateY(-50%) rotate(180deg);
|
||||||
}
|
writing-mode: vertical-rl;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
letter-spacing: 0.4em;
|
||||||
|
margin: 0;
|
||||||
|
z-index: 85;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Footer → fixed right sidebar (mirrors navbar approach — explicit right boundary)
|
// Footer → fixed right sidebar (mirrors navbar approach — explicit right boundary)
|
||||||
@@ -336,7 +352,8 @@ body {
|
|||||||
flex-direction: column-reverse;
|
flex-direction: column-reverse;
|
||||||
width: auto;
|
width: auto;
|
||||||
max-width: none;
|
max-width: none;
|
||||||
gap: 3rem;
|
gap: 1.5rem !important;
|
||||||
|
margin-bottom: 4rem;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
font-size: 1.75rem;
|
font-size: 1.75rem;
|
||||||
@@ -348,13 +365,49 @@ body {
|
|||||||
|
|
||||||
.footer-container {
|
.footer-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0.75rem;
|
top: 0.25rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 1rem;
|
line-height: 0.75 !important;
|
||||||
line-height: 1.4;
|
|
||||||
color: rgba(var(--secUser), 1);
|
color: rgba(var(--secUser), 1);
|
||||||
|
|
||||||
br { display: block; }
|
br { display: block; }
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 0.75rem !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (orientation: landscape) and (min-width: 700px) {
|
||||||
|
body .container .row .col-lg-6 h2 {
|
||||||
|
@media (min-height: 400px) {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
@media (min-height: 500px) {
|
||||||
|
font-size: 3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body #id_footer {
|
||||||
|
#id_footer_nav {
|
||||||
|
gap: 3rem !important;
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-container {
|
||||||
|
line-height: 1;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -373,7 +426,7 @@ body {
|
|||||||
|
|
||||||
.navbar-brand h1 { font-size: 2.4rem; }
|
.navbar-brand h1 { font-size: 2.4rem; }
|
||||||
.navbar-text { font-size: 0.78rem; } // 0.65rem × 1.2
|
.navbar-text { font-size: 0.78rem; } // 0.65rem × 1.2
|
||||||
.btn-primary { width: 4rem; height: 4rem; font-size: 0.875rem; }
|
// .btn-primary { width: 4rem; height: 4rem; font-size: 0.875rem; }
|
||||||
|
|
||||||
.input-group {
|
.input-group {
|
||||||
left: $sidebar-xl;
|
left: $sidebar-xl;
|
||||||
@@ -386,23 +439,31 @@ body {
|
|||||||
margin-right: $sidebar-xl;
|
margin-right: $sidebar-xl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// h2 page title: portrait-style — centred and full-size on a wide canvas
|
// h2 page title: keep vertical rotation; shift left to clear the wider XL navbar.
|
||||||
body .container .row .col-lg-6 h2 {
|
body .container .row .col-lg-6 h2 {
|
||||||
font-size: 4rem;
|
left: 8rem; // $sidebar-xl
|
||||||
letter-spacing: 1em;
|
@media (min-height: 800px) {
|
||||||
text-align: center;
|
font-size: 4.5rem;
|
||||||
text-align-last: center;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body #id_footer {
|
body #id_footer {
|
||||||
width: $sidebar-xl;
|
width: $sidebar-xl;
|
||||||
|
|
||||||
#id_footer_nav {
|
#id_footer_nav {
|
||||||
gap: 8rem;
|
gap: 8rem !important;
|
||||||
a { font-size: 3rem; }
|
a { font-size: 3rem; }
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-container { font-size: 0.85rem; }
|
.footer-container {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,13 @@
|
|||||||
0 0 0.5rem rgba(var(--quaUser), 0.22)
|
0 0 0.5rem rgba(var(--quaUser), 0.22)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (orientation: landscape) and (max-width: 1100px) {
|
||||||
|
width: 2.75rem !important;
|
||||||
|
height: 2.75rem !important;
|
||||||
|
font-size: 0.625rem !important;
|
||||||
|
border-width: 0.125rem !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.btn-abandon {
|
&.btn-abandon {
|
||||||
|
|||||||
@@ -809,29 +809,23 @@ $card-h: 60px;
|
|||||||
z-index: 50;
|
z-index: 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reflow position strip into a vertical column along the left edge,
|
// Position strip: horizontal row across the top, slots 1-6 in order.
|
||||||
// reversed so 6 is at top, 1 at bottom, below the GAMEROOM title.
|
// Offset from both sidebars (5rem each) and centred with gap.
|
||||||
.position-strip {
|
.position-strip {
|
||||||
flex-direction: column-reverse;
|
flex-direction: row;
|
||||||
top: 3rem;
|
top: 2.5rem;
|
||||||
left: 0.5rem;
|
left: 5rem;
|
||||||
right: auto;
|
right: 5rem;
|
||||||
|
justify-content: center;
|
||||||
gap: round($gate-gap * 0.4);
|
gap: round($gate-gap * 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shallow landscape (phones): wrap into two columns — left: 6,5,4 / right: 3,2,1
|
// Small landscape (phones ≤550px tall): strip stays horizontal — no two-column
|
||||||
// Columns grow rightward (wrap, not wrap-reverse) so overflow: hidden doesn't clip.
|
// trick needed now that the h2 is in the gutter. Just clear any order overrides.
|
||||||
// order: -1 on slots 4–6 pulls them to the front of the flex sequence; combined
|
|
||||||
// with column-reverse they land in the left column reading 6,5,4 top-to-bottom.
|
|
||||||
@media (max-height: 550px) {
|
@media (max-height: 550px) {
|
||||||
.position-strip {
|
.position-strip {
|
||||||
flex-wrap: wrap;
|
.gate-slot { order: 0; }
|
||||||
// cap height to exactly 3 circles so the 4th wraps to a new column
|
top: 1rem;
|
||||||
max-height: #{3 * round($gate-node * 0.75) + 2 * round($gate-gap * 0.4)};
|
|
||||||
|
|
||||||
.gate-slot[data-slot="4"],
|
|
||||||
.gate-slot[data-slot="5"],
|
|
||||||
.gate-slot[data-slot="6"] { order: -1; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1084,23 +1078,50 @@ html:has(.sig-backdrop) {
|
|||||||
// Grid margins reset to 0 — overlay padding handles all edge clearance.
|
// Grid margins reset to 0 — overlay padding handles all edge clearance.
|
||||||
|
|
||||||
@media (orientation: landscape) {
|
@media (orientation: landscape) {
|
||||||
.sig-overlay { padding-left: 4rem; }
|
.sig-modal {
|
||||||
.sig-modal { max-width: none; }
|
max-width: none;
|
||||||
|
flex-direction: row; // grid to the right, stage + card preview to the left
|
||||||
|
margin-left: 4rem;
|
||||||
|
margin-right: 3rem;
|
||||||
|
}
|
||||||
|
.sig-stage {
|
||||||
|
min-width: 0; // allow shrinking in row layout; align-items:flex-end already set
|
||||||
|
}
|
||||||
.sig-deck-grid {
|
.sig-deck-grid {
|
||||||
grid-template-columns: repeat(9, 3rem);
|
grid-template-columns: repeat(6, 2.5rem);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
align-self: flex-end; // sit at the bottom of the modal row
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (orientation: landscape) and (min-width: 1100px) {
|
@media (orientation: landscape) and (min-width: 900px) {
|
||||||
|
// Wide landscape: revert to stacked layout (stage top, 18-card row grid bottom).
|
||||||
|
.sig-modal {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
.sig-stage {
|
||||||
|
min-width: auto;
|
||||||
|
align-self: stretch; // fill full modal width so JS sizeSigCard() gets correct stageWidth
|
||||||
|
margin-left: 3rem;
|
||||||
|
}
|
||||||
.sig-deck-grid {
|
.sig-deck-grid {
|
||||||
grid-template-columns: repeat(18, 3rem);
|
grid-template-columns: repeat(18, 3rem);
|
||||||
|
align-self: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (orientation: landscape) and (min-width: 1800px) {
|
@media (orientation: landscape) and (min-width: 1800px) {
|
||||||
// Sig overlay: clear doubled navbar sidebar (8rem instead of 4rem)
|
// Sig overlay: clear doubled sidebars (8rem each instead of 4rem/6rem)
|
||||||
.sig-overlay { padding-left: 8rem; }
|
.sig-overlay { padding-left: 8rem; padding-right: 8rem; }
|
||||||
|
.sig-stage {
|
||||||
|
align-self: stretch; // fill full modal width so JS sizeSigCard() gets correct stageWidth
|
||||||
|
margin-left: 3rem;
|
||||||
|
}
|
||||||
|
.sig-deck-grid {
|
||||||
|
grid-template-columns: repeat(18, 5rem);
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
// Room menu: base right: 0.5rem (same-specificity ID rule) overrides _applets.scss
|
// Room menu: base right: 0.5rem (same-specificity ID rule) overrides _applets.scss
|
||||||
// XL block because _room.scss is imported later. Re-declare here to win the cascade.
|
// XL block because _room.scss is imported later. Re-declare here to win the cascade.
|
||||||
|
|||||||
@@ -329,76 +329,4 @@ $handle-r: 1rem;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── XL landscape (≥1800px): portrait-style tray — slides in from right ─────
|
// ≥1800px uses the same landscape tray rules as narrower landscape — no override block needed.
|
||||||
// Overrides all landscape rules above. JS also returns false from _isLandscape()
|
|
||||||
// at this width so portrait code paths run throughout.
|
|
||||||
@media (orientation: landscape) and (min-width: 1800px) {
|
|
||||||
#id_tray_wrap {
|
|
||||||
flex-direction: row;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: auto; // JS controls left; width set to innerWidth so wrap fills viewport
|
|
||||||
right: auto;
|
|
||||||
height: auto;
|
|
||||||
width: auto;
|
|
||||||
z-index: 95; // below footer/nav sidebars (z-100) — opaque footer masks the tray
|
|
||||||
transition: left 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
|
|
||||||
&.wobble { animation: tray-wobble 0.45s ease; }
|
|
||||||
&.snap { animation: tray-snap 0.30s ease; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#id_tray_handle {
|
|
||||||
width: $handle-exposed; // 48px portrait strip
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
#id_tray_grip {
|
|
||||||
top: 50%;
|
|
||||||
bottom: auto;
|
|
||||||
left: calc(#{$handle-exposed} / 2 - 0.125rem);
|
|
||||||
transform: translateY(-50%);
|
|
||||||
width: $handle-rect-w; // 10000px extends leftward
|
|
||||||
height: $handle-rect-h; // 72px
|
|
||||||
}
|
|
||||||
|
|
||||||
#id_tray {
|
|
||||||
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);
|
|
||||||
border-right: none;
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
margin-bottom: 0;
|
|
||||||
width: auto;
|
|
||||||
max-width: none;
|
|
||||||
align-self: auto;
|
|
||||||
flex: 1;
|
|
||||||
height: auto;
|
|
||||||
overflow: hidden;
|
|
||||||
box-shadow:
|
|
||||||
-0.25rem 0 0.5rem rgba(0, 0, 0, 0.55),
|
|
||||||
inset 0 0 0 0.3rem rgba(var(--quiUser), 0.45),
|
|
||||||
inset 0.6rem 0 1.5rem -0.5rem rgba(0, 0, 0, 1),
|
|
||||||
inset 0.6rem 0 1.5rem -0.5rem rgba(var(--quiUser), 0.5),
|
|
||||||
inset 0 0.6rem 1.5rem -0.5rem rgba(0, 0, 0, 1),
|
|
||||||
inset 0 0.6rem 1.5rem -0.5rem rgba(var(--quiUser), 0.5),
|
|
||||||
inset 0 -0.6rem 1.5rem -0.5rem rgba(0, 0, 0, 1),
|
|
||||||
inset 0 -0.6rem 1.5rem -0.5rem rgba(var(--quiUser), 0.5)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
#id_tray_grid {
|
|
||||||
grid-template-columns: none;
|
|
||||||
grid-template-rows: repeat(8, var(--tray-cell-size, 48px));
|
|
||||||
grid-auto-flow: column;
|
|
||||||
grid-auto-columns: var(--tray-cell-size, 48px);
|
|
||||||
grid-auto-rows: auto;
|
|
||||||
position: static;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tray-cell {
|
|
||||||
border-top: none;
|
|
||||||
border-right: 2px dotted rgba(var(--priUser), 0.35);
|
|
||||||
border-bottom: 2px dotted rgba(var(--priUser), 0.35);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user