/* Nova Tournaments & Leagues — brand book palette on a light ground.
   Deep green primary, lime accent (≤25%, never on white), light gray ground, ink text.
   Barlow Semi Condensed 800 uppercase for headings, Inter for body. */
:root {
  --ink:#1B1B1B; --deep:#2E5644; --court:#1B3A2D; --lime:#D8FF3F; --gray:#ECEFF0; --chalk:#FFFFFF;
  --paper:#F4F6F2; --muted:#5E6B64; --line:#DCE2DE; --tint:#E4EFE8; --coral:#FF6A3D; --coral-tint:#F9E3DB;
  --r:16px;
}
* { box-sizing:border-box; }
html { -webkit-text-size-adjust:100%; }
/* Ink, not paper: this colour is what the phone paints behind the status bar
   and behind its own toolbar, so it has to be the colour those strips should
   be. The pages themselves get their light ground from <main> below. */
html { background:var(--paper); }
body { margin:0; background:var(--paper); color:var(--ink); font:16px/1.55 Inter, system-ui, -apple-system, sans-serif; }
/* Only the tournament pages paint the canvas dark. They open on a hero that
   has to run past the top and bottom of the screen, and a light canvas showed
   as a pale band above and below it when the page was pulled about. But this
   stylesheet is shared — the waiver, the family account and the print sheet
   all load it — and several of those have no <main> of their own, so a dark
   canvas there meant near-black text on a near-black page. It did, for most
   of 10 September 2026, and the waiver is the first thing a new family ever
   opens. The dark is opt-in now, and only the tournament shell opts in. */
html.t-ink, html.t-ink body { background:var(--ink); }
/* A short page — the waiver's two choices, a thank-you, an error — used to
   leave the dark footer stranded halfway down with a pale strip under it.
   The footer takes the slack instead, so every page ends where the screen
   ends and there is never a band below the last thing on it. */
body { display:flex; flex-direction:column; min-height:100vh; min-height:100dvh; }
.foot { margin-top:auto; }
a { color:var(--deep); }
img { max-width:100%; }
/* Measured off the academy site so the two read as one place: same measure,
   same gutters, same section rhythm, same heading scale. */
.wrap { width:100%; max-width:1280px; margin-inline:auto; padding-inline:20px; }
@media (min-width: 640px) { .wrap { padding-inline:32px; } }
@media (min-width: 1024px) { .wrap { padding-inline:48px; } }

/* type */
.h, .h2, .h3, .num-big { font-family:"Barlow Semi Condensed", "Arial Narrow", sans-serif; font-weight:800; text-transform:uppercase; line-height:.95; letter-spacing:.005em; margin:0; }
.h { font-size:clamp(44px, 6.5vw, 84px); line-height:.9; letter-spacing:-.02em; color:var(--court); text-wrap:balance; }
.h2 { font-size:40px; font-weight:700; line-height:.9; letter-spacing:-.02em; color:var(--court); text-wrap:balance; }
@media (min-width: 640px) { .h2 { font-size:56px; } }
@media (min-width: 1024px) { .h2 { font-size:72px; } }
.h3 { font-size:24px; color:var(--deep); margin-bottom:10px; }
.eyebrow { margin-bottom:12px; font:600 11px/1.5 inherit; letter-spacing:.2em; text-transform:uppercase; opacity:.7; }
@media (min-width: 1024px) { .eyebrow { font-size:12px; } }
.lead { font-size:18px; line-height:1.55; max-width:62ch; color:#3d4a44; margin:12px 0 0; }
.muted { color:var(--muted); }
.script { font-family:Caveat, cursive; font-size:24px; color:var(--deep); }
.num { font-variant-numeric:tabular-nums; }
.up { color:#2E8B57; font-weight:700; } .down { color:#C0392B; font-weight:700; }
.right { text-align:right !important; }
.gap-top { margin-top:28px; }

/* header: court-deep with the white logo, and the site's own sub-navigation */
/* The bar rides over the hero photo until the page moves, the same way the
   academy's front page does — there on the phone as well as on the desktop.
   Only where a hero is actually underneath it: over a white page a transparent
   bar would hide its own white links, so the script below adds .nav-over only
   when the first thing in <main> is the hero. */
/* Measured off the academy bar so the two are the same object: 16px of padding
   round a 44px-tall row, a 1440 box centred in it, the wordmark hard against the
   left edge. Click through to the tournament and only the logo and the links
   change — nothing moves. */
.nav { background:var(--deep); color:var(--chalk); position:sticky; top:0; z-index:60; padding:16px; transition:background .2s ease, backdrop-filter .2s ease, box-shadow .2s ease; }
/* iOS and the bar at the top of the screen.
   -------------------------------------------------------------------------
   Safari resolves position:sticky against the LAYOUT viewport and does not
   move a sticky element during momentum scrolling, so a strip of page appears
   ABOVE the bar and it reads as "the frame is stuck and the page is climbing
   over it". Chromium never shows it: measured at scrollY 0/300/900 the bar is
   at top:0 every time.

   Two answers, because the first one alone was not enough on a real iPhone:

   1. The bar paints its own colour a screenful upwards, as a hard-edged box
      shadow. A shadow is part of the element's own box decoration, so it is
      composited with the bar and moves with it. An absolutely positioned
      child was tried first and iOS did not draw it — off-screen at rest, it
      never made it into the scrolling layer.
   2. Where the bar does not have to float over a hero photo — the family
      cabinet and the waiver, which is where this was actually reported — it
      is taken out of the flow entirely. A fixed element is pinned to the
      VISUAL viewport on iOS, so nothing can appear above it at all. The space
      it used to occupy is given back as padding on the body, which reproduces
      the previous layout exactly, negative-margin hero and all. */
.nav { box-shadow: 0 -100vh 0 0 var(--deep); }
body.fixed-nav { padding-top: var(--navh, 76px); }
/* Anything the browser scrolls to itself — a missed required field, an #anchor
   — used to land underneath the fixed bar, its own label off the top of the
   screen, so the "please fill this in" bubble appeared to point at the next
   field down. */
html { scroll-padding-top: 96px; }
body.fixed-nav .nav { position: fixed; top: 0; left: 0; right: 0; }
/* Over a hero the bar is transparent on purpose, and a green sheet above it
   would be worse than the thing it fixes. */
body.nav-over .nav { box-shadow: none; }
/* The tournament puts the test banner ABOVE the bar, so it has to sit above
   the cover too. */
.staging { position:relative; z-index:61; }
/* Lifted out of the flow by pulling <main> up under the whole chrome, rather
   than by dragging the hero up: --chromeh is the bar plus the strip beneath it
   (0 tall on a wide screen), so anything ABOVE the bar — the test banner — keeps
   its own place instead of showing as a pale line across the top. */
body.nav-over main { margin-top:calc(-1 * var(--chromeh, 76px)); }
body.nav-over .nav, body.nav-over .subnav { background:transparent; }
/* The strip has no place of its own in the paint order, so once <main> is
   pulled up under it the hero paints straight over its links. */
body.nav-over .subnav { border-bottom-color:transparent; position:relative; z-index:59; }
body.nav-over .subnav a { color:rgba(255,255,255,.85); }
body.nav-over .subnav a.on { color:var(--lime); border-bottom-color:var(--lime); }
body.nav-over .subnav .back, body.nav-over .subnav .nav-out { color:rgba(255,255,255,.85) !important; border-color:rgba(255,255,255,.28); }
body.nav-over .subnav-lead { border-bottom-color:rgba(255,255,255,.18); }
body.nav-over.is-scrolled .nav { background:rgba(46,86,68,.8); backdrop-filter:blur(24px); -webkit-backdrop-filter:blur(24px); box-shadow:0 1px 0 0 rgba(255,255,255,.08); }
.nav-in { max-width:1440px; margin:0 auto; display:flex; align-items:center; justify-content:space-between; gap:20px; }
.brand { display:inline-flex; }
.brand img { height:44px; display:block; }   /* same 246x92 artboard as the academy wordmark, so the same height puts NOVA in the same place */
.nav-links { display:flex; gap:28px; font-weight:400; font-size:14px; line-height:30px; align-items:center; }
.subnav-links { display:contents; }
.nav-links a { color:rgba(255,255,255,.75); text-decoration:none; } .nav-links a:hover { color:#fff; } .nav-links a.on { color:var(--lime); }
/* The way back to the academy is not a page of this site, so it is not one of
   the tabs: quieter, boxed, and last. */
.nav-out { margin-right:6px; display:inline-flex; align-items:center; min-height:36px; padding:0 16px; background:rgba(255,255,255,.1); border:1px solid rgba(255,255,255,.2); border-radius:999px; font-size:12px; font-weight:500; letter-spacing:.24px; color:rgba(255,255,255,.9) !important; white-space:nowrap; }
.subnav .nav-out { background:transparent; color:var(--muted) !important; border-color:var(--line); align-self:center; }
.nav-right { display:flex; align-items:center; gap:12px; }
/* The two pills on the right are the academy pair: a lime-tinted call to action
   and a quieter white-tinted one, both 36px on the same baseline. */
/* Inter, not the condensed shouting face the buttons use elsewhere: in the bar
   the academy sets 'Pay & book' in 13px semibold, and this pill is its twin. */
.nav-right .btn { min-height:36px; padding:0 20px; font:600 13px/1 Inter, system-ui, sans-serif; letter-spacing:.52px; text-transform:none; }
.nav-right .btn-lime { background:rgba(216,255,63,.15); border-color:rgba(216,255,63,.5); color:#fff; }
.nav-right .btn-lime:hover { background:rgba(216,255,63,.3); filter:none; }
.pill-user { display:inline-flex; align-items:center; gap:8px; background:rgba(255,255,255,.1); border:1px solid rgba(255,255,255,.2); color:var(--chalk); border-radius:999px; padding:0 16px; text-decoration:none; font-weight:500; font-size:12px; letter-spacing:.24px; min-height:36px; }
/* The other two sites, in the academy's own pill. Same shape as .pill-user
   beside it, so the bar reads as one row of doors rather than a link and two
   buttons. Under 600px the label goes and the icon stays, exactly as the
   academy header does it. */
.pill-game { display:inline-flex; align-items:center; gap:8px; background:rgba(255,255,255,.1); border:1px solid rgba(255,255,255,.2); color:var(--chalk); border-radius:999px; padding:0 16px; text-decoration:none; font-weight:500; font-size:12px; letter-spacing:.24px; min-height:36px; white-space:nowrap; }
.pill-game:hover { background:rgba(255,255,255,.2); }
.pill-game img { display:block; width:18px; height:18px; flex:0 0 auto; }
@media (max-width: 600px) { .pill-game { padding:0 11px; } }
@media (max-width: 760px) { .pill-game { min-height:44px; } }
.nav-long { display:inline; }
@media (max-width: 600px) { .nav-long { display:none; } }
.subnav { background:var(--chalk); border-bottom:1px solid var(--line); }
.subnav-in { max-width:1440px; margin:0 auto; padding:0 16px; display:flex; align-items:center; gap:4px; min-width:0; }
.subnav a { padding:13px 14px; font-weight:600; font-size:14.5px; color:var(--muted); text-decoration:none; border-bottom:3px solid transparent; white-space:nowrap; }
.subnav a.on { color:var(--court); border-bottom-color:var(--deep); }
.subnav .back { margin-right:auto; color:var(--deep); display:inline-flex; align-items:center; gap:6px; }
.staging { background:#C0392B; color:#fff; text-align:center; font-size:13px; padding:6px; }
/* The same ink as the page behind it, so the strip the phone paints under the
   footer is the footer — exactly how the academy's own footer works. */
.foot { padding:26px 40px; display:flex; justify-content:space-between; gap:20px; flex-wrap:wrap; font-size:14px; color:rgba(255,255,255,.72); background:var(--ink); }
.foot a { color:rgba(255,255,255,.9); }
.foot img { height:26px; opacity:.9; }

/* sections */
.section { padding-block:64px; }
@media (min-width: 1024px) { .section { padding-block:120px; } }
.section-light { background:var(--chalk); border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
/* Eyebrow over a display heading, with any "see them all" link dropping to
   the end of the row — the academy's own arrangement. */
.section-head { display:flex; align-items:flex-end; justify-content:space-between; gap:16px 24px; flex-wrap:wrap; margin-bottom:40px; }
.section-head > div:first-child { min-width:0; }
.section-head .eyebrow { margin-bottom:8px; }
@media (min-width: 1024px) { .section-head { margin-bottom:56px; } }
/* ---- hero: the academy's, to the same measurements ------------------ */
.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100lvh;
  display: flex;
  align-items: center;
  /* The tournament's own photo — tennis on one side of the net, pickleball on
     the other — instead of borrowing the academy's serve. Each of the three
     now has its own: tennis, pickleball, tournament.
     The veil over it is the academy's, to the number: ink black at 85% at the
     top, 72% across the middle, 88% at the foot. It used to be rgb(12,18,10),
     which is green, and that green over a green court is what made the two
     sites look like different brands.
     Two declarations on purpose: a browser that does not know image-set()
     keeps the jpg line above it. */
  background-color: var(--deep);
  background-image: linear-gradient(rgba(27,27,27,.85) 0%, rgba(27,27,27,.72) 50%, rgba(27,27,27,.88) 100%),
                    url('/tournament/assets/tournament-hero-1600.jpg');
  background-image: linear-gradient(rgba(27,27,27,.85) 0%, rgba(27,27,27,.72) 50%, rgba(27,27,27,.88) 100%),
                    image-set(url('/tournament/assets/tournament-hero-1600.webp') type('image/webp'),
                              url('/tournament/assets/tournament-hero-1600.jpg') type('image/jpeg'));
  background-position: center center;
  background-size: cover;
  background-repeat: no-repeat;
  color: var(--chalk);
  /* The bar floats over the hero, so the top of the box is under it: reserve
     exactly its height (the script in View::foot measures it) and centre what
     is left in what the reader can actually see. */
  /* Not dead centre. On a wide screen the block is lifted by leaving more room
     under it than over it; on a phone there is not enough screen for that to
     work, so it is simply hung from under the bar at a fixed drop — which is
     where the academy's own hero starts. */
  align-items: flex-start;
  padding: calc(var(--chromeh, 76px) + 45px) 0 40px;
}
@media (min-width: 1024px) {
  /* The same arithmetic the academy uses, so the block lands on the same line
     rather than near it. Over there the hero is one screen less the bar and
     the content is centred in what is left, with 40px of air top and bottom.
     Ours was one whole screen with 152px of padding at each end, which left so
     little room that the content stopped centring and simply sat where the
     padding put it — pinned at y542 on every laptop between 789 and 900 tall
     while the academy went on moving with the screen. */
  /* 168px of padding in total, which is what the academy spends, so the hero
     runs out of room for centring at the same screen height it does — ours was
     spending 236 and started pinning the block 68px of screen earlier. */
  /* Tuned against the live academy, not the test copy: the test copy carries a
     red banner above the page that pushed this block 32px down and made the
     numbers look right here while being 32px out where it matters. */
  .hero { align-items: center; padding: calc(var(--chromeh, 76px) + 59px) 0 54px; }
}
/* A short phone — an iPhone SE is 667px tall — cannot hold the hero at full
   size. Everything comes down a notch so it is still ONE screen there, rather
   than one screen and a slice of the next section. */
@media (max-height: 700px) {
  .hero { padding: calc(var(--chromeh, 76px) + 16px) 0 24px; }
  .hero-h span { font-size: 32px; }
  /* The heading already says what this is; on a screen this short the line
     under it is the first thing that can go. */
  .hero-lead { display: none; }
  .hero-row { margin-top: 14px; gap: 12px; }
  .board-cell { width: 36px; height: 54px; font-size: 44px; border-radius: 5px; }
  .board-plus { font-size: 24px; }
  .board-label { margin-top: 6px; }
  .hero-stats b { font-size: 28px; }
  .hero-cta { margin-top: 16px; gap: 8px; }
  .btn-hero { height: 48px; }
  .btn-hero-ghost { height: 44px; }
}
.hero-in { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 0; }
.hero-eyebrow { margin: 0 0 12px; font-weight: 500; font-size: 12px; letter-spacing: .18em; text-transform: uppercase; color: rgba(255,255,255,.55); }
@media (min-width: 640px) { .hero-eyebrow { font-size: 13px; } }

/* The one italic on either site: the academy sets its headline this way and
   nothing else, so it is the single strongest signal that this is the same
   place. Upright everywhere below. */
.hero-h { margin: 0; font-family: "Barlow Semi Condensed", "Arial Narrow", sans-serif; font-weight: 800; font-style: italic; letter-spacing: -.015em; line-height: .95; text-transform: none; }
.hero-h span { display: block; font-size: 38px; }
.hero-h .hero-h2 { color: var(--lime); }
@media (min-width: 640px) { .hero-h span { font-size: 56px; } }
@media (min-width: 1024px) { .hero-h span { font-size: 72px; } }
@media (min-width: 1536px) { .hero-h span { font-size: 88px; } }

.hero-lead { margin: 16px auto 0; max-width: 320px; font-weight: 600; font-size: 18px; line-height: 1.3; color: var(--chalk); }
/* Hidden on a phone, as it is on the academy's own hero: one screen is one
   screen, and the levels are repeated three lines further down the page. */
.hero-sub { display: none; margin: 8px auto 0; max-width: 320px; font-size: 15px; line-height: 1.5; color: rgba(255,255,255,.8); }
@media (min-width: 1024px) {
  .hero-lead { margin-top: 24px; max-width: 560px; font-size: 22px; }
  .hero-sub { display: block; max-width: 560px; font-size: 18px; }
}

.hero-row { display: flex; flex-direction: column-reverse; align-items: center; gap: 20px; width: 100%; margin-top: 24px; }
@media (min-width: 1024px) { .hero-row { flex-direction: row; justify-content: space-between; gap: 40px; margin-top: 44px; } }

/* On a wide screen the academy does NOT centre its hero text. The column is
   880px wide and sits against the right-hand side, because the photo behind it
   is a player mid-serve on the left and text over a face reads badly. The
   tournament hero was centred instead, which is why the two sites look like
   two sites on a computer while matching on a phone.
   The sum is the academy's own: its outer box stops at 1440 (1680 from the
   2xl breakpoint), is inset 20px, and the column keeps a further 60px off the
   right edge — 80px in total, plus half of whatever the screen has spare. */
@media (min-width: 1024px) {
  .hero-in {
    max-width: 880px;
    margin-left: auto;
    margin-right: calc(60px + max(20px, (100vw - 1680px) / 2));
    padding-inline: 0;
  }
}
@media (min-width: 1536px) {
  /* The academy widens the column and drops the extra inset at this size. */
  .hero-in { max-width: 1040px; }
}

.hero-stats { display: grid; grid-template-columns: repeat(3, 1fr); list-style: none; margin: 0; padding: 0; width: 100%; }
/* Each item centred its own content, so a label that wrapped to two lines
   lifted its number above the other two. Aligned to the top, the numbers sit
   on one line whatever the labels do. */
.hero-stats li { display: flex; flex-direction: column; justify-content: flex-start; align-items: center; min-height: 56px; padding: 0 8px; }
.hero-stats li + li { border-left: 1px solid rgba(255,255,255,.25); }
.hero-stats b { font: 800 34px/.9 "Barlow Semi Condensed", sans-serif; color: var(--chalk); font-variant-numeric: tabular-nums; }
.hero-stats span { margin-top: 8px; max-width: 150px; font-weight: 600; font-size: 11px; letter-spacing: .14em; text-transform: uppercase; line-height: 1.2; color: rgba(255,255,255,.75); }
@media (min-width: 1024px) {
  .hero-stats { display: flex; flex: 1; width: auto; }
  .hero-stats li { align-items: flex-start; min-height: 72px; padding: 0 40px; }
  .hero-stats li:first-child { padding-left: 0; }
  .hero-stats b { font-size: 52px; }
  .hero-stats span { font-size: 13px; }
}

/* The scoreboard: ink cells with one figure each, the academy's own. It does
   not flip here — there is nothing to flip from on a page that is loaded once
   and read. */
.hero-board { display: flex; flex-direction: column; align-items: center; flex-shrink: 0; }
@media (min-width: 1024px) { .hero-board { align-items: flex-end; } }
.board { display: inline-flex; align-items: flex-end; gap: 4px; }
.board-cell {
  display: flex; align-items: center; justify-content: center;
  width: 48px; height: 80px; border-radius: 6px;
  background: var(--ink); box-shadow: inset 0 0 0 1px rgba(255,255,255,.24);
  font: 700 64px/1 "Barlow Semi Condensed", sans-serif; color: var(--chalk);
}
.board-plus { margin-left: 4px; font: 700 32px/1 "Barlow Semi Condensed", sans-serif; color: var(--lime); }
.board-label { margin: 10px 0 0; font-weight: 600; font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: rgba(255,255,255,.7); }
@media (min-width: 1024px) {
  .board { gap: 6px; }
  .board-cell { width: 72px; height: 120px; font-size: 96px; }
  .board-plus { font-size: 48px; }
  .board-label { font-size: 12px; }
}

.hero-cta { display: flex; flex-direction: column; align-items: center; gap: 10px; width: 100%; margin-top: 24px; }
.btn-hero, .btn-hero-ghost {
  display: inline-flex; align-items: center; justify-content: center;
  width: 100%; max-width: 340px; border-radius: 999px; text-decoration: none;
  text-align: center; white-space: nowrap;
}
.btn-hero {
  height: 52px; padding: 0 36px; background: var(--lime); color: #0d1206;
  font: 700 16px/1 Inter, sans-serif; font-style: italic; text-transform: uppercase; letter-spacing: .04em;
  box-shadow: 0 8px 24px rgba(0,0,0,.28);
}
.btn-hero:hover { background: var(--chalk); }
.btn-hero-ghost {
  height: 48px; padding: 0 36px; background: rgba(255,255,255,.1);
  border: 1px solid rgba(255,255,255,.6); color: var(--chalk);
  font: 600 15px/1 Inter, sans-serif; letter-spacing: .01em;
}
.btn-hero-ghost:hover { background: rgba(255,255,255,.2); }
.hero-link { font-weight: 500; font-size: 14px; color: rgba(255,255,255,.6); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }
.hero-link:hover { color: rgba(255,255,255,.9); }
@media (min-width: 640px) { .btn-hero { height: 56px; } }


/* buttons & pills */
.btn { display:inline-flex; align-items:center; justify-content:center; gap:8px; border-radius:999px; padding:0 22px; min-height:48px; font:700 14px "Barlow Semi Condensed", sans-serif; letter-spacing:.06em; text-transform:uppercase; text-decoration:none; border:1.5px solid transparent; cursor:pointer; }
.btn-sm { min-height:38px; padding:0 16px; font-size:13px; }
.btn-lime { background:var(--lime); color:var(--ink); } .btn-lime:hover { filter:brightness(.96); }
.btn-green { background:var(--deep); color:var(--chalk); } .btn-green:hover { background:var(--court); }
.btn-white { background:var(--chalk); color:var(--court); } .hero .btn-white { border-color:transparent; }
.btn-ghost { background:transparent; color:var(--deep); border-color:#B8C6BE; } .btn-ghost:hover { background:var(--tint); }
/* The quiet one. A button that undoes something must be findable and must not
   be the thing the eye lands on: no border, no fill, muted until hovered.
   Marco Calderon withdrew from a pair two minutes after joining it because
   "Withdraw" was the only button his entry had while his rating was being
   confirmed — it looked like the way forward. */
.btn-quiet { background:transparent; color:#6B7C72; border-color:transparent; font-weight:600; }
.btn-quiet:hover { background:transparent; color:var(--deep); text-decoration:underline; }
.btn[disabled] { opacity:.5; cursor:not-allowed; }
.pill { display:inline-flex; align-items:center; border-radius:999px; padding:4px 11px; font:700 11.5px "Barlow Semi Condensed", sans-serif; letter-spacing:.08em; text-transform:uppercase; white-space:nowrap; }
.band-beginner { background:var(--gray); color:var(--court); } .band-intermediate { background:var(--deep); color:var(--chalk); } .band-advanced { background:var(--court); color:var(--lime); } .band-open { background:var(--tint); color:var(--deep); }
.status-open { background:var(--tint); color:var(--deep); } .status-pending { background:#FBF1E6; color:#8A4B1F; } .status-paid { background:var(--deep); color:var(--chalk); } .status-unpaid { background:var(--coral-tint); color:#9A3C1C; } .status-done { background:var(--gray); color:var(--muted); }
.pill-kind { background:rgba(255,255,255,.16); color:var(--chalk); }

/* cards */
.card { border-radius:var(--r); padding:22px 24px; }
.card-white { background:var(--chalk); border:1px solid var(--line); border-radius:var(--r); padding:22px 24px; }
.card-green { background:var(--deep); color:var(--chalk); } .card-green .eyebrow { color:var(--lime); } .card-green .muted { color:rgba(255,255,255,.72); }
.card-coral { background:var(--coral-tint); color:#7A3B22; }
.grid-2 { display:grid; grid-template-columns:1fr 1fr; gap:28px; } .grid-3 { display:grid; grid-template-columns:repeat(3, 1fr); gap:24px; }
.nextcard { display:flex; align-items:center; justify-content:space-between; gap:16px; padding:20px 24px; }

/* event card */
/* The event card is the academy's programme card: the photo attached to the
   event fills the whole frame, one scrim lifts the words off it, and the facts
   sit along the foot. An event with no photo keeps the same frame on deep
   green — the shape never changes, only what is behind it. */
.ecard { position:relative; display:flex; overflow:hidden; border-radius:12px; background:var(--court); color:var(--chalk); text-decoration:none; min-height:380px; }
@media (min-width: 1024px) { .ecard { border-radius:16px; aspect-ratio:4/5; min-height:0; } }
.ecard-photo { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:50% 35%; transition:transform .5s ease; }
.ecard:hover .ecard-photo { transform:scale(1.03); }
.ecard-scrim { position:absolute; inset:0; background:linear-gradient(to top, rgba(27,58,45,.95) 0%, rgba(27,58,45,.7) 50%, rgba(27,58,45,.2) 100%); }
.ecard-body { position:relative; align-self:flex-end; width:100%; padding:20px; display:flex; flex-direction:column; }
@media (min-width: 1024px) { .ecard-body { padding:24px; } }
.ecard-tags { display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-bottom:12px; }
.ecard-name { font-family:"Barlow Semi Condensed", "Arial Narrow", sans-serif; font-weight:800; font-size:26px; line-height:.95; letter-spacing:-.01em; text-transform:uppercase; color:var(--chalk); margin:0; overflow-wrap:anywhere; }
@media (min-width: 1024px) { .ecard-name { font-size:30px; } }
.ecard-facts { display:grid; grid-template-columns:auto 1fr; gap:6px 16px; margin:12px 0 0; font-size:14px; line-height:1.35; }
.ecard-facts dt { color:rgba(255,255,255,.65); }
.ecard-facts dd { margin:0; color:rgba(255,255,255,.92); overflow-wrap:anywhere; }
.ecard-facts dd b { color:var(--chalk); font-weight:600; }
.ecard-go { margin-top:16px; display:inline-flex; align-items:center; gap:8px; font-size:14px; font-weight:600; color:var(--lime); }
.ecard:hover .ecard-go { text-decoration:underline; }
/* On the card the pills sit on a photo, so they carry their own ground. */
.ecard .pill-kind { background:rgba(255,255,255,.16); color:var(--chalk); }
.ecard .band { background:rgba(255,255,255,.16); color:var(--chalk); }

/* filters */
.filters { display:flex; gap:12px; flex-wrap:wrap; align-items:center; margin-bottom:18px; }
.seg { display:inline-flex; background:var(--gray); border-radius:999px; padding:4px; gap:2px; flex-wrap:wrap; }
.seg a { color:var(--ink); font-weight:600; font-size:14px; padding:8px 14px; border-radius:999px; text-decoration:none; min-height:36px; display:inline-flex; align-items:center; }
.seg a.on { background:var(--court); color:var(--lime); }
.toggle-link { font-size:14px; }

/* tables */
.tablewrap { overflow-x:auto; border-radius:var(--r); border:1px solid var(--line); background:var(--chalk); }
table.t { width:100%; border-collapse:collapse; font-size:15px; }
table.t th, table.t td { padding:12px 14px; text-align:left; border-bottom:1px solid var(--line); vertical-align:middle; }
table.t thead th { font:700 12px "Barlow Semi Condensed", sans-serif; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); background:var(--paper); }
table.t tbody tr:last-child td { border-bottom:0; }
table.t tr.me td { background:#F3FBD4; }
table.t.t-sm th, table.t.t-sm td { padding:8px 10px; font-size:14px; }
.rating { font:800 20px "Barlow Semi Condensed", sans-serif; color:var(--court); white-space:nowrap; } .rating small { font:600 12.5px Inter, sans-serif; color:var(--muted); margin-left:4px; }
.rating-lg { font-size:34px; line-height:1; }
.pchip { display:inline-flex; align-items:center; gap:8px; color:inherit; text-decoration:none; } .pname { font-weight:600; } .prating { font-size:12.5px; color:var(--muted); font-variant-numeric:tabular-nums; }
.teamline { display:inline-flex; gap:14px; flex-wrap:wrap; align-items:center; }
.avatar { display:inline-flex; align-items:center; justify-content:center; border-radius:999px; background:var(--deep); color:var(--chalk); font:700 14px "Barlow Semi Condensed", sans-serif; overflow:hidden; flex:none; }
.flag { vertical-align:middle; border-radius:2px; flex:none; } .flag-emoji { font-size:18px; line-height:1; }
.gicon { color:var(--muted); vertical-align:middle; }

/* player card */
.pcard { display:flex; justify-content:space-between; gap:24px; flex-wrap:wrap; align-items:center; }
.pcard-id { display:flex; gap:20px; align-items:center; } .pcard-meta { display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin:8px 0; }
.pcard-stats { display:flex; gap:12px; flex-wrap:wrap; }
.stat { background:var(--chalk); border:1px solid var(--line); border-radius:var(--r); padding:14px 18px; min-width:120px; display:flex; flex-direction:column; }
.stat b { font:800 32px/1 "Barlow Semi Condensed", sans-serif; color:var(--court); } .stat b small { font-size:16px; color:var(--muted); }
.stat span { font-size:11.5px; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); margin-top:5px; }
.lock { display:flex; gap:8px; align-items:flex-start; color:var(--muted); }

/* match rows and history */
.mlist { display:flex; flex-direction:column; gap:8px; }
.mrow { display:grid; grid-template-columns:200px 1fr auto; gap:16px; align-items:center; background:var(--chalk); border:1px solid var(--line); border-radius:14px; padding:12px 16px; }
.mrow-when { display:flex; flex-direction:column; font-weight:600; font-size:14px; color:inherit; text-decoration:none; } .mrow-when .muted { font-weight:500; font-size:12.5px; }
.mrow-who { display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
.mrow-res { display:flex; gap:8px; align-items:center; white-space:nowrap; }
.hist td .delta { font-weight:700; } .hist .arrow { color:var(--muted); }

/* event page */
.eventhead { display:grid; grid-template-columns:1.2fr 1fr; gap:32px; align-items:center; }
.eventhead .photo { border-radius:var(--r); min-height:260px; background:var(--deep) center/cover; color:var(--chalk); }
.facts { display:grid; grid-template-columns:repeat(2, 1fr); gap:12px 20px; margin:16px 0; } .facts div { display:flex; flex-direction:column; }
.facts small { font-size:11.5px; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); } .facts b { font-size:17px; }
.hero .facts small { color:rgba(255,255,255,.7); } .hero .facts .muted { color:rgba(255,255,255,.75); }
.tabs { display:flex; gap:4px; border-bottom:1px solid var(--line); margin:8px 0 24px; overflow-x:auto; }
.tabs a { padding:12px 16px; color:var(--muted); text-decoration:none; font-weight:600; border-bottom:3px solid transparent; white-space:nowrap; } .tabs a.on { color:var(--court); border-bottom-color:var(--deep); }
.bracket { overflow-x:auto; background:var(--chalk); border:1px solid var(--line); border-radius:var(--r); padding:16px; }
/* minmax(340px, 1fr) means "never narrower than 340" — including on a screen
   that is only 320 wide, where the track then sticks out and drags the whole
   page sideways. min() makes the floor "340, or the width we actually have,
   whichever is smaller", which is what was meant all along. */
.poolgrid { display:grid; grid-template-columns:repeat(auto-fit, minmax(min(340px, 100%), 1fr)); gap:20px; }
.matchvs { display:grid; grid-template-columns:1fr auto 1fr; gap:20px; align-items:center; text-align:center; padding:20px 0; }
/* The score sits on white. Lime on white (#D8FF3F) is the brand's own "never" —
   it read as a glowing blank on a phone in daylight. Deep green carries it. */
.matchvs .vs { font:800 28px "Barlow Semi Condensed", sans-serif; color:var(--court); font-variant-numeric:tabular-nums; }
.matchvs .side { display:flex; flex-direction:column; gap:8px; align-items:center; min-width:0; } .matchvs .side.won { outline:2px solid var(--deep); outline-offset:10px; border-radius:12px; }
.matchvs > * { min-width:0; } .matchvs .pchip { max-width:100%; flex-wrap:wrap; justify-content:center; } .matchvs .pname { overflow-wrap:anywhere; }

/* forms */
.form { display:flex; flex-direction:column; gap:14px; max-width:560px; } .form-wide { max-width:none; }
.form-row { display:grid; grid-template-columns:1fr 1fr; gap:14px; } .form-row > * { min-width:0; }
.field { display:flex; flex-direction:column; gap:6px; } .field label { font-size:13px; font-weight:600; color:#3d4a44; }
/* Text boxes only. A tick and a radio are not text boxes, and this rule used
   to catch them too: on the waiver's "any medical conditions?" the two circles
   were handed width:100% and height:48px, came out 626px wide, and pushed
   their own words onto the next line. The waiver carried a patch for it — but
   only inside a max-width:680px block, so it was right on a phone and wrong on
   every computer, which is exactly how it went unnoticed. */
.field input:not([type=radio]):not([type=checkbox]), .field select, .field textarea { height:48px; border-radius:12px; border:1px solid #C9D3CD; background:var(--chalk); color:var(--ink); padding:0 14px; font:inherit; font-size:16px; width:100%; min-width:0; }
.field input[type=radio], .field input[type=checkbox] { width:20px; height:20px; flex:0 0 20px; margin:0; accent-color:var(--deep); }
/* The word sits beside its circle, on one line, with room to be tapped. */
.field label.checkbox-inline, .field .checkbox-inline { display:flex; align-items:center; gap:10px; min-height:32px; width:auto; cursor:pointer; }
.field textarea { height:auto; padding:12px 14px; }
.field input:focus, .field select:focus, .field textarea:focus { outline:2px solid var(--deep); outline-offset:1px; }
.field .hint { font-size:12.5px; color:var(--muted); font-weight:400; }
.err { background:var(--coral-tint); color:#9A3C1C; border-radius:12px; padding:12px 16px; font-weight:600; }
.ok { background:var(--tint); color:var(--court); border-radius:12px; padding:12px 16px; font-weight:600; }
.radio-row { display:flex; gap:12px; flex-wrap:wrap; align-items:flex-start; font-weight:500; min-height:44px; } .radio-row input { margin-top:5px; }
.sets { display:flex; gap:12px; flex-wrap:wrap; } .sets .set { display:flex; flex-direction:column; gap:6px; align-items:center; } .sets input { width:64px; text-align:center; height:48px; border-radius:12px; border:1px solid #C9D3CD; font:inherit; font-size:18px; }
.waiver { background:var(--paper); border:1px solid var(--line); border-radius:var(--r); padding:20px 24px; max-height:420px; overflow-y:auto; font-size:14.5px; line-height:1.55; }
.waiver h4 { font:800 15px "Barlow Semi Condensed", sans-serif; text-transform:uppercase; margin:18px 0 6px; color:var(--deep); } .waiver .notice { font-weight:700; font-size:13px; }
#sigCanvas { width:100%; height:150px; background:var(--chalk); border:2px dashed #C9D3CD; border-radius:12px; touch-action:none; }
.code-input { font:800 32px "Barlow Semi Condensed", sans-serif; letter-spacing:.3em; text-align:center; height:64px !important; }
.notif { display:flex; flex-direction:column; gap:8px; } .notif a { background:var(--chalk); border:1px solid var(--line); border-radius:12px; padding:12px 14px; color:inherit; text-decoration:none; display:flex; justify-content:space-between; gap:12px; } .notif .muted { font-size:12.5px; }
.auth { max-width:460px; margin:0 auto; }
.note { font-size:13.5px; color:var(--muted); }
.callout { background:var(--tint); border-radius:var(--r); padding:16px 20px; display:flex; gap:14px; align-items:center; }

/* bracket, from renderer/bracket.js */
.nb .nb-match rect { fill:#fff; stroke:#C9D3CD; stroke-width:1.2; } .nb .nb-match line { stroke:#E6E8EB; } .nb .nb-match.nb-bye rect { stroke-dasharray:4 3; }
.nb .nb-side { font:13px Inter, sans-serif; fill:#1B1B1B; } .nb .nb-muted { fill:#8A9188; font-style:italic; } .nb .nb-winner { font-weight:700; fill:#2E5644; }
.nb .nb-seed { font-size:10px; fill:#B5654A; font-weight:700; } .nb .nb-score { font:600 12px Inter, sans-serif; fill:#2E5644; } .nb .nb-key { font:10px Inter, sans-serif; fill:#A0A6A0; }
.nb .nb-link { fill:none; stroke:#B5C2B2; stroke-width:1.5; } .nb .nb-loser-link { stroke:#D9A08A; stroke-dasharray:5 4; }
.nb .nb-round { font:600 11px Inter, sans-serif; fill:#6B7280; text-transform:uppercase; letter-spacing:.06em; } .nb .nb-title { font:700 14px "Barlow Semi Condensed", sans-serif; fill:#2E5644; }
.nb .nb-me rect { stroke:#2E5644; stroke-width:2.5; fill:#F3FBD4; }
.nb-rr { border-collapse:collapse; font-size:13.5px; font-variant-numeric:tabular-nums; white-space:nowrap; }
.nb-rr th, .nb-rr td { border:1px solid #DCE2DE; padding:7px 10px; text-align:center; }
.nb-rr thead th { font:700 12px "Barlow Semi Condensed", sans-serif; letter-spacing:.08em; text-transform:uppercase; color:#6B7280; background:#F4F6F2; }
.nb-rr tbody th { text-align:left; font-weight:600; background:#F4F6F2; }
.nb-rr .nb-self { background:#E6E8EB; } .nb-rr .nb-w { background:#EEF7EA; color:#2E5644; font-weight:600; } .nb-rr .nb-l { color:#6B7280; } .nb-rr .nb-todo { color:#9AA19C; }

/* The strip below the bar is the phone's copy of the same links. On a wide
   screen the bar already has them, so the strip is drawn only when it carries
   a back link — and then only the back link is in it. */
@media (min-width: 901px) {
  .subnav-phone { display:none; }
  /* The bar above already carries the tabs and the way out, so down here only
     the page's own back link is worth the room. */
  .subnav .subnav-tabs, .subnav-lead .nav-out { display:none; }
}
@media (max-width: 900px) {
  .wrap, .foot { padding-left:20px; padding-right:20px; }
  /* On a phone the strip IS the navigation, so it is set like the bar above it:
     words separated by a gap rather than boxes, lined up with the wordmark. */
  /* One static row: the items share the width and shrink together rather
     than running off the edge. */
  /* Row one: where you came from. Row two: where you can go. */
  .subnav-in { flex-direction:column; align-items:stretch; padding:0; gap:0; }
  .subnav-lead { display:flex; align-items:center; justify-content:space-between; gap:14px; padding:0 16px; border-bottom:1px solid var(--line); }
  .subnav-lead .back { margin-right:0; padding:11px 0; font-size:14px; font-weight:600; }
  /* Beside a real back arrow this is a plain word, not a second arrow. On a
     page with no back of its own it keeps the arrow and reads as the way out. */
  .subnav-lead .nav-out { margin:0; padding:11px 0; min-height:0; background:none; border:0; font-size:13px; font-weight:500; letter-spacing:0; }
  .subnav-lead .nav-out-quiet { opacity:.8; }
  /* The three tabs share the width and never run off the edge. */
  .subnav-tabs { display:flex; padding:0 8px; }
  .subnav-tabs a { flex:1 1 0; min-width:0; text-align:center; padding:12px 4px; font-size:13.5px; white-space:nowrap; }
  .subnav a { padding:13px 0; min-width:0; font-size:13.5px; white-space:nowrap; }
  .nav-links { display:none; }
  .subnav-links { display:contents; }
  .hero-in, .eventhead, .form-row, .grid-2 { grid-template-columns:1fr; } .grid-3 { grid-template-columns:1fr; }
  .hero-stats { justify-content:flex-start; }
  .mrow { grid-template-columns:1fr; gap:8px; } .matchvs { grid-template-columns:1fr; } .matchvs .vs { padding:8px 0; }
  .facts { grid-template-columns:1fr 1fr; }
  table.t { font-size:14px; }
}
@media (max-width: 600px) { .nav-in { gap:8px; } .nav-right { gap:6px; } .nav-right .btn { padding:0 12px; white-space:nowrap; } .nav-right .pill-user { padding:0 10px; white-space:nowrap; } .facts { grid-template-columns:1fr; } }

/* The family cabinet's own strip. The bar above it carries the academy's
   links, not these, so unlike the tournament its tabs have to stay on every
   width — hence the three-class selectors, which win wherever they sit. */
.subnav.subnav-acct .subnav-tabs { display:flex; }
@media (min-width: 901px) {
  .subnav.subnav-acct .subnav-in { flex-direction:row; align-items:center; }
  .subnav.subnav-acct .subnav-tabs { order:1; padding:0; }
  .subnav.subnav-acct .subnav-tabs a { padding:13px 14px; }
  /* The way out stays reachable on a desktop too; the wordmark already goes
     home, so the academy link beside it is the one that goes. */
  .subnav.subnav-acct .subnav-lead { order:2; margin-left:auto; display:flex; align-items:center; border:0; padding:0; }
  .subnav.subnav-acct .subnav-lead .nav-out-quiet { display:inline-flex; background:none; border:0;
    padding:13px 0; min-height:0; font:600 14.5px/1 Inter, system-ui, sans-serif; letter-spacing:0; opacity:1; }
}

/* --- round-robin match rows (a league is a table, not a tree) --- */
.rrow { display:flex; justify-content:space-between; align-items:center; gap:12px; padding:9px 12px; border:1px solid var(--line); border-radius:12px; background:var(--paper); text-decoration:none; color:inherit; font-size:14.5px; }
.rrow.mine { background:#F3FBD4; border-color:#C6D98F; }
.rrow-who { min-width:0; display:grid; grid-template-columns:1fr auto 1fr; gap:8px; align-items:center; flex:1 1 auto; }
.rrow-v { text-align:center; }
.pairname { display:block; min-width:0; overflow-wrap:anywhere; } .pairname.pair span { display:block; line-height:1.3; }
.rrow-who > .pairname:last-child { text-align:left; }
.nb-lpair span { display:block; line-height:1.25; }
.nb .nb-pair { font-size:12px; }
.card-white table.t-sm .teamline { display:flex; flex-direction:column; align-items:flex-start; gap:4px; }
/* "anywhere" tore Gonzalez into Gonzal / ez and Barrenechea into three lines
   on the print sheet. break-word breaks a word only when it genuinely cannot
   fit, and the sheet keeps a usable Player column instead. */
.card-white table.t-sm .pchip { white-space:normal; } .card-white table.t-sm .pname { overflow-wrap:break-word; }
.sheet table.t-sm { min-width:340px; }
.hist .move { padding:1px 0; } .hist .move a { color:inherit; text-decoration:none; font-weight:600; }
.hist .score { color:var(--court); font-weight:700; text-decoration:none; font-size:16px; }
.hist .sub { font-size:12.5px; }

/* --- phones: wide tables become a stack of cards, one line per fact --- */
@media (max-width: 760px) {
  .hide-sm { display:none !important; }
  .tablewrap:has(> .t-cards) { border:0; background:transparent; overflow:visible; }
  table.t-cards, table.t-cards tbody, table.t-cards tr, table.t-cards td { display:block; width:100%; }
  table.t-cards thead { display:none; }
  table.t-cards { background:transparent; }
  table.t-cards tr { border:1px solid var(--line); border-radius:14px; background:var(--chalk); padding:12px 14px; margin-bottom:10px; }
  table.t-cards tr.me { background:#F3FBD4; border-color:#C6D98F; }
  table.t-cards td { border:0; padding:3px 0; text-align:left !important; }
  table.t-cards td[data-l]:not(.c-head)::before { content:attr(data-l); display:block; font:700 10.5px "Barlow Semi Condensed", sans-serif; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); margin-top:6px; }
  table.t-cards td.c-head { display:inline; padding:0; font-weight:600; }
  table.t-cards td.c-head + td.c-head::before { content:" · "; color:var(--muted); font-weight:400; }
  table.t-cards td:empty { display:none; }
  .hist .moves { font-size:13.5px; }
  .rrow { flex-direction:column; align-items:flex-start; gap:4px; }
}

/* --- the draw on a phone: rounds as a list, the tree one tap away --- */
.drawview { display:flex; justify-content:flex-end; gap:6px; margin:-8px 0 12px; }
.drawview a { font-size:13px; font-weight:600; color:var(--muted); text-decoration:none; padding:6px 12px; border-radius:999px; border:1px solid var(--line); background:var(--chalk); min-height:36px; display:inline-flex; align-items:center; }
.drawview a.on { background:var(--court); color:var(--chalk); border-color:var(--court); }
.bracket-list { display:none; }
.nb-list { display:flex; flex-direction:column; gap:18px; }
.nb-list-round h4 { font:800 13px "Barlow Semi Condensed", sans-serif; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); margin:0 0 8px; }
.nb-lhref { text-decoration:none; color:inherit; display:block; }
.nb-lmatch { background:var(--chalk); border:1px solid var(--line); border-radius:14px; padding:8px 12px 10px; margin-bottom:8px; }
.nb-lmatch.nb-lbye { border-style:dashed; }
.nb-lmatch.nb-me { background:#F3FBD4; border-color:#C6D98F; }
.nb-lkey { display:block; font-size:11px; color:#9AA19C; letter-spacing:.04em; margin-bottom:2px; }
.nb-lside { display:flex; align-items:center; gap:8px; min-height:30px; font-size:15px; }
.nb-lside + .nb-lside { border-top:1px solid var(--line); }
.nb-lmuted { color:#8A9188; font-style:italic; }
.nb-lwon .nb-lname { font-weight:700; color:var(--court); }
.nb-lseed { font:700 11px Inter, sans-serif; color:#B5654A; width:14px; flex:none; }
.nb-lname { flex:1 1 auto; min-width:0; overflow-wrap:anywhere; }
.nb-lgames { display:flex; gap:2px; flex:none; font-variant-numeric:tabular-nums; }
.nb-lg { display:inline-block; min-width:26px; text-align:center; font-weight:600; color:var(--muted); position:relative; }
.nb-lg-won { color:var(--court); font-weight:800; }
.nb-lg sup { font-size:9px; margin-left:1px; }
@media (max-width: 760px) {
  .bracket-tree { display:none; }
  .bracket-list { display:block; }
  .bracket.show-tree .bracket-tree { display:block; }
  .bracket.show-tree .bracket-list { display:none; }
  .bracket { padding:12px; }
}

/* A wide tree shrinks to the card on a desktop rather than clipping its last
   column; on a phone the tree is behind the List/Tree switch and keeps its
   natural size, because a five-round draw scaled to 390px is unreadable. */
@media (min-width: 761px) { .bracket svg.nb { max-width:100%; height:auto; } }

/* The rating table on the match page has five columns; on a phone it pushed
   the whole card 63px past the edge and the page scrolled sideways. */
.grid-2 > * { min-width:0; } .card-white { min-width:0; }
@media (max-width: 760px) {
  /* The rating moved into column three, and this rule was hiding whatever sat
     there — so on a phone the one number the league is played for disappeared.
     It is the played count that goes; the rating, the wins and the losses stay. */
  /* Keyed on the column NUMBER, this also struck the fourth column of two
     other tables: the new rating on a match page and the "before -> after"
     on a player's history — the very thing a player opens the page to see.
     It is the standings' own P column that should go, and that column now
     says so itself with .hide-sm. */
  .card-white table.t-sm th.hide-sm, .card-white table.t-sm td.hide-sm { display:none; }
  .card-white table.t-sm th, .card-white table.t-sm td { padding:8px 6px; font-size:13px; }
}

/* Every other page in this shell has a .lead paragraph between the heading
   and the first field; the login page has none, and the "Email" label read as
   a continuation of "Log in". */
.auth .form { margin-top: 16px; }

/* --- rankings: the number is the point, so it never falls off the edge --- */
table.rank .pchip { max-width:100%; } table.rank .pname { overflow-wrap:anywhere; }
table.rank .pband { display:block; margin-top:3px; }
/* The level filter used to be one non-wrapping row that scrolled sideways,
   which on a phone simply cut "Advanced 3.5+" off the edge with nothing to say
   it was there. Four choices wrap onto two lines and all four are visible. */
.filters .seg { flex-wrap:wrap; max-width:100%; }
@media (max-width: 760px) {
  .filters { gap:8px; }
  .seg a { padding:7px 12px; font-size:13.5px; min-height:34px; white-space:nowrap; }
  .tablewrap:has(> table.rank) { border:0; background:transparent; overflow:visible; }
  table.rank, table.rank tbody { display:block; width:100%; }
  table.rank thead { display:none; }
  table.rank tr { display:grid; grid-template-columns:28px minmax(0,1fr) auto; align-items:center; gap:10px; background:var(--chalk); border:1px solid var(--line); border-radius:14px; padding:10px 12px; margin-bottom:8px; }
  table.rank tr.me { background:#F3FBD4; border-color:#C6D98F; }
  table.rank td { display:block; border:0; padding:0; }
  table.rank td.num { font:800 16px "Barlow Semi Condensed", sans-serif; color:var(--muted); text-align:center; }
  table.rank td.right { text-align:right !important; }
  /* Below 375px the name cell's own content (name + a nowrap level pill) was
     wider than its track, so it printed across the rating — the one number
     the table exists for. A grid item does not shrink past min-content unless
     it is told it may. */
  table.rank .pchip, table.rank .pchip > span { min-width:0; max-width:100%; }
  table.rank .pband .pill, table.rank .pband { white-space:normal; max-width:100%; }
  .rating { font-size:22px; } .rating small { display:block; margin:0; font-size:11.5px; }
}

/* --- how it works (home, visitors only) --- */
.how .card { position:relative; padding-top:26px; }
.how-n { font:800 40px "Barlow Semi Condensed", sans-serif; color:var(--lime); line-height:1; margin-bottom:6px; }
.how .h3 { margin:0 0 6px; }
.how p { margin:0; color:var(--muted); font-size:15px; line-height:1.55; }
/* a pair's rating: the sum, then how it adds up */
.pairrating small { display:block; margin:2px 0 0; font-size:12px; }
/* the result form: the small tiebreak box */
.sets .set input.tb { width:54px; font-size:13px; opacity:.8; }

/* ================= 8 Sep 2026, second pass ==================== */

/* The footer belongs at the bottom of the window, not halfway up a short
   page — the page column fills the screen and the main block grows. */
body { min-height:100vh; display:flex; flex-direction:column; }
main { flex:1 0 auto; background:var(--paper); }
.foot { flex:0 0 auto; }

/* A pair is ALWAYS two lines, wherever it appears: a name that sometimes
   sits beside its partner and sometimes under it reads as two different
   things. One player is unaffected — a single line has nothing to stack. */
.teamline { display:inline-flex; flex-direction:column; align-items:flex-start; gap:4px; }
.matchvs .teamline { align-items:center; }
.mrow-who .teamline { align-items:flex-start; }

/* Latest results: nothing breaks mid-score or mid-number. The stage sits
   under the event name instead of wrapping the word "stage" onto its own
   line, and each rating move is one unbreakable line. */
.hist td { vertical-align:top; }
.hist .sub { display:block; font-size:12.5px; }
.hist .score, .hist td.num { white-space:nowrap; }
/* A rating move may wrap between the name and the numbers, never inside
   them — and never gets cut off at the edge of the column. */
.hist .move { white-space:normal; }
.hist .move .num, .hist .move b { white-space:nowrap; }

/* A match row: the middle column may shrink, and the buttons on the right
   wrap under the score instead of climbing over it. */
.mrow > * { min-width:0; }
.mrow-res { flex-wrap:wrap; justify-content:flex-end; white-space:normal; row-gap:6px; }
.mrow-res b, .mrow-res .num, .mrow-res .pill { white-space:nowrap; }

/* A name is a name: it does not break across two lines in a table that has
   room for it ("Andriy" / "Kovalenko", "Zzt Groups" / "62059"). The wide
   columns keep their content whole and the table scrolls if it must; on a
   phone the whole table is a stack of cards, where wrapping is right. */
.hist td > a, .hist td .pname, .hist td .rrow-who { white-space:nowrap; }
.hist td:nth-child(2) { min-width:150px; }
@media (max-width: 760px) { .hist td > a, .hist td .pname { white-space:normal; } .hist td:nth-child(2) { min-width:0; } }

/* A league match nobody has scheduled: the window it must be played in. */
.playwin { display:inline-flex; align-items:center; gap:6px; white-space:nowrap; }
.playwin.late { color:#9A3C1C; font-weight:700; }

/* A form hidden with the `hidden` attribute must stay hidden: .form sets
   display:flex, which quietly beats it (the trap that once showed every
   collapsed block on the admin's event page). */
[hidden] { display:none !important; }

/* Hand-sized taps on a phone: a finger is about 9 mm, so anything tapped
   rather than read gets 44 px of height on a small screen. */
@media (max-width: 680px) {
  .seg a, .seg button { min-height: 44px; }
  .btn-sm { min-height: 44px; }
  .pill-user { min-height: 44px; }
  .filters .seg { padding: 3px; }
}

/* ── The waiting animation ──────────────────────────────────────────
   Its look lives in tournament/assets/wait.js now, beside the markup it
   belongs to, and is injected when the overlay is built. That is what lets
   the admin panel — which loads its own stylesheet and not this one — show
   the same waiting frame without a second copy of these rules. */

/* 320-379 px: an iPhone SE, and the smallest thing anyone still carries. The
   bar has to hold a wordmark, a way in and a way back, so the lime call to
   action stands down here — the page repeats it two screens later. */
@media (max-width: 379px) {
  .nav-right .btn-lime { display:none; }
  .subnav a, .subnav .nav-out { font-size:12.5px; }
  .nav-in { gap:8px; }
}

/* The small print under a centred column. It sits in the full-width wrap while
   the waiver and the account hold a 460-760px column in the middle, so the
   bottom line started a couple of hundred pixels to the left of everything
   above it. Centring puts it back under the column, whatever width that
   column happens to be. The tournament footer is a different shape and keeps
   its own alignment. */
.foot-centre .wrap { text-align: center; }

/* The tournament photo is a 2:1 panorama — tennis on one side of the net,
   pickleball on the other. On a phone the hero box is taller than it is wide,
   so "cover" keeps only a narrow strip: dead centre is the net post and
   nothing else. Sliding the crop left brings the tennis player and the net
   back into the frame, which is the half that says what the picture is.
   The academy's photo is 3:2 and needs no such help, which is why only this
   one carries the rule. */
@media (max-width: 760px) {
  .hero { background-position: 34% center; }
}

/* ---- the three facts and the counter, to the academy's own measurements ----
   Measured off the academy at 1440: three cells of 152, 214 and 214 — 580 in
   all — and 87 tall, because over there the second and third labels run to two
   lines and these do not. Fixed rather than fitted to the words on purpose:
   the point is that stepping from one site to the other should move nothing
   but the numbers. 580 leaves exactly 260 for the counter and 40 between them,
   which is the academy's row to the pixel — and the counter is on three digits
   now, so it is 260 wide there too. */
@media (min-width: 1024px) {
  .hero-stats { width: 580px; flex: 0 0 580px; grid-template-columns: 152px 214px 214px; }
  .hero-stats li { min-height: 87px; justify-content: flex-start; padding-top: 8px; }
  .hero-stats b { font-weight: 700; }
  .hero-stats li span { max-width: 190px; }
  .hero-stats li:first-child span { max-width: 112px; }
  .board-label { line-height: 18px; }
}

/* The dividers between the three facts have to fall in the same two places as
   the academy's — 632 and 846 at a 1440 screen — or switching between the
   sites slides them. The academy's cells are sized by its own words; ours are
   pinned to the same widths so the frame is identical whatever the words are. */
@media (min-width: 1024px) {
  .hero-stats { display: flex; }
  .hero-stats li { flex: 0 0 auto; }
  .hero-stats li:nth-child(1) { width: 152px; }
  .hero-stats li:nth-child(2) { width: 214px; }
  .hero-stats li:nth-child(3) { width: 214px; }
  /* One line, as the academy's is. Two lines here pushed everything below it
     down by 28px and nothing lined up any more. */
  .hero-lead { max-width: 720px; }
}

/* The academy changes its own numbers at 1536: the three facts go from 580
   wide to 740, the cells from 152/214/214 to 170/231/231, the height from 87
   to 95 and the big number from 52px to 60px. Copied here so the two sites
   step together instead of one of them growing and the other not. */
@media (min-width: 1536px) {
  .hero-stats { width: 740px; flex: 0 0 740px; }
  .hero-stats li { min-height: 95px; }
  .hero-stats li:nth-child(1) { width: 170px; }
  .hero-stats li:nth-child(2) { width: 231px; }
  .hero-stats li:nth-child(3) { width: 231px; }
  .hero-stats b { font-size: 60px; }
}
/* The academy leaves 28px between its heading block, the facts and the
   buttons. Ours left 44, which put the facts a line and a half lower. */
@media (min-width: 1024px) {
  .hero-row { margin-top: 28px; }
}

/* --- the event page on a small phone --------------------------------------
   Two things ran off the edge at 320px: the row of page tabs (About, Draw,
   Matches, Results, Players — five words in 280px), and the standings card,
   which was sized by the table inside it rather than by the screen. The tabs
   come down a size so all five fit without a sideways drag, and the card is
   told it may never be wider than what it sits in; the table keeps its own
   scroll, which is the right place for one. */
@media (max-width: 600px) {
  .tabs { gap: 0; }
  .tabs a { padding: 12px 7px; font-size: 12.5px; }
  .card-white { padding: 18px 14px; }
}
.tablewrap { min-width: 0; max-width: 100%; }
.card-white > * { min-width: 0; }

/* --- which way a number went ---------------------------------------------
   Green up, red down, and nothing at all when it did not move. The arrow sits
   beside the number it belongs to rather than in a column of its own, because
   a column of mostly-blank cells is worse than no column. */
.mv { margin-left: 6px; font: 700 12px/1 Inter, system-ui, sans-serif; letter-spacing: 0; white-space: nowrap; }
.mv-up { color: #1E7A3E; }
.mv-down { color: #C0392B; }
td.num .mv { margin-left: 4px; font-size: 11px; }

/* --- a tiebreak, on one line ---------------------------------------------
   7-6⁵, never 7-6(5): the brackets are how a score is typed, not how one is
   printed. A deciding match tiebreak carries no mark at all — that third set
   IS the tiebreak, played to 10, so it is written as a set: 6-4 3-6 10-8. */
.scoreline { white-space: nowrap; }
.scoreline sup.tb { font-size: .56em; font-weight: 600; line-height: 0; vertical-align: super; margin-left: 1px; }

/* --- a result the way a tournament prints one ----------------------------
   Two lines, winner on top, sets in columns down the right. The old row put
   both names and "6-4 6-4" on one line and left the reader to work out who
   had won — which, when the second player won, most people got backwards.

   The card itself is the grid and each line is display:contents, so the two
   ratings and the set columns sit under one another however long the names
   are. Two separate grids would only line up by luck. */
.sb { display: grid; grid-template-columns: 1fr auto auto auto; gap: 3px 10px; align-items: baseline;
      padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px;
      background: var(--paper); text-decoration: none; color: inherit; }
.sb + .sb { margin-top: 6px; }
a.sb:hover { border-color: #C3D2C6; background: #fff; }
.sb-flat { background: transparent; border: 0; padding: 0; margin: 2px 0 16px; }

/* The strip that names the columns. Small, quiet, and on the same grid as the
   cards below it, so a label sits over the thing it names. */
.sb-head { background: transparent; border: 0; padding: 0 12px 1px; }
.sb-head span { font: 700 9.5px/1.4 Inter, system-ui, sans-serif; letter-spacing: .09em;
                text-transform: uppercase; color: var(--muted); }
.sb-head .sb-set { color: var(--muted); font-weight: 700; }
.sb-head:hover { background: transparent; border: 0; }
.sb.mine { background: #F3FBD4; border-color: #C6D98F; }
.sb-row { display: contents; }
.sb-meta, .sb-note { grid-column: 1 / -1; font-size: 12px; color: var(--muted); line-height: 1.3; }
.sb-meta { margin-bottom: 1px; }
.sb-note { margin-top: 2px; }
.sb-name { min-width: 0; overflow-wrap: anywhere; font-size: 15px; line-height: 1.3; color: var(--muted); }
.sb-win .sb-name { font-weight: 700; color: var(--court); }
.sb-tick { color: #1E7A3E; font-weight: 700; margin-right: 6px; }
.sb-rating { width: 46px; font: 600 13px/1.3 Inter, system-ui, sans-serif; color: var(--muted); font-variant-numeric: tabular-nums; text-align: right; }
.sb-mv { width: 30px; text-align: left; font-variant-numeric: tabular-nums; }
.sb-mv .mv { margin-left: 0; }
/* Fixed-width set columns: a tiebreak superscript must not shove one line's
   numbers out of step with the other's. */
.sb-sets { display: grid; grid-auto-flow: column; grid-auto-columns: 20px; column-gap: 7px; }
.sb-w2 .sb-sets { grid-auto-columns: 26px; }
.sb-set { position: relative; text-align: center; font: 600 15px/1.3 Inter, system-ui, sans-serif;
          color: var(--muted); font-variant-numeric: tabular-nums; }
.sb-set-won { color: var(--court); font-weight: 800; }
.sb-set sup { position: absolute; top: -2px; right: 0; font-size: 10px; font-weight: 600; line-height: 1; }
/* Not played yet: one line, and when it is expected. */
.sb-todo { grid-template-columns: 1fr auto 1fr auto; }
.sb-todo .sb-side { min-width: 0; font-size: 15px; overflow-wrap: anywhere; }
.sb-v { color: var(--muted); font-size: 13px; }
.sb-when { font-size: 13px; white-space: nowrap; }
@media (max-width: 600px) {
  .sb { gap: 3px 6px; padding: 9px 10px; }
  .sb-head { padding: 0 10px 1px; }
  .sb-name, .sb-todo .sb-side { font-size: 14px; }
  .sb-set { font-size: 14px; }
  .sb-sets { grid-auto-columns: 17px; column-gap: 4px; }
  .sb-w2 .sb-sets { grid-auto-columns: 21px; }
  .sb-rating { width: 38px; }
  .sb-mv { width: 24px; }
  .sb-head span { font-size: 9px; letter-spacing: .06em; }
  .sb-mv .mv { font-size: 11px; }
  .sb-todo { grid-template-columns: 1fr; gap: 2px; }
  .sb-v { display: none; }
}
}

/* --- a choice that changes the form ---------------------------------------
   Two halves, side by side, and the one you pick is obvious from across the
   room. A checkbox under the fields it governs — which is what this was — reads
   as a footnote, and the coach looked straight past it for a week. */
.pick2 { display:grid; grid-template-columns:1fr 1fr; gap:10px; margin:0 0 14px; }
@media (max-width:560px) { .pick2 { grid-template-columns:1fr; } }
.pick2-o { display:flex; gap:10px; align-items:flex-start; padding:12px 14px; border:1px solid var(--line);
           border-radius:12px; background:var(--paper); cursor:pointer; font-size:14.5px; line-height:1.35; }
.pick2-o:has(input:checked) { border-color:var(--deep); background:#fff; box-shadow:0 0 0 2px rgba(46,86,68,.14); }
.pick2-o input { margin:2px 0 0; flex:0 0 auto; }
.note { border:1px solid #C6D98F; background:#F7FBE8; border-radius:12px; padding:12px 14px; margin:0 0 14px; }

/* --- the rating column lines up ------------------------------------------
   The number, the NTRP in brackets and the movement arrow were three inline
   pieces of different widths, so a row carrying an arrow pushed its number left
   and a row without one did not. Read down the column, the figures wandered.
   Each piece now has a lane of its own inside the cell. */
table.rank td.right { text-align: right; white-space: nowrap; }
table.rank td.right .rating { display: inline-grid; grid-template-columns: auto 46px; align-items: baseline;
                              gap: 4px; text-align: right; font-variant-numeric: tabular-nums; }
table.rank td.right .rating small { text-align: left; }
table.rank td.right .mv { display: inline-block; width: 40px; text-align: left; margin-left: 6px;
                          font-variant-numeric: tabular-nums; }
@media (max-width: 600px) {
  table.rank td.right .rating { grid-template-columns: auto 40px; }
  table.rank td.right .mv { width: 34px; margin-left: 4px; }
}

/* ---------------------------------------------------------------------------
 * The side menu (21 Sep 2026)
 *
 * This site had no burger at all. The strip under the bar carried the three
 * tabs and passed for navigation, which left the two academy doors as a pair
 * of unlabelled circles with nowhere to say what they were. The owner asked
 * for the words on a desktop and for the circles to stay in the bar on a
 * phone, with the words moved into a menu behind three stripes.
 *
 * So: the burger appears exactly where the labels disappear (900px), and the
 * labels now go at 900 rather than 600 — the bar keeps round icons on every
 * screen that has a burger, and carries words on every screen that does not.
 * ------------------------------------------------------------------------- */
@media (max-width: 900px) { .nav-long { display:none; } }

.nav-burger { display:none; flex-direction:column; justify-content:center; gap:5px; width:44px; height:44px; padding:0 11px; background:rgba(255,255,255,.1); border:1px solid rgba(255,255,255,.2); border-radius:999px; cursor:pointer; }
.nav-burger span { display:block; height:2px; background:var(--chalk); border-radius:2px; }
.nav-burger:hover { background:rgba(255,255,255,.2); }
@media (max-width: 900px) { .nav-burger { display:flex; } }

.tdrawer { position:fixed; inset:0; z-index:60; }
.tdrawer[hidden] { display:none; }
.tdrawer-back { position:absolute; inset:0; background:rgba(0,0,0,.5); }
/* The academy's own drawer is this colour and slides from the right; crossing
   between the two sites should not feel like crossing between two products. */
.tdrawer-sheet { position:absolute; inset:0 0 0 auto; width:min(88vw, 420px); background:#2E5644; padding:16px 20px 28px; overflow-y:auto; display:flex; flex-direction:column; gap:8px; }
body.tdrawer-open { overflow:hidden; }

.tdrawer-x { align-self:flex-end; width:40px; height:40px; margin-bottom:8px; background:none; border:0; color:#fff; font-size:30px; line-height:1; cursor:pointer; }
.tdrawer-cta, .tdrawer-btn { display:inline-flex; align-items:center; justify-content:center; gap:10px; min-height:52px; padding:0 20px; border-radius:999px; font:700 14px/1 Inter, system-ui, sans-serif; letter-spacing:.84px; text-transform:uppercase; text-decoration:none; white-space:nowrap; }
.tdrawer-cta { background:var(--lime); color:#1b1b1b; }
.tdrawer-btn { background:transparent; border:1px solid rgba(255,255,255,.35); color:#fff; }
.tdrawer-btn:hover { background:rgba(255,255,255,.1); }
.tdrawer-game img { display:block; width:20px; height:20px; flex:0 0 auto; }
.tdrawer-note { margin:0 0 10px; font-size:12px; color:rgba(255,255,255,.6); text-align:center; }
.tdrawer-links { display:flex; flex-direction:column; gap:2px; margin-top:6px; }
.tdrawer-links a { padding:10px 0; color:#fff; text-decoration:none; font-size:22px; font-weight:400; }
.tdrawer-links a.on { color:var(--lime); }

/* Log in and register on one page (21 Sep 2026).
   The bar used to offer "Join" beside "Log in" and the hero asked a third
   time. One door now, with both halves behind it, separated by a rule so
   neither reads as the small print of the other. */
.auth-or { display:flex; align-items:center; gap:14px; margin:28px 0 22px; color:var(--muted); font-size:13px; text-transform:uppercase; letter-spacing:1.2px; }
.auth-or::before, .auth-or::after { content:""; flex:1 1 auto; height:1px; background:var(--line); }
.auth-new .lead { margin-bottom:16px; }
.auth-new .muted { margin-top:12px; }
