ผีในเกม จริงหรือไม่

This commit is contained in:
2026-05-29 03:35:35 +00:00
parent 69b70dc422
commit 9c77c8405d
493 changed files with 10562 additions and 26 deletions
+38
View File
@@ -3860,6 +3860,44 @@
bindEmbedPanelFullscreen('btn-map-editor-fullscreen', 'tab-panel-map-editor');
bindEmbedPanelFullscreen('btn-character-fullscreen', 'tab-panel-characters');
/* Test Mode toggle — เก็บใน localStorage (share ระหว่าง Admin กับ Game ภายใต้ origin เดียวกัน) */
var TEST_MODE_KEY = 'justiceTestMode';
function isTestModeOn() {
try { return localStorage.getItem(TEST_MODE_KEY) === '1'; } catch (e) { return false; }
}
function setTestMode(on) {
try { localStorage.setItem(TEST_MODE_KEY, on ? '1' : '0'); } catch (e) { /* ignore */ }
}
function syncTestModeUi() {
var chk = el('test-mode-toggle');
var lbl = el('test-mode-state-label');
var msg = el('test-mode-msg');
var on = isTestModeOn();
if (chk) chk.checked = on;
if (lbl) {
lbl.textContent = on ? 'เปิดอยู่ (ON)' : 'ปิดอยู่ (OFF)';
lbl.style.color = on ? '#4ade80' : '#94a3b8';
}
if (msg) {
msg.textContent = on
? '✓ Test Mode เปิด — Shortcuts ใช้งานได้ในแท็บอื่นของเบราว์เซอร์นี้'
: '○ Test Mode ปิด — Shortcuts ไม่ทำงาน';
msg.style.color = on ? '#4ade80' : '#94a3b8';
}
}
var testModeChk = el('test-mode-toggle');
if (testModeChk) {
testModeChk.addEventListener('change', function () {
setTestMode(!!testModeChk.checked);
syncTestModeUi();
});
}
syncTestModeUi();
/* ฟัง storage event — sync เมื่อเปิดหลายแท็บ */
window.addEventListener('storage', function (e) {
if (e && e.key === TEST_MODE_KEY) syncTestModeUi();
});
var btnGameTimingSave = el('btn-game-timing-save');
if (btnGameTimingSave) {
btnGameTimingSave.addEventListener('click', function () {
+24 -1
View File
@@ -80,6 +80,7 @@
<button type="button" class="tab" data-tab="characters" role="tab" id="tab-characters" aria-controls="tab-panel-characters"><span class="tab-label">ตัวละคร</span><span class="tab-desc">อัปโหลด · เลือกใช้ในเกม</span></button>
<button type="button" class="tab" data-tab="accounts" role="tab" id="tab-accounts" aria-controls="tab-panel-accounts"><span class="tab-label">ผู้ใช้</span><span class="tab-desc">บัญชี &amp; COINS</span></button>
<button type="button" class="tab" data-tab="admins" role="tab" id="tab-admins" aria-controls="tab-panel-admins"><span class="tab-label">แอดมิน</span><span class="tab-desc">สิทธิ์ระบบ</span></button>
<button type="button" class="tab" data-tab="test-mode" role="tab" id="tab-test-mode" aria-controls="tab-panel-test-mode"><span class="tab-label">Test Mode</span><span class="tab-desc">เปิด hotkeys ทดสอบเกม</span></button>
</nav>
<section id="tab-panel-change-password" class="tab-panel card card--password" hidden role="tabpanel" aria-labelledby="tab-change-password">
@@ -901,9 +902,31 @@
</div>
<p id="admins-msg" class="msg" role="status"></p>
</section>
<section id="tab-panel-test-mode" class="tab-panel card" hidden role="tabpanel" aria-labelledby="tab-test-mode">
<h2>Test Mode (โหมดทดสอบ)</h2>
<p class="muted">เปิดเพื่อเปิดใช้ shortcut ทดสอบในเกม โดยทั่วไปควรปิดในการใช้งานจริงของผู้เล่น</p>
<div class="test-mode-toggle-wrap" style="display:flex;align-items:center;gap:16px;margin:18px 0;">
<label class="test-mode-switch" for="test-mode-toggle" style="display:inline-flex;align-items:center;gap:12px;cursor:pointer;user-select:none;">
<input type="checkbox" id="test-mode-toggle" style="width:22px;height:22px;cursor:pointer;">
<strong id="test-mode-state-label" style="font-size:16px;">ปิดอยู่</strong>
</label>
<span class="muted" style="font-size:13px;">บันทึกในเครื่องนี้เท่านั้น (localStorage)</span>
</div>
<h3 class="admin-subheading">Shortcuts ที่เปิดเมื่อ Test Mode = ON</h3>
<ul style="line-height:1.8;color:#cfd6ea;">
<li><kbd>Ctrl</kbd> + <kbd>1</kbd> / <kbd>2</kbd> / <kbd>3</kbd> — ในหน้าเลือกผู้ต้องสงสัย: เก็บหลักฐาน 1 ใบให้ suspect คนนั้นทันที (เทียบเท่าเล่นมินิเกมจบ 1 ครั้ง)<br>
<span class="muted" style="font-size:13px;">กดครบ 3 ปุ่ม → ปุ่ม "ชี้ตัวคนร้าย" โผล่</span>
</li>
</ul>
<p id="test-mode-msg" class="msg" role="status" style="margin-top:14px;"></p>
</section>
</div>
</main>
</div>
<script src="admin.js?v=70"></script>
<script src="admin.js?v=71"></script>
</body>
</html>
+34 -18
View File
@@ -2718,21 +2718,24 @@
: !!playQuizEverWrong[sid];
}
/** วาด "ผี" แทน avatar ทั้งตัวในแมป mng8a80o เมื่อตอบผิด — คุมผีเลย */
function drawQuizWrongGhostOverlayPlay(ax, ay, entId, nameLabel) {
/** "" avatar mng8a80o
* args กตวเป "screen pixels" แล (คำนวณจาก worldToScreen caller)
* - sxCenter = X งกลาง avatar บนจอ (px)
* - syBottom = Y เท avatar บนจอ (px)
* - heightPx = ความส avatar บนจอ (px) ใชมขนาดผใหพอด
*/
function drawQuizWrongGhostOverlayPlay(sxCenter, syBottom, heightPx, entId, nameLabel) {
const img = getQuizWrongGhostImg();
if (!img || !img.complete || !img.naturalWidth) return;
const tile = (typeof tileSize === 'number' && tileSize > 0) ? tileSize : 32;
/* ผีขนาดเท่าตัวละครเดิม: avatar ปกติ ~1 tile กว้าง, ~1.6 tile สูง → ผีกว้าง ~1.4, สูงตามสัดส่วน */
const wPx = tile * 1.4;
const ratio = img.naturalHeight / Math.max(1, img.naturalWidth);
const hPx = wPx * ratio;
/* ผีสูงเท่า avatar ตามจริง — คงสัดส่วนภาพ */
const hPx = Math.max(24, Number(heightPx) || 0);
const ratio = img.naturalWidth / Math.max(1, img.naturalHeight);
const wPx = hPx * ratio;
const sid = String(entId == null ? '' : entId);
const tBob = Math.sin(performance.now() / 360 + (sid ? sid.charCodeAt(0) || 0 : 0)) * (tile * 0.06);
/* วาดให้ "เท้าผี" ตรงกับเท้า avatar (avatar สูง 1.6 tile จากจุดบนซ้าย ay) */
const groundY = ay + tile * 1.6;
const drawX = ax + (tile - wPx) / 2;
const drawY = groundY - hPx + tBob;
const tBob = Math.sin(performance.now() / 360 + (sid ? sid.charCodeAt(0) || 0 : 0)) * (hPx * 0.04);
/* วาดให้ "เท้าผี" ตรงกับเท้า avatar */
const drawX = sxCenter - wPx / 2;
const drawY = syBottom - hPx + tBob;
ctx.save();
ctx.globalAlpha = 0.98;
ctx.drawImage(img, drawX, drawY, wPx, hPx);
@@ -2745,13 +2748,24 @@
ctx.fillStyle = 'rgba(255,255,255,0.95)';
ctx.strokeStyle = 'rgba(0,0,0,0.85)';
ctx.lineWidth = 3;
const nx = ax + tile / 2;
const ny = groundY + 14;
ctx.strokeText(nameLabel, nx, ny);
ctx.fillText(nameLabel, nx, ny);
const ny = syBottom + 14;
ctx.strokeText(nameLabel, sxCenter, ny);
ctx.fillText(nameLabel, sxCenter, ny);
ctx.restore();
}
}
/** tile coords screen pos ghost ( caller render scope)
* helpers เป scope-local (worldToScreen, zDraw) เพราะถกเรยกในรอบ draw เทาน */
function _quizGhostScreenAnchorPlay(axTile, ayTile, w2s, zDrawIn) {
const md = mapData;
const { cw, ch } = getCharacterFootprintWH(md);
const cxWorld = (axTile + cw * 0.5) * tileSize;
const cyBottomWorld = (ayTile + ch) * tileSize;
const [sx, sy] = w2s(cxWorld, cyBottomWorld);
/* ความสูง = สูง avatar บนจอ (สอดคล้องกับ drawAvatar: boxH = tileSize * zDraw * ch * 1.35) */
const sizeH = tileSize * zDrawIn * Math.max(ch, 1) * 1.35;
return { sx, sy, sizeH };
}
/** เกมถูก/ผิด — ตรงกับ server QUIZ_TF_POINTS_PER_CORRECT */
const QUIZ_TF_POINTS_PER_CORRECT = 10;
const QUIZ_TF_SCORE_PLUS_URL = BASE + '/img/QUESTION/score+.png';
@@ -18503,7 +18517,8 @@
if (botOut) ctx.globalAlpha = 0.4;
/* ตอบผิดในแมป mng8a80o → แทน avatar ด้วยผีเลย */
if (ghostActiveO) {
drawQuizWrongGhostOverlayPlay(axO, ayO, id, peerName);
const ga = _quizGhostScreenAnchorPlay(axO, ayO, worldToScreen, zDraw);
drawQuizWrongGhostOverlayPlay(ga.sx, ga.sy, ga.sizeH, id, peerName);
} else {
drawAvatar(axO, ayO, false, peerName, o.characterId, faceDirOther, otherWalk, ot, (o.gauntletJumpVis != null ? o.gauntletJumpVis : o.gauntletJumpTicks) || 0, o.gauntletScore || 0, quizCarrySignForEntity(o), isGauntletCrownHeistMapPlay() ? (o.gauntletCrownPenaltyFxUntil || 0) : 0);
}
@@ -18518,7 +18533,8 @@
if (isJumpSurvive() && jumpSurviveEliminated) ctx.globalAlpha = 0.4;
const faceDirMe = isGauntletFaceRightMapMno9kb07() ? 'right' : me.direction;
if (ghostActiveMe) {
drawQuizWrongGhostOverlayPlay(axMe, ayMe, myId, me.nickname + meTag);
const gam = _quizGhostScreenAnchorPlay(axMe, ayMe, worldToScreen, zDraw);
drawQuizWrongGhostOverlayPlay(gam.sx, gam.sy, gam.sizeH, myId, me.nickname + meTag);
} else {
drawAvatar(axMe, ayMe, true, me.nickname + meTag, me.characterId, faceDirMe, meWalking, mt, meGauntletJumpVis, me.gauntletScore || 0, quizCarrySignForEntity(me), isGauntletCrownHeistMapPlay() ? (me.gauntletCrownPenaltyFxUntil || 0) : 0);
}
+14 -3
View File
@@ -5598,9 +5598,13 @@
});
});
/* ลบปุ่ม X ปิดออกตาม design — ใช้ปุ่ม "เริ่มสืบสวน/ชี้ตัวคนร้าย" เท่านั้น */
const __sustClose = document.getElementById('suspect-pick-close');
if (__sustClose && __sustClose.parentNode) __sustClose.parentNode.removeChild(__sustClose);
/* X suspect overlay #btn-suspect-reopen
(โหมด trial: ไมให นหลดโฟกสตอนโหวต) */
document.getElementById('suspect-pick-close')?.addEventListener('click', () => {
if (!suspectPickOverlayOpen) return;
if (trialMode === 'voting' || trialMode === 'revealed') return;
closeSuspectOverlay();
});
document.getElementById('btn-suspect-reopen')?.addEventListener('click', () => {
if (!serverSuspectPhaseActive || suspectPickOverlayOpen) return;
@@ -5611,11 +5615,18 @@
* Hotkey ดสำหรบเทสต (เฉพาะตอน suspect overlay เป): Ctrl+1 / Ctrl+2 / Ctrl+3
* "เล่นเสร็จ 1 รอบ" ของ suspect คนน (เกบหลกฐาน 1 ใบใหนท)
* กดครบ 3 "ชี้ตัวคนร้าย" โผลตโนม
*
* เป/ดไดจาก Admin Panel tab "Test Mode" (localStorage: justiceTestMode = "1"|"0")
* โหมดโหวต/เปดเผยผล: hotkey องกนการกระทบเกม
*/
function __isJusticeTestModeOn() {
try { return localStorage.getItem('justiceTestMode') === '1'; } catch (e) { return false; }
}
document.addEventListener('keydown', (ev) => {
if (!ev.ctrlKey || ev.altKey || ev.metaKey || ev.shiftKey) return;
if (!suspectPickOverlayOpen) return;
/* Test Mode ปิดอยู่ — ข้าม (ตั้งใน Admin Panel → Test Mode) */
if (!__isJusticeTestModeOn()) return;
/* ขณะอยู่ใน input/textarea/ที่แก้ไขได้ — ข้าม กันชน UX */
const ae = document.activeElement;
if (ae && (ae.tagName === 'INPUT' || ae.tagName === 'TEXTAREA' || ae.isContentEditable)) return;
+1 -1
View File
@@ -3214,7 +3214,7 @@
<script src="/app-base.js?v=2"></script>
<script src="/Game/socket.io/socket.io.js"></script>
<script src="js/version.js?v=0.0306"></script>
<script src="js/play.js?v=0.0474"></script>
<script src="js/play.js?v=0.0475"></script>
<div class="version-tag">v —</div>
</body>
</html>
+8 -3
View File
@@ -426,10 +426,12 @@
}
#suspect-pick-close:hover { transform: scale(1.07); filter: brightness(1.12); }
#suspect-pick-close img { display: block; width: min(52px, 11vw); height: auto; }
/* ปุ่มบนโถง — เปิด overlay ใหม่เมื่อเฟสยัง active */
/* ปุ่มบนโถง — เปิด overlay ใหม่เมื่อเฟสยัง active
NOTE: ต้องอยู่ "หลัง" #testimony-overlay (z 9000) และ #suspect-pick-overlay (z 10045)
เพื่อไม่ทับ overlay สำคัญ — ตั้งค่าต่ำกว่า 9000 (สูงพอเหนือ HUD โถง) */
#btn-suspect-reopen {
position: fixed;
z-index: 10044;
z-index: 5500;
left: max(12px, env(safe-area-inset-left));
top: 50%;
transform: translateY(-50%);
@@ -1121,6 +1123,9 @@
</div>
<div id="suspect-pick-overlay" class="is-hidden" role="dialog" aria-modal="true" aria-labelledby="suspect-pick-sr-title" aria-hidden="true">
<h2 id="suspect-pick-sr-title" class="visually-hidden" style="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);">เลือกผู้ต้องสงสัย</h2>
<button type="button" id="suspect-pick-close" class="suspect-pick-close" title="ปิดหน้าต่าง (กดปุ่มด้านล่างเพื่อเปิดอีกครั้ง)" aria-label="ปิดหน้าเลือกผู้ต้องสงสัย">
<img src="/Main-Lobby/IMAGE/Choose%20a%20suspect/btn-close_1.png" alt="" width="56" height="56" decoding="async">
</button>
<div id="suspect-pick-scale-wrap" class="suspect-pick-scale-wrap">
<div class="suspect-pick-inner">
<img class="suspect-pick-title-img" src="/Main-Lobby/IMAGE/Choose%20a%20suspect/txt-suspect.png" alt="เลือกผู้ต้องสงสัย" width="1149" height="198" decoding="async">
@@ -1608,7 +1613,7 @@
<script src="js/display-name.js?v=2"></script>
<script src="js/version.js?v=0.0122"></script>
<script src="js/customize-popup.js?v=31" data-customize-triggers="" data-customize-asset-base="img/03-5-Customize"></script>
<script src="js/room-lobby.js?v=0.0253"></script>
<script src="js/room-lobby.js?v=0.0255"></script>
<div class="version-tag">v —</div>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

@@ -0,0 +1,103 @@
/* =========================================================
Base CSS Minigame-1 "จริงหรือไม่"
Base resolution : 1920 x 1080 (16:9)
========================================================= */
@font-face {
font-family: "NotoSansThai";
src: url("../../Fonts/NotoSansThai-Medium.ttf") format("truetype");
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "NotoSansThai";
src: url("../../Fonts/NotoSansThai-Bold.ttf") format("truetype");
font-weight: 700;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "NotoSansThai";
src: url("../../Fonts/NotoSansThai-Black.ttf") format("truetype");
font-weight: 900;
font-style: normal;
font-display: swap;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
background: #050813;
color: #ffffff;
font-family: "NotoSansThai", "Segoe UI", sans-serif;
overflow: hidden;
user-select: none;
-webkit-font-smoothing: antialiased;
}
img {
display: block;
pointer-events: none;
-webkit-user-drag: none;
}
/* ---------- 1920x1080 Stage ---------- */
.stage-wrap {
position: fixed;
inset: 0;
background: #050813;
overflow: hidden;
}
.stage {
position: absolute;
left: 0;
top: 0;
width: 1920px;
height: 1080px;
transform-origin: 0 0;
transform: scale(0.5);
}
/* ทุก element ภายใน stage ใช้พิกัด/ขนาดเป็น px ของ 1920x1080 */
.layer {
position: absolute;
}
/* placeholder กรอบกำกับช่องที่ยังไม่มี PNG */
.placeholder {
position: absolute;
border: 2px dashed rgba(255, 255, 255, 0.2);
border-radius: 10px;
color: rgba(255, 255, 255, 0.4);
font-size: 14px;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
background: rgba(255, 255, 255, 0.03);
pointer-events: none;
}
/* ปุ่มคลิกได้ */
.btn {
cursor: pointer;
transition: transform 0.15s ease, filter 0.15s ease;
}
.btn:hover {
filter: brightness(1.18) drop-shadow(0 0 14px rgba(120, 220, 255, 0.55));
transform: translateY(-2px);
}
.btn:active {
transform: translateY(1px);
filter: brightness(0.95);
}
@@ -0,0 +1,433 @@
/* =========================================================
game-hud.css Shared HUD สำหรับทุกหน้า in-game
• Top-left : SCORE panel (score-bar.png + 5 players)
• Top-center: TIME counter
• Top-right : Host avatar frame + mic button
• Background: BG.png (1920x1080)
========================================================= */
.mg-stage {
background: #04050d;
}
/* ---------------- พื้นหลัง BG เต็มจอ ---------------- */
.mg-bg {
left: 0;
top: 0;
width: 1920px;
height: 1080px;
z-index: 1;
}
.mg-bg img {
width: 100%;
height: 100%;
object-fit: cover;
}
/* =========================================================
มุมซ้ายบน : SCORE Panel (score-bar.png + 5 players)
========================================================= */
.mg-score-panel {
left: 2px;
top: 16px;
width: 156px;
height: 433px;
padding: 0;
overflow: hidden;
background: url("../../cut/score-bar.png") no-repeat left top / 156px 433px;
border: none;
border-radius: 0;
box-shadow: none;
z-index: 8;
}
.mg-score-title {
/* ข้อความ SCORE อยู่ใน score-bar.png แล้ว */
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.mg-score-list {
position: absolute;
left: 16px;
top: 60px;
width: 136px;
display: flex;
flex-direction: column;
gap: 5px;
}
.mg-score-row {
display: flex;
align-items: center;
gap: 10px;
height: 70px;
}
.mg-score-row .av {
position: relative;
width: 70px;
height: 70px;
flex: 0 0 70px;
border-radius: 0;
overflow: visible;
background: transparent;
}
.mg-score-row .av::after {
content: "";
position: absolute;
inset: 0;
background: url("../../cut/score-avartar.png") no-repeat center / contain;
pointer-events: none;
z-index: 2;
}
.mg-score-row .av img {
position: absolute;
inset: 4px;
width: calc(100% - 8px);
height: calc(100% - 8px);
object-fit: cover;
border-radius: 6px;
z-index: 1;
}
/* ไม่ใช้ placeholder สี — แสดงเฉพาะกรอบ score-avartar.png (หรือรูปใน <img>) */
.mg-score-row .av .ph {
display: none;
}
.mg-score-row .meta {
display: flex;
flex-direction: column;
gap: 1px;
line-height: 1.05;
flex: 1;
min-width: 0;
}
.mg-score-row .nm {
font-family: "NotoSansThai", sans-serif;
font-weight: 700;
font-size: 11px;
color: #e8f4ff;
letter-spacing: 0.2px;
text-transform: uppercase;
white-space: nowrap;
}
.mg-score-row .sc {
font-family: "NotoSansThai", sans-serif;
font-weight: 900;
font-size: 22px;
color: #ffffff;
line-height: 1;
text-shadow: 0 0 8px rgba(120, 220, 255, 0.6);
}
/* =========================================================
ตรงกลางบน : TIME : XX
========================================================= */
.mg-time {
left: 50%;
top: 23px;
transform: translateX(-50%);
display: flex;
align-items: center;
gap: 10px;
z-index: 8;
}
.mg-time-label {
width: 131px;
height: 71px;
flex: 0 0 131px;
}
.mg-time .num {
font-family: "NotoSansThai", sans-serif;
font-weight: 900;
font-size: 42px;
height: 71px;
line-height: 71px;
color: #e6f6ff;
letter-spacing: 1px;
font-variant-numeric: tabular-nums;
text-shadow:
0 0 10px rgba(120, 220, 255, 0.85),
0 0 22px rgba(80, 180, 240, 0.55);
}
.mg-time.is-warning .num {
color: #ff7a7a;
text-shadow:
0 0 12px rgba(255, 90, 90, 0.85),
0 0 24px rgba(255, 60, 60, 0.5);
}
.mg-time.is-warning {
animation: mg-pulse 0.9s ease-in-out infinite;
}
@keyframes mg-pulse {
0%, 100% { transform: translateX(-50%) scale(1); }
50% { transform: translateX(-50%) scale(1.08); }
}
/* =========================================================
มุมขวาบน : Host avatar (Avartar.png) + mic
========================================================= */
.mg-host {
left: 1729px;
top: 21px;
width: 201px;
height: 201px;
z-index: 8;
}
.mg-host-frame {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
z-index: 2;
pointer-events: none;
}
.mg-host-face {
position: absolute;
left: 49px;
top: 49px;
width: 104px;
height: 104px;
border-radius: 8px;
object-fit: cover;
z-index: 1;
}
.mg-host-face:not([src]),
.mg-host-face[src=""] {
display: none;
}
.mg-host .host-ph {
display: none;
}
.mg-mic {
left: 1796px;
top: 205px;
width: 121px;
height: 121px;
z-index: 8;
}
.mg-mic img {
width: 100%;
height: 100%;
}
@@ -0,0 +1,80 @@
/* =========================================================
howto.css หน้า 01 + 01-2 (HOW TO PLAY popup)
ใช้ popup-Howto.png เป็น content หลัก
+ ปุ่ม READY/START และ status text ใต้ popup
========================================================= */
/* ---------- dark overlay ทับ BG ---------- */
.mg-overlay {
left: 0;
top: 0;
width: 1920px;
height: 1080px;
background: rgba(4, 6, 18, 0.45);
z-index: 9;
}
/* ---------- popup HOW TO PLAY ---------- */
.howto-popup {
/* popup-Howto.png native 1451x851 (aspect 1.706)
ใน mockup กินพื้นที่เกือบทั้งจอ → ขยายให้ใหญ่ขึ้น แต่ยังคง aspect ratio */
left: 50%;
top: 50px;
transform: translateX(-50%);
width: 1500px;
height: 880px;
z-index: 10;
}
.howto-popup img {
width: 100%;
height: 100%;
}
/* ---------- ปุ่ม READY/START + status text ---------- */
.howto-status {
/* "Ready Status : 4/5" อยู่เหนือปุ่ม READY (ตาม mockup 01.png) */
left: 50%;
top: 808px;
transform: translateX(-50%);
font-family: "NotoSansThai", sans-serif;
font-weight: 700;
font-size: 22px;
color: #f067e8;
text-shadow: 0 0 10px rgba(240, 103, 232, 0.6),
0 0 22px rgba(237, 86, 224, 0.35);
letter-spacing: 0.5px;
text-align: center;
z-index: 13;
white-space: nowrap;
pointer-events: none;
}
.howto-status #hwRatio {
color: #f067e8;
}
.howto-btn {
/* btn-ready.png / btn-start.png native 351x141 (aspect 2.49)
ใน mockup ปุ่มอยู่ตรงเส้นกรอบล่าง popup (กึ่งกลาง) */
left: 957px;
top: 885px;
transform: translate(-50%, -50%);
height: 120px;
width: auto;
z-index: 12;
}
.howto-btn img {
height: 100%;
width: auto;
filter: drop-shadow(0 0 18px rgba(120, 220, 255, 0.65));
}
/* ---------- hover effect บนปุ่ม ---------- */
.howto-btn.btn:hover {
transform: translate(-50%, calc(-50% - 3px));
}
.howto-btn.btn:hover img {
filter: drop-shadow(0 0 28px rgba(120, 220, 255, 0.95));
}
.howto-btn.btn:active {
transform: translate(-50%, calc(-50% + 2px));
}
@@ -0,0 +1,254 @@
/* =========================================================
quiz.css หน้า 02-05 (in-game quiz states)
• SMS bar (กลางบน)
• 5 players row (กลางจอ)
• SAFE/SCAM zones (ด้านล่าง - มาจาก BG)
========================================================= */
/* =========================================================
SMS bar - กล่องข้อความ scam/safe กลางบน
========================================================= */
.qz-sms {
left: 50%;
top: 178px;
transform: translateX(-50%);
width: auto;
max-width: 1500px;
min-height: 0;
display: block;
text-align: center;
padding: 0 24px;
font-family: "NotoSansThai", sans-serif;
font-weight: 700;
font-size: 34px;
color: #fcf005;
line-height: 1.35;
text-shadow:
0 2px 4px rgba(0, 0, 0, 0.85),
0 0 12px rgba(252, 240, 5, 0.35);
letter-spacing: 0.3px;
z-index: 7;
}
.qz-sms .qz-num {
font-family: "NotoSansThai", sans-serif;
font-weight: 700;
font-size: 22px;
color: #cfeeff;
margin-bottom: 8px;
text-shadow: 0 0 8px rgba(120, 220, 255, 0.5);
letter-spacing: 1px;
}
/* ---------- explain text (สีเหลือง, เฉลย) ---------- */
.qz-explain {
left: 280px;
top: 110px;
width: 1360px;
min-height: 130px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: 8px 30px;
font-family: "NotoSansThai", sans-serif;
color: #ffd047;
z-index: 7;
}
.qz-explain .head {
font-weight: 700;
font-size: 30px;
text-shadow:
0 2px 4px rgba(0, 0, 0, 0.8),
0 0 12px rgba(255, 200, 80, 0.45);
line-height: 1.2;
}
.qz-explain .desc {
font-weight: 500;
font-size: 20px;
color: #ffffff;
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85);
line-height: 1.4;
margin-top: 4px;
}
/* =========================================================
Players row (5 ตัวกลางจอ ก่อนกดตอบ)
========================================================= */
.qz-players {
left: 50%;
top: 380px;
transform: translateX(-50%);
width: 920px;
height: 200px;
display: flex;
justify-content: space-between;
align-items: flex-end;
z-index: 5;
}
.qz-player {
width: 130px;
text-align: center;
position: relative;
}
.qz-player .nm {
font-family: "NotoSansThai", sans-serif;
font-weight: 700;
font-size: 18px;
color: #ffffff;
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
margin-bottom: 4px;
display: inline-flex;
align-items: center;
gap: 4px;
}
.qz-player .crown {
color: #ffd047;
font-size: 16px;
filter: drop-shadow(0 0 6px rgba(255, 200, 80, 0.55));
}
.qz-player .body {
width: 80px;
height: 130px;
margin: 0 auto;
border-radius: 14px 14px 8px 8px;
background:
radial-gradient(circle at 50% 22%, #f1d0c2 0%, #d49b80 40%, transparent 60%),
linear-gradient(180deg, var(--c, #ec88b8) 30%, color-mix(in srgb, var(--c, #ec88b8) 80%, #000) 100%);
border: 1.5px solid rgba(0, 0, 0, 0.3);
box-shadow:
inset 0 -10px 14px rgba(0, 0, 0, 0.3),
0 4px 10px rgba(0, 0, 0, 0.45);
position: relative;
}
.qz-player .body::after {
content: '';
position: absolute;
inset: 5px 5px auto;
height: 32px;
border-radius: 50%;
background: radial-gradient(circle at 50% 35%, #ffd9c4 0%, #c08a6e 70%, #5a3826 100%);
}
/* ---------- player ตอนถูกย้ายเข้า SAFE / SCAM ---------- */
.qz-zone-players {
left: 0;
top: 590px;
width: 1920px;
height: 460px;
pointer-events: none;
z-index: 6;
}
.qz-zone-players .qz-zp {
position: absolute;
width: 110px;
text-align: center;
}
.qz-zone-players .qz-zp .nm {
font-family: "NotoSansThai", sans-serif;
font-weight: 700;
font-size: 16px;
color: #ffffff;
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
margin-bottom: 4px;
display: inline-flex;
align-items: center;
gap: 4px;
}
.qz-zone-players .qz-zp .crown {
color: #ffd047;
font-size: 14px;
filter: drop-shadow(0 0 6px rgba(255, 200, 80, 0.55));
}
.qz-zone-players .qz-zp .body {
width: 70px;
height: 110px;
margin: 0 auto;
border-radius: 12px 12px 8px 8px;
background:
radial-gradient(circle at 50% 22%, #f1d0c2 0%, #d49b80 40%, transparent 60%),
linear-gradient(180deg, var(--c, #ec88b8) 30%, color-mix(in srgb, var(--c, #ec88b8) 80%, #000) 100%);
border: 1.5px solid rgba(0, 0, 0, 0.3);
box-shadow:
inset 0 -8px 12px rgba(0, 0, 0, 0.3),
0 4px 8px rgba(0, 0, 0, 0.45);
position: relative;
}
.qz-zone-players .qz-zp .body::after {
content: '';
position: absolute;
inset: 4px 4px auto;
height: 28px;
border-radius: 50%;
background: radial-gradient(circle at 50% 35%, #ffd9c4 0%, #c08a6e 70%, #5a3826 100%);
}
/* =========================================================
Countdown "3" / "2" / "1" (3.png / 2.png / 1.png)
วางทับกลางจอ บน SAFE/SCAM
========================================================= */
.qz-countdown {
left: 50%;
top: 750px;
transform: translate(-50%, -50%);
width: auto;
height: 220px;
z-index: 9;
filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.5));
}
.qz-countdown img {
height: 100%;
width: auto;
}
/* =========================================================
"+10" score (score+.png) เด้งบน SCAM/SAFE ตอนเฉลย
========================================================= */
.qz-score-pop {
left: 50%;
top: 770px;
transform: translate(-50%, -50%);
height: 130px;
z-index: 10;
pointer-events: none;
animation: qz-pop 0.6s ease-out;
}
.qz-score-pop.on-scam {
left: 65%;
}
.qz-score-pop.on-safe {
left: 35%;
}
.qz-score-pop img {
height: 100%;
width: auto;
filter: drop-shadow(0 0 18px rgba(255, 240, 110, 0.7));
}
@keyframes qz-pop {
0% { transform: translate(-50%, -30%) scale(0.4); opacity: 0; }
60% { transform: translate(-50%, -50%) scale(1.18); opacity: 1; }
100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}
/* =========================================================
ผีคนตกรอบ (ตอบผิด) - emoji 👻 + ชื่อ
========================================================= */
.qz-ghost {
position: absolute;
width: 90px;
text-align: center;
z-index: 6;
}
.qz-ghost .nm {
font-family: "NotoSansThai", sans-serif;
font-weight: 700;
font-size: 14px;
color: #ffffff;
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
margin-bottom: 2px;
}
.qz-ghost .ico {
font-size: 84px;
line-height: 1;
filter: drop-shadow(0 0 14px rgba(255, 255, 255, 0.8));
}
@@ -0,0 +1,427 @@
/* =========================================================
summary.css – หน้า 06 สรุปผลภารกิจ
อ้างอิง Mockup/06.png + ขนาด asset จริง (1920×1080)
popup-result.png 1451×851 @ 234,114
popup-result-Line1 938×3
popup-result-Line2 4×270
player-frame.png 137×137
mission-complete-select 271×90
btn-done.png 351×141
card-5 (Bail Coin) 287×383
========================================================= */
.sm-overlay {
left: 0;
top: 0;
width: 1920px;
height: 1080px;
background: rgba(4, 6, 18, 0.45);
z-index: 9;
}
/* ---------- popup-result.png ---------- */
.sm-popup {
left: 234px;
top: 114px;
width: 1451px;
height: 851px;
z-index: 10;
}
.sm-popup img {
width: 100%;
height: 100%;
display: block;
}
/* ---------- content layer (พิกัดเดียวกับ popup) ---------- */
.sm-content {
left: 234px;
top: 114px;
width: 1451px;
height: 851px;
z-index: 11;
overflow: hidden;
}
/* =========================================================
แถวอันดับ 5 คน
mockup: 5 ช่อง × 137px + gap 30px กึ่งกลาง (ไม่ space-between)
รวมความกว้าง = 5×137 + 4×30 = 805px
========================================================= */
.sm-ranks {
position: absolute;
left: 323px;
top: 168px;
display: flex;
align-items: flex-start;
gap: 30px;
width: 805px;
}
.sm-rank {
flex: 0 0 137px;
width: 137px;
min-width: 137px;
text-align: center;
position: relative;
}
.sm-rank .pos {
display: block;
width: 41px;
height: 21px;
margin: 0 auto 6px;
object-fit: contain;
}
/* กรอบ avatar = player-frame.png เท่านั้น (สีตัวละครอยู่ใน portrait) */
.sm-rank .av {
position: relative;
width: 137px;
height: 137px;
margin: 0 auto 8px;
background: transparent;
overflow: visible;
}
.sm-rank .portrait {
position: absolute;
inset: 10px;
z-index: 2;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
background: transparent;
}
/* ตัวละคร placeholder — จัดกึ่งกลางในกรอบ 117×117 */
.sm-rank .chibi {
position: relative;
width: 86px;
height: 92px;
flex-shrink: 0;
}
.sm-rank .ch-body {
position: absolute;
left: 50%;
bottom: 0;
width: 86px;
height: 52px;
transform: translateX(-50%);
border-radius: 50%;
background: var(--body, #6a6f96);
box-shadow: inset 0 6px 8px rgba(255, 255, 255, 0.2);
}
.sm-rank .ch-head {
position: absolute;
left: 50%;
bottom: 34px;
width: 54px;
height: 54px;
transform: translateX(-50%);
border-radius: 50%;
background: var(--skin, #f5d6b3);
z-index: 2;
}
.sm-rank .ch-hair {
position: absolute;
left: 50%;
bottom: 52px;
width: 62px;
height: 36px;
transform: translateX(-50%);
border-radius: 50% 50% 16px 16px / 80% 80% 28% 28%;
background: var(--hair, #2a2a2a);
z-index: 3;
}
/* ทุกอันดับใช้ player-frame.png ตรง asset — ไม่ hue-rotate */
.sm-rank .av .frame {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
z-index: 3;
pointer-events: none;
object-fit: contain;
}
/* ผู้เสียสละ — จางลง + stamp */
.sm-rank.is-out .av,
.sm-rank.is-out .portrait,
.sm-rank.is-out .chibi,
.sm-rank.is-out .ch-body,
.sm-rank.is-out .ch-head,
.sm-rank.is-out .ch-hair,
.sm-rank.is-out .av .frame {
filter: opacity(0.5);
}
.sm-rank .nm {
font-family: "NotoSansThai", sans-serif;
font-weight: 900;
font-size: 17px;
color: #ffffff;
letter-spacing: 0.6px;
line-height: 1.1;
margin-bottom: 2px;
}
.sm-rank .sc {
font-family: "NotoSansThai", sans-serif;
font-weight: 900;
font-size: 30px;
color: #ffffff;
text-shadow: 0 0 10px rgba(120, 220, 255, 0.4);
line-height: 1;
}
.sm-rank .av .stamp {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%) rotate(-8deg);
width: 114px;
height: auto;
z-index: 5;
pointer-events: none;
}
/* =========================================================
คะแนนรวม
========================================================= */
.sm-total {
position: absolute;
left: 5px;
right: 0;
top: 398px;
z-index: 4;
text-align: center;
font-family: "NotoSansThai", sans-serif;
font-weight: 700;
font-size: 24px;
color: #ffd047;
text-shadow:
0 0 10px rgba(255, 200, 80, 0.45),
0 2px 4px rgba(0, 0, 0, 0.6);
letter-spacing: 0.3px;
line-height: 1.2;
}
.sm-total .num {
font-weight: 900;
font-size: 40px;
color: #ffffff;
text-shadow: 0 0 14px rgba(120, 220, 255, 0.55);
margin-left: 6px;
}
/* เส้นแนวนอน บน + ล่าง "คะแนนรวม" (popup-result-Line1.png 938×3) */
.sm-line-1 {
position: absolute;
left: 50%;
transform: translateX(-50%);
width: 938px;
height: 3px;
display: block;
object-fit: fill;
z-index: 4;
pointer-events: none;
}
.sm-line-above {
top: 394px;
}
.sm-line-below {
top: 452px;
}
/* =========================================================
โซนล่าง — ระดับความสำเร็จ | โบนัสพิเศษ (Mockup/06)
grid 3 คอลัมน์: 1fr | เส้น 4px | 1fr ภายใน padding 72px
========================================================= */
.sm-bottom {
position: absolute;
left: 72px;
right: 72px;
top: 460px;
height: 270px;
display: grid;
grid-template-columns: 1fr 4px 1fr;
align-items: start;
column-gap: 0;
pointer-events: none;
}
.sm-bottom > * {
pointer-events: auto;
}
.sm-col {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
text-align: center;
min-width: 0;
}
.sm-col-grade {
margin-left: 173px;
margin-right: 14px;
margin-top: 41px;
height: 174px;
vertical-align: top;
}
.sm-col .head {
font-family: "NotoSansThai", sans-serif;
font-weight: 700;
font-size: 24px;
line-height: 1.2;
color: #ffffff;
margin: 0 0 12px;
padding: 0;
letter-spacing: 0.3px;
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}
.sm-col-grade .head {
height: 40px;
font-size: 40px;
}
.sm-grade {
margin: 0;
padding: 7px 6px;
font-family: "NotoSansThai", sans-serif;
font-weight: 900;
font-size: 96px;
color: #ffffff;
text-shadow:
0 0 16px rgba(120, 220, 255, 0.65),
0 0 32px rgba(80, 180, 240, 0.4);
line-height: 0.95;
}
/* เส้นแบ่งแนวตั้ง (popup-result-Line2.png 4×270) */
.sm-vrule {
display: flex;
justify-content: center;
align-self: stretch;
height: 270px;
}
.sm-line-2 {
width: 4px;
height: 270px;
display: block;
object-fit: fill;
}
/* โบนัส: ซ้าย = หัวข้อ + ภารกิจสำเร็จ | ขวา = Bail Coin สูงเท่ากลุ่มซ้าย */
.sm-col-bonus {
align-items: center;
width: 486px;
}
.sm-bonus {
display: flex;
flex-direction: row;
align-items: stretch;
justify-content: center;
gap: 14px;
width: auto;
max-width: 100%;
margin-left: 0;
margin-right: 0;
}
.sm-bonus-left {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: flex-start;
gap: 8px;
width: 271px;
height: 272px;
flex-shrink: 0;
font-size: 15px;
padding-top: 42px;
padding-bottom: 42px;
vertical-align: middle;
}
.sm-bonus-left .head {
width: 100%;
height: 53px;
margin: 0;
text-align: left;
font-size: 40px;
line-height: 1.2;
padding-left: 23px;
padding-right: 23px;
}
.sm-bonus .complete {
display: block;
width: 271px;
height: 90px;
flex-shrink: 0;
object-fit: contain;
filter: drop-shadow(0 0 10px rgba(91, 255, 141, 0.45));
}
.sm-bonus-right {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
height: 258px;
}
.sm-bonus .bail-card {
display: block;
width: auto;
height: 258px;
max-width: 152px;
flex-shrink: 0;
object-fit: contain;
object-position: center center;
filter: drop-shadow(0 0 14px rgba(120, 220, 255, 0.55));
}
/* =========================================================
ปุ่ม "รับหลักฐาน" – กึ่งกลางจอ ทับขอบล่าง popup
========================================================= */
.sm-btn-done {
left: 784px;
top: 818px;
width: 351px;
height: 141px;
z-index: 12;
}
.sm-btn-done img {
width: 100%;
height: 100%;
display: block;
object-fit: contain;
filter: drop-shadow(0 0 14px rgba(120, 220, 255, 0.45));
}
.sm-btn-done.btn:hover {
transform: none;
filter: brightness(1.12) drop-shadow(0 0 18px rgba(120, 220, 255, 0.6));
}
.sm-btn-done.btn:active {
transform: none;
filter: brightness(0.95);
}
@@ -0,0 +1,26 @@
/**
* scale.js - ปรับขนาด .stage (1920x1080) ให้พอดี viewport
* รักษาอัตราส่วน 16:9 เสมอ (letterbox ถ้าจำเป็น)
*/
(function () {
const BASE_W = 1920;
const BASE_H = 1080;
function fit() {
const stage = document.querySelector(".stage");
if (!stage) return;
const vw = window.innerWidth;
const vh = window.innerHeight;
const scale = Math.min(vw / BASE_W, vh / BASE_H);
const scaledW = BASE_W * scale;
const scaledH = BASE_H * scale;
const tx = (vw - scaledW) / 2;
const ty = (vh - scaledH) / 2;
stage.style.transform = `translate(${tx}px, ${ty}px) scale(${scale})`;
}
window.addEventListener("resize", fit);
window.addEventListener("orientationchange", fit);
document.addEventListener("DOMContentLoaded", fit);
window.addEventListener("load", fit);
})();
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 485 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

@@ -0,0 +1,165 @@
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<title>Minigame 1 - จริงหรือไม่ | Mockup Pages</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="assets/css/base.css">
<style>
body {
background: radial-gradient(ellipse at 50% 30%, #1a2447 0%, #07091a 70%);
color: #cfe5ff;
overflow: auto;
}
.wrap {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 60px 20px;
gap: 36px;
}
h1 {
font-size: 38px;
font-weight: 800;
letter-spacing: 1px;
text-shadow: 0 0 16px rgba(120, 220, 255, 0.5);
text-align: center;
}
h1 small {
display: block;
font-size: 16px;
font-weight: 500;
color: rgba(207, 229, 255, 0.6);
margin-top: 8px;
letter-spacing: 1px;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
gap: 24px;
max-width: 1280px;
width: 100%;
}
a.card {
display: block;
background: linear-gradient(180deg, #18234a 0%, #0c1230 100%);
border: 1px solid rgba(120, 220, 255, 0.32);
border-radius: 14px;
padding: 18px;
text-decoration: none;
color: inherit;
transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45);
}
a.card:hover {
transform: translateY(-4px);
border-color: rgba(255, 110, 220, 0.6);
box-shadow: 0 12px 36px rgba(255, 110, 220, 0.18), 0 4px 18px rgba(0, 0, 0, 0.55);
}
.thumb {
width: 100%;
aspect-ratio: 16/9;
border-radius: 10px;
background: #04060f center/cover no-repeat;
margin-bottom: 12px;
border: 1px solid rgba(255, 255, 255, 0.06);
}
.name {
font-size: 18px;
font-weight: 800;
color: #ffffff;
margin-bottom: 4px;
}
.sub {
font-size: 13px;
color: rgba(207, 229, 255, 0.7);
}
.badge {
display: inline-block;
margin-top: 12px;
padding: 5px 12px;
border-radius: 999px;
background: rgba(120, 220, 255, 0.15);
border: 1px solid rgba(120, 220, 255, 0.4);
color: #cfe5ff;
font-size: 12px;
font-weight: 700;
letter-spacing: 1px;
}
footer {
color: rgba(207, 229, 255, 0.5);
font-size: 13px;
text-align: center;
}
.back {
color: rgba(207, 229, 255, 0.7);
text-decoration: none;
font-size: 14px;
border: 1px solid rgba(120, 220, 255, 0.3);
padding: 6px 14px;
border-radius: 999px;
}
.back:hover {
color: #fff;
border-color: rgba(120, 220, 255, 0.7);
}
</style>
</head>
<body>
<div class="wrap">
<a class="back" href="../index.html">← กลับหน้าหลัก</a>
<h1>
Minigame 1 · "จริงหรือไม่"
<small>วิเคราะห์ภัยร้าย · ปกป้องระบบให้ปลอดภัย</small>
</h1>
<div class="grid">
<a class="card" href="pages/01-howto.html">
<div class="thumb" style="background-image:url('Mockup/01.png');"></div>
<div class="name">01 · HOW TO PLAY</div>
<div class="sub">หน้ารอเข้าเกม (READY / START)</div>
<span class="badge">เข้าหน้านี้ →</span>
</a>
<a class="card" href="pages/02-quiz-sms.html">
<div class="thumb" style="background-image:url('Mockup/02.png');"></div>
<div class="name">02 · Quiz - SMS</div>
<div class="sub">แสดง SMS · TIME 10 วินาที</div>
<span class="badge">เข้าหน้านี้ →</span>
</a>
<a class="card" href="pages/03-quiz-countdown.html">
<div class="thumb" style="background-image:url('Mockup/03.png');"></div>
<div class="name">03 · Quiz - Countdown</div>
<div class="sub">นับถอยหลัง "3" ก่อนตัดสิน</div>
<span class="badge">เข้าหน้านี้ →</span>
</a>
<a class="card" href="pages/04-quiz-voting.html">
<div class="thumb" style="background-image:url('Mockup/04.png');"></div>
<div class="name">04 · Quiz - Voting</div>
<div class="sub">ผู้เล่นวิ่งเข้าโซน SAFE/SCAM</div>
<span class="badge">เข้าหน้านี้ →</span>
</a>
<a class="card" href="pages/05-quiz-result.html">
<div class="thumb" style="background-image:url('Mockup/05.png');"></div>
<div class="name">05 · Quiz - Result</div>
<div class="sub">แสดงเฉลย + +10 คะแนน + ผีคนตกรอบ</div>
<span class="badge">เข้าหน้านี้ →</span>
</a>
<a class="card" href="pages/06-summary.html">
<div class="thumb" style="background-image:url('Mockup/06.png');"></div>
<div class="name">06 · สรุปผลภารกิจ</div>
<div class="sub">อันดับผู้เล่น + คะแนนรวม + เกรด</div>
<span class="badge">เข้าหน้านี้ →</span>
</a>
</div>
<footer>หน้าทั้งหมดถูก scale อัตโนมัติ (Base 1920×1080 · รักษาอัตราส่วน 16:9)</footer>
</div>
</body>
</html>
@@ -0,0 +1,117 @@
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<title>01 HOW TO PLAY · Minigame 1 - จริงหรือไม่</title>
<meta name="viewport" content="width=1920, initial-scale=1">
<link rel="stylesheet" href="../assets/css/base.css">
<link rel="stylesheet" href="../assets/css/game-hud.css">
<link rel="stylesheet" href="../assets/css/howto.css">
</head>
<body>
<div class="stage-wrap">
<div class="stage mg-stage">
<!-- ===== BG (TRUE/SAFE/SCAM/FALSE control room) ===== -->
<div class="layer mg-bg">
<img src="../cut/BG.png" alt="bg">
</div>
<!-- ===== SCORE Panel (มุมซ้ายบน) ===== -->
<div class="layer mg-score-panel">
<div class="mg-score-title">SCORE</div>
<div class="mg-score-list">
<div class="mg-score-row">
<div class="av"></div>
<div class="meta">
<span class="nm">MONE</span>
<span class="sc">0</span>
</div>
</div>
<div class="mg-score-row">
<div class="av"></div>
<div class="meta">
<span class="nm">JACKSON</span>
<span class="sc">0</span>
</div>
</div>
<div class="mg-score-row">
<div class="av"></div>
<div class="meta">
<span class="nm">MICKY</span>
<span class="sc">0</span>
</div>
</div>
<div class="mg-score-row">
<div class="av"></div>
<div class="meta">
<span class="nm">RAINY</span>
<span class="sc">0</span>
</div>
</div>
<div class="mg-score-row">
<div class="av"></div>
<div class="meta">
<span class="nm">JAME</span>
<span class="sc">0</span>
</div>
</div>
</div>
</div>
<!-- ===== TIME : 0 (top-center) ===== -->
<div class="layer mg-time">
<img class="mg-time-label" src="../cut/time.png" alt="TIME :">
<span class="num">0</span>
</div>
<!-- ===== Host avatar (top-right) ===== -->
<div class="layer mg-host">
<img class="mg-host-frame" src="../cut/Avartar.png" alt="">
<img class="mg-host-face" src="" alt="">
</div>
<div class="layer mg-mic">
<img src="../cut/btn-mic_on.png" alt="mic">
</div>
<!-- ===== Overlay + HOW TO PLAY popup ===== -->
<div class="layer mg-overlay"></div>
<div class="layer howto-popup">
<img src="../cut/popup-Howto.png" alt="HOW TO PLAY">
</div>
<!-- ===== Status + button (เปลี่ยนตาม state) ===== -->
<div class="layer howto-status" id="hwStatus">
Ready Status : <span id="hwRatio">4/5</span>
</div>
<div class="layer howto-btn btn" id="hwBtn">
<img id="hwBtnImg" src="../cut/btn-ready.png" alt="READY">
</div>
</div>
</div>
<script src="../assets/js/scale.js"></script>
<script>
// toggle ระหว่าง state READY (รอ) ↔ START (host พร้อมกด)
(function () {
const btn = document.getElementById('hwBtn');
const img = document.getElementById('hwBtnImg');
const status = document.getElementById('hwStatus');
let isStart = false;
btn.addEventListener('click', () => {
isStart = !isStart;
if (isStart) {
img.src = '../cut/btn-start.png';
img.alt = 'START';
status.innerHTML = 'กำลังรอ..ผู้เล่นกด Ready : <span id="hwRatio">3/4</span>';
} else {
img.src = '../cut/btn-ready.png';
img.alt = 'READY';
status.innerHTML = 'Ready Status : <span id="hwRatio">4/5</span>';
}
});
})();
</script>
</body>
</html>
@@ -0,0 +1,78 @@
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<title>02 Quiz · SMS - Minigame 1</title>
<meta name="viewport" content="width=1920, initial-scale=1">
<link rel="stylesheet" href="../assets/css/base.css">
<link rel="stylesheet" href="../assets/css/game-hud.css">
<link rel="stylesheet" href="../assets/css/quiz.css">
</head>
<body>
<div class="stage-wrap">
<div class="stage mg-stage">
<div class="layer mg-bg">
<img src="../cut/BG.png" alt="bg">
</div>
<!-- ===== SCORE Panel ===== -->
<div class="layer mg-score-panel">
<div class="mg-score-title">SCORE</div>
<div class="mg-score-list">
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">MONE</span><span class="sc">0</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">JACKSON</span><span class="sc">0</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">MICKY</span><span class="sc">0</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">RAINY</span><span class="sc">0</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">JAME</span><span class="sc">0</span></div></div>
</div>
</div>
<!-- ===== TIME ===== -->
<div class="layer mg-time">
<img class="mg-time-label" src="../cut/time.png" alt="TIME :">
<span class="num">10</span></div>
<!-- ===== Host avatar + mic ===== -->
<div class="layer mg-host">
<img class="mg-host-frame" src="../cut/Avartar.png" alt="">
<img class="mg-host-face" src="" alt="">
</div>
<div class="layer mg-mic"><img src="../cut/btn-mic_on.png" alt="mic"></div>
<!-- ===== SMS ข้อความ scam/safe กลางบน ===== -->
<div class="layer qz-sms">
SMS: คุณได้รับสิทธิ์กู้เงินฉุกเฉิน 50,000 บาท<br>
ดอกเบี้ย 0% คลิกเลย
</div>
<!-- ===== 5 ผู้เล่นยืนแถวกลางจอ ===== -->
<div class="layer qz-players">
<div class="qz-player">
<div class="nm">Mone</div>
<div class="body" style="--c:#ff8db5"></div>
</div>
<div class="qz-player">
<div class="nm"><span class="crown"></span>Jackson</div>
<div class="body" style="--c:#ffd267"></div>
</div>
<div class="qz-player">
<div class="nm">Micky</div>
<div class="body" style="--c:#7e84d1"></div>
</div>
<div class="qz-player">
<div class="nm">Rainy</div>
<div class="body" style="--c:#ff6b6b"></div>
</div>
<div class="qz-player">
<div class="nm">Jame</div>
<div class="body" style="--c:#85d28a"></div>
</div>
</div>
</div>
</div>
<script src="../assets/js/scale.js"></script>
</body>
</html>
@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<title>03 Quiz · Countdown - Minigame 1</title>
<meta name="viewport" content="width=1920, initial-scale=1">
<link rel="stylesheet" href="../assets/css/base.css">
<link rel="stylesheet" href="../assets/css/game-hud.css">
<link rel="stylesheet" href="../assets/css/quiz.css">
</head>
<body>
<div class="stage-wrap">
<div class="stage mg-stage">
<div class="layer mg-bg">
<img src="../cut/BG.png" alt="bg">
</div>
<div class="layer mg-score-panel">
<div class="mg-score-title">SCORE</div>
<div class="mg-score-list">
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">MONE</span><span class="sc">0</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">JACKSON</span><span class="sc">0</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">MICKY</span><span class="sc">0</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">RAINY</span><span class="sc">0</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">JAME</span><span class="sc">0</span></div></div>
</div>
</div>
<div class="layer mg-time is-warning">
<img class="mg-time-label" src="../cut/time.png" alt="TIME :">
<span class="num">0</span></div>
<div class="layer mg-host">
<img class="mg-host-frame" src="../cut/Avartar.png" alt="">
<img class="mg-host-face" src="" alt="">
</div>
<div class="layer mg-mic"><img src="../cut/btn-mic_on.png" alt="mic"></div>
<!-- ===== SMS with Quiz N number ===== -->
<div class="layer qz-sms">
<div class="qz-num">- Quiz 3 -</div>
SMS: "พัสดุของคุณถูกอายัดโดยกรมศุลกากร<br>
ชำระค่าปรับด่วนที่ [Link]"
</div>
<div class="layer qz-players">
<div class="qz-player"><div class="nm">Mone</div><div class="body" style="--c:#ff8db5"></div></div>
<div class="qz-player"><div class="nm"><span class="crown"></span>Jackson</div><div class="body" style="--c:#ffd267"></div></div>
<div class="qz-player"><div class="nm">Micky</div><div class="body" style="--c:#7e84d1"></div></div>
<div class="qz-player"><div class="nm">Rainy</div><div class="body" style="--c:#ff6b6b"></div></div>
<div class="qz-player"><div class="nm">Jame</div><div class="body" style="--c:#85d28a"></div></div>
</div>
<!-- ===== Countdown "3" (3.png) ตรงกลาง SAFE/SCAM ===== -->
<div class="layer qz-countdown">
<img src="../cut/3.png" alt="3">
</div>
</div>
</div>
<script src="../assets/js/scale.js"></script>
</body>
</html>
@@ -0,0 +1,77 @@
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<title>04 Quiz · Voting - Minigame 1</title>
<meta name="viewport" content="width=1920, initial-scale=1">
<link rel="stylesheet" href="../assets/css/base.css">
<link rel="stylesheet" href="../assets/css/game-hud.css">
<link rel="stylesheet" href="../assets/css/quiz.css">
</head>
<body>
<div class="stage-wrap">
<div class="stage mg-stage">
<div class="layer mg-bg">
<img src="../cut/BG.png" alt="bg">
</div>
<div class="layer mg-score-panel">
<div class="mg-score-title">SCORE</div>
<div class="mg-score-list">
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">MONE</span><span class="sc">20</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">JACKSON</span><span class="sc">20</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">MICKY</span><span class="sc">20</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">RAINY</span><span class="sc">20</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">JAME</span><span class="sc">10</span></div></div>
</div>
</div>
<div class="layer mg-time is-warning">
<img class="mg-time-label" src="../cut/time.png" alt="TIME :">
<span class="num">5</span></div>
<div class="layer mg-host">
<img class="mg-host-frame" src="../cut/Avartar.png" alt="">
<img class="mg-host-face" src="" alt="">
</div>
<div class="layer mg-mic"><img src="../cut/btn-mic_on.png" alt="mic"></div>
<div class="layer qz-sms">
<div class="qz-num">- Quiz 3 -</div>
SMS: "พัสดุของคุณถูกอายัดโดยกรมศุลกากร<br>
ชำระค่าปรับด่วนที่ [Link]"
</div>
<!-- ===== ผู้เล่นวิ่งเข้าโซน SAFE / SCAM (ตามตำแหน่งใน mockup) ===== -->
<div class="layer qz-zone-players">
<!-- Jame อยู่ใน SAFE -->
<div class="qz-zp" style="left:420px; top:130px;">
<div class="nm">Jame</div>
<div class="body" style="--c:#85d28a"></div>
</div>
<!-- Mone, Micky, Rainy, Jackson อยู่ใน SCAM -->
<div class="qz-zp" style="left:1010px; top:170px;">
<div class="nm">Mone</div>
<div class="body" style="--c:#ff8db5"></div>
</div>
<div class="qz-zp" style="left:1140px; top:50px;">
<div class="nm">Micky</div>
<div class="body" style="--c:#7e84d1"></div>
</div>
<div class="qz-zp" style="left:1280px; top:0px;">
<div class="nm">Rainy</div>
<div class="body" style="--c:#ff6b6b"></div>
</div>
<div class="qz-zp" style="left:1240px; top:180px;">
<div class="nm"><span class="crown"></span>Jackson</div>
<div class="body" style="--c:#ffd267"></div>
</div>
</div>
</div>
</div>
<script src="../assets/js/scale.js"></script>
</body>
</html>
@@ -0,0 +1,85 @@
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<title>05 Quiz · Result - Minigame 1</title>
<meta name="viewport" content="width=1920, initial-scale=1">
<link rel="stylesheet" href="../assets/css/base.css">
<link rel="stylesheet" href="../assets/css/game-hud.css">
<link rel="stylesheet" href="../assets/css/quiz.css">
</head>
<body>
<div class="stage-wrap">
<div class="stage mg-stage">
<div class="layer mg-bg">
<img src="../cut/BG.png" alt="bg">
</div>
<div class="layer mg-score-panel">
<div class="mg-score-title">SCORE</div>
<div class="mg-score-list">
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">MONE</span><span class="sc">20</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">JACKSON</span><span class="sc">20</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">MICKY</span><span class="sc">20</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">RAINY</span><span class="sc">20</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">JAME</span><span class="sc">10</span></div></div>
</div>
</div>
<div class="layer mg-time is-warning">
<img class="mg-time-label" src="../cut/time.png" alt="TIME :">
<span class="num">0</span></div>
<div class="layer mg-host">
<img class="mg-host-frame" src="../cut/Avartar.png" alt="">
<img class="mg-host-face" src="" alt="">
</div>
<div class="layer mg-mic"><img src="../cut/btn-mic_on.png" alt="mic"></div>
<!-- ===== เฉลย (สีเหลือง) ===== -->
<div class="layer qz-explain">
<div class="head">พัสดุถูกอายัด/ให้ชำระค่าปรับ = SCAM</div>
<div class="desc">
(หน่วยงานรัฐไม่มีนโยบายส่งลิงค์ SMS ให้ชำระเงินโดยตรง<br>
ต้องไปที่สถานี หรือจ่ายผ่านระบบทางการ)
</div>
</div>
<!-- ===== Jame ตอบผิด → ผี (ghost) อยู่นอกโซน ===== -->
<div class="qz-ghost" style="left:340px; top:540px;">
<div class="nm">Jame</div>
<div class="ico">👻</div>
</div>
<!-- ===== ผู้เล่น 4 คนที่ตอบถูกใน SCAM ===== -->
<div class="layer qz-zone-players">
<div class="qz-zp" style="left:1010px; top:170px;">
<div class="nm">Mone</div>
<div class="body" style="--c:#ff8db5"></div>
</div>
<div class="qz-zp" style="left:1140px; top:50px;">
<div class="nm">Micky</div>
<div class="body" style="--c:#7e84d1"></div>
</div>
<div class="qz-zp" style="left:1280px; top:0px;">
<div class="nm">Rainy</div>
<div class="body" style="--c:#ff6b6b"></div>
</div>
<div class="qz-zp" style="left:1240px; top:180px;">
<div class="nm"><span class="crown"></span>Jackson</div>
<div class="body" style="--c:#ffd267"></div>
</div>
</div>
<!-- ===== +10 score popup ===== -->
<div class="layer qz-score-pop on-scam">
<img src="../cut/score+.png" alt="+10">
</div>
</div>
</div>
<script src="../assets/js/scale.js"></script>
</body>
</html>
@@ -0,0 +1,184 @@
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<title>06 สรุปผลภารกิจ · Minigame 1</title>
<meta name="viewport" content="width=1920, initial-scale=1">
<link rel="stylesheet" href="../assets/css/base.css">
<link rel="stylesheet" href="../assets/css/game-hud.css">
<link rel="stylesheet" href="../assets/css/summary.css">
</head>
<body>
<div class="stage-wrap">
<div class="stage mg-stage">
<div class="layer mg-bg">
<img src="../cut/BG.png" alt="bg">
</div>
<!-- ===== HUD ===== -->
<div class="layer mg-score-panel">
<div class="mg-score-title">SCORE</div>
<div class="mg-score-list">
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">MONE</span><span class="sc">100</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">JACKSON</span><span class="sc">100</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">MICKY</span><span class="sc">20</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">RAINY</span><span class="sc">100</span></div></div>
<div class="mg-score-row"><div class="av"></div><div class="meta"><span class="nm">JAME</span><span class="sc">10</span></div></div>
</div>
</div>
<div class="layer mg-time">
<img class="mg-time-label" src="../cut/time.png" alt="TIME :">
<span class="num">0</span>
</div>
<div class="layer mg-host">
<img class="mg-host-frame" src="../cut/Avartar.png" alt="">
<img class="mg-host-face" src="" alt="">
</div>
<div class="layer mg-mic"><img src="../cut/btn-mic_on.png" alt="mic"></div>
<!-- ===== Overlay + popup-result ===== -->
<div class="layer sm-overlay"></div>
<div class="layer sm-popup">
<img src="../cut/popup-result.png" alt="สรุปผลภารกิจ">
</div>
<!-- ===== Content ใน popup (อ้างอิง Mockup/06.png) ===== -->
<div class="layer sm-content">
<div class="sm-ranks">
<div class="sm-rank is-1st" style="--bg:#ffd96b; --hair:#3a2210; --body:#e09f2a; --skin:#f5d6b3;">
<img class="pos" src="../cut/result-1st.png" alt="">
<div class="av">
<div class="portrait">
<div class="chibi">
<div class="ch-body"></div>
<div class="ch-head"></div>
<div class="ch-hair"></div>
</div>
</div>
<img class="frame" src="../cut/player-frame.png" alt="">
</div>
<div class="nm">JACKSON</div>
<div class="sc">100</div>
</div>
<div class="sm-rank is-2nd" style="--bg:#f5b9c8; --hair:#ec5fa0; --body:#ffffff; --skin:#f7d8c2;">
<img class="pos" src="../cut/result-2nd.png" alt="">
<div class="av">
<div class="portrait">
<div class="chibi">
<div class="ch-body"></div>
<div class="ch-head"></div>
<div class="ch-hair"></div>
</div>
</div>
<img class="frame" src="../cut/player-frame.png" alt="">
</div>
<div class="nm">MONE</div>
<div class="sc">100</div>
</div>
<div class="sm-rank is-3rd" style="--bg:#ff7b7b; --hair:#c8252a; --body:#9b1f23; --skin:#f5cba7;">
<img class="pos" src="../cut/result-3rd.png" alt="">
<div class="av">
<div class="portrait">
<div class="chibi">
<div class="ch-body"></div>
<div class="ch-head"></div>
<div class="ch-hair"></div>
</div>
</div>
<img class="frame" src="../cut/player-frame.png" alt="">
</div>
<div class="nm">RAINY</div>
<div class="sc">100</div>
</div>
<div class="sm-rank is-out" style="--bg:#7e84d1; --hair:#2a3580; --body:#3848a8; --skin:#f5d6b3;">
<img class="pos" src="../cut/result-txt-1.png" alt="">
<div class="av">
<div class="portrait">
<div class="chibi">
<div class="ch-body"></div>
<div class="ch-head"></div>
<div class="ch-hair"></div>
</div>
</div>
<img class="frame" src="../cut/player-frame.png" alt="">
<img class="stamp" src="../cut/result-Lose_stamp.png" alt="">
</div>
<div class="nm">MICKY</div>
<div class="sc">20</div>
</div>
<div class="sm-rank is-out" style="--bg:#85d28a; --hair:#216a2c; --body:#2f8a4a; --skin:#f5d6b3;">
<img class="pos" src="../cut/result-txt-2.png" alt="">
<div class="av">
<div class="portrait">
<div class="chibi">
<div class="ch-body"></div>
<div class="ch-head"></div>
<div class="ch-hair"></div>
</div>
</div>
<img class="frame" src="../cut/player-frame.png" alt="">
<img class="stamp" src="../cut/result-Lose_stamp.png" alt="">
</div>
<div class="nm">JAME</div>
<div class="sc">10</div>
</div>
</div>
<img class="sm-line sm-line-1 sm-line-above" src="../cut/popup-result-Line1.png" alt="">
<div class="sm-total">
คะแนนรวม (100+100+100+20+10) =<span class="num">330</span>
</div>
<img class="sm-line sm-line-1 sm-line-below" src="../cut/popup-result-Line1.png" alt="">
<!-- โซนล่าง: เกรด | เส้นกลาง | โบนัส (grid ตาม Mockup/06) -->
<div class="sm-bottom">
<section class="sm-col sm-col-grade">
<h3 class="head">ระดับความสำเร็จ</h3>
<p class="sm-grade" aria-label="เกรด B">B</p>
</section>
<div class="sm-vrule" aria-hidden="true">
<img class="sm-line-2" src="../cut/popup-result-Line2.png" alt="">
</div>
<section class="sm-col sm-col-bonus">
<div class="sm-bonus">
<div class="sm-bonus-left">
<h3 class="head">โบนัสพิเศษ</h3>
<img class="complete" src="../cut/mission-complete-select.png" alt="ภารกิจสำเร็จ">
</div>
<div class="sm-bonus-right">
<img class="bail-card" src="../../cut/10-Game-1-result/card-5.png" alt="Bail Coin">
</div>
</div>
</section>
</div>
</div>
<div class="layer sm-btn-done btn" id="smBtnDone">
<img src="../cut/btn-done.png" alt="รับหลักฐาน">
</div>
</div>
</div>
<script src="../assets/js/scale.js"></script>
<script>
document.getElementById('smBtnDone')?.addEventListener('click', () => {
alert('รับหลักฐาน (mockup)');
});
</script>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

@@ -0,0 +1,99 @@
/* =========================================================
Base CSS Minigame-2 "วิ่งหลบสิ่งกีดขวาง"
Base resolution : 1920 x 1080 (16:9)
========================================================= */
@font-face {
font-family: "NotoSansThai";
src: url("../../Fonts/NotoSansThai-Medium.ttf") format("truetype");
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "NotoSansThai";
src: url("../../Fonts/NotoSansThai-Bold.ttf") format("truetype");
font-weight: 700;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "NotoSansThai";
src: url("../../Fonts/NotoSansThai-Black.ttf") format("truetype");
font-weight: 900;
font-style: normal;
font-display: swap;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
background: #050813;
color: #ffffff;
font-family: "NotoSansThai", "Segoe UI", sans-serif;
overflow: hidden;
user-select: none;
-webkit-font-smoothing: antialiased;
}
img {
display: block;
pointer-events: none;
-webkit-user-drag: none;
}
.stage-wrap {
position: fixed;
inset: 0;
background: #050813;
overflow: hidden;
}
.stage {
position: absolute;
left: 0;
top: 0;
width: 1920px;
height: 1080px;
transform-origin: 0 0;
transform: scale(0.5);
}
.layer {
position: absolute;
}
.placeholder {
position: absolute;
border: 2px dashed rgba(255, 255, 255, 0.2);
border-radius: 10px;
color: rgba(255, 255, 255, 0.4);
font-size: 14px;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
background: rgba(255, 255, 255, 0.03);
pointer-events: none;
}
.btn {
cursor: pointer;
transition: transform 0.15s ease, filter 0.15s ease;
}
.btn:hover {
filter: brightness(1.18) drop-shadow(0 0 14px rgba(120, 220, 255, 0.55));
transform: translateY(-2px);
}
.btn:active {
transform: translateY(1px);
filter: brightness(0.95);
}
@@ -0,0 +1,181 @@
/* =========================================================
game-hud.css Shared HUD Minigame-2
• Top-center : SCORE bar (score.png + 5 players แนวนอน)
• Top-right : Host avatar + mic
• Bottom-right: JUMP button
========================================================= */
.mg-stage {
background: #1a1410;
}
.mg-bg {
left: 0;
top: 0;
width: 1920px;
height: 1080px;
z-index: 1;
}
.mg-bg img {
width: 100%;
height: 100%;
object-fit: cover;
}
/* ---------- SCORE bar แนวนอน (Mockup/0207) ---------- */
/* อ้างอิง Mockup/02: SCORE เริ่ม x≈50 · ผู้เล่น 5 คนห่าง center-to-center ≈155px */
.mg2-score-bar {
left: 50px;
top: 30px;
display: flex;
align-items: flex-start;
gap: 0;
z-index: 8;
}
.mg2-score-label {
width: 144px;
height: 71px;
flex: 0 0 144px;
margin: 0 1px 0 0;
transform: translateY(11px);
}
.mg2-players {
display: flex;
align-items: flex-start;
gap: 85px;
}
.mg2-player {
width: 70px;
text-align: center;
flex: 0 0 70px;
}
.mg2-player .nm {
font-family: "NotoSansThai", sans-serif;
font-weight: 700;
font-size: 11px;
color: #e8f4ff;
letter-spacing: 0.2px;
text-transform: uppercase;
white-space: nowrap;
margin-bottom: 4px;
line-height: 1;
}
.mg2-player .av {
position: relative;
width: 70px;
height: 70px;
margin: 0 auto 4px;
}
.mg2-player .av::after {
content: "";
position: absolute;
inset: 0;
background: url("../../cut/score-avartar.png") no-repeat center / contain;
pointer-events: none;
z-index: 2;
}
.mg2-player .av img {
position: absolute;
inset: 4px;
width: calc(100% - 8px);
height: calc(100% - 8px);
object-fit: cover;
border-radius: 6px;
z-index: 1;
}
.mg2-player .sc {
font-family: "NotoSansThai", sans-serif;
font-weight: 900;
font-size: 22px;
color: #ffffff;
line-height: 1;
text-shadow: 0 0 8px rgba(120, 220, 255, 0.6);
}
.mg2-player.is-zero .sc {
color: #ff8a8a;
text-shadow: 0 0 8px rgba(255, 90, 90, 0.55);
}
/* ---------- Host avatar + mic ---------- */
.mg-host {
left: 1729px;
top: 21px;
width: 201px;
height: 201px;
z-index: 8;
}
.mg-host-frame {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
z-index: 2;
pointer-events: none;
}
.mg-host-face {
position: absolute;
left: 49px;
top: 49px;
width: 104px;
height: 104px;
border-radius: 8px;
object-fit: cover;
z-index: 1;
}
.mg-host-face:not([src]),
.mg-host-face[src=""] {
display: none;
}
.mg-mic {
left: 1796px;
top: 205px;
width: 121px;
height: 121px;
z-index: 8;
}
.mg-mic img {
width: 100%;
height: 100%;
}
/* ---------- JUMP button (มุมขวาล่าง) ---------- */
.mg2-jump {
left: 1648px;
top: 818px;
width: 231px;
height: 231px;
z-index: 8;
}
.mg2-jump img {
width: 100%;
height: 100%;
filter: drop-shadow(0 0 18px rgba(255, 110, 220, 0.45));
}
.mg2-jump.btn:hover {
transform: translateY(-3px);
}
.mg2-jump.btn:hover img {
filter: drop-shadow(0 0 28px rgba(255, 110, 220, 0.75));
}
.mg2-jump.btn:active {
transform: translateY(1px);
}
@@ -0,0 +1,72 @@
/* =========================================================
howto.css หน้า 01 HOW TO PLAY (Minigame-2)
popup-Howto.png 1452×852
========================================================= */
.mg-overlay {
left: 0;
top: 0;
width: 1920px;
height: 1080px;
background: rgba(4, 6, 18, 0.45);
z-index: 9;
}
.howto-popup {
left: 50%;
top: 50px;
transform: translateX(-50%);
width: 1500px;
height: 880px;
z-index: 10;
}
.howto-popup img {
width: 100%;
height: 100%;
}
.howto-status {
left: 50%;
top: 808px;
transform: translateX(-50%);
font-family: "NotoSansThai", sans-serif;
font-weight: 700;
font-size: 22px;
color: #f067e8;
text-shadow:
0 0 10px rgba(240, 103, 232, 0.6),
0 0 22px rgba(237, 86, 224, 0.35);
letter-spacing: 0.5px;
text-align: center;
z-index: 13;
white-space: nowrap;
pointer-events: none;
}
.howto-btn {
left: 957px;
top: 885px;
transform: translate(-50%, -50%);
height: 120px;
width: auto;
z-index: 12;
}
.howto-btn img {
height: 100%;
width: auto;
filter: drop-shadow(0 0 18px rgba(120, 220, 255, 0.65));
}
.howto-btn.btn:hover {
transform: translate(-50%, calc(-50% - 3px));
}
.howto-btn.btn:hover img {
filter: drop-shadow(0 0 28px rgba(120, 220, 255, 0.95));
}
.howto-btn.btn:active {
transform: translate(-50%, calc(-50% + 2px));
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Some files were not shown because too many files have changed in this diff Show More