diff --git a/www/html/Game/public/css/room-lobby.css b/www/html/Game/public/css/room-lobby.css
index f4a12b8..568ce02 100644
--- a/www/html/Game/public/css/room-lobby.css
+++ b/www/html/Game/public/css/room-lobby.css
@@ -1,2042 +1,2049 @@
-* { box-sizing: border-box; }
-@font-face {
- font-family: 'NotoSansThai';
- src:
- url('/Create%20Room/FONTS/NotoSansThai-Medium.ttf') format('truetype');
- font-weight: 500;
- font-style: normal;
- font-display: swap;
-}
-body { font-family: sans-serif; margin: 0; background: #1a1b26; color: #c0caf5; }
-body.room-lobby-page,
-body.room-lobby-page * {
- font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif !important;
-}
-.container { max-width: 720px; margin: 1rem auto; padding: 1rem; }
-
-/* โครง Editor — แยกแถบเครื่องมือ / พื้นที่วาด */
-.editor-page {
- display: block;
-}
-
-/* Editor ฝังใน Admin (?embed=1) — เต็มความสูง iframe, พื้นที่แคนวาสใหญ่ + เลื่อนแยก */
-html.editor-embed-admin {
- height: 100%;
-}
-html.editor-embed-admin body {
- height: 100%;
- margin: 0;
- overflow: hidden;
-}
-body.editor-embed-admin .version-tag {
- display: none !important;
-}
-body.editor-embed-admin .container.editor-page {
- max-width: none !important;
- width: 100%;
- height: 100%;
- margin: 0 !important;
- padding: 0.35rem 0.5rem 0.45rem;
- display: flex;
- flex-direction: column;
- min-height: 0;
- box-sizing: border-box;
-}
-body.editor-embed-admin .container.editor-page > h1 {
- display: none;
-}
-body.editor-embed-admin .editor-toolbar-wrap {
- flex: 0 1 auto;
- max-height: min(36vh, 360px);
- overflow-x: hidden;
- overflow-y: auto;
- padding: 0.15rem 0.25rem 0.45rem 0;
- margin: 0 0 0.3rem;
- border-bottom: 1px solid rgba(65, 72, 104, 0.9);
- scrollbar-width: thin;
-}
-body.editor-embed-admin .editor-workspace {
- flex: 1 1 auto;
- min-height: 0;
- display: flex;
- flex-direction: column;
- overflow: hidden;
-}
-body.editor-embed-admin .canvas-wrap {
- flex: 1 1 auto;
- min-height: 140px;
- overflow: auto;
- margin: 0 !important;
- border-radius: 10px;
- border: 1px solid #414868;
- background: #0f1018;
- -webkit-overflow-scrolling: touch;
-}
-body.editor-embed-admin #editor-status {
- flex: 0 0 auto;
- margin: 0.3rem 0 0;
- font-size: 0.8rem;
- line-height: 1.35;
-}
-body.editor-embed-admin .editor-legend-short {
- margin: 0.25rem 0 0;
- font-size: 0.76rem;
- line-height: 1.4;
- color: #a8b0d0;
-}
-body.editor-embed-admin .editor-toolbar {
- margin-top: 0.25rem;
- margin-bottom: 0.35rem;
-}
-body.editor-embed-admin .frogger-lanes {
- margin: 0.35rem 0;
-}
-body.editor-embed-admin .editor-bg-section {
- margin: 0.35rem 0 0.15rem;
-}
-h1 { color: #7aa2f7; }
-a { color: #9ece6a; }
-label { display: inline-block; margin: 0.25rem 0.5rem 0.25rem 0; }
-input, button { padding: 0.4rem 0.6rem; margin: 0 0.25rem 0 0; border-radius: 6px; border: 1px solid #414868; }
-input { background: #24283b; color: #c0caf5; }
-button { background: #7aa2f7; color: #1a1b26; cursor: pointer; border: none; }
-.legend { font-size: 0.9rem; color: #a9b1d6; margin: 0.5rem 0; }
-.frogger-lanes { margin: 1rem 0; padding: 0.75rem; background: #24283b; border-radius: 8px; position: relative; z-index: 2; min-height: 80px; }
-.frogger-lanes h3 { margin: 0 0 0.5rem 0; color: #7aa2f7; font-size: 1rem; }
-.frogger-lanes table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
-.frogger-lanes th, .frogger-lanes td { padding: 0.25rem 0.5rem; text-align: left; border: 1px solid #414868; }
-.frogger-lanes select, .frogger-lanes input[type="number"] { padding: 0.35rem 0.5rem; min-width: 4rem; background: #1a1b26; color: #c0caf5; border: 1px solid #414868; border-radius: 4px; cursor: pointer; font-size: 0.9rem; }
-.frogger-lanes select { min-width: 6rem; }
-.frogger-lanes .lane-speed { width: 4rem; }
-.frogger-lanes .lane-spacing { width: 4rem; }
-.frogger-lanes td { vertical-align: middle; }
-.frogger-lanes select:disabled, .frogger-lanes input:disabled { opacity: 0.6; cursor: not-allowed; }
-.game-type-hint { font-size: 0.85rem; color: #a9b1d6; margin-left: 0.5rem; }
-.editor-toolbar { margin: 1rem 0; flex-wrap: wrap; display: flex; align-items: center; gap: 0.5rem 1rem; }
-.editor-toolbar label, .editor-toolbar .game-type-hint { margin: 0; }
-.editor-bg-section { margin: 0.75rem 0; display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
-.editor-bg-section label { margin: 0; }
-.canvas-wrap { margin: 1rem 0; }
-.container { padding-left: 1rem; padding-right: 1rem; }
-#editor-canvas { background: #1a1b26; display: block; }
-.game-wrap { display: flex; flex-direction: column; height: 100vh; height: 100dvh; min-height: 0; }
-.game-header { flex-shrink: 0; background: #24283b; padding: 0.5rem 1rem; display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; }
-.game-header span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
-.game-header button { flex-shrink: 0; }
-#game-canvas {
- flex: 1 1 auto;
- display: block;
- width: 100%;
- min-height: 0;
- min-width: 0;
- touch-action: none;
-}
-.game-wrap .chat-panel { flex-shrink: 0; }
-.chat-panel { height: 160px; border-top: 1px solid #414868; display: flex; flex-direction: column; }
-#chat-messages { flex: 1; overflow-y: auto; padding: 0.5rem; font-size: 0.9rem; }
-#chat-form { display: flex; padding: 0.5rem; gap: 0.5rem; }
-#chat-input { flex: 1; }
-
-.lobby-section { margin: 1.25rem 0; padding: 1rem; background: #24283b; border-radius: 8px; }
-.lobby-section h2 { margin: 0 0 0.75rem 0; font-size: 1rem; color: #7aa2f7; }
-#room-list { list-style: none; margin: 0; padding: 0; }
-#room-list .room-item { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; padding: 0.5rem 0; border-bottom: 1px solid #414868; }
-#room-list .room-item:last-child { border-bottom: none; }
-#room-list .room-name { font-weight: 600; color: #c0caf5; min-width: 0; }
-#room-list .room-meta { font-size: 0.85rem; color: #a9b1d6; }
-#room-list .room-meta-inline { font-size: 0.8rem; color: #565f89; font-weight: normal; }
-#room-list-status { margin: 0; color: #a9b1d6; font-size: 0.9rem; }
-
-.room-lobby-peers { margin: 1rem 0; padding: 0.75rem; background: #24283b; border-radius: 8px; }
-.room-lobby-peer { padding: 0.35rem 0; color: #c0caf5; }
-.room-lobby-peer:not(:last-child) { border-bottom: 1px solid #414868; }
-#lobby-map-wrap { position: fixed; top: 0; left: 0; right: 0; bottom: 0; width: 100%; height: 100%; min-width: 100vw; min-height: 100vh; z-index: 0; }
-body.room-lobby-page {
- background:
- radial-gradient(120% 120% at 50% -12%, rgba(86, 122, 255, 0.26) 0%, rgba(30, 37, 83, 0.16) 40%, rgba(7, 10, 25, 0) 75%),
- linear-gradient(180deg, #1a1d46 0%, #111530 42%, #090d22 100%);
- color: #ebf6ff;
-}
-#lobby-map-wrap::before {
- content: '';
- position: absolute;
- inset: 0;
- z-index: 1;
- pointer-events: none;
- background:
- radial-gradient(80% 65% at 50% 18%, rgba(106, 194, 255, 0.2), rgba(106, 194, 255, 0) 72%),
- linear-gradient(180deg, rgba(10, 16, 46, 0.25) 0%, rgba(6, 12, 31, 0.05) 30%, rgba(5, 9, 24, 0.5) 100%);
-}
-#lobby-map-wrap::after {
- content: '';
- position: absolute;
- inset: 0;
- z-index: 2;
- pointer-events: none;
- box-shadow: inset 0 0 160px rgba(8, 12, 30, 0.85);
-}
-#lobby-map-canvas {
- display: block;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- width: 100%;
- height: 100%;
- min-width: 100%;
- min-height: 100%;
- margin: 0;
- padding: 0;
- background:
- radial-gradient(circle at 50% 20%, rgba(124, 197, 255, 0.25) 0%, rgba(124, 197, 255, 0) 45%),
- linear-gradient(180deg, #252c66 0%, #1a2150 45%, #121a3b 100%);
- box-sizing: border-box;
-}
-#lobby-map-canvas:focus {
- outline: none;
-}
-#lobby-map-canvas:focus-visible {
- outline: 2px solid rgba(122, 162, 247, 0.45);
- outline-offset: -2px;
-}
-/* LobbyB (mn8nx46h) — ไม่แสดงปุ่มพร้อม */
-body.room-lobby--lobby-b .room-lobby-ready-fixed {
- display: none !important;
-}
-.lobby-interact-hint {
- position: absolute;
- bottom: max(10px, env(safe-area-inset-bottom));
- left: 50%;
- transform: translateX(-50%);
- z-index: 2;
- margin: 0;
- padding: 0.2rem 0.55rem;
- font-size: clamp(0.72rem, 1.8vw, 0.85rem);
- color: rgba(203, 213, 245, 0.9);
- text-shadow: 0 1px 10px rgba(0, 0, 0, 0.55);
- pointer-events: none;
- font-family: system-ui, 'Kanit', sans-serif;
- white-space: nowrap;
-}
-.lobby-interact-hint kbd {
- display: inline-block;
- padding: 0.06em 0.32em;
- border-radius: 4px;
- background: rgba(26, 27, 38, 0.88);
- border: 1px solid rgba(122, 162, 247, 0.45);
- font-size: 0.88em;
- font-family: inherit;
-}
-.lobby-zoom-pct {
- position: absolute;
- top: 12px;
- left: 50%;
- transform: translateX(-50%);
- z-index: 2;
- padding: 6px 12px;
- border-radius: 8px;
- background: rgba(26, 27, 38, 0.85);
- color: #c0caf5;
- font-size: 1rem;
- font-weight: 600;
- pointer-events: none;
- opacity: 0;
- transition: opacity 0.2s ease;
-}
-.lobby-zoom-pct.lobby-zoom-pct-visible { opacity: 1; }
-/* ซ่อนแผง overlay รายชื่อ / host / แชท — โถงโฟกัสแผนที่ + ปุ่ม READY/ไมค์ ด้านนอก */
-.room-lobby-overlay { display: none !important; }
-.room-lobby-top-left-cluster {
- position: fixed;
- top: max(12px, env(safe-area-inset-top));
- left: max(0px, env(safe-area-inset-left));
- z-index: 55;
- display: flex;
- flex-direction: column;
- align-items: flex-start;
- gap: 0.4rem;
- pointer-events: none;
-}
-.room-lobby-top-left-cluster .room-lobby-exit-fixed {
- pointer-events: auto;
-}
-.room-lobby-room-id-pill {
- pointer-events: auto;
- display: inline-flex;
- align-items: center;
- gap: 0.4rem;
- min-height: 44px;
- padding: 0.5rem 0.9rem;
- border-radius: 12px;
- border: 1px solid rgba(106, 232, 255, 0.58);
- background: linear-gradient(180deg, rgba(43, 67, 128, 0.86), rgba(22, 34, 74, 0.9));
- box-shadow:
- inset 0 0 0 1px rgba(188, 247, 255, 0.2),
- 0 0 18px rgba(80, 213, 255, 0.32);
- color: #dff6ff;
- font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif;
- letter-spacing: 0.03em;
-}
-.room-lobby-room-id-label {
- font-weight: 600;
- font-size: clamp(0.78rem, 1.7vw, 0.9rem);
- opacity: 0.92;
-}
-#room-id-value {
- font-weight: 800;
- font-size: clamp(0.85rem, 1.9vw, 1rem);
- color: #f4fdff;
-}
-.room-lobby-room-id-lock {
- font-size: 0.85rem;
- filter: drop-shadow(0 0 6px rgba(105, 227, 255, 0.6));
-}
-
-/* มุมขวาบน — โปรไฟล์ตัวละคร */
-.room-lobby-top-right-cluster {
- position: fixed;
- top: max(12px, env(safe-area-inset-top));
- right: max(12px, env(safe-area-inset-right));
- z-index: 56;
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- gap: 0.4rem;
- pointer-events: none;
-}
-.room-lobby-top-right-cluster > * {
- pointer-events: auto;
-}
-.room-lobby-top-right-actions {
- display: none !important;
-}
-.room-lobby-top-right-action-btn {
- position: relative;
- flex: 0 0 auto;
- width: clamp(100px, 11vw, 161px);
- height: auto;
- min-width: 0;
- min-height: 0;
- max-width: 161px;
- aspect-ratio: 161 / 176;
- padding: 0;
- margin: 0;
- border: none;
- border-radius: 0;
- background: transparent;
- box-shadow: none;
- cursor: pointer;
- overflow: visible;
- isolation: isolate;
-}
-.room-lobby-top-right-action-btn img {
- width: 100%;
- height: auto;
- max-width: 161px;
- aspect-ratio: 161 / 176;
- object-fit: contain;
- display: block;
- pointer-events: none;
- user-select: none;
- -webkit-user-drag: none;
-}
-.room-lobby-profile-wrap {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 0.2rem;
-}
-.room-lobby-profile-frame {
- position: relative;
- width: 159px;
- height: 157px;
- min-width: 159px;
- min-height: 157px;
- max-width: 159px;
- max-height: 157px;
- aspect-ratio: 159 / 157;
- border-radius: 0;
- border: none;
- overflow: hidden;
- background: url(../img/btn-profile-bg.png) center/100% 100% no-repeat;
- box-shadow: none;
-}
-.room-lobby-profile-avatar-viewport {
- position: absolute;
- left: 12px;
- top: 10px;
- width: 124px;
- height: 118px;
- overflow: hidden;
- border-radius: 12px;
-}
-.room-lobby-profile-frame #room-lobby-profile-avatar {
- position: absolute;
- left: 50%;
- top: 5px;
- display: block;
- width: 120%;
- height: auto;
- max-width: none;
- object-fit: contain;
- object-position: center top;
- transform: translateX(-50%);
- transform-origin: center center;
- image-rendering: pixelated;
- image-rendering: crisp-edges;
-}
-.room-lobby-profile-set-btn {
- position: absolute;
- right: 0;
- bottom: 0;
- width: 71px;
- height: 71px;
- min-width: 71px;
- min-height: 71px;
- max-width: 71px;
- max-height: 71px;
- aspect-ratio: 71 / 71;
- padding: 0;
- margin: 0;
- border: none;
- border-radius: 0;
- background: transparent;
- cursor: pointer;
- z-index: 2;
-}
-.room-lobby-profile-set-btn img {
- display: block;
- width: 71px;
- height: 71px;
- min-width: 71px;
- min-height: 71px;
- max-width: 71px;
- max-height: 71px;
- aspect-ratio: 71 / 71;
- object-fit: contain;
-}
-
-/* Profile overlay — see profile-popup.css (linked from room-lobby.html) */
-
-
-/* Host Console popup */
-.room-lobby-host-console-overlay {
- position: fixed;
- inset: 0;
- z-index: 10070;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
-}
-.room-lobby-host-console-overlay.is-hidden {
- display: none !important;
-}
-.room-lobby-host-console-backdrop {
- position: absolute;
- inset: 0;
- background: rgba(0, 0, 0, 0.8);
-}
-.room-lobby-host-console-dialog {
- position: relative;
- z-index: 1;
- width: min(990px, calc(100vw - 24px), calc((100dvh - 24px) * (990 / 881)));
- aspect-ratio: 990 / 881;
- max-height: calc(100dvh - 24px);
- --hc-scale: 1;
- --hc-close-hit-size: calc(82px * var(--hc-scale));
- --hc-close-hit-top: 9%;
- --hc-close-hit-right: 6.5%;
- background: url(../img/03-4-Host-Console/host-console-bg.png) center/100% 100% no-repeat;
- box-sizing: border-box;
-}
-.room-lobby-host-console-body {
- position: absolute;
- top: 13.6%;
- right: 7.9%;
- bottom: 6%;
- left: 8.2%;
- display: flex;
- flex-direction: column;
- align-items: center;
- min-height: 0;
- padding-top: calc(50px * var(--hc-scale));
- padding-bottom: calc(62px * var(--hc-scale));
- box-sizing: border-box;
-}
-.room-lobby-host-console-close {
- position: absolute;
- top: var(--hc-close-hit-top);
- right: var(--hc-close-hit-right);
- width: var(--hc-close-hit-size);
- height: var(--hc-close-hit-size);
- border: none;
- border-radius: 0;
- background: transparent;
- color: transparent;
- font-size: 0;
- line-height: 1;
- cursor: pointer;
- text-shadow: none;
- z-index: 3;
- -webkit-tap-highlight-color: transparent;
-}
-.room-lobby-host-console-txt-img {
- width: auto;
- object-fit: contain;
- display: block;
-}
-.room-lobby-host-console-txt-max {
- height: calc(66px * var(--hc-scale));
- margin-bottom: calc(10px * var(--hc-scale));
-}
-.room-lobby-host-console-max-wrap {
- position: relative;
- width: min(82%, calc(657px * var(--hc-scale)));
- aspect-ratio: 657 / 141;
- margin-bottom: calc(-10px * var(--hc-scale));
- margin-top: calc(-30px * var(--hc-scale));
-}
-.room-lobby-host-console-textfield-bg {
- width: 100%;
- height: 100%;
- object-fit: contain;
- display: block;
-}
-.room-lobby-host-console-arrow-btn {
- position: absolute;
- top: 50%;
- width: calc(51px * var(--hc-scale));
- height: calc(54px * var(--hc-scale));
- padding: 0;
- margin: 0;
- border: none;
- border-radius: 0;
- background: transparent;
- cursor: pointer;
- transform: translateY(-50%);
-}
-.room-lobby-host-console-arrow-left { left: 4.9%; }
-.room-lobby-host-console-arrow-right { right: 4.9%; }
-.room-lobby-host-console-arrow-btn img {
- width: 100%;
- height: 100%;
- object-fit: contain;
- display: block;
-}
-.room-lobby-host-console-max-value {
- position: absolute;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
- min-width: 2ch;
- text-align: center;
- font-size: calc(40px * var(--hc-scale));
- font-weight: 700;
- color: #eaf9ff;
- text-shadow: 0 0 10px rgba(0, 255, 255, 0.35);
-}
-.room-lobby-host-console-summary {
- margin: 0 0 calc(12px * var(--hc-scale));
- font-size: calc(24px * var(--hc-scale));
- color: #d9f3ff;
- margin-bottom: 4%;
-}
-.room-lobby-host-console-line {
- width: min(94%, calc(744px * var(--hc-scale)));
- height: auto;
- margin-bottom: calc(10px * var(--hc-scale));
- object-fit: contain;
-}
-.room-lobby-host-console-txt-members {
- height: calc(61px * var(--hc-scale));
- margin-bottom: calc(8px * var(--hc-scale));
-}
-.room-lobby-host-console-members {
- width: min(84%, calc(694px * var(--hc-scale)));
- flex: 1 1 auto;
- min-height: 0;
- overflow-x: hidden;
- overflow-y: scroll;
- padding-right: calc(40px * var(--hc-scale));
- padding-left: calc(35px * var(--hc-scale));
- scrollbar-width: auto;
- scrollbar-color: rgba(255, 104, 228, 0.98) rgba(20, 40, 70, 0.55);
- scrollbar-gutter: stable both-edges;
-}
-.room-lobby-host-console-members::-webkit-scrollbar {
- width: clamp(24px, calc(36px * var(--hc-scale)), 42px);
-}
-.room-lobby-host-console-members::-webkit-scrollbar-track {
- background: rgba(20, 40, 70, 0.55);
- border-radius: 999px;
- border: 1px solid rgba(90, 220, 255, 0.35);
-}
-.room-lobby-host-console-members::-webkit-scrollbar-thumb {
- background: linear-gradient(180deg, rgba(255, 125, 236, 1) 0%, rgba(241, 74, 215, 1) 100%);
- border-radius: 999px;
- border: 3px solid rgba(16, 32, 56, 0.65);
- background-clip: padding-box;
- box-shadow: 0 0 10px rgba(255, 84, 226, 0.45);
-}
-.room-lobby-host-console-members-list {
- list-style: none;
- margin: 0;
- padding: 0;
- display: flex;
- flex-direction: column;
- gap: calc(18px * var(--hc-scale));
-}
-.room-lobby-host-console-member-item {
- position: relative;
- min-height: calc(44px * var(--hc-scale));
- padding: calc(2px * var(--hc-scale)) calc(104px * var(--hc-scale)) calc(2px * var(--hc-scale)) calc(12px * var(--hc-scale));
- display: flex;
- align-items: center;
- justify-content: flex-start;
- gap: 0.6rem;
- color: #e9f8ff;
- font-size: calc(28px * var(--hc-scale));
- background: url(../img/03-4-Host-Console/host-console-line-2.png) left bottom/100% 3px no-repeat;
-}
-.room-lobby-host-console-member-item.is-host {
- min-height: calc(80px * var(--hc-scale));
- padding-right: calc(12px * var(--hc-scale));
- background: url(../img/03-4-Host-Console/host-console-hostname.png) center/100% 100% no-repeat;
- font-weight: 700;
-}
-.room-lobby-host-console-member-name {
- min-width: 0;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- color: inherit;
- padding-left: 4%;
- margin-top: -4%;
-}
-.room-lobby-host-console-member-item.is-host .room-lobby-host-console-member-name {
- margin-top: 0%; /* เพิ่มค่านี้ = ขยับลง */
-}
-.room-lobby-host-console-delete-btn {
- position: absolute;
- right: calc(10px * var(--hc-scale));
- top: 50%;
- transform: translateY(-50%);
- width: calc(84px * var(--hc-scale));
- height: calc(84px * var(--hc-scale));
- min-width: calc(84px * var(--hc-scale));
- padding: 0;
- border: none;
- border-radius: 0;
- background: transparent;
- cursor: pointer;
- margin-top: -2%;
- margin-right: -1%;
-}
-.room-lobby-host-console-delete-btn img {
- width: 100%;
- height: 100%;
- object-fit: contain;
- display: block;
-}
-.room-lobby-host-console-delete-btn:disabled {
- opacity: 0.35;
- cursor: default;
-}
-.room-lobby-host-console-confirm {
- position: absolute;
- left: 50%;
- bottom: calc(-60px * var(--hc-scale));
- transform: translateX(-50%);
- width: min(43%, calc(350px * var(--hc-scale)));
- aspect-ratio: 350 / 129;
- border: none;
- border-radius: 0;
- padding: 0;
- background: transparent;
- cursor: pointer;
-}
-.room-lobby-host-console-confirm img {
- width: 100%;
- height: 100%;
- object-fit: contain;
- display: block;
-}
-/* Profile popup: tightened scaling for reduced viewports */
-@media (max-width: 1100px), (max-height: 700px) {
- .room-lobby-profile-content {
- top: 13%;
- right: 4%;
- bottom: 8%;
- left: 4%;
- gap: clamp(8px, 1vw, 14px);
- grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.12fr);
- }
- .room-lobby-profile-left-pane {
- grid-template-rows: minmax(0, 1fr) auto;
- row-gap: clamp(3px, 0.5vw, 6px);
- }
- .room-lobby-profile-logout {
- width: min(58%, 100%);
- }
- .room-lobby-profile-char-card #room-lobby-profile-overlay-avatar {
- width: 74%;
- max-width: 74%;
- max-height: 60%;
- }
-}
-@media (max-width: 900px), (max-height: 560px) {
- .room-lobby-profile-content {
- top: 11%;
- right: 3%;
- bottom: 7%;
- left: 3%;
- gap: 8px;
- grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.08fr);
- }
- .room-lobby-profile-logout {
- width: min(62%, 100%);
- }
- .room-lobby-profile-char-card #room-lobby-profile-overlay-avatar {
- width: 64%;
- max-width: 64%;
- max-height: 56%;
- }
-}
-.room-lobby-actions { margin-top: 1rem; display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; }
-.room-lobby-actions .room-lobby-btn-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0; opacity: 0; pointer-events: none; }
-.room-lobby-actions label { margin: 0; }
-.room-lobby-actions #btn-start { background: #9ece6a; color: #1a1b26; }
-#host-only { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; }
-#host-only select { padding: 0.4rem 0.6rem; border-radius: 6px; border: 1px solid #414868; background: #24283b; color: #c0caf5; }
-.host-start-area-hint {
- flex-basis: 100%;
- margin: 0;
- font-size: 0.88rem;
- color: #e0af68;
- line-height: 1.35;
- max-width: 100%;
-}
-#host-only #btn-start:disabled {
- opacity: 0.5;
- cursor: not-allowed;
- filter: grayscale(0.25);
-}
-.room-lobby-chat { margin-top: 1rem; }
-.room-lobby-chat.chat-panel {
- border-radius: 12px;
- overflow: hidden;
- box-shadow: none;
-}
-.room-lobby-chat-peers.chat-panel {
- position: fixed;
- right: 0.25rem;
- bottom: 10rem;
- width: 576px;
- height: 525px;
- max-width: calc(100vw - 2.5rem);
- z-index: 52;
- margin-top: 0;
- display: flex;
- flex-flow: column;
- padding: 2rem;
- box-sizing: border-box;
- border-top: 0px solid #414868;
- background: url(../img/chat-msg-bg-alpha.png) center/100% 100% no-repeat;
- background-color: transparent;
-}
-.room-lobby-chat-peers.chat-panel .chat-header-title.chat-header-title-img img { width: 90px; height: 77px; }
-.room-lobby-chat-peers.chat-panel .chat-close-btn { width: 48px; height: 48px; }
-.room-lobby-chat-peers.chat-panel .chat-close-btn img { width: 50px; height: 50px; }
-.room-lobby-chat-peers.chat-panel #chat-messages { padding: 0.75rem; font-size: 1.05rem; gap: 0.5rem; }
-.room-lobby-chat-peers.chat-panel .chat-form-bar { padding: 0.6rem 0; gap: 0.5rem; }
-.room-lobby-chat-peers.chat-panel #chat-input { padding: 0.6rem 0.85rem; font-size: 1.05rem; }
-.room-lobby-chat-peers.chat-panel .chat-send-btn { width: 52px; height: 52px; }
-.room-lobby-chat-peers.chat-panel .chat-send-btn img { width: 58px; height: 58px; }
-.room-lobby-chat-peers.chat-panel .chat-msg { padding: 0.6rem 1rem; font-size: 1.05rem; }
-.room-lobby-chat-peers.chat-panel .chat-header-bar {
- margin: 0 -2rem 0 -2rem;
- padding-left: 2rem;
- padding-right: 2rem;
- justify-content: space-between;
- align-items: center;
- min-height: 72px;
- height: 72px;
-}
-.room-lobby-chat-peers.chat-panel #chat-messages {
- flex: 1;
- min-height: 0;
- height: auto;
-}
-.room-lobby-chat .chat-header-bar {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0;
- min-height: 48px;
- height: 48px;
- background: url(../img/chat-line.png) bottom repeat-x;
- background-size: 100% 4px;
- background-color: transparent;
-}
-.room-lobby-chat-peers .chat-header-title.chat-header-title-img {
- display: inline-flex;
- align-items: center;
- line-height: 0;
-}
-.room-lobby-chat-peers .chat-header-title.chat-header-title-img img {
- width: 60px;
- height: 51px;
- object-fit: contain;
- display: block;
-}
-.room-lobby-chat-ai .chat-header-title.chat-header-title-img {
- display: flex;
- align-items: flex-end;
- gap: 0.5rem;
- line-height: 0;
- min-width: 0;
- overflow: visible;
-}
-.room-lobby-chat-ai .chat-header-title.chat-header-title-img .ai-chat-title-label {
- height: 64px;
- width: auto;
- max-width: none;
- object-fit: contain;
- display: block;
- flex-shrink: 0;
- margin-bottom: -2px;
-}
-/* รูปหัวแชท AI — ยกขึ้นเหนือเส้น */
-.room-lobby-chat-ai .chat-header-title.chat-header-title-img img {
- width: 86px;
- height: 92px;
- object-fit: cover;
- display: block;
- flex-shrink: 0;
- margin-top: -27px;
- margin-left: -6px;
- position: relative;
- z-index: 1;
-}
-.room-lobby-chat .chat-header-title {
- font-size: 1rem;
- font-weight: 600;
- color: #a0aec0;
-}
-.room-lobby-chat .chat-close-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 32px;
- height: 32px;
- padding: 0;
- border: none;
- border-radius: 8px;
- background: transparent;
- cursor: pointer;
- margin-left: auto;
-}
-.room-lobby-chat-peers .chat-header-bar .chat-close-btn { margin-left: 0; }
-.room-lobby-chat .chat-close-btn img { width: 34px; height: 34px; object-fit: contain; }
-.room-lobby-chat .chat-close-btn:hover { opacity: 0.9; }
-.room-lobby-chat.chat-panel-collapsed #chat-messages,
-.room-lobby-chat.chat-panel-collapsed .chat-form-bar { display: none !important; }
-.room-lobby-chat-peers.chat-panel-collapsed .chat-header-title { display: none !important; }
-.room-lobby-chat-peers.chat-panel-collapsed .chat-header-bar {
- justify-content: center;
- padding: 0;
- background: none !important;
- border: none;
-}
-.room-lobby-chat-peers.chat-panel-collapsed.chat-panel {
- width: 80px;
- height: 80px;
- min-height: 0;
- padding: 0;
- right: 1.25rem;
- bottom: 6.25rem;
- display: flex;
- align-items: center;
- justify-content: center;
- background: none !important;
- background-color: transparent !important;
- border: none;
- box-shadow: none;
-}
-.room-lobby-chat-peers.chat-panel-collapsed .chat-close-btn {
- width: 80px;
- height: 80px;
- overflow: visible;
-}
-.room-lobby-chat-peers.chat-panel-collapsed .chat-close-btn img {
- width: 100%;
- height: 100%;
- object-fit: contain;
- object-position: center;
- display: block;
-}
-.room-lobby-chat #chat-messages,
-.room-lobby-chat #ai-chat-messages {
- height: 100px;
- overflow-y: auto;
- padding: 0.5rem;
- font-size: 0.85rem;
- border: none;
- margin: 0;
- display: flex;
- flex-direction: column;
- gap: 0.35rem;
- background: none;
- background-color: transparent;
- box-shadow: none;
-}
-.room-lobby-chat .chat-messages-bg { border-radius: 0; }
-.room-lobby-chat #chat-form.chat-form-bar,
-.room-lobby-chat #ai-chat-form.chat-form-bar {
- display: flex;
- gap: 0.4rem;
- align-items: center;
- padding: 0.4rem 0;
- background: none;
- background-color: transparent;
- border-top: none;
- flex-shrink: 0;
-}
-.room-lobby-chat-peers .chat-form-bar {
- padding-left: 0;
- padding-right: 0;
-}
-.room-lobby-chat #chat-input,
-.room-lobby-chat #ai-chat-input {
- flex: 1;
- min-width: 0;
- padding: 0.45rem 0.6rem;
- border-radius: 10px;
- border: 1px solid rgba(0, 212, 255, 0.25);
- background: rgba(30, 35, 50, 0.8);
- color: #c0caf5;
- font-size: 0.9rem;
- box-sizing: border-box;
- margin-left: 9px;
-}
-.room-lobby-chat .chat-send-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 40px;
- height: 40px;
- flex-shrink: 0;
- padding: 0;
- border: none;
- border-radius: 10px;
- background: transparent;
- cursor: pointer;
-}
-.room-lobby-chat .chat-send-btn img { width: 45px; height: 45px; object-fit: contain; }
-.room-lobby-chat .chat-send-btn:hover { opacity: 0.9; }
-.room-lobby-chat .chat-msg {
- padding: 0.4rem 0.75rem;
- border-radius: 12px;
- max-width: 85%;
- background-size: 100% 100%;
- background-repeat: no-repeat;
- background-position: center;
-}
-.room-lobby-chat .chat-msg-mine {
- align-self: flex-end;
- text-align: right;
- background-image: url(../img/chat-bubble-me.png);
- background-color: rgba(122, 162, 247, 0.9);
- color: #1a1b26;
-}
-.room-lobby-chat .chat-msg-other {
- align-self: flex-start;
- text-align: left;
- background-image: url(../img/chat-bubble-friend.png);
- background-color: rgba(65, 72, 104, 0.9);
- color: #c0caf5;
-}
-.room-lobby-chat .chat-msg-ai {
- align-self: flex-start;
- text-align: left;
- background-image: url(../img/chat-bubble-friend.png);
- background-color: rgba(158, 206, 106, 0.9);
- color: #1a1b26;
-}
-.room-lobby-chat .chat-msg-system {
- align-self: center;
- text-align: center;
- max-width: 95%;
- background-image: none;
- background-color: rgba(26, 27, 38, 0.72);
- color: #9aa5ce;
- font-size: 0.88rem;
- font-style: italic;
- padding: 0.35rem 0.6rem;
-}
-
-/* AI chat — loading แบบ Messenger (จุดกระโดด 3 จุด), อยู่ติดข้อความล่าสุดในลิสต์ */
-.room-lobby-chat .ai-chat-typing {
- display: flex;
- align-items: center;
- gap: 4px;
- padding: 12px 14px;
- min-height: 24px;
- flex-shrink: 0;
- background-image: url(../img/chat-bubble-friend.png);
- background-color: rgba(158, 206, 106, 0.9);
- background-size: 100% 100%;
- background-repeat: no-repeat;
- background-position: center;
-}
-.room-lobby-chat .ai-typing-dot {
- width: 6px;
- height: 6px;
- border-radius: 50%;
- background: #1a1b26;
- animation: ai-typing-bounce 1.4s ease-in-out infinite both;
-}
-.room-lobby-chat .ai-typing-dot:nth-child(1) { animation-delay: 0s; }
-.room-lobby-chat .ai-typing-dot:nth-child(2) { animation-delay: 0.2s; }
-.room-lobby-chat .ai-typing-dot:nth-child(3) { animation-delay: 0.4s; }
-@keyframes ai-typing-bounce {
- 0%, 60%, 100% { transform: translateY(0); }
- 30% { transform: translateY(-6px); }
-}
-
-/* AI chat panel — match Main-Lobby lobby-ai-chat-panel */
-.room-lobby-chat-ai.chat-panel {
- position: fixed;
- left: 8px;
- right: auto;
- bottom: clamp(0.5rem, 2vw, 1rem);
- width: 454px;
- height: 526px;
- max-width: calc(100vw - 2.5rem);
- z-index: 51;
- margin: 0;
- display: flex;
- flex-flow: column;
- box-sizing: border-box;
- padding: 2.6rem;
- overflow: visible;
- background: url(../img/chat-msg-bg-alpha.png) center/100% 100% no-repeat;
- background-color: transparent;
- border: none;
- box-shadow: none;
- border-radius: 12px;
- pointer-events: none;
-}
-.room-lobby-chat-ai.chat-panel .chat-header-bar,
-.room-lobby-chat-ai.chat-panel #ai-chat-messages,
-.room-lobby-chat-ai.chat-panel #ai-chat-form,
-.room-lobby-chat-ai.chat-panel .ai-chat-admin-link {
- pointer-events: auto;
-}
-.room-lobby-chat-ai.chat-panel .chat-header-bar {
- margin: 0 -2rem 0 -2rem;
- padding: 0 1rem;
- justify-content: space-between;
- align-items: center;
- min-height: 50px;
- height: 50px;
- overflow: visible;
- background: url(../img/AI-chat-line.png) bottom repeat-x;
- background-size: 100% 3px;
- background-color: transparent;
-}
-.room-lobby-chat-ai.chat-panel .chat-header-title.chat-header-title-img img {
- width: 100px;
- height: 116px;
- margin-top: -39px;
- margin-left: 16px;
- object-fit: cover;
- position: relative;
- z-index: 1;
-}
-.room-lobby-chat-ai.chat-panel .chat-header-title.chat-header-title-img .ai-chat-title-label {
- height: 80px;
- width: auto;
- max-width: none;
- margin-bottom: -4px;
- margin-left: -5px;
- transform: translateX(-6px);
-}
-.room-lobby-chat-ai.chat-panel .chat-close-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 60px;
- height: 60px;
- padding: 0;
- border: none;
- border-radius: 8px;
- background: transparent;
- cursor: pointer;
- margin-left: auto;
-}
-.room-lobby-chat-ai.chat-panel .chat-close-btn img {
- width: 60px;
- height: 60px;
- object-fit: contain;
-}
-.room-lobby-chat-ai.chat-panel .chat-close-btn:hover {
- opacity: 0.9;
-}
-.room-lobby-chat-ai.chat-panel #ai-chat-messages {
- flex: 1;
- min-height: 0;
- height: auto;
- overflow-y: auto;
- padding: 0.2rem 0.35rem 0.25rem 0;
- font-size: 1.05rem;
- gap: 0.5rem;
- background: none;
- border: none;
- scrollbar-width: thin;
- scrollbar-color: rgba(244, 252, 255, 0.98) rgba(53, 110, 167, 0.28);
-}
-.room-lobby-chat-ai.chat-panel #ai-chat-messages::-webkit-scrollbar {
- width: 1rem;
- scrollbar-width: auto;
-}
-.room-lobby-chat-ai.chat-panel #ai-chat-messages::-webkit-scrollbar-track {
- border-radius: 999px;
- background: linear-gradient(180deg, rgba(38, 77, 125, 0.45) 0%, rgba(32, 66, 106, 0.38) 100%);
- box-shadow: inset 0 0 0 1px rgba(107, 193, 255, 0.25);
-}
-.room-lobby-chat-ai.chat-panel #ai-chat-messages::-webkit-scrollbar-thumb {
- border-radius: 999px;
- background: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(221, 244, 255, 0.96) 100%);
- box-shadow:
- 0 0 10px rgba(169, 239, 255, 0.55),
- inset 0 0 0 1px rgba(180, 235, 255, 0.9);
-}
-.room-lobby-chat-ai.chat-panel .chat-form-bar {
- display: flex;
- gap: 0;
- align-items: center;
- padding: 0.6rem 0;
- flex-shrink: 0;
- background: none;
- border: none;
- width: calc(100% + 3rem);
- margin-left: 0;
- margin-right: 0;
-}
-.room-lobby-chat-ai.chat-panel #ai-chat-input {
- flex: 0.85;
- min-width: 0;
- min-height: 50px;
- padding: 0.6rem 0.85rem;
- border-radius: 8px;
- border: 1px solid rgba(0, 212, 255, 0.32);
- background: rgba(30, 35, 50, 0.55);
- color: #c0caf5;
- font-size: 1.05rem;
- margin: 0;
-}
-.room-lobby-chat-ai.chat-panel .chat-send-btn {
- width: 73px;
- height: 73px;
- margin-left: 0;
- margin-right: -0.7rem;
-}
-.room-lobby-chat-ai.chat-panel .chat-send-btn img {
- width: 102px;
- height: 98px;
- object-fit: contain;
-}
-.room-lobby-chat-ai.chat-panel .chat-send-btn:focus,
-.room-lobby-chat-ai.chat-panel .chat-send-btn:focus-visible {
- outline: none !important;
- box-shadow: none !important;
- border-color: transparent !important;
-}
-.room-lobby-chat-ai.chat-panel .chat-msg {
- padding: 0.58rem 0.92rem;
- font-size: 1.05rem;
- line-height: 1.33;
- border: none;
- box-shadow: none;
-}
-.room-lobby-chat-ai.chat-panel .chat-msg-mine {
- background-color: rgba(122, 162, 247, 0.2);
- color: #f787e4;
-}
-.room-lobby-chat-ai.chat-panel .chat-msg-ai {
- background-color: rgba(158, 206, 106, 0.2);
- color: #f2f8ff;
-}
-.room-lobby-chat-ai.chat-panel .ai-chat-typing {
- padding: 14px 18px;
- min-height: 28px;
- background-color: rgba(158, 206, 106, 0.32);
-}
-.room-lobby-chat-ai.chat-panel .ai-typing-dot {
- width: 8px;
- height: 8px;
- background: #f2f8ff;
-}
-.room-lobby-chat-ai.chat-panel .ai-chat-admin-link {
- margin: 0.35rem 0 0 0;
- font-size: 0.75rem;
- flex-shrink: 0;
-}
-.room-lobby-chat-ai.chat-panel,
-.room-lobby-chat-ai.chat-panel #ai-chat-messages,
-.room-lobby-chat-ai.chat-panel #ai-chat-input,
-.room-lobby-chat-ai.chat-panel .chat-msg,
-.room-lobby-chat-ai.chat-panel .ai-chat-typing,
-.room-lobby-chat-ai.chat-panel .chat-send-btn,
-.room-lobby-chat-ai.chat-panel .ai-chat-admin-link,
-.room-lobby-chat-ai.chat-panel .ai-chat-admin-link a {
- font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif !important;
-}
-.room-lobby-chat-ai.chat-panel #ai-chat-messages,
-.room-lobby-chat-ai.chat-panel #ai-chat-messages * {
- font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif !important;
-}
-.room-lobby-chat-ai.chat-panel #ai-chat-input::placeholder {
- font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif !important;
-}
-
-/* Host console: force NotoSansThai for highlighted text areas */
-.room-lobby-host-console-summary,
-.room-lobby-host-console-member-item,
-.room-lobby-host-console-member-name,
-.room-lobby-host-console-max-value {
- font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif !important;
-}
-
-/* AI chat collapsed — match Main-Lobby lobby-btn-ai-chat style */
-.room-lobby-chat-ai.chat-panel-collapsed #ai-chat-messages,
-.room-lobby-chat-ai.chat-panel-collapsed .chat-form-bar,
-.room-lobby-chat-ai.chat-panel-collapsed .ai-chat-admin-link { display: none !important; }
-.room-lobby-chat-ai.chat-panel-collapsed .chat-header-title { display: none !important; }
-.room-lobby-chat-ai.chat-panel-collapsed .chat-header-bar {
- justify-content: center;
- padding: 0;
- background: none !important;
- border: none;
- min-height: 0;
- height: auto;
-}
-.room-lobby-chat-ai.chat-panel-collapsed.chat-panel {
- width: 213px;
- max-width: 213px;
- height: 201px;
- min-height: 201px;
- padding: 0;
- left: max(1.25rem, env(safe-area-inset-left));
- bottom: clamp(0.5rem, 2vw, 1rem);
- display: flex;
- align-items: center;
- justify-content: center;
- background: none !important;
- background-color: transparent !important;
- border: none;
- box-shadow: none;
-}
-.room-lobby-chat-ai.chat-panel-collapsed .chat-close-btn {
- width: 213px;
- height: 201px;
- min-width: 213px;
- min-height: 201px;
- max-width: 213px;
- max-height: 201px;
- aspect-ratio: 213 / 201;
- overflow: visible;
- border-radius: 0;
- margin-left: 0;
-}
-.room-lobby-chat-ai.chat-panel-collapsed .chat-close-btn img {
- width: 213px;
- height: 201px;
- min-width: 213px;
- min-height: 201px;
- max-width: 213px;
- max-height: 201px;
- aspect-ratio: 213 / 201;
- object-fit: contain;
- object-position: center;
- display: block;
-}
-
-.room-lobby-exit-fixed {
- position: static;
- display: flex;
- flex-direction: row;
- flex-wrap: nowrap;
- align-items: center;
- justify-content: flex-start;
- gap: 10px;
- width: max-content;
- max-width: calc(100vw - 24px);
- box-sizing: border-box;
-}
-.room-lobby-exit-fixed .btn-exit-icon {
- display: flex;
- align-items: center;
- justify-content: center;
- flex: 0 0 auto;
- margin: 0;
- width: clamp(58px, 9vw, 72px);
- height: clamp(58px, 9vw, 72px);
- min-width: clamp(58px, 9vw, 72px);
- padding: 0;
- border: none;
- border-radius: 0;
- background: transparent;
- box-shadow: none;
- cursor: pointer;
-}
-.room-lobby-exit-fixed .btn-exit-icon:hover {
- transform: translateY(-1px);
- filter: brightness(1.08);
-}
-.room-lobby-exit-fixed .btn-exit-icon img {
- width: 100%;
- height: auto;
- object-fit: contain;
- display: block;
-}
-
-.room-lobby-ready-fixed {
- position: fixed;
- bottom: max(2rem, env(safe-area-inset-bottom));
- left: 50%;
- transform: translateX(-50%);
- z-index: 120;
- pointer-events: none;
-}
-.room-lobby-ready-fixed .ready-label,
-.room-lobby-ready-fixed .ready-check-input {
- pointer-events: auto;
-}
-.room-lobby-ready-fixed .ready-label {
- position: relative;
- display: inline-block;
- padding: 0;
- margin: 0;
- border: none;
- border-radius: 0;
- background: transparent;
- box-shadow: none;
- cursor: pointer;
- transition: transform 0.15s ease, filter 0.15s ease;
- line-height: 0;
- filter: drop-shadow(0 10px 20px rgba(0, 0, 0, 0.42));
-}
-.room-lobby-ready-fixed .ready-label:hover {
- transform: scale(1.04);
- filter: brightness(1.08);
-}
-.room-lobby-ready-fixed .ready-label:active {
- transform: scale(0.98);
-}
-.room-lobby-ready-fixed .ready-check-input {
- position: absolute;
- inset: 0;
- width: 100%;
- height: 100%;
- margin: 0;
- opacity: 0;
- cursor: pointer;
- z-index: 2;
-}
-.room-lobby-ready-fixed .ready-label-img {
- display: block;
- height: clamp(44px, 8vh, 72px);
- width: auto;
- max-width: min(240px, 78vw);
- pointer-events: none;
- user-select: none;
- -webkit-user-drag: none;
-}
-.room-lobby-ready-fixed .ready-label--active .ready-label-img {
- filter: drop-shadow(0 0 10px rgba(158, 206, 106, 0.45));
-}
-body.room-lobby-page #room-players-hud {
- top: max(10px, env(safe-area-inset-top)) !important;
- min-width: 0;
- border-radius: 0;
- border: none;
- background: transparent;
- box-shadow: none;
- backdrop-filter: none;
- color: #e3f6ff !important;
- font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif !important;
- text-transform: none;
- letter-spacing: 0.08em;
- text-shadow:
- 0 2px 0 rgba(0, 0, 0, 0.8),
- 0 0 12px rgba(0, 0, 0, 0.55);
- text-align: center;
-}
-
-/* มุมขวาล่าง — ไมค์ทุกห้อง + ปุ่ม LobbyB (แว่น/ถ้วย) */
-.room-lobby-br-fixed {
- --lobby-br-btn: 80px;
- position: fixed;
- bottom: max(0.95rem, env(safe-area-inset-bottom));
- right: max(1.25rem, env(safe-area-inset-right));
- z-index: 400;
- display: flex;
- flex-direction: row;
- align-items: flex-end;
- gap: 10px;
- pointer-events: none;
-}
-.room-lobby-br-fixed .lobby-b-extra-row,
-.room-lobby-br-fixed .btn-voice-icon {
- pointer-events: auto;
-}
-.lobby-b-extra-row {
- display: flex;
- flex-direction: row;
- align-items: flex-end;
- gap: 10px;
-}
-.lobby-b-extra-row.is-hidden {
- display: none !important;
-}
-/* โหมดเกม (ควิซ) ใน room-lobby — ไม่โชว์แว่น/ถ้วย LobbyB */
-body.room-lobby--quiz-active .lobby-b-extra-row {
- display: none !important;
- visibility: hidden !important;
- pointer-events: none !important;
-}
-/* ปุ่มมุมขวาล่าง — ขนาดเดียวกัน (กัน UA border / box model ต่างกัน) */
-.room-lobby-br-fixed .lobby-b-sq-btn,
-.room-lobby-br-fixed .btn-voice-icon {
- box-sizing: border-box;
- width: var(--lobby-br-btn);
- height: var(--lobby-br-btn);
- min-width: var(--lobby-br-btn);
- min-height: var(--lobby-br-btn);
- max-width: var(--lobby-br-btn);
- max-height: var(--lobby-br-btn);
- margin: 0;
- padding: 0;
- border: none;
- border-radius: 0;
- appearance: none;
- -webkit-appearance: none;
- flex-shrink: 0;
- cursor: pointer;
- background: transparent;
- box-shadow: none;
-}
-/* สไตล์เดียวกับปุ่มไมค์ — ไม่มีกรอบ cyan / bg-item */
-.lobby-b-sq-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- transition: transform 0.15s ease, filter 0.15s ease;
-}
-.lobby-b-sq-btn:hover {
- transform: scale(1.04);
- filter: brightness(1.08);
-}
-.lobby-b-sq-btn:active { transform: scale(0.98); }
-.room-lobby-br-fixed .lobby-b-sq-btn img,
-.room-lobby-br-fixed .btn-voice-icon img {
- width: 100%;
- height: 100%;
- max-width: 100%;
- max-height: 100%;
- object-fit: contain;
- object-position: center;
- display: block;
- pointer-events: none;
- user-select: none;
- -webkit-user-drag: none;
-}
-.room-lobby-br-fixed .btn-voice-icon {
- display: flex;
- align-items: center;
- justify-content: center;
- background: transparent;
-}
-
-/* Desktop tuning: keep controls visibly large and readable */
-@media (min-width: 1024px) {
- .room-lobby-chat-peers.chat-panel {
- right: 0.9rem;
- bottom: 11rem;
- width: 454px;
- height: 414px;
- padding: 1.7rem 1.45rem 1.15rem;
- border-radius: 0;
- background: url(../img/chat-bg.png) center/100% 100% no-repeat;
- border: none;
- box-shadow: none;
- backdrop-filter: none;
- }
- .room-lobby-chat-peers.chat-panel .chat-header-bar {
- margin: 0;
- padding: 0 0.15rem;
- min-height: 58px;
- height: 58px;
- background: url(../img/chat-line.png) left bottom / 375px 4px no-repeat;
- box-shadow: none;
- }
- .room-lobby-chat-peers.chat-panel .chat-header-title.chat-header-title-img img {
- display: block;
- width: 90px;
- height: 77px;
- object-fit: contain;
- }
- .room-lobby-chat-peers.chat-panel .chat-header-title.chat-header-title-img::before {
- content: none;
- display: none;
- }
- .room-lobby-chat-peers.chat-panel .chat-close-btn {
- width: 58px;
- height: 58px;
- min-width: 58px;
- min-height: 58px;
- max-width: 58px;
- max-height: 58px;
- margin-left: auto;
- }
- .room-lobby-chat-peers.chat-panel .chat-close-btn img {
- width: 58px;
- height: 58px;
- object-fit: contain;
- }
- .room-lobby-chat-peers.chat-panel #chat-messages {
- width: calc(100% - 16px);
- margin-right: 16px;
- padding: 0.35rem 0.7rem 0.25rem 0.15rem;
- font-size: 1rem;
- line-height: 1.42;
- gap: 0.42rem;
- margin-top: 0.15rem;
- margin-bottom: 0.2rem;
- scrollbar-width: auto;
- scrollbar-color: rgba(250, 253, 255, 0.98) rgba(12, 26, 47, 0.45);
- box-sizing: border-box;
- }
- .room-lobby-chat-peers.chat-panel #chat-messages::-webkit-scrollbar {
- width: 15px;
- }
- .room-lobby-chat-peers.chat-panel #chat-messages::-webkit-scrollbar-track {
- border-radius: 999px;
- background: rgba(20, 44, 72, 0.45);
- border: 1px solid rgba(124, 221, 255, 0.3);
- }
- .room-lobby-chat-peers.chat-panel #chat-messages::-webkit-scrollbar-thumb {
- border-radius: 999px;
- background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(241, 249, 255, 0.98) 100%);
- box-shadow: 0 0 8px rgba(182, 239, 255, 0.45);
- }
- .room-lobby-chat-peers.chat-panel .chat-msg {
- max-width: 93%;
- padding: 0.22rem 0.35rem;
- font-size: 0.98rem;
- border-radius: 10px;
- background-image: none;
- background-color: transparent;
- box-shadow: none;
- }
- .room-lobby-chat-peers.chat-panel .chat-msg-other {
- color: #d5bb63;
- font-weight: 500;
- }
- .room-lobby-chat-peers.chat-panel .chat-msg-mine {
- color: #cf74d1;
- background-color: rgba(39, 67, 112, 0.82);
- border: 1px solid rgba(116, 206, 255, 0.2);
- align-self: flex-end;
- text-align: left;
- padding: 0.32rem 0.62rem;
- }
- .room-lobby-chat-peers.chat-panel .chat-form-bar {
- padding: 0.24rem 0 0;
- gap: 0;
- align-items: center;
- justify-content: space-between;
- }
- .room-lobby-chat-peers.chat-panel #chat-input {
- margin-left: 17px;
- width: 308px;
- min-width: 308px;
- max-width: 308px;
- height: 61px;
- min-height: 61px;
- max-height: 61px;
- padding: 0 0.95rem;
- font-size: 0.95rem;
- border-radius: 0;
- border: none;
- background: url(../img/chatbox.png) center/100% 100% no-repeat;
- color: #e8f7ff;
- }
- .room-lobby-chat-peers.chat-panel #chat-input::placeholder {
- color: rgba(195, 211, 236, 0.66);
- }
- .room-lobby-chat-peers.chat-panel .chat-send-btn {
- width: 102px;
- height: 98px;
- min-width: 102px;
- min-height: 98px;
- max-width: 102px;
- max-height: 98px;
- margin-left: -26px;
- margin-right: 2px;
- }
- .room-lobby-chat-peers.chat-panel .chat-send-btn img {
- width: 102px;
- height: 98px;
- }
- .room-lobby-top-left-cluster {
- top: max(18px, env(safe-area-inset-top));
- left: max(0px, env(safe-area-inset-left));
- gap: 0;
- }
- .room-lobby-exit-fixed {
- flex-direction: column;
- align-items: flex-start;
- justify-content: flex-start;
- gap: 0.45rem;
- margin-top: -1.4rem;
- width: auto;
- max-width: none;
- }
- .room-lobby-top-right-cluster {
- top: max(16px, env(safe-area-inset-top));
- right: max(16px, env(safe-area-inset-right));
- }
- .room-lobby-room-id-pill {
- width: fit-content;
- min-width: 0;
- height: 180px;
- min-height: 180px;
- max-height: 180px;
- max-width: none;
- padding: 0 15px;
- border-style: solid;
- border-width: 0 60px;
- border-radius: 0;
- background: transparent;
- border-image-source: url("../img/Room-id-BG.png");
- border-image-slice: 0 60 0 60 fill;
- border-image-repeat: stretch;
- box-shadow: none;
- gap: 0.7rem;
- align-items: center;
- white-space: nowrap;
- }
- .room-lobby-room-id-label {
- font-size: 2.05rem;
- font-weight: 600;
- line-height: 1;
- font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif;
- text-transform: none;
- color: #e8f7ff;
- text-shadow:
- 0 0 6px rgba(110, 226, 255, 0.8),
- 0 0 14px rgba(44, 198, 255, 0.5);
- }
- #room-id-value {
- font-size: 2.35rem;
- line-height: 1;
- font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif;
- text-transform: none;
- font-weight: 600;
- color: #ecfbff;
- text-shadow:
- 0 0 7px rgba(118, 230, 255, 0.9),
- 0 0 16px rgba(52, 203, 255, 0.55);
- }
- .room-lobby-room-id-lock {
- width: 60px;
- height: 65px;
- min-width: 60px;
- min-height: 65px;
- max-width: 60px;
- max-height: 65px;
- aspect-ratio: 60 / 65;
- font-size: 0;
- color: transparent;
- background: url("../img/Room-id-private.png") center / 100% 100% no-repeat;
- filter: none;
- }
- .room-lobby-profile-frame {
- width: 159px;
- height: 157px;
- min-width: 159px;
- min-height: 157px;
- max-width: 159px;
- max-height: 157px;
- aspect-ratio: 159 / 157;
- }
- .room-lobby-exit-fixed .btn-exit-icon {
- width: 121px;
- height: 119px;
- min-width: 121px;
- min-height: 119px;
- max-width: 121px;
- max-height: 119px;
- aspect-ratio: 121 / 119;
- margin-left: 13px;
- margin-top: -15px;
- margin-bottom: -15px;
- }
- body.room-lobby-page #room-players-hud {
- min-width: 0;
- font-size: clamp(1.35rem, 1.95vw, 1.9rem);
- padding: 0.1rem 0.4rem;
- }
- .room-lobby-ready-fixed .ready-label-img {
- width: 320px;
- height: 126px;
- min-width: 320px;
- min-height: 126px;
- max-width: 320px;
- max-height: 126px;
- aspect-ratio: 320 / 126;
- }
- .room-lobby-br-fixed {
- --lobby-br-btn: 137px;
- bottom: max(0.65rem, env(safe-area-inset-bottom));
- right: max(0.85rem, env(safe-area-inset-right));
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: flex-end;
- gap: 0.75rem;
- }
- /* แถวเดียว: หลักฐาน | อันดับ | ไมค์ (ตรง production) */
- .room-lobby-br-fixed .lobby-b-extra-row:not(.is-hidden) {
- display: contents;
- }
- .room-lobby-br-fixed .lobby-b-extra-row {
- position: static !important;
- margin: 0 !important;
- transform: none !important;
- z-index: auto;
- }
- .room-lobby-br-fixed .btn-voice-icon {
- position: static !important;
- margin: 0 !important;
- transform: none !important;
- }
- .room-lobby-br-fixed .lobby-b-sq-btn,
- .room-lobby-br-fixed .btn-voice-icon {
- width: var(--lobby-br-btn);
- height: var(--lobby-br-btn);
- min-width: var(--lobby-br-btn);
- min-height: var(--lobby-br-btn);
- max-width: var(--lobby-br-btn);
- max-height: var(--lobby-br-btn);
- }
- .room-lobby-chat-peers.chat-panel-collapsed.chat-panel {
- width: 122px;
- height: 120px;
- bottom: 12rem;
- right: max(0.85rem, env(safe-area-inset-right));
- }
- .room-lobby-chat-peers.chat-panel-collapsed .chat-close-btn {
- width: 122px;
- height: 120px;
- min-width: 122px;
- min-height: 120px;
- max-width: 122px;
- max-height: 120px;
- aspect-ratio: 122 / 120;
- margin-right: -20px;
- }
- .room-lobby-chat-peers.chat-panel-collapsed .chat-close-btn img {
- width: 122px;
- height: 120px;
- aspect-ratio: 122 / 120;
- }
-}
-
-/* แฟ้มหลักฐาน LobbyB — ดู css/evidence-view-overlay.css (layout ev-*) */
-
-/* กระดานอันดับ LobbyB — ดู css/leaderboard-popup.css */
-
-.version-tag {
- position: fixed;
- right: 8px;
- bottom: 4px;
- left: auto;
- font-size: 10px;
- color: #a9b1d6;
- opacity: 0.7;
- pointer-events: none;
-}
-
-/* Editor — เกมตอบคำถาม */
-.quiz-editor-wrap {
- margin: 1rem 0;
- padding: 1rem;
- background: #24283b;
- border-radius: 8px;
- border: 1px solid #414868;
-}
-.quiz-editor-wrap h3 {
- margin: 0 0 0.5rem;
- font-size: 1rem;
- color: #7aa2f7;
-}
-.quiz-questions-list {
- display: flex;
- flex-direction: column;
- gap: 0.6rem;
- margin: 0.75rem 0;
-}
-.quiz-q-row {
- display: grid;
- grid-template-columns: 1fr auto auto;
- gap: 0.5rem;
- align-items: center;
-}
-@media (max-width: 600px) {
- .quiz-q-row {
- grid-template-columns: 1fr;
- }
-}
-.quiz-q-row input[type="text"] {
- min-width: 0;
- padding: 0.4rem 0.5rem;
- border-radius: 6px;
- border: 1px solid #565f89;
- background: #1a1b26;
- color: #c0caf5;
-}
-.quiz-q-row select {
- padding: 0.35rem;
- border-radius: 6px;
- border: 1px solid #565f89;
- background: #1a1b26;
- color: #c0caf5;
-}
-.btn-quiz-add,
-.quiz-q-remove {
- padding: 0.35rem 0.65rem;
- border-radius: 6px;
- cursor: pointer;
- border: 1px solid #565f89;
- background: #414868;
- color: #c0caf5;
- font: inherit;
-}
-.quiz-q-remove {
- font-size: 0.8rem;
-}
-
-/* design 2026-05: แสดงปุ่มตั้งค่าโฮสต์ + ปรับแต่ง มุมขวาบน (ตาม TryChangeCSS/CSS ใหม่ — ไม่ใช้ JS เก่า) */
-body.room-lobby-page .room-lobby-top-right-actions {
- display: none !important;
-}
-
-/* ---- Player Pick Vote overlay (Card Ban / Silence) — โหวตเลือกผู้เล่น ----
- สร้างด้วย JS ใน room-lobby.js (#pick-vote-overlay) แต่เดิมไม่มี CSS เลย → div จมหลัง UI lobby มองไม่เห็น */
-#pick-vote-overlay {
- position: fixed;
- inset: 0;
- z-index: 12000;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 4vh 4vw;
- background: rgba(4, 8, 16, 0.74);
- backdrop-filter: blur(4px);
- -webkit-backdrop-filter: blur(4px);
- opacity: 0;
- visibility: hidden;
- pointer-events: none;
- transition: opacity 0.22s ease, visibility 0.22s ease;
- font-family: 'Kanit', sans-serif;
-}
-#pick-vote-overlay.is-open {
- opacity: 1;
- visibility: visible;
- pointer-events: auto;
-}
-#pick-vote-overlay .pv-shell {
- width: min(460px, 92vw);
- max-height: 88vh;
- overflow-y: auto;
- box-sizing: border-box;
- padding: 1.4rem 1.5rem 1.6rem;
- border-radius: 18px;
- text-align: center;
- color: #e8f6ff;
- background: linear-gradient(165deg, rgba(16, 30, 50, 0.97), rgba(8, 16, 30, 0.97));
- border: 1px solid rgba(83, 224, 255, 0.55);
- box-shadow: 0 0 28px rgba(83, 224, 255, 0.35), inset 0 0 24px rgba(80, 180, 240, 0.14);
- transform: translateY(12px) scale(0.97);
- transition: transform 0.26s cubic-bezier(0.2, 0.9, 0.3, 1.2);
-}
-#pick-vote-overlay.is-open .pv-shell {
- transform: translateY(0) scale(1);
-}
-#pick-vote-overlay .pv-badge {
- display: inline-block;
- padding: 0.2rem 0.85rem;
- border-radius: 999px;
- font-size: 0.74rem;
- font-weight: 700;
- letter-spacing: 0.08em;
- color: #04121e;
- background: linear-gradient(90deg, #53e0ff, #8ad8ff);
- box-shadow: 0 0 14px rgba(83, 224, 255, 0.55);
-}
-#pick-vote-overlay .pv-title {
- margin: 0.7rem 0 0.3rem;
- font-size: 1.32rem;
- font-weight: 700;
- text-shadow: 0 0 12px rgba(83, 224, 255, 0.45);
-}
-#pick-vote-overlay .pv-sub {
- margin: 0 0 0.7rem;
- font-size: 0.86rem;
- line-height: 1.35;
- color: #a9c7da;
-}
-#pick-vote-overlay .pv-timer {
- font-size: 1.5rem;
- font-weight: 700;
- color: #53e0ff;
- margin-bottom: 0.6rem;
- min-height: 1.4em;
-}
-#pick-vote-overlay .pv-timer.low {
- color: #ff7a7a;
- animation: pvPulse 0.7s ease-in-out infinite;
-}
-@keyframes pvPulse {
- 0%, 100% { transform: scale(1); }
- 50% { transform: scale(1.12); }
-}
-#pick-vote-overlay .pv-list {
- display: flex;
- flex-direction: column;
- gap: 0.5rem;
- margin-bottom: 0.6rem;
-}
-#pick-vote-overlay .pv-cand {
- position: relative;
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 0.5rem;
- width: 100%;
- padding: 0.7rem 1rem;
- border-radius: 12px;
- font: 600 1rem 'Kanit', sans-serif;
- color: #e8f6ff;
- cursor: pointer;
- background: rgba(28, 48, 74, 0.85);
- border: 1px solid rgba(83, 224, 255, 0.3);
- transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease;
-}
-#pick-vote-overlay .pv-cand:hover {
- transform: translateY(-1px);
- border-color: rgba(83, 224, 255, 0.7);
- background: rgba(36, 62, 94, 0.95);
-}
-#pick-vote-overlay .pv-cand.is-picked {
- border-color: #53e0ff;
- background: linear-gradient(90deg, rgba(83, 224, 255, 0.28), rgba(83, 224, 255, 0.14));
- box-shadow: 0 0 14px rgba(83, 224, 255, 0.5);
-}
-#pick-vote-overlay .pv-me {
- font-size: 0.78rem;
- color: #8ad8ff;
-}
-#pick-vote-overlay .pv-bot {
- font-size: 0.72rem;
- color: #04121e;
- background: #7fd4a8;
- padding: 0.05rem 0.45rem;
- border-radius: 999px;
-}
-#pick-vote-overlay .pv-count {
- position: absolute;
- right: 0.7rem;
- min-width: 1.5em;
- height: 1.5em;
- line-height: 1.5em;
- border-radius: 999px;
- font-size: 0.82rem;
- font-weight: 700;
- color: #04121e;
- background: #53e0ff;
- opacity: 0;
- transform: scale(0.6);
- transition: opacity 0.15s ease, transform 0.15s ease;
-}
-#pick-vote-overlay .pv-count.show {
- opacity: 1;
- transform: scale(1);
-}
-#pick-vote-overlay .pv-result {
- margin: 0.4rem 0;
- padding: 0.7rem;
- border-radius: 12px;
- font-size: 1.05rem;
- font-weight: 700;
- color: #fff;
- background: rgba(83, 224, 255, 0.16);
- border: 1px solid rgba(83, 224, 255, 0.5);
-}
-#pick-vote-overlay .pv-foot {
- font-size: 0.82rem;
- color: #a9c7da;
- min-height: 1.2em;
-}
-
-/* ===== มือถือ: ย่อปุ่ม AI chat ที่ใหญ่เกิน (213x201) + ปุ่ม interact (F) ให้พอดีจอ ===== */
-@media (max-width: 600px) {
- .room-lobby-chat-ai.chat-panel-collapsed .chat-close-btn,
- .room-lobby-chat-ai.chat-panel-collapsed .chat-close-btn img {
- width: 92px !important;
- height: 87px !important;
- min-width: 92px !important;
- min-height: 87px !important;
- max-width: 92px !important;
- max-height: 87px !important;
- }
- .room-lobby-chat-ai.chat-panel .chat-close-btn,
- .room-lobby-chat-ai.chat-panel .chat-close-btn img {
- width: 42px !important;
- height: 42px !important;
- }
-}
-
-/* ===== มือถือแนวนอน (จอเตี้ย) — ย่อ/จัด UI ห้องเกม (LobbyA) ให้พอดีไม่ล้น · อิงแนวทาง Main-Lobby · ไม่แตะ PC ===== */
-@media (orientation: landscape) and (max-height: 540px) {
- /* ปุ่มมุมขวาล่าง (ไมค์ + แว่น/ถ้วย) — ย่อตามความสูงจอ */
- .room-lobby-br-fixed { --lobby-br-btn: clamp(46px, 11vh, 64px); gap: 7px; }
- /* แผงแชท — เดิม 576x525 ล้นจอแนวนอน → ย่อให้พอดีความสูงจอ */
- .room-lobby-chat-peers.chat-panel {
- width: min(360px, 52vw);
- height: min(248px, calc(100dvh - 80px));
- bottom: max(0.5rem, env(safe-area-inset-bottom));
- padding: 0.9rem 1rem;
- }
- /* ปุ่มแชท AI (collapsed) — ย่อลงอีกบนแนวนอน */
- .room-lobby-chat-ai.chat-panel-collapsed .chat-close-btn,
- .room-lobby-chat-ai.chat-panel-collapsed .chat-close-btn img {
- width: 62px !important; height: 58px !important;
- min-width: 62px !important; min-height: 58px !important;
- max-width: 62px !important; max-height: 58px !important;
- }
- /* ปุ่ม ready — เตี้ยลงเล็กน้อย ไม่ชนปุ่มอื่น */
- .room-lobby-ready-fixed .ready-label-img { height: clamp(38px, 9.5vh, 58px); }
- /* ปุ่ม exit/howto มุมซ้ายบน — อิงความสูงจอ */
- .room-lobby-exit-fixed .btn-exit-icon {
- width: clamp(46px, 10vh, 62px);
- height: clamp(46px, 10vh, 62px);
- min-width: clamp(46px, 10vh, 62px);
- }
-}
+* { box-sizing: border-box; }
+@font-face {
+ font-family: 'NotoSansThai';
+ src:
+ url('/Create%20Room/FONTS/NotoSansThai-Medium.ttf') format('truetype');
+ font-weight: 500;
+ font-style: normal;
+ font-display: swap;
+}
+body { font-family: sans-serif; margin: 0; background: #1a1b26; color: #c0caf5; }
+body.room-lobby-page,
+body.room-lobby-page * {
+ font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif !important;
+}
+.container { max-width: 720px; margin: 1rem auto; padding: 1rem; }
+
+/* โครง Editor — แยกแถบเครื่องมือ / พื้นที่วาด */
+.editor-page {
+ display: block;
+}
+
+/* Editor ฝังใน Admin (?embed=1) — เต็มความสูง iframe, พื้นที่แคนวาสใหญ่ + เลื่อนแยก */
+html.editor-embed-admin {
+ height: 100%;
+}
+html.editor-embed-admin body {
+ height: 100%;
+ margin: 0;
+ overflow: hidden;
+}
+body.editor-embed-admin .version-tag {
+ display: none !important;
+}
+body.editor-embed-admin .container.editor-page {
+ max-width: none !important;
+ width: 100%;
+ height: 100%;
+ margin: 0 !important;
+ padding: 0.35rem 0.5rem 0.45rem;
+ display: flex;
+ flex-direction: column;
+ min-height: 0;
+ box-sizing: border-box;
+}
+body.editor-embed-admin .container.editor-page > h1 {
+ display: none;
+}
+body.editor-embed-admin .editor-toolbar-wrap {
+ flex: 0 1 auto;
+ max-height: min(36vh, 360px);
+ overflow-x: hidden;
+ overflow-y: auto;
+ padding: 0.15rem 0.25rem 0.45rem 0;
+ margin: 0 0 0.3rem;
+ border-bottom: 1px solid rgba(65, 72, 104, 0.9);
+ scrollbar-width: thin;
+}
+body.editor-embed-admin .editor-workspace {
+ flex: 1 1 auto;
+ min-height: 0;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+}
+body.editor-embed-admin .canvas-wrap {
+ flex: 1 1 auto;
+ min-height: 140px;
+ overflow: auto;
+ margin: 0 !important;
+ border-radius: 10px;
+ border: 1px solid #414868;
+ background: #0f1018;
+ -webkit-overflow-scrolling: touch;
+}
+body.editor-embed-admin #editor-status {
+ flex: 0 0 auto;
+ margin: 0.3rem 0 0;
+ font-size: 0.8rem;
+ line-height: 1.35;
+}
+body.editor-embed-admin .editor-legend-short {
+ margin: 0.25rem 0 0;
+ font-size: 0.76rem;
+ line-height: 1.4;
+ color: #a8b0d0;
+}
+body.editor-embed-admin .editor-toolbar {
+ margin-top: 0.25rem;
+ margin-bottom: 0.35rem;
+}
+body.editor-embed-admin .frogger-lanes {
+ margin: 0.35rem 0;
+}
+body.editor-embed-admin .editor-bg-section {
+ margin: 0.35rem 0 0.15rem;
+}
+h1 { color: #7aa2f7; }
+a { color: #9ece6a; }
+label { display: inline-block; margin: 0.25rem 0.5rem 0.25rem 0; }
+input, button { padding: 0.4rem 0.6rem; margin: 0 0.25rem 0 0; border-radius: 6px; border: 1px solid #414868; }
+input { background: #24283b; color: #c0caf5; }
+button { background: #7aa2f7; color: #1a1b26; cursor: pointer; border: none; }
+.legend { font-size: 0.9rem; color: #a9b1d6; margin: 0.5rem 0; }
+.frogger-lanes { margin: 1rem 0; padding: 0.75rem; background: #24283b; border-radius: 8px; position: relative; z-index: 2; min-height: 80px; }
+.frogger-lanes h3 { margin: 0 0 0.5rem 0; color: #7aa2f7; font-size: 1rem; }
+.frogger-lanes table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
+.frogger-lanes th, .frogger-lanes td { padding: 0.25rem 0.5rem; text-align: left; border: 1px solid #414868; }
+.frogger-lanes select, .frogger-lanes input[type="number"] { padding: 0.35rem 0.5rem; min-width: 4rem; background: #1a1b26; color: #c0caf5; border: 1px solid #414868; border-radius: 4px; cursor: pointer; font-size: 0.9rem; }
+.frogger-lanes select { min-width: 6rem; }
+.frogger-lanes .lane-speed { width: 4rem; }
+.frogger-lanes .lane-spacing { width: 4rem; }
+.frogger-lanes td { vertical-align: middle; }
+.frogger-lanes select:disabled, .frogger-lanes input:disabled { opacity: 0.6; cursor: not-allowed; }
+.game-type-hint { font-size: 0.85rem; color: #a9b1d6; margin-left: 0.5rem; }
+.editor-toolbar { margin: 1rem 0; flex-wrap: wrap; display: flex; align-items: center; gap: 0.5rem 1rem; }
+.editor-toolbar label, .editor-toolbar .game-type-hint { margin: 0; }
+.editor-bg-section { margin: 0.75rem 0; display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
+.editor-bg-section label { margin: 0; }
+.canvas-wrap { margin: 1rem 0; }
+.container { padding-left: 1rem; padding-right: 1rem; }
+#editor-canvas { background: #1a1b26; display: block; }
+.game-wrap { display: flex; flex-direction: column; height: 100vh; height: 100dvh; min-height: 0; }
+.game-header { flex-shrink: 0; background: #24283b; padding: 0.5rem 1rem; display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; }
+.game-header span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
+.game-header button { flex-shrink: 0; }
+#game-canvas {
+ flex: 1 1 auto;
+ display: block;
+ width: 100%;
+ min-height: 0;
+ min-width: 0;
+ touch-action: none;
+}
+.game-wrap .chat-panel { flex-shrink: 0; }
+.chat-panel { height: 160px; border-top: 1px solid #414868; display: flex; flex-direction: column; }
+#chat-messages { flex: 1; overflow-y: auto; padding: 0.5rem; font-size: 0.9rem; }
+#chat-form { display: flex; padding: 0.5rem; gap: 0.5rem; }
+#chat-input { flex: 1; }
+
+.lobby-section { margin: 1.25rem 0; padding: 1rem; background: #24283b; border-radius: 8px; }
+.lobby-section h2 { margin: 0 0 0.75rem 0; font-size: 1rem; color: #7aa2f7; }
+#room-list { list-style: none; margin: 0; padding: 0; }
+#room-list .room-item { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; padding: 0.5rem 0; border-bottom: 1px solid #414868; }
+#room-list .room-item:last-child { border-bottom: none; }
+#room-list .room-name { font-weight: 600; color: #c0caf5; min-width: 0; }
+#room-list .room-meta { font-size: 0.85rem; color: #a9b1d6; }
+#room-list .room-meta-inline { font-size: 0.8rem; color: #565f89; font-weight: normal; }
+#room-list-status { margin: 0; color: #a9b1d6; font-size: 0.9rem; }
+
+.room-lobby-peers { margin: 1rem 0; padding: 0.75rem; background: #24283b; border-radius: 8px; }
+.room-lobby-peer { padding: 0.35rem 0; color: #c0caf5; }
+.room-lobby-peer:not(:last-child) { border-bottom: 1px solid #414868; }
+#lobby-map-wrap { position: fixed; top: 0; left: 0; right: 0; bottom: 0; width: 100%; height: 100%; min-width: 100vw; min-height: 100vh; min-height: 100dvh; z-index: 0; }
+body.room-lobby-page {
+ background:
+ radial-gradient(120% 120% at 50% -12%, rgba(86, 122, 255, 0.26) 0%, rgba(30, 37, 83, 0.16) 40%, rgba(7, 10, 25, 0) 75%),
+ linear-gradient(180deg, #1a1d46 0%, #111530 42%, #090d22 100%);
+ color: #ebf6ff;
+}
+#lobby-map-wrap::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ z-index: 1;
+ pointer-events: none;
+ background:
+ radial-gradient(80% 65% at 50% 18%, rgba(106, 194, 255, 0.2), rgba(106, 194, 255, 0) 72%),
+ linear-gradient(180deg, rgba(10, 16, 46, 0.25) 0%, rgba(6, 12, 31, 0.05) 30%, rgba(5, 9, 24, 0.5) 100%);
+}
+#lobby-map-wrap::after {
+ content: '';
+ position: absolute;
+ inset: 0;
+ z-index: 2;
+ pointer-events: none;
+ box-shadow: inset 0 0 160px rgba(8, 12, 30, 0.85);
+}
+#lobby-map-canvas {
+ display: block;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ width: 100%;
+ height: 100%;
+ min-width: 100%;
+ min-height: 100%;
+ margin: 0;
+ padding: 0;
+ background:
+ radial-gradient(circle at 50% 20%, rgba(124, 197, 255, 0.25) 0%, rgba(124, 197, 255, 0) 45%),
+ linear-gradient(180deg, #252c66 0%, #1a2150 45%, #121a3b 100%);
+ box-sizing: border-box;
+}
+/* [2026-08-02] กันภาพยืดตอนบัฟเฟอร์ยังค้างขนาดเก่า (หมุนจอ / แถบ URL ยุบ-กางบน iOS)
+ ปกติ canvas.width/height = ขนาด viewport พอดี ⇒ contain ไม่ทำอะไรเลย (วัดแล้วยืด 0.0% ทุกเครื่อง)
+ แต่ช่วงที่ค่ายังไม่ถูกวัดใหม่ จะเห็นเป็น "ขอบว่าง" แทน "ภาพยืดผิดสัดส่วน" ซึ่งดีกว่ามาก
+ ห่อด้วย pointer: coarse → PC (pointer: fine) ไม่โดนกฎนี้เลย · สูตรเดียวกับที่ play.html ใช้มาตั้งแต่ 07-31 */
+@media (pointer: coarse) {
+ #lobby-map-canvas { object-fit: contain; }
+}
+#lobby-map-canvas:focus {
+ outline: none;
+}
+#lobby-map-canvas:focus-visible {
+ outline: 2px solid rgba(122, 162, 247, 0.45);
+ outline-offset: -2px;
+}
+/* LobbyB (mn8nx46h) — ไม่แสดงปุ่มพร้อม */
+body.room-lobby--lobby-b .room-lobby-ready-fixed {
+ display: none !important;
+}
+.lobby-interact-hint {
+ position: absolute;
+ bottom: max(10px, env(safe-area-inset-bottom));
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 2;
+ margin: 0;
+ padding: 0.2rem 0.55rem;
+ font-size: clamp(0.72rem, 1.8vw, 0.85rem);
+ color: rgba(203, 213, 245, 0.9);
+ text-shadow: 0 1px 10px rgba(0, 0, 0, 0.55);
+ pointer-events: none;
+ font-family: system-ui, 'Kanit', sans-serif;
+ white-space: nowrap;
+}
+.lobby-interact-hint kbd {
+ display: inline-block;
+ padding: 0.06em 0.32em;
+ border-radius: 4px;
+ background: rgba(26, 27, 38, 0.88);
+ border: 1px solid rgba(122, 162, 247, 0.45);
+ font-size: 0.88em;
+ font-family: inherit;
+}
+.lobby-zoom-pct {
+ position: absolute;
+ top: 12px;
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 2;
+ padding: 6px 12px;
+ border-radius: 8px;
+ background: rgba(26, 27, 38, 0.85);
+ color: #c0caf5;
+ font-size: 1rem;
+ font-weight: 600;
+ pointer-events: none;
+ opacity: 0;
+ transition: opacity 0.2s ease;
+}
+.lobby-zoom-pct.lobby-zoom-pct-visible { opacity: 1; }
+/* ซ่อนแผง overlay รายชื่อ / host / แชท — โถงโฟกัสแผนที่ + ปุ่ม READY/ไมค์ ด้านนอก */
+.room-lobby-overlay { display: none !important; }
+.room-lobby-top-left-cluster {
+ position: fixed;
+ top: max(12px, env(safe-area-inset-top));
+ left: max(0px, env(safe-area-inset-left));
+ z-index: 55;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 0.4rem;
+ pointer-events: none;
+}
+.room-lobby-top-left-cluster .room-lobby-exit-fixed {
+ pointer-events: auto;
+}
+.room-lobby-room-id-pill {
+ pointer-events: auto;
+ display: inline-flex;
+ align-items: center;
+ gap: 0.4rem;
+ min-height: 44px;
+ padding: 0.5rem 0.9rem;
+ border-radius: 12px;
+ border: 1px solid rgba(106, 232, 255, 0.58);
+ background: linear-gradient(180deg, rgba(43, 67, 128, 0.86), rgba(22, 34, 74, 0.9));
+ box-shadow:
+ inset 0 0 0 1px rgba(188, 247, 255, 0.2),
+ 0 0 18px rgba(80, 213, 255, 0.32);
+ color: #dff6ff;
+ font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif;
+ letter-spacing: 0.03em;
+}
+.room-lobby-room-id-label {
+ font-weight: 600;
+ font-size: clamp(0.78rem, 1.7vw, 0.9rem);
+ opacity: 0.92;
+}
+#room-id-value {
+ font-weight: 800;
+ font-size: clamp(0.85rem, 1.9vw, 1rem);
+ color: #f4fdff;
+}
+.room-lobby-room-id-lock {
+ font-size: 0.85rem;
+ filter: drop-shadow(0 0 6px rgba(105, 227, 255, 0.6));
+}
+
+/* มุมขวาบน — โปรไฟล์ตัวละคร */
+.room-lobby-top-right-cluster {
+ position: fixed;
+ top: max(12px, env(safe-area-inset-top));
+ right: max(12px, env(safe-area-inset-right));
+ z-index: 56;
+ display: flex;
+ flex-direction: row;
+ align-items: flex-start;
+ gap: 0.4rem;
+ pointer-events: none;
+}
+.room-lobby-top-right-cluster > * {
+ pointer-events: auto;
+}
+.room-lobby-top-right-actions {
+ display: none !important;
+}
+.room-lobby-top-right-action-btn {
+ position: relative;
+ flex: 0 0 auto;
+ width: clamp(100px, 11vw, 161px);
+ height: auto;
+ min-width: 0;
+ min-height: 0;
+ max-width: 161px;
+ aspect-ratio: 161 / 176;
+ padding: 0;
+ margin: 0;
+ border: none;
+ border-radius: 0;
+ background: transparent;
+ box-shadow: none;
+ cursor: pointer;
+ overflow: visible;
+ isolation: isolate;
+}
+.room-lobby-top-right-action-btn img {
+ width: 100%;
+ height: auto;
+ max-width: 161px;
+ aspect-ratio: 161 / 176;
+ object-fit: contain;
+ display: block;
+ pointer-events: none;
+ user-select: none;
+ -webkit-user-drag: none;
+}
+.room-lobby-profile-wrap {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 0.2rem;
+}
+.room-lobby-profile-frame {
+ position: relative;
+ width: 159px;
+ height: 157px;
+ min-width: 159px;
+ min-height: 157px;
+ max-width: 159px;
+ max-height: 157px;
+ aspect-ratio: 159 / 157;
+ border-radius: 0;
+ border: none;
+ overflow: hidden;
+ background: url(../img/btn-profile-bg.png) center/100% 100% no-repeat;
+ box-shadow: none;
+}
+.room-lobby-profile-avatar-viewport {
+ position: absolute;
+ left: 12px;
+ top: 10px;
+ width: 124px;
+ height: 118px;
+ overflow: hidden;
+ border-radius: 12px;
+}
+.room-lobby-profile-frame #room-lobby-profile-avatar {
+ position: absolute;
+ left: 50%;
+ top: 5px;
+ display: block;
+ width: 120%;
+ height: auto;
+ max-width: none;
+ object-fit: contain;
+ object-position: center top;
+ transform: translateX(-50%);
+ transform-origin: center center;
+ image-rendering: pixelated;
+ image-rendering: crisp-edges;
+}
+.room-lobby-profile-set-btn {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ width: 71px;
+ height: 71px;
+ min-width: 71px;
+ min-height: 71px;
+ max-width: 71px;
+ max-height: 71px;
+ aspect-ratio: 71 / 71;
+ padding: 0;
+ margin: 0;
+ border: none;
+ border-radius: 0;
+ background: transparent;
+ cursor: pointer;
+ z-index: 2;
+}
+.room-lobby-profile-set-btn img {
+ display: block;
+ width: 71px;
+ height: 71px;
+ min-width: 71px;
+ min-height: 71px;
+ max-width: 71px;
+ max-height: 71px;
+ aspect-ratio: 71 / 71;
+ object-fit: contain;
+}
+
+/* Profile overlay — see profile-popup.css (linked from room-lobby.html) */
+
+
+/* Host Console popup */
+.room-lobby-host-console-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 10070;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
+}
+.room-lobby-host-console-overlay.is-hidden {
+ display: none !important;
+}
+.room-lobby-host-console-backdrop {
+ position: absolute;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.8);
+}
+.room-lobby-host-console-dialog {
+ position: relative;
+ z-index: 1;
+ width: min(990px, calc(100vw - 24px), calc((100dvh - 24px) * (990 / 881)));
+ aspect-ratio: 990 / 881;
+ max-height: calc(100dvh - 24px);
+ --hc-scale: 1;
+ --hc-close-hit-size: calc(82px * var(--hc-scale));
+ --hc-close-hit-top: 9%;
+ --hc-close-hit-right: 6.5%;
+ background: url(../img/03-4-Host-Console/host-console-bg.png) center/100% 100% no-repeat;
+ box-sizing: border-box;
+}
+.room-lobby-host-console-body {
+ position: absolute;
+ top: 13.6%;
+ right: 7.9%;
+ bottom: 6%;
+ left: 8.2%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ min-height: 0;
+ padding-top: calc(50px * var(--hc-scale));
+ padding-bottom: calc(62px * var(--hc-scale));
+ box-sizing: border-box;
+}
+.room-lobby-host-console-close {
+ position: absolute;
+ top: var(--hc-close-hit-top);
+ right: var(--hc-close-hit-right);
+ width: var(--hc-close-hit-size);
+ height: var(--hc-close-hit-size);
+ border: none;
+ border-radius: 0;
+ background: transparent;
+ color: transparent;
+ font-size: 0;
+ line-height: 1;
+ cursor: pointer;
+ text-shadow: none;
+ z-index: 3;
+ -webkit-tap-highlight-color: transparent;
+}
+.room-lobby-host-console-txt-img {
+ width: auto;
+ object-fit: contain;
+ display: block;
+}
+.room-lobby-host-console-txt-max {
+ height: calc(66px * var(--hc-scale));
+ margin-bottom: calc(10px * var(--hc-scale));
+}
+.room-lobby-host-console-max-wrap {
+ position: relative;
+ width: min(82%, calc(657px * var(--hc-scale)));
+ aspect-ratio: 657 / 141;
+ margin-bottom: calc(-10px * var(--hc-scale));
+ margin-top: calc(-30px * var(--hc-scale));
+}
+.room-lobby-host-console-textfield-bg {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ display: block;
+}
+.room-lobby-host-console-arrow-btn {
+ position: absolute;
+ top: 50%;
+ width: calc(51px * var(--hc-scale));
+ height: calc(54px * var(--hc-scale));
+ padding: 0;
+ margin: 0;
+ border: none;
+ border-radius: 0;
+ background: transparent;
+ cursor: pointer;
+ transform: translateY(-50%);
+}
+.room-lobby-host-console-arrow-left { left: 4.9%; }
+.room-lobby-host-console-arrow-right { right: 4.9%; }
+.room-lobby-host-console-arrow-btn img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ display: block;
+}
+.room-lobby-host-console-max-value {
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%);
+ min-width: 2ch;
+ text-align: center;
+ font-size: calc(40px * var(--hc-scale));
+ font-weight: 700;
+ color: #eaf9ff;
+ text-shadow: 0 0 10px rgba(0, 255, 255, 0.35);
+}
+.room-lobby-host-console-summary {
+ margin: 0 0 calc(12px * var(--hc-scale));
+ font-size: calc(24px * var(--hc-scale));
+ color: #d9f3ff;
+ margin-bottom: 4%;
+}
+.room-lobby-host-console-line {
+ width: min(94%, calc(744px * var(--hc-scale)));
+ height: auto;
+ margin-bottom: calc(10px * var(--hc-scale));
+ object-fit: contain;
+}
+.room-lobby-host-console-txt-members {
+ height: calc(61px * var(--hc-scale));
+ margin-bottom: calc(8px * var(--hc-scale));
+}
+.room-lobby-host-console-members {
+ width: min(84%, calc(694px * var(--hc-scale)));
+ flex: 1 1 auto;
+ min-height: 0;
+ overflow-x: hidden;
+ overflow-y: scroll;
+ padding-right: calc(40px * var(--hc-scale));
+ padding-left: calc(35px * var(--hc-scale));
+ scrollbar-width: auto;
+ scrollbar-color: rgba(255, 104, 228, 0.98) rgba(20, 40, 70, 0.55);
+ scrollbar-gutter: stable both-edges;
+}
+.room-lobby-host-console-members::-webkit-scrollbar {
+ width: clamp(24px, calc(36px * var(--hc-scale)), 42px);
+}
+.room-lobby-host-console-members::-webkit-scrollbar-track {
+ background: rgba(20, 40, 70, 0.55);
+ border-radius: 999px;
+ border: 1px solid rgba(90, 220, 255, 0.35);
+}
+.room-lobby-host-console-members::-webkit-scrollbar-thumb {
+ background: linear-gradient(180deg, rgba(255, 125, 236, 1) 0%, rgba(241, 74, 215, 1) 100%);
+ border-radius: 999px;
+ border: 3px solid rgba(16, 32, 56, 0.65);
+ background-clip: padding-box;
+ box-shadow: 0 0 10px rgba(255, 84, 226, 0.45);
+}
+.room-lobby-host-console-members-list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ display: flex;
+ flex-direction: column;
+ gap: calc(18px * var(--hc-scale));
+}
+.room-lobby-host-console-member-item {
+ position: relative;
+ min-height: calc(44px * var(--hc-scale));
+ padding: calc(2px * var(--hc-scale)) calc(104px * var(--hc-scale)) calc(2px * var(--hc-scale)) calc(12px * var(--hc-scale));
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ gap: 0.6rem;
+ color: #e9f8ff;
+ font-size: calc(28px * var(--hc-scale));
+ background: url(../img/03-4-Host-Console/host-console-line-2.png) left bottom/100% 3px no-repeat;
+}
+.room-lobby-host-console-member-item.is-host {
+ min-height: calc(80px * var(--hc-scale));
+ padding-right: calc(12px * var(--hc-scale));
+ background: url(../img/03-4-Host-Console/host-console-hostname.png) center/100% 100% no-repeat;
+ font-weight: 700;
+}
+.room-lobby-host-console-member-name {
+ min-width: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ color: inherit;
+ padding-left: 4%;
+ margin-top: -4%;
+}
+.room-lobby-host-console-member-item.is-host .room-lobby-host-console-member-name {
+ margin-top: 0%; /* เพิ่มค่านี้ = ขยับลง */
+}
+.room-lobby-host-console-delete-btn {
+ position: absolute;
+ right: calc(10px * var(--hc-scale));
+ top: 50%;
+ transform: translateY(-50%);
+ width: calc(84px * var(--hc-scale));
+ height: calc(84px * var(--hc-scale));
+ min-width: calc(84px * var(--hc-scale));
+ padding: 0;
+ border: none;
+ border-radius: 0;
+ background: transparent;
+ cursor: pointer;
+ margin-top: -2%;
+ margin-right: -1%;
+}
+.room-lobby-host-console-delete-btn img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ display: block;
+}
+.room-lobby-host-console-delete-btn:disabled {
+ opacity: 0.35;
+ cursor: default;
+}
+.room-lobby-host-console-confirm {
+ position: absolute;
+ left: 50%;
+ bottom: calc(-60px * var(--hc-scale));
+ transform: translateX(-50%);
+ width: min(43%, calc(350px * var(--hc-scale)));
+ aspect-ratio: 350 / 129;
+ border: none;
+ border-radius: 0;
+ padding: 0;
+ background: transparent;
+ cursor: pointer;
+}
+.room-lobby-host-console-confirm img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ display: block;
+}
+/* Profile popup: tightened scaling for reduced viewports */
+@media (max-width: 1100px), (max-height: 700px) {
+ .room-lobby-profile-content {
+ top: 13%;
+ right: 4%;
+ bottom: 8%;
+ left: 4%;
+ gap: clamp(8px, 1vw, 14px);
+ grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.12fr);
+ }
+ .room-lobby-profile-left-pane {
+ grid-template-rows: minmax(0, 1fr) auto;
+ row-gap: clamp(3px, 0.5vw, 6px);
+ }
+ .room-lobby-profile-logout {
+ width: min(58%, 100%);
+ }
+ .room-lobby-profile-char-card #room-lobby-profile-overlay-avatar {
+ width: 74%;
+ max-width: 74%;
+ max-height: 60%;
+ }
+}
+@media (max-width: 900px), (max-height: 560px) {
+ .room-lobby-profile-content {
+ top: 11%;
+ right: 3%;
+ bottom: 7%;
+ left: 3%;
+ gap: 8px;
+ grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.08fr);
+ }
+ .room-lobby-profile-logout {
+ width: min(62%, 100%);
+ }
+ .room-lobby-profile-char-card #room-lobby-profile-overlay-avatar {
+ width: 64%;
+ max-width: 64%;
+ max-height: 56%;
+ }
+}
+.room-lobby-actions { margin-top: 1rem; display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; }
+.room-lobby-actions .room-lobby-btn-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0; opacity: 0; pointer-events: none; }
+.room-lobby-actions label { margin: 0; }
+.room-lobby-actions #btn-start { background: #9ece6a; color: #1a1b26; }
+#host-only { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; }
+#host-only select { padding: 0.4rem 0.6rem; border-radius: 6px; border: 1px solid #414868; background: #24283b; color: #c0caf5; }
+.host-start-area-hint {
+ flex-basis: 100%;
+ margin: 0;
+ font-size: 0.88rem;
+ color: #e0af68;
+ line-height: 1.35;
+ max-width: 100%;
+}
+#host-only #btn-start:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ filter: grayscale(0.25);
+}
+.room-lobby-chat { margin-top: 1rem; }
+.room-lobby-chat.chat-panel {
+ border-radius: 12px;
+ overflow: hidden;
+ box-shadow: none;
+}
+.room-lobby-chat-peers.chat-panel {
+ position: fixed;
+ right: 0.25rem;
+ bottom: 10rem;
+ width: 576px;
+ height: 525px;
+ max-width: calc(100vw - 2.5rem);
+ z-index: 52;
+ margin-top: 0;
+ display: flex;
+ flex-flow: column;
+ padding: 2rem;
+ box-sizing: border-box;
+ border-top: 0px solid #414868;
+ background: url(../img/chat-msg-bg-alpha.png) center/100% 100% no-repeat;
+ background-color: transparent;
+}
+.room-lobby-chat-peers.chat-panel .chat-header-title.chat-header-title-img img { width: 90px; height: 77px; }
+.room-lobby-chat-peers.chat-panel .chat-close-btn { width: 48px; height: 48px; }
+.room-lobby-chat-peers.chat-panel .chat-close-btn img { width: 50px; height: 50px; }
+.room-lobby-chat-peers.chat-panel #chat-messages { padding: 0.75rem; font-size: 1.05rem; gap: 0.5rem; }
+.room-lobby-chat-peers.chat-panel .chat-form-bar { padding: 0.6rem 0; gap: 0.5rem; }
+.room-lobby-chat-peers.chat-panel #chat-input { padding: 0.6rem 0.85rem; font-size: 1.05rem; }
+.room-lobby-chat-peers.chat-panel .chat-send-btn { width: 52px; height: 52px; }
+.room-lobby-chat-peers.chat-panel .chat-send-btn img { width: 58px; height: 58px; }
+.room-lobby-chat-peers.chat-panel .chat-msg { padding: 0.6rem 1rem; font-size: 1.05rem; }
+.room-lobby-chat-peers.chat-panel .chat-header-bar {
+ margin: 0 -2rem 0 -2rem;
+ padding-left: 2rem;
+ padding-right: 2rem;
+ justify-content: space-between;
+ align-items: center;
+ min-height: 72px;
+ height: 72px;
+}
+.room-lobby-chat-peers.chat-panel #chat-messages {
+ flex: 1;
+ min-height: 0;
+ height: auto;
+}
+.room-lobby-chat .chat-header-bar {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0;
+ min-height: 48px;
+ height: 48px;
+ background: url(../img/chat-line.png) bottom repeat-x;
+ background-size: 100% 4px;
+ background-color: transparent;
+}
+.room-lobby-chat-peers .chat-header-title.chat-header-title-img {
+ display: inline-flex;
+ align-items: center;
+ line-height: 0;
+}
+.room-lobby-chat-peers .chat-header-title.chat-header-title-img img {
+ width: 60px;
+ height: 51px;
+ object-fit: contain;
+ display: block;
+}
+.room-lobby-chat-ai .chat-header-title.chat-header-title-img {
+ display: flex;
+ align-items: flex-end;
+ gap: 0.5rem;
+ line-height: 0;
+ min-width: 0;
+ overflow: visible;
+}
+.room-lobby-chat-ai .chat-header-title.chat-header-title-img .ai-chat-title-label {
+ height: 64px;
+ width: auto;
+ max-width: none;
+ object-fit: contain;
+ display: block;
+ flex-shrink: 0;
+ margin-bottom: -2px;
+}
+/* รูปหัวแชท AI — ยกขึ้นเหนือเส้น */
+.room-lobby-chat-ai .chat-header-title.chat-header-title-img img {
+ width: 86px;
+ height: 92px;
+ object-fit: cover;
+ display: block;
+ flex-shrink: 0;
+ margin-top: -27px;
+ margin-left: -6px;
+ position: relative;
+ z-index: 1;
+}
+.room-lobby-chat .chat-header-title {
+ font-size: 1rem;
+ font-weight: 600;
+ color: #a0aec0;
+}
+.room-lobby-chat .chat-close-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ padding: 0;
+ border: none;
+ border-radius: 8px;
+ background: transparent;
+ cursor: pointer;
+ margin-left: auto;
+}
+.room-lobby-chat-peers .chat-header-bar .chat-close-btn { margin-left: 0; }
+.room-lobby-chat .chat-close-btn img { width: 34px; height: 34px; object-fit: contain; }
+.room-lobby-chat .chat-close-btn:hover { opacity: 0.9; }
+.room-lobby-chat.chat-panel-collapsed #chat-messages,
+.room-lobby-chat.chat-panel-collapsed .chat-form-bar { display: none !important; }
+.room-lobby-chat-peers.chat-panel-collapsed .chat-header-title { display: none !important; }
+.room-lobby-chat-peers.chat-panel-collapsed .chat-header-bar {
+ justify-content: center;
+ padding: 0;
+ background: none !important;
+ border: none;
+}
+.room-lobby-chat-peers.chat-panel-collapsed.chat-panel {
+ width: 80px;
+ height: 80px;
+ min-height: 0;
+ padding: 0;
+ right: 1.25rem;
+ bottom: 6.25rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: none !important;
+ background-color: transparent !important;
+ border: none;
+ box-shadow: none;
+}
+.room-lobby-chat-peers.chat-panel-collapsed .chat-close-btn {
+ width: 80px;
+ height: 80px;
+ overflow: visible;
+}
+.room-lobby-chat-peers.chat-panel-collapsed .chat-close-btn img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ object-position: center;
+ display: block;
+}
+.room-lobby-chat #chat-messages,
+.room-lobby-chat #ai-chat-messages {
+ height: 100px;
+ overflow-y: auto;
+ padding: 0.5rem;
+ font-size: 0.85rem;
+ border: none;
+ margin: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 0.35rem;
+ background: none;
+ background-color: transparent;
+ box-shadow: none;
+}
+.room-lobby-chat .chat-messages-bg { border-radius: 0; }
+.room-lobby-chat #chat-form.chat-form-bar,
+.room-lobby-chat #ai-chat-form.chat-form-bar {
+ display: flex;
+ gap: 0.4rem;
+ align-items: center;
+ padding: 0.4rem 0;
+ background: none;
+ background-color: transparent;
+ border-top: none;
+ flex-shrink: 0;
+}
+.room-lobby-chat-peers .chat-form-bar {
+ padding-left: 0;
+ padding-right: 0;
+}
+.room-lobby-chat #chat-input,
+.room-lobby-chat #ai-chat-input {
+ flex: 1;
+ min-width: 0;
+ padding: 0.45rem 0.6rem;
+ border-radius: 10px;
+ border: 1px solid rgba(0, 212, 255, 0.25);
+ background: rgba(30, 35, 50, 0.8);
+ color: #c0caf5;
+ font-size: 0.9rem;
+ box-sizing: border-box;
+ margin-left: 9px;
+}
+.room-lobby-chat .chat-send-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 40px;
+ height: 40px;
+ flex-shrink: 0;
+ padding: 0;
+ border: none;
+ border-radius: 10px;
+ background: transparent;
+ cursor: pointer;
+}
+.room-lobby-chat .chat-send-btn img { width: 45px; height: 45px; object-fit: contain; }
+.room-lobby-chat .chat-send-btn:hover { opacity: 0.9; }
+.room-lobby-chat .chat-msg {
+ padding: 0.4rem 0.75rem;
+ border-radius: 12px;
+ max-width: 85%;
+ background-size: 100% 100%;
+ background-repeat: no-repeat;
+ background-position: center;
+}
+.room-lobby-chat .chat-msg-mine {
+ align-self: flex-end;
+ text-align: right;
+ background-image: url(../img/chat-bubble-me.png);
+ background-color: rgba(122, 162, 247, 0.9);
+ color: #1a1b26;
+}
+.room-lobby-chat .chat-msg-other {
+ align-self: flex-start;
+ text-align: left;
+ background-image: url(../img/chat-bubble-friend.png);
+ background-color: rgba(65, 72, 104, 0.9);
+ color: #c0caf5;
+}
+.room-lobby-chat .chat-msg-ai {
+ align-self: flex-start;
+ text-align: left;
+ background-image: url(../img/chat-bubble-friend.png);
+ background-color: rgba(158, 206, 106, 0.9);
+ color: #1a1b26;
+}
+.room-lobby-chat .chat-msg-system {
+ align-self: center;
+ text-align: center;
+ max-width: 95%;
+ background-image: none;
+ background-color: rgba(26, 27, 38, 0.72);
+ color: #9aa5ce;
+ font-size: 0.88rem;
+ font-style: italic;
+ padding: 0.35rem 0.6rem;
+}
+
+/* AI chat — loading แบบ Messenger (จุดกระโดด 3 จุด), อยู่ติดข้อความล่าสุดในลิสต์ */
+.room-lobby-chat .ai-chat-typing {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ padding: 12px 14px;
+ min-height: 24px;
+ flex-shrink: 0;
+ background-image: url(../img/chat-bubble-friend.png);
+ background-color: rgba(158, 206, 106, 0.9);
+ background-size: 100% 100%;
+ background-repeat: no-repeat;
+ background-position: center;
+}
+.room-lobby-chat .ai-typing-dot {
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ background: #1a1b26;
+ animation: ai-typing-bounce 1.4s ease-in-out infinite both;
+}
+.room-lobby-chat .ai-typing-dot:nth-child(1) { animation-delay: 0s; }
+.room-lobby-chat .ai-typing-dot:nth-child(2) { animation-delay: 0.2s; }
+.room-lobby-chat .ai-typing-dot:nth-child(3) { animation-delay: 0.4s; }
+@keyframes ai-typing-bounce {
+ 0%, 60%, 100% { transform: translateY(0); }
+ 30% { transform: translateY(-6px); }
+}
+
+/* AI chat panel — match Main-Lobby lobby-ai-chat-panel */
+.room-lobby-chat-ai.chat-panel {
+ position: fixed;
+ left: 8px;
+ right: auto;
+ bottom: clamp(0.5rem, 2vw, 1rem);
+ width: 454px;
+ height: 526px;
+ max-width: calc(100vw - 2.5rem);
+ z-index: 51;
+ margin: 0;
+ display: flex;
+ flex-flow: column;
+ box-sizing: border-box;
+ padding: 2.6rem;
+ overflow: visible;
+ background: url(../img/chat-msg-bg-alpha.png) center/100% 100% no-repeat;
+ background-color: transparent;
+ border: none;
+ box-shadow: none;
+ border-radius: 12px;
+ pointer-events: none;
+}
+.room-lobby-chat-ai.chat-panel .chat-header-bar,
+.room-lobby-chat-ai.chat-panel #ai-chat-messages,
+.room-lobby-chat-ai.chat-panel #ai-chat-form,
+.room-lobby-chat-ai.chat-panel .ai-chat-admin-link {
+ pointer-events: auto;
+}
+.room-lobby-chat-ai.chat-panel .chat-header-bar {
+ margin: 0 -2rem 0 -2rem;
+ padding: 0 1rem;
+ justify-content: space-between;
+ align-items: center;
+ min-height: 50px;
+ height: 50px;
+ overflow: visible;
+ background: url(../img/AI-chat-line.png) bottom repeat-x;
+ background-size: 100% 3px;
+ background-color: transparent;
+}
+.room-lobby-chat-ai.chat-panel .chat-header-title.chat-header-title-img img {
+ width: 100px;
+ height: 116px;
+ margin-top: -39px;
+ margin-left: 16px;
+ object-fit: cover;
+ position: relative;
+ z-index: 1;
+}
+.room-lobby-chat-ai.chat-panel .chat-header-title.chat-header-title-img .ai-chat-title-label {
+ height: 80px;
+ width: auto;
+ max-width: none;
+ margin-bottom: -4px;
+ margin-left: -5px;
+ transform: translateX(-6px);
+}
+.room-lobby-chat-ai.chat-panel .chat-close-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 60px;
+ height: 60px;
+ padding: 0;
+ border: none;
+ border-radius: 8px;
+ background: transparent;
+ cursor: pointer;
+ margin-left: auto;
+}
+.room-lobby-chat-ai.chat-panel .chat-close-btn img {
+ width: 60px;
+ height: 60px;
+ object-fit: contain;
+}
+.room-lobby-chat-ai.chat-panel .chat-close-btn:hover {
+ opacity: 0.9;
+}
+.room-lobby-chat-ai.chat-panel #ai-chat-messages {
+ flex: 1;
+ min-height: 0;
+ height: auto;
+ overflow-y: auto;
+ padding: 0.2rem 0.35rem 0.25rem 0;
+ font-size: 1.05rem;
+ gap: 0.5rem;
+ background: none;
+ border: none;
+ scrollbar-width: thin;
+ scrollbar-color: rgba(244, 252, 255, 0.98) rgba(53, 110, 167, 0.28);
+}
+.room-lobby-chat-ai.chat-panel #ai-chat-messages::-webkit-scrollbar {
+ width: 1rem;
+ scrollbar-width: auto;
+}
+.room-lobby-chat-ai.chat-panel #ai-chat-messages::-webkit-scrollbar-track {
+ border-radius: 999px;
+ background: linear-gradient(180deg, rgba(38, 77, 125, 0.45) 0%, rgba(32, 66, 106, 0.38) 100%);
+ box-shadow: inset 0 0 0 1px rgba(107, 193, 255, 0.25);
+}
+.room-lobby-chat-ai.chat-panel #ai-chat-messages::-webkit-scrollbar-thumb {
+ border-radius: 999px;
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(221, 244, 255, 0.96) 100%);
+ box-shadow:
+ 0 0 10px rgba(169, 239, 255, 0.55),
+ inset 0 0 0 1px rgba(180, 235, 255, 0.9);
+}
+.room-lobby-chat-ai.chat-panel .chat-form-bar {
+ display: flex;
+ gap: 0;
+ align-items: center;
+ padding: 0.6rem 0;
+ flex-shrink: 0;
+ background: none;
+ border: none;
+ width: calc(100% + 3rem);
+ margin-left: 0;
+ margin-right: 0;
+}
+.room-lobby-chat-ai.chat-panel #ai-chat-input {
+ flex: 0.85;
+ min-width: 0;
+ min-height: 50px;
+ padding: 0.6rem 0.85rem;
+ border-radius: 8px;
+ border: 1px solid rgba(0, 212, 255, 0.32);
+ background: rgba(30, 35, 50, 0.55);
+ color: #c0caf5;
+ font-size: 1.05rem;
+ margin: 0;
+}
+.room-lobby-chat-ai.chat-panel .chat-send-btn {
+ width: 73px;
+ height: 73px;
+ margin-left: 0;
+ margin-right: -0.7rem;
+}
+.room-lobby-chat-ai.chat-panel .chat-send-btn img {
+ width: 102px;
+ height: 98px;
+ object-fit: contain;
+}
+.room-lobby-chat-ai.chat-panel .chat-send-btn:focus,
+.room-lobby-chat-ai.chat-panel .chat-send-btn:focus-visible {
+ outline: none !important;
+ box-shadow: none !important;
+ border-color: transparent !important;
+}
+.room-lobby-chat-ai.chat-panel .chat-msg {
+ padding: 0.58rem 0.92rem;
+ font-size: 1.05rem;
+ line-height: 1.33;
+ border: none;
+ box-shadow: none;
+}
+.room-lobby-chat-ai.chat-panel .chat-msg-mine {
+ background-color: rgba(122, 162, 247, 0.2);
+ color: #f787e4;
+}
+.room-lobby-chat-ai.chat-panel .chat-msg-ai {
+ background-color: rgba(158, 206, 106, 0.2);
+ color: #f2f8ff;
+}
+.room-lobby-chat-ai.chat-panel .ai-chat-typing {
+ padding: 14px 18px;
+ min-height: 28px;
+ background-color: rgba(158, 206, 106, 0.32);
+}
+.room-lobby-chat-ai.chat-panel .ai-typing-dot {
+ width: 8px;
+ height: 8px;
+ background: #f2f8ff;
+}
+.room-lobby-chat-ai.chat-panel .ai-chat-admin-link {
+ margin: 0.35rem 0 0 0;
+ font-size: 0.75rem;
+ flex-shrink: 0;
+}
+.room-lobby-chat-ai.chat-panel,
+.room-lobby-chat-ai.chat-panel #ai-chat-messages,
+.room-lobby-chat-ai.chat-panel #ai-chat-input,
+.room-lobby-chat-ai.chat-panel .chat-msg,
+.room-lobby-chat-ai.chat-panel .ai-chat-typing,
+.room-lobby-chat-ai.chat-panel .chat-send-btn,
+.room-lobby-chat-ai.chat-panel .ai-chat-admin-link,
+.room-lobby-chat-ai.chat-panel .ai-chat-admin-link a {
+ font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif !important;
+}
+.room-lobby-chat-ai.chat-panel #ai-chat-messages,
+.room-lobby-chat-ai.chat-panel #ai-chat-messages * {
+ font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif !important;
+}
+.room-lobby-chat-ai.chat-panel #ai-chat-input::placeholder {
+ font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif !important;
+}
+
+/* Host console: force NotoSansThai for highlighted text areas */
+.room-lobby-host-console-summary,
+.room-lobby-host-console-member-item,
+.room-lobby-host-console-member-name,
+.room-lobby-host-console-max-value {
+ font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif !important;
+}
+
+/* AI chat collapsed — match Main-Lobby lobby-btn-ai-chat style */
+.room-lobby-chat-ai.chat-panel-collapsed #ai-chat-messages,
+.room-lobby-chat-ai.chat-panel-collapsed .chat-form-bar,
+.room-lobby-chat-ai.chat-panel-collapsed .ai-chat-admin-link { display: none !important; }
+.room-lobby-chat-ai.chat-panel-collapsed .chat-header-title { display: none !important; }
+.room-lobby-chat-ai.chat-panel-collapsed .chat-header-bar {
+ justify-content: center;
+ padding: 0;
+ background: none !important;
+ border: none;
+ min-height: 0;
+ height: auto;
+}
+.room-lobby-chat-ai.chat-panel-collapsed.chat-panel {
+ width: 213px;
+ max-width: 213px;
+ height: 201px;
+ min-height: 201px;
+ padding: 0;
+ left: max(1.25rem, env(safe-area-inset-left));
+ bottom: clamp(0.5rem, 2vw, 1rem);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: none !important;
+ background-color: transparent !important;
+ border: none;
+ box-shadow: none;
+}
+.room-lobby-chat-ai.chat-panel-collapsed .chat-close-btn {
+ width: 213px;
+ height: 201px;
+ min-width: 213px;
+ min-height: 201px;
+ max-width: 213px;
+ max-height: 201px;
+ aspect-ratio: 213 / 201;
+ overflow: visible;
+ border-radius: 0;
+ margin-left: 0;
+}
+.room-lobby-chat-ai.chat-panel-collapsed .chat-close-btn img {
+ width: 213px;
+ height: 201px;
+ min-width: 213px;
+ min-height: 201px;
+ max-width: 213px;
+ max-height: 201px;
+ aspect-ratio: 213 / 201;
+ object-fit: contain;
+ object-position: center;
+ display: block;
+}
+
+.room-lobby-exit-fixed {
+ position: static;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ align-items: center;
+ justify-content: flex-start;
+ gap: 10px;
+ width: max-content;
+ max-width: calc(100vw - 24px);
+ box-sizing: border-box;
+}
+.room-lobby-exit-fixed .btn-exit-icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex: 0 0 auto;
+ margin: 0;
+ width: clamp(58px, 9vw, 72px);
+ height: clamp(58px, 9vw, 72px);
+ min-width: clamp(58px, 9vw, 72px);
+ padding: 0;
+ border: none;
+ border-radius: 0;
+ background: transparent;
+ box-shadow: none;
+ cursor: pointer;
+}
+.room-lobby-exit-fixed .btn-exit-icon:hover {
+ transform: translateY(-1px);
+ filter: brightness(1.08);
+}
+.room-lobby-exit-fixed .btn-exit-icon img {
+ width: 100%;
+ height: auto;
+ object-fit: contain;
+ display: block;
+}
+
+.room-lobby-ready-fixed {
+ position: fixed;
+ bottom: max(2rem, env(safe-area-inset-bottom));
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 120;
+ pointer-events: none;
+}
+.room-lobby-ready-fixed .ready-label,
+.room-lobby-ready-fixed .ready-check-input {
+ pointer-events: auto;
+}
+.room-lobby-ready-fixed .ready-label {
+ position: relative;
+ display: inline-block;
+ padding: 0;
+ margin: 0;
+ border: none;
+ border-radius: 0;
+ background: transparent;
+ box-shadow: none;
+ cursor: pointer;
+ transition: transform 0.15s ease, filter 0.15s ease;
+ line-height: 0;
+ filter: drop-shadow(0 10px 20px rgba(0, 0, 0, 0.42));
+}
+.room-lobby-ready-fixed .ready-label:hover {
+ transform: scale(1.04);
+ filter: brightness(1.08);
+}
+.room-lobby-ready-fixed .ready-label:active {
+ transform: scale(0.98);
+}
+.room-lobby-ready-fixed .ready-check-input {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ opacity: 0;
+ cursor: pointer;
+ z-index: 2;
+}
+.room-lobby-ready-fixed .ready-label-img {
+ display: block;
+ height: clamp(44px, 8vh, 72px);
+ width: auto;
+ max-width: min(240px, 78vw);
+ pointer-events: none;
+ user-select: none;
+ -webkit-user-drag: none;
+}
+.room-lobby-ready-fixed .ready-label--active .ready-label-img {
+ filter: drop-shadow(0 0 10px rgba(158, 206, 106, 0.45));
+}
+body.room-lobby-page #room-players-hud {
+ top: max(10px, env(safe-area-inset-top)) !important;
+ min-width: 0;
+ border-radius: 0;
+ border: none;
+ background: transparent;
+ box-shadow: none;
+ backdrop-filter: none;
+ color: #e3f6ff !important;
+ font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif !important;
+ text-transform: none;
+ letter-spacing: 0.08em;
+ text-shadow:
+ 0 2px 0 rgba(0, 0, 0, 0.8),
+ 0 0 12px rgba(0, 0, 0, 0.55);
+ text-align: center;
+}
+
+/* มุมขวาล่าง — ไมค์ทุกห้อง + ปุ่ม LobbyB (แว่น/ถ้วย) */
+.room-lobby-br-fixed {
+ --lobby-br-btn: 80px;
+ position: fixed;
+ bottom: max(0.95rem, env(safe-area-inset-bottom));
+ right: max(1.25rem, env(safe-area-inset-right));
+ z-index: 400;
+ display: flex;
+ flex-direction: row;
+ align-items: flex-end;
+ gap: 10px;
+ pointer-events: none;
+}
+.room-lobby-br-fixed .lobby-b-extra-row,
+.room-lobby-br-fixed .btn-voice-icon {
+ pointer-events: auto;
+}
+.lobby-b-extra-row {
+ display: flex;
+ flex-direction: row;
+ align-items: flex-end;
+ gap: 10px;
+}
+.lobby-b-extra-row.is-hidden {
+ display: none !important;
+}
+/* โหมดเกม (ควิซ) ใน room-lobby — ไม่โชว์แว่น/ถ้วย LobbyB */
+body.room-lobby--quiz-active .lobby-b-extra-row {
+ display: none !important;
+ visibility: hidden !important;
+ pointer-events: none !important;
+}
+/* ปุ่มมุมขวาล่าง — ขนาดเดียวกัน (กัน UA border / box model ต่างกัน) */
+.room-lobby-br-fixed .lobby-b-sq-btn,
+.room-lobby-br-fixed .btn-voice-icon {
+ box-sizing: border-box;
+ width: var(--lobby-br-btn);
+ height: var(--lobby-br-btn);
+ min-width: var(--lobby-br-btn);
+ min-height: var(--lobby-br-btn);
+ max-width: var(--lobby-br-btn);
+ max-height: var(--lobby-br-btn);
+ margin: 0;
+ padding: 0;
+ border: none;
+ border-radius: 0;
+ appearance: none;
+ -webkit-appearance: none;
+ flex-shrink: 0;
+ cursor: pointer;
+ background: transparent;
+ box-shadow: none;
+}
+/* สไตล์เดียวกับปุ่มไมค์ — ไม่มีกรอบ cyan / bg-item */
+.lobby-b-sq-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: transform 0.15s ease, filter 0.15s ease;
+}
+.lobby-b-sq-btn:hover {
+ transform: scale(1.04);
+ filter: brightness(1.08);
+}
+.lobby-b-sq-btn:active { transform: scale(0.98); }
+.room-lobby-br-fixed .lobby-b-sq-btn img,
+.room-lobby-br-fixed .btn-voice-icon img {
+ width: 100%;
+ height: 100%;
+ max-width: 100%;
+ max-height: 100%;
+ object-fit: contain;
+ object-position: center;
+ display: block;
+ pointer-events: none;
+ user-select: none;
+ -webkit-user-drag: none;
+}
+.room-lobby-br-fixed .btn-voice-icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: transparent;
+}
+
+/* Desktop tuning: keep controls visibly large and readable */
+@media (min-width: 1024px) {
+ .room-lobby-chat-peers.chat-panel {
+ right: 0.9rem;
+ bottom: 11rem;
+ width: 454px;
+ height: 414px;
+ padding: 1.7rem 1.45rem 1.15rem;
+ border-radius: 0;
+ background: url(../img/chat-bg.png) center/100% 100% no-repeat;
+ border: none;
+ box-shadow: none;
+ backdrop-filter: none;
+ }
+ .room-lobby-chat-peers.chat-panel .chat-header-bar {
+ margin: 0;
+ padding: 0 0.15rem;
+ min-height: 58px;
+ height: 58px;
+ background: url(../img/chat-line.png) left bottom / 375px 4px no-repeat;
+ box-shadow: none;
+ }
+ .room-lobby-chat-peers.chat-panel .chat-header-title.chat-header-title-img img {
+ display: block;
+ width: 90px;
+ height: 77px;
+ object-fit: contain;
+ }
+ .room-lobby-chat-peers.chat-panel .chat-header-title.chat-header-title-img::before {
+ content: none;
+ display: none;
+ }
+ .room-lobby-chat-peers.chat-panel .chat-close-btn {
+ width: 58px;
+ height: 58px;
+ min-width: 58px;
+ min-height: 58px;
+ max-width: 58px;
+ max-height: 58px;
+ margin-left: auto;
+ }
+ .room-lobby-chat-peers.chat-panel .chat-close-btn img {
+ width: 58px;
+ height: 58px;
+ object-fit: contain;
+ }
+ .room-lobby-chat-peers.chat-panel #chat-messages {
+ width: calc(100% - 16px);
+ margin-right: 16px;
+ padding: 0.35rem 0.7rem 0.25rem 0.15rem;
+ font-size: 1rem;
+ line-height: 1.42;
+ gap: 0.42rem;
+ margin-top: 0.15rem;
+ margin-bottom: 0.2rem;
+ scrollbar-width: auto;
+ scrollbar-color: rgba(250, 253, 255, 0.98) rgba(12, 26, 47, 0.45);
+ box-sizing: border-box;
+ }
+ .room-lobby-chat-peers.chat-panel #chat-messages::-webkit-scrollbar {
+ width: 15px;
+ }
+ .room-lobby-chat-peers.chat-panel #chat-messages::-webkit-scrollbar-track {
+ border-radius: 999px;
+ background: rgba(20, 44, 72, 0.45);
+ border: 1px solid rgba(124, 221, 255, 0.3);
+ }
+ .room-lobby-chat-peers.chat-panel #chat-messages::-webkit-scrollbar-thumb {
+ border-radius: 999px;
+ background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(241, 249, 255, 0.98) 100%);
+ box-shadow: 0 0 8px rgba(182, 239, 255, 0.45);
+ }
+ .room-lobby-chat-peers.chat-panel .chat-msg {
+ max-width: 93%;
+ padding: 0.22rem 0.35rem;
+ font-size: 0.98rem;
+ border-radius: 10px;
+ background-image: none;
+ background-color: transparent;
+ box-shadow: none;
+ }
+ .room-lobby-chat-peers.chat-panel .chat-msg-other {
+ color: #d5bb63;
+ font-weight: 500;
+ }
+ .room-lobby-chat-peers.chat-panel .chat-msg-mine {
+ color: #cf74d1;
+ background-color: rgba(39, 67, 112, 0.82);
+ border: 1px solid rgba(116, 206, 255, 0.2);
+ align-self: flex-end;
+ text-align: left;
+ padding: 0.32rem 0.62rem;
+ }
+ .room-lobby-chat-peers.chat-panel .chat-form-bar {
+ padding: 0.24rem 0 0;
+ gap: 0;
+ align-items: center;
+ justify-content: space-between;
+ }
+ .room-lobby-chat-peers.chat-panel #chat-input {
+ margin-left: 17px;
+ width: 308px;
+ min-width: 308px;
+ max-width: 308px;
+ height: 61px;
+ min-height: 61px;
+ max-height: 61px;
+ padding: 0 0.95rem;
+ font-size: 0.95rem;
+ border-radius: 0;
+ border: none;
+ background: url(../img/chatbox.png) center/100% 100% no-repeat;
+ color: #e8f7ff;
+ }
+ .room-lobby-chat-peers.chat-panel #chat-input::placeholder {
+ color: rgba(195, 211, 236, 0.66);
+ }
+ .room-lobby-chat-peers.chat-panel .chat-send-btn {
+ width: 102px;
+ height: 98px;
+ min-width: 102px;
+ min-height: 98px;
+ max-width: 102px;
+ max-height: 98px;
+ margin-left: -26px;
+ margin-right: 2px;
+ }
+ .room-lobby-chat-peers.chat-panel .chat-send-btn img {
+ width: 102px;
+ height: 98px;
+ }
+ .room-lobby-top-left-cluster {
+ top: max(18px, env(safe-area-inset-top));
+ left: max(0px, env(safe-area-inset-left));
+ gap: 0;
+ }
+ .room-lobby-exit-fixed {
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: flex-start;
+ gap: 0.45rem;
+ margin-top: -1.4rem;
+ width: auto;
+ max-width: none;
+ }
+ .room-lobby-top-right-cluster {
+ top: max(16px, env(safe-area-inset-top));
+ right: max(16px, env(safe-area-inset-right));
+ }
+ .room-lobby-room-id-pill {
+ width: fit-content;
+ min-width: 0;
+ height: 180px;
+ min-height: 180px;
+ max-height: 180px;
+ max-width: none;
+ padding: 0 15px;
+ border-style: solid;
+ border-width: 0 60px;
+ border-radius: 0;
+ background: transparent;
+ border-image-source: url("../img/Room-id-BG.png");
+ border-image-slice: 0 60 0 60 fill;
+ border-image-repeat: stretch;
+ box-shadow: none;
+ gap: 0.7rem;
+ align-items: center;
+ white-space: nowrap;
+ }
+ .room-lobby-room-id-label {
+ font-size: 2.05rem;
+ font-weight: 600;
+ line-height: 1;
+ font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif;
+ text-transform: none;
+ color: #e8f7ff;
+ text-shadow:
+ 0 0 6px rgba(110, 226, 255, 0.8),
+ 0 0 14px rgba(44, 198, 255, 0.5);
+ }
+ #room-id-value {
+ font-size: 2.35rem;
+ line-height: 1;
+ font-family: 'NotoSansThai', 'Kanit', system-ui, sans-serif;
+ text-transform: none;
+ font-weight: 600;
+ color: #ecfbff;
+ text-shadow:
+ 0 0 7px rgba(118, 230, 255, 0.9),
+ 0 0 16px rgba(52, 203, 255, 0.55);
+ }
+ .room-lobby-room-id-lock {
+ width: 60px;
+ height: 65px;
+ min-width: 60px;
+ min-height: 65px;
+ max-width: 60px;
+ max-height: 65px;
+ aspect-ratio: 60 / 65;
+ font-size: 0;
+ color: transparent;
+ background: url("../img/Room-id-private.png") center / 100% 100% no-repeat;
+ filter: none;
+ }
+ .room-lobby-profile-frame {
+ width: 159px;
+ height: 157px;
+ min-width: 159px;
+ min-height: 157px;
+ max-width: 159px;
+ max-height: 157px;
+ aspect-ratio: 159 / 157;
+ }
+ .room-lobby-exit-fixed .btn-exit-icon {
+ width: 121px;
+ height: 119px;
+ min-width: 121px;
+ min-height: 119px;
+ max-width: 121px;
+ max-height: 119px;
+ aspect-ratio: 121 / 119;
+ margin-left: 13px;
+ margin-top: -15px;
+ margin-bottom: -15px;
+ }
+ body.room-lobby-page #room-players-hud {
+ min-width: 0;
+ font-size: clamp(1.35rem, 1.95vw, 1.9rem);
+ padding: 0.1rem 0.4rem;
+ }
+ .room-lobby-ready-fixed .ready-label-img {
+ width: 320px;
+ height: 126px;
+ min-width: 320px;
+ min-height: 126px;
+ max-width: 320px;
+ max-height: 126px;
+ aspect-ratio: 320 / 126;
+ }
+ .room-lobby-br-fixed {
+ --lobby-br-btn: 137px;
+ bottom: max(0.65rem, env(safe-area-inset-bottom));
+ right: max(0.85rem, env(safe-area-inset-right));
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: flex-end;
+ gap: 0.75rem;
+ }
+ /* แถวเดียว: หลักฐาน | อันดับ | ไมค์ (ตรง production) */
+ .room-lobby-br-fixed .lobby-b-extra-row:not(.is-hidden) {
+ display: contents;
+ }
+ .room-lobby-br-fixed .lobby-b-extra-row {
+ position: static !important;
+ margin: 0 !important;
+ transform: none !important;
+ z-index: auto;
+ }
+ .room-lobby-br-fixed .btn-voice-icon {
+ position: static !important;
+ margin: 0 !important;
+ transform: none !important;
+ }
+ .room-lobby-br-fixed .lobby-b-sq-btn,
+ .room-lobby-br-fixed .btn-voice-icon {
+ width: var(--lobby-br-btn);
+ height: var(--lobby-br-btn);
+ min-width: var(--lobby-br-btn);
+ min-height: var(--lobby-br-btn);
+ max-width: var(--lobby-br-btn);
+ max-height: var(--lobby-br-btn);
+ }
+ .room-lobby-chat-peers.chat-panel-collapsed.chat-panel {
+ width: 122px;
+ height: 120px;
+ bottom: 12rem;
+ right: max(0.85rem, env(safe-area-inset-right));
+ }
+ .room-lobby-chat-peers.chat-panel-collapsed .chat-close-btn {
+ width: 122px;
+ height: 120px;
+ min-width: 122px;
+ min-height: 120px;
+ max-width: 122px;
+ max-height: 120px;
+ aspect-ratio: 122 / 120;
+ margin-right: -20px;
+ }
+ .room-lobby-chat-peers.chat-panel-collapsed .chat-close-btn img {
+ width: 122px;
+ height: 120px;
+ aspect-ratio: 122 / 120;
+ }
+}
+
+/* แฟ้มหลักฐาน LobbyB — ดู css/evidence-view-overlay.css (layout ev-*) */
+
+/* กระดานอันดับ LobbyB — ดู css/leaderboard-popup.css */
+
+.version-tag {
+ position: fixed;
+ right: 8px;
+ bottom: 4px;
+ left: auto;
+ font-size: 10px;
+ color: #a9b1d6;
+ opacity: 0.7;
+ pointer-events: none;
+}
+
+/* Editor — เกมตอบคำถาม */
+.quiz-editor-wrap {
+ margin: 1rem 0;
+ padding: 1rem;
+ background: #24283b;
+ border-radius: 8px;
+ border: 1px solid #414868;
+}
+.quiz-editor-wrap h3 {
+ margin: 0 0 0.5rem;
+ font-size: 1rem;
+ color: #7aa2f7;
+}
+.quiz-questions-list {
+ display: flex;
+ flex-direction: column;
+ gap: 0.6rem;
+ margin: 0.75rem 0;
+}
+.quiz-q-row {
+ display: grid;
+ grid-template-columns: 1fr auto auto;
+ gap: 0.5rem;
+ align-items: center;
+}
+@media (max-width: 600px) {
+ .quiz-q-row {
+ grid-template-columns: 1fr;
+ }
+}
+.quiz-q-row input[type="text"] {
+ min-width: 0;
+ padding: 0.4rem 0.5rem;
+ border-radius: 6px;
+ border: 1px solid #565f89;
+ background: #1a1b26;
+ color: #c0caf5;
+}
+.quiz-q-row select {
+ padding: 0.35rem;
+ border-radius: 6px;
+ border: 1px solid #565f89;
+ background: #1a1b26;
+ color: #c0caf5;
+}
+.btn-quiz-add,
+.quiz-q-remove {
+ padding: 0.35rem 0.65rem;
+ border-radius: 6px;
+ cursor: pointer;
+ border: 1px solid #565f89;
+ background: #414868;
+ color: #c0caf5;
+ font: inherit;
+}
+.quiz-q-remove {
+ font-size: 0.8rem;
+}
+
+/* design 2026-05: แสดงปุ่มตั้งค่าโฮสต์ + ปรับแต่ง มุมขวาบน (ตาม TryChangeCSS/CSS ใหม่ — ไม่ใช้ JS เก่า) */
+body.room-lobby-page .room-lobby-top-right-actions {
+ display: none !important;
+}
+
+/* ---- Player Pick Vote overlay (Card Ban / Silence) — โหวตเลือกผู้เล่น ----
+ สร้างด้วย JS ใน room-lobby.js (#pick-vote-overlay) แต่เดิมไม่มี CSS เลย → div จมหลัง UI lobby มองไม่เห็น */
+#pick-vote-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 12000;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 4vh 4vw;
+ background: rgba(4, 8, 16, 0.74);
+ backdrop-filter: blur(4px);
+ -webkit-backdrop-filter: blur(4px);
+ opacity: 0;
+ visibility: hidden;
+ pointer-events: none;
+ transition: opacity 0.22s ease, visibility 0.22s ease;
+ font-family: 'Kanit', sans-serif;
+}
+#pick-vote-overlay.is-open {
+ opacity: 1;
+ visibility: visible;
+ pointer-events: auto;
+}
+#pick-vote-overlay .pv-shell {
+ width: min(460px, 92vw);
+ max-height: 88vh;
+ overflow-y: auto;
+ box-sizing: border-box;
+ padding: 1.4rem 1.5rem 1.6rem;
+ border-radius: 18px;
+ text-align: center;
+ color: #e8f6ff;
+ background: linear-gradient(165deg, rgba(16, 30, 50, 0.97), rgba(8, 16, 30, 0.97));
+ border: 1px solid rgba(83, 224, 255, 0.55);
+ box-shadow: 0 0 28px rgba(83, 224, 255, 0.35), inset 0 0 24px rgba(80, 180, 240, 0.14);
+ transform: translateY(12px) scale(0.97);
+ transition: transform 0.26s cubic-bezier(0.2, 0.9, 0.3, 1.2);
+}
+#pick-vote-overlay.is-open .pv-shell {
+ transform: translateY(0) scale(1);
+}
+#pick-vote-overlay .pv-badge {
+ display: inline-block;
+ padding: 0.2rem 0.85rem;
+ border-radius: 999px;
+ font-size: 0.74rem;
+ font-weight: 700;
+ letter-spacing: 0.08em;
+ color: #04121e;
+ background: linear-gradient(90deg, #53e0ff, #8ad8ff);
+ box-shadow: 0 0 14px rgba(83, 224, 255, 0.55);
+}
+#pick-vote-overlay .pv-title {
+ margin: 0.7rem 0 0.3rem;
+ font-size: 1.32rem;
+ font-weight: 700;
+ text-shadow: 0 0 12px rgba(83, 224, 255, 0.45);
+}
+#pick-vote-overlay .pv-sub {
+ margin: 0 0 0.7rem;
+ font-size: 0.86rem;
+ line-height: 1.35;
+ color: #a9c7da;
+}
+#pick-vote-overlay .pv-timer {
+ font-size: 1.5rem;
+ font-weight: 700;
+ color: #53e0ff;
+ margin-bottom: 0.6rem;
+ min-height: 1.4em;
+}
+#pick-vote-overlay .pv-timer.low {
+ color: #ff7a7a;
+ animation: pvPulse 0.7s ease-in-out infinite;
+}
+@keyframes pvPulse {
+ 0%, 100% { transform: scale(1); }
+ 50% { transform: scale(1.12); }
+}
+#pick-vote-overlay .pv-list {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ margin-bottom: 0.6rem;
+}
+#pick-vote-overlay .pv-cand {
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ width: 100%;
+ padding: 0.7rem 1rem;
+ border-radius: 12px;
+ font: 600 1rem 'Kanit', sans-serif;
+ color: #e8f6ff;
+ cursor: pointer;
+ background: rgba(28, 48, 74, 0.85);
+ border: 1px solid rgba(83, 224, 255, 0.3);
+ transition: transform 0.12s ease, border-color 0.15s ease, background 0.15s ease;
+}
+#pick-vote-overlay .pv-cand:hover {
+ transform: translateY(-1px);
+ border-color: rgba(83, 224, 255, 0.7);
+ background: rgba(36, 62, 94, 0.95);
+}
+#pick-vote-overlay .pv-cand.is-picked {
+ border-color: #53e0ff;
+ background: linear-gradient(90deg, rgba(83, 224, 255, 0.28), rgba(83, 224, 255, 0.14));
+ box-shadow: 0 0 14px rgba(83, 224, 255, 0.5);
+}
+#pick-vote-overlay .pv-me {
+ font-size: 0.78rem;
+ color: #8ad8ff;
+}
+#pick-vote-overlay .pv-bot {
+ font-size: 0.72rem;
+ color: #04121e;
+ background: #7fd4a8;
+ padding: 0.05rem 0.45rem;
+ border-radius: 999px;
+}
+#pick-vote-overlay .pv-count {
+ position: absolute;
+ right: 0.7rem;
+ min-width: 1.5em;
+ height: 1.5em;
+ line-height: 1.5em;
+ border-radius: 999px;
+ font-size: 0.82rem;
+ font-weight: 700;
+ color: #04121e;
+ background: #53e0ff;
+ opacity: 0;
+ transform: scale(0.6);
+ transition: opacity 0.15s ease, transform 0.15s ease;
+}
+#pick-vote-overlay .pv-count.show {
+ opacity: 1;
+ transform: scale(1);
+}
+#pick-vote-overlay .pv-result {
+ margin: 0.4rem 0;
+ padding: 0.7rem;
+ border-radius: 12px;
+ font-size: 1.05rem;
+ font-weight: 700;
+ color: #fff;
+ background: rgba(83, 224, 255, 0.16);
+ border: 1px solid rgba(83, 224, 255, 0.5);
+}
+#pick-vote-overlay .pv-foot {
+ font-size: 0.82rem;
+ color: #a9c7da;
+ min-height: 1.2em;
+}
+
+/* ===== มือถือ: ย่อปุ่ม AI chat ที่ใหญ่เกิน (213x201) + ปุ่ม interact (F) ให้พอดีจอ ===== */
+@media (max-width: 600px) {
+ .room-lobby-chat-ai.chat-panel-collapsed .chat-close-btn,
+ .room-lobby-chat-ai.chat-panel-collapsed .chat-close-btn img {
+ width: 92px !important;
+ height: 87px !important;
+ min-width: 92px !important;
+ min-height: 87px !important;
+ max-width: 92px !important;
+ max-height: 87px !important;
+ }
+ .room-lobby-chat-ai.chat-panel .chat-close-btn,
+ .room-lobby-chat-ai.chat-panel .chat-close-btn img {
+ width: 42px !important;
+ height: 42px !important;
+ }
+}
+
+/* ===== มือถือแนวนอน (จอเตี้ย) — ย่อ/จัด UI ห้องเกม (LobbyA) ให้พอดีไม่ล้น · อิงแนวทาง Main-Lobby · ไม่แตะ PC ===== */
+@media (orientation: landscape) and (max-height: 540px) {
+ /* ปุ่มมุมขวาล่าง (ไมค์ + แว่น/ถ้วย) — ย่อตามความสูงจอ */
+ .room-lobby-br-fixed { --lobby-br-btn: clamp(46px, 11vh, 64px); gap: 7px; }
+ /* แผงแชท — เดิม 576x525 ล้นจอแนวนอน → ย่อให้พอดีความสูงจอ */
+ .room-lobby-chat-peers.chat-panel {
+ width: min(360px, 52vw);
+ height: min(248px, calc(100dvh - 80px));
+ bottom: max(0.5rem, env(safe-area-inset-bottom));
+ padding: 0.9rem 1rem;
+ }
+ /* ปุ่มแชท AI (collapsed) — ย่อลงอีกบนแนวนอน */
+ .room-lobby-chat-ai.chat-panel-collapsed .chat-close-btn,
+ .room-lobby-chat-ai.chat-panel-collapsed .chat-close-btn img {
+ width: 62px !important; height: 58px !important;
+ min-width: 62px !important; min-height: 58px !important;
+ max-width: 62px !important; max-height: 58px !important;
+ }
+ /* ปุ่ม ready — เตี้ยลงเล็กน้อย ไม่ชนปุ่มอื่น */
+ .room-lobby-ready-fixed .ready-label-img { height: clamp(38px, 9.5vh, 58px); }
+ /* ปุ่ม exit/howto มุมซ้ายบน — อิงความสูงจอ */
+ .room-lobby-exit-fixed .btn-exit-icon {
+ width: clamp(46px, 10vh, 62px);
+ height: clamp(46px, 10vh, 62px);
+ min-width: clamp(46px, 10vh, 62px);
+ }
+}
diff --git a/www/html/Game/public/css/style.css b/www/html/Game/public/css/style.css
index f9e04a3..acec7b3 100644
--- a/www/html/Game/public/css/style.css
+++ b/www/html/Game/public/css/style.css
@@ -1,1988 +1,1999 @@
-* { box-sizing: border-box; }
-body { font-family: sans-serif; margin: 0; background: #1a1b26; color: #c0caf5; }
-.container { max-width: 720px; margin: 1rem auto; padding: 1rem; }
-
-/* โครง Editor — แยกแถบเครื่องมือ / พื้นที่วาด */
-.editor-page {
- display: block;
-}
-
-/* Editor ฝังใน Admin (?embed=1) — เต็มความสูง iframe, พื้นที่แคนวาสใหญ่ + เลื่อนแยก */
-html.editor-embed-admin {
- height: 100%;
-}
-html.editor-embed-admin body {
- height: 100%;
- margin: 0;
- overflow: hidden;
-}
-body.editor-embed-admin .version-tag {
- display: none !important;
-}
-body.editor-embed-admin .container.editor-page {
- max-width: none !important;
- width: 100%;
- height: 100%;
- margin: 0 !important;
- padding: 0.35rem 0.5rem 0.45rem;
- display: flex;
- flex-direction: column;
- min-height: 0;
- box-sizing: border-box;
-}
-body.editor-embed-admin .container.editor-page > h1 {
- display: none;
-}
-body.editor-embed-admin .editor-toolbar-wrap {
- /* อย่าให้แถบเครื่องมือถูก flex บีบแล้วล้นไปทับแคนวาส (body overflow:hidden) */
- flex: 0 0 auto;
- min-height: 0;
- max-height: min(56vh, 520px);
- overflow-x: hidden;
- overflow-y: auto;
- overscroll-behavior: contain;
- -webkit-overflow-scrolling: touch;
- padding: 0.15rem 0.35rem 0.5rem 0;
- margin: 0 0 0.35rem;
- border-bottom: 1px solid rgba(65, 72, 104, 0.9);
- position: relative;
- z-index: 1;
- background: linear-gradient(180deg, #1a1b26 0%, #16171f 100%);
-}
-body.editor-embed-admin .editor-workspace {
- flex: 1 1 auto;
- min-height: 0;
- display: flex;
- flex-direction: column;
- overflow: hidden;
- position: relative;
- z-index: 0;
-}
-body.editor-embed-admin .canvas-wrap {
- flex: 1 1 auto;
- min-height: 140px;
- overflow: auto;
- margin: 0 !important;
- border-radius: 10px;
- border: 1px solid #414868;
- background: #0f1018;
- -webkit-overflow-scrolling: touch;
- touch-action: pan-x pan-y;
-}
-body.editor-embed-admin #editor-status {
- flex: 0 0 auto;
- margin: 0.3rem 0 0;
- font-size: 0.8rem;
- line-height: 1.35;
-}
-body.editor-embed-admin .editor-legend-short {
- margin: 0;
- font-size: 0.76rem;
- line-height: 1.45;
- color: #a8b0d0;
-}
-body.editor-embed-admin .editor-toolbar-grid {
- gap: 0.45rem;
-}
-/* การ์ด «ประเภทเกม» ข้อความยาว — ให้กว้างเต็มแถวบนจอแคบ ลดการอัดคอลัมน์ */
-@media (max-width: 720px) {
- body.editor-embed-admin .editor-toolbar-grid .editor-card:first-child {
- grid-column: 1 / -1;
- }
-}
-body.editor-embed-admin .editor-card {
- padding: 0.45rem 0.55rem;
- margin-bottom: 0;
-}
-body.editor-embed-admin .editor-card__title {
- font-size: 0.68rem;
- margin-bottom: 0.3rem;
-}
-body.editor-embed-admin .editor-card__hint {
- font-size: 0.72rem;
- margin-top: 0.3rem;
- overflow-wrap: break-word;
- word-break: break-word;
-}
-body.editor-embed-admin .game-type-hint .editor-hint-lead {
- font-size: 0.78rem;
- margin-bottom: 0.35rem;
-}
-body.editor-embed-admin .game-type-hint .editor-hint-bullets {
- padding-left: 1.05rem;
-}
-body.editor-embed-admin .game-type-hint .editor-hint-bullets li {
- margin: 0.26rem 0;
- font-size: 0.72rem;
- line-height: 1.45;
-}
-body.editor-embed-admin .frogger-lanes {
- margin: 0.35rem 0;
- position: relative;
- z-index: auto;
-}
-body.editor-embed-admin .editor-card--bg {
- margin-top: 0.25rem;
-}
-body.editor-embed-admin .editor-card--help {
- margin-top: 0.2rem;
-}
-h1 { color: #7aa2f7; }
-a { color: #9ece6a; }
-label { display: inline-block; margin: 0.25rem 0.5rem 0.25rem 0; }
-input, button { padding: 0.4rem 0.6rem; margin: 0 0.25rem 0 0; border-radius: 6px; border: 1px solid #414868; }
-input { background: #24283b; color: #c0caf5; }
-button { background: #7aa2f7; color: #1a1b26; cursor: pointer; border: none; }
-.legend { font-size: 0.9rem; color: #a9b1d6; margin: 0.5rem 0; }
-.frogger-lanes { margin: 1rem 0; padding: 0.75rem; background: #24283b; border-radius: 8px; position: relative; z-index: 2; min-height: 80px; }
-.frogger-lanes h3 { margin: 0 0 0.5rem 0; color: #7aa2f7; font-size: 1rem; }
-.frogger-lanes table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
-.frogger-lanes th, .frogger-lanes td { padding: 0.25rem 0.5rem; text-align: left; border: 1px solid #414868; }
-.frogger-lanes select, .frogger-lanes input[type="number"] { padding: 0.35rem 0.5rem; min-width: 4rem; background: #1a1b26; color: #c0caf5; border: 1px solid #414868; border-radius: 4px; cursor: pointer; font-size: 0.9rem; }
-.frogger-lanes select { min-width: 6rem; }
-.frogger-lanes .lane-speed { width: 4rem; }
-.frogger-lanes .lane-spacing { width: 4rem; }
-.frogger-lanes td { vertical-align: middle; }
-.frogger-lanes select:disabled, .frogger-lanes input:disabled { opacity: 0.6; cursor: not-allowed; }
-.game-type-hint {
- font-size: 0.85rem;
- color: #a9b1d6;
- margin: 0;
- line-height: 1.5;
- display: block;
-}
-.game-type-hint .editor-hint-lead {
- margin: 0 0 0.45rem;
- font-size: 0.9rem;
- font-weight: 500;
- color: #c0caf5;
- line-height: 1.4;
-}
-.game-type-hint .editor-hint-lead:last-child {
- margin-bottom: 0;
-}
-.editor-hint-bullets {
- margin: 0;
- padding-left: 1.2rem;
- list-style: disc;
-}
-.editor-hint-bullets li {
- margin: 0.35rem 0;
-}
-.editor-hint-bullets li:first-child {
- margin-top: 0;
-}
-.editor-hint-bullets li:last-child {
- margin-bottom: 0;
-}
-.game-type-hint .editor-hint-bullets code {
- font-size: 0.88em;
-}
-.game-type-hint kbd {
- display: inline-block;
- font-size: 0.82em;
- padding: 0.1em 0.38em;
- margin: 0 0.06em;
- border-radius: 4px;
- background: #1a1b26;
- border: 1px solid #414868;
- font-family: ui-monospace, monospace;
- color: #c0caf5;
-}
-
-/* Editor — การ์ดจัดกลุ่มเครื่องมือ (อ่านง่าย ไม่บีบเป็นแถบเดียวยาว) */
-.editor-toolbar-grid {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
- gap: 0.65rem;
- margin: 0.75rem 0 0.5rem;
- align-items: start;
-}
-.editor-card {
- margin: 0;
- padding: 0.65rem 0.75rem;
- background: #24283b;
- border: 1px solid rgba(65, 72, 104, 0.95);
- border-radius: 10px;
-}
-.editor-card--wide {
- grid-column: 1 / -1;
-}
-.editor-card__title {
- margin: 0 0 0.45rem 0;
- padding: 0;
- font-size: 0.72rem;
- font-weight: 700;
- letter-spacing: 0.04em;
- text-transform: uppercase;
- color: #7aa2f7;
-}
-.editor-card__row {
- display: flex;
- flex-wrap: wrap;
- align-items: flex-end;
- gap: 0.45rem 0.75rem;
-}
-.editor-card__row--wrap {
- align-items: center;
-}
-.editor-card__row--actions {
- margin-top: 0.55rem;
- padding-top: 0.5rem;
- border-top: 1px solid rgba(65, 72, 104, 0.75);
- gap: 0.5rem;
-}
-.editor-card__hint {
- margin: 0.4rem 0 0;
- padding: 0.45rem 0.55rem;
- background: rgba(15, 16, 24, 0.55);
- border-radius: 6px;
- border-left: 3px solid #7aa2f7;
-}
-.editor-card label { margin: 0; }
-/* กลุ่มกล่องตรวจ: ชนกำแพง vs โซนห้ามซ้อน — แยกมองชัดจากแถว label เปล่า ๆ */
-.editor-footprint-row {
- display: flex;
- flex-wrap: wrap;
- align-items: center;
- gap: 0.45rem 0.85rem;
- width: 100%;
- padding: 0.42rem 0.55rem 0.48rem;
- border-radius: 8px;
- border: 1px solid rgba(122, 162, 247, 0.38);
- background: rgba(20, 22, 34, 0.72);
- box-sizing: border-box;
-}
-.editor-footprint-row--wall {
- border-color: rgba(122, 162, 247, 0.45);
- background: rgba(26, 32, 52, 0.65);
-}
-.editor-footprint-row--no-overlap {
- border-color: rgba(158, 206, 106, 0.5);
- background: rgba(22, 34, 26, 0.55);
-}
-.editor-footprint-row__head {
- flex: 0 0 100%;
- margin: 0 0 0.08rem 0;
- padding: 0;
- font-size: 0.68rem;
- font-weight: 700;
- letter-spacing: 0.06em;
- text-transform: uppercase;
- color: #7aa2f7;
-}
-.editor-footprint-row--no-overlap .editor-footprint-row__head {
- color: #9ece6a;
-}
-.editor-footprint-row .editor-footprint-row__field input[type="number"] {
- width: 3.1rem;
- margin-left: 0.2rem;
-}
-.editor-field-grow {
- flex: 1 1 180px;
- min-width: min(100%, 200px);
-}
-.editor-field-grow select,
-.editor-field-grow input[type="text"] {
- width: 100%;
- max-width: 100%;
- min-width: 0;
-}
-.editor-field-drawmode {
- flex: 1 1 280px;
- min-width: min(100%, 240px);
-}
-.editor-field-drawmode select {
- width: 100%;
- max-width: 100%;
- min-width: 0;
-}
-.editor-cell-color {
- display: inline-flex;
- flex-wrap: wrap;
- align-items: center;
- gap: 0.35rem 0.75rem;
-}
-.editor-grid-image-tools {
- display: none;
- flex-direction: column;
- align-items: stretch;
- gap: 0.5rem;
- max-width: 100%;
- width: min(100%, 520px);
-}
-.editor-grid-image-size-row {
- display: flex;
- flex-wrap: wrap;
- gap: 0.5rem 1rem;
- align-items: center;
-}
-.editor-grid-image-size-row input[type="number"] {
- width: 3.2rem;
- margin-left: 0.25rem;
-}
-.editor-grid-image-carry-bind-row {
- display: flex;
- flex-wrap: wrap;
- gap: 0.35rem 0.75rem;
- align-items: center;
- font-size: 0.72rem;
- color: #a9b1d6;
-}
-.editor-grid-image-carry-bind-row select {
- margin-left: 0.35rem;
- max-width: 12rem;
-}
-.editor-hint-inline {
- font-size: 0.68rem;
- color: #787c99;
- line-height: 1.35;
- flex: 1 1 140px;
-}
-.editor-grid-image-gallery-wrap {
- display: flex;
- flex-direction: column;
- gap: 0.25rem;
-}
-.editor-grid-image-gallery-label {
- font-size: 0.72rem;
- color: #a9b1d6;
- font-weight: 600;
-}
-.editor-grid-image-gallery-note {
- margin: 0.1rem 0 0.35rem;
- font-size: 0.65rem;
- line-height: 1.35;
- color: #787c99;
- max-width: 36rem;
-}
-.grid-cell-image-gallery {
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(68px, 1fr));
- gap: 0.4rem;
- max-height: 200px;
- overflow-y: auto;
- padding: 0.35rem;
- border-radius: 8px;
- border: 1px solid rgba(65, 72, 104, 0.85);
- background: rgba(15, 16, 24, 0.6);
-}
-.grid-cell-image-gallery-empty {
- font-size: 0.72rem;
- color: #787c99;
- padding: 0.35rem;
-}
-.grid-cell-image-gallery-item {
- position: relative;
- padding: 0;
- margin: 0;
- border: 2px solid transparent;
- border-radius: 8px;
- overflow: hidden;
- cursor: pointer;
- background: #24283b;
- line-height: 0;
-}
-.grid-cell-image-gallery-item.is-selected {
- border-color: #9ece6a;
- box-shadow: 0 0 0 1px rgba(158, 206, 106, 0.35);
-}
-.grid-cell-image-gallery-item img {
- display: block;
- width: 100%;
- height: 56px;
- object-fit: cover;
-}
-.grid-cell-image-gallery-row {
- display: flex;
- flex-direction: column;
- gap: 0.35rem;
- align-items: stretch;
-}
-.grid-cell-image-gallery-same-hint {
- font-size: 0.62rem;
- line-height: 1.35;
- color: #f7768e;
- padding: 0.2rem 0.35rem;
- border-radius: 4px;
- background: rgba(247, 118, 142, 0.12);
- border: 1px solid rgba(247, 118, 142, 0.35);
-}
-.grid-cell-image-gallery-held-side {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 0.2rem;
- padding: 0.15rem 0.1rem 0.25rem;
- border-radius: 6px;
- background: rgba(0, 0, 0, 0.22);
-}
-.grid-cell-image-gallery-held-label {
- font-size: 0.58rem;
- font-weight: 700;
- color: #7dcfff;
- letter-spacing: 0.04em;
-}
-.grid-cell-image-gallery-held-thumb {
- display: block;
- width: 100%;
- max-height: 44px;
- object-fit: cover;
- border-radius: 4px;
- background: #1a1b26;
-}
-.grid-cell-image-gallery-held-btn {
- font-size: 0.58rem;
- padding: 0.15rem 0.35rem;
- border-radius: 4px;
- border: 1px solid rgba(125, 207, 255, 0.45);
- background: rgba(26, 27, 38, 0.95);
- color: #c0caf5;
- cursor: pointer;
-}
-.grid-cell-image-gallery-held-btn:hover {
- border-color: rgba(158, 206, 106, 0.65);
- color: #9ece6a;
-}
-.grid-cell-image-gallery-clear-held {
- font-size: 0.7rem;
- line-height: 1;
- padding: 0.05rem 0.25rem;
- border: none;
- border-radius: 4px;
- background: rgba(247, 118, 142, 0.25);
- color: #f7768e;
- cursor: pointer;
-}
-.grid-cell-image-gallery-clear-held:hover {
- background: rgba(247, 118, 142, 0.45);
-}
-.grid-cell-image-gallery-cap {
- display: block;
- font-size: 0.65rem;
- text-align: center;
- padding: 0.15rem 0;
- color: #c0caf5;
- background: rgba(0, 0, 0, 0.35);
-}
-.editor-grid-image-upload-row {
- display: flex;
- flex-wrap: wrap;
- align-items: center;
- gap: 0.5rem;
-}
-body.editor-embed-admin .grid-cell-image-gallery {
- max-height: 160px;
-}
-body.editor-embed-admin .grid-cell-image-gallery-item img {
- height: 48px;
-}
-.editor-btn-primary {
- font-weight: 600;
-}
-.editor-card--bg {
- margin: 0.5rem 0 0.35rem;
-}
-.editor-card--help {
- margin: 0.35rem 0 0.15rem;
-}
-.editor-help-list {
- margin: 0;
- padding-left: 1.15rem;
- list-style: disc;
-}
-.editor-help-list li {
- margin-bottom: 0.28rem;
-}
-@media (min-width: 900px) {
- .editor-help-list {
- columns: 2;
- column-gap: 1.5rem;
- }
- .editor-help-list li {
- break-inside: avoid;
- }
-}
-.canvas-wrap { margin: 1rem 0; }
-.container { padding-left: 1rem; padding-right: 1rem; }
-#editor-canvas {
- background: #1a1b26;
- display: block;
- touch-action: none;
- image-rendering: pixelated;
- image-rendering: crisp-edges;
-}
-.editor-map-zoom-bar {
- display: flex;
- align-items: center;
- gap: 5px;
- padding: 6px 10px;
- border-radius: 999px;
- background: rgba(8, 12, 28, 0.88);
- border: 1px solid #2a3357;
- box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
-}
-.editor-map-zoom-btn {
- border: 1px solid #2a3357;
- background: #0d1430;
- color: #eef2ff;
- border-radius: 8px;
- min-width: 34px;
- height: 32px;
- padding: 0 8px;
- cursor: pointer;
- font: inherit;
- font-weight: 700;
- line-height: 1;
-}
-.editor-map-zoom-btn:hover { filter: brightness(1.2); }
-.editor-map-zoom-label {
- min-width: 46px;
- text-align: center;
- font-size: 12px;
- font-weight: 700;
- color: #c7d2fe;
- user-select: none;
-}
-.game-wrap { display: flex; flex-direction: column; height: 100vh; height: 100dvh; min-height: 0; }
-.game-header { flex-shrink: 0; background: #24283b; padding: 0.5rem 1rem; display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; }
-.game-header span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
-.game-header button { flex-shrink: 0; }
-#game-canvas {
- flex: 1 1 auto;
- display: block;
- width: 100%;
- min-height: 0;
- min-width: 0;
- touch-action: none;
- image-rendering: pixelated;
- image-rendering: crisp-edges;
-}
-.game-wrap .chat-panel { flex-shrink: 0; }
-.chat-panel { height: 160px; border-top: 1px solid #414868; display: flex; flex-direction: column; }
-#chat-messages { flex: 1; overflow-y: auto; padding: 0.5rem; font-size: 0.9rem; }
-#chat-form { display: flex; padding: 0.5rem; gap: 0.5rem; }
-#chat-input { flex: 1; }
-
-.lobby-section { margin: 1.25rem 0; padding: 1rem; background: #24283b; border-radius: 8px; }
-.lobby-section h2 { margin: 0 0 0.75rem 0; font-size: 1rem; color: #7aa2f7; }
-#room-list { list-style: none; margin: 0; padding: 0; }
-#room-list .room-item { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; padding: 0.5rem 0; border-bottom: 1px solid #414868; }
-#room-list .room-item:last-child { border-bottom: none; }
-#room-list .room-name { font-weight: 600; color: #c0caf5; min-width: 0; }
-#room-list .room-meta { font-size: 0.85rem; color: #a9b1d6; }
-#room-list .room-meta-inline { font-size: 0.8rem; color: #565f89; font-weight: normal; }
-#room-list-status { margin: 0; color: #a9b1d6; font-size: 0.9rem; }
-
-.room-lobby-peers { margin: 1rem 0; padding: 0.75rem; background: #24283b; border-radius: 8px; }
-.room-lobby-peer { padding: 0.35rem 0; color: #c0caf5; }
-.room-lobby-peer:not(:last-child) { border-bottom: 1px solid #414868; }
-#lobby-map-wrap { position: fixed; top: 0; left: 0; right: 0; bottom: 0; width: 100%; height: 100%; min-width: 100vw; min-height: 100vh; z-index: 0; }
-#lobby-map-canvas {
- display: block;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- width: 100%;
- height: 100%;
- min-width: 100%;
- min-height: 100%;
- margin: 0;
- padding: 0;
- background: #303770;
- box-sizing: border-box;
-}
-#lobby-map-canvas:focus {
- outline: none;
-}
-#lobby-map-canvas:focus-visible {
- outline: 2px solid rgba(122, 162, 247, 0.45);
- outline-offset: -2px;
-}
-/* LobbyB (mn8nx46h) — ไม่แสดงปุ่มพร้อม */
-body.room-lobby--lobby-b .room-lobby-ready-fixed {
- display: none !important;
-}
-.lobby-interact-hint {
- position: absolute;
- bottom: max(10px, env(safe-area-inset-bottom));
- left: 50%;
- transform: translateX(-50%);
- z-index: 2;
- margin: 0;
- padding: 0.2rem 0.55rem;
- font-size: clamp(0.72rem, 1.8vw, 0.85rem);
- color: rgba(203, 213, 245, 0.9);
- text-shadow: 0 1px 10px rgba(0, 0, 0, 0.55);
- pointer-events: none;
- font-family: system-ui, 'Kanit', sans-serif;
- white-space: nowrap;
-}
-.lobby-interact-hint kbd {
- display: inline-block;
- padding: 0.06em 0.32em;
- border-radius: 4px;
- background: rgba(26, 27, 38, 0.88);
- border: 1px solid rgba(122, 162, 247, 0.45);
- font-size: 0.88em;
- font-family: inherit;
-}
-.lobby-zoom-pct {
- position: absolute;
- top: 12px;
- left: 50%;
- transform: translateX(-50%);
- z-index: 2;
- padding: 6px 12px;
- border-radius: 8px;
- background: rgba(26, 27, 38, 0.85);
- color: #c0caf5;
- font-size: 1rem;
- font-weight: 600;
- pointer-events: none;
- opacity: 0;
- transition: opacity 0.2s ease;
-}
-.lobby-zoom-pct.lobby-zoom-pct-visible { opacity: 1; }
-/* ซ่อนแผง overlay รายชื่อ / host / แชท — โถงโฟกัสแผนที่ + ปุ่ม READY/ไมค์ ด้านนอก */
-.room-lobby-overlay { display: none !important; }
-.room-lobby-top-left-cluster {
- position: fixed;
- top: max(12px, env(safe-area-inset-top));
- left: max(12px, env(safe-area-inset-left));
- z-index: 55;
- display: flex;
- flex-direction: column;
- align-items: flex-start;
- gap: 0.65rem;
- pointer-events: none;
-}
-.room-lobby-top-left-cluster .room-lobby-exit-fixed {
- pointer-events: auto;
-}
-
-/* มุมขวาบน — โปรไฟล์ตัวละคร */
-.room-lobby-top-right-cluster {
- position: fixed;
- top: max(12px, env(safe-area-inset-top));
- right: max(12px, env(safe-area-inset-right));
- z-index: 56;
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- gap: 0.65rem;
- pointer-events: none;
-}
-.room-lobby-top-right-cluster > * {
- pointer-events: auto;
-}
-.room-lobby-profile-wrap {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 0.2rem;
-}
-.room-lobby-profile-frame {
- width: clamp(56px, 12vw, 72px);
- height: clamp(56px, 12vw, 72px);
- border-radius: 14px;
- border: 2px solid rgba(0, 212, 255, 0.65);
- overflow: hidden;
- background: rgba(18, 22, 42, 0.92);
- box-shadow:
- 0 0 0 1px rgba(34, 211, 238, 0.2),
- 0 0 22px rgba(34, 211, 238, 0.28);
-}
-.room-lobby-profile-frame img {
- display: block;
- width: 100%;
- height: 100%;
- object-fit: cover;
- object-position: center bottom;
- image-rendering: pixelated;
- image-rendering: crisp-edges;
-}
-.room-lobby-actions { margin-top: 1rem; display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; }
-.room-lobby-actions .room-lobby-btn-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0; opacity: 0; pointer-events: none; }
-.room-lobby-actions label { margin: 0; }
-.room-lobby-actions #btn-start { background: #9ece6a; color: #1a1b26; }
-#host-only { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; }
-#host-only select { padding: 0.4rem 0.6rem; border-radius: 6px; border: 1px solid #414868; background: #24283b; color: #c0caf5; }
-.host-start-area-hint {
- flex-basis: 100%;
- margin: 0;
- font-size: 0.88rem;
- color: #e0af68;
- line-height: 1.35;
- max-width: 100%;
-}
-#host-only #btn-start:disabled {
- opacity: 0.5;
- cursor: not-allowed;
- filter: grayscale(0.25);
-}
-.room-lobby-chat { margin-top: 1rem; }
-.room-lobby-chat.chat-panel {
- border-radius: 12px;
- overflow: hidden;
- box-shadow: none;
-}
-.room-lobby-chat-peers.chat-panel {
- position: fixed;
- right: 1.25rem;
- bottom: 5.5rem;
- width: 576px;
- height: 525px;
- max-width: calc(100vw - 2.5rem);
- z-index: 52;
- margin-top: 0;
- display: flex;
- flex-flow: column;
- padding: 2rem;
- box-sizing: border-box;
- border-top: 0px solid #414868;
- background: url(/Game/img/chat-msg-bg-alpha.png) center/100% 100% no-repeat;
- background-color: transparent;
-}
-.room-lobby-chat-peers.chat-panel .chat-header-title.chat-header-title-img img { width: 90px; height: 77px; }
-.room-lobby-chat-peers.chat-panel .chat-close-btn { width: 48px; height: 48px; }
-.room-lobby-chat-peers.chat-panel .chat-close-btn img { width: 50px; height: 50px; }
-.room-lobby-chat-peers.chat-panel #chat-messages { padding: 0.75rem; font-size: 1.05rem; gap: 0.5rem; }
-.room-lobby-chat-peers.chat-panel .chat-form-bar { padding: 0.6rem 0; gap: 0.5rem; }
-.room-lobby-chat-peers.chat-panel #chat-input { padding: 0.6rem 0.85rem; font-size: 1.05rem; }
-.room-lobby-chat-peers.chat-panel .chat-send-btn { width: 52px; height: 52px; }
-.room-lobby-chat-peers.chat-panel .chat-send-btn img { width: 58px; height: 58px; }
-.room-lobby-chat-peers.chat-panel .chat-msg { padding: 0.6rem 1rem; font-size: 1.05rem; }
-.room-lobby-chat-peers.chat-panel .chat-header-bar {
- margin: 0 -2rem 0 -2rem;
- padding-left: 2rem;
- padding-right: 2rem;
- justify-content: space-between;
- align-items: center;
- min-height: 72px;
- height: 72px;
-}
-.room-lobby-chat-peers.chat-panel #chat-messages {
- flex: 1;
- min-height: 0;
- height: auto;
-}
-.room-lobby-chat .chat-header-bar {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0;
- min-height: 48px;
- height: 48px;
- background: url(/Game/img/chat-line.png) bottom repeat-x;
- background-size: 100% 4px;
- background-color: transparent;
-}
-.room-lobby-chat-peers .chat-header-title.chat-header-title-img {
- display: inline-flex;
- align-items: center;
- line-height: 0;
-}
-.room-lobby-chat-peers .chat-header-title.chat-header-title-img img {
- width: 60px;
- height: 51px;
- object-fit: contain;
- display: block;
-}
-.room-lobby-chat-ai .chat-header-title.chat-header-title-img {
- display: flex;
- align-items: flex-end;
- gap: 0.5rem;
- line-height: 0;
-}
-.room-lobby-chat-ai .chat-header-title.chat-header-title-img .ai-chat-title-label {
- height: 52px;
- width: auto;
- object-fit: contain;
- display: block;
- flex-shrink: 0;
- margin-bottom: -2px;
-}
-/* รูปหัวแชท AI — ยกขึ้นเหนือเส้น */
-.room-lobby-chat-ai .chat-header-title.chat-header-title-img img {
- width: 86px;
- height: 92px;
- object-fit: cover;
- display: block;
- flex-shrink: 0;
- margin-top: -27px;
- margin-left: -6px;
- position: relative;
- z-index: 1;
-}
-.room-lobby-chat .chat-header-title {
- font-size: 1rem;
- font-weight: 600;
- color: #a0aec0;
-}
-.room-lobby-chat .chat-close-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 32px;
- height: 32px;
- padding: 0;
- border: none;
- border-radius: 8px;
- background: transparent;
- cursor: pointer;
- margin-left: auto;
-}
-.room-lobby-chat-peers .chat-header-bar .chat-close-btn { margin-left: 0; }
-.room-lobby-chat .chat-close-btn img { width: 34px; height: 34px; object-fit: contain; }
-.room-lobby-chat .chat-close-btn:hover { opacity: 0.9; }
-.room-lobby-chat.chat-panel-collapsed #chat-messages,
-.room-lobby-chat.chat-panel-collapsed .chat-form-bar { display: none !important; }
-.room-lobby-chat-peers.chat-panel-collapsed .chat-header-title { display: none !important; }
-.room-lobby-chat-peers.chat-panel-collapsed .chat-header-bar {
- justify-content: center;
- padding: 0;
- background: none !important;
- border: none;
-}
-.room-lobby-chat-peers.chat-panel-collapsed.chat-panel {
- width: 80px;
- height: 80px;
- min-height: 0;
- padding: 0;
- right: 1.25rem;
- bottom: 6.25rem;
- display: flex;
- align-items: center;
- justify-content: center;
- background: none !important;
- background-color: transparent !important;
- border: none;
- box-shadow: none;
-}
-.room-lobby-chat-peers.chat-panel-collapsed .chat-close-btn {
- width: 80px;
- height: 80px;
- overflow: visible;
-}
-.room-lobby-chat-peers.chat-panel-collapsed .chat-close-btn img {
- width: 100%;
- height: 100%;
- object-fit: contain;
- object-position: center;
- display: block;
-}
-.room-lobby-chat #chat-messages,
-.room-lobby-chat #ai-chat-messages {
- height: 100px;
- overflow-y: auto;
- padding: 0.5rem;
- font-size: 0.85rem;
- border: none;
- margin: 0;
- display: flex;
- flex-direction: column;
- gap: 0.35rem;
- background: none;
- background-color: transparent;
- box-shadow: none;
-}
-.room-lobby-chat .chat-messages-bg { border-radius: 0; }
-.room-lobby-chat #chat-form.chat-form-bar,
-.room-lobby-chat #ai-chat-form.chat-form-bar {
- display: flex;
- gap: 0.4rem;
- align-items: center;
- padding: 0.4rem 0;
- background: none;
- background-color: transparent;
- border-top: none;
- flex-shrink: 0;
-}
-.room-lobby-chat-peers .chat-form-bar {
- padding-left: 0;
- padding-right: 0;
-}
-.room-lobby-chat #chat-input,
-.room-lobby-chat #ai-chat-input {
- flex: 1;
- min-width: 0;
- padding: 0.45rem 0.6rem;
- border-radius: 10px;
- border: 1px solid rgba(0, 212, 255, 0.25);
- background: rgba(30, 35, 50, 0.8);
- color: #c0caf5;
- font-size: 0.9rem;
- box-sizing: border-box;
- margin-left: 9px;
-}
-.room-lobby-chat .chat-send-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 40px;
- height: 40px;
- flex-shrink: 0;
- padding: 0;
- border: none;
- border-radius: 10px;
- background: transparent;
- cursor: pointer;
-}
-.room-lobby-chat .chat-send-btn img { width: 45px; height: 45px; object-fit: contain; }
-.room-lobby-chat .chat-send-btn:hover { opacity: 0.9; }
-.room-lobby-chat .chat-msg {
- padding: 0.4rem 0.75rem;
- border-radius: 12px;
- max-width: 85%;
- background-size: 100% 100%;
- background-repeat: no-repeat;
- background-position: center;
-}
-.room-lobby-chat .chat-msg-mine {
- align-self: flex-end;
- text-align: right;
- background-image: url(/Game/img/chat-bubble-me.png);
- background-color: rgba(122, 162, 247, 0.9);
- color: #1a1b26;
-}
-.room-lobby-chat .chat-msg-other {
- align-self: flex-start;
- text-align: left;
- background-image: url(/Game/img/chat-bubble-friend.png);
- background-color: rgba(65, 72, 104, 0.9);
- color: #c0caf5;
-}
-.room-lobby-chat .chat-msg-ai {
- align-self: flex-start;
- text-align: left;
- background-image: url(/Game/img/chat-bubble-friend.png);
- background-color: rgba(158, 206, 106, 0.9);
- color: #1a1b26;
-}
-.room-lobby-chat .chat-msg-system {
- align-self: center;
- text-align: center;
- max-width: 95%;
- background-image: none;
- background-color: rgba(26, 27, 38, 0.72);
- color: #9aa5ce;
- font-size: 0.88rem;
- font-style: italic;
- padding: 0.35rem 0.6rem;
-}
-
-/* AI chat — loading แบบ Messenger (จุดกระโดด 3 จุด), อยู่ติดข้อความล่าสุดในลิสต์ */
-.room-lobby-chat .ai-chat-typing {
- display: flex;
- align-items: center;
- gap: 4px;
- padding: 12px 14px;
- min-height: 24px;
- flex-shrink: 0;
- background-image: url(/Game/img/chat-bubble-friend.png);
- background-color: rgba(158, 206, 106, 0.9);
- background-size: 100% 100%;
- background-repeat: no-repeat;
- background-position: center;
-}
-.room-lobby-chat .ai-typing-dot {
- width: 6px;
- height: 6px;
- border-radius: 50%;
- background: #1a1b26;
- animation: ai-typing-bounce 1.4s ease-in-out infinite both;
-}
-.room-lobby-chat .ai-typing-dot:nth-child(1) { animation-delay: 0s; }
-.room-lobby-chat .ai-typing-dot:nth-child(2) { animation-delay: 0.2s; }
-.room-lobby-chat .ai-typing-dot:nth-child(3) { animation-delay: 0.4s; }
-@keyframes ai-typing-bounce {
- 0%, 60%, 100% { transform: translateY(0); }
- 30% { transform: translateY(-6px); }
-}
-
-/* AI chat panel — ขนาดและตำแหน่งตาม reference (วงซ้าย) */
-.room-lobby-chat-ai.chat-panel {
- position: fixed;
- left: 20px;
- right: auto;
- bottom: 5.5rem;
- width: 576px;
- height: 525px;
- max-width: calc(100vw - 2.5rem);
- z-index: 51;
- margin-top: 0;
- display: flex;
- flex-flow: column;
- padding: 2rem;
- box-sizing: border-box;
- border-top: 0;
- background: url(/Game/img/chat-msg-bg-alpha.png) center/100% 100% no-repeat;
- background-color: transparent;
-}
-.room-lobby-chat-ai.chat-panel .chat-header-bar {
- margin: 0 -2rem 0 -2rem;
- padding-left: 2rem;
- padding-right: 2rem;
- justify-content: space-between;
- align-items: center;
- min-height: 80px;
- height: 80px;
- overflow: visible;
-}
-.room-lobby-chat-ai.chat-panel .chat-header-title.chat-header-title-img img { width: 130px; height: 138px; margin-top: -38px; margin-left: -8px; }
-.room-lobby-chat-ai.chat-panel .chat-header-title.chat-header-title-img .ai-chat-title-label { height: 78px; }
-.room-lobby-chat-ai.chat-panel .chat-close-btn { width: 48px; height: 48px; }
-.room-lobby-chat-ai.chat-panel .chat-close-btn img { width: 50px; height: 50px; }
-.room-lobby-chat-ai.chat-panel #ai-chat-messages { padding: 0.75rem; font-size: 1.05rem; gap: 0.5rem; }
-.room-lobby-chat-ai.chat-panel .chat-form-bar { padding: 0.6rem 0; gap: 0.5rem; }
-.room-lobby-chat-ai.chat-panel #ai-chat-input { padding: 0.6rem 0.85rem; font-size: 1.05rem; }
-.room-lobby-chat-ai.chat-panel .chat-send-btn { width: 52px; height: 52px; }
-.room-lobby-chat-ai.chat-panel .chat-send-btn img { width: 58px; height: 58px; }
-.room-lobby-chat-ai.chat-panel .chat-msg { padding: 0.6rem 1rem; font-size: 1.05rem; }
-.room-lobby-chat-ai.chat-panel .ai-chat-typing { padding: 14px 18px; min-height: 28px; }
-.room-lobby-chat-ai.chat-panel .ai-typing-dot { width: 8px; height: 8px; }
-.room-lobby-chat-ai.chat-panel {
- overflow: visible;
-}
-.room-lobby-chat-ai.chat-panel #ai-chat-messages {
- flex: 1;
- min-height: 0;
- height: auto;
-}
-.room-lobby-chat-ai .chat-form-bar {
- padding-left: 0;
- padding-right: 0;
-}
-.room-lobby-chat-ai .ai-chat-admin-link {
- margin: 0.35rem 0 0 0;
- font-size: 0.75rem;
- flex-shrink: 0;
-}
-/* AI chat collapsed */
-.room-lobby-chat-ai.chat-panel-collapsed #ai-chat-messages,
-.room-lobby-chat-ai.chat-panel-collapsed .chat-form-bar,
-.room-lobby-chat-ai.chat-panel-collapsed .ai-chat-admin-link { display: none !important; }
-.room-lobby-chat-ai.chat-panel-collapsed .chat-header-title { display: none !important; }
-.room-lobby-chat-ai.chat-panel-collapsed .chat-header-bar {
- justify-content: center;
- padding: 0;
- background: none !important;
- border: none;
-}
-.room-lobby-chat-ai.chat-panel-collapsed.chat-panel {
- width: 80px;
- height: 80px;
- min-height: 0;
- padding: 0;
- left: 20px;
- bottom: 1.25rem;
- display: flex;
- align-items: center;
- justify-content: center;
- background: none !important;
- background-color: transparent !important;
- border: none;
- box-shadow: none;
-}
-.room-lobby-chat-ai.chat-panel-collapsed .chat-close-btn {
- width: 80px;
- height: 80px;
- overflow: visible;
-}
-.room-lobby-chat-ai.chat-panel-collapsed .chat-close-btn img {
- width: 100%;
- height: 100%;
- object-fit: contain;
- object-position: center;
- display: block;
-}
-
-.room-lobby-exit-fixed {
- position: static;
- display: flex;
- flex-direction: row;
- flex-wrap: nowrap;
- align-items: center;
- justify-content: flex-start;
- gap: 10px;
- width: max-content;
- max-width: calc(100vw - 24px);
- box-sizing: border-box;
-}
-.room-lobby-exit-fixed .btn-exit-icon {
- display: flex;
- align-items: center;
- justify-content: center;
- flex: 0 0 auto;
- width: 80px;
- height: 80px;
- min-width: 80px;
- padding: 0;
- border: none;
- border-radius: 12px;
- background: transparent;
- cursor: pointer;
-}
-.room-lobby-exit-fixed .btn-exit-icon:hover {
- opacity: 0.9;
-}
-.room-lobby-exit-fixed .btn-exit-icon img {
- width: 100%;
- height: auto;
- object-fit: contain;
- display: block;
-}
-
-.room-lobby-ready-fixed {
- position: fixed;
- bottom: 1.25rem;
- left: 50%;
- transform: translateX(-50%);
- z-index: 120;
- pointer-events: none;
-}
-.room-lobby-ready-fixed .ready-label,
-.room-lobby-ready-fixed .ready-check-input {
- pointer-events: auto;
-}
-.room-lobby-ready-fixed .ready-label {
- position: relative;
- display: inline-block;
- padding: 0;
- margin: 0;
- border: none;
- border-radius: 0;
- background: transparent;
- box-shadow: none;
- cursor: pointer;
- transition: transform 0.15s ease, filter 0.15s ease;
- line-height: 0;
-}
-.room-lobby-ready-fixed .ready-label:hover {
- transform: scale(1.04);
- filter: brightness(1.08);
-}
-.room-lobby-ready-fixed .ready-label:active {
- transform: scale(0.98);
-}
-.room-lobby-ready-fixed .ready-check-input {
- position: absolute;
- inset: 0;
- width: 100%;
- height: 100%;
- margin: 0;
- opacity: 0;
- cursor: pointer;
- z-index: 2;
-}
-.room-lobby-ready-fixed .ready-label-img {
- display: block;
- height: clamp(44px, 8vh, 72px);
- width: auto;
- max-width: min(240px, 78vw);
- pointer-events: none;
- user-select: none;
- -webkit-user-drag: none;
-}
-.room-lobby-ready-fixed .ready-label--active .ready-label-img {
- filter: drop-shadow(0 0 10px rgba(158, 206, 106, 0.45));
-}
-
-/* มุมขวาล่าง — ไมค์ทุกห้อง + ปุ่ม LobbyB (แว่น/ถ้วย) */
-.room-lobby-br-fixed {
- --lobby-br-btn: 80px;
- position: fixed;
- bottom: 1.25rem;
- right: max(1.25rem, env(safe-area-inset-right));
- z-index: 400;
- display: flex;
- flex-direction: row;
- align-items: flex-end;
- gap: 10px;
- pointer-events: none;
-}
-.room-lobby-br-fixed .lobby-b-extra-row,
-.room-lobby-br-fixed .btn-voice-icon {
- pointer-events: auto;
-}
-.lobby-b-extra-row {
- display: flex;
- flex-direction: row;
- align-items: flex-end;
- gap: 10px;
-}
-.lobby-b-extra-row.is-hidden {
- display: none !important;
-}
-/* โหมดเกม (ควิซ) ใน room-lobby — ไม่โชว์แว่น/ถ้วย LobbyB */
-body.room-lobby--quiz-active .lobby-b-extra-row {
- display: none !important;
- visibility: hidden !important;
- pointer-events: none !important;
-}
-/* ปุ่มมุมขวาล่าง — ขนาดเดียวกัน (กัน UA border / box model ต่างกัน) */
-.room-lobby-br-fixed .lobby-b-sq-btn,
-.room-lobby-br-fixed .btn-voice-icon {
- box-sizing: border-box;
- width: var(--lobby-br-btn);
- height: var(--lobby-br-btn);
- min-width: var(--lobby-br-btn);
- min-height: var(--lobby-br-btn);
- max-width: var(--lobby-br-btn);
- max-height: var(--lobby-br-btn);
- margin: 0;
- padding: 0;
- border: none;
- border-radius: 12px;
- appearance: none;
- -webkit-appearance: none;
- flex-shrink: 0;
- cursor: pointer;
-}
-/* สไตล์เดียวกับปุ่มไมค์ — ไม่มีกรอบ cyan / bg-item */
-.lobby-b-sq-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- background: transparent;
- box-shadow: none;
- transition: transform 0.15s ease, filter 0.15s ease;
-}
-.lobby-b-sq-btn:hover {
- transform: scale(1.04);
- filter: brightness(1.08);
-}
-.lobby-b-sq-btn:active { transform: scale(0.98); }
-.room-lobby-br-fixed .lobby-b-sq-btn img,
-.room-lobby-br-fixed .btn-voice-icon img {
- width: 100%;
- height: 100%;
- max-width: 100%;
- max-height: 100%;
- object-fit: contain;
- object-position: center;
- display: block;
- pointer-events: none;
- user-select: none;
- -webkit-user-drag: none;
-}
-.room-lobby-br-fixed .btn-voice-icon {
- display: flex;
- align-items: center;
- justify-content: center;
- background: transparent;
-}
-
-/* —— แฟ้มหลักฐาน LobbyB (รูปจาก /Main-Lobby/IMAGE/See evidence) —— */
-.lobby-evidence-overlay {
- position: fixed;
- inset: 0;
- z-index: 10047;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
- box-sizing: border-box;
-}
-.lobby-evidence-overlay.is-hidden {
- display: none !important;
-}
-.lobby-evidence-backdrop {
- position: absolute;
- inset: 0;
- background: rgba(4, 8, 22, 0.78);
- backdrop-filter: blur(10px);
- -webkit-backdrop-filter: blur(10px);
- cursor: pointer;
-}
-.lobby-evidence-dialog {
- position: relative;
- z-index: 1;
- width: min(96vw, 900px);
- max-height: min(92vh, 920px);
- pointer-events: none;
-}
-.lobby-evidence-dialog * {
- pointer-events: auto;
-}
-.lobby-evidence-frame {
- position: relative;
- width: 100%;
- aspect-ratio: 1684 / 963;
- filter: drop-shadow(0 0 24px rgba(0, 255, 255, 0.12)) drop-shadow(0 0 40px rgba(255, 0, 255, 0.08));
-}
-.lobby-evidence-bg {
- display: block;
- width: 100%;
- height: 100%;
- object-fit: contain;
- object-position: center top;
- pointer-events: none;
- user-select: none;
- -webkit-user-drag: none;
-}
-.lobby-evidence-close {
- position: absolute;
- top: 5.5%;
- right: 4%;
- width: 8%;
- max-width: 56px;
- aspect-ratio: 1;
- padding: 0;
- margin: 0;
- border: none;
- border-radius: 10px;
- background: transparent;
- color: rgba(0, 255, 255, 0.95);
- font-size: clamp(1.25rem, 4vw, 2rem);
- line-height: 1;
- cursor: pointer;
- text-shadow: 0 0 12px rgba(0, 255, 255, 0.9);
- display: flex;
- align-items: center;
- justify-content: center;
- transition: transform 0.15s ease, filter 0.15s ease;
-}
-.lobby-evidence-close:hover {
- transform: scale(1.08);
- filter: brightness(1.15);
-}
-.lobby-evidence-tabs-layer {
- position: absolute;
- left: 7%;
- right: 7%;
- top: 15.5%;
- height: 13.5%;
- min-height: 36px;
-}
-.lobby-evidence-tabs-img {
- display: block;
- width: 100%;
- height: 100%;
- object-fit: contain;
- object-position: left center;
- pointer-events: none;
- user-select: none;
- -webkit-user-drag: none;
-}
-.lobby-evidence-tab-hits {
- position: absolute;
- inset: 0;
- display: flex;
- flex-direction: row;
- align-items: stretch;
- padding-left: 1.5%;
- padding-right: 0;
- box-sizing: border-box;
-}
-.lobby-evidence-tab-hit {
- flex: 0 0 13.2%;
- min-width: 0;
- height: 100%;
- padding: 0;
- margin: 0;
- border: none;
- background: transparent;
- cursor: pointer;
- border-radius: 8px;
-}
-.lobby-evidence-tab-hit:focus-visible {
- outline: 2px solid rgba(0, 255, 255, 0.9);
- outline-offset: 2px;
-}
-.lobby-evidence-tab-hit-spacer {
- flex: 1 1 auto;
- pointer-events: none;
-}
-.lobby-evidence-cards-root {
- position: absolute;
- left: 5%;
- right: 5%;
- top: 31%;
- bottom: 7%;
- display: flex;
- flex-direction: row;
- flex-wrap: nowrap;
- gap: clamp(6px, 1.2vw, 14px);
- align-items: stretch;
- justify-content: center;
- overflow-x: auto;
- overflow-y: hidden;
- scrollbar-width: thin;
- padding-bottom: 4px;
- box-sizing: border-box;
-}
-.lobby-evidence-card {
- flex: 1 1 0;
- min-width: min(200px, 28vw);
- max-width: 320px;
- display: flex;
- flex-direction: column;
- border-radius: 10px;
- padding: clamp(6px, 1vw, 10px);
- background: rgba(15, 20, 36, 0.92);
- box-sizing: border-box;
- box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 8px 24px rgba(0, 0, 0, 0.35);
-}
-.lobby-evidence-card--common {
- box-shadow: 0 0 0 2px rgba(180, 190, 200, 0.65), 0 0 16px rgba(200, 210, 220, 0.2), 0 8px 24px rgba(0, 0, 0, 0.35);
-}
-.lobby-evidence-card--rare {
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.85), 0 0 20px rgba(59, 130, 246, 0.35), 0 8px 24px rgba(0, 0, 0, 0.35);
-}
-.lobby-evidence-card--legendary {
- box-shadow: 0 0 0 2px rgba(234, 179, 8, 0.9), 0 0 22px rgba(250, 204, 21, 0.4), 0 8px 24px rgba(0, 0, 0, 0.35);
-}
-.lobby-evidence-card-head {
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- gap: 8px;
- margin-bottom: 6px;
-}
-.lobby-evidence-card-icon {
- flex-shrink: 0;
- width: 28px;
- height: 28px;
- border-radius: 6px;
- background: linear-gradient(135deg, rgba(0, 255, 255, 0.25), rgba(255, 0, 255, 0.15));
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 14px;
- line-height: 1;
-}
-.lobby-evidence-card-titles {
- flex: 1;
- min-width: 0;
-}
-.lobby-evidence-card-title-th {
- font-family: 'Sarabun', 'Kanit', system-ui, sans-serif;
- font-size: clamp(0.68rem, 1.35vw, 0.82rem);
- font-weight: 700;
- color: #e8ecff;
- line-height: 1.25;
- margin: 0;
-}
-.lobby-evidence-card-title-en {
- font-family: system-ui, sans-serif;
- font-size: clamp(0.58rem, 1.05vw, 0.68rem);
- color: rgba(180, 190, 220, 0.85);
- margin: 2px 0 0;
- line-height: 1.2;
-}
-.lobby-evidence-card-art {
- flex: 1 1 auto;
- min-height: clamp(72px, 14vh, 140px);
- max-height: min(22vh, 200px);
- border-radius: 8px;
- background: linear-gradient(160deg, rgba(30, 40, 70, 0.95), rgba(12, 16, 32, 0.98));
- border: 1px solid rgba(0, 255, 255, 0.12);
- margin-bottom: 6px;
- display: flex;
- align-items: center;
- justify-content: center;
- color: rgba(0, 255, 255, 0.35);
- font-size: clamp(1.5rem, 4vw, 2.25rem);
- user-select: none;
-}
-.lobby-evidence-card-body {
- font-family: 'Sarabun', 'Kanit', system-ui, sans-serif;
- font-size: clamp(0.6rem, 1.15vw, 0.72rem);
- color: rgba(210, 218, 240, 0.92);
- line-height: 1.4;
- margin: 0 0 8px;
- flex-shrink: 0;
- max-height: 4.5em;
- overflow: hidden;
- display: -webkit-box;
- -webkit-line-clamp: 4;
- -webkit-box-orient: vertical;
-}
-.lobby-evidence-card-foot {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- gap: 8px;
- margin-top: auto;
- flex-shrink: 0;
-}
-.lobby-evidence-link {
- display: flex;
- flex-direction: row;
- align-items: center;
- gap: 6px;
- min-width: 0;
-}
-.lobby-evidence-avatar {
- width: 26px;
- height: 26px;
- border-radius: 50%;
- background: linear-gradient(145deg, #7aa2f7, #565f89);
- color: #1a1b26;
- font-size: 11px;
- font-weight: 800;
- display: flex;
- align-items: center;
- justify-content: center;
- flex-shrink: 0;
- box-shadow: 0 0 0 2px rgba(0, 255, 255, 0.25);
-}
-.lobby-evidence-link-name {
- font-size: clamp(0.62rem, 1.1vw, 0.74rem);
- font-weight: 600;
- color: #c0caf5;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-.lobby-evidence-foot-meta {
- text-align: right;
- flex-shrink: 0;
-}
-.lobby-evidence-rarity {
- display: block;
- font-size: clamp(0.55rem, 0.95vw, 0.65rem);
- color: rgba(170, 180, 210, 0.9);
- margin-bottom: 2px;
-}
-.lobby-evidence-stars {
- font-size: clamp(0.65rem, 1.2vw, 0.78rem);
- letter-spacing: 1px;
- line-height: 1;
-}
-.lobby-evidence-card--common .lobby-evidence-stars { color: #d4d4d8; text-shadow: 0 0 8px rgba(200, 200, 210, 0.4); }
-.lobby-evidence-card--rare .lobby-evidence-stars { color: #60a5fa; text-shadow: 0 0 10px rgba(59, 130, 246, 0.5); }
-.lobby-evidence-card--legendary .lobby-evidence-stars { color: #fcd34d; text-shadow: 0 0 10px rgba(234, 179, 8, 0.55); }
-@media (max-width: 720px) {
- .lobby-evidence-cards-root {
- flex-wrap: wrap;
- overflow-y: auto;
- align-content: flex-start;
- }
- .lobby-evidence-card {
- flex: 1 1 100%;
- max-width: none;
- min-width: 0;
- }
-}
-
-/* —— กระดานอันดับ LobbyB (เหรียญ leaderboard-1/2/3 จาก Main-Lobby) —— */
-.lobby-rank-overlay {
- position: fixed;
- inset: 0;
- z-index: 10048;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
- box-sizing: border-box;
-}
-.lobby-rank-overlay.is-hidden {
- display: none !important;
-}
-.lobby-rank-backdrop {
- position: absolute;
- inset: 0;
- background: rgba(2, 4, 14, 0.82);
- backdrop-filter: blur(8px);
- -webkit-backdrop-filter: blur(8px);
- cursor: pointer;
-}
-.lobby-rank-dialog {
- position: relative;
- z-index: 1;
- width: min(96vw, 520px);
- max-height: min(90vh, 720px);
- pointer-events: none;
-}
-.lobby-rank-dialog * {
- pointer-events: auto;
-}
-.lobby-rank-panel {
- background: linear-gradient(165deg, rgba(28, 36, 58, 0.96), rgba(12, 16, 32, 0.98));
- border-radius: 16px;
- border: 2px solid rgba(0, 255, 255, 0.45);
- box-shadow:
- 0 0 0 1px rgba(255, 0, 200, 0.25),
- 0 0 32px rgba(0, 255, 255, 0.12),
- 0 0 48px rgba(255, 0, 180, 0.08),
- inset 0 1px 0 rgba(255, 255, 255, 0.06);
- padding: clamp(10px, 2.5vw, 16px);
- display: flex;
- flex-direction: column;
- min-height: 0;
- font-family: 'Kanit', 'Sarabun', system-ui, sans-serif;
-}
-.lobby-rank-head {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: center;
- position: relative;
- padding: 6px 44px 12px 12px;
- border-bottom: 1px solid rgba(0, 255, 255, 0.28);
- margin-bottom: 8px;
-}
-.lobby-rank-case-title {
- margin: 0;
- font-size: clamp(0.95rem, 2.8vw, 1.15rem);
- font-weight: 700;
- color: #e8f4ff;
- text-align: center;
- text-shadow: 0 0 12px rgba(0, 255, 255, 0.35);
- line-height: 1.25;
-}
-.lobby-rank-close {
- position: absolute;
- top: 2px;
- right: 4px;
- width: 44px;
- height: 44px;
- padding: 0;
- border: none;
- border-radius: 10px;
- background: transparent;
- color: rgba(0, 255, 255, 0.95);
- font-size: 1.75rem;
- line-height: 1;
- cursor: pointer;
- text-shadow: 0 0 14px rgba(0, 255, 255, 0.85);
- display: flex;
- align-items: center;
- justify-content: center;
- transition: transform 0.15s ease, filter 0.15s ease;
-}
-.lobby-rank-close:hover {
- transform: scale(1.06);
- filter: brightness(1.12);
-}
-.lobby-rank-podium {
- display: flex;
- flex-direction: row;
- align-items: flex-end;
- justify-content: center;
- gap: clamp(6px, 2vw, 14px);
- padding: 8px 4px 14px;
- flex-shrink: 0;
-}
-.lobby-rank-ped {
- flex: 1 1 0;
- min-width: 0;
- max-width: 150px;
- display: flex;
- flex-direction: column;
- align-items: center;
- text-align: center;
- padding: 10px 6px 12px;
- border-radius: 14px;
- background: rgba(0, 0, 0, 0.28);
- border: 1px solid rgba(0, 255, 255, 0.22);
- box-sizing: border-box;
-}
-.lobby-rank-ped--2 {
- order: 1;
- min-height: 148px;
-}
-.lobby-rank-ped--1 {
- order: 2;
- min-height: 188px;
- border-color: rgba(255, 215, 0, 0.45);
- box-shadow: 0 0 22px rgba(255, 200, 0, 0.12);
-}
-.lobby-rank-ped--3 {
- order: 3;
- min-height: 132px;
-}
-.lobby-rank-crown {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: center;
- gap: 4px;
- margin-bottom: 4px;
- font-size: 1.1rem;
- line-height: 1;
- filter: drop-shadow(0 0 6px rgba(255, 215, 0, 0.6));
-}
-.lobby-rank-crown-n {
- font-size: 0.85rem;
- font-weight: 800;
- color: #ffe066;
-}
-.lobby-rank-medal-wrap {
- height: 36px;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 6px;
-}
-.lobby-rank-medal-img {
- width: auto;
- height: 34px;
- object-fit: contain;
- display: block;
-}
-.lobby-rank-ped-avatar {
- width: 48px;
- height: 48px;
- border-radius: 50%;
- background: linear-gradient(145deg, #7aa2f7, #565f89);
- color: #1a1b26;
- font-size: 1.1rem;
- font-weight: 800;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 6px;
- box-shadow: 0 0 0 2px rgba(0, 255, 255, 0.3);
- flex-shrink: 0;
-}
-.lobby-rank-ped--1 .lobby-rank-ped-avatar {
- width: 56px;
- height: 56px;
- font-size: 1.25rem;
-}
-.lobby-rank-ped-name {
- font-size: clamp(0.68rem, 2vw, 0.8rem);
- font-weight: 600;
- color: #e8ecff;
- line-height: 1.2;
- word-break: break-word;
- max-width: 100%;
-}
-.lobby-rank-ped-score {
- margin-top: 4px;
- font-size: clamp(0.75rem, 2.2vw, 0.9rem);
- font-weight: 700;
- color: #fff;
- text-shadow: 0 0 8px rgba(255, 255, 255, 0.2);
-}
-.lobby-rank-table-wrap {
- flex: 1 1 auto;
- min-height: 0;
- overflow-y: auto;
- overflow-x: hidden;
- margin: 0 -4px;
- padding: 0 4px;
- scrollbar-width: thin;
-}
-.lobby-rank-table {
- width: 100%;
- border-collapse: collapse;
- font-size: clamp(0.65rem, 1.9vw, 0.78rem);
-}
-.lobby-rank-table thead th {
- text-align: left;
- text-transform: uppercase;
- letter-spacing: 0.06em;
- color: rgba(0, 255, 255, 0.85);
- font-weight: 700;
- padding: 8px 6px;
- border-bottom: 1px solid rgba(0, 255, 255, 0.25);
- position: sticky;
- top: 0;
- background: linear-gradient(180deg, rgba(20, 26, 44, 0.98), rgba(20, 26, 44, 0.92));
- z-index: 1;
-}
-.lobby-rank-table thead th:nth-child(1) { width: 3.2rem; }
-.lobby-rank-table thead th:nth-child(3) { text-align: right; width: 4rem; }
-.lobby-rank-table tbody td {
- padding: 7px 6px;
- border-bottom: 1px solid rgba(255, 255, 255, 0.06);
- color: #e2e8f0;
- vertical-align: middle;
-}
-.lobby-rank-table tbody td:nth-child(3) {
- text-align: right;
- font-weight: 600;
- color: #fff;
-}
-.lobby-rank-table .lobby-rank-row-av {
- display: inline-flex;
- align-items: center;
- gap: 8px;
- min-width: 0;
-}
-.lobby-rank-table .lobby-rank-mini-av {
- width: 26px;
- height: 26px;
- border-radius: 50%;
- background: linear-gradient(145deg, #9ece6a, #565f89);
- color: #1a1b26;
- font-size: 0.65rem;
- font-weight: 800;
- display: flex;
- align-items: center;
- justify-content: center;
- flex-shrink: 0;
- box-shadow: 0 0 0 1px rgba(0, 255, 255, 0.2);
-}
-.lobby-rank-table .lobby-rank-row-name {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- max-width: 180px;
-}
-.lobby-rank-self {
- flex-shrink: 0;
- display: flex;
- flex-direction: row;
- align-items: center;
- gap: 10px;
- padding: 12px 10px 6px;
- margin-top: 6px;
- border-top: 1px solid rgba(255, 0, 180, 0.42);
- background: linear-gradient(90deg, rgba(255, 0, 180, 0.07), transparent);
-}
-.lobby-rank-self-rank {
- font-weight: 800;
- color: #c0caf5;
- min-width: 2.5rem;
- font-size: clamp(0.75rem, 2vw, 0.88rem);
-}
-.lobby-rank-self-av {
- width: 40px;
- height: 40px;
- border-radius: 50%;
- background: linear-gradient(145deg, #f472b6, #a855f7);
- color: #fff;
- font-size: 1rem;
- font-weight: 800;
- display: flex;
- align-items: center;
- justify-content: center;
- flex-shrink: 0;
- box-shadow: 0 0 0 2px rgba(255, 100, 200, 0.45);
-}
-.lobby-rank-self-meta {
- flex: 1;
- min-width: 0;
-}
-.lobby-rank-self-name {
- font-size: clamp(0.85rem, 2.4vw, 1rem);
- font-weight: 800;
- color: #fff;
- line-height: 1.2;
-}
-.lobby-rank-self-score {
- font-size: clamp(0.85rem, 2.4vw, 1rem);
- font-weight: 800;
- color: #ff4ecd;
- text-shadow: 0 0 12px rgba(255, 78, 205, 0.45);
- flex-shrink: 0;
-}
-
-.version-tag {
- position: fixed;
- right: 8px;
- bottom: 4px;
- left: auto;
- font-size: 10px;
- color: #a9b1d6;
- opacity: 0.7;
- pointer-events: none;
-}
-
-/* play — quiz carry pregame (สอดคล้อง play.html) */
-.quiz-carry-pregame-card {
- position: relative;
- z-index: 1;
- display: flex;
- flex-direction: column;
- align-items: stretch;
- max-width: min(94vw, 900px);
- width: 100%;
- max-height: min(94vh, 900px);
- overflow: hidden;
- background: rgba(10, 12, 26, 0.55);
- border: none;
- border-radius: 4px;
- box-shadow: none;
- pointer-events: auto;
-}
-.quiz-carry-pregame-footer {
- flex: 0 0 auto;
- padding: 0.85rem 1rem 1rem;
- background: linear-gradient(180deg, rgba(8, 10, 22, 0.2), rgba(8, 10, 22, 0.96));
- border-top: none;
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 0.65rem;
-}
-
-/* Editor — เกมตอบคำถาม */
-.quiz-editor-wrap {
- margin: 1rem 0;
- padding: 1rem;
- background: #24283b;
- border-radius: 8px;
- border: 1px solid #414868;
-}
-.quiz-editor-wrap h3 {
- margin: 0 0 0.5rem;
- font-size: 1rem;
- color: #7aa2f7;
-}
-.quiz-questions-list {
- display: flex;
- flex-direction: column;
- gap: 0.6rem;
- margin: 0.75rem 0;
-}
-.quiz-q-row {
- display: grid;
- grid-template-columns: 1fr auto auto;
- gap: 0.5rem;
- align-items: center;
-}
-@media (max-width: 600px) {
- .quiz-q-row {
- grid-template-columns: 1fr;
- }
-}
-.quiz-q-row input[type="text"] {
- min-width: 0;
- padding: 0.4rem 0.5rem;
- border-radius: 6px;
- border: 1px solid #565f89;
- background: #1a1b26;
- color: #c0caf5;
-}
-.quiz-q-row select {
- padding: 0.35rem;
- border-radius: 6px;
- border: 1px solid #565f89;
- background: #1a1b26;
- color: #c0caf5;
-}
-.btn-quiz-add,
-.quiz-q-remove {
- padding: 0.35rem 0.65rem;
- border-radius: 6px;
- cursor: pointer;
- border: 1px solid #565f89;
- background: #414868;
- color: #c0caf5;
- font: inherit;
-}
-.quiz-q-remove {
- font-size: 0.8rem;
-}
-
-/* Stack Tower play — เฟรมกล้องต้อง "คงที่ทุก resolution"
- cover สเกลตามด้านที่ใหญ่กว่า → จอกว้าง/เตี้ย ต่างกัน = เฟรม/ซูมเปลี่ยน (กล้องเพี้ยนเวลาเปลี่ยน resolution + บล็อกห้อย/จุดวางหลุดเฟรม)
- contain = เห็นทั้งฉาก 16:9 (บล็อกห้อย+จุดวาง+หอ) เหมือนกันเป๊ะทุกจอ; แถบ letterbox กลืนสีฉาก (#0a0e22) ไม่ดูจอเสีย */
-html.play-stack-tower-pixel-canvas #play-canvas-stage.play-canvas-stage {
- background: #0a0e22 !important;
-}
-html.play-stack-tower-pixel-canvas #play-canvas-stage #game-canvas {
- object-fit: contain !important;
- object-position: center center !important;
- background: #0a0e22 !important;
-}
+* { box-sizing: border-box; }
+body { font-family: sans-serif; margin: 0; background: #1a1b26; color: #c0caf5; }
+.container { max-width: 720px; margin: 1rem auto; padding: 1rem; }
+
+/* โครง Editor — แยกแถบเครื่องมือ / พื้นที่วาด */
+.editor-page {
+ display: block;
+}
+
+/* Editor ฝังใน Admin (?embed=1) — เต็มความสูง iframe, พื้นที่แคนวาสใหญ่ + เลื่อนแยก */
+html.editor-embed-admin {
+ height: 100%;
+}
+html.editor-embed-admin body {
+ height: 100%;
+ margin: 0;
+ overflow: hidden;
+}
+body.editor-embed-admin .version-tag {
+ display: none !important;
+}
+body.editor-embed-admin .container.editor-page {
+ max-width: none !important;
+ width: 100%;
+ height: 100%;
+ margin: 0 !important;
+ padding: 0.35rem 0.5rem 0.45rem;
+ display: flex;
+ flex-direction: column;
+ min-height: 0;
+ box-sizing: border-box;
+}
+body.editor-embed-admin .container.editor-page > h1 {
+ display: none;
+}
+body.editor-embed-admin .editor-toolbar-wrap {
+ /* อย่าให้แถบเครื่องมือถูก flex บีบแล้วล้นไปทับแคนวาส (body overflow:hidden) */
+ flex: 0 0 auto;
+ min-height: 0;
+ max-height: min(56vh, 520px);
+ overflow-x: hidden;
+ overflow-y: auto;
+ overscroll-behavior: contain;
+ -webkit-overflow-scrolling: touch;
+ padding: 0.15rem 0.35rem 0.5rem 0;
+ margin: 0 0 0.35rem;
+ border-bottom: 1px solid rgba(65, 72, 104, 0.9);
+ position: relative;
+ z-index: 1;
+ background: linear-gradient(180deg, #1a1b26 0%, #16171f 100%);
+}
+body.editor-embed-admin .editor-workspace {
+ flex: 1 1 auto;
+ min-height: 0;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ position: relative;
+ z-index: 0;
+}
+body.editor-embed-admin .canvas-wrap {
+ flex: 1 1 auto;
+ min-height: 140px;
+ overflow: auto;
+ margin: 0 !important;
+ border-radius: 10px;
+ border: 1px solid #414868;
+ background: #0f1018;
+ -webkit-overflow-scrolling: touch;
+ touch-action: pan-x pan-y;
+}
+body.editor-embed-admin #editor-status {
+ flex: 0 0 auto;
+ margin: 0.3rem 0 0;
+ font-size: 0.8rem;
+ line-height: 1.35;
+}
+body.editor-embed-admin .editor-legend-short {
+ margin: 0;
+ font-size: 0.76rem;
+ line-height: 1.45;
+ color: #a8b0d0;
+}
+body.editor-embed-admin .editor-toolbar-grid {
+ gap: 0.45rem;
+}
+/* การ์ด «ประเภทเกม» ข้อความยาว — ให้กว้างเต็มแถวบนจอแคบ ลดการอัดคอลัมน์ */
+@media (max-width: 720px) {
+ body.editor-embed-admin .editor-toolbar-grid .editor-card:first-child {
+ grid-column: 1 / -1;
+ }
+}
+body.editor-embed-admin .editor-card {
+ padding: 0.45rem 0.55rem;
+ margin-bottom: 0;
+}
+body.editor-embed-admin .editor-card__title {
+ font-size: 0.68rem;
+ margin-bottom: 0.3rem;
+}
+body.editor-embed-admin .editor-card__hint {
+ font-size: 0.72rem;
+ margin-top: 0.3rem;
+ overflow-wrap: break-word;
+ word-break: break-word;
+}
+body.editor-embed-admin .game-type-hint .editor-hint-lead {
+ font-size: 0.78rem;
+ margin-bottom: 0.35rem;
+}
+body.editor-embed-admin .game-type-hint .editor-hint-bullets {
+ padding-left: 1.05rem;
+}
+body.editor-embed-admin .game-type-hint .editor-hint-bullets li {
+ margin: 0.26rem 0;
+ font-size: 0.72rem;
+ line-height: 1.45;
+}
+body.editor-embed-admin .frogger-lanes {
+ margin: 0.35rem 0;
+ position: relative;
+ z-index: auto;
+}
+body.editor-embed-admin .editor-card--bg {
+ margin-top: 0.25rem;
+}
+body.editor-embed-admin .editor-card--help {
+ margin-top: 0.2rem;
+}
+h1 { color: #7aa2f7; }
+a { color: #9ece6a; }
+label { display: inline-block; margin: 0.25rem 0.5rem 0.25rem 0; }
+input, button { padding: 0.4rem 0.6rem; margin: 0 0.25rem 0 0; border-radius: 6px; border: 1px solid #414868; }
+input { background: #24283b; color: #c0caf5; }
+button { background: #7aa2f7; color: #1a1b26; cursor: pointer; border: none; }
+.legend { font-size: 0.9rem; color: #a9b1d6; margin: 0.5rem 0; }
+.frogger-lanes { margin: 1rem 0; padding: 0.75rem; background: #24283b; border-radius: 8px; position: relative; z-index: 2; min-height: 80px; }
+.frogger-lanes h3 { margin: 0 0 0.5rem 0; color: #7aa2f7; font-size: 1rem; }
+.frogger-lanes table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
+.frogger-lanes th, .frogger-lanes td { padding: 0.25rem 0.5rem; text-align: left; border: 1px solid #414868; }
+.frogger-lanes select, .frogger-lanes input[type="number"] { padding: 0.35rem 0.5rem; min-width: 4rem; background: #1a1b26; color: #c0caf5; border: 1px solid #414868; border-radius: 4px; cursor: pointer; font-size: 0.9rem; }
+.frogger-lanes select { min-width: 6rem; }
+.frogger-lanes .lane-speed { width: 4rem; }
+.frogger-lanes .lane-spacing { width: 4rem; }
+.frogger-lanes td { vertical-align: middle; }
+.frogger-lanes select:disabled, .frogger-lanes input:disabled { opacity: 0.6; cursor: not-allowed; }
+.game-type-hint {
+ font-size: 0.85rem;
+ color: #a9b1d6;
+ margin: 0;
+ line-height: 1.5;
+ display: block;
+}
+.game-type-hint .editor-hint-lead {
+ margin: 0 0 0.45rem;
+ font-size: 0.9rem;
+ font-weight: 500;
+ color: #c0caf5;
+ line-height: 1.4;
+}
+.game-type-hint .editor-hint-lead:last-child {
+ margin-bottom: 0;
+}
+.editor-hint-bullets {
+ margin: 0;
+ padding-left: 1.2rem;
+ list-style: disc;
+}
+.editor-hint-bullets li {
+ margin: 0.35rem 0;
+}
+.editor-hint-bullets li:first-child {
+ margin-top: 0;
+}
+.editor-hint-bullets li:last-child {
+ margin-bottom: 0;
+}
+.game-type-hint .editor-hint-bullets code {
+ font-size: 0.88em;
+}
+.game-type-hint kbd {
+ display: inline-block;
+ font-size: 0.82em;
+ padding: 0.1em 0.38em;
+ margin: 0 0.06em;
+ border-radius: 4px;
+ background: #1a1b26;
+ border: 1px solid #414868;
+ font-family: ui-monospace, monospace;
+ color: #c0caf5;
+}
+
+/* Editor — การ์ดจัดกลุ่มเครื่องมือ (อ่านง่าย ไม่บีบเป็นแถบเดียวยาว) */
+.editor-toolbar-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
+ gap: 0.65rem;
+ margin: 0.75rem 0 0.5rem;
+ align-items: start;
+}
+.editor-card {
+ margin: 0;
+ padding: 0.65rem 0.75rem;
+ background: #24283b;
+ border: 1px solid rgba(65, 72, 104, 0.95);
+ border-radius: 10px;
+}
+.editor-card--wide {
+ grid-column: 1 / -1;
+}
+.editor-card__title {
+ margin: 0 0 0.45rem 0;
+ padding: 0;
+ font-size: 0.72rem;
+ font-weight: 700;
+ letter-spacing: 0.04em;
+ text-transform: uppercase;
+ color: #7aa2f7;
+}
+.editor-card__row {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: flex-end;
+ gap: 0.45rem 0.75rem;
+}
+.editor-card__row--wrap {
+ align-items: center;
+}
+.editor-card__row--actions {
+ margin-top: 0.55rem;
+ padding-top: 0.5rem;
+ border-top: 1px solid rgba(65, 72, 104, 0.75);
+ gap: 0.5rem;
+}
+.editor-card__hint {
+ margin: 0.4rem 0 0;
+ padding: 0.45rem 0.55rem;
+ background: rgba(15, 16, 24, 0.55);
+ border-radius: 6px;
+ border-left: 3px solid #7aa2f7;
+}
+.editor-card label { margin: 0; }
+/* กลุ่มกล่องตรวจ: ชนกำแพง vs โซนห้ามซ้อน — แยกมองชัดจากแถว label เปล่า ๆ */
+.editor-footprint-row {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 0.45rem 0.85rem;
+ width: 100%;
+ padding: 0.42rem 0.55rem 0.48rem;
+ border-radius: 8px;
+ border: 1px solid rgba(122, 162, 247, 0.38);
+ background: rgba(20, 22, 34, 0.72);
+ box-sizing: border-box;
+}
+.editor-footprint-row--wall {
+ border-color: rgba(122, 162, 247, 0.45);
+ background: rgba(26, 32, 52, 0.65);
+}
+.editor-footprint-row--no-overlap {
+ border-color: rgba(158, 206, 106, 0.5);
+ background: rgba(22, 34, 26, 0.55);
+}
+.editor-footprint-row__head {
+ flex: 0 0 100%;
+ margin: 0 0 0.08rem 0;
+ padding: 0;
+ font-size: 0.68rem;
+ font-weight: 700;
+ letter-spacing: 0.06em;
+ text-transform: uppercase;
+ color: #7aa2f7;
+}
+.editor-footprint-row--no-overlap .editor-footprint-row__head {
+ color: #9ece6a;
+}
+.editor-footprint-row .editor-footprint-row__field input[type="number"] {
+ width: 3.1rem;
+ margin-left: 0.2rem;
+}
+.editor-field-grow {
+ flex: 1 1 180px;
+ min-width: min(100%, 200px);
+}
+.editor-field-grow select,
+.editor-field-grow input[type="text"] {
+ width: 100%;
+ max-width: 100%;
+ min-width: 0;
+}
+.editor-field-drawmode {
+ flex: 1 1 280px;
+ min-width: min(100%, 240px);
+}
+.editor-field-drawmode select {
+ width: 100%;
+ max-width: 100%;
+ min-width: 0;
+}
+.editor-cell-color {
+ display: inline-flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 0.35rem 0.75rem;
+}
+.editor-grid-image-tools {
+ display: none;
+ flex-direction: column;
+ align-items: stretch;
+ gap: 0.5rem;
+ max-width: 100%;
+ width: min(100%, 520px);
+}
+.editor-grid-image-size-row {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem 1rem;
+ align-items: center;
+}
+.editor-grid-image-size-row input[type="number"] {
+ width: 3.2rem;
+ margin-left: 0.25rem;
+}
+.editor-grid-image-carry-bind-row {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.35rem 0.75rem;
+ align-items: center;
+ font-size: 0.72rem;
+ color: #a9b1d6;
+}
+.editor-grid-image-carry-bind-row select {
+ margin-left: 0.35rem;
+ max-width: 12rem;
+}
+.editor-hint-inline {
+ font-size: 0.68rem;
+ color: #787c99;
+ line-height: 1.35;
+ flex: 1 1 140px;
+}
+.editor-grid-image-gallery-wrap {
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+}
+.editor-grid-image-gallery-label {
+ font-size: 0.72rem;
+ color: #a9b1d6;
+ font-weight: 600;
+}
+.editor-grid-image-gallery-note {
+ margin: 0.1rem 0 0.35rem;
+ font-size: 0.65rem;
+ line-height: 1.35;
+ color: #787c99;
+ max-width: 36rem;
+}
+.grid-cell-image-gallery {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(68px, 1fr));
+ gap: 0.4rem;
+ max-height: 200px;
+ overflow-y: auto;
+ padding: 0.35rem;
+ border-radius: 8px;
+ border: 1px solid rgba(65, 72, 104, 0.85);
+ background: rgba(15, 16, 24, 0.6);
+}
+.grid-cell-image-gallery-empty {
+ font-size: 0.72rem;
+ color: #787c99;
+ padding: 0.35rem;
+}
+.grid-cell-image-gallery-item {
+ position: relative;
+ padding: 0;
+ margin: 0;
+ border: 2px solid transparent;
+ border-radius: 8px;
+ overflow: hidden;
+ cursor: pointer;
+ background: #24283b;
+ line-height: 0;
+}
+.grid-cell-image-gallery-item.is-selected {
+ border-color: #9ece6a;
+ box-shadow: 0 0 0 1px rgba(158, 206, 106, 0.35);
+}
+.grid-cell-image-gallery-item img {
+ display: block;
+ width: 100%;
+ height: 56px;
+ object-fit: cover;
+}
+.grid-cell-image-gallery-row {
+ display: flex;
+ flex-direction: column;
+ gap: 0.35rem;
+ align-items: stretch;
+}
+.grid-cell-image-gallery-same-hint {
+ font-size: 0.62rem;
+ line-height: 1.35;
+ color: #f7768e;
+ padding: 0.2rem 0.35rem;
+ border-radius: 4px;
+ background: rgba(247, 118, 142, 0.12);
+ border: 1px solid rgba(247, 118, 142, 0.35);
+}
+.grid-cell-image-gallery-held-side {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 0.2rem;
+ padding: 0.15rem 0.1rem 0.25rem;
+ border-radius: 6px;
+ background: rgba(0, 0, 0, 0.22);
+}
+.grid-cell-image-gallery-held-label {
+ font-size: 0.58rem;
+ font-weight: 700;
+ color: #7dcfff;
+ letter-spacing: 0.04em;
+}
+.grid-cell-image-gallery-held-thumb {
+ display: block;
+ width: 100%;
+ max-height: 44px;
+ object-fit: cover;
+ border-radius: 4px;
+ background: #1a1b26;
+}
+.grid-cell-image-gallery-held-btn {
+ font-size: 0.58rem;
+ padding: 0.15rem 0.35rem;
+ border-radius: 4px;
+ border: 1px solid rgba(125, 207, 255, 0.45);
+ background: rgba(26, 27, 38, 0.95);
+ color: #c0caf5;
+ cursor: pointer;
+}
+.grid-cell-image-gallery-held-btn:hover {
+ border-color: rgba(158, 206, 106, 0.65);
+ color: #9ece6a;
+}
+.grid-cell-image-gallery-clear-held {
+ font-size: 0.7rem;
+ line-height: 1;
+ padding: 0.05rem 0.25rem;
+ border: none;
+ border-radius: 4px;
+ background: rgba(247, 118, 142, 0.25);
+ color: #f7768e;
+ cursor: pointer;
+}
+.grid-cell-image-gallery-clear-held:hover {
+ background: rgba(247, 118, 142, 0.45);
+}
+.grid-cell-image-gallery-cap {
+ display: block;
+ font-size: 0.65rem;
+ text-align: center;
+ padding: 0.15rem 0;
+ color: #c0caf5;
+ background: rgba(0, 0, 0, 0.35);
+}
+.editor-grid-image-upload-row {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 0.5rem;
+}
+body.editor-embed-admin .grid-cell-image-gallery {
+ max-height: 160px;
+}
+body.editor-embed-admin .grid-cell-image-gallery-item img {
+ height: 48px;
+}
+.editor-btn-primary {
+ font-weight: 600;
+}
+.editor-card--bg {
+ margin: 0.5rem 0 0.35rem;
+}
+.editor-card--help {
+ margin: 0.35rem 0 0.15rem;
+}
+.editor-help-list {
+ margin: 0;
+ padding-left: 1.15rem;
+ list-style: disc;
+}
+.editor-help-list li {
+ margin-bottom: 0.28rem;
+}
+@media (min-width: 900px) {
+ .editor-help-list {
+ columns: 2;
+ column-gap: 1.5rem;
+ }
+ .editor-help-list li {
+ break-inside: avoid;
+ }
+}
+.canvas-wrap { margin: 1rem 0; }
+.container { padding-left: 1rem; padding-right: 1rem; }
+#editor-canvas {
+ background: #1a1b26;
+ display: block;
+ touch-action: none;
+ image-rendering: pixelated;
+ image-rendering: crisp-edges;
+}
+.editor-map-zoom-bar {
+ display: flex;
+ align-items: center;
+ gap: 5px;
+ padding: 6px 10px;
+ border-radius: 999px;
+ background: rgba(8, 12, 28, 0.88);
+ border: 1px solid #2a3357;
+ box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
+}
+.editor-map-zoom-btn {
+ border: 1px solid #2a3357;
+ background: #0d1430;
+ color: #eef2ff;
+ border-radius: 8px;
+ min-width: 34px;
+ height: 32px;
+ padding: 0 8px;
+ cursor: pointer;
+ font: inherit;
+ font-weight: 700;
+ line-height: 1;
+}
+.editor-map-zoom-btn:hover { filter: brightness(1.2); }
+.editor-map-zoom-label {
+ min-width: 46px;
+ text-align: center;
+ font-size: 12px;
+ font-weight: 700;
+ color: #c7d2fe;
+ user-select: none;
+}
+.game-wrap { display: flex; flex-direction: column; height: 100vh; height: 100dvh; min-height: 0; }
+.game-header { flex-shrink: 0; background: #24283b; padding: 0.5rem 1rem; display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; }
+.game-header span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
+.game-header button { flex-shrink: 0; }
+#game-canvas {
+ flex: 1 1 auto;
+ display: block;
+ width: 100%;
+ /* [2026-07-31] ล็อกอัตราส่วนภาพ — เดิมมีแต่ width:100% ไม่มี height เลย
+ ผลคือกล่องแสดงผล "กว้างตามจอ แต่สูงตามบัฟเฟอร์" พอ canvas.width ยังเป็นค่าเก่า
+ (ช่วงหมุนจอ / แถบ URL ของมือถือยุบ) เบราว์เซอร์จะยืดบิตแมปตามแนวนอนอย่างเดียว
+ = อาการ "ภาพในเกมยืดแปลก ๆ" ที่ผู้เล่นมือถือเจอ
+ object-fit: contain ทำให้ยืดแบบไม่เท่ากันสองแกน "เป็นไปไม่ได้" แม้ในเฟรมที่ค่ายังค้าง
+ (ระหว่างนั้นเห็นเป็นขอบว่างแทน ซึ่งดีกว่าภาพเพี้ยน)
+ บน PC บัฟเฟอร์เท่ากล่องเสมอ → contain ไม่ทำอะไร = ภาพเดิมทุกพิกเซล
+ ต้นแบบ: MG3 ใช้วิธีนี้อยู่แล้ว (ดู html.play-stack-tower-pixel-canvas ด้านล่าง) */
+ height: 100%;
+ object-fit: contain;
+ object-position: center center;
+ min-height: 0;
+ min-width: 0;
+ touch-action: none;
+ image-rendering: pixelated;
+ image-rendering: crisp-edges;
+}
+.game-wrap .chat-panel { flex-shrink: 0; }
+.chat-panel { height: 160px; border-top: 1px solid #414868; display: flex; flex-direction: column; }
+#chat-messages { flex: 1; overflow-y: auto; padding: 0.5rem; font-size: 0.9rem; }
+#chat-form { display: flex; padding: 0.5rem; gap: 0.5rem; }
+#chat-input { flex: 1; }
+
+.lobby-section { margin: 1.25rem 0; padding: 1rem; background: #24283b; border-radius: 8px; }
+.lobby-section h2 { margin: 0 0 0.75rem 0; font-size: 1rem; color: #7aa2f7; }
+#room-list { list-style: none; margin: 0; padding: 0; }
+#room-list .room-item { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; padding: 0.5rem 0; border-bottom: 1px solid #414868; }
+#room-list .room-item:last-child { border-bottom: none; }
+#room-list .room-name { font-weight: 600; color: #c0caf5; min-width: 0; }
+#room-list .room-meta { font-size: 0.85rem; color: #a9b1d6; }
+#room-list .room-meta-inline { font-size: 0.8rem; color: #565f89; font-weight: normal; }
+#room-list-status { margin: 0; color: #a9b1d6; font-size: 0.9rem; }
+
+.room-lobby-peers { margin: 1rem 0; padding: 0.75rem; background: #24283b; border-radius: 8px; }
+.room-lobby-peer { padding: 0.35rem 0; color: #c0caf5; }
+.room-lobby-peer:not(:last-child) { border-bottom: 1px solid #414868; }
+#lobby-map-wrap { position: fixed; top: 0; left: 0; right: 0; bottom: 0; width: 100%; height: 100%; min-width: 100vw; min-height: 100vh; min-height: 100dvh; z-index: 0; }
+#lobby-map-canvas {
+ display: block;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ width: 100%;
+ height: 100%;
+ min-width: 100%;
+ min-height: 100%;
+ margin: 0;
+ padding: 0;
+ background: #303770;
+ box-sizing: border-box;
+}
+#lobby-map-canvas:focus {
+ outline: none;
+}
+#lobby-map-canvas:focus-visible {
+ outline: 2px solid rgba(122, 162, 247, 0.45);
+ outline-offset: -2px;
+}
+/* LobbyB (mn8nx46h) — ไม่แสดงปุ่มพร้อม */
+body.room-lobby--lobby-b .room-lobby-ready-fixed {
+ display: none !important;
+}
+.lobby-interact-hint {
+ position: absolute;
+ bottom: max(10px, env(safe-area-inset-bottom));
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 2;
+ margin: 0;
+ padding: 0.2rem 0.55rem;
+ font-size: clamp(0.72rem, 1.8vw, 0.85rem);
+ color: rgba(203, 213, 245, 0.9);
+ text-shadow: 0 1px 10px rgba(0, 0, 0, 0.55);
+ pointer-events: none;
+ font-family: system-ui, 'Kanit', sans-serif;
+ white-space: nowrap;
+}
+.lobby-interact-hint kbd {
+ display: inline-block;
+ padding: 0.06em 0.32em;
+ border-radius: 4px;
+ background: rgba(26, 27, 38, 0.88);
+ border: 1px solid rgba(122, 162, 247, 0.45);
+ font-size: 0.88em;
+ font-family: inherit;
+}
+.lobby-zoom-pct {
+ position: absolute;
+ top: 12px;
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 2;
+ padding: 6px 12px;
+ border-radius: 8px;
+ background: rgba(26, 27, 38, 0.85);
+ color: #c0caf5;
+ font-size: 1rem;
+ font-weight: 600;
+ pointer-events: none;
+ opacity: 0;
+ transition: opacity 0.2s ease;
+}
+.lobby-zoom-pct.lobby-zoom-pct-visible { opacity: 1; }
+/* ซ่อนแผง overlay รายชื่อ / host / แชท — โถงโฟกัสแผนที่ + ปุ่ม READY/ไมค์ ด้านนอก */
+.room-lobby-overlay { display: none !important; }
+.room-lobby-top-left-cluster {
+ position: fixed;
+ top: max(12px, env(safe-area-inset-top));
+ left: max(12px, env(safe-area-inset-left));
+ z-index: 55;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 0.65rem;
+ pointer-events: none;
+}
+.room-lobby-top-left-cluster .room-lobby-exit-fixed {
+ pointer-events: auto;
+}
+
+/* มุมขวาบน — โปรไฟล์ตัวละคร */
+.room-lobby-top-right-cluster {
+ position: fixed;
+ top: max(12px, env(safe-area-inset-top));
+ right: max(12px, env(safe-area-inset-right));
+ z-index: 56;
+ display: flex;
+ flex-direction: row;
+ align-items: flex-start;
+ gap: 0.65rem;
+ pointer-events: none;
+}
+.room-lobby-top-right-cluster > * {
+ pointer-events: auto;
+}
+.room-lobby-profile-wrap {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 0.2rem;
+}
+.room-lobby-profile-frame {
+ width: clamp(56px, 12vw, 72px);
+ height: clamp(56px, 12vw, 72px);
+ border-radius: 14px;
+ border: 2px solid rgba(0, 212, 255, 0.65);
+ overflow: hidden;
+ background: rgba(18, 22, 42, 0.92);
+ box-shadow:
+ 0 0 0 1px rgba(34, 211, 238, 0.2),
+ 0 0 22px rgba(34, 211, 238, 0.28);
+}
+.room-lobby-profile-frame img {
+ display: block;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ object-position: center bottom;
+ image-rendering: pixelated;
+ image-rendering: crisp-edges;
+}
+.room-lobby-actions { margin-top: 1rem; display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; }
+.room-lobby-actions .room-lobby-btn-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0; opacity: 0; pointer-events: none; }
+.room-lobby-actions label { margin: 0; }
+.room-lobby-actions #btn-start { background: #9ece6a; color: #1a1b26; }
+#host-only { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; }
+#host-only select { padding: 0.4rem 0.6rem; border-radius: 6px; border: 1px solid #414868; background: #24283b; color: #c0caf5; }
+.host-start-area-hint {
+ flex-basis: 100%;
+ margin: 0;
+ font-size: 0.88rem;
+ color: #e0af68;
+ line-height: 1.35;
+ max-width: 100%;
+}
+#host-only #btn-start:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ filter: grayscale(0.25);
+}
+.room-lobby-chat { margin-top: 1rem; }
+.room-lobby-chat.chat-panel {
+ border-radius: 12px;
+ overflow: hidden;
+ box-shadow: none;
+}
+.room-lobby-chat-peers.chat-panel {
+ position: fixed;
+ right: 1.25rem;
+ bottom: 5.5rem;
+ width: 576px;
+ height: 525px;
+ max-width: calc(100vw - 2.5rem);
+ z-index: 52;
+ margin-top: 0;
+ display: flex;
+ flex-flow: column;
+ padding: 2rem;
+ box-sizing: border-box;
+ border-top: 0px solid #414868;
+ background: url(/Game/img/chat-msg-bg-alpha.png) center/100% 100% no-repeat;
+ background-color: transparent;
+}
+.room-lobby-chat-peers.chat-panel .chat-header-title.chat-header-title-img img { width: 90px; height: 77px; }
+.room-lobby-chat-peers.chat-panel .chat-close-btn { width: 48px; height: 48px; }
+.room-lobby-chat-peers.chat-panel .chat-close-btn img { width: 50px; height: 50px; }
+.room-lobby-chat-peers.chat-panel #chat-messages { padding: 0.75rem; font-size: 1.05rem; gap: 0.5rem; }
+.room-lobby-chat-peers.chat-panel .chat-form-bar { padding: 0.6rem 0; gap: 0.5rem; }
+.room-lobby-chat-peers.chat-panel #chat-input { padding: 0.6rem 0.85rem; font-size: 1.05rem; }
+.room-lobby-chat-peers.chat-panel .chat-send-btn { width: 52px; height: 52px; }
+.room-lobby-chat-peers.chat-panel .chat-send-btn img { width: 58px; height: 58px; }
+.room-lobby-chat-peers.chat-panel .chat-msg { padding: 0.6rem 1rem; font-size: 1.05rem; }
+.room-lobby-chat-peers.chat-panel .chat-header-bar {
+ margin: 0 -2rem 0 -2rem;
+ padding-left: 2rem;
+ padding-right: 2rem;
+ justify-content: space-between;
+ align-items: center;
+ min-height: 72px;
+ height: 72px;
+}
+.room-lobby-chat-peers.chat-panel #chat-messages {
+ flex: 1;
+ min-height: 0;
+ height: auto;
+}
+.room-lobby-chat .chat-header-bar {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0;
+ min-height: 48px;
+ height: 48px;
+ background: url(/Game/img/chat-line.png) bottom repeat-x;
+ background-size: 100% 4px;
+ background-color: transparent;
+}
+.room-lobby-chat-peers .chat-header-title.chat-header-title-img {
+ display: inline-flex;
+ align-items: center;
+ line-height: 0;
+}
+.room-lobby-chat-peers .chat-header-title.chat-header-title-img img {
+ width: 60px;
+ height: 51px;
+ object-fit: contain;
+ display: block;
+}
+.room-lobby-chat-ai .chat-header-title.chat-header-title-img {
+ display: flex;
+ align-items: flex-end;
+ gap: 0.5rem;
+ line-height: 0;
+}
+.room-lobby-chat-ai .chat-header-title.chat-header-title-img .ai-chat-title-label {
+ height: 52px;
+ width: auto;
+ object-fit: contain;
+ display: block;
+ flex-shrink: 0;
+ margin-bottom: -2px;
+}
+/* รูปหัวแชท AI — ยกขึ้นเหนือเส้น */
+.room-lobby-chat-ai .chat-header-title.chat-header-title-img img {
+ width: 86px;
+ height: 92px;
+ object-fit: cover;
+ display: block;
+ flex-shrink: 0;
+ margin-top: -27px;
+ margin-left: -6px;
+ position: relative;
+ z-index: 1;
+}
+.room-lobby-chat .chat-header-title {
+ font-size: 1rem;
+ font-weight: 600;
+ color: #a0aec0;
+}
+.room-lobby-chat .chat-close-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ padding: 0;
+ border: none;
+ border-radius: 8px;
+ background: transparent;
+ cursor: pointer;
+ margin-left: auto;
+}
+.room-lobby-chat-peers .chat-header-bar .chat-close-btn { margin-left: 0; }
+.room-lobby-chat .chat-close-btn img { width: 34px; height: 34px; object-fit: contain; }
+.room-lobby-chat .chat-close-btn:hover { opacity: 0.9; }
+.room-lobby-chat.chat-panel-collapsed #chat-messages,
+.room-lobby-chat.chat-panel-collapsed .chat-form-bar { display: none !important; }
+.room-lobby-chat-peers.chat-panel-collapsed .chat-header-title { display: none !important; }
+.room-lobby-chat-peers.chat-panel-collapsed .chat-header-bar {
+ justify-content: center;
+ padding: 0;
+ background: none !important;
+ border: none;
+}
+.room-lobby-chat-peers.chat-panel-collapsed.chat-panel {
+ width: 80px;
+ height: 80px;
+ min-height: 0;
+ padding: 0;
+ right: 1.25rem;
+ bottom: 6.25rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: none !important;
+ background-color: transparent !important;
+ border: none;
+ box-shadow: none;
+}
+.room-lobby-chat-peers.chat-panel-collapsed .chat-close-btn {
+ width: 80px;
+ height: 80px;
+ overflow: visible;
+}
+.room-lobby-chat-peers.chat-panel-collapsed .chat-close-btn img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ object-position: center;
+ display: block;
+}
+.room-lobby-chat #chat-messages,
+.room-lobby-chat #ai-chat-messages {
+ height: 100px;
+ overflow-y: auto;
+ padding: 0.5rem;
+ font-size: 0.85rem;
+ border: none;
+ margin: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 0.35rem;
+ background: none;
+ background-color: transparent;
+ box-shadow: none;
+}
+.room-lobby-chat .chat-messages-bg { border-radius: 0; }
+.room-lobby-chat #chat-form.chat-form-bar,
+.room-lobby-chat #ai-chat-form.chat-form-bar {
+ display: flex;
+ gap: 0.4rem;
+ align-items: center;
+ padding: 0.4rem 0;
+ background: none;
+ background-color: transparent;
+ border-top: none;
+ flex-shrink: 0;
+}
+.room-lobby-chat-peers .chat-form-bar {
+ padding-left: 0;
+ padding-right: 0;
+}
+.room-lobby-chat #chat-input,
+.room-lobby-chat #ai-chat-input {
+ flex: 1;
+ min-width: 0;
+ padding: 0.45rem 0.6rem;
+ border-radius: 10px;
+ border: 1px solid rgba(0, 212, 255, 0.25);
+ background: rgba(30, 35, 50, 0.8);
+ color: #c0caf5;
+ font-size: 0.9rem;
+ box-sizing: border-box;
+ margin-left: 9px;
+}
+.room-lobby-chat .chat-send-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 40px;
+ height: 40px;
+ flex-shrink: 0;
+ padding: 0;
+ border: none;
+ border-radius: 10px;
+ background: transparent;
+ cursor: pointer;
+}
+.room-lobby-chat .chat-send-btn img { width: 45px; height: 45px; object-fit: contain; }
+.room-lobby-chat .chat-send-btn:hover { opacity: 0.9; }
+.room-lobby-chat .chat-msg {
+ padding: 0.4rem 0.75rem;
+ border-radius: 12px;
+ max-width: 85%;
+ background-size: 100% 100%;
+ background-repeat: no-repeat;
+ background-position: center;
+}
+.room-lobby-chat .chat-msg-mine {
+ align-self: flex-end;
+ text-align: right;
+ background-image: url(/Game/img/chat-bubble-me.png);
+ background-color: rgba(122, 162, 247, 0.9);
+ color: #1a1b26;
+}
+.room-lobby-chat .chat-msg-other {
+ align-self: flex-start;
+ text-align: left;
+ background-image: url(/Game/img/chat-bubble-friend.png);
+ background-color: rgba(65, 72, 104, 0.9);
+ color: #c0caf5;
+}
+.room-lobby-chat .chat-msg-ai {
+ align-self: flex-start;
+ text-align: left;
+ background-image: url(/Game/img/chat-bubble-friend.png);
+ background-color: rgba(158, 206, 106, 0.9);
+ color: #1a1b26;
+}
+.room-lobby-chat .chat-msg-system {
+ align-self: center;
+ text-align: center;
+ max-width: 95%;
+ background-image: none;
+ background-color: rgba(26, 27, 38, 0.72);
+ color: #9aa5ce;
+ font-size: 0.88rem;
+ font-style: italic;
+ padding: 0.35rem 0.6rem;
+}
+
+/* AI chat — loading แบบ Messenger (จุดกระโดด 3 จุด), อยู่ติดข้อความล่าสุดในลิสต์ */
+.room-lobby-chat .ai-chat-typing {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ padding: 12px 14px;
+ min-height: 24px;
+ flex-shrink: 0;
+ background-image: url(/Game/img/chat-bubble-friend.png);
+ background-color: rgba(158, 206, 106, 0.9);
+ background-size: 100% 100%;
+ background-repeat: no-repeat;
+ background-position: center;
+}
+.room-lobby-chat .ai-typing-dot {
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ background: #1a1b26;
+ animation: ai-typing-bounce 1.4s ease-in-out infinite both;
+}
+.room-lobby-chat .ai-typing-dot:nth-child(1) { animation-delay: 0s; }
+.room-lobby-chat .ai-typing-dot:nth-child(2) { animation-delay: 0.2s; }
+.room-lobby-chat .ai-typing-dot:nth-child(3) { animation-delay: 0.4s; }
+@keyframes ai-typing-bounce {
+ 0%, 60%, 100% { transform: translateY(0); }
+ 30% { transform: translateY(-6px); }
+}
+
+/* AI chat panel — ขนาดและตำแหน่งตาม reference (วงซ้าย) */
+.room-lobby-chat-ai.chat-panel {
+ position: fixed;
+ left: 20px;
+ right: auto;
+ bottom: 5.5rem;
+ width: 576px;
+ height: 525px;
+ max-width: calc(100vw - 2.5rem);
+ z-index: 51;
+ margin-top: 0;
+ display: flex;
+ flex-flow: column;
+ padding: 2rem;
+ box-sizing: border-box;
+ border-top: 0;
+ background: url(/Game/img/chat-msg-bg-alpha.png) center/100% 100% no-repeat;
+ background-color: transparent;
+}
+.room-lobby-chat-ai.chat-panel .chat-header-bar {
+ margin: 0 -2rem 0 -2rem;
+ padding-left: 2rem;
+ padding-right: 2rem;
+ justify-content: space-between;
+ align-items: center;
+ min-height: 80px;
+ height: 80px;
+ overflow: visible;
+}
+.room-lobby-chat-ai.chat-panel .chat-header-title.chat-header-title-img img { width: 130px; height: 138px; margin-top: -38px; margin-left: -8px; }
+.room-lobby-chat-ai.chat-panel .chat-header-title.chat-header-title-img .ai-chat-title-label { height: 78px; }
+.room-lobby-chat-ai.chat-panel .chat-close-btn { width: 48px; height: 48px; }
+.room-lobby-chat-ai.chat-panel .chat-close-btn img { width: 50px; height: 50px; }
+.room-lobby-chat-ai.chat-panel #ai-chat-messages { padding: 0.75rem; font-size: 1.05rem; gap: 0.5rem; }
+.room-lobby-chat-ai.chat-panel .chat-form-bar { padding: 0.6rem 0; gap: 0.5rem; }
+.room-lobby-chat-ai.chat-panel #ai-chat-input { padding: 0.6rem 0.85rem; font-size: 1.05rem; }
+.room-lobby-chat-ai.chat-panel .chat-send-btn { width: 52px; height: 52px; }
+.room-lobby-chat-ai.chat-panel .chat-send-btn img { width: 58px; height: 58px; }
+.room-lobby-chat-ai.chat-panel .chat-msg { padding: 0.6rem 1rem; font-size: 1.05rem; }
+.room-lobby-chat-ai.chat-panel .ai-chat-typing { padding: 14px 18px; min-height: 28px; }
+.room-lobby-chat-ai.chat-panel .ai-typing-dot { width: 8px; height: 8px; }
+.room-lobby-chat-ai.chat-panel {
+ overflow: visible;
+}
+.room-lobby-chat-ai.chat-panel #ai-chat-messages {
+ flex: 1;
+ min-height: 0;
+ height: auto;
+}
+.room-lobby-chat-ai .chat-form-bar {
+ padding-left: 0;
+ padding-right: 0;
+}
+.room-lobby-chat-ai .ai-chat-admin-link {
+ margin: 0.35rem 0 0 0;
+ font-size: 0.75rem;
+ flex-shrink: 0;
+}
+/* AI chat collapsed */
+.room-lobby-chat-ai.chat-panel-collapsed #ai-chat-messages,
+.room-lobby-chat-ai.chat-panel-collapsed .chat-form-bar,
+.room-lobby-chat-ai.chat-panel-collapsed .ai-chat-admin-link { display: none !important; }
+.room-lobby-chat-ai.chat-panel-collapsed .chat-header-title { display: none !important; }
+.room-lobby-chat-ai.chat-panel-collapsed .chat-header-bar {
+ justify-content: center;
+ padding: 0;
+ background: none !important;
+ border: none;
+}
+.room-lobby-chat-ai.chat-panel-collapsed.chat-panel {
+ width: 80px;
+ height: 80px;
+ min-height: 0;
+ padding: 0;
+ left: 20px;
+ bottom: 1.25rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: none !important;
+ background-color: transparent !important;
+ border: none;
+ box-shadow: none;
+}
+.room-lobby-chat-ai.chat-panel-collapsed .chat-close-btn {
+ width: 80px;
+ height: 80px;
+ overflow: visible;
+}
+.room-lobby-chat-ai.chat-panel-collapsed .chat-close-btn img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ object-position: center;
+ display: block;
+}
+
+.room-lobby-exit-fixed {
+ position: static;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ align-items: center;
+ justify-content: flex-start;
+ gap: 10px;
+ width: max-content;
+ max-width: calc(100vw - 24px);
+ box-sizing: border-box;
+}
+.room-lobby-exit-fixed .btn-exit-icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex: 0 0 auto;
+ width: 80px;
+ height: 80px;
+ min-width: 80px;
+ padding: 0;
+ border: none;
+ border-radius: 12px;
+ background: transparent;
+ cursor: pointer;
+}
+.room-lobby-exit-fixed .btn-exit-icon:hover {
+ opacity: 0.9;
+}
+.room-lobby-exit-fixed .btn-exit-icon img {
+ width: 100%;
+ height: auto;
+ object-fit: contain;
+ display: block;
+}
+
+.room-lobby-ready-fixed {
+ position: fixed;
+ bottom: 1.25rem;
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 120;
+ pointer-events: none;
+}
+.room-lobby-ready-fixed .ready-label,
+.room-lobby-ready-fixed .ready-check-input {
+ pointer-events: auto;
+}
+.room-lobby-ready-fixed .ready-label {
+ position: relative;
+ display: inline-block;
+ padding: 0;
+ margin: 0;
+ border: none;
+ border-radius: 0;
+ background: transparent;
+ box-shadow: none;
+ cursor: pointer;
+ transition: transform 0.15s ease, filter 0.15s ease;
+ line-height: 0;
+}
+.room-lobby-ready-fixed .ready-label:hover {
+ transform: scale(1.04);
+ filter: brightness(1.08);
+}
+.room-lobby-ready-fixed .ready-label:active {
+ transform: scale(0.98);
+}
+.room-lobby-ready-fixed .ready-check-input {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ opacity: 0;
+ cursor: pointer;
+ z-index: 2;
+}
+.room-lobby-ready-fixed .ready-label-img {
+ display: block;
+ height: clamp(44px, 8vh, 72px);
+ width: auto;
+ max-width: min(240px, 78vw);
+ pointer-events: none;
+ user-select: none;
+ -webkit-user-drag: none;
+}
+.room-lobby-ready-fixed .ready-label--active .ready-label-img {
+ filter: drop-shadow(0 0 10px rgba(158, 206, 106, 0.45));
+}
+
+/* มุมขวาล่าง — ไมค์ทุกห้อง + ปุ่ม LobbyB (แว่น/ถ้วย) */
+.room-lobby-br-fixed {
+ --lobby-br-btn: 80px;
+ position: fixed;
+ bottom: 1.25rem;
+ right: max(1.25rem, env(safe-area-inset-right));
+ z-index: 400;
+ display: flex;
+ flex-direction: row;
+ align-items: flex-end;
+ gap: 10px;
+ pointer-events: none;
+}
+.room-lobby-br-fixed .lobby-b-extra-row,
+.room-lobby-br-fixed .btn-voice-icon {
+ pointer-events: auto;
+}
+.lobby-b-extra-row {
+ display: flex;
+ flex-direction: row;
+ align-items: flex-end;
+ gap: 10px;
+}
+.lobby-b-extra-row.is-hidden {
+ display: none !important;
+}
+/* โหมดเกม (ควิซ) ใน room-lobby — ไม่โชว์แว่น/ถ้วย LobbyB */
+body.room-lobby--quiz-active .lobby-b-extra-row {
+ display: none !important;
+ visibility: hidden !important;
+ pointer-events: none !important;
+}
+/* ปุ่มมุมขวาล่าง — ขนาดเดียวกัน (กัน UA border / box model ต่างกัน) */
+.room-lobby-br-fixed .lobby-b-sq-btn,
+.room-lobby-br-fixed .btn-voice-icon {
+ box-sizing: border-box;
+ width: var(--lobby-br-btn);
+ height: var(--lobby-br-btn);
+ min-width: var(--lobby-br-btn);
+ min-height: var(--lobby-br-btn);
+ max-width: var(--lobby-br-btn);
+ max-height: var(--lobby-br-btn);
+ margin: 0;
+ padding: 0;
+ border: none;
+ border-radius: 12px;
+ appearance: none;
+ -webkit-appearance: none;
+ flex-shrink: 0;
+ cursor: pointer;
+}
+/* สไตล์เดียวกับปุ่มไมค์ — ไม่มีกรอบ cyan / bg-item */
+.lobby-b-sq-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: transparent;
+ box-shadow: none;
+ transition: transform 0.15s ease, filter 0.15s ease;
+}
+.lobby-b-sq-btn:hover {
+ transform: scale(1.04);
+ filter: brightness(1.08);
+}
+.lobby-b-sq-btn:active { transform: scale(0.98); }
+.room-lobby-br-fixed .lobby-b-sq-btn img,
+.room-lobby-br-fixed .btn-voice-icon img {
+ width: 100%;
+ height: 100%;
+ max-width: 100%;
+ max-height: 100%;
+ object-fit: contain;
+ object-position: center;
+ display: block;
+ pointer-events: none;
+ user-select: none;
+ -webkit-user-drag: none;
+}
+.room-lobby-br-fixed .btn-voice-icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: transparent;
+}
+
+/* —— แฟ้มหลักฐาน LobbyB (รูปจาก /Main-Lobby/IMAGE/See evidence) —— */
+.lobby-evidence-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 10047;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
+ box-sizing: border-box;
+}
+.lobby-evidence-overlay.is-hidden {
+ display: none !important;
+}
+.lobby-evidence-backdrop {
+ position: absolute;
+ inset: 0;
+ background: rgba(4, 8, 22, 0.78);
+ backdrop-filter: blur(10px);
+ -webkit-backdrop-filter: blur(10px);
+ cursor: pointer;
+}
+.lobby-evidence-dialog {
+ position: relative;
+ z-index: 1;
+ width: min(96vw, 900px);
+ max-height: min(92vh, 920px);
+ pointer-events: none;
+}
+.lobby-evidence-dialog * {
+ pointer-events: auto;
+}
+.lobby-evidence-frame {
+ position: relative;
+ width: 100%;
+ aspect-ratio: 1684 / 963;
+ filter: drop-shadow(0 0 24px rgba(0, 255, 255, 0.12)) drop-shadow(0 0 40px rgba(255, 0, 255, 0.08));
+}
+.lobby-evidence-bg {
+ display: block;
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ object-position: center top;
+ pointer-events: none;
+ user-select: none;
+ -webkit-user-drag: none;
+}
+.lobby-evidence-close {
+ position: absolute;
+ top: 5.5%;
+ right: 4%;
+ width: 8%;
+ max-width: 56px;
+ aspect-ratio: 1;
+ padding: 0;
+ margin: 0;
+ border: none;
+ border-radius: 10px;
+ background: transparent;
+ color: rgba(0, 255, 255, 0.95);
+ font-size: clamp(1.25rem, 4vw, 2rem);
+ line-height: 1;
+ cursor: pointer;
+ text-shadow: 0 0 12px rgba(0, 255, 255, 0.9);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: transform 0.15s ease, filter 0.15s ease;
+}
+.lobby-evidence-close:hover {
+ transform: scale(1.08);
+ filter: brightness(1.15);
+}
+.lobby-evidence-tabs-layer {
+ position: absolute;
+ left: 7%;
+ right: 7%;
+ top: 15.5%;
+ height: 13.5%;
+ min-height: 36px;
+}
+.lobby-evidence-tabs-img {
+ display: block;
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ object-position: left center;
+ pointer-events: none;
+ user-select: none;
+ -webkit-user-drag: none;
+}
+.lobby-evidence-tab-hits {
+ position: absolute;
+ inset: 0;
+ display: flex;
+ flex-direction: row;
+ align-items: stretch;
+ padding-left: 1.5%;
+ padding-right: 0;
+ box-sizing: border-box;
+}
+.lobby-evidence-tab-hit {
+ flex: 0 0 13.2%;
+ min-width: 0;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+ border: none;
+ background: transparent;
+ cursor: pointer;
+ border-radius: 8px;
+}
+.lobby-evidence-tab-hit:focus-visible {
+ outline: 2px solid rgba(0, 255, 255, 0.9);
+ outline-offset: 2px;
+}
+.lobby-evidence-tab-hit-spacer {
+ flex: 1 1 auto;
+ pointer-events: none;
+}
+.lobby-evidence-cards-root {
+ position: absolute;
+ left: 5%;
+ right: 5%;
+ top: 31%;
+ bottom: 7%;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ gap: clamp(6px, 1.2vw, 14px);
+ align-items: stretch;
+ justify-content: center;
+ overflow-x: auto;
+ overflow-y: hidden;
+ scrollbar-width: thin;
+ padding-bottom: 4px;
+ box-sizing: border-box;
+}
+.lobby-evidence-card {
+ flex: 1 1 0;
+ min-width: min(200px, 28vw);
+ max-width: 320px;
+ display: flex;
+ flex-direction: column;
+ border-radius: 10px;
+ padding: clamp(6px, 1vw, 10px);
+ background: rgba(15, 20, 36, 0.92);
+ box-sizing: border-box;
+ box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 8px 24px rgba(0, 0, 0, 0.35);
+}
+.lobby-evidence-card--common {
+ box-shadow: 0 0 0 2px rgba(180, 190, 200, 0.65), 0 0 16px rgba(200, 210, 220, 0.2), 0 8px 24px rgba(0, 0, 0, 0.35);
+}
+.lobby-evidence-card--rare {
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.85), 0 0 20px rgba(59, 130, 246, 0.35), 0 8px 24px rgba(0, 0, 0, 0.35);
+}
+.lobby-evidence-card--legendary {
+ box-shadow: 0 0 0 2px rgba(234, 179, 8, 0.9), 0 0 22px rgba(250, 204, 21, 0.4), 0 8px 24px rgba(0, 0, 0, 0.35);
+}
+.lobby-evidence-card-head {
+ display: flex;
+ flex-direction: row;
+ align-items: flex-start;
+ gap: 8px;
+ margin-bottom: 6px;
+}
+.lobby-evidence-card-icon {
+ flex-shrink: 0;
+ width: 28px;
+ height: 28px;
+ border-radius: 6px;
+ background: linear-gradient(135deg, rgba(0, 255, 255, 0.25), rgba(255, 0, 255, 0.15));
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 14px;
+ line-height: 1;
+}
+.lobby-evidence-card-titles {
+ flex: 1;
+ min-width: 0;
+}
+.lobby-evidence-card-title-th {
+ font-family: 'Sarabun', 'Kanit', system-ui, sans-serif;
+ font-size: clamp(0.68rem, 1.35vw, 0.82rem);
+ font-weight: 700;
+ color: #e8ecff;
+ line-height: 1.25;
+ margin: 0;
+}
+.lobby-evidence-card-title-en {
+ font-family: system-ui, sans-serif;
+ font-size: clamp(0.58rem, 1.05vw, 0.68rem);
+ color: rgba(180, 190, 220, 0.85);
+ margin: 2px 0 0;
+ line-height: 1.2;
+}
+.lobby-evidence-card-art {
+ flex: 1 1 auto;
+ min-height: clamp(72px, 14vh, 140px);
+ max-height: min(22vh, 200px);
+ border-radius: 8px;
+ background: linear-gradient(160deg, rgba(30, 40, 70, 0.95), rgba(12, 16, 32, 0.98));
+ border: 1px solid rgba(0, 255, 255, 0.12);
+ margin-bottom: 6px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: rgba(0, 255, 255, 0.35);
+ font-size: clamp(1.5rem, 4vw, 2.25rem);
+ user-select: none;
+}
+.lobby-evidence-card-body {
+ font-family: 'Sarabun', 'Kanit', system-ui, sans-serif;
+ font-size: clamp(0.6rem, 1.15vw, 0.72rem);
+ color: rgba(210, 218, 240, 0.92);
+ line-height: 1.4;
+ margin: 0 0 8px;
+ flex-shrink: 0;
+ max-height: 4.5em;
+ overflow: hidden;
+ display: -webkit-box;
+ -webkit-line-clamp: 4;
+ -webkit-box-orient: vertical;
+}
+.lobby-evidence-card-foot {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+ gap: 8px;
+ margin-top: auto;
+ flex-shrink: 0;
+}
+.lobby-evidence-link {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 6px;
+ min-width: 0;
+}
+.lobby-evidence-avatar {
+ width: 26px;
+ height: 26px;
+ border-radius: 50%;
+ background: linear-gradient(145deg, #7aa2f7, #565f89);
+ color: #1a1b26;
+ font-size: 11px;
+ font-weight: 800;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ box-shadow: 0 0 0 2px rgba(0, 255, 255, 0.25);
+}
+.lobby-evidence-link-name {
+ font-size: clamp(0.62rem, 1.1vw, 0.74rem);
+ font-weight: 600;
+ color: #c0caf5;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.lobby-evidence-foot-meta {
+ text-align: right;
+ flex-shrink: 0;
+}
+.lobby-evidence-rarity {
+ display: block;
+ font-size: clamp(0.55rem, 0.95vw, 0.65rem);
+ color: rgba(170, 180, 210, 0.9);
+ margin-bottom: 2px;
+}
+.lobby-evidence-stars {
+ font-size: clamp(0.65rem, 1.2vw, 0.78rem);
+ letter-spacing: 1px;
+ line-height: 1;
+}
+.lobby-evidence-card--common .lobby-evidence-stars { color: #d4d4d8; text-shadow: 0 0 8px rgba(200, 200, 210, 0.4); }
+.lobby-evidence-card--rare .lobby-evidence-stars { color: #60a5fa; text-shadow: 0 0 10px rgba(59, 130, 246, 0.5); }
+.lobby-evidence-card--legendary .lobby-evidence-stars { color: #fcd34d; text-shadow: 0 0 10px rgba(234, 179, 8, 0.55); }
+@media (max-width: 720px) {
+ .lobby-evidence-cards-root {
+ flex-wrap: wrap;
+ overflow-y: auto;
+ align-content: flex-start;
+ }
+ .lobby-evidence-card {
+ flex: 1 1 100%;
+ max-width: none;
+ min-width: 0;
+ }
+}
+
+/* —— กระดานอันดับ LobbyB (เหรียญ leaderboard-1/2/3 จาก Main-Lobby) —— */
+.lobby-rank-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 10048;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
+ box-sizing: border-box;
+}
+.lobby-rank-overlay.is-hidden {
+ display: none !important;
+}
+.lobby-rank-backdrop {
+ position: absolute;
+ inset: 0;
+ background: rgba(2, 4, 14, 0.82);
+ backdrop-filter: blur(8px);
+ -webkit-backdrop-filter: blur(8px);
+ cursor: pointer;
+}
+.lobby-rank-dialog {
+ position: relative;
+ z-index: 1;
+ width: min(96vw, 520px);
+ max-height: min(90vh, 720px);
+ pointer-events: none;
+}
+.lobby-rank-dialog * {
+ pointer-events: auto;
+}
+.lobby-rank-panel {
+ background: linear-gradient(165deg, rgba(28, 36, 58, 0.96), rgba(12, 16, 32, 0.98));
+ border-radius: 16px;
+ border: 2px solid rgba(0, 255, 255, 0.45);
+ box-shadow:
+ 0 0 0 1px rgba(255, 0, 200, 0.25),
+ 0 0 32px rgba(0, 255, 255, 0.12),
+ 0 0 48px rgba(255, 0, 180, 0.08),
+ inset 0 1px 0 rgba(255, 255, 255, 0.06);
+ padding: clamp(10px, 2.5vw, 16px);
+ display: flex;
+ flex-direction: column;
+ min-height: 0;
+ font-family: 'Kanit', 'Sarabun', system-ui, sans-serif;
+}
+.lobby-rank-head {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ padding: 6px 44px 12px 12px;
+ border-bottom: 1px solid rgba(0, 255, 255, 0.28);
+ margin-bottom: 8px;
+}
+.lobby-rank-case-title {
+ margin: 0;
+ font-size: clamp(0.95rem, 2.8vw, 1.15rem);
+ font-weight: 700;
+ color: #e8f4ff;
+ text-align: center;
+ text-shadow: 0 0 12px rgba(0, 255, 255, 0.35);
+ line-height: 1.25;
+}
+.lobby-rank-close {
+ position: absolute;
+ top: 2px;
+ right: 4px;
+ width: 44px;
+ height: 44px;
+ padding: 0;
+ border: none;
+ border-radius: 10px;
+ background: transparent;
+ color: rgba(0, 255, 255, 0.95);
+ font-size: 1.75rem;
+ line-height: 1;
+ cursor: pointer;
+ text-shadow: 0 0 14px rgba(0, 255, 255, 0.85);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: transform 0.15s ease, filter 0.15s ease;
+}
+.lobby-rank-close:hover {
+ transform: scale(1.06);
+ filter: brightness(1.12);
+}
+.lobby-rank-podium {
+ display: flex;
+ flex-direction: row;
+ align-items: flex-end;
+ justify-content: center;
+ gap: clamp(6px, 2vw, 14px);
+ padding: 8px 4px 14px;
+ flex-shrink: 0;
+}
+.lobby-rank-ped {
+ flex: 1 1 0;
+ min-width: 0;
+ max-width: 150px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+ padding: 10px 6px 12px;
+ border-radius: 14px;
+ background: rgba(0, 0, 0, 0.28);
+ border: 1px solid rgba(0, 255, 255, 0.22);
+ box-sizing: border-box;
+}
+.lobby-rank-ped--2 {
+ order: 1;
+ min-height: 148px;
+}
+.lobby-rank-ped--1 {
+ order: 2;
+ min-height: 188px;
+ border-color: rgba(255, 215, 0, 0.45);
+ box-shadow: 0 0 22px rgba(255, 200, 0, 0.12);
+}
+.lobby-rank-ped--3 {
+ order: 3;
+ min-height: 132px;
+}
+.lobby-rank-crown {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ gap: 4px;
+ margin-bottom: 4px;
+ font-size: 1.1rem;
+ line-height: 1;
+ filter: drop-shadow(0 0 6px rgba(255, 215, 0, 0.6));
+}
+.lobby-rank-crown-n {
+ font-size: 0.85rem;
+ font-weight: 800;
+ color: #ffe066;
+}
+.lobby-rank-medal-wrap {
+ height: 36px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 6px;
+}
+.lobby-rank-medal-img {
+ width: auto;
+ height: 34px;
+ object-fit: contain;
+ display: block;
+}
+.lobby-rank-ped-avatar {
+ width: 48px;
+ height: 48px;
+ border-radius: 50%;
+ background: linear-gradient(145deg, #7aa2f7, #565f89);
+ color: #1a1b26;
+ font-size: 1.1rem;
+ font-weight: 800;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 6px;
+ box-shadow: 0 0 0 2px rgba(0, 255, 255, 0.3);
+ flex-shrink: 0;
+}
+.lobby-rank-ped--1 .lobby-rank-ped-avatar {
+ width: 56px;
+ height: 56px;
+ font-size: 1.25rem;
+}
+.lobby-rank-ped-name {
+ font-size: clamp(0.68rem, 2vw, 0.8rem);
+ font-weight: 600;
+ color: #e8ecff;
+ line-height: 1.2;
+ word-break: break-word;
+ max-width: 100%;
+}
+.lobby-rank-ped-score {
+ margin-top: 4px;
+ font-size: clamp(0.75rem, 2.2vw, 0.9rem);
+ font-weight: 700;
+ color: #fff;
+ text-shadow: 0 0 8px rgba(255, 255, 255, 0.2);
+}
+.lobby-rank-table-wrap {
+ flex: 1 1 auto;
+ min-height: 0;
+ overflow-y: auto;
+ overflow-x: hidden;
+ margin: 0 -4px;
+ padding: 0 4px;
+ scrollbar-width: thin;
+}
+.lobby-rank-table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: clamp(0.65rem, 1.9vw, 0.78rem);
+}
+.lobby-rank-table thead th {
+ text-align: left;
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+ color: rgba(0, 255, 255, 0.85);
+ font-weight: 700;
+ padding: 8px 6px;
+ border-bottom: 1px solid rgba(0, 255, 255, 0.25);
+ position: sticky;
+ top: 0;
+ background: linear-gradient(180deg, rgba(20, 26, 44, 0.98), rgba(20, 26, 44, 0.92));
+ z-index: 1;
+}
+.lobby-rank-table thead th:nth-child(1) { width: 3.2rem; }
+.lobby-rank-table thead th:nth-child(3) { text-align: right; width: 4rem; }
+.lobby-rank-table tbody td {
+ padding: 7px 6px;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.06);
+ color: #e2e8f0;
+ vertical-align: middle;
+}
+.lobby-rank-table tbody td:nth-child(3) {
+ text-align: right;
+ font-weight: 600;
+ color: #fff;
+}
+.lobby-rank-table .lobby-rank-row-av {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ min-width: 0;
+}
+.lobby-rank-table .lobby-rank-mini-av {
+ width: 26px;
+ height: 26px;
+ border-radius: 50%;
+ background: linear-gradient(145deg, #9ece6a, #565f89);
+ color: #1a1b26;
+ font-size: 0.65rem;
+ font-weight: 800;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ box-shadow: 0 0 0 1px rgba(0, 255, 255, 0.2);
+}
+.lobby-rank-table .lobby-rank-row-name {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ max-width: 180px;
+}
+.lobby-rank-self {
+ flex-shrink: 0;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 10px;
+ padding: 12px 10px 6px;
+ margin-top: 6px;
+ border-top: 1px solid rgba(255, 0, 180, 0.42);
+ background: linear-gradient(90deg, rgba(255, 0, 180, 0.07), transparent);
+}
+.lobby-rank-self-rank {
+ font-weight: 800;
+ color: #c0caf5;
+ min-width: 2.5rem;
+ font-size: clamp(0.75rem, 2vw, 0.88rem);
+}
+.lobby-rank-self-av {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ background: linear-gradient(145deg, #f472b6, #a855f7);
+ color: #fff;
+ font-size: 1rem;
+ font-weight: 800;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ box-shadow: 0 0 0 2px rgba(255, 100, 200, 0.45);
+}
+.lobby-rank-self-meta {
+ flex: 1;
+ min-width: 0;
+}
+.lobby-rank-self-name {
+ font-size: clamp(0.85rem, 2.4vw, 1rem);
+ font-weight: 800;
+ color: #fff;
+ line-height: 1.2;
+}
+.lobby-rank-self-score {
+ font-size: clamp(0.85rem, 2.4vw, 1rem);
+ font-weight: 800;
+ color: #ff4ecd;
+ text-shadow: 0 0 12px rgba(255, 78, 205, 0.45);
+ flex-shrink: 0;
+}
+
+.version-tag {
+ position: fixed;
+ right: 8px;
+ bottom: 4px;
+ left: auto;
+ font-size: 10px;
+ color: #a9b1d6;
+ opacity: 0.7;
+ pointer-events: none;
+}
+
+/* play — quiz carry pregame (สอดคล้อง play.html) */
+.quiz-carry-pregame-card {
+ position: relative;
+ z-index: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ max-width: min(94vw, 900px);
+ width: 100%;
+ max-height: min(94vh, 900px);
+ overflow: hidden;
+ background: rgba(10, 12, 26, 0.55);
+ border: none;
+ border-radius: 4px;
+ box-shadow: none;
+ pointer-events: auto;
+}
+.quiz-carry-pregame-footer {
+ flex: 0 0 auto;
+ padding: 0.85rem 1rem 1rem;
+ background: linear-gradient(180deg, rgba(8, 10, 22, 0.2), rgba(8, 10, 22, 0.96));
+ border-top: none;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 0.65rem;
+}
+
+/* Editor — เกมตอบคำถาม */
+.quiz-editor-wrap {
+ margin: 1rem 0;
+ padding: 1rem;
+ background: #24283b;
+ border-radius: 8px;
+ border: 1px solid #414868;
+}
+.quiz-editor-wrap h3 {
+ margin: 0 0 0.5rem;
+ font-size: 1rem;
+ color: #7aa2f7;
+}
+.quiz-questions-list {
+ display: flex;
+ flex-direction: column;
+ gap: 0.6rem;
+ margin: 0.75rem 0;
+}
+.quiz-q-row {
+ display: grid;
+ grid-template-columns: 1fr auto auto;
+ gap: 0.5rem;
+ align-items: center;
+}
+@media (max-width: 600px) {
+ .quiz-q-row {
+ grid-template-columns: 1fr;
+ }
+}
+.quiz-q-row input[type="text"] {
+ min-width: 0;
+ padding: 0.4rem 0.5rem;
+ border-radius: 6px;
+ border: 1px solid #565f89;
+ background: #1a1b26;
+ color: #c0caf5;
+}
+.quiz-q-row select {
+ padding: 0.35rem;
+ border-radius: 6px;
+ border: 1px solid #565f89;
+ background: #1a1b26;
+ color: #c0caf5;
+}
+.btn-quiz-add,
+.quiz-q-remove {
+ padding: 0.35rem 0.65rem;
+ border-radius: 6px;
+ cursor: pointer;
+ border: 1px solid #565f89;
+ background: #414868;
+ color: #c0caf5;
+ font: inherit;
+}
+.quiz-q-remove {
+ font-size: 0.8rem;
+}
+
+/* Stack Tower play — เฟรมกล้องต้อง "คงที่ทุก resolution"
+ cover สเกลตามด้านที่ใหญ่กว่า → จอกว้าง/เตี้ย ต่างกัน = เฟรม/ซูมเปลี่ยน (กล้องเพี้ยนเวลาเปลี่ยน resolution + บล็อกห้อย/จุดวางหลุดเฟรม)
+ contain = เห็นทั้งฉาก 16:9 (บล็อกห้อย+จุดวาง+หอ) เหมือนกันเป๊ะทุกจอ; แถบ letterbox กลืนสีฉาก (#0a0e22) ไม่ดูจอเสีย */
+html.play-stack-tower-pixel-canvas #play-canvas-stage.play-canvas-stage {
+ background: #0a0e22 !important;
+}
+html.play-stack-tower-pixel-canvas #play-canvas-stage #game-canvas {
+ object-fit: contain !important;
+ object-position: center center !important;
+ background: #0a0e22 !important;
+}
diff --git a/www/html/Game/public/js/play.js b/www/html/Game/public/js/play.js
index 91df0ea..b9cb45a 100644
--- a/www/html/Game/public/js/play.js
+++ b/www/html/Game/public/js/play.js
@@ -2371,6 +2371,47 @@
ctx.restore();
}
+ /* ===== [2026-07-31] เติมขอบว่างด้วยอาร์ต (มือถือ/แท็บเล็ตเท่านั้น) =====
+ * เกมส่วนใหญ่ fit แบบ contain → จอที่สัดส่วนไม่ตรงแมปจะเหลือขอบสีพื้น = ผู้เล่นรู้สึก "ไม่เต็มจอ"
+ * แก้โดยปูภาพพื้นหลังตัวเดียวกันแบบ cover + เบลอ + หรี่ ไว้ "ใต้" ฉากจริง
+ * ⚠️ ห้ามเอาภาพ cover ไปแทนฉากจริง — ฉากต้องล็อกกับกริดโลก (งานจัดทางเดิน QB 17 รอบอยู่บนสมมติฐานนี้)
+ * ตัวนี้เป็นแค่ฉากหลังที่จะถูกฉากจริงทับทั้งหมดในพื้นที่ของโลก จึงไม่กระทบพิกัดใด ๆ
+ * perf: เรนเดอร์ครั้งเดียวเก็บใส่ canvas สำรอง (เบลอทุกเฟรมกินแรงเกินไปสำหรับมือถือ)
+ * ขอบเขต: เฉพาะ pointer: coarse → บน PC ภาพยังเป็นแบบเดิมเป๊ะ */
+ let _bleedCache = null;
+ let _bleedCoarse = null;
+ function playIsCoarsePointer() {
+ if (_bleedCoarse != null) return _bleedCoarse;
+ try { _bleedCoarse = !!(window.matchMedia && window.matchMedia('(pointer: coarse)').matches); }
+ catch (e) { _bleedCoarse = false; }
+ return _bleedCoarse;
+ }
+ function drawBleedBackdropPlay(ctx2, img, cw, ch, fallbackColor) {
+ ctx2.fillStyle = fallbackColor;
+ ctx2.fillRect(0, 0, cw, ch);
+ if (!playIsCoarsePointer()) return;
+ if (!img || !img.complete || !img.naturalWidth) return;
+ const key = (img.currentSrc || img.src || '') + '|' + cw + 'x' + ch;
+ if (!_bleedCache || _bleedCache.key !== key) {
+ try {
+ const off = document.createElement('canvas');
+ off.width = Math.max(1, Math.round(cw));
+ off.height = Math.max(1, Math.round(ch));
+ const octx = off.getContext('2d');
+ const s = Math.max(cw / img.naturalWidth, ch / img.naturalHeight);
+ const dw = img.naturalWidth * s;
+ const dh = img.naturalHeight * s;
+ try { octx.filter = 'blur(18px) brightness(0.42) saturate(0.85)'; } catch (e) { /* เบราว์เซอร์ไม่รองรับ filter */ }
+ octx.drawImage(img, (cw - dw) / 2, (ch - dh) / 2, dw, dh);
+ try { octx.filter = 'none'; } catch (e) { /* ignore */ }
+ octx.fillStyle = 'rgba(10, 14, 34, 0.35)';
+ octx.fillRect(0, 0, off.width, off.height);
+ _bleedCache = { key, canvas: off };
+ } catch (e) { _bleedCache = null; return; }
+ }
+ if (_bleedCache) ctx2.drawImage(_bleedCache.canvas, 0, 0, cw, ch);
+ }
+
/** กล้องมองเหนือขอบบนแมป (worldMinY<0) + ใช้รูปแผนที่ — ยัด loop ท้องฟ้าเติมครึ่งบนจอ */
function drawStackTowerLoopSkyFillAboveMap(ctx, worldMinY, zDraw, cw, ch) {
if (!isStackTowerMissionUiMapPlay() || worldMinY >= 0) return;
@@ -6781,9 +6822,24 @@
zDraw = Math.min(canvas.width / mwPx, canvas.height / mhPx) * 0.96;
} else if (isJumpSurvive()) {
/* MG5 (jump_survive) — เกมเดียวที่ตกไปใช้ zoom ดิบ 1.4 (ไม่ fit จอ = เหลือขอบซ้าย-ขวา)
- → fit ความกว้างเต็มจอ (vertical scroller เลื่อนแนวตั้งด้วย jumpSurviveCamCenterY อยู่แล้ว) */
+ → fit ความกว้างเต็มจอ (vertical scroller เลื่อนแนวตั้งด้วย jumpSurviveCamCenterY อยู่แล้ว)
+ [2026-08-02] user: "mg5 ในมือถือเห็นไม่เท่า pc 1920×1080 · ควรเห็นทั้งเกม"
+ สูตรเดิม `zDraw = cw / mwPx` fit **แค่แนวนอน** → แนวตั้งเห็นเท่าไรขึ้นกับความสูงจอล้วน ๆ
+ จอเตี้ยจึงเห็นแท่นข้างบน/ข้างล่างน้อยกว่า PC (วัดแล้วเหลือ ~81% ของ PC และแย่ลงอีกเมื่อแถบ URL กางอยู่)
+ แก้แบบเดียวกับ lobby/MG4: บนจอสัมผัสให้เห็น "โลกแนวตั้ง" ไม่น้อยกว่าที่เดสก์ท็อป 1920×1080 เห็น
+ zRef = 1920/mwPx · โลกแนวตั้งที่ PC เห็น = 1080/zRef
+ zDraw = min(cw/mwPx, ch / โลกแนวตั้งที่ PC เห็น)
+ ⇒ ได้ทั้งความกว้างเต็มแมป และแนวตั้งไม่น้อยกว่า PC (จอกว้างมากจะเหลือขอบซ้ายขวาแทน ซึ่งดีกว่ามองไม่เห็นแท่น)
+ ⚠️ PC ไม่กระทบ — pointer: fine คืนสูตรเดิมเป๊ะ */
const mwPx = w * tileSize;
- if (mwPx > 0) zDraw = canvas.width / mwPx;
+ if (mwPx > 0) {
+ zDraw = canvas.width / mwPx;
+ if (playIsCoarsePointer()) {
+ const zRef = JS_REF_VIEW_W / mwPx;
+ const refVertWorld = JS_REF_VIEW_H / zRef; /* โลกแนวตั้งที่เดสก์ท็อป 1920×1080 เห็น */
+ if (refVertWorld > 0) zDraw = Math.min(zDraw, canvas.height / refVertWorld);
+ }
+ }
} else if (isQuizQuestionMissionRenderLockPlay()) {
const qmc = getQuizQuestionMissionMapCenterWorldPxPlay();
if (qmc) {
@@ -6793,9 +6849,16 @@
} else if (isQuizCarry()) {
const mwPx = w * tileSize;
const mhPx = h * tileSize;
- zDraw = Math.min(canvas.width / mwPx, canvas.height / mhPx) * 0.96;
+ zDraw = quizCarryEffectiveZoomPlay(mwPx, mhPx, canvas.width, canvas.height);
} else if (isQuizBattle()) {
zDraw *= quizBattleUserZoomMul;
+ /* [2026-08-02] Quiz Battle **ไม่มีการ fit จอเลย** (ซูมดิบ × ตัวคูณของผู้ใช้) ⇒ จอเล็กเห็นโลกน้อยกว่า PC ตามส่วน
+ วัดได้: iPhone 13 Pro แนวนอน เห็น 67% กว้าง · 64% สูง ของเดสก์ท็อป 1920×1080
+ แก้แบบเดียวกับ lobby/MG5: จอสัมผัสคูณด้วย min(1, cw/1920, ch/1080) → เห็นไม่น้อยกว่า PC
+ ⚠️ PC ได้ตัวคูณ 1 พอดี = ไม่ขยับ · และไม่แตะ quizBattleUserZoomMul (ผู้เล่นยังบีบซูมเองได้) */
+ if (playIsCoarsePointer() && canvas.width > 0 && canvas.height > 0) {
+ zDraw *= Math.min(1, canvas.width / QB_REF_VIEW_W, canvas.height / QB_REF_VIEW_H);
+ }
} else if (isGauntletCrownHeistMapPlay() && !(previewMode && editorEmbedReturn)) {
/* #1 map fit: gauntlet เกมจริง — fit "ความสูงแมป (ลู่ทั้งหมด)" ให้พอดีจอ resolution-adaptive
(เดิมใช้ zoom ดิบ ไม่ปรับตาม resolution = ไม่พอดี) · fit สูงอย่างเดียว เพราะ runway เลื่อนแนวนอน */
@@ -9373,11 +9436,51 @@
return !!(isDetectiveMinigamePlay() && quizCarryUseMissionSummaryOverlay());
}
/** quiz_carry: จุดกลางแมป (world px) — กล้องไม่ตามตัวละคร; ใช้ร่วม draw + overlay DOM */
+ /* ===== [2026-08-02] MG4 บนจอเล็ก — ซูมอย่างน้อยเท่าที่เดสก์ท็อป 1920×1080 ใช้ =====
+ ปัญหา (user: "mg4 อ่านไม่รู้เรื่อง"): ป้ายคำตอบ **วาดบน canvas** และฟอนต์มีพื้นล่างตายตัว 10px
+ (`drawQuizCarryChoiceLabels`: `Math.max(10, Math.min(24, ts * 0.24 * ps))`)
+ กล่องป้ายกว้างตามความกว้างข้อความ ⇒ พอฟอนต์ติดพื้น ป้ายค้างขนาดเดิมในหน่วยพิกเซลจอ
+ แต่แมปหดลงตาม zoom ⇒ **ป้ายใหญ่เกินแมปจนทับกัน**
+ วัดจริง: เดสก์ท็อป ts≈29px (ฟอนต์ที่ควรได้ 9.0 → ใช้ 10 = เกินนิดเดียว)
+ iPhone 13 Pro แนวนอน ts≈9.5px (ควรได้ 2.8 → ใช้ 10 = **เกิน 3.6 เท่า**) · แนวตั้ง เกิน 4.3 เท่า
+ แก้ (ทางเลือก B ที่ user เคาะ): จอสัมผัสใช้ zoom ไม่ต่ำกว่าที่เดสก์ท็อป 1920×1080 ใช้
+ ⇒ อัตราส่วน "ป้ายต่อช่อง" เท่ากับ PC เป๊ะ = ไม่ทับ และอ่านออก · แลกกับเห็นแมปแคบลงต้องเดินดู
+ ⚠️ PC ไม่กระทบเลย — `pointer: fine` คืนค่า fit เดิมทุกกรณี */
+ const QUIZ_CARRY_REF_VIEW_W = 1920;
+ const QUIZ_CARRY_REF_VIEW_H = 1080;
+ /* จอเดสก์ท็อปอ้างอิงของ MG5 — ใช้เป็นเกณฑ์ "ต้องเห็นไม่น้อยกว่านี้" บนจอสัมผัส (ดู computePlayCameraZDrawPlay) */
+ const JS_REF_VIEW_W = 1920;
+ const JS_REF_VIEW_H = 1080;
+ /* เกณฑ์เดียวกันสำหรับ Quiz Battle */
+ const QB_REF_VIEW_W = 1920;
+ const QB_REF_VIEW_H = 1080;
+ function quizCarryFitZoomPlay(mwPx, mhPx, cw, ch) {
+ return Math.min(cw / mwPx, ch / mhPx) * 0.96;
+ }
+ function quizCarryEffectiveZoomPlay(mwPx, mhPx, cw, ch) {
+ const fit = quizCarryFitZoomPlay(mwPx, mhPx, cw, ch);
+ if (!playIsCoarsePointer()) return fit;
+ const ref = quizCarryFitZoomPlay(mwPx, mhPx, QUIZ_CARRY_REF_VIEW_W, QUIZ_CARRY_REF_VIEW_H);
+ return Math.max(fit, ref);
+ }
+
function getQuizCarryMapCameraWorldCenterPxPlay() {
if (!mapData || mapData.gameType !== 'quiz_carry') return null;
const ww = mapData.width || 20, hh = mapData.height || 15;
const ts = tileSize;
- return { cx: ww * ts * 0.5, cy: hh * ts * 0.5 };
+ const mwPx = ww * ts, mhPx = hh * ts;
+ const center = { cx: mwPx * 0.5, cy: mhPx * 0.5 };
+ if (!canvas || !canvas.width || !canvas.height) return center;
+ const fit = quizCarryFitZoomPlay(mwPx, mhPx, canvas.width, canvas.height);
+ const zd = quizCarryEffectiveZoomPlay(mwPx, mhPx, canvas.width, canvas.height);
+ if (zd <= fit + 1e-6) return center; /* แมปยังพอดีจอ → กลางแมปเหมือนเดิมเป๊ะ */
+ /* ซูมเข้าจนแมปไม่พอดีแล้ว → กล้องตามตัวเรา แต่ห้ามเลื่อนจนเห็นนอกขอบแมป */
+ const halfW = canvas.width / (2 * zd);
+ const halfH = canvas.height / (2 * zd);
+ const px = ((me && typeof me.x === 'number') ? me.x : ww * 0.5) * ts;
+ const py = ((me && typeof me.y === 'number') ? me.y : hh * 0.5) * ts;
+ const clamp = (v, half, span) => (half * 2 >= span ? span * 0.5 : Math.max(half, Math.min(span - half, v)));
+ return { cx: clamp(px, halfW, mwPx), cy: clamp(py, halfH, mhPx) };
}
function isQuizBattle() { return mapData && mapData.gameType === 'quiz_battle'; }
@@ -17793,6 +17896,11 @@
if (keys['ArrowRight'] || keys['KeyD']) vx += 1;
if (keys['ArrowUp'] || keys['KeyW']) vy -= 1;
if (keys['ArrowDown'] || keys['KeyS']) vy += 1;
+ /* virtual joystick (จอสัมผัส) — บังคับยานเหมือน WASD · clamp ±1 กันกดคีย์+จอยพร้อมกันแล้วเร็วเป็นสองเท่า */
+ if (shouldShowVirtualJoystickPlay()) {
+ vx = Math.max(-1, Math.min(1, vx + (Number(quizQuestionMissionJoyVecX) || 0)));
+ vy = Math.max(-1, Math.min(1, vy + (Number(quizQuestionMissionJoyVecY) || 0)));
+ }
}
const moveSpd = 280;
const canPilotMe = !(isSpaceShooterMissionUiMapPlay() && me.spaceShooterEliminated);
@@ -20281,8 +20389,9 @@
if (jq && jumpSurviveOnGround && window.jdSound) { try { window.jdSound.playSfx('jump', 'mg5'); } catch (e) { /* ignore */ } }
if (jq && jumpSurviveOnGround) { try { if (socket && myId != null) socket.emit('js-jump'); } catch (e) { /* ignore */ } } /* broadcast กระโดด → peer ได้ยินเสียง (mg5 ไม่มีสัญญาณ jump แยกใน sync) */
- /* virtual joystick (touch) — แกน x ป้อนซ้าย/ขวาเหมือนคีย์ A/D (deadzone จัดการในตัว update แล้ว) */
- const joyX = isJumpSurviveMissionHudActivePlay() ? (Number(quizQuestionMissionJoyVecX) || 0) : 0;
+ /* virtual joystick (touch) — แกน x ป้อนซ้าย/ขวาเหมือนคีย์ A/D (deadzone จัดการในตัว update แล้ว)
+ MG5 ไม่ใช้แกน y: กระโดดอยู่ที่ปุ่มกระโดดมุมขวาล่างตามเดิม */
+ const joyX = shouldShowVirtualJoystickPlay() ? (Number(quizQuestionMissionJoyVecX) || 0) : 0;
const moveLeftIn = !!(keys['ArrowLeft'] || keys['KeyA']) || joyX < -0.001;
const moveRightIn = !!(keys['ArrowRight'] || keys['KeyD']) || joyX > 0.001;
@@ -25181,6 +25290,77 @@
});
}
+ /** [2026-08-01] ฉากนี้ "ต้องบังคับทิศ" ไหม — ตัวตัดสินว่าจอยเสมือนควรมีอยู่ในฉากนี้หรือเปล่า
+ (การแสดงผลจริงถูกกรองอีกชั้นด้วย @media (pointer: coarse) ใน play.html ⇒ PC ไม่เห็น)
+ ไม่เอา: MG2 gauntlet (วิ่งอัตโนมัติ · มีแต่ปุ่มกระโดด) · MG3 stack (ไม่เดินเลย)
+ · MG7 balloon_boss (ยานลอยตามลม **ไม่มีอินพุตทิศทางในโค้ดเลย** มีแต่ปุ่มยิง) · frogger (กดทีละช่อง) */
+ function playSceneUsesWalkJoystick() {
+ if (!mapData) return false;
+ if (isGauntlet() || isStack() || isBalloonBoss() || isFrogger()) return false;
+ return isQuiz() || isQuizCarry() || isJumpSurvive() || isSpaceShooter() || isQuizBattle() || isLobby();
+ }
+
+ /** จอยเสมือนควรโชว์ "ตอนนี้" ไหม — ต้องตรงกับช่วงที่เดินได้จริง
+ ไม่งั้นจะได้จอยที่กดแล้วตัวไม่ขยับ (เฟส howto/นับถอยหลัง/อ่านคำถาม/ป๊อปอัพคำถาม QB) */
+ /** [2026-08-02] ตกรอบแล้วไหม — เฉพาะ MG5/MG6 ที่ "ตายแล้วบังคับอะไรไม่ได้เลย" (เดินก็ไม่ได้ ยิงก็ไม่ได้)
+ คืนข้อความที่จะขึ้นบนป้าย · คืนค่าว่างถ้ายังเล่นอยู่
+ เหตุผล: เดิมไม่มีอะไรบอกว่าตายแล้ว ผู้เล่นอ่านว่า "ปุ่มเสีย" (user แจ้งมาเองทั้ง MG5 และ MG6)
+ วัดจริง MG6: ยานถูกทำลายที่วินาทีที่ 5.5-6.2 · เกมจริง 2-6 คน ต้องนั่งรอจนหมดเวลา ~83 วินาที */
+ function meEliminatedNoticePlay() {
+ if (isJumpSurvive() && isJumpSurviveMissionHudActivePlay() && jumpSurviveEliminated) {
+ return 'ตกรอบแล้ว — รอเพื่อนเล่นให้จบรอบ';
+ }
+ if (isSpaceShooter() && isSpaceShooterMissionHudActivePlay() && me && me.spaceShooterEliminated) {
+ return 'ยานถูกทำลาย — รอรอบจบ';
+ }
+ return '';
+ }
+
+ /** ป้าย "ตกรอบแล้ว" + หรี่ปุ่มแอ็กชันให้เข้าชุดกับจอย (จอยหรี่เองผ่าน shouldShowVirtualJoystickPlay) */
+ function syncEliminatedBannerPlay() {
+ const txt = meEliminatedNoticePlay();
+ const on = !!txt;
+ const el = document.getElementById('play-eliminated-banner');
+ if (el) {
+ el.classList.toggle('is-on', on);
+ el.setAttribute('aria-hidden', on ? 'false' : 'true');
+ if (on) {
+ const t = document.getElementById('play-eliminated-text');
+ if (t && t.textContent !== txt) t.textContent = txt;
+ }
+ }
+ /* MG5 มีปุ่มกระโดดฝั่งขวา — ตกรอบแล้วต้องหรี่+กดไม่ติดเหมือนจอย (MG6 ยิงอัตโนมัติ ไม่มีปุ่ม) */
+ const jb = document.getElementById('gauntlet-crown-jump-btn');
+ if (jb) jb.classList.toggle('is-inert', on);
+ }
+
+ function shouldShowVirtualJoystickPlay() {
+ if (!playSceneUsesWalkJoystick()) return false;
+ if (isChatFocused()) return false;
+ if (meEliminatedNoticePlay()) return false; /* ตกรอบแล้ว → จอยหรี่ กดไม่ติด */
+ if (isQuizCarryEmbedLobbyBlockingMovement() || isQuizCarryEmbedCountdownBlockingMovement()) return false;
+ if (isQuizBattleQuestionBlockingMovementPlay()) return false;
+ if (isQuizCarry() && quizCarryReadFreezeActive()) return false;
+ if (isQuiz() && isQuizQuestionMissionUiMapPlay()) return isQuizQuestionMissionHudActivePlay();
+ if (isJumpSurvive() && isJumpSurviveMissionUiMapPlay()) return isJumpSurviveMissionHudActivePlay();
+ if (isSpaceShooter() && isSpaceShooterMissionUiMapPlay()) return isSpaceShooterMissionHudActivePlay();
+ return true;
+ }
+
+ /** url ของรูปจอยที่โหลดไม่ขึ้น — จำไว้ถาวรเพื่อ **กันลูป 404 ทุกเฟรม** (sync จะไปหยิบ url เดิมซ้ำไม่รู้จบ) */
+ const virtualJoystickFailedImgUrls = Object.create(null);
+
+ /** รูปจอยตามสกินของฉาก — `btn-joystick-1/2.png` มีครบทุกโฟลเดอร์สกิน (md5 ตรงกันทั้ง 7 ณ 2026-08-01)
+ ฉากที่ไม่มีสกิน mock (Quiz Battle / lobby map) → ใช้ของ /img/QUESTION/ */
+ function virtualJoystickAssetUrlPlay(file) {
+ const fb = questionMissionAssetUrl(file);
+ let url = fb;
+ try {
+ if (isMissionMockHudPlay()) url = missionMockHudAssetUrl(file);
+ } catch (e) { /* ignore */ }
+ return virtualJoystickFailedImgUrls[url] ? fb : url;
+ }
+
function quizQuestionMissionJoystickResetVisual() {
quizQuestionMissionJoyVecX = 0;
quizQuestionMissionJoyVecY = 0;
@@ -25217,25 +25397,33 @@
knob.style.transform = 'translate(calc(-50% + ' + dx + 'px), calc(-50% + ' + dy + 'px))';
}
- function syncQuizQuestionMissionJoystickPlay() {
+ function syncVirtualJoystickPlay() {
const root = document.getElementById('quiz-question-mission-joystick');
if (!root) return;
- const jumperOn = isJumpSurviveMissionHudActivePlay();
- const on = !!((isQuizQuestionMissionHudActivePlay() || jumperOn) && !isChatFocused());
- root.classList.toggle('is-hidden', !on);
+ /* [2026-08-01] แยก 2 ระดับ:
+ ซ่อนสนิท (.is-hidden) = ฉากนี้ไม่มีการบังคับทิศเลย (MG2/MG3/MG7)
+ หรี่+กดไม่ได้ (.is-inert) = ฉากนี้เดินได้ แต่ "ตอนนี้" เกมบล็อกการเดินชั่วคราว
+ เหตุ: user แจ้ง QB/MG4 "ขยับไม่ค่อยได้" — ต้นเหตุคือเดิมพอบล็อกแล้ว **จอยหายไปทั้งอัน**
+ (QB = ป๊อปอัพคำถามเปิด · MG4 = เฟสอ่านคำถามที่ freeze ทุกคน) นิ้วที่วางอยู่จึงหลุด pointer capture
+ ต้องยกนิ้วแล้วกดใหม่ทุกรอบ = รู้สึกเหมือนคุมไม่ได้. คงปุ่มไว้แต่หรี่ = เห็นว่า "ยังอยู่ แค่ยังเดินไม่ได้" */
+ const sceneOk = playSceneUsesWalkJoystick();
+ const on = sceneOk && shouldShowVirtualJoystickPlay();
+ root.classList.toggle('is-hidden', !sceneOk);
+ root.classList.toggle('is-inert', sceneOk && !on);
root.setAttribute('aria-hidden', on ? 'false' : 'true');
if (on) {
- /* สลับรูป joystick ตามฉาก: jumper → /img/Jumper/, quiz คำถาม → /img/QUESTION/ (เปลี่ยน src เฉพาะตอน skin เปลี่ยน) */
- const skin = jumperOn ? 'jumper' : 'question';
+ /* สลับรูป joystick ตามสกินของฉาก (เปลี่ยน src เฉพาะตอน url เปลี่ยน — ไม่ยิงโหลดซ้ำทุกเฟรม) */
+ const bgUrl = virtualJoystickAssetUrlPlay('btn-joystick-1.png');
+ const knobUrl = virtualJoystickAssetUrlPlay('btn-joystick-2.png');
const bg = document.getElementById('quiz-q-mission-joystick-bg');
const knobImg = document.getElementById('quiz-q-mission-joystick-knob-img');
- if (bg && bg.dataset.joySkin !== skin) {
- bg.src = jumperOn ? jumperAssetUrl('btn-joystick-1.png') : questionMissionAssetUrl('btn-joystick-1.png');
- bg.dataset.joySkin = skin;
+ if (bg && bg.dataset.joyUrl !== bgUrl) {
+ bg.dataset.joyUrl = bgUrl;
+ bg.src = bgUrl;
}
- if (knobImg && knobImg.dataset.joySkin !== skin) {
- knobImg.src = jumperOn ? jumperAssetUrl('btn-joystick-2.png') : questionMissionAssetUrl('btn-joystick-2.png');
- knobImg.dataset.joySkin = skin;
+ if (knobImg && knobImg.dataset.joyUrl !== knobUrl) {
+ knobImg.dataset.joyUrl = knobUrl;
+ knobImg.src = knobUrl;
}
}
if (!on) {
@@ -26073,6 +26261,21 @@
}
/* Stack Tower (mnn93hpi): ไม่เลื่อนกล้องตาม floorWorldY — ใช้ cam จาก getStackCameraCentersPx() เหมือน Stack ทั่วไป (วางบล็อกแล้วจอไม่ไหล) */
lastPlayZDrawForInput = zDraw;
+ /* [2026-08-02] เปิดค่ากล้องที่ใช้วาดจริงให้ driver อ่านได้ (อ่านอย่างเดียว ไม่มีผลต่อเกม)
+ จำเป็นเพราะวัด "โลกที่มองเห็นกี่ช่อง" จากภาพไม่ได้ — ฉากที่เต็มจอจะคืนขนาดแมปเสมอ ไม่ว่าซูมเท่าไร
+ (เจอมาแล้ว: scene-view-parity-check วัด MG5 ได้ 35.0×20.0 = ขนาดแมปเป๊ะทั้งมือถือและ PC = อ่านไม่ออกว่าซูมต่างกัน) */
+ try {
+ window.__jdPlayView = {
+ gameType: (mapData && mapData.gameType) || '',
+ zDraw,
+ tileSize,
+ cw: canvas.width,
+ ch: canvas.height,
+ tilesW: canvas.width / (tileSize * zDraw),
+ tilesH: canvas.height / (tileSize * zDraw),
+ coarse: playIsCoarsePointer(),
+ };
+ } catch (e) { /* ignore */ }
const stackTowerWorldScrollScreenY = getStackTowerWorldLayerScrollScreenOffsetYPlay(zDraw);
const halfW = canvas.width / (2 * zDraw);
const halfH = canvas.height / (2 * zDraw);
@@ -26122,8 +26325,10 @@
ctx.drawImage(mapBackgroundImg, (canvas.width - _bbDw) / 2, (canvas.height - _bbDh) / 2, _bbDw, _bbDh);
} else if (mapBackgroundImg && mapBackgroundImg.complete && mapBackgroundImg.naturalWidth) {
/* กล้องเห็นพื้นที่นอก [0,map] ได้ — ห้ามสุ่มต้นทาง drawImage เกินขอบภาพ (จะเกิดซ้ำ/เส้นตัด/ซ้อนกันที่ขอบจอ) */
- ctx.fillStyle = (isSpaceShooter() || isBalloonBoss()) ? '#0a0e22' : '#1a1b26';
- ctx.fillRect(0, 0, canvas.width, canvas.height);
+ /* [2026-07-31] แทน fillRect สีพื้นเปล่า ๆ ด้วยฉากหลังเบลอจากภาพเดียวกัน (เฉพาะจอสัมผัส)
+ → ขอบว่างจากการ fit แบบ contain ไม่เป็นแถบทึบอีก · ฉากจริงวาดทับด้านล่างนี้ตามพิกัดโลกเหมือนเดิม */
+ drawBleedBackdropPlay(ctx, mapBackgroundImg, canvas.width, canvas.height,
+ (isSpaceShooter() || isBalloonBoss()) ? '#0a0e22' : '#1a1b26');
drawStackTowerLoopSkyFillAboveMap(ctx, worldMinY, zDraw, canvas.width, canvas.height);
const natW = mapBackgroundImg.naturalWidth;
const natH = mapBackgroundImg.naturalHeight;
@@ -27081,7 +27286,8 @@
}
drawQuizTfScorePopupsLayer(ctx, worldToScreen, zDraw, timeMs);
syncPlayCyberHud();
- syncQuizQuestionMissionJoystickPlay();
+ syncVirtualJoystickPlay();
+ syncEliminatedBannerPlay();
syncQuizCarryGrabButton();
syncGauntletCrownJumpButton();
syncStackTowerDropButtonPlay();
@@ -27538,9 +27744,11 @@
if (keys['ArrowRight'] || keys['KeyD']) kx += 1;
if (keys['ArrowUp'] || keys['KeyW']) ky -= 1;
if (keys['ArrowDown'] || keys['KeyS']) ky += 1;
+ /* virtual joystick (จอสัมผัส) — ป้อนทิศเหมือนคีย์ WASD ให้ทุกฉากที่ใช้ลูปเดินนี้
+ (MG1 quiz · MG4 quiz_carry · Quiz Battle · lobby map) */
let jx = 0;
let jy = 0;
- if (isQuizQuestionMissionHudActivePlay()) {
+ if (shouldShowVirtualJoystickPlay()) {
jx = quizQuestionMissionJoyVecX;
jy = quizQuestionMissionJoyVecY;
}
@@ -27561,7 +27769,17 @@
const antiStuckGame = !pathStrict && (isQuiz() || isQuizCarry());
let normalMoved = false;
if (pathStrict) {
- const moved = quizBattleTryStepMovePlay(me.x, me.y, tox, toy, (nx, ny, ox, oy) => canWalkLikeLobby(nx, ny, ox, oy));
+ const canWalkQb = (nx, ny, ox, oy) => canWalkLikeLobby(nx, ny, ox, oy);
+ const moved = quizBattleTryStepMovePlay(me.x, me.y, tox, toy, canWalkQb);
+ /* [2026-08-01] ❌ **เคยลองเพิ่ม "ไถลตามผนัง" ตรงนี้แล้วถอดออก — อย่าใส่กลับโดยไม่แก้แผนที่ก่อน**
+ เหตุผลที่อยากใส่: ก้าวทแยงที่ชนขอบเลนตันทั้งก้าว (สาขานี้ไม่มี fallback รายแกนเหมือนฉากอื่น)
+ เลน QB สูง 3 แถว กล่องชนสูง 1.35 → นิ้วบนจอยที่เอียงตลอดเวลารู้สึกว่าเดินไม่ค่อยได้
+ เหตุผลที่ต้องถอด (วัดด้วย A/B บนเครื่องจริง `justice-qb-playall` 10 ห้อง):
+ ไม่มีไถล = **10/10, 10/10** · มีไถล (สองแกน) = 7/10, 9/10 · มีไถล (แกนหลักอย่างเดียว) = 8/10, 9/10
+ ทุกห้องที่ล้ม **จบที่ (11,6) เหมือนกันเป๊ะ** = มุมขวาสุดของเลนแถว 6
+ ต้นเหตุจริงอยู่ที่ **รูปร่างแผนที่**: แถว 4-6 กว้าง x1-11 แต่ทางลง (แถว 7) กว้างแค่ x2-10
+ ⇒ x=11 บนแถว 6 เป็น "กระเป๋าตัน" (กดลงไม่ลง) · การไถลทำให้ไหลเข้าไปติดง่ายมาก
+ ถ้าจะเอาการไถลกลับมา ต้องแก้แผนที่ให้แถว 6 กับทางลงกว้างเท่ากันก่อน (งานข้อมูล ปลอดภัยกว่าแก้ฟิสิกส์) */
me.x = moved.x;
me.y = moved.y;
normalMoved = true;
@@ -27731,26 +27949,66 @@
});
})();
- (function wireQuizQuestionMissionJoystick() {
+ /* [2026-08-01] "เครื่องที่ไม่ได้โฟกัสจบไม่พร้อมเครื่องอื่น" (MG2)
+ ต้นเหตุ: เบราว์เซอร์หยุด requestAnimationFrame ทั้งหมดเมื่อแท็บถูกซ่อน → ตัวตัดสิน "จบเกม" ของ MG2
+ ซึ่งอยู่ใน tickGauntletCrownRunwayBgPlay() (ทั้งเส้นทาง "ตกขอบหมด" และ "ถึงเส้นชัย") ไม่ถูกเรียกเลย
+ เครื่องนั้นจึงต้องรอ event จาก server ที่มี grace 3 วิ = จบช้ากว่าเพื่อนเห็น ๆ
+ แก้: ระหว่างถูกซ่อน เดินลูปเดิมด้วย setInterval แทน — timer ในแท็บพื้นหลังถูก clamp (~1 วิ) แต่ยังทำงาน
+ และ `gauntlet-sync` ทาง socket ยังเข้ามาเต็มอัตรา → state สดพอให้ตัดสินได้ตรงจังหวะกับเครื่องอื่น
+ กลับมาแสดงผลเมื่อไหร่ ปล่อยให้ rAF คุมต่อทันที (กันเดินลูปซ้อนสองทาง) */
+ let hiddenRunwayHeartbeatTimer = null;
+ let hiddenRunwayHeartbeatLastMs = 0;
+ function stopHiddenRunwayHeartbeatPlay() {
+ if (hiddenRunwayHeartbeatTimer) {
+ clearInterval(hiddenRunwayHeartbeatTimer);
+ hiddenRunwayHeartbeatTimer = null;
+ }
+ hiddenRunwayHeartbeatLastMs = 0;
+ }
+ function startHiddenRunwayHeartbeatPlay() {
+ if (hiddenRunwayHeartbeatTimer) return;
+ hiddenRunwayHeartbeatLastMs = performance.now();
+ hiddenRunwayHeartbeatTimer = setInterval(function () {
+ if (typeof document !== 'undefined' && !document.hidden) { stopHiddenRunwayHeartbeatPlay(); return; }
+ if (!mapData || !isGauntlet()) return;
+ const now = performance.now();
+ const dt = Math.min(0.5, Math.max(0, (now - hiddenRunwayHeartbeatLastMs) / 1000));
+ hiddenRunwayHeartbeatLastMs = now;
+ try { tickGauntletCrownRunwayBgPlay(dt); } catch (_e) { /* ignore */ }
+ }, 250);
+ }
+ if (typeof document !== 'undefined') {
+ document.addEventListener('visibilitychange', function () {
+ if (document.hidden) startHiddenRunwayHeartbeatPlay();
+ else stopHiddenRunwayHeartbeatPlay();
+ });
+ }
+
+ (function wireVirtualJoystickPlay() {
const base = document.getElementById('quiz-q-mission-joystick-base');
const bg = document.getElementById('quiz-q-mission-joystick-bg');
const knobImg = document.getElementById('quiz-q-mission-joystick-knob-img');
if (!base) return;
- if (bg) {
- bg.src = questionMissionAssetUrl('btn-joystick-1.png');
- bg.dataset.joySkin = 'question';
- bg.onerror = function () {
- this.onerror = null;
- this.removeAttribute('src');
+ /* สกินไหนไม่มีไฟล์ → จำ url ที่พังไว้ (กัน sync หยิบซ้ำทุกเฟรม) แล้วตกไปใช้ของ /img/QUESTION/ ซึ่งมีแน่ */
+ const fallbackJoyImg = function (file) {
+ return function () {
+ const failed = this.dataset.joyUrl || this.getAttribute('src') || '';
+ if (failed) virtualJoystickFailedImgUrls[failed] = 1;
+ const fb = questionMissionAssetUrl(file);
+ if (failed === fb) { this.onerror = null; this.removeAttribute('src'); return; }
+ this.dataset.joyUrl = fb;
+ this.src = fb;
};
+ };
+ if (bg) {
+ bg.dataset.joyUrl = questionMissionAssetUrl('btn-joystick-1.png');
+ bg.src = bg.dataset.joyUrl;
+ bg.onerror = fallbackJoyImg('btn-joystick-1.png');
}
if (knobImg) {
- knobImg.src = questionMissionAssetUrl('btn-joystick-2.png');
- knobImg.dataset.joySkin = 'question';
- knobImg.onerror = function () {
- this.onerror = null;
- this.removeAttribute('src');
- };
+ knobImg.dataset.joyUrl = questionMissionAssetUrl('btn-joystick-2.png');
+ knobImg.src = knobImg.dataset.joyUrl;
+ knobImg.onerror = fallbackJoyImg('btn-joystick-2.png');
}
function endJoy(e) {
if (quizQuestionMissionJoyPointerId == null || e.pointerId !== quizQuestionMissionJoyPointerId) return;
@@ -27761,7 +28019,7 @@
quizQuestionMissionJoystickResetVisual();
}
base.addEventListener('pointerdown', (e) => {
- if (!(isQuizQuestionMissionHudActivePlay() || isJumpSurviveMissionHudActivePlay()) || isChatFocused()) return;
+ if (!shouldShowVirtualJoystickPlay()) return;
if (e.button != null && e.button !== 0) return;
e.preventDefault();
try {
@@ -27991,6 +28249,48 @@
resizeCanvas();
draw();
});
+ /** [2026-07-31] วัดขนาดใหม่ให้ครบทุกเหตุที่ "จอเปลี่ยนแต่ resize ไม่บอกความจริง" บนมือถือ
+ * - orientationchange: เดิมไม่ได้ผูกกับแคนวาสหลักเลย (ที่มีอยู่เป็นของ HUD MG1 คนละตัว)
+ * - visualViewport.resize: แถบ URL ยุบ/กาง จอสูงเปลี่ยนโดยไม่มี window resize ในบางเบราว์เซอร์
+ * ทั้งสองเหตุ เบราว์เซอร์มือถือรายงานขนาด "ค่าเก่า" อยู่ 1-2 เฟรม → วัดซ้ำอีก 2 จังหวะ
+ * (rAF ถัดไป + 250ms) กันค่าค้าง · กันเรียกซ้อนด้วย flag ตัวเดียว */
+ (function setupPlayViewportChangeRemeasure() {
+ let pending = false;
+ const remeasure = () => {
+ if (!mapData || !canvas) return;
+ resizeCanvas();
+ draw();
+ };
+ const schedule = () => {
+ remeasure();
+ if (pending) return;
+ pending = true;
+ requestAnimationFrame(() => { remeasure(); });
+ setTimeout(() => { pending = false; remeasure(); }, 250);
+ };
+ window.addEventListener('orientationchange', schedule);
+ try {
+ if (window.visualViewport && window.visualViewport.addEventListener) {
+ window.visualViewport.addEventListener('resize', schedule);
+ }
+ } catch (e) { /* เบราว์เซอร์เก่าไม่มี visualViewport — resize เดิมยังทำงานอยู่ */ }
+ })();
+ /** [2026-07-31] hint ชวนหมุนจอ — การ "แสดง/ซ่อน" คุมด้วย CSS ล้วน
+ * (@media orientation: portrait and pointer: coarse) เดสก์ท็อปจึงไม่มีทางเห็น โดยไม่ต้อง sniff อุปกรณ์
+ * JS ทำแค่เรื่องเดียว: จำว่าผู้เล่นกด "ข้าม" แล้ว จะได้ไม่ขึ้นกวนซ้ำในรอบเล่นเดียวกัน */
+ (function setupRotateHintDismiss() {
+ const KEY = 'jdRotateHintOff';
+ try { if (sessionStorage.getItem(KEY) === '1') document.documentElement.classList.add('rotate-hint-off'); }
+ catch (e) { /* private mode ปิด sessionStorage — ปล่อยให้ hint ขึ้นตามปกติ */ }
+ const btn = document.getElementById('rotate-hint-close');
+ if (!btn) return;
+ btn.addEventListener('click', (ev) => {
+ ev.preventDefault();
+ ev.stopPropagation();
+ document.documentElement.classList.add('rotate-hint-off');
+ try { sessionStorage.setItem(KEY, '1'); } catch (e) { /* ignore */ }
+ });
+ })();
/** แคนวาส flex ขยายทีหลัง (จอใหญ่ / editor iframe) — ResizeObserver จับได้ดีกว่า resize อย่างเดียว */
(function setupPlayCanvasStackResizeObserver() {
const stack = document.getElementById('play-canvas-stack');
diff --git a/www/html/Game/public/js/room-lobby.js b/www/html/Game/public/js/room-lobby.js
index a157516..98d9db8 100644
--- a/www/html/Game/public/js/room-lobby.js
+++ b/www/html/Game/public/js/room-lobby.js
@@ -1338,10 +1338,38 @@
let lobbyLastTickTs = 0; /* timestamp เฟรมก่อน (ms) ใช้คำนวณ dt */
let lastMoveSend = 0;
const moveCodes = ['KeyW', 'KeyA', 'KeyS', 'KeyD', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];
+ /* [2026-08-01] virtual joystick มุมซ้ายล่าง (จอสัมผัสเท่านั้น — การแสดงผลคุมด้วย @media (pointer: coarse) ใน room-lobby.html)
+ ทั้ง LobbyA และ LobbyB ต้องเดิน → ใช้จอยชุดเดียวกับ play.html (คลาส/ไอดีเดียวกัน) */
+ let lobbyJoyVecX = 0;
+ let lobbyJoyVecY = 0;
+ let lobbyJoyPointerId = null;
let lobbyInteractPulse = null;
- /* มือถือจอแคบ → zoom ต่ำลง ให้เห็นพื้นที่ lobby กว้างขึ้น (PC ย่อส่วน) · PC คงเดิม 1.2 */
- let lobbyZoom = (typeof window !== 'undefined' && (window.innerWidth || 0) > 0 && window.innerWidth < 600) ? 0.85 : 1.2;
- const LOBBY_ZOOM_MIN = 0.4;
+ /* [2026-08-02] zoom ของ lobby — user: "iPhone 13 Pro แนวนอน ซูมมากไป อยากเห็นเท่า desktop 1920×1080"
+ ของเดิมเป็นค่าคงที่ (`innerWidth < 600 ? 0.85 : 1.2`) ไม่ผูกกับขนาดจอเลย
+ iPhone 13 Pro แนวนอน (750×342) จึงได้ 1.2 เท่าเดสก์ท็อป แต่จอเล็กกว่า ⇒ วัดได้ว่าเห็นโลกแค่
+ **39% ของความกว้าง · 32% ของความสูง** ที่เดสก์ท็อป 1920×1080 เห็น
+ แก้: บนจอสัมผัส คิด zoom ให้ "พื้นที่โลกที่เห็น" เท่าเดสก์ท็อป 1920×1080
+ zoom = 1.2 × min(1, vw/1920, vh/1080) → iPhone 13 Pro ได้ ≈ 0.380 (ตรงกับที่วัดไว้)
+ ⚠️ PC ไม่แตะ — `pointer: fine` คืน 1.2 เท่าเดิมทุกกรณี (กฎ "ห้ามกระทบการเล่นบน PC") */
+ const LOBBY_ZOOM_DESKTOP = 1.2;
+ const LOBBY_VIEW_REF_W = 1920;
+ const LOBBY_VIEW_REF_H = 1080;
+ function lobbyDefaultZoom() {
+ try {
+ if (typeof window === 'undefined') return LOBBY_ZOOM_DESKTOP;
+ const coarse = !!(window.matchMedia && window.matchMedia('(pointer: coarse)').matches);
+ if (!coarse) return LOBBY_ZOOM_DESKTOP;
+ const vw = Math.max(1, window.innerWidth || 0);
+ const vh = Math.max(1, window.innerHeight || 0);
+ const k = Math.min(1, vw / LOBBY_VIEW_REF_W, vh / LOBBY_VIEW_REF_H);
+ return Math.max(0.2, LOBBY_ZOOM_DESKTOP * k);
+ } catch (e) { return LOBBY_ZOOM_DESKTOP; }
+ }
+ let lobbyZoom = lobbyDefaultZoom();
+ /** ผู้เล่นหมุนล้อ/ซูมเองแล้วหรือยัง — ถ้าเองแล้ว ห้ามไปคำนวณทับตอนหมุนจอ */
+ let lobbyZoomUserSet = false;
+ /* เพดานล่างต้องไม่ตัดค่า default ทิ้ง (จอเล็กมากคำนวณได้ต่ำกว่า 0.4) */
+ const LOBBY_ZOOM_MIN = Math.min(0.4, lobbyDefaultZoom());
const LOBBY_ZOOM_MAX = 2.5;
let mapTransform = { offsetX: 0, offsetY: 0, ts: 32, w: 20, h: 15 };
/** true เฉพาะช่องพิมพ์ข้อความ — ไม่รวม READY / แผนที่ (ให้กด F โต้ตอบได้โดยไม่ต้องกดพร้อมก่อน) */
@@ -1496,6 +1524,8 @@
const meY = (me && typeof me.y === 'number') ? me.y : 1;
const ts = tileSize * lobbyZoom;
mapTransform = { cw, ch, lobbyZoom, tileSize, meX, meY, w, h };
+ /* เปิดค่าที่ใช้วาดให้ตรวจได้จากภายนอก (driver วัด "โลกที่มองเห็นกี่ช่อง") — อ่านอย่างเดียว ไม่มีผลต่อเกม */
+ try { window.__jdLobbyView = { zoom: lobbyZoom, tileSize, cw, ch, tilesW: cw / (tileSize * lobbyZoom), tilesH: ch / (tileSize * lobbyZoom) }; } catch (e) { /* ignore */ }
ctx.fillStyle = '#303770';
ctx.fillRect(0, 0, cw, ch);
@@ -2310,7 +2340,16 @@
var byWidth = rect.width / baseWidth;
var byHeight = rect.height / baseHeight;
var targetScale = 1.08;
- var scale = Math.max(0.56, Math.min(targetScale, Math.min(byWidth, byHeight) * targetScale));
+ /* ⚠️ ห้ามคูณ targetScale เข้าไปในค่า "พอดีจอ" — targetScale คือ **เพดานขยายบนจอใหญ่** ไม่ใช่ตัวคูณ
+ ของเดิมคิด fit = min(byW,byH) × 1.08 ⇒ จอสูง 342px ได้ 0.38×1.08 = 0.41 → เนื้อหาสูง 369px = ยังล้น
+ ที่ถูกคือ fit = min(byW,byH) ตรง ๆ ⇒ 0.38 → 342px พอดีจอ · จอใหญ่ยังโดน clamp ที่ 1.08 เหมือนเดิม */
+ var fit = Math.min(byWidth, byHeight);
+ /* [2026-08-02] เดิมมีพื้นล่างตายตัว `Math.max(0.56, …)`
+ จอเตี้ย (iPhone แนวนอน + แถบ URL/บุ๊กมาร์กกินความสูง เหลือ ~342px) ต้องการแค่ ~0.41 จึงพอดีจอ
+ แต่ถูกดันขึ้นเป็น 0.56 ⇒ เนื้อหาสูง 0.56×900 = 504px ในจอสูง 342px = **การ์ดคดีโดนตัดขอบล่าง**
+ (user ส่งภาพจากเครื่องจริงมายืนยัน) · แก้: พื้นล่างห้ามดันจนล้นจอ เหลือแค่กันเล็กเกินอ่านไม่ออก
+ PC ไม่กระทบ — จอใหญ่ fit > 1.08 อยู่แล้ว ค่าจึงถูก clamp ที่ targetScale เหมือนเดิม */
+ var scale = Math.max(0.25, Math.min(targetScale, fit));
preplayStepCase.style.setProperty('--lobby-preplay-case-scale', scale.toFixed(4));
}
@@ -2519,7 +2558,11 @@
wrapper ตั้ง aspect-ratio ไว้ → ถ้าคดีไหนไม่มีไฟล์ข้อความ (404) ซ่อนแค่รูป ปุ่มไม่เลื่อน */
ov.innerHTML =
'' +
- '