/* Fixed full-screen background layer, admin-configurable (solid /
 * gradient / image) — sits behind #tcg-app, which goes transparent
 * via inline style in TCG_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. */
.tcg-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 TCG_Background::
 * text_color()) -- deliberately separate from --tcg-text (this
 * plugin's general ink colour, used throughout cards/buttons too), so
 * repainting it never touches card/button text. Declared at :root
 * (not #tcg-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
 * TCG_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 {
	--tcg-outside-text: #2c2416;
}

/* Thai Checkers (หมากฮอสไทย) — self-contained front-end styles.
 * Board/piece colors are CSS custom properties on #tcg-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;
}

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

#tcg-app {
	--tcg-light: #e8d3ab;
	--tcg-dark: #8a5a34;
	--tcg-board-border: #4a331d;
	--tcg-p0-a: #3a3a3a;
	--tcg-p0-b: #141414;
	--tcg-p1-a: #fbf6ec;
	--tcg-p1-b: #d9cdb6;
	/* Optional admin-uploaded piece IMAGE skins (see class-tcg-piece-skins.php
	 * + game.js's applyTheme()) — 'none' by default so the plain colour
	 * gradients below (--tcg-p0-a/b, --tcg-p1-a/b) show through until a
	 * player picks an image skin in the customize panel. */
	--tcg-p0-img: none;
	--tcg-p1-img: none;
	--tcg-accent: #c8912f;
	--tcg-bg: #faf6ef;
	--tcg-card: #ffffff;
	--tcg-text: #2c2416;
	--tcg-muted: #7a6f5c;
	--tcg-danger: #c0392b;
	--tcg-success: #2e7d32;
	--tcg-radius: 14px;
	--tcg-shadow: 0 4px 18px rgba(60, 40, 10, 0.12);

	box-sizing: border-box;
	max-width: 520px;
	margin: 0 auto;
	padding: 16px;
	color: var(--tcg-text);
	background: var(--tcg-bg);
	border-radius: 18px;
	/* display:flex + .tcg-back's own "order" (below) is what moves the
	 * back button to the bottom of the pre-game setup screens
	 * (2026-09-27) — #tcg-app's own direct children (back button,
	 * optional header, .tcg-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;
}
#tcg-app *, #tcg-app *::before, #tcg-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. */
#tcg-app .tcg-loading { text-align: center; padding: 40px 0; color: var(--tcg-outside-text, var(--tcg-muted)); }

/* ---------- Layout shell ---------- */
#tcg-app .tcg-screen { display: none; }
#tcg-app .tcg-screen.active { display: block; animation: tcg-fade-in .18s ease; }
@keyframes tcg-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 .tcg-screen.active so it
 * must come after it in source order to win; the compound selector
 * below also wins outright regardless of order. */
#tcg-app .tcg-screen.active.tcg-no-anim { animation: none; }

#tcg-app .tcg-logo { text-align: center; margin-bottom: 6px; }
#tcg-app .tcg-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. */
#tcg-app .tcg-header { text-align: center; margin-bottom: 18px; }
#tcg-app .tcg-header h2 { font-size: 26px; margin: 0 0 4px; color: var(--tcg-outside-text, var(--tcg-text)); }
#tcg-app .tcg-header p { margin: 0; color: var(--tcg-outside-text, var(--tcg-muted)); font-size: 14px; }
#tcg-app .tcg-home-link {
	display: block;
	text-align: center;
	margin-top: 18px;
	padding: 12px 0;
	color: var(--tcg-outside-text, var(--tcg-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 (#tcg-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. */
#tcg-app .tcg-back {
	order: 2;
	align-self: flex-start;
	display: inline-flex; align-items: center; gap: 6px;
	background: #ffffff; border: 1.5px solid #e7ddc9; color: var(--tcg-text);
	font-size: 14px; font-weight: 600; padding: 10px 18px; border-radius: 999px;
	margin-top: 16px; margin-bottom: 0; cursor: pointer;
	box-shadow: var(--tcg-shadow);
}
#tcg-app .tcg-back:hover { background: #faf6ef; }

/* ---------- Mode select cards ---------- */
#tcg-app .tcg-mode-list { display: flex; flex-direction: column; gap: 12px; }
#tcg-app .tcg-mode-card {
	display: flex; align-items: center; gap: 14px;
	background: var(--tcg-card); border: 1.5px solid #e7ddc9; border-radius: var(--tcg-radius);
	padding: 11px 16px; cursor: pointer; text-align: left; width: 100%;
	box-shadow: var(--tcg-shadow); transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
	font: inherit; color: inherit;
}
#tcg-app .tcg-mode-card:hover { transform: translateY(-2px); box-shadow: 0 8px 22px rgba(60,40,10,.16); border-color: var(--tcg-accent); }
#tcg-app .tcg-mode-card .tcg-mode-icon {
	width: 46px; height: 46px; border-radius: 50%; flex: none;
	display: flex; align-items: center; justify-content: center;
	background: #ffffff; color: var(--tcg-accent);
	border: 1px solid #eee1c8; box-shadow: 0 2px 6px rgba(60,40,10,.10);
}
#tcg-app .tcg-mode-card .tcg-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. */
#tcg-app .tcg-mode-card .tcg-mode-icon.tcg-mode-icon--computer, #tcg-app .tcg-mode-card .tcg-mode-icon.tcg-mode-icon--phone, #tcg-app .tcg-mode-card .tcg-mode-icon.tcg-mode-icon--globe { color: #ffffff; border-color: transparent; }
#tcg-app .tcg-mode-card .tcg-mode-icon.tcg-mode-icon--computer { background: linear-gradient(135deg, #29b6f6 0%, #12c98b 100%); box-shadow: 0 3px 8px rgba(18,201,139,.35); }
#tcg-app .tcg-mode-card .tcg-mode-icon.tcg-mode-icon--phone { background: linear-gradient(135deg, #ffd23f 0%, #ff8a1f 100%); box-shadow: 0 3px 8px rgba(255,138,31,.35); }
#tcg-app .tcg-mode-card .tcg-mode-icon.tcg-mode-icon--globe { background: linear-gradient(135deg, #ff5fa2 0%, #8b5cf6 100%); box-shadow: 0 3px 8px rgba(139,92,246,.35); }
#tcg-app .tcg-mode-card strong { display: block; font-size: 16px; }
#tcg-app .tcg-mode-card span { display: block; font-size: 13px; color: var(--tcg-muted); margin-top: 2px; }

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

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

/* ---------- Difficulty picker ---------- */
#tcg-app .tcg-difficulty-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 18px; }
#tcg-app .tcg-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;
}
#tcg-app .tcg-difficulty-option strong { display: block; font-size: 15px; }
#tcg-app .tcg-difficulty-option span { display: block; font-size: 12.5px; color: var(--tcg-muted); margin-top: 2px; }
#tcg-app .tcg-difficulty-option.selected { border-color: var(--tcg-accent); background: #fff8ea; }

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

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

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

#tcg-app .tcg-timer-digital {
	flex: none;
	font-family: 'Digital-Dismay', monospace !important;
	background: #fff;
	color: var(--tcg-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;
}
#tcg-app .tcg-timer-digital.is-low { font-weight: 800; }

/* ---------- Board ---------- */
#tcg-app .tcg-board-wrap { display: flex; justify-content: center; margin-bottom: 12px; }
#tcg-app .tcg-board {
	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(--tcg-board-border); border-radius: 8px; overflow: hidden;
	box-shadow: var(--tcg-shadow);
}
#tcg-app .tcg-square { position: relative; display: flex; align-items: center; justify-content: center; }
#tcg-app .tcg-square.light { background: var(--tcg-light); }
#tcg-app .tcg-square.dark { background: var(--tcg-dark); }
#tcg-app .tcg-square.selectable::after {
	content: ""; position: absolute; inset: 6px; border-radius: 50%;
	border: 2px solid var(--tcg-accent); opacity: .55; pointer-events: none;
}
#tcg-app .tcg-square.dest-hint::before {
	content: ""; position: absolute; width: 26%; height: 26%; border-radius: 50%;
	background: var(--tcg-accent); opacity: .7; pointer-events: none;
}
#tcg-app .tcg-square.dest-hint.dest-capture::before { background: var(--tcg-danger); width: 34%; height: 34%; }
#tcg-app .tcg-square.selected { box-shadow: inset 0 0 0 4px var(--tcg-accent); }
#tcg-app .tcg-square.last-move { box-shadow: inset 0 0 0 3px rgba(46, 125, 50, .55); }
#tcg-app .tcg-square.tcg-clickable { cursor: pointer; }

#tcg-app .tcg-piece {
	width: 78%; height: 78%; border-radius: 50%; position: relative;
	display: flex; align-items: center; justify-content: center;
	box-shadow: 0 2px 3px rgba(0,0,0,.35), inset 0 2px 3px rgba(255,255,255,.25), inset 0 -3px 5px rgba(0,0,0,.25);
	transition: transform .12s ease;
	/* Prevents touch-drag on a piece from also scrolling the page — needed
	 * for the mouse/touch drag-to-move support (see the pointerdown/move/up
	 * handlers in game.js). */
	touch-action: none;
}
#tcg-app .tcg-square.selectable .tcg-piece { cursor: grab; }
/* While a piece is actively being dragged (pointer down + moved past the
 * tap threshold): it tracks the pointer 1:1 above everything else, then
 * game.js hands it back to the transition above to glide/snap into place
 * on drop. */
#tcg-app .tcg-piece.tcg-piece-dragging {
	cursor: grabbing; box-shadow: 0 8px 16px rgba(0,0,0,.45); z-index: 5;
	/* So document.elementFromPoint() at the drop point (used to find which
	 * square the pointer is over) sees the square underneath instead of
	 * hitting the dragged piece itself — pointer capture (set in game.js)
	 * still delivers pointermove/pointerup to this element regardless. */
	pointer-events: none;
}
/* Each has two background layers: the admin's optional piece-skin image
 * on top (--tcg-p0-img/--tcg-p1-img, 'none' unless a player picked an
 * image skin — see game.js applyTheme()) and the flat-colour radial
 * gradient underneath, so switching skins/colours is an instant CSS
 * custom-property update with no board re-render needed. */
#tcg-app .tcg-piece.p0 {
	background: var(--tcg-p0-img) center/cover no-repeat, radial-gradient(circle at 35% 30%, var(--tcg-p0-a), var(--tcg-p0-b));
	border: 1px solid rgba(0,0,0,.4);
}
#tcg-app .tcg-piece.p1 {
	background: var(--tcg-p1-img) center/cover no-repeat, radial-gradient(circle at 35% 30%, var(--tcg-p1-a), var(--tcg-p1-b));
	border: 1px solid rgba(0,0,0,.15);
}
/* While an image skin is active (data-piece-skin="img"), drop the flat-
 * colour layer entirely and zoom the image in past plain "cover" — a
 * square product photo (e.g. a bottle-cap skin) has the round graphic
 * sitting a little smaller than the square canvas (transparent margin
 * around it), and the piece itself only clips to a circle inscribed in
 * that same square, so at 100%/"cover" a thin gap is left between the
 * graphic's own edge and the piece's circular clip — the board's square
 * colour shows through that gap (seen as a stray cream/light ring or
 * crescent, user-reported 2026-09-26). Zooming in trims that gap away,
 * but too much (145%, tried earlier) also crops into the graphic's own
 * jagged outline (a bottle cap's crown teeth got rounded off), while too
 * little (105%, tried next) doesn't close the gap fully and the ring
 * reappears. 112% is the balance point: just past what a graphic that
 * fills ~90% of its canvas needs to fully cover the circular clip,
 * without over-cropping a jagged edge that reaches further out than
 * that. Individual uploaded images can still vary a little in how much
 * margin they carry, so a specific image may need its own future
 * per-slot adjustment if this generic value doesn't quite fit it. Also:
 * the base .tcg-piece rule below adds an inset light/dark bevel meant to
 * make a FLAT colour look like a glossy button; over a photo that inset
 * shadow instead shows up as a stray dark crescent/"ring" along one edge
 * (user-reported 2026-09-26, mistaken for a leftover background ring),
 * so image-skin pieces drop that inset bevel and keep only a plain drop
 * shadow, and lose the flat-colour border too since the photo supplies
 * its own edge. */
#tcg-app[data-piece-skin="img"] .tcg-piece.p0 { background: var(--tcg-p0-img) center / 112% no-repeat; border-color: transparent; }
#tcg-app[data-piece-skin="img"] .tcg-piece.p1 { background: var(--tcg-p1-img) center / 112% no-repeat; border-color: transparent; }
#tcg-app[data-piece-skin="img"] .tcg-piece { box-shadow: 0 2px 4px rgba(0,0,0,.4); }
#tcg-app[data-piece-skin="img"] .tcg-piece.tcg-piece-dragging { box-shadow: 0 8px 16px rgba(0,0,0,.45); }
#tcg-app .tcg-piece.king::after {
	content: "♛"; font-size: 15px; line-height: 1; color: var(--tcg-accent); text-shadow: 0 1px 1px rgba(0,0,0,.4);
}
#tcg-app .tcg-piece.p1.king::after { color: #a86f1f; }
/* Over a busy piece image, no backing chip (user-requested 2026-09-26 —
 * dropped the dark circle behind the crown) — just a bigger crown with
 * a stronger shadow for contrast, only while an image skin is actually
 * active (data-piece-skin="img", toggled by applyTheme() in game.js),
 * so the plain-colour look is unchanged for everyone else. */
#tcg-app[data-piece-skin="img"] .tcg-piece.p0.king::after,
#tcg-app[data-piece-skin="img"] .tcg-piece.p1.king::after {
	font-size: 34px;
	/* A little shadow only (user-requested 2026-09-27 — the piece is
	 * already big, a heavy double shadow isn't needed and, combined
	 * with the fallback below, is what made the crown read as a plain
	 * dark/black blob instead of gold). */
	text-shadow: 0 2px 3px rgba(0,0,0,.35);
	/* Solid orange-gold fallback FIRST (user-requested colour): if the
	 * gradient-clip below silently fails to apply -- reported
	 * 2026-09-27, the crown over a piece image was rendering as a flat
	 * black/shadow shape instead of gold on at least one browser/site
	 * context, even though the gradient rule was already present here
	 * -- the crown still shows as a solid orange-gold glyph, never
	 * black, instead of falling through to transparent with nothing
	 * painted over it. */
	color: #ffab1f;
}
@supports (background-clip: text) or (-webkit-background-clip: text) {
	/* Orange-to-yellow gradient crown over a piece image (user-requested
	 * 2026-09-26), instead of the plain accent-gold / dark-gold used for
	 * the flat-colour look -- text can't take a gradient fill directly,
	 * so the gradient is painted behind the glyph and clipped to its
	 * shape via background-clip:text, with the actual text colour made
	 * transparent so the gradient shows through instead. Gated behind
	 * @supports so a browser that can't clip a background to text keeps
	 * the solid fallback colour above rather than going transparent. */
	#tcg-app[data-piece-skin="img"] .tcg-piece.p0.king::after,
	#tcg-app[data-piece-skin="img"] .tcg-piece.p1.king::after {
		background: linear-gradient(180deg, #ffd54a 0%, #ff8c1a 100%);
		background-clip: text; -webkit-background-clip: text;
		color: transparent; -webkit-text-fill-color: transparent;
	}
}
#tcg-app .tcg-square.selected .tcg-piece { transform: scale(1.08); }
#tcg-app .tcg-piece.tcg-just-moved { animation: tcg-pop .25s ease; }
@keyframes tcg-pop { 0% { transform: scale(.7); } 60% { transform: scale(1.12); } 100% { transform: scale(1); } }

#tcg-app .tcg-table-actions { display: flex; gap: 8px; margin-top: 6px; }
#tcg-app .tcg-table-actions .tcg-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. */
#tcg-app .tcg-gameover-overlay { align-items: center; padding: 20px; }
#tcg-app .tcg-gameover-card {
	border-radius: 18px;
	box-shadow: 0 12px 40px rgba(0, 0, 0, .3);
	text-align: center;
	max-width: 380px;
}
#tcg-app .tcg-gameover-card .tcg-result-title { font-size: 24px; font-weight: 800; margin: 6px 0; }
#tcg-app .tcg-gameover-card .tcg-result-reason { color: var(--tcg-muted); margin-bottom: 14px; }
#tcg-app .tcg-gameover-card .tcg-result-stats {
	background: rgba(0, 0, 0, .05); border-radius: 10px; padding: 10px 12px; margin-bottom: 16px;
}
#tcg-app .tcg-gameover-card .tcg-result-stats p { margin: 4px 0; font-size: 13px; color: var(--tcg-text); }
#tcg-app .tcg-gameover-card .tcg-btn { margin-bottom: 10px; }
#tcg-app .tcg-gameover-card .tcg-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. */
#tcg-app .tcg-draw-banner {
	background: #fff8e1; border: 1.5px solid var(--tcg-accent); border-radius: 12px;
	padding: 12px 14px; margin-top: 6px; text-align: center; font-size: 14px; color: var(--tcg-text);
}
#tcg-app .tcg-draw-banner p { margin: 0 0 10px; font-weight: 700; }
#tcg-app .tcg-draw-banner .tcg-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
 * .tcg-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. */
#tcg-app .tcg-overlay {
	position: fixed; inset: 0; background: rgba(20, 14, 4, .5);
	display: flex; align-items: center; justify-content: center; z-index: 9999; padding: 20px;
}
#tcg-app .tcg-overlay.hidden { display: none; }
#tcg-app .tcg-panel {
	background: var(--tcg-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);
}
#tcg-app .tcg-panel-title { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
#tcg-app .tcg-panel-title h2 { font-size: 18px; margin: 0; }
#tcg-app .tcg-panel-title button { background: none; border: none; font-size: 20px; cursor: pointer; color: var(--tcg-muted); }
#tcg-app .tcg-swatch-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
#tcg-app .tcg-swatch-row label { font-size: 14px; font-weight: 600; }
#tcg-app .tcg-swatch-row input[type="color"] {
	width: 44px; height: 34px; border: none; border-radius: 8px; padding: 0; background: none; cursor: pointer;
}
#tcg-app .tcg-preset-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 10px 0 18px; }
#tcg-app .tcg-preset-swatch {
	height: 40px; border-radius: 8px; cursor: pointer; border: 2px solid transparent;
	background-size: cover;
}
#tcg-app .tcg-preset-swatch.selected { border-color: var(--tcg-text); }
#tcg-app .tcg-panel h3 { font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--tcg-muted); margin: 16px 0 8px; }
#tcg-app .tcg-panel .tcg-btn-ok { width: 100%; margin-top: 14px; }

/* Admin-uploaded piece-image skins ("ภาพหมาก" section of the customize
 * panel) — same grid/card idea as the board-theme presets above, but
 * each swatch shows both players' actual piece images side by side. */
#tcg-app .tcg-skin-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin: 10px 0 12px; }
#tcg-app .tcg-skin-swatch {
	display: flex; gap: 4px; justify-content: center; align-items: center;
	padding: 8px 6px; border-radius: 8px; cursor: pointer; border: 2px solid transparent;
	background: rgba(0,0,0,.04);
}
#tcg-app .tcg-skin-swatch.selected { border-color: var(--tcg-accent); background: rgba(200,145,47,.12); }
#tcg-app .tcg-skin-thumb {
	width: 34px; height: 34px; border-radius: 50%; background-size: cover; background-position: center;
	box-shadow: 0 1px 2px rgba(0,0,0,.3), inset 0 0 0 1px rgba(0,0,0,.15);
}

/* ---------- Responsive ---------- */
@media (max-width: 380px) {
	#tcg-app { padding: 12px; }
	#tcg-app .tcg-room-code { font-size: 30px; letter-spacing: 5px; }
	#tcg-app .tcg-player-info .tcg-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) {
	#tcg-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) {
	#tcg-app { max-width: 900px; padding: 22px; }
	#tcg-app .tcg-logo img { width: 260px; }
	#tcg-app .tcg-header h2 { font-size: 34px; }
	#tcg-app .tcg-header p { font-size: 16px; }
	#tcg-app .tcg-mode-card { padding: 14px 20px; }
	#tcg-app .tcg-mode-card .tcg-mode-icon { width: 56px; height: 56px; }
	#tcg-app .tcg-mode-card .tcg-mode-icon svg { width: 28px; height: 28px; }
	#tcg-app .tcg-mode-card strong { font-size: 18px; }
	#tcg-app .tcg-mode-card span { font-size: 14px; }
	#tcg-app .tcg-room-code { font-size: 56px; letter-spacing: 10px; padding: 22px 14px; }
	#tcg-app .tcg-player-bar { padding: 14px 16px; }
	#tcg-app .tcg-player-avatar { width: 40px; height: 40px; }
	#tcg-app .tcg-player-info .tcg-player-name { font-size: 15px; max-width: 160px; }
	#tcg-app .tcg-player-info .tcg-player-pieces { font-size: 13px; }
	#tcg-app .tcg-status-line { font-size: 16px; padding: 10px; }
	#tcg-app .tcg-timer-digital { font-size: 22px; padding: 10px 12px; }
	/* Board squares are already % of .tcg-board, and pieces are 78% of a
	 * square, so simply raising this cap (was 440px) scales the whole
	 * board — squares, pieces, king glyph — proportionally. */
	#tcg-app .tcg-board { width: min(100%, 560px); }
	#tcg-app .tcg-table-top,
	#tcg-app .tcg-status-line,
	#tcg-app .tcg-table-actions,
	#tcg-app .tcg-gameover-card {
		max-width: 560px;
		margin-left: auto;
		margin-right: auto;
	}
	#tcg-app .tcg-piece.king::after { font-size: 22px; }
	#tcg-app[data-piece-skin="img"] .tcg-piece.p0.king::after,
	#tcg-app[data-piece-skin="img"] .tcg-piece.p1.king::after { font-size: 46px; }
	#tcg-app .tcg-btn { font-size: 17px; padding: 11px 18px; }
	#tcg-app .tcg-gameover .tcg-result-title { font-size: 30px; }
	#tcg-app .tcg-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) ---------- */
/* .tcg-chat-root sits OUTSIDE #tcg-app (a sibling — see game.js) so its
 * own <input> never gets torn down by #tcg-app's frequent full innerHTML
 * rebuilds. Being outside #tcg-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. */
.tcg-chat-root, .tcg-chat-root * {
	font-family: 'db', 'SF Thonburi', 'Sarabun', 'Noto Sans Thai', sans-serif;
	box-sizing: border-box;
}
.tcg-chat-root { position: fixed; right: 16px; bottom: 16px; z-index: 55; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
.tcg-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;
}
.tcg-chat-fab-icon { position: relative; z-index: 1; display: block; width: 52px; height: 47px; }
.tcg-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. */
.tcg-chat-fab::before,
.tcg-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: tcg-chat-glow 5s ease-out infinite;
}
.tcg-chat-fab::after { animation-delay: .35s; }
@keyframes tcg-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) {
	.tcg-chat-fab::before, .tcg-chat-fab::after { animation: none; opacity: 0; }
}
.tcg-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;
}
.tcg-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;
}
.tcg-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". */
.tcg-chat-close { background: none; border: none; color: #fff; font-size: 12px; line-height: 1; cursor: pointer; padding: 0 4px; }
.tcg-chat-messages { flex: 1; overflow-y: auto; padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; }
.tcg-chat-empty { color: #9a8f7a; font-size: 13px; text-align: center; margin-top: 20px; }
.tcg-chat-msg { max-width: 82%; background: #f3ede0; border-radius: 10px; padding: 6px 10px; align-self: flex-start; }
.tcg-chat-msg-mine { background: #fff1c4; align-self: flex-end; }
.tcg-chat-msg-name { font-size: 11px; font-weight: 800; color: #7a6f5c; margin-bottom: 2px; }
.tcg-chat-msg-text { font-size: 14px; word-break: break-word; white-space: pre-wrap; }
.tcg-chat-form { display: flex; gap: 6px; padding: 8px; border-top: 1px solid #eee2cc; }
.tcg-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;
}
.tcg-chat-input:focus { outline: none; border-color: #c7bb9e; }
.tcg-chat-send {
	border: none; border-radius: 999px; padding: 8px 16px; background: #ffb600; color: #fff; font-weight: normal; font-size: 14px; cursor: pointer;
}
.tcg-chat-send:hover { background: linear-gradient(135deg, #ffd400, #ff7a00); }
.tcg-chat-send:active { transform: scale(.97); }
@media (max-width: 1023px) {
	.tcg-chat-root { right: 12px; bottom: 12px; }
	.tcg-chat-panel { width: calc(100vw - 24px); height: 50vh; }
}

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

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

/* Whose turn: pulsing orange glow on the player card */
#tcg-app .tcg-player-bar.active-turn {
	border-color: #ff8a00;
	animation: tcg-turn-glow 1.1s ease-in-out infinite;
}
@keyframes tcg-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 */
#tcg-app .tcg-btn.tcg-btn-danger { background: linear-gradient(135deg, #ff8a3d, #e53935); color: #fff; }
