/* VANTA BLACK — Avatar Studio.
   Extracted from the v1 stylesheet: only the rules the studio itself needs.
   The rest of that file was the old hub, which styles/vanta.css replaces. */

.fine-print { color: var(--text-faint); font-size: 12.5px; line-height: 1.55; margin-top: 10px; }

.ae-preview { position: relative; background: radial-gradient(80% 60% at 50% 30%, rgba(143,123,216,0.14), transparent), var(--bg1); border: 1px solid var(--line); border-radius: var(--r-lg); display: flex; flex-direction: column; }

.ae-canvas { width: 100%; flex: 1; min-height: 400px; cursor: grab; touch-action: none; }

.ae-canvas:active { cursor: grabbing; }

.ae-preview-hint { text-align: center; color: var(--text-faint); font-size: 11.5px; padding: 4px 0; }

.ae-outfits { display: flex; gap: 8px; align-items: center; padding: 10px; border-top: 1px solid var(--line); flex-wrap: wrap; }

.ae-outfits > span { font-size: 12px; color: var(--text-faint); font-family: var(--font-display); }

.ae-panel { display: flex; flex-direction: column; min-width: 0; }

.ae-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 14px; }

.ae-tab { padding: 7px 14px; border-radius: 999px; border: 1px solid var(--line-strong); color: var(--text-dim); font-family: var(--font-display); font-size: 13px; }

.ae-tab.active { background: var(--grad); color: #16121e; border-color: transparent; font-weight: 600; }

.ae-grid, .ae-grid-inner { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; align-content: start; }

.ae-grid { overflow-y: auto; padding-right: 4px; max-height: 560px; }

.ae-grid > h4, .ae-grid > .swatch-row, .ae-grid > .emote-slots, .ae-grid > .ae-note, .ae-grid > .ae-grid-inner { grid-column: 1 / -1; }

.ae-subhead { font-size: 13px; color: var(--text-dim); margin: 6px 0 2px; }

.ae-note { color: var(--text-faint); font-size: 12.5px; display: flex; gap: 6px; align-items: center; }

.ae-note svg { width: 16px; height: 16px; }

.ae-item {
  background: var(--bg1); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 12px; display: flex; flex-direction: column; gap: 6px; align-items: flex-start;
  transition: border-color 0.15s, transform 0.15s;
}

.ae-item:hover { border-color: var(--line-strong); transform: translateY(-2px); }

.ae-item.equipped { border-color: var(--lav-deep); background: linear-gradient(160deg, rgba(106,85,196,0.14), var(--bg1)); }

.ae-item.locked { opacity: 0.85; }

/* Preview is a distinct, temporary state — dashed and unfilled, so it never reads
   as the solid "equipped" treatment. Nothing has been bought or worn yet. */
.ae-item.previewing {
  border-style: dashed;
  border-color: color-mix(in srgb, var(--lav) 62%, transparent);
  background: var(--bg1);
}

/* The art + name are one button: the whole tile face starts a preview. */
.ae-item-preview {
  appearance: none; background: none; border: 0; padding: 0; margin: 0; width: 100%;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  color: inherit; font: inherit; text-align: center; cursor: pointer;
}

.ae-preview-tag {
  font-size: 10px; letter-spacing: 0.11em; text-transform: uppercase;
  color: var(--lav); font-weight: 600;
}

/* Spans the grid, above the items, naming what is being previewed. */
.ae-preview-bar {
  grid-column: 1 / -1;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 9px 13px; border-radius: var(--r-md);
  border: 1px dashed color-mix(in srgb, var(--lav) 52%, transparent);
  background: rgba(106, 85, 196, 0.09);
  font-size: 12.5px; color: var(--text-2);
}

.ae-preview-bar b { color: var(--text); }

.ae-item-art { align-self: center; padding: 4px 0; }

/* Shared item art (src/platform/item-art.js). `--accent` is set per item by the
   renderer and drives the stroke and the wash together, so a rarity change moves
   both at once. One tile is one <svg>: nothing is layered or duplicated here. */
.item-art {
  display: grid; place-items: center; width: 54px; height: 54px;
  border-radius: 14px; color: var(--accent, #8E93AC);
  background:
    radial-gradient(circle at 30% 22%, color-mix(in srgb, var(--accent, #8E93AC) 26%, transparent), transparent 72%),
    var(--bg3);
  border: 1px solid color-mix(in srgb, var(--accent, #8E93AC) 22%, transparent);
}

.item-art svg { width: 58%; height: 58%; overflow: visible; }

/* A single, contained accent glow — kept off by default and only applied to the
   selected/equipped tile, so a grid of items never overdraws. */
.ae-item.equipped .item-art {
  border-color: color-mix(in srgb, var(--accent, #8E93AC) 52%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent, #8E93AC) 22%, transparent),
              0 2px 14px -6px color-mix(in srgb, var(--accent, #8E93AC) 60%, transparent);
}

.ae-item:hover .item-art { border-color: color-mix(in srgb, var(--accent, #8E93AC) 38%, transparent); }

@media (prefers-reduced-motion: reduce) {
  .ae-item { transition: none; }
  .ae-item:hover { transform: none; }
}

.ae-item-name { font-family: var(--font-display); font-size: 13.5px; font-weight: 600; }

.ae-item-desc { font-size: 11.5px; color: var(--text-faint); min-height: 28px; }

.ae-item-meta { display: flex; gap: 8px; align-items: center; width: 100%; font-size: 12px; }

.rarity-tag { color: var(--text-faint); font-size: 10.5px; letter-spacing: 0.1em; text-transform: uppercase; }
/* Separates a danced emote from a posed one at a glance — the difference the
   price is asking the player to pay for. */
.ae-clip-tag {
  font-size: 9.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--gold);
  border: 1px solid var(--line-strong); border-radius: 6px; padding: 1px 5px; white-space: nowrap;
}

.rarity-rare .rarity-tag { color: var(--gold); }

.rarity-premium .rarity-tag { color: #e8a0c8; }

.rarity-event .rarity-tag { color: #b98fe8; }

.price.owned { color: var(--ok); }

.price.event-price { color: #b98fe8; font-size: 11.5px; }

.ae-item-btn { align-self: stretch; }

.swatch-row { display: flex; gap: 10px; flex-wrap: wrap; padding: 4px 0 10px; }

.swatch {
  width: 40px; height: 40px; border-radius: 50%; background: var(--c);
  border: 2px solid var(--line-strong); transition: transform 0.15s, border-color 0.15s;
}

.swatch:hover { transform: scale(1.1); }

.swatch.active { border-color: #fff; box-shadow: 0 0 0 3px var(--lav-deep); }

.emote-slots { display: flex; gap: 10px; flex-wrap: wrap; padding-bottom: 6px; }

.emote-slot-btn {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: var(--bg1); border: 1px solid var(--line-strong); border-radius: var(--r-md);
  padding: 10px 16px; min-width: 88px;
}

.emote-slot-btn b { color: var(--gold); font-family: var(--font-display); }

.emote-slot-btn span { font-size: 12px; color: var(--text-dim); }

.emote-slot-btn.active { border-color: var(--lav); background: rgba(106,85,196,0.14); }

.emote-slot-btn.empty span { color: var(--text-faint); }

.buy-box { display: flex; flex-direction: column; gap: 14px; }

.buy-item { display: flex; gap: 14px; align-items: center; }

.buy-rows { display: flex; flex-direction: column; gap: 8px; background: var(--bg2); border-radius: var(--r-md); padding: 14px; }

.buy-rows > div { display: flex; justify-content: space-between; font-size: 14px; }

.buy-rows span:first-child { color: var(--text-dim); }

.buy-rows .insufficient b { color: var(--danger); }

/* Zoom-out escape hatch for the studio's per-category framing.
   The camera moves in close when you open Shoes or Face; this is the one
   obvious way back to the whole avatar, because a player who has zoomed into a
   boot should not have to discover a scroll gesture to get out. */
.ae-full-body {
  position: absolute; top: 10px; right: 10px; z-index: 3;
  padding: 6px 11px; font: inherit; font-size: 11.5px; letter-spacing: .04em;
  color: var(--text-2); cursor: pointer;
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  border: 1px solid var(--line); border-radius: 999px;
  backdrop-filter: blur(8px);
  transition: color var(--fast), border-color var(--fast);
}
.ae-full-body:hover { color: var(--text); border-color: var(--line-strong); }
.ae-full-body:focus-visible { outline: 2px solid var(--lavender); outline-offset: 2px; }

/* ── the studio INSIDE NEXUS ──────────────────────────────────────────────
   Scoped to `.ingame-overlay-body`, which only the in-world overlay uses — the
   hub's own Avatar Studio page is deliberately untouched by everything below.

   The problem this solves is specific to the overlay: it lives in a 760px
   modal capped at 88vh, and the editor has no layout rule of its own, so the
   preview and the item panel stack as plain blocks. A 400px-minimum canvas at
   full width then pushes every item below the fold, and picking a hat means
   scrolling past a picture of yourself inside an already-scrolling modal.

   Two columns, and a preview sized to be a reference rather than the subject. */
/* NOTE the compound selector, not a descendant one: renderAvatarEditor() adds
   `avatar-editor` to the SAME element that already carries
   `ingame-overlay-body`, so `.a .b` matches nothing here. */
.ingame-overlay-body.avatar-editor {
  display: grid;
  /* Proportional with hard limits: at the modal's width a fixed column would
     take half the space and leave room for two item cards. */
  grid-template-columns: clamp(170px, 30%, 260px) minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}

/* Sized from its own WIDTH, so a narrow column is not also a very tall one.
   3:4 frames a standing figure; the cap stops it eating the modal. */
.ingame-overlay-body .ae-canvas {
  flex: none;
  width: 100%; aspect-ratio: 3 / 4; height: auto;
  min-height: 190px; max-height: 34vh;
}

/* The modal already scrolls. A second scrolling region inside it is how a
   player ends up unable to reach the last row of hats. */
.ingame-overlay-body .ae-grid { max-height: none; overflow-y: visible; }

/* At ~170px a label plus three full-size buttons wrapped onto three lines. */
.ingame-overlay-body .ae-outfits {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; padding: 8px;
}
.ingame-overlay-body .ae-outfits > span {
  grid-column: 1 / -1; font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
}
.ingame-overlay-body .ae-outfits .btn { padding: 6px 4px; font-size: 12px; justify-content: center; }
.ingame-overlay-body .ae-preview-hint { line-height: 1.45; padding: 5px 8px; }

/* Narrow windows and phones: stack, and shrink the canvas hard — a preview
   competing with the items is the whole problem being fixed here. */
@media (max-width: 700px) {
  .ingame-overlay-body.avatar-editor { grid-template-columns: 1fr; gap: 12px; }
  .ingame-overlay-body .ae-canvas { aspect-ratio: 4 / 3; min-height: 170px; max-height: 26vh; }
}

/* ── emote cards ──────────────────────────────────────────────────────────
   The art is a BUTTON now, because the primary thing you want to do with an
   emote is watch it — not assign it to a wheel slot you have not chosen yet.
   Assign stays as the secondary action underneath. */
.ae-emote-play {
  position: relative; display: block; width: 100%; padding: 0; border: 0;
  background: none; cursor: pointer; border-radius: var(--r-md, 10px);
  overflow: hidden;
}
.ae-emote-play:focus-visible { outline: 2px solid var(--lavender); outline-offset: 2px; }
.ae-play-badge {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 20px; color: #fff; letter-spacing: .05em;
  background: rgba(10, 9, 16, .45);
  opacity: 0; transition: opacity var(--fast, 140ms) ease;
}
.ae-emote-play:hover .ae-play-badge,
.ae-emote-play:focus-visible .ae-play-badge { opacity: 1; }
.emote-card.playing .ae-play-badge { opacity: 1; background: rgba(10, 9, 16, .3); }
.emote-card.playing {
  border-color: var(--lavender);
  box-shadow: 0 0 0 1px var(--lavender), 0 6px 22px rgba(200, 180, 228, .18);
}
.ae-item-desc {
  font-size: 11.5px; line-height: 1.4; color: var(--text-faint);
  margin: 2px 0 4px; min-height: 2.8em;
}
/* A locked emote is still playable — seeing it before paying is the point. */
.emote-card.locked .ae-emote-play { opacity: 1; }
