@import url("https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600;700&family=Bricolage+Grotesque:wght@600;700;800&family=IBM+Plex+Mono:wght@500;600&display=swap");

:root {
    color-scheme: dark;
    --night: #0e120f;
    --felt: #171e18;
    --felt-light: #1e271f;
    --ink: #f2e9d6;
    --quiet: #b9b4a5;
    --rule: #3c463d;
    --leaf: #d3e18f;
    --leaf-deep: #a9bb64;
    --rose: #d18b9c;
    --paper: #efe4cb;
    --paper-2: #e5d7ba;
    --paper-3: #dccbab;
    --ink-on-paper: #1c1812;
    --muted-ink: #5d5547;
    --rule-ink: rgba(28, 24, 18, 0.26);
    --oxblood: #9c3c4b;
    --mustard: #d2a23f;
    --indigo: #4d5192;
    --display: "Bricolage Grotesque", "Archivo", sans-serif;
    --body: "Archivo", "Helvetica Neue", sans-serif;
    --mono: "IBM Plex Mono", ui-monospace, monospace;
    --paper-texture: url("img/paper-grain.svg");
}

* {
    box-sizing: border-box;
}

html {
    min-width: 320px;
    background: var(--night);
}

body {
    min-width: 320px;
    min-height: 100vh;
    margin: 0;
    overflow-x: hidden;
    background: var(--night);
    color: var(--ink);
    font-family: var(--body);
    font-size: 15px;
    user-select: none;
}

::selection {
    background: var(--mustard);
    color: var(--ink-on-paper);
}

button {
    font: inherit;
}

button:focus-visible,
.card:focus-visible {
    outline: 2px solid var(--mustard);
    outline-offset: 4px;
}

#FIGMA {
    display: none;
}

#gameScreen {
    position: relative;
    display: flex;
    width: 100%;
    min-height: 100vh;
    min-height: 100svh;
    height: auto !important;
    padding: clamp(18px, 3.5vh, 34px) clamp(14px, 4vw, 58px) 22px;
    flex-direction: column;
    justify-content: space-between;
    gap: 18px;
    overflow: hidden auto;
    isolation: isolate;
    background: radial-gradient(
        120% 95% at 50% 42%,
        #182019 0%,
        var(--night) 72%
    );
}

#gameScreen::before {
    position: absolute;
    z-index: 0;
    inset: 0;
    background:
        url("img/paper-grain.svg") center / 190px repeat,
        url("img/table-swirl.svg") center / cover no-repeat;
    content: "";
    opacity: 0.52;
    pointer-events: none;
}

.cat-scene {
    position: absolute;
    z-index: -1;
    top: 50%;
    right: 0;
    width: min(72vw, 920px);
    height: auto;
    opacity: 0.62;
    pointer-events: none;
    transform: translateY(-50%);
}

.row,
.row2,
#player1 {
    position: relative;
    z-index: 1;
}

.row {
    display: flex;
    width: min(100%, 930px);
    margin: 0 auto;
    justify-content: space-between;
    align-items: flex-start;
    gap: clamp(12px, 3vw, 42px);
}

#opponents {
    display: flex;
    width: 100%;
    justify-content: space-between;
    align-items: flex-start;
    gap: clamp(8px, 1.5vw, 18px);
}

#opponents .hand {
    flex: 1 1 0;
    min-width: 0;
}

.hand {
    position: relative;
    display: flex;
    min-width: 128px;
    min-height: 102px;
    padding: 42px 12px 12px;
    flex-wrap: wrap;
    justify-content: center;
    align-content: center;
    border: 1px dashed rgba(242, 233, 214, 0.24);
    border-radius: 4px;
    background: rgba(14, 18, 15, 0.3);
    transition:
        border-color 0.2s ease,
        background-color 0.2s ease;
}

.hand h2 {
    position: absolute;
    top: 10px;
    left: 11px;
    display: inline-flex;
    min-height: 22px;
    margin: 0;
    padding: 2px 9px 2px 7px;
    align-items: center;
    gap: 6px;
    border: 1px solid var(--ink-on-paper);
    border-radius: 1px;
    background-color: var(--paper);
    background-image: var(--paper-texture);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.34);
    color: var(--ink-on-paper);
    font-family: var(--body);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.14em;
    line-height: 16px;
    /* Long online names must stay inside their own hand: the tab is absolutely
       positioned, so without a cap it spills over the neighbouring seat. */
    max-width: calc(100% - 22px);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-transform: uppercase;
    transform: rotate(-1.4deg);
    transform-origin: 0 50%;
}

#opponents .hand:nth-child(even) h2 {
    transform: rotate(1.1deg);
}

.hand h2 > span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.hand:not(.player) h2::before,
.player h2::before {
    display: inline-block;
    width: 13px;
    height: 13px;
    flex: 0 0 13px;
    background: url("img/cat-mark.svg") center / contain no-repeat;
    content: "";
}

.hand:not(.player) .card {
    width: clamp(28px, 2.7vw, 38px);
    margin: 0 -2px;
    border-radius: 6px;
}

.uno-bubble {
    position: absolute;
    z-index: 3;
    top: -13px;
    right: 8px;
    padding: 6px 10px;
    border: 1px solid rgba(26, 33, 28, 0.16);
    border-radius: 12px 12px 12px 4px;
    background: var(--leaf);
    box-shadow: 0 4px 12px #0005;
    color: #182017;
    font-size: 12px;
    font-weight: 800;
    line-height: 1;
    pointer-events: none;
    animation: uno-bubble-pop 0.2s ease-out both;
}

@keyframes uno-bubble-pop {
    from {
        opacity: 0;
        transform: translateY(4px) scale(0.92);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.hand.turn:not(.player) {
    border-style: solid;
    border-color: rgba(211, 225, 143, 0.8);
    background: rgba(30, 39, 31, 0.78);
}

.hand.turn:not(.player) h2 {
    background-color: var(--leaf);
    color: var(--ink-on-paper);
}
.hand.turn:not(.player) h2::before {
    filter: brightness(1.12);
}

#player1 {
    --hand-border-color: var(--rule);
    width: min(100%, 930px);
    min-height: 164px;
    margin: 0 auto;
    padding: 51px 12px 12px;
    align-content: flex-start;
    border-top: 3px solid var(--hand-border-color);
    border-radius: 0;
    background: linear-gradient(
        180deg,
        rgba(23, 30, 24, 0.94),
        rgba(17, 22, 18, 0.56)
    );
}

#player1 h2 {
    top: 10px;
    left: 12px;
    color: var(--ink-on-paper);
    font-size: 10px;
}

#player1 h2::before {
    background-image: url("img/cat-mark.svg");
}

#player1.turn {
    --hand-border-color: var(--required-color, var(--leaf));
    border-top-color: var(--hand-border-color);
}
#player1.turn h2 {
    background-color: var(--leaf);
    color: var(--ink-on-paper);
}
#player1.canPull {
    --hand-border-color: var(--required-color, var(--rose));
    border-top-color: var(--hand-border-color);
}
#player1.canPull h2 {
    background-color: var(--rose);
    color: var(--ink-on-paper);
}

.player-cards {
    position: relative;
    display: flex;
    width: 100%;
    flex-wrap: wrap;
    justify-content: center;
    align-content: flex-start;
}

.player .card {
    width: clamp(54px, 7vw, 82px);
    margin: 0 2px;
    border: 2px solid transparent;
    border-radius: 9px;
    cursor: pointer;
}

.row2 {
    display: flex;
    width: min(100%, 1160px);
    min-height: 186px;
    margin: auto;
    justify-content: space-between;
    align-items: center;
    gap: clamp(10px, 2.4vw, 30px);
}

.divider {
    display: flex;
    width: min(18%, 208px);
    min-width: 150px;
    justify-content: center;
    align-items: center;
}

#poolCard.card {
    cursor: pointer;
}

#pool,
#throwPool {
    position: relative;
    display: flex;
    width: 120px;
    height: 162px;
    margin: 0;
    justify-content: center;
    align-items: center;
}

#pool.deck-empty {
    visibility: hidden;
    pointer-events: none;
}

#pool::before,
#throwPool::before {
    position: absolute;
    left: 50%;
    top: -25px;
    padding: 3px 7px 2px;
    border: 1px solid var(--ink-on-paper);
    border-radius: 1px;
    background: var(--paper);
    background-image: var(--paper-texture);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
    color: var(--ink-on-paper);
    content: "";
    font-family: var(--body);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.12em;
    line-height: 1.3;
    white-space: nowrap;
    transform: translateX(-50%) rotate(-1.5deg);
    text-transform: uppercase;
    pointer-events: none;
}

#throwPool::before {
    transform: translateX(-50%) rotate(1.2deg);
}

#pool::before {
    content: "scratch pile";
}
#throwPool::before {
    content: "Paw pile";
}

#pool .card,
#throwPool .card {
    width: 94px;
    margin: 0;
    border-radius: 8px;
}

#pool .styleCard,
#throwPool .styleCard {
    position: absolute;
    z-index: 0;
    pointer-events: none;
    transition: none;
}

#pool .styleCard {
    transform: translate(-6px, 4px) rotate(-4deg);
    opacity: 0.56;
}

#throwPool .styleCard {
    transform: translate(-12px, 5px) rotate(-4deg);
    opacity: 0.92;
}

#throwPool #styleCard {
    visibility: hidden;
}

#pool #poolCard {
    position: relative;
    z-index: 1;
}

#pool:not(.draw-disabled) #poolCard {
    outline-offset: 4px;
    animation: legal-card 1.8s ease-in-out infinite;
}

#pool.draw-disabled #poolCard {
    animation: none !important;
}

#throwPool .card:not(.styleCard) {
    position: relative;
    z-index: 1;
}

#throwPool .card {
    pointer-events: none;
    -webkit-user-drag: none;
}

#throwPool.drag-over {
    filter: brightness(0.7);
}

.card {
    display: none;
    filter: saturate(2.9) contrast(1.2);
    transition:
        transform 0.24s cubic-bezier(0.2, 0.8, 0.2, 1),
        filter 0.2s ease;
    -webkit-user-drag: element;
    touch-action: manipulation;
}

.hand .card,
#throwPool .card {
    display: block;
}
#pool #poolCard {
    display: block;
}

.player .card:hover,
#pool .card:hover {
    filter: saturate(2.9) contrast(1.2);
    transform: translateY(-8px) rotate(-1deg);
    animation: hover-card 1.8s ease-in-out infinite;
}

@keyframes hover-card {
    0%,
    100% {
        outline: 2px solid gray;
    }
    50% {
        outline: 2px solid white;
    }
}

.player .card:active,
#pool .card:active {
    filter: saturate(2.9) contrast(1.2) brightness(0.76);
    transform: translateY(-2px);
}

#pool.draw-disabled #poolCard {
    cursor: not-allowed;
}

#pool.draw-disabled #poolCard:hover,
#pool.draw-disabled #poolCard:active {
    filter: saturate(2.9) contrast(1.2);
    transform: none;
}

.throwable {
    outline: 2px solid #c9a13d;
    outline-offset: 2px;
    animation: suggestion-card 1.7s ease-in-out infinite;
}

.suggestion-shine {
    position: absolute;
    z-index: 2;
    overflow: hidden;
    border-radius: 8px;
    mix-blend-mode: screen;
    pointer-events: none;
    transition: transform 0.24s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.player .card:hover + .suggestion-shine {
    transform: translateY(-8px) rotate(-1deg);
}

.player .card:active + .suggestion-shine {
    transform: translateY(-2px);
}

.suggestion-shine::before {
    position: absolute;
    top: -30%;
    bottom: -30%;
    left: -60%;
    width: 45%;
    background: linear-gradient(
        100deg,
        transparent,
        rgba(255, 255, 255, 0.18) 30%,
        rgba(255, 255, 255, 0.9) 50%,
        rgba(255, 255, 255, 0.18) 70%,
        transparent
    );
    content: "";
    transform: translateX(-120%) rotate(12deg);
    animation: suggestion-shine 2.4s ease-in-out infinite;
}

@keyframes suggestion-shine {
    0%,
    15% {
        transform: translateX(-120%) rotate(12deg);
    }
    60%,
    100% {
        transform: translateX(400%) rotate(12deg);
    }
}

#turnBtn,
#newMatchBtn,
#startGameBtn,
#rematchBtn,
#mainMenuBtn {
    display: block;
    min-height: 46px;
    padding: 12px 19px;
    border: 2px solid var(--ink-on-paper);
    border-radius: 3px;
    background: var(--mustard);
    box-shadow: 0 4px 9px rgba(0, 0, 0, 0.28);
    color: var(--ink-on-paper);
    font-family: var(--body);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    cursor: pointer;
    transition:
        color 0.18s ease,
        background-color 0.18s ease,
        transform 0.18s ease,
        box-shadow 0.18s ease;
}

#turnBtn:hover:not(:disabled),
#newMatchBtn:hover,
#startGameBtn:hover,
#rematchBtn:hover,
#mainMenuBtn:hover {
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.24);
    background: #dfb354;
    transform: translateY(2px);
}

#rematchBtn[hidden] {
    display: none;
}

#turnBtn:disabled {
    border-color: rgba(242, 233, 214, 0.2);
    background: transparent;
    box-shadow: none;
    color: #8b8e82;
    cursor: default;
}

#unoBtn {
    position: relative;
    display: inline-flex;
    max-width: 100%;
    min-height: 46px;
    padding: 11px 42px 11px 14px;
    align-items: center;
    justify-content: center;
    border: 1px dashed rgba(242, 233, 214, 0.3);
    border-radius: 3px;
    background: rgba(14, 18, 15, 0.4);
    color: var(--quiet);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    cursor: default;
    transition:
        transform 0.18s ease,
        background-color 0.18s ease,
        border-color 0.18s ease,
        color 0.18s ease;
}

#unoBtn::after {
    position: absolute;
    top: 50%;
    right: 9px;
    width: 22px;
    height: 22px;
    background: url("img/cat-mark.svg") center / contain no-repeat;
    content: "";
    filter: brightness(0) invert(1);
    opacity: 0.36;
    transform: translateY(-50%);
    pointer-events: none;
}

#unoBtn.uno-ready {
    border-style: solid;
    border-color: var(--ink-on-paper);
    background: var(--rose);
    box-shadow: 0 3px 9px rgba(0, 0, 0, 0.3);
    color: var(--ink-on-paper);
    cursor: pointer;
    transform: rotate(-1deg);
}

#unoBtn.uno-ready::after {
    opacity: 0.92;
}

#unoBtn.uno-ready:hover:not(:disabled) {
    border-color: var(--ink-on-paper);
    background: #e0a0b0;
    transform: translateY(-2px) rotate(-1deg);
}
#unoBtn:disabled {
    color: #94978a;
    cursor: default;
}

#messageBox {
    width: fit-content;
    max-width: 220px;
    padding: 10px 13px 9px;
    border: 1px solid var(--ink-on-paper);
    border-radius: 2px;
    background: var(--paper);
    background-image: var(--paper-texture);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
    color: var(--ink-on-paper);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.45;
    text-align: center;
    transform: rotate(-0.6deg);
    transition:
        opacity 0.2s ease,
        scale 0.2s ease;
}

.colorPicker {
    position: fixed;
    z-index: 10;
    top: 50%;
    left: 50%;
    display: flex;
    width: min(350px, calc(100vw - 32px));
    padding: 22px 23px 24px;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;
    border: 2px solid var(--ink-on-paper);
    border-radius: 3px;
    background: var(--paper);
    background-image: var(--paper-texture);
    box-shadow:
        0 3px 8px rgba(0, 0, 0, 0.24),
        0 22px 66px #0009;
    transform: translate(-50%, -50%);
    scale: 0;
    transition: scale 0.22s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.colorPicker h2 {
    width: 100%;
    margin: 0 0 6px;
    color: var(--ink-on-paper);
    font-family: var(--display);
    font-size: 24px;
    font-weight: 700;
    letter-spacing: -0.02em;
    text-align: center;
}

.color {
    width: 60px;
    height: 60px;
    padding: 0;
    border: 2px solid var(--ink-on-paper);
    border-radius: 50%;
    cursor: pointer;
    box-shadow: inset 0 0 0 4px var(--paper);
    transition: transform 0.16s ease;
}

.color:hover {
    transform: scale(1.08);
    outline: 2px solid var(--ink-on-paper);
    outline-offset: 2px;
}
.red.color {
    background: #d24d64 !important;
}
.blue.color {
    background: #7d91d4 !important;
}
.green.color {
    background: #82bb77 !important;
}
.purple.color {
    background: #b067a7 !important;
}

.message-color.red {
    color: #a32f42;
}
.message-color.blue {
    color: #3e56a3;
}
.message-color.green {
    color: #3c7544;
}
.message-color.purple {
    color: #88377e;
}

#newMatchScreen {
    position: fixed;
    z-index: 20;
    inset: 0;
    display: flex;
    padding: 28px 20px;
    flex-direction: column;
    justify-content: safe center;
    align-items: center;
    overflow: hidden auto;
    background:
        url("img/paper-grain.svg") center / 190px repeat,
        radial-gradient(120% 90% at 50% 38%, #1a241c 0%, var(--night) 70%);
}

#newMatchScreen::before {
    position: absolute;
    left: 50%;
    bottom: -4%;
    width: min(92vw, 980px);
    aspect-ratio: 920 / 560;
    background: url("img/cat-table.svg") center / contain no-repeat;
    content: "";
    opacity: 0.82;
    pointer-events: none;
    transform: translateX(-50%);
}
.card {
    box-shadow: -2px 0 10px black;
}

#catsIMG {
    position: absolute;
    left: 0;
    z-index: 100;
    width: 8rem;
    opacity: 0.42;
    filter: invert();
    user-select: none;
    -webkit-user-drag: none;
}
#newMatchScreen > * {
    position: relative;
    z-index: 1;
}

@media (max-width: 760px), (pointer: coarse) {
    #newMatchScreen {
        justify-content: flex-start;
        padding: max(20px, env(safe-area-inset-top))
            max(14px, env(safe-area-inset-right))
            max(28px, env(safe-area-inset-bottom))
            max(14px, env(safe-area-inset-left));
        overscroll-behavior-y: contain;
    }

    #newMatchScreen > * {
        flex-shrink: 0;
    }
}

.logo {
    display: block;
    width: 68px;
    height: 68px;
    margin: 0 auto 14px;
    padding: 9px;
    border: 2px solid var(--ink-on-paper);
    border-radius: 50%;
    background: var(--paper);
    box-shadow:
        0 3px 8px rgba(0, 0, 0, 0.22),
        0 10px 24px rgba(0, 0, 0, 0.28);
    transform: rotate(-5deg);
}

.menu-title {
    margin: 0;
    color: var(--ink);
    font-family: var(--display);
    font-size: clamp(48px, 8vw, 78px);
    font-weight: 800;
    letter-spacing: -0.045em;
    line-height: 0.92;
    text-shadow: 3px 3px 0 rgba(156, 60, 75, 0.55);
}

.menu-caption {
    margin: 12px 0 0;
    color: var(--quiet);
    font-size: 14px;
    letter-spacing: 0.01em;
}

.online-panel {
    width: min(560px, 100%);
    margin-top: 26px;
    padding: 18px 20px 20px;
    border: 2px solid var(--ink-on-paper);
    border-radius: 3px;
    background: var(--paper);
    background-image: var(--paper-texture);
    box-shadow:
        0 3px 8px rgba(0, 0, 0, 0.24),
        0 18px 38px rgba(0, 0, 0, 0.32);
    color: var(--ink-on-paper);
    text-align: left;
    transform: rotate(-0.45deg);
    animation: paper-settle 0.42s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

.online-panel h2 {
    margin: 0 0 12px;
    color: var(--ink-on-paper);
    font-family: var(--display);
    font-size: 24px;
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.05;
}

.online-heading {
    display: flex;
    margin-bottom: 12px;
    padding-bottom: 9px;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    border-bottom: 1px dashed var(--rule-ink);
}

/* Beat the short-window `.online-panel h2` margin rules. */
.online-panel .online-heading h2 {
    margin: 0;
}

.online-panel #showWinsBtn {
    min-height: 0;
    padding: 2px 0;
    border: 0;
    border-bottom: 1px solid var(--ink-on-paper);
    border-radius: 0;
    background: transparent;
    color: var(--ink-on-paper);
    font-family: var(--body);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.online-panel #showWinsBtn:hover:not(:disabled) {
    border-color: var(--oxblood);
    background: transparent;
    color: var(--oxblood);
}

.online-panel > label {
    display: block;
    margin-bottom: 6px;
    color: var(--muted-ink);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

#onlineName {
    width: 100%;
    min-height: 40px;
    margin-bottom: 10px;
}

.online-panel input {
    min-width: 0;
    padding: 9px 10px;
    border: 1.5px solid var(--ink-on-paper);
    border-radius: 2px;
    background: var(--paper-2);
    color: var(--ink-on-paper);
}

.online-panel input::placeholder {
    color: #6f5a3a;
    opacity: 1;
}

.online-panel input:focus-visible,
.opponent-settings select:focus-visible,
#opponentNames input:focus-visible {
    outline: 2px solid var(--oxblood);
    outline-offset: 2px;
}

.online-create-option > p {
    margin: 7px 0 0;
    color: var(--muted-ink);
    font-size: 12px;
}

.online-create-option #createRoomBtn {
    width: 100%;
    min-height: 46px;
    border: 2px solid var(--ink-on-paper);
    border-radius: 3px;
    background: var(--mustard);
    box-shadow: 0 3px 8px rgba(0, 0, 0, 0.24);
    color: var(--ink-on-paper);
}

.online-create-option #createRoomBtn:hover:not(:disabled) {
    background: #dfb354;
}

/* While the room is being created the button shows the cat mark spinning,
   like a cat chasing its own tail while it waits for the table to clear. */
.online-create-option #createRoomBtn.is-loading {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    background: var(--mustard);
    cursor: progress;
    opacity: 1;
}

.online-create-option #createRoomBtn.is-loading::before {
    width: 17px;
    height: 17px;
    flex: none;
    background: url("img/cat-mark.svg") center / contain no-repeat;
    content: "";
    animation: cat-fidget 0.9s linear infinite;
}

@keyframes cat-fidget {
    from {
        transform: rotate(0deg) scale(1);
    }

    50% {
        transform: rotate(180deg) scale(0.87);
    }

    to {
        transform: rotate(360deg) scale(1);
    }
}

@media (prefers-reduced-motion: reduce) {
    .online-create-option #createRoomBtn.is-loading::before {
        animation-duration: 3s;
    }
}

.online-divider {
    display: flex;
    margin: 15px 0 12px;
    align-items: center;
    gap: 12px;
    color: var(--muted-ink);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.12em;
}

.online-divider::before,
.online-divider::after {
    height: 0;
    flex: 1;
    border-top: 1px dashed var(--rule-ink);
    background: none;
    content: "";
}

.online-join-option > label {
    display: block;
    margin-bottom: 6px;
    color: var(--muted-ink);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.online-join-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 8px;
}

#roomCode {
    width: 100%;
    font-family: var(--mono);
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

.online-panel button {
    min-height: 40px;
    padding: 8px 12px;
    border: 1.5px solid var(--ink-on-paper);
    border-radius: 2px;
    background: var(--paper-2);
    color: var(--ink-on-paper);
    font-family: var(--body);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    cursor: pointer;
}

.online-panel button:hover:not(:disabled) {
    border-color: var(--ink-on-paper);
    background: var(--paper-3);
}

.online-panel button:disabled {
    color: #8a8171;
    cursor: default;
    opacity: 0.7;
}

#onlineStatus {
    min-height: 18px;
    margin: 10px 0 0;
    color: var(--muted-ink);
    font-size: 12px;
}

#onlineLobby > p {
    margin: 13px 0 7px;
    color: var(--muted-ink);
    font-size: 12px;
}

.room-code-row {
    display: flex;
    align-items: center;
    gap: 10px;
}

#roomCodeDisplay {
    color: var(--ink-on-paper);
    font-family: var(--mono);
    font-size: 24px;
    font-weight: 600;
    letter-spacing: 0.18em;
}

#onlinePlayers {
    display: flex;
    margin: 8px 0 12px;
    padding: 0;
    flex-wrap: wrap;
    gap: 6px;
    list-style: none;
}

#onlinePlayers li {
    padding: 5px 9px;
    border: 1px solid var(--rule-ink);
    border-radius: 2px;
    background: var(--paper-2);
    color: var(--ink-on-paper);
    font-size: 12px;
}

.local-panel {
    position: relative;
    width: min(760px, 100%);
    margin-top: 32px;
    transform: rotate(0.45deg);
    animation: paper-settle 0.46s cubic-bezier(0.2, 0.8, 0.2, 1) 0.06s both;
}

.local-match-label {
    position: absolute;
    z-index: 2;
    top: -14px;
    left: 14px;
    margin: 0;
    padding: 5px 10px 4px;
    border: 1.5px solid var(--ink-on-paper);
    border-radius: 3px;
    background: var(--paper-2);
    background-image: var(--paper-texture);
    color: var(--ink-on-paper);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    transform: rotate(-0.8deg);
}

.match-settings {
    display: grid;
    width: 100%;
    margin: 0;
    padding: 18px 20px 20px;
    border: 2px solid var(--ink-on-paper);
    border-radius: 3px;
    background: var(--paper);
    background-image: var(--paper-texture);
    box-shadow:
        0 3px 8px rgba(0, 0, 0, 0.24),
        0 18px 38px rgba(0, 0, 0, 0.32);
    color: var(--ink-on-paper);
    grid-template-columns: minmax(0, 1.1fr) minmax(230px, 0.9fr);
    gap: 14px 26px;
    text-align: left;
}

.opponent-settings,
.game-options {
    display: grid;
    align-content: start;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
    color: var(--ink-on-paper);
}

.opponent-settings {
    grid-template-columns: minmax(0, 1fr) minmax(130px, 0.85fr);
    gap: 10px 12px;
}

.game-options {
    padding-left: 26px;
    border-left: 1px dashed var(--rule-ink);
    gap: 5px;
}

.opponent-settings h2,
.game-options h2 {
    margin: 0 0 4px;
    color: var(--ink-on-paper);
    font-family: var(--display);
    font-size: 20px;
    font-weight: 700;
    letter-spacing: -0.015em;
}

.opponent-settings h2 {
    grid-column: 1 / -1;
}

.opponent-settings > label {
    align-self: center;
    color: var(--muted-ink);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.game-options h2 {
    margin-bottom: 7px;
}

.game-options-note {
    margin: -2px 0 6px;
    color: var(--muted-ink);
    font-size: 12px;
    line-height: 1.4;
}

.switch-row {
    display: flex;
    min-height: 58px;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    border-top: 1px dashed var(--rule-ink);
    cursor: pointer;
}

.switch-row span {
    display: grid;
    gap: 2px;
}

.switch-row strong {
    color: var(--ink-on-paper);
    font-size: 12.5px;
}

.switch-row small {
    color: var(--muted-ink);
    font-size: 12px;
}

.switch-row input[type="checkbox"] {
    position: relative;
    width: 26px;
    height: 26px;
    flex: 0 0 26px;
    margin: 0;
    appearance: none;
    border: 2px solid var(--ink-on-paper);
    border-radius: 1px;
    background: var(--paper-2);
    cursor: pointer;
    transition:
        background-color 0.18s ease,
        border-color 0.18s ease;
}

.switch-row input[type="checkbox"]::before {
    position: absolute;
    top: 2px;
    left: 5px;
    width: 8px;
    height: 13px;
    border: solid var(--paper);
    border-width: 0 3px 3px 0;
    background: none;
    content: "";
    opacity: 0;
    transform: rotate(40deg) scale(0.6);
    transition:
        opacity 0.16s ease,
        transform 0.16s ease;
}

.switch-row input[type="checkbox"]:checked {
    border-color: var(--ink-on-paper);
    background: var(--ink-on-paper);
}

.switch-row input[type="checkbox"]:checked::before {
    opacity: 1;
    transform: rotate(40deg) scale(1);
}

.switch-row input[type="checkbox"]:focus-visible {
    outline: 2px solid var(--oxblood);
    outline-offset: 3px;
}

#opponentNames {
    display: grid;
    grid-column: 1 / -1;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 7px 12px;
}

#opponentNames label {
    color: var(--muted-ink);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.opponent-settings select,
#opponentNames input {
    width: 100%;
    min-height: 42px;
    padding: 7px 9px;
    border: 1.5px solid var(--ink-on-paper);
    border-radius: 2px;
    background: var(--paper-2);
    color: var(--ink-on-paper);
    font: inherit;
}

#opponentNames label {
    white-space: nowrap;
}

@media (max-width: 640px) {
    #catsIMG {
        display: none;
    }

    .online-join-row {
        grid-template-columns: minmax(0, 1fr);
    }

    #roomCode {
        min-height: 42px;
    }

    .match-settings {
        padding: 16px 16px 18px;
        grid-template-columns: 1fr;
        gap: 14px;
    }

    .game-options {
        padding-top: 14px;
        padding-right: 0;
        padding-left: 0;
        border-top: 1px dashed var(--rule-ink);
        border-left: 0;
    }

    .opponent-settings {
        padding-right: 0;
        padding-left: 0;
    }
}

/* Two paper slips on the table once there is room: online play and the local
   table. Keeps the start button above the fold on laptop screens. */
@media (min-width: 900px) {
    #newMatchScreen {
        display: grid;
        padding: 26px clamp(24px, 4vw, 64px);
        grid-template-columns: minmax(0, 0.94fr) minmax(0, 1.06fr);
        grid-template-areas:
            "logo logo"
            "title title"
            "caption caption"
            "online local"
            "start start";
        align-content: safe center;
        justify-content: center;
        align-items: start;
        column-gap: clamp(20px, 2.6vw, 40px);
        row-gap: 0;
    }

    #newMatchScreen > .logo {
        grid-area: logo;
        justify-self: center;
    }

    #newMatchScreen > .menu-title {
        grid-area: title;
        justify-self: center;
    }

    #newMatchScreen > .menu-caption {
        grid-area: caption;
        justify-self: center;
    }

    #newMatchScreen > .online-panel {
        grid-area: online;
        justify-self: end;
        width: 100%;
        max-width: 560px;
    }

    #newMatchScreen > .local-panel {
        grid-area: local;
        justify-self: start;
        width: 100%;
        max-width: 760px;
    }

    #newMatchScreen > #startGameBtn {
        grid-area: start;
        justify-self: center;
        margin-top: 24px;
    }
}

/* At the narrow end of the two-panel grid the local card's label column
   collapses to a few pixels, so stack each label above its field. */
@media (min-width: 900px) and (max-width: 1000px) {
    .opponent-settings {
        grid-template-columns: minmax(0, 1fr);
    }

    .opponent-settings h2 {
        grid-column: auto;
    }

    .opponent-settings > label {
        margin-top: 2px;
    }

    #opponentNames {
        grid-template-columns: minmax(0, 1fr);
    }

    #opponentNames label {
        margin-top: 2px;
    }
}

/* Short desktop windows (e.g. 1440x900) must still show the start button
   without scrolling. Tighten the menu's vertical rhythm instead of clipping. */
@media (min-width: 761px) and (max-height: 960px) {
    #newMatchScreen {
        padding: 14px 20px;
    }

    .logo {
        width: 54px;
        height: 54px;
        margin-bottom: 8px;
        padding: 7px;
    }

    .menu-title {
        font-size: clamp(40px, 5.2vw, 58px);
    }

    .menu-caption {
        margin-top: 5px;
    }

    .online-panel {
        margin-top: 18px;
        padding: 12px 16px 14px;
    }

    .online-panel h2 {
        margin-bottom: 8px;
        font-size: 21px;
    }

    #onlineName {
        min-height: 36px;
        margin-bottom: 7px;
    }

    .online-create-option #createRoomBtn {
        min-height: 40px;
    }

    .online-divider {
        margin: 10px 0 8px;
    }

    #onlineStatus {
        min-height: 16px;
        margin-top: 7px;
    }

    .local-panel {
        margin-top: 28px;
    }

    .local-match-label {
        top: -12px;
    }

    .match-settings {
        margin: 0;
        padding: 14px 16px 16px;
    }

    #startGameBtn {
        margin-top: 18px;
    }
}

/* 720p/768p laptops still need the primary Start button above the fold, so
   tighten the same rhythm one more step on very short desktop windows. */
@media (min-width: 761px) and (max-height: 840px) {
    #newMatchScreen {
        padding: 10px 20px;
    }

    .logo {
        width: 44px;
        height: 44px;
        margin-bottom: 5px;
        padding: 6px;
    }

    .menu-title {
        font-size: clamp(34px, 4vw, 46px);
    }

    .menu-caption {
        margin-top: 3px;
        font-size: 13px;
    }

    .online-panel {
        margin-top: 14px;
        padding: 10px 14px 12px;
    }

    .online-panel h2 {
        margin-bottom: 6px;
        font-size: 19px;
    }

    .online-panel button {
        min-height: 34px;
        padding: 6px 10px;
    }

    #onlineName {
        min-height: 32px;
        margin-bottom: 5px;
    }

    .online-create-option #createRoomBtn {
        min-height: 34px;
    }

    .online-create-option > p {
        margin-top: 5px;
        font-size: 12px;
    }

    .online-divider {
        margin: 8px 0 6px;
    }

    #roomCode {
        min-height: 34px;
    }

    #onlineStatus {
        min-height: 14px;
        margin-top: 5px;
    }

    .local-panel {
        margin-top: 26px;
    }

    .local-match-label {
        top: -12px;
        padding: 4px 8px 3px;
    }

    .match-settings {
        margin: 0;
        padding: 11px 14px 12px;
        gap: 10px;
    }

    .opponent-settings {
        gap: 7px 10px;
    }

    .game-options {
        padding-top: 11px;
        padding-right: 0;
        padding-left: 18px;
        border-top: 0;
        border-left: 1px dashed var(--rule-ink);
    }

    .opponent-settings select,
    #opponentNames input {
        min-height: 33px;
    }

    .switch-row {
        min-height: 44px;
    }

    .game-options h2 {
        margin-bottom: 5px;
        font-size: 17px;
    }

    .game-options-note {
        margin-bottom: 2px;
        font-size: 12px;
    }

    #startGameBtn {
        margin-top: 14px;
        min-height: 44px;
    }
}

#newMatchBtn,
#startGameBtn {
    min-width: 220px;
}

#startGameBtn {
    min-height: 54px;
    padding: 15px 30px;
    border-width: 2px;
    box-shadow:
        0 3px 8px rgba(0, 0, 0, 0.3),
        0 14px 30px rgba(0, 0, 0, 0.3);
    font-size: 13px;
    letter-spacing: 0.13em;
}

#startGameBtn:hover {
    box-shadow:
        0 2px 6px rgba(0, 0, 0, 0.24),
        0 8px 18px rgba(0, 0, 0, 0.24);
}

#endScreen {
    position: fixed;
    z-index: 100;
    inset: 0;
    display: flex;
    width: 100%;
    height: 100%;
    padding: 24px 16px;
    align-items: safe center;
    justify-content: center;
    overflow-y: auto;
    background:
        url("img/paper-grain.svg") center / 190px repeat,
        radial-gradient(120% 90% at 50% 40%, #1a241c 0%, var(--night) 72%);
    animation: fade-in 0.32s ease both;
}

.result-slip {
    width: min(460px, 100%);
    margin: auto;
    padding: 28px 26px 24px;
    border: 2px solid var(--ink-on-paper);
    border-radius: 3px;
    background: var(--paper);
    background-image: var(--paper-texture);
    box-shadow:
        0 3px 8px rgba(0, 0, 0, 0.24),
        0 26px 60px rgba(0, 0, 0, 0.44);
    color: var(--ink-on-paper);
    text-align: center;
    transform: rotate(-0.6deg);
    animation: paper-settle 0.42s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

#endScreen h1 {
    margin: 0 0 20px;
    color: var(--ink-on-paper);
    font-family: var(--display);
    font-size: clamp(40px, 8vw, 58px);
    font-weight: 800;
    letter-spacing: -0.04em;
    line-height: 0.9;
    text-align: center;
    text-shadow: 2px 2px 0 rgba(156, 60, 75, 0.45);
}

.leaderboard {
    width: 100%;
    margin: 0 auto 20px;
    padding: 14px 0 6px;
    border: 0;
    border-top: 1px dashed var(--rule-ink);
    border-radius: 0;
    background: none;
    color: var(--ink-on-paper);
    text-align: center;
}

.leaderboard > h2 {
    margin: 0 0 12px;
    color: var(--muted-ink);
    font-family: var(--body);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

.leaderCard {
    display: flex;
    margin: 0;
    padding: 10px 4px;
    justify-content: space-evenly;
    align-items: center;
    border: 0;
    border-bottom: 1px dashed var(--rule-ink);
    border-radius: 0;
    background: none;
    color: var(--ink-on-paper);
}

.leaderCard:last-child {
    border-bottom: 0;
}

.leaderCardPlayer {
    border-color: var(--rule-ink);
    background: rgba(210, 162, 63, 0.24);
}
.leaderCard h3,
.leaderCard p {
    margin: 3px;
}
.leaderCard h3 {
    font-family: var(--display);
    font-size: 18px;
    font-weight: 700;
}
.leaderCard p {
    color: var(--muted-ink);
    font-size: 12px;
}
.placement {
    margin: 0;
    padding-right: 16px;
    border-right: 1px dashed var(--rule-ink);
    font-family: var(--mono);
    font-size: 13px;
}
.end-actions {
    display: flex;
    justify-content: center;
    gap: 10px;
    margin: 4px auto 0;
}

#mainMenuBtn,
#rematchBtn {
    margin: 0;
}

#mainMenuBtn {
    min-width: 0;
    border-color: var(--ink-on-paper);
    background: transparent;
    box-shadow: none;
    color: var(--ink-on-paper);
}

#mainMenuBtn:hover {
    background: var(--paper-3);
    box-shadow: none;
}

.wins-dialog {
    position: fixed;
    z-index: 120;
    inset: 0;
    display: flex;
    padding: 20px;
    align-items: center;
    justify-content: center;
    background: rgba(8, 11, 9, 0.84);
}

.wins-dialog[hidden] {
    display: none;
}

.wins-card {
    width: min(440px, 100%);
    max-height: min(82vh, 580px);
    padding: 22px 24px;
    overflow: auto;
    border: 2px solid var(--ink-on-paper);
    border-radius: 3px;
    background: var(--paper);
    background-image: var(--paper-texture);
    box-shadow:
        0 3px 8px rgba(0, 0, 0, 0.26),
        0 26px 70px rgba(0, 0, 0, 0.55);
    color: var(--ink-on-paper);
    text-align: left;
    transform: rotate(0.4deg);
    animation: paper-settle 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

.wins-heading {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
    padding-bottom: 12px;
    border-bottom: 1px dashed var(--rule-ink);
}

.wins-heading h2 {
    margin: 0;
    color: var(--ink-on-paper);
    font-family: var(--display);
    font-size: 26px;
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1;
}

.wins-heading p {
    margin: 5px 0 0;
    color: var(--muted-ink);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.11em;
    text-transform: uppercase;
}

#closeWinsBtn {
    width: 34px;
    height: 34px;
    flex: none;
    border: 1.5px solid var(--ink-on-paper);
    border-radius: 2px;
    background: transparent;
    color: var(--ink-on-paper);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}

#closeWinsBtn:hover {
    background: var(--paper-3);
}

#winsList {
    display: grid;
    margin: 12px 0 0;
    padding: 0;
    gap: 0;
    list-style: none;
}

#winsList li {
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr) auto;
    padding: 10px 4px;
    align-items: center;
    gap: 10px;
    border-bottom: 1px dashed var(--rule-ink);
    border-radius: 0;
    background: none;
}

#winsList li:nth-child(-n + 3) {
    background: none;
}

#winsList li:first-child {
    background: rgba(210, 162, 63, 0.22);
}

.wins-rank {
    color: var(--muted-ink);
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 600;
    text-align: center;
}

.wins-name {
    overflow: hidden;
    color: var(--ink-on-paper);
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.wins-count {
    color: var(--oxblood);
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
}

#winsStatus {
    min-height: 16px;
    margin: 12px 0 0;
    color: var(--muted-ink);
    font-size: 12px;
}

@media (max-width: 640px) {
    .wins-dialog {
        padding: 12px;
    }

    .wins-card {
        max-height: 88vh;
        padding: 18px;
    }
}

.animatedCard {
    display: block;
    position: fixed;
    z-index: 95;
    width: 70px;
    border-radius: 8px;
    pointer-events: none;
}

@keyframes turn-beat {
    0%,
    100% {
        opacity: 1;
        transform: scale(1);
    }
    50% {
        opacity: 0.5;
        transform: scale(0.76);
    }
}

@keyframes legal-card {
    0%,
    100% {
        outline: 2px solid grey;
    }
    50% {
        outline: 2px solid white;
    }
}

@keyframes suggestion-card {
    0%,
    100% {
        outline-color: #c9a13d;
    }
    50% {
        outline-color: #ffe6a3;
    }
}

@keyframes fade-in {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

/* A paper slip dropped onto the table: settles without fighting the
   element's own rotation. */
@keyframes paper-settle {
    from {
        opacity: 0;
        translate: 0 10px;
        scale: 0.98;
    }
    to {
        opacity: 1;
        translate: 0 0;
        scale: 1;
    }
}

@media (max-width: 760px) {
    #opponents {
        flex-wrap: wrap;
        justify-content: center;
    }

    #opponents .hand {
        flex: 1 1 28%;
    }

    #gameScreen {
        min-height: 100svh;
        padding: 16px 12px;
        gap: 14px;
    }
    .cat-scene {
        top: 67%;
        right: 0;
        width: 100vw;
        opacity: 0.24;
    }
    .row {
        gap: 8px;
    }
    .hand:not(.player) {
        width: 32%;
        min-width: 0;
        min-height: 95px;
        padding: 39px 5px 9px;
    }
    .hand:not(.player) h2 {
        left: 7px;
        gap: 5px;
        font-size: 11px;
    }
    .hand:not(.player) h2::before {
        width: 13px;
        height: 13px;
        flex-basis: 13px;
    }
    .hand:not(.player) .card {
        width: clamp(25px, 6vw, 36px);
        margin: 0 -4px;
    }
    .hand.turn:not(.player)::after {
        right: 8px;
        top: 17px;
        width: 6px;
        height: 6px;
    }
    .row2 {
        display: grid;
        width: min(100%, 460px);
        min-height: 0;
        margin: auto;
        grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
        grid-template-rows: auto auto auto;
        justify-items: center;
        gap: 16px 8px;
        padding: 18px 0;
    }
    #pool {
        grid-column: 1;
        grid-row: 1;
    }
    #turnBtn {
        grid-column: 2;
        grid-row: 1;
    }
    #throwPool {
        grid-column: 3;
        grid-row: 1;
    }
    #pool,
    #throwPool {
        width: 92px;
        height: 128px;
    }
    #pool .card,
    #throwPool .card {
        width: 72px;
    }
    .row2 .divider:first-child {
        grid-column: 1 / -1;
        grid-row: 2;
        width: 100%;
    }
    .row2 .divider:last-child {
        grid-column: 1 / -1;
        grid-row: 3;
        width: 100%;
    }
    #messageBox {
        max-width: 280px;
    }
    #player1 {
        min-height: 142px;
        padding: 49px 4px 10px;
    }
    #player1 h2 {
        left: 7px;
    }
    .player .card {
        width: clamp(43px, 10vw, 64px);
        margin: 0 1px;
        border-radius: 7px;
    }
    #unoBtn,
    #turnBtn {
        min-height: 48px;
    }
}

@media (max-width: 760px), (pointer: coarse) {
    html,
    body {
        width: 100%;
        height: 100%;
        min-width: 0;
        min-height: 0;
        overflow: hidden;
        overscroll-behavior: none;
    }

    #gameScreen {
        width: 100%;
        height: 100vh !important;
        height: 100dvh !important;
        min-height: 0;
        overflow: hidden;
    }

    #endScreen {
        /* The results slip can be taller than a short phone screen (six seats),
           so the overlay itself must remain scrollable or the action buttons
           are clipped out of reach. */
        overflow-y: auto;
    }
}

@media (max-width: 760px) and (max-height: 720px),
    (pointer: coarse) and (max-height: 720px) {
    #gameScreen {
        gap: 4px;
        padding: 8px 10px;
    }

    .hand:not(.player) {
        min-height: clamp(64px, 14vh, 88px);
        padding-top: clamp(28px, 5vh, 36px);
        padding-bottom: 6px;
    }

    .row2 {
        gap: clamp(6px, 1.4vh, 10px) 8px;
        padding: 8px 0;
    }

    #pool,
    #throwPool {
        height: clamp(100px, 22vh, 122px);
    }

    #player1 {
        min-height: clamp(106px, 20vh, 128px);
        padding-top: 40px;
        padding-bottom: 8px;
    }
}

@media (pointer: coarse) {
    html,
    body,
    body * {
        -webkit-tap-highlight-color: transparent;
        -webkit-touch-callout: none;
        -webkit-user-select: none;
        user-select: none;
    }

    img {
        -webkit-user-drag: none;
    }

    .card {
        touch-action: manipulation;
    }
}

@media (max-width: 390px) {
    .hand:not(.player) h2 {
        font-size: 11px;
    }
    .hand:not(.player) .card {
        width: 24px;
        margin: 0 -5px;
    }
    #pool,
    #throwPool {
        width: 82px;
        height: 116px;
    }
    #pool .card,
    #throwPool .card {
        width: 66px;
    }
    #turnBtn {
        padding: 11px 12px;
        font-size: 12px;
    }
    #player1 {
        padding-right: 2px;
        padding-left: 2px;
    }
    .player .card {
        width: clamp(39px, 10.6vw, 50px);
        margin: 0;
    }
}

@media (max-width: 350px) and (orientation: portrait) {
    #gameScreen {
        padding-right: 10px;
        padding-left: 10px;
    }

    .row {
        gap: 5px;
    }

    .hand:not(.player) {
        min-height: 74px;
        padding: 34px 3px 6px;
        flex-wrap: nowrap;
        overflow: hidden;
    }

    .hand:not(.player) h2 {
        left: 5px;
        font-size: 11px;
    }

    .hand:not(.player) .card {
        width: 18px;
        margin: 0 -4px;
        flex: 0 0 18px;
    }
}

@media (max-height: 680px) and (min-width: 761px) {
    #gameScreen {
        min-height: 680px;
        gap: 14px;
    }
    .row2 {
        min-height: 162px;
    }
    .hand:not(.player) {
        min-height: 92px;
    }
    #player1 {
        min-height: 148px;
    }
}

@media (max-width: 900px) and (max-height: 520px) {
    #gameScreen {
        min-height: 100svh;
        padding: 8px 14px;
        gap: 6px;
    }

    .cat-scene {
        display: none;
    }

    .row {
        width: 100%;
        gap: 8px;
    }

    .hand:not(.player) {
        min-height: 64px;
        padding: 25px 5px 5px;
    }

    .hand:not(.player) h2 {
        top: 4px;
        left: 7px;
        min-height: 20px;
        padding: 1px 7px;
        font-size: 11px;
    }

    .hand:not(.player) .card {
        width: clamp(18px, 2.8vw, 24px);
        margin: 0 -3px;
    }

    .row2 {
        display: grid;
        width: min(100%, 760px);
        min-height: 0;
        margin: 0 auto;
        padding: 8px 0;
        grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
        grid-template-rows: auto auto;
        justify-items: center;
        gap: 6px 10px;
    }

    #pool,
    #throwPool {
        width: clamp(72px, 10vw, 90px);
        height: clamp(96px, 28vh, 110px);
    }

    #pool .card,
    #throwPool .card {
        width: clamp(54px, 7.4vw, 70px);
    }

    .row2 .divider:first-child {
        width: 100%;
        min-width: 0;
        grid-column: 1;
        grid-row: 2;
    }

    .row2 .divider:last-child {
        width: 100%;
        min-width: 0;
        grid-column: 3;
        grid-row: 2;
    }

    #unoBtn {
        min-height: 44px;
        padding: 8px 10px;
        font-size: 11px;
    }

    #messageBox {
        max-width: 100%;
        padding: 8px 9px;
        font-size: 12px;
    }

    #turnBtn {
        min-height: 44px;
        padding: 9px 12px;
        font-size: 12px;
    }

    #player1 {
        min-height: 100px;
        padding: 34px 8px 6px;
    }

    #player1 h2 {
        top: 7px;
        left: 8px;
        font-size: 11px;
    }

    .player .card {
        width: clamp(34px, 4.5vw, 44px);
        margin: 0 1px;
    }
}

@media (max-width: 760px), (pointer: coarse) {
    html,
    body {
        width: 100%;
        height: auto;
        min-width: 0;
        min-height: 100%;
        overflow-x: hidden;
        overflow-y: auto;
        overscroll-behavior-y: contain;
    }

    #gameScreen {
        width: 100%;
        height: auto !important;
        min-height: 100vh;
        min-height: 100dvh;
        padding: max(14px, env(safe-area-inset-top))
            max(12px, env(safe-area-inset-right))
            max(16px, env(safe-area-inset-bottom))
            max(12px, env(safe-area-inset-left));
        gap: clamp(12px, 2.2vh, 20px);
        overflow: visible;
    }

    .row {
        width: 100%;
        align-items: stretch;
    }

    #opponents {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(min(100%, 104px), 1fr));
        align-items: stretch;
        gap: 8px;
    }

    #opponents .hand {
        width: auto;
        min-width: 0;
        min-height: clamp(76px, 10dvh, 92px);
        padding: clamp(30px, 4.2dvh, 38px) 5px 7px;
        overflow: hidden;
    }

    #opponents .hand h2 {
        top: 7px;
        left: 8px;
        min-height: 20px;
        padding: 1px 8px 1px 6px;
        max-width: calc(100% - 16px);
        overflow: hidden;
        font-size: 11px;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    #opponents .hand .card {
        width: clamp(26px, 7vw, 36px);
        flex: 0 0 auto;
        margin: 0 -4px;
    }

    #player1 {
        width: 100%;
        min-height: clamp(158px, 24dvh, 196px);
        padding: clamp(40px, 5dvh, 48px) 10px 10px;
        overflow: hidden;
        border-radius: 0;
    }

    #player1 h2 {
        top: 13px;
        left: 11px;
        z-index: 4;
    }

    #player1.has-more-cards::after {
        position: absolute;
        z-index: 3;
        right: 10px;
        bottom: 8px;
        display: flex;
        width: max-content;
        height: 28px;
        padding: 0 8px;
        align-items: center;
        justify-content: flex-end;
        border: 1px solid rgba(238, 233, 221, 0.12);
        border-radius: 14px;
        background: rgba(32, 42, 34, 0.96);
        color: var(--ink);
        content: "Swipe  ›";
        font-size: 11px;
        font-weight: 700;
        letter-spacing: 0.02em;
        pointer-events: none;
        animation: swipe-cue-nudge 1.1s ease-in-out infinite;
        translate: 0;
    }

    @keyframes swipe-cue-nudge {
        0%,
        100% {
            translate: 0;
        }
        50% {
            translate: 3px;
        }
    }

    #playerCards {
        min-width: 0;
        height: auto;
        min-height: 130px;
        padding: 5px 6px;
        flex-wrap: nowrap;
        justify-content: flex-start;
        align-items: center;
        overflow-x: auto;
        overflow-y: hidden;
        overscroll-behavior-x: contain;
        scrollbar-width: none;
    }

    #playerCards .card {
        width: clamp(62px, 18vw, 76px);
        height: auto;
        aspect-ratio: 159 / 247;
        flex: 0 0 clamp(62px, 18vw, 76px);
        margin: 0 2px;
        border-radius: 8px;
    }

    #playerCards::-webkit-scrollbar {
        display: none;
    }

    .row2 {
        width: min(100%, 460px);
        gap: clamp(8px, 1.8dvh, 16px) 8px;
        padding: clamp(8px, 1.6dvh, 18px) 0;
    }

    #pool,
    #throwPool {
        width: clamp(78px, 22vw, 92px);
        height: clamp(96px, 16dvh, 128px);
    }

    #pool .card,
    #throwPool .card {
        width: clamp(60px, 17vw, 72px);
    }

    #playerCards {
        min-height: clamp(108px, 16dvh, 130px);
    }
}

/* ------------------------------------------------------------------
   Motion — the table takes a breath.

   One authored moment: the start screen lifts away as a full-viewport
   sheet, uncovering the table that is already dealing itself in.
   Everything else is feedback on state already on screen, so entrance
   choreography is scoped to `.is-entering` and never replays when the
   online renderer rebuilds a hand mid-match.
   ------------------------------------------------------------------ */

/* The menu arriving: each paper slip lands in turn. */
#newMatchScreen::before {
    animation: menu-table-settle 1.1s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

.logo {
    animation: logo-land 0.62s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

.menu-title {
    animation: menu-rise 0.6s cubic-bezier(0.16, 1, 0.3, 1) 0.08s backwards;
}

.menu-caption {
    animation: menu-rise 0.55s cubic-bezier(0.16, 1, 0.3, 1) 0.16s backwards;
}

#catsIMG {
    animation: cat-arrive 0.9s cubic-bezier(0.16, 1, 0.3, 1) 0.1s backwards;
}

.online-panel {
    animation-delay: 0.14s;
}

.local-panel {
    animation-delay: 0.22s;
}

/* The primary action: rises with the menu, catches one glint of light,
   and physically gives under the press. */
#startGameBtn {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    animation: menu-rise 0.55s cubic-bezier(0.16, 1, 0.3, 1) 0.3s backwards;
}

#startGameBtn::after {
    position: absolute;
    top: -60%;
    bottom: -60%;
    left: -45%;
    width: 38%;
    background: linear-gradient(
        100deg,
        transparent,
        rgba(255, 255, 255, 0.55) 45%,
        transparent
    );
    content: "";
    pointer-events: none;
    rotate: 8deg;
    translate: -180% 0;
    animation: start-glint 0.95s cubic-bezier(0.4, 0, 0.2, 1) 1.05s 1 both;
}

#startGameBtn:active {
    transform: translateY(4px) scale(0.985);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.34);
    transition-duration: 0.06s;
}

@keyframes menu-table-settle {
    from {
        opacity: 0;
        transform: translate(-50%, 12px) scale(1.02);
    }
    to {
        opacity: 0.82;
        transform: translateX(-50%);
    }
}

@keyframes logo-land {
    from {
        opacity: 0;
        transform: translateY(-14px) rotate(-19deg) scale(0.72);
    }
    60% {
        opacity: 1;
    }
    to {
        opacity: 1;
        transform: translateY(0) rotate(-5deg) scale(1);
    }
}

@keyframes menu-rise {
    from {
        opacity: 0;
        translate: 0 14px;
        filter: blur(5px);
    }
    to {
        opacity: 1;
        translate: 0 0;
        filter: blur(0);
    }
}

@keyframes cat-arrive {
    from {
        opacity: 0;
        translate: -16px 6px;
    }
    to {
        opacity: 0.42;
        translate: 0 0;
    }
}

@keyframes start-glint {
    from {
        translate: -180% 0;
    }
    to {
        translate: 360% 0;
    }
}

/* The full-screen hand-off: the start screen is one sheet covering the
   viewport, and it slides clear to reveal the table underneath. */
#newMatchScreen.is-leaving {
    pointer-events: none;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
    animation: menu-leave 0.64s cubic-bezier(0.65, 0, 0.2, 1) forwards;
    will-change: transform;
}

@keyframes menu-leave {
    from {
        transform: translateY(0);
    }
    to {
        transform: translateY(-101%);
    }
}

/* The veil that covers the result/table swap. It is created on demand and
   fades back into the felt, so a rematch reads as one move. */
.screen-wipe {
    position: fixed;
    z-index: 300;
    inset: 0;
    background:
        url("img/paper-grain.svg") center / 190px repeat,
        radial-gradient(120% 90% at 50% 40%, #1a241c 0%, var(--night) 72%);
    opacity: 1;
    pointer-events: none;
    scale: 1;
    transform-origin: 50% 42%;
    transition:
        opacity 0.42s cubic-bezier(0.16, 1, 0.3, 1),
        scale 0.62s cubic-bezier(0.16, 1, 0.3, 1);
}

.screen-wipe[hidden] {
    display: none;
}

.screen-wipe.is-revealing {
    opacity: 0;
    scale: 1.035;
}

/* The table arriving: seats, then centre, then the player's hand. */
#gameScreen.is-entering {
    animation: table-arrive 0.5s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

.is-entering .cat-scene {
    animation: cat-scene-in 0.9s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.is-entering .row2 {
    animation: table-rise 0.5s cubic-bezier(0.16, 1, 0.3, 1) 0.1s both;
}

.is-entering #player1 {
    animation: table-rise 0.56s cubic-bezier(0.16, 1, 0.3, 1) 0.16s both;
}

.is-entering #opponents .hand {
    animation: seat-deal 0.55s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.is-entering #opponents .hand:nth-child(1) {
    animation-delay: 0.04s;
}

.is-entering #opponents .hand:nth-child(2) {
    animation-delay: 0.09s;
}

.is-entering #opponents .hand:nth-child(3) {
    animation-delay: 0.14s;
}

.is-entering #opponents .hand:nth-child(4) {
    animation-delay: 0.19s;
}

.is-entering #opponents .hand:nth-child(5) {
    animation-delay: 0.24s;
}

.is-entering #opponents .hand:nth-child(6) {
    animation-delay: 0.29s;
}

.is-entering #opponents .hand .card {
    animation: card-deal-seat 0.42s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

.is-entering #playerCards > .card {
    animation: card-deal-hand 0.42s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

/* The first card in each opponent hand is child 2, after the name tab. */
.is-entering #opponents .hand .card:nth-child(2),
.is-entering #playerCards > .card:nth-child(1) {
    animation-delay: 0.18s;
}

.is-entering #opponents .hand .card:nth-child(3),
.is-entering #playerCards > .card:nth-child(2) {
    animation-delay: 0.21s;
}

.is-entering #opponents .hand .card:nth-child(4),
.is-entering #playerCards > .card:nth-child(3) {
    animation-delay: 0.24s;
}

.is-entering #opponents .hand .card:nth-child(5),
.is-entering #playerCards > .card:nth-child(4) {
    animation-delay: 0.27s;
}

.is-entering #opponents .hand .card:nth-child(6),
.is-entering #playerCards > .card:nth-child(5) {
    animation-delay: 0.3s;
}

.is-entering #opponents .hand .card:nth-child(7),
.is-entering #playerCards > .card:nth-child(6) {
    animation-delay: 0.33s;
}

.is-entering #opponents .hand .card:nth-child(8),
.is-entering #playerCards > .card:nth-child(7) {
    animation-delay: 0.36s;
}

.is-entering .hand.turn h2 {
    animation: tab-in 0.38s cubic-bezier(0.16, 1, 0.3, 1) 0.34s both;
}

@keyframes table-arrive {
    from {
        opacity: 0;
        translate: 0 10px;
    }
    to {
        opacity: 1;
        translate: 0 0;
    }
}

@keyframes cat-scene-in {
    from {
        scale: 1.035;
    }
    to {
        scale: 1;
    }
}

@keyframes table-rise {
    from {
        opacity: 0;
        translate: 0 10px;
    }
    to {
        opacity: 1;
        translate: 0 0;
    }
}

@keyframes seat-deal {
    from {
        opacity: 0;
        translate: 0 -12px;
        scale: 0.96;
    }
    to {
        opacity: 1;
        translate: 0 0;
        scale: 1;
    }
}

@keyframes card-deal-seat {
    from {
        opacity: 0;
        translate: 0 -9px;
        scale: 0.9;
    }
    to {
        opacity: 1;
        translate: 0 0;
        scale: 1;
    }
}

@keyframes card-deal-hand {
    from {
        opacity: 0;
        translate: 0 12px;
        scale: 0.9;
    }
    to {
        opacity: 1;
        translate: 0 0;
        scale: 1;
    }
}

@keyframes tab-in {
    from {
        opacity: 0;
        translate: -6px 0;
    }
    to {
        opacity: 1;
        translate: 0 0;
    }
}

/* Press feedback on the other paper buttons, so the whole menu answers
   the hand the same way the start button does. */
#turnBtn:active:not(:disabled),
#newMatchBtn:active,
#rematchBtn:active {
    transform: translateY(4px) scale(0.985);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.34);
    transition-duration: 0.06s;
}

.online-panel button {
    transition:
        background-color 0.16s ease,
        border-color 0.16s ease,
        transform 0.12s ease;
}

.online-panel button:not(:disabled):active {
    transform: translateY(1px);
}

/* Turn change: the felt border eases across instead of snapping. */
#player1 {
    transition:
        border-color 0.2s ease,
        border-top-color 0.35s ease,
        background-color 0.2s ease;
}

/* The MEOW window opens with a small paper pop rather than appearing. */
#unoBtn.uno-ready {
    animation: uno-ready-in 0.44s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

@keyframes uno-ready-in {
    from {
        opacity: 0.45;
        scale: 0.9;
    }
    60% {
        opacity: 1;
        scale: 1.04;
    }
    to {
        opacity: 1;
        scale: 1;
    }
}

/* Message slips flutter up as they become visible (inline scale 0 → 1). */
#messageBox[style*="scale: 1"] {
    animation: message-in 0.3s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

@keyframes message-in {
    from {
        translate: 0 6px;
        filter: blur(2px);
    }
    to {
        translate: 0 0;
        filter: blur(0);
    }
}

/* Colour dots deal out of the picker when it opens. */
.colorPicker[style*="scale: 1"] h2 {
    animation: picker-title-in 0.32s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

.colorPicker[style*="scale: 1"] .color {
    animation: color-dot-in 0.4s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

.colorPicker[style*="scale: 1"] .color:nth-of-type(1) {
    animation-delay: 0.04s;
}

.colorPicker[style*="scale: 1"] .color:nth-of-type(2) {
    animation-delay: 0.08s;
}

.colorPicker[style*="scale: 1"] .color:nth-of-type(3) {
    animation-delay: 0.12s;
}

.colorPicker[style*="scale: 1"] .color:nth-of-type(4) {
    animation-delay: 0.16s;
}

@keyframes picker-title-in {
    from {
        opacity: 0;
        translate: 0 5px;
    }
    to {
        opacity: 1;
        translate: 0 0;
    }
}

@keyframes color-dot-in {
    from {
        opacity: 0;
        scale: 0.7;
    }
    to {
        opacity: 1;
        scale: 1;
    }
}

/* Results: the slip stamps down and the standings arrive one by one. */
#endScreen h1 {
    animation: result-stamp 0.45s cubic-bezier(0.16, 1, 0.3, 1) 0.06s backwards;
}

@keyframes result-stamp {
    from {
        opacity: 0;
        scale: 1.14;
        filter: blur(3px);
    }
    60% {
        opacity: 1;
    }
    to {
        opacity: 1;
        scale: 1;
        filter: blur(0);
    }
}

.leaderCard {
    animation: leader-row 0.42s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

.leaderboard .leaderCard:nth-child(2) {
    animation-delay: 0.1s;
}

.leaderboard .leaderCard:nth-child(3) {
    animation-delay: 0.15s;
}

.leaderboard .leaderCard:nth-child(4) {
    animation-delay: 0.2s;
}

.leaderboard .leaderCard:nth-child(5) {
    animation-delay: 0.25s;
}

.leaderboard .leaderCard:nth-child(6) {
    animation-delay: 0.3s;
}

.leaderboard .leaderCard:nth-child(7) {
    animation-delay: 0.35s;
}

@keyframes leader-row {
    from {
        opacity: 0;
        translate: 0 8px;
    }
    to {
        opacity: 1;
        translate: 0 0;
    }
}

/* Leaderboard dialog and lobby roster. */
.wins-dialog {
    animation: fade-in 0.24s ease-out both;
}

#winsList li {
    animation: leader-row 0.34s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

#winsList li:nth-child(2) {
    animation-delay: 0.05s;
}

#winsList li:nth-child(3) {
    animation-delay: 0.1s;
}

#winsList li:nth-child(4) {
    animation-delay: 0.15s;
}

#winsList li:nth-child(5) {
    animation-delay: 0.2s;
}

#winsList li:nth-child(6) {
    animation-delay: 0.25s;
}

#winsList li:nth-child(7) {
    animation-delay: 0.3s;
}

#winsList li:nth-child(8) {
    animation-delay: 0.35s;
}

#onlineLobby:not([hidden]) {
    animation: table-rise 0.34s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

#onlinePlayers li {
    animation: leader-row 0.3s cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

#onlinePlayers li:nth-child(2) {
    animation-delay: 0.04s;
}

#onlinePlayers li:nth-child(3) {
    animation-delay: 0.08s;
}

#onlinePlayers li:nth-child(4) {
    animation-delay: 0.12s;
}

#onlinePlayers li:nth-child(5) {
    animation-delay: 0.16s;
}

#onlinePlayers li:nth-child(6) {
    animation-delay: 0.2s;
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        scroll-behavior: auto !important;
        animation-duration: 0.01ms !important;
        animation-delay: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        transition-delay: 0.01ms !important;
    }

    .screen-wipe {
        display: none !important;
    }
}
