/* Live view — the ClockRing and the three lists around it.
 *
 * Loaded alongside app.css, which already owns the shell, the buttons, the
 * banners and the coverage bars. Nothing here restates them.
 *
 * Every colour is a token (05_CONVENTIONS.md guardrail 10). The one exception
 * is the territory hue on a row's left edge and on an arc, which arrives from
 * the API as `var(--t-<key>, <hex>)` built by components/territory-paint.js —
 * the token wins, the row's own value is only the fallback.
 *
 * Sizes lean large on purpose. This is read at arm's length, in blinding sun
 * and at 3am, by someone who has not slept.
 */

/* --- layout --------------------------------------------------------------- */

.live { display: flex; flex-direction: column; gap: var(--space-5); }

/* On a phone the list comes before the dial.
 *
 * Source order is the desktop's (and the screen reader's): the ring is the
 * screen's headline and it sits top-left. But 340px of clock face above the
 * fold is 340px spent on atmosphere, and the question somebody opens this
 * screen with at 3am is "am I on now" — which the on-now column answers in
 * words. The design says the same thing with `ordRing: isPhone ? 2 : 1`. */
.live-body { display: flex; flex-direction: column; gap: var(--space-6); }

.live-cols { order: 1; }
.live-ring-col { order: 2; }
.live-asides { order: 3; }

.live-ring-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
}

.live-cols { display: flex; flex-direction: column; gap: var(--space-6); }

.live-asides {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
}

.live-day {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-family: var(--font-ui);
  font-size: var(--size-small);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--soft);
}

/* --- the breathing pulse ---------------------------------------------------
 * The one animation on this screen, and it earns its place: it is how you know
 * at a glance that the numbers are live rather than a page left open since
 * yesterday. Under prefers-reduced-motion tokens.css stops it and it becomes
 * exactly what the design asks for — a static dot. */

.live-pulse {
  width: 9px;
  height: 9px;
  border-radius: var(--radius-pill);
  background: var(--live);
  flex: none;
  animation: breathe 2.6s ease-in-out infinite;
}

.live-pulse--live { background: var(--live); }
.live-pulse--gap { background: var(--gap); }

/* --- the ring ------------------------------------------------------------- */

.ring-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
}

.ring {
  position: relative;
  width: 100%;
  max-width: 310px;
  padding: var(--space-4) 0;
}

.ring-svg { display: block; width: 100%; height: auto; overflow: visible; }

.ring-track { fill: none; stroke: var(--card); }
.ring-track--inner { opacity: 0.75; }

.ring-arc { fill: none; stroke-linecap: butt; }

.ring-hand { stroke: var(--ink); stroke-width: 2.5; stroke-linecap: round; }
.ring-hub { fill: var(--ink); }

.ring-centre {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

.ring-time {
  font-family: var(--font-display);
  /* Sized to sit inside the innermost ring rather than across it: the hole is
   * the box width scaled by 91/260, so this has to stay under about a third of
   * the container. */
  font-size: 26px;
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.ring-sub {
  margin-top: var(--space-1);
  font-size: var(--size-kicker);
  letter-spacing: var(--track-kicker);
  color: var(--soft);
}

/* Four quarter labels punched through the ring, on the page background. */
.ring-mark {
  position: absolute;
  font-size: var(--size-micro);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.1em;
  color: var(--soft);
  background: var(--bg);
  font-variant-numeric: tabular-nums;
}

.ring-mark--0,
.ring-mark--2 { left: 50%; transform: translateX(-50%); padding: 0 var(--space-1); text-transform: uppercase; }
.ring-mark--0 { top: 0; }
.ring-mark--2 { bottom: 0; }
.ring-mark--1,
.ring-mark--3 { top: 50%; transform: translateY(-50%); padding: var(--space-1) 0; }
.ring-mark--1 { right: -6px; }
.ring-mark--3 { left: -6px; }

/* Out of season: the four tracks are drawn, the hand is at now, and nothing is
 * on it. Says so, rather than leaving a bare diagonal line to be read as a bug. */
.ring-empty {
  margin: var(--space-2) 0 0;
  font-size: var(--size-micro);
  color: var(--soft);
  text-align: center;
  line-height: 1.45;
}

/* --- section headings -----------------------------------------------------
 * The kicker label itself (uppercase, small, --soft) is now `sectionHead()`
 * from `components/ui.js` — this file used to define it a second time under
 * its own global `.kicker`, which is exactly the class `admin.css` also
 * defined; see `admin.css`'s `.akicker` comment for the rendering bug that
 * caused. What is left here is layout that wraps the shared heading. */

.live-col-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  padding-bottom: var(--space-2);
  margin-bottom: var(--space-3);
  border-bottom: 1px solid var(--line);
}

.col-note {
  font-size: var(--size-micro);
  color: var(--soft);
  font-variant-numeric: tabular-nums;
}

.countdown { font-variant-numeric: tabular-nums; }

/* --- needed right now ------------------------------------------------------
 * The loudest thing on the screen, deliberately: an uncovered core seat during
 * the burn is the one problem this app exists to make visible. */

/* --- the next thing happening in camp ------------------------------------- */

/* The design's event banner: a fill, an icon, three lines and a door. Its
 * surface follows how close the event is — panel, then --soon-bg inside four
 * hours, then --live-bg while it runs. */
.live-event {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  background: var(--panel);
  border-radius: var(--radius-card);
  padding: var(--space-4) 17px;
}

.live-event.is-soon { background: var(--soon-bg); }
.live-event.is-now { background: var(--live-bg); }

.live-event-icon { font-size: 20px; flex: none; }

.live-event-body {
  flex: 1;
  min-width: 170px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.live-event-title { font-size: 17px; font-weight: var(--weight-semibold); }
.live-event-when { font-size: var(--size-small); color: var(--soft); }

.needs {
  background: var(--gap-bg);
  border-radius: var(--radius-card);
  padding: 15px 17px;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.needs-list,
.rows,
.later,
.live-legend { list-style: none; margin: 0; padding: 0; }

.needs-list {
  /* Columns rather than one long list, so on a wide screen the Claim button
   * stays beside the words it belongs to instead of a foot away at the edge. */
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--space-2);
}

/* Below 480px a 300px track and this section's own 34px of horizontal padding
 * (15px 17px) leave nothing to fit a second column in and risk overflow on
 * anything narrower than about 334px — this screen had no phone override at
 * all. One column, full width, is also simply the right read at arm's length
 * on a phone: two narrow Need rows side by side is two things half-read. */
@media (max-width: 480px) {
  .needs-list { grid-template-columns: 1fr; }
}

.need {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 11px;
  min-height: 52px;
  padding: 11px 13px;
  border-radius: var(--radius-control);
  background: var(--panel);
  color: var(--ink);
}

/* --- rows ----------------------------------------------------------------- */

.rows { display: flex; flex-direction: column; gap: var(--space-2); }

.live-row {
  display: flex;
  /* The columns are narrow on a desktop. When the text and the button stop
   * fitting side by side the button drops to its own line instead of squeezing
   * a camper's name into one word per row. */
  flex-wrap: wrap;
  align-items: center;
  gap: 11px;
  min-height: 52px;
  padding: 11px 13px;
  border-radius: var(--radius-control);
  /* The territory's hue, so a row can be traced back to its arc on the ring.
   * The design leaves this edge off — it is our addition, and the reason it
   * stays is that four rings of colour above a monochrome list is a puzzle. At
   * 3px it matches every other accent edge in the design (agenda shift cards,
   * training rows) rather than being the one 4px line in the app. The colour
   * itself is an inline style from components/territory-paint.js — it is data,
   * and only the fallback below lives in the stylesheet. */
  border-left: 3px solid var(--line);
}

.live-row--live { background: var(--live-bg); color: var(--ink); }
.live-row--gap { background: var(--gap-bg); color: var(--gap); }
.live-row--held { background: var(--card); color: var(--ink); }
.live-row--open { background: var(--soon-bg); color: var(--soon); }
/* Only an admin ever sees this one: a column camp has not released (Rule 7). */
.live-row--closed { background: var(--card); color: var(--soft); }
.live-row--mine { box-shadow: inset 0 0 0 2px var(--ink); }

.live-row-emoji { font-size: 19px; flex: none; }

.live-row-body { flex: 1 1 140px; min-width: 0; }


/* Keeps the button at the right edge, on its own line once the row wraps. */
.live-row > .btn,
.need > .btn { margin-left: auto; }

.live-row-name {
  display: block;
  font-size: var(--size-body);
  font-weight: var(--weight-semibold);
}

/* No opacity here on purpose: a gap row is --gap on --gap-bg, which clears AA
 * at full strength and stops clearing it the moment it is faded. */
.live-row-sub {
  display: block;
  font-size: var(--size-micro);
  line-height: 1.35;
}

/* --- rest of today -------------------------------------------------------- */

.later { display: flex; flex-direction: column; gap: var(--space-3); }

.later-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--size-small);
  min-height: 26px;
}

.later-time {
  width: 78px;
  flex: none;
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}

.bars-wrap { flex: none; display: inline-flex; }

.later-text { flex: 1; min-width: 0; color: var(--soft); }

.later-flag { font-weight: var(--weight-semibold); color: var(--soft); white-space: nowrap; }
.later-flag.is-gap { color: var(--gap); }

/* The design sets this 15px clear of the last change of the day. */
.later-more { margin-top: 15px; }

/* --- the panels under the ring --------------------------------------------
 *
 * `.live-card`, not the shared `card()` from `components/ui.js`: that
 * primitive is `display: block` with a single `<h3>` title slot, and these two
 * panels need `aria-labelledby` pointing at their own `sectionHead()` — a
 * pairing `card()` has no parameter for. Forcing it would mean dropping the
 * landmark label or inventing one more prop on a shared file this port does
 * not own. The heading itself is shared (`sectionHead`, above); only the
 * surrounding box stays local. */

.live-card {
  width: 100%;
  max-width: 340px;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: flex-start;
  background: var(--panel);
  border-radius: var(--radius-card);
  padding: var(--space-4);
}

.live-card--you { background: var(--card); }

/* The card's one door — "My shifts →" or "Sign in →" (the design's youCta). */
.you-door { margin-top: var(--space-3); margin-right: var(--space-2); }
.live-card--anon { background: var(--soon-bg); }

.live-card-note {
  margin: 0;
  font-size: var(--size-micro);
  color: var(--soft);
  line-height: 1.5;
}

.live-card-note--rule {
  border-top: 1px solid var(--line);
  padding-top: var(--space-2);
  width: 100%;
}

.you-line {
  margin: 0;
  font-size: var(--size-body);
  font-weight: var(--weight-semibold);
}

/* `.live-legend` is the `<ul>` this screen wraps around
 * `ringLegend()` (`components/clock-ring.js`). `.legend-row` / `-swatch` /
 * `-text` below stay unprefixed on purpose: they are the class names that
 * shared component hard-codes into the `<li>`s it returns, so renaming them
 * here without also editing `clock-ring.js` — a file this port does not own —
 * would silently unstyle the ring's own legend. */
.live-legend { display: flex; flex-direction: column; gap: var(--space-2); width: 100%; }

.legend-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--size-micro);
  color: var(--soft);
}

.legend-swatch { width: 26px; border-radius: 3px; flex: none; }
.legend-text { flex: 1; min-width: 0; }
.legend-text strong { color: var(--ink); font-weight: var(--weight-semibold); }

/* --- buttons this screen adds --------------------------------------------- */

.btn--gap { border-color: var(--gap); background: var(--gap); color: var(--on); }
.btn--outline { border-color: currentColor; background: transparent; color: inherit; }

/* --- desktop: the ring left, the three lists beside it --------------------- */

@media (min-width: 768px) {
  .live-body {
    display: grid;
    grid-template-columns: 340px 1fr;
    grid-template-areas:
      'ring cols'
      'aside cols';
    grid-template-rows: auto 1fr;
    column-gap: var(--space-6);
    row-gap: var(--space-5);
    align-items: start;
  }

  .live-ring-col { grid-area: ring; }
  .live-cols { grid-area: cols; }
  .live-asides { grid-area: aside; }

  .live-cols {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: var(--space-5);
  }

  .ring-time { font-size: 28px; }
}

/* --- build week -------------------------------------------------------------
 *
 * The six days before the season. No ring, because there are no shift times to
 * draw one from — the whole screen is a list of days and who lands on each.
 *
 * Painted in the Build territory's own pair so that walking from the Build
 * sign-up screen into Live feels like the same subject, and so a glance tells
 * you which half of the year you are looking at.
 */

.live-build {
  display: grid;
  gap: var(--space-4);
  margin-top: var(--space-4);
}

.live-build-day {
  border: 1px solid var(--line);
  border-left: 4px solid var(--t-build);
  border-radius: var(--radius-card);
  background: var(--panel);
  padding: var(--space-4);
}

/* Today is the one somebody opened the app to find. It gets the tint behind it
 * rather than a heavier border, so the page still reads as one list. */
.live-build-day.is-today {
  background: var(--t-build-t);
  border-color: var(--t-build);
}

/* Already arrived. Still on the page — who is *here* is half the question — but
 * it stops competing with the days that have not happened yet. */
.live-build-day.is-past {
  border-left-color: var(--line);
  opacity: 0.72;
}

.live-build-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.live-build-when {
  font-family: var(--font-display);
  font-size: 20px;
  margin: 0;
  color: var(--ink);
}

/* `-deep` and not the primary: the primary on its own tint measures 1.89:1
 * (04_DESIGN_HANDOFF.md § Contrast). */
.live-build-tag {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--t-build-deep);
}

.live-build-count {
  margin-left: auto;
  font-size: 14px;
  color: var(--soft);
  font-variant-numeric: tabular-nums;
}

.live-build-credit {
  margin: var(--space-2) 0 var(--space-3);
  font-size: 14px;
  color: var(--soft);
}

.live-build-people {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2px;
}

/* A whole row is the tap target, and it clears the 48px floor the conditions
 * spec sets — this gets read one-handed, in dust, by somebody watching for
 * headlights. */
.live-build-person {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 48px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-control);
  cursor: pointer;
}

.live-build-person:hover,
.live-build-person:focus-visible {
  background: var(--card);
  outline: none;
}

.live-build-person:focus-visible {
  box-shadow: 0 0 0 2px var(--t-build);
}

.live-build-name { color: var(--ink); }

.live-build-pod {
  font-size: 13px;
  color: var(--soft);
  text-align: right;
}

@media (min-width: 900px) {
  /* Multi-column rather than grid, because these cards are wildly uneven — one
   * arrival on Tuesday, eleven on Thursday — and a grid reserves every row at
   * the height of its tallest card. That left half the screen empty. Columns
   * flow instead, so a short day takes a short box.
   *
   * The trade is column-major order: the first half of the week fills the left
   * column and the rest the right, rather than reading left-to-right. That is
   * fine here and only here — every card carries its own date in 20px Fraunces,
   * so this is a thing you scan for a day, not a sequence you read in order.
   */
  .live-build {
    display: block;
    columns: 2;
    column-gap: var(--space-4);
  }

  .live-build-day {
    break-inside: avoid;
    margin-bottom: var(--space-4);
  }
}
