/* Cric Squad — admin console additions
   ===========================================================================
   Loaded after the prototype's stylesheets and only for the admin area. It adds
   the few pieces the prototype rendered in JavaScript or did not have at all:
   the activity feed, the avatar stand-in, and the "soon" menu items.

   Everything here uses the design system's own tokens, so a change to the
   palette reaches these too. No new colours are introduced.
   ========================================================================= */

/* ---------------------------------------------------------------------------
   Avatar stand-in
   The prototype used a photograph for the signed-in user. A real admin account
   has no picture, so this is the initial on the brand colour — which is also
   what every one of these components does when an image fails to load.
   --------------------------------------------------------------------------- */
.admin-initials {
    display: inline-grid;
    place-items: center;
    background: var(--primary);
    color: #fff;
    font-weight: 700;
    font-size: 14px;
    line-height: 1;
}

/* ---------------------------------------------------------------------------
   Menu items for screens that do not exist yet
   Dimmed and not clickable. They are in the menu so the shape of the finished
   console is visible, and marked so nobody tries to click into nothing.
   --------------------------------------------------------------------------- */
.ds-nav .ds-soon {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border-radius: var(--radius-sm, 8px);
    color: var(--muted-2, #9CA3AF);
    font-size: 14px;
    cursor: not-allowed;
    opacity: .62;
    user-select: none;
}

/* .ds-count is a solid brand-green pill with white text — it was built to
   shout a number that needs attention. On a disabled item it does the
   opposite of what the item means, so it is flattened to an outline. */
.ds-nav .ds-count--soon {
    margin-left: auto;
    padding: 1px 7px;
    border: 1px solid currentColor;
    border-radius: 999px;
    background: none;
    color: inherit;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .08em;
}

/* ---------------------------------------------------------------------------
   Activity feed
   A list, not a timeline with a connecting rail: the entries are unrelated
   events that happen to be in order, and a rail implies one leads to the next.
   --------------------------------------------------------------------------- */
.act-feed {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 2px;
}

.act-item {
    display: grid;
    grid-template-columns: 32px minmax(0, 1fr) auto;
    align-items: start;
    gap: 12px;
    padding: 10px 4px;
    font-size: 14px;
    line-height: 1.45;
}

.act-item + .act-item {
    border-top: 1px solid var(--border);
}

.act-icon {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--surface-2);
    color: var(--muted);
    font-size: 14px;
}

.act-icon.ok   { background: var(--primary-soft); color: var(--primary); }
.act-icon.info { background: var(--info-soft, var(--surface-2)); color: var(--info, var(--muted)); }
.act-icon.warn { background: var(--warning-soft); color: var(--warning); }

.act-text {
    min-width: 0;          /* lets a long summary wrap instead of widening the card */
}

.act-when {
    color: var(--muted);
    font-size: 12px;
    white-space: nowrap;   /* "3 hrs ago" must never break across two lines */
    padding-top: 2px;
}

@media (max-width: 575.98px) {
    /* The timestamp drops under the text rather than squeezing it to nothing. */
    .act-item {
        grid-template-columns: 32px minmax(0, 1fr);
    }
    .act-when {
        grid-column: 2;
        padding-top: 0;
    }
}

/* ---------------------------------------------------------------------------
   Topbar dropdown — two plain rows the prototype's menu did not have
   --------------------------------------------------------------------------- */
.dropdown-menu .dd-plain {
    padding: 4px 14px 10px;
    font-size: 13px;
    color: var(--muted);
}

/* .dd-item is a link that sits in the same list as the sign-out button, so it
   shares the row shape rather than carrying a near-copy of it. */
.dropdown-menu .dd-signout,
.dropdown-menu .dd-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 10px 14px;
    border: 0;
    background: none;
    font: inherit;
    color: inherit;
    text-align: left;
    cursor: pointer;
}

.dropdown-menu .dd-signout:hover,
.dropdown-menu .dd-item:hover {
    background: var(--surface-2);
}

/* The sign-out form is a layout element the dropdown did not expect; without
   this it introduces a block gap between the separator and the button. */
.dropdown-menu form {
    margin: 0;
}

/* ===========================================================================
   Players list — sortable headings, row actions, detail pairs
   ========================================================================= */

/* ---- sortable column headings ---- */
.th-sort {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: inherit;
    text-decoration: none;
    white-space: nowrap;
}

.th-sort i {
    font-size: 11px;
    opacity: .35;      /* the arrow is a hint on every column, not a label */
}

.th-sort:hover i,
.th-sort.is-sorted i {
    opacity: 1;
    color: var(--primary);
}

/* ---- row actions ---- */
.row-actions {
    display: flex;
    align-items: center;
    gap: 2px;
    justify-content: flex-end;
}

/* Each action is its own form, which is a block element and would otherwise
   push the buttons onto separate lines. */
.inline-form {
    display: inline-flex;
    margin: 0;
}

.row-actions .icon-btn {
    width: 32px;
    height: 32px;
    font-size: 15px;
}

.row-actions .icon-btn.ok:hover    { color: var(--primary); }
.row-actions .icon-btn.danger:hover { color: var(--danger); }

/* ---- toolbar ---- */
/* The form is the toolbar, so it has to lay out like one rather than stacking
   its controls the way a form normally would. */
form.table-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}

form.table-toolbar .input-group {
    flex: 1 1 260px;
    min-width: 0;
}

form.table-toolbar .tt-actions {
    display: flex;
    gap: 8px;
    margin-left: auto;
}

/* ---- pagination gap marker ---- */
.pagination .pg-gap {
    padding: 0 4px;
    color: var(--muted);
    align-self: center;
}

/* ---- breadcrumb ---- */
.crumbs {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 14px;
    font-size: 13px;
    color: var(--muted);
}

.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--primary); text-decoration: underline; }
.crumbs i { font-size: 10px; opacity: .6; }

/* ---- label / value pairs on the detail page ---- */
.detail-list {
    display: grid;
    gap: 0;
    margin: 0;
}

.detail-list > div {
    display: grid;
    grid-template-columns: 150px minmax(0, 1fr);
    gap: 12px;
    padding: 10px 0;
    font-size: 14px;
}

.detail-list > div + div {
    border-top: 1px solid var(--border);
}

.detail-list dt { color: var(--muted); margin: 0; }
.detail-list dd { margin: 0; }

@media (max-width: 575.98px) {
    /* The label above the value, not squeezed into a third of a phone. */
    .detail-list > div { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}

.pv-avatar {
    width: 56px;
    height: 56px;
    font-size: 22px;
}

/* ---- form helpers ---- */
.field-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
}

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

.hint-error { color: var(--danger); }

.form-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding: 16px 20px;
    border-top: 1px solid var(--border);
}

/* The player cell carries a name over an email address, and an email address
   has no natural width — "naveen.kumar.33@example.com" pushed the table about
   90px past its card and took the action buttons off the right-hand edge with
   it. The name is what people scan; the address truncates. */
.table-cards .tc-main .media-row {
    max-width: 240px;
}

/* The text column of the flex row must be allowed to shrink below its content
   width, or ellipsis never engages - a flex item's min-width is auto. */
.table-cards .tc-main .media-row > span:last-child {
    min-width: 0;
}

.table-cards .tc-main .sub {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The actions column should never be the one that gets squeezed off. */
.table .cell-actions {
    width: 1%;
    white-space: nowrap;
}

@media (max-width: 767.98px) {
    /* .table-cards stacks into cards on a phone, where a capped width would
       truncate an address that now has the full row to itself. */
    .table-cards .tc-main .media-row { max-width: none; }
}

/* ---------------------------------------------------------------------------
   Players table column widths

   table-layout:auto sizes a table to its content, so a column holding email
   addresses simply makes the table wider than its card — the action buttons
   ended up past the right edge behind a horizontal scrollbar, which is the one
   column nobody should have to scroll to reach. A max-width on the cell does
   not help: in auto layout it is a suggestion.

   Fixed layout makes the widths below binding and lets the long values
   truncate. It applies only from 768px up, because below that .table-cards
   restacks each row as a card and there are no columns left to size.
   --------------------------------------------------------------------------- */
@media (min-width: 768px) {
    .players-table {
        table-layout: fixed;
        width: 100%;
    }

    .players-table .col-player  { width: 26%; }
    .players-table .col-role    { width: 13%; }
    .players-table .col-team    { width: 17%; }
    .players-table .col-city    { width: 12%; }
    .players-table .col-when    { width: 13%; }
    .players-table .col-status  { width: 11%; }
    .players-table .col-actions { width: 108px; }

    /* Anything that does not fit its column ends in an ellipsis rather than
       wrapping to a second line and making one row twice as tall as the rest. */
    .players-table tbody td {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* …except the player cell, which is a flex row of avatar + two lines. */
    .players-table tbody .tc-main {
        overflow: visible;
        white-space: normal;
    }
}

/* ---------------------------------------------------------------------------
   Bio, and the team picker
   --------------------------------------------------------------------------- */

.bio-block {
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
}

.bio-title {
    margin: 0 0 6px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--muted);
}

.bio-text {
    margin: 0;
    font-size: 14px;
    line-height: 1.6;
    /* A bio is prose. Past about 70 characters a line is hard to come back to
       at the start of the next one. */
    max-width: 65ch;
}

/* A pasted bio can contain a URL with no spaces in it, which would otherwise
   push the card wider than its column. */
.bio-text { overflow-wrap: anywhere; }

.team-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 6px;
}

.team-list li {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

/* ---- the picker on the edit form ---- */

.team-picker {
    border: 0;
    padding: 0;
    margin: 0;
    min-width: 0;   /* a fieldset refuses to shrink inside a grid without this */
}

.team-picker legend {
    padding: 0;
    margin-bottom: 6px;
    font-size: 14px;
    font-weight: 600;
}

.team-picker__box {
    max-height: 220px;
    overflow-y: auto;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm, 8px);
    background: var(--surface);
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 6px 16px;
}

.team-picker__box .check {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    margin: 0;
    cursor: pointer;
}

.team-picker.is-invalid .team-picker__box {
    border-color: var(--danger);
}

textarea.input {
    resize: vertical;
    min-height: 110px;
    line-height: 1.55;
}

/* ---------------------------------------------------------------------------
   Teams
   --------------------------------------------------------------------------- */
@media (min-width: 768px) {
    .teams-table { table-layout: fixed; width: 100%; }

    .teams-table .col-team    { width: 30%; }
    .teams-table .col-short   { width: 10%; }
    .teams-table .col-city    { width: 16%; }
    .teams-table .col-squad   { width: 10%; }
    .teams-table .col-played  { width: 11%; }
    .teams-table .col-status  { width: 12%; }
    .teams-table .col-actions { width: 108px; }

    .teams-table tbody td {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .teams-table tbody .tc-main { overflow: visible; white-space: normal; }
}

/* The "no players" toggle sits in the filter row, so it needs to line up with
   the controls beside it rather than with a form field's baseline. */
.table-toolbar .tt-check {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: 14px;
    white-space: nowrap;
    cursor: pointer;
}

.logo-preview {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border: 1px dashed var(--border);
    border-radius: var(--radius-sm, 8px);
}

.logo-preview img {
    width: 48px;
    height: 48px;
    object-fit: contain;
}

/* ---------------------------------------------------------------------------
   Matches
   --------------------------------------------------------------------------- */
@media (min-width: 768px) {
    .matches-table { table-layout: fixed; width: 100%; }

    /* Re-cut when the Scorer column arrived: the widths have to total 100%
       under table-layout:fixed, so adding a column means taking the space
       from somewhere rather than appending to it. */
    .matches-table .col-fixture { width: 21%; }
    .matches-table .col-comp    { width: 18%; }
    .matches-table .col-when    { width: 15%; }
    .matches-table .col-ground  { width: 16%; }
    .matches-table .col-state   { width: 12%; }
    .matches-table .col-scorer  { width: 13%; }
    .matches-table .col-actions { width: 76px; }

    .matches-table tbody td {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .matches-table tbody .tc-main { overflow: hidden; white-space: normal; }
}

/* ---- status chips above the table ---- */
.status-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 16px;
}

.status-chips .chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 14px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    color: var(--text);
    font-size: 13.5px;
    font-weight: 500;
    text-decoration: none;
}

.status-chips .chip:hover { border-color: var(--text); }

.status-chips .chip.is-active {
    background: var(--primary);
    border-color: var(--primary);
    color: #fff;
}

/* The count sits inside the chip, so it needs to read against both the plain
   and the selected background. */
.status-chips .chip-n {
    font-variant-numeric: tabular-nums;
    font-size: 12px;
    opacity: .7;
}

.status-chips .chip.is-active .chip-n { opacity: .85; }

/* ---- date range in the toolbar ---- */
.date-range {
    display: flex;
    align-items: center;
    gap: 6px;
}

.date-range .input {
    width: auto;
    min-width: 0;
    padding-inline: 10px;
}

/* ---- the two sides on the match page ---- */
.fixture-row {
    display: flex;
    align-items: center;
    gap: var(--is-s4, 16px);
    flex-wrap: wrap;
}

.fixture-side {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
    flex: 1 1 200px;
}

.fixture-v {
    flex: 0 0 auto;
    color: var(--text-2);
    font-weight: 600;
    text-transform: uppercase;
    font-size: 12px;
    letter-spacing: .1em;
}

.text-warning { color: var(--warning); }

/* ---------------------------------------------------------------------------
   Image field — upload, preview, remove, or a typed path
   --------------------------------------------------------------------------- */

.image-field__label {
    display: block;
    margin-bottom: 6px;
    font-size: 14px;
    font-weight: 600;
}

.image-field__row {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    flex-wrap: wrap;
}

.image-field__preview {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 84px;
    height: 84px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm, 8px);
    background: var(--surface-2);
    overflow: hidden;
}

/* contain, not cover: a crest with its own margins must not be cropped into. */
.image-field__preview img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.image-field__empty {
    font-size: 24px;
    color: var(--text-2);
    opacity: .5;
}

.image-field__controls {
    flex: 1 1 260px;
    min-width: 0;
    display: grid;
    gap: 8px;
    justify-items: start;
}

/* The file input is driven by its <label>, which can be styled as a button.
   Hidden with clip rather than display:none so it stays focusable and still
   announces itself — display:none would take it out of the tab order. */
.image-field__file {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.image-field__pick {
    cursor: pointer;
    margin: 0;
}

/* Keyboard focus lands on the hidden input, so the ring has to be drawn on the
   label that stands in for it. */
.image-field__file:focus-visible + .image-field__note,
.image-field__file:focus-visible ~ .image-field__note {
    outline: none;
}

.image-field__file:focus-visible + * { outline: none; }

.image-field:focus-within .image-field__pick {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

.image-field__note {
    font-size: 12px;
    color: var(--text-2);
}

.image-field__remove {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13.5px;
    margin: 0;
    cursor: pointer;
}

.image-field__path {
    width: 100%;
    font-size: 13px;
}

.image-field__path summary {
    cursor: pointer;
    color: var(--text-2);
    padding: 2px 0;
}

.image-field__path summary:hover { color: var(--primary); }

.image-field__path .input { margin-top: 8px; }

/* ---------------------------------------------------------------------------
   Career figures
   A two-column key/value grid rather than a table: these are nine unrelated
   numbers, not rows of the same kind of thing, and a table would promise a
   relationship between them that is not there.
   --------------------------------------------------------------------------- */

.stat-table {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 0 24px;
}

.stat-table > div {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 9px 0;
    border-bottom: 1px solid var(--border);
    font-size: 14px;
}

.stat-table .k { color: var(--text-2); }

.stat-table .v {
    font-weight: 700;
    /* Tabular figures, so a column of numbers lines up on the decimal point
       instead of wandering with the width of each digit. */
    font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------
   Scorecard
   --------------------------------------------------------------------------- */

.card-header--sub {
    border-top: 1px solid var(--border);
    background: var(--surface-2);
}

.card-header--sub h3 {
    margin: 0;
    font-size: 14px;
    font-weight: 700;
}

.scorecard-table td.n,
.scorecard-table th.n {
    font-variant-numeric: tabular-nums;
    text-align: right;
}

/* A did-not-bat row is there for completeness, not to be read. */
.scorecard-table tbody tr:has(.text-muted:first-child) { opacity: .85; }

/* The fixture card has six short lines in it; with the scorecard moved below it
   there is no second column, so it stops pretending to be half of a pair. */
.db-grid--one { grid-template-columns: minmax(0, 1fr); }

.scorecard-wrap { margin-top: var(--is-s5, 20px); }

/* ---------------------------------------------------------------------------
   Tournaments
   --------------------------------------------------------------------------- */
@media (min-width: 768px) {
    .tours-table { table-layout: fixed; width: 100%; }

    .tours-table .col-tour    { width: 26%; }
    .tours-table .col-dates   { width: 18%; }
    .tours-table .col-format  { width: 11%; }
    .tours-table .col-teams   { width: 10%; }
    .tours-table .col-fix     { width: 12%; }
    .tours-table .col-state   { width: 14%; }
    .tours-table .col-actions { width: 76px; }

    .tours-table tbody td {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .tours-table tbody .tc-main { overflow: hidden; white-space: normal; }
}

/* ---------------------------------------------------------------------------
   Form sections
   A long form needs headings, or it reads as thirty fields in a row. Each is a
   band inside the same card rather than separate cards, because they are one
   form with one Save button and separate cards would imply otherwise.
   --------------------------------------------------------------------------- */

.form-section {
    border-top: 1px solid var(--border);
}

.form-section__title {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0;
    padding: 16px 20px 0;
    font-size: 14px;
    font-weight: 700;
    letter-spacing: .02em;
}

.form-section__title i { color: var(--primary); }

/* A currency symbol sitting inside the field rather than floating beside it. */
.input-prefix {
    padding-left: 12px;
    color: var(--text-2);
    font-weight: 600;
}

/* ---------------------------------------------------------------------------
   Map
   --------------------------------------------------------------------------- */

.map-embed {
    position: relative;
    aspect-ratio: 16 / 9;
    background: var(--surface-2);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}

.map-embed iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

/* ---------------------------------------------------------------------------
   Gallery
   --------------------------------------------------------------------------- */

.gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
    gap: 14px;
}

.gallery__item { margin: 0; }

.gallery__item img {
    width: 100%;
    aspect-ratio: 4 / 3;
    /* cover, not contain: a gallery of photographs wants a tidy grid, and a
       photograph can be cropped without losing what it is of. Logos use
       contain for the opposite reason. */
    object-fit: cover;
    border-radius: var(--radius-sm, 8px);
    border: 1px solid var(--border);
    display: block;
}

.gallery__item figcaption {
    margin-top: 6px;
    font-size: 12.5px;
    color: var(--text-2);
    line-height: 1.4;
}

/* ---- the editable version ---- */

.gallery-edit {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 16px;
}

.gallery-edit__item {
    margin: 0;
    display: grid;
    gap: 8px;
    padding: 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm, 8px);
}

.gallery-edit__item img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: 6px;
    display: block;
}

.gallery-edit__item figcaption { display: grid; gap: 8px; }

.gallery-edit__item .check {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: 13px;
    cursor: pointer;
}

/* ---------------------------------------------------------------------------
   Grounds
   --------------------------------------------------------------------------- */
@media (min-width: 768px) {
    .grounds-table { table-layout: fixed; width: 100%; }

    .grounds-table .col-ground  { width: 30%; }
    .grounds-table .col-gcity   { width: 16%; }
    .grounds-table .col-pitch   { width: 14%; }
    .grounds-table .col-gmatch  { width: 14%; }
    .grounds-table .col-gstate  { width: 13%; }
    .grounds-table .col-actions { width: 108px; }

    .grounds-table tbody td {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .grounds-table tbody .tc-main { overflow: hidden; white-space: normal; }
}

/* ---------------------------------------------------------------------------
   Spacing utilities the admin pages use
   ---------------------------------------------------------------------------
   .mb-4 and .mt-3 are written throughout these screens but were never defined
   anywhere — the markup read as if it had spacing and silently had none. Added
   here rather than rewritten out of five files; the step matches the existing
   .mb-8/.mb-16/.mb-24 scale.
   --------------------------------------------------------------------------- */
.mb-4 { margin-bottom: 24px; }
.mt-3 { margin-top: 16px; }

/* ---------------------------------------------------------------------------
   Subscriptions
   --------------------------------------------------------------------------- */

/* The plan tiles sit in a .grid.grid-4, so each needs to carry its own height
   rather than stretch: a retired plan with no MRR line must not leave the row
   ragged. align-content:start is already on .plan-tile; this pins the footer
   link to the bottom so the four "Edit plan" links line up. */
.plan-tile { position: relative; }
.plan-tile .link { margin-top: auto; }
.plan-tile .progress { margin-top: 2px; }

@media (min-width: 768px) {
    .subs-table { table-layout: fixed; width: 100%; }

    .subs-table .col-subscriber { width: 26%; }
    .subs-table .col-plan       { width: 14%; }
    .subs-table .col-amount     { width: 13%; }
    .subs-table .col-since      { width: 11%; }
    .subs-table .col-renews     { width: 14%; }
    .subs-table .col-substate   { width: 12%; }
    .subs-table .col-actions    { width: 84px; }

    /* table-layout:fixed makes the widths above binding, but a long email would
       then push the cell wide unless the overflow is handled too. */
    .subs-table tbody td {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .subs-table tbody .tc-main { overflow: hidden; white-space: normal; }
}

/* ---------------------------------------------------------------------------
   Match results and standings
   --------------------------------------------------------------------------- */

/* The scoreline beside an innings heading: the total, then the overs under it. */
.innings-head { display: inline-flex; align-items: center; gap: 8px; }

/* The result entry form groups each innings, because four number fields with no
   boundary between the two innings is four fields nobody can place. */
.innings-fieldset {
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 16px;
    margin: 0;
}

.innings-fieldset > legend {
    padding: 0 8px;
    font-weight: 700;
    color: var(--heading);
}

/* Four across on a wide screen, stacking on a narrow one — the default
   .field-row is built for two. */
@media (min-width: 720px) {
    .innings-row { grid-template-columns: repeat(4, 1fr); }
}

/* What is about to be recorded, said back in words before saving. */
.result-preview {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border-radius: 12px;
    border: 1px dashed var(--primary);
    background: var(--surface-2);
    font-weight: 600;
    color: var(--heading);
}

.result-preview > i { color: var(--primary); }

@media (min-width: 768px) {
    .standings-table { table-layout: fixed; width: 100%; }

    .standings-table .col-pos    { width: 38px; }
    .standings-table .col-stteam { width: auto; }
    .standings-table .col-stn    { width: 44px; }
    .standings-table .col-stpts  { width: 54px; }
    .standings-table .col-stnrr  { width: 78px; }

    /* Figures in a table are read down the column, so they line up on the digit
       rather than on the left edge. */
    .standings-table td.n,
    .standings-table th.n { text-align: right; font-variant-numeric: tabular-nums; }
}

/* A points table on a phone is the one table that must NOT become cards: the
   whole value of it is comparing the rows. Narrow columns and a smaller figure
   keep all eight across at 360px. */
@media (max-width: 767px) {
    .standings-table { font-size: 13px; }
    .standings-table .media-row img,
    .standings-table .media-row .avatar { display: none; }
    .standings-table td, .standings-table th { padding-left: 6px; padding-right: 6px; }
}

/* ---------------------------------------------------------------------------
   Scorers
   --------------------------------------------------------------------------- */

/* A candidate who cannot take the fixture is dimmed, not hidden: an estimated
   duration is not entitled to remove somebody from the list, only to argue. */
.row-muted > td { opacity: .62; }
.row-muted:hover > td { opacity: 1; }

/* The one-time password. Deliberately loud — it is readable for this page load
   and then gone, so it must not be mistaken for a field somebody can come back
   to. */
.password-once__value {
    display: inline-block;
    margin: 6px 0;
    padding: 8px 14px;
    border-radius: 10px;
    background: var(--surface-3);
    border: 1px dashed var(--border);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 18px;
    letter-spacing: .04em;
    color: var(--heading);
    /* Selectable in one gesture: this gets read down a phone or pasted into a
       message, and a half-selected password is a support call. */
    user-select: all;
}

@media (min-width: 768px) {
    .scorers-table { table-layout: fixed; width: 100%; }

    .scorers-table .col-scorer   { width: 26%; }
    .scorers-table .col-scontact { width: 24%; }
    .scorers-table .col-scn      { width: 11%; }
    .scorers-table .col-seen     { width: 15%; }
    .scorers-table .col-scstate  { width: 11%; }
    .scorers-table .col-actions  { width: 108px; }

    .scorers-table tbody td {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .scorers-table tbody .tc-main { overflow: hidden; white-space: normal; }
}

/* ---------------------------------------------------------------------------
   Live scoring
   ---------------------------------------------------------------------------
   The pad is used one-handed on a phone at the edge of a ground, so the run
   buttons are sized for a thumb rather than a cursor: 56px is about the smallest
   target somebody hits reliably without looking, and the dots are the ones they
   hit most.
   --------------------------------------------------------------------------- */

.live-board {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px 24px;
    padding: 18px 22px;
    margin-bottom: 20px;
    border-radius: var(--radius-md);
    background: var(--surface-2);
    border: 1px solid var(--border);
}

.live-board .lb-main { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.live-board .lb-team { font-size: 13px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); font-weight: 700; }

.live-board .lb-score {
    font-family: var(--font-display);
    font-size: 2.6rem;
    font-weight: 800;
    line-height: 1;
    color: var(--heading);
    font-variant-numeric: tabular-nums;
}

.live-board .lb-sep   { color: var(--muted); font-weight: 500; margin: 0 2px; }
.live-board .lb-overs { font-size: 15px; color: var(--heading); font-variant-numeric: tabular-nums; }
.live-board .lb-meta  { display: flex; flex-wrap: wrap; gap: 6px 18px; font-size: 13px; color: var(--muted); }
.live-board .lb-meta b { color: var(--heading); font-variant-numeric: tabular-nums; }

/* Pad on the left, the book on the right — and stacked on a phone, pad first,
   because that is the half somebody is touching. */
.live-grid { display: grid; gap: 20px; }

@media (min-width: 1100px) {
    .live-grid { grid-template-columns: minmax(0, 420px) minmax(0, 1fr); align-items: start; }
}

/* The two batters and the bowler: the three lines a scorer actually watches. */
.at-wicket { display: grid; gap: 10px; }
.at-wicket .aw-batter,
.at-wicket .aw-bowler {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 12px;
    border-radius: 10px;
    background: var(--surface-2);
}

/* On strike needs to be obvious at a glance and without relying on the caret
   alone, which is small and easy to miss in sunlight. */
.at-wicket .is-striker { background: var(--surface-3); border-left: 3px solid var(--primary); }
.at-wicket .aw-bowler  { border-left: 3px solid var(--border); }
.at-wicket .aw-name    { font-weight: 600; color: var(--heading); }
.at-wicket .aw-figures { font-variant-numeric: tabular-nums; white-space: nowrap; }
.at-wicket .aw-figures b { font-size: 1.1rem; color: var(--heading); }

.run-pad   { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.extra-pad { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }

@media (min-width: 560px) {
    .run-pad   { grid-template-columns: repeat(7, 1fr); }
    .extra-pad { grid-template-columns: repeat(4, 1fr); }
}

.run-btn {
    width: 100%;
    min-height: 56px;
    border-radius: 12px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--heading);
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-weight: 700;
    cursor: pointer;
    transition: background var(--t-fast), border-color var(--t-fast), transform var(--t-fast);
}

.run-btn:hover  { border-color: var(--primary); background: var(--surface-3); }
/* Pressed state matters more than hover here: on a touch screen there is no
   hover, and the only feedback a scorer gets is the button moving. */
.run-btn:active { transform: scale(.96); }
.run-btn.is-dot      { color: var(--muted); font-size: 2rem; }
.run-btn.is-boundary { border-color: var(--primary); color: var(--primary); }

.live-more > summary { cursor: pointer; font-size: 13px; color: var(--muted); padding: 6px 0; }
.live-more[open] > summary { color: var(--heading); font-weight: 600; }

/* The over-by-over log, newest over first. */
.over-log  { display: grid; gap: 6px; max-height: 420px; overflow-y: auto; }
.over-row  { display: grid; grid-template-columns: 54px 1fr 36px; gap: 8px; align-items: center; }
.over-no   { font-size: 12px; color: var(--muted); font-weight: 600; }
.over-runs { font-size: 13px; text-align: right; color: var(--heading); font-variant-numeric: tabular-nums; }
.over-balls { display: flex; flex-wrap: wrap; gap: 4px; }

.ob {
    display: inline-grid;
    place-items: center;
    min-width: 26px;
    height: 26px;
    padding: 0 5px;
    border-radius: 50px;
    background: var(--surface-3);
    font-size: 12px;
    font-weight: 600;
    color: var(--heading);
}

.ob.is-extra    { background: transparent; border: 1px dashed var(--border); color: var(--muted); }
.ob.is-boundary { background: var(--primary); color: #fff; }
.ob.is-wicket   { background: var(--danger); color: #fff; }

/* Choosing a batter: a column of full-width buttons, because a grid of names at
   thumb size is a mis-tap waiting to happen. */
.pick-grid { display: grid; gap: 8px; }

@media (min-width: 560px) {
    .pick-grid { grid-template-columns: repeat(2, 1fr); }
}

.live-card.is-scoring { border-color: var(--danger); }
.live-mini { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px; }
.live-mini .lm-score {
    font-family: var(--font-display);
    font-size: 1.9rem;
    font-weight: 800;
    line-height: 1;
    color: var(--heading);
    font-variant-numeric: tabular-nums;
}
.live-mini .lm-overs { font-size: 13px; color: var(--muted); }

/* ---------------------------------------------------------------------------
   Settings
   ---------------------------------------------------------------------------
   WHY EVERY ROW IS THE SAME GRID

   Six control types with wildly different widths — a 150px number box, a
   full-width text input, a checkbox, a select, a file picker, a password field —
   laid out as a plain stack came out ragged: labels sat at different heights
   depending on how tall the control beside them was, hints started at different
   indents, and the "back to default" button floated under its field with a
   negative margin pulling it up.

   So every row is one three-column grid: label and provenance on the left, the
   control and its hint in the middle, the reset button in a column of its own on
   the right. The labels then line up down the page however different the controls
   are, and the reset button has somewhere to be instead of being wedged
   underneath.
   --------------------------------------------------------------------------- */

.setting-list { display: grid; gap: 0; }

.setting {
    display: grid;
    gap: 6px 20px;
    padding: 18px 0;
    border-top: 1px solid var(--border);
    align-items: start;
}

/* The first row sits against the card body's own padding, so it needs no rule. */
.setting:first-child { border-top: 0; padding-top: 4px; }
.setting:last-child  { padding-bottom: 4px; }

@media (min-width: 860px) {
    .setting {
        /* Label | control | reset. The control column takes the slack, because that
           is the one whose contents vary. */
        grid-template-columns: minmax(170px, 230px) minmax(0, 1fr) auto;
    }
}

.setting__label { display: grid; gap: 4px; }

.setting__label > label {
    font-weight: 600;
    color: var(--heading);
    /* Nudged onto the same optical line as the top of the control beside it: the
       label is 14px text and the input is a 40px box, so they do not align on
       their own. */
    padding-top: 9px;
    line-height: 1.3;
    cursor: pointer;
}

/* Provenance, under the label rather than beside it, so a long setting name and a
   long editor name never collide. */
.setting__flag {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--primary);
}

.setting__when {
    display: block;
    text-transform: none;
    letter-spacing: 0;
    font-weight: 500;
    color: var(--muted);
}

.setting__control { display: grid; gap: 8px; min-width: 0; }

/* A number field sized to its content. A year-wide box for a two-digit figure
   invites somebody to type four. */
.setting__control .input-num { max-width: 150px; }

/* The hint carries markup — <b>, <code> — so it is styled rather than escaped. */
.setting__control .hint { max-width: 62ch; }

.setting__control .hint code,
.setting__state code {
    padding: 1px 5px;
    border-radius: 5px;
    background: var(--surface-3);
    font-size: .92em;
}

.setting__state {
    font-size: 12px;
    color: var(--muted);
    display: flex;
    align-items: baseline;
    gap: 6px;
    flex-wrap: wrap;
}

.setting__state > i { color: var(--primary); }

/* The current logo, beside its path. */
.setting__image {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border-radius: 10px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    width: fit-content;
    max-width: 100%;
}

.setting__image img { max-height: 56px; width: auto; border-radius: 6px; }
.setting__image code { color: var(--muted); word-break: break-all; }

/* The reset column. On a narrow screen it has no column, so it drops under the
   control and the label is hidden to keep it to an icon. */
.setting__action { display: flex; justify-content: flex-end; padding-top: 4px; }

@media (max-width: 859px) {
    .setting__action { justify-content: flex-start; }
    .setting__action-label { display: none; }
}

.setting.has-error .setting__label > label { color: var(--danger); }

/* ---------------------------------------------------------------------------
   Settings tabs
   --------------------------------------------------------------------------- */

/* Nine tabs do not fit on a phone, so the strip scrolls sideways rather than
   wrapping into three rows that push the content off the screen. */
.settings-tabs {
    margin-bottom: 20px;
    overflow-x: auto;
    flex-wrap: nowrap;
    scrollbar-width: thin;
    /* Room for the focus ring, which an overflow container otherwise clips. */
    padding: 3px;
}

.settings-tabs .tab { white-space: nowrap; display: inline-flex; align-items: center; gap: 7px; }
.settings-tabs .tab > i { font-size: 15px; }

/* How many settings in a section somebody has changed. */
.tab-count {
    display: inline-grid;
    place-items: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 99px;
    background: var(--primary);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.settings-tabs .tab[aria-selected="true"] .tab-count { background: var(--heading); color: var(--surface-1); }

/* ---------------------------------------------------------------------------
   The SMTP conversation
   --------------------------------------------------------------------------- */

.inline-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.inline-row .input { flex: 1 1 220px; min-width: 0; }

.mail-log > summary { cursor: pointer; font-size: 13px; color: var(--muted); font-weight: 600; }

.mail-log pre {
    margin: 10px 0 6px;
    padding: 12px 14px;
    max-height: 260px;
    overflow: auto;
    border-radius: 10px;
    background: var(--surface-3);
    border: 1px solid var(--border);
    font-size: 12px;
    line-height: 1.6;
    /* The server's replies are long; wrapped, because a horizontal scrollbar hides
       the line that says what went wrong. */
    white-space: pre-wrap;
    word-break: break-word;
}

/* ---------------------------------------------------------------------------
   Admin accounts
   --------------------------------------------------------------------------- */

@media (min-width: 768px) {
    .admins-table { table-layout: fixed; width: 100%; }

    .admins-table .col-aname   { width: 34%; }
    .admins-table .col-arole   { width: 20%; }
    .admins-table .col-aseen   { width: 20%; }
    .admins-table .col-astate  { width: 14%; }
    .admins-table .col-actions { width: 84px; }

    .admins-table tbody td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .admins-table tbody .tc-main { overflow: hidden; white-space: normal; }
}

/* A control that is deliberately absent rather than disabled: the two account
   changes with no undo get no button, and this keeps the row's columns aligned
   while saying why on hover. */
.icon-btn.is-disabled { opacity: .3; cursor: not-allowed; display: inline-grid; place-items: center; }

/* ---------------------------------------------------------------------------
   Branding
   --------------------------------------------------------------------------- */

/* An uploaded logo is any shape. Constrained rather than stretched, so a wide
   wordmark stays legible and a tall one does not push the row open. */
.brand-logo { max-height: 34px; width: auto; max-width: 120px; object-fit: contain; }
.ds-brand .brand-logo { max-height: 30px; max-width: 96px; }

/* ---------------------------------------------------------------------------
   News
   --------------------------------------------------------------------------- */

/* Side by side on a wide screen: the body is the thing being written, and the
   publishing controls are glanceable beside it rather than a scroll away. */
.news-grid { display: grid; gap: 20px; margin-bottom: 20px; }

@media (min-width: 1100px) {
    .news-grid { grid-template-columns: minmax(0, 1fr) minmax(300px, 380px); align-items: start; }
}

.news-grid textarea { resize: vertical; min-height: 160px; font-family: inherit; line-height: 1.7; }

/* The thumbnail in the list. Fixed ratio so a portrait photo and a wide banner do
   not give the rows different heights. */
.news-thumb {
    width: 54px;
    height: 36px;
    flex: 0 0 auto;
    border-radius: 6px;
    object-fit: cover;
    background: var(--surface-3);
}

.news-thumb--empty { display: grid; place-items: center; color: var(--muted); font-size: 15px; }

@media (min-width: 768px) {
    .news-table { table-layout: fixed; width: 100%; }

    .news-table .col-article { width: 44%; }
    .news-table .col-ncat    { width: 15%; }
    .news-table .col-nwhen   { width: 16%; }
    .news-table .col-nstate  { width: 17%; }
    .news-table .col-actions { width: 108px; }

    .news-table tbody td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .news-table tbody .tc-main { overflow: hidden; white-space: normal; }
}

/* The preview, set as an article rather than as a form. Narrow measure on purpose:
   prose at full width is prose nobody finishes. */
.news-article {
    max-width: 68ch;
    margin: 0 auto;
    padding: 28px 0 8px;
}

.news-article__image {
    width: 100%;
    height: auto;
    max-height: 380px;
    object-fit: cover;
    border-radius: var(--radius-md);
    margin-bottom: 22px;
}

.news-article__byline { font-size: 13px; color: var(--muted); margin-bottom: 18px; }

.news-article__standfirst {
    font-size: 1.12rem;
    line-height: 1.6;
    color: var(--heading);
    font-weight: 500;
    padding-bottom: 18px;
    margin-bottom: 18px;
    border-bottom: 1px solid var(--border);
}

.news-article__body { font-size: 1rem; line-height: 1.75; }
.news-article__body p { margin: 0 0 1.1em; }
.news-article__body p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------------------
   Bulk import
   --------------------------------------------------------------------------- */

.import-grid { display: grid; gap: 20px; align-items: start; }

@media (min-width: 1000px) {
    .import-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* Every row of the preview is colour-coded down its left edge, because the thing
   somebody is scanning for is "what will this do" and a badge alone makes that a
   read-every-row job. The border is in addition to the badge, not instead of it:
   colour alone is not a label. */
.import-row > td:first-child { border-left: 3px solid transparent; }
.import-row--create > td:first-child { border-left-color: var(--success, #19a974); }
.import-row--update > td:first-child { border-left-color: var(--info, #3b82f6); }
.import-row--skip   > td:first-child { border-left-color: var(--border); }
.import-row--error  > td:first-child { border-left-color: var(--danger); }

/* A row that will do nothing is dimmed, so the ones that will act stand out. */
.import-row--skip > td { opacity: .66; }

/* An errored row is the one somebody has to act on, so it is tinted rather than
   dimmed. */
.import-row--error > td { background: color-mix(in srgb, var(--danger) 7%, transparent); }

@media (min-width: 768px) {
    .import-table { table-layout: fixed; width: 100%; }

    .import-table th:nth-child(1), .import-table td:nth-child(1) { width: 56px; }
    .import-table th:nth-child(2), .import-table td:nth-child(2) { width: 90px; }
    .import-table th:nth-child(3), .import-table td:nth-child(3) { width: 24%; }
    .import-table th:nth-child(4), .import-table td:nth-child(4) { width: 80px; }
    .import-table th:nth-child(5), .import-table td:nth-child(5) { width: 16%; }
    .import-table th:nth-child(6), .import-table td:nth-child(6) { width: 90px; }

    .import-table td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* A long file makes a long table; the preview scrolls inside the card rather than
   pushing the Import button off the bottom of the page. */
.import-table { margin: 0; }
.card > .table-wrap:has(.import-table) { max-height: 520px; overflow-y: auto; }

/* ---------------------------------------------------------------------------
   Player sign-in
   ---------------------------------------------------------------------------
   Built on .auth-layout, which the console's sign-in already uses — so these are
   additions to that layout rather than a second one. Only the pieces the player
   pages introduce are here: the bullet list and the figures in the visual panel,
   the label-with-link row, the strength meter and the step indicator.
   --------------------------------------------------------------------------- */

/* The form column is the one being used, so it gets the room on a laptop. The
   visual panel is an argument, not a tool. */
@media (min-width: 1024px) {
    .player-auth-layout { grid-template-columns: 1.05fr 1fr; }
}

/* ---- the visual panel ---------------------------------------------------- */

.av-points {
    list-style: none;
    margin: 22px 0 0;
    padding: 0;
    display: grid;
    gap: 10px;
}

.av-points li {
    display: flex;
    align-items: center;
    gap: 10px;
    color: #D7DCE1;
    font-size: 14px;
}

.av-points i {
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    flex: 0 0 auto;
    border-radius: 8px;
    background: rgba(255, 255, 255, .08);
    border: 1px solid rgba(255, 255, 255, .12);
    color: var(--primary-light);
    font-size: 13px;
}

/* The real contents of the database. Tabular figures so the three sit on a grid
   rather than drifting as the numbers change. */
.av-numbers {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 28px;
    padding-top: 20px;
    border-top: 1px solid rgba(255, 255, 255, .14);
}

.av-numbers > div { display: grid; gap: 1px; }

.av-numbers b {
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-weight: 800;
    line-height: 1;
    color: #fff;
    font-variant-numeric: tabular-nums;
}

.av-numbers span {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: #9CA3AF;
}

/* ---- the form column ----------------------------------------------------- */

/* NOT .auth-row: content.css already uses that name for the "remember me" line on
   the admin sign-in, as a flex row with justify-content: space-between. Overriding
   its display left that justify-content applying to a grid, where it stopped the
   single column stretching and left every field short of the panel. */

.auth-fields { display: grid; gap: 18px; }

/* Label on the left, "Forgotten it?" on the right, on the same line — so the link
   sits beside the field it is about instead of under the button, where it reads as
   an afterthought. */
.field-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 6px;
}

.field-head > label { margin: 0; }

.btn-lg { min-height: 48px; font-size: 15px; }

.auth-alt {
    margin-top: 22px;
    padding-top: 18px;
    border-top: 1px solid var(--border);
    display: grid;
    gap: 10px;
    text-align: center;
    font-size: 14px;
    color: var(--muted);
}

.auth-hint {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 10px 12px;
    border-radius: 10px;
    background: var(--card-2, var(--bg-alt));
    text-align: left;
    font-size: 12.5px;
    line-height: 1.55;
}

.auth-hint > i { color: var(--primary); margin-top: 2px; flex: 0 0 auto; }

/* ---- the step indicator -------------------------------------------------- */

/* Registering is two steps and the second happens in an email client, which is
   where people get lost. Saying so before they start is most of the fix. */
.auth-steps {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 4px;
    font-size: 12px;
    color: var(--muted);
}

.auth-steps__step { display: flex; align-items: center; gap: 7px; }

.auth-steps__num {
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: 1px solid var(--border-strong, var(--border));
    font-size: 11px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.auth-steps__step.is-current .auth-steps__num { background: var(--primary); border-color: var(--primary); color: #fff; }
.auth-steps__step.is-current { color: var(--heading); font-weight: 600; }
.auth-steps__step.is-done .auth-steps__num { background: var(--primary-soft); border-color: var(--primary); color: var(--primary); }
.auth-steps__rule { flex: 1; height: 1px; background: var(--border); }

/* ---- the strength meter -------------------------------------------------- */

/* The bar styles are in content.css, driven by data-level — this is the row the
   bar and its word sit in. */
.strength { margin-top: 8px; }
.strength .progress { height: 4px; }

.strength__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-top: 5px;
    font-size: 11.5px;
    color: var(--muted);
}

.strength__label { font-weight: 600; }
.strength[data-level="1"] .strength__label { color: var(--danger); }
.strength[data-level="2"] .strength__label { color: var(--warning); }
.strength[data-level="3"] .strength__label,
.strength[data-level="4"] .strength__label { color: var(--primary); }

/* ---- the "check your email" state ---------------------------------------- */

/* The screen somebody lands on after registering or asking for a reset. It is a
   dead end by design — the next step is in their inbox — so it is built to look
   finished rather than like a form that failed to appear. */
.auth-sent { text-align: center; padding: 6px 0 2px; }

.auth-sent__icon {
    display: grid;
    place-items: center;
    width: 64px;
    height: 64px;
    margin: 0 auto 18px;
    border-radius: 50%;
    background: var(--primary-soft);
    color: var(--primary);
    font-size: 26px;
}

.auth-sent__to {
    display: inline-block;
    margin: 2px 0 14px;
    padding: 5px 12px;
    border-radius: 99px;
    background: var(--card-2, var(--bg-alt));
    border: 1px solid var(--border);
    font-weight: 600;
    color: var(--heading);
    word-break: break-all;
}

.auth-sent__why {
    margin: 18px 0 0;
    padding: 12px 14px;
    border-radius: 10px;
    background: var(--card-2, var(--bg-alt));
    text-align: left;
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--muted);
}

/* The development stand-in for an email. Dashed and monospaced so it reads as
   scaffolding — if it ever shows up in production it should look wrong. */
.dev-link { border-style: dashed; }

.dev-link a {
    display: block;
    margin-top: 6px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 11px;
    word-break: break-all;
    line-height: 1.5;
}

/* ---------------------------------------------------------------------------
   Player dashboard
   --------------------------------------------------------------------------- */

.player-page { background: var(--bg-alt, var(--bg)); }

.player-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 12px 20px;
    background: var(--card, var(--bg));
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    z-index: 20;
}

.player-bar__right { display: flex; align-items: center; gap: 12px; }
.player-bar__who   { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 600; color: var(--heading); }

/* The name goes on a phone; the avatar carries the identity in the space left. */
@media (max-width: 520px) {
    .player-bar__who > span:last-child { display: none; }
}

.player-main { max-width: 900px; margin: 0 auto; padding: 24px 16px 48px; }

.player-team {
    padding: 12px 14px;
    border-radius: 12px;
    background: var(--card-2, var(--bg-alt));
    border: 1px solid var(--border);
    display: grid;
    gap: 2px;
}

/* The four headline figures above the dashboard cards. Four across on a laptop,
   two on a phone — not one, because these are meant to be read as a set and a
   single column turns them into a list. */
.mini-stats {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
}

.mini-stats > div {
    padding: 14px 16px;
    border-radius: 12px;
    background: var(--card, var(--bg));
    border: 1px solid var(--border);
    text-align: center;
}

.mini-stats .v {
    font-family: var(--font-display);
    font-size: 1.65rem;
    font-weight: 800;
    line-height: 1.1;
    color: var(--heading);
    /* So the four do not shuffle sideways as the figures change width. */
    font-variant-numeric: tabular-nums;
}

.mini-stats .l {
    margin-top: 2px;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: var(--muted);
}

@media (max-width: 640px) {
    .mini-stats { grid-template-columns: repeat(2, 1fr); }
}

/* Two short answers on one line. A sign-up form that asks eight questions down a
   phone screen gets abandoned around the fifth, so the ones that fit together go
   together — and go back to one column where they would not fit. */
.auth-pair {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 18px;
}

@media (max-width: 560px) {
    .auth-pair { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------------------------
   Player dashboard
   ---------------------------------------------------------------------------
   Built from the pieces the admin screens already use — .card, .badge, .table,
   .mini-stats, the SVG charts — so there is one visual language. Only the parts
   a player sees and an administrator does not are defined here.
   --------------------------------------------------------------------------- */

/* ---- the live banner ----------------------------------------------------- */

/* The one reason to open this page mid-afternoon, so it is the one thing that is
   allowed to shout. Dark, full width, above everything. */
.live-now {
    display: grid;
    gap: 6px;
    margin-bottom: 20px;
    padding: 16px 18px;
    border-radius: var(--radius-lg, 14px);
    background: linear-gradient(135deg, #111827, #1F2937);
    border: 1px solid rgba(239, 68, 68, .35);
    color: #fff;
    text-decoration: none;
}

.live-now__flag {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: #F87171;
}

.live-now__teams {
    font-family: var(--font-display);
    font-size: 1.25rem;
    font-weight: 800;
    line-height: 1.2;
}

.live-now__v { color: #9CA3AF; font-weight: 600; padding: 0 4px; }
.live-now__meta { font-size: 13px; color: #D1D5DB; }

/* ---- fixtures ------------------------------------------------------------ */

.fixture-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }

/* A grid, not a flex row. As a row the tournament badge sat beside the match and
   competed with it for width, so "vs Peelamedu United" wrapped onto three lines
   while the badge kept its own. The date spans both rows; the badge drops
   underneath, where it is a label on the fixture rather than a rival to it. */
.fixture {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 8px 14px;
    padding: 12px 2px;
}

.fixture__date { grid-row: span 2; align-self: start; }
.fixture .badge { grid-column: 2; justify-self: start; }

/* With nothing in the second row the gap would still be spent. */
.fixture:not(:has(.badge)) .fixture__date { grid-row: auto; align-self: center; }

.fixture + .fixture { border-top: 1px solid var(--border); }

/* A date block rather than a line of text: a column of them scans as a calendar,
   which is how somebody reads a fixture list. */
.fixture__date {
    display: grid;
    place-items: center;
    width: 46px;
    height: 46px;
    flex: 0 0 auto;
    border-radius: 10px;
    background: var(--card-2, var(--bg-alt));
    border: 1px solid var(--border);
    line-height: 1;
}

.fixture__date b {
    font-family: var(--font-display);
    font-size: 1.1rem;
    font-variant-numeric: tabular-nums;
    color: var(--heading);
}

.fixture__date span { font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }

.fixture__body { display: grid; gap: 2px; min-width: 0; flex: 1; }
.fixture__body b { color: var(--heading); }
.fixture__for, .fixture__where { font-size: 12.5px; color: var(--muted); }

.fixture__note {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--warning);
}

/* ---- team cards ---------------------------------------------------------- */

.team-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 14px;
}

.team-card {
    display: grid;
    gap: 10px;
    padding: 16px;
    border-radius: 12px;
    background: var(--card-2, var(--bg-alt));
    border: 1px solid var(--border);
}

.team-card__head { display: flex; align-items: center; gap: 12px; }
.team-card__head b { color: var(--heading); }

.team-card__logo {
    width: 40px;
    height: 40px;
    flex: 0 0 auto;
    border-radius: 10px;
    object-fit: contain;
    background: var(--surface, #fff);
    border: 1px solid var(--border);
}

.team-card__logo--empty { display: grid; place-items: center; color: var(--muted); }

/* The win rate as a bar, because "won 18 of 31" is a fraction nobody divides in
   their head while scrolling. */
.team-card__bar {
    height: 6px;
    border-radius: 99px;
    background: var(--surface-3, var(--border));
    overflow: hidden;
}

.team-card__bar > span { display: block; height: 100%; border-radius: 99px; background: var(--primary); }

.team-card__mine {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
    text-align: center;
}

.team-card__mine b {
    display: block;
    font-family: var(--font-display);
    font-size: 1.05rem;
    font-variant-numeric: tabular-nums;
    color: var(--heading);
}

.team-card__mine span { font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }

/* ---- the profile card ---------------------------------------------------- */

.profile-row { display: flex; align-items: flex-start; gap: 18px; flex-wrap: wrap; }

.profile-photo {
    width: 84px;
    height: 84px;
    flex: 0 0 auto;
    border-radius: 14px;
    object-fit: cover;
    background: var(--card-2, var(--bg-alt));
    border: 1px solid var(--border);
}

.profile-photo--empty {
    display: grid;
    place-items: center;
    font-family: var(--font-display);
    font-size: 2rem;
    font-weight: 800;
    color: var(--primary);
}

.profile-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 12px 24px;
    margin: 0;
    flex: 1;
    min-width: 220px;
}

.profile-facts dt {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: var(--muted);
}

.profile-facts dd { margin: 2px 0 0; color: var(--heading); font-weight: 600; word-break: break-word; }

.profile-bio {
    margin: 18px 0 14px;
    padding: 12px 14px;
    border-radius: 10px;
    background: var(--card-2, var(--bg-alt));
    font-size: 13.5px;
    line-height: 1.65;
    color: var(--muted);
}

@media (max-width: 560px) {
    .fixture__date { width: 40px; height: 40px; }
    .live-now__teams { font-size: 1.05rem; }
}

/* The four cards under the headline figures. Two up on a laptop, one on a phone.
   NOT .db-grid, which lives in the admin dashboard's own stylesheet and is a
   2:1 split for a main column beside a rail — the wrong shape here, and loading
   that whole sheet to borrow one rule would drag the admin chrome with it. */
.dash-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 20px;
    align-items: start;
}

/* An anchor, unlike a button, arrives underlined and in link colour. */
.dropdown-menu .dd-item { text-decoration: none; color: inherit; }

/* ---- the player topbar --------------------------------------------------- */

/* Where the admin console puts a search box. A player's season is one screen,
   so there is nothing to search; the space says which area you are in instead. */
.dt-title { display: grid; gap: 1px; flex: 1; min-width: 0; }
.dt-title b { color: var(--heading); font-size: 15px; }

/* The dashboard body is wider than the player area needs — a line of text 1100px
   long is hard to read — so the content is held to a column and centred. */
.player-shell .dash-content { max-width: 1120px; }

/* ---- profile completion -------------------------------------------------- */

/* "7 of 7" is a fraction nobody divides while scrolling, so the bar carries the
   answer and the number confirms it. */
.completion { display: flex; align-items: center; gap: 14px; }

.completion__bar {
    flex: 1;
    height: 8px;
    border-radius: 99px;
    background: var(--surface-3, var(--border));
    overflow: hidden;
}

.completion__bar > span {
    display: block;
    height: 100%;
    border-radius: 99px;
    background: var(--primary);
    transition: width var(--t-med, .25s);
}

.completion__pct {
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-variant-numeric: tabular-nums;
    color: var(--heading);
}

/* What is left, not what is done: a list of ticks is pleasant and tells somebody
   nothing they can act on. */
.completion__list {
    list-style: none;
    margin: 16px 0 0;
    padding: 0;
    display: grid;
    gap: 8px;
}

.completion__list li {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: 13.5px;
    color: var(--muted);
}

.completion__list i { font-size: 9px; color: var(--primary); }

/* The completion block beside the photo on the dashboard's profile card. */
.profile-side { flex: 1; min-width: 220px; display: grid; gap: 4px; align-content: start; }

/* ---------------------------------------------------------------------------
   My matches
   --------------------------------------------------------------------------- */

.result-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }

.result {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 14px;
    padding: 14px 2px;
}

.result + .result { border-top: 1px solid var(--border); }

/* W, L or a dash. A column of these is the fastest way to read a season, which
   is why it is a letter in a block and not a word in a sentence. */
.result__mark {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    flex: 0 0 auto;
    border-radius: 9px;
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 14px;
}

.result__mark--won  { background: var(--primary-soft); color: var(--primary); }
.result__mark--lost { background: var(--danger-soft, rgba(239,68,68,.12)); color: var(--danger); }
/* A tie and an abandoned match are neither, and must not read as a defeat. */
.result__mark--draw { background: var(--surface-3, var(--bg-alt)); color: var(--muted); }

.result__body { display: grid; gap: 2px; min-width: 0; }
.result__teams { font-weight: 600; color: var(--heading); text-decoration: none; }
.result__teams:hover { text-decoration: underline; }
.result__meta, .result__outcome { font-size: 12.5px; color: var(--muted); }
.result__outcome { font-style: italic; }

.result__mine { display: flex; align-items: center; gap: 18px; }

.result__stat { display: grid; justify-items: end; gap: 1px; text-align: right; }

.result__stat b {
    font-family: var(--font-display);
    font-size: 1.05rem;
    font-variant-numeric: tabular-nums;
    color: var(--heading);
}

.result__stat span { font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.result__stat--none span { text-transform: none; letter-spacing: 0; font-size: 12px; font-style: italic; }

.pager { display: flex; align-items: center; justify-content: center; gap: 16px; }
.pager__count { font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---- one match ----------------------------------------------------------- */

.match-result { display: grid; gap: 4px; }

.match-result__line {
    font-family: var(--font-display);
    font-size: 1.15rem;
    color: var(--heading);
}

.match-result__meta { font-size: 13px; color: var(--muted); }
.match-result__note { font-size: 13px; color: var(--muted); font-style: italic; }

.innings-totals {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 14px;
    margin-top: 18px;
    padding-top: 18px;
    border-top: 1px solid var(--border);
}

.innings-total { display: grid; gap: 2px; }
.innings-total__team { font-size: 12px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }

.innings-total__score {
    font-family: var(--font-display);
    font-size: 1.7rem;
    font-weight: 800;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--heading);
}

.innings-total__overs { font-size: 12.5px; color: var(--muted); }

/* Figures in a scorecard are compared down the column, so they need to line up:
   tabular numerals keep 8 and 11 the same width. */
.scorecard .num { font-variant-numeric: tabular-nums; }
.scorecard td, .scorecard th { white-space: nowrap; }
.scorecard td:first-child, .scorecard th:first-child { white-space: normal; }

/* The reader's own line. The point of the whole page is finding it quickly. */
.scorecard tr.is-me { background: var(--primary-soft); }
.scorecard tr.is-me td { font-weight: 600; }
.scorecard tr.is-me .badge { margin-left: 8px; }

@media (max-width: 640px) {
    .result { grid-template-columns: auto minmax(0, 1fr); gap: 8px 12px; }
    .result__mine { grid-column: 2; justify-content: flex-start; gap: 20px; }
    .result__stat { justify-items: start; text-align: left; }
}

/* ---------------------------------------------------------------------------
   My statistics / Performance
   --------------------------------------------------------------------------- */

/* A career figure and its name. Two columns on a laptop so batting and bowling
   cards stay the same height beside each other. */
.figures {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: 14px 20px;
    margin: 0;
}

.figures dt {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: var(--muted);
}

.figures dd {
    margin: 2px 0 0;
    font-family: var(--font-display);
    font-size: 1.25rem;
    font-weight: 800;
    line-height: 1.1;
    /* So a column of figures lines up: 8 and 11 the same width. */
    font-variant-numeric: tabular-nums;
    color: var(--heading);
}

.best-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.best-list li { display: grid; gap: 1px; padding: 10px 2px; }
.best-list li + li { border-top: 1px solid var(--border); }

.best-list__score {
    font-family: var(--font-display);
    font-size: 1.2rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    color: var(--heading);
    text-decoration: none;
}

.best-list__score:hover { text-decoration: underline; }
.best-list__score span { font-size: .8rem; font-weight: 600; color: var(--muted); }
.best-list__meta { font-size: 12.5px; color: var(--muted); }

/* ---- my teams ------------------------------------------------------------ */

.team-card__name { color: var(--heading); font-weight: 700; text-decoration: none; }
.team-card__name:hover { text-decoration: underline; }

.past-teams { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.past-teams li { display: grid; gap: 2px; padding: 11px 2px; }
.past-teams li + li { border-top: 1px solid var(--border); }
.past-teams__name { font-weight: 600; color: var(--heading); text-decoration: none; }
.past-teams__name:hover { text-decoration: underline; }
.past-teams__meta { font-size: 12.5px; color: var(--muted); }

/* ---- my tournaments ------------------------------------------------------ */

.tour-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }

.tour {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: center;
    gap: 8px 16px;
    padding: 13px 2px;
}

.tour + .tour { border-top: 1px solid var(--border); }
.tour__body { display: grid; gap: 2px; min-width: 0; }
.tour__name { font-weight: 600; color: var(--heading); text-decoration: none; }
.tour__name:hover { text-decoration: underline; }
.tour__meta { font-size: 12.5px; color: var(--muted); }
.tour__mine { display: flex; align-items: center; gap: 18px; }

@media (max-width: 640px) {
    .tour { grid-template-columns: minmax(0, 1fr) auto; }
    .tour__mine { grid-column: 1 / -1; justify-content: flex-start; gap: 20px; }
}

/* ---- achievements -------------------------------------------------------- */

.honour-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }

.honour {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 14px;
    padding: 13px 2px;
}

.honour + .honour { border-top: 1px solid var(--border); }

.honour__icon {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    flex: 0 0 auto;
    border-radius: 10px;
    background: var(--card-2, var(--bg-alt));
    border: 1px solid var(--border);
    color: var(--muted);
    font-size: 16px;
}

/* An award given by a person is marked out from a record that was counted. */
.honour__icon--award {
    background: var(--primary-soft);
    border-color: rgba(34, 197, 94, .25);
    color: var(--primary);
}

.honour__body { display: grid; gap: 2px; min-width: 0; }
.honour__body b { color: var(--heading); }
.honour__meta { font-size: 12.5px; color: var(--muted); }

.honour__figures {
    font-family: var(--font-display);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    color: var(--heading);
}

@media (max-width: 560px) {
    .honour { grid-template-columns: auto minmax(0, 1fr); }
    .honour > .btn { grid-column: 2; justify-self: start; }
}

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

.rank-figure { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px; }

.rank-figure b {
    font-family: var(--font-display);
    font-size: 2.2rem;
    font-weight: 800;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--primary);
}

.rank-figure span { font-size: 13px; color: var(--muted); }

/* Unranked is grey, not red. Not being ranked yet is not a failing. */
.rank-figure--none b { color: var(--muted); }

/* ---------------------------------------------------------------------------
   Availability & notifications
   --------------------------------------------------------------------------- */

.avail-toggle { display: flex; gap: 10px; flex-wrap: wrap; }

/* Two buttons rather than a checkbox: "In" and "Out" are both answers, and a
   checkbox makes one of them the absence of the other. */
.avail-answer { display: flex; gap: 6px; flex: 0 0 auto; }

.notice-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }

.notice {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: start;
    gap: 14px;
    padding: 14px 2px;
}

.notice + .notice { border-top: 1px solid var(--border); }

/* Unread is marked by a bar at the edge, not by a different background: a block
   of coloured rows reads as a warning rather than as "new". */
.notice.is-unread { box-shadow: inset 3px 0 0 var(--primary); padding-left: 12px; }

.notice__icon {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    flex: 0 0 auto;
    border-radius: 9px;
    background: var(--card-2, var(--bg-alt));
    border: 1px solid var(--border);
    color: var(--muted);
}

.notice.is-unread .notice__icon { background: var(--primary-soft); color: var(--primary); border-color: rgba(34,197,94,.25); }

.notice__body { display: grid; gap: 2px; min-width: 0; }

.notice__kind {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: var(--muted);
}

.notice__title { color: var(--heading); font-weight: 600; text-decoration: none; }
a.notice__title:hover { text-decoration: underline; }
.notice__text { font-size: 13px; color: var(--muted); }
.notice__when { font-size: 11.5px; color: var(--subtle, var(--muted)); }

/* ---- a row of tabs inside a card header ---------------------------------- */

.tab-row { display: flex; gap: 4px; }

.tab-link {
    padding: 7px 14px;
    border-radius: 9px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--muted);
    text-decoration: none;
}

.tab-link:hover { background: var(--surface-2, var(--bg-alt)); }
.tab-link.is-active { background: var(--primary-soft); color: var(--primary); }

@media (max-width: 560px) {
    .notice { grid-template-columns: auto minmax(0, 1fr); }
    .notice > form { grid-column: 2; justify-self: start; }
}

/* ---------------------------------------------------------------------------
   Account: settings, verification, help
   --------------------------------------------------------------------------- */

.pref-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.pref-list .check { display: flex; align-items: center; gap: 10px; }
.pref-list .check > span { display: flex; align-items: center; gap: 9px; color: var(--heading); }
.pref-list .check i { color: var(--muted); }

/* ---- verification status ------------------------------------------------- */

.verify-state {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px;
    border-radius: 12px;
    background: var(--card-2, var(--bg-alt));
    border: 1px solid var(--border);
}

.verify-state > i { font-size: 26px; color: var(--muted); }
.verify-state b { display: block; color: var(--heading); }
.verify-state span { font-size: 13px; color: var(--muted); }

.verify-state--done { background: var(--primary-soft); border-color: rgba(34, 197, 94, .25); }
.verify-state--done > i { color: var(--primary); }

/* Waiting is amber, not red: nothing has gone wrong. */
.verify-state--waiting { background: var(--warning-soft, var(--bg-alt)); border-color: rgba(245, 158, 11, .25); }
.verify-state--waiting > i { color: var(--warning); }

/* ---- FAQs ---------------------------------------------------------------- */

.faqs { display: grid; gap: 2px; }

.faqs details { padding: 4px 0; }
.faqs details + details { border-top: 1px solid var(--border); }

.faqs summary {
    padding: 11px 2px;
    cursor: pointer;
    font-weight: 600;
    color: var(--heading);
    list-style: none;
}

.faqs summary::-webkit-details-marker { display: none; }

.faqs summary::before {
    content: "\F4FE";
    font-family: "bootstrap-icons";
    font-size: 12px;
    margin-right: 10px;
    color: var(--muted);
}

.faqs details[open] summary::before { content: "\F2E6"; }

.faqs p { margin: 0 0 12px 24px; font-size: 13.5px; line-height: 1.65; color: var(--muted); }

/* ---------------------------------------------------------------------------
   Find teams & tournaments
   --------------------------------------------------------------------------- */

.filter-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 14px;
    align-items: end;
}

.filter-row__go { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

.role-tags { display: flex; flex-wrap: wrap; gap: 6px; }

.team-card__note {
    margin: 0;
    font-size: 13px;
    line-height: 1.6;
    color: var(--muted);
    font-style: italic;
}

/* The "ask to join" form, folded away until wanted — a textarea under every
   card on the page would bury the clubs themselves. */
.apply summary { list-style: none; display: inline-flex; cursor: pointer; }
.apply summary::-webkit-details-marker { display: none; }
.apply[open] summary { margin-bottom: 4px; }

/* A status badge on a team card carries a sentence, not a word, so it has to be
   allowed to wrap rather than being clipped by the card edge. */
.team-card > .badge { white-space: normal; text-align: left; align-self: start; }

/* ---------------------------------------------------------------------------
   Highlights
   --------------------------------------------------------------------------- */

.featured {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 12px;
}

.featured__item {
    display: grid;
    gap: 2px;
    padding: 14px 16px;
    border-radius: 12px;
    background: var(--card-2, var(--bg-alt));
    border: 1px solid var(--border);
    text-decoration: none;
}

.featured__item:hover { border-color: var(--primary); }

.featured__item b {
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-variant-numeric: tabular-nums;
    color: var(--heading);
}

.featured__item span { font-size: 12.5px; color: var(--muted); }
.featured__when { font-size: 11px !important; letter-spacing: .05em; text-transform: uppercase; }

.reel {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 18px;
}

.reel__item {
    margin: 0;
    display: grid;
    gap: 8px;
    padding: 12px;
    border-radius: 12px;
    background: var(--card-2, var(--bg-alt));
    border: 1px solid var(--border);
}

/* 16:9 without a wrapper hack, so the iframe cannot stretch the grid row. */
.reel__video { position: relative; width: 100%; aspect-ratio: 16 / 9; border-radius: 9px; overflow: hidden; background: #000; }
.reel__video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.reel__image { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 9px; background: var(--surface-3, var(--border)); }

.reel__item figcaption { display: grid; gap: 2px; }
.reel__item figcaption b { color: var(--heading); font-size: 14px; }
.reel__item figcaption span { font-size: 12px; color: var(--muted); }
.reel__item form { justify-self: start; }

/* ---------------------------------------------------------------------------
   Messages
   --------------------------------------------------------------------------- */

.thread-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }

.thread {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: start;
    gap: 14px;
    padding: 14px 2px;
}

.thread + .thread { border-top: 1px solid var(--border); }
.thread.is-unread { box-shadow: inset 3px 0 0 var(--primary); padding-left: 12px; }

.thread__icon {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 9px;
    background: var(--card-2, var(--bg-alt));
    border: 1px solid var(--border);
    color: var(--muted);
}

.thread.is-unread .thread__icon { background: var(--primary-soft); color: var(--primary); }

.thread__body { display: grid; gap: 2px; min-width: 0; }
.thread__subject { font-weight: 600; color: var(--heading); text-decoration: none; }
.thread__subject:hover { text-decoration: underline; }
.thread__meta { font-size: 12px; color: var(--muted); }

.thread__preview {
    font-size: 13px;
    color: var(--muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.people { display: flex; flex-wrap: wrap; gap: 8px 16px; }
.people__one { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--heading); }

/* ---- the conversation ---------------------------------------------------- */

.talk { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }

.talk__item {
    display: grid;
    gap: 4px;
    padding: 12px 14px;
    border-radius: 12px;
    background: var(--card-2, var(--bg-alt));
    border: 1px solid var(--border);
    max-width: 80%;
}

/* Your own messages sit to the right, which is how every messaging app reads
   and saves anybody checking the name on each one. */
.talk__item.is-mine { margin-left: auto; background: var(--primary-soft); border-color: rgba(34, 197, 94, .25); }

.talk__who { display: flex; align-items: baseline; gap: 10px; font-size: 12.5px; font-weight: 600; color: var(--heading); }
.talk__when { font-weight: 400; font-size: 11.5px; color: var(--muted); }
.talk__body { margin: 0; font-size: 14px; line-height: 1.6; color: var(--heading); overflow-wrap: anywhere; }

form.card-footer { display: flex; align-items: flex-end; gap: 12px; }

@media (max-width: 560px) {
    .talk__item { max-width: 100%; }
    .thread { grid-template-columns: auto minmax(0, 1fr); }
}

/* =============================================================================
   TEAM & ORGANISER AREA CLASSES
   -----------------------------------------------------------------------------
   The team (/team) and organiser (/organizer) screens were written with a set
   of class names that no stylesheet defined — stat tiles, spacing helpers, row
   layouts — so they rendered as plain stacked boxes. Defined here in the same
   visual language as the player dashboard (.mini-stats, .stat-card), so all
   three areas look like one product.
   ============================================================================= */

/* Headline figures: a row of tiles, four across on a laptop, two on a phone. */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 14px;
}
.stat-grid .stat-card {
    padding: 18px 20px;
    box-shadow: var(--shadow-sm, none);
    position: relative;
    overflow: hidden;
}
.stat-grid .stat-card::before {
    content: "";
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 3px;
    background: var(--primary-light);
    opacity: .85;
}
.sc-label {
    font-size: 12px;
    font-weight: 700;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: .08em;
}
.sc-value {
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 2.1rem;
    line-height: 1.1;
    color: var(--heading);
    margin-top: 6px;
    font-variant-numeric: tabular-nums;
}
.sc-foot { font-size: 12px; color: var(--muted); margin-top: 4px; }
@media (max-width: 640px) {
    .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
    .sc-value { font-size: 1.7rem; }
}

/* Two cards side by side (recent results | upcoming), stacked on a phone. */
.row-split {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 20px;
    align-items: start;
}
@media (max-width: 900px) { .row-split { grid-template-columns: minmax(0, 1fr); } }

/* A grid of link cards (the team picker, the organiser's tournaments). */
.row-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 14px;
}
.row-cards > .card { margin-bottom: 0; }

/* Avatar + name + subline in one row. */
.cell-media { display: flex; align-items: center; gap: 12px; min-width: 0; }
.cell-media b, .cell-media strong { color: var(--heading); }

/* Flex helpers. */
.flex-between { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.flex-wrap { flex-wrap: wrap; }
.gap-2 { gap: 8px; }
.btn-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

/* Spacing helpers (Bootstrap-style numbers used by these screens). */
.mb-1 { margin-bottom: 4px; }
.mb-2 { margin-bottom: 8px; }
.mb-3 { margin-bottom: 16px; }
.mt-2 { margin-top: 8px; }
.mt-4 { margin-top: 24px; }
.d-none { display: none !important; }

.text-success { color: var(--primary-light); font-weight: 600; }

/* Inactive rows: still readable, clearly secondary. */
tr.is-dimmed td, tr.is-dimmed th, .is-dimmed { opacity: .55; }

/* Smaller inputs for inline table forms and filters. */
.input-sm { height: 34px; padding: 0 10px; font-size: 13px; border-radius: 7px; }
select.input-sm { padding-right: 28px; }

/* Form labels written as <label class="field"><span class="field-label">. */
.field-label { font-size: 13px; font-weight: 600; color: var(--heading); }
.field-hint { font-size: 12px; color: var(--muted); }
.form-grid .field-wide, .field-wide { grid-column: 1 / -1; }
.form-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 900px) { .form-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .form-grid-4 { grid-template-columns: minmax(0, 1fr); } }

.sticky-actions {
    position: sticky;
    bottom: 0;
    z-index: 5;
    background: var(--surface);
    border-top: 1px solid var(--border);
}

/* Bootstrap-style bar inside .progress. */
.progress > .progress-bar {
    height: 100%;
    border-radius: inherit;
    background: linear-gradient(90deg, var(--primary-dark), var(--primary-light));
}

.btn-warning { background: #F59E0B; color: #111; border-color: #F59E0B; }
.btn-warning:hover { background: #D97706; border-color: #D97706; color: #111; }

@media print { .no-print { display: none !important; } }
