/*
 * Shared auth styles for marketing/login.html and marketing/signup.html.
 *
 * Design tokens are translated from the Flutter app's _LoginLayout and
 * _SignupLayout (lib/screens/athlete_and_coach/auth/) so the marketing
 * auth flow visually matches the in-app one.  Everything else on the
 * marketing site keeps using fitclub-c188d8.webflow.css.
 *
 * Mobile breakpoint: 768px (matches AppTheme.mobileBreakpoint).
 */

:root {
  /* Brand color is sourced from the marketing palette (#6a4cff) so these
     pages stay visually consistent with the rest of marketing.  The Flutter
     app uses a slightly different purple (#5951D6) but switching marketing
     to that would create a brand mismatch on the rest of the site. */
  --auth-brand: var(--colors--brand-color, #6a4cff);
  --auth-brand-soft-22: rgba(106, 76, 255, 0.22);
  --auth-brand-soft-30: rgba(106, 76, 255, 0.30);
  --auth-brand-soft-48: rgba(106, 76, 255, 0.48);

  --auth-surface: rgba(255, 255, 255, 0.05);
  --auth-surface-strong: rgba(255, 255, 255, 0.08);
  --auth-border: rgba(255, 255, 255, 0.1);
  --auth-border-strong: rgba(255, 255, 255, 0.15);

  --auth-text: #ffffff;
  --auth-text-soft: rgba(255, 255, 255, 0.94);
  --auth-text-muted: rgba(255, 255, 255, 0.65);
  --auth-text-grey: var(--colors--grey-color, #a3a6b3);

  --auth-error: #ef4444;
  --auth-success: #22c55e;

  --auth-radius-input: 14px;
  --auth-radius-button: 16px;
  --auth-radius-tile: 16px;
  --auth-radius-card: 24px;
}

/* ============================================================
 * Global baseline — prevents horizontal scroll on narrow viewports.
 * auth pages don't load mobile.css so we set this here.
 * ============================================================ */

html,
body {
  overflow-x: hidden;
  -webkit-text-size-adjust: 100%;
}

/* ============================================================
 * Page section + card
 * ============================================================ */

.auth-section {
  position: relative;
  /* Default top padding for top-aligned steps (signup steps 1+,
     login).  Step 0 of signup overrides this with a flex layout
     anyway, so this value only matters for the back-button /
     title rows on inner steps. */
  padding-top: 48px;
  /* Bottom padding mirrors Flutter's
     `effectiveBottomPadding = AppTheme.spacingL + bottomInset`
     (~24 px on desktop without safe-area).  The previous 96 px
     left a chunky empty band beneath the "Criar conta" button on
     the last signup step compared to the in-app version. */
  padding-bottom: 28px;
  /*
   * Pin the section to a single vertical extent across every
   * step so the photographic hero (`.auth-section-bg-img`) and
   * its scrim never re-flow when the user advances between
   * step 0 (role chooser), step 1 (criar conta), and step 2
   * (seu perfil).  Without this, the section's height followed
   * the form's intrinsic height and the background "jumped"
   * with each step transition because the role tiles take up
   * far more vertical room than the credential / profile
   * forms do.
   *
   * Using `min-height` (not `height`) keeps long forms safe on
   * narrow viewports — the section can still grow taller than
   * the viewport if the keyboard pushes content down on mobile.
   */
  min-height: calc(100vh - var(--site-header, 0px));
}

/*
 * Section padding is now shared across every signup step (no
 * per-step override).  The base `.auth-section { padding-top: 48 }`
 * applies to step 0 (Treinador/Atleta), step 1 (Criar conta) and
 * step 2 (Seu perfil) alike, so the rendered section height is
 * IDENTICAL between steps — `min-height` already pinned the outer
 * box, but a per-step `padding-top` override would still grow the
 * content area on viewports where intrinsic content height + padding
 * exceeds the min-height (typical on shorter laptops).  Equalising
 * the padding kills that 32 px discrepancy so the hero photograph
 * and scrim never re-flow when the user advances between steps.
 *
 * Step 0's "extra headroom above the FitClub logo" is achieved
 * via `.auth-step--welcome > .auth-wordmark { margin-top: ... }`
 * below — it pushes the centered content stack downward inside the
 * (otherwise identical) section, so we can dial the logo's visual
 * breathing room independently of the section box itself.
 */

/*
 * On signup step 0 the content (wordmark + tagline + role tiles)
 * should sit vertically centered against the hero — same feel as
 * lib/screens/.../signup_page.dart, which uses
 * `Align(alignment: Alignment.center)` while on step 0.  We toggle
 * an attribute on the section based on `data-step` so this only
 * applies to the role chooser; later steps go back to the
 * top-aligned layout so the form doesn't bounce around when the
 * user advances.
 *
 * The full-viewport `min-height` lives on the base `.auth-section`
 * rule above so all three steps share the same vertical extent
 * (locks the photographic hero in place across step transitions).
 */
.auth-section[data-step="0"] {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/*
 * `.hero-glow` is the Webflow purple-smudge decoration that's
 * positioned `absolute; inset: 0` over the section.  The signup
 * hero now uses photographic role-specific backgrounds, and the
 * login hero relies on the cleaner `.auth-section-bg-scrim`, so the
 * purple blob just adds visual noise and clips the dynamic
 * background.  Hiding it outright also resolves the click-eating
 * stacking-context bug we'd previously patched with
 * `pointer-events: none`.
 */
.auth-section .hero-glow {
  display: none !important;
}

.auth-card {
  /* Free-flowing layout: no border / no fill — the form breathes inside
     the page's hero glow.  Matches the in-app login/signup, which also
     drops the auth fields directly onto the dark canvas instead of
     wrapping them in a panel.
     `position: relative; z-index: 1` is what guarantees the form sits
     above the absolutely-positioned `.hero-glow` decoration. */
  position: relative;
  z-index: 1;
  max-width: 440px;
  margin: 0 auto;
  /* Generous bottom padding so the trailing copy ("Já tem uma
     conta?", "Não tem uma conta?", and the terms blurb on the
     final signup step) lands well above the page-fold and isn't
     visually crammed against the next section.  This stacks with
     the parent `.auth-section { padding-bottom: 28px }`, which
     handles the breathing room between the form and whatever
     sits below the auth shell.  */
  padding: 16px 40px 40px;
  background: transparent;
  border: none;
  border-radius: 0;
  backdrop-filter: none;
}

.auth-section .w-layout-blockcontainer {
  position: relative;
  z-index: 1;
}

/* ============================================================
 * Step header (back button + title)
 * ============================================================ */

.auth-step-header {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  margin-bottom: 24px;
  /* No flex gap on purpose: back-button spacing + title/subtitle
     spacing are tuned individually below to match Flutter's rhythm
     (~32px after back, ~8px between title and subtitle). */
}

.auth-back-button {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: none;
  padding: 4px 4px 4px 0;
  margin: 0 0 32px 0;
  cursor: pointer;
  color: var(--auth-text-grey);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.1px;
  font-family: inherit;
  transition: color 0.2s ease;
}

.auth-back-button:hover {
  color: var(--auth-text-soft);
}

.auth-back-button svg {
  width: 16px;
  height: 16px;
}

.auth-title {
  font-size: 25px;
  font-weight: 700;
  letter-spacing: -0.55px;
  line-height: 1.08;
  color: var(--auth-text-soft);
  margin: 0;
}

.auth-subtitle {
  font-size: 15px;
  color: var(--auth-text-grey);
  margin: 8px 0 0 0;
  line-height: 1.4;
}

/* Welcome step (signup step 0) is centered around the wordmark hero. */
.auth-step--welcome .auth-step-header {
  text-align: center;
  margin-bottom: 16px;
}

.auth-step--welcome .auth-title {
  font-size: 28px;
  text-align: center;
}

.auth-step--welcome .auth-subtitle {
  text-align: center;
}

/*
 * Welcome step layout — we drop the default `.auth-step` flex `gap`
 * so we can give the wordmark and the tagline the SAME visual
 * padding underneath them (per the design call-out), then add a
 * larger breathing space before the role tiles, all via explicit
 * margins.  Other steps continue to use the parent's 16px gap.
 */
.auth-step--welcome {
  gap: 0;
}

.auth-step--welcome > .auth-wordmark {
  /*
   * The hero animation centers the wordmark alone in the section
   * and then slides the tagline + role tiles in from below.  We
   * deliberately give the wordmark a LARGER top margin than
   * bottom margin: the welcome step's overall layout (`.auth-
   * section[data-step="0"]`) flex-centers the entire content
   * column, so an asymmetric top:bottom margin pushes the whole
   * "wordmark + tagline + tiles" stack visually downward — i.e.
   * adds breathing room between the navbar and the FitClub logo
   * without crowding the role tiles against the page fold.
   *
   * The top value here also subsumes what used to be the per-step
   * `.auth-section[data-step="0"] { padding-top: 80px }` override
   * (now removed, see the section rule above) so step 0 and step
   * 1 land on identical section heights.  Pushing the breathing
   * room to the wordmark — instead of the section padding — keeps
   * the logo's vertical position dialled in without changing the
   * outer box geometry.
   *
   * Bottom margin still controls the gap between the wordmark
   * and the "Escolha sua experiência" tagline — the small
   * (22 px) value keeps that pair tight, so the tagline reads
   * as a caption to the logo instead of a separate paragraph.
   */
  margin: 104px auto 22px;
}

@media screen and (max-width: 767px) {
  .auth-step--welcome > .auth-wordmark {
    /* Tighter on phones — the section already takes up a smaller
       slice of the viewport so we can afford to keep these
       margins small without crowding the role tiles.  Same
       asymmetry as desktop (bigger top than bottom) so the
       logo isn't glued to the navbar. */
    margin: 64px auto 12px;
  }
}

/*
 * Tagline — pixel-matches the in-app `_buildBrandHeader` Text in
 * lib/screens/.../signup_page.dart, which uses
 *   GoogleFonts.montserrat(
 *     fontSize: 13–15,                  // tight vs roomy layout
 *     fontWeight: FontWeight.w500,
 *     fontStyle: FontStyle.italic,
 *     color: AppTheme.white.withOpacity(0.82),
 *   )
 * The bottom margin is intentionally small so the tagline reads
 * as the prompt for the role tiles directly underneath, not as a
 * separate paragraph beneath the wordmark.
 */
.auth-welcome-tagline {
  margin: 0 0 12px;
  font-family: 'Montserrat', 'Geist', system-ui, sans-serif;
  font-size: 15px;
  font-weight: 500;
  font-style: italic;
  text-align: center;
  color: rgba(255, 255, 255, 0.82);
  letter-spacing: 0.1px;
}

@media screen and (max-width: 767px) {
  .auth-welcome-tagline {
    font-size: 13px;
    margin-bottom: 10px;
  }
}

/*
 * Step 0 spacing override
 *
 * Default `.auth-role-row` margin is `8px 0 22px` to mirror
 * Flutter's `Padding.fromLTRB(0, 8, 0, 22)` in
 * `_buildMinimalRoleOptions`, which keeps the role tiles in
 * vertical rhythm with the wordmark + tagline above and gives
 * the selected/hover glow some breathing room below.
 *
 * No further override is needed inside `.auth-step--welcome`,
 * since this step is the only consumer of `.auth-role-row`.
 */

/*
 * Step 0 reveal animation
 *
 * The brief: on page load the FitClub wordmark should sit by itself,
 * vertically centered in the hero.  After a short beat the tagline
 * ("Escolha sua experiência") and the Treinador / Atleta tiles
 * slide in from below, and the wordmark glides upward so the whole
 * cluster (logo + tagline + tiles) ends up centered as a group.
 *
 * Implementation:
 *   - The section uses `display: flex; justify-content: center` for
 *     the welcome step (see `.auth-section[data-step="0"]` above),
 *     so the wordmark is naturally centered against whatever
 *     vertical extent its column happens to have.
 *   - Tagline and role-row start with `max-height: 0`, `opacity: 0`,
 *     zero margins and `overflow: hidden`, so they take ZERO
 *     vertical space — meaning the column is just the wordmark and
 *     the wordmark is centered alone.
 *   - At t = 600 ms (matches Flutter's `_kWelcomeRevealDelay`) the
 *     animation grows them back to their natural footprint over
 *     560 ms of `Curves.easeOutCubic` motion (matches Flutter's
 *     `_kWelcomeRevealAnimation`).  As `max-height` and margins
 *     expand, the section's flex centering pushes the wordmark up
 *     so the whole group stays visually centered the whole way.
 *   - Tagline and role-row are also given a small upward
 *     translate3d as they fade in — pure cosmetic motion to add a
 *     touch of energy to the reveal.
 *
 * Note: explicit `max-height` upper bounds (200 px / 320 px) are
 * comfortably larger than the natural rendered heights at every
 * supported breakpoint, so the easeOutCubic curve still resolves
 * before content gets clipped.
 */
.auth-step--welcome > .auth-welcome-tagline {
  max-height: 0;
  opacity: 0;
  margin: 0;
  overflow: hidden;
  transform: translate3d(0, 8px, 0);
  animation: auth-welcome-tagline-reveal 560ms cubic-bezier(0.215, 0.61, 0.355, 1) 600ms forwards;
}

.auth-step--welcome > .auth-role-row {
  max-height: 0;
  opacity: 0;
  margin: 0;
  overflow: hidden;
  transform: translate3d(0, 8px, 0);
  animation: auth-welcome-role-reveal 560ms cubic-bezier(0.215, 0.61, 0.355, 1) 600ms forwards;
}

@keyframes auth-welcome-tagline-reveal {
  to {
    max-height: 200px;
    opacity: 1;
    /* Restores the normal post-reveal margins set on
       `.auth-welcome-tagline` (12 px below).  */
    margin: 0 0 12px;
    transform: translate3d(0, 0, 0);
  }
}

@keyframes auth-welcome-role-reveal {
  to {
    max-height: 320px;
    opacity: 1;
    /* Restores the normal post-reveal margins from `.auth-role-row`
       (8 px above, 22 px below).  */
    margin: 8px 0 22px;
    transform: translate3d(0, 0, 0);
  }
}

@media screen and (max-width: 767px) {
  /* Mobile tagline uses a 10 px bottom margin (set on
     `.auth-welcome-tagline`).  Match it in the keyframe so the
     animation lands on the right resting state.  */
  @keyframes auth-welcome-tagline-reveal {
    to {
      max-height: 200px;
      opacity: 1;
      margin: 0 0 10px;
      transform: translate3d(0, 0, 0);
    }
  }
}

@media (prefers-reduced-motion: reduce) {
  .auth-step--welcome > .auth-welcome-tagline,
  .auth-step--welcome > .auth-role-row {
    animation: none;
    opacity: 1;
    max-height: none;
    transform: none;
  }
  .auth-step--welcome > .auth-welcome-tagline {
    margin: 0 0 12px;
  }
  .auth-step--welcome > .auth-role-row {
    margin: 8px 0 22px;
  }
}

/* ============================================================
 * Hero wordmark + shimmer (signup step 0)
 *
 * Translates lib/widgets/fitclub_wordmark.dart `_HeroWordmark` to
 * a CSS-only equivalent.  The previous version animated
 * `background-position` on a masked element, which on every
 * iteration teleported the gradient back across the screen — the
 * snap-back was visible as a flicker on Chromium.  This version
 * replaces it with a fixed-size GPU-composited bar that moves via
 * `transform: translateX` inside a separate masked container.
 * Transforms don't trigger relayout/repaint of the mask, and the
 * bar's edges are off-screen at the start and end of every cycle
 * so the loop reset is invisible.
 * ============================================================ */

.auth-wordmark {
  position: relative;
  display: block;
  width: 100%;
  max-width: 460px;
  margin: 0 auto;
  /* Aspect ratio of fitclub_wordmark_both.svg = 2801 / 280 = 10.0 */
  aspect-ratio: 2801 / 280;
  pointer-events: none;
}

.auth-wordmark img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  user-select: none;
  -webkit-user-drag: none;
}

.auth-wordmark-mask {
  position: absolute;
  inset: 0;
  overflow: hidden;
  /*
   * The mask SVG is a uniformly-white silhouette of the wordmark
   * (`fitclub_wordmark_both_mask.svg`).  Using a separate
   * silhouette — instead of the colored display SVG —
   * sidesteps every browser's mask-mode quirk:
   *   - `mask-mode: alpha` should fill all opaque paths, but
   *     Chrome's `-webkit-mask` historically defaulted to
   *     `luminance` for SVG sources;
   *   - `mask-mode: luminance` then weights the mask by each
   *     fill's brightness, so the dark-purple "ONE" letters
   *     ramped to ~37% opacity while "Fitclub" (near-white) hit
   *     ~98%, painting the shimmer unevenly across the mark.
   * Forcing every path in the silhouette to `#ffffff` makes
   * BOTH luminance AND alpha masks hit 100% opacity — the
   * shimmer now sweeps cleanly across "Fitclub" AND "ONE"
   * without touching the actual displayed colors below.
   */
  -webkit-mask: url('../images/fitclub_wordmark_both_mask.svg') no-repeat center / contain;
          mask: url('../images/fitclub_wordmark_both_mask.svg') no-repeat center / contain;
  -webkit-mask-mode: alpha;
          mask-mode: alpha;
  pointer-events: none;
}

.auth-wordmark-shimmer {
  position: absolute;
  top: -10%;
  bottom: -10%;
  left: 0;
  width: 35%;
  background: linear-gradient(
    100deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0) 30%,
    rgba(255, 255, 255, 0.55) 50%,
    rgba(255, 255, 255, 0) 70%,
    rgba(255, 255, 255, 0) 100%
  );
  /*
   * Start the bar fully off-screen LEFT, sweep to fully off-screen
   * RIGHT, and hold there for ~40% of each cycle to mimic the pause
   * between Flutter's shimmer cycles.  Loop reset jumps from
   * +320% back to -120% — both off-screen positions so the user
   * never sees the snap.
   */
  transform: translate3d(-120%, 0, 0);
  mix-blend-mode: screen;
  will-change: transform;
  animation: auth-wordmark-shimmer 3.4s linear infinite;
  pointer-events: none;
}

@keyframes auth-wordmark-shimmer {
  0%, 6%    { transform: translate3d(-120%, 0, 0); }
  60%, 100% { transform: translate3d(320%, 0, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .auth-wordmark-shimmer { animation: none; opacity: 0; }
}

/* ============================================================
 * Hero backgrounds (signup step 0)
 *
 * Three layered <img> elements; only one has `is-active` at a time.
 * Hovering Treinador or Atleta swaps which layer is visible —
 * mirrors lib/screens/.../signup_page.dart `_signupWelcomeBgLayer`.
 *
 * On step 1+ the entire stack fades out so the rest of the form is
 * not painted over a busy photograph.
 * ============================================================ */

.auth-section-bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}

.auth-section-bg-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  opacity: 0;
  transition: opacity 0.32s cubic-bezier(0.4, 0, 0.2, 1);
}

.auth-section-bg-img.is-active {
  opacity: 1;
}

.auth-section-bg-scrim {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.46);
  transition: background 0.32s cubic-bezier(0.4, 0, 0.2, 1);
}

.auth-section--bg-coach .auth-section-bg-scrim,
.auth-section--bg-athlete .auth-section-bg-scrim {
  background: rgba(0, 0, 0, 0.38);
}

/*
 * Once the user picks a role we LOCK the chosen background in for
 * the rest of the flow (steps 1 + 2), mirroring the in-app
 * signup_page.dart where the role-specific hero stays put after
 * tapping a tile.  We just dim the layer slightly and darken the
 * scrim so the inputs read cleanly against the imagery — the same
 * effect Flutter achieves with its 0.48 background opacity.
 */
.auth-section--past-step-0 .auth-section-bg-img {
  opacity: 0;
}
.auth-section--past-step-0.auth-section--bg-coach .auth-section-bg-img--coach,
.auth-section--past-step-0.auth-section--bg-athlete .auth-section-bg-img--athlete {
  opacity: 0.55;
}
.auth-section--past-step-0 .auth-section-bg-scrim {
  background: rgba(0, 0, 0, 0.58);
}

/* ============================================================
 * Form fields
 * ============================================================ */

/* Login uses the regular flex column layout (no steps). */
.auth-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/*
 * Signup uses a grid that stacks all step panes in the same cell.  The
 * form's height becomes the max of every step's natural height, so
 * advancing or going back between steps never shifts the page height
 * (no scroll-jump, no resize).  Inactive steps still occupy space —
 * they're just hidden via opacity / visibility / `inert`.
 */
.auth-form--steps {
  display: grid;
  grid-template-areas: "stack";
  gap: 0;
}

.auth-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.auth-input-wrap {
  position: relative;
  display: flex;
  align-items: center;
  background: var(--auth-surface);
  border: 1px solid var(--auth-border);
  border-radius: var(--auth-radius-input);
  transition: border-color 0.2s ease, background 0.2s ease;
}

.auth-input-wrap:focus-within {
  border-color: var(--auth-brand-soft-48);
  background: var(--auth-surface-strong);
}

.auth-input-wrap--error {
  border-color: rgba(239, 68, 68, 0.55);
}

.auth-input-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  width: 44px;
  color: var(--auth-text-grey);
  pointer-events: none;
}

.auth-input-icon svg {
  width: 18px;
  height: 18px;
}

.auth-input-icon--button {
  pointer-events: auto;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  font: inherit;
  color: var(--auth-text-grey);
  transition: color 0.2s ease;
}

.auth-input-icon--button:hover {
  color: var(--auth-text-soft);
}

.auth-input {
  flex: 1;
  background: transparent;
  border: none;
  /* Webflow's webflow.css applies its own input :focus styles (border /
     shadow) that paint a hard-edged ring on top of our soft brand glow.
     Forcefully kill them so the only visible focus state is the
     parent .auth-input-wrap's brand-color border. */
  outline: none !important;
  box-shadow: none !important;
  padding: 13px 16px 13px 0;
  font-size: 14px;
  font-family: inherit;
  color: var(--auth-text-soft);
  min-width: 0;
  /* Mobile: Safari-iOS adds a tap highlight on touch — kill it. */
  -webkit-tap-highlight-color: transparent;
}

/* Read-only inputs (e.g. the birthdate field, which only writes when
   the wheel picker confirms) should still feel like a button: show a
   pointer cursor, and skip the muted text some browsers apply when an
   input is non-editable. */
.auth-input[readonly] {
  cursor: pointer;
  color: var(--auth-text-soft);
}
.auth-input[readonly]::placeholder {
  color: var(--auth-text-grey);
}

.auth-input:focus,
.auth-input:focus-visible {
  outline: none !important;
  box-shadow: none !important;
  border: none !important;
}

/*
 * Browser autofill (Chrome / Safari) paints a hard yellow / white box
 * on the input itself, which clashes badly with the dark surface.  We
 * mask it with an inset box-shadow that matches the rendered colour of
 * the surrounding .auth-input-wrap, and force the text colour back to
 * our soft white.  The 9999s transition is a well-known trick to delay
 * the yellow flash long enough that nobody ever sees it.
 */
.auth-input:-webkit-autofill,
.auth-input:-webkit-autofill:hover,
.auth-input:-webkit-autofill:focus,
.auth-input:-webkit-autofill:active {
  -webkit-text-fill-color: var(--auth-text-soft);
  -webkit-box-shadow: 0 0 0 1000px #16161f inset;
  box-shadow: 0 0 0 1000px #16161f inset;
  caret-color: var(--auth-text-soft);
  transition: background-color 9999s ease-out 0s;
}

/* Bigger paddings/font on mobile to match Flutter's compact layout. */
@media screen and (max-width: 767px) {
  .auth-input {
    padding-top: 18px;
    padding-bottom: 18px;
    font-size: 16px;
  }
  .auth-input-icon {
    width: 48px;
  }
  .auth-input-icon svg {
    width: 20px;
    height: 20px;
  }
}

.auth-input::placeholder {
  color: rgba(255, 255, 255, 0.4);
}

.auth-field-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--auth-text-soft);
  letter-spacing: 0.1px;
}

.auth-field-error {
  display: none;
  font-size: 12px;
  color: var(--auth-error);
  margin-top: 4px;
  line-height: 1.4;
}

/*
 * Always-visible field hint (e.g. password requirements).  We hide
 * it when the field is in an error state to avoid stacking two
 * lines of helper text — the inline error is more important.
 */
.auth-field-hint {
  font-size: 12px;
  color: var(--auth-text-grey);
  margin-top: 6px;
  line-height: 1.45;
}

.auth-field--has-error .auth-field-hint {
  display: none;
}

.auth-field--has-error .auth-field-error {
  display: block;
}

.auth-field--has-error .auth-input-wrap {
  border-color: rgba(239, 68, 68, 0.55);
}

/*
 * Birthdate trigger — the chevron-down icon on the right side of
 * the birthdate field.  Matches the Flutter behavior: pressing it
 * (or any "non-text" part of the field) opens the native date
 * picker; typing into the input still works for users who prefer
 * keyboard input.
 */
.auth-input-icon--trigger {
  pointer-events: auto;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  font: inherit;
  color: var(--auth-text-grey);
  transition: color 0.2s ease;
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
}

.auth-input-icon--trigger:hover {
  color: var(--auth-text-soft);
}

.auth-input-icon--trigger svg {
  width: 16px;
  height: 16px;
}

/* The hidden native <input type="date"> backing the calendar picker.
   Kept in the DOM (so showPicker() works on browsers that require it)
   but pulled out of the layout. */
.auth-date-native {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
  pointer-events: none;
}

/* Username availability indicator (right-side adornment in the input wrap). */
.auth-input-trailing {
  display: flex;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  width: 36px;
  color: var(--auth-text-grey);
}

.auth-input-trailing--ok {
  color: var(--auth-success);
}

.auth-input-trailing--bad {
  color: var(--auth-error);
}

.auth-input-trailing svg {
  width: 16px;
  height: 16px;
}

.auth-input-trailing .auth-spinner {
  width: 14px;
  height: 14px;
  border: 2px solid rgba(255, 255, 255, 0.2);
  border-top-color: var(--auth-brand);
  border-radius: 50%;
  animation: auth-spin 0.7s linear infinite;
}

@keyframes auth-spin {
  to { transform: rotate(360deg); }
}

/* ============================================================
 * Primary button
 * ============================================================ */

.auth-primary {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 46px;
  background: var(--auth-brand);
  color: #ffffff;
  border: none;
  border-radius: var(--auth-radius-button);
  font-size: 14.5px;
  font-weight: 600;
  letter-spacing: -0.2px;
  font-family: inherit;
  cursor: pointer;
  transition: opacity 0.2s ease, background 0.2s ease;
  margin-top: 8px;
}

.auth-primary:hover:not(:disabled) {
  opacity: 0.92;
}

.auth-primary:disabled {
  background: var(--auth-brand-soft-48);
  cursor: not-allowed;
}

@media screen and (max-width: 767px) {
  .auth-primary {
    height: 54px;
    font-size: 16px;
  }
}

/* ============================================================
 * OAuth (Google) button + divider
 * ============================================================ */

.auth-divider {
  display: flex;
  align-items: center;
  gap: 16px;
  /*
   * Margin reset to 0 so the divider's vertical breathing is
   * provided entirely by the parent flex `gap: 16` — same 16 px
   * above and below.  The previous asymmetric 24 / 16 created a
   * lopsided "ou" line that visually leaned closer to the OAuth
   * button than to the form fields above.
   */
  margin: 0;
}

.auth-divider-line {
  flex: 1;
  height: 1px;
  background: var(--auth-border-strong);
}

.auth-divider-text {
  font-size: 13px;
  color: var(--auth-text-grey);
}

.auth-oauth-button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  height: 46px;
  background: rgba(26, 26, 37, 0.9);
  color: var(--auth-text);
  border: 1px solid var(--auth-border);
  border-radius: var(--auth-radius-button);
  font-size: 14px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
  /*
   * Extra breathing room below the Google tile so the typed-
   * credential CTA underneath it ("Continuar" on signup step 1,
   * "Entrar" on login) reads as a clearly-separate path, not as
   * an option pinned right under the OAuth button.  Combined
   * with the parent's `gap: 16` and `.auth-primary { margin-top: 8 }`,
   * the gap between the bottom of the Google button and the top
   * of the primary CTA ends up at ~144 px — deliberately roomy
   * so the OAuth tile reads as a self-contained option above
   * the credential form, not as a sibling button.
   *
   * NOTE: this only takes visible effect when the primary CTA is
   * in normal flex flow (no `margin-top: auto`).  Step 2 of the
   * signup flow uses `margin-top: auto` to anchor the primary at
   * the bottom of the cell — the auto-margin absorbs whatever
   * margin we set here, so the CSS in "Pinned primary action"
   * below explicitly drops the auto-margin override on step 1
   * to let this margin show through.
   */
  margin-bottom: 120px;
}

.auth-oauth-button:hover:not(:disabled) {
  background: rgba(40, 40, 56, 0.95);
  border-color: var(--auth-border-strong);
}

.auth-oauth-button:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.auth-oauth-button svg {
  width: 20px;
  height: 20px;
}

@media screen and (max-width: 767px) {
  .auth-oauth-button {
    height: 54px;
    font-size: 15px;
  }
}

/* ============================================================
 * Role tiles (signup step 0)
 *
 * Visual / motion parity with the in-app Flutter tiles in
 * lib/screens/.../signup_page.dart `_SignupRoleChoiceCell`:
 *
 *   - 16px corner radius, 2px border (constant width across all
 *     states so layout never shifts).
 *   - Idle / hover / selected fills lifted from `surfaceColor`
 *     at 62 / 78 / 82 % opacity.
 *   - Borders idle-white-10 → brand-48 → brand-88 across the
 *     same three states.
 *   - Three-shadow stack on hover (subtle purple halo + brand
 *     drop + soft black drop) and two-shadow stack on selected
 *     (outer glow ring + brand drop) — directly transcribed from
 *     the Flutter `BoxShadow` lists.
 *   - 220 ms easeOutCubic transition (`cubic-bezier(...)`)
 *     matching the Flutter `Curves.easeOutCubic`.
 *   - Label fades from 92 % → 98 % white on hover (subtle).
 * ============================================================ */

.auth-role-row {
  display: flex;
  gap: 16px;
  /* Mirrors Flutter `Padding.fromLTRB(0, 8, 0, 22)` in
     `_buildMinimalRoleOptions`: extra bottom space so the
     selected/hover glow shadows don't get clipped by whatever
     element follows the row.  */
  margin: 8px 0 22px;
  align-items: stretch;
}

.auth-role-tile {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 96px;
  padding: 24px 28px;
  background: rgba(26, 26, 37, 0.62);
  border: 2px solid var(--auth-border);
  border-radius: var(--auth-radius-tile);
  /* Match Flutter label opacity (white @ 92 %) for the idle
     state; hover/selected nudge to 98 %.  */
  color: rgba(255, 255, 255, 0.92);
  font-size: 15.5px;
  font-weight: 600;
  letter-spacing: 0.2px;
  line-height: 1.15;
  cursor: pointer;
  transition: background 220ms cubic-bezier(0.215, 0.61, 0.355, 1),
              border-color 220ms cubic-bezier(0.215, 0.61, 0.355, 1),
              box-shadow 220ms cubic-bezier(0.215, 0.61, 0.355, 1),
              color 220ms cubic-bezier(0.215, 0.61, 0.355, 1);
  text-align: center;
  font-family: inherit;
  /* Idle drop-shadow — mirrors Flutter idle BoxShadow
     (color: black @ 35%, blur: 10, offset: (0, 5)).  */
  box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.35);
}

.auth-role-tile:hover:not(.is-selected) {
  background: rgba(26, 26, 37, 0.78);
  border-color: var(--auth-brand-soft-48);
  color: rgba(255, 255, 255, 0.98);
  /* Three-shadow hover stack from Flutter:
       1. subtle purple halo (blur 26, spread 0.5)
       2. brand drop (blur 22, y 12, spread -2)
       3. soft black drop (blur 14, y 8)               */
  box-shadow: 0 0 26px 0.5px rgba(106, 76, 255, 0.22),
              0 12px 22px -2px rgba(106, 76, 255, 0.18),
              0 8px 14px 0 rgba(0, 0, 0, 0.4);
}

.auth-role-tile.is-selected {
  background: rgba(26, 26, 37, 0.82);
  border-color: rgba(106, 76, 255, 0.88);
  color: rgba(255, 255, 255, 0.98);
  /* Two-shadow selected stack from Flutter:
       1. soft outer glow ring (blur 28, spread 1)
       2. brand drop (blur 18, y 10)                   */
  box-shadow: 0 0 28px 1px rgba(106, 76, 255, 0.30),
              0 10px 18px 0 rgba(106, 76, 255, 0.22);
}

/* Tap state: dim slightly so a press registers visually (the
   Flutter version gets this for free from InkWell's
   highlight/splash; on the marketing pages we approximate it
   via a deeper background tone).  */
.auth-role-tile:active:not(.is-selected) {
  background: rgba(26, 26, 37, 0.86);
}

@media (prefers-reduced-motion: reduce) {
  .auth-role-tile {
    transition: none;
  }
}

@media screen and (max-width: 767px) {
  .auth-role-tile {
    min-height: 108px;
    padding: 28px 16px;
    font-size: 17px;
  }
}

/* ============================================================
 * Gender tiles (signup step 2 for athletes)
 * ============================================================ */

.auth-gender-row {
  display: flex;
  gap: 12px;
}

.auth-gender-tile {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 42px;
  background: rgba(26, 26, 37, 1);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 14px;
  color: rgba(255, 255, 255, 0.94);
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.18s ease, border-color 0.18s ease;
  /* Removes Webflow's tap-highlight glow on touch (matches the "no splash"
     change we already made on the in-app gender tiles). */
  -webkit-tap-highlight-color: transparent;
}

.auth-gender-tile:hover {
  border-color: rgba(255, 255, 255, 0.22);
}

.auth-gender-tile.is-selected {
  background: var(--auth-brand-soft-22);
  border-color: var(--auth-brand);
  border-width: 1.5px;
  font-weight: 600;
}

@media screen and (max-width: 767px) {
  .auth-gender-tile {
    height: 50px;
    font-size: 15px;
  }
}

/* ============================================================
 * Footer links (existing-account / forgot-password / etc.)
 * ============================================================ */

/*
 * Footer link (e.g. "Já tem uma conta? Entrar" on signup,
 * "Esqueci minha senha" / "Não tem uma conta? Criar" on login).
 *
 * Each footer link is a SINGLE anchor whose entire text is the
 * click target — much friendlier on touch devices than the old
 * "static text + tiny embedded `<a>`" pattern.  Inside that anchor
 * a `<span class="auth-footer-link-cta">` paints the call-to-
 * action word in brand purple while the surrounding copy stays in
 * the muted grey.
 *
 * Sized at 13 px on purpose — same scale as the legacy
 * `.auth-forgot-link a`, so the trailing pills read as quiet
 * secondary navigation rather than competing with the primary
 * "Entrar" / "Criar conta" CTA above them.
 *
 * `margin-top` is left at 0 because most steps already pin the
 * footer link via `position: absolute` — see the
 * "Pinned primary action" section below.
 */
.auth-footer-link {
  display: block;
  text-align: center;
  font-size: 13px;
  color: var(--auth-text-grey);
  text-decoration: none;
  margin-top: 0;
  transition: opacity 0.2s ease;
}

.auth-footer-link:hover,
.auth-footer-link:focus-visible {
  opacity: 0.85;
}

.auth-footer-link:link,
.auth-footer-link:visited,
.auth-footer-link:hover,
.auth-footer-link:active {
  color: var(--auth-text-grey);
}

.auth-footer-link-cta {
  color: var(--auth-brand);
  font-weight: 500;
}

/*
 * Legacy "div.auth-footer-link > a" pattern still in use a few
 * places; keep the brand-purple link styling working until those
 * markups are migrated to the single-anchor variant.
 */
.auth-footer-link a,
.auth-footer-link a:link,
.auth-footer-link a:visited,
.auth-footer-link a:hover,
.auth-footer-link a:active {
  color: var(--auth-brand);
  text-decoration: none;
  font-weight: 500;
  transition: opacity 0.2s ease;
}

.auth-footer-link a:hover {
  opacity: 0.85;
}

/*
 * Horizontal footer row — used on login.html to combine the
 * "Esqueci minha senha" link with the "Não tem uma conta? Criar"
 * link in a single line, separated by a thin vertical pipe.  The
 * legacy `.auth-forgot-link` slot below the password field is
 * empty in this layout so the bottom of the form ends with a
 * single, scannable navigation row.
 *
 * Each child anchor uses the standard `.auth-footer-link` styles
 * (block / 13 px / grey).  Inside this row we relax the `display:
 * block` to inline flow so both anchors sit side-by-side, and we
 * scale the click padding down a touch so the row reads as a
 * single phrase instead of two heavy buttons.
 */
.auth-footer-row {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0;
}

.auth-footer-row > .auth-footer-link {
  display: inline-block;
  margin: 0;
}

.auth-footer-row-sep {
  font-size: 13px;
  color: var(--auth-text-grey);
  /* Quiet pipe — it's just a visual divider, not a token the
     user needs to read.  Tone it down so neither link feels
     visually anchored to it.  */
  opacity: 0.55;
  user-select: none;
}

.auth-forgot-link {
  text-align: right;
  margin-top: -6px;
  margin-bottom: 4px;
}

.auth-forgot-link a {
  font-size: 13px;
  /* Subtle gray — the link is secondary; we don't want it pulling
     attention away from the primary "Entrar" call to action. */
  color: var(--auth-text-grey);
  text-decoration: none;
  transition: color 0.2s ease;
}

.auth-forgot-link a:hover {
  color: var(--auth-text-soft);
}

.auth-terms {
  text-align: center;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.5);
  line-height: 1.5;
  /* Margin handled by the parent flex `gap`, plus the `position:
     absolute` pinning on signup step 2 (see "Pinned primary
     action" below).  Leaving this at 0 avoids a stacked margin
     that would push the terms further from the primary CTA than
     the in-app version. */
  margin-top: 0;
}

/* ============================================================
 * Form-level message banner (global errors)
 * ============================================================ */

.auth-banner {
  display: none;
  padding: 14px 16px;
  background: rgba(239, 68, 68, 0.1);
  border: 1px solid rgba(239, 68, 68, 0.3);
  border-radius: 12px;
  color: var(--auth-error);
  font-size: 13.5px;
  line-height: 1.4;
  margin-top: 4px;
}

.auth-banner.is-visible {
  display: block;
}

/*
 * Success banner — shown on login.html after the user clicks the
 * email confirmation link.  We deliberately don't auto-log them in
 * (see boot() in login.html), so this strip is the only signal that
 * their click actually did something.
 */
.auth-success-banner {
  padding: 12px 16px;
  background: rgba(34, 197, 94, 0.08);
  border: 1px solid rgba(34, 197, 94, 0.32);
  border-radius: 12px;
  color: var(--auth-success);
  font-size: 13.5px;
  line-height: 1.4;
  margin-bottom: 4px;
}

.auth-success-banner[hidden] { display: none; }

/* ============================================================
 * Step container transitions (signup is multi-step)
 * ============================================================ */

/*
 * All step panes live in the same grid cell ("stack"), so each pane
 * occupies the full cell.  Inactive panes are visually hidden but
 * still take up space — that's how the form's height ends up matching
 * the tallest step regardless of which one is active.
 *
 * The `inert` attribute on inactive panes (toggled in signup.html JS)
 * removes them from focus traversal and screen-reader output, so even
 * though they're still in the DOM tree the user can't accidentally
 * tab into them.
 */
.auth-step {
  grid-area: stack;
  display: flex;
  flex-direction: column;
  gap: 16px;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}

.auth-step.is-active {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
  /* No fade between steps — the in-app Flutter signup swaps panes
     synchronously inside `setState`, with no transition tween,
     so the marketing flow does the same for parity.  The
     `auth-step-in` keyframes below are kept (unused) as a
     reference / opt-in for `prefers-reduced-motion` flips that
     might want a subtle 0ms fall-back later.  */
}

/*
 * Pinned primary action (signup steps 1 + 2)
 *
 * The user-visible brief: clicking "Continuar" on step 1 should
 * NOT make the next step's "Criar conta" button visually jump to a
 * different vertical position.  Both buttons need to land at the
 * EXACT same Y so the eye stays put across the transition.
 *
 * How: every step in the form shares the same grid cell (height =
 * tallest pane), so we can safely anchor the primary CTA to a
 * fixed offset from the bottom of the cell:
 *   - `position: relative` + `padding-bottom` on the step reserves
 *     a strip at the bottom for the trailing copy ("Já tem uma
 *     conta?" link / terms-of-use blurb).
 *   - The primary button gets `margin-top: auto`, which inside a
 *     flex column pushes it as far down as the inner content
 *     allows — i.e. against the reserved strip.  Both steps share
 *     the same reserved strip, so both buttons land at the same Y.
 *   - The trailing copy is taken out of flow with `position:
 *     absolute; bottom: 0`, so its line count (1 line vs. 2 lines)
 *     no longer affects where the primary button sits.
 */
.auth-step[data-step-pane="1"],
.auth-step[data-step-pane="2"] {
  position: relative;
  /* Tall enough for two-line terms (~36 px) + 16 px breathing
     room.  Trimmed values would overlap the trailing copy onto
     the primary CTA on narrow viewports.  */
  padding-bottom: 52px;
}

/*
 * Only step 2 anchors its primary via `margin-top: auto`.  Step 1
 * leaves the primary in normal flow so the explicit
 * `margin-bottom: 40` on the Google tile actually produces a
 * visible gap above the "Continuar" CTA — auto-margin would
 * otherwise absorb that 40 px and the Google→Continuar gap would
 * collapse back to whatever the cell-fill leftover happens to be.
 *
 * Buttons still align across steps because step 1's natural
 * stacked height (header + email + password + divider + google +
 * primary, with the new 40 px margin-bottom on google) ends up
 * matching the Y at which step 2's auto-margin lands the primary
 * — both bottom out at the same offset above the reserved
 * trailing-copy strip (`padding-bottom: 52`).
 */
.auth-step[data-step-pane="2"] > .auth-primary {
  margin-top: auto;
}

.auth-step[data-step-pane="1"] > .auth-footer-link {
  position: absolute;
  left: 0;
  right: 0;
  /* 14 px from the cell bottom keeps the 1-line "Já tem uma
     conta? Entrar" pill optically aligned with where the
     2-line terms blurb sits on step 2 (`bottom: 0`, ~36 px
     tall) — both end up the same distance below the primary
     CTA, which is what makes the buttons feel "anchored".  */
  bottom: 14px;
}

.auth-step[data-step-pane="2"] > .auth-terms {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
}

/* Athlete-only block in step 2 stacks birthdate + gender with the same
   16px rhythm as the rest of the form.  `is-hidden` is toggled by JS
   based on the selected role; we use a class instead of inline display
   so we don't fight the flex display in CSS. */
.auth-athlete-block {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.auth-athlete-block.is-hidden {
  display: none;
}

@keyframes auth-step-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ============================================================
 * Email confirmation modal (matches Flutter _showEmailConfirmDialog)
 * ============================================================ */

.auth-modal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: rgba(0, 0, 0, 0.55);
  align-items: center;
  justify-content: center;
  padding: 24px;
  animation: auth-modal-fade 0.18s ease-out;
}

.auth-modal.is-open {
  display: flex;
}

@keyframes auth-modal-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

.auth-modal-card {
  width: 100%;
  /* Tightened on desktop per the in-app dialog change ("decrease the max
     width of the dialog while keeping it friendly to different screen
     widths"). */
  max-width: 380px;
  background: #1a1a25;
  border: 1px solid rgba(106, 76, 255, 0.3);
  border-radius: 20px;
  padding: 28px 28px 22px;
  color: #ffffff;
  box-shadow: 0 24px 40px rgba(0, 0, 0, 0.4);
}

.auth-modal-title {
  font-size: 20px;
  font-weight: 700;
  color: #ffffff;
  margin: 0 0 14px 0;
  letter-spacing: -0.3px;
}

.auth-modal-body {
  color: var(--auth-text-grey);
  font-size: 14px;
  line-height: 1.6;
  margin-bottom: 22px;
}

.auth-modal-body strong {
  color: var(--auth-text-soft);
  font-weight: 600;
}

.auth-modal-body p {
  margin: 0 0 10px 0;
}

.auth-modal-body p:last-child {
  margin-bottom: 0;
}

.auth-modal-button {
  width: 100%;
  height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--auth-brand);
  color: #ffffff;
  border: none;
  border-radius: var(--auth-radius-button);
  font-size: 14.5px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: opacity 0.2s ease;
}

.auth-modal-button:hover {
  opacity: 0.92;
}

@media screen and (max-width: 767px) {
  .auth-modal-card {
    max-width: 100%;
    padding: 24px 22px 20px;
  }
  .auth-modal-button {
    height: 54px;
    font-size: 16px;
  }
}

/* ============================================================
 * Wheel date picker — iOS-style 3-column scroller
 *
 * Matches lib/screens/.../signup_page.dart `_pickAthleteBirthdate`,
 * which renders a CupertinoDatePicker on mobile and a Cupertino
 * picker inside a dialog on desktop.  We translate that to a
 * single responsive overlay: full-width sheet on phones, centered
 * card on wider viewports.
 *
 * Each column is a vertical scroll container with `scroll-snap-type:
 * y mandatory` so the closest item always lands centered.  The
 * highlighted "selection band" is a fixed strip in the middle of
 * the picker that visually marks which row will be returned.
 * ============================================================ */

.auth-wheel-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  animation: auth-modal-fade 0.18s ease-out;
}

.auth-wheel-card {
  width: 100%;
  max-width: 360px;
  background: #1a1a25;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 24px 40px rgba(0, 0, 0, 0.4);
}

.auth-wheel-header {
  display: grid;
  grid-template-columns: 56px 1fr 56px;
  align-items: center;
  padding: 8px 4px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.auth-wheel-title {
  font-size: 13.5px;
  font-weight: 600;
  text-align: center;
  color: rgba(255, 255, 255, 0.92);
  letter-spacing: 0.1px;
}

.auth-wheel-ok,
.auth-wheel-ok:link,
.auth-wheel-ok:visited,
.auth-wheel-ok:hover,
.auth-wheel-ok:active {
  background: none;
  border: none;
  padding: 8px 14px;
  font: inherit;
  font-size: 14.5px;
  font-weight: 600;
  /* Same swatch as the primary signup/login CTA above the Google
     button — keeps "OK" reading as the affirmative action. */
  color: var(--auth-brand);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity 0.2s ease;
}

.auth-wheel-ok:hover { opacity: 0.85; }

.auth-wheel-body {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1.1fr 1.1fr;
  height: 220px;
  overflow: hidden;
}

/* The selection band: a horizontal strip in the middle of the body,
   one item-height tall, with hairline borders top and bottom — same
   visual cue Cupertino uses to indicate "this row is the value". */
.auth-wheel-band {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 36px;
  pointer-events: none;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

.auth-wheel-column {
  height: 100%;
  overflow-y: scroll;
  overflow-x: hidden;
  scroll-snap-type: y mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  text-align: center;
  /* Signal to desktop users that they can grab and drag the column.
     Touch gets the native scroll-snap flick, so the cursor only
     matters on mouse/pen pointers — see `wireWheelDrag` in
     auth-helpers.js. */
  cursor: grab;
  /* Don't let the browser jump the page on touch-drag — the column
     handles scrolling internally. */
  touch-action: pan-y;
}

.auth-wheel-column:active {
  cursor: grabbing;
}

.auth-wheel-column::-webkit-scrollbar { display: none; }

/* Top + bottom spacers ensure the FIRST and LAST items can be
   scrolled into the centered selection band (otherwise they'd be
   stuck at the top/bottom of the column and never "selectable"). */
.auth-wheel-spacer {
  height: 92px; /* (220 column height - 36 item height) / 2 */
  pointer-events: none;
}

.auth-wheel-item {
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  scroll-snap-align: center;
  font-size: 21px;
  font-weight: 400;
  color: rgba(255, 255, 255, 0.55);
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.18s ease;
  font-variant-numeric: tabular-nums;
}

/* Column is currently centered on this row — paint it brighter
   so it visually matches what the OK button will return. */
.auth-wheel-item.is-selected {
  color: rgba(255, 255, 255, 0.96);
  font-weight: 500;
}

@media screen and (max-width: 767px) {
  .auth-wheel-card {
    max-width: 100%;
  }
  .auth-wheel-body {
    height: 240px;
  }
  .auth-wheel-spacer {
    height: 102px; /* (240 - 36) / 2 */
  }
  .auth-wheel-ok {
    height: 44px;
    font-size: 16px;
  }
}

/* ============================================================
 * Mobile tweaks
 * ============================================================ */

@media screen and (max-width: 767px) {
  .auth-section {
    padding-top: 48px;
    /* Match desktop bottom-padding behaviour: keep the gap below
       the primary CTA snug (matches Flutter's `spacingL`) so the
       last step doesn't float in a sea of empty space.  */
    padding-bottom: 28px;
  }
  .auth-card {
    padding: 12px 24px 40px;
    border-radius: 0;
  }
  .auth-title {
    font-size: 32px;
    line-height: 1.1;
    letter-spacing: -0.55px;
  }
  .auth-step--welcome .auth-title {
    font-size: 30px;
  }
}

/* ── Small phone (≤ 390px: iPhone SE, Galaxy A-series) ───── */

@media screen and (max-width: 390px) {
  /* Slightly tighter card padding so form fields don't feel cramped */
  .auth-card {
    padding-left: 16px;
    padding-right: 16px;
  }

  /* Headline scales to viewport on smallest screens */
  .auth-title {
    font-size: 28px;
    letter-spacing: -0.4px;
  }

  .auth-step--welcome .auth-title {
    font-size: 26px;
  }

  /* Input height: 48px is slightly more comfortable on small touch screens */
  .auth-input {
    height: 48px;
    font-size: 15px;
  }

  /* Primary CTA button: same height as input for visual harmony */
  .auth-primary {
    height: 50px;
    font-size: 15px;
  }

  /* OAuth Google button: match CTA height */
  .auth-oauth-button {
    height: 50px;
    font-size: 14px;
  }
}
