/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */

/* Base body font stack, used on every page */
body {
  font-family: "Inter var", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}

/* Required field indicator */
label.required::after {
  content: " *";
  color: #ef4444;
}

/* Nav shake, e.g. to draw attention to an invalid/blocked action */
@keyframes shake {
  0% { transform: translateX(0); }
  25% { transform: translateX(-5px) rotate(-5deg); }
  50% { transform: translateX(5px) rotate(5deg); }
  75% { transform: translateX(-5px) rotate(-5deg); }
  100% { transform: translateX(0); }
}
.shake {
  animation: shake 0.5s ease-in-out;
}

/* Submit button spinner */
@keyframes btn-spin {
  to {
    transform: rotate(360deg);
  }
}
.btn-spinner {
  animation: btn-spin 0.75s linear infinite;
}

/* One-shot entrance animation - same technique as the submission "received"
   and account "welcome" pages (fade-up reveal + a short accent line drawing
   in under the heading), reused here so the wizard's own step badges match
   that same quality bar instead of a busier, continuously-looping icon. */
@keyframes fade-up-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
@keyframes line-draw-in {
  from {
    opacity: 0;
    transform: scaleX(0);
    transform-origin: left;
  }
  to {
    opacity: 1;
    transform: scaleX(1);
    transform-origin: left;
  }
}
.wizard-illustration-badge {
  animation: fade-up-in 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.wizard-hero-line {
  animation: line-draw-in 0.45s cubic-bezier(0.22, 1, 0.36, 1) 0.15s both;
}

/* Same fade-up entrance as the wizard badges, reused for /news rows so each
   article settles in on load/page change instead of popping in instantly.
   Rows carry a small animation-delay (capped at 6 steps) for a gentle stagger. */
.news-item-in {
  animation: fade-up-in 0.4s cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* Generic page-entrance pair, reused by every simple confirmation/status page
   (sign-in, sign-up, email-sent, magic-link-sent, received, rewards) instead
   of each page redefining its own identically-shaped keyframe/class. */
.page-fade-up {
  animation: fade-up-in 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.page-hero-line {
  animation: line-draw-in 0.45s cubic-bezier(0.22, 1, 0.36, 1) 0.15s both;
}

@media (prefers-reduced-motion: reduce) {
  .wizard-illustration-badge,
  .wizard-hero-line,
  .news-item-in,
  .page-fade-up,
  .page-hero-line {
    animation: none;
  }
}

/* Shared with account/api_settings/show and static/api - both pages used an
   identical keyframe/class under this same name already. */
@keyframes api-settings-fade-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
.api-settings-fade-in {
  animation: api-settings-fade-in 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
}
@media (prefers-reduced-motion: reduce) {
  .api-settings-fade-in { animation: none; }
}

/* Small (6px) hero/detail fade-in, shared by agents/show and services/show -
   each page keeps its own class names (they stagger different numbers of
   sections) but both animate via this one keyframe instead of duplicating it. */
@keyframes fade-in-up-xs {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Checkout-success checkmark: shared verbatim by feature_now_success,
   submission_success, and feature_success - see the design skill's
   "animated success checkmark" section. */
@keyframes success-scale-in {
  from { opacity: 0; transform: scale(0.85); }
  to   { opacity: 1; transform: scale(1); }
}
@keyframes checkmark-draw {
  0%   { stroke-dashoffset: 24; }
  100% { stroke-dashoffset: 0; }
}
@keyframes circle-draw {
  0%   { stroke-dashoffset: 63; }
  100% { stroke-dashoffset: 0; }
}
.success-card {
  animation: success-scale-in 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
.success-checkmark-circle {
  stroke-dasharray: 63;
  animation: circle-draw 0.4s ease-out 0.1s forwards;
  stroke-dashoffset: 63;
}
.success-checkmark-tick {
  stroke-dasharray: 24;
  animation: checkmark-draw 0.35s ease-out 0.35s forwards;
  stroke-dashoffset: 24;
}
@media (prefers-reduced-motion: reduce) {
  .success-card {
    animation: none;
  }
  .success-checkmark-circle,
  .success-checkmark-tick {
    animation: none;
    stroke-dashoffset: 0;
  }
}

/* Shine animation for text */
@keyframes shine {
  0% {
    background-position: -200% center;
  }
  100% {
    background-position: 200% center;
  }
}

.shine-text {
  color: var(--page-text);
  background-color: transparent;
  background-image: linear-gradient(
    270deg,
    transparent 0%,
    transparent 40%,
    var(--agent-shine) 50%,
    transparent 60%,
    transparent 100%
  );
  background-size: 200% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  animation: shine 10s ease-in-out;
}

/* Patron card title: a shine band sweeps across text that is otherwise painted in
   --page-text, so contrast never drops below the base color by much.
   Rests for most of the cycle, then sweeps. The gradient is 250% of the element so
   every glyph always has background to clip; the position stays within 0%-100% for
   the same reason. Outside that range the text would have no fill and vanish. */
@keyframes patron-title-shine {
  0%,
  60% {
    background-position: 0% center;
  }
  100% {
    background-position: 100% center;
  }
}

.patron-shine-text {
  color: var(--page-text);
  /* The gradient is sized to the element box, not the glyphs. Without this a short
     title in a full-width h3 would send the band across mostly empty space. */
  width: fit-content;
  max-width: 100%;
}

@supports (background-clip: text) or (-webkit-background-clip: text) {
  .patron-shine-text {
    background-image: linear-gradient(
      100deg,
      var(--page-text) 0%,
      var(--page-text) 28%,
      var(--patron-shine) 50%,
      var(--page-text) 72%,
      var(--page-text) 100%
    );
    background-size: 250% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: patron-title-shine 6s ease-in-out infinite;
  }
}

@media (prefers-reduced-motion: reduce) {
  .patron-shine-text {
    background-image: none;
    -webkit-text-fill-color: var(--page-text);
    animation: none;
  }
}
