/* Pocket Rem Mini App - single stylesheet.

   Apple-flavoured: the iOS type ramp (SF Pro via -apple-system), inset grouped
   lists, hairline separators, and translucent chrome built from the platform's
   material recipe (a tinted surface behind a saturating blur).

   Theming stays hybrid: the FRAME (page, cell, ink) follows Telegram's theme
   params, while ACCENTS and STATUS colors are the brand's own, fixed per mode
   and snapped to >=4.5:1 WCAG text contrast on the real Telegram surfaces.

   Note the light/dark flip in the page/cell mapping. iOS puts the darker tone
   behind the lighter cell in both modes, but Telegram's secondary_bg is lighter
   than bg in dark and darker than bg in light - so the two roles swap by mode
   to keep the grouped-list relationship intact either way. */

:root {
  color-scheme: light;

  /* Light: page = grouped background (secondary), cell = content (bg). */
  --page: var(--tg-theme-secondary-bg-color, #f2f2f7);
  --cell: var(--tg-theme-bg-color, #ffffff);
  --text: var(--tg-theme-text-color, #000000);
  --muted: var(--tg-theme-hint-color, #8a8a8e);
  --link: var(--tg-theme-link-color, #2e428a);

  --ink: 60, 60, 67;
  --separator: rgba(var(--ink), 0.29);
  --fill: rgba(var(--ink), 0.06);
  --fill-strong: rgba(var(--ink), 0.12);
  --shadow: 0 1px 3px rgba(0, 0, 0, 0.06);

  /* Brand accent - logo indigo. 9.28:1 on #ffffff, 8.14:1 on #f0f0f0. */
  --accent: #2e428a;
  --accent-ink: #ffffff;
  --accent-wash: rgba(46, 66, 138, 0.10);
  --accent-track: rgba(46, 66, 138, 0.16);

  /* Status - reserved roles, never decoration, snapped for text legibility. */
  --good: #008000;
  --warning: #9f5c00;
  --critical: #c93435;
  --good-wash: rgba(0, 128, 0, 0.09);
  --warning-wash: rgba(159, 92, 0, 0.09);
  --critical-wash: rgba(201, 52, 53, 0.09);

  /* Backdrop glows: brand indigo + the lavender from img/main.jpg. They exist
     so the frosted chrome has something to actually blur - a blur over a flat
     fill is mathematically real and visually invisible. */
  --glow-1: rgba(46, 66, 138, 0.13);
  --glow-2: rgba(160, 130, 188, 0.13);
  --watermark: 0.055;

  --radius: 12px;
  --radius-lg: 16px;
  --inset: 16px;
  --tabbar-h: 52px;
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    /* Dark: page = bg (darker), cell = secondary (lighter) - the flip. */
    --page: var(--tg-theme-bg-color, #17212b);
    --cell: var(--tg-theme-secondary-bg-color, #232e3c);
    --text: var(--tg-theme-text-color, #ffffff);
    --muted: var(--tg-theme-hint-color, #8e8e93);
    --link: var(--tg-theme-link-color, #7691e0);

    --ink: 235, 235, 245;
    --separator: rgba(var(--ink), 0.22);
    --fill: rgba(var(--ink), 0.10);
    --fill-strong: rgba(var(--ink), 0.18);
    --shadow: 0 1px 3px rgba(0, 0, 0, 0.4);

    --accent: #7691e0;
    --accent-ink: #10161f;
    --accent-wash: rgba(118, 145, 224, 0.16);
    --accent-track: rgba(118, 145, 224, 0.22);

    --good: #1fab1d;
    --warning: #fab219;
    --critical: #f9625d;
    --good-wash: rgba(31, 171, 29, 0.14);
    --warning-wash: rgba(250, 178, 25, 0.14);
    --critical-wash: rgba(249, 98, 93, 0.14);

    --glow-1: rgba(118, 145, 224, 0.20);
    --glow-2: rgba(160, 130, 188, 0.16);
    --watermark: 0.075;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --page: var(--tg-theme-bg-color, #17212b);
  --cell: var(--tg-theme-secondary-bg-color, #232e3c);
  --text: var(--tg-theme-text-color, #ffffff);
  --muted: var(--tg-theme-hint-color, #8e8e93);
  --link: var(--tg-theme-link-color, #7691e0);

  --ink: 235, 235, 245;
  --separator: rgba(var(--ink), 0.22);
  --fill: rgba(var(--ink), 0.10);
  --fill-strong: rgba(var(--ink), 0.18);
  --shadow: 0 1px 3px rgba(0, 0, 0, 0.4);

  --accent: #7691e0;
  --accent-ink: #10161f;
  --accent-wash: rgba(118, 145, 224, 0.16);
  --accent-track: rgba(118, 145, 224, 0.22);

  --good: #1fab1d;
  --warning: #fab219;
  --critical: #f9625d;
  --good-wash: rgba(31, 171, 29, 0.14);
  --warning-wash: rgba(250, 178, 25, 0.14);
  --critical-wash: rgba(249, 98, 93, 0.14);

  --glow-1: rgba(118, 145, 224, 0.20);
  --glow-2: rgba(160, 130, 188, 0.16);
  --watermark: 0.075;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* ---------- type ----------
   The iOS text styles. SF Pro comes from -apple-system on Apple platforms and
   degrades to the platform UI sans elsewhere; tracking is set per style because
   SF is optically sized and the web fallbacks are not. */

html { background: var(--page); }

html, body {
  margin: 0;
  padding: 0;
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI",
               Roboto, system-ui, sans-serif;
  font-size: 17px;
  line-height: 22px;
  letter-spacing: -0.01em;
  overscroll-behavior-y: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body { min-height: 100vh; }

/* Two fixed layers behind everything: soft brand glows, then the logo as a
   watermark. Together they give the translucent chrome and cards a varying
   field to sit on, which is what makes the material read as glass. */
body::before,
body::after {
  content: '';
  position: fixed;
  pointer-events: none;
}

body::before {
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(52% 34% at 6% -6%, var(--glow-1), transparent 72%),
    radial-gradient(58% 34% at 104% 12%, var(--glow-2), transparent 70%),
    radial-gradient(78% 38% at 50% 106%, var(--glow-1), transparent 74%);
}

body::after {
  z-index: -1;
  width: 128vw;
  height: 128vw;
  max-width: 560px;
  max-height: 560px;
  right: -34vw;
  top: 4vh;
  opacity: var(--watermark);
}

.hidden { display: none !important; }

.brand-mark { flex: 0 0 auto; }

/* The logo is painted as a masked fill so it takes the accent colour of the
   active theme instead of dragging a white JPEG box into a dark UI. The fill is
   applied only where masking is supported - otherwise it would render as a
   solid indigo rectangle, and an absent mark is far better than that. */
@supports ((-webkit-mask-image: url("")) or (mask-image: url(""))) {
  .brand-mark,
  body::after {
    background: var(--accent);
    -webkit-mask: url(/static/img/logo-mask.png) center / contain no-repeat;
    mask: url(/static/img/logo-mask.png) center / contain no-repeat;
  }
}
button { font: inherit; color: inherit; cursor: pointer; }

.icon { display: block; flex: 0 0 auto; }

/* ---------- boot / gate ---------- */

.boot, .gate {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 32px 24px;
  text-align: center;
}

.boot .brand-mark, .gate .brand-mark { width: 72px; height: 72px; margin-bottom: 6px; }

.boot__spinner {
  width: 28px; height: 28px;
  border: 2.5px solid var(--fill-strong);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .8s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

.boot__text, .gate__text {
  color: var(--muted);
  margin: 0;
  max-width: 320px;
  font-size: 15px;
  line-height: 20px;
}

.gate__icon { color: var(--muted); margin-bottom: 4px; }
.gate__icon .icon { width: 44px; height: 44px; stroke-width: 1.4; }

.gate__title {
  margin: 0;
  font-size: 28px;
  line-height: 34px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.gate__error {
  color: var(--critical);
  font-size: 13px;
  line-height: 18px;
  min-height: 18px;
  margin: 2px 0 0;
}

.gate .btn { width: 100%; max-width: 320px; }

/* ---------- layout & chrome ----------
   Chrome is translucent the way the platform does it: a tinted copy of the
   surface behind a saturating blur, so content scrolling underneath tints it.
   The solid declaration comes first as the fallback for engines without
   color-mix or backdrop-filter - they lose the translucency, not the color. */

.app { padding-bottom: calc(var(--tabbar-h) + var(--safe-bottom) + 18px); }

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  padding: 12px var(--inset) 8px;
  background: var(--page);
}

/* Large Title */
.topbar__title {
  font-size: 30px;
  line-height: 36px;
  font-weight: 700;
  letter-spacing: -0.028em;
}

/* Footnote */
.topbar__sub {
  font-size: 13px;
  line-height: 18px;
  color: var(--muted);
  letter-spacing: -0.005em;
  margin-top: 1px;
}

.screen {
  padding: 0 var(--inset) 16px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* ---------- tab bar ---------- */

.tabbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 30;
  display: flex;
  height: calc(var(--tabbar-h) + var(--safe-bottom));
  padding-bottom: var(--safe-bottom);
  border-top: 0.5px solid var(--separator);
  background: var(--page);
}

.tab {
  flex: 1;
  border: 0;
  background: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  color: var(--muted);
  font-size: 10px;
  line-height: 12px;
  font-weight: 500;
  letter-spacing: 0;
  padding: 0;
  transition: color .15s;
}

.tab .icon { width: 25px; height: 25px; stroke-width: 1.7; }
.tab.is-active { color: var(--accent); }

/* ---------- controls ---------- */

/* iOS segmented control: a filled track with a raised selected segment. */
.segmented {
  display: flex;
  gap: 2px;
  background: var(--fill);
  border-radius: 9px;
  padding: 2px;
}

.segmented__item {
  flex: 1;
  border: 0;
  background: none;
  color: var(--text);
  font-size: 13px;
  line-height: 18px;
  font-weight: 600;
  letter-spacing: -0.005em;
  padding: 7px 6px;
  border-radius: 7px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: background .18s, color .18s, box-shadow .18s;
}

.segmented__item.is-active {
  background: var(--cell);
  color: var(--text);
  box-shadow: var(--shadow);
}

.chips { display: flex; flex-wrap: wrap; gap: 7px; }

.chip {
  border: 0;
  background: var(--fill);
  color: var(--text);
  border-radius: 999px;
  padding: 7px 14px;
  font-size: 14px;
  line-height: 18px;
  font-weight: 500;
  letter-spacing: -0.008em;
  transition: background .15s, color .15s;
}

.chip.is-active { background: var(--accent); color: var(--accent-ink); font-weight: 600; }

.filter-group { display: flex; flex-direction: column; gap: 8px; }

/* Grouped-list section header: uppercase footnote, inset, muted. */
.filter-group__label, .section-title {
  font-size: 13px;
  line-height: 18px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-weight: 500;
  padding: 0 4px;
}

.section-title { margin: 6px 0 -8px; }

.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  width: 100%;
  border: 0;
  background: var(--cell);
  color: var(--accent);
  border-radius: var(--radius);
  padding: 14px 16px;
  font-size: 17px;
  line-height: 22px;
  font-weight: 600;
  letter-spacing: -0.015em;
  transition: opacity .12s;
}

.btn .icon { width: 20px; height: 20px; }
.btn { transition: opacity .12s, transform .12s cubic-bezier(.34, 1.4, .64, 1); }
.btn:active { opacity: .6; transform: scale(.975); }
.btn[disabled] { opacity: .4; pointer-events: none; }

.btn--primary { background: var(--accent); color: var(--accent-ink); }
.btn--ghost { background: transparent; }
.btn--danger { background: var(--cell); color: var(--critical); }
.btn--sm { padding: 11px 14px; font-size: 15px; line-height: 20px; }
.btn--sm .icon { width: 18px; height: 18px; }
.btn-row { display: flex; gap: 10px; }

.input, .textarea {
  width: 100%;
  background: var(--cell);
  border: 0;
  border-radius: var(--radius);
  color: var(--text);
  padding: 13px 15px;
  font: inherit;
  letter-spacing: -0.01em;
  outline: none;
  box-shadow: inset 0 0 0 1px transparent;
  transition: box-shadow .15s;
}

.input::placeholder, .textarea::placeholder { color: var(--muted); }
.input:focus, .textarea:focus { box-shadow: inset 0 0 0 2px var(--accent); }
.textarea { min-height: 112px; resize: vertical; }

.search-field { position: relative; display: flex; align-items: center; }
.search-field .icon { position: absolute; left: 12px; width: 18px; height: 18px; color: var(--muted); }
.search-field .input { padding-left: 38px; }

.field { display: flex; flex-direction: column; gap: 7px; }

.field__label {
  font-size: 13px;
  line-height: 18px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-weight: 500;
  padding: 0 4px;
}

.field__hint { font-size: 13px; line-height: 18px; color: var(--muted); padding: 0 4px; }
.field__hint.is-error { color: var(--critical); }
.counter { font-size: 13px; line-height: 18px; color: var(--muted); text-align: right; padding: 0 4px; }

/* ---------- grouped lists & cards ---------- */

.card {
  background: var(--cell);
  border-radius: var(--radius);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.card--tight { padding: 14px 16px; gap: 8px; }

/* Headline */
.card__title { font-size: 17px; line-height: 22px; font-weight: 600; letter-spacing: -0.02em; }

/* Subheadline */
.card__text {
  font-size: 15px;
  line-height: 20px;
  color: var(--muted);
  margin: 0;
  white-space: pre-wrap;
  word-break: break-word;
  letter-spacing: -0.008em;
}

.notice {
  border-radius: var(--radius);
  padding: 13px 15px;
  font-size: 13px;
  line-height: 18px;
  background: var(--warning-wash);
  color: var(--text);
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

.notice .icon { width: 19px; height: 19px; color: var(--warning); margin-top: 1px; }
.notice--danger { background: var(--critical-wash); }
.notice--danger .icon { color: var(--critical); }
.notice--info { background: var(--accent-wash); }
.notice--info .icon { color: var(--accent); }

.list { display: flex; flex-direction: column; gap: 10px; }

/* Inset grouped list: one rounded card, cells divided by inset hairlines. */
.group {
  background: var(--cell);
  border-radius: var(--radius);
  overflow: hidden;
}

.group > .row { border-radius: 0; background: none; }
.group > .row:not(:last-child) { box-shadow: inset 0 -0.5px 0 var(--separator); }

.row {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--cell);
  border: 0;
  border-radius: var(--radius);
  padding: 11px 16px;
  width: 100%;
  min-height: 48px;
  text-align: left;
  transition: background .12s;
}

button.row:active { background: var(--fill); }

.row__rank {
  min-width: 20px;
  font-size: 15px;
  line-height: 20px;
  font-weight: 600;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.row__rank.is-top { color: var(--accent); }
.row__main { flex: 1; min-width: 0; }

/* Body */
.row__name {
  font-size: 17px;
  line-height: 22px;
  font-weight: 400;
  letter-spacing: -0.02em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Footnote. Kept to one line so row heights stay even down the list; the tail
   (the least critical figures) is what gets clipped on narrow screens. */
.row__meta {
  font-size: 13px;
  line-height: 18px;
  color: var(--muted);
  margin-top: 1px;
  letter-spacing: -0.005em;
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.row__chevron { color: var(--muted); opacity: .5; }
.row__chevron .icon { width: 15px; height: 15px; stroke-width: 2.4; }

/* ---------- status ----------
   A status color never carries meaning alone: every value pairs the hue with a
   glyph, so it survives grayscale, CVD and forced-colors. */

.status {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  font-size: 17px;
  line-height: 22px;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.status__glyph { font-size: 9px; line-height: 1; transform: translateY(-2px); }
.status--good { color: var(--good); }
.status--mid { color: var(--warning); }
.status--bad { color: var(--critical); }

/* ---------- meter ---------- */

.meter { height: 6px; border-radius: 3px; background: var(--accent-track); overflow: hidden; }
.meter__fill { height: 100%; border-radius: 3px; background: var(--accent); min-width: 3px; }

/* ---------- figures ---------- */

.stat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }

.stat { background: var(--cell); border-radius: var(--radius); padding: 14px 16px; }

.stat__label {
  font-size: 13px;
  line-height: 18px;
  color: var(--muted);
  letter-spacing: -0.005em;
}

/* Proportional figures on purpose: tabular-nums looses up a standalone value. */
.stat__value {
  font-size: 28px;
  line-height: 34px;
  font-weight: 600;
  margin-top: 2px;
  letter-spacing: -0.03em;
}

.stat__sub { font-size: 13px; line-height: 18px; color: var(--muted); }

.hero-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }

.hero-btn {
  background: var(--cell);
  border: 0;
  border-radius: var(--radius);
  padding: 13px 12px;
  font-size: 14px;
  line-height: 19px;
  font-weight: 500;
  letter-spacing: -0.012em;
  text-align: left;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: background .12s;
}

.hero-btn:active { background: var(--fill); }
.hero-btn .icon { width: 17px; height: 17px; color: var(--accent); }
.hero-btn.is-selected { background: var(--accent); color: var(--accent-ink); font-weight: 600; }
.hero-btn.is-selected .icon { opacity: 1; color: var(--accent-ink); }
.hero-btn__name { overflow: hidden; text-overflow: ellipsis; }

.kv {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 15px;
  line-height: 20px;
  letter-spacing: -0.01em;
}

.kv__k { color: var(--muted); }
.kv__v { font-weight: 500; text-align: right; word-break: break-word; font-variant-numeric: tabular-nums; }

.empty {
  text-align: center;
  color: var(--muted);
  font-size: 13px;
  line-height: 18px;
  padding: 22px 12px;
  letter-spacing: -0.005em;
}

.skeleton {
  height: 52px;
  border-radius: var(--radius);
  background: linear-gradient(90deg, var(--cell) 25%, var(--fill) 50%, var(--cell) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.3s infinite;
}

@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }

.profile-card {
  background: var(--cell);
  border-radius: var(--radius-lg);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Title 2 */
.profile-card__ign { font-size: 22px; line-height: 28px; font-weight: 700; letter-spacing: -0.024em; }
.profile-card__rank { font-size: 15px; line-height: 20px; color: var(--accent); font-weight: 600; letter-spacing: -0.01em; }
.profile-card__heroes { display: flex; flex-wrap: wrap; gap: 6px; }

.tag {
  font-size: 13px;
  line-height: 18px;
  padding: 4px 11px;
  border-radius: 999px;
  background: var(--fill);
  color: var(--text);
  letter-spacing: -0.005em;
}

.swipe-actions { display: flex; gap: 10px; }
.swipe-actions .btn { flex: 1; }

.progress { font-size: 13px; line-height: 18px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---------- sheet ---------- */

.sheet { position: fixed; inset: 0; z-index: 60; }
.sheet__backdrop { position: absolute; inset: 0; background: rgba(0, 0, 0, .4); }

.sheet__panel {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  max-height: 88vh;
  overflow-y: auto;
  background: var(--page);
  border-radius: 14px 14px 0 0;
  padding: 8px var(--inset) calc(22px + var(--safe-bottom));
  animation: sheet-up .28s cubic-bezier(.32, .72, 0, 1);
}

@keyframes sheet-up { from { transform: translateY(100%); } to { transform: none; } }

.sheet__handle { width: 36px; height: 5px; border-radius: 999px; background: var(--fill-strong); margin: 6px auto 12px; }
.sheet__head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.sheet__title { flex: 1; font-size: 20px; line-height: 25px; font-weight: 700; letter-spacing: -0.024em; }

.sheet__close {
  border: 0;
  background: var(--fill);
  color: var(--muted);
  border-radius: 999px;
  width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
}

.sheet__close .icon { width: 16px; height: 16px; stroke-width: 2.4; }
.sheet__body { display: flex; flex-direction: column; gap: 12px; }

/* ---------- toast ---------- */

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--tabbar-h) + var(--safe-bottom) + 18px);
  transform: translateX(-50%);
  z-index: 80;
  max-width: 86vw;
  background: var(--text);
  color: var(--page);
  border-radius: 999px;
  padding: 11px 18px;
  font-size: 15px;
  line-height: 20px;
  font-weight: 500;
  letter-spacing: -0.01em;
  text-align: center;
  box-shadow: 0 8px 28px rgba(0, 0, 0, .22);
  animation: toast-in .24s cubic-bezier(.32, .72, 0, 1);
}

.toast--error { background: var(--critical); color: #ffffff; }
.toast--success { background: var(--good); color: #ffffff; }

@keyframes toast-in { from { opacity: 0; transform: translate(-50%, 10px); } to { opacity: 1; transform: translate(-50%, 0); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }

  /* Progress indicators are information, not decoration: a frozen spinner
     reads as a hung request, so these keep running. */
  .boot__spinner,
  .btn.is-busy::before {
    animation-duration: .65s !important;
  }
}


/* ---------- glass surfaces ----------
   Appended last on purpose: these rules re-tint surfaces declared above, so
   they must win on source order.

   Only the chrome (top bar, tab bar, sheet) carries a real backdrop blur.
   Cells are merely translucent: blurring dozens of scrolling rows costs far
   more on a phone than it adds, and over a soft gradient the alpha alone
   already reads as glass. The solid `background` line stays as the fallback
   for engines without color-mix. */

.card,
.group,
.row,
.stat,
.hero-btn,
.profile-card,
.input,
.textarea,
.btn:not(.btn--primary):not(.btn--ghost),
.segmented__item.is-active {
  background: var(--cell);
  background: color-mix(in srgb, var(--cell) 62%, transparent);
}

/* Rows inside a group share the group's surface - they must not stack a second
   translucent layer on top of it. */
.group > .row { background: none; }

.segmented { background: color-mix(in srgb, var(--fill) 70%, transparent); }

/* A hairline ring keeps the edge of a translucent surface readable where it
   crosses a bright part of the gradient. */
.card,
.group,
.stat,
.profile-card,
.hero-btn,
.row {
  box-shadow: inset 0 0 0 0.5px var(--separator);
}

/* Rows inside a group keep only the divider, re-asserted after the ring above.
   Written as two plain rules rather than :not(.group > .row) - a complex
   argument in :not() invalidates the whole selector list on older engines. */
.group > .row { box-shadow: inset 0 -0.5px 0 var(--separator); }
.group > .row:last-child { box-shadow: none; }

.btn--primary { box-shadow: 0 6px 18px var(--accent-wash); }

/* ---------- brand mark in the header ---------- */

.topbar { display: flex; align-items: flex-start; gap: 12px; }
.topbar__titles { flex: 1; min-width: 0; }

.topbar__mark {
  width: 30px;
  height: 30px;
  margin-top: 4px;
  opacity: .9;
}

/* ---------- chrome material ----------
   Translucency is gated on blur support, not declared alongside it. A bar that
   is see-through but NOT blurred puts sharp scrolling text directly behind its
   own labels, which is worse than an opaque bar - so engines without
   backdrop-filter keep the solid surface declared above. */
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .topbar, .tabbar {
    background: color-mix(in srgb, var(--page) 55%, transparent);
    -webkit-backdrop-filter: saturate(200%) blur(30px);
    backdrop-filter: saturate(200%) blur(30px);
  }

  .sheet__panel {
    background: color-mix(in srgb, var(--page) 62%, transparent);
    -webkit-backdrop-filter: saturate(200%) blur(40px);
    backdrop-filter: saturate(200%) blur(40px);
  }
}

/* ---------- hero art ----------
   Every image here is optional: the JS removes the element when the source
   fails, so these rules only ever style art that actually arrived. The tinted
   box behind each image doubles as the placeholder while it loads and as the
   backdrop for the transparent PNG/WebP the CDN serves. */

.avatar {
  width: 31px;
  height: 31px;
  border-radius: 9px;
  object-fit: cover;
  background: var(--fill);
  flex: 0 0 auto;
}

.avatar--sm { width: 27px; height: 27px; border-radius: 7px; }
.avatar--tag { width: 19px; height: 19px; border-radius: 5px; margin: -1px 0 -1px -4px; }





/* The hero button turns into an avatar + name pair. */
.hero-btn { gap: 9px; padding: 9px 11px; }
.hero-btn .avatar { width: 30px; height: 30px; border-radius: 8px; }
.hero-btn .icon { margin-left: auto; }

/* Two-line hero name: the avatar already identifies the hero, so the Latin and
   Cyrillic halves stack instead of competing for one truncated line. */
.hero-btn__name { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }

.hero-btn__en {
  font-size: 14px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hero-btn__ru {
  font-size: 11.5px;
  font-weight: 400;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hero-btn.is-selected .hero-btn__ru { color: var(--accent-ink); opacity: .75; }

/* ---------- hero header ----------
   The portrait keeps its own 280:380 ratio inside a fixed-width frame, so no
   hero gets cropped at the chin and the layout stays identical for all of them. */

.hero-header {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 14px;
  background: var(--cell);
  background: color-mix(in srgb, var(--cell) 62%, transparent);
  border-radius: var(--radius-lg);
  box-shadow: inset 0 0 0 0.5px var(--separator);
}

.hero-header__frame {
  width: 74px;
  aspect-ratio: 280 / 380;
  flex: 0 0 auto;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--accent-wash);
}

.hero-header__art { width: 100%; height: 100%; object-fit: contain; display: block; }
.hero-header__text { min-width: 0; }

.hero-header__name {
  font-size: 24px;
  line-height: 29px;
  font-weight: 700;
  letter-spacing: -0.026em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hero-header__ru {
  font-size: 15px;
  line-height: 20px;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hero-header__sub {
  font-size: 13px;
  line-height: 18px;
  color: var(--muted);
  margin-top: 4px;
}

/* ---------- motion ----------
   Button feedback is state, not decoration: idle, busy and done each look
   different, and the transition between them is the animation. Built on the
   SVG set already in the app so every glyph keeps inheriting currentColor -
   a baked-colour animation format cannot do that, and would need its own
   player on top. */

@keyframes spin-mark { to { transform: rotate(360deg); } }
@keyframes draw-stroke { to { stroke-dashoffset: 0; } }

@keyframes pop {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.22); }
  100% { transform: scale(1); }
}

@keyframes beat {
  0%   { transform: scale(1); }
  28%  { transform: scale(1.32); }
  52%  { transform: scale(.94); }
  100% { transform: scale(1); }
}

@keyframes nudge {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(-2px); }
  75%      { transform: translateX(2px); }
}

/* Busy: the glyph steps aside for a ring that keeps its place in the flex row,
   so the label never shifts while the request is in flight. */
.btn.is-busy .icon { display: none; }

.btn.is-busy::before {
  content: '';
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  opacity: .85;
  animation: spin-mark .65s linear infinite;
}

/* Done: the checkmark draws itself instead of appearing. */
.btn.is-done .icon path {
  stroke-dasharray: 30;
  stroke-dashoffset: 30;
  animation: draw-stroke .42s cubic-bezier(.65, 0, .35, 1) forwards;
}

/* Tab bar: the selected glyph pops once on switch. */
.tab.is-active .icon { animation: pop .34s cubic-bezier(.34, 1.56, .64, 1); }

/* Like: the heart beats on tap. */
.btn.is-beating .icon { animation: beat .42s cubic-bezier(.34, 1.56, .64, 1); }

/* Rejected input: the field nudges rather than just turning red. */
.is-nudging { animation: nudge .26s ease-in-out; }

/* Rows and grid cells settle back instead of snapping. */
button.row, .hero-btn, .chip, .segmented__item {
  transition: background .14s, color .14s, transform .12s cubic-bezier(.34, 1.4, .64, 1), box-shadow .14s;
}

button.row:active, .hero-btn:active { transform: scale(.985); }
.chip:active, .segmented__item:active { transform: scale(.95); }

/* Newly rendered list groups fade up a little; cheap, and it hides the moment
   the skeleton is swapped for real rows. */
@keyframes rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

.group, .stat-grid, .hero-grid, .hero-header, .profile-card {
  animation: rise .26s cubic-bezier(.32, .72, 0, 1) both;
}
