/* Beat Pete shared UI layer: design tokens, loading skeletons, page transitions, optimistic-UI states.
   Loaded on every page right after a11y.css. Tokens are additive: existing per-game variables keep working,
   new and shared components should use these instead of hard-coding values. */
:root{
  /* spacing (4px base) */
  --sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:16px;--sp-5:24px;--sp-6:32px;
  /* radii */
  --r-sm:8px;--r-md:12px;--r-lg:16px;--r-xl:22px;--r-pill:999px;
  /* elevation */
  --sh-1:0 1px 3px rgba(0,0,0,.28);
  --sh-2:0 4px 14px rgba(0,0,0,.32);
  --sh-3:0 12px 32px rgba(0,0,0,.42);
  /* type scale */
  --fs-xs:12px;--fs-sm:13.5px;--fs-md:15px;--fs-lg:18px;--fs-xl:22px;--fs-2xl:28px;
  --font-ui:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  /* semantic colours (felt-theme defaults; a page's own :root can override) */
  --c-gold:var(--gold,#ffd54f);--c-danger:#ff8a80;--c-ok:#7fe0a0;--c-line:rgba(255,255,255,.14);
  /* motion */
  --ease:cubic-bezier(.2,.7,.2,1);--dur-fast:.12s;--dur:.2s;--dur-slow:.35s;
}

/* ---------- loading skeletons: <div class="skel"></div>, optionally sized inline or with .skel-row/.skel-line/.skel-circle ---------- */
.skel{display:block;min-height:12px;border-radius:var(--r-md);
  background:linear-gradient(90deg,rgba(255,255,255,.05) 25%,rgba(255,255,255,.13) 50%,rgba(255,255,255,.05) 75%);
  background-size:300% 100%;animation:skel-shimmer 1.3s linear infinite}
.skel-row{height:62px}
.skel-line{height:12px;border-radius:6px}
.skel-circle{width:40px;height:40px;border-radius:50%;flex:none}
@keyframes skel-shimmer{from{background-position:100% 0}to{background-position:-100% 0}}
/* a skeleton row that mimics a list item: avatar + two lines */
.skel-item{display:flex;align-items:center;gap:12px;padding:10px 12px;min-height:62px}
.skel-item>div{flex:1;display:grid;gap:8px}
.skel-item .skel-line:first-child{width:55%}.skel-item .skel-line:last-child{width:35%}

/* ---------- optimistic UI: a row that is being removed/changed fades at once while the server confirms ---------- */
.is-leaving{opacity:.45;pointer-events:none;transition:opacity var(--dur) var(--ease)}
.is-pending{opacity:.7}

/* ---------- page transitions: the info page -> play page jump (and everything else) cross-fades instead of flashing white.
   Cross-document View Transitions (Chrome/Edge 126+, Safari 18.2+); other browsers simply ignore the at-rule. ---------- */
@view-transition{navigation:auto}
::view-transition-old(root),::view-transition-new(root){animation-duration:.18s;animation-timing-function:ease-out}
@media (prefers-reduced-motion:reduce){
  @view-transition{navigation:none}
  .skel{animation:none}
}

/* guests have no friends list: the nav Friends link only shows once signed in (html.li is set by theme.js before first paint) */
html:not(.li) .nav a.nav-friends{display:none}

/* tablets / big screens: the board games' table column may grow past the phone cap so the board fills the iPad (their layout() sizes the board from the column width) */
@media (min-width:900px) and (min-height:700px){
  html[data-where="chess"] main.table,html[data-where="checkers"] main.table,html[data-where="connect4"] main.table,html[data-where="tictactoe"] main.table{max-width:min(1000px,100%)}
}

/* the chosen option in every Customise picker: the same gold border (2026-10-20) */
.hh-opt[aria-pressed="true"],.fxt:has(input:checked),.abo.on{border-color:#ffd54f!important;box-shadow:none!important}
.mvf.on{box-shadow:inset 0 0 0 2px #ffd54f!important}
.box button.cxc.on,.tface.on{box-shadow:inset 0 0 0 2px #ffd54f!important}
.tsw.on{box-shadow:0 0 0 3px var(--m-bg,#14251c),0 0 0 5px #ffd54f!important}
.tpat.on{border-color:#ffd54f!important}

/* notification quick actions (Account.noteActionsHTML, shared/account.js): Accept / Decline / Play now under a notification row */
.na-acts{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}
.na-b{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:40px;padding:0 16px;border-radius:var(--r-pill,999px);font-weight:700;font-size:14px;line-height:1;font-family:inherit;cursor:pointer;border:1px solid var(--m-line,rgba(255,255,255,.18));background:transparent;color:var(--m-text,#f4f8f5)}
.na-b.na-yes{background:var(--m-accent,#ffd54f);border-color:transparent;color:#1b1b1b}
.na-b:active{transform:scale(.96)}
.na-acts.is-pending{pointer-events:none}
.na-done{display:inline-flex;align-items:center;gap:6px;font-size:13.5px;font-weight:700;color:var(--m-muted,#b9c9bf)}

/* ---- Tablet landscape play pages (iPad 1180x820, 1366x1024), chess / checkers / connect4 / tictactoe (2026-10-20) ----
   The board takes the left column at the full height of the screen (the games' own layout() sizes it from min(column width, column height),
   so no JS change); the opponent / you / move-list panels stack in a side column. Phones (<900px wide) and phone landscape (<700px tall) are untouched. */
@media (min-width:900px) and (min-height:700px) and (orientation:landscape){
  html[data-where="chess"] main.table,html[data-where="checkers"] main.table,html[data-where="connect4"] main.table,html[data-where="tictactoe"] main.table{
    max-width:min(1240px,100%);grid-template-columns:minmax(0,1fr) minmax(250px,320px);column-gap:18px;align-content:stretch;align-items:start}
  html[data-where="checkers"] main.table,html[data-where="connect4"] main.table,html[data-where="tictactoe"] main.table,
  html[data-where="checkers"] main.table.cx-rvon,html[data-where="connect4"] main.table.cx-rvon,html[data-where="tictactoe"] main.table.cx-rvon,html[data-where="checkers"] main.table.cx-st{
    grid-template-rows:auto auto auto auto minmax(0,1fr);grid-template-areas:"board opp" "board you" "board rview" "board steps" "board ."}
  html[data-where="chess"] main.table,html[data-where="chess"] main.table.cx-rvon{
    grid-template-rows:auto minmax(0,1fr) auto auto;grid-template-areas:"board opp" "board moves" "board you" "board rview"}
  html[data-where="chess"] #boardWrap,html[data-where="checkers"] #boardWrap,html[data-where="connect4"] #boardWrap,html[data-where="tictactoe"] #boardWrap{height:100%;align-self:stretch}
  /* chess: the move list is always open beside the board */
  html[data-where="chess"] .mp .mh{pointer-events:none}
  html[data-where="chess"] .mp .mh i{display:none}
  html[data-where="chess"] #moveList,html[data-where="chess"] .mp.open #moveList{display:grid;max-height:none;flex:1;min-height:0;align-content:start;overflow:auto;grid-template-columns:repeat(auto-fill,minmax(130px,1fr))}
  html[data-where="chess"] .mp{min-height:0;height:100%}
  html[data-where="chess"] #youPanel,html[data-where="chess"] #oppPanel{align-self:start}
}
