/* bracket.css -- the Instant Tournament bracket-tree view.
   Genuinely new: docs/02-DECISIONS.md ADR-009's own comment on
   tournament.css explains why the TEACHER format never grew a tree layout
   (dynamic loss-group pairing has no fixed tree to draw). This one does --
   BracketService's seeded single-elimination math is a real tree, so this
   is the first bracket-shaped component in the app. Palette is tokens.css
   only, no new colors. */

.bracket-champion {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  background: linear-gradient(135deg, rgb(242 179 61 / 0.18), rgb(242 179 61 / 0.02));
  border: 1px solid rgb(242 179 61 / 0.35);
  border-radius: var(--r-lg);
  padding: var(--s-4) var(--s-6);
  margin-bottom: var(--s-6);
}
.bracket-champion__icon { font-size: var(--t-2xl); line-height: 1; }
.bracket-champion strong { color: var(--hit); font-family: var(--f-display); }

/* Your own championship. Same confetti vocabulary duel.css already uses for
   a won race, scaled up -- winning the bracket outranks winning one match. */
.bracket-champion--mine {
  position: relative;
  overflow: hidden;
  border-color: var(--hit);
  box-shadow: 0 0 0 1px var(--hit);
}
.bracket-champion--mine .bracket-champion__icon {
  animation: bracket-trophy-pop 700ms var(--ease);
}
@keyframes bracket-trophy-pop {
  0% { transform: scale(0.6) rotate(-12deg); opacity: 0; }
  60% { transform: scale(1.15) rotate(4deg); opacity: 1; }
  100% { transform: scale(1) rotate(0); }
}
.bracket-champion__confetti {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.bracket-champion__confetti span {
  position: absolute;
  top: -12px;
  width: 7px;
  height: 12px;
  border-radius: 1px;
  opacity: 0;
  animation: bracket-confetti-fall 1600ms var(--ease) forwards;
}
@keyframes bracket-confetti-fall {
  0% { transform: translateY(-12px) rotate(0); opacity: 0; }
  12% { opacity: 1; }
  100% { transform: translateY(180px) rotate(420deg); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .bracket-champion__confetti { display: none; }
  .bracket-champion--mine .bracket-champion__icon { animation: none; }
}

/* "Where am I in this bracket" -- a participant's own status, always in the
   same place regardless of which column their match has scrolled to. */
.bracket-my-status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: var(--s-6);
}
.bracket-my-status__text { color: var(--muted); font-size: var(--t-sm); }

/* It's your turn -- lift the whole card so it reads as the one thing on the
   page that wants attention, not another row of status text. */
.bracket-my-status--live {
  border-color: var(--hit);
  box-shadow: 0 0 0 1px var(--hit);
}
.bracket-my-status__auto {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  color: var(--muted);
  font-size: var(--t-sm);
}
.bracket-my-status__auto b {
  color: var(--hit);
  font-family: var(--f-mono);
}
#myMatchStatus.match-status { margin: 0; font-size: var(--t-sm); color: var(--muted); }
.match-status--urgent { color: var(--hit); font-weight: 600; }

/* ---------- /tournament landing ---------- */

.bracket-intro__lede {
  color: var(--muted);
  max-width: 640px;
}
.bracket-intro__guest {
  max-width: 640px;
  margin: var(--s-4) 0;
}

.bracket-intro {
  display: grid;
  grid-template-columns: minmax(260px, 380px) 1fr;
  gap: var(--s-8);
  align-items: start;
  margin: var(--s-6) 0;
}
/* One column on anything narrow -- the steps read fine stacked under the
   join card, and two cramped columns read worse than one clear one. */
@media (max-width: 720px) {
  .bracket-intro { grid-template-columns: 1fr; }
}

.bracket-intro__join {
  text-align: center;
}
.bracket-intro__join .btn {
  font-size: var(--t-md);
  padding: var(--s-3) var(--s-8);
}
.bracket-intro__hint {
  color: var(--muted);
  font-size: var(--t-xs);
  margin: var(--s-3) 0 0;
}

.bracket-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--s-4);
}
.bracket-steps li {
  display: flex;
  gap: var(--s-4);
  align-items: flex-start;
}
.bracket-steps__num {
  flex: none;
  width: 1.75rem;
  height: 1.75rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgb(242 179 61 / 0.14);
  color: var(--hit);
  font-family: var(--f-mono);
  font-size: var(--t-xs);
}
.bracket-steps strong { color: var(--legend); }
.bracket-steps p {
  margin: var(--s-1) 0 0;
  color: var(--muted);
  font-size: var(--t-sm);
}

/* Wide content scrolls in its own box -- the page body never scrolls
   sideways, same rule every other wide table/diagram in this app follows. */
.bracket-scroll {
  overflow-x: auto;
  padding-bottom: var(--s-2);
}

.bracket {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(190px, 1fr);
  /* Exactly twice the connector stub width (--s-4), so the elbow leaving one
     column and the stub arriving at the next meet in the middle of the gutter
     rather than leaving a break in the line. */
  gap: var(--s-8);
  align-items: stretch;
  min-width: max-content;
}

.bracket-col {
  display: flex;
  flex-direction: column;
}

.bracket-col__label {
  font-family: var(--f-mono);
  font-size: var(--t-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: center;
  margin: 0 0 var(--s-4);
}

/* Which round is live right now -- the bracket columns answer "what bracket
   are we at" on their own, not just via a participant's own status line. */
.bracket-col__live-tag {
  display: inline-block;
  margin-left: var(--s-2);
  padding: 0 var(--s-2);
  border-radius: var(--r-sm);
  background: rgb(94 224 192 / 0.16);
  color: var(--pace);
  font-size: 0.65rem;
  letter-spacing: 0.06em;
  vertical-align: middle;
}
.bracket-col--live .bracket-col__label { color: var(--pace); }

.bracket-col__matches {
  flex: 1;
  display: flex;
  flex-direction: column;
  /* No gap, deliberately: adjacent slots must share an edge or the vertical
     halves of a connector elbow won't meet. Spacing comes from the slots
     themselves being equal-height and centring their card. */
}

/* ---------- the tree ----------
   Each match sits centred in an equal-height "band" (.bracket-slot). Because
   a round always has half the matches of the one before it, a slot in round
   N+1 is exactly twice as tall as -- and vertically centred across -- the two
   slots that feed it. That is the whole trick: the elbows below are drawn
   against the slot box, so the vertical run is always exactly half a slot,
   and no spacing ever has to be measured or hard-coded per round. */
.bracket-slot {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  position: relative;
  /* Roomier than the original 62px: each side now carries a name AND a
     wpm/accuracy line, and cards that touch read as one block instead of
     eight separate matches. */
  min-height: 104px;
  padding: var(--s-2) 0;
}

/* Horizontal stub arriving from the previous round, at this card's centre. */
.bracket-col:not(:first-child) .bracket-slot::before {
  content: '';
  position: absolute;
  right: 100%;
  top: 50%;
  width: var(--s-4);
  border-top: 1px solid var(--plate-hi);
}

/* The elbow leaving toward the next round: a horizontal run at this card's
   centre, then a vertical run to the edge this slot shares with its pair.
   Odd slots reach DOWN, even slots reach UP, so each pair's two halves meet
   and read as one continuous line into the parent match. */
.bracket-col:not(:last-child) .bracket-slot::after {
  content: '';
  position: absolute;
  left: 100%;
  width: var(--s-4);
  border-right: 1px solid var(--plate-hi);
}
.bracket-col:not(:last-child) .bracket-slot:nth-child(odd)::after {
  top: 50%;
  bottom: 0;
  border-top: 1px solid var(--plate-hi);
}
.bracket-col:not(:last-child) .bracket-slot:nth-child(even)::after {
  top: 0;
  bottom: 50%;
  border-bottom: 1px solid var(--plate-hi);
}

/* A lone final-round slot has nothing to pair with -- suppress its elbow so
   it never draws a line into empty space. */
.bracket-col:not(:last-child) .bracket-slot:only-child::after {
  bottom: auto;
  top: 50%;
  height: 0;
  border-right: 0;
}

.bracket-match {
  width: 100%; /* fills its slot -- the slot centres it vertically, not horizontally */
  background: var(--plate);
  border: 1px solid var(--plate-hi);
  border-radius: var(--r-md);
  box-shadow: var(--e-1);
  overflow: hidden;
}

.bracket-match--mine {
  border-color: var(--hit);
  box-shadow: 0 0 0 1px var(--hit), var(--e-1);
}

.bracket-match--pending {
  background: transparent;
  border-style: dashed;
  border-color: var(--plate-hi);
  box-shadow: none;
}

.bracket-match__side {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-3);
  font-size: var(--t-sm);
  color: var(--legend);
}
.bracket-match__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Figures are secondary to the name -- mono so columns line up down the
   card, muted so they never outrank who actually won. */
.bracket-match__stat {
  flex: none;
  font-family: var(--f-mono);
  font-size: var(--t-xs);
  color: var(--muted);
}
.bracket-match__side.is-winner .bracket-match__stat { color: var(--hit); }

/* Why you lost -- only ever rendered under your own match. */
.bracket-match__reason {
  margin: var(--s-2) 0 0;
  padding: var(--s-2) var(--s-3);
  border-left: 2px solid var(--hit);
  background: rgb(242 179 61 / 0.07);
  border-radius: var(--r-sm);
  color: var(--legend);
  font-size: var(--t-xs);
  line-height: 1.5;
}
.bracket-match__side + .bracket-match__side {
  border-top: 1px solid var(--plate-hi);
}

.bracket-match__side.is-winner {
  color: var(--hit);
  font-weight: 600;
}
.bracket-match__side.is-loser {
  color: var(--muted);
}
.bracket-match__side.is-bye {
  color: var(--muted);
  font-style: italic;
}
.bracket-match__side.is-pending {
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: var(--s-2);
}
.bracket-match__trophy {
  opacity: 0.4;
  font-size: var(--t-sm);
}

.bracket-standings {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--s-2);
}
.bracket-standings__row {
  display: flex;
  justify-content: space-between;
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-sm);
  font-size: var(--t-sm);
  color: var(--legend);
}
.bracket-standings__row.is-me {
  background: rgb(94 224 192 / 0.08);
  color: var(--pace);
}
.bracket-standings__row.is-eliminated {
  color: var(--muted);
}
.bracket-standings__status {
  color: var(--muted);
  font-size: var(--t-xs);
}
.bracket-standings__row.is-me .bracket-standings__status { color: var(--pace); }

@media (prefers-reduced-motion: reduce) {
  .bracket-match { transition: none; }
}
