/* Public live board (Proposal 012) — purpose-built, large-type, read-only.
   Reuses style.css tokens (--sq-*, --space-*, --danger, etc.); only the bits
   specific to the public board live here. */

.pub-body {
  background: var(--bg);
  color: var(--text);
  margin: 0;
  min-height: 100vh;
}

.pub-wrap {
  max-width: 880px;
  margin: 0 auto;
  padding: var(--space-lg) var(--space-md) var(--space-2xl);
}

.pub-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  flex-wrap: wrap;
  margin-bottom: var(--space-lg);
}

.pub-title {
  font-family: 'Poppins', sans-serif;
  font-weight: 800;
  font-size: clamp(1.3rem, 4vw, 1.8rem);
  letter-spacing: -0.03em;
}

/* --- Liveness chip (header) --- */
.pub-live {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--text-xs);
  font-weight: var(--fw-semibold);
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--muted);
}

.live-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--muted);
}

.pub-live.is-live {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
}

.pub-live.is-live .live-dot {
  background: var(--accent);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 70%, transparent);
  animation: pub-pulse 2s infinite;
}

.pub-live.is-stale {
  color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 40%, var(--border));
}

.pub-live.is-stale .live-dot {
  background: var(--danger);
}

@keyframes pub-pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 60%, transparent); }
  70% { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

@media (prefers-reduced-motion: reduce) {
  .pub-live.is-live .live-dot { animation: none; }
}

/* --- Full-width STALE banner: fail loud (§4) --- */
/* `display: flex` below would otherwise defeat the `hidden` attribute (an author
   `display` rule beats the UA `[hidden] { display:none }`), leaving the banner
   permanently visible. This scoped rule (higher specificity) lets `hidden` win. */
.stale-banner[hidden] {
  display: none;
}

.stale-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  background: var(--danger);
  color: #fff;
  font-weight: var(--fw-bold);
  font-size: clamp(0.9rem, 3vw, 1.1rem);
  padding: var(--space-sm) var(--space-md);
  text-align: center;
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  box-shadow: 0 2px 12px rgba(193, 48, 48, 0.4);
}

.stale-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #fff;
  animation: pub-blink 1s steps(2, start) infinite;
}

@keyframes pub-blink { 50% { opacity: 0.25; } }

/* When stale, grey/dim the board so it cannot be mistaken for current. */
.pub-board.is-stale {
  opacity: 0.4;
  filter: grayscale(0.7);
  transition: opacity 0.2s, filter 0.2s;
}

/* --- Day note (today vs weekend roll-forward) --- */
.day-note {
  font-size: clamp(1rem, 3.5vw, 1.35rem);
  font-weight: var(--fw-semibold);
  margin-bottom: var(--space-lg);
}

.day-note .dn-today { color: var(--accent); }
.day-note .dn-fwd {
  color: var(--warn);
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

/* --- Squad header inside the board --- */
.pub-squad {
  border-radius: 14px;
  border-left: 6px solid;
  padding: var(--space-lg) var(--space-xl);
  margin-bottom: var(--space-lg);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.07);
}

.pub-squad .sq-title {
  font-family: 'Poppins', sans-serif;
  font-weight: 800;
  font-size: clamp(1.5rem, 5vw, 2.2rem);
  line-height: 1;
  letter-spacing: -0.04em;
}

.pub-squad.sq-a { border-color: var(--sq-a); background: rgba(46, 109, 181, 0.08); }
.pub-squad.sq-b { border-color: var(--sq-b); background: rgba(163, 77, 132, 0.08); }
.pub-squad.sq-c { border-color: var(--sq-c); background: rgba(39, 146, 77, 0.08); }
.pub-squad.sq-a .sq-title { color: var(--sq-a); }
.pub-squad.sq-b .sq-title { color: var(--sq-b); }
.pub-squad.sq-c .sq-title { color: var(--sq-c); }

/* --- Slot cards --- */
.pub-slots {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-md);
}

.pub-slot {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: var(--space-lg);
}

.pub-slot .ps-role {
  font-size: var(--text-xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-bottom: 0.4rem;
}

.pub-slot .ps-name {
  font-family: 'Poppins', sans-serif;
  font-weight: 700;
  font-size: clamp(1.15rem, 4vw, 1.5rem);
  line-height: 1.15;
}

.pub-slot .ps-from {
  font-size: var(--text-sm);
  color: var(--muted);
  margin-top: 0.3rem;
}

.pub-slot.is-empty .ps-name { color: var(--danger); }

/* A small badge when the on-call person is a fallback (not the on-duty squad). */
.ps-flag {
  display: inline-block;
  margin-top: 0.5rem;
  font-size: var(--text-xs);
  font-weight: var(--fw-semibold);
  padding: 0.15rem 0.5rem;
  border-radius: 6px;
  background: rgba(208, 106, 46, 0.14);
  color: var(--warn);
}

.pub-empty {
  text-align: center;
  color: var(--muted);
  padding: var(--space-2xl);
  font-size: var(--text-md);
}

.pub-foot {
  margin-top: var(--space-xl);
  text-align: center;
  font-size: var(--text-xs);
  color: var(--muted);
}

/* Heartbeat-age ticker. The ⟳ icon spins gently while live to reinforce the
   "continuously updating" feel; the whole signal turns danger-colored once the
   stream has stalled (paired with the stale banner). */
#signal-sep .sig-ico {
  display: inline-block;
  animation: sig-spin 2s linear infinite;
}

#signal-sep.sig-stale {
  color: var(--danger);
  font-weight: var(--fw-semibold);
}

#signal-sep.sig-stale .sig-ico {
  animation: none;
}

@keyframes sig-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  #signal-sep .sig-ico { animation: none; }
}
