:root {
    --bg: #f4f6fa;
    --header: #ffffff;
    --surface: #ffffff;
    --surface-2: #f0f3f8;
    --border: #e0e5ee;
    --text: #1a2740;
    --muted: #627089;
    --primary: #315fe9;
    --primary-strong: #244bc5;
    --primary-soft: #eaf0ff;
    --on-primary: #ffffff;
    --success: #12773f;
    --success-strong: #0d5c30;
    --success-soft: #e0f3e8;
    --on-success: #ffffff;
    --warning: #8a5a00;
    --warning-soft: #fff2d6;
    --danger: #b9202f;
    --danger-soft: #fde6e9;
    --banker: #8a94a8;
    --chart-bar: #315fe9;
    --chart-muted: #c3cbdb;
    --chart-band: rgb(31 91 255 / 10%);
    --chart-stripe: rgb(255 255 255 / 55%);
    --chart-ghost: rgb(91 104 130 / 8%);
    --shadow: 0 2px 6px rgb(24 39 70 / 3%);
    --radius: 14px;
    --mono: ui-monospace, "Cascadia Mono", "SFMono-Regular", Consolas, monospace;
    color-scheme: light;
}

:root[data-theme="dark"] {
    --bg: #3b424f;
    --header: #161f30;
    --surface: #000000;
    --surface-2: #1c283c;
    --border: #2b374c;
    --text: #e8edf7;
    --muted: #a0adc3;
    --primary: #88a7ff;
    --primary-strong: #abc0ff;
    --primary-soft: #243558;
    --on-primary: #0d1320;
    --success: #59c98f;
    --success-strong: #82dbac;
    --success-soft: #12301f;
    --on-success: #0d1320;
    --warning: #f0c060;
    --warning-soft: #33280f;
    --danger: #ff7d88;
    --danger-soft: #3a1820;
    --banker: #6f7a92;
    --chart-bar: #6487f2;
    --chart-muted: #3a4866;
    --chart-band: rgb(111 147 255 / 20%);
    --chart-stripe: rgb(13 19 32 / 50%);
    --chart-ghost: rgb(155 168 195 / 10%);
    --shadow: 0 2px 6px rgb(0 0 0 / 12%);
    color-scheme: dark;
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

/* Reserve room for the scrollbar so the page doesn't shift sideways when it appears. */
html {
    -webkit-text-size-adjust: 100%;
    scrollbar-gutter: stable;
}

body {
    margin: 0;
    min-width: 320px;
    background: var(--bg);
    color: var(--text);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

h1, h2, p {
    margin: 0;
}

/* Blazor focuses the page heading after navigation; keep focus rings on interactive controls. */
h1[tabindex="-1"]:focus {
    outline: none;
}

button, input {
    font: inherit;
    color: inherit;
}

/* Hidden whatever display its classes give it, such as the panel of the tab that isn't chosen. */
[hidden] {
    display: none !important;
}

/* The header, the page and the footer under each other, at least as tall as the window, so that the footer is at the
   bottom of the window also when the page is shorter. */
#app {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh;
}

/* Header */

.app-header {
    background: var(--header);
    border-bottom: 1px solid var(--border);
}

/* One row in the page's columns (see .layout): the brand and the game above the coupon, and R-System and Reducera above
   the panels beside it, with the page's tools and the theme at the right edge. The tabs are as tall as the header, so
   the active one's line covers its border. */
.app-header-inner {
    display: grid;
    column-gap: 32px;
    min-height: 76px;
    max-width: 2000px;
    margin: 0 auto;
    padding: 0 28px;
}

.header-start,
.header-end {
    display: flex;
    align-items: center;
    gap: 28px;
    min-width: 0;
}

/* How much fits above the panels beside the coupon depends on how wide they are; see the container queries below. */
.header-end {
    container-type: inline-size;
}

.header-tools {
    display: flex;
    align-items: center;
    gap: 28px;
    flex: none;
    margin-left: auto;
}

.theme-toggle {
    flex: none;
    font-size: 13px;
    min-height: 40px;
}

.theme-icon {
    width: 18px;
    height: 18px;
    flex: none;
}

.theme-icon-sun,
:root[data-theme="dark"] .theme-icon-moon {
    display: none;
}

:root[data-theme="dark"] .theme-icon-sun {
    display: block;
}

/* The labels differ in width, so the hidden one still takes up room and the button doesn't change size. */
.theme-labels {
    display: grid;
}

.theme-labels > span {
    grid-area: 1 / 1;
}

.theme-label-light,
:root[data-theme="dark"] .theme-label-dark {
    visibility: hidden;
}

:root[data-theme="dark"] .theme-label-light {
    visibility: visible;
}

.brand {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}

.brand-mark {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border-radius: 13px;
    background: var(--primary);
    color: var(--on-primary);
    font-weight: 800;
    font-size: 14px;
    letter-spacing: 0.02em;
    flex: none;
}

.brand h1 {
    font-size: 20px;
    font-weight: 700;
    letter-spacing: -0.6px;
    line-height: 1.2;
}

.brand p {
    color: var(--muted);
    margin-top: 3px;
    font-size: 13px;
}

/* Rätta, beside the theme. */
.header-actions {
    display: flex;
    gap: 8px;
}

.header-actions .btn {
    min-height: 42px;
    padding: 9px 16px;
    font-size: 13px;
}

.header-actions .btn svg {
    width: 20px;
    height: 20px;
    flex: none;
}

/* R-System and Reducera, after what they are for. */
.header-tabs {
    display: flex;
    align-self: stretch;
    align-items: center;
    gap: 20px;
}

.header-tabs:empty {
    display: none;
}

.tabs-label {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    white-space: nowrap;
    font-size: 14px;
    font-weight: 700;
    letter-spacing: -0.2px;
}

.tabs-label svg {
    width: 20px;
    height: 20px;
    color: var(--primary);
}

.tabs {
    display: flex;
    align-self: stretch;
    gap: 4px;
    margin-bottom: -1px;
}

.tab {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 48px;
    padding: 8px 14px;
    border: 0;
    border-bottom: 3px solid transparent;
    background: transparent;
    color: var(--muted);
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s;
}

.tab svg {
    width: 20px;
    height: 20px;
    flex: none;
}

.tab:hover:not(:disabled, .active) {
    color: var(--text);
}

.tab.active {
    border-bottom-color: var(--primary);
    color: var(--text);
}

.tab:disabled {
    cursor: not-allowed;
}

.tab:disabled:not(.active) {
    opacity: 0.5;
}

/* Less room above the panels beside the coupon: first the theme's label goes, then the tabs', and then the tools move
   closer together. */
@container (max-width: 720px) {
    .theme-toggle {
        width: 40px;
        padding: 8px;
    }

    .theme-toggle span {
        display: none !important;
    }
}

@container (max-width: 630px) {
    .tabs-label {
        display: none;
    }
}

@container (max-width: 460px) {
    .header-tools {
        gap: 16px;
    }
}

/* With the coupon and the panels under each other, there are no columns to be above. So the brand and the tools go in a
   row, and under it the tabs: the game to the left and R-System and Reducera to the right, or under each other when
   they don't fit beside each other. */
@media (max-width: 1100px) {
    .app-header-inner {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 4px 20px;
        min-height: 0;
        padding-top: 14px;
    }

    .header-start,
    .header-end {
        display: contents;
        container-type: normal;
    }

    /* Its text wraps rather than the tools going under it. */
    .brand {
        flex: 1 1 0;
    }

    .header-tools {
        order: 1;
    }

    /* Ends the row after the tools. */
    .app-header-inner::after {
        content: "";
        order: 2;
        flex-basis: 100%;
    }

    .header-start > :not(.brand),
    .header-tabs {
        order: 3;
    }

    .header-tabs {
        margin-left: auto;
    }
}

@media (max-width: 600px) {
    .tabs-label {
        display: none;
    }

    .header-tabs,
    .tabs {
        flex: 1;
    }

    .tab {
        flex: 1;
        justify-content: center;
        min-height: 44px;
    }
}

/* Give the coupon room for single-line names; add columns only when the remaining panels fit. */

.app-main {
    flex: 1 0 auto;
    width: 100%;
    max-width: 2000px;
    margin: 0 auto;
    padding: 28px 28px 56px;
}

/* The page's columns, which the header's row has too: the coupon, and the panels beside it. */
.layout,
.app-header-inner {
    /* Text plus name padding, number, signs, kind, gaps and the card's padding/borders. */
    --coupon-width: max(520px, calc(var(--coupon-name-width, 202px) + 288px));
    --urows-width: 370px;
    grid-template-columns: minmax(0, min(var(--coupon-width), 56%)) minmax(0, 1fr);
}

.layout {
    display: grid;
    gap: 24px 32px;
    align-items: start;
}

.group,
.stack {
    display: grid;
    gap: 24px;
    align-items: start;
    min-width: 0;
}

@media (min-width: 1600px) {
    .reduction-group {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Under R-System the U-rows are hidden and their column stays empty, so the panels beside them stay where they are under
   Reducera, as wide as there. */
@media (min-width: 2000px) {
    .layout,
    .app-header-inner {
        grid-template-columns: minmax(0, min(calc(var(--coupon-width) + 24px + var(--urows-width)), 62%)) minmax(0, 1fr);
    }

    .system-group {
        grid-template-columns: minmax(0, 1fr) var(--urows-width);
    }
}

/* Beside the coupon, U-rows share its rows: the headers, the U-rows' titles, the 13 matches, the U-rows' limits, and how
   many rows the U-rows keep. So each match of a U-row is level with its match on the coupon and the two cards are equally
   tall. More than two U-rows scroll sideways instead of going on under each other. Without U-rows, their card is only
   its header. */
@media (min-width: 2000px) {
    .layout.with-urows .system-group {
        grid-template-rows: [title] auto [heads] auto [matches] repeat(13, auto) [foot] auto [summary] auto [end];
        row-gap: 2px;
    }

    .layout.with-urows :is(.coupon-card, .urows-panel, .urows-card, .coupon, .urows, .urow, .urow-signs) {
        display: grid;
        grid-template-rows: subgrid;
        row-gap: 2px;
    }

    .layout.with-urows :is(.coupon-card, .urows-panel, .urows-card) {
        grid-row: title / end;
    }

    .layout.with-urows :is(.coupon-card, .urows-card) > .card-header {
        grid-row: title;
        margin-bottom: 16px;
    }

    /* The draw goes level with the U-rows' titles, which the coupon has no row of its own for. With the header's margin
       and the margin under it, the draw and the matches stay where they are without U-rows, where the card's gap is
       between them. */
    .layout.with-urows .coupon-draw {
        grid-row: heads;
        align-self: start;
        margin-bottom: 16px;
    }

    .layout.with-urows .coupon {
        grid-row: matches / foot;
    }

    /* A taller row when a U-row is taller than it doesn't spread its lines apart. */
    .layout.with-urows .coupon-row {
        align-content: start;
    }

    /* The padding is room for the scrollbar, which would otherwise cover the bottom of the U-rows. */
    .layout.with-urows .urows {
        grid-row: heads / summary;
        grid-template-columns: none;
        grid-auto-flow: column;
        grid-auto-columns: calc((100% - 10px) / 2);
        align-items: stretch;
        padding-bottom: 12px;
        overflow: auto hidden;
        overscroll-behavior-x: contain;
        scroll-snap-type: x mandatory;
        scrollbar-width: thin;
    }

    .layout.with-urows .urows ~ * {
        grid-row: summary;
        align-self: start;
        margin-top: 16px;
    }

    .layout.with-urows .urow {
        grid-row: 1 / -1;
        scroll-snap-align: start;
    }

    .layout.with-urows .urow-head {
        align-self: start;
        margin-bottom: 6px;
    }

    .layout.with-urows .urow-signs {
        grid-row: 2 / -2;
    }

    .layout.with-urows .urow-match {
        align-self: start;
    }

    .layout.with-urows .urow-limits {
        grid-row: -2 / -1;
        align-self: start;
        margin-top: 8px;
    }
}

@media (max-width: 1100px) {
    .layout {
        grid-template-columns: minmax(0, 1fr);
    }
}

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 22px;
    display: grid;
    gap: 18px;
    min-width: 0;
    max-width: 500px;
}

.coupon-card {
    min-width: 520px;
}

/* A card's heading with a small round button beside it, such as the question mark that opens what stands out in the draw. */
.card-title {
    display: flex;
    align-items: center;
    gap: 6px;
}

.info-button {
    display: inline-grid;
    place-items: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s;
}

.info-button:hover {
    background: var(--surface-2);
    color: var(--primary-strong);
}

.info-button svg {
    width: 20px;
    height: 20px;
}

.card h2,
.dialog h2 {
    font-size: 18px;
    line-height: 1.35;
    letter-spacing: -0.3px;
}

.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--border);
    padding: 10px;
    border-radius: 16px;
}

.card-subtitle {
    margin-top: 5px;
    font-size: 13px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.hint {
    color: var(--muted);
    font-size: 13px;
    line-height: 1.65;
}

/* Info: the icon beside a heading opens a box under the header that explains the card (InfoTip). The box is a popover
   in the top layer, which app.js places under the header with the arrow at the icon. */

.info-button {
    display: inline-grid;
    place-items: center;
    flex: none;
    width: 30px;
    height: 30px;
    padding: 0;
    border: none;
    border-radius: 999px;
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s;
}

.info-button svg {
    width: 20px;
    height: 20px;
}

.info-button:hover,
.info-button:has(+ .info-popover:popover-open) {
    background: var(--primary-soft);
    color: var(--primary-strong);
}

.info-popover {
    position: fixed;
    inset: auto;
    width: min(560px, calc(100vw - 24px));
    margin: 0;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface);
    color: var(--text);
    box-shadow: 0 12px 32px rgb(16 24 40 / 18%);
    overflow: visible;
}

/* Only while open: closed, the browser hides it. */
.info-popover:popover-open {
    display: flex;
    flex-direction: column;
}

/* The arrow up at the icon. */
.info-popover::before {
    content: "";
    position: absolute;
    top: -7px;
    left: calc(var(--info-arrow, 24px) - 6px);
    width: 12px;
    height: 12px;
    border-top: 1px solid var(--border);
    border-left: 1px solid var(--border);
    background: var(--surface);
    transform: rotate(45deg);
}

.info-body {
    min-height: 0;
    padding: 14px 18px 16px;
    overflow-y: auto;
    overscroll-behavior: contain;
    font-size: 14px;
    line-height: 1.6;
}

.info-body h3 {
    margin: 14px 0 4px;
    font-size: 14px;
}

.info-close + h3 {
    margin-top: 0;
}

.info-body p + p {
    margin-top: 8px;
}

/* The text runs beside the close button, which floats at the top right. */
.info-close {
    float: right;
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    margin: -6px -10px 4px 10px;
    padding: 0;
    border: none;
    border-radius: 999px;
    background: transparent;
    color: var(--muted);
    cursor: pointer;
}

.info-close:hover {
    background: var(--surface-2);
    color: var(--text);
}

.info-close svg {
    width: 18px;
    height: 18px;
}

/* Buttons */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 40px;
    padding: 8px 14px;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--surface);
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.15s, border-color 0.15s, color 0.15s;
}

.btn:hover:not(:disabled) {
    border-color: var(--primary);
    color: var(--primary-strong);
}

.btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.btn-ghost {
    border-color: transparent;
    background: transparent;
    color: var(--muted);
}

.btn-ghost:hover:not(:disabled) {
    background: var(--surface-2);
    border-color: transparent;
}

.btn-primary {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--on-primary);
}

.btn-primary:hover:not(:disabled) {
    background: var(--primary-strong);
    border-color: var(--primary-strong);
    color: var(--on-primary);
}

.btn-wide {
    width: 100%;
    min-height: 48px;
    font-size: 15px;
}

.btn-small {
    min-height: 30px;
    padding: 2px 10px;
    font-size: 14px;
}

/* The download becomes the main action once the reduced rows are ready. */
.btn-download {
    border-color: var(--success);
    background: var(--success);
    color: var(--on-success);
}

.btn-download:hover:not(:disabled) {
    border-color: var(--success-strong);
    background: var(--success-strong);
    color: var(--on-success);
}

.btn-download:active:not(:disabled) {
    transform: translateY(1px);
    box-shadow: none;
}

.btn-download:disabled {
    box-shadow: none;
    background: var(--surface-2);
    border-color: var(--border);
    color: var(--muted);
    opacity: 1;
}

button:focus-visible,
input:focus-visible,
summary:focus-visible,
.rows:focus-visible,
.dist-plot:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

.actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

/* Draw */

/* On the coupon, under the header's line and in line with the game's name above it: the draw's number in a field, when
   it closes beside it, and any error on a line of its own. */
.coupon-draw {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-top: 0;
    padding-inline: 10px;
}

.coupon-draw .message {
    flex-basis: 100%;
}

.draw-field {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.draw-number {
    flex: none;
    width: 88px;
    height: 32px;
    padding: 4px 8px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface);
    color: var(--text);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}

.draw-number::placeholder {
    color: var(--muted);
    opacity: 0.8;
}

.draw-number:disabled {
    opacity: 0.6;
}

/* Coupon */

.coupon {
    --sign-width: 38px;
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 2px;
}

.coupon-row {
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr) auto 38px;
    align-items: center;
    gap: 0 8px;
    padding: 3px 6px;
    border-radius: 8px;
}

.coupon-row:nth-child(odd) {
    background: var(--surface-2);
}

.match-number {
    grid-column: 1;
    grid-row: 1;
    font-weight: 700;
    color: var(--muted);
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-size: 12px;
}

.match-name-field {
    grid-column: 2;
    grid-row: 1;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
}

/* Keep names on one line beside the signs; unusually long names can still scroll independently. */
.match-name-content {
    display: grid;
    width: max-content;
    min-width: 100%;
}

.match-name,
.match-name-sizing {
    grid-area: 1 / 1;
    width: 100%;
    min-width: 0;
    min-height: 32px;
    margin: 0;
    padding: 4px 8px;
    border: 1px solid transparent;
    border-radius: 8px;
    background: transparent;
    font-size: 14px;
    line-height: 1.5;
    white-space: pre;
}

.match-name {
    height: 32px;
}

.match-name-sizing {
    visibility: hidden;
    pointer-events: none;
}

.coupon-row > .signs {
    grid-column: 3;
    grid-row: 1;
}

.coupon .sign {
    height: 32px;
}

.match-name:hover:not(:disabled),
.match-name:focus {
    border-color: var(--border);
    background: var(--surface);
}

.match-name::placeholder {
    color: var(--muted);
    opacity: 0.85;
}

.signs {
    display: flex;
    gap: 4px;
}

.sign {
    width: var(--sign-width, 38px);
    height: 36px;
    border-radius: 6px;
    border: 1px solid var(--border);
    font-weight: 700;
    font-family: var(--mono);
    cursor: pointer;
    transition: background-color 0.12s, border-color 0.12s, color 0.12s;
}

.sign:hover:not(:disabled) {
    border-color: var(--primary);
}

.sign.on {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--on-primary);
}

.sign:disabled {
    cursor: not-allowed;
    opacity: 0.7;
}

.match-kind {
    grid-column: 4;
    grid-row: 1;
    font-size: 12px;
    color: var(--muted);
    text-align: center;
}

.kind-full .match-kind,
.kind-half .match-kind {
    color: var(--primary-strong);
    font-weight: 600;
}

.kind-empty .match-kind {
    color: var(--danger);
}

/* Under the team names, lined up with their text. */
.match-info {
    grid-column: 2;
    grid-row: 2;
    align-self: start;
    display: flex;
    flex-wrap: wrap;
    gap: 0 8px;
    padding-left: 9px;
    font-size: 12px;
    line-height: 16px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.match-note {
    font-weight: 600;
    color: var(--warning);
}

.match-stats {
    grid-column: 3;
    grid-row: 2;
    display: grid;
    grid-template-columns: repeat(3, var(--sign-width));
    column-gap: 4px;
    font-size: 12px;
    line-height: 14px;
    text-align: center;
    white-space: nowrap;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.match-stats .on {
    color: var(--text);
    font-weight: 600;
}

/* Under the kind of a banker or half hedge: green when the odds give its signs a higher chance than Svenska folket's
   share of the bets, on average for a half hedge, and red when lower. */
.match-value {
    grid-column: 4;
    grid-row: 2;
    align-self: start;
    font-size: 12px;
    line-height: 16px;
    text-align: center;
    white-space: nowrap;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.match-value.up {
    color: var(--success);
    font-weight: 600;
}

.match-value.down {
    color: var(--danger);
    font-weight: 600;
}

.system-summary {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding-top: 4px;
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 5px 9px;
    border-radius: 6px;
    background: var(--surface-2);
    font-size: 12px;
    color: var(--muted);
}

.chip strong {
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

.summary-line {
    padding-top: 14px;
    border-top: 1px solid var(--border);
    font-size: 14px;
    color: var(--muted);
}

.summary-line strong {
    color: var(--text);
}

@media (max-width: 600px) {
    .coupon {
        --sign-width: 32px;
    }

    .coupon-row {
        grid-template-columns: 20px minmax(0, 1fr) auto;
        column-gap: 4px;
        padding-inline: 2px;
    }

    .match-kind {
        display: none;
    }

    .match-name,
    .match-name-sizing {
        padding-inline: 4px;
    }

    .match-info {
        padding-left: 5px;
        font-size: 11px;
    }

    .match-value {
        grid-column: 1;
        font-size: 10px;
    }
}

/* U-rows: side by side, each a column with the matches from top to bottom like on the coupon. */

.urows-card {
    width: var(--urows-width);
    max-width: 100%;
}

.urows {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(156px, 1fr));
    gap: 10px;
    align-items: start;
}

.urow {
    display: grid;
    gap: 10px;
    padding: 10px;
    border-radius: 12px;
    background: var(--surface-2);
}

/* As tall as the signs on the coupon, so that a match is as tall as its row there. */
.urow .sign.small {
    max-width: none;
    height: 32px;
}

.urow .sign.small:not(.on) {
    background: var(--surface);
}

/* The title with the remove button at its end. */
.urow-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.urow-title {
    margin: 0;
    font-size: 15px;
}

.urow-signs {
    display: grid;
    gap: 2px;
}

.urow-match {
    display: grid;
    grid-template-columns: 20px repeat(3, minmax(0, 56px));
    align-items: center;
    gap: 4px;
    padding-block: 3px;
}

.urow-number {
    font-size: 12px;
    font-weight: 700;
    color: var(--muted);
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* The steppers under each other, with their buttons lined up, and the rule they make under them. */
.urow-limits {
    display: grid;
    grid-template-columns: repeat(4, auto);
    justify-content: start;
    align-items: center;
    gap: 6px;
    font-size: 14px;
}

.urow-limits > * {
    grid-column: 1 / -1;
}

.urow-limits .stepper {
    display: grid;
    grid-template-columns: subgrid;
}

/* On one line, so that the U-row keeps its height whatever the rule. */
.urow-rule {
    min-width: 0;
    overflow: hidden;
    font-size: 13px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.stepper {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.stepper-name {
    font-weight: 600;
}

.stepper button {
    width: 30px;
    height: 30px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface);
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
}

.stepper button:hover:not(:disabled) {
    border-color: var(--primary);
    color: var(--primary-strong);
}

.stepper button:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.stepper output {
    min-width: 2ch;
    text-align: center;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* Reduction settings */

.field {
    display: grid;
    gap: 9px;
}

.field-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.segmented {
    display: flex;
    padding: 3px;
    gap: 3px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--surface-2);
}

.segmented button {
    flex: 1;
    min-height: 36px;
    border: 0;
    padding: 6px 10px;
    border-radius: 6px;
    background: transparent;
    font-weight: 600;
    color: var(--muted);
    cursor: pointer;
    font-size: 13px;
    transition: color 0.15s, background-color 0.15s;
}

.segmented button.active {
    background: var(--surface);
    color: var(--primary-strong);
    box-shadow: 0 1px 4px rgb(16 24 40 / 10%);
}

.segmented button:hover:not(:disabled, .active) {
    color: var(--text);
}

.segmented button:disabled {
    cursor: not-allowed;
}

.progress {
    height: 8px;
    border-radius: 999px;
    background: var(--surface-2);
    overflow: hidden;
}

.progress-bar {
    height: 100%;
    background: var(--primary);
    transition: width 0.2s linear;
}

/* A search without an end: a stretch of bar that keeps sweeping across. */
.progress-bar.open-ended {
    width: 30%;
    animation: progress-sweep 1.6s ease-in-out infinite;
}

@keyframes progress-sweep {
    from {
        transform: translateX(-100%);
    }

    to {
        transform: translateX(340%);
    }
}

@media (prefers-reduced-motion: reduce) {
    .progress-bar.open-ended {
        width: 100%;
        opacity: 0.5;
        animation: none;
    }
}

.progress-text {
    font-size: 14px;
    color: var(--muted);
}

.progress-text strong {
    color: var(--text);
}

.message {
    padding: 10px 12px;
    border-radius: 10px;
    font-size: 14px;
}

.message.ok {
    background: var(--success-soft);
    color: var(--success);
}

.message.warn {
    background: var(--warning-soft);
    color: var(--warning);
}

.message.error {
    background: var(--danger-soft);
    color: var(--danger);
}

/* Filtered and prioritized intervals: the switches, sliders and bars look the same for both */

.priority {
    gap: 10px;
    padding-top: 18px;
    border-top: 1px solid var(--border);
}

.priority-head .field-label {
    color: var(--text);
    text-transform: none;
    letter-spacing: 0;
    font-size: 13px;
}

.priority-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.switch {
    -webkit-appearance: none;
    appearance: none;
    position: relative;
    flex: none;
    width: 42px;
    height: 24px;
    margin: 0;
    border-radius: 999px;
    background: var(--chart-muted);
    cursor: pointer;
    transition: background-color 0.15s;
}

.switch::after {
    content: "";
    position: absolute;
    top: 3px;
    left: 3px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #ffffff;
    box-shadow: 0 1px 2px rgb(16 24 40 / 25%);
    transition: transform 0.15s;
}

.switch:checked {
    background: var(--primary);
}

.switch:checked::after {
    transform: translateX(18px);
}

.switch:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.priority-value {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 2px 12px;
    font-size: 14px;
    color: var(--muted);
}

.priority-value strong {
    color: var(--text);
    font-size: 15px;
}

.priority-scale {
    --thumb: 22px;
    display: grid;
    gap: 4px;
}

.priority-bars {
    display: grid;
    grid-template-rows: 100%;
    align-items: end;
    height: 48px;
    padding: 0 calc(var(--thumb) / 2);
    border-bottom: 1px solid var(--border);
}

.priority-bars span {
    background: var(--chart-muted);
    border-radius: 2px 2px 0 0;
    transition: background-color 0.12s;
}

.priority-bars span.in {
    background: var(--chart-bar);
}

.priority-ends {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    font-size: 12px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.priority-count {
    font-size: 14px;
}

.priority-count.warn {
    color: var(--warning);
}

/* Sliders: the track and fill are drawn behind native range inputs, so two inputs can share one track. */

.range {
    --thumb: 22px;
    position: relative;
    height: var(--thumb);
}

.range-track,
.range-fill {
    position: absolute;
    top: 50%;
    height: 4px;
    margin-top: -2px;
    border-radius: 999px;
    pointer-events: none;
}

.range-track {
    left: calc(var(--thumb) / 2);
    right: calc(var(--thumb) / 2);
    background: var(--surface-2);
}

.range-fill {
    background: var(--primary);
}

.range input[type="range"] {
    -webkit-appearance: none;
    appearance: none;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    background: transparent;
    /* Only the thumbs take the pointer, so the lower input's thumb can be reached under the upper input. */
    pointer-events: none;
}

.range.single input[type="range"] {
    pointer-events: auto;
    cursor: pointer;
}

/* Firefox draws no track of its own once the appearance is none, so only WebKit needs one hidden. */
.range input[type="range"]::-webkit-slider-runnable-track {
    height: var(--thumb);
    background: transparent;
    border: 0;
}

.range input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    box-sizing: border-box;
    width: var(--thumb);
    height: var(--thumb);
    border: 2px solid var(--primary);
    border-radius: 50%;
    background: var(--surface);
    box-shadow: 0 1px 3px rgb(16 24 40 / 25%);
    pointer-events: auto;
    cursor: grab;
}

.range input[type="range"]::-moz-range-thumb {
    box-sizing: border-box;
    width: var(--thumb);
    height: var(--thumb);
    border: 2px solid var(--primary);
    border-radius: 50%;
    background: var(--surface);
    box-shadow: 0 1px 3px rgb(16 24 40 / 25%);
    pointer-events: auto;
    cursor: grab;
}

.range input[type="range"]:active::-webkit-slider-thumb {
    cursor: grabbing;
}

.range input[type="range"]:active::-moz-range-thumb {
    cursor: grabbing;
}

.range input[type="range"]:focus-visible {
    outline: none;
}

.range input[type="range"]:focus-visible::-webkit-slider-thumb {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

.range input[type="range"]:focus-visible::-moz-range-thumb {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

.range input[type="range"]:disabled::-webkit-slider-thumb {
    border-color: var(--chart-muted);
    cursor: not-allowed;
}

.range input[type="range"]:disabled::-moz-range-thumb {
    border-color: var(--chart-muted);
    cursor: not-allowed;
}

/* R-System: the systems that fit the coupon, the highest guarantee first, each with its guarantee and rows. */

.rsystem-summary {
    padding-top: 0;
}

.rsystem-choices {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
}

.rsystem-choice {
    display: grid;
    justify-items: center;
    gap: 2px;
    min-width: 0;
    padding: 10px 8px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface);
    font-variant-numeric: tabular-nums;
    cursor: pointer;
    transition: background-color 0.12s, border-color 0.12s, color 0.12s;
}

.rsystem-choice strong {
    font-size: 16px;
}

.rsystem-choice span {
    font-size: 13px;
    color: var(--muted);
}

.rsystem-choice:hover:not(:disabled, .active) {
    border-color: var(--primary);
}

.rsystem-choice.active {
    border-color: var(--primary);
    background: var(--primary);
    color: var(--on-primary);
}

.rsystem-choice.active span {
    color: inherit;
    opacity: 0.85;
}

.rsystem-choice:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

@media (max-width: 520px) {
    .rsystem-choices {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Result */

.badge {
    padding: 3px 10px;
    border-radius: 999px;
    background: var(--primary-soft);
    color: var(--primary-strong);
    font-weight: 700;
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}

.stats {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
}

.stat {
    display: grid;
    padding: 14px 12px;
    border-radius: 8px;
    background: var(--surface-2);
    min-width: 0;
}

.stat-value {
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -0.6px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.stat-label {
    font-size: 13px;
    color: var(--muted);
}

@media (max-width: 520px) {
    .stat {
        padding: 8px 10px;
    }

    .stat-value {
        font-size: 18px;
    }

    .stat-label {
        font-size: 12px;
    }
}

/* How well the reductions meet the priority */

.priority-result {
    container-type: inline-size;
    display: grid;
    gap: 8px;
    padding: 12px;
    border-radius: 12px;
    background: var(--surface-2);
}

.priority-options,
.priority-choices {
    display: grid;
    gap: 4px;
}

.priority-option {
    display: grid;
    grid-template-columns: 7rem 6.5rem minmax(0, 1fr) 4rem;
    grid-template-areas: "name rows bar value";
    align-items: center;
    gap: 4px 10px;
    width: 100%;
    min-height: 40px;
    padding: 6px 10px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface);
    text-align: left;
    font-variant-numeric: tabular-nums;
}

button.priority-option {
    cursor: pointer;
    transition: background-color 0.15s, border-color 0.15s;
}

button.priority-option:hover {
    border-color: var(--primary);
}

.priority-option.active {
    border-color: var(--primary);
    background: var(--primary-soft);
}

.priority-option.reference {
    border-color: transparent;
    background: transparent;
    color: var(--muted);
}

.priority-option-name {
    grid-area: name;
    font-weight: 600;
}

.priority-option-rows {
    grid-area: rows;
    font-size: 14px;
    color: var(--muted);
}

.priority-option-bar {
    grid-area: bar;
    height: 8px;
    border-radius: 999px;
    background: var(--surface-2);
    overflow: hidden;
}

.priority-option.active .priority-option-bar {
    background: var(--surface);
}

.priority-option-bar span {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: var(--chart-bar);
}

.priority-option.reference .priority-option-bar span {
    background: var(--chart-muted);
}

.priority-option-value {
    grid-area: value;
    text-align: right;
    font-weight: 700;
}

.priority-option.reference .priority-option-value {
    font-weight: 600;
}

/* "1 på 1,23 milj." needs more room than a percentage, so the bar goes below. */
.priority-result.rarity .priority-option {
    grid-template-columns: 7rem minmax(0, 1fr) auto;
    grid-template-areas:
        "name rows value"
        "bar bar bar";
}

/* Narrow: on phones, or in a column beside the results on wide screens. */
@container (max-width: 430px) {
    .priority-option,
    .priority-result.rarity .priority-option {
        grid-template-columns: auto minmax(0, 1fr) auto;
        grid-template-areas:
            "name rows value"
            "bar bar bar";
    }
}

/* Rows */

.row-details .rows {
    margin-top: 8px;
}

.rows {
    --cell: minmax(18px, 1fr);
    max-height: 450px;
    overflow-y: auto;
    scrollbar-gutter: stable;
    border: 1px solid var(--border);
    border-radius: 12px;
    font-family: var(--mono);
    font-size: 14px;
}

.rows-head,
.row-line {
    display: grid;
    grid-template-columns: 52px repeat(13, var(--cell));
    align-items: center;
    height: 30px;
    padding: 0 8px 0 0;
}

.rows-head {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    color: var(--muted);
    font-size: 12px;
    font-weight: 700;
}

.row-line.alt {
    background: var(--surface-2);
}

/* When grading: how many correct each row has, last on the line. */
.rows.with-correct .rows-head,
.rows.with-correct .row-line {
    grid-template-columns: 52px repeat(13, var(--cell)) 44px;
}

@media (max-width: 420px) {
    .rows {
        font-size: 13px;
    }

    .rows-head,
    .row-line {
        grid-template-columns: 38px repeat(13, var(--cell));
        padding-right: 4px;
    }

    .rows.with-correct .rows-head,
    .rows.with-correct .row-line {
        grid-template-columns: 38px repeat(13, var(--cell)) 32px;
    }

    .row-number {
        padding-right: 6px;
    }
}

.row-number {
    text-align: right;
    padding-right: 10px;
    color: var(--muted);
    font-size: 12px;
}

.cell {
    text-align: center;
    font-weight: 700;
}

.cell.banker {
    color: var(--banker);
    font-weight: 400;
}

.cell.hit {
    color: var(--success);
}

.cell.miss {
    color: var(--danger);
    opacity: 0.55;
    font-weight: 400;
}

.row-correct {
    text-align: right;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.rows-head .row-correct {
    font-weight: inherit;
}

/* A row with enough correct to win something. */
.row-correct.won {
    color: var(--success);
}

/* Distribution */

.dist {
    --dist-stripes: repeating-linear-gradient(135deg, transparent 0 3px, var(--chart-stripe) 3px 5px);
    display: grid;
    gap: 12px;
}

.dist-chart {
    display: grid;
    grid-template-columns: var(--dist-y-width, 3ch) minmax(0, 1fr);
    grid-template-rows: auto 160px auto;
    column-gap: 8px;
    font-size: 12px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.dist-axis-title {
    grid-column: 1 / -1;
    margin-bottom: 10px;
}

.dist-y {
    position: relative;
}

.dist-y span {
    position: absolute;
    right: 0;
    line-height: 1;
    transform: translateY(50%);
}

.dist-plot {
    position: relative;
    border-bottom: 1px solid var(--border);
}

.dist-grid {
    position: absolute;
    left: 0;
    right: 0;
    height: 1px;
    background: var(--surface-2);
}

.dist-band {
    position: absolute;
    top: 0;
    bottom: 0;
    background: var(--chart-band);
}

.dist-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 8px;
    font-size: 13px;
    color: var(--muted);
}

.dist-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-left: 4px;
}

.dist-legend-band,
.dist-legend-gain,
.dist-legend-loss {
    flex: none;
    width: 14px;
    height: 14px;
    border-radius: 3px;
}

.dist-legend-band {
    border: 1px solid var(--chart-bar);
    background: var(--chart-band);
}

.dist-legend-gain {
    background: var(--dist-stripes), var(--chart-bar);
}

.dist-legend-loss {
    border: 1px dashed var(--muted);
    background: var(--chart-ghost);
}

/* The heights of a bar and of how it differs from the other reduction, in percent of the plot. Registered so they animate. */
@property --dist-count {
    syntax: "<number>";
    inherits: true;
    initial-value: 0;
}

@property --dist-other {
    syntax: "<number>";
    inherits: true;
    initial-value: 0;
}

.dist-bars {
    position: absolute;
    inset: 0;
    display: grid;
}

.dist-slot {
    position: relative;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    border-radius: 6px 6px 0 0;
    /* Through a variable, since Visual Studio's validator does not know that custom properties can be transitioned. */
    --dist-transition: --dist-count 0.3s ease, --dist-other 0.3s ease;
    transition: var(--dist-transition);
}

.dist-slot.active {
    background: var(--surface-2);
}

.dist-slot.has-rows {
    cursor: pointer;
}

.dist-bar,
.dist-gain,
.dist-loss {
    width: min(24px, calc(100% - 2px));
    border-radius: 4px 4px 0 0;
    transition: background-color 0.12s, opacity 0.12s;
}

.dist-bar {
    height: calc(var(--dist-count) * 1%);
    background: var(--chart-bar);
}

.dist-slot.has-rows .dist-bar {
    min-height: 2px;
}

.dist-slot.active .dist-bar {
    background: var(--primary-strong);
}

.dist-gain,
.dist-loss {
    position: absolute;
    left: 50%;
    translate: -50% 0;
    pointer-events: none;
}

/* Rows more than in the other reduction: the top of the bar, striped. */
.dist-gain {
    bottom: calc(var(--dist-other) * 1%);
    height: calc(max(0, var(--dist-count) - var(--dist-other)) * 1%);
    background: var(--dist-stripes);
}

/* Rows fewer than in the other reduction: a dashed outline up to where its bar reaches. */
.dist-loss {
    bottom: calc(var(--dist-count) * 1%);
    height: calc(max(0, var(--dist-other) - var(--dist-count)) * 1%);
    overflow: hidden;
    background: var(--chart-ghost);
}

/* The outline is clipped by its box, so it vanishes with it where the bars are as tall. */
.dist-loss::before {
    content: "";
    position: absolute;
    inset: 0;
    border: 1px dashed var(--muted);
    border-bottom: 0;
    border-radius: inherit;
}

/* With a bar's rows shown, the other bars step back. */
.dist-bars.has-selection .dist-slot:not(.selected, .active) :is(.dist-bar, .dist-gain, .dist-loss) {
    opacity: 0.35;
}

@media (prefers-reduced-motion: reduce) {
    .dist-slot {
        transition: none;
    }
}

.dist-tooltip {
    position: absolute;
    top: 4px;
    z-index: 2;
    display: grid;
    padding: 6px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface);
    box-shadow: var(--shadow);
    font-size: 13px;
    line-height: 1.4;
    white-space: nowrap;
    pointer-events: none;
}

.dist-tooltip strong {
    color: var(--text);
    font-size: 14px;
}

.dist-tooltip-hint {
    margin-top: 2px;
    font-size: 12px;
    color: var(--muted);
}

.dist-selection {
    display: grid;
    gap: 8px;
}

.dist-selection-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.dist-x {
    grid-column: 2;
    position: relative;
    height: 24px;
}

.dist-x span {
    position: absolute;
    top: 8px;
    line-height: 1;
    white-space: nowrap;
    transform: translateX(-50%);
}

.dist-x span::before {
    content: "";
    position: absolute;
    top: -8px;
    left: 50%;
    width: 1px;
    height: 5px;
    background: var(--border);
}

.dist-ends {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 8px 16px;
}

.dist-end {
    display: grid;
    gap: 1px;
}

.dist-end.least {
    margin-left: auto;
    text-align: right;
}

.dist-end-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.dist-end-row {
    font-family: var(--mono);
    font-weight: 700;
    letter-spacing: 0.08em;
}

.dist-end-row .banker {
    color: var(--banker);
    font-weight: 400;
}

.dist-end-share {
    font-size: 14px;
    color: var(--muted);
}

.dist-table summary,
.row-details summary {
    width: fit-content;
    font-size: 14px;
    font-weight: 600;
    color: var(--primary-strong);
    cursor: pointer;
}

.dist-table table {
    width: 100%;
    margin-top: 8px;
    border-collapse: collapse;
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}

.dist-table th {
    padding: 6px 10px;
    border-bottom: 1px solid var(--border);
    font-size: 12px;
    color: var(--muted);
    text-align: left;
}

.dist-table td {
    padding: 5px 10px;
}

.dist-table tbody tr:nth-child(even) {
    background: var(--surface-2);
}

.dist-table th:not(:first-child),
.dist-table td:not(:first-child) {
    text-align: right;
}

/* Too little to be paid out. */
.dist-table td.unpaid {
    color: var(--muted);
}

@media (max-width: 420px) {
    .dist-chart {
        grid-template-rows: auto 140px auto;
        column-gap: 6px;
        font-size: 11px;
    }
}

/* Chances */

.chance-table {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}

.chance-table th,
.chance-table td {
    padding: 7px 10px;
    text-align: right;
    vertical-align: top;
}

.chance-table thead th {
    border-bottom: 1px solid var(--border);
    font-size: 12px;
    color: var(--muted);
    vertical-align: bottom;
}

.chance-table th:first-child {
    text-align: left;
    white-space: nowrap;
}

.chance-table tbody tr:nth-child(even) {
    background: var(--surface-2);
}

.chance-table tfoot th,
.chance-table tfoot td {
    border-top: 1px solid var(--border);
}

.chance-percent {
    display: block;
    font-weight: 700;
}

.chance-table .zero .chance-percent {
    font-weight: 400;
    color: var(--muted);
}

.chance-one-in {
    display: block;
    font-size: 13px;
    color: var(--muted);
}

/* Between the chances by the odds and by Svenska folket: red down when Svenska folket give the higher chance, green up
   when the odds do. */
.chance-table .chance-compare {
    width: 1px;
    padding-left: 0;
    padding-right: 0;
    text-align: center;
    vertical-align: middle;
}

.chance-arrow {
    display: block;
    margin: 0 auto;
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.6px;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.chance-arrow.up {
    color: var(--success);
}

.chance-arrow.down {
    color: var(--danger);
}

/* Read by screen readers but not shown. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Up to three columns of chances on a phone: the numbers closer together and "Minst 10 rätt" on two lines if need be. */
@media (max-width: 420px) {
    .chance-table th,
    .chance-table td {
        padding: 7px 6px;
    }

    .chance-table tfoot th:first-child {
        white-space: normal;
    }
}

@media (max-width: 360px) {
    .chance-table {
        font-size: 13px;
    }

    .chance-table th,
    .chance-table td {
        padding: 7px 4px;
    }

    .chance-table thead th,
    .chance-one-in {
        font-size: 11px;
    }

    .chance-arrow {
        width: 14px;
        height: 14px;
    }
}

/* Payouts */

.payout-turnover {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 10px;
}

.payout-turnover input {
    width: 96px;
    height: 38px;
    padding: 6px 10px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface);
    font-variant-numeric: tabular-nums;
}

.payout-turnover span {
    font-size: 14px;
    color: var(--muted);
}

.payout-table {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}

.payout-table th,
.payout-table td {
    padding: 7px 10px;
    text-align: right;
    white-space: nowrap;
}

.payout-table thead th {
    border-bottom: 1px solid var(--border);
    font-size: 12px;
    color: var(--muted);
}

.payout-table th:first-child {
    text-align: left;
}

.payout-table td {
    font-weight: 700;
}

/* Too little to be paid out. */
.payout-table td.unpaid {
    font-weight: 400;
    color: var(--muted);
}

.payout-table tbody tr:nth-child(even) {
    background: var(--surface-2);
}

/* Three amounts beside each other on a phone: closer together. */
@media (max-width: 420px) {
    .payout-table th,
    .payout-table td {
        padding: 7px 5px;
        font-size: 14px;
    }
}

/* Dialogs: over the page, which waits behind a backdrop. Contents that don't fit scroll under the header. */

.dialog {
    width: min(940px, calc(100% - 32px));
    max-width: none;
    max-height: calc(100% - 32px);
    max-height: calc(100dvh - 32px);
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    box-shadow: 0 24px 64px rgb(16 24 40 / 24%);
    overflow: hidden;
}

.dialog[open] {
    display: flex;
    flex-direction: column;
}

/* Not every browser lets the backdrop inherit the theme's colours, so it has its own, dark in both themes. */
.dialog::backdrop {
    background: rgb(10 16 30 / 55%);
}

.dialog-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 14px 14px 22px;
    border-bottom: 1px solid var(--border);
}

.dialog-close {
    width: 40px;
    padding: 0;
}

.dialog-close svg {
    width: 20px;
    height: 20px;
}

.dialog-body {
    container-type: inline-size;
    display: grid;
    align-content: start;
    gap: 18px;
    min-height: 0;
    padding: 22px;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-gutter: stable;
}

@media (max-width: 600px) {
    .dialog {
        width: calc(100% - 16px);
        max-height: calc(100% - 16px);
        max-height: calc(100dvh - 16px);
    }

    .dialog-header {
        padding: 10px 8px 10px 16px;
    }

    .dialog-body {
        padding: 16px;
    }
}

/* What stands out in the draw: three lists side by side with a line between them, one under the other when narrow. */

.highlights {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.highlight {
    min-width: 0;
    padding: 0 20px;
    border-left: 1px solid var(--border);
}

.highlight:first-child {
    padding-left: 0;
    border-left: none;
}

.highlight:last-child {
    padding-right: 0;
}

.highlight h3 {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 8px;
    font-size: 16px;
    line-height: 1.35;
}

.highlight-info {
    flex: none;
    width: 18px;
    height: 18px;
    color: var(--muted);
    cursor: help;
}

.highlight-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.highlight-list li {
    display: grid;
    grid-template-columns: 2.4em minmax(0, 1fr) auto;
    align-items: baseline;
    gap: 8px;
    padding: 9px 0;
    border-bottom: 1px solid var(--border);
    font-size: 14px;
}

.highlight-list li:last-child {
    border-bottom: none;
}

.highlight-match {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.highlight-name {
    overflow: hidden;
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.highlight-teams {
    color: var(--muted);
    font-size: 12px;
    font-weight: 400;
}

.highlight-value {
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
}

.highlight-value.up {
    color: var(--success);
}

.highlight-value.down {
    color: var(--danger);
}

@container (max-width: 720px) {
    .highlights {
        grid-template-columns: minmax(0, 1fr);
        gap: 22px;
    }

    .highlight,
    .highlight:first-child,
    .highlight:last-child {
        padding: 0;
        border-left: none;
    }
}

/* Grading: what is graded, the buttons and the result filled in like the coupon, with the matches from top to bottom, and
   beside them from the very top, or under the matches when narrow, how many correct the rows get and what they are
   expected to win, compact enough to end about where the matches do. The rows go across the bottom. */

.grade {
    display: grid;
    gap: 18px;
    align-items: start;
}

@container (min-width: 720px) {
    .grade {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        grid-template-rows: auto 1fr auto;
        grid-template-areas:
            "intro outcome"
            "matches outcome"
            "rows rows";
        column-gap: 28px;
    }

    .grade-intro {
        grid-area: intro;
    }

    .grade-matches {
        grid-area: matches;
    }

    .grade-outcome {
        grid-area: outcome;
    }

    .grade-rows {
        grid-area: rows;
    }
}

.grade-intro,
.grade-outcome {
    display: grid;
    gap: 14px;
    min-width: 0;
}

.grade-matches {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 2px;
}

.grade-match {
    display: grid;
    grid-template-columns: 22px minmax(0, 1fr) auto;
    align-items: center;
    gap: 0 8px;
    padding: 2px 6px;
    border-radius: 8px;
}

.grade-match:nth-child(odd) {
    background: var(--surface-2);
}

.grade-number {
    font-size: 12px;
    font-weight: 700;
    color: var(--muted);
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Long names are cut short, and the whole name shows on hover. */
.grade-name {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-size: 14px;
}

.grade-signs {
    display: grid;
    grid-template-columns: repeat(3, 38px);
    gap: 4px;
}

.sign.small {
    width: 100%;
    max-width: 38px;
    height: 30px;
    padding: 0;
    font-size: 13px;
}

.sign.outside:not(.on) {
    border-style: dashed;
    color: var(--muted);
}

/* The best row and the turnover on one line, the turnover to the right also before there is a best row. */
.grade-summary {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 16px;
}

.grade-summary .payout-turnover {
    margin-left: auto;
}

.grade-best {
    font-size: 17px;
}

/* Laid out as the expected payouts, but with headers that may wrap, a muted line without rows, muted dashes where nothing
   is paid and the total under a rule. */
.grade-table {
    table-layout: fixed;
}

/* Lower lines than the expected payouts, so that all 14 numbers of correct fit beside the matches. */
.grade-table th,
.grade-table td {
    padding-block: 4px;
}

.grade-col-correct {
    width: 24%;
}

.grade-col-rows {
    width: 16%;
}

.grade-col-payout,
.grade-col-win {
    width: 30%;
}

.grade-table thead th {
    white-space: normal;
    vertical-align: bottom;
}

.grade-table tr.none td,
.grade-table td.unpaid {
    font-weight: 400;
    color: var(--muted);
}

.grade-table tfoot th,
.grade-table tfoot td {
    border-top: 1px solid var(--border);
}

/* Every row graded, under the rest. */
.grade-rows {
    display: grid;
    gap: 10px;
    min-width: 0;
}

/* Over the grading: the reduction or a file to grade, and the button for another file. */
.grade-source {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}

/* As wide as there is room for beside the file's button, which stays on the same line. */
.grade-source .segmented {
    flex: 1 1 auto;
    max-width: 380px;
}

.file-button svg {
    width: 18px;
    height: 18px;
}

/* The file input in a button or the upload area is out of sight, so they show its focus instead. */
.file-button:has(input:focus-visible) {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* Before a file is chosen: an area to click or drop a file on. The file input covers all of it, so a file dropped
   anywhere on it is chosen. */
.upload {
    position: relative;
    display: grid;
    justify-items: center;
    gap: 6px;
    padding: 36px 20px;
    border: 2px dashed var(--border);
    border-radius: 12px;
    background: var(--surface-2);
    color: var(--muted);
    text-align: center;
    cursor: pointer;
    transition: border-color 0.15s;
}

.upload:hover,
.upload:has(input:focus-visible) {
    border-color: var(--primary);
}

.upload strong {
    color: var(--text);
    font-size: 16px;
}

.upload svg {
    width: 34px;
    height: 34px;
    color: var(--primary);
}

.upload input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
}

/* Footer: the coupon's system along the bottom of the window once a match has a sign (CouponFooter). It comes up from the
   bottom and stays there over the page while it scrolls, and at the end of the page it is under it. */

.app-footer {
    position: sticky;
    bottom: 0;
    z-index: 10;
    border-top: 1px solid var(--border);
    background: var(--header);
    box-shadow: 0 -6px 20px rgb(16 24 40 / 8%);
    animation: footer-up 0.25s ease-out;
}

@keyframes footer-up {
    from {
        transform: translateY(100%);
    }
}

/* Keyboard focus and scrolling into view stop above the footer instead of under it. */
html:has(.app-footer) {
    scroll-padding-bottom: 120px;
}

/* The bankers and hedges, then how many of the matches have signs on the rest of the line, or once all have, what the
   rows cost and the download at the end. */
.app-footer-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 36px;
    max-width: 2000px;
    min-height: 68px;
    margin: 0 auto;
    padding: 12px 28px;
}

.footer-count {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    white-space: nowrap;
}

.footer-count svg {
    width: 18px;
    height: 18px;
    flex: none;
}

/* The names as short as on the coupon, only on phones. */
.footer-short {
    display: none;
}

.footer-count strong,
.footer-progress-text {
    font-variant-numeric: tabular-nums;
}

.footer-progress {
    display: flex;
    align-items: center;
    gap: 16px;
    flex: 1 1 240px;
    min-width: 0;
}

.footer-progress .progress {
    flex: 1;
    height: 6px;
    background: var(--border);
}

.footer-progress-text {
    font-size: 13px;
    white-space: nowrap;
}

/* The cost and the download, together at the end of the line. */
.footer-end {
    display: flex;
    align-items: center;
    gap: 24px;
    margin-left: auto;
}

/* What the rows cost, written as on Svenska Spel's coupon, for example "648 KR". */
.footer-cost {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-transform: uppercase;
    white-space: nowrap;
}

.app-footer .btn-download {
    font-size: 14px;
}

.app-footer .btn svg {
    width: 20px;
    height: 20px;
    flex: none;
}

@media (max-width: 600px) {
    .app-footer-inner {
        gap: 8px 20px;
        min-height: 0;
        padding: 10px 12px;
        font-size: 14px;
    }

    .footer-count {
        gap: 7px;
    }

    .footer-long {
        display: none;
    }

    .footer-short {
        display: inline;
    }

    /* The bankers and hedges on the first line, and the rest on the next. */
    .footer-progress,
    .footer-end {
        flex-basis: 100%;
    }

    .footer-end {
        gap: 16px;
    }

    .app-footer .btn-download {
        flex: 1 1 auto;
    }
}

@media (prefers-reduced-motion: reduce) {
    .app-footer {
        animation: none;
    }
}

/* Blazor loading and error UI */

#blazor-error-ui {
    background: var(--warning-soft);
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    color: var(--warning);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui a {
    color: inherit;
}

#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: "Ett fel har inträffat.";
}

.loading-progress {
    position: absolute;
    display: block;
    width: 8rem;
    height: 8rem;
    inset: 20vh 0 auto 0;
    margin: 0 auto 0 auto;
}

.loading-progress circle {
    fill: none;
    stroke: var(--border);
    stroke-width: 0.6rem;
    transform-origin: 50% 50%;
    transform: rotate(-90deg);
}

.loading-progress circle:last-child {
    stroke: var(--primary);
    stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
    transition: stroke-dasharray 0.05s ease-in-out;
}

.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}

.loading-progress-text:after {
    content: var(--blazor-load-percentage-text, "Laddar");
}

@media (max-width: 600px) {
    .app-header-inner {
        column-gap: 12px;
        padding: 12px 16px 0;
    }

    .brand {
        gap: 9px;
    }

    .brand-mark {
        width: 38px;
        height: 38px;
        font-size: 12px;
        border-radius: 10px;
    }

    .brand h1 {
        font-size: 17px;
    }

    .brand p {
        font-size: 11px;
    }

    .theme-toggle {
        width: 40px;
        padding: 8px;
    }

    .theme-toggle span {
        display: none !important;
    }

    .header-tools {
        gap: 12px;
    }

    .header-actions .btn {
        padding-inline: 12px;
    }

    .app-main {
        padding: 18px 12px 36px;
    }

    .layout,
    .group,
    .stack {
        gap: 18px;
    }

    .card {
        padding: 16px;
        gap: 16px;
    }

    /* A phone is narrower than the coupon's minimum width, so it takes the screen's width instead. */
    .coupon-card {
        min-width: 0;
    }

    .card h2 {
        font-size: 17px;
    }

    .segmented button {
        padding-inline: 7px;
    }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        transition: none !important;
    }
}
