/* dash.css — the authenticated dashboard.
 *
 * Sits on top of pad.css and adds nothing to its type system: the display face
 * is still Roboto Flex at wdth 140 / wght 900, the text face is still Archivo,
 * and every size, leading and em tracking is the one measured off the
 * reference. Nothing here redefines a --dxl, --dl, --bl or a tracking value.
 *
 * What it adds is the shell: a rail on the left at desktop, a compact bar at
 * the bottom on a phone, and the module language the pages are built from.
 *
 * NOT a Vercel or Stripe dashboard: no dense tables of small text, no
 * four-up stat cards, no monospace addresses on the surface. Big rounded
 * panels, friendly empty states, one obvious action per module.
 */

:root {
  --side-w: 264px;
  --panel-r: 28px;
  --tile-r: 20px;
  --dash-pad: 40px;
  --panel: #0e1122;
  --panel-2: #131730;
  --hair-2: rgba(255, 255, 255, .09);
}

@media (max-width: 1200px) { :root { --side-w: 216px; --dash-pad: 28px; --panel-r: 24px; } }
@media (max-width: 860px) { :root { --dash-pad: 20px; --panel-r: 22px; --tile-r: 16px; } }

/* The dashboard's ground is the flat body black of the marketing page, with
   the same climb to blurple kept for the rail so the two feel like one site. */
/* A flat navy, and nothing else.

   This used to be a gradient ending at var(--ground). That was fine while
   --ground was black, but dash.html also loads pad.css, and when the public
   site's ground became Discord blurple this token followed it: the dashboard
   grew a navy-to-blurple fade up its bottom edge, behind the launch wizard,
   which looked exactly like the bug it was.

   A literal value, not a token, because this surface must not move again the
   next time the marketing ground is retuned. It is still the navy the panels
   are made of, so the panels read as sitting on it rather than floating in a
   void, which is what the gradient was there for in the first place. */
body.dash {
  background: #10142c;
  min-height: 100vh;
}

.shell {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr);
  min-height: 100vh;
}

/* ══════════════════════════════════════════════════════════════════ rail */

/* A bar, stuck to the top of the window, flat rather than graded: the same
   navy as the ground it sits on with one hairline under it. */
.side {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 6px;
  padding: 10px 20px;
  background: #151935;
  box-shadow: inset 0 -1px 0 var(--hair-2);
}
.side-brand {
  display: flex; align-items: center; gap: 10px;
  padding: 0 16px 0 0;
  margin-right: 4px;
  font-size: 16px;
  flex: none;
}
.side-brand b {
  font-family: var(--display);
  font-stretch: var(--display-wdth);
  font-weight: var(--display-wght);
  font-size: 19px;
  letter-spacing: -.02em;
}
.side a.side-link, .side button.side-link {
  display: flex; align-items: center; gap: 9px;
  width: auto;
  flex: none;
  white-space: nowrap;
  padding: 9px 13px;
  border: 0;
  border-radius: 14px;
  background: transparent;
  color: rgba(255, 255, 255, .78);
  font-size: 15px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  transition: background-color .13s ease, color .13s ease;
}
.side a.side-link:hover, .side button.side-link:hover { background: rgba(255, 255, 255, .08); color: #fff; }
.side a.side-link.is-on { background: var(--blurple); color: #fff; }
.side .side-link svg { width: 19px; height: 19px; flex: none; opacity: .92; }
.side .side-link.is-cta { background: #fff; color: #06070f; margin-left: 4px; justify-content: center; font-weight: 600; }
.side .side-link.is-cta:hover { background: #e8eaff; color: #06070f; }
.side-spacer { flex: 1 1 auto; }
/* Everything after the spacer is the account end of the bar. */

.side-foot {
  border-top: 0;
  padding-top: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
}
.who { display: flex; align-items: center; gap: 10px; padding: 6px 10px; }
.who img { width: 34px; height: 34px; border-radius: 50%; flex: none; background: #262b52; }
.who b { display: block; font-size: 14px; font-weight: 600; line-height: 1.2; }
.who small { display: block; font-size: 12px; color: var(--ink-mute); }
.who .grow { min-width: 0; }
.who b, .who small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.wallet-chip {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px;
  border-radius: 12px;
  background: rgba(255, 255, 255, .07);
  font-size: 13px;
  color: var(--ink-dim);
}
.wallet-chip i { width: 8px; height: 8px; border-radius: 50%; background: var(--green); flex: none; }
.wallet-chip.is-off i { background: var(--ink-mute); }
.wallet-chip .grow { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ═══════════════════════════════════════════════════════════ mobile bar
 *
 * A bottom bar, not a shrunken rail: on a phone the rail's five items become
 * four tap targets at the thumb, and the account moves into the page header
 * where it is read rather than tapped. */
.tabbar { display: none; }
@media (max-width: 860px) {
  .side { display: none; }
  .tabbar {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 60;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 2px;
    padding: 8px 8px calc(8px + env(safe-area-inset-bottom, 0px));
    background: rgba(12, 15, 34, .94);
    backdrop-filter: blur(14px);
    box-shadow: inset 0 1px 0 var(--hair-2);
  }
  .tabbar a {
    display: grid;
    justify-items: center;
    gap: 3px;
    padding: 8px 4px;
    border-radius: 14px;
    font-size: 11px;
    font-weight: 500;
    color: rgba(255, 255, 255, .66);
  }
  .tabbar a svg { width: 21px; height: 21px; }
  .tabbar a.is-on { color: #fff; background: rgba(88, 101, 242, .3); }
  main.dash-main { padding-bottom: 96px; }
}

/* ══════════════════════════════════════════════════════════════════ page */

main.dash-main {
  min-width: 0;
  padding: var(--dash-pad) var(--dash-pad) 72px;
}
.page { max-width: 1120px; margin-inline: auto; }

.page-head { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; margin-bottom: 26px; }
.page-head .grow { flex: 1 1 260px; min-width: 0; }
.page-head h1 {
  font-family: var(--display);
  font-stretch: var(--display-wdth);
  font-weight: var(--display-wght);
  text-transform: uppercase;
  font-size: var(--dl);
  line-height: var(--dl-lh);
  letter-spacing: var(--dl-tr);
  margin: 0;
}
.page-head p { margin: 8px 0 0; color: var(--ink-dim); font-size: 16px; line-height: 24px; }
.page-head .who { padding: 0; }

/* Greeting: the avatar is big because the whole product is "this is you, and
   this is what people have put in your name". */
.greet { display: flex; align-items: center; gap: 16px; }
.greet img { width: 60px; height: 60px; border-radius: 50%; background: #262b52; flex: none; }
@media (max-width: 860px) { .greet img { width: 48px; height: 48px; } }

/* ═══════════════════════════════════════════════════════════════ modules
 *
 * One headline number in a large panel, with the supporting numbers beside it
 * as tiles. Not four identical stat cards: the thing a visitor came to find
 * out is bigger than the things they did not. */
.modules {
  display: grid;
  grid-template-columns: 1.55fr 1fr;
  gap: 18px;
  align-items: stretch;
}
@media (max-width: 1060px) { .modules { grid-template-columns: 1fr; } }

.panel {
  border-radius: var(--panel-r);
  background: var(--panel);
  box-shadow: inset 0 0 0 1px var(--hair-2);
  padding: 28px;
}
@media (max-width: 860px) { .panel { padding: 22px; } }

.panel-hero {
  background: linear-gradient(150deg, #2b3186 0%, #1a1d52 54%, #12142f 100%);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 22px;
  position: relative;
  overflow: hidden;
}
.panel-hero .prop {
  position: absolute; right: -26px; bottom: -34px;
  width: 190px; height: 190px; opacity: .92;
  pointer-events: none;
  animation: bob 8s ease-in-out infinite;
}
@media (max-width: 520px) { .panel-hero .prop { width: 130px; right: -22px; bottom: -26px; } }

.label {
  font-size: 12px;
  font-weight: 600;
  /* 0.08em, not 0.12em. Still clearly a label, roughly 12% narrower, which
     is the difference between these phrases fitting on one line and not. */
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin: 0;
}
.panel-hero .label { color: rgba(255, 255, 255, .72); }

.big {
  font-family: var(--display);
  font-stretch: var(--display-wdth);
  font-weight: var(--display-wght);
  font-size: clamp(38px, 5.2vw, 62px);
  line-height: .96;
  letter-spacing: -.03em;
  margin: 10px 0 0;
  font-variant-numeric: tabular-nums;
}
.big small { font-size: .42em; letter-spacing: -.01em; margin-left: .22em; opacity: .74; }
.panel-hero .sub { margin: 10px 0 0; color: rgba(255, 255, 255, .82); font-size: 15px; line-height: 22px; max-width: 34ch; }

/* Tiles take a width their contents fit in and then wrap, rather than being
   handed a fixed share of the row. 190px is the widest of these labels plus
   the tile's own padding, so a label never has to break. */
.tiles {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
@media (max-width: 420px) { .tiles { grid-template-columns: 1fr; } }
.tile {
  border-radius: var(--tile-r);
  background: var(--panel-2);
  box-shadow: inset 0 0 0 1px var(--hair-2);
  padding: 18px;
  min-width: 0;
}
/* One line, always. The column above is sized so this fits; keeping it on a
   single line also keeps every figure in the row on one baseline. */
.tile .label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tile .n {
  font-family: var(--display);
  font-stretch: var(--display-wdth);
  font-weight: var(--display-wght);
  font-size: 27px;
  line-height: 1.04;
  letter-spacing: -.02em;
  margin: 8px 0 0;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.tile .n small { font-size: .5em; opacity: .7; margin-left: .38em; }

/* ════════════════════════════════════════════════════════════ reward rows
 *
 * A reward is a person-shaped thing, so it is laid out like one: who launched
 * it, what share they gave you, and one button. */
.stack { display: grid; gap: 14px; }
.section-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 12px; margin: 34px 0 14px; }
.section-head h2 {
  font-family: var(--display);
  font-stretch: var(--display-wdth);
  font-weight: var(--display-wght);
  text-transform: uppercase;
  font-size: var(--dm);
  line-height: var(--dm-lh);
  letter-spacing: var(--dm-tr);
  margin: 0;
}
.section-head .grow { flex: 1 1 auto; }
.section-head p { margin: 0; color: var(--ink-mute); font-size: 14px; }

.reward {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) auto;
  align-items: center;
  gap: 18px;
  border-radius: var(--panel-r);
  background: var(--panel);
  box-shadow: inset 0 0 0 1px var(--hair-2);
  padding: 20px 24px;
}
.reward.is-ready { box-shadow: inset 0 0 0 1px rgba(53, 237, 126, .34); background: linear-gradient(180deg, rgba(53,237,126,.07), rgba(53,237,126,0) 58%), var(--panel); }
.reward .coin-mark {
  width: 56px; height: 56px; border-radius: 18px; flex: none;
  background: linear-gradient(150deg, #5865f2, #9aa4ff);
  display: grid; place-items: center; overflow: hidden;
  font-family: var(--display); font-stretch: var(--display-wdth); font-weight: var(--display-wght);
  font-size: 19px; letter-spacing: -.02em; color: #fff;
}
.reward .coin-mark img { width: 100%; height: 100%; object-fit: cover; }
.reward .name { font-size: 18px; font-weight: 600; margin: 0; overflow-wrap: anywhere; }
.reward .said { margin: 5px 0 0; color: var(--ink-dim); font-size: 15px; line-height: 21px; overflow-wrap: anywhere; }
.reward .amt {
  text-align: right;
  display: grid;
  gap: 10px;
  justify-items: end;
}
.reward .amt .v {
  font-family: var(--display); font-stretch: var(--display-wdth); font-weight: var(--display-wght);
  font-size: 25px; line-height: 1; letter-spacing: -.02em; font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
@media (max-width: 720px) {
  .reward { grid-template-columns: 48px minmax(0, 1fr); padding: 18px; gap: 14px; }
  .reward .coin-mark { width: 48px; height: 48px; border-radius: 15px; font-size: 16px; }
  .reward .amt { grid-column: 1 / -1; justify-items: stretch; text-align: left; }
  .reward .amt .btn { width: 100%; }
}

.meta { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 11px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .07);
  font-size: 13px;
  color: var(--ink-dim);
  white-space: nowrap;
}
.chip b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.chip.ok { background: rgba(53, 237, 126, .16); color: #b6ffd6; }
.chip.warn { background: rgba(255, 196, 81, .15); color: #ffe2a6; }
.chip.bad { background: rgba(255, 125, 125, .16); color: #ffc4c4; }

/* ══════════════════════════════════════════════════════════════ split bar
 *
 * The fee routing, drawn. This is the screen the product is supposed to be
 * understandable from, so the shares are a physical proportion, not a table. */
.splitbar {
  display: flex;
  height: 26px;
  border-radius: 999px;
  overflow: hidden;
  background: rgba(255, 255, 255, .07);
}
.splitbar span { display: block; min-width: 3px; }
.who-row {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 13px 0;
}
.who-row + .who-row { border-top: 1px solid var(--hair-2); }
.who-row img, .who-row .fallback {
  width: 44px; height: 44px; border-radius: 50%; background: #262b52; flex: none;
  display: grid; place-items: center; font-weight: 600; font-size: 15px; color: var(--ink-dim);
}
.who-row b { font-size: 16px; font-weight: 600; display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.who-row small { display: block; color: var(--ink-mute); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.who-row .share {
  font-family: var(--display); font-stretch: var(--display-wdth); font-weight: var(--display-wght);
  font-size: 21px; letter-spacing: -.02em; font-variant-numeric: tabular-nums;
}

/* ═══════════════════════════════════════════════════════════ empty states */

.empty {
  border-radius: var(--panel-r);
  background: var(--panel);
  box-shadow: inset 0 0 0 1px var(--hair-2);
  padding: 52px 32px;
  text-align: center;
}
.empty img { width: 132px; height: 132px; margin: 0 auto 20px; object-fit: contain; }
.empty h3 {
  font-family: var(--display); font-stretch: var(--display-wdth); font-weight: var(--display-wght);
  text-transform: uppercase; font-size: 24px; line-height: 1.04; letter-spacing: -.02em; margin: 0;
}
.empty p { margin: 12px auto 0; color: var(--ink-dim); max-width: 46ch; font-size: 16px; line-height: 24px; }
.empty .btns { justify-content: center; margin-top: 24px; }

/* ═════════════════════════════════════════════════════════════════ skeleton
 *
 * Loading is a real state with a real shape, so the page does not jump when
 * the answer arrives. */
.skel {
  border-radius: var(--panel-r);
  background: linear-gradient(100deg, var(--panel) 30%, #171b33 50%, var(--panel) 70%);
  background-size: 300% 100%;
  animation: sweep 1.25s linear infinite;
  min-height: 92px;
}
.skel.is-tall { min-height: 190px; }
@keyframes sweep { to { background-position: -300% 0; } }
@media (prefers-reduced-motion: reduce) { .skel { animation: none; } }

/* ══════════════════════════════════════════════════════════════════ forms */

.field { display: grid; gap: 8px; }
.field > label { font-size: 14px; font-weight: 600; }
.field .hint { font-size: 13.5px; line-height: 20px; color: var(--ink-mute); }
.input, .textarea, .select {
  width: 100%;
  padding: 14px 16px;
  border: 0;
  border-radius: 14px;
  background: #070912;
  box-shadow: inset 0 0 0 1px var(--hair-2);
  color: var(--ink);
  font: inherit;
  font-size: 16px;
}
.input:focus, .textarea:focus, .select:focus { outline: 2px solid var(--blurple); outline-offset: 1px; }
.input.is-bad, .textarea.is-bad { box-shadow: inset 0 0 0 1px rgba(255, 125, 125, .6); }
.textarea { min-height: 96px; resize: vertical; }
.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 620px) { .row2 { grid-template-columns: 1fr; } }

.pct-input {
  width: 92px; text-align: right;
  padding: 10px 12px;
  border: 0; border-radius: 12px;
  background: #070912;
  box-shadow: inset 0 0 0 1px var(--hair-2);
  color: var(--ink); font: inherit; font-variant-numeric: tabular-nums;
}

/* Steps: a Discord-style onboarding line, not a crypto wizard. */
.steps { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 26px; }
.steps .s {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 15px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .06);
  font-size: 14px;
  color: var(--ink-mute);
}
.steps .s i {
  width: 22px; height: 22px; border-radius: 50%;
  background: rgba(255, 255, 255, .1);
  display: grid; place-items: center;
  font-size: 12px; font-weight: 600; font-style: normal;
}
.steps .s.is-on { background: var(--blurple); color: #fff; }
.steps .s.is-on i { background: rgba(255, 255, 255, .25); }
.steps .s.is-done { background: rgba(53, 237, 126, .15); color: #b6ffd6; }
.steps .s.is-done i { background: rgba(53, 237, 126, .28); }

/* ══════════════════════════════════════════════════════════════ technical
 *
 * Addresses, hashes and contract names live behind this and nowhere else. */
details.tech {
  margin-top: 26px;
  border-radius: var(--tile-r);
  background: var(--panel-2);
  box-shadow: inset 0 0 0 1px var(--hair-2);
  overflow: hidden;
}
details.tech > summary {
  list-style: none;
  cursor: pointer;
  padding: 16px 20px;
  font-size: 15px;
  font-weight: 600;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
details.tech > summary::-webkit-details-marker { display: none; }
details.tech > summary::after {
  content: ""; width: 9px; height: 9px;
  border-right: 2px solid var(--ink-mute); border-bottom: 2px solid var(--ink-mute);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .18s ease;
}
details.tech[open] > summary::after { transform: rotate(225deg) translate(-2px, -2px); }
details.tech .body { padding: 0 20px 20px; display: grid; gap: 12px; }
.kv { display: grid; grid-template-columns: 180px minmax(0, 1fr); gap: 10px 16px; font-size: 14px; }
@media (max-width: 620px) { .kv { grid-template-columns: 1fr; gap: 3px 0; } .kv > dt { margin-top: 10px; } }
.kv dt { color: var(--ink-mute); }
.kv dd {
  margin: 0;
  font-family: ui-monospace, 'SFMono-Regular', Menlo, monospace;
  font-size: 13px;
  overflow-wrap: anywhere;
}
.kv dd a { color: var(--ice); text-decoration: underline; text-underline-offset: 2px; }

/* ══════════════════════════════════════════════════════════════════ notice */

.notice {
  border-radius: var(--tile-r);
  padding: 18px 20px;
  background: var(--panel-2);
  box-shadow: inset 0 0 0 1px var(--hair-2);
  border-left: 3px solid var(--blurple);
}
.notice.ok { border-left-color: var(--green); }
.notice.warn { border-left-color: #ffc451; }
.notice.bad { border-left-color: #ff7d7d; }
.notice h4 { margin: 0 0 6px; font-size: 16px; font-weight: 600; }
.notice p { margin: 0; color: var(--ink-dim); font-size: 15px; line-height: 22px; }
.notice p + p { margin-top: 8px; }

/* Progress of a claim or a launch, reusing the site's step language. */
.prog { display: grid; gap: 9px; margin-top: 14px; }
.prog .p { display: flex; align-items: flex-start; gap: 10px; font-size: 14px; color: var(--ink-dim); }
.prog .p i {
  width: 16px; height: 16px; border-radius: 50%; flex: none; margin-top: 3px;
  background: rgba(255, 255, 255, .16);
}
.prog .p.is-now i { background: var(--blurple); box-shadow: 0 0 0 4px rgba(88, 101, 242, .22); }
.prog .p.is-done i { background: var(--green); }
.prog .p a { color: var(--ice); text-decoration: underline; text-underline-offset: 2px; }

/* ═══════════════════════════════════════════════════════════════════ toast */

.toast {
  position: fixed;
  left: 50%; bottom: 26px;
  transform: translate(-50%, 140%);
  z-index: 90;
  max-width: min(520px, calc(100vw - 32px));
  padding: 14px 20px;
  border-radius: 16px;
  background: #171c38;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .5), inset 0 0 0 1px var(--hair-2);
  font-size: 15px;
  line-height: 21px;
  transition: transform .22s cubic-bezier(.2, .7, .3, 1);
}
.toast.is-up { transform: translate(-50%, 0); }
.toast.is-bad { box-shadow: 0 18px 50px rgba(0, 0, 0, .5), inset 0 0 0 1px rgba(255, 125, 125, .5); }
@media (max-width: 860px) { .toast { bottom: 96px; } }

/* The brand mark. Sized explicitly so the rail does not reflow between the
   first paint and the image arriving. */
.side-brand img { width: 26px; height: 26px; object-fit: contain; flex: none; }

/* ── the bar, narrowed ────────────────────────────────────────────────
   The labels are the first thing that will not fit. The icons stay, so
   every destination is still reachable, and the wordmark goes before the
   mark does. */
@media (max-width: 1100px) {
  .side { padding-inline: 14px; gap: 2px; }
  .side a.side-link, .side button.side-link { padding-inline: 10px; }
}
@media (max-width: 900px) {
  .side .side-link span { display: none; }
  .side .side-link.is-cta span { display: inline; }
  .side-brand b { display: none; }
  .side-foot .who span { display: none; }
}
@media (max-width: 620px) {
  .side { overflow-x: auto; }
  .side-foot { margin-left: auto; }
}

/* The recipient identity card.

   A launcher checks a person, not a number: the avatar, the display name and
   the handle are what confirm the right account was pasted. The snowflake is
   still the thing that gets committed to the roster and it still has to be
   visible, so it sits underneath, small and muted, where it can be checked
   without being what anyone reads first. */
.who-row .idline {
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  color: rgba(255, 255, 255, .42);
  letter-spacing: .01em;
}
.who-row .verified { color: var(--good, #35ed7e); font-weight: 600; white-space: nowrap; }

/* The one phrase in the help text that a person has to find in Discord's own
   menu, so it is set the way Discord sets it. */
.hint .em { color: #fff; font-weight: 600; }
