/* AIM Olympic Badminton Academy — site styles.

   THE ROOM.
     Green playing surface, chalk court markings, the sprung wooden floor,
     parquet cream daylight: the palette is the hall the academy plays in.

   THE TYPE.
     Barlow Condensed set large, tight and uppercase, with Montserrat carrying
     body copy.

   THE DISCIPLINE.
     One radius scale, one elevation, one card recipe, one press on every
     button, one vertical rhythm. A page reads as neat when nothing in it is
     decided twice, and this sheet holds to that rule. Search for "ONE"
     below — each note marks a decision made once and then reused.

   READABILITY.
     Every text/background pair here clears 4.5:1, small text included, and
     the court markings are held behind a scrim wherever type sits over them.
     A chalk line running through a paragraph is the fastest way to make a
     page unreadable. */

:root{
  /* Playing surface */
  --court:#0f5c3f;        /* the mat — primary dark surface            */
  --court-deep:#08331f;   /* deep shade, footer and fixture headers     */
  --court-lit:#166b4a;    /* lit court, hover state                     */
  --court-line:#e9f2ea;   /* painted court marking                      */

  /* Sprung wooden floor */
  --timber:#c58a49;       /* board face — the accent                    */
  --timber-lit:#dda765;   /* hover                                      */
  --timber-dk:#89561f;    /* board shadow gap, and accent text on cream */
  --timber-pale:#eed3ac;  /* pale board, accent text on green           */
  --on-timber:#33200c;    /* text on a timber surface — 5.3:1           */

  /* Hall light */
  --parquet:#f7efe2;      /* page ground — sunlight on wood             */
  --parquet-2:#efe1cb;    /* recessed panel                             */
  --chalk:#fffaf1;        /* card face                                  */
  --ink:#1d2620;          /* text — warm near-black, never pure black   */
  --ink-soft:#4f5d54;     /* body text — 6.1:1 on parquet               */
  --ink-faint:#58665c;    /* tertiary — 5.3:1; never go lighter         */
  --hair:#e0d3bd;         /* rule on cream                              */

  /* Text on green. Both clear 4.5:1 over --court, so small type is safe
     anywhere in the room, not only over the deep shade. */
  --on-court:#d6e6db;      /* body copy on green           — 6.2:1      */
  --on-court-soft:#b8d0c1; /* notes and captions on green  — 4.9:1      */

  /* The typefaces. Teko and Hind follow them
     for Devanagari only: Barlow and Montserrat have no Hindi letters, so the
     browser falls through to the next face for those characters alone, and
     Google Fonts' unicode-range means the Hindi files are only downloaded
     when Hindi is actually on screen. */
  --display:'Barlow Condensed',Teko,Oswald,ui-sans-serif,system-ui,sans-serif;
  --body:Montserrat,Hind,ui-sans-serif,system-ui,-apple-system,sans-serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,monospace;
  --wrap:1200px;

  /* ONE radius scale. Surfaces take --r; chips and inline marks take --r-sm;
     anything you press is a pill. Nothing else invents its own corner. */
  --r:14px;
  --r-sm:6px;

  /* ONE elevation. Every raised surface is a board resting on the floor: a
     hard offset shadow, no blur, no second variant. */
  --lift:0 5px 0 rgba(11,40,26,.22);
  --lift-lg:0 7px 0 rgba(11,40,26,.24);

  /* Sprung-floor boards: the one texture this system uses. */
  --wood:repeating-linear-gradient(90deg,
    #c58a49 0 46px,#b97d3e 46px 48px,#cf9455 48px 96px,#ab7135 96px 98px);
  /* Net mesh, laid over green at low opacity. */
  --net:repeating-linear-gradient(0deg,rgba(233,242,234,.07) 0 1px,transparent 1px 13px),
        repeating-linear-gradient(90deg,rgba(233,242,234,.07) 0 1px,transparent 1px 13px);
}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--parquet);color:var(--ink);font-family:var(--body);
  font-size:16px;-webkit-font-smoothing:antialiased;overflow-x:hidden}
a{color:inherit;text-decoration:none}
a:hover{text-decoration:underline}
img{max-width:100%}
/* The hidden attribute loses to any author display rule — a button styled
   display:inline-flex stays on screen with hidden set. This makes it win. */
[hidden]{display:none!important}
:focus-visible{outline:3px solid var(--timber);outline-offset:3px;border-radius:var(--r-sm)}
.green :focus-visible,.ftr :focus-visible{outline-color:var(--timber-pale)}

.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
/* "Dwarka vs Ashok Vihar", as three flex items. When the title is too wide
   for one line it wraps INSIDE the last name, so Vihar drops directly below
   Ashok. Wrapped as plain text, VIHAR went to the left edge under DWARKA and
   read as "Dwarka Vihar vs Ashok". The last item takes whatever width is left
   on the line, so wide screens still set the whole title on one line. The
   Hindi text swapped into the same spans wraps the same way. */
.vs-title{display:flex;flex-wrap:wrap;align-items:baseline;column-gap:.22em}
.vs-side{flex:1 1 0}
.skip{position:absolute;left:-9999px;top:0;background:var(--court);color:#fff;padding:12px 22px;
  font-size:15px;font-weight:700;z-index:99;border-radius:300px}
.skip:focus{left:12px;top:12px}

/* ---- structure ---------------------------------------------------------
   ONE vertical rhythm: 88px between sections, 60px for the short ones, and
   36px between a heading block and whatever it introduces. */
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 28px}
.sec{padding:88px 0}
.sec--sm{padding:60px 0}

/* Green sections carry the net mesh, so the room reads the same way from
   every section. */
.green{background:var(--court);color:var(--court-line);position:relative;overflow:hidden}
.green::before{content:"";position:absolute;inset:0;z-index:0;background:var(--net);
  pointer-events:none}
.green>*{position:relative;z-index:2}
.green--deep{background:var(--court-deep)}

/* The court markings are scenery, and scenery must never cross a word. Where
   a section draws them, a scrim of the court's own colour covers the left
   two-thirds — the part a text column actually occupies — and fades out to
   full markings on the right. */
.green:has(.markings)::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(100deg,
    var(--court) 0%,rgba(15,92,63,.97) 30%,rgba(15,92,63,.72) 52%,rgba(15,92,63,0) 78%)}
.markings{position:absolute;inset:0;z-index:0;pointer-events:none;opacity:.34}
.markings svg{width:100%;height:100%;display:block}

/* The floor: a wooden band that separates surfaces. Never a grey fade. */
.floor{height:16px;background:var(--wood);
  box-shadow:inset 0 3px 0 rgba(0,0,0,.22),inset 0 -3px 0 rgba(0,0,0,.14)}
.floor--tall{height:26px}

/* ---- type ---------------------------------------------------------------- */
/* Labels are 19px condensed capitals rather than small print: at this width
   they read as a graphic element, which is what gives the page its poster
   feel. */
.eyebrow{margin:0 0 18px;display:inline-flex;align-items:center;gap:12px;
  font-family:var(--display);font-size:19px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--timber-dk)}
.eyebrow::before{content:"";width:30px;height:4px;background:var(--timber);display:block}
.green .eyebrow{color:var(--timber-pale)}

/* Headlines: condensed, uppercase, set tight, and pulled left by their own
   sidebearing so the first letter lines up with the text beneath. */
.h1{margin:0;font-family:var(--display);font-weight:700;text-transform:uppercase;
  font-size:clamp(62px,10.5vw,150px);line-height:.84;letter-spacing:-.018em;margin-left:-.035em}
.h2{margin:0;font-family:var(--display);font-weight:700;text-transform:uppercase;
  font-size:clamp(46px,6.6vw,92px);line-height:.86;letter-spacing:-.016em;margin-left:-.03em}
.h3{margin:0;font-family:var(--display);font-weight:700;text-transform:uppercase;
  font-size:32px;line-height:.96;letter-spacing:-.005em}
.lede{margin:24px 0 0;max-width:560px;font-size:19px;line-height:1.5;letter-spacing:-.35px;
  color:var(--ink-soft)}
.green .lede{color:var(--on-court)}
/* A headline on .84 line-height leaves no descender room, and a chalk
   underline lands in what little there is — so a paragraph following a
   headline directly needs more clearance than the default. */
.h1 + .lede,.h2 + .lede{margin-top:36px}
.body{font-size:15.5px;line-height:1.65;letter-spacing:-.2px;color:var(--ink-soft)}
.green .body{color:var(--on-court)}
.note{font-family:var(--mono);font-size:13px;line-height:1.7;color:var(--ink-faint);max-width:720px}
/* A link inside running small print is still something a thumb has to land
   on, so it carries its own height. */
.note a,.det-grid p a,.rev-link{display:inline-block;padding:5px 0}
.green .note{color:var(--on-court-soft)}

/* A word served on the wooden floor. */
.tape{background:var(--timber);color:var(--on-timber);padding:0 .16em;border-radius:var(--r-sm);
  box-shadow:0 5px 0 var(--timber-dk)}
.chalkline{color:var(--court-line);text-decoration:underline;text-decoration-color:var(--timber);
  text-underline-offset:.09em;text-decoration-thickness:.07em}

/* ---- buttons -------------------------------------------------------------
   ONE press. Every button — filled or outlined, large or small, in a card or
   in the sticky bar — lifts 2px on hover and sinks on the way down, and its
   board shadow follows. An outlined button carries the same shadow so it
   never sits flat beside a filled one. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;
  padding:16px 32px;min-height:52px;border:0;border-radius:300px;cursor:pointer;
  font-family:var(--display);font-size:20px;font-weight:700;letter-spacing:.12em;
  text-transform:uppercase;text-decoration:none;text-align:center;
  --press:rgba(11,40,26,.34);
  box-shadow:0 4px 0 var(--press);
  transition:transform 110ms ease,background 160ms ease,box-shadow 160ms ease,color 160ms ease}
.btn:hover{text-decoration:none;transform:translateY(-2px);box-shadow:0 6px 0 var(--press)}
.btn:active{transform:translateY(2px);box-shadow:0 2px 0 var(--press)}
/* Condensed capitals have no descenders, so their optical centre sits above
   the box centre — the icon has to come up with them or it reads low. */
.btn .ico{width:20px;height:20px;flex:0 0 20px;display:block;margin-top:-2px}

.btn--wood{background:var(--timber);color:var(--on-timber);--press:var(--timber-dk)}
.btn--wood:hover{background:var(--timber-lit)}
.btn--court{background:var(--court);color:var(--court-line);--press:var(--court-deep)}
.btn--court:hover{background:var(--court-lit)}
.btn--chalk{background:var(--chalk);color:var(--ink)}
.btn--chalk:hover{background:#fff}
/* The outlined button draws its edge with an inset ring, so the ring and the
   board shadow live on one box-shadow declaration. */
.btn--line{background:transparent;color:inherit;
  box-shadow:inset 0 0 0 2px currentColor,0 4px 0 var(--press)}
.btn--line:hover{background:rgba(197,138,73,.18);
  box-shadow:inset 0 0 0 2px currentColor,0 6px 0 var(--press)}
.btn--line:active{box-shadow:inset 0 0 0 2px currentColor,0 2px 0 var(--press)}
.green .btn--line,.ftr .btn--line{--press:rgba(0,0,0,.3)}

.btn--sm{padding:11px 22px;min-height:44px;font-size:17px;gap:8px}
.btn--sm .ico{width:17px;height:17px;flex:0 0 17px}
.btn-row{display:flex;flex-wrap:wrap;gap:14px;margin-top:34px}

/* ---- announcement + header --------------------------------------------- */
.strip{background:var(--wood);color:var(--on-timber);padding:9px 20px;text-align:center;
  display:flex;flex-wrap:wrap;gap:6px 18px;align-items:center;justify-content:center;
  font-family:var(--display);font-size:18px;font-weight:600;letter-spacing:.13em;
  text-transform:uppercase;box-shadow:inset 0 -3px 0 rgba(0,0,0,.18)}
.strip a{display:inline-block;padding:4px 0;text-decoration:underline;
  text-underline-offset:3px;font-weight:700}

/* The header is not permanent furniture. It retracts while you read and
   returns the moment you scroll back up — see the chrome block in mix.js. The
   slide is its own height, eased out, so it leaves and arrives as one piece
   rather than fading into a smear; and it only earns an edge once it is
   actually floating over content, since flush against the announcement strip
   a shadow would be drawing a line that is already there. */
.hdr{background:var(--parquet);border-bottom:2px solid var(--hair);
  position:sticky;top:0;z-index:30;
  box-shadow:0 0 0 rgba(11,40,26,0);
  transition:transform 340ms cubic-bezier(.22,.68,.24,1),box-shadow 260ms ease}
.hdr.floating{box-shadow:0 8px 22px rgba(11,40,26,.16)}
.hdr.tucked{transform:translateY(-101%)}

/* An in-page link has to clear the header when it lands, or the heading it
   jumps to sits underneath it. */
html{scroll-padding-top:104px}
.nav{max-width:var(--wrap);margin:0 auto;padding:14px 28px;display:flex;flex-wrap:wrap;
  gap:14px 28px;align-items:center}
.brand{display:flex;align-items:center;gap:12px;margin-right:auto}
.brand:hover{text-decoration:none}
.brand img{width:46px;height:46px;border-radius:50%;display:block;
  border:2px solid var(--timber);background:#fff}
.brand-txt{font-family:var(--display);font-size:26px;font-weight:700;line-height:.94;
  letter-spacing:.01em;text-transform:uppercase}
.brand-sub{display:block;margin-top:3px;font-family:var(--body);font-size:9.5px;font-weight:600;
  letter-spacing:.2em;text-transform:uppercase;color:var(--ink-faint)}
.navlinks{display:flex;flex-wrap:wrap;gap:10px 24px;align-items:center;
  font-family:var(--display);font-size:19px;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase}
/* The underline is painted on like a court line: it grows from the left edge
   rather than appearing all at once. */
/* 5px of padding gave a 31px tap target on a phone. Nav links are the most
   tapped things on the page after the trial button, so they take a full-height
   one — the padding is vertical only, so the row does not get any wider. */
.navlinks a{position:relative;padding:11px 0}
.navlinks a:hover{text-decoration:none}
.navlinks a::after{content:"";position:absolute;left:0;right:0;bottom:0;height:3px;
  background:var(--timber);transform:scaleX(0);transform-origin:left;
  transition:transform 200ms cubic-bezier(.2,.7,.2,1)}
.navlinks a:hover::after{transform:scaleX(1)}
.navlinks a[aria-current="page"]{color:var(--court)}
.navlinks a[aria-current="page"]::after{background:var(--court);transform:scaleX(1)}

/* ---- hero ---------------------------------------------------------------- */
.hero{padding:80px 0 92px}
.hero-in{display:flex;flex-wrap:wrap;gap:44px;align-items:center}
.hero-col{flex:1.3 1 440px;min-width:0}
.hero-art{flex:1 1 320px;min-width:0}
/* The hero headline sits in a column, not across the page, so it takes its
   own step down from .h1 — three lines, none allowed to wrap. Condensed type
   buys roughly 40% more size than Archivo did in the same column. */
.hero .h1{font-size:clamp(52px,7.2vw,100px)}
/* Set as running text, not flex items: on a phone the branch and the address
   have to wrap as one sentence rather than into two stacked columns. */
.hero-badge{display:inline-block;background:rgba(233,242,234,.1);
  border:1px solid rgba(233,242,234,.3);border-radius:999px;padding:7px 17px;
  font-family:var(--display);font-size:17px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:#eef6f0}
.hero-badge b{color:var(--timber-pale);font-weight:700}

/* A photograph mounted like a court-side board: wood frame, chalk inner line. */
.frame{position:relative;padding:10px;background:var(--wood);border-radius:var(--r);
  box-shadow:0 18px 40px rgba(0,0,0,.3),inset 0 2px 0 rgba(255,255,255,.25)}
.frame-in{position:relative;overflow:hidden;border-radius:var(--r-sm);
  outline:2px solid rgba(255,255,255,.78);outline-offset:-8px;aspect-ratio:4/3}

/* ---- scoreboard ---------------------------------------------------------- */
.board{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  background:var(--court-deep);border-radius:var(--r);overflow:hidden;
  border-top:5px solid var(--timber);box-shadow:var(--lift-lg)}
.board-c{padding:28px 22px 24px;border-right:1px solid rgba(233,242,234,.14)}
.board-c:last-child{border-right:0}
.board-n{margin:0;font-family:var(--display);font-size:clamp(56px,7vw,86px);font-weight:700;
  line-height:.8;letter-spacing:-.03em;color:var(--court-line);font-variant-numeric:tabular-nums}
.board-l{margin:14px 0 0;font-family:var(--display);font-size:17px;font-weight:600;
  letter-spacing:.15em;text-transform:uppercase;color:var(--timber-pale)}

/* ---- grid + card ----------------------------------------------------------
   ONE card recipe: chalk face, timber top edge, the shared radius, the shared
   lift, and no border competing with the shadow. Rows stretch so cards end
   level — ragged card bottoms are the quickest way to make a page look
   untidy. */
.grid{display:grid;gap:20px;align-items:stretch}
.g260{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
.g300{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}

.card{display:flex;flex-direction:column;background:var(--chalk);border-radius:var(--r);
  padding:28px;border-top:6px solid var(--timber);box-shadow:var(--lift)}
.green .card{background:rgba(255,255,255,.06);color:var(--court-line);
  box-shadow:0 5px 0 rgba(0,0,0,.22)}
.green .card .body{color:var(--on-court)}

/* ---- timings: the fixture board ------------------------------------------ */
.slab{display:flex;flex-direction:column;background:var(--chalk);border-radius:var(--r);
  overflow:hidden;box-shadow:var(--lift);color:var(--ink)}
.slab-h{background:var(--court-deep);color:var(--court-line);padding:15px 22px;
  display:flex;flex-wrap:wrap;gap:8px 14px;align-items:baseline;justify-content:space-between}
.slab-h b{font-family:var(--display);font-size:27px;font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;line-height:1}
.slab-h span{font-family:var(--display);font-size:16px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--timber-pale)}
.row{padding:15px 22px;display:flex;flex-wrap:wrap;gap:4px 14px;align-items:baseline;
  justify-content:space-between;border-bottom:1px dashed var(--hair)}
.row:nth-child(even){background:rgba(197,138,73,.08)}
.row-t{font-family:var(--display);font-size:28px;font-weight:600;line-height:1.05;
  letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.row-d{font-size:13.5px;color:var(--ink-soft)}
.pip{display:inline-block;background:var(--timber);color:var(--on-timber);border-radius:300px;
  padding:2px 11px;font-family:var(--display);font-size:15px;font-weight:700;letter-spacing:.13em;
  text-transform:uppercase;vertical-align:2px}

/* ---- fees: the scorecard -------------------------------------------------- */
.fee{display:flex;flex-direction:column;gap:16px;background:var(--chalk);
  border-radius:var(--r);padding:0 0 24px;overflow:hidden;box-shadow:var(--lift)}
/* Condensed capitals make some plan names run to two lines and others one, so
   the header takes a fixed two-line height — otherwise the card bodies below
   it fall out of alignment across the row. */
.fee h3{margin:0;background:var(--court);color:var(--court-line);padding:14px 24px;
  font-family:var(--display);font-size:28px;font-weight:700;letter-spacing:.03em;
  text-transform:uppercase;line-height:1.05;display:flex;align-items:center;min-height:84px}
.fee-body{display:flex;flex-direction:column;gap:12px;padding:0 24px}
.fee-r{display:flex;flex-wrap:wrap;gap:4px 14px;align-items:center;justify-content:space-between;
  border-bottom:1px dashed var(--hair);padding-bottom:12px}
.fee-r>span:first-child{display:flex;flex-direction:column;gap:2px;
  font-size:14px;font-weight:600;color:var(--ink-soft)}
/* What a longer term works out to a month — the comparison being made. */
.fee-r small{font-size:12px;font-weight:500;color:var(--ink-faint)}
/* Four prices to a card, so they step down from the single headline figure
   the card used to carry. */
.fee-r .price{font-size:32px}
.fee-sub{margin:0;padding:0 24px;font-family:var(--display);font-size:16px;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint)}
.price{font-family:var(--display);font-size:44px;font-weight:700;line-height:.9;
  letter-spacing:-.02em;color:var(--court);font-variant-numeric:tabular-nums}
.unit{font-size:12.5px;color:var(--ink-faint)}
.fee-note{margin:0;padding:0 24px;font-size:14px;line-height:1.6;color:var(--ink-soft)}
/* A 260px card cannot hold a full-size pill without wrapping its label. */
.fee .btn{margin:auto 24px 0;font-size:17px;padding:13px 22px;min-height:46px;letter-spacing:.1em}


/* ---- tournament ------------------------------------------------------------ */
/* The prize list used to live only on green, so its rule was hard-coded to a
   pale hairline. On the tournament page it sits on cream as well, where that
   line is invisible — so the default is the cream rule and green overrides. */
.prize{display:flex;align-items:center;gap:12px;padding:11px 0;
  border-bottom:1px solid var(--hair);
  font-family:var(--display);font-size:21px;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase}
.green .prize{border-bottom-color:rgba(233,242,234,.2)}
.prize::before{content:"";width:9px;height:9px;flex:0 0 9px;background:var(--timber);
  transform:rotate(45deg)}
.tcard{display:flex;flex-direction:column;background:var(--chalk);border-radius:var(--r);
  overflow:hidden;color:var(--ink);box-shadow:var(--lift)}
.tcard-img{position:relative;aspect-ratio:4/5;overflow:hidden;background:var(--parquet-2)}
.tcard-pos{position:absolute;top:0;left:0;z-index:2;background:var(--court-deep);
  color:var(--timber-pale);padding:6px 15px;font-family:var(--display);font-size:18px;
  font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  border-bottom-right-radius:var(--r-sm)}
.tcard-b{padding:18px 22px 22px;display:flex;flex-direction:column;gap:6px;flex:1;
  border-top:5px solid var(--timber)}
.tcard-n{margin:0;font-family:var(--display);font-size:28px;font-weight:700;line-height:1;
  letter-spacing:-.01em;text-transform:uppercase}
.tcard-c{margin:0;font-family:var(--display);font-size:16px;font-weight:600;letter-spacing:.13em;
  text-transform:uppercase;color:var(--court)}
.tcard-p{margin:auto 0 0;padding-top:8px;font-size:14px;line-height:1.55;color:var(--ink-soft)}

/* ---- photograph slots ------------------------------------------------------ */
.art{position:absolute;inset:0;width:100%;height:100%;display:block;object-fit:cover}
.art-tag{position:absolute;top:10px;right:10px;z-index:2;background:rgba(6,20,13,.94);
  color:var(--timber-pale);border-radius:300px;padding:4px 12px;font-family:var(--display);
  font-size:14px;font-weight:700;letter-spacing:.14em;text-transform:uppercase}

/* ---- photograph slideshow -------------------------------------------------
   One frame at a time, on the same chalk card and the same board edge as
   every other surface here. The stage is a fixed ratio so the card never
   jumps height between photographs of different shapes, and the slides
   cross-fade rather than slide, because a slide would fight the swipe. */
.show{position:relative;background:var(--chalk);border-radius:var(--r);overflow:hidden;
  box-shadow:var(--lift);border-top:6px solid var(--timber)}
/* pan-y keeps vertical scrolling but hands sideways gestures to the drag
   handler in mix.js, which is what makes a swipe on a phone work at all. */
.show-stage{position:relative;aspect-ratio:3/2;background:var(--parquet-2);
  touch-action:pan-y}
/* Only a carousel with somewhere to go offers a grab cursor. */
.show.is-swipeable .show-stage{cursor:grab}
/* The photographs take no pointer input at all, so every press lands on the
   stage and the drag handler sees it. A browser does its own thing with an
   image under a finger — drags it, or opens the long-press menu — and that
   was eating the swipe on the portrait shots, where the image covers the
   whole stage. Nothing inside a slide is clickable, so there is nothing to
   lose by making them inert. */
.show-stage img,.show-stage .art-tag{pointer-events:none}
.show-stage img{-webkit-user-drag:none;user-select:none;-webkit-touch-callout:none}
.show.is-dragging .show-stage{cursor:grabbing}
.show-slide{position:absolute;inset:0;opacity:0;pointer-events:none;
  transition:opacity 520ms cubic-bezier(.2,.7,.2,1),
             transform 260ms cubic-bezier(.2,.7,.2,1)}
/* While a finger is down the photograph tracks it exactly, with no easing
   lagging behind the drag. */
.show.is-dragging .show-slide{transition:none}
.show-slide.is-on{opacity:1;pointer-events:auto}
.show-prog{display:block;height:4px;background:rgba(29,38,32,.1)}
.show-prog i{display:block;height:100%;width:100%;background:var(--timber);
  transform:scaleX(0);transform-origin:left}
.show-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:12px 14px}
.show-nav{width:44px;height:44px;flex:0 0 44px;border:0;padding:0;cursor:pointer;
  border-radius:300px;background:transparent;color:var(--ink);
  display:inline-flex;align-items:center;justify-content:center;
  transition:background 160ms ease,transform 120ms ease}
.show-nav:hover{background:rgba(197,138,73,.18)}
.show-nav:active{transform:scale(.94)}
.show-nav svg{width:22px;height:22px;display:block}
.show-dots{display:flex;gap:2px;flex-wrap:wrap;justify-content:center;flex:1 1 auto}
/* Pause/play for anything that advances by itself (WCAG 2.2.2). Same round
   44px button as the arrows; the icon swaps when it is paused. */
.play-toggle .i-play,.play-toggle.is-paused .i-pause{display:none}
.play-toggle.is-paused .i-play{display:block}
/* A portrait photograph in the landscape stage: whole, centred, over a
   blurred and darkened copy of itself. The backdrop is scaled past the edges
   so the blur has no soft border showing at the stage edge. */
.art--backdrop{filter:blur(22px) brightness(.5) saturate(1.15);transform:scale(1.2)}
.art--contain{object-fit:contain}

/* ---- video clip ------------------------------------------------------------
   The same card as the slideshow — chalk face, board edge, one radius, one
   lift — so a clip and a slideshow stacked in one section read as a pair.
   The controls sit on the footage in a dark wash, so they read over any
   frame, and they are the same 44px round targets as the slideshow arrows. */
/* Two clips side by side on a wide screen, stacked on a phone. */
.clips{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:20px}
.clip{margin:0;background:var(--chalk);border-radius:var(--r);overflow:hidden;
  box-shadow:var(--lift);border-top:6px solid var(--timber)}
.clip-stage{position:relative;aspect-ratio:16/9;background:var(--court-deep)}
.clip-stage video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.clip-ctrl{position:absolute;right:12px;bottom:12px;z-index:2;display:flex;gap:8px}
.clip-ctrl button{width:44px;height:44px;border:0;padding:0;border-radius:300px;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;color:#fff;
  background:rgba(8,26,16,.72);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  transition:background 160ms ease,transform 120ms ease}
.clip-ctrl button:hover{background:rgba(8,26,16,.9)}
.clip-ctrl button:active{transform:scale(.94)}
.clip-ctrl svg{width:20px;height:20px;display:block}
.clip-play .i-pause,.clip-play.is-playing .i-play{display:none}
.clip-play.is-playing .i-pause{display:block}
.clip-sound .i-sound,.clip-sound.is-on .i-muted{display:none}
.clip-sound.is-on .i-sound{display:block}

/* The stage is taller on a phone, where a 3:2 frame across a 335px column
   leaves the subject too small to read. */
@media (max-width:720px){
  .show-stage{aspect-ratio:4/3}
  .show-foot{padding:10px 8px}
}


/* ---- disclosure ------------------------------------------------------------- */
details{border-top:1px solid var(--hair)}
.green details{border-top:1px solid rgba(233,242,234,.22)}
summary::-webkit-details-marker{display:none}
summary{list-style:none;cursor:pointer;padding:20px 0;display:flex;gap:14px;align-items:center;
  justify-content:space-between;font-family:var(--display);font-size:21px;font-weight:600;
  letter-spacing:.11em;text-transform:uppercase}
/* ---- the racket that opens a disclosure --------------------------------
   Not a "+" in a circle: a racket, which says press-me in the language the
   rest of the page already speaks, and which can act when pressed. On open it
   swings through and the shuttle leaves it; on close it settles back. Drawn
   in currentColor, so one glyph serves both the cream and the green sections.
   The whole thing is decorative — the summary text is the accessible name — so
   it carries aria-hidden and never takes focus of its own. */
/* Obvious at rest, not only on hover. The racket is drawn exactly as before,
   but it always sits on a filled timber disc with the same board shadow as
   every other pressable thing on the page, at full strength in the accent
   colour. A filled disc does not read as a magnifying glass the way an
   outlined ring did. It lifts on hover and sinks when pressed, like a button,
   and the question beside it underlines — so the whole row says "press". */
.chev{position:relative;width:44px;height:44px;flex:0 0 44px;border:0;border-radius:300px;
  background:rgba(197,138,73,.22);color:var(--timber-dk);
  box-shadow:0 3px 0 rgba(137,86,31,.3);
  display:inline-flex;align-items:center;justify-content:center;
  transition:background 180ms ease,transform 140ms ease,box-shadow 140ms ease}
summary:hover .chev{background:rgba(197,138,73,.34);transform:translateY(-2px);
  box-shadow:0 5px 0 rgba(137,86,31,.3)}
summary:active .chev{transform:translateY(1px);box-shadow:0 1px 0 rgba(137,86,31,.3)}
details[open] .chev{background:var(--timber);color:var(--on-timber)}
.green .chev{background:rgba(238,211,172,.18);color:var(--timber-pale);box-shadow:0 3px 0 rgba(0,0,0,.28)}
.green summary:hover .chev{background:rgba(238,211,172,.28)}
.green details[open] .chev{background:var(--timber);color:var(--on-timber)}
summary > span:first-child{text-decoration:underline;text-decoration-color:transparent;
  text-underline-offset:5px;text-decoration-thickness:2px;transition:text-decoration-color 160ms ease}
summary:hover > span:first-child{text-decoration-color:var(--timber)}
.chev-svg{width:28px;height:28px;display:block;overflow:visible}

/* Resting: cocked back a little, the way a racket is held ready. It comes
   forward on hover, then swings through on open. */
.chev-rk{transform-box:fill-box;transform-origin:88% 94%;
  transform:rotate(-14deg);
  transition:transform 220ms cubic-bezier(.2,.7,.2,1)}
summary:hover .chev-rk{transform:rotate(-24deg)}
/* Once, as a question first scrolls into view, its racket's disc pulses:
   the disc brightens and a ring of light spreads out from it and fades,
   three times, then it rests. Enough to say "press this" without the page
   twitching. Three pulses keep it under five seconds — past that, anything
   that moves on its own needs a control to stop it. The ring is scaled, not
   grown with a shadow, so it costs nothing to draw. */
.chev::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  box-shadow:0 0 0 2px var(--timber);opacity:0}
/* --pulse-phase is set by mix.js so every racket joins the same beat; the
   ring on ::after inherits it, so disc and ring stay in step as well. */
.chev.hint{animation:mx-glow 1400ms ease-in-out 3;animation-delay:var(--pulse-phase,0ms)}
.chev.hint::after{animation:mx-pulse 1400ms cubic-bezier(.2,.6,.3,1) 3;
  animation-delay:var(--pulse-phase,0ms)}
@keyframes mx-glow{
  0%,100%{background:rgba(197,138,73,.22)}
  35%    {background:rgba(197,138,73,.52)}
}
@keyframes mx-pulse{
  0%  {opacity:.9;transform:scale(1)}
  100%{opacity:0;transform:scale(1.6)}
}
/* On green the ring and the glow are the pale board colour, as the disc is. */
.green .chev::after{box-shadow:0 0 0 2px var(--timber-pale)}
.green .chev.hint{animation-name:mx-glow-green}
@keyframes mx-glow-green{
  0%,100%{background:rgba(238,211,172,.18)}
  35%    {background:rgba(238,211,172,.44)}
}
details[open] .chev-rk{animation:mx-chev-swing 620ms cubic-bezier(.35,0,.2,1) forwards}
@keyframes mx-chev-swing{
  0%{transform:rotate(-24deg)}
  30%{transform:rotate(26deg)}   /* contact */
  62%{transform:rotate(-6deg)}
  100%{transform:rotate(2deg)}
}

/* The shuttle sits on the strings, invisible, until the racket sends it. */
.chev-bird{transform-box:fill-box;transform-origin:50% 50%;opacity:0}
details[open] .chev-bird{animation:mx-chev-hit 620ms cubic-bezier(.3,0,.2,1) forwards}
@keyframes mx-chev-hit{
  0%{opacity:0;transform:translate(0,0) scale(1) rotate(0deg)}
  26%{opacity:1;transform:translate(0,0) scale(1) rotate(0deg)}
  70%{opacity:.9;transform:translate(15px,-13px) scale(.72) rotate(150deg)}
  100%{opacity:0;transform:translate(23px,-20px) scale(.6) rotate(230deg)}
}

/* Closing plays the other half of the rally: a lift. The racket dips under
   the returning shuttle and sends it back up over the net, and settles into
   the ready angle it started from. */
.chev.lift .chev-rk{animation:mx-chev-lift 640ms cubic-bezier(.3,0,.25,1) forwards}
@keyframes mx-chev-lift{
  0%{transform:rotate(2deg)}
  32%{transform:rotate(40deg)}    /* dip under it */
  68%{transform:rotate(-36deg)}   /* and lift */
  100%{transform:rotate(-14deg)}  /* ready again */
}
.chev.lift .chev-bird{animation:mx-chev-lifted 640ms cubic-bezier(.3,0,.25,1) forwards}
@keyframes mx-chev-lifted{
  0%{opacity:0;transform:translate(13px,10px) scale(.58) rotate(210deg)}
  26%{opacity:1;transform:translate(2px,3px) scale(.86) rotate(120deg)}
  100%{opacity:0;transform:translate(-6px,-24px) scale(1) rotate(0deg)}
}

/* The panel is a single box so its height can be animated in both directions
   — see the disclosure block in mix.js, which takes over the click so the
   closing half can be animated at all. It clips only while the height is
   moving: clipped all the time, it cut the focus ring and the board shadow
   off anything inside an open panel that sat against its edge. */
.disclosure-body.is-moving{overflow:hidden}
.det-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:18px;
  padding:0 0 28px;align-items:stretch}
.det-grid p{margin:0;font-size:15px;line-height:1.65;color:var(--ink-soft)}
.green .det-grid p{color:var(--on-court)}
.det-grid strong{color:var(--ink)}
.green .det-grid strong{color:var(--court-line)}

/* FAQ */
.faq-block{margin-bottom:46px}
.faq-h{margin:0 0 4px;font-family:var(--display);font-size:clamp(32px,4.4vw,54px);font-weight:700;
  line-height:.92;letter-spacing:-.012em;text-transform:uppercase;
  padding-bottom:12px;border-bottom:4px solid var(--timber)}
.faq details{border-top:0;border-bottom:1px solid var(--hair)}
.faq summary{font-size:23px;letter-spacing:.03em;padding:19px 0;align-items:center}
.faq p{margin:0;padding:0 0 22px;font-size:16px;line-height:1.7;color:var(--ink-soft);max-width:660px}

/* ---- location ---------------------------------------------------------------- */
.warn{display:flex;flex-wrap:wrap;gap:16px;align-items:center;background:var(--court-deep);
  color:var(--court-line);border-radius:var(--r);padding:22px 24px;margin-top:28px;
  border-left:8px solid var(--timber)}
.warn-i{width:44px;height:44px;flex:0 0 44px;border-radius:50%;background:var(--timber);
  color:var(--on-timber);display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--display);font-size:26px;font-weight:700;line-height:1}
.warn p{margin:0;font-size:17px;line-height:1.55;letter-spacing:-.25px;max-width:780px}
.split{display:flex;flex-wrap:wrap;gap:28px;margin-top:28px}
.split-a{flex:1 1 300px;min-width:0;display:flex;flex-direction:column;gap:22px}
.split-b{flex:1 1 400px;min-width:0}
.lbl{margin:0 0 6px;font-family:var(--display);font-size:17px;font-weight:600;letter-spacing:.17em;
  text-transform:uppercase;color:var(--ink-faint)}
.val{margin:0;font-size:18px;line-height:1.5;letter-spacing:-.25px;max-width:420px}
.mapbox{width:100%;aspect-ratio:4/3;border-radius:var(--r);overflow:hidden;box-shadow:var(--lift)}
.map{width:100%;height:100%;border:0;display:block;background:var(--parquet-2)}
.mapcard{width:100%;height:100%;background:var(--court);color:var(--court-line);position:relative;
  display:flex;flex-direction:column;justify-content:flex-end;gap:10px;padding:26px;overflow:hidden}
.mapcard-lines{position:absolute;inset:0;background:var(--net);pointer-events:none}
.mapcard-pin{position:absolute;top:22px;left:26px;width:44px;height:44px;border-radius:50%;
  background:var(--timber);color:var(--on-timber);display:inline-flex;align-items:center;
  justify-content:center;font-size:22px;line-height:1}
.mapcard h3{position:relative;margin:0;font-family:var(--display);font-size:32px;font-weight:700;
  line-height:1;letter-spacing:.01em;text-transform:uppercase}
.mapcard p{position:relative;margin:0;font-size:15px;line-height:1.6;color:var(--on-court);
  max-width:400px}
.mapcard-go{position:relative;font-family:var(--display);font-size:17px;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--timber-pale)}

/* ---- reviews ------------------------------------------------------------------
   A fixed card and a bar counting down to the next review, on the chalk
   surface. */
.rev{position:relative;background:var(--chalk);border-top:6px solid var(--court);
  border-radius:var(--r);padding:26px 26px 32px;margin-top:32px;overflow:hidden;
  box-shadow:var(--lift)}
.rev-prog{position:absolute;left:0;right:0;bottom:0;height:4px;background:rgba(29,38,32,.1)}
.rev-prog i{display:block;height:100%;width:100%;background:var(--timber);
  transform:scaleX(0);transform-origin:left}
.rev-top{display:flex;flex-wrap:wrap;gap:10px 18px;align-items:center;justify-content:space-between}
.rev-stars{font-size:18px;letter-spacing:.12em;color:var(--timber-dk)}
.rev-body{margin-top:20px;min-height:124px}
.rev-q{margin:0;font-size:18.5px;line-height:1.6;letter-spacing:-.35px;color:var(--ink);
  max-width:700px}
.rev-who{margin:15px 0 0;font-family:var(--display);font-size:21px;font-weight:600;
  letter-spacing:.11em;text-transform:uppercase}
.rev-src{margin-left:10px;font-family:var(--body);font-size:12.5px;font-weight:500;letter-spacing:0;
  text-transform:none;color:var(--ink-faint)}
.rev-foot{display:flex;flex-wrap:wrap;gap:14px;align-items:center;justify-content:space-between;
  margin-top:20px}
/* The dot reads as 9px but takes a 24px hit area — a thumb has to be able to
   land on it. */
.rev-actions{display:flex;align-items:center;gap:8px}
.rev-dots{display:flex;gap:2px;margin-left:-6px}
/* The visible dot is 9px; the button around it is the tap target. With two
   carousels on a page there are a lot of these to hit, so it is bigger than
   the 24px minimum rather than exactly at it. */
.dot{width:28px;height:28px;border:0;padding:0;background:none;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center}
/* An idle dot is a control, not decoration: WCAG asks 3:1 for a UI
   component's non-text contrast, and a pale cream dot on a chalk card gave
   1.7. This one gives 3.3 and still recedes behind the selected dot. */
.dot::before{content:"";width:9px;height:9px;border-radius:50%;background:#9a8a68;
  transition:background 160ms ease,transform 160ms ease}
.dot[aria-current="true"]::before{background:var(--court);transform:scale(1.35)}
.dot:hover::before{background:var(--timber-dk)}
.rev-link{font-size:12px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  text-decoration:underline}
.rev-fade{animation:mx-fade 320ms ease both}

/* ---- footer --------------------------------------------------------------------- */
.ftr{background:var(--court-deep);color:var(--court-line);padding:52px 0 40px}
.ftr-in{display:flex;flex-wrap:wrap;gap:32px 44px}
/* Footer identity: the same condensed capitals as every other display line
   on the site (the inline version was mixed case, left over from the old
   typeface), and addresses in the green-surface text token rather than two
   different hand-typed greys on different pages. */
.ftr-brand{margin:0;font-family:var(--display);font-size:24px;font-weight:700;line-height:1;
  letter-spacing:.02em;text-transform:uppercase}
.ftr-addr{margin:10px 0 0;font-size:15px;line-height:1.6;color:var(--on-court-soft);max-width:440px}
.ftr-addr + .ftr-addr{margin-top:4px}
.ftr-addr b{color:var(--court-line);font-weight:600}
/* 4px of padding takes these from 23px tall to 31px: a footer link was the
   smallest thing on the page to hit, and under the 24px minimum. The gap
   comes down by the same amount, so the column looks unchanged. */
.ftr-col a{padding:4px 0}
.ftr-col{flex:0 1 200px;display:flex;flex-direction:column;gap:3px;
  font-family:var(--display);font-size:19px;font-weight:500;letter-spacing:.08em;
  text-transform:uppercase}
.ftr-col a:hover{color:var(--timber-pale)}
.ftr-copy{margin:34px 0 0;padding-top:22px;border-top:1px solid rgba(233,242,234,.18);
  font-size:13px;line-height:1.6;color:var(--on-court-soft)}
.social{display:flex;gap:10px;flex-wrap:wrap;margin-top:16px}
.social a{width:44px;height:44px;border-radius:300px;border:1px solid rgba(233,242,234,.26);
  display:inline-flex;align-items:center;justify-content:center;
  transition:background 160ms ease,border-color 160ms ease,transform 140ms ease}
.social a:hover{background:var(--court);border-color:var(--timber);transform:translateY(-2px)}
.social svg{width:19px;height:19px;display:block;fill:currentColor}

/* ==================================================================
   MOTION
   Everything here is either the room reacting to you (a press, a
   line being painted) or the game itself: a shuttle in flight, a
   smash landing, a scoreboard ticking over. Nothing decorative
   moves on its own, and the whole layer switches off for anyone
   who asked for reduced motion.
   ================================================================== */
@keyframes mx-rise{from{opacity:0;transform:translateY(22px)}to{opacity:1;transform:none}}
@keyframes mx-wipe{from{opacity:0;transform:translateX(-42px)}to{opacity:1;transform:none}}
@keyframes mx-fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
/* The serve: the hero art drops in like a shuttle landing. */
@keyframes mx-drop{from{opacity:0;transform:translateY(-26px) rotate(-1.5deg)}to{opacity:1;transform:none}}
.rise{animation:mx-rise 640ms cubic-bezier(.2,.7,.2,1) both}
.wipe{animation:mx-wipe 760ms cubic-bezier(.2,.7,.2,1) both}
.drop{animation:mx-drop 800ms cubic-bezier(.2,.8,.3,1) both}
.js .reveal{opacity:0;transform:translateY(22px);
  transition:opacity 600ms cubic-bezier(.2,.7,.2,1),transform 600ms cubic-bezier(.2,.7,.2,1)}
.js .reveal.in{opacity:1;transform:none}
/* Content is only ever hidden when JavaScript is running (html.js is set by a
   one-line script in each page's head), so a visitor without it sees every
   section. If the script dies part-way, it never sets html.js-ready, and this
   reveals anything still hidden at five seconds — CSS cannot be stopped by a
   JavaScript error. When the script does finish, the rule never applies, so
   the scroll reveal still plays for everything further down. */
.js:not(.js-ready) .reveal:not(.in){animation:mx-failsafe 1ms 5s forwards}
@keyframes mx-failsafe{to{opacity:1;transform:none}}

/* --- the rally: a shuttle crossing the hero ------------------------------
   Drawn onto the hero's own court markings, so it reads as a shuttle played
   down the court you are looking at rather than a sticker sliding past. Runs
   once on load, then rests. */
/* Above the content layer, not below it: the markings scrim sits at z-index 1
   and is generated after every child, so anything sharing that level is
   painted out. The shuttle is small, brief and pointer-transparent, so it can
   safely cross in front — its trail is held light so it never competes with
   the headline it passes over. */
.rally{position:absolute;inset:0;z-index:3;pointer-events:none;overflow:hidden}
.rally svg{position:absolute;inset:0;width:100%;height:100%}
.rally-path{fill:none;stroke:#eed3ac;stroke-width:2.5;stroke-linecap:round;
  stroke-dasharray:6 12;stroke-dashoffset:1400;opacity:0;
  animation:mx-trail 2.2s cubic-bezier(.33,.05,.4,1) .55s forwards}
@keyframes mx-trail{
  0%{opacity:0;stroke-dashoffset:1400}
  12%{opacity:.5}
  70%{opacity:.5;stroke-dashoffset:0}
  100%{opacity:0;stroke-dashoffset:0}
}
.rally-bird{opacity:0;offset-rotate:auto;offset-distance:0%;
  animation:mx-fly 2.2s cubic-bezier(.33,.05,.4,1) .55s forwards}
@keyframes mx-fly{
  0%{opacity:0;offset-distance:0%}
  9%{opacity:1}
  70%{opacity:1;offset-distance:100%}
  100%{opacity:0;offset-distance:100%}
}

/* --- the jump smash ------------------------------------------------------
   A player doing a jump smash over a net, drawn and moved by mix.js in a band
   across the top of the results. The band takes the scene's own shape, so on
   a phone the player and the net fill it rather than sitting in a strip of
   empty green; on a wide screen it stops at 680px and the scene scales to fit.
   It sits above the section's content (z-index 3, over the content's 2),
   because the copy fades back in while the player is still on court; the
   band takes no pointer input and fades away when the stroke is finished. */
/* The height is worked out from the width rather than set with aspect-ratio:
   aspect-ratio plus a max-height makes the browser keep the shape by
   narrowing the band, which left it 1055px wide on a 1280px screen with the
   scene pushed left. 64.47vw is the scene's own 490:760 proportion. */
.smash{position:absolute;left:0;right:0;top:0;height:min(680px,64.47vw);
  z-index:3;pointer-events:none;overflow:hidden;opacity:0}
.smash svg{display:block;width:100%;height:100%}
.smash.go{opacity:1}
.smash.done{opacity:0;transition:opacity 450ms ease}
/* Content waits behind the stroke and returns as the player lands. */
.smash-hold{opacity:0}
#tournament > .wrap{transition:opacity 560ms cubic-bezier(.2,.7,.2,1)}

/* --- the scoreboard ticks over ------------------------------------------
   The numbers count up when the board comes into view, the way a real one
   rolls to its total. Script does the counting; this is the flick of the
   digit as it settles. */
.board-n{display:inline-block}
.board-c.in .board-n{animation:mx-tick 520ms cubic-bezier(.2,.8,.3,1) both}
@keyframes mx-tick{from{transform:translateY(10px);opacity:.35}to{transform:none;opacity:1}}

/* --- section headings are underlined by a line being painted ------------- */
/* fit-content, not inline-block: the underline has to end where the words
   end, but the heading must still start its own line — as an inline-block it
   flowed up alongside the eyebrow above it. */
.h2.drawn{position:relative;display:block;width:fit-content;max-width:100%;padding-bottom:.1em}
.h2.drawn::after{content:"";position:absolute;left:.035em;right:0;bottom:0;height:5px;
  background:var(--timber);transform:scaleX(0);transform-origin:left;border-radius:2px}
.h2.drawn.in::after{animation:mx-paint 620ms cubic-bezier(.2,.7,.2,1) 120ms forwards}
@keyframes mx-paint{to{transform:scaleX(1)}}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation:none!important;transition:none!important}
  .js .reveal{opacity:1;transform:none}
  .rally,.smash{display:none}
  .show-prog,.rev-prog{display:none}
  /* Chrome that slides in and out of view is motion, so it is not used here:
     the header stays where it is and the action bar keeps its old rule. */
  .hdr.tucked{transform:none}
  details[open] .chev-rk{transform:rotate(2deg)}
  .chev-bird{display:none}
  .smash-hold{opacity:1}
  .h2.drawn::after{transform:scaleX(1)}
}

/* ==================================================================
   MOBILE — three devices for a narrow screen: swipe rails, a fee
   comparison table in place of the fee cards, and a sticky
   call-to-action bar. All of them in the court's own colours.
   ================================================================== */

.cta-bar{
  position:fixed;left:0;right:0;bottom:0;z-index:60;display:none;
  gap:10px;padding:10px 14px calc(10px + env(safe-area-inset-bottom,0px));
  background:rgba(8,51,31,.96);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  border-top:3px solid var(--timber);
  transform:translateY(120%);transition:transform 340ms cubic-bezier(.22,.68,.24,1);
}
.cta-bar.show{transform:none}
/* Inside a fixed bar there is no room to lift, and a shadow under a button
   sitting on the bar's own edge reads as a rendering fault — so this is the
   one place the shared press is deliberately dropped. */
.cta-bar .btn{flex:1 1 0;justify-content:center;padding:13px 12px;font-size:17px;
  letter-spacing:.08em;gap:8px;min-width:0;box-shadow:none;white-space:nowrap}
.cta-bar .btn:hover,.cta-bar .btn:active{transform:none;box-shadow:none}
.cta-bar .btn--line{color:var(--court-line);box-shadow:inset 0 0 0 2px currentColor}
.cta-bar .btn .ico{width:18px;height:18px;flex:0 0 18px}

.fees-table{display:none}
.fees-table table{width:100%;border-collapse:collapse;background:var(--chalk);color:var(--ink);
  border-radius:var(--r);overflow:hidden;box-shadow:var(--lift)}
/* Four columns on a 375px screen: the padding and the figures are as
   large as will fit without the table pushing the page sideways, and the
   container scrolls if a longer price ever arrives. */
.fees-table th,.fees-table td{padding:10px 5px;text-align:right;
  border-bottom:1px dashed var(--hair);white-space:nowrap}
.fees-table th:first-child,.fees-table td:first-child{text-align:left;white-space:normal}
.fees-table thead th{background:var(--court-deep);font-family:var(--display);font-size:12.5px;
  font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--timber-pale);
  border-bottom:0}
.fees-table thead th:first-child{color:var(--court-line)}
.fees-table tbody th{font-family:var(--display);font-size:17px;font-weight:600;
  letter-spacing:.04em;text-transform:uppercase;line-height:1.05}
.fees-table td{font-family:var(--display);font-size:17px;font-weight:700;line-height:1;
  color:var(--court);font-variant-numeric:tabular-nums}
.fees-table tr:last-child th,.fees-table tr:last-child td{border-bottom:0}
.fees-solo{display:flex;flex-wrap:wrap;gap:10px 16px;align-items:baseline;
  justify-content:space-between;background:var(--chalk);border-radius:var(--r);
  border-top:6px solid var(--timber);padding:20px;margin-top:14px;box-shadow:var(--lift)}
.fees-solo .price{font-size:34px}
.fees-solo-p{display:flex;gap:6px;align-items:baseline}
.fees-solo-k{display:flex;flex-direction:column;gap:2px;font-family:var(--display);font-size:21px;
  font-weight:600;letter-spacing:.04em;text-transform:uppercase}
.fees-solo-k small{font-family:var(--body);font-size:12px;font-weight:400;letter-spacing:0;
  text-transform:none;color:var(--ink-faint)}
/* Which plan is how many days a week: the table head has no room for it. */
.fee-days{display:flex;flex-direction:column;gap:4px;margin:12px 0 0;font-size:13px;
  line-height:1.5;color:var(--ink-soft)}
.fee-days b{margin-right:6px;font-family:var(--display);font-size:16px;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink)}
.fee-days small{display:block;font-size:12.5px;color:var(--ink-faint)}

/* Between a phone and a wide desktop, the logo, six links and the trial
   button no longer fit on one line, and flex-wrap left the button stranded on
   a row of its own — at 760px the header ran to three rows. So this range
   takes the phone layout: logo and button share the top row, and the links
   get one row of their own beneath, scrolling only if they have to. */
/* "Swipe for more" only means something where the row actually swipes. */
.rail-note{display:none}

@media (max-width:1220px){
  .nav{row-gap:4px}
  .navlinks{order:3;flex:1 0 100%;flex-wrap:nowrap;overflow-x:auto;gap:22px;
    padding-bottom:2px;-webkit-overflow-scrolling:touch;scrollbar-width:none}
  .navlinks::-webkit-scrollbar{display:none}
  .navlinks a{white-space:nowrap}
}

@media (max-width:720px){

  /* 1. Card rows become swipeable rails. Cards sit at 78% width so the next
        one peeks in — the affordance that says "swipe me". */
  .rail{
    display:flex!important;gap:14px;overflow-x:auto;overflow-y:hidden;
    scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
    scrollbar-width:none;-ms-overflow-style:none;
    margin-inline:-20px;padding:2px 20px 12px;scroll-padding-inline:20px;
    overscroll-behavior-x:contain;
  }
  .rail::-webkit-scrollbar{display:none}
  .rail > *{flex:0 0 78%;scroll-snap-align:start;min-width:0}
  /* Scroll-reveal cannot fire for cards parked off-screen to the right, so
     inside a rail everything is simply visible. */
  .rail .reveal{opacity:1!important;transform:none!important}
  .rail-note{display:block;margin:10px 0 0;font-family:var(--display);font-size:16px;font-weight:600;
    letter-spacing:.13em;text-transform:uppercase;color:var(--ink-faint)}
  .green .rail-note{color:var(--timber-pale)}

  /* 2. Fee cards give way to a comparison table */
  .fees-cards{display:none}
  .fees-table{display:block;overflow-x:auto}

  /* 3. The sticky action bar is a phone device only */
  .cta-bar{display:flex}

  /* 4. The display sizes come down. The clamp minimum that a big desktop
        headline needs (62px) is not a phone size — the closing "Come and
        play. The first session is free." ran to five lines at 375px. */
  .h1{font-size:clamp(46px,12vw,62px)}
  .hero .h1{font-size:clamp(42px,11vw,54px)}
  .h2{font-size:clamp(36px,9vw,46px)}

  /* 5. Less dead space between sections */
  .sec{padding:60px 0}
  .sec--sm{padding:46px 0}
  .hero{padding:52px 0 64px}
  .wrap{padding:0 20px}

  /* 6. Scoreboard two-up instead of four stacked */
  .board{grid-template-columns:1fr 1fr}
  .board-c{padding:20px 16px 18px;border-right:0;
    border-bottom:1px solid rgba(233,242,234,.14)}
  .board-c:nth-child(odd){border-right:1px solid rgba(233,242,234,.14)}
  .board-n{font-size:clamp(46px,13vw,64px)}
  .board-l{font-size:15px;margin-top:10px}

  html{scroll-padding-top:128px}

  /* 7. Compact header. It stays sticky on a phone — most visitors are parents
        on one, and the free-trial action should never scroll away. To pay for
        that it has to stay short: brand and action on one line, links on a
        single scrolling line beneath rather than wrapping to three. */
  .nav{padding:10px 20px;gap:8px 12px}
  .brand img{width:36px;height:36px}
  .brand-txt{font-size:20px}
  .brand-sub{display:none}
  /* 40px was a compromise from when the header was permanent and every pixel
     of it cost viewport. It retracts on scroll now, so the most important
     button on the page can have a full-size tap target back. */
  .hdr .btn{padding:11px 16px;font-size:15px;min-height:44px;gap:7px}
  .navlinks{order:3;flex:1 0 100%;flex-wrap:nowrap;overflow-x:auto;gap:18px;font-size:17px;
    padding-bottom:2px;-webkit-overflow-scrolling:touch;scrollbar-width:none}
  .navlinks::-webkit-scrollbar{display:none}
  .navlinks a{white-space:nowrap}
  .strip{font-size:15px;padding:8px 16px;gap:4px 12px;letter-spacing:.1em}

  /* 8. A phone screen is almost entirely the text column, so the markings
        scrim has to cover the full width rather than fade out across it. */
  .green:has(.markings)::after{
    background:linear-gradient(180deg,
      rgba(15,92,63,.97) 0%,rgba(15,92,63,.9) 60%,rgba(15,92,63,.74) 100%)}
}

/* Three pills side by side on a 375px screen, which is why the bar says
   "Call" and "WhatsApp" where the page says "Call the coach" and "WhatsApp
   us". Condensed type loses a couple of points and the tracking as well. */
@media (max-width:400px){
  .cta-bar .btn{font-size:15px;padding:12px 8px;letter-spacing:.04em;gap:6px}
  .cta-bar .btn .ico{width:16px;height:16px;flex:0 0 16px}
}

/* A landscape phone has no height to spare; let the header scroll away. */
@media (max-height:560px){ .hdr{position:static} }

/* ---- the trial booker ----------------------------------------------------------
   The form and "your first session" side by side: the form on the ONE chalk
   card, the first-session list on green, so the two read as the thing you
   do and the thing you need to know. */
.trial{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);gap:24px;align-items:start}
.book{background:var(--chalk);border-radius:var(--r);border-top:6px solid var(--timber);
  box-shadow:var(--lift);padding:30px}
.q{border:0;margin:0 0 26px;padding:0;min-width:0}
.q legend{display:flex;align-items:center;gap:12px;padding:0;margin:0 0 12px;
  font-family:var(--display);font-size:23px;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;color:var(--ink)}
.q-n{width:30px;height:30px;flex:0 0 30px;border-radius:50%;background:var(--court);
  color:var(--court-line);display:inline-flex;align-items:center;justify-content:center;
  font-size:17px;letter-spacing:0}

/* A choice is a pill, like everything else you press. The radio itself is
   kept in the page (visually hidden, never display:none) so it still takes
   focus and arrow keys. */
.chips{display:flex;flex-wrap:wrap;gap:10px}
.chip{position:relative;display:inline-flex}
.chip input{position:absolute;opacity:0;width:1px;height:1px;margin:0;pointer-events:none}
.chip > span{display:flex;flex-direction:column;justify-content:center;min-height:52px;
  padding:8px 22px;border-radius:300px;cursor:pointer;background:#fff;color:var(--ink);
  box-shadow:inset 0 0 0 2px #9a8a68,0 3px 0 rgba(11,40,26,.14);
  transition:background 160ms ease,color 160ms ease,box-shadow 160ms ease,transform 120ms ease}
.chip b{font-family:var(--display);font-size:19px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;line-height:1.1}
.chip small{font-size:12.5px;line-height:1.35;color:var(--ink-faint)}
.chip:hover > span{transform:translateY(-2px);
  box-shadow:inset 0 0 0 2px var(--timber-dk),0 5px 0 rgba(11,40,26,.14)}
.chip input:checked + span{background:var(--court);color:var(--court-line);
  box-shadow:inset 0 0 0 2px var(--court),0 3px 0 var(--court-deep);
  animation:mx-pop 280ms cubic-bezier(.3,1.5,.5,1)}
.chip input:checked + span small{color:var(--on-court-soft)}
.chip input:focus-visible + span{outline:3px solid var(--timber);outline-offset:3px}
/* A tap lands like a shuttle on the strings: a small give, then back. */
@keyframes mx-pop{0%{transform:scale(.92)}100%{transform:none}}

/* The suggestion is the scoreboard of the form: court-deep, timber edge,
   the batch in display type. Until there is one it is a dashed outline that
   says what to do next. */
.pick{margin:0 0 28px;background:var(--court-deep);color:var(--court-line);
  border-radius:var(--r);border-left:8px solid var(--timber);padding:22px 24px}
.pick.is-new{animation:mx-fade 320ms ease both}
.pick-k{margin:0;font-family:var(--display);font-size:16px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--timber-pale)}
.pick-p{margin:6px 0 0;font-family:var(--display);font-size:clamp(34px,4vw,46px);font-weight:700;
  line-height:.95;text-transform:uppercase}
.pick-t{margin:6px 0 0;font-family:var(--display);font-size:30px;font-weight:600;line-height:1.05;
  font-variant-numeric:tabular-nums}
.pick-d{margin:6px 0 0;font-size:14.5px;line-height:1.5;color:var(--on-court)}
.pick .chips{margin-top:12px}
.pick .chip > span{background:rgba(255,255,255,.06);color:var(--court-line);
  box-shadow:inset 0 0 0 2px rgba(233,242,234,.42),0 3px 0 rgba(0,0,0,.3)}
.pick .chip small{color:var(--on-court-soft)}
/* These chips are batch times. The timings board writes them "5:30 pm",
   so they are not set in capitals here either. */
.pick .chip b{text-transform:none;letter-spacing:.02em;font-variant-numeric:tabular-nums}
.pick .chip:hover > span{box-shadow:inset 0 0 0 2px var(--timber-pale),0 5px 0 rgba(0,0,0,.3)}
.pick .chip input:checked + span{background:var(--timber);color:var(--on-timber);
  box-shadow:inset 0 0 0 2px var(--timber),0 3px 0 var(--timber-dk)}
.pick .chip input:checked + span small{color:var(--on-timber)}
.pick .chip input:focus-visible + span{outline-color:var(--timber-pale)}
.pick-fee{margin:16px 0 0;display:flex;flex-wrap:wrap;gap:6px 10px;align-items:baseline}
.pick .price{color:var(--court-line);font-size:40px}
.pick .unit{color:var(--on-court-soft)}
.pick-freq{font-family:var(--display);font-size:17px;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;color:var(--timber-pale)}
.pick-freq::before{content:"·";margin-right:10px;color:var(--on-court-soft)}
.pick-note{margin:12px 0 0;font-size:13.5px;line-height:1.55;color:var(--on-court-soft);max-width:540px}

/* Fields. Their edge is dark enough to find (3:1 against the card, the
   contrast a control's boundary needs), and focus turns it court green. */
.fields{display:grid;grid-template-columns:minmax(0,1fr) 120px;gap:18px 16px}
.field{display:flex;flex-direction:column;gap:7px;min-width:0}
.field--wide{grid-column:1 / -1}
.field label{font-family:var(--display);font-size:17px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-soft)}
.field label i{margin-left:6px;font-family:var(--body);font-size:12.5px;font-style:normal;
  font-weight:500;letter-spacing:0;text-transform:none;color:var(--ink-faint)}
/* 16px text, so iOS does not zoom the page when a field takes focus. */
.field input,.field textarea{width:100%;min-height:52px;padding:13px 15px;
  font:500 16px/1.4 var(--body);color:var(--ink);background:#fff;
  border:2px solid #9a8a68;border-radius:var(--r-sm);
  transition:border-color 160ms ease,box-shadow 160ms ease}
.field textarea{resize:vertical;min-height:86px}
.field input:focus,.field textarea:focus{outline:none;border-color:var(--court);
  box-shadow:0 0 0 4px rgba(15,92,63,.18)}
.field.has-error input{border-color:#a3321f}
.field.has-error input:focus{box-shadow:0 0 0 4px rgba(163,50,31,.16)}
.field-err{margin:0;font-size:13.5px;font-weight:600;line-height:1.45;color:#a3321f}
.book-go{margin-top:26px}
.book-note:empty{display:none}
.book-note{margin:14px 0 0;font-size:13.5px;line-height:1.6;color:var(--ink-faint);max-width:540px}
.book-note a{margin-left:4px;font-weight:600;color:var(--court);text-decoration:underline}

/* Your first session: the green card beside the form. */
.first{position:relative;overflow:hidden;background:var(--court);color:var(--court-line);
  border-radius:var(--r);border-top:6px solid var(--timber);box-shadow:var(--lift);
  padding:28px 26px 30px}
.first::before{content:"";position:absolute;inset:0;background:var(--net);pointer-events:none}
.first > *{position:relative}
.first .eyebrow{margin-bottom:12px;font-size:16px;color:var(--timber-pale)}
.first-h{margin:0;font-family:var(--display);font-size:clamp(34px,3.6vw,44px);font-weight:700;
  line-height:.92;letter-spacing:-.005em;text-transform:uppercase}
.first-list{list-style:none;margin:24px 0 0;padding:0;display:flex;flex-direction:column;gap:20px}
.first-i{display:flex;gap:14px;align-items:flex-start}
.first-ic{width:44px;height:44px;flex:0 0 44px;border-radius:50%;background:rgba(238,211,172,.16);
  color:var(--timber-pale);display:inline-flex;align-items:center;justify-content:center}
.first-ic svg{width:24px;height:24px;display:block}
.first-k{margin:0;font-family:var(--display);font-size:21px;font-weight:700;letter-spacing:.05em;
  line-height:1.15;text-transform:uppercase}
.first-v{margin:4px 0 0;font-size:14.5px;line-height:1.55;color:var(--on-court)}
.pip--line{margin-left:4px;padding:1px 9px;font-size:13px;background:transparent;
  color:var(--timber-pale);box-shadow:inset 0 0 0 1.5px currentColor}

@media (max-width:960px){
  .trial{grid-template-columns:minmax(0,1fr)}
}
@media (max-width:720px){
  .book{padding:24px 18px}
  .fields{grid-template-columns:minmax(0,1fr) 96px}
  .chip > span{padding:8px 18px}
  .pick{padding:20px 18px}
  .first{padding:24px 20px 26px}
}

/* ---- language -------------------------------------------------------------------
   The हिंदी / English switch sits in the header beside the trial button, so
   it is on every page and comes back with the header on every scroll up. */
.lang{position:relative;display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;padding:0 16px;border:0;border-radius:300px;cursor:pointer;
  background:transparent;color:var(--ink);box-shadow:inset 0 0 0 2px var(--ink);
  font-family:var(--display);font-size:18px;font-weight:700;letter-spacing:.06em;line-height:1;
  transition:background 160ms ease,transform 120ms ease}
.lang:hover{background:rgba(197,138,73,.18);transform:translateY(-1px)}
.lang:active{transform:translateY(1px)}
@media (max-width:1220px){
  /* Beside the scrolling row of links, never inside it — scrolled out of
     sight is exactly where a language switch cannot be. */
  .navlinks{flex:1 1 calc(100% - 110px);min-width:0}
  .lang{order:4}
}
@media (max-width:720px){
  .navlinks{flex:1 1 calc(100% - 90px)}
  /* Still the full 44px target the rest of the site keeps to. */
  .lang{padding:0 13px;font-size:16px}
}

/* Until a saved Hindi preference has been applied, the page is held back
   rather than flashed in English. The head script lifts this after 2.5s
   whatever happens, so a failed script can never leave the page blank. */
.i18n-wait body{visibility:hidden}

/* Devanagari. Teko and Hind carry it: Teko is condensed like Barlow, Hind
   sits with Montserrat. They come after the Latin faces in each stack, so
   Latin keeps its own type and only the Devanagari letters fall through.
   Tracking breaks the headstroke that joins Devanagari letters into words,
   so it is switched off in Hindi, and headlines set at .84 line height
   need the room above and below the line that the vowel signs take. */
html[lang="hi"] body *{letter-spacing:0!important}
html[lang="hi"] .h1{line-height:1.02}
html[lang="hi"] .h2{line-height:1.05}
html[lang="hi"] .h3,html[lang="hi"] .faq-h,html[lang="hi"] .first-h,html[lang="hi"] .pick-p,
html[lang="hi"] .fee h3,html[lang="hi"] .tcard-n,html[lang="hi"] .mapcard h3{line-height:1.12}
html[lang="hi"] .lede,html[lang="hi"] .body,html[lang="hi"] .faq p{line-height:1.7}
/* Set on one line for Latin capitals, these clip the marks that sit above
   and below a Devanagari letter. */
html[lang="hi"] .slab-h b,html[lang="hi"] .chip b,html[lang="hi"] .fees-table tbody th,
html[lang="hi"] .pick-t,html[lang="hi"] .board-l,html[lang="hi"] .tcard-pos{line-height:1.25}

/* Without JavaScript these two are rendered empty, and an empty card looks
   like something that failed rather than something that is not there. */
html:not(.js) .needs-js{display:none}

/* ---- the spacing scale -------------------------------------------------------
   The only vertical gaps the HTML may ask for. Inline margins had drifted to
   fourteen different values, against this sheet's own "one rhythm" rule;
   these three replace every one of them. Last in the file so they win. */
.mt-s{margin:20px 0 0}
.mt-m{margin:30px 0 0}
.mt-l{margin:40px 0 0}
