/* The live monitor (pages/live.js, pages/live-view.js).
 *
 * Motion here means something each time: a number hops because it changed,
 * a dot glides because someone is on the road, a row slides in because it
 * just happened. Nothing moves for decoration, and all of it stops under
 * prefers-reduced-motion (components.css shortens every animation to 1 ms;
 * the block at the end removes the ones that would still loop).
 *
 * Colour: one lane hue per mark, always beside an icon and a word. Numbers
 * stay in text ink. No gradients (owner's rule).
 */
.live {
  --live-dot: var(--sp-4);        /* a moving dot */
  --live-mark: var(--sp-3);       /* a small status or lane mark */
  --live-hair: var(--sp-1);       /* a rail, a quiet minute */
  --live-icon: var(--sp-8);       /* the round seat behind an icon */
  --live-strip: var(--sp-11);     /* height of the last-hour strip */
  --live-glide: 1000ms;           /* one clock tick, so a dot never stops */
  --lane: var(--brand);
}
.live:fullscreen { padding: var(--sp-7); overflow: auto; background: var(--bg); }

.lane--clinic { --lane: var(--lane-clinic); }
.lane--pharmacy { --lane: var(--lane-pharmacy); }
.lane--nursing { --lane: var(--lane-nursing); }
.lane--money { --lane: var(--lane-money); }
.lane--reps { --lane: var(--lane-reps); }
.lane--support { --lane: var(--lane-support); }
.lane--platform { --lane: var(--lane-platform); }

.live__body { display: grid; gap: var(--sp-6); }
.live__columns { display: grid; gap: var(--sp-6); grid-template-columns: minmax(0, 1.6fr) minmax(320px, 1fr); align-items: start; }
.live__main { display: grid; gap: var(--sp-6); min-inline-size: 0; }
.live__side { min-inline-size: 0; position: sticky; inset-block-start: calc(var(--topbar) + var(--sp-5)); }
@media (max-width: 1100px) {
  .live__columns { grid-template-columns: minmax(0, 1fr); }
  .live__side { position: static; }
}

.live-section {
  padding: var(--sp-6); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--e-1);
}
.live-section__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-2) var(--sp-4); margin-block-end: var(--sp-5); }
.live-section__head p { margin: 0; font-size: var(--fs-label); line-height: var(--lh-label); }
.live-section__title { margin: 0; font-family: var(--font-display); font-size: var(--fs-title-m); line-height: var(--lh-title-m); }
.live-empty { margin: 0; padding-block: var(--sp-6); text-align: center; color: var(--text-muted); }

/* --- connection ------------------------------------------------------------ */
.live-status {
  display: inline-flex; align-items: center; gap: var(--sp-3);
  min-block-size: var(--control); padding-inline: var(--sp-4);
  border-radius: var(--r-pill); background: var(--surface-sunken); color: var(--text-muted);
  font-size: var(--fs-label); white-space: nowrap;
}
/* "42 s ago" counts every second: fixed-width digits keep the pill still. */
.live-status__text { font-variant-numeric: tabular-nums; }
.live-status__dot {
  position: relative; flex: none;
  inline-size: var(--live-mark); block-size: var(--live-mark);
  border-radius: var(--r-pill); background: var(--text-subtle);
}
.live-status__dot::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  border: var(--live-hair) solid currentColor; opacity: 0;
}
.live-status[data-state="live"] .live-status__dot { background: var(--success); color: var(--success); }
.live-status[data-state="paused"] .live-status__dot { background: var(--warning); }
.live-status[data-state="lost"] { background: var(--danger-soft); color: var(--danger); }
.live-status[data-state="lost"] .live-status__dot { background: var(--danger); }
/* One ring for every answer that brought something new. */
.live-status.is-beating .live-status__dot::after { animation: live-ring calc(var(--m-slow) * 2.5) var(--ease-slow) 1; }

/* --- today, in a line -------------------------------------------------------- */
.live-today {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-2) var(--sp-6);
  color: var(--text-muted); font-size: var(--fs-label); line-height: var(--lh-label);
}
.live-today__title { font-weight: 600; color: var(--text); }
.live-today__item strong { color: var(--text); font-size: var(--fs-body-m); }

/* --- gauges ------------------------------------------------------------------ */
.live-gauges { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); }
.live-gauge {
  position: relative; display: grid; gap: var(--sp-2); align-content: start;
  min-block-size: var(--target); padding: var(--sp-5);
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--surface); color: var(--text); text-decoration: none;
  transition: border-color var(--m-fast) var(--ease), background var(--m-fast) var(--ease), transform var(--m-fast) var(--ease);
}
a.live-gauge:hover { border-color: var(--border-strong); background: var(--surface-hover); transform: translateY(calc(var(--sp-1) * -1)); }
a.live-gauge:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.live-gauge__icon {
  display: grid; place-items: center; inline-size: var(--live-icon); block-size: var(--live-icon);
  border-radius: var(--r-pill); color: var(--lane);
  background: color-mix(in srgb, var(--lane) 12%, var(--surface));
}
.live-gauge__value {
  justify-self: start; font-size: var(--fs-display-l); line-height: var(--lh-display-l); font-weight: 600;
  transform-origin: center bottom;
}
.live-gauge__label { font-size: var(--fs-label); line-height: var(--lh-label); color: var(--text-muted); }
/* Something here is waiting for a person: an edge, and a mark that breathes. */
.live-gauge.is-waiting { border-color: var(--warning); background: var(--warning-soft); }
.live-gauge.is-waiting::after {
  content: ''; position: absolute; inset-block-start: var(--sp-5); inset-inline-end: var(--sp-5);
  inline-size: var(--live-mark); block-size: var(--live-mark); border-radius: var(--r-pill);
  background: var(--warning); animation: breathe calc(var(--m-slow) * 3) var(--ease) infinite alternate;
}
.live-gauge__value.is-bumped { animation: live-bump calc(var(--m-slow) * 1.5) var(--ease-slow) 1; }

/* --- on the move --------------------------------------------------------------- */
.live-trips { display: grid; gap: var(--sp-2); margin: 0; padding: 0; list-style: none; }
.live-trip {
  display: grid; align-items: center; gap: var(--sp-3) var(--sp-5);
  grid-template-columns: minmax(180px, 1.1fr) minmax(120px, 2fr) minmax(120px, auto);
  min-block-size: var(--target); padding-block: var(--sp-3);
  transition: opacity var(--m-slow) var(--ease), transform var(--m-slow) var(--ease-slow);
}
.live-trip + .live-trip { border-block-start: 1px solid var(--border); }
.live-trip.is-new { opacity: 0; transform: translateY(var(--sp-3)); }
.live-trip__who { display: flex; align-items: center; gap: var(--sp-4); min-inline-size: 0; }
.live-trip__icon {
  flex: none; display: grid; place-items: center; inline-size: var(--live-icon); block-size: var(--live-icon);
  border-radius: var(--r-pill); color: var(--lane);
  background: color-mix(in srgb, var(--lane) 12%, var(--surface));
}
.live-trip__title { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.live-trip__sub { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--text-muted); }
.live-trip__meta { font-size: var(--fs-label); color: var(--text-muted); text-align: end; white-space: nowrap; }

/* The road: a hairline, the part already covered, the dot, the door. */
.live-trip__rail { position: relative; block-size: var(--sp-7); margin-inline: calc(var(--live-dot) / 2); }
.live-trip__rail::before {
  content: ''; position: absolute; inset-inline: 0; inset-block-start: 50%;
  block-size: var(--live-hair); margin-block-start: calc(var(--live-hair) / -2);
  border-radius: var(--r-pill); background: var(--border-strong);
}
.live-trip__done {
  position: absolute; inset-inline-start: 0; inset-block-start: 50%;
  block-size: var(--live-hair); margin-block-start: calc(var(--live-hair) / -2);
  border-radius: var(--r-pill); background: var(--lane);
  transition: inline-size var(--live-glide) linear, background var(--m-base) var(--ease);
}
.live-trip__dot {
  position: absolute; inset-block-start: 50%;
  inline-size: var(--live-dot); block-size: var(--live-dot);
  margin-block-start: calc(var(--live-dot) / -2); margin-inline-start: calc(var(--live-dot) / -2);
  border-radius: var(--r-pill); background: var(--lane);
  box-shadow: 0 0 0 var(--sp-1) var(--surface);
  transition: inset-inline-start var(--live-glide) linear, background var(--m-base) var(--ease);
}
.live-trip__dot::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  border: var(--live-hair) solid var(--lane); opacity: 0;
  animation: live-ring calc(var(--m-slow) * 5) var(--ease-slow) infinite;
}
.live-trip__end {
  position: absolute; inset-inline-end: 0; inset-block-start: 50%;
  inline-size: var(--live-mark); block-size: var(--live-mark);
  margin-block-start: calc(var(--live-mark) / -2); margin-inline-end: calc(var(--live-mark) / -2);
  border-radius: var(--r-pill); background: var(--surface); border: var(--live-hair) solid var(--text-subtle);
}
.live-trip.is-late { --lane: var(--warning); }
.live-trip.is-late .live-trip__meta { color: var(--warning); font-weight: 600; }
.live-trip.is-arrived { --lane: var(--success); animation: live-leave var(--m-slow) var(--ease) calc(var(--m-slow) * 5) 1 forwards; }
.live-trip.is-arrived .live-trip__meta { color: var(--success); font-weight: 600; }
.live-trip.is-arrived .live-trip__dot::after { animation: none; }
@media (max-width: 768px) {
  .live-trip { grid-template-columns: minmax(0, 1fr) auto; }
  .live-trip__rail { grid-column: 1 / -1; grid-row: 2; }
}

/* --- the last hour ----------------------------------------------------------- */
.live-pulse { min-inline-size: 0; }
.live-pulse__strip { display: flex; align-items: flex-end; gap: var(--sp-1); block-size: var(--live-strip); }
.live-pulse__bar {
  flex: 1 1 0; min-inline-size: var(--sp-1); min-block-size: var(--live-hair);
  border-start-start-radius: var(--sp-1); border-start-end-radius: var(--sp-1);
  background: var(--chart-1);
  transition: block-size var(--m-slow) var(--ease-slow), background var(--m-fast) var(--ease);
}
.live-pulse__bar.is-empty { background: var(--border-strong); }
.live-pulse__bar:hover { background: var(--text); }
/* The minute being lived through. */
.live-pulse__bar.is-now:not(.is-empty) { animation: breathe calc(var(--m-slow) * 3) var(--ease) infinite alternate; }
.live-pulse__axis {
  display: flex; justify-content: space-between; margin-block-start: var(--sp-2);
  font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--text-subtle);
}
.live-pulse__readout { margin-block: var(--sp-3) 0; min-block-size: var(--lh-label); font-size: var(--fs-label); line-height: var(--lh-label); }
.live-mixes { display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-6); margin-block-start: var(--sp-4); }
.live-mixes:empty { display: none; }
.live-mix { display: inline-flex; align-items: center; gap: var(--sp-3); font-size: var(--fs-label); color: var(--text-muted); }
.live-mix strong { color: var(--text); }
.live-mix__dot { inline-size: var(--live-mark); block-size: var(--live-mark); border-radius: var(--r-pill); background: var(--lane); }

/* --- provinces ----------------------------------------------------------------- */
.live-tiles { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fill, minmax(136px, 1fr)); margin: 0; padding: 0; list-style: none; }
.live-tile {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3);
  min-block-size: var(--target); padding: var(--sp-4) var(--sp-5);
  border-radius: var(--r-md); background: var(--surface-sunken); color: var(--text);
  transition: background var(--m-slow) var(--ease);
}
.live-tile__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-label); }
.live-tile__count { font-weight: 600; }
/* One hue, five steps. The number says how many; the tint says where to look. */
.live-tile[data-level="0"] { color: var(--text-muted); }
.live-tile[data-level="1"] { background: color-mix(in srgb, var(--chart-1) 12%, var(--surface)); }
.live-tile[data-level="2"] { background: color-mix(in srgb, var(--chart-1) 22%, var(--surface)); }
.live-tile[data-level="3"] { background: color-mix(in srgb, var(--chart-1) 34%, var(--surface)); }
.live-tile[data-level="4"] { background: color-mix(in srgb, var(--chart-1) 46%, var(--surface)); }
.live-tile.is-pinged { animation: live-ping calc(var(--m-slow) * 3) var(--ease-slow) 1; }

/* --- the stream ---------------------------------------------------------------- */
.live-filter { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-block-end: var(--sp-5); }
.live-stream { margin: 0; padding: 0; list-style: none; max-block-size: 70vh; overflow-y: auto; overscroll-behavior: contain; }
.live:fullscreen .live-stream { max-block-size: 78vh; }
.live-item {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: start; gap: var(--sp-4);
  padding-block: var(--sp-4); padding-inline: var(--sp-2);
  border-radius: var(--r-sm);
}
.live-item + .live-item { border-block-start: 1px solid var(--border); }
.live-item__icon {
  display: grid; place-items: center; inline-size: var(--live-icon); block-size: var(--live-icon);
  border-radius: var(--r-pill); color: var(--lane);
  background: color-mix(in srgb, var(--lane) 12%, var(--surface));
}
.live-item__body { min-inline-size: 0; }
.live-item__what { font-size: var(--fs-body-m); line-height: var(--lh-body-m); overflow-wrap: anywhere; }
.live-item__meta { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--text-muted); }
.live-item__when {
  font-family: var(--font-data); font-variant-numeric: tabular-nums;
  font-size: var(--fs-caption); line-height: var(--lh-body-m); color: var(--text-subtle); white-space: nowrap;
}
/* Just happened: drops in from above with a tint that fades. `backwards`
   keeps a delayed row hidden until its turn in the cascade. */
.live-item.is-new { animation: live-arrive calc(var(--m-slow) * 2) var(--ease-slow) 1 backwards; }

@keyframes live-ring { from { opacity: .7; transform: scale(1); } to { opacity: 0; transform: scale(2.6); } }
@keyframes live-bump {
  0% { transform: none; color: var(--brand-text); }
  35% { transform: translateY(-18%) scale(1.14); color: var(--brand-text); }
  100% { transform: none; }
}
@keyframes live-arrive {
  from { opacity: 0; transform: translateY(calc(var(--sp-4) * -1)); background: var(--brand-soft); }
  60% { opacity: 1; transform: none; background: var(--brand-soft); }
  to { opacity: 1; transform: none; background: transparent; }
}
@keyframes live-leave { to { opacity: 0; } }
@keyframes live-ping {
  from { box-shadow: 0 0 0 0 color-mix(in srgb, var(--chart-1) 70%, transparent); }
  to { box-shadow: 0 0 0 var(--sp-4) transparent; }
}

@media (prefers-reduced-motion: reduce) {
  .live { --live-glide: 0ms; }
  .live-trip__dot::after, .live-gauge.is-waiting::after, .live-pulse__bar.is-now { animation: none; }
  .live-trip.is-new { opacity: 1; transform: none; }
  a.live-gauge:hover { transform: none; }
}
