/* css/base.css - resets, typography, the aurora canvas, and the shared
   patterns every page uses: row lists, status chips, platform tiles,
   progress, panels. Page stylesheets only add what is specific to them. */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--header-height) + var(--space-4));
}

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
}

body {
  overflow-x: clip; /* full-bleed decorations never cause sideways scroll */
  background: var(--color-canvas);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-body);
  line-height: var(--leading-body);
  font-kerning: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* The aurora: three soft pools of color fixed behind the page, drifting
   slowly. One composited layer - it never repaints the content; the
   fixed frame (.aurora in index.html) clips it to the viewport. */
.aurora {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}
.aurora > i {
  position: absolute;
  inset: -20vmax;
  background:
    radial-gradient(38vmax 30vmax at 18% 12%, var(--aurora-pool-1), transparent 70%),
    radial-gradient(34vmax 28vmax at 86% 22%, var(--aurora-pool-2), transparent 70%),
    radial-gradient(40vmax 30vmax at 60% 96%, var(--aurora-pool-3), transparent 70%);
  animation: aurora-drift 26s ease-in-out infinite alternate;
  will-change: transform;
}
@keyframes aurora-drift {
  0% { transform: translate3d(0, 0, 0) rotate(0deg) scale(1); }
  50% { transform: translate3d(3vmax, -2vmax, 0) rotate(4deg) scale(1.06); }
  100% { transform: translate3d(-3vmax, 2vmax, 0) rotate(-3deg) scale(1.02); }
}
/* ── Type ─────────────────────────────────────────────────────────────── */

h1, h2, h3, h4 {
  color: var(--color-ink);
  font-weight: 700;
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}

h1 { font-size: var(--font-size-2xl); font-weight: 700; letter-spacing: -0.035em; margin: 0 0 var(--space-5); }
h2 { font-size: var(--font-size-lg); margin: var(--space-8) 0 var(--space-4); }
h3 { font-size: var(--font-size-base); margin: var(--space-5) 0 var(--space-2); }
h2:first-child, h3:first-child { margin-top: 0; }

p { text-wrap: pretty; }

strong, b { font-weight: var(--font-weight-strong); }

a {
  color: var(--color-accent);
  font-weight: 600;
  text-decoration: none;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
a:hover { text-decoration: underline; }

code {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.875em;
}

img, svg { max-width: 100%; display: block; }

button, input, select, textarea {
  font: inherit;
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
  border-radius: 6px;
}

::selection { background: color-mix(in srgb, var(--color-accent) 24%, transparent); }

/* The `hidden` attribute must win over component display rules. */
[hidden] { display: none !important; }

/* !important: form-field rules (.field input) must not size it back up. */
.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  margin: -1px !important;
  padding: 0 !important;
  overflow: hidden;
  border: 0 !important;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ── Row lists ────────────────────────────────────────────────────────── */
/* Every list of records is one hairline-bordered container with divided
   rows - a list is one object, so it gets one outline, not a stack of
   identical cards. Item classes keep their own inner layout. */

:is(.task-list, .campaign-list, .submission-list, .ledger-list, .notification-list,
    .referral-list, .report-list, .admin-user-list, .admin-report-list, .social-list,
    .activity-list, .home-task-list) {
  list-style: none;
  margin: 0 0 var(--space-5);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm), var(--highlight);
  overflow: hidden;
}

/* While a list is still empty (first load), show skeleton rows; once the
   page has rendered rows or an empty-state row this no longer matches.
   If loading failed (the error message after it is visible), hide it. */
:is(.task-list, .campaign-list, .submission-list, .ledger-list, .notification-list,
    .referral-list, .report-list, .admin-user-list, .admin-report-list,
    .home-task-list):empty {
  display: block;
  height: 216px;
  background:
    linear-gradient(90deg, transparent, var(--color-hover) 40%, transparent 80%) -60% 0 / 60% 100% no-repeat,
    repeating-linear-gradient(to bottom,
      transparent 0 20px, var(--color-tile) 20px 32px, transparent 32px 40px,
      var(--color-tile) 40px 48px, transparent 48px 71px, var(--color-border) 71px 72px)
      var(--space-4) 0 / 55% 100% no-repeat,
    var(--color-bg);
  animation: skeleton-sweep 1.4s ease-in-out infinite;
}
:is(.task-list, .campaign-list, .submission-list, .ledger-list, .notification-list,
    .referral-list, .report-list, .admin-user-list, .admin-report-list,
    .home-task-list):empty:has(~ .form-error:not([hidden])) { display: none; }
.social-list:empty, .activity-list:empty { display: none; }

@keyframes skeleton-sweep {
  to { background-position: 160% 0, var(--space-4) 0, 0 0; }
}

:is(.task-list, .campaign-list, .submission-list, .ledger-list, .notification-list,
    .referral-list, .report-list, .admin-user-list, .admin-report-list, .social-list,
    .activity-list, .home-task-list) > li {
  margin: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  animation: row-in 460ms var(--ease-out) both;
}

/* Rows arrive one after another - the first ten, then the rest at once. */
:is(.task-list, .campaign-list, .submission-list, .ledger-list, .notification-list,
    .referral-list, .report-list, .admin-user-list, .admin-report-list, .social-list,
    .activity-list, .home-task-list) > li:nth-child(n) { animation-delay: 300ms; }
:is(.task-list, .campaign-list, .submission-list, .ledger-list, .notification-list,
    .referral-list, .report-list, .admin-user-list, .admin-report-list, .social-list,
    .activity-list, .home-task-list) > li:nth-child(1) { animation-delay: 0ms; }
:is(.task-list, .campaign-list, .submission-list, .ledger-list, .notification-list,
    .referral-list, .report-list, .admin-user-list, .admin-report-list, .social-list,
    .activity-list, .home-task-list) > li:nth-child(2) { animation-delay: 35ms; }
:is(.task-list, .campaign-list, .submission-list, .ledger-list, .notification-list,
    .referral-list, .report-list, .admin-user-list, .admin-report-list, .social-list,
    .activity-list, .home-task-list) > li:nth-child(3) { animation-delay: 70ms; }
:is(.task-list, .campaign-list, .submission-list, .ledger-list, .notification-list,
    .referral-list, .report-list, .admin-user-list, .admin-report-list, .social-list,
    .activity-list, .home-task-list) > li:nth-child(4) { animation-delay: 105ms; }
:is(.task-list, .campaign-list, .submission-list, .ledger-list, .notification-list,
    .referral-list, .report-list, .admin-user-list, .admin-report-list, .social-list,
    .activity-list, .home-task-list) > li:nth-child(5) { animation-delay: 140ms; }
:is(.task-list, .campaign-list, .submission-list, .ledger-list, .notification-list,
    .referral-list, .report-list, .admin-user-list, .admin-report-list, .social-list,
    .activity-list, .home-task-list) > li:nth-child(6) { animation-delay: 175ms; }
:is(.task-list, .campaign-list, .submission-list, .ledger-list, .notification-list,
    .referral-list, .report-list, .admin-user-list, .admin-report-list, .social-list,
    .activity-list, .home-task-list) > li:nth-child(7) { animation-delay: 210ms; }
:is(.task-list, .campaign-list, .submission-list, .ledger-list, .notification-list,
    .referral-list, .report-list, .admin-user-list, .admin-report-list, .social-list,
    .activity-list, .home-task-list) > li:nth-child(8) { animation-delay: 245ms; }

@keyframes row-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

:is(.task-list, .campaign-list, .submission-list, .ledger-list, .notification-list,
    .referral-list, .report-list, .admin-user-list, .admin-report-list, .social-list,
    .activity-list, .home-task-list) > li + li {
  border-top: 1px solid var(--color-border);
}

/* Empty-state rows: an invitation to act, not a dead end. */
:is(.task-list__empty, .campaign-list__empty, .submission-list__empty, .ledger-item--empty,
    .notification-list__empty, .social-list__empty, .home-task-list__empty) {
  padding: var(--space-5) var(--space-4);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* ── Status chips ─────────────────────────────────────────────────────── */
/* Neutral pill + a 6px dot in the status color. Modifiers only set --dot
   (in each page stylesheet). Labels are shown in sentence case. */

:is(.campaign-status, .submission-status, .referral-item__status, .report-item__status,
    .admin-report-status, .admin-user-status, .admin-user-role) {
  --dot: var(--color-text-subtle);
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex-shrink: 0;
  padding: 3px 11px 3px 9px;
  background: color-mix(in srgb, var(--dot) 12%, var(--color-bg));
  color: var(--color-ink);
  border: 1px solid color-mix(in srgb, var(--dot) 26%, transparent);
  border-radius: var(--radius-pill);
  font-size: var(--font-size-xs);
  font-weight: 700;
  line-height: 1.6;
  letter-spacing: 0;
  /* Values are single words ("open", "admin") - capitalize = sentence case. */
  text-transform: capitalize;
  white-space: nowrap;
}

:is(.campaign-status, .submission-status, .referral-item__status, .report-item__status,
    .admin-report-status, .admin-user-status, .admin-user-role)::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--dot);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--dot) 22%, transparent), 0 0 10px var(--dot);
}

/* Things still waiting pulse; settled ones sit still. */
:is(.campaign-status--active, .submission-status--pending, .admin-report-status--open,
    .referral-item__status--pending)::before {
  animation: dot-pulse 1.8s ease-out infinite;
}
@keyframes dot-pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--dot) 55%, transparent), 0 0 10px var(--dot); }
  70%, 100% { box-shadow: 0 0 0 7px transparent, 0 0 10px var(--dot); }
}

/* ── Page shells ──────────────────────────────────────────────────────── */
/* Every page reads at the same comfortable width, left-aligned. */

:is(.tasks-page, .task-detail-page, .campaigns-page, .campaign-new-page, .campaign-detail-page,
    .submissions-page, .review-queue-page, .credits-page, .notifications-page, .achievements-page,
    .referrals-page, .reports-page, .profile-page) {
  max-width: var(--content-width);
}

:is(.admin-page, .admin-user-page, .admin-reports-page) { max-width: 880px; }

/* Title + one action on the same line (My campaigns / New campaign). */
:is(.campaigns-page__header, .notifications-page__header) {
  display: flex;
  flex-wrap: wrap; /* a long title (Georgian, Russian) pushes the action below */
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3) var(--space-4);
  margin-bottom: var(--space-5);
}
:is(.campaigns-page__header, .notifications-page__header) h1 { margin: 0; }

/* Intro line under a page title. */
:is(.page-intro, .review-queue__intro, .campaign-new__intro, .task-detail__meta, .campaign-detail__meta) {
  margin: calc(var(--space-3) * -1) 0 var(--space-5);
  color: var(--color-text-muted);
}

/* Filter rows above lists. */
:is(.tasks-filter, .submissions-filter, .admin-reports-filter) {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3);
  max-width: none;
  margin-bottom: var(--space-5);
}
:is(.tasks-filter, .submissions-filter) .field { flex: 1 1 140px; max-width: 260px; }

/* ── Stat panels ──────────────────────────────────────────────────────── */
/* <dl> summaries: label left, value right, one hairline per row - the
   same reading as the credit ledger. */

:is(.profile-stats, .profile-view__stats, .credits-summary,
    .campaign-detail__stats, .admin-user-detail__meta) {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  margin: 0 0 var(--space-6);
  padding: 0;
  overflow: hidden;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm), var(--highlight);
  font-size: var(--font-size-sm);
}
:is(.profile-stats, .profile-view__stats, .credits-summary,
    .campaign-detail__stats, .admin-user-detail__meta):empty { display: none; }

:is(.profile-stats, .profile-view__stats, .credits-summary,
    .campaign-detail__stats, .admin-user-detail__meta) :is(dt, dd) {
  margin: 0;
  padding: 12px var(--space-4);
  border-top: 1px solid var(--color-border);
}

:is(.profile-stats, .profile-view__stats, .credits-summary,
    .campaign-detail__stats, .admin-user-detail__meta) :is(dt:first-of-type, dt:first-of-type + dd) {
  border-top: 0;
}

:is(.profile-stats, .profile-view__stats, .credits-summary,
    .campaign-detail__stats, .admin-user-detail__meta) dt {
  color: var(--color-text-muted);
  font-weight: 500;
  white-space: normal;
}

:is(.profile-stats, .profile-view__stats, .credits-summary,
    .campaign-detail__stats, .admin-user-detail__meta) dd {
  color: var(--color-ink);
  font-weight: 700;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Tabular figures wherever credits are shown, so columns line up. */
:is(.task-card__reward, .task-detail__reward, .ledger-amount, .credits-balance,
    .credits-summary dd, .admin-stat-tile__value, .home-stat__value, .app-nav__credits) {
  font-variant-numeric: tabular-nums;
}

/* ── Script-specific type ────────────────────────────────────────────── */
/* Georgian (Mkhedruli) has tall ascenders and descenders and no capitals,
   so headings get looser leading and lighter negative tracking than the
   Latin settings above; Cyrillic only needs a touch less tracking. */
:lang(ka) :is(h1, h2, h3) { line-height: 1.2; letter-spacing: -0.01em; }
:lang(ru) :is(h1, h2) { letter-spacing: -0.025em; }

/* Until core/language.js has translated the shell, a non-English visit
   stays hidden so English doesn't flash first (theme-init.js sets
   data-i18n="pending"). If scripts never run, the page shows anyway. */
:root[data-i18n="pending"] body { opacity: 0; animation: i18n-reveal 0s linear 1.6s forwards; }
@keyframes i18n-reveal { to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .aurora > i { animation: none; }
}

/* ── Icons ────────────────────────────────────────────────────────────── */
/* UI icons inherit stroke settings from here (sprite symbols set none);
   platform logos carry their own solid fill. */

.icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.icon {
  flex-shrink: 0;
  display: inline-block;
  vertical-align: middle;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ── Platform tiles + avatars ─────────────────────────────────────────── */

.platform-tile {
  --brand: var(--gradient-brand);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: 14px;
  background: var(--brand);
  color: #ffffff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 8px 18px -10px var(--brand-glow, var(--color-glow));
  transition: transform 320ms var(--ease-spring);
}
.platform-tile--sm { width: 36px; height: 36px; border-radius: 11px; }
.platform-tile--lg { width: 52px; height: 52px; border-radius: 16px; }

/* Each platform in its own colors. */
.platform-tile--instagram { --brand: linear-gradient(45deg, #f9a825 0%, #e1306c 50%, #8134af 100%); --brand-glow: rgba(225, 48, 108, 0.55); }
.platform-tile--tiktok { --brand: linear-gradient(135deg, #111018 60%, #25f4ee 60% 66%, #111018 66% 80%, #fe2c55 80%); --brand-glow: rgba(254, 44, 85, 0.45); }
.platform-tile--youtube { --brand: linear-gradient(160deg, #ff3b30, #d90012); --brand-glow: rgba(255, 0, 0, 0.45); }
.platform-tile--facebook { --brand: linear-gradient(160deg, #3b8bff, #0a5ce0); --brand-glow: rgba(24, 119, 242, 0.5); }
.platform-tile--x { --brand: linear-gradient(160deg, #2b2b35, #000000); --brand-glow: rgba(0, 0, 0, 0.45); }
.platform-tile--telegram { --brand: linear-gradient(160deg, #3fc0f0, #1f8fd6); --brand-glow: rgba(38, 165, 228, 0.5); }
.platform-tile--discord { --brand: linear-gradient(160deg, #7984ff, #4f5bdc); --brand-glow: rgba(88, 101, 242, 0.5); }
.platform-tile--twitch { --brand: linear-gradient(160deg, #a970ff, #7a3ff0); --brand-glow: rgba(145, 70, 255, 0.5); }
.platform-tile--reddit { --brand: linear-gradient(160deg, #ff6a2b, #ff3d00); --brand-glow: rgba(255, 69, 0, 0.5); }
.platform-tile--pinterest { --brand: linear-gradient(160deg, #f0283b, #c50f23); --brand-glow: rgba(230, 0, 35, 0.45); }
.platform-tile--linkedin { --brand: linear-gradient(160deg, #1f86d6, #0a5ea8); --brand-glow: rgba(10, 102, 194, 0.5); }
:root[data-theme="dark"] .platform-tile--x { --brand: linear-gradient(160deg, #3a3a48, #15151c); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12); }
:root[data-theme="dark"] .platform-tile--tiktok { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12); }

/* A row's tile pops when the row is pointed at. */
a:hover > .platform-tile,
:is(.task-card, .submission-card, .campaign-card):hover .platform-tile { transform: rotate(-6deg) scale(1.08); }

.avatar {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--gradient-brand);
  color: var(--color-on-gradient);
  box-shadow: 0 0 0 2px var(--color-bg), 0 0 0 3.5px color-mix(in srgb, var(--aurora-2) 45%, transparent);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.avatar--sm { width: 28px; height: 28px; font-size: 0.6875rem; }
.avatar--lg { width: 56px; height: 56px; font-size: 1.125rem; }
.avatar--xl { width: 96px; height: 96px; font-size: 1.75rem; }
.avatar--photo { background: var(--color-tile); }
.avatar__img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}
/* The green "online" dot, with a soft ring that breathes. */
.avatar__online {
  position: absolute;
  right: -1px;
  bottom: -1px;
  width: 30%;
  min-width: 10px;
  max-width: 18px;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--color-success);
  box-shadow: 0 0 0 2.5px var(--color-bg);
}
.avatar__online::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--color-success);
  animation: online-ring 2.4s var(--ease-out) infinite;
}
@keyframes online-ring { 0% { transform: scale(1); opacity: 0.55; } 70%, 100% { transform: scale(2.4); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .avatar__online::after { animation: none; } }

/* ── Badges ───────────────────────────────────────────────────────────── */

.nav-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  margin-left: auto;
  padding: 0 7px;
  border-radius: var(--radius-pill);
  background: var(--gradient-brand);
  color: var(--color-on-gradient);
  box-shadow: 0 4px 12px -4px var(--color-glow);
  font-size: 0.71875rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  animation: badge-in 420ms var(--ease-spring) both;
}
@keyframes badge-in { from { transform: scale(0.4); opacity: 0; } }
.nav-badge--dot {
  position: absolute;
  top: 8px;
  right: calc(50% - 17px);
  min-width: 10px;
  width: 10px;
  height: 10px;
  padding: 0;
  margin: 0;
  background: var(--aurora-3);
  box-shadow: 0 0 0 2.5px var(--color-bg);
  animation: badge-in 420ms var(--ease-spring) both, dot-ring 2s ease-out 600ms infinite;
}
@keyframes dot-ring {
  0% { box-shadow: 0 0 0 2.5px var(--color-bg), 0 0 0 2.5px color-mix(in srgb, var(--aurora-3) 60%, transparent); }
  70%, 100% { box-shadow: 0 0 0 2.5px var(--color-bg), 0 0 0 10px transparent; }
}

/* ── Visitor / member visibility (html[data-auth]) ────────────────────── */

:root[data-auth="in"] .visitor-only,
:root:not([data-auth="in"]) .member-only { display: none !important; }

/* ── Empty states ─────────────────────────────────────────────────────── */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-6) var(--space-5);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}
.empty-state > .icon {
  box-sizing: content-box;
  padding: 12px;
  margin-bottom: var(--space-2);
  border-radius: 16px;
  background: var(--gradient-soft);
  color: var(--color-accent);
  box-shadow: inset 0 0 0 1px var(--color-border);
  animation: float-y 3.2s ease-in-out infinite;
}
@keyframes float-y { 50% { transform: translateY(-4px); } }
.empty-state strong { color: var(--color-ink); font-size: 1.0625rem; font-weight: 700; }
.empty-state p { margin: 0; max-width: 46ch; }
.empty-state .btn { margin-top: var(--space-2); }

/* ── Skip link ────────────────────────────────────────────────────────── */

.skip-link {
  position: absolute;
  left: var(--space-3);
  top: -100px;
  z-index: 100;
  padding: var(--space-2) var(--space-3);
  background: var(--gradient-brand);
  color: var(--color-on-gradient);
  border-radius: var(--radius-sm);
}
.skip-link:focus { top: var(--space-3); }

/* ── Page enter ───────────────────────────────────────────────────────── */
/* The router swaps #app-root's children; each new page arrives in a short
   cascade - its blocks rise one after another. */

.app-main > * { animation: page-in 420ms var(--ease-out) both; }
.app-main > * > :nth-child(1) { animation: block-in 520ms var(--ease-out) 40ms both; }
.app-main > * > :nth-child(2) { animation: block-in 520ms var(--ease-out) 90ms both; }
.app-main > * > :nth-child(3) { animation: block-in 520ms var(--ease-out) 140ms both; }
.app-main > * > :nth-child(4) { animation: block-in 520ms var(--ease-out) 190ms both; }
.app-main > * > :nth-child(5) { animation: block-in 520ms var(--ease-out) 240ms both; }
.app-main > * > :nth-child(n + 6) { animation: block-in 520ms var(--ease-out) 290ms both; }

@keyframes page-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes block-in {
  from { opacity: 0; transform: translateY(14px) scale(0.985); filter: blur(3px); }
  to { opacity: 1; transform: none; filter: none; }
}

/* ── Row parts ────────────────────────────────────────────────────────── */

/* Credits to earn: a gradient coin and a tinted pill - money is the one
   thing that always carries the gradient. */
.reward-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  height: 30px;
  padding: 0 11px 0 6px;
  border-radius: var(--radius-pill);
  background: var(--gradient-soft), var(--color-bg);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--aurora-1) 22%, transparent);
  color: var(--color-accent-strong);
  font-size: var(--font-size-sm);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
:root[data-theme="dark"] .reward-chip { color: var(--color-accent-strong); }
.reward-chip::before {
  content: "";
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 35% 30%, rgba(255, 255, 255, 0.7) 0 2px, transparent 3px),
    radial-gradient(circle, transparent 0 4px, rgba(255, 255, 255, 0.55) 4.5px 5.5px, transparent 6px),
    var(--gradient-brand);
  box-shadow: 0 2px 6px -1px var(--color-glow);
}
a:hover .reward-chip::before,
.task-card:hover .reward-chip::before { animation: coin-flip 700ms var(--ease-out); }
@keyframes coin-flip { 50% { transform: rotateY(180deg) scale(1.1); } }

/* Leading icon tile for rows without a platform (ledger, notifications).
   --tone sets its color; the accent by default. */
.row-icon {
  --tone: var(--color-accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: 13px;
  background: color-mix(in srgb, var(--tone) 13%, var(--color-bg));
  color: var(--tone);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tone) 22%, transparent);
  transition: transform 320ms var(--ease-spring);
}
a:hover > .row-icon { transform: rotate(-6deg) scale(1.08); }
.row-icon--success { --tone: var(--color-success); }
.row-icon--danger { --tone: var(--color-danger); }
.row-icon--warning { --tone: var(--color-warning); }
.row-icon--brand {
  background: var(--gradient-brand);
  color: var(--color-on-gradient);
  box-shadow: 0 8px 18px -10px var(--color-glow);
}

.row-chevron {
  color: var(--color-text-subtle);
  transition: transform var(--transition-fast), color var(--transition-fast);
}
a:hover > .row-chevron { color: var(--color-accent); transform: translateX(4px); }

/* Progress track (campaign completions, level XP): a gradient bar that
   fills in when it appears, with a light sweeping along it. */
.progress {
  display: block;
  height: 8px;
  overflow: hidden;
  border-radius: var(--radius-pill);
  background: var(--color-tile);
  box-shadow: inset 0 0 0 1px var(--color-border);
}
.progress__bar {
  position: relative;
  display: block;
  height: 100%;
  min-width: 8px;
  overflow: hidden;
  border-radius: inherit;
  background: var(--gradient-brand);
  box-shadow: 0 0 12px -2px var(--color-glow);
  transform-origin: left center;
  animation: bar-fill 1100ms var(--ease-out) 200ms both;
}
.progress__bar::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 20%, rgba(255, 255, 255, 0.55) 50%, transparent 80%);
  transform: translateX(-100%);
  animation: bar-sheen 2.6s ease-in-out 1.3s infinite;
}
@keyframes bar-fill { from { transform: scaleX(0); } }
@keyframes bar-sheen { 60%, 100% { transform: translateX(100%); } }

/* ── Panels ───────────────────────────────────────────────────────────── */
/* Raised containers for summaries (dashboard cards, credits balance). */

.panel {
  padding: 22px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-bg);
  box-shadow: var(--shadow-sm), var(--highlight);
}

.panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.panel__head h2 { margin: 0; font-size: 1.0625rem; font-weight: 700; letter-spacing: -0.01em; }
.panel__head a { font-size: 0.84375rem; font-weight: 700; }

.panel__label {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--color-text-muted);
  font-size: 0.875rem;
  font-weight: 600;
}
.panel__label .icon { color: var(--color-accent); }

/* ── Confetti (js/shared/motion.js celebrate()) ───────────────────────── */

.confetti {
  position: fixed;
  z-index: 200;
  width: 0;
  height: 0;
  pointer-events: none;
}
.confetti > i {
  position: absolute;
  left: -4px;
  top: -6px;
  width: 8px;
  height: 12px;
  border-radius: 2px;
  opacity: 0;
  animation: confetti-burst 1200ms cubic-bezier(0.15, 0.7, 0.3, 1) var(--d, 0ms) forwards;
}
@keyframes confetti-burst {
  0% { opacity: 1; transform: translate(0, 0) rotate(0) scale(0.6); }
  70% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--x), calc(var(--y) + 90px)) rotate(var(--r)) scale(1); }
}
