/* Seat gear + controls panel (bot level, replace). */
.seat-controls {
    position: absolute;
    /* Stacking-context root for the panel; needs to beat hand (50-70) and
       table-info (60). Use a very high value to be safe across phases. */
    z-index: 9999;
    width: 0;
    height: 0;
}
/* The .player parent itself must also win the stacking context so the
   panel actually paints over neighbouring seats and the hand strip. */
.players .player:has(.seat-controls-panel[style*="block"]) { z-index: 9999; }
/* Position gear away from the table center for each seat. */
.players .player.player-2 .seat-controls,
.players .player.player-3 .seat-controls { top: -18px; left: 50%; }
.players .player.player-5 .seat-controls,
.players .player.player-6 .seat-controls { top: -18px; left: 50%; transform: rotatez(180deg); }
.players .player.player-1 .seat-controls { top: 50%;  left: -18px; }
.players .player.player-4 .seat-controls { top: 50%;  left: calc(100% + 18px); }

/* Counter-rotate panels so they read upright regardless of seat rotation.
   Each value is the inverse of the parent .player's rotateZ. */
.players .player.player-1 .seat-controls-panel { transform: rotatez(90deg);  transform-origin: center center; }
.players .player.player-4 .seat-controls-panel { transform: rotatez(-90deg); transform-origin: center center; }
.players .player.player-5 .seat-controls-panel,
.players .player.player-6 .seat-controls-panel {
    /* .seat-controls already counter-rotates 180 for these seats, so the
       panel needs NO additional rotation - inheriting screen-upright is right.
       But position has to compensate so the panel pops UP (toward table)
       not down (into hand cards). */
    transform: none;
    top: auto;
    bottom: 16px;
    left: auto;
    right: -50px;
}

/* Same idea for the gear icon itself - undo the parent rotation so the cog
   reads correctly from the user's perspective. */
.players .player.player-1 .seat-gear { display: inline-block; transform: rotatez(90deg); }
.players .player.player-4 .seat-gear { display: inline-block; transform: rotatez(-90deg); }
.players .player.player-5 .seat-gear,
.players .player.player-6 .seat-gear { display: inline-block; transform: rotatez(180deg); }

.seat-gear {
    cursor: pointer;
    font-size: 16px;
    color: #fff;
    opacity: 0.45;
    transition: opacity 0.15s;
    display: block;
    padding: 2px 6px;
    position: absolute;
    transform: translate(-50%, -50%);
    background: rgba(0,0,0,0.4);
    border-radius: 50%;
    user-select: none;
}
.seat-gear:hover { opacity: 1; }
.seat-controls-panel {
    position: absolute;
    top: 16px;
    left: -50px;
    background: rgba(25,25,25,0.97);
    padding: 18px 6px 6px 6px;
    border-radius: 4px;
    min-width: 170px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.6);
    /* Above hand cards (z-index up to 70 in mobile) and table chrome. */
    z-index: 9999;
}
.seat-controls-panel select,
.seat-controls-panel .replace-seat {
    width: 100%;
    font-size: 11px;
    margin-bottom: 4px;
    color: #000;
}
.seat-controls-panel .replace-seat {
    padding: 3px 4px;
    cursor: pointer;
    color: #fff;
    margin-bottom: 0;
}
.preset-row { display: flex; flex-wrap: wrap; gap: 2px; margin-bottom: 4px; }
.preset-btn { font-size: 10px !important; padding: 1px 4px !important; cursor: pointer; }
.knob-row {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-bottom: 3px;
    color: #ddd;
    font-size: 10px;
}
.knob-row label { width: 30px; flex-shrink: 0; margin: 0; }
.knob-row input[type=range] { flex: 1; min-width: 0; height: 14px; }
.knob-row span { width: 24px; text-align: right; flex-shrink: 0; }
.knob-row select { flex: 1; font-size: 10px; padding: 0; color: #000; }
.knob-min, .knob-max { width: 10px !important; flex-shrink: 0; font-size: 9px; opacity: 0.6; text-align: center; }
.panel-close { position: absolute; top: 2px; right: 4px; cursor: pointer; font-size: 14px; line-height: 1; color: #aaa; z-index: 1; }
.panel-close:hover { color: #fff; }

/* Bot config tag shown under each bot's name */
.bot-tag {
    display: inline-block;
    font-size: 9px;
    font-weight: bold;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    padding: 1px 6px;
    border-radius: 7px;
    margin-top: 1px;
    line-height: 1.4;
    cursor: help;
}
.bot-tag-expert { background: #f0c050; color: #222; }
.bot-tag-mixed  { background: #6db3f2; color: #112233; }
.bot-tag-rules  { background: #777; color: #fff; }

/* Bot Guide modal */
.bot-guide-content { background: #2a2a2a; color: #e0e0e0; border: 1px solid #444; }
.bot-guide-content .modal-header { border-bottom: 1px solid #444; }
.bot-guide-content .modal-footer { border-top: 1px solid #444; }
.bot-guide-content .close { color: #fff; opacity: 0.7; text-shadow: none; }
.bot-guide-content .close:hover { opacity: 1; }
.bot-guide-body { font-size: 14px; }
.bot-guide-section {
    color: #6db3f2;
    font-weight: bold;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-size: 12px;
    margin-bottom: 10px;
    border-bottom: 1px solid #444;
    padding-bottom: 4px;
}
.preset-card {
    background: #353535;
    border-left: 3px solid #555;
    padding: 8px 12px;
    margin-bottom: 8px;
    border-radius: 3px;
}
.preset-card.preset-expert { border-left-color: #ffc107; background: #3a3320; }
.preset-name { font-weight: bold; color: #fff; margin-bottom: 3px; }
.preset-badge {
    display: inline-block;
    background: #ffc107;
    color: #222;
    font-size: 10px;
    font-weight: bold;
    padding: 1px 6px;
    border-radius: 8px;
    margin-left: 6px;
    vertical-align: middle;
}
.preset-desc { color: #bbb; font-size: 13px; line-height: 1.4; }
.knob-doc { margin-bottom: 10px; }
.knob-doc-name { font-weight: bold; color: #6db3f2; font-size: 13px; margin-bottom: 2px; }
.knob-doc-desc { color: #ccc; font-size: 13px; line-height: 1.4; }
.ctrl-doc { color: #ccc; font-size: 13px; padding: 4px 0; line-height: 1.4; }
.ctrl-doc b { color: #fff; }

/* MLP move-check modal (Learning Game coach) */
#mlp-warning {
    display: none;
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(0,0,0,0.6);
    z-index: 2000;
    align-items: center;
    justify-content: center;
}
#mlp-warning[style*="block"] { display: flex !important; }
.mlp-warning-inner {
    background: #2a2a2a;
    color: #e0e0e0;
    border: 2px solid #f0c050;
    border-radius: 6px;
    padding: 16px 18px;
    width: 90%;
    max-width: 360px;
    box-shadow: 0 6px 24px rgba(0,0,0,0.6);
}
.mlp-warning-title { font-size: 18px; font-weight: bold; color: #f0c050; margin-bottom: 12px; }
.mlp-warning-inner .mlp-warning-row {
    font-size: 16px;
    margin-bottom: 6px;
    line-height: 1.5;
}
.mlp-warning-inner .mlp-tag {
    display: inline-block;
    font-size: 10px;
    font-weight: bold;
    padding: 1px 6px;
    margin: 0 6px 0 0;
    border-radius: 3px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.mlp-warning-inner .mlp-tag.yours { background: #6c757d; color: #fff; }
.mlp-warning-inner .mlp-tag.mlp { background: #f0c050; color: #222; margin-left: 12px; }
.mlp-warning-reason {
    color: #ddd;
    font-size: 14px;
    margin: 10px 0 14px;
    padding: 10px 12px;
    background: rgba(240,192,80,0.08);
    border-left: 3px solid #f0c050;
    border-radius: 3px;
    line-height: 1.5;
}
.mlp-warning-buttons { display: flex; gap: 8px; justify-content: flex-end; }

html,
body {
    background-color: #4b4b4b;
    margin: 0;
    padding: 0;
}

#header {
    height: 30px;
    pointer-events: none;
}

#header a,
#header .badge,
#header button
{
    pointer-events: initial;
}

#header .badge {
    pointer-events: initial;
}

#header-pad {
    padding: 15px;
}

.table-container {
    width: 100vw;
    height: calc(100vh - 200px);
}

#games-list {
    max-height: 500px;
    overflow: auto;
}

.single-container {
    margin-top: 50px;
    max-width: 500px;
}

@font-face {
    font-family: 'RideTheFader-1XKg';
    src: url('/fonts/RideTheFader-1XKg.eot');
    src: url('/fonts/RideTheFader-1XKg.eot?#iefix') format('embedded-opentype');
    font-weight: normal;
    font-style: normal;
}

@font-face {
    font-family: 'RidetheFader';
    src: url('/fonts/RidetheFader.woff') format('woff');
    font-weight: normal;
    font-style: normal;
}

.game-info {
    font-family: 'RidetheFader';
    text-align: center;
    height: 100px;
    width: 180px;
    position: absolute;
    padding: 10px;
    top: 30%;
    left: 50%;
    -webkit-transform: translateX(-50%) translateY(-50%);
    transform: translateX(-50%) translateY(-50%);
    box-sizing: border-box;
}

.instructions {
    font-family: 'Nunito', sans-serif;
}

.score {
    -webkit-text-stroke: 1px rgba(255,255,255,.2);
    font-size: 40px;
}

.bid, .trump, .bidding-player, .status-text {
    color: rgba(0,0,0,0.35);
    font-weight: bold;
}

.dealer {
    position: absolute;
    top: 80px;
    right: -30px;
    z-index: 10;

    width: 20px;
    height: 20px;
    background-image: url('/img/dealer-chip.png');
    background-size: cover;
    border-radius: 100%;
    /*border: 2px white dotted;*/
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.1);
    /*background-color: #444;*/
}

.player.player-1 .dealer {
    -webkit-transform: rotatez(90deg);
    transform: rotatez(90deg);
}

.player.player-2 .dealer {
    right: 120px;
}

.player.player-4 .dealer {
    right: 120px;
    -webkit-transform: rotatez(-90deg);
    transform: rotatez(-90deg);
}

.player.player-5 .dealer {
    right: 120px;
    -webkit-transform: rotatez(180deg);
    transform: rotatez(180deg);
}

.player.player-6 .dealer {
    -webkit-transform: rotatez(180deg);
    transform: rotatez(180deg);
}

.playing-card {
    height:120px;
    display: inline-block;
    position: relative;
    background-color: transparent;
    margin-right: 5px;
    border-radius: 5px;
}

.playing-card img {
    height: 100% !important;
    width: auto !important;
}

.playing-card.figures-Spade,
.playing-card.figures-Club {
    color: #515260;
}

.playing-card.figures-Heart,
.playing-card.figures-Diamond {
    color: #EC6E69;
}

.playing-card h1 {
    font-size: 14px;
    text-align: center;
    position: absolute;
    margin: 0;
    font-weight: bold;
}

.playing-card h1:first-child {
    top: 5px;
    left: 5px;
}

.playing-card h1:last-child {
    bottom: 5px;
    right: 5px;
}

.figures {
    width: 20px;
    height: 20px;
    /* Self-hosted. The old CodePen-hosted copy of this sprite started returning
       403, which blanked every suit glyph (trump readout + call-suit buttons). */
    background-image: url('/img/suits.svg');
    background-size: 40px;
}

.figures.Spade {
    background-position: 0 0;
}

.figures.Diamond {
    background-position: 20px 0;
}

.figures.Club {
    background-position: 20px 20px;
}

.figures.Heart {
    background-position: 0 20px;
}

.card-table {
    width: 1000px;
    height: 400px;
    background-color: #4aad4a;
    left: 50%;
    top: calc(55% - 40px);
    /* --felt-shift recentres the felt in the gap between the top chrome and the
       hand, and --felt-scale squishes it to fit when a short window can't hold the
       table plus the bidding panel (the seats, names and played cards scale with
       it, so text shrinks rather than clipping). Both are set by syncTableInset()
       in app.js. Defaults are a no-op, so without JS this is the original layout.
       scale() sits rightmost so it runs about the felt's own centre; the shift is
       then a plain px translation, which moves that centre by exactly --felt-shift
       whatever the scale. Mobile overrides this transform outright with !important
       and drives its own --table-scale / --table-shift. */
    -webkit-transform: translateX(-50%) translateY(calc(-50% + var(--felt-shift, 0px))) scale(var(--felt-scale, 1));
    transform: translateX(-50%) translateY(calc(-50% + var(--felt-shift, 0px))) scale(var(--felt-scale, 1));
    border-radius: 150px;
    position: relative;
    border: 15px solid #a95555;
    box-shadow: 0 0 15px 20px rgba(0,0,0,0.2);
}

.card-table:before {
    content: '';
    border: 7px solid rgba(0, 0, 0, 0.1);
    display: block;
    width: 1000px;
    height: 400px;
    border-radius: 150px;
    position: absolute;
    top: -15px;
    left: -15px;
}

.card-table:after {
    content: '';
    border: 7px solid rgba(0, 0, 0, 0.1);
    display: block;
    width: 970px;
    height: 370px;
    border-radius: 130px;
    position: absolute;
    top: 0;
    left: 0;
}

.players {
    position: relative;
    width: 100%;
    height: 100%;
    z-index: 100;
}

.players .player {
    position: absolute;
    border-radius: 10px;
    /* Reserve space for the bot-tag whether or not a bot is in this seat so
       top:110% on .played-card lands at the same offset for human seats too.
       Without this, the user's seat container is 18px shorter and the played
       card ends up right against the avatar after the 180deg rotation. */
    min-height: 118px;
}

.players .player .avatar {
    width: 100px;
    height: 100px;
    border-radius: 10%;
    position: relative;
    box-shadow: 0 0 4px 4px rgba(0, 0, 0, 0.4);
    z-index: 20;
}

.players .player .avatar:after {
    content: '';
    width: 70px;
    height: 70px;
    position: absolute;
    background-color: rgba(0, 0, 0, 0.1);
    top: 50%;
    left: 50%;
    -webkit-transform: translatex(-50%) translatey(-50%);
    transform: translatex(-50%) translatey(-50%);
    border-radius: 100%;
    box-shadow: 0px 0px 2px 2px rgba(0, 0, 0, 0.3);
    margin-top: 4px;
}

.players .player .avatar img {
    width: 70px;
    height: 70px;
    position: relative;
    top: 50%;
    left: 50%;
    -webkit-transform: translatex(-50%) translatey(-50%);
    transform: translatex(-50%) translatey(-50%);
    border-radius: 100%;
    margin-top: 4px;
    border: 2px solid #303030;
}

.players .player-1 .avatar img
{
    -webkit-transform: translatex(-50%) translatey(-50%) rotatez(90deg);
    transform: translatex(-50%) translatey(-50%) rotatez(90deg);
    margin-top: 0;
    margin-left: 4px;
}

.players .player-4 .avatar img {
    -webkit-transform: translatex(-50%) translatey(-50%) rotatez(-90deg);
    transform: translatex(-50%) translatey(-50%) rotatez(-90deg);
    margin-top: 0;
    margin-left: -4px;
}

.players .player-6 .avatar img,
.players .player-5 .avatar img
{
    -webkit-transform: translatex(-50%) translatey(-50%) rotatez(-180deg);
    transform: translatex(-50%) translatey(-50%) rotatez(-180deg);
}

.players .player-1 .avatar::after {
    margin-top: 0;
    margin-left: 4px;
}

.players .player-4 .avatar::after {
    margin-top: 0;
    margin-left: -4px;
}

.players .player .name {
    text-align: center;
    width: 100px;
    color: #ffffff;
    padding: 5px 0;
    box-sizing: border-box;
    background-color: #272727;
    border: 2px solid #000000;
    border-bottom-right-radius: 10px;
    border-bottom-left-radius: 10px;
    margin-top: 15px;
    text-overflow: ellipsis;
    font-size: 11px;
    overflow: hidden;
    position: absolute;
    top: 80%;
    z-index: 20;
    font-weight: bold;
}

.players .player .name.is-player:before {
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    content: "\f005";
    margin-right: 3px;
    color: yellow;
}

.players .player.player-1 {
    top: 50%;
    left: 0px;
    -webkit-transform: translatex(-50%) translatey(-50%) rotatez(-90deg);
    transform: translatex(-50%) translatey(-50%) rotatez(-90deg);
}

.players .player.player-1 .name {
    top: 20%;
    right: 55%;
    -webkit-transform: rotatez(90deg);
    transform: rotatez(90deg);
}

.players .player.player-2 {
    top: 0px;
    left: 30%;
    -webkit-transform: translatex(-50%) translatey(-50%);
    transform: translatex(-50%) translatey(-50%);
}

.players .player.player-2 .name {
    top: -35%;
    border-radius: 0;
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
}

.players .player.player-3 {
    top: 0px;
    left: 70%;
    -webkit-transform: translatex(-50%) translatey(-50%);
    transform: translatex(-50%) translatey(-50%);
}

.players .player.player-3 .name {
    top: -35%;
    border-radius: 0;
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
}

.players .player.player-4 {
    top: 50%;
    right: 0px;
    -webkit-transform: translatex(50%) translatey(-50%) rotatez(90deg);
    transform: translatex(50%) translatey(-50%) rotatez(90deg);
}

.players .player.player-4 .name {
    top: 20%;
    left: 55%;
    -webkit-transform: rotatez(-90deg);
    transform: rotatez(-90deg);
}

.players .player.player-5 {
    bottom: 0px;
    left: 70%;
    -webkit-transform: translatex(-50%) translatey(50%) rotatez(180deg);
    transform: translatex(-50%) translatey(50%) rotatez(180deg);
}

.players .player.player-5 .name,
.players .player.player-5 .bot-tag {
    top: -35%;
    -webkit-transform: rotatez(180deg);
    transform: rotatez(180deg);
}

.players .player.player-6 {
    bottom: 0px;
    left: 30%;
    -webkit-transform: translatex(-50%) translatey(50%) rotatez(180deg);
    transform: translatex(-50%) translatey(50%) rotatez(180deg);
}

.players .player.player-6 .name,
.players .player.player-6 .bot-tag {
    top: -35%;
    -webkit-transform: rotatez(180deg);
    transform: rotatez(180deg);
}

.team-1 .avatar {
    background-color: lightblue;
}

.team-1-score {
    color: lightblue;
}

.team-2 .avatar {
    background-color: lightcoral;
}

.team-2-score {
    color: lightcoral;
}

.blue {
    color: lightblue;
}

.red {
    color: lightcoral;
}

.team-1-bid {
    color: lightblue;
}

.team-2-bid {
    color: #eaa4a4;
}

.player .played-card {
    position: absolute;
    top: 110%;
    left: 11px;
}

.call-suit {
    margin-bottom: -3px;
    display: inline-block;
}

.player.player-1 .played-card .playing-card {
    -webkit-transform: rotatez(90deg);
    transform: rotatez(90deg);
}

.player.player-4 .played-card .playing-card {
    -webkit-transform: rotatez(-90deg);
    transform: rotatez(-90deg);
}

.player.player-5 .played-card .playing-card,
.player.player-6 .played-card .playing-card {
    -webkit-transform: rotatez(180deg);
    transform: rotatez(180deg);
}

/* Played-card placement nudges (desktop): the six trick cards bunch up in the
   middle. Each seat is rotated to face the felt, so a smaller `top` pulls the
   card back toward its player and a larger `top` pushes it further in toward
   center. Pull the top & bottom seats back toward their players; slide the
   left/right seats further into the table so the cards overlap less and use
   the wide felt. (top seats 2/3 unrotated, bottom 5/6 at 180°, so a smaller
   top moves both toward their player; left 1 at -90° / right 4 at +90°, so a
   larger top moves the card horizontally inward.) */
/* Wide felt: each card sits centered directly in front of its player (no
   sideways shift). Top seats (2/3) and bottom seats (5/6) keep only the
   toward-player vertical nudge; the side seats (1/4) sit a touch further in. */
.player.player-2 .played-card,
.player.player-3 .played-card { top: 98%; }
/* Bottom seats nudged up a little so the card clears the player's name
   (it only grazed it during trump-calling). */
.player.player-5 .played-card,
.player.player-6 .played-card { top: 105%; }
.player.player-1 .played-card { top: 124%; }
.player.player-4 .played-card { top: 124%; }

.trump .figures {
    display: inline-block;
    vertical-align:middle;
}

#options {
    cursor: pointer;
}

.name.empty {
    font-style: italic;
    cursor: pointer;
    transition: .3s all;
}

.name.switch {
    cursor: pointer;
    transition: .3s all;
}

.name.empty:hover, .name.switch:hover {
    background-color: white;
    color: black;
}

.name.empty::after {
    content: '<empty>';
}

.name.empty:hover::after {
    content: '<Take Seat>';
}

#error-toast {
    opacity: 100%;
    position: fixed;
    bottom: 5px;
    right: 5px;
}

#hand {
    position: fixed;
    bottom: 5px;
    left: 50%;
    margin-left: -350px;
    text-align: center;
    width: 700px;
}

.action-on.team-1 {
    -webkit-animation: glow-blue 1s ease-in-out infinite alternate;
    -moz-animation: glow-blue 1s ease-in-out infinite alternate;
    animation: glow-blue 1s ease-in-out infinite alternate;
}

@-webkit-keyframes glow-blue {
    from {
        box-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #6f8896, 0 0 40px #6f8896, 0 0 50px #6f8896, 0 0 60px #6f8896, 0 0 70px #6f8896;
    }

    to {
        box-shadow: 0 0 20px #fff, 0 0 30px #ADD8E6, 0 0 40px #ADD8E6, 0 0 50px #ADD8E6, 0 0 60px #ADD8E6, 0 0 70px #ADD8E6, 0 0 80px #ADD8E6;
    }
}

.action-on.team-2 {
    -webkit-animation: glow-red 1s ease-in-out infinite alternate;
    -moz-animation: glow-red 1s ease-in-out infinite alternate;
    animation: glow-red 1s ease-in-out infinite alternate;
}

@-webkit-keyframes glow-red {
    from {
        box-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #b95d5d, 0 0 40px #b95d5d, 0 0 50px #b95d5d, 0 0 60px #b95d5d, 0 0 70px #b95d5d;
    }

    to {
        box-shadow: 0 0 20px #fff, 0 0 30px #F08080, 0 0 40px #F08080, 0 0 50px #F08080, 0 0 60px #F08080, 0 0 70px #F08080, 0 0 80px #F08080;
    }
}

.bid-option {
    display: inline-block;
    text-align: center;
    padding-right: 20px;
    margin-right: 10px;
    margin-left: 10px;
    padding-left: 20px;
    font-size: large;
}

.can-play img {
    cursor: pointer;
    transition: .3s all;
}

.can-play:hover img {
    background-color: #1e7e34;
    box-shadow: 0 0 10px 2px #1e7e34;
    -moz-transform: translate(0, -4px);
    -ms-transform: translate(0, -4px);
    -o-transform: translate(0, -4px);
    -webkit-transform: translate(0, -4px);
    transform: translate(0, -4px)
}

/* ── MOBILE-ONLY (touch devices, hover-incapable): desktop never matches this
   query. A tap sets a sticky :hover on touch screens, so a rejected play left
   the card raised and glowing until the next tap somewhere else — neutralize
   the hover lift there. ── */
@media (hover: none) {
    .can-play:hover img {
        background-color: transparent;
        box-shadow: none;
        -moz-transform: none;
        -ms-transform: none;
        -o-transform: none;
        -webkit-transform: none;
        transform: none;
    }
}


.tricks-taken {
    position: absolute;
    top: 10px;
    left: 50%;
    width: 200px;
    margin-left: -100px;
    text-align: center;
}

.trick-dot {
    height: 15px;
    width: 15px;
    border-radius: 50%;
    display: inline-block;
}

.team-1-trick {
    background-color: lightblue;
    border: 1px solid #6f8896;
}

.team-2-trick {
    background-color: lightcoral;
    border: 1px solid #b95d5d;
}

.hand-message {
    font-family: 'RidetheFader';
    font-size: 24px;
    font-weight: bold;
    border: 1px solid #2d5b2d;
    background-color: #4aad4a;
    text-align: center;
    margin-bottom: 5px;
}

.user-avatar {
    max-width: 400px;
    max-height: 400px;
    display: block;
}

.avatar-container {
    width: 100px;
    height: 100px;
    border-radius: 10%;
    position: relative;
    z-index: 20;
    cursor: pointer;
}

.avatar-container:after {
    content: "";
    text-align: center;
    padding-top: 6px;
    width: 70px;
    height: 70px;
    position: absolute;
    top: 50%;
    left: 50%;
    color: white;
    font-weight: bold;
    -webkit-transform: translatex(-50%) translatey(-50%);
    transform: translatex(-50%) translatey(-50%);
    border-radius: 100%;
    margin-top: 4px;
    border: 2px solid #303030;
    cursor: pointer;
    transition: all .3s;
    background-color: rgba(0,0,0,0);
}

.avatar-container:hover:after {
    content: "View Profile";
    text-align: center;
    padding-top: 6px;
    width: 70px;
    height: 70px;
    position: absolute;
    top: 50%;
    left: 50%;
    background-color: rgba(0,0,0,.8);
    color: white;
    font-weight: bold;
    -webkit-transform: translatex(-50%) translatey(-50%);
    transform: translatex(-50%) translatey(-50%);
    border-radius: 100%;
    margin-top: 4px;
    border: 2px solid #303030;
    cursor: pointer;
}

.player-4 .avatar-container:after {
    -webkit-transform: translatex(-50%) translatey(-50%) rotatez(-90deg);
    transform: translatex(-50%) translatey(-50%) rotatez(-90deg);
    margin-top: 0;
    margin-left: -4px;
}

.player-1 .avatar-container:after {
    -webkit-transform: translatex(-50%) translatey(-50%) rotatez(90deg);
    transform: translatex(-50%) translatey(-50%) rotatez(90deg);
    margin-top: 0;
    margin-left: 4px;
}

.player-5 .avatar-container:after,
.player-6 .avatar-container:after {
    -webkit-transform: translatex(-50%) translatey(-50%) rotatez(-180deg);
    transform: translatex(-50%) translatey(-50%) rotatez(-180deg);
    margin-top: 4px;
}

.profile-info {
    position: absolute;
    width: 300px;
}

.profile-info .close {
    position: absolute;
    top: 8px;
    right: 10px;
    z-index: 100;
}

.main-container {
    margin-top: 50px;
}

.login-card {
    width: 450px;
    height: 300px;
}

.profile-table {
    margin-bottom: 0;
}

.profile-table td {
    padding: .5rem .75rem;
}

.user-level-progress {
    border: 1px solid #b3b7bb;
    position: relative;
}

.user-level {
    width: 100%;
    text-align: center;
    font-weight: bold;
    position: absolute;
    color: black;
}

@media (max-width: 976px) {
    .login-card {
        width: inherit;
        height: inherit;
    }
}

@media (max-width: 885px) {
    .card-table {
        width: 640px;
        height: 320px;
    }

    .card-table:before {
        width: 640px;
        height: 320px;
    }

    .card-table:after {
        width: 616px;
        height: 296px;
    }
}

/* Short viewport: shrink the felt to fit. Scoped to touch (pointer: coarse) so a
   desktop/laptop in a short window keeps its full-size felt — a bare max-height
   rule was clamping desktops to 640px and crowding the played cards over the
   center text. */
@media (max-height: 820px) and (pointer: coarse) {
    .card-table {
        width: 640px;
        height: 320px;
    }

    .card-table:before {
        width: 640px;
        height: 320px;
    }

    .card-table:after {
        width: 616px;
        height: 296px;
    }

    #hand {
        margin-bottom: -5px;
    }

    .trick-dot {
        height: 10px;
        width: 10px;
    }
}

/* ── Landscape on short viewports (tablets showing the desktop layout) ──
   The player's own hand is position:fixed at the bottom of the screen and the
   two bottom players (5 & 6) hang off the lower edge of the felt. On a short
   landscape screen the felt is too tall, so the bottom row slid down behind the
   hand and off the screen edge. Fix: scale the felt AND the hand to the viewport
   height (clamped to the normal desktop sizes, so it never grows past them) and
   nudge the felt up a touch. Both edges move toward center as height shrinks, so
   the bottom row clears the hand without pushing the top players (2 & 3) up under
   the fixed header. Self-fitting via clamp() — no device-specific dimensions.
   Scoped to landscape + short height AND a coarse (touch) pointer so it only
   hits tablets — a desktop/laptop in a short window (same pixel height) keeps
   its full-size felt, since it reports a fine pointer. The felt is a 2:1
   ellipse, so width is kept at 2× the height. */
@media (orientation: landscape) and (max-height: 820px) and (pointer: coarse) {
    .card-table {
        width: clamp(480px, 80vh, 640px);
        height: clamp(240px, 40vh, 320px);
        top: 46%;
    }
    .card-table:before {
        width: clamp(480px, 80vh, 640px);
        height: clamp(240px, 40vh, 320px);
    }
    .card-table:after {
        width: clamp(456px, calc(80vh - 24px), 616px);
        height: clamp(216px, calc(40vh - 24px), 296px);
    }

    /* Smaller hand reclaims the bottom band the cards were covering. */
    .hand-card {
        height: clamp(60px, 12vh, 110px);
    }
    #hand {
        bottom: 2px;
        margin-bottom: 0;
    }
}

@media (max-width: 750px) {
    #hand {
        width: 500px;
        margin-left: -250px;
    }

    .hand-card {
        height: 80px;
    }
}

/* ── Phone portrait (width ≤ 480 px) ── */
@media (max-width: 480px) {
    body { overflow-x: hidden; }

    /* Move game info OFF the table center: pin to top as a compact strip.
       Since the template now places .game-info as a sibling of .card-table
       (not a child), it no longer inherits the table's rotation in portrait
       mobile mode and position:fixed works correctly. */
    .game-info {
        position: fixed !important;
        top: 38px !important;
        left: 0 !important;
        right: 0 !important;
        width: 100vw !important;
        max-width: 100vw !important;
        height: auto !important;
        transform: none !important;
        background: rgba(0,0,0,0.55);
        padding: 4px 8px !important;
        z-index: 60;
        text-align: center;
        border-top: 1px solid rgba(240,192,80,0.25);
        border-bottom: 1px solid rgba(240,192,80,0.25);
    }
    .game-info .score { font-size: 22px !important; line-height: 1.1; }
    .game-info .bid, .game-info .trump, .game-info .bidding-player,
    .game-info .status-text { font-size: 12px !important; color: #eee !important; display: inline-block; margin: 0 4px; }
    .game-info .mt-2 { margin-top: 2px !important; }
    .game-info .btn-sm { padding: 1px 6px !important; font-size: 11px !important; }

    /* Collapsed: keep the always-on info (score, tricks, bid, trump, status) on
       one tight row so the strip stays short and the top player shows below it. */
    body:not(.controls-open) .game-info .score,
    body:not(.controls-open) .game-info .tricks-num {
        display: inline-block !important;
        vertical-align: middle;
        font-size: 16px !important;
        margin: 0 6px !important;
    }

    .table-container {
        height: calc(100vh - 240px) !important;
        overflow: hidden;
        margin-top: 80px;
    }
    /* Collapsed = the top strip is tiny (just bid/trump/status/score), so reclaim
       most of the 80px top reservation. The table area grows ~50px taller and
       recenters, pulling the bottom player (p1) up off the hand and the top
       player (p4) down out of the clip edge. Restored when controls are open. */
    body:not(.controls-open) .table-container {
        height: calc(100vh - 196px) !important;
        margin-top: 36px !important;
    }

    .card-table {
        /* width = vertical (long) axis after the -90deg rotation; height = horizontal
           (short) axis. Fattened from 400 → 600 so the felt fills the screen width
           and opens up a large central area for the played cards.
           --table-w  : the long (screen-vertical) axis. Shrunk when controls are
                        collapsed to "squish" the felt and pull the bottom player up
                        off the hand (see body:not(.controls-open) override below).
           --table-scale : per-height fill scale, set in the queries below.
           --table-shift : screen-space upward nudge (px). Pairs with the squish so
                        the top player stays anchored while the bottom rim rises. */
        --table-w: 820px;
        --table-scale: 0.50;
        --table-shift: 0px;
        width: var(--table-w) !important;
        height: 600px !important;
        top: 50% !important;
        border-radius: 220px !important;
        /* Rotate -90deg (counter-clockwise) so the table's long axis runs vertically
           and player-6 (the typical user seat) lands bottom-right, nearest the hand. */
        transform: translateX(-50%) translateY(calc(-50% - var(--table-shift))) scale(var(--table-scale)) rotate(-90deg) !important;
    }
    /* Per-height scales: fill the width on modern phones (S24 ≈ 740–820px tall,
       depending on browser chrome). */
    @media (max-width: 480px) and (min-height: 720px) {
        .card-table { --table-scale: 0.58; }
    }
    @media (max-width: 480px) and (min-height: 860px) {
        .card-table { --table-scale: 0.62; }
    }
    @media (max-width: 480px) and (max-height: 700px) {
        .card-table { --table-scale: 0.40; }
    }
    @media (max-width: 480px) and (max-height: 600px) {
        .card-table { --table-scale: 0.34; }
    }

    /* Controls collapsed: squish the table's long axis (820 → 660) so the top and
       bottom rims pull toward center, and shift the whole table up ~46px so the top
       player stays anchored (it was sitting a few px below the top edge) while the
       bottom player rises ~half the squish out from behind the hand. */
    body:not(.controls-open) .card-table {
        --table-w: 660px;
        --table-shift: 46px;
    }
    /* Mobile-rotated mode strategy: each .player gets rotate(+90deg) to cancel the
       table's -90deg, so the player's local frame is upright in screen coords.
       ALL per-seat inner rotations (.name, .bot-tag, .seat-gear, .played-card,
       .avatar img, .dealer, .avatar-container:after) are zeroed out — they were
       tuned for the player being rotated, so without per-player rotation they
       must be unrotated too. Position translations are preserved. */
    .players .player.player-1,
    .players .player.player-2,
    .players .player.player-3 { transform: translatex(-50%) translatey(-50%) rotate(90deg) !important; }
    .players .player.player-4 { transform: translatex(50%) translatey(-50%) rotate(90deg) !important; }
    .players .player.player-5,
    .players .player.player-6 { transform: translatex(-50%) translatey(50%) rotate(90deg) !important; }

    /* Zero every per-seat inner rotation, then pin every name to its avatar so
       the label reads as one connected tag instead of floating per-seat offsets.
       All seats: name flush under the avatar's bottom edge (avatar is 76px tall,
       2px overlap swallows the border seam). The screen-bottom seat (player-1)
       instead docks flush above its avatar so the label stays clear of the hand. */
    .players .player .name {
        transform: none !important;
        left: 0 !important;
        right: auto !important;
        top: 74px !important;
        margin-top: 0 !important;
        border-radius: 0 0 10px 10px !important;
    }
    .players .player.player-1 .name {
        top: auto !important;
        bottom: calc(100% - 2px) !important;
        border-radius: 10px 10px 0 0 !important;
    }
    /* Keep the centring, drop only the counter-rotation (the seat is upright here). */
    .players .player .add-bot-btn { transform: translate(-50%, -50%) !important; }

    /* The docked name now covers the spot the bot-tag flowed into, and the seat
       is too narrow for "Expert · ML 90%" anyway — the name already says Bot. */
    .players .player .bot-tag { display: none !important; }

    .players .player.player-1 .seat-gear,
    .players .player.player-4 .seat-gear,
    .players .player.player-5 .seat-gear,
    .players .player.player-6 .seat-gear { transform: translate(-50%, -50%) !important; }

    .players .player.player-1 .seat-controls-panel,
    .players .player.player-4 .seat-controls-panel,
    .players .player.player-5 .seat-controls-panel,
    .players .player.player-6 .seat-controls-panel { transform: none !important; }

    .player.player-1 .played-card .playing-card,
    .player.player-4 .played-card .playing-card,
    .player.player-5 .played-card .playing-card,
    .player.player-6 .played-card .playing-card { transform: none !important; }

    .players .player-1 .avatar img,
    .players .player-4 .avatar img,
    .players .player-5 .avatar img,
    .players .player-6 .avatar img {
        transform: translatex(-50%) translatey(-50%) !important;
        margin-top: 4px !important;
        margin-left: 0 !important;
    }

    .player.player-1 .dealer,
    .player.player-4 .dealer,
    .player.player-5 .dealer,
    .player.player-6 .dealer { transform: none !important; }

    .player-1 .avatar-container:after,
    .player-4 .avatar-container:after,
    .player-5 .avatar-container:after,
    .player-6 .avatar-container:after {
        transform: translatex(-50%) translatey(-50%) !important;
        margin-top: 4px !important;
        margin-left: 0 !important;
    }
    .card-table:before { width: var(--table-w) !important; height: 600px !important; top: -15px !important; left: -15px !important; border-radius: 220px !important; }
    .card-table:after  { width: calc(var(--table-w) - 30px) !important; height: 570px !important; border-radius: 205px !important; }

    /* Shrink the players in portrait. Avatars scale WITH the table, so without this
       the bigger table scale (above) would also enlarge the avatars. Smaller base +
       larger table = players occupy less of the felt, table+cards read bigger. */
    .players .player { min-height: 96px !important; }
    .players .player .avatar { width: 76px !important; height: 76px !important; }
    .players .player .avatar img,
    .players .player .avatar:after { width: 52px !important; height: 52px !important; }
    .players .player .name {
        width: 76px !important;
        font-size: 16px !important;
        padding: 3px 0 !important;
        margin-top: 0 !important; /* docked to the avatar (see name rules above) */
    }
    /* Gather the played cards into a trick pile in the open middle of the felt —
       each card lands near the felt center, offset toward its own seat, instead
       of hanging by (or under) its avatar. The card's local frame is
       screen-aligned (+x right, +y down) for every seat, so these are
       screen-space nudges (in pre-scale felt px). Tuned in the collapsed
       (controls hidden) state. Screen seat map: p4=top, p1=bottom,
       p3=left-upper, p2=left-lower, p5=right-upper, p6=right-lower. */
    .player.player-4 .played-card { transform: translate(-15px, 59px) !important; }
    .player.player-1 .played-card { transform: translate(-15px, -329px) !important; }
    .player.player-3 .played-card { transform: translate(176px, -56px) !important; }
    .player.player-2 .played-card { transform: translate(175px, -164px) !important; }
    .player.player-5 .played-card { transform: translate(-205px, -63px) !important; }
    .player.player-6 .played-card { transform: translate(-205px, -170px) !important; }

    /* The felt is rotated -90° here, so the trick counter pinned to the felt's
       top edge lands on the screen-left rim reading sideways — counter-rotate
       it upright in place. */
    .tricks-num { transform: translateX(-50%) rotate(90deg) !important; }

    #hand {
        width: 100vw !important;
        left: 0 !important;
        margin-left: 0 !important;
        box-sizing: border-box;
        padding: 4px 6px !important;
        bottom: 0 !important;
        background: rgba(0,0,0,0.55);
        border-top: 2px solid #f0c050;
        z-index: 70;
    }

    .cards-in-hand {
        white-space: nowrap;
        display: flex;
        justify-content: center;
        align-items: flex-end;
        overflow: visible;
    }

    /* Fan the hand: overlap cards so all 9 fit on a narrow phone without
       horizontal scroll. Negative margin pulls each card on top of the previous;
       :hover/:last-child gets a slight lift so the leftmost card stays visible. */
    .hand-card {
        height: 110px !important;
        margin: 0 -28px 0 0 !important;
        position: relative;
        transition: transform 0.15s, margin 0.15s;
    }
    .hand-card:last-child { margin-right: 0 !important; }
    /* :active only — :hover is sticky on touch, so a rejected tap used to
       leave the card stuck raised. */
    .hand-card.can-play:active {
        transform: translateY(-8px);
        z-index: 10;
    }
    /* A card you'd have to renege with: dimmed and untappable (phones only —
       desktop keeps the click + error toast it always had). pointer-events
       also keeps the :active lift from firing on it. */
    .cant-play { pointer-events: none; }
    .cant-play img { filter: grayscale(0.5) brightness(0.75); }
    /* Cards on the table inherit table scale; sized up to fill the open center. */
    .player .played-card .playing-card { height: 128px !important; }

    .bidding-options {
        white-space: normal !important;
        padding: 4px 6px !important;
    }

    .bid-option {
        padding: 3px 8px !important;
        margin: 2px 2px !important;
        font-size: 13px !important;
    }
}

/* ── Phone landscape (height ≤ 480 px, width > 480 px) ── */
@media (max-height: 480px) and (min-width: 481px) {
    body { overflow: hidden; }

    /* Move game-info to right edge as a thin column - frees the table center */
    .game-info {
        position: fixed !important;
        top: 38px !important;
        right: 0 !important;
        left: auto !important;
        width: 130px !important;
        max-width: 130px !important;
        height: auto !important;
        max-height: calc(100vh - 130px) !important;
        transform: none !important;
        background: rgba(0,0,0,0.55);
        padding: 4px 6px !important;
        z-index: 60;
        text-align: left;
        border-left: 2px solid rgba(240,192,80,0.4);
        overflow-y: auto;
    }
    .game-info .score { font-size: 18px !important; line-height: 1.1; }
    .game-info .bid, .game-info .trump, .game-info .bidding-player,
    .game-info .status-text { font-size: 11px !important; color: #eee !important; }
    .game-info .btn-sm { padding: 1px 6px !important; font-size: 10px !important; }

    /* table consumes the remaining width to the left of the info panel */
    .table-container {
        height: calc(100vh - 100px) !important;
        width: calc(100vw - 130px) !important;
        overflow: hidden;
    }

    .card-table {
        width: 800px !important;
        height: 400px !important;
        top: 50% !important;
        transform: translateX(-50%) translateY(-50%) scale(0.66) !important;
    }
    .card-table:before { width: 800px !important; height: 400px !important; top: -15px !important; left: -15px !important; }
    .card-table:after  { width: 770px !important; height: 370px !important; }

    #hand {
        width: 100vw !important;
        left: 0 !important;
        margin-left: 0 !important;
        bottom: 0 !important;
        box-sizing: border-box;
        padding: 4px 6px;
        background: rgba(0,0,0,0.55);
        border-top: 2px solid #f0c050;
        z-index: 70;
    }

    .cards-in-hand {
        overflow-x: auto;
        white-space: nowrap;
        -webkit-overflow-scrolling: touch;
        display: block;
        text-align: center;
    }

    /* Big hand cards - cards dominate the bottom, easy to read and tap */
    .hand-card { height: 90px !important; margin: 0 2px !important; }
    .player .played-card .playing-card { height: 80px !important; }
    .bidding-options { font-size: 11px !important; padding: 2px 4px !important; margin-bottom: 2px !important; }
    .bidding-options .small { display: none !important; }

    .bidding-options {
        overflow-x: auto;
        white-space: nowrap !important;
        -webkit-overflow-scrolling: touch;
        padding: 2px 4px !important;
    }

    .bid-option {
        padding: 3px 10px !important;
        margin: 1px 2px !important;
        font-size: 13px !important;
    }
}

/* ===== solo controls: speed + dismiss tabbed panel ===== */
/* Solo pacing controls: compact fixed bar of dropdowns, off the table,
   above the cards. Lives outside #game-table so position:fixed is
   viewport-anchored and it survives AJAX table refreshes. */
#solo-controls {
    position: fixed;
    top: 8px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 4000;
    display: flex;
    gap: 12px;
    align-items: center;
    background: rgba(0,0,0,0.62);
    border: 1px solid rgba(255,255,255,0.18);
    border-radius: 6px;
    padding: 3px 12px;
    font-family: 'RidetheFader';
    font-size: 12px;
    color: #e8e8e8;
    white-space: nowrap;
}
#solo-controls label { margin: 0; display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
/* Heading belongs to the centred desktop popup only; the mobile bar has no room. */
#solo-controls .settings-title { display: none; }
#solo-controls select { font-size: 12px; padding: 1px 4px; border-radius: 3px; }

#dismiss-continue-btn {
    position: fixed;
    top: 44px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 4001;
}

/* Gear toggle for the collapsible secondary controls (score, speed, pause,
   autoplay, ask grandpa). Hidden by default — only mobile portrait shows it;
   on larger screens there's room and those controls always show. */
#controls-toggle {
    display: none;
    position: fixed;
    top: 6px;
    right: 8px;
    z-index: 4002;
    width: 34px;
    height: 34px;
    padding: 0;
    font-size: 18px;
    line-height: 32px;
    text-align: center;
    color: #e8e8e8;
    background: rgba(0,0,0,0.62);
    border: 1px solid rgba(255,255,255,0.25);
    border-radius: 6px;
    cursor: pointer;
}
#controls-toggle:active { background: rgba(0,0,0,0.85); }
body.controls-open #controls-toggle { color: #f0c050; border-color: rgba(240,192,80,0.6); }

/* Desktop: Speed / Tricks used to sit in a bar pinned to the top-centre of the
   viewport at z-index 4000, directly on top of the top two seats' names. Tuck it
   behind the gear the way mobile portrait already does, and open it as a panel in
   the middle of the felt — the one place on the table that is always empty. Being
   off the top edge means it costs the table no height at all, so syncTableInset()
   never has to squish the felt to clear it, and it stays well clear of the player
   menu in the top-right corner. Only the solo bar collapses here — the score /
   pause / autoplay controls have room on desktop and stay put (mobile portrait
   collapses those too, further down). */
@media (min-width: 481px) {
    body:not(.controls-open) #solo-controls { display: none !important; }

    #solo-controls {
        top: 50%;
        left: 50%;
        right: auto;
        -webkit-transform: translate(-50%, -50%);
        transform: translate(-50%, -50%);
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
        padding: 14px 18px;
        font-size: 13px;
        background: rgba(0,0,0,0.85);
        box-shadow: 0 6px 24px rgba(0,0,0,0.5);
    }
    #solo-controls .settings-title {
        display: block;
        text-align: center;
        letter-spacing: 0.08em;
        text-transform: uppercase;
        font-size: 11px;
        color: #f0c050;
        border-bottom: 1px solid rgba(255,255,255,0.15);
        padding-bottom: 6px;
    }
    #solo-controls label { justify-content: space-between; gap: 14px; }

    /* The gear only has something to open in a solo game. Centred at the top: it
       clears the player menu in the right corner, and sits above the felt's top
       rim so it never covers a seat. */
    #controls-toggle { display: none; }
    #game-table[data-solo="1"] ~ #controls-toggle {
        display: block;
        left: 50%;
        right: auto;
        -webkit-transform: translateX(-50%);
        transform: translateX(-50%);
    }
}

/* Ask-to-join: compact dropdown (a select of bot seats + a button). */
#join-control {
    display: inline-flex;
    gap: 6px;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
}
#join-control select { font-size: 12px; padding: 1px 4px; border-radius: 3px; max-width: 170px; }

/* Numeric trick count replaces the dot row everywhere (desktop + mobile).
   Pinned to the top of the felt (where the dot row sat), centered, even with
   the top players. */
.tricks-taken { display: none; }
.tricks-num {
    position: absolute;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 110;
    text-align: center;
    font-size: 18px;
    line-height: 1;
    font-weight: bold;
}
.tricks-num .team-1-trick-num { color: lightblue; }
.tricks-num .team-2-trick-num { color: lightcoral; }
.tricks-num .tricks-num-sep { color: #999; margin: 0 5px; }
/* end solo controls */

/* ===== per-seat bot action buttons: overlaid on the avatar tile ===== */
.bot-seat-actions {
    position: absolute;
    top: 6px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 6px;
    z-index: 25;
}

.bot-seat-action {
    line-height: 1;
    padding: 0 5px;
    font-size: 13px;
    cursor: pointer;
    background: rgba(0,0,0,0.6);
    color: #fff;
    border: 1px solid rgba(255,255,255,0.45);
    border-radius: 3px;
}
.bot-seat-action:hover { background: rgba(0,0,0,0.85); }
/* end bot-seat-actions */

/* === "+ Bot" on an open seat ===
   It was a bare Bootstrap outline button: grey border, grey text, sitting on
   green felt with nothing behind it, so it read as disabled. Give it the same
   solid chip treatment as the name plates, a size you can actually hit, and
   real contrast.

   It also used to sit in normal flow, which put it wherever the seat's rotated
   frame happened to throw it — the left seat's button landed up near the top of
   the table, so you'd click it and a bot would appear on the left. It's now
   pinned to the centre of its own seat, so the button you click is always the
   seat you get. */
.players .player .add-bot-btn {
    position: absolute;
    top: 50%;
    left: 50%;
    background-color: #272727;
    border: 2px solid #000000;
    border-radius: 8px;
    color: #ffffff;
    font-size: 13px;
    font-weight: bold;
    line-height: 1;
    padding: 7px 12px;
    box-shadow: 0 0 4px 2px rgba(0, 0, 0, 0.35);
    z-index: 25;
    white-space: nowrap;
    -webkit-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
}

.players .player .add-bot-btn:hover {
    background-color: #ffffff;
    border-color: #000000;
    color: #000000;
}

/* Read upright for the viewer on every seat. The seat containers are rotated
   (-90 left, +90 right, 180 bottom) so the label inherits that and lands
   sideways or upside down — cancel it out, exactly like the name plates do.
   The centring translate has to be repeated here or these rules drop it. */
.players .player.player-1 .add-bot-btn {
    -webkit-transform: translate(-50%, -50%) rotatez(90deg);
    transform: translate(-50%, -50%) rotatez(90deg);
}

.players .player.player-4 .add-bot-btn {
    -webkit-transform: translate(-50%, -50%) rotatez(-90deg);
    transform: translate(-50%, -50%) rotatez(-90deg);
}

.players .player.player-5 .add-bot-btn,
.players .player.player-6 .add-bot-btn {
    -webkit-transform: translate(-50%, -50%) rotatez(180deg);
    transform: translate(-50%, -50%) rotatez(180deg);
}

/* === mobile: show numeric trick count instead of the dot row === */
@media (max-width: 480px) {
    .tricks-taken { display: none !important; }
    .tricks-num { display: block !important; font-size: 15px; line-height: 1; margin-top: 2px; font-weight: bold; }
    .tricks-num .team-1-trick-num { color: lightblue; }
    .tricks-num .team-2-trick-num { color: lightcoral; }
    .tricks-num .tricks-num-sep { color: #999; margin: 0 5px; }
    /* keep the solo bar compact on phones */
    #solo-controls { font-size: 11px; gap: 8px; padding: 2px 8px; }

    /* Secondary controls collapse away until the gear is tapped, freeing the
       top of the felt so the top (and bottom) players aren't covered. */
    #controls-toggle { display: block; }
    body:not(.controls-open) .collapsible-control { display: none !important; }
    body:not(.controls-open) #solo-controls { display: none !important; }
}
