/*
 * Design tokens and components.
 *
 * ONE STYLESHEET, HAND-WRITTEN. This replaces Tailwind: there is no build step,
 * no class-name scanner and no generated output — the browser reads this file as
 * it is. The cost is that class names have to be chosen deliberately; the gain is
 * that what ships is what is written here, and it is about 8 KB.
 */

/*
 * THE `hidden` ATTRIBUTE MUST BEAT EVERY `display` RULE IN THIS FILE.
 *
 * The browser hides `[hidden]` through its own default stylesheet, and any
 * author rule setting `display` on the same element silently wins — so an
 * element written as hidden is shown anyway, with nothing to indicate why.
 *
 * It bit four things here at once, and one of them shipped to the owner: the
 * farm panel carries both a "Running" and a "Stopped" badge with one marked
 * hidden, and `.badge` sets `display: inline-flex` — so the card showed
 * "Running" and "Stopped" side by side on a stopped farm. The same fault was
 * making the refresh button and the password-strength meter visible before the
 * script that is supposed to reveal them had run, which on a page with
 * scripting disabled leaves controls that do nothing.
 *
 * `!important` is right here and almost nowhere else: `hidden` is a statement
 * that the element is not part of the page yet, not a suggestion about its
 * presentation, and no component rule should be able to argue with it.
 */
[hidden] {
  display: none !important;
}

/*
 * THE TYPEFACES, SERVED FROM THIS ORIGIN.
 *
 * The stylesheet used to ASK for Inter and never ship it, so the brand rendered
 * in Segoe UI on Windows, San Francisco on macOS and Roboto on Android — three
 * different products depending on the device, and none of them chosen. A
 * declared font that is not loaded is not a design decision, it is a note to
 * nobody.
 *
 * WHY SELF-HOSTED. The Content-Security-Policy allows nothing from another
 * origin, which would block a Google Fonts stylesheet outright — and that is the
 * right policy here: a font CDN sees every page view of a site about money.
 *
 * LATIN ONLY. The interface exists in English, Spanish, Portuguese, French and
 * German; every character those five need lives in the latin subset. Shipping
 * the extended one as well would have added 97 KB to render letters nobody here
 * types.
 *
 * `font-display: swap` on purpose. Text appears immediately in the fallback and
 * reflows when the real face arrives — on a slow connection that is the
 * difference between a readable page and a blank one.
 */
@font-face {
  font-family: 'Inter var';
  src: url('/assets/fonts/inter.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Clash Display';
  src: url('/assets/fonts/clashdisplay-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Clash Display';
  src: url('/assets/fonts/clashdisplay-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Geist Mono';
  src: url('/assets/fonts/geistmono.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/*
 * THE DESIGN TOKENS.
 *
 * Every colour, radius and shadow in the stylesheet resolves through here, so
 * the look can be changed in one screenful rather than in three thousand lines.
 *
 * BLACK, GREEN AND VIOLET, and the discipline is in how little of the last two
 * there is.
 *
 * The surfaces are a near-black with a green cast rather than a neutral grey —
 * enough that the eye reads the whole product as belonging to one family, not
 * enough to be seen as a colour. Every large area on every screen is one of the
 * four surfaces below.
 *
 * THE TWO ACCENTS MEAN DIFFERENT THINGS AND NEVER SHARE A SURFACE.
 *   · GREEN is money doing something: a balance growing, a farm running, a
 *     payout completed. It is the brand and it is the positive outcome, which
 *     works here only because on this site those are the same statement.
 *   · VIOLET is standing: tiers, status, the things you rise through. It never
 *     appears on a number.
 *
 * WHAT MAKES THIS READ AS EXPENSIVE RATHER THAN AS A CRYPTO CASINO: neither
 * accent is ever used at full saturation across a large area. They live in
 * gradients, in hairlines and in glow — the neutrals do ninety per cent of the
 * work, and the colour arrives as light rather than as paint.
 */
:root {
  /* Individual I-V share a vivid gold, distinct from Private cluster bronze. */
  --individual-gold-light: #fff7aa;
  --individual-gold-mid: #ffdc45;
  --individual-gold-deep: #efb913;
  --individual-gold-edge: #fff190;
  --individual-gold-ink: #332600;
  /*
   * Surfaces: charcoal that is barely green, not a green that is nearly black.
   *
   * The first version pushed the green cast far enough to be seen, and a tinted
   * neutral under a saturated accent of the same hue is what makes an interface
   * look like it was themed rather than designed. These read as dark grey to
   * anybody not looking for it, which is what a neutral is for.
   */
  --bg: #080b0a;
  --bg-raised: #0e1413;
  --bg-card: #131a18;
  --bg-input: #0a100e;

  /*
   * Hairlines as white at a percentage, not as opaque greys.
   *
   * A translucent line sits correctly on every surface it crosses — card,
   * input, raised panel — where a fixed grey is right on one and wrong on the
   * rest. It is also what makes the gradient border below possible.
   */
  --line: #ffffff14;
  --line-strong: #ffffff26;
  --border: var(--line);
  --border-strong: var(--line-strong);

  --fg: #e9efeb;
  --fg-muted: #8b9791;
  --fg-subtle: #8b979166;

  /*
   * THE ACCENT COMES IN TWO STRENGTHS, AND WHICH ONE GOES WHERE IS THE WHOLE
   * DIFFERENCE BETWEEN EXPENSIVE AND CHEAP.
   *
   * `--accent` is a DEEP emerald and it is what fills things: buttons, bars, any
   * area larger than a word. The first version of this palette used the bright
   * mint below for those, and a full-width button in neon green is the single
   * loudest way to make a finance product look like a trading bot. Saturation on
   * a large area is what reads as cheap — not the hue.
   *
   * `--accent-bright` is the mint, and it is rationed: a figure that has earned
   * something, a running-state dot, a link, a glow behind a card. Small marks and
   * light. Never a fill.
   *
   * Kept in one family so the two never argue: the bright one is the deep one
   * with the lights on.
   */
  --accent: #0e9e68;
  --accent-hover: #12b375;
  --accent-bright: #35e6a2;
  --accent-deep: #0a7a50;
  --accent-tint: #b4f0d4;
  --accent-soft: #0e9e6824;
  --accent-wash: #0c1f19;

  /*
   * Standing. Tiers, status, the ladder — never a number and never a balance.
   * Two colours that both meant "good" would leave the eye with no way to tell
   * a rank from an amount.
   */
  --rank: #8b7bf0;
  --rank-bright: #b6a8ff;
  --rank-deep: #6d5cd6;
  --rank-soft: #8b7bf01f;

  /*
   * CHAMPAGNE. The one warm note in the whole palette, and it is rationed
   * harder than anything else here.
   *
   * WHY IT EXISTS. Green was doing three jobs at once — the brand, "this went
   * well", and the bottom rung of the tier ladder — and a colour that means
   * everything means nothing. More than that, the summit of the ladder was
   * violet, which is the single most worn-out hue in this category: every
   * competitor's card, every generated banner, the same purple gradient.
   *
   * Emerald with a warm metal is the oldest expensive pairing there is, and it
   * is the one thing on that reference banner nobody was using. Cool green does
   * the work; a little warm metal marks the top of it.
   *
   * WHERE IT IS ALLOWED: the highest tier, the badge that says which tier is
   * yours, and first place on the leaderboard. Nowhere else, ever. Gold spread
   * across an interface is a casino; gold on three things is a hallmark.
   *
   * DESATURATED ON PURPOSE. #ffd700 is a prize wheel. This is closer to brushed
   * brass, which is what reads as metal rather than as yellow.
   */
  --prestige: #d9bd85;
  --prestige-bright: #f0dcb0;
  --prestige-deep: #a8894f;
  --prestige-soft: #d9bd851f;

  /*
   * Reserved for outcomes, never for decoration.
   *
   * `--ok` is the BRIGHT accent rather than the deep one: it appears on figures
   * and on small marks, which is exactly where the bright version belongs, and a
   * deep emerald number on a dark card is unreadable.
   */
  --ok: var(--accent-bright);
  --ok-soft: var(--accent-soft);
  --danger: #ff5a5f;
  --danger-soft: #ff5a5f1f;
  --warning: #e8a33d;
  --warning-soft: #e8a33d1f;

  --radius: 16px;
  --radius-sm: 10px;
  --radius-lg: 20px;

  /*
   * THE SIGNATURE. A hairline that is brighter along the top edge and fades
   * towards the bottom, as though the panel were catching light from above.
   *
   * It is what separates a surface that looks made from one that looks like a
   * div with a border. Applied through `.edge` — see the rule near the end of
   * this file for how a gradient becomes a border.
   */
  --edge-gradient: linear-gradient(to bottom, #ffffff2e, #ffffff0f 40%, #ffffff08);
  --edge-gradient-accent: linear-gradient(to bottom, #35e6a280, #35e6a21a);

  /*
   * Deeper shadows than a grey theme needs, because the surfaces are nearly
   * black: a shadow that reads on #1e2029 disappears on #101a16, and a card that
   * casts nothing looks painted on rather than placed.
   */
  --shadow-card: 0 1px 2px rgb(0 0 0 / 0.5), 0 14px 36px -18px rgb(0 0 0 / 0.85);
  --shadow-raised: 0 2px 8px rgb(0 0 0 / 0.55), 0 28px 56px -24px rgb(0 0 0 / 0.9);

  /*
   * THREE FACES, EACH WITH ONE JOB.
   *
   * `--font-sans` is everything you read: Inter, chosen for being invisible.
   * Body text that has personality is body text that is competing with the
   * numbers, and on this site the numbers are the content.
   *
   * `--font-display` is for the few places that are supposed to have presence —
   * page titles, the balance, tier names. Clash Display is a grotesque with
   * slightly narrow proportions and real character in its caps, which is what
   * makes a heading look set rather than typed.
   *
   * `--font-mono` is for anything that must line up in a column or be read one
   * character at a time: amounts, wallet addresses, recovery codes. Geist Mono
   * has a dotted zero and a distinct 1/l/I, which matters when somebody is
   * checking an address against their wallet.
   *
   * The fallbacks are the platform faces, close enough in proportion that the
   * swap when the real file arrives does not move the layout.
   */
  --font-sans:
    'Inter var', Inter, system-ui, -apple-system, 'Segoe UI Variable Text', 'Segoe UI', Roboto,
    'Helvetica Neue', Arial, sans-serif;
  --font-display: 'Clash Display', 'Inter var', Inter, system-ui, sans-serif;
  --font-mono: 'Geist Mono', ui-monospace, 'SF Mono', 'Cascadia Mono', Menlo, Consolas, monospace;
}

/*
 * Headings are set tighter than body text.
 *
 * At display sizes the default spacing between letters reads as loose and
 * amateurish; pulling it in is most of the difference between "typed" and
 * "typeset". Small uppercase labels go the other way, because capitals need
 * air to stay legible.
 */
/*
 * THE DISPLAY FACE, ON THE FEW THINGS THAT ARE SUPPOSED TO HAVE PRESENCE.
 *
 * Page titles, card titles, and the figures the page exists to show. Everything
 * else stays in Inter — a product where every element has personality is a
 * product where nothing stands out, and here what has to stand out is the money.
 */
h1,
h2,
h3,
.card__title,
.stat__value,
.farmboard__value {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.015em;
  /*
   * THE WORDS RAN TOGETHER. "How it works" read as "Howitworks" and a card
   * heading came out as one long word.
   *
   * Clash Display draws a narrow space to begin with — it is a display face,
   * built for two or three words at a large size — and negative tracking is
   * applied to every character INCLUDING the space, so tightening the letters
   * closed the gaps between the words at the same time. At heading sizes the
   * letters can take it; the spaces cannot.
   *
   * So the space is given back what the tracking takes from it. The headings
   * still read as tight and set, and the words stay separate words.
   */
  word-spacing: 0.08em;
}

h1 {
  font-weight: 700;
  letter-spacing: -0.02em;
  /* The largest text on the page, so it loses the most from tracking. */
  word-spacing: 0.1em;
}

/*
 * MONEY, SET AS MONEY.
 *
 * Three things separate a designed figure from a typed one, and all three are
 * here:
 *
 *   · TABULAR FIGURES, so a column of amounts lines up on the decimal point and
 *     a number that changes does not shift the ones around it. On a page that
 *     polls a live balance, proportional digits make the whole card twitch.
 *   · TIGHTER TRACKING. Display sizes need less letter-spacing than body text;
 *     the default reads loose and amateurish above about 24px.
 *   · A QUIETER CURRENCY SIGN. The dollar is grammar, not information — smaller
 *     and dimmer, it stops competing with the digits it introduces.
 */
.stat__value,
.farmboard__value,
.money {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1, 'ss01' 1;
}

.money__symbol {
  font-size: 0.72em;
  opacity: 0.55;
  margin-right: 0.06em;
  font-weight: 600;
}

/*
 * The pennies, one step down. What somebody reads across a room is the whole
 * number; the decimals are for when they look properly.
 */
.money__fraction {
  font-size: 0.66em;
  opacity: 0.7;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  /*
   * A single ambient light source, top-left, behind everything.
   *
   * A dark theme with one flat background colour reads as a switched-off screen.
   * One very low-contrast wash gives the page a direction for its light, which
   * every card's top highlight then agrees with — that agreement is most of what
   * makes a set of panels look like objects rather than rectangles.
   */
  background-image:
    radial-gradient(80rem 50rem at 8% -10%, #0e9e6817, transparent 60%),
    radial-gradient(60rem 40rem at 95% 0%, #8b7bf010, transparent 55%);
  background-attachment: fixed;
}

/*
 * GRAIN.
 *
 * Two per cent of noise over the whole page. It is the single cheapest thing on
 * this list and it removes the tell that makes a dark interface look generated:
 * perfectly smooth gradients with no texture in them. Real screens, real print
 * and every expensive dark UI have some noise; a mathematically clean gradient
 * has none, and the eye notices without being able to say why.
 *
 * An inline SVG turbulence rather than an image file: no request, no cache
 * entry, about two hundred bytes, and it scales to any screen density.
 *
 * `pointer-events: none` because it covers everything and must never eat a tap.
 */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.045'/%3E%3C/svg%3E");
}

/*
 * Everything the person can actually touch sits above the grain. Without this
 * the overlay would be painted over the interface rather than under it, and the
 * whole page would take on a haze.
 */
body > *:not(script) {
  position: relative;
  z-index: 1;
}

a {
  color: var(--accent);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

/*
 * Focus is never removed, only restyled. Removing it makes the site unusable by
 * keyboard, which is the one accessibility failure that locks people out
 * entirely rather than merely inconveniencing them.
 */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  padding: 0.75rem 1rem;
  background: var(--bg-card);
  border: 1px solid var(--border-strong);
  border-radius: 0 0 var(--radius-sm) 0;
  z-index: 100;
}

.skip-link:focus {
  left: 0;
}

/* ---------- Auth screen ---------- */

.page-auth {
  /* A quiet radial glow behind the panel. Pure CSS, no image request. */
  background:
    radial-gradient(60rem 40rem at 50% -10%, #0093fd12, transparent 70%),
    var(--bg);
  min-height: 100dvh;
}

.auth {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100dvh;
  padding: 3rem 1.5rem;
}

.auth__panel {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  width: 100%;
  max-width: 30rem;
}

.auth__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.auth__switch {
  margin: 0;
  text-align: center;
  font-size: 0.875rem;
  color: var(--fg-muted);
}

/* ---------- Brand ---------- */

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
}

.brand__glyph {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  color: var(--accent);
}

/*
 * The mark sits at 20 of the tile's 36, which is a wider margin than an icon
 * usually gets. It needs one: the glyph is a rhombus, so its corners reach the
 * bounding box only at four points and the flats fall well inside it — matched
 * to a square tile by its box it looks small, and matched by its apparent mass
 * it looks like it is about to touch the corners.
 */
.brand__glyph svg {
  width: 1.25rem;
  height: 1.25rem;
}

.brand__name {
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* ---------- Card ---------- */

/*
 * The card. Border comes from `.edge` (a gradient hairline), not from `border`,
 * so `overflow: hidden` would clip the ring — the radius does the containing
 * instead, and children that need clipping ask for it themselves.
 */
/*
 * LIGHT DOES THE SEPARATING, NOT A BORDER.
 *
 * A 1px grey outline around every panel is the house style of a dashboard
 * template: it says "here is a box" and nothing else. What an expensive dark
 * interface does instead is light the top edge of a surface, as though the panel
 * were catching the same light the page is lit by, and let the shadow underneath
 * do the rest. The outline can then drop to almost nothing.
 *
 * Three layers, cheapest first: a hairline that is brightest at the top edge
 * (`inset 0 1px 0`), a barely-there containing ring, and the ambient shadow.
 */
.card {
  position: relative;
  background: var(--bg-card);
  border-radius: var(--radius);
  box-shadow:
    inset 0 1px 0 #ffffff14,
    inset 0 0 0 1px #ffffff08,
    var(--shadow-card);
}

/* The one card on a page that matters most. */
.card--highlighted {
  background: linear-gradient(to bottom, var(--accent-wash), var(--bg-card) 55%);
}

.card__title {
  margin: 0;
  padding: 1.25rem 1.5rem;
  border-bottom: 1px solid var(--border);
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.card__content {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  padding: 1.5rem;
}

/* ---------- Tabs: sign in / register ---------- */

/*
 * Ordinary links, not buttons and not a script-driven widget. Each tab is a real
 * page with its own address, so the back button, bookmarking and "open in new
 * tab" all behave the way the browser already knows how to make them behave.
 */
.tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-bottom: 1px solid var(--border);
}

.tabs__tab {
  padding: 0.9375rem 1rem;
  text-align: center;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--fg-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition:
    color 120ms ease,
    border-color 120ms ease,
    background-color 120ms ease;
}

.tabs__tab:hover {
  color: var(--fg);
  text-decoration: none;
  background: #ffffff06;
}

.tabs__tab--active {
  color: var(--fg);
  border-bottom-color: var(--accent);
  background: var(--accent-soft);
}

.prose {
  margin: 0;
  max-width: 60ch;
  color: var(--fg-muted);
  font-size: 0.9375rem;
}

/* ---------- Callout ---------- */

.callout {
  border-radius: var(--radius-sm);
  padding: 0.875rem 1rem;
  border: 1px solid transparent;
}

.callout__title {
  margin: 0 0 0.25rem;
  font-size: 0.875rem;
  font-weight: 600;
}

.callout__body {
  margin: 0;
  font-size: 0.875rem;
  color: var(--fg-muted);
  overflow-wrap: anywhere;
}

.callout--danger {
  background: var(--danger-soft);
  border-color: #f2555a33;
}

.callout--danger .callout__title {
  color: var(--danger);
}

.callout--warning {
  background: var(--warning-soft);
  border-color: #f5a52433;
}

.callout--warning .callout__title {
  color: var(--warning);
}

.callout--accent {
  background: var(--accent-soft);
  border-color: #0093fd33;
}

.callout--accent .callout__title {
  color: var(--accent);
}

/* ---------- Checkbox ---------- */

.checkbox {
  display: flex;
  align-items: flex-start;
  gap: 0.625rem;
  cursor: pointer;
}

.checkbox__input {
  margin: 0;
  margin-top: 0.1875rem;
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
  accent-color: var(--accent);
  cursor: pointer;
}

.checkbox__text {
  font-size: 0.8125rem;
  color: var(--fg-muted);
  line-height: 1.5;
}

/* ---------- Form ---------- */

.form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.4375rem;
}

.field__label {
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--fg-muted);
}

.field__input {
  width: 100%;
  padding: 0.625rem 0.8125rem;
  background: var(--bg-input);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--fg);
  font: inherit;
  transition: border-color 120ms ease;
}

.field__input:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.field__hint {
  margin: 0;
  font-size: 0.75rem;
  color: var(--fg-muted);
}

/* ---------- Button ---------- */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.625rem 1.125rem;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition:
    background-color 140ms ease,
    box-shadow 140ms ease,
    transform 90ms cubic-bezier(0.2, 0, 0, 1);
}

/*
 * A press that gives, slightly.
 *
 * 96% is too much and 99% is invisible; 0.985 with a one-pixel drop is about the
 * amount of movement that registers as the control responding rather than as an
 * animation. The curve is fast out of the gate and slow into the stop, which is
 * what makes it feel physical instead of linear.
 */
.button:active {
  transform: translateY(1px) scale(0.985);
}

/*
 * The primary button. A shallow gradient plus a bright inset top edge, so it
 * reads as a raised surface rather than a coloured rectangle — the same "lit
 * from above" idea as the card, at button scale.
 *
 * White text, not near-black: on this blue, dark text is the lower contrast of
 * the two and looks washed out.
 */
/*
 * DEEP TO DEEPER, NOT BRIGHT TO DEEP.
 *
 * The gradient used to run from the bright mint down to the mid green, which
 * made every full-width button on the site a slab of neon — the loudest thing on
 * any screen and the reason the palette read as a trading bot rather than as a
 * product about money. It now runs between two deep emeralds, a narrow range, so
 * the button reads as one solid colour with a lit top edge rather than as a
 * gradient. The brightness that was in the fill has moved into the glow beneath
 * it, where a large area of it costs nothing.
 */
.button--primary {
  background: linear-gradient(to bottom, #13a870, var(--accent) 55%, var(--accent-deep));
  color: #f2fbf6;
  box-shadow:
    inset 0 1px 0 #ffffff2e,
    inset 0 0 0 1px #ffffff14,
    0 1px 2px rgb(0 0 0 / 0.4),
    0 10px 26px -14px var(--accent-bright);
}

.button--primary:hover {
  background: linear-gradient(to bottom, #17bd7e, var(--accent-hover) 55%, var(--accent));
  box-shadow:
    inset 0 1px 0 #ffffff3d,
    inset 0 0 0 1px #ffffff1a,
    0 1px 2px rgb(0 0 0 / 0.4),
    0 14px 32px -14px var(--accent-bright);
}

.button--primary:active {
  background: linear-gradient(to bottom, var(--accent-deep), #07603e);
  box-shadow: inset 0 1px 3px rgb(0 0 0 / 0.45);
}

.button--block {
  width: 100%;
  padding-block: 0.75rem;
}

/* ---------- Locale switcher ---------- */

.locale-switcher {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

.locale-switcher__label {
  /* Present for screen readers, absent on screen: the select is self-evident. */
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.locale-switcher__select {
  padding: 0.375rem 0.5rem;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--fg-muted);
  font: inherit;
  font-size: 0.8125rem;
}

.locale-switcher__go {
  padding: 0.375rem 0.625rem;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--fg-muted);
  font: inherit;
  font-size: 0.8125rem;
  cursor: pointer;
}

/*
 * With scripting on, the switcher submits on change and the button is redundant.
 * The script adds this class; without it the button stays, so the control works
 * either way.
 */
.locale-switcher--enhanced .locale-switcher__go {
  display: none;
}

/* ---------- Auth: two columns ---------- */

.auth {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  max-width: 68rem;
  margin: 0 auto;
  padding: 1.5rem;
}

.auth__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 0.5rem 2rem;
}

.auth__brand {
  text-decoration: none;
  color: inherit;
}

.auth__brand:hover {
  text-decoration: none;
}

.auth__body {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
  align-items: center;
  flex: 1;
  padding-bottom: 3rem;
}

/*
 * The explanatory column appears only when there is room for it. On a phone the
 * form is the entire reason the page was opened, and pushing it below three
 * paragraphs of copy is how a signup gets abandoned.
 */
.auth__aside {
  display: none;
}

.auth__form-column {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  width: 100%;
  max-width: 27rem;
  margin: 0 auto;
}

@media (min-width: 60rem) {
  .auth__body {
    grid-template-columns: 1fr 27rem;
    gap: 4rem;
  }

  .auth__aside {
    display: block;
  }

  .auth__form-column {
    margin: 0;
  }
}

.auth__tagline {
  margin: 0 0 2rem;
  font-size: 2rem;
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -0.025em;
  max-width: 16ch;
}

.auth__switch {
  margin: 0;
  text-align: center;
  font-size: 0.875rem;
  color: var(--fg-muted);
}

.points {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.points__item {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
}

.points__index {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--accent);
  padding-top: 0.1875rem;
  letter-spacing: 0.05em;
}

.points__title {
  margin: 0 0 0.25rem;
  font-weight: 600;
  font-size: 0.9375rem;
}

.points__body {
  margin: 0;
  font-size: 0.875rem;
  color: var(--fg-muted);
  max-width: 46ch;
}

/* ---------- Password field ---------- */

.field__wrap {
  position: relative;
  display: flex;
}

.field__input--with-action {
  padding-right: 4.25rem;
}

.field__input--code {
  font-family: var(--font-mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/*
 * The PIN field: six digits, big, centred, visible.
 *
 * LARGER THAN EVERY OTHER FIELD ON PURPOSE. This is typed on a phone, several
 * times a day, often one-handed and while moving. Type at the ordinary size with
 * ordinary spacing is type that gets mistyped, and a mistyped PIN costs one of
 * five attempts.
 *
 * NOT `type="password"`. Hiding six digits behind dots guards against somebody
 * reading over a shoulder — real, and rare — at the cost of making every typing
 * mistake invisible on a screen that locks after five of them. Every banking app
 * shows the digits for the same reason.
 */
.field__input--pin {
  font-family: var(--font-mono);
  font-size: 1.5rem;
  letter-spacing: 0.6em;
  /* The letter-spacing is added AFTER the last digit too, which pushes centred
     text half a character left. Taking it back on the right re-centres it. */
  text-indent: 0.6em;
  text-align: center;
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}

.field__input--pin::placeholder {
  letter-spacing: 0.35em;
  font-size: 1.1rem;
}

.field__action {
  position: absolute;
  right: 0.3125rem;
  top: 50%;
  transform: translateY(-50%);
  padding: 0.3125rem 0.5rem;
  background: transparent;
  border: 0;
  border-radius: 6px;
  color: var(--fg-muted);
  font: inherit;
  font-size: 0.75rem;
  font-weight: 500;
  cursor: pointer;
}

.field__action:hover {
  color: var(--fg);
  background: #ffffff0d;
}

.field__optional {
  font-weight: 400;
  color: var(--fg-muted);
  opacity: 0.7;
}

.field__optional::before {
  content: ' · ';
}

/* ---------- Password strength meter ---------- */

.meter {
  display: flex;
  align-items: center;
  gap: 0.625rem;
}

.meter__track {
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: var(--bg-input);
  overflow: hidden;
}

.meter__fill {
  height: 100%;
  width: 0;
  border-radius: 2px;
  background: var(--danger);
  transition:
    width 160ms ease,
    background-color 160ms ease;
}

.meter__label {
  margin: 0;
  font-size: 0.75rem;
  color: var(--fg-muted);
  min-width: 5rem;
  text-align: right;
}

.meter--weak .meter__fill {
  background: var(--danger);
}
.meter--fair .meter__fill {
  background: var(--warning);
}
.meter--good .meter__fill,
.meter--strong .meter__fill {
  background: var(--accent);
}

/* ---------- Buttons: ghost ---------- */

.button--ghost {
  background: transparent;
  border-color: var(--border-strong);
  color: var(--fg-muted);
  font-weight: 500;
}

.button--ghost:hover {
  color: var(--fg);
  background: #ffffff08;
}

/* ---------- Application shell ---------- */

.page-app {
  background: var(--bg);
}

.shell {
  display: grid;
  grid-template-columns: 1fr;
  min-height: 100dvh;
}

@media (min-width: 60rem) {
  .shell {
    grid-template-columns: 15rem 1fr;
  }
}

.sidebar {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  padding: 1.25rem;
  background: var(--bg-raised);
  border-right: 1px solid var(--border);
}

.sidebar__brand {
  text-decoration: none;
  color: inherit;
  padding-block: 0.25rem;
}

.sidebar__brand:hover {
  text-decoration: none;
}

.sidebar__nav {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  flex: 1;
}

/*
 * TWO COLUMNS, AND THE SECOND ONE STACKS.
 *
 * It was a single flex row: icon, label, and then whatever the item carried —
 * which meant the farm status pushed "Dashboard" into "Dashboa…". The name of a
 * menu entry is the one thing on it that must never be abbreviated; a status
 * that costs the label its last four letters is worse than no status.
 *
 * The icon holds its own column and the text column stacks: name on the first
 * line, state underneath in small type. The label now has the whole width and
 * the row grows by ten pixels only on the entries that actually carry something.
 */
.sidebar__link {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  column-gap: 0.75rem;
  padding: 0.4375rem 0.75rem;
  border-radius: var(--radius-sm);
  color: var(--fg-muted);
  font-size: 0.9375rem;
  text-decoration: none;
}

/* The icon spans both rows so it stays centred against the pair. */
.sidebar__link > .icon {
  grid-row: 1 / -1;
}

.sidebar__label {
  grid-column: 2;
  overflow: visible;
  text-overflow: clip;
}

/*
 * The state and the unread count go under the name, not beside it. Line height
 * pulled in hard: this is a second line on a menu item, and the default leading
 * would make every entry that has one noticeably taller than the rest.
 */
.sidebar__state,
.sidebar__badge {
  grid-column: 2;
  justify-self: start;
  line-height: 1.1;
  margin-top: 0.0625rem;
}

.sidebar__link:hover {
  color: var(--fg);
  background: #ffffff08;
  text-decoration: none;
}

.sidebar__link--active {
  color: var(--fg);
  background: var(--accent-soft);
}

.sidebar__link--soon {
  opacity: 0.45;
  cursor: default;
}

.sidebar__link--soon:hover {
  background: transparent;
  color: var(--fg-muted);
}

/*
 * Navigation icons take the link's own colour, so they dim with the label when
 * inactive and light up with it when the page is current. A permanently accent
 * coloured icon column reads as eight things all being emphasised at once.
 */
.sidebar__link .icon {
  width: 1.15rem;
  height: 1.15rem;
  opacity: 0.75;
  transition: opacity 0.12s ease;
}

.sidebar__link:hover .icon,
.sidebar__link--active .icon {
  opacity: 1;
}

.sidebar__link--soon .sidebar__icon {
  color: var(--fg-muted);
}

.sidebar__soon {
  margin-left: auto;
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--fg-muted);
}

.sidebar__foot {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}

.sidebar__email {
  margin: 0;
  font-size: 0.75rem;
  color: var(--fg-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.shell__main {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/*
 * GLASS, AND ONLY WHERE SOMETHING FLOATS OVER SOMETHING ELSE.
 *
 * Frosted panels everywhere is the single clearest tell of a generated
 * interface: it is applied because it is available, to cards that are not on top
 * of anything, where there is nothing to see through and the blur is decoration.
 *
 * Used correctly it is the opposite. Three surfaces here genuinely sit ABOVE the
 * page — the sticky top bar, the help button and the cookie banner — and for
 * those, letting the content underneath show through blurred is what tells the
 * eye which layer is which. It is also what iOS and Telegram itself do, so it
 * reads as native rather than as an effect.
 *
 * `saturate` alongside the blur because a plain blur over a dark page goes grey;
 * pushing the colour back up is what keeps it looking like glass rather than
 * like fog. And every one of these keeps a solid fallback colour first, for the
 * browsers that do not support it.
 */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.125rem 1.75rem;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  /*
   * THE LANGUAGE MENU OPENED UNDERNEATH THE BALANCE BAR.
   * `backdrop-filter` below makes this bar its own stacking context, and a
   * stacking context is a sealed box: the `z-index: 40` on the open language
   * list stopped meaning "above the page" and started meaning "above the other
   * things inside the top bar" — which was nothing. The bar itself then sat at
   * `auto`, so the balance bar right after it in the document painted over the
   * open menu.
   *
   * The glass is worth keeping, so the bar is lifted instead. 30 is above the
   * page and below the support button and the mobile drawer, which are the two
   * things that genuinely belong on top of an open dropdown.
   */
  position: relative;
  z-index: 30;
}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .topbar {
    background: #060b09b8;
    -webkit-backdrop-filter: blur(18px) saturate(150%);
    backdrop-filter: blur(18px) saturate(150%);
  }
}

.topbar__title {
  margin: 0;
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.content {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  padding: 1.75rem;
  max-width: 72rem;
  width: 100%;
}

/* ---------- Stats ---------- */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.875rem;
}

.stat {
  position: relative;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.125rem 1.25rem;
  /*
   * A faint highlight along the top inside edge. One line, and it is most of
   * what makes a tile look like an object instead of a rectangle.
   */
  box-shadow: inset 0 1px 0 #ffffff0f;
}

.stat--accent {
  border-color: #0093fd33;
  background: linear-gradient(var(--accent-soft), var(--accent-soft)), var(--bg-card);
}

/*
 * Used for figures that are normal but should not be comfortable — chiefly
 * "how much is sitting on hot keys". Amber rather than red: nothing is wrong,
 * and a red number that is red every day stops being read.
 */
.stat--warning {
  border-color: #f59e0b40;
  background: linear-gradient(rgba(245, 158, 11, 0.06), rgba(245, 158, 11, 0.06)), var(--bg-card);
}

.stat__label {
  margin: 0 0 0.5rem;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-muted);
}

.stat__value {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.stat__unit {
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--fg-muted);
}

.stat__hint {
  margin: 0.375rem 0 0;
  font-size: 0.75rem;
  color: var(--fg-muted);
}

/* ---------- Grid ---------- */

.grid {
  display: grid;
  gap: 1.25rem;
}

@media (min-width: 55rem) {
  .grid--2 {
    grid-template-columns: 1fr 1fr;
  }
}

/* ---------- Cycle rows ---------- */

.cycle {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.cycle__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

.cycle__label {
  font-size: 0.875rem;
  color: var(--fg-muted);
}

.cycle__value {
  font-size: 0.9375rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.code {
  font-family: var(--font-mono);
  letter-spacing: 0.1em;
  color: var(--accent);
}

/*
 * An <svg>, because the filled-div version could not work under this site's
 * Content-Security-Policy — see the note on `progress()` in views/ui.js. The
 * fill is a rect whose width is an attribute; only its colour is CSS.
 */
.progress {
  display: block;
  width: 100%;
  height: 6px;
  border-radius: 3px;
  background: var(--bg-input);
  overflow: hidden;
}

.progress__fill {
  fill: var(--accent);
  transition: width 400ms linear;
}

/* ---------- Tables ---------- */

.card__content--flush {
  padding: 0;
}

/*
 * A wide table scrolls inside its own box. Without this the whole page scrolls
 * sideways on a phone, which moves the navigation off screen too.
 */
.table-wrap {
  overflow-x: auto;
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.table th,
.table td {
  padding: 0.6875rem 1.5rem;
  text-align: left;
  white-space: nowrap;
}

.table thead th {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-muted);
  font-weight: 500;
  border-bottom: 1px solid var(--border);
}

.table tbody tr + tr td {
  border-top: 1px solid var(--border);
}

.table__num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.table__dim {
  color: var(--fg-muted);
}

/*
 * A column that holds a sentence rather than a value.
 *
 * Cells above do not wrap, which keeps a date or an amount from breaking in the
 * middle. Applied to an explanation it is a disaster: on a 768-wide tablet the
 * "what it means" column of the reward table stretched to 956 pixels and every
 * line was clipped by the table's own scroller. Nothing reported it — the page
 * did not overflow, the table just quietly cut its own text off.
 *
 * `min-width` stops the opposite failure, where a narrow prose column squeezes
 * to one word per line beside a wide numeric one.
 */
/*
 * Written as `.table td.table__prose` rather than `.table__prose` alone because
 * `.table td` above is the more specific selector and simply won out — the class
 * was on the cell, in the stylesheet, and doing nothing at all.
 */
.table th.table__prose,
.table td.table__prose {
  white-space: normal;
  min-width: 12rem;
  max-width: 34rem;
}

/*
 * Tighter cells on a tablet, where the table is still a table but the screen is
 * not a desktop's.
 *
 * On an iPad in portrait the closed-cycles table came to 803 pixels in a 768
 * pixel window, so its last column — the net figure, the one the whole row is
 * about — sat off the right edge behind a sideways scroll nobody would think to
 * try. It was over by sixty pixels; the 24-pixel gutters on six columns are a
 * hundred and forty-four of them.
 *
 * Bounded below at 46rem so it cannot touch the card layout, which sets its own
 * padding and needs the roomier one.
 */
@media (min-width: 46.0625rem) and (max-width: 60rem) {
  .table th,
  .table td {
    padding-left: 0.625rem;
    padding-right: 0.625rem;
  }

  /*
   * And the monospaced cells a notch down with them. Geist Mono is a little
   * wider than the platform monospace it replaced, which put the history table
   * five pixels over its wrapper on an iPad — invisible until measured, and a
   * column of dates hidden behind a sideways scroll once it happened.
   */
  .table .mono,
  .table .hashcell {
    font-size: 0.8125rem;
  }
}

.amount--in {
  color: var(--accent);
}

.amount--out {
  color: var(--fg-muted);
}

/*
 * A list with nothing in it yet.
 *
 * A new account meets several of these before it meets anything else, so for the
 * first few minutes they are the product. A drawn mark, a sentence and — where
 * the caller offers one — the single action that would fill the list.
 */
.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  padding: 2.5rem 1.5rem;
  text-align: center;
}

.empty__mark {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  color: var(--fg-subtle);
  background: #ffffff05;
  box-shadow: inset 0 0 0 1px #ffffff0a;
}

.empty__text {
  margin: 0;
  max-width: 34ch;
  color: var(--fg-muted);
}

.prose--dim {
  font-size: 0.8125rem;
  opacity: 0.85;
}

.callout--muted {
  background: var(--bg-raised);
  border-color: var(--border);
}

.callout--muted .callout__title {
  color: var(--fg);
}

/* ---------- Page header ---------- */

.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.page-header__title {
  margin: 0;
  font-size: 1.375rem;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.page-header__description {
  margin: 0.3125rem 0 0;
  color: var(--fg-muted);
  font-size: 0.9375rem;
  max-width: 62ch;
}

/*
 * A page header that is only its lede — no heading, because the top bar already
 * carries the section name.
 *
 * The sentence stands alone now, so it is given a little more presence than a
 * subtitle tucked under a title needs: without that it reads as a caption for
 * nothing. The top margin comes off for the same reason — there is no longer a
 * heading above it to be spaced away from.
 */
.page-header--lede .page-header__description {
  margin-top: 0;
  font-size: 1rem;
  color: #b6c1bb;
}

/* ---------- Data rows ---------- */

.data-grid {
  display: grid;
  gap: 0 2rem;
}

@media (min-width: 48rem) {
  .data-grid--2 {
    grid-template-columns: 1fr 1fr;
  }
  .data-grid--3 {
    grid-template-columns: repeat(3, 1fr);
  }
}

.data-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 0.625rem;
}

.data-row + .data-row {
  border-top: 1px solid var(--border);
}

@media (min-width: 48rem) {
  .data-grid--2 > .data-row:nth-child(-n + 2),
  .data-grid--3 > .data-row:nth-child(-n + 3) {
    border-top: 0;
  }
}

.data-row__label {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  font-size: 0.875rem;
  color: var(--fg-muted);
}

.data-row__hint {
  font-size: 0.75rem;
  opacity: 0.75;
}

.data-row__value {
  font-size: 0.9375rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

.data-row__value--accent {
  color: var(--accent);
}

.data-row__value--muted {
  color: var(--fg-muted);
}

.unit {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--fg-muted);
}

/* ---------- Tier grid ---------- */

.tier-grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
}

@media (min-width: 45rem) {
  .tier-grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (min-width: 78rem) {
  .tier-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

.tier__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.tier__description {
  min-height: 3.25rem;
  font-size: 0.8125rem;
}

.card--highlighted {
  box-shadow:
    var(--shadow-card),
    0 0 0 1px #0093fd33;
}

/*
 * A highlighted TIER card is highlighted in its own colour, not in the brand
 * blue. Otherwise the card marked "your tier" is the one card in the grid whose
 * frame contradicts the dot and the tagline inside it.
 */
.tier.card--highlighted {
  background: linear-gradient(to bottom, var(--tier-soft), var(--bg-card) 55%);
  box-shadow:
    var(--shadow-card),
    0 0 0 1px var(--tier-soft),
    0 18px 40px -28px var(--tier-glow);
}

.tier.edge--accent::before {
  background: linear-gradient(to bottom, var(--tier-glow), var(--tier-soft));
}

.card__footer {
  padding: 1rem 1.5rem;
  border-top: 1px solid var(--border);
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}

/* ---------- Moving between sections ---------- */

/*
 * THE SITE SHOULD NOT LOOK LIKE IT IS RELOADING WHEN A SECTION IS OPENED.
 *
 * app.js fetches the next page and puts its content in place; these rules are
 * what make that read as a response rather than as a redraw. Both halves are
 * optional — with the script absent, or in a browser without view transitions,
 * nothing here applies and the site navigates exactly as it always did.
 */

/*
 * The furniture holds still. Naming an element means the browser carries it
 * across the transition as the same object instead of cross-fading the old copy
 * into an identical new one — so the bar, the drawer and the balances stay put
 * and only the content underneath changes.
 */
@supports (view-transition-name: none) {
  .topbar {
    view-transition-name: topbar;
  }

  .sidebar {
    view-transition-name: sidebar;
  }

  .balancebar {
    view-transition-name: balancebar;
  }

  .content {
    view-transition-name: content;
  }

  /*
   * Quick, and only on the content. Long enough to read as motion, short enough
   * that it never delays somebody who knows where they are going. The default
   * is a quarter of a second, which on a control you press repeatedly is a lot.
   */
  ::view-transition-old(content),
  ::view-transition-new(content) {
    animation-duration: 140ms;
  }

  ::view-transition-old(topbar),
  ::view-transition-new(topbar),
  ::view-transition-old(sidebar),
  ::view-transition-new(sidebar),
  ::view-transition-old(balancebar),
  ::view-transition-new(balancebar) {
    /* Held rather than animated: these are the same elements either side. */
    animation: none;
    mix-blend-mode: normal;
  }
}

/*
 * The thin bar along the top while a page is on its way.
 *
 * IT DOES NOT PRETEND TO KNOW HOW FAR ALONG IT IS. A progress bar that fills to
 * a fraction it invented is a lie; this one travels the width and repeats, which
 * says "working" and claims nothing else. On a fast answer it is on screen for
 * about a tenth of a second and reads as a flicker of acknowledgement, which is
 * exactly what a pressed button owes you.
 */
html::after {
  content: '';
  position: fixed;
  inset: 0 auto auto 0;
  height: 2px;
  width: 100%;
  z-index: 200;
  transform-origin: 0 50%;
  background: linear-gradient(to right, transparent, var(--accent-bright), transparent);
  opacity: 0;
  pointer-events: none;
}

html.is-navigating::after {
  opacity: 1;
  animation: nav-sweep 900ms linear infinite;
}

@keyframes nav-sweep {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(100%);
  }
}

/*
 * A pressed control looks pressed. This is the other half of the complaint that
 * the site felt like a page rather than an application: on a phone there is no
 * hover, so between the tap and the new content there was no sign that anything
 * had been registered at all.
 */
.sidebar__link:active,
.pager__step:active,
.pager__page:active,
.tabs__link:active {
  transform: scale(0.985);
}

/* ---------- The operations console, tightened ---------- */

/*
 * THE CONSOLE IS NOT THE SITE, and it was being spaced like it.
 *
 * The public pages are read once by somebody deciding whether to trust us, and
 * air is part of that. This screen is opened every day by one person looking for
 * a number and a button, and there the same air means scrolling past things they
 * already know to reach the thing they came for. The owner's words were "giant
 * vertical distances", and they were right.
 *
 * Only spacing changes here. Nothing is hidden and no target gets smaller than a
 * thumb, because a cramped control that is hard to hit costs more than the room
 * it saved.
 */
.shell--admin .content {
  gap: 0.75rem;
}

.shell--admin .card {
  margin: 0;
}

.shell--admin .card__title {
  padding: 0.7rem 1rem 0;
  font-size: 1rem;
}

.shell--admin .card__content {
  padding: 0.7rem 1rem;
}

.shell--admin .card__content--flush {
  padding: 0;
}

.shell--admin .card__footer {
  padding: 0.5rem 1rem;
}

.shell--admin .stats {
  gap: 0.5rem;
}

.shell--admin .stat {
  padding: 0.6rem 0.75rem;
}

.shell--admin .table td,
.shell--admin .table th {
  padding-top: 0.45rem;
  padding-bottom: 0.45rem;
}

/* A table straight after another one in the same card reads as one block. */
.shell--admin .card__content > .table-wrap + .table-wrap {
  border-top: 1px solid var(--line);
}

.shell--admin .prose {
  margin: 0.3rem 0;
  font-size: 0.875rem;
}

.shell--admin .prose + .prose {
  margin-top: 0.2rem;
}

.shell--admin .callout {
  padding: 0.6rem 0.85rem;
}

/* The section tabs sit tight under the top bar rather than floating. */
.shell--admin .tabs {
  margin-bottom: 0.25rem;
}

/* A small control sitting in a card footer beside its caption. */
.cardhead {
  display: inline-flex;
}

/* Two buttons on one row, side by side rather than stacked. */
.rowacts {
  display: inline-flex;
  gap: 0.35rem;
  flex-wrap: wrap;
}

/*
 * What is moving right now, under the button that started it.
 *
 * It used to be a card of its own, three below the button — so pressing
 * something and then looking for what it did meant scrolling past two other
 * things. A job belongs under the control that starts it.
 */
.running__job {
  padding: 0.5rem 0;
  border-top: 1px solid var(--line);
}

.running__job:first-child {
  border-top: 0;
}

.running__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  font-size: 0.875rem;
}

.running__sum {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  margin-left: auto;
}

/*
 * The wallets, folded away below the work. Not a person, so not in the list of
 * people — it spent a version pretending to be an account called "Wallet
 * addresses and gas".
 */
.fold {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
}

.fold__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.6rem 1rem;
  cursor: pointer;
  font-size: 0.8125rem;
  color: var(--fg-muted);
  list-style: none;
}

.fold__head::-webkit-details-marker {
  display: none;
}

.fold__head::before {
  content: '▸';
  font-size: 0.7rem;
}

.fold[open] > .fold__head::before {
  content: '▾';
}

.fold__body {
  border-top: 1px solid var(--line);
}

/* The Money screen's permanent wallet reference panel. */
.wallets-panel {
  overflow: hidden;
}

.wallets-panel > .card__content {
  gap: 0.75rem;
}

.wallet-addresses {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.5rem;
}

.wallet-address {
  min-width: 0;
  padding: 0.65rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: linear-gradient(145deg, #ffffff08, #ffffff02);
}

.wallet-address__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.45rem;
}

.wallet-address__head strong {
  font-size: 0.8125rem;
}

.wallet-address__head span {
  color: var(--fg-muted);
  font-size: 0.625rem;
  text-align: right;
}

.wallet-address__value {
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  min-width: 0;
}

.wallet-address__value > .mono {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
  word-break: break-all;
  white-space: normal;
  color: var(--fg);
  font-size: 0.6875rem;
  line-height: 1.35;
  user-select: all;
}

.wallet-address__copy {
  flex: 0 0 auto;
  padding: 0.2rem 0.42rem;
  border: 1px solid var(--line-strong);
  border-radius: 0.4rem;
  background: var(--bg-input);
  color: var(--accent-bright);
  font: inherit;
  font-size: 0.6875rem;
  font-weight: 650;
  cursor: pointer;
}

.wallet-address__copy:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.wallet-address__copy.is-copied {
  border-color: var(--ok);
  color: var(--ok);
}

.gas-funding { display: grid; gap: .6rem; min-width: 0; }
.gas-funding__group{min-width:0;display:grid;align-content:start;gap:.55rem;border:1px solid var(--line);border-radius:.8rem;padding:.7rem;background:var(--bg-raised)}
.gas-funding__group>header{display:flex;flex-wrap:wrap;justify-content:space-between;gap:.3rem;font-size:.8rem}
.gas-funding__group>header small{font-size:.65rem;color:var(--fg-muted)}
.gas-funding__columns,.gas-funding__coinrow{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr) minmax(0,1fr);gap:.45rem;align-items:center;font-size:.7rem}
.gas-funding__columns{font-size:.6rem;color:var(--fg-muted)}
.gas-funding__columns>:not(:first-child),.gas-funding__coinrow>:not(:first-child){text-align:right;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}
.gas-funding__coinrow{padding:.45rem 0;border-top:1px solid var(--line)}
.gas-funding__coin{display:flex;align-items:center;gap:.4rem;min-width:0}
.gas-funding__coin .coin{width:22px;height:22px;flex:none}
.gas-funding__coin small{display:block;color:var(--fg-muted);font-size:.6rem;line-height:1.4}
.wallets-panel .wallet-addresses{grid-template-columns:repeat(2,minmax(0,1fr))}
.gas-funding__tron{min-width:0;display:grid;gap:.2rem;padding-bottom:.3rem}
.gas-funding__tron .wallet-address__value{margin:0}
.wallet-address__head strong{display:flex;align-items:center;gap:.4rem;min-width:0}
.direct-pending{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:.75rem}
.direct-pending>div{display:flex;align-items:center;gap:.4rem;padding:.4rem .6rem;border:1px solid var(--line);border-radius:10px;font-size:.75rem}
.direct-pending small{opacity:.65}
@media(max-width:600px){.wallets-panel .wallet-addresses{grid-template-columns:minmax(0,1fr)}}
.deposit-choice [hidden]{display:none!important}
.deposit-choice .depositqr{margin-block:.875rem}
.deposit-choice .deposit__address{overflow-wrap:anywhere;word-break:break-all;white-space:normal}
.deposit-choice__pair{display:flex;gap:.4rem;justify-content:center;align-items:center;flex-wrap:wrap;margin:.5rem 0;font-size:.8rem}
.deposit-choice__pair .coin{width:22px;height:22px}
.deposit-choice__actions{display:flex;justify-content:center;padding:.65rem .5rem .4rem;min-width:0}
.collection-refresh{display:flex;justify-content:flex-end;margin:0 0 .6rem}
.collection-status__balance,.collection-status__state{display:flex;flex-direction:column;gap:.25rem;min-width:0}
.collection-status__balance small{color:var(--muted);font-size:.65rem;white-space:normal}
.collection-status__issue{font-size:.7rem;color:var(--muted);max-width:24rem;white-space:normal;overflow-wrap:anywhere}
.collection-status__issue summary{cursor:pointer}
.collection-status__issue code{display:block;margin-top:.3rem;font-size:.62rem;overflow-wrap:anywhere}
.collection-status__results{display:grid;grid-template-columns:repeat(auto-fit,minmax(10rem,1fr));gap:.75rem;margin-bottom:.75rem}
.collection-status__result{display:flex;flex-direction:column;align-items:flex-start;gap:.65rem;min-width:0;padding:1rem;border:1px solid var(--line);border-radius:.75rem}
.collection-status__result>span:first-child{overflow-wrap:anywhere}
.collection-status__details>summary{cursor:pointer;padding:.4rem 0}
.collection-status__details>.table-wrap{margin-top:.75rem}
.collection-status__list{display:block}
.collection-status__list .table-wrap{margin:0}
.collection-status__transactions{font-size:.75rem;min-width:0;overflow-wrap:anywhere}
.collection-status__transactions>summary{cursor:pointer;white-space:nowrap}
.collection-status__transaction{display:flex;flex-direction:column;gap:.35rem;padding:.65rem 0;border-bottom:1px solid var(--line)}
.collection-status__transaction small{color:var(--muted)}
@media(max-width:700px){
  .collection-status__list .table tr{border:0;border-bottom:1px solid var(--line);border-radius:0;margin:0;padding:.85rem 0;box-shadow:none;background:transparent}
  .collection-status__list .table td{padding:.3rem 0}
}
.deposit-choice .deposit-choice__copy{flex:0 1 auto;width:auto;max-width:100%;min-height:2.25rem;margin:0;padding:.4rem .85rem;font-size:.78rem;line-height:1.3;white-space:normal;box-shadow:none}
.deposit-choice .field__hint{line-height:1.5}
.pickgrid__item[hidden]{display:none!important}
.pickgrid__button:disabled{opacity:1;cursor:default}
.pickgrid__button:disabled .pickgrid__arrow{visibility:hidden}
.gas-funding__hint { margin: .25rem 0; color: var(--fg-muted); font-size: .7rem; line-height: 1.5; }
.gas-funding__network { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .55rem; padding: .65rem; border: 1px solid var(--line); border-radius: .8rem; min-width: 0; }
.gas-funding__network > header { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .25rem .65rem; font-size: .8rem; }
.gas-funding__network > header > span { color: var(--accent-bright); font-size: .7rem; }
.gas-funding__wallet { display: grid; gap: .4rem; min-width: 0; padding: .6rem; background: var(--bg-raised); border: 1px solid var(--line); border-radius: .6rem; }
.gas-funding__title,.gas-funding__amount { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: .2rem .5rem; min-width: 0; font-size: .7rem; }
.gas-funding__title > span,.gas-funding__wallet > small,.gas-funding__amount > span { color: var(--fg-muted); font-size: .625rem; }
.gas-funding__title > .amount--out { color: var(--danger, #ee8888); }
.gas-funding__amount > strong { overflow-wrap: anywhere; font-size: .7rem; font-variant-numeric: tabular-nums; }
.gas-funding__notice { grid-column: 1 / -1; color: var(--fg-muted); font-size: .65rem; line-height: 1.5; }
.gas-funding__pending { display: flex; flex-wrap: wrap; gap: .2rem .7rem; padding: .5rem .65rem; border: 1px solid var(--line); border-radius: .6rem; font-size: .7rem; }
.gas-funding__pending > span { color: var(--fg-muted); font-size: .65rem; }
.gas-funding__path { overflow-wrap: anywhere; font-size: .6rem; }
@media (min-width: 1200px) { .gas-funding { grid-template-columns: repeat(2, minmax(0, 1fr)); } .gas-funding__hint,.gas-funding__pending { grid-column: 1 / -1; } }
@media (max-width: 600px) { .gas-funding__network { grid-template-columns: minmax(0, 1fr); padding: .5rem; } }

.wallet-gas {
  display: grid;
  gap: 0.35rem;
}

.wallet-gas__row {
  display: grid;
  grid-template-columns: minmax(8rem, 1fr) minmax(9rem, auto) minmax(9rem, auto);
  align-items: center;
  gap: 0.8rem;
  padding: 0.45rem 0.65rem;
  border: 1px solid var(--line);
  border-radius: 0.6rem;
  background: var(--bg-raised);
}

.wallet-gas__network {
  font-size: 0.8125rem;
}

.wallet-gas__balance {
  display: grid;
  gap: 0.05rem;
  text-align: right;
}

.wallet-gas__balance > span {
  color: var(--fg-muted);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.wallet-gas__balance > strong {
  font-size: 0.75rem;
  font-weight: 650;
}

.wallets-panel__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  width: 100%;
}

.wallets-panel__footer form {
  margin-left: auto;
}

/*
 * Below the breakpoint the columns collapse the way the console's tables do:
 * the header goes, the row becomes two lines, and each figure carries its own
 * label so a bare number never has to be guessed at.
 */
@media (max-width: 60rem) {
  .wallet-addresses {
    grid-template-columns: 1fr;
  }

  .people__legend {
    display: none;
  }

  .people__head {
    grid-template-columns: 0.9rem minmax(0, 1fr) auto;
    row-gap: 0.3rem;
  }

  .people__when {
    grid-column: 2 / -1;
    order: 2;
  }

  .people__num {
    grid-column: auto;
    order: 3;
    text-align: left;
  }

  .people__num::before {
    content: attr(data-label) ' ';
    color: var(--fg-subtle);
    font-size: 0.6875rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
  }

  .people__do {
    grid-column: 1 / -1;
    order: 4;
    justify-content: flex-start;
  }
}


/* The one action a row carries, sitting with the figures rather than under them. */

@media (max-width: 40rem) {
  .people__figs {
    gap: 0.6rem;
    font-size: 0.8125rem;
  }
}

/* ---------- A field that is refusing what was typed ---------- */

/*
 * `:user-invalid` AND NOT `:invalid`, and the difference is the whole reason
 * this rule is usable. `:invalid` matches from the moment the page loads, so a
 * required field that has never been touched is drawn as an error — the form
 * greets somebody with three red boxes for the crime of existing.
 * `:user-invalid` waits until they have actually typed something and moved on.
 */
.field__input:user-invalid,
.field__input[aria-invalid='true'] {
  border-color: var(--danger);
}

.field__input:user-invalid:focus,
.field__input[aria-invalid='true']:focus {
  outline-color: var(--danger);
}

/*
 * The sentence under the field. Sits between the input and the hint, in the
 * place the eye is already travelling to, rather than at the top of the form
 * where errors usually go and where nobody looks while typing.
 */
.field__error {
  margin: 0.35rem 0 0;
  color: var(--danger);
  font-size: 0.8125rem;
  font-weight: 600;
}

.field__error[hidden] {
  display: none;
}

/* ---------- Putting a message away, and following a job ---------- */

.callout__title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
}

/* Big enough to hit, quiet enough not to compete with the message itself. */
.callout__close {
  flex: 0 0 auto;
  margin: -0.4rem -0.3rem -0.4rem 0;
  padding: 0.15rem 0.5rem;
  border-radius: var(--radius-sm);
  color: inherit;
  opacity: 0.55;
  font-size: 1.1rem;
  line-height: 1.4;
  text-decoration: none;
}

.callout__close:hover {
  opacity: 1;
  background: #ffffff14;
}

/*
 * The stages of a job.
 *
 * A word like "exchanging" says what is happening and nothing about how far
 * along it is. This says both: what is finished, what is running, and what is
 * still to come, on a job that takes several transactions across two chains.
 */
/*
 * A list, one line per transaction, rather than three words in a row.
 *
 * The row version summarised and did not report: nothing on it moved while four
 * transactions went out, so the screen looked frozen when it was busiest.
 */
.trail {
  margin: 0.35rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.75rem;
  display: grid;
  gap: 0.1rem;
}

.trail__step {
  display: grid;
  grid-template-columns: 0.9rem 1fr auto auto;
  align-items: baseline;
  gap: 0.4rem;
  color: var(--fg-subtle);
}

.trail__mark {
  text-align: center;
}

.trail__state {
  font-variant: small-caps;
  letter-spacing: 0.04em;
  opacity: 0.8;
}

.trail__hash {
  opacity: 0.55;
}

.trail__step--done {
  color: var(--fg-muted);
}

.trail__step--done .trail__mark {
  color: var(--accent-bright);
}

/* The one that is happening. The only line drawn at full strength. */
.trail__step--now {
  color: var(--fg);
  font-weight: 600;
}

.trail__step--now .trail__mark {
  color: var(--warning);
}

.trail__step--bad,
.trail__step--bad .trail__mark {
  color: var(--danger);
}

@media (max-width: 40rem) {
  .trail__step {
    grid-template-columns: 0.9rem 1fr auto;
  }

  .trail__hash {
    display: none;
  }
}

/* ---------- Paging ---------- */

/*
 * THE STRIP UNDER A PAGED TABLE.
 *
 * It lives in the card footer, so it inherits that footer's rule above it and
 * needs no border of its own. Laid out as three parts — back, numbers, forward —
 * with the numbers taking the middle so the two steps stay pinned to the edges
 * and the control does not shuffle sideways as the page count changes.
 *
 * Every target is at least 2.25rem, which is the smallest thing on this site a
 * thumb is asked to hit. The disabled ends are drawn rather than removed: a
 * control that changes shape at the first and last page is a control that moves
 * under the finger going back the way it came.
 */
.pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  width: 100%;
}

.pager__step {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  min-height: 2.25rem;
  padding: 0 0.7rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  color: var(--fg);
  font-size: 0.8125rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.pager__step:hover {
  border-color: var(--line-strong);
  background: #ffffff0d;
}

.pager__step--off {
  opacity: 0.35;
  cursor: default;
}

.pager__numbers {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.pager__page {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.25rem;
  min-height: 2.25rem;
  padding: 0 0.4rem;
  border-radius: var(--radius-sm);
  color: var(--fg-muted);
  font-size: 0.8125rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
}

.pager__page:hover {
  color: var(--fg);
  background: #ffffff0d;
}

.pager__page--on {
  color: #04120a;
  background: var(--accent);
}

/* Audit rows stay short until their machine-readable evidence is needed. */
.audit-action {
  display: grid;
  gap: 0.15rem;
}

.audit-action > strong {
  font-size: 0.8125rem;
  font-weight: 650;
}

.audit-action > .mono {
  color: var(--fg-muted);
  font-size: 0.6875rem;
}

.audit-detail {
  max-width: 32rem;
}

.audit-detail > summary {
  color: var(--fg);
  cursor: pointer;
  font-size: 0.75rem;
  line-height: 1.35;
}

.audit-detail > pre {
  max-width: 32rem;
  margin: 0.55rem 0 0;
  padding: 0.65rem;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
  color: var(--fg-muted);
  font: 0.6875rem/1.45 var(--font-mono);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/*
 * On a narrow screen the words go and the arrows stay. "Newer" and "Older" are
 * a help on a desktop and a wrapped line on a phone, where the arrows either
 * side of a highlighted page number say the same thing in a third of the room.
 */
@media (max-width: 30rem) {
  .pager__steptext {
    display: none;
  }

  .pager__step {
    padding: 0 0.6rem;
  }
}

/* ---------- Badges ---------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.1875rem 0.5rem;
  border-radius: 999px;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.badge--default,
.badge--muted {
  background: var(--bg-input);
  color: var(--fg-muted);
  border: 1px solid var(--border);
}

.badge--accent {
  background: var(--accent-soft);
  color: var(--accent-bright);
  border: 1px solid #0093fd3d;
}

.badge--danger {
  background: var(--danger-soft);
  color: var(--danger);
  border: 1px solid #f2555a33;
}

/* ---------- Forms: rows, inline, mono ---------- */

.form__row {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
}

@media (min-width: 40rem) {
  .form__row {
    grid-template-columns: 2fr 1fr;
  }
}

.field__input--mono,
.mono {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
}

.field__input--inline {
  margin-bottom: 0.5rem;
}

.address-box {
  margin: 0;
  padding: 0.625rem 0.8125rem;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  word-break: break-all;
}

.button-row {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
}

@media (min-width: 48rem) {
  .button-row {
    grid-template-columns: 1fr 1fr;
  }
}

.button--danger {
  background: transparent;
  border-color: #f2555a55;
  color: var(--danger);
}

.button--danger:hover {
  background: var(--danger-soft);
}

/*
 * FILLED RED, NOT AN OUTLINE.
 *
 * `--danger` above is the outlined treatment used for destructive things buried
 * in settings, where the point is that it does not invite a click. Stopping the
 * farm is the opposite: it is a control somebody is looking for, and it sat
 * beside "Take out" as an identical ghost button — so the act that ends the
 * position looked like the smaller of the two.
 *
 * Filled says "this one is different" without a word of explanation.
 */
.button--stop {
  background: linear-gradient(to bottom, #f2555a, #d43a3f);
  border-color: transparent;
  color: #fff;
  box-shadow:
    inset 0 1px 0 #ffffff33,
    0 6px 16px -8px #f2555a;
}

.button--stop:hover {
  background: linear-gradient(to bottom, #ff6b70, #e04449);
}

.button--stop:active {
  background: linear-gradient(to bottom, #d43a3f, #b62f34);
}

.button--small {
  padding: 0.375rem 0.75rem;
  font-size: 0.8125rem;
}

.prose__strong {
  color: var(--fg);
  font-weight: 600;
}

/* ---------- Inline tabs ---------- */

.tabs--inline {
  display: flex;
  gap: 0.25rem;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
}

.tabs--inline .tabs__tab {
  padding: 0.6875rem 1rem;
  white-space: nowrap;
  background: transparent;
}

/*
 * Narrower gutters where the third tab would otherwise be half a word.
 *
 * The wallet's three tabs came to 307 pixels in a 251 pixel strip on a folded
 * Galaxy, so "Transactions" read as "Transa". The strip scrolls, so nothing was
 * unreachable — it just looked broken, and a tab that looks cut in half does not
 * look like something to swipe.
 *
 * Placed AFTER the rule it narrows: the shorthand `padding` above would win over
 * a `padding-left` written before it, media query or not.
 */
@media (max-width: 20rem) {
  .tabs--inline .tabs__tab {
    padding-left: 0.5rem;
    padding-right: 0.5rem;
    font-size: 0.8125rem;
  }
}

/* ---------- Sidebar groups ---------- */

.sidebar__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.sidebar__group + .sidebar__group {
  margin-top: 1rem;
}

.sidebar__group-label {
  margin: 0 0 0.1875rem;
  padding-left: 0.75rem;
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--fg-muted);
  opacity: 0.7;
}

.sidebar__console {
  margin: 0;
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--accent);
}

.sidebar__admin {
  font-size: 0.75rem;
  color: var(--accent);
}

/* ---------- Mode toggle and demo banner ---------- */

.mode__button {
  padding: 0.375rem 0.6875rem;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--fg-muted);
  font: inherit;
  font-size: 0.75rem;
  cursor: pointer;
  white-space: nowrap;
}

.mode__button:hover {
  color: var(--fg);
}

.mode__button--demo {
  border-color: #f5a52455;
  color: var(--warning);
  background: var(--warning-soft);
}

.demo-banner {
  padding: 0.6875rem 1.75rem;
  background: var(--warning-soft);
  border-bottom: 1px solid #f5a52433;
  color: var(--warning);
  font-size: 0.8125rem;
}

/* ---------- Mobile navigation ---------- */

/*
 * The sidebar collapses behind a checkbox on small screens. A checkbox and a
 * label, not a script: the menu opens with JavaScript switched off, and there is
 * no state to get stuck in.
 */
.topbar__burger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  color: var(--fg-muted);
  cursor: pointer;
  user-select: none;
}

@media (min-width: 60rem) {
  .topbar__burger {
    display: none;
  }
}

@media (max-width: 59.99rem) {
  /*
   * THE MENU IS A PANEL OVER THE PAGE, NOT A BLOCK INSERTED INTO IT.
   *
   * It used to be `display: none` flipped to `display: flex`, which put the
   * whole sidebar into the document flow above the content: opening the menu
   * pushed the page down, the section you were reading disappeared below the
   * fold, and closing it jumped you somewhere else. On a phone that reads as the
   * app losing your place, and inside Telegram — where the sheet is already
   * short — it was most of the screen.
   *
   * Now it slides in over the content from the left, with the page dimmed behind
   * it. Nothing moves underneath, so closing puts you back exactly where you
   * were.
   *
   * STILL NO SCRIPT. It is the same hidden checkbox and the same label; only the
   * geometry changed. The menu works with JavaScript switched off, which is what
   * it was built for.
   */
  .sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 60;
    width: min(17rem, 82vw);
    /* Off-screen rather than hidden: a `display: none` panel cannot animate, and
       cannot be reached by a keyboard on the way in either. */
    transform: translateX(-100%);
    transition: transform 0.22s ease;
    overflow-y: auto;
    box-shadow: var(--shadow-raised);
    /* Telegram draws its own header over the top of the viewport. */
    padding-top: calc(1.25rem + var(--tg-safe-top, 0px) + var(--tg-content-top, 0px));
    padding-bottom: calc(1.25rem + var(--tg-safe-bottom, 0px));
  }

  .shell__toggle:checked ~ .sidebar {
    transform: translateX(0);
  }

  /*
   * The dimmed page behind it, and the thing you tap to close.
   *
   * A label rather than a script: it is the same control as the burger, so
   * tapping outside the menu closes it exactly as tapping the burger does. It is
   * `aria-hidden` because it duplicates a control that is already in the
   * document, and a screen reader announcing "menu, menu" is worse than silence.
   */
  .shell__scrim {
    position: fixed;
    inset: 0;
    z-index: 55;
    background: rgb(0 0 0 / 0.55);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.22s ease;
  }

  .shell__toggle:checked ~ .shell__scrim {
    opacity: 1;
    pointer-events: auto;
  }

  .topbar {
    padding-inline: 1rem;
  }

  .content {
    padding: 1.25rem 1rem;
  }
}

/* On a wide screen the scrim does not exist at all: the sidebar is a column. */
@media (min-width: 60rem) {
  .shell__scrim {
    display: none;
  }
}

/* ---------- FAQ ---------- */

/*
 * Built on <details>. The browser supplies the open/close behaviour, the
 * keyboard handling and the screen-reader semantics; none of it is reimplemented
 * and none of it depends on a script having loaded.
 */
.faq {
  display: flex;
  flex-direction: column;
}

.faq__item + .faq__item {
  border-top: 1px solid var(--border);
}

.faq__question {
  padding: 0.9375rem 0;
  cursor: pointer;
  font-weight: 500;
  font-size: 0.9375rem;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.faq__question::-webkit-details-marker {
  display: none;
}

/* The marker is drawn rather than relying on the default triangle, which differs
   between browsers and cannot be positioned. */
.faq__question::before {
  content: '+';
  flex-shrink: 0;
  width: 1.125rem;
  color: var(--accent);
  font-size: 1rem;
  text-align: center;
}

.faq__item[open] .faq__question::before {
  content: '−';
}

.faq__question:hover {
  color: var(--fg);
}

.faq__answer {
  padding: 0 0 1rem 1.875rem;
}

/* ---------- Support thread ---------- */

.thread {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.thread__item {
  padding: 0.875rem 1rem;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

/* An operator reply is visually distinct so a user scanning a long thread can
   find the answer without reading their own words again. */
.thread__item--operator {
  background: var(--accent-soft);
  border-color: #0093fd33;
}

.thread__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.375rem;
}

.thread__author {
  font-size: 0.8125rem;
  font-weight: 600;
}

.thread__item--operator .thread__author {
  color: var(--accent);
}

.thread__when {
  font-size: 0.75rem;
  color: var(--fg-muted);
}

.thread__body {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.6;
  /* Preserves the line breaks the user typed without letting a long unbroken
     string push the layout sideways. */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.field__textarea {
  resize: vertical;
  min-height: 6rem;
  line-height: 1.55;
}

.field__label--hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.field__hint--ok {
  color: var(--accent);
}

/* ---------- Support button, bottom right ---------- */

/*
 * A link, not a widget. Nothing is loaded from another origin, nothing runs, and
 * it works with scripting off.
 */
.support-fab {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 50;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6875rem 1rem;
  border-radius: 999px;
  background: var(--accent);
  color: #04120a;
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
  box-shadow: 0 6px 20px -6px rgb(0 0 0 / 0.7);
  transition: transform 120ms ease;
}

.support-fab:hover {
  text-decoration: none;
  transform: translateY(-1px);
}

.support-fab__icon {
  font-size: 1rem;
  line-height: 1;
}

/* On a phone the label is dropped rather than the whole control: a bare icon is
   still recognisable, and a full-width pill would cover the content. */
@media (max-width: 40rem) {
  .support-fab__label {
    display: none;
  }

  .support-fab {
    padding: 0.75rem;
  }
}

.support-fab__icon svg {
  display: block;
}

.support-fab__badge {
  position: absolute;
  top: -0.32rem;
  right: -0.32rem;
  display: grid;
  place-items: center;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 0.3rem;
  border: 2px solid var(--bg);
  border-radius: 999px;
  background: #ef5350;
  color: white;
  font-size: 0.66rem;
  font-weight: 750;
  line-height: 1;
  box-shadow: 0 4px 12px rgb(0 0 0 / 0.3);
}

.support-fab__badge[hidden] {
  display: none;
}

/* ---------- support mini-chat popup + greeting ---------- */

.support-pop {
  position: fixed;
  right: 1.25rem;
  bottom: calc(1.25rem + 3.6rem);
  z-index: 51;
  width: min(370px, calc(100vw - 1.5rem));
  height: min(72dvh, 33rem);
  display: flex;
  flex-direction: column;
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-raised);
  overflow: hidden;
}

.support-pop__close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 2;
  width: 1.9rem;
  height: 1.9rem;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: #ffffff14;
  color: var(--fg);
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
}
.support-pop__close:hover {
  background: #ffffff26;
}

.support-pop__body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
}
.support-pop__loading {
  flex: 1;
}

/* The chat fills the popup: the header stays on top, the messages scroll, and
   the composer is pinned at the foot. */
.support-pop .guestchat {
  flex: 1 1 auto;
  min-height: 0;
  height: 100%;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: transparent;
  padding: 0.7rem;
}
.support-pop .guestchat__bar {
  flex: none;
  padding-right: 2rem; /* clear of the close button */
}
.support-pop .guestchat__empty,
.support-pop .guestchat__thread {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  margin: 0.5rem 0;
}
.support-pop .guestchat__contact {
  flex: none;
}
.support-pop .guestchat > form {
  flex: none;
}

.support-greet {
  position: fixed;
  right: 1.25rem;
  bottom: calc(1.25rem + 3.6rem);
  z-index: 51;
  display: inline-flex;
  align-items: stretch;
  max-width: min(260px, calc(100vw - 2rem));
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: 1rem 1rem 0.25rem 1rem;
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.support-greet__text {
  border: 0;
  background: transparent;
  color: var(--fg);
  font: inherit;
  font-size: 0.86rem;
  line-height: 1.35;
  text-align: left;
  padding: 0.6rem 0.4rem 0.6rem 0.8rem;
  cursor: pointer;
}
.support-greet__close {
  flex: none;
  border: 0;
  background: transparent;
  color: var(--fg-subtle);
  font-size: 1rem;
  line-height: 1;
  padding: 0 0.6rem;
  cursor: pointer;
}
.support-greet__close:hover {
  color: var(--fg);
}

@media (prefers-reduced-motion: no-preference) {
  .support-pop {
    animation: pn-pop 0.16s ease both;
  }
  .support-greet {
    animation: pn-pop 0.2s ease both;
  }
}

@media (max-width: 40rem) {
  .support-pop {
    right: 0.75rem;
    left: 0.75rem;
    width: auto;
    bottom: calc(0.75rem + 3.3rem);
    height: min(70dvh, 30rem);
  }
  .support-greet {
    right: 0.75rem;
    bottom: calc(0.75rem + 3.3rem);
  }
}

/* ---------- QR code ---------- */

/*
 * On a white plaque regardless of the page theme. A QR inverted for a dark
 * background is a QR that half the scanners on the market refuse to read, and
 * the quiet zone has to be light for any of them.
 */
.qr {
  display: inline-block;
  padding: 0.5rem;
  background: #ffffff;
  border-radius: var(--radius-sm);
  line-height: 0;
  align-self: flex-start;
}

.qr svg {
  display: block;
  width: 11rem;
  height: 11rem;
}

/*
 * The heading over each group of calculator rows.
 *
 * It exists because a column of amounts with no stated period gets read as
 * whichever period is nearest: the daily commission sat under a thirty-day total
 * and was taken for a thirty-day commission. Small, quiet, and load-bearing.
 */
.calc__grouphead {
  margin: 0.9rem 0 0.15rem;
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--fg-muted);
  opacity: 0.75;
}

/* ---------- The coins and chains, as a trust signal ---------- */

/*
 * Quiet on purpose. These are marks somebody recognises, not a feature list —
 * they work by being present, not by being loud, and a row of bright logos
 * under a sign-in form reads as an advertisement for somebody else.
 */
.trustmarks {
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
  text-align: center;
}

.trustmarks__label {
  margin: 0 0 0.5rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-subtle);
}

.trustmarks__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.4rem 1rem;
  margin-bottom: 0.9rem;
}

.trustmark {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--fg-muted);
}

.trustmark .coin {
  width: 1.125rem;
  height: 1.125rem;
}

/* ---------- What a menu entry carries besides its name ---------- */

/*
 * The name takes the room that is left, so a badge or a status never pushes
 * itself off the edge of a narrow sidebar.
 */
.sidebar__label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Unread replies. A count, not a dot: "3" is a different decision from "1". */
.sidebar__badge {
  flex: 0 0 auto;
  min-width: 1.25rem;
  padding: 0 0.35rem;
  border-radius: 999px;
  background: var(--accent);
  color: #04121f;
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1.25rem;
  text-align: center;
}

/*
 * Whether the farm is running, on the Dashboard entry.
 *
 * A dot AND a word, never the dot alone: colour on its own says nothing to
 * somebody who cannot tell green from red, and this is the one line in the
 * interface that answers "is my money working".
 */
.sidebar__state {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.6875rem;
  font-weight: 600;
}

.sidebar__dot {
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: currentColor;
}

.sidebar__state--on {
  color: var(--accent);
}

.sidebar__state--off {
  color: var(--fg-muted);
}

/* ---------- The guest's own view of the conversation ---------- */

/*
 * Two-sided, like any chat: their messages on the left, ours indented and
 * tinted. Not the full chat component from the console — this is a short thread
 * on a screen where the form below it is the thing to reach.
 */
.guestthread {
  list-style: none;
  margin: 0 0 0.25rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.guestthread__item {
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
}

.guestthread__item--us {
  margin-left: 1.25rem;
  border-color: var(--accent-dim, var(--border-strong));
  background: var(--bg-accent-soft, var(--bg-elevated));
}

.guestthread__who {
  margin: 0 0 0.2rem;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--fg-muted);
  text-transform: uppercase;
}

.guestthread__item--us .guestthread__who {
  color: var(--accent);
}

.guestthread__body {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.guestthread__meta {
  margin: 0.25rem 0 0;
  font-size: 0.6875rem;
  color: var(--fg-muted);
}

/* ---------- Messages from people with no account ---------- */

.guestmsg {
  padding: 0.875rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
}

/* Operator "new message": the ✎ in the list header, the search field, and the
   blank state of a conversation that has not been written into yet. */
.tg__new {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 50%;
  color: var(--fg);
  background: var(--bg-input);
  border: 1px solid var(--line);
  font-size: 1rem;
  line-height: 1;
  text-decoration: none;
  flex: none;
  align-self: center;
}

.tg__new:hover {
  background: var(--accent-soft, var(--bg-input));
  border-color: var(--accent, var(--line));
}

.tg__new--search {
  width: auto;
  padding-inline: 0.58rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 650;
}

.tg__searchclose,
.account-head-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  flex: 0 0 auto;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgb(255 255 255 / 0.045);
  color: var(--fg-muted);
  font-size: 1.15rem;
  line-height: 1;
  text-decoration: none;
}

.tg__searchclose {
  margin-left: auto;
}

.tg__searchclose:hover,
.account-head-close:hover {
  border-color: var(--line-strong);
  background: rgb(255 255 255 / 0.09);
  color: var(--fg);
}

.tg__search {
  padding: 0.5rem 0.65rem;
  border-bottom: 1px solid var(--line);
}

.tg__search .field__input {
  width: 100%;
}

.tg__blank {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1.25rem;
  color: var(--fg-muted);
  text-align: center;
}

.guestmsg + .guestmsg {
  margin-top: 0.75rem;
}

.guestmsg__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  font-size: 0.8125rem;
}

.guestmsg__who {
  font-weight: 600;
}

.guestmsg__when {
  color: var(--fg-muted);
}

/*
 * The message itself, written by a stranger. `pre-wrap` keeps the line breaks
 * they typed — a bug report is usually a list — and `overflow-wrap: anywhere`
 * stops one unbroken 400-character string from widening the console.
 */
.guestmsg__body {
  margin: 0 0 0.5rem;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.guestmsg__photo {
  display: inline-block;
  margin-bottom: 0.5rem;
  font-size: 0.8125rem;
}

.guestmsg__reply {
  gap: 0.5rem;
}

.guestmsg__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* ---------- Recovery codes ---------- */

.recovery {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.375rem;
}

@media (min-width: 30rem) {
  .recovery {
    grid-template-columns: 1fr 1fr;
  }
}

.recovery__code {
  padding: 0.5rem 0.75rem;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 0.875rem;
  letter-spacing: 0.06em;
  /*
   * Centred, now that a code is short enough for it to read as centred.
   *
   * Left-aligned is right for a column of values you scan down. This is a column
   * of ten things being copied one at a time, all the same length, so centring
   * makes each one a block in its own box instead of text with a ragged right
   * edge — which is what it looked like when the codes were fifteen characters
   * and nearly filled the row anyway.
   */
  text-align: center;
  /*
   * The trailing letter of a spaced-out string carries the extra space with it,
   * which pushes centred text half a character to the left. Taking it back off
   * the right is the usual fix and the only one that does not fight the font.
   */
  text-indent: 0.06em;
  /* Selectable as a block, so copying one does not drag half of the next. */
  user-select: all;
}

/* ---------- Admin: the money summary shown beside every decision ---------- */

.summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: 0.5rem;
  padding: 0.875rem;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.summary__item {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}

.summary__label {
  margin: 0;
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--fg-muted);
}

.summary__value {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.summary__value--out {
  color: var(--danger);
}

.summary__value--in {
  color: var(--accent);
}

.wallet-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.wallet-list__item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.4375rem 0.625rem;
  background: var(--bg-input);
  border-radius: 6px;
  font-size: 0.8125rem;
}

.wallet-list__address {
  font-family: var(--font-mono);
  overflow-wrap: anywhere;
}

.wallet-list__meta {
  color: var(--fg-muted);
  white-space: nowrap;
}

/* ---------- The live accrual readout ---------- */

.accrued {
  padding: 1rem 1.125rem;
  background: linear-gradient(var(--accent-soft), var(--accent-soft)), var(--bg-input);
  border: 1px solid #0093fd33;
  border-radius: var(--radius-sm);
}

.accrued__label {
  margin: 0 0 0.25rem;
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-muted);
}

.accrued__value {
  margin: 0;
  font-size: 1.75rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--accent);
  /* Tabular figures so the digits do not jump sideways as the number grows. */
  font-variant-numeric: tabular-nums;
}

.accrued__hint {
  margin: 0.25rem 0 0;
  font-size: 0.75rem;
  color: var(--fg-muted);
}

.cycle__hint {
  display: block;
  font-size: 0.6875rem;
  color: var(--fg-muted);
  opacity: 0.8;
  font-weight: 400;
}

/* ---------- Balance strip, on every signed-in page ---------- */

/*
 * The strip is a panel, not a background colour.
 *
 * The version before this one was three low-contrast pills floating on the same
 * flat grey as the header above them, so the row read as a caption rather than
 * as the account's headline figures — which is the one thing on the page a user
 * came to see. It now sits on its own darker surface, lit from above, with a
 * hairline under it that fades out at both ends instead of running edge to edge
 * like a table rule.
 */
.balancebar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  position: relative;
  padding: 0.9rem 1.75rem 1rem;
  background:
    radial-gradient(120% 140% at 12% 0%, #0e9e6820, transparent 60%),
    linear-gradient(to bottom, #131c19, var(--bg-raised) 70%);
  box-shadow: inset 0 1px 0 #ffffff12;
}

/*
 * The hairline is a pseudo-element with a gradient rather than a border, so it
 * can fade at the ends. A hard 1px line across the full width cuts the page in
 * two; this one reads as the edge of a surface.
 */
.balancebar::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: linear-gradient(to right, transparent, #ffffff1f 15%, #ffffff1f 85%, transparent);
  pointer-events: none;
}

.balancebar--demo {
  background:
    radial-gradient(120% 140% at 12% 0%, #f5a5241a, transparent 60%),
    linear-gradient(to bottom, #241f16, var(--bg-raised) 70%);
}

.balancebar--demo::after {
  background: linear-gradient(to right, transparent, #f5a52447 15%, #f5a52447 85%, transparent);
}

.balancebar__figures {
  display: flex;
  align-items: stretch;
  gap: 0.625rem;
  flex-wrap: wrap;
}

/*
 * Each figure in its own tile.
 *
 * Three bare numbers in a row have to be read before they can be told apart;
 * three framed ones are three objects, and the eye lands on the right one
 * first. The icon does the same job faster than the label does.
 *
 * A grid, not a flex column: the icon chip spans both rows down the left, with
 * the label above the amount to its right.
 */
.balancebar__item {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  align-items: center;
  gap: 0 0.6rem;
  min-width: 9.5rem;
  padding: 0.55rem 1rem 0.6rem 0.6rem;
  border-radius: 0.85rem;
  background: linear-gradient(to bottom, #ffffff0f, #ffffff05);
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.3);
}

/*
 * The same masked-gradient ring the cards use — see `.edge` near the end of the
 * file for how it works. Repeated here rather than reached for with a class,
 * because the markup for these tiles is generated in one place and the ring is
 * not optional on any of them.
 */
.balancebar__item::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: var(--edge-gradient);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

/* The icon gets a chip of its own, so it reads as a mark and not as punctuation. */
.balancebar__item .icon {
  grid-row: 1 / 3;
  box-sizing: content-box;
  width: 1.05rem;
  height: 1.05rem;
  padding: 0.45rem;
  border-radius: 0.6rem;
  background: #ffffff0d;
  color: var(--fg-muted);
}

/* The one that is earning: lit, and the only colour in the row. */
.balancebar__item--accent {
  background: linear-gradient(to bottom, #0093fd2e, #0093fd0f);
  box-shadow:
    0 1px 2px rgb(0 0 0 / 0.3),
    0 6px 18px -10px var(--accent);
}

.balancebar__item--accent::before {
  background: var(--edge-gradient-accent);
}

.balancebar__item--accent .icon {
  background: #0093fd2b;
  color: var(--accent-bright);
}

.balancebar__label {
  font-size: 0.625rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--fg-muted);
}

.balancebar__value {
  font-size: 1.1875rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: 1.15;
}

.balancebar__value--accent {
  color: var(--accent-bright);
}

/*
 * ON A PHONE THE TILE BECOMES A COLUMN, AND THE AMOUNTS STILL LINE UP.
 *
 * The three tiles share the width, so each is about a third of a narrow screen
 * — and "In the farm" does not fit on one line there. With the icon beside the
 * text the label wrapped to two lines and pushed that one amount a line lower
 * than the two next to it: three figures at three different heights, which is
 * what the owner saw as the font having slipped.
 *
 * Stacking the icon above the label gives the words the full width of the tile,
 * and `margin-top: auto` on the amount pins all three to the bottom of tiles
 * the grid has already made equal height. A label may wrap; the numbers cannot
 * move.
 */
@media (max-width: 40rem) {
  .balancebar {
    padding: 0.75rem 1rem 0.85rem;
  }

  .balancebar__figures {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem;
    width: 100%;
  }

  .balancebar__item {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.3rem;
    min-width: 0;
    padding: 0.55rem 0.6rem 0.6rem;
  }

  .balancebar__item .icon {
    width: 0.95rem;
    height: 0.95rem;
    padding: 0.35rem;
  }

  .balancebar__label {
    line-height: 1.25;
  }

  .balancebar__value {
    margin-top: auto;
    font-size: 1rem;
  }
}

/* ---------- Real / demo switch ---------- */

/*
 * Two labelled halves, the current one lit. A single button saying "switch to
 * demo" leaves which mode you are in right now to be inferred — and that is the
 * one thing about a demo account that must never need inferring.
 */
.modeswitch {
  display: flex;
  align-items: center;
  gap: 0.625rem;
}

.modeswitch__caption {
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--fg-muted);
}

.modeswitch__track {
  display: inline-flex;
  padding: 2px;
  border-radius: 999px;
  background: var(--bg-input);
  border: 1px solid var(--border);
}

.modeswitch__option {
  padding: 0.3125rem 0.875rem;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--fg-muted);
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
}

.modeswitch__option:hover {
  color: var(--fg);
}

.modeswitch__option--on {
  background: var(--accent);
  color: #04120a;
}

.modeswitch__option--on.modeswitch__option--demo {
  background: var(--warning);
  color: #1a1204;
}

/* One clear farm language in both modes: green for real, orange for demo. */
.card.farm-card--entry,
.card.farm-card--running-preview {
  --farm-signal: var(--accent-bright);
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--farm-signal) 61%, var(--border-strong));
  background:
    radial-gradient(50rem 19rem at 42% -15%, color-mix(in srgb, var(--farm-signal) 22%, transparent), transparent 72%),
    linear-gradient(150deg, color-mix(in srgb, var(--farm-signal) 6%, var(--bg-card)), var(--bg-card) 70%);
  box-shadow:
    0 18px 48px -27px color-mix(in srgb, var(--farm-signal) 42%, transparent),
    var(--shadow-card);
}

.card.farm-card--running-preview {
  background:
    radial-gradient(48rem 18rem at 50% -22%, color-mix(in srgb, var(--farm-signal) 17%, transparent), transparent 70%),
    var(--bg-card);
}

.card.farm-card--demo-preview {
  --farm-signal: var(--warning);
}

.farm-card--entry .card__title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.45rem 0.75rem;
  padding: 0.7rem 0.9rem;
  background: linear-gradient(90deg, color-mix(in srgb, var(--farm-signal) 12%, transparent), transparent 72%);
  border-bottom-color: color-mix(in srgb, var(--farm-signal) 31%, var(--border));
  color: var(--fg);
  font-size: 1.08rem;
}

.farm-entry__title {
  display: inline-flex;
  align-items: center;
  gap: 0.72rem;
}

.farm-entry__title > .icon {
  width: 2rem;
  height: 2rem;
  padding: 0.43rem;
  border-radius: 0.58rem;
  background: color-mix(in srgb, var(--farm-signal) 19%, transparent);
  color: var(--farm-signal);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--farm-signal) 37%, transparent);
}

.farm-entry__mode {
  display: inline-flex;
  align-items: center;
  min-height: 1.55rem;
  padding: 0.15rem 0.52rem;
  border: 1px solid color-mix(in srgb, var(--farm-signal) 45%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--farm-signal) 13%, transparent);
  color: var(--farm-signal);
  font-size: 0.67rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.farm-card--entry .card__content {
  gap: 0.65rem;
}

.farm-entry__intro {
  display: grid;
  gap: 0.24rem;
}

.farm-entry__lead {
  margin: 0;
  color: var(--fg);
  font-size: 1rem;
  font-weight: 650;
}

.farm-entry__copy {
  margin: 0;
  color: var(--fg-muted);
  font-size: 0.86rem;
  line-height: 1.5;
}

.farm-card--entry .farm-entry__intro {
  gap: 0.22rem;
  padding: 0.62rem 0.78rem;
  border-left: 3px solid var(--farm-signal);
  border-radius: 0 0.65rem 0.65rem 0;
  background: color-mix(in srgb, var(--farm-signal) 8%, transparent);
}

.farm-card--entry .farm-entry__lead {
  color: var(--farm-signal);
  font-size: 1.04rem;
}

.farm-entry__window {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0;
  padding: 0.7rem 0.85rem;
  border: 1px solid color-mix(in srgb, var(--farm-signal) 25%, var(--border));
  border-radius: 0.65rem;
  background: color-mix(in srgb, var(--bg-input) 77%, transparent);
  color: var(--fg-muted);
  font-size: 0.78rem;
  line-height: 1.4;
}

.farm-entry__window > .icon {
  width: 1rem;
  height: 1rem;
  flex: none;
  color: var(--farm-signal);
}

.farm-card--ready .farm-entry__form {
  gap: 0.58rem;
  padding: 0.7rem;
  border: 1px solid color-mix(in srgb, var(--farm-signal) 30%, var(--border-strong));
  border-radius: 0.85rem;
  background: color-mix(in srgb, var(--bg-input) 82%, transparent);
  box-shadow: inset 0 1px 0 #ffffff0c;
}

.farm-entry__form .field__label {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.2rem 0.75rem;
  color: var(--fg);
  font-weight: 650;
}

.farm-entry__form .field__optional {
  opacity: 1;
  font-size: 0.76rem;
  font-weight: 400;
}

.farm-entry__form .field__optional::before {
  content: '';
}

.farm-entry__form .amount-input__field {
  min-height: 3rem;
  border-color: color-mix(in srgb, var(--farm-signal) 27%, var(--border-strong));
  background: color-mix(in srgb, var(--bg-card) 75%, black);
  font-size: 1rem;
}

.farm-entry__steps {
  display: flex;
  align-items: center;
  gap: 0.52rem;
  min-width: 0;
  padding: 0.58rem 0.68rem;
  border: 1px solid color-mix(in srgb, var(--farm-signal) 27%, var(--border));
  border-radius: 0.75rem;
  background: color-mix(in srgb, var(--bg-input) 70%, transparent);
}

.farm-entry__step {
  display: inline-flex;
  align-items: center;
  gap: 0.42rem;
  min-width: 0;
  white-space: nowrap;
  color: var(--fg-muted);
  font-size: 0.77rem;
  font-weight: 600;
}

.farm-entry__step > span,
.farm-entry__step > .icon {
  display: inline-grid;
  width: 1.45rem;
  height: 1.45rem;
  flex: none;
  place-items: center;
  border-radius: 999px;
  background: #ffffff0d;
  color: var(--fg-muted);
  font-size: 0.65rem;
  font-variant-numeric: tabular-nums;
}

.farm-entry__step > .icon {
  padding: 0.3rem;
}

.farm-entry__step--current {
  color: var(--fg);
}

.farm-entry__step--current > span {
  background: var(--farm-signal);
  color: #101414;
}

.farm-entry__step--done > .icon {
  background: color-mix(in srgb, var(--accent) 17%, transparent);
  color: var(--accent-bright);
}

.farm-entry__step-line {
  height: 1px;
  min-width: 0.5rem;
  flex: 1;
  background: color-mix(in srgb, var(--farm-signal) 35%, var(--border));
}

.farm-entry__alternate {
  display: inline-flex;
  align-items: center;
  align-self: center;
  gap: 0.2rem;
  padding: 0.25rem 0.4rem;
  color: var(--fg-muted);
  font-size: 0.76rem;
  font-weight: 600;
  text-decoration: none;
  transition: color 150ms ease;
}

.farm-entry__alternate:hover,
.farm-entry__alternate:focus-visible {
  color: var(--farm-signal);
}

.farm-entry__alternate > .icon {
  width: 0.75rem;
  height: 0.75rem;
}

.farm-card--entry .button--farm-fund,
.farm-card--entry .button--farm-start {
  width: 100%;
  min-height: 3.35rem;
  font-size: 0.95rem;
}

@media (max-width: 28rem) {
  .farm-entry__steps {
    gap: 0.42rem;
    padding: 0.62rem;
  }

  .farm-entry__step {
    gap: 0.3rem;
    white-space: normal;
    font-size: 0.69rem;
    line-height: 1.25;
  }
}

/* Active farm: the same mode colour frames live capital, reward and payout. */
.farm-card--running-preview .card__title {
  padding: 0.7rem 0.9rem;
  border-bottom-color: color-mix(in srgb, var(--farm-signal) 28%, var(--border));
  background: linear-gradient(90deg, color-mix(in srgb, var(--farm-signal) 12%, transparent), transparent 75%);
}

.farm-card--running-preview .card__content {
  gap: 0.62rem;
}

.farm-running__heading {
  display: inline-flex;
  align-items: center;
  gap: 0.72rem;
}

.farm-running__heading > .icon {
  width: 2rem;
  height: 2rem;
  padding: 0.43rem;
  border-radius: 0.58rem;
  background: color-mix(in srgb, var(--farm-signal) 19%, transparent);
  color: var(--farm-signal);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--farm-signal) 37%, transparent);
}

.farm-card--running-preview .badge--live {
  border-color: color-mix(in srgb, var(--farm-signal) 41%, transparent);
  background: color-mix(in srgb, var(--farm-signal) 13%, transparent);
  color: var(--farm-signal);
}

.farm-card--running-preview .live-dot {
  background: var(--farm-signal);
}

.farm-card--running-preview .farmboard__cell {
  min-height: 6.8rem;
  border-radius: 0.85rem;
}

.farm-card--running-preview .farmboard__cell:not(.farmboard__cell--profit) {
  border-color: color-mix(in srgb, var(--farm-signal) 24%, var(--border));
  background: linear-gradient(145deg, color-mix(in srgb, var(--farm-signal) 8%, var(--bg-input)), var(--bg-input) 75%);
  box-shadow: inset 0 1px 0 #ffffff0b;
}

.farm-card--running-preview .farmboard__cell--profit {
  border-color: color-mix(in srgb, var(--farm-signal) 39%, var(--border));
  background:
    radial-gradient(circle at 84% 17%, #2775ca1d, transparent 45%),
    linear-gradient(145deg, color-mix(in srgb, var(--farm-signal) 15%, var(--bg-input)), color-mix(in srgb, var(--farm-signal) 7%, var(--bg-input)));
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, var(--farm-signal) 17%, transparent),
    0 12px 30px -19px color-mix(in srgb, var(--farm-signal) 45%, transparent);
}

.farm-card--running-preview .farmboard__value--profit {
  color: var(--farm-signal);
}

.farm-card--running-preview .window {
  gap: 0.5rem;
  padding: 0.72rem;
  border: 1px solid color-mix(in srgb, var(--farm-signal) 31%, var(--border));
  border-radius: 0.9rem;
  background:
    radial-gradient(30rem 11rem at 0% 0%, color-mix(in srgb, var(--farm-signal) 10%, transparent), transparent 72%),
    color-mix(in srgb, var(--bg-input) 82%, var(--bg-card));
  box-shadow: inset 0 1px 0 #ffffff10;
}

.farm-card--running-preview .window__head {
  align-items: center;
}

.farm-card--running-preview .window__title {
  color: var(--fg);
  font-size: 0.7rem;
}

.farm-card--running-preview .window__title .icon {
  color: var(--farm-signal);
  opacity: 1;
}

.farm-card--running-preview .window__countdown {
  padding: 0.38rem 0.58rem;
  border: 1px solid color-mix(in srgb, var(--farm-signal) 32%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--farm-signal) 11%, transparent);
  color: var(--farm-signal);
  font-size: 0.82rem;
}

.farm-card--running-preview .window__track {
  height: 1.05rem;
  border-radius: 999px;
  background: var(--bg-input);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--farm-signal) 28%, transparent),
    0 5px 17px -10px color-mix(in srgb, var(--farm-signal) 48%, transparent);
}

.farm-card--running-preview .window__band--missed {
  fill: #44484a;
}

.farm-card--running-preview .window__band--ahead {
  fill: color-mix(in srgb, var(--farm-signal) 28%, #24292a);
}

.farm-card--running-preview .window__band--earned {
  fill: var(--farm-signal);
}

.farm-card--running-preview .window__scale {
  gap: 0.3rem;
  font-size: 0.65rem;
  color: var(--fg-muted);
}

.farm-card--running-preview .window__joined {
  color: var(--farm-signal);
}

.farm-card--running-preview .window__legend {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.25rem 0.4rem;
  margin: 0.1rem 0 0;
  font-size: 0.67rem;
  color: var(--fg-muted);
}

.farm-card--running-preview .window__key {
  min-width: 0;
  gap: 0.3rem;
  white-space: nowrap;
}

.farm-card--running-preview .window__swatch {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 999px;
}

.farm-card--running-preview .window__swatch--missed {
  background: #44484a;
}

.farm-card--running-preview .window__swatch--ahead {
  background: color-mix(in srgb, var(--farm-signal) 28%, #24292a);
  box-shadow: none;
}

.farm-card--running-preview .window__swatch--earned {
  background: var(--farm-signal);
}

.farm-card--running-preview .window__explain {
  margin-top: 0.05rem;
  border-top-color: color-mix(in srgb, var(--farm-signal) 20%, var(--border));
  padding-top: 0.72rem;
}

.farm-card--running-preview .window__explainhead {
  color: var(--fg-muted);
}

.farm-card--running-preview .window__explainhead:hover {
  color: var(--farm-signal);
}

.farmmanage__head {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.1rem 0.1rem 0;
  color: var(--fg);
  font-family: var(--font-display, inherit);
  font-size: 0.93rem;
  font-weight: 650;
}

.farmmanage__head > .icon {
  width: 1.1rem;
  height: 1.1rem;
  color: var(--farm-signal);
}

.farm-card--running-preview .farmops {
  gap: 0.55rem;
}

.farm-card--running-preview .farmop {
  --farm-op-signal: var(--farm-signal);
  gap: 0.46rem;
  padding: 0.72rem;
  border: 1px solid color-mix(in srgb, var(--farm-op-signal) 24%, var(--border));
  border-radius: 0.9rem;
  background: linear-gradient(155deg, color-mix(in srgb, var(--farm-op-signal) 7%, var(--bg-input)), var(--bg-input) 72%);
  box-shadow: inset 0 1px 0 #ffffff0e;
}

.farm-card--running-preview .farmop--pull {
  --farm-op-signal: #85aebf;
}

.farm-card--running-preview .farmop .field__label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.3rem 0.65rem;
  color: var(--fg);
  font-size: 0.83rem;
  font-weight: 650;
}

.farmop__label-main {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.farmop__label-main > .icon {
  box-sizing: border-box;
  width: 1.7rem;
  height: 1.7rem;
  padding: 0.35rem;
  border-radius: 0.48rem;
  background: color-mix(in srgb, var(--farm-op-signal, var(--farm-signal)) 15%, transparent);
  color: var(--farm-op-signal, var(--farm-signal));
}

.farm-card--running-preview .farmop .field__optional {
  opacity: 1;
  font-size: 0.72rem;
}

.farm-card--running-preview .farmop .field__optional::before {
  content: '';
}

.farm-card--running-preview .farmop .amount-input__field {
  min-height: 2.9rem;
  border-color: color-mix(in srgb, var(--farm-op-signal) 24%, var(--border-strong));
  background: color-mix(in srgb, var(--bg-card) 76%, black);
  font-size: 0.95rem;
}

.farm-card--running-preview .farmop .field__hint {
  line-height: 1.45;
}

.farm-card--running-preview .farmop .button {
  min-height: 3rem;
}

.farm-card--running-preview .farmend {
  gap: 0.38rem;
  margin-top: 0;
  padding: 0.68rem 0.78rem;
  border: 1px solid color-mix(in srgb, #bb9079 25%, var(--border));
  border-radius: 0.85rem;
  background: linear-gradient(150deg, color-mix(in srgb, #bb9079 5%, var(--bg-input)), var(--bg-input));
}

.farm-card--running-preview .farmend .button--stop {
  min-height: 2.85rem;
}

/* A single quiet metal-and-glass language for every farm action. The label
   never changes colour between primary and secondary; account colour lives in
   the surface, edge and focus ring instead. */
.card.farm-card--entry,
.card.farm-card--running-preview,
.card.auto-card--preview {
  --farm-action-top: #205a45;
  --farm-action-bottom: #123729;
  --farm-action-edge: #53b38b;
  --farm-action-glow: #1b815b;
}

.auto-card--preview .card__content {
  gap: 0.6rem;
  padding: 0.72rem 0.9rem 0.8rem;
}

.auto-card--preview .auto-control__form {
  gap: 0.58rem;
}

.card.farm-card--demo-preview {
  --farm-action-top: #77522d;
  --farm-action-bottom: #3e2b1b;
  --farm-action-edge: #c89960;
  --farm-action-glow: #9c682f;
}

.button--farm-action--withdraw {
  --farm-action-top: #284450;
  --farm-action-bottom: #182930;
  --farm-action-edge: #85aebf;
  --farm-action-glow: #477d91;
}

.button--farm-action--exit {
  --farm-action-top: #493830;
  --farm-action-bottom: #29201d;
  --farm-action-edge: #bb9079;
  --farm-action-glow: #805b49;
}

.button--farm-action--auto {
  --farm-action-top: #24504e;
  --farm-action-bottom: #17302f;
  --farm-action-edge: #81b9ae;
  --farm-action-glow: #498c80;
}

:is(.farm-card--entry, .farm-card--running-preview, .auto-card--preview) .button--farm-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.85rem;
  padding: 0.52rem 1rem;
  border-radius: 0.7rem;
  color: #f2f7f3;
  font-family: var(--font-sans);
  font-size: 0.85rem;
  font-weight: 660;
  line-height: 1.2;
  letter-spacing: 0.002em;
  text-align: center;
  text-shadow: 0 1px 1px rgb(0 0 0 / 0.23);
  white-space: normal;
  backdrop-filter: blur(10px) saturate(1.1);
  -webkit-backdrop-filter: blur(10px) saturate(1.1);
  transition: background 180ms ease, border-color 180ms ease, box-shadow 180ms ease, transform 180ms ease;
}

.button--farm-action .farm-action__label {
  min-width: 0;
  text-align: center;
}

.farm-card--entry .button--farm-action {
  min-height: 2.95rem;
  font-size: 0.9rem;
}

.farm-card--running-preview .farmop .button--farm-action,
.farm-card--running-preview .farmend .button--farm-action {
  min-height: 2.85rem;
}

:is(.farm-card--entry, .farm-card--running-preview, .auto-card--preview) .button--farm-action--primary {
  border: 1px solid var(--farm-action-edge);
  background:
    radial-gradient(100% 160% at 12% -65%, rgb(255 255 255 / 0.26), transparent 68%),
    linear-gradient(180deg, rgb(255 255 255 / 0.11), transparent 46%),
    linear-gradient(145deg, var(--farm-action-top), var(--farm-action-bottom));
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.3),
    inset 0 -1px 0 rgb(0 0 0 / 0.36),
    0 1px 0 rgb(0 0 0 / 0.45),
    0 12px 24px -16px var(--farm-action-glow);
}

:is(.farm-card--entry, .farm-card--running-preview, .auto-card--preview) .button--farm-action--primary:hover {
  border-color: color-mix(in srgb, var(--farm-action-edge) 74%, white);
  background:
    radial-gradient(100% 160% at 12% -65%, rgb(255 255 255 / 0.3), transparent 68%),
    linear-gradient(180deg, rgb(255 255 255 / 0.13), transparent 46%),
    linear-gradient(145deg,
      color-mix(in srgb, var(--farm-action-top) 89%, white),
      color-mix(in srgb, var(--farm-action-bottom) 88%, var(--farm-signal)));
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.37),
    inset 0 -1px 0 rgb(0 0 0 / 0.28),
    0 3px 8px rgb(0 0 0 / 0.18),
    0 16px 28px -16px var(--farm-action-glow);
  transform: translateY(-1px);
}

:is(.farm-card--entry, .farm-card--running-preview, .auto-card--preview) .button--farm-action--secondary {
  border: 1px solid color-mix(in srgb, var(--farm-action-edge) 38%, rgb(255 255 255 / 0.18));
  background:
    linear-gradient(180deg, rgb(255 255 255 / 0.12), rgb(255 255 255 / 0.01) 60%),
    linear-gradient(135deg,
      color-mix(in srgb, var(--farm-action-top) 57%, #181d1b),
      color-mix(in srgb, var(--farm-action-bottom) 51%, #101513));
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.17),
    inset 0 -1px 0 rgb(0 0 0 / 0.23),
    0 6px 15px -12px rgb(0 0 0 / 0.65);
}

:is(.farm-card--entry, .farm-card--running-preview, .auto-card--preview) .button--farm-action--secondary:hover {
  border-color: color-mix(in srgb, var(--farm-action-edge) 46%, rgb(255 255 255 / 0.22));
  background:
    linear-gradient(180deg, rgb(255 255 255 / 0.17), rgb(255 255 255 / 0.025) 60%),
    linear-gradient(135deg,
      color-mix(in srgb, var(--farm-action-top) 68%, #1b211e),
      color-mix(in srgb, var(--farm-action-bottom) 60%, #151b18));
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.22),
    0 8px 17px -12px color-mix(in srgb, var(--farm-action-glow) 34%, transparent);
  transform: translateY(-1px);
}

:is(.farm-card--entry, .farm-card--running-preview, .auto-card--preview) .button--farm-action:active {
  transform: translateY(1px) scale(0.995);
  box-shadow: inset 0 2px 5px rgb(0 0 0 / 0.35), 0 1px 0 rgb(255 255 255 / 0.05);
}

:is(.farm-card--entry, .farm-card--running-preview, .auto-card--preview) .button--farm-action:focus-visible,
.farm-card--entry .farm-entry__alternate:focus-visible {
  outline: 2px solid var(--farm-action-edge);
  outline-offset: 3px;
}

:is(.farm-card--entry, .farm-card--running-preview, .auto-card--preview) .button--farm-action:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
}

.farm-card--entry .farm-entry__alternate {
  min-height: 2.25rem;
  padding: 0.45rem 0.85rem;
  border: 1px solid rgb(255 255 255 / 0.16);
  border-radius: 0.65rem;
  background: linear-gradient(180deg, rgb(255 255 255 / 0.08), rgb(255 255 255 / 0.015));
  color: #dce7df;
  font-family: var(--font-sans);
  font-size: 0.77rem;
  font-weight: 620;
  letter-spacing: 0.006em;
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.1);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.farm-card--entry .farm-entry__alternate > .icon {
  color: var(--farm-signal);
}

.farm-card--entry .farm-entry__alternate:hover {
  border-color: color-mix(in srgb, var(--farm-action-edge) 48%, transparent);
  background: color-mix(in srgb, var(--farm-signal) 9%, #151b18);
  color: #f2f7f3;
}

.card.auto-card--preview {
  --farm-signal: var(--accent-bright);
  border-color: color-mix(in srgb, var(--farm-signal) 27%, var(--border));
  background:
    radial-gradient(35rem 15rem at 45% -22%, color-mix(in srgb, var(--farm-signal) 11%, transparent), transparent 75%),
    var(--bg-card);
}

.auto-card--preview .card__title {
  border-bottom-color: color-mix(in srgb, #81b9ae 28%, var(--border));
}

.auto-card--preview .button--auto-toggle {
  width: 100%;
  min-height: 2.85rem;
}

.auto-card--preview .auto-control__form .amount-input__field {
  min-height: 2.75rem;
  border-color: color-mix(in srgb, var(--farm-signal) 25%, var(--border));
}

.auto-preview {
  display: flex;
  flex-direction: column;
  gap: 0.58rem;
}

.auto-preview__notice {
  margin: 0;
  padding: 0.48rem 0.62rem;
  border: 1px solid color-mix(in srgb, #81b9ae 33%, var(--border));
  border-radius: 0.55rem;
  background: color-mix(in srgb, #81b9ae 8%, transparent);
  color: #c7ddd6;
  font-size: 0.73rem;
  line-height: 1.35;
}

.auto-preview__balance {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 0.6rem;
  padding: 0.52rem 0.7rem;
  border: 1px solid color-mix(in srgb, #81b9ae 28%, var(--border));
  border-radius: 0.6rem;
  background: color-mix(in srgb, #81b9ae 6%, var(--bg-input));
  color: var(--fg-muted);
  font-size: 0.75rem;
}

.auto-preview__balance > strong {
  color: var(--fg);
  font-family: var(--font-mono);
  font-size: 0.92rem;
  font-weight: 600;
}

.auto-preview__state {
  margin-left: auto;
  color: var(--fg-muted);
  font-size: 0.72rem;
  font-weight: 700;
}

.auto-preview__state--on,
.auto-preview__turn-off,
.auto-preview__next {
  display: none;
}

.auto-preview__switch:checked ~ .auto-preview__balance .auto-preview__state--off,
.auto-preview__switch:checked ~ .auto-preview__amount,
.auto-preview__switch:checked ~ .auto-preview__toggle .auto-preview__turn-on {
  display: none;
}

.auto-preview__switch:checked ~ .auto-preview__balance .auto-preview__state--on,
.auto-preview__switch:checked ~ .auto-preview__toggle .auto-preview__turn-off,
.auto-preview__switch:checked ~ .auto-preview__next {
  display: block;
}

.auto-preview__state--on,
.auto-preview__next {
  color: #a6d9ca;
}

.auto-preview__next {
  margin: 0;
  padding: 0.5rem 0.65rem;
  border-left: 2px solid #81b9ae;
  background: color-mix(in srgb, #81b9ae 7%, transparent);
  font-size: 0.75rem;
}

.auto-preview__amount .amount-input__field {
  min-height: 2.75rem;
  border-color: color-mix(in srgb, #81b9ae 27%, var(--border));
}

.auto-preview__toggle {
  width: 100%;
}

.auto-preview__switch:checked ~ .auto-preview__toggle {
  border-color: color-mix(in srgb, #81b9ae 48%, var(--border));
  background: linear-gradient(180deg, #263f3b, #172b29);
}

.auto-preview__switch:focus-visible ~ .auto-preview__toggle {
  outline: 2px solid #81b9ae;
  outline-offset: 3px;
}

/* The farm and its auto-reinvest control are one real-account workspace. */
.farm-suite--preview {
  --farm-signal: var(--accent-bright);
  min-width: 0;
  overflow: visible;
  border: 1px solid color-mix(in srgb, var(--farm-signal) 48%, var(--border));
  border-radius: 1rem;
  background: var(--bg-card);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.16),
    0 17px 42px -29px color-mix(in srgb, var(--farm-signal) 36%, transparent),
    var(--shadow-card);
}

.farm-suite--preview > .card {
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

/* The shell must stay overflow-visible for help and confirmation popovers.
   Round the farm surface and its tinted header explicitly instead. */
.farm-suite--preview > .card:first-child,
.farm-suite--preview > .card:first-child > .card__title {
  border-radius: calc(1rem - 1px) calc(1rem - 1px) 0 0;
}

.farm-suite--preview > .card::before {
  content: none;
}

.farm-suite--preview > .auto-card--preview {
  border-top: 1px solid color-mix(in srgb, var(--farm-signal) 28%, var(--border));
}

.farm-suite--demo { --farm-signal: #efb35c; }

.auto-switch-card {
  --auto-signal: #b6ed83;
  margin: .55rem 0 0;
  padding: .72rem .85rem;
  border: 1px solid color-mix(in srgb, var(--auto-signal) 29%, var(--border));
  border-radius: .9rem;
  background: linear-gradient(145deg, color-mix(in srgb, var(--auto-signal) 9%, var(--bg-input)), var(--bg-input) 76%);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .08);
}
.farm-suite--preview > .auto-switch-card { margin: .5rem .62rem .65rem; }
.auto-switch-card--demo { --auto-signal: #efb35c; }
.auto-switch-card--disabled { --auto-signal: #9da29a; }
.auto-switch-card__row { display: flex; align-items: center; gap: .7rem; min-height: 2.1rem; }
.auto-switch-card__title { margin-right: auto; color: #f1f5e9; font-family: var(--font-display, inherit); font-weight: 650; font-size: .9rem; }
.auto-switch-card form { margin: 0; }
.auto-switch {
  position: relative; display: block; flex: none; width: 4.8rem; height: 2rem;
  padding: 0; border: 1px solid rgb(255 255 255 / .2); border-radius: 999px;
  background: linear-gradient(180deg, rgb(255 255 255 / .12), rgb(255 255 255 / .05));
  color: #e1e5dd; font: inherit; cursor: pointer;
  box-shadow: inset 0 1px 3px rgb(0 0 0 / .25), 0 1px 0 rgb(255 255 255 / .06);
  transition: background .2s ease, border-color .2s ease, box-shadow .2s ease;
}
.auto-switch:hover:not(:disabled) { border-color: color-mix(in srgb, var(--auto-signal) 65%, white); }
.auto-switch--on {
  background: linear-gradient(145deg, color-mix(in srgb, var(--auto-signal) 30%, #13271e), color-mix(in srgb, var(--auto-signal) 13%, #15221b));
  border-color: color-mix(in srgb, var(--auto-signal) 65%, transparent);
  color: #f8fff0;
  box-shadow: inset 0 1px 3px rgb(0 0 0 / .18), 0 0 14px color-mix(in srgb, var(--auto-signal) 16%, transparent);
}
.auto-switch:disabled { filter: grayscale(1); opacity: .58; cursor: not-allowed; }
.auto-switch:focus-visible { outline: 2px solid var(--auto-signal); outline-offset: 3px; }
.auto-switch__thumb {
  position: absolute; top: .28rem; left: .28rem; width: 1.3rem; height: 1.3rem;
  border-radius: 50%; background: linear-gradient(145deg, #b2b9ae, #7e867c);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .3), 0 1px 4px rgb(0 0 0 / .45);
  transition: transform .22s ease, background .22s ease;
}
.auto-switch--on .auto-switch__thumb {
  transform: translateX(2.83rem);
  background: linear-gradient(145deg, #f2ffe7, var(--auto-signal));
}
.auto-switch__state {
  position: absolute; top: 0; bottom: 0; left: 1.65rem; right: .25rem;
  display: grid; place-items: center; text-align: center;
  font-size: .72rem; font-weight: 650; line-height: 1;
}
.auto-switch--on .auto-switch__state { left: .25rem; right: 1.65rem; }
.auto-switch-card__hint {
  margin: .32rem 0 0; color: #b8beb5; font-size: .75rem; line-height: 1.35;
}
.auto-switch-card__error { margin: .35rem 0 0; color: #ffb9a9; font-size: .75rem; }
.auto-switch-help { position: relative; flex: none; }
.auto-switch-help summary { display: grid; place-items: center; width: 1.55rem; height: 1.55rem; border: 1px solid rgb(255 255 255 / .23); border-radius: 50%; color: #d0d4cc; font-size: .73rem; cursor: pointer; list-style: none; }
.auto-switch-help summary::-webkit-details-marker { display: none; }
.auto-switch-help__body { position: absolute; z-index: 5; right: 0; top: calc(100% + .5rem); width: min(17rem, 75vw); padding: .7rem .8rem; border: 1px solid rgb(255 255 255 / .22); border-radius: .7rem; background: #242822; box-shadow: 0 12px 30px rgb(0 0 0 / .4); color: #e5e8df; font-size: .76rem; line-height: 1.45; }
@media (prefers-reduced-motion: reduce) {
  .auto-switch, .auto-switch__thumb { transition: none; }
}

@media (prefers-reduced-motion: reduce) {
  :is(.farm-card--entry, .farm-card--running-preview, .auto-card--preview) .button--farm-action {
    transition: none;
  }

  :is(.farm-card--entry, .farm-card--running-preview, .auto-card--preview) .button--farm-action:hover,
  :is(.farm-card--entry, .farm-card--running-preview, .auto-card--preview) .button--farm-action:active {
    transform: none;
  }
}

/* ---------- The farm board ---------- */

.farmboard {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.875rem;
}

@media (min-width: 34rem) {
  .farmboard {
    grid-template-columns: 1fr 1fr;
  }
}

.farmboard__cell {
  padding: 1.125rem 1.25rem;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

/*
 * PROFIT IS GREEN, and it is the only green figure on a signed-in page.
 *
 * It was the brand blue, which is the colour of every other accent here — so
 * the one number on the dashboard that says "you are making money" looked like
 * one more panel highlight. Green is already this palette's meaning for money
 * arriving (`--ok`, used by `.amount--in` in the ledger), and this is money
 * arriving. Reusing it costs nothing and says the thing without a word.
 */
.farmboard__cell--profit {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: linear-gradient(var(--ok-soft), var(--ok-soft)), var(--bg-input);
  border-color: #3eb46840;
}

/*
 * A live profit tile gets a quiet token stream: just enough movement
 * to make the money feel active, kept behind the figures so it never competes
 * with the amount.
 */
.farmboard__cell--profit-motion {
  background:
    radial-gradient(circle at 88% 22%, #2775ca24 0, transparent 42%),
    radial-gradient(circle at 12% 90%, #3eb4681f 0, transparent 46%),
    linear-gradient(var(--ok-soft), var(--ok-soft)),
    var(--bg-input);
  box-shadow:
    inset 0 1px 0 #ffffff0b,
    0 0.875rem 2.25rem #07130c14;
}

.farmboard__cell--profit > .farmboard__label,
.farmboard__cell--profit > .farmboard__value {
  position: relative;
  z-index: 2;
}

.profit-stream {
  position: absolute;
  z-index: 1;
  inset: 0;
  pointer-events: none;
}

.profit-stream__token {
  --token-size: 1.7rem;
  --token-opacity: 0.34;
  --token-turn: 8deg;
  --token-drift: 0.42rem;
  position: absolute;
  left: 12%;
  top: -2.5rem;
  display: grid;
  width: var(--token-size);
  height: var(--token-size);
  place-items: center;
  opacity: 0;
  transform: translateX(calc(var(--token-drift) * -1)) rotate(calc(var(--token-turn) * -1)) scale(0.82);
  animation: profit-token-fall 10.5s linear infinite;
  will-change: top, opacity, transform;
}

.profit-stream__token img {
  display: block;
  width: 78%;
  height: 78%;
  object-fit: contain;
  filter: drop-shadow(0 0.25rem 0.45rem #00000030);
}

.profit-stream__token--polymarket img {
  border-radius: 0.28rem;
}

.profit-stream__token:nth-child(2) {
  --token-size: 1.25rem;
  --token-opacity: 0.27;
  --token-turn: -6deg;
  --token-drift: 0.3rem;
  left: 29%;
  animation-duration: 13s;
  animation-delay: -8s;
}

.profit-stream__token:nth-child(3) {
  --token-size: 1.45rem;
  --token-opacity: 0.3;
  --token-turn: 5deg;
  --token-drift: 0.55rem;
  left: 46%;
  animation-duration: 14.5s;
  animation-delay: -12s;
}

.profit-stream__token:nth-child(4) {
  --token-size: 1.12rem;
  --token-opacity: 0.24;
  --token-turn: -9deg;
  --token-drift: 0.35rem;
  left: 62%;
  animation-duration: 11.5s;
  animation-delay: -4s;
}

.profit-stream__token:nth-child(5) {
  --token-size: 1.32rem;
  --token-opacity: 0.28;
  --token-turn: 7deg;
  --token-drift: 0.48rem;
  left: 78%;
  animation-duration: 13.5s;
  animation-delay: -10s;
}

.profit-stream__token:nth-child(6) {
  --token-size: 1rem;
  --token-opacity: 0.22;
  --token-turn: -7deg;
  --token-drift: 0.28rem;
  left: 91%;
  animation-duration: 15s;
  animation-delay: -6s;
}

@keyframes profit-token-fall {
  0% {
    top: -2.5rem;
    opacity: 0;
    transform: translateX(calc(var(--token-drift) * -1)) rotate(calc(var(--token-turn) * -1)) scale(0.82);
  }

  12%,
  82% {
    opacity: var(--token-opacity);
  }

  48% {
    transform: translateX(var(--token-drift)) rotate(0deg) scale(1);
  }

  100% {
    top: calc(100% + 2.5rem);
    opacity: 0;
    transform: translateX(calc(var(--token-drift) * -0.55)) rotate(var(--token-turn)) scale(0.88);
  }
}

/* Keep live panels quiet on touch devices. Their figures still tick every
   second, without continuous decorative repaints competing with taps/scroll. */
@media (pointer: coarse) {
  .farm-card, .farm-card *, .farm-card *::before, .farm-card *::after,
  .window, .window * {
    animation: none !important;
    transition: none !important;
  }
  .profit-stream__token { will-change: auto; }
}

/* Honour the accessibility preference; live profit remains independent. */
@media (prefers-reduced-motion: reduce) {
  .profit-stream__token {
    animation: none !important;
    will-change: auto;
  }
}

.farmboard__label {
  margin: 0 0 0.375rem;
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-muted);
}

.farmboard__value {
  margin: 0;
  font-size: 1.875rem;
  font-weight: 600;
  letter-spacing: -0.025em;
  /* Tabular figures so the digits do not shuffle as the number climbs. */
  font-variant-numeric: tabular-nums;
}

.farmboard__value--accent {
  color: var(--accent);
}

.farmboard__value--profit {
  color: var(--ok);
  /*
   * The last digits change roughly once a second while a cycle runs. A hard
   * swap reads as a glitch; a short fade reads as a number that is alive.
   */
  transition: color 200ms ease;
}

.farmboard__hint {
  margin: 0.25rem 0 0;
  font-size: 0.6875rem;
  color: var(--fg-muted);
}

.farm-progress {
  display: flex;
  flex-direction: column;
  gap: 0.4375rem;
}

.farm-progress__caption {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin: 0;
  font-size: 0.8125rem;
  color: var(--fg-muted);
}

.farm-progress__ends {
  font-size: 0.75rem;
  opacity: 0.8;
}

/* ------------------------------------------------------ the settlement window -- */

/*
 * THE WINDOW BAR: one UTC day, with the position's own history drawn on it.
 *
 * The bare progress bar this replaced showed a fraction with no scale, beside a
 * notice claiming the cycle "runs for 24 hours" — which it does not; it runs
 * until the next 00:00 UTC. The bar and the sentence were describing different
 * things and neither was the rule.
 *
 * Three segments, left to right:
 *   `__before`  the part of the day that was already gone when the money landed
 *   `__earned`  the part this position has actually been earning over
 *   (the rest)  what is still to come before the payout
 *
 * The gap on the left is the whole point. "You joined at nine in the morning so
 * you are paid for fifteen hours, not twenty-four" is a sentence people read
 * twice and still argue with; as a picture it needs no sentence at all.
 */
.window {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: 1rem 1.1rem 0.9rem;
  border-radius: var(--radius);
  background: linear-gradient(to bottom, #ffffff0a, #ffffff04);
  box-shadow: inset 0 0 0 1px var(--line);
}

.window__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.window__title {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--fg-muted);
}

.window__title .icon {
  opacity: 0.75;
}

.window__countdown {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  color: var(--accent-bright);
}

/*
 * THE TRACK HAS TO READ IN ITS FIRST MINUTE, NOT ONLY ITS LAST HOUR.
 *
 * The first version was 12px tall with a 4%-white hatch and a plain green fill.
 * The arithmetic was right — the owner joined at 09:38 and the segment rendered
 * at `left: 40.187%; width: 2.169%` — but two per cent of a twelve-pixel bar is
 * a twenty-pixel smudge in a colour barely above the background, and he
 * reasonably reported the green bar as missing. A position an hour old is
 * exactly when somebody stares at this thing.
 *
 * So: the bar is taller, the elapsed part is a visible surface rather than a
 * suggestion, the earning part glows and can never be thinner than a few pixels,
 * and "now" is a marker with a head rather than a hairline.
 */
/*
 * An <svg>, not a <div> of positioned spans.
 *
 * The span version took its geometry from inline style attributes, and the
 * site's Content-Security-Policy (`style-src 'self'`) makes the browser discard
 * those — so every band had zero width and the bar rendered empty, silently, in
 * every browser. SVG geometry lives in attributes, which the policy does not
 * touch. `display: block` because an inline <svg> otherwise sits on the text
 * baseline and leaves a gap under it.
 */
.window__track {
  display: block;
  width: 100%;
  height: 1.125rem;
  border-radius: 999px;
  overflow: hidden;
  background: var(--bg-input);
  box-shadow: inset 0 0 0 1px var(--line);
}

/*
 * The bands are filled with `fill`, not `background`. Geometry is in the
 * attributes; only the colour is CSS, which is exactly the split the policy
 * allows.
 */
.window__band--missed {
  fill: #f5a524;
}

.window__band--ahead {
  fill: #3eb46847;
}

.window__band--earned {
  fill: #55d183;
}

.window__band--now {
  fill: #ffffff;
}

/*
 * THE TRACK IS FILLED END TO END, IN TWO COLOURS.
 *
 * The version before this drew only the earning segment on an otherwise empty
 * track. The arithmetic was right, but an hour into a cycle that segment is two
 * per cent of the width, and against an empty bar it reads as nothing at all —
 * which is exactly what the owner reported.
 *
 * Now every pixel of the day is one of two things: amber for the part that was
 * over before the money landed, green for the part this position holds. The
 * boundary between them is the join, and it is unmissable even when the green
 * is a sliver, because the amber ends there.
 *
 * The green is split by brightness rather than by hue: solid up to now, dimmed
 * after it. Two colours, three readings, and no third thing to learn.
 */
/*
 * The bands move by their `x` and `width` attributes, so the transition is on
 * those rather than on `left`. SVG geometry attributes are animatable in CSS in
 * every current browser; where they are not, the bar simply jumps, which is
 * what an un-animated progress bar has always done.
 */
.window__band {
  transition:
    x 400ms linear,
    width 400ms linear;
}

/*
 * The legend. Three words that make the three colours readable without anybody
 * having to open the explanation underneath.
 */
.window__legend {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  flex-wrap: wrap;
  margin: 0;
  font-size: 0.6875rem;
  color: var(--fg-subtle);
}

.window__key {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.window__swatch {
  width: 0.7rem;
  height: 0.7rem;
  flex: none;
  border-radius: 0.2rem;
}

.window__swatch--missed {
  background: linear-gradient(to right, #b0781c, #f5a524);
}

.window__swatch--earned {
  background: linear-gradient(to right, #3eb468, #55d183);
}

.window__swatch--ahead {
  background: linear-gradient(to right, #3eb46833, #3eb46859);
  box-shadow: inset 0 0 0 1px #3eb46840;
}

.window__scale {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin: 0;
  font-size: 0.6875rem;
  font-variant-numeric: tabular-nums;
  color: var(--fg-subtle);
}

.window__joined {
  color: var(--ok);
  font-weight: 600;
}

/*
 * The explanation. A `<details>`, not a tooltip: a tooltip has nothing to hover
 * on a phone, and this is the paragraph that stops a support ticket.
 */
.window__explain {
  margin-top: 0.15rem;
  border-top: 1px solid var(--line);
  padding-top: 0.6rem;
}

.window__explainhead {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--accent-bright);
  cursor: pointer;
  list-style: none;
}

.window__explainhead::-webkit-details-marker {
  display: none;
}

.window__explainhead::after {
  content: '';
  width: 0.4rem;
  height: 0.4rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 150ms ease;
}

.window__explain[open] .window__explainhead::after {
  transform: rotate(225deg) translate(-1px, -1px);
}

.window__explainbody {
  display: grid;
  gap: 0.5rem;
  margin-top: 0.6rem;
}

.window__explainbody p {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--fg-muted);
}

.window__explainnote {
  padding-top: 0.5rem;
  border-top: 1px solid var(--line);
  opacity: 0.85;
}

/* ---------------------------------------------------------- refresh button -- */

/*
 * Ships hidden and is revealed by `app.js`. Without scripting it would be a
 * button that does nothing, and the reload it stands in for is already F5.
 */
/*
 * IT SITS BESIDE THE FIGURES, NOT OUT IN THE MIDDLE OF THE BAR.
 *
 * The bar is `space-between` over three children — the figures, this button and
 * the account switch — so the button was handed a third of the leftover width
 * and floated in the gap, attached to nothing. `margin-right: auto` eats that
 * gap on its right instead: the button lands against the tiles whose numbers it
 * reloads, and the account switch stays pinned to the far edge.
 */
.balancebar__refresh {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  align-self: center;
  margin-right: auto;
  padding: 0.45rem 0.75rem;
  border: 0;
  border-radius: 0.7rem;
  background: #ffffff0a;
  box-shadow: inset 0 0 0 1px var(--line);
  color: var(--fg-muted);
  font: inherit;
  font-size: 0.75rem;
  font-weight: 600;
  cursor: pointer;
}

.balancebar__refresh:hover:not(:disabled) {
  color: var(--fg);
  background: #ffffff14;
}

.balancebar__refresh:disabled {
  cursor: default;
}

/* Spins only while a request is in flight, so it reports work rather than decorating. */
.balancebar__refresh.is-busy .icon {
  animation: spin 700ms linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .balancebar__refresh.is-busy .icon {
    animation: none;
    opacity: 0.5;
  }

  .window__band {
    transition: none;
  }

  /*
   * THE BLANKET RULE, AND IT COMES LAST SO IT WINS.
   *
   * Somebody who has asked their system for less motion has usually asked for a
   * reason — vestibular disorders make sliding and scaling genuinely unpleasant,
   * not merely unwanted. Rather than remembering to switch off each new
   * animation as it is added, everything is reduced to almost nothing here and
   * new work inherits the courtesy automatically.
   *
   * `0.01ms` rather than `none`: a transition that is cancelled outright can
   * skip the events some scripts wait for, and a duration this short is
   * imperceptible while still firing them.
   */
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .button:active {
    transform: none;
  }
}

/*
 * THE LABEL STAYS ON A PHONE.
 *
 * It used to be hidden below 40rem to save room, which left a wide empty pill
 * with a small circular arrow in it — and a lone refresh glyph is a shape
 * people recognise on a toolbar, not in the middle of a balance strip. The
 * owner read it as a broken button. The word costs about forty pixels and
 * removes the question.
 *
 * `align-self: start` so it sits at the top of its row rather than stretching
 * to the height of the tiles beside it.
 */
@media (max-width: 40rem) {
  .balancebar__refresh {
    align-self: start;
    padding: 0.4rem 0.7rem;
  }
}

.farm-actions {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  padding-top: 0.25rem;
  border-top: 1px solid var(--border);
}

.badge--live {
  gap: 0.375rem;
}

.live-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse 2s ease-in-out infinite;
}

@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.35;
  }
}

.tier-now {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 0.5rem;
  font-size: 1.375rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--tier-color, var(--fg));
}

/* ---------- Amount input with a currency symbol ---------- */

.amount-input {
  position: relative;
  display: flex;
}

.amount-input__symbol {
  position: absolute;
  left: 0.8125rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--fg-muted);
  font-size: 0.9375rem;
  pointer-events: none;
}

.amount-input__field {
  padding-left: 1.75rem;
  font-variant-numeric: tabular-nums;
}

.form--inline {
  gap: 0.875rem;
}

.button--lg {
  padding: 0.75rem 1.5rem;
  font-size: 0.9375rem;
}

/* ---------- Admin: per-transaction history ---------- */

.txhistory {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

@media (min-width: 52rem) {
  .txhistory {
    grid-template-columns: 1fr 1fr;
  }
}

.txhistory__side {
  min-width: 0;
}

.txhistory__title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin: 0 0 0.5rem;
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-muted);
}

.txhistory__count {
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.75rem;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}

.txhistory__empty {
  margin: 0;
  padding: 0.75rem;
  font-size: 0.8125rem;
  color: var(--fg-muted);
  background: var(--bg-input);
  border-radius: var(--radius-sm);
}

.txlist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4375rem;
  /* Long histories scroll inside the card rather than making it endless. */
  max-height: 17rem;
  overflow-y: auto;
}

.txlist__item {
  padding: 0.5625rem 0.75rem;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.txlist__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
}

.txlist__amount {
  font-size: 0.9375rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.txlist__date {
  font-size: 0.6875rem;
  color: var(--fg-muted);
  white-space: nowrap;
}

.txlist__meta {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.1875rem;
}

.txlist__network {
  font-size: 0.6875rem;
  color: var(--fg-muted);
}

.txlist__address {
  margin: 0.3125rem 0 0;
  font-size: 0.6875rem;
  color: var(--fg-muted);
  overflow-wrap: anywhere;
  line-height: 1.4;
}

/* ---------- Two-line table cell: network above, address below ---------- */

.txcell {
  display: flex;
  flex-direction: column;
  gap: 0.0625rem;
  min-width: 0;
}

.txcell__network {
  font-size: 0.75rem;
}

.txcell__address {
  font-size: 0.6875rem;
  line-height: 1.35;
  color: var(--fg-muted);
  /* Addresses are long and must not push the table sideways forever. */
  max-width: 22rem;
  overflow-wrap: anywhere;
  /*
   * AND THE CELL AROUND IT MUST ALLOW THE WRAP.
   *
   * Table cells are `white-space: nowrap` so that dates and amounts never break
   * mid-figure. That also silently defeated `overflow-wrap` here: the hash was
   * laid out as one unbreakable line and ran straight under the status column,
   * which is what it looked like on screen — the address printed over the badge
   * beside it. Normal wrapping restored for this cell only.
   */
  white-space: normal;
}

/* In the console the same cell is narrower, because the card is half a row. */
.shell--admin .txcell__address {
  max-width: 15rem;
}

/* ---------- Admin: per-account expandable rows ---------- */

/*
 * Built on <details>. The browser supplies the open/close behaviour and the
 * keyboard handling; with thousands of accounts the alternative is either a wall
 * of transactions or a script, and this is neither.
 */
.people {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-card);
}

.people__head,
.person {
  display: grid;
  grid-template-columns: minmax(0, 2.2fr) minmax(0, 1fr) minmax(0, 1fr) 1.5rem;
  gap: 1rem;
  align-items: center;
  padding: 0.75rem 1.25rem;
}

.people__head {
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--fg-muted);
  background: var(--bg-raised);
  border-bottom: 1px solid var(--border);
}

.person-row + .person-row {
  border-top: 1px solid var(--border);
}

.person {
  cursor: pointer;
  list-style: none;
}

.person::-webkit-details-marker {
  display: none;
}

.person:hover {
  background: #ffffff06;
}

.person-row[open] > .person {
  background: #ffffff08;
  border-bottom: 1px solid var(--border);
}

/* A row that needs a decision is marked without forcing every row open. */
.person-row--flagged > .person {
  box-shadow: inset 3px 0 0 var(--warning);
}

@media (max-width: 40rem) {
  .wallet-gas__row {
    grid-template-columns: 1fr 1fr;
    gap: 0.35rem 0.75rem;
  }

  .wallet-gas__network {
    grid-column: 1 / -1;
    padding-bottom: 0.25rem;
    border-bottom: 1px solid var(--line);
  }

  .wallet-gas__balance {
    text-align: left;
  }
}

/* The same metal palette identifies the selected level on every surface. */
.tierline {
  --plaque-light: #e8f8b7;
  --plaque-mid: #acd876;
  --plaque-deep: #77a14a;
  --plaque-ink: #25341a;
  --plaque-edge: #d4ef97;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border: 1px solid var(--plaque-edge);
  background:
    radial-gradient(ellipse at 8% -75%, rgb(255 253 230 / 0.82), transparent 61%),
    linear-gradient(115deg, var(--plaque-light), var(--plaque-mid) 60%, var(--plaque-deep));
  box-shadow: inset 0 1px 0 rgb(255 255 240 / 0.7), 0 12px 26px -18px var(--plaque-deep);
  color: var(--plaque-ink);
}
.tierline::before {
  content: '';
  position: absolute;
  width: 11rem;
  height: 11rem;
  right: 1.8rem;
  top: -7rem;
  border: 1px solid rgb(55 45 20 / 0.12);
  border-radius: 50%;
  box-shadow: 0 0 0 1.3rem rgb(255 250 219 / 0.09), 0 0 0 2.8rem rgb(255 250 219 / 0.07);
  pointer-events: none;
}
.tierline > * { position: relative; z-index: 1; }
.tierline .tierline__label,
.tierline .tierline__name,
.tierline .tierline__go,
.tierline .tierline__aside { color: var(--plaque-ink); }
.tierline .tier__dot { background: var(--plaque-ink); box-shadow: 0 0 0 3px rgb(255 255 255 / 0.3); }
.tierline.tier--dedicated_node {
  --plaque-light: #c9f5df; --plaque-mid: #80d4ad; --plaque-deep: #4b9d78;
  --plaque-ink: #19392d; --plaque-edge: #a9efd0;
}
.tierline.tier--priority_node {
  --plaque-light: #e1dfff; --plaque-mid: #aaaaf0; --plaque-deep: #777ac5;
  --plaque-ink: #292a50; --plaque-edge: #cbc9ff;
}
.tierline.tier--private_cluster {
  --plaque-light: #f0d99e; --plaque-mid: #d8b371; --plaque-deep: #b58640;
  --plaque-ink: #332515; --plaque-edge: #f7e1aa;
}
.tierline.tierline--individual {
  --plaque-light: var(--individual-gold-light);
  --plaque-mid: var(--individual-gold-mid);
  --plaque-deep: var(--individual-gold-deep);
  --plaque-ink: var(--individual-gold-ink);
  --plaque-edge: var(--individual-gold-edge);
}
.tierline.tier--below_minimum {
  --plaque-light: #e5e7e5; --plaque-mid: #bcc3bc; --plaque-deep: #8e9990;
  --plaque-ink: #26312a; --plaque-edge: #d7ddd6;
}
.tierline__aside { grid-column: 2; grid-row: 2; font-size: 0.69rem; opacity: 0.8; }
@media (max-width: 26rem) {
  .tierline__aside { grid-column: 1; grid-row: 3; }
}
.tier-individual--active {
  border-color: var(--individual-gold-edge);
  box-shadow: inset 0 1px 0 rgb(255 255 238 / 0.85), 0 0 0 1px rgb(255 220 69 / 0.55), 0 20px 46px -22px rgb(255 193 20 / 0.65);
}
.tier-individual__badge {
  border: 1px solid rgb(67 44 14 / 0.24);
  border-radius: 99px;
  padding: 0.28rem 0.55rem;
  background: var(--individual-gold-mid);
  color: var(--individual-gold-ink);
  font-size: 0.67rem;
  font-weight: 800;
}
.tier-individual__levels {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.65rem;
}
.tier-individual__level {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35rem;
  padding: 0.32rem 0.48rem;
  border: 1px solid rgb(74 48 14 / 0.21);
  border-radius: 0.5rem;
  background: rgb(255 248 215 / 0.4);
  color: #543a1b;
  font-size: 0.68rem;
}
.tier-individual__level small { font-size: 0.63rem; }
.tier-individual__level--current {
  border-color: #4e3516;
  background: var(--individual-gold-mid);
  color: var(--individual-gold-ink);
}

.individual-admin__steps,
.individual-admin__filters { display: flex; flex-wrap: wrap; gap: 0.45rem; margin: 0.65rem 0; }
.individual-admin__step {
  display: grid;
  gap: 0.16rem;
  flex: 1 1 8.2rem;
  padding: 0.7rem 0.8rem;
  border: 1px solid rgb(244 207 126 / 0.44);
  border-radius: 0.8rem;
  background: linear-gradient(130deg, #332b1e, #211f1b);
  color: #f8e7bb;
}
.individual-admin__step span { color: #cfbf9c; font-size: 0.76rem; }
.individual-admin__step b { color: #f8cd78; font-size: 0.86rem; }
.individual-admin__filter {
  padding: 0.42rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: 99px;
  color: var(--fg-muted);
  font-size: 0.76rem;
  text-decoration: none;
}
.individual-admin__filter--current { border-color: #e0b965; background: rgb(232 186 94 / 0.12); color: #f5d995; }
.individual-admin__tier { color: var(--individual-gold-mid); font-weight: 750; }
.individual-admin__muted { color: var(--fg-muted); }
.individual-admin__detail { display: grid; grid-template-columns: minmax(0, 1fr) minmax(15rem, 0.82fr); gap: 0.75rem; margin-top: 0.75rem; }
.individual-admin__account,
.individual-admin__message {
  min-width: 0;
  padding: 0.85rem;
  border: 1px solid rgb(244 207 126 / 0.37);
  border-radius: 0.9rem;
  background: linear-gradient(135deg, #25241f, #191b1b);
}
.individual-admin__heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.5rem; }
.individual-admin__heading h2 { overflow-wrap: anywhere; margin: 0.15rem 0; font-size: 1.12rem; }
.individual-admin__eyebrow { color: #d5b96f; font-size: 0.65rem; letter-spacing: 0.08em; text-transform: uppercase; }
.individual-admin__numbers { display: flex; flex-wrap: wrap; gap: 0.35rem; margin: 0.55rem 0; }
.individual-admin__numbers span { display: grid; gap: 0.16rem; flex: 1 1 7rem; padding: 0.52rem; border: 1px solid rgb(255 255 255 / 0.12); border-radius: 0.55rem; font-size: 0.7rem; color: var(--fg-muted); }
.individual-admin__numbers strong { color: var(--fg); font-size: 0.86rem; }
.individual-admin__current { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.6rem; padding: 0.65rem; border: 1px solid var(--individual-gold-edge); border-radius: 0.65rem; background: linear-gradient(115deg, var(--individual-gold-light), var(--individual-gold-mid) 60%, var(--individual-gold-deep)); color: var(--individual-gold-ink); }
.individual-admin__current div { display: grid; gap: 0.1rem; }
.individual-admin__current small { font-size: 0.65rem; }
.individual-admin__hint { color: #d5c6a5; font-size: 0.78rem; }
.individual-admin__message textarea { width: 100%; min-height: 11rem; margin-top: 0.4rem; }
.individual-admin__actions { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.55rem; }
@media (max-width: 52rem) { .individual-admin__detail { grid-template-columns: 1fr; } }
.individual-admin__message-head { display: grid; gap: 0.2rem; margin-bottom: 0.65rem; }
.individual-admin__message-head strong { color: #f2d58e; font-size: 0.92rem; }
.individual-admin__message-head small { color: var(--fg-muted); font-size: 0.72rem; line-height: 1.35; }
.individual-admin__offer-widget {
  display: grid;
  gap: 0.48rem;
  margin-bottom: 0.65rem;
  padding: 0.65rem;
  border: 1px solid rgb(242 208 139 / 0.28);
  border-radius: 0.7rem;
  background: linear-gradient(140deg, rgb(70 53 27 / 0.32), rgb(18 22 20 / 0.82));
}
.individual-admin__offer-balance { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 0.25rem 0.5rem; }
.individual-admin__offer-balance span { display: inline-flex; align-items: baseline; gap: 0.32rem; color: #c5bda9; font-size: 0.7rem; }
.individual-admin__offer-balance strong { color: #f6dc9d; font-size: 0.98rem; font-variant-numeric: tabular-nums; }
.individual-admin__offer-balance .individual-admin__offer-gap { font-size: 0.63rem; }
.individual-admin__offer-balance .individual-admin__offer-gap strong { font-size: 0.72rem; }
.individual-admin__offer-levels { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0.26rem; }
.individual-admin__offer-level {
  display: grid;
  justify-items: center;
  gap: 0.06rem;
  min-width: 0;
  padding: 0.38rem 0.12rem;
  border: 1px solid rgb(236 200 121 / 0.22);
  border-radius: 0.45rem;
  background: rgb(12 15 14 / 0.43);
  color: #ead7aa;
  font-size: 0.68rem;
  text-decoration: none;
}
.individual-admin__offer-level small { overflow: hidden; max-width: 100%; color: #b6ad94; font-size: 0.55rem; text-overflow: ellipsis; white-space: nowrap; }
.individual-admin__offer-level:hover,
.individual-admin__offer-level:focus-visible { border-color: #f0d08a; background: rgb(229 184 94 / 0.13); }
.individual-admin__offer-level--selected { border-color: var(--individual-gold-edge); background: linear-gradient(145deg, var(--individual-gold-light), var(--individual-gold-mid) 60%, var(--individual-gold-deep)); box-shadow: inset 0 1px 0 rgb(255 249 226 / 0.6); color: var(--individual-gold-ink); }
.individual-admin__offer-level--selected small { color: #4f381a; }
.individual-admin__offer-level--past { opacity: 0.35; cursor: default; }
.individual-admin__offer-metrics { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.3rem; }
.individual-admin__offer-metrics span { display: grid; gap: 0.1rem; min-width: 0; padding: 0.42rem 0.48rem; border: 1px solid rgb(238 210 150 / 0.14); border-radius: 0.45rem; background: rgb(12 15 14 / 0.36); color: #beb8aa; font-size: 0.63rem; }
.individual-admin__offer-metrics strong { overflow-wrap: anywhere; color: #f7e0a7; font-size: 0.85rem; font-variant-numeric: tabular-nums; }
.individual-admin__offer-note { color: #aaa38f; font-size: 0.62rem; line-height: 1.35; }
.individual-admin__templates { display: grid; gap: 0.4rem; }
.individual-admin__template {
  min-width: 0;
  border: 1px solid rgb(244 207 126 / 0.22);
  border-radius: 0.65rem;
  background: rgb(13 15 15 / 0.45);
  overflow: hidden;
}
.individual-admin__template[open] { border-color: rgb(244 207 126 / 0.56); background: rgb(28 25 19 / 0.75); }
.individual-admin__template summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.55rem;
  padding: 0.45rem 0.65rem;
  color: #eee6d3;
  cursor: pointer;
  font-size: 0.78rem;
  font-weight: 700;
  list-style: none;
}
.individual-admin__template summary::-webkit-details-marker { display: none; }
.individual-admin__template summary:hover,
.individual-admin__template summary:focus-visible { background: rgb(244 207 126 / 0.08); }
.individual-admin__template summary .icon { margin-left: auto; transition: transform 150ms ease; }
.individual-admin__template[open] summary .icon { transform: rotate(90deg); }
.individual-admin__template-body { padding: 0 0.65rem 0.65rem; }
.individual-admin__template-body textarea { min-height: 8rem; max-height: 16rem; margin: 0; resize: vertical; font-size: 0.77rem; line-height: 1.48; }
.individual-admin__template-body .individual-admin__actions { margin-top: 0.45rem; }
.individual-admin__template-body .button { min-height: 1.9rem; padding: 0.32rem 0.55rem; font-size: 0.7rem; }

/* ================================================= promotional farm boost == */

.promo-summary { display: grid; gap: .55rem; padding-top: .5rem; border-top: 1px solid var(--line); }
.promo-summary__metrics { display: grid; grid-template-columns: minmax(0,1fr); margin: 0; }
.promo-summary__metric { display: grid; grid-template-columns: minmax(0,1fr) auto; gap: .75rem; align-items: baseline; padding: .5rem 0; border-bottom: 1px solid var(--line); }
.promo-summary__metric dt { min-width: 0; margin: 0; font-size: .76rem; color: var(--fg-muted); line-height: 1.4; overflow-wrap: anywhere; }
.promo-summary__metric dd { margin: 0; font-size: .85rem; font-weight: 600; line-height: 1.4; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.promo-summary__codes { display: grid; gap: .4rem; }
.promo-summary__code { display: flex; align-items: center; justify-content: space-between; gap: .5rem; font-size: .78rem; min-width: 0; }
.promo-summary__code > .mono { min-width: 0; overflow-wrap: anywhere; }
.promo-summary__code > .badge { flex: none; }
.promo-card--entry [data-live-wallet-promo]:empty { display: none; }
.promo-card--entry .promo-code-entry { grid-template-columns: minmax(0,1fr); gap: .5rem; }
.promo-card--entry .promo-code-entry .button { padding-inline: .9rem; }
.promo-activations { display: grid; gap: .4rem; min-width: 0; }
.promo-activation { min-width: 0; border: 1px solid var(--border); border-radius: .8rem; overflow: hidden; }
.promo-activation > summary { display: flex; justify-content: space-between; gap: .6rem; padding: .65rem .8rem; cursor: pointer; font-size: .8rem; }
.promo-activation > summary span { overflow-wrap: anywhere; min-width: 0; }
.promo-activation > summary::after { content: '+'; flex: 0 0 auto; }
.promo-activation[open] > summary::after { content: '−'; }
.promo-activation .promo-card { margin: 0; border: 0; border-top: 1px solid var(--border); border-radius: 0; }

.promo-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.65rem;
  align-items: stretch;
  margin-block: 0.85rem;
  padding: 1rem;
  border: 1px solid color-mix(in srgb, var(--accent) 25%, var(--line));
  border-radius: var(--radius-lg);
  background:
    radial-gradient(circle at 100% 0, color-mix(in srgb, var(--accent) 10%, transparent), transparent 42%),
    var(--surface);
}

.promo-card h2 { margin: 0.15rem 0 0.25rem; font-size: 1rem; }
.promo-card p { margin: 0; color: var(--muted); font-size: 0.78rem; line-height: 1.45; }
.promo-card__eyebrow { color: var(--accent-bright); font: 0.64rem/1.2 var(--font-mono); letter-spacing: 0.09em; text-transform: uppercase; }
.promo-card__form { min-width: 0; }
.promo-card__titlebar,
.promo-card__titleline { display: flex; align-items: center; gap: 0.42rem; }
.promo-card__titlebar { justify-content: space-between; }
.promo-card__titlebar h2,
.promo-card__titleline h2 { margin: 0; }
.promo-help {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.35rem;
  height: 1.35rem;
  flex: none;
  border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--muted);
  font: 700 0.72rem/1 var(--font-mono);
  text-decoration: none;
}
.promo-help:hover,
.promo-help:focus-visible { border-color: var(--accent); color: var(--accent-bright); }
.promo-code-entry { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0.45rem; margin-top: 0.32rem; }
.promo-card__head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
.promo-card__note { padding-top: 0.15rem; }

.promo-metrics {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.45rem;
}
.promo-metrics--four { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.promo-metrics > span,
.promo-admin-strip__figures > span {
  min-width: 0;
  padding: 0.55rem 0.65rem;
  border: 1px solid var(--line);
  border-radius: 0.65rem;
  background: color-mix(in srgb, var(--surface-2) 74%, transparent);
}
.promo-metrics small,
.promo-admin-strip small { display: block; margin-bottom: 0.2rem; color: var(--muted); font-size: 0.62rem; }
.promo-metrics strong,
.promo-admin-strip strong { font-size: 0.86rem; font-variant-numeric: tabular-nums; }
.promo-progress { display: block; width: 100%; height: 0.28rem; overflow: hidden; border: 0; border-radius: 999px; background: var(--line); appearance: none; }
.promo-progress::-webkit-progress-bar { background: var(--line); }
.promo-progress::-webkit-progress-value { border-radius: 999px; background: var(--accent); }
.promo-progress::-moz-progress-bar { border-radius: 999px; background: var(--accent); }

.promo-admin-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.7rem; }
.promo-generator { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0.5rem; align-items: end; }
.promo-generator > .field { min-width: 0; margin: 0; }
.promo-generator .field__label { white-space: nowrap; }
.promo-rule-note,
.promo-withdraw-note { margin: 0.55rem 0 0; color: var(--muted); font-size: 0.7rem; line-height: 1.4; }
.promo-code-list { display: grid; }
.promo-code-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto auto; gap: 0.65rem; align-items: center; padding: 0.55rem 0.7rem; border-bottom: 1px solid var(--line); }
.promo-code-row:last-child { border-bottom: 0; }
.promo-code-row small { display: block; margin-top: 0.12rem; color: var(--muted); font-size: 0.62rem; }
.promo-created-code { display: inline-block; margin-right: 0.5rem; font-size: 1rem; color: var(--accent-bright); }

.promo-admin-strip { margin: 0 0 0.7rem; padding: 0.7rem; border: 1px solid color-mix(in srgb, var(--accent) 25%, var(--line)); border-radius: var(--radius-lg); background: var(--surface); }
.promo-admin-strip__head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.55rem; margin-bottom: 0.5rem; }
.promo-admin-strip__head > .mono { min-width: 0; overflow-wrap: anywhere; }
.promo-admin-strip__figures { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.4rem; }
.promo-admin-strip__figures--preview { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.promo-admin-strip > p { margin: 0.45rem 0 0; color: var(--muted); font-size: 0.66rem; }
.minisummary__promo { border-color: color-mix(in srgb, var(--accent) 25%, var(--line)) !important; }

@media (max-width: 56rem) {
  .promo-card,
  .promo-admin-grid { grid-template-columns: 1fr; }
}

@media (max-width: 40rem) {
  .promo-card { padding: 0.75rem; gap: 0.65rem; }
  .promo-code-entry { grid-template-columns: 1fr; }
  .promo-generator { grid-template-columns: 1fr; }
  .promo-generator .button { grid-column: auto; width: 100%; }
  .promo-metrics,
  .promo-metrics--four,
  .promo-admin-strip__figures { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .promo-admin-strip__figures--preview > :last-child { grid-column: 1 / -1; }
  .promo-code-row { grid-template-columns: minmax(0, 1fr) auto; }
  .promo-code-row form { justify-self: end; }
}

#promo-codes { scroll-margin-top: 5rem; }
.how__question {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.3rem;
  height: 1.3rem;
  border: 1px solid color-mix(in srgb, var(--accent) 42%, var(--line));
  border-radius: 50%;
  color: var(--accent-bright);
  font: 700 0.7rem/1 var(--font-mono);
}

/* Each withdrawal account is a small card, not another line in one long box. */
.people--withdrawals,
.people--deposits {
  display: grid;
  gap: 0.4rem;
  border: 0;
  border-radius: 0;
  overflow: visible;
  background: transparent;
}

.people--withdrawals .people__head,
.people--withdrawals .person-row,
.people--deposits .people__head,
.people--deposits .person-row {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--bg-card);
}

.people--withdrawals .people__head,
.people--deposits .people__head {
  border-color: var(--border-strong);
}

.people--withdrawals .person-row + .person-row,
.people--deposits .person-row + .person-row {
  border-top: 1px solid var(--border);
}

.people--withdrawals .person-row--flagged {
  border-color: color-mix(in srgb, var(--warning) 42%, var(--border));
}

.people--withdrawals .person-row[open] {
  border-color: color-mix(in srgb, var(--accent) 42%, var(--border));
}

.person__who {
  display: flex;
  flex-direction: column;
  gap: 0.0625rem;
  min-width: 0;
}

.person__email {
  font-size: 0.9375rem;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.person__meta {
  font-size: 0.6875rem;
  color: var(--fg-muted);
}

.person__waiting {
  display: inline-flex;
  margin-left: 0.45rem;
  padding: 0.05rem 0.38rem;
  border: 1px solid color-mix(in srgb, var(--warning) 38%, transparent);
  border-radius: 999px;
  color: var(--warning);
  line-height: 1.35;
}

.person__figure {
  display: flex;
  flex-direction: column;
  gap: 0.0625rem;
}

.person__amount {
  font-size: 0.9375rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.person__count,
.person__last {
  font-size: 0.6875rem;
  color: var(--fg-muted);
}

.person__chevron {
  color: var(--fg-muted);
  transition: transform 140ms ease;
}

.person-row[open] .person__chevron {
  transform: rotate(180deg);
}

.person-row__body {
  padding: 1rem 1.25rem 1.25rem;
  background: var(--bg-raised);
}

.person-row__link {
  margin: 0.75rem 0 0;
  font-size: 0.8125rem;
}

/*
 * THE WHOLE ACCOUNT, OPENED INSIDE THE ROW RATHER THAN ON A PAGE OF ITS OWN.
 *
 * It is the account page's own markup, so it arrives carrying a page header and
 * a column of cards sized for a page. Inside a row it needs a line to separate
 * it from the summary above and a little less of everything: the heading drops
 * to the size of a heading within a card, and the cards lose the outer gap that
 * would otherwise leave the row twice as tall as what is in it.
 */
.person-row__account {
  margin-top: 0.9rem;
  border-top: 1px solid var(--border);
  padding-top: 0.9rem;

  /*
   * IT IS A PANEL INSIDE A ROW, NOT A PAGE.
   *
   * The account view is written for a screen of its own, so dropped into a list
   * it arrives at page scale: a page heading, cards with card-sized padding,
   * grids that want the full width. Three of those stacked made one row taller
   * than the entire list it belonged to, and the list stopped reading as a list.
   *
   * Everything below shrinks it in place rather than forking the markup — one
   * description of an account, drawn smaller when it is a guest somewhere else.
   */
  font-size: 0.9375rem;
}

.person-row__account .page-header {
  margin-bottom: 0.6rem;
}

.person-row__account .page-header__title {
  font-size: 1rem;
}

.person-row__account .card {
  margin: 0 0 0.6rem;
  border-radius: var(--radius-sm, 8px);
  background: var(--bg);
}

.person-row__account .card__head,
.person-row__account .card__content,
.person-row__account .card__foot {
  padding: 0.55rem 0.7rem;
}

.person-row__account .card__title {
  font-size: 0.8125rem;
}

/* Wide fixed grids are what actually push the row past the viewport. */
.person-row__account .grid,
.person-row__account .stats,
.person-row__account .tier {
  gap: 0.5rem;
}

.person-row__account table {
  font-size: 0.8125rem;
}

.person-row__account > :last-child {
  margin-bottom: 0;
}

/*
 * A SUBMENU INSIDE A ROW. The console already had `.subdetails`; these two rules
 * only stop a table inside one from touching the summary above it, and keep a
 * long history scrolling inside its own box instead of stretching the row.
 */
.person-row__body .subdetails table {
  font-size: 0.8125rem;
}

.person-row__body .subdetails > :not(summary) {
  margin-top: 0.5rem;
}

/* What one account is owed, and the button for all of it. */
.payperson {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin: 0.75rem 0;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 8px);
  background: var(--bg-raised);
}

.people--withdrawals .payperson {
  margin: 0.5rem 0;
}

/* The ordinary payout action is deliberately the strongest control in the row. */
.button--pay {
  background: linear-gradient(to bottom, #30c96b, #16a34a 58%, #117a39);
  border-color: #43d47a;
  color: #061c0e;
  font-weight: 750;
  box-shadow:
    inset 0 1px 0 #ffffff5c,
    0 7px 18px -11px #22c55e;
}

.button--pay:hover {
  background: linear-gradient(to bottom, #4ade80, #22b455 58%, #16823f);
  border-color: #68e492;
}

.button--pay:active {
  background: #12813d;
}

.button.button--pay.button--small {
  padding: 0.42rem 0.85rem;
}

.payperson .prose {
  margin: 0;
}

.payperson > :first-child {
  margin-top: 0;
}

.payperson > :last-child {
  margin-bottom: 0;
}

/*
 * THE ONE FIGURE AND THE ONE ADDRESS, BIG ENOUGH TO COPY WITHOUT SQUINTING.
 *
 * This is the only step of a payout a person still performs by hand, off a
 * wallet whose key is deliberately not on the server. Getting the address wrong
 * here is irreversible, so it gets its own line, at full length, in mono — never
 * truncated with an ellipsis, which is unreadable and untypeable.
 */
.paylump {
  margin-bottom: 1rem;
}

.paylump__address {
  margin: 0.35rem 0 0.5rem;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 8px);
  background: var(--bg);
  font-size: 0.9375rem;
  overflow-wrap: anywhere;
  user-select: all;
}

/*
 * A PAYOUT IN PROGRESS, IN THE ROW THAT STARTED IT.
 *
 * The one thing a person still has to do — move coins off the cold wallet — is
 * the line that has to be readable at a glance, so the address is on its own
 * line in mono and allowed to wrap rather than pushing the table sideways.
 */
.payline {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.3rem;
}

.payline__ask {
  font-size: 0.8125rem;
  line-height: 1.45;
}

.payline__ask .mono {
  overflow-wrap: anywhere;
}

/* The ways that are not the ordinary way, folded shut beside the button. */
.subdetails--tight {
  margin-top: 0;
  border-top: 0;
  padding-top: 0;
}

.subdetails--tight .subdetails__summary {
  font-size: 0.8125rem;
  opacity: 0.75;
}

.subdetails--tight form {
  margin-top: 0.5rem;
}

.subdetails__summary--danger {
  color: var(--danger);
}

.rowactions .cancel-withdrawal {
  display: grid;
  align-items: stretch;
  gap: 0.4rem;
  width: min(24rem, 100%);
}

.rowactions > .subdetails--tight[open] {
  flex: 1 0 100%;
}

.rowactions > .subdetails--tight > .subdetails__summary {
  padding: 0.28rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-input);
  color: var(--fg-muted);
  line-height: 1.35;
}

.rowactions > .subdetails--tight > .subdetails__summary--danger {
  border-color: color-mix(in srgb, var(--danger) 34%, var(--border));
  color: var(--danger);
}

.cancel-withdrawal textarea {
  box-sizing: border-box;
  width: 100%;
  min-height: 3.5rem;
  resize: vertical;
}

.cancel-withdrawal .field__optional {
  margin: 0;
  white-space: normal;
}

.cancel-withdrawal .button {
  justify-self: start;
}

/* A long history scrolls inside its own box; the summary above it stays put. */
.person-row__body .subdetails .table-wrap {
  max-height: 20rem;
  overflow-y: auto;
}

.subdetails {
  margin-top: 0.875rem;
  border-top: 1px solid var(--border);
  padding-top: 0.75rem;
}

.subdetails__summary {
  cursor: pointer;
  font-size: 0.8125rem;
  color: var(--accent);
  list-style: none;
}

.subdetails__summary::-webkit-details-marker {
  display: none;
}

.subdetails__summary::before {
  content: '▸ ';
}

.subdetails[open] .subdetails__summary::before {
  content: '▾ ';
}

/* ---------- The compact account summary inside an open row ---------- */

.minisummary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
  gap: 0.625rem;
  margin-bottom: 0.875rem;
  padding: 0.75rem;
  background: var(--bg-input);
  border-radius: var(--radius-sm);
}

.minisummary > div {
  display: flex;
  flex-direction: column;
  gap: 0.0625rem;
}

.minisummary span {
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--fg-muted);
}

.minisummary strong {
  font-size: 0.9375rem;
  font-variant-numeric: tabular-nums;
}

.minisummary--withdrawal {
  grid-template-columns: repeat(4, minmax(7.5rem, 1fr));
  padding: 0.6rem 0.7rem;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
}

.withdrawal-requests {
  margin-top: 0.75rem;
}

.withdrawal-requests__title {
  margin: 0 0 0.4rem;
  font-size: 0.8125rem;
  font-weight: 650;
  color: var(--fg-muted);
}

.withdrawal-requests table {
  font-size: 0.8125rem;
}

.withdrawal-requests .table th,
.withdrawal-requests .table td {
  padding: 0.45rem 0.6rem;
}

.withdrawal-requests .table tbody tr:nth-child(even) td {
  background: #ffffff03;
}

.withdrawal-requests .table tbody tr + tr td {
  border-top-color: var(--border-strong);
}

.withdrawal-destination {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-width: 0;
}

.transfer-identifiers {
  display: grid;
  gap: 0.25rem;
  min-width: 12rem;
}

.compact-copy {
  display: grid;
  grid-template-columns: 2.6rem minmax(5rem, 1fr) auto;
  align-items: center;
  gap: 0.35rem;
  min-width: 0;
  max-width: 21rem;
}

.compact-copy__kind {
  color: var(--fg-muted);
  font-size: 0.625rem;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.045em;
}

.compact-copy__value {
  display: block;
  min-width: 0;
  max-width: 14rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  user-select: all;
}

.compact-copy__button {
  padding: 0.2rem 0.42rem;
  border: 1px solid var(--border-strong);
  border-radius: 0.4rem;
  background: var(--bg-input);
  color: var(--accent-bright);
  font: inherit;
  font-size: 0.6875rem;
  font-weight: 650;
  line-height: 1.25;
  cursor: pointer;
}

.compact-copy__button:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.compact-copy__button.is-copied {
  border-color: var(--ok);
  color: var(--ok);
}

.compact-copy--empty {
  grid-template-columns: 2.6rem minmax(5rem, 1fr);
}

.people--deposits .table th,
.people--deposits .table td {
  padding: 0.45rem 0.6rem;
}

/* ---------- Coin and network, one above the other ---------- */

.netcell {
  display: flex;
  flex-direction: column;
  gap: 0.0625rem;
}

.netcell__coin {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.8125rem;
  font-weight: 700;
  white-space: nowrap;
}

.netcell__mark {
  width: 1.1rem;
  height: 1.1rem;
  vertical-align: baseline;
}

.netcell__chain {
  font-size: 0.6875rem;
  color: var(--fg-muted);
  white-space: nowrap;
}

/*
 * A hash or an address, shortened to a head and a tail.
 *
 * `min-width: 0` and `max-width` together: a table cell will happily be as wide
 * as its longest unbreakable word, and a 66-character hash in a monospace face
 * pushed the status column off the end of the row — which is what the operator
 * saw as two columns printed on top of each other.
 *
 * The full value is in `title`, so hovering still gives it in one piece.
 */
.hashcell {
  display: inline-block;
  max-width: 14rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
  font-size: 0.75rem;
  letter-spacing: -0.01em;
  cursor: help;
}

/*
 * `overflow-wrap: anywhere` DOES NOTHING INSIDE A `white-space: nowrap` CELL,
 * and every table cell here is nowrap. So this used to be an 18rem box whose
 * content simply painted past its own edge and over the column beside it — which
 * is how the transaction hash ended up printed on top of the status badge.
 */
.breakable {
  display: inline-block;
  max-width: 18rem;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* ---------- Date filters ---------- */

.filters {
  display: flex;
  align-items: flex-end;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.875rem 1rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.filters__field {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.filters__label {
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-muted);
}

.filters .field__input {
  padding: 0.4375rem 0.625rem;
  font-size: 0.8125rem;
  /* The native date picker is dark-scheme aware only if told so. */
  color-scheme: dark;
}

.filters__clear {
  font-size: 0.8125rem;
  color: var(--fg-muted);
  padding-bottom: 0.5rem;
}

.totalsbar {
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
  padding: 0.6875rem 1rem;
  background: var(--bg-input);
  border-radius: var(--radius-sm);
  font-size: 0.8125rem;
  color: var(--fg-muted);
  font-variant-numeric: tabular-nums;
}

.totalsbar strong {
  color: var(--fg);
}

.totalsbar__flag {
  color: var(--warning);
}

.field__input--tiny {
  padding: 0.3125rem 0.5rem;
  font-size: 0.75rem;
  max-width: 9rem;
}

.rowactions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.rowactions form {
  display: flex;
  gap: 0.3125rem;
  align-items: center;
  flex-wrap: wrap;
}

.country strong {
  font-family: var(--font-mono);
  letter-spacing: 0.06em;
}

@media (max-width: 48rem) {
  .people__head {
    display: none;
  }

  .person {
    grid-template-columns: minmax(0, 1fr) auto 1.5rem;
  }

  .person__last {
    display: none;
  }

  .minisummary--withdrawal {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .withdrawal-destination {
    align-items: flex-start;
    flex-direction: column;
    gap: 0.25rem;
  }
}

/* ========================================================== phones: tables ==
 *
 * A table is a grid because the columns line up. On a 375px screen they cannot,
 * and the previous answer — scroll it sideways — meant a seven-column console
 * table showed two columns and hid the rest behind a blind swipe.
 *
 * Below this width each row becomes a card and each cell carries its column name
 * from the `data-label` the server writes. The header row is removed from the
 * flow but NOT with `display: none` — hiding it that way takes it away from
 * screen readers too, and then the labels have nothing to associate with.
 */
@media (max-width: 46rem) {
  .table-wrap {
    /* No longer the scroll container: nothing overflows once rows are blocks,
       and leaving it scrollable produces a phantom horizontal drag. */
    overflow-x: visible;
  }

  .table,
  .table tbody,
  .table tr,
  .table td {
    display: block;
    width: 100%;
  }

  .table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .table tr {
    background: var(--bg-raised);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 0.75rem 0.875rem;
    margin-bottom: 0.625rem;
  }

  .table td {
    display: flex;
    /*
     * WRAPPING, AND A FLOOR OF ZERO. Without both, a long value cannot shrink
     * below the width of its own text and simply runs off the card — which is
     * exactly what the reward table did on an iPhone: "What it means" carried a
     * sentence, the sentence would not fold, and the right-hand half of every
     * row was outside the screen.
     *
     * `min-width: 0` lets the flex item be narrower than its content, and
     * `overflow-wrap: anywhere` lets the text break rather than push. A long
     * value then drops onto its own line instead of widening the page.
     */
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.2rem 1rem;
    min-width: 0;
    overflow-wrap: anywhere;
    border: 0;
    padding: 0.3125rem 0;
    text-align: left;
    /*
     * THE ACTUAL CAUSE OF THE TEXT RUNNING OFF THE SCREEN.
     *
     * `.table td` carries `white-space: nowrap` for the wide layout, where a
     * table column that wraps mid-address is worse than one that scrolls. In the
     * card layout nobody removed it — so a cell holding a whole sentence kept it
     * on ONE line, and since the box had been made shrinkable the text simply
     * ran out of the card and off the phone.
     *
     * It cost two rounds of "fixed it" that fixed nothing, because the box was
     * measured and the box was innocent: `getBoundingClientRect` reported the
     * cell as exactly the right width while its content sat outside it.
     */
    white-space: normal;
  }

  /*
   * A cell whose value is a sentence takes the whole width of the card, under
   * its label rather than squeezed beside it. Half a line of prose in a column
   * two words wide is unreadable however neatly it wraps.
   */
  .table td > .field__hint,
  .table td > .prose {
    flex: 1 1 100%;
    min-width: 0;
    text-align: left;
  }

  /* The label, from the column heading. */
  .table td::before {
    content: attr(data-label);
    flex: 0 0 auto;
    color: var(--fg-muted);
    font-size: 0.8125rem;
    font-weight: 500;
  }

  /* A cell with no label is a full-width block — action buttons, mostly. */
  .table td:not([data-label])::before {
    content: none;
  }

  .table td.table__num {
    /* Right alignment meant "compare down the column". There is no column. */
    text-align: right;
  }

  /* Values that cannot wrap — addresses, hashes — scroll inside their own cell
     rather than widening the card and with it the page. */
  .table td .mono,
  .table td .breakable {
    min-width: 0;
    overflow-wrap: anywhere;
    text-align: right;
  }
}

/* --------------------------------------------------------- back to top --- */

/*
 * THE OPPOSITE CORNER FROM THE HELP BUTTON.
 *
 * It was stacked above it on the right, which is tidy in a mockup and wrong in a
 * hand: two round buttons in a column at the same edge are one target somebody
 * hits by accident, and the owner looked for this one on the left because that
 * is where the corner was free.
 *
 * Round, plain, and a full 44px — the size below which the miss rate on a phone
 * climbs sharply.
 */
.to-top {
  position: fixed;
  left: 1.25rem;
  /* Level with the help button, and clear of the home indicator on an iPhone. */
  bottom: calc(1.25rem + var(--tg-safe-bottom, 0px));
  z-index: 50;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: var(--bg-card);
  color: var(--fg-muted);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: var(--shadow-card);
}

.to-top:hover {
  color: var(--fg);
  border-color: var(--accent);
}

/* ------------------------------------------------------- copy by tapping -- */

/*
 * A value that is its own copy button: the referral code, and anything else
 * short enough to be aimed at.
 *
 * Styled as a chip rather than a button, because it is a VALUE first — a control
 * that looks like a button beside a label reads as "do something", and this one
 * reads as "here it is, and you may take it".
 */
.copyable {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  /* A finger-sized target without a finger-sized box: the padding does the work. */
  padding: 0.3rem 0.55rem;
  min-height: 2rem;
  border: 1px dashed var(--line-strong);
  border-radius: 0.5rem;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.copyable:hover {
  border-color: var(--accent);
  border-style: solid;
}

.copyable__value {
  font-family: var(--font-mono);
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  /* Selectable, so copying by hand still works with no script at all. */
  user-select: all;
}

.copyable__mark {
  color: var(--fg-muted);
  font-size: 0.85rem;
}

/* Confirmation: the value stays put, only the mark beside it changes. */
.copyable.is-copied {
  border-color: var(--ok);
  border-style: solid;
}

.copyable.is-copied .copyable__mark {
  color: var(--ok);
  font-family: var(--font-sans);
  font-size: 0.75rem;
}

/* ====================================================== the bar on a phone ==
 *
 * TWO FAULTS THE OWNER FOUND ON A REAL iPHONE, and both are about the same bar.
 *
 * 1. THE MENU BUTTON SCROLLED AWAY. The top bar was an ordinary block, so on a
 *    long page — how-it-works, the tier list, history — reaching the navigation
 *    meant scrolling back to the top first. On a phone that is the difference
 *    between an app and a document.
 *
 * 2. THE TITLE WAS NOT CENTRED. The bar was a flex row: burger, title, language
 *    picker. The picker is far wider than the burger, so "centring" the middle
 *    item put it visibly left of centre — the kind of thing you cannot unsee.
 *    A three-column grid with equal outer columns centres the title against the
 *    SCREEN rather than against whatever happens to be beside it.
 */
@media (max-width: 60rem) {
  .topbar {
    position: sticky;
    top: 0;
    z-index: 50;
    display: grid;
    /* Equal outer columns: the title is centred on the screen, not between two
       controls of different widths. */
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 0.5rem;
    /* Opaque, because content scrolls underneath it. */
    background: var(--bg-raised);
    border-bottom: 1px solid var(--line);
    /* Telegram draws its own header above the page; this keeps the bar clear of
       it and of the notch. */
    padding-top: calc(0.6rem + var(--tg-safe-top, 0px) + var(--tg-content-top, 0px));
    padding-bottom: 0.6rem;
  }

  .topbar__burger {
    justify-self: start;
  }

  .topbar__title {
    grid-column: 2;
    text-align: center;
    font-size: 1.05rem;
    /* A long page name shortens rather than pushing the controls apart. */
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .topbar__actions {
    grid-column: 3;
    justify-self: end;
    min-width: 0;
  }

  /* The language picker beside a page title: the flag alone, so the bar stays a
     bar. The full names are still in the menu it opens. */
  .topbar .langmenu__name {
    display: none;
  }

  .topbar .langmenu__button {
    padding: 0.35rem 0.45rem;
  }
}

/* ============================================================== density ====
 *
 * THE WHOLE SITE, TIGHTENED VERTICALLY. One block, at the end of the file, so
 * that the rhythm is a decision in one place instead of forty numbers scattered
 * through three thousand lines — and so that undoing it is deleting one block.
 *
 * WHY IT WAS TOO LOOSE. The spacing was written for a desktop, on a desktop:
 * 1.75rem of page padding, 1.5rem inside every card, 1.25rem between them, ten
 * pixels above and below every data row. On a phone that is most of the screen
 * spent on nothing, and the owner's complaint — a tier card where four figures
 * fill a whole screen — is the visible half of it. Inside Telegram, where the
 * sheet is shorter still, it costs more again.
 *
 * WHY IT IS NOT SIMPLY SMALLER. Every reduction here is about a quarter, and the
 * RELATIONSHIPS are kept: a card still breathes more than a row inside it, a
 * heading still sits further from what precedes it than from what it labels.
 * Compressing everything to the same value is what makes an interface look
 * cheap; compressing proportionally makes it look edited.
 *
 * Overriding rather than editing the originals is deliberate: the originals stay
 * readable next to the components they belong to, and the one thing anybody will
 * want to adjust later — "a bit tighter", "a bit looser" — is all here.
 */

/*
 * A SECOND PASS, TIGHTER AGAIN. The first one took about a quarter out; the
 * owner looked at the result and said there was still too much nothing on the
 * screen, which was right — a card was still spending nearly a fifth of its
 * height on its own padding. This takes roughly another fifth off every vertical
 * measure while leaving the horizontal ones alone: width is not what was being
 * wasted, and narrowing the padding sideways would push text against the edge.
 */
.content {
  gap: 0.75rem;
  padding: 1rem 1.15rem;
}

.card__content {
  gap: 0.7rem;
  padding: 0.85rem 1.15rem 0.95rem;
}

.card__title {
  padding: 0.7rem 1.15rem;
}

.card__footer {
  padding: 0.65rem 1.15rem;
}

.grid {
  gap: 0.75rem;
}

.stats {
  gap: 0.6rem;
}

/* Rows inside a card: the tightest thing on the page, because they are read as a
   list rather than as separate objects. */
.data-row {
  padding-block: 0.35rem;
}

.tierspec__row {
  padding: 0.28rem 0;
}

.page-header {
  gap: 0.55rem;
}

.tier-grid {
  gap: 0.75rem;
}

/* Paragraphs stacked in a card were carrying a full blank line between them. */
.card__content .prose + .prose,
.card__content .prose + .field__hint {
  margin-top: -0.15rem;
}

/*
 * A phone gets one step tighter again.
 *
 * Not because small screens deserve less care — because a card's padding is a
 * fixed cost repeated down the page, and on 390 points of width it is the
 * difference between four figures per screen and seven.
 */
@media (max-width: 46rem) {
  .content {
    gap: 0.6rem;
    padding: 0.7rem 0.85rem;
  }

  .card__content {
    gap: 0.6rem;
    padding: 0.75rem 0.9rem 0.85rem;
  }

  .card__title {
    padding: 0.62rem 0.9rem;
    font-size: 1rem;
  }

  .card__footer {
    padding: 0.6rem 0.9rem;
  }

  .data-row {
    padding-block: 0.32rem;
  }

  .grid,
  .tier-grid,
  .stats {
    gap: 0.7rem;
  }

  /* The card-per-row table, which is a list of small cards and gains the most
     from losing a few pixels each. */
  .table tr {
    padding: 0.6rem 0.75rem;
    margin-bottom: 0.5rem;
  }

  .table td {
    padding: 0.22rem 0;
  }
}

/*
 * NOTHING MAY MAKE THE PAGE ITSELF SCROLL SIDEWAYS.
 *
 * A phone that drags horizontally takes the navigation off screen with it, and
 * the cause is always one element that refuses to shrink: a table, an address, a
 * long word in a heading. The rows above fix the case that was found; this is
 * the backstop for the next one, and it is deliberately on the two outermost
 * boxes rather than on `*`, which would break the panels that are supposed to
 * scroll inside themselves.
 */
@media (max-width: 60rem) {
  html,
  body {
    /*
     * `clip`, NOT `hidden`, AND THE DIFFERENCE IS A BUG I SHIPPED.
     *
     * `overflow-x: hidden` makes the element a scroll container — and a scroll
     * container breaks `position: sticky` for everything inside it. So this
     * line, added as a belt-and-braces against sideways scrolling, quietly
     * unstuck the top bar on every phone: the menu button scrolled away again,
     * which is exactly the thing that had just been fixed.
     *
     * `clip` cuts the overflow without creating a scroll container, so sticky
     * keeps working. It is the real fix rather than a workaround, and the
     * sideways overflow it was guarding against is gone anyway — that was the
     * `white-space: nowrap` in the table cells.
     */
    overflow-x: clip;
  }

  .content,
  .card,
  .card__content {
    min-width: 0;
    max-width: 100%;
  }
}

/* ============================================================ phones: touch ==
 *
 * Anything tapped gets a 44px target. Not a style preference: below roughly that
 * size the miss rate on a phone climbs sharply, and every control here either
 * moves money or navigates away from a page showing a balance.
 */
@media (pointer: coarse) {
  .button,
  .tabs__tab,
  .sidebar__link,
  .topbar__burger,
  .locale-switcher__select,
  .field__action {
    min-height: 44px;
  }

  .button--small {
    /* Still visually small, still a legal target. */
    min-height: 40px;
    padding-inline: 0.875rem;
  }
}

/* ================================================================== footer == */

.site-footer {
  border-top: 1px solid var(--border);
  margin-top: 3rem;
  padding: 1.5rem 1.25rem 2.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  align-items: center;
  text-align: center;
}

.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 1.25rem;
}

.site-footer__links a {
  color: var(--fg-muted);
  font-size: 0.875rem;
  text-decoration: none;
}

.site-footer__links a:hover,
.site-footer__links a:focus-visible {
  color: var(--fg);
  text-decoration: underline;
}

/* The risk line is muted but never hidden, and never smaller than this. */
.site-footer__note {
  color: var(--fg-muted);
  font-size: 0.8125rem;
  max-width: 46rem;
  line-height: 1.5;
}

/* =========================================================== cookie banner == */

.cookie-banner {
  position: fixed;
  left: 0.75rem;
  right: 0.75rem;
  bottom: 0.75rem;
  z-index: 60;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.875rem;
  padding: 1rem 1.125rem;
  background: var(--bg-card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
}

.cookie-banner__text {
  flex: 1 1 22rem;
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--fg-muted);
}

.cookie-banner__text a {
  color: var(--accent);
}

.cookie-banner__actions {
  flex: 0 0 auto;
}

@media (min-width: 60rem) {
  .cookie-banner {
    left: auto;
    right: 1.5rem;
    bottom: 1.5rem;
    max-width: 34rem;
  }
}

/*
 * КОРОТКИЙ ЭКРАН. Баннер закреплён снизу, а его текст в немецком и
 * португальском заметно длиннее английского. На iPhone SE и на сложенном
 * Fold он вырастал настолько, что занимал половину вьюпорта и накрывал то,
 * ради чего человек пришёл — форму входа или кнопку в приложение.
 *
 * Высота ограничивается, а не текст: сокращать согласие нельзя, оно
 * юридическое. Всё, что не поместилось, прокручивается внутри баннера,
 * кнопка при этом остаётся на виду.
 */
@media (max-height: 46rem) {
  .cookie-banner {
    max-height: 40vh;
    overflow-y: auto;
  }

  .cookie-banner__text {
    font-size: 0.8125rem;
  }
}

/* ============================================================ legal pages == */

.auth__body--wide {
  display: block;
  max-width: 52rem;
  margin-inline: auto;
}

.auth__form-column--centred {
  margin-inline: auto;
  max-width: 34rem;
}

.legal {
  max-width: 46rem;
  margin-inline: auto;
  padding-bottom: 1rem;
}

.legal__header {
  margin-bottom: 1.75rem;
}

.legal__title {
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.legal__updated {
  margin-top: 0.375rem;
  color: var(--fg-muted);
  font-size: 0.8125rem;
}

.legal__section {
  margin-bottom: 1.5rem;
}

.legal__heading {
  font-size: 1rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

.legal__section .prose + .prose {
  margin-top: 0.75rem;
}

.legal__list {
  margin: 0.5rem 0 0;
  padding-left: 1.125rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  color: var(--fg-muted);
  line-height: 1.6;
}

.legal__siblings {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  margin-top: 2rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
}

/* ====================================================== verification ask == *
 *
 * Sits directly under the top bar, above the balance. With no mail and no menu
 * entry, this strip is the only way somebody learns that support has asked them
 * for something — so it is deliberately hard to read past, and deliberately
 * gone the moment they have submitted.
 */

.verify-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.75rem 1.25rem;
  background: var(--warning-soft);
  border-bottom: 1px solid var(--border);
  color: var(--fg);
  font-size: 0.9375rem;
  line-height: 1.45;
}

.verify-banner span {
  flex: 1 1 16rem;
}

/* Verification asked: the banner and its menu item go red, to stand out from
   everything green the product otherwise is. */
.verify-banner--alert {
  background: var(--danger-soft);
  border-bottom-color: var(--danger);
}

.sidebar__link--verify {
  grid-template-columns: auto 1fr auto;
  color: var(--danger);
}

.sidebar__link--verify:hover,
.sidebar__link--verify.sidebar__link--active {
  color: var(--danger);
  background: var(--danger-soft);
}

.sidebar__link--verify .icon,
.sidebar__link--verify:hover .icon,
.sidebar__link--verify.sidebar__link--active .icon {
  opacity: 1;
}

.sidebar__badge--alert {
  grid-column: 3;
  grid-row: 1;
  align-self: center;
  justify-self: end;
  margin-top: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.15rem;
  height: 1.15rem;
  padding: 0 0.35rem;
  border-radius: 999px;
  background: var(--danger);
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1;
}

/* ============================================================ combo select ==
 *
 * A styled, searchable dropdown that app.js builds on top of a real <select>.
 * With no script the native select shows through and works; once enhanced, the
 * select is taken out of the layout (kept in the DOM so the form still submits)
 * and this custom control stands in its place — so the country field is the
 * product's own list, not the operating system's.
 */
.combo {
  position: relative;
}

.combo__native {
  width: 100%;
}

.combo--ready .combo__native {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.combo__control {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  width: 100%;
  padding: 0.625rem 0.8125rem;
  background: var(--bg-input);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--fg);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.combo__control:hover {
  border-color: var(--fg-muted);
}

.combo--open .combo__control {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.combo--error .combo__control {
  border-color: var(--danger);
}

.combo__control--empty .combo__text {
  color: var(--fg-muted);
}

.combo__text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.combo__caret {
  flex: none;
  color: var(--fg-muted);
  transition: transform 0.12s ease;
}

.combo--open .combo__caret {
  transform: rotate(180deg);
}

.combo__panel {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + 0.25rem);
  z-index: 40;
  background: var(--bg-card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  box-shadow: 0 12px 30px rgb(0 0 0 / 0.35);
  overflow: hidden;
}

.combo__search {
  width: 100%;
  padding: 0.55rem 0.8125rem;
  border: 0;
  border-bottom: 1px solid var(--border);
  background: var(--bg-input);
  color: var(--fg);
  font: inherit;
  outline: none;
}

.combo__options {
  list-style: none;
  margin: 0;
  padding: 0.25rem;
  max-height: 15rem;
  overflow-y: auto;
}

.combo__option {
  padding: 0.5rem 0.6rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.combo__option:hover,
.combo__option--active {
  background: #ffffff0f;
}

.combo__option[aria-selected='true'] {
  color: var(--accent);
  font-weight: 600;
}

.combo__empty {
  padding: 0.75rem;
  color: var(--fg-muted);
  text-align: center;
}

/* The premium-emoji library: a plain emoji, a name field, a remove. */
.emoji-lib {
  list-style: none;
  margin: 0.75rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.emoji-lib__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
}

.emoji-lib__glyph {
  font-size: 1.5rem;
  line-height: 1;
  flex: none;
}

.emoji-lib__form {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1 1 14rem;
}

.emoji-lib__form .field__input {
  flex: 1 1 auto;
}

/* Broadcast button rows: label, destination, type, colour, emoji. */
.bcbtns {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.4rem;
}

.bcbtn {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1.4fr) auto auto auto;
  gap: 0.4rem;
}
.bcbtn--web-app input[name$="btnUrl"] {
  border-color: rgb(151 225 103 / 0.48);
  color: var(--fg-muted);
}

@media (max-width: 640px) {
  .bcbtn {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .bcbtn input[name$="btnUrl"] { grid-column: 1 / -1; grid-row: 2; }
  .bcbtn select[name$="btnType"] { grid-column: 2; grid-row: 1; }
}

.audience-picker { margin: 0 0 0.75rem; padding: 0; border: 0; }
.audience-picker legend { margin-bottom: 0.55rem; color: var(--fg-muted); font-size: 0.78rem; font-weight: 650; letter-spacing: 0.04em; text-transform: uppercase; }
.audience-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: 0.55rem; }
.audience-option { display: flex; flex-direction: column; gap: 0.35rem; min-height: 5.5rem; padding: 0.75rem; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg-input); color: var(--fg-muted); font-size: 0.8rem; line-height: 1.4; text-decoration: none; }
.audience-option:hover, .audience-option--active { border-color: var(--accent); background: var(--accent-soft); }
.audience-option__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.5rem; color: var(--fg); }
.bc-button-tools, .bc-quick-actions, .bc-save-buttons, .bc-saved-list { display: flex; flex-wrap: wrap; align-items: center; gap: 0.45rem; }
.bc-button-tools { margin-top: 0.4rem; justify-content: space-between; }
.bc-button-tools > .field__input { flex: 1 1 14rem; }
.bc-quick-action--selected,
.bc-quick-action--selected:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.bc-button-feedback { flex-basis: 100%; color: var(--accent); font-size: 0.78rem; }
.bc-button-feedback[hidden] { display: none; }
.bc-button-preview {
  margin-top: 0.55rem;
  padding: 0.65rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: #17202b;
}
.bc-button-preview[hidden] { display: none; }
.bc-button-preview__label { display: block; margin-bottom: 0.45rem; color: #aebccc; font-size: 0.73rem; }
.bc-button-preview__list { display: grid; gap: 0.3rem; }
.bc-button-preview__button {
  display: block;
  overflow: hidden;
  padding: 0.48rem 0.65rem;
  border-radius: 0.4rem;
  font-size: 0.86rem;
  font-weight: 650;
  line-height: 1.3;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bc-button-preview__button--default { background: #26384b; color: #63b3f5; }
.bc-button-preview__button--primary { background: #347fbd; color: #fff; }
.bc-button-preview__button--success { background: #2b9b69; color: #fff; }
.bc-button-preview__button--danger { background: #c6535c; color: #fff; }
.bc-button-preview__note { display: block; margin-top: 0.4rem; color: #95a4b6; font-size: 0.69rem; }
.bc-button-settings { margin-top: 0.5rem; }
.bc-button-settings > summary { width: fit-content; color: var(--fg-muted); cursor: pointer; font-size: 0.8rem; }
.bc-button-settings[open] > summary { margin-bottom: 0.55rem; color: var(--fg); }
.bc-button-settings > .field__input { width: 100%; margin-bottom: 0.5rem; }
.bc-button-settings > .field__hint { margin-top: 0.5rem; }
.bc-save-buttons { margin-top: 0.65rem; }
.bc-save-buttons .field__input { flex: 1 1 14rem; }
.bc-saved-list { margin-top: 0.5rem; }
.bc-saved-pill { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.25rem 0.35rem 0.25rem 0.55rem; border: 1px solid var(--border); border-radius: 999px; color: var(--fg-muted); font-size: 0.78rem; }
.bc-saved-pill__remove { border: 0; background: transparent; color: inherit; font: inherit; cursor: pointer; }
.bc-post-line { display: flex; align-items: stretch; gap: 0.45rem; }
.bc-post-line .field__input { flex: 1 1 auto; }
.bc-post-preview { margin-top: 0.65rem; overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg-input); }
.bc-post-preview__head { display: flex; justify-content: space-between; gap: 0.75rem; padding: 0.65rem 0.75rem; border-bottom: 1px solid var(--border); font-size: 0.8rem; }
.bc-post-preview__body { display: grid; gap: 0.75rem; padding: 0.75rem; }
.bc-post-preview__body img { display: block; width: 100%; max-height: 28rem; border-radius: var(--radius-sm); object-fit: contain; background: var(--bg); }
.bc-post-preview__status { margin: 0; color: var(--fg-muted); font-size: 0.82rem; }
.bc-post-preview__text { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.5; }
.bc-post-preview[hidden], .bc-post-preview [hidden] { display: none; }
.bc-tabs > .tabs { margin-bottom: 1rem; }
.bc-advanced { margin-top: 1rem; }
.bc-advanced > summary { cursor: pointer; color: var(--fg-muted); font-weight: 650; }
.bc-advanced[open] > summary { margin-bottom: 1rem; }
.bc-manual-message { margin-top: 0.9rem; padding-top: 0.9rem; border-top: 1px solid var(--border); }
.bc-manual-message > summary { cursor: pointer; color: var(--fg-muted); font-size: 0.85rem; }
.bc-manual-message[open] > summary { margin-bottom: 0.9rem; }
.automation-list { display: flex; flex-direction: column; gap: 1rem; margin: 0.75rem 0 1rem; padding: 0; list-style: none; }
.automation-sequence { overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-input); }
.automation-sequence > summary { cursor: pointer; list-style: none; }
.automation-sequence > summary::-webkit-details-marker { display: none; }
.automation-sequence > summary::after { color: var(--fg-muted); content: '›'; font-size: 1.25rem; transition: transform 0.15s ease; }
.automation-sequence[open] > summary::after { transform: rotate(90deg); }
.automation-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; padding: 0.65rem; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg-input); }
.automation-sequence > .automation-row { border: 0; border-radius: 0; }
.automation-row__main { display: flex; flex: 1 1 18rem; flex-direction: column; gap: 0.2rem; }
.automation-row__main span { color: var(--fg-muted); font-size: 0.78rem; }
.automation-conversions { margin: 0 0.65rem; padding: 0.65rem 0; border-top: 1px solid var(--border); }
.automation-conversions summary { cursor: pointer; color: var(--accent); font-size: 0.82rem; font-weight: 650; }
.automation-conversions ul { display: flex; flex-direction: column; gap: 0.35rem; margin: 0.6rem 0 0; padding: 0; list-style: none; }
.automation-conversions li { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.5rem; font-size: 0.8rem; }
.automation-conversions li span { color: var(--fg-muted); }
.automation-editor-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; padding: 0.75rem 0.85rem; border-top: 1px solid var(--border); }
.automation-settings { display: flex; flex-wrap: wrap; align-items: end; gap: 0.65rem; padding: 0.75rem; border-top: 1px solid var(--border); }
.automation-settings .field { flex: 1 1 13rem; margin: 0; }
.automation-settings > .button { margin-left: auto; }
.automation-builder { margin-bottom: 1rem; padding: 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-input); }
.automation-draft-list { display: flex; flex-direction: column; gap: 0.55rem; }
.automation-draft-step { padding: 0.7rem; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); }
.automation-draft-step__head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.5rem; }
.automation-draft-step__head > strong { font-size: 1rem; }
.automation-draft-step__actions { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.automation-draft-step:only-child .automation-draft-step__actions { display: none; }
.automation-draft-step__buttons { margin-top: 0.75rem; }
.automation-draft-step__buttons > summary { cursor: pointer; color: var(--fg-muted); font-size: 0.84rem; font-weight: 650; }
.automation-draft-step__buttons[open] > summary { margin-bottom: 0.75rem; }
.automation-builder__add { width: 100%; justify-content: center; border-style: dashed; }
.automation-exclusions { flex: 1 0 100%; margin: 0.3rem 0; }
.automation-exclusions > summary { width: fit-content; cursor: pointer; color: var(--fg-muted); font-size: 0.82rem; }
.automation-exclusions[open] > summary { margin-bottom: 0.5rem; color: var(--fg); }
.automation-exclusions__list { display: grid; gap: 0.3rem; max-height: 12rem; overflow: auto; margin: 0.5rem 0; }
.automation-exclusions__item { display: flex; align-items: start; gap: 0.5rem; padding: 0.4rem 0.5rem; border: 1px solid var(--border); border-radius: var(--radius-sm); cursor: pointer; }
.automation-exclusions__item span { display: grid; min-width: 0; gap: 0.1rem; font-size: 0.8rem; }
.automation-exclusions__item code { overflow-wrap: anywhere; color: var(--fg-muted); font-size: 0.68rem; }
.bc-history-id { display: block; margin-top: 0.2rem; overflow-wrap: anywhere; color: var(--fg-muted); font-size: 0.68rem; }
.automation-timeline { position: relative; display: flex; flex-direction: column; gap: 0.8rem; margin: 0; padding: 0.85rem; list-style: none; }
.automation-timeline::before { position: absolute; top: 0; bottom: 0; left: 1.68rem; width: 2px; background: var(--border); content: ''; }
.automation-step { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 0.65rem; padding: 0.85rem; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg); box-shadow: 0 0.35rem 1rem rgb(0 0 0 / 6%); }
.automation-step__marker { z-index: 1; display: grid; flex: 0 0 1.9rem; width: 1.9rem; height: 1.9rem; place-items: center; border: 2px solid var(--bg-input); border-radius: 999px; background: var(--accent); color: #fff; font-size: 0.75rem; font-weight: 700; }
.automation-step__main { display: flex; flex: 1 1 14rem; flex-direction: column; gap: 0.2rem; }
.automation-step__main span { color: var(--fg-muted); font-size: 0.78rem; }
.automation-node__schedule { color: var(--accent) !important; font-weight: 650; }
.automation-step__actions { display: flex; flex: 1 0 100%; flex-wrap: wrap; gap: 0.4rem; padding-left: 2.55rem; }
.automation-node__preview { flex: 1 0 100%; }
.automation-node__preview > .button { width: 100%; justify-content: center; }
.automation-node__preview .bc-post-preview { width: 100%; }
.automation-step-edit { flex: 1 0 100%; margin-left: 2.55rem; padding-top: 0.65rem; border-top: 1px solid var(--border); }
.automation-step-edit > summary { cursor: pointer; color: var(--accent); font-size: 0.82rem; font-weight: 650; }
.automation-step-edit[open] > summary { margin-bottom: 0.75rem; }
.automation-add-step { padding: 0.85rem; border-top: 1px solid var(--border); }
.automation-add-step > summary { display: flex; min-height: 2.8rem; align-items: center; justify-content: center; padding: 0.65rem 1rem; border: 1px dashed var(--accent); border-radius: var(--radius-sm); background: var(--accent-soft); cursor: pointer; color: var(--accent); font-weight: 700; list-style: none; }
.automation-add-step > summary::-webkit-details-marker { display: none; }
.automation-add-step[open] > summary { margin-bottom: 0.8rem; }
.bc-automation-create > summary { display: inline-flex; list-style: none; cursor: pointer; }
.bc-automation-create > summary::-webkit-details-marker { display: none; }
.bc-automation-create[open] > summary { margin-bottom: 1rem; }

@media (max-width: 640px) {
  .bc-post-line, .bc-save-buttons { align-items: stretch; flex-direction: column; }
  .automation-settings .field { flex-basis: 100%; }
}

.bc__or {
  margin: 1rem 0 0;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
  color: var(--fg-muted);
  font-size: 0.85rem;
}

/* Onboarding drip: the list of steps and the delay control. */
.drip {
  list-style: none;
  margin: 0.5rem 0 1rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.drip__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
}

.drip__when {
  flex: 0 0 auto;
  font-weight: 650;
}

.drip__meta {
  flex: 1 1 12rem;
  min-width: 0;
  color: var(--fg-muted);
  font-size: 0.85rem;
}

.drip__delay {
  display: flex;
  gap: 0.4rem;
}

.drip__delay input {
  max-width: 7rem;
}

/* ========================================================= payout breakdown ==
 *
 * Sits directly above the approve button. The operator is about to decide
 * whether to send money, and the only figure that decision turns on — how much
 * of it is the account's own deposit and how much is profit — has to be in the
 * same glance as the button, not on another screen.
 */

.breakdown {
  margin: 0.875rem 0;
  padding: 0.875rem 1rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-raised);
}

/* Paying out more than was ever deposited is the case worth catching. */
.breakdown--profit {
  border-left-color: var(--accent);
  background: var(--accent-soft);
}

.breakdown__lead {
  font-size: 0.9375rem;
  font-weight: 600;
  margin-bottom: 0.625rem;
}

.breakdown__split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 0.625rem 1.25rem;
}

.breakdown__split div {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}

.breakdown__split span {
  color: var(--fg-muted);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.breakdown__split strong {
  font-size: 1.0625rem;
  font-variant-numeric: tabular-nums;
}

.breakdown__note {
  margin-top: 0.75rem;
  color: var(--fg-muted);
  font-size: 0.8125rem;
  line-height: 1.5;
}

/* ============================================================ attachments == *
 *
 * Plain links, never thumbnails. Rendering an uploaded image inline would mean
 * the browser fetching and decoding bytes a stranger chose, on a page showing
 * somebody''s balance — and every file here is served as an attachment, which a
 * thumbnail could not be anyway.
 */

.attachments {
  list-style: none;
  margin: 0.625rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.attachments__link {
  display: inline-flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.4375rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
  color: var(--fg);
  text-decoration: none;
  font-size: 0.875rem;
  max-width: 100%;
}

.attachments__link:hover,
.attachments__link:focus-visible {
  border-color: var(--border-strong);
}

.attachments__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.attachments__meta {
  color: var(--fg-muted);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  flex: 0 0 auto;
}

/*
 * A picture attached to a ticket, shown rather than described.
 *
 * Capped in height so a phone photograph three thousand pixels tall does not
 * push the reply box off the screen — it is a preview, and the full file is one
 * click away. `object-fit: cover` keeps the crop sensible whatever shape the
 * original is, and the checked background makes a transparent PNG legible.
 */
.attachments__item--shot {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.3rem;
}

.attachments__preview {
  display: block;
  border-radius: var(--radius-sm);
  overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--border);
  line-height: 0;
}

.attachments__preview:hover {
  box-shadow: inset 0 0 0 1px var(--accent);
}

.attachments__image {
  display: block;
  width: auto;
  max-width: min(22rem, 100%);
  max-height: 13rem;
  object-fit: cover;
  background: #ffffff0a;
}

/* In the console the thread sits in a narrower column. */
.shell--admin .attachments__image {
  max-width: min(18rem, 100%);
  max-height: 11rem;
}

/* File inputs are styled by the browser; this only keeps them from overflowing. */
input[type='file'].field__input {
  padding: 0.5rem;
  font-size: 0.875rem;
}

/* ================================================================ helpers == */

/* A note under a form: the forgotten-password link, a standalone action. */
.form__aside {
  margin-top: 0.875rem;
  text-align: center;
  font-size: 0.875rem;
}

.mono {
  font-family: var(--font-mono);
  font-size: 0.9375em;
}

/* ---------------------------------------------------------------- tiers -- */

/*
 * THE ROWS HAVE TO LINE UP ACROSS THE CARDS.
 *
 * Without this the tagline and the description are as tall as their own text,
 * so "Private Cluster" — whose tagline wraps to two lines and whose description
 * runs to five — pushes its Capital, Yield band and Commission rows a
 * centimetre below the same rows in the card beside it. Four price columns
 * whose figures do not align are hard to compare, which is the one thing the
 * page exists for.
 *
 * Reserved height rather than CSS subgrid: subgrid is well supported now, but
 * this needs to hold on whatever a visitor is actually using, and two
 * min-heights cannot fail.
 */
/* ---------------------------------------------------------- tier colours -- */

/*
 * A COLOUR PER TIER, AND ONE PLACE THAT DECIDES IT.
 *
 * Four cards side by side that differ only in their numbers read as one thing
 * repeated; four that each carry their own hue read as a ladder, which is what
 * they are. The hues ascend blue → teal → violet → gold, and gold at the top is
 * the one convention about rank that needs no explaining.
 *
 * Each tier sets three custom properties and nothing else. Everything that
 * wants tinting — the rail, the dot, the tagline, the ticks, the badge, the
 * heading on the dashboard — reads `--tier-color` and does not know which tier
 * it is inside. Adding a tier is one block here.
 *
 * NOT USED FOR OUTCOMES. Green and red stay reserved for money arriving and
 * money failing; a tier colour never appears on a figure, only on the frame
 * around one. Teal is close enough to the success green that it is worth
 * saying: it is a hue on a ladder here, never a verdict.
 *
 * The class comes from the tier's id, not its position, so inserting a tier
 * cannot silently hand somebody else's colour to a different rung.
 */
.tier {
  --tier-color: var(--accent-bright);
  --tier-soft: #0093fd1f;
  --tier-glow: #0093fd66;
}

/*
 * THE LADDER IS A JOURNEY ACROSS THE SPECTRUM, and that is the whole idea.
 *
 * The colours used to be four unrelated hues, so a tier's colour said "this is a
 * different tier" and nothing more. Now the hue TRAVELS, and it travels away
 * from the brand: emerald at the bottom, through teal and periwinkle, to
 * champagne at the top. Colour means level, and somebody who has seen this page
 * once reads their standing off a single badge on the dashboard.
 *
 * WHY IT ENDS IN METAL AND NOT IN VIOLET. Violet was the summit in the first
 * version, and violet is what every competitor in this category and every
 * generated banner already uses — arriving there says "the same as everyone
 * else" at exactly the moment the ladder is supposed to say "the top". Warm
 * metal against a cold palette is the oldest signal of arrival there is, and it
 * is the one nobody on that reference was using.
 */
.tier--shared_node {
  --tier-color: #1fc98a;
  --tier-soft: #1fc98a1f;
  --tier-glow: #1fc98a55;
}

.tier--dedicated_node {
  --tier-color: #2ec2b8;
  --tier-soft: #2ec2b81f;
  --tier-glow: #2ec2b855;
}

.tier--priority_node {
  --tier-color: #8b7bf0;
  --tier-soft: #8b7bf01f;
  --tier-glow: #8b7bf055;
}

.tier--private_cluster {
  /* The top of the ladder: violet, the colour standing arrives at. */
  --tier-color: var(--prestige);
  --tier-soft: var(--prestige-soft);
  --tier-glow: #d9bd8555;
}

/* Not on the grid, but it is the tier somebody is on before they fund. */
.tier--below_minimum {
  /* Off the ladder entirely: no hue at all, which is the point. */
  --tier-color: #7f8f87;
  --tier-soft: #7f8f871f;
  --tier-glow: #7f8f8744;
}

/*
 * EVERY tier card is tinted, not only the one you are on.
 *
 * A wash of the tier's own colour running out of the top of the card, plus a
 * matching tint behind the heading. Four cards that share one grey surface are
 * one object repeated; four that each glow their own colour are four products
 * on a shelf, which is how somebody chooses between them.
 *
 * The wash is short and it fades to nothing well before the numbers — a colour
 * behind a figure makes the figure harder to read, and the figures are the
 * thing that has to stay legible.
 */
/*
 * THE TIER CARD AS A CUT STONE.
 *
 * This is the surface people screenshot and the one the whole page is selling,
 * so it gets the design budget the rest of the interface deliberately does not.
 * Four layers, and the order matters:
 *
 *   1. A GRADIENT STROKE, bright at the top in the tier's colour and gone by the
 *      bottom. Drawn as a background on the element with a mask that hollows out
 *      the middle — a real 1px gradient border, which `border-image` cannot do
 *      with rounded corners. This is the thing that reads as expensive: a card
 *      FILLED with a gradient looks cheap, a card OUTLINED in one does not.
 *   2. A GLOW BLEEDING FROM ABOVE the top edge, as though the stone were lit
 *      from behind.
 *   3. A SPECULAR SWEEP across the upper third, at a slight angle. This is the
 *      single detail that turns a flat panel into something with a surface.
 *   4. The dark body underneath, so the colour never floods the card.
 *
 * The lift on hover is two pixels and a deeper shadow. Enough to say the card is
 * an object; not enough to be an animation.
 */
.tier {
  position: relative;
  display: flex;
  flex-direction: column;
  background:
    linear-gradient(160deg, var(--tier-soft), transparent 42%),
    linear-gradient(to bottom, #0e1a16, var(--bg-card) 40%);
  transition:
    transform 220ms cubic-bezier(0.2, 0, 0, 1),
    box-shadow 220ms ease;
}

/*
 * The stroke. `mask-composite: exclude` keeps only the ring: the gradient is
 * painted over the whole rounded rectangle and then the inside is subtracted,
 * leaving a hairline that follows the corners exactly.
 */
.tier::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(to bottom, var(--tier-color), var(--tier-soft) 45%, transparent 85%);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
  z-index: 1;
}

/* The specular sweep, and the glow above the top edge. */
.tier::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background:
    linear-gradient(104deg, transparent 18%, #ffffff0a 34%, transparent 52%),
    radial-gradient(120% 60% at 50% -12%, var(--tier-glow), transparent 62%);
  opacity: 0.85;
  pointer-events: none;
}

@media (hover: hover) {
  .tier:hover {
    transform: translateY(-2px);
    box-shadow:
      inset 0 1px 0 #ffffff14,
      0 2px 8px rgb(0 0 0 / 0.55),
      0 28px 60px -28px var(--tier-glow);
  }
}

.tier .card__title {
  background: linear-gradient(to bottom, var(--tier-soft), transparent);
  border-radius: var(--radius) var(--radius) 0 0;
}

/*
 * Cards in the grid are the height of the tallest one, so the "Also included"
 * box has to be pushed to the bottom (`margin-top: auto` on it) — which needs
 * the content column to actually fill the card. Without this the box floats
 * halfway up three cards out of four and the row of them looks broken.
 */
.tier .card__content {
  flex: 1;
}

/*
 * The rail: a short bar of tier colour along the top edge, fading out to the
 * right. It is what makes the colour readable at a glance from across the grid,
 * where a dot beside a name is not.
 *
 * `::after` because `::before` is already the card's gradient ring.
 */
.tier::after {
  content: '';
  position: absolute;
  top: 0;
  left: var(--radius);
  right: var(--radius);
  height: 2px;
  border-radius: 0 0 2px 2px;
  background: linear-gradient(to right, var(--tier-color), transparent 85%);
  pointer-events: none;
}

.tier__name {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
}

/*
 * The dot. A small disc of tier colour with its own halo — the halo is what
 * stops it reading as a bullet point and starts it reading as a status light.
 */
.tier__dot {
  width: 0.5rem;
  height: 0.5rem;
  flex: none;
  border-radius: 50%;
  background: var(--tier-color, var(--accent));
  box-shadow: 0 0 0 3px var(--tier-soft, var(--accent-soft));
}

.tier__dot--lg {
  width: 0.625rem;
  height: 0.625rem;
  box-shadow:
    0 0 0 4px var(--tier-soft, var(--accent-soft)),
    0 0 12px var(--tier-glow, transparent);
}

/* The "Your tier" pill, in the colour of the tier it is pinned to. */
.badge--tier {
  background: var(--tier-soft, var(--accent-soft));
  color: var(--tier-color, var(--accent));
  border: 1px solid var(--tier-glow, transparent);
}

.tier__tagline {
  margin: 0;
  min-height: 2.6rem;
  display: flex;
  align-items: flex-start;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--tier-color, var(--accent));
}

/* On one column there is nothing to line up with, so the space is just waste. */
@media (max-width: 52rem) {
  .tier__tagline {
    min-height: 0;
  }
}

/*
 * SERVER / EXECUTION / LATENCY — the three rows that make the tiers a ladder.
 *
 * Same three labels, same order, on every card, so the comparison is read down
 * a column. The value is the only bright thing in the row and it carries the
 * tier's colour: at a glance the four cards are "Standard, Fast, Very fast,
 * Ultra-fast" in four different hues, which is the whole point of the page.
 *
 * The block sits on its own inset surface so it reads as the specification and
 * not as more body text.
 */
.tierspec {
  margin: 0;
  padding: 0.25rem 0.75rem;
  list-style: none;
  border-radius: 0.7rem;
  background: linear-gradient(to bottom, #00000038, #00000014);
  box-shadow: inset 0 0 0 1px #ffffff0d;
}

.tierspec__row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.55rem;
  padding: 0.5rem 0;
}

.tierspec__row + .tierspec__row {
  border-top: 1px solid #ffffff0f;
}

.tierspec__icon {
  color: var(--fg-muted);
  opacity: 0.85;
}

.tierspec__label {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--fg-muted);
}

.tierspec__value {
  font-size: 0.875rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  text-align: right;
  color: var(--tier-color, var(--fg));
}

/*
 * "Also included" — the outlined box.
 *
 * Outlined rather than listed loose because the things in it are a different
 * kind of claim from the rows above: those are what the tier IS, these are what
 * else comes with it. A box says "and on top of that" without a word spent
 * saying it.
 */
.tierextras {
  margin-top: auto;
  padding: 0.8rem 0.9rem 0.85rem;
  border-radius: 0.7rem;
  background: linear-gradient(to bottom, var(--tier-soft), transparent);
  box-shadow: inset 0 0 0 1px var(--tier-glow);
}

.tierextras__title {
  margin: 0 0 0.5rem;
  font-size: 0.625rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--tier-color, var(--accent));
}

.tierextras__list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.35rem;
}

.tierextras__list li {
  position: relative;
  padding-left: 1.1rem;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--fg);
}

.tierextras__list li::before {
  content: '+';
  position: absolute;
  left: 0;
  top: -0.02em;
  font-weight: 700;
  color: var(--tier-color, var(--accent));
}

/*
 * The worked example: the one line on a tier card that turns two abstractions
 * into a number. Set apart so the eye lands on it after the rows, not before.
 */
.tier__example {
  margin: 0.875rem 0 0;
  padding: 0.7rem 0.85rem;
  border-radius: 0.55rem;
  background: var(--surface-2, rgba(255, 255, 255, 0.04));
  font-size: 0.875rem;
  line-height: 1.5;
}

.tier__perks {
  margin: 0.875rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.4rem;
}

.tier__perks li {
  position: relative;
  padding-left: 1.35rem;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--fg-muted);
}

.tier__perks li::before {
  /* A tick, drawn in text rather than loaded as an icon. */
  content: '✓';
  position: absolute;
  left: 0;
  color: var(--tier-color, var(--accent));
  font-weight: 700;
}

.tier__perks--wide li {
  font-size: 0.9375rem;
  color: inherit;
}

/* A heading inside a card, for grouping tables under it. */
.card__subtitle {
  margin: 1.5rem 0 0.5rem;
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-muted);
}

/* ---------------------------------------------------------------- icons -- */

/*
 * Line icons, from views/icons.js. `currentColor` means an icon is the colour
 * of the text beside it, so nothing here needs to know about the palette.
 *
 * `flex: none` because an icon inside a flex row must never be squeezed into an
 * oval when the text beside it is long.
 */
.icon {
  width: 1.25rem;
  height: 1.25rem;
  flex: none;
  /* Nudged up: at this size an icon aligned on the baseline reads as sagging. */
  vertical-align: -0.18em;
}

.icon--sm {
  width: 1rem;
  height: 1rem;
}

.icon--lg {
  width: 1.5rem;
  height: 1.5rem;
}

/*
 * An icon in a tinted disc: for the one thing a panel is about, at the top of
 * it. Used sparingly — a page where everything is emphasised has nothing
 * emphasised.
 */
.iconbox {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  flex: none;
  border-radius: 0.7rem;
  background: var(--accent-soft);
  color: var(--accent-bright);
}

.iconbox--muted {
  background: #ffffff0d;
  color: var(--fg-muted);
}

.iconbox--ok {
  background: var(--ok-soft);
  color: var(--ok);
}

.iconbox--danger {
  background: var(--danger-soft);
  color: var(--danger);
}

/* --------------------------------------------------------- gradient edge -- */

/*
 * A hairline brighter at the top than the bottom, as though lit from above.
 *
 * CSS has no gradient border, so this is the standard trick: a pseudo-element
 * one pixel larger than the box, filled with the gradient, then masked so only
 * the outermost pixel shows. `mask-composite: exclude` punches the inside out
 * of the outside, leaving a ring.
 *
 * Worth the trouble because it is the whole difference between a panel that
 * looks made and a div with `border: 1px solid grey`. Where masking is not
 * supported the element simply keeps its ordinary border and nothing breaks.
 */
.edge {
  position: relative;
}

.edge::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: var(--edge-gradient);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

.edge--accent::before {
  background: var(--edge-gradient-accent);
}

/* ------------------------------------------------------------ money tiles -- */

/*
 * An amount with its own surface.
 *
 * The layout this replaced put three figures on one line among their labels and
 * hints, all at the same size — so the numbers, the only reason anybody opens
 * the page, carried no more weight than the words explaining them.
 */
.moneytiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}

.moneytile {
  position: relative;
  padding: 1.1rem 1.25rem 1.15rem;
  border-radius: var(--radius);
  background: var(--bg-card);
  box-shadow:
    inset 0 1px 0 #ffffff0f,
    var(--shadow-card);
}

.moneytile__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  margin-bottom: 0.7rem;
  border-radius: 0.6rem;
  background: #ffffff0d;
  color: var(--fg-muted);
}

.moneytile__label {
  margin: 0 0 0.3rem;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--fg-muted);
}

/*
 * `tabular-nums` so the digits sit in fixed columns: three tiles side by side
 * can then be compared by eye without the decimal points wandering.
 */
.moneytile__value {
  margin: 0;
  font-size: 1.75rem;
  font-weight: 650;
  letter-spacing: -0.025em;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.moneytile__hint {
  margin: 0.45rem 0 0;
  font-size: 0.75rem;
  line-height: 1.4;
  color: var(--fg-subtle);
}

/* The one that is earning. */
.moneytile--accent {
  background: linear-gradient(to bottom, var(--accent-wash), var(--bg-card) 60%);
}

.moneytile--accent .moneytile__icon {
  background: var(--accent-soft);
  color: var(--accent-bright);
}

.moneytile--accent .moneytile__value {
  color: var(--accent-bright);
}

/* Money in flight: worth noticing, not worth alarm. */
.moneytile--muted .moneytile__icon {
  background: var(--warning-soft);
  color: var(--warning);
}

/* Zero, and nothing to say about it. */
.moneytile--quiet .moneytile__value {
  color: var(--fg-muted);
}

/* ----------------------------------------------------------- how it works -- */

/*
 * The explainer page. Reachable signed out, so it is the first thing a lot of
 * people will see — but it is a page of arithmetic, not a landing page, and it
 * is set like one.
 */
.how {
  display: grid;
  gap: 1rem;
  max-width: 52rem;
  margin: 0 auto;
}

.how__title {
  margin: 0 0 0.4rem;
  font-size: 1.75rem;
  font-weight: 650;
  letter-spacing: -0.03em;
}

.how__subtitle {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--fg-muted);
}

/* Signed in, the top bar carries the page name and this sentence stands alone. */
.how__header--lede .how__subtitle {
  font-size: 1rem;
  color: #b6c1bb;
}

/*
 * The five steps, numbered down the left. The order is the part people get
 * wrong — particularly that the payout is at a fixed hour rather than 24 hours
 * after they started.
 */
.how__steps {
  display: grid;
  gap: 0.6rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.how__step {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.9rem;
  align-items: start;
  padding: 0.95rem 1.1rem;
  border-radius: var(--radius);
  background: linear-gradient(to bottom, #ffffff0d, #ffffff05);
  box-shadow: inset 0 0 0 1px var(--line);
}

.how__stepnum {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.7rem;
  height: 1.7rem;
  flex: none;
  border-radius: 50%;
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px #0093fd3d;
  color: var(--accent-bright);
  font-size: 0.8125rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.how__steptitle {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0.15rem 0 0.35rem;
  font-size: 0.9375rem;
  font-weight: 650;
}

.how__stepicon {
  color: var(--fg-muted);
  opacity: 0.8;
}

.how__steptext {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--fg-muted);
}

.how__cardhead {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.how__cardhead .icon {
  color: var(--fg-muted);
  opacity: 0.85;
}

.how__lead {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.6;
}

.how__points {
  display: grid;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.how__points li {
  position: relative;
  padding-left: 1.15rem;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--fg-muted);
}

.how__points li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 0.35rem;
  height: 0.35rem;
  border-radius: 50%;
  background: var(--accent);
}

/*
 * The worked sum. "Commission on profit" is a phrase people have read on sites
 * that then charged them on the balance; four lines of arithmetic they can
 * check is a different kind of statement.
 */
.how__sum {
  padding: 0.9rem 1rem;
  border-radius: 0.7rem;
  background: var(--bg-input);
  box-shadow: inset 0 0 0 1px var(--line);
}

.how__sumtitle {
  margin: 0 0 0.6rem;
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--fg-muted);
}

.how__sumrows {
  margin: 0;
  display: grid;
  gap: 0.4rem;
}

.how__sumrow {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.875rem;
}

.how__sumrow dt {
  color: var(--fg-muted);
}

.how__sumrow dd {
  margin: 0;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.how__sumrow--total {
  margin-top: 0.15rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--line);
}

.how__sumrow--total dt {
  color: var(--fg);
  font-weight: 600;
}

.how__note,
.how__more {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--fg-muted);
}

.how__more a {
  color: var(--accent-bright);
}

@media (max-width: 34rem) {
  .how__step {
    grid-template-columns: 1fr;
    gap: 0.5rem;
  }
}

/* ------------------------------------------------------------ coin marks -- */

/*
 * Drawn coin logos, from views/coins.js. Filled shapes, unlike the stroked
 * interface icons: a logo is an object and an icon is a symbol, and drawing
 * them the same way makes both look wrong.
 */
.coin {
  width: 1.5rem;
  height: 1.5rem;
  flex: none;
  vertical-align: -0.3em;
}

.coin--sm {
  width: 1.15rem;
  height: 1.15rem;
}

/* --------------------------------------------------------- legacy marks -- */

/*
 * A lettered disc in the project's colour. See `coinMark` in pages/wallet.js
 * for why these are drawn rather than loaded.
 */
.coinmark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  /*
   * The token's colour at low opacity with the glyph at full strength, rather
   * than a solid disc. Six saturated circles in a row shout; six tinted ones
   * sit inside the interface and still say which coin is which.
   */
  background: color-mix(in srgb, var(--mark, #64748b) 18%, transparent);
  color: var(--mark, #64748b);
  border: 1px solid color-mix(in srgb, var(--mark, #64748b) 35%, transparent);
  font-size: 0.875rem;
  font-weight: 700;
  line-height: 1;
  padding-bottom: 0.05em;
}

/* The bridged token: same colour, visibly the lesser of the two. */
.coinmark--muted {
  background: transparent;
  color: var(--mark, #64748b);
  border: 2px solid var(--mark, #64748b);
}

/*
 * WHAT YOU CAN SEND: THE COIN IS THE HEADLINE, THE NETWORK IS THE CAPTION.
 *
 * The layout this replaced led each row with the chain's own coin logo and the
 * chain's name in the heaviest type on the panel, with USDT and USDC as small
 * chips beside it. The owner read it the way it was drawn — "it looks like I
 * can send BNB" — and that reading was correct: the three loudest words on a
 * deposit page named three coins that are NOT accepted.
 *
 * Now the tickers are the largest type here and carry their real logos; the
 * chain is a small muted caption underneath, prefixed with the word "Network"
 * and drawn with the line network glyph. A coin logo beside a chain name is
 * exactly what caused the confusion, so the chain no longer has one.
 */
/*
 * The two coins, then the three networks.
 *
 * This was one card per network, each repeating the same pair of coins. Three
 * identical pairs said nothing the first said, and cost a moment of working out
 * that only the caption underneath was changing. The coins are the same
 * everywhere, so they are stated once and the chains listed under them.
 */
.sendcoins {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.4rem;
}

.sendcoins--big {
  gap: 0.6rem 1.75rem;
  margin: 0.9rem 0 0.9rem;
  padding: 0.85rem 0.95rem;
  border-radius: 0.8rem;
  background: linear-gradient(to bottom, #ffffff0d, #ffffff05);
  box-shadow: inset 0 0 0 1px var(--line);
}

.sendnets__caption {
  margin: 0 0 0.4rem;
  font-size: 0.625rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--fg-muted);
}

.sendnets {
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.6rem;
}

/* The object on this panel. Nothing here is bigger than the ticker. */
.sendcoin {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.sendcoin__mark {
  width: 1.9rem;
  height: 1.9rem;
}

.sendcoin__ticker {
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

/*
 * The caption. Deliberately quiet, deliberately prefixed: "Network · Polygon"
 * cannot be read as a thing to send, where "Polygon" on its own can.
 */
/* One chip per chain, sitting in a row rather than each on its own line. */
.sendnet {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  padding: 0.35rem 0.6rem;
  border-radius: 999px;
  background: #ffffff0a;
  box-shadow: inset 0 0 0 1px var(--line);
  font-size: 0.8125rem;
  color: var(--fg-muted);
}

/*
 * The chain's own logo, at caption size. Small on purpose: the coins above it
 * are drawn at 1.9rem, and the gap between the two sizes is what says which of
 * them is the thing being sent.
 */
.sendnet__mark {
  width: 1.15rem;
  height: 1.15rem;
}

.sendnet__caption {
  font-size: 0.625rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  opacity: 0.75;
}

.sendnet__name {
  font-weight: 600;
  color: var(--fg);
}

/* Pinned right on a wide row, and simply last in the flow on a narrow one. */
.sendnet__time {
  margin-left: auto;
  white-space: nowrap;
}

@media (max-width: 34rem) {
  .sendnet__time {
    margin-left: 0;
    flex-basis: 100%;
  }
}

/* ------------------------------------------------------ the console, tight -- */

/*
 * THE OPERATIONS CONSOLE IS A DENSE SCREEN, AND THE SITE'S SPACING IS NOT.
 *
 * The user-facing pages are read once, slowly, by somebody deciding whether to
 * part with money — generous padding is doing a job there. The console is read
 * fifty times a day by one person looking for a number they already know the
 * name of, and every row of blank pixels between them and it is a row they have
 * to scroll past. The owner's words: half an hour of scrolling through menus.
 *
 * SO IT IS SCOPED, not global. Everything here hangs off `.shell--admin`, which
 * only the console renders. The same `card`, `table` and `stat` components keep
 * their roomy metrics everywhere else — one set of components, two densities,
 * and no second stylesheet to keep in step.
 *
 * WHAT IS NOT SHRUNK: font sizes stay legible, tap targets on buttons stay
 * pressable, and the rules between rows stay. Density that costs readability
 * has moved the problem rather than solved it — what goes is padding, gap and
 * margin, which are the whole of the complaint.
 */
.shell--admin .content {
  gap: 0.5rem;
  padding: 0.7rem 0.9rem 1.2rem;
  /* Wider, too: on a console screen the table is the point, and 72rem was
     leaving columns to wrap while the window had room to spare. */
  max-width: 88rem;
}

/*
 * SECOND PASS ON HEIGHT. The first one took the padding out of the components;
 * what was left was the furniture between them — page headers with a paragraph
 * under every title, filter bars, totals strips, the space above and below every
 * heading. On a console read fifty times a day that furniture is most of the
 * scrolling, so it is compressed here and the components are left alone.
 */
.shell--admin .pagehead,
.shell--admin .page-header {
  margin: 0;
}

.shell--admin .pagehead__title,
.shell--admin .page-header__title,
.shell--admin h2 {
  margin: 0 0 0.15rem;
  font-size: 1.0625rem;
}

.shell--admin .pagehead__description,
.shell--admin .page-header__description {
  margin: 0;
  font-size: 0.8125rem;
}

.shell--admin .filters {
  gap: 0.5rem;
  padding: 0.5rem 0.7rem;
}

.shell--admin .totalsbar {
  gap: 0.75rem;
  padding: 0.45rem 0.7rem;
  font-size: 0.8125rem;
}

.shell--admin .grid {
  gap: 0.5rem;
}

.shell--admin .person {
  padding: 0.5rem 0.7rem;
}

.shell--admin .person-row__body {
  padding: 0.5rem 0.7rem 0.7rem;
}

.shell--admin .thread__item {
  padding: 0.6rem 0.7rem;
}

.shell--admin .rowactions {
  gap: 0.3rem;
}

/* A callout in the console is a line of text, not a poster. */
.shell--admin .callout__title {
  margin-bottom: 0.1rem;
  font-size: 0.8125rem;
}

.shell--admin .callout__body {
  font-size: 0.8125rem;
}

.shell--admin .prose {
  line-height: 1.45;
}

.shell--admin .stat__hint,
.shell--admin .field__hint {
  line-height: 1.35;
}

.shell--admin .topbar {
  padding: 0.55rem 1.05rem;
}

.shell--admin .topbar__title {
  font-size: 1rem;
}

.shell--admin .card__title {
  padding: 0.55rem 0.85rem;
  font-size: 0.9375rem;
}

.shell--admin .card__content {
  gap: 0.7rem;
  padding: 0.75rem 0.85rem;
}

.shell--admin .card__footer {
  gap: 0.5rem;
  padding: 0.55rem 0.85rem;
}

/* The row height of the console. Six-tenths of what it was, and the number is
   still on its own line with air above and below it. */
.shell--admin .table th,
.shell--admin .table td {
  padding: 0.35rem 0.85rem;
}

.shell--admin .empty {
  padding: 1rem 0.85rem;
}

.shell--admin .stats {
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 0.5rem;
}

.shell--admin .stat {
  padding: 0.6rem 0.75rem;
}

.shell--admin .stat__label {
  margin-bottom: 0.15rem;
  font-size: 0.6875rem;
}

.shell--admin .stat__value {
  font-size: 1.25rem;
}

.shell--admin .stat__hint {
  margin-top: 0.15rem;
}

.shell--admin .data-row {
  padding-block: 0.35rem;
}

.shell--admin .starts-note {
  margin: 0.35rem 0 0.6rem;
  color: var(--fg-muted);
  font-size: 0.75rem;
  line-height: 1.4;
}

.shell--admin .callout {
  padding: 0.6rem 0.75rem;
}

.shell--admin .tabs__tab {
  padding: 0.5rem 0.85rem;
  font-size: 0.875rem;
}

.shell--admin .prose {
  font-size: 0.8125rem;
}

/* The sidebar scrolls too when the section list is long. */
.shell--admin .sidebar {
  gap: 0.9rem;
  padding: 0.85rem;
}

.shell--admin .sidebar__link {
  padding: 0.35rem 0.6rem;
  font-size: 0.875rem;
  /* The count goes to the right edge; the label keeps the left. */
  justify-content: space-between;
}

/*
 * How many things in that section are waiting for a person.
 *
 * Amber and filled rather than a plain number: at 11px a bare digit beside a
 * word reads as part of the word. Absent at zero — a column of grey noughts is
 * precisely what a real count has to compete with.
 */
.sidebar__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 0.35rem;
  border-radius: 999px;
  background: #f59e0b26;
  box-shadow: inset 0 0 0 1px #f59e0b59;
  color: #fbbf24;
  font-size: 0.6875rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

/* On the section you are already looking at it is a label, not an alarm. */
.sidebar__link--active .sidebar__count {
  background: #ffffff14;
  box-shadow: inset 0 0 0 1px #ffffff26;
  color: var(--fg);
}

.shell--admin .form {
  gap: 0.6rem;
}

.shell--admin .field {
  gap: 0.25rem;
}

.shell--admin .field__input {
  padding: 0.4rem 0.6rem;
}

.shell--admin .button {
  padding: 0.45rem 0.85rem;
}

/* ------------------------------------------------------ sweeps in flight -- */

/*
 * What the sweeper is doing right now, one block per transfer.
 *
 * The console used to show a status word and nothing else, so "funding" for
 * three minutes was indistinguishable from "stuck". Four steps, ticked as they
 * complete, answers the question the word was standing in for.
 */
.sweepnow {
  display: grid;
  gap: 0.5rem;
}

.sweepnow__item {
  padding: 0.6rem 0.7rem;
  border-radius: 0.6rem;
  background: #ffffff08;
  box-shadow: inset 0 0 0 1px var(--line);
}

.sweepnow__item--failed {
  background: var(--danger-soft);
  box-shadow: inset 0 0 0 1px #f2555a3d;
}

.sweepnow__head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.25rem 0.5rem;
  margin: 0 0 0.4rem;
  font-size: 0.8125rem;
}

.sweepnow__what {
  font-weight: 650;
}

.sweepnow__where,
.sweepnow__who {
  color: var(--fg-muted);
  font-size: 0.75rem;
}

.sweepnow__amount {
  margin-left: auto;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

.sweepnow__steps {
  display: grid;
  gap: 0.15rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.sweepnow__step {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.75rem;
  color: var(--fg-muted);
  opacity: 0.55;
}

.sweepnow__mark {
  width: 0.9rem;
  text-align: center;
}

/* Done: full strength, and the tick is the accent colour. */
.sweepnow__step--done {
  opacity: 1;
}

.sweepnow__step--done .sweepnow__mark {
  color: var(--accent-bright);
}

/* Working: full strength and amber, so exactly one line draws the eye. */
.sweepnow__step--active {
  opacity: 1;
  color: var(--fg);
}

.sweepnow__step--active .sweepnow__mark {
  color: #fbbf24;
}

.sweepnow__state {
  margin-left: auto;
  font-size: 0.6875rem;
  letter-spacing: 0.02em;
}

.sweepnow__state--wait {
  color: #fbbf24;
}

.sweepnow__error {
  margin: 0;
  font-size: 0.75rem;
  color: var(--danger);
  overflow-wrap: anywhere;
}

.sweepnow__links {
  display: flex;
  gap: 0.75rem;
  margin: 0.4rem 0 0;
  font-size: 0.6875rem;
}

.sweepnow__links a {
  color: var(--accent-bright);
}

/* --------------------------------------------------- sweep, by account -- */

/*
 * The per-account sweep buttons, under the one that sweeps everybody.
 *
 * Separated by a rule and a caption rather than sitting in the same row: these
 * act on one person's money and the button above acts on everyone's, and two
 * buttons of the same weight side by side is how the wrong one gets pressed.
 */
.sweepaccounts {
  margin-top: 1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--line);
}

.sweepaccounts__caption {
  margin: 0 0 0.6rem;
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--fg-muted);
}

.sweepaccounts__list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* The form is plumbing; only the button inside it should occupy space. */
.sweepaccounts__form {
  margin: 0;
}

/*
 * The per-coin breakdown, folded away.
 *
 * The account list answers the question that gets asked; this answers the one
 * asked when something looks wrong. Open it and the old table is there,
 * per-coin buttons and all.
 */
.sweepdetail__summary {
  padding: 0.55rem 0.85rem;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--fg-muted);
  cursor: pointer;
}

.sweepdetail__summary:hover {
  color: var(--fg);
}

.sweepdetail[open] .sweepdetail__summary {
  border-bottom: 1px solid var(--border);
}

/* ------------------------------------------------------- withdraw picker -- */

/*
 * Coin and network on the withdraw form, chosen from what is on screen.
 *
 * They were two `<select>`s sharing a `.form__row` with the amount. That row is
 * a two-column grid, so the third control dropped onto its own line under a
 * half-width neighbour, and the amount's hint pushed the two menus out of line
 * with the input beside them — the whole block read as broken.
 *
 * Radios instead: two coins and three networks is a small enough set to draw in
 * full, a menu hides half the answer behind a tap, and a `<select>` has nowhere
 * to put the coin's own mark. The form posts the same `coin` and `network`
 * fields as before and needs no script.
 */
.pick {
  display: flex;
  flex-direction: column;
  gap: 0.4375rem;
  margin: 0;
  padding: 0;
  border: 0;
}

.pick__legend {
  padding: 0;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--fg-muted);
}

.pick__options {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
  gap: 0.5rem;
}

.pick__option {
  display: block;
  cursor: pointer;
}

/* Off-screen but still focusable — the focus ring is drawn on the face. */
.pick__input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.pick__face {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
  transition:
    border-color 120ms ease,
    background-color 120ms ease;
}

.pick__option:hover .pick__face {
  border-color: var(--accent);
}

.pick__input:checked + .pick__face {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.pick__input:focus-visible + .pick__face {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.pick__mark {
  width: 1.5rem;
  height: 1.5rem;
}

.pick__name {
  font-weight: 650;
  font-size: 0.9375rem;
}

/* A chain's name is longer than a ticker and is not the object being chosen. */
.pick__name--net {
  font-weight: 600;
  font-size: 0.875rem;
}

/* ------------------------------------------------------------- deposit -- */

/*
 * The deposit panel: a QR code beside the address it encodes.
 *
 * It collapses to one column below 40rem rather than shrinking, because a QR
 * code that has been scaled down stops scanning — and on a phone the QR is the
 * only part of this screen anybody uses.
 */
.deposit {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  align-items: flex-start;
}

.deposit__qr {
  /* White regardless of theme. A QR inverted for a dark background is not
     reliably readable: many scanners assume dark-on-light and give up. */
  background: #fff;
  padding: 0.75rem;
  border-radius: 0.75rem;
  line-height: 0;
  flex: 0 0 auto;
}

.deposit__qr svg {
  display: block;
  width: 10.5rem;
  height: auto;
}

.deposit__detail {
  flex: 1 1 16rem;
  min-width: 0;
}

/*
 * The address itself.
 *
 * `break-all` rather than a scrollbar or an ellipsis: every character has to be
 * visible at once so somebody comparing it against their wallet can do so
 * without scrolling, and a truncated address is one people paste incomplete.
 */
.deposit__address {
  font-size: 1.0625rem;
  line-height: 1.5;
  word-break: break-all;
  user-select: all;
  margin: 0.35rem 0 0.85rem;
  padding: 0.7rem 0.85rem;
  border-radius: 0.6rem;
  background: var(--surface-2, rgba(255, 255, 255, 0.04));
  border: 1px solid var(--border, rgba(255, 255, 255, 0.09));
}

@media (max-width: 40rem) {
  .deposit {
    flex-direction: column;
    align-items: center;
    text-align: center;
  }

  .deposit__detail {
    width: 100%;
  }

  .deposit__address {
    text-align: left;
  }
}

/* ============================================================ leaderboard == */

/*
 * The 24-hour board on the dashboard.
 *
 * A LIST WITH A GRID ON IT, not a table. Three columns — place, wallet, amount —
 * and the whole thing reflows to two lines on a narrow screen by changing the
 * template, where a table would have needed the card-per-row breakpoint the
 * console uses. For three columns that machinery costs more than it returns.
 */
/*
 * COMPACT ON PURPOSE. Ten rows at the comfortable spacing the rest of the site
 * uses is most of a phone screen for information nobody acts on — so the row is
 * tightened to about 1.6rem, the card's own padding is pulled in, and the note
 * underneath is set small. Everything else on the dashboard keeps its air; this
 * is the one panel that is read at a glance and scrolled past.
 */
.lb-card .card__title {
  padding: 0.75rem 1rem;
  font-size: 0.95rem;
}

.lb-card .card__content {
  gap: 0.5rem;
  padding: 0.5rem 0.75rem 0.75rem;
}

.lb {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
}

.lb__row {
  display: grid;
  grid-template-columns: 1.5rem minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.6rem;
  padding: 0.22rem 0.45rem;
  border-radius: 0.45rem;
  font-size: 0.85rem;
}

/* Zebra at two per cent, which is enough to follow a row across and not enough
   to read as a second surface. */
.lb__row:nth-child(odd) {
  background: rgb(255 255 255 / 0.022);
}

.lb__row--you {
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent-soft);
}

.lb__rank {
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  text-align: center;
  color: var(--fg-muted);
  font-size: 0.8rem;
}

/*
 * The first three places get a colour and the rest do not. Medals without
 * pictures of medals — and first place shares its champagne with the highest
 * tier, so the two places in the product that mean "the top" say it in the same
 * voice rather than in two unrelated yellows.
 */
.lb__rank--1 {
  color: var(--prestige);
}

.lb__rank--2 {
  color: #c3ccc7;
}

.lb__rank--3 {
  color: #b98a5e;
}

.lb__who {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  min-width: 0;
}

.lb__addr {
  font-size: 0.82rem;
  letter-spacing: 0.02em;
}

/*
 * The dots standing in for the rest of the address.
 *
 * They are the visible half of a rule enforced in `data/leaderboard.js`: nothing
 * past the first six characters ever reaches this page, so a row cannot be
 * looked up in an explorer. The dots say so without a footnote.
 */
.lb__mask {
  color: var(--fg-subtle);
  letter-spacing: 0.06em;
  font-size: 0.7rem;
  overflow: hidden;
}

.lb__me {
  flex: 0 0 auto;
}

.lb__amount {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.lb__coin {
  width: 1rem;
  height: 1rem;
  flex: 0 0 auto;
}

.lb__value {
  font-weight: 600;
}

.lb__unit {
  color: var(--fg-muted);
  font-size: 0.7rem;
  letter-spacing: 0.04em;
}

.lb__mine {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin: 0.75rem 0 0;
  padding-top: 0.75rem;
  border-top: 1px solid var(--line);
  color: var(--fg-muted);
  font-size: 0.85rem;
}

.lb__mineamount {
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 34rem) {
  .lb__row {
    grid-template-columns: 1.5rem minmax(0, 1fr);
    row-gap: 0.15rem;
  }

  /* The amount drops under the wallet rather than shrinking the wallet: the
     figure is the thing being compared down the column. */
  .lb__amount {
    grid-column: 2;
  }

  .lb__unit {
    display: none;
  }
}

/* ============================================================= calculator == */

.calc__form {
  margin: 0.5rem 0 0;
}

.calc__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

.calc__label {
  color: var(--fg-muted);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.calc__amount {
  font-size: 1.75rem;
  font-weight: 650;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

/*
 * The slider.
 *
 * `accent-color` does the whole job in every current browser; the thumb rules
 * below are only there to make the target big enough for a finger, which the
 * default is not. Both vendor forms are needed and neither can be combined into
 * one selector — an unknown pseudo-element invalidates the whole rule.
 */
.calc__slider {
  width: 100%;
  margin: 0.75rem 0 0.25rem;
  accent-color: var(--accent);
  background: transparent;
}

.calc__slider::-webkit-slider-thumb {
  width: 1.4rem;
  height: 1.4rem;
}

.calc__slider::-moz-range-thumb {
  width: 1.4rem;
  height: 1.4rem;
}

.calc__scale {
  display: flex;
  justify-content: space-between;
  margin: 0;
  color: var(--fg-subtle);
  font-size: 0.72rem;
}

.calc__go {
  margin-top: 0.75rem;
}

.calc__result {
  margin-top: 1.1rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
}

.calc__tier {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.04);
  border: 1px solid var(--line);
}

.calc__tiername {
  font-weight: 600;
}

.calc__tierrate {
  color: var(--fg-muted);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}

.calc__netlabel {
  margin: 0.9rem 0 0;
  color: var(--fg-muted);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.calc__net {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0.15rem 0 0;
}

.calc__netvalue {
  font-size: 2.4rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--ok);
  font-variant-numeric: tabular-nums;
}

.calc__netunit {
  color: var(--fg-muted);
  font-size: 0.85rem;
  letter-spacing: 0.04em;
}

.calc__range {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0.35rem 0 1rem;
  font-size: 0.85rem;
}

.calc__rangepair {
  display: inline-flex;
  gap: 0.35rem;
  font-variant-numeric: tabular-nums;
}

.calc__rangenote {
  color: var(--fg-muted);
}

@media (max-width: 34rem) {
  .calc__netvalue {
    font-size: 1.9rem;
  }

  .calc__amount {
    font-size: 1.4rem;
  }
}

/* ======================================================== support, as chat == */

/*
 * THE CONSOLE'S SUPPORT SECTION, LAID OUT LIKE A MESSENGER.
 *
 * Two columns on a desktop: conversations, and the open one. One column on a
 * phone, where the list and the thread are two screens and `.tg--thread` decides
 * which of them is showing — the same markup either way, so there is no second
 * template that can drift.
 *
 * The height is pinned to the viewport rather than left to the content, because
 * a chat scrolls in its own pane. Without it the page scrolls, the composer ends
 * up below the fold, and answering a long thread means scrolling to the bottom
 * of the browser window every time.
 */
.tg {
  display: grid;
  grid-template-columns: minmax(15rem, 21rem) minmax(0, 1fr);
  gap: 1rem;
  height: calc(100vh - 9rem);
  min-height: 30rem;
}

.tg__list,
.tg__thread {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.tg__listhead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.9rem 1rem;
  border-bottom: 1px solid var(--line);
}

.tg__listtitle {
  font-weight: 650;
}

.tg__waiting {
  color: var(--danger);
  font-size: 0.78rem;
}

.tg__clear {
  color: var(--fg-subtle);
  font-size: 0.78rem;
}

.tg__chats {
  list-style: none;
  margin: 0;
  padding: 0.35rem;
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 0;
}

.tg__empty {
  margin: 0;
  padding: 1.5rem 1rem;
  color: var(--fg-muted);
  text-align: center;
}

.tg__chat {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.7rem;
  padding: 0.6rem 0.65rem;
  border-radius: 0.7rem;
  color: inherit;
  text-decoration: none;
}

.tg__chat:hover {
  background: rgb(255 255 255 / 0.04);
}

.tg__chat--active {
  background: var(--accent-soft);
}

.tg__chat--closed {
  opacity: 0.6;
}

.tg__chatbody {
  min-width: 0;
}

.tg__chattop {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}

.tg__name {
  font-weight: 600;
  font-size: 0.9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tg__time {
  color: var(--fg-subtle);
  font-size: 0.72rem;
  flex: 0 0 auto;
}

.tg__subject {
  display: block;
  font-size: 0.8rem;
  color: var(--fg-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Two lines of the last message, and no more: a preview that grows with the
   message turns the list into a transcript. */
.tg__preview {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 0.8rem;
  color: var(--fg-subtle);
}

.tg__prefix {
  color: var(--fg-muted);
}

.tg__chat--unread .tg__name,
.tg__chat--attention .tg__name {
  color: var(--fg);
}

.tg__chat--unread .tg__preview,
.tg__chat--attention .tg__preview {
  color: var(--fg-muted);
}

.tg__dot {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 999px;
  background: var(--danger);
  flex: 0 0 auto;
}

/* --- the avatar --- */

.tg__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 999px;
  font-weight: 650;
  color: #0d1116;
  flex: 0 0 auto;
}

.tg__avatar--head {
  width: 2.1rem;
  height: 2.1rem;
  font-size: 0.9rem;
}

.tg__avatar--1 {
  background: #4aa8ff;
}

.tg__avatar--2 {
  background: #5ec98a;
}

.tg__avatar--3 {
  background: #f0a63c;
}

.tg__avatar--4 {
  background: #d47ce0;
}

.tg__avatar--5 {
  background: #e97b7b;
}

.tg__avatar--6 {
  background: #56c8c8;
}

/* --- the thread --- */

.tg__head {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
}

.tg__back {
  display: none;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 999px;
  color: var(--fg-muted);
  text-decoration: none;
  flex: 0 0 auto;
}

.tg__headwho {
  min-width: 0;
  flex: 1 1 auto;
}

.tg__headname {
  margin: 0;
  font-weight: 650;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tg__headmeta {
  margin: 0;
  font-size: 0.75rem;
  color: var(--fg-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tg__headactions {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex: 0 0 auto;
}

.tg__headactions form {
  margin: 0;
}

.tg__notice {
  padding: 0.75rem 0.9rem 0;
}

.tg__msgs {
  list-style: none;
  margin: 0;
  padding: 1rem 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 0;
}

.tg__msg {
  display: flex;
}

.tg__msg--out {
  justify-content: flex-end;
}

.tg__bubble {
  max-width: min(42rem, 82%);
  padding: 0.55rem 0.75rem;
  border-radius: 1rem;
  background: var(--bg-raised);
  border: 1px solid var(--line);
}

/* Ours is tinted and its corner is square on the side it came from, which is
   the entire visual grammar of a chat and needs no legend. */
.tg__msg--in .tg__bubble {
  border-bottom-left-radius: 0.3rem;
}

.tg__msg--out .tg__bubble {
  background: var(--accent-wash);
  border-color: var(--accent-soft);
  border-bottom-right-radius: 0.3rem;
}

.tg__author {
  margin: 0 0 0.15rem;
  font-size: 0.72rem;
  font-weight: 650;
  color: var(--accent-bright);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* `pre-wrap`, so a message typed with line breaks arrives with them. The old
   thread collapsed every paragraph into one. */
.tg__text {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.tg__stamp {
  display: block;
  margin-top: 0.2rem;
  text-align: right;
  font-size: 0.68rem;
  color: var(--fg-subtle);
}

.tg__closed {
  margin: 0;
  padding: 0.9rem;
  border-top: 1px solid var(--line);
  color: var(--fg-muted);
  text-align: center;
  flex: 0 0 auto;
}

.tg__composer {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.5rem;
  padding: 0.7rem 0.9rem 0.8rem;
  border-top: 1px solid var(--line);
  flex: 0 0 auto;
}

.tg__input {
  width: 100%;
  resize: vertical;
  min-height: 2.75rem;
  padding: 0.6rem 0.75rem;
  border-radius: 0.8rem;
  border: 1px solid var(--line-strong);
  background: var(--bg-input);
  color: var(--fg);
  font: inherit;
}

.tg__send {
  align-self: end;
}

/*
 * The attachment control.
 *
 * A LABEL WITH THE REAL INPUT INSIDE IT. The input is taken out of the layout
 * rather than hidden with `display: none` — a display-none input cannot be
 * focused, so the control would vanish for anyone using a keyboard. Clipped to a
 * pixel keeps it focusable and lets the focus ring land on the label.
 */
.tg__clip {
  grid-column: 1;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  justify-self: start;
  padding: 0.25rem 0.5rem;
  border-radius: 0.5rem;
  color: var(--fg-muted);
  font-size: 0.8rem;
  cursor: pointer;
}

.tg__clip:hover {
  color: var(--fg);
  background: rgb(255 255 255 / 0.04);
}

.tg__file {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.tg__clip:focus-within {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.tg__clipnames {
  grid-column: 2;
  align-self: center;
  font-size: 0.75rem;
  color: var(--fg-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tg__rule {
  grid-column: 1 / -1;
  margin: 0;
  font-size: 0.72rem;
  color: var(--fg-subtle);
}

.tg__thread--none {
  align-items: center;
  justify-content: center;
}

.tg__placeholder {
  max-width: 26rem;
  padding: 2rem;
  text-align: center;
}

.tg__placeholdertitle {
  margin: 0 0 0.4rem;
  font-weight: 650;
}

.tg__placeholderbody {
  margin: 0 0 1rem;
  color: var(--fg-muted);
}

.tg__placeholderrule {
  margin: 0;
  font-size: 0.8rem;
  color: var(--fg-subtle);
}

/*
 * One column, two screens.
 *
 * With a conversation open the list is where you came from, so it goes away and
 * the back arrow appears. With none open the placeholder pane would be a screen
 * of nothing under the list, so that goes away instead.
 */
@media (max-width: 62rem) {
  .tg {
    grid-template-columns: minmax(0, 1fr);
    height: auto;
    min-height: 0;
  }

  .tg--thread .tg__list {
    display: none;
  }

  .tg:not(.tg--thread) .tg__thread--none {
    display: none;
  }

  .tg__back {
    display: inline-flex;
  }

  .tg__msgs {
    max-height: 70vh;
  }

  .tg__headactions .button {
    padding-left: 0.55rem;
    padding-right: 0.55rem;
  }
}

/* ============================================================= danger zone == */

/*
 * The card holding the one control that destroys something.
 *
 * Outlined in red at the bottom of an account page, away from everything else,
 * because it must never be the thing a hand lands on while reaching for
 * something adjacent.
 */
.danger-zone {
  border-color: var(--danger-soft);
}

.danger-zone .card__title {
  color: var(--danger);
}

/* ================================================================ telegram == */

/*
 * The Telegram button.
 *
 * Their blue, not ours, and that is the point: it is the one control on the page
 * that leads somewhere else, and a button in the site's own accent would read as
 * one more of ours. #2AABEE is Telegram's published brand colour.
 */
.button--tg {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  background: #2aabee;
  border: 1px solid #2aabee;
  color: #06121b;
  font-weight: 600;
}

.button--tg:hover {
  background: #34b6f7;
  border-color: #34b6f7;
}

.tglogin {
  margin-top: 1.25rem;
}

/* A rule with the word "or" sitting in it, rather than a bare divider. */
.tglogin__or {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0 0 0.9rem;
  color: var(--fg-subtle);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.tglogin__or::before,
.tglogin__or::after {
  content: '';
  flex: 1 1 auto;
  height: 1px;
  background: var(--line);
}

.tglogin__hint {
  margin-top: 0.6rem;
  text-align: center;
}

.tglink {
  margin-top: 0.5rem;
}

.tg__meta {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.4rem;
}

.tg__meta .tg__stamp { margin-top: 0; }

.tg__delete { position: relative; }

.tg__delete summary {
  list-style: none;
  cursor: pointer;
  color: var(--fg-subtle);
  font-size: 0.68rem;
  line-height: 1.2;
  padding: 0.2rem 0.35rem;
  border-radius: 0.4rem;
}

.tg__delete summary::-webkit-details-marker { display: none; }
.tg__delete summary:hover, .tg__delete[open] summary { background: var(--bg-raised); color: var(--fg); }
.tg__delete form { position: absolute; z-index: 5; right: 0; top: 100%; min-width: 10rem; }
.tg__delete button {
  width: 100%;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--line);
  border-radius: 0.55rem;
  background: var(--bg-raised);
  color: var(--danger, #e88989);
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0 0.5rem 1.5rem #0008;
}

/* A link inside a settings row, not a primary page action. Keep Telegram's
   colour while removing the oversized phone target imposed on main actions. */
.tglink .button--tg {
  min-height: 2rem;
  padding: 0.34rem 0.8rem;
  font-size: 0.76rem;
  line-height: 1.1;
}

#two-factor {
  scroll-margin-top: 5rem;
}

.settings-totp-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.45rem;
}

.settings-totp-actions .button {
  min-width: 7rem;
}

/* The Telegram column in the console: an identity, not a sentence. */
.tgcell {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.social__head {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.social__mark {
  color: #2aabee;
}

.social__list {
  margin: 0.75rem 0 0;
  padding-left: 1.1rem;
  color: var(--fg-muted);
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.socials__url {
  margin: 0.5rem 0 0;
  padding: 0.55rem 0.7rem;
  border-radius: 0.6rem;
  background: var(--bg-input);
  border: 1px solid var(--line);
  overflow-wrap: anywhere;
}

.socials__fix {
  display: inline-block;
  margin-top: 0.5rem;
}

/*
 * THE LEADERBOARD IS NOT SHOWN INSIDE TELEGRAM.
 *
 * The owner's call and the right one: a table of other people's daily earnings
 * is the first thing read as a performance claim, and inside Telegram the app
 * sits next to advertising rules that forbid exactly that. It stays on the
 * website, where it is one panel at the foot of a page full of qualifications.
 *
 * Hidden rather than not rendered, because the server cannot know which client
 * is asking — the same URL is served to both. The rows are invented figures with
 * no personal data in them, so there is nothing sensitive sitting in the markup.
 */
body.is-telegram .lb-card {
  display: none;
}

/*
 * The block of qualifications under the tier cards.
 *
 * Bordered and quiet rather than a red alert: it is a permanent statement about
 * every number on the page, not a warning about something that went wrong, and a
 * page that shouts constantly is a page nobody reads.
 */
.risknote {
  margin-top: 0.5rem;
  padding: 1rem 1.15rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgb(255 255 255 / 0.02);
}

.risknote__title {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0 0 0.6rem;
  font-weight: 650;
  color: var(--warning);
}

.risknote__list {
  margin: 0;
  padding-left: 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  color: var(--fg-muted);
  font-size: 0.88rem;
}

.risknote__more {
  margin: 0.75rem 0 0;
  font-size: 0.82rem;
}

.calc__notguaranteed {
  color: var(--fg);
}

/* --------------------------------------------------- the first-run screen -- */

.page-start .start {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  padding: 1rem;
}

.start__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0.25rem 1rem;
}

.start__hello {
  margin: 0;
  color: var(--fg-muted);
}

/*
 * A COLUMN, NOT A ROW.
 *
 * This was `display: flex` with the default `row` direction, which was fine while
 * the screen held one card. The moment a second card appeared — registration and
 * sign-in, side by side — a 393-pixel phone put them in two columns about 170
 * pixels wide each, with "Sign in and connect Telegram" wrapped over three
 * lines. Nothing overflowed, so nothing complained; it was simply unusable.
 */
.start__body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}

.start__card {
  width: min(34rem, 100%);
}

/* The three risks. Marks are amber and aligned, so the list reads as a set of
   warnings rather than as features. */
.start__risks {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.start__risks li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0.6rem;
  align-items: start;
  font-size: 0.92rem;
}

.start__risk-mark {
  color: var(--warning);
  line-height: 1;
  padding-top: 0.15rem;
}

.start__existing {
  margin-top: 1.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}

.start__existingtitle {
  margin: 0 0 0.25rem;
  font-weight: 650;
}

/* ------------------------------------------------- the single-panel view -- */

/*
 * Where a hand-off link lands: one panel, centred, nothing around it.
 *
 * No sidebar, no tabs, no other sections — somebody pressed a button meaning
 * "show me my deposit address on a proper screen" and that is all this shows.
 * One link at the bottom for anybody who wants the rest of the site.
 */
.page-focus .focus {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  padding: 1rem;
}

.focus__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0.25rem 1rem;
}

.focus__what {
  color: var(--fg-muted);
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.focus__body {
  flex: 1 1 auto;
  width: min(38rem, 100%);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.focus__foot {
  margin: 0.5rem 0 0;
  text-align: center;
  font-size: 0.85rem;
}

/* ------------------------------------------------- the language picker --- */

/*
 * A dropdown built from `<details>`, so each row can carry a drawn flag and the
 * language's own name — neither of which a native `<select>` can hold.
 *
 * The open and close behaviour is the browser's own. Nothing here is a script.
 */
.langmenu {
  position: relative;
}

.langmenu__button {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  color: var(--fg);
  font-size: 0.85rem;
  cursor: pointer;
  user-select: none;
  /* The default triangle is replaced by the caret in the markup, which sits
     after the name rather than before the flag. */
  list-style: none;
}

.langmenu__button::-webkit-details-marker {
  display: none;
}

.langmenu__button:hover {
  border-color: var(--line-strong);
}

.langmenu__caret {
  color: var(--fg-muted);
  font-size: 0.7rem;
}

.langmenu__flag {
  display: block;
  border-radius: 2px;
  flex: 0 0 auto;
}

.langmenu__list {
  position: absolute;
  right: 0;
  z-index: 40;
  margin: 0.35rem 0 0;
  padding: 0.3rem;
  min-width: 11rem;
  max-height: min(70vh, 420px);
  overflow-y: auto;
  list-style: none;
  background: var(--bg-card);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-raised);
}

.langmenu__item {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  /* A row tall enough for a finger. */
  padding: 0.55rem 0.6rem;
  border-radius: 0.45rem;
  color: var(--fg);
  text-decoration: none;
  font-size: 0.9rem;
}

.langmenu__item:hover {
  background: rgb(255 255 255 / 0.05);
}

/* The language you are already reading, marked by more than colour. */
.langmenu__item--current {
  background: var(--accent-soft);
  font-weight: 600;
}

/* The hand-off button: a row on its own, above the wallet tabs. */
.handoff {
  margin: 0 0 1rem;
}

.handoff .field__hint {
  margin-top: 0.35rem;
}

.bc__count {
  margin: 0.25rem 0 0.35rem;
  font-weight: 600;
}

.bc-recipient-toggle {
  display: inline-block;
  margin: 0 0 0.7rem;
  color: var(--accent-bright);
  cursor: pointer;
  font-size: 0.86rem;
  text-decoration: underline;
  text-underline-offset: 0.2rem;
}

.bc-recipient-scroll {
  max-height: 22rem;
  overflow: auto;
  margin-bottom: 0.4rem;
  border: 1px solid var(--line);
  border-radius: 0.75rem;
}


/* A card that is asking for attention without being an error. */
.card--warn {
  border-color: var(--warning-soft);
}

/*
 * BOTH CARDS ON THE SOCIALS PAGE, EVERYWHERE.
 *
 * They used to be shown one at a time — Telegram on the website, the website
 * inside Telegram — and the owner was right that it is wrong: a mixed audience
 * needs both addresses in both places, and hiding one from somebody who came
 * looking for it is the opposite of what the page is for.
 *
 * The order is the same in both, and deliberately not reversed by client: an
 * `order` flip only works inside a flex container, and making the page one just
 * to move a card would be a layout change in service of a preference. Two cards
 * on a short page are both visible at once anyway.
 */
.social-pair + .social-pair {
  margin-top: 1rem;
}

.social-pair,
.social {
  min-width: 0;
  width: 100%;
}

.social__head {
  display: flex;
  align-items: center;
  gap: 0.65rem;
}

.social__mark {
  flex: 0 0 auto;
  width: 1.15rem;
  height: 1.15rem;
  color: #2aabee;
}

.social__actions {
  display: flex;
  align-items: stretch;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.social__actions .button {
  flex: 1 1 7rem;
  min-width: 0;
  max-width: 14rem;
  text-align: center;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* `onlytg` survives for anything that genuinely belongs to one client only. */
.onlytg {
  display: none;
}

body.is-telegram .onlytg {
  display: block;
}

/*
 * And its opposite, for a sentence that is only true in a browser.
 *
 * The pair exists because the server cannot tell the two apart on a GET: the
 * signed Telegram payload lives in the client and reaches the page after it has
 * been rendered. Writing both and letting the class decide is the only way the
 * page can be right in a Mini App without a round trip.
 */
body.is-telegram .notg {
  display: none;
}

/* ------------------------------------------------------- the mini app shell */

/*
 * INSIDE TELEGRAM THE APP IS NOT A WEBSITE, and two things go.
 *
 * The legal footer belongs to a browser — a column of links at the bottom of a
 * sheet somebody swipes is dead space, and the documents are linked from the
 * screens that matter. The cookie banner goes because there is no third-party
 * context to disclose: it is the same session cookie, inside an app the person
 * opened on purpose.
 *
 * THE LANGUAGE PICKER STAYED, and it was a mistake to hide it. The reasoning was
 * "Telegram already knows the language" — true for the language the CLIENT is
 * in, and useless to somebody whose phone is in one language and who wants to
 * read in another. Taking away a control because it is usually unnecessary is
 * how a product becomes unusable for the minority who need it, and that minority
 * here is anybody with a mixed audience.
 *
 * The floating support button stays too: it is the one thing somebody in trouble
 * looks for, and a phone is where they will be looking.
 */
body.is-telegram .site-footer,
body.is-telegram .cookie-banner {
  display: none;
}

/*
 * The safe areas.
 *
 * `--tg-safe-*` are written by `tg.js` from the values Telegram reports, and
 * they are what keeps the top bar out from under a notch and the bottom of the
 * page off the home indicator. The fallbacks are zero, so a device with neither
 * is unaffected and a browser outside Telegram never sees any of this.
 */
body.is-telegram {
  padding-top: calc(var(--tg-safe-top, 0px) + var(--tg-content-top, 0px));
  padding-bottom: var(--tg-safe-bottom, 0px);
  padding-left: var(--tg-safe-left, 0px);
  padding-right: var(--tg-safe-right, 0px);
}

/*
 * Telegram's viewport is not the window: it changes as the sheet is dragged and
 * as the keyboard opens. `--tg-viewport-stable-height` is the settled figure and
 * is what a full-height pane should follow — the unstable one makes the layout
 * jump while a finger is still moving.
 */
body.is-telegram .shell {
  min-height: var(--tg-viewport-stable-height, 100vh);
}

/*
 * The sidebar becomes a bottom bar inside Telegram.
 *
 * A left rail is a desktop shape. In a phone-sized sheet with the client's own
 * header above it, the navigation belongs where a thumb is — and Telegram's back
 * button handles going backwards, so this only has to handle going somewhere.
 */
@media (max-width: 60rem) {
  body.is-telegram .sidebar__foot,
  body.is-telegram .sidebar__group-label,
  body.is-telegram .sidebar__head {
    display: none;
  }
}

/*
 * THE TELEGRAM OPENING SPLASH.
 *
 * Two moments, one look. `html.tg-early` is set by tg-boot.js in the head, before
 * the body paints, on the page that auto-forwards into Telegram (it carries
 * data-tg-signin) — so the web sign-in form is hidden from the very first frame
 * rather than flashing and being swapped. `is-telegram-signing-in` is set by
 * tg.js while the signed identity is on its way up. Both show the same quiet
 * splash: the brand mark at the top (it lives outside .auth__body and stays) and
 * a spinner in the middle. On a slow connection this is what a person waits on,
 * instead of a form they were never meant to fill in.
 *
 * `:has()` is how the early rule is scoped to the sign-in page only; a client too
 * old to support it simply shows the form as before — no worse than today.
 */
html.tg-early body:has([data-tg-signin]) .auth__form-column,
html.tg-early body:has([data-tg-signin]) .auth__aside,
body.is-telegram-signing-in .auth__form-column,
body.is-telegram-signing-in .auth__aside {
  visibility: hidden;
  pointer-events: none;
}

html.tg-early body:has([data-tg-signin]) .auth__body::after,
body.is-telegram-signing-in .auth__body::after {
  content: '';
  position: fixed;
  inset: 0;
  margin: auto;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 999px;
  border: 3px solid var(--accent-soft);
  border-top-color: var(--accent);
  animation: tgspin 0.8s linear infinite;
}

@keyframes tgspin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }

  /*
   * The view-transition pseudo-elements are not descendants of anything, so the
   * universal selector above never reaches them. Named separately, or the page
   * would still cross-fade for somebody who asked it not to.
   */
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation-duration: 0.01ms !important;
  }

  /* A pressed control still has to look pressed; it just does not move. */
  .sidebar__link:active,
  .pager__step:active,
  .pager__page:active,
  .tabs__link:active {
    transform: none;
  }
}

/* ================================================== tiers and calculator, 2026-08-26 == */

/*
 * A THIRD DENSITY PASS, ON THE TWO BLOCKS THE OWNER NAMED: the tier grid and the
 * calculator. Both were described the same way — huge, unordered, too much
 * nothing between things — and both were, for two different reasons.
 *
 * WHY THIS SITS AT THE END OF THE FILE AND NOT IN THE DENSITY SECTION ABOVE.
 * That section overrides by coming later, which works only for components
 * defined before it. `.tier*` is defined at ~5600 and `.calc*` at ~7300, both
 * AFTER it — so its `.tierspec__row { padding: 0.28rem 0 }` has been dead the
 * whole time, silently beaten by the original at 5860. Same specificity, later
 * wins. Putting these at the end is the only placement that cannot be undone by
 * a rule further down, because there is no further down.
 */

/*
 * THE HOLE IN THE MIDDLE OF THREE CARDS OUT OF FOUR.
 *
 * `.tierextras` was pinned with `margin-top: auto` so the "Also included" boxes
 * would line up across the row. In a stretched grid that means the shortest
 * cards absorb the whole difference as one gap in their middle — which is
 * exactly what the owner was looking at. The intent was sound and the result was
 * not: a void between two blocks reads as a rendering fault, while the same void
 * at the bottom of a card reads as nothing at all.
 *
 * Unpinned. The boxes no longer align, the content is continuous, and the slack
 * moves to the bottom edge where the eye never goes looking.
 */
.tierextras {
  margin-top: 0.7rem;
  padding: 0.65rem 0.75rem 0.7rem;
}

.tierextras__list {
  gap: 0.25rem;
}

.tierextras__list li {
  line-height: 1.4;
}

/* The dead override from the density section, applied where it actually lands. */
.tierspec__row {
  padding: 0.34rem 0;
}

.tierspec {
  padding: 0.15rem 0.65rem;
}

/*
 * The tagline reserved 2.6rem so four cards would start their spec block on the
 * same line. Three of the four taglines are one line, so most of that height was
 * reserved for nothing. Two lines' worth is enough to keep the alignment that
 * was worth having.
 */
.tier__tagline {
  min-height: 2.2rem;
  font-size: 0.9rem;
}

.tier__example {
  margin: 0.6rem 0 0;
  padding: 0.55rem 0.7rem;
  font-size: 0.85rem;
  line-height: 1.45;
}

.tier .card__content {
  gap: 0.55rem;
}

.tier .data-row {
  padding-block: 0.28rem;
}

.tier-grid .tier .card__title {
  min-height: 3.25rem;
  display: flex;
  align-items: center;
}

.tier-grid .tier__head {
  width: 100%;
}

/* The compact copy is held to the same three-line rail on a four-card row. */
.tier-grid .tier__tagline {
  min-height: 3.65rem;
}

/* Make the three specification glyphs part of the tier colour system. */
.tier-grid .tierspec__icon {
  width: 0.86rem;
  height: 0.86rem;
  box-sizing: content-box;
  padding: 0.18rem;
  border: 1px solid var(--tier-soft);
  border-radius: 0.35rem;
  color: var(--tier-color);
  background: var(--tier-soft);
  opacity: 1;
}

/*
 * Financial rows use an explicit label/value grid. This prevents the label
 * from wrapping while a wide amount leaves unused room beside it.
 */
.tier-grid .tier .data-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: 0.35rem;
}

.tier-grid .tier .data-row__label > span:first-child {
  white-space: nowrap;
  font-size: 0.78rem;
}

.tier-grid .tier .data-row__hint {
  line-height: 1.3;
}

/* All four examples finish on the same baseline and occupy the same box. */
.tier-grid .tier__example {
  min-height: 4.45rem;
  margin-top: auto;
  display: flex;
  align-items: center;
}

@media (max-width: 67.999rem) {
  .tier-grid .tier__tagline {
    min-height: 2.8rem;
  }
}

@media (max-width: 44.999rem) {
  .tier-grid .tier .card__title,
  .tier-grid .tier__tagline,
  .tier-grid .tier__example {
    min-height: 0;
  }

  .tier-grid .tier__example {
    margin-top: 0.6rem;
  }
}

/*
 * FOUR CARDS GO FOUR-ACROSS SOONER.
 *
 * The four-column breakpoint was 78rem, so a laptop at 1280 CSS pixels — the
 * commonest desktop width there is — got two columns of two, which is the layout
 * the owner called unordered. It is: a ladder of four rungs shown as a square
 * stops being a ladder. The cards fit at 68rem once the padding above came down.
 */
@media (min-width: 68rem) {
  .tier-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* ---------- the dashboard tier card, now on its own ---------- */

/*
 * It lost its paragraph and its neighbour, so it is one line of content in a
 * full-width card. Left alone it would be a band of empty card with a name
 * floating at the left. The name grows into the space instead.
 */
.tier--bare .card__content {
  padding-block: 0.7rem;
}

.tier--bare .tier-now {
  margin: 0;
  font-size: 1.5rem;
}

/* ---------- calculator ---------- */

.calc__result {
  margin-top: 0.85rem;
  padding-top: 0.85rem;
}

.calc__netlabel {
  margin-top: 0.7rem;
}

.calc__range {
  margin-bottom: 0.75rem;
}

/*
 * TWO TILES INSTEAD OF FIVE LABELLED ROWS.
 *
 * Side by side rather than stacked, because they are the same kind of thing
 * measured over two horizons and the comparison is the point. `1fr 1fr` and not
 * `auto-fit`: with two items auto-fit collapses to one column at a width where
 * two still fit comfortably, and a single tile in a row looks like something
 * failed to load.
 */
.calc__tiles {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
}

.calc__tile {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.6rem 0.75rem;
  border-radius: 0.6rem;
  background: rgb(255 255 255 / 0.035);
  box-shadow: inset 0 0 0 1px var(--line);
}

.calc__tilelabel {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-muted);
}

.calc__tilevalue {
  font-size: 1.15rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}

/*
 * The two tiles stack only on a genuinely narrow screen.
 *
 * THE FIRST ATTEMPT PUT THIS AT 26rem AND WAS WRONG. 26rem is 416px, which
 * stacks every phone in existence — an iPhone 14 is 393 — so the change meant to
 * save vertical space spent it instead, on the devices where vertical space is
 * the scarce thing. Caught by screenshotting at 393 rather than by reading the
 * number and thinking it sounded small.
 *
 * 22rem is 352px: below every mainstream phone (360 is the narrowest common
 * Android) and above the folded Galaxy Fold at 280, where two columns of
 * eight-character figures genuinely do not fit.
 */
@media (max-width: 22rem) {
  .calc__tiles {
    grid-template-columns: 1fr;
  }
}

/* ---------- the two blocks that moved into the FAQ ---------- */

/*
 * A list under an answer. It carries the four qualifications that used to sit
 * under the tier grid, and the six-step table.
 *
 * Dimmer and a step smaller than the answer above it: this is the detail behind
 * an answer somebody has already read, not a second answer competing with it.
 */
.faq__points {
  margin: 0.6rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.4rem;
}

.faq__points li {
  position: relative;
  padding-left: 1rem;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--fg-muted);
}

.faq__points li::before {
  content: '—';
  position: absolute;
  left: 0;
  color: var(--fg-subtle);
}

/* The links out. No dash: it is not one of the points, it is where they lead. */
.faq__points-more {
  padding-left: 0;
  margin-top: 0.15rem;
}

.faq__points-more::before {
  content: none;
}

/*
 * The table inside an answer. A `<details>` body is narrower than a card, and
 * this table has a prose column, so on a phone it has to be allowed to scroll
 * inside itself rather than push the page sideways.
 */
.faq__answer .table-wrap,
.faq__answer table {
  margin-top: 0.6rem;
}

/* ==================================================== lime + premium pass, 2026-08-26 == */

/*
 * A WHOLE-SITE RESKIN, DONE AT THE TOKEN LAYER ON PURPOSE.
 *
 * Every surface in this stylesheet is built from the same handful of primitives
 * — `.card`, `.button`, `.data-row`, `.badge` — and every colour in it comes
 * from a custom property. So the way to change how the site LOOKS is to change
 * what those mean, not to visit ninety selectors. One block, and it reaches the
 * desktop, the phone and the Telegram Mini App at once, because all three are
 * the same pages.
 *
 * WHAT THE OWNER ASKED FOR: the lime green from their reference, outlines with
 * some craft in them, and a premium feel overall.
 *
 * WHAT THE OLD PALETTE ARGUED, AND WHY IT IS BEING OVERRULED. The note at the
 * top of this file says a saturated green filling a large area is what makes a
 * finance product look like a trading bot, and that deep emerald should do the
 * filling while mint is rationed to small marks. That reasoning is sound and it
 * is not wrong now — it just assumed WHITE text on the fill. A light lime with
 * near-black text is a different object: the ink carries the contrast, the green
 * carries the identity, and the result reads closer to a bank card than to a
 * neon button. That is the whole trick, and it is why `--accent-ink` exists
 * below rather than a lighter shade of white.
 */

:root {
  /*
   * Neutrals, one step deeper and one step cleaner.
   *
   * The green cast in the old charcoal was there to agree with an emerald
   * accent. Lime is a warmer, lighter green, and the same cast under it reads as
   * a colour mistake rather than as a tint. These are near-neutral with the
   * faintest warmth, which is what stops a black interface looking like a hole.
   */
  --bg: #0a0b09;
  --bg-raised: #101210;
  --bg-card: #141613;
  --bg-input: #0c0e0b;

  /*
   * Hairlines, slightly stronger than before.
   *
   * The old ones were honest but timid: at #ffffff14 a card edge disappears on
   * anything but a good monitor in a dark room. An outline that cannot be seen
   * is not restraint, it is an absent outline.
   */
  --line: #ffffff1c;
  --line-strong: #ffffff2e;
  --border: var(--line);
  --border-strong: var(--line-strong);

  --fg: #edf0e8;
  --fg-muted: #949a8c;
  --fg-subtle: #949a8c66;

  /* ---- the lime family ---- */

  --accent: #b1e76a;
  --accent-hover: #c2f083;
  --accent-deep: #93cc4c;
  --accent-bright: #c8f58f;
  --accent-tint: #e6f8cd;
  --accent-soft: #b1e76a1f;
  --accent-wash: #151a0e;

  /*
   * THE INK THAT GOES ON TOP OF THE LIME, and the reason this reskin works.
   *
   * #b1e76a has a relative luminance around 0.72. White on it is roughly 1.3:1 —
   * illegible, and the exact mistake that makes a neon button look cheap: the
   * label fights the fill instead of sitting on it. Near-black gives about 14:1
   * and turns the same green into a surface rather than a light.
   *
   * Not pure #000: a true black edge against a saturated colour buzzes. #131313
   * is what the owner's reference uses, and it is right.
   */
  --accent-ink: #131313;

  --ok: var(--accent-bright);
  --ok-soft: var(--accent-soft);

  /*
   * Rank and prestige, re-tuned against the new accent.
   *
   * Violet next to emerald was a clean split. Next to lime it turns muddy, so
   * the rank hue moves toward periwinkle — further from the accent in hue, and
   * cooler, so the ladder still reads as a different KIND of thing from money.
   * Prestige loses its yellow: brass beside lime is two yellows arguing, and
   * warm silver holds the "top of the ladder" meaning without competing.
   */
  --rank: #8d90f2;
  --rank-bright: #b3b5ff;
  --rank-deep: #6b6ed8;
  --rank-soft: #8d90f21f;

  --prestige: #d8d2c0;

  /* Radii open up. A larger corner is the cheapest premium signal there is. */
  --radius: 18px;
  --radius-sm: 12px;
  --radius-lg: 24px;

  /*
   * Shadow in two parts: a tight contact shadow that sits the object on the
   * page, and a wide soft one that gives it air. One shadow can do either but
   * not both, and a single mid-blur is what makes a card look printed on.
   */
  --shadow-card: 0 1px 2px rgb(0 0 0 / 0.55), 0 20px 48px -28px rgb(0 0 0 / 0.9);
  --shadow-raised: 0 2px 10px rgb(0 0 0 / 0.6), 0 36px 72px -32px rgb(0 0 0 / 0.95);

  /*
   * TELLS THE BROWSER THIS PAGE IS DARK, and it is one line for a lot.
   *
   * Everything the operating system draws rather than the stylesheet — select
   * popups, scrollbars, the date picker, form autofill, the caret — is rendered
   * light by default, because the browser assumes a light page unless told.
   * That is why an open dropdown appeared as a white panel on a black site.
   *
   * With this, all of them come up dark, and the rules below only have to agree
   * with what the platform is already doing rather than fight it.
   */
  color-scheme: dark;
}

/* ---------------------------------------------------------------- surfaces -- */

/*
 * THE OUTLINE THE OWNER POINTED AT.
 *
 * Three layers, and each does one job:
 *   1. a top highlight, brightest at the very top edge — this is what reads as
 *      a bevel and it is the difference between "a rectangle" and "an object";
 *   2. a full hairline ring, so the card has an edge on every side rather than
 *      only where it happens to meet a darker neighbour;
 *   3. the two-part drop shadow from the tokens.
 *
 * The card also stops being a flat fill. A barely-there vertical gradient — two
 * or three per cent — is what stops a large dark panel looking like a hole cut
 * in the page. It is not visible as a gradient; it is visible as depth.
 */
.card {
  border-radius: var(--radius);
  background: linear-gradient(to bottom, #ffffff08, transparent 40%), var(--bg-card);
  box-shadow:
    inset 0 1px 0 #ffffff24,
    inset 0 0 0 1px #ffffff12,
    var(--shadow-card);
}

/*
 * The card that matters most on a page gets the accent in its ring rather than
 * a wash across its whole body. A tinted panel says "this is different"; a
 * tinted EDGE says "this is the one" and leaves the content on the same surface
 * as everywhere else, which is what keeps figures comparable between cards.
 */
.card--highlighted {
  background: linear-gradient(to bottom, var(--accent-wash), var(--bg-card) 60%);
  box-shadow:
    inset 0 1px 0 #ffffff2b,
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 26%, transparent),
    0 1px 2px rgb(0 0 0 / 0.55),
    0 24px 60px -30px color-mix(in srgb, var(--accent) 22%, transparent),
    var(--shadow-card);
}

.card__title {
  padding: 1rem 1.35rem;
  letter-spacing: -0.015em;
}

/* ----------------------------------------------------------------- buttons -- */

/*
 * PILLS, EVERYWHERE.
 *
 * A fully round control is the single strongest shape cue in this reference and
 * it costs one line. It also fixes something the old radius did badly: at 10px
 * on a 40px-tall button the corner is neither square nor round, which is the
 * shape everything defaults to and therefore the shape that reads as default.
 */
.button {
  border-radius: 999px;
  padding: 0.7rem 1.35rem;
  letter-spacing: -0.005em;
}

/*
 * The primary: lime fill, black ink. The gradient runs light-to-deep over the
 * height so the top edge catches light and the bottom sits down — the same
 * logic as the card bevel, at button scale.
 *
 * The glow underneath is the accent at low alpha, not a grey shadow. A coloured
 * shadow under a coloured control is what makes it look lit rather than pasted.
 */
.button--primary {
  background: linear-gradient(to bottom, var(--accent-hover), var(--accent) 55%, var(--accent-deep));
  color: var(--accent-ink);
  font-weight: 650;
  box-shadow:
    inset 0 1px 0 #ffffff5c,
    inset 0 0 0 1px #00000014,
    0 1px 2px rgb(0 0 0 / 0.45),
    0 12px 30px -14px color-mix(in srgb, var(--accent) 55%, transparent);
}

.button--primary:hover {
  background: linear-gradient(to bottom, #cdf596, var(--accent-hover) 55%, var(--accent));
  box-shadow:
    inset 0 1px 0 #ffffff70,
    inset 0 0 0 1px #0000001a,
    0 1px 2px rgb(0 0 0 / 0.45),
    0 16px 38px -14px color-mix(in srgb, var(--accent) 65%, transparent);
}

.button--primary:active {
  background: linear-gradient(to bottom, var(--accent-deep), #7fb63d);
  box-shadow: inset 0 1px 4px rgb(0 0 0 / 0.35);
}

/*
 * The secondary, as an outline in the accent — the "Withdraw" button in the
 * reference. Ghost buttons were muted grey on grey, which is correct when they
 * are genuinely minor and wrong for the other half of a pair: a person choosing
 * between putting money in and taking it out is not choosing between a button
 * and an afterthought.
 *
 * Outline rather than fill keeps the hierarchy: same shape, same size, one is
 * filled and one is drawn.
 */
.button--ghost {
  border-color: color-mix(in srgb, var(--accent) 42%, transparent);
  color: var(--accent-bright);
  font-weight: 600;
  box-shadow: inset 0 1px 0 #ffffff0f;
}

.button--ghost:hover {
  border-color: color-mix(in srgb, var(--accent) 70%, transparent);
  color: var(--accent-tint);
  background: var(--accent-soft);
}

/* ------------------------------------------------------------------ inputs -- */

/*
 * Inputs get the inverse of the card bevel: the highlight goes at the BOTTOM
 * and the shadow inside the top edge, so the field reads as cut into the
 * surface rather than sitting on it. It is the oldest trick in interface
 * drawing and it still works.
 */
.input,
.field input,
.field select,
.field textarea,
.amount-input {
  border-radius: var(--radius-sm);
  background: var(--bg-input);
  box-shadow:
    inset 0 1px 2px rgb(0 0 0 / 0.5),
    inset 0 0 0 1px #ffffff12,
    inset 0 -1px 0 #ffffff0a;
}

.input:focus,
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  box-shadow:
    inset 0 1px 2px rgb(0 0 0 / 0.4),
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 55%, transparent),
    0 0 0 3px var(--accent-soft);
}

/* ------------------------------------------------------------------ badges -- */

/*
 * Badges become pills with a hairline of their own colour. A tint alone is a
 * smudge at this size; a tint inside a thin ring of the same hue is a chip.
 */
.badge {
  border-radius: 999px;
  padding: 0.2rem 0.65rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  box-shadow: inset 0 0 0 1px #ffffff14;
}

.badge--accent {
  background: var(--accent-soft);
  color: var(--accent-bright);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 34%, transparent);
}

/* ------------------------------------------------------- figures and rows -- */

/*
 * The money tiles carry the same edge treatment as the cards, one step quieter.
 * They sit INSIDE a card, so repeating the full ring would draw a box in a box;
 * a hairline and a top highlight is enough to separate them.
 */
.moneytile {
  border-radius: var(--radius-sm);
  background: linear-gradient(to bottom, #ffffff0a, transparent 45%), #ffffff05;
  box-shadow:
    inset 0 1px 0 #ffffff1a,
    inset 0 0 0 1px #ffffff0f;
}

/*
 * Numbers get their tracking tightened. Tabular figures are drawn on a fixed
 * advance, which at display sizes leaves them looking spaced out; a touch of
 * negative letter-spacing puts them back together without breaking alignment.
 */
.moneytile__value,
.stat__value,
.tier-now,
.calc__netvalue,
.calc__amount {
  letter-spacing: -0.025em;
}

.data-row {
  border-bottom: 1px solid #ffffff0a;
}

.data-row:last-child {
  border-bottom: none;
}

/* ------------------------------------------------------------------- shell -- */

/*
 * The active item in the sidebar was a filled block. Filled blocks in a
 * navigation column compete with the content for the eye, and there are eleven
 * of them down the left of every page. A quiet surface plus a lime rail on the
 * leading edge says the same thing and stops shouting it.
 */
.sidebar__link--active {
  position: relative;
  background: linear-gradient(to right, var(--accent-soft), transparent 70%);
  color: var(--fg);
  box-shadow: inset 0 0 0 1px #ffffff0f;
}

.sidebar__link--active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 20%;
  bottom: 20%;
  width: 2px;
  border-radius: 0 2px 2px 0;
  background: var(--accent);
  box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 70%, transparent);
}

/*
 * The top bar and the balance strip sit above the content, so they get the
 * raised surface rather than the card one, and a hairline underneath instead of
 * a shadow — a shadow there would fall across the first card on every page.
 */
.topbar,
.balancebar {
  background: linear-gradient(to bottom, #ffffff08, transparent 60%), var(--bg-raised);
  border-bottom: 1px solid var(--line);
}

/* --------------------------------------------------------------- the pager -- */

/* Black ink on lime here too — the same fill needs the same treatment. */
.pager__page--on {
  color: var(--accent-ink);
  background: var(--accent);
  box-shadow: inset 0 1px 0 #ffffff5c;
}

/* ----------------------------------------------------------------- tables -- */

/*
 * Table heads lose their bottom rule and gain a lighter one: at full strength a
 * horizontal line under a header competes with the card's own edge a few pixels
 * above it, and the eye reads two boxes.
 */
.table th {
  border-bottom-color: #ffffff14;
  letter-spacing: 0.05em;
}

.table tbody tr + tr td {
  border-top-color: #ffffff0a;
}

/* ------------------------------------------------- leftovers of the old hue -- */

/*
 * THREE PLACES STILL PAINTED THEMSELVES BLUE, and they were written before the
 * tokens covered everything: `#0093fd` is typed straight into the rules below.
 * A reskin done only at the token layer leaves exactly this kind of island, and
 * on the dashboard it was obvious — one teal tile sitting in a lime row.
 */
.balancebar__item--accent {
  background: linear-gradient(to bottom, var(--accent-soft), color-mix(in srgb, var(--accent) 6%, transparent));
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 28%, transparent),
    0 1px 2px rgb(0 0 0 / 0.3),
    0 8px 22px -12px color-mix(in srgb, var(--accent) 45%, transparent);
}

.balancebar__item--accent .icon {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  color: var(--accent-bright);
}

.tier {
  --tier-soft: var(--accent-soft);
  --tier-glow: color-mix(in srgb, var(--accent) 40%, transparent);
}

/*
 * THE LADDER, RE-ANCHORED.
 *
 * The idea it was built on still holds and is worth keeping: the hue TRAVELS as
 * the tiers climb, away from the brand colour, so a badge tells somebody their
 * standing without a word. Only the starting point moves. It began at emerald
 * because the brand was emerald; the brand is lime now, so the bottom rung is
 * lime and the journey runs lime → mint → periwinkle → warm metal.
 *
 * The top stays metal rather than violet, for the reason written where the old
 * ladder was defined: violet is what every competitor in this category already
 * uses, and arriving there says "the same as everyone else" at exactly the
 * moment the ladder is meant to say "the top".
 */
.tier--shared_node {
  --tier-color: #b1e76a;
  --tier-soft: #b1e76a1f;
  --tier-glow: #b1e76a55;
}

.tier--dedicated_node {
  --tier-color: #5fd3a0;
  --tier-soft: #5fd3a01f;
  --tier-glow: #5fd3a055;
}

.tier--priority_node {
  --tier-color: #8d90f2;
  --tier-soft: #8d90f21f;
  --tier-glow: #8d90f255;
}

.tier--private_cluster {
  --tier-color: var(--prestige);
  --tier-soft: #d8d2c01f;
  --tier-glow: #d8d2c055;
}

:root {
  --prestige-bright: #efeade;
  --prestige-soft: #d8d2c01f;
}

/* --------------------------------------------------------- the edge, again -- */

/*
 * The first pass at the ring was too polite. The owner asked for outlines you
 * can SEE, and #ffffff12 on a #141613 card is about two per cent of contrast —
 * technically an edge, visually nothing on a laptop screen in daylight.
 *
 * This is roughly double, plus a brighter top line. It is still a hairline: the
 * difference between "I can find the edge if I look" and "the card has a shape"
 * is smaller than people expect, and going further starts drawing boxes.
 */
.card {
  box-shadow:
    inset 0 1px 0 #ffffff30,
    inset 0 0 0 1px #ffffff1f,
    var(--shadow-card);
}

/*
 * A card lifts a little under the pointer. Not a transform — cards are not
 * buttons and should not appear pressable — just the edge catching more light,
 * which is what a real object does when you lean toward it.
 */
@media (hover: hover) {
  .card:hover {
    box-shadow:
      inset 0 1px 0 #ffffff3d,
      inset 0 0 0 1px #ffffff29,
      var(--shadow-card);
  }
}

.moneytile {
  box-shadow:
    inset 0 1px 0 #ffffff26,
    inset 0 0 0 1px #ffffff1a;
}

/*
 * The sections that are not cards — the risk callout, the console panels — get
 * the same ring, or they read as unfinished next to everything that does.
 */
.callout,
.tg__list,
.tg__thread,
.tierextras,
.tierspec,
.calc__tile,
.how__sum {
  box-shadow:
    inset 0 1px 0 #ffffff1c,
    inset 0 0 0 1px #ffffff14;
}

/* ============================================ deposit and withdraw sheets, 2026-08-26 == */

/*
 * THE TWO ACTIONS, AS A PAIR.
 *
 * Equal width on a phone so neither reads as the safer choice by being bigger;
 * natural width on a desktop, where a full-bleed pair of buttons looks like a
 * form rather than a toolbar.
 */
.walletactions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.6rem;
}

@media (min-width: 34rem) {
  /*
   * SIZED BY THE WORDS, AND EQUAL TO EACH OTHER.
   *
   * The pair had `min-width: 11rem` each — 176px for a label and a mark that
   * together measure about a hundred. So both buttons carried forty pixels of
   * empty pill on either side of their content, which is what read as out of
   * proportion: the shape was much larger than the thing inside it.
   *
   * `width: fit-content` on the row shrinks the grid to its content, and two
   * `1fr` columns inside that make both halves the width of the wider label.
   * Equal to each other matters more than either being a particular size: they
   * are one decision with two answers, and a wider Withdraw would quietly read
   * as the bigger option.
   */
  .walletactions {
    width: fit-content;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/*
 * The mark inside them, one step up and given room.
 *
 * At 0.85rem beside 0.9375rem text the arrow was thinner than the letters next
 * to it and sat a little high. Matching the cap height and adding a touch of
 * gap is the difference between a label with an icon and a label with a speck.
 */
.walletactions__go .icon {
  width: 1.05rem;
  height: 1.05rem;
  flex: none;
}

.walletactions__go {
  gap: 0.55rem;
  padding-inline: 1.4rem;
}

/* ------------------------------------------------------------------ sheets -- */

/*
 * A DIALOG THAT IS TWO THINGS DEPENDING ON HOW IT WAS OPENED.
 *
 * With the `open` attribute from the server it is an ordinary block in the page
 * — the panel the tab used to render, in the same place, looking the same. The
 * browser's default dialog styling has to be undone for that: it ships with a
 * border, a white background, `width: fit-content` and auto margins, all of
 * which are wrong for a panel.
 *
 * After `showModal()` the `:modal` pseudo-class matches and the same element
 * becomes an overlay. One set of markup, two presentations, and no second copy
 * of the most safety-critical forms on the site.
 */
.sheet {
  display: block;

  /*
   * POSITION FIRST, AND IT IS THE ONE THAT MATTERS.
   *
   * The user-agent stylesheet gives every dialog `position: absolute` along with
   * a border, white background, `width: fit-content` and auto margins. The first
   * version of this rule reset all of those EXCEPT the position — so the panel
   * the server renders open on the deposit tab was taken out of the flow and
   * drawn on top of the sidebar and the balance strip. The page looked broken,
   * and it was.
   *
   * `static` is what a block in the flow is. The overlay state sets `fixed`
   * for itself further down.
   */
  position: static;
  width: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  overflow: visible;
}

.sheet:not([open]) {
  display: none;
}

.sheet__body {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* ---- as an overlay ---- */

/*
 * SELECTED BY THE `[open]` ATTRIBUTE, NOT A CLASS. A `<dialog>` carries `open`
 * whether the server rendered it open (the deposit / withdraw tab) or app.js
 * raised it with showModal() — so this presentation applies in every case,
 * INCLUDING the webviews (a Telegram Mini App among them) where showModal did
 * not promote the dialog and the sheet was left drawn flat in the flow:
 * transparent, its header and close button hidden. showModal, when it works, now
 * only adds the focus trap; the look no longer depends on it.
 */
.sheet[open] {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: end center;
  width: 100vw;
  max-width: 100vw;
  height: 100dvh;
  margin: 0;
  /*
   * THE DIM IS ON THE ELEMENT, NOT ON ::backdrop. ::backdrop only paints for a
   * dialog actually in the top layer (showModal); an inline `<dialog open>` has
   * none, which is why the tab was see-through. The dialog element fills the
   * viewport and dims it itself, so it works either way — and in the modal case
   * this dim sits in front of the (now transparent) ::backdrop.
   */
  background: rgb(4 5 4 / 0.72);
  overflow: hidden;
}

@supports (backdrop-filter: blur(6px)) {
  .sheet[open] {
    backdrop-filter: blur(6px);
  }
}

@media (min-width: 40rem) {
  .sheet[open] {
    place-items: center;
  }
}

.sheet::backdrop {
  background: transparent;
}

/*
 * The panel itself. On a phone it rises from the bottom edge and keeps its top
 * corners round — the shape every mobile payment sheet uses, and the one that
 * says "this can be dismissed downward" without a word. On a desktop it is a
 * centred card.
 */
.sheet[open] .sheet__inner {
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
  overflow: hidden;
  width: min(34rem, 100%);
  max-height: 92dvh;
  background: linear-gradient(to bottom, #ffffff0a, transparent 30%), var(--bg-raised);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  box-shadow:
    inset 0 1px 0 #ffffff30,
    inset 0 0 0 1px #ffffff1c,
    var(--shadow-raised);
  animation: sheet-rise 200ms cubic-bezier(0.2, 0, 0, 1);
}

@media (min-width: 40rem) {
  .sheet[open] .sheet__inner {
    border-radius: var(--radius-lg);
    max-height: 88dvh;
  }
}

@keyframes sheet-rise {
  from {
    transform: translateY(14px);
    opacity: 0;
  }
}

.sheet__head {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.15rem;
  border-bottom: 1px solid var(--line);
}

.sheet__title {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 650;
  letter-spacing: -0.015em;
}

.sheet__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  flex: none;
  border: 0;
  border-radius: 999px;
  background: #ffffff0d;
  color: var(--fg-muted);
  cursor: pointer;
  box-shadow: inset 0 0 0 1px #ffffff14;
  transition: background-color 140ms ease, color 140ms ease;
}

.sheet__close:hover {
  background: #ffffff1a;
  color: var(--fg);
}

/*
 * The body scrolls, the header does not. A deposit panel is taller than a phone
 * and the close button has to stay reachable — a dismiss control that scrolls
 * away is the reason people close a tab instead.
 */
.sheet[open] .sheet__body {
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
  overscroll-behavior: contain;
  padding: 0.9rem 1.15rem 1.15rem;
}

.calc__compare-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.45rem;
  padding-top: 0.35rem;
  color: var(--fg-muted);
  font-size: 0.73rem;
}

.calc__compare-line + .calc__compare-line {
  margin-top: 0.18rem;
  border-top: 1px solid rgb(255 255 255 / 0.08);
}

.calc__compare-line > span { display: inline-flex; align-items: center; gap: 0.25rem; }
.calc__compare-line strong { color: var(--fg); font-size: 0.93rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.calc__compare-line--reinvest strong { color: var(--accent-bright); }

.calc__help { position: relative; display: inline-flex; align-items: center; }
.calc__help summary {
  display: grid;
  place-items: center;
  width: 0.92rem;
  height: 0.92rem;
  border: 1px solid rgb(255 255 255 / 0.25);
  border-radius: 50%;
  color: var(--fg-muted);
  font-size: 0.63rem;
  font-weight: 700;
  cursor: pointer;
  list-style: none;
}
.calc__help summary::-webkit-details-marker { display: none; }
.calc__help[open] summary { color: var(--accent-bright); border-color: var(--accent-bright); }
.calc__help p {
  position: absolute;
  z-index: 30;
  left: 0;
  bottom: calc(100% + 0.48rem);
  width: min(13rem, 72vw);
  margin: 0;
  padding: 0.55rem 0.65rem;
  border: 1px solid var(--line-strong);
  border-radius: 0.55rem;
  background: #252a28;
  color: var(--fg);
  box-shadow: 0 12px 30px rgb(0 0 0 / 0.35);
  font-size: 0.7rem;
  line-height: 1.4;
}

@media (max-width: 35rem) {
  .calc__tiles { grid-template-columns: 1fr; }
}

.sheet[open] .sheet__body > * { flex-shrink: 0; }

/* Both Wallet operations share one compact card. Only its body scrolls;
   the title, switch and close button always stay inside the visible card. */
:is(#sheet-deposit, #sheet-withdraw)[open] {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0.75rem;
  max-height: none;
  overflow: hidden;
  overscroll-behavior-y: contain;
  touch-action: pan-y pinch-zoom;
}

:is(#sheet-deposit, #sheet-withdraw)[open] .sheet__inner {
  flex: 0 1 auto;
  width: min(28rem, 100%);
  max-height: min(44rem, 100%);
  overflow: hidden;
  margin: 0;
  border-radius: var(--radius-lg);
}

:is(#sheet-deposit, #sheet-withdraw)[open] .sheet__head {
  position: relative;
  padding: 0.65rem 0.8rem;
  gap: 0.5rem;
  background: var(--bg-raised);
}

:is(#sheet-deposit, #sheet-withdraw)[open] .sheet__body {
  flex: 1 1 auto;
  min-height: 0;
  padding: 0.75rem;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior-y: contain;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y pinch-zoom;
  overflow-anchor: none;
}

/* Telegram's visible WebView can be shorter than the browser layout viewport.
   Keep the scroll owner inside it, including the client's safe-area overlays. */
body.is-telegram :is(#sheet-deposit, #sheet-withdraw)[open] {
  height: min(100dvh, var(--tg-viewport-stable-height, 100dvh));
  padding-top: max(0.5rem, calc(var(--tg-safe-top, 0px) + var(--tg-content-top, 0px)));
  padding-bottom: max(0.5rem, var(--tg-safe-bottom, 0px));
  overflow-anchor: none;
}

:is(#sheet-deposit, #sheet-withdraw) .pickgrid__list {
  overscroll-behavior-y: auto;
  touch-action: pan-y;
  -webkit-overflow-scrolling: touch;
}

:is(#sheet-deposit, #sheet-withdraw) .sheet__close {
  width: 2.25rem;
  height: 2.25rem;
  color: var(--fg);
}

#sheet-deposit .depositqr {
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
}

#sheet-deposit .depositqr svg {
  width: 10rem;
  height: auto;
  max-width: 100%;
}

#promo-codes { scroll-margin-top: 1rem; }

/* Inside the overlay the panels are already on a raised surface, so their own
   ring would draw a box inside a box. */
.sheet[open] .sheet__body > .card {
  box-shadow: inset 0 0 0 1px #ffffff12;
}

/* ---- the reassurance line and the check button ---- */

.sheet__note {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  margin: 0;
  padding: 0.65rem 0.8rem;
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 26%, transparent);
  font-size: 0.875rem;
  line-height: 1.45;
  color: var(--fg);
}

.sheet__note .icon {
  flex: none;
  margin-top: 0.1rem;
  color: var(--accent-bright);
}

/* The credited state: same box, louder ring, so the change is noticed without
   anything moving on the page. */
.sheet__note.is-credited {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 60%, transparent);
  color: var(--accent-tint);
}

.sheet__check {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin: 0;
}

/* The answer to the question the button asks, beside the button that asks it. */
.sheet__balance {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  margin: 0;
}

.sheet__balancelabel {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--fg-muted);
}

.sheet__balancevalue {
  font-size: 1.0625rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

/* --------------------------------------------------------------- the switch -- */

/*
 * Deposit and Withdraw as one segmented control in the sheet's header.
 *
 * The header used to be a title repeating the button that had just been
 * pressed, and opening the wrong sheet meant closing it to find the other
 * button. A segment is the shortest possible correction of a wrong choice.
 *
 * Both halves are links, so with no script they navigate to the tab and the
 * server renders that panel; the class is what marks the current one.
 */
.sheetswitch {
  display: inline-flex;
  gap: 0.15rem;
  padding: 0.2rem;
  border-radius: 999px;
  background: #00000059;
  box-shadow: inset 0 0 0 1px #ffffff12;
}

.sheetswitch__tab {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.42rem 0.85rem;
  border-radius: 999px;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1;
  color: var(--fg-muted);
  text-decoration: none;
  transition:
    background-color 140ms ease,
    color 140ms ease;
}

.sheetswitch__tab:hover {
  color: var(--fg);
}

.sheetswitch__tab.is-on {
  background: linear-gradient(to bottom, var(--accent-hover), var(--accent) 60%, var(--accent-deep));
  color: var(--accent-ink);
  box-shadow:
    inset 0 1px 0 #ffffff5c,
    0 1px 2px rgb(0 0 0 / 0.35);
}

.sheetswitch__tab .icon {
  flex: none;
}

/* On the narrowest phones the words go and the marks carry it. */
@media (max-width: 23rem) {
  .sheetswitch__tab {
    padding: 0.42rem 0.6rem;
    font-size: 0.8125rem;
  }
}

/* ---------------------------------------------------------------- the toast -- */

/*
 * Bottom centre on a phone, bottom right on a desktop — where a notification is
 * expected on each, and in both cases out of the way of the thing being read.
 *
 * Above the sheet's own layer: a dialog opened with showModal() sits in the top
 * layer, which no z-index can reach, so the toast is promoted into it as well
 * with `position: fixed` plus a very high stacking context. On the pages where
 * no dialog is open this changes nothing.
 */
.toast {
  position: fixed;
  z-index: 2147483000;
  left: 50%;
  bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  max-width: min(26rem, calc(100vw - 2rem));
  padding: 0.7rem 1rem;
  border-radius: 999px;
  background: linear-gradient(to bottom, var(--accent-hover), var(--accent) 60%, var(--accent-deep));
  color: var(--accent-ink);
  font-size: 0.875rem;
  font-weight: 650;
  text-align: center;
  box-shadow:
    inset 0 1px 0 #ffffff5c,
    0 8px 30px -8px color-mix(in srgb, var(--accent) 55%, transparent),
    0 2px 8px rgb(0 0 0 / 0.5);
  animation: toast-life 5s cubic-bezier(0.2, 0, 0, 1) forwards;
}

@media (min-width: 46rem) {
  .toast {
    left: auto;
    right: 1.25rem;
    bottom: 1.25rem;
    transform: none;
  }
}

/*
 * One animation covers the whole life: in, hold, out. A separate timer would be
 * a second place the duration is written down, and the two would drift.
 */
@keyframes toast-life {
  0% {
    opacity: 0;
    transform: translateX(-50%) translateY(12px);
  }
  6%,
  88% {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
  100% {
    opacity: 0;
    transform: translateX(-50%) translateY(12px);
  }
}

@media (min-width: 46rem) {
  @keyframes toast-life {
    0% {
      opacity: 0;
      transform: translateY(12px);
    }
    6%,
    88% {
      opacity: 1;
      transform: translateY(0);
    }
    100% {
      opacity: 0;
      transform: translateY(12px);
    }
  }
}

/* ------------------------------------------------------- token and network -- */

/*
 * The pair of pickers on the deposit panel. Side by side, because they are one
 * question asked twice and splitting them down the page would make the second
 * look optional.
 */
.sendpick {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.6rem;
}

.sendpick__field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}

.sendpick__label {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--fg-muted);
}

/*
 * `appearance: none` removes the platform control so the field can carry the
 * same inset bevel as every other input here — and the arrow has to be drawn
 * back, because removing the appearance removes that too. It is a background
 * image rather than a pseudo-element: a select cannot have children, and an
 * absolutely-positioned sibling would need a wrapper that exists only to hold
 * it.
 */
.sendpick__select {
  appearance: none;
  width: 100%;
  /*
   * The right padding has to clear the arrow AND the longest label. "BNB Smart
   * Chain" was running under the arrow at 2.1rem — a select does not ellipsize,
   * it simply draws over. A slightly smaller face buys the rest.
   */
  padding: 0.65rem 2.4rem 0.65rem 0.85rem;
  font-size: 0.9375rem;
  text-overflow: ellipsis;
  border: 0;
  border-radius: var(--radius-sm);
  background-color: var(--bg-input);
  background-image: linear-gradient(45deg, transparent 50%, var(--fg-muted) 50%),
    linear-gradient(135deg, var(--fg-muted) 50%, transparent 50%);
  background-position: right 1.15rem center, right 0.85rem center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  color: var(--fg);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  box-shadow:
    inset 0 1px 2px rgb(0 0 0 / 0.5),
    inset 0 0 0 1px #ffffff14;
}

.sendpick__select:focus {
  outline: none;
  box-shadow:
    inset 0 1px 2px rgb(0 0 0 / 0.4),
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 55%, transparent),
    0 0 0 3px var(--accent-soft);
}

/* The list itself is drawn by the operating system, which does not inherit the
   page palette — naming both keeps it from opening as white on white. */
.sendpick__select option {
  background: var(--bg-raised);
  color: var(--fg);
}

.sendpick__note {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--fg-muted);
}

/* ---------------------------------------------------------------- the code -- */

/*
 * THE QR, ON ITS OWN LINE AND BIG ENOUGH TO SCAN.
 *
 * It was a small square in a two-column row beside the address. That row
 * collapsed badly inside a sheet: the code shrank to fit whatever width was
 * left and ended up off-centre, which is exactly what the owner saw.
 *
 * A code that has to be read by a camera across a desk is not an ornament next
 * to the address — for anybody holding a second phone it IS the address. So it
 * gets the full width, a white quiet zone of its own, and a size that survives
 * being photographed at an angle.
 *
 * WHITE, NOT INVERTED. Scanners are trained on dark-on-light and many refuse a
 * light-on-dark code outright. The white plate is not a style choice.
 */
.depositqr {
  display: flex;
  justify-content: center;
  margin: 0;
  /*
   * THE PLATE IS THE QUIET ZONE AND NOTHING MORE.
   *
   * It was a wide white panel with a small code adrift in the middle of it,
   * because the code was capped at 15rem while the plate stretched. A QR needs
   * a light margin of about four modules around it to be read — that is the
   * only reason the white exists — so the padding is now the quiet zone and the
   * code takes everything else.
   */
  padding: 0.75rem;
  border-radius: var(--radius);
  background: #ffffff;
  box-shadow: inset 0 0 0 1px #0000001a;
}

.depositqr svg {
  display: block;
  /* Full width of the sheet, square, with a ceiling so it does not become a
     poster on a wide desktop. */
  width: 100%;
  max-width: 22rem;
  height: auto;
  /* The code is drawn as one path; crisp edges keep the modules square at any
     scale rather than letting the browser soften them into grey. */
  shape-rendering: crispEdges;
}

/*
 * The address itself: full width, wrapping on the character rather than the
 * word, because a 42-character hex string has no words to break at and would
 * otherwise push the sheet sideways.
 */
.deposit__address {
  margin: 0;
  padding: 0.7rem 0.85rem;
  border-radius: var(--radius-sm);
  background: var(--bg-input);
  box-shadow:
    inset 0 1px 2px rgb(0 0 0 / 0.5),
    inset 0 0 0 1px #ffffff14;
  font-size: 0.9375rem;
  line-height: 1.5;
  word-break: break-all;
}

/* ------------------------------------------------------- the one-line warning -- */

.sendpick__warn {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--warning, #e8b45f);
}

/*
 * THE TWO PICKER ROWS, TIGHTENED.
 *
 * They are the first thing in the sheet now, and everything below them is
 * pushed down by whatever height they take. The withdraw form can afford the
 * looser version — it is a page of fields and these are two of them — but here
 * they are a heading for the address underneath, so they get the compact form:
 * the legend inline-cased and small, the chips one step shorter.
 */
.sheet .pick,
.sheet__body .pick {
  margin: 0;
  padding: 0;
  border: 0;
}

.sheet .pick + .pick {
  margin-top: 0.5rem;
}

.sheet .pick__legend {
  padding: 0;
  margin-bottom: 0.3rem;
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--fg-muted);
}

.sheet .pick__options {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.sheet .pick__face {
  padding: 0.4rem 0.7rem;
  font-size: 0.8125rem;
  border-radius: 999px;
}

.sheet .pick__mark {
  width: 1.1rem;
  height: 1.1rem;
}

/* ------------------------------------------------- fitting without a scroll -- */

/*
 * A DEPOSIT SHOULD BE ONE SCREEN, and on a phone that is about 700 points of
 * height minus the browser chrome. Owner's requirement, and it is the right one:
 * a person copying an address between two apps loses their place every time the
 * sheet moves under them.
 *
 * The two cards that pointed elsewhere are gone from the markup. What is left is
 * spacing, and this takes roughly a third out of the vertical measures inside a
 * sheet without touching the horizontal ones — the same principle as the density
 * passes earlier in this file, applied where it is now needed most.
 *
 * Scoped to `.sheet`. The wallet page behind keeps its own rhythm; a card in a
 * sheet is read at arm's length with one job in front of it, which is not the
 * same reading and does not want the same air.
 */
.sheet__body {
  gap: 0.5rem;
}

.sheet .card__title {
  padding: 0.6rem 0.9rem;
  font-size: 0.9375rem;
}

.sheet .card__content {
  gap: 0.5rem;
  padding: 0.7rem 0.9rem 0.8rem;
}

.sheet .card__footer {
  padding: 0.55rem 0.9rem;
}

.sheet .sheet__note {
  padding: 0.55rem 0.7rem;
  font-size: 0.8125rem;
  line-height: 1.4;
}

.sheet .depositqr {
  padding: 0.6rem;
}

.sheet .deposit__address {
  padding: 0.55rem 0.7rem;
  font-size: 0.875rem;
  line-height: 1.4;
}

.sheet .field__hint {
  font-size: 0.6875rem;
  line-height: 1.35;
}

.sheet .field__label {
  margin-bottom: 0.15rem;
}

.sheet .sendpick__note {
  font-size: 0.75rem;
  line-height: 1.35;
}

.sheet .sendpick__warn {
  font-size: 0.75rem;
  line-height: 1.35;
}

/*
 * The plain blocks that replaced the two cards. A hairline and a little padding
 * is all the separation they need: inside a sheet there is one job on screen, so
 * the blocks are steps in it rather than objects to tell apart.
 */
/* ------------------------------------------------------- coin and chain pair -- */

/*
 * TWO FIELDS ON ONE ROW: coin on the left, chain on the right.
 *
 * They stay two columns all the way down to the narrowest phone. Stacking them
 * would be the usual reflex and it is wrong here: the pair is one question with
 * two halves, and the whole reason this replaced rows of chips is that chips
 * wrapped to four lines where the address needed the room.
 */
.pickgrid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.55rem;
}

.pickgrid__field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}

.pickgrid__label {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--fg-muted);
}

/*
 * The box that holds the mark and the field together.
 *
 * A native select cannot contain an image, so the logo is a sibling and this
 * wrapper is what makes them look like one control. The wrapper carries the
 * surface, the bevel and the focus ring; the select inside is transparent.
 */
.pickgrid__control {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding-left: 0.6rem;
  border-radius: 999px;
  background: var(--bg-input);
  box-shadow:
    inset 0 1px 2px rgb(0 0 0 / 0.5),
    inset 0 0 0 1px #ffffff14;
}

.pickgrid__control:focus-within {
  box-shadow:
    inset 0 1px 2px rgb(0 0 0 / 0.4),
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 55%, transparent),
    0 0 0 3px var(--accent-soft);
}

.pickgrid__mark {
  width: 1.25rem;
  height: 1.25rem;
  flex: none;
  border-radius: 50%;
}

/*
 * The select itself: no background, no border, no platform arrow. The arrow is
 * drawn back as a background image because removing the appearance removes it
 * too, and a select cannot hold a pseudo-element to draw one in.
 */
.pickgrid__select {
  appearance: none;
  flex: 1;
  min-width: 0;
  padding: 0.55rem 1.9rem 0.55rem 0;
  border: 0;

  /*
   * A REAL COLOUR, NOT `transparent`, AND THIS IS WHY THE OPEN LIST WAS WHITE.
   *
   * The popup is drawn by the operating system, and Chrome paints it with the
   * SELECT's own background-color. Transparent resolved to white, so the list
   * opened as white rows with a blue highlight — a bright rectangle hanging off
   * a dark field, which is what "обрезанный" was describing.
   *
   * The value is the same as the wrapper behind it, so the field looks exactly
   * as it did while the list is closed, and the list now opens in the same
   * colour as everything else.
   */
  background-color: var(--bg-input);
  background-image: linear-gradient(45deg, transparent 50%, var(--fg-muted) 50%),
    linear-gradient(135deg, var(--fg-muted) 50%, transparent 50%);
  background-position: right 0.95rem center, right 0.65rem center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  color: var(--fg);
  font: inherit;
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  text-overflow: ellipsis;
}

.pickgrid__select:focus {
  outline: none;
}

/* The option list is drawn by the operating system and inherits nothing from
   the page, so both colours are named or it opens white on white. */
.pickgrid__select option {
  background: var(--bg-raised);
  color: var(--fg);
}

@media (max-width: 22rem) {
  .pickgrid__select {
    font-size: 0.8125rem;
  }
}

/* ------------------------------------------------- the dropdown we control -- */

/*
 * Once app.js has put a button and a listbox in front of it, the native select
 * is hidden but NOT removed: it is still what the form posts and what the
 * server validates. Kept in the layout with zero size rather than
 * `display: none`, so that a validation message the browser attaches to it
 * still has somewhere to point.
 */
.pickgrid__control.is-enhanced .pickgrid__select {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  opacity: 0;
  pointer-events: none;
}

.pickgrid__control.is-enhanced {
  padding-left: 0;
}

.pickgrid__button {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  width: 100%;
  padding: 0.55rem 0.7rem 0.55rem 0.6rem;
  border: 0;
  border-radius: inherit;
  background: transparent;
  color: var(--fg);
  font: inherit;
  font-size: 0.875rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.pickgrid__button:focus-visible {
  outline: none;
}

.pickgrid__value {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The arrow, drawn rather than typed: a glyph would sit on the text baseline
   and change size with the font. */
.pickgrid__arrow {
  flex: none;
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid var(--fg-muted);
  transition: transform 140ms ease;
}

.pickgrid__control.is-open .pickgrid__arrow {
  transform: rotate(180deg);
}

/*
 * The list. Absolutely positioned under its own control, which is why the
 * control is `position: relative` — and why this can be styled at all, unlike
 * the platform popup it replaces.
 */
.pickgrid__list {
  position: absolute;
  z-index: 40;
  top: calc(100% + 0.35rem);
  left: 0;
  right: 0;
  margin: 0;
  padding: 0.25rem;
  list-style: none;
  max-height: 14rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  border-radius: var(--radius-sm);
  background: var(--bg-raised);
  box-shadow:
    inset 0 1px 0 #ffffff1f,
    inset 0 0 0 1px #ffffff1c,
    var(--shadow-raised);
  animation: pick-drop 130ms cubic-bezier(0.2, 0, 0, 1);
}

@keyframes pick-drop {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
}

.pickgrid__item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.6rem;
  border-radius: calc(var(--radius-sm) - 0.25rem);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--fg);
  cursor: pointer;
}

.pickgrid__item:hover {
  background: #ffffff0f;
}

/* The current one, marked with the accent rather than a tick: at this size a
   tick is a smudge, and the row is short enough to tint whole. */
.pickgrid__item[aria-selected='true'] {
  background: var(--accent-soft);
  color: var(--accent-bright);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent);
}

.pickgrid__itemmark {
  width: 1.25rem;
  height: 1.25rem;
  flex: none;
  border-radius: 50%;
}

/*
 * A sheet clips nothing: the list has to be able to hang below its field, and
 * the body of a sheet scrolls. `overflow: visible` on the row that holds the
 * pair is what stops the list being cut off at the block's edge.
 */
.pickgrid,
.pickgrid__field,
.depositblock,
.depositblock__body {
  overflow: visible;
}

/* ==================================================== leaderboard, compact == */

/*
 * ONE ROW PER ROW, AND THE FIGURE HARD RIGHT.
 *
 * The grid was already three columns with the amount last, so on a desktop it
 * behaved. On a phone it broke onto two lines, and the cause was width rather
 * than layout: the amount cell carried a coin mark, the figure, and the letters
 * USDC, which together needed more than the third column could take — so the
 * cell wrapped and the address above it looked orphaned.
 *
 * The ticker is gone from the markup. What is left here is making sure the
 * figure never wraps and always ends on the same vertical line, which is what
 * "centre them" was asking for: ten amounts of different lengths only read as a
 * column when their last digits agree.
 */
.lb__amount {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.35rem;
  white-space: nowrap;
}

.lb__value {
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

.lb__coin {
  width: 0.95rem;
  height: 0.95rem;
  flex: none;
  border-radius: 50%;
}

/* Tighter down the page: ten rows of a board are read as a list, and a list is
   the one thing that gains from being close together. */
.lb__row {
  padding: 0.18rem 0.4rem;
  gap: 0.5rem;
}

.lb-card .card__content {
  gap: 0.35rem;
}

@media (max-width: 34rem) {
  /*
   * THE DOTS GO ON A PHONE. They stand for the rest of an address that is
   * deliberately never sent to the browser, so they carry no information — and
   * they were taking about a fifth of the row on the screen with the least of
   * it. The truncated head still reads as truncated with the figure beside it.
   */
  .lb__mask {
    display: none;
  }

  .lb__row {
    grid-template-columns: 1.15rem minmax(0, 1fr) auto;
    gap: 0.4rem;
    padding: 0.16rem 0.3rem;
    font-size: 0.8125rem;
  }

  /*
   * PUTTING THE FIGURE BACK ON THE SAME LINE, and this is the rule that was
   * actually doing the damage.
   *
   * An earlier phone override dropped the amount to a second row on purpose —
   * `grid-column: 2` — reasoning that the figure should not have to shrink the
   * wallet. That was a fair trade when the amount cell carried a coin mark, the
   * number AND the letters USDC. Without the ticker it fits beside a truncated
   * address with room to spare, and ten two-line rows are a list twice as long
   * for nothing.
   *
   * `auto` rather than `3`: it lands in the next free column either way, and
   * naming a number here would be a second place that has to agree with the
   * template above it.
   */
  .lb__amount {
    grid-column: auto;
  }

  .lb__addr {
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .lb__coin {
    width: 0.85rem;
    height: 0.85rem;
  }
}


/* ================================================== the sidebar, rebuilt == */

/*
 * WRITTEN ONCE, RATHER THAN PATCHED FIVE TIMES.
 *
 * The previous version of this section grew by correction: a minimum height to
 * line the rows up, then a stretched icon to fill it, then a bigger square for
 * the one row with a status, then arithmetic to size that square. Each fix was
 * aimed at the last one's side effect, and the result was a menu of tall boxes
 * with a floating mark in each. It has been deleted, not amended.
 *
 * THE DESIGN, IN ONE SENTENCE: every item is a tile and a label, the tile is the
 * same square on all eleven, and a row is exactly as tall as what is in it.
 *
 * That single decision answers everything the patches were chasing. The column
 * looks ordered because the tiles form one straight left edge -- not because the
 * rows are forced to a common height. Dashboard is a little taller than the rest
 * because it carries a status, which is the honest shape for an item that says
 * more. And the tile, at 2.25rem, is within a pixel or two of the two-line text
 * beside it, so on that row it reads as spanning both lines without anything
 * having to be measured against anything.
 */

/*
 * THE GEOMETRY IS THE ORIGINAL. THE DRESSING IS NEW.
 *
 * Owner's call after several rounds of me moving things: put the arrangement
 * back where it was and keep the look. So every measurement below — padding,
 * the gap to the label, the space between items and between groups, the size of
 * the glyph — is what this menu had before any of this started. What stays from
 * the rebuild is the part that was actually wanted: a face and an edge on each
 * row, a tile behind the mark, the accent on the current page, and the new
 * icons.
 *
 * Written next to the values rather than in a commit message because the next
 * person to "tidy" the spacing here will otherwise do exactly what I did.
 */
.sidebar__link {
  align-items: center;
  column-gap: 0.75rem;
  padding: 0.4375rem 0.75rem;
  /*
   * Less rounded than the pill I had made of it: at a third of the row height
   * the corner reads as a button, and a menu entry is not one.
   */
  border-radius: 0.45rem;
  color: var(--fg-muted);

  /* A face and an edge, so the row reads as a control and not as a word. */
  background: #ffffff05;
  box-shadow:
    inset 0 1px 0 #ffffff0f,
    inset 0 0 0 1px #ffffff12;
  transition:
    background-color 140ms ease,
    box-shadow 140ms ease,
    color 140ms ease;
}

/* The original rhythm: 0.125rem between items, 1rem between groups. */
.sidebar__link + .sidebar__link {
  margin-top: 0.125rem;
}

/*
 * Spacing belongs to the items. Setting it on the nav is what caused the chasms
 * between groups once: that element carries `flex: 1` to fill the sidebar, and a
 * grid container with spare height stretches its rows.
 */
.sidebar__nav {
  justify-content: flex-start;
}

.sidebar__group + .sidebar__group {
  margin-top: 1rem;
}

/* ---- the tile ---- */

/*
 * ONE SQUARE, EVERY ITEM. `border-box` with equal sides is what keeps it square
 * whatever the padding does; the earlier version used content-box and drifted
 * into rectangles the moment anything else changed.
 */
/*
 * THE GLYPH IS BACK TO 1.15rem, its original size — the tile around it is what
 * is new. `border-box` with equal sides plus that padding gives a 2.15rem
 * square, so the mark is drawn at the size it always was and simply sits on
 * something now.
 */
.sidebar__link .icon {
  box-sizing: border-box;
  width: 2.15rem;
  height: 2.15rem;
  flex: none;
  padding: 0.5rem;
  /* The tile keeps a touch more curve than the row it sits in — a small square
     with the same radius as a large one looks sharper than it is. */
  border-radius: 0.5rem;
  background: #ffffff08;
  color: var(--fg-muted);
  box-shadow:
    inset 0 1px 0 #ffffff14,
    inset 0 0 0 1px #ffffff12;
  transition:
    background-color 140ms ease,
    box-shadow 140ms ease,
    color 140ms ease;
}

/* ---- the text ---- */

/* Label and status left as the page had them: the original leading, the
   original 0.0625rem between the two lines. */

/*
 * The status belongs to the word above it. It used to sit half a centimetre
 * below, which reads as a separate label rather than as this item's state --
 * three sources of space stacked up: the grid row gap, a margin, and the default
 * leading. All three are pulled in here.
 */
/*
 * THE FARM STATUS IS OUT OF THE MENU, at the owner's call, and the menu is
 * simpler for it.
 *
 * It was the only second line in the column, so Dashboard was the only item
 * with a different shape — and every attempt to make that shape look deliberate
 * (a taller row, a bigger tile, a matched square) traded the whole menu's
 * evenness for one entry's extra word. Eleven identical rows beat ten identical
 * rows and one special case.
 *
 * NOTHING IS LOST. "Stopped" and "Farming" are the state of the farm, and the
 * farm is the first card on the dashboard: the panel says which it is, in full
 * words, next to the button that changes it. A menu is for going somewhere, not
 * for reporting.
 *
 * `.sidebar__badge` is deliberately NOT hidden with it — the unread count on
 * Support is a reason to click, which is exactly what a menu is for.
 */
.sidebar__state {
  display: none;
}

.sidebar__farm-indicators {
  grid-column: 3;
  display: inline-flex;
  align-items: center;
  justify-self: end;
  gap: .35rem;
  padding: .2rem .05rem;
}
.sidebar__farm-dot {
  display: block;
  width: .48rem;
  height: .48rem;
  border-radius: 50%;
}
.sidebar__farm-dot--real {
  background: #b7ed83;
  box-shadow: 0 0 0 2px rgb(183 237 131 / .12), 0 0 9px rgb(183 237 131 / .3);
}
.sidebar__farm-dot--demo {
  background: #f2b45d;
  box-shadow: 0 0 0 2px rgb(242 180 93 / .12), 0 0 9px rgb(242 180 93 / .3);
}

/* A support count is metadata for the menu item, not a second menu line. */
.sidebar__link {
  grid-template-columns: auto minmax(0, 1fr) auto;
}

.sidebar__link > .sidebar__badge {
  grid-column: 3;
  grid-row: 1;
  align-self: center;
  justify-self: end;
  margin: 0;
}

/* ---- states ---- */

@media (hover: hover) {
  .sidebar__link:hover {
    background: #ffffff0d;
    color: var(--fg);
    box-shadow:
      inset 0 1px 0 #ffffff1a,
      inset 0 0 0 1px #ffffff1f;
  }

  .sidebar__link:hover .icon {
    background: #ffffff12;
    color: var(--fg);
  }
}

/*
 * The current page, marked three ways: a tinted face, an accent edge, and the
 * tile lit. On a phone the sidebar is opened, glanced at and closed, and one
 * tint alone is easy to miss in that time.
 */
.sidebar__link--active {
  background: linear-gradient(to right, var(--accent-soft), #ffffff05 70%);
  color: var(--fg);
  box-shadow:
    inset 0 1px 0 #ffffff1f,
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 32%, transparent);
}

.sidebar__link--active .icon {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent-bright);
  box-shadow:
    inset 0 1px 0 #ffffff1f,
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 38%, transparent);
}

.sidebar__link--active .sidebar__state {
  color: color-mix(in srgb, var(--accent-bright) 65%, var(--fg-muted));
}

/* The earning destination is recognizable before it is opened. */
.sidebar__link--earn:not(.sidebar__link--active) {
  background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 12%, transparent), #ffffff05 82%);
  color: var(--fg);
  box-shadow:
    inset 0 1px 0 #ffffff16,
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 25%, transparent);
}

.sidebar__link--earn .icon {
  background: color-mix(in srgb, var(--accent) 15%, transparent);
  color: var(--accent-bright);
}

/* Not a destination yet, so not dressed as one. */
.sidebar__link--soon,
.sidebar__link--soon .icon {
  background: transparent;
  box-shadow: inset 0 0 0 1px #ffffff0a;
}

/* ==================================================== the way in, dressed == */

/*
 * THE SIGN-IN PAGE IS THE SHOP WINDOW.
 *
 * It is what a referral link opens, what an ad lands on, and the only page most
 * visitors will judge the product by. It was a correct two-column layout with
 * everything at the same weight: a headline barely larger than the body, a form
 * card on the flat page background, three points set like a footnote.
 *
 * Nothing here changes what the page says. It changes what it weighs.
 */

/*
 * The headline earns the display face and real size. `clamp` rather than a
 * breakpoint: the line should grow with the window rather than jump at one
 * width, and the middle term is what keeps it proportional on every screen
 * between a phone and a large monitor.
 */
.auth__tagline {
  font-family: var(--font-display, inherit);
  font-size: clamp(1.9rem, 3.6vw, 3rem);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.03em;
  color: var(--fg);
  text-wrap: balance;
  margin-bottom: 2rem;
}

/*
 * A light behind the card. Two washes: the accent low and warm behind the form,
 * indigo cold and wide behind the whole column. Neither is visible as a colour —
 * what is visible is that the card is standing in front of something.
 */
.auth__body::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: -10% -5% auto auto;
  width: min(46rem, 80vw);
  height: min(34rem, 60vh);
  border-radius: 50%;
  background:
    radial-gradient(closest-side, color-mix(in srgb, var(--accent) 10%, transparent), transparent 70%);
  filter: blur(20px);
  pointer-events: none;
}

.auth__body {
  position: relative;
  isolation: isolate;
}

/* The numbered points: the index becomes a quiet monospace tick rather than a
   heading, and the pair reads as a list rather than three small articles. */
.points__index {
  font-family: var(--font-mono, inherit);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  color: color-mix(in srgb, var(--accent) 60%, var(--fg-muted));
}

.points__title {
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--fg);
}

.points__body {
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--fg-muted);
}

/*
 * The card itself sits higher off the page: a stronger ring, the raised shadow
 * rather than the card one, and a hairline of accent along its top edge — the
 * one place on a signed-out page where the brand colour appears without being a
 * control.
 */
.auth__card,
.auth__body > .card {
  box-shadow:
    inset 0 1px 0 #ffffff2e,
    inset 0 0 0 1px #ffffff1f,
    var(--shadow-raised);
}

/* ================================================= support, as a messenger == */

/*
 * A TICKET IS A CONVERSATION, SO IT IS DRAWN AS ONE.
 *
 * It was a stack of full-width panels, each with a header naming who wrote it
 * and when. Correct, and it reads like a mail archive: every message the same
 * width, the same shape, the author discoverable only by reading a label.
 *
 * Nobody needs a label to know which side of a chat is theirs. Ours right,
 * theirs left, the two in different colours, timestamps small and inside — the
 * arrangement everybody has already learned, so the thread can be scanned at a
 * glance instead of read.
 *
 * NO MARKUP CHANGED. The list already carried `thread__item--operator`, which is
 * all the information the layout needs; the rest is which side to sit on and
 * what colour to be. That also means the escaping around the message body — the
 * thing that keeps a pasted `<script>` a paste — is untouched.
 */
.thread {
  gap: 0.4rem;
}

.thread__day,
.tg__day {
  align-self: center;
  width: fit-content;
  max-width: calc(100% - 2rem);
  margin: 0.55rem auto 0.35rem;
  padding: 0.28rem 0.7rem;
  border: 1px solid rgb(255 255 255 / 0.08);
  border-radius: 999px;
  background: rgb(24 28 32 / 0.76);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.06),
    0 4px 14px rgb(0 0 0 / 0.12);
  color: var(--fg-muted);
  font-size: 0.7rem;
  font-weight: 650;
  line-height: 1.25;
  text-align: center;
  list-style: none;
  backdrop-filter: blur(14px) saturate(125%);
}

.thread__item {
  /*
   * A bubble is as wide as its words, up to a limit. Full-width bubbles are the
   * single thing that stops a chat looking like a chat, and 78% is about where
   * a long paragraph still wraps naturally while a two-word reply stays short.
   */
  max-width: 78%;
  width: fit-content;
  margin-left: auto;
  padding: 0.6rem 0.85rem;
  border: 0;
  border-radius: 1.05rem 1.05rem 0.3rem 1.05rem;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--accent) 22%, transparent), color-mix(in srgb, var(--accent) 14%, transparent));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 26%, transparent);
}

/*
 * Theirs: left, and on the raised surface rather than the accent. The corner
 * that is squared off is the one nearest the speaker, which is the detail that
 * makes a rounded rectangle read as coming FROM somewhere.
 */
.thread__item--operator {
  margin-left: 0;
  margin-right: auto;
  border-radius: 1.05rem 1.05rem 1.05rem 0.3rem;
  background: linear-gradient(to bottom, #ffffff0f, #ffffff08);
  box-shadow: inset 0 0 0 1px #ffffff1a;
}

/* Consecutive messages from the same side belong together: tighter, and the
   repeated corner squared so the run reads as one turn in the conversation. */
.thread__item + .thread__item {
  margin-top: 0;
}

.thread__head {
  margin-bottom: 0.15rem;
  gap: 0.6rem;
}

.thread__author {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.thread__item--operator .thread__author {
  color: var(--accent-bright);
}

.thread__when {
  font-size: 0.6875rem;
  color: var(--fg-subtle);
}

.thread__body {
  font-size: 0.9375rem;
  line-height: 1.5;
}

/* The card the thread lives in stops being a card and becomes the room the
   conversation happens in: no inner rule, more air at the edges. */
.thread {
  padding: 0.25rem 0;
}

@media (max-width: 34rem) {
  .thread__item {
    max-width: 88%;
  }
}

/* ---- the composer ---- */

/*
 * One rounded bar: the box on the left, attach and send on the right, all inside
 * a single edge so it reads as one control rather than three that happen to be
 * adjacent.
 *
 * `align-items: end` so the two buttons stay on the bottom line as the textarea
 * grows — the alternative, centring them, walks them down the bar as somebody
 * types, which is the kind of small wrongness that makes an interface feel
 * homemade.
 */
.composer {
  display: flex;
  align-items: flex-end;
  gap: 0.4rem;
  padding: 0.4rem 0.4rem 0.4rem 0.9rem;
  border-radius: 1.4rem;
  background: var(--bg-input);
  box-shadow:
    inset 0 1px 2px rgb(0 0 0 / 0.5),
    inset 0 0 0 1px #ffffff16;
}

.composer:focus-within {
  box-shadow:
    inset 0 1px 2px rgb(0 0 0 / 0.4),
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent),
    0 0 0 3px var(--accent-soft);
}

.composer__input {
  flex: 1;
  min-width: 0;
  max-height: 9rem;
  padding: 0.5rem 0;
  border: 0;
  background: transparent;
  color: var(--fg);
  font: inherit;
  font-size: 0.9375rem;
  line-height: 1.45;
  resize: none;
}

.composer__input:focus {
  outline: none;
}

.composer__input::placeholder {
  color: var(--fg-subtle);
}

.composer__clip,
.composer__send {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  flex: none;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transition:
    background-color 140ms ease,
    color 140ms ease,
    transform 90ms ease;
}

.composer__clip {
  background: transparent;
  color: var(--fg-muted);
}

.composer__clip:hover {
  background: #ffffff12;
  color: var(--fg);
}

/*
 * THE FILE INPUT IS STILL THERE. Clipped, not `display: none` — a hidden input
 * is skipped by the keyboard and by some screen readers, and the label above
 * points at it by id, so it has to remain focusable for that to mean anything.
 */
.composer__files {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* A visible ring when the hidden input has focus, so tabbing to it is not
   tabbing into nothing. */
.composer__files:focus-visible + .composer__send,
.composer__files:focus-visible ~ .composer__clip,
.composer__clip:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.composer__send {
  background: linear-gradient(to bottom, var(--accent-hover), var(--accent) 60%, var(--accent-deep));
  color: var(--accent-ink);
  box-shadow:
    inset 0 1px 0 #ffffff5c,
    0 4px 12px -6px color-mix(in srgb, var(--accent) 55%, transparent);
}

.composer__send:active {
  transform: scale(0.94);
}

/* ======================================== colours that were left behind == */

/*
 * TWO PLACES STILL SHOUTING IN THE OLD PALETTE'S VOICE.
 *
 * A reskin done at the token layer cannot reach a value typed straight into a
 * rule, and these two were the loudest things on the dashboard.
 */

/*
 * THE PAYOUT WINDOW BAR. Amber for the part of the day that ran before you
 * joined, mid-green for the part you earned. Two saturated hues, neither of them
 * the brand's, sitting under a lime button — it was the first thing the eye went
 * to on the page and it was the one element that means nothing on its own.
 *
 * What the bar says is: this much of the day is gone, this much you were in for,
 * this much is left. Only the middle band is about the reader's money, so only
 * the middle band gets colour. The other two go to the indigo family — present,
 * legible, and clearly not the subject.
 */
.window__band--missed {
  fill: color-mix(in srgb, var(--deep) 80%, #ffffff);
}

.window__band--ahead {
  fill: color-mix(in srgb, var(--deep) 92%, #ffffff);
}

.window__band--earned {
  fill: var(--accent);
}

.window__band--now {
  fill: var(--fg);
}

.window__swatch--missed {
  background: color-mix(in srgb, var(--deep) 80%, #ffffff);
}

.window__swatch--ahead {
  background: color-mix(in srgb, var(--deep) 92%, #ffffff);
}

.window__swatch--earned {
  background: var(--accent);
}

/*
 * THE ENDING BUTTON. It was a full-strength red with a red glow under it — the
 * visual weight of a delete-account confirmation for an action that returns your
 * own money to your own balance.
 *
 * Nothing is lost by stopping and nothing is destroyed, so it is not drawn as
 * destruction. Outlined in a muted red instead: unmistakably the different one,
 * without claiming to be dangerous. Filling it red also put the only other
 * saturated colour on the page directly beneath the lime pair, which is what
 * made that corner look assembled rather than designed.
 */
.button--stop {
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  color: color-mix(in srgb, var(--danger) 70%, var(--fg));
  border-color: color-mix(in srgb, var(--danger) 38%, transparent);
  box-shadow: inset 0 1px 0 #ffffff0f;
}

.button--stop:hover {
  background: color-mix(in srgb, var(--danger) 20%, transparent);
  border-color: color-mix(in srgb, var(--danger) 55%, transparent);
  color: color-mix(in srgb, var(--danger) 85%, var(--fg));
}

.button--stop:active {
  background: color-mix(in srgb, var(--danger) 26%, transparent);
}

/*
 * The primary button's glow, halved. One lit control on a screen reads as the
 * thing to press; four of them read as a toy. The lift stays, the halo stops
 * being the loudest thing in the card.
 */
.button--primary {
  box-shadow:
    inset 0 1px 0 #ffffff5c,
    inset 0 0 0 1px #00000014,
    0 1px 2px rgb(0 0 0 / 0.45),
    0 8px 20px -12px color-mix(in srgb, var(--accent) 40%, transparent);
}

/* ============================================ palette v2: the third colour == */

/*
 * WHAT WAS MISSING, AND WHY ONE MORE COLOUR FIXES IT.
 *
 * The site had two: a lime accent and a stack of near-blacks. That is a correct
 * palette and a flat one. Everything not lime was the same temperature as
 * everything else not lime, so depth had to come entirely from opacity — and a
 * page built out of white-at-eight-per-cent looks like a wireframe someone
 * darkened.
 *
 * THE THIRD IS INDIGO, AND IT IS NEVER A CONTROL. It appears only where depth
 * is wanted: under the top of the page, inside the glow beneath a card, behind
 * the sheet backdrop. It is dark enough to read as shadow rather than as colour,
 * and cold enough that the lime in front of it looks brighter than it is. That
 * last part is the whole trick — a warm accent on a cold ground is the oldest
 * way to make a bright colour look expensive instead of loud.
 *
 * THE FOURTH IS NOT REALLY A COLOUR: the body type moves off pure white onto
 * bone. #ffffff on black is a screen; #e9e4d6 is paper. It is a two per cent
 * change that the eye reads as quality without ever locating it, and it is what
 * most "premium" dark interfaces are actually doing when they look warmer than
 * yours for no reason you can name.
 *
 * RATIONING, AS BEFORE: lime is action, indigo is depth, bone is type, and the
 * tier ladder keeps its own hues. Nothing else gets a colour.
 */

:root {
  /* Ground, one shade cooler and deeper than before. */
  --bg: #08090b;
  --bg-raised: #0f1114;
  --bg-card: #14161a;
  --bg-input: #0b0d10;

  /* The third colour. Never a fill for a control, never text. */
  --deep: #171a35;
  --deep-soft: #171a3566;

  /* Type: bone rather than white. */
  --fg: #e9e4d6;
  --fg-muted: #9a978c;
  --fg-subtle: #9a978c5c;

  --line: #ffffff1f;
  --line-strong: #ffffff33;
}

/*
 * THE PAGE ITSELF GETS DEPTH.
 *
 * Two very large, very faint radial washes: indigo from the top left, a breath
 * of the accent from the far right. Both are under three per cent — invisible
 * as colour, present as the sense that the page has a light source. Fixed, so
 * they do not slide up as content scrolls past.
 */
body {
  background-color: var(--bg);
  background-image:
    radial-gradient(1200px 700px at 12% -10%, color-mix(in srgb, var(--deep) 55%, transparent), transparent 70%),
    radial-gradient(900px 600px at 110% 8%, color-mix(in srgb, var(--accent) 6%, transparent), transparent 70%);
  background-attachment: fixed;
  background-repeat: no-repeat;
}

/*
 * Cards sit on that ground with an indigo shadow rather than a black one. A
 * coloured shadow is what makes an object look like it is ON something; a pure
 * black one makes it look like a hole.
 */
:root {
  --shadow-card:
    0 1px 2px rgb(0 0 0 / 0.5),
    0 18px 44px -26px color-mix(in srgb, var(--deep) 85%, black);
  --shadow-raised:
    0 2px 10px rgb(0 0 0 / 0.55),
    0 34px 70px -30px color-mix(in srgb, var(--deep) 90%, black);
}

/* Display type takes the warm end of the scale; the muted text stays cooler so
   the two do not merge into one beige. */
.card__title,
.stat__value,
.moneytile__value,
.balancebar__value {
  color: var(--fg);
}

/* ---------------------------------------------------------------- motion -- */

/*
 * TELEGRAM'S TRICK, WHICH IS NOT ANIMATION FOR ITS OWN SAKE.
 *
 * What makes that app feel expensive is that nothing appears abruptly and
 * nothing moves far. Panels rise a few pixels while fading in; controls answer a
 * press within a frame. The distances are small enough that you never watch the
 * movement, only notice its absence when it is gone.
 *
 * So: cards settle in on load, staggered by a few tens of milliseconds down the
 * page. One keyframe, six positions, no library.
 */
@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
}

@media (prefers-reduced-motion: no-preference) {
  .content > .card,
  .content > .tierline,
  .content > .moneytiles,
  .content > .walletactions {
    animation: rise-in 380ms cubic-bezier(0.16, 1, 0.3, 1) both;
  }

  .content > :nth-child(1) { animation-delay: 0ms; }
  .content > :nth-child(2) { animation-delay: 40ms; }
  .content > :nth-child(3) { animation-delay: 80ms; }
  .content > :nth-child(4) { animation-delay: 120ms; }
  .content > :nth-child(5) { animation-delay: 160ms; }
  .content > :nth-child(n + 6) { animation-delay: 200ms; }
}

/*
 * A pressed control gives by one and a half per cent. Less is invisible, more is
 * a toy. The timing is deliberately faster going down than coming back up,
 * which is how a physical key behaves.
 */
.button:active {
  transform: scale(0.985) translateY(1px);
}

/* ================================================ the tier, as one line == */

/*
 * Text for a screen reader and nobody else. The tier row is a link whose visible
 * content is a label, a name and a chevron — none of which says where it goes.
 * Clipping rather than `display: none`, because a hidden element is not read out
 * at all, which defeats the point.
 */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/*
 * THE ROW. Label on the left, the tier's name in the middle taking the slack, a
 * chevron on the right — the shape of a settings row, which is what this is: a
 * current value and a way to change it.
 *
 * The whole row is the link. A person reaching for "See all tiers" on a phone
 * was aiming at a button the width of four words; now the target is the row.
 */
.tierline {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--fg);
  background:
    linear-gradient(
      to right,
      color-mix(in srgb, var(--tier-color, var(--accent)) 10%, transparent),
      transparent 55%
    ),
    var(--bg-card);
  box-shadow:
    inset 0 1px 0 #ffffff24,
    inset 0 0 0 1px #ffffff1a,
    var(--shadow-card);
  transition:
    background-color 140ms ease,
    box-shadow 140ms ease;
}

@media (hover: hover) {
  .tierline:hover {
    box-shadow:
      inset 0 1px 0 #ffffff30,
      inset 0 0 0 1px color-mix(in srgb, var(--tier-color, var(--accent)) 34%, transparent),
      var(--shadow-card);
  }

  .tierline:hover .tierline__go {
    transform: translateX(2px);
  }
}

.tierline__label {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--fg-muted);
}

.tierline__name {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
  font-family: var(--font-display, inherit);
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--tier-color, var(--fg));
}

.tierline__go {
  display: inline-flex;
  color: var(--fg-subtle);
  transition: transform 140ms ease;
}

/* On a narrow phone the label goes above the name rather than fighting it for
   width — two short lines beat one line with a truncated tier name. */
@media (max-width: 26rem) {
  .tierline {
    grid-template-columns: 1fr auto;
    gap: 0.15rem 0.75rem;
    padding: 0.65rem 0.85rem;
  }

  .tierline__label {
    grid-column: 1;
  }

  .tierline__name {
    grid-column: 1;
  }

  .tierline__go {
    grid-column: 2;
    grid-row: 1 / -1;
  }
}

/* ============================================ the running farm, laid out == */

/*
 * ADD AND TAKE SOME OUT ARE MIRROR IMAGES, SO THEY ARE DRAWN AS A PAIR.
 *
 * They were three stacked forms of different shapes, each with its own hint
 * paragraph, running about four hundred pixels down the card — and the third,
 * "Stop farming", looked like a fourth kind of thing rather than the same act
 * for the whole amount.
 *
 * Two columns on a wide screen, one on a phone. Same field, same button width,
 * same hint position: the only difference between the halves is the word on the
 * button, which is exactly the difference between the two actions.
 */
.farmops {
  display: grid;
  gap: 0.85rem;
}

@media (min-width: 46rem) {
  .farmops {
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
  }
}

/*
 * Each half is a column: label, field, hint, button. The button goes last and
 * is pushed to the bottom, so the two buttons sit on one line even when one
 * hint wraps to two lines and the other does not.
 */
.farmop {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.farmop .field {
  flex: 1;
}

.farmop .button {
  width: 100%;
}

/*
 * THE ENDING ACTION, BELOW A RULE.
 *
 * A person scanning the card should meet the two amount fields first and this
 * only after — it is the one control here that closes the position. The rule is
 * what says "different kind of thing" without a heading, and the hint under it
 * answers the question the button raises rather than the one before it.
 */
.farmend {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.35rem;
  margin-top: 1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--line);
}

.farmend .field__hint {
  margin: 0;
}

.farmend__confirm,
.farmend__confirm > summary,
.farmend__confirm-body form,
.farmend__confirm-body button { width: 100%; box-sizing: border-box; }
.farmend__confirm { position: relative; }
.farmend__confirm[open] { z-index: 70; }
.farmend__confirm > summary {
  position: relative;
  list-style: none;
  min-height: 2.85rem;
  text-align: center;
}
.farmend__confirm > summary::-webkit-details-marker { display: none; }
.farmend__chevron {
  position: absolute; right: .8rem; top: 50%;
  display: grid; place-items: center; width: 1.5rem; height: 1.5rem;
  transform: translateY(-50%) rotate(90deg);
  color: currentColor; opacity: .72;
  transition: transform .18s ease;
}
.farmend__chevron .icon { width: .95rem; height: .95rem; }
.farmend__confirm[open] .farmend__chevron { transform: translateY(-50%) rotate(-90deg); }
.farmend__confirm-body {
  position: absolute; bottom: calc(100% + .55rem); left: 0; right: 0;
  display: grid; gap: .55rem;
  padding: .68rem; border: 1px solid color-mix(in srgb, #bb9079 35%, var(--border));
  border-radius: .7rem; background: #24231f;
  box-shadow: 0 16px 36px rgb(0 0 0 / .46), inset 0 1px 0 rgb(255 255 255 / .08);
}
.farmend__confirm-body p { margin: 0; color: var(--fg); font-size: .8rem; line-height: 1.42; }
.farmend__confirm-body form { margin: 0; }
.farmend__confirm-body button { min-height: 2.55rem; }

/* Keep the confirmation clear of the two floating corner controls. */
.page-app:has(.farmend__confirm[open]) .support-fab,
.page-app:has(.farmend__confirm[open]) .to-top {
  opacity: 0;
  pointer-events: none;
}

/* The Tier row is a link; corner shortcuts must never sit on top of it. */
.page-app.tier-float-clear .support-fab,
.page-app.tier-float-clear .to-top {
  opacity: 0;
  pointer-events: none;
}

.depositblock {
  border-radius: var(--radius-sm);
  background: #ffffff05;
  box-shadow: inset 0 0 0 1px #ffffff12;
}

.depositblock__body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.7rem 0.8rem;
}

/* On a phone the code is the tallest single thing left; this keeps the whole
   sheet inside one screen without making it unscannable. */
@media (max-width: 40rem) {
  .depositqr svg {
    /*
     * 11rem is 176 points. A QR at that size, with its quiet zone, is read by
     * every phone camera from about 15cm — which is the distance somebody holds
     * a second phone at. Going larger only buys range nobody uses and costs the
     * copy button its place on the screen.
     */
    max-width: 11rem;
  }
}

/* The withdraw form is mostly fields, so its rows are what take the height. */
.sheet .field + .field {
  margin-top: 0.5rem;
}

.sheet .form,
.sheet .form--stack {
  gap: 0.5rem;
}

.sheet .button {
  padding-block: 0.55rem;
}

/*
 * The header is fixed and the body scrolls, so on a short screen the sheet can
 * still be reached end to end. This raises the ceiling from 92% to 96% of the
 * viewport: the four per cent bought nothing but a glimpse of the page behind,
 * and the sheet has a backdrop for that.
 */
.sheet[open] .sheet__inner {
  max-height: 96dvh;
}

@media (min-width: 40rem) {
  .sheet[open] .sheet__inner {
    max-height: 92dvh;
  }
}

.sendpick__warn .icon {
  flex: none;
  margin-top: 0.1rem;
}

/* ================================================ tiers: the expensive pass == */

/*
 * WHAT "PREMIUM" ACTUALLY MEANS HERE, because it is not more decoration.
 *
 * The display face is already in this project — Clash Display, self-hosted next
 * to Inter and Geist Mono. Nothing new is being loaded; it was simply not being
 * used where it would earn its keep. Expensive typography is a SMALL amount of
 * a distinctive face doing the naming, a lot of a quiet face doing the reading,
 * and figures that line up in a column. That is the whole recipe.
 *
 * So: tier names take the display face, everything else gets smaller and tighter
 * rather than louder, and the light on the cards is one specular sweep instead
 * of a glow.
 */

/*
 * THE MIRROR. A single diagonal highlight across the top corner, in the tier's
 * own colour at very low alpha.
 *
 * It reads as a sheet of glass catching a window. The reason it works and a
 * plain glow does not: a glow is symmetrical and therefore looks like a light
 * source behind the card, while a sweep has a DIRECTION, and a directional
 * highlight is what the eye reads as a surface with a finish.
 *
 * Drawn on the existing gradient layer, so no extra element and nothing to
 * position. `pointer-events` never comes up: it is a background.
 */
.tier {
  background:
    linear-gradient(
      118deg,
      color-mix(in srgb, var(--tier-color, var(--accent)) 9%, transparent) 0%,
      transparent 38%
    ),
    linear-gradient(to bottom, #ffffff0a, transparent 42%),
    var(--bg-card);
}

/* The rail across the top edge gets the tier colour at full strength, fading
   out to the right — the one saturated line on an otherwise quiet card. */
.tier::after {
  height: 1.5px;
  background: linear-gradient(
    to right,
    var(--tier-color),
    color-mix(in srgb, var(--tier-color) 30%, transparent) 45%,
    transparent 88%
  );
}

/* ---- naming ---- */

/*
 * The tier name in the display face. This is the one place on the card where a
 * distinctive letterform is worth the attention it takes, because the name is
 * the thing being chosen between.
 */
.tier .card__title,
.tier__name {
  font-family: var(--font-display, inherit);
  font-weight: 600;
  letter-spacing: -0.01em;
}

.tier__name {
  font-size: 1.0625rem;
}

/* ---- everything else, smaller and more even ---- */

/*
 * ONE STEP DOWN ACROSS THE CARD, and the labels one step further.
 *
 * The owner's note was that it looks unsymmetrical. Most of that was not
 * alignment — it was four different type sizes competing inside one small card,
 * so no two rows shared a baseline rhythm. Fewer sizes, closer together, is what
 * makes a dense card look composed rather than crowded.
 */
.tier__tagline {
  min-height: 2rem;
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.4;
  color: color-mix(in srgb, var(--tier-color, var(--accent)) 78%, var(--fg));
}

.tier .data-row__label,
.tierspec__label {
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
}

.tier .data-row__value,
.tierspec__value {
  font-size: 0.8125rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  /* One line, always. A wrapped value is what broke the top card's alignment. */
  white-space: nowrap;
}

.tier .data-row__hint {
  font-size: 0.6875rem;
  line-height: 1.35;
}

.tier__example {
  margin-top: 0.5rem;
  padding: 0.6rem 0.7rem;
  font-size: 0.8125rem;
  line-height: 1.4;
  background: linear-gradient(to bottom, #ffffff0a, #ffffff05);
  box-shadow: inset 0 0 0 1px #ffffff12;
}

/*
 * The cards no longer stretch to the tallest. With the prose box gone they are
 * within a few pixels of each other, and letting each be its own height removes
 * the last of the dead space at the bottom of the short ones.
 */
.tier-grid {
  align-items: start;
}

.sheet__check .icon {
  transition: transform 400ms cubic-bezier(0.2, 0, 0, 1);
}

.sheet__check.is-busy .icon {
  animation: sheet-spin 700ms linear infinite;
}

@keyframes sheet-spin {
  to {
    transform: rotate(360deg);
  }
}

/* ==========================================================================
   THE CONVERSATION LIST, OUTSIDE THE CONSOLE
   ==========================================================================

   The operator's queue draws `.tg__chats` inside a pane that has a pinned
   height and scrolls on its own. The user's support page draws the same rows
   inside an ordinary card, where both of those are wrong: `flex: 1 1 auto`
   means nothing outside a flex column, and `overflow-y: auto` on a box that is
   as tall as its content is a scrollbar that never appears but does clip the
   focus ring. This modifier undoes exactly those two things and nothing else.

   THE DOT IS NOT RED HERE. On the console a dot means "somebody is waiting on
   you", which is a warning. On this side it means "there is an answer you have
   not read", which is the thing the person came to the page hoping to see. Same
   mark, opposite feeling, so it takes the accent instead of the danger colour.
*/

.tg__chats--flat {
  overflow: visible;
  flex: none;
  padding: 0.4rem;
}

.tg__chats--flat .tg__chat {
  padding: 0.7rem;
}

/* A hairline between rows, because there is no surrounding pane to separate
   them from the page. Not on the last one: a line under the final row reads as
   the start of something that is not there. */
.tg__chats--flat li + li .tg__chat {
  border-top: 1px solid var(--line-soft, var(--line));
  border-radius: 0.7rem;
}

.tg__chats--flat .tg__dot {
  background: var(--accent);
  box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--accent) 22%, transparent);
}

/* The subject leads the row here, so it carries the weight the console gives
   the address. Unread pushes it further, the way an unread chat does. */
.tg__chats--flat .tg__chat--unread .tg__name {
  font-weight: 700;
}

/* ==========================================================================
   THE PHONE PASS: FIGURES TWO ACROSS, AND ROOM UNDER THE LAST LINE
   ==========================================================================

   FOUR TILES, FOUR SCREENS-WORTH OF NOTHING. `.stats` is
   `repeat(auto-fit, minmax(11rem, 1fr))`, and on a 390-point phone the content
   box is about 363 points wide while two 11rem columns plus the gap need 363.2.
   It missed by a fifth of a pixel, dropped to a single column, and History spent
   roughly four hundred points of height on four short numbers -- pushing the
   actual money movements, which is what the page is for, below the fold.

   Explicit two columns rather than a smaller `minmax`: the numbers here are
   short by construction (a count, or an amount that has its own unit inside it),
   so the honest instruction is "two across", not "as many as happen to fit".

   The tile is tightened to match. A tile that keeps desktop padding at half the
   width is mostly padding.
*/

@media (max-width: 30rem) {
  .stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .stat {
    padding: 0.8rem 0.85rem;
  }

  .stat__label {
    margin-bottom: 0.35rem;
    font-size: 0.66rem;
  }

  .stat__value {
    font-size: 1.2rem;
  }

  .stat__hint {
    font-size: 0.7rem;
  }
}

/*
   ROOM UNDER THE FOOT OF THE PAGE.

   The help button is fixed to the bottom-right corner, which is the point of it
   -- but at the very end of a long page it landed on the footer links, and one
   of the things it covered was the footer's own Support link. A button sitting
   on top of the link it duplicates is the kind of detail that reads as unfinished.

   Only on the widths where the button is a circle in the corner; above that it
   sits clear of a centred footer on its own.
*/
@media (max-width: 40rem) {
  .site-footer {
    padding-bottom: 4.25rem;
  }
}

/* --- the stamp inside a bubble --------------------------------------------

   `--fg-subtle` is calibrated against the page background. An outgoing bubble
   is not the page background: it is a lighter, accent-tinted surface, and on it
   the subtle grey stops being subtle and becomes unreadable -- the timestamp on
   your own messages was legible only if you knew it was there.

   Tied to the foreground colour rather than given a new hex value, so it
   follows the palette instead of becoming a number to remember.
*/

.thread__item:not(.thread__item--operator) .thread__when {
  color: color-mix(in srgb, var(--fg) 58%, transparent);
}

.thread__item:not(.thread__item--operator) .thread__author {
  color: color-mix(in srgb, var(--fg) 66%, transparent);
}

/* A message in a run has no name above it, so its head is just the stamp --
   which should sit with the text rather than reserve a line of its own. */
.thread__head--run {
  justify-content: flex-end;
  margin-bottom: 0.1rem;
}

/* The console's outgoing bubble has the same problem for the same reason. */
.tg__msg--out .tg__stamp {
  color: color-mix(in srgb, var(--fg) 58%, transparent);
}

/* Мелкая пометка внутри пузыря треда (например, "со скриншотом" у гостя). */
.thread__meta {
  margin: 0.15rem 0 0;
  font-size: 0.72rem;
  color: color-mix(in srgb, var(--fg) 55%, transparent);
}
.thread__item:not(.thread__item--operator) .thread__meta {
  color: color-mix(in srgb, var(--fg) 62%, transparent);
}

/* ==========================================================================
   СВЯЗАННЫЕ АККАУНТЫ В КОНСОЛИ (панель "уже видел этого человека")
   ========================================================================== */

.related {
  list-style: none;
  margin: 0.75rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.related__item {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm, 0.7rem);
  padding: 0.7rem 0.8rem;
  background: var(--bg-raised, rgb(255 255 255 / 0.02));
}

.related__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.related__email {
  font-weight: 650;
}

.related__signals {
  display: inline-flex;
  gap: 0.35rem;
  flex-wrap: wrap;
}

.chip {
  display: inline-flex;
  align-items: center;
  padding: 0.12rem 0.5rem;
  border-radius: 999px;
  font-size: 0.72rem;
  border: 1px solid var(--line);
  color: var(--fg-muted);
  white-space: nowrap;
}

.chip--danger {
  color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
  background: color-mix(in srgb, var(--danger) 12%, transparent);
}

.related__addr {
  margin: 0.4rem 0 0;
  font-size: 0.75rem;
  color: var(--fg-subtle);
  overflow-wrap: anywhere;
}

.related__facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 1rem;
  margin-top: 0.45rem;
  font-size: 0.8rem;
  color: var(--fg-muted);
}

.related__facts b {
  color: var(--fg);
  font-weight: 650;
}

/* Маленькая аватарка у имени в шапке реплики треда (мейн-саппорт). */
.thread__author {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.thread__avatar {
  width: 1.15rem;
  height: 1.15rem;
  font-size: 0.62rem;
  flex: 0 0 auto;
}
/* На своей стороне (справа) лицо идёт после имени. */
.thread__item:not(.thread__item--operator) .thread__author {
  flex-direction: row-reverse;
}

/* ==========================================================================
   ГОСТЕВОЙ ЧАТ (страница помощи без аккаунта)
   ========================================================================== */

.guestchat {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  min-height: 15rem;
  padding: 0.75rem;
  border-radius: var(--radius);
  /* A distinct chat surface, darker than the card it sits on, with a soft warm
     wash at the top — so it reads as a messenger window at a glance, not a form
     on a card. This is the "make it obviously a chat" fill. */
  background:
    radial-gradient(130% 60% at 50% 0%, color-mix(in srgb, var(--accent) 12%, transparent), transparent 60%),
    var(--bg);
  box-shadow:
    inset 0 0 0 1px var(--border),
    inset 0 1px 2px rgb(0 0 0 / 0.35);
}

/* The chat header: who you are talking to, with an avatar and an honest status. */
.guestchat__bar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.15rem 0.25rem 0.65rem;
  border-bottom: 1px solid var(--border);
}
.guestchat__ava {
  display: grid;
  place-items: center;
  width: 2.15rem;
  height: 2.15rem;
  flex: none;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent-bright);
}
.guestchat__who {
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
  min-width: 0;
}
.guestchat__name {
  /* Name and the green "online" dot on one line, the dot to the right of it. */
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.92rem;
  font-weight: 600;
}
.guestchat__status {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--fg-muted);
  font-size: 0.78rem;
}
.guestchat__dot {
  width: 0.45rem;
  height: 0.45rem;
  flex: none;
  border-radius: 50%;
  background: var(--accent-bright);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* Пустое состояние: не форма, а первая реплика — говорит, что это чат. */
.guestchat__empty {
  /* margin-bottom:auto docks the composer at the foot of the panel. */
  margin: 0.35rem 0 auto;
  padding: 0.9rem 1rem;
  border-radius: 1.05rem 1.05rem 1.05rem 0.3rem;
  background: linear-gradient(to bottom, #ffffff14, #ffffff09);
  box-shadow: inset 0 0 0 1px #ffffff1f;
  color: var(--fg);
  font-size: 0.9rem;
  line-height: 1.5;
  max-width: 92%;
}

.guestchat__thread {
  /* Messages at the top, composer pushed to the bottom of the panel. */
  margin: 0.25rem 0 auto;
  width: 100%;
}

/* On the dark chat surface the composer is lifted a shade so the "type here"
   bar clearly stands out as the place to write. */
.guestchat .composer {
  background: var(--bg-raised);
}

.guestchat__contact {
  margin: 0;
}

.guestchat__contact-label {
  display: block;
  margin: 0 0 0.15rem 0.1rem;
  line-height: 1.25;
}

.guestchat__contact-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: stretch;
  gap: 0.45rem;
  min-width: 0;
}

.guestchat__contact-row .field__input {
  min-width: 0;
}

.guestchat__contact-next {
  min-height: 2.7rem;
  padding-inline: 1rem;
}

.guestchat__contact-hint {
  margin-top: 0.05rem;
}

.guestchat__contact-saved {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.65rem;
  min-width: 0;
  padding: 0.18rem 0.25rem;
  color: var(--fg-muted);
  font-size: 0.75rem;
}

.guestchat__contact-saved span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.guestchat__contact-saved button {
  flex: none;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--accent-bright);
  font: inherit;
  cursor: pointer;
}

/* Progressive enhancement: without JavaScript the composer remains available. */
.guestchat--email-gated > form {
  display: none;
}

.guestchat--email-gated.guestchat--email-ready > form,
body.is-telegram .guestchat--email-gated > form {
  display: flex;
}

body.is-telegram .guestchat__contact-saved {
  display: none;
}

.guestchat__hint {
  margin: 0.3rem 0 0;
}

/* Появляется, когда app.js отправил сообщение и добавил его без перезагрузки. */
.guestchat__sending {
  opacity: 0.55;
}

/* Messenger-style quoted replies. The quote is part of the bubble; the draft
   sits immediately above the composer and disappears when cancelled/sent. */
.message-reply {
  display: grid;
  gap: 0.12rem;
  margin: 0 0 0.42rem;
  padding: 0.38rem 0.55rem;
  overflow: hidden;
  border: 0;
  border-left: 2px solid var(--accent-bright);
  border-radius: 0.25rem 0.55rem 0.55rem 0.25rem;
  background: rgb(0 0 0 / 0.18);
  color: inherit;
  text-align: left;
}

.message-reply strong {
  color: var(--accent-bright);
  font-size: 0.72rem;
  font-weight: 650;
}

.message-reply span {
  overflow: hidden;
  color: color-mix(in srgb, currentColor 72%, transparent);
  font-size: 0.76rem;
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.message-reply__action {
  width: max-content;
  margin: 0.28rem 0 -0.15rem auto;
  padding: 0.1rem 0.25rem;
  border: 0;
  background: transparent;
  color: color-mix(in srgb, currentColor 62%, transparent);
  font: inherit;
  font-size: 0.68rem;
  cursor: pointer;
}

.message-reply__action:hover,
.message-reply__action:focus-visible {
  color: var(--accent-bright);
}

.reply-draft {
  display: grid;
  grid-template-columns: 3px minmax(0, 1fr) 1.8rem;
  align-items: center;
  gap: 0.55rem;
  min-height: 3rem;
  padding: 0.35rem 0.55rem 0.35rem 0.72rem;
  border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--bg-raised) 92%, var(--accent) 8%);
}

.reply-draft[hidden] { display: none; }
.reply-draft__bar { align-self: stretch; border-radius: 1rem; background: var(--accent-bright); }
.reply-draft__copy { display: grid; min-width: 0; }
.reply-draft__copy strong { color: var(--accent-bright); font-size: 0.75rem; }
.reply-draft__copy span {
  overflow: hidden;
  color: var(--fg-muted);
  font-size: 0.76rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.reply-draft__close {
  width: 1.8rem;
  height: 1.8rem;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--fg-muted);
  font-size: 1.2rem;
  cursor: pointer;
}

.composer__selection,
.composer__sent-files {
  display: block;
  min-width: 0;
  margin: 0;
  padding: 0.45rem 0.1rem 0.55rem;
  overflow: hidden;
  color: var(--fg-muted);
}

.composer__selection[hidden],
.tg__clipnames[hidden] {
  display: none;
}

.file-preview-strip {
  display: flex;
  gap: 0.5rem;
  min-width: 0;
  overflow-x: auto;
  padding: 0.1rem 0.55rem 0.2rem;
  scrollbar-width: thin;
  scroll-snap-type: x proximity;
}

.file-preview {
  position: relative;
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  min-width: 0;
  overflow: hidden;
  border: 1px solid rgb(255 255 255 / 0.1);
  border-radius: 0.85rem;
  background: rgb(35 39 45 / 0.96);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.06),
    0 5px 16px rgb(0 0 0 / 0.16);
  scroll-snap-align: start;
}

.file-preview--image {
  width: 6.8rem;
  height: 5.7rem;
}

.file-preview--document {
  width: min(15rem, 72vw);
  min-height: 4.25rem;
  padding: 0.62rem 2.25rem 0.62rem 0.62rem;
  gap: 0.65rem;
}

.file-preview__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.file-preview__type {
  display: grid;
  place-items: center;
  width: 2.65rem;
  height: 2.65rem;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent-bright);
  font-size: 0.62rem;
  font-weight: 750;
  letter-spacing: 0.04em;
}

.file-preview__copy {
  display: grid;
  min-width: 0;
  gap: 0.12rem;
}

.file-preview--image .file-preview__copy {
  position: absolute;
  inset: auto 0 0;
  padding: 1.1rem 0.45rem 0.35rem;
  background: linear-gradient(transparent, rgb(0 0 0 / 0.76));
  color: #fff;
}

.file-preview__name {
  overflow: hidden;
  font-size: 0.68rem;
  font-weight: 600;
  line-height: 1.2;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-preview__size {
  color: color-mix(in srgb, currentColor 66%, transparent);
  font-size: 0.61rem;
  font-variant-numeric: tabular-nums;
}

.file-preview__remove {
  position: absolute;
  top: 0.28rem;
  right: 0.28rem;
  display: grid;
  place-items: center;
  width: 1.45rem;
  height: 1.45rem;
  padding: 0 0 0.08rem;
  border: 1px solid rgb(255 255 255 / 0.22);
  border-radius: 50%;
  background: rgb(9 11 14 / 0.78);
  color: #fff;
  font: inherit;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  backdrop-filter: blur(10px);
}

.file-preview__remove:active {
  transform: scale(0.9);
}

.tg__composer .tg__clipnames,
.tg__composer .reply-draft {
  grid-column: 1 / -1;
}

.tg__clipnames .file-preview-strip {
  padding-inline: 0;
}

/* Sent media belongs inside the bubble, not in a filename row beneath it. */
.attachments {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  width: min(26rem, 100%);
  margin: 0.12rem 0 0.4rem;
  gap: 0.18rem;
}

.attachments__item {
  min-width: 0;
}

.attachments__item:only-child {
  grid-column: 1 / -1;
}

.attachments__item--shot {
  align-items: stretch;
  gap: 0;
}

.attachments__preview,
.attachments__video-wrap {
  position: relative;
  display: block;
  width: 100%;
  overflow: hidden;
  border-radius: 0.85rem;
  background: #090b0d;
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.08);
  line-height: 0;
}

.attachments__image,
.shell--admin .attachments__image {
  display: block;
  width: 100%;
  max-width: none;
  height: auto;
  max-height: 24rem;
  object-fit: cover;
  background: #090b0d;
}

.attachments:has(> :nth-child(2)) .attachments__image {
  aspect-ratio: 1;
}

.attachments__media-meta {
  position: absolute;
  right: 0.38rem;
  bottom: 0.38rem;
  padding: 0.19rem 0.38rem;
  border-radius: 999px;
  background: rgb(0 0 0 / 0.58);
  color: rgb(255 255 255 / 0.84);
  font-size: 0.61rem;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  backdrop-filter: blur(8px);
}

.attachments__video {
  width: 100%;
  max-height: 24rem;
  border-radius: 0;
}

.attachments__link--document {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  width: min(20rem, 100%);
  min-height: 4rem;
  gap: 0.65rem;
  padding: 0.55rem 0.65rem;
  border-color: rgb(255 255 255 / 0.1);
  border-radius: 0.85rem;
  background: rgb(255 255 255 / 0.055);
}

.attachments__fileicon {
  display: grid;
  place-items: center;
  width: 2.65rem;
  height: 2.65rem;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent-bright);
}

.attachments__filecopy {
  display: grid;
  min-width: 0;
  gap: 0.12rem;
}

.attachments__download {
  color: var(--accent-bright);
  font-size: 1.1rem;
}

.attachments + .thread__body,
.attachments + .tg__text,
.composer__sent-files + .thread__body {
  margin-top: 0.42rem;
}

.composer__sent-files {
  padding: 0;
}

.composer__sent-files .file-preview-strip {
  padding: 0;
}

.composer__sent-files .file-preview--image {
  width: min(19rem, 68vw);
  height: min(15rem, 52vw);
}

/* Full-screen viewer stays inside the Mini App instead of opening a browser tab. */
.media-viewer {
  width: 100vw;
  max-width: none;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding: max(3.5rem, env(safe-area-inset-top)) 0.75rem max(1rem, env(safe-area-inset-bottom));
  border: 0;
  background: rgb(5 7 9 / 0.92);
  color: #fff;
  backdrop-filter: blur(24px) saturate(115%);
}

.media-viewer[open] {
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  place-items: center;
  gap: 0.8rem;
}

.media-viewer::backdrop {
  background: rgb(0 0 0 / 0.74);
}

.media-viewer__image {
  display: block;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 0.65rem;
  box-shadow: 0 20px 60px rgb(0 0 0 / 0.36);
}

.media-viewer__close {
  position: fixed;
  z-index: 1;
  top: max(0.75rem, env(safe-area-inset-top));
  right: 0.75rem;
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0 0 0.12rem;
  border: 0;
  border-radius: 50%;
  background: rgb(37 41 47 / 0.82);
  color: #fff;
  font: inherit;
  font-size: 1.45rem;
  cursor: pointer;
  backdrop-filter: blur(14px);
}

.media-viewer__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: min(44rem, 100%);
  min-width: 0;
  gap: 1rem;
}

.media-viewer__name {
  overflow: hidden;
  font-size: 0.78rem;
  font-weight: 550;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.media-viewer__download {
  flex: 0 0 auto;
  color: var(--accent-bright);
  font-size: 0.78rem;
  font-weight: 650;
  text-decoration: none;
}

.attachments__video {
  display: block;
  width: min(100%, 22rem);
  max-height: 20rem;
  border-radius: 0.75rem;
  background: #050607;
}

/* ================================================= dedicated support Mini App == */

/*
 * Telegram supplies the window; this page supplies one focused conversation.
 * The outer glass frame is visible on desktop and disappears on a phone, where
 * edge-to-edge content and the client's own chrome are the native convention.
 */
.page-support-mini {
  min-height: 100svh;
  overflow: hidden;
  background:
    radial-gradient(70rem 40rem at 12% -10%, color-mix(in srgb, var(--accent) 15%, transparent), transparent 58%),
    radial-gradient(52rem 34rem at 105% 110%, rgb(72 112 255 / 0.12), transparent 62%),
    #090b0e;
}

.page-support-mini .site-footer,
.page-support-mini .support-fab,
.page-support-mini .to-top,
.page-support-mini .cookie-banner,
.page-support-mini .start__head,
.page-support-mini > .skip-link:not(:focus) {
  display: none;
}

.support-mini {
  position: relative;
  isolation: isolate;
  display: flex;
  min-height: 100svh;
  padding:
    calc(0.9rem + var(--tg-content-top, 0px))
    calc(0.9rem + var(--tg-safe-right, 0px))
    calc(0.9rem + var(--tg-content-bottom, 0px))
    calc(0.9rem + var(--tg-safe-left, 0px));
}

.support-mini__aurora,
.support-launch__glow {
  position: fixed;
  z-index: -1;
  width: 24rem;
  height: 24rem;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 20%, transparent);
  filter: blur(90px);
  opacity: 0.55;
  pointer-events: none;
  transform: translate3d(-35%, -35%, 0);
}

.support-mini__window,
.page-support-mini .start__card {
  display: flex;
  flex-direction: column;
  width: min(100%, 54rem);
  height: min(52rem, calc(100svh - 1.8rem - var(--tg-content-top, 0px) - var(--tg-content-bottom, 0px)));
  min-height: 32rem;
  margin: auto;
  padding: 0;
  overflow: hidden;
  border: 1px solid rgb(255 255 255 / 0.12);
  border-radius: 1.55rem;
  background: rgb(14 17 21 / 0.82);
  box-shadow:
    0 30px 90px rgb(0 0 0 / 0.46),
    inset 0 1px 0 rgb(255 255 255 / 0.08);
  backdrop-filter: blur(28px) saturate(125%);
}

.page-support-mini .start {
  min-height: 100svh;
}

.page-support-mini .start__body {
  width: 100%;
  max-width: none;
  margin: 0;
}

.page-support-mini .start__card > .card__title {
  display: none;
}

.page-support-mini .start__card > .card__content {
  display: flex;
  flex: 1;
  min-height: 0;
  padding: 0;
}

.page-support-mini .guestchat--mini {
  flex: 1;
  min-height: 0;
  gap: 0;
  padding: 0;
  border-radius: 0;
  background:
    radial-gradient(circle at 1px 1px, rgb(255 255 255 / 0.025) 1px, transparent 1.5px) 0 0 / 22px 22px,
    linear-gradient(145deg, rgb(13 17 21 / 0.94), rgb(9 12 15 / 0.98));
  box-shadow: none;
}

.page-support-mini .guestchat--mini .guestchat__bar {
  z-index: 2;
  gap: 0.75rem;
  min-height: 4.4rem;
  padding: 0.7rem 1rem;
  border: 0;
  border-bottom: 1px solid rgb(255 255 255 / 0.08);
  background: rgb(22 25 30 / 0.78);
  box-shadow: 0 10px 32px rgb(0 0 0 / 0.16);
  backdrop-filter: blur(24px) saturate(130%);
}

.page-support-mini .guestchat--mini .guestchat__ava {
  width: 2.75rem;
  height: 2.75rem;
  background:
    linear-gradient(145deg, color-mix(in srgb, var(--accent) 82%, white), var(--accent));
  color: #071009;
  box-shadow:
    0 8px 24px color-mix(in srgb, var(--accent) 24%, transparent),
    inset 0 1px 0 rgb(255 255 255 / 0.4);
}

.page-support-mini .guestchat--mini .guestchat__name {
  font-size: 0.96rem;
  font-weight: 680;
  letter-spacing: -0.012em;
}

.page-support-mini .guestchat--mini .guestchat__status {
  color: var(--accent-bright);
  font-size: 0.72rem;
  line-height: 1.2;
}

.page-support-mini .guestchat--mini .guestchat__dot {
  width: 0.38rem;
  height: 0.38rem;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 12%, transparent);
}

.page-support-mini .guestchat--mini .guestchat__thread {
  flex: 1;
  min-height: 0;
  margin: 0;
  padding: 1.1rem clamp(0.75rem, 3vw, 1.6rem);
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  scroll-behavior: smooth;
  scrollbar-width: thin;
  scrollbar-color: rgb(255 255 255 / 0.14) transparent;
}

.page-support-mini .guestchat--mini .guestchat__empty {
  margin: 1.1rem auto auto 1rem;
  max-width: min(76%, 30rem);
  border-radius: 1.2rem 1.2rem 1.2rem 0.35rem;
  background: rgb(31 35 41 / 0.92);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.07),
    0 8px 22px rgb(0 0 0 / 0.16);
}

.page-support-mini .guestchat--mini .thread {
  display: flex;
  flex-direction: column;
  gap: 0.28rem;
}

.page-support-mini .guestchat--mini .thread__item {
  max-width: min(76%, 34rem);
  padding: 0.52rem 0.75rem 0.46rem;
  border-radius: 1.15rem 1.15rem 0.34rem 1.15rem;
  background: linear-gradient(145deg, color-mix(in srgb, var(--accent) 30%, #172019), color-mix(in srgb, var(--accent) 18%, #141a16));
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.08),
    0 7px 20px rgb(0 0 0 / 0.14);
  animation: support-bubble-in 220ms cubic-bezier(0.22, 0.8, 0.3, 1) both;
}

.page-support-mini .guestchat--mini .thread__item--operator {
  border-radius: 1.15rem 1.15rem 1.15rem 0.34rem;
  background: rgb(31 35 41 / 0.94);
}

.page-support-mini .guestchat--mini .thread__head {
  justify-content: flex-end;
  margin: 0 0 0.08rem;
}

.page-support-mini .guestchat--mini .thread__author {
  display: none;
}

.page-support-mini .guestchat--mini .thread__when {
  order: 2;
  font-size: 0.62rem;
  opacity: 0.72;
}

.page-support-mini .guestchat--mini .thread__body {
  font-size: 0.92rem;
  line-height: 1.42;
}

.page-support-mini .guestchat--mini > form {
  z-index: 3;
  flex: none;
  padding:
    0.65rem 0.75rem
    calc(0.65rem + var(--tg-safe-bottom, 0px));
  border-top: 1px solid rgb(255 255 255 / 0.07);
  background: rgb(18 21 25 / 0.84);
  backdrop-filter: blur(24px) saturate(130%);
}

.page-support-mini .guestchat--mini .composer {
  max-width: 48rem;
  margin: 0 auto;
  padding: 0.3rem 0.32rem 0.3rem 0.82rem;
  border-radius: 1.35rem;
  background: rgb(43 47 54 / 0.9);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.08),
    0 8px 26px rgb(0 0 0 / 0.2);
}

.page-support-mini .guestchat--mini .composer__send {
  width: 2.4rem;
  height: 2.4rem;
  background: var(--accent);
  color: #071009;
  box-shadow: 0 6px 18px color-mix(in srgb, var(--accent) 28%, transparent);
}

.page-support-mini .guestchat--mini .composer__send:active,
.page-support-mini .guestchat--mini .composer__clip:active {
  transform: scale(0.92);
}

.page-support-mini .guestchat__contact,
.page-support-mini .guestchat__hint {
  display: none;
}

@keyframes support-bubble-in {
  from { opacity: 0; transform: translateY(0.3rem) scale(0.985); }
  to { opacity: 1; transform: none; }
}

/* The verified-identity hand-off: intentionally quiet and fast. */
.support-launch {
  position: relative;
  isolation: isolate;
  display: grid;
  place-items: center;
  min-height: 100svh;
  padding: 1.25rem;
}

.support-launch__card {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: min(100%, 23rem);
  padding: 1.4rem;
  border: 1px solid rgb(255 255 255 / 0.11);
  border-radius: 1.6rem;
  background: rgb(24 27 32 / 0.76);
  box-shadow: 0 30px 80px rgb(0 0 0 / 0.42), inset 0 1px 0 rgb(255 255 255 / 0.09);
  text-align: center;
  backdrop-filter: blur(28px) saturate(125%);
}

.support-launch__mark {
  margin-bottom: 1.4rem;
  transform: scale(0.82);
  opacity: 0.8;
}

.support-launch__avatar {
  display: grid;
  place-items: center;
  width: 4.4rem;
  height: 4.4rem;
  margin-bottom: 1rem;
  border-radius: 50%;
  background: linear-gradient(145deg, color-mix(in srgb, var(--accent) 80%, white), var(--accent));
  color: #071009;
  box-shadow: 0 18px 44px color-mix(in srgb, var(--accent) 26%, transparent);
}

.support-launch__card h1 {
  margin: 0;
  font-size: 1.28rem;
  letter-spacing: -0.025em;
}

.support-launch__status {
  min-height: 2.5rem;
  margin: 0.5rem 0 1rem;
  color: var(--fg-muted);
  font-size: 0.86rem;
  line-height: 1.45;
}

.support-launch__spinner {
  width: 1.35rem;
  height: 1.35rem;
  border: 2px solid rgb(255 255 255 / 0.14);
  border-top-color: var(--accent-bright);
  border-radius: 50%;
  animation: spin 700ms linear infinite;
}

@media (max-width: 40rem) {
  .support-mini {
    padding: var(--tg-content-top, 0px) var(--tg-safe-right, 0px) var(--tg-content-bottom, 0px) var(--tg-safe-left, 0px);
  }

  .support-mini__window,
  .page-support-mini .start__card {
    width: 100%;
    height: 100svh;
    min-height: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;
  }

  .page-support-mini .guestchat--mini .thread__item,
  .page-support-mini .guestchat--mini .guestchat__empty {
    max-width: 84%;
  }
}

@media (max-width: 28rem) {
  .guestchat__contact-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .guestchat__contact-next {
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .page-support-mini .thread__item,
  .support-launch__spinner {
    animation: none;
  }

  .page-support-mini .guestchat__thread {
    scroll-behavior: auto;
  }
}

/* ==========================================================================
   ФОРМА ВХОДА/РЕГИСТРАЦИИ: компактнее, вкладки переключаются на месте
   ========================================================================== */

/* Свёрнутое необязательное поле (реферальный код). */
.field-fold {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm, 0.7rem);
  padding: 0 0.75rem;
}
.field-fold[open] {
  padding-bottom: 0.7rem;
}
.field-fold__summary {
  cursor: pointer;
  padding: 0.6rem 0;
  font-size: 0.85rem;
  color: var(--fg-muted);
  list-style: none;
}
.field-fold__summary::-webkit-details-marker {
  display: none;
}
.field-fold__summary::after {
  content: '+';
  float: right;
  color: var(--fg-subtle);
}
.field-fold[open] .field-fold__summary::after {
  content: '\2212'; /* минус */
}
.field-fold__label {
  margin-top: 0;
}

/* На телефоне форма регистрации не должна требовать прокрутки: чуть плотнее. */
@media (max-width: 40rem) {
  .page-auth .form {
    gap: 0.7rem;
  }
  .page-auth .field {
    gap: 0.3rem;
  }
  .page-auth .card__content {
    gap: 0.7rem;
  }
}

/* ==========================================================================
   ВКЛАДКИ РЕГИСТРАЦИЯ/ЛОГИН НА ОДНОЙ КАРТОЧКЕ (телеграм-онбординг)
   Без скрипта обе панели видны (как было); скрипт добавляет .is-tabbed.
   ========================================================================== */

.authtabs {
  display: none;
}
.authtabs-wrap.is-tabbed .authtabs {
  display: flex;
}
.authtabs-wrap.is-tabbed .authpane {
  display: none;
}
.authtabs-wrap.is-tabbed .authpane.is-active {
  display: block;
}

/* Вкладки здесь — кнопки, а не ссылки: сбрасываем вид кнопки. */
.authtabs .tabs__tab {
  background: none;
  border: 0;
  font: inherit;
  cursor: pointer;
}

/* ==========================================================================
   ФОРМА ВХОДА/РЕГИСТРАЦИИ — премиальная отделка
   Вкладки .tabs используются только на страницах входа (консоль — .tabs--inline
   / .tabs__link), поэтому переопределяем их безопасно в сегмент-контрол.
   ========================================================================== */

.tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.25rem;
  padding: 0.28rem;
  margin: 0 0 0.9rem;
  background: color-mix(in srgb, var(--fg) 6%, transparent);
  border: 1px solid var(--line);
  border-radius: 0.9rem;
}

.tabs__tab {
  padding: 0.6rem 1rem;
  text-align: center;
  font-size: 0.9rem;
  font-weight: 640;
  letter-spacing: -0.01em;
  color: var(--fg-muted);
  text-decoration: none;
  border: 0;
  border-radius: 0.66rem;
  transition:
    color 150ms ease,
    background-color 150ms ease,
    box-shadow 150ms ease;
}

.tabs__tab:hover {
  color: var(--fg);
  text-decoration: none;
  background: color-mix(in srgb, var(--fg) 5%, transparent);
}

/* Активный сегмент — приподнятая поверхность, тонкая лаймовая грань сверху,
   мягкая контактная тень. Не заливка лаймом: она у главной кнопки, и две
   лаймовые заливки на экране спорят друг с другом. */
.tabs__tab--active,
.tabs__tab--active:hover {
  color: var(--fg);
  background: var(--bg-card);
  box-shadow:
    0 1px 2px rgb(0 0 0 / 0.35),
    inset 0 1px 0 color-mix(in srgb, var(--accent) 55%, transparent),
    inset 0 0 0 1px color-mix(in srgb, #ffffff 9%, transparent);
}

/* --- карточка формы: чуть больше воздуха и глубины на страницах входа --- */
.page-auth .card,
.page-start .card {
  border-radius: 1.25rem;
  box-shadow:
    0 1px 2px rgb(0 0 0 / 0.4),
    0 18px 50px -28px rgb(0 0 0 / 0.65);
}

.page-auth .card__content,
.page-start .card__content {
  padding: 1.15rem 1.15rem 1.25rem;
}

/* --- поля: ярлык поспокойнее, ввод чуть выше и мягче в фокусе --- */
.page-auth .field__label,
.page-start .field__label {
  font-size: 0.82rem;
  font-weight: 560;
  color: var(--fg-muted);
  letter-spacing: 0.01em;
}

.page-auth .field__input,
.page-start .field__input {
  border-radius: 0.7rem;
  transition:
    border-color 150ms ease,
    box-shadow 150ms ease,
    background-color 150ms ease;
}

.page-auth .field__input:focus,
.page-start .field__input:focus {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}

/* Приветствие в шапке телеграм-онбординга — теплее и заметнее. */
.start__hello {
  font-weight: 560;
  color: var(--fg);
}

/* Согласие с документами — одна спокойная строка, не кричит. */
.page-start .checkbox__text,
.page-auth .checkbox__text {
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--fg-muted);
}

/* ==========================================================================
   ONBOARDING, THE TOUR, AND A LITTLE MOTION
   Added for the first-run experience: the three-step checklist, the guided
   tour overlay, the "Start here" step links, and a few quiet animations.
   Everything here is token-based so it follows light and dark on its own, and
   every animation is behind prefers-reduced-motion.
   ========================================================================== */

/* ---- first-run checklist ------------------------------------------------ */

.onboard {
  background: linear-gradient(to bottom, var(--accent-wash), var(--bg-card) 60%);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-card);
  padding: 0.7rem 0.8rem 0.75rem;
}

.onboard__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.onboard__title {
  margin: 0;
  font-weight: 650;
  font-size: 0.9rem;
}

.onboard__progress {
  margin: 0;
  color: var(--fg-muted);
  font-size: 0.72rem;
  white-space: nowrap;
}

.onboard__steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.3rem;
}

.onboard__step {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.38rem 0.5rem;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.onboard__mark {
  flex: none;
  width: 1.35rem;
  height: 1.35rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--bg-input);
  border: 1px solid var(--border);
  color: var(--fg-muted);
  font-weight: 650;
  font-size: 0.74rem;
}

.onboard__step.is-done .onboard__mark {
  background: var(--accent-soft);
  border-color: transparent;
  color: var(--accent-bright);
}

.onboard__label {
  flex: 1;
  font-size: 0.84rem;
}

.onboard__step.is-done .onboard__label {
  color: var(--fg-muted);
  text-decoration: line-through;
  text-decoration-color: var(--fg-subtle);
}

.onboard__state {
  color: var(--accent-bright);
  font-size: 0.72rem;
  font-weight: 600;
}

.onboard__go {
  padding: 0.22rem 0.65rem;
  font-size: 0.78rem;
}

.onboard__foot {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.65rem;
  margin-top: 0.6rem;
}

.onboard__tour {
  padding: 0.35rem 0.8rem;
  font-size: 0.82rem;
}

.onboard__guide {
  color: var(--accent-bright);
  font-size: 0.8rem;
  text-decoration: none;
}

.onboard__guide:hover {
  text-decoration: underline;
}

/* ---- "Start here" step links -------------------------------------------- */

.how__steplink {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  margin-top: 0.5rem;
  color: var(--accent-bright);
  text-decoration: none;
  font-size: 0.88rem;
  font-weight: 550;
}

.how__steplink:hover {
  text-decoration: underline;
}

/* ---- the guided tour ---------------------------------------------------- */

.tour {
  position: fixed;
  inset: 0;
  z-index: 1000;
  pointer-events: none;
}

.tour__ring {
  position: fixed;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  border-radius: var(--radius);
  /* The bright edge on the target and the dim over everything else, in one
     element: a small dark gap, a thick bright ring, then a shadow spread wide
     enough to cover any screen. The gap makes the ring stand off the card so it
     reads clearly on a dark background, in the Mini App and everywhere else. */
  box-shadow:
    0 0 0 2px var(--bg),
    0 0 0 5px var(--accent-bright),
    0 0 0 9999px rgb(0 0 0 / 0.6);
  pointer-events: none;
}

.tour__pop {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  width: min(340px, calc(100vw - 24px));
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-raised);
  padding: 1rem 1.1rem 1.05rem;
  pointer-events: auto;
}

.tour__pop--center {
  top: 50%;
  transform: translate(-50%, -50%);
}

.tour__title {
  margin: 0 0 0.35rem;
  font-weight: 650;
  font-size: 1rem;
}

.tour__body {
  margin: 0 0 0.9rem;
  color: var(--fg-muted);
  font-size: 0.9rem;
  line-height: 1.5;
}

.tour__row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.tour__spacer {
  flex: 1;
}

.tour__count {
  color: var(--fg-subtle);
  font-size: 0.8rem;
}

.tour__pop .button {
  padding: 0.45rem 0.95rem;
  font-size: 0.88rem;
}

.tour__guide {
  text-decoration: none;
}

/* The tour uses measured viewport coordinates, including Safari keyboard and
   Telegram safe areas. Animations must not replace an anchoring transform. */
.tour {
  padding-top: max(12px, env(safe-area-inset-top, 0px), calc(var(--tg-safe-top, 0px) + var(--tg-content-top, 0px)));
  padding-bottom: max(12px, env(safe-area-inset-bottom, 0px), var(--tg-safe-bottom, 0px));
  padding-left: max(12px, env(safe-area-inset-left, 0px), var(--tg-safe-left, 0px));
  padding-right: max(12px, env(safe-area-inset-right, 0px), var(--tg-safe-right, 0px));
}
.tour__pop,
.tour__pop--center {
  left: 12px;
  transform: none;
  display: flex;
  flex-direction: column;
  max-height: calc(100dvh - 24px);
  overflow: hidden;
}
.tour__heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  flex: 0 0 auto;
}
.tour__close {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--fg-muted);
  font: inherit;
  font-size: 1.5rem;
  cursor: pointer;
}
.tour__close:hover,
.tour__close:focus-visible {
  background: var(--accent-soft);
  color: var(--accent-bright);
}
.tour__body {
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  overflow-wrap: anywhere;
}
.tour__row {
  flex-wrap: wrap;
  flex: 0 0 auto;
}
html.tour-open .cookie-banner { visibility: hidden; }
.cookie-banner__error {
  flex-basis: 100%;
  margin: 0;
  color: var(--danger);
  font-size: 0.8125rem;
}
/* A 16px entry field avoids focus zoom in iPhone Safari. Keep larger PIN text. */
@media (pointer: coarse) {
  .field__input:not(.field__input--pin) { font-size: 16px; }
}

/* Long translated settings actions must wrap instead of being clipped by the
   page's horizontal overflow guard. Financial values keep their own formatting. */
.content .data-row:has(.button) { flex-wrap: wrap; }
.content .data-row:has(.button) > * { min-width: 0; max-width: 100%; }
.content .data-row__value .button { max-width: 100%; white-space: normal; overflow-wrap: anywhere; }
@media (max-width: 22rem) {
  .walletactions { grid-template-columns: minmax(0, 1fr); }
  .walletactions__go { min-width: 0; white-space: normal; }
}

/* Safari's keyboard can shrink visualViewport without changing dvh. Keep the
   support composer and its close control above it and below Telegram chrome. */
.support-pop {
  --support-top-edge: max(12px, env(safe-area-inset-top, 0px), calc(var(--tg-safe-top, 0px) + var(--tg-content-top, 0px)));
  --support-bottom-edge: max(12px, env(safe-area-inset-bottom, 0px), calc(var(--tg-safe-bottom, 0px) + var(--tg-content-bottom, 0px)));
  bottom: calc(var(--support-keyboard-bottom, 0px) + var(--support-bottom-edge) + var(--support-fab-gap, 3.3rem));
  max-height: max(0px, calc(var(--support-view-height, 100dvh) - var(--support-top-edge) - var(--support-bottom-edge) - var(--support-fab-gap, 3.3rem)));
}
.support-pop .guestchat .composer__input {
  max-height: min(10rem, calc(var(--support-view-height, 100dvh) * 0.25));
}

/* ---- quiet motion ------------------------------------------------------- */

@keyframes pn-rise {
  from {
    opacity: 0;
    transform: translateY(9px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes pn-pop {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* A money figure glowing for a moment when it actually changes. */
@keyframes pn-fresh {
  0% {
    color: var(--accent-bright);
    text-shadow: 0 0 12px var(--accent-soft);
  }
  100% {
    color: inherit;
    text-shadow: none;
  }
}

@media (prefers-reduced-motion: no-preference) {
  /* Dashboard blocks ease in on load and after a client-side navigation. Scoped
     to these classes so the operations console — which reloads its own content
     on a timer — is never touched. */
  .onboard,
  .farm-card,
  .window,
  .tierline,
  .lb-card {
    animation: pn-rise 0.3s ease both;
  }

  /* A small stagger down the step list on "Start here" and "How it works". */
  .how__steps .how__step {
    animation: pn-rise 0.32s ease both;
  }
  .how__steps .how__step:nth-child(2) {
    animation-delay: 0.05s;
  }
  .how__steps .how__step:nth-child(3) {
    animation-delay: 0.1s;
  }
  .how__steps .how__step:nth-child(4) {
    animation-delay: 0.15s;
  }
  .how__steps .how__step:nth-child(5) {
    animation-delay: 0.2s;
  }

  .tour__ring {
    transition:
      top 0.25s ease,
      left 0.25s ease,
      width 0.25s ease,
      height 0.25s ease,
      opacity 0.2s ease;
  }

  .tour__pop {
    animation: pn-pop 0.2s ease both;
  }

  .money.is-fresh {
    animation: pn-fresh 1.1s ease;
  }

  /* A hair of lift on the one-line tier card, which is a link. */
  .tierline {
    transition: transform 0.15s ease;
  }
  .tierline:hover {
    transform: translateY(-1px);
  }
}

/* ---- the quick-start block at the top of "How it works" ----------------- */

.how__quickstart {
  background: linear-gradient(to bottom, var(--accent-wash), transparent 72%);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  padding: 1rem 1.1rem 1.15rem;
  margin-bottom: 0.4rem;
}

.how__quicktitle {
  margin: 0 0 0.85rem;
  font-size: 1.05rem;
  font-weight: 650;
}

.how__watch {
  margin-top: 0.4rem;
}

/* ---- in-app announcement push ------------------------------------------- */

.announce {
  position: fixed;
  left: 50%;
  bottom: 1.25rem;
  transform: translateX(-50%);
  z-index: 70;
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  width: min(440px, calc(100vw - 1.5rem));
  padding: 0.85rem 0.85rem 0.85rem 1rem;
  background: linear-gradient(to bottom, var(--accent-wash), var(--bg-raised) 55%);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  box-shadow: var(--shadow-raised);
}

.announce__body {
  flex: 1;
  min-width: 0;
  margin: 0;
  color: var(--fg);
  font-size: 0.9rem;
  line-height: 1.45;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.announce__close {
  flex: none;
  border: 0;
  background: transparent;
  color: var(--fg-muted);
  font-size: 1.2rem;
  line-height: 1;
  padding: 0 0.15rem;
  cursor: pointer;
}
.announce__close:hover {
  color: var(--fg);
}

@media (prefers-reduced-motion: no-preference) {
  .announce {
    animation: pn-rise 0.28s ease both;
  }
}

/* ================================================= support messenger polish == */

/* A quoted message reads as a real nested reply, not a second grey paragraph. */
.message-reply {
  position: relative;
  padding: 0.45rem 0.62rem 0.45rem 0.72rem;
  border-left-width: 3px;
  border-left-color: var(--accent-bright);
  background: color-mix(in srgb, var(--accent) 10%, rgb(0 0 0 / 0.2));
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 16%, transparent),
    0 2px 8px rgb(0 0 0 / 0.08);
}

.thread__item--operator .message-reply,
.tg__msg--in .message-reply {
  background: rgb(255 255 255 / 0.055);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.07);
}

.reply-draft {
  border-bottom-color: color-mix(in srgb, var(--accent) 24%, var(--border));
  box-shadow: inset 0 -1px 0 rgb(0 0 0 / 0.16);
}

/* Identity and guest state share one compact line in the common inbox. */
.tg__identity {
  display: flex;
  align-items: center;
  min-width: 0;
  gap: 0.38rem;
}

.tg__identity .tg__name {
  min-width: 0;
}

.tg__guestbadge {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  padding: 0.12rem 0.38rem;
  border: 1px solid color-mix(in srgb, #f0a63c 42%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, #f0a63c 13%, transparent);
  color: #f4bd68;
  font-size: 0.58rem;
  font-weight: 750;
  line-height: 1.2;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.tg__headname .tg__guestbadge {
  margin-left: 0.35rem;
  vertical-align: 0.12rem;
}

/* Desktop admin: one continuous Telegram-like split window. */
.shell--admin .tg {
  gap: 0;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 1rem;
  background: var(--bg-card);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.04),
    0 18px 45px rgb(0 0 0 / 0.14);
}

.shell--admin .tg__list,
.shell--admin .tg__thread {
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.shell--admin .tg__list {
  border-right: 1px solid var(--line);
  background: color-mix(in srgb, var(--bg-card) 94%, #fff 1%);
}

.shell--admin .tg__listhead,
.shell--admin .tg__head {
  min-height: 3.75rem;
  background: rgb(22 25 30 / 0.78);
  backdrop-filter: blur(18px) saturate(120%);
}

.shell--admin .tg__chats {
  padding: 0.3rem 0;
}

.shell--admin .tg__chats > li + li {
  border-top: 1px solid rgb(255 255 255 / 0.045);
}

.shell--admin .tg__chat {
  min-height: 4.55rem;
  padding: 0.58rem 0.72rem;
  border-radius: 0;
}

.shell--admin .tg__chat:hover {
  background: rgb(255 255 255 / 0.045);
}

.shell--admin .tg__chat--active {
  background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 18%, transparent), color-mix(in srgb, var(--accent) 9%, transparent));
  box-shadow: inset 3px 0 0 var(--accent-bright);
}

.shell--admin .tg__msgs {
  background-color: #0d1013;
  background-image:
    radial-gradient(circle at 1px 1px, rgb(255 255 255 / 0.025) 1px, transparent 0),
    radial-gradient(45rem 28rem at 100% 0%, color-mix(in srgb, var(--accent) 7%, transparent), transparent 68%);
  background-size: 24px 24px, auto;
  padding: 1rem clamp(0.75rem, 2vw, 1.5rem);
  scroll-padding-block: 1rem;
}

.shell--admin .tg__bubble {
  border-color: rgb(255 255 255 / 0.075);
  background: rgb(28 32 37 / 0.96);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.045),
    0 4px 15px rgb(0 0 0 / 0.12);
}

.shell--admin .tg__msg--out .tg__bubble {
  border-color: color-mix(in srgb, var(--accent) 20%, transparent);
  background: linear-gradient(145deg, color-mix(in srgb, var(--accent) 24%, #172019), color-mix(in srgb, var(--accent) 14%, #141a16));
}

.shell--admin .tg__composer {
  padding: 0.62rem 0.75rem 0.72rem;
  border-top-color: rgb(255 255 255 / 0.07);
  background: rgb(18 21 25 / 0.88);
  backdrop-filter: blur(22px) saturate(125%);
}

.shell--admin .tg__input {
  min-height: 2.65rem;
  max-height: 9.5rem;
  resize: none;
  border-color: rgb(255 255 255 / 0.09);
  border-radius: 1.15rem;
  background: rgb(43 47 54 / 0.9);
  line-height: 1.42;
  scrollbar-gutter: stable;
}

.shell--admin .tg__send {
  min-height: 2.65rem;
  border-radius: 1.15rem;
}

/* The normal website gets a real chat window too, not an expanding page. */
.guestchat:not(.guestchat--mini) {
  width: min(68rem, 100%);
  height: min(48rem, calc(100dvh - 10rem));
  min-height: 32rem;
  margin-inline: auto;
  padding: 0;
  gap: 0;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 1rem;
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.04),
    0 18px 48px rgb(0 0 0 / 0.15);
}

.guestchat:not(.guestchat--mini) .guestchat__bar {
  min-height: 3.8rem;
  padding: 0.65rem 0.9rem;
  background: rgb(22 25 30 / 0.82);
  backdrop-filter: blur(18px) saturate(120%);
}

.guestchat:not(.guestchat--mini) .guestchat__thread {
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
  padding: 1rem clamp(0.75rem, 2vw, 1.5rem);
  overflow-y: auto;
  background-color: #0d1013;
  background-image:
    radial-gradient(circle at 1px 1px, rgb(255 255 255 / 0.025) 1px, transparent 0),
    radial-gradient(45rem 28rem at 100% 0%, color-mix(in srgb, var(--accent) 7%, transparent), transparent 68%);
  background-size: 24px 24px, auto;
}

.guestchat:not(.guestchat--mini) > form {
  flex: 0 0 auto;
  padding: 0.6rem 0.75rem 0.72rem;
  border-top: 1px solid rgb(255 255 255 / 0.07);
  background: rgb(18 21 25 / 0.9);
  backdrop-filter: blur(20px) saturate(120%);
}

.composer__input,
.tg__input {
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  overflow-y: hidden;
  overflow-x: hidden;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  word-break: break-word;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: rgb(255 255 255 / 0.22) transparent;
}

.guestchat,
.guestchat > form,
.support-mini,
.support-mini__window,
.composer,
.thread,
.thread__item,
.thread__body {
  box-sizing: border-box;
  min-width: 0;
  max-width: 100%;
}

.composer {
  width: 100%;
  overflow: hidden;
}

.thread__body,
.tg__text {
  overflow-wrap: anywhere;
  word-break: break-word;
}

.composer__input.is-scrollable,
.tg__input.is-scrollable {
  overflow-y: auto;
}

.tg__msgs,
.tg__chats,
.guestchat__thread {
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
  scrollbar-width: thin;
  scrollbar-color: rgb(255 255 255 / 0.18) transparent;
}

/* A full support page is fetched into the floating window. Inside that window
   it must obey the window's height, not keep the page's 32rem minimum. */
.support-pop .guestchat:not(.guestchat--mini) {
  width: 100%;
  height: 100%;
  min-height: 0;
  margin: 0;
  border: 0;
  border-radius: 0;
}

.support-pop .guestchat__thread,
.support-pop .guestchat__empty {
  flex: 1 1 0;
  min-height: 0;
  max-height: none;
}

.support-pop .guestchat > form {
  flex: 0 0 auto;
  min-height: 0;
}

.attachments__video {
  width: 100%;
  max-height: 24rem;
  border-radius: 0;
}

@media (max-width: 62rem) {
  .shell--admin .tg {
    height: calc(100dvh - 8.5rem);
    min-height: 31rem;
  }

  .shell--admin .tg__list {
    border-right: 0;
  }

  .shell--admin .tg--thread .tg__thread {
    display: flex;
    min-height: 0;
  }

  .shell--admin .tg__msgs {
    max-height: none;
  }

  .tg__headactions {
    max-width: 45%;
    overflow-x: auto;
  }
}

@media (max-width: 40rem) {
  .guestchat:not(.guestchat--mini) {
    width: 100%;
    height: calc(100dvh - 7.5rem);
    min-height: 30rem;
    margin-inline: 0;
    border-radius: 0.8rem;
  }

  .shell--admin .tg {
    height: calc(100dvh - 7rem);
    border-radius: 0.75rem;
  }

  .shell--admin .tg__head {
    padding-inline: 0.55rem;
  }

  .shell--admin .tg__headmeta {
    max-width: 13rem;
  }

  .shell--admin .tg__bubble {
    max-width: 90%;
  }
}

/* =============================================== support chat proportions == */

/* On a desktop this is a conversation window, not a full-width dashboard
   panel. The absolute cap also keeps a long message at a readable line length. */
@media (min-width: 40.001rem) {
  .page-app .content > .guestchat:not(.guestchat--mini),
  .page-auth .start__card .guestchat:not(.guestchat--mini) {
    width: min(52rem, 100%);
    height: min(42rem, calc(100dvh - 10rem));
    min-height: 29rem;
  }
}

.guestchat:not(.guestchat--mini) .thread__item {
  max-width: min(72%, 34rem);
}

/* ================================================= admin support account == */

/* One account is one row now, so the list can be denser without losing any
   information to old ticket subjects. */
.shell--admin .tg__chat {
  min-height: 3.95rem;
  padding: 0.48rem 0.62rem;
}

.shell--admin .tg__head {
  gap: 0.52rem;
  padding: 0.55rem 0.7rem;
}

.shell--admin .tg__headactions {
  gap: 0.3rem;
  max-width: none;
  overflow: visible;
}

.shell--admin .tg__headactions .button {
  min-height: 2.1rem;
  padding: 0.38rem 0.68rem;
}

.support-account[open] .support-account__inner {
  width: min(72rem, calc(100vw - 1rem));
  max-height: calc(100dvh - 1rem);
}

.support-account__head {
  gap: 0.65rem;
  padding: 0.72rem 0.8rem;
}

.support-account__head > div {
  min-width: 0;
}

.support-account__eyebrow {
  margin: 0 0 0.08rem;
  color: var(--accent-bright);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.support-account__title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sheet[open] .support-account__body {
  min-width: 0;
  gap: 0;
  padding: 0.55rem 0.65rem 0.7rem;
}

/* The account page and the account sheet use exactly the same record. These
   rules turn both into a dense console view and keep every wide ledger inside
   its own horizontal scroller instead of letting it widen the page. */
.admin-account-view {
  display: grid;
  gap: 0.55rem;
  min-width: 0;
  max-width: 100%;
}

.admin-account-view > *,
.admin-account-view .grid,
.admin-account-view .card,
.admin-account-view .card__content,
.admin-account-view .table-wrap {
  min-width: 0;
  max-width: 100%;
}

.admin-account-view .page-header {
  align-items: center;
  gap: 0.45rem 0.7rem;
  padding: 0.1rem 0.15rem;
}

.admin-account-view .page-header > div:first-child {
  min-width: 0;
}

.admin-account-view .page-header__title {
  overflow: hidden;
  font-size: 1rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin-account-view .page-header__description {
  margin-top: 0.08rem;
  max-width: 100%;
  font-size: 0.72rem;
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.account-head-actions,
.account-head-actions .tier__head {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  flex-wrap: wrap;
}

.account-head-actions {
  justify-content: flex-end;
}

.admin-account-view .stats {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.38rem;
}

.admin-account-view .stat {
  min-width: 0;
  padding: 0.48rem 0.58rem;
  border-radius: 0.65rem;
}

.admin-account-view .stat__label {
  margin-bottom: 0.08rem;
  font-size: 0.61rem;
}

.admin-account-view .stat__value {
  overflow: hidden;
  font-size: 1rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin-account-view .stat__hint {
  margin-top: 0.08rem;
  font-size: 0.65rem;
}

.admin-account-view .grid {
  gap: 0.45rem;
}

.admin-account-view .card {
  overflow: hidden;
  border-radius: 0.7rem;
}

.admin-account-view .card__title {
  padding: 0.45rem 0.62rem;
  font-size: 0.78rem;
}

.admin-account-view .card__content {
  gap: 0.42rem;
  padding: 0.52rem 0.62rem;
}

.admin-account-view .card__content--flush {
  padding: 0;
}

.admin-account-view .table-wrap {
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.account-history-pages {
  border-top: 1px solid var(--line);
}

.account-history-page + .account-history-page {
  border-top: 1px solid rgb(255 255 255 / 0.045);
}

.account-history-page > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.42rem 0.58rem;
  cursor: pointer;
  list-style: none;
  color: var(--fg-muted);
  font-size: 0.7rem;
}

.account-history-page > summary::-webkit-details-marker {
  display: none;
}

.account-history-page > summary::before {
  content: '▸';
  color: var(--accent-bright);
}

.account-history-page[open] > summary::before {
  content: '▾';
}

.account-history-page > summary > span {
  margin-left: auto;
  color: var(--fg-subtle);
  font-variant-numeric: tabular-nums;
}

.admin-account-view .table {
  font-size: 0.74rem;
}

.admin-account-view .table th,
.admin-account-view .table td {
  padding: 0.3rem 0.55rem;
}

.admin-account-view .data-row {
  gap: 0.55rem;
  padding-block: 0.28rem;
}

.admin-account-view .data-row__label,
.admin-account-view .data-row__value {
  min-width: 0;
  font-size: 0.75rem;
}

.admin-account-view .data-row__value {
  overflow-wrap: anywhere;
  white-space: normal;
}

.admin-account-view .callout {
  margin: 0;
  padding: 0.5rem 0.62rem;
}

.support-account__overview .auth__switch {
  display: none;
}

.tg__deposit {
  flex: 0 0 auto;
  color: var(--accent-bright);
  font-size: 0.69rem;
  font-variant-numeric: tabular-nums;
  font-weight: 650;
}

.tg__joined {
  display: block;
  margin-top: 0.05rem;
  color: var(--fg-subtle);
  font-size: 0.64rem;
}

/* Overview stays a table, not a stack of unrelated labels. The identity is one
   clipped line and the right-most activity cell owns every transient status. */
.admin-users-card .table th,
.admin-users-card .table td {
  padding-right: 0.38rem;
  padding-left: 0.38rem;
  vertical-align: middle;
}

.admin-users-card .table {
  table-layout: fixed;
  font-size: 0.79rem;
}

.admin-users-card .table th {
  overflow: hidden;
  font-size: 0.62rem;
  text-overflow: ellipsis;
}

.admin-users-card .table th:nth-child(1) { width: 27%; }
.admin-users-card .table th:nth-child(2) { width: 15%; }
.admin-users-card .table th:nth-child(3) { width: 7%; }
.admin-users-card .table th:nth-child(4) { width: 8%; }
.admin-users-card .table th:nth-child(5) { width: 8%; }
.admin-users-card .table th:nth-child(6) { width: 8%; }
.admin-users-card .table th:nth-child(7) { width: 7%; }
.admin-users-card .table th:nth-child(8) { width: 20%; }

.admin-users-card .table th:first-child,
.admin-users-card .table td:first-child {
  padding-left: 0.7rem;
}

.admin-users-card .table th:last-child,
.admin-users-card .table td:last-child {
  padding-right: 0.7rem;
}

.admin-user-cell {
  min-width: 0;
  max-width: 100%;
}

.admin-user-cell__identity {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  min-width: 0;
}

.admin-user-cell__identity > a {
  display: block;
  min-width: 0;
  overflow: hidden;
  font-size: 0.69rem;
  letter-spacing: -0.015em;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin-user-cell__identity > .badge {
  flex: 0 0 auto;
}

.admin-user-activity {
  display: grid;
  justify-items: start;
  gap: 0.16rem;
  min-width: 10.5rem;
  line-height: 1.15;
}

.admin-user-activity__states {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  min-height: 1rem;
}

.admin-user-activity .badge {
  padding: 0.08rem 0.34rem;
  font-size: 0.59rem;
}

.admin-user-activity__farm.badge {
  flex: 0 0 auto;
}

.admin-user-activity__seen {
  color: var(--fg-subtle);
  font-size: 0.62rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

@media (max-width: 46rem) {
  .table td > .admin-user-cell {
    flex: 1 1 auto;
    text-align: right;
  }

  .admin-user-cell__identity {
    justify-content: flex-end;
  }

  .admin-user-cell__identity > a {
    max-width: min(14rem, 60vw);
  }

  .admin-user-activity {
    min-width: 0;
    justify-items: end;
  }
}

.support-account__facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.38rem;
  margin: 0;
}

.support-account__facts > div {
  min-width: 0;
  padding: 0.5rem 0.58rem;
  border: 1px solid rgb(255 255 255 / 0.07);
  border-radius: 0.65rem;
  background: rgb(255 255 255 / 0.025);
}

.support-account__facts dt {
  margin: 0 0 0.12rem;
  color: var(--fg-subtle);
  font-size: 0.64rem;
  font-weight: 650;
  letter-spacing: 0.045em;
  text-transform: uppercase;
}

.support-account__facts dd {
  margin: 0;
  overflow: hidden;
  color: var(--fg);
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.support-account__id {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  min-width: 0;
  margin: 0;
  padding: 0.42rem 0.55rem;
  border-radius: 0.6rem;
  background: rgb(0 0 0 / 0.18);
  color: var(--fg-subtle);
  font-size: 0.68rem;
}

.support-account__id code {
  min-width: 0;
  overflow: hidden;
  color: var(--fg-muted);
  font-size: 0.7rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.support-account__full {
  align-self: flex-end;
}

@media (max-width: 32rem) {
  .support-account__facts {
    grid-template-columns: minmax(0, 1fr);
  }

  .shell--admin .tg__headwho {
    min-width: 4.5rem;
  }

  .shell--admin .tg__headactions .button {
    padding-inline: 0.5rem;
    font-size: 0.75rem;
  }

  .admin-account-view .stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .account-head-actions {
    width: 100%;
    justify-content: space-between;
  }
}

/* The initial greeting is a real incoming bubble. As a flex item it otherwise
   stretches almost from edge to edge even though the sentence is short. */
.guestchat:not(.guestchat--mini) .guestchat__empty {
  align-self: flex-start;
  width: fit-content;
  max-width: min(72%, 32rem);
  margin: 1rem auto auto 1rem;
  padding: 0.62rem 0.82rem;
}

/* Three distinct controls: the draft has its own bubble, while attachment and
   send are separate tactile buttons. Shared by desktop, mobile, Mini App and
   the floating support window. */
.guestchat .composer,
.page-support-mini .guestchat--mini .composer {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 2.65rem 2.65rem;
  align-items: end;
  gap: 0.48rem;
  width: 100%;
  max-width: 48rem;
  margin-inline: auto;
  padding: 0;
  overflow: visible;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.guestchat .composer:focus-within,
.page-support-mini .guestchat--mini .composer:focus-within {
  box-shadow: none;
}

.guestchat .composer__input,
.page-support-mini .guestchat--mini .composer__input {
  min-height: 2.65rem;
  padding: 0.62rem 0.9rem;
  border: 1px solid rgb(255 255 255 / 0.11);
  border-radius: 1.2rem;
  background: rgb(38 42 48 / 0.94);
  box-shadow:
    inset 0 1px 2px rgb(0 0 0 / 0.36),
    0 4px 14px rgb(0 0 0 / 0.1);
  transition: border-color 140ms ease, box-shadow 140ms ease;
}

.guestchat .composer__input:focus,
.page-support-mini .guestchat--mini .composer__input:focus {
  border-color: color-mix(in srgb, var(--accent-bright) 52%, transparent);
  outline: none;
  box-shadow:
    inset 0 1px 2px rgb(0 0 0 / 0.3),
    0 0 0 3px color-mix(in srgb, var(--accent) 13%, transparent);
}

.guestchat .composer__clip,
.guestchat .composer__send,
.page-support-mini .guestchat--mini .composer__clip,
.page-support-mini .guestchat--mini .composer__send {
  width: 2.65rem;
  height: 2.65rem;
  border: 1px solid rgb(255 255 255 / 0.1);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.08),
    0 5px 16px rgb(0 0 0 / 0.18);
}

.guestchat .composer__clip,
.page-support-mini .guestchat--mini .composer__clip {
  background: rgb(39 43 49 / 0.96);
  color: var(--fg-muted);
}

.guestchat .composer__clip:hover,
.guestchat .composer__clip:focus-visible,
.page-support-mini .guestchat--mini .composer__clip:hover,
.page-support-mini .guestchat--mini .composer__clip:focus-visible {
  border-color: rgb(255 255 255 / 0.2);
  background: rgb(49 54 61 / 0.98);
  color: var(--fg);
}

.guestchat .composer__send,
.page-support-mini .guestchat--mini .composer__send {
  border-color: color-mix(in srgb, var(--accent-bright) 46%, transparent);
  background: linear-gradient(145deg, color-mix(in srgb, var(--accent) 88%, white), var(--accent));
  color: #071009;
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.42),
    0 7px 20px color-mix(in srgb, var(--accent) 27%, transparent);
}

/* Bespoke tier, offered for individual discussion to every account. */
.tier-individual {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.85rem 1.4rem;
  padding: clamp(0.95rem, 2vw, 1.3rem);
  border: 1px solid var(--individual-gold-edge);
  border-radius: 1.15rem;
  background:
    radial-gradient(ellipse at 10% -35%, rgb(255 254 210 / 0.92), transparent 55%),
    radial-gradient(ellipse at 98% 120%, rgb(235 151 0 / 0.12), transparent 54%),
    linear-gradient(118deg, var(--individual-gold-light), var(--individual-gold-mid) 53%, var(--individual-gold-deep));
  box-shadow:
    inset 0 1px 0 rgb(255 255 238 / 0.78),
    inset 0 -1px 0 rgb(112 72 18 / 0.2),
    0 19px 44px -23px rgb(255 193 20 / 0.65);
}

.tier-individual::before {
  content: '';
  position: absolute;
  z-index: -1;
  width: 17rem;
  height: 17rem;
  right: -6rem;
  top: -8rem;
  border: 1px solid rgb(91 60 18 / 0.14);
  border-radius: 50%;
  box-shadow: 0 0 0 2rem rgb(255 250 219 / 0.1), 0 0 0 4.5rem rgb(255 250 219 / 0.07);
  pointer-events: none;
}

.tier-individual__intro { min-width: 0; }

.tier-individual__heading {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.7rem;
  margin: 0 0 0.58rem;
}

.tier-individual__mark {
  display: grid;
  place-items: center;
  width: 2.2rem;
  height: 2.2rem;
  flex: none;
  border: 1px solid rgb(77 53 21 / 0.28);
  border-radius: 0.76rem;
  background: linear-gradient(145deg, rgb(255 250 225 / 0.66), rgb(132 87 28 / 0.13));
  color: #513716;
  box-shadow: inset 0 1px 0 rgb(255 255 238 / 0.66);
}

.tier-individual__mark .icon { width: 1.3rem; height: 1.3rem; }

.tier-individual h3 {
  margin: 0;
  color: #332515;
  font-size: clamp(1.35rem, 2vw, 1.8rem);
  letter-spacing: -0.035em;
  line-height: 1.12;
}

.tier-individual__statement {
  width: fit-content;
  margin: 0;
  padding: 0.5rem 0.7rem;
  border: 1px solid rgb(83 57 25 / 0.2);
  border-radius: 0.7rem;
  background: rgb(255 249 222 / 0.5);
  box-shadow: inset 0 1px 0 rgb(255 255 243 / 0.4);
  color: #453116;
  font-size: 0.85rem;
  line-height: 1.4;
}

.tier-individual__contact {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  min-height: 2.55rem;
  padding: 0.55rem 0.8rem;
  border: 1px solid rgb(255 239 180 / 0.56);
  border-radius: 0.68rem;
  background: linear-gradient(145deg, #3c2e1b, #241f18);
  box-shadow: inset 0 1px 0 rgb(255 243 199 / 0.15), 0 9px 20px -12px rgb(86 50 8 / 0.58);
  color: #fff0c6;
  font-size: 0.81rem;
  font-weight: 750;
  text-decoration: none;
  white-space: nowrap;
}
.tier-individual__contact:hover,
.tier-individual__contact:focus-visible {
  border-color: #fff8d0;
  background: linear-gradient(145deg, #50391c, #302619);
  color: #fff9e4;
}

@media (max-width: 58rem) {
  .tier-individual { grid-template-columns: 1fr; gap: 0.75rem; }
  .tier-individual__contact { width: fit-content; }
}

.admin-user-cell__chat {
  display: inline-flex;
  align-items: center;
  gap: 0.28rem;
  width: fit-content;
  margin-top: 0.28rem;
  padding: 0.2rem 0.42rem;
  border: 1px solid rgb(176 222 135 / 0.26);
  border-radius: 0.42rem;
  background: rgb(176 222 135 / 0.08);
  color: #c7e8a5;
  font-size: 0.64rem;
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
}

.admin-user-cell__chat .icon { width: 0.72rem; height: 0.72rem; }
.admin-user-cell__chat:hover,
.admin-user-cell__chat:focus-visible {
  border-color: rgb(176 222 135 / 0.63);
  background: rgb(176 222 135 / 0.17);
  color: #e3fac9;
}

/* One clear current-tier signal, on the tier itself, in both account modes. */
.tier--current {
  --current-tier-mark: #b9ee80;
  box-shadow: inset 0 0 0 1px var(--current-tier-mark), 0 0 0 1px rgb(185 238 128 / 0.22), 0 13px 34px -24px rgb(156 223 97 / 0.5);
}
.tier--current-demo { --current-tier-mark: #f2b451; }
.tier--current-demo { box-shadow: inset 0 0 0 1px var(--current-tier-mark), 0 0 0 1px rgb(242 180 81 / 0.22), 0 13px 34px -24px rgb(242 180 81 / 0.45); }
.tier--current::before { display: none; }
.tier--current .card__title { background: linear-gradient(100deg, color-mix(in srgb, var(--current-tier-mark) 16%, transparent), transparent 88%); }
.tier--current .badge--tier {
  border-color: var(--current-tier-mark);
  background: var(--current-tier-mark);
  color: #192116;
  box-shadow: 0 2px 13px color-mix(in srgb, var(--current-tier-mark) 30%, transparent);
  font-weight: 800;
}
.tier-grid__starter {
  width: fit-content;
  margin: 0;
  padding: 0.4rem 0.65rem;
  border: 1px solid #b9ee80;
  border-radius: 0.5rem;
  background: rgb(185 238 128 / 0.12);
  color: #d7f6af;
  font-size: 0.75rem;
  font-weight: 750;
}

/* The tier ladder borrows the individual plan's cut-metal light and depth,
   while keeping each tier's original hue. The line engraving stays behind copy. */
.tier-grid .tier {
  --metal-light: #e8f8b7;
  --metal-mid: #acd876;
  --metal-deep: #77a14a;
  --metal-edge: #d4ef97;
  --metal-ink: #25341a;
  --metal-subtle: #465d30;
  --metal-engraving: #365b27;
  --metal-panel: #293b20;
  --metal-panel-text: #efffd6;
  --metal-shadow: rgb(89 132 45 / 0.57);
  isolation: isolate;
  overflow: hidden;
  border: 1px solid var(--metal-edge);
  background:
    radial-gradient(ellipse at 8% -30%, rgb(255 252 227 / 0.8), transparent 53%),
    radial-gradient(ellipse at 100% 115%, rgb(23 56 17 / 0.2), transparent 55%),
    linear-gradient(120deg, var(--metal-light), var(--metal-mid) 57%, var(--metal-deep));
  color: var(--metal-ink);
  box-shadow:
    inset 0 1px 0 rgb(255 255 235 / 0.65),
    inset 0 -1px 0 rgb(18 45 15 / 0.19),
    0 18px 39px -25px var(--metal-shadow);
}
.tier-grid .tier--shared_node {
  --metal-light: #e8f8b7;
  --metal-mid: #acd876;
  --metal-deep: #77a14a;
  --metal-edge: #d4ef97;
}
.tier-grid .tier--dedicated_node {
  --metal-light: #c9f5df;
  --metal-mid: #80d4ad;
  --metal-deep: #4b9d78;
  --metal-edge: #a9efd0;
  --metal-ink: #19392d;
  --metal-subtle: #37614f;
  --metal-engraving: #246449;
  --metal-panel: #1e4033;
  --metal-panel-text: #e2fff0;
  --metal-shadow: rgb(45 126 91 / 0.55);
}
.tier-grid .tier--priority_node {
  --metal-light: #e1dfff;
  --metal-mid: #aaaaf0;
  --metal-deep: #777ac5;
  --metal-edge: #cbc9ff;
  --metal-ink: #292a50;
  --metal-subtle: #4d4d7c;
  --metal-engraving: #4f4f91;
  --metal-panel: #2a2c51;
  --metal-panel-text: #f0f0ff;
  --metal-shadow: rgb(85 84 161 / 0.54);
}
.tier-grid .tier--private_cluster {
  --metal-light: #f0d99e;
  --metal-mid: #d8b371;
  --metal-deep: #b58640;
  --metal-edge: #f7e1aa;
  --metal-ink: #332515;
  --metal-subtle: #624623;
  --metal-engraving: #64431c;
  --metal-panel: #3d2f1c;
  --metal-panel-text: #fff0c8;
  --metal-shadow: rgb(135 87 29 / 0.6);
}
.tier-grid .tier::before {
  display: block;
  inset: auto;
  top: -5.7rem;
  right: -4.5rem;
  width: 12.5rem;
  height: 12.5rem;
  padding: 0;
  border: 1px solid color-mix(in srgb, var(--metal-engraving) 17%, transparent);
  border-radius: 50%;
  background: none;
  box-shadow: 0 0 0 1.5rem rgb(255 250 224 / 0.1), 0 0 0 3.25rem rgb(255 250 224 / 0.07);
  -webkit-mask: none;
  mask: none;
  pointer-events: none;
  z-index: 0;
}
.tier-grid .tier::after {
  left: 1.15rem;
  right: 1.15rem;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgb(255 253 226 / 0.8) 35%, transparent);
}
.tier__etching {
  position: absolute;
  z-index: 0;
  top: 0.4rem;
  right: 0.4rem;
  width: 15rem;
  height: 18.75rem;
  color: var(--metal-engraving, #553817);
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.16;
  pointer-events: none;
}
.tier-grid .tier .card__title,
.tier-grid .tier .card__content > :not(.tier__etching),
.tier-individual__intro,
.tier-individual__contact {
  position: relative;
  z-index: 1;
}
.tier-grid .tier .card__title {
  border-bottom-color: color-mix(in srgb, var(--metal-ink) 20%, transparent);
  background: transparent;
  color: var(--metal-ink);
}
.tier-grid .tier--current .card__title {
  background: linear-gradient(90deg, color-mix(in srgb, var(--current-tier-mark) 18%, transparent), transparent 82%);
}
.tier-grid .tier__tagline {
  color: var(--metal-ink);
}
.tier-grid .tier .tierspec {
  background: rgb(255 255 255 / 0.39);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--metal-ink) 18%, transparent), inset 0 1px 0 rgb(255 255 255 / 0.37);
}
.tier-grid .tier .tierspec__row + .tierspec__row,
.tier-grid .tier .data-row + .data-row {
  border-top-color: color-mix(in srgb, var(--metal-ink) 18%, transparent);
}
.tier-grid .tier .tierspec__icon {
  border-color: color-mix(in srgb, var(--metal-ink) 19%, transparent);
  background: rgb(255 255 255 / 0.45);
  color: var(--metal-ink);
}
.tier-grid .tier .tierspec__label,
.tier-grid .tier .data-row__label,
.tier-grid .tier .data-row__hint {
  color: var(--metal-subtle);
}
.tier-grid .tier .tierspec__value,
.tier-grid .tier .data-row__value {
  color: var(--metal-ink);
}
.tier-grid .tier .amount--in {
  color: var(--metal-ink);
}
.tier-grid .tier__example {
  border: 1px solid rgb(255 255 255 / 0.38);
  background: linear-gradient(145deg, var(--metal-panel), color-mix(in srgb, var(--metal-panel) 75%, #111));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.15), 0 8px 18px -13px var(--metal-shadow);
  color: var(--metal-panel-text);
}
.tier-grid .tier--current {
  border-color: var(--current-tier-mark);
  box-shadow:
    inset 0 1px 0 rgb(255 255 235 / 0.7),
    0 0 0 1px color-mix(in srgb, var(--current-tier-mark) 55%, transparent),
    0 19px 43px -24px var(--metal-shadow);
}
.tier-individual > .tier__etching {
  top: -3rem;
  right: 0;
  width: clamp(14rem, 23vw, 21rem);
  height: auto;
  opacity: 0.15;
}
@media (hover: hover) {
  .tier-grid .tier:hover {
    box-shadow:
      inset 0 1px 0 rgb(255 255 238 / 0.8),
      0 0 0 1px color-mix(in srgb, var(--metal-edge) 60%, transparent),
      0 25px 50px -25px var(--metal-shadow);
  }
}

/* Calculator: one concise 30-day comparison below the live daily estimate. */
.calc .card__title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding-block: 0.55rem;
  font-size: 0.98rem;
}
.calc .card__content { gap: 0.28rem; padding-block: 0.65rem 0.75rem; }
.calc__form { margin: 0; }
.calc__label { font-size: 0.68rem; }
.calc__amount { font-size: 1.45rem; }
.calc__slider { margin: 0.38rem 0 0.12rem; }
.calc__scale { font-size: 0.63rem; }
.calc__result { margin-top: 0.45rem; padding-top: 0.5rem; }
.calc__tier { padding: 0.18rem 0.5rem; gap: 0.38rem; font-size: 0.74rem; }
.calc__tier[data-tier-id^="individual_"] {
  border-color: var(--individual-gold-edge);
  background: linear-gradient(115deg, var(--individual-gold-light), var(--individual-gold-mid) 60%, var(--individual-gold-deep));
  color: var(--individual-gold-ink);
}
.calc__tier[data-tier-id^="individual_"] .calc__tierrate { color: inherit; }
.calc__tier[data-tier-id^="individual_"] .tier__dot {
  background: var(--individual-gold-ink);
  box-shadow: 0 0 0 3px rgb(255 255 255 / 0.3);
}
.calc__tierrate { font-size: 0.72rem; }
.calc__netlabel { margin-top: 0.4rem; font-size: 0.68rem; }
.calc__net { margin-top: 0.08rem; }
.calc__netvalue { font-size: 1.8rem; }
.calc__netunit { font-size: 0.72rem; }
.calc__range { margin: 0.08rem 0 0.45rem; font-size: 0.74rem; }
.calc__tiles--single { grid-template-columns: 1fr; }
.calc__tiles--single .calc__tile { gap: 0.08rem; padding: 0.45rem 0.65rem; }
.calc__tiles--single .calc__tilelabel { font-size: 0.68rem; }
.calc__tiles--single .calc__compare-line { padding-top: 0.22rem; }
.calc__tiles--single .calc__compare-line + .calc__compare-line { margin-top: 0.08rem; }
.calc__tiles--single .calc__compare-line strong { font-size: 0.88rem; }
.calc__help--title summary { width: 1.1rem; height: 1.1rem; }
.calc__help--title p { left: auto; right: 0; top: calc(100% + 0.45rem); bottom: auto; width: min(17rem, 76vw); }

@media (max-width: 34rem) {
  .calc__amount { font-size: 1.35rem; }
  .calc__netvalue { font-size: 1.65rem; }
}

@media (max-width: 46rem) {
  .admin-user-cell__chat { margin-left: auto; }
}

/* Keep the dashboard plaque ahead of its older generic row styling. */
.content > .tierline {
  border: 1px solid var(--plaque-edge);
  background:
    radial-gradient(ellipse at 8% -75%, rgb(255 253 230 / 0.82), transparent 61%),
    linear-gradient(115deg, var(--plaque-light), var(--plaque-mid) 60%, var(--plaque-deep));
  box-shadow: inset 0 1px 0 rgb(255 255 240 / 0.7), 0 12px 26px -18px var(--plaque-deep);
}
.content > .tierline:hover {
  box-shadow: inset 0 1px 0 rgb(255 255 240 / 0.8), 0 0 0 1px var(--plaque-edge), 0 16px 30px -18px var(--plaque-deep);
}
.tierline__etching {
  position: absolute;
  z-index: 0;
  right: 2.5rem;
  top: -1.65rem;
  width: 6rem;
  height: 7.5rem;
  stroke: var(--plaque-ink);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.15;
  pointer-events: none;
}
.account-tier-badge {
  --tier-badge-bg: #d4ef97;
  --tier-badge-ink: #25341a;
  display: inline-flex;
  width: fit-content;
  padding: 0.22rem 0.48rem;
  border: 1px solid color-mix(in srgb, var(--tier-badge-bg) 76%, transparent);
  border-radius: 0.4rem;
  background: color-mix(in srgb, var(--tier-badge-bg) 85%, white);
  color: var(--tier-badge-ink);
  font-weight: 750;
}
.account-tier-badge--dedicated_node { --tier-badge-bg: #80d4ad; --tier-badge-ink: #19392d; }
.account-tier-badge--priority_node { --tier-badge-bg: #aaaaf0; --tier-badge-ink: #292a50; }
.account-tier-badge--private_cluster { --tier-badge-bg: #e8bf70; --tier-badge-ink: #332515; }
.account-tier-badge--individual_i,
.account-tier-badge--individual_ii,
.account-tier-badge--individual_iii,
.account-tier-badge--individual_iv,
.account-tier-badge--individual_v { --tier-badge-bg: var(--individual-gold-mid); --tier-badge-ink: var(--individual-gold-ink); }
.account-tier-badge--below_minimum { --tier-badge-bg: #bbc5ba; --tier-badge-ink: #26312a; }

@media (max-width: 40rem) {
  .guestchat:not(.guestchat--mini) .thread__item,
  .guestchat:not(.guestchat--mini) .guestchat__empty {
    max-width: 86%;
  }

  .guestchat .composer,
  .page-support-mini .guestchat--mini .composer {
    grid-template-columns: minmax(0, 1fr) 2.55rem 2.55rem;
    gap: 0.38rem;
  }

  .guestchat .composer__clip,
  .guestchat .composer__send,
  .page-support-mini .guestchat--mini .composer__clip,
  .page-support-mini .guestchat--mini .composer__send {
    width: 2.55rem;
    height: 2.55rem;
  }
}
/* Referrals: small cards and horizontal rank ladder for the Telegram viewport. */
.ref-invite,.ref-claim,.ref-metric,.ref-rank,.ref-network { border:1px solid var(--border,#2b3634); border-radius:14px; background:var(--bg-card,#17201e); }
.ref-invite { padding:14px; margin-bottom:16px; }
.ref-invite__fields { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,2fr); gap:10px; }
.ref-invite .field { min-width:0; margin:0; }
.ref-section { margin:0 0 16px; }
.ref-section__head { display:flex; align-items:center; gap:8px; margin:0 0 9px; }
.ref-section__head h2 { font-size:1rem; margin:0; }
.ref-help { display:inline-grid; place-items:center; width:19px; height:19px; flex:none; border:1px solid var(--border,#2b3634); border-radius:50%; color:var(--fg-muted,#a9b4ae); font-size:.72rem; font-weight:700; text-decoration:none; }
.ref-help:hover,.ref-help:focus-visible { color:#a9f37b; border-color:#a9f37b; }
.ref-eyebrow { display:inline-flex; align-items:center; gap:6px; color:var(--fg-muted,#a9b4ae); font-size:.68rem; text-transform:uppercase; letter-spacing:.08em; }
.ref-detail { margin:8px 0 12px; color:var(--fg-muted,#a9b4ae); font-size:.8rem; }
.ref-metrics { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:8px; }
.ref-admin-summary { grid-template-columns:repeat(4,minmax(0,1fr)); margin:0 0 14px; }
.ref-admin-indirect { color:var(--fg-muted,#a9b4ae); font-size:.8em; }
.ref-metric { min-width:0; min-height:76px; padding:12px; display:flex; flex-direction:column; justify-content:space-between; gap:7px; }
.ref-metric span { font-size:.72rem; line-height:1.25; color:var(--fg-muted,#a9b4ae); }
.ref-metric strong { font-size:1.28rem; line-height:1.1; font-variant-numeric:tabular-nums; overflow-wrap:anywhere; }
.ref-claims { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px; margin-bottom:16px; }
.ref-claim { display:flex; align-items:center; justify-content:space-between; gap:10px; min-width:0; padding:13px 14px; border-color:rgba(31,201,138,.35); background:linear-gradient(100deg,rgba(31,201,138,.12),transparent 85%),var(--bg-card,#17201e); }
.ref-claim--rank { border-color:rgba(225,190,111,.3); background:linear-gradient(100deg,rgba(225,190,111,.1),transparent 85%),var(--bg-card,#17201e); }
.ref-claim strong { display:block; margin-top:5px; color:#90e9ac; font-size:1.65rem; line-height:1; }
.ref-claim--rank strong { color:#e1be6f; }
.ref-claim .button { min-width:86px; min-height:36px; padding:7px 12px; }
.ref-notice { padding:9px 12px; margin:0 0 12px; border:1px solid rgba(31,201,138,.5); border-radius:10px; color:#90e9ac; }
.ref-network { padding:11px 13px 10px; border-color:rgba(169,243,123,.2); background:linear-gradient(135deg,rgba(169,243,123,.055),transparent 45%),var(--bg-card,#17201e); }
.ref-network__head { display:flex; align-items:center; gap:10px; }
.ref-network__mark { display:grid; place-items:center; width:37px; height:37px; flex:none; padding:7px; border:1px solid rgba(169,243,123,.3); border-radius:11px; color:#a9f37b; background:rgba(169,243,123,.09); }
.ref-network__mark svg { width:100%; height:100%; }
.ref-network__head div { display:flex; flex-wrap:wrap; align-items:baseline; gap:2px 8px; }
.ref-network__head small { width:100%; color:var(--fg-muted,#a9b4ae); font-size:.62rem; text-transform:uppercase; letter-spacing:.06em; }
.ref-network__head strong { color:#d9f9cb; font-size:.94rem; }
.ref-network__head span:not(.ref-network__mark) { color:var(--fg-muted,#a9b4ae); font-size:.68rem; }
.ref-network__diagram { position:relative; width:min(100%,420px); height:304px; margin:10px auto 0; overflow:hidden; }
.ref-network__tree { position:absolute; inset:0; width:100%; height:100%; }
.ref-network__link { fill:none; stroke:#65706b; stroke-width:1.3; stroke-dasharray:3 5; opacity:.5; }
.ref-network__link--open { stroke:#a9f37b; stroke-dasharray:none; opacity:.8; }
.ref-network__node { fill:#252d2a; stroke:#718078; stroke-width:1.4; opacity:.8; }
.ref-network__node--open { fill:#a9f37b; stroke:#a9f37b; opacity:1; }
.ref-network__rows { position:absolute; inset:40px 0 auto; display:grid; grid-template-rows:repeat(8,32px); }
.ref-network__row { display:flex; align-items:center; justify-content:space-between; gap:8px; min-width:0; font-size:.72rem; }
.ref-network__row > span:first-child,.ref-network__meta { position:relative; z-index:1; padding:1px 3px; background:var(--bg-card,#17201e); }
.ref-network__meta { display:flex; flex:0 0 84px; flex-direction:column; align-items:flex-end; justify-content:center; gap:1px; min-height:25px; white-space:nowrap; }
.ref-network__rate { font-size:.77rem; line-height:1; font-variant-numeric:tabular-nums; }
.ref-network__row--open { color:#e8f7e4; }
.ref-network__row--open .ref-network__rate { color:#a9f37b; }
.ref-network__row--locked { color:#929e97; }
.ref-network__locked { display:inline-flex; align-items:center; gap:3px; color:#d4b873; font-size:.62rem; line-height:1; }
.ref-network__lock { width:10px; height:10px; flex:none; }
.ref-network__guide { display:grid; gap:9px; margin-top:6px; padding:12px 2px 2px; border-top:1px solid rgba(169,243,123,.16); }
.ref-network__guide-steps { display:grid; grid-template-columns:minmax(0,1fr) 16px minmax(0,1fr); align-items:stretch; gap:6px; }
.ref-network__guide-step { min-width:0; min-height:54px; padding:8px 10px; border:1px solid rgba(169,243,123,.19); border-radius:9px; background:linear-gradient(125deg,rgba(169,243,123,.085),rgba(169,243,123,.015)); }
.ref-network__guide-step:last-child { border-color:rgba(169,243,123,.12); background:rgba(169,243,123,.025); }
.ref-network__guide-step small { display:block; color:#a9f37b; font-size:.58rem; font-weight:700; letter-spacing:.1em; text-transform:uppercase; }
.ref-network__guide-step strong { display:block; margin-top:4px; color:#e7f2e8; font-size:.75rem; font-weight:600; line-height:1.18; }
.ref-network__guide-arrow { display:grid; place-items:center; color:#809d7a; font-size:1rem; }
.ref-network__glass { position:relative; display:flex; align-items:flex-start; gap:10px; overflow:hidden; padding:11px 12px; border:1px solid rgba(202,247,188,.19); border-radius:11px; background:linear-gradient(115deg,rgba(230,255,226,.11),rgba(169,243,123,.04) 52%,rgba(255,255,255,.025)); box-shadow:inset 0 1px rgba(255,255,255,.11),0 9px 22px rgba(0,0,0,.1); -webkit-backdrop-filter:blur(12px) saturate(130%); backdrop-filter:blur(12px) saturate(130%); }
.ref-network__glass::before { content:''; position:absolute; inset:0 0 auto; height:1px; background:linear-gradient(90deg,transparent,rgba(230,255,226,.42),transparent); }
.ref-network__glass-icon { display:grid; place-items:center; width:26px; height:26px; flex:none; border:1px solid rgba(169,243,123,.25); border-radius:8px; background:rgba(169,243,123,.11); color:#b7f692; font-size:.78rem; font-weight:700; }
.ref-network__glass strong { display:block; color:#e8f6e5; font-size:.7rem; font-weight:700; line-height:1.2; }
.ref-network__glass p { margin:4px 0 0; color:#b8c9ba; font-size:.69rem; line-height:1.4; }
.ref-ranks { display:flex; gap:9px; overflow-x:auto; padding:2px 2px 9px; scroll-snap-type:x proximity; scrollbar-width:thin; }
.ref-rank { --ref-color:#af956c; position:relative; flex:0 0 190px; min-width:0; padding:12px; overflow:hidden; scroll-snap-align:start; background:linear-gradient(140deg,color-mix(in srgb,var(--ref-color) 14%,transparent),transparent 55%),var(--bg-card,#17201e); }
.ref-rank--1 { --ref-color:#cf8b5a; }.ref-rank--2 { --ref-color:#b8c8d6; }.ref-rank--3 { --ref-color:#e0bf66; }
.ref-rank--4 { --ref-color:#a9a4db; }.ref-rank--5 { --ref-color:#65c9a4; }.ref-rank--6 { --ref-color:#8dd9f2; }
.ref-rank--7 { --ref-color:#d794e2; }.ref-rank--8 { --ref-color:#e59eac; }.ref-rank--9 { --ref-color:#e1c67b; }
.ref-rank--10 { --ref-color:#92e8c8; }.ref-rank--11 { --ref-color:#b7dfff; }
.ref-rank__top { display:flex; justify-content:space-between; align-items:flex-start; gap:6px; }
.ref-rank__icon { position:relative; display:grid; place-items:center; width:43px; height:43px; border-radius:13px; color:var(--ref-color); background:radial-gradient(circle at 35% 28%,color-mix(in srgb,var(--ref-color) 32%,transparent),transparent 74%),#1b2424; box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ref-color) 35%,transparent); }
.ref-rank__icon::before { content:''; position:absolute; inset:5px; border:1px solid color-mix(in srgb,var(--ref-color) 55%,transparent); border-radius:10px; transform:rotate(45deg); opacity:.45; }
.ref-rank:nth-child(n+4) .ref-rank__icon::before { inset:2px; border-style:double; border-width:3px; opacity:.75; }
.ref-rank:nth-child(n+7) .ref-rank__icon::after { content:'✦'; position:absolute; top:-8px; right:-7px; color:var(--ref-color); font-size:12px; text-shadow:0 0 9px var(--ref-color); }
.ref-rank:nth-child(n+10) .ref-rank__icon { box-shadow:inset 0 0 0 1px var(--ref-color),0 0 16px color-mix(in srgb,var(--ref-color) 45%,transparent); }
.ref-rank__brand { width:25px; height:25px; z-index:1; }.ref-rank__brand svg { width:100%; height:100%; }
.ref-rank__state { color:var(--fg-muted,#a9b4ae); font-size:.62rem; text-transform:uppercase; letter-spacing:.05em; }
.ref-rank--reached .ref-rank__state { color:var(--ref-color); }
.ref-rank h3 { margin:9px 0 12px; font-size:1rem; }
.ref-rank__requirement span,.ref-rank__award span { display:block; color:var(--fg-muted,#a9b4ae); font-size:.64rem; text-transform:uppercase; letter-spacing:.035em; }
.ref-rank__requirement strong { display:block; margin-top:3px; font-size:.84rem; }
.ref-rank__progress { display:block; width:100%; height:4px; margin:8px 0 10px; overflow:hidden; border:0; border-radius:10px; background:rgba(255,255,255,.08); }
.ref-rank__progress::-webkit-progress-bar { background:rgba(255,255,255,.08); }
.ref-rank__progress::-webkit-progress-value { background:var(--ref-color); }
.ref-rank__progress::-moz-progress-bar { background:var(--ref-color); }
.ref-rank__award { display:grid; justify-items:center; gap:3px; margin-top:5px; padding:9px 7px; border:1px solid color-mix(in srgb,var(--ref-color) 34%,transparent); border-radius:10px; background:linear-gradient(140deg,color-mix(in srgb,var(--ref-color) 18%,transparent),color-mix(in srgb,var(--ref-color) 5%,transparent)); text-align:center; }
.ref-rank__award span { color:color-mix(in srgb,var(--ref-color) 75%,white); }
.ref-rank__award strong { color:var(--ref-color); font-size:1.22rem; line-height:1.15; font-variant-numeric:tabular-nums; text-shadow:0 0 14px color-mix(in srgb,var(--ref-color) 35%,transparent); white-space:nowrap; }
.ref-rank__profit { display:flex; flex-direction:column; gap:3px; margin:0 0 9px; padding:7px 0; border-bottom:1px solid rgba(255,255,255,.08); }
.ref-rank__profit span { color:var(--fg-muted,#a9b4ae); font-size:.64rem; text-transform:uppercase; letter-spacing:.035em; }
.ref-rank__profit strong { color:#a9f37b; font-size:.74rem; font-weight:600; }
.how__referrals { scroll-margin-top:85px; margin:20px 0; padding:18px; border:1px solid var(--border,#2b3634); border-radius:14px; }
.how__referrals h2 { margin:0 0 8px; font-size:1.25rem; }.how__referrals p { margin:8px 0 0; }
.how__referrals .how__referrals-example { margin:10px 0; padding:10px 12px; border:1px solid rgba(31,201,138,.25); border-radius:10px; background:rgba(31,201,138,.07); }
@media(max-width:900px) { .ref-metrics { grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media(max-width:600px) { .ref-invite__fields,.ref-claims { grid-template-columns:1fr; } .ref-metric { min-height:68px; } }
