/* Walls on Loop store, «Collection» (T-048; webapp/DESIGN.md v6; the sample: brand/SHOWCASE_DEMO_v5). An album of collectible cards at
   night: a dark blue scene; the wallpaper and its rarity glow carry the colour; gold only for the main action and the hall of fame.
   Values: the tokens of css/tokens.css only - no colour literal here. */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* the search and the drum hold the page still under them */
html.is-locked,
html.is-drum {
  overflow: hidden;
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font: var(--t-body);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior-y: none;
}

#app {
  min-height: var(--tg-viewport-stable-height, 100vh);
  overflow-x: clip; /* glows reach past the screen's edges: clipped, never a wider page (acceptance T-048 М2); clip keeps sticky alive */
  padding: 0 max(var(--gutter), var(--safe-right)) calc(var(--space-6) + var(--safe-bottom)) max(var(--gutter), var(--safe-left));
}

#app[data-screen="home"] {
  background: var(--home-glow);
  background-repeat: no-repeat;
}

h1,
h2,
p {
  margin: 0;
}

button {
  font: inherit;
  color: inherit;
  cursor: pointer;
}

input {
  font: inherit;
  color: inherit;
  margin: 0;
}

svg {
  display: block;
}

/* keyboard focus: a solid 2 px ring of accent-ink with a 2 px gap (one rule for every control) */
:focus-visible {
  outline: 2px solid var(--accent-ink);
  outline-offset: 2px;
}

/* ---- buttons, links, notes ------------------------------------------------------------------------------------------ */

/* the one in-page main action of a screen: the accent fill; the purchase itself is Telegram's MainButton */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 var(--space-6);
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--on-accent);
  font: var(--t-label);
  text-decoration: none;
}

/* a second action as a quiet button: the words in accent-ink. The press plate and the hit area reach --space-1 further (::before). */
.linkbtn {
  position: relative;
  isolation: isolate;
  min-height: 44px;
  padding: var(--space-2) var(--space-1);
  border: 0;
  border-radius: var(--radius-ui);
  background: none;
  color: var(--accent-ink);
  font: var(--t-label);
}

.linkbtn::before {
  content: "";
  position: absolute;
  inset: 0 calc(-1 * var(--space-1));
  z-index: -1;
  border-radius: var(--radius-ui);
  transition: background-color var(--duration-press-out) var(--ease-standard);
}

/* a link in the text column: its words stand on the column's line, the plate reaches out past them */
.linkbtn--line {
  padding-inline: 0;
  text-align: start;
}

.linkbtn--line::before {
  inset: 0 calc(-1 * var(--space-2));
}

/* a note: an inner block on surface; warn and ok tint the ground (with the words that say it: never colour alone) - ink and an accent-ink
   action keep 4.5:1 on them (tools/check_webapp.py) */
.note {
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-ui);
  background: var(--surface);
  text-align: left;
}

.note--warn {
  background: color-mix(in srgb, var(--warn) 12%, var(--ground));
}

.note--ok {
  background: color-mix(in srgb, var(--ok) 10%, var(--ground));
}

.note__text {
  font: var(--t-body);
}

.note .linkbtn {
  margin: var(--space-1) 0 calc(-1 * var(--space-2));
  min-height: 36px;
  padding: var(--space-1) 0;
}

.notes {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.notes:empty {
  display: none;
}

.notes > .note {
  margin: 0;
}

.lead {
  margin-top: var(--space-3);
  font: var(--t-lead);
}

.hint {
  margin-top: var(--space-2);
  color: var(--ink-muted);
  font: var(--t-meta);
}

.footnote {
  margin: 0;
  color: var(--ink-muted);
  font: var(--t-meta);
}

/* the foot of a card: the link to the chat and the EU legal block */
.fine {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
}

.fine:empty,
.paying-slot:empty,
.wall__meta:empty {
  display: none;
}

/* headings sit in their group (a flex column, gap 12); the space above a group is its parent's step */
.section-title {
  margin: 0;
  font: var(--t-shelf);
}

.inpacks,
.similar,
.inside {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* a label in the flow of the page ("New", "3 wallpapers", "#2 in Top"): meta text, no plate */
.label {
  color: var(--ink-muted);
  font: var(--t-meta);
}

/* ---- the language button and its sheet (T-033) --------------------------------------------------------------------- */

/* the code of the language in a 44 px circle on surface */
.langbtn {
  flex: none;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--ink);
  font: 600 12px/1 var(--font-text);
  letter-spacing: 0.04em;
}

.sheet {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: var(--backdrop);
}

.sheet__panel {
  width: 100%;
  max-width: 480px;
  padding: var(--space-8) var(--gutter) calc(var(--space-3) + var(--safe-bottom));
  border-radius: var(--radius-panel) var(--radius-panel) 0 0;
  background: var(--surface);
  box-shadow: var(--shadow-lift);
}

.sheet__title {
  margin: 0 0 var(--space-4);
  font: var(--t-name);
  letter-spacing: var(--t-tight);
}

.sheet__list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
}

.sheet__opt {
  min-height: 48px;
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  color: var(--ink);
  font: var(--t-label);
}

.sheet__opt[aria-pressed="true"] {
  background: var(--ink);
  color: var(--ground);
}

.sheet__opt[aria-busy="true"] {
  opacity: 0.6;
}

.sheet__cancel {
  display: block;
  width: 100%;
  margin-top: var(--space-2);
}

/* ---- the rarity glow (DESIGN.md v6 «Свечение редкости»): three drawn halos stretched round a poster; only opacity and transform move ------ */

.glow {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  opacity: var(--go, 0);
}

.glow::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--gimg) center / 100% 100% no-repeat;
}

.t-none,
.t-common {
  --gimg: none;
  --gx: 0;
  --gy: 0;
  --rimc: var(--rim-common);
  --rimglow: transparent;
}

.t-rare {
  --gimg: url("../img/glow-rare.png");
  --gx: 0.34;
  --gy: 0.115;
  --rimc: var(--rim-rare);
  --rimglow: var(--rim-glow-rare);
}

.t-epic {
  --gimg: url("../img/glow-epic.png");
  --gx: 0.46;
  --gy: 0.145;
  --rimc: var(--rim-epic);
  --rimglow: var(--rim-glow-epic);
}

.t-legendary {
  --gimg: url("../img/glow-legendary.png");
  --gx: 0.6;
  --gy: 0.175;
  --rimc: var(--rim-legendary);
  --rimglow: var(--rim-glow-legendary);
}

.t-none .glow,
.t-common .glow {
  display: none;
}

.t-epic .glow::before {
  animation: breathe 3.2s ease-in-out infinite alternate;
}

.t-legendary .glow::before {
  animation: breathe 2.2s ease-in-out infinite alternate;
}

@keyframes breathe {
  from { opacity: 1; }
  to { opacity: 0.66; }
}

/* the rim: 1.5 px of the level's rim colour and its inner light; no rim without a level */
.rim {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  box-shadow: inset 0 0 0 var(--rimw, 1.5px) var(--rimc), inset 0 0 var(--rimg, 14px) var(--rimglow);
}

.t-none .rim {
  display: none;
}

/* legendary: a glint runs round the rim (3.4 s) and a light sweeps the picture every 5.2 s */
.shine,
.sheen {
  display: none;
}

.t-legendary .shine {
  display: block;
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: var(--shw, 2px);
  overflow: hidden;
  pointer-events: none;
  -webkit-mask: linear-gradient(var(--screen-off) 0 0) content-box, linear-gradient(var(--screen-off) 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(var(--screen-off) 0 0) content-box exclude, linear-gradient(var(--screen-off) 0 0);
}

.t-legendary .shine::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 260%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: var(--shine);
  animation: spin 3.4s linear infinite;
}

@keyframes spin {
  to { transform: translate(-50%, -50%) rotate(1turn); }
}

.t-legendary .sheen {
  display: block;
  position: absolute;
  inset: -10% -60%;
  pointer-events: none;
  background: var(--sheen);
  transform: translateX(-60%);
  animation: sheen 5.2s ease-in-out infinite;
}

@keyframes sheen {
  0% { transform: translateX(-60%); }
  28%,
  100% { transform: translateX(60%); }
}

/* ---- the tile of the collection (ui.js collectionTile; DESIGN.md v6 «Плитка») ----------------------------------------------------- */

.ctile {
  --tw: 106px;
  --w: var(--tw);
  --h: calc(var(--w) * 650 / 300);
  position: relative;
  flex: 0 0 auto;
  width: var(--w);
  height: var(--h);
  scroll-snap-align: start;
}

.ctile__glow,
.ctile__card {
  position: absolute;
  transform-origin: 50% 100%;
  will-change: transform;
}

.ctile__glow {
  inset: calc(var(--h) * var(--gy) * -1) calc(var(--w) * var(--gx) * -1);
}

.ctile__card {
  inset: 0;
  z-index: 1;
  display: block;
  padding: 0;
  border: 0;
  border-radius: var(--radius-tile);
  background: none;
  text-align: left;
}

.ctile__face {
  position: absolute;
  inset: 0;
  display: block;
  overflow: hidden;
  border-radius: inherit;
  background: var(--surface);
}

.ctile__face img,
.ctile__video {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ctile__face img.is-broken {
  opacity: 0;
}

/* the frame: 3 px of `frame` inside the tile, over the picture; the rim, its light and the plate inside it */
.ctile__face::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: inherit;
  box-shadow: inset 0 0 0 3px var(--frame);
  pointer-events: none;
}

.ctile__face .rim {
  inset: 3px;
  z-index: 2;
  border-radius: var(--radius-inner);
}

.ctile__face .shine {
  inset: 3px;
  z-index: 2;
  border-radius: var(--radius-inner);
}

.ctile__video {
  opacity: 0;
  transition: opacity 220ms var(--ease-standard);
}

.ctile__video.is-on {
  opacity: 1;
}

/* the score at the top left: display numbers with a shadow */
.ctile__num {
  position: absolute;
  left: 8px;
  top: 8px;
  z-index: 4;
  color: var(--on-scrim);
  font: var(--t-num);
  font-variant-numeric: tabular-nums;
  text-shadow: var(--shadow-num);
}

/* "Yours", "Free", "New": a scrim pill at the top right */
.ctile__badge {
  position: absolute;
  right: 6px;
  top: 6px;
  z-index: 4;
  max-width: calc(100% - 34px);
  overflow: hidden;
  padding: 3px 7px;
  border-radius: var(--radius-pill);
  background: var(--scrim);
  color: var(--on-scrim);
  font: var(--t-plate);
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* the plate: the diamond of the level and the name, over the gradient at the bottom (inside the frame) */
.ctile__plate {
  position: absolute;
  left: 3px;
  right: 3px;
  bottom: 3px;
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 22px 7px 7px;
  border-radius: 0 0 var(--radius-inner) var(--radius-inner);
  background: var(--plate);
  color: var(--on-scrim);
  font: var(--t-plate);
}

.ctile__plate i,
.cap__tier i,
.tchip i {
  flex: none;
  background: var(--tc);
  box-shadow: 0 0 6px var(--tc);
}

.ctile__plate i {
  width: 7px;
  height: 7px;
  border-radius: 1.5px;
  transform: rotate(45deg);
}

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

/* the foil glint of a tile raised by the dock: a slanted light crosses it left to right (650 ms) */
.foil {
  position: absolute;
  inset: -20% -80%;
  z-index: 5;
  pointer-events: none;
  opacity: 0;
  background: var(--foil);
  transform: translateX(-55%);
}

.ctile.is-focus .foil {
  animation: foil 650ms var(--ease-standard);
}

@keyframes foil {
  0% { opacity: 1; transform: translateX(-55%); }
  100% { opacity: 1; transform: translateX(55%); }
}

.ctile.is-bump .ctile__face {
  animation: bump 200ms var(--ease-standard);
}

@keyframes bump {
  40% { scale: 1.05; }
}

/* the tiles of an open drum: the drum carries them */
.ctile.is-lifted .ctile__card,
.ctile.is-lifted .ctile__glow {
  visibility: hidden;
}

/* no "save image" menu, no selection: a long press plays the wallpaper (DESIGN.md v6 «iPhone») */
.ctile__card,
.home,
.plaque,
.rchip,
.drum,
.hero,
.minitile {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

.ctile__face img,
.ctile__video,
.plaque__fan img,
.rchip img,
.dc__face img,
.dc__video,
.poster img,
.poster__video {
  pointer-events: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
}

/* ---- the home (DESIGN.md v6 «Главная») ---------------------------------------------------------------------------------- */

/* the home runs edge to edge: its rows scroll under the screen's edges; its parts keep the gutter themselves */
.home {
  margin: 0 calc(-1 * max(var(--gutter), var(--safe-right))) 0 calc(-1 * max(var(--gutter), var(--safe-left)));
  padding-bottom: var(--space-8);
}

.home__body {
  display: flex;
  flex-direction: column;
}

.home__notes {
  margin: var(--space-3) var(--gutter) 0;
}

/* a state of the home (empty, an error) and its stand-ins keep the gutter */
.home__body > .state,
.home__body > .skeleton {
  margin: 0 var(--gutter);
}

.hd {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: calc(18px + var(--safe-top)) var(--gutter) 4px;
}

.hd .wol-mark {
  flex: none;
  width: 31px;
  height: 21px;
}

/* the name pushes the count and the language to the right edge (the count hides under 380 px) */
.hd__name {
  margin-right: auto;
  font: var(--t-app);
  letter-spacing: var(--t-app-tracking);
  white-space: nowrap;
}

.hd__count {
  color: var(--ink-muted);
  font: var(--t-count);
  white-space: nowrap;
}

@media (max-width: 379px) {
  .hd__count {
    display: none;
  }
}

/* the search field: 48 high, surface, a hairline ring; "Cancel" next to it while the search is open */
.search {
  position: relative;
  z-index: 6;
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 12px var(--gutter) 0;
}

.search__box {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 0 6px 0 15px;
  border-radius: var(--radius-ui);
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line);
  cursor: text;
}

.search__ico {
  flex: none;
  width: 20px;
  height: 20px;
  color: var(--ink-muted);
}

.search__input {
  flex: 1;
  min-width: 0;
  height: 46px;
  padding: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--ink);
  font: var(--t-input);
  -webkit-appearance: none;
  appearance: none;
}

.search__input::placeholder {
  color: var(--ink-muted);
  opacity: 1;
}

.search__input::-webkit-search-cancel-button,
.search__input::-webkit-search-decoration {
  display: none;
  -webkit-appearance: none;
}

.search__x {
  display: none;
  flex: none;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--ink-muted);
}

.search__x .ico {
  width: 18px;
  height: 18px;
}

.search.has-q .search__x {
  display: grid;
}

.search__cancel {
  display: none;
  flex: none;
  min-height: 44px;
  padding: 0 2px;
  border: 0;
  background: none;
  color: var(--accent-ink);
  font: var(--t-label);
}

.search.is-on .search__cancel {
  display: block;
}

/* the rarity chips: their own row across; a search by the word of the level */
.tiers {
  display: flex;
  gap: 8px;
  margin-top: 12px;
  padding: 3px var(--gutter);
  overflow-x: auto;
  scrollbar-width: none;
}

.tiers::-webkit-scrollbar,
.ruler__in::-webkit-scrollbar,
.row::-webkit-scrollbar {
  display: none;
}

.tchip {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 38px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--radius-chip);
  background: var(--surface);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tc) 40%, transparent);
  color: var(--ink);
  font: var(--t-chip);
  white-space: nowrap;
}

.tchip::before {
  content: "";
  position: absolute;
  inset: -3px 0;
}

.tchip i {
  width: 9px;
  height: 9px;
  border-radius: 2px;
  transform: rotate(45deg);
  box-shadow: 0 0 9px var(--tc);
}

.tchip b {
  color: var(--ink-muted);
  font: var(--t-count);
  font-weight: 800;
}

/* the hall of fame: a fan of the Top 10 (#2, #1, #3), "Top 10", its line, a chevron */
.plaque {
  display: grid;
  grid-template-columns: 100px minmax(0, 1fr) 22px;
  align-items: center;
  gap: 14px;
  width: calc(100% - 2 * var(--gutter));
  margin: 16px var(--gutter) 0;
  padding: 14px 14px 14px 12px;
  border: 0;
  border-radius: var(--radius-hall);
  background: var(--hall-bg);
  box-shadow: var(--hall-ring);
  color: var(--hall-sub);
  text-align: left;
}

.plaque__fan {
  position: relative;
  height: 96px;
}

.plaque__fan img {
  position: absolute;
  bottom: 2px;
  width: 42px;
  aspect-ratio: 300 / 650;
  border-radius: var(--radius-fan);
  object-fit: cover;
  box-shadow: var(--shadow-fan);
  background: var(--surface);
}

.plaque__fan img:nth-child(1) {
  left: 2px;
  transform: rotate(-11deg);
}

.plaque__fan img:nth-child(2) {
  left: 29px;
  bottom: 6px;
  z-index: 2;
  width: 46px;
}

.plaque__fan img:nth-child(3) {
  left: 56px;
  transform: rotate(11deg);
}

.plaque__txt {
  display: grid;
  gap: 6px;
  min-width: 0;
}

.plaque__k {
  color: var(--accent-ink);
  font: var(--t-hall);
}

.plaque__s {
  color: var(--hall-sub);
  font: var(--t-hall-sub);
}

.plaque__go {
  width: 22px;
  height: 22px;
  color: var(--accent);
}

/* the ruler of packs: sticky, the ground at 86 % under a blur; the current pack - surface-raised, a 1.5 px accent ring, accent-ink words */
.ruler {
  position: sticky;
  top: 0;
  z-index: 5;
  margin-top: 18px;
  padding: 10px 0;
  background: color-mix(in srgb, var(--ground) 86%, transparent);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}

.ruler__in {
  display: flex;
  gap: 8px;
  padding: 0 var(--gutter);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}

.rchip {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-height: 42px;
  padding: 0 14px 0 6px;
  border: 0;
  border-radius: var(--radius-chip);
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--line);
  color: var(--ink);
  font: 600 13.5px/1 var(--font-text);
  white-space: nowrap;
  transition: background-color var(--duration-micro) var(--ease-standard), color var(--duration-micro) var(--ease-standard);
}

.rchip img {
  width: 22px;
  height: 32px;
  border-radius: var(--radius-cover);
  object-fit: cover;
  object-position: 50% 22%;
  background: var(--surface-raised);
}

.rchip small {
  color: var(--ink-muted);
  font: 400 12px/1 var(--font-text);
}

.rchip[aria-current="true"] {
  background: var(--surface-raised);
  box-shadow: inset 0 0 0 1.5px var(--accent);
  color: var(--accent-ink);
}

/* a shelf: its head is a button across the content - the name, "10 wallpapers ›", the bar of rarities; then the row with the dock */
.shelf {
  position: relative;
  padding-top: 22px;
}

.shelf__hd {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  column-gap: 12px;
  padding: 0 var(--gutter) 6px;
  cursor: pointer;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

.shelf__t {
  grid-column: 1;
  font: var(--t-shelf);
  overflow-wrap: anywhere;
}

.shelf__n {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: end;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  color: var(--ink-muted);
  font: var(--t-meta);
  white-space: nowrap;
}

.shelf__go {
  width: 16px;
  height: 16px;
}

.dist {
  grid-column: 1;
  display: flex;
  gap: 2px;
  width: 148px;
  height: 6px;
  margin-top: 9px;
  overflow: hidden;
  border-radius: 3px;
}

.dist i {
  display: block;
  height: 100%;
}

/* the row: 34 above and below for the rise and the glow, pulled back by 12; tiles 12 apart; a soft snap to the start of a tile */
.row {
  position: relative;
  z-index: 1;
  isolation: isolate;
  display: flex;
  align-items: flex-end;
  gap: 12px;
  margin: -12px 0;
  padding: 34px var(--gutter);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  scroll-padding-inline: var(--gutter);
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}

@media (min-width: 600px) {
  .ctile {
    --tw: 120px;
  }
}

/* ---- the search layer (search.js; DESIGN.md v6 «Поиск») ------------------------------------------------------------------------ */

.srch {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  top: var(--srch-top, 96px);
  z-index: 20;
  display: flex;
  flex-direction: column;
  background: var(--ground);
  animation: srch-in 200ms var(--ease-standard);
}

.srch[hidden] {
  display: none;
}

@keyframes srch-in {
  from { opacity: 0; transform: translateY(8px); }
}

.srch__sugg {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 2px var(--gutter) 6px;
}

.srch__sugg[hidden] {
  display: none;
}

.sugg {
  min-height: 38px;
  padding: 0 15px;
  border: 0;
  border-radius: var(--radius-chip);
  background: var(--surface);
  color: var(--ink);
  font: var(--t-sugg);
}

.srch__meta {
  min-height: 25px;
  padding: 8px var(--gutter) 0;
  color: var(--ink-muted);
  font: var(--t-meta);
}

.srch__grid {
  position: relative;
  isolation: isolate;
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(var(--cols, 3), var(--gw, 1fr));
  justify-content: space-between;
  align-content: start;
  gap: 30px 0;
  padding: 22px var(--gutter) calc(120px + var(--safe-bottom));
  overflow-y: auto;
  overscroll-behavior: contain;
}

.srch__grid .ctile {
  scroll-snap-align: none;
}

.srch__empty {
  grid-column: 1 / -1;
  max-width: 34ch;
  color: var(--ink-muted);
  font: var(--t-body);
}

/* ---- the lock screen of a phone (lockscreen.js; DESIGN.md v6 «Экран блокировки и часы») --------------------------------------------
   Every size is base pixels of a 300 x 650 screen times --lu = --lock-w / 300: the drum gives 300 px (its cards are scaled whole), the hero
   the width of its poster, "Preview on lock screen" the width of the screen. */
.lock {
  --lu: calc(var(--lock-w, 300px) / 300);
  --glass: none;
  position: absolute;
  inset: 0;
  z-index: 2;
  color: var(--on-scrim);
  pointer-events: none;
  transition: opacity 200ms var(--ease-standard);
}

.lock__sb {
  position: absolute;
  top: calc(18 * var(--lu));
  right: calc(24 * var(--lu));
  height: calc(14 * var(--lu));
  opacity: 0.95;
}

.lock__sb .ico {
  width: auto;
  height: 100%;
}

.lock__clock {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(62 * var(--lu) + var(--lock-shift, 0px));
}

.lock__g,
.lock__e {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  font: var(--t-clock);
  font-size: calc(100 * var(--lu));
  letter-spacing: var(--t-clock-tracking);
  line-height: 1;
  text-align: center;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* the glass: the light gradient over the blurred wallpaper, both cut by the digits; the wallpaper is laid as on the screen behind them */
.lock__g {
  color: transparent;
  background: var(--glass-light) 0 0 / 100% 100% no-repeat, var(--glass) 0 calc(-62 * var(--lu)) / calc(300 * var(--lu)) calc(650 * var(--lu)) no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  filter: drop-shadow(0 calc(3 * var(--lu)) calc(10 * var(--lu)) var(--glass-shadow));
}

/* the edge: a thin fill and stroke, stronger at the top */
.lock__e {
  color: var(--edge-fill);
  -webkit-text-stroke: calc(1.3 * var(--lu)) var(--edge-stroke);
  -webkit-mask: var(--edge-mask);
  mask: var(--edge-mask);
}

.lock__btn {
  position: absolute;
  bottom: calc(48 * var(--lu));
  display: grid;
  place-items: center;
  width: calc(54 * var(--lu));
  height: calc(54 * var(--lu));
  border-radius: 50%;
  background: var(--lock-btn);
  box-shadow: var(--lock-btn-shadow);
}

.lock__btn .ico {
  width: calc(24 * var(--lu));
  height: calc(24 * var(--lu));
}

.lock__btn--l {
  left: calc(38 * var(--lu));
}

.lock__btn--r {
  right: calc(38 * var(--lu));
}

.lock__home {
  position: absolute;
  left: 50%;
  bottom: calc(10 * var(--lu));
  width: calc(124 * var(--lu));
  height: calc(5 * var(--lu));
  margin-left: calc(-62 * var(--lu));
  border-radius: calc(3 * var(--lu));
  background: var(--lock-home);
}

/* ---- the drum (drum.js; DESIGN.md v6 «Барабан») ------------------------------------------------------------------------------------ */

/* the visible area of the Mini App (Telegram's bottom buttons are outside it; telegram-web-app.js keeps --tg-viewport-height) */
.drum {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  height: var(--tg-viewport-height, 100%);
  z-index: 30;
  overflow: hidden;
  touch-action: none;
  overscroll-behavior: contain;
}

.drum[hidden] {
  display: none;
}

.drum__bg {
  position: absolute;
  inset: 0;
  background: var(--ground);
}

/* the light of the drum: a soft spot of the wallpaper's colour behind the front; two layers cross-fade (600 ms) */
.drum__tint {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 600ms var(--ease-wake);
}

.drum__tint.is-on {
  opacity: 1;
}

.drum__stage {
  position: absolute;
  inset: 0;
  overflow: hidden;
  perspective: 1100px;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}

.drum__world {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0;
  height: 0;
  transform-style: preserve-3d;
}

/* a wallpaper of the drum: a phone screen of 300 x 650 base pixels, scaled whole */
.dc {
  --lock-w: 300px;
  position: absolute;
  left: -150px;
  top: -325px;
  width: 300px;
  height: 650px;
  transform-origin: 50% 50%;
  will-change: transform;
}

.dc__gw {
  position: absolute;
  inset: 0;
  pointer-events: none;
  transform-origin: 50% 50%;
  will-change: transform, opacity;
}

.dc__glow {
  inset: calc(650px * var(--gy) * -1) calc(300px * var(--gx) * -0.5);
}

.dc__face {
  --rimw: 3px;
  --rimg: 34px;
  --shw: 4px;
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: calc(300px * var(--radius-phone));
  background: var(--screen-off);
  transition: scale 90ms var(--ease-standard);
}

.dc__face img,
.dc__video {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.dc__video {
  z-index: 1;
  opacity: 0;
  transition: opacity 200ms var(--ease-standard);
}

.dc__video.is-on {
  opacity: 1;
}

/* the dim lies over the lock screen (it darkens with the wallpaper); the rim and its lights lie over the dim */
.dc__dim {
  position: absolute;
  inset: 0;
  z-index: 3;
  background: var(--screen-off);
  opacity: 0;
  pointer-events: none;
  will-change: opacity;
}

.dc__face .rim,
.dc__face .shine,
.dc__face .sheen {
  z-index: 4;
}

.drum__stage.is-press .dc.is-front .dc__face {
  scale: 0.985;
}

.drum.is-lock-off .lock {
  opacity: 0;
}

/* the play badge: the phone refused to play by itself (Low Power Mode), or Save-Data - a tap plays it */
.dc__play {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 5;
  display: none;
  place-items: center;
  width: 84px;
  height: 84px;
  margin: -42px 0 0 -42px;
  border-radius: 50%;
  background: var(--scrim);
  color: var(--on-scrim);
  pointer-events: none;
}

.dc__play .ico {
  width: 34px;
  height: 34px;
  margin-left: 5px;
}

.dc.is-blocked.is-front .dc__play {
  display: grid;
}

/* the header: "back", the name of the set and "3 of 10" */
.drum__bar {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  z-index: 5;
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  height: calc(66px + var(--safe-top));
  padding: var(--safe-top) max(12px, var(--safe-right)) 0 max(12px, var(--safe-left));
  pointer-events: none;
}

.drum__bar > * {
  pointer-events: auto;
}

.drum__back {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  color: var(--ink);
}

.drum__back .ico {
  width: 20px;
  height: 20px;
}

.drum__titles {
  min-width: 0;
}

.drum__title {
  overflow: hidden;
  font: var(--t-bar);
  letter-spacing: var(--t-tight);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.drum__sub {
  margin-top: 2px;
  overflow: hidden;
  color: var(--ink-muted);
  font: var(--t-meta);
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* the caption over Telegram's MainButton: the name and the level, the description, the price; the hint once */
.drum__foot {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 5;
  display: grid;
  justify-items: center;
  gap: 9px;
  padding: 0 max(16px, var(--safe-right)) calc(14px + var(--safe-bottom)) max(16px, var(--safe-left));
  text-align: center;
  pointer-events: none;
}

.drum__foot > * {
  pointer-events: auto;
}

.cap {
  display: grid;
  justify-items: center;
  gap: 6px;
  max-width: 100%;
  transition: opacity 140ms var(--ease-standard);
}

.drum.is-spinning .cap,
.drum.is-moving .cap {
  opacity: 0.35;
}

.cap__main {
  display: grid;
  justify-items: center;
  gap: 4px;
  max-width: 100%;
  padding: 2px 6px;
  border: 0;
  border-radius: var(--radius-ui);
  background: none;
  color: var(--ink);
  text-align: center;
}

.cap__row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  max-width: 100%;
}

.cap__name {
  min-width: 0;
  overflow: hidden;
  font: var(--t-name);
  letter-spacing: var(--t-tight);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.cap__tier {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 10px;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--tc) 15%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tc) 55%, transparent);
  color: var(--tc);
  font: var(--t-chip);
  font-variant-numeric: tabular-nums;
}

.cap__tier[hidden] {
  display: none;
}

.cap__tier i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  box-shadow: 0 0 8px var(--tc);
}

.cap__desc {
  max-width: 100%;
  overflow: hidden;
  color: var(--ink-muted);
  font: var(--t-meta);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.cap__price:empty,
.cap__disc:empty,
.cap__pack:empty {
  display: none;
}

.cap__disc .pack__discount {
  max-width: 34ch;
}

.cap__packbtn {
  min-height: 40px;
}

.drum__hint {
  color: var(--ink-muted);
  font: var(--t-hint);
}

.drum__hint.is-gone {
  display: none;
}

.drum.is-busy .drum__stage {
  pointer-events: none;
}

/* ---- the price ------------------------------------------------------------------------------------------------------------------ */

/* "⭐N" in a pill on surface-raised; "≈ $N" is a line next to it, never in the pill; "Yours" and "Free" take the price's place */
.price {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-2);
  white-space: nowrap;
}

.price__stars {
  display: inline-block;
  padding: 5px 10px;
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  color: var(--ink);
  font: var(--t-price);
  font-variant-numeric: tabular-nums;
}

.price__approx {
  color: var(--ink-muted);
  font: var(--t-meta);
}

/* v6: the full price of a pack struck through next to the price with the discount */
.price__was {
  color: var(--ink-muted);
  font: var(--t-meta);
  font-variant-numeric: tabular-nums;
  text-decoration: line-through;
}

.pack__discount,
.pack__save,
.price-note {
  max-width: 44ch;
  color: var(--ink-muted);
  font: var(--t-meta);
}

.price--owned,
.price--free {
  color: var(--ink-muted);
  font: var(--t-chip);
}

.poster .price__stars,
.poster .price--owned,
.poster .price--free {
  padding: 4px 8px;
  border-radius: var(--radius-pill);
  background: var(--scrim);
  color: var(--on-scrim);
}

/* ---- posters of the cards: phone screens with the frame of «Collection» and the rarity rim ----------------------------------------- */

.poster {
  position: relative;
  flex: none;
  overflow: hidden;
  background: var(--surface);
  isolation: isolate;
}

.poster img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 35%;
}

.poster img.is-broken {
  opacity: 0;
}

.poster__video {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 35%;
}

/* the frame (3 px of `frame`) and inside it the rim of the level; over the clip and the lock screen */
.poster__rim {
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: inherit;
  box-shadow: inset 0 0 0 3px var(--frame);
  pointer-events: none;
}

.poster__rim::after {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: calc(max(0px, var(--poster-r, 12px) - 3px));
  box-shadow: inset 0 0 0 1.5px var(--rimc, transparent), inset 0 0 14px var(--rimglow, transparent);
}

.poster[data-rarity="none"] .poster__rim::after {
  display: none;
}

.poster[data-rarity="common"] { --rimc: var(--rim-common); --rimglow: transparent; }
.poster[data-rarity="rare"] { --rimc: var(--rim-rare); --rimglow: var(--rim-glow-rare); }
.poster[data-rarity="epic"] { --rimc: var(--rim-epic); --rimglow: var(--rim-glow-epic); }
.poster[data-rarity="legendary"] { --rimc: var(--rim-legendary); --rimglow: var(--rim-glow-legendary); }

/* the screen-off layer of a wake-up (js/preview.js drives its opacity with --duration-sleep / --duration-wake) */
.poster__sleep {
  position: absolute;
  inset: 0;
  z-index: 4;
  background: var(--screen-off);
  opacity: 0;
  pointer-events: none;
}

.poster.is-waking .poster__sleep,
.poster.is-waking .poster__video {
  will-change: opacity;
}

/* every picture is a phone screen, 9:19.5; the radius of a screen is a share of its width (--radius-phone) */
.poster--hero {
  --lock-w: min(64vw, 300px);
  --poster-r: calc(var(--lock-w) * var(--radius-phone));
  width: var(--lock-w);
  aspect-ratio: 9 / 19.5;
  border-radius: var(--poster-r);
}

.poster--flow {
  --poster-r: calc(min(42vw, 190px) * var(--radius-phone));
  width: min(42vw, 190px);
  aspect-ratio: 9 / 19.5;
  border-radius: var(--poster-r);
}

.poster--thumb {
  --poster-r: var(--radius-fan);
  width: 40px;
  aspect-ratio: 9 / 19.5;
  border-radius: var(--poster-r);
}

.poster--thumb .poster__rim {
  box-shadow: inset 0 0 0 1.5px var(--frame);
}

.poster--thumb .poster__rim::after {
  display: none;
}

.poster--mini {
  --poster-r: var(--radius-tile);
  aspect-ratio: 9 / 19.5;
  border-radius: var(--poster-r);
}

/* labels at the top of a picture; the price at the bottom left */
.poster__top {
  position: absolute;
  top: var(--space-2);
  left: var(--space-2);
  right: var(--space-2);
  z-index: 6;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

.poster__bottom {
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 8px;
  z-index: 6;
  display: flex;
}

.poster__top:empty,
.poster__bottom:empty {
  display: none;
}

/* a label on a picture: a scrim pill; a rarity label: the fill of the level with ground words */
.chip {
  display: inline-flex;
  align-items: center;
  padding: 3px 7px;
  border-radius: var(--radius-pill);
  background: var(--scrim);
  color: var(--on-scrim);
  font: var(--t-plate);
}

.chip--common { background: var(--rarity-common); color: var(--ground); }
.chip--rare { background: var(--rarity-rare); color: var(--ground); }
.chip--epic { background: var(--rarity-epic); color: var(--ground); }
.chip--legendary { background: var(--rarity-legendary); color: var(--ground); }

.poster--mini .poster__top {
  top: var(--space-1);
  left: var(--space-1);
  right: var(--space-1);
}

.count {
  color: var(--ink-muted);
  font: var(--t-meta);
  font-variant-numeric: tabular-nums;
}

/* ---- fans of posters (packs) ------------------------------------------------------------------------------------------------- */

.fan {
  --fan-h: 120px;
  position: relative;
  width: 100%;
  height: var(--fan-h);
}

.fan--hero { --fan-h: min(320px, (100vw - 2 * var(--gutter)) * 0.9); }
.fan--flow { --fan-h: 250px; }
.fan--thumb { --fan-h: 110px; }

.fan__img {
  position: absolute;
  left: 50%;
  bottom: calc(var(--fan-h) * 0.034);
  height: calc(var(--fan-h) * 0.92);
  aspect-ratio: 9 / 19.5;
  object-fit: cover;
  border-radius: calc(var(--fan-h) * 0.92 * 300 / 650 * var(--radius-phone));
  background: var(--surface);
  transform-origin: 50% 100%;
  transform: translateX(-50%);
}

.fan[data-n="1"] .fan__img--0,
.fan[data-n="2"] .fan__img--1,
.fan[data-n="3"] .fan__img--1 {
  box-shadow: var(--shadow-pic);
}

.fan[data-n="2"] .fan__img--0 { transform: translateX(-50%) translateX(-30%) rotate(-7deg); }
.fan[data-n="2"] .fan__img--1 { transform: translateX(-50%) translateX(30%) rotate(7deg); z-index: 2; }
.fan[data-n="3"] .fan__img--0 { transform: translateX(-50%) translateX(-44%) rotate(-9deg); z-index: 1; }
.fan[data-n="3"] .fan__img--1 { transform: translateX(-50%); z-index: 3; }
.fan[data-n="3"] .fan__img--2 { transform: translateX(-50%) translateX(44%) rotate(9deg); z-index: 2; }

/* the fan of a pack row: one cover on top, two plain screens behind it (a pack has one cover in the API) */
.fan--row {
  flex: none;
  width: 104px;
  height: 96px;
}

.fan--row::before,
.fan--row::after {
  content: "";
  position: absolute;
  top: 10px;
  width: 44px;
  height: 82px;
  border-radius: var(--radius-fan);
  background: var(--surface-raised);
}

.fan--row::before {
  left: 4px;
  transform: rotate(-9deg);
}

.fan--row::after {
  left: 56px;
  transform: rotate(9deg);
}

.fan--row .fan__img {
  left: 30px;
  top: 2px;
  bottom: auto;
  z-index: 1;
  width: 46px;
  height: 88px;
  border-radius: var(--radius-fan);
  transform: none;
}

/* ---- wallpaper and pack cards ------------------------------------------------------------------------------------------------- */

/* one rhythm: groups one step apart (--space-6), elements of a group 12, a heading and its own lines 4-8 */
.wall,
.pack {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.wall > *,
.pack > *,
.wall__info > * {
  margin: 0;
}

.wall__stage,
.pack__stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  padding-top: calc(var(--space-4) + var(--safe-top));
}

/* the hero: the phone screen and its rarity glow under it (outside the screen's rounded clip) */
.hero {
  --w: min(64vw, 300px);
  --h: calc(var(--w) * 650 / 300);
  position: relative;
  isolation: isolate;
}

.hero__glow {
  inset: calc(var(--h) * var(--gy) * -1) calc(var(--w) * var(--gx) * -0.5);
}

.hero > .poster,
.hero > .hero-btn {
  position: relative;
  z-index: 1;
}

.wall__info,
.wall__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.wall__title {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.wall__price {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
}

.wall__owned {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.wall__owned > *,
.wall__info .paying {
  margin: 0;
}

.wall__name {
  font: var(--t-hero);
  letter-spacing: var(--t-tight);
  overflow-wrap: anywhere;
}

/* v6: the owner's description in the viewer's language, up to two lines */
.wall__desc {
  display: -webkit-box;
  overflow: hidden;
  color: var(--ink-muted);
  font: var(--t-body);
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.wall__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
}

/* a rarity label in the flow: the word in the colour of the level, no plate */
.wall__meta .chip {
  padding: 0;
  background: none;
  font: var(--t-meta);
  font-weight: 600;
}

.wall__meta .chip--common { color: var(--rarity-common); }
.wall__meta .chip--rare { color: var(--rarity-rare); }
.wall__meta .chip--epic { color: var(--rarity-epic); }
.wall__meta .chip--legendary { color: var(--rarity-legendary); }

.packlist {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* a pack in one row ("Also in packs"): the fan, then the name, the price and "3 wallpapers", the discount, "Best value" */
.packrow {
  display: grid;
  grid-template-columns: 104px minmax(0, 1fr);
  align-items: center;
  gap: var(--space-4);
  width: 100%;
  padding: var(--space-3) var(--space-4) var(--space-3) var(--space-3);
  border: 0;
  border-radius: var(--radius-hall);
  background: var(--surface);
  color: var(--ink);
  text-align: left;
}

.packrow__info {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.packrow__name {
  overflow: hidden;
  font: var(--t-shelf);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.packrow__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-1) var(--space-2);
}

.packrow__meta .price {
  order: 2;
}

.packrow__k {
  color: var(--ink-muted);
  font: var(--t-meta);
}

/* "Best value" in the flow: the accent as text */
.label--best {
  color: var(--accent-ink);
  font-weight: 600;
}

.minigrid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-5) var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* a small tile of "More like this" and "Inside": the poster with its frame and rim (its glow under it), the name and the code under it */
.minitile {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  width: 100%;
  min-width: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  text-align: left;
}

/* the picture of a small tile and its glow: the glow reaches gx/2 of the width to the sides and gy of the height up and down */
.minitile__pic {
  position: relative;
  display: block;
  isolation: isolate;
}

.minitile__glow {
  inset: calc(-100% * var(--gy)) calc(-50% * var(--gx));
}

.minitile__pic > .poster {
  z-index: 1;
}

.minitile__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 0 var(--space-1);
}

.minitile__name {
  overflow: hidden;
  font: var(--t-code);
  font-size: 13px;
  font-weight: 800;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.tile__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0 var(--space-2);
}

.tile__code {
  color: var(--ink-muted);
  font: var(--t-code);
}

/* the vibes of a card: chips as wide as their words, wrapping */
.chips--inline {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.vchip {
  position: relative;
  flex: none;
  min-height: 34px;
  padding: 0 14px;
  border: 0;
  border-radius: var(--radius-chip);
  background: var(--surface);
  color: var(--ink);
  font: var(--t-chip);
  white-space: nowrap;
}

.vchip::before {
  content: "";
  position: absolute;
  inset: -5px 0;
}

/* ---- purchase screens ----------------------------------------------------------------------------------------------------------- */

.flow {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: calc(var(--tg-viewport-stable-height, 100vh) - 40px);
  padding: calc(var(--space-6) + var(--safe-top)) 0 var(--space-6);
  text-align: center;
}

.flow > .lead,
.flow > .flow__title {
  max-width: 34ch;
}

.flow__art {
  margin: 0 0 var(--space-6);
}

.flow__art .fan {
  width: min(84vw, 340px);
}

.flow__title {
  font: var(--t-name);
  letter-spacing: var(--t-tight);
}

.flow__status {
  width: 100%;
  max-width: 420px;
}

.flow__links {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: var(--space-4);
}

.flow--consent {
  align-items: stretch;
  text-align: left;
}

.flow--consent .flow__art {
  align-self: center;
  margin-bottom: var(--space-6);
}

.consent__body,
.consent__main {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.consent__main {
  gap: var(--space-3);
}

.consent__body > *,
.consent__main > * {
  margin: 0;
}

/* v6 (D-053 p.2): the product over the server's texts - its name, the price with "≈" and its footnote, how it arrives */
.consent__product {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--line);
}

.consent__name {
  font: var(--t-name);
  letter-spacing: var(--t-tight);
}

.consent__arrives {
  font: var(--t-body);
}

.consent__statement {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-ui);
  background: var(--surface);
  font: var(--t-lead);
}

/* Waiting: the poster "sleeps" (dimmed and still) - the one moving thing is the mark. Delivered: the same poster wakes out of that dim
   (duration-wake, ease-wake, no overshoot); after duration-hold the title, the tick and the rest come in (duration-small). */
.is-waiting .poster::after,
.is-done .poster::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;
  background: var(--screen-off);
  opacity: 0.45;
  pointer-events: none;
}

.is-waiting .fan__img {
  filter: brightness(0.55);
}

.is-done .poster::after {
  opacity: 0;
  animation: poster-wake var(--duration-wake) var(--ease-wake) both;
}

.is-done .fan__img {
  animation: fan-wake var(--duration-wake) var(--ease-wake) both;
}

.done__after,
.done__check {
  animation: fade-in var(--duration-small) var(--ease-standard) both;
  animation-delay: calc(var(--duration-wake) + var(--duration-hold));
}

@keyframes poster-wake {
  from { opacity: 0.45; }
  to { opacity: 0; }
}

@keyframes fan-wake {
  from { filter: brightness(0.55); }
  to { filter: brightness(1); }
}

@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .is-done .poster::after,
  .is-done .fan__img {
    animation: none;
  }

  .done__after,
  .done__check {
    animation-delay: 0ms;
  }
}

/* ---- states, skeleton, the mark, the toast -------------------------------------------------------------------------------- */

.state {
  padding: var(--space-12) var(--space-3);
  text-align: center;
}

.state__title {
  font: var(--t-name);
  letter-spacing: var(--t-tight);
}

.state__body {
  max-width: 34ch;
  margin: var(--space-2) auto 0;
  color: var(--ink-muted);
}

.state__body:first-child {
  margin-top: 0;
  color: var(--ink);
  font: var(--t-lead);
}

.state__actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-6);
}

/* loading: grey stand-ins in the shape of the screen; still - nothing moves at rest */
.skeleton {
  display: grid;
  gap: var(--space-3);
  padding-top: var(--space-3);
}

.skeleton--home {
  padding: calc(18px + var(--safe-top)) 0 0;
}

.skeleton--wall,
.skeleton--pack {
  padding-top: 0;
}

.ph {
  display: block;
  background: var(--surface);
}

.ph--line {
  height: 12px;
  border-radius: var(--radius-pill);
}

.ph--title {
  height: 22px;
  border-radius: var(--radius-pill);
}

.ph--search {
  height: 48px;
  border-radius: var(--radius-ui);
}

.ph--hall {
  height: 124px;
  border-radius: var(--radius-hall);
}

.ph-row {
  display: flex;
  gap: 12px;
  overflow: hidden;
  padding-top: var(--space-2);
}

.ph--ctile {
  flex: none;
  width: 106px;
  aspect-ratio: 300 / 650;
  border-radius: var(--radius-tile);
}

.ph--hero {
  width: min(64vw, 300px);
  aspect-ratio: 9 / 19.5;
  border-radius: calc(min(64vw, 300px) * var(--radius-phone));
}

.ph--fan {
  width: min(56vw, 240px);
  height: 320px;
  border-radius: var(--radius-hall);
}

.ph-head {
  display: grid;
  gap: var(--space-2);
}

.skeleton--flow {
  padding-top: var(--space-6);
}

/* The mark instead of a spinner (components/Mark): the ribbon in ink; rendering - light (accent) runs along its ghost; under reduced motion
   the mark stands still in ink. */
.wol-mark {
  display: block;
  overflow: visible;
}

.wol-mark path {
  fill: none;
  stroke: var(--ink);
  stroke-width: 6.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.wol-mark .wol-mark__ghost {
  opacity: 0.22;
}

.wol-mark .wol-mark__run {
  stroke: var(--accent);
  stroke-width: 7.4;
  stroke-dasharray: 16 200;
  animation: wol-run var(--duration-mark-rendering) linear infinite;
}

@keyframes wol-run {
  0% { stroke-dashoffset: 24; }
  80%,
  100% { stroke-dashoffset: -108; }
}

.spinner {
  flex: none;
  width: 48px;
}

.spinner .wol-mark {
  width: 100%;
  height: auto;
}

@media (prefers-reduced-motion: reduce) {
  .wol-mark .wol-mark__run {
    display: none;
  }

  .wol-mark .wol-mark__ghost {
    opacity: 1;
  }
}

/* the toast: an ink plate with ground words; an error - the error fill with ground words */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--space-4) + var(--safe-bottom));
  z-index: 50;
  max-width: calc(100% - 2 * var(--space-4));
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-ui);
  background: var(--ink);
  color: var(--ground);
  font: var(--t-body);
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 16px);
  transition: opacity var(--duration-micro) var(--ease-exit), transform var(--duration-micro) var(--ease-exit);
}

.toast.is-on {
  opacity: 1;
  transform: translate(-50%, 0);
  transition: opacity var(--duration-small) var(--ease-wake), transform var(--duration-small) var(--ease-wake);
}

.toast[data-tone="error"] {
  background: var(--error);
  color: var(--ground);
}

.eu-legal {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
}

.eu-legal .linkbtn--small {
  min-height: 36px;
  padding: var(--space-1) 0;
  font: var(--t-chip);
}

.flow__art--small .poster--thumb {
  width: 54px;
}

.lead--big {
  max-width: 30ch;
  font: var(--t-name);
  letter-spacing: var(--t-tight);
}

.paying {
  margin-top: var(--space-3);
}

.wait__spin {
  display: flex;
  justify-content: center;
  margin: var(--space-4) 0 var(--space-1);
}

.flow__art.is-done {
  position: relative;
}

/* the tick of the final screen: an ok circle with a ground tick and a ground ring */
.done__check {
  position: absolute;
  right: -8px;
  bottom: -8px;
  width: 44px;
  height: 44px;
  border: 3px solid var(--ground);
  border-radius: 50%;
  background: var(--ok);
}

.done__check::after {
  content: "";
  position: absolute;
  left: 14px;
  top: 7px;
  width: 9px;
  height: 18px;
  border: solid var(--ground);
  border-width: 0 3px 3px 0;
  transform: rotate(45deg);
}

/* ---- motion and touch (DESIGN.md v6 «Движение»: press, screens, the sheet) ------------------------------------------------------ */
/* Press: js/motion.js sets data-pressed on pointer-down (kept >= 90 ms) and --press-scale from the size. Down at once, back without
   overshoot. Properties are listed, never `transition: all`. */
.minitile,
.packrow,
.vchip,
.langbtn,
.sheet__opt,
.linkbtn,
.btn,
.hero-btn,
.plaque,
.rchip,
.tchip,
.sugg,
.search__cancel,
.drum__back,
.cap__main {
  touch-action: manipulation;
  transform: scale(1);
  transition:
    transform var(--duration-press-out) var(--ease-wake),
    background-color var(--duration-press-out) var(--ease-standard),
    color var(--duration-micro) var(--ease-standard),
    box-shadow var(--duration-micro) var(--ease-standard),
    opacity var(--duration-press-out) var(--ease-standard);
}

[data-pressed] {
  transform: scale(var(--press-scale, 0.97));
  transition-duration: var(--duration-press-in);
  transition-timing-function: var(--ease-standard);
}

/* the tile of a shelf moves with the dock (its transform is the dock's): the press is the dim of its picture; the head of a shelf - its name */
.ctile__card[data-pressed],
.shelf__hd[data-pressed] {
  transform: none;
}

.ctile__face::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;
  background: var(--press-dim);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--duration-press-out) var(--ease-standard);
}

.ctile__card[data-pressed] .ctile__face::before {
  opacity: 1;
  transition-duration: var(--duration-press-in);
}

.shelf__hd .shelf__t {
  transition: opacity var(--duration-press-out) var(--ease-standard);
}

.shelf__hd[data-pressed] .shelf__t {
  opacity: 0.7;
  transition-duration: var(--duration-press-in);
}

.vchip[data-pressed],
.langbtn[data-pressed],
.packrow[data-pressed],
.tchip[data-pressed],
.sugg[data-pressed],
.rchip[data-pressed]:not([aria-current="true"]) {
  background-color: color-mix(in srgb, var(--ink) 8%, var(--surface));
}

.sheet__opt[data-pressed] {
  background-color: color-mix(in srgb, var(--ink) 8%, var(--surface-raised));
}

.linkbtn[data-pressed]::before,
.cap__main[data-pressed] {
  background-color: var(--press-fill);
  transition-duration: var(--duration-press-in);
}

.sheet__opt[aria-pressed="true"][data-pressed] {
  background-color: color-mix(in srgb, var(--ink) 88%, var(--ground));
}

.btn[data-pressed] {
  background-color: color-mix(in srgb, var(--accent) 88%, var(--on-accent));
}

/* the posters of the cards dim under the finger (press-dim) */
.minitile::after,
.hero-btn::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 7;
  aspect-ratio: 9 / 19.5;
  border-radius: var(--radius-tile);
  background: var(--press-dim);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--duration-press-out) var(--ease-standard);
}

.hero-btn::after {
  border-radius: calc(min(64vw, 300px) * var(--radius-phone));
}

.minitile[data-pressed]::after,
.hero-btn[data-pressed]::after {
  opacity: 1;
  transition-duration: var(--duration-press-in);
}

@media (hover: hover) and (pointer: fine) {
  .linkbtn:hover::before,
  .cap__main:hover {
    background-color: var(--hover-fill);
  }

  .vchip:hover,
  .langbtn:hover,
  .packrow:hover,
  .tchip:hover,
  .sugg:hover,
  .rchip:hover:not([aria-current="true"]) {
    background-color: color-mix(in srgb, var(--ink) 4%, var(--surface));
  }

  .sheet__opt:hover:not([aria-pressed="true"]) {
    background-color: color-mix(in srgb, var(--ink) 4%, var(--surface-raised));
  }

  .minitile:hover::after,
  .hero-btn:hover::after {
    opacity: 0.5;
  }

  .linkbtn:hover[data-pressed]::before,
  .cap__main:hover[data-pressed] {
    background-color: var(--press-fill);
  }

  .vchip:hover[data-pressed],
  .langbtn:hover[data-pressed],
  .packrow:hover[data-pressed],
  .tchip:hover[data-pressed],
  .sugg:hover[data-pressed] {
    background-color: color-mix(in srgb, var(--ink) 8%, var(--surface));
  }

  .minitile:hover[data-pressed]::after,
  .hero-btn:hover[data-pressed]::after {
    opacity: 1;
  }
}

:focus-visible {
  transition: outline-offset var(--duration-micro) var(--ease-standard);
}

@supports (text-box: trim-both cap alphabetic) {
  .vchip,
  .langbtn,
  .linkbtn {
    text-box: trim-both cap alphabetic;
  }
}

/* the hero: a button over the poster (a tap plays the wake-up again); "Play preview" under reduced motion */
.hero-btn {
  display: block;
  padding: 0;
  border: 0;
  border-radius: calc(min(64vw, 300px) * var(--radius-phone));
  background: none;
}

.hero__play,
.hero__lock {
  display: block;
  margin: 0;
}

/* "Preview on lock screen": an in-page action on surface, 48 px, a pill */
.linkbtn.hero__lock {
  min-height: 48px;
  padding: 0 var(--space-6);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--ink);
}

.linkbtn.hero__lock::before {
  inset: 0;
  border-radius: inherit;
}

/* no orphan last word in headings */
.flow__title,
.wall__name,
.state__title,
.section-title,
.lead--big {
  text-wrap: balance;
}

/* screen entrance (router.js): forward - up 8 px out of the dark; back and replace - a shorter fade */
#app > main[data-enter="fwd"] {
  animation: screen-in var(--duration-large) var(--ease-wake) backwards;
}

#app > main[data-enter="back"],
#app > main[data-enter="replace"] {
  animation: fade-in var(--duration-medium) var(--ease-standard) backwards;
}

@keyframes screen-in {
  from { opacity: 0; transform: translateY(8px); }
}

.is-revealing {
  animation: fade-in var(--duration-small) var(--ease-standard) backwards;
}

/* the language sheet: the panel comes up from the bottom edge, the backdrop fades; it leaves faster */
.sheet {
  animation: fade-in var(--duration-small) var(--ease-standard) backwards;
}

.sheet__panel {
  padding-bottom: calc(var(--space-3) + var(--safe-bottom) + var(--tg-content-safe-area-inset-bottom, 0px));
  animation: sheet-in var(--duration-medium) var(--ease-standard) backwards;
}

.sheet.is-closing {
  opacity: 0;
  transition: opacity var(--duration-small) var(--ease-exit);
}

.sheet.is-closing .sheet__panel {
  transform: translateY(100%);
  transition: transform var(--duration-small) var(--ease-exit);
}

@keyframes sheet-in {
  from { transform: translateY(100%); }
}

/* the posters of the cards answer a finger resting on them (D-043): no callout, no selection; a vertical pan still scrolls the page */
.minitile,
.hero-btn,
.lockview__screen,
.minitile img,
.hero-btn img,
.lockview__screen img {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-user-drag: none;
}

.minitile,
.hero-btn {
  touch-action: pan-y;
}

/* ---- "Preview on lock screen" (js/lockview.js): the phone screen over the whole window --------------------------------------------- */
.lockview {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  justify-content: center;
  background: var(--screen-off);
  animation: fade-in var(--duration-small) var(--ease-standard) backwards;
}

.lockview.is-closing {
  opacity: 0;
  transition: opacity var(--duration-medium) var(--ease-exit);
}

.lockview__screen,
.lockview__screen[data-pressed] {
  position: relative;
  display: block;
  width: min(100%, calc(var(--tg-viewport-height, 100vh) * 9 / 19.5));
  height: 100%;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: var(--screen-off);
  touch-action: none;
  transform: translateY(var(--drag, 0px));
  transition: transform var(--duration-small) var(--ease-standard);
}

.lockview.is-dragging .lockview__screen {
  transition: none;
}

.lockview__screen:focus-visible {
  outline-offset: -4px;
}

.lockview__screen::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 7;
  background: var(--press-dim);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--duration-press-out) var(--ease-standard);
}

.lockview__screen[data-pressed]::after {
  opacity: 1;
  transition-duration: var(--duration-press-in);
}

/* the picture covers the screen; the lock screen follows the screen's width; Telegram's own buttons of the full screen float over the top:
   when they reach the clock, it moves down under them (DESIGN.md P-23) */
.poster--lock {
  --lock-w: min(100vw, calc(var(--tg-viewport-height, 100vh) * 9 / 19.5));
  --lock-shift: max(0px, calc(var(--tg-safe-area-inset-top, env(safe-area-inset-top, 0px)) + var(--tg-content-safe-area-inset-top, 0px)
    + var(--space-2) - var(--lock-w) * 0.2067));
  width: 100%;
  height: 100%;
  border-radius: 0;
  background: var(--screen-off);
}

.poster--lock .poster__rim {
  display: none;
}

.lockview__close {
  position: absolute;
  left: 50%;
  bottom: calc(var(--safe-bottom) + var(--space-6));
  z-index: 8;
  width: 44px;
  height: 44px;
  margin-left: -22px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--scrim);
  transition:
    transform var(--duration-press-out) var(--ease-wake),
    background-color var(--duration-press-out) var(--ease-standard);
}

.lockview__close::before,
.lockview__close::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 18px;
  height: 2px;
  margin: -1px 0 0 -9px;
  border-radius: 1px;
  background: var(--on-scrim);
  transform: rotate(45deg);
}

.lockview__close::after {
  transform: rotate(-45deg);
}

.lockview__close[data-pressed] {
  background-color: color-mix(in srgb, var(--on-scrim) 16%, var(--scrim));
  transition-duration: var(--duration-press-in);
}

/* ---- reduced motion: every change stays visible, nothing travels, spins or breathes ------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  [data-pressed] {
    transform: none;
  }

  .glow::before,
  .shine::before,
  .sheen,
  .ctile.is-bump .ctile__face,
  .ctile.is-focus .foil {
    animation: none;
  }

  .minitile,
  .packrow,
  .vchip,
  .langbtn,
  .sheet__opt,
  .linkbtn,
  .btn,
  .hero-btn,
  .plaque,
  .rchip,
  .tchip,
  .sugg,
  .search__cancel,
  .drum__back,
  .cap__main {
    transition-property: background-color, color, box-shadow, opacity;
  }

  #app > main[data-enter="fwd"],
  #app > main[data-enter="back"],
  #app > main[data-enter="replace"],
  .sheet__panel,
  .lockview,
  .srch {
    animation: fade-in var(--duration-small) linear backwards;
  }

  .sheet.is-closing .sheet__panel {
    transform: none;
  }

  .toast,
  .toast.is-on {
    transform: translate(-50%, 0);
  }

  .drum__tint,
  .ctile__video,
  .dc__video,
  .cap,
  .lock {
    transition: none;
  }

  .lockview__screen,
  .lockview__screen[data-pressed] {
    transform: none;
  }

  .lockview__close[data-pressed] {
    transform: none;
  }
}
