/* Look and feel of the game client: the same weathered-wood scene background
   (MariasekMonoGame.GameBackground = "background2", dimmed by BackgroundTint = Color.Gray),
   the same Gold button nine-patch and LeftRightSelector arrows sliced out of buttons.png,
   and the same gold accent color (ButtonThemes.GoldAccentColor). */

:root {
    --gold: #fbdfb7;           /* ButtonThemes.GoldAccentColor */
    --gold-dim: #cba869;       /* ButtonThemes.GoldMidtone */
    --cream: #fff4e6;          /* ButtonThemes._defaultTextColor */
    --ink: #0a0b0d;            /* ButtonThemes._darkTextColor */
    --green: #34bf49;          /* ButtonThemes.DefaultHintColor */
    --panel: rgba(16, 12, 8, 0.62);
    --panel-strong: rgba(16, 12, 8, 0.82);
    --rule: rgba(203, 168, 105, 0.35);
    /* Not from the game palette: the activity chart's session line is drawn over the bars far more
       often than over open panel (sessions are always well under the player count), so it is
       picked for contrast against gold above all. Light blue looks right on the dark panel but
       matches the bars in lightness and vanishes on them - 1.3:1 against the lit gold, against
       this red's 3.0:1. The greens above have the same problem. */
    --chart-sessions: #f5372a;
    --shadow: 0 2px 6px rgba(0, 0, 0, 0.85);
}

* {
    box-sizing: border-box;
}

html,
body {
    margin: 0;
    min-height: 100%;
}

body {
    font-family: "Trebuchet MS", "Segoe UI", Roboto, system-ui, sans-serif;
    color: var(--cream);
    background: #14100c url("../img/wood.jpg") center / cover no-repeat fixed;
    -webkit-text-size-adjust: 100%;
}

/* Stands in for the scene's BackgroundTint, which multiplies the wood texture by gray. */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    background: radial-gradient(ellipse at 50% 35%, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.68));
    pointer-events: none;
    z-index: -1;
}

.page {
    max-width: 1600px;
    margin: 0 auto;
    padding: 24px clamp(12px, 3vw, 40px) 48px;
}

/* ---------- header ---------- */

.topbar {
    display: flex;
    align-items: center;
    gap: 18px;
    flex-wrap: wrap;
    padding-bottom: 20px;
    border-bottom: 1px solid var(--rule);
}

.brand-icon {
    width: 72px;
    height: 72px;
    flex: 0 0 auto;              /* a .avatar div has no intrinsic size to keep the flex row off it */
    border-radius: 14px;
    border: 2px solid var(--gold-dim);
    box-shadow: var(--shadow);
}

/* Player portrait in the .brand-icon slot (player.html). The frame is drawn whether or not a
   picture arrives, so the header keeps its height while the profile request is in flight and
   for a player who never picked an avatar - dummy_avatar.png fills it in those cases. */
.avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: var(--panel-strong);
}

.avatar img {
    width: 100%;
    height: 100%;
    /* The avatars the game produces are square (CropScene.TargetSize), but a picture that
       reached the database by some other route shouldn't be able to stretch the frame. */
    object-fit: cover;
    display: block;
}

/* Picture and name side by side in the rankings name cell, so a name long enough to wrap wraps
   beside the portrait rather than under it. */
.name-cell {
    display: flex;
    align-items: center;
    gap: 9px;
}

/* Row-sized portrait. flex: 0 0 auto because the name beside it is the part that should give
   when the column is narrow. */
.avatar-inline {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    border-radius: 8px;
    border: 1px solid var(--gold-dim);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);
    /* .deleted strikes its row's name through, and a line-through inherited from the cell paints
       across an inline replaced element too - it would run over the portrait as readily as over
       the name. */
    text-decoration: none;
}

.brand-text {
    flex: 1 1 auto;
}

.brand-text h1 {
    margin: 0;
    font-size: clamp(28px, 5vw, 46px);
    font-style: italic;
    letter-spacing: 0.5px;
    color: var(--gold);
    text-shadow: 0 2px 0 rgba(0, 0, 0, 0.7), 0 0 18px rgba(0, 0, 0, 0.6);
}

.brand-text p {
    margin: 2px 0 0;
    font-size: clamp(13px, 2vw, 17px);
    letter-spacing: 3px;
    text-transform: uppercase;
    color: rgba(255, 244, 230, 0.65);
}

.topnav {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
}

/* ---------- Gold nine-patch button (ButtonTheme.Gold, buttons.png at 0,0) ---------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 0;                       /* the nine-patch borders supply the whole 49px height */
    min-width: 101px;
    /* The button face in button-gold.png starts 5px in from the top and the left edge of the
       source rect (the right and bottom edges have no such gap), so the middle of the border box
       sits above and left of the middle of the face the user sees. The label is a zero-height,
       zero-leading line centred on the content box, so padding the content box down and right
       puts it in the middle of the face: 5px on the left, and 7px on top - twice the vertical
       offset, because the padding pushes the bottom of the face down along with the label. */
    padding: 7px 14px 0 19px;
    border-style: solid;
    border-width: 24px 24px 25px;
    border-image: url("../img/button-gold.png") 23 24 26 fill / 24px 24px 25px stretch;
    font: inherit;
    font-size: 17px;
    font-weight: 700;
    line-height: 0;
    color: rgba(0, 0, 0, 0.78);      /* ButtonTheme.Gold TextColor */
    text-decoration: none;
    white-space: nowrap;
    background: none;
    cursor: pointer;
    filter: drop-shadow(0 3px 4px rgba(0, 0, 0, 0.6));
}

.btn:hover {
    filter: drop-shadow(0 3px 4px rgba(0, 0, 0, 0.6)) brightness(1.08);
}

.btn:active {
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.6)) brightness(0.86);
}

.btn:focus-visible {
    outline: 2px solid var(--gold);
    outline-offset: 3px;
}

/* ---------- gilded oak plaque heading (ButtonTheme.GildedOak, buttons.png at 4,272) ---------- */

.plaque {
    /* the art is a plaque, not a rail - let it keep plaque proportions on wide screens */
    max-width: 760px;
    margin: 28px auto 22px;
    /* Same story as .btn: the face in plaque-oak.png does not sit in the middle of its source
       rect - it is inset 3px on the left against nothing on the right, and 3px at the bottom
       against 1px at the top. The extra 3px of left padding moves the heading right by half of
       that, and the 2px of bottom padding moves the face down past it, by half of that. */
    padding: 0 8px 2px 11px;
    border-style: solid;
    border-width: 38px 86px;
    border-image: url("../img/plaque-oak.png") 38 86 fill / 38px 86px stretch;
    min-height: 0;
    font-size: clamp(17px, 2.4vw, 22px);
    font-weight: 700;
    line-height: 0;
    text-align: center;
    letter-spacing: 1px;
    color: var(--ink);
    text-shadow: 0 1px 0 rgba(255, 235, 200, 0.35);
    filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.6));
}

/* ---------- landing page tiles ---------- */

.tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 16px;
}

.tile {
    padding: 18px 20px;
    background: var(--panel);
    border: 1px solid var(--rule);
    border-radius: 10px;
    box-shadow: inset 0 1px 0 rgba(251, 223, 183, 0.14), 0 4px 12px rgba(0, 0, 0, 0.5);
}

.tile-value {
    display: block;
    font-size: clamp(24px, 3.4vw, 34px);
    font-weight: 700;
    color: var(--gold);
    text-shadow: var(--shadow);
    overflow-wrap: anywhere;
}

/* dates and version strings need a lot more room than a counter does */
.tile-value.text {
    font-size: clamp(17px, 1.9vw, 22px);
    line-height: 1.35;
}

.tile-label {
    display: block;
    margin-top: 6px;
    font-size: 13px;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: rgba(255, 244, 230, 0.6);
}

/* ---------- 24h activity chart (info.js, /api/mariasek/activity) ---------- */

.chart-card {
    margin-top: 24px;
    padding: 20px 22px 16px;
    background: var(--panel);
    border: 1px solid var(--rule);
    border-radius: 10px;
    box-shadow: inset 0 1px 0 rgba(251, 223, 183, 0.14), 0 4px 12px rgba(0, 0, 0, 0.5);
}

.chart-title {
    margin: 0 0 18px;
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: rgba(255, 244, 230, 0.7);
}

/* The axis column is sized in ch so the gutter grows with the widest tick label. */
.chart {
    display: grid;
    grid-template-columns: 4ch minmax(0, 1fr);
    gap: 8px;
}

.chart-axis {
    position: relative;
    height: 180px;
    font-size: 11px;
    color: rgba(255, 244, 230, 0.45);
}

/* Each tick is anchored by its own bottom edge at the value's height in the plot, then lifted by
   half its line height so the text sits centred on the gridline rather than resting on it. */
.chart-tick {
    position: absolute;
    right: 0;
    line-height: 12px;
    margin-bottom: -6px;
}

.chart-plot {
    position: relative;
    height: 180px;
    display: grid;
    grid-template-columns: repeat(24, minmax(0, 1fr));
    gap: 2px;
    align-items: end;
    border-bottom: 1px solid var(--rule);
}

/* Gridlines run behind the bars, drawn as one element per tick so they line up with the labels. */
.chart-gridline {
    position: absolute;
    left: 0;
    right: 0;
    border-top: 1px dashed rgba(203, 168, 105, 0.18);
    pointer-events: none;
}

.chart-col {
    position: relative;
    height: 100%;
    display: flex;
    align-items: flex-end;
}

.chart-bar {
    width: 100%;
    /* A zero-player hour still needs to be visibly "there" rather than absent, hence min-height. */
    min-height: 2px;
    position: relative;
    border-radius: 3px 3px 0 0;
    background: linear-gradient(180deg, var(--gold) 0%, var(--gold-dim) 100%);
    box-shadow: 0 -1px 4px rgba(251, 223, 183, 0.25);
}

/* The queued share sits at the foot of the same bar: it is part of the online headcount, not an
   extra on top of it. Both are hourly maxima, so it is a share of the hour, not of one instant. */
.chart-bar-queue {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    border-radius: 0 0 3px 3px;
    /* Dark enough to read as a distinct segment against the lit gold above it, and against the
       panel behind a one-player bar. */
    background: #7a5a2e;
    border-top: 1px solid rgba(20, 16, 12, 0.55);
}

/* Hours with no samples at all - server down, or not up a full day yet. */
.chart-col.empty {
    background: repeating-linear-gradient(135deg,
                                          rgba(255, 244, 230, 0.1) 0 4px,
                                          transparent 4px 8px);
    border-radius: 3px 3px 0 0;
}

/* Sessions are not a share of the player count, so they get their own stepped line across the
   plot instead of a segment inside the bars. Scaled against the same axis. */
.chart-line {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
    pointer-events: none;
}

.chart-line path {
    fill: none;
    stroke: var(--chart-sessions);
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.7));
}

.chart-hours {
    display: grid;
    grid-template-columns: repeat(24, minmax(0, 1fr));
    gap: 2px;
    margin: 6px 0 0 calc(4ch + 8px);
    font-size: 11px;
    text-align: center;
    color: rgba(255, 244, 230, 0.45);
}

.chart-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 18px;
    margin-top: 14px;
    font-size: 12px;
    letter-spacing: 0.5px;
    color: rgba(255, 244, 230, 0.6);
}

.legend-item {
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

.swatch {
    width: 12px;
    height: 12px;
    border-radius: 3px;
    flex: none;
}

.swatch-online {
    background: linear-gradient(180deg, var(--gold) 0%, var(--gold-dim) 100%);
}

.swatch-queue {
    background: #7a5a2e;
}

/* a line, not a block - it stands for the stepped session line */
.swatch-session {
    height: 3px;
    border-radius: 2px;
    background: var(--chart-sessions);
}

.swatch-empty {
    background: repeating-linear-gradient(135deg,
                                          rgba(255, 244, 230, 0.22) 0 3px,
                                          transparent 3px 6px);
    border: 1px solid var(--rule);
}

.chart-note {
    margin: 10px 0 0;
    font-size: 12px;
    color: rgba(255, 244, 230, 0.45);
}

.downloads {
    display: flex;
    gap: 24px;
    margin-top: 32px;
    justify-content: center;
    flex-wrap: wrap;
    align-items: center;
}

.store-link {
    display: flex;
    align-items: center;
    transition: transform 0.2s ease, filter 0.2s ease;
    text-decoration: none;
}

.store-link:hover {
    transform: scale(1.05);
    filter: brightness(1.1);
}

.app-badge {
    height: 40px;
    width: auto;
    display: block;
    vertical-align: middle;
}

.notice {
    margin: 32px 0;
    text-align: center;
    font-size: 22px;
    color: var(--gold);
    text-shadow: var(--shadow);
}

.footnote {
    margin-top: 22px;
    text-align: center;
    font-size: 13px;
    color: rgba(255, 244, 230, 0.45);
}

/* ---------- rankings layout: the scene's left control column plus the table ---------- */

.rankings {
    display: grid;
    grid-template-columns: 300px minmax(0, 1fr);
    gap: 24px;
    align-items: start;
    margin-top: 24px;
}

.controls {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 18px 14px;
    background: var(--panel);
    border: 1px solid var(--rule);
    border-radius: 10px;
    box-shadow: inset 0 1px 0 rgba(251, 223, 183, 0.14), 0 4px 12px rgba(0, 0, 0, 0.5);
    position: sticky;
    top: 16px;
}

.controls h2 {
    margin: 0;
    text-align: center;
    font-size: 26px;
    color: var(--gold);
    text-shadow: var(--shadow);
}

.control-label {
    margin: 4px 0 -8px;
    text-align: center;
    font-size: 13px;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: rgba(255, 244, 230, 0.6);
}

.controls .btn {
    align-self: center;
    margin-top: 6px;
}

/* ---------- LeftRightSelector look-alike ---------- */

.selector {
    display: flex;
    align-items: center;
    gap: 6px;
}

.selector[hidden] {
    display: none;
}

.selector .arrow {
    flex: 0 0 auto;
    width: 44px;
    height: 49px;
    padding: 0;
    border: 0;
    background: transparent center / contain no-repeat;
    cursor: pointer;
    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.7));
}

.selector .arrow:hover {
    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.7)) brightness(1.15);
}

.selector .arrow:active {
    transform: scale(0.92);
}

.selector .arrow:focus-visible {
    outline: 2px solid var(--gold);
    outline-offset: 2px;
    border-radius: 4px;
}

.selector .arrow.left {
    background-image: url("../img/arrow-left.png");
}

.selector .arrow.right {
    background-image: url("../img/arrow-right.png");
}

.selector .value {
    flex: 1 1 auto;
    min-width: 0;
    text-align: center;
    font-size: 21px;
    font-weight: 600;
    color: var(--gold);
    text-shadow: var(--shadow);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.selector.disabled {
    opacity: 0.5;
    pointer-events: none;
}

/* ---------- rankings table ---------- */

.board {
    position: relative;
    min-height: 240px;
    padding: 10px 6px 6px;
    background: var(--panel-strong);
    border: 1px solid var(--rule);
    border-radius: 10px;
    box-shadow: inset 0 1px 0 rgba(251, 223, 183, 0.14), 0 4px 12px rgba(0, 0, 0, 0.5);
    overflow-x: auto;
}

table.rankings-table {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

table.rankings-table th {
    position: sticky;
    top: 0;
    padding: 8px 10px;
    background: rgba(16, 12, 8, 0.95);
    border-bottom: 1px solid var(--rule);
    font-size: 14px;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--gold-dim);
    text-align: right;
}

table.rankings-table th:first-child,
table.rankings-table th.name {
    text-align: left;
}

table.rankings-table td {
    padding: 7px 10px;
    border-bottom: 1px solid rgba(203, 168, 105, 0.12);
    font-size: 17px;
    text-align: right;
}

table.rankings-table td.rank {
    width: 1%;
    color: rgba(255, 244, 230, 0.5);
    text-align: left;
}

table.rankings-table td.name {
    text-align: left;
    white-space: normal;
    overflow-wrap: anywhere;
}

table.rankings-table tbody tr {
    cursor: pointer;
}

table.rankings-table tbody tr:nth-child(even) {
    background: rgba(0, 0, 0, 0.22);
}

table.rankings-table tbody tr:hover {
    background: rgba(251, 223, 183, 0.08);
}

/* TextBox.HighlightColor = Settings.HighlightedTextColor (gold) in the rankings scene */
table.rankings-table tbody tr.highlighted td {
    color: var(--gold);
    font-weight: 700;
    background: rgba(251, 223, 183, 0.12);
}

.deleted td.name {
    text-decoration: line-through;
    opacity: 0.6;
}

/* the name cell is a real link so a row can be opened in a new tab, but it should read as part
   of the row rather than as a blue link */
.player-link {
    color: inherit;
    text-decoration: none;
}

table.rankings-table tbody tr:hover .player-link {
    color: var(--gold);
    text-decoration: underline;
}

/* ---------- player detail page ---------- */

.player-main {
    display: flex;
    flex-direction: column;
    gap: 24px;
    min-width: 0;
}

.section-title {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin: 6px 6px 10px;
    font-size: 20px;
    font-weight: 700;
    letter-spacing: 1px;
    color: var(--gold);
    text-shadow: var(--shadow);
}

.session-count {
    font-size: 14px;
    font-weight: 400;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: rgba(255, 244, 230, 0.55);
}

/* the summary is a single row - it reads as a headline, not as a table body */
table.summary-table td {
    font-size: 21px;
    font-weight: 700;
    color: var(--gold);
}

/* The pointer above belongs to the rankings, where the whole row opens a player. Nothing in
   these three is clickable but the links inside them, so their rows keep the plain cursor. */
table.summary-table tbody tr,
table.details-table tbody tr,
table.session-table tbody tr {
    cursor: default;
}

/* Except a game whose saved XML is still there, which does open its review from anywhere in
   the row - the rows without one look the same and are not clickable. */
table.session-table tbody tr.has-review {
    cursor: pointer;
}

table.summary-table tbody tr:hover,
table.session-table tbody tr:hover {
    background: rgba(251, 223, 183, 0.05);
}

/* ---------- charts ---------- */

.charts {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 18px;
    padding: 10px 4px 18px;
}

svg.radar {
    width: min(100%, 380px);
    height: auto;
}

.radar-grid {
    fill: none;
    stroke: rgba(203, 168, 105, 0.22);
    stroke-width: 1;
}

.radar-axis {
    stroke: rgba(203, 168, 105, 0.35);
    stroke-width: 1;
}

.radar-series {
    fill-opacity: 0.28;
    stroke-width: 2.5;
    stroke-linejoin: round;
}

.radar-label {
    font: 600 13px "Trebuchet MS", "Segoe UI", sans-serif;
    fill: var(--cream);
}

.radar-value {
    font-weight: 400;
    fill: rgba(255, 244, 230, 0.6);
}

.bars {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 10px;
    width: 100%;
}

.bar-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
}

svg.bar {
    width: 100%;
    height: 110px;
}

.bar-zero {
    stroke: rgba(203, 168, 105, 0.45);
    stroke-width: 1;
}

.bar-label {
    font-size: 14px;
    color: rgba(255, 244, 230, 0.7);
}

.bar-value {
    font-size: 16px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* ---------- history line chart ---------- */

.chart-legend {
    display: flex;
    gap: 18px;
    margin: 0 6px 6px;
    font-size: 14px;
}

.chart-legend .key::before {
    content: "";
    display: inline-block;
    width: 22px;
    height: 3px;
    margin-right: 7px;
    vertical-align: middle;
}

/* the two series keep the game's own colors: Player1Color for money, Player3Color for Elo */
.chart-legend .key.money::before {
    background: #ff4c4c;
}

.chart-legend .key.elo::before {
    background: #0399e5;
}

.line-chart svg.line {
    display: block;
    width: 100%;
    height: auto;
}

.line-grid {
    stroke: rgba(203, 168, 105, 0.16);
    stroke-width: 1;
}

.line-zero {
    stroke: rgba(203, 168, 105, 0.5);
    stroke-width: 1;
}

.line-label {
    font: 400 12px "Trebuchet MS", "Segoe UI", sans-serif;
    fill: rgba(255, 244, 230, 0.55);
}

.chart-footer {
    margin: 4px 8px 8px;
    text-align: right;
    font-size: 18px;
    font-variant-numeric: tabular-nums;
    color: var(--gold);
    text-shadow: var(--shadow);
    white-space: pre;
}

/* ---------- session tables ---------- */

#sessions {
    display: flex;
    flex-direction: column;
    gap: 22px;
}

.sessions-title {
    margin: 8px 6px 0;
    font-size: 24px;
    color: var(--gold);
    text-shadow: var(--shadow);
}

.board.session {
    min-height: 0;
}

/* multi-row headers can't stick without overlapping each other */
table.session-table th {
    position: static;
}

table.session-table th.seat {
    text-align: center;
    font-size: 15px;
    text-transform: none;
    letter-spacing: 0;
    color: var(--cream);
    border-bottom: 0;
}

table.session-table th.seat.me {
    color: var(--gold);
}

table.session-table th.seat.deleted-name {
    text-decoration: line-through;
    opacity: 0.6;
}

table.session-table th.seat .player-link:hover {
    text-decoration: underline;
}

/* the sitting's result, right under the names it belongs to */
table.session-table tr.session-total th {
    font-size: 17px;
    font-weight: 700;
    text-transform: none;
    letter-spacing: 0;
    font-variant-numeric: tabular-nums;
    border-bottom: 0;
}

table.session-table tr.session-units th {
    font-size: 12px;
    font-weight: 400;
    color: rgba(255, 244, 230, 0.45);
}

table.session-table td.time,
table.session-table th.time {
    color: rgba(255, 244, 230, 0.5);
    font-size: 14px;
    text-align: left;
}

table.session-table td.me {
    font-weight: 700;
    background: rgba(251, 223, 183, 0.07);
}

/* the game type and who chose it stack in one cell; letting them wrap mid-word would shred
   long player names across four lines */
table.session-table td.name {
    white-space: nowrap;
    overflow-wrap: normal;
}

.starter {
    display: block;
    color: rgba(255, 244, 230, 0.4);
    font-size: 14px;
}

/* gains and losses, as the scenes color them */
.pos {
    color: #7ee081;
}

.neg {
    color: #ff8a8a;
}

.overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    text-align: center;
    background: rgba(16, 12, 8, 0.6);
    border-radius: 10px;
    font-size: 24px;
    color: var(--gold);
    text-shadow: var(--shadow);
}

[hidden] {
    display: none !important;
}

/* ---------- game review page ---------- */

/* The card art is Mariasek.Content/Assets/marias.png re-sliced for the web by
   tools/make_web_cards.py: a value-by-suit grid of 168x279 cards, each centred in a 176x287 cell
   so the four transparent pixels of padding swallow whatever the browser oversamples when it
   scales the sheet. Every measurement below is a fraction of --card-w, so one variable resizes
   the whole board. */
.review {
    --card-w: 84px;
    --cell-w: calc(var(--card-w) * 176 / 168);
    --cell-h: calc(var(--card-w) * 287 / 168);
    --card-h: calc(var(--card-w) * 279 / 168);
    /* GameReview steps a hand along by CardWidth * scale - 20 per card and fans the three cards
       of a round down by 20 virtual pixels each; at its 0.42 scale those are 0.855 of a card
       width and 0.0875 of a card height. */
    --card-step: calc(var(--card-w) * 0.855);
    --card-stagger: calc(var(--card-h) * 0.0875);
    display: flex;
    flex-direction: column;
    gap: 18px;
    padding: 4px 4px 8px;
}

/* the scene writes each row's name above its cards rather than beside them */
.review-row {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.review-name {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
}

.review-player {
    font-size: 17px;
    font-weight: 700;
    color: var(--gold);
    text-shadow: var(--shadow);
}

.review-bid {
    font-size: 14px;
    color: rgba(255, 244, 230, 0.55);
}

.hand {
    position: relative;
    flex: none;
    width: calc(var(--card-step) * (var(--n) - 1) + var(--cell-w));
    height: calc(var(--cell-h) + var(--card-stagger) * var(--stagger) * (var(--n) - 1));
}

.card {
    position: absolute;
    left: calc(var(--card-step) * var(--i));
    top: calc(var(--card-stagger) * var(--stagger) * var(--i));
    width: var(--cell-w);
    height: var(--cell-h);
    z-index: var(--i);
    background-image: url(/img/cards.png);
    background-size: calc(var(--cell-w) * 8) calc(var(--cell-h) * 4);
    background-position: calc(var(--cell-w) * var(--col) * -1) calc(var(--cell-h) * var(--row) * -1);
    /* the tint below blends in multiply mode; without a stacking context of its own it would
       reach through to the card underneath it in the fan */
    isolation: isolate;
}

/* Sprite.Tint multiplies the texture, so the tint is an overlay in multiply mode masked by the
   same sprite - it has to stop at the card's artwork instead of filling the whole cell. */
.card.tint-won::after,
.card.tint-lost::after {
    content: "";
    position: absolute;
    inset: 0;
    mix-blend-mode: multiply;
    -webkit-mask-image: url(/img/cards.png);
    mask-image: url(/img/cards.png);
    -webkit-mask-size: calc(var(--cell-w) * 8) calc(var(--cell-h) * 4);
    mask-size: calc(var(--cell-w) * 8) calc(var(--cell-h) * 4);
    -webkit-mask-position: calc(var(--cell-w) * var(--col) * -1) calc(var(--cell-h) * var(--row) * -1);
    mask-position: calc(var(--cell-w) * var(--col) * -1) calc(var(--cell-h) * var(--row) * -1);
}

/* GameSettings.ReviewPtsWonRgba / ReviewPtsLostRgba */
.card.tint-won::after {
    background: #90ee90;
}

.card.tint-lost::after {
    background: #ff90a0;
}

/* the scene stacks the round's three text lines to the right of the fanned cards */
.review-round {
    display: flex;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 8px 22px;
}

.round-plays {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

.round-plays li {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 10px;
    color: var(--cream);
}

/* Settings.HighlightedTextColor on the seat that took the trick, and on the card it took it with */
.round-plays li.winner .round-player {
    color: var(--gold);
    font-weight: 700;
}

.round-plays li.winner .round-card {
    color: var(--gold);
}

.round-player {
    min-width: 130px;
}

.round-card {
    font-size: 14px;
    color: rgba(255, 244, 230, 0.6);
}

.round-note {
    font-size: 13px;
    font-style: italic;
    color: rgba(255, 244, 230, 0.45);
}

/* ReviewScene's description block, split into a definition list and a score table */
.game-facts {
    margin: 0;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 4px 12px;
    font-size: 15px;
}

.game-facts dt {
    color: rgba(255, 244, 230, 0.55);
}

.game-facts dd {
    margin: 0;
    color: var(--cream);
    overflow-wrap: anywhere;
}

/* nothing in this table is clickable except the names, so it keeps the default cursor */
table.score-table tbody tr {
    cursor: default;
}

table.score-table tbody tr.akter td.name {
    color: var(--gold);
    font-weight: 700;
}

@media (max-width: 860px) {
    .rankings {
        grid-template-columns: minmax(0, 1fr);
    }

    .controls {
        position: static;
    }

    table.rankings-table td {
        font-size: 15px;
        padding: 6px 7px;
    }

    table.rankings-table th {
        padding: 7px;
        font-size: 12px;
    }

    .name-cell {
        gap: 7px;
    }

    .avatar-inline {
        width: 24px;
        height: 24px;
        border-radius: 7px;
    }

    .review {
        --card-w: 62px;
    }

    .round-player {
        min-width: 0;
    }
}

/* Seven columns leave the name perhaps sixty pixels on a small phone, and the portrait wants
   half of that - below this the names wrap to a letter a line, so the picture goes instead.
   Measured on the rankings table: it still fits at 414px, and breaks by 375px. The player page
   keeps its own portrait at every width - it has a header to itself. */
@media (max-width: 479px) {
    .avatar-inline {
        display: none;
    }

    .name-cell {
        gap: 0;
    }

    .review {
        --card-w: 48px;
    }
}
