/* assets/css/components.css
 * Reusable pieces shared across every Sasmax page: buttons, eyebrow +
 * marker-accent heading treatment, cards, tabs, form fields, social row.
 * Page-specific composition lives in sections.css.
 */

/* ---- Buttons -------------------------------------------------------
 * Source: "Property 1=Default" and "Property 1=Variant2" symbols.
 * Default  — lime fill, 1px ink border, ink label.
 * Inverted — ink fill, 1px lime border, white label.
 */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 49px;
  padding: 13px 28px;
  border: 1px solid var(--forest);
  border-radius: var(--radius-btn);
  background: var(--band);
  color: var(--forest);
  font-family: var(--font-body);
  font-size: var(--body);
  line-height: 21px;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease,
    transform 0.12s ease, box-shadow 0.12s ease;
}

/* Hard offset shadow on hover, no blur, so the button reads as a solid block
   lifting off the page. It matches the hand-drawn artwork better than a soft
   shadow would, and it collapses on :active so clicking presses it back down. */
.btn:hover {
  background: var(--forest);
  color: var(--band);
  transform: translate(-2px, -2px);
  box-shadow: 4px 4px 0 var(--verde-400);
}

.btn:active {
  transform: translate(0, 0);
  box-shadow: 0 0 0 var(--verde-400);
}

.btn--inverted {
  background: var(--forest);
  border-color: var(--band);
  color: var(--white);
}

.btn--inverted:hover {
  background: var(--band);
  border-color: var(--forest);
  color: var(--forest);
  box-shadow: 4px 4px 0 var(--forest);
}

/* Secondary action that still reads as a button. Used for Log in beside the
   filled Book a demo, so the two do not compete. */
.btn--outline {
  background: transparent;
  border-color: var(--forest);
  color: var(--forest);
}

.btn--outline:hover {
  background: var(--forest);
  color: var(--band);
}

.btn--text {
  min-height: 0;
  padding: 0;
  border: 0;
  background: none;
}

/* A borderless text button has no block to lift, so it opts out. */
.btn--text:hover {
  background: none;
  color: var(--ink);
  transform: none;
  box-shadow: none;
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* ---- Hard shadow ----------------------------------------------------
 * The text counterpart to the button lift above. Opt-in, so a heading
 * only gets it where it earns it — heroes, not every h2 on the page.
 *
 * Callers set --hard-shadow-offset in their own rule and leave the colour
 * alone; see tokens.css for why it is fixed. The shadow inherits into
 * nested spans, which is what keeps a .marked phrase looking like the
 * rest of the line instead of a separate treatment.
 */

.hard-shadow {
  text-shadow: var(--hard-shadow-offset) var(--hard-shadow-offset) 0
    var(--hard-shadow);
}

/* ---- Eyebrow + marker accent ---------------------------------------
 * Eyebrows are set in the handwritten accent face. The lime marker
 * strokes under headings are the designer's own vector art, exported
 * from the source file — positioned absolutely so they sit behind the
 * words exactly as drawn.
 */

.eyebrow {
  font-family: var(--font-accent);
  font-size: 20px;
  line-height: 20.8px;
  color: var(--ink);
}


.marked {
  position: relative;
  display: inline-block;
}

/* One stroke, one rule. The marker is sized from the phrase it marks
   (104% of its width, height kept proportional) and dropped just under
   the baseline, so it reads the same under a 76px headline and a 16px
   nav link. */
.marker {
  position: absolute;
  left: -2%;
  top: calc(100% - 0.30em);
  width: 104%;

  /* HEIGHT FROM THE TYPE SIZE, NOT THE TEXT WIDTH.
   *
   * This was `height: auto` on a 300x22 SVG, so the thickness of the stroke
   * followed how LONG the phrase was. Under "whole club from" at 1030px wide
   * it came out 75px tall; under "Home" in the nav at 62px wide it came out
   * 4.5px — a hairline where the brand mark should be. The comment above
   * claimed it read the same at both sizes. It did not.
   *
   * In em it tracks the type instead, which is the thing it is drawn under.
   * The stroke gets LONGER on a longer phrase rather than fatter, which is
   * also how a real marker behaves — you do not press harder to underline
   * more words.
   *
   * Horizontal stretch is the one distortion a horizontal brush stroke can
   * take without reading as distorted. */
  height: 0.4em;
  pointer-events: none;
  user-select: none;
  z-index: 0;
}

/* THE CURRENT-PAGE MARK IS THE STRONGEST ONE ON THE SITE.
 *
 * Everywhere else the stroke sits under a phrase you are already reading, so
 * it can be a wash of colour. In the nav it is doing a job: it is the only
 * thing saying which page you are on, and it has to carry that from across a
 * header at a glance rather than close up.
 *
 * 0.62em against 0.4em elsewhere, and pulled up so it overlaps the descenders
 * rather than floating below them — which is how a real marker crosses a word
 * instead of underlining it. */
.nav__link .marker {
  /* The nav link carries a DIFFERENT FILE, swapped in build.mjs rather than
     with `content: url()` here — the markup is generated, so pointing the src
     at the right asset is cleaner than overriding a replaced element from CSS.
     Geometry only below. */
  /* THINNER. 0.78em on a cropped stroke was a band; the original reads as a
     swipe because it is thin relative to its length. 0.48em on a two-word
     link is about the same ratio the hero stroke has under a long phrase,
     which is the thing that makes it look like the same hand. */
  top: calc(100% - 0.30em);
  left: -7%;
  width: 114%;
  height: 0.48em;
}

.marked > span {
  position: relative;
  z-index: 1;
}

/* ---- Section heading block ----------------------------------------- */

.sec-head {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.sec-head--center {
  align-items: center;
  text-align: center;
}

.sec-head__lead {
  max-width: 674px;
}

.sec-head--center .sec-head__lead {
  margin-inline: auto;
}

/* ---- Feature card (dark) -------------------------------------------
 * Source: Features > "Frame 13" / "Frame 14" — ink fill, 5px radius,
 * centered icon over centered copy.
 */

.feature-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  min-height: 240px;
  padding: 30px;
  border-radius: var(--radius);
  background: var(--forest);
  color: var(--white);
  text-align: center;
}

/* The new icons are drawn dark-on-light, so on a forest card they sit on
   a pale tile rather than being recolored. One tile size across all four
   keeps the row even even though the drawings differ in proportion. */
.feature-card__icon {
  width: 118px;
  height: 78px;
  padding: 12px 16px;
  border-radius: 16px;
  background: var(--verde-100);
  object-fit: contain;
}

.feature-card__title {
  color: var(--white);
}

.feature-card__body {
  max-width: 317px;
  color: var(--white);
}

/* ---- Pricing card ---------------------------------------------------
 * Source: Pricing > "Frame 47" (ink head, radius 5 5 0 0) over
 * "Frame 52" (paper body, radius 0 0 5 5).
 */

.plan {
  display: flex;
  flex-direction: column;
}

.plan__head {
  min-height: 146px;
  padding: 25px 32px;
  border-radius: var(--radius) var(--radius) 0 0;
  background: var(--forest);
  color: var(--white);
  text-align: center;
}

.plan__name {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 32px;
  line-height: 41.6px;
  color: var(--white);
}

.plan__price {
  margin-top: 10px;
  color: var(--white);
}

.plan__body {
  flex: 1;
  min-height: 323px;
  padding: 30px;
  border-radius: 0 0 var(--radius) var(--radius);
  background: var(--paper);
}

.plan__list {
  display: flex;
  flex-direction: column;
  gap: 30px;
}

.plan__item {
  display: flex;
  align-items: flex-start;
  gap: 6px;
}

.plan__check {
  flex: none;
  width: 26px;
  height: auto;
  margin-top: -1px;
}

/* ---- Tabs -----------------------------------------------------------
 * Source: "Choose Sections" symbol — lime when idle, ink with lime
 * label when selected. Square corners, three equal thirds.
 */

.tabs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  width: 1080px;
  max-width: 100%;
  margin-inline: auto;
}

.tab {
  min-height: 51px;
  padding: 15px 12px;
  border: 0;
  background: var(--band);
  color: var(--forest);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 16px;
  line-height: 21px;
  text-align: center;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}

/* The strip is a panel, so its outer corners match the stage below it. */
.tab:first-child {
  border-radius: var(--radius) 0 0 var(--radius);
}

.tab:last-child {
  border-radius: 0 var(--radius) var(--radius) 0;
}

.tab[aria-selected="true"] {
  background: var(--forest);
  color: var(--band);
}

/* ---- Social row ----------------------------------------------------- */

.socials {
  display: flex;
  align-items: center;
  gap: 20px;
}

.socials a {
  display: block;
  opacity: 1;
  transition: opacity 0.15s ease;
}

.socials a:hover {
  opacity: 0.7;
}

/* 26, not 20. The old icons were flat single-colour glyphs and survived being
   tiny; these are drawn, with linework and a blob behind them, and at 20px the
   strokes close up — the X in particular becomes a smudge. I rendered 20, 26
   and 32 on the footer's own colour before picking. */
.socials img {
  height: 26px;
  width: auto;
}

/* ---- Dots ------------------------------------------------------------
 * The selected review stretches to a pill rather than just darkening, so
 * position in the set is readable at a glance instead of by comparing
 * three opacities.
 */

.dots {
  display: flex;
  align-items: center;
  gap: 8px;
}

.dots button {
  width: 10px;
  height: 10px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--forest);
  opacity: 0.28;
  cursor: pointer;
  transition: width 0.22s ease, opacity 0.22s ease;
}

.dots button:hover {
  opacity: 0.55;
}

.dots button[aria-selected="true"] {
  width: 30px;
  opacity: 1;
}

@media (max-width: 640px) {
  .plan__head {
    min-height: 0;
  }

  .plan__body {
    min-height: 0;
  }

  .tabs {
    grid-template-columns: 1fr;
  }

  .tab:first-child {
    border-radius: var(--radius) var(--radius) 0 0;
  }

  .tab:last-child {
    border-radius: 0 0 var(--radius) var(--radius);
  }
}

/* ---- Brand lockup ---------------------------------------------------
 * The Verde mark plus a typeset wordmark, so the footer can invert the
 * word without needing a second image.
 */

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.brand__mark {
  width: auto;
  height: 38px;
}

.brand__word {
  font-family: var(--font-brand);
  font-weight: 700;
  font-size: 28px;
  line-height: 1;

  /* Geometric faces need tracking opened at display size, not closed. The
     previous -0.01em was set for Be Vietnam Pro, whose bowls are narrower;
     applied to Outfit it jams the r against the d. */
  letter-spacing: 0.01em;
  color: var(--forest);
}

.brand--light .brand__word {
  color: var(--white);
}

.brand--lg .brand__mark {
  height: 48px;
}

.brand--lg .brand__word {
  font-size: 34px;
}

/* ---- Sport chips ----------------------------------------------------
 * Names the four things Verde runs. Used under the hero so the page
 * says what it covers before anyone scrolls.
 */

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 16px;
}

/* The illustrated icons carry their own tinted blob, so the pill that used
   to sit behind them is gone. They stop reading below about 56px, which is
   why this is a row of icon-and-label rather than small tags. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 15px;
  line-height: 20px;
  color: var(--ink);
}

.chip img {
  width: 44px;
  height: 44px;
}


/* ---- Form ------------------------------------------------------------
 * Fields are sized for the dark contact panel but inherit nothing from it,
 * so the same markup works on a light background too.
 */

.form__row + .form__row {
  margin-top: 40px;
}

.form__label {
  display: block;
  margin-bottom: 11px;
  font-size: var(--body);
  line-height: 18px;
  color: var(--white);
}

.form__control {
  display: block;
  width: 100%;
  min-height: 48px;
  padding: 13px 18px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: var(--white);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--body);
  line-height: 22px;
}

.form__control:focus-visible {
  border-color: var(--band);
  outline: 2px solid var(--band);
  outline-offset: 2px;
}

textarea.form__control {
  min-height: 202px;
  resize: vertical;
}

.form__submit {
  width: 100%;
  margin-top: 40px;
}

.form__status {
  margin-top: 16px;
  min-height: 21px;
  font-size: var(--small);
  line-height: var(--small-lh);
  color: var(--band);
}

.form__status[data-state="error"] {
  color: #ffb4a8;
}

/* ---- Accordion -------------------------------------------------------
 * Native <details>/<summary>, so it works with JavaScript disabled and the
 * keyboard behaviour comes free. The script only handles closing siblings.
 */

.faq {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.faq__item {
  border-radius: var(--radius);
  background: var(--paper);
  overflow: hidden;
}

.faq__item[open] {
  background: transparent;
}

.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  min-height: 52px;
  padding: 15px 20px;
  border-radius: var(--radius);
  background: var(--paper);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: var(--body);
  line-height: 22px;
  cursor: pointer;
  list-style: none;
  transition: background-color 0.15s ease;
}

.faq__q::-webkit-details-marker {
  display: none;
}

.faq__item[open] .faq__q {
  min-height: 58px;
  background: var(--band);
}

.faq__q:hover {
  background: var(--verde-100);
}

.faq__item[open] .faq__q:hover {
  background: var(--band);
}

.faq__sign {
  flex: none;
  width: 20px;
  height: 20px;
  color: var(--ink);
  transition: transform 0.18s ease;
}

.faq__item[open] .faq__sign {
  transform: rotate(45deg);
}

.faq__a {
  padding: 16px 20px 6px;
  font-size: var(--lead);
  line-height: 26px;
  color: var(--ink-soft);
}

/* ---- Closing CTA -----------------------------------------------------
 * Shared by About, Hardware and Careers. The artwork sits at the two edges
 * and the copy sits in the gap between them, so the panel padding has to
 * clear the ornaments rather than the container.
 */

.cta {
  padding: 110px 0 20px;
}

.cta__box {
  position: relative;
  overflow: hidden;
  display: grid;
  place-items: center;
  min-height: 406px;
  padding: 60px 360px;
  border-radius: 18px;
  background: var(--paper);
  text-align: center;
}

.cta__orn {
  position: absolute;
  top: 0;
  height: 100%;
  width: auto;
  pointer-events: none;
  user-select: none;
}

.cta__orn--l {
  left: 0;
}

.cta__orn--r {
  right: 0;
}

.cta__copy {
  position: relative;
  z-index: 1;
}

.cta__title {
  max-width: 600px;
  margin-inline: auto;
  font-size: var(--h3);
  line-height: var(--h3-lh);
}

.cta__lead {
  max-width: 560px;
  margin: 18px auto 0;
  color: var(--ink-soft);
}

.cta__btn {
  margin-top: 30px;
}

/* The Founding Partner variant: a more saturated panel and a dark button,
   because it is an offer rather than a generic closing CTA. */
.cta--founding .cta__box {
  background: var(--verde-100);
}

.cta--founding .cta__title {
  max-width: 660px;
}

@media (max-width: 1340px) {
  .cta__box {
    padding: 60px 280px;
  }
}

@media (max-width: 1100px) {
  .cta {
    padding-top: 72px;
  }

  /* The ornaments are sized off the panel height; below this there is not
     enough width left between them for the heading. */
  .cta__orn {
    display: none;
  }

  .cta__box {
    min-height: 0;
    padding: 52px 40px;
  }
}

@media (max-width: 640px) {
  .cta__box {
    padding: 40px 24px;
  }
}

/* ---- Form primitives -------------------------------------------------
 * Shared by the demo and sign-in pages. The contact page keeps its own
 * dark-panel variants.
 */

.form-row + .form-row,
.form-grid + .form-row,
.form-row + .form-grid,
.form-grid + .form-grid {
  margin-top: 20px;
}

/* Two rows sitting side by side inside a grid are not stacked, so the
   stacking margin above must not apply to them — it was pushing the right
   column of every pair 20px below its partner. */
.form-grid .form-row + .form-row {
  margin-top: 0;
}

.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}

.form-row__label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
  padding: 0;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 15px;
  line-height: 20px;
  color: var(--ink);
}

.form-row__hint {
  font-family: var(--font-body);
  font-weight: 400;
  color: var(--ink-soft);
}

.form-row__aside {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 14px;
  color: var(--brand);
}

.form-row__aside:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.input {
  display: block;
  width: 100%;
  min-height: 50px;
  padding: 13px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--white);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--body);
  line-height: 22px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.input::placeholder {
  color: var(--ink-soft);
  opacity: 0.7;
}

.input:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(47, 163, 114, 0.16);
  outline: none;
}

.input[aria-invalid="true"] {
  border-color: var(--danger);
}

textarea.input {
  resize: vertical;
}

.input-wrap {
  position: relative;
}

.input-wrap .input {
  padding-right: 74px;
}

.reveal {
  position: absolute;
  top: 50%;
  right: 8px;
  transform: translateY(-50%);
  padding: 7px 10px;
  border: 0;
  border-radius: var(--radius-btn);
  background: transparent;
  color: var(--brand);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
}

.reveal:hover {
  background: var(--verde-50);
}

.check {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 18px;
  font-size: 15px;
  line-height: 21px;
  color: var(--ink-soft);
  cursor: pointer;
}

.check input {
  width: 17px;
  height: 17px;
  accent-color: var(--brand);
}

.form-status {
  min-height: 21px;
  margin-top: 14px;
  font-size: var(--small);
  line-height: var(--small-lh);
  color: var(--brand);
}

.form-status[data-state="error"] {
  color: var(--danger);
}

/* ---- Sport picker ----------------------------------------------------
 * A checkbox that looks like a chip. The native input stays in the DOM and
 * keeps its keyboard behaviour and focus ring; only its appearance moves.
 */

.picks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 10px;
}

.pick {
  cursor: pointer;
}

.pick__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.pick__body {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--white);
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 15px;
  line-height: 20px;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

.pick__icon {
  width: 30px;
  height: 30px;
}

.pick:hover .pick__body {
  border-color: var(--brand);
}

.pick__input:checked + .pick__body {
  border-color: var(--forest);
  background: var(--verde-100);
}

.pick__input:focus-visible + .pick__body {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* ============================================================
   PLAN CARD, shared rules

   These lived in pricing.css. The homepage renders the same card
   from /api/public/plans, and a card used by two pages cannot
   have half its rules in one page's stylesheet — index.html
   loads tokens, base, components and sections, so six of these
   classes resolved to nothing there.

   pricing.css keeps what is genuinely about the pricing PAGE:
   the hero, the plan grid and the comparison matrix.
   ============================================================ */

/* The middle plan is the one most clubs land on, so it sits proud of the
   other two rather than relying on a "most popular" sticker. */
.plan--featured {
  box-shadow: 0 18px 44px rgba(5, 52, 36, 0.14);
  border-radius: var(--radius);
}

/* Lifted rather than enlarged, so the feature lists still line up. */
.plan--featured {
  margin-top: -18px;
}

.plan--featured {
    box-shadow: none;
  }

.plan__figure {
  display: block;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 44px;
  line-height: 54px;
  color: var(--white);
}

.plan__cta {
  width: 100%;
  margin-top: 34px;
}

.plan__body {
  display: flex;
  flex-direction: column;
}

.plan__list {
  flex: 1;
}

/* The light half of the card. Everything that varies in length lives here
   rather than in the dark head — the head has a min-height, so a two-line
   tagline up there makes one card's panel taller than the others, and
   --ink-soft is a light-mode colour that goes muddy on forest. */
.c-plan-body {
  flex: 1;
  gap: 12px;
  padding: 26px 32px 30px;
}

/* First thing in the light area: the sentence that tells a club whether this
   is their plan at all. */
.c-plan-tag {
  font-size: var(--body);
  line-height: 24px;
  color: var(--ink);
}

.c-plan-year,
.c-plan-count {
  font-size: var(--small);
  line-height: var(--small-lh);
  color: var(--ink-soft);
}

.c-plan-count b {
  font-family: var(--font-data);
  font-weight: 500;
  color: var(--ink);
}

/* ---- Generated plan cards: the button goes to the floor ------------------
 *
 * .plan__cta is `margin-top: 34px`, which fixes the button 34px under whatever
 * is above it and leaves the rest of the card empty below. It was `auto` for a
 * while — that rule was lost when pricing.css and its build source diverged,
 * which is the same divergence commit-120 closed.
 *
 * `auto` on a column flex child eats all the free space above it, so the
 * button sits at the bottom of whatever height the row settles on and three
 * cards with different amounts of copy still line their buttons up.
 */
/* .plan__body carries min-height: 323px, sized for the old card that held a
   feature list. These cards hold four short lines, so that number is now just
   empty space under the button. The grid already equalises the heights. */
.c-plan-body {
  min-height: 0;
}

/* `auto` eats the free space above it, so the button lands at the bottom of
   whatever height the row settles on. padding-top keeps it off the last line
   of copy on a card short enough that `auto` yields nothing. */
.c-plan-body .plan__cta {
  margin-top: auto;
  padding-top: 18px;
}

/* The yearly price. Quiet, under the monthly figure's own line, because the
   monthly number is the one being compared across the three cards. */
.c-plan-year {
  font-size: var(--small);
  line-height: var(--small-lh);
  color: var(--ink-soft);
}
