/* ============================================================
   /contributor — the PAGE-SPECIFIC half of the archive.

   ⚠️ REQUIRES public/css/archive.css, LOADED FIRST. That file carries every
   `.as-*` rule the three archives share (filter bar, view toggle, list frame,
   `.is-grid` reflow, empty state). What is left here is only the part that is
   named after contributor data: the column tracks and their placement, the
   `.as-col-*` typography, the avatar, the podium treatment and the
   golden/special badge palette.

   Both files are pulled in by resources/views/contributors.blade.php via
   @include('partials.archive.head') followed by a <link> to this file — order
   is load-bearing, because most rules below sit at the SAME specificity as the
   shared ones they refine.

   ── THE ONE STRUCTURAL DIVERGENCE FROM /stones ──────────────────────────────
   The stones archive relies on grid AUTO-PLACEMENT: its row cells and its
   header cells are written in the same DOM order, so track 1 gets the first
   cell of each. This page cannot do that. partials.archive.list-head renders
   sortable columns first and $staticColumns after them, and two of this page's
   static cells (rank, avatar) belong at the FRONT of the row while two (places,
   type) belong in the middle — so head order and row order are necessarily
   different.

   Every cell is therefore placed EXPLICITLY with `grid-column: N`. That is
   strictly stronger than matching DOM order: the head and the rows line up
   regardless of how either is written, and adding or removing a cell cannot
   silently shift every column after it by one track.
   ============================================================ */

/* The two grid tracks the shared chrome reads. `--as-grid` is consumed by BOTH
   `.as-list-head` and `.as-row`, so the header and the rows cannot drift out of
   alignment.

   Nine tracks: #, avatar, name, stones, countries, continents, places, type,
   latest. Four filter cells: search, country, continent, actions. */
.as-wrap {
    --as-grid: 40px 44px 1fr 74px 82px 96px 68px 104px 104px;
    --as-filter-cols: 1.6fr 1.1fr 1.1fr auto;
}

/* Nine columns is four more than /stones carries, so the shared 16px gutter is
   tightened here to buy the name column back ~32px on a laptop.

   ⚠️ WRAPPED IN min-width:761px ON PURPOSE. A media query adds no specificity,
   so a bare `.as-row { gap: 12px }` in this file would also beat archive.css's
   `@media (max-width: 760px) { .as-row { gap: 6px 14px } }` — later file, equal
   specificity — and would quietly retune the mobile card's row/column gutters
   as a side effect of a desktop tweak. */
@media (min-width: 761px) {
    .as-list-head,
    .as-row { gap: 12px; }
}

/* ── Column placement ───────────────────────────────────────────────────────
   Applies to the header cells and the data cells alike — one class, one track,
   both files. `.as-thumb` (row) and `.as-col-avatar` (header) share track 2. */
.as-col-rank { grid-column: 1; }
.as-thumb,
.as-col-avatar { grid-column: 2; }
.as-col-name { grid-column: 3; }
.as-col-stones { grid-column: 4; }
.as-col-countries { grid-column: 5; }
.as-col-continents { grid-column: 6; }
.as-col-places { grid-column: 7; }
.as-col-types { grid-column: 8; }
.as-col-latest { grid-column: 9; }

/* ⚠️ `grid-column` ALONE IS NOT ENOUGH, and this header proved it in a browser.
   It names the track but not the ROW, so auto-placement still runs a cursor that
   only ever moves FORWARD: once `latest` is placed in track 9, the next cell
   asking for track 1 cannot go behind the cursor and starts a second row instead.
   partials.archive.list-head emits sortable columns first and the static ones
   after, so the head order really is 3,4,5,6,9 then 1,2,7,8 — the header split
   across two lines with "Places" and "Type" sitting under the wrong columns,
   while every data row (whose DOM order happens to ascend) looked perfect.

   Pinning the row makes the placement fully explicit, which is what the note at
   the top of this file believed it already was. It also means a future reorder
   of the head partial cannot reintroduce this.

   ⚠️ Scoped away from gallery view below: there the same cells deliberately
   reflow into a multi-line card. */
.as-list-head > * { grid-row: 1; }

/* The SAME defect hit the data rows, for the same reason and just as invisibly
   to the test suite. `.as-thumb` (track 2) is emitted before `.as-col-rank`
   (track 1), so the avatar took row 1 and every other cell was pushed to row 2:
   each row rendered 112px tall with the avatar stranded above the name, instead
   of one 56px line. It looked like a spacing choice, which is why only a
   screenshot caught it.

   ⚠️ `:not(.is-grid)` IS LOAD-BEARING. Gallery view reflows these exact cells
   into a stacked card on purpose; pinning them all to row 1 there would collapse
   every card onto a single line.

   ⚠️ AND SO IS THE MEDIA QUERY, WHICH WAS MISSING AND BROKE THE PHONE LAYOUT
   COMPLETELY. Unscoped, this rule also applied at ≤760px, where the row is a
   multi-line CARD — it pinned all nine cells to row 1 at (0,3,1), beating the
   card's `grid-area` placements at (0,1,0) on grid-row-start alone. The result:
   rows 2-7 computed to 0px and every stat stacked on top of every other one.
   Measured at 375px before the fix: stones, countries, continents, places and
   latest all occupied the identical 311x27 box, and `grid-area: stones`
   computed to `1 / stones`.

   That is the "overlapping text" on the contributors list, and it is invisible
   to the test suite: the markup, the classes and the desktop table are all
   correct. Only a measured box comparison or a real phone shows it. */
@media (min-width: 761px) {
    .as-list:not(.is-grid) .as-row > * { grid-row: 1; }
}

/* ── Columns ────────────────────────────────────────────────────────────────
   Size/weight/colour are scoped to `.as-row` so they do not leak into the
   header, which keeps its own uniform 11px uppercase treatment. */
.as-col-rank,
.as-col-stones,
.as-col-countries,
.as-col-continents,
.as-col-places,
.as-col-latest { min-width: 0; }
.as-col-name { min-width: 0; }

.as-row .as-col-rank {
    font-family: var(--ps-font-heading);
    font-size: 16px;
    line-height: 1.35;
    color: var(--ps-text-light);
}
.as-row .as-stat-num {
    font-size: 14px;
    font-weight: 700;
    color: var(--ps-text-mid);
    line-height: 1.35;
    white-space: nowrap;
}
/* Stones is the number the page is ranked by — it reads as the primary one. */
.as-row .as-col-stones .as-stat-num { color: var(--ps-heading); font-weight: 800; }
.as-row .as-col-latest .as-stat-num { font-weight: 600; color: var(--ps-text-light); }

/* The unit ("stones", "countries") is carried by the column header in list
   view, so the per-cell label is hidden there and revealed only where there is
   no header to read: the mobile card and the gallery card. */
.as-stat-label { display: none; }

.as-col-types { display: flex; flex-wrap: wrap; gap: 4px; align-content: flex-start; }

/* ── Avatar ─────────────────────────────────────────────────────────────────
   ⚠️ archive.css keeps `.as-thumb` display:none in list view, because on
   /stones the thumbnail is a GALLERY-ONLY image. Here it is the avatar, which
   the list has always shown, so this page turns it back on. It is still ONE
   element rendered once per row — the gallery enlarges it rather than
   rendering a second copy, which is what keeps list and gallery a single
   server render. */
.as-thumb {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
}
.as-thumb img {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    object-fit: cover;
    display: block;
    background: var(--ps-border);
}

/* ── Badge colours ──────────────────────────────────────────────────────────
   Shape comes from `.as-badge` in archive.css; these two modifiers are the
   same palette /stones uses for the matching stone types. Only golden and
   special are defined — a "standard" badge is never rendered here, because
   every contributor would carry one. */
.as-badge--golden { background: #FEF3C7; color: #92400E; }
.as-badge--special { background: #EDE9FE; color: #4C1D95; }

/* ── Podium ─────────────────────────────────────────────────────────────────
   Kept from the list this replaces. The medal stripe is an INSET BOX-SHADOW
   rather than a border-left: a border would add 4px to the row's box and shift
   every track out of line with the header, which has no such border. */
.as-row.is-podium { background: linear-gradient(90deg, var(--ps-tint-gold, #fff8e1) 0%, rgba(255, 248, 225, 0) 55%); }
/* ⚠️ Scoped with :not(.is-grid) rather than overridden inside the gallery block.
   A stripe declared unconditionally would have to be cancelled there, and the
   cancelling rule would sit at the same specificity as archive.css's
   `.as-list.is-grid .as-row:hover` box-shadow — so podium CARDS would be the
   only ones with no hover lift. Not declaring it is cleaner than undoing it. */
.as-list:not(.is-grid) .as-row.is-podium-1 { box-shadow: inset 4px 0 0 #d4a017; }
.as-list:not(.is-grid) .as-row.is-podium-2 { box-shadow: inset 4px 0 0 #c0c0c0; }
.as-list:not(.is-grid) .as-row.is-podium-3 { box-shadow: inset 4px 0 0 #cd7f32; }
/* archive.css's `.as-row:hover` is the same specificity as `.as-row.is-podium`
   and loses on load order, so the podium rows would otherwise be the only ones
   with no hover feedback. */
.as-row.is-podium:hover { background: var(--ps-blue-pale); }
.as-row.is-podium .as-col-rank { color: var(--ps-heading); font-weight: 700; }

/* ── Gallery view: the contributor card ─────────────────────────────────────
   Same rows, reflowed. archive.css makes `.as-list.is-grid .as-row` a column
   flexbox; a card here needs two stats side by side, so it becomes a small
   named grid instead. Every cell is re-placed with `grid-area`, which overrides
   the `grid-column` above. */
.as-list.is-grid .as-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
        "thumb      thumb"
        "rank       rank"
        "name       name"
        "stones     countries"
        "continents places"
        "types      types";
    gap: 0;
    padding: 0 0 16px;
    text-align: center;
    justify-items: center;
}
.as-list.is-grid .as-thumb {
    grid-area: thumb;
    /* archive.css sets display:block here at this same specificity; the avatar
       needs the flex centring from the base rule back. */
    display: flex;
    /* archive.css gives the stones card a full-bleed 4:3 photo; an avatar is a
       portrait, so it sits centred with air around it instead. */
    aspect-ratio: auto;
    background: transparent;
    width: auto;
    height: auto;
    padding: 22px 0 12px;
}
.as-list.is-grid .as-thumb img {
    width: 92px;
    height: 92px;
    border: 3px solid var(--ps-border);
}
.as-list.is-grid .as-col-rank {
    grid-area: rank;
    font-size: 13px;
    font-weight: 800;
    color: var(--ps-yellow);
    padding: 0 14px;
}
.as-list.is-grid .as-col-rank::before { content: "#"; }
.as-list.is-grid .as-col-name { grid-area: name; padding: 2px 14px 10px; max-width: 100%; }
.as-list.is-grid .as-col-name .as-loc-main { font-size: 15px; white-space: normal; }
/* archive.css hides the secondary line on a card; here it is the "N stones in
   Slovakia" answer to the filter that produced the card, so it stays. */
.as-list.is-grid .as-col-name .as-loc-sub { display: block; white-space: normal; }
.as-list.is-grid .as-col-stones { grid-area: stones; }
.as-list.is-grid .as-col-countries { grid-area: countries; }
.as-list.is-grid .as-col-continents { grid-area: continents; }
.as-list.is-grid .as-col-places { grid-area: places; }
.as-list.is-grid .as-col-types { grid-area: types; justify-content: center; padding: 8px 14px 0; }
/* The date is the one column a card drops — it is a table fact, and it is the
   widest thing that would have to wrap. */
.as-list.is-grid .as-col-latest { display: none; }

.as-list.is-grid .as-col-stones,
.as-list.is-grid .as-col-countries,
.as-list.is-grid .as-col-continents,
.as-list.is-grid .as-col-places {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
    padding: 6px 8px;
    width: 100%;
    box-sizing: border-box;
}
.as-list.is-grid .as-stat-label {
    display: block;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--ps-text-light);
}
/* The card keeps archive.css's white background (`.as-list.is-grid .as-row`
   already outranks `.as-row.is-podium`), so the podium reads as a medal-coloured
   border instead of the list's left stripe. */
.as-list.is-grid .as-row.is-podium-1 { border-color: #d4a017; }
.as-list.is-grid .as-row.is-podium-2 { border-color: #c0c0c0; }
.as-list.is-grid .as-row.is-podium-3 { border-color: #cd7f32; }

/* ── Breakpoints ────────────────────────────────────────────────────────────
   760 / 600 / 420 are the theme's own archive breakpoints. archive.css already
   handles the shared half of each (card chrome, hidden header, mobile sortbar,
   two-up gallery, 16px inputs); what remains is this page's cell layout.
   ------------------------------------------------------------------------- */
@media (max-width: 760px) {
    /* ── THE PHONE LIST IS DELIBERATELY THREE THINGS ──────────────────────────
       Avatar, name, stones. Nothing else.

       What was here mirrored the countries table: nine cells laid out as
       identity-then-figures over three rows. It was correct and it was too
       much — on a phone this page is a LEADERBOARD you scan, and countries,
       continents, places, golden count and latest date are all answers to
       questions nobody asks while scrolling. Six rows now fit on a screen
       where two did.

       ⚠️ THE DATA IS HIDDEN, NOT REMOVED, which is the whole point of the one
       shared render: the same markup still carries every cell, so the desktop
       table and the GALLERY view keep the full picture. Nothing here changes
       what the server sends.

       ⚠️ SCOPED TO `:not(.is-grid)`. Gallery view reflows these exact cells
       into a card on purpose — hiding them without the guard would empty every
       gallery tile on a phone, and gallery is precisely the view somebody
       switches TO in order to see more. */
    .as-list:not(.is-grid) .as-row {
        grid-template-columns: auto minmax(0, 1fr) auto;
        grid-template-areas: "avatar name stones";
        align-items: center;
    }
    .as-list:not(.is-grid) .as-col-rank { grid-area: avatar; }
    .as-list:not(.is-grid) .as-thumb { grid-area: avatar; }
    .as-list:not(.is-grid) .as-col-name { grid-area: name; }
    .as-list:not(.is-grid) .as-col-stones { grid-area: stones; text-align: right; }

    .as-list:not(.is-grid) .as-col-countries,
    .as-list:not(.is-grid) .as-col-continents,
    .as-list:not(.is-grid) .as-col-places,
    .as-list:not(.is-grid) .as-col-types,
    .as-list:not(.is-grid) .as-col-latest { display: none; }

    /* Rank rides the avatar as a corner badge rather than taking a track of its
       own: it is an ordinal, not a statistic, and it belongs to the face it
       numbers. */
    .as-list:not(.is-grid) .as-col-rank {
        font-size: 11px;
        font-weight: 800;
        align-self: end;
        justify-self: start;
        z-index: 1;
        background: var(--ps-navy);
        color: #fff;
        border-radius: 999px;
        min-width: 20px;
        height: 20px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        padding: 0 5px;
        margin: 0 0 -4px -4px;
    }

    /* One figure, so it reads as a number over its unit. Block, never inline:
       "491 stones" on one baseline in a monospace face is what used to wrap
       into the neighbouring cell. */
    .as-list:not(.is-grid) .as-stat-label {
        display: block;
        font-size: 10px;
        font-weight: 800;
        text-transform: uppercase;
        letter-spacing: 0.5px;
        color: var(--ps-text-light);
        margin: 1px 0 0;
    }
    .as-list:not(.is-grid) .as-col-stones { font-size: 19px; font-weight: 800; }

    /* The medal stripe becomes a top edge — a left inset shadow is invisible
       once the row has its own rounded card border. */
    .as-list:not(.is-grid) .as-row.is-podium-1 { box-shadow: inset 0 4px 0 #d4a017, var(--ps-shadow); }
    .as-list:not(.is-grid) .as-row.is-podium-2 { box-shadow: inset 0 4px 0 #c0c0c0, var(--ps-shadow); }
    .as-list:not(.is-grid) .as-row.is-podium-3 { box-shadow: inset 0 4px 0 #cd7f32, var(--ps-shadow); }
}

/* ⚠️ NO 420px BLOCK ANY MORE. It re-flowed the nine-cell card into two columns
   because three stats stopped fitting side by side; with three items in one row
   there is nothing left to re-flow, and `minmax(0, 1fr)` on the name track is
   what lets a long handle shrink instead of pushing the count off-screen. */
