$gate-node: 64px; $gate-gap: 36px; $gate-line: 2px; .room-page { position: relative; display: flex; align-items: center; justify-content: center; min-height: 60vh; } .room-page .gear-btn { z-index: 101; } #id_room_menu { position: absolute; bottom: 3.5rem; right: 0.5rem; z-index: 101; background-color: rgba(var(--priUser), 0.95); border: 0.15rem solid rgba(var(--secUser), 1); box-shadow: 0 0 0.5rem rgba(var(--secUser), 0.75), 0.12rem 0.12rem 0.5rem rgba(0, 0, 0, 0.25) ; border-radius: 0.75rem; padding: 1rem; display: flex; flex-direction: column; gap: 0.5rem; } html:has(.gate-overlay) { overflow: hidden; } body:has(.gate-overlay) { // Pin gear controls to the visual viewport, // bypassing iOS 100vh chrome-inclusion bug. // Offset upward so gear btn clears the kit btn below it. .room-page .gear-btn { position: fixed; bottom: 4.2rem; right: 0.5rem; z-index: 202; } #id_room_menu { position: fixed; bottom: 6.6rem; right: 0.5rem; z-index: 202; } } .gate-overlay { position: fixed; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.7); backdrop-filter: blur(4px); z-index: 100; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; pointer-events: none; } .gate-modal { display: flex; flex-direction: column; align-items: center; pointer-events: auto; padding: 2rem; border: 0.1rem solid rgba(var(--terUser), 0.5); border-radius: 1rem; background-color: rgba(var(--priUser), 1); .gate-header { text-align: center; h1 { font-size: 2rem; color: rgba(var(--secUser), 0.6); margin-bottom: 1rem; text-align: justify; text-align-last: center; text-justify: inter-character; text-transform: uppercase; text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.125), // highlight (up-left) -0.125rem -0.125rem 0 rgba(0, 0, 0, 0.8) // shadow (down-right) ; span { color: rgba(var(--quaUser), 0.6); } margin: 0 0 0.5rem; } .gate-status-wrap { display: flex; justify-content: center; align-items: baseline; opacity: 0.5; font-size: 0.75em; text-transform: uppercase; letter-spacing: 0.15em; margin-bottom: 1rem; .status-dots { display: inline-flex; span { display: inline-block; width: 0.5em; text-align: center; } } } } .token-slot { position: relative; display: flex; flex-direction: row; border: 2px solid rgba(var(--terUser), 0.7); border-radius: 0.4rem; background: rgba(0, 0, 0, 0.35); min-width: 180px; &.locked { opacity: 0.3; pointer-events: none; } &.ready { border-color: rgba(var(--terUser), 1); box-shadow: 0 0 0.6rem rgba(var(--terUser), 0.6), 0 0 1.6rem rgba(var(--terUser), 0.25) ; } &.pending, &.claimed { box-shadow: 0 0 0.6rem rgba(var(--terUser), 0.5), 0 0 1.4rem rgba(var(--terUser), 0.2), ; .token-reject-btn { text-shadow: 0 0 0.5rem rgba(var(--terUser), 0.8); } &:hover { border-color: rgba(var(--terUser), 1); background: rgba(0, 0, 0, 0.55); box-shadow: 0 0 0.8rem rgba(var(--terUser), 0.75), 0 0 2rem rgba(var(--terUser), 0.35), ; } } .token-rails, button.token-rails { display: flex; flex-direction: row; align-items: stretch; padding: 0.6rem 0.45rem; gap: 0.2rem; border-right: 1px solid rgba(var(--terUser), 0.35); .rail { display: block; width: 2px; background: rgba(var(--terUser), 0.55); border-radius: 1px; } } button.token-rails { background: transparent; border: none; outline: none; border-right: 1px solid rgba(var(--terUser), 0.35); cursor: pointer; border-radius: 0.3rem 0 0 0.3rem; &:hover { background: rgba(var(--terUser), 0.1); .rail { background: rgba(var(--terUser), 1); } } } .token-reject-btn { position: absolute; inset: 0; background: transparent; border: none; outline: none; cursor: pointer; border-radius: inherit; } .token-panel { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 0.45rem 0.75rem; gap: 0.15rem; .token-denomination { font-size: 1.5em; font-weight: bold; color: rgba(var(--terUser), 1); line-height: 1; } .token-insert-label, .token-insert-btn { &::before { content: '← '; } font-size: 0.6em; text-transform: uppercase; letter-spacing: 0.08em; text-align: center; line-height: 1.3; } .token-reject-label { font-size: 0.55em; text-transform: uppercase; letter-spacing: 0.06em; opacity: 0.5; line-height: 1.3; text-align: center; } } } .gate-slots { display: flex; flex-direction: row; align-items: center; gap: $gate-gap; .gate-slot { position: relative; width: $gate-node; height: $gate-node; border-radius: 50%; border: $gate-line solid rgba(var(--terUser), 1); display: flex; flex-direction: column; align-items: center; justify-content: center; flex-shrink: 0; &.filled, &.reserved { background: rgba(var(--terUser), 0.2); } &.filled:hover, &.reserved:hover { box-shadow: -0.1rem -0.1rem 1rem rgba(var(--ninUser), 1), -0.1rem -0.1rem 0.25rem rgba(0, 0, 0, 1), 0.05rem 0.05rem 0.5rem rgba(0, 0, 0, 1), ; } .slot-number { font-size: 0.7em; opacity: 0.5; } .slot-gamer { display: none; } form { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; } .drop-token-btn { position: absolute; inset: 0; border-radius: 50%; width: 100%; height: 100%; background: transparent; border: none; box-shadow: 0.05rem 0.05rem 0.5rem rgba(0, 0, 0, 1), ; font-size: 0; cursor: pointer; &:hover { background: rgba(var(--quaUser), 0.15); box-shadow: -0.1rem -0.1rem 1rem rgba(var(--ninUser), 1), -0.1rem -0.1rem 0.25rem rgba(0, 0, 0, 1), 0.05rem 0.05rem 0.5rem rgba(0, 0, 0, 1), ; } } } } } // Narrow viewport — scale down, 2×3 slot grid (portrait mobile + narrow desktop) @media (max-width: 550px) { .gate-modal { padding: 1.25rem 1.5rem; .gate-header { h1 { font-size: 1.5rem; } .gate-status-wrap { margin-bottom: 0.5rem; } } .token-slot { min-width: 150px; } .gate-slots { display: grid; grid-template-columns: repeat(3, 52px); grid-template-rows: repeat(2, 52px); gap: 24px; .gate-slot { width: 52px; height: 52px; &:nth-child(1) { grid-column: 1; grid-row: 1; } &:nth-child(2) { grid-column: 2; grid-row: 1; } &:nth-child(3) { grid-column: 3; grid-row: 1; } &:nth-child(4) { grid-column: 1; grid-row: 2; } &:nth-child(5) { grid-column: 2; grid-row: 2; } &:nth-child(6) { grid-column: 3; grid-row: 2; } } } } } // Landscape mobile — aggressively scale down to fit short viewport @media (orientation: landscape) and (max-width: 1023px) { .room-page .gear-btn { bottom: 3.5rem; } .gate-modal { padding: 0.6rem 1.25rem; .gate-header { h1 { font-size: 1rem; margin: 0 0 0.25rem; } .gate-status-wrap { font-size: 0.65em; margin-bottom: 0.35rem; } } .token-slot { min-width: 130px; .token-rails, button.token-rails { padding: 0.4rem 0.35rem; } .token-panel { padding: 0.3rem 0.5rem; .token-denomination { font-size: 1.1em; } } } .gate-slots { gap: 14px; .gate-slot { width: 40px; height: 40px; .slot-number { font-size: 0.6em; } } } .form-container { h3 { font-size: 0.85rem; margin: 0.25rem 0; } form { gap: 0.35rem; } .form-control-lg { --_pad-v: 0.4rem; font-size: 0.9rem; } } } }