@tailwind base;
@tailwind components;
@tailwind utilities;

/* Flag emoji polyfill — Windows has no glyphs for regional-indicator flags, so
   they fall back to country letters. This locally-bundled Twemoji flag font is
   scoped via unicode-range to ONLY flag codepoints, so adding it to the front
   of the font stacks fixes every flag everywhere without touching any markup
   and without affecting any other text. Root fix, not a per-component wrap. */
@font-face {
  font-family: "Twemoji Country Flags";
  unicode-range: U+1F1E6-1F1FF, U+1F3F4, U+E0062-E007F;
  src: url("/fonts/TwemojiCountryFlags.woff2") format("woff2");
  font-display: swap;
}

/* Animated gradient border — @property enables CSS-only angle animation */
@property --border-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

.hover-border-gradient {
  --_bg: var(--border-inner-bg, rgb(var(--color-dark-900)));
  --_accent: var(--accent-color, rgb(var(--color-accent-400)));
  border: 1.5px solid transparent;
  background:
    linear-gradient(var(--_bg), var(--_bg)) padding-box,
    conic-gradient(
      from var(--border-angle),
      var(--_accent) 0%,
      transparent 25%,
      transparent 75%,
      var(--_accent) 100%
    )
    border-box;
  animation: border-rotate var(--border-duration, 3s) linear infinite;
}

.hover-border-gradient {
  transition: box-shadow 0.3s ease;
}

.hover-border-gradient:hover,
.hover-border-gradient:active {
  box-shadow: 0 0 20px var(--accent-glow, rgba(var(--color-accent-400), 0.25));
}

.hover-border-gradient:disabled,
.hover-border-gradient[disabled] {
  box-shadow: none;
  pointer-events: auto;
}

.light .hover-border-gradient {
  --_bg: var(--border-inner-bg, rgb(var(--color-champagne-100)));
}

@media (prefers-reduced-motion: reduce) {
  .hover-border-gradient {
    animation-play-state: paused;
  }
}

/* Global reduced-motion defence — collapses every animation and transition
   to ~0ms so users with vestibular disorders, motion sensitivity, or just
   the OS-level preference set get instant state changes. State-conveying
   motion still arrives at its final frame; only the journey is skipped.
   Specific rules above (animation-play-state: paused, animation: none)
   stay as documentation of intent — this rule subsumes them via !important.
   WCAG 2.3.3 (Animation from Interactions). */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

@keyframes border-rotate {
  to {
    --border-angle: 360deg;
  }
}

/* Aceternity UI background CSS variables */
:root {
  --blue-500: #3b82f6;
  --indigo-300: #a5b4fc;
  --blue-300: #93c5fd;
  --violet-200: #ddd6fe;
  --blue-400: #60a5fa;
  --black: #000000;
  --white: #ffffff;
}

@layer base {
  :root {
    --safe-area-inset-bottom: env(safe-area-inset-bottom, 0px);

    /* Unified Card System */
    --bento-radius: 16px;
    --bento-radius-lg: 20px;
    --bento-gap: 16px;
    --bento-gap-lg: 24px;
    --bento-padding: 20px;
    --bento-padding-lg: 24px;

    /* Linear Design Tokens */
    --linear-radius: 8px;
    --linear-radius-lg: 12px;
    --linear-blur: 12px;
    --linear-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
    --linear-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
    --linear-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);

    /* Border radius scale (used by user preferences) */
    --radius-none: 0px;
    --radius-small: 8px;
    --radius-medium: 16px;
    --radius-large: 24px;
    --radius-pill: 9999px;

    /* Spacing scale */
    --spacing-compact: 12px;
    --spacing-comfortable: 16px;
    --spacing-spacious: 24px;

    /* Theme colors - RGB format for opacity support */
    /* Dark palette (RGB values) */
    --color-dark-50: 248, 250, 252;
    --color-dark-100: 241, 245, 249;
    --color-dark-200: 226, 232, 240;
    --color-dark-300: 203, 213, 225;
    --color-dark-400: 148, 163, 184;
    --color-dark-500: 100, 116, 139;
    --color-dark-600: 71, 85, 105;
    --color-dark-700: 51, 65, 85;
    --color-dark-800: 30, 41, 59;
    --color-dark-850: 23, 32, 51;
    --color-dark-900: 15, 23, 42;
    --color-dark-950: 10, 15, 26;

    /* Champagne palette (RGB values) */
    --color-champagne-50: 255, 253, 249;
    --color-champagne-100: 254, 249, 240;
    --color-champagne-200: 247, 231, 206;
    --color-champagne-300: 232, 212, 181;
    --color-champagne-400: 212, 188, 150;
    --color-champagne-500: 191, 164, 119;
    --color-champagne-600: 160, 139, 94;
    --color-champagne-700: 125, 107, 72;
    --color-champagne-800: 92, 79, 53;
    --color-champagne-900: 61, 52, 36;
    --color-champagne-950: 31, 26, 18;

    /* Accent palette (RGB values) - dynamically set by ThemeColorsProvider */
    --color-accent-50: 239, 246, 255;
    --color-accent-100: 219, 234, 254;
    --color-accent-200: 191, 219, 254;
    --color-accent-300: 147, 197, 253;
    --color-accent-400: 96, 165, 250;
    --color-accent-500: 59, 130, 246;
    --color-accent-600: 37, 99, 235;
    --color-accent-700: 29, 78, 216;
    --color-accent-800: 30, 64, 175;
    --color-accent-900: 30, 58, 138;
    --color-accent-950: 23, 37, 84;

    /* Success palette (RGB values) */
    --color-success-50: 240, 253, 244;
    --color-success-100: 220, 252, 231;
    --color-success-200: 187, 247, 208;
    --color-success-300: 134, 239, 172;
    --color-success-400: 74, 222, 128;
    --color-success-500: 34, 197, 94;
    --color-success-600: 22, 163, 74;
    --color-success-700: 21, 128, 61;
    --color-success-800: 22, 101, 52;
    --color-success-900: 20, 83, 45;
    --color-success-950: 5, 46, 22;

    /* Warning palette (RGB values) */
    --color-warning-50: 255, 251, 235;
    --color-warning-100: 254, 243, 199;
    --color-warning-200: 253, 230, 138;
    --color-warning-300: 252, 211, 77;
    --color-warning-400: 251, 191, 36;
    --color-warning-500: 245, 158, 11;
    --color-warning-600: 217, 119, 6;
    --color-warning-700: 180, 83, 9;
    --color-warning-800: 146, 64, 14;
    --color-warning-900: 120, 53, 15;
    --color-warning-950: 69, 26, 3;

    /* Error palette (RGB values) */
    --color-error-50: 254, 242, 242;
    --color-error-100: 254, 226, 226;
    --color-error-200: 254, 202, 202;
    --color-error-300: 252, 165, 165;
    --color-error-400: 248, 113, 113;
    --color-error-500: 239, 68, 68;
    --color-error-600: 220, 38, 38;
    --color-error-700: 185, 28, 28;
    --color-error-800: 153, 27, 27;
    --color-error-900: 127, 29, 29;
    --color-error-950: 69, 10, 10;

    /* Subscription-status semantic tokens — distinct from warning/error
       because the urgency timeline ("expiring soon" vs "expired") needs a
       sharper, hotter signal than the system-wide warning/error roles.
       Extracted from inline #FFB800 / #FF3B5C in Subscription.tsx etc. */
    --color-urgent-400: 255, 184, 0; /* #FFB800 — expiring soon */
    --color-critical-500: 255, 59, 92; /* #FF3B5C — expired */

    /* Theme semantic colors (hex for direct use) */
    --color-dark-bg: #0a0f1a;
    --color-dark-surface: #0f172a;
    --color-dark-text: #f1f5f9;
    --color-dark-text-secondary: #94a3b8;

    --color-light-bg: #f7e7ce;
    --color-light-surface: #fef9f0;
    --color-light-text: #1f1a12;
    --color-light-text-secondary: #7d6b48;
  }

  html {
    overflow-x: hidden;
    scrollbar-width: thin;
    scrollbar-color: rgb(var(--color-dark-700)) transparent;
  }

  body {
    /* 100vw включает ширину скроллбара, поэтому центрированный контент не
       сдвигается, когда при навигации появляется/исчезает вертикальный
       скроллбар; лишние ~6px справа уходят под скроллбар и срезаются
       overflow-x: hidden на html. Вариант со scrollbar-gutter: stable не
       подошёл: фоновый слой (fixed-портал) не красит зарезервированный жёлоб,
       и справа остаётся пустая полоса. На мобильных overlay-скроллбары места
       не занимают — правило ни на что не влияет. */
    width: 100vw;
  }

  /* Hide scrollbar on mobile (iOS/Android) */
  @media (max-width: 1023px) {
    html,
    body {
      scrollbar-width: none;
      -ms-overflow-style: none;
    }
    html::-webkit-scrollbar,
    body::-webkit-scrollbar {
      display: none;
      width: 0;
      height: 0;
    }
  }

  ::-webkit-scrollbar {
    width: 6px;
    height: 6px;
  }

  ::-webkit-scrollbar-track {
    background: transparent;
  }

  ::-webkit-scrollbar-thumb {
    background: rgb(var(--color-dark-700));
    border-radius: 3px;
  }

  ::-webkit-scrollbar-thumb:hover {
    background: rgb(var(--color-dark-600));
  }

  .light ::-webkit-scrollbar-thumb {
    background: rgb(var(--color-champagne-400));
  }

  .light ::-webkit-scrollbar-thumb:hover {
    background: rgb(var(--color-champagne-500));
  }

  /* Smooth scroll only on desktop - mobile uses native */
  @media (min-width: 1024px) {
    html {
      scroll-behavior: smooth;
    }
  }

  /* Dark theme (default) */
  body,
  .dark body {
    @apply bg-dark-950 font-sans text-dark-100 antialiased;
    overscroll-behavior-y: contain;
    /* iOS smooth scrolling */
    -webkit-overflow-scrolling: touch;
    position: relative;
  }

  /* Global Noise Texture — no mix-blend-mode to avoid fullscreen GPU compositing */
  body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
    background-size: 200px 200px;
    background-repeat: repeat;
    opacity: 0.03;
  }

  /* Disable noise on mobile to save GPU */
  @media (max-width: 1023px) {
    body::before {
      display: none;
    }
  }

  /* Main content — containment removed to avoid GPU layer conflicts
     with isolation: isolate on content wrapper */
  main {
    contain: content;
  }

  /* Light theme - Champagne */
  .light body {
    @apply bg-champagne-200 font-sans text-champagne-900 antialiased;
    overscroll-behavior-y: contain;
    -webkit-overflow-scrolling: touch;
  }

  /* Light theme: swap dark palette → dynamic champagne palette from API.
     Uses var() to reference values set by applyThemeColors().
     !important overrides inline styles from applyThemeColors on :root. */
  .light {
    --color-dark-50: var(--color-champagne-950) !important;
    --color-dark-100: var(--color-champagne-900) !important;
    --color-dark-200: var(--color-champagne-800) !important;
    --color-dark-300: var(--color-champagne-700) !important;
    --color-dark-400: var(--color-champagne-600) !important;
    --color-dark-500: var(--color-champagne-500) !important;
    --color-dark-600: var(--color-champagne-400) !important;
    --color-dark-700: var(--color-champagne-300) !important;
    --color-dark-800: var(--color-champagne-50) !important;
    --color-dark-850: var(--color-champagne-100) !important;
    --color-dark-900: var(--color-champagne-100) !important;
    --color-dark-950: var(--color-champagne-200) !important;

    /* Статусные палитры генерируются под тёмную тему: текстовые оттенки
       300/400 (зелёные суммы, жёлтая «Админка», бейджи) на светлом фоне
       дают контраст 1.3–1.6. В светлой теме подменяем их тёмными шейдами —
       зеркально ремапу серых выше. Фоновые употребления (bg-*-500/15 и т.п.)
       используют 500+ и не затрагиваются. */
    --color-accent-300: var(--color-accent-700) !important;
    --color-accent-400: var(--color-accent-700) !important;
    --color-success-300: var(--color-success-700) !important;
    --color-success-400: var(--color-success-700) !important;
    --color-warning-300: var(--color-warning-700) !important;
    --color-warning-400: var(--color-warning-700) !important;
    --color-error-300: var(--color-error-700) !important;
    --color-error-400: var(--color-error-700) !important;
  }

  /* Custom scrollbar - Dark */
  .dark ::-webkit-scrollbar {
    @apply w-2;
  }

  .dark ::-webkit-scrollbar-track {
    @apply bg-dark-900;
  }

  .dark ::-webkit-scrollbar-thumb {
    @apply rounded-full bg-dark-700;
  }

  .dark ::-webkit-scrollbar-thumb:hover {
    @apply bg-dark-600;
  }

  /* Custom scrollbar - Light */
  .light ::-webkit-scrollbar {
    @apply w-2;
  }

  .light ::-webkit-scrollbar-track {
    @apply bg-champagne-200;
  }

  .light ::-webkit-scrollbar-thumb {
    @apply rounded-full bg-champagne-400;
  }

  .light ::-webkit-scrollbar-thumb:hover {
    @apply bg-champagne-500;
  }
}

/* Twemoji — cross-platform emoji rendering */
img.twemoji {
  display: inline-block;
  width: 1.2em;
  height: 1.2em;
  vertical-align: -0.2em;
}

@layer components {
  /* ========== BENTO DESIGN SYSTEM ========== */

  .bento-card {
    @apply border border-dark-700/40 bg-dark-900/70;
    border-radius: var(--bento-radius);
    padding: var(--bento-padding);
    /* Glass Border - Inset Highlight */
    box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.05);
    /* Stagger animation support */
    animation: bentoFadeIn 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
    animation-delay: calc(var(--stagger, 0) * 50ms);
    position: relative;
    overflow: hidden;
  }

  @media (min-width: 1024px) {
    .bento-card {
      @apply bg-dark-900/60;
    }
  }

  /* Disable animation if user prefers reduced motion */
  @media (prefers-reduced-motion: reduce) {
    .bento-card {
      animation: none;
    }
  }

  .bento-card-hover {
    @apply bento-card cursor-pointer;
    transition:
      border-color 0.3s cubic-bezier(0.4, 0, 0.2, 1),
      background-color 0.3s cubic-bezier(0.4, 0, 0.2, 1),
      box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1),
      transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  }

  .bento-card-hover:hover {
    @apply border-dark-600/50 bg-dark-800/60 shadow-lg;
    transform: translateY(-2px) translateZ(0);
    /* Intensify Glass Border & Add Top Spotlight */
    box-shadow:
      inset 0 1px 0 0 rgba(255, 255, 255, 0.1),
      0 10px 40px -10px rgba(0, 0, 0, 0.5);
  }

  /* CSS Spotlight Effect via pseudo-element */
  .bento-card-hover::after {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at top, rgba(255, 255, 255, 0.06), transparent 60%);
    opacity: 0;
    transition: opacity 0.3s ease;
    pointer-events: none;
    z-index: 10;
  }

  .bento-card-hover:hover::after {
    opacity: 1;
  }

  .bento-card-hover:active {
    transform: scale(0.98) translateZ(0);
    transition-duration: 0.15s;
  }

  .bento-card-glow {
    @apply bento-card cursor-pointer;
    transition:
      border-color 0.3s cubic-bezier(0.4, 0, 0.2, 1),
      box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1),
      transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  }

  .bento-card-glow:hover {
    @apply border-accent-500/30 shadow-glow;
    transform: translateY(-2px) translateZ(0);
  }

  .bento-card-glow:active {
    transform: scale(0.98) translateZ(0);
    transition-duration: 0.15s;
  }

  .bento-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--bento-gap);
  }

  @media (min-width: 375px) {
    .bento-grid {
      grid-template-columns: repeat(2, 1fr);
    }
  }

  @media (min-width: 768px) {
    .bento-grid {
      grid-template-columns: repeat(4, 1fr);
      gap: var(--bento-gap-lg);
    }
  }

  .light .bento-card {
    @apply border-champagne-300/50 bg-champagne-50/90 shadow-sm;
    /* Light Theme Glass Border */
    box-shadow: inset 0 1px 0 0 rgba(0, 0, 0, 0.03);
  }

  @media (min-width: 1024px) {
    .light .bento-card {
      @apply bg-champagne-50/85;
    }
  }

  .light .bento-card-hover:hover {
    @apply border-champagne-400/50 bg-champagne-50 shadow-md;
    transform: translateY(-2px) translateZ(0);
    /* Intensify Light Theme Glass Border */
    box-shadow:
      inset 0 1px 0 0 rgba(0, 0, 0, 0.06),
      0 10px 40px -10px rgba(160, 139, 94, 0.15);
  }

  /* Adjust spotlight for light theme to be a warm glow */
  .light .bento-card-hover::after {
    background: radial-gradient(circle at top, rgba(255, 253, 249, 0.8), transparent 70%);
  }

  .light .bento-card-glow:hover {
    @apply border-accent-400/40 shadow-lg;
    transform: translateY(-2px) translateZ(0);
  }

  /* ========== DARK THEME COMPONENTS (default) ========== */

  /* Cards - Dark (unified style) */
  .card {
    @apply border border-dark-700/40 bg-dark-900/70 p-5 transition-colors duration-200 sm:p-6;
    border-radius: var(--bento-radius);
    box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.05);
  }

  @media (min-width: 1024px) {
    .card {
      @apply bg-dark-900/60;
    }
  }

  .card-hover {
    @apply card cursor-pointer hover:border-dark-600/50 hover:bg-dark-800/60 active:scale-[0.98];
  }

  .card-glow {
    @apply card cursor-pointer hover:border-accent-500/30 hover:shadow-glow;
  }

  .card-animated {
    @apply card animate-slide-up;
  }

  /* Glass effect - Dark (optimized for mobile) */
  .glass {
    @apply border border-dark-700/30 bg-dark-900/80;
  }

  /* Enable backdrop-blur only on desktop where it's performant */
  @media (min-width: 1024px) {
    .glass {
      @apply bg-dark-900/30 backdrop-blur-xl;
    }
  }

  /* Buttons - Dark
     min-h-[44px] on mobile (WCAG 2.5.5 AAA touch target floor), keeping
     visual at py-2 / ~36px on desktop where mouse precision rules.
     Cascades to every .btn-primary / .btn-secondary / .btn-ghost / .btn-danger. */
  .btn {
    @apply inline-flex min-h-[44px] items-center justify-center gap-2 rounded-lg px-4 py-2 text-sm font-medium duration-200 ease-smooth focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-dark-900 active:scale-[0.98] disabled:cursor-not-allowed disabled:opacity-50 sm:min-h-0;
    transition-property: color, background-color, border-color, box-shadow, transform, opacity;
  }

  .btn-icon {
    /* Same logic for icon-only buttons. */
    @apply min-h-[44px] min-w-[44px] rounded-lg p-2 text-dark-400 duration-200 hover:bg-dark-800 hover:text-dark-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent-500/50 active:scale-95 sm:min-h-0 sm:min-w-0;
    transition-property: color, background-color, transform;
  }

  .btn-primary {
    @apply btn bg-accent-500 text-on-accent shadow-lg shadow-accent-500/25 hover:bg-accent-400 hover:shadow-xl hover:shadow-accent-500/30 focus-visible:ring-accent-500 active:bg-accent-600;
  }

  .btn-secondary {
    @apply btn border border-dark-700 bg-dark-800 text-dark-200 hover:border-dark-600 hover:bg-dark-700 hover:text-dark-100 focus-visible:ring-dark-500 active:bg-dark-600;
  }

  .btn-ghost {
    @apply btn text-dark-400 hover:bg-dark-800 hover:text-dark-100 focus-visible:ring-dark-500;
  }

  .btn-danger {
    @apply btn border border-error-500/30 bg-error-500/10 text-error-400 hover:border-error-500/50 hover:bg-error-500/20 focus-visible:ring-error-500 active:bg-error-500/30;
  }

  /* Highlighted button for onboarding */
  .btn-highlight {
    @apply relative z-10 animate-spotlight;
  }

  /* Inputs - Dark */
  .input {
    @apply w-full rounded-xl border border-dark-700/50 bg-dark-800/50 px-4 py-3 text-sm text-dark-100 placeholder-dark-500 duration-200 focus:border-accent-500/50 focus:outline-none focus:ring-2 focus:ring-accent-500/20;
    transition-property: color, background-color, border-color, box-shadow;
  }

  .input-error {
    @apply input border-error-500/50 focus:border-error-500 focus:ring-error-500/20;
  }

  /* Remove tap highlight and focus outline on mobile */
  button,
  a,
  [role="button"] {
    -webkit-tap-highlight-color: transparent;
    outline: none;
  }

  /* Only show focus ring for keyboard navigation */
  button:focus-visible,
  a:focus-visible,
  [role="button"]:focus-visible {
    @apply ring-2 ring-accent-500/50 ring-offset-2 ring-offset-dark-900;
  }

  .light button:focus-visible,
  .light a:focus-visible,
  .light [role="button"]:focus-visible {
    @apply ring-offset-champagne-100;
  }

  .label {
    @apply mb-2 block text-sm font-medium text-dark-300;
  }

  /* Badge - Dark */
  .badge {
    @apply inline-flex items-center rounded-full px-2.5 py-1 text-xs font-medium;
  }

  .badge-success {
    @apply badge border border-success-500/30 bg-success-500/15 text-success-400;
  }

  .badge-warning {
    @apply badge border border-warning-500/30 bg-warning-500/15 text-warning-400;
  }

  .badge-error {
    @apply badge border border-error-500/30 bg-error-500/15 text-error-400;
  }

  .badge-info {
    @apply badge border border-accent-500/30 bg-accent-500/15 text-accent-400;
  }

  .badge-neutral {
    @apply badge border border-dark-600/50 bg-dark-700/50 text-dark-300;
  }

  /* Stat card - Dark */
  .stat-value {
    @apply text-2xl font-bold text-dark-50 sm:text-3xl;
  }

  .stat-label {
    @apply mt-1 text-sm text-dark-400;
  }

  /* Navigation - Dark */
  .nav-item {
    @apply flex items-center gap-3 rounded-xl px-4 py-3 text-dark-400 duration-200 hover:bg-dark-800/50 hover:text-dark-100;
    transition-property: color, background-color;
  }

  .nav-item-active {
    @apply nav-item bg-accent-500/10 text-accent-400;
  }

  .bottom-nav {
    @apply fixed z-50 bg-dark-900/95;
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    left: 16px;
    right: 16px;
    border-radius: var(--bento-radius);
    padding: 8px 4px;
    transform: translateZ(0);
    box-shadow:
      0 4px 30px rgba(0, 0, 0, 0.4),
      0 0 0 1px rgba(255, 255, 255, 0.05) inset;
  }

  @media (min-width: 1024px) {
    .bottom-nav {
      @apply bg-dark-900/80 backdrop-blur-xl;
    }
  }

  .bottom-nav-item {
    @apply flex min-w-[56px] flex-1 shrink-0 flex-col items-center justify-center rounded-2xl px-3 py-2.5 text-dark-500 duration-200;
    transition-property: color, background-color;
  }

  .bottom-nav-item:hover {
    @apply text-dark-300;
  }

  .bottom-nav-item-active {
    @apply flex min-w-[56px] flex-1 shrink-0 flex-col items-center justify-center rounded-2xl bg-accent-500/15 px-3 py-2.5 text-accent-400 duration-200;
    transition-property: color, background-color;
  }

  /* Divider - Dark */
  .divider {
    @apply border-t border-dark-800/50;
  }

  /* ========== MOBILE PERFORMANCE: Disable backdrop-blur ========== */
  @media (max-width: 1023px) {
    /* Disable all backdrop-blur on mobile for better scroll performance */
    .backdrop-blur,
    .backdrop-blur-sm,
    .backdrop-blur-md,
    .backdrop-blur-lg,
    .backdrop-blur-xl,
    .backdrop-blur-2xl,
    .backdrop-blur-3xl,
    .backdrop-blur-linear {
      backdrop-filter: none !important;
      -webkit-backdrop-filter: none !important;
    }
  }

  /* ========== LIGHT THEME COMPONENTS (Champagne) ========== */

  /* Cards - Light */
  .light .card {
    @apply border-champagne-300/50 bg-champagne-50/90 p-5 shadow-sm sm:p-6;
    border-radius: var(--bento-radius);
    box-shadow: inset 0 1px 0 0 rgba(0, 0, 0, 0.03);
  }

  @media (min-width: 1024px) {
    .light .card {
      @apply bg-champagne-50/85;
    }
  }

  .light .card-hover {
    @apply hover:border-champagne-400/50 hover:bg-champagne-50 hover:shadow-md;
  }

  .light .card-glow {
    @apply hover:border-accent-400/40 hover:shadow-lg;
  }

  /* Glass effect - Light (optimized for mobile) */
  .light .glass {
    @apply border border-champagne-300/40 bg-champagne-50/90;
  }

  @media (min-width: 1024px) {
    .light .glass {
      @apply bg-champagne-50/60 backdrop-blur-xl;
    }
  }

  /* Buttons - Light */
  .light .btn {
    @apply focus-visible:ring-offset-champagne-100;
  }

  .light .btn-primary {
    @apply bg-champagne-700 text-white shadow-lg shadow-champagne-500/20 hover:bg-champagne-600 hover:shadow-xl hover:shadow-champagne-500/30 focus-visible:ring-champagne-500 active:bg-champagne-800;
  }

  .light .btn-secondary {
    @apply border border-champagne-300 bg-champagne-50 text-champagne-800 hover:border-champagne-400 hover:bg-champagne-100 hover:text-champagne-900 focus-visible:ring-champagne-400 active:bg-champagne-200;
  }

  .light .btn-ghost {
    @apply text-champagne-600 hover:bg-champagne-200/50 hover:text-champagne-900 focus-visible:ring-champagne-400;
  }

  .light .btn-danger {
    @apply border border-error-200 bg-error-50 text-error-600 hover:border-error-300 hover:bg-error-100 active:bg-error-200;
  }

  .light .btn-icon {
    @apply text-champagne-500 hover:bg-champagne-200/50 hover:text-champagne-800;
  }

  /* Inputs - Light */
  .light .input {
    @apply rounded-xl border border-champagne-300 bg-champagne-50 text-champagne-900 placeholder-champagne-400 focus:border-accent-400 focus:ring-accent-300/30;
  }

  .light .input-error {
    @apply border-error-300 focus:border-error-400 focus:ring-error-300/30;
  }

  .light .label {
    @apply text-champagne-700;
  }

  /* Badge - Light */
  .light .badge-success {
    @apply border border-success-200 bg-success-50 text-success-700;
  }

  .light .badge-warning {
    @apply border border-warning-200 bg-warning-50 text-warning-700;
  }

  .light .badge-error {
    @apply border border-error-200 bg-error-50 text-error-700;
  }

  .light .badge-info {
    @apply border border-accent-200 bg-accent-50 text-accent-700;
  }

  .light .badge-neutral {
    @apply border border-champagne-300 bg-champagne-200/50 text-champagne-700;
  }

  /* Stat card - Light */
  .light .stat-value {
    @apply text-champagne-900;
  }

  .light .stat-label {
    @apply text-champagne-600;
  }

  /* Navigation - Light */
  .light .nav-item {
    @apply text-champagne-600 hover:bg-champagne-200/50 hover:text-champagne-900;
  }

  .light .nav-item-active {
    @apply bg-champagne-200/70 text-champagne-800;
  }

  .light .bottom-nav {
    @apply bg-white/95;
    box-shadow:
      0 4px 30px rgba(0, 0, 0, 0.1),
      0 0 0 1px rgba(0, 0, 0, 0.05);
  }

  @media (min-width: 1024px) {
    .light .bottom-nav {
      @apply bg-white/80 backdrop-blur-xl;
    }
  }

  .light .bottom-nav-item {
    @apply text-champagne-500;
  }

  .light .bottom-nav-item:hover {
    @apply text-champagne-700;
  }

  .light .bottom-nav-item-active {
    @apply bg-champagne-300/40 text-champagne-800;
  }

  /* Divider - Light */
  .light .divider {
    @apply border-t border-champagne-200;
  }

  /* Safe area */
  .safe-area-pb {
    padding-bottom: calc(0.5rem + var(--safe-area-inset-bottom));
  }

  .pt-safe {
    padding-top: env(safe-area-inset-top, 0px);
  }

  /* Skeleton loader */
  .skeleton {
    @apply animate-pulse rounded-lg bg-dark-800;
  }

  .light .skeleton {
    @apply bg-champagne-300;
  }

  /* Link */
  .link {
    @apply text-accent-400 transition-colors duration-200 hover:text-accent-300;
  }

  .light .link {
    @apply text-accent-600 hover:text-accent-500;
  }

  /* Prose styles for formatted content */
  .prose {
    @apply leading-relaxed text-dark-200;
  }

  .prose-invert {
    @apply text-dark-200;
  }

  .prose h1 {
    @apply mb-4 mt-6 text-2xl font-bold text-dark-50 first:mt-0;
  }

  .prose h2 {
    @apply mb-3 mt-6 text-xl font-semibold text-dark-50 first:mt-0;
  }

  .prose h3 {
    @apply mb-2 mt-5 text-lg font-semibold text-dark-100 first:mt-0;
  }

  .prose h4 {
    @apply mb-2 mt-4 text-base font-semibold text-dark-100 first:mt-0;
  }

  .prose p {
    @apply mb-4 last:mb-0;
  }

  .prose ul {
    @apply mb-4 list-disc space-y-2 pl-6;
  }

  .prose ol {
    @apply mb-4 list-decimal space-y-2 pl-6;
  }

  .prose li {
    @apply text-dark-300;
  }

  /* TipTap wraps list-item content in <p>. Without these resets, the marker
     stays on its line and the <p> drops to the next line, breaking lists
     in the editor and on the rendered article page (Telegram bug #597116). */
  .prose li > p {
    @apply mb-0 inline;
  }

  .prose li > p + p {
    @apply mt-2 block;
  }

  .prose li::marker {
    @apply text-accent-400;
  }

  .prose a {
    @apply text-accent-400 underline underline-offset-2 transition-colors hover:text-accent-300;
  }

  .prose strong,
  .prose b {
    @apply font-semibold text-dark-100;
  }

  .prose em,
  .prose i {
    @apply italic text-dark-300;
  }

  .prose u {
    @apply underline underline-offset-2;
  }

  .prose s,
  .prose del {
    @apply text-dark-400 line-through;
  }

  .prose tg-spoiler {
    @apply cursor-pointer rounded bg-dark-600 px-1 text-transparent transition-colors hover:bg-transparent hover:text-dark-200;
  }

  .prose blockquote {
    @apply my-4 rounded-r-lg border-l-4 border-accent-500/50 bg-dark-800/30 py-2 pl-4 italic text-dark-300;
  }

  .prose code {
    @apply rounded bg-dark-800 px-1.5 py-0.5 font-mono text-sm text-accent-300;
  }

  .prose pre {
    @apply mb-4 overflow-x-auto rounded-xl bg-dark-800 p-4;
  }

  .prose pre code {
    @apply bg-transparent p-0;
  }

  .prose hr {
    @apply my-6 border-dark-700;
  }

  .prose table {
    @apply mb-4 w-full border-collapse;
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  .prose th {
    @apply border border-dark-700 bg-dark-800 p-3 text-left font-semibold text-dark-100;
  }

  .prose td {
    @apply border border-dark-700 p-3 text-dark-300;
  }

  .prose img {
    @apply my-4 h-auto max-w-full rounded-xl;
  }

  .prose mark {
    @apply rounded bg-warning-500/30 px-1 text-dark-100;
  }

  .prose iframe {
    @apply my-4 block aspect-video w-full max-w-2xl rounded-xl;
  }

  .prose video {
    @apply my-4 block h-auto w-full max-w-full rounded-xl;
  }

  /* Light theme prose styles */
  .light .prose {
    @apply text-champagne-800;
  }

  .light .prose h1 {
    @apply text-champagne-950;
  }

  .light .prose h2 {
    @apply text-champagne-950;
  }

  .light .prose h3,
  .light .prose h4 {
    @apply text-champagne-900;
  }

  .light .prose li {
    @apply text-champagne-700;
  }

  .light .prose li::marker {
    @apply text-champagne-600;
  }

  .light .prose a {
    @apply text-accent-600 hover:text-accent-500;
  }

  .light .prose strong,
  .light .prose b {
    @apply text-champagne-900;
  }

  .light .prose em,
  .light .prose i {
    @apply text-champagne-700;
  }

  .light .prose s,
  .light .prose del {
    @apply text-champagne-500;
  }

  .light .prose tg-spoiler {
    @apply bg-champagne-300 text-transparent hover:bg-transparent hover:text-champagne-800;
  }

  .light .prose blockquote {
    @apply border-champagne-400 bg-champagne-100/50 text-champagne-700;
  }

  .light .prose code {
    @apply bg-champagne-200 text-champagne-800;
  }

  .light .prose pre {
    @apply border border-champagne-300 bg-champagne-100;
  }

  .light .prose hr {
    @apply border-champagne-300;
  }

  .light .prose th {
    @apply border-champagne-300 bg-champagne-200 text-champagne-900;
  }

  .light .prose td {
    @apply border-champagne-300 text-champagne-700;
  }

  .light .prose mark {
    @apply bg-warning-400/30 text-champagne-900;
  }

  .light .prose iframe {
    @apply border border-champagne-300;
  }

  .light .prose video {
    @apply border border-champagne-300;
  }

  .light .prose img {
    @apply border border-champagne-300;
  }

  /* Support for plain text with line breaks */
  .prose-plain {
    @apply whitespace-pre-line;
  }

  .max-w-none {
    max-width: none;
  }

  /* Hide scrollbar */
  .scrollbar-hide {
    -ms-overflow-style: none;
    scrollbar-width: none;
  }
  .scrollbar-hide::-webkit-scrollbar {
    display: none;
  }

  /* Touch target */
  .touch-target {
    min-height: 44px;
    min-width: 44px;
  }
}

@layer utilities {
  /* Viewport height — correct across web (dvh) and Telegram Mini App.
     main.tsx binds --tg-viewport-stable-height via bindViewportCssVars();
     on the standalone web build the var is undefined and falls back to 100dvh. */
  .min-h-viewport {
    min-height: 100dvh;
    min-height: var(--tg-viewport-stable-height, 100dvh);
  }
  .h-viewport {
    height: 100dvh;
    height: var(--tg-viewport-stable-height, 100dvh);
  }

  /* Text gradient */
  .text-gradient {
    @apply bg-gradient-to-r from-accent-400 to-accent-600 bg-clip-text text-transparent;
  }

  /* Glow effects */
  .glow-accent {
    box-shadow: 0 0 20px theme("colors.accent.500 / 30%");
  }

  .glow-success {
    box-shadow: 0 0 20px theme("colors.success.500 / 30%");
  }

  /* Blur backdrop */
  .blur-backdrop {
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
  }

  /* Safe area insets for mobile bottom sheets */
  .safe-area-inset-bottom {
    padding-bottom: max(1rem, env(safe-area-inset-bottom, 0px));
  }
  @media (min-width: 640px) {
    .safe-area-inset-bottom {
      padding-bottom: 1.25rem;
    }
  }
}

/* Animations */
@keyframes bentoFadeIn {
  0% {
    opacity: 0;
    transform: translateY(16px);
  }
  100% {
    opacity: 1;
    transform: none;
  }
}

@keyframes shimmer {
  0% {
    background-position: -200% 0;
  }
  100% {
    background-position: 200% 0;
  }
}

.shimmer {
  background: linear-gradient(
    90deg,
    theme("colors.dark.800") 0%,
    theme("colors.dark.700") 50%,
    theme("colors.dark.800") 100%
  );
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
}

.light .shimmer {
  background: linear-gradient(
    90deg,
    theme("colors.champagne.200") 0%,
    theme("colors.champagne.300") 50%,
    theme("colors.champagne.200") 100%
  );
}

/* Tap effect on mobile */
@media (hover: none) {
  .btn:active,
  .card-hover:active,
  .nav-item:active {
    transform: scale(0.98) translateZ(0);
  }
}

/* Color picker range input styling */
input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  height: 12px;
  border-radius: 6px;
  outline: none;
  touch-action: pan-x;
}

/* Desktop: smaller track */
@media (min-width: 640px) {
  input[type="range"] {
    height: 8px;
    border-radius: 4px;
  }
}

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: white;
  cursor: pointer;
  border: 2px solid rgba(0, 0, 0, 0.15);
  box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.3),
    0 0 0 1px rgba(255, 255, 255, 0.1);
  transition:
    transform 0.15s ease,
    box-shadow 0.15s ease;
}

input[type="range"]::-webkit-slider-thumb:hover {
  transform: scale(1.1);
  box-shadow:
    0 3px 8px rgba(0, 0, 0, 0.4),
    0 0 0 2px rgba(255, 255, 255, 0.2);
}

input[type="range"]::-webkit-slider-thumb:active {
  transform: scale(0.95);
}

/* Desktop: smaller thumb */
@media (min-width: 640px) {
  input[type="range"]::-webkit-slider-thumb {
    width: 18px;
    height: 18px;
  }
}

input[type="range"]::-moz-range-thumb {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: white;
  cursor: pointer;
  border: 2px solid rgba(0, 0, 0, 0.15);
  box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.3),
    0 0 0 1px rgba(255, 255, 255, 0.1);
  transition:
    transform 0.15s ease,
    box-shadow 0.15s ease;
}

input[type="range"]::-moz-range-thumb:hover {
  transform: scale(1.1);
  box-shadow:
    0 3px 8px rgba(0, 0, 0, 0.4),
    0 0 0 2px rgba(255, 255, 255, 0.2);
}

/* Desktop: smaller thumb */
@media (min-width: 640px) {
  input[type="range"]::-moz-range-thumb {
    width: 18px;
    height: 18px;
  }
}

/* Hide number input spinners for cleaner look */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

input[type="number"] {
  -moz-appearance: textfield;
}

/* Custom checkbox styling - more visible */
input[type="checkbox"] {
  -webkit-appearance: none;
  appearance: none;
  width: 1.25rem;
  height: 1.25rem;
  border: 1.5px solid rgb(var(--color-dark-600));
  border-radius: 0.375rem;
  background-color: rgb(var(--color-dark-700));
  cursor: pointer;
  transition:
    border-color 0.15s ease,
    background-color 0.15s ease;
  position: relative;
  flex-shrink: 0;
}

input[type="checkbox"]:checked {
  background-color: rgb(var(--color-accent-500));
  border-color: rgb(var(--color-accent-500));
}

input[type="checkbox"]:checked::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 45%;
  width: 5px;
  height: 9px;
  border: solid white;
  border-width: 0 2px 2px 0;
  transform: translate(-50%, -50%) rotate(45deg);
}

input[type="checkbox"]:focus {
  outline: none;
  box-shadow: 0 0 0 2px rgba(var(--color-accent-500), 0.3);
}

input[type="checkbox"]:hover:not(:checked) {
  border-color: rgb(var(--color-dark-500));
  background-color: rgb(var(--color-dark-600));
}

/* Recharts: bars, pie sectors and dots become focusable, so clicking one draws
   the browser's focus outline — a visual artifact on read-only charts. Kill it. */
.recharts-wrapper:focus,
.recharts-wrapper:focus-visible,
.recharts-wrapper :focus,
.recharts-wrapper :focus-visible,
.recharts-surface,
.recharts-sector,
.recharts-rectangle {
  outline: none;
}

/* react-day-picker (DateField) — themed via the library's CSS variables.
   The library declares its rdp variables ON .rdp-root, so overriding them on a
   parent (.rdp-dark) gets shadowed. We must target `.rdp-dark .rdp-root` to win.
   All colors go through the app's theme tokens (the dark and accent scales),
   which flip for light themes (e.g. champagne) — so the picker stays legible in
   every theme without bespoke per-theme rules. */
.rdp-dark {
  color: rgb(var(--color-dark-100));
  font-size: 0.85rem;
}
.rdp-dark .rdp-root {
  --rdp-accent-color: rgb(var(--color-accent-500));
  --rdp-accent-background-color: rgb(var(--color-accent-500) / 0.18);
  --rdp-today-color: rgb(var(--color-accent-400));
  --rdp-day-height: 2.25rem;
  --rdp-day-width: 2.25rem;
  --rdp-outside-opacity: 0.4;
  --rdp-disabled-opacity: 0.4;
  --rdp-selected-border: none;
  --rdp-weekday-opacity: 1;
}
.rdp-dark .rdp-month_caption,
.rdp-dark .rdp-caption_label {
  color: rgb(var(--color-dark-100));
  font-weight: 600;
  text-transform: capitalize;
}
.rdp-dark .rdp-weekday {
  color: rgb(var(--color-dark-400));
  font-weight: 500;
  text-transform: capitalize;
}
.rdp-dark .rdp-day_button {
  color: rgb(var(--color-dark-100));
  border: none;
  border-radius: 0.5rem;
}
.rdp-dark .rdp-day_button:hover:not([disabled]) {
  background-color: rgb(var(--color-dark-700));
}
.rdp-dark .rdp-day_button:focus-visible {
  outline: 2px solid rgb(var(--color-accent-500));
  outline-offset: 1px;
}
/* Today: accent-tinted text + subtle ring (loses to the filled "selected" look). */
.rdp-dark .rdp-today:not(.rdp-outside) .rdp-day_button {
  color: rgb(var(--color-accent-400));
  font-weight: 700;
  box-shadow: inset 0 0 0 1px rgb(var(--color-accent-500) / 0.45);
}
.rdp-dark .rdp-selected .rdp-day_button {
  background-color: rgb(var(--color-accent-500));
  color: #fff;
  font-weight: 700;
  border: none;
  box-shadow: none;
}
.rdp-dark .rdp-chevron {
  fill: currentColor;
}
.rdp-dark .rdp-button_previous,
.rdp-dark .rdp-button_next {
  color: rgb(var(--color-dark-300));
  border-radius: 0.5rem;
}
.rdp-dark .rdp-button_previous:hover:not([disabled]),
.rdp-dark .rdp-button_next:hover:not([disabled]) {
  color: rgb(var(--color-dark-100));
  background-color: rgb(var(--color-dark-700));
}

.light input[type="checkbox"] {
  border-color: rgb(var(--color-champagne-400));
  background-color: rgb(var(--color-champagne-100));
}

.light input[type="checkbox"]:checked {
  background-color: rgb(var(--color-accent-500));
  border-color: rgb(var(--color-accent-500));
}

.light input[type="checkbox"]:hover:not(:checked) {
  border-color: rgb(var(--color-champagne-500));
  background-color: rgb(var(--color-champagne-200));
}

/* Selection color */
::selection {
  @apply bg-accent-500/30 text-dark-50;
}

.light ::selection {
  @apply bg-champagne-400/50 text-champagne-950;
}

/* Onboarding styles */
.onboarding-overlay {
  @apply pointer-events-none fixed inset-0 z-[100];
  background: rgba(0, 0, 0, 0.75);
  transition: opacity 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}

.onboarding-spotlight {
  @apply pointer-events-auto absolute;
  border-radius: 16px;
  box-shadow:
    0 0 0 9999px rgba(0, 0, 0, 0.75),
    0 0 30px rgba(59, 130, 246, 0.4);
  transition: all 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}

.onboarding-tooltip {
  @apply pointer-events-auto absolute max-w-xs rounded-2xl border border-accent-500/30 bg-dark-900 p-5 shadow-xl shadow-accent-500/10 sm:max-w-sm;
  animation: scaleInBounce 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.onboarding-tooltip::before {
  content: "";
  @apply absolute h-3 w-3 border-l border-t border-accent-500/30 bg-dark-900;
  transform: rotate(45deg);
}

/* Light theme onboarding */
.light .onboarding-overlay {
  background: rgba(0, 0, 0, 0.5);
}

.light .onboarding-spotlight {
  box-shadow:
    0 0 0 9999px rgba(0, 0, 0, 0.5),
    0 0 30px rgba(160, 139, 94, 0.4);
}

.light .onboarding-tooltip {
  @apply border-champagne-400/50 bg-white shadow-champagne-500/20;
}

.light .onboarding-tooltip::before {
  @apply border-champagne-400/50 bg-white;
}

.onboarding-tooltip.tooltip-top::before {
  @apply -bottom-1.5 left-1/2 -translate-x-1/2;
  transform: translateX(-50%) rotate(-135deg);
}

.onboarding-tooltip.tooltip-bottom::before {
  @apply -top-1.5 left-1/2;
  transform: translateX(-50%) rotate(45deg);
}

.onboarding-tooltip.tooltip-left::before {
  @apply -right-1.5 top-1/2;
  transform: translateY(-50%) rotate(135deg);
}

.onboarding-tooltip.tooltip-right::before {
  @apply -left-1.5 top-1/2;
  transform: translateY(-50%) rotate(-45deg);
}

/* Stagger animation utilities */
.stagger-1 {
  animation-delay: 0.05s;
}
.stagger-2 {
  animation-delay: 0.1s;
}
.stagger-3 {
  animation-delay: 0.15s;
}
.stagger-4 {
  animation-delay: 0.2s;
}
.stagger-5 {
  animation-delay: 0.25s;
}
.stagger-6 {
  animation-delay: 0.3s;
}
.stagger-7 {
  animation-delay: 0.35s;
}
.stagger-8 {
  animation-delay: 0.4s;
}

/* Animation fill mode for stagger */
.animate-fill-both {
  animation-fill-mode: both;
}

/* Smooth page transitions */
.page-enter {
  @apply translate-y-4 opacity-0;
}

.page-enter-active {
  @apply translate-y-0 opacity-100 transition-all duration-500;
  transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}

.page-exit {
  @apply translate-y-0 opacity-100;
}

.page-exit-active {
  @apply -translate-y-4 opacity-0 transition-all duration-300;
  transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
}

/* Keyframes for scale in bounce */
@keyframes scaleInBounce {
  0% {
    opacity: 0;
    transform: scale(0.9);
  }
  50% {
    transform: scale(1.02);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

/* Fortune Wheel animations */
@keyframes wheel-shimmer {
  0% {
    background-position: 200% 50%;
  }
  100% {
    background-position: -200% 50%;
  }
}

@keyframes wheel-glow {
  0%,
  100% {
    filter: drop-shadow(0 0 10px rgba(255, 215, 0, 0.3));
  }
  50% {
    filter: drop-shadow(0 0 20px rgba(255, 215, 0, 0.6));
  }
}

@keyframes prize-reveal {
  0% {
    opacity: 0;
    transform: scale(0.5) rotate(-10deg);
  }
  50% {
    transform: scale(1.1) rotate(5deg);
  }
  100% {
    opacity: 1;
    transform: scale(1) rotate(0);
  }
}

@keyframes confetti-fall {
  0% {
    transform: translateY(-100%) rotate(0deg);
    opacity: 1;
  }
  100% {
    transform: translateY(100vh) rotate(720deg);
    opacity: 0;
  }
}

.animate-scale-in {
  animation: scaleInBounce 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.animate-prize-reveal {
  animation: prize-reveal 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.animate-wheel-glow {
  animation: wheel-glow 2s ease-in-out infinite;
}

/* Toast progress bar animation — use scaleX instead of width to avoid layout thrashing */
@keyframes shrink {
  from {
    transform: scaleX(1);
  }
  to {
    transform: scaleX(0);
  }
}

/* News section shimmer */
@keyframes newsShimmer {
  0%,
  100% {
    opacity: 0.3;
    transform: scaleX(0.5);
  }
  50% {
    opacity: 1;
    transform: scaleX(1);
  }
}

/* User preference: reduce motion */
.reduce-motion,
.reduce-motion * {
  animation-duration: 0.01ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.01ms !important;
  scroll-behavior: auto !important;
}

/* ========== SHEET MODAL STYLES ========== */

/* Sheet animations */
@keyframes sheetSlideUp {
  from {
    transform: translateY(100%);
  }
  to {
    transform: translateY(0);
  }
}

@keyframes sheetSlideDown {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(100%);
  }
}

@keyframes backdropFadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes backdropFadeOut {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

/* Page transitions */
@keyframes pageEnter {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes pageExit {
  from {
    opacity: 1;
    transform: translateY(0);
  }
  to {
    opacity: 0;
    transform: translateY(-12px);
  }
}

.page-enter {
  animation: pageEnter 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.page-exit {
  animation: pageExit 0.2s ease-in both;
}

/* Light theme sheet overrides */
.light .sheet-backdrop {
  @apply bg-black/40;
}

.light .sheet-container {
  @apply bg-champagne-100;
}

.light .sheet-handle {
  @apply bg-champagne-400;
}

/* ── Admin Panel: Floating Orbs Background ── */
@keyframes adminOrbFloat {
  0% {
    transform: translate(0, 0) scale(1);
  }
  33% {
    transform: translate(30px, -40px) scale(1.05);
  }
  66% {
    transform: translate(-20px, 30px) scale(0.95);
  }
  100% {
    transform: translate(10px, -20px) scale(1.02);
  }
}

@keyframes adminPulse {
  0%,
  100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.4;
    transform: scale(0.85);
  }
}

@keyframes adminCardEnter {
  from {
    opacity: 0;
    transform: translateY(20px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes adminItemEnter {
  from {
    opacity: 0;
    transform: translateX(-8px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

.admin-orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(120px);
  pointer-events: none;
  animation: adminOrbFloat 20s ease-in-out infinite alternate;
}

.light .admin-orb {
  filter: blur(140px);
  opacity: 0.15 !important;
}

/* Mobile: reduce orb count and blur for performance */
@media (max-width: 1023px) {
  .admin-orb {
    filter: blur(80px);
  }
  .admin-orb:nth-child(n + 4) {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .admin-orb {
    animation: none;
  }
}
