/* ═══════════════════════════════════════════════════════════════
   BASE: ANIMATIONS, UTILITIES, BUTTONS, INPUTS, SKELETON
   ═══════════════════════════════════════════════════════════════ */
/* ═══════════════════════════════════════════════════════════════
   ANIMATIONS
   ═══════════════════════════════════════════════════════════════ */
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes fadeUp { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
@keyframes tierReveal { 0% { opacity:0; transform:scale(.8); } 50% { transform:scale(1.08); } 100% { opacity:1; transform:scale(1); } }
@keyframes fadeDown { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } }
@keyframes slideRight { from { opacity: 0; transform: translateX(-16px); } to { opacity: 1; transform: translateX(0); } }
@keyframes slideLeft { from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: translateX(0); } }
@keyframes scaleIn { from { opacity: 0; transform: scale(.95); } to { opacity: 1; transform: scale(1); } }
@keyframes modalIn { from { opacity: 0; transform: scale(.96) translateY(12px); } to { opacity: 1; transform: scale(1) translateY(0); } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .4; } }
@keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }
@keyframes shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-4px); } 75% { transform: translateX(4px); } }
@keyframes breathe { 0%,100% { box-shadow: 0 0 0 0 rgba(0,196,114,.3); } 50% { box-shadow: 0 0 0 8px rgba(0,196,114,0); } }
@keyframes slideUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
@keyframes toastIn { from { opacity: 0; transform: translateY(16px) scale(.96); } to { opacity: 1; transform: translateY(0) scale(1); } }
@keyframes toastOut { from { opacity: 1; transform: translateY(0) scale(1); } to { opacity: 0; transform: translateY(10px) scale(.97); } }
@keyframes countUp { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
@keyframes voteBurst { 0% { transform: scale(1); } 30% { transform: scale(1.4); } 60% { transform: scale(.9); } 100% { transform: scale(1); } }
@keyframes glowPulse { 0%,100% { filter: brightness(1); } 50% { filter: brightness(1.3); } }
@keyframes ripple { 0% { box-shadow: 0 0 0 0 rgba(0,196,114,.4); } 100% { box-shadow: 0 0 0 12px rgba(0,196,114,0); } }
@keyframes slideInRight { from { opacity:0;transform:translateX(20px); } to { opacity:1;transform:translateX(0); } }
@keyframes numberPop { 0% { transform:scale(1); } 50% { transform:scale(1.3);color:var(--accent); } 100% { transform:scale(1); } }
@keyframes cardGlow { 0%,100% { border-color:var(--border); } 50% { border-color:rgba(0,196,114,.2); } }
@keyframes successFlash { 0% { background:rgba(0,196,114,.15); } 100% { background:transparent; } }
@keyframes priceUp { 0% { color:var(--text-0); } 30% { color:var(--accent); } 100% { color:var(--text-0); } }
@keyframes priceDown { 0% { color:var(--text-0); } 30% { color:var(--red); } 100% { color:var(--text-0); } }
@keyframes reelSlide { from { opacity:0;transform:translateY(40px) scale(.98); } to { opacity:1;transform:translateY(0) scale(1); } }

/* Micro-interaction classes */
.vote-burst { animation: voteBurst .3s ease; }
.number-pop { animation: numberPop .3s ease; }
.card-glow { animation: cardGlow 1s ease; }
.success-flash { animation: successFlash .5s ease; }
.price-flash-up { animation: priceUp .6s ease; }
.price-flash-down { animation: priceDown .6s ease; }

/* Hover micro-interactions */
.post:hover { border-color: rgba(0,196,114,.22); }
.post { transition: all .2s ease; }
.card { transition: border-color .2s ease; }
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0) scale(.97); }
.tag:hover { transform: translateY(-1px); }
.tag { transition: all .15s ease; font-size: 12px; }
.nav-item { transition: all .15s ease; }
.avatar { transition: all .15s ease; font-weight: 600; }
.avatar:hover { transform: scale(1.05); }
.post-trade-btn:active { transform: scale(.95); }
.top-token-row { transition: all .15s ease; }
.leader-row { transition: all .15s ease; }

/* ═══════════════════════════════════════════════════════════════
   UTILITY CLASSES
   ═══════════════════════════════════════════════════════════════ */
.hide { display: none !important; }
.mono { font-family: var(--mono); }
.green { color: var(--accent); }
.red { color: var(--red); }
.gold { color: var(--gold); }
.blue { color: var(--blue); }
.dim { color: var(--text-3); }
.bold { font-weight: 700; }
.center { text-align: center; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.flex { display: flex; }
.flex-col { display: flex; flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-4 { gap: 4px; }
.gap-6 { gap: 6px; }
.gap-8 { gap: 8px; }
.gap-10 { gap: 10px; }
.gap-12 { gap: 12px; }
.gap-16 { gap: 16px; }
.gap-20 { gap: 20px; }
.flex-1 { flex: 1; min-width: 0; }
.w-full { width: 100%; }
.shrink-0 { flex-shrink: 0; }
.relative { position: relative; }
.pointer { cursor: pointer; }
.no-select { user-select: none; }

/* ═══════════════════════════════════════════════════════════════
   COMPONENT: BUTTONS
   ═══════════════════════════════════════════════════════════════ */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 6px; border-radius: var(--radius); padding: 10px 18px;
  font-size: 13px; font-weight: 600; transition: all var(--transition);
  white-space: nowrap; position: relative; overflow: hidden;
}
.btn:active { transform: scale(.97); }
.btn-primary { background: var(--accent); color: #000; font-weight: 700; }
.btn-primary:hover { background: var(--accent-hover); box-shadow: 0 2px 12px rgba(0,196,114,.2); }
.btn-secondary { background: var(--bg-3); color: var(--text-1); border: 1px solid var(--border); }
.btn-secondary:hover { background: var(--bg-4); border-color: var(--border-hover); }
.btn-ghost { background: transparent; color: var(--text-2); }
.btn-ghost:hover { background: var(--bg-hover); color: var(--text-1); }
.btn-danger { background: var(--red-dim); color: var(--red); border: 1px solid var(--red-border); }
.btn-danger:hover { background: rgba(196,64,64,.2); }
.btn-buy { background: var(--accent); color: #000; font-weight: 700; }
.btn-buy:hover { background: var(--accent-hover); }
.btn-sell { background: var(--red-dim); color: var(--red); border: 1px solid var(--red-border); font-weight: 700; }
.btn-sell:hover { background: rgba(196,64,64,.18); }
.btn-sm { padding: 6px 12px; font-size: 12px; border-radius: var(--radius-s); }
.btn-lg { padding: 14px 24px; font-size: 15px; }
.btn-full { width: 100%; }
.btn-icon { width: 36px; height: 36px; padding: 0; border-radius: var(--radius); }
.btn-icon-sm { width: 30px; height: 30px; padding: 0; border-radius: var(--radius-s); }
.btn .spinner { width: 16px; height: 16px; border: 2px solid rgba(0,0,0,.2); border-top-color: #000; border-radius: 50%; animation: spin .6s linear infinite; }
.btn-primary .spinner { border-color: rgba(0,0,0,.2); border-top-color: #000; }

/* ═══════════════════════════════════════════════════════════════
   COMPONENT: INPUTS
   ═══════════════════════════════════════════════════════════════ */
.input-group { display: flex; flex-direction: column; gap: 5px; }
.input-label { font-size: 11px; font-weight: 600; color: var(--text-4); letter-spacing: .04em; text-transform: uppercase; }
.input {
  width: 100%; background: var(--bg-3); border: 1px solid rgba(0,196,114,.06);
  border-radius: 8px; padding: 10px 14px; font-size: 13px;
  color: var(--text-0); outline: none; transition: all .2s; font-family: var(--font);
}
.input:focus { border-color: rgba(0,196,114,.25); box-shadow: 0 0 0 3px rgba(0,196,114,.06); }
/* P65.275 — placeholder visibility bump (var(--text-4) was almost
   invisible against dark inputs).  Affects every .input across the
   platform: composers, settings fields, search bars, etc.  Slight
   opacity keeps it clearly placeholder-y vs typed text. */
.input::placeholder { color: var(--text-3); opacity: .85; }
.input-error { border-color: var(--red-border) !important; }
.input-error:focus { box-shadow: 0 0 0 3px rgba(196,64,64,.08) !important; }
.input-hint { font-size: 10px; color: var(--text-4); }
.input-error-msg { font-size: 11px; color: var(--red); }
textarea.input { resize: vertical; min-height: 72px; line-height: 1.5; }
.input-with-icon { position: relative; }
.input-with-icon .input { padding-left: 40px; }
.input-with-icon .input-icon { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--text-4); pointer-events: none; }
.input-with-icon .input-action { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); }
.toggle-wrap { display: flex; align-items: center; justify-content: space-between; padding: 8px 0; }
.toggle-info { display: flex; flex-direction: column; gap: 2px; }
.toggle-title { font-size: 12px; font-weight: 600; color: var(--text-1); }
.toggle-desc { font-size: 10px; color: var(--text-4); }
.toggle { position: relative; width: 38px; height: 20px; flex-shrink: 0; }
.toggle input { opacity: 0; width: 0; height: 0; }
.toggle-slider {
  position: absolute; inset: 0; background: var(--bg-4); border-radius: 10px;
  cursor: pointer; transition: all .2s; border: 1px solid rgba(255,255,255,.06);
}
.toggle-slider::before {
  content: ''; position: absolute; left: 2px; top: 2px; width: 14px; height: 14px;
  background: var(--text-3); border-radius: 50%; transition: all .2s;
}
.toggle input:checked + .toggle-slider { background: rgba(0,196,114,.15); border-color: rgba(0,196,114,.25); }
.toggle input:checked + .toggle-slider::before { transform: translateX(18px); background: var(--accent); box-shadow: 0 0 6px rgba(0,196,114,.3); }


/* ═══════════════════════════════════════════════════════════════
   SKELETON LOADING
   ═══════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════════════════════════════
   P33 — UNIVERSAL TRANSITION SYSTEM
   ─────────────────────────────────────────────────────────────
   Goal: institutional polish via consistent motion. Every render
   surface uses the same primitives so the platform feels
   intentional, not random. Three layers:

     1. .page-transition — main content area, on every page nav
     2. .fx-fade-up      — element entering from below (reusable)
     3. .fx-stagger      — children of a list, cascading in

   All durations land in the 220–360ms range with a calm easing
   (cubic-bezier(.2,.7,.2,1)) — slow enough to feel deliberate,
   fast enough to not impede flow. Twitter / Linear / Stripe are
   all in this range.

   prefers-reduced-motion is respected at the bottom.
   ═══════════════════════════════════════════════════════════════ */

/* Page-level transition — applied to the main content host on
   every page change. Briefly drops opacity + lifts content,
   then settles. */
@keyframes pageEnter {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.page-transition {
  animation: pageEnter 280ms cubic-bezier(.2,.7,.2,1);
}

/* Element entrance — used on post cards, notification rows,
   sidebar widget items, etc. */
@keyframes fxFadeUp {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.fx-fade-up {
  animation: fxFadeUp 320ms cubic-bezier(.2,.7,.2,1) both;
  /* "both" so the element starts at the from-state until the animation runs,
     preventing the brief flicker that "forwards" alone produces. */
}

/* Stagger system — when applied to a parent, children get
   cascading delays. Capped at 12 children so lists of 100+
   don't have an annoyingly long roll-in. */
.fx-stagger > * {
  animation: fxFadeUp 320ms cubic-bezier(.2,.7,.2,1) both;
}
.fx-stagger > *:nth-child(1)  { animation-delay: 20ms; }
.fx-stagger > *:nth-child(2)  { animation-delay: 60ms; }
.fx-stagger > *:nth-child(3)  { animation-delay: 100ms; }
.fx-stagger > *:nth-child(4)  { animation-delay: 140ms; }
.fx-stagger > *:nth-child(5)  { animation-delay: 180ms; }
.fx-stagger > *:nth-child(6)  { animation-delay: 215ms; }
.fx-stagger > *:nth-child(7)  { animation-delay: 245ms; }
.fx-stagger > *:nth-child(8)  { animation-delay: 270ms; }
.fx-stagger > *:nth-child(9)  { animation-delay: 290ms; }
.fx-stagger > *:nth-child(10) { animation-delay: 305ms; }
.fx-stagger > *:nth-child(n+11) { animation-delay: 315ms; }

/* Tighter variant for sidebar widget items (small, frequent
   re-renders shouldn't have a 320ms entrance every time). */
.fx-stagger-tight > * {
  animation: fxFadeUp 220ms cubic-bezier(.2,.7,.2,1) both;
}
.fx-stagger-tight > *:nth-child(1) { animation-delay: 0ms; }
.fx-stagger-tight > *:nth-child(2) { animation-delay: 30ms; }
.fx-stagger-tight > *:nth-child(3) { animation-delay: 55ms; }
.fx-stagger-tight > *:nth-child(4) { animation-delay: 75ms; }
.fx-stagger-tight > *:nth-child(5) { animation-delay: 90ms; }
.fx-stagger-tight > *:nth-child(n+6) { animation-delay: 100ms; }

/* Media loading — soft fade-in reveal. Originally used filter: blur
   for a focus-pull effect, but filter is GPU-heavy on Chrome/Windows
   and causes scroll lag when many media elements are on-screen
   (whole-page recomposites every frame). Opacity-only fade is
   visually nearly identical and essentially free. */
.fx-media {
  opacity: 0;
  transition: opacity 240ms ease-out;
}
.fx-media-loaded {
  opacity: 1;
}

/* Avatar loading shimmer — wraps an avatar that's still loading.
   Reuses the existing shimmer keyframe from earlier in this file. */
.fx-avatar-loading {
  background: linear-gradient(90deg,
    rgba(255,255,255,.04) 0%,
    rgba(255,255,255,.10) 50%,
    rgba(255,255,255,.04) 100%);
  background-size: 200% 100%;
  animation: shimmer 1.2s linear infinite;
}

/* Honor user accessibility preference */
@media (prefers-reduced-motion: reduce) {
  .page-transition,
  .fx-fade-up,
  .fx-stagger > *,
  .fx-stagger-tight > * {
    animation: none !important;
  }
  .fx-media { opacity: 1; transition: none; }
}
