/* The public, unauthenticated pages (TV mode, dernières arrivées, runner
   lookup, results, link-unavailable). See base.css's header comment for why
   a rule ending up here instead of base.css is a filing choice, not a
   loading boundary. */


/* Public per-race results page (plain and "TV mode" ?display=tv alike): the
   title and the table's header row must stay on screen no matter how far
   the results list is scrolled (by hand, or auto-scrolled in TV mode). This
   page pins the whole body to the viewport height with nothing but
   .public-results-scroll-area actually scrolling inside it, and keeps the
   title outside that scrolling region entirely, so it never moves.

   The header row is deliberately its OWN separate, non-scrolling <table>
   (.public-results-header-scroll) rather than a sticky <thead> inside the
   same table as the body: browsers have a well-known rendering bug where a
   sticky <th> can flicker BEHIND an actively-scrolling row instead of
   staying in front of it (a compositing race - looks fine on a static
   screenshot, only shows up while genuinely scrolling), and neither
   border-collapse:separate nor forcing a compositor layer reliably fixes
   it. Two structurally separate tables can never have that problem. Since
   they then size their columns independently by their own content, JS
   (see public_results.html) mirrors the body's horizontal scroll onto the
   header and copies each body column's rendered width onto its header
   cell, so the two still read as one aligned table. */
body.public-results-body {
    margin: 0;
    height: 100vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

/* .page-content (base.css) sits between `body` and .public-results-page -
   it must keep passing the flex chain through unconstrained (no
   max-width/padding of its own here) for .public-results-page's own
   `flex: 1 1 auto` below to actually fill the remaining viewport height. */
body.public-results-body .page-content {
    max-width: none;
    margin: 0;
    padding: 0;
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.public-results-page {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding: 16px clamp(12px, 3vw, 32px) 0;
}

.public-results-title {
    flex: 0 0 auto;
    margin: 0 0 8px;
}

/* The dedicated event-level TV screen (public_event_tv.html) is read from
   across a room rather than up close - bump its title well past the
   normal h1 size (22px) for that viewing distance. Scoped to that page
   only (not the per-race results page, which shares .public-results-title
   but is a normal up-close screen/device). */
.public-event-tv-body .public-results-title {
    font-size: 30px;
}

/* Houses the title and #connection-status on the same line - same idea as
   .public-arrivals-title-group on the "dernières arrivées" page, just
   without a second item (this screen has no race-clocks widget) so there's
   no need for the row/group split or justify-content:space-between there. */
.public-tv-title-row {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 12px;
    margin: 0 0 8px;
}

.public-tv-title-row .public-results-title {
    margin: 0;
    flex: 0 1 auto;
    min-width: 0;
}

/* Bottom ticker (public_event_tv.html): a fixed flex child alongside
   .public-results-page, like .app-footer below it - toggling its
   display:none (see renderTicker) hands its space straight back to the
   results card above via flexbox, no JS height recalculation needed. Text
   size matches the title (30px, see above) since both are meant to be
   read from across a room. */
.public-tv-ticker {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 24px;
    background: #000;
    color: #fff;
    font-size: 30px;
    font-weight: 700;
    padding: 10px clamp(12px, 3vw, 32px);
}

.public-tv-ticker-label {
    flex: 0 0 auto;
    white-space: nowrap;
}

.public-tv-ticker-track {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
}

.public-tv-ticker-content {
    display: inline-block;
    white-space: nowrap;
    will-change: transform;
    /* Scrolling text only - the fixed "Dernières arrivées :" label stays
       at the full title-matching size (see .public-tv-ticker above); 0.8em
       of that inherited 30px is a 20% reduction. */
    font-size: 0.8em;
}

/* Same pink as .text-female in the results/arrivals tables, for a female
   runner's name in the ticker. */
.public-tv-ticker-female {
    color: #FF1493;
}

.public-results-card {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding: 0;
    overflow: hidden;
}

.public-results-header-scroll {
    flex: 0 0 auto;
    overflow: hidden;
    padding: 16px 16px 0;
}

.public-results-scroll-area {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
    padding: 0 16px 16px;
}

/* Overrides the global table's margin-top:8px - with two separate tables
   now (header + body) that default would open a visible seam between the
   header row and the first data row that never existed with one <table>. */
.public-results-table {
    margin-top: 0;
}

/* #connection-banner (see .connection-banner above) is left in its default,
   normal-flow layout here - same as the quick-entry card - so it pushes the
   title row and results card down by its own height while shown rather than
   overlaying them (an earlier fixed/full-bleed version clipped the title
   underneath it). public_event_arrivals.html recomputes the table's visible
   row count whenever this shifts the available height (see the
   MutationObserver there), same idea as loadRacesForClocks re-triggering it
   when the race clocks wrap. */

.public-arrivals-title-row {
    flex: 0 0 auto;
    margin: 0 0 8px;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 6px 16px;
}

/* Houses the title and #connection-status side by side on the same line -
   this group (not the title alone) now carries the flex:1 1 auto that lets
   .public-arrivals-race-clocks stay pinned to the row's far right via the
   row's justify-content:space-between. */
.public-arrivals-title-group {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 12px;
    flex: 1 1 auto;
    min-width: 0;
}

.public-arrivals-title-row .public-results-title {
    margin: 0;
    flex: 0 1 auto;
    min-width: 0;
}

.public-arrivals-race-clocks {
    flex: 0 0 auto;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 8px;
}

.public-arrivals-race-clock {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 4px 12px;
    border: 2px solid #ccc;
    border-radius: 20px;
    background: #fff;
    white-space: nowrap;
}

.public-arrivals-race-clock-name {
    font-weight: 700;
    font-size: 13px;
    text-transform: uppercase;
}

.public-arrivals-race-clock-time {
    font-weight: 700;
    font-size: 16px;
    font-family: "Courier New", Courier, monospace;
    font-variant-numeric: tabular-nums;
    color: #222;
}

@media (max-width: 700px) {
    .public-arrivals-race-clock { padding: 3px 9px; }
    .public-arrivals-race-clock-name { font-size: 11px; }
    .public-arrivals-race-clock-time { font-size: 14px; }
}

/* Public "dernières arrivées" screen (public_event_arrivals.html).

   The header/body split (see the big comment above) mirrors the BODY's
   rendered column widths onto the header via JS on every other public
   results page - that works there because those tables are wide relative
   to their (few, longer) column labels. This table has many narrow
   columns with short-but-not-that-short labels ("Clt sexe", "Clt cat"):
   under the default auto table layout, a <th> can never be forced
   narrower than its own nowrap text needs, so the browser silently
   overrides whatever width JS copied from the (much narrower) data cell -
   and since every column's rendering depends on all the others sharing
   one fixed total width, that one refusal throws off every column after
   it, compounding rightward into a growing header/data misalignment.

   table-layout:fixed sidesteps this entirely: column widths come only
   from these explicit rules (identical for both the header <th>s and the
   body <td>s, since both tables share .public-results-table), never from
   content, so the two tables can never disagree - no JS width sync
   needed at all, just the horizontal scroll-position mirror. Overflowing
   text is handled explicitly instead (ellipsis on data cells; header
   labels are short enough to just wrap). */
.public-event-arrivals-body .public-results-table {
    table-layout: fixed;
}

.public-event-arrivals-body .public-results-table th {
    white-space: normal;
}

.public-event-arrivals-body .public-results-table td {
    overflow: hidden;
    text-overflow: ellipsis;
}

.public-event-arrivals-body .public-results-table th:nth-child(1),
.public-event-arrivals-body .public-results-table td:nth-child(1) { width: 70px; }   /* Dossard */
.public-event-arrivals-body .public-results-table th:nth-child(2),
.public-event-arrivals-body .public-results-table td:nth-child(2) { width: 40px; }   /* Clt */
.public-event-arrivals-body .public-results-table th:nth-child(3),
.public-event-arrivals-body .public-results-table td:nth-child(3) { width: 110px; }  /* Nom */
.public-event-arrivals-body .public-results-table th:nth-child(4),
.public-event-arrivals-body .public-results-table td:nth-child(4) { width: 100px; }  /* Prénom */
.public-event-arrivals-body .public-results-table th:nth-child(5),
.public-event-arrivals-body .public-results-table td:nth-child(5) { width: 130px; }  /* Club */
.public-event-arrivals-body .public-results-table th:nth-child(6),
.public-event-arrivals-body .public-results-table td:nth-child(6) { width: 55px; }   /* Sexe */
.public-event-arrivals-body .public-results-table th:nth-child(7),
.public-event-arrivals-body .public-results-table td:nth-child(7) { width: 50px; }   /* Cat */
.public-event-arrivals-body .public-results-table th:nth-child(8),
.public-event-arrivals-body .public-results-table td:nth-child(8) { width: 140px; }  /* Course */
.public-event-arrivals-body .public-results-table th:nth-child(9),
.public-event-arrivals-body .public-results-table td:nth-child(9) { width: 85px; }   /* Temps */
.public-event-arrivals-body .public-results-table th:nth-child(10),
.public-event-arrivals-body .public-results-table td:nth-child(10) { width: 85px; }  /* Écart */
.public-event-arrivals-body .public-results-table th:nth-child(11),
.public-event-arrivals-body .public-results-table td:nth-child(11) { width: 75px; }  /* Clt sexe */
.public-event-arrivals-body .public-results-table th:nth-child(12),
.public-event-arrivals-body .public-results-table td:nth-child(12) { width: 65px; }  /* Clt cat */

/* Public runner-lookup page (public_runner_lookup.html): a single big
   search field with a custom autocomplete dropdown underneath - no
   <datalist>, since we need custom rows (bib badge + name + race/category/
   gender) rather than plain text options. */
.runner-search-box {
    position: relative;
}

.runner-search-input {
    width: 100%;
    box-sizing: border-box;
    font-size: 20px;
    padding: 14px 16px;
    border: 2px solid #185fa5;
    border-radius: 10px;
}

.runner-search-input:focus {
    outline: none;
    border-color: #0c447c;
    box-shadow: 0 0 0 4px rgba(24, 95, 165, 0.15);
}

.runner-search-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: 4px;
    background: white;
    border: 1px solid #ddd;
    border-radius: 10px;
    max-height: 320px;
    overflow-y: auto;
    z-index: 50;
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12);
}

.runner-search-dropdown-item {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    padding: 12px 14px;
    cursor: pointer;
    border-bottom: 1px solid #eee;
}

.runner-search-dropdown-item:last-child { border-bottom: none; }
.runner-search-dropdown-item:hover { background: #f4f8fc; }

.runner-search-dropdown-meta {
    color: #777;
    font-size: 13px;
    margin-left: auto;
}

.runner-search-dropdown-empty {
    padding: 14px;
    color: #777;
    text-align: center;
}

/* Selected runner's identity, on the public runner-lookup page: a plain
   2-line header (name + bib, then race/gender/category/club) rather than
   boxed "input-like" fields - those are reserved for the actual results
   grid below (.profile-grid), which stays boxed since each is a distinct
   labelled stat. */
.runner-header-line1 {
    font-size: 22px;
    font-weight: 800;
    text-transform: uppercase;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 10px;
}

.runner-header-bib {
    color: #185fa5;
}

.runner-header-line2 {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 8px;
    color: #555;
    font-size: 15px;
}

.runner-header-line2 strong {
    color: #1c1f24;
}

.runner-header-line3 {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 4px;
    color: #555;
    font-size: 15px;
}

.runner-header-line3 strong {
    color: #1c1f24;
}

.runner-header-sep {
    color: #ccc;
}

/* Shown instead of the actual public page (results/runner-lookup) when a
   public link's token is unrecognized (typo, or the link was regenerated -
   see public_token in models.py) or was explicitly disabled (see
   public_link_active) - same centered, logo-topped layout as the login
   page, since both are anonymous full-page states unrelated to any event. */
.link-unavailable-wrap {
    display: flex;
    justify-content: center;
    padding-top: 8vh;
}

.link-unavailable-card {
    width: 100%;
    max-width: 420px;
    text-align: center;
}

.link-unavailable-logo {
    display: block;
    max-width: 220px;
    width: 100%;
    height: auto;
    margin: 0 auto 16px;
}

.link-unavailable-message {
    color: #555;
    font-size: 15px;
}
