/* ============================================================================
   The small features added in October 2026 (features.js):

     · the two live lines under the hero's Book button (next open lesson,
       today's court weather), each with the ball's dot;
     · the tip of the week, a short section before the FAQ;
     · the bring-a-friend line on the semi-private card;
     · the intro video in About (hidden until a clip is named);
     · the press ripple: every button answers a press with a ring in the
       ball's colour spreading from the fingertip.
   ========================================================================== */

/* --- The arrival (arrival.js): a court in hairline grey behind the hero,
       each line drawing in turn; the serving player's canvas over it. */
.hero { position: relative; }
.hero > .hero-grid { position: relative; z-index: 1; }
.hero-court {
  position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none;
  color: var(--line);
}
.hero-court path { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.hero-court .hero-net { stroke-width: 3.5; }
.js .hero-court path { stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 1.1s cubic-bezier(.65, 0, .35, 1) var(--cd, 0s); }
.js .hero-court.is-drawn path { stroke-dashoffset: 0; }
.hero-serve { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .js .hero-court path { transition: none; stroke-dashoffset: 0; } }

/* --- "Tennis is for everyone": the row of players under the line, white
       line on the black band, each drawing itself as the band arrives
       (tools/everyone-figures.mjs writes the markup). One ball. */
.everyone { margin-top: clamp(1.75rem, 4vw, 3rem); }
.everyone-art { display: block; width: 100%; height: auto; overflow: visible; }
/* one row on wide screens, two rows (bigger people) on phones */
.everyone-art.is-narrow { display: none; }
@media (max-width: 640px) { .everyone-art.is-wide { display: none; } .everyone-art.is-narrow { display: block; } }
.everyone-art .ev-ground { fill: none; stroke: rgba(255, 255, 255, .3); stroke-width: 1; }
.everyone-art .ev-string { opacity: .55; }
/* The people rise into place one after another as the band arrives, and
   step back out of sight once it has gone, so they arrive again. */
.js .everyone.fade { opacity: 1; transform: none; }
.js .everyone.fade .ev-fig { opacity: 0; transform: translateY(14px); transition: opacity .55s var(--ease) var(--d, 0s), transform .8s var(--ease) var(--d, 0s); }
.js .everyone.fade.is-in .ev-fig { opacity: 1; transform: none; }
.js .everyone.fade .ev-ground { stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 1.4s cubic-bezier(.65, 0, .35, 1); }
.js .everyone.fade.is-in .ev-ground { stroke-dashoffset: 0; }
@media (prefers-reduced-motion: reduce) {
  .js .everyone.fade .ev-fig { opacity: 1; transform: none; transition: none; }
  .js .everyone.fade .ev-ground { transition: none; stroke-dashoffset: 0; }
}

/* --- Cards tilt toward the pointer and catch a yellow light (features.js
       sets --rx, --ry and the light's place); the Book buttons glow. */
.tilt-light {
  position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none; opacity: 0;
  background: radial-gradient(18rem circle at var(--lx, 50%) var(--ly, 50%), rgba(217, 239, 63, .3), rgba(217, 239, 63, 0) 62%);
  transition: opacity .35s var(--ease);
}
.review { position: relative; isolation: isolate; }
.js .lesson.fade.is-in.is-tilt, .js .review.fade.is-in.is-tilt {
  transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(-4px);
  transition: transform .14s ease-out, box-shadow .35s var(--ease), border-color .35s var(--ease);
  box-shadow: 0 18px 40px rgba(0, 0, 0, .12), 0 0 0 1px rgba(217, 239, 63, .5);
  border-color: transparent;
}
.is-tilt > .tilt-light { opacity: 1; }
.btn-primary, .btn-invert, .nav-book {
  transition-property: background-color, border-color, color, transform, translate, box-shadow;
  transition-duration: var(--dur-ui), var(--dur-ui), var(--dur-ui), var(--dur-ui), .5s, .4s;
  transition-timing-function: var(--ease);
}
.btn-primary:hover, .btn-invert:hover { box-shadow: 0 10px 28px rgba(217, 239, 63, .38); }
@media (prefers-reduced-motion: reduce) {
  .js .lesson.fade.is-in.is-tilt, .js .review.fade.is-in.is-tilt { transform: none; }
}

/* --- Live lines. */
.live-line {
  display: flex; align-items: center; gap: .55rem;
  margin: .4rem 0 0; font-size: .875rem; color: var(--muted);
}
.live-line[hidden] { display: none; }
.live-line::before { content: ""; flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: #d9ef3f; }
.hero-note + .live-line { margin-top: .75rem; }

/* --- Tip of the week. */
.tip-week { padding-block: clamp(2.5rem, 5vw, 4rem) clamp(2rem, 4vw, 3.25rem); }
.tip-week h2 { font-size: clamp(1.4rem, 2.4vw, 1.75rem); letter-spacing: -0.02em; margin: .4rem 0 .6rem; max-width: 26ch; }
.tip-week .tip-week-text { max-width: 62ch; margin: 0 0 .5rem; }
.tip-week .tip-week-link { margin-top: 0; }

/* --- Bring a friend. */
.offer {
  margin: .6rem 0 0; padding-inline-start: .85rem;
  border-inline-start: 3px solid #d9ef3f;
  font-size: .9375rem; color: var(--muted);
}

/* --- How to find the court: a drawn map on the black band, after the
       contact grid, with its numbered legend beside it. */
.court-map {
  display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: 1.25rem clamp(1.5rem, 4vw, 3rem); align-items: center;
  margin: clamp(2rem, 4vw, 3rem) 0 0; padding-top: clamp(1.5rem, 3vw, 2.25rem);
  border-top: 1px solid rgba(255, 255, 255, .18);
}
.court-map-art { display: block; width: 100%; height: auto; max-width: 34rem; font-family: var(--font); }
.court-map figcaption { min-width: 0; }
.court-map-legend { list-style: none; margin: 0; padding: 0; counter-reset: stop; }
.court-map-legend li {
  position: relative; padding: .4rem 0 .4rem 2.1rem; counter-increment: stop;
  border-top: 1px solid rgba(255, 255, 255, .18); color: rgba(255, 255, 255, .86);
}
.court-map-legend li:last-child { border-bottom: 1px solid rgba(255, 255, 255, .18); }
.court-map-legend li::before {
  content: counter(stop); position: absolute; left: 0; top: .5rem;
  width: 1.5rem; height: 1.5rem; border-radius: 50%; background: #fff; color: var(--ink);
  font-size: .8125rem; font-weight: 600; display: grid; place-items: center;
}
.court-map-note { margin: .9rem 0 0; font-size: .9375rem; color: rgba(255, 255, 255, .76); max-width: 44ch; }
.court-map-scale { display: inline-block; margin-inline-start: .35rem; font-size: .8125rem; color: rgba(255, 255, 255, .5); }
:root[dir="rtl"] .court-map-legend li { padding: .4rem 2.1rem .4rem 0; }
:root[dir="rtl"] .court-map-legend li::before { left: auto; right: 0; }
@media (max-width: 760px) { .court-map { grid-template-columns: 1fr; } }

/* --- The intro video. */
.intro-video { margin: 1.75rem 0 0; }
.intro-video video { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; border-radius: var(--radius); background: #000; }
.intro-video figcaption { margin-top: .6rem; font-size: .875rem; color: var(--muted); }

/* --- On the Persian page motion.js keeps each rolling price in one
       left-to-right span; it is the number itself, not a unit, so it opts
       out of the unit's small muted style like the digits do. */
.hero-facts dd .sb-ltr, .price .sb-ltr { font-size: 1em; font-weight: inherit; color: inherit; letter-spacing: inherit; }

/* --- The press ripple. The ring lives in its own clipped layer, so the
       button's shape clips it and nothing else on the button changes. */
.btn { position: relative; isolation: isolate; }
.btn > .ripple { position: absolute; inset: 0; z-index: -1; overflow: hidden; border-radius: inherit; pointer-events: none; }
.btn > .ripple > i {
  position: absolute; width: 14px; height: 14px; margin: -7px 0 0 -7px; border-radius: 50%;
  background: #d9ef3f; opacity: .85; transform: scale(0);
  animation: btnRipple .65s cubic-bezier(.22, 1, .36, 1) forwards;
}
.btn-primary > .ripple > i, .btn-invert > .ripple > i { mix-blend-mode: normal; }
@keyframes btnRipple { to { transform: scale(28); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .btn > .ripple { display: none; } }
