/* KIOSK LEADERBOARD styles
   Loaded ONLY on the kiosk-leaderboard submodule page, so page-level
   overrides below (body background, hiding the site footer) cannot
   affect any other page.

   Default is LIGHT mode using the site's bootstrap palette (light body,
   dark table heads, subtle borders, colour only for indication).
   .kiosk-theme-dark overrides the variables for the optional dark mode. */

body {
    overflow: hidden;
}

footer.footer {
    display: none !important;
}

.kiosk-root {
    /* light theme (site style) */
    --k-bg: #f8f9fa;
    --k-surface: #ffffff;
    --k-border: #dee2e6;
    --k-border-soft: #e9ecef;
    --k-text: #212529;
    --k-text-muted: #6c757d;
    --k-head-bg: #343a40;
    --k-head-text: #ffffff;
    --k-head-sub: #ced4da;
    --k-accent: #007bff;
    --k-row-alt: #f8f9fa;
    --k-bib: #495057;
    --k-danger: #dc3545;
    --k-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
}

.kiosk-root.kiosk-theme-dark {
    --k-bg: #10141b;
    --k-surface: #1a212d;
    --k-border: #2a3547;
    --k-border-soft: #222b3a;
    --k-text: #e8ecf2;
    --k-text-muted: #8fa3c0;
    --k-head-bg: #24405e;
    --k-head-text: #ffffff;
    --k-head-sub: #9db4d0;
    --k-accent: #4d9fff;
    --k-row-alt: rgba(255, 255, 255, 0.03);
    --k-bib: #ffd166;
    --k-danger: #e5484d;
    --k-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
}

.kiosk-root {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    background: var(--k-bg);
    color: var(--k-text);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    z-index: 1040;
}

.kiosk-error,
.kiosk-empty {
    margin: auto;
    padding: 2rem 3rem;
    font-size: 1.6rem;
    color: var(--k-text-muted);
    text-align: center;
}

/* ---------------- event header/footer banners -------------------------- */
/* Always white, in both themes - uploaded event images are designed on white.
   The image drives the banner height (max-height:9vh); the JS ResizeObserver
   re-splits the pages once the images have decoded, so the card area always
   knows the real available height. */
.kiosk-banner {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: #ffffff;
    border-bottom: 1px solid var(--k-border);
}

.kiosk-banner-header {
    border-top: 1px solid var(--k-border);
}

.kiosk-banner-footer {
    border-bottom: none;
    border-top: 1px solid var(--k-border);
}

.kiosk-banner img {
    max-width: 100%;
    max-height: 9vh;
    object-fit: contain;
}

/* ---------------- top bar ---------------------------------------------- */
.kiosk-topbar {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.55rem 1.25rem;
    background: var(--k-head-bg);
    color: var(--k-head-text);
    border-bottom: 3px solid var(--k-accent);
}

.kiosk-topbar-left,
.kiosk-topbar-right {
    display: flex;
    align-items: center;
    min-width: 0;
    flex: 1 1 0;
}

.kiosk-topbar-right {
    justify-content: flex-end;
}

.kiosk-topbar-center {
    flex: 0 0 auto;
    text-align: center;
    padding: 0 1rem;
}

.kiosk-live-dot {
    width: 0.65rem;
    height: 0.65rem;
    border-radius: 50%;
    background: var(--k-danger);
    margin-right: 0.55rem;
    animation: kiosk-pulse 1.6s ease-in-out infinite;
}

@keyframes kiosk-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.35; }
}

.kiosk-event-name {
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.kiosk-title {
    display: block;
    font-size: 1.3rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.kiosk-scope {
    display: block;
    font-size: 0.85rem;
    color: var(--k-head-sub);
    letter-spacing: 0.05em;
}

.kiosk-updated {
    font-size: 0.85rem;
    color: var(--k-head-sub);
    white-space: nowrap;
}

/* icon buttons (fullscreen + settings) */
.kiosk-icon-btn {
    margin-left: 0.6rem;
    color: var(--k-head-sub);
    border: 1px solid var(--k-head-sub);
    background: transparent;
    font-size: 1rem;
    line-height: 1;
    padding: 0.25rem 0.5rem;
}

.kiosk-icon-btn:hover {
    color: var(--k-head-text);
    border-color: var(--k-accent);
}

/* ---------------- cards grid ------------------------------------------- */
.kiosk-cards-viewport {
    flex: 1 1 auto;
    /* min-height:0 lets this flex child shrink below its content so the fixed
       pager footer below it is always kept on screen (never pushed off the
       fixed-height root). overflow:hidden then clips any excess cards. */
    min-height: 0;
    overflow: hidden;
    padding: 0.9rem;
    /* containing block for the step-walk progress marker overlay; positioning
       a static element is layout-neutral (geometry/measurement unchanged) */
    position: relative;
}

/* Step-walk progress marker: slim right-edge track + thumb showing how far
   down an overflowing page the kiosk has walked. Pure overlay - absolutely
   positioned, pointer-events none, zero layout/measurement impact. */
#kiosk-walk-progress {
    position: absolute;
    top: 0.9rem;
    bottom: 0.9rem;
    right: 4px;
    width: 5px;
    border-radius: 3px;
    background: var(--k-border);
    opacity: 0.55;
    pointer-events: none;
    z-index: 5;
}

#kiosk-walk-progress-thumb {
    position: absolute;
    left: 0;
    width: 100%;
    border-radius: 3px;
    background: var(--k-text-muted);
    transition: top 0.6s ease-in-out, height 0.2s ease;
}

/* pause/play: inline SVG icons (never emoji-rendered like the old unicode
   glyphs were on iOS); currentColor follows the button's text colour */
.kiosk-pause-icon,
.kiosk-play-icon {
    display: inline-flex;
}

.kiosk-pause-icon svg,
.kiosk-play-icon svg {
    display: block;
}

.kiosk-cards {
    display: grid;
    gap: 0.9rem;
    align-items: start;
    /* crossfade when flipping pages (see kiosk-cards-fading); the viewport
       already pads symmetrically and the JS keeps an 8px safety gap, so no
       extra bottom margin is needed here. transform is the overflow step-walk
       slide (paint-only - never affects layout/measurement; the JS resets it
       to identity before every rebuild/measure). */
    transition: opacity 0.26s ease, transform 0.6s ease-in-out;
    /* ONE persistent compositing layer for this container. The walk toggles
       inline transforms and the crossfade animates opacity; without this some
       browsers create/destroy the layer around every flip and leave STALE
       PAINTED GHOSTS of hidden cards (page 2 showing page 1 leftovers until a
       tab switch forces a repaint). A stable layer is invalidated correctly
       whenever its content changes. */
    will-change: transform, opacity;
}

.kiosk-cards.kiosk-cards-fading {
    opacity: 0;
}

.kiosk-card {
    background: var(--k-surface);
    border: 1px solid var(--k-border);
    border-radius: 8px;
    overflow: hidden;
    box-shadow: var(--k-shadow);
}

.kiosk-card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: 0.5rem 0.9rem;
    background: var(--k-head-bg);
    color: var(--k-head-text);
}

.kiosk-card-title {
    font-size: 1rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.kiosk-card-count {
    font-size: 0.75rem;
    color: var(--k-head-sub);
    white-space: nowrap;
    margin-left: 0.75rem;
}

/* Keep overflow-x: auto (unchanged layout/measurement behavior - the vertical
   sizing that the pagination footer depends on must stay exactly as-is). The JS
   sizes each card to its real content width, so any horizontal overflow is only
   a sub-pixel of column rounding; we just HIDE the scrollbar chrome so there's no
   grey strip. This is visual-only - it does not change the element's overflow
   mode, so it can't affect card heights or the footer's reserved space. */
.kiosk-table-wrap {
    width: 100%;
    overflow-x: auto;
    scrollbar-width: none;      /* Firefox */
    -ms-overflow-style: none;   /* old Edge */
}

.kiosk-table-wrap::-webkit-scrollbar {
    display: none;              /* Safari / Chrome */
    width: 0;
    height: 0;
}

.kiosk-table {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}

.kiosk-table thead th {
    padding: 0.28rem 0.6rem;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--k-text-muted);
    border-bottom: 2px solid var(--k-border);
    background: var(--k-row-alt);
    text-align: left;
    white-space: nowrap;
}

.kiosk-table tbody td {
    padding: 0.3rem 0.6rem;
    font-size: 0.95rem;
    border-bottom: 1px solid var(--k-border-soft);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 16rem;
}

.kiosk-table tbody tr:last-child td {
    border-bottom: none;
}

.kiosk-table tbody tr:nth-child(even) {
    background: var(--k-row-alt);
}

/* ---------------- mobile: one column, shrink to fit -------------------- */
/* Cards are always a single full-width column and the type/spacing shrink so a
   card fits the narrow screen without horizontal scroll. The !important beats
   the inline grid-template-columns the JS sets for desktop. */
@media (max-width: 768px) {
    /* topbar: two condensed rows - row 1 = event name + updated/fullscreen,
       row 2 = kiosk title + scope. Stops the centre block colliding with the
       right-hand "Updated" text on narrow screens. */
    .kiosk-topbar {
        flex-wrap: wrap;
        padding: 0.4rem 0.75rem;
        row-gap: 0.1rem;
    }
    .kiosk-topbar-left {
        order: 1;
        flex: 1 1 0;
    }
    .kiosk-topbar-right {
        order: 2;
        flex: 0 0 auto;
    }
    .kiosk-topbar-center {
        order: 3;
        flex: 1 1 100%;
        display: flex;
        align-items: baseline;
        gap: 0.5rem;
        padding: 0;
        text-align: left;
        min-width: 0;
    }
    .kiosk-event-name {
        font-size: 0.95rem;
    }
    .kiosk-title {
        font-size: 0.9rem;
        letter-spacing: 0.05em;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .kiosk-scope {
        font-size: 0.72rem;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .kiosk-updated {
        font-size: 0.72rem;
    }
    .kiosk-cards {
        grid-template-columns: 1fr !important;
        gap: 0.6rem;
    }
    .kiosk-cards-viewport {
        padding: 0.5rem;
    }
    /* a full-width banner would run its logos into the screen edge; inset it like the cards */
    .kiosk-banner {
        padding: 0 0.5rem;
    }
    .kiosk-card-head {
        padding: 0.4rem 0.6rem;
    }
    .kiosk-card-title {
        font-size: 0.85rem;
    }
    .kiosk-card-count {
        font-size: 0.62rem;
    }
    .kiosk-table thead th {
        padding: 0.2rem 0.4rem;
        font-size: 0.6rem;
        letter-spacing: 0.04em;
    }
    .kiosk-table tbody td {
        padding: 0.22rem 0.4rem;
        font-size: 0.8rem;
        max-width: 42vw;
    }
    td.kiosk-col-pos {
        font-size: 0.85rem;
    }
    .kiosk-col-pos,
    .kiosk-col-vehicle_num {
        width: 2.4rem;
    }
}

.kiosk-col-pos,
.kiosk-col-vehicle_num {
    text-align: center !important;
    width: 3.2rem;
}

.kiosk-col-overall_result,
.kiosk-col-gap_to_leader,
.kiosk-col-penalty_total,
.kiosk-col-start,
.kiosk-col-finish {
    text-align: right !important;
    font-weight: 600;
}

td.kiosk-col-pos {
    font-weight: 800;
    font-size: 1rem;
}

td.kiosk-col-vehicle_num {
    font-weight: 700;
    color: var(--k-bib);
}

td.kiosk-col-gap_to_leader {
    color: var(--k-text-muted);
    font-weight: 500;
}

td.kiosk-col-penalty_total {
    color: var(--k-danger);
}

td.kiosk-col-status {
    color: var(--k-danger);
    font-weight: 700;
}

.kiosk-row-p1 td.kiosk-col-pos { color: #b8860b; }
.kiosk-row-p2 td.kiosk-col-pos { color: #6c757d; }
.kiosk-row-p3 td.kiosk-col-pos { color: #a05a2c; }

.kiosk-row-p1 td:first-child {
    box-shadow: inset 3px 0 0 #b8860b;
}

.kiosk-no-rows {
    text-align: center;
    color: var(--k-text-muted);
    font-style: italic;
    padding: 0.8rem !important;
}

.kiosk-card-compact .kiosk-table tbody td {
    padding: 0.14rem 0.5rem;
    font-size: 0.8rem;
}

.kiosk-card-compact .kiosk-table thead th {
    padding: 0.18rem 0.5rem;
    font-size: 0.62rem;
}

.kiosk-card-compact .kiosk-card-head {
    padding: 0.3rem 0.7rem;
}

/* ---------------- footer pager ----------------------------------------- */
/* FIXED height: the pager's height is constant by design (ring + max 4 class
   rows, extra classes wrap into more columns, overflow hidden). The JS always
   reserves this space while measuring pages, so showing/hiding the pager can
   never change the card area mid-measure - the root cause of the old cutoffs. */
.kiosk-footer {
    position: relative; /* anchors the thin swipe bar (.kiosk-pager-bar) */
    flex: 0 0 auto;
    height: 5.4rem;
    background: var(--k-surface);
    border-top: 1px solid var(--k-border);
    padding: 0.5rem 1rem;
    overflow: hidden;
    /* pager fills the width; pause/play button sits on the far right */
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

/* The pager swipes sideways (touch / trackpad / wheel, see bindPagerScroll)
   with the scrollbar chrome hidden: the thin bar below shows the position
   instead. Vertical clipping stays exactly as before (overflow-y hidden) and
   the footer keeps its fixed height, so page measurement is unaffected. */
.kiosk-pager {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: flex-start;
    gap: 1.75rem;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-behavior: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
}

.kiosk-pager::-webkit-scrollbar {
    display: none;
}

/* thin bar on the footer's top edge: the part of the class list on screen */
.kiosk-pager-bar {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    pointer-events: none;
}

.kiosk-pager-bar-thumb {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 0;
    background: var(--k-accent);
    border-radius: 0 0 2px 2px;
}

/* pause / resume rotation button (footer far right) */
.kiosk-pause-btn {
    flex: 0 0 auto;
    width: 2.6rem;
    height: 2.6rem;
    border-radius: 50%;
    border: 1px solid var(--k-border);
    background: var(--k-surface);
    color: var(--k-text-muted);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
}

.kiosk-pause-btn:hover {
    color: var(--k-text);
    border-color: var(--k-accent);
}

.kiosk-pager-item {
    flex: 0 0 auto;
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.15rem 0.35rem;
    border-radius: 6px;
    cursor: pointer;
    opacity: 0.5;
    transition: opacity 0.4s ease, background 0.4s ease;
}

.kiosk-pager-item.passed {
    opacity: 0.75;
}

.kiosk-pager-item.active {
    opacity: 1;
    background: var(--k-row-alt);
}

.kiosk-pager-ring {
    position: relative;
    width: 2.4rem;
    height: 2.4rem;
    flex: 0 0 auto;
}

.kiosk-pager-ring svg {
    width: 100%;
    height: 100%;
    transform: rotate(-90deg);
}

.kiosk-ring-bg {
    fill: none;
    stroke: var(--k-border);
    stroke-width: 3;
}

.kiosk-ring-fill {
    fill: none;
    stroke: var(--k-accent);
    stroke-width: 3;
    stroke-linecap: round;
    transition: stroke-dashoffset 0.12s linear;
}

.kiosk-pager-num {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--k-text);
}

/* class list beside a ring: columns of up to CLASSES_PER_COLUMN rows */
.kiosk-pager-classes {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(6rem, 11rem);
    column-gap: 0.9rem;
    row-gap: 0.05rem;
    align-content: start;
}

.kiosk-pager-class {
    font-size: 0.72rem;
    line-height: 1.25;
    color: var(--k-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 11rem;
}

.kiosk-pager-class-num {
    display: inline-block;
    min-width: 1.1rem;
    color: var(--k-accent);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.kiosk-pager-item.active .kiosk-pager-class {
    color: var(--k-text);
    font-weight: 600;
}

/* ---------------- admin config ----------------------------------------- */
.kiosk-config-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(33, 37, 41, 0.55);
    z-index: 1050;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem 5vw;
}

.kiosk-config-dialog {
    width: 900px;
    max-width: 100%;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    background: var(--k-surface);
    color: var(--k-text);
    border: 1px solid var(--k-border);
    border-radius: 8px;
    overflow: hidden;
    margin: auto;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
}

.kiosk-config-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.7rem 1.5rem;
    background: var(--k-head-bg);
    color: var(--k-head-text);
    font-weight: 700;
}

.kiosk-config-head .btn {
    color: var(--k-head-text);
    border-color: var(--k-head-sub);
}

.kiosk-config-body {
    padding: 1.25rem 1.75rem;
    overflow-y: auto;
}

.kiosk-config-body label {
    color: var(--k-text-muted);
    font-size: 0.85rem;
}

.kiosk-config-hint {
    font-weight: 400;
    font-style: italic;
}

.kiosk-config-body .form-check-label {
    color: var(--k-text);
}

/* Section separation inside the config dialog: a subtle inset divider line plus
   a small muted section heading, so each group of fields reads as its own unit.
   Colours come from the theme variables, so dark mode adapts automatically. */
.kiosk-config-section-divider {
    height: 1px;
    background: var(--k-border);
    opacity: 0.65;
    margin: 1.4rem 0.75rem 1.15rem;
}

.kiosk-config-section-title {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--k-text-muted);
    margin: 0 0 0.7rem;
}

.kiosk-config-body .form-control {
    background: var(--k-bg);
    color: var(--k-text);
    border-color: var(--k-border);
}

.kiosk-config-columns-wrap {
    margin-top: 0.5rem;
}

.kiosk-config-columns-table {
    color: var(--k-text);
    margin-bottom: 0;
}

.kiosk-config-columns-table th,
.kiosk-config-columns-table td {
    border-color: var(--k-border-soft);
    vertical-align: middle;
}

.kiosk-config-order-cell {
    white-space: nowrap;
}

.kiosk-config-column-label {
    min-width: 8rem;
    max-width: 14rem;
    display: inline-block;
}

.kiosk-config-feedback {
    min-height: 1.4rem;
    margin-top: 0.5rem;
    font-size: 0.85rem;
    color: var(--k-text-muted);
}

.kiosk-config-foot {
    padding: 0.7rem 1.75rem;
    border-top: 1px solid var(--k-border);
    display: flex;
    justify-content: flex-end;
}

.kiosk-config-foot .btn {
    margin-left: 0.5rem;
}
