@keyframes orb1{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(80px,50px) scale(1.12)}}
@keyframes orb2{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(-90px,40px) scale(1.08)}}
@keyframes orb3{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(50px,-60px) scale(1.15)}}
@keyframes coinspin{0%{transform:rotateY(0)}100%{transform:rotateY(360deg)}}
@keyframes floaty{0%,100%{transform:translateY(0)}50%{transform:translateY(-14px)}}
@keyframes floaty2{0%,100%{transform:translateY(0)}50%{transform:translateY(-8px)}}
@keyframes sheen{0%{transform:translateX(-150%) skewX(-18deg)}100%{transform:translateX(350%) skewX(-18deg)}}
@keyframes wave{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}
@keyframes activity-ticker-scroll{from{transform:translateX(0)}to{transform:translateX(-50%)}}
#activity-ticker:hover #activity-ticker-track{animation-play-state:paused}

/* Smooth cross-fade between full page loads (Chromium's cross-document
   View Transitions API). Browsers without support just keep the current
   instant navigation — nothing to feature-detect, it's inert elsewhere. */
@view-transition{navigation:auto}

body{margin:0;background:#08090f;font-family:'Geist',sans-serif;color:#f5f6f8;-webkit-font-smoothing:antialiased}
a{color:rgba(235,240,250,.9);text-decoration:none}
a:hover{color:#fff}
button{font-family:'Geist',sans-serif}
::-webkit-scrollbar{width:7px}
::-webkit-scrollbar-thumb{background:rgba(255,255,255,.14);border-radius:4px}
::-webkit-scrollbar-track{background:transparent}

.nav-link{color:rgba(235,240,250,.6);padding:8px 18px;border-radius:100px;transition:background .15s,color .15s}
.nav-link:hover{color:#fff;background:rgba(255,255,255,.07)}
.nav-link.active{color:#fff;background:rgba(255,255,255,.12);box-shadow:inset 0 1px 0 rgba(255,255,255,.2)}

.btn-primary{position:relative;overflow:hidden;background:linear-gradient(180deg,rgba(10,132,255,.92),rgba(10,110,230,.78));color:#fff;border:1px solid rgba(255,255,255,.3);font-weight:600;font-size:15px;padding:15px 32px;border-radius:100px;cursor:pointer;box-shadow:inset 0 1px 0 rgba(255,255,255,.4),0 12px 32px rgba(10,132,255,.45);display:inline-block}
.btn-primary:hover{filter:brightness(1.12);color:#fff}
.btn-primary .sheen{position:absolute;top:0;bottom:0;left:0;width:40%;background:linear-gradient(90deg,transparent,rgba(255,255,255,.35),transparent);animation:sheen 3.6s ease-in-out infinite}

.btn-ghost{background:rgba(255,255,255,.07);color:#f5f6f8;border:1px solid rgba(255,255,255,.15);font-weight:500;font-size:15px;padding:15px 32px;border-radius:100px;cursor:pointer;backdrop-filter:blur(12px);box-shadow:inset 0 1px 0 rgba(255,255,255,.18);display:inline-block}
.btn-ghost:hover{background:rgba(255,255,255,.12);color:#f5f6f8}

.offer-card{border-radius:24px;overflow:hidden;border:1px solid rgba(255,255,255,.11);background:rgba(255,255,255,.04);box-shadow:inset 0 1px 0 rgba(255,255,255,.14),0 14px 36px rgba(0,0,0,.3);transition:transform .25s cubic-bezier(.2,.9,.3,1.4)}
.offer-card:hover{transform:translateY(-5px);border:1px solid rgba(255,255,255,.28)}
.offer-card-summary{cursor:pointer}

/* Placeholder cards shown while GET /offers/data is in flight — same shape
   as a real .offer-card so nothing jumps around once it's replaced. */
@keyframes offer-skeleton-pulse{0%,100%{opacity:.5}50%{opacity:1}}
.offer-skeleton{border-radius:24px;overflow:hidden;border:1px solid rgba(255,255,255,.08);background:rgba(255,255,255,.03);animation:offer-skeleton-pulse 1.6s ease-in-out infinite}
.offer-skeleton .sk-block{background:rgba(255,255,255,.08)}

.cat-pill{background:transparent;color:rgba(235,240,250,.55);border:1px solid transparent;font-weight:600;font-size:12.5px;padding:8px 18px;border-radius:100px;cursor:pointer}
.cat-pill.active{background:rgba(255,255,255,.14);color:#fff;border:1px solid rgba(255,255,255,.18);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 4px 12px rgba(0,0,0,.3)}

.net-pill{background:rgba(255,255,255,.05);color:rgba(235,240,250,.6);border:1px solid rgba(255,255,255,.12);font-weight:600;font-size:12px;padding:7px 16px;border-radius:100px;cursor:pointer}
.net-pill.active{background:rgba(10,132,255,.18);color:#a8c8ff;border:1px solid rgba(10,132,255,.4)}

.device-pill{display:inline-flex;align-items:center;gap:6px;background:rgba(255,255,255,.05);color:rgba(235,240,250,.6);border:1px solid rgba(255,255,255,.12);font-weight:600;font-size:12px;padding:6px 14px 6px 10px;border-radius:100px;cursor:pointer}
.device-pill svg{opacity:.75}
.device-pill.active{background:rgba(110,231,168,.14);color:#6ee7a8;border:1px solid rgba(110,231,168,.4)}
.device-pill.active svg{opacity:1}

.sort-link{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.12);border-radius:100px;padding:8px 16px;font-weight:500;color:rgba(235,240,250,.8);box-shadow:inset 0 1px 0 rgba(255,255,255,.14)}
.sort-link.active{background:rgba(255,255,255,.14);color:#fff}

.method-radio{position:absolute;opacity:0;pointer-events:none}
.method-card{border-radius:20px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.12);padding:17px 18px;cursor:pointer;transition:transform .2s ease;display:block}
.method-card:hover{transform:translateY(-3px)}
.method-card .check-mark{display:none}
.method-radio:checked + .method-card{background:rgba(110,231,168,.1);border:1px solid rgba(110,231,168,.4);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 10px 30px rgba(110,231,168,.15)}
.method-radio:checked + .method-card .check-mark{display:flex}
.method-radio:focus-visible + .method-card{outline:2px solid rgba(110,231,168,.6);outline-offset:2px}

.text-input{width:100%;background:rgba(0,0,0,.28);border:1px solid rgba(255,255,255,.14);border-radius:14px;color:#f5f6f8;font-family:'Geist',sans-serif;font-size:14px;padding:13px 16px;box-shadow:inset 0 2px 6px rgba(0,0,0,.3);box-sizing:border-box}

.status-badge{font-size:11px;font-weight:600;padding:4px 11px;border-radius:100px;text-align:center;display:inline-block}
.status-paid{color:#6ee7a8;background:rgba(110,231,168,.1);border:1px solid rgba(110,231,168,.3)}
.status-pending{color:#ffd76e;background:rgba(255,215,110,.1);border:1px solid rgba(255,215,110,.3)}
.status-rejected{color:#fda4af;background:rgba(253,164,175,.1);border:1px solid rgba(253,164,175,.3)}

.alert{border-radius:20px;padding:14px 20px;font-size:13.5px;margin-bottom:4px}
.alert-error{background:rgba(253,164,175,.1);border:1px solid rgba(253,164,175,.3);color:#fda4af}
.alert-success{background:rgba(110,231,168,.1);border:1px solid rgba(110,231,168,.3);color:#6ee7a8}

.badge-tile{border-radius:18px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.1);padding:16px 12px;display:flex;flex-direction:column;align-items:center;text-align:center;gap:6px}
.badge-tile.earned{background:rgba(110,231,168,.08);border-color:rgba(110,231,168,.3)}
.badge-tile.locked{opacity:.5}
.badge-icon{font-size:28px}
.badge-name{font-size:11.5px;font-weight:600;letter-spacing:-.01em}
.badge-progress{font-size:10px;color:rgba(235,240,250,.5);font-family:'Geist Mono',monospace}
.badge-progress.earned{color:#6ee7a8}

/* Custom tooltip — replaces native title="" attributes everywhere in the
   app (those render as ugly, unstyled OS tooltips). Usage: add
   data-tooltip="text" plus this class to any element. */
[data-tooltip]{position:relative}
[data-tooltip]::after{content:attr(data-tooltip);position:absolute;bottom:100%;left:50%;transform:translateX(-50%) translateY(-6px);background:rgba(20,22,32,.97);color:#f5f6f8;font-size:11px;font-weight:500;padding:6px 10px;border-radius:8px;white-space:nowrap;border:1px solid rgba(255,255,255,.13);box-shadow:0 8px 20px rgba(0,0,0,.4);opacity:0;pointer-events:none;transition:opacity .15s ease,transform .15s ease;z-index:80}
[data-tooltip]:hover::after{opacity:1;transform:translateX(-50%) translateY(-10px)}
/* Variant for elements near the top of a clipping (overflow:hidden/auto)
   ancestor, where an upward tooltip would get cut off — flips it below. */
[data-tooltip-below]::after{bottom:auto;top:100%;transform:translateX(-50%) translateY(6px)}
[data-tooltip-below]:hover::after{transform:translateX(-50%) translateY(10px)}

.legal-content h2{font-weight:700;font-size:18px;letter-spacing:-.02em;margin:28px 0 10px}
.legal-content h2:first-child{margin-top:0}
.legal-content p{font-size:14.5px;line-height:1.7;color:rgba(235,240,250,.6);margin:0 0 4px}

.admin-card{border-radius:24px;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.11);box-shadow:inset 0 1px 0 rgba(255,255,255,.16),0 14px 36px rgba(0,0,0,.3);padding:24px 26px;display:block;transition:transform .2s ease,border-color .2s ease}
.admin-card:hover{transform:translateY(-3px);border-color:rgba(255,255,255,.24)}
.admin-table{width:100%;border-collapse:collapse;font-size:13.5px}
.admin-table th{text-align:left;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:rgba(235,240,250,.45);padding:0 14px 12px;border-bottom:1px solid rgba(255,255,255,.1)}
.admin-table td{padding:14px;border-bottom:1px solid rgba(255,255,255,.07);color:rgba(235,240,250,.85)}
.admin-table tr:last-child td{border-bottom:none}
.admin-btn{font-size:12px;font-weight:600;padding:7px 14px;border-radius:100px;border:1px solid rgba(255,255,255,.15);background:rgba(255,255,255,.07);color:#f5f6f8;cursor:pointer;font-family:'Geist',sans-serif}
.admin-btn:hover{background:rgba(255,255,255,.12)}
.admin-btn-approve{border-color:rgba(110,231,168,.35);background:rgba(110,231,168,.1);color:#6ee7a8}
.admin-btn-approve:hover{background:rgba(110,231,168,.18)}
.admin-btn-reject,.admin-btn-delete{border-color:rgba(253,164,175,.35);background:rgba(253,164,175,.1);color:#fda4af}
.admin-btn-reject:hover,.admin-btn-delete:hover{background:rgba(253,164,175,.18)}
.admin-input{background:rgba(0,0,0,.28);border:1px solid rgba(255,255,255,.14);border-radius:10px;color:#f5f6f8;font-family:'Geist',sans-serif;font-size:12.5px;padding:7px 10px;box-sizing:border-box}

/* Mobile layout: below this width, the 1fr+fixed-sidebar page grids (chat
   rail, withdraw summary) collapse to a single column instead of squeezing
   the main content into a sliver — `1fr` has no minimum by default, so a
   fixed-width sibling column just keeps its size and starves the other. */
@media (max-width:900px){
  .mobile-stack-grid{grid-template-columns:1fr !important}
  .hero-decor{display:none !important}
  .mobile-static{position:static !important}
}

/* Sign-up page: a two-column pitch+form split with no mobile layout —
   both columns had fixed/large flex-basis values (640px, 520px) that
   don't fit a phone width and just fought each other for space, and the
   pitch column's logo/coin were absolutely positioned assuming a wide
   panel. Stack to one column and let the logo sit in normal flow. */
@media (max-width:900px){
  .auth-shell{flex-direction:column !important}
  .auth-pitch{
    flex:none !important;
    width:100% !important;
    box-sizing:border-box !important;
    margin:0 !important;
    padding:28px 20px 8px !important;
    justify-content:flex-start !important;
  }
  .auth-logo{position:static !important;margin-bottom:24px !important}
  .auth-form-panel{
    width:100% !important;
    box-sizing:border-box !important;
    margin:0 !important;
    padding:8px 20px 40px !important;
  }
}

@media (max-width:480px){
  /* Desktop hero cards use 52px 56px padding, which alone eats ~200px+ of
     a phone's width and forces the CTA button row to wrap mid-word. */
  .hero-card{padding:32px 24px !important}
  .hero-heading{font-size:34px !important;line-height:1.15 !important}
  /* A 26px gap between 4 stat items wraps to 2-3 rows at phone widths,
     inflating the hero card's height for no reason — tighten it up. */
  .stat-row{gap:14px !important}
}

@media (max-width:600px){
  /* Nav content (logo + links + admin pill + avatar + logout) is sized
     for desktop and doesn't fit a phone-width pill even trimmed down —
     it either clips off-canvas or reads as cramped/messy. Below this
     width only the logo, balance, and notif bell stay inline; the rest
     (links, admin, profile, logout) moves into the hamburger menu. The
     bell stays paired with the hamburger (not folded into it), reordered
     here so it sits directly beside it regardless of source order. */
  .nav-hide-mobile{display:none !important}
  #main-nav{padding:8px 6px 8px 16px !important}
  #main-nav .nav-left-cluster{gap:12px !important}
  #main-nav .nav-link{font-size:12px !important}
  #mobile-menu-toggle{display:flex !important}
  .nav-order-balance{order:1}
  .nav-order-bell{order:2}
  .nav-order-hamburger{order:3}

  /* The dropdown is a fixed 300px anchored right:0 to the bell — fine on
     desktop where the bell sits near the nav's right edge, but at this
     width that anchor point is nowhere near the actual right edge, so it
     overflowed off-screen to the left. Detach it from the bell entirely
     and give it the same viewport-margined treatment as the hamburger
     panel. */
  #notif-dropdown{
    position:fixed !important;
    top:76px !important;
    left:12px !important;
    right:12px !important;
    width:auto !important;
  }
}

.mobile-menu-link{display:block;padding:13px 14px;border-radius:14px;font-size:14px;font-weight:500;color:rgba(235,240,250,.8)}
.mobile-menu-link:hover{background:rgba(255,255,255,.06);color:#fff}
.mobile-menu-link.active{background:rgba(255,255,255,.1);color:#fff}
.mobile-menu-divider{height:1px;background:rgba(255,255,255,.09);margin:8px 6px}
.mobile-menu-label{display:flex;align-items:center;gap:8px;padding:8px 14px 4px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:rgba(235,240,250,.45)}
.mobile-menu-badge{font-size:9.5px;font-weight:700;color:#fff;background:linear-gradient(180deg,#ff6b81,#f43f5e);border-radius:100px;padding:1px 7px}

/* Chat rail: a desktop side panel, collapsed into a toggled bottom sheet
   below the stacked-grid breakpoint so it doesn't push page content down. */
@media (max-width:900px){
  #chat-toggle{display:flex !important}
  #chat-rail{
    display:none !important;
    position:fixed !important;
    top:auto !important;
    left:12px !important;
    right:12px !important;
    bottom:12px !important;
    height:min(70vh,560px) !important;
    z-index:85;
    box-shadow:0 -12px 50px rgba(0,0,0,.6) !important;
  }
  #chat-rail.chat-open{display:flex !important}
  #chat-backdrop.chat-open{display:block !important}
  #chat-close{display:flex !important}
  /* Without this, the toggle stays put behind the open panel and lands
     right on top of the send button in the same corner — reads as a
     duplicated chat bubble. */
  #chat-toggle.chat-open{display:none !important}
}

/* FAQ answers are rendered from admin-authored markdown (see
   services/markdown.js) rather than plain pre-wrapped text, so the tags it
   can produce need their own spacing/list styling here instead of relying
   on inline styles per element. */
.faq-answer p{margin:0 0 10px}
.faq-answer p:last-child{margin-bottom:0}
.faq-answer ul,.faq-answer ol{margin:0 0 10px;padding-left:20px}
.faq-answer li{margin-bottom:4px}
.faq-answer a{color:#a8c8ff}
.faq-answer code{background:rgba(255,255,255,.08);border-radius:4px;padding:1px 5px;font-size:12.5px;font-family:'Geist Mono',monospace}
.faq-answer pre{background:rgba(255,255,255,.05);border-radius:10px;padding:10px 12px;overflow-x:auto}
.faq-answer blockquote{margin:0 0 10px;padding-left:10px;border-left:2px solid rgba(255,255,255,.15);color:rgba(235,240,250,.55)}
