:root {
  --clay: #D2622E;
  --clay-dark: #A8431A;
  --clay-light: #F0936A;
  --chalk: #FFFCF5;
  --ink: #16241A;
  --ink-soft: #5B6B5E;
  --ink-soft-on-dark: rgba(250, 246, 239, 0.62);
  --grass: #3F8753;
  --grass-dark: #2A6339;
  --grass-light: #E3F3E6;
  --sky: #2E8FC9;
  --sky-dark: #1F6694;
  --sky-light: #E5F2FA;
  --ball: #E4F23D;
  --ball-dark: #8A9322;
  --line: #E5DCC8;
  --danger: #C23B3B;
  /* Pro (paid plan). --gold-pro is the fill and only ever carries --ink on top
     of it (11:1). --gold-pro-ink is the same hue taken down far enough to be
     TEXT on a white card: the fill itself measures 1.7:1 there, which is the
     "premium gold micro-type" that looks right in a mockup and disappears on a
     phone outdoors. Same family as the existing prize golds (#C8912B icons,
     #8A5E12 chip text), not a fifth one. */
  --gold-pro: #F4C542;
  --gold-pro-ink: #8A5E12;
  --white: #FFFFFF;
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --font-display: 'Oswald', sans-serif;
  --font-body: 'Inter', system-ui, -apple-system, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
  /* This shows up on screens wider than the app shell's card — on a phone
     the card fills the viewport so this is invisible, but on a laptop/desktop
     it's the backdrop framing the card. Light, sunlit-court base (chalk/cream,
     matching the card itself) with bright color blooms, so the card reads as
     part of one bright scene instead of a light card floating on a dark void. */
  /* Page background = soft colour blooms + warm gradient only. The sports
     line-art lives in the #wm-layer signature background system
     (js/watermarks.js) — the old filled racquet/padel silhouettes that used
     to be baked in here are gone for good (the design language forbids
     filled icons). */
  background:
    radial-gradient(ellipse 62% 46% at 50% 26%, rgba(255, 255, 255, 0.05), transparent 70%),
    radial-gradient(ellipse at 50% 50%, transparent 64%, rgba(22, 36, 26, 0.05) 100%),
    radial-gradient(circle at 10% 4%, rgba(228, 145, 71, 0.24), transparent 46%),
    radial-gradient(circle at 92% 6%, rgba(64, 178, 235, 0.21), transparent 44%),
    radial-gradient(circle at 10% 96%, rgba(82, 173, 107, 0.24), transparent 50%),
    radial-gradient(circle at 94% 94%, rgba(228, 242, 61, 0.18), transparent 44%),
    linear-gradient(155deg, #FFFDF8 0%, #FBF4E6 45%, #F3E9D4 100%);
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  /* Nothing should ever push the page wider than the viewport (a dropdown or
     wide element could, revealing the backdrop and letting the page scroll
     sideways). Inner scrollers like the bracket keep their own overflow:auto. */
  overflow-x: hidden;
}

button {
  font-family: inherit;
}

:focus-visible {
  outline: 2px solid var(--clay);
  outline-offset: 2px;
}

.hidden { display: none !important; }

img { display: block; }

/* Every Icon.* string is a bare <svg viewBox="0 0 24 24" ...> with no
   width/height attributes of its own, so any icon dropped into the markup
   without an explicit size — a button with no descendant-svg rule yet, a
   future icon someone forgets to size — falls back to the browser's default
   replaced-element box (300x150 in most engines) and renders huge. Giving
   the bare element a sane 1em default (so it scales with whatever text size
   it sits next to instead of one fixed px value everywhere) makes that the
   worst case instead of "giant icon." Any more specific rule below (a class,
   the span-wrapper rule, a descendant selector) still wins over this on
   specificity, so real per-spot sizing is untouched. */
svg {
  display: block;
  width: 1em;
  height: 1em;
}

/* Inline icon wrappers (the <span style="width:Npx;height:Npx"> pattern used
   throughout the JS) need display:inline-flex for their width/height to take
   effect at all (plain inline spans ignore sizing), and their child <svg>
   needs to actually fill the box rather than falling back to browser-default
   intrinsic sizing. Without both rules, icons render oversized/misaligned
   next to text. */
span[style*="width"][style*="height"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  vertical-align: middle;
}

span[style*="width"][style*="height"] > svg {
  width: 100%;
  height: 100%;
}

/* ============================================================
   LAYOUT SHELLS
============================================================ */

/* Decorative sport watermarks in the empty desktop side-margins. Sits behind
   everything; only shown once the viewport is wide enough to have margins. */

.app {
  max-width: 480px;
  margin: 0 auto;
  min-height: 100vh;
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  background:
    radial-gradient(circle at 0% 0%, rgba(210, 98, 46, 0.10), transparent 40%),
    radial-gradient(circle at 100% 15%, rgba(46, 143, 201, 0.10), transparent 45%),
    radial-gradient(circle at 20% 100%, rgba(63, 135, 83, 0.12), transparent 45%),
    radial-gradient(circle at 90% 95%, rgba(228, 242, 61, 0.10), transparent 40%),
    var(--chalk);
  background-attachment: fixed;
  position: relative;
}

.view-root {
  flex: 1;
  padding-bottom: 90px;
}

/* ============================================================
   TOP BAR + HAMBURGER MENU DRAWER
   ============================================================ */
.app-topbar {
  position: sticky;
  top: 0;
  z-index: 70;
  display: flex;
  align-items: center;
  gap: 12px;
  height: 52px;
  padding: 0 14px;
  background: color-mix(in srgb, var(--chalk) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(8px);
  -webkit-backdrop-filter: saturate(1.4) blur(8px);
  border-bottom: 1px solid var(--line);
}
.app-menu-btn {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 38px;
  height: 38px;
  padding: 8px;
  border: none;
  background: transparent;
  cursor: pointer;
  border-radius: var(--radius-sm);
}
.app-menu-btn:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); }
.app-menu-btn span {
  display: block;
  height: 2.5px;
  width: 100%;
  border-radius: 2px;
  background: #3730A3;
  transition: transform .25s ease, opacity .2s ease;
}
.app-topbar-brand {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: .01em;
  color: var(--ink);
}
.app-notif-btn { position: relative; margin-left: auto; display: inline-flex; align-items: center; justify-content: center; width: 58px; height: 58px; border: none; background: transparent; color: #3730A3; cursor: pointer; border-radius: var(--radius-sm); }
.app-notif-btn svg { width: 32px; height: 32px; }
.app-notif-btn:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); }
.app-notif-badge { position: absolute; top: 3px; right: 3px; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 999px; background: var(--clay); color: var(--white); font-size: 10px; font-weight: 800; display: flex; align-items: center; justify-content: center; line-height: 1; }
.notif-list { display: flex; flex-direction: column; }
.notif-item { display: flex; gap: 10px; align-items: flex-start; padding: 11px 4px; border-bottom: 1px solid var(--line); }
.notif-item:last-child { border-bottom: none; }
.notif-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--grass); margin-top: 6px; flex-shrink: 0; }
.notif-text { font-size: 13.5px; color: var(--ink); }
.notif-sub { font-size: 12px; color: var(--ink-soft); margin-top: 2px; }
.notif-time { font-size: 11px; color: var(--ink-soft); margin-top: 3px; }
.notif-empty { font-size: 13px; color: var(--ink-soft); line-height: 1.6; padding: 8px 2px; }
/* Section headings inside the bell: "Needs action" (stays until resolved)
   vs "New" (clears once seen). The split is what stops resolved-later items
   from reading as the same unread notification nagging forever. */
.notif-sec {
  font-size: 10px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
  color: var(--ink-soft); padding: 6px 2px 4px;
}
.notif-sec:not(:first-child) { margin-top: 8px; border-top: 1px solid var(--line); padding-top: 12px; }

/* Drawer: scoped to the .app column (position:relative) so it lines up with
   the centered card on desktop rather than the whole viewport. */
.app-drawer {
  position: absolute;
  inset: 0;
  z-index: 300;
  visibility: hidden;
  opacity: 0;
  transition: opacity .25s ease, visibility 0s linear .25s;
}
.app-drawer.open {
  visibility: visible;
  opacity: 1;
  transition: opacity .25s ease;
}
.app-drawer-scrim {
  position: absolute;
  inset: 0;
  background: rgba(10, 20, 14, 0.46);
}
.app-drawer-panel {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 82%;
  max-width: 320px;
  background: var(--surface, var(--white));
  box-shadow: 8px 0 40px -8px rgba(0, 0, 0, 0.4);
  display: flex;
  flex-direction: column;
  transform: translateX(-100%);
  transition: transform .28s cubic-bezier(.4, 0, .2, 1);
}
.app-drawer.open .app-drawer-panel { transform: translateX(0); }
.app-drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 16px 12px;
  border-bottom: 1px solid var(--line);
}
.app-drawer-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.app-drawer-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: none;
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
  border-radius: var(--radius-sm);
}
.app-drawer-close:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); color: var(--ink); }
.app-drawer-list { display: flex; flex-direction: column; padding: 8px; }
.app-drawer-item {
  text-align: left;
  padding: 14px 14px;
  border: none;
  background: transparent;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  border-radius: var(--radius-sm);
  border-bottom: 1px solid color-mix(in srgb, var(--line) 60%, transparent);
}
.app-drawer-item:last-child { border-bottom: none; }
.app-drawer-item:hover { background: color-mix(in srgb, var(--clay) 8%, transparent); color: var(--clay-dark); }

/* Long-form content shown in the menu modals. */
.menu-doc { font-size: 14px; line-height: 1.65; color: var(--ink); }
.menu-doc h4 { font-family: var(--font-display); font-size: 13px; letter-spacing: .04em; text-transform: uppercase; color: var(--clay-dark); margin: 18px 0 6px; }
.menu-doc p { margin: 0 0 10px; color: var(--ink-soft); }
.menu-doc ul { margin: 0 0 10px; padding-left: 18px; color: var(--ink-soft); }
.menu-doc li { margin-bottom: 6px; }
.menu-doc a { color: var(--clay); font-weight: 600; }
.menu-doc .menu-doc-lead { font-size: 15px; color: var(--ink); font-weight: 600; }
/* The contact address in "Advertise with us" — the one thing that modal exists
   to get someone to tap, so it is shaped like the app's tabs and filter chips
   (.profile-tab / .filter-chip: 20px pill, 1px border, same padding rhythm)
   rather than left as underlined text. It reads as tappable at a glance, which
   plain text never does.
   `inline-flex`, not block: the pill hugs the address instead of stretching a
   button the width of the modal, and it still sits on its own line because the
   wrapper below puts it there.
   Colour is --clay-dark, not --clay. Both are the app's orange; clay-dark is
   the one already used for text in this modal (see .menu-doc h4), and it
   measures 6.0:1 on white where --clay is 3.8:1 — which fails AA at this size,
   and this is the line that must not be hard to read. */
.menu-doc .menu-doc-email-wrap { margin: 6px 0 4px; }
.menu-doc .menu-doc-email {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 100%;
  padding: 11px 18px;
  border-radius: 20px;
  border: 1px solid color-mix(in srgb, var(--clay) 45%, var(--line));
  background: color-mix(in srgb, var(--clay) 8%, var(--white));
  font-size: 15.5px;
  font-weight: 800;
  line-height: 1.25;
  color: var(--clay-dark);
  text-decoration: none;
  word-break: break-word;
  /* The house minimum tap target — same bar the ops check-in pill was fixed to. */
  min-height: 34px;
}
.menu-doc .menu-doc-email svg { width: 16px; height: 16px; flex-shrink: 0; }
@media (hover: hover) {
  .menu-doc .menu-doc-email:hover {
    background: color-mix(in srgb, var(--clay) 15%, var(--white));
    border-color: var(--clay);
  }
}
.menu-doc .menu-doc-email:focus-visible { outline: 2px solid var(--clay); outline-offset: 2px; }
/* On a narrow phone a 30-character address in a pill would push the modal
   sideways; let it fill the line and centre instead. */
@media (max-width: 420px) {
  .menu-doc .menu-doc-email { width: 100%; justify-content: center; font-size: 14.5px; padding: 11px 12px; }
}

/* FAQ accordion — native <details>, each question expands with a flipping
   chevron. */
.faq-list { margin-top: 10px; }
.faq-item { border: 1px solid var(--line); border-radius: var(--radius-sm); margin-bottom: 9px; background: var(--white); overflow: hidden; transition: border-color .2s ease, box-shadow .2s ease; }
.faq-item[open] { border-color: color-mix(in srgb, var(--clay) 40%, var(--line)); box-shadow: 0 4px 16px -8px rgba(210, 98, 46, 0.35); }
.faq-item summary { list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 13px 14px; font-weight: 600; font-size: 14px; color: var(--ink); }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--clay-dark); }
.faq-chevron { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; color: var(--ink-soft); flex-shrink: 0; transition: transform .22s ease, color .2s ease; }
.faq-chevron svg { width: 100%; height: 100%; }
.faq-item[open] summary { color: var(--clay-dark); border-bottom: 1px solid var(--line); }
.faq-item[open] .faq-chevron { transform: rotate(180deg); color: var(--clay); }
.faq-answer { padding: 12px 14px 14px; font-size: 13.5px; line-height: 1.62; color: var(--ink-soft); }
.faq-answer p { margin: 0 0 8px; }
.faq-answer p:last-child { margin-bottom: 0; }
.faq-tagline { color: var(--clay); font-weight: 700; }

/* Past phone width, present the app as a wider centered card instead of a
   phone-width strip glued to a blank void — but at the SAME content scale
   as mobile (no `zoom`), so spacing/positions stay identical across
   devices and nothing needs extra vertical room to fit. No top margin
   either: the header sits flush with the viewport top exactly like mobile,
   just inside a wider, rounded frame. clip-path (not overflow) does the
   corner-rounding on purpose — it's a paint-time clip, so it can't
   interfere with the tabbar's position:sticky behavior the way
   overflow:hidden on this element would. */
@media (min-width: 700px) {
  .app {
    max-width: 640px;
    margin: 0 auto;
    min-height: 100vh;
    border-radius: 28px;
    clip-path: inset(0 round 28px);
    box-shadow: 0 30px 90px -10px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(255, 255, 255, 0.06);
  }
}

@media (min-width: 1024px) {
  .app {
    max-width: 760px;
  }
}

@media (min-width: 1440px) {
  .app {
    max-width: 860px;
  }
}

/* ============================================================
   GATE (IDENTITY SCREEN)
============================================================ */

.gate {
  min-height: 100vh;
  min-height: 100dvh; /* real visible height on mobile, ignores the
    address-bar/keyboard chrome that makes plain 100vh push content out of
    view and look unaligned on phones */
  background:
    radial-gradient(circle at 15% 8%, rgba(210, 98, 46, 0.35), transparent 45%),
    radial-gradient(circle at 85% 92%, rgba(63, 135, 83, 0.4), transparent 50%),
    var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.gate-card { width: 100%; max-width: 420px; }

.gate-brand { text-align: center; margin-bottom: 32px; }

.gate-hero {
  width: 150px;
  height: auto;
  display: block;
  margin: 0 auto 8px;
  filter: drop-shadow(0 8px 20px rgba(0, 0, 0, 0.35));
}

.gate-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 40px;
  color: var(--chalk);
  letter-spacing: -0.5px;
  text-transform: uppercase;
}

.gate-sub {
  color: var(--ball);
  font-size: 13px;
  margin-top: 4px;
  letter-spacing: 1.5px;
}

.gate-panel {
  background: var(--chalk);
  border-radius: var(--radius-lg);
  padding: 24px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3);
}

.gate-tabs {
  display: flex;
  margin-bottom: 20px;
  border-radius: 10px;
  background: var(--line);
  padding: 4px;
}

.gate-tab {
  flex: 1;
  padding: 8px 0;
  border-radius: 8px;
  border: none;
  background: transparent;
  color: var(--ink);
  font-weight: 600;
  font-size: 13px;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.gate-tab.active {
  background: var(--clay);
  color: var(--white);
}

.gate-player-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 320px;
  overflow-y: auto;
}

.gate-player-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--white);
  cursor: pointer;
  text-align: left;
  width: 100%;
}

.gate-player-row .name { font-weight: 600; font-size: 14px; color: var(--ink); }
.gate-player-row .meta { font-size: 12px; color: var(--ink-soft); margin-top: 1px; }

.gate-create {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.gate-error {
  background: rgba(163, 45, 45, 0.1);
  border: 1px solid var(--danger);
  color: var(--danger);
  font-size: 12.5px;
  font-weight: 600;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  margin-bottom: 14px;
}

/* "These four fields are permanent" on sign-up. Built from .gate-error's exact
   shape — same font size, padding and radius — but in the app's clay accent
   rather than danger red, because nothing has gone wrong: it is telling the
   reader something they need before they commit, not reporting a mistake.
   Body weight is 500 so the box does not shout; only "Important:" is bold. */
.signup-permanent-note {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  background: color-mix(in srgb, var(--clay) 8%, var(--white));
  border: 1px solid color-mix(in srgb, var(--clay) 32%, transparent);
  color: var(--ink);
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.5;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  margin-bottom: 14px;
}
.signup-permanent-note strong { font-weight: 800; color: var(--clay-dark); }

/* A permanent value shown back to the player in Edit profile. Deliberately
   built ON TOP of .input so it keeps that class's height, padding, radius,
   border and width — the locked rows and the editable Mobile row have to line
   up, and re-declaring the box here is how they drift apart on the next tweak.
   It reads as settled rather than broken: a faint tint and softer ink, the
   same treatment the already-disabled Email field used before this. */
.input--locked {
  background: color-mix(in srgb, var(--ink) 4%, var(--white));
  color: var(--ink-soft);
  cursor: default;
  display: flex;
  align-items: center;
  min-height: 39px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Says WHY it cannot be edited, once per field, without a control that would
   imply it could be. */
.ep-locked-tag {
  display: inline-block;
  margin-left: 4px;
  padding: 1px 6px;
  border-radius: 20px;
  background: color-mix(in srgb, var(--ink) 7%, var(--white));
  color: var(--ink-soft);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  vertical-align: 1px;
}
/* A drawn badge rather than the ⚠️ emoji: an emoji renders as a colour glyph
   on iOS, at its own size, next to type it is meant to sit inside. */
.spn-icon {
  flex-shrink: 0;
  width: 17px;
  height: 17px;
  margin-top: 1px;
  border-radius: 50%;
  background: var(--clay);
  color: var(--white);
  font-size: 11.5px;
  font-weight: 800;
  line-height: 17px;
  text-align: center;
}

.link-button {
  background: transparent;
  border: none;
  color: var(--clay);
  font-size: 12.5px;
  font-weight: 600;
  text-decoration: underline;
  cursor: pointer;
  padding: 4px 0;
  text-align: center;
  width: 100%;
}

/* ============================================================
   FORM ELEMENTS
============================================================ */

.field { display: flex; flex-direction: column; gap: 5px; }
.field-label { font-size: 12px; color: var(--ink-soft); font-weight: 600; }
/* Explanatory line under an input. Sits inside .field so it inherits the 5px
   gap rather than needing its own margin. */
.field-hint { font-size: 11px; color: var(--ink-soft); line-height: 1.45; }

.input {
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  font-size: 14px;
  font-family: inherit;
  background: var(--white);
  color: var(--ink);
}

.input:focus { border-color: var(--clay); }

/* Password show/hide. The wrapper is the positioning context only — it is
   `block` and adds no box of its own, so the field's width, height, border and
   radius are still entirely .input's. The single thing done TO the input is
   right padding, so typed characters stop before the icon instead of running
   under it. */
.pw-field { position: relative; display: block; }
.pw-field .input { padding-right: 42px; }
.pw-toggle {
  position: absolute;
  top: 50%;
  right: 4px;
  transform: translateY(-50%);
  /* 34px is this app's minimum touch target (see the operations dashboard's
     check-in pill, which was fixed for the same reason). The icon inside is
     18px; the rest is thumb room. */
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  background: none;
  color: var(--ink-soft);
  cursor: pointer;
  border-radius: var(--radius-sm);
}
.pw-toggle svg { width: 18px; height: 18px; display: block; }
.pw-toggle:hover { color: var(--ink); }
.pw-toggle:focus-visible { outline: 2px solid var(--clay); outline-offset: -2px; }

select.input {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='14' height='14'%3E%3Cpath d='M6 9l6 6 6-6' fill='none' stroke='%235B6B5E' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 32px;
}

/* ============================================================
   BUTTONS
============================================================ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 11px 18px;
  border-radius: var(--radius-sm);
  border: none;
  font-weight: 700;
  font-size: 13.5px;
  cursor: pointer;
  transition: transform 0.08s ease, filter 0.15s ease, box-shadow 0.15s ease;
}

.btn:active { transform: scale(0.98); filter: brightness(0.96); }

/* Hover lift only on devices that actually have a hover-capable pointer —
   gated behind (hover: hover) so this never gets "stuck" active on touch
   screens, which don't have a real hover state to clear it. */
@media (hover: hover) {
  .btn:not(:disabled):hover { filter: brightness(1.07); box-shadow: 0 4px 14px rgba(0, 0, 0, 0.14); }
}

/* ALL solid action buttons are GREEN app-wide (single action colour). */
.btn-primary { background: #2E9E5B; color: var(--white); }
.btn-primary:hover { background: #278A50; }
.btn-primary:disabled { background: var(--line); color: var(--ink-soft); cursor: not-allowed; }

.btn-ghost { background: var(--white); color: var(--ink); border: 1px solid var(--line); font-weight: 600; }

.btn-block { width: 100%; }

.btn-icon {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
  transition: transform 0.08s ease, background-color 0.15s ease;
}

.btn-icon:active { transform: scale(0.92); }

@media (hover: hover) {
  .btn-icon:hover { background-color: rgba(0, 0, 0, 0.06); }
}

/* This button had no rule sizing its icon at all — the svg has no intrinsic
   size of its own, so it was falling back to the browser default (~300px)
   and rendering hugely oversized inside this 36px button. */
.btn-icon svg {
  width: 18px;
  height: 18px;
}

/* ============================================================
   HOME HERO
============================================================ */

.home-hero {
  position: relative;
  background:
    radial-gradient(circle at 100% 0%, rgba(228, 242, 61, 0.12), transparent 55%),
    var(--ink);
  border-radius: 16px;
  padding: 18px;
  margin-bottom: 18px;
  overflow: hidden;
  color: var(--chalk);
}

.home-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 400'%3E%3Cg fill='none' stroke='%23FAF6EF' stroke-width='3' opacity='0.07'%3E%3Crect x='20' y='20' width='360' height='360' rx='4'/%3E%3Cline x1='20' y1='200' x2='380' y2='200'/%3E%3Cline x1='90' y1='20' x2='90' y2='380'/%3E%3Cline x1='310' y1='20' x2='310' y2='380'/%3E%3Cline x1='90' y1='140' x2='310' y2='140'/%3E%3Cline x1='90' y1='260' x2='310' y2='260'/%3E%3Cline x1='200' y1='20' x2='200' y2='140'/%3E%3Cline x1='200' y1='260' x2='200' y2='380'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 220px 220px;
  background-position: right -40px top -40px;
  background-repeat: no-repeat;
  pointer-events: none;
}

.community-row {
  display: flex;
  gap: 10px;
  margin: 14px 0 18px;
}

.community-stat {
  flex: 1;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 12px 10px;
  text-align: center;
}

.community-stat-count {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 24px;
  color: #3730A3;   /* Indigo 800 */
}

.community-stat-label {
  font-size: 11px;
  color: var(--ink-soft);
  font-weight: 600;
  margin-top: 2px;
}

/* ============================================================
   MARKETING / ABOUT BANNER (Home page, sits above the personal
   dashboard — same dark court-pattern treatment as .home-hero so the
   two cards read as one family rather than clashing styles).
============================================================ */

.marketing-banner {
  position: relative;
  background:
    radial-gradient(circle at 100% 0%, rgba(228, 242, 61, 0.12), transparent 55%),
    var(--ink);
  border-radius: 16px;
  padding: 20px 18px;
  margin-bottom: 18px;
  overflow: hidden;
  color: var(--chalk);
}

.marketing-banner::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 400'%3E%3Cg fill='none' stroke='%23FAF6EF' stroke-width='3' opacity='0.07'%3E%3Crect x='20' y='20' width='360' height='360' rx='4'/%3E%3Cline x1='20' y1='200' x2='380' y2='200'/%3E%3Cline x1='90' y1='20' x2='90' y2='380'/%3E%3Cline x1='310' y1='20' x2='310' y2='380'/%3E%3Cline x1='90' y1='140' x2='310' y2='140'/%3E%3Cline x1='90' y1='260' x2='310' y2='260'/%3E%3Cline x1='200' y1='20' x2='200' y2='140'/%3E%3Cline x1='200' y1='260' x2='200' y2='380'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 220px 220px;
  background-position: right -40px top -40px;
  background-repeat: no-repeat;
  pointer-events: none;
}

.marketing-banner-content {
  position: relative;
  z-index: 1;
}

.marketing-banner-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 22px;
  line-height: 1.15;
  text-transform: uppercase;
  letter-spacing: 0.3px;
}

.marketing-banner-title .accent {
  color: var(--ball);
}

.marketing-banner-subtext {
  margin-top: 8px;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.5;
  color: var(--ink-soft-on-dark);
  max-width: 440px;
}

.marketing-sports-row {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 16px;
}

.marketing-sport-chip {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--chalk);
}

.marketing-sport-chip-icon {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.marketing-sport-chip-icon svg {
  width: 14px;
  height: 14px;
}

/* All three CTA controls in one row: Learn More | Follow us | Join community.
   On mobile they wrap and centre; on ≥600px they sit on a single line. */
.marketing-banner-cta {
  margin-top: 18px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center; /* centre on narrow/mobile screens */
}

@media (min-width: 600px) {
  .marketing-banner-cta {
    justify-content: flex-start;
    flex-wrap: nowrap;
  }
}

/* keep old selector working in case anything else references it */
.marketing-banner-actions {
  margin-top: 18px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.marketing-banner-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.35);
  color: var(--chalk);
  border-radius: var(--radius-sm);
  padding: 10px 16px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  transition: background-color 0.15s ease, transform 0.08s ease;
}

.marketing-banner-btn:hover {
  background: rgba(255, 255, 255, 0.08);
}

.marketing-banner-btn:active {
  transform: scale(0.97);
}

/* .marketing-social-row kept for backward compat but no longer generated */
.marketing-social-row {
  margin-top: 10px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.marketing-social-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: var(--radius-sm);
  padding: 8px 14px;
  color: var(--chalk);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  transition: background-color 0.15s ease, transform 0.08s ease;
}

.marketing-social-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.marketing-social-icon svg {
  width: 18px;
  height: 18px;
}

.marketing-social-link:active {
  transform: scale(0.97);
}

@media (hover: hover) {
  .marketing-social-link:hover { background: rgba(255, 255, 255, 0.08); }
}

/* Professional social block: "Follow us" → row of icon buttons → Join community */
.marketing-social {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  margin-top: 22px;
}
.marketing-social-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
}
.marketing-social-row { display: flex; gap: 12px; }
.marketing-social-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  color: #fff; /* white glyph on the brand-coloured badge */
  border: 1px solid rgba(255, 255, 255, 0.22);
  box-shadow: 0 4px 12px -6px rgba(0, 0, 0, 0.6);
  transition: transform 0.15s ease, filter 0.2s ease;
}
.marketing-social-btn svg { width: 20px; height: 20px; }
/* Real platform brand colours */
.marketing-social-btn.social-ig { background: radial-gradient(circle at 30% 107%, #fdf497 0%, #fdf497 5%, #fd5949 45%, #d6249f 60%, #285AEB 90%); }
.marketing-social-btn.social-yt { background: #FF0000; }
.marketing-social-btn.social-tw { background: #000000; }
.marketing-social-btn.social-fb { background: #1877F2; }
.marketing-social-btn:active { transform: scale(0.93); }
@media (hover: hover) {
  .marketing-social-btn:hover { transform: translateY(-2px); filter: brightness(1.08); }
}
.marketing-join-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 2px;
  padding: 10px 20px;
  border-radius: 999px;
  background: #fff;
  color: var(--ink);
  font-weight: 700;
  font-size: 13px;
  box-shadow: 0 8px 20px -10px rgba(0, 0, 0, 0.55);
  transition: transform 0.15s ease;
}
.marketing-join-btn .marketing-join-icon { display: inline-flex; color: var(--grass); }
.marketing-join-btn .marketing-join-icon svg { width: 18px; height: 18px; }
.marketing-join-btn:active { transform: scale(0.97); }
@media (hover: hover) {
  .marketing-join-btn:hover { transform: translateY(-1px); }
}

.marketing-bio-panel {
  position: relative;
  z-index: 1;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.marketing-bio-panel p {
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.65;
  color: rgba(255, 255, 255, 0.92);
  margin: 0 0 12px;
}

.marketing-bio-panel p:last-child {
  margin-bottom: 0;
}

.marketing-bio-divider {
  height: 1px;
  background: rgba(255, 255, 255, 0.14);
  margin: 16px 0;
}

.marketing-bio-heading {
  font-family: var(--font-display);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--ball);
  margin-bottom: 7px;
}

.marketing-bio-closing {
  font-style: italic;
  text-align: center;
  color: rgba(255, 255, 255, 0.92);
}

/* Bled out to the full width of the card (cancelling .marketing-banner's
   18px side padding) and given room to breathe — at the card's own width
   the 4x3 grid's per-tile captions were too small to read comfortably. */
.marketing-bio-image {
  display: block;
  width: calc(100% + 36px);
  max-width: calc(100% + 36px);
  margin: 16px -18px -2px;
  border-radius: 0;
}

/* ============================================================
   TOP BAR
============================================================ */

.topbar {
  padding: 20px 16px 14px;
  background: var(--ink);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 12px;
}

.topbar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

.topbar-right {
  display: flex;
  flex: 1 1 auto;
  justify-content: flex-end;
  min-width: 0;
}

.topbar-logo {
  width: 56px;
  height: auto;
  flex-shrink: 0;
}

.topbar-title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 22px;
  color: var(--chalk);
  text-transform: uppercase;
  letter-spacing: -0.3px;
}

/* The academy name shares this rule rather than restating the values, so the
   two can never drift apart. Typography ONLY — margin is spacing, not type,
   and belongs to the subtitle alone. Font family and letter-spacing are
   deliberately absent: both elements inherit them from the page, so they
   already match, and naming them here would be a copy that can go stale. */
.topbar-sub,
.topbar-acad-name {
  font-size: 12.5px;
  color: var(--ink-soft-on-dark);
}
.topbar-sub { margin-top: 2px; }

/* ============================================================
   TAB BAR
============================================================ */

/* FIXED, not sticky: sticky only pins while the containing block is in view,
   so the bar could scroll out of reach inside long lists (rosters, standings,
   player lists). Fixed + centred keeps all six tabs on screen at all times
   while still respecting the 480px app shell on desktop. */
.tabbar {
  position: fixed;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  max-width: 480px;
  background: var(--ink);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  display: flex;
  justify-content: space-around;
  padding: 8px 2px calc(10px + env(safe-area-inset-bottom, 0px));
  z-index: 60;
}

/* The bar must track .app's responsive width exactly, otherwise it floats as a
   narrow strip over wider desktop content. These breakpoints mirror the .app
   rules above — keep them in sync if those ever change. */
@media (min-width: 700px) {
  .tabbar { max-width: 640px; border-radius: 0 0 28px 28px; }
}
@media (min-width: 1024px) {
  .tabbar { max-width: 760px; }
}
@media (min-width: 1440px) {
  .tabbar { max-width: 860px; }
}

.tab {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--tab-color, rgba(250, 246, 239, 0.55));
  opacity: 0.62;
  padding: 4px 2px;
  border-radius: 12px;
  /* flex-basis 0 + min-width 0 is what keeps all six tabs EXACTLY equal width.
     With the default min-width:auto a tab can't shrink below its label, so
     when the active label switched to bold it got wider and shoved every
     other tab sideways — the tabs visibly jumped on each switch. */
  flex: 1 1 0;
  min-width: 0;
  transition: color 0.15s ease, transform 0.08s ease;
}

.tab:active { transform: scale(0.92); }

.tab .icon { width: 20px; height: 20px; }

.tab-icon-wrap {
  position: relative;
  display: inline-flex;
}

.tab-badge {
  position: absolute;
  top: -4px;
  right: -7px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: 8px;
  background: var(--clay);
  color: var(--white);
  font-size: 9.5px;
  font-weight: 800;
  line-height: 15px;
  text-align: center;
  border: 1.5px solid var(--ink);
}

/* Six tabs have to fit a 360px phone without wrapping or clipping. The label
   is clipped rather than allowed to widen its tab, so nothing can reflow. */
.tab span {
  font-size: 9.5px;
  font-weight: 500;
  line-height: 1.15;
  text-align: center;
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (min-width: 400px) { .tab span { font-size: 10.5px; } }

/* "Community Games" is far longer than any other tab label, so it wraps onto
   two tight lines instead of ellipsising to "Communi…". The negative margin
   keeps the bar the same height as it was with one-line labels. */
.tab span.tab-2line {
  white-space: normal;
  line-height: 1.05;
  font-size: 8.8px;
  margin-bottom: -5px;
}
@media (min-width: 400px) { .tab span.tab-2line { font-size: 9.6px; } }

/* Each tab carries its OWN colour at all times, matching the icon set:
   Home warm orange, Players sky blue, Play teal, Tournaments gold,
   Rankings green, Profile warm grey. Because colour no longer signals which
   tab is selected, the active state is carried by full opacity + a bolder
   label + a heavier stroke + a soft tinted pill. */
/* One brand colour for every tab — the indigo AI/brand identity. The tab bar
   is dark, so this is the LIGHT indigo of the same family (Indigo 800 itself
   would disappear on ink); active tabs brighten, inactive stay muted. */
.tab[data-tab="home"],
.tab[data-tab="players"],
.tab[data-tab="community"],
.tab[data-tab="tournaments"],
.tab[data-tab="rankings"],
.tab[data-tab="profile"]     { --tab-color: #A5B4FC; }

.tab.active {
  opacity: 1;
  background: color-mix(in srgb, var(--tab-color) 15%, transparent);
}
.tab.active span { font-weight: 700; }
.tab.active .icon { stroke-width: 2.4; }
@media (hover: hover) { .tab:hover { opacity: 0.85; } }

/* ============================================================
   AVATAR
============================================================ */

.avatar {
  border-radius: 50%;
  background: var(--ink);
  color: var(--ball);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  flex-shrink: 0;
}

.avatar.ring { border: 2px solid var(--ball); }

/* ============================================================
   RATING BADGE
============================================================ */

.rating-badge {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.rating-ring {
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.rating-ring-inner {
  border-radius: 50%;
  background: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--chalk);
  font-family: var(--font-display);
  font-weight: 600;
  white-space: nowrap;
  letter-spacing: -0.5px;
}

.rating-badge-label {
  font-size: 11px;
  color: var(--ink-soft);
  font-weight: 600;
}

/* ============================================================
   SECTION LABEL
============================================================ */

.section-label {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 4px 0 10px;
}

/* Neutral grey — accent colours are reserved for states and actions, not
   decorative section icons. */
.section-label .icon { width: 14px; height: 14px; color: var(--ink-soft); }

.section-label span {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink);
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

/* ============================================================
   EMPTY STATE
============================================================ */

.empty-state {
  text-align: center;
  padding: 48px 24px;
  color: var(--ink-soft);
}

.empty-state .icon { width: 32px; height: 32px; opacity: 0.4; margin: 0 auto 10px; color: var(--ink-soft); display: inline-flex; align-items: center; justify-content: center; }
.empty-state .icon svg { width: 100%; height: 100%; }
.empty-state .icon.multi-sport { opacity: 0.9; width: 44px; height: 44px; }
.empty-state .empty-title { font-weight: 700; font-size: 15px; color: var(--ink); margin-bottom: 4px; }
.empty-state .empty-body { font-size: 13px; line-height: 1.5; }

/* ============================================================
   SCORECARD (signature element)
============================================================ */

.scorecard {
  background: var(--white);
  border-radius: 14px;
  border: 1px solid var(--line);
  overflow: hidden;
  margin-bottom: 12px;
}

.scorecard-header {
  background: var(--ink);
  padding: 8px 14px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.scorecard-tag {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--ball);
  font-weight: 700;
  letter-spacing: 0.5px;
}

.scorecard-time { font-size: 11px; color: rgba(250, 246, 239, 0.55); }

.scorecard-meta-row {
  padding: 0 16px 8px;
  font-size: 11.5px;
  color: rgba(250, 246, 239, 0.6);
}

.scorecard-body { padding: 14px 16px; }

.scorecard-matchup {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.scorecard-team {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 90px;
}

.scorecard-team.right { align-items: flex-end; }

.scorecard-player {
  display: flex;
  align-items: center;
  gap: 6px;
}

.scorecard-team.right .scorecard-player { flex-direction: row-reverse; }

.scorecard-player .pname { font-size: 13.5px; }
.scorecard-player .pname.winner { font-weight: 700; color: var(--ink); }
.scorecard-player .pname.loser { font-weight: 500; color: var(--ink-soft); }

.scorecard-score {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 600;
  color: var(--clay);
  padding: 0 10px;
  white-space: nowrap;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
}

/* Perspective WON/LOST badge shown immediately LEFT of the score on the
   Player Detail > Match History tab. Small, soft, premium — green for a win,
   red for a loss. */
.scorecard-result-badge {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  padding: 2px 7px;
  border-radius: 999px;
  font-family: var(--font);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.5px;
  line-height: 1.5;
  text-transform: uppercase;
}
.scorecard-result-badge.won { background: color-mix(in srgb, var(--grass) 16%, var(--white)); color: var(--grass); }
.scorecard-result-badge.lost { background: color-mix(in srgb, #c0392b 12%, var(--white)); color: #b23b30; }

.scorecard-footer {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.scorecard-footer-action {
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
  margin: 12px -16px -14px;
  padding: 12px 16px 14px;
  border-top: 1px solid var(--clay-light);
  background: rgba(210, 98, 46, 0.07);
  border-radius: 0 0 14px 14px;
}

.scorecard-prompt {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
}

.scorecard-prompt-icon {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  color: var(--clay);
  display: inline-flex;
}

.scorecard-prompt-icon svg { width: 100%; height: 100%; }

.scorecard-pending-label {
  font-size: 12px;
  color: var(--ink-soft);
  display: flex;
  align-items: center;
  gap: 5px;
}

.scorecard-actions { display: flex; gap: 6px; flex-shrink: 0; }

.scorecard-action-btn {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  background: var(--white);
  flex-shrink: 0;
}

/* Same gap as .btn-icon above — these approve/reject check/x icons (used on
   admin requests, organizer requests, join requests) had no svg sizing rule
   of their own, so they were rendering at the browser's oversized default
   instead of fitting this 30px button. */
.scorecard-action-btn svg {
  width: 16px;
  height: 16px;
}

.scorecard-action-btn.approve { background: var(--grass); border: none; color: var(--white); }
.scorecard-action-btn.reject { color: var(--danger); }

.scorecard-action-btn-labeled {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px 12px;
  border-radius: 9px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
}

.scorecard-action-btn-labeled svg { width: 15px; height: 15px; }

.scorecard-action-btn-labeled.approve {
  background: var(--grass);
  border: none;
  color: var(--white);
}

.scorecard-action-btn-labeled.reject {
  background: var(--white);
  border: 1px solid var(--line);
  color: var(--danger);
}

.scorecard-status {
  margin-top: 10px;
  font-size: 11.5px;
  font-weight: 600;
  display: flex;
  gap: 5px;
  align-items: center;
}

.scorecard-delete-link {
  background: transparent;
  border: none;
  color: var(--ink-soft);
  font-size: 11px;
  font-weight: 600;
  text-decoration: underline;
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
}

.scorecard-delete-link:hover { color: var(--danger); }

.scorecard-status svg {
  width: 13px;
  height: 13px;
  flex-shrink: 0;
}

.scorecard-status.confirmed { color: var(--grass); }
.scorecard-status.rejected { color: var(--danger); }

/* ============================================================
   CARDS / LISTS
============================================================ */

.card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 14px 16px;
}

.card-list-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  margin-bottom: 8px;
}

/* Fixed width so "NR" (no matches yet) doesn't make this column narrower
   than a real "X.XX" value — without it, the SGL/DBL block's overall width
   varies row to row and the whole block (it's flush against the row's right
   edge) drifts left/right depending on which rows show "NR", instead of the
   numbers lining up in a clean column down the list. */
.mini-rating { text-align: center; min-width: 38px; }
/* Rating numbers app-wide use warm bronze; "NR" (unrated) goes light grey
   so rated and unrated players separate at a glance. */
.ss-rating-val { color: #96775A !important; }
.mini-rating .val { font-family: var(--font-display); font-weight: 600; font-size: 16px; color: #96775A; }
.mini-rating .val.doubles { color: #96775A; }
.mini-rating .val.nr { color: #C2BCB2; font-weight: 500; }
.mini-rating .lbl { font-size: 9.5px; color: var(--ink-soft); font-weight: 700; }

/* ============================================================
   STAT CARDS
============================================================ */

.stat-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 10px;
}

.stat-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  min-width: 0;
}

.stat-card.accent-clay { border-color: var(--clay-light); }
.stat-card.accent-sky { border-color: var(--sky); }

.stat-label { font-size: 11px; color: var(--ink-soft); font-weight: 600; margin-bottom: 4px; }
.stat-value { font-family: var(--font-display); font-weight: 600; font-size: 22px; color: var(--ink); }
.stat-sub { font-size: 10.5px; color: var(--ink-soft); margin-top: 2px; }

/* Compact player summary strip (Player Detail > Overview) */
.player-summary-strip { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 9px; font-size: 13px; color: var(--ink-soft); margin: 2px 0 14px; }
.player-summary-strip strong { color: var(--ink); font-weight: 700; }
.player-summary-empty { font-style: italic; }
.player-summary-strip .pss-sep { color: var(--line); }
.player-summary-strip .pss-form { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.player-summary-strip .pss-form-label { font-size: 9.5px; font-weight: 700; letter-spacing: 0.7px; text-transform: uppercase; color: var(--ink-soft); opacity: 0.75; margin-right: 3px; }
.player-summary-strip .pss-w, .player-summary-strip .pss-l { display: inline-flex; align-items: center; justify-content: center; width: 19px; height: 19px; border-radius: 50%; font-size: 10.5px; font-weight: 800; }
.player-summary-strip .pss-w { background: color-mix(in srgb, var(--grass) 16%, var(--white)); color: var(--grass); }
.player-summary-strip .pss-l { background: color-mix(in srgb, #c0392b 12%, var(--white)); color: #b23b30; }

/* Reliability tag — "how settled is this rating", DUPR-style. Green when the
   rating is trusted, clay while it's still provisional (rating settling in). */
.rel-tag { display: inline-block; margin-top: 6px; font-size: 10px; font-weight: 700; letter-spacing: .02em; padding: 2px 8px; border-radius: 999px; background: color-mix(in srgb, var(--grass) 14%, var(--white)); color: var(--grass); border: 1px solid color-mix(in srgb, var(--grass) 32%, transparent); }
.rel-tag.provisional { background: color-mix(in srgb, var(--clay) 13%, var(--white)); color: var(--clay-dark); border-color: color-mix(in srgb, var(--clay) 30%, transparent); }

/* Info icon + tooltip beside "Rating Confidence". Shows on hover (desktop) and
   focus/tap (mobile — the span is focusable via tabindex). */
.rel-info { position: relative; display: inline-flex; align-items: center; margin: 0 1px 0 3px; vertical-align: -1px; cursor: help; opacity: 0.8; outline: none; }
.rel-info svg { display: block; }
.rel-tip {
  position: absolute; bottom: calc(100% + 7px); left: 50%; transform: translateX(-50%);
  width: 210px; max-width: 60vw;
  background: var(--ink); color: var(--white);
  font-family: var(--font); font-size: 11px; font-weight: 500; line-height: 1.45;
  letter-spacing: 0; text-transform: none; text-align: left;
  padding: 8px 10px; border-radius: 9px;
  box-shadow: 0 8px 22px -8px rgba(0,0,0,.45);
  opacity: 0; visibility: hidden; transition: opacity .14s ease; z-index: 60; pointer-events: none;
}
.rel-tip::after { content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border: 5px solid transparent; border-top-color: var(--ink); }
.rel-info:hover .rel-tip, .rel-info:focus .rel-tip, .rel-info:focus-visible .rel-tip { opacity: 1; visibility: visible; }
.rank-rel { margin-top: 3px; }

/* Tournament finish badge beside a draw's name on Player Detail > Tournaments.
   CHAMPION uses the warm highlighted achievement style; the other finishes use
   a subtle muted pill so they read as secondary. */
.tourn-result { display: inline-flex; align-items: center; flex-shrink: 0; margin-left: 8px; padding: 2px 8px; border-radius: 999px; font-size: 9px; font-weight: 800; letter-spacing: 0.6px; text-transform: uppercase; line-height: 1.5; white-space: nowrap; }
.tourn-result.champion { background: linear-gradient(135deg, color-mix(in srgb, var(--clay) 32%, var(--white)), color-mix(in srgb, #E4F23D 42%, var(--white))); color: var(--clay-dark); border: 1px solid color-mix(in srgb, var(--clay) 50%, transparent); }
.tourn-result.runnerup,
.tourn-result.semifinalist,
.tourn-result.quarterfinalist { background: color-mix(in srgb, var(--ink) 6%, var(--white)); color: var(--ink-soft); border: 1px solid var(--line); }

/* Player-detail Tournaments tab — each tournament is its own coloured card
   (accent supplied inline via --tg-accent), with a premium gold treatment for
   the ones the player actually won. */
.tourn-group {
  margin-bottom: 14px;
  border-radius: var(--radius-md);
  border: 1px solid color-mix(in srgb, var(--tg-accent, var(--clay)) 28%, var(--line));
  border-left: 4px solid var(--tg-accent, var(--clay));
  background: color-mix(in srgb, var(--tg-accent, var(--clay)) 6%, var(--white));
  overflow: hidden;
  transition: box-shadow 0.15s ease, transform 0.08s ease;
}
@media (hover: hover) {
  .tourn-group:hover { box-shadow: 0 5px 16px -8px color-mix(in srgb, var(--tg-accent, var(--clay)) 45%, transparent); }
}
.tourn-group .tourn-group-toggle { background: transparent; border: none; border-radius: 0; }
.tourn-group .tourn-group-toggle:hover { box-shadow: none; border: none; }
.tourn-group-ic { color: var(--tg-accent, var(--clay)); }
.tourn-group-body { padding: 2px 10px 10px; }
.tourn-group-body .card-list-row { background: var(--white); border: 1px solid var(--line); border-radius: 10px; margin-top: 8px; }

/* Champion cards — warm gold, so a win reads instantly as special. */
.tourn-group.champion {
  border-color: color-mix(in srgb, #D9A62E 55%, transparent);
  border-left-color: #D9A62E;
  background: linear-gradient(120deg, color-mix(in srgb, #EFCB57 22%, var(--white)), color-mix(in srgb, var(--clay) 9%, var(--white)));
  box-shadow: 0 5px 18px -9px color-mix(in srgb, #D9A62E 60%, transparent);
}
.tourn-group.champion .tourn-group-ic { color: #C0851A; }

/* ---- Shareable Player Card ------------------------------------------------
   Header entry button + the portrait (9:16) card rasterised by html2canvas.
   The card itself uses explicit hex colours (no var()/color-mix) so the
   exported PNG matches the on-screen preview exactly. */
.player-share-card-btn {
  display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0;
  padding: 7px 12px; border-radius: 999px; cursor: pointer;
  background: rgba(250,246,239,0.10); color: var(--chalk);
  border: 1px solid rgba(250,246,239,0.22);
  font-family: var(--font); font-size: 12px; font-weight: 600;
}
.player-share-card-btn:hover { background: rgba(250,246,239,0.18); }
/* Light-background variant for the Profile header (dark text on the chalk page).
   Slightly larger + bolder + a clay outline so it reads as the primary action,
   while staying an outlined button (not filled). */
.player-share-card-btn-light { flex-shrink: 0; padding: 9px 16px; font-size: 13px; font-weight: 700; background: var(--white); color: var(--clay-dark); border: 1.5px solid var(--clay); }
.player-share-card-btn-light svg { width: 15px; height: 15px; }
.player-share-card-btn-light:hover { background: color-mix(in srgb, var(--clay) 8%, var(--white)); border-color: var(--clay); color: var(--clay-dark); }

.pcard-stage { display: flex; justify-content: center; padding: 4px 0 16px; }
.player-overview-card { margin-top: 18px; }
/* Inline profile card — a touch wider than the default 320px, but not the
   full width (~70% of the column, centred). */
.player-overview-card .pcard-stage { padding: 8px 0 4px; }
.player-overview-card .pcard { width: 360px; max-width: 88%; }

.pcard {
  position: relative; overflow: hidden;
  width: 320px; aspect-ratio: 9 / 16;
  border-radius: 22px;
  background: linear-gradient(165deg, #16241A 0%, #1B3122 48%, #3A2317 100%);
  box-shadow: 0 18px 44px -18px rgba(0,0,0,0.55);
  color: #FFFCF5;
  padding: 26px 22px 20px;
  display: flex; flex-direction: column;
  font-family: var(--font);
}
.pcard-glow { position: absolute; top: -70px; right: -60px; width: 220px; height: 220px; border-radius: 50%; background: radial-gradient(circle, rgba(210,98,46,0.55), rgba(210,98,46,0) 70%); pointer-events: none; }

.pcard-top { position: relative; display: flex; align-items: center; justify-content: space-between; }
/* Logo + wordmark lockup. The mark always sits with the name — the shared
   card is the piece most likely to be screenshotted and reposted, so it has
   to carry the logo, not just the text. */
.pcard-brand { display: inline-flex; align-items: center; gap: 7px; font-family: var(--font-display); font-size: 15px; font-weight: 700; letter-spacing: 1px; color: #FFFCF5; }
.pcard-brand-logo { width: 22px; height: 22px; object-fit: contain; display: block; flex-shrink: 0; }
.pcard-brand-word { display: inline-block; line-height: 1; }
.pcard-brand-accent { color: #F0936A; }
.pcard-sport { font-size: 10px; font-weight: 700; letter-spacing: 1.2px; text-transform: uppercase; color: rgba(255,252,245,0.72); border: 1px solid rgba(255,252,245,0.24); padding: 3px 9px; border-radius: 999px; }

.pcard-hero { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; margin-top: 26px; }
.pcard-avatar {
  width: 96px; height: 96px; border-radius: 50%;
  background: linear-gradient(150deg, #D2622E, #A8431A);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-size: 36px; font-weight: 700; color: #FFFCF5;
  box-shadow: 0 0 0 4px rgba(255,252,245,0.10);
}
.pcard-name { font-family: var(--font-display); font-size: 25px; font-weight: 700; line-height: 1.12; margin-top: 14px; color: #FFFCF5; }
.pcard-role { font-size: 12px; color: rgba(255,252,245,0.65); margin-top: 4px; }

.pcard-rating { position: relative; text-align: center; margin-top: 22px; }
.pcard-rating-val { font-family: var(--font-display); font-size: 52px; font-weight: 700; line-height: 1; color: #F0936A; }
.pcard-rating-lbl { font-size: 10.5px; font-weight: 700; letter-spacing: 1.4px; text-transform: uppercase; color: rgba(255,252,245,0.62); margin-top: 6px; }

.pcard-stats { position: relative; display: flex; margin-top: 22px; background: rgba(255,252,245,0.07); border: 1px solid rgba(255,252,245,0.12); border-radius: 14px; padding: 12px 6px; }
.pcard-stat { flex: 1; text-align: center; }
.pcard-stat + .pcard-stat { border-left: 1px solid rgba(255,252,245,0.14); }
.pcard-stat .pc-v { font-family: var(--font-display); font-size: 20px; font-weight: 700; color: #FFFCF5; }
.pcard-stat .pc-l { font-size: 9.5px; font-weight: 700; letter-spacing: 0.8px; text-transform: uppercase; color: rgba(255,252,245,0.6); margin-top: 3px; }

.pcard-form { position: relative; margin-top: 20px; text-align: center; }
.pcard-form-lbl { font-size: 9.5px; font-weight: 700; letter-spacing: 1.2px; text-transform: uppercase; color: rgba(255,252,245,0.6); margin-bottom: 8px; }
.pcard-form-row { display: flex; justify-content: center; gap: 6px; }
.pcard-form-row .pc-chip { width: 26px; height: 26px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 800; }
.pc-chip.pc-w { background: rgba(63,135,83,0.26); color: #7FD79A; }
.pc-chip.pc-l { background: rgba(192,57,43,0.24); color: #F0A199; }
.pc-chip.pc-new { width: auto; padding: 0 12px; border-radius: 999px; background: rgba(255,252,245,0.1); color: rgba(255,252,245,0.75); letter-spacing: 1px; }

.pcard-footer { position: relative; margin-top: auto; padding-top: 14px; text-align: center; }
.pcard-footer-main { display: flex; align-items: center; justify-content: center; gap: 6px; font-size: 11px; font-weight: 700; letter-spacing: 0.6px; color: rgba(255,252,245,0.82); }
.pcard-footer-logo { width: 14px; height: 14px; object-fit: contain; display: block; opacity: 0.85; flex-shrink: 0; }
.pcard-footer-sub { font-size: 9.5px; font-weight: 600; letter-spacing: 0.7px; color: rgba(255,252,245,0.5); margin-top: 2px; }

/* Achievement badge (one, highest priority) — shown on every card. */
.pcard-ach { position: relative; display: inline-flex; align-items: center; gap: 5px; margin-top: 12px; max-width: 100%; padding: 5px 13px; border-radius: 999px; background: linear-gradient(135deg, rgba(210,98,46,0.30), rgba(228,242,61,0.20)); border: 1px solid rgba(240,147,106,0.55); color: #FCE8CF; font-size: 10.5px; font-weight: 700; letter-spacing: 0.4px; text-align: center; line-height: 1.3; }
.pcard-ach-ic { font-size: 12px; line-height: 1; flex-shrink: 0; }

/* Rating "since last update" sub-line (single-sport card). */
.pcard-rating-sub { font-size: 10px; font-weight: 600; color: #9FD8B0; margin-top: 5px; letter-spacing: 0.2px; }

/* Sport selector above the card (only when 2+ active sports). */
.pcard-select-row { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.pcard-select-lbl { font-size: 12px; font-weight: 700; color: var(--ink-soft); flex-shrink: 0; }
.pcard-select { flex: 1; }

/* ---- Multi-sport ("All Sports") card ---- */
.pcard-multi { padding-top: 22px; aspect-ratio: auto; height: auto; min-height: 569px; }
.pcard-hero-compact { margin-top: 18px; }
.pcard-avatar-sm { width: 70px; height: 70px; font-size: 26px; }
.pcard-name-sm { font-size: 22px; margin-top: 10px; }
.pcard-multisport-badge { margin-top: 10px; padding: 4px 13px; border-radius: 999px; background: rgba(255,252,245,0.10); border: 1px solid rgba(255,252,245,0.24); color: #FFFCF5; font-size: 10px; font-weight: 800; letter-spacing: 1.4px; text-transform: uppercase; }

.pcard-msrows { position: relative; margin-top: 18px; display: flex; flex-direction: column; gap: 8px; }
.pcard-msrow { display: flex; align-items: center; gap: 10px; padding: 9px 13px; background: rgba(255,252,245,0.07); border: 1px solid rgba(255,252,245,0.12); border-radius: 12px; }
.pcard-msrow-icon { width: 18px; height: 18px; flex-shrink: 0; color: #F0936A; display: inline-flex; }
.pcard-msrow-icon svg { width: 18px; height: 18px; }
.pcard-msrow-name { font-size: 13px; font-weight: 700; color: #FFFCF5; flex: 1; }
/* Rating is the prominent value; rank sits beneath it, smaller + muted. */
.pcard-msrow-stat { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.05; }
.pcard-msrow-rating { font-family: var(--font-display); font-size: 20px; font-weight: 700; color: #F0936A; }
.pcard-msrow-rank { font-family: var(--font); font-size: 10px; font-weight: 600; letter-spacing: 0.3px; color: rgba(255,252,245,0.62); margin-top: 2px; }

/* Public profile URL, small muted text just above the footer. */
.pcard-profile-url { position: relative; margin-top: 14px; text-align: center; font-size: 10px; font-weight: 500; letter-spacing: 0.3px; color: rgba(255,252,245,0.45); word-break: break-all; }

.pcard-overall { position: relative; margin-top: 16px; }
.pcard-overall-lbl { font-size: 9.5px; font-weight: 700; letter-spacing: 1.2px; text-transform: uppercase; color: rgba(255,252,245,0.55); text-align: center; margin-bottom: 8px; }
.pcard-overall-grid { display: flex; background: rgba(255,252,245,0.07); border: 1px solid rgba(255,252,245,0.12); border-radius: 12px; padding: 10px 4px; }
.pcard-ostat { flex: 1; text-align: center; }
.pcard-ostat + .pcard-ostat { border-left: 1px solid rgba(255,252,245,0.14); }
.pcard-ostat .pc-v { font-family: var(--font-display); font-size: 18px; font-weight: 700; color: #FFFCF5; }
.pcard-ostat .pc-l { font-size: 8px; font-weight: 700; letter-spacing: 0.4px; text-transform: uppercase; color: rgba(255,252,245,0.6); margin-top: 3px; line-height: 1.2; }

.pcard-actions { display: flex; gap: 8px; }
.pcard-act {
  flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 11px 8px; border-radius: 12px; cursor: pointer;
  background: var(--white); color: var(--ink);
  border: 1px solid var(--line);
  font-family: var(--font); font-size: 12.5px; font-weight: 700;
}
.pcard-act:hover { border-color: var(--clay); color: var(--clay-dark); }
.pcard-act:disabled { opacity: 0.55; cursor: default; }
.pcard-act svg { flex-shrink: 0; }

/* KrossRally Level chips — earned skill tier per sport (Level 1 Beginner →
   Level 6 Elite), colour-graded so higher tiers read hotter. "Provisional" is
   the neutral state before a Level is earned. */
.kr-level { display: inline-block; margin-top: 6px; font-size: 10.5px; font-weight: 700; letter-spacing: .01em; padding: 3px 9px; border-radius: 999px; border: 1px solid transparent; white-space: nowrap; }
.rank-level { margin-top: 4px; }
.kr-level.provisional { background: color-mix(in srgb, var(--ink) 6%, var(--white)); color: var(--ink-soft); border-color: var(--line); }
.kr-level.lvl-1 { background: color-mix(in srgb, var(--ink-soft) 12%, var(--white)); color: var(--ink-soft); border-color: color-mix(in srgb, var(--ink-soft) 26%, transparent); }
.kr-level.lvl-2 { background: color-mix(in srgb, var(--sky) 14%, var(--white)); color: var(--sky-dark); border-color: color-mix(in srgb, var(--sky) 32%, transparent); }
.kr-level.lvl-3 { background: color-mix(in srgb, var(--grass) 14%, var(--white)); color: var(--grass); border-color: color-mix(in srgb, var(--grass) 32%, transparent); }
.kr-level.lvl-4 { background: color-mix(in srgb, var(--clay) 13%, var(--white)); color: var(--clay-dark); border-color: color-mix(in srgb, var(--clay) 32%, transparent); }
.kr-level.lvl-5 { background: color-mix(in srgb, var(--clay) 24%, var(--white)); color: var(--clay-dark); border-color: color-mix(in srgb, var(--clay) 48%, transparent); }
.kr-level.lvl-6 { background: linear-gradient(135deg, color-mix(in srgb, var(--clay) 34%, var(--white)), color-mix(in srgb, #E4F23D 45%, var(--white))); color: var(--clay-dark); border-color: color-mix(in srgb, var(--clay) 52%, transparent); font-weight: 800; }

/* Level shown under the player's name on the rankings list — a small tier chip
   just below the "N matches · win%" line. */
.rank-level .kr-level { margin-top: 0; }
.rank-level .kr-level.provisional { background: none; border: none; padding: 0; color: var(--ink-soft); font-style: italic; font-weight: 600; }

/* Composable category builder (create-tournament modal) */
.cat-builder { display: flex; flex-direction: column; gap: 8px; padding: 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: color-mix(in srgb, var(--ink) 2%, var(--white)); }
.cat-builder-row { display: flex; gap: 8px; }
.cat-builder-row .input { flex: 1; min-width: 0; }
.cat-chip-list { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 10px; }
.cat-chip-empty { font-size: 12px; color: var(--ink-soft); font-style: italic; }
.cat-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--ink); background: color-mix(in srgb, var(--clay) 10%, var(--white)); border: 1px solid color-mix(in srgb, var(--clay) 30%, transparent); border-radius: 999px; padding: 4px 6px 4px 11px; }
.cat-chip.locked { background: color-mix(in srgb, var(--ink) 6%, var(--white)); border-color: var(--line); color: var(--ink-soft); padding-right: 11px; }
.cat-chip-x { display: inline-flex; align-items: center; justify-content: center; width: 17px; height: 17px; border: none; border-radius: 50%; background: color-mix(in srgb, var(--clay) 20%, transparent); color: var(--clay-dark); font-size: 14px; line-height: 1; cursor: pointer; }
.cat-chip-x:hover { background: var(--clay); color: var(--white); }

/* Live summary panel shown when a tournament status group is collapsed. */
.tp-panel { border: 1px solid var(--line); border-radius: 16px; overflow: hidden; margin-bottom: 14px; background: var(--white); box-shadow: 0 8px 26px -16px var(--tp); }
.tp-hero { position: relative; overflow: hidden; text-align: center; padding: 20px 16px 14px; background: linear-gradient(160deg, color-mix(in srgb, var(--tp) 16%, var(--white)), color-mix(in srgb, var(--tp) 4%, var(--white))); border-bottom: 1px solid color-mix(in srgb, var(--tp) 20%, transparent); }
.tp-hero-art { position: absolute; bottom: -24px; width: 128px; color: var(--tp); pointer-events: none; }
.tp-hero-art svg { width: 100%; height: auto; display: block; }
.tp-hero-art-right { right: -16px; opacity: 0.12; }
.tp-hero-art-left { left: -16px; transform: scaleX(-1); opacity: 0.07; }
.tp-hero .tp-title, .tp-hero .tp-sub { position: relative; z-index: 1; }
.tp-title { font-family: var(--font-display); font-weight: 800; font-size: 18px; color: color-mix(in srgb, var(--tp) 82%, var(--ink)); letter-spacing: .01em; text-transform: uppercase; line-height: 1.2; }
.tp-sub { font-size: 12.5px; color: var(--ink-soft); margin-top: 4px; display: inline-flex; align-items: center; gap: 7px; }
/* Live status dot now rides inline with the subtitle instead of a separate
   "OPEN FOR REGISTRATION" strip. Uses the panel's status colour (--tp). */
.tp-sub .tp-dot { position: relative; top: 0; }
.tp-stats { display: flex; padding: 15px 8px; }
.tp-stat { flex: 1; text-align: center; position: relative; }
.tp-stat + .tp-stat::before { content: ""; position: absolute; left: 0; top: 18%; height: 64%; width: 1px; background: var(--line); }
.tp-stat-num { font-family: var(--font-display); font-weight: 800; font-size: 25px; color: var(--tp); }
.tp-stat-label { font-size: 9.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); margin-top: 2px; }
.tp-now-label { display: flex; align-items: center; justify-content: center; gap: 7px; font-size: 11px; font-weight: 800; letter-spacing: .09em; color: var(--ink-soft); padding: 2px 0 11px; }
/* The pulsing dot takes the panel's status colour too (green/amber/blue),
   rather than a fixed red, so the whole panel reads as one status. */
.tp-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--tp, #e23b3b); animation: tpPulse 1.6s infinite; }
@keyframes tpPulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--tp, #e23b3b) 50%, transparent); }
  70%  { box-shadow: 0 0 0 7px color-mix(in srgb, var(--tp, #e23b3b) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--tp, #e23b3b) 0%, transparent); }
}
/* One tournament per line at every width — two-across read badly on laptop. */
.tp-now-grid { display: grid; grid-template-columns: 1fr; gap: 8px; padding: 0 12px 12px; }
.tp-now-card { display: flex; align-items: center; gap: 9px; text-align: left; cursor: pointer; padding: 9px 10px; border: 1px solid var(--line); border-radius: 11px; background: var(--white); transition: transform .12s ease, box-shadow .2s ease; }
.tp-now-card:hover { transform: translateY(-1px); box-shadow: 0 5px 14px -8px rgba(0,0,0,.3); }
.tp-now-icon { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 9px; color: #fff; flex-shrink: 0; }
.tp-now-icon svg { width: 17px; height: 17px; }
.tp-now-text { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.tp-now-sport { font-size: 9.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.tp-now-name { font-size: 12.5px; font-weight: 700; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tp-now-stage { font-size: 11px; color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tp-now-badge { flex-shrink: 0; font-size: 8.5px; font-weight: 800; letter-spacing: .04em; padding: 2px 6px; border-radius: 999px; }
.tp-badge-in_progress { background: color-mix(in srgb, #e23b3b 14%, var(--white)); color: #c0392b; }
.tp-badge-registering { background: color-mix(in srgb, var(--grass) 16%, var(--white)); color: var(--grass); }
.tp-badge-completed { background: color-mix(in srgb, var(--ink) 8%, var(--white)); color: var(--ink-soft); }
.tp-view-btn { display: flex; align-items: center; justify-content: center; gap: 7px; width: 100%; padding: 12px; border: none; border-top: 1px solid var(--line); background: color-mix(in srgb, var(--tp) 8%, var(--white)); color: color-mix(in srgb, var(--tp) 80%, var(--ink)); font-weight: 700; font-size: 13px; cursor: pointer; }
.tp-view-btn:hover { background: color-mix(in srgb, var(--tp) 15%, var(--white)); }
.tp-view-chevron { display: inline-flex; width: 15px; height: 15px; }
.tp-view-chevron svg { width: 100%; height: 100%; }

/* Per-tournament collapse/expand chevron badge on the corner of each card, and
   the compact one-line row shown when a tournament is collapsed. */
.t-toggle-btn { position: absolute; top: -8px; right: -8px; width: 24px; height: 24px; border-radius: 50%; border: 1.5px solid var(--line); background: var(--white); color: var(--ink-soft); display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 2px 6px -2px rgba(0,0,0,.35); z-index: 3; padding: 0; }
.t-toggle-btn svg { width: 14px; height: 14px; }
.t-toggle-btn:hover { background: color-mix(in srgb, var(--ink) 6%, var(--white)); color: var(--ink); }
.t-compact-row { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; cursor: pointer; padding: 12px 44px 12px 14px; margin-bottom: 12px; border-radius: 14px; background: var(--white); }
.t-compact-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.t-compact-name { flex: 1; min-width: 0; font-weight: 800; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ============================================================
   PILLS / BADGES
============================================================ */

.pill {
  font-size: 10.5px;
  font-weight: 700;
  padding: 4px 9px;
  border-radius: 20px;
  white-space: nowrap;
}

.pill-registering { background: var(--grass-light); color: var(--grass-dark); }
.pill-in_progress { background: #FBE7A1; color: #7A5B00; }
.pill-completed { background: #CDE3FB; color: #1D4E89; }
.pill-pending { background: #F6E2C6; color: #8A5216; }

.chip {
  font-size: 12px;
  background: var(--line);
  padding: 5px 10px;
  border-radius: 20px;
  color: var(--ink);
}

/* ============================================================
   COMMUNITY GAMES (sessions)
   Visually distinct from tournament cards on purpose: a session leads with
   WHEN it starts (the thing a player actually decides on), uses the grass
   accent rather than clay, and never shows brackets or prize money.
============================================================ */
.cg-card {
  position: relative;
  display: flex;
  gap: 12px;
  background: var(--white);
  border: 1.8px solid color-mix(in srgb, var(--grass) 40%, var(--white));
  border-radius: 14px;
  padding: 14px 52px 14px 14px;
  margin-bottom: 12px;
  box-shadow: 0 4px 14px -10px rgba(22, 36, 26, 0.28);
}
.cg-open {
  position: absolute;
  top: 50%;
  right: 12px;
  transform: translateY(-50%);
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid color-mix(in srgb, var(--grass) 45%, var(--line));
  border-radius: 10px;
  background: var(--white);
  color: var(--grass);
  cursor: pointer;
}
.cg-when {
  flex-shrink: 0;
  width: 62px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  background: color-mix(in srgb, var(--grass) 10%, var(--white));
  border-radius: 10px;
  padding: 8px 4px;
}
.cg-day { font-size: 11.5px; font-weight: 700; color: var(--grass-dark, var(--grass)); text-align: center; line-height: 1.25; }
.cg-time { font-size: 11px; font-weight: 600; color: var(--ink-soft); }
.cg-body { min-width: 0; flex: 1; }
.cg-name { font-weight: 800; font-size: 16px; color: var(--ink); margin-bottom: 3px; }
.cg-meta { font-size: 12px; color: var(--ink-soft); font-weight: 600; margin-bottom: 5px; }
.cg-fmt { color: var(--grass); font-weight: 700; }
.cg-dot { margin: 0 4px; }
.cg-line { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-soft); font-weight: 500; margin-bottom: 4px; }
.cg-ic { width: 13px; height: 13px; flex-shrink: 0; display: inline-flex; color: var(--ink-soft); }
.cg-ic svg { width: 100%; height: 100%; }
.cg-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 7px; }
.cg-chip {
  font-size: 11px;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 6%, var(--white));
  color: var(--ink-soft);
  white-space: nowrap;
}
.cg-chip-full { background: color-mix(in srgb, #C22B2B 12%, var(--white)); color: #8E1F1F; }
.cg-chip-host { background: color-mix(in srgb, var(--grass) 12%, var(--white)); color: var(--grass); }

/* Back row sits directly under the top bar, matching the tournament detail
   page, and stays pinned so it's always one tap away while scrolling. */
.cg-detail-back {
  position: sticky;
  top: 52px;
  z-index: 30;
  padding: 10px 16px;
  background: color-mix(in srgb, var(--chalk) 94%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
/* .back-link is near-WHITE by default because on the tournament page it sits
   on a dark hero. On this light background it was invisible — which read as
   "there's no way back". Force a dark, obviously-tappable colour here. */
.cg-detail-back .back-link {
  color: var(--ink);
  font-weight: 700;
  font-size: 13.5px;
  margin-bottom: 0;
  padding: 4px 0;
}
.cg-detail-back .back-link span { color: var(--clay); }

.cg-share-preview {
  white-space: pre-wrap;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--ink);
  background: color-mix(in srgb, var(--ink) 4%, var(--white));
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px;
  margin-bottom: 12px;
  max-height: 200px;
  overflow-y: auto;
}

/* Rounds + live score entry */
.cg-round { border: 1.5px solid var(--line); border-radius: 12px; padding: 10px; margin-bottom: 10px; }
.cg-round-head { display: flex; align-items: center; justify-content: space-between; font-size: 12px; font-weight: 800; color: var(--ink-soft); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 8px; }
.cg-round-count { font-size: 10.5px; font-weight: 700; color: var(--ink-soft); text-transform: none; letter-spacing: 0; }

/* Status is PER MATCH, not per round — two courts in the same round routinely
   finish minutes apart, so a round-level badge hid which court was still out. */
.cg-score-wrap { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex-shrink: 0; }
.cg-match-status {
  font-size: 9.5px;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 999px;
  white-space: nowrap;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.cg-match-status.done { color: var(--grass); background: color-mix(in srgb, var(--grass) 13%, var(--white)); }
.cg-match-status.waiting { color: var(--ink-soft); background: color-mix(in srgb, var(--ink) 7%, var(--white)); }
.cg-court { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.cg-court:last-of-type { border-bottom: none; }
.cg-court-no {
  font-size: 10px; font-weight: 800; color: var(--ink-soft);
  width: 38px; flex-shrink: 0; text-align: center; line-height: 1.25;
  text-transform: uppercase; letter-spacing: 0.03em;
}
.cg-court-teams { flex: 1; min-width: 0; }
/* Each team's score sits on that team's own row, so the score column reads in
   the same top-to-bottom order as the names. */
.cg-line { display: flex; align-items: center; gap: 10px; }
.cg-line .cg-team { flex: 1; min-width: 0; }
.cg-team { font-size: 13px; font-weight: 600; color: var(--ink); line-height: 1.35; }
.cg-team.win { font-weight: 800; color: var(--grass); }
.cg-vs { font-size: 10.5px; color: var(--ink-soft); margin: 3px 0; }
.cg-sc {
  width: 46px; padding: 6px 4px; text-align: center; flex-shrink: 0;
  border: 1.5px solid var(--line); border-radius: 8px;
  font-family: inherit; font-size: 14px; font-weight: 700; color: var(--ink); background: var(--white);
}
.cg-sc:focus { outline: none; border-color: var(--grass); }
.cg-score-out {
  font-size: 15px; font-weight: 800; color: var(--ink);
  flex-shrink: 0; width: 46px; text-align: center;
}

/* Organiser's points-per-match target, at the top of the rounds list. */
.cg-points-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 12px; margin-bottom: 12px;
  border: 1.5px solid var(--line); border-radius: 12px;
  background: color-mix(in srgb, var(--grass) 6%, var(--white));
}
.cg-points-bar.readonly { justify-content: flex-start; }
.cg-points-label { font-size: 12.5px; font-weight: 800; color: var(--ink); }
.cg-points-hint { font-size: 11px; color: var(--ink-soft); line-height: 1.4; margin-top: 2px; }
.cg-points-set { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.cg-sitout { font-size: 11.5px; color: var(--ink-soft); margin-top: 8px; font-style: italic; }

/* Live standings */
.cg-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.cg-table th { text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-soft); padding: 6px 4px; border-bottom: 1px solid var(--line); }
.cg-table td { padding: 8px 4px; border-bottom: 1px solid var(--line); color: var(--ink); }
.cg-table tr:last-child td { border-bottom: none; }
.cg-table tr.cg-lead td { background: color-mix(in srgb, var(--grass) 8%, var(--white)); }

.cg-rating { font-size: 11.5px; font-weight: 700; color: var(--ink-soft); margin-left: 5px; }
.cg-checked { width: 15px; height: 15px; display: inline-flex; color: var(--grass); flex-shrink: 0; }
.cg-checked svg { width: 100%; height: 100%; }

/* ---- community game entry fees ----
   Two audiences, two shapes. A PLAYER gets one number and one button; an
   ORGANISER gets the whole list at once, because people queue in front of them
   and a per-player drill-down is a queue that stops moving. */
.cg-pay { margin-bottom: 14px; }
.cg-pay__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.cg-pay__t { font-weight: 700; font-size: 14px; color: var(--ink); }
.cg-pay__s { font-size: 12px; color: var(--ink-soft); margin-top: 3px; line-height: 1.45; }
.cg-pay__amt { font-size: 22px; font-weight: 800; letter-spacing: -.03em; color: var(--ink); flex-shrink: 0; font-variant-numeric: tabular-nums; }
.cg-pay__qr { display: flex; justify-content: center; margin: 12px 0; min-height: 160px; align-items: center; }
.cg-pay__qr img, .cg-pay__qr canvas { border-radius: 10px; }
.cg-pay__wait {
  margin-top: 10px; text-align: center; font-size: 12px; font-weight: 600;
  color: var(--clay-dark, #A8431A); background: color-mix(in srgb, var(--clay, #D2622E) 10%, transparent);
  border-radius: 999px; padding: 8px 12px;
}
/* Settled. No button, no amount competing with it — just the fact. */
.cg-pay--done { display: flex; align-items: center; gap: 12px; }
.cg-pay__tick {
  width: 32px; height: 32px; flex-shrink: 0; border-radius: 50%; display: grid; place-items: center;
  background: color-mix(in srgb, var(--grass, #3F8753) 14%, transparent); color: var(--grass-dark, #1B7A43);
}
.cg-pay__tick svg { width: 17px; height: 17px; }

.cg-desk__totals { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 12px; }
.cg-desk__totals > div { text-align: center; }
.cg-desk__n { display: block; font-size: 17px; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.cg-desk__l { display: block; font-size: 9.5px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); margin-top: 3px; }
.cg-desk { display: flex; flex-direction: column; }
.cg-desk__row {
  display: flex; align-items: center; gap: 10px; padding: 9px 0;
  border-bottom: 1px solid var(--line, #E3E0DA);
}
.cg-desk__row:last-child { border-bottom: 0; }
.cg-desk__name { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 600; display: flex; align-items: center; gap: 6px; }
.cg-desk__in { width: 13px; height: 13px; color: var(--grass, #3F8753); display: inline-flex; flex-shrink: 0; }
.cg-desk__in svg { width: 100%; height: 100%; }
.cg-desk__state { flex-shrink: 0; }
.cg-desk__ok { font-size: 11px; font-weight: 700; color: var(--grass-dark, #1B7A43); }
/* A claim is somebody's word, not money. Coloured as pending, never as paid. */
.cg-desk__claim { font-size: 11px; font-weight: 700; color: var(--clay-dark, #A8431A); }
.cg-desk__row.is-paid .cg-desk__name { color: var(--ink-soft); }
.cg-cta-in {
  font-size: 13px; font-weight: 700; color: var(--grass);
  background: color-mix(in srgb, var(--grass) 10%, var(--white));
  border-radius: 10px; padding: 11px 14px; margin-bottom: 8px; text-align: center;
}
.cg-cta-wait {
  font-size: 12.5px; font-weight: 600; color: var(--ink-soft);
  background: color-mix(in srgb, var(--ink) 5%, var(--white));
  border-radius: 10px; padding: 11px 14px; margin-bottom: 8px; text-align: center;
}

.cg-req-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 2px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.cg-req-row:last-child { border-bottom: none; }
.cg-req-name { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.cg-req-actions { display: flex; gap: 6px; flex-shrink: 0; }

/* Upcoming / Past segmented toggle */
.cg-seg { display: inline-flex; border: 1.5px solid var(--line); border-radius: 999px; overflow: hidden; }
.cg-seg-btn {
  border: none;
  background: var(--white);
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  padding: 7px 14px;
  cursor: pointer;
}
.cg-seg-btn.active { background: var(--grass); color: var(--white); font-weight: 700; }

/* Compact location dropdown popover on the Tournaments page. */
.loc-popover {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 50;
  width: 260px;
  max-width: 82vw;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 16px 40px -14px rgba(22, 36, 26, 0.45);
  padding: 12px;
}

/* Two-step Date picker (Month + Year chips) inside the Date dropdown. */
.date-facet-label { font-size: 12px; font-weight: 700; color: var(--ink-soft); margin-bottom: 8px; }
.date-chip-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.date-chip {
  padding: 7px 4px;
  border: 1.5px solid var(--line);
  border-radius: 8px;
  background: var(--white);
  color: var(--ink);
  font-size: 12.5px;
  font-family: inherit;
  cursor: pointer;
  text-align: center;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
@media (hover: hover) { .date-chip:hover { border-color: color-mix(in srgb, var(--clay) 45%, var(--line)); } }
.date-chip.active { background: var(--clay); border-color: var(--clay); color: var(--white); font-weight: 700; }

/* Faceted location filter panel (State / City) on the Tournaments page. */
.filters-panel { border: 1px solid var(--line); border-radius: 12px; background: var(--white); margin-bottom: 14px; overflow: hidden; }
.filters-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px; border-bottom: 1px solid var(--line); }
.filters-title { font-size: 15px; font-weight: 800; color: var(--ink); }
.filters-clear { background: none; border: none; color: var(--clay); font-size: 13px; font-weight: 600; text-decoration: underline; cursor: pointer; padding: 0; }
.filter-facet { border-bottom: 1px solid var(--line); }
.filter-facet:last-child { border-bottom: none; }
.filter-facet-head { width: 100%; display: flex; align-items: center; justify-content: space-between; padding: 12px 14px; background: none; border: none; cursor: pointer; font-size: 13.5px; font-weight: 700; color: var(--ink); text-align: left; }
.filter-facet-chev { width: 16px; height: 16px; color: var(--ink-soft); flex-shrink: 0; }
.filter-facet-chev svg { width: 100%; height: 100%; }
.filter-facet-body { padding: 0 14px 12px; }
.filter-search { position: relative; display: flex; align-items: center; margin-bottom: 8px; }
.filter-search-ic { position: absolute; left: 10px; width: 15px; height: 15px; color: var(--ink-soft); pointer-events: none; }
.filter-search-ic svg { width: 100%; height: 100%; }
.filter-search-input { width: 100%; padding: 9px 10px 9px 32px; border: 1px solid var(--line); border-radius: 8px; font-size: 13px; font-family: inherit; color: var(--ink); background: var(--white); }
.filter-search-input:focus { outline: none; border-color: var(--grass); }
.filter-checklist { max-height: 220px; overflow-y: auto; display: flex; flex-direction: column; }
.filter-check { display: flex; align-items: center; gap: 10px; padding: 7px 2px; cursor: pointer; font-size: 13.5px; color: var(--ink); }
.filter-check input { position: absolute; opacity: 0; width: 0; height: 0; }
.filter-check-box { width: 20px; height: 20px; border: 1.5px solid var(--line); border-radius: 6px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; color: var(--white); transition: background 0.15s ease, border-color 0.15s ease; }
.filter-check-box svg { width: 13px; height: 13px; }
.filter-check input:checked + .filter-check-box { background: var(--clay); border-color: var(--clay); }
.filter-check-label { line-height: 1.2; }
.filter-empty { font-size: 13px; color: var(--ink-soft); padding: 8px 2px; }

/* ============================================================
   FILTER CHIPS (rankings)
============================================================ */

.filter-row {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding-bottom: 12px;
}

.filter-chip {
  white-space: nowrap;
  padding: 8px 14px;
  border-radius: 20px;
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--ink);
  font-weight: 600;
  font-size: 12.5px;
  cursor: pointer;
  flex-shrink: 0;
}

.filter-chip.active { border-color: var(--clay); background: var(--clay); color: var(--white); }

.filter-chip-sub {
  padding: 6px 12px;
  font-size: 11.5px;
  font-weight: 600;
  border-radius: 16px;
}

.filter-chip-sub.active { border-color: var(--ink); background: var(--ink); color: var(--chalk); }

/* ============================================================
   RANKINGS TABLE
============================================================ */

/* Rating-tier filter: Official / Establishing / Unrated. */
.rank-status-tabs { display: flex; gap: 6px; margin-bottom: 8px; }
.rank-status-tab { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 8px 6px; border-radius: 999px; border: 1px solid var(--line); background: var(--white); color: var(--ink-soft); font-family: var(--font); font-size: 12.5px; font-weight: 600; cursor: pointer; }
.rank-status-tab.active { background: var(--clay); border-color: var(--clay); color: var(--white); }
.rank-status-count { font-size: 11px; font-weight: 700; background: color-mix(in srgb, var(--ink) 8%, transparent); border-radius: 999px; padding: 1px 6px; }
.rank-status-tab.active .rank-status-count { background: rgba(255,255,255,0.25); }
.rank-status-note { font-size: 11.5px; color: var(--ink-soft); margin-bottom: 12px; line-height: 1.4; }

/* Establishing-tier qualification progress toward the Official leaderboard. */
.rank-qual-metrics { display: flex; flex-direction: column; gap: 1px; margin: 4px 0 6px; font-size: 11px; color: var(--ink-soft); }
.rank-qual-metrics b { color: var(--ink); font-weight: 700; }
.rank-progress-bar { height: 5px; border-radius: 999px; background: var(--line); overflow: hidden; max-width: 230px; }
.rank-progress-fill { height: 100%; border-radius: 999px; background: var(--grass); }
.rank-qual-status { font-size: 10.5px; font-weight: 600; color: var(--clay-dark); margin-top: 5px; }
.rank-no-match { text-align: center; padding: 16px 12px; font-size: 12.5px; color: var(--ink-soft); }
.rank-qual-ready { color: var(--grass); font-weight: 800; }
.rank-ready-mini { font-size: 9px; font-weight: 800; color: var(--grass); margin-top: 4px; white-space: nowrap; line-height: 1.2; }

/* Pinned "YOU" card at the very top of Rankings — a full themed card,
   colour-coded by tier (tinted fill + matching border, inside and out). */
/* Clean YOU card: white inside, Indigo 800 border, green rating — the tier
   is text, not a colour wash. */
.you-card { display: flex; align-items: center; gap: 13px; margin-bottom: 14px; padding: 14px 16px; border-radius: 16px; border: 1.8px solid #3730A3; background: var(--white); box-shadow: 0 4px 14px -10px rgba(55, 48, 163, 0.35); }
.you-card.you-official .you-card-score,
.you-card.you-establishing .you-card-score { color: #96775A; }
.you-card.you-unrated .you-card-score { color: var(--ink-soft); }
.you-tag { flex-shrink: 0; display: inline-block; font-size: 10px; font-weight: 800; letter-spacing: 0.8px; color: var(--white); background: var(--ink); border-radius: 6px; padding: 3px 8px; }
.you-card-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
/* Badge lives INSIDE the name line (not as a side column), so the name, the
   board label and the tier line all start at the same left edge. */
.you-name { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 15px; color: var(--ink); min-width: 0; }
.you-name-text { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.you-sub { font-size: 11.5px; color: var(--ink-soft); }
.you-tier-line { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 8px; margin-top: 4px; }
.you-progress { height: 4px; border-radius: 999px; background: color-mix(in srgb, var(--ink) 8%, var(--white)); overflow: hidden; margin-top: 7px; max-width: 240px; }
.you-progress-fill { height: 100%; border-radius: 999px; background: var(--grass); }
.you-card-score-wrap { flex-shrink: 0; text-align: right; align-self: center; }
.you-card-score-lbl { font-size: 8.5px; font-weight: 700; letter-spacing: 0.6px; text-transform: uppercase; color: var(--ink-soft); margin-top: 1px; }
.you-tier-badge { display: inline-block; font-size: 9.5px; font-weight: 800; letter-spacing: 0.6px; text-transform: uppercase; padding: 2px 9px; border-radius: 999px; }
.you-tier-official { background: color-mix(in srgb, var(--ink) 6%, var(--white)); color: var(--ink-soft); }
.you-tier-establishing { background: color-mix(in srgb, var(--ink) 6%, var(--white)); color: var(--ink-soft); }
.you-tier-unrated { background: color-mix(in srgb, var(--ink) 8%, var(--white)); color: var(--ink-soft); }
.you-detail { font-size: 11.5px; font-weight: 600; color: var(--ink-soft); }
.you-card-score { flex-shrink: 0; font-family: var(--font-display); font-size: 22px; font-weight: 700; color: #96775A; }

/* Tier filter tabs — each active tier in its own colour. */
.rank-status-tab[data-rank-status="official"].active { background: var(--grass); border-color: var(--grass); }
.rank-status-tab[data-rank-status="establishing"].active { background: var(--clay); border-color: var(--clay); }
.rank-status-tab[data-rank-status="unrated"].active { background: var(--ink-soft); border-color: var(--ink-soft); }
.rank-score.rank-score-empty { font-size: 12px; font-weight: 600; color: var(--ink-soft); text-align: right; line-height: 1.3; }

.rank-list {
  background: var(--white);
  border-radius: 14px;
  border: 1px solid var(--line);
  overflow: hidden;
}

.rank-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
}

.rank-row:last-child { border-bottom: none; }
.rank-row.top { background: rgba(217, 232, 78, 0.12); }

.rank-num {
  width: 26px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  color: var(--ink-soft);
  text-align: center;
}

.rank-num.crown { color: var(--clay-dark); }

.rank-info { flex: 1; }
.rank-name { font-weight: 700; font-size: 14px; color: var(--ink); }
.rank-meta { font-size: 11px; color: var(--ink-soft); }
/* Fixed width + right-align: "Unrated" is far wider than a real "X.XX"
   value, and since this sits after .rank-stat (a fixed-width block) in the
   row's flex flow with .rank-info absorbing the leftover space, an
   unconstrained width here made .rank-stat's column drift left on every row
   that happened to say "Unrated" instead of a number. */
.rank-score { font-family: var(--font-display); font-weight: 600; font-size: 18px; color: #96775A; min-width: 72px; text-align: right; flex-shrink: 0; }
.rank-score.doubles { color: #96775A; }

/* Podium — top 3 stand out as gold / silver / bronze cards, each distinct. */
.rank-top { border-radius: 13px; margin-bottom: 9px; border: 1.6px solid var(--line); }
.rank-top .rank-name { font-weight: 800; }
.rank-top .rank-medal { font-size: 23px; line-height: 1; display: inline-block; }
.rank-top-1 { background: linear-gradient(100deg, color-mix(in srgb, #E7B400 20%, var(--white)), var(--white) 62%); border-color: color-mix(in srgb, #E7B400 60%, transparent); box-shadow: 0 6px 18px -9px #E7B400; }
.rank-top-2 { background: linear-gradient(100deg, color-mix(in srgb, #9AA6B2 20%, var(--white)), var(--white) 62%); border-color: color-mix(in srgb, #9AA6B2 60%, transparent); box-shadow: 0 6px 18px -10px #9AA6B2; }
.rank-top-3 { background: linear-gradient(100deg, color-mix(in srgb, #C77B3B 18%, var(--white)), var(--white) 62%); border-color: color-mix(in srgb, #C77B3B 55%, transparent); box-shadow: 0 6px 18px -10px #C77B3B; }
.rank-top-1 .rank-score { color: #96775A; }
.rank-top-3 + .rank-row:not(.rank-top) { margin-top: 6px; }

.rank-stats { display: flex; gap: 12px; align-items: center; flex-shrink: 0; }
.rank-stat { text-align: center; min-width: 32px; flex-shrink: 0; }
.rank-stat-value { font-family: var(--font-display); font-weight: 600; font-size: 13px; color: var(--ink); }
.rank-stat-label { font-size: 9px; color: var(--ink-soft); font-weight: 700; text-transform: uppercase; letter-spacing: 0.3px; }

/* ============================================================
   TREND / STREAK BADGES (rank movement, rating change, win streaks)
============================================================ */

.trend-pill {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 11px;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 10px;
  white-space: nowrap;
}

.trend-pill .trend-icon { width: 11px; height: 11px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; }
.trend-pill .trend-icon svg { width: 100%; height: 100%; }
.trend-pill.up { background: var(--grass-light); color: var(--grass-dark); }
.trend-pill.down { background: rgba(194, 59, 59, 0.12); color: var(--danger); }
.trend-pill.flat { background: var(--line); color: var(--ink-soft); }

.streak-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 14px;
  color: var(--clay-dark);
}

.streak-badge .streak-icon { width: 14px; height: 14px; color: var(--clay); flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; }
.streak-badge .streak-icon svg { width: 100%; height: 100%; }
.streak-badge.cold { color: var(--ink-soft); }
.streak-badge.cold .streak-icon { color: var(--ink-soft); }

.form-dots { display: flex; gap: 3px; align-items: center; }
.form-dot {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  font-size: 9.5px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.form-dot.w { background: var(--grass); color: var(--white); }
.form-dot.l { background: var(--line); color: var(--ink-soft); }

/* ============================================================
   HOME DASHBOARD CARDS
============================================================ */

.dash-grid { display: flex; flex-direction: column; gap: 10px; margin-bottom: 18px; }

.dash-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 14px;
}

/* This is a <summary> (the dash-card is a <details>), but the browser's
   own disclosure triangle looks like a stray bullet next to the heading
   rather than an intentional control — so it's suppressed below in favor
   of laying the summary out as a flex row with an explicit chevron icon
   pinned to the right (.dash-card-chevron), matching the disclosure
   affordance used everywhere else in the app. */
.dash-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
  cursor: pointer;
  list-style: none;
}

.dash-card-head::marker,
.dash-card-head::-webkit-details-marker {
  display: none;
  content: "";
}

.dash-card-chevron {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-soft);
  transition: transform 0.15s ease;
}

.dash-card-chevron svg { width: 100%; height: 100%; }

/* Chevron points down (collapsed-looking) by default and flips to point up
   once the card is actually open — driven purely by the <details> element's
   own [open] attribute, no JS listener needed. */
.dash-card[open] .dash-card-chevron {
  transform: rotate(180deg);
}

.dash-card-sport {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 14px;
  color: var(--ink);
  text-transform: uppercase;
  letter-spacing: 0.3px;
}

.dash-card-sport .dash-sport-icon { width: 15px; height: 15px; color: var(--clay); display: inline-flex; align-items: center; justify-content: center; }
.dash-card-sport .dash-sport-icon svg { width: 100%; height: 100%; }

.dash-stat-row { display: flex; gap: 10px; }

.dash-stat {
  flex: 1;
  text-align: center;
  background: var(--chalk);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 9px 6px;
  min-width: 0;
}

.dash-stat-value { font-family: var(--font-display); font-weight: 600; font-size: 17px; color: var(--ink); margin-top: 2px; }
.dash-stat-label { font-size: 9.5px; color: var(--ink-soft); font-weight: 700; margin-top: 1px; text-transform: uppercase; }
.dash-stat-total { font-size: 10px; color: var(--ink-soft); margin-top: 2px; }

.dash-recent {
  margin-top: 10px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--ink-soft);
}

.dash-recent-badge {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  font-size: 10.5px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--white);
}
.dash-recent-badge.w { background: var(--grass); }
.dash-recent-badge.l { background: var(--ink-soft); }

/* ============================================================
   PLAYER PROFILE TABS (Overview / Stats / History / Tournaments)
============================================================ */

.profile-tabs {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  margin-bottom: 14px;
  /* This row scrolls horizontally (4 tabs don't always fit a phone's
     width), but with no visual cue the last tab just looks cut off /
     misaligned instead of "swipe for more" — so fade its trailing edge
     instead of hard-clipping it, and hide the scrollbar so it reads as a
     deliberate chip strip rather than a broken layout. */
  mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent 100%);
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent 100%);
  scrollbar-width: none;
}

.profile-tabs::-webkit-scrollbar { display: none; }

.profile-tab {
  white-space: nowrap;
  padding: 8px 13px;
  border-radius: 20px;
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--ink-soft);
  font-weight: 600;
  font-size: 12.5px;
  cursor: pointer;
  flex-shrink: 0;
}

.profile-tab.active { border-color: var(--ink); background: var(--ink); color: var(--chalk); }

/* Status-coloured tabs (Tournaments + Community Games): green = registration
   open, amber/yellow = in progress, blue = completed. The active tab fills
   with its own status colour instead of the generic black so the tab, the
   count pill and the summary panel below all read as one colour. */
.profile-tab.st-tab { border-color: color-mix(in srgb, var(--st) 32%, var(--line)); color: color-mix(in srgb, var(--st) 70%, var(--ink)); }
.profile-tab.st-tab.active { background: var(--st); border-color: var(--st); color: var(--st-on, var(--white)); }
.profile-tab.st-tab.active .pill { background: color-mix(in srgb, var(--st-on, #fff) 24%, transparent); color: var(--st-on, var(--white)); }
.profile-tab.st-registering { --st: #2E9E5B; --st-on: #FFFFFF; }
.profile-tab.st-in_progress { --st: #D9A125; --st-on: #3D2C00; }
.profile-tab.st-completed   { --st: #2F6FB5; --st-on: #FFFFFF; }
/* Without this rule the Pending Approval tab had NO --st: the background
   shorthand fell to unset (transparent over white) while the text resolved
   to white — an active tab rendered white-on-white, and the one organiser
   whose stuck tournament lived behind it saw a blank chip strip and
   reasonably concluded his tournament didn't exist. Every status that can
   come out of overallStatus() MUST have a line here. */
.profile-tab.st-pending     { --st: #C77D2E; --st-on: #FFFFFF; }

.h2h-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  margin-bottom: 8px;
}

.h2h-record { font-family: var(--font-display); font-weight: 600; font-size: 14px; color: var(--ink); }

/* ---- Player detail → Stats: the format comparison table ----
   The wrapper wears .stat-card's clothes exactly — var(--white), one
   var(--line) border, var(--radius-md), the same 12px/14px inset — because
   this replaces the Singles/Doubles rating cards that stood here and should
   read as the same object, not as a table that arrived from somewhere else.
   The 14px horizontal inset is moved onto the edge CELLS rather than the
   wrapper: the wrapper is the scrollport, so padding on it would scroll away
   and the sticky Metric column would have nothing solid to sit on. */
.fmt-table-wrap {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 4px 0;
  margin-bottom: 14px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
/* `separate` is REQUIRED, not a preference: position:sticky does not work on
   cells under border-collapse:collapse in Chrome or Safari — the same trap
   the operations dashboard documents. */
.fmt-table { width: 100%; border-collapse: separate; border-spacing: 0; }
.fmt-table th,
.fmt-table td {
  padding: 9px 10px;
  text-align: right;
  white-space: nowrap;
  vertical-align: middle;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
}
.fmt-table th:first-child, .fmt-table td:first-child { padding-left: 14px; }
.fmt-table th:last-child,  .fmt-table td:last-child  { padding-right: 14px; }
.fmt-table tbody tr:last-child th,
.fmt-table tbody tr:last-child td { border-bottom: none; }
/* Column heads and the metric names are .stat-label; the figures are the
   card's own value weight. No new type scale. */
.fmt-table thead th { font-size: 11px; font-weight: 600; color: var(--ink-soft); }
.fmt-table tbody td {
  font-size: 12.5px; font-weight: 700; color: var(--ink);
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1;
}
/* `.fmt-table .fmt-metric`, not `.fmt-metric` — the cell rules above are
   `.fmt-table th` / `.fmt-table td`, which are class+type and therefore BEAT a
   bare class. Written the short way, the metric names silently kept the
   right-alignment meant for the figures. */
.fmt-table .fmt-metric {
  position: sticky; left: 0; z-index: 1;
  background: var(--white);
  text-align: left;
  font-size: 11px; font-weight: 600; color: var(--ink-soft);
}
/* The sticky column has to carry the row's own bottom border with it, or the
   rules break at the moment it starts overlapping the scrolled figures. */
.fmt-table thead .fmt-metric { z-index: 2; }
/* Last 5 Matches. Solid fill, white letter INSIDE the circle — flex centring
   on both axes rather than a line-height guess, so a W and an L sit on the
   same optical centre at any font size. */
.fmt-form { display: inline-flex; align-items: center; gap: 4px; }
.fmt-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; flex: 0 0 20px; border-radius: 50%;
  font-size: 10.5px; font-weight: 800; line-height: 1; color: var(--white);
}
.fmt-badge.w { background: var(--grass); }
.fmt-badge.l { background: var(--danger); }

.sparkline-wrap {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  margin-bottom: 14px;
}

.sparkline-label { font-size: 11px; color: var(--ink-soft); font-weight: 600; margin-bottom: 6px; }

/* ============================================================
   MODALS
============================================================ */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(28, 43, 34, 0.55);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 200;
}

.modal-sheet {
  background: var(--chalk);
  border-radius: 18px 18px 0 0;
  width: 100%;
  max-width: 480px;
  max-height: 88vh;
  overflow-y: auto;
  padding: 20px;
  box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.3);
}

@media (min-width: 540px) {
  .modal-overlay { align-items: center; }
  .modal-sheet { border-radius: 18px; }
}

.modal-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.modal-title { font-weight: 700; font-size: 17px; color: var(--ink); }

.modal-close {
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--ink-soft);
  padding: 4px;
}

.modal-close svg {
  width: 20px;
  height: 20px;
}

.modal-body { display: flex; flex-direction: column; gap: 14px; }

/* ============================================================
   MISC
============================================================ */

.type-toggle { display: flex; gap: 8px; }

.type-toggle button {
  flex: 1;
  padding: 9px 0;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--ink);
  font-weight: 600;
  font-size: 13px;
  cursor: pointer;
  text-transform: capitalize;
}

.type-toggle button.active { border-color: var(--clay); background: var(--clay); color: var(--white); }
.type-toggle button[data-type="doubles"].active { border-color: var(--sky); background: var(--sky); color: var(--white); }

.set-row { display: flex; gap: 8px; align-items: center; }
.set-row .input { width: 70px; }
.set-row .sep { color: var(--ink-soft); }

/* Score modal: result-type selector (Completed / Walkover / Retired / Default)
   and winner picker for walkover/retirement/default. */
.bsm-note { font-size: 12px; color: var(--ink-soft); margin-bottom: 8px; }
.bsm-type-label, .bsm-winner-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  margin: 2px 0 6px;
}
.bsm-winner-label { margin-top: 14px; }
.bsm-type-row, .bsm-winner-row {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.bsm-type-btn, .bsm-winner-btn {
  flex: 1 1 auto;
  min-width: 0;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.bsm-winner-btn { flex-basis: calc(50% - 3px); }
.bsm-type-btn:hover, .bsm-winner-btn:hover { border-color: var(--clay); }
.bsm-type-btn.active {
  background: var(--clay);
  border-color: var(--clay);
  color: #fff;
}
.bsm-winner-btn.active {
  background: var(--grass);
  border-color: var(--grass);
  color: #fff;
}
.bsm-hint {
  font-size: 12px;
  color: var(--ink-soft);
  line-height: 1.4;
  margin-top: 10px;
  background: rgba(210, 98, 46, 0.06);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
}

.add-set-btn {
  align-self: flex-start;
  background: transparent;
  border: none;
  color: var(--clay);
  font-weight: 600;
  font-size: 12.5px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 0;
}

.remove-set-btn {
  background: transparent;
  border: none;
  color: var(--ink-soft);
  cursor: pointer;
  display: flex;
  align-items: center;
}

.remove-set-btn svg {
  width: 15px;
  height: 15px;
}

.helper-text { font-size: 11.5px; color: var(--ink-soft); text-align: center; }

.pending-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  background: rgba(210, 98, 46, 0.1);
  border: 1px solid var(--clay);
  border-radius: var(--radius-md);
  padding: 13px 14px;
  margin-bottom: 18px;
  cursor: pointer;
}

.pending-banner-icon {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--clay);
  color: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.pending-banner-icon svg { width: 16px; height: 16px; }

.pending-banner-title { font-weight: 700; font-size: 13.5px; color: var(--ink); }
.pending-banner-sub { font-size: 11.5px; color: var(--ink-soft); margin-top: 1px; }

.pending-banner-arrow {
  width: 16px;
  height: 16px;
  color: var(--clay);
  flex-shrink: 0;
  margin-left: auto;
}

.pending-banner-arrow svg { width: 100%; height: 100%; }

.section-toggle {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 13px 14px;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.08s ease;
}

.section-toggle:active { transform: scale(0.99); }

@media (hover: hover) {
  .section-toggle:hover { border-color: var(--clay-light); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); }
}

.section-toggle-label { }

/* Shared "open this row" arrow — one boxed chevron used by the Tournaments
   list and the Players list so the arrow and its box are identical in size and
   style on every tab. */
.kr-open-arrow {
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.8px solid #3730A3;
  border-radius: 10px;
  background: var(--white);
  color: #111111;
  box-shadow: 0 2px 6px -4px rgba(55, 48, 163, 0.35);
  cursor: pointer;
}
.kr-open-arrow:hover { background: color-mix(in srgb, #3730A3 6%, var(--white)); }
.kr-open-arrow svg { width: 18px; height: 18px; display: block; }

/* Autofill hint under the Sport / Game type row — confirms what was read out
   of the game name, and that it can be overridden. */
.cg-autofill {
  display: flex;
  align-items: flex-start;
  gap: 7px;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--grass-dark);
  background: color-mix(in srgb, var(--grass) 9%, var(--white));
  border: 1px solid color-mix(in srgb, var(--grass) 26%, var(--line));
  border-radius: 9px;
  padding: 7px 9px;
  margin: -4px 0 10px;
}
.cg-autofill[hidden] { display: none; }
.cg-autofill-ic { width: 13px; height: 13px; flex-shrink: 0; display: inline-flex; color: var(--grass); margin-top: 1px; }
.cg-autofill-ic svg { width: 100%; height: 100%; }
.cg-autofill strong { font-weight: 800; }

/* ---------- Community Games: live plan panel + duration block ---------- */

/* "AI Ready" — appears the moment game type, players and courts are known. */
.cg-ai {
  border: 1px solid color-mix(in srgb, var(--grass) 30%, var(--line));
  border-radius: var(--radius-md);
  background: linear-gradient(140deg, color-mix(in srgb, var(--grass) 10%, var(--white)), color-mix(in srgb, var(--grass) 3%, var(--white)));
  padding: 12px 13px;
  margin: 0 0 14px;
}
.cg-ai-head {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--grass-dark);
}
.cg-ai-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--grass);
  flex-shrink: 0;
}
.cg-ai-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 12px;
  margin-top: 9px;
}
.cg-ai-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink);
}
.cg-ai-tick { width: 13px; height: 13px; flex-shrink: 0; display: inline-flex; color: var(--grass); }
.cg-ai-tick svg { width: 100%; height: 100%; }
.cg-ai-note { font-size: 11.5px; color: var(--ink-soft); margin-top: 8px; line-height: 1.45; }

/* Not enough information yet — same shell, muted. */
.cg-ai-wait {
  border-color: var(--line);
  background: color-mix(in srgb, var(--ink) 3%, var(--white));
}
.cg-ai-wait .cg-ai-head { color: var(--ink-soft); }
.cg-ai-wait .cg-ai-dot { background: var(--ink-soft); opacity: 0.5; }

/* Expected duration, at the foot of the form. */
.cg-dur-block {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--white);
  padding: 12px 13px;
  margin: 4px 0 14px;
}
.cg-dur-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.cg-dur-calc {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid color-mix(in srgb, var(--clay) 40%, var(--line));
  background: color-mix(in srgb, var(--clay) 8%, var(--white));
  color: var(--clay-dark);
  font-size: 12px;
  font-weight: 700;
  padding: 6px 11px;
  border-radius: 999px;
  cursor: pointer;
  flex-shrink: 0;
}
.cg-dur-calc:hover { background: color-mix(in srgb, var(--clay) 15%, var(--white)); }
.cg-dur-calc svg { width: 13px; height: 13px; }
.cg-dur-row { display: flex; align-items: center; gap: 9px; margin-top: 9px; }
.cg-dur-row .input { flex: 1; min-width: 0; }
.cg-dur-unit { font-size: 12.5px; font-weight: 600; color: var(--ink-soft); flex-shrink: 0; }
.cg-dur-note { font-size: 11.5px; color: var(--ink-soft); margin-top: 8px; line-height: 1.45; }

/* ---------- Shared filter row (Tournaments + Community Games) ----------
   A grid, not a flex row: every control gets an identical column width, so
   the boxes line up instead of each one sizing itself to its own label. The
   columns reflow to fit whatever width is available, so the whole set always
   stays on screen without a horizontal scroll. */
.filter-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: 8px;
  margin-bottom: 14px;
  align-items: stretch;
}
@media (max-width: 620px) {
  .filter-grid { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); gap: 7px; }
}
@media (max-width: 380px) {
  .filter-grid { grid-template-columns: 1fr 1fr; }
}

/* The popover-based controls (Hosted by / Location / Date) are a button in a
   positioned wrapper; the wrapper is the grid cell so the button can fill it
   and match the plain <select>s exactly. */
.filter-ctl-wrap { position: relative; display: flex; }

/* A popover (260px) is wider than its grid cell (~150px), so anchoring it to
   the cell would push it off the right edge of the screen. Inside the filter
   grid we make the GRID the positioning context instead: the panel drops
   below the whole filter block, aligned to its left edge, so it is always
   fully on screen no matter which control opened it. */
.filter-grid { position: relative; }
.filter-grid .filter-ctl-wrap { position: static; }
.filter-grid .loc-popover { left: 0; right: auto; width: min(300px, calc(100vw - 34px)); }

/* One rule for BOTH <select> and <button> filters so their height, padding,
   font and border are guaranteed to match. */
.filter-grid .filter-ctl {
  width: 100%;
  min-width: 0;
  max-width: none;
  height: 38px;
  font-size: 13px;
  padding: 8px 10px;
  cursor: pointer;
}
.filter-grid button.filter-ctl {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  text-align: left;
}
.filter-ctl-main { display: inline-flex; align-items: center; gap: 5px; min-width: 0; }
.filter-ctl-ic { width: 13px; height: 13px; flex-shrink: 0; display: inline-flex; }
.filter-ctl-ic svg { width: 100%; height: 100%; }
/* Long values ("Hosted by (2)", "Apex Tennis Academy") truncate rather than
   stretching the box and breaking the alignment with its neighbours. */
.filter-ctl-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.filter-ctl-chev { width: 13px; height: 13px; flex-shrink: 0; display: inline-flex; }
.filter-ctl-chev svg { width: 100%; height: 100%; }
.filter-ctl-active { border-color: var(--clay); color: var(--clay); font-weight: 600; }

/* "Rank Your Racquets" banner above the My Sports picker (Profile). The list of
   tickboxes and #1 / ↑ / ★ controls is meaningless without a title telling
   people what they're looking at. */
.rr-banner {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 13px 14px;
  margin-bottom: 10px;
  border: 1px solid color-mix(in srgb, var(--clay) 22%, var(--line));
  border-radius: var(--radius-md);
  background: linear-gradient(140deg, color-mix(in srgb, var(--clay) 11%, var(--white)), color-mix(in srgb, var(--clay) 3%, var(--white)));
}
.rr-banner-icon {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  color: var(--clay);
  margin-top: 1px;
}
.rr-banner-icon svg { width: 100%; height: 100%; display: block; }
.rr-banner-text { min-width: 0; }
.rr-banner-title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 16px;
  line-height: 1.15;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--clay-dark);
}
.rr-banner-sub {
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink-soft);
  margin-top: 3px;
}
.rr-banner-sub strong { color: var(--ink); font-weight: 800; }
/* The ★ / ↑ / ✓ key. It sits under the description rather than in its own row
   below the LIST, so the symbols are named before the reader meets them — but
   it gets its own line, because trailing it onto the end of the sentence made
   the opening bracket land mid-paragraph and read as an afterthought.
   It stays a child of .rr-banner-sub deliberately: that is what makes the type
   and colour identical to the description without restating either. `block` is
   the whole mechanism — it forces the line break and lets the key wrap within
   itself on a narrow phone. Held one step back by opacity alone, so it reads
   as secondary without shrinking to unreadable. */
.rr-banner-key { display: block; margin-top: 6px; opacity: 0.85; }
/* The .rr-key chips are 17px tall inside 12px text, so without a little
   breathing room above they collide with the line before them once the key
   wraps. */
.rr-banner-key .rr-key { margin: 0 1px; vertical-align: -3px; }
.rr-banner-dot { margin: 0 3px; opacity: 0.55; }

/* Compact key for the ★ / ↑ / ✓ controls, replacing the old paragraph of
   small grey text that sat under the list. */
.rr-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 7px 14px;
  margin-top: 9px;
  font-size: 11px;
  color: var(--ink-soft);
}
.rr-legend span { display: inline-flex; align-items: center; gap: 5px; }
.rr-key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 17px;
  height: 17px;
  border-radius: 5px;
  background: color-mix(in srgb, var(--clay) 12%, var(--white));
  color: var(--clay-dark);
  font-size: 10.5px;
  font-weight: 800;
  line-height: 1;
}

/* Per-sport header stats on the Profile page (Tennis / Pickleball / …).
   Each figure sits in its own equal-width bordered chip so the numbers line
   up in a column down the list instead of the old run-on
   "3.62 Rating • 17 Matches • 94% Win Rate" text, which wrapped at a
   different point on every row and looked randomly spaced. */
.ss-metrics { display: flex; align-items: stretch; gap: 6px; flex-shrink: 0; }
.ss-metric {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: 62px;
  padding: 4px 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: color-mix(in srgb, var(--ink) 2.5%, var(--white));
  line-height: 1.15;
}
.ss-metric-val {
  font-size: 12.5px;
  font-weight: 800;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
.ss-metric-lbl {
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-top: 1px;
  white-space: nowrap;
}
/* "No matches yet" / "Hide" — one wider chip, vertically centred on its own. */
.ss-metric-empty {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--ink-soft);
  white-space: nowrap;
  padding: 7px 10px;
}

@media (max-width: 460px) {
  .ss-metrics { gap: 4px; }
  .ss-metric { min-width: 52px; padding: 3px 5px; }
  .ss-metric-val { font-size: 11.5px; }
  .ss-metric-lbl { font-size: 7.5px; letter-spacing: 0.03em; }
}

/* The per-sport header row on Profile. These four declarations blocks are the
   INLINE STYLES the row used to carry, moved out verbatim — same properties,
   same values, so the desktop row is byte-identical to what it rendered
   before. They are classes now only because the mobile rule below has to
   address them, and a media query cannot reach an inline style. */
.ss-head-name { display: flex; align-items: center; gap: 6px; }
.ss-head-ic { width: 14px; height: 14px; color: var(--clay); }
.ss-head-right {
  display: flex; align-items: center; gap: 8px;
  color: var(--ink-soft); font-size: 12.5px; font-weight: 600;
}
.ss-head-chev { width: 14px; height: 14px; flex-shrink: 0; }

/* Below 768px the four chips take a row of their own.
   ┌──────────────────────────────┐
   │ 🏸 Badminton               ▼ │
   │ [Rating][Rank][Match][Win%]  │
   └──────────────────────────────┘
   The chips and the chevron are SIBLINGS inside .ss-head-right, so the chips
   cannot wrap out from under the chevron while that wrapper is a box. Making
   it `display: contents` dissolves the box and promotes both to flex items of
   the button itself, which is what lets `order` put the chevron on line 1 and
   the chips on line 2. No markup is duplicated and nothing moves on desktop.
   `display: contents` keeps the element in the inheritance chain, so the
   colour, size and weight above still reach the chevron; only the wrapper's
   own `gap` is lost, which is why the button restates 8px here. */
@media (max-width: 767px) {
  .section-toggle--sport { flex-wrap: wrap; gap: 10px 8px; }
  .section-toggle--sport .ss-head-name { order: 1; flex: 1 1 auto; min-width: 0; }
  .section-toggle--sport .ss-head-right { display: contents; }
  /* A lone "Hide" / "No matches yet" chip stays on line 1 — see the comment on
     ss-metrics--single in profile.js. */
  .section-toggle--sport .ss-metrics--single { order: 2; }
  .section-toggle--sport .ss-head-chev { order: 3; }
  /* flex-basis:100% is the line break. The chips then divide that line equally
     (`flex: 1 1 0`) rather than sitting at their content widths against a
     ragged right edge — the same equal-width rule the chip set was designed
     around, now measured against the row instead of against `min-width`. */
  .section-toggle--sport .ss-metrics:not(.ss-metrics--single) {
    order: 4; flex-basis: 100%; width: 100%;
  }
  .section-toggle--sport .ss-metrics:not(.ss-metrics--single) .ss-metric {
    flex: 1 1 0; min-width: 0;
  }
}

.admin-banner {
  background: rgba(181, 83, 44, 0.08);
  border: 1px solid var(--clay);
  border-radius: var(--radius-md);
  padding: 12px;
  margin-bottom: 18px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  color: var(--clay-dark);
}

/* ---- Profile page enhancements (summary, photo, admin card, achievements, goal) ---- */
/* Premium badge row under the name — kept tight so the hero isn't airy. */
.profile-summary { display: flex; flex-wrap: wrap; gap: 5px 8px; margin: 5px 0 1px; }
.profile-summary-item { font-size: 11px; font-weight: 600; color: var(--ink); background: var(--surface); border: 1px solid var(--line); border-radius: 999px; padding: 3px 9px; white-space: nowrap; }

.stat-extra { font-size: 11px; font-weight: 600; color: var(--ink-soft); margin-top: 3px; }
.stat-goal { font-size: 11px; font-weight: 700; color: var(--clay-dark); margin-top: 6px; padding-top: 6px; border-top: 1px dashed var(--line); }

/* Per-category Rating + Record pair, with its own match-history dropdown. */
.cat-block { margin-bottom: 12px; }
.cat-history-toggle { display: flex; align-items: center; justify-content: flex-start; gap: 4px; width: 100%; margin-top: 8px; padding: 7px 0 0; border: none; border-top: 1px dashed var(--line); background: none; cursor: pointer; font-family: var(--font); font-size: 11px; font-weight: 700; color: var(--clay-dark); }
.cat-history-toggle:hover { color: var(--clay); }
.cat-history { margin-top: 8px; display: flex; flex-direction: column; gap: 8px; }

/* Compact meta line under the hero badges. */
.profile-meta-row { font-size: 11.5px; font-weight: 500; color: var(--ink-soft); margin-top: 5px; }

/* Scoreboard-style W–L value on the record cards. */
.stat-value.scoreboard { letter-spacing: 0.5px; font-variant-numeric: tabular-nums; }

/* Friendly in-card empty line (unplayed discipline). */
.stat-empty { font-size: 12px; font-weight: 500; color: var(--ink-soft); margin-top: 6px; line-height: 1.4; }

.sport-empty { text-align: center; padding: 16px 12px; font-size: 13px; font-weight: 600; color: var(--ink); }
.sport-empty span { display: block; margin-top: 3px; font-size: 12px; font-weight: 500; color: var(--ink-soft); }

/* Quick summary card — one horizontal glance row above Achievements. */
.quick-summary { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin-bottom: 16px; padding: 12px 14px; border-radius: var(--radius-md); background: var(--surface); border: 1px solid var(--line); }
.qs-item { font-size: 12.5px; font-weight: 700; color: var(--ink); white-space: nowrap; }

/* Profile completeness card. */
.completeness-card { margin-bottom: 18px; padding: 13px 14px; border-radius: var(--radius-md); background: var(--surface); border: 1px solid var(--line); }
.completeness-head { display: flex; align-items: baseline; justify-content: space-between; }
.completeness-lbl { font-size: 12.5px; font-weight: 700; color: var(--ink); }
.completeness-pct { font-family: var(--font-display); font-size: 18px; font-weight: 700; color: var(--clay); }
.completeness-sub { font-size: 11.5px; color: var(--ink-soft); margin-top: 7px; }
.completeness-list { margin: 6px 0 0; padding-left: 18px; font-size: 11.5px; color: var(--ink-soft); line-height: 1.55; }

/* Rating-impact chip on confirmed match cards. */
.scorecard-impact { font-size: 11px; font-weight: 700; margin-left: 8px; }
.scorecard-impact.up { color: var(--grass); }
.scorecard-impact.down { color: var(--clay-dark); }

.profile-avatar-btn { border: 2px solid var(--ball); padding: 0; overflow: hidden; cursor: pointer; }
.profile-avatar-btn:hover { opacity: 0.92; }
.profile-avatar-img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block; }

.my-sport-icon { width: 15px; height: 15px; color: var(--clay); display: inline-flex; flex-shrink: 0; }
.my-sport-icon svg { width: 15px; height: 15px; }

.admin-card { display: flex; align-items: center; gap: 11px; margin-bottom: 16px; padding: 7px 13px; border-radius: var(--radius-md); background: linear-gradient(135deg, color-mix(in srgb, var(--clay) 12%, var(--white)), color-mix(in srgb, var(--clay) 4%, var(--white))); border: 1px solid color-mix(in srgb, var(--clay) 40%, transparent); }
.admin-card-ic { width: 30px; height: 30px; flex-shrink: 0; border-radius: 9px; background: var(--clay); color: var(--white); display: flex; align-items: center; justify-content: center; font-size: 16px; }
.admin-card-ic svg { width: 20px; height: 20px; }
.admin-card-title { font-size: 14px; font-weight: 700; color: var(--ink); }
.admin-card-sub { font-size: 12px; color: var(--ink-soft); margin-top: 1px; }

.ach-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.ach-chip { display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px; border-radius: 999px; background: var(--surface); border: 1px solid var(--line); font-size: 12.5px; font-weight: 600; color: var(--ink); }
.ach-chip-ic { font-size: 14px; line-height: 1; }
.ach-empty { font-size: 12.5px; color: var(--ink-soft); margin-top: 8px; }

.goal-card { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; padding: 12px 14px; border-radius: var(--radius-md); background: var(--surface); border: 1px dashed var(--line); }
.goal-card-ic { width: 30px; height: 30px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; color: var(--grass); font-size: 16px; }
.goal-card-ic svg { width: 18px; height: 18px; }
.goal-card-lbl { font-size: 10px; font-weight: 700; letter-spacing: 0.8px; text-transform: uppercase; color: var(--ink-soft); }
.goal-card-detail { font-size: 12px; font-weight: 600; color: var(--ink-soft); margin-top: 2px; }
.goal-card-val { font-size: 14px; font-weight: 700; color: var(--ink); margin-top: 1px; }
.goal-bar { height: 5px; border-radius: 999px; background: var(--line); overflow: hidden; margin-top: 7px; }
.goal-bar-fill { height: 100%; border-radius: 999px; background: var(--grass); }

.photo-menu { display: flex; flex-direction: column; gap: 10px; }

.lock-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--ink-soft);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 10px 12px;
  margin-bottom: 14px;
}

.category-check-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.category-check-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: var(--white);
  cursor: pointer;
  font-size: 13.5px;
  color: var(--ink);
  border-bottom: 1px solid var(--line);
}

.category-check-row:last-child { border-bottom: none; }

.category-check-row input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--clay);
  flex-shrink: 0;
}

/* Doubles / Mixed Doubles opt-in sub-row, shown under a sport once it's
   checked — see Profile's mySportsHtml. Indented under the sport row it
   belongs to, with its own bottom border so it reads as that sport's
   sub-item rather than a new row in the list. */
.discipline-optin-row {
  display: flex;
  gap: 18px;
  padding: 0 12px 10px 34px;
  background: var(--white);
  border-bottom: 1px solid var(--line);
}

.discipline-optin-row:last-child { border-bottom: none; }

.checkbox-inline {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--ink-soft);
  cursor: pointer;
}

.checkbox-inline input[type="checkbox"] {
  width: 14px;
  height: 14px;
  accent-color: var(--sky-dark);
  flex-shrink: 0;
}

.bracket-round-title {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--clay);
  margin-bottom: 8px;
  text-transform: uppercase;
}

.bracket-round {
  border: 1px solid var(--line);
  border-radius: 14px;
  margin-bottom: 14px;
  overflow: hidden;
  background: var(--sky-light);
}

.bracket-round-header {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  background: transparent;
  border: none;
  cursor: pointer;
  text-align: left;
}

.bracket-round-header .bracket-round-title { margin-bottom: 0; }

.round-status {
  font-size: 10.5px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  text-transform: none;
}
.round-status svg, .round-status span { width: 11px; height: 11px; }
.round-status.done { background: var(--grass-light); color: var(--grass-dark); }
.round-status.live { background: var(--ball); color: var(--ink); }
.round-status.upcoming { background: var(--line); color: var(--ink-soft); }

.round-chevron {
  width: 15px;
  height: 15px;
  margin-left: auto;
  color: var(--ink-soft);
  flex-shrink: 0;
}

.bracket-round-body { padding: 0 12px 12px; }

.bracket-match-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px 14px;
  margin-bottom: 10px;
}

.bracket-match-row.clickable { cursor: pointer; }
.bracket-match-row.clickable:hover { border-color: var(--clay); }

.bracket-names { display: flex; flex-direction: column; gap: 7px; flex: 1; min-width: 0; }
.bracket-names .bname {
  font-size: 13.5px;
  line-height: 1.35;
  display: flex;
  align-items: center;
  gap: 6px;
  word-break: break-word;
}
.bracket-names .bname.slot-a { color: var(--clay-dark); }
.bracket-names .bname.slot-b { color: var(--sky-dark); }
.bracket-names .bname.winner { font-weight: 700; color: var(--ink); }
.bracket-names .bname.pending { font-weight: 500; }
.bracket-names .bname.tbd { font-style: italic; font-weight: 500; color: var(--ink-soft); }
.bracket-names .bname.bye { font-style: italic; font-weight: 500; color: var(--ink-soft); }
.bname-tick { width: 14px; height: 14px; color: var(--grass-dark); flex-shrink: 0; display: inline-flex; }
.bname-tick svg { width: 100%; height: 100%; }

.bracket-score {
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
  background: var(--chalk);
  border-radius: 6px;
  padding: 2px 7px;
  display: inline-block;
  width: fit-content;
}

.bracket-meta {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 11.5px;
  color: var(--ink-soft);
}
.bracket-meta-icon { width: 12px; height: 12px; display: inline-flex; flex-shrink: 0; }
.bracket-meta-icon svg { width: 100%; height: 100%; }
.bracket-meta-dot { margin: 0 1px; }

.bracket-cta { font-size: 12.5px; color: var(--clay); font-weight: 700; flex-shrink: 0; }

/* ---------- bracket flow chart (pro-tournament-style draw tree) ---------- */

.bracket-flow-wrap {
  overflow-x: auto;
  margin: 0 -16px 4px;
  padding: 4px 16px 14px;
}

/* Inside the boxed knockout stage, keep the scroll area within the box border
   (drop the full-bleed negative margins used when it's on its own). */
.bracket-stage-box .bracket-flow-wrap { margin: 0 0 2px; padding: 4px 2px 10px; }

.bracket-flow { display: flex; align-items: stretch; min-width: max-content; }

/* A fixed pixel width meant a Round-of-16 draw (4 columns) looked the same
   tiny size whether the card around it was 480px (phone) or 860px (desktop)
   — there was no way to take advantage of the extra room on a bigger
   screen. flex-grow lets each round's column actually expand to fill
   whatever width the .app card has available (e.g. 2-3 rounds on desktop
   stretch out and read much bigger), while min-width keeps every column
   from ever shrinking below a comfortably-readable floor. When a draw has
   enough rounds that even the floor width doesn't all fit (Round of 64/128
   on a phone, or even on desktop), .bracket-flow-wrap's overflow-x: auto
   takes over and it scrolls horizontally instead of squeezing — exactly
   the same pattern every bracket viewer (Challonge, ESPN, etc.) uses. */
.bf-round {
  display: flex;
  flex-direction: column;
  flex: 1 1 390px;
  flex-shrink: 0;
  min-width: 390px;
  max-width: 540px;
}

/* Neutral premium columns: white, subtle grey border. Only the CURRENT round
   carries the indigo brand accent; completed rounds a quiet green title. */
.bf-round-boxed { border: 1px solid var(--line); background: var(--white); border-radius: 14px; padding: 12px 10px; margin: 0 6px; }
.bf-round-current { border-color: #3730A3; }
.bf-round-current .bf-round-title { color: #3730A3; }

.bf-round-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-soft);
  text-transform: uppercase;
  text-align: center;
  margin-bottom: 12px;
  letter-spacing: 0.05em;
  border-bottom: 1px solid var(--line);
  padding-bottom: 8px;
}

.bf-matches { flex: 1; display: flex; flex-direction: column; justify-content: space-around; gap: 18px; }

.bf-pair {
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  gap: 18px;
  position: relative;
  padding-right: 20px;
}

.bf-pair::after {
  content: "";
  position: absolute;
  top: 25%;
  bottom: 25%;
  right: 0;
  width: 12px;
  border: 4px solid color-mix(in srgb, var(--ink) 55%, var(--white));
  border-left: none;
  border-radius: 0 10px 10px 0;
}

.bf-slot { flex: 1; display: flex; align-items: center; }

.bf-card {
  width: 100%;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.bf-card.clickable { cursor: pointer; }
.bf-card { transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease; }
.bf-card:hover { border-color: #3730A3; box-shadow: 0 6px 16px -10px rgba(22, 36, 26, 0.35); transform: translateY(-1px); }

/* Match states: completed (green edge + badge) / live (red badge) / upcoming
   (plain white card, unchanged). */
.bf-card.bf-done { border-left: 4px solid var(--grass); }
.bf-state-row { display: flex; }
.bf-state { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 800; letter-spacing: 0.4px; border-radius: 999px; padding: 2px 9px; }
/* Neutral grey — green is reserved for the WINNER's name/scores, so the
   state badge never competes with it. */
.bf-state-done { color: var(--ink-soft); background: color-mix(in srgb, var(--ink) 7%, var(--white)); }
.bf-state-done svg { width: 11px; height: 11px; }
.bf-state-live { color: #C22B2B; background: color-mix(in srgb, #C22B2B 10%, var(--white)); }
.bf-live-dot { width: 7px; height: 7px; border-radius: 50%; background: #C22B2B; animation: kr-live-pulse 1.1s ease-in-out infinite; }

/* Clickable player names inside bracket cards. */
.bname-click { cursor: pointer; border-radius: 4px; }
.bname-click:hover { color: var(--clay-dark); text-decoration: underline; text-underline-offset: 3px; }

.bf-cta-row { display: flex; align-items: center; gap: 12px; }
.bf-view-match { cursor: pointer; color: var(--grass); }
.bf-view-match:hover { text-decoration: underline; text-underline-offset: 3px; }

.bf-time-ic { width: 12px; height: 12px; display: inline-flex; margin-right: 4px; color: var(--ink-soft); vertical-align: -1px; }
.bf-time-ic svg { width: 100%; height: 100%; }

/* Logged-in player's own matches — a subtle clay accent traces their path
   through the draw without shouting over the rest of the bracket. */
.bf-card.bf-mine {
  border-color: color-mix(in srgb, var(--clay) 55%, var(--line));
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--clay) 22%, transparent);
  background: color-mix(in srgb, var(--clay) 4%, var(--white));
}

/* Fully-completed rounds: green header + a gentle success wash on the
   round's finished cards. Upcoming rounds stay neutral. */
.bf-round-done .bf-round-title { color: var(--grass); }
.bf-round-tick { width: 14px; height: 14px; display: inline-flex; margin-left: 6px; vertical-align: -2px; color: var(--grass); }
.bf-round-tick svg { width: 100%; height: 100%; }
.bf-round-done .bf-card.bf-done {
  background: color-mix(in srgb, var(--grass) 5%, var(--white));
  border-color: color-mix(in srgb, var(--grass) 28%, var(--line));
}

/* Champion column after the Final — premium trophy card. */
.bf-champ-col { flex: 0 1 300px; min-width: 280px; max-width: 340px; }
.bf-champ-title { color: #B58A25; }
.bf-champ-card {
  width: 100%;
  border: 2px dashed var(--line);
  border-radius: 14px;
  padding: 24px 18px;
  text-align: center;
  background: var(--white);
  color: var(--ink-soft);
}
.bf-champ-card.crowned {
  border: 2px solid #D9A93C;
  background: linear-gradient(160deg, #FFF9E8 0%, var(--white) 75%);
  box-shadow: 0 12px 28px -14px rgba(217, 169, 60, 0.55);
}
.bf-champ-trophy { width: 36px; height: 36px; display: inline-flex; color: #D9A93C; margin-bottom: 8px; }
.bf-champ-trophy svg { width: 100%; height: 100%; }
.bf-champ-label { font-size: 11px; font-weight: 800; letter-spacing: 1.4px; text-transform: uppercase; color: var(--ink-soft); }
.bf-champ-name { font-family: var(--font-display); font-size: 22px; font-weight: 700; margin-top: 6px; color: var(--ink-soft); }
.bf-champ-card.crowned .bf-champ-name { color: var(--ink); }
.bf-champ-sub { margin-top: 4px; font-size: 12px; font-weight: 700; letter-spacing: 0.4px; color: #B58A25; }

/* Names inside the flow-chart cards. These used to inherit the small default
   text size (the .bracket-names .bname rules above only cover the LIST view,
   not the flow chart), which made big draws — where every column sits at its
   minimum width — hard to read. Sized up + given the winner/tbd states the
   list view already had. */
/* ONE size for every name state — real names, winners, "waiting for winner"
   placeholders and BYEs all render at 17px so cards never look randomly
   bigger or smaller than their neighbours. States differ only by weight,
   colour and the winner tick. */
.bf-card .bname {
  font-size: 17px;
  line-height: 1.35;
  font-weight: 700;
  color: var(--ink);
  display: flex;
  align-items: flex-start;
  gap: 7px;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
.bf-card .bname-text { min-width: 0; word-break: break-word; flex: 1; }
/* Winner reads instantly: green + heavy; the loser steps back in grey. */
.bf-card .bname.winner { font-weight: 800; color: var(--grass); }
.bf-card .bname.loser { font-weight: 600; color: var(--ink-soft); }
.bf-card .bname.tbd { font-weight: 700; color: var(--ink); }
.bf-card .bname.bye { font-style: italic; font-weight: 500; color: var(--ink-soft); }

/* Per-side set scores at the end of each name row — each side's numbers on
   their own line, so who won 6 and who won 2 is unmistakable. */
.bname-scores { margin-left: auto; display: inline-flex; gap: 7px; flex-shrink: 0; padding-left: 8px; }
.bscore-cell { min-width: 17px; text-align: center; font-size: 15px; font-weight: 700; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.bf-card .bname.winner .bscore-cell { color: var(--grass); font-weight: 800; }
.bf-card .bracket-score { font-size: 15px; }
.bf-card .bracket-cta { font-size: 14.5px; }

/* ---------- Tournament detail hero (green gradient header) ---------- */
.draw-hero-name {
  font-family: var(--font-display);
  font-size: 25px;
  font-weight: 700;
  line-height: 1.15;
  color: var(--white);
  margin: 10px 0 2px;
}

.draw-hero-info {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 14px;
}

/* Dense two-column info grid for the tournament hero. */
.dhi-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 22px;
  margin-top: 11px;
}
.dhi-cell { display: flex; align-items: center; gap: 8px; min-width: 0; }
@media (max-width: 520px) {
  .dhi-grid { grid-template-columns: 1fr; gap: 9px; }
}
/* When the prize medallion floats top-right, keep the info grid clear of it. */
@media (min-width: 701px) {
  .tourn-hero.has-perks .dhi-grid { max-width: 60%; }
}

/* ===== Category (draw) page: registration card ===== */
.reg-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.reg-count { font-weight: 800; font-size: 14px; color: var(--ink); }
.reg-progress-bar { height: 8px; border-radius: 999px; background: color-mix(in srgb, var(--ink) 8%, var(--white)); overflow: hidden; }
.reg-progress-fill { height: 100%; border-radius: 999px; transition: width 0.4s ease; }
.reg-remaining { margin-top: 9px; font-size: 12.5px; font-weight: 600; color: var(--ink-soft); }
.reg-teams-block { margin-top: 15px; }
.reg-teams-title { font-size: 11px; font-weight: 800; letter-spacing: 0.6px; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 9px; }
.reg-team-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.reg-team-list li { display: flex; align-items: center; gap: 10px; }
.rtl-num { width: 22px; height: 22px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: color-mix(in srgb, var(--clay) 12%, var(--white)); color: var(--clay-dark); font-size: 11.5px; font-weight: 800; }
.rtl-name { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.reg-empty { display: flex; flex-direction: column; gap: 3px; padding: 16px; border: 1px dashed var(--line); border-radius: 12px; text-align: center; font-size: 13px; font-weight: 600; color: var(--ink); }
.reg-empty span { font-size: 12px; font-weight: 500; color: var(--ink-soft); }
.reg-cta-wrap { margin-top: 15px; }
.draw-register-cta { font-size: 15px; font-weight: 800; padding: 13px; }
.draw-format-readonly .dfr-value { margin-top: 8px; font-size: 15px; font-weight: 700; color: var(--ink); }

/* Category card meta chips (entry fee, prize, rating event). */
.draw-meta-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 11px; }
.draw-meta-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 700; padding: 3px 9px; border-radius: 999px; background: color-mix(in srgb, var(--ink) 7%, var(--white)); color: var(--ink); border: 1px solid var(--line); }
.draw-meta-chip-gold { background: color-mix(in srgb, #E7B54B 20%, var(--white)); color: #8A5E12; border-color: color-mix(in srgb, #E7B54B 45%, transparent); }
.draw-meta-chip-rating { background: color-mix(in srgb, #96775A 10%, var(--white)); color: #96775A; border-color: color-mix(in srgb, #96775A 32%, transparent); }
.dmc-ic { width: 12px; height: 12px; display: inline-flex; }
.dmc-ic svg { width: 100%; height: 100%; }

/* ===== Invite modal (WhatsApp / Copy / QR) ===== */
.invite-modal { display: flex; flex-direction: column; gap: 10px; }
.invite-opt { display: flex; align-items: center; gap: 12px; padding: 13px 14px; border: 1px solid var(--line); border-radius: 12px; background: var(--white); font-size: 14px; font-weight: 700; color: var(--ink); cursor: pointer; text-decoration: none; transition: background 0.15s ease, transform 0.15s ease; }
.invite-opt:hover { background: color-mix(in srgb, var(--clay) 6%, var(--white)); transform: translateY(-1px); }
.invite-opt-ic { width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center; color: var(--ink-soft); }
.invite-opt-ic svg { width: 22px; height: 22px; }
.invite-wa { color: #25D366; }
.invite-qr { display: flex; flex-direction: column; align-items: center; gap: 8px; margin-top: 6px; padding: 14px; border: 1px solid var(--line); border-radius: 12px; }
.invite-qr img { border-radius: 8px; }
.invite-qr span { font-size: 12px; color: var(--ink-soft); font-weight: 600; }

/* ===== Suggested partner chips ===== */
.partner-suggest { margin-bottom: 10px; }
.partner-suggest-title { font-size: 11px; font-weight: 800; letter-spacing: 0.5px; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 7px; }
.partner-suggest-row { display: flex; flex-wrap: wrap; gap: 7px; }
.partner-chip { display: inline-flex; align-items: center; gap: 7px; padding: 5px 12px 5px 5px; border: 1px solid var(--line); border-radius: 999px; background: var(--white); font-size: 12.5px; font-weight: 700; color: var(--ink); cursor: pointer; transition: border-color 0.15s ease, background 0.15s ease; }
.partner-chip:hover { border-color: var(--clay); }
.partner-chip.selected { border-color: var(--clay); background: color-mix(in srgb, var(--clay) 10%, var(--white)); }

/* ===== Sticky register CTA (floating pill above the tab bar) ===== */
.draw-sticky-cta { position: fixed; bottom: 74px; left: 50%; transform: translateX(-50%); z-index: 45; display: flex; align-items: center; gap: 12px; padding: 8px 8px 8px 18px; border-radius: 999px; background: var(--ink); color: #fff; box-shadow: 0 14px 32px -10px rgba(0, 0, 0, 0.55); max-width: calc(100% - 24px); }
.dsc-count { font-size: 12.5px; font-weight: 700; white-space: nowrap; }
.draw-sticky-cta .btn { padding: 9px 20px; border-radius: 999px; font-weight: 800; }

/* ===== Draw empty state ===== */
.draw-empty-state { text-align: center; padding: 22px 16px; }
.des-ic { width: 26px; height: 26px; display: inline-flex; color: var(--ink-soft); opacity: 0.7; }
.des-ic svg { width: 100%; height: 100%; }
.des-title { font-weight: 800; font-size: 14px; color: var(--ink); margin-top: 8px; }
.des-sub { font-size: 12.5px; color: var(--ink-soft); margin-top: 4px; }

/* Closing-soon pill (amber). */
.pill-soon { background: color-mix(in srgb, #E0891E 16%, var(--white)); color: #9A5A0E; }

/* Per-category fee row on the category page (with organiser edit link). */
.draw-fee-row { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; margin-bottom: 12px; }
.draw-fee-edit { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 700; color: var(--clay-dark); background: none; border: none; cursor: pointer; padding: 2px 4px; }
.draw-fee-edit:hover { text-decoration: underline; }
.dfe-ic { width: 13px; height: 13px; display: inline-flex; }
.dfe-ic svg { width: 100%; height: 100%; }

/* Scarcity nudge (75%+ full) + full/closed registration box. */
.reg-urgency { display: flex; align-items: center; gap: 7px; margin-top: 10px; padding: 8px 12px; border-radius: 10px; background: color-mix(in srgb, #E0891E 12%, var(--white)); color: #9A5A0E; font-size: 12.5px; font-weight: 800; }
.ru-ic { width: 14px; height: 14px; display: inline-flex; }
.ru-ic svg { width: 100%; height: 100%; }
.reg-closed-box { display: flex; align-items: center; gap: 12px; padding: 14px 16px; border-radius: 12px; background: color-mix(in srgb, var(--ink) 5%, var(--white)); border: 1px solid var(--line); }
.rcb-ic { width: 22px; height: 22px; flex-shrink: 0; display: inline-flex; color: var(--ink-soft); }
.rcb-ic svg { width: 100%; height: 100%; }
.rcb-title { font-weight: 800; font-size: 14px; color: var(--ink); }
.rcb-sub { font-size: 12.5px; color: var(--ink-soft); margin-top: 1px; }

/* Edit / remove controls on each registered team row. */
.rtl-actions { margin-left: auto; display: flex; gap: 4px; }
.rtl-btn { width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--line); border-radius: 8px; background: var(--white); color: var(--ink-soft); cursor: pointer; transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease; }
.rtl-btn svg { width: 14px; height: 14px; }
.rtl-btn:hover { background: color-mix(in srgb, var(--clay) 8%, var(--white)); color: var(--ink); border-color: var(--clay); }
.rtl-danger:hover { background: color-mix(in srgb, var(--clay) 12%, var(--white)); color: var(--clay-dark); border-color: var(--clay); }

/* ===== Court + time schedule on bracket match cards ===== */
.bf-sched { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--line); }
.bf-sched-court { font-size: 14px; font-weight: 800; letter-spacing: 0.3px; color: var(--white); background: var(--clay-dark); border-radius: 6px; padding: 3px 10px; }
.bf-sched-time { font-size: 15px; font-weight: 700; color: var(--ink); }
.bf-sched-edit { margin-left: auto; width: 22px; height: 22px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--line); border-radius: 6px; background: var(--white); color: var(--ink-soft); cursor: pointer; }
.bf-sched-edit svg { width: 12px; height: 12px; }
.bf-sched-edit:hover { border-color: var(--clay); color: var(--clay-dark); }

/* Court picker in the schedule modal. */
.sched-court-list { display: flex; flex-wrap: wrap; gap: 8px; }
.sched-court { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--ink); border: 1px solid var(--line); border-radius: 999px; padding: 6px 12px; cursor: pointer; }
.sched-note { font-size: 11.5px; color: var(--ink-soft); margin-top: 8px; text-align: center; }

.dhi-row { display: flex; align-items: center; gap: 9px; }
.dhi-ic { width: 15px; height: 15px; flex-shrink: 0; display: inline-flex; color: #F0CE8E; }
.dhi-ic svg { width: 100%; height: 100%; display: block; }
.dhi-link { color: var(--white); text-decoration: underline; text-decoration-color: rgba(255, 255, 255, 0.6); text-underline-offset: 2px; }
.dhi-link:hover { text-decoration-color: #fff; }
/* Plain venue text + a small "(open maps)" link (default = dark hero). The
   light hero overrides these colours below. */
.dhi-place { }
.dhi-maps { color: #F0CE8E; font-weight: 700; text-decoration: none; white-space: nowrap; }
.dhi-maps:hover { text-decoration: underline; }

.draw-invite-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 700;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.4);
  box-shadow: none;
}
.draw-invite-btn:hover { background: rgba(255, 255, 255, 0.2); }

/* ---------- Tournament poster ---------- */

/* Small poster thumbnail on the tournament browse-list card. */
.tournament-row-thumb {
  width: 56px;
  height: 56px;
  flex-shrink: 0;
  object-fit: cover;
  border-radius: 10px;
  border: 1px solid var(--line);
  box-shadow: 0 3px 8px -4px rgba(22, 36, 26, 0.4);
}
/* Placeholder when no poster was uploaded — a plain grey rounded square. */
.tournament-row-thumb-empty {
  background: color-mix(in srgb, var(--ink) 12%, var(--white));
  box-shadow: none;
}

/* Poster display on the tournament detail page (below the last category). */
.tournament-poster {
  margin-top: 18px;
  text-align: center;
}

/* Poster shows in full (never cropped), auto-fitted to ~70% of the column and
   centred. Tapping it opens the full-resolution lightbox. */
.tournament-poster-img {
  display: block;
  width: 92%;
  max-width: 480px;
  height: auto;
  margin: 10px auto 0;
  object-fit: contain;
  border-radius: 16px;
  border: 1px solid var(--line);
  box-shadow: 0 10px 30px -14px rgba(22, 36, 26, 0.45);
  cursor: zoom-in;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.tournament-poster-img:hover {
  transform: translateY(-2px);
  box-shadow: 0 16px 36px -14px rgba(22, 36, 26, 0.55);
}

/* Poster picker inside the create / edit tournament modal. */
.ct-poster-box {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.ct-poster-preview {
  display: block;
  width: 100%;
  max-height: 220px;
  object-fit: cover;
  border-radius: 12px;
  border: 1px solid var(--line);
}

/* Poster upload promoted to the top of the Create Tournament form — it's the
   fastest way to fill everything else in, so it leads. */
.ct-poster-lead {
  border: 1px solid color-mix(in srgb, var(--clay) 26%, var(--line));
  border-radius: var(--radius-md);
  background: linear-gradient(150deg, color-mix(in srgb, var(--clay) 7%, var(--white)), var(--white));
  padding: 13px;
  margin-bottom: 16px;
}
.ct-poster-lead .ct-poster-empty {
  flex-direction: column;
  gap: 4px;
  text-align: center;
  padding: 22px 14px;
  border-style: dashed;
  border-width: 1.5px;
}
.ct-poster-empty-ic { width: 22px; height: 22px; color: var(--clay); display: inline-flex; }
.ct-poster-empty-ic svg { width: 100%; height: 100%; }
.ct-poster-empty-main { font-size: 13.5px; font-weight: 800; color: var(--clay-dark); }
.ct-poster-empty-sub { font-size: 11.5px; color: var(--ink-soft); line-height: 1.4; }

/* Reading / result / problem line under the poster box. */
.ct-ai-status {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 12px;
  line-height: 1.45;
  border-radius: 9px;
  padding: 9px 10px;
  margin-top: 10px;
}
.ct-ai-status[hidden] { display: none; }
.ct-ai-status strong { font-weight: 800; }
.ct-ai-busy { background: color-mix(in srgb, var(--clay) 8%, var(--white)); color: var(--clay-dark); border: 1px solid color-mix(in srgb, var(--clay) 22%, var(--line)); }
.ct-ai-ok { background: color-mix(in srgb, var(--grass) 9%, var(--white)); color: var(--grass-dark); border: 1px solid color-mix(in srgb, var(--grass) 26%, var(--line)); }
.ct-ai-warn { background: color-mix(in srgb, var(--ink) 4%, var(--white)); color: var(--ink-soft); border: 1px solid var(--line); }
.ct-ai-tick { width: 14px; height: 14px; flex-shrink: 0; display: inline-flex; color: var(--grass); margin-top: 1px; }
.ct-ai-tick svg { width: 100%; height: 100%; }
.ct-ai-spin {
  width: 13px; height: 13px; flex-shrink: 0; margin-top: 1px;
  border: 2px solid color-mix(in srgb, var(--clay) 30%, transparent);
  border-top-color: var(--clay);
  border-radius: 50%;
  animation: loading-spin 0.8s linear infinite;
}

.ct-poster-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 96px;
  padding: 16px;
  border: 2px dashed var(--line);
  border-radius: 12px;
  color: var(--ink-soft);
  font-size: 13px;
  background: color-mix(in srgb, var(--clay) 4%, var(--white));
}

.ct-poster-actions {
  display: flex;
  gap: 10px;
}

/* Full-size poster lightbox. */
.poster-lightbox {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(12, 18, 14, 0.86);
  backdrop-filter: blur(3px);
  animation: poster-fade 0.15s ease;
}

@keyframes poster-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

.poster-lightbox-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 12px;
  box-shadow: 0 20px 60px -20px rgba(0, 0, 0, 0.7);
}

.poster-lightbox-close {
  position: absolute;
  top: 18px;
  right: 18px;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
  cursor: pointer;
}

.poster-lightbox-close:hover {
  background: rgba(255, 255, 255, 0.28);
}

/* ---------- Prizes & entry ---------- */

/* Per-category prize inputs inside the create / edit modal. */
.ct-prize-list { display: flex; flex-direction: column; gap: 10px; }

.ct-prize-cat {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: color-mix(in srgb, var(--grass) 4%, var(--white));
}

.ct-prize-cat-name {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.4px;
  color: var(--ink);
}

.ct-prize-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }

/* Prize/entry chips shown on category cards and in the hero. */
.prize-chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}

.prize-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11.5px;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 8%, var(--white));
  color: var(--ink);
  border: 1px solid var(--line);
}

.prize-chip-ic { width: 12px; height: 12px; display: inline-flex; }

.prize-chip-pool {
  background: color-mix(in srgb, var(--grass) 16%, var(--white));
  color: var(--grass);
  border-color: color-mix(in srgb, var(--grass) 40%, transparent);
}

.prize-chip-offer {
  background: color-mix(in srgb, var(--clay) 14%, var(--white));
  color: var(--clay-dark);
  border-color: color-mix(in srgb, var(--clay) 40%, transparent);
}

.prize-breakdown {
  margin-top: 6px;
  font-size: 12px;
  color: var(--ink-soft);
  font-weight: 600;
}

.prize-breakdown-hero { color: rgba(255, 255, 255, 0.85); margin-top: 8px; }

/* Eye-catching total-prize medallion, floated to the top-right of the
   tournament detail hero (the hero is position:relative). Gold gradient with a
   trophy mark and a big amount so it reads as the headline prize, not a note. */
/* Perks column (prize pool + offer) floated to the bottom-right of the hero,
   so the two headline draws sit side-by-side with the tournament info. */
.hero-perks {
  position: absolute;
  bottom: 14px;
  right: 14px;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-end;
  gap: 8px;
  max-width: min(232px, 56%);
  /* No hard clipping here: fitHeroPerks() in tournaments.js measures this
     stack after every render and scales the WHOLE thing (fonts, icons,
     padding) down proportionally until it fits the hero — long perk lists
     shrink gracefully instead of getting cut off. */
  transform-origin: bottom right;
}

.hero-prize-medallion {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 15px 9px 11px;
  border-radius: 13px;
  background: linear-gradient(135deg, #FCEBB0 0%, #E7B54B 52%, #C88E28 100%);
  box-shadow: 0 10px 22px -10px rgba(0, 0, 0, 0.5), inset 0 0 0 1px rgba(255, 255, 255, 0.45);
}

/* Offer / perk badge — green to read as a distinct second "great thing". */
.hero-offer-badge {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 13px 8px 9px;
  border-radius: 13px;
  background: linear-gradient(135deg, #D8F3E0 0%, #6FC58A 55%, #3F8753 100%);
  box-shadow: 0 10px 22px -10px rgba(0, 0, 0, 0.45), inset 0 0 0 1px rgba(255, 255, 255, 0.4);
}
.hob-ic {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(16, 50, 26, 0.18);
  color: #123821;
}
.hob-ic svg { width: 17px; height: 17px; display: block; }
.hob-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.12; }
.hob-label { font-family: var(--font-display); font-size: 9px; font-weight: 700; letter-spacing: 0.8px; text-transform: uppercase; color: #14512F; }
/* Auto-sizes with viewport and clamps to 3 lines so many/long offers never
   blow the badge up into the surrounding UI. */
.hob-value { font-family: var(--font-display); font-size: clamp(10.5px, 1.8vw, 13px); font-weight: 700; color: #0E2E1B; margin-top: 1px; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }

.hpm-ic {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(58, 40, 4, 0.16);
  color: #4E370A;
}
.hpm-ic svg { width: 18px; height: 18px; display: block; }

.hpm-text { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.1; }

.hpm-label {
  font-family: var(--font-display);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: #6E4C0E;
}

.hpm-amount {
  font-family: var(--font-display);
  font-size: 23px;
  font-weight: 700;
  color: #241900;
  margin-top: 1px;
}

/* On narrow screens there's no room to the right of the hero text — let the
   medallion drop below the info instead, still big and gold. */
@media (max-width: 700px) {
  .hero-perks {
    position: static;
    margin-top: 14px;
    max-width: none;
  }
  .hpm-amount { font-size: 22px; }
}

/* Compact prize badge on the tournament browse-list card. */
.card-prize-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-top: 9px;
  padding: 3px 9px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--grass) 14%, var(--white));
  color: var(--grass);
  font-size: 11.5px;
  font-weight: 800;
  border: 1px solid color-mix(in srgb, var(--grass) 35%, transparent);
}

.card-prize-ic { width: 12px; height: 12px; display: inline-flex; }

/* ============ Tournament detail premium polish ============ */

/* Hero: make the name the clear focal point. */
.tourn-name-lg {
  font-size: 34px;
  font-weight: 700;
  letter-spacing: 0.2px;
  line-height: 1.05;
  margin: 4px 0 0;
}

/* Status badge under the title — kept small so the title stays the hero. */
.tourn-status-badge {
  display: inline-flex;
  align-items: center;
  margin-top: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}
/* Hero status badge colours: green = registration open / tournament LIVE,
   blue = completed. (The "in progress" label used on category pills + list
   tabs stays amber — "live" and "in progress" read differently here.) */
.tsb-registering { background: rgba(63, 135, 83, 0.92); color: #fff; }
.tsb-in_progress { background: #2E9E5B; color: #fff; }
.tsb-completed { background: #2F6FB5; color: #fff; }

/* Winner / prize-breakdown sub-line on the prize medallion — clamped to two
   lines so a long breakdown can't balloon the medallion. */
.hpm-sub {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.3px;
  color: #6E4C0E;
  margin-top: 2px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Quick info strip below the hero. */
.tourn-quickinfo {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 14px 16px;
  background: var(--surface, #fff);
  border-bottom: 1px solid var(--line);
}
.tqi-item {
  flex: 1 1 0;
  min-width: 92px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  text-align: center;
  padding: 16px 8px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--white);
  box-shadow: 0 3px 10px -8px rgba(22, 36, 26, 0.3);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.tqi-item:hover { transform: translateY(-2px); box-shadow: 0 10px 22px -12px rgba(22, 36, 26, 0.4); }
/* Stat-card icons (people / trophy / tick) in Indigo 800, same as the arrows. */
.tqi-ic { width: 23px; height: 23px; color: #3730A3; display: inline-flex; }
.tqi-ic svg { width: 100%; height: 100%; }
.tqi-ic-gold { color: #C8912B; }
.tqi-num { font-family: var(--font-display); font-size: 17px; font-weight: 700; color: var(--ink); line-height: 1; }
.tqi-num-sm { font-size: 13px; }
.tqi-lbl { font-size: 10.5px; font-weight: 600; letter-spacing: 0.4px; text-transform: uppercase; color: var(--ink-soft); }

/* Category card refinements. */
/* Category name is the one bold, black element; everything else in the card is
   light grey (like this format line) so only the name draws the eye. */
.draw-cat-name { font-weight: 900; font-size: 20px; color: #111111; letter-spacing: 0; }
.draw-cat-format { font-size: 12.5px; color: var(--ink-soft); font-weight: 500; margin-top: 4px; }
/* More air around the category header block. */
/* ===== Category card vertical rhythm — 8px spacing system =====
   Each content block (title → description → status → progress → controls →
   fees → action) is separated by exactly 16px; elements WITHIN a block sit
   8px apart, so groups read as units and the eye flows evenly downward. */
.draw-cat-format { margin-top: 8px !important; }         /* title → description */
.draw-cat-badges { margin-top: 16px !important; }        /* → status block */
.draw-row .draw-progress { margin-top: 16px; }           /* → progress block */
.draw-progress-top { margin-bottom: 8px !important; }    /* count → bar (within) */
.dpc-spots { margin-top: 8px !important; }               /* bar → spots (within) */
.draw-row .exp-set-row { margin-top: 16px !important; }  /* → registration controls */
.draw-row .draw-info-strip { margin-top: 16px; }         /* → fee & prize block */
.draw-row .draw-reg-actions { margin-top: 16px; }        /* → action block */
.draw-row .btn-block { margin-top: 16px !important; }    /* → primary action */
.draw-row .draw-reg-closed { margin-top: 16px; }

.draw-progress { margin-top: 11px; }
.draw-progress-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
/* Secondary category text matches the clean "Custom — Best of 1…" format line
   (small, muted, light) so only the category NAME stands out. */
.draw-progress-count { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 500; color: var(--ink-soft); }

/* Slightly taller, roomier primary action on a category card — feels more
   premium without changing its look. */
.draw-row .btn-block { padding: 14px 18px; border-radius: 12px; font-size: 14px; }

/* Register / withdraw row on a category card. */
/* Compact registered box — ~40% less bulk than before. */
.draw-reg-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 12px; padding: 7px 11px; border: 1px solid color-mix(in srgb, var(--grass) 30%, var(--line)); border-radius: 10px; background: color-mix(in srgb, var(--grass) 7%, var(--white)); }
.draw-reg-in { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 700; color: var(--grass-dark, #2A6339); }
.dri-tick { display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px; border-radius: 50%; background: var(--grass); color: #fff; font-size: 9.5px; font-weight: 800; }
.draw-withdraw-btn { flex-shrink: 0; padding: 5px 11px; font-size: 12px; font-weight: 700; color: var(--clay-dark); border: 1px solid color-mix(in srgb, var(--clay) 32%, var(--line)); background: var(--white); border-radius: 8px; }
.draw-withdraw-btn:hover { background: color-mix(in srgb, var(--clay) 8%, var(--white)); }
.draw-reg-closed { display: flex; align-items: center; gap: 7px; margin-top: 14px; font-size: 12.5px; color: var(--ink-soft); }
.draw-reg-closed svg { width: 14px; height: 14px; }
/* ── "Your week" digest card (Home) ── */
.week-card { border: 1px solid var(--line); background: var(--white); border-radius: 14px; padding: 13px 16px; margin-bottom: 16px; box-shadow: 0 4px 14px -12px rgba(22,36,26,0.3); }
.week-title { font-size: 11px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 5px; }
.week-line { font-size: 13.5px; color: var(--ink-soft); line-height: 1.5; }
.week-line strong { color: var(--ink); font-weight: 800; }

.week-narrate { margin-top: 9px; padding: 6px 12px; border: 1px dashed color-mix(in srgb, var(--clay) 40%, var(--line)); border-radius: 999px; background: var(--white); color: var(--clay-dark); font-size: 12px; font-weight: 700; cursor: pointer; }
.week-narrate:hover { background: color-mix(in srgb, var(--clay) 7%, var(--white)); }
.week-story { margin-top: 10px; font-size: 13px; color: var(--ink); line-height: 1.55; border-top: 1px dashed var(--line); padding-top: 10px; }

/* ── Ask KrossRally (Home) ── */
.ask-card { border: 1px solid var(--line); background: var(--white); border-radius: 14px; padding: 14px 16px; margin-bottom: 16px; box-shadow: 0 4px 14px -12px rgba(22,36,26,0.3); }
.ask-title { font-size: 13.5px; font-weight: 800; color: var(--ink); margin-bottom: 10px; }
.ask-row { display: flex; gap: 8px; }
.ask-row .input { flex: 1; min-width: 0; }
/* "Ask Kross AI" — the AI identity across the app. Filled Indigo 800 pill,
   white text + white sparkle, soft indigo glow. Absolutely centred in the
   top bar so it sits EXACTLY midway between the menu and the bell on every
   screen size. Indigo 800 = the dedicated colour of every AI feature. */
#ask-fab { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); display: flex; align-items: center; gap: 7px; padding: 9px 16px; border-radius: 999px; border: 1.5px solid #3730A3; background: #F0F5FF; color: #000; font-family: inherit; font-size: 12.5px; font-weight: 800; letter-spacing: 0.02em; cursor: pointer; box-shadow: 0 3px 10px rgba(55, 48, 163, 0.18); transition: background 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease; white-space: nowrap; }
#ask-fab svg { width: 15px; height: 15px; flex: 0 0 auto; color: #3730A3; }
#ask-fab:hover { background: #E3ECFF; box-shadow: 0 5px 16px rgba(55, 48, 163, 0.28); transform: translate(-50%, -50%) scale(1.03); }
#ask-fab:active { transform: translate(-50%, -50%) scale(0.97); }

/* The Ask button inside the sheet matches the FAB — one consistent AI colour. */
.ask-row .btn-primary { background: #2E9E5B; border-color: #2E9E5B; }
.ask-row .btn-primary:hover { background: #278A50; border-color: #278A50; }

.ask-sheet-overlay { position: fixed; inset: 0; z-index: 80; background: rgba(22, 36, 26, 0.45); display: flex; align-items: flex-end; justify-content: center; }
.ask-sheet { width: 100%; max-width: 560px; height: 86%; background: var(--chalk); border-radius: 18px 18px 0 0; display: flex; flex-direction: column; box-shadow: 0 -8px 32px rgba(22, 36, 26, 0.25); animation: askSheetUp 0.22s ease; }
@keyframes askSheetUp { from { transform: translateY(28px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
.ask-sheet-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px 10px; border-bottom: 1px solid var(--line); flex: 0 0 auto; }
.ask-sheet-title { font-size: 16px; font-weight: 900; color: var(--ink); }
.ask-sheet-sub { font-size: 11.5px; color: var(--ink-soft); margin-top: 1px; }
.ask-sheet-body { flex: 1; overflow-y: auto; padding: 16px; -webkit-overflow-scrolling: touch; }

/* Voice-input mic button — matches the boxed-arrow language (white fill,
   indigo 800 border, dark icon). Turns red and pulses while listening. */
.ask-mic { flex: 0 0 auto; width: 42px; height: 42px; display: flex; align-items: center; justify-content: center; border-radius: 12px; border: 1.8px solid #3730A3; background: var(--white); color: #111; cursor: pointer; transition: border-color 0.15s ease, color 0.15s ease; }
.ask-mic svg { width: 18px; height: 18px; }
.ask-mic:hover { border-color: #312E81; }
.ask-mic.listening { border-color: #C0392B; color: #C0392B; animation: askMicPulse 1.2s ease-in-out infinite; }
@keyframes askMicPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(192, 57, 43, 0.35); }
  50% { box-shadow: 0 0 0 8px rgba(192, 57, 43, 0); }
}
.ask-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.ask-chip { padding: 5px 11px; border-radius: 999px; border: 1px solid var(--line); background: color-mix(in srgb, var(--ink) 3%, var(--white)); font-size: 11.5px; font-weight: 600; color: var(--ink-soft); cursor: pointer; }
.ask-chip:hover { border-color: var(--clay-light); color: var(--clay-dark); }
.ask-answer { margin-top: 10px; font-size: 13px; color: var(--ink); line-height: 1.55; border-top: 1px solid var(--line); padding-top: 10px; white-space: pre-wrap; }

/* Collapsible sections on the Ask tab — one shared shell so every future
   block (matchmaking, insights, history…) looks consistent. */
.ask-section { border: 1px solid var(--line); background: var(--white); border-radius: 14px; margin-top: 20px; box-shadow: 0 4px 14px -12px rgba(22,36,26,0.3); overflow: hidden; }
.ask-section-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 13px 16px; cursor: pointer; list-style: none; }
.ask-section-head::-webkit-details-marker { display: none; }
.ask-section-title { display: inline-flex; align-items: center; gap: 8px; font-size: 13.5px; font-weight: 800; color: var(--ink); }
.ask-section-ic { width: 15px; height: 15px; display: inline-flex; color: var(--clay); }
.ask-section-ic svg { width: 100%; height: 100%; }
.ask-section-chev { width: 16px; height: 16px; display: inline-flex; color: var(--ink-soft); transition: transform 0.18s ease; }
.ask-section-chev svg { width: 100%; height: 100%; }
.ask-section[open] .ask-section-chev { transform: rotate(180deg); }
.ask-section-body { padding: 0 16px 14px; }

/* Formatted answer bubbles: tidy paragraphs + real bullet lists. */
.ask-a-bubble .ask-p { margin: 0 0 8px; }
.ask-a-bubble .ask-p:last-child { margin-bottom: 0; }
.ask-a-bubble .ask-list { margin: 0 0 8px; padding-left: 20px; display: flex; flex-direction: column; gap: 5px; }
.ask-a-bubble .ask-list:last-child { margin-bottom: 0; }
.ask-a-bubble .ask-list li { line-height: 1.5; }
.ask-a-bubble .ask-list li::marker { color: var(--clay); }
.ask-a-bubble strong { font-weight: 800; color: #111; }

/* Dedicated Ask Kross Rally tab: intro + conversation thread. */
.ask-page-intro { font-size: 13px; color: var(--ink-soft); line-height: 1.55; margin-bottom: 14px; }
.ask-thread { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; }
.ask-q-bubble { align-self: flex-end; max-width: 85%; background: var(--ink); color: var(--chalk); font-size: 13px; line-height: 1.5; padding: 9px 13px; border-radius: 14px 14px 4px 14px; }
.ask-a-bubble { align-self: flex-start; max-width: 90%; background: var(--white); border: 1px solid var(--line); color: var(--ink); font-size: 13px; line-height: 1.55; padding: 10px 13px; border-radius: 14px 14px 14px 4px; box-shadow: 0 3px 10px -8px rgba(22,36,26,0.3); }

/* ── "Find me a game" (Home) ── */
.fg-sports { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; }
.fg-sport-tab { padding: 6px 12px; border-radius: 999px; border: 1px solid var(--line); background: var(--white); font-size: 12px; font-weight: 600; color: var(--ink-soft); cursor: pointer; }
.fg-sport-tab.active { background: var(--ink); border-color: var(--ink); color: var(--chalk); }
.fg-row { display: flex; align-items: center; gap: 10px; padding: 9px 0; border-top: 1px solid var(--line); }
.fg-info { flex: 1; min-width: 0; }
.fg-name { font-size: 13.5px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fg-sub { font-size: 11.5px; color: var(--ink-soft); margin-top: 2px; display: flex; align-items: center; gap: 6px; }
.fg-tag { font-size: 10px; font-weight: 700; padding: 1px 7px; border-radius: 999px; }
.fg-even { background: color-mix(in srgb, var(--grass) 12%, var(--white)); color: var(--grass); }
.fg-up { background: color-mix(in srgb, #D9A125 16%, var(--white)); color: #7A5B00; }
.fg-down { background: color-mix(in srgb, var(--ink) 6%, var(--white)); color: var(--ink-soft); }
.fg-invite { flex-shrink: 0; padding: 7px 13px; border-radius: 9px; border: 1px solid color-mix(in srgb, #25D366 45%, var(--line)); background: color-mix(in srgb, #25D366 8%, var(--white)); color: #128C57; font-size: 12px; font-weight: 700; cursor: pointer; }
.fg-invite:hover { background: color-mix(in srgb, #25D366 16%, var(--white)); }

/* Photo score-fill button in the result modal. */
.bsm-photo-btn { display: block; width: 100%; margin-top: 12px; padding: 10px; border: 1px dashed color-mix(in srgb, var(--clay) 45%, var(--line)); border-radius: 10px; background: color-mix(in srgb, var(--clay) 5%, var(--white)); color: var(--clay-dark); font-weight: 700; font-size: 12.5px; cursor: pointer; }
.bsm-photo-btn:hover { background: color-mix(in srgb, var(--clay) 10%, var(--white)); }

/* ── Championship odds panel ── */
.odds-row { display: flex; align-items: center; gap: 10px; padding: 6px 0; }
.odds-rank { flex-shrink: 0; width: 18px; text-align: center; font-size: 11.5px; font-weight: 700; color: var(--ink-soft); }
.odds-name { flex: 0 1 auto; min-width: 90px; max-width: 45%; font-size: 13px; font-weight: 600; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.odds-bar { flex: 1; height: 7px; border-radius: 999px; background: color-mix(in srgb, var(--ink) 7%, var(--white)); overflow: hidden; }
.odds-fill { display: block; height: 100%; border-radius: 999px; background: #3730A3; }
.odds-pct { flex-shrink: 0; width: 42px; text-align: right; font-size: 12.5px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
.odds-note { font-size: 11px; color: var(--ink-soft); margin-top: 8px; }

/* ── Tournament recap card ── */
.recap-card { border: 1.8px solid color-mix(in srgb, var(--ink-soft) 65%, var(--white)); background: var(--white); border-radius: 14px; padding: 16px; margin-bottom: 16px; box-shadow: 0 4px 14px -10px rgba(22,36,26,0.28); }
.recap-title { display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 900; color: #111; margin-bottom: 12px; }
.recap-title svg { width: 17px; height: 17px; color: #C8912B; }
.recap-champ { display: flex; align-items: baseline; gap: 8px; padding: 6px 0; border-top: 1px solid var(--line); font-size: 13px; }
.recap-medal { flex-shrink: 0; }
.recap-cat { color: var(--ink-soft); font-weight: 500; min-width: 0; }
.recap-name { font-weight: 800; color: var(--ink); margin-left: auto; text-align: right; }
.recap-stats { font-size: 12.5px; color: var(--ink-soft); margin-top: 10px; line-height: 1.5; }

/* ── Schedule clash banner (organiser-only, tournament page) ── */
.clash-banner {
  border: 1.8px solid #C22B2B;
  background: color-mix(in srgb, #C22B2B 6%, var(--white));
  border-radius: 14px;
  padding: 14px 16px;
  margin-bottom: 16px;
}
.clash-title { font-size: 13.5px; font-weight: 800; color: #A21F1F; margin-bottom: 10px; }
.clash-row { padding: 7px 0; border-top: 1px solid color-mix(in srgb, #C22B2B 14%, transparent); font-size: 12.5px; line-height: 1.5; }
.clash-name { font-weight: 800; color: var(--ink); margin-right: 6px; }
.clash-detail { color: var(--ink-soft); }
.clash-more { font-size: 12px; color: var(--ink-soft); padding-top: 6px; }
.clash-hint { font-size: 11.5px; color: var(--ink-soft); margin-top: 10px; }
.clash-ok { font-size: 12px; font-weight: 600; color: var(--grass); margin-bottom: 14px; }

/* WhatsApp actions — WhatsApp's own green so the intent is instantly clear. */
.wa-share-btn { color: var(--ink) !important; border: 1px solid var(--line) !important; background: var(--white) !important; }
.wa-share-btn:hover { background: color-mix(in srgb, var(--ink) 5%, var(--white)) !important; }
.wa-join-btn { display: inline-flex; align-items: center; gap: 7px; background: #128C57; color: #fff; font-weight: 700; text-decoration: none; }
.wa-join-btn:hover { filter: brightness(1.05); }

/* Greyed-out Register for players who can't enter this category. */
.draw-reg-ineligible {
  background: color-mix(in srgb, var(--ink) 7%, var(--white)) !important;
  border: 1px solid var(--line) !important;
  color: var(--ink-soft) !important;
  cursor: not-allowed !important;
  opacity: 0.8;
}
.draw-reg-why { margin-top: 8px; font-size: 12px; color: var(--ink-soft); text-align: center; }
/* Centred arrow — the single, only way into the category detail. */
.draw-open-center { display: flex; justify-content: center; margin-top: 14px; }

/* Action-button colours across tournaments: Register is GREEN, while Close
   Registration and Add players are BLUE — so they read distinctly from the
   clay/orange brand primary. */
.btn-primary[data-action="register-draw"],
#draw-add-players-btn.btn-primary,
#draw-save-format-btn.btn-primary,
#draw-start-btn.btn-primary { background: #2E9E5B !important; border-color: #2E9E5B !important; color: #fff !important; }
.btn-primary[data-action="register-draw"]:hover,
#draw-add-players-btn.btn-primary:hover,
#draw-save-format-btn.btn-primary:hover,
#draw-start-btn.btn-primary:hover { background: #278A50 !important; }
#draw-close-reg-btn.btn-primary { background: #2E9E5B !important; border-color: #2E9E5B !important; color: #fff !important; }
#draw-close-reg-btn.btn-primary:hover { background: #278A50 !important; }

/* Round-robin stage tabs: Players | Group 1… | Overall Standings. */
.rr-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin: 4px 0 12px; }
.rr-tab { font-size: 12px; font-weight: 700; padding: 7px 13px; border-radius: 999px; border: 1px solid var(--line); background: var(--white); color: var(--ink-soft); cursor: pointer; font-family: inherit; transition: background 0.15s ease, color 0.15s ease; }
.rr-tab.active { background: #3730A3; border-color: #3730A3; color: #fff; }
.rr-overall-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.rr-overall-table th { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-soft); padding: 6px; border-bottom: 1px solid var(--line); text-align: center; }
.rr-overall-table td { padding: 7px 6px; border-bottom: 1px solid color-mix(in srgb, var(--ink) 5%, var(--white)); text-align: center; color: var(--ink); }
.rr-overall-table tr:last-child td { border-bottom: none; }

/* Mobile bracket pager — one round at a time. The desktop bracket strip
   (.bf-desktop-only) hides on phones; the pager hides on desktop. */
.bf-mobile-pager { display: none; }
@media (max-width: 719px) {
  .bf-desktop-only { display: none !important; }
  .bf-mobile-pager { display: block; }
}
.bfp-current { text-align: center; font-size: 12.5px; color: var(--ink-soft); border: 1px solid var(--line); background: var(--white); border-radius: 10px; padding: 8px 10px; margin-bottom: 10px; }
.bfp-current strong { color: var(--ink); font-weight: 800; }
.bfp-nav { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 12px; }
.bfp-btn { font-size: 12px; font-weight: 800; color: #111; background: var(--white); border: 1.8px solid #3730A3; border-radius: 10px; padding: 9px 13px; cursor: pointer; font-family: inherit; }
.bfp-btn:active { transform: scale(0.97); }
.bfp-matches .bf-slot { width: 100%; margin-bottom: 10px; }
.bfp-matches .bf-slot > * { width: 100%; }

/* Create/record actions are GREEN across the app: Record a match (Home),
   New game (Community), the tournaments "+" and Request-a-tournament card. */
#home-record-btn.btn-primary,
#cg-create-btn.btn-primary { background: #2E9E5B !important; border-color: #2E9E5B !important; color: #fff !important; }
#home-record-btn.btn-primary:hover,
#cg-create-btn.btn-primary:hover { background: #278A50 !important; }

/* ---- Tournament-day attendance ---- */
.att-self { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; padding: 14px 16px; }
.att-self-txt { flex: 1; min-width: 180px; font-size: 12.5px; color: var(--ink-soft); }
.att-self-ok { font-size: 13px; font-weight: 700; color: #2E9E5B; }
.att-time { flex: 0 0 auto; margin-left: 6px; font-size: 11px; color: var(--ink-soft); white-space: nowrap; }
.bf-ready, .rr-ready { margin-top: 6px; font-size: 11px; font-weight: 700; letter-spacing: 0.02em; color: #7FC79C; }

/* ---- Entry-fee payments (UPI + manual confirm) ---- */
.pay-block { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--line); }
.pay-pending { font-size: 12px; font-weight: 700; color: #D9A125; text-align: center; margin-top: 8px; }
.pay-confirmed { font-size: 12.5px; font-weight: 700; color: #2E9E5B; text-align: center; margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--line); }
.pay-chip { flex: 0 0 auto; font-size: 10px; font-weight: 800; letter-spacing: 0.02em; border-radius: 999px; padding: 2px 8px; margin-left: 6px; white-space: nowrap; }
.pay-chip.pc-ok { color: #fff; background: #2E9E5B; }
.pay-chip.pc-claim { color: #7A5A10; background: color-mix(in srgb, #D9A125 22%, var(--white)); border: 1px solid color-mix(in srgb, #D9A125 45%, transparent); }
.pay-chip.pc-none { color: var(--ink-soft); background: color-mix(in srgb, var(--ink) 6%, var(--white)); }
.rtl-btn.pay-ok { color: #2E9E5B; font-weight: 800; font-size: 11px; width: auto; padding: 0 7px; }
.pay-bulkbar { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; margin: 10px 0 2px; }
.pay-selall { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--ink-soft); cursor: pointer; }
.pay-sel, .pay-sel-all { width: 16px; height: 16px; accent-color: #2E9E5B; flex: 0 0 auto; cursor: pointer; }
.pay-sel-spacer { width: 16px; flex: 0 0 auto; }
.rtl-btn.wa-chat { text-decoration: none; display: inline-flex; align-items: center; justify-content: center; }

/* "Invite players" on category cards — plain bordered button, black text. */
.draw-invite-btn { background: var(--white); border: 1px solid var(--line); color: #111; font-weight: 600; }
.draw-invite-btn:hover { border-color: color-mix(in srgb, var(--ink) 30%, var(--line)); }

/* Category status flow — quiet GitHub/Linear-style step indicator.
   done = green ✓  ·  current = indigo dot  ·  future = grey. */
.cat-flow { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 2px; margin: 12px 0 4px; }
.cat-flow-step { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 600; color: var(--ink-soft); white-space: nowrap; }
.cat-flow-step.done { color: var(--ink); }
.cat-flow-step.cur { color: #3730A3; font-weight: 700; }
.cfs-dot { width: 14px; height: 14px; border-radius: 50%; border: 1.5px solid var(--line); display: inline-flex; align-items: center; justify-content: center; font-size: 9px; line-height: 1; flex: 0 0 auto; background: var(--white); color: #fff; }
.cfs-dot-done { background: #2E9E5B; border-color: #2E9E5B; }
.cfs-dot-cur { background: #3730A3; border-color: #3730A3; box-shadow: inset 0 0 0 2.5px var(--white); }
.cat-flow-line { flex: 1 0 8px; max-width: 20px; height: 1.5px; background: var(--line); margin: 0 3px; }
.cat-flow-line.done { background: #2E9E5B; }

/* Tournament progress — thicker rounded bar + count + current stage. */
.cpc-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; margin-top: 16px; flex-wrap: wrap; }
.cpc-title { font-size: 11.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-soft); }
.cpc-count { font-size: 13.5px; font-weight: 800; color: var(--ink); }
.cpc-bar { height: 10px; border-radius: 999px; background: color-mix(in srgb, var(--ink) 7%, var(--white)); margin: 8px 0; overflow: hidden; }
.cpc-fill { height: 100%; border-radius: 999px; background: #2E9E5B; transition: width 0.3s ease; }
.cpc-stage { font-size: 12px; color: var(--ink-soft); }
.cpc-stage strong { color: #3730A3; font-weight: 700; }

/* Registered players/teams — expandable section at the bottom of a category. */
.reg-teams-details summary::-webkit-details-marker { display: none; }
.rtd-summary { display: flex; align-items: center; gap: 8px; font-weight: 800; font-size: 13.5px; color: var(--ink); cursor: pointer; list-style: none; }
.rtd-ic { width: 16px; height: 16px; display: inline-flex; color: #3730A3; }
.rtd-ic svg { width: 100%; height: 100%; }
.rtd-summary .rr-results-chev { margin-left: auto; transition: transform 0.15s ease; }
.reg-teams-details[open] .rtd-summary .rr-results-chev { transform: rotate(180deg); }

/* ===== Americano / Mexicano social rotation view ===== */
.soc-standings { display: flex; flex-direction: column; padding: 4px 2px; }
.soc-stand-row { display: flex; align-items: center; gap: 10px; padding: 9px 8px; border-bottom: 1px solid var(--line); }
.soc-stand-row:last-child { border-bottom: none; }
.soc-rank { flex-shrink: 0; width: 22px; text-align: center; font-weight: 800; font-size: 13px; color: var(--ink-soft); }
.soc-sname { flex: 1; min-width: 0; font-weight: 700; font-size: 14px; color: var(--ink); display: flex; align-items: center; gap: 8px; }
.soc-pts { flex-shrink: 0; font-weight: 800; font-size: 15px; color: var(--ink); font-variant-numeric: tabular-nums; }
.soc-pts-lbl { font-size: 10px; font-weight: 700; color: var(--ink-soft); margin-left: 3px; text-transform: uppercase; }
.soc-champ { background: color-mix(in srgb, #E7B54B 10%, transparent); border-radius: 8px; }
.soc-champ-tag { display: inline-flex; align-items: center; gap: 4px; font-size: 10.5px; font-weight: 800; color: #8A5E12; text-transform: uppercase; letter-spacing: 0.03em; }
.soc-champ-tag svg { width: 12px; height: 12px; }

.soc-rounds { display: flex; flex-direction: column; gap: 10px; }
.soc-round { border: 1px solid var(--line); border-radius: 12px; background: var(--white); overflow: hidden; }
.soc-round-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 12px 14px; font-weight: 700; font-size: 13.5px; color: var(--ink); cursor: pointer; list-style: none; }
.soc-round-head::-webkit-details-marker { display: none; }
.soc-round-count { font-size: 11.5px; font-weight: 600; color: var(--ink-soft); }
.soc-courts { padding: 0 14px 12px; display: flex; flex-direction: column; gap: 10px; }
.soc-court { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 10px; padding: 10px 0; border-top: 1px solid var(--line); }
.soc-court:first-child { border-top: none; }
.soc-team { font-size: 13px; font-weight: 600; color: var(--ink-soft); min-width: 0; }
.soc-court .soc-team:last-of-type { text-align: right; }
.soc-team.soc-won { color: var(--ink); font-weight: 800; }
.soc-score { font-size: 14px; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.soc-enter-btn { grid-column: 1 / -1; margin-top: 4px; padding: 9px; border: 1px solid var(--line); border-radius: 9px; background: color-mix(in srgb, var(--clay) 6%, var(--white)); color: var(--clay-dark); font-weight: 700; font-size: 12.5px; cursor: pointer; }
.soc-enter-btn:hover { background: color-mix(in srgb, var(--clay) 12%, var(--white)); }
.soc-sitout { font-size: 11.5px; color: var(--ink-soft); padding-top: 8px; border-top: 1px dashed var(--line); }
.soc-score-form { display: flex; flex-direction: column; gap: 12px; }

/* Category cards read like clean list rows: everything muted grey EXCEPT the
   category name and the coloured Register button. Every status pill, spots
   pill, entry-fee and prize chip is flattened to the same grey. Scoped to
   .draw-row so the status colours elsewhere (list tabs) are untouched. */
.draw-row .pill,
.draw-row .draw-meta-chip,
.draw-row .draw-meta-chip-gold,
.draw-row .draw-meta-chip-rating,
.draw-row .draw-meta-chip-fee {
  background: color-mix(in srgb, var(--ink) 6%, var(--white)) !important;
  color: var(--ink-soft) !important;
  border: 1px solid var(--line) !important;
  font-weight: 600 !important;
}
.draw-row .pill { font-size: 12.5px !important; font-weight: 500 !important; padding: 4px 11px !important; }
.draw-row .pill::before { background: var(--ink-soft) !important; }
.draw-row .draw-progress-pending { color: var(--ink-soft); }
.draw-row .dmc-ic, .draw-row .dpc-ic { color: var(--ink-soft); }
/* Progress bar + live dot keep a STATUS colour (green open / amber in progress
   / blue completed) — everything else in the card is grey. Colour is set
   inline per draw status. */

/* Clean information strip (replaces the old pill badges): icon + text only,
   no backgrounds, no borders. Grey icons for normal info, subtle gold for
   prize positions. Wraps gracefully with even spacing. */
.draw-info-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 22px;
  margin-top: 16px;
}
.dis-item {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-soft);   /* light grey like the format line */
  line-height: 1.2;
}
.dis-ic {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  display: inline-flex;
  color: var(--ink-soft);   /* grey for normal info */
}
.dis-ic svg { width: 100%; height: 100%; display: block; }
.dis-ic-gold { color: #C8912B; }   /* subtle gold, prize positions only */
.dpc-ic { width: 13px; height: 13px; display: inline-flex; color: var(--ink-soft); }
.dpc-ic svg { width: 100%; height: 100%; }
.draw-progress-pending { font-size: 11.5px; font-weight: 700; color: var(--clay); }
/* Live stage line shown once a draw has started (replaces the registered bar). */
.draw-live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--grass); flex-shrink: 0; animation: kr-live-pulse 1.4s ease-in-out infinite; }
@keyframes kr-live-pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.4; transform: scale(0.75); } }
.draw-live-matches { font-size: 11.5px; font-weight: 500; color: var(--ink-soft); }

/* "Last-minute changes" organiser panel shown under a live bracket until the
   first score is entered (add / replace / remove entrants, draw regenerates). */
.late-changes-card { margin-top: 16px; }
.late-changes-summary { display: flex; align-items: center; gap: 8px; font-size: 13.5px; font-weight: 700; color: var(--ink); cursor: pointer; list-style: none; }
.late-changes-summary::-webkit-details-marker { display: none; }
.lcs-ic { width: 15px; height: 15px; display: inline-flex; color: var(--clay-dark); flex-shrink: 0; }
.lcs-ic svg { width: 100%; height: 100%; }
.late-changes-summary .dxt-chev { margin-left: auto; }
details[open] > .late-changes-summary .dxt-chev { transform: rotate(180deg); }
.late-changes-note { margin-top: 10px; font-size: 12.5px; color: var(--ink-soft); line-height: 1.5; }

/* Inline max-players slider on the tournament page's category cards. */
.exp-inline { display: flex; align-items: center; gap: 10px; margin-top: 9px; }
/* Plain sentence-case label, same muted grey as the rest of the card (not the
   old shouty uppercase). */
.exp-inline-label { flex-shrink: 0; font-size: 12.5px; font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--ink-soft); }
.exp-set-locked { font-size: 12.5px !important; font-weight: 600 !important; color: var(--ink) !important; }
/* Reset / Set button shares the same 12.5px type as the rest of the row. */
.exp-set-row .btn { font-weight: 500; font-size: 12.5px; }
.exp-inline input[type="range"] { flex: 1; min-width: 0; cursor: pointer; }
.exp-inline-value { flex-shrink: 0; min-width: 26px; text-align: right; font-family: var(--font-display); font-size: 17px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
.dpc-detail { font-weight: 600; color: var(--ink-soft); }


/* Completed-category podium on the tournament page: winner + runner-up with
   the rating points each gained in this category. */
/* Clean completed-category "Results" block — a heading, then each place
   stacked: role, name(s), rating change. */
.draw-results { margin-top: 16px; }
.dr-head {
  display: flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 800; color: var(--ink);
  letter-spacing: 0.02em; margin-bottom: 12px;
}
.dr-trophy { width: 16px; height: 16px; flex-shrink: 0; display: inline-flex; color: #C8912B; }
.dr-trophy svg { width: 100%; height: 100%; display: block; }
.dr-place { margin-bottom: 12px; }
.dr-place:last-child { margin-bottom: 0; }
.dr-role {
  font-size: 11px; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--ink-soft);
}
.dr-name { font-size: 15px; font-weight: 700; color: var(--ink); margin-top: 3px; }
.dr-rating { font-size: 13px; font-weight: 600; margin-top: 2px; font-variant-numeric: tabular-nums; }
.dr-rating.up { color: var(--grass); }
.dr-rating.down { color: #C22B2B; }

/* Bold accent title for the Add Categories section (create tournament). */
.ct-cat-title { font-weight: 800 !important; color: var(--clay-dark) !important; }

/* Pre-draw summary grid (organiser, after closing registration). */
.predraw-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 8px; margin-top: 8px; }
.predraw-cell { display: flex; flex-direction: column; gap: 1px; font-size: 10.5px; font-weight: 700; letter-spacing: 0.3px; text-transform: uppercase; color: var(--ink-soft); background: color-mix(in srgb, var(--ink) 4%, var(--white)); border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; }
.predraw-cell strong { font-family: var(--font-display); font-size: 17px; color: var(--ink); text-transform: none; letter-spacing: 0; }

/* Priority number chip in My Sports — green, which reads livelier than the
   clay/orange and sets it apart from the destructive-looking warm tones. */
.prio-num { margin-left: auto; flex-shrink: 0; font-size: 11px; font-weight: 800; color: var(--grass-dark, #2A6B3D); background: color-mix(in srgb, var(--grass) 14%, var(--white)); border: 1px solid color-mix(in srgb, var(--grass) 26%, transparent); border-radius: 999px; padding: 2px 8px; }
.prio-num + .fav-star { margin-left: 6px; }

/* Player-card photo avatar. */
.pcard-avatar-photo { overflow: hidden; padding: 0; }
.pcard-avatar-photo img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: inherit; }

/* Favourite-sport star in Profile's My Sports list. */
.fav-star { margin-left: auto; flex-shrink: 0; width: 30px; height: 30px; border: none; background: transparent; font-size: 19px; line-height: 1; color: var(--ink-soft); cursor: pointer; border-radius: 8px; padding: 0; }
.fav-star:hover { background: color-mix(in srgb, var(--ball, #E4C34A) 18%, transparent); color: var(--clay-dark); }
.fav-star.active { color: #D9A93C; }

/* ===== Kross Rally signature background language (js/watermarks.js) =====
   One curated full-viewport composition per page — fixed, behind everything,
   never interactive. Thin outlines stay crisp 1–2px at any scale via
   non-scaling-stroke. Slow "breathing" is decorative only and disabled for
   reduced-motion users. */
/* The layer is deliberately STATIC — no breathing opacity, no scroll parallax.
   Animating it forced the browser to keep re-rasterising everything drawn on
   top of it, which made cards and poster thumbnails look like they were
   drifting and blurring. `contain` keeps it isolated from page content. */
#wm-layer { position: fixed; inset: -40px 0; overflow: hidden; pointer-events: none; opacity: 0.9; contain: paint; }
#wm-layer svg { display: block; width: 100%; height: 100%; }
#wm-layer svg * { vector-effect: non-scaling-stroke; }

/* Tournament progress strip above the bracket. */
.bracket-progress { margin: 2px 0 12px; }
.bracket-progress-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.bp-title { font-size: 12px; font-weight: 800; letter-spacing: 0.4px; text-transform: uppercase; color: var(--ink-soft); }
.bp-count { font-size: 12.5px; font-weight: 700; color: var(--ink); }

/* Bracket player popup (click a name on a card). */
.bpp-row { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.bpp-row:last-of-type { border-bottom: none; }
.bpp-photo { width: 46px; height: 46px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.bpp-info { flex: 1; min-width: 0; }
.bpp-name { font-weight: 700; font-size: 15px; color: var(--ink); margin-bottom: 4px; }
.bpp-stats { display: flex; gap: 14px; flex-wrap: wrap; }
.bpp-stat { display: flex; flex-direction: column; font-size: 10.5px; color: var(--ink-soft); font-weight: 600; }
.bpp-stat strong { font-size: 14px; color: var(--ink); }
.bpp-view-btn { flex-shrink: 0; padding: 6px 10px; font-size: 12px; }
.bpp-note { margin-top: 10px; font-size: 11px; color: var(--ink-soft); }

/* "View match" read-only summary modal. */
.vm-names { font-size: 16px; font-weight: 700; color: var(--ink); }
.vm-vs { color: var(--ink-soft); font-weight: 500; font-size: 13px; }
.vm-winner { display: flex; align-items: center; gap: 6px; margin-top: 6px; font-size: 13.5px; font-weight: 700; color: var(--grass); }
.vm-crown { width: 14px; height: 14px; display: inline-flex; color: var(--ball, #E8C34A); }
.vm-crown svg { width: 100%; height: 100%; }
.vm-block { margin-top: 14px; }
.vm-block-title { font-size: 11px; font-weight: 800; letter-spacing: 0.4px; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 6px; }
.vm-row { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding: 5px 0; border-bottom: 1px dashed var(--line); font-size: 13px; color: var(--ink-soft); }
.vm-row:last-child { border-bottom: none; }
.vm-row strong { color: var(--ink); }
.vm-up { color: var(--grass) !important; }
.vm-down { color: #C22B2B !important; }
.vm-status { margin-top: 14px; display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 700; border-radius: 999px; padding: 4px 12px; }
.vm-status.vm-ok { color: var(--grass); background: color-mix(in srgb, var(--grass) 12%, var(--white)); }
.vm-status.vm-warn { color: var(--clay-dark); background: color-mix(in srgb, var(--clay) 12%, var(--white)); }
.draw-progress-bar { height: 8px; border-radius: 999px; background: color-mix(in srgb, var(--ink) 8%, var(--white)); overflow: hidden; margin: 2px 0 4px; }
.draw-progress-fill { height: 100%; border-radius: 999px; transition: width 0.4s ease; }

.draw-expand-toggle {
  margin-top: 11px;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-soft);
  background: color-mix(in srgb, var(--ink) 4%, var(--white));
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.draw-expand-toggle:hover { background: color-mix(in srgb, var(--clay) 8%, var(--white)); color: var(--ink); }
.dxt-chev { width: 14px; height: 14px; display: inline-flex; }
.dxt-chev svg { width: 100%; height: 100%; }

/* Registered players/teams inside an expanded category row — a numbered list
   in registration order (the participants array is appended as players join /
   are added, so array order IS join order). CSS multi-column layout flows the
   names DOWN each column first, then into the next column, auto-fitting as
   many ~170px columns as the card width allows. */
.draw-entrant-grid {
  columns: 170px;
  column-gap: 14px;
  margin-top: 12px;
}
.draw-entrant-item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
  font-size: 13.5px;
  padding: 5px 8px;
  margin-bottom: 7px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 8px;
  break-inside: avoid;
}
.dei-num {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 800;
  color: var(--clay-dark);
  min-width: 16px;
  text-align: right;
}
.dei-name {
  min-width: 0;
  font-weight: 600;
  color: var(--ink);
  word-break: break-word;
}

.pill-closed { background: color-mix(in srgb, var(--ink) 12%, var(--white)); color: var(--ink-soft); }

/* Status dots on registration pills — colour-coded state at a glance. */
.pill-registering::before, .pill-soon::before, .pill-full::before, .pill-closed::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  margin-right: 5px;
  vertical-align: 1px;
}
.pill-registering::before { background: var(--grass); }
.pill-soon::before { background: #D9A93C; }
.pill-full::before { background: #C22B2B; }
.pill-closed::before { background: var(--ink-soft); }

/* Premium entry-fee chip on category cards. */
.draw-meta-chip-fee { background: var(--clay-dark); color: var(--white); font-weight: 800; border-color: var(--clay-dark); }

/* Stronger stat cards under the tournament hero. */
.tourn-quickinfo .tqi-num { font-size: 19px; }
.tourn-quickinfo .tqi-num.tqi-num-sm { font-size: 14px; }

/* Clearer full-width Manage/View teams action on category cards. */
.draw-expand-toggle { font-size: 13.5px; font-weight: 700; color: var(--ink); border-color: color-mix(in srgb, var(--ink) 18%, var(--white)); background: var(--white); }
.draw-expand-toggle:hover { border-color: var(--clay); color: var(--clay-dark); background: color-mix(in srgb, var(--clay) 6%, var(--white)); }

/* Progress bars animate smoothly as registrations land. */
.reg-progress-fill, .draw-progress-fill { transition: width 0.45s ease; }

/* Little overlapping person icons + spots-remaining line on category cards. */
.dpc-persons { display: inline-flex; align-items: center; margin-right: 2px; }
.dpc-person { width: 13px; height: 13px; display: inline-flex; color: var(--ink-soft); }
.dpc-person svg { width: 100%; height: 100%; }
.dpc-person + .dpc-person { margin-left: -4px; }
.dpc-spots { margin-top: 8px; font-size: 12.5px; font-weight: 500; color: var(--ink-soft); }

/* Hourglass state on the registration stat card (Closing Soon). */
.tqi-ic-hourglass { font-size: 18px; line-height: 1; }

/* Player-facing draw-format explainer — trophy in its own column so all
   three text lines share one clean left edge. */
.dfr-row { display: flex; align-items: flex-start; gap: 10px; }
.dfr-emoji { font-size: 19px; line-height: 1.25; flex-shrink: 0; }
.dfr-col { min-width: 0; }
.dfr-col .dfr-value { margin: 0; }
.dfr-sub { font-size: 13px; font-weight: 700; color: var(--ink); margin-top: 3px; }
.dfr-sub2 { font-size: 12px; color: var(--ink-soft); margin-top: 2px; }

/* "What happens next" journey timeline (players, while registration open).
   The whole column is centred in the card, but steps are LEFT-aligned within
   it so every dot sits on the same vertical line, with each arrow centred
   under the dots. */
.draw-journey { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; padding: 6px 0; width: max-content; margin: 0 auto; }
.dj-step { display: inline-flex; align-items: center; gap: 9px; font-size: 13.5px; font-weight: 700; color: var(--ink-soft); }
.dj-step.done { color: var(--grass); }
.dj-dot { width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--line); display: inline-flex; align-items: center; justify-content: center; font-size: 11px; flex-shrink: 0; background: var(--white); }
.dj-step.done .dj-dot { border-color: var(--grass); color: var(--grass); font-weight: 800; }
.dj-arrow { color: var(--ink-soft); font-size: 13px; line-height: 1; opacity: 0.6; width: 18px; text-align: center; }

/* Urgency line on the shareable tournament card. */
.share-card-urgency { margin-top: 10px; font-size: 12.5px; font-weight: 800; color: var(--clay-dark); background: color-mix(in srgb, var(--clay) 10%, var(--white)); border: 1px solid color-mix(in srgb, var(--clay) 28%, transparent); border-radius: 9px; padding: 7px 11px; }

/* Perk checklist lines inside the hero offer badge. */
.hob-line { font-family: var(--font-display); font-size: clamp(10.5px, 1.8vw, 12.5px); font-weight: 700; color: #0E2E1B; margin-top: 2px; }

/* Status + official badges side by side under the tournament name. */
.hero-badge-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 8px 0 2px; position: relative; z-index: 1; }
.hero-badge-row .tourn-status-badge { position: static; margin: 0; }
/* Gold "Official Rating Event" badge — same gilt treatment as the prize
   medallion so it reads as premium at a glance. */
.official-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #4A3305;
  background: linear-gradient(135deg, #FCEBB0 0%, #E7B54B 55%, #C88E28 100%);
  border-radius: 999px;
  padding: 4px 11px;
  box-shadow: 0 4px 10px -4px rgba(0, 0, 0, 0.4), inset 0 0 0 1px rgba(255, 255, 255, 0.4);
}
.official-badge .ob-ic { width: 12px; height: 12px; display: inline-flex; }
.official-badge .ob-ic svg { width: 100%; height: 100%; }

/* Overflow (⋮) menu. */
.tourn-menu-wrap { position: relative; z-index: 10; }
/* The ⋮ sits near the hero's right edge, so the dropdown must open toward the
   LEFT (right-aligned to the button) — opening rightward pushed it off the
   screen edge on mobile, which is what caused the sideways-scroll/background. */
.tourn-menu-wrap .tourn-menu { left: auto; right: 0; }
.tourn-menu-btn { transition: background 0.15s ease, transform 0.15s ease; }
.tourn-menu-btn:hover { transform: translateY(-1px); }
.tourn-menu {
  position: absolute;
  top: 44px;
  right: 0;
  min-width: 210px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 16px 40px -14px rgba(22, 36, 26, 0.5);
  padding: 6px;
  z-index: 40;
  animation: tourn-menu-in 0.14s ease;
}
@keyframes tourn-menu-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }
.tourn-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border: none;
  background: none;
  border-radius: 8px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
  transition: background 0.12s ease;
}
.tourn-menu-item:hover { background: color-mix(in srgb, var(--clay) 8%, var(--white)); }
.tourn-menu-item:disabled { opacity: 0.45; cursor: default; }
.tourn-menu-item.danger { color: var(--clay-dark); }
.tourn-menu-item.danger:hover { background: color-mix(in srgb, var(--clay) 14%, var(--white)); }
.tmi-ic { width: 16px; height: 16px; flex-shrink: 0; display: inline-flex; }
.tmi-ic svg { width: 100%; height: 100%; }

/* Poster lightbox tools + zoom. */
.poster-lightbox-tools { position: absolute; top: 18px; right: 18px; display: flex; gap: 10px; z-index: 2; }
.poster-lightbox-btn {
  width: 42px;
  height: 42px;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Solid dark chips with a light border — clearly visible over ANY poster,
     light or dark (the old translucent white vanished on light posters). */
  border: 1.5px solid rgba(255, 255, 255, 0.85);
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.62);
  color: #fff;
  cursor: pointer;
  transition: background 0.15s ease;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.45);
}
.poster-lightbox-btn:hover { background: rgba(0, 0, 0, 0.82); }
.poster-lightbox-btn svg { width: 20px; height: 20px; }
.poster-lightbox-img { cursor: zoom-in; transition: transform 0.25s ease; }
.poster-lightbox-img.zoomed { transform: scale(2); cursor: zoom-out; }

/* Shareable tournament card. */
.share-card {
  width: 300px;
  max-width: 100%;
  margin: 0 auto 16px;
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid var(--line);
  box-shadow: 0 14px 34px -16px rgba(22, 36, 26, 0.5);
  background: var(--white);
}
.share-card-top { padding: 20px 18px; color: #fff; }
.share-card-brand { font-family: var(--font-display); font-size: 12px; font-weight: 700; letter-spacing: 2px; opacity: 0.9; }
.share-card-name { font-family: var(--font-display); font-size: 23px; font-weight: 700; line-height: 1.15; margin-top: 6px; }
.share-card-sport { font-size: 12.5px; font-weight: 600; opacity: 0.9; margin-top: 3px; }
.share-card-body { padding: 16px 18px; display: flex; flex-direction: column; gap: 9px; }
.share-card-row { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; color: var(--ink); }
.scr-ic { width: 15px; height: 15px; flex-shrink: 0; color: var(--clay); display: inline-flex; }
.scr-ic svg { width: 100%; height: 100%; }
.share-card-prize {
  margin-top: 4px;
  padding: 9px 12px;
  border-radius: 10px;
  background: linear-gradient(135deg, #FCEBB0, #E7B54B 55%, #C88E28);
  color: #241900;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  text-align: center;
}
.share-card-foot { padding: 11px 18px; border-top: 1px solid var(--line); font-size: 11.5px; font-weight: 700; letter-spacing: 0.5px; color: var(--ink-soft); text-align: center; }
.share-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.share-actions .btn { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 7px; text-decoration: none; }

/* Unique per-tournament QR inside the shareable card — scanning it deep-links
   straight to that tournament. */
.share-card-qr { display: flex; flex-direction: column; align-items: center; gap: 6px; margin-top: 14px; padding-top: 14px; border-top: 1px dashed var(--line); }
.share-card-qr img { width: 132px; height: 132px; border-radius: 10px; border: 1px solid var(--line); background: #fff; padding: 4px; }
.share-card-qr span { font-size: 11px; font-weight: 700; letter-spacing: 0.4px; color: var(--ink-soft); text-transform: uppercase; }

/* Give the detail sections a touch more breathing room. */
.tourn-hero + .tourn-quickinfo { margin-top: 0; }

/* ===== Light tournament hero — clean, front-page aesthetic ===== */
/* Name in the same black bold face as the tournament list; meta rows in the
   muted style used on the list cards; a soft light background instead of the
   old dark maroon gradient. */
/* A bordered, rounded card — the same container treatment as a tournament
   list item — rather than a full-bleed banner. */
/* Two classes so this beats the base .back-link (cream, for dark heroes) which
   appears later in the file — otherwise the link is invisible on the page bg. */
.back-link.back-link-top { margin: 10px 0 6px 16px; color: var(--ink); font-weight: 700; }
.back-link.back-link-top:hover { color: var(--ink); opacity: 0.7; }
.tourn-hero-light {
  margin: 4px 16px 16px;   /* a little breathing room before the stat cards */
  background: var(--white);
  /* Same darker, more visible border as the tournament list cards. */
  border: 1.8px solid color-mix(in srgb, var(--ink-soft) 65%, var(--white));
  border-radius: 14px;
  box-shadow: 0 4px 14px -10px rgba(22, 36, 26, 0.28);
}
/* More air inside the hero: name → status → meta → prize all get room. */
.tourn-hero-light .hero-badge-row { margin: 12px 0 4px; }
/* Meta rows: tighter, elegant rhythm — ~10px between rows, clear column gap. */
.tourn-hero-light .dhi-grid { margin-top: 14px; gap: 10px 28px; }
.tourn-hero-light .dhi-cell { align-items: flex-start; }
.tourn-hero-light .dhi-ic { margin-top: 1px; }
/* Prize chip floats on the right, VERTICALLY CENTRED against the tournament
   info block for balance (instead of pinned to the bottom). Drops below the
   meta on narrow screens via the base .hero-perks media query. */
.tourn-hero-light .hero-perks { margin-top: 16px; }
@media (min-width: 701px) {
  .tourn-hero-light .hero-perks {
    top: 50%;
    bottom: auto;
    right: 20px;
    transform: translateY(-50%);
  }
}

/* ===== Flat soft-gold Prize chip ===== */
/* Premium information card: a very soft indigo gradient wash (not a flat
   fill), light border, subtle shadow. Indigo 800 is the accent; the AMOUNT is
   the focal point, everything else stays quiet. */
.prize-card {
  background: linear-gradient(155deg, color-mix(in srgb, #3730A3 8%, var(--white)), color-mix(in srgb, #3730A3 3%, var(--white)));
  border: 1px solid color-mix(in srgb, #3730A3 22%, var(--white));
  border-radius: 14px;
  box-shadow: 0 4px 14px -10px rgba(55, 48, 163, 0.35);
  padding: 16px 18px;
  min-width: 176px;
}
.pp-head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: color-mix(in srgb, #3730A3 72%, var(--ink-soft));
}
.pp-trophy { width: 13px; height: 13px; flex-shrink: 0; display: inline-flex; color: #3730A3; }
.pp-trophy svg { width: 100%; height: 100%; display: block; }
.pp-amount {
  font-family: var(--font-display);
  font-size: 27px;
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.05;
  color: #111111;
  margin: 8px 0 0;
}
.pp-rows {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin-top: 12px;
  padding-top: 11px;
  border-top: 1px solid color-mix(in srgb, #3730A3 14%, transparent);
}
.pp-row { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.pp-row-label { font-size: 12px; font-weight: 500; color: var(--ink-soft); }
.pp-row-value { font-size: 13px; font-weight: 700; color: #111111; font-variant-numeric: tabular-nums; }
.tourn-hero-light .draw-hero-name.tourn-name-lg {
  font-family: var(--font);
  font-weight: 900;
  font-size: 28px;          /* the clear visual hero */
  letter-spacing: -0.015em;
  line-height: 1.14;
  color: #111111;           /* stronger black */
  margin: 2px 0 4px;
}
/* All hero meta (sport, date, venue, organiser) in the same muted grey as the
   list card — only the name stays black. */
.tourn-hero-light .dhi-ic { color: var(--ink-soft); }
.tourn-hero-light .dhi-val {
  color: var(--ink-soft);
  font-weight: 500;
  font-size: 12.5px;
  white-space: normal;      /* let "(open maps)" sit beside the venue */
}
.tourn-hero-light .dhi-place { color: var(--ink-soft); font-weight: 500; }
/* Mobile number and "(open maps)" match the rest of the meta — muted grey,
   no orange. They only underline on hover to show they're tappable. */
.tourn-hero-light .dhi-maps { color: var(--ink-soft); font-weight: 500; text-decoration: none; white-space: nowrap; }
.tourn-hero-light .dhi-maps:hover { text-decoration: underline; }
.tourn-hero-light .dhi-tel { color: var(--ink-soft); font-weight: 500; text-decoration: none; }
.tourn-hero-light .dhi-tel:hover { text-decoration: underline; }
.tourn-hero-light .tourn-menu-btn:hover { background: color-mix(in srgb, var(--ink) 12%, var(--white)) !important; }

/* Quick-info strip stays readable on small screens. */
@media (max-width: 560px) {
  .tqi-item { min-width: calc(33.333% - 7px); flex-basis: calc(33.333% - 7px); }
}

/* Category status badge on its own row, under name + format. */
.draw-cat-badges { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }

/* A touch more breathing room inside category cards + gentle hover lift. */
.draw-row { padding: 16px !important; transition: transform 0.18s ease, box-shadow 0.18s ease; }
.draw-row:hover { transform: translateY(-2px); }

/* Section rhythm: let the major blocks breathe a little more. */
.tourn-quickinfo { padding: 0 16px 8px; border-bottom: none; justify-content: center; }
.tourn-quickinfo + div[style*="padding:16px"] { padding-top: 20px !important; }
.tournament-poster { margin-top: 26px; }

/* Registration Open badge: a subtle, slow pulse (respecting reduced-motion). */
.tsb-registering { animation: tsb-pulse 2.6s ease-in-out infinite; }
@keyframes tsb-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(63, 135, 83, 0.45); }
  50% { box-shadow: 0 0 0 6px rgba(63, 135, 83, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .tsb-registering { animation: none; }
  .tqi-item, .draw-row, .tqi-item:hover, .draw-row:hover { transition: none; transform: none; }
}

/* Typography: firmer section headings, softer secondary text. */
.section-label span { font-weight: 800; letter-spacing: 0.6px; }

/* Desktop-only hero watermark: faint racquet-sport silhouettes that sit behind
   the content and never compete with it. Hidden on mobile. */
.tourn-hero { isolation: isolate; }
.tourn-hero-watermark { display: none; }
@media (min-width: 760px) {
  .tourn-hero-watermark {
    display: block;
    position: absolute;
    inset: 0;
    z-index: -1;
    overflow: hidden;
    pointer-events: none;
  }
  .thw { position: absolute; color: #fff; opacity: 0.06; }
  .thw svg { width: 100%; height: 100%; display: block; }
  .thw1 { width: 150px; height: 150px; top: -14px; right: 150px; transform: rotate(18deg); }
  .thw2 { width: 120px; height: 120px; bottom: -26px; right: 40px; transform: rotate(-12deg); }
  .thw3 { width: 130px; height: 130px; top: 30px; right: -18px; transform: rotate(24deg); }
}

/* Labels: condensed display font (Oswald), warm gold. Values: Inter, bold
   white. Two distinct font + colour treatments so the two columns read apart. */
.dhi-label { flex: 0 0 108px; font-family: var(--font-display); font-size: 12px; font-weight: 600; letter-spacing: 0.9px; text-transform: uppercase; color: #F0CE8E; }
.dhi-val { flex: 1; min-width: 0; font-family: var(--font); font-size: 13.5px; font-weight: 700; color: var(--white); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dhi-tel { color: var(--chalk); text-decoration: underline; text-underline-offset: 2px; }
@media (max-width: 380px) {
  .dhi-label { flex-basis: auto; }
}

.search-input-wrap { position: relative; }
.search-input-icon {
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  width: 14px;
  height: 14px;
  color: var(--ink-soft);
  display: inline-flex;
  pointer-events: none;
}
.search-input-icon svg { width: 100%; height: 100%; }

.player-pick-list {
  max-height: 220px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.player-pick-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 4px;
  border-bottom: 1px solid var(--line);
  font-size: 13px;
  color: var(--ink);
  cursor: pointer;
}
.player-pick-row:last-child { border-bottom: none; }
.player-pick-row input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--clay);
  flex-shrink: 0;
}
/* Shown once the picker has as many boxes checked as there's room left in
   the category's max-players cap — the remaining, unchecked rows go dim
   and unclickable instead of letting someone keep selecting past the cap. */
.player-pick-row-disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.winner-banner {
  text-align: center;
  padding: 20px;
  background: rgba(217, 232, 78, 0.15);
  border-radius: 14px;
  margin-top: 6px;
}

.winner-banner .icon { width: 26px; height: 26px; color: var(--clay-dark); margin: 0 auto 6px; }
.winner-banner .wtext { font-weight: 700; font-size: 15px; color: var(--ink); }

/* ── Draw format picker (organiser inline section) ───────────────────────── */

.draw-format-card {
  border: 2px solid var(--clay);
  margin-bottom: 16px;
}

.draw-format-card__header {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: 14px;
}

.draw-format-card__label {
  font-weight: 700;
  font-size: 12.5px;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.draw-format-card__sub {
  font-size: 11.5px;
  color: var(--ink-soft);
}

.draw-format-options {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.draw-format-opt {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: 14px 10px;
  /* Same 1px --line border as every input field, for consistency. */
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--white);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
  text-align: center;
}

.draw-format-opt:active { transform: scale(0.97); }

.draw-format-opt__title {
  font-weight: 700;
  font-size: 14px;
  color: var(--ink);
}

.draw-format-opt__desc {
  font-size: 11.5px;
  color: var(--ink-soft);
}

.draw-format-opt--active {
  border-color: var(--clay);
  background: rgba(210, 98, 46, 0.08);
}

.draw-format-opt--active .draw-format-opt__title { color: var(--clay); }
.draw-format-opt--active .draw-format-opt__desc  { color: var(--clay); opacity: 0.75; }

/* ── Rivalry summary card ─────────────────────────────────────────────────── */

/* Default "Your top rivalries" list (shown before an opponent is picked). */
.rivalry-top-title { font-family: var(--font-display); font-weight: 700; font-size: 13px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); margin: 2px 0 10px; }
.rivalry-top-list { display: flex; flex-direction: column; gap: 8px; }
.rivalry-top-row { display: flex; align-items: center; gap: 11px; width: 100%; text-align: left; cursor: pointer; padding: 11px 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--white); transition: transform .12s ease, box-shadow .2s ease, border-color .2s ease; }
.rivalry-top-row:hover { transform: translateY(-1px); box-shadow: 0 5px 14px -8px rgba(0,0,0,.3); border-color: color-mix(in srgb, var(--clay) 40%, var(--line)); }
.rivalry-top-icon { font-size: 18px; line-height: 1; flex-shrink: 0; }
.rivalry-top-info { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.rivalry-top-name { font-weight: 700; font-size: 14px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rivalry-top-rec { font-size: 12px; color: var(--ink-soft); margin-top: 1px; }
.rivalry-top-count { flex-shrink: 0; font-size: 11.5px; color: var(--ink-soft); }
.rivalry-top-count strong { font-family: var(--font-display); font-size: 16px; color: var(--clay); margin-right: 3px; }

.rivalry-summary-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 4px;
  text-align: center;
}
.rivalry-summary-vs {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: 14px;
}
.rivalry-vs-dot {
  color: var(--ink-soft);
  font-weight: 400;
  margin: 0 4px;
}
.rivalry-summary-stats {
  display: flex;
  justify-content: space-around;
  gap: 0;
  margin-bottom: 10px;
}
.rivalry-summary-col {
  flex: 1;
  padding: 8px 0;
}
.rivalry-summary-num {
  font-size: 30px;
  font-weight: 800;
  line-height: 1;
  color: var(--ink);
}
.rivalry-summary-lbl {
  font-size: 11px;
  color: var(--ink-soft);
  margin-top: 3px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.rivalry-summary-sub {
  font-size: 12px;
  color: var(--ink-soft);
}

/* ── Forecast a Match ────────────────────────────────────────────────────── */

.fc-ai-badge {
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  background: linear-gradient(135deg, var(--clay), var(--ball));
  color: #fff;
  border-radius: 4px;
  padding: 2px 5px;
}

.fc-grid {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

@media (min-width: 620px) {
  .fc-grid { flex-direction: row; align-items: flex-start; }
  .fc-form-panel { flex: 0 0 220px; }
  .fc-result-panel { flex: 1; min-width: 0; }
}

.fc-panel {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px;
}

.fc-panel-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: 14px;
}

/* Match type toggle */
.fc-type-toggle {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 2px;
}
.fc-type-btn {
  flex: 1;
  padding: 7px 4px;
  font-size: 11px;
  font-weight: 600;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
  white-space: nowrap;
}
.fc-type-btn.active {
  background: var(--clay);
  color: #fff;
  border-color: var(--clay);
}

/* Team blocks — doubles / mixed doubles player selection */
.fc-team-block {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 8px 10px 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--surface);
}
.fc-team-block-label {
  font-size: 10.5px;
  font-weight: 700;
  color: var(--clay);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* Side-by-side avatars for doubles teams in VS row */
.fc-vs-duo-avatars {
  display: flex;
  gap: 4px;
  justify-content: center;
  margin-bottom: 2px;
}

/* Stacks the form fields with consistent vertical spacing */
.fc-fields {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* ── Searchable player combobox (ps = player search) ── */
.ps-wrap { position: relative; }

.ps-trigger {
  display: flex; align-items: center; gap: 8px;
  width: 100%; text-align: left; cursor: pointer;
  padding: 8px 10px; border-radius: var(--radius-sm);
  border: 1px solid var(--line); background: var(--white);
  font-size: 14px; font-family: inherit; color: var(--ink);
  min-height: 42px; transition: border-color 0.15s;
}
.ps-trigger:hover { border-color: var(--clay); }
.ps-trigger:focus { outline: none; border-color: var(--clay); }

.ps-caret { margin-left: auto; width: 16px; height: 16px; color: var(--ink-soft); flex-shrink: 0; }

.ps-placeholder { color: var(--ink-soft); }

.ps-popup {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0;
  z-index: 400; background: var(--white);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  box-shadow: 0 6px 24px rgba(0,0,0,0.14);
}
.ps-popup.hidden { display: none; }

.ps-search-row {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; border-bottom: 1px solid var(--line);
}
.ps-search-icon { width: 14px; height: 14px; color: var(--ink-soft); flex-shrink: 0; }
.ps-input {
  flex: 1; border: none; background: transparent;
  font-size: 13px; color: var(--ink); outline: none; font-family: inherit;
}

.ps-list {
  list-style: none; margin: 0; padding: 4px 0;
  max-height: 200px; overflow-y: auto;
}
.ps-item {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; cursor: pointer; font-size: 13px;
}
.ps-item:hover { background: color-mix(in srgb, var(--clay) 6%, transparent); }
.ps-item.selected { background: color-mix(in srgb, var(--clay) 10%, transparent); }
.ps-item.hidden { display: none !important; }
.ps-clear-item { opacity: 0.6; }
.ps-empty {
  padding: 10px; text-align: center;
  color: var(--ink-soft); font-size: 12px;
}
/* ──────────────────────────────────────────────────── */

.fc-disclaimer {
  font-size: 10.5px;
  color: var(--ink-soft);
  text-align: center;
  margin: 0;
  line-height: 1.45;
}

/* Result panel */
.fc-result-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
.fc-conf-pill {
  font-size: 10.5px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 100px;
}

/* VS row */
.fc-vs-row {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin-bottom: 14px;
}
.fc-vs-player {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  text-align: center;
  padding: 10px 4px;
  border-radius: var(--radius);
  border: 1px solid transparent;
  min-width: 0;
}
.fc-vs-player.fc-vs-winner {
  border-color: var(--clay);
  background: color-mix(in srgb, var(--clay) 6%, transparent);
}
.fc-vs-name {
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
  word-break: break-word;
}
.fc-vs-rating { font-size: 11px; color: var(--ink-soft); }
.fc-winner-chip {
  font-size: 9px;
  font-weight: 700;
  background: var(--clay);
  color: #fff;
  border-radius: 100px;
  padding: 2px 7px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.fc-vs-mid {
  display: flex;
  align-items: center;
  padding-top: 30px;
  flex-shrink: 0;
}
.fc-vs-dot {
  font-size: 10px;
  font-weight: 700;
  color: var(--ink-soft);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 50%;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Probability bar */
.fc-prob-section { margin-bottom: 12px; }
.fc-prob-labels {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 6px;
}
.fc-prob-track {
  height: 8px;
  background: var(--line);
  border-radius: 100px;
  overflow: hidden;
  margin-bottom: 4px;
}
.fc-prob-fill {
  height: 100%;
  border-radius: 100px;
  transition: width 0.55s cubic-bezier(0.4, 0, 0.2, 1);
}
.fc-prob-names {
  display: flex;
  justify-content: space-between;
  font-size: 10.5px;
  color: var(--ink-soft);
}

/* Cards inside result */
.fc-section-card {
  background: var(--surface);
  border-radius: var(--radius);
  padding: 12px;
  margin-bottom: 10px;
}
.fc-section-card:last-child { margin-bottom: 0; }
.fc-section-card-title {
  font-size: 10.5px;
  font-weight: 700;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 8px;
}
.fc-scoreline-card { text-align: center; }
.fc-scoreline-val { font-size: 22px; font-weight: 800; color: var(--ink); margin-bottom: 3px; }
.fc-scoreline-sub { font-size: 11.5px; color: var(--ink-soft); }

/* Key factors */
.fc-factors-list { display: flex; flex-direction: column; }
.fc-factor-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 0;
  border-bottom: 1px solid var(--line);
  font-size: 12px;
}
.fc-factor-row:last-child { border-bottom: none; }
.fc-factor-label { color: var(--ink-soft); }
.fc-factor-pct { color: var(--grass); font-weight: 700; }
.fc-factor-warn .fc-factor-label { color: var(--ball); font-style: italic; }

/* Factor Analysis breakdown table */
.fc-breakdown {
  display: flex;
  flex-direction: column;
}
.fc-breakdown-head {
  display: grid;
  grid-template-columns: 1fr 72px 72px;
  padding: 5px 0 6px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 1px;
}
.fc-breakdown-head span {
  font-size: 10.5px;
  font-weight: 700;
  color: var(--clay);
  text-align: center;
}
.fc-breakdown-head span:first-child { text-align: left; color: transparent; }
.fc-breakdown-row {
  display: grid;
  grid-template-columns: 1fr 72px 72px;
  padding: 5px 0;
  border-bottom: 1px solid var(--line);
  align-items: center;
}
.fc-breakdown-row:last-child { border-bottom: none; }
.fc-bd-lbl {
  font-size: 11.5px;
  color: var(--ink-soft);
  padding-right: 6px;
}
.fc-bd-val {
  font-size: 11.5px;
  color: var(--ink-soft);
  text-align: center;
  font-weight: 500;
}
.fc-bd-val.fc-edge {
  color: var(--clay);
  font-weight: 700;
}

/* H2H */
.fc-h2h-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.fc-h2h-col { flex: 1; }
.fc-h2h-col.right { text-align: right; }
.fc-h2h-wins { font-size: 26px; font-weight: 800; color: var(--ink); line-height: 1; }
.fc-h2h-name { font-size: 11px; color: var(--ink-soft); margin-top: 2px; }
.fc-h2h-col.fc-h2h-lead .fc-h2h-wins { color: var(--clay); }
.fc-h2h-total { font-size: 11px; color: var(--ink-soft); text-align: center; flex-shrink: 0; }

/* Form meta row */
.fc-form-meta {
  margin-top: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 11.5px;
  color: var(--ink-soft);
}
.fc-form-meta-lbl { font-weight: 600; }

/* Empty state */
.fc-result-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 160px;
  color: var(--ink-soft);
}
.fc-empty-icon { font-size: 26px; opacity: 0.4; }
.fc-empty-text { font-size: 13px; text-align: center; line-height: 1.45; }

/* ── Round Robin group-stage styles ──────────────────────────────────────── */

/* Horizontal scrolling row of group cards — stacks to one-column on narrow
   viewports, scrolls horizontally on wider ones. */
/* Responsive grid — 1 group on narrow screens, as many across as fit on
   wider ones, so 3/4/5 groups all stay on screen and aligned. */
.rr-groups-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 14px;
  align-items: stretch;
}

.rr-group-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  min-width: 0;
  height: 100%;
  box-shadow: 0 1px 3px rgba(22, 36, 26, 0.05);
}

/* Neutral header — no coloured banner. */
.rr-group-header {
  color: var(--ink);
  font-weight: 800;
  font-size: 12.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 8px 12px;
  background: color-mix(in srgb, var(--ink) 3%, var(--white));
  border-bottom: 1px solid var(--line);
}

/* Standings table inside each group card */
/* Fixed layout + explicit column widths so every group's table is identical
   and the numeric columns line up (and the "+/−" header never wraps). The
   Player column (2nd) is left unsized, so it absorbs the remaining width. */
.rr-standings-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
  table-layout: fixed;
}
.rr-standings-table th {
  color: var(--ink-soft);
  font-weight: 600;
  text-align: left;
  padding: 5px 6px;
  border-bottom: 1px solid var(--line);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
.rr-standings-table th:not(.rr-player) { text-align: center; }
.rr-standings-table td {
  padding: 6px 6px;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
}
/* Numeric columns (W / L / GW / +/−) in quiet grey — the name is the star. */
.rr-standings-table td:not(.rr-player) { color: var(--ink-soft); font-weight: 500; }
.rr-standings-table td:not(.rr-player) { text-align: center; }
.rr-standings-table tbody tr:last-child td { border-bottom: none; padding-bottom: 14px; }
.rr-standings-table tr > :nth-child(1) { width: 22px; }  /* #  */
.rr-standings-table tr > :nth-child(3) { width: 28px; }  /* W  */
.rr-standings-table tr > :nth-child(4) { width: 28px; }  /* L  */
.rr-standings-table tr > :nth-child(5) { width: 36px; }  /* GW */
.rr-standings-table tr > :nth-child(6) { width: 42px; }  /* +/-*/
.rr-standings-table .rr-rank { color: var(--ink-soft); }
.rr-standings-table td.rr-player { white-space: normal; line-height: 1.25; color: var(--ink-soft); font-weight: 600; }
.rr-standing-row:nth-child(even) { background: rgba(22, 36, 26, 0.02); }

/* Advancing players: clear green tint, left accent bar, bold, and a green
   "advances" pill next to the name. */
.rr-standing-row.rr-advancing {
  background: rgba(63, 135, 83, 0.07);
  box-shadow: inset 3px 0 0 #7FC79C;
}
.rr-standing-row.rr-advancing td { font-weight: 600; }
.rr-standing-row.rr-advancing .rr-rank { color: var(--grass); }
.rr-adv-pill {
  display: inline-block;
  margin-left: 5px;
  color: #fff;
  background: var(--grass);
  font-size: 8.5px;
  font-weight: 800;
  line-height: 1;
  padding: 2px 4px;
  border-radius: 5px;
  vertical-align: 1px;
}

/* Sequentially-numbered match results (Match 1, Match 2, …), left-aligned */
.rr-matches {
  padding: 2px 0 4px;
}
.rr-match {
  padding: 6px 10px;
  border-top: 1px solid var(--line);
  position: relative; /* anchors the Completed chip to the box */
}
.rr-match:first-child { border-top: none; }
.rr-match-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  /* ~1.2× the previous overall gap between "MATCH n" and the first name. */
  margin-bottom: 7px;
}
.rr-match-num {
  flex-shrink: 0;
  font-size: 9px;
  font-weight: 800;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.rr-match-score {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-soft);
  white-space: nowrap;
}
/* Same winner/loser language as the knockout bracket: green + tick for the
   winner, grey for the loser, one consistent readable size. */
.rr-match-players {
  /* inline-block shrinks the container to the WIDTH OF THE NAMES, so the
     centred "vs" sits directly between them (not out in the middle of the
     card, miles from short left-aligned names). */
  display: inline-block;
  font-size: 14px;
  font-weight: 600;
  /* Names in the same quiet grey as the scores; once a match is confirmed
     the WINNER flips to light green (rule below). */
  color: var(--ink-soft);
}
.rr-name { display: block; min-width: 0; line-height: 1.35; }
.rr-name.rr-winner { font-weight: 800; color: #7FC79C; }
.rr-name.rr-loser { font-weight: 600; color: var(--ink-soft); }
.rr-win-tick { width: 13px; height: 13px; flex-shrink: 0; display: inline-flex; color: #7FC79C; }
.rr-win-tick svg { width: 100%; height: 100%; }
.rr-vs { display: block; width: 100%; text-align: center; color: var(--ink-soft); font-size: 11px; font-weight: 700; letter-spacing: 0.04em; margin: 4px 0; line-height: 1; }
.rr-matches { padding-bottom: 14px; }
/* "Completed" chip — pinned right, level with the SECOND player's name (no
   extra row of its own, keeps the match box compact). */
.rr-match-done { position: absolute; right: 10px; bottom: 8px; padding: 3px 9px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--white); font-size: 10.5px; font-weight: 700; letter-spacing: 0.03em; color: var(--ink-soft); }
.rr-score {
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-soft);
  white-space: nowrap;
}
/* Full-width "Enter score" button below a pending match */
.rr-enter-score-btn {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 5px 8px;
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--ink-soft);
  border-radius: var(--radius-sm);
  font-size: 11px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.12s ease;
}
.rr-enter-score-btn:hover { background: color-mix(in srgb, var(--ink) 5%, var(--white)); }
.rr-match-pending {
  margin-top: 4px;
  font-size: 10.5px;
  color: var(--ink-soft);
  font-style: italic;
}
/* Small pencil button next to an entered score — reopens the score modal in
   edit mode to correct a wrong entry (standings recompute on save). */
.rr-edit-btn {
  border: none;
  background: none;
  cursor: pointer;
  padding: 2px;
  margin-left: 2px;
  color: var(--ink-soft);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  vertical-align: middle;
}
.rr-edit-btn svg { width: 12px; height: 12px; }
.rr-edit-btn:hover { color: var(--clay); background: rgba(210, 98, 46, 0.10); }

/* Games-won column + game-difference column — the visible tiebreakers among
   equal-win players. */
.rr-standings-table td.rr-gw { font-weight: 500; color: var(--ink-soft); }
.rr-standings-table td.rr-diff { font-weight: 500; color: var(--ink-soft); white-space: nowrap; }
/* Small "H2H" tag on rows that were level on every number and split only by
   their head-to-head result. */
.rr-h2h-tag {
  display: inline-block;
  margin-left: 4px;
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.03em;
  color: var(--grass);
  border: 1px solid var(--grass);
  border-radius: 4px;
  padding: 1px 3px;
  vertical-align: 1px;
}
/* One-line ranking legend above the groups */
.rr-legend {
  font-size: 11.5px;
  color: var(--ink-soft);
  margin: 0 0 10px;
}
.rr-legend strong { color: var(--ink); font-weight: 700; }

/* Champion row in a crowned round-robin final */
.rr-champion-row { background: rgba(210, 98, 46, 0.10); }
.rr-champion-row td { font-weight: 700; }
.rr-champ-badge {
  display: inline-flex;
  width: 13px;
  height: 13px;
  color: var(--clay);
  vertical-align: -2px;
}
.rr-champ-badge svg { width: 100%; height: 100%; }

/* Small "Results" caption above each group's match list */
/* "Results" caption doubles as a click target to hide/expand the match list. */
.rr-matches-label {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  padding: 8px 10px 6px;
  border-top: 1px solid var(--line);
  cursor: pointer;
  user-select: none;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.rr-matches-label::-webkit-details-marker { display: none; }
.rr-matches-label:hover { color: var(--ink); }
.rr-matches-chev {
  width: 13px;
  height: 13px;
  display: inline-flex;
  flex-shrink: 0;
  transition: transform 0.2s ease;
}
.rr-matches-chev svg { width: 100%; height: 100%; }
.rr-matches-collapse[open] .rr-matches-chev { transform: rotate(180deg); }

/* Collapsible "Group Stage — Final Standings" summary shown above the bracket
   once the draw has advanced. */
.rr-results-details {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  margin-bottom: 16px;
  overflow: hidden;
}
.rr-results-summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 14px;
  font-weight: 700;
  font-size: 13.5px;
  color: var(--ink);
  user-select: none;
}
.rr-results-summary::-webkit-details-marker { display: none; }
.rr-results-icon { width: 16px; height: 16px; color: var(--clay); flex-shrink: 0; display: inline-flex; }
.rr-results-icon svg, .rr-results-chev svg { width: 100%; height: 100%; }
.rr-results-chev {
  width: 16px; height: 16px; margin-left: auto; color: var(--ink-soft);
  flex-shrink: 0; display: inline-flex; transition: transform 0.2s ease;
}
.rr-results-details[open] .rr-results-chev { transform: rotate(180deg); }
.rr-results-note {
  font-size: 11.5px;
  color: var(--ink-soft);
  padding: 0 14px 10px;
}
.rr-results-details .rr-groups-row { padding: 0 14px 14px; }
.rr-results-details .rr-legend { padding: 10px 14px 0; margin-bottom: 8px; }

/* ── end Round Robin styles ───────────────────────────────────────────────── */

.back-link {
  background: transparent;
  border: none;
  color: rgba(250, 246, 239, 0.7);
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  cursor: pointer;
  margin-bottom: 10px;
  padding: 0;
}

.profile-header { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 16px; }
/* One uniform 8px gap between every row (name / meta / badges / meta-row) —
   the rows' own margins are zeroed below so nothing fights this rhythm. */
.profile-header-info { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 8px; padding-top: 2px; }
.profile-header-info .profile-summary { margin: 0; }
.profile-header-info .profile-meta-row { margin-top: 0; }
/* Phones: the Share button drops below the avatar + text as a full-width
   action instead of squeezing the name column. */
@media (max-width: 520px) {
  .profile-header { flex-wrap: wrap; }
  .player-share-card-btn-light { width: 100%; justify-content: center; }
}
/* Name + edit icon on one properly centred row (no baseline hacks). */
.profile-name { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 19px; line-height: 1.2; color: var(--ink); }
.profile-edit-btn {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 32px; height: 32px;
  border: 1px solid color-mix(in srgb, var(--clay) 32%, var(--line)); border-radius: 10px;
  background: color-mix(in srgb, var(--clay) 6%, var(--white)); cursor: pointer; color: var(--clay-dark);
}
.profile-edit-btn svg { width: 17px; height: 17px; }
.profile-edit-btn:hover { background: color-mix(in srgb, var(--clay) 12%, var(--white)); border-color: var(--clay-light); }
.edit-profile-form { display: flex; flex-direction: column; gap: 12px; }
.profile-meta { font-size: 12.5px; color: var(--ink-soft); }

/* About me — highlighted card below the name, with an inline edit pencil. */
.profile-bio-inline {
  margin: 0 0 16px;
  padding: 11px 14px;
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--clay) 7%, var(--white));
  border: 1px solid color-mix(in srgb, var(--clay) 22%, transparent);
  border-left: 3px solid var(--clay);
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink);
  white-space: pre-wrap;
  word-break: break-word;
}
.bio-edit-btn {
  display: inline-flex; align-items: center; justify-content: center;
  vertical-align: -2px; margin-left: 4px; padding: 2px;
  border: none; background: none; cursor: pointer; color: var(--clay-dark);
}
.bio-edit-btn:hover { color: var(--clay); }
.bio-add-btn {
  display: inline-flex; align-items: center; gap: 6px;
  margin: 2px 0 16px; padding: 8px 13px;
  border: 1px dashed color-mix(in srgb, var(--clay) 45%, transparent);
  border-radius: var(--radius-md); background: none; cursor: pointer;
  font-family: var(--font); font-size: 12.5px; font-weight: 600; color: var(--clay-dark);
}
.bio-add-btn:hover { background: color-mix(in srgb, var(--clay) 6%, var(--white)); }
/* Player-detail bio sits in the dark header, so it uses light text. */
.player-detail-bio {
  margin-top: 9px;
  font-size: 12.5px;
  line-height: 1.5;
  color: rgba(250, 246, 239, 0.85);
  max-width: 680px;
  white-space: pre-wrap;
  word-break: break-word;
}

/* Player "About" bio card shown on a player's Overview */
.player-bio-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--clay);
  border-radius: var(--radius);
  padding: 12px 14px;
  margin-bottom: 14px;
}
.player-bio-label {
  font-size: 10.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--clay);
  margin-bottom: 5px;
}
.player-bio-text {
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink);
  white-space: pre-wrap;
  word-break: break-word;
}

.error-banner {
  background: var(--danger);
  color: var(--white);
  font-size: 12px;
  padding: 8px 16px;
  text-align: center;
}

.toast-root {
  position: fixed;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 999;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  pointer-events: none;
}

.toast {
  background: var(--ink);
  color: var(--chalk);
  font-size: 13px;
  font-weight: 600;
  padding: 10px 18px;
  border-radius: 30px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
  animation: toast-in 0.2s ease;
}

.toast.error { background: var(--danger); }

@keyframes toast-in {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: translateY(0); }
}

.loading-screen {
  min-height: 100vh;
  background: var(--ink);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  color: var(--chalk);
  font-family: var(--font-display);
  font-size: 15px;
  letter-spacing: 0.3px;
}

.loading-spinner {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 3px solid rgba(228, 242, 61, 0.18);
  border-top-color: var(--ball);
  animation: loading-spin 0.8s linear infinite;
}

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

/* Quick crossfade applied to #view-root every time a tab/view re-renders —
   keeps tab switches from feeling like an abrupt content swap, without
   adding any real delay (the animation runs while the new markup is
   already in place). */
.view-fade-in {
  animation: view-fade-in 0.18s ease;
}

/* Opacity only. The old translateY(4px) rise made every tab switch look like
   the page was sliding, which combined with the tab-bar reflow read as things
   moving around at random. A clean cross-fade is calmer and just as clear. */
@keyframes view-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (max-width: 380px) {
  .scorecard-team { min-width: 70px; }
  .scorecard-score { font-size: 17px; }
}

/* ============================================================
   MANUAL DRAW — automatic/manual toggle + group assignment screen
   Indigo 800 marks the CURRENT selection (same identity it carries
   on tabs and the current bracket round); green stays the action
   colour, on the Generate button only.
============================================================ */

.drawmode-toggle {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.drawmode-opt {
  display: flex;
  flex-direction: column;
  gap: 3px;
  text-align: left;
  padding: 10px 11px;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--white);
  cursor: pointer;
  transition: border-color .15s, background .15s;
}

.drawmode-opt:hover { border-color: #A5B4FC; }

.drawmode-opt--active {
  border-color: #3730A3;
  background: color-mix(in srgb, #3730A3 6%, var(--white));
}

.drawmode-opt__title { font-size: 13px; font-weight: 700; color: var(--ink); }
.drawmode-opt--active .drawmode-opt__title { color: #3730A3; }
.drawmode-opt__desc { font-size: 11px; line-height: 1.35; color: var(--ink-soft); }

/* ---- the assignment screen ---- */

.mdraw-sheet { max-height: 92vh; }

.mdraw { display: flex; flex-direction: column; gap: 16px; }
#md-content { display: flex; flex-direction: column; gap: 16px; }

.mdraw-summary {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 12px;
}

.mdraw-summary__title { font-size: 13px; font-weight: 700; color: var(--ink); margin-bottom: 8px; }

.mdraw-balrow { display: flex; flex-wrap: wrap; gap: 8px; }

.mdraw-bal {
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: 4px 8px;
  border-radius: 999px;
  background: var(--white);
  border: 1px solid var(--line);
  font-size: 12px;
}

.mdraw-bal--head { background: transparent; border-color: transparent; color: var(--ink-soft); font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; }
.mdraw-bal__g { font-weight: 700; color: #3730A3; }
.mdraw-bal--head .mdraw-bal__g { color: var(--ink-soft); }
.mdraw-bal__n { font-weight: 700; color: var(--ink); }
.mdraw-bal--head .mdraw-bal__n { color: var(--ink-soft); font-weight: 600; }
.mdraw-bal__r { color: #96775A; font-variant-numeric: tabular-nums; }
.mdraw-bal--head .mdraw-bal__r { color: var(--ink-soft); }

.mdraw-warn {
  margin-top: 8px;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--ink-soft);
  padding-left: 10px;
  border-left: 2px solid #E0BE7A;
}

.mdraw-groupcount {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-soft);
}

.mdraw-gc-btns { display: flex; align-items: center; gap: 12px; }
.mdraw-gc-btns strong { font-size: 15px; color: var(--ink); min-width: 18px; text-align: center; }

.mdraw-gc {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  border: 1.5px solid var(--line);
  background: var(--white);
  color: var(--ink);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
}

.mdraw-gc:disabled { opacity: .35; cursor: default; }

.mdraw-unassigned {
  border: 1.5px dashed var(--clay);
  border-radius: var(--radius-sm);
  padding: 10px;
  background: color-mix(in srgb, var(--clay) 4%, var(--white));
}

.mdraw-unassigned__head {
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--clay-dark);
  margin-bottom: 8px;
}

.mdraw-group {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 10px;
  background: var(--white);
}

.mdraw-group__head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }

.mdraw-group__badge {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  border-radius: 7px;
  background: #3730A3;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mdraw-group__name {
  flex: 1 1 auto;
  min-width: 0;
  border: none;
  border-bottom: 1px dashed var(--line);
  background: transparent;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
  padding: 2px 0;
}

.mdraw-group__name:focus { outline: none; border-bottom-color: #3730A3; }
.mdraw-group__meta { flex: 0 0 auto; font-size: 11.5px; color: var(--ink-soft); }

.mdraw-empty { font-size: 11.5px; color: var(--ink-soft); padding: 8px 2px; font-style: italic; }

.mdraw-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 5px 0;
  border-top: 1px solid var(--line);
}

.mdraw-row:first-of-type { border-top: none; }
.mdraw-row__who { display: flex; align-items: center; gap: 8px; min-width: 0; flex: 1 1 auto; }
.mdraw-row__text { display: flex; flex-direction: column; min-width: 0; }
.mdraw-row__name { font-size: 12.5px; font-weight: 600; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mdraw-row__rating { font-size: 10.5px; color: #96775A; font-variant-numeric: tabular-nums; }

.mdraw-chips { display: flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end; flex: 0 0 auto; }

.mdraw-chip {
  min-width: 26px;
  height: 26px;
  padding: 0 5px;
  border-radius: 7px;
  border: 1.5px solid var(--line);
  background: var(--white);
  color: var(--ink-soft);
  font-size: 11.5px;
  font-weight: 700;
  cursor: pointer;
  transition: border-color .12s, background .12s, color .12s;
}

.mdraw-chip:hover { border-color: #A5B4FC; color: var(--ink); }

.mdraw-chip--on {
  background: #3730A3;
  border-color: #3730A3;
  color: #fff;
}

.mdraw-actions { display: flex; flex-direction: column; gap: 8px; padding-top: 4px; }

/* A one-entrant group: shown as an explicit bye rather than as an unbeaten
   player with no record. Neutral grey — a bye is neither a win nor a loss. */
.rr-bye-chip {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .03em;
  vertical-align: middle;
}

.rr-bye-chip--onhead {
  background: rgba(255, 255, 255, .22);
  border-color: rgba(255, 255, 255, .4);
  color: #fff;
}

.rr-row-bye td { color: var(--ink-soft); }

/* ============================================================
   PAYMENT DASHBOARD (organiser only)
   Colour lives ONLY on the four numbers: green = paid count and
   money received, orange = awaiting your approval, light red =
   still remaining. Tiles and progress bars stay neutral so the
   figures aren't competing with their own containers.
============================================================ */

.pdash-head {
  margin-top: 12px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}

.pdash-total { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; min-width: 0; }
.pdash-total__got { font-size: 27px; font-weight: 800; color: #2E9E5B; line-height: 1.05; letter-spacing: -.01em; }
.pdash-total__of { font-size: 13.5px; font-weight: 600; color: var(--ink-soft); }

.pdash-pct {
  flex-shrink: 0;
  font-size: 13px;
  font-weight: 800;
  color: #2E9E5B;
  background: color-mix(in srgb, #2E9E5B 10%, var(--white));
  border: 1px solid color-mix(in srgb, #2E9E5B 28%, var(--white));
  border-radius: 999px;
  padding: 3px 10px;
}

.pdash-bar {
  position: relative;
  height: 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 8%, var(--white));
  overflow: hidden;
  margin-bottom: 14px;
}

.pdash-bar--sm { height: 6px; margin-bottom: 6px; }

.pdash-bar__fill,
.pdash-bar__claim {
  position: absolute;
  top: 0;
  bottom: 0;
  transition: width .4s ease;
}

/* Bars are deliberately MONOCHROME. All the meaning is carried by the four
   coloured numbers below; a green/orange/red bar on top of coloured numbers
   was saying the same thing twice and made the card noisy. The bar's job here
   is proportion, not status. */
.pdash-bar__fill { left: 0; background: color-mix(in srgb, var(--ink) 55%, var(--white)); border-radius: 999px; }
/* Claimed-but-unconfirmed sits immediately after the confirmed portion,
   striped so it still reads as provisional rather than banked — texture
   instead of hue. */
.pdash-bar__claim {
  background: repeating-linear-gradient(45deg, color-mix(in srgb, var(--ink) 28%, var(--white)) 0 4px, transparent 4px 8px);
}

.pdash-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
/* Four tiles: 2×2 on a phone, one row on anything wider. */
.pdash-stats--4 { grid-template-columns: repeat(2, 1fr); }
@media (min-width: 560px) { .pdash-stats--4 { grid-template-columns: repeat(4, 1fr); } }
/* The "/30" in "5/30" must match the figure it sits inside, or the count tile
   reads at a different size from the three money tiles beside it. `inherit`
   rather than a fixed px so it also tracks the smaller phone size below. */
.pdash-stat__den { font-size: inherit; font-weight: inherit; }

.pdash-stat {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--white);
  min-width: 0;
}

/* min-height, not just line-height: it reserves the height of the tallest
   thing that can sit in this slot (the status pill, ~21px) so every tile's
   LABEL lands on the same line regardless of what's above it. Without it the
   pill tile's label sat several pixels lower than its three neighbours'. */
.pdash-stat__n { font-size: 15px; font-weight: 800; color: var(--ink); line-height: 1.15; min-height: 21px; overflow: hidden; text-overflow: ellipsis; }

/* The status tile holds a pill, not a figure. overflow:hidden clipped the
   pill's rounded top and bottom, and text-overflow does nothing for a
   non-text child — so this slot opts out of both and centres its pill in the
   reserved height instead. */
.pdash-stat__n--pill { overflow: visible; text-overflow: clip; display: flex; align-items: center; }

.pdash-stat__l { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--ink-soft); }
.pdash-stat__s { font-size: 10.5px; color: var(--ink-soft); }

/* Tiles stay plain — same border, same white background, no tint. Colour
   lives ONLY on the number, so the four figures read as a set and the eye
   goes straight to them. */
.pdash-stat--count .pdash-stat__n { color: #2E9E5B; }   /* paid / total   — green  */
.pdash-stat--got   .pdash-stat__n { color: #2E9E5B; }   /* received       — green  */
.pdash-stat--claim .pdash-stat__n { color: #D97A16; }   /* awaiting       — orange */
.pdash-stat--due   .pdash-stat__n { color: #E06A66; }   /* remaining      — light red */
/* The whole "5/30" is green — it's one figure ("paid out of total"), so
   splitting its colour would make it read as two. */

.pdash-cats { margin-top: 16px; display: flex; flex-direction: column; gap: 12px; }

.pdash-cat { padding-top: 12px; border-top: 1px solid var(--line); }
.pdash-cat:first-child { padding-top: 0; border-top: none; }

.pdash-cat__top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
/* That 6px exists to clear the progress bar that follows in the payment
   dashboard. The plan dashboard's rows are a single line with no bar, so the
   margin became dead space BELOW each row on top of the 12px flex gap —
   6px more air under every row than over it. */
.pdash-cat--rows .pdash-cat__top { margin-bottom: 0; }

.pdash-cat__name { font-size: 12.5px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The usage figure and its "Limit reached" flag sit on one line; align-items
   is baseline on the parent, so the pill needs its own gap rather than a
   margin on the flag, or the spacing changes with the pill's font metrics. */
.pdash-cat__amt { font-size: 12.5px; color: var(--ink); flex-shrink: 0; display: inline-flex; align-items: baseline; gap: 6px; }
.pdash-cat__amt strong { color: #2E9E5B; }
/* .pdash-cat__amt--full and .plan-limit-flag lived here. They turned a
   per-category "15 / 15" red at the cap — a cap that no longer exists, now the
   plan counts players across the whole tournament. The one usage figure moved
   to .plan-usage, which carries its own full state. */
.pdash-cat__of { color: var(--ink-soft); font-weight: 600; }
.pdash-cat__meta { font-size: 11px; color: var(--ink-soft); line-height: 1.4; }
.pdash-warnlink { color: var(--clay-dark); font-weight: 600; }

.pdash-note { margin-top: 14px; font-size: 11px; color: var(--ink-soft); line-height: 1.45; }

@media (max-width: 380px) {
  .pdash-stats { grid-template-columns: 1fr; }
  /* The 4-tile row stays 2×2 even on the narrowest phones — four stacked
     tiles would push the category breakdown off the first screen. */
  .pdash-stats--4 { grid-template-columns: repeat(2, 1fr); }
  /* ONE selector for all four tiles. Singling the count tile out here is what
     let its size drift from the money tiles — don't reintroduce it. */
  .pdash-stats--4 .pdash-stat__n { font-size: 14px; }
  .pdash-total__got { font-size: 23px; }
}

/* ============================================================
   MANUAL KNOCKOUT — the hand-built draw sheet
   Select-then-place: indigo marks the current selection, dashed
   slots are open, "Bye" reads as intentional rather than missing.
============================================================ */

.mk-hint { font-size: 11.5px; line-height: 1.45; color: var(--ink-soft); margin-top: 2px; }
.mk-hint strong { color: #3730A3; }

.mk-sheet { display: flex; flex-direction: column; gap: 10px; }

.mk-match { display: flex; align-items: center; gap: 8px; }

.mk-match__no {
  flex: 0 0 auto;
  width: 18px;
  font-size: 10.5px;
  font-weight: 700;
  color: var(--ink-soft);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.mk-match__slots {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  position: relative;
  border-left: 2px solid var(--line);
  padding-left: 9px;
}

.mk-vs {
  position: absolute;
  left: -9px;
  top: 50%;
  transform: translate(-50%, -50%);
  background: var(--chalk);
  font-size: 9px;
  font-weight: 700;
  color: var(--ink-soft);
  padding: 1px 2px;
}

.mk-slot {
  display: flex;
  align-items: center;
  gap: 7px;
  width: 100%;
  min-width: 0;
  padding: 6px 9px;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--white);
  cursor: pointer;
  text-align: left;
  transition: border-color .12s, background .12s;
}

.mk-slot:hover { border-color: #A5B4FC; }

.mk-slot--sel {
  border-color: #3730A3;
  background: color-mix(in srgb, #3730A3 8%, var(--white));
}

.mk-slot--empty {
  border-style: dashed;
  background: transparent;
}

/* While someone is selected, every open slot advertises itself. */
.mk-slot--target {
  border-color: #3730A3;
  border-style: dashed;
  background: color-mix(in srgb, #3730A3 5%, var(--white));
}

.mk-slot__seat {
  flex: 0 0 auto;
  min-width: 16px;
  font-size: 9.5px;
  font-weight: 700;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.mk-slot__name {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mk-slot__rating { flex: 0 0 auto; font-size: 10.5px; color: #96775A; font-variant-numeric: tabular-nums; }
.mk-slot__bye { flex: 1 1 auto; font-size: 11.5px; font-style: italic; color: var(--ink-soft); }
.mk-slot--target .mk-slot__bye { color: #3730A3; font-style: normal; font-weight: 600; }

.mk-tray-row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-width: 0;
  padding: 6px 4px;
  border: none;
  border-top: 1px solid var(--line);
  background: transparent;
  cursor: pointer;
  text-align: left;
}

.mk-tray-row:first-of-type { border-top: none; }
.mk-tray-row--sel { background: color-mix(in srgb, #3730A3 9%, transparent); border-radius: var(--radius-sm); }

/* ============================================================
   ACADEMY / ORGANISER IDENTITY
============================================================ */

.acad-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  margin-bottom: 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--white);
}

.acad-banner--compact { padding: 10px 12px; margin-bottom: 10px; }

.acad-logo {
  flex: 0 0 auto;
  width: 52px;
  height: 52px;
  border-radius: 12px;
  object-fit: cover;
  background: var(--surface);
  border: 1px solid var(--line);
}

.acad-banner--compact .acad-logo { width: 40px; height: 40px; border-radius: 10px; }

.acad-logo--initials {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 17px;
  font-weight: 800;
  color: var(--clay-dark);
  background: color-mix(in srgb, var(--clay) 10%, var(--white));
  border-color: color-mix(in srgb, var(--clay) 25%, var(--white));
}

.acad-banner--compact .acad-logo--initials { font-size: 14px; }

.acad-meta { flex: 1 1 auto; min-width: 0; }
.acad-name { font-size: 15px; font-weight: 800; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acad-banner--compact .acad-name { font-size: 13.5px; }
.acad-venue { font-size: 11.5px; color: var(--ink-soft); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acad-count { font-size: 11px; color: var(--ink-soft); margin-top: 3px; font-weight: 600; }

.acad-upload { display: flex; align-items: center; gap: 12px; }
.acad-upload .acad-logo { width: 56px; height: 56px; }

.acad-back { flex: 0 0 auto; font-size: 11.5px; padding: 6px 10px; white-space: nowrap; }

/* ---- organiser view ---- */

/* Tabs the mode hides. display:none rather than visibility so the remaining
   tabs redistribute across the bar instead of leaving gaps. */
.tab-hidden { display: none !important; }

.orgview-card { margin-bottom: 14px; }
.orgview-title { font-size: 14px; font-weight: 800; color: var(--ink); }
.orgview-sub { font-size: 11.5px; color: var(--ink-soft); line-height: 1.5; margin-top: 4px; }

/* The Ask Kross AI pill is a player-facing tool; organiser view is about the
   event, so it steps out of the way. */
.organiser-view #ask-fab { display: none; }

/* ---- match-day reminder in the bell ----
   Green and quiet on purpose. This lands on the morning someone is about to
   compete, so it reads as a checklist, never as a warning. */
.notif-item--matchday {
  cursor: pointer;
  background: color-mix(in srgb, #2E9E5B 5%, transparent);
  border-radius: var(--radius-sm);
  margin: 0 -6px 4px;
  padding-left: 6px;
  padding-right: 6px;
}

.notif-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; }

.notif-chip {
  font-size: 10.5px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 999px;
  color: var(--clay-dark);
  background: color-mix(in srgb, var(--clay) 9%, var(--white));
  border: 1px solid color-mix(in srgb, var(--clay) 25%, var(--white));
}

.notif-chip--done {
  color: #2E9E5B;
  background: color-mix(in srgb, #2E9E5B 8%, var(--white));
  border-color: color-mix(in srgb, #2E9E5B 25%, var(--white));
}

/* ============================================================
   ATTENDANCE TABLE (organiser)
   A real table: at the desk you're scanning down one column
   (a name, a number) rather than reading rows end to end.
   Alphabetical and stable — the order never reshuffles as
   people check in.
============================================================ */

/* Eight columns can't fit a phone, so the table scrolls BOTH ways inside the
   card. The max-height gives the sticky header a scrollport to stick to (with
   overflow-x alone, overflow-y computes to auto but never scrolls, so
   position:sticky on a th would do nothing) — and it stops a 64-player roster
   from pushing everything else off the page.
   Negative inline margin bleeds the scroller to the card edge; without it the
   cut-off column sat 16px inside the border and read as a rendering bug
   rather than "there's more to the right". */
.att-table-wrap {
  margin: 10px -16px 0;
  padding: 0 16px;
  max-height: 65vh;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

/* PLAYERS OPERATIONS SCROLLS WITH THE PAGE.
   The shared wrapper above is a 65vh box with its own scrollbar. That is fine
   for a short attendance table and wrong for this one: with 298 entrants the
   organiser got a nested scroller — flick the page and it moves, flick again
   two pixels lower and the table moves instead, and the rows below the fold
   are inside a box most people never realise scrolls. One axis for the page,
   and the whole list is simply there.
   Horizontal scrolling is kept, because on a phone eight columns still cannot
   fit; `pan-x pan-y` stops the browser claiming a vertical swipe for the inner
   scroller, which is what made it feel sticky. */
[data-keep-scroll="ops-table"] {
  max-height: none;
  overflow-y: visible;
  overflow-x: auto;
  touch-action: pan-x pan-y;
  overscroll-behavior-x: contain;
}
/* With the box gone, the column headers would scroll away up the page. They
   stick to the app bar instead, so the filters stay reachable at row 250. */
[data-keep-scroll="ops-table"] .op-table thead th {
  position: sticky;
  top: 52px;              /* .app-topbar height */
  z-index: 3;
  background: var(--white);
}

/* separate, not collapse: sticky cells are broken under border-collapse in
   Chrome and Safari — the borders detach and scroll independently. The
   per-cell border-bottom still renders correctly this way. */
.att-table {
  width: 100%;
  min-width: 520px;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 12.5px;
}

/* Header stays put vertically; the Player column stays put horizontally.
   Scrolled right to the Payment column, every visible cell is an anonymous
   pill — without a pinned name you can confirm ₹1,000 against the wrong row. */
.att-table thead th { position: sticky; top: 0; z-index: 3; background: var(--white); }
/* No divider shadow here — it read as a stray vertical line next to every
   player's name. The column still pins; it just doesn't announce itself. */
.op-table td.att-td-name,
.op-table thead th.op-th-name { position: sticky; left: 0; background: var(--white); }
.op-table td.att-td-name { z-index: 2; }
.op-table thead th.op-th-name { z-index: 4; }

.att-table th {
  text-align: left;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--ink-soft);
  padding: 0 10px 8px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}

/* TOP, not middle. Payment and Categories cells are stacks of chips, so a
   3-category player makes a ~90px row — middle-aligning floated the name
   halfway down it and the eye lost the grid while scanning names. */
/* Gutters widened ~20% so the columns read as separate rather than butting
   into each other. */
.att-table td {
  padding: 12px 10px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.att-table tbody tr:last-child td { border-bottom: none; }

/* th.* is needed on the alignment: `.att-table th { text-align: left }` is
   0-1-1 and beats a bare `.att-td-num`, so the "#" header sat flush left over
   right-aligned numbers. */
th.att-td-num,
td.att-td-num {
  width: 28px;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  text-align: right;
  padding-right: 4px;
}

.att-td-name { font-weight: 600; color: var(--ink); white-space: nowrap; }
.att-td-status { white-space: nowrap; }
.att-td-phone { white-space: nowrap; }
.att-td-phone a { color: var(--ink); text-decoration: none; border-bottom: 1px dotted var(--line); }
.att-td-phone a:hover { color: var(--clay-dark); }

/* NOTE: max-width on a <td> is IGNORED in auto table layout — that's what let
   the doubles chip spill into the Owes and Categories columns. The width has
   to be bounded on the inner block (.op-chipstack), which does respect it. */
.att-td-cats { min-width: 118px; }
.op-td-pay { min-width: 150px; }
.op-td-pay .op-chipstack { max-width: 196px; }
.att-td-cats .op-chipstack { max-width: 160px; }

/* A player can be entered in several categories — each gets its own chip so
   two entries never read as one long category name. */
.att-cat {
  display: inline-block;
  font-size: 10.5px;
  padding: 2px 7px;
  margin: 1px 3px 1px 0;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--ink-soft);
  white-space: nowrap;
}

.att-none { color: var(--ink-soft); }

/* ---- Players Operations Dashboard ---- */

.op-table { min-width: 560px; }
/* Tightened to give the columns that carry information more room. The label
   still wraps the box so the tap target stays bigger than the box itself. */
.op-td-sel { width: 22px; padding-left: 4px !important; padding-right: 2px !important; }
/* 34px, not 28: this checkbox is the entry point for both bulk actions, so a
   missed tap here is a missed check-in or an uncollected fee. The cell stays
   22px wide; only the tap target grows. */
.op-sel-hit { display: flex; align-items: center; justify-content: center; min-width: 20px; min-height: 34px; cursor: pointer; }
.op-sel-hit input { width: 15px; height: 15px; margin: 0; }

/* Just the QR button now — the search box moved into the Player and Mobile
   column filters, where it belongs alongside the other four. */
.op-toolbar { display: flex; gap: 8px; align-items: center; margin: 12px 0 4px; }
.op-qr { flex: 0 0 auto; font-size: 12px; padding: 8px 12px; min-height: 34px; white-space: nowrap; }

.op-bulkbar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 8px 0 2px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, #3730A3 7%, var(--white));
  border: 1px solid color-mix(in srgb, #3730A3 25%, var(--white));
  /* NOT sticky. It was, at top:0 — which pinned it UNDER the 52px app top bar
     (z-index 70) where it was invisible, and moving it to top:52px only traded
     that for covering the table's own sticky <thead>, hiding the column labels
     and the select-all checkbox. The table body scrolls inside .att-table-wrap
     (max-height 65vh) rather than moving the page, so the bar stays beside the
     table on its own. */
}

/* The bar is always on screen so the two operations are discoverable. When
   nothing is ticked it recedes — same layout, quieter — rather than
   disappearing and reflowing the table under the organiser's thumb. */
.op-bulkbar--idle { background: var(--surface); border-color: var(--line); }
.op-bulkbar--idle .op-bulk-count { color: var(--ink-soft); font-weight: 600; }
.op-bulkbar--idle .op-bulk-clear { visibility: hidden; }

/* Full-width so the count doesn't blow a hole in the middle of a wrapped
   line — `margin-right: auto` applies PER FLEX LINE, which left the two
   action buttons at different x positions once the bar wrapped. */
.op-bulk-count { flex: 1 0 100%; font-size: 12px; font-weight: 800; color: #3730A3; }
.op-bulk-btn { font-size: 12px; padding: 8px 14px; min-height: 34px; }
.op-bulk-clear { background: none; border: none; padding: 8px 10px; min-height: 34px; font-size: 11.5px; color: var(--ink-soft); cursor: pointer; text-decoration: underline; }

/* Check-in reads as a switch: tap to flip. Green when in, grey when not. */
/* 34px minimum: this is the single most-tapped control at the desk and it
   was rendering ~21px tall, which is well under a comfortable thumb target. */
.op-ci {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  font-size: 10.5px;
  font-weight: 800;
  padding: 0 12px;
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
  border: 1px solid transparent;
}

.op-ci--in { background: #2E9E5B; color: #fff; }
.op-ci--out { background: color-mix(in srgb, var(--ink) 6%, var(--white)); color: var(--ink-soft); border-color: var(--line); }
.op-ci--out:hover { border-color: #2E9E5B; color: #2E9E5B; }

/* One chip per fee. Shows the category so it's obvious WHICH fee, and the
   amount until it's settled. Tap to confirm or un-confirm. */
.op-charge {
  display: inline-flex;
  gap: 7px;
  margin: 0;
  padding: 0 10px;
  min-height: 34px;
  max-width: 100%;
  border-radius: 999px;
  font-size: 10.5px;
  cursor: pointer;
  border: 1px solid var(--line);
  background: var(--white);
  white-space: nowrap;
  overflow: hidden;
}

/* The partner's name goes ON the chip, on its own line. It used to be a
   `title` tooltip, which never appears on a phone — and "who is this person
   playing with" is the first thing an organiser needs to settle a doubles
   pair at the desk. */
/* baseline, not center: the amount is one line and the label is two, so
   centring parked the ₹ figure between the two text lines, belonging to
   neither. Baseline puts it on the category name's line. */
.op-charge { align-items: baseline; padding-top: 6px; padding-bottom: 6px; }
/* The category label recedes to grey; the partner line is the darker of the
   two so the eye lands on WHO the shared fee is with. */
.op-charge .opc-cat { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.28; font-weight: 700; color: var(--ink-soft); min-width: 0; overflow: hidden; }
.op-charge .opc-val { font-weight: 800; flex: 0 0 auto; }

/* The category name itself needs its own block box to ellipsis — as a bare
   text node inside the flex column it had nothing to truncate against, so a
   long name pushed the chip past its column. */
.opc-name {
  display: block;
  max-width: 122px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Block box with a real width, so the ellipsis can actually fire — on the
   flex parent it silently did nothing (text-overflow needs a block box, and
   the parent had no width to overflow). */
.opc-with,
.op-partner {
  display: block;
  max-width: 122px;
  font-size: 9.5px;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.opc-due { border-color: color-mix(in srgb, #E06A66 40%, var(--white)); }
.opc-due .opc-val { color: #E06A66; }
.opc-claim { border-color: color-mix(in srgb, #D97A16 45%, var(--white)); background: color-mix(in srgb, #D97A16 6%, var(--white)); }
.opc-claim .opc-val { color: #D97A16; }
.opc-ok { border-color: color-mix(in srgb, #2E9E5B 35%, var(--white)); background: color-mix(in srgb, #2E9E5B 6%, var(--white)); }
.opc-ok .opc-val { color: #2E9E5B; }

.op-owed { font-weight: 800; color: #E06A66; white-space: nowrap; }
.op-settled { font-size: 11px; color: #2E9E5B; font-weight: 700; white-space: nowrap; }

/* ---- column filters, in the table header (spreadsheet-style) ---- */
/* Every column carries its own filter, on the column itself. Two earlier
   versions put the controls in a block above the table and both read as a
   second, unrelated toolbar; people already know to look for the funnel on the
   header. Player and Mobile filter by text, Check-in / Payment / Categories by
   a multi-tick value list. Filter to a cohort, then Select-all acts on exactly
   that group. */

.op-th-f { white-space: nowrap; }

/* display:flex, NOT inline-flex. Inline-flex shrinks to its text, so on a
   column whose width comes from the BODY cells (Payment is min-width 150px)
   the right-hand half of the header was dead to the touch and read as "this
   column isn't filterable". Block-level flex fills the cell's content box. */
.op-thf {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  width: 100%;
  /* 34px of tappable header. The header text is 10px — without this the
     funnel is a 12px target at the top edge of a scrolling table. */
  min-height: 34px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-align: left;
  text-transform: inherit;
  cursor: pointer;
}

.op-thf-top { display: inline-flex; align-items: center; gap: 4px; }

.op-thf-ic {
  display: inline-flex;
  width: 11px;
  height: 11px;
  flex: 0 0 auto;
  color: var(--ink-soft);
  opacity: .55;
  transition: opacity .12s ease;
}
.op-thf-ic svg { width: 100%; height: 100%; }
.op-thf:hover .op-thf-ic { opacity: 1; }
.op-thf:focus-visible { outline: 2px solid var(--clay); outline-offset: 2px; border-radius: 4px; }

/* Active column: indigo label, FILLED funnel, and the selection printed
   underneath. An organiser who forgets a filter is on and reads a short list
   as "only 6 registered" is the failure all three of these prevent. */
.op-th-f--on .op-thf-lbl { color: #3730A3; }
.op-th-f--on .op-thf-ic { color: #3730A3; opacity: 1; }
.op-th-f--on .op-thf-ic svg { fill: currentColor; }

/* max-width 80px is load-bearing, not cosmetic: this text sits in an
   auto-layout table, so its intrinsic width feeds the COLUMN width. Uncapped,
   picking "Men's Doubles 40+ Plate" widened the column by ~90px and reflowed
   every column to its right the instant the popup closed, under the
   organiser's finger. 80px is under the narrowest of the columns' existing
   min-widths, so choosing a filter can never move the table sideways. */
.op-thf-val {
  display: block;
  max-width: 80px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  color: #3730A3;
}

/* ---- the filter popup ----
   Appended to <body> and positioned `fixed` in JS. It CANNOT live inside the
   header cell: .att-table-wrap is `overflow: auto` with a max-height, so a
   popup anchored there is clipped to the table's own box — for the last
   column, or any column near the bottom of the scrollport, most of it simply
   isn't there. */
.opf-pop {
  position: fixed;
  z-index: 120;          /* over .app-topbar (70); under modals */
  width: 232px;
  max-width: calc(100vw - 16px);
  /* On a phone in landscape the viewport can be shorter than the popup. The
     JS clamp pins the top at 8px and the footer then overflows off-screen —
     and a `fixed` box with no overflow of its own cannot be scrolled to, so
     Clear and Done became physically unreachable. */
  max-height: calc(100vh - 16px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 8px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--white);
  box-shadow: 0 12px 32px rgba(22, 36, 26, .18);
  font-size: 12px;
  color: var(--ink);
}

.opf-head {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding: 2px 4px 6px;
}

/* 16px or iOS Safari zooms the whole page on focus, throwing away the
   organiser's scroll position — and the popup is positioned against a rect
   that the zoom then invalidates. */
.opf-q {
  width: 100%;
  min-height: 34px;
  font-size: 16px;
  padding: 0 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--white);
  color: var(--ink);
}
.opf-q:focus { outline: none; border-color: #3730A3; }

/* The list scrolls; the header, Select-all and footer stay put, so Clear is
   always one tap away however many categories there are. */
.opf-list { max-height: 208px; overflow-y: auto; margin-top: 2px; }

.opf-item {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 34px;
  padding: 0 4px;
  cursor: pointer;
  border-radius: 6px;
}
.opf-item:hover { background: var(--surface); }
.opf-item input { flex: 0 0 auto; width: 16px; height: 16px; accent-color: #3730A3; }

.opf-lbl { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.opf-n { flex: 0 0 auto; font-size: 11px; font-weight: 700; color: var(--ink-soft); }

.opf-item--all { border-bottom: 1px solid var(--line); border-radius: 0; margin-top: 4px; }
.opf-item--all .opf-lbl { font-weight: 700; }

.opf-foot { display: flex; gap: 8px; margin-top: 6px; }

.opf-clear, .opf-done {
  flex: 1 1 0;
  min-height: 34px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--white);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}
.opf-clear { color: var(--ink-soft); }
.opf-done { border-color: #3730A3; background: color-mix(in srgb, #3730A3 8%, var(--white)); color: #3730A3; }

/* Result count + escape hatch, directly under the table so it reads as part of
   it rather than as another panel. Only present when something is filtered. */
.op-count {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 8px 0 0;
  font-size: 11px;
  font-weight: 700;
  color: var(--ink-soft);
}

.op-filter-clear {
  flex: 0 0 auto;
  min-height: 30px;
  padding: 0 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--white);
  font-size: 11px;
  font-weight: 700;
  color: #3730A3;
  cursor: pointer;
  white-space: nowrap;
}

/* ---- expandable categories ---- */

.op-expand {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 34px;
  padding: 0 10px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--white);
  font-size: 11px;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
}

.op-expand:hover { border-color: #3730A3; color: #3730A3; }
.op-expand--open { border-color: #3730A3; background: color-mix(in srgb, #3730A3 7%, var(--white)); color: #3730A3; }
.op-caret { width: 12px; height: 12px; display: inline-flex; transition: transform .15s ease; }
.op-caret svg { width: 100%; height: 100%; }
.op-expand--open .op-caret { transform: rotate(180deg); }

.op-detailrow > td { background: var(--surface); padding: 0 10px 10px !important; }

.op-detail { display: flex; flex-direction: column; gap: 6px; padding: 10px 12px; border-radius: var(--radius-sm); background: var(--white); border: 1px solid var(--line); }

.op-detail-line { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.op-detail-cat { font-size: 12px; font-weight: 700; color: var(--ink); min-width: 110px; }
.op-detail-with { font-size: 10.5px; font-weight: 700; color: var(--ink); flex: 1 1 auto; }
.op-detail-fee { flex: 0 0 auto; }
.op-detail-total { margin-top: 2px; padding-top: 7px; border-top: 1px solid var(--line); font-size: 11.5px; color: var(--ink-soft); }
.op-detail-total strong { color: #E06A66; font-size: 13px; }

/* Same treatment in the Categories column — the category, then who they're
   partnered with underneath it. */
/* Matches the payment chip exactly: category grey, partner line darker so the
   eye lands on who they're playing with. Same padding and line-height as
   .op-charge so the two chip types don't visibly step against each other. */
.att-td-cats .att-cat {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  line-height: 1.28;
  margin: 0;
  padding: 0 9px;
  min-height: 34px;
  max-width: 100%;
  overflow: hidden;
}

/* Chips laid out as a flex stack rather than inline boxes on a text line.
   Inline chips sit on the line box's baseline strut, so wrapped rows got
   ~5px of uneven leading that changed with chip height. */
.op-chipstack { display: flex; flex-wrap: wrap; gap: 5px 6px; }

.op-empty { padding: 16px 8px; font-size: 12px; color: var(--ink-soft); text-align: center; }
.op-legend { margin-top: 10px; font-size: 11px; color: var(--ink-soft); line-height: 1.45; }

/* .att-time was built for the old flex row layout and carries a left margin
   that would indent it inside a table cell. (The matching .pay-chip reset was
   removed — .pay-chip is only used in .reg-team-list, never in this table.) */
.att-table .att-time { display: block; margin-left: 0; font-size: 10px; color: var(--ink-soft); margin-top: 3px; }

/* ============================================================
   POST-LOGIN VIEW CHOOSER
   First thing an organiser sees after signing in, so it gets room
   to breathe. Two full-width cards on a phone, side by side on
   anything wider.
============================================================ */

.vc-intro {
  font-size: 12.5px;
  color: var(--ink-soft);
  line-height: 1.5;
  margin-bottom: 14px;
}

.vc-grid { display: grid; grid-template-columns: 1fr; gap: 10px; }
@media (min-width: 520px) { .vc-grid { grid-template-columns: 1fr 1fr; } }

.vc-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 7px;
  text-align: left;
  padding: 18px 16px;
  border: 1.5px solid var(--line);
  border-radius: var(--radius);
  background: var(--white);
  cursor: pointer;
  transition: border-color .16s, box-shadow .16s, transform .12s;
}

.vc-card:hover {
  border-color: #3730A3;
  box-shadow: 0 6px 18px rgba(22, 36, 26, .08);
}

.vc-card:active { transform: scale(.99); }

/* The mode they were last in — a quiet hint, not a pre-selection. */
.vc-card--current { border-color: color-mix(in srgb, #3730A3 45%, var(--white)); background: color-mix(in srgb, #3730A3 4%, var(--white)); }

.vc-badge {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, #3730A3 9%, var(--white));
  color: #3730A3;
  margin-bottom: 3px;
  overflow: hidden;
}

.vc-badge svg { width: 22px; height: 22px; }
.vc-badge--org { padding: 0; background: transparent; }
.vc-badge--org .acad-logo { width: 44px; height: 44px; border-radius: 12px; margin: 0; }

.vc-title { font-size: 15.5px; font-weight: 800; color: var(--ink); letter-spacing: -.01em; }
.vc-desc { font-size: 11.5px; color: var(--ink-soft); line-height: 1.5; }
.vc-foot { font-size: 10.5px; font-weight: 700; color: #3730A3; text-transform: uppercase; letter-spacing: .04em; min-height: 13px; }

@media (max-width: 380px) {
  .drawmode-toggle { grid-template-columns: 1fr; }
  .mdraw-row__name { max-width: 130px; }
}

/* ===== Tournament pricing plans ===== */
.btn-sm { padding: 6px 12px; font-size: 12px; }
.ct-plan-section { margin-top: 18px; }
.ct-section-head { font-size: 13px; font-weight: 800; color: var(--ink); margin: 14px 0 8px; }
.plan-note { font-size: 12px; color: var(--ink-soft); line-height: 1.5; margin-bottom: 10px; }

/* plan chooser (radio cards)
   This is the buying decision, so the card is built around the two things an
   organiser is actually comparing: how many players it covers, and what it
   costs. The capacity is the headline (their number is already in their head),
   the price column is right-aligned so the tiers read as a column of figures,
   and the saving is stated in rupees rather than left as arithmetic between a
   price and a strike-through. */
.plan-radio-list { display: flex; flex-direction: column; gap: 9px; }
.plan-radio {
  display: flex; align-items: center; gap: 13px;
  border: 1.5px solid var(--line, #E3E0DA); border-radius: 14px;
  padding: 14px 16px; cursor: pointer; background: var(--white);
  transition: border-color .18s ease, background .18s ease, box-shadow .18s ease, transform .18s ease;
}
.plan-radio:hover { border-color: #C7C3F0; box-shadow: 0 1px 2px rgba(20,18,40,.04), 0 10px 22px -16px rgba(20,18,40,.3); }
.plan-radio:active { transform: scale(.995); }
.plan-radio--selected {
  border-color: #3730A3; background: color-mix(in srgb, #3730A3 5%, var(--white));
  box-shadow: 0 0 0 3px color-mix(in srgb, #3730A3 12%, transparent);
}
.plan-radio--selected:hover { border-color: #3730A3; }
.plan-radio-input { flex-shrink: 0; accent-color: #3730A3; width: 18px; height: 18px; }
.plan-radio-main { flex: 1; min-width: 0; }
/* The number carries the weight; "Up to" and "players" stay quiet around it. */
.plan-radio-name { font-size: 14.5px; font-weight: 600; color: var(--ink-soft); letter-spacing: -.005em; }
.plan-radio-name strong { font-size: 19px; font-weight: 800; color: var(--ink); letter-spacing: -.02em; }
.plan-radio-limit { font-size: 11.5px; color: var(--ink-soft); margin-top: 3px; line-height: 1.4; }
.plan-radio-price {
  flex-shrink: 0; text-align: right; display: flex; flex-direction: column;
  align-items: flex-end; gap: 1px; line-height: 1.15;
}
.plan-price { font-size: 17px; font-weight: 800; color: var(--ink); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.plan-price-strike { color: var(--ink-soft); text-decoration: line-through; font-weight: 600; font-size: 11.5px; font-variant-numeric: tabular-nums; }
.plan-price-save {
  font-size: 9.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--grass-dark, #1B7A43); background: color-mix(in srgb, var(--grass-dark, #1B7A43) 10%, transparent);
  border-radius: 999px; padding: 2px 7px; margin-top: 2px; white-space: nowrap;
}

/* Plan usage — ONE figure for the tournament, because that is what the plan
   measures. Replaced a per-category "count / limit" row that said the same
   thing once per category and, after the limit went tournament-wide, said it
   wrong. */
.plan-usage {
  border: 1px solid var(--line, #E3E0DA); border-radius: 12px;
  padding: 12px 14px; margin: 12px 0 4px; background: var(--white);
}
.plan-usage--unlimited { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.plan-usage__top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.plan-usage__label { font-size: 10px; font-weight: 800; letter-spacing: .13em; text-transform: uppercase; color: var(--ink-soft); }
.plan-usage__count { font-size: 12.5px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.plan-usage__count strong { font-size: 17px; font-weight: 800; color: var(--ink); letter-spacing: -.02em; }
.plan-usage__track { height: 6px; border-radius: 999px; background: var(--line-2, #DFD6C4); margin-top: 9px; overflow: hidden; }
.plan-usage__fill {
  height: 100%; border-radius: 999px; transition: width .8s cubic-bezier(.22,.85,.3,1);
  background: linear-gradient(90deg, var(--grass-dark, #1B7A43), #4FA96C);
}
.plan-usage__note { font-size: 11.5px; color: var(--ink-soft); margin-top: 7px; }
.plan-usage--full .plan-usage__fill { background: linear-gradient(90deg, #B4341F, #D2622E); }
.plan-usage--full .plan-usage__note { color: #B4341F; font-weight: 600; }

/* payment block */
.plan-qr {
  display: flex; justify-content: center; align-items: center;
  min-height: 180px; margin: 8px auto 6px; color: var(--ink-soft); font-size: 12px;
}
.plan-pay-amt { font-size: 14px; color: var(--ink); margin: 8px 0; }
.plan-pay-tier { font-size: 11.5px; color: var(--ink-soft); }
.plan-qr-hint { font-size: 11px; color: var(--ink-soft); text-align: center; margin: 0 0 8px; line-height: 1.4; }

/* One tap per UPI app, same payment, different scheme. */
.upi-app-row { display: flex; gap: 8px; margin: 0 0 8px; }
.upi-app-btn {
  flex: 1 1 0;
  display: flex; align-items: center; justify-content: center;
  min-height: 36px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--white);
  font-size: 12.5px; font-weight: 700; color: var(--ink);
  text-decoration: none;
}
.plan-pay-upi { font-size: 12.5px; color: var(--ink); margin-bottom: 10px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.plan-proof-status { font-size: 11.5px; color: var(--ink-soft); min-height: 14px; margin-bottom: 6px; }

/* dashboard bits */
.plan-pill { display: inline-block; font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 20px; }
.plan-pill--ok { background: var(--grass-light, #D8F0E1); color: var(--grass-dark, #1B7A43); }
.plan-pill--pending { background: #F6E2C6; color: #8A5216; }
.plan-pill--bad { background: #F8D7D3; color: #A33227; }
/* 12px top, 16px bottom: this note sits between the stat grid and the category
   list, whose own margin-top is 16px. At `margin: 8px 0` it was crowded
   against the tiles above and unevenly spaced from the list below. */
.plan-admin-note { font-size: 12px; color: #8A5216; background: #FBF1E1; border-radius: 8px; padding: 8px 10px; margin: 12px 0 0; line-height: 1.45; }
/* 14px, not 10px: the category rows above are 12px apart, so a 10px gap made
   the buttons look attached to the last row rather than separate from the list. */
.plan-dash-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.plan-dash-btn { flex: 1 1 0; min-width: 130px; }

/* ---- request: tournament count, running total, withdraw ---- */

.acad-count-field { margin-top: 12px; }
/* Narrow on purpose: it holds 1–20, and a full-width box invites someone to
   treat it as a text field. 16px so iOS doesn't zoom the modal on focus. */
.acad-count-field .input { max-width: 110px; font-size: 16px; }

/* The running total sits between the count and the payment block, so the
   amount in the QR below is never a surprise. */
.acad-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-top: 10px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--surface);
}
/* display:flex above OUTRANKS the browser's own [hidden] { display: none },
   so the `hidden` attribute alone left an empty bordered box sitting under the
   count field before a plan was picked. Same fix as .cg-autofill[hidden]. */
.acad-total[hidden] { display: none; }
.acad-total__calc { font-size: 12px; font-weight: 600; color: var(--ink-soft); min-width: 0; }
.acad-total__amt { font-size: 17px; font-weight: 800; color: var(--ink); flex-shrink: 0; }

/* Withdraw sits BELOW the request card, never inside it — the approved card is
   itself a <button>, and a nested button is invalid HTML that browsers
   silently un-nest, taking the click handler with it. Understated on purpose:
   this is the exit, not the action we want. */
.req-withdraw-row { display: flex; justify-content: center; margin-top: 8px; }
.req-withdraw-btn {
  min-height: 34px;
  padding: 0 12px;
  border: 0;
  background: none;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-soft);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.req-withdraw-btn:hover { color: var(--clay-dark); }

/* admin approval modal */
.plan-approval { display: flex; flex-direction: column; }
.plan-af { display: flex; justify-content: space-between; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--line, #EEECE7); }
.plan-af-k { font-size: 11.5px; font-weight: 700; color: var(--ink-soft); flex-shrink: 0; text-transform: uppercase; letter-spacing: .03em; }
.plan-af-v { font-size: 13px; color: var(--ink); text-align: right; word-break: break-word; }
.plan-af-proof { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; padding: 10px 0; }
.plan-proof-img { max-width: 160px; max-height: 200px; border-radius: 8px; border: 1px solid var(--line, #E3E0DA); }
.plan-approval-actions { display: flex; gap: 8px; margin-top: 14px; }
.plan-approval-actions .btn { flex: 1; }
.plan-btn-reject { color: #A33227; }

/* payment history */
.plan-hist { display: flex; flex-direction: column; gap: 8px; }
.plan-hist-row { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; border: 1px solid var(--line, #E3E0DA); border-radius: 10px; padding: 10px 12px; }
.plan-hist-sub { font-size: 11.5px; color: var(--ink-soft); margin-top: 2px; }
.plan-hist-events { margin-top: 6px; border-top: 1px dashed var(--line, #E3E0DA); padding-top: 8px; }
.plan-hist-event { font-size: 11px; color: var(--ink-soft); padding: 2px 0; }

@media (max-width: 380px) {
  .plan-proof-img { max-width: 120px; }
  .plan-dash-btn { min-width: 100%; }
}

/* ===== Action Center + notification history ===== */
/* Reuses .card, .reg-teams-details/.rtd-summary (the app's only collapse
   pattern), .btn*, the .plan-af / .plan-approval review modals, .notif-*,
   .tab-badge and .app-notif-badge. Only what those can't express is new. */
/* The line above used to glob those two selectors as ".plan-af" + star + slash
   + ".plan-approval". That star-then-slash CLOSED THIS COMMENT four words
   early, so the rest of the sentence was parsed as CSS, and the parser's error
   recovery — skip to the next close brace — ate the whole
   `.app-drawer-item--action` rule below. It never applied: the Action Center's
   badge has never been right-aligned and the drawer items have been plain
   blocks. A star immediately before a slash ENDS a CSS comment wherever it
   appears, so never write a selector glob followed by a slash in one. */

/* Hamburger entry needs flex to right-align its badge (.app-drawer-item is a
   plain block button). */
.app-drawer-item--action { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.ac-menu-badge {
  flex-shrink: 0; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px;
  background: var(--clay); color: var(--white); font-size: 11px; font-weight: 800;
  display: inline-flex; align-items: center; justify-content: center; line-height: 1;
}

/* ===== Tournament Operations (organiser action inbox) =====
   Sits above two real dashboards, so it stays deliberately quiet: one compact
   summary line and a plain list of rows. No tiles, no colour beyond the count. */
/* ===========================================================================
   PLAYERS OPERATIONS — table polish
   ---------------------------------------------------------------------------
   Visual only: spacing, sizing, type and hierarchy. No column moved, no control
   removed, no behaviour changed.

   SCOPING NOTE. The fixed layout (percentage columns, 58px rows) applies from
   900px UP. Below that the existing behaviour is kept deliberately: this is a
   PWA an organiser works on a PHONE at the desk, where eight columns cannot fit
   and the horizontally-scrolling table with a sticky Player column is what makes
   it usable at all. Forcing percentage widths onto a 390px screen would trade a
   working phone tool for something that only photographs well on a monitor.
   =========================================================================== */

/* ---- toolbar: one 56px row instead of two stacked strips ---- */
.op-toolbar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  min-height: 44px; padding: 6px 0; margin-bottom: 6px;
  border-bottom: 1px solid #ECEFF3;
}
.op-toolbar-grow { flex: 1 1 auto; }
.op-toolbar-sep { width: 1px; height: 20px; background: #ECEFF3; flex-shrink: 0; }
/* flex-basis 100% is inherited from the old stacked bulk bar, where the count
   deliberately sat on its own line. In a single toolbar row it forces a wrap
   and turns 56px into 130px, so it is reset here rather than there — the old
   rule still serves the narrow-screen fallback. */
.op-toolbar .op-bulk-count { flex: 0 0 auto; width: auto; font-size: 12px; color: #6B7280; font-weight: 500; }
.op-toolbar .btn { min-height: 28px; height: 28px; padding: 0 10px; font-size: 12px; font-weight: 600; border-radius: 8px; }
.op-toolbar.op-bulkbar--idle .op-bulk-btn { opacity: .55; }

/* ---- header ---- */
.op-table thead th {
  height: 48px;
  font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: #6B7280; border-bottom: 1px solid #ECEFF3;
}
.op-table .op-thf-lbl { font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; }

/* ---- cells ---- */
.op-table td { transition: background 150ms ease; }
.op-table tbody tr:hover td { background: #F8FAFC; }
/* Type is ~30% tighter than the previous pass so eight columns fit without
   anything spilling. */
.op-table .att-td-name { font-size: 13px; font-weight: 600; line-height: 17px; color: #111827; }
.op-table .op-td-sel { padding-right: 0; vertical-align: middle; }
.op-table .att-td-num { padding-left: 0; color: #6B7280; font-size: 11px; font-weight: 400; line-height: 15px; vertical-align: middle; }
.op-table .op-sub { font-size: 11px; font-weight: 400; line-height: 15px; color: #6B7280; }
.op-table .op-stat { font-size: 12px; font-weight: 600; line-height: 16px; white-space: nowrap; }
.op-table .op-stat--due { font-size: 13px; font-weight: 600; line-height: 17px; color: #111827; }
.op-table .op-stat-note { font-size: 11px; font-weight: 400; }

/* Status and its action sit on ONE line — the word buttons are gone, so a
   24px icon fits beside the status instead of costing a second row.
   The STATUS is the part allowed to shrink (min-width:0 + ellipsis). The tick,
   the undo and the 📎 proof link are flex-shrink:0, because losing a control is
   a functional failure and losing the tail of a label is only cosmetic — at
   900px "₹1,299 Says paid ✓ 📎" is 7px too wide, and before this the paperclip
   to the screenshot the organiser is being asked to verify was what got cut. */
.op-table .op-line { display: flex; align-items: center; gap: 6px; min-width: 0; }
/* .op-cell is a column flex with align-items:flex-start, so its children size to
   their CONTENT and happily exceed the cell. Stretching the line to the cell is
   what gives the ellipsis below something to shrink against — without it the
   status never yields and the 📎 is pushed out instead. */
.op-table .op-cell > .op-line { align-self: stretch; }
.op-table .op-line .op-stat { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.op-table .op-cell { gap: 2px; }
/* Green tick to do it, quiet undo to reverse it. Both always visible, so the
   reverse is never hidden behind the status. */
.op-table .op-ico {
  position: relative;
  flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0; border-radius: 6px;
  border: 1px solid #E5E7EB; background: var(--white);
  line-height: 1; cursor: pointer; text-decoration: none;
}
.op-table .op-ico svg { width: 13px; height: 13px; display: block; }
/* 24px is under every touch-target minimum (44pt iOS / 48dp Android) and these
   two buttons sit 6px apart and move money. The BOX stays 24px so the table
   keeps its density; the HIT AREA is grown invisibly to 40px. */
.op-table .op-ico::after { content: ""; position: absolute; top: 50%; left: 50%; width: 40px; height: 40px; transform: translate(-50%, -50%); }
.op-table .op-ico--ok { border-color: color-mix(in srgb, var(--grass) 45%, #E5E7EB); color: var(--grass-dark, #1B7A43); }
.op-table .op-ico--undo { color: #6B7280; }
.op-table .op-ico:active { transform: scale(.94); }
.op-table .op-proof { flex-shrink: 0; font-size: 11px; text-decoration: none; }

/* Player cell: the name takes what's left and ellipsises; the WhatsApp link is
   pinned. Without this the cell just clipped at the column edge — a long name
   was cut mid-word with no "…", and the 💬 link vanished entirely below about
   1100px, so the organiser lost the control rather than a few letters. */
.op-table .op-name { display: flex; align-items: center; gap: 6px; min-width: 0; }
.op-table .op-name-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.op-table .op-name .op-proof { flex-shrink: 0; }

/* ---- category pills: compact, capped, truncating ---- */
.op-table .att-cat {
  display: inline-flex; flex-direction: column; justify-content: center;
  min-height: 24px; max-width: 100%; padding: 3px 8px; border-radius: 999px;
  border: 1px solid #E5E7EB; background: var(--white);
  font-size: 11px; font-weight: 500; line-height: 1.25; overflow: hidden;
}
.op-table .att-cat .opc-name { font-weight: 500; color: #111827; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.op-table .att-cat .op-partner { font-size: 10px; color: #6B7280; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* MOBILE COLUMN: was spilling past its cell — a 10-digit number at 13px is
   wider than the column, and a bare <a> neither wraps nor truncates. Bounded
   and ellipsised so it can never push the table wider than its container. */
.op-table .att-td-phone { text-align: center; font-size: 11px; font-weight: 400; color: #6B7280; }
.op-table .att-td-phone,
.op-table .att-td-phone a { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.op-table .att-td-phone a { display: block; }

/* ---- desktop: ONE continuous data table ---- */
@media (min-width: 900px) {
  /* Fixed layout is what makes the percentage widths real — and, as a bonus,
     what finally makes max-width on a <td> mean anything (it is IGNORED in auto
     layout, the trap that once let a payment chip spill into the next column).
     border-collapse stays SEPARATE because sticky positioning is broken under
     collapse in Chrome and Safari; border-spacing is 0 so rows stay joined —
     separators come from a single bottom border per cell, nothing else. */
  .op-table { table-layout: fixed; width: 100%; border-collapse: separate; border-spacing: 0; border: 1px solid #ECEFF3; }
  .att-table-wrap { overflow-x: visible; }        /* no horizontal scroll on a monitor */

  /* Icon actions need far less room than the old word buttons, so Check-in
     gives width back to Categories and Mobile — Mobile was the column that
     overflowed. Everything still sums to 100. */
  .op-table th:nth-child(1), .op-table td:nth-child(1) { width: 4%; }    /* checkbox */
  .op-table th:nth-child(2), .op-table td:nth-child(2) { width: 4%; }    /* row number */
  .op-table th:nth-child(3), .op-table td:nth-child(3) { width: 30%; }   /* Player */
  .op-table th:nth-child(4), .op-table td:nth-child(4) { width: 15%; }   /* Check-in */
  .op-table th:nth-child(5), .op-table td:nth-child(5) { width: 17%; }   /* Payment */
  .op-table th:nth-child(6), .op-table td:nth-child(6) { width: 20%; }   /* Categories */
  .op-table th:nth-child(7), .op-table td:nth-child(7) { width: 10%; }   /* Mobile */

  /* Rows, not cards: one horizontal rule between them and nothing else. No
     radius, no shadow, no vertical separators. ~30% shorter than the last pass
     now that status and action share a line. */
  .op-table tbody td {
    height: 58px; padding: 8px 12px; vertical-align: middle;
    border: none; border-bottom: 1px solid #ECEFF3; box-shadow: none; border-radius: 0;
    overflow: hidden;                 /* nothing escapes its column */
  }
  .op-table tbody tr:last-child td { border-bottom: none; }
  .op-table thead th { height: 40px; padding: 0 12px; }

  .op-table .op-detailrow td { height: auto; padding: 6px 12px; }

  /* The sticky Player column is a phone affordance; on a monitor the whole
     table fits and a stuck column only adds a seam. Matched on `td.`/`th.` so
     it actually outranks the sticky rule above — as `.att-td-name` alone it
     lost on specificity and the column stayed stuck (harmless with no
     horizontal overflow, but it left an opaque background and a z-index=2
     stacking context sitting under the header filter popups). */
  .op-table td.att-td-name, .op-table thead th.op-th-name { position: static; background: none; }

  /* Those 196px/160px caps exist because max-width on a <td> is ignored in AUTO
     table layout, so the bound had to go on the inner block. Under fixed layout
     the cell width is real and the px cap is now the thing that overflows it:
     at 900px the Payment column is 143px while its chipstack still claimed 196,
     pushing the 📎 proof link outside the cell. Percentages instead, so the
     content follows the column it lives in. */
  .op-table .op-td-pay .op-chipstack,
  .op-table .att-td-cats .op-chipstack { max-width: 100%; }
  .op-table .op-td-pay, .op-table .att-td-cats { min-width: 0; }
}

/* ===== Players Operations: status, then its action beside it =====
   Every cell reads left-to-right — what the state IS, then the one icon that
   changes it (✓ to do, ↩ to reverse). Both directions are always visible, so an
   undo is never hidden behind the status text. Everything stays inside its own
   column; nothing floats between them. */
.op-cell { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0; }
.op-stat {
  display: inline-block; padding: 0; border: none; background: none;
  font-size: 12.5px; font-weight: 700; line-height: 1.3; text-align: left;
}
.op-stat--due { color: var(--ink); cursor: default; }
/* Completed. Purely a status now — the undo lives in its own ↩ icon beside it,
   so nothing about the text should invite a press. */
.op-stat--ok { color: var(--grass-dark, #1B7A43); cursor: default; }
.op-stat-note { font-weight: 600; color: var(--ink-soft); }
/* Secondary context under the status: partner, category, arrival time. */
.op-sub { font-size: 11px; color: var(--ink-soft); line-height: 1.35; }
/* Evidence / contact links — inline with the text they belong to, never a
   free-standing button between columns. */
.op-proof { text-decoration: none; font-size: 12px; }

.top-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding: 10px 0 2px; flex-wrap: wrap; }
.top-head__n { font-size: 14px; font-weight: 800; color: var(--ink); }
.top-head__g { font-size: 12px; color: var(--ink-soft); }
.top-rows { display: flex; flex-direction: column; }
/* Label left, count right. The whole row is the tap target. */
.top-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%;
  padding: 12px 2px; background: none; border: none;
  border-top: 1px solid var(--line); cursor: pointer; text-align: left;
}
.top-row:first-child { border-top: none; }
.top-row:active { background: color-mix(in srgb, var(--ink) 4%, transparent); }
.top-row__label { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 600; color: var(--ink); line-height: 1.35; }
.top-row__n { flex-shrink: 0; font-size: 14px; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; }
/* Zero recedes rather than shouting — no colour, just less weight. */
.top-row__n--clear { color: var(--ink-soft); font-weight: 600; }
.top-clear { padding: 12px 0 6px; font-size: 13.5px; font-weight: 700; color: var(--ink); }
.top-clear span { display: block; font-size: 12.5px; font-weight: 400; color: var(--ink-soft); margin-top: 2px; }

/* Pointer from a category to the merged Players Operations dashboard. */
.op-jump { display: block; width: 100%; text-align: left; cursor: pointer; }
.op-jump__t { display: flex; align-items: center; gap: 7px; font-size: 13.5px; font-weight: 700; color: var(--ink); }
.op-jump__t svg { width: 15px; height: 15px; flex-shrink: 0; }
.op-jump__s { display: block; font-size: 12px; color: var(--ink-soft); margin-top: 3px; line-height: 1.45; }

/* The two worlds: outside organisers vs Kross Rally's own events. */
.ac-toggles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 12px; }
.ac-toggle {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 11px 10px; border: 1.5px solid var(--line); border-radius: 12px;
  background: var(--white); font-size: 12.5px; font-weight: 700; color: var(--ink-soft);
  cursor: pointer; line-height: 1.25; text-align: center;
}
.ac-toggle--on { border-color: #3730A3; color: #3730A3; background: color-mix(in srgb, #3730A3 7%, var(--white)); }
.ac-toggle__n {
  flex-shrink: 0; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
  background: var(--clay); color: var(--white); font-size: 10.5px; font-weight: 800;
  display: inline-flex; align-items: center; justify-content: center;
}

/* Sport chips — horizontally scrollable so four sports never wrap awkwardly. */
.ac-chips { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 4px; margin-bottom: 14px; -webkit-overflow-scrolling: touch; }
.ac-chip {
  flex-shrink: 0; display: inline-flex; align-items: center; gap: 5px;
  padding: 7px 12px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--white); font-size: 12px; font-weight: 700; color: var(--ink-soft); cursor: pointer;
}
.ac-chip--on { border-color: #3730A3; color: #3730A3; background: color-mix(in srgb, #3730A3 6%, var(--white)); }
.ac-chip__n { font-weight: 800; opacity: .7; }
.ac-sportTag {
  display: inline-block; margin-right: 6px; padding: 2px 7px; border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 7%, var(--white)); color: var(--ink-soft);
  font-size: 10px; font-weight: 700;
}

/* Dashboard summary cards — 2-up on a phone, 3-up from 560px. */
.ac-cards { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-bottom: 16px; }
@media (min-width: 560px) { .ac-cards { grid-template-columns: repeat(3, 1fr); } }
.ac-card {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-md);
  padding: 12px 14px; text-align: left; cursor: pointer; width: 100%;
}
.ac-card--total { cursor: default; background: color-mix(in srgb, #3730A3 5%, var(--white)); }
.ac-card__n { font-size: 22px; font-weight: 800; line-height: 1.1; }
.ac-card__l { font-size: 11px; font-weight: 700; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .03em; line-height: 1.3; }
.ac-allclear { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink-soft); margin-bottom: 16px; }
.ac-allclear svg { width: 16px; height: 16px; flex-shrink: 0; color: var(--grass); }

/* Sections */
.ac-sec { margin-bottom: 12px; }
.ac-sec__n {
  margin-left: auto; min-width: 22px; height: 20px; padding: 0 7px; border-radius: 999px;
  background: var(--clay); color: var(--white); font-size: 11px; font-weight: 800;
  display: inline-flex; align-items: center; justify-content: center;
}
.ac-sec__n--zero { background: color-mix(in srgb, var(--ink) 10%, var(--white)); color: var(--ink-soft); }
.ac-sec .rtd-summary .rr-results-chev { margin-left: 8px; }
.ac-sec__body { padding-top: 10px; }
.ac-empty { font-size: 12.5px; color: var(--ink-soft); padding: 6px 0 2px; }

/* One pending item */
.ac-row { border: 1px solid var(--line); border-radius: 12px; padding: 12px; margin-bottom: 10px; }
.ac-row__head { display: flex; align-items: center; gap: 10px; }
.ac-row__id { flex: 1; min-width: 0; }
.ac-row__title { font-size: 14px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ac-row__sub { font-size: 11.5px; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ac-row__when { flex-shrink: 0; font-size: 11px; color: var(--ink-soft); }
.ac-flag { font-size: 11.5px; color: #8A5216; background: #FBF1E1; border-radius: 8px; padding: 7px 9px; margin-top: 8px; line-height: 1.45; }
.ac-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 12px; margin-top: 10px; }
@media (max-width: 420px) { .ac-fields { grid-template-columns: 1fr; } }
.ac-field { min-width: 0; }
.ac-field__k { display: block; font-size: 10px; font-weight: 700; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .03em; }
.ac-field__v { display: block; font-size: 12.5px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ac-row__acts { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.ac-row__acts .btn { flex: 1; min-width: 120px; }
.ac-btn-danger { color: #A33227; }

/* Unread notifications are visually distinct; read look normal. */
.notif-item--unread { background: color-mix(in srgb, #3730A3 5%, var(--white)); }
.notif-sec--row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.notif-linkbtn { font-size: 11.5px; font-weight: 700; color: #3730A3; background: none; border: none; padding: 0; cursor: pointer; }

/* History page */
.nh-tabs { display: flex; gap: 6px; margin-bottom: 12px; }
.nh-tab {
  flex: 1; padding: 8px 6px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--white); font-size: 12.5px; font-weight: 700; color: var(--ink-soft); cursor: pointer;
}
.nh-tab--on { border-color: #3730A3; color: #3730A3; background: color-mix(in srgb, #3730A3 6%, var(--white)); }
.nh-tab__n { font-weight: 800; opacity: .75; }
.nh-list { display: flex; flex-direction: column; gap: 8px; }
.nh-row { display: flex; gap: 10px; align-items: flex-start; border: 1px solid var(--line); border-radius: 12px; padding: 12px; cursor: pointer; background: var(--white); }
.nh-row--unread { background: color-mix(in srgb, #3730A3 5%, var(--white)); border-color: color-mix(in srgb, #3730A3 22%, var(--line)); }
.nh-row__dot { flex-shrink: 0; width: 8px; height: 8px; border-radius: 50%; background: #3730A3; margin-top: 6px; }
.nh-row__body { min-width: 0; flex: 1; }
.nh-row__title { font-size: 13.5px; font-weight: 700; color: var(--ink); line-height: 1.4; }
.nh-row__msg { font-size: 12.5px; color: var(--ink-soft); line-height: 1.45; margin-top: 2px; }
.nh-row__meta { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 6px; font-size: 10.5px; color: var(--ink-soft); }
.nh-row__rel, .nh-row__status {
  padding: 2px 7px; border-radius: 999px; background: color-mix(in srgb, var(--ink) 7%, var(--white)); font-weight: 700;
}

/* ===========================================================================
   WORKSPACES — the Play / Organiser switch and the organiser-only tabs.
   Existing tokens only: --ink, --ink-soft, --line, --white, --clay, --grass.
   No new colours, no gradients, no glassmorphism; the only shadow in play is
   the modal's own.
   =========================================================================== */

/* ---- the Workspace block at the top of the hamburger menu ---- */
/* Reads as a label and a status, NOT a button — the divider below it is what
   separates "which product am I in" from the documents underneath. */
.ws-menu { padding: 4px 14px 12px; border-bottom: 1px solid var(--line); margin-bottom: 6px; }
.ws-menu-label {
  font-size: 10.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft); margin-bottom: 8px;
}
.ws-menu-current { display: flex; flex-direction: column; gap: 3px; }
.ws-menu-name { display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 700; color: var(--ink); }
.ws-menu-emoji { font-size: 16px; line-height: 1; }
/* The only tappable thing in the block. A quiet text affordance, so the status
   above it is never mistaken for a control. */
.ws-menu-switch {
  margin-top: 8px; padding: 0; border: none; background: none; cursor: pointer;
  font-size: 12.5px; font-weight: 600; color: var(--clay-dark); text-align: left;
}
.ws-menu-switch:hover { text-decoration: underline; }

/* ---- Choose Workspace: bottom sheet on a phone, modal on a desktop ---- */
/* One set of markup for both — it renders inside the app's existing modal,
   which is already bottom-anchored on small screens and centred above them. */
.ws-sheet { display: flex; flex-direction: column; gap: 10px; }
.ws-opt {
  display: flex; align-items: flex-start; gap: 12px; width: 100%; text-align: left;
  padding: 14px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--white); cursor: pointer;
}
.ws-opt:hover { border-color: color-mix(in srgb, var(--clay) 40%, var(--line)); }
/* The one already active. A border and a tick, not a fill — choosing it is a
   no-op, so it must not look like the recommended action. */
.ws-opt--current { border-color: color-mix(in srgb, var(--grass) 45%, var(--line)); }
.ws-opt-emoji { font-size: 22px; line-height: 1.1; flex-shrink: 0; }
.ws-opt-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1; }
.ws-opt-title { font-size: 14.5px; font-weight: 700; color: var(--ink); }
.ws-opt-lines { display: flex; flex-direction: column; gap: 1px; }
.ws-opt-lines span { font-size: 12px; color: var(--ink-soft); line-height: 1.45; }
.ws-opt-tick { flex-shrink: 0; width: 16px; height: 16px; color: var(--grass-dark, #1B7A43); }
.ws-cancel { margin-top: 2px; }

/* ---- the 200ms crossfade on switch ---- */
/* Opacity only. Moving the nav or the page would read as a route change, and
   this is not navigation — it is the ground changing underneath. */
@keyframes wsFade { from { opacity: 0; } to { opacity: 1; } }
.ws-fade { animation: wsFade 200ms ease-out; }
@media (prefers-reduced-motion: reduce) { .ws-fade { animation: none; } }

/* ---- Dashboard tournament header ----
   [n] [sport] [name] [date] [chevron], one row. Inherits .rtd-summary, so the
   whole row is already the toggle — a <summary> needs no click handler and
   leaves no dead zone between the name and the arrow. Every card stays the
   same neutral colour: nothing here varies by tournament or status, because a
   list you scan by position should not also be asking you to decode a palette.
   The chevron is pushed right by .rtd-summary's own margin-left:auto. */
.dash-head { gap: 9px; }
.dash-num {
  flex-shrink: 0; min-width: 16px; text-align: right;
  font-size: 12px; font-weight: 700; color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
.dash-sport { flex-shrink: 0; }
/* The name takes the room and ellipsises; the date never gets squeezed out,
   because "which tournament, and when" is the whole point of the row. */
.dash-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-date {
  flex-shrink: 0; font-size: 11.5px; font-weight: 500; color: var(--ink-soft);
  white-space: nowrap;
}
/* Below ~380px the date drops under the name rather than crushing it. */
@media (max-width: 380px) {
  .dash-head { flex-wrap: wrap; }
  .dash-name { flex: 1 1 auto; }
  .dash-date { flex-basis: 100%; padding-left: 25px; }
}

/* ---- Category Summary ----
   Six figures per category, on the same 3-up grid the dashboard tiles use. No
   cards inside cards: one rule between categories, same as every other list in
   the app. */
.csum-list { display: flex; flex-direction: column; }
.csum-cat { border-top: 1px solid var(--line); }
.csum-cat:first-child { border-top: none; }
.csum-head {
  display: block; padding: 11px 2px 0;
  cursor: pointer; list-style: none;
}
/* "Category 1" over the name, not "1 Men's Singles" on one line: the label is
   how an organiser refers to it out loud ("category two is running late"), so
   it reads as a heading for the name rather than a bullet beside it. */
.csum-head-top { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; margin-bottom: 8px; }
.csum-label {
  font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-soft); font-variant-numeric: tabular-nums;
}
/* The stage rides on the same line as the number, one notch lighter so
   "Category 2" stays the thing you count by and the status is the detail. */
.csum-stage { font-weight: 600; color: var(--ink-soft); opacity: .85; }
.csum-head::-webkit-details-marker { display: none; }
.csum-head--static { cursor: inherit; width: 100%; }
.csum-name { flex: 1; min-width: 0; font-size: 13px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.csum-head--static { display: block; padding: 11px 2px 0; }
.csum-head--static .csum-name { display: inline-block; }

.csum-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; padding: 0 2px 12px; }
@media (min-width: 640px) { .csum-stats { grid-template-columns: repeat(6, 1fr); } }
.csum-stat { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.csum-v { font-size: 14px; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.csum-l { font-size: 10px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); }


/* On the Dashboard tab a category is INFORMATION — same block, no <details>,
   no tap target. The only way into a tournament is the button at the bottom of
   its card, so there is never a question of which tap does what. */
.csum-cat--static { border-top: 1px solid var(--line); }
.csum-cat--static:first-child { border-top: none; }
.csum-cat--static .csum-name { cursor: default; }

/* The DUPR window on a category card. Sky, from the palette — it sits in the
   same badge row as the status pills, and the neutral grey it used to be was a
   near-twin of .pill-closed, so a closed category showed two grey pills meaning
   completely different things. Sky is the one palette family the category
   badges don't already use for status, so it reads as information rather than
   as a stage. No ::before dot for the same reason. */
.pill-dupr { background: var(--sky-light); color: var(--sky-dark); font-variant-numeric: tabular-nums; }
/* Per-category DUPR limits in the create/edit form. No margin-top — the parent
   .ct-prize-cat is already a flex column with gap:8px, so adding one doubled
   the space above this block and only this block. */
.ct-dupr { display: flex; flex-direction: column; gap: 5px; }
.ct-dupr-lbl { font-size: 11.5px; font-weight: 600; color: var(--ink); }
.ct-dupr-opt { font-weight: 400; color: var(--ink-soft); }

/* ---- DUPR verification (profile editor) ---- */
.dupr-row { display: flex; gap: 8px; align-items: stretch; }
.dupr-row .input { flex: 1; min-width: 0; text-transform: uppercase; }
.dupr-row .btn { flex-shrink: 0; }
.dupr-note { font-size: 11.5px; color: var(--ink-soft); line-height: 1.45; margin-top: 6px; }
/* --danger, not --clay-dark. Clay is the app's brand accent — hovers, section
   headings, the champion badge — so a failed verification rendered in it reads
   as a highlight rather than as something going wrong. */
.dupr-note--bad { color: var(--danger); }
/* Verified reads as a settled fact, not a form control — there is nothing to
   edit, only to remove and redo. */
.dupr-verified { padding: 10px 12px; border: 1px solid color-mix(in srgb, var(--grass) 40%, var(--line)); border-radius: 10px; background: var(--white); }
.dupr-v-top { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 700; color: var(--ink); }
.dupr-v-tick { width: 14px; height: 14px; color: var(--grass-dark, #1B7A43); flex-shrink: 0; }
.dupr-v-sub { font-size: 11.5px; color: var(--ink-soft); margin-top: 3px; }

/* ---- Action Centre (organiser workspace home) ----
   Reuses the app's existing rhythm: one rule between rows, no cards, no
   shadows, no new colours. A cleared group stays visible but recedes — the
   zero is the reassurance, so it must be legible without competing with the
   groups that actually need attention. */
.aco-lead { font-size: 12.5px; color: var(--ink-soft); margin-bottom: 14px; line-height: 1.5; }
.aco-lead--clear { color: var(--grass-dark, #1B7A43); font-weight: 600; }
.aco-list { display: flex; flex-direction: column; }

.aco-grp { border-top: 1px solid var(--line); }
.aco-grp:first-child { border-top: none; }
.aco-head {
  display: flex; align-items: center; gap: 12px; padding: 14px 2px;
  cursor: pointer; list-style: none;
}
.aco-head::-webkit-details-marker { display: none; }
.aco-label { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 700; color: var(--ink); }
.aco-n {
  flex-shrink: 0; min-width: 24px; text-align: center;
  font-size: 12px; font-weight: 800; color: var(--clay-dark);
  font-variant-numeric: tabular-nums;
}
.aco-n--clear { color: var(--ink-soft); font-weight: 600; }
.aco-chev { flex-shrink: 0; width: 15px; height: 15px; color: var(--ink-soft); transition: transform 160ms ease; }
.aco-grp[open] .aco-chev { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .aco-chev { transition: none; } }
/* Nothing pending: the row is a statement, not a control. */
.aco-grp--clear .aco-head { cursor: default; }
.aco-grp--clear .aco-label { color: var(--ink-soft); font-weight: 600; }

.aco-rows { display: flex; flex-direction: column; padding-bottom: 6px; }
/* The row itself is no longer a control — it states who and what, and the
   button beside it is the only thing that does anything. */
.aco-row {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 10px 2px 10px 12px; border-left: 2px solid var(--line);
}
.aco-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
/* The NAME leads and stays solid; what they did is one weight lighter, so a
   column of these scans as a list of people. */
.aco-row-t { font-size: 13px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aco-row-act { font-weight: 500; color: var(--ink-soft); }
.aco-row-s { font-size: 11.5px; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aco-open {
  flex-shrink: 0; min-height: 30px; height: 30px; padding: 0 11px;
  font-size: 12px; font-weight: 600; border-radius: 8px; white-space: nowrap;
}
/* On a phone the button drops under the text rather than squeezing a name to
   nothing — the name is the point of the row. */
@media (max-width: 420px) {
  .aco-row { flex-wrap: wrap; }
  .aco-open { margin-left: auto; }
}

/* ---- "Where does the knockout start?" ---- */
.ko-entry-list { display: flex; flex-direction: column; gap: 8px; }
.ko-entry {
  display: flex; flex-direction: column; gap: 2px; width: 100%; text-align: left;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--white); cursor: pointer;
}
.ko-entry:hover { border-color: color-mix(in srgb, var(--clay) 40%, var(--line)); }
.ko-entry-t { font-size: 14px; font-weight: 700; color: var(--ink); }
.ko-entry-s { font-size: 12px; color: var(--ink-soft); }

/* ---- organiser tab ORDER ----
   One tab bar serves both workspaces, so the organiser-only tabs sit after
   Profile in the markup and the bar read Tournaments · Profile · Dashboard ·
   Players · Payments. `order` fixes the sequence without moving anything in
   the DOM (which would break the play order instead). Play mode needs no rule
   — its DOM order is already its display order. */
.organiser-view .tabbar .tab[data-tab="orgDashboard"] { order: 1; }
.organiser-view .tabbar .tab[data-tab="tournaments"]  { order: 2; }
.organiser-view .tabbar .tab[data-tab="orgPlayers"]   { order: 3; }  /* Dashboard */
.organiser-view .tabbar .tab[data-tab="profile"]      { order: 4; }

/* ---- Organiser Dashboard ---- */
.odash-stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-bottom: 16px; }
@media (min-width: 640px) { .odash-stats { grid-template-columns: repeat(4, 1fr); } }
.odash-stat { padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px; background: var(--white); }
.odash-stat-v { font-size: 19px; font-weight: 800; color: var(--ink); line-height: 1.2; }
.odash-stat-l { font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); margin-top: 3px; }
.odash-stat-s { font-size: 11px; color: var(--ink-soft); margin-top: 2px; }

.odash-sec { margin-bottom: 18px; }
/* Collapsible: an organiser with 22 tournaments had several screens of list
   before anything actionable. The count stays on the closed summary, so a shut
   section still tells you whether it is worth opening. */
.odash-sec-head {
  display: flex; align-items: center; gap: 10px; padding: 0 2px 8px;
  cursor: pointer; list-style: none;
}
.odash-sec-head::-webkit-details-marker { display: none; }
.odash-sec-t { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 800; color: var(--ink); }
.odash-sec-n { flex-shrink: 0; font-size: 12px; font-weight: 700; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.odash-sec-chev { flex-shrink: 0; width: 15px; height: 15px; color: var(--ink-soft); transition: transform 160ms ease; }
.odash-sec[open] .odash-sec-chev { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .odash-sec-chev { transition: none; } }
.odash-empty { padding: 12px 2px; font-size: 12.5px; color: var(--ink-soft); }

/* One rule between rows, matching the operations table. No cards. */
.odash-row {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 12px 2px; background: none; border: none; border-top: 1px solid var(--line); cursor: pointer;
}
.odash-row:first-child { border-top: none; }
.odash-row:active { background: color-mix(in srgb, var(--ink) 4%, transparent); }
.odash-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.odash-row-t { font-size: 13.5px; font-weight: 600; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.odash-row-s { font-size: 11.5px; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.odash-row-go { flex-shrink: 0; width: 15px; height: 15px; color: var(--ink-soft); }
/* Status on the tournament row. Reuses the four status colours already used by
   the tab chips and summary panels — no new colours. */
.odash-status {
  flex-shrink: 0; font-size: 10.5px; font-weight: 700; letter-spacing: .02em;
  padding: 3px 8px; border-radius: 999px; white-space: nowrap;
  border: 1px solid var(--line); color: var(--ink-soft);
}
.odash-status--registering { color: #2E9E5B; border-color: color-mix(in srgb, #2E9E5B 40%, var(--line)); }
.odash-status--in_progress { color: #D9A125; border-color: color-mix(in srgb, #D9A125 40%, var(--line)); }
.odash-status--completed   { color: #2F6FB5; border-color: color-mix(in srgb, #2F6FB5 40%, var(--line)); }
.odash-status--upcoming    { color: var(--ink-soft); }
/* Five cards now (Today's Matches joined them) — two up on a phone, five
   across once there is room. */
@media (min-width: 640px) { .odash-stats { grid-template-columns: repeat(5, 1fr); } }

/* ---- Kross Rally mark in the app top bar (organiser workspace) ----
   Occupies the exact slot #ask-fab uses in the play workspace: absolutely
   centred between the menu and the bell, so nothing shifts when you switch.
   Just the mark — the ACADEMY's identity lives in the dark page band below. */
.org-brand {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  display: flex; align-items: center; pointer-events: none;
}
.org-brand img { height: 26px; width: auto; display: block; }

/* ---- academy lockup, centred in the dark page band ---- */
/* Three columns rather than space-between: with `1fr auto 1fr` the middle
   column is centred on the BAND, not on whatever is left over after the title
   — which is what makes it line up with the mark in the bar above it. */
/* Title left, then anything the page puts in the right slot, then the academy
   hard against the band's right edge. The grid does the ordering, so the DOM
   keeps topBarHtml's natural title → academy → rightHtml sequence and the
   academy is still last on screen.
   Track sizing decides WHO YIELDS when the band is too narrow, and the answer
   has to be the academy name: it is the only element with an ellipsis, and
   squeezing the first track instead wraps the page title onto two lines. So
   the title and the right slot are `auto` (content-sized, with a min-content
   floor) and the academy is the `1fr` — an fr track floors at 0, so it gives
   up its width first and the name ellipses inside it.
   `grid-row: 1` on all three is NOT decorative. Auto-placement walks the DOM
   in order — brand, academy, right slot — so naming only the COLUMN left the
   right slot's cursor already past column 2 on row 1, and the "+" create
   button on the Tournaments header silently dropped to a second row. */
.topbar--org {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  align-items: center;
  column-gap: 12px;
}
.topbar--org .topbar-brand { grid-column: 1; grid-row: 1; min-width: 0; }
.topbar--org .topbar-right { grid-column: 2; grid-row: 1; }
/* STRETCHED to fill its track, with the contents pushed to the far end —
   deliberately not `justify-self: end`, which sizes the box to its content and
   then aligns it: an over-long academy name then overflows LEFT, across the
   page title, instead of ellipsing. Filling the track is what makes the track's
   width the name's budget. */
.topbar-acad {
  grid-column: 3; grid-row: 1;
  display: flex; align-items: center; justify-content: flex-end;
  gap: 12px; min-width: 0;
}
/* WHITE TILE, deliberately. An academy logo is usually dark artwork on a
   transparent or white ground, and dropped straight onto --ink it vanishes.
   A white tile makes every logo legible whatever is in it, and `contain`
   shows the whole mark instead of cropping it to fill a circle. */
.topbar-acad-badge {
  flex-shrink: 0; width: 34px; height: 34px; border-radius: 8px;
  background: var(--white); padding: 3px;
  display: inline-flex; align-items: center; justify-content: center; overflow: hidden;
}
.topbar-acad-badge img { width: 100%; height: 100%; object-fit: contain; display: block; }
.topbar-acad-ini { font-size: 12px; font-weight: 800; color: var(--ink); letter-spacing: .02em; }
/* Type comes from the shared .topbar-sub rule above — size, colour, weight and
   line-height are NOT restated here, or this later rule would simply win again
   and the two would drift. Only the truncation behaviour is this element's. */
.topbar-acad-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Below ~560px three tracks cannot hold a title, a name and a button at full
   width. The lockup USED TO drop to its own centred row here; it now holds its
   place on the right and gives up name width instead, so the branding sits in
   the same corner on a phone as on a desktop. The mark itself never shrinks
   (.topbar-acad-badge is flex-shrink: 0) — only the name ellipses. */
@media (max-width: 560px) {
  .topbar--org { column-gap: 10px; }
  .topbar-acad { gap: 10px; }

  /* MOBILE ONLY: the mark rides ABOVE the name, and the pair stops fighting
     the title for width.
     The old third track was minmax(0, 1fr) — an fr track floors at ZERO, so
     the 279px title claimed the whole row and left the name 9px of the 129px
     it needed. Widening that track cannot fix it either: title + name simply
     do not fit on one 358px line, so the name would only wrap into a ragged
     column and push the header from 77px to 118px.
     Instead `display: contents` promotes the title, subtitle, mark and name
     into grid items of ONE 2x2 grid. The mark sits level with the title, and
     the name sits level with "Organiser Workspace" — beside it, in the ~230px
     that was empty there. Full name, one line, header barely taller.
     `display: contents` only dissolves the wrapper boxes; the markup, the DOM
     order and the reading order are untouched, so desktop is unaffected.
     Scoped away from headers that carry a right-hand action — the Tournaments
     create button owns that corner, and it keeps the plain stack further
     down instead of colliding with the mark. */
  .topbar--org:not(:has(.topbar-right)) {
    grid-template-columns: minmax(0, 1fr) auto;
    row-gap: 2px;
  }
  .topbar--org:not(:has(.topbar-right)) .topbar-brand,
  .topbar--org:not(:has(.topbar-right)) .topbar-brand > div,
  .topbar--org:not(:has(.topbar-right)) .topbar-acad { display: contents; }
  .topbar--org:not(:has(.topbar-right)) .topbar-title { grid-column: 1; grid-row: 1; }
  .topbar--org:not(:has(.topbar-right)) .topbar-sub { grid-column: 1; grid-row: 2; }
  .topbar--org:not(:has(.topbar-right)) .topbar-acad-badge {
    grid-column: 2; grid-row: 1; justify-self: end;
    width: 28px; height: 28px;
  }
  .topbar--org:not(:has(.topbar-right)) .topbar-acad-name {
    grid-column: 2; grid-row: 2; justify-self: end;
    text-align: right;
  }

  /* Mark above name for the rest (Tournaments), and NEVER an ellipsis on a
     phone: the whole point is that the name reads in full, so it wraps. */
  .topbar-acad {
    flex-direction: column-reverse;
    align-items: flex-end;
    gap: 6px;
  }
  .topbar-acad-badge { width: 28px; height: 28px; }
  .topbar-acad-name {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    text-align: right;
    overflow-wrap: anywhere;
  }
}

/* ---- Organisation Settings (organiser Profile tab) ---- */
.orgset-list { display: flex; flex-direction: column; }
.orgset-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding: 10px 0; border-top: 1px solid var(--line);
}
.orgset-row:first-child { border-top: none; }
.orgset-l { flex-shrink: 0; font-size: 12.5px; color: var(--ink-soft); }
.orgset-opt { font-size: 10.5px; }
.orgset-v { min-width: 0; font-size: 13px; font-weight: 600; color: var(--ink); text-align: right; overflow-wrap: anywhere; }
/* An empty field still gets a row — a settings page that hides what is missing
   cannot tell you anything is missing. */
.orgset-v--none { font-weight: 400; color: var(--ink-soft); }

.odash-line { padding: 9px 2px; border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: 2px; }
.odash-line:first-child { border-top: none; }
.odash-line-t { font-size: 13px; font-weight: 600; color: var(--ink); }
.odash-line-w { font-weight: 400; color: var(--ink-soft); }
.odash-line-s { font-size: 11.5px; color: var(--ink-soft); }

/* First-run / not-approved panels. */
.odash-become { padding: 20px 18px; text-align: center; }
.odash-become-t { font-size: 15.5px; font-weight: 800; color: var(--ink); }
.odash-become-s { font-size: 12.5px; color: var(--ink-soft); line-height: 1.5; margin-top: 4px; }

/* ---- Organiser Players ---- */
.oplr-total { font-size: 12px; color: var(--ink-soft); margin-bottom: 12px; }
.oplr-list { display: flex; flex-direction: column; margin-top: 6px; }
.oplr-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 0; border-top: 1px solid var(--line); }
.oplr-row:first-child { border-top: none; }
/* Name baseline sits with the chips, not above them: the chips are 11px inside
   a 1px border, so matching line-heights is what stops the row looking like
   the name floats. */
.oplr-name { font-size: 13px; font-weight: 600; line-height: 18px; color: var(--ink); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.oplr-meta { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.oplr-chip {
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600; line-height: 16px; color: var(--ink-soft);
  padding: 1px 8px; border-radius: 999px; border: 1px solid var(--line); white-space: nowrap;
}
/* Both chips are CONTENT-width by default, so "Paid" and "₹4,111 due" are
   different widths and the check-in chip beside them lands in a different
   place on every row — the whole right-hand side jitters down the list. Fixed
   columns instead, and tabular figures so ₹900 and ₹4,111 occupy the same
   grid. min-width, not width: a longer amount grows rather than clipping. */
.oplr-chip--ci  { min-width: 96px; }
.oplr-chip--pay { min-width: 86px; font-variant-numeric: tabular-nums; }
.oplr-chip--ok { color: var(--grass-dark, #1B7A43); border-color: color-mix(in srgb, var(--grass) 40%, var(--line)); }
/* The whole group is right-aligned as one block, so the two columns stay put
   however long a player's name is. */
.oplr-list + .btn { margin-top: 10px; }

/* ---- Organiser Payments ---- */
.opay-row {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 12px 2px; background: none; border: none; border-top: 1px solid var(--line); cursor: pointer;
}
.opay-row:first-child { border-top: none; }
.opay-row:active { background: color-mix(in srgb, var(--ink) 4%, transparent); }
.opay-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.opay-t { font-size: 13.5px; font-weight: 600; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.opay-s { font-size: 11.5px; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.opay-due { flex-shrink: 0; font-size: 13px; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; }
.opay-due--clear { color: var(--grass-dark, #1B7A43); font-weight: 600; }

/* ============================================================
   COACH FINDER
   ------------------------------------------------------------
   Reuses .card, .field, .field-label, .input, .chip, .btn* and
   .empty-state — this block only adds the arrangement those
   components sit in. No new colour is introduced: clay for the
   one accent, grass for verified, sky for the Pro tag, and
   --ink-soft for everything secondary. A discovery page whose
   cards each shout in a different colour is the "simple
   directory" this feature is explicitly not.
   ============================================================ */

.cf-root { display: flex; flex-direction: column; gap: 12px; }

/* Section nav. A segmented control, not tabs — the bottom nav is the app's tab
   metaphor and Coach Finder deliberately does not live there.
   WRAPS rather than scrolls. An earlier version scrolled sideways, which on a
   320px phone left the third chip cut off at the screen edge with nothing to
   suggest it was still there. With only three items, a second row costs ~34px
   and hides nothing; a hidden nav item may as well not exist. All three fit on
   one line from 360px up, so most phones never see the wrap at all. */
.cf-nav { display: flex; flex-wrap: wrap; gap: 6px; }
.cf-nav-btn {
  flex-shrink: 0; padding: 8px 12px; border-radius: 20px;
  border: 1px solid var(--line); background: var(--white);
  font-size: 12.5px; font-weight: 600; color: var(--ink-soft); cursor: pointer;
  white-space: nowrap;   /* one line each — a wrapped chip doubles the nav's height */
}
.cf-nav-btn.is-on { background: var(--clay); border-color: var(--clay); color: var(--white); }

/* Carries the full section name where the chip had to be abbreviated. Negative
   top margin pulls it against the nav's own gap so the two read as one header
   block rather than as two stacked things. */
.cf-section-title {
  font-family: var(--font-display); font-size: 17px; margin: -2px 0 0; color: var(--ink);
}

/* ---- filters ---- */
.cf-filters { display: flex; flex-direction: column; gap: 10px; }
/* Two up from 380px, one up below it. Eight controls in a single column is a
   lot of scrolling before the button that actually searches. */
.cf-filter-grid { display: grid; grid-template-columns: 1fr; gap: 10px; }
@media (min-width: 380px) { .cf-filter-grid { grid-template-columns: 1fr 1fr; } }

.cf-go { margin-top: 2px; display: flex; align-items: center; justify-content: center; gap: 7px; }
.cf-go svg { width: 16px; height: 16px; }

.cf-loc {
  display: flex; align-items: center; gap: 7px; font-size: 11.5px;
  color: var(--ink-soft); line-height: 1.45;
}
.cf-loc svg { width: 14px; height: 14px; flex-shrink: 0; }
.cf-loc--btn {
  width: 100%; text-align: left; padding: 9px 11px; border-radius: 10px;
  border: 1px dashed var(--line); background: transparent; cursor: pointer;
  font-family: inherit; color: var(--ink-soft);
}
.cf-loc--ok { color: var(--grass-dark); }

.cf-hint { font-size: 12.5px; color: var(--ink-soft); text-align: center; padding: 20px 12px; line-height: 1.5; }
.cf-count { font-size: 11.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); }
.cf-results { display: flex; flex-direction: column; gap: 10px; }

/* ---- coach card ---- */
.cf-card { display: flex; flex-direction: column; gap: 9px; cursor: pointer; }
.cf-card-top { display: flex; gap: 11px; align-items: flex-start; }
.cf-photo { width: 52px; height: 52px; border-radius: 12px; object-fit: cover; flex-shrink: 0; }
.cf-photo--lg { width: 72px; height: 72px; border-radius: 14px; }
.cf-card-id { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 2px; }
.cf-name { font-size: 15px; font-weight: 700; color: var(--ink); }
.cf-academy { font-size: 12.5px; color: var(--ink-soft); }
.cf-meta { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 3px; }
.cf-sport, .cf-years {
  font-size: 10.5px; font-weight: 700; padding: 3px 8px; border-radius: 20px;
  background: color-mix(in srgb, var(--ink) 6%, var(--white)); color: var(--ink-soft);
}

.cf-card-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.cf-rating { font-size: 12.5px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
.cf-reviews { font-weight: 400; color: var(--ink-soft); }
/* "New listing" reads as a fact. A zero-star row would read as a bad coach. */
.cf-rating--none { font-weight: 600; color: var(--ink-soft); }
.cf-verified {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10.5px; font-weight: 700; padding: 3px 8px; border-radius: 20px;
  background: var(--grass-light); color: var(--grass-dark);
}
.cf-verified svg { width: 12px; height: 12px; }

.cf-where { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--ink-soft); }
.cf-where svg { width: 13px; height: 13px; flex-shrink: 0; }
.cf-intro { font-size: 12.5px; color: var(--ink-soft); line-height: 1.5; }

.cf-card-actions { display: flex; flex-wrap: wrap; gap: 7px; }
.cf-act { flex: 1; min-width: 92px; display: inline-flex; align-items: center; justify-content: center; gap: 5px; text-decoration: none; }
.cf-act svg { width: 14px; height: 14px; }

/* ---- profile ---- */
.cf-back {
  align-self: flex-start; display: inline-flex; align-items: center; gap: 4px;
  background: none; border: none; padding: 4px 0; cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 600; color: var(--clay);
}
.cf-back svg { width: 15px; height: 15px; }
.cf-profile-head { display: flex; gap: 13px; align-items: flex-start; }
.cf-profile-id { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 5px; }
.cf-profile-name { font-family: var(--font-display); font-size: 21px; margin: 0; color: var(--ink); }
.cf-years-lg { font-size: 12.5px; color: var(--ink-soft); }
.cf-block { display: flex; flex-direction: column; gap: 9px; }
.cf-bio { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--ink); }

.cf-detail-row { display: flex; flex-direction: column; gap: 4px; }
.cf-detail-label { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); }
.cf-detail-value { font-size: 13px; color: var(--ink); line-height: 1.5; }
.cf-detail-chips { display: flex; flex-wrap: wrap; gap: 5px; }

.cf-loc-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.cf-loc-name { font-size: 13px; font-weight: 600; color: var(--ink); }
.cf-loc-sub { font-size: 11.5px; color: var(--ink-soft); }

/* Sideways strip, not a grid — a grid of two photos looks broken, and most
   coaches will have two. data-keep-scroll on the container preserves the
   scroll offset across the re-render (see renderCurrentView). */
.cf-gallery { display: flex; gap: 8px; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.cf-gallery-img { width: 128px; height: 96px; border-radius: 10px; object-fit: cover; flex-shrink: 0; }

.cf-contact { gap: 8px; }
.cf-contact .btn { display: flex; align-items: center; justify-content: center; gap: 7px; text-decoration: none; }
.cf-contact svg { width: 15px; height: 15px; }

/* Recedes deliberately. Nothing in here can be tapped, so at the same visual
   weight as the contact card above it, it competes with the buttons that DO
   work. Flat, borderless, no card shading. */
.cf-soon { background: transparent; border-style: dashed; box-shadow: none; }
.cf-soon-row {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 13px; color: var(--ink-soft); padding: 3px 0;
}
.cf-soon-tag {
  font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 20px;
  background: color-mix(in srgb, var(--ink) 6%, var(--white)); color: var(--ink-soft);
}

/* ---- enquiries ---- */
.cf-enq-list { display: flex; flex-direction: column; gap: 10px; }
.cf-enq { display: flex; flex-direction: column; gap: 9px; align-items: flex-start; }
.cf-enq-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; width: 100%; }
.cf-enq-date { font-size: 11.5px; color: var(--ink-soft); margin-top: 2px; }
.cf-status { flex-shrink: 0; font-size: 10.5px; font-weight: 700; padding: 3px 9px; border-radius: 20px; }
.cf-status--pending { background: #F6E2C6; color: #8A5216; }
.cf-status--contacted { background: var(--grass-light); color: var(--grass-dark); }
.cf-status--closed { background: color-mix(in srgb, var(--ink) 8%, var(--white)); color: var(--ink-soft); }

/* ---- registration ---- */
.cf-checks { display: flex; flex-wrap: wrap; gap: 7px; }
.cf-check {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  padding: 7px 11px; border: 1px solid var(--line); border-radius: 20px;
  font-size: 12.5px; color: var(--ink); background: var(--white);
}
.cf-check input { margin: 0; accent-color: var(--clay); }
.cf-textarea { resize: vertical; min-height: 96px; font-family: inherit; line-height: 1.55; }
.cf-coord-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.cf-coord-state { font-size: 11.5px; color: var(--ink-soft); flex: 1; min-width: 140px; line-height: 1.45; }

/* Status of the coach's own listing. Three states, three meanings — waiting is
   not the same as rejected, and neither is the same as "we need one more
   thing", which is why info_requested reads as amber and not red. */
.cf-banner {
  display: flex; flex-direction: column; gap: 3px;
  padding: 11px 13px; border-radius: 12px; border: 1px solid var(--line);
  font-size: 12.5px; line-height: 1.5; color: var(--ink-soft);
}
.cf-banner strong { font-size: 13px; color: var(--ink); }
.cf-banner--ok { background: var(--grass-light); border-color: color-mix(in srgb, var(--grass) 35%, var(--line)); }
.cf-banner--wait { background: #FDF4E3; border-color: #EBD8B4; }
.cf-banner--bad { background: color-mix(in srgb, var(--danger) 7%, var(--white)); border-color: color-mix(in srgb, var(--danger) 28%, var(--line)); }

/* ---- Pro (paid plan) marks ----
   Gold, and gold is spoken for in this app: it means PRIZE (.tqi-ic-gold,
   .draw-meta-chip-gold, the podium). Pro is the second thing it now means, and
   the two never appear on the same screen — a drawer entry and a pre-launch
   card are nowhere near a bracket's medallions — so they cannot be confused
   with each other.
   Was sky-blue and read "Soon". A launch-state tag and a plan badge are
   different claims: "Soon" expires the day the thing ships, PRO does not. */
.pro-tag {
  font-size: 10.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 20px;
  background: var(--gold-pro); color: var(--ink);
  flex-shrink: 0; line-height: 1.5;
}
/* .app-drawer-item--action right-aligns its badge, which is right for a COUNT
   (the Action Center's red number is a quantity, and quantities line up) and
   wrong for this one: PRO qualifies the name, so it reads as a label only while
   it sits against it. Same class, one property back. */
.app-drawer-item--pro { justify-content: flex-start; gap: 8px; }

/* ---- coming soon (pre-launch) ----
   Reads as a considered announcement rather than a broken page. One accent
   (the tag), one button, and generous line height — the whole screen is about
   40 words, so crowding it would be the only way to get this wrong. */
.cs-card { display: flex; flex-direction: column; gap: 12px; }
.cs-tag {
  align-self: flex-start;
  font-size: 10px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  padding: 4px 10px; border-radius: 20px;
  background: var(--sky-light); color: var(--sky-dark);
}
.cs-title { font-family: var(--font-display); font-size: 22px; line-height: 1.25; margin: 0; color: var(--ink); }
.cs-lede { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--ink-soft); }
.cs-list { margin: 2px 0 4px; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 9px; }
.cs-list li {
  position: relative; padding-left: 20px;
  font-size: 13px; line-height: 1.5; color: var(--ink);
}
/* A tick, not a bullet — these are things it will do, not a shopping list. */
.cs-list li::before {
  content: ""; position: absolute; left: 2px; top: 7px;
  width: 7px; height: 7px; border-radius: 50%; background: var(--clay);
}
.cs-done {
  display: flex; align-items: center; gap: 8px;
  padding: 11px 13px; border-radius: 12px;
  background: var(--grass-light); color: var(--grass-dark);
  font-size: 13px; font-weight: 600; line-height: 1.45;
}
.cs-done svg { width: 16px; height: 16px; flex-shrink: 0; }
.cs-foot { margin: 0; font-size: 11.5px; line-height: 1.55; color: var(--ink-soft); }

/* The Pro pair that brackets the button. No margins: .cs-card is a flex column
   with gap 12px, so both sit on the card's own rhythm rather than introducing a
   second spacing system beside it — which is also why adding them moved nothing
   else on either page. */
.cs-pro {
  align-self: center;
  font-size: 10.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  padding: 4px 10px; border-radius: 20px;
  background: var(--gold-pro); color: var(--ink);
}
.cs-pro-note {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  margin: 0; font-size: 12.5px; font-weight: 600; color: var(--gold-pro-ink);
}
.cs-pro-note svg { width: 13px; height: 13px; flex-shrink: 0; }


/* ---- admin review modal ---- */
.ac-rev { display: flex; flex-direction: column; gap: 9px; margin-bottom: 12px; }
.ac-rev-row { display: flex; flex-direction: column; gap: 2px; }
.ac-rev-label { font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); }
.ac-rev-value { font-size: 13px; color: var(--ink); line-height: 1.5; word-break: break-word; }
.ac-rev-bio {
  font-size: 12.5px; line-height: 1.6; color: var(--ink); padding: 10px 12px;
  border-radius: 10px; background: color-mix(in srgb, var(--ink) 4%, var(--white));
}
.ac-rev-verify { width: 100%; margin-bottom: 10px; }

/* ---- Kross Pro (player membership) ----
   The header button sits under Share Profile Card and borrows that button's
   whole shape — same class, same height, same radius — so the two stack as a
   matched pair rather than one control and one advert. Gold is the Pro colour
   already established by .pro-tag on the drawer and the pre-launch cards; this
   adds no new hue. */
.profile-header-actions {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  flex-shrink: 0;
}
.player-share-card-btn-pro {
  background: var(--gold-pro);
  border-color: color-mix(in srgb, var(--gold-pro) 70%, var(--ink));
  color: var(--ink);
  font-weight: 800;
}
.player-share-card-btn-pro svg { width: 14px; height: 14px; }
@media (hover: hover) {
  .player-share-card-btn-pro:hover { background: color-mix(in srgb, var(--gold-pro) 85%, var(--ink)); }
}
/* Already a member, or waiting on an admin — a statement, not a control, so it
   is deliberately not button-shaped. */
.pro-member-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border-radius: 20px;
  background: color-mix(in srgb, var(--gold-pro) 18%, var(--white));
  border: 1px solid color-mix(in srgb, var(--gold-pro) 45%, transparent);
  font-size: 11.5px;
  font-weight: 700;
  color: var(--gold-pro-ink);
  white-space: nowrap;
}
.pro-member-chip--wait {
  background: color-mix(in srgb, var(--ink) 5%, var(--white));
  border-color: var(--line);
  color: var(--ink-soft);
}
/* On a phone the header stacks, and two full-width buttons read better than
   two shrink-wrapped ones sitting off to one side. */
@media (max-width: 560px) {
  .profile-header-actions { width: 100%; }
  .profile-header-actions > * { width: 100%; justify-content: center; }
}
