/* ==========================================================================
   THE DESIGN SYSTEM. One file, loaded by every public page.

   Change a colour, a font or a button here and the whole site follows. Page
   specific layout stays in the page itself, so this file only ever holds
   things that appear more than once.

   THE GROUND IS LIGHT. Benson asked for a brighter site after looking at how
   the bigger coaching businesses present themselves, so ivory and paper carry
   most of the page and the deep court green is now used in bands, for the
   hero, for performance and for the footer. The palette itself is unchanged.

   Contrast rules that are not negotiable, from the brand identity:
     - Brass on Ivory is 2.02:1 and is illegible. Never do it. Use Deep Brass.
     - Sage on Ivory is 1.89:1. Never do it. Use Deep Sage.
   Everything below already respects that, so use the .band classes and the
   colour will look after itself.
   ========================================================================== */

:root{
  /* ---- palette, locked ---- */
  --green:#0F2A21;
  --ink:#0A1E18;
  --surface:#16382C;
  --ivory:#F2EBDC;
  --paper:#FBF7EE;          /* the lighter of the two grounds, for stacking bands */
  --brass:#C9A24C;
  --brass-lift:#E6CB86;
  --brass-deep:#836220;
  --sage:#9DB2A4;
  --sage-deep:#4C6155;
  --clay:#C0705A;

  /* ---- lines, all derived so a palette change carries through ---- */
  --line:color-mix(in srgb, var(--brass) 30%, transparent);
  --line-soft:color-mix(in srgb, var(--brass) 15%, transparent);
  --line-dark:color-mix(in srgb, var(--sage-deep) 26%, transparent);
  --glass:color-mix(in srgb, var(--green) 88%, transparent);
  --glass-light:color-mix(in srgb, var(--paper) 90%, transparent);

  /* ---- type ---- */
  --serif:"Libre Baskerville",Georgia,"Times New Roman",serif;
  --sans:"Archivo","Helvetica Neue",Arial,sans-serif;

  /* ---- rhythm ---- */
  --pad:clamp(1.15rem,4.5vw,2.75rem);
  --shell:1180px;
  --band-y:clamp(3.75rem,9vw,7rem);
  --r:3px;                       /* the one corner radius. Restrained on purpose. */
  --ease:cubic-bezier(.22,.61,.36,1);
}

*{box-sizing:border-box}
/* Anchors stop clear of the sticky bar. Measured, like the hero's top padding
   and the menu panel's offset, rather than the flat 5.5rem this used to be. */
html{scroll-behavior:smooth;scroll-padding-top:calc(var(--navh,72px) + 1.25rem);
  -webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--paper);color:var(--ink);
  font-family:var(--sans);font-size:16px;line-height:1.65;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
img,svg{max-width:100%}
h1,h2,h3,h4{margin:0;font-family:var(--serif);font-weight:400;text-wrap:balance;letter-spacing:-.01em}
p{margin:0;text-wrap:pretty}
a{color:inherit}
button{font:inherit}
:focus-visible{outline:2px solid var(--brass-deep);outline-offset:3px;border-radius:2px}
.band.dark :focus-visible,.hero :focus-visible{outline-color:var(--brass)}
::selection{background:var(--brass);color:var(--ink)}

/* Cross page navigation fades instead of flashing white, where supported. */
@view-transition{navigation:auto}

/* ---------------------------------------------------------- layout ---- */
.shell{max-width:var(--shell);margin:0 auto;padding-left:var(--pad);padding-right:var(--pad)}
.shell.narrow{max-width:920px}
.shell.wide{max-width:1340px}

/* Four grounds. light and paper are the two the site mostly lives on, dark
   and deep are the accents. */
.band{padding-top:var(--band-y);padding-bottom:var(--band-y);position:relative}
.band.light{background:var(--ivory);color:var(--ink)}
.band.paper{background:var(--paper);color:var(--ink)}
.band.dark{background:var(--green);color:var(--ivory)}
.band.deep{background:var(--ink);color:var(--ivory)}
.band.tight{padding-top:clamp(2.25rem,5vw,3.5rem);padding-bottom:clamp(2.25rem,5vw,3.5rem)}

/* A hairline that fades out at both ends. Reads as brass inlay, not a border. */
.rule{height:1px;border:0;margin:0;
  background:linear-gradient(90deg,transparent,var(--line-dark) 12%,var(--line-dark) 88%,transparent)}
.band.dark .rule,.band.deep .rule{
  background:linear-gradient(90deg,transparent,var(--line) 12%,var(--line) 88%,transparent)}

/* ------------------------------------------------------------ type ---- */
.eyebrow{
  font-size:.68rem;font-weight:700;text-transform:uppercase;
  letter-spacing:.18em;color:var(--brass-deep);margin:0;
}
:is(.band.dark,.band.deep,.hero) .eyebrow{color:var(--brass)}

.display{font-size:clamp(2.4rem,6.4vw,4.4rem);line-height:1.02;letter-spacing:-.022em}
h2,.h2{font-size:clamp(1.8rem,4.2vw,2.95rem);line-height:1.1;letter-spacing:-.015em}
h3,.h3{font-size:clamp(1.1rem,2vw,1.3rem);line-height:1.25}

.lede{font-size:clamp(1.02rem,1.5vw,1.15rem);line-height:1.7;color:var(--sage-deep);max-width:56ch}
:is(.band.dark,.band.deep,.hero) .lede{color:var(--sage)}
.fine{font-size:.86rem;line-height:1.7;color:var(--sage-deep)}
:is(.band.dark,.band.deep,.hero) .fine{color:var(--sage)}
.num{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}

.sec-head{display:flex;flex-direction:column;gap:.8rem;margin-bottom:clamp(2rem,4vw,3rem);max-width:62ch}
.sec-head.centred{margin-left:auto;margin-right:auto;text-align:center;align-items:center}
.sec-head.centred .lede{text-align:center}

/* --------------------------------------------------------- wordmark ---- */
/* Centred, not left aligned. In the drawn wordmark the descriptor is inset
   symmetrically under the name, and the text-indent below is what keeps it
   optically centred despite the trailing letter-space on the last character. */
.lockup{display:inline-flex;flex-direction:column;align-items:center;gap:.3rem;
  text-decoration:none}
.lockup .nm{font-family:var(--serif);font-weight:700;text-transform:uppercase;
  letter-spacing:.1em;line-height:1;color:var(--ivory);white-space:nowrap}
.lockup .dv{height:1px;width:100%;background:var(--brass)}
.lockup .ds{font-family:var(--sans);font-weight:600;text-transform:uppercase;
  color:var(--brass);line-height:1}
.lockup.sm .nm{font-size:1.24rem}
.lockup.sm .ds{font-size:.52rem;letter-spacing:.36em;text-indent:.36em}
.lockup.lg .nm{font-size:1.4rem}
.lockup.lg .ds{font-size:.56rem;letter-spacing:.4em;text-indent:.4em}
.lockup.onlight .nm{color:var(--ink)}
.lockup.onlight .dv{background:var(--brass-deep)}
.lockup.onlight .ds{color:var(--brass-deep)}

/* --------------------------------------------------------- buttons ---- */
/* Default button is for a LIGHT ground, because most of the site is light
   now. Add .ondark on green and ink bands. */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.55rem;
  font-family:var(--sans);font-size:.78rem;font-weight:700;
  letter-spacing:.13em;text-transform:uppercase;
  padding:.95rem 1.5rem;border-radius:var(--r);text-decoration:none;
  border:1px solid var(--brass-deep);background:transparent;color:var(--brass-deep);
  cursor:pointer;position:relative;
  transition:color .2s var(--ease),background .2s var(--ease),
             border-color .2s var(--ease),transform .12s var(--ease),
             box-shadow .2s var(--ease);
}
.btn:active{transform:translateY(1px)}
.btn.solid{background:var(--brass-deep);color:var(--paper);border-color:var(--brass-deep)}
.btn.solid:hover{background:#6E521A;border-color:#6E521A;box-shadow:0 6px 18px rgba(131,98,32,.22)}
.btn.ghost:hover{background:color-mix(in srgb,var(--brass-deep) 9%,transparent)}

.btn.ondark{border-color:var(--brass);color:var(--brass)}
.btn.ondark.solid{background:var(--brass);color:var(--ink);border-color:var(--brass)}
.btn.ondark.solid:hover{background:var(--brass-lift);border-color:var(--brass-lift);
  box-shadow:0 6px 20px rgba(0,0,0,.3)}
.btn.ondark.ghost:hover{background:color-mix(in srgb,var(--brass) 14%,transparent)}

.btn.small{padding:.62rem 1.05rem;font-size:.7rem;letter-spacing:.12em}
.btn.big{padding:1.1rem 2rem;font-size:.82rem}
.btn[disabled]{opacity:.5;pointer-events:none}
.btn .arw{transition:transform .25s var(--ease)}
.btn:hover .arw{transform:translateX(3px)}

/* A quiet text link that still looks clickable. */
.tlink{color:var(--brass-deep);text-decoration:none;font-weight:600;
  border-bottom:1px solid color-mix(in srgb,var(--brass-deep) 35%,transparent);
  padding-bottom:1px;transition:border-color .2s var(--ease)}
.tlink:hover{border-bottom-color:var(--brass-deep)}
:is(.band.dark,.band.deep,.hero) .tlink{color:var(--brass);
  border-bottom-color:var(--line)}
:is(.band.dark,.band.deep,.hero) .tlink:hover{border-bottom-color:var(--brass)}

/* ------------------------------------------------------------ shots ---- */
/* Every photograph on the site goes through this. The picture is cropped by
   the frame rather than the other way round, and if the file is missing the
   frame falls back to a drawn court with a label saying which photo belongs
   there. That way a half finished photo library never breaks the layout.
   See web/img/README.md for the shot list. */
.shot{position:relative;overflow:hidden;border-radius:var(--r);background:var(--green);
  display:block;isolation:isolate}
.shot img{display:block;width:100%;height:100%;object-fit:cover;
  transition:transform .8s var(--ease)}
.shot .ph{position:absolute;inset:0;display:none;place-items:center;text-align:center;
  padding:1.25rem;font-size:.68rem;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--brass);line-height:1.7;
  background:
    repeating-linear-gradient(90deg,transparent 0 46px,var(--line-soft) 46px 47px),
    repeating-linear-gradient(0deg,transparent 0 46px,var(--line-soft) 46px 47px),
    linear-gradient(150deg,var(--surface),var(--green) 60%,var(--ink))}
.shot.noimg img{display:none}
.shot.noimg .ph{display:grid}
.shot.noimg{border:1px solid var(--line-soft)}

.r-21x9{aspect-ratio:21/9}
.r-16x9{aspect-ratio:16/9}
.r-3x2{aspect-ratio:3/2}
.r-4x3{aspect-ratio:4/3}
.r-1x1{aspect-ratio:1/1}
.r-4x5{aspect-ratio:4/5}
.r-3x4{aspect-ratio:3/4}

/* Readable by a screen reader and by Google, invisible on screen. For a page
   whose design has no visible title of its own, which is the booking wizard:
   it opens straight into step one. Clip rather than display:none, because
   display:none is skipped by screen readers too. */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* A green wash over a photograph so ivory type stays readable on top of it. */
.scrim{position:absolute;inset:0;z-index:1;pointer-events:none}
.scrim.up{background:linear-gradient(0deg,
  color-mix(in srgb,var(--ink) 92%,transparent) 0%,
  color-mix(in srgb,var(--ink) 55%,transparent) 42%,
  color-mix(in srgb,var(--ink) 8%,transparent) 100%)}
.scrim.side{background:linear-gradient(90deg,
  color-mix(in srgb,var(--ink) 88%,transparent) 0%,
  color-mix(in srgb,var(--ink) 62%,transparent) 45%,
  color-mix(in srgb,var(--ink) 20%,transparent) 100%)}

/* ------------------------------------------------------------- nav ---- */
/* Solid paper by default, so it is readable with no script running at all.
   JavaScript adds .transparent while the bar is sitting over the hero
   photograph, and takes it off again as soon as you scroll past it. */
.nav{position:sticky;top:0;z-index:60;
  background:var(--glass-light);border-bottom:1px solid var(--line-dark);
  backdrop-filter:blur(14px) saturate(120%);-webkit-backdrop-filter:blur(14px) saturate(120%);
  transition:background .35s var(--ease),border-color .35s var(--ease)}
.nav.transparent{background:transparent;border-bottom-color:transparent;
  backdrop-filter:none;-webkit-backdrop-filter:none}
/* An open menu always wins. The script also drops .transparent while the menu
   is open, and this is the belt to that pair of braces: an open panel is paper,
   so the bar above it has to be paper too or the two read as one smear. */
.nav.menuopen,.nav.transparent.menuopen{background:var(--paper);
  border-bottom-color:var(--line-dark);
  backdrop-filter:none;-webkit-backdrop-filter:none}
.nav .in{display:flex;align-items:center;justify-content:space-between;gap:1.25rem;
  padding-top:.9rem;padding-bottom:.9rem}
.nav .links{display:none;align-items:center;gap:1.6rem}
@media(min-width:1020px){.nav .links{display:flex}}
.nav .links a{font-size:.84rem;font-weight:500;color:var(--sage-deep);text-decoration:none;
  position:relative;padding:.2rem 0;transition:color .3s var(--ease)}
.nav .links a::after{content:"";position:absolute;left:0;right:0;bottom:-3px;height:1px;
  background:currentColor;transform:scaleX(0);transform-origin:left;
  transition:transform .25s var(--ease)}
.nav .links a:hover::after{transform:scaleX(1)}
.nav .links a:hover{color:var(--ink)}
.nav .links a.btn::after{display:none}
/* The one button in the bar, filled brass.

   It needs its padding set here or it gets none. The rule above gives every
   link in the bar `padding:.2rem 0`, and that beats .btn.small on specificity,
   so the button was coming out with no horizontal padding at all and the gold
   box sat clamped against the word. This lands it at the same height as the
   other small buttons on the site, with real room either side of the label.

   Ink on brass in BOTH bar states, not just over the hero. The bar used to
   switch this text to paper once it went light, which is paper on brass at
   about 2:1 and unreadable. Ink on brass is around 7:1 and needs no switch,
   and the second selector is only there to outrank the sage rule below. */
.nav .links a.btn,
.nav.transparent .links a.btn{color:var(--ink);padding:.6rem 1.2rem}
.nav .lockup .nm{color:var(--ink)}
.nav .lockup .dv{background:var(--brass-deep)}
.nav .lockup .ds{color:var(--brass-deep)}

/* everything flips to ivory while the bar is over the photograph */
.nav.transparent .links a{color:var(--sage)}
.nav.transparent .links a:hover{color:var(--ivory)}
.nav.transparent .lockup .nm{color:var(--ivory)}
.nav.transparent .lockup .dv{background:var(--brass)}
.nav.transparent .lockup .ds{color:var(--brass)}
.nav.transparent .navtoggle{color:var(--sage);border-color:var(--line-soft)}
.nav.transparent .navtoggle:hover{color:var(--ivory)}
/* and back to ink the moment the menu opens, whatever the scroll position */
.nav.menuopen .lockup .nm{color:var(--ink)}
.nav.menuopen .lockup .dv{background:var(--brass-deep)}
.nav.menuopen .lockup .ds{color:var(--brass-deep)}
.nav.menuopen .navtoggle{color:var(--ink);border-color:var(--line-dark)}

.navtoggle{display:inline-flex;align-items:center;gap:.5rem;background:transparent;
  border:1px solid var(--line-dark);color:var(--sage-deep);font-size:.7rem;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;padding:.6rem .85rem;border-radius:var(--r);
  cursor:pointer;transition:color .3s var(--ease),border-color .3s var(--ease)}
.navtoggle:hover{color:var(--ink)}
@media(min-width:1020px){.navtoggle{display:none}}
/* The phone menu is a panel that hangs off the bottom of the bar, not a
   drawer inside it. It used to be a row inside the header that grew from 0fr
   to 1fr, which meant two things went wrong on a phone at the top of the page.
   The header grew, shoving the hero down mid animation, and the panel took
   the bar's own see through treatment, so the menu was drawn straight over the
   headline with the artwork showing through the words. Taking it out of the
   flow fixes the shove, and giving it its own solid ground fixes the mush.

   It sits under the bar rather than over it: top is the measured bar height,
   and z-index is one below .nav so the wordmark and the close button stay
   readable and clickable above it. */
.mobilemenu{position:fixed;left:0;right:0;top:var(--navh,72px);z-index:59;
  max-height:calc(100dvh - var(--navh,72px));overflow-y:auto;
  -webkit-overflow-scrolling:touch;overscroll-behavior:contain;
  background:var(--paper);border-bottom:1px solid var(--line-dark);
  box-shadow:0 22px 44px rgba(8,26,20,.22);
  padding-bottom:calc(1.1rem + env(safe-area-inset-bottom));
  /* Visibility is switched outright rather than transitioned. A transition on
     it is a discrete one, which leaves the panel unclickable for part of the
     open. On the way in it flips at once; on the way out it waits for the fade
     to finish, which is what the delay on the closed state is for. */
  opacity:0;visibility:hidden;transform:translateY(-10px);
  transition:opacity .24s var(--ease),transform .24s var(--ease),visibility 0s linear .24s}
.mobilemenu.open{opacity:1;visibility:visible;transform:translateY(0);
  transition:opacity .24s var(--ease),transform .24s var(--ease),visibility 0s}
/* Colours are fixed here rather than inherited. The panel is always paper, so
   its links are always ink on paper, whatever state the bar behind it is in. */
.mobilemenu a{display:block;font-size:1rem;color:var(--sage-deep);text-decoration:none;
  padding:.95rem 0;border-top:1px solid var(--line-dark)}
.mobilemenu .shell>a:first-child{border-top:0}

/* The ground behind the panel. Its job is to stop the page reading through the
   gap under a short menu, and to give a tap target for closing. */
.navscrim{position:fixed;inset:0;z-index:58;background:rgba(10,30,24,.5);
  opacity:0;visibility:hidden;
  transition:opacity .24s var(--ease),visibility 0s linear .24s;
  -webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}
.navscrim.open{opacity:1;visibility:visible;
  transition:opacity .24s var(--ease),visibility 0s}
@media(min-width:1020px){.mobilemenu,.navscrim{display:none}}
/* With no script there is nothing to open the panel with, so it simply sits
   open under the bar as a plain list. A phone with JavaScript off still gets
   navigation, which is more than the old drawer managed. */
html:not(.js) .mobilemenu{position:static;max-height:none;opacity:1;visibility:visible;
  transform:none;box-shadow:none}
html:not(.js) .navtoggle,html:not(.js) .navscrim{display:none}

/* ---------------------------------------------- sticky booking bar ---- */
.bookbar{position:fixed;left:0;right:0;bottom:0;z-index:55;
  background:color-mix(in srgb,var(--ink) 94%,transparent);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border-top:1px solid var(--line-soft);
  padding:.7rem var(--pad) calc(.7rem + env(safe-area-inset-bottom));
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  transform:translateY(110%);transition:transform .3s var(--ease)}
.bookbar.show{transform:translateY(0)}
.bookbar .bl{display:flex;flex-direction:column;gap:.1rem;min-width:0}
.bookbar .bl b{font-family:var(--serif);font-size:.95rem;font-weight:400;color:var(--ivory)}
.bookbar .bl span{font-size:.74rem;color:var(--sage)}
@media(min-width:1020px){.bookbar{display:none}}

/* ---------------------------------------------------------- chips ---- */
.chip{display:inline-flex;align-items:center;gap:.4rem;font-size:.68rem;font-weight:700;
  letter-spacing:.09em;text-transform:uppercase;padding:.32rem .65rem;border-radius:100px;
  border:1px solid var(--line-dark);color:var(--sage-deep);white-space:nowrap;line-height:1.3}
.chip.low{color:var(--brass-deep);border-color:color-mix(in srgb,var(--brass-deep) 40%,transparent)}
.chip.full{color:#9E4C36;border-color:rgba(158,76,54,.4)}
.chip.free{color:var(--ink);background:var(--brass);border-color:var(--brass)}
:is(.band.dark,.band.deep) .chip{color:var(--sage);border-color:var(--line-soft)}
:is(.band.dark,.band.deep) .chip.low{color:var(--brass);border-color:var(--line)}
:is(.band.dark,.band.deep) .chip.full{color:var(--clay);
  border-color:color-mix(in srgb,var(--clay) 35%,transparent)}
.chip .dot{width:5px;height:5px;border-radius:50%;background:currentColor;flex:none}

/* --------------------------------------------------------- footer ---- */
footer{background:var(--ink);color:var(--ivory);
  padding-top:clamp(3rem,6vw,4.5rem);padding-bottom:2.5rem}
.foot{display:flex;flex-direction:column;gap:2.5rem}
@media(min-width:800px){.foot{flex-direction:row;justify-content:space-between;gap:3rem}}
.foot .fl{display:flex;flex-direction:column;gap:1rem;align-items:flex-start;max-width:34ch}
.foot .fl .fine{color:var(--sage)}
.foot .fr{display:flex;flex-wrap:wrap;gap:2rem 3.5rem}
.fcol{display:flex;flex-direction:column;gap:.6rem}
.fcol b{font-size:.63rem;font-weight:700;text-transform:uppercase;letter-spacing:.16em;color:var(--brass)}
.fcol a,.fcol span{font-size:.87rem;color:var(--sage);text-decoration:none;line-height:1.6}
.fcol a:hover{color:var(--ivory)}
.legal{margin-top:2.75rem;padding-top:1.5rem;border-top:1px solid var(--line-soft);
  font-size:.76rem;color:var(--sage);line-height:1.7;opacity:.85}

/* ---------------------------------------------------------- grain ---- */
.grain::before{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:1;opacity:.05;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* --------------------------------------------------- scroll reveal ---- */
/* Gated behind .js, which an inline script puts on <html> before anything
   paints. Without JavaScript, or in a preview that does not run scripts, the
   page is simply visible. Content must never depend on a script to be read.

   The state class is .seen, not .in. .in is a layout class on the shell
   wrappers and the two collided once already. */
.js .rise{opacity:0;transform:translateY(18px);
  transition:opacity .7s var(--ease),transform .7s var(--ease)}
.js .rise.seen{opacity:1;transform:none}
.js .rise.d1{transition-delay:.07s}
.js .rise.d2{transition-delay:.14s}
.js .rise.d3{transition-delay:.21s}

/* ------------------------------------------------ reduced motion ---- */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important}
  .rise{opacity:1;transform:none}
}

/* ------------------------------------------------------- printing ---- */
@media print{
  .nav,.bookbar,.hero-art,iframe{display:none!important}
  body{background:#fff;color:#000}
}
