/* Shared styling for the pages a player or parent sees: booking, check-in and
   the academy's privacy notice.
 *
 * One file so the three cannot drift apart, and so an academy's brand colour is
 * set in exactly one place. Every page sets --brand at runtime from its own
 * academy row; everything else here is deliberately neutral, because these
 * pages belong to the academy, not to us.
 *
 * Mobile first throughout: a parent opens these on a phone, usually one-handed,
 * often outside. Tap targets are large, contrast is high, nothing relies on
 * hover. */

:root{
  --brand:#0b1220;
  --ink:#0f172a; --t2:#475569; --t3:#94a3b8;
  --line:#e2e8f0; --line2:#cbd5e1;
  --bg:#f6f8fb; --card:#fff;
  --ok:#15803d; --ok-bg:#dcfce7; --err:#dc2626; --err-bg:#fef2f2;
  --radius:14px;
  --shadow:0 1px 2px rgba(15,23,42,.04), 0 8px 24px -12px rgba(15,23,42,.12);
}

*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{
  background:var(--bg); color:var(--ink);
  font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Inter,Roboto,sans-serif;
  line-height:1.6; -webkit-font-smoothing:antialiased;
  font-size:16px;                      /* never below 16: iOS zooms on focus */
}
a{color:var(--brand);text-decoration:none;font-weight:600}
a:hover{text-decoration:underline}

/* The bottom padding clears the browser's own furniture. On an iPhone, Safari
   floats its address bar over the page, and on the booking page the last line —
   the academy's name and the privacy notice — sat underneath it. Nothing was
   broken; it just could not be read, which on the page a parent is judging is
   the same thing. env() adds the home-indicator inset on top for a device that
   has one, and resolves to zero on every device that does not. */
.wrap{max-width:620px;margin:0 auto;padding:0 18px calc(64px + env(safe-area-inset-bottom))}

/* ── header ─────────────────────────────────────────── */
.hero{
  background:var(--brand); color:#fff; padding:34px 18px 30px; text-align:center;
  position:relative; overflow:hidden;
}
.hero::after{                          /* a little depth, no image to load */
  content:''; position:absolute; inset:auto 0 -60% 0; height:120%;
  background:radial-gradient(ellipse at 50% 0,rgba(255,255,255,.14),transparent 62%);
  pointer-events:none;
}
/* The academy's logo, beside its name.
 *
 * Both this and its row had no CSS whatsoever, so the image rendered at
 * whatever size was uploaded — BounZ's is 512x288, which on a 375px phone was
 * wider than the screen and shoved the academy's own name out of view. A
 * booking page whose first impression is a giant cropped picture is not one a
 * parent trusts with a card number later.
 *
 * A fixed height with contain, rather than a fixed width: logos arrive square,
 * wide and tall, and height is the dimension that has to agree with the text
 * beside it. The white tile is deliberate — plenty of logos are dark ink on a
 * transparent background and would vanish against the brand colour behind
 * them. It costs a little on white-on-transparent logos and saves the rest. */
.hero-id{
  display:flex; align-items:center; justify-content:center; gap:12px;
  flex-wrap:wrap; position:relative;
}
#academy-logo{
  flex:none;
  /* Bigger than the first pass. That one was sized to sit politely beside the
     name and ended up at 41px tall on a phone — safe, and too small to read
     the academy's own mark, which is half of what a parent uses to check they
     are on the right page. This is roughly half again. It is still bounded on
     both axes, so an enormous upload cannot come back. */
  height:clamp(58px,16vw,82px);
  width:auto; max-width:min(56%,240px);
  object-fit:contain;
  background:#fff; border-radius:13px; padding:7px;
  box-shadow:0 3px 14px rgba(0,0,0,.18);
}
.hero h1{font-size:clamp(1.24rem,4.4vw,1.6rem);font-weight:800;letter-spacing:-.02em;position:relative}
/* The academy's own words, and the facts a parent asks before booking.
 *
 * Deliberately inside the hero rather than a section below it. This page
 * converts because a parent taps a link and books; a brochure between them and
 * the time picker costs bookings. Identity AROUND the form, not the form buried
 * inside a website. The 400-character cap in the database is the same decision.
 *
 * Both hidden unless the academy filled them in — a coach who has written
 * nothing sees the page exactly as it was. */
.hero-about{
  position:relative;max-width:520px;margin:14px auto 0;
  font-size:.92rem;line-height:1.6;color:rgba(255,255,255,.9);
  white-space:pre-wrap;
}
.hero-facts{
  position:relative;display:flex;justify-content:center;flex-wrap:wrap;
  gap:6px 8px;margin-top:14px;
}
.hero-facts span{
  font-size:.76rem;font-weight:600;letter-spacing:.01em;
  color:rgba(255,255,255,.92);background:rgba(255,255,255,.13);
  border:1px solid rgba(255,255,255,.2);
  padding:5px 12px;border-radius:99px;white-space:nowrap;
}
.hero-facts a{color:inherit;text-decoration:none}
.hero .sub{opacity:.86;font-size:.87rem;margin-top:5px;position:relative}
/* An eyebrow over the heading, not a control.
 *
 * This was a pill: rounded to 99px, filled, and outlined — every visual cue a
 * button has. It says "Book a session" at the top of the booking page and does
 * nothing at all, so the first thing a parent does on that page is tap the one
 * thing that cannot be tapped, and the second thing is wonder whether the page
 * is broken. The same rule sits over "Check-in" and "Privacy notice", which
 * are labels too.
 *
 * Kept: the size, weight, letter-spacing and caps that make it read as a
 * kicker. Dropped: everything that made it look pressable. */
.hero .badge{
  display:block;margin:0 0 6px;padding:0;
  background:none;border:0;border-radius:0;
  font-size:.68rem;font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  color:rgba(255,255,255,.72);
  position:relative;
}

/* ── cards ──────────────────────────────────────────── */
.card{
  background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
  padding:24px 20px; margin-top:16px; box-shadow:var(--shadow);
}
.card h2{font-size:1.06rem;font-weight:800;letter-spacing:-.01em;margin-bottom:4px}
.hint{font-size:.87rem;color:var(--t2);margin-bottom:18px}
.step{
  font-size:.66rem;font-weight:800;letter-spacing:.12em;text-transform:uppercase;
  color:var(--t3);margin-bottom:9px;
}

/* ── form ───────────────────────────────────────────── */
label{display:block;font-size:.85rem;font-weight:700;margin:16px 0 6px}
label:first-of-type{margin-top:0}
input,textarea,select{
  width:100%;padding:12px 13px;border:1.5px solid var(--line);border-radius:11px;
  font-size:1rem;font-family:inherit;color:var(--ink);background:#fff;outline:none;
  transition:border-color .15s, box-shadow .15s;
}
input:focus,textarea:focus,select:focus{
  border-color:var(--brand);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--brand) 15%,transparent);
}
textarea{min-height:74px;resize:vertical;line-height:1.55}
select{appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--t3) 50%),linear-gradient(135deg,var(--t3) 50%,transparent 50%);
  background-position:calc(100% - 19px) calc(50% + 2px),calc(100% - 14px) calc(50% + 2px);
  background-size:5px 5px,5px 5px;background-repeat:no-repeat;padding-right:38px}
.req{color:var(--err)}

/* ── scale ──────────────────────────────────────────── */
.scale{display:flex;align-items:center;gap:14px;margin-top:8px}
.scale input[type=range]{flex:1;accent-color:var(--brand);padding:0;height:22px}
.scale output{min-width:56px;text-align:right;font-weight:800;font-variant-numeric:tabular-nums;font-size:1.08rem}
.scale-ends{display:flex;justify-content:space-between;font-size:.72rem;color:var(--t3);margin-top:3px}

/* ── slots ──────────────────────────────────────────── */
.daygroup{margin-bottom:20px}
.daygroup:last-child{margin-bottom:0}
.dayname{
  font-size:.7rem;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  color:var(--t3);margin-bottom:9px;
}

/* A level heading is not a day heading, and should not look like one.
   A day is a label — the parent already knows which days suit them. The level
   is the question they came to answer: which of these is for my child. So when
   the page groups by level, the heading stops being a faint grey caption and
   becomes a title, sitting on its own line above a rule.

   Kept as a separate class rather than restyling .dayname, because the same
   element still heads the day groups on every academy that has not set levels
   — which is nineteen of twenty-one — and a day called MONDAY does not deserve
   this weight. */
.daygroup.by-level{margin-bottom:26px}
.dayname.level{
  font-size:1rem;font-weight:800;letter-spacing:-.01em;text-transform:none;
  color:var(--t1);margin-bottom:11px;padding-bottom:9px;
  border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:9px;
}
/* The count, so a parent can see at a glance that one band has three sessions
   and the other has one, without counting cards. */
.dayname.level .n{
  font-size:.7rem;font-weight:700;letter-spacing:.04em;color:var(--t3);
  text-transform:uppercase;margin-left:auto;
}
/* auto-FIT, not auto-fill.
   auto-fill keeps the empty column, so a day with one published time drew a
   card 175px wide on a 390px phone with the other half of the row blank — which
   reads as a broken page rather than a designed one. auto-fit collapses the
   empty track and lets a lone time fill the row; two or more still sit side by
   side. Coach Tomiwa's page had four days with exactly one time each. */
.slots{display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));gap:10px}
.slot{
  border:1.5px solid var(--line);background:#fff;border-radius:12px;padding:12px 13px;
  cursor:pointer;text-align:left;font-family:inherit;width:100%;display:block;
  transition:border-color .15s, box-shadow .15s, transform .12s;
}
.slot:hover{border-color:var(--line2)}
.slot.on{
  border-color:var(--brand);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--brand) 16%,transparent);
}
.slot .t{font-weight:800;font-size:.98rem;letter-spacing:-.01em}
.slot .m{font-size:.77rem;color:var(--t2);margin-top:3px;line-height:1.45}

/* Dates, as one tap each.
 *
 * This was a <select>. There are only ever four dates, and on a phone a select
 * costs a native picker — tap, spin, confirm — for a choice that fits on the
 * screen. Worse, a select always has a value, so the date was answered before
 * the parent looked at it: the commonest way to book the wrong week is a
 * default nobody read. Chips make the choice visible and cost one tap.
 * Deliberately the same shape as .slot, because it is the same kind of act. */
.datechips{display:flex;flex-wrap:wrap;gap:8px;margin-top:2px}
.datechip{
  border:1.5px solid var(--line);background:#fff;border-radius:12px;
  padding:10px 13px;cursor:pointer;font-family:inherit;font-size:.87rem;
  font-weight:700;color:var(--t1);
  transition:border-color .15s, box-shadow .15s;
}
.datechip:hover{border-color:var(--line2)}
.datechip.on{
  border-color:var(--brand);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--brand) 16%,transparent);
}
.datechip .dc-sub{display:block;font-weight:600;font-size:.74rem;color:var(--t2);margin-top:2px}

/* ── buttons ────────────────────────────────────────── */
.btn{
  /* An <a class="btn"> is inline by default, so width:100% did nothing and the
     vertical padding spilled out of the line box and sat on top of the text
     above it. The pay link has always been an anchor; it was only visible once
     a second one appeared beside it. */
  display:block;box-sizing:border-box;text-align:center;text-decoration:none;
  width:100%;margin-top:24px;padding:15px;border:none;border-radius:12px;
  background:var(--brand);color:#fff;font-size:1rem;font-weight:800;
  cursor:pointer;font-family:inherit;letter-spacing:-.01em;
  transition:filter .15s, transform .12s;
}
.btn:hover{filter:brightness(1.12)}
.btn:active{transform:translateY(1px)}
.btn[disabled]{opacity:.5;cursor:not-allowed;filter:none;transform:none}
/* The unpicked half of a two-way choice. Quiet, not gone: a parent who taps
   "Pay now" and changes their mind must be able to tap the other one without
   reloading, so both stay on screen and only the emphasis moves.
   Written against the tokens, not against a guess at the background — the first
   version used a white border, which is invisible on the white card this page
   actually uses. */
.btn.ghost{background:transparent;color:var(--t2);
  border:1.5px solid var(--line2)}
.btn.ghost:hover{filter:none;border-color:var(--t3);color:var(--ink)}

/* ── messages ───────────────────────────────────────── */
.msg{margin-top:15px;padding:13px 15px;border-radius:11px;font-size:.89rem;display:none}
.msg.err{display:block;background:var(--err-bg);color:#991b1b;border:1px solid #fecaca}
.privnote{margin-top:18px;font-size:.8rem;color:var(--t3);line-height:1.6}

/* ── done ───────────────────────────────────────────── */
.done{text-align:center;padding:18px 0 8px}
.done .tick{
  width:60px;height:60px;border-radius:50%;background:var(--ok-bg);color:var(--ok);
  display:grid;place-items:center;font-size:1.85rem;margin:0 auto 16px;
}
.done h2{font-size:1.2rem}
.done p{color:var(--t2);font-size:.92rem;margin-top:7px}

.empty{text-align:center;padding:30px 12px;color:var(--t2);font-size:.92rem;line-height:1.6}

/* ── prose, for the notice ──────────────────────────── */
.prose h3{font-size:.98rem;font-weight:800;margin:22px 0 7px}
.prose h3:first-child{margin-top:0}
.prose p{margin-bottom:11px;color:var(--t2);font-size:.92rem}
.prose ul{margin:0 0 13px 20px;color:var(--t2);font-size:.92rem}
.prose li{margin-bottom:6px}
.prose strong{color:var(--ink)}

footer{text-align:center;font-size:.8rem;color:var(--t3);margin-top:28px;line-height:1.8}
/* The attribution mark. Muted on purpose: it sits under an academy's own name
   on a page their parents opened, and it is ours, not theirs. */
/* ── Show the password ───────────────────────────────────────────────────────
   A coach typing a password on a phone, one-handed, courtside, cannot see what
   they typed and cannot tell a typo from a wrong password. The reveal is a
   button inside the field rather than a checkbox beside it, so it costs no
   layout and is where the thumb already is.

   The input keeps its right padding permanently, revealed or not, so the text
   does not shift under the caret when the button is pressed. */
.pw-wrap{position:relative}
.pw-wrap input{padding-right:52px}
.pw-eye{position:absolute;top:0;right:0;height:100%;width:48px;
  background:none;border:0;padding:0;margin:0;cursor:pointer;
  display:grid;place-items:center;color:var(--t3);font:inherit;font-size:1.05rem;
  border-radius:0 11px 11px 0}
.pw-eye:hover{color:var(--brand,#1a6b3a)}
.pw-eye:focus-visible{outline:2px solid var(--blue);outline-offset:-2px}

.mark{display:block;margin-top:14px;font-size:.78rem;color:var(--t2);
  text-decoration:none;letter-spacing:.01em;font-weight:600;opacity:1}
.mark b{font-weight:800;color:var(--ink);letter-spacing:-.01em}
.mark:hover b{color:var(--blue)}
footer a{color:var(--t2);font-weight:600}

@media(max-width:420px){
  .wrap{padding:0 14px calc(72px + env(safe-area-inset-bottom))}
  .card{padding:20px 16px}
  .slots{grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:8px}
}

/* ── The iOS zoom floor ──────────────────────────────────────────────────────
   Safari zooms the whole page when a focused control's text is under 16px, and
   it does not zoom back out afterwards — you are left stranded at 1.4x with the
   layout off the side of the screen. Every control is floored at 16px, whatever
   else set it, so no future rule can reintroduce it by using .9rem somewhere.

   1em rather than 16px on the upper side keeps deliberately large controls
   large. The condition is both a width and pointer:coarse, because a phone held
   sideways is wider than 768px and still zooms.

   Pinch zoom is deliberately NOT disabled. user-scalable=no would stop this too
   and would also stop anyone who needs to magnify text from doing so. */
@media (max-width: 900px), (pointer: coarse) {
  input, select, textarea { font-size: max(16px, 1em) !important; }

  /* ── The other way iOS zooms, and the one that has kept coming back ────────
     Focus-zoom is the rule above. This is double-tap-to-zoom, and nothing in
     this repo has ever stopped it.
  
     It matters here more than on most sites because of what the product is
     for. Taking a register means tapping name after name, fast, one-handed,
     usually outdoors. Two taps landing near each other inside about 300ms is
     a double tap as far as Safari is concerned, so the page zooms — and, as
     with focus-zoom, it does not zoom back out. The coach is left at 1.4x
     halfway through a register.
  
     That is why it reads as intermittent and why no layout tool ever found
     it: it depends on how fast somebody taps, not on the markup. Every page
     measured clean at 390px with all 131 controls at or above the floor on
     the day this was added, and the zooming was still being reported.
  
     touch-action:manipulation removes the double-tap gesture and NOTHING
     else. Scrolling, panning and pinch-to-zoom all still work. That
     distinction is the entire point: user-scalable=no would also stop the
     double tap, and would stop a coach who needs to magnify small text from
     ever doing so. This repo turned that flag down once already. */
  html, body { touch-action: manipulation; }
}

/* ── Sponsor board ───────────────────────────────────────────────────────────
   At the foot of the booking page, below the times and the form. A sponsor pays
   to be in front of an academy's players, and the booking link is the page every
   parent opens — but a page that sells something before it lets you book has
   stopped being a booking page, so this sits after the job is done.

   Tier shows as a thin edge rather than a badge. Gold should read as more
   prominent without a booking page turning into a leaderboard. */
.spon{margin:26px 0 10px}
.spon-t{
  font-size:.68rem; font-weight:800; letter-spacing:.14em; text-transform:uppercase;
  color:var(--t3); text-align:center; margin-bottom:12px;
}
.spon-list{display:flex; flex-wrap:wrap; gap:9px; justify-content:center}
.spon-i{
  display:flex; align-items:center; gap:9px;
  background:#fff; border:1px solid var(--line); border-left-width:3px;
  border-radius:11px; padding:9px 13px; text-decoration:none; color:var(--ink);
  font-size:.85rem; font-weight:700; max-width:100%;
}
a.spon-i:hover{border-color:var(--blue)}
/* A logo is whatever the sponsor supplied — any shape, any aspect. Bounded on
   both axes and set to contain, so a tall one cannot stretch the row. */
.spon-i img{height:26px; width:auto; max-width:96px; object-fit:contain; flex:none}
.spon-i span{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.spon-gold{border-left-color:#d4a017}
.spon-silver{border-left-color:#98a2b3}
.spon-bronze{border-left-color:#b06a2c}
