/* Pretendard, SIL Open Font License 1.1 — the licence text ships beside the
   file at /assets/fonts/OFL.txt, as the OFL requires. Self-hosted because the
   site's CSP is font-src 'self'.

   The variable cut rather than static weights: this sheet asks for 500, 700,
   750, 800, 850, 900 and 950, and the four odd ones only exist in a font that
   can interpolate. Static faces would collapse 750 into 700 and 850/950 into
   900, flattening a hierarchy the design leans on. One 2.0MB file covers the
   whole 45–920 range; font-display: swap means text is readable in the
   fallback from the first paint and never blocks on it. */
@font-face {
  font-family: "Pretendard Variable";
  font-weight: 45 920;
  font-style: normal;
  font-display: swap;
  src: url("/assets/fonts/PretendardVariable.woff2") format("woff2");
}

:root {
  color-scheme: light;
  --navy-950: #0a1126;
  --navy-900: #101a35;
  --navy-800: #18264a;
  --blue-700: #214aa8;
  --blue-600: #2d5cc2;
  --blue-100: #e8efff;
  --red-700: #9f2f3f;
  --red-100: #fae9ec;
  --gold-600: #a66a00;
  --gold-400: #e8a928;
  --gold-100: #fff0c7;
  --green-700: #17634e;
  --green-100: #e4f4ed;
  --ink: #172033;
  --muted: #5e687a;
  --line: #d7dce5;
  --line-strong: #b7bfcd;
  --canvas: #f4f1e9;
  --paper: #fffdf9;
  --paper-blue: #f5f8ff;
  --focus: #006fcc;
  --shadow-small: 0 6px 20px rgba(10, 17, 38, 0.08);
  --shadow-card: 0 18px 48px rgba(10, 17, 38, 0.11);
  --radius-small: 0.65rem;
  --radius: 1rem;
  --radius-large: 1.5rem;
  /* Fallback is per character, so this reads: Latin keeps the rounded face
     wherever the platform has one, and Hangul — which no rounded face covers —
     lands on Pretendard everywhere instead of whatever the system happened to
     pick. Noto Sans KR stays behind it for anyone whose font fails to load. */
  font-family:
    ui-rounded,
    "Arial Rounded MT Bold",
    "Pretendard Variable",
    "Noto Sans KR",
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    sans-serif;
  font-synthesis: none;
  line-height: 1.5;
  text-rendering: optimizeLegibility;
}

* {
  box-sizing: border-box;
}

html {
  /* Stated in px on purpose: the narrow breakpoint raises the root font size,
     and a rem floor here would grow with it and force a sideways scroll on a
     320px phone. */
  min-width: 320px;
  background: var(--canvas);
  scroll-behavior: smooth;
}

body {
  min-width: 320px;
  min-height: 100vh;
  margin: 0;
  color: var(--ink);
  /* Korean is written with spaces between words, but the default CJK rule lets
     a line break between any two Hangul syllables — which is why "체크인" was
     splitting as "체 / 크인" and "토너먼트" as "토너 / 먼트". keep-all breaks at
     spaces only; break-word is the escape hatch so a long unbroken token (a SHA,
     a UTC timestamp) still wraps instead of overflowing. */
  word-break: keep-all;
  overflow-wrap: break-word;
  background:
    radial-gradient(circle at 10% 10%, rgba(232, 169, 40, 0.14), transparent 24rem),
    radial-gradient(circle at 90% 22%, rgba(45, 92, 194, 0.09), transparent 28rem),
    var(--canvas);
}

body::before {
  position: fixed;
  z-index: -1;
  inset: 0;
  background-image:
    linear-gradient(rgba(16, 26, 53, 0.025) 1px, transparent 1px),
    linear-gradient(90deg, rgba(16, 26, 53, 0.025) 1px, transparent 1px);
  background-size: 2.25rem 2.25rem;
  content: "";
  pointer-events: none;
}

a {
  color: var(--blue-700);
}

button,
input,
select,
textarea {
  font: inherit;
}

button,
a {
  -webkit-tap-highlight-color: transparent;
}

button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 0.2rem solid var(--focus);
  outline-offset: 0.2rem;
}

button:disabled {
  cursor: wait;
  opacity: 0.66;
}

h1,
h2,
h3,
p,
dl,
dd {
  margin-top: 0;
}

h1,
h2,
h3 {
  line-height: 1.15;
  letter-spacing: -0.035em;
  /* Even out the lines rather than filling the first one and orphaning the
     last word: "다음 승부가 시작되는 / 곳" becomes "다음 승부가 / 시작되는 곳". */
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.25rem, 6vw, 4.8rem);
}

h2 {
  font-size: clamp(1.35rem, 3vw, 2rem);
}

.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

.skip-link {
  position: fixed;
  z-index: 100;
  top: 0.75rem;
  left: 0.75rem;
  padding: 0.75rem 1rem;
  color: white;
  background: var(--navy-950);
  border-radius: var(--radius-small);
  font-weight: 800;
  transform: translateY(-180%);
}

.skip-link:focus {
  transform: translateY(0);
}

.site-header {
  position: sticky;
  z-index: 20;
  top: 0;
  color: white;
  background: rgba(16, 26, 53, 0.98);
  border-bottom: 1px solid rgba(255, 255, 255, 0.13);
  box-shadow: 0 3px 18px rgba(10, 17, 38, 0.16);
}

.header-inner {
  display: flex;
  width: min(74rem, calc(100% - 2rem));
  min-height: 5rem;
  margin: 0 auto;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
}

.brand {
  display: inline-flex;
  min-height: 2.75rem;
  align-items: center;
  gap: 0.7rem;
  color: white;
  text-decoration: none;
}

.brand-picks {
  display: inline-flex;
  align-items: center;
  gap: 0.12rem;
  flex: 0 0 auto;
}

.brand-picks img {
  display: block;
  width: 2.25rem;
  height: 2.25rem;
  object-fit: contain;
  filter: drop-shadow(0 0.18rem 0.16rem rgba(0, 0, 0, 0.3));
}

.brand-wordmark {
  display: inline-flex;
  align-items: baseline;
  gap: 0.38rem;
  line-height: 1;
  white-space: nowrap;
}

.brand strong {
  font-size: 1.12rem;
  letter-spacing: -0.025em;
}

.brand small {
  color: #c9d6f7;
  font-size: 0.7rem;
  font-weight: 850;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.primary-nav {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.primary-nav a {
  min-height: 2.75rem;
  padding: 0.72rem 0.85rem;
  color: #d8e1f6;
  border-radius: 0.7rem;
  font-size: 0.9rem;
  font-weight: 750;
  text-decoration: none;
}

/* Above the phone breakpoint the nav stays the row of full words it has always
   been: there is room for them, and the icon is redundant next to "Notifications". */
.nav-icon,
.nav-label--short {
  display: none;
}

.primary-nav a:hover,
.primary-nav a[aria-current="page"] {
  color: white;
  background: rgba(255, 255, 255, 0.11);
}

.primary-nav a[aria-current="page"] {
  box-shadow: inset 0 -0.18rem 0 var(--gold-400);
}

.header-tools {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.75rem;
}

.language-switcher {
  display: flex;
  padding: 0.2rem;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 999px;
}

.language-switcher button {
  min-width: 2.65rem;
  min-height: 2.35rem;
  padding: 0 0.65rem;
  color: #d8e1f6;
  background: transparent;
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  font-size: 0.72rem;
  font-weight: 850;
  white-space: nowrap;
}

.language-switcher button[aria-pressed="true"] {
  color: var(--navy-950);
  background: white;
}

.session-slot {
  min-width: 5rem;
}

.session-user {
  display: flex;
  align-items: center;
  gap: 0.55rem;
}

.session-avatar {
  display: grid;
  width: 2.3rem;
  height: 2.3rem;
  flex: 0 0 auto;
  place-items: center;
  color: var(--navy-950);
  background: var(--gold-400);
  border-radius: 50%;
  font-weight: 900;
}

.session-copy {
  display: grid;
  max-width: 9rem;
  line-height: 1.2;
}

.session-copy small {
  color: #b8c6e8;
  font-size: 0.62rem;
}

.session-copy strong {
  overflow: hidden;
  font-size: 0.78rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.text-button {
  min-height: 2.75rem;
  padding: 0.4rem 0.65rem;
  color: var(--blue-700);
  background: transparent;
  border: 0;
  border-radius: 0.5rem;
  cursor: pointer;
  font-weight: 800;
  text-decoration: underline;
  text-underline-offset: 0.2rem;
}

.site-header .text-button {
  color: #d8e1f6;
}

.environment-strip {
  display: flex;
  min-height: 2rem;
  padding: 0.35rem 1rem;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  color: #704600;
  background: var(--gold-100);
  border-bottom: 1px solid #e2c673;
  font-size: 0.76rem;
  font-weight: 750;
  text-align: center;
}

.environment-strip > span:first-child {
  color: var(--green-700);
  font-size: 0.65rem;
}

main {
  width: min(74rem, calc(100% - 2rem));
  min-height: 60vh;
  margin: 0 auto;
  padding: 2rem 0 5rem;
}

/* ── Leaving-the-site confirmation ──────────────────────────────────────────
   A native <dialog>, so focus trapping, Esc and inerting the page behind it
   come from the browser rather than from script here. Only the look is set. */

.external-dialog {
  width: min(26rem, calc(100% - 2rem));
  padding: 1.4rem;
  color: var(--ink);
  background: var(--paper);
  border: 0;
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
}

.external-dialog::backdrop {
  background: rgba(10, 17, 38, 0.55);
}

.external-dialog h2 {
  margin: 0 0 0.5rem;
  font-size: 1.15rem;
}

.external-dialog p {
  margin: 0 0 0.75rem;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.5;
}

/* The address is the point of the dialog, so it is shown in full and allowed
   to wrap rather than being cut off mid-host. */
.external-dialog__host {
  padding: 0.55rem 0.7rem;
  color: var(--ink) !important;
  background: var(--paper-blue);
  border: 1px solid var(--line);
  border-radius: var(--radius-small);
  font-weight: 750;
  overflow-wrap: anywhere;
}

.external-dialog__actions {
  display: flex;
  margin-top: 1.1rem;
  justify-content: flex-end;
  gap: 0.5rem;
  flex-wrap: wrap;
}

@media (max-width: 34rem) {
  /* Full-width buttons on a phone, confirm on top so it sits under the thumb. */
  .external-dialog__actions {
    flex-direction: column-reverse;
  }

  .external-dialog__actions .button {
    width: 100%;
    justify-content: center;
  }
}

/* ── Section jump bar ───────────────────────────────────────────────────────
   An event page is a single tall column — the heart ranking alone sits some
   three screens below the fold — so every marked section gets a chip here and
   the bar rides just under the header. app.js builds it from the sections the
   route actually rendered. */

.section-tabs {
  position: sticky;
  z-index: 15;
  top: var(--header-height, 5rem);
  margin: 0 0 1.25rem;
  padding: 0.45rem 0;
  background: rgba(244, 241, 233, 0.97);
  border-bottom: 1px solid var(--line);
}

.section-tabs ul {
  display: flex;
  margin: 0;
  padding: 0;
  gap: 0.3rem;
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}

.section-tabs ul::-webkit-scrollbar {
  display: none;
}

.section-tabs a {
  display: inline-flex;
  min-height: 2.5rem;
  padding: 0 0.85rem;
  align-items: center;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 0.86rem;
  font-weight: 800;
  text-decoration: none;
  white-space: nowrap;
}

.section-tabs a[aria-current="true"] {
  color: white;
  background: var(--navy-900);
  border-color: var(--navy-900);
}

/* Both sticky bars sit above the anchor target, so a jump has to stop short of
   them or it lands with the heading already scrolled underneath. */
[data-section-tab] {
  scroll-margin-top:
    calc(var(--header-height, 5rem) + var(--section-tabs-height, 3rem) + 0.75rem);
}

.loading-panel {
  display: flex;
  min-height: 18rem;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  color: var(--muted);
  font-weight: 700;
}

.loading-dot {
  width: 1rem;
  height: 1rem;
  background: var(--blue-600);
  border: 0.25rem solid var(--blue-100);
  border-radius: 50%;
  box-shadow: 0 0 0 0.15rem var(--blue-600);
  animation: pulse 1.2s ease-in-out infinite;
}

@keyframes pulse {
  50% {
    opacity: 0.38;
    transform: scale(0.85);
  }
}

.app-message {
  position: fixed;
  z-index: 50;
  /* Clears whatever the sticky header and jump bar currently measure, so the
     toast is not hidden behind them when the mobile nav wraps to two rows. */
  top: calc(var(--header-height, 5rem) + var(--section-tabs-height, 0px) + 1rem);
  right: max(1rem, calc((100vw - 74rem) / 2));
  width: min(30rem, calc(100% - 2rem));
  padding: 0.9rem 1rem;
  color: white;
  background: var(--green-700);
  border: 2px solid white;
  border-radius: var(--radius-small);
  box-shadow: var(--shadow-card);
  font-weight: 750;
}

.app-message--error {
  background: var(--red-700);
}

.urgent-notification-popup {
  position: fixed;
  z-index: 70;
  right: max(1rem, calc((100vw - 74rem) / 2));
  bottom: 1rem;
  width: min(31rem, calc(100% - 2rem));
  padding: 1.3rem 3rem 1.3rem 1.3rem;
  color: var(--ink);
  background:
    linear-gradient(135deg, rgba(255, 240, 199, 0.98), rgba(255, 253, 249, 0.99));
  border: 2px solid var(--gold-400);
  border-left: 0.55rem solid var(--red-700);
  border-radius: var(--radius);
  box-shadow: 0 1.4rem 4rem rgba(10, 17, 38, 0.28);
}

.urgent-notification-popup[hidden] {
  display: none;
}

.urgent-notification-popup .eyebrow {
  margin-bottom: 0.45rem;
  color: var(--red-700);
}

.urgent-notification-popup h2 {
  margin-bottom: 0.5rem;
  font-size: 1.4rem;
}

.urgent-notification-popup > p:not(.eyebrow) {
  margin-bottom: 0.9rem;
  color: #3f4758;
}

.urgent-notification-popup__help {
  padding: 0.65rem 0.75rem;
  background: rgba(159, 47, 63, 0.09);
  border-radius: 0.55rem;
  font-size: 0.85rem;
  font-weight: 800;
}

.urgent-notification-popup__dismiss {
  position: absolute;
  top: 0.65rem;
  right: 0.65rem;
  display: grid;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  place-items: center;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.7);
  border: 1px solid #d7c389;
  border-radius: 50%;
  cursor: pointer;
  font-size: 1.35rem;
  line-height: 1;
}

.page-hero {
  display: grid;
  min-height: 24rem;
  padding: clamp(2rem, 6vw, 4.5rem);
  align-items: center;
  grid-template-columns: minmax(0, 1.45fr) minmax(12rem, 0.55fr);
  gap: 2rem;
  color: white;
  background:
    radial-gradient(circle at 84% 18%, rgba(232, 169, 40, 0.35), transparent 13rem),
    linear-gradient(135deg, var(--navy-950), var(--navy-800));
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--radius-large);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}

.page-hero h1 {
  max-width: 46rem;
  margin-bottom: 1.2rem;
}

.page-hero p:not(.eyebrow) {
  max-width: 42rem;
  margin-bottom: 0;
  color: #d8e1f6;
  font-size: clamp(1rem, 2vw, 1.2rem);
}

.eyebrow {
  margin-bottom: 0.65rem;
  color: var(--blue-700);
  font-size: 0.74rem;
  font-weight: 900;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.page-hero .eyebrow {
  color: #f6c75f;
}

.hero-symbols {
  position: relative;
  display: grid;
  min-height: 12rem;
  place-items: center;
}

.hero-symbols::before,
.hero-symbols::after {
  position: absolute;
  width: 11rem;
  height: 11rem;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 50%;
  content: "";
}

.hero-symbols::after {
  width: 8rem;
  height: 8rem;
  background: rgba(255, 255, 255, 0.05);
}

.hero-symbols img {
  position: absolute;
  z-index: 1;
  width: 5.2rem;
  height: 5.2rem;
  object-fit: contain;
  filter: drop-shadow(0 0.75rem 0.8rem rgba(0, 0, 0, 0.25));
}

.hero-symbols img:nth-child(1) {
  transform: translate(-3.7rem, 2.6rem) rotate(-16deg);
}

.hero-symbols img:nth-child(2) {
  transform: translate(3.7rem, 2.6rem) rotate(16deg);
}

.hero-symbols img:nth-child(3) {
  transform: translateY(-3.2rem);
}

.content-section {
  padding: 4rem 0 1.5rem;
}

.section-heading {
  display: flex;
  margin-bottom: 1.3rem;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
}

.section-heading h2 {
  margin-bottom: 0;
}

.count-badge {
  display: grid;
  min-width: 2.4rem;
  min-height: 2.4rem;
  padding: 0.25rem;
  place-items: center;
  color: white;
  background: var(--navy-900);
  border-radius: 999px;
  font-size: 0.9rem;
  font-weight: 900;
}

.event-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
  gap: 1.2rem;
}

.event-card {
  display: flex;
  min-width: 0;
  padding: 1.35rem;
  flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-small);
}

.event-card:hover {
  border-color: var(--line-strong);
  box-shadow: var(--shadow-card);
  transform: translateY(-0.15rem);
}

.event-card__top,
.event-hero__chips {
  display: flex;
  margin-bottom: 1rem;
  flex-wrap: wrap;
  gap: 0.45rem;
}

.status-chip,
.registration-chip,
.priority-chip,
.mode-badge,
.version-badge {
  display: inline-flex;
  min-height: 1.75rem;
  padding: 0.28rem 0.58rem;
  align-items: center;
  color: var(--blue-700);
  background: var(--blue-100);
  border: 1px solid #c3d3fa;
  border-radius: 999px;
  font-size: 0.69rem;
  font-weight: 900;
  letter-spacing: 0.035em;
  line-height: 1.2;
  text-transform: uppercase;
}

.registration-chip {
  color: var(--muted);
  background: #f0f2f6;
  border-color: var(--line);
}

.status-chip--completed,
.status-chip--registered,
.status-chip--in_progress {
  color: var(--green-700);
  background: var(--green-100);
  border-color: #abd8c8;
}

.status-chip--cancelled {
  color: var(--red-700);
  background: var(--red-100);
  border-color: #e7bbc2;
}

/* Missing the bracket is not a mistake the participant made, so it borrows the
   same red as a cancellation rather than getting a louder treatment of its
   own. The card carries one chip and one short explanation; there is no third
   place that repeats it. */
.registration-chip--excluded {
  color: var(--red-700);
  background: var(--red-100);
  border-color: #e7bbc2;
}

.status-chip--check_in,
.status-chip--waitlisted,
.status-chip--registration_open {
  color: #755000;
  background: var(--gold-100);
  border-color: #e2c673;
}

.event-card__copy {
  flex: 1;
}

.event-card h3 {
  margin-bottom: 0.7rem;
  font-size: 1.35rem;
}

.event-card h3 a {
  color: var(--ink);
  text-decoration: none;
}

.event-card h3 a:hover {
  color: var(--blue-700);
  text-decoration: underline;
  text-underline-offset: 0.2rem;
}

.event-card__copy p {
  color: var(--muted);
  line-height: 1.65;
}

.event-card__schedule,
.compact-times {
  margin: 0.4rem 0 1rem;
  padding: 0.85rem 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.time-row {
  display: grid;
  padding: 0.45rem 0;
  grid-template-columns: minmax(6.5rem, 0.7fr) minmax(0, 1.3fr);
  gap: 0.75rem;
}

.time-row dt {
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 750;
}

.time-row dd {
  min-width: 0;
  font-size: 0.84rem;
  font-weight: 800;
}

.time-row dd small {
  display: block;
  margin-top: 0.25rem;
  color: var(--muted);
  font-size: 0.66rem;
  font-weight: 500;
  overflow-wrap: anywhere;
}

.capacity-meter {
  height: 0.4rem;
  overflow: hidden;
  background: var(--line);
  border-radius: 999px;
}

.capacity-meter progress {
  appearance: none;
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  background: var(--line);
}

.capacity-meter progress::-webkit-progress-bar {
  background: var(--line);
}

.capacity-meter progress::-webkit-progress-value {
  background: linear-gradient(90deg, var(--blue-600), var(--gold-400));
}

.capacity-meter progress::-moz-progress-bar {
  background: linear-gradient(90deg, var(--blue-600), var(--gold-400));
}

.capacity-copy {
  margin: 0.45rem 0 1rem;
  color: var(--muted);
  font-size: 0.78rem;
}

.capacity-next {
  display: grid;
  margin: 0 0 1rem;
  gap: 0.2rem;
  color: var(--blue-700);
  font-size: 0.76rem;
}

.capacity-next strong {
  font-size: 0.8rem;
}

.capacity-next span {
  color: var(--muted);
}

.card-link {
  display: inline-flex;
  min-height: 2.75rem;
  align-items: center;
  align-self: flex-start;
  font-weight: 850;
  text-underline-offset: 0.2rem;
}

.button {
  display: inline-flex;
  min-height: 2.85rem;
  padding: 0.65rem 1rem;
  align-items: center;
  justify-content: center;
  border: 1px solid transparent;
  border-radius: 0.75rem;
  cursor: pointer;
  font-weight: 850;
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
}

.button:hover:not(:disabled) {
  transform: translateY(-0.1rem);
}

.button--primary {
  color: white;
  background: var(--blue-700);
  border-color: var(--blue-700);
  box-shadow: 0 0.55rem 1.2rem rgba(33, 74, 168, 0.2);
}

.button--primary:hover:not(:disabled) {
  background: #193b8a;
}

.button--secondary,
.button--light {
  color: var(--ink);
  background: var(--paper);
  border-color: var(--line-strong);
}

.button--danger {
  color: white;
  background: var(--red-700);
  border-color: var(--red-700);
}

.button--danger:hover:not(:disabled) {
  background: #7d2331;
}

.button--small {
  min-height: 2.4rem;
  padding: 0.45rem 0.75rem;
  font-size: 0.78rem;
}

.auth-card,
.registration-panel,
.policy-callout,
.admin-overview,
.danger-zone,
.result-panel {
  margin-top: 2rem;
  padding: clamp(1.25rem, 4vw, 2rem);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-small);
}

.auth-card {
  display: grid;
  align-items: center;
  grid-template-columns: minmax(0, 0.85fr) minmax(16rem, 1.15fr);
  gap: 2rem;
}

.card-heading h2 {
  margin-bottom: 0.65rem;
}

.card-heading p {
  margin-bottom: 0;
  color: var(--muted);
}

.mode-badge {
  margin-bottom: 0.8rem;
  color: #755000;
  background: var(--gold-100);
  border-color: #e2c673;
}

.stack-form,
.registration-form {
  display: grid;
  gap: 0.75rem;
}

label,
legend {
  font-weight: 800;
}

input:not([type="checkbox"]),
select,
textarea {
  width: 100%;
  min-height: 2.9rem;
  padding: 0.65rem 0.75rem;
  color: var(--ink);
  background: white;
  border: 1px solid var(--line-strong);
  border-radius: 0.65rem;
}

input:not([type="checkbox"]):hover,
select:hover,
textarea:hover {
  border-color: var(--blue-600);
}

.field-help,
.subtle {
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.55;
}

.google-placeholder {
  display: grid;
  min-height: 6rem;
  padding: 1rem;
  justify-items: center;
  align-items: center;
  gap: 0.75rem;
  text-align: center;
  background: var(--paper-blue);
  border: 1px dashed var(--line-strong);
  border-radius: 0.75rem;
}

.google-placeholder p {
  margin: 0;
  color: var(--muted);
  font-size: 0.85rem;
}

/* ── Google sign-in button ──────────────────────────────────────────────────
   Google Identity Services renders its button, then styles it from a second
   request to accounts.google.com/gsi/style. Between the two the raw markup is
   on screen — an oversized logo and the accessible "opens in a new tab" label
   showing next to the visible one — and the card jumps 35px when the sheet
   lands. Waiting for the sheet is not ours to do, so nothing of Google's is
   shown at all: our own face fills the slot on first paint and Google's real
   button sits invisibly on top of it, taking the click.

   This is the arrangement the Main site settled on for the same symptom
   (js/net/socialAuth.js, css/components/google-button.css, 2026-07-11).

   The slot is the fixed frame both layers fill, so the card's height never
   depends on what Google has or has not rendered yet. */
.g-oauth-slot {
  position: relative;
  width: min(20rem, 100%);
  height: 2.75rem;
  overflow: hidden;
  border-radius: 999px;
}

.g-oauth__face {
  position: absolute;
  z-index: 1;
  inset: 0;
  display: flex;
  padding: 0 1rem;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  color: white;
  background: var(--blue-700);
  border-radius: 999px;
  font-size: 0.95rem;
  font-weight: 800;
  overflow: hidden;
  white-space: nowrap;
  /* The click belongs to the invisible Google button above. */
  pointer-events: none;
}

.g-oauth__mark {
  display: grid;
  width: 1.5rem;
  height: 1.5rem;
  flex: 0 0 auto;
  place-items: center;
  background: white;
  border-radius: 50%;
}

.g-oauth__mark svg {
  display: block;
  width: 62%;
  height: 62%;
}

/* Google's button, invisible but real: opacity rather than visibility so it
   still takes the tap and still carries its own accessible name. It renders
   narrower and shorter than the pill it covers, so it is scaled up until the
   whole face is live — the slot's overflow clips the excess, and a transform
   costs no layout, so nothing moves. */
.g-oauth__gis {
  position: absolute;
  z-index: 2;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.001;
  transform: scale(1.25, 1.6);
  transform-origin: center;
}

.google-mark {
  display: grid;
  width: 2.8rem;
  height: 2.8rem;
  flex: 0 0 auto;
  place-items: center;
  color: var(--blue-700);
  background: white;
  border: 1px solid var(--line);
  border-radius: 50%;
  font-size: 1.3rem;
  font-weight: 900;
}

.policy-callout {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  background: var(--gold-100);
  border-color: #e2c673;
}

.policy-callout--compact {
  margin: 1.3rem 0;
}

.policy-callout--excluded {
  background: var(--red-100);
  border-color: #e7bbc2;
}

.policy-callout--excluded .policy-callout__icon {
  background: var(--red-700);
}

.policy-callout--excluded p {
  color: #6d2b36;
}

.policy-callout__icon {
  display: grid;
  width: 2.6rem;
  height: 2.6rem;
  flex: 0 0 auto;
  place-items: center;
  color: white;
  background: var(--green-700);
  border-radius: 50%;
  font-weight: 900;
}

.policy-callout h2 {
  margin-bottom: 0.45rem;
  font-size: 1.05rem;
  letter-spacing: -0.02em;
}

.policy-callout p {
  margin-bottom: 0;
  color: #5e470f;
}

.empty-panel,
.state-panel {
  display: grid;
  min-height: 16rem;
  padding: 2rem;
  place-items: center;
  align-content: center;
  gap: 0.8rem;
  background: rgba(255, 253, 249, 0.7);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
  text-align: center;
}

.empty-panel > span {
  font-size: 2.5rem;
}

.empty-pick-mark {
  display: block;
  width: 3rem;
  height: 3rem;
  object-fit: contain;
  filter: drop-shadow(0 0.3rem 0.35rem rgba(10, 17, 38, 0.16));
}

.empty-panel p,
.state-panel p {
  max-width: 34rem;
  margin: 0;
  color: var(--muted);
}

.empty-panel--compact {
  min-height: 9rem;
}

.state-panel h1 {
  margin: 0;
  font-size: clamp(1.8rem, 5vw, 3rem);
}

.state-icon {
  display: grid;
  width: 3.5rem;
  height: 3.5rem;
  place-items: center;
  color: white;
  background: var(--blue-700);
  border-radius: 50%;
  font-size: 1.7rem;
  font-weight: 900;
}

.state-panel--error .state-icon {
  background: var(--red-700);
}

.breadcrumb {
  margin-bottom: 1rem;
}

.breadcrumb a {
  display: inline-flex;
  min-height: 2.75rem;
  align-items: center;
  gap: 0.45rem;
  font-weight: 800;
  text-underline-offset: 0.2rem;
}

.event-hero {
  display: flex;
  min-height: 18rem;
  padding: clamp(1.5rem, 5vw, 3.25rem);
  align-items: flex-end;
  justify-content: space-between;
  gap: 2rem;
  color: white;
  background:
    radial-gradient(circle at 90% 15%, rgba(232, 169, 40, 0.32), transparent 14rem),
    linear-gradient(135deg, var(--navy-950), var(--navy-800));
  border-radius: var(--radius-large);
  box-shadow: var(--shadow-card);
}

.event-hero > div {
  max-width: 48rem;
}

.event-hero h1 {
  margin-bottom: 1rem;
  font-size: clamp(2.1rem, 6vw, 4.3rem);
}

.event-hero p {
  color: #d8e1f6;
  font-size: 1.05rem;
  line-height: 1.7;
}

.event-hero .prize-summary {
  display: inline-flex;
  margin-bottom: 0;
  padding: 0.65rem 0.85rem;
  align-items: center;
  gap: 0.45rem;
  color: #ffe8ae;
  background: rgba(0, 0, 0, 0.22);
  border-radius: 0.65rem;
  font-size: 0.9rem;
}

.detail-grid,
.policy-grid {
  display: grid;
  margin-top: 1.3rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.3rem;
}

.detail-card,
.policy-document {
  min-width: 0;
  padding: clamp(1.2rem, 3vw, 1.6rem);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-small);
}

.detail-card__heading {
  display: flex;
  margin-bottom: 0.8rem;
  align-items: center;
  gap: 0.65rem;
}

.detail-card__heading > span {
  display: grid;
  width: 2.3rem;
  height: 2.3rem;
  flex: 0 0 auto;
  place-items: center;
  color: var(--blue-700);
  background: var(--blue-100);
  border-radius: 50%;
  font-size: 1.15rem;
  font-weight: 900;
}

.detail-card__heading h2 {
  margin: 0;
  font-size: 1.2rem;
}

.schedule-list {
  margin-bottom: 0;
}

.schedule-list .time-row + .time-row {
  border-top: 1px solid var(--line);
}

.stat-grid {
  display: grid;
  margin-bottom: 0.8rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 7rem), 1fr));
  gap: 0.7rem;
}

.stat-grid > div {
  padding: 0.8rem;
  background: var(--paper-blue);
  border: 1px solid #dce5fa;
  border-radius: 0.7rem;
}

.stat-grid dt {
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 750;
}

.stat-grid dd {
  margin: 0.15rem 0 0;
  font-size: 1.35rem;
  font-weight: 900;
}

.stat-grid--compact {
  margin: 1rem 0 0;
}

.policy-document__heading {
  display: flex;
  margin-bottom: 1rem;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.8rem;
}

.policy-document__heading h2 {
  margin-bottom: 0;
  font-size: 1.35rem;
}

.version-badge {
  flex: 0 0 auto;
  color: var(--muted);
  background: #f0f2f6;
  border-color: var(--line);
  text-transform: none;
}

.policy-document pre {
  min-height: 10rem;
  margin: 0;
  padding: 1rem;
  overflow: visible;
  color: var(--ink);
  background: #f8f6f0;
  border: 1px solid var(--line);
  border-radius: 0.7rem;
  font: inherit;
  line-height: 1.7;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
  word-break: break-word;
}

.policy-meta {
  margin: 0.75rem 0 0;
  color: var(--muted);
  font-size: 0.72rem;
}

.bracket-section {
  margin-top: 2rem;
  padding: clamp(1.15rem, 3vw, 1.6rem);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-small);
}

.champion-card {
  display: flex;
  width: fit-content;
  margin-bottom: 1rem;
  padding: 0.75rem 1rem;
  align-items: center;
  gap: 0.75rem;
  color: #5e3d00;
  background: var(--gold-100);
  border: 1px solid #e2c673;
  border-radius: 0.75rem;
}

.champion-card > span {
  font-size: 2rem;
}

.champion-card > div {
  display: grid;
}

.champion-card small {
  font-size: 0.7rem;
  font-weight: 750;
}

.champion-card strong {
  font-size: 1.05rem;
}

.placement-panel {
  position: relative;
  isolation: isolate;
  margin-bottom: 1.25rem;
  padding: clamp(1.25rem, 3vw, 2rem);
  overflow: hidden;
  color: white;
  background:
    radial-gradient(
      circle at 50% -30%,
      rgba(255, 213, 95, 0.34),
      transparent 48%
    ),
    linear-gradient(145deg, #101a35 0%, #172b59 58%, #101a35 100%);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 1.1rem;
  box-shadow: 0 1rem 2.4rem rgba(16, 26, 53, 0.2);
}

.placement-panel::before {
  position: absolute;
  z-index: -1;
  inset: 0;
  background-image:
    linear-gradient(
      115deg,
      transparent 0 42%,
      rgba(255, 255, 255, 0.035) 42% 43%,
      transparent 43% 100%
    );
  background-size: 4.5rem 4.5rem;
  content: "";
  pointer-events: none;
}

.placement-panel h3 {
  margin: 0 0 1.45rem;
  color: white;
  font-size: clamp(1.05rem, 2.4vw, 1.4rem);
  letter-spacing: -0.02em;
  text-align: center;
}

.placement-panel__list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: end;
  gap: clamp(0.65rem, 2vw, 1rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.placement-panel__entry {
  display: flex;
  position: relative;
  min-width: 0;
  min-height: 9rem;
  padding: 1.15rem 0.85rem 1rem;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 0.9rem;
  background: linear-gradient(
    160deg,
    rgba(255, 255, 255, 0.17),
    rgba(255, 255, 255, 0.07)
  );
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 1rem;
  box-shadow: 0 0.8rem 1.5rem rgba(3, 9, 25, 0.24);
  text-align: center;
  backdrop-filter: blur(0.3rem);
}

.placement-panel__entry--champion {
  grid-column: 2;
  min-height: 11rem;
  padding-top: 1.35rem;
  background:
    radial-gradient(
      circle at 50% 0,
      rgba(255, 255, 255, 0.46),
      transparent 42%
    ),
    linear-gradient(160deg, #ffe9a8, #dcae3f);
  border-color: #fff0b4;
  box-shadow:
    0 1rem 2rem rgba(3, 9, 25, 0.34),
    0 0 1.8rem rgba(255, 207, 79, 0.28);
  color: #493000;
  transform: translateY(-0.65rem);
}

.placement-panel__entry--runner_up {
  grid-column: 1;
  grid-row: 1;
  background: linear-gradient(
    160deg,
    rgba(238, 245, 255, 0.32),
    rgba(181, 197, 225, 0.14)
  );
}

.placement-panel__entry--shared_third {
  grid-column: 3;
  grid-row: 1;
  min-height: 8.25rem;
  background: linear-gradient(
    160deg,
    rgba(236, 170, 116, 0.3),
    rgba(154, 91, 46, 0.13)
  );
}

.placement-panel__medal {
  display: grid;
  position: relative;
  width: 3.45rem;
  height: 3.45rem;
  flex: 0 0 auto;
  place-items: center;
  color: #5b3a00;
  background: linear-gradient(145deg, #fff4bd, #e5b53b);
  border: 0.22rem solid rgba(255, 255, 255, 0.8);
  border-radius: 50%;
  box-shadow:
    0 0.35rem 0.8rem rgba(3, 9, 25, 0.3),
    inset 0 -0.25rem 0.45rem rgba(109, 66, 0, 0.18);
}

.placement-panel__medal::before,
.placement-panel__medal::after {
  position: absolute;
  z-index: -1;
  top: 2.6rem;
  width: 0.85rem;
  height: 1.4rem;
  background: #d49b24;
  clip-path: polygon(0 0, 100% 0, 86% 100%, 50% 74%, 14% 100%);
  content: "";
}

.placement-panel__medal::before {
  left: 0.55rem;
  transform: rotate(9deg);
}

.placement-panel__medal::after {
  right: 0.55rem;
  transform: rotate(-9deg);
}

.placement-panel__entry--champion .placement-panel__medal {
  width: 4.1rem;
  height: 4.1rem;
  color: #4b2d00;
  background: linear-gradient(145deg, #fff8cc, #efbd35);
  box-shadow:
    0 0.4rem 1rem rgba(73, 43, 0, 0.36),
    0 0 1.2rem rgba(255, 255, 255, 0.5);
}

.placement-panel__entry--runner_up .placement-panel__medal {
  color: #37435a;
  background: linear-gradient(145deg, #fff, #aebbd0);
}

.placement-panel__entry--runner_up .placement-panel__medal::before,
.placement-panel__entry--runner_up .placement-panel__medal::after {
  background: #8999b4;
}

.placement-panel__entry--shared_third .placement-panel__medal {
  color: #4e2b16;
  background: linear-gradient(145deg, #ffd4ad, #b96f3d);
}

.placement-panel__entry--shared_third .placement-panel__medal::before,
.placement-panel__entry--shared_third .placement-panel__medal::after {
  background: #a86034;
}

/* A shared rank cannot be one face, so its medal shows the number — and it
   carries the whole meaning there, so it is set as large as the circle allows. */
.placement-panel__rank {
  font-size: 1.9rem;
  font-weight: 950;
  line-height: 1;
}

.placement-panel__entry--champion .placement-panel__rank {
  font-size: 2.4rem;
}

/* A single winner's medal is their own face instead. */
.placement-panel__face {
  font-size: 1.85rem;
  line-height: 1;
}

.placement-panel__entry--champion .placement-panel__face {
  font-size: 2.35rem;
}

/* Only ever beside a shared rank, where it says which of the two names this
   is. Set at the name's own size so it reads as part of the line rather than a
   badge, with room so it never touches the first letter. */
.placement-panel__name-face {
  margin-right: 0.35rem;
  font-size: 1em;
}

.placement-panel__copy {
  display: grid;
  gap: 0.3rem;
  min-width: 0;
}

.placement-panel__entry small {
  color: rgba(255, 255, 255, 0.72);
  font-size: 0.7rem;
  font-weight: 850;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.placement-panel__entry--champion small {
  color: rgba(73, 48, 0, 0.72);
}

.placement-panel__names {
  display: grid;
  gap: 0.32rem;
  min-width: 0;
}

.placement-panel__names strong {
  overflow: hidden;
  font-size: clamp(0.88rem, 2vw, 1.05rem);
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.placement-panel__entry--champion .placement-panel__names strong {
  font-size: clamp(1.05rem, 2.3vw, 1.25rem);
}

.placement-panel__entry--shared_third
  .placement-panel__names strong + strong {
  padding-top: 0.32rem;
  border-top: 1px solid rgba(255, 255, 255, 0.18);
}

.bracket-stage-tabs {
  display: flex;
  max-width: 100%;
  margin: 0 0 0.9rem;
  padding: 0.2rem 0.1rem 0.55rem;
  gap: 0.45rem;
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scrollbar-width: thin;
}

.bracket-stage-tab {
  flex: 0 0 auto;
  padding: 0.55rem 0.85rem;
  color: var(--muted);
  background: white;
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  font-size: 0.78rem;
  font-weight: 800;
}

.bracket-stage-tab:hover {
  color: var(--blue-700);
  border-color: var(--blue-600);
}

.bracket-stage-tab[aria-selected="true"] {
  color: white;
  background: var(--blue-700);
  border-color: var(--blue-700);
}

/* Double elimination runs two ladders at once, and the stage tabs interleave
   them (winners 1, losers 1, winners 2, ...). Without a colour the strip reads
   as one long sequence and a competitor cannot tell which ladder a round
   belongs to. Colour is carried on the border and text so the section stays
   legible in the selected state too, where the fill is already spoken for.
   Single-elimination brackets have no section and keep the plain styling. */
.bracket-stage-tab--winners {
  color: var(--green-700);
  border-color: var(--green-700);
}

.bracket-stage-tab--losers {
  color: var(--red-700);
  border-color: var(--red-700);
}

.bracket-stage-tab--grand_final {
  color: var(--blue-700);
  border-color: var(--blue-700);
}

.bracket-stage-tab--winners[aria-selected="true"] {
  color: white;
  background: var(--green-700);
  border-color: var(--green-700);
}

.bracket-stage-tab--losers[aria-selected="true"] {
  color: white;
  background: var(--red-700);
  border-color: var(--red-700);
}

.bracket-stage-tab--grand_final[aria-selected="true"] {
  color: white;
  background: var(--blue-700);
  border-color: var(--blue-700);
}

/* The band above the round title. It names the ladder and, more usefully,
   what losing this round costs — that is the part of double elimination
   nobody guesses correctly the first time. */
.bracket-section-band {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0 0 0.5rem;
  padding: 0.4rem 0.65rem;
  border-radius: 0.5rem;
  border-left: 0.3rem solid var(--line);
  font-size: 0.74rem;
}

.bracket-section-band--winners {
  background: var(--green-100);
  border-left-color: var(--green-700);
}

.bracket-section-band--losers {
  background: var(--red-100);
  border-left-color: var(--red-700);
}

.bracket-section-band--grand_final {
  background: #eaf0fb;
  border-left-color: var(--blue-700);
}

.bracket-section-band__name {
  font-weight: 800;
  letter-spacing: 0.01em;
}

.bracket-section-band--winners .bracket-section-band__name {
  color: var(--green-700);
}

.bracket-section-band--losers .bracket-section-band__name {
  color: var(--red-700);
}

.bracket-section-band--grand_final .bracket-section-band__name {
  color: var(--blue-700);
}

.bracket-section-band__hint {
  color: var(--muted);
  font-weight: 600;
}

/* The series length, said once for the round on screen. The match rows never
   repeat it — no box, no rule, just a quiet line under the round selector.
   The negative top margin pulls it into the space .bracket-stage-tabs already
   reserves below itself, so it reads as attached to the selector. */
.bracket-series {
  margin: -0.35rem 0 0.8rem;
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.bracket-series[hidden] {
  display: none;
}

/* Inner vertical scrolling is removed site-wide (operator request
   2026-07-30): tall content expands and the browser scrollbar stays the
   only vertical scrollbar. Do not reintroduce max-height + overflow-y on
   content regions. */
.bracket-stage-viewport {
  padding: 0.2rem 0.45rem 0.8rem 0.2rem;
}

.bracket-round {
  width: 100%;
  min-width: 0;
}

.bracket-round[hidden] {
  display: none;
}

.bracket-round > h3 {
  position: sticky;
  z-index: 1;
  top: -0.2rem;
  margin-top: 0;
  padding-bottom: 0.6rem;
  color: var(--muted);
  background: var(--paper);
  border-bottom: 2px solid var(--blue-100);
  font-size: 0.9rem;
  letter-spacing: 0;
}

.bracket-match-list {
  display: grid;
  margin: 0;
  padding: 0;
  align-content: start;
  gap: 0.8rem;
  list-style: none;
}

.bracket-match {
  min-width: 0;
  padding: 0.55rem 0.6rem 0.6rem;
  background: white;
  border: 1px solid #d3dcf2;
  border-radius: 0.6rem;
  box-shadow: 0 1px 2px rgb(16 26 56 / 6%);
}

.bracket-match__heading {
  display: flex;
  margin-bottom: 0.45rem;
  justify-content: space-between;
  gap: 0.6rem;
  color: var(--muted);
  font-size: 0.65rem;
  font-weight: 750;
  text-transform: uppercase;
}

.match-status {
  overflow: hidden;
  text-align: right;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bracket-player {
  display: grid;
  min-height: 2.6rem;
  padding: 0.4rem 0.45rem;
  align-items: center;
  grid-template-columns: 1.4rem minmax(0, 1fr) auto;
  gap: 0.4rem;
  background: var(--paper);
  border: 1px solid var(--line);
}

.bracket-player + .bracket-player {
  border-top: 0;
}

.bracket-player:first-of-type {
  border-radius: 0.5rem 0.5rem 0 0;
}

.bracket-player:last-child {
  border-radius: 0 0 0.5rem 0.5rem;
}

.bracket-player--winner {
  color: var(--green-700);
  background: var(--green-100);
  border-color: #abd8c8;
}

.bracket-player--pending {
  color: var(--muted);
  font-size: 0.76rem;
  font-style: italic;
}

.bracket-player__identity {
  display: grid;
  min-width: 0;
  gap: 0.3rem;
}

.bracket-player__identity > strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bracket-player__meta {
  display: flex;
  min-width: 0;
  flex-wrap: wrap;
  gap: 0.25rem;
}

.participant-badge {
  display: inline-flex;
  min-height: 1.25rem;
  padding: 0.14rem 0.4rem;
  align-items: center;
  gap: 0.25rem;
  color: var(--muted);
  background: #eef0f4;
  border-radius: 999px;
  font-size: 0.62rem;
  font-style: normal;
  font-weight: 750;
  line-height: 1.25;
}

.participant-badge--online,
.participant-badge--ready {
  color: var(--green-700);
  background: var(--green-100);
}

.participant-badge--offline,
.participant-badge--waiting {
  color: var(--muted);
  background: #eceef2;
}

.participant-badge--health {
  color: #704800;
  background: var(--gold-100);
}

.participant-badge--excluded {
  color: var(--red-700);
  background: var(--red-100);
}

.participant-badge--pick {
  color: var(--blue-700);
  background: var(--blue-100);
}

.presence-dot {
  width: 0.42rem;
  height: 0.42rem;
  background: currentColor;
  border-radius: 50%;
}

.bracket-seed {
  display: grid;
  place-items: center;
  color: var(--muted);
  background: #eef1f8;
  border-right: 1px solid #dde4f5;
  font-size: 0.68rem;
  font-style: normal;
  font-weight: 850;
}

.winner-mark {
  color: var(--green-700);
  font-weight: 900;
}

.bracket-match__details {
  display: flex;
  margin-top: 0.55rem;
  padding-top: 0.5rem;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.35rem 0.75rem;
  color: var(--muted);
  border-top: 1px dashed var(--line);
  font-size: 0.68rem;
}

.bracket-match--viewer {
  border-color: var(--gold-400);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--gold-400) 35%, transparent);
}

.bracket-match__details > span {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}

.match-countdown {
  min-width: 3.2rem;
  color: var(--red-700);
  font-variant-numeric: tabular-nums;
}

.registration-countdown {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  color: var(--muted);
  font-size: 0.78rem;
}

.registration-countdown strong {
  color: var(--red-700);
  font-variant-numeric: tabular-nums;
}

.match-spectate-link {
  margin-left: auto;
  font-weight: 850;
  text-decoration: none;
}

.match-spectate-link:hover {
  text-decoration: underline;
}

.match-join-button {
  margin-left: auto;
}

.participant-presence {
  margin-top: 1.25rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
}

.participant-presence h3 {
  margin: 0;
  font-size: 1.05rem;
}

.participant-presence__list {
  display: grid;
  margin: 0.75rem 0 0;
  padding: 0 0.35rem 0 0;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  gap: 0.4rem;
  list-style: none;
}

.participant-presence__entry {
  display: grid;
  min-width: 0;
  padding: 0.55rem 0.65rem;
  align-items: center;
  grid-template-columns: 2rem minmax(0, 1fr) auto;
  gap: 0.5rem;
  background: white;
  border: 1px solid var(--line);
  border-radius: 0.6rem;
}

.participant-presence__entry > strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.participant-presence__order {
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 850;
  text-align: center;
}

.health-ranking {
  margin-top: 1.25rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
}

.health-ranking h3 {
  margin: 0;
  font-size: 1.05rem;
}

.health-ranking__list {
  display: grid;
  margin: 0.75rem 0 0;
  padding: 0 0.35rem 0 0;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  gap: 0.4rem;
  list-style: none;
}

.health-ranking__entry {
  display: grid;
  min-width: 0;
  padding: 0.55rem 0.65rem;
  align-items: center;
  grid-template-columns: 2rem minmax(0, 1fr) auto auto;
  gap: 0.5rem;
  background: white;
  border: 1px solid var(--line);
  border-radius: 0.6rem;
}

/* Keep every semantic column explicit. If the optional face were simply
   omitted from one five-column grid, auto-placement would move the name into
   the face column and stretch the health cell across the flexible name track. */
.health-ranking__entry--with-face {
  grid-template-columns: 2rem auto minmax(0, 1fr) auto auto;
}

.health-ranking__entry--excluded {
  color: var(--muted);
  background: #f5f5f6;
}

.health-ranking__rank {
  grid-column: 1;
  color: var(--blue-700);
  font-weight: 900;
  text-align: center;
}

.health-ranking__face {
  grid-column: 2;
  font-size: 1.35rem;
  line-height: 1;
}

.health-ranking__entry > strong {
  grid-column: 2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.health-ranking__entry--with-face > strong {
  grid-column: 3;
}

.health-ranking__health {
  display: inline-flex;
  grid-column: 3;
  align-items: center;
  gap: 0.25rem;
  color: #704800;
  font-size: 0.75rem;
  font-weight: 800;
}

.health-ranking__entry--with-face > .health-ranking__health {
  grid-column: 4;
}

.health-ranking__entry > .participant-badge {
  grid-column: 4;
}

.health-ranking__entry--with-face > .participant-badge {
  grid-column: 5;
}

.announcement-archive,
.chat-panel {
  margin-top: 1.25rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
}

.announcement-archive h3,
.chat-panel h3 {
  margin: 0;
  font-size: 1.05rem;
}

.announcement-list,
.chat-message-list {
  display: grid;
  margin: 0.75rem 0 0;
  padding: 0 0.35rem 0 0;
  gap: 0.45rem;
  list-style: none;
}

.announcement-list li,
.chat-message {
  min-width: 0;
  padding: 0.65rem 0.75rem;
  background: white;
  border: 1px solid var(--line);
  border-radius: 0.6rem;
}

.announcement-list p,
.chat-message p {
  margin: 0;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

.announcement-list time,
.chat-message__meta time {
  color: var(--muted);
  font-size: 0.65rem;
}

.announcement-list time {
  display: block;
  margin-top: 0.35rem;
}

.chat-panel__heading,
.chat-message__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.65rem;
}

.chat-message__meta {
  margin-bottom: 0.3rem;
}

.chat-message__meta strong {
  min-width: 0;
  overflow: hidden;
  font-size: 0.78rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chat-message__meta time {
  flex: 0 0 auto;
  text-align: right;
}

.chat-message p {
  font-size: 0.82rem;
}

.chat-message__actions,
.chat-block-list {
  margin-top: 0.45rem;
  color: var(--muted);
  font-size: 0.7rem;
}

.chat-message__actions > summary,
.chat-block-list > summary {
  width: max-content;
  cursor: pointer;
  font-weight: 800;
}

.chat-message__actions > div {
  display: flex;
  margin-top: 0.35rem;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.chat-message__actions button,
.chat-block-list button {
  min-height: 1.8rem;
  padding: 0.2rem 0.45rem;
  color: var(--blue-700);
  background: #f6f8ff;
  border: 1px solid var(--line);
  border-radius: 0.4rem;
  cursor: pointer;
  font-size: 0.68rem;
  font-weight: 800;
}

.chat-block-list ul {
  display: grid;
  margin: 0.4rem 0 0;
  padding: 0;
  gap: 0.3rem;
  list-style: none;
}

.chat-block-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.chat-empty {
  padding: 0.85rem;
  color: var(--muted);
  background: #f7f7f5;
  border: 1px dashed var(--line-strong);
  border-radius: 0.6rem;
  font-size: 0.78rem;
  text-align: center;
}

.chat-form {
  display: grid;
  margin-top: 0.75rem;
  align-items: end;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.55rem;
}

.chat-form textarea {
  min-height: 3.25rem;
  max-height: 10rem;
  resize: vertical;
}

.chat-panel__notice {
  margin: 0.75rem 0 0;
  color: var(--muted);
  font-size: 0.76rem;
}

.match-chat {
  margin-top: 0.6rem;
  border-top: 1px dashed var(--line);
}

.match-chat > summary {
  display: flex;
  min-height: 2.4rem;
  padding: 0.55rem 0.2rem 0;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  color: var(--blue-700);
  cursor: pointer;
  font-size: 0.74rem;
  font-weight: 850;
}

.match-chat .count-badge {
  min-width: 1.55rem;
  min-height: 1.55rem;
  font-size: 0.66rem;
}

.match-chat .chat-panel {
  margin-top: 0.45rem;
  padding: 0.65rem;
  background: white;
  border: 1px solid var(--line);
  border-radius: 0.6rem;
}

.match-chat .chat-panel__heading {
  display: none;
}

.match-chat .chat-message-list {
  margin-top: 0;
}

.my-matches {
  margin-top: 0.8rem;
  padding-top: 0.8rem;
  border-top: 1px solid var(--line);
}

.my-matches h3 {
  font-size: 0.9rem;
}

.bracket-match-list--participant {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
}

.registration-panel {
  max-width: 52rem;
  margin-right: auto;
  margin-left: auto;
}

.registration-form {
  gap: 1rem;
}

.registration-form fieldset {
  display: grid;
  margin: 0;
  padding: 1rem;
  gap: 0.8rem;
  background: var(--paper-blue);
  border: 1px solid #dce5fa;
  border-radius: 0.75rem;
}

.registration-form legend {
  padding: 0 0.35rem;
}

.check-label {
  display: grid;
  align-items: start;
  grid-template-columns: 1.25rem minmax(0, 1fr);
  gap: 0.65rem;
  font-size: 0.88rem;
  line-height: 1.55;
}

.check-label input {
  width: 1.15rem;
  height: 1.15rem;
  margin: 0.18rem 0 0;
  accent-color: var(--blue-700);
}

.registration-facts {
  display: grid;
  margin: 1rem 0;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
  gap: 0.8rem;
}

.registration-facts > div {
  padding: 0.8rem;
  background: var(--paper-blue);
  border-radius: 0.65rem;
}

.registration-facts dt {
  color: var(--muted);
  font-size: 0.73rem;
  font-weight: 750;
}

.registration-facts dd {
  margin: 0.25rem 0 0;
  font-weight: 850;
  overflow-wrap: anywhere;
}

.page-heading {
  max-width: 52rem;
  padding: clamp(1.5rem, 5vw, 3rem) 0;
}

.page-heading h1 {
  margin-bottom: 1rem;
}

.page-heading > p:last-child {
  color: var(--muted);
  font-size: 1.05rem;
}

.page-heading--admin {
  max-width: 60rem;
}

.participation-list,
.notification-list {
  display: grid;
  gap: 1rem;
}

.notification-alert-settings {
  display: grid;
  margin-bottom: 1.25rem;
  padding: clamp(1rem, 3vw, 1.4rem);
  gap: 1.1rem;
  background: var(--paper-blue);
  border: 1px solid #bdcbed;
  border-radius: var(--radius);
  box-shadow: var(--shadow-small);
}

.notification-alert-settings__heading {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
}

.notification-alert-settings__heading > span {
  display: grid;
  width: 2.65rem;
  height: 2.65rem;
  flex: 0 0 auto;
  place-items: center;
  background: white;
  border: 1px solid #cbd6ef;
  border-radius: 50%;
  font-size: 1.15rem;
}

.notification-alert-settings h2,
.notification-alert-settings h3 {
  margin-bottom: 0.35rem;
}

.notification-alert-settings h2 {
  font-size: 1.35rem;
}

.notification-alert-settings h3 {
  font-size: 1rem;
}

.notification-alert-settings p {
  margin-bottom: 0;
  color: var(--muted);
  font-size: 0.82rem;
}

.notification-alert-settings__options {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.8rem;
}

.notification-alert-option {
  display: flex;
  min-width: 0;
  padding: 0.9rem;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  background: white;
  border: 1px solid var(--line);
  border-radius: 0.75rem;
}

.notification-alert-option__control {
  display: grid;
  flex: 0 0 auto;
  justify-items: end;
  gap: 0.4rem;
}

.setting-state {
  color: var(--muted);
  font-size: 0.7rem;
  font-weight: 850;
}

.setting-state--on {
  color: var(--green-700);
}

.participation-card {
  display: grid;
  padding: clamp(1.1rem, 3vw, 1.5rem);
  align-items: center;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 1.5rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-small);
}

.participation-card h2 {
  margin: 0.75rem 0 0.45rem;
  font-size: 1.35rem;
}

.participation-card h2 a {
  color: var(--ink);
  text-underline-offset: 0.2rem;
}

.participation-card p {
  color: var(--muted);
}

.participation-actions {
  display: grid;
  min-width: 10rem;
  gap: 0.6rem;
}

.compact-times {
  max-width: 38rem;
  margin-bottom: 0;
}

.notification-card {
  display: grid;
  min-width: 0;
  padding: 1.2rem;
  grid-template-columns: 0.4rem minmax(0, 1fr);
  gap: 1rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-small);
}

.notification-card--unread {
  border-color: #aebfe8;
  box-shadow: inset 0 0 0 1px #dce5fa, var(--shadow-small);
}

.notification-card__marker {
  min-height: 100%;
  background: var(--line);
  border-radius: 999px;
}

.notification-card--unread .notification-card__marker {
  background: var(--blue-600);
}

.notification-card__meta {
  display: flex;
  margin-bottom: 0.65rem;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.55rem;
  color: var(--muted);
  font-size: 0.7rem;
}

.priority-chip {
  min-height: 1.45rem;
  padding: 0.18rem 0.45rem;
  color: var(--muted);
  background: #f0f2f6;
  border-color: var(--line);
}

.priority-chip--high,
.priority-chip--urgent {
  color: var(--red-700);
  background: var(--red-100);
  border-color: #e7bbc2;
}

.notification-card h2 {
  margin-bottom: 0.45rem;
  font-size: 1.12rem;
}

.notification-card p {
  margin-bottom: 0.65rem;
  color: var(--muted);
  white-space: pre-wrap;
}

.notification-card__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.7rem;
}

.admin-overview {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(15rem, 0.9fr);
  gap: 1.5rem;
}

.admin-participants {
  margin-top: 2rem;
}

.admin-participant-list {
  display: grid;
  gap: 0.55rem;
}

.admin-participant {
  display: grid;
  min-width: 0;
  padding: 0.75rem 0.9rem;
  align-items: center;
  grid-template-columns: minmax(10rem, 1.4fr) repeat(4, minmax(6rem, 0.65fr));
  gap: 0.75rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 0.7rem;
  box-shadow: var(--shadow-small);
  font-size: 0.78rem;
}

.admin-participant > div {
  display: grid;
  min-width: 0;
}

.admin-participant strong,
.admin-participant small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin-participant small {
  color: var(--muted);
  font-size: 0.65rem;
}

.admin-overview > .schedule-list {
  grid-column: 1 / -1;
  padding-top: 0.75rem;
  border-top: 1px solid var(--line);
}

.admin-overview h2 {
  margin: 0.7rem 0;
}

.admin-overview p {
  color: var(--muted);
}

.event-settings-form {
  max-width: none;
}

.event-settings-grid,
.event-round-rule-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}

.event-round-rule-grid {
  grid-template-columns: repeat(5, minmax(6rem, 1fr));
}

.event-round-rule-group {
  display: grid;
  margin-top: 1rem;
  gap: 0.65rem;
}

.event-round-rule-group[hidden] {
  display: none;
}

.event-round-rule-group h4 {
  margin: 0;
  color: var(--ink);
  font-size: 0.92rem;
}

.event-settings-grid label,
.event-round-rule-grid label {
  display: grid;
  gap: 0.4rem;
}

.qualifier-settings {
  margin: 0;
  padding: 1rem;
  background: var(--paper-blue);
  border: 1px solid #cbd8f2;
  border-radius: var(--radius);
}

.qualifier-settings legend {
  padding: 0 0.4rem;
  color: var(--blue-700);
  font-weight: 900;
}

.qualifier-settings > .field-help {
  margin-bottom: 1rem;
}

.danger-zone {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(18rem, 1.1fr);
  gap: 2rem;
  border-color: #dbaab2;
  box-shadow: inset 0.35rem 0 0 var(--red-700), var(--shadow-small);
}

.danger-zone .eyebrow {
  color: var(--red-700);
}

.warning-copy {
  color: var(--red-700);
}

.result-panel {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  color: #164d3f;
  background: var(--green-100);
  border-color: #abd8c8;
}

.result-panel__icon {
  display: grid;
  width: 2.8rem;
  height: 2.8rem;
  flex: 0 0 auto;
  place-items: center;
  color: white;
  background: var(--green-700);
  border-radius: 50%;
  font-weight: 900;
}

.result-panel h2 {
  margin-bottom: 0;
}

.technical-id {
  max-width: 42rem;
  margin: 0.8rem 0 0;
  color: var(--muted);
  font-family: ui-monospace, "Cascadia Mono", "SFMono-Regular", Consolas, monospace;
  font-size: 0.68rem;
  overflow-wrap: anywhere;
}

.site-footer {
  display: flex;
  width: min(74rem, calc(100% - 2rem));
  min-height: 6rem;
  margin: 0 auto;
  padding: 1.5rem 0;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  color: var(--muted);
  border-top: 1px solid var(--line-strong);
  font-size: 0.78rem;
}

.site-footer p {
  margin: 0;
}

.site-footer p:last-child {
  max-width: 38rem;
  text-align: right;
}

.noscript-message {
  position: fixed;
  z-index: 200;
  right: 1rem;
  bottom: 1rem;
  left: 1rem;
  padding: 1rem;
  color: white;
  background: var(--red-700);
  border-radius: var(--radius-small);
  text-align: center;
}

@media (max-width: 67rem) {
  .header-inner {
    padding: 0.65rem 0;
    flex-wrap: wrap;
  }

  .brand {
    order: 1;
  }

  .header-tools {
    order: 2;
  }

  .primary-nav {
    width: 100%;
    order: 3;
    justify-content: center;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
  }

  .page-hero {
    grid-template-columns: 1fr;
  }

  .hero-symbols {
    min-height: 9rem;
  }

  .auth-card,
  .admin-overview,
  .danger-zone {
    grid-template-columns: 1fr;
  }

  .admin-participant {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .event-round-rule-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .admin-participant > div {
    grid-column: 1 / -1;
  }
}

@media (max-width: 42rem) {
  .event-settings-grid,
  .event-round-rule-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 48rem) {
  .header-inner,
  main,
  .site-footer {
    width: min(100% - 1rem, 74rem);
  }

  .header-tools {
    max-width: 70%;
  }

  .session-copy {
    display: none;
  }

  .site-header .text-button {
    padding-right: 0.3rem;
    padding-left: 0.3rem;
  }

  .page-hero {
    min-height: 21rem;
    padding: 1.5rem;
  }

  .hero-symbols {
    display: none;
  }

  .event-hero {
    min-height: 16rem;
    align-items: flex-start;
    flex-direction: column;
  }

  .detail-grid,
  .policy-grid {
    grid-template-columns: 1fr;
  }

  .notification-alert-settings__options {
    grid-template-columns: 1fr;
  }

  .participation-card {
    grid-template-columns: 1fr;
  }

  .admin-participant {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .participation-actions {
    min-width: 0;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .time-row {
    grid-template-columns: 1fr;
    gap: 0.2rem;
  }

  .health-ranking__entry {
    grid-template-columns: 2rem minmax(0, 1fr) auto;
  }

  .health-ranking__entry--with-face {
    grid-template-columns: 2rem auto minmax(0, 1fr) auto;
  }

  .health-ranking__entry > strong {
    grid-column: 2;
  }

  .health-ranking__entry--with-face > strong {
    grid-column: 3;
  }

  .health-ranking__health {
    grid-column: 3;
  }

  .health-ranking__entry--with-face > .health-ranking__health {
    grid-column: 4;
  }

  .health-ranking__entry > .participant-badge {
    grid-column: 2 / -1;
    justify-self: start;
  }

  .health-ranking__entry--with-face > .participant-badge {
    grid-column: 3 / -1;
  }

  .placement-panel__list {
    grid-template-columns: minmax(0, 1fr);
  }

  .placement-panel__entry,
  .placement-panel__entry--champion,
  .placement-panel__entry--runner_up,
  .placement-panel__entry--shared_third {
    grid-column: 1;
    grid-row: auto;
    min-height: 0;
    padding: 0.95rem 1rem;
    align-items: center;
    justify-content: flex-start;
    flex-direction: row;
    text-align: left;
    transform: none;
  }

  .placement-panel__entry--champion {
    order: -1;
  }

  .placement-panel__medal,
  .placement-panel__entry--champion .placement-panel__medal {
    width: 3.35rem;
    height: 3.35rem;
  }

  .placement-panel__copy {
    flex: 1;
  }

  .site-footer {
    align-items: flex-start;
    flex-direction: column;
  }

  .site-footer p:last-child {
    text-align: left;
  }
}

@media (max-width: 34rem) {
  /* One phone-sized lever for "the text is small": every size in this sheet is
     stated in rem, so lifting the root lifts body copy, labels and the spacing
     around them together instead of one rule at a time. Media-query rem always
     resolves against the initial 16px, so the breakpoint itself cannot move. */
  html {
    font-size: 109%;
  }

  .participant-presence__list,
  .health-ranking__list {
    grid-template-columns: minmax(0, 1fr);
  }

  /* The top row carries a logo and two controls; giving it the desktop 5rem
     bought nothing and pushed the nav down. Trimming it here is what pays for
     the larger nav below without a taller sticky header. */
  .header-inner {
    min-height: 0;
    padding: 0.4rem 0 0;
    gap: 0.3rem 0.35rem;
  }

  .brand {
    min-height: 0;
    gap: 0.4rem;
  }

  .brand-picks {
    gap: 0.04rem;
  }

  .brand-picks img {
    width: 1.4rem;
    height: 1.4rem;
  }

  .brand-wordmark {
    display: grid;
    gap: 0.1rem;
  }

  .brand-wordmark strong {
    font-size: 1rem;
  }

  /* Tracked-out 10px was both the smallest type on the page and the widest
     thing in the brand — and the brand's width is what decides whether the
     language and sign-in controls fit on its row. The link keeps its
     "RPSPlay Competition" label for assistive tech. */
  .brand-wordmark small {
    display: none;
  }

  .header-tools {
    max-width: calc(100% - 9.5rem);
    gap: 0.4rem;
  }

  .session-slot {
    min-width: 0;
  }

  .language-switcher button {
    min-width: 2.2rem;
    padding: 0 0.4rem;
    font-size: 0.78rem;
  }

  .session-avatar {
    display: none;
  }

  /* Two sticky bars share the top of a phone screen, so this one is trimmed to
     the smallest row that still holds a comfortable tap target. */
  .section-tabs {
    padding: 0.3rem 0;
    margin-bottom: 1rem;
  }

  .section-tabs ul {
    gap: 0.25rem;
  }

  .section-tabs a {
    padding: 0 0.7rem;
    font-size: 0.84rem;
  }

  /* What was still under 12px after the root bump. These are labels a
     participant reads to find their own row — timestamps, seeds, state pills —
     so they get lifted the rest of the way by hand. */
  .participant-badge {
    padding: 0.16rem 0.45rem;
    font-size: 0.76rem;
  }

  .announcement-list time,
  .chat-message__meta time,
  .match-chat .count-badge {
    font-size: 0.74rem;
  }

  .bracket-seed {
    font-size: 0.76rem;
  }

  .time-row dd small {
    font-size: 0.74rem;
  }

  /* Conditional labels do not appear in the anonymous event fixture used for
     the common mobile measurement, but moderation and organizer views must
     keep the same 12px floor. Qualifier labels are repeated after their later
     base rules below. */
  .chat-message__actions button,
  .chat-block-list button,
  .admin-participant small,
  .technical-id {
    font-size: 0.7rem;
  }

  .event-card,
  .detail-card,
  .policy-document,
  .auth-card,
  .registration-panel,
  .notification-alert-settings,
  .admin-overview,
  .danger-zone,
  .result-panel {
    padding: 1rem;
  }

  .participation-actions {
    grid-template-columns: 1fr;
  }

  .policy-callout {
    align-items: stretch;
    flex-direction: column;
  }

  .policy-document__heading {
    flex-direction: column;
  }

  .health-ranking__entry {
    align-items: start;
    grid-template-columns: 1.75rem minmax(0, 1fr);
  }

  .health-ranking__entry--with-face {
    grid-template-columns: 1.75rem auto minmax(0, 1fr);
  }

  .health-ranking__entry > strong {
    grid-column: 2;
  }

  .health-ranking__entry--with-face > strong {
    grid-column: 3;
  }

  .health-ranking__health,
  .health-ranking__entry > .participant-badge {
    grid-column: 2;
  }

  .health-ranking__entry--with-face > .health-ranking__health,
  .health-ranking__entry--with-face > .participant-badge {
    grid-column: 3;
  }
}

/* At 344px and below the three pick badges are the difference between the brand
   sharing a row with the controls and the sticky header growing one. They are
   decorative and aria-hidden; the wordmark and the link's own label carry the
   brand without them. */
@media (max-width: 21.5rem) {
  /* The cap reserving room for the brand pushes the signed-out controls past
     the viewport below 344px. Remove it only in the range where the decorative
     badges are also hidden; doing so up to 368px makes the 360px header wrap
     and grow by an extra row. */
  .header-tools {
    max-width: 100%;
  }

  .brand-picks {
    display: none;
  }
}

/* ── Phone navigation dock ──────────────────────────────────────────────────
   Five words of English never fit one line on a phone — at 412px the labels
   needed 583px of a 395px row — so the nav wrapped 4+1 and read as an accident.
   Below the tablet breakpoint it becomes five equal tiles of icon over short
   label instead: one line at every width, in either language, and a bigger tap
   target than the text row it replaces. The long wording stays on the link's
   aria-label, so a screen reader still hears "Notifications" where the tile
   says "Alerts". Icons are inline SVG — no request, nothing to arrive late.
   The boundary is 640px because that is where the English row of full words
   stops wrapping — below it the dock is the shorter header either way. */
@media (max-width: 40rem) {
  .primary-nav {
    display: grid;
    width: 100%;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0.1rem;
    overflow-x: visible;
  }

  .primary-nav a {
    display: flex;
    min-height: 3.3rem;
    padding: 0.35rem 0.1rem;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.22rem;
    border-radius: 0.75rem;
    font-size: max(0.72rem, 12px);
    font-weight: 750;
    text-align: center;
    white-space: nowrap;
  }

  .nav-icon {
    display: block;
    width: 1.4rem;
    height: 1.4rem;
    flex: 0 0 auto;
  }

  .nav-label--full {
    display: none;
  }

  .nav-label--short {
    display: block;
    overflow: hidden;
    max-width: 100%;
    text-overflow: ellipsis;
  }

  /* A filled tile reads as "you are here" from arm's length; the 0.18rem
     underline did not. */
  .primary-nav a[aria-current="page"] {
    color: var(--navy-950);
    background: var(--gold-400);
    box-shadow: none;
  }

  .primary-nav a[aria-current="page"] .nav-icon {
    stroke-width: 2.2;
  }
}

/* The narrowest phones: the tile keeps its 44px touch target and 12px type
   floor; the label only gets less air around it. */
@media (max-width: 22rem) {
  .primary-nav a {
    padding: 0.3rem 0.05rem;
    gap: 0.15rem;
    font-size: max(0.66rem, 12px);
  }

  .nav-icon {
    width: 1.25rem;
    height: 1.25rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

@media (forced-colors: active) {
  .status-chip,
  .registration-chip,
  .priority-chip,
  .mode-badge,
  .version-badge,
  .button,
  .urgent-notification-popup,
  .event-card,
  .detail-card,
  .policy-document,
  .auth-card,
  .registration-panel,
  .notification-alert-settings {
    border: 1px solid CanvasText;
  }
}
/* ── Bracket slice ─────────────────────────────────────────────────────────
   Within a round, matches feeding the same next-round match are joined by a
   connector that ends at a chip naming their destination. That is one fork of
   the tree, drawn without needing the tournament's full width. */

.bracket-round-groups {
  display: grid;
  margin: 0;
  padding: 0;
  align-items: start;
  grid-template-columns: repeat(auto-fill, minmax(21rem, 1fr));
  gap: 0.5rem 1.6rem;
  list-style: none;
}

.bracket-pair {
  --bracket-pair-gap: 0.7rem;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 1.5rem minmax(0, 5.5rem);
  grid-template-areas: "matches connector destination";
  align-items: stretch;
  margin: 0 0 1.25rem;
  list-style: none;
}

.bracket-pair__matches { grid-area: matches; }
.bracket-pair__connector { grid-area: connector; }
.bracket-pair__destination { grid-area: destination; }

.bracket-pair__matches {
  display: grid;
  grid-auto-rows: 1fr;
  gap: var(--bracket-pair-gap);
  margin: 0;
  padding: 0;
  list-style: none;
}

.bracket-pair__connector {
  position: relative;
}

/* The spine runs from the first card's centre to the last card's centre, so
   its own ends are exactly the two junction points. */
.bracket-pair__spine {
  position: absolute;
  left: 0.9rem;
  top: calc((100% - var(--bracket-pair-gap)) / 4);
  height: calc((100% + var(--bracket-pair-gap)) / 2);
  width: 2px;
  background: var(--line-strong);
}

.bracket-pair__spine::before,
.bracket-pair__spine::after {
  content: "";
  position: absolute;
  right: 0;
  width: 0.9rem;
  height: 2px;
  background: var(--line-strong);
}

.bracket-pair__spine::before { top: 0; }
.bracket-pair__spine::after { bottom: 0; }

.bracket-pair__outlet {
  position: absolute;
  left: 0.9rem;
  top: 50%;
  width: 0.9rem;
  height: 2px;
  margin-top: -1px;
  background: var(--line-strong);
}

.bracket-pair--single .bracket-pair__spine { display: none; }

.bracket-pair--single .bracket-pair__outlet {
  left: 0;
  width: 1.8rem;
}

.bracket-pair__destination {
  align-self: center;
  max-width: 7rem;
  margin: 0;
  padding: 0.3rem 0.5rem;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-small);
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--muted);
}

/* On a phone the destination reads better under the pair than beside it. */
@media (max-width: 34rem) {
  .bracket-round-groups {
    grid-template-columns: minmax(0, 1fr);
  }

  .bracket-pair {
    grid-template-columns: minmax(0, 1fr) 1.6rem;
    grid-template-areas:
      "matches connector"
      "destination destination";
  }

  .bracket-pair__spine { left: 0.5rem; }

  .bracket-pair__spine::before,
  .bracket-pair__spine::after { width: 0.5rem; }

  .bracket-pair__outlet {
    left: 0.5rem;
    width: 0.55rem;
  }

  .bracket-pair--single .bracket-pair__outlet {
    left: 0;
    width: 1.05rem;
  }

  .bracket-pair__destination {
    max-width: none;
    margin: 0.5rem 0 0;
    text-align: right;
    border: 0;
    background: none;
    padding: 0;
  }
}

/* ── Reinforced pick ───────────────────────────────────────────────────────
   The Main-site rock/paper/scissors artwork, shown without a caption. */

.participant-badge--pick {
  padding: 0;
  border: 0;
  background: none;
}

/* No border-radius. Each pick's artwork carries its own frame — a circle for
   rock, a rounded square for paper, a triangle for scissors — so a round crop
   here cut the square's corners and the triangle's base. */
.pick-mark {
  display: block;
  width: 1.5rem;
  height: 1.5rem;
}

.health-mark {
  display: inline-block;
  width: 1.05rem;
  height: 1.05rem;
  vertical-align: -0.18rem;
}

.pick-mark--large {
  width: 2.25rem;
  height: 2.25rem;
}

/* ── Tournament reinforced pick chooser ────────────────────────────────────
   Three equal options; entry requires one. The native radio is removed from
   view — the card itself is the control, so selection reads as a highlighted
   tile rather than a dial with a picture beside it.

   The selected pick carries the Main site's reinforcement marker: the same
   green up-arrow, laid over the artwork (match-play-board__pick-reinforce).
   Green therefore drives the whole selected state so the tile and the marker
   read as one thing. The mark deliberately does not inherit .pick-mark, which
   is a round avatar crop. */

.pick-choice-field .pick-choice-row {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.85rem;
}

.pick-choice {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.45rem 0.3rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-small);
  background: var(--paper);
  cursor: pointer;
  text-align: center;
  transition: border-color 0.12s ease, background-color 0.12s ease;
}

.pick-choice:hover {
  border-color: var(--line-strong);
}

.pick-choice__input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  border: 0;
  opacity: 0;
  pointer-events: none;
}

/* The artwork is the tile. It carries ~14% of its own margin, so the box runs
   larger than the drawn shape looks. */
.pick-choice__art {
  position: relative;
  display: block;
  width: 100%;
  max-width: 6rem;
  aspect-ratio: 1;
}

.pick-choice__mark {
  display: block;
  width: 100%;
  height: 100%;
  /* No border-radius: the artwork already carries its own frame. */
}

/* Hidden until chosen, then marked exactly as the Main site marks a reinforced
   troop: the same green up-arrow, small, at the top-left of the artwork —
   where match-play-board__pick-reinforce[data-role^="my-"] puts it.

   The offset is per pick rather than one value, because each shape meets that
   corner at a different depth. Measured along the top-left diagonal of the
   artwork: paper's rounded square starts at 15.6%, rock's circle at 25.0%,
   the scissors triangle only at 35.9%. A single offset would leave the arrow
   floating away from the circle while sitting on the square. Each value below
   puts the arrow just outside its own shape so it overlaps slightly; scissors
   has no surface up there at all, so it stays clear — as intended. */
.pick-choice__reinforce {
  position: absolute;
  width: 22%;
  height: 22%;
  object-fit: contain;
  opacity: 0;
  pointer-events: none;
  filter: drop-shadow(0 1px 2px rgba(10, 17, 38, 0.5));
}

.pick-choice[data-pick="paper"] .pick-choice__reinforce {
  left: 6%;
  top: 6%;
}

.pick-choice[data-pick="rock"] .pick-choice__reinforce {
  left: 15%;
  top: 15%;
}

.pick-choice[data-pick="scissors"] .pick-choice__reinforce {
  left: 9%;
  top: 9%;
}

.pick-choice:has(.pick-choice__input:checked) {
  border-color: var(--green-700);
  background: var(--green-100);
  box-shadow: inset 0 0 0 1px var(--green-700);
}

.pick-choice:has(.pick-choice__input:checked) .pick-choice__reinforce {
  opacity: 1;
}

.pick-choice:has(.pick-choice__input:focus-visible) {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

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



/* ── Bracket rows ──────────────────────────────────────────────────────────
   Challonge-style: no card, no match number, no worded status. Two lines per
   player — emoji and name, then the reinforced pick and tournament health. */

.bracket-match {
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  box-shadow: none;
  list-style: none;
}

/* One bordered pair is one match. Keep both participant rows inside the same
   clipped outline so the bracket is readable before following a connector. */
.bracket-match__pair {
  overflow: hidden;
  background: white;
  border: 1px solid #c5d1ec;
  border-radius: 0.55rem;
  box-shadow: 0 1px 2px rgb(16 26 56 / 8%);
}

.bracket-match--viewer .bracket-match__pair {
  border-left: 3px solid var(--gold-600);
  padding-left: 0.15rem;
}

.bracket-match--live .bracket-match__pair {
  border-left: 3px solid var(--blue-600);
  padding-left: 0.15rem;
}

.bracket-player {
  display: grid;
  min-height: 2.7rem;
  grid-template-columns: 2.1rem minmax(0, 1fr) 2.7rem;
  align-items: stretch;
  gap: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
}

.bracket-player + .bracket-player {
  border-top: 1px solid var(--line);
}

.bracket-player--winner {
  background: var(--green-100);
}

.bracket-player__identity {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.15rem;
  min-width: 0;
  padding: 0.4rem 0.55rem;
}

.bracket-player__name {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  min-width: 0;
}

.bracket-player__name > strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.profile-emoji {
  font-size: 1.05rem;
  line-height: 1;
}

.bracket-player__stats {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--muted);
}

.stat-mark {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
}

.stat-mark > img {
  width: 0.95rem;
  height: 0.95rem;
}

.pick-mark--inline {
  width: 1.15rem;
  height: 1.15rem;
}

.bracket-player__score {
  display: grid;
  place-items: center;
  background: #f2f5fc;
  border-left: 1px solid #dde4f5;
  font-size: 1rem;
  font-weight: 850;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.presence-dot--offline {
  opacity: 0.35;
}

.bracket-match__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.4rem 0.1rem 0;
}

.match-countdown {
  font-variant-numeric: tabular-nums;
  font-weight: 800;
  color: var(--red-700);
}

.match-flag {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--red-700);
}

/* Challonge-style score column: the win count sits at the end of each row and
   the winning side is the one carrying colour. */
.bracket-player--winner > strong,
.bracket-player--winner .bracket-player__name > strong {
  color: var(--green-700);
}

.bracket-player--winner .bracket-player__score {
  color: white;
  background: var(--green-700);
  border-left-color: var(--green-700);
}

.bracket-player:not(.bracket-player--winner) .bracket-player__score {
  color: var(--muted);
}

.bracket-player--pending .bracket-player__score {
  opacity: 0.4;
}

/* ── Open-play qualifier ───────────────────────────────────────────────── */

.status-chip--qualifier-scheduled,
.status-chip--qualifier-skipped {
  color: #755000;
  background: var(--gold-100);
  border-color: #e2c673;
}

.status-chip--qualifier-open {
  color: var(--blue-700);
  background: var(--blue-100);
  border-color: #b6c9f1;
}

.status-chip--qualifier-settling,
.status-chip--qualifier-finalizing {
  color: #684600;
  background: #fff6dc;
  border-color: #e6cb7d;
}

.status-chip--qualifier-completed {
  color: var(--green-700);
  background: var(--green-100);
  border-color: #abd8c8;
}

.status-chip--qualifier-cancelled {
  color: var(--red-700);
  background: var(--red-100);
  border-color: #e7bbc2;
}

.capacity-next--qualifier {
  padding: 0.75rem;
  color: var(--ink);
  background: var(--paper-blue);
  border: 1px solid #cbd8f2;
  border-radius: var(--radius-small);
}

.qualifier-guide,
.qualifier-panel {
  margin: 1.25rem 0;
  padding: clamp(1rem, 3vw, 1.75rem);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-large);
  box-shadow: var(--shadow-small);
}

.qualifier-guide {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(18rem, 1.15fr);
  gap: 1.25rem 2rem;
  border-top: 0.35rem solid var(--gold-400);
}

.qualifier-guide__intro p:last-child,
.qualifier-guide__notes,
.qualifier-panel__notice,
.qualifier-health-help,
.qualifier-standings .section-heading p {
  color: var(--muted);
}

.qualifier-guide__steps {
  display: grid;
  margin: 0;
  padding: 0;
  gap: 0.65rem;
  counter-reset: qualifier-step;
  list-style: none;
}

.qualifier-guide__steps li {
  position: relative;
  min-height: 2.4rem;
  padding: 0.45rem 0 0.45rem 3rem;
  counter-increment: qualifier-step;
}

.qualifier-guide__steps li::before {
  position: absolute;
  top: 0.25rem;
  left: 0;
  display: grid;
  width: 2.1rem;
  height: 2.1rem;
  place-items: center;
  color: white;
  background: var(--navy-800);
  border-radius: 50%;
  content: counter(qualifier-step);
  font-size: 0.75rem;
  font-weight: 900;
}

.qualifier-guide__notes {
  grid-column: 1 / -1;
  padding: 1rem;
  background: var(--paper-blue);
  border-left: 0.25rem solid var(--blue-600);
  border-radius: var(--radius-small);
  font-size: 0.85rem;
}

.qualifier-guide__notes p:last-child {
  margin-bottom: 0;
}

.qualifier-guide__boundary {
  padding-top: 0.75rem;
  border-top: 1px solid #cbd8f2;
  color: var(--ink);
  font-weight: 750;
}

.qualifier-panel {
  overflow: clip;
  border-top: 0.35rem solid var(--blue-600);
}

.qualifier-panel--compact {
  margin: 1rem 0 0;
  padding: 1rem;
  border-radius: var(--radius);
}

.qualifier-panel__header,
.qualifier-viewer__heading,
.qualifier-countdown,
.qualifier-minimum > div {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.qualifier-panel__header h2,
.qualifier-viewer__heading h3,
.qualifier-standings h3 {
  margin-bottom: 0;
}

.qualifier-countdown {
  margin: 1rem 0;
  padding: 0.8rem 1rem;
  background: var(--navy-950);
  border-radius: var(--radius-small);
  color: white;
}

.qualifier-countdown strong {
  color: #ffd476;
  font-size: clamp(1.1rem, 4vw, 1.5rem);
  font-variant-numeric: tabular-nums;
}

.qualifier-panel__notice {
  margin: 0 0 1rem;
  padding: 0.75rem 0.9rem;
  background: var(--paper-blue);
  border: 1px solid #cbd8f2;
  border-radius: var(--radius-small);
  font-size: 0.86rem;
}

.qualifier-viewer {
  padding: 1rem;
  background: linear-gradient(135deg, #f5f8ff, #fffdf9);
  border: 1px solid #cbd8f2;
  border-radius: var(--radius);
}

.qualifier-viewer__stats {
  display: grid;
  margin: 1rem 0;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0.6rem;
}

.qualifier-viewer__stats > div {
  min-width: 0;
  padding: 0.7rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-small);
}

.qualifier-viewer__stats dt {
  color: var(--muted);
  font-size: 0.7rem;
  font-weight: 750;
}

.qualifier-viewer__stats dd {
  margin: 0.2rem 0 0;
  font-size: 1rem;
  font-weight: 900;
  overflow-wrap: anywhere;
}

.qualifier-health-stat {
  color: var(--red-700);
}

.qualifier-health-help {
  margin: -0.25rem 0 0.9rem;
  font-size: 0.76rem;
}

.qualifier-buffs {
  display: grid;
  margin: 0.9rem 0;
  padding: 0.85rem;
  grid-template-columns: minmax(10rem, 0.8fr) minmax(0, 1.2fr);
  gap: 0.75rem 1rem;
  background: #fff8e8;
  border: 1px solid #ead18d;
  border-radius: var(--radius-small);
}

.qualifier-buffs h4 {
  margin: 0;
  font-size: 0.9rem;
}

.qualifier-buffs p {
  margin: 0.25rem 0 0;
  color: var(--muted);
  font-size: 0.72rem;
}

.qualifier-buffs__streak {
  align-self: center;
  justify-self: end;
  padding: 0.25rem 0.55rem;
  color: #684600 !important;
  background: var(--gold-100);
  border-radius: 999px;
  font-weight: 900;
}

.qualifier-buffs__troops {
  display: grid;
  margin: 0;
  grid-column: 1 / -1;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.5rem;
}

.qualifier-buffs__troops > div {
  padding: 0.55rem;
  background: var(--paper);
  border: 1px solid #ead9ae;
  border-radius: 0.55rem;
}

.qualifier-buffs__troops dt {
  color: #684600;
  font-size: 0.72rem;
  font-weight: 900;
}

.qualifier-buffs__troops dd {
  display: grid;
  margin: 0.2rem 0 0;
  gap: 0.15rem;
  font-size: 0.7rem;
}

.qualifier-minimum {
  margin: 0.8rem 0;
}

.qualifier-minimum span,
.qualifier-minimum strong {
  font-size: 0.78rem;
}

.qualifier-minimum progress {
  appearance: none;
  display: block;
  width: 100%;
  height: 0.55rem;
  margin-top: 0.5rem;
  overflow: hidden;
  background: var(--line);
  border: 0;
  border-radius: 999px;
}

.qualifier-minimum progress::-webkit-progress-bar {
  background: var(--line);
}

.qualifier-minimum progress::-webkit-progress-value {
  background: linear-gradient(90deg, var(--blue-600), var(--green-700));
}

.qualifier-minimum progress::-moz-progress-bar {
  background: linear-gradient(90deg, var(--blue-600), var(--green-700));
}

.qualifier-outcome {
  padding: 0.8rem;
  color: var(--green-700);
  background: var(--green-100);
  border-radius: var(--radius-small);
  font-weight: 800;
}

.qualifier-actions {
  display: flex;
  min-height: 3rem;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.qualifier-actions__status {
  margin: 0;
  font-size: 0.86rem;
  font-weight: 750;
}

.qualifier-primary-action {
  min-width: 10rem;
}

.qualifier-standings {
  margin-top: 1.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}

.qualifier-standings--hidden {
  display: flex;
  padding: 1rem;
  align-items: center;
  gap: 1rem;
  background: #f6f7f9;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-small);
}

.qualifier-standings--hidden > span {
  display: grid;
  width: 2.5rem;
  height: 2.5rem;
  flex: 0 0 auto;
  place-items: center;
  background: var(--line);
  border-radius: 50%;
  font-weight: 900;
}

.qualifier-standings--hidden p {
  margin: 0.3rem 0 0;
}

.qualifier-standings__header,
.qualifier-standing {
  display: grid;
  grid-template-columns: 3.5rem minmax(8rem, 1.4fr) minmax(5rem, 0.7fr)
    minmax(6rem, 0.7fr) minmax(5rem, 0.6fr) minmax(8rem, 1fr);
  gap: 0.75rem;
  align-items: center;
}

.qualifier-standings__header {
  padding: 0 0.8rem 0.45rem;
  color: var(--muted);
  font-size: 0.67rem;
  font-weight: 800;
  text-transform: uppercase;
}

.qualifier-standings__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.qualifier-standing {
  min-height: 3.4rem;
  padding: 0.65rem 0.8rem;
  border-top: 1px solid var(--line);
  font-size: 0.82rem;
}

.qualifier-standing--viewer {
  background: var(--blue-100);
  box-shadow: inset 0.2rem 0 var(--blue-600);
}

.qualifier-standing__rank {
  font-size: 1rem;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
}

.qualifier-standing__status {
  color: var(--muted);
  font-size: 0.75rem;
  font-weight: 750;
}

.qualifier-standing__health {
  color: var(--red-700);
  font-weight: 900;
  font-variant-numeric: tabular-nums;
}

.qualifier-you {
  margin-left: 0.4rem;
  padding: 0.12rem 0.35rem;
  color: white;
  background: var(--blue-600);
  border-radius: 999px;
  font-size: 0.62rem;
  vertical-align: middle;
}

.qualifier-cutline {
  display: flex;
  padding: 0.35rem 0.8rem;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  color: #684600;
  background: var(--gold-100);
  border-top: 1px solid #e2c673;
  border-bottom: 1px solid #e2c673;
  font-size: 0.72rem;
  font-weight: 900;
}

@media (max-width: 55rem) {
  .qualifier-guide {
    grid-template-columns: 1fr;
  }

  .qualifier-guide__notes {
    grid-column: auto;
  }

  .qualifier-viewer__stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .qualifier-buffs {
    grid-template-columns: 1fr;
  }

  .qualifier-buffs__streak {
    justify-self: start;
  }

  .qualifier-standings__header {
    display: none;
  }

  .qualifier-standing {
    grid-template-columns: 2.5rem minmax(0, 1fr);
    gap: 0.3rem 0.75rem;
    align-items: start;
  }

  .qualifier-standing__rank {
    grid-row: 1 / span 5;
  }

  .qualifier-standing > strong,
  .qualifier-standing__metric {
    grid-column: 2;
  }

  .qualifier-standing__metric {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
  }

  .qualifier-standing__metric::before {
    color: var(--muted);
    content: attr(data-mobile-label);
    font-size: 0.68rem;
    font-weight: 700;
  }

  .qualifier-standing__health::before {
    content: none;
  }

  .qualifier-cutline {
    min-width: 0;
  }
}

@media (max-width: 34rem) {
  .qualifier-guide,
  .qualifier-panel {
    padding: 1rem;
    border-radius: var(--radius);
  }

  .qualifier-you,
  .qualifier-standing__metric::before {
    font-size: 0.7rem;
  }

  .qualifier-panel__header,
  .qualifier-viewer__heading,
  .qualifier-countdown,
  .qualifier-actions {
    align-items: stretch;
    flex-direction: column;
  }

  .qualifier-viewer__stats {
    grid-template-columns: 1fr;
  }

  .qualifier-buffs__troops {
    grid-template-columns: 1fr;
  }

  .qualifier-actions {
    position: sticky;
    z-index: 2;
    bottom: max(0.5rem, env(safe-area-inset-bottom));
    padding: 0.65rem;
    background: rgba(255, 253, 249, 0.97);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-small);
    box-shadow: var(--shadow-card);
  }

  .qualifier-primary-action {
    width: 100%;
    min-height: 3.2rem;
  }

  .qualifier-standings--hidden {
    align-items: flex-start;
  }
}

@media (forced-colors: active) {
  .qualifier-guide,
  .qualifier-panel,
  .qualifier-viewer,
  .qualifier-panel__notice,
  .qualifier-standings--hidden,
  .qualifier-standing,
  .qualifier-cutline,
  .qualifier-actions {
    border: 1px solid CanvasText;
  }
}

/* ---------------------------------------------------------------------------
   Bracket tree — the left-to-right ladder used at offline fighting-game events.

   Each round is a column; every match carries a line out to the right and a
   line in from the left, so the path through the bracket is continuous even
   where a round hands over one-to-one. That case is the norm on the losers
   ladder, and it is exactly where the older pair-fork drew nothing at all.

   The columns are equal height and space their cells evenly, which is what
   makes the fork arithmetic work: the vertical drop from one cell's centre to
   the next cell's centre is exactly one cell height.
--------------------------------------------------------------------------- */
.bracket-tree {
  --tree-line: var(--line-strong);
  --tree-gutter: 1.1rem;
  --tree-card: 13.5rem;
  display: flex;
  align-items: stretch;
  margin: 0 0 0.4rem;
  padding: 0 0 0.4rem;
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scrollbar-width: thin;
}

.bracket-tree__round {
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  min-width: calc(var(--tree-card) + var(--tree-gutter) * 2);
}

/* A labelled chip per column, the way bracket tools head their rounds. Left
   aligned with the card below it rather than centred over the whole column,
   so the eye can run straight down the ladder. */
.bracket-tree__round-name {
  margin: 0 0 0.45rem;
  padding: 0 var(--tree-gutter);
  white-space: nowrap;
}

.bracket-tree__round-name > span {
  display: inline-block;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tree-line) 10%, white);
  color: var(--tree-line);
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.02em;
}

.bracket-tree__cells {
  display: flex;
  flex: 1;
  flex-direction: column;
  justify-content: space-around;
  margin: 0;
  padding: 0;
  list-style: none;
}

.bracket-tree__cell {
  position: relative;
  display: flex;
  flex: 1;
  align-items: center;
  padding: 0.3rem var(--tree-gutter);
}

.bracket-tree__match {
  width: 100%;
  min-width: 0;
}

/* The two horizontal stubs. Together with the neighbouring column's stub they
   form one unbroken line across the gutter. */
.bracket-tree__in,
.bracket-tree__out {
  position: absolute;
  top: 50%;
  width: var(--tree-gutter);
  height: 2px;
  margin-top: -1px;
  /* Faint until the match behind the line is decided. An all-solid ladder
     made a bracket that had not started look exactly like a finished one. */
  background: color-mix(in srgb, var(--tree-line) 28%, transparent);
}

.bracket-tree__in.is-settled,
.bracket-tree__out.is-settled {
  background: var(--tree-line);
}

.bracket-tree__in { left: 0; }
.bracket-tree__out { right: 0; }

/* The fork, drawn once on the upper match of a pair and reaching down to the
   centre of the match below. One cell height is exactly that distance. */
.bracket-tree__fork {
  position: absolute;
  right: 0;
  top: 50%;
  width: 2px;
  height: 100%;
  background: color-mix(in srgb, var(--tree-line) 28%, transparent);
}

.bracket-tree__cell--forks.is-settled .bracket-tree__fork {
  background: color-mix(in srgb, var(--tree-line) 64%, transparent);
}

/* The card sits in its own list so the match markup stays valid inside the
   cell; the list itself contributes no styling of its own. */
.bracket-tree__match {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The decider earns a heavier outline. Everything else on the page is a step
   towards it, and at a glance it should not read as one more round. */
.bracket-tree--grand_final .bracket-match__pair {
  border-color: var(--blue-700);
  box-shadow: 0 2px 6px rgb(33 74 168 / 16%);
}

.bracket-tree--winners { --tree-line: var(--green-700); }
.bracket-tree--losers { --tree-line: var(--red-700); }
.bracket-tree--grand_final { --tree-line: var(--blue-700); }

/* A phone cannot show a whole ladder at once, so the tree scrolls sideways one
   round at a time. A narrower fixed card left a slice of the next column in
   view, cutting its round label at the right edge — most noticeably across the
   longer losers ladder. Make each column exactly one scrollport wide and snap
   to its start so every round label is either fully visible or fully offscreen. */
@media (max-width: 34rem) {
  .bracket-tree {
    --tree-gutter: 0.9rem;
    scroll-snap-type: inline mandatory;
  }

  .bracket-tree__round {
    flex-basis: 100%;
    min-width: 100%;
    scroll-snap-align: start;
    scroll-snap-stop: always;
  }
}

/* Why a match on a finished bracket was never played. Only the unused
   grand-final reset carries it, and without it the card read as though the
   tournament were still waiting on someone. */
.bracket-match__note {
  margin: 0.35rem 0 0;
  color: var(--muted);
  font-size: 0.68rem;
  font-weight: 700;
}
