:root {
    /* Bevel scale. The default tracks the board-square size on both the desktop
       (90vh) and narrow (100vw) board layouts; elements adopt the bevel at their
       own scale by overriding --bevelSize on themselves. The shadow itself is
       written out literally wherever it is consumed rather than stored in a
       custom property: var() inside a custom property is substituted where that
       property is *defined*, so a --bevelShadow on :root would bake in :root's
       --bevelSize and ignore every per-element override. */
    --bevelSize: min(0.45vh, 0.5vw);
    --bevelSheen: linear-gradient(135deg,
        rgba(255, 231, 194, 0.25) 0%,
        rgba(255, 231, 194, 0.08) 40%,
        rgba(0, 0, 0, 0.05) 70%,
        rgba(0, 0, 0, 0.16) 100%);
}
html, body {
    margin: 0 auto;
    padding: 0;
}
/* This has to stay on * rather than move to body and inherit. The UA stylesheet
   sets font-weight directly on h1-h6 (and font-family/color on form controls),
   and a directly-set UA declaration beats an inherited one — so from body, the
   font-weight: 100 would never reach a single heading and every title in the
   game would render bold. */
* {
    box-sizing: border-box;
    font-family: "Rubik Dirt", "Open Sans", "sans-serif";
    color: #b18c69CC;
    text-shadow: 0 0 4px #000, 1px 1px 4px #3F2820, -1px -1px 4px #3F2820;
    font-weight: 100;
    user-select: none;
}
/* The board is a drag surface, so the browser must not claim a finger on it for
   scrolling or double-tap zoom — it would cancel the pointer stream partway
   through a drag and drop the piece. Scoped to the board on purpose: the saved
   games list and the plaque bodies still have to scroll with a finger. */
#grid {
    touch-action: none;
}
/* The wall behind the game: carved obsidian, baked at startup by raster.js
   into --backdrop (one big PNG, cover-scaled — never tiled, so the stone's
   noise needs no seam). Until the bake lands (or if it ever fails) the
   fallback gradient holds the same near-black so the switch is invisible. */
body {
    display: flex;
    justify-content: center;
    background-color: #0b0a0d;
    background-image: var(--backdrop, linear-gradient(to bottom, #16141a, #0b0a0d));
    background-size: cover;
    background-position: center;
    background-attachment: fixed;
}
::selection {
    background-color: rgba(255, 255, 255, 0.5);
}
/* 128vh: the content plans for 125 (90 of board + 35 of sidebar), plus a
   1.5vh flank each side that the edge bevels span exactly — the chamfer
   runs right up to the readouts' panels and the board's last file, but
   never under them. */
#gameWrap {
    width: 128vh;
    height: 100vh;
    box-shadow: 0 0 50px #000;
    position: relative; /* anchors the bevel strips */
}
/* The slab's edges: a chamfer down each side. A cut face is flat, so each
   strip is built from hard stops, not fades — a fade reads as a rounded-over
   edge. Outer to inner: a thin dark arris where the face falls away to the
   wall, the flat chamfer face, and a thin crease line where the cut meets
   the top. The face itself is wood.png squashed to 800% horizontally: the
   grain visibly foreshortens, the way a plane turning away from the viewer
   should, and the tint over it is uniform — both cuts sit in shade, the left
   only slightly lighter for the top-left lamp. */
#gameWrap::before,
#gameWrap::after {
    content: "";
    position: absolute;
    top: 0;
    height: 100%;
    width: 1.5vh;
    z-index: 2;
    pointer-events: none;
}
#gameWrap::before {
    left: 0;
    background:
        linear-gradient(90deg,
            rgba(0, 0, 0, 0.50) 0%, rgba(0, 0, 0, 0.50) 8%,
            rgba(0, 0, 0, 0.30) 8%, rgba(0, 0, 0, 0.30) 92%,
            rgba(0, 0, 0, 0.55) 92%, rgba(0, 0, 0, 0.55) 100%),
        url(../assets/ui/wood.png) left center / 800% 100%;
}
#gameWrap::after {
    right: 0;
    background:
        linear-gradient(90deg,
            rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0.55) 8%,
            rgba(0, 0, 0, 0.38) 8%, rgba(0, 0, 0, 0.38) 92%,
            rgba(0, 0, 0, 0.65) 92%, rgba(0, 0, 0, 0.65) 100%),
        url(../assets/ui/wood.png) right center / 800% 100%;
}
#game {
    width: 100%;
    height: 100%;
    display: flex;
    flex-wrap: wrap;
    background-image: url(../assets/ui/wood.png);
    background-size: cover;
    overflow-x: hidden;
    /* the flanks the bevels span; border-box keeps the content line at the
       125vh the sidebar and board are budgeted for */
    padding: 0 1.5vh;
    box-sizing: border-box;
}
#titleBar {
    height: 10%;
    flex-basis: 100%;
}
h1 {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 1vh;
    color: #fff;
    text-align: center;
    font-size: 6vh;
    background-color: rgba(0, 0, 0, 0.5);
    user-select: none;
}
/* On the title screen the centre splash already carries the name, so the top
   banner goes quiet — visibility, not display, so the bar keeps its height
   and the board does not jump when a game starts. */
body.onTitle #titleBar h1 {
    visibility: hidden;
}
h2 {
    padding: 0.5vh 0 0;
    margin: 0;
    width: 100%;
    color: #fff;
    font-size: 3vh;
    text-align: center;
}
h3 {
    margin: 0;
    padding: 0;
    color: #fff;
    width: 100%;
    text-align: center;
    font-size: 3.5vh;
}

/* Carved panels and wooden buttons */
.carvedPanel {
    background-color: rgba(0, 0, 0, 0.35);
    border-radius: 0.6vh;
    box-shadow: inset 0 0.3vh 1vh rgba(0, 0, 0, 0.8), inset 0 -0.1vh 0 rgba(255, 255, 255, 0.07);
    padding: 0.8vh;
}
.trayTitle {
    margin: 0 0 0.8vh;
    text-align: center;
    font-size: 2.2vh;
    letter-spacing: 0.2vh;
    color: #d8b98d;
}
button {
    border: none;
    cursor: pointer;
    transition: 0.125s;
    background: none;
    padding: 0;
}
/* Reusable 3D bevel: warm top-left light, deep bottom-right shade, and a soft
   sheen across the face, as if the surface were raised toward the lantern
   light. It lives on a ::before overlay with static shadows and only its
   opacity transitions, which composites. z-index -1 (with isolation on the
   host) keeps the sheen on the wood face, beneath labels and icons. */
.modeBtn, .linkBtn, #settings, .plaqueClose, .saveDelete, #secretKing, .saveCard {
    position: relative;
    isolation: isolate;
    --bevelSize: 0.35vh;
}
.plaqueClose, .saveDelete {
    --bevelSize: 0.22vh;
}
.modeBtn::before, .linkBtn::before, #settings::before,
.plaqueClose::before, .saveDelete::before, #secretKing::before, .saveCard::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    box-shadow:
        inset var(--bevelSize) var(--bevelSize) calc(var(--bevelSize) * 1.2) rgba(255, 227, 183, 0.65),
        inset calc(-1 * var(--bevelSize)) calc(-1 * var(--bevelSize)) calc(var(--bevelSize) * 1.2) rgba(15, 6, 0, 0.7),
        inset 0 0 calc(var(--bevelSize) * 5) rgba(255, 214, 150, 0.25);
    background: var(--bevelSheen);
    opacity: 0;
    transition: opacity 0.125s;
    pointer-events: none;
}
.modeBtn:hover::before, .linkBtn:hover::before, #settings:hover::before,
.plaqueClose:hover::before, .saveDelete:hover::before, #secretKing:hover::before, .saveCard:hover::before,
.saveCard.active::before {
    opacity: 1;
}
/* Pressed buttons hide the bevel so their sunken :active shadow reads clean. */
.modeBtn:active::before, #secretKing:active::before {
    opacity: 0;
}
.modeBtn {
    display: block;
    width: 100%;
    padding: 1vh;
    margin-bottom: 0.8vh;
    font-size: 2.4vh;
    color: #f2dfc2;
    text-shadow: 0 0.2vh 0.3vh #000;
    background-image: url(../assets/ui/wood.png);
    background-size: 220%;
    border-radius: 0.6vh;
    box-shadow: 0 0.4vh 0.8vh rgba(0, 0, 0, 0.6), inset 0 0.2vh 0 rgba(255, 255, 255, 0.18), inset 0 -0.4vh 0.6vh rgba(0, 0, 0, 0.45);
}
.modeBtn:last-child {
    margin-bottom: 0;
}
/* Mode icons: inline SVGs painted in currentColor, so they are always exactly
   the colour of the label beside them (and brighten with it on hover). Sized
   to the label's em square, seated on its baseline, with the same drop
   shadow the text wears. */
/* The icons carry their paint as fill attributes in the #modeIcons symbols
   (kept in step with .modeBtn's color above) rather than via currentColor:
   how a <use> clone resolves CSS colours differs between engines, and the
   universal colour rule up top made every resolution path land on the dim
   coordinate-label tan in at least one of them. Attributes clone verbatim. */
/* Pinned to the button's left edge, vertically centred; the label keeps its
   own centring, so every icon in a tray sits on one column no matter how
   long the label beside it runs. */
.modeIcon {
    position: absolute;
    left: 0.55em;
    top: 50%;
    transform: translateY(-50%);
    width: 1em;
    height: 1em;
    filter: drop-shadow(0 0.2vh 0.2vh #000);
}
.modeBtn:hover {
    filter: brightness(1.15);
}
.modeBtn:active {
    transform: translateY(0.2vh);
    box-shadow: inset 0 0.3vh 0.8vh rgba(0, 0, 0, 0.7);
}
.linkBtn {
    flex: 1;
    font-size: 1.9vh;
    color: #d8b98d;
    background-color: rgba(0, 0, 0, 0.35);
    border-radius: 0.6vh;
    box-shadow: inset 0 0.2vh 0.6vh #000;
}
.linkBtn:hover {
    color: #fff;
}

@media screen and (max-width: 1011px) {
    /* The wrap's fixed 125vh box only makes sense beside the desktop board;
       here it would draw its drop shadow as a dark band across any content
       that scrolls past 100vh. */
    #gameWrap {
        width: 100vw;
        height: auto;
        box-shadow: none;
    }
    /* The slab's bevels belong to the desktop's wooden block; here the game
       is transparent stone-on-stone with no slab to chamfer. */
    #gameWrap::before,
    #gameWrap::after {
        display: none;
    }
    /* No wood and no flat brown here: the game goes transparent so the
       carved-obsidian backdrop on <body> shows through, same stone as the
       desktop surround. min-height rather than height because the action
       trays sit under the board (see #mobileActions) and on short, wide
       screens the page scrolls to reach them. */
    #game {
        display: block;
        min-height: 100vh;
        height: auto;
        width: 100vw;
        background: none;
        padding: 0; /* no slab, no gutter — the bevels are gone here too */
    }
    #titleBar {
        display: none;
    }
    h2 {
        font-size: 2.6vh;
        padding: 0;
    }
    h3 {
        font-size: 2.4vh;
    }
}
