/*
 * Ladder event wire. It sits above the full-viewport scene explicitly: the
 * backdrop is z-index: 0 across the page, so an unlayered transient surface
 * can otherwise be swallowed by new scene treatments.
 *
 * One wire, one row family. A row is a mark, then the people involved with
 * their direction and new rank, then a figure -- never a headline word. The
 * mark is the player's Discord avatar for rows about a person, a geometric
 * glyph for facts nobody owns. Health checks are not rows of the wire: they
 * hold their own strip above it, still for as long as they are true.
 */

.event-feed {
  position: relative;
  z-index: 1;
}

.event-feed__announcer {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Idle means absent; this measured ceiling lets the board settle into place. */
.event-feed__slot {
  max-height: 0;
  margin-bottom: 0;
  overflow: hidden;
  transition: max-height 260ms cubic-bezier(.32, .72, 0, 1), margin-bottom 260ms cubic-bezier(.32, .72, 0, 1);
}

.event-feed__slot.is-visible {
  max-height: 96px;
  margin-bottom: 14px;
}

/*
 * The error strip: its own surface above the wire, shown only while a check
 * is failing. Rows stack and hold still -- nothing here scrolls away.
 */
.event-feed__issues {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 12px;
}

.event-feed__issues[hidden] {
  display: none;
}

.event-feed__clip {
  min-height: 0;
  overflow: hidden;
}

.event-feed__ticker {
  display: flex;
  align-items: center;
  height: 54px;
  overflow: hidden;
  border: 1px solid rgb(255 255 255 / 9%);
  border-radius: 8px;
  color: var(--text);
  background: rgb(13 17 26 / 52%);
  box-shadow: inset 0 1px rgb(255 255 255 / 4%);
}

/* A class display rule otherwise beats the browser's lower-priority [hidden]. */
.event-feed__ticker[hidden] {
  display: none;
}

.event-feed__viewport {
  min-width: 0;
  overflow: hidden;
}

.event-feed__track {
  display: flex;
  width: max-content;
  animation: event-wire var(--wire-duration, 44s) linear infinite;
  will-change: transform;
}

/* A wire with one row on it holds still rather than sliding past itself. */
.event-feed__track.is-static {
  width: 100%;
  animation: none;
  transform: none;
}

.event-feed__ticker:hover .event-feed__track,
.event-feed__ticker:focus .event-feed__track,
.event-feed__ticker:focus-within .event-feed__track {
  animation-play-state: paused;
}

.event-feed__ticker:focus-visible {
  outline: 2px solid var(--stat-accent);
  outline-offset: 3px;
}

.event-feed__cycle {
  display: flex;
  align-items: center;
  gap: 30px;
  padding-right: 30px;
  white-space: nowrap;
}

.event-feed__track.is-static .event-feed__cycle {
  width: 100%;
  padding-right: 0;
}

.event-feed__event {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  padding-left: 14px;
  border-left: 2px solid currentColor;
  color: var(--text);
  animation: event-wire-enter 360ms cubic-bezier(.32, .72, 0, 1) both;
}

/* Editorial weight from events.js: a lead change, a promotion or a ruling
   takes a heavier rail and a louder name than a routine climb. */
.event-feed__event[data-priority="headline"] {
  border-left-width: 3px;
}

.event-feed__visual {
  position: relative;
  flex: 0 0 17px;
  width: 17px;
  height: 17px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 0;
  vertical-align: middle;
}

.event-feed__icon {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
}

.event-feed__avatar {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}

.event-feed__line {
  display: flex;
  align-items: baseline;
  gap: 14px;
  min-width: 0;
  color: var(--text);
  font-size: 0.83rem;
}

/* One player: their name, then where they landed. */
.event-feed__party {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  min-width: 0;
}

.event-feed__actor {
  overflow: hidden;
  color: var(--text);
  font-weight: 700;
  letter-spacing: -0.015em;
  text-overflow: ellipsis;
}

.event-feed__event[data-priority="headline"] .event-feed__actor {
  font-size: 0.88rem;
  font-weight: 800;
}

/* The direction mark keeps the board's own colours whatever the row's type
   is: green climbs, red falls, muted for an arrival with nothing to compare. */
.event-feed__mark {
  flex: 0 0 auto;
  font-family: var(--numeric);
  font-size: 0.7rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

.event-feed__mark.is-up { color: var(--lp-up); }
.event-feed__mark.is-down { color: var(--lp-down); }
.event-feed__mark.is-flat { color: var(--muted); }

.event-feed__figure {
  flex: 0 0 auto;
  color: currentColor;
  font-family: var(--numeric);
  font-size: 0.74rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.03em;
}

/* Struck exactly as the game log strikes a voided row: this LP is gone. */
.event-feed__figure.is-struck {
  text-decoration: line-through;
  text-decoration-thickness: 1.5px;
}

.event-feed__pulse {
  font-size: 0.6rem;
  animation: event-wire-pulse 1.6s ease-in-out infinite;
}

/* System rows carry a label and a sentence rather than figures. */
.event-feed__label {
  flex: 0 0 auto;
  font-family: var(--numeric);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.event-feed__detail {
  min-width: 0;
  overflow: hidden;
  color: var(--muted);
  font-family: var(--numeric);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Type is colour. */
.event-feed__event--lead,
.event-feed__event--top-three,
.event-feed__event--streak {
  color: var(--crown-gold);
}

.event-feed__event--overtake,
.event-feed__event--live,
.event-feed__event--clip-uploaded {
  color: var(--stat-accent);
}

.event-feed__event--tier-promotion {
  color: var(--lp-up);
}

.event-feed__event--reshuffle,
.event-feed__event--update {
  color: var(--muted);
}

/* A losing run is reported, not celebrated: no flame, no gold. */
.event-feed__event--slump {
  color: color-mix(in srgb, var(--lp-down) 70%, var(--muted));
}

/* A ruling against a player is the loudest thing on the wire. */
.event-feed__event--void {
  color: var(--lp-down);
}

/*
 * An error or health issue is shown in red with a warning icon, in the strip
 * above the wire -- holding still, never scrolling with the news.
 */
.event-feed__event--system,
.event-feed__event--error {
  border-left-style: solid;
  border-left-color: var(--lp-down, #e0637f);
  color: var(--lp-down, #e0637f);
}

.event-feed__event--system-down,
.event-feed__event--system-warn,
.event-feed__event--system-error {
  color: var(--lp-down, #e0637f);
}

.event-feed__event--system .event-feed__detail,
.event-feed__event--error .event-feed__detail {
  color: var(--lp-down, #e0637f);
  font-weight: 700;
}

@keyframes event-wire {
  to { transform: translateX(-50%); }
}

@keyframes event-wire-enter {
  from { opacity: 0; transform: translateY(5px); }
  to { opacity: 1; transform: none; }
}

@keyframes event-wire-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

.event-history {
  margin: 0;
  padding: 0;
  list-style: none;
}

.feed-title {
  margin: 20px 0 12px;
  color: var(--text);
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 600;
}

.event-history__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 4px;
  border-bottom: 1px solid color-mix(in srgb, var(--hairline) 55%, transparent);
  color: var(--text);
  font-size: 0.86rem;
}

.event-history__time {
  flex: 0 0 auto;
  color: var(--muted);
  font-family: var(--numeric);
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
}

.event-history__text { color: currentColor; }
.event-history__item--lead,
.event-history__item--top-three,
.event-history__item--streak { color: var(--crown-gold); }
.event-history__item--overtake,
.event-history__item--live { color: var(--stat-accent); }
.event-history__item--tier-promotion { color: var(--lp-up); }
.event-history__item--slump { color: color-mix(in srgb, var(--lp-down) 70%, var(--muted)); }
.event-history__item--void { color: var(--lp-down); }

/* Narrow layouts */
@media (max-width: 860px) {
  .event-feed__ticker {
    height: auto;
    min-height: 54px;
  }
}

@media (max-width: 560px) {
  .event-feed__line {
    gap: 9px;
    font-size: 0.78rem;
  }
  .event-feed__event[data-priority="headline"] .event-feed__actor {
    font-size: 0.82rem;
  }
}

/* This is a real static mode for reduced motion: preserves horizontal scrolling without hiding elements. */
@media (prefers-reduced-motion: reduce) {
  .event-feed__viewport {
    overflow-x: auto;
    scrollbar-width: none;
  }

  .event-feed__viewport::-webkit-scrollbar {
    display: none;
  }

  .event-feed__track {
    width: max-content;
    animation: none;
    transform: none;
  }

  .event-feed__cycle {
    gap: 24px;
    padding-right: 24px;
  }

  .event-feed__cycle[aria-hidden="true"] {
    display: none;
  }

  .event-feed__event,
  .event-feed__pulse,
  .event-feed__slot {
    animation: none;
  }
}
