/* ================================================================ */
/*  SPROUT LEARNING — BUTTON COMPONENTS                              */
/*  Version: 1.0                                                     */
/*  Consumes: sprout-tokens-handoff-darkmode.css v2.4                */
/*  Scope: Public marketing site (Parent-area typography/touch       */
/*  targets — --touch-target-adult-*, per token file §3.8 which      */
/*  explicitly scopes this file's consumer to the adult values).     */
/* ================================================================ */
/*
  READ THIS FIRST — 3 decisions made while building this, flagged
  per MasterContext §14 ("make assumptions explicit"):

  1. HYBRID CTA COLOR RULE (per founder decision, WordPress/Blocksy
     integration work): hero/high-visibility CTAs use the 500-weight
     vibrant fill (--jade-500 / --coral-500) with DARK text; every
     other button stays on the 700-weight fill with white text,
     exactly as the token file's existing --button-*-bg tokens
     already define. This file does NOT invent a third color scale —
     it just adds a --btn-hero variant on top of the existing
     --jade-500 / --coral-500 primitives.

     CONTRAST CAVEAT: token file only pre-verifies jade-700 (white
     text, 6.52:1) and coral-700 (white text, 5.0:1). jade-500 /
     coral-500 + ink-900 dark text is NOT pre-verified anywhere in
     the token file — --color-primary-decorative's own comment just
     says "pair with dark text if labeled," not that it clears any
     specific ratio. Run this pairing through a contrast checker
     before shipping; I did not fabricate a ratio for it.

  2. --ease-playful IS DELIBERATELY NOT USED HERE. The token file
     reserves it for reward moments and explicitly excludes it from
     "parent-area UI (Report, Settings, Billing)." This marketing
     site's audience is parents, not the child in-app experience —
     so hover/press motion below uses --ease-standard / --ease-out,
     not the bounce curve. If you want the bounce specifically on
     the hero CTA as a brand-personality flourish, that's a call to
     make deliberately, not inherit by default — flagging rather
     than deciding it for you.

  3. DARK-MODE PATCH: the token file's own v2.2 changelog flags that
     Section 3 button tokens reference primitives directly (e.g.
     var(--jade-700)) instead of the semantic layer, so dark mode
     doesn't apply to buttons automatically, and recommends
     repointing them. Rather than silently duplicating a full second
     token set, I implemented that exact recommended fix as a small
     override block (§6 below) — only the 3 fills the token file
     already identified as failing 3:1 on dark navy (Jade, Lavender,
     Crimson) get patched; Coral and Meadow are left alone because
     the token file says they already clear 3:1 unchanged.
*/


/* ================================================================ */
/* 0. USAGE                                                          */
/* ================================================================ */
/*
  <button class="btn btn-primary">Start Playing</button>
  <a class="btn btn-hero" href="/signup">Start Your Free Trial</a>
  <a class="btn btn-hero-secondary" href="/how-it-works">See How It Works</a>
  <button class="btn btn-outline-primary btn-sm">Learn More</button>
  <button class="btn btn-ghost">Cancel</button>
  <button class="btn btn-danger" data-loading="true">Delete Profile</button>
  <button class="btn btn-icon btn-ghost" aria-label="Close"><svg>...</svg></button>

  Size modifiers (.btn-sm / .btn-lg) and color modifiers (.btn-primary,
  .btn-outline-primary, etc.) are independent — combine freely. Only
  .btn-hero / .btn-hero-secondary bundle size + color together, because
  the hybrid-CTA rule ties a specific size tier to a specific fill.
*/


/* ================================================================ */
/* 1. BASE                                                           */
/* ================================================================ */
.btn {
  /* Reset */
  appearance: none;
  border: none;
  margin: 0;
  text-decoration: none;
  background: none;
  font: inherit;

  /* Layout */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  white-space: nowrap;
  user-select: none;
  cursor: pointer;
  vertical-align: middle;

  /* Type */
  font-family: var(--font-body);
  font-size: var(--text-body-lg-size);
  font-weight: var(--text-body-lg-weight-medium);
  line-height: 1;
  letter-spacing: var(--text-body-lg-tracking);
  color: var(--button-primary-text);

  /* Shape & sizing — md is the implicit default size */
  padding: var(--space-sm) var(--space-lg);
  min-height: var(--touch-target-adult-min);
  border-radius: var(--radius-md);

  /* Motion — see note 2 above on why not --ease-playful */
  transition:
    background-color var(--duration-standard) var(--ease-standard),
    border-color var(--duration-standard) var(--ease-standard),
    color var(--duration-standard) var(--ease-standard),
    transform var(--duration-fast) var(--ease-out),
    box-shadow var(--duration-fast) var(--ease-standard);
}

/* Keyboard focus — token file marks this "required on all
   interactive elements." Deliberately :focus-visible, not :focus,
   so mouse/touch clicks don't show a ring that's only meant for
   keyboard and switch-device navigation. */
.btn:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: var(--focus-ring-offset);
}

.btn:disabled,
.btn[aria-disabled="true"] {
  cursor: not-allowed;
  transform: none !important;
  box-shadow: none !important;
}

/* Reduced motion — the token file's global media query already
   zeroes --duration-standard/--scale-press etc. This just makes
   sure the hover "lift" (a translateY, not covered by --scale-press)
   also drops out, since lift is this file's addition, not a token. */
@media (prefers-reduced-motion: reduce) {
  .btn:hover,
  .btn:active {
    transform: none !important;
  }
}


/* ================================================================ */
/* 2. SOLID FILLS                                                    */
/*  Each variant = a chunky "pressable" button: a flat offset shadow */
/*  that collapses and the button drops by the same distance on      */
/*  press, using each color's existing --shadow-btn-* token. This    */
/*  matches ChildCharacterGuide §9's "soft, friendly, alive" motion   */
/*  requirement without borrowing the reward-only bounce curve.      */
/* ================================================================ */

.btn-primary {
  background-color: var(--button-primary-bg);
  color: var(--button-primary-text);
  box-shadow: var(--button-primary-shadow);
}
.btn-primary:hover:not(:disabled) { background-color: var(--button-primary-bg-hover); transform: translateY(-2px); color: var(--ink-900); }
.btn-primary:active:not(:disabled) { background-color: var(--button-primary-bg-active); transform: translateY(3px); color: var(--ink-0); box-shadow: none; }
.btn-primary:disabled { background-color: var(--button-primary-bg-disabled); color: var(--button-primary-text-disabled); }

.btn-secondary {
  background-color: var(--button-secondary-bg);
  color: var(--button-secondary-text);
  box-shadow: var(--button-secondary-shadow);
}
.btn-secondary:hover:not(:disabled) { background-color: var(--button-secondary-bg-hover); transform: translateY(-1px); }
.btn-secondary:active:not(:disabled) { background-color: var(--button-secondary-bg-active); transform: translateY(3px); box-shadow: none; }
.btn-secondary:disabled { background-color: var(--button-secondary-bg-disabled); color: var(--ink-0); opacity: .6; }

.btn-accent {
  /* Gold — celebratory/reward actions only ("Claim reward"), per
     component-token comment. Don't reach for this as a general CTA. */
  background-color: var(--button-accent-bg);
  color: var(--button-accent-text);
  box-shadow: var(--button-accent-shadow);
}
.btn-accent:hover:not(:disabled) { background-color: var(--button-accent-bg-hover); transform: translateY(-1px); }
.btn-accent:active:not(:disabled) { background-color: var(--button-accent-bg-active); transform: translateY(3px); box-shadow: none; }
.btn-accent:disabled { background-color: var(--button-accent-bg-disabled); color: var(--button-primary-text-disabled); }

.btn-success {
  /* Confirmations only ("Continue" after a correct answer) — not a
     general-purpose green CTA (that's --btn-primary/Jade). */
  background-color: var(--button-success-bg);
  color: var(--button-success-text);
  box-shadow: var(--button-success-shadow);
}
.btn-success:hover:not(:disabled) { background-color: var(--meadow-800); transform: translateY(-1px); }
.btn-success:active:not(:disabled) { background-color: var(--button-success-bg-active); transform: translateY(3px); box-shadow: none; }
.btn-success:disabled { background-color: var(--ink-200); color: var(--ink-400); }

.btn-danger {
  /* Destructive actions — delete account, remove child profile. */
  background-color: var(--button-danger-bg);
  color: var(--button-danger-text);
  box-shadow: var(--button-danger-shadow);
}
.btn-danger:hover:not(:disabled) { background-color: var(--button-danger-bg-hover); transform: translateY(-1px); }
.btn-danger:active:not(:disabled) { background-color: var(--button-danger-bg-active); transform: translateY(3px); box-shadow: none; }
.btn-danger:disabled { background-color: var(--ink-200); color: var(--ink-400); }

.btn-creative {
  /* Lavender — storytelling/creativity contexts ("Start a Story").
     Keep rare, per the token file's own 4%-of-UI budget (§8). */
  background-color: var(--color-creative);
  color: var(--color-on-creative);
  box-shadow: var(--shadow-btn-creative);
}
.btn-creative:hover:not(:disabled) { background-color: var(--lavender-800); transform: translateY(-1px); }
.btn-creative:active:not(:disabled) { background-color: var(--lavender-900); transform: translateY(3px); box-shadow: none; }
.btn-creative:disabled { background-color: var(--ink-200); color: var(--ink-400); }


/* ================================================================ */
/* 3. OUTLINE VARIANTS                                               */
/*  Secondary-weight actions that still need brand color — e.g. a    */
/*  card's "Learn more" next to a section's one primary CTA.         */
/* ================================================================ */

.btn-outline-primary {
  background-color: transparent;
  color: var(--color-primary);
  border: 2px solid var(--color-primary);
  box-shadow: none;
  padding: calc(var(--space-sm) - 2px) calc(var(--space-lg) - 2px);
}
.btn-outline-primary:hover:not(:disabled) { background-color: var(--color-primary-subtle); }
.btn-outline-primary:active:not(:disabled) { background-color: var(--jade-200); }
.btn-outline-primary:disabled { color: var(--ink-400); border-color: var(--ink-200); }

.btn-outline-secondary {
  background-color: transparent;
  color: var(--color-secondary);
  border: 2px solid var(--color-secondary);
  box-shadow: none;
  padding: calc(var(--space-sm) - 2px) calc(var(--space-lg) - 2px);
}
.btn-outline-secondary:hover:not(:disabled) { background-color: var(--color-secondary-subtle); }
.btn-outline-secondary:active:not(:disabled) { background-color: var(--coral-200); }
.btn-outline-secondary:disabled { color: var(--ink-400); border-color: var(--ink-200); }

.btn-outline-creative {
  background-color: transparent;
  color: var(--color-creative);
  border: 2px solid var(--color-creative);
  box-shadow: none;
  padding: calc(var(--space-sm) - 2px) calc(var(--space-lg) - 2px);
}
.btn-outline-creative:hover:not(:disabled) { background-color: var(--color-creative-subtle); }
.btn-outline-creative:active:not(:disabled) { background-color: var(--lavender-200); }
.btn-outline-creative:disabled { color: var(--ink-400); border-color: var(--ink-200); }

.btn-outline-danger {
  background-color: transparent;
  color: var(--color-error-strong);
  border: 2px solid var(--color-error-strong);
  box-shadow: none;
  padding: calc(var(--space-sm) - 2px) calc(var(--space-lg) - 2px);
}
.btn-outline-danger:hover:not(:disabled) { background-color: var(--color-error-subtle); }
.btn-outline-danger:active:not(:disabled) { background-color: var(--crimson-200); }
.btn-outline-danger:disabled { color: var(--ink-400); border-color: var(--ink-200); }


/* ================================================================ */
/* 4. GHOST & LINK                                                   */
/*  Lowest-emphasis actions — "Cancel," nav items, inline text CTAs. */
/* ================================================================ */

.btn-ghost {
  background-color: var(--button-ghost-bg);
  color: var(--button-ghost-text);
  border: 2px solid var(--button-ghost-border);
  box-shadow: none;
  padding: calc(var(--space-sm) - 2px) calc(var(--space-lg) - 2px);
}
.btn-ghost:hover:not(:disabled) { background-color: var(--button-ghost-bg-hover); }
.btn-ghost:active:not(:disabled) { background-color: var(--ink-200); }
.btn-ghost:disabled { color: var(--button-ghost-text-disabled); border-color: var(--color-border); }

.btn-link {
  /* Not a "button" visually at all — inline text acting as a CTA.
     Still gets .btn's focus ring and touch target via padding, so
     it stays keyboard- and thumb-accessible despite looking like text. */
  background-color: transparent;
  color: var(--link-text);
  padding: var(--space-2xs) var(--space-2xs);
  min-height: auto;
  text-decoration: underline;
  text-underline-offset: 3px;
  box-shadow: none;
  font-weight: var(--text-body-lg-weight-medium);
}
.btn-link:hover:not(:disabled) { color: var(--link-text-hover); }
.btn-link:active:not(:disabled) { transform: none; }
.btn-link:disabled { color: var(--ink-400); text-decoration: none; }


/* ================================================================ */
/* 5. HERO / HYBRID-CTA VARIANTS                                     */
/*  500-weight vibrant fill + dark text, per the hybrid CTA color    */
/*  decision (see note 1 at top). Reserve for ONE primary hero       */
/*  action per view — this is deliberately the loudest button in     */
/*  the system, not a size upgrade of .btn-primary.                  */
/* ================================================================ */

.btn-hero,
.btn-hero-secondary {
  padding: var(--space-md) var(--space-2xl);
  min-height: 56px;
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-size: var(--text-display-sm-size);
  font-weight: var(--text-display-sm-weight);
  letter-spacing: var(--text-display-sm-tracking);
}

.btn-hero {
  background-color: var(--jade-500);
  color: var(--ink-900);
  box-shadow: var(--shadow-btn-primary); /* grounding shadow stays on the darkest step for legibility regardless of fill lightness */
}
.btn-hero:hover:not(:disabled) { background-color: var(--jade-400); transform: translateY(-2px); }
.btn-hero:active:not(:disabled) { background-color: var(--jade-300); transform: translateY(3px); box-shadow: none; }
.btn-hero:disabled { background-color: var(--ink-200); color: var(--ink-400); box-shadow: none; }

.btn-hero-secondary {
  background-color: var(--coral-500);
  color: var(--ink-900);
  box-shadow: var(--shadow-btn-secondary);
}
.btn-hero-secondary:hover:not(:disabled) { background-color: var(--coral-400); transform: translateY(-2px); }
.btn-hero-secondary:active:not(:disabled) { background-color: var(--coral-300); transform: translateY(3px); box-shadow: none; }
.btn-hero-secondary:disabled { background-color: var(--ink-200); color: var(--ink-400); box-shadow: none; }


/* ================================================================ */
/* 6. DARK MODE PATCH                                                */
/*  Implements the fix the token file's v2.2 note recommends (see    */
/*  note 3 at top). Only Primary, Creative, and Danger need it —     */
/*  Secondary/Accent/Success/Warning/Info are already dark-mode-safe */
/*  per the token file's own contrast notes in §3.5.                 */
/* ================================================================ */
:root[data-theme="dark"] {
  --button-primary-bg:          var(--jade-600);
  --button-primary-bg-hover:    var(--jade-700);
  --button-primary-bg-active:   var(--jade-800);

  --shadow-btn-creative: 0 3px 0 rgba(0, 0, 0, 0.45);
}

:root[data-theme="dark"] .btn-primary,
:root[data-theme="dark"] .btn-danger,
:root[data-theme="dark"] .btn-creative,
:root[data-theme="dark"] .btn-accent,
:root[data-theme="dark"] .btn-secondary,
:root[data-theme="dark"] .btn-success,
:root[data-theme="dark"] .btn-hero,
:root[data-theme="dark"] .btn-hero-secondary {
  /* Flat primitive-based shadows (jade-900, lavender-900, etc.) go
     visually muddy against the dark navy page — same root cause the
     token file names for text/fill contrast. Swap every button's
     "pressed" shadow to a neutral dark shadow instead of trying to
     re-tune each color's shadow step individually. */
  box-shadow: 0 3px 0 rgba(0, 0, 0, 0.45);
}
:root[data-theme="dark"] .btn-primary:active:not(:disabled),
:root[data-theme="dark"] .btn-danger:active:not(:disabled),
:root[data-theme="dark"] .btn-creative:active:not(:disabled),
:root[data-theme="dark"] .btn-accent:active:not(:disabled),
:root[data-theme="dark"] .btn-secondary:active:not(:disabled),
:root[data-theme="dark"] .btn-success:active:not(:disabled),
:root[data-theme="dark"] .btn-hero:active:not(:disabled),
:root[data-theme="dark"] .btn-hero-secondary:active:not(:disabled) {
  box-shadow: none;
}

:root[data-theme="dark"] .btn-creative {
  background-color: var(--lavender-600);
}
:root[data-theme="dark"] .btn-creative:hover:not(:disabled) { background-color: var(--lavender-700); }
:root[data-theme="dark"] .btn-creative:active:not(:disabled) { background-color: var(--lavender-800); }

:root[data-theme="dark"] .btn-danger {
  background-color: var(--crimson-600);
}
:root[data-theme="dark"] .btn-danger:hover:not(:disabled) { background-color: var(--crimson-700); }
:root[data-theme="dark"] .btn-danger:active:not(:disabled) { background-color: var(--crimson-800); }

:root[data-theme="dark"] .btn-outline-danger {
  color: var(--crimson-400);
  border-color: var(--crimson-400);
}


/* ================================================================ */
/* 7. SIZE MODIFIERS                                                 */
/*  Combine with any color variant above: .btn.btn-primary.btn-sm    */
/* ================================================================ */

.btn-sm {
  padding: var(--space-xs) var(--space-md);
  min-height: 36px;
  font-size: var(--text-body-md-size);
  border-radius: var(--radius-sm);
}
/* Outline/ghost variants carry a 2px border already accounted for
   in their own padding formula — override that formula at this size. */
.btn-outline-primary.btn-sm,
.btn-outline-secondary.btn-sm,
.btn-outline-creative.btn-sm,
.btn-outline-danger.btn-sm,
.btn-ghost.btn-sm {
  padding: calc(var(--space-xs) - 2px) calc(var(--space-md) - 2px);
}

.btn-lg {
  padding: var(--space-md) var(--space-xl);
  min-height: 52px;
  font-size: var(--text-body-lg-size);
}
.btn-outline-primary.btn-lg,
.btn-outline-secondary.btn-lg,
.btn-outline-creative.btn-lg,
.btn-outline-danger.btn-lg,
.btn-ghost.btn-lg {
  padding: calc(var(--space-md) - 2px) calc(var(--space-xl) - 2px);
}


/* ================================================================ */
/* 8. ICON SUPPORT                                                   */
/* ================================================================ */

.btn svg {
  width: 1.1em;
  height: 1.1em;
  flex-shrink: 0;
}

/* Icon-only — square, centered, still meets the 44px adult touch
   target. Always pair with aria-label in markup; this class has no
   opinion on accessible naming, that's the button's job. */
.btn-icon {
  padding: 0;
  width: var(--touch-target-adult-min);
  height: var(--touch-target-adult-min);
  border-radius: var(--radius-pill);
}
.btn-icon.btn-sm { width: 36px; height: 36px; }
.btn-icon.btn-lg { width: 52px; height: 52px; }


/* ================================================================ */
/* 9. LOADING STATE                                                  */
/*  Toggle via [data-loading="true"] on any .btn. Hides label text   */
/*  (keeps it in the accessibility tree via visually-hidden, not     */
/*  display:none) and shows a spinner sized to the current font.     */
/* ================================================================ */

.btn[data-loading="true"] {
  color: transparent !important;
  pointer-events: none;
  position: relative;
}
.btn[data-loading="true"]::after {
  content: "";
  position: absolute;
  width: 1.1em;
  height: 1.1em;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  color: var(--button-primary-text);
  animation: btn-spin 700ms linear infinite;
}
.btn-outline-primary[data-loading="true"]::after,
.btn-outline-secondary[data-loading="true"]::after,
.btn-outline-creative[data-loading="true"]::after,
.btn-outline-danger[data-loading="true"]::after,
.btn-ghost[data-loading="true"]::after,
.btn-link[data-loading="true"]::after,
.btn-hero[data-loading="true"]::after,
.btn-hero-secondary[data-loading="true"]::after {
  color: var(--ink-900);
}

@keyframes btn-spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .btn[data-loading="true"]::after {
    animation-duration: 1400ms; /* keep it a visible status indicator, just slower — spinners are exempt from full motion removal since they communicate state, not decoration */
  }
}
