/* Fixed full-screen background layer, admin-configurable (solid /
 * gradient / image) — sits behind #otg-app, which goes transparent
 * via inline style in OTG_Shortcode::render() so this shows through.
 * A slightly oversized inset avoids a thin unblurred edge when the
 * "image" mode's blur filter softens/shrinks the visible bitmap. */
.otg-bg-layer {
	position: fixed; inset: -20px; z-index: -1;
	background-repeat: no-repeat; background-size: cover; background-position: center;
}

/* Admin-configurable outside-box text colour (see OTG_Background::
 * text_color()) -- deliberately separate from --otg-text (this
 * plugin's general ink colour, used throughout cards/buttons too), so
 * repainting it never touches card/button text. Declared at :root
 * (not #otg-app) so it also reaches the customize-panel overlay,
 * which game.js appends straight to <body>. The live value is also
 * written straight into :root via an inline <style> from
 * OTG_Background::layer_html(), so it's correct even before this
 * stylesheet finishes loading. Defaults to this plugin's existing ink
 * tone -- an untouched install looks exactly as before. */
:root {
	--otg-outside-text: #2c2416;
}

/* Othello (โอเทลโล่ / Reversi) — self-contained front-end styles.
 * Board/piece colors are CSS custom properties on #otg-app so the
 * in-game "customize" panel can override them live (and persist the
 * choice in localStorage) without touching this stylesheet. */

@font-face {
	font-family: 'Digital-Dismay';
	src: url('../fonts/Digital-Dismay.woff2') format('woff2');
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}

#otg-app,
#otg-app *:not(h1, h2, h3, h4, h5, p) {
	font-family: 'db', 'SF Thonburi', 'Sarabun', sans-serif !important;
	font-weight: normal !important;
}

#otg-app {
	--otg-light: #2f9457;
	--otg-dark: #2a8a51;
	--otg-board-border: #1c5a35;
	--otg-p0-a: #4a4a4e;
	--otg-p0-b: #101012;
	--otg-p1-a: #ffffff;
	--otg-p1-b: #d8d8d0;
	/* Piece fill + outline colours (set live by game.js's applyTheme());
	 * p0 = ฝ่ายดำ (seat 0, moves first), p1 = ฝ่ายขาว (seat 1). */
	--otg-p0-fill: #1b1b1d;
	--otg-p0-line: #000000;
	--otg-p1-fill: #f7f7f2;
	--otg-p1-line: #b9b9b0;
	--otg-accent: #c8912f;
	--otg-bg: #faf6ef;
	--otg-card: #ffffff;
	--otg-text: #2c2416;
	--otg-muted: #7a6f5c;
	--otg-danger: #c0392b;
	--otg-success: #2e7d32;
	--otg-radius: 14px;
	--otg-shadow: 0 4px 18px rgba(60, 40, 10, 0.12);

	box-sizing: border-box;
	max-width: 520px;
	margin: 0 auto;
	padding: 16px;
	color: var(--otg-text);
	background: var(--otg-bg);
	border-radius: 18px;
	/* display:flex + .otg-back's own "order" (below) is what moves the
	 * back button to the bottom of the pre-game setup screens
	 * (2026-09-27) — #otg-app's own direct children (back button,
	 * optional header, .otg-screen) simply stack top-to-bottom same as
	 * plain block flow, so this is a no-op for every other screen. */
	display: flex;
	flex-direction: column;
}
#otg-app *, #otg-app *::before, #otg-app *::after { box-sizing: border-box; }

/* Outside-box text colour, not the fixed muted gray: sits directly on
 * the page background, no card behind it. */
#otg-app .otg-loading { text-align: center; padding: 40px 0; color: var(--otg-outside-text, var(--otg-muted)); }

/* ---------- Layout shell ---------- */
#otg-app .otg-screen { display: none; }
#otg-app .otg-screen.active { display: block; animation: otg-fade-in .18s ease; }
@keyframes otg-fade-in { from { opacity: 0; transform: translateY(4px);} to { opacity: 1; transform: none; } }
/* Set by shell() (game.js) whenever a render is just a same-screen data
 * refresh (e.g. after each move, including every bot move) rather than
 * an actual screen change — without this, the whole board would replay
 * the fade-in/slide-up above on every single move, reading as a stutter
 * or a full page refresh. Same specificity as .otg-screen.active so it
 * must come after it in source order to win; the compound selector
 * below also wins outright regardless of order. */
#otg-app .otg-screen.active.otg-no-anim { animation: none; }

#otg-app .otg-logo { text-align: center; margin-bottom: 6px; }
#otg-app .otg-logo img { width: 220px; max-width: 80%; height: auto; display: inline-block; }
/* Outside-box text colour, not the fixed ink/muted tones: the home
 * header, subtitle, back link and "กลับหน้าหลัก" link all sit directly
 * on the page background, no card behind any of them. */
#otg-app .otg-header { text-align: center; margin-bottom: 18px; }
#otg-app .otg-header h2 { font-size: 26px; margin: 0 0 4px; color: var(--otg-outside-text, var(--otg-text)); }
#otg-app .otg-header p { margin: 0; color: var(--otg-outside-text, var(--otg-muted)); font-size: 14px; }
#otg-app .otg-home-link {
	display: block;
	text-align: center;
	margin-top: 18px;
	padding: 12px 0;
	color: var(--otg-outside-text, var(--otg-muted));
	font-size: 14px;
	text-decoration: none;
	border-top: 1px solid rgba(0,0,0,.08);
}

/* Moved to the bottom of the pre-game setup screens (vs-computer,
 * pass-play, online choice/create/join) and restyled as a snug white
 * pill, per user request (2026-09-27) — width fits its own text
 * rather than stretching, so it needs an explicit align-self since
 * its flex-container parent (#otg-app) would otherwise stretch it
 * full width. Fixed ink text (not the outside-text var) since it now
 * has its own white background to sit on. */
#otg-app .otg-back {
	order: 2;
	align-self: flex-start;
	display: inline-flex; align-items: center; gap: 6px;
	background: #ffffff; border: 1.5px solid #e7ddc9; color: var(--otg-text);
	font-size: 14px; font-weight: 600; padding: 10px 18px; border-radius: 999px;
	margin-top: 16px; margin-bottom: 0; cursor: pointer;
	box-shadow: var(--otg-shadow);
}
#otg-app .otg-back:hover { background: #faf6ef; }

/* ---------- Mode select cards ---------- */
#otg-app .otg-mode-list { display: flex; flex-direction: column; gap: 12px; }
#otg-app .otg-mode-card {
	display: flex; align-items: center; gap: 14px;
	background: var(--otg-card); border: 1.5px solid #e7ddc9; border-radius: var(--otg-radius);
	padding: 11px 16px; cursor: pointer; text-align: left; width: 100%;
	box-shadow: var(--otg-shadow); transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
	font: inherit; color: inherit;
}
#otg-app .otg-mode-card:hover { transform: translateY(-2px); box-shadow: 0 8px 22px rgba(60,40,10,.16); border-color: var(--otg-accent); }
#otg-app .otg-mode-card .otg-mode-icon {
	width: 46px; height: 46px; border-radius: 50%; flex: none;
	display: flex; align-items: center; justify-content: center;
	background: #ffffff; color: var(--otg-accent);
	border: 1px solid #eee1c8; box-shadow: 0 2px 6px rgba(60,40,10,.10);
}
#otg-app .otg-mode-card .otg-mode-icon svg { width: 24px; height: 24px; }

/* Mode-select icons (2026-09-30): white line icon on a diagonal
 * (top-left -> bottom-right) gradient disc, same in all card games.
 * vs computer = blue-green, same device = yellow-orange, online = pink-purple. */
#otg-app .otg-mode-card .otg-mode-icon.otg-mode-icon--computer, #otg-app .otg-mode-card .otg-mode-icon.otg-mode-icon--phone, #otg-app .otg-mode-card .otg-mode-icon.otg-mode-icon--globe { color: #ffffff; border-color: transparent; }
#otg-app .otg-mode-card .otg-mode-icon.otg-mode-icon--computer { background: linear-gradient(135deg, #29b6f6 0%, #12c98b 100%); box-shadow: 0 3px 8px rgba(18,201,139,.35); }
#otg-app .otg-mode-card .otg-mode-icon.otg-mode-icon--phone { background: linear-gradient(135deg, #ffd23f 0%, #ff8a1f 100%); box-shadow: 0 3px 8px rgba(255,138,31,.35); }
#otg-app .otg-mode-card .otg-mode-icon.otg-mode-icon--globe { background: linear-gradient(135deg, #ff5fa2 0%, #8b5cf6 100%); box-shadow: 0 3px 8px rgba(139,92,246,.35); }
#otg-app .otg-mode-card strong { display: block; font-size: 16px; }
#otg-app .otg-mode-card span { display: block; font-size: 13px; color: var(--otg-muted); margin-top: 2px; }

/* ---------- Forms ---------- */
#otg-app .otg-field { margin-bottom: 16px; }
/* Outside-box text colour: these labels ("ชื่อเล่นของคุณ",
 * "เลือกระดับความยากของคอมพิวเตอร์", room code, etc.) sit directly on
 * the page background, not inside a white card. */
#otg-app .otg-field label { display: block; font-size: 14px; font-weight: 600; margin-bottom: 6px; color: var(--otg-outside-text, var(--otg-text)); }
#otg-app .otg-field input[type="text"] {
	width: 100%; padding: 11px 12px; border-radius: 10px; border: 1px solid #d9cdb2;
	font-size: 15px; background: #fff; color: var(--otg-text);
}
#otg-app .otg-field input[type="text"]:focus { outline: 2px solid var(--otg-accent); outline-offset: 1px; }
#otg-app .otg-field.otg-code-field input { text-transform: uppercase; letter-spacing: 3px; text-align: center; font-weight: 700; }

#otg-app .otg-btn {
	display: inline-flex; align-items: center; justify-content: center; gap: 8px;
	width: 100%; padding: 10px 16px; border-radius: 10px; border: none;
	background: var(--otg-accent); color: #fff; font-size: 15px; font-weight: 700;
	cursor: pointer; text-decoration: none; transition: filter .12s ease, transform .12s ease;
}
#otg-app .otg-btn:hover:not(:disabled) { filter: brightness(1.06); transform: translateY(-1px); }
#otg-app .otg-btn:disabled { opacity: .5; cursor: not-allowed; }
#otg-app .otg-btn.otg-btn-secondary { background: #fff; color: var(--otg-text); border: 1.5px solid #e7ddc9; }
#otg-app .otg-btn.otg-btn-outline { background: #fff; border: 1px solid var(--otg-accent); color: var(--otg-accent); }
/* "ออก" (leave-table) button — same outline shape as .otg-btn-outline
 * above, but with black-ish text instead of the gold accent colour
 * (user-requested 2026-09-26), without touching .otg-btn-outline's
 * other uses (customize, back-to-main-site, lobby-add-bot). */
#otg-app .otg-btn.otg-btn-outline-dark { color: var(--otg-text); border-color: #e7ddc9; }
/* "ขอเสมอ" (offer-draw) button — cream background, black-ish text
 * (user-requested 2026-09-26); reuses the same cream/near-black
 * tokens as the page background and body text elsewhere. */
#otg-app .otg-btn.otg-btn-cream { background: var(--otg-bg); color: var(--otg-text); border: 1px solid #e7ddc9; }
#otg-app .otg-btn.otg-btn-danger { background: var(--otg-danger); }
#otg-app .otg-btn.otg-btn-small { width: auto; padding: 8px 14px; font-size: 13px; }
#otg-app .otg-btn-row { display: flex; gap: 10px; margin-top: 10px; }
#otg-app .otg-btn-row .otg-btn { flex: 1; }

/* ---------- Difficulty picker ---------- */
#otg-app .otg-difficulty-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 18px; }
#otg-app .otg-difficulty-option {
	display: block; width: 100%; text-align: left; cursor: pointer;
	border: 2px solid #e7ddc9; border-radius: 12px; padding: 9px 14px; background: #fff;
	transition: border-color .12s ease, background .12s ease;
}
#otg-app .otg-difficulty-option strong { display: block; font-size: 15px; }
#otg-app .otg-difficulty-option span { display: block; font-size: 12.5px; color: var(--otg-muted); margin-top: 2px; }
#otg-app .otg-difficulty-option.selected { border-color: var(--otg-accent); background: #fff8ea; }

/* ---------- Lobby / room code ---------- */
#otg-app .otg-lobby { text-align: center; }
#otg-app .otg-room-code {
	font-size: 40px; font-weight: 800; letter-spacing: 8px; color: var(--otg-accent);
	background: #fff8ea; border: 2px dashed var(--otg-accent); border-radius: 12px;
	padding: 16px 10px; margin: 16px 0; user-select: all;
}
/* Outside-box text colour, not the fixed muted gray: .otg-lobby has no
 * card background of its own. */
#otg-app .otg-lobby p { color: var(--otg-outside-text, var(--otg-muted)); font-size: 14px; }
#otg-app .otg-lobby-spinner {
	width: 34px; height: 34px; margin: 18px auto; border-radius: 50%;
	border: 4px solid #e7ddc9; border-top-color: var(--otg-accent);
	animation: otg-spin 0.9s linear infinite;
}
@keyframes otg-spin { to { transform: rotate(360deg); } }

/* ---------- Table screen: player bars + timer ---------- */
#otg-app .otg-table-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; }
#otg-app .otg-player-bar {
	flex: 1; display: flex; align-items: center; gap: 10px;
	background: var(--otg-card); border-radius: 12px; padding: 10px 12px;
	border: 2px solid transparent; box-shadow: var(--otg-shadow);
}
#otg-app .otg-player-bar.active-turn { border-color: var(--otg-accent); }
#otg-app .otg-player-avatar {
	width: 30px; height: 30px; border-radius: 50%; flex: none; border: 2px solid var(--otg-board-border);
}
#otg-app .otg-player-avatar.p0 { background: linear-gradient(160deg, var(--otg-p0-a), var(--otg-p0-b)); }
#otg-app .otg-player-avatar.p1 { background: linear-gradient(160deg, var(--otg-p1-a), var(--otg-p1-b)); }
#otg-app .otg-player-info { min-width: 0; }
#otg-app .otg-player-info .otg-player-name { font-size: 13px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 110px; }
#otg-app .otg-player-info .otg-player-pieces { font-size: 11.5px; color: var(--otg-muted); }

#otg-app .otg-status-line {
	text-align: center; font-size: 14px; font-weight: 600; margin: 6px 0 10px;
	padding: 8px; border-radius: 10px; background: #fff8ea; color: var(--otg-text);
}
#otg-app .otg-status-line.otg-warn { background: #fdecea; color: var(--otg-danger); }

#otg-app .otg-timer-digital {
	flex: none;
	font-family: 'Digital-Dismay', monospace !important;
	background: #fff;
	color: var(--otg-danger);
	font-size: 18px;
	letter-spacing: 1px;
	font-variant-numeric: tabular-nums;
	border: 1.5px solid #e7ddc9;
	border-radius: 12px;
	padding: 8px 10px;
	min-width: 44px;
	text-align: center;
}
#otg-app .otg-timer-digital.is-low { font-weight: 800; }

/* ---------- Board ---------- */
#otg-app .otg-board-wrap { display: flex; justify-content: center; margin-bottom: 12px; }
#otg-app .otg-board {
	background: var(--otg-dark);
	display: grid; grid-template-columns: repeat(8, 1fr); grid-template-rows: repeat(8, 1fr);
	width: min(100%, 440px); aspect-ratio: 1 / 1;
	border: 6px solid var(--otg-board-border); border-radius: 8px; overflow: hidden;
	box-shadow: var(--otg-shadow);
}
#otg-app .otg-square { position: relative; display: flex; align-items: center; justify-content: center; }
#otg-app .otg-square.light { background: var(--otg-light); }
#otg-app .otg-square.dark { background: var(--otg-dark); }
/* Thin grid lines between squares, like a real Othello board. */
#otg-app .otg-square { box-shadow: inset 0 0 0 .5px rgba(0, 0, 0, .38); }
/* A legal placement: a soft dot (the dot grows slightly when tapped/hovered). */
#otg-app .otg-square.dest-hint::before {
	content: ""; position: absolute; width: 24%; height: 24%; border-radius: 50%;
	background: rgba(0, 0, 0, .3); pointer-events: none; transition: transform .12s ease, background .12s ease;
}
#otg-app .otg-square.dest-hint:hover::before { transform: scale(1.35); background: rgba(255, 214, 64, .85); }
/* The disc that was just placed gets a small gold marker. */
#otg-app .otg-square.last-move::after {
	content: ""; position: absolute; width: 14%; height: 14%; border-radius: 50%;
	background: #ffd540; box-shadow: 0 0 0 1.5px rgba(0,0,0,.55); top: 8%; left: 8%; pointer-events: none; z-index: 3;
}
#otg-app .otg-square.otg-clickable { cursor: pointer; }

/* ---------- Discs ----------
 * A disc has two faces, black (seat 0) and white (seat 1), on a rotating
 * .otg-disc. p0 shows the black face; p1 turns it 180deg. A flip is a
 * keyframe animation between the two orientations (delays are set inline by
 * game.js so the turn ripples outward from the placed disc). */
#otg-app .otg-piece {
	width: 84%; height: 84%; position: relative;
	perspective: 420px;
	filter: drop-shadow(0 2px 2px rgba(0,0,0,.45));
	pointer-events: none;
}
#otg-app .otg-disc {
	position: relative; width: 100%; height: 100%;
	transform-style: preserve-3d;
}
#otg-app .otg-piece.p0 .otg-disc { transform: rotateY(0deg); }
#otg-app .otg-piece.p1 .otg-disc { transform: rotateY(180deg); }
#otg-app .otg-face {
	position: absolute; inset: 0; border-radius: 50%; overflow: hidden;
	backface-visibility: hidden; -webkit-backface-visibility: hidden;
}
#otg-app .otg-face.f0 {
	background: radial-gradient(circle at 34% 30%, var(--otg-p0-a), var(--otg-p0-fill) 62%);
	box-shadow: inset 0 0 0 1.5px var(--otg-p0-line), inset 0 -3px 5px rgba(0,0,0,.35), inset 0 2px 3px rgba(255,255,255,.18);
}
#otg-app .otg-face.f1 {
	background: radial-gradient(circle at 34% 30%, #ffffff, var(--otg-p1-fill) 66%);
	box-shadow: inset 0 0 0 1.5px var(--otg-p1-line), inset 0 -3px 5px rgba(0,0,0,.2), inset 0 2px 3px rgba(255,255,255,.5);
	transform: rotateY(180deg);
}
/* Uploaded 1:1 disc images fill the face unscaled. */
#otg-app img.otg-pc-img { width: 100%; height: 100%; object-fit: cover; display: block; -webkit-user-drag: none; user-select: none; }
#otg-app .otg-piece.otg-flipping.f-to-0 .otg-disc { animation: otg-flip-to-0 .55s ease-in-out both; }
#otg-app .otg-piece.otg-flipping.f-to-1 .otg-disc { animation: otg-flip-to-1 .55s ease-in-out both; }
@keyframes otg-flip-to-0 {
	0%   { transform: rotateY(180deg) scale(1); }
	50%  { transform: rotateY(90deg) scale(1.14); }
	100% { transform: rotateY(0deg) scale(1); }
}
@keyframes otg-flip-to-1 {
	0%   { transform: rotateY(0deg) scale(1); }
	50%  { transform: rotateY(90deg) scale(1.14); }
	100% { transform: rotateY(180deg) scale(1); }
}
#otg-app .otg-piece.otg-just-moved { animation: otg-pop .28s ease both; }
@keyframes otg-pop { 0% { transform: scale(.4); opacity: .4; } 60% { transform: scale(1.12); opacity: 1; } 100% { transform: scale(1); } }
#otg-app .otg-result-score { font-size: 17px; margin: 4px 0 8px; font-weight: 700; }

#otg-app .otg-table-actions { display: flex; gap: 8px; margin-top: 6px; }
#otg-app .otg-table-actions .otg-btn { flex: 1; }

/* ---------- Game over ----------
 * Shown as a centered overlay on top of the final board position
 * (see game.js's shell()/gameOverOverlayHtml()) rather than a
 * separate full-screen result page, so it reads as "the game just
 * ended right here" -- including for the "no legal moves" forfeit
 * case, which used to be easy to miss as just another screen. */
#otg-app .otg-gameover-overlay { align-items: center; padding: 20px; }
#otg-app .otg-gameover-card {
	border-radius: 18px;
	box-shadow: 0 12px 40px rgba(0, 0, 0, .3);
	text-align: center;
	max-width: 380px;
}
#otg-app .otg-gameover-card .otg-result-title { font-size: 24px; font-weight: 800; margin: 6px 0; }
#otg-app .otg-gameover-card .otg-result-reason { color: var(--otg-muted); margin-bottom: 14px; }
#otg-app .otg-gameover-card .otg-result-stats {
	background: rgba(0, 0, 0, .05); border-radius: 10px; padding: 10px 12px; margin-bottom: 16px;
}
#otg-app .otg-gameover-card .otg-result-stats p { margin: 4px 0; font-size: 13px; color: var(--otg-text); }
#otg-app .otg-gameover-card .otg-btn { margin-bottom: 10px; }
#otg-app .otg-gameover-card .otg-btn-row { margin-top: 0; }

/* ---------- Draw-offer banner -----------
 * Replaces the normal customize/resign/leave/offer-draw row on the
 * table screen while a draw offer is pending -- an immediate,
 * impossible-to-miss decision point rather than a small button
 * among several others. */
#otg-app .otg-draw-banner {
	background: #fff8e1; border: 1.5px solid var(--otg-accent); border-radius: 12px;
	padding: 12px 14px; margin-top: 6px; text-align: center; font-size: 14px; color: var(--otg-text);
}
#otg-app .otg-draw-banner p { margin: 0 0 10px; font-weight: 700; }
#otg-app .otg-draw-banner .otg-btn-row { margin-top: 0; }

/* ---------- Customize panel ----------
 * Shown as a centered modal (like the game-over card), not a bottom
 * sheet -- was previously align-items:flex-end (anchored to the bottom
 * edge of the screen), which the user reported for both this panel and
 * the game-over overlay (2026-09-26): the two share this same base
 * .otg-overlay rule, and its flex-end here was overriding the game-over
 * overlay's own centered rule further up the file (equal specificity,
 * later rule wins) as well as keeping this panel pinned low itself.
 * Centering here fixes both at once. */
#otg-app .otg-overlay {
	position: fixed; inset: 0; background: rgba(20, 14, 4, .5);
	display: flex; align-items: center; justify-content: center; z-index: 9999; padding: 20px;
}
#otg-app .otg-overlay.hidden { display: none; }
#otg-app .otg-panel {
	background: var(--otg-bg); width: 100%; max-width: 520px; border-radius: 18px;
	padding: 20px; max-height: 86vh; overflow-y: auto; box-shadow: 0 12px 40px rgba(0,0,0,.3);
}
#otg-app .otg-panel-title { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
#otg-app .otg-panel-title h2 { font-size: 18px; margin: 0; }
#otg-app .otg-panel-title button { background: none; border: none; font-size: 20px; cursor: pointer; color: var(--otg-muted); }
#otg-app .otg-swatch-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
#otg-app .otg-swatch-row label { font-size: 14px; font-weight: 600; }
#otg-app .otg-swatch-row input[type="color"] {
	width: 44px; height: 34px; border: none; border-radius: 8px; padding: 0; background: none; cursor: pointer;
}
#otg-app .otg-preset-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 10px 0 18px; }
#otg-app .otg-preset-swatch {
	height: 40px; border-radius: 8px; cursor: pointer; border: 2px solid transparent;
	background-size: cover;
}
#otg-app .otg-preset-swatch.selected { border-color: var(--otg-text); }
#otg-app .otg-panel h3 { font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--otg-muted); margin: 16px 0 8px; }
#otg-app .otg-panel .otg-btn-ok { width: 100%; margin-top: 14px; }

/* ---------- Responsive ---------- */
@media (max-width: 380px) {
	#otg-app { padding: 12px; }
	#otg-app .otg-room-code { font-size: 30px; letter-spacing: 5px; }
	#otg-app .otg-player-info .otg-player-name { max-width: 78px; }
}
/* On mobile (below the desktop breakpoint further down), no left/right
 * padding on the outer container -- user-requested 2026-09-26. Only the
 * horizontal padding is dropped; top/bottom padding (16px normally, 12px
 * on very small phones per the rule above) is untouched, and this comes
 * after that rule so it still wins down to the smallest phone widths too. */
@media (max-width: 1023px) {
	#otg-app { padding-left: 0; padding-right: 0; }
}

/* ---------- Desktop (>=1024px): wider table + larger board/text ----------
 * Requested 2026-09-25: on screens wide enough to be "a computer" (not a
 * tablet/phone), let the table grow from the mobile 520px cap to 1000px
 * and scale up the board and key text to fill that space. Everything
 * below the breakpoint (all phones, and portrait tablets up to 1023px)
 * is completely untouched. */
@media (min-width: 1024px) {
	#otg-app { max-width: 900px; padding: 22px; }
	#otg-app .otg-logo img { width: 260px; }
	#otg-app .otg-header h2 { font-size: 34px; }
	#otg-app .otg-header p { font-size: 16px; }
	#otg-app .otg-mode-card { padding: 14px 20px; }
	#otg-app .otg-mode-card .otg-mode-icon { width: 56px; height: 56px; }
	#otg-app .otg-mode-card .otg-mode-icon svg { width: 28px; height: 28px; }
	#otg-app .otg-mode-card strong { font-size: 18px; }
	#otg-app .otg-mode-card span { font-size: 14px; }
	#otg-app .otg-room-code { font-size: 56px; letter-spacing: 10px; padding: 22px 14px; }
	#otg-app .otg-player-bar { padding: 14px 16px; }
	#otg-app .otg-player-avatar { width: 40px; height: 40px; }
	#otg-app .otg-player-info .otg-player-name { font-size: 15px; max-width: 160px; }
	#otg-app .otg-player-info .otg-player-pieces { font-size: 13px; }
	#otg-app .otg-status-line { font-size: 16px; padding: 10px; }
	#otg-app .otg-timer-digital { font-size: 22px; padding: 10px 12px; }
	/* Board squares are already % of .otg-board, and pieces are 78% of a
	 * square, so simply raising this cap (was 440px) scales the whole
	 * board — squares, pieces, king glyph — proportionally. */
	#otg-app .otg-board { width: min(100%, 560px); }
	#otg-app .otg-table-top,
	#otg-app .otg-status-line,
	#otg-app .otg-table-actions,
	#otg-app .otg-gameover-card {
		max-width: 560px;
		margin-left: auto;
		margin-right: auto;
	}
	#otg-app .otg-btn { font-size: 17px; padding: 11px 18px; }
	#otg-app .otg-gameover .otg-result-title { font-size: 30px; }
	#otg-app .otg-panel { max-width: 580px; }
}

/* ---------- Shared room chat (2026-09-28 request, ported from the
 * phom-sib-game/atari-go-game/uno-game/domino-game sibling plugins) ---------- */
/* .otg-chat-root sits OUTSIDE #otg-app (a sibling — see game.js) so its
 * own <input> never gets torn down by #otg-app's frequent full innerHTML
 * rebuilds. Being outside #otg-app also means it does NOT inherit that
 * element's CSS custom properties or its own font-family rule above, so
 * everything here uses fixed colors/fonts instead — always legible
 * regardless of the admin's theme. */
.otg-chat-root, .otg-chat-root * {
	font-family: 'db', 'SF Thonburi', 'Sarabun', 'Noto Sans Thai', sans-serif;
	box-sizing: border-box;
}
.otg-chat-root { position: fixed; right: 16px; bottom: 16px; z-index: 55; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
.otg-chat-fab {
	/* Gradient speech-bubble fab with 3 white dots inside, kept still, with an orange glow burst every 5s (see
	 * glow burst via the chat-glow animation
	 * below. */
	position: relative; width: 56px; height: 52px; border: none; cursor: pointer;
	background: transparent; padding: 0; display: flex; align-items: flex-start; justify-content: center;
	isolation: isolate; overflow: visible;
}
.otg-chat-fab-icon { position: relative; z-index: 1; display: block; width: 52px; height: 47px; }
.otg-chat-fab-icon svg { width: 100%; height: 100%; display: block; }
/* Orange glow burst instead of the old up/down bob (no layout/transform
 * jitter on the button itself): every 5s a soft orange light spreads out
 * from behind the bubble and fades, then stays still until the next
 * burst. Only opacity/transform are animated, so it stays on the
 * compositor and never stutters. */
.otg-chat-fab::before,
.otg-chat-fab::after {
	content: ""; position: absolute; left: 50%; top: 45%; width: 56px; height: 56px;
	margin: -28px 0 0 -28px; border-radius: 50%; pointer-events: none; z-index: 0;
	background: radial-gradient(circle, rgba(255,150,30,.85) 0%, rgba(255,122,0,.45) 40%, rgba(255,122,0,0) 70%);
	opacity: 0; transform: scale(.7); will-change: transform, opacity;
	animation: otg-chat-glow 5s ease-out infinite;
}
.otg-chat-fab::after { animation-delay: .35s; }
@keyframes otg-chat-glow {
	0%   { opacity: 0;   transform: scale(.7); }
	6%   { opacity: .9;  transform: scale(1.1); }
	26%  { opacity: 0;   transform: scale(2.8); }
	100% { opacity: 0;   transform: scale(2.8); }
}
@media (prefers-reduced-motion: reduce) {
	.otg-chat-fab::before, .otg-chat-fab::after { animation: none; opacity: 0; }
}
.otg-chat-badge {
	position: absolute; top: -2px; right: 0; min-width: 18px; height: 18px; padding: 0 4px;
	background: #ff5a36; color: #000; font-size: 11px; font-weight: 800; line-height: 18px;
	border-radius: 999px; text-align: center; box-shadow: 0 0 0 2px #fff;
}
.otg-chat-panel {
	width: 300px; max-width: calc(100vw - 32px); height: 380px; max-height: 60vh;
	background: #fff; color: #2c2416; border-radius: 14px; box-shadow: 0 8px 30px rgba(0,0,0,.35);
	display: flex; flex-direction: column; overflow: hidden;
}
.otg-chat-header {
	display: flex; align-items: center; justify-content: space-between; padding: 10px 14px;
	background: #2c2416; color: #fff; font-weight: 700; font-size: 14px;
}
/* Down-pointing triangle "▼" — reads as "collapse" rather than "close". */
.otg-chat-close { background: none; border: none; color: #fff; font-size: 12px; line-height: 1; cursor: pointer; padding: 0 4px; }
.otg-chat-messages { flex: 1; overflow-y: auto; padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; }
.otg-chat-empty { color: #9a8f7a; font-size: 13px; text-align: center; margin-top: 20px; }
.otg-chat-msg { max-width: 82%; background: #f3ede0; border-radius: 10px; padding: 6px 10px; align-self: flex-start; }
.otg-chat-msg-mine { background: #fff1c4; align-self: flex-end; }
.otg-chat-msg-name { font-size: 11px; font-weight: 800; color: #7a6f5c; margin-bottom: 2px; }
.otg-chat-msg-text { font-size: 14px; word-break: break-word; white-space: pre-wrap; }
.otg-chat-form { display: flex; gap: 6px; padding: 8px; border-top: 1px solid #eee2cc; }
.otg-chat-input {
	/* font-size MUST be >= 16px — below that, iOS Safari (and some
	 * Android browsers) auto-zoom the whole page in the moment this
	 * field gets focus. */
	flex: 1; min-width: 0; border: 1px solid #e0d6bd; border-radius: 999px; padding: 8px 12px; font-size: 16px; color: #2c2416; background: #fff;
}
.otg-chat-input:focus { outline: none; border-color: #c7bb9e; }
.otg-chat-send {
	border: none; border-radius: 999px; padding: 8px 16px; background: #ffb600; color: #fff; font-weight: normal; font-size: 14px; cursor: pointer;
}
.otg-chat-send:hover { background: linear-gradient(135deg, #ffd400, #ff7a00); }
.otg-chat-send:active { transform: scale(.97); }
@media (max-width: 1023px) {
	.otg-chat-root { right: 12px; bottom: 12px; }
	.otg-chat-panel { width: calc(100vw - 24px); height: 50vh; }
}

/* ขอเสมอ — teal/blue gradient */
#otg-app .otg-btn.otg-btn-teal { background: linear-gradient(135deg, #2196f3, #1de9b6); color: #04262b; border: none; }

/* v1.4.3 - customize panel always fits the screen (no scrollbar) */
#otg-app .otg-panel {
	max-height: calc(100dvh - 40px); overflow: hidden; padding: clamp(10px, 2.2vh, 20px);
	display: flex; flex-direction: column;
}
#otg-app .otg-panel-title { margin-bottom: clamp(4px, 1.2vh, 14px); }
#otg-app .otg-panel h3 { margin: clamp(4px, 1.2vh, 16px) 0 clamp(3px, .8vh, 8px); }
#otg-app .otg-panel .otg-preset-grid { margin: clamp(4px, 1vh, 10px) 0 clamp(6px, 1.4vh, 18px); }
#otg-app .otg-panel .otg-preset-swatch { height: clamp(28px, 5vh, 40px); }
#otg-app .otg-panel .otg-swatch-row { margin-bottom: clamp(4px, 1.2vh, 14px); }
#otg-app .otg-panel .otg-btn { padding-top: clamp(6px, 1.2vh, 10px); padding-bottom: clamp(6px, 1.2vh, 10px); margin-bottom: clamp(4px, .8vh, 8px); }
#otg-app .otg-panel .otg-btn-ok { margin-top: clamp(4px, 1vh, 14px); }

/* Whose turn: pulsing orange glow on the player card */
#otg-app .otg-player-bar.active-turn {
	border-color: #ff8a00;
	animation: otg-turn-glow 1.1s ease-in-out infinite;
}
@keyframes otg-turn-glow {
	0%, 100% { box-shadow: 0 0 0 0 rgba(255,138,0,.55), 0 0 6px 0 rgba(255,138,0,.35); }
	50% { box-shadow: 0 0 0 5px rgba(255,138,0,0), 0 0 16px 3px rgba(255,138,0,.6); }
}
/* ยอมแพ้ - orange-red gradient */
#otg-app .otg-btn.otg-btn-danger { background: linear-gradient(135deg, #ff8a3d, #e53935); color: #fff; }

/* ---------- Home button row: three equal, text-fitting buttons (2026-10-02) ---------- */
#otg-app .otg-home-row { gap: 8px; }
#otg-app .otg-home-row .otg-btn { flex: 1 1 0; min-width: 0; white-space: nowrap; padding: 10px 6px; font-size: 15px; }
@media (max-width: 480px) {
	#otg-app .otg-home-row { gap: 6px; }
	#otg-app .otg-home-row .otg-btn { font-size: 13px; padding: 10px 4px; }
}

/* ---------- Rules pop-up (2026-10-02) ----------
 * White rounded box centred on a blurred grey backdrop. 20px gutter on every
 * side (so it keeps a 20px margin on phones). Description text is forced to
 * SF Thonburi on desktop and mobile. */
#otg-app .otg-rules-overlay {
	position: fixed; inset: 0; z-index: 99999;
	display: flex; align-items: center; justify-content: center;
	padding: 20px; box-sizing: border-box;
	background: rgba(110, 110, 110, .5);
	-webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
#otg-app .otg-rules-panel {
	box-sizing: border-box; width: 100%; max-width: 760px;
	max-height: calc(100vh - 40px); max-height: calc(100dvh - 40px);
	overflow-y: auto; -webkit-overflow-scrolling: touch;
	background: #ffffff; color: #2c2416;
	border-radius: 22px; padding: 22px 24px 18px;
	box-shadow: 0 20px 60px rgba(0, 0, 0, .35);
	text-align: left;
}
#otg-app .otg-rules-overlay,
#otg-app .otg-rules-overlay * {
	font-family: 'SF Thonburi', 'Thonburi', 'db', 'Sarabun', sans-serif !important;
}
#otg-app .otg-rules-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
#otg-app .otg-rules-head h3 { margin: 0; font-size: 24px; color: #2c2416; }
#otg-app .otg-rules-x {
	flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%; border: none; cursor: pointer;
	background: #f0f0f0; color: #2c2416; font-size: 22px; line-height: 1; padding: 0; box-shadow: none;
}
#otg-app .otg-rules-x:hover { background: #e2e2e2; }
#otg-app .otg-rules-row {
	display: flex; justify-content: space-between; align-items: baseline; gap: 18px;
	padding: 9px 0; border-bottom: 1px solid #dcdcdc; font-size: 15px; line-height: 1.5; color: #2c2416;
}
#otg-app .otg-rules-t { flex: 0 0 auto; white-space: nowrap; color: #2c2416; }
#otg-app .otg-rules-d { min-width: 0; text-align: right; color: #2c2416; }
#otg-app .otg-rules-close {
	display: block; margin: 16px auto 2px; padding: 10px 36px ; border: none; border-radius: 999px ;
	background: #111; color: #fff; font-size: 15px; cursor: pointer; box-shadow: none;
}
@media (max-width: 480px) {
	#otg-app .otg-rules-panel { padding: 18px 16px 14px; border-radius: 18px; }
	#otg-app .otg-rules-row { gap: 12px; font-size: 13.5px; }
}

/* ---------- Sound toggle + fireworks (2026-10-02) ---------- */
#otg-app .otg-sound-btn {
	display: inline-flex; align-items: center; justify-content: center;
	width: 34px; height: 34px; padding: 0; margin: 0; flex: 0 0 auto;
	background: transparent !important; border: 0 !important; box-shadow: none !important;
	color: #fff; opacity: .6; cursor: pointer; border-radius: 50%;
	-webkit-tap-highlight-color: transparent;
}
#otg-app .otg-sound-btn.otg-sound-on { opacity: 1; }
#otg-app .otg-sound-btn:hover { opacity: 1; }
#otg-app .otg-sound-btn .otg-sound-icon { display: block; width: 22px; height: 22px; pointer-events: none; }
.otg-fireworks { position: fixed; left: 0; top: 0; width: 100vw; height: 100vh; pointer-events: none; z-index: 100000; }
/* Table action row (sound · offer draw · resign · leave): exactly as wide as
 * the board above it (440px, 560px on desktop), never wider. */
#otg-app .otg-table-actions { width: min(100%, 440px); max-width: none; margin-left: auto; margin-right: auto; gap: 6px; }
#otg-app .otg-table-actions .otg-btn { flex: 1 1 0; min-width: 0; white-space: nowrap; padding: 8px 4px; font-size: 13px; }
#otg-app .otg-table-actions .otg-sound-btn.otg-sound-act {
	flex: 0 0 44px; width: 44px; height: auto; align-self: stretch; padding: 0; border-radius: 999px; opacity: 1;
	background: #fff !important; color: var(--otg-text);
	border: 1.5px solid #e7ddc9 !important;
}
#otg-app .otg-table-actions .otg-sound-btn.otg-sound-act .otg-sound-icon { width: 20px; height: 20px; }
@media (min-width: 1024px) {
	#otg-app .otg-table-actions { width: min(100%, 560px); max-width: none; }
	#otg-app .otg-table-actions .otg-btn { font-size: 15px; padding: 9px 6px; }
}
