*, *:before, *:after { box-sizing: border-box; }

/* Times New Roman carries no CJK glyphs, so Korean/Chinese/Japanese park names
   drop into the OS serif fallback and read heavier than everything around them.
   Re-declaring the family for just those ranges routes them to the system
   sans-serif; every other character still comes from the real Times.
   Chrome resolves local() against PostScript names, not family names, so each
   face lists the PostScript name first and the family name after it for the
   browsers that want that instead. */
@font-face {
    font-family: 'Times New Roman';
    src: local('AppleSDGothicNeo-Regular'), local('Apple SD Gothic Neo'),
         local('MalgunGothic'), local('Malgun Gothic'),
         local('NotoSansKR-Regular'), local('Noto Sans KR'),
         local('NotoSansCJKkr-Regular'), local('Noto Sans CJK KR');
    unicode-range: U+1100-11FF, U+3130-318F, U+A960-A97F, U+AC00-D7FF;
}
@font-face {
    font-family: 'Times New Roman';
    src: local('HiraginoSans-W3'), local('Hiragino Sans'),
         local('HiraKakuProN-W3'), local('Hiragino Kaku Gothic ProN'),
         local('YuGothicUI-Regular'), local('Yu Gothic UI'),
         local('NotoSansJP-Regular'), local('Noto Sans JP'),
         local('NotoSansCJKjp-Regular'), local('Noto Sans CJK JP');
    unicode-range: U+3040-30FF, U+31F0-31FF;
}
@font-face {
    font-family: 'Times New Roman';
    src: local('PingFangSC-Regular'), local('PingFang SC'),
         local('MicrosoftYaHei'), local('Microsoft YaHei'),
         local('NotoSansSC-Regular'), local('Noto Sans SC'),
         local('NotoSansCJKsc-Regular'), local('Noto Sans CJK SC'),
         local('HiraginoSans-W3'), local('Hiragino Sans');
    unicode-range: U+2E80-2EFF, U+3000-303F, U+3400-4DBF, U+4E00-9FFF, U+F900-FAFF, U+FF00-FFEF;
}

html {
    background-color: #78b800;
}
body {
    margin: 0;
    padding: 0;
    color: #000;
    -webkit-font-smoothing: antialiased;
}

#stage {
    position: fixed;
    top: 0;
    left: 0;
    width: 100dvw;
    height: 100dvh;
}
/* each minute's video(s) live in a stacked full-screen layer, so the next
   clip can paint over the previous frame without a green gap */
#stage .layer {
    position: absolute;
    inset: 0;
    display: grid;
}
#stage .layer video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
#stage .layer.n2 { grid-template-columns: 1fr 1fr; }
#stage .layer.n3 { grid-template-columns: 1fr 1fr 1fr; }
#stage .layer.n4 { grid-template-columns: 1fr 1fr; grid-auto-rows: 1fr; }
@media (orientation: portrait) {
    #stage .layer.n2 { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
    #stage .layer.n3 { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr 1fr; }
}

/* Shown while a clip is still loading. Fades in on a delay so an ordinary
   quick swap never flashes it — you only see it when something is actually
   taking a while, instead of staring at the bare green background. */
#stage-loading {
    position: fixed;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    z-index: 90;
    border: 1px solid #000;
    border-radius: 6px;
    padding: 2px 8px;
    text-align: center;
    background-color: #78b800;
    color: #000;
    font-family: 'Times New Roman', Times, serif;
    font-size: 22px;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
}
body.video-loading #stage-loading {
    visibility: visible;
    animation: stage-loading-in 0.25s ease-out 0.9s forwards;
}
@keyframes stage-loading-in { to { opacity: 1; } }

#time {
    position: fixed;
    display: flex;
    justify-content: center;
    align-items: center;
    top: 0;
    right: 0;
    z-index: 100;
    margin: 10px;
    border: 1px solid #000;
    border-radius: 6px;
    padding: 2px 8px;
    color: #000;
    background-color: #78b800;
    font-size: 28px;
    font-family: 'Times New Roman', Times, serif;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
    text-decoration: none;
}

/* 24-hour timeline along the bottom. Sits above the control bars so its
   hover preview can pop over them. */
#timeline {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: 20px;
    background-color: rgba(0, 32, 2, 0.45);
    z-index: 1100;
    cursor: pointer;
}
.tl-tick {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 3px;
    transform: translateX(-50%);
    background-color: #78b800;
}
/* the black playhead marker (.tl-play) is the indicator; the underlying
   tick needs no extra highlight */
/* wall-clock current time: plain yellow line, no label */
.tl-now {
    position: absolute;
    top: -4px;
    bottom: 0;
    width: 3px;
    transform: translateX(-50%);
    background-color: #ffd400;
    pointer-events: none;
    z-index: 2;
}
/* playhead: blue line with a labelled tag, over the park being played */
.tl-play {
    position: absolute;
    top: -6px;
    bottom: 0;
    width: 3px;
    transform: translateX(-50%);
    background-color: #1565ff;
    pointer-events: none;
    z-index: 3;
}
.tl-play-label {
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    margin-bottom: 4px;
    padding: 1px 6px;
    border: 1px solid #000;
    border-radius: 4px;
    color: #000;
    background-color: #78b800;
    font-family: 'Times New Roman', Times, serif;
    font-size: 13px;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* Netflix-style hover preview */
.tl-preview {
    position: absolute;
    bottom: 100%;
    margin-bottom: 8px;
    transform: translateX(-50%);
    width: 180px;
    background-color: #16330a;
    border: 1px solid #000;
    overflow: hidden;
    pointer-events: none;
    opacity: 0;
    transition: opacity .1s;
    z-index: 3;
}
.tl-preview.show {
    opacity: 1;
}
.tl-preview img {
    display: block;
    width: 100%;
    height: 101px;
    object-fit: cover;
    background-color: #16330a;
}
.tl-preview.empty {
    background-color: #78b800;
    border-color: #000;
}
.tl-preview-cap {
    padding: 4px 6px;
    color: #000;
    background-color: #78b800;
    font-family: 'Times New Roman', Times, serif;
    font-size: 12px;
    line-height: 15px;
    font-variant-numeric: tabular-nums;
}
@media (max-width: 700px) {
    .tl-preview { display: none; }
    /* the playhead's time pill lands on top of the bottom-left controls on a
       narrow screen, and the corner clock already says the same thing */
    .tl-play-label { display: none; }
}

/* "info" button (bottom-right) and its big centered overlay */
#corner-buttons {
    position: fixed;
    bottom: 32px;
    right: 12px;
    z-index: 1000;
    display: flex;
    gap: 8px;
}
/* in full screen the timeline is gone, so drop the button to sit an even
   12px from the bottom, matching its inset from the side */
body.ui-hidden #corner-buttons {
    bottom: 12px;
}
#info-toggle,
#ui-toggle {
    padding: 3px 9px;
    color: #000;
    background-color: #78b800;
    border: 1px solid #000;
    border-radius: 6px;
    font-family: 'Times New Roman', Times, serif;
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
}

/* Full screen takes away everything that says what you're looking at, so the
   clip's own provenance — when, where, who filmed it — goes in the opposite
   bottom corner from the toggle that brought you here. Same green pill as the
   buttons: bare text over an arbitrary frame of video isn't readable. */
#fs-credit {
    display: none;
    position: fixed;
    bottom: 12px;
    left: 12px;
    z-index: 1000;
    /* stops short of the "timeline" button in the other corner */
    max-width: min(700px, calc(100vw - 160px));
    padding: 3px 9px;
    color: #000;
    background-color: #78b800;
    border: 1px solid #000;
    /* square, unlike the buttons: rounded ends on a line that slides through
       them make the text look like it's being clipped by mistake */
    border-radius: 0;
    font-family: 'Times New Roman', Times, serif;
    font-size: 16px;
    line-height: 1.25;
    /* one line always: a long park name would otherwise stack two or three
       deep in the corner. Anything past the width scrolls instead (below). */
    white-space: nowrap;
    overflow: hidden;
}
body.ui-hidden #fs-credit {
    display: block;
}
/* .. except when there's nothing to credit */
#fs-credit[hidden] {
    display: none !important;
}
/* Marquee, for the lines that don't fit. The run holds two copies of the text
   with a gap between them and slides left by exactly one copy-plus-gap, so the
   loop point lands the second copy where the first started and the line reads
   as continuous rather than snapping back. Both the distance and the duration
   are measured per line in player.js — a fixed duration would crawl through a
   short overflow and race through a long one. */
#fs-credit .fs-credit-run {
    display: inline-block;
}
/* the same drawn circle the browse list separates things with (see .b-dot):
   a box can be centred exactly where the "·" glyph can't, and the character
   itself is pushed out of view rather than dropped, so the line still reads
   properly if it's selected or copied */
#fs-credit .fs-credit-dot {
    display: inline-block;
    width: 0.52em;
    height: 0.52em;
    border-radius: 50%;
    background-color: currentColor;
    vertical-align: middle;
    position: relative;
    top: calc(-0.14em + 1px);
    text-indent: -9em;
    overflow: hidden;
}
#fs-credit.scroll .fs-credit-run {
    animation: fs-credit-scroll var(--fs-credit-dur) linear infinite;
}
/* hold it wherever it is while the pointer is on it, so a line you're halfway
   through reading doesn't slide out from under you */
#fs-credit.scroll:hover .fs-credit-run {
    animation-play-state: paused;
}
/* The rest at the top of each lap is built into the easing rather than the
   keyframes: a keyframe percentage can't be a variable, and the hold has to
   be the same few seconds whether the line takes 20s to cross or 50s. The
   easing holds the run at 0 and then plays out the travel at constant speed,
   so `linear()` is what makes both the pause and the even scroll possible. */
@supports (animation-timing-function: linear(0 0%, 1 100%)) {
    #fs-credit.scroll .fs-credit-run {
        animation-timing-function: var(--fs-credit-ease, linear);
    }
}
@keyframes fs-credit-scroll {
    from { transform: translateX(0); }
    to { transform: translateX(var(--fs-credit-shift)); }
}
/* no crawling text for anyone who's asked motion to stop; the line just sits
   there and the tail is clipped */
@media (prefers-reduced-motion: reduce) {
    #fs-credit.scroll .fs-credit-run {
        animation: none;
    }
}
@media (max-width: 700px) {
    #fs-credit {
        max-width: calc(100vw - 116px);
        font-size: 13px;
    }
}

/* "hide ui" hides all chrome so only the video shows; the ui toggle
   itself stays put so you can bring everything back, and the corner clock
   stays too — the minute and the seconds counting through it are part of
   watching, not chrome */
body.ui-hidden #controls,
body.ui-hidden #timeline,
body.ui-hidden #keep-alive-button,
body.ui-hidden #info-toggle,
body.ui-hidden #info {
    display: none !important;
}
#info {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: none;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    padding: 72px 24px;
    color: #78b800;
    -webkit-text-stroke: 4px #000;
    text-stroke: 4px #000;
    paint-order: stroke fill;
    font-family: 'Times New Roman', Times, serif;
    pointer-events: none;
    overflow: hidden;
}
#info.show {
    display: flex;
}
/* wrapper we can scale down so the text never overflows the viewport */
#info .info-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 48px;
    transform-origin: center center;
}
#info .info-park {
    max-width: 1000px;
}
#info .info-name {
    font-size: clamp(56px, 8.5vw, 120px);
    line-height: 1.12;
    font-weight: bold;
    font-variant-numeric: tabular-nums;
}
#info .info-by {
    font-size: 28px;
    line-height: 1.12;
    font-weight: bold;
    font-variant-numeric: tabular-nums;
    margin-top: 12px;
    -webkit-text-stroke: 3px #000;
    text-stroke: 3px #000;
}
#info .info-by a {
    color: #78b800;
    text-decoration: none;
    pointer-events: auto;
}

#loading {
    font-family: 'Times New Roman', Times, serif;
    font-size: 16px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
}
/* one green pill holding all the bottom controls, like the corner
   clock but smaller */
#controls {
    position: fixed;
    bottom: 32px;
    left: 12px;
    z-index: 1000;
    display: flex;
    flex-flow: row nowrap;
    align-items: center;
    gap: 9px;
    padding: 3px 9px;
    background-color: #78b800;
    border: 1px solid #000;
    border-radius: 6px;
    font-family: 'Times New Roman', Times, serif;
}
#controls button {
    cursor: pointer;
}
/* keeps the mute + ? icons together (side by side) even when the rest of
   the controls stack vertically on mobile */
#controls .icon-row {
    display: flex;
    align-items: center;
    gap: 9px;
}

/* black silhouette icons (recolored via mask on ::before, ignoring the
   svg's own fill) */
#controls button#mute,
#controls a#open-instructions,
#controls button#random-toggle {
    position: relative;
    border: 0;
    padding: 0;
    background: transparent;
    outline: none;
    cursor: pointer;
}
#controls button#mute::before,
#controls a#open-instructions::before,
#controls button#random-toggle::before {
    content: '';
    position: absolute;
    inset: 0;
    background: #000;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: contain;
    mask-size: contain;
}
/* speaker icon: always the cone + waves so it stays centered; a diagonal
   slash marks the muted state */
#controls button#mute {
    width: 20px;
    height: 18px;
}
#controls button#mute::before {
    -webkit-mask-image: url('../images/sound-on.svg');
    mask-image: url('../images/sound-on.svg');
}
#controls button#mute::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    width: 105%;
    height: 1px;
    background: #000;
    transform: translate(-50%, -50%) rotate(45deg);
}
#controls button#mute.sound-on::after {
    display: none;
}
/* hand-drawn question mark: keep its tall 1:2 proportions */
#controls a#open-instructions {
    display: block;
    width: 9px;
    height: 18px;
}
#controls a#open-instructions::before {
    -webkit-mask-image: url('../images/question-mark.svg');
    mask-image: url('../images/question-mark.svg');
}
/* Playback order, as a single icon that swaps rather than a menu: the clock
   means playing in order (timeline or live), the spiral means random. The
   box stays 20x18 for both so the bar doesn't shift when it flips. */
#controls button#random-toggle {
    display: block;
    width: 20px;
    height: 18px;
}
#controls button#random-toggle::before {
    -webkit-mask-image: url('../images/clock.svg');
    mask-image: url('../images/clock.svg');
}
body.random-on #controls button#random-toggle::before {
    -webkit-mask-image: url('../images/spiral.svg');
    mask-image: url('../images/spiral.svg');
}
/* random has no minute worth showing in the corner, so the clock becomes a
   count of the park's own 60 seconds — a circle instead of the usual pill */
body.random-on #time {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    padding: 0;
    text-align: center;
}


#instructions {
    position: fixed;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
    color: #000;
    background-color: #78b800;
    z-index: 1000;
    overflow-y: auto;
    display: none;
}
/* on the "how to" page: no timeline, no hide-ui/info buttons, but keep
   the bottom-left nav visible on top of the overlay */
body.instructions-open #timeline,
body.instructions-open #corner-buttons,
body.instructions-open #info {
    display: none !important;
}
/* the about page is its own screen — its close button is the only chrome.
   !important because the player sets #controls' display inline. */
body.instructions-open #controls {
    display: none !important;
}
#instructions #inner {
    margin: 0 auto;
    font-family: 'Times New Roman', Times, serif;
    padding: 15px;
}
#instructions #inner img {
    width: 100%;
    max-width: 1200px;
    margin: 40px auto;
    display: block;
}
#instructions #inner ol, #instructions #inner p, #instructions #inner h2 {
    max-width: 700px;
    margin: 20px auto;
}
#instructions #inner a {
    color: #000;
}
/* centered Bell Kiosk credit at the end of the about page */
#instructions #inner .bell-kiosk-credit {
    text-align: center;
    margin-top: 60px;
}
#instructions #inner h2, #instructions #inner p, #instructions #inner li {
    font-size: 24px;
    line-height: 32px;
}
#instructions #inner h2 {
    font-weight: bold;
    margin-bottom: 0;
    margin-top: 60px;
}
#instructions #inner ol {
    padding: 0;
    padding-left: 24px;
}
#instructions #inner li {
    margin-bottom: 20px;
}
#instructions #inner img {
    width: 100%;
}
/* same bottom-left green pill as the minutes/parks close button */
#close-instructions {
    position: fixed;
    bottom: 12px;
    left: 12px;
    z-index: 2;
    padding: 5px 11px;
    background-color: #78b800;
    border: 1px solid #000;
    border-radius: 6px;
    color: #000;
    font-family: 'Times New Roman', Times, serif;
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
}




#controls a.nav-link, #controls button.nav-link, #controls button#live {
    display: flex;
    align-items: center;
    justify-content: center;
    width: max-content;
    font-family: inherit;
    font-size: 16px;
    line-height: 1;
    color: #000;
    background: transparent;
    border: 0;
    padding: 0;
    text-decoration: none;
    cursor: pointer;
    font-weight: normal;
}
/* "now" bolds while live mode is locked to the wall clock */
#controls button#live.active {
    font-weight: bold;
}

/* 24 hour clock page — empty minute screen */
#clock-empty {
    position: fixed;
    top: 0;
    left: 0;
    width: 100dvw;
    height: 100dvh;
    background-color: #78b800;
    color: #000;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    font-family: 'Times New Roman', Times, serif;
    padding: 20px;
    z-index: 10;
}
#clock-empty-time {
    font-size: clamp(80px, 18vw, 220px);
    line-height: 1;
    font-variant-numeric: tabular-nums;
    margin-bottom: 20px;
}
#clock-empty p,
#clock-empty .clock-empty-small {
    font-size: 24px;
    line-height: 32px;
    max-width: 700px;
    margin: 8px 0;
    opacity: 1;
}
/* the two links are the only things to click on this screen, so they don't
   need a rule under them to be found — the underline is kept for the hover */
#clock-empty a {
    color: #000;
    text-decoration: none;
}
#clock-empty a:hover,
#clock-empty a:focus-visible {
    text-decoration: underline;
}
@media (max-width: 700px) {
    #clock-empty p,
    #clock-empty .clock-empty-small {
        font-size: 18px;
        line-height: 24px;
    }
    /* stack the bottom-left nav vertically, each item its own pill */
    #controls {
        flex-flow: column nowrap;
        align-items: flex-start;
        gap: 5px;
        background: transparent;
        border: 0;
        padding: 0;
    }
    #controls a.nav-link,
    #controls button.nav-link,
    #controls button#live,
    #controls button#mute,
    #controls a#open-instructions,
    #controls button#random-toggle {
        display: flex;
        align-items: center;
        justify-content: center;
        background-color: #78b800;
        border: 1px solid #000;
        border-radius: 6px;
        padding: 5px 11px;
        width: auto;
        height: auto;
    }
    #controls button#mute::before,
    #controls a#open-instructions::before,
    #controls button#random-toggle::before {
        position: static;
        display: block;
    }
    #controls button#mute::before { width: 20px; height: 18px; }
    #controls a#open-instructions::before { width: 9px; height: 18px; }
    #controls button#random-toggle::before { width: 20px; height: 18px; }
    #controls button#mute::after { width: 24px; }
    #controls .icon-row { gap: 5px; }
}

/* Donation Slider Styles */
#fundraiser {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5);
    padding: 20px;
    z-index: 2000;
}
#fundraiser-inner {
    position: relative;
    max-width: 500px;
    margin: 0 auto;
    padding: 20px;
    background-color: #78b800;
    border: 1px solid #000;
}
#fundraiser-inner p {
    font-size: 20px;
    line-height: 24px;
}
#fundraiser-inner a {
    color: #000;
}
#fundraiser-inner p:first-child {
    margin-top: 0px;
}

.donation-slider-container {
    background: transparent;
    padding: 15px;
    border: 1px solid #000;
    border-radius: 8px;
    margin-top: 15px;
}

.slider-wrapper {
    display: flex;
    align-items: center;
    margin-bottom: 15px;
}

.donation-slider {
    flex-grow: 1;
    height: 5px;
    -webkit-appearance: none;
    appearance: none;
    background: #000;
    outline: none;
    border-radius: 5px;
}

.donation-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: #78b800;
    border: 1px solid #000;
    cursor: pointer;
}

.donation-slider::-moz-range-thumb {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: #78b800;
    border: 1px solid #000;
    cursor: pointer;
}

.donation-value {
    margin-left: 15px;
    font-weight: bold;
    min-width: 50px;
}

.donate-button {
    color: #000;
    border: none;
    padding: 10px 20px;
    border-radius: 5px;
    cursor: pointer;
    font-size: 18px;
    font-weight: normal;
    background-color: #78b800;
    width: 100%;
    border: 1px solid #000;
}

.donate-button:hover {
    background-color: #6aa300;
}

button#skip-fundraiser {
    position: absolute;
    top: 10px;
    right: 10px;
    cursor: pointer;
    font-size: 12px;
    color: #000;
}

#keep-alive-button {
    position: fixed;
    top: 10px;
    left: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: max-content;
    font-size: 16px;
    line-height: 1;
    color: #000;
    background-color: #78b800;
    border: 1px solid #000;
    padding: 3px 9px;
    border-radius: 6px;
    text-decoration: none;
    cursor: pointer;
    font-weight: normal;
    font-family: 'Times New Roman', Times, serif;
    z-index: 1000;
}


@media (max-width: 700px) {
    #instructions #inner h2, #instructions #inner p, #instructions #inner li {
        font-size: 20px;
        line-height: 27px;
    }
    #instructions #inner h2 {
        margin-top: 40px;
    }
    #instructions #inner {
        padding: 15px 15px 70px;
    }
}


/* Says which way playback is going when you flip the clock/spiral button,
   then fades. Same outlined treatment as the info overlay. */
#mode-flash {
    position: fixed;
    inset: 0;
    z-index: 1250;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 24px;
    text-align: center;
    color: #78b800;
    -webkit-text-stroke: 4px #000;
    text-stroke: 4px #000;
    paint-order: stroke fill;
    font-family: 'Times New Roman', Times, serif;
    font-size: clamp(38px, 7vw, 96px);
    font-weight: bold;
    line-height: 1.1;
    pointer-events: none;
    opacity: 0;
    transition: opacity .45s ease-out;
}
#mode-flash.show {
    opacity: 1;
    transition: none;
}

/* ---------------------------------------------------- browse (minutes/parks)

   A full-screen list over the player. Each entry is two lines — the thing
   you're picking on top, the detail under it — rather than one long run of
   text at mixed sizes, which was hard to parse once a park or city name got
   long (especially on a phone, where it wrapped mid-name). */
#browse {
    position: fixed;
    inset: 0;
    z-index: 1300;
    background-color: #78b800;
    color: #000;
    font-family: 'Times New Roman', Times, serif;
    -webkit-font-smoothing: antialiased;
    overflow: hidden;
}
#browse[hidden] {
    display: none;
}
#browse-scroll {
    height: 100%;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    /* no side padding: rows run the full width so their hover wash reaches
       both edges. The header and the rows carry their own insets. */
    padding: 70px 0 120px;
    text-align: center;
}
#browse h1,
#browse-count {
    padding: 0 28px;
}
#browse h1 {
    font-size: clamp(40px, 8vw, 96px);
    line-height: 1.05;
    margin: 0 0 10px;
    font-weight: normal;
}
#browse-count {
    font-size: clamp(15px, 2.6vw, 21px);
    margin: 0 0 56px;
}
/* top-right corner, same slot the parks country dropdown uses — the two are
   never shown at once */
#browse-filter {
    position: fixed;
    top: 12px;
    right: 12px;
    z-index: 2;
    margin: 0;
    padding: 5px 11px;
    background-color: #78b800;
    border: 1px solid #000;
    border-radius: 6px;
    color: #000;
    font-family: 'Times New Roman', Times, serif;
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
}
#browse-filter[hidden] {
    display: none;
}
#browse-country {
    position: fixed;
    top: 12px;
    right: 12px;
    z-index: 2;
    max-width: calc(100vw - 24px);
    margin: 0;
    padding: 5px 26px 5px 11px;
    background-color: #78b800;
    background-image:
        linear-gradient(45deg, transparent 50%, #000 50%),
        linear-gradient(135deg, #000 50%, transparent 50%);
    background-position: right 12px center, right 7px center;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
    background-color: #78b800;
    border: 1px solid #000;
    border-radius: 6px;
    color: #000;
    font-family: 'Times New Roman', Times, serif;
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}
#browse-country:focus,
#browse-country:focus-visible {
    outline: none;
}
#browse-country[hidden] {
    display: none;
}
#browse.hide-empty .b-row.b-empty {
    display: none;
}

/* full width, held off the viewport edges */
#browse-list {
    margin: 0 20px;
}

/* one entry: .b-main is the park name or the time, .b-sub the detail */
#browse .b-row {
    display: block;
    width: 100%;
    color: #000;
    background: transparent;
    border: 0;
    font-family: inherit;
    text-align: center;
    text-decoration: none;
    padding: 14px 28px;
    cursor: pointer;
}
/* .b-row sets display, which would beat the [hidden] UA rule */
#browse .b-row[hidden] {
    display: none;
}
/* A rule between minutes, so the list reads as one continuous run of the day
   rather than free-floating rows. Every minute row carries it on its top edge,
   the first included: hiding the empty minutes pulls whole rows out, and a
   top border is the version of this that survives that without leaving gaps
   (the leading line just closes the list off under the header). The parks
   list keeps its unruled two-line blocks. */
#browse .b-row.b-minute {
    border-top: 1px solid rgba(0, 0, 0, 0.25);
}
#browse .b-row.b-park {
    padding-top: 18px;
    padding-bottom: 18px;
}
#browse .b-main {
    display: block;
    font-size: clamp(28px, 5vw, 46px);
    line-height: 1.15;
    text-wrap: balance;
}
#browse .b-sub {
    display: block;
    font-size: clamp(15px, 2.6vw, 20px);
    line-height: 1.3;
    margin-top: 6px;
    text-wrap: balance;
}
#browse .b-row:hover,
#browse .b-row:focus-visible {
    background-color: rgba(0, 0, 0, 0.08);
    border-radius: 3px;
    outline: none;
}
/* Drawn as a circle rather than typeset as "·": the glyph sits wherever the
   font puts it, a box can be centred exactly. The character itself is pushed
   out of view by the text-indent. */
#browse .b-sub .b-dot {
    display: inline-block;
    width: 0.52em;
    height: 0.52em;
    margin: 0 0.42em;
    border-radius: 50%;
    background-color: currentColor;
    vertical-align: middle;
    position: relative;
    top: calc(-0.14em + 1px); /* "middle" sits it low against the lowercase */
    text-indent: -9em;
    overflow: hidden;
}
#browse .b-by {
    display: block;
    font-size: clamp(13px, 1.9vw, 16px);
    line-height: 1.3;
    margin-top: 5px;
    text-wrap: balance;
}

/* Empty minutes stay one dim compact line. The contrast between those runs
   and the taller two-line entries is what gives the list its rhythm — you
   can see where the parks are without reading every row. */
#browse .b-row.b-empty {
    color: rgba(0, 0, 0, 0.34);
    padding-top: 5px;
    padding-bottom: 5px;
}
#browse .b-row.b-empty .b-main {
    font-size: clamp(17px, 2.8vw, 24px);
    font-variant-numeric: tabular-nums;
}
/* an empty minute darkens to full strength on hover, so it reads as pickable */
#browse .b-row.b-empty:hover,
#browse .b-row.b-empty:focus-visible {
    color: #000;
}
#browse .b-row.b-minute .b-main {
    font-variant-numeric: tabular-nums;
}
/* the minute you came from, via the corner clock */
#browse .b-row.b-here {
    outline: 2px solid #000;
    outline-offset: -2px;
    border-radius: 6px;
}

#browse-close {
    position: fixed;
    bottom: 12px;
    left: 12px;
    z-index: 2;
    padding: 5px 11px;
    background-color: #78b800;
    border: 1px solid #000;
    border-radius: 6px;
    color: #000;
    font-family: 'Times New Roman', Times, serif;
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
}

@media (max-width: 700px) {
    #browse-scroll {
        padding: 50px 0 110px;
    }
    #browse h1,
    #browse-count {
        padding: 0 20px;
    }
    #browse-list {
        margin: 0 12px;
    }
    #browse-count {
        margin-bottom: 36px;
    }
    #browse .b-row {
        padding-left: 20px;
        padding-right: 20px;
        padding-top: 12px;
        padding-bottom: 12px;
    }
    #browse .b-row.b-empty {
        padding-top: 5px;
        padding-bottom: 5px;
    }
}


