/* Document-level rules: the non-scrolling app frame, base buttons, fixed bars. */

/* The document itself never scrolls -- html/body are pinned to exactly
   one viewport (100dvh, the mobile-toolbar-aware unit, with a 100%
   fallback for browsers that don't understand dvh yet). Every screen
   (the lobby overlay, and .game-layout below) is its own confined
   `position:fixed` pane with its own `overflow-y:auto`, the same pattern
   -- so the docked header/nav are never sharing a scroll container with
   page content and can't drift, jump, or lag behind it, including on
   mobile browsers where a fixed element coexisting with *document*-level
   scrolling is the classic source of that jank. */
* { box-sizing: border-box; margin: 0; padding: 0; user-select: none; -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
html, body { max-width: 100%; overflow: hidden; overscroll-behavior: none; height: 100%; height: 100dvh; }
/* The canvas behind everything: if a home-screen (standalone) iOS launch
   leaves any strip outside the body, it's page-coloured, not white. */
html { background: var(--page-bg-2); }
/* Home-screen (standalone) launches on iOS, with black-translucent +
   viewport-fit=cover: 100dvh resolves short by the top safe area on a cold
   start (it only corrects after a rotation), which left the bottom nav
   floating ~50px above the screen edge. 100vh is the full screen there, and
   standalone has no collapsing browser toolbars for dvh to track anyway. */
@media (display-mode: standalone) {
  html, body { height: 100vh; }
}
body {
  background: radial-gradient(circle, var(--page-bg-1) 0%, var(--page-bg-2) 100%);
  color: var(--text-primary);
  font-family: 'Alegreya Sans', sans-serif;
}

.btn-ui {
  background: #3b2214;
  border: 1px solid var(--gold-accent);
  color: #fef08a;
  padding: 5px 10px;
  border-radius: 8px;
  cursor: pointer;
  font-weight: 700;
  font-size: 0.76rem;
  white-space: nowrap;
  flex-shrink: 0;
  transition: all 0.2s ease;
}
.btn-ui:hover { background: var(--gold-accent); color: #000; }
.btn-ui.selected { background: var(--success); border-color: #fff; color: #000; }

/* The in-game screen's own confined scroll pane -- same treatment as
   .lobby-overlay/.shell-scroll below, so it never depends on the document
   itself scrolling (see the html/body comment above). */
.game-layout {
  position: fixed; left: 0; right: 0; z-index: 140; margin: 0 auto;
  top: calc(var(--topbar-h) + env(safe-area-inset-top));
  bottom: calc(var(--navbar-h) + env(safe-area-inset-bottom));
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  width: 100%;
  max-width: 1100px;
  padding: 12px calc(10px + env(safe-area-inset-right)) 12px calc(10px + env(safe-area-inset-left));
}

/* The HUD column: transparent to layout when the HUD is stacked with the
   board (portrait), a real side column in landscape (responsive.css). */
.game-side { display: contents; }

.top-controls-row { display: flex; gap: 14px; width: 100%; }
.top-controls-row .hud-panel { flex: 1 1 0; min-width: 0; }

.mat-frame-wrap { position: relative; width: 100%; max-width: 1060px; display: flex; }
.mat-border-frame { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 4; }

.embroidered-mat {
  background-color: var(--mat-bg);
  /* Toned down from the original (larger, higher-contrast dots) -- this
     texture sits directly behind every cell/token, so it was competing
     with the game-state colors it needs to stay legible against. */
  background-image: radial-gradient(rgba(138,90,61,0.16) 12%, transparent 13%);
  background-size: 14px 14px;
  border: 22px solid var(--mat-border);
  box-shadow: 0 12px 30px rgba(0,0,0,0.7), inset 0 0 20px rgba(0,0,0,0.15);
  position: relative;
  width: 100%;
  min-height: 200px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden;
}
.embroidered-mat::before { content: ''; position: absolute; inset: 6px; border: 1px solid var(--mat-border); opacity: .5; pointer-events: none; z-index: 1; }

.corner-ornament { position: absolute; width: 26px; height: 26px; z-index: 2; pointer-events: none; }
.corner-ornament::before, .corner-ornament::after { content: ''; position: absolute; inset: 3px; background: var(--gold-accent); box-shadow: 0 0 4px var(--shadow); }
.corner-ornament::before { clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); }
.corner-ornament::after { clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); transform: rotate(45deg); }
.corner-ornament.tl { top: 8px; left: 8px; }
.corner-ornament.tr { top: 8px; right: 8px; }
.corner-ornament.bl { bottom: 8px; left: 8px; }
.corner-ornament.br { bottom: 8px; right: 8px; }

/* Visibility is controlled with the standard `hidden` attribute (el.hidden in
   scripts). !important so a component's own display rule can't override it. */
[hidden] { display: none !important; }
/* Keeps its layout space while invisible (e.g. the tour's Back button on step 1). */
.invisible { visibility: hidden; }

/* Off-screen but still read by screen readers and crawlers. */
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Hidden SVG <symbol> sprite at the top of the body. */
.svg-sprite { position: absolute; }

/* Spacing and layout utilities used by the markup instead of inline styles.
   !important because they stand in for inline styles, which always won over
   component rules -- a utility on an element is meant to be the last word. */
.mt-2 { margin-top: 2px !important; }
.mt-6 { margin-top: 6px !important; }
.mt-8 { margin-top: 8px !important; }
.mt-10 { margin-top: 10px !important; }
.mt-14 { margin-top: 14px !important; }
.mt-16 { margin-top: 16px !important; }
.mb-6 { margin-bottom: 6px !important; }
.mb-10 { margin-bottom: 10px !important; }
.mb-12 { margin-bottom: 12px !important; }
.mb-14 { margin-bottom: 14px !important; }
.mb-16 { margin-bottom: 16px !important; }
.text-center { text-align: center !important; }
.flex-1 { flex: 1 !important; }
.w-full { width: 100% !important; }
.row-gap-8 { display: flex !important; gap: 8px !important; }

/* Status-line tones (components/status-line.js). !important for the same
   reason as the utilities: they replace colours that used to be set inline and
   must beat a component's default colour (e.g. .lobby-status is red). The
   'neutral' tone has no rule on purpose -- it keeps the element's own colour. */
.status-error { color: var(--status-error) !important; }
.status-success { color: var(--status-success) !important; }

/* Global: text selection, keyboard focus ring, scrollbars. */
::selection { background: var(--gold-accent); color: #120a06; }
:focus-visible { outline: 3px solid #f5cf54; outline-offset: 3px; }
* { scrollbar-width: thin; scrollbar-color: #8a5a3d #1e130c; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: #1e130c; }
*::-webkit-scrollbar-thumb { background: #8a5a3d; border-radius: 8px; }
