/*
 * affiliates.css: page layer for /affiliates, /affiliates/dashboard and the 404 page.
 * Layout comes from orbio's own classes (orbio.css); this file only adds the PonModel touches that orbio's
 * light theme had no equivalent for, and the few things our dark canvas needs.
 */

/* ------------------------------------------------------------------ hero */

/* the lava band sits a little lower and warmer than the home one: the copy column is on the left and the
   relay image on the right, so the big dark pool follows the copy and a smaller one calms the lava right
   behind the render (--aff-pool: under the image on phones, where it sits below the copy) */
.aff-lava {
  background:
    radial-gradient(ellipse 30% 34% at var(--aff-pool, 69% 52%), rgba(11, 9, 8, .78) 30%, transparent 100%),
    radial-gradient(ellipse 58% 60% at 30% 42%, rgba(11, 9, 8, .96) 24%, rgba(11, 9, 8, .78) 56%, rgba(11, 9, 8, .5) 100%),
    linear-gradient(to bottom, rgba(11, 9, 8, .3) 0%, rgba(11, 9, 8, .12) 34%, rgba(11, 9, 8, .62) 76%, var(--pm-bg) 100%),
    url(/assets/img/lava.webp) center 30% / cover no-repeat,
    var(--pm-bg);
}
@media (max-width: 47.99rem) { .aff-lava { --aff-pool: 50% 84%; } }

/* the highlighted words never split across lines: on a 320px phone "on repeat." would break inside the
   neon block and leave dark text on the dark page */
.affiliate-landing h1 .marker { white-space: nowrap; }

/* the band drifts slowly, standing in for orbio's live dither-wave canvas (still for reduced motion). It
   grows from its bottom edge, which is already the page colour, so the seam into the steps never shows. */
@media (prefers-reduced-motion: no-preference) {
  .aff-lava { transform-origin: 50% 100%; animation: aff-lava-drift 44s ease-in-out infinite alternate; will-change: transform; }
}
@keyframes aff-lava-drift {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to { transform: scale(1.05) translate3d(-1.2%, -.4%, 0); }
}

/* the relay render is orbio's framed card (w-full rounded-2xl): its near-black backdrop reads as a dark tile on
   the lava, edged with a hairline and a soft molten glow, like orbio's white card on its marble */
.aff-relay {
  background: var(--pm-bg-2);
  box-shadow: 0 0 0 1px var(--pm-line-strong), 0 24px 60px -28px rgba(0, 0, 0, .9), 0 0 40px -12px rgba(250, 109, 1, .22);
}

/* the header mark sits over the glowing pillar capitals between 390 and 1024px: a small dark pool behind it
   keeps its orange outline readable */
.affiliate-landing header .pm-mark {
  border-radius: 50%;
  background: radial-gradient(circle, rgba(11, 9, 8, .92) 45%, rgba(11, 9, 8, .6) 62%, transparent 72%);
}

/* ring pillars: orbio masks at 82%; the obsidian render is lifted a little and rim lit in orange so the
   whole shaft reads on the dark canvas, not only the glowing ring */
.aff-pillar {
  filter: brightness(1.9) contrast(1.08) drop-shadow(0 0 1px rgba(255, 138, 43, .55)) drop-shadow(0 0 16px rgba(250, 109, 1, .18)) drop-shadow(0 24px 40px rgba(0, 0, 0, .55));
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 82%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 82%, transparent 100%);
}
/* orbio fades its phone pillars to 60% on white; on our dark canvas that loses the shaft, so keep more */
@media (max-width: 39.99rem) { .affiliate-landing [data-aff-pillar] { opacity: .85; } }

/* the landing header on the narrowest phones: our name is wider than orbio's, so the two links tighten a
   little and the row stays one line down to 320 */
@media (max-width: 399.98px) { .aff-nav-links { gap: .75rem; font-size: 13px; } }

/* signed in, the account chip joins the header (after the links). On phones there is no room for all four on
   one line: the brand and the chip share the first row and the two links run right-aligned under them (the
   header stays inside the hero's top padding) */
.aff-nav-chip { flex: none; }
@media (max-width: 39.99rem) {
  .affiliate-landing header nav:has(> .aff-nav-chip:not([hidden])) { row-gap: 10px; }
  .affiliate-landing header nav:has(> .aff-nav-chip:not([hidden])) > .aff-nav-chip { order: 1; margin-left: auto; }
  .affiliate-landing header nav:has(> .aff-nav-chip:not([hidden])) > .aff-nav-links { order: 2; flex-basis: 100%; justify-content: flex-end; }
}
/* the affiliate dashboard keeps one row signed in: on phones "The program" steps aside once the chip shows (the
   /dashboard rule for its leaderboard link) */
@media (max-width: 39.99rem) {
  .aff-dash-right:has(> [data-wallet-chip]:not([hidden])) > .aff-program-link { display: none; }
}
/* signed out, brand + "The program" + Sign in need 300px: under 340px the link steps aside too (the gate
   carries "Read about the program" right under the heading) */
@media (max-width: 21.24rem) {
  .aff-dash-right > .aff-program-link { display: none; }
}

/* bigger touch targets with the same look: the hit box grows past the text, the layout does not move
   (header and page links, and the pasted footer's links, which stay verbatim) */
.aff-hit, footer a { position: relative; }
.aff-hit::after, footer a::after { content: ""; position: absolute; inset: -10px -6px; }
/* orbio's 32px secondary Sign in button gets the same 40px reach */
.aff-hit-btn { position: relative; }
.aff-hit-btn::after { content: ""; position: absolute; inset: -4px; }

/* ------------------------------------------------------------------ steps */

.aff-step { transition: border-color .2s var(--pm-ease), box-shadow .2s var(--pm-ease); }
.aff-step:hover { border-color: var(--pm-line-strong); box-shadow: 0 0 0 1px rgba(250, 109, 1, .08), 0 18px 40px -28px rgba(250, 109, 1, .5); }
.aff-step > span:first-child { box-shadow: 0 0 14px rgba(250, 109, 1, .45); }

/* ------------------------------------------------------------------ calculator */

/* blueprint grid behind the calculator section, fading to nothing at every edge */
.aff-grid { --pm-grid-mask: radial-gradient(ellipse 70% 62% at 62% 50%, #000 20%, rgba(0, 0, 0, .4) 58%, transparent 86%); }

/* orbio's native accent range, drawn by hand so it keeps the look on a dark canvas: 8px track, orange fill
   up to the thumb (--fill, set by affiliates.js), a 16px neon thumb */
.aff-range {
  --fill: 9.09%;
  -webkit-appearance: none;
  appearance: none;
  display: block;
  /* a 40px touch box around the 8px track; the margins give back the 32px so orbio's my-7 rhythm holds */
  height: 40px;
  margin-block: 16px;
  background: transparent;
  border-radius: 999px;
}
.aff-range::-webkit-slider-runnable-track {
  height: 8px;
  border-radius: 999px;
  /* the unfilled track is a dark ember bar with a 3.6:1 edge on the card, so the whole range reads */
  background: linear-gradient(90deg, var(--pm-orange) 0 var(--fill), #4a3322 var(--fill) 100%);
  box-shadow: inset 0 0 0 1px #86644c;
}
.aff-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  margin-top: -4px;
  border: 0;
  border-radius: 50%;
  background: var(--pm-orange-2);
  box-shadow: 0 0 0 3px rgba(250, 109, 1, .22), 0 0 14px rgba(250, 109, 1, .6);
  transition: transform .16s var(--pm-ease), box-shadow .16s var(--pm-ease);
}
.aff-range:hover::-webkit-slider-thumb,
.aff-range:active::-webkit-slider-thumb { transform: scale(1.12); box-shadow: 0 0 0 5px rgba(250, 109, 1, .2), 0 0 20px rgba(250, 109, 1, .7); }
.aff-range::-moz-range-track { height: 8px; border-radius: 999px; background: #4a3322; box-shadow: inset 0 0 0 1px #86644c; }
.aff-range::-moz-range-progress { height: 8px; border-radius: 999px; background: var(--pm-orange); }
.aff-range::-moz-range-thumb { width: 16px; height: 16px; border: 0; border-radius: 50%; background: var(--pm-orange-2); box-shadow: 0 0 0 3px rgba(250, 109, 1, .22), 0 0 14px rgba(250, 109, 1, .6); }
.aff-range:focus-visible { outline: 2px solid var(--pm-orange); outline-offset: 4px; }

/* the commission highlight: orbio's neon block, with the logo glow. The rolling digits are masked 0.2em past
   the line box, which runs outside this block (pt-2, no bottom padding), so the block clips them; the glow is
   its own box-shadow and stays. */
.aff-commission { box-shadow: var(--pm-glow); overflow: clip; }

/* FAQ: the whole 64px row is the tap target. The details lost orbio's py-5; the summary carries it, and the
   answer gives the 4px back (16px under the question, 20px under the answer, as before). */
.aff-faq > details > summary { padding-block: 20px; }
.aff-faq > details > p { margin-top: -4px; padding-bottom: 20px; }

/* ------------------------------------------------------------------ dashboard room */

/* orbio's dark "Lifetime earnings" panel (bg-ink text-paper on a light page) becomes a lava panel on our
   dark page. --color-paper flips to ink inside it so orbio's text-paper/70, border-paper/10 keep working. */
.aff-earn {
  --color-paper: #f6eee7;
  color: var(--pm-ink);
  background:
    linear-gradient(100deg, rgba(11, 9, 8, .9) 0%, rgba(11, 9, 8, .78) 45%, rgba(11, 9, 8, .45) 100%),
    radial-gradient(ellipse 70% 60% at 25% 55%, rgba(11, 9, 8, .6) 30%, transparent 80%),
    url(/assets/img/lava.webp) 70% 40% / cover no-repeat,
    var(--pm-bg-3);
}
.aff-earn .text-neon { text-shadow: 0 0 22px rgba(250, 109, 1, .5); }

/* the referral link: orbio's readonly input, as a field that wraps, so the personal code at the end of the
   link is never cut off on a 320px phone. One line from 375 up, like orbio. */
.aff-link {
  display: flex;
  align-items: center;
  min-height: 42px;
  line-height: 16px;
  word-break: break-all;
  -webkit-user-select: all;
  user-select: all;
  cursor: text;
}
.aff-link:focus-visible { outline: 2px solid var(--pm-orange); outline-offset: 2px; }
/* affiliates.js splits the link so a wrap lands before "?ref=": the code (the wallet address) starts its own line
   and only breaks inside itself when even a whole line is too narrow for it */
.aff-link:has(.aff-link-code) { word-break: normal; overflow-wrap: anywhere; }
.aff-link-code { display: inline-block; max-width: 100%; white-space: nowrap; }
@media (max-width: 39.99rem) { .aff-link-code { white-space: normal; word-break: break-all; } }
/* the full-address link takes two lines beside the button: the button sits level with the middle of the field */
@media (min-width: 40rem) { .aff-link-row { align-items: center; } }

/* the disabled payout request: a quiet dark button, not a muddy 45% orange, with its reason underneath */
.aff-request:disabled { opacity: 1; background: var(--pm-tint); color: var(--pm-ink-3); box-shadow: inset 0 0 0 1px var(--pm-line-strong); }

/* the quiet preview tag in the room's status line */
.aff-preview-tag { vertical-align: 1px; }

/* the room's section headings are focus targets after a sign in, never a visible ring */
[data-aff-room] h1:focus { outline: none; }

/* stat values stay on one line and shrink on the narrowest phones */
.aff-stat { font-size: clamp(1.6rem, 7vw, 1.875rem); }
@media (min-width: 40rem) { .aff-stat { font-size: 2.25rem; } }

/* the program terms list */
.aff-terms dt { color: var(--pm-ink); font-size: 14px; font-weight: 500; }
.aff-terms dd { margin-top: 4px; color: var(--pm-ink-2); font-size: 14px; line-height: 1.6; }

/* ------------------------------------------------------------------ live (contracts on chain) */

/* two sets of copy: .aff-off is the page as it is until the contracts are live, .aff-live the on-chain version.
   affiliates.js sets html[data-pm-live] when chain.js is LIVE (deployed contracts, or a localnet on localhost). */
html:not([data-pm-live]) .aff-live { display: none !important; }
html[data-pm-live] .aff-off { display: none !important; }

/* figures waiting for their first read sit back until the chain answers */
[data-aff-room]:is([aria-busy="true"], [data-aff-unread]) :is([data-aff-stat], [data-aff-earned]) { opacity: .45; transition: opacity .2s var(--pm-ease); }
[data-aff-room] :is([data-aff-stat], [data-aff-earned]) { transition: opacity .2s var(--pm-ease); }

/* the live Claim button: orbio's neon Request button once there is something to claim */
.aff-request[data-busy] { opacity: 1; background: var(--pm-tint); color: var(--pm-ink-2); box-shadow: inset 0 0 0 1px var(--pm-line-strong); }

/* the claim note under the button: the balance split, wallet steps while a claim runs, then its result */
.aff-claim-note[data-tone="error"] { color: var(--pm-ask); }
.aff-claim-note[data-tone="ok"] { color: var(--pm-ember); }
.aff-claim-note a, [data-aff-msg] a, .aff-table a { color: var(--pm-orange-2); text-decoration: underline; text-underline-offset: 3px; }
.aff-claim-note a:hover, [data-aff-msg] a:hover, .aff-table a:hover { color: var(--pm-ink); }

/* orbio's history tables: plain rows on the page, a horizontal scroller on phones */
.aff-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.aff-table { border-collapse: collapse; }
.aff-table th { font-weight: 500; }
.aff-table td a { position: relative; }
.aff-table td a::after { content: ""; position: absolute; inset: -12px -6px; }

/* ------------------------------------------------------------------ 404 */

.pm-404-code {
  font-family: var(--pm-mono);
  font-size: 12px;
  letter-spacing: .08em;
  color: var(--pm-orange-2);
}

/* the 404 card's page links wrap to two rows on phones: 40px reach, and the rows sit 20px apart so two
   reaches only meet in the gap, never land on the other row's words */
.aff-404-links { row-gap: 20px; }
.aff-404-links .aff-hit::after { inset: -10px -6px; }

/* the grid canvas behind the dashboard gate and the top of the room */
.aff-dash-grid { height: 46rem; --pm-grid-mask: radial-gradient(ellipse 62% 70% at 50% 30%, #000 18%, rgba(0, 0, 0, .4) 56%, transparent 86%); }
