/* Payee — design tokens, components and motion.
   The palette is driven by two RGB triples per theme so Tailwind can apply
   any opacity to them (text-primary/45, bg-primary/[0.06], and so on). */

:root {
  --background: 255 255 255;
  --background-hover: 10 10 10;
  --primary: 10 10 10;
  --secondary: 110 110 110;
  --card: 250 250 250;
  --border: 232 232 232;
  --accent: 199 24 110;
  --success: 22 163 96;
  --warning: 191 133 0;
  color-scheme: light;
}

.dark {
  --background: 10 10 10;
  --background-hover: 255 255 255;
  --primary: 255 255 255;
  --secondary: 138 138 138;
  --card: 20 20 20;
  --border: 33 33 33;
  --accent: 224 52 140;
  --success: 52 199 123;
  --warning: 240 175 60;
  color-scheme: dark;
}

html, body { background: rgb(var(--background)); color: rgb(var(--primary)); }
body { -webkit-font-smoothing: antialiased; }

/* Figures line up in columns everywhere money is shown. */
.money-figure { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

/* ---- buttons ------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  height: 2.25rem; border-radius: 9999px;
  font-size: 13px; font-weight: 500; white-space: nowrap;
  transition: background-color .15s ease, color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.btn-primary {
  display: inline-flex; align-items: center; justify-content: center;
  height: 2.75rem; padding: 0 1.4rem; border-radius: 9999px;
  background: rgb(var(--primary)); color: rgb(var(--background));
  font-size: 15px; font-weight: 500;
  transition: transform .2s cubic-bezier(.22,1,.36,1), box-shadow .2s ease;
}
.btn-primary:hover { transform: translateY(-1px); box-shadow: 0 8px 24px rgb(var(--primary) / .18); }
.btn-outline {
  display: inline-flex; align-items: center; justify-content: center;
  gap: .5rem;
  height: 2.75rem; padding: 0 1.4rem; border-radius: 9999px;
  border: 1px solid rgb(var(--primary) / .12); color: rgb(var(--primary));
  font-size: 15px; font-weight: 500;
  transition: background-color .15s ease, border-color .15s ease;
}
.btn-outline:hover { background: rgb(var(--card)); border-color: rgb(var(--primary) / .25); }

/* A slow sheen that crosses the filled button. */
.btn-glow { position: relative; overflow: hidden; isolation: isolate; }
.btn-glow::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(105deg, transparent 40%, rgb(255 255 255 / .22) 50%, transparent 60%);
  transform: translateX(-100%);
  animation: btn-sheen 4.5s cubic-bezier(.22,1,.36,1) infinite;
}
@keyframes btn-sheen { 0%, 62% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }

/* A dot that travels the border of the outlined button. */
.btn-orbit { position: relative; }
.btn-orbit::before {
  content: ""; position: absolute; inset: -1px; border-radius: inherit; padding: 1px;
  background: conic-gradient(from var(--orbit, 0deg), transparent 0deg, rgb(var(--accent) / .85) 26deg, transparent 52deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  opacity: 0; transition: opacity .2s ease;
  animation: btn-orbit-spin 3.2s linear infinite;
}
.btn-orbit:hover::before { opacity: 1; }
@property --orbit { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
@keyframes btn-orbit-spin { to { --orbit: 360deg; } }

/* ---- entrances ----------------------------------------------------------- */

@keyframes card-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes fade-slide-up { from { opacity: 0; transform: translateY(0.38em); } to { opacity: 1; transform: none; } }
@keyframes section-in { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }

.animate-card-in { animation: card-in .5s cubic-bezier(.22,1,.36,1) both; }
.animate-fade-slide-up { animation: fade-slide-up .6s cubic-bezier(.22,1,.36,1) both; }
.animate-section-in { animation: section-in .6s cubic-bezier(.22,1,.36,1) both; }

/* ---- ambient loops in the four overview cards ---------------------------- */

/* Merchants: the tile wall drifts diagonally and wraps seamlessly. */
@keyframes diag-pan { from { transform: translate3d(0,0,0); } to { transform: translate3d(-50%, -50%, 0); } }
.animate-diag-pan { animation: diag-pan 46s linear infinite; }

/* Analytics: the timeframe label steps 1D / 7D / 30D / All. */
@keyframes timeframe-label {
  0%, 20%   { transform: translateY(0); }
  25%, 45%  { transform: translateY(-1rem); }
  50%, 70%  { transform: translateY(-2rem); }
  75%, 95%  { transform: translateY(-3rem); }
  100%      { transform: translateY(0); }
}
.animate-timeframe-label { animation: timeframe-label 12s steps(1, end) infinite; }

/* …and the series redraws from the right each time it switches. */
@keyframes chart-timeframe {
  0%, 4%    { transform: scaleX(.18); opacity: .35; }
  18%, 22%  { transform: scaleX(1); opacity: 1; }
  25%       { transform: scaleX(.18); opacity: .35; }
  43%, 47%  { transform: scaleX(1); opacity: 1; }
  50%       { transform: scaleX(.18); opacity: .35; }
  68%, 72%  { transform: scaleX(1); opacity: 1; }
  75%       { transform: scaleX(.18); opacity: .35; }
  93%, 100% { transform: scaleX(1); opacity: 1; }
}
.animate-chart-timeframe { animation: chart-timeframe 12s cubic-bezier(.22,1,.36,1) infinite; }

/* Launch: two scenes alternate — pick a website, then check it live. */
@keyframes scene-pick { 0%, 42% { opacity: 1; } 48%, 94% { opacity: 0; } 100% { opacity: 1; } }
@keyframes scene-send { 0%, 42% { opacity: 0; } 48%, 94% { opacity: 1; } 100% { opacity: 0; } }
.animate-scene-pick { animation: scene-pick 11s ease-in-out infinite; }
.animate-scene-send { animation: scene-send 11s ease-in-out infinite; }

/* The query types itself out, character by character. */
@keyframes type-query { from { width: 0; } to { width: var(--type-w); } }
.animate-type-query { animation: type-query 1.6s steps(var(--type-steps)) .3s both; }
@keyframes type-caret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
.animate-type-caret { animation: type-caret 1s steps(1, end) infinite; }
@keyframes pick-match {
  0%, 26%  { background: transparent; }
  32%, 42% { background: rgb(var(--primary) / .06); }
  48%,100% { background: transparent; }
}
.animate-pick-match { animation: pick-match 11s ease-in-out infinite; }
@keyframes send-confirm { 0%, 62% { opacity: 0; } 70%, 92% { opacity: 1; } 100% { opacity: 0; } }
.animate-send-confirm { animation: send-confirm 11s ease-in-out infinite; }

/* Docs: the spec sheet scrolls slowly and repeats. */
@keyframes spec-drift { from { transform: translateY(0); } to { transform: translateY(-50%); } }
.animate-spec-drift { animation: spec-drift 26s linear infinite; }

/* ---- reduced motion ------------------------------------------------------ */
/* Every ambient loop is decorative, so it stands down entirely. Entrances
   resolve to their finished state rather than replaying. */
@media (prefers-reduced-motion: reduce) {
  .motion-loop, .motion-loop * { animation: none !important; }
  .animate-card-in, .animate-fade-slide-up, .animate-section-in { animation: none !important; opacity: 1 !important; transform: none !important; }
  .btn-glow::after, .btn-orbit::before { animation: none !important; }
  .animate-type-query { width: var(--type-w) !important; }
}

/* ---- misc ---------------------------------------------------------------- */

.ease-decel { transition-timing-function: cubic-bezier(.22,1,.36,1); }
:focus-visible { outline: 2px solid rgb(var(--accent)); outline-offset: 2px; border-radius: 4px; }
::selection { background: rgb(var(--accent) / .28); }
.no-scrollbar::-webkit-scrollbar { display: none; }
.no-scrollbar { scrollbar-width: none; }

/* ---- the mobile drawer -----------------------------------------------------
   Below the nav breakpoint the sidebar is display:none and its labels are held
   back until xl. When the menu button opens it as a drawer, it needs the full
   width and the labels the wide layout would have given it. */
#sidebar[data-open] {
  display: block;
  position: fixed;
  inset-block: 0;
  left: 0;
  width: 275px;
  animation: drawer-in 220ms cubic-bezier(.22, 1, .36, 1) both;
}
#sidebar[data-open] > #sidebar-inner { width: 275px; }
#sidebar[data-open] #nav-list .hidden { display: inline; }
#sidebar[data-open] #sidebar-inner > div:last-child .hidden { display: flex; }
#sidebar[data-open] [data-copy] > span:last-child { display: inline-flex; }
#sidebar[data-open] ~ #sidebar-toggle,
#sidebar[data-open] #sidebar-toggle { display: none; }

#sidebar-scrim {
  position: fixed;
  inset: 0;
  z-index: 55;
  background: rgb(0 0 0 / 0.5);
  backdrop-filter: blur(2px);
  animation: fade-in 220ms ease both;
}

@keyframes drawer-in { from { transform: translateX(-100%); } to { transform: none; } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  #sidebar[data-open], #sidebar-scrim { animation: none; }
}

/* ---- the cookie gate -------------------------------------------------------
   Resolved before first paint by the inline script in the head: the page is
   never briefly readable behind it, and people who have already chosen never
   see it flash. */
#cookie-gate { display: none; }

html.needs-consent { overflow: hidden; }
html.needs-consent #cookie-gate,
#cookie-gate[data-open] {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgb(var(--background) / 0.72);
  backdrop-filter: blur(14px) saturate(120%);
  animation: fade-in 220ms ease both;
}

.cookie-panel {
  width: 100%;
  max-width: 30rem;
  max-height: calc(100svh - 32px);
  overflow-y: auto;
  padding: 28px;
  border-radius: 24px;
  border: 1px solid rgb(var(--border));
  background: rgb(var(--card));
  box-shadow: 0 30px 80px -20px rgb(0 0 0 / 0.5);
  animation: gate-in 320ms cubic-bezier(.22, 1, .36, 1) both;
}

@keyframes gate-in { from { opacity: 0; transform: translateY(12px) scale(.985); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  #cookie-gate, .cookie-panel { animation: none; }
}

/* ---- the wallet picker ------------------------------------------------------ */
#wallet-modal[hidden] { display: none; }
html.modal-open { overflow: hidden; }
#wallet-modal {
  position: fixed;
  inset: 0;
  z-index: 190;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgb(var(--background) / 0.7);
  backdrop-filter: blur(10px);
  animation: fade-in 180ms ease both;
}
.wallet-sheet {
  width: 100%;
  max-width: 24rem;
  max-height: calc(100svh - 32px);
  display: flex;
  flex-direction: column;
  border-radius: 24px;
  border: 1px solid rgb(var(--border));
  background: rgb(var(--card));
  box-shadow: 0 30px 80px -20px rgb(0 0 0 / 0.5);
  animation: gate-in 260ms cubic-bezier(.22, 1, .36, 1) both;
}
@media (prefers-reduced-motion: reduce) {
  #wallet-modal, .wallet-sheet { animation: none; }
}
