* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html, body {
    width: 100%;
    height: 100%;
    overflow: hidden;
    background: #f4f5f9;
    color: #1a1f2e;
    font-family: 'Poppins', Arial, sans-serif;
}

.board {
    width: 100vw;
    height: 100vh;
    display: flex;
    flex-direction: column;
    padding: 22px 30px 16px;
}

/* ================= HEADER ================= */

.board-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding-bottom: 16px;
    border-bottom: 3px solid #b3253a;
    flex-shrink: 0;
}

.board-brand {
    display: flex;
    align-items: center;
    gap: 16px;
}

.board-logo {
    width: 58px;
    height: 58px;
    object-fit: contain;
    background: #fff;
    border-radius: 8px;
    padding: 4px;
    border: 1px solid #e2e5ee;
}

.board-title {
    font-family: 'Montserrat', sans-serif;
    font-weight: 800;
    font-size: 30px;
    letter-spacing: 0.3px;
    color: #12213f;
}

.board-subtitle {
    font-size: 15px;
    color: #6b7280;
    margin-top: 2px;
}

.board-clock-wrap {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
}

.board-date {
    font-size: 16px;
    font-weight: 600;
    color: #6b7280;
    letter-spacing: 0.2px;
}

.board-clock {
    font-family: 'Montserrat', sans-serif;
    font-weight: 700;
    font-size: 40px;
    font-variant-numeric: tabular-nums;
    letter-spacing: 1px;
    color: #12213f;
    line-height: 1;
}

/* ================= NOTICE MARQUEE ================= */
/* Same live notices shown on the ZSB portal homepage (fetched from the same
   /api/content call the ads panel already uses — see loadAds() in
   display.js), scrolling here too so kiosk viewers see them without
   needing to visit the portal separately. */

.notice-marquee {
    margin-top: 14px;
    background: #12213f;
    color: #fff;
    overflow: hidden;
    position: relative;
    display: flex;
    align-items: stretch;
    border-radius: 10px;
    flex-shrink: 0;
}

.notice-marquee[hidden] {
    display: none;
}

.notice-tag {
    background: #b3253a;
    color: #fff;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    padding: 0 13px;
    display: flex;
    align-items: center;
    flex: none;
    z-index: 2;
}

.notice-viewport {
    overflow: hidden;
    flex: 1;
    padding: 9px 0;
}

.notice-track {
    display: flex;
    width: max-content;
    white-space: nowrap;
    animation: noticeScroll var(--notice-speed, 24s) linear infinite;
}

.notice-marquee:hover .notice-track {
    animation-play-state: paused;
}

.notice-item {
    font-size: 14px;
    font-weight: 600;
    padding: 0 22px;
    color: #eaf2fb;
}

.notice-item b {
    color: #ffd7dd;
    font-weight: 800;
}

.notice-sep {
    color: #7fb3ea;
    font-weight: 800;
}

@keyframes noticeScroll {
    from { transform: translateX(0); }
    to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
    .notice-track { animation: none; }
}

/* ================= OVERRIDE BANNER ================= */

.override-banner {
    display: none;
    margin-top: 14px;
    padding: 8px 16px;
    background: #fdf0da;
    border: 1px solid #f0cf8f;
    border-radius: 10px;
    color: #8a5a0e;
    font-weight: 600;
    font-size: 15px;
    text-align: center;
    flex-shrink: 0;
}

.override-banner.show {
    display: block;
}

/* ================= GRID + ADS PANEL ROW ================= */

.board-main {
    flex: 1;
    min-height: 0;
    margin-top: 16px;
    display: flex;
    gap: 16px;
}

.board-grid {
    flex: 1;
    min-width: 0;
    min-height: 0;
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 14px;
}

.counter-column {
    background: #ffffff;
    border: 1px solid #e2e5ee;
    border-radius: 14px;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(18, 33, 63, 0.06);
}

.counter-column.closed {
    background: #fdf4f4;
    border-color: #f0d6d6;
}

.counter-header {
    flex-shrink: 0;
    text-align: center;
    padding: 14px 8px 12px;
    font-family: 'Montserrat', sans-serif;
    font-weight: 700;
    font-size: 20px;
    color: #12213f;
    background: #eef1fa;
    border-bottom: 1px solid #e2e5ee;
    letter-spacing: 0.5px;
}

.counter-column.closed .counter-header {
    background: #f7e3e3;
    color: #a3313e;
}

.counter-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 10px 8px;
    overflow: hidden;
}

.token-row {
    flex-shrink: 0;
    background: #f7f8fc;
    border-left: 5px solid #d4af37;
    border-radius: 8px;
    padding: 8px 10px;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.token-row:first-child {
    border-left-color: #2f9e57;
    background: #eef8f0;
}

.token-number {
    font-family: 'Montserrat', sans-serif;
    font-weight: 800;
    line-height: 1.05;
    color: #12213f;
}

.token-rank {
    color: #7a8199;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.token-name {
    color: #2c3348;
    font-weight: 500;
    line-height: 1.2;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: normal;
    word-break: break-word;
}

.counter-empty,
.counter-closed-label {
    margin: auto;
    text-align: center;
    color: #9aa0b4;
    font-size: 15px;
    padding: 0 10px;
}

.counter-closed-label {
    color: #a3313e;
    font-weight: 600;
}

.counter-more {
    flex-shrink: 0;
    text-align: center;
    background: #eef1fa;
    border: 1px dashed #c7cede;
    border-radius: 8px;
    padding: 10px;
    font-size: 13px;
    font-weight: 700;
    color: #5f6b8a;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ================= ADS PANEL ================= */

.ads-panel {
    flex-shrink: 0;
    width: 240px;
    background: #12213f;
    border-radius: 14px;
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    color: #eaf2fb;
    overflow: hidden;
}

.ads-panel[hidden] {
    display: none;
}

.ads-panel-label {
    flex-shrink: 0;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #9fb6d4;
}

.ads-panel-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 8px;
    overflow: hidden;
}

.ads-panel-poster {
    width: 100%;
    max-height: 42%;
    object-fit: contain;
    background: #fff;
    border-radius: 8px;
    flex-shrink: 0;
}

.ads-panel-name {
    flex-shrink: 0;
    font-family: 'Montserrat', sans-serif;
    font-weight: 800;
    font-size: 18px;
    color: #ffd7dd;
}

.ads-panel-desc {
    font-size: 13px;
    line-height: 1.4;
    color: #dbe6f5;
    overflow: hidden;
}

.ads-panel-qr {
    flex-shrink: 0;
    margin-top: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
}

.ads-panel-qr img {
    width: 90px;
    height: 90px;
    background: #fff;
    padding: 4px;
    border-radius: 8px;
}

.ads-panel-qr span {
    font-size: 11px;
    color: #9fb6d4;
    font-weight: 600;
}

/* density steps, applied by JS based on row count. Since the board now caps
   each counter at 3 rows, density-1 (<=4 rows) is the only step that ever
   actually applies — but its sizes still need to work both on a real kiosk
   screen (very wide, own viewport) and inside a narrower host-page iframe
   (e.g. embedded on the ZSB portal, where the host page's own layout can
   leave much less than a kiosk's width). vw-based clamps size the numbers
   off the iframe's own width so they use full kiosk-sized digits when
   there's room and shrink just enough to avoid wrapping when there isn't. */
.density-1 .token-number { font-size: clamp(22px, 2.2vw, 42px); }
.density-1 .token-rank { font-size: clamp(11px, 0.9vw, 15px); }
.density-1 .token-name { font-size: clamp(12px, 1.05vw, 18px); }

.density-2 .token-number { font-size: 30px; }
.density-2 .token-rank { font-size: 13px; }
.density-2 .token-name { font-size: 15px; }

.density-3 .token-number { font-size: 22px; }
.density-3 .token-rank { font-size: 11px; }
.density-3 .token-name { font-size: 13px; }

.density-4 .token-number { font-size: 17px; }
.density-4 .token-rank { font-size: 10px; }
.density-4 .token-name { font-size: 11px; }
.density-4 .token-row { padding: 5px 8px; }

/* ================= CONNECTION BANNER ================= */

.connection-banner {
    display: none;
    position: fixed;
    bottom: 18px;
    left: 50%;
    transform: translateX(-50%);
    background: #b3253a;
    color: #fff;
    font-weight: 600;
    font-size: 14px;
    padding: 8px 20px;
    border-radius: 20px;
}

.connection-banner.show {
    display: block;
}

/* Breakpoints are widths of THIS page's own viewport — whether that's a real
   screen (kiosk TV) or an <iframe> embedded elsewhere at a narrower width
   (e.g. the live board embedded on the public ZSB portal, where the host
   page's own layout can pin the iframe to ~870px wide even on a fairly
   wide screen). 7 columns need real room to stay legible — each one holds
   a 4-5 digit token number at a large font plus a name — so the fallback
   kicks in as soon as the iframe drops below 900px, not just on phones. */
@media (max-width: 900px) {
    /* The kiosk desktop layout crams every counter into exactly one
       screen's height with no scrolling — that only works because a TV
       kiosk has a fixed, known viewport. On a phone (or embedded on the
       ZSB portal, which already scrolls), forcing 7 counters into one
       screen leaves no room to show queued visitors and clips them
       instead. So on mobile the page is allowed to grow and scroll
       instead, and each counter shows at most 2 real entries plus a
       "+N more waiting" summary card (see display.js) sized to fit
       without needing to scroll inside the counter itself. */
    html, body {
        height: auto;
        overflow: visible;
    }

    .board {
        height: auto;
        min-height: 100vh;
    }

    /* Two competing widths (brand text vs. the clock) squeezed the
       headline into 2-3 broken lines. Stacking the date/time under the
       headline instead of beside it gives the title the full width. */
    .board-header {
        flex-direction: column;
        align-items: flex-start;
        gap: 10px;
    }

    .board-clock-wrap {
        align-items: flex-start;
    }

    .board-main {
        flex-direction: column;
    }

    .board-grid {
        grid-template-columns: repeat(4, 1fr);
        grid-auto-rows: auto;
    }

    .counter-body {
        flex: none;
        height: auto;
        overflow: visible;
    }

    /* Ads already have a dedicated section on the ZSB portal — showing
       them again inside the embedded queue view just eats phone screen
       space that the counters need. */
    .ads-panel {
        display: none;
    }
}

/* Most phones (portrait and small landscape) fall in here. 4 columns at
   this width leaves each one too narrow to be worth it — 2 wider columns
   read better and still only take 2 rows to show all 7 counters. */
@media (max-width: 700px) {
    .board-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}
