/* ==== theme tokens ==== */
:root {
    --page-bg: #ffffff;
    --text: #344861;
    --text-muted: #6e7c8c;
    --accent: #325aaf;
    --accent-soft: #dce3ed;
    --board-bg: #ffffff;
    /* Ring buttons float over the board, so they let some of it through. The alpha comes
       from the settings slider (Game.razor sets --ring-alpha); the channels are per theme.
       The two are combined on .digit-ring, not here, so that a theme scoped to a descendant
       (Hell lives on .game-page) still gets its own channels. */
    --ring-rgb: 255, 255, 255;
    --line: #bfc6d4;
    --line-strong: #344861;
    --cell-selected: #7fb5e6;
    --notes-accent: #7a4fd6;
    --notes-glow: rgba(122, 79, 214, 0.28);
    /* row/column/box and same-digit highlights darken whatever the cell already shows */
    --highlight-peer: rgba(20, 40, 70, 0.09);
    --highlight-same: rgba(20, 40, 70, 0.2);
    /* the selected cell is darkened harder than the row/column/box and same-digit marks */
    --highlight-selected: rgba(20, 40, 70, 0.34);
    --cell-error-bg: #f7cfd6;
    --digit-given: #344861;
    --digit-user: #325aaf;
    --digit-wrong: #e55c6c;
    /* the wrong digit sits on the pink error tint, so it needs to be far darker than
       the accent red used on plain page backgrounds */
    --digit-wrong-ink: #9c1826;
    --note: #6e7c8c;
    --cage-line: #5b6b7f;
    --cage-sum: #5b6b7f;
    --button-bg: #eaeef4;
    --button-hover: #dce3ed;
    /* pastel cage fills (colored-cages mode) */
    --cage-fill-0: #f6e7c9;
    --cage-fill-1: #dcedd5;
    --cage-fill-2: #d7e6f4;
    --cage-fill-3: #f4dbe3;
    --cage-fill-4: #e6def2;
}

:root[data-theme="dark"] {
    --page-bg: #10151d;
    --text: #d3dbe8;
    --text-muted: #8b98ab;
    --accent: #6ea8ff;
    --accent-soft: #24354f;
    --board-bg: #171e29;
    --ring-rgb: 23, 30, 41;
    --line: #33404f;
    --line-strong: #8296ad;
    --cell-selected: #3d6ba8;
    --notes-accent: #a98bff;
    --notes-glow: rgba(169, 139, 255, 0.3);
    /* on dark backgrounds the highlight lightens instead */
    --highlight-peer: rgba(200, 220, 255, 0.1);
    --highlight-same: rgba(200, 220, 255, 0.22);
    --highlight-selected: rgba(200, 220, 255, 0.38);
    --cell-error-bg: #4c2430;
    --digit-given: #e6edf7;
    --digit-user: #7ab1ff;
    --digit-wrong: #ff8296;
    --digit-wrong-ink: #ff9fae;
    --note: #8b98ab;
    --cage-line: #93a5bb;
    --cage-sum: #a5b4c8;
    --button-bg: #223047;
    --button-hover: #2c3e5c;
    --cage-fill-0: #383023;
    --cage-fill-1: #263728;
    --cage-fill-2: #223243;
    --cage-fill-3: #3a2733;
    --cage-fill-4: #302a41;
}

* {
    box-sizing: border-box;
}

html, body {
    margin: 0;
    padding: 0;
    background: var(--page-bg);
    color: var(--text);
    font-family: "Segoe UI", system-ui, -apple-system, Roboto, "Helvetica Neue", sans-serif;
}

button {
    font-family: inherit;
    cursor: pointer;
}

a {
    color: var(--accent);
    text-decoration: none;
}

/* ==== difficulty colors (dot + accent on the status card and choice buttons) ==== */
.diff-easy { --diff-color: #3fbf6f; }
.diff-medium { --diff-color: #4c8dff; }
.diff-hard { --diff-color: #ff9d42; }
.diff-expert { --diff-color: #ff5c74; }
.diff-nightmare { --diff-color: #b44cff; }
.diff-hell { --diff-color: #c1121f; }

/* the last two levels are meant to look dangerous even in the plain menus */
.difficulty-button.diff-nightmare,
.difficulty-option.diff-nightmare {
    font-weight: 700;
    letter-spacing: 0.02em;
}

.difficulty-button.diff-hell,
.difficulty-option.diff-hell {
    font-weight: 700;
    letter-spacing: 0.03em;
    color: var(--diff-color);
    text-transform: uppercase;
}

.diff-dot {
    width: 0.6rem;
    height: 0.6rem;
    border-radius: 50%;
    background: var(--diff-color, var(--text-muted));
    flex-shrink: 0;
}

/* ==== keyboard hints ==== */
.key-hint {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.35rem;
    height: 1.35rem;
    padding: 0 0.3rem;
    border: 1px solid var(--line);
    border-bottom-width: 2px;
    border-radius: 0.35rem;
    background: var(--page-bg);
    color: var(--text-muted);
    font-family: inherit;
    font-size: 0.62rem;
    font-weight: 700;
    line-height: 1;
    text-transform: uppercase;
    white-space: nowrap;
}

/* wide buttons carry the badge at their right edge (symmetric padding keeps the label centered) */
.invite-button,
.new-game-button,
.new-game-option,
.difficulty-button {
    position: relative;
    padding-left: 2.6rem;
    padding-right: 2.6rem;
}

.invite-button .key-hint,
.new-game-button .key-hint,
.new-game-option .key-hint,
.difficulty-button .key-hint {
    position: absolute;
    right: 0.6rem;
    top: 50%;
    transform: translateY(-50%);
}

/* badges on accent-colored buttons */
.new-game-button .key-hint,
.copy-button .key-hint {
    background: rgba(255, 255, 255, 0.18);
    border-color: rgba(255, 255, 255, 0.45);
    color: #fff;
}

.copy-button .key-hint {
    margin-left: 0.35rem;
}

/* ==== home ==== */
.home-page {
    position: relative;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    /* the top padding is the prefs bar's own row: the bar is positioned over this page,
       so without it the centred content slides under the bar on a short window */
    padding: 3.4rem 1rem 1rem;
    outline: none;
}

/* the wordmark is Czech text set in a Japanese brush face (Yuji Syuku). It already
   carries generous side bearings, so it needs no extra tracking — but it is a light,
   airy design, so it wants to be set larger than a normal heading. */
.brand {
    margin: 0 0 1.5rem;
    font-family: "Yuji Syuku", "Yu Mincho", "Hiragino Mincho ProN", Georgia, serif;
    font-size: clamp(2.6rem, 11vw, 4.5rem);
    font-weight: 400;
    line-height: 1.2;
    text-align: center;
    color: var(--accent);
}

.difficulty-menu {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    width: min(20rem, 90vw);
    text-align: center;
}

.difficulty-menu h2 {
    margin: 0 0 0.4rem;
    font-size: 1.1rem;
    font-weight: 600;
}

.difficulty-button {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding-top: 0.7rem;
    padding-bottom: 0.7rem;
    border: 0;
    border-radius: 0.6rem;
    background: var(--button-bg);
    color: var(--text);
    font-size: 1.05rem;
    font-weight: 600;
    text-align: center;
    transition: background 120ms;
}

.difficulty-button:hover:not(:disabled) {
    background: var(--button-hover);
}

.difficulty-button:disabled {
    opacity: 0.6;
    cursor: default;
}

.generating,
.not-found {
    color: var(--text-muted);
}

/* ==== game layout ==== */
/* one column width for the whole page, derived from the board plus the digit pad beside
   it, so the header, the status strip, the board and the multiplayer section all share
   the same left and right edges. --board-size is the single source of the board's size. */
.game-page {
    --board-size: min(92vw, 62dvh, 33rem);
    --side-width: 15.5rem;
    --page-width: min(100%, calc(var(--board-size) + var(--side-width) + 1.6rem));
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0.6rem 1rem 1.2rem;
    outline: none;
}

.game-header {
    width: var(--page-width);
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.3rem 0 0.8rem;
}

/* ==== preferences bar ==== */
.prefs-bar {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.home-prefs {
    position: absolute;
    top: 0.9rem;
    right: 1rem;
}

.pref-toggle {
    height: 2rem;
    padding: 0 0.6rem 0 0.45rem;
    border: 0;
    border-radius: 0.5rem;
    background: var(--button-bg);
    color: var(--text-muted);
    font-size: 0.76rem;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    white-space: nowrap;
    transition: background 120ms;
}

/* the theme and cage switches are icons alone, so they get a square button */
.pref-toggle.icon-only {
    width: 2rem;
    padding: 0;
    justify-content: center;
    gap: 0;
}

.pref-toggle:hover {
    background: var(--button-hover);
}

.pref-toggle.active {
    background: var(--accent-soft);
    color: var(--accent);
}

.pref-icon {
    font-size: 0.95rem;
    line-height: 1;
}

/* the bar floats over the home and account pages, so those pages keep a row of space
   free at the top — otherwise the centred wordmark rides up underneath it on a short
   window. Below the breakpoint the remaining labels go too and every button is an icon. */
@media (max-width: 760px) {
    .prefs-bar .pref-label {
        display: none;
    }

    .prefs-bar .pref-toggle {
        width: 2rem;
        padding: 0;
        justify-content: center;
        gap: 0;
    }

    .account-toggle {
        max-width: none;
    }
}

.lang-switch {
    display: inline-flex;
    border-radius: 0.55rem;
    overflow: hidden;
    background: var(--button-bg);
}

.lang-option {
    border: 0;
    background: transparent;
    color: var(--text-muted);
    font-size: 0.78rem;
    font-weight: 700;
    padding: 0.45rem 0.55rem;
}

.lang-option.active {
    background: var(--accent);
    color: #fff;
}

/* the in-game wordmark: same brush face as the home page, just smaller */
.brand-small {
    font-family: "Yuji Syuku", "Yu Mincho", "Hiragino Mincho ProN", Georgia, serif;
    font-size: 1.5rem;
    font-weight: 400;
}

/* ==== status cards (difficulty / mistakes / time) ==== */
.game-status {
    width: var(--page-width);
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 0.6rem;
    padding-bottom: 0.8rem;
}

.stat {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    min-width: 7.5rem;
    padding: 0.45rem 0.9rem;
    border-radius: 0.7rem;
    background: var(--button-bg);
}

.stat-label {
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.stat-value {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 1.15rem;
    font-weight: 600;
    line-height: 1.2;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

.game-difficulty {
    border-left: 4px solid var(--diff-color, var(--accent));
}

.game-timer {
    margin-left: auto;
}

.pause-button {
    border: 0;
    border-radius: 50%;
    width: 1.7rem;
    height: 1.7rem;
    background: var(--page-bg);
    color: var(--text);
    font-size: 0.8rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.pause-button:hover:not(:disabled) {
    background: var(--accent-soft);
}

.game-layout {
    width: var(--page-width);
    display: flex;
    gap: 1.6rem;
    align-items: flex-start;
}

.board-area {
    position: relative;
}

.board-cover {
    position: absolute;
    inset: 0;
    background: var(--board-bg);
    border: 2px solid var(--line-strong);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.8rem;
    color: var(--text-muted);
    font-weight: 600;
}

.resume-button {
    width: 3.6rem;
    height: 3.6rem;
    border: 0;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    font-size: 1.4rem;
}

/* ==== overlays ==== */
.overlay {
    position: fixed;
    inset: 0;
    background: rgba(20, 30, 46, 0.55);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 100;
}

.overlay-card {
    background: var(--page-bg);
    border-radius: 1rem;
    padding: 2rem 2.4rem;
    text-align: center;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
    width: min(24rem, 92vw);
}

.overlay-card h2 {
    margin: 0 0 0.6rem;
    color: var(--accent);
}

.dialog-prompt {
    color: var(--text-muted);
    margin: 0 0 1rem;
}

.dialog-note {
    color: var(--text-muted);
    font-size: 0.85rem;
    margin: 0.9rem 0 0;
}

.dialog-actions {
    display: flex;
    gap: 0.6rem;
    margin-top: 1.2rem;
}

.dialog-actions button {
    flex: 1;
}

.victory-time {
    font-size: 1.2rem;
    margin: 0.2rem 0;
}

.victory-meta {
    color: var(--text-muted);
    margin: 0.2rem 0 1rem;
}

/* ==== multiplayer ==== */
.players h3 {
    margin: 0 0 0.4rem;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

.players ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.player {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.player-dot {
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 50%;
    flex-shrink: 0;
}

.p-color-0 { background: #4c8dff; }
.p-color-1 { background: #ff9d42; }
.p-color-2 { background: #3fbf6f; }
.p-color-3 { background: #d75cff; }
.p-color-4 { background: #ff5c74; }
.p-color-5 { background: #2fc4c4; }
.p-color-6 { background: #c9a13a; }
.p-color-7 { background: #8a90ff; }

.player-name {
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.player-badge {
    margin-left: auto;
    font-size: 0.68rem;
    color: var(--text-muted);
    background: var(--button-bg);
    padding: 0.15rem 0.4rem;
    border-radius: 0.4rem;
    white-space: nowrap;
}

.spectating {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.9rem;
}

.invite-button {
    display: block;
    width: 100%;
    padding-top: 0.7rem;
    padding-bottom: 0.7rem;
    border: 0;
    border-radius: 0.6rem;
    background: var(--button-bg);
    color: var(--accent);
    font-size: 1rem;
    font-weight: 600;
}

.invite-button:hover {
    background: var(--button-hover);
}

.invite-label {
    display: block;
    text-align: left;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-muted);
    margin: 0.8rem 0 0.25rem;
}

.invite-row {
    display: flex;
    gap: 0.4rem;
}

.invite-link {
    flex: 1;
    min-width: 0;
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--line);
    border-radius: 0.5rem;
    background: var(--button-bg);
    color: var(--text);
    font-size: 0.8rem;
}

.copy-button {
    border: 0;
    border-radius: 0.5rem;
    background: var(--accent);
    color: #fff;
    font-weight: 600;
    font-size: 0.8rem;
    padding: 0 0.7rem;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
}

.close-button {
    margin-top: 1.1rem;
    width: 100%;
}

/* ==== nickname dialog ==== */
.nickname-input {
    width: 100%;
    padding: 0.65rem 0.8rem;
    border: 1px solid var(--line);
    border-radius: 0.55rem;
    background: var(--page-bg);
    color: var(--text);
    font-size: 1rem;
    margin-bottom: 0.9rem;
}

.play-button {
    width: 100%;
}

.play-button:disabled {
    opacity: 0.55;
}

/* ==== new game / difficulty choice ==== */
.new-game-button {
    display: block;
    width: 100%;
    text-align: center;
    padding-top: 0.7rem;
    padding-bottom: 0.7rem;
    border: 0;
    border-radius: 0.6rem;
    background: var(--accent);
    color: #fff;
    font-size: 1rem;
    font-weight: 600;
}

.new-game-button:disabled {
    opacity: 0.6;
    cursor: default;
}

.new-game-option {
    display: block;
    padding-top: 0.55rem;
    padding-bottom: 0.55rem;
    border: 0;
    border-radius: 0.5rem;
    background: var(--button-bg);
    color: var(--text);
    font-weight: 600;
    text-align: center;
    transition: background 120ms;
}

.new-game-option:hover:not(:disabled) {
    background: var(--accent-soft);
}

.new-game-option:disabled {
    opacity: 0.6;
    cursor: default;
}

.difficulty-options {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.difficulty-option {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding-left: 1rem;
    border-left: 4px solid var(--diff-color, var(--line));
}

/* replaying the same puzzle: set apart from the difficulty list above it */
.restart-option {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 0.7rem;
}

.restart-icon {
    font-size: 1.05em;
    line-height: 1;
}

/* the defeat screen offers just these two, stacked */
.defeat-actions {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.defeat-actions .restart-option {
    margin-top: 0;
}

.side-panel {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    width: var(--side-width);
    flex-shrink: 0;
}

@media (max-width: 760px) {
    .game-layout {
        flex-direction: column;
        align-items: center;
        width: 100%;
    }

    .side-panel {
        width: min(26rem, 100%);
    }

    .stat {
        flex: 1;
        min-width: 0;
        padding: 0.4rem 0.6rem;
    }

    .stat-value {
        font-size: 1rem;
    }

    /* icons only — the labels do not fit next to the brand */
    .pref-label {
        display: none;
    }

    .pref-toggle {
        width: 2.2rem;
        padding: 0;
        justify-content: center;
    }
}

/* ==== board ==== */
.board-wrap {
    position: relative;
    width: var(--board-size, min(92vw, 62dvh, 33rem));
    aspect-ratio: 1;
    user-select: none;
}

.board {
    position: absolute;
    inset: 0;
    display: grid;
    grid-template-columns: repeat(9, 1fr);
    grid-template-rows: repeat(9, 1fr);
    background: var(--board-bg);
    border: 2px solid var(--line-strong);
}

.cell {
    position: relative;
    border-right: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.cell:nth-child(9n) {
    border-right: 0;
}

.cell:nth-child(n+73) {
    border-bottom: 0;
}

.cell.wall-right {
    border-right: 2px solid var(--line-strong);
}

.cell.wall-bottom {
    border-bottom: 2px solid var(--line-strong);
}

/* pastel cage fills come first so selection/peer/error tints below win the cascade */
.cell.cage-c0 { background-color: var(--cage-fill-0); }
.cell.cage-c1 { background-color: var(--cage-fill-1); }
.cell.cage-c2 { background-color: var(--cage-fill-2); }
.cell.cage-c3 { background-color: var(--cage-fill-3); }
.cell.cage-c4 { background-color: var(--cage-fill-4); }

/* a translucent gradient layer sits above background-color, so the tint darkens
   the board background or the cage pastel alike instead of replacing it */
.cell.peer {
    background-image: linear-gradient(var(--highlight-peer), var(--highlight-peer));
}

.cell.same {
    background-image: linear-gradient(var(--highlight-same), var(--highlight-same));
}

.cell.error {
    background-color: var(--cell-error-bg);
}

/* the selection darkens the cage colour the cell already has, the same way the peer and
   same-digit highlights do — only harder, so it stays the strongest mark on the board.
   No background-color and no outline: the cage fill and its dashed border stay visible. */
.cell.selected {
    background-image: linear-gradient(var(--highlight-selected), var(--highlight-selected));
}

/* cells other participants have selected — ring in their color */
.cell.peer-cursor.pc-0 { box-shadow: inset 0 0 0 3px #4c8dff; }
.cell.peer-cursor.pc-1 { box-shadow: inset 0 0 0 3px #ff9d42; }
.cell.peer-cursor.pc-2 { box-shadow: inset 0 0 0 3px #3fbf6f; }
.cell.peer-cursor.pc-3 { box-shadow: inset 0 0 0 3px #d75cff; }
.cell.peer-cursor.pc-4 { box-shadow: inset 0 0 0 3px #ff5c74; }
.cell.peer-cursor.pc-5 { box-shadow: inset 0 0 0 3px #2fc4c4; }
.cell.peer-cursor.pc-6 { box-shadow: inset 0 0 0 3px #c9a13a; }
.cell.peer-cursor.pc-7 { box-shadow: inset 0 0 0 3px #8a90ff; }

.digit {
    font-size: clamp(1.1rem, 4.2dvh, 1.9rem);
    font-weight: 500;
    line-height: 1;
}

.digit.given {
    color: var(--digit-given);
    font-weight: 600;
}

.digit.user {
    color: var(--digit-user);
}

.digit.wrong {
    color: var(--digit-wrong-ink);
}

/* pencil marks: 3×3 mini grid. the bottom and side insets clear the dashed cage
   outline (drawn 8% in from the cell edge); the top also clears the cage-sum corner */
.notes {
    position: absolute;
    inset: 14% 9% 9% 9%;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(3, 1fr);
}

.note {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: clamp(0.5rem, 1.5dvh, 0.72rem);
    color: var(--note);
    line-height: 1;
}

.note.n1 { grid-area: 1 / 1; }
.note.n2 { grid-area: 1 / 2; }
.note.n3 { grid-area: 1 / 3; }
.note.n4 { grid-area: 2 / 1; }
.note.n5 { grid-area: 2 / 2; }
.note.n6 { grid-area: 2 / 3; }
.note.n7 { grid-area: 3 / 1; }
.note.n8 { grid-area: 3 / 2; }
.note.n9 { grid-area: 3 / 3; }

/* ==== cage overlay ==== */
/* the board draws its 2px frame as a border, so the cells start 2px in on every side —
   the overlay must sit inside that frame or the 9×9 viewBox lands off-center */
.cage-layer {
    position: absolute;
    inset: 2px;
    pointer-events: none;
}

.cage-line {
    stroke: var(--cage-line);
    stroke-width: 0.022;
    stroke-dasharray: 0.09 0.06;
    fill: none;
}

.cage-sum {
    fill: var(--cage-sum);
    font-size: 0.2px;
    font-weight: 600;
}

/* ==== digit pad ==== */
.digit-pad {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}

.pad-tools {
    display: flex;
    gap: 0.6rem;
}

.tool {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.15rem;
    padding: 0.5rem 0.4rem;
    border: 0;
    border-radius: 0.6rem;
    background: var(--button-bg);
    color: var(--text);
    position: relative;
}

.tool:hover {
    background: var(--button-hover);
}

/* the Notes button is the only place the mode is shown, so "on" is filled, not tinted */
.tool.active {
    background: var(--accent);
    color: #fff;
}

/* tool buttons are narrow — the badge sits in the top-left corner (notes' on/off is top-right) */
.tool .key-hint {
    position: absolute;
    top: 0.25rem;
    left: 0.3rem;
    min-width: 1.1rem;
    height: 1.1rem;
    padding: 0 0.2rem;
    font-size: 0.55rem;
}

.tool-icon {
    font-size: 1.2rem;
    line-height: 1;
}

.tool-label {
    font-size: 0.75rem;
}

.tool-state {
    position: absolute;
    top: 0.25rem;
    right: 0.4rem;
    font-size: 0.6rem;
    font-weight: 700;
    text-transform: uppercase;
    color: var(--text-muted);
}

.tool.active .tool-state {
    color: #fff;
}

.tool.active .key-hint {
    color: #fff;
    background: rgba(255, 255, 255, 0.18);
    border-color: rgba(255, 255, 255, 0.45);
}

.pad-digits {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem;
}

.pad-digit {
    aspect-ratio: 1;
    border: 0;
    border-radius: 0.6rem;
    background: var(--button-bg);
    color: var(--accent);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.1rem;
    transition: background 120ms;
}

.pad-digit:hover {
    background: var(--button-hover);
}

.pad-digit.depleted {
    visibility: hidden;
}

.pad-digit-value {
    font-size: 1.6rem;
    font-weight: 500;
    line-height: 1;
}

.pad-digit-count {
    font-size: 0.7rem;
    color: var(--text-muted);
    line-height: 1;
}

@media (max-width: 760px) {
    .pad-digits {
        grid-template-columns: repeat(9, 1fr);
        gap: 0.3rem;
    }

    .pad-digit {
        font-size: 1.25rem;
        border-radius: 0.4rem;
    }
}


/* ==== lives (hearts) ==== */
.hearts {
    display: inline-flex;
    align-items: center;
    gap: 0.12rem;
    line-height: 1;
}

.heart {
    color: var(--heart, #e5384f);
    font-size: 1.05rem;
    line-height: 1;
}

.heart.lost {
    color: var(--text-muted);
    opacity: 0.55;
}

.hearts.endless {
    gap: 0.2rem;
}

.heart-infinity {
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--text);
    line-height: 1;
}

/* the last life pulses so it is impossible to miss */
.game-lives.critical .heart.filled {
    animation: heart-pulse 1.4s ease-in-out infinite;
}

.game-lives.critical {
    border-left: 4px solid var(--heart, #e5384f);
}

@keyframes heart-pulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.18); }
}

@media (prefers-reduced-motion: reduce) {
    .game-lives.critical .heart.filled {
        animation: none;
    }
}

/* ==== radial digit picker ==== */
/* positioned by the board in percentages, so it tracks the cell at any board size */
/* width must stay in step with DigitRing.HalfSize, which clamps the ring inside the board:
   the ring spans a little over 4 cells plus the radius of the buttons sitting on its rim */
.digit-ring {
    position: absolute;
    --ring-bg: rgba(var(--ring-rgb), var(--ring-alpha, 0.65));
    width: 46%;
    aspect-ratio: 1;
    transform: translate(-50%, -50%);
    pointer-events: none;
    z-index: 5;
    /* the tools below the ring size themselves in cqw, against the ring's own width */
    container-type: inline-size;
}

.ring-digit {
    position: absolute;
    transform: translate(-50%, -50%);
    pointer-events: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: 1px solid var(--line);
    background: var(--ring-bg);
    backdrop-filter: blur(2px);
    color: var(--digit-user);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.28);
}

/* sized against the ring itself so the picker scales with the board on any screen; the
   percentage shrank when the ring widened, so the buttons keep their old absolute size */
.ring-digit {
    width: 28%;
    height: 28%;
    font-size: clamp(0.85rem, 2.6vmin, 1.2rem);
    font-weight: 600;
}

.ring-digit:hover {
    background: var(--cell-selected);
    color: var(--text);
}

.ring-digit.depleted {
    opacity: 0.45;
}

/* ==== settings dialog ==== */
.settings-dialog {
    text-align: left;
    min-width: min(22rem, 90vw);
}

.settings-label {
    display: block;
    font-size: 0.8rem;
    color: var(--text-muted);
    margin-bottom: 0.3rem;
}

/* the live percentage next to the ring-opacity slider */
.settings-value {
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

.settings-slider {
    width: 100%;
    margin: 0 0 0.9rem;
    accent-color: var(--accent);
}

.settings-row {
    display: flex;
    gap: 0.5rem;
    align-items: stretch;
}

.settings-row .nickname-input {
    margin: 0;
    flex: 1;
    min-width: 0;
}

.settings-hint {
    margin: 0.35rem 0 1rem;
    font-size: 0.78rem;
    color: var(--text-muted);
}

.settings-check {
    display: flex;
    align-items: flex-start;
    gap: 0.55rem;
    margin-bottom: 0.7rem;
    font-size: 0.9rem;
    cursor: pointer;
    line-height: 1.35;
}

.settings-check input {
    width: 1.05rem;
    height: 1.05rem;
    margin: 0.1rem 0 0;
    accent-color: var(--accent);
    flex-shrink: 0;
    cursor: pointer;
}

/* ==== renaming in-game ==== */
.player-name.own {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    font-weight: 600;
    color: inherit;
    max-width: 100%;
}

.player-name.own:hover {
    color: var(--accent);
}

.edit-pencil {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.player-name.own:hover .edit-pencil {
    color: var(--accent);
}

/* ==== defeat ==== */
.defeat h2 {
    color: var(--digit-wrong);
}

.defeat-text {
    margin: 0 0 0.35rem;
    color: var(--text);
}

.notes-blocked {
    opacity: 0.4;
    cursor: not-allowed;
}

/* ==== Nightmare: marked out, but still the normal palette ==== */
.theme-nightmare .game-difficulty {
    box-shadow: 0 0 0 1px rgba(180, 76, 255, 0.45);
}

.theme-nightmare .board {
    border-color: #b44cff;
}

/* ==== Hell: a bloody skin over the whole page ==== */
.theme-hell {
    --accent: #c1121f;
    --accent-soft: #4a1116;
    --heart: #ff2d3f;
    --page-bg: #140708;
    --board-bg: #1b0b0d;
    --ring-rgb: 27, 11, 13;
    --text: #f0d9db;
    --text-muted: #b08a8e;
    --line: #5a2028;
    --line-strong: #c1121f;
    --cell-selected: #8c1a25;
    /* hell's board is nearly black, so its highlights lighten like the dark theme's do */
    --highlight-peer: rgba(255, 190, 195, 0.09);
    --highlight-same: rgba(255, 190, 195, 0.2);
    --highlight-selected: rgba(255, 150, 160, 0.36);
    --notes-accent: #ff8a3d;
    --notes-glow: rgba(255, 138, 61, 0.3);
    --cell-error-bg: #7d1420;
    --digit-given: #ffd9dc;
    --digit-user: #ff6b7a;
    --digit-wrong: #ff2d3f;
    --digit-wrong-ink: #ff8c99;
    --note: #b08a8e;
    --cage-line: #d4707a;
    --cage-sum: #e08b93;
    --button-bg: #341015;
    --button-hover: #4a161d;
    background: radial-gradient(ellipse at 50% 0%, #2a0c10 0%, var(--page-bg) 70%);
    min-height: 100vh;
}

/* the colored-cage fills would fight the red skin, so hell keeps the board plain */
/* background-color, not the shorthand: the shorthand would also clear background-image
   and with it the selection / peer highlights that ride on top */
.theme-hell .cell[class*="cage-c"] {
    background-color: var(--board-bg);
}

.theme-hell .board {
    border-width: 3px;
    box-shadow: 0 0 22px rgba(193, 18, 31, 0.55);
}

.theme-hell .game-difficulty .stat-value {
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 700;
}

.theme-hell .brand-small {
    color: var(--digit-user);
}

/* ==== mobile ==== */
@media (max-width: 760px) {
    .game-page {
        padding: 0.5rem 0.6rem 1.2rem;
        gap: 0.6rem;
    }

    .game-status {
        gap: 0.4rem;
    }

    .stat-label {
        font-size: 0.62rem;
    }

    .heart {
        font-size: 0.95rem;
    }

    /* the pad is the primary input on a phone: bigger targets, full width */
    .side-panel {
        gap: 0.7rem;
    }

    .pad-digit {
        min-height: 3rem;
    }

    .tool {
        min-height: 2.8rem;
    }

    /* the ring sizes itself from the board now, so no fixed mobile override */

    .overlay-card {
        width: min(22rem, 92vw);
        padding: 1.1rem;
    }

    .dialog-actions {
        flex-direction: column-reverse;
    }

    .dialog-actions button {
        width: 100%;
    }

    .settings-dialog {
        min-width: 0;
    }
}

/* phones in landscape and very short windows: keep the board on screen */
@media (max-height: 520px) and (max-width: 900px) {
    .game-header,
    .game-status {
        margin-bottom: 0.2rem;
    }

    .board-wrap {
        width: min(92vw, 78dvh, 33rem);
    }
}

/* ==== live score card ==== */
.game-score .stat-value {
    font-variant-numeric: tabular-nums;
}

/* a short pop whenever the shared score goes up */
.game-score.bumped .stat-value {
    animation: score-bump 450ms ease-out;
    color: var(--accent);
}

@keyframes score-bump {
    0% { transform: scale(1); }
    35% { transform: scale(1.28); }
    100% { transform: scale(1); }
}

/* ==== end-of-game cards ==== */
.result-badge {
    font-size: 3rem;
    line-height: 1;
    margin-bottom: 0.2rem;
}

.result-badge.win {
    animation: badge-drop 700ms cubic-bezier(0.2, 1.5, 0.4, 1) both;
}

.result-badge.lose {
    animation: badge-crack 900ms ease-out both;
}

@keyframes badge-drop {
    0% { transform: translateY(-60px) scale(0.4) rotate(-25deg); opacity: 0; }
    100% { transform: none; opacity: 1; }
}

@keyframes badge-crack {
    0% { transform: scale(0.6); opacity: 0; }
    45% { transform: scale(1.15); opacity: 1; }
    60% { transform: scale(1.05) rotate(-6deg); }
    75% { transform: scale(1) rotate(5deg); }
    100% { transform: none; opacity: 1; }
}

.overlay-card.celebrate {
    animation: card-rise 420ms cubic-bezier(0.2, 1.2, 0.35, 1) both;
}

.overlay-card.shatter {
    animation: card-shake 520ms ease-out both;
    border: 1px solid var(--digit-wrong);
}

@keyframes card-rise {
    0% { transform: translateY(26px) scale(0.94); opacity: 0; }
    100% { transform: none; opacity: 1; }
}

@keyframes card-shake {
    0% { transform: scale(0.94); opacity: 0; }
    30% { transform: translateX(-9px); opacity: 1; }
    45% { transform: translateX(8px); }
    60% { transform: translateX(-5px); }
    75% { transform: translateX(3px); }
    100% { transform: none; opacity: 1; }
}

/* ==== confetti ==== */
.confetti {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
}

.confetti-piece {
    position: absolute;
    top: -6vh;
    width: 0.55rem;
    height: 0.9rem;
    border-radius: 1px;
    opacity: 0;
    animation: confetti-fall var(--duration, 3s) linear var(--delay, 0s) forwards;
}

.confetti-piece.c0 { background: #4c8dff; }
.confetti-piece.c1 { background: #ff9d42; }
.confetti-piece.c2 { background: #3fbf6f; }
.confetti-piece.c3 { background: #d75cff; }
.confetti-piece.c4 { background: #ff5c74; }
.confetti-piece.c5 { background: #ffd23f; }

@keyframes confetti-fall {
    0% { transform: translate3d(0, 0, 0) rotate(0deg); opacity: 1; }
    100% {
        transform: translate3d(var(--drift, 0), 108vh, 0) rotate(var(--spin, 360deg));
        opacity: 0.9;
    }
}

/* ==== score panel on the end cards ==== */
.score-panel {
    width: 100%;
    margin: 0.6rem 0 0.2rem;
    padding-top: 0.7rem;
    border-top: 1px solid var(--line);
}

.score-earned {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.8rem;
    margin-bottom: 0.6rem;
}

.score-label {
    font-size: 0.78rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.score-value {
    font-size: 1.9rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

.score-earned.positive .score-value {
    color: var(--accent);
}

.score-earned.zero .score-value {
    color: var(--text-muted);
}

.score-plus {
    margin-right: 0.05em;
}

.count-up.running {
    animation: count-glow 900ms ease-out;
}

@keyframes count-glow {
    0% { opacity: 0.55; }
    100% { opacity: 1; }
}

.score-stats {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.35rem 0.9rem;
    margin: 0;
}

.score-stat {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    font-size: 0.84rem;
}

.score-stat dt {
    color: var(--text-muted);
}

.score-stat dd {
    margin: 0;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.stat-sub {
    color: var(--text-muted);
    font-weight: 400;
    font-size: 0.78rem;
}

.score-scope {
    margin: 0.6rem 0 0;
    font-size: 0.74rem;
    color: var(--text-muted);
    text-align: center;
}

/* ==== statistics table in settings ==== */
/* the dialog's own actions sit at the very bottom, clear of the stats table */
.settings-actions {
    margin-top: 1.2rem;
}

.settings-heading {
    margin: 1.2rem 0 0.5rem;
    font-size: 0.95rem;
    font-weight: 600;
}

.stats-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.8rem;
}

.stats-table th,
.stats-table td {
    padding: 0.32rem 0.3rem;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.stats-table thead th {
    font-size: 0.68rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    border-bottom: 1px solid var(--line);
}

.stats-table tbody th {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    text-align: left;
    font-weight: 600;
    white-space: nowrap;
}

.stats-table thead th:first-child {
    text-align: left;
}

.stats-table tbody tr + tr th,
.stats-table tbody tr + tr td {
    border-top: 1px solid var(--accent-soft);
}

.reset-stats {
    margin-top: 0.7rem;
    padding: 0.35rem 0.6rem;
    border: 1px solid var(--line);
    border-radius: 0.45rem;
    background: transparent;
    color: var(--text-muted);
    font-size: 0.76rem;
}

.reset-stats:hover {
    border-color: var(--digit-wrong);
    color: var(--digit-wrong);
}

/* respect a reduced-motion preference: keep the information, drop the movement */
@media (prefers-reduced-motion: reduce) {
    .confetti {
        display: none;
    }

    .result-badge.win,
    .result-badge.lose,
    .overlay-card.celebrate,
    .overlay-card.shatter,
    .game-score.bumped .stat-value,
    .count-up.running {
        animation: none;
    }
}

@media (max-width: 760px) {
    .score-stats {
        grid-template-columns: 1fr;
    }

    .score-value {
        font-size: 1.6rem;
    }

    .stats-table {
        font-size: 0.74rem;
    }

    /* the two rarely-read columns give way first on a narrow screen */
    .stats-table th:nth-child(3),
    .stats-table td:nth-child(3) {
        display: none;
    }
}

/* ==== new game in the status strip ==== */
/* the stat cards shrank a little so the action fits beside them on one row */
.stat {
    min-width: 6.4rem;
    padding: 0.4rem 0.75rem;
}

/* the accent action that opens the strip; matches the stat cards' height but reads as
   a button, not a readout (a button stretches in a flex row where a div would not) */
.stat-button {
    flex: 0 0 auto;
    align-self: stretch;
    display: flex;
    align-items: center;
    padding: 0.4rem 1.1rem;
    border: 0;
    border-radius: 0.7rem;
    background: var(--accent);
    color: #fff;
    font-size: 0.95rem;
    font-weight: 600;
    white-space: nowrap;
    transition: opacity 120ms;
}

.stat-button:hover:not(:disabled) {
    opacity: 0.88;
}

.stat-button:disabled {
    opacity: 0.55;
    cursor: default;
}

/* ==== dialog actions of equal weight ==== */
/* both buttons share one class so they cannot drift apart in size again */
.equal-actions {
    display: flex;
    gap: 0.6rem;
    width: 100%;
}

.dialog-action {
    flex: 1 1 0;
    min-width: 0;
    padding: 0.6rem 0.9rem;
    border: 0;
    border-radius: 0.55rem;
    font-size: 0.95rem;
    font-weight: 600;
    text-align: center;
    transition: background 120ms, opacity 120ms;
}

.dialog-action.secondary {
    background: var(--button-bg);
    color: var(--text);
}

.dialog-action.secondary:hover:not(:disabled) {
    background: var(--button-hover);
}

.dialog-action.primary {
    background: var(--accent);
    color: #fff;
}

.dialog-action.primary:hover:not(:disabled) {
    opacity: 0.9;
}

.dialog-action:disabled {
    opacity: 0.5;
    cursor: default;
}

/* ==== notes mode ==== */
/* the pencil cursor over the board is the only ambient signal; the state itself is
   read off the Notes button, which carries its own on/off styling */
.notes-mode .cell {
    cursor: cell;
}

.digit-pad {
    position: relative;
}

/* ==== digit ring tools ==== */
/* a row under the circle rather than inside it, so the middle of the ring stays clear
   and the selected cell underneath remains visible. The digit buttons straddle the rim and
   so hang half their height (14cqw) past the ring box — the offset clears that overhang,
   otherwise the bottom digits sit on top of this row. */
.ring-tools {
    position: absolute;
    left: 50%;
    top: 100%;
    transform: translate(-50%, 0);
    margin-top: calc(14cqw + 0.35rem);
    display: flex;
    gap: 0.3rem;
    pointer-events: auto;
}

/* same round buttons as the digits: 28% of the ring, matched here in ring units */
.ring-tool {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28cqw;
    height: 28cqw;
    border-radius: 50%;
    border: 1px solid var(--line);
    background: var(--ring-bg);
    backdrop-filter: blur(2px);
    color: var(--text-muted);
    font-size: clamp(0.85rem, 2.6vmin, 1.2rem);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.28);
}

/* rings in the lower half flip their tools above the circle — see DigitRing.ToolsAbove */
.digit-ring.tools-above .ring-tools {
    top: auto;
    bottom: 100%;
    margin-top: 0;
    margin-bottom: calc(14cqw + 0.35rem);
}

.ring-tool:hover {
    background: var(--button-hover);
    color: var(--text);
}

/* the tool shows the mode on itself; the digits around it stay in their normal colour */
.ring-notes.active {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

/* ==== multiplayer section, below the board ==== */
.multiplayer {
    width: var(--page-width);
    margin-top: 1.4rem;
    padding: 0.8rem 1rem;
    border: 1px solid var(--line);
    border-radius: 0.7rem;
}

.multiplayer-body {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.8rem 1.5rem;
}

/* the invite button no longer fills a narrow column, so it sizes to its own label */
.multiplayer .invite-button {
    width: auto;
    flex-shrink: 0;
    margin-left: auto;
}

/* ==== players on one line ==== */
.players.inline {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.35rem 0.55rem;
}

.players.inline h3 {
    margin: 0;
    flex-shrink: 0;
}

.players.inline ul {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.3rem 0.7rem;
    margin: 0;
    padding: 0;
    list-style: none;
    min-width: 0;
}

.players.inline .player {
    gap: 0.3rem;
}

.players.inline .player-name {
    max-width: 9rem;
}

.players.inline .player-badge {
    margin-left: 0;
}

@media (max-width: 760px) {
    /* the pad is nine columns wide on a phone; without this the last digit
       pushed the layout past the viewport and 9 slid off the right edge */
    .side-panel,
    .digit-pad,
    .pad-digits,
    .pad-tools {
        max-width: 100%;
        min-width: 0;
    }

    .pad-digits {
        gap: 0.25rem;
    }

    /* nine square cells plus gaps overflow a phone; let height be free instead so the
       row always fits the viewport exactly (this is what pushed 9 off the edge) */
    .pad-digit {
        aspect-ratio: auto;
        min-width: 0;
        padding-left: 0;
        padding-right: 0;
    }

    .pad-digit-value {
        font-size: 1.15rem;
    }

    .game-layout,
    .board-area {
        max-width: 100%;
        min-width: 0;
    }

    .players.inline .player-name {
        max-width: 7rem;
    }

    .stat {
        min-width: 5.2rem;
    }
}
/* ==== framework chrome ==== */
#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
    color: #333;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

.blazor-error-boundary {
    background: #b32121;
    padding: 1rem;
    color: white;
}

.blazor-error-boundary::after {
    content: "Došlo k chybě.";
}

/* ==== shared puzzle code ==== */
/* the code is a word to be read and retyped, so it is set in a monospace face at a
   comfortable size, with the letters spaced out enough to tell them apart */
.puzzle-code,
.code-input {
    font-family: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace;
    font-size: 0.95rem;
    letter-spacing: 0.06em;
}

.code-entry {
    text-align: left;
}

.code-hint,
.code-error {
    margin: 0.35rem 0 0;
    font-size: 0.78rem;
}

.code-error {
    color: var(--digit-wrong);
}

/* on the home page the entry sits below the levels, separated by a little air */
.difficulty-menu .code-entry {
    margin-top: 0.9rem;
}

/* the code shown next to the invite button in the multiplayer strip */
.code-chip {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    padding: 0.35rem 0.7rem;
    border: 1px solid var(--line);
    border-radius: 0.5rem;
    background: transparent;
    color: var(--text);
}

.code-chip:hover {
    background: var(--button-hover);
}

.code-chip-label {
    font-size: 0.72rem;
    color: var(--text-muted);
}

.code-chip-value {
    font-family: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace;
    font-weight: 600;
    letter-spacing: 0.05em;
}

/* ==== accounts: sign in, sign up, passwords ==== */
/* the wordmark leads these pages too, but smaller — the form is what came here for */
.auth-page .brand {
    font-size: clamp(2rem, 8vw, 3rem);
    margin-bottom: 1rem;
}

.auth-card {
    width: min(24rem, 92vw);
    padding: 1.6rem 1.8rem 1.4rem;
    border-radius: 1rem;
    background: var(--page-bg);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);
    text-align: left;
}

.auth-title {
    margin: 0 0 0.8rem;
    font-size: 1.25rem;
    color: var(--accent);
    text-align: center;
}

.auth-intro {
    margin: 0 0 1rem;
    font-size: 0.9rem;
    color: var(--text-muted);
}

/* the address a link belongs to, so it is clear whose password is being set */
.auth-address {
    margin: 0 0 1rem;
    font-weight: 600;
    word-break: break-all;
}

.auth-label {
    display: block;
    margin: 0 0 0.3rem;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-muted);
}

/* the shared nickname field is the app's one input style; inside a form it needs
   its own rhythm, since here several of them stack */
.auth-card .nickname-input {
    margin-bottom: 0.9rem;
}

.auth-error {
    margin: 0 0 0.8rem;
    font-size: 0.82rem;
    color: var(--digit-wrong);
}

.auth-card .settings-hint {
    margin: 0 0 0.9rem;
}

.auth-links {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0.6rem;
    margin-top: 1rem;
    font-size: 0.85rem;
}

.auth-links a,
.auth-back {
    color: var(--accent);
    text-decoration: none;
}

.auth-links a:hover,
.auth-back:hover {
    text-decoration: underline;
}

.auth-back {
    display: block;
    margin-top: 1.2rem;
    font-size: 0.82rem;
    text-align: center;
    color: var(--text-muted);
}

/* only shown where undelivered links are put on the page (development) */
.auth-devlink-note {
    margin: 1.2rem 0 0.4rem;
    font-size: 0.8rem;
    color: var(--text-muted);
}

/* ==== account section of the settings dialog ==== */
.account-address {
    margin: 0 0 0.7rem;
    font-weight: 600;
    word-break: break-all;
}

.account-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.account-actions .new-game-option {
    flex: 1;
    min-width: 8rem;
    padding-left: 0.6rem;
    padding-right: 0.6rem;
    font-size: 0.9rem;
}

.account-actions .account-save {
    background: var(--accent);
    color: #fff;
}

.account-done {
    color: var(--accent);
}

/* the account button carries a name, which can be long — let it shrink before the row wraps */
.account-toggle {
    max-width: 10rem;
}

.account-toggle .pref-label {
    overflow: hidden;
    text-overflow: ellipsis;
}
