/* QUST RUST — profile decoration
   Everything a player can wear. Two colours arrive as --c1/--c2 and the look
   arrives as a class; nothing here reads a value the player typed.

   All movement is switched off under prefers-reduced-motion at the bottom of
   the file — the shop still sells the look, it just stops moving. */

/* ============================================================ имя ========= */

.cos-name{font-weight:600}

/* Two colours across the letters. Painting the text with a clipped background
   is the only way to get a gradient into glyphs; the fallback colour keeps the
   name readable if the clip is unsupported. */
.cos-name-gradient{
  color:var(--c1);
  background-image:linear-gradient(100deg,var(--c1),var(--c2),var(--c1));
  background-size:100% 100%;
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;
}

/* Металл, а не мягкий перелив.
   Блик был растянут на треть имени и читался как выцветание. У полированного
   металла подсвет узкий и резкий: восемь процентов ширины, белое ядро и
   обратный скат — только тогда по букве видно, что она блестит. */
.cos-name-shimmer{
  color:var(--c1);
  background-image:linear-gradient(100deg,
    var(--c1) 0%,var(--c1) 38%,
    var(--c2) 46%,#ffffff 50%,var(--c2) 54%,
    var(--c1) 62%,var(--c1) 100%);
  background-size:300% 100%;
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;
  filter:drop-shadow(0 0 5px color-mix(in srgb,var(--c1) 45%,transparent));
  animation:cos-sheen 4s linear infinite;
}
@keyframes cos-sheen{from{background-position:180% 0}to{background-position:-80% 0}}

/* a soft light around the letters, breathing slowly */
/* Свет в три слоя: плотное ядро у самой буквы, средний ореол и дальний развал.
   Один слой на двенадцать пикселей давал ровное пятно — оно читается как
   нерезкость, а не как свечение. */
.cos-name-halo{
  color:var(--c1);
  text-shadow:
    0 0 4px color-mix(in srgb,var(--c1) 90%,transparent),
    0 0 12px color-mix(in srgb,var(--c1) 55%,transparent),
    0 0 26px color-mix(in srgb,var(--c1) 28%,transparent);
  animation:cos-halo 3s ease-in-out infinite;
}
@keyframes cos-halo{
  0%,100%{text-shadow:
    0 0 3px color-mix(in srgb,var(--c1) 75%,transparent),
    0 0 9px color-mix(in srgb,var(--c1) 38%,transparent),
    0 0 18px color-mix(in srgb,var(--c1) 18%,transparent)}
  50%{text-shadow:
    0 0 5px color-mix(in srgb,var(--c1) 100%,transparent),
    0 0 17px color-mix(in srgb,var(--c1) 70%,transparent),
    0 0 38px color-mix(in srgb,var(--c1) 38%,transparent)}
}

/* Highlight, not just ink. A colour applied only to the glyphs disappears
   against a busy row; these give the name a surface of its own. Each keeps the
   text itself readable — the colour goes around the letters, not into them. */

/* a plate behind the name, like a tag */
.cos-name-plate{
  padding:.05em .45em;border-radius:999px;
  background:color-mix(in srgb,var(--c1) 18%,transparent);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--c1) 40%,transparent);
}

/* a drawn edge around the letters; the fill stays the page's text colour so
   it reads at any size, and the outline carries the identity */
/* Гравировка. Обводка в полпикселя пропадала на любом экране без ретины, а
   без тёмной подложки снизу буква лежала на фоне плоско. Толще вдвое, свет
   снаружи и тень под кромкой — тогда видно, что она выбита, а не подкрашена. */
.cos-name-edge{
  color:var(--text,#eaedf2);
  -webkit-text-stroke:1.2px var(--c1);
  paint-order:stroke fill;
  text-shadow:
    0 0 7px color-mix(in srgb,var(--c1) 70%,transparent),
    0 0 18px color-mix(in srgb,var(--c1) 30%,transparent),
    0 1px 0 rgba(0,0,0,.55);
}

/* a bar under the name that fills in and drains back */
.cos-name-underline{position:relative}
.cos-name-underline::after{
  content:"";position:absolute;left:-.1em;right:-.1em;bottom:-.14em;height:3px;border-radius:3px;
  background:linear-gradient(90deg,var(--c1),var(--c2),#fff,var(--c2),var(--c1));
  background-size:260% 100%;
  /* полоса без свечения выглядит как рамка таблицы, а не как подсветка */
  box-shadow:0 0 8px color-mix(in srgb,var(--c1) 70%,transparent),
             0 0 18px color-mix(in srgb,var(--c1) 30%,transparent);
  animation:cos-sheen 4s linear infinite;
}

/* =========================================================== значок ====== */

.cos-badge{
  display:inline-block;margin-left:.35rem;line-height:1;vertical-align:middle;
  color:var(--c1);
}
/* Значки живут покадрово, как спрайты.

   Плавные ease-in-out и размытая тень тянули их в ту же мягкость, от которой
   ушли имена и обложки. Здесь восьмибитность даёт не растр, а сама подача:
   считанное число кадров и жёсткая тень со смещением на пиксель вместо
   размытого ореола — так рисовали свечение, когда размывать было нечем. */

.cos-badge-glow{
  text-shadow:
    1px 0 0 color-mix(in srgb,var(--c1) 55%,transparent),
    -1px 0 0 color-mix(in srgb,var(--c1) 55%,transparent),
    0 1px 0 color-mix(in srgb,var(--c1) 55%,transparent),
    0 -1px 0 color-mix(in srgb,var(--c1) 55%,transparent);
  animation:cos-badge-blink 1.8s steps(1,end) infinite;
}
/* четыре ступени яркости и обратно — ровно как мигали значки на спрайтовых
   панелях, где плавного перехода не существовало */
@keyframes cos-badge-blink{
  0%,100%{opacity:1}
  25%{opacity:.72}
  50%{opacity:.5}
  75%{opacity:.72}
}

/* два кадра: обычный и крупный. Третьего у спрайта нет */
.cos-badge-beat{animation:cos-badge-beat 1.6s steps(1,end) infinite}
@keyframes cos-badge-beat{
  0%,74%{transform:scale(1)}
  76%,88%{transform:scale(1.28)}
  90%,100%{transform:scale(1)}
}

/* Оборот кадрами, но частыми.
   
   Восьми за три секунды оказалось мало: между углами проходило почти полсекунды,
   и знак не крутился, а подтормаживал. Шестнадцать за две с половиной читаются
   как спрайтовое вращение — рывок различим, но движение не рвётся. */
.cos-badge-spin{
  text-shadow:1px 1px 0 color-mix(in srgb,var(--c2) 60%,transparent);
  animation:cos-spin 2.4s steps(16,end) infinite;
}
@keyframes cos-spin{to{transform:rotate(360deg)}}

/* ============================================================ рамка ====== */

.cos-av{
  position:relative;flex:0 0 auto;display:inline-grid;place-items:center;
  width:var(--px);height:var(--px);border-radius:50%;line-height:0;
}
.cos-av>img{width:100%;height:100%;border-radius:50%;object-fit:cover;display:block}
.cos-av-none{
  display:grid;place-items:center;width:100%;height:100%;border-radius:50%;
  background:var(--surface-2);color:var(--muted);
  font-size:calc(var(--px)*.42);font-weight:700;line-height:1;
}

.cos-av-solid{box-shadow:0 0 0 2px var(--c1)}
/* Свечение рамки — концентрические кольца, а не размытая клякса.
   
   Размытие в четырнадцать пикселей было единственным местом, где оправа ещё
   растекалась: рядом с пиксельным именем и пиксельной обложкой это читалось
   как недоделка. Три кольца с падающей плотностью дают тот же ореол ступенями
   — так его и рисовали, когда размывать было нечем. */
.cos-av-glow{
  box-shadow:
    0 0 0 2px var(--c1),
    0 0 0 4px color-mix(in srgb,var(--c1) 42%,transparent),
    0 0 0 6px color-mix(in srgb,var(--c1) 16%,transparent);
}
.cos-av-dashed{outline:2px dashed var(--c1);outline-offset:2px}

.cos-av-pulse{box-shadow:0 0 0 2px var(--c1)}
.cos-av-pulse::after{
  content:"";position:absolute;inset:-3px;border-radius:50%;
  box-shadow:0 0 0 2px var(--c2);opacity:.9;
  animation:cos-ring 2.4s ease-out infinite;
}
@keyframes cos-ring{
  0%{transform:scale(.96);opacity:.85}
  70%{transform:scale(1.22);opacity:0}
  100%{transform:scale(1.22);opacity:0}
}

/* Кольцо, которое правда вращается: конический градиент живёт на ::before за
   картинкой и обрезан маской в полоску, поэтому сам аватар стоит на месте.

   Вращение плавное, а не покадровое. Покадровость — это про спрайт, который
   целиком меняет кадр; равномерно едущий градиент от неё просто дёргается, и
   вместо ретро выходит подтормаживание. Восьмибитность у рамок держится на
   форме — жёстких концентрических кольцах без размытия, — а не на рывках. */
.cos-av-orbit::before,
.cos-av-spark::before{
  content:"";position:absolute;inset:-3px;border-radius:50%;z-index:0;
  background:conic-gradient(from 0deg,transparent 0deg,var(--c1) 70deg,var(--c2) 150deg,transparent 220deg,transparent 360deg);
  -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 3px),#000 calc(100% - 3px));
  mask:radial-gradient(farthest-side,transparent calc(100% - 3px),#000 calc(100% - 3px));
  animation:cos-spin 3.4s linear infinite;
}
.cos-av-orbit>img,.cos-av-spark>img,
.cos-av-orbit>.cos-av-none,.cos-av-spark>.cos-av-none{position:relative;z-index:1}

/* the top of the ladder: the turning ring plus a light that breathes with it */
.cos-av-spark{box-shadow:0 0 0 1px color-mix(in srgb,var(--c1) 60%,transparent)}
.cos-av-spark::after{
  content:"";position:absolute;inset:-6px;border-radius:50%;z-index:0;
  box-shadow:
    0 0 0 2px color-mix(in srgb,var(--c1) 55%,transparent),
    0 0 0 5px color-mix(in srgb,var(--c1) 22%,transparent);
  animation:cos-breathe 2.4s ease-in-out infinite;
}
@keyframes cos-breathe{0%,100%{opacity:.35}50%{opacity:1}}

/* ========================================================== обложка ====== */

.cos-cover{
  position:relative;overflow:hidden;height:5.5rem;
  background:var(--surface-2);border-bottom:1px solid var(--line);
}
@media(max-width:560px){.cos-cover{height:4rem}}

/* The profile banner. At 5.5rem a cover reads as a divider above the real
   content; at 12 it is the first thing on the page, which is the only reason
   anyone would save up for one. */
.cos-cover-hero{
  /* the colour the banner fades into is whatever it sits on; the preview card
     is a different surface from the profile card and would otherwise show a
     visible seam where the fade lands */
  --ground:var(--surface);
  height:12rem;border-bottom:0;
}

/* Растворение низа баннера в карточке.
   
   Было внутренней тенью. Внутренняя тень ложится поверх фона, но под детьми, а
   обложку теперь рисует канва — то есть ребёнок. Тень оказалась бы под ней и
   пропала бы совсем. Псевдоэлемент поверх всего решает это и заодно
   освободился: анимации, которые раньше занимали ::after у трёх обложек,
   уехали в движок. */
.cos-cover-hero::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:46px;
  background:linear-gradient(180deg,transparent,var(--ground));
  pointer-events:none;z-index:2;
}
@media(max-width:560px){.cos-cover-hero{height:8rem}}

/* nothing bought yet: a surface that still looks deliberate, so the empty
   state does not read as an image that failed to load */
.cos-cover-hero.cos-cover-none{
  background:
    radial-gradient(120% 90% at 20% 0%,rgba(255,138,31,.10),transparent 60%),
    linear-gradient(160deg,var(--surface-2),var(--bg));
}

/* Подложка под пиксельную канву.
   
   Обложки рисует pixfx.js по клеткам. Заливка нужна на те доли секунды, пока
   скрипт не поднялся, и на случай, когда его нет вовсе: без неё карточка
   мигает серым, а при выключенном JS обложка пропадает совсем — игрок платил
   не за это. Цвета берём те же, что уйдут в палитру канвы. */
.cos-cover-gradient,
.cos-cover-rays,
.cos-cover-aurora,
.cos-cover-scan,
.cos-cover-storm,
.cos-cover-ridge,
.cos-cover-stars{background:linear-gradient(170deg,var(--c1),var(--c2))}

/* =========================================================== эффекты ===== */
/* Слой поверх обложки. Считает его тот же движок, что и всё остальное:
   пылинки, искры, дождь, осадки, метель и орбита — это частицы на канве, а не
   повторяющаяся картинка из радиальных градиентов.

   Прежние варианты были фоном с background-position в анимации. Оно ползало
   плиткой: на широкой обложке шов между повторами читался явно, а «искры» и
   «осадки» отличались только скоростью, потому что рисунок у них был один. */

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

/* ---------------------------------------------------- пиксельная канва --- */

/* Канва во всю коробку: обложка снизу, эффект поверх неё.
   
   image-rendering:pixelated обязателен — без него браузер сглаживает
   растянутые клетки, и вся затея превращается в мыло. */
.pixfx-fill{
  position:absolute;inset:0;
  width:100%;height:100%;
  display:block;
  image-rendering:pixelated;
  pointer-events:none;
}

/* обложка ложится под всё, что лежит в карточке; слой эффекта — над ней */
.cos-cover>.pixfx-fill{z-index:0}
.cos-fx>.pixfx-fill{z-index:1}

/* ====================================================== редкость ========= */

.cos-rar{
  display:inline-block;font-size:.6875rem;letter-spacing:.04em;text-transform:uppercase;
  color:var(--r);
}
.cos-rar-dot{
  display:inline-block;width:.5rem;height:.5rem;border-radius:50%;
  background:var(--r);box-shadow:0 0 6px -1px var(--r);
}

/* ---------- начертания имени ----------

   Само семейство подтягивает скрипт, и только если такое имя на странице
   встретилось. Здесь — как его показывать.

   У каждого своя оптическая величина: пиксельное набирается крупнее обычного
   при том же кегле, рукописное мельче. Поэтому размер правится в самом
   правиле, иначе имя в строке рейтинга то распухнет, то усохнет и собьёт
   выравнивание соседей. Запасное семейство указано всегда: пока файл не
   пришёл, ник должен читаться, а не пропадать. */

/* Селектор из двух классов намеренно: у карточки в лавке своя подпись
   .cos-demo-nick с той же специфичностью, объявленная ниже, и она перебивала
   поправку кегля — пиксельное имя выходило в полный размер и раздувало
   строку. */
.cos-name.cos-font-pixel{
  font-family:"Press Start 2P",ui-monospace,monospace;
  font-size:.72em;letter-spacing:.02em;font-weight:400;
}
.cos-name.cos-font-steel{
  font-family:"Russo One",Impact,"Arial Narrow",sans-serif;
  letter-spacing:.015em;font-weight:400;
}
.cos-name.cos-font-regal{
  font-family:"Yeseva One",Georgia,"Times New Roman",serif;
  font-size:1.06em;font-weight:400;
}
.cos-name.cos-font-narrow{
  font-family:"Oswald","Arial Narrow",sans-serif;
  font-size:1.06em;letter-spacing:.02em;font-weight:600;
}
.cos-name.cos-font-hand{
  font-family:"Caveat","Segoe Script",cursive;
  font-size:1.22em;font-weight:700;
}

/* ---------- верхние ступени имени ----------

   Отличаются от остальных не яркостью, а тем, что у них есть собственное
   вещество: у пламени — тяга вверх, у угля — жар изнутри, у сияния — движение
   поперёк, у неона — трубка со светом вокруг. Свечение даётся через
   drop-shadow, а не text-shadow: заливка букв прозрачная, и тень должна
   повторять форму глифа, а не прямоугольник за ним.

   Во всех четырёх сохраняется читаемость: цвет уходит в буквы или вокруг них,
   но контраст с фоном остаётся. */

/* Пламя: заливка тянется снизу вверх и не кончается. Нижняя треть — тёмный
   жар, середина — основной цвет, верх выбелен: так огонь и выглядит, а не
   ровной оранжевой полосой. */
.cos-name-flame{
  color:var(--c1);
  background-image:linear-gradient(
    0deg,
    color-mix(in srgb,var(--c1) 55%,#40100a) 0%,
    var(--c1) 38%,
    var(--c2,#ffd24a) 72%,
    #fff6e0 100%
  );
  background-size:100% 260%;
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;
  filter:drop-shadow(0 0 4px color-mix(in srgb,var(--c1) 60%,transparent))
         drop-shadow(0 1px 7px color-mix(in srgb,var(--c1) 35%,transparent));
  animation:cos-flame 2.4s linear infinite;
}
@keyframes cos-flame{
  from{background-position:0 130%}
  to{background-position:0 -60%}
}

/* Уголь: снаружи почти погасший, внутри дышит жар. Медленнее пламени —
   у тлеющего своя частота, и если её ускорить, получится то же пламя. */
.cos-name-ember{
  color:color-mix(in srgb,var(--c1) 78%,#2a1206);
  text-shadow:0 0 4px color-mix(in srgb,var(--c1) 45%,transparent);
  animation:cos-ember 3.8s ease-in-out infinite;
}
@keyframes cos-ember{
  0%,100%{
    color:color-mix(in srgb,var(--c1) 62%,#2a1206);
    text-shadow:0 0 3px color-mix(in srgb,var(--c1) 30%,transparent);
  }
  45%{
    color:color-mix(in srgb,var(--c1) 100%,transparent);
    text-shadow:0 0 10px color-mix(in srgb,var(--c1) 75%,transparent),
                0 0 20px color-mix(in srgb,var(--c1) 30%,transparent);
  }
}

/* Сияние: волна идёт поперёк букв и не повторяет саму себя на глаз — три
   остановки вместо двух и большой запас ширины. */
.cos-name-aurora{
  color:var(--c1);
  background-image:linear-gradient(
    92deg,
    var(--c1) 0%,
    var(--c2,#b36bff) 26%,
    color-mix(in srgb,var(--c1) 40%,#eafcff) 50%,
    var(--c2,#b36bff) 74%,
    var(--c1) 100%
  );
  background-size:340% 100%;
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;
  filter:drop-shadow(0 0 5px color-mix(in srgb,var(--c2,#b36bff) 40%,transparent));
  animation:cos-aurora 7s ease-in-out infinite;
}
@keyframes cos-aurora{
  0%,100%{background-position:0 0}
  50%{background-position:100% 0}
}

/* Неон: тонкая светящаяся трубка. Буква почти белая, весь цвет — в свечении
   вокруг неё, поэтому имя читается на любом фоне. Мерцание редкое и
   несимметричное: ровное выглядит как ошибка анимации, а не как лампа. */
.cos-name-neon{
  color:#fff;
  text-shadow:
    0 0 2px #fff,
    0 0 6px var(--c1),
    0 0 14px color-mix(in srgb,var(--c1) 70%,transparent),
    0 0 28px color-mix(in srgb,var(--c1) 35%,transparent);
  animation:cos-neon 6s steps(1,end) infinite;
}
@keyframes cos-neon{
  0%,7%,9%,54%,56%,100%{opacity:1}
  8%,55%{opacity:.72}
}

/* ---------- пиксельные эффекты за именем ----------

   Огонь, ореол и искры считает pixfx.js и кладёт на канву клетками по три
   пикселя. Здесь только посадка.

   Раньше это были размытые пятна на псевдоэлементах. Размытие и пиксель —
   противоположные вещи: под буквами получалась грязь, а не эффект.

   isolation:isolate обязателен: канва уходит на z-index:-1, и без своего
   контекста наложения она провалилась бы под фон родителя, а не под буквы.
   pointer-events:none — иначе эффект перехватит наведение, и карточка игрока
   перестанет открываться по имени. */

.cos-name-pixfire,
.cos-name-blaze,
.cos-name-aura,
.cos-name-sparks{position:relative;isolation:isolate}

.cos-name-pixfire{color:var(--c2,#ffd68c);text-shadow:0 0 3px color-mix(in srgb,var(--c1) 55%,transparent)}
.cos-name-blaze{color:var(--c2,#ffc24a);text-shadow:0 0 3px color-mix(in srgb,var(--c1) 60%,transparent)}
.cos-name-aura{color:var(--c1)}
.cos-name-sparks{color:var(--c1)}

.pixfx-canvas{
  position:absolute;left:50%;bottom:-.42em;
  transform:translateX(-50%);
  z-index:-1;
  pointer-events:none;
  image-rendering:pixelated;
  /* screen складывает свет с фоном: тёмный низ эффекта не оставляет чёрного
     прямоугольника под строкой */
  mix-blend-mode:screen;
  opacity:.92;
}


/* ================================================== без движения ========= */

@media(prefers-reduced-motion:reduce){
  .cos-name-shimmer,.cos-name-halo,.cos-name-underline::after,
  .cos-name-flame,.cos-name-ember,.cos-name-aurora,.cos-name-neon,
  .cos-badge-glow,.cos-badge-beat,.cos-badge-spin,
  .cos-av-pulse::after,.cos-av-orbit::before,.cos-av-spark::before,.cos-av-spark::after,
  .cos-fx{
    animation:none !important;
  }
  /* Обложки и эффекты останавливает сам движок: он спрашивает
     prefers-reduced-motion при запуске и, если движение не нужно, рисует один
     прогретый кадр и не заводит кадровый цикл. Гасить их правилом здесь
     нечем — там канва, а не анимация CSS. */
  /* the turning ring has to keep a visible arc when it stops turning */
  .cos-av-orbit::before,.cos-av-spark::before{background:conic-gradient(var(--c1),var(--c2),var(--c1))}
  /* остановленное пламя иначе замерло бы на самой тёмной своей части */
  .cos-name-flame{background-position:0 42%}
}

/* ============================================================ лавка ====== */

.mkt-head{display:flex;align-items:flex-start;gap:1rem;flex-wrap:wrap;margin-bottom:.9rem}
.mkt-title{font-size:1.375rem;margin:0;letter-spacing:-.01em}
.mkt-sub{margin:.25rem 0 0;color:var(--muted);font-size:.8125rem;max-width:56ch}
.mkt-purse{
  margin-left:auto;flex:0 0 auto;text-decoration:none;
  padding:.4rem .7rem;border:1px solid var(--line);border-radius:5px;background:var(--surface);
}
.mkt-purse:hover{border-color:var(--muted)}

.mkt-tabs{display:flex;gap:.35rem;flex-wrap:wrap;border-bottom:1px solid var(--line);margin-bottom:.9rem}
.mkt-tab{
  padding:.5rem .85rem;font-size:.8125rem;text-decoration:none;color:var(--muted);
  border-bottom:2px solid transparent;margin-bottom:-1px;
}
.mkt-tab:hover{color:var(--text)}
.mkt-tab.on{color:var(--text);border-bottom-color:var(--amber)}
.mkt-dot{
  display:inline-block;min-width:1.15rem;padding:0 .3rem;margin-left:.35rem;
  border-radius:999px;background:var(--ember);color:#fff;
  font-size:.6875rem;line-height:1.15rem;text-align:center;
}

.mkt-kinds{display:flex;gap:.35rem;flex-wrap:wrap;align-items:center;margin-bottom:.9rem}
.mkt-kind{
  display:inline-flex;align-items:center;gap:.4rem;
  padding:.4rem .75rem;border:1px solid var(--line);border-radius:999px;
  font-size:.8125rem;text-decoration:none;color:var(--muted);background:var(--surface);
  transition:border-color .14s,color .14s;
}
.mkt-kind:hover{color:var(--text);border-color:var(--muted)}
.mkt-kind.on{color:var(--text);border-color:var(--amber);background:var(--amber-dim)}
.mkt-kind-n{font-family:var(--mono);font-size:.6875rem;color:var(--faint)}
.mkt-sortwrap{margin-left:auto;display:flex;gap:.6rem}
.mkt-sort{font-size:.75rem;color:var(--faint);text-decoration:none}
.mkt-sort:hover{color:var(--text)}
.mkt-sort.on{color:var(--amber)}

.mkt-grid{display:grid;gap:.7rem;grid-template-columns:repeat(auto-fill,minmax(10.5rem,1fr))}

/* The rarity colour is the card's own edge, so a shelf reads at a glance —
   this is the whole point of having rarity at all. */
.mkt-card{
  position:relative;display:grid;gap:.5rem;padding:.7rem;align-content:start;
  border:1px solid var(--line);border-top:2px solid var(--r);border-radius:6px;
  background:linear-gradient(180deg,color-mix(in srgb,var(--r) 9%,var(--surface-2)),var(--surface-2));
  transition:transform .14s,box-shadow .14s;
}
.mkt-card:hover{transform:translateY(-2px);box-shadow:0 6px 18px -12px var(--r)}
.mkt-card.worn{border-color:color-mix(in srgb,var(--r) 55%,var(--line))}
.mkt-card.worn::after{
  content:"";position:absolute;inset:0;border-radius:6px;pointer-events:none;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--r) 40%,transparent);
}

.mkt-stage{
  height:5rem;display:grid;place-items:center;border-radius:5px;overflow:hidden;
  background:var(--bg);
}
/* Эффект вокруг имени выходит за буквы, а закрытая коробка срезает его — и
   покупатель судит о вещи по обрезку. Обложкам и эффектам обрезка нужна, они
   баннеры во всю площадку; имени — нет. */
.mkt-card:has(.cos-demo-nick) .mkt-stage{overflow:visible}

/* covers and effects are banners; judged in a 5rem box they all look alike */
.mkt-card:has(.cos-demo-cover) .mkt-stage,
.mkt-card:has(.cos-demo-effect) .mkt-stage{height:7rem}
/* Кегль предпросмотра стоит на обёртке, а не на самом имени.
   На имени он перебивал оптическую поправку начертания, а поставленный поверх
   неё считался бы уже от родителя — и пиксельное имя выходило мельче
   обычного вместо ровно нужного. */
.cos-demo{display:grid;place-items:center;width:100%;height:100%;font-size:1rem}
.cos-demo-cover{width:100%;height:100%;border:0}
.cos-demo-mark{margin:0}

.mkt-meta{display:grid;gap:.1rem;min-width:0}
.mkt-name{font-size:.8125rem;line-height:1.25}
.cos-rar{display:inline-flex;align-items:center;gap:.3rem}

.mkt-foot{display:grid;gap:.35rem}
.mkt-price{font-family:var(--mono);font-size:.75rem}
.mkt-btn{width:100%;text-align:center;justify-content:center;font-size:.75rem;padding:.35rem .6rem}
.mkt-btn:disabled{opacity:.45;cursor:not-allowed}
.mkt-btn.ghost{background:var(--surface);color:var(--text);box-shadow:inset 0 0 0 1px var(--line)}
.mkt-state{font-size:.75rem;text-align:center}
.mkt-state.on{color:var(--live)}
.mkt-bound,.mkt-src{font-size:.6875rem;color:var(--faint);text-align:center;line-height:1.3}

.mkt-note{color:var(--muted);font-size:.8125rem;margin-top:1rem}
.mkt-empty{color:var(--muted);font-size:.8125rem;margin:.4rem 0 0}

/* ------------------------------------------------------- инвентарь ------ */

.mkt-me{overflow:hidden;margin-bottom:1rem}
.mkt-me-row{display:flex;align-items:center;gap:1rem;flex-wrap:wrap}
.mkt-me-id{flex:1 1 12rem;min-width:0}
.mkt-me-name{margin:0;font-size:1.125rem}
.mkt-me-link{flex:0 0 auto;font-size:.75rem;text-decoration:none;color:var(--muted)}
.mkt-me-link:hover{color:var(--amber)}

.mkt-slot{margin-bottom:.9rem}
.mkt-slot-h{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;margin-bottom:.55rem}
.mkt-strip{background:none;border:0;padding:0;cursor:pointer;color:var(--faint);font-size:.8125rem;text-decoration:none}
.mkt-strip:hover{color:var(--ember)}
.mkt-past summary{cursor:pointer}

/* ---------------------------------------------------------- обмены ------ */

.tr-card{border:1px solid var(--line);border-radius:6px;padding:.7rem;margin-bottom:.6rem;background:var(--surface-2)}
.tr-head{display:flex;align-items:baseline;gap:.6rem;flex-wrap:wrap;margin-bottom:.55rem}
.tr-who{font-weight:600;font-size:.875rem;text-decoration:none;color:var(--text)}
.tr-who:hover{color:var(--amber)}
.tr-state{font-size:.6875rem;padding:.1rem .45rem;border-radius:999px;background:var(--surface);color:var(--muted)}
.tr-accepted{color:var(--live)}
.tr-declined,.tr-cancelled{color:var(--ember)}
.tr-head time{margin-left:auto}

.tr-sides{display:flex;align-items:stretch;gap:.7rem;flex-wrap:wrap}
.tr-side{flex:1 1 12rem;min-width:0}
.tr-swap{align-self:center;color:var(--faint);font-size:1.1rem}

.tr-items{list-style:none;margin:.3rem 0 0;padding:0;display:grid;gap:.2rem}
.tr-item{display:flex;align-items:center;gap:.45rem;font-size:.8125rem;min-width:0}
.tr-item-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tr-item-dot{flex:0 0 auto;width:.45rem;height:.45rem;border-radius:50%;background:var(--r)}
.tr-item.empty{color:var(--faint)}

.tr-note{margin:.55rem 0 0;font-size:.8125rem;color:var(--muted)}
.tr-acts{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;margin-top:.6rem}
.tr-acts form{margin:0}
.tr-acts .mkt-btn{width:auto}
.tr-expiry{margin-left:auto}

.tr-form{display:grid;gap:.8rem}
.tr-cols{display:flex;gap:1rem;flex-wrap:wrap}
.tr-col{flex:1 1 15rem;min-width:0}
.tr-col-h{margin:0 0 .35rem;font-size:.8125rem;color:var(--muted);font-weight:600}
.tr-pick-h{margin:.55rem 0 .2rem;font-size:.6875rem;text-transform:uppercase;letter-spacing:.05em;color:var(--faint)}
.tr-pick{
  display:flex;align-items:center;gap:.45rem;padding:.3rem .4rem;border-radius:4px;
  font-size:.8125rem;cursor:pointer;
}
.tr-pick:hover{background:var(--surface)}
.tr-pick.off{opacity:.5;cursor:not-allowed}
.tr-pick-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tr-pick .lbl{flex:0 0 auto}

/* the single way in for a guest, where the purse sits for everyone else */
.mkt-signin{margin-left:auto;flex:0 0 auto;white-space:nowrap}

/* ------------------------------------------------------- «примерить» ---- */

/* the tile is a button now; it must not look like one until hovered */
button.mkt-stage{
  position:relative;width:100%;padding:0;border:0;cursor:pointer;
  font:inherit;color:inherit;
}
.mkt-zoom{
  position:absolute;left:50%;bottom:.35rem;transform:translateX(-50%) translateY(.3rem);
  padding:.1rem .45rem;border-radius:999px;
  background:rgba(12,14,19,.82);color:var(--text);
  font-size:.625rem;letter-spacing:.03em;
  opacity:0;transition:opacity .14s,transform .14s;pointer-events:none;
}
.mkt-stage:hover .mkt-zoom,
.mkt-stage:focus-visible .mkt-zoom{opacity:1;transform:translateX(-50%) translateY(0)}

.pv-modal{
  border:0;padding:0;background:transparent;max-width:min(30rem,92vw);
  color:var(--text);
}
.pv-modal::backdrop{background:rgba(6,7,10,.72)}
.pv-inner{
  position:relative;display:grid;gap:.8rem;padding:1rem;
  border:1px solid var(--line);border-radius:8px;background:var(--surface);
}
.pv-x{
  position:absolute;top:.35rem;right:.5rem;z-index:2;
  background:none;border:0;cursor:pointer;color:var(--faint);
  font-size:1.4rem;line-height:1;padding:.2rem .35rem;
}
.pv-x:hover{color:var(--text)}

.pv-card{border:1px solid var(--line);border-radius:6px;overflow:hidden;background:var(--surface-2)}
.pv-cover{height:6rem;border-bottom:1px solid var(--line)}
.pv-body{display:flex;align-items:center;gap:.8rem;padding:.7rem}
.pv-id{display:grid;gap:.15rem;min-width:0}
.pv-name{font-size:1.0625rem;font-weight:600}

.pv-info{display:grid;gap:.2rem}
.pv-title{font-size:.9375rem}
.pv-hint{margin:.15rem 0 0}
.pv-acts .mkt-foot,
.pv-acts .item-acts{display:grid;gap:.4rem}
.pv-acts .mkt-btn{width:100%}
.pv-acts .pop-auto{text-align:center}

/* A reward has no profile to try it on, so the window draws the thing itself
   at a size worth looking at — the same square the tile uses, grown up. */
.pv-thing{
  aspect-ratio:1;max-height:11rem;display:grid;place-items:center;
  border:1px solid color-mix(in srgb,var(--rar) 45%,var(--line));border-radius:8px;
  background:
    radial-gradient(120% 90% at 50% 100%,color-mix(in srgb,var(--rar) 22%,transparent),transparent 70%),
    var(--surface-2);
}
.pv-thing img{max-width:64%;max-height:64%;object-fit:contain;display:block}
.pv-thing-none{font-size:3.5rem;color:var(--rar);opacity:.75}

/* the same details the tile shows on hover, kept legible at window size */
.pv-meta .pop-meta{gap:.28rem;padding-top:0;border-top:0}
.pv-meta dt,
.pv-meta dd{font-size:.75rem}

@media(max-width:560px){
  .pv-modal{max-width:94vw}
  .pv-cover{height:4.5rem}
}

/* ------------------------------------------------- аватар на баннере ---- */

/* The cut-out that lets the avatar sit half on the banner. The ring is padding
   filled with the card colour rather than a box-shadow, because the moving
   frames use box-shadow themselves and would have to fight it. */
.player-avslot{
  display:inline-block;line-height:0;position:relative;z-index:2;
  padding:5px;border-radius:50%;background:var(--surface);
  /* align-self, not the container's alignment: with align-items:flex-end the
     line box is laid out from the bottom and the negative margin is mostly
     absorbed — the avatar ended up 10px over the banner instead of half on it */
  align-self:flex-start;margin-top:-3.75rem;
}
@media(max-width:560px){
  .player-avslot{margin-top:-2.75rem;padding:4px}
  .player-avslot .cos-av{--px:76px !important}
}

/* the head has to start below the banner, not beside it */
.player-card .player-head{align-items:flex-end;padding-top:0}
.player-card .player-id{padding-bottom:.15rem}

.pv-card{--ground:var(--surface-2)}
.pv-cover{height:9rem}
.pv-avslot{align-self:flex-start;margin-top:-2.6rem;background:var(--surface-2)}
.pv-body{align-items:flex-end;padding-top:0}

/* --------------------------------------------- карточка при наведении --- */

.pcard-pop{
  position:absolute;z-index:60;width:19rem;max-width:calc(100vw - 1rem);
  animation:pcard-in .12s ease-out;
}
@keyframes pcard-in{from{opacity:0;transform:translateY(-3px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){.pcard-pop{animation:none}}

.pcard{
  overflow:hidden;border:1px solid var(--line);border-radius:10px;
  background:var(--surface);box-shadow:0 18px 44px -20px #000;
}
.pcard .pcard-cover{--ground:var(--surface);height:4.5rem;border-bottom:0}
.pcard-head{display:flex;align-items:flex-end;gap:.6rem;padding:0 .75rem}
.pcard-avslot{
  align-self:flex-start;margin-top:-1.9rem;
  display:inline-block;line-height:0;padding:4px;border-radius:50%;
  background:var(--surface);position:relative;z-index:2;
}
.pcard-id{padding-bottom:.4rem;min-width:0}
.pcard-name{display:block;font-size:.9375rem;line-height:1.2}
.pcard-body{padding:.5rem .75rem .75rem;display:grid;gap:.4rem}
.pcard-bio{margin:0;font-size:.75rem;color:var(--muted);line-height:1.45}
.pcard-stats{display:flex;flex-wrap:wrap;gap:.7rem;font-size:.75rem;color:var(--muted)}
.pcard-stats b{color:var(--text);font-family:var(--mono)}
.pcard-seen{display:flex;align-items:center;gap:.35rem;margin:0}
.pcard-dot{width:.45rem;height:.45rem;border-radius:50%;background:var(--faint)}
.pcard-dot.live{background:var(--live);box-shadow:0 0 6px -1px var(--live)}
.pcard-acts{display:flex;gap:.4rem;margin-top:.15rem}
.pcard-btn{
  flex:1 1 0;text-align:center;justify-content:center;
  font-size:.75rem;padding:.35rem .6rem;text-decoration:none;
}
.pcard-btn.ghost{
  border-radius:4px;color:var(--text);
  box-shadow:inset 0 0 0 1px var(--line);background:var(--surface-2);
}
.pcard-btn.ghost:hover{box-shadow:inset 0 0 0 1px var(--muted)}

/* --------------------------------------------------- кто на сервере ----- */

.whoson-grid{display:flex;flex-wrap:wrap;gap:.7rem}
.whoson-one{
  display:grid;justify-items:center;gap:.3rem;width:4.5rem;
  text-decoration:none;color:var(--text);
}
.whoson-nick{
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:.75rem;text-align:center;
}
.whoson-list{display:grid;gap:.15rem}
.whoson-row{
  display:flex;align-items:center;gap:.55rem;padding:.3rem 0;
  text-decoration:none;color:var(--text);border-bottom:1px solid var(--line-soft);
}
.whoson-row:last-child{border-bottom:0}
.whoson-rownick{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.8125rem}
.whoson-when{flex:0 0 auto}

/* ------------------------------------------------------ расходуемое ----- */
.boost-grid{grid-template-columns:repeat(auto-fill,minmax(15rem,1fr))}
.boost-card{gap:.6rem}
.boost-text{line-height:1.45}
.boost-form{display:grid;gap:.45rem}
.boost-form select{font-size:.8125rem}

/* -------------------------------------------------- витрина профилей ---- */
.feat-grid{display:grid;gap:.6rem;grid-template-columns:repeat(auto-fill,minmax(11rem,1fr))}
.feat-one{
  display:block;overflow:hidden;text-decoration:none;color:var(--text);
  border:1px solid var(--line);border-radius:8px;background:var(--surface-2);
  transition:border-color .14s,transform .14s;
}
.feat-one:hover{border-color:var(--muted);transform:translateY(-2px)}
.feat-cover{--ground:var(--surface-2);height:3.5rem;border-bottom:0}
.feat-body{display:flex;align-items:center;gap:.5rem;padding:0 .6rem .6rem}
.feat-body .cos-av{margin-top:-1.1rem;padding:3px;border-radius:50%;background:var(--surface-2);position:relative;z-index:2}
.feat-nick{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.8125rem}

/* база, подсвеченная владельцем */
.basecard.lit{
  position:relative;
  border-color:color-mix(in srgb,#ffc24a 55%,var(--line));
  box-shadow:0 0 0 1px color-mix(in srgb,#ffc24a 25%,transparent),0 8px 22px -16px #ffc24a;
}
.basecard-lit{
  position:absolute;top:.4rem;left:.4rem;z-index:3;
  padding:.1rem .45rem;border-radius:999px;
  background:rgba(255,194,74,.9);color:#412402;
  font-size:.625rem;font-weight:600;letter-spacing:.02em;
}

/* автор базы и лицо в комментарии новости */
.base-author{display:flex;align-items:center;gap:.8rem;flex-wrap:wrap;margin:.6rem 0 .8rem}
.base-author-who{display:flex;align-items:center;gap:.55rem;text-decoration:none;color:var(--text)}
.base-author-tx{display:grid;gap:.05rem;line-height:1.25}
.base-tags{display:flex;gap:.3rem;flex-wrap:wrap;margin-left:auto}
.nm-av{flex:0 0 auto;margin-right:.45rem;vertical-align:middle}

/* ========================================================= инвентарь ===== */
/* A bag, not a second shop window. Nothing here has a price, and the cells are
   uniform so the eye compares items instead of reading five headings. */

.inv{margin-bottom:.9rem}

/* --- надетое: пять слотов, всегда все пять --- */
.inv-slots{display:grid;gap:.6rem;grid-template-columns:repeat(auto-fit,minmax(8.5rem,1fr))}
.inv-slot{
  display:grid;gap:.35rem;justify-items:center;padding:.6rem .5rem;
  border:1px solid var(--line);border-radius:8px;background:var(--surface-2);
  text-align:center;min-height:9.5rem;align-content:start;
}
.inv-slot.on{
  border-color:color-mix(in srgb,var(--r) 55%,var(--line));
  background:linear-gradient(180deg,color-mix(in srgb,var(--r) 10%,var(--surface-2)),var(--surface-2));
}
.inv-slot-name{
  font-family:var(--mono);font-size:.5625rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--faint);
}
.inv-slot-pic{
  display:grid;place-items:center;width:100%;height:3.6rem;
  border-radius:6px;background:var(--bg);overflow:hidden;
}
.inv-slot-item{font-size:.75rem;line-height:1.25}
.inv-off{
  background:none;border:0;padding:0;cursor:pointer;
  font-family:inherit;font-size:.6875rem;color:var(--faint);
}
.inv-off:hover{color:var(--ember)}

/* an empty slot drawn as a slot: the shape says what is missing */
.inv-slot-empty{
  display:grid;gap:.25rem;justify-items:center;align-content:center;
  width:100%;height:3.6rem;border-radius:6px;text-decoration:none;
  border:1px dashed var(--line);color:var(--faint);
  transition:border-color .14s,color .14s;
}
.inv-slot-empty:hover{border-color:var(--amber);color:var(--amber)}
.inv-plus{font-size:1.1rem;line-height:1}

/* --- сумка --- */
.inv-grid{display:grid;gap:.5rem;grid-template-columns:repeat(auto-fill,minmax(7.5rem,1fr))}
.inv-cell{
  display:grid;gap:.3rem;padding:.45rem;align-content:start;
  border:1px solid var(--line);border-top:2px solid var(--r);border-radius:6px;
  background:var(--surface-2);transition:transform .14s,box-shadow .14s;
}
.inv-cell:hover{transform:translateY(-2px);box-shadow:0 6px 16px -12px var(--r)}
.inv-cell.on{box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--r) 45%,transparent)}

.inv-pic{
  position:relative;height:4rem;width:100%;padding:0;cursor:pointer;
  display:grid;place-items:center;overflow:hidden;
  border:0;border-radius:4px;background:var(--bg);
}
.inv-on,.inv-mark{
  position:absolute;top:.2rem;font-size:.625rem;line-height:1;
  padding:.1rem .25rem;border-radius:3px;background:rgba(12,14,19,.8);
}
.inv-on{right:.2rem;color:var(--live)}
.inv-mark{left:.2rem;color:var(--muted)}
.inv-mark.hold{left:auto;right:1.6rem}

.inv-name{font-size:.75rem;line-height:1.2;min-width:0}
.inv-rar{font-size:.625rem;letter-spacing:.04em;text-transform:uppercase;color:var(--r)}
.inv-cell .mkt-foot{margin-top:.1rem}
.inv-cell .mkt-btn{font-size:.6875rem;padding:.28rem .5rem}
