/* A net's live page (Pages/Public/Net.cshtml): the globe with the session's stations, the net's
   card, the list of who checked in and the bar that steps through the sessions. The look is
   aprsthursday's live page. It comes after site.css and map.css and uses their variables.

   Three layouts, all from the same markup:

   1. A phone, and anything up to 900 pixels: one column that scrolls. "Did my check-in get
      through?" first, then the globe from edge to edge at half the screen, the sessions, the
      net, the list. One finger on the globe scrolls the page (the map kit sees to that).
   2. A wide screen with a map (body.with-map): the globe fills the page and the cards lie on
      it, the question and the net on the left, the list on the right, the sessions under
      the middle. Nothing scrolls but the list and the left column.
   3. No station with a place (no body.with-map; the script takes the class off when the map
      cannot be drawn, too): an ordinary page, the list first, and after it one plain line
      that says there is no map.

   The script (wwwroot/js/public/live.js) sets body.with-map and body.past and nothing else
   about the look. */

/* ── One column: a phone ─────────────────────────────────────────────────── */
.live-main { width: min(1080px, 100% - 24px); margin: 0 auto; padding: 14px 0 40px; flex: 1; }
.live-page { display: flex; flex-direction: column; }
/* The left column of a wide screen is no box here: its cards take their own places in the page. */
.live-side { display: contents; }
.live-ask { order: 1; }
.live-map { order: 2; }
.live-pick { order: 3; }
.live-net { order: 4; }
.live-list { order: 5; }
/* What the controller wrote about the net (Pages/Public/_About.cshtml) comes last. */
.live-side > .card:not(.live-net):not(.live-ask) { order: 7; }
/* With no map the net comes straight after the question and the list straight after the
   sessions: the list first, and the one line that says no station has a place after it. A
   map that could not be drawn says so before the list, where it is seen. */
body.live:not(.with-map) .live-net { order: 2; }
body.live:not(.with-map) .live-map[data-state="missing"] { order: 4; }
body.live:not(.with-map) .live-list { order: 5; }
body.live:not(.with-map) .live-map { order: 6; }
/* While a run is on (a net that closes when its time runs out), the net's card is first,
   above the question: how much time is left is what the reader came for. */
body.live.run-on .live-net, body.live.run-on:not(.with-map) .live-net { order: 0; }

/* The globe: from edge to edge, half the screen, so the list's first lines show under it. */
.live-map { height: clamp(280px, 50vh, 520px); height: clamp(280px, 50svh, 520px); margin: 0 -12px 14px; border-left: 0; border-right: 0; border-radius: 0; }
.live-map[data-state="empty"], .live-map[data-state="missing"] { margin: 0 0 14px; border: 1px solid var(--line); border-radius: var(--radius); }
.live-map[data-state="empty"] .map-note, .live-map[data-state="missing"] .map-note { padding: 16px; }
/* A flat map is a square (map.css), which is never wider than the screen. */
.live-map.map-flat { margin-left: 0; margin-right: 0; border: 1px solid var(--line); border-radius: var(--radius); }
body.live.past .live-map { filter: saturate(0.85); }
/* A session with nobody in it at all: the list says so, and the line about the map would only say it again. */
.live-page.nobody .live-map[data-state="empty"] { display: none; }

/* ── The net's card ──────────────────────────────────────────────────────── */
.live-title { font-size: 20px; line-height: 1.25; }
.live-about-line { margin: 2px 0 0; color: var(--muted); font-size: 14px; }
.live-net #liveState { margin-top: 10px; }
.live-net .net-state { margin-bottom: 6px; }
.live-net .summary { margin-bottom: 8px; }
.live-net h2.live-of { margin: 12px 0 8px; }
.live-net h2.live-of { color: var(--text); }
.live-of #liveHeading { color: var(--muted); }
.live-off { margin: 0 0 8px; }
.live-nums { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.live-nums > div { display: flex; flex-direction: column; min-width: 0; padding: 8px 12px; border: 1px solid var(--line); border-radius: 10px; background: rgba(var(--tint), 0.02); }
.live-nums b { font: 600 22px/1.25 var(--mono); letter-spacing: -0.02em; }
.live-nums span { color: var(--muted); font-size: 12.5px; }
.live-last, .live-more { margin: 10px 0 0; color: var(--muted); font-size: 13.5px; }
.live-last time { color: var(--text); }
.live-more { margin-top: 6px; }
/* The way to the directions: a link as tall as a finger needs, the last line of the card. */
.live-how { margin: 0 0 -8px; font-size: 14px; }
.live-net > .summary:last-of-type { margin-bottom: 0; }
.live-net #liveWaiting { margin: 8px 0 0; }

/* ── A net that closes when its time runs out: the lines under the state block ─ */
.live-run .notice { margin: 8px 0; }
.live-run .live-more { margin-top: 0; }
.live-run-line { margin: 6px 0 0; color: var(--text); font-size: 14px; }
.live-run-line + .live-run-line { margin-top: 2px; color: var(--muted); font-size: 13.5px; }
.run-result { margin: 10px 0 0; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: rgba(var(--tint), 0.02); }
.run-headline { margin: 0; font-weight: 600; }
.run-headline a.tap { color: var(--text); font-weight: 600; }
.run-headline .tag { margin-left: 4px; }
.run-why { margin: 4px 0 0; color: var(--muted); font-size: 13.5px; }

/* ── The sessions ────────────────────────────────────────────────────────── */
.live-pick { padding: 8px; }
.pick-row { display: flex; align-items: center; gap: 8px; }
.pick-btn { flex: none; width: 48px; min-height: 48px; padding: 0 0 4px; font-size: 30px; line-height: 1; background: rgba(var(--tint), 0.04); }
.pick-btn:hover { border-color: var(--amber); color: var(--amber); background: rgba(var(--tint), 0.04); }
.pick-btn[aria-disabled="true"] { opacity: 0.25; pointer-events: none; }
.pick-form { flex: 1; display: flex; gap: 8px; min-width: 0; }
.pick-form select { flex: 1; min-width: 0; min-height: 48px; padding: 0 10px; background: var(--adm-well); border: 1px solid var(--line-strong); border-radius: 9px; font-weight: 600; text-overflow: ellipsis; }
body.live.past .pick-form select { color: var(--amber); }
.pick-one { margin: 0; padding: 4px 6px; color: var(--muted); }
.pick-one b { color: var(--text); font-weight: 650; margin-right: 6px; }
.pick-links { display: flex; flex-wrap: wrap; gap: 0 16px; justify-content: center; margin: 0; }
.pick-links:empty { display: none; }

/* ── Who checked in ──────────────────────────────────────────────────────── */
.live-list .card-head { margin-bottom: 6px; }
.live-list .card-head h2 { margin: 2px 0; }
.live-total { color: var(--text); font-family: var(--mono); letter-spacing: 0; margin-left: 4px; }
.live-filter { margin: 0 0 8px; }
.live-filter .chip b { margin-left: 6px; color: var(--muted); font: 600 12.5px var(--mono); }
.live-filter .chip.on b { color: var(--amber); }
.live-rows { list-style: none; margin: 0 -6px; padding: 0; }
.live-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 10px; padding: 10px 6px 10px 4px; border-bottom: 1px solid var(--line); border-left: 2px solid transparent; border-radius: 2px; }
.live-row[data-map-fly], .live-row[data-href] { cursor: pointer; }
.live-row[data-map-fly]:hover, .live-row[data-href]:hover { background: rgba(var(--tint), 0.04); }
.live-row:focus-visible { outline: 2px solid var(--adm-ring); outline-offset: -2px; }
/* Checked in during the last twenty minutes of a session that is on. */
.live-row.recent { border-left-color: var(--amber-mark); }
/* The line of the station that was tapped on the map. */
.live-row.picked { background: rgba(var(--amber-rgb), 0.12); border-left-color: var(--amber-mark); }
.live-row .who { min-width: 0; }
.live-row .call { font-size: 15px; }
.live-row .flag { margin: 0 0 0 6px; }
.live-row .also { margin-left: 6px; color: var(--muted); font-size: 13px; }
.live-row .when { color: var(--muted); font-size: 13px; text-align: right; white-space: nowrap; }
.live-row .when .utc { color: var(--faint); font-size: 12.5px; }
.live-row .said { grid-column: 1 / -1; color: var(--text); }
.live-row .meta { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 3px 10px; color: var(--faint); font-size: 12.5px; }
.live-row .meta .n { color: var(--amber); }
.live-row .meta .tags { margin-right: -2px; }
/* The line's Raw button ends its small print, at the right (net.js draws it; site.css, .raw-btn). */
.live-row .meta .raw-btn { margin-left: auto; }
.live-also { margin: 10px 0 0; }
.live-links { margin: 12px 0 0; }
.live-list .empty .btn { margin: 14px 4px 0; }

/* The card a tap on a station opens: one more line, which takes the page to its line in the list. */
.map-pop .pop-go { display: inline-flex; align-items: center; min-height: 32px; margin-right: 14px; padding: 0; border: 0; background: none; color: var(--blue); font: inherit; font-weight: 600; cursor: pointer; }
.map-pop .pop-go:hover { text-decoration: underline; }
.map-pop .tags { margin: 3px 0; }

@media (max-width: 760px) {
    .map-pop .pop-go { min-height: 44px; }
}

/* ── A wide screen with no map: two columns ──────────────────────────────── */
@media (min-width: 901px) {
    .live-main { width: min(1080px, 100% - 36px); padding-top: 26px; }
    body.live:not(.with-map) .live-page { display: grid; grid-template-columns: 340px minmax(0, 1fr); grid-template-rows: auto auto auto 1fr; gap: 0 18px; align-items: start; }
    body.live:not(.with-map) .live-side { display: block; grid-column: 1; grid-row: 1 / span 4; }
    body.live:not(.with-map) .live-pick { grid-column: 2; grid-row: 1; }
    body.live:not(.with-map) .live-map[data-state="missing"] { grid-row: 2; }
    body.live:not(.with-map) .live-list { grid-column: 2; grid-row: 3; }
    body.live:not(.with-map) .live-map { grid-column: 2; grid-row: 4; }
    /* A net that has not met has no sessions and no map: its one card takes the second column. */
    body.live:not(.with-map) .live-side + .live-list { grid-row: 1; }
}

/* ── A wide screen with a map: the globe is the page and the cards lie on it ─ */
@media (min-width: 901px) {
    body.live.with-map { height: 100vh; overflow: hidden; }
    body.live.with-map .live-main { position: relative; display: flex; width: auto; min-height: 0; margin: 0; padding: 0; }
    body.live.with-map .live-page { position: relative; flex: 1; min-width: 0; min-height: 0; display: grid; grid-template-columns: 310px minmax(0, 1fr) 350px; grid-template-rows: minmax(0, 1fr) auto; gap: 12px; padding: 16px; pointer-events: none; }
    body.live.with-map .live-map { position: absolute; inset: 0; height: auto; margin: 0; border: 0; border-radius: 0; pointer-events: auto; }
    body.live.with-map .card { margin-bottom: 0; pointer-events: auto; backdrop-filter: blur(14px) saturate(1.1); -webkit-backdrop-filter: blur(14px) saturate(1.1); box-shadow: 0 10px 30px rgba(0, 0, 0, calc(0.35 * var(--shade))); }

    /* The left column: the question, the net, what the controller wrote. It scrolls by itself
       when the window is too short for all three, so the question is the one at the top. */
    body.live.with-map .live-side { display: flex; flex-direction: column; gap: 12px; grid-column: 1; grid-row: 1 / span 2; min-height: 0; overflow-y: auto; scrollbar-width: none; z-index: 3; }
    body.live.with-map .live-side::-webkit-scrollbar { display: none; }
    body.live.with-map .live-side > * { flex: none; }
    body.live.with-map .live-ask { order: 1; }
    body.live.with-map .live-net { order: 2; }
    body.live.with-map .live-side > .card:not(.live-net):not(.live-ask) { order: 3; }

    /* The right column: the list, which scrolls inside its card. */
    body.live.with-map .live-list { grid-column: 3; grid-row: 1 / span 2; display: flex; flex-direction: column; min-height: 0; z-index: 3; }
    body.live.with-map .live-list > * { flex: none; }
    body.live.with-map .live-rows-box { flex: 1 1 auto; min-height: 0; overflow-y: auto; margin: 0 -8px; padding: 0 8px; scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
    body.live.with-map .live-links { margin-top: 6px; margin-bottom: -4px; }
    body.live.with-map .live-links .btn { min-height: 34px; }

    /* The sessions: a small card under the middle of the globe. */
    body.live.with-map .live-pick { grid-column: 2; grid-row: 2; justify-self: center; width: min(430px, 100%); z-index: 3; }
    body.live.with-map .pick-btn, body.live.with-map .pick-form select { min-height: 44px; }
    body.live.with-map .pick-links .tap { min-height: 30px; font-size: 13.5px; }

    /* The map's own buttons and its credit keep clear of the list. */
    body.live.with-map .live-map .maplibregl-ctrl-top-right { right: 372px; top: 12px; }
    body.live.with-map .live-map .maplibregl-ctrl-bottom-right { right: 372px; }
    body.live.with-map .live-map .maplibregl-ctrl-bottom-left { left: 332px; }
    body.live.with-map .live-map .map-toast { top: 16px; }

    /* Full screen takes the globe and its cards, as aprsthursday does. */
    .live-page:fullscreen { background: var(--bg); }
}

/* Somebody who asked their device for less motion: a new line does not flash. */
@media (prefers-reduced-motion: reduce) {
    .live-row.new { animation: none; }
}

/* Another session is on its way: what is on the page is the one before, dimmed until it lands. */
.live-page.loading .live-rows-box, .live-page.loading .live-nums { opacity: 0.55; transition: opacity 0.15s 0.2s; }
