/* ==========================================================================
   Dashboard grid (admin-new home) — empty skeleton
   ------------------------------------------------------------------------
   Rebuilt from scratch to mirror the reference "our copy.png" 1:1.
   Reference content box = 1266px wide → columns 310 / 588 / 316 (fr) and
   every tile is sized by aspect-ratio (w/h from the reference), so the WHOLE
   board is a pure scale of the reference at ANY container width — no fixed
   heights that break when the sidebar narrows the content area. Gaps are in
   cqw (relative to the content width) so they scale with everything else.
   Tiles are themed card chrome (both themes); the promo tile is locked to the
   reference orange, per spec.
   ========================================================================== */

.admin-main .dash-page { container-type: inline-size; }

.admin-main .dash {
  --gap: 16px;              /* ONE uniform gap — columns, rows, sub-cards */
  --dash-radius: 18px;
  display: grid;
  grid-template-columns: 310fr 588fr 316fr;
  gap: var(--gap);
  align-items: start;
}

/* columns are independent vertical stacks (they don't share row lines).
   promo & regs heights are tuned so all three columns end at the same line —
   no stray gap under the shorter (orange) column. */
.admin-main .dash-col {
  display: flex;
  flex-direction: column;
  row-gap: var(--gap);
  min-width: 0;
}
.admin-main .dash-col--left  { grid-column: 1; grid-row: 1; }
.admin-main .dash-col--mid   { grid-column: 2; grid-row: 1; }
.admin-main .dash-col--right { grid-column: 3; grid-row: 1; }
.admin-main .dash-wide       { grid-column: 1 / -1; grid-row: 2; }

/* ---- Tile chrome (empty card) ------------------------------------------- */
.admin-main .dtile {
  position: relative;
  min-width: 0;
  border-radius: var(--dash-radius);
  border: 1px solid var(--border);
  background: var(--card-bg);
  box-shadow: var(--shadow);
}

/* ---- Sizes as reference aspect-ratios (w / h) --------------------------- */
.admin-main .dtile--gauge   { aspect-ratio: 311 / 260; padding: 0; overflow: hidden; }
.admin-main .dtile--promo   { aspect-ratio: 310 / 338; }
.admin-main .dtile--hero    { aspect-ratio: 588 / 250; }
.admin-main .dtile--chart   { aspect-ratio: 588 / 187; }
.admin-main .dtile--heat    { aspect-ratio: 588 / 175; }
.admin-main .dtile--finance { aspect-ratio: 316 / 433; }
.admin-main .dtile--regs    { aspect-ratio: 316 / 190; }
.admin-main .dtile--domains { aspect-ratio: 1266 / 179; }

/* ---- Orange promo tile — "Подключите новый домен" ------------------------
   Rebuild of the reference promo card (admnewww/our copy.png): two-line title,
   short blurb, white CTA pill and — in place of the reference 3D lock — the
   animated LadyCat bicep sticker, enlarged and dropped so her resting-pose
   bottom lines up with the bottom of the "Добавить" pill, kept clear of the
   copy on the left. Colours are the reference's own sampled orange (#ec3c12
   family), locked in BOTH themes (text stays white on orange), so no light-
   theme override is needed. The tile is its OWN inline-size container, so every
   unit below is cqw-of-the-tile: the card scales as one piece at any board
   width / breakpoint — no px pins, no drift. */
.admin-main .dtile--promo {
  container-type: inline-size;
  background: linear-gradient(159deg, #ee4016 0%, #e93a10 56%, #e5380f 100%);
  border-color: #e5380f;
  overflow: hidden;
}
.admin-main .promo {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  padding: 5.8cqw 5.8cqw 5.8cqw;      /* ≈18px of the 310-wide tile */
  color: #fff;
}

/* text column — align-self:flex-start pins it to the left 52% (not stretched),
   so the title + blurb clear the enlarged sticker on the right with a gap.
   z-index above the sticker as a safety net for any incidental overlap. */
.admin-main .promo__body {
  position: relative;
  z-index: 2;
  align-self: flex-start;
  flex: 1 1 auto;
  min-height: 0;
  width: 52%;
  display: flex;
  flex-direction: column;
}
.admin-main .promo__title {
  margin: 0;
  font-size: 7.2cqw;                  /* two lines via <br>; nowrap so "новый
                                         домен" never breaks into a third line */
  line-height: 1.1;
  font-weight: 800;
  letter-spacing: -.02em;
  white-space: nowrap;
}
/* The tile is locked orange in BOTH themes, so the title stays white — beat the
   global light-theme heading rule (core.css) that would otherwise darken this
   <h3>. Higher specificity + !important, so it wins regardless of load order. */
html:not([data-theme="dark"]) .admin-main .promo__title { color: #fff !important; }
.admin-main .promo__desc {
  margin: 2.8cqw 0 0;
  font-size: 4.8cqw;                  /* 1.5× smaller than the title (7.2 / 1.5) */
  line-height: 1.34;
  font-weight: 500;
  color: rgba(255, 255, 255, .92);
}
.admin-main .promo__btn {
  margin-top: auto;
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 1.7cqw;
  padding: 3.1cqw 5cqw;
  border: 0;
  border-radius: 999px;
  background: #fff;
  color: #191512;
  font-size: 4.6cqw;                  /* ≈14.3px */
  font-weight: 700;
  letter-spacing: -.01em;
  cursor: pointer;
  box-shadow: 0 2cqw 4cqw rgba(120, 20, 0, .18);
  transition: transform .15s cubic-bezier(.4, 0, .2, 1), box-shadow .15s ease;
}
.admin-main .promo__btn svg {
  width: 4.4cqw; height: 4.4cqw;
  fill: none; stroke: currentColor; stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
  transition: transform .15s cubic-bezier(.4, 0, .2, 1);
}
.admin-main .promo__btn:hover { transform: translateY(-1px); box-shadow: 0 3cqw 6cqw rgba(120, 20, 0, .24); }
.admin-main .promo__btn:hover svg { transform: translateX(2px); }
.admin-main .promo__btn:active { transform: translateY(0) scale(.98); }
.admin-main .promo__btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* bicep sticker — replaces the reference lock: enlarged (~2×) and bottom-aligned
   (JS passes preserveAspectRatio 'xMidYMax meet') so her feet sit on the same
   baseline as the bottom of the "Добавить" pill (bottom == the tile's bottom
   padding), bleeding slightly off the right. */
.admin-main .promo__sticker {
  position: absolute;
  right: -19.5cqw;            /* extra right-bleed keeps her LEFT edge (the gap to
                                the copy) fixed as she grows wider */
  bottom: -11cqw;             /* drops her resting-pose bottom onto the button
                                baseline (the art has empty canvas below her) */
  width: 67.5%;              /* +9.5% width ≈ +31px of rendered height — the same
                                the card grew taller (kept width-limited) */
  height: 100%;
  z-index: 1;
  display: grid;
  place-items: end center;
  pointer-events: none;
}
.admin-main .promo__sticker svg {
  display: block;
  width: 100% !important;
  height: 100% !important;
  filter: drop-shadow(0 3cqw 5cqw rgba(90, 12, 0, .3));
}
@media (prefers-reduced-motion: reduce) {
  .admin-main .promo__btn, .admin-main .promo__btn svg { transition: none; }
}

/* Desktop 3-col: stretch ONLY the left column to the row height (set by the
   tallest stack — the mid column that ends at the "Активность регистраций"
   heatmap), then let the promo grow into the slack below the gauge so its bottom
   lines up with the heatmap. The grid stays align-items:start, so the mid/right
   columns and every other tile keep their exact aspect-ratio sizes — nothing
   else moves. Tablet/phone stacks keep the promo's own aspect-ratio height. */
@media (min-width: 1025px) {
  .admin-main .dash-col--left { align-self: stretch; }
  .admin-main .dtile--promo { flex: 1 1 auto; min-height: 0; }
}

/* ---- Hero tile: greeting (left) + animated Pepe sticker (right) ---------- */
/* Geometry measured from the reference at 1:1 (content box = 1266px = 100cqw):
   heading font 40px → 3.16cqw, top pad 66px → 5.2cqw, left pad 24px → 1.9cqw.
   The sticker fills the tile height on the right, mirroring the airplane bleed. */
.admin-main .dtile--hero {
  display: flex;
  align-items: stretch;
  overflow: hidden;                 /* clip the sticker bleed to the tile radius */
}
.admin-main .dtile--hero .hero-greet {
  flex: 1 1 auto;
  min-width: 0;
  padding: 4.8cqw 0 1.6cqw 1.45cqw; /* ≈61px top / 18px left — matches ref corner */
}
.admin-main .dtile--hero .hero-greet__title {
  margin: 0;
  font-size: 3.24cqw;               /* ≈41px @1266 — matches ref cap height */
  line-height: 1.02;                /* ≈42px — ref line spacing is near-solid */
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text);
}
.admin-main .dtile--hero .hero-sticker {
  flex: 0 0 auto;
  align-self: center;
  width: 22cqw;                     /* ≈278px — a touch of vertical bleed, clipped */
  aspect-ratio: 1 / 1;
  margin-inline-end: 0.4cqw;
  pointer-events: none;
  display: grid;
  place-items: center;
}
.admin-main .dtile--hero .hero-sticker svg {
  display: block;
  width: 100% !important;
  height: 100% !important;
}

/* ---- Finance tile: huge all-time deposit sum + money-printer sticker ------
   Portrait tile (316×433). The amount reads HUGE — its font is fitted to the
   tile width in JS (fill-to-width), so short sums grow and long sums shrink to
   the same margin. Caption is muted; the money-printer sticker fills whatever
   height is left and bleeds to the bottom edge, clipped to the tile radius. */
.admin-main .dtile--finance {
  display: flex;
  overflow: hidden;
}
.admin-main .dtile--finance .fin {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: 1.9cqw 1.75cqw 0;         /* ≈24px 22px; no bottom pad — sticker bleeds */
}
.admin-main .fin__amount {
  font-weight: 800;
  font-size: 5cqw;                   /* pre-fit fallback; JS overrides to fill width */
  line-height: 1;
  letter-spacing: -0.03em;
  color: #05b200;                    /* earnings green — locked in both themes */
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.admin-main .fin__cap {
  margin: 0.85cqw 0 0;
  font-size: 1.5cqw;                 /* ≈19px @1266 */
  line-height: 1.32;
  font-weight: 500;
  color: var(--text-muted);
}
.admin-main .fin__brand { color: var(--text-strong); font-weight: 700; }
.admin-main .fin__sticker {
  flex: 1 1 auto;
  min-height: 0;
  margin-top: 0.6cqw;
  display: grid;
  place-items: center;
}
.admin-main .fin__sticker svg {
  display: block;
  width: 100% !important;
  height: 100% !important;
}

/* ---- "Онлайн сейчас" gauge tile — reference-faithful SVG speedometer ----
   Everything (title / big number / arc / knob / caption) lives in ONE SVG in
   the reference 311×260 coordinate box, so it scales 1:1 with the tile. Fill
   colour + length are driven by the online count: <5 red (near the start),
   5–29 yellow (toward the middle), ≥30 green (near the end). */
.admin-main .dtile--gauge .gauge { display: block; width: 100%; height: 100%; }
.admin-main .gauge { --g-track: color-mix(in srgb, var(--text-strong) 15%, transparent); }
.admin-main .gauge text { font-family: var(--font-ui); }
.admin-main .g-title { fill: var(--text-strong); font-size: 15px; font-weight: 700; letter-spacing: -.01em; }
.admin-main .g-num   { fill: var(--text-strong); font-size: 56px; font-weight: 800; letter-spacing: -.02em; }
.admin-main .g-sub   { fill: var(--text); font-size: 12.5px; font-weight: 600; }
.admin-main .g-track { fill: none; stroke: var(--g-track); stroke-width: 22; stroke-linecap: round; }
.admin-main .g-fill  { fill: none; stroke: var(--g-c2); stroke-width: 22; stroke-linecap: round; }
.admin-main .g-glow  { fill: none; stroke: var(--g-c2); stroke-width: 22; stroke-linecap: round; opacity: .5; }
.admin-main .g-knob      { fill: var(--g-c2); }
.admin-main .g-knob-hole { fill: var(--card-bg); }
.admin-main .gauge.is-green  { --g-c2: #5dd873; }
.admin-main .gauge.is-yellow { --g-c2: #f7c948; }
.admin-main .gauge.is-red    { --g-c2: #ff5e52; }
/* entrance: fill sweeps in from the left, knob pops at the leading edge */
@keyframes gauge-sweep { from { stroke-dasharray: 0 400; } }
@keyframes gauge-knob  { from { opacity: 0; transform: scale(.4); } }
.admin-main .g-fill, .admin-main .g-glow { animation: gauge-sweep .9s cubic-bezier(.22,.61,.36,1) both; }
.admin-main .g-knob, .admin-main .g-knob-hole {
  transform-box: fill-box; transform-origin: center;
  animation: gauge-knob .34s cubic-bezier(.34,1.56,.64,1) .8s both;
}
/* live updates (updateGauge): ease the fill length, knob position and zone
   colour between polls. The one-shot entrance keyframe runs once on mount and
   hands off cleanly to these transitions for every later value change. */
.admin-main .g-fill, .admin-main .g-glow {
  transition: stroke-dasharray .6s cubic-bezier(.22,.61,.36,1), stroke .35s ease;
}
.admin-main .g-knob, .admin-main .g-knob-hole {
  transition: cx .6s cubic-bezier(.22,.61,.36,1), cy .6s cubic-bezier(.22,.61,.36,1), fill .35s ease;
}
@media (prefers-reduced-motion: reduce) {
  .admin-main .g-fill, .admin-main .g-glow,
  .admin-main .g-knob, .admin-main .g-knob-hole { animation: none; transition: none; }
}

/* ---- Top-domains tile: header + 4 sub-cards ---------------------------- */
.admin-main .dtile--domains {
  display: flex;
  flex-direction: column;
  padding: 1.65cqw 1.75cqw;   /* ≈21px 22px */
}
/* Header row — title only (reference "Смотреть все" pill intentionally dropped). */
.admin-main .dtile--domains .dom-head {
  display: flex;
  align-items: center;
  margin-bottom: 1.5cqw;      /* ≈19px — keeps cards at the reference height */
}
.admin-main .dtile--domains .dom-title {
  font-size: 1.42cqw;         /* ≈18px */
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text-strong);
  text-decoration: none;
  cursor: pointer;
  transition: color .15s ease;
}
.admin-main .dtile--domains .dom-title:hover { text-decoration: underline; }
.admin-main .dtile--domains .dom-title:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 3px;
}

.admin-main .dtile--domains .dom-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.75cqw;
  flex: 1 1 auto;
}
/* Card shell — elevated a touch above the tile so the border isn't the only cue,
   clips the globe that overflows its bottom-right corner. */
.admin-main .dtile--domains .dom-sub {
  position: relative;
  overflow: hidden;
  border-radius: 1.1cqw;
  border: 1px solid var(--border);
  background: color-mix(in srgb, var(--text-strong) 4%, var(--card-bg));
}
.admin-main .dtile--domains .dom-card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 1.35cqw 1.6cqw 1.4cqw;   /* ≈17px 20px */
}
.admin-main .dtile--domains .dom-card__name {
  position: relative;
  z-index: 1;
  font-size: 1.26cqw;         /* ≈16px */
  font-weight: 700;
  color: var(--text-strong);
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.admin-main .dtile--domains .dom-card__stat {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 0.15cqw;
}
.admin-main .dtile--domains .dom-card__num {
  font-size: 2.75cqw;         /* ≈35px */
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.02em;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
}
.admin-main .dtile--domains .dom-card__label {
  font-size: 1.05cqw;         /* ≈13px */
  font-weight: 500;
  color: var(--text-muted);
}

/* Wireframe globe — faint, clipped in the bottom-right corner (reference). */
.admin-main .dtile--domains .dom-globe {
  position: absolute;
  top: 50%;
  right: -12%;
  transform: translateY(-50%);
  width: 40%;
  height: auto;
  aspect-ratio: 1;
  color: var(--text-muted);
  opacity: 0.22;
  pointer-events: none;
}
.admin-main .dtile--domains .dom-globe :is(ellipse, path, circle) {
  fill: none;
  stroke: currentColor;
  stroke-width: 0.7;
  vector-effect: non-scaling-stroke;
}

/* Add-domain filler card (tenants with <4 domains) — a centred CTA + plus. */
.admin-main .dtile--domains .dom-card--add {
  align-items: center;
  justify-content: center;
  gap: 1cqw;
  text-align: center;
  cursor: pointer;
  font: inherit;
  transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.admin-main .dtile--domains .dom-card__add-text {
  font-size: 1.2cqw;          /* ≈15px */
  font-weight: 600;
  line-height: 1.25;
  color: var(--text-muted);
  transition: color .15s ease;
}
.admin-main .dtile--domains .dom-card__add-plus {
  display: grid;
  place-items: center;
  width: 2.7cqw;
  height: 2.7cqw;
  border-radius: 50%;
  background: var(--accent-bg);
  color: var(--accent);
  transition: background .15s ease, transform .15s ease;
}
.admin-main .dtile--domains .dom-card__add-plus svg {
  width: 55%;
  height: 55%;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
}
.admin-main .dtile--domains .dom-card--add:hover {
  border-color: var(--accent-border-soft);
  background: color-mix(in srgb, var(--accent) 6%, var(--card-bg));
}
.admin-main .dtile--domains .dom-card--add:hover .dom-card__add-text { color: var(--text-strong); }
.admin-main .dtile--domains .dom-card--add:hover .dom-card__add-plus { background: var(--accent); color: var(--accent-contrast); transform: scale(1.04); }
.admin-main .dtile--domains .dom-card--add:active .dom-card__add-plus { transform: scale(0.97); }
.admin-main .dtile--domains .dom-card--add:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .admin-main .dtile--domains .dom-card--add,
  .admin-main .dtile--domains .dom-card__add-plus,
  .admin-main .dtile--domains .dom-title { transition: none; }
}

/* ---- Responsive collapse ------------------------------------------------ */
@media (max-width: 1024px) {
  .admin-main .dash {
    grid-template-columns: 1fr 1fr;
    column-gap: 14px; row-gap: 14px;
  }
  .admin-main .dash-col { row-gap: 14px; }
  .admin-main .dash-col--left  { grid-column: 1; }
  .admin-main .dash-col--mid   { grid-column: 1 / -1; grid-row: 2; }
  .admin-main .dash-col--right { grid-column: 2; grid-row: 1; }
  .admin-main .dash-wide       { grid-row: 3; }
  .admin-main .dtile { --dash-radius: 16px; }
  .admin-main .dtile--domains { padding: 16px; }
  .admin-main .dtile--domains .dom-grid { gap: 14px; }
  .admin-main .dtile--domains .dom-sub { border-radius: 12px; }
}
@media (max-width: 620px) {
  /* One column. Flatten the column wrappers to `display: contents` so every
     tile becomes a direct grid child of .dash. Otherwise the three columns
     collide in the single 1fr track — their base grid-row/column still point at
     the desktop 3-up areas (left & right both sit in row 1) — AND aspect-ratio
     on a flex item inside a container-type ancestor paints as a thin strip.
     As grid items the tiles auto-flow down the column, source order, and size
     correctly from their aspect-ratio. */
  /* 2-колоночная сетка: почти все плитки на всю ширину (span обе колонки), но
     gauge (Онлайн сейчас) и finance (Столько заработали) делят ОДИН ряд —
     gauge слева, finance справа (запрос оператора). */
  .admin-main .dash { grid-template-columns: 1fr 1fr; gap: 12px; }
  .admin-main .dash-col { display: contents; }
  .admin-main .dash-wide,
  .admin-main .dtile--hero,
  .admin-main .dtile--chart,
  .admin-main .dtile--heat,
  .admin-main .dtile--regs,
  .admin-main .dtile--promo,
  .admin-main .dtile--domains { grid-column: 1 / -1; grid-row: auto; }
  .admin-main .dtile--gauge   { grid-column: 1; }
  .admin-main .dtile--finance { grid-column: 2; }
  /* Domains: the 1266/179 landscape ratio is nonsense at phone width — drop it
     and let the 2×2 sub-cards drive the tile height. */
  .admin-main .dtile--domains { aspect-ratio: auto; padding: 16px; }
  .admin-main .dtile--domains .dom-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .admin-main .dtile--domains .dom-sub { aspect-ratio: 5 / 3; }
  /* cqw fonts collapse at phone width — pin readable px for the whole card. */
  .admin-main .dtile--domains .dom-head { margin-bottom: 14px; }
  .admin-main .dtile--domains .dom-title { font-size: 16px; }
  .admin-main .dtile--domains .dom-card { padding: 12px 14px; }
  .admin-main .dtile--domains .dom-card__name { font-size: 14px; }
  .admin-main .dtile--domains .dom-card__num { font-size: 26px; }
  .admin-main .dtile--domains .dom-card__label { font-size: 12px; }
  .admin-main .dtile--domains .dom-globe { width: 44%; right: -10%; }
  .admin-main .dtile--domains .dom-card--add { gap: 10px; }
  .admin-main .dtile--domains .dom-card__add-text { font-size: 13px; }
  .admin-main .dtile--domains .dom-card__add-plus { width: 34px; height: 34px; }
  /* Hero: cqw fonts get tiny on a phone-width board — pin readable px. */
  .admin-main .dtile--hero .hero-greet { padding: 20px 0 14px 18px; }
  .admin-main .dtile--hero .hero-greet__title { font-size: 24px; line-height: 1.12; }
  /* Finance: cqw caption/padding need pins. */
  .admin-main .dtile--finance .fin { padding: 16px 16px 0; }
  .admin-main .fin__cap { font-size: 13px; margin-top: 8px; }

  /* ── Мобильная нормализация плиток дашборда ──────────────────────────────
     На десктопе каждая плитка держит aspect-ratio (пропорция от ширины). На
     телефоне это ломает вертикаль: landscape-плитки (chart/heat/hero) сплющены
     в полосу ~110px, а portrait finance раздут в полэкрана. Сбрасываем
     aspect-ratio → высота от контента + разумный min-height. domains уже auto. */
  .admin-main .dtile--gauge,
  .admin-main .dtile--promo,
  .admin-main .dtile--hero,
  .admin-main .dtile--chart,
  .admin-main .dtile--heat,
  .admin-main .dtile--finance,
  .admin-main .dtile--regs { aspect-ratio: auto; }

  .admin-main .dtile--chart   { min-height: 220px; }
  .admin-main .dtile--heat    { min-height: 180px; }
  .admin-main .dtile--hero    { min-height: 150px; }
  .admin-main .dtile--regs    { min-height: 260px; }
  .admin-main .dtile--promo   { min-height: 180px; }
  /* gauge + finance — пара в одном ряду: ОДИНАКОВАЯ фикс-высота (иначе finance
     из-за 3 стопкой раздувался выше gauge на ~9px). Контент центрируем по
     вертикали, чтобы пустота распределялась ровно, а не копилась снизу. */
  .admin-main .dtile--gauge,
  .admin-main .dtile--finance { min-height: 0; height: 210px; }

  /* Карточка «Онлайн сейчас» на мобиле (только home-дашборд, не статистика):
     размеры текста как у соседней finance-карточки + цифра СВЕРХУ, подпись СНИЗУ.
     Gauge — единый SVG (viewBox 311×260, рендер-масштаб ≈0.563), поэтому число и
     подпись двигаем/масштабируем через CSS на SVG-тексте:
       g-num  68px ×0.563 ≈ 38px  ← вровень с $34; поднимаем вверх
       g-title 21px ×0.563 ≈ 12px ← вровень с caption finance; опускаем под число */
  .admin-main .dash .dtile--gauge .g-num {
    font-size: 64px;
    transform: translateY(-37px);
  }
  .admin-main .dash .dtile--gauge .g-title {
    font-size: 21px;
    font-weight: 600;
    transform: translateY(65px);
  }
  /* Арку (спидометр) опускаем, чтобы её центр совпал с центром стикера справа —
     нижние визуалы обеих карточек в одной полосе, по центру. */
  .admin-main .dash .dtile--gauge :is(.g-track, .g-fill, .g-glow, .g-knob, .g-knob-hole, .g-sub) {
    transform: translateY(36px);
  }

  /* Смысловой порядок вместо source-order: приветствие → live-KPI (онлайн, $) →
     визуализации → лента → CTA-баннер → домены. `display: contents` на .dash-col
     делает плитки прямыми grid-детьми .dash — order применяется напрямую. */
  .admin-main .dtile--hero    { order: 1; }
  .admin-main .dtile--gauge   { order: 2; }
  .admin-main .dtile--finance { order: 3; }
  .admin-main .dtile--chart   { order: 4; }
  .admin-main .dtile--heat    { order: 5; }
  .admin-main .dtile--regs    { order: 6; }
  .admin-main .dtile--promo   { order: 7; }
  .admin-main .dtile--domains { order: 8; }

  /* Hero-стикер (Bugatti-Pepe): базовый width:22cqw + aspect-ratio 1/1 делал его
     квадратом во всю высоту сплющенной плитки. Фиксируем высоту, ширина — от арта.
     Скоуп :not(.shero-tile) — чтобы не задеть hero-стикер страницы статистики. */
  .admin-main .dtile--hero:not(.shero-tile) .hero-sticker {
    width: auto;
    height: 118px;
    aspect-ratio: auto;
    margin-inline-end: 6px;
  }

  /* Promo: .promo базово position:absolute;inset:0 → НЕ даёт высоту плитке,
     поэтому после сброса aspect-ratio контент (заголовок+текст+кнопка ≈260px)
     обрезался overflow:hidden в 180px. Делаем .promo in-flow → плитка растёт
     под контент. .promo остаётся positioned-контекстом для абсолютного стикера. */
  .admin-main .dtile--promo .promo {
    position: relative;
    inset: auto;
  }
  /* Текстовая колонка уступает место стикеру справа. */
  .admin-main .promo__body { width: auto; max-width: calc(100% - 150px); }
  /* Promo-стикер: арт портретный + preserveAspectRatio 'xMidYMax meet' →
     фигуру ограничивает ширина. Увеличиваем width → девушка выше (и шире
     пропорционально), стоит в правом нижнем углу баннера. */
  .admin-main .promo__sticker {
    width: 168px !important;
    right: -12px !important;
    bottom: -8px !important;
    height: auto !important;
  }

  /* Finance-контент по центру карточки (как gauge-арт), число ~в размер
     gauge-числа (не 61px fitAmount, который делал finance «тяжелее» gauge).
     Кап ~42px + ellipsis: короткие суммы ($34) читаются крупно, длинные не рвут
     плитку. Стикер компактный. */
  .admin-main .dtile--finance .fin { padding: 28px 14px 10px; justify-content: flex-start; }
  .admin-main .fin__amount {
    font-size: clamp(28px, 9.5vw, 38px) !important;
    line-height: 1.15;          /* было 1.02 — плотная строка + overflow:hidden срезала верх глифов */
    overflow: visible;          /* по вертикали не режем; длинные суммы клипует overflow:hidden самой плитки */
  }
  .admin-main .fin__cap { font-size: 12px; margin-top: 5px; }
  /* Стикер заполняет всё нижнее пространство карточки, чтобы лотти-фигура была
     крупной (не «вдвое меньше спидометра»). Лотти центрируется по aspect. */
  .admin-main .fin__sticker {
    flex: 1 1 auto !important;
    min-height: 0;
    height: auto;
    margin: 4px 0 0;
  }
}

/* ==========================================================================
   "Динамика депозитов" chart tile
   --------------------------------------------------------------------------
   Header (title + segmented period control) over a bespoke responsive SVG
   chart (modules/area-chart.js + deposits-chart.js). All colours are theme-
   local custom properties so DARK == the reference (white line, white tooltip
   chip, white active pill) and LIGHT inverts cleanly (dark line, dark chip).
   The `.dchart` component is self-contained — the tile only lends it padding —
   so it can be reused in other tiles later. Header scales in cqw with the
   board (like the hero); the plot's SVG labels stay a fixed, readable px.
   ========================================================================== */
.admin-main .dchart {
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* light (default) */
  --dc-line: #12151a;
  --dc-grad-top: rgba(16, 19, 25, .09);
  --dc-grad-bot: rgba(16, 19, 25, 0);
  --dc-grid: var(--chart-grid);
  --dc-tick: var(--chart-tick);
  --dc-cross: color-mix(in srgb, var(--text-strong) 24%, transparent);
  --dc-marker: #12151a;
  --dc-marker-ring: var(--card-bg);
  --dc-tip-bg: #12151a;
  --dc-tip-fg: #ffffff;
  --dc-seg-bg: #f5f6f7;
  --dc-seg-border: #e7e9ec;
  --dc-seg-fg: var(--text-muted);
  --dc-seg-hover-bg: #eaecef;
  --dc-seg-active-bg: #12151a;
  --dc-seg-active-fg: #ffffff;
  --dc-seg-active-hover-bg: #262a31;
  /* column chart (modules/bar-chart.js) — ahefi "Activity": muted columns,
     the active one in full contrast; deposits = the locked earnings green */
  --bc-bar: #e3e6e9;
  --bc-on: #12151a;
  --bc-green: #05b200;
  --bc-green-dim: color-mix(in srgb, #05b200 32%, var(--card-bg));
  --bc-band: rgba(16, 19, 25, .04);
  --bc-grid: rgba(16, 19, 25, .06);
  --bc-sk: rgba(16, 19, 25, .07);
  --bc-tip-bg: #ffffff;
  --bc-tip-border: #e4e7ea;
  --bc-tip-shadow: 0 6px 18px rgba(16, 19, 25, .08);
}
[data-theme="dark"] .admin-main .dchart {
  --dc-line: #f4f6f8;
  --dc-grad-top: rgba(255, 255, 255, .11);
  --dc-grad-bot: rgba(255, 255, 255, 0);
  --dc-cross: rgba(255, 255, 255, .24);
  --dc-marker: #ffffff;
  --dc-marker-ring: var(--card-bg);
  --dc-tip-bg: #ffffff;
  --dc-tip-fg: #12151a;
  --dc-seg-bg: #232a30;
  --dc-seg-border: #2e363d;
  --dc-seg-hover-bg: #2d353c;
  --dc-seg-active-bg: #f4f6f8;
  --dc-seg-active-fg: #12151a;
  --dc-seg-active-hover-bg: #ffffff;
  --bc-bar: #363e46;
  --bc-on: #f4f6f8;
  --bc-green-dim: color-mix(in srgb, #05b200 36%, var(--card-bg));
  --bc-band: rgba(255, 255, 255, .035);
  --bc-grid: rgba(255, 255, 255, .05);
  --bc-sk: rgba(255, 255, 255, .06);
  --bc-tip-bg: #262d33;
  --bc-tip-border: #3a434b;
  --bc-tip-shadow: 0 8px 22px rgba(0, 0, 0, .35);
}
/* tile placement — padding + clip only (layout/tokens live on .dchart) */
.admin-main .dtile--chart { padding: 1.55cqw 1.6cqw 1.15cqw; overflow: hidden; }

/* ---- header ---- */
.admin-main .dchart__head {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.admin-main .dchart__title {
  margin: 0; color: var(--text-strong);
  font-size: clamp(13px, 1.18cqw, 16px);
  font-weight: 700; letter-spacing: -.015em; line-height: 1.2;
  white-space: nowrap;
}

/* ---- segmented period control ----
   Form of the ahefi "Activity" switch: bordered rounded-rect track, rounded-rect
   buttons, the active one inverted. Outer size unchanged vs the old pill
   (2px padding + 1px border = the former 3px padding). */
.admin-main .dchart__seg {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 2px;
  padding: 2px; border: 1px solid var(--dc-seg-border); border-radius: 10px;
  background: var(--dc-seg-bg);
}
.admin-main .dchart__seg-btn {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  font-family: var(--font-ui);
  font-size: clamp(11px, .95cqw, 13.5px); font-weight: 600;
  color: var(--dc-seg-fg);
  padding: clamp(4px, .42cqw, 7px) clamp(9px, .92cqw, 15px);
  border-radius: 7px; line-height: 1; white-space: nowrap;
  transition: color .15s cubic-bezier(.4, 0, .2, 1), background-color .15s cubic-bezier(.4, 0, .2, 1), transform .15s cubic-bezier(.4, 0, .2, 1);
}
.admin-main .dchart__seg-btn:hover { background: var(--dc-seg-hover-bg); color: var(--text-strong); }
.admin-main .dchart__seg-btn:active { transform: scale(.97); }
.admin-main .dchart__seg-btn.is-active { background: var(--dc-seg-active-bg); color: var(--dc-seg-active-fg); }
.admin-main .dchart__seg-btn.is-active:hover { background: var(--dc-seg-active-hover-bg); color: var(--dc-seg-active-fg); }
.admin-main .dchart__seg-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---- plot ---- */
.admin-main .dchart__plot { flex: 1 1 auto; min-height: 0; margin-top: .8cqw; }
.admin-main .dchart-host { width: 100%; height: 100%; }
.admin-main .dchart-svg { display: block; width: 100%; height: 100%; overflow: visible; touch-action: pan-y; }

/* ---- chart elements ---- */
.admin-main .dchart-grid   { stroke: var(--dc-grid); stroke-width: 1; stroke-dasharray: 2 5; }
.admin-main .dchart-ylabel { fill: var(--dc-tick); font: 500 11px var(--font-ui); text-anchor: end; }
.admin-main .dchart-xlabel { fill: var(--dc-tick); font: 500 11px var(--font-ui); }
.admin-main .dchart-xactive    { fill: var(--text-strong); font: 600 11px var(--font-ui); font-variant-numeric: tabular-nums; }
.admin-main .dchart-xactive-bg { fill: var(--card-bg); }
.admin-main .dchart-grad-top { stop-color: var(--dc-grad-top); }
.admin-main .dchart-grad-bot { stop-color: var(--dc-grad-bot); }
.admin-main .dchart-area   { stroke: none; }
.admin-main .dchart-line   { fill: none; stroke: var(--dc-line); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.admin-main .dchart-line--flat { stroke-width: 1.5; opacity: .45; }
.admin-main .dchart-cross  { stroke: var(--dc-cross); stroke-width: 1; stroke-dasharray: 2 3; }
.admin-main .dchart-marker { fill: var(--dc-marker); stroke: var(--dc-marker-ring); stroke-width: 2.5; }
.admin-main .dchart-tip-bg { fill: var(--dc-tip-bg); filter: drop-shadow(0 2px 5px rgba(0, 0, 0, .22)); }
.admin-main .dchart-tip-txt {
  fill: var(--dc-tip-fg); font: 700 12.5px var(--font-ui);
  font-variant-numeric: tabular-nums;
}

/* ---- states ---- */
.admin-main .dchart-note text { fill: var(--text-muted); font: 500 12.5px var(--font-ui); }
.admin-main .dchart-note.is-error text { fill: var(--red); }
.admin-main .dchart-skel-line {
  stroke: var(--dc-grid); stroke-width: 6; stroke-linecap: round; opacity: .5;
  animation: dchart-pulse 1.4s ease-in-out infinite;
}
@keyframes dchart-pulse { 0%, 100% { opacity: .22; } 50% { opacity: .6; } }

/* ---- column chart (modules/bar-chart.js) ---- */
.admin-main .bchart { position: relative; }
.admin-main .bchart__svg {
  position: absolute; inset: 0; display: block; overflow: visible;
  touch-action: pan-y; font-family: var(--font-ui); border-radius: 8px;
}
.admin-main .bchart__svg:focus { outline: none; }
.admin-main .bchart__svg:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.admin-main .bchart__grid { stroke: var(--bc-grid); stroke-width: 1; shape-rendering: crispEdges; }
.admin-main .bchart__axis {
  fill: var(--chart-tick); font-size: 11px; font-weight: 500;
  font-variant-numeric: tabular-nums; letter-spacing: .01em;
}
.admin-main .bchart__axis--right { fill: color-mix(in srgb, var(--bc-green) 58%, var(--chart-tick)); }

.admin-main .bchart__band { fill: transparent; transition: fill .15s cubic-bezier(.4, 0, .2, 1); }
.admin-main .bchart__band.is-on { fill: var(--bc-band); }

.admin-main .bchart__bar { transition: fill .15s cubic-bezier(.4, 0, .2, 1); }
.admin-main .bchart__bar--mono { fill: var(--bc-bar); }
.admin-main .bchart__bar--mono.is-on { fill: var(--bc-on); }
.admin-main .bchart__bar--green { fill: var(--bc-green-dim); }
.admin-main .bchart__bar--green.is-on { fill: var(--bc-green); }
.admin-main .bchart__bars.is-enter .bchart__bar {
  transform-box: fill-box; transform-origin: 50% 100%;
  animation: bchart-grow .42s cubic-bezier(.2, .7, .2, 1) both;
}
@keyframes bchart-grow { from { transform: scaleY(0); } to { transform: scaleY(1); } }

.admin-main .bchart__day {
  fill: var(--chart-tick); font-size: 11px; font-weight: 500;
  font-variant-numeric: tabular-nums; letter-spacing: .03em;
  transition: fill .15s cubic-bezier(.4, 0, .2, 1);
}
.admin-main .bchart__day.is-on { fill: var(--text-strong); font-weight: 600; }
.admin-main .bchart__day.is-hidden { visibility: hidden; }

.admin-main .bchart__tip {
  position: absolute; z-index: 3; pointer-events: none;
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px 12px; border-radius: 12px; white-space: nowrap;
  background: var(--bc-tip-bg); border: 1px solid var(--bc-tip-border);
  box-shadow: var(--bc-tip-shadow); font-family: var(--font-ui);
}
.admin-main .bchart__tip[hidden] { display: none !important; }
.admin-main .bchart__tip-day {
  font-size: 10px; font-weight: 600; line-height: 1.5; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-muted);
}
.admin-main .bchart__tip-row { display: flex; align-items: center; gap: 6px; }
.admin-main .bchart__tip-val {
  font-size: 16px; font-weight: 600; letter-spacing: -.012em; line-height: 1.3;
  color: var(--text-strong); font-variant-numeric: tabular-nums;
}
.admin-main .bchart__tip-key ~ .bchart__tip-val { font-size: 14px; }
.admin-main .bchart__tip-lab { font-size: 12px; color: var(--text-muted); }
.admin-main .bchart__tip-key { flex: none; width: 8px; height: 8px; border-radius: 2px; }
.admin-main .bchart__tip-key--mono { background: var(--bc-on); }
.admin-main .bchart__tip-key--green { background: var(--bc-green); }

.admin-main .bchart__note { fill: var(--text-muted); font-size: 12.5px; font-weight: 500; }
.admin-main .bchart__note.is-error { fill: var(--red); }
.admin-main .bchart__sk-block { fill: var(--bc-sk); animation: dchart-pulse 1.4s ease-in-out infinite; }
.admin-main .bchart__sr {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (prefers-reduced-motion: reduce) {
  .admin-main .dchart-skel-line { animation: none; }
  .admin-main .dchart__seg-btn { transition: none; }
  .admin-main .bchart__sk-block,
  .admin-main .bchart__bars.is-enter .bchart__bar { animation: none; }
  .admin-main .bchart__band,
  .admin-main .bchart__bar,
  .admin-main .bchart__day { transition: none; }
}

/* Phone board — cqw header fonts get tiny; pin readable px like the hero. */
@media (max-width: 620px) {
  .admin-main .dtile--chart { padding: 14px 14px 10px; }
  /* Заголовок (nowrap ~145px) + 5-кнопочный сегмент не влезали в ~362px —
     «Все» обрезалось. Ужимаем сегмент и зазоры, чтобы всё поместилось. */
  .admin-main .dchart__head { gap: 8px; }
  .admin-main .dchart__title { font-size: 14px; }
  .admin-main .dchart__seg { gap: 1px; padding: 1px; border-radius: 9px; }
  .admin-main .dchart__seg-btn { border-radius: 7px; }
  .admin-main .dchart__seg-btn { font-size: 11px; padding: 5px 8px; }
  .admin-main .dchart__plot { margin-top: 8px; }
  /* Tiles lose aspect-ratio here and `.dchart { min-height: 0 }` outranks the
     tile min-height, so the plot must hold its own height (the old line chart
     got the same 150px from the SVG's default size). */
  .admin-main .dtile--chart .bchart { min-height: 150px; }
}

/* ==========================================================================
   "Активность регистраций" — registration-activity heatmap.
   Component: modules/reg-heatmap.js. Render engine: vendor/gh-heatmap.js (MIT).
   Selectors are UNPREFIXED (.dheat, not .admin-main .dheat) so the fullscreen
   overlay — appended to <body>, outside .admin-main — reuses the same tokens.
   The warm scale is the sampled reference (dark = faithful 1:1); light is a
   derived warm ramp. Cells/gaps are px custom props set live by the module so
   6 rows stay square and columns fill the tile at any size.
   ========================================================================== */
/* tile placement — padding + clip only, like the chart tile */
.admin-main .dtile--heat { padding: 1.55cqw 1.6cqw 1.15cqw; overflow: hidden; }

.dheat {
  position: relative;
  display: flex; flex-direction: column; min-height: 0; height: 100%;
  /* light (default) — derived warm ramp */
  --hm-0: #eee7e0; --hm-1: #f6d3ac; --hm-2: #f2a862; --hm-3: #ec7d34;
  --hm-4: #e75f1c; --hm-5: #f0a500; --hm-6: #f5c518;
  /* Цвет числа В клетке. По умолчанию белый; на светло-жёлтых уровнях белый
     физически не читается (контраст ~1.2:1), там тёплый чёрный. */
  --hm-ink-1: #4a2a12; --hm-ink-2: #3d2008; --hm-ink-3: #fff;
  --hm-ink-4: #fff;    --hm-ink-5: #3d2008; --hm-ink-6: #3d2008;
  /* tooltip MATCHES the theme (dark box on dark, light on light) — token-driven,
     so both blocks resolve automatically; not the old inverted chip. */
  --hm-tip-bg: var(--card-bg); --hm-tip-fg: var(--text-strong);
}
[data-theme="dark"] .dheat {
  /* faithful reference — colours sampled from admnewww/our copy.png */
  --hm-0: #3a2820; --hm-1: #5e3020; --hm-2: #8a3b21; --hm-3: #c94e1e;
  --hm-4: #ec5624; --hm-5: #fabf4a; --hm-6: #fae654;
  --hm-ink-1: #fff;    --hm-ink-2: #fff;    --hm-ink-3: #fff;
  --hm-ink-4: #fff;    --hm-ink-5: #2b1508; --hm-ink-6: #2b1508;
}

/* Period-scoped heatmap (statistics board). The tile keeps its height — the middle
   column's height is load-bearing (its bottom lines up with the taller left/right
   columns, which balloon on wide boards via the finance tile's aspect-ratio), so
   shrinking it would leave a void below the card. Instead the grid is content-sized
   and the whole heatmap block is CENTERED vertically: a short range (few rows, cells
   capped at 34px) reads as a centered chart with balanced padding, not cells jammed
   to the top with a big empty gap beneath. Home's all-time heatmap (no .dheat--period)
   fills its tile as before. */
.dheat--period .dheat__body { justify-content: center; }
.dheat--period .dheat__grid { flex: 0 0 auto; min-height: 0; }

/* ---- header (mirrors .dchart__head) ---- */
.dheat__head { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.dheat__title {
  margin: 0; color: var(--text-strong);
  font-size: clamp(13px, 1.18cqw, 16px);
  font-weight: 700; letter-spacing: -.015em; line-height: 1.2; white-space: nowrap;
}
.dheat__expand {
  appearance: none; border: 0; background: transparent; color: var(--text-muted);
  cursor: pointer; padding: 4px; border-radius: 8px; display: inline-flex; line-height: 0;
  transition: color .15s ease, background-color .15s ease;
}
.dheat__expand:hover { color: var(--text-strong); background: color-mix(in srgb, var(--text-strong) 8%, transparent); }
.dheat__expand:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dheat__expand svg { width: 16px; height: 16px; }

/* ---- body / grid / months ---- */
.dheat__body { position: relative; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; margin-top: .35cqw; }
.dheat__grid { flex: 1 1 auto; min-height: 56px; }
.dheat .ghm-grid {
  display: grid; grid-auto-flow: column; align-content: start;
  grid-template-rows: repeat(var(--ghm-rows, 6), var(--ghm-cell, 12px));
  grid-auto-columns: var(--ghm-cell, 12px);
  gap: var(--ghm-gap, 4px);
}
.dheat .entry {
  background: var(--hm-0); border-radius: var(--ghm-radius, 3px);
  outline: 1.5px solid transparent; outline-offset: -1px;
  transition: outline-color .12s ease;
  /* число регистраций внутри клетки: строго по центру, кегль (--ghm-fs) считает
     модуль под размер клетки — цифра занимает ≤50% клетки, не растягивается */
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  font: 700 var(--ghm-fs, 0px)/1 var(--font-ui);
  font-variant-numeric: tabular-nums; letter-spacing: -.04em;
  -webkit-user-select: none; user-select: none;
}
.dheat .entry.is-hover { outline-color: color-mix(in srgb, var(--text-strong) 55%, transparent); }
.dheat .color-0 { background: var(--hm-0); }
.dheat .color-1 { background: var(--hm-1); color: var(--hm-ink-1); }
.dheat .color-2 { background: var(--hm-2); color: var(--hm-ink-2); }
.dheat .color-3 { background: var(--hm-3); color: var(--hm-ink-3); }
.dheat .color-4 { background: var(--hm-4); color: var(--hm-ink-4); }
.dheat .color-5 { background: var(--hm-5); color: var(--hm-ink-5); }
.dheat .color-6 { background: var(--hm-6); color: var(--hm-ink-6); }

.dheat__months { position: relative; height: 14px; margin-top: 5px; flex: 0 0 auto; }
.dheat__months span {
  position: absolute; top: 0;
  font: 500 clamp(10px, .82cqw, 12px)/1 var(--font-ui);
  color: var(--text-muted); white-space: nowrap; letter-spacing: .01em;
}

/* ---- styled tooltip (count + date) ---- */
.dheat__tip {
  position: absolute; z-index: 6; pointer-events: none; transform: translate(-50%, -100%);
  background: var(--hm-tip-bg); color: var(--hm-tip-fg);
  border: 1px solid var(--border);
  padding: 6px 9px; border-radius: 8px; white-space: nowrap;
  font: 600 12px/1.25 var(--font-ui); font-variant-numeric: tabular-nums;
  box-shadow: var(--shadow-lg);
}
.dheat__tip b { font-weight: 700; }
.dheat__tip-d { display: block; margin-top: 1px; font-weight: 500; font-size: 11px; opacity: .7; }
.dheat__tip::after {
  content: ""; position: absolute; left: 50%; top: 100%; transform: translateX(-50%);
  border: 5px solid transparent; border-top-color: var(--hm-tip-bg);
}
/* flipped below the cell (top rows) — tail points up */
.dheat__tip--below { transform: translate(-50%, 0); }
.dheat__tip--below::after {
  top: auto; bottom: 100%; border-top-color: transparent; border-bottom-color: var(--hm-tip-bg);
}

/* ---- states ---- */
.dheat__note {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  gap: 8px; text-align: center; color: var(--text-muted); font: 500 12.5px var(--font-ui);
}
.dheat__retry {
  appearance: none; border: 1px solid var(--border); background: transparent; cursor: pointer;
  color: var(--text-strong); font: 600 12px var(--font-ui); padding: 4px 10px; border-radius: 8px;
}
.dheat__retry:hover { background: color-mix(in srgb, var(--text-strong) 8%, transparent); }
.dheat.is-loading .entry { animation: dheat-pulse 1.4s ease-in-out infinite; }
@keyframes dheat-pulse { 0%, 100% { opacity: .5; } 50% { opacity: .85; } }

/* ---- fullscreen overlay ---- */
.dheat-overlay {
  position: fixed; inset: 0; z-index: 9999; display: flex;
  padding: clamp(16px, 4vw, 48px);
  background: rgba(8, 10, 13, .72); backdrop-filter: blur(6px);
  animation: dheat-fade .18s ease-out;
}
.dheat-overlay__card {
  margin: auto; width: min(1180px, 94vw); max-height: 90vh; overflow: auto;
  background: var(--card-bg); border: 1px solid var(--border);
  border-radius: 16px; box-shadow: var(--shadow); padding: 24px;
}
/* content-height card: the grid is a FIXED height (not stretch-to-fill) so the
   fullscreen view shows a comfortably-sized larger heatmap with more history,
   not six giant rows. */
.dheat--full { height: auto; }
.dheat--full .dheat__grid { flex: 0 0 auto; height: clamp(132px, 22vh, 184px); }
.dheat--full .dheat__title { font-size: 20px; }
@keyframes dheat-fade { from { opacity: 0; } to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .dheat.is-loading .entry { animation: none; }
  .dheat .entry, .dheat__expand { transition: none; }
  .dheat-overlay { animation: none; }
}

@media (max-width: 620px) {
  .admin-main .dtile--heat { padding: 14px; }
  .dheat__title { font-size: 15px; }
}

/* ==========================================================================
   "Последние депозиты" — compact deposit ledger in the right-column tile
   (.dtile--regs). Title metrics mirror .dheat__title 1:1 (same cqw clamp,
   resolved against .dash-page), so it reads identical to "Активность
   регистраций". Each row: clickable username (underlines on hover, opens the
   user's settings), deposit amount (mono, green), full MSK timestamp.
   ========================================================================== */
.admin-main .dtile--regs { padding: 1.55cqw 1.6cqw 1.15cqw; overflow: hidden; }

.rdep { position: relative; display: flex; flex-direction: column; min-height: 0; height: 100%; }

.rdep__head { flex: 0 0 auto; }
.rdep__title {
  margin: 0; color: var(--text-strong);
  font-size: clamp(13px, 1.18cqw, 16px);
  font-weight: 700; letter-spacing: -.015em; line-height: 1.2; white-space: nowrap;
}

/* body — vertical stack that fills the tile; scrolls only if rows overrun.
   It's ALSO the query container for the rows (see the two row layouts below).
   The container lives HERE, not on the tile, so the title's cqw (a sibling in
   .rdep__head, outside this element) still resolves against .dash-page and
   stays 1:1 with the "Активность регистраций" title. */
.rdep__list {
  list-style: none; margin: .6cqw 0 0; padding: 0 2px 0 0;
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
  overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--border) transparent;
  container-type: inline-size;
}
.rdep__list::-webkit-scrollbar { width: 6px; }
.rdep__list::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
.rdep__list::-webkit-scrollbar-track { background: transparent; }

/* Row = one deposit. Narrow tiles STACK it (username + amount on the top line,
   full date below); once the ledger has room (≥360px) it collapses to a SINGLE
   line — username · amount · date, the requested order. Both layouts keep the
   username visible: it truncates with an ellipsis, never squeezed to nothing.
   Fonts are all Inter (project rule: admin text is Inter only) with tabular
   numerals so the amounts and timestamps still align vertically. */
.rdep__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "user amt"
    "date date";
  align-items: center; column-gap: 12px; row-gap: 2px; padding: 8px 4px;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
  transition: background-color .14s ease;
}
.rdep__row:last-child { border-bottom: 0; }
.rdep__row:not(.rdep__row--skel):hover { background: color-mix(in srgb, var(--text-strong) 5%, transparent); }

@container (min-width: 360px) {
  .rdep__row {
    grid-template-columns: minmax(0, 1fr) auto auto;
    grid-template-areas: "user amt date";
    column-gap: 14px; row-gap: 0; padding: 9px 4px;
  }
}

/* username — link by default (opens #users/<tenant>/<addr>/data), underlines
   on hover; truncates instead of pushing the amount/date off the row. */
.rdep__user {
  grid-area: user;
  min-width: 0; max-width: 100%; display: inline-block;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--text-strong); font: 500 13px/1.35 var(--font-ui);
  text-decoration: none; text-underline-offset: 3px;
  transition: color .14s ease;
}
.rdep__user:hover { color: var(--accent); text-decoration: underline; }
.rdep__user:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
.rdep__user--static { color: var(--text); cursor: default; }

.rdep__amt {
  grid-area: amt; justify-self: end;
  font: 600 13px/1.35 var(--font-ui); font-variant-numeric: tabular-nums;
  color: var(--green); white-space: nowrap;
}
.rdep__date {
  grid-area: date;
  font: 500 11.5px/1.35 var(--font-ui); font-variant-numeric: tabular-nums;
  color: var(--text-muted); white-space: nowrap;
}

/* loading skeleton — pulsing placeholders in the row's own grid tracks. */
.rdep__row--skel { pointer-events: none; }
.rdep__sk {
  height: 11px; border-radius: 4px;
  background: color-mix(in srgb, var(--text-strong) 12%, transparent);
  animation: rdep-pulse 1.4s ease-in-out infinite;
}
.rdep__sk--user { grid-area: user; width: 42%; }
.rdep__sk--amt  { grid-area: amt; justify-self: end; width: 52px; }
.rdep__sk--date { grid-area: date; width: 104px; }
@keyframes rdep-pulse { 0%, 100% { opacity: .5; } 50% { opacity: .85; } }

/* empty / error — centered in the tile, with character (banknote glyph). */
.rdep__state {
  flex: 1 1 auto; border-bottom: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 14px; text-align: center; color: var(--text-muted);
}
.rdep__state-ic { color: color-mix(in srgb, var(--text-muted) 65%, transparent); line-height: 0; }
.rdep__state-ic svg { width: 46px; height: auto; }
.rdep__state-txt { font: 500 12.5px var(--font-ui); }
.rdep__retry {
  appearance: none; border: 1px solid var(--border); background: transparent; cursor: pointer;
  color: var(--text-strong); font: 600 12px var(--font-ui); padding: 5px 12px; border-radius: 8px;
  transition: background-color .14s ease;
}
.rdep__retry:hover { background: color-mix(in srgb, var(--text-strong) 8%, transparent); }

@media (prefers-reduced-motion: reduce) {
  .rdep__sk { animation: none; }
  .rdep__row, .rdep__user, .rdep__retry { transition: none; }
}
