/* =========================================================================
   Inspector — original front-end chrome
   Dark technical inspector viewer.
   ========================================================================= */

:root {
  /* Surfaces — cool desaturated near-black */
  --bg-0: oklch(0.16 0.008 250);
  --bg-1: oklch(0.2 0.01 250);
  --bg-2: oklch(0.24 0.012 250);
  --bg-3: oklch(0.28 0.014 250);

  --line-1: oklch(0.32 0.016 250 / 0.9);
  --line-2: oklch(0.4 0.02 250 / 0.6);
  --line-soft: oklch(0.55 0.02 250 / 0.18);

  --fg-0: oklch(0.97 0.005 90);
  --fg-1: oklch(0.85 0.008 250);
  --fg-2: oklch(0.65 0.012 250);
  --fg-3: oklch(0.62 0.014 250);

  /* Two-tone blue accent. --accent is bright for links, focus rings and
     small indicators. --accent-soft is a deeper, darker navy
     for selection backgrounds (Inspector tab, active rail entry, equipped
     finish card, etc.) — solid fill, not a transparent overlay, so it
     reads as a deliberate "this is selected" panel rather than a tint. */
  --accent: oklch(0.65 0.22 255);
  --accent-soft: #022d5e;
  --accent-button-bg: var(--accent-soft);
  --accent-button-fg: var(--fg-0);
  --accent-button-hover-bg: color-mix(in oklch, var(--accent-soft) 88%, white);
  --accent-line: oklch(0.65 0.22 255 / 0.55);
  --accent-glow: oklch(0.65 0.22 255 / 0.4);

  --warn: oklch(0.78 0.16 60);
  --rare: oklch(0.7 0.22 320);

  --font-ui: system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

  --radius-1: 4px;
  --radius-2: 8px;
  --radius-3: 14px;

  --shadow-1: 0 1px 0 oklch(1 0 0 / 0.04) inset, 0 1px 2px oklch(0 0 0 / 0.5);
  --shadow-2: 0 24px 64px -28px oklch(0 0 0 / 0.7), 0 4px 16px -8px oklch(0 0 0 / 0.5);
  --shadow-3: 0 40px 80px -32px oklch(0 0 0 / 0.85);

  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);

  --nav-h: 72px;
  --side-w: 340px;
  --right-panel-w: 340px;
  --topbars-h: var(--nav-h);
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--bg-0);
  color: var(--fg-1);
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.45;
  letter-spacing: -0.005em;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  position: relative;
}

button,
input,
select,
output {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: 0;
  cursor: pointer;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

kbd {
  display: inline-grid;
  place-items: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border: 1px solid var(--line-1);
  border-bottom-width: 2px;
  border-radius: var(--radius-1);
  background: var(--bg-2);
  color: var(--fg-1);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
}

kbd.kbd-wide {
  min-width: 56px;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* =========================================================================
   3D viewport
   ========================================================================= */

.viewport {
  position: fixed;
  top: var(--topbars-h);
  left: var(--side-w);
  right: var(--right-panel-w);
  bottom: 0;
  z-index: 0;
}

.viewport canvas {
  display: block;
  width: 100% !important;
  height: 100% !important;
}

.viewport-vignette {
  position: fixed;
  top: var(--topbars-h);
  left: var(--side-w);
  right: var(--right-panel-w);
  bottom: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(ellipse at 50% 60%, transparent 50%, oklch(0 0 0 / 0.45) 100%),
    linear-gradient(
      to bottom,
      oklch(0 0 0 / 0.18) 0,
      transparent 18%,
      transparent 70%,
      oklch(0 0 0 / 0.35) 100%
    );
}

/* ── Viewport loading overlay ───────────────────────────────────────────────
   A 2D preview remains visible while WebGL mounts, then fades after the
   initial view is ready. */
.viewport-loading {
  position: fixed;
  top: var(--topbars-h);
  left: var(--side-w);
  right: var(--right-panel-w);
  bottom: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 22px;
  padding: 32px;
  pointer-events: none;
  overflow: hidden;
  background: oklch(0.12 0.012 252);
  opacity: 1;
  transition:
    opacity 280ms ease,
    visibility 280ms ease;
}

.viewport-loading::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(
      to bottom,
      oklch(0.1 0.01 252 / 0.74),
      oklch(0.1 0.01 252 / 0.28) 42%,
      oklch(0.1 0.01 252 / 0.82)
    ),
    radial-gradient(ellipse at 50% 44%, transparent 0 36%, oklch(0.06 0.012 252 / 0.72) 78%),
    repeating-linear-gradient(to bottom, oklch(0.95 0.01 252 / 0.035) 0 1px, transparent 1px 7px);
}

.viewport-loading > *:not(.viewport-loading__backdrops) {
  position: relative;
  z-index: 2;
}

.viewport-loading.is-hidden {
  opacity: 0;
  visibility: hidden;
}

.viewport-loading__backdrops {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}

.viewport-loading__backdrop {
  position: absolute;
  inset: -4%;
  background-position: center;
  background-size: cover;
  filter: brightness(0.54) saturate(0.86) contrast(1.06);
  opacity: 0;
  transform: scale(1.03);
  transition:
    opacity 900ms ease,
    transform 6200ms ease;
}

.viewport-loading__backdrop.is-active {
  opacity: 0.48;
  transform: scale(1.08);
}

.viewport-loading__preview {
  /* Source is the saved /assets/skin-thumbnails/600x400 webp. Cap display near the
     native 600px width so the thumb stays crisp on hi-DPI without further
     upscale beyond what Steam's master can supply. */
  max-width: min(600px, 56%);
  max-height: 52%;
  object-fit: contain;
  filter: brightness(1.12) saturate(1.04) drop-shadow(0 24px 34px rgb(0 0 0 / 0.5));
  opacity: 0.98;
  animation: viewport-loading-preview-float 3600ms ease-in-out infinite;
  transition:
    opacity 220ms ease,
    transform 220ms ease;
}

.viewport-loading__preview[hidden] {
  display: none;
}

.viewport-loading__preview.is-swapping {
  animation:
    viewport-loading-preview-swap 420ms ease-out,
    viewport-loading-preview-float 3600ms ease-in-out infinite;
}

.viewport-loading__status {
  width: min(500px, 72%);
  display: grid;
  gap: 9px;
}

.viewport-loading__meta {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  align-items: center;
  color: var(--fg-1);
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  white-space: nowrap;
}

.viewport-loading__stage {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.viewport-loading__count {
  color: var(--fg-2);
  flex: 0 0 auto;
}

.viewport-loading__bar {
  position: relative;
  height: 6px;
  overflow: hidden;
  border-radius: 999px;
  border: 1px solid oklch(0.72 0.02 252 / 0.12);
  background: oklch(0.18 0.012 252 / 0.72);
}

.viewport-loading__bar-fill {
  position: absolute;
  inset: -1px auto -1px -1px;
  width: var(--viewport-loading-progress, 0%);
  min-width: 6%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--accent), color-mix(in oklch, var(--accent) 58%, white));
  box-shadow: 0 0 18px color-mix(in oklch, var(--accent) 38%, transparent);
  transition: width 260ms ease;
}

.viewport-loading__bar-fill::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, oklch(0.98 0.02 252 / 0.46), transparent);
  transform: translateX(-100%);
  animation: viewport-loading-progress-sheen 1500ms ease-out infinite;
}

.viewport-loading__pill {
  display: inline-flex;
  gap: 10px;
  align-items: center;
  padding: 8px 14px;
  border: 1px solid oklch(0.76 0.02 252 / 0.18);
  border-radius: 999px;
  color: var(--fg-1);
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  background: oklch(0.12 0.012 252 / 0.82);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.viewport-loading__activity {
  display: grid;
  grid-template-columns: repeat(4, 12px);
  gap: 3px;
  align-items: center;
  flex: 0 0 auto;
}

.viewport-loading__activity span {
  height: 3px;
  border-radius: 999px;
  background: var(--accent);
  opacity: 0.28;
  transform: scaleX(0.65);
  transform-origin: left center;
  animation: viewport-loading-activity 1200ms ease-in-out infinite;
}

.viewport-loading__activity span:nth-child(2) {
  animation-delay: 120ms;
}
.viewport-loading__activity span:nth-child(3) {
  animation-delay: 240ms;
}
.viewport-loading__activity span:nth-child(4) {
  animation-delay: 360ms;
}

@keyframes viewport-loading-activity {
  0%,
  100% {
    opacity: 0.28;
    transform: scaleX(0.65);
  }
  45% {
    opacity: 0.95;
    transform: scaleX(1);
  }
}

@keyframes viewport-loading-preview-float {
  0%,
  100% {
    transform: translate3d(0, 0, 0);
  }
  50% {
    transform: translate3d(0, -5px, 0);
  }
}

@keyframes viewport-loading-preview-swap {
  from {
    opacity: 0.62;
    transform: translate3d(0, 8px, 0) scale(0.985);
  }
  to {
    opacity: 0.98;
    transform: translate3d(0, 0, 0) scale(1);
  }
}

@keyframes viewport-loading-progress-sheen {
  0% {
    transform: translateX(-100%);
  }
  62%,
  100% {
    transform: translateX(100%);
  }
}

@media (max-width: 900px) {
  .viewport-loading {
    left: 0;
    right: 0;
  }

  .viewport-loading__preview {
    max-width: min(520px, 78%);
  }

  .viewport-loading__status {
    width: min(420px, 82%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .viewport-loading__preview,
  .viewport-loading__activity span,
  .viewport-loading__bar-fill::after {
    animation: none;
  }

  .viewport-loading__backdrop {
    transition: none;
  }
}

/* Floating view-mode tabs over the viewport. Two pills (In-game / Model)
   centered horizontally at the top edge of the viewport. */
.view-tabs {
  position: fixed;
  top: calc(var(--topbars-h) + 16px);
  left: calc(var(--side-w) + (100vw - var(--side-w) - var(--right-panel-w)) / 2);
  transform: translateX(-50%);
  z-index: 5;
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  background: oklch(0.18 0.008 250 / 0.78);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--line-1);
  border-radius: 999px;
  box-shadow: var(--shadow-2);
}
.model-panel-tabs {
  position: fixed;
  top: var(--topbars-h);
  right: 0;
  z-index: 11;
  display: none;
  align-items: center;
  gap: 4px;
  width: var(--right-panel-w);
  min-height: 48px;
  padding: 8px 10px 6px;
  border-left: 1px solid var(--line-1);
  border-bottom: 1px solid var(--line-1);
  background: oklch(0.15 0.008 250 / 0.92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 8px 18px oklch(0 0 0 / 0.22);
}
.view-tabs[data-active-view='stickers'] ~ .model-panel-tabs {
  display: inline-flex;
}
body[data-mode='craft'] .model-panel-tabs {
  width: 480px;
}
.model-panel-tab {
  appearance: none;
  flex: 1 1 0;
  border: 0;
  border-radius: 10px;
  background: var(--bg-2);
  color: var(--fg-1);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
  padding: 7px 12px;
  box-shadow: inset 0 0 0 1px var(--line-soft);
  cursor: pointer;
}
.model-panel-tab:hover {
  color: var(--fg-0);
  background: var(--bg-3);
}
.model-panel-tab.is-active {
  color: var(--accent-button-fg);
  background: var(--accent-button-bg);
}
@media (min-width: 901px) {
  .view-tabs[data-active-view='stickers'] ~ #craft-panel {
    top: calc(var(--topbars-h) + 48px);
  }
}

/* Rotation hint icon — small pill, centered on viewport, model view only */
/* But never over the initial loading overlay — it covers the viewport, so the
   hint would float on top of the loader. Hide it until the loader is dismissed. */

/* Clean mode keeps the view tabs at the true horizontal middle of the screen. */
html.clean-bar-left .view-tabs {
  left: 50%;
}

.view-tab {
  flex-shrink: 0;
  white-space: nowrap;
  appearance: none;
  border: none;
  background: var(--bg-2);
  color: var(--fg-1);
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
  padding: 7px 18px;
  border-radius: 999px;
  box-shadow: inset 0 0 0 1px var(--line-soft);
  cursor: pointer;
}
.view-tab:hover {
  color: var(--fg-0);
  background: var(--bg-3);
}
.view-tab.is-active {
  color: var(--accent-button-fg);
  background: var(--accent-button-bg);
}

.background-picker {
  position: fixed;
  top: calc(var(--topbars-h) + 16px);
  left: calc(var(--side-w) + 20px);
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: min(260px, calc(100vw - var(--side-w) - var(--right-panel-w) - 40px));
  padding: 6px 8px 6px 12px;
  border: 1px solid var(--line-1);
  border-radius: 999px;
  background: oklch(0.18 0.008 250 / 0.78);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: var(--shadow-1);
}

.background-picker__label {
  flex: 0 0 auto;
  color: var(--fg-2);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: uppercase;
}

.background-picker__select {
  min-width: 0;
  max-width: 150px;
  border: 0;
  border-radius: 999px;
  background: var(--bg-2);
  color: var(--fg-0);
  font-size: 12px;
  line-height: 1.2;
  letter-spacing: 0;
  padding: 5px 8px;
}

.background-picker__select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* =========================================================================
   Top nav
   ========================================================================= */

.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 70;
  display: grid;
  grid-template-columns: max-content max-content minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  height: var(--nav-h);
  padding: 0 28px 0 0;
  background: var(--bg-0);
  border-bottom: 1px solid var(--line-1);
}

.brand {
  grid-column: 1;
  display: flex;
  align-items: center;
  padding-left: 28px;
  text-decoration: none;
}

.brand__lockup {
  display: block;
  height: 44px;
  width: auto;
}

/* ── Inspector layout ───────────────────────────────────────────────────
   The 3D viewport fills the screen while the tagged inspector controls
   remain available as compact overlays. */
html.is-clean {
  /* Reclaim the two reserved side columns — the viewport, view-tabs, and
     hints all derive geometry from these, so zeroing them lets the gun span
     the full width with the panels floating over the edges. */
  --side-w: 0px;
  --right-panel-w: 0px;
  --clean-panel-w: 304px;
  --clean-gap: 16px;
  --clean-pop-w: min(460px, calc(100vw - 32px));
  --clean-panel-bg: oklch(0.17 0.008 250 / 0.92);
  --clean-panel-blur: blur(16px) saturate(135%);
}

/* Viewport, vignette and loading overlay go edge-to-edge. */
html.is-clean .viewport,
html.is-clean .viewport-vignette,
html.is-clean .viewport-loading {
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

/* Top nav: dissolve the solid bar into a downward scrim so the links stay
   legible while the model shows through behind them. The base grid pins its
   first column to var(--side-w) (now 0), so re-size it to fit the brand
   lockup or it overflows onto the links. */
html.is-clean .nav {
  grid-template-columns: max-content max-content minmax(0, 1fr);
  background: linear-gradient(
    to bottom,
    oklch(0.1 0.012 252 / 0.8) 0%,
    oklch(0.1 0.012 252 / 0.32) 58%,
    transparent 100%
  );
  border: 0;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  /* Scrim is visual only — let pointer drags fall through to the viewport so
     the gun stays grabbable up to the top edge. Controls re-enable below. */
  pointer-events: none;
}
html.is-clean .nav a,
html.is-clean .nav button,
html.is-clean .nav input,
html.is-clean .nav select {
  pointer-events: auto;
}

/* ── At rest: just the gun ──────────────────────────────────────────────
   All docked chrome is hidden; controls live in the floating command bar
   (built by src/inspector-menu.js). The panels below are revealed only as
   popovers anchored to a bar trigger (.is-clean-pop). */
html.is-clean .rail,
html.is-clean .controls-helper,
html.is-clean .model-panel-tabs {
  display: none !important;
}
/* Backdrop picker stays clear of the command dock. */
html.is-clean .background-picker {
  top: auto;
  bottom: 14px;
  left: 20px;
  z-index: 6;
}
/* Force the docked instances hidden unless they're the active popover. The
   app toggles these panels' visibility with inline styles / mode classes, so
   this must be !important (which beats inline styles) and id-specific, or the
   docked panel reappears on the right alongside the popover. */
html.is-clean #skin-panel.panel--picker:not(.is-clean-pop),
html.is-clean #craft-panel:not(.is-clean-pop) {
  display: none !important;
}

/* ── Command bar ────────────────────────────────────────────────────────
   One floating control surface. Position chosen by ?bar= (bottom default |
   left | top) → html.clean-bar-*. Built/positioned by inspector-menu.js; styled
   here with the existing design tokens (no new colours/fonts). */
.clean-bar {
  position: fixed;
  z-index: 40;
  display: flex;
  align-items: stretch;
  gap: 2px;
  padding: 6px;
  background: var(--clean-panel-bg);
  backdrop-filter: var(--clean-panel-blur);
  -webkit-backdrop-filter: var(--clean-panel-blur);
  border: 1px solid var(--line-1);
  border-radius: 999px;
  box-shadow: var(--shadow-2);
}
html.clean-bar-bottom .clean-bar {
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  flex-direction: row;
}
html.clean-bar-top .clean-bar {
  left: 50%;
  top: calc(var(--nav-h) + 14px);
  transform: translateX(-50%);
  flex-direction: row;
}
html.clean-bar-left .clean-bar {
  left: 16px;
  top: calc(var(--nav-h) + 16px);
  transform: none;
  flex-direction: column;
  width: 380px;
  gap: 6px;
  padding: 8px;
  border-radius: var(--radius-3);
  transition:
    width 180ms var(--ease),
    opacity 140ms var(--ease);
}

/* While a sticker is armed, keep its open panel interactive and let all other
   dock areas pass placement clicks through to the canvas. */
body.sticker-brushing .clean-bar {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-color: transparent;
  box-shadow: none;
  pointer-events: none;
}
body.sticker-brushing .clean-bar > :not(.is-clean-pop) {
  opacity: 0;
  pointer-events: none;
}
body.sticker-brushing .clean-bar > .is-clean-pop {
  opacity: 1;
  pointer-events: auto;
}
/* Each control is a defined surface (subtle card) rather than a bare text row,
   so the dock reads as an intentional stack instead of a flat list. */
html.clean-bar-left .clean-bar__sep {
  display: none;
}
html.clean-bar-left .clean-bar__btn[aria-expanded='true'] {
  background: var(--bg-2);
  box-shadow: inset 0 0 0 1px var(--accent-line);
}
/* Skin name is the dock's focal heading — large and bright, so the eye has a
   clear anchor instead of a wall of same-size grey text. */
html.clean-bar-left #clean-bar-skin {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--fg-0);
  line-height: 1.15;
}
/* Focal image: the current skin's render, shown only in the left dock. */
.clean-bar__thumb-wrap {
  display: none;
}
html.clean-bar-left .clean-bar__thumb-wrap {
  display: block;
  padding: 2px 2px 0;
}
html.clean-bar-left .clean-bar__thumb-wrap[hidden] {
  display: none;
}
.clean-bar__thumb {
  display: block;
  width: 100%;
  height: 118px;
  object-fit: contain;
  border-radius: var(--radius-2);
  background:
    radial-gradient(ellipse at 50% 62%, oklch(0.28 0.02 255 / 0.45), transparent 72%),
    oklch(0.13 0.008 250 / 0.6);
}
/* Muted placeholder for unavailable inspector values. */
.clean-bar__main--empty {
  color: var(--fg-3);
  font-weight: 500;
}
html.clean-bar-left .clean-bar__btn {
  width: 100%;
}
/* In the vertical dock there's room to let labels wrap instead of truncating,
   so a long skin name flows onto a second line under the weapon name. */
html.clean-bar-left .clean-bar__main {
  white-space: normal;
  max-width: none;
  overflow: visible;
  line-height: 1.25;
}
html.clean-bar-left .clean-bar__toggle {
  margin-left: auto;
}
.clean-bar__btn {
  appearance: none;
  display: flex;
  align-items: center;
  gap: 9px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--fg-1);
  font-family: inherit;
  padding: 11px 20px;
  cursor: pointer;
  text-align: left;
  transition:
    background 160ms var(--ease),
    color 160ms var(--ease),
    transform 140ms var(--ease);
}
html.clean-bar-left .clean-bar__btn {
  border-radius: var(--radius-2);
  padding: 10px 14px;
}
.clean-bar__btn--icon {
  gap: 10px;
}
.clean-bar__btn:hover {
  background: var(--bg-2);
  color: var(--fg-0);
}
.clean-bar__btn:active {
  transform: scale(0.985);
}
.clean-bar__btn[aria-expanded='true'] {
  background: var(--bg-3);
  color: var(--fg-0);
}
.clean-bar__icon {
  display: none;
}
.clean-bar__labels {
  display: flex;
  flex-direction: column;
  gap: 2px;
  line-height: 1.2;
  min-width: 0;
}
/* Weapon name sits inline in the SKIN eyebrow (e.g. "SKIN · M4A1-S"); it
   inherits the eyebrow's mono-uppercase style. */
.clean-bar__sub {
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--fg-3);
}
.clean-bar__main {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--fg-0);
  white-space: nowrap;
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Case/collection icon in the dock skin row — bare artwork, right of labels. */
.clean-bar__collection-icon {
  flex: 0 0 auto;
  width: 60px;
  height: 60px;
  margin-left: 10px;
  object-fit: contain;
}
.clean-bar__collection-icon[hidden] {
  display: none;
}

/* Meta line under the skin name: "Rarity · Case". */
.clean-bar__skin-meta {
  display: flex;
  align-items: center;
  margin-top: 4px;
  min-width: 0;
  font-size: 11px;
  color: var(--fg-2);
}
.clean-bar__skin-meta[hidden] {
  display: none;
}
.clean-bar__skin-meta > span:last-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Rarity side column on the skin header — mirrors the picker cards' left bar. */
.clean-bar__btn[data-clean-pop='skin'] {
  position: relative;
}
.clean-bar__rarity-col {
  position: absolute;
  left: 0;
  top: 8px;
  bottom: 8px;
  width: 4px;
  border-radius: 0 2px 2px 0;
  background: var(--fg-3);
}
.clean-bar__rarity-col[hidden] {
  display: none;
}
/* Keep the dock skin header a constant size whether the skin carries a case
   icon + rarity/meta (named skins) or none (Vanilla). A fixed height stops it
   collapsing vertically, and reserving the icon's slot (visibility instead of
   display:none) stops the row narrowing when the icon disappears. */
html.clean-bar-left .clean-bar__btn[data-clean-pop='skin'] {
  min-height: 80px;
}
html.clean-bar-left .clean-bar__collection-icon[hidden] {
  display: block;
  visibility: hidden;
}
.clean-bar__toggle {
  flex: 0 0 auto;
  margin-left: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 7px;
  background: var(--bg-3);
  border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
  color: var(--fg-2);
  transition:
    background 160ms var(--ease),
    color 160ms var(--ease),
    border-color 160ms var(--ease);
}
.clean-bar__toggle-ic {
  display: block;
}
.clean-bar__toggle-back {
  display: none;
}
.clean-bar__btn[aria-expanded='true'] .clean-bar__toggle-open {
  display: none;
}
.clean-bar__btn[aria-expanded='true'] .clean-bar__toggle-back {
  display: block;
}
.clean-bar__btn:hover .clean-bar__toggle,
.clean-bar__btn[aria-expanded='true'] .clean-bar__toggle {
  background: var(--accent, var(--bg-4, var(--bg-3)));
  color: var(--fg-0);
  border-color: transparent;
}
.clean-bar__sep {
  flex: 0 0 auto;
  align-self: center;
  width: 1px;
  height: 30px;
  background: var(--line-1);
}
html.clean-bar-left .clean-bar__sep {
  align-self: stretch;
  width: auto;
  height: 1px;
  margin: 2px 12px;
  background: var(--line-soft);
}

/* Always-on wear control: the #skin-float-tiers element is relocated into the
   bar by inspector-menu.js, so wear (FN..BS) is adjustable without opening the
   Skin menu. Restyle the tiers as compact bar pills. */
/* Wear(float) + pattern-seed sliders relocated into the dock (cb-live-controls
   from main.js). Re-theme to the dock's tokens with the larger custom thumbs. */
/* The wear/pattern sliders are shown for weapon skins (overriding any stale
   `hidden`), but for gloves main.js hides them (gloves use the tier buttons and
   have no pattern seed) — so honour the `hidden` attribute when set. */
.clean-paint-dock .cb-live-controls {
  margin: 0;
  display: flex !important;
  flex-direction: column;
  gap: 12px;
}
.clean-paint-dock .cb-live-controls[hidden] {
  display: none !important;
}
.clean-paint-dock .cb-live-row {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: 'label val' 'slider slider';
  gap: 3px 8px;
  align-items: center;
}
.clean-paint-dock .cb-live-label {
  grid-area: label;
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--fg-3);
}
.clean-paint-dock .cb-live-val {
  grid-area: val;
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--fg-1);
}
/* The readout is an editable number input — type a float/seed directly. The
   bordered box is always visible so it reads as an input field. */
.clean-paint-dock .cb-live-num {
  justify-self: end;
  width: 64px;
  text-align: right;
  background: var(--bg-2, rgba(0, 0, 0, 0.2));
  border: 1px solid var(--line-1);
  border-radius: 6px;
  padding: 2px 6px;
  -moz-appearance: textfield;
  transition:
    border-color 140ms var(--ease),
    background 140ms var(--ease);
}
.clean-paint-dock .cb-live-num::-webkit-outer-spin-button,
.clean-paint-dock .cb-live-num::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.clean-paint-dock .cb-live-num:hover {
  border-color: var(--fg-3, #6b7689);
}
.clean-paint-dock .cb-live-num:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--bg-2, rgba(0, 0, 0, 0.25));
}
.clean-paint-dock .cb-live-num:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.clean-paint-dock .cb-live-controls input[type='range'] {
  grid-area: slider;
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 20px;
  margin: 0;
  background: transparent;
  cursor: pointer;
}
.clean-paint-dock .cb-live-controls input[type='range']::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 999px;
  background: var(--line-1);
}
.clean-paint-dock .cb-live-controls input[type='range']::-moz-range-track {
  height: 4px;
  border-radius: 999px;
  border: 0;
  background: var(--line-1);
}
.clean-paint-dock .cb-live-controls input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  margin-top: -7px;
  border-radius: 50%;
  background: var(--fg-0);
  border: 2px solid var(--bg-0);
  box-shadow:
    0 0 0 1px var(--line-2, var(--line-1)),
    0 2px 6px oklch(0 0 0 / 0.45);
}
.clean-paint-dock .cb-live-controls input[type='range']::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--fg-0);
  border: 2px solid var(--bg-0);
  box-shadow:
    0 0 0 1px var(--line-2, var(--line-1)),
    0 2px 6px oklch(0 0 0 / 0.45);
}
.clean-paint-dock #skin-float-tiers {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
/* "WEAR" caption above the tier buttons (shown for gloves, where the buttons
   replace the Float/Pattern sliders). flex-basis:100% forces it onto its own
   line above the wrapped buttons; it hides with the tiers when weapons show the
   sliders instead. Matches the slider labels' style. */
.clean-paint-dock #skin-float-tiers::before {
  content: 'Wear';
  flex-basis: 100%;
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--fg-3);
}
.clean-paint-dock .control__tier {
  padding: 6px 10px;
  border: 0;
  border-radius: 999px;
  background: var(--bg-2);
  color: var(--fg-2);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.03em;
  transition:
    background 160ms var(--ease),
    color 160ms var(--ease),
    transform 120ms var(--ease);
}
.clean-paint-dock .control__tier:hover:not(:disabled) {
  background: var(--bg-3);
  color: var(--fg-0);
}
.clean-paint-dock .control__tier:active:not(:disabled) {
  transform: scale(0.95);
}
.clean-paint-dock .control__tier[aria-pressed='true'] {
  background: var(--accent-button-bg);
  color: var(--accent-button-fg);
}
.clean-paint-dock .control__tier:disabled {
  opacity: 0.35;
}
/* Tier row (gloves / non-client-bake): full-width buttons. main.js toggles the
   tiers vs the continuous sliders via #skin-float-tiers' inline display, so the
   box shows whichever applies to the active item. */
.clean-paint-dock .control__tier {
  flex: 1 1 0;
  padding: 7px 4px;
  text-align: center;
}

/* ── Wear / pattern / StatTrak — pinned to the bottom of the left dock ───────
   Lives at the foot of the command dock (below the menu buttons / open panel),
   so wear + pattern + StatTrak stay accessible whichever menu is open. main.js
   hides it (.clean-paint-dock[hidden]) whenever the active item isn't paintable. */
html.is-clean .clean-paint-dock {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 8px;
  padding: 12px 14px 4px;
  border-top: 1px solid var(--line-1);
}
html.is-clean .clean-paint-dock[hidden] {
  display: none;
}
/* The injected sliders / StatTrak default to margin-top for the in-flow layout;
   the box owns spacing via its own gap, so neutralize those margins. */
.clean-paint-dock .cb-live-controls,
.clean-paint-dock .cb-stattrak {
  margin-top: 0;
}

/* Wear lives in its own box now, so hide the (empty) wear control in the Skin
   popover. */
html.is-clean #skin-panel .panel__controls {
  display: none;
}

/* ── Click-away backdrop ───────────────────────────────────────────────── */
.clean-pop-backdrop {
  position: fixed;
  inset: 0;
  z-index: 38;
  background: oklch(0 0 0 / 0.28);
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms var(--ease);
}
.clean-pop-backdrop[data-open='true'] {
  opacity: 1;
  pointer-events: auto;
}

/* Keep the In-game/Model toggle clear of a top-positioned command bar. */
html.clean-bar-top .view-tabs {
  top: calc(var(--nav-h) + 72px);
}

/* ── Popovers — the existing panels, revealed + anchored by inspector-menu.js.
   JS sets left/top/bottom; CSS owns appearance, size, and internal scroll. */
html.is-clean #skin-panel.panel--picker.is-clean-pop,
html.is-clean #craft-panel.is-clean-pop {
  display: flex;
  flex-direction: column;
  position: fixed;
  z-index: 42;
  width: var(--clean-pop-w);
  max-height: min(86vh, 860px);
  background: var(--clean-panel-bg);
  backdrop-filter: var(--clean-panel-blur);
  -webkit-backdrop-filter: var(--clean-panel-blur);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-3);
  box-shadow: var(--shadow-3);
  overflow: hidden;
  animation: clean-pop-in 180ms var(--ease) both;
}
@keyframes clean-pop-in {
  from {
    opacity: 0;
    transform: translateY(6px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
/* The craft panel is hidden outside craft mode, so its open state must win
   with matching id specificity. */
html.is-clean #craft-panel.is-clean-pop {
  display: flex !important;
}

/* ── Inline accordion ──────────────────────────────────────────────────
   The menu expands as part of the one dock panel (right under its row),
   instead of floating as a separate popover. Overrides the fixed-position
   popover styles above. */
html.is-clean #skin-panel.panel--picker.is-clean-accordion,
html.is-clean #craft-panel.is-clean-accordion {
  position: static !important;
  left: auto !important;
  top: auto !important;
  right: auto !important;
  bottom: auto !important;
  width: auto !important;
  max-width: none;
  flex: 1 1 auto;
  min-height: 0;
  max-height: none;
  margin: 6px 0 2px;
  border: 0;
  border-radius: var(--radius-2);
  box-shadow: none;
  background: var(--bg-0);
  overflow: hidden auto;
  animation: none;
}
/* The expanded panel scrolls as a whole, so the skin list renders at its
   natural height (flex:1 inside a scroll container collapses to nothing). */
html.is-clean #skin-panel.is-clean-accordion #skin-list {
  flex: 0 0 auto;
  min-height: 0;
  max-height: none;
  overflow: visible;
}

/* When a menu is open the dock becomes a full panel dedicated to that one
   control: hide the thumb, the other rows, wear and dividers; the active row
   is the header and its content fills the height. Wider so rich content
   (sticker grid, finish list) isn't cramped. */
html.clean-pop-open.clean-bar-left .clean-bar {
  width: 480px;
  height: min(88vh, 980px);
}
html.clean-pop-open.clean-bar-left .clean-bar > .clean-bar__thumb-wrap,
html.clean-pop-open.clean-bar-left .clean-bar > .clean-bar__sep,
html.clean-pop-open.clean-bar-left .clean-bar > .clean-bar__btn:not([aria-expanded='true']) {
  display: none;
}
html.clean-pop-open.clean-bar-left .clean-bar > .clean-bar__btn[aria-expanded='true'] {
  flex: 0 0 auto;
}
/* The dock can get tall once a menu is expanded — let it scroll as a whole if
   it would run past the viewport. */
html.clean-bar-left .clean-bar {
  max-height: calc(100vh - var(--nav-h) - 28px);
  overflow-y: auto;
}

/* Combined "Skin" popover: weapon selector + wear + search + browse stay fixed
   at the top; the finish list fills the rest and scrolls. */
html.is-clean #skin-panel.is-clean-pop .panel__controls,
html.is-clean #skin-panel.is-clean-pop .panel__search,
html.is-clean #skin-panel.is-clean-pop .panel__nav {
  flex: 0 0 auto;
}
html.is-clean #skin-panel.is-clean-pop #skin-list {
  flex: 1 1 auto;
  min-height: 0;
  max-height: none;
  overflow-y: auto;
}

/* One panel, two views toggled by the ‹Weapon / Skin› switcher (data-view on
   #skin-panel). Each view hides the other's list so it gets the full panel
   height. Skin view = search + finish list; Weapon view = class tabs + the
   weapon row list. */
html.is-clean #skin-panel[data-view='skin'] #weapon-picker {
  display: none;
}
html.is-clean #skin-panel[data-view='weapon'] .panel__search,
html.is-clean #skin-panel[data-view='weapon'] #skin-list {
  display: none;
}

/* Weapon view: the picker fills the panel and its row list scrolls, mirroring
   the skin list (meta + class tabs stay pinned above the scrolling rows). */
html.is-clean #skin-panel[data-view='weapon'] #weapon-picker {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
html.is-clean #skin-panel[data-view='weapon'] .weapon-picker__models--rows {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
}

/* ‹Weapon / Skin› view switcher — two clearly labelled tabs, active one filled
   with the accent so it's obvious which list is showing. */
html.is-clean .panel__view-switch {
  display: flex;
  flex: 0 0 auto;
  gap: 5px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line-1);
}
html.is-clean .panel__view-tab {
  flex: 1 1 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--radius-2);
  background: var(--bg-1);
  color: var(--fg-2);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition:
    background 160ms var(--ease),
    color 160ms var(--ease);
}
html.is-clean .panel__view-tab:hover {
  background: var(--bg-2);
  color: var(--fg-0);
}
html.is-clean .panel__view-tab[aria-selected='true'] {
  background: var(--accent-button-bg);
  color: var(--accent-button-fg);
}
html.is-clean .panel__view-tab svg {
  opacity: 0.85;
}

/* Weapon rows — thumbnail-left + name rows, same shape as the skin/finish rows,
   laid out in TWO columns so more weapons fit. The grid grows downward, so when
   it overflows it scrolls vertically (never horizontally). Scoped under
   #weapon-picker so it beats the base .weapon-picker__models flex/wrap rule
   (same class-specificity, defined later in the file). */
html.is-clean #weapon-picker .weapon-picker__models--rows {
  display: grid;
  grid-template-columns: 1fr 1fr;
  /* Pack rows at the top at their natural height. A grid's default align-content
     (normal → stretch) blows the rows up to fill the panel when there are only a
     few weapons, leaving huge gaps. */
  align-content: start;
  gap: 4px 8px;
  /* Dark, thin scrollbar (matches the skin list) — never the OS light bar. */
  scrollbar-width: thin;
  scrollbar-color: var(--bg-3) transparent;
}
html.is-clean #weapon-picker .weapon-picker__models--rows::-webkit-scrollbar {
  width: 8px;
}
html.is-clean #weapon-picker .weapon-picker__models--rows::-webkit-scrollbar-track {
  background: transparent;
}
html.is-clean #weapon-picker .weapon-picker__models--rows::-webkit-scrollbar-thumb {
  background: var(--bg-3);
  border-radius: 4px;
}
html.is-clean .weapon-picker__models--rows .weapon-picker__model {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-width: 0;
  min-height: 66px;
  padding: 5px 8px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--fg-1);
  cursor: pointer;
  text-align: left;
  transition: background 120ms var(--ease);
}
html.is-clean .weapon-picker__models--rows .weapon-picker__model:hover {
  background: oklch(0.24 0.012 250 / 0.5);
}
html.is-clean .weapon-picker__models--rows .weapon-picker__model[aria-pressed='true'] {
  background: var(--accent-soft);
}
html.is-clean .weapon-picker__models--rows .wp-thumb {
  flex: 0 0 96px;
  width: 96px;
  aspect-ratio: 3 / 2;
  background-color: transparent;
  background-repeat: no-repeat;
  /* The 300x200 preview store is 3:2 like this box, so contain shows the
     whole render; auto (the inherited default) would crop to the top-left
     corner and read as zoomed-in. */
  background-size: contain;
  background-position: center;
  border-radius: 4px;
  opacity: 0.95;
}
html.is-clean .weapon-picker__models--rows .wp-name {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--fg-0);
  letter-spacing: -0.005em;
  text-align: left;
  white-space: normal;
}

/* Reveal + restyle the integrated weapon selector (base CSS hides it). */
html.is-clean #skin-panel #weapon-picker {
  display: block;
  flex: 0 0 auto;
  padding: 11px 16px 11px;
  border-bottom: 1px solid var(--line-1);
  background: oklch(0.2 0.01 250 / 0.45);
}
html.is-clean .weapon-picker__meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 8px;
}
html.is-clean .weapon-picker__name {
  font-size: 15px;
  font-weight: 600;
  color: var(--fg-0);
  letter-spacing: -0.01em;
}
html.is-clean .weapon-picker__count {
  font-family: var(--font-mono);
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--fg-3);
  white-space: nowrap;
}
/* Class tabs: a wrap of text pills, separated from the model chips below by a
   hairline so the two rows read as "pick class" then "pick model". */
html.is-clean .weapon-picker__cats {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin: 0 0 9px;
  padding-bottom: 9px;
  border-bottom: 1px solid var(--line-soft);
}
html.is-clean .weapon-picker__cat {
  min-height: 0;
  padding: 6px 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--fg-2);
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition:
    background 160ms var(--ease),
    color 160ms var(--ease);
}
html.is-clean .weapon-picker__cat:hover {
  color: var(--fg-0);
  background: var(--bg-2);
}
html.is-clean .weapon-picker__cat[aria-pressed='true'] {
  color: var(--accent-button-fg);
  background: var(--accent-button-bg);
}
/* Model chips: subtle filled pills (no borders) so the row isn't a grid of
   boxes; the selected one is the only filled-accent element. */
html.is-clean .weapon-picker__models {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
html.is-clean .weapon-picker__model {
  min-height: 0;
  padding: 6px 12px;
  border: 0;
  border-radius: 999px;
  background: var(--bg-2);
  color: var(--fg-2);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  transition:
    background 160ms var(--ease),
    color 160ms var(--ease);
}
html.is-clean .weapon-picker__model:hover {
  color: var(--fg-0);
  background: var(--bg-3);
}
html.is-clean .weapon-picker__model[aria-pressed='true'] {
  color: var(--accent-button-fg);
  background: var(--accent-button-bg);
}

/* Weapon-model grid: uniform thumbnail tiles (vanilla silhouette + name) so a
   model is picked by shape, not by reading near-identical labels. Overrides the
   pill layout above for weapon mode; the gloves family list keeps the pills. */
html.is-clean .weapon-picker__models--grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 10px 7px;
  /* No inner scroll: every model shows at once. Forced to 6 columns (auto-fill
     landed just under the 6-col threshold at this dock width), so 11 rifles fit
     in 2 rows and a 19-knife class in ~4. Tiles (~66px) stay legible. */
}
/* Tiles are frameless: just the thumbnail + caption, so the panel isn't a grid
   of dark boxes. The only "surface" is the thumbnail's own soft display. */
html.is-clean .weapon-picker__models--grid .weapon-picker__model {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-height: 0;
  /* Grid items default to min-width:auto, so the nowrap caption forced the tile
     wider than its track and the long knife names bled into the next column.
     Allow the tile to shrink to its track so the caption stays inside it. */
  min-width: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  cursor: pointer;
}
html.is-clean .weapon-picker__models--grid .wp-thumb {
  width: 100%;
  aspect-ratio: 3 / 2;
  /* No background — the weapon render sits directly on the panel. State is
     carried by opacity (idle vs active) and, for the selection, an accent ring. */
  background-color: transparent;
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center;
  border-radius: 6px;
  opacity: 0.78;
  transition:
    opacity 160ms var(--ease),
    box-shadow 160ms var(--ease);
}
html.is-clean .weapon-picker__models--grid .wp-name {
  font-size: 11.5px;
  line-height: 1.2;
  text-align: center;
  color: var(--fg-2);
  /* Long knife names wrap to a second line within the tile rather than
     truncating or overflowing into the neighbour. */
  white-space: normal;
  overflow-wrap: anywhere;
  max-width: 100%;
  transition: color 160ms var(--ease);
}
html.is-clean .weapon-picker__models--grid .weapon-picker__model:hover .wp-thumb {
  opacity: 1;
}
html.is-clean .weapon-picker__models--grid .weapon-picker__model:hover .wp-name {
  color: var(--fg-0);
}
html.is-clean .weapon-picker__models--grid .weapon-picker__model[aria-pressed='true'] .wp-thumb {
  opacity: 1;
  box-shadow: inset 0 0 0 2px var(--accent);
}
html.is-clean .weapon-picker__models--grid .weapon-picker__model[aria-pressed='true'] .wp-name {
  color: var(--fg-0);
  font-weight: 600;
}

/* Gloves: only ~6 families with long names, so a roomier 3-column grid with a
   larger render and a full (wrapping) name instead of the 6-up weapon layout. */
html.is-clean .weapon-picker__models--gloves {
  grid-template-columns: repeat(3, 1fr);
  gap: 14px 10px;
}
html.is-clean .weapon-picker__models--gloves .wp-name {
  font-size: 12px;
  white-space: normal;
  overflow: visible;
}

/* HUD */
.hud {
  display: flex;
  gap: 0;
  background: oklch(0.18 0.008 250 / 0.78);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-2);
  overflow: hidden;
  box-shadow: var(--shadow-1);
}

.hud__cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 14px;
  min-width: 92px;
  border-right: 1px solid var(--line-1);
}

.hud__cell:last-child {
  border-right: 0;
}

.hud__label {
  font-family: var(--font-mono);
  font-size: 9.5px;
  color: var(--fg-3);
  text-transform: uppercase;
  letter-spacing: 0.16em;
}

.hud__value {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  color: var(--fg-0);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 180px;
}

.hud[hidden] {
  display: none !important;
}

/* Controls helper — collapsible icon at the bottom-left of the viewport.
   The shortcut grid is hidden by default and slides up when the user clicks
   the "Shortcuts" pill and stays clear of the centred view tabs. */
.controls-helper {
  position: fixed;
  left: calc(var(--side-w) + 20px);
  bottom: 20px;
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-start;
}
.controls-helper__toggle {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  border-radius: 999px;
  background: oklch(0.18 0.008 250 / 0.85);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--line-1);
  box-shadow: var(--shadow-1);
  color: var(--fg-1);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  cursor: pointer;
  transition:
    color 120ms ease,
    border-color 120ms ease;
}
.controls-helper__toggle:hover {
  color: var(--fg-0);
  border-color: var(--line-2, var(--line-1));
}
.controls-helper[data-open='true'] .controls-helper__toggle {
  color: var(--accent);
}
.controls-helper__grid {
  display: none;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px 14px;
  margin: 0;
  padding: 12px 14px;
  background: oklch(0.18 0.008 250 / 0.85);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-2);
  box-shadow: var(--shadow-1);
}
.controls-helper[data-open='true'] .controls-helper__grid {
  display: grid;
}
.controls-helper__grid div {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 6px;
}
.controls-helper__grid dt {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 0;
}
.controls-helper__grid dd {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--fg-2);
  white-space: nowrap;
}

/* =========================================================================
   Left rail — slot selector
   ========================================================================= */

.rail {
  position: fixed;
  left: calc(var(--side-w) + 20px);
  top: calc(var(--nav-h) + (100vh - var(--nav-h)) / 2);
  transform: translateY(-50%);
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px;
  /* overflow MUST be visible so each entry's hover-flyout can escape the
     rail's right edge. The 6 fixed-size entries fit within most viewports
     without scrolling. */
  overflow: visible;
  background: oklch(0.18 0.008 250 / 0.78);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-3);
  box-shadow: var(--shadow-2);
}

.rail__divider {
  height: 1px;
  background: var(--line-1);
  margin: 4px 6px;
}

/* Agents share the weapon picker; standalone showcases keep that menu usable. */
.agent-actions {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--line-1);
  border-radius: 24px;
  background: var(--clean-panel-bg);
}
.agent-actions[hidden] { display: none; }
.agent-actions .view-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  gap: 6px;
  height: 30px;
  padding: 5px 12px;
  white-space: nowrap;
  line-height: 18px;
}
.agent-actions .view-tab:disabled { opacity: .4; cursor: default; }
.agent-actions kbd { margin: 0; height: 18px; min-width: 18px; padding: 0 3px; opacity: .55; font: inherit; font-size: 10px; line-height: 16px; }
@media (max-width: 900px) {
  .agent-actions { gap: 4px; padding: 3px; }
  .agent-actions .view-tab { padding: 7px 10px; font-size: 11px; }
}
@media (max-width: 360px) {
  .nav:has(.agent-actions:not([hidden])) .brand { width: 24px; overflow: hidden; }
  .nav:has(.agent-actions:not([hidden])) .brand__lockup { max-width: none; flex-shrink: 0; }
}
html[data-agent-showcase='true'] #model-panel-tabs,
html[data-agent-showcase='true'] #skin-next,
html[data-agent-showcase='true'] .clean-bar [data-clean-pop='stickers'],
html[data-agent-showcase='true'] .clean-bar__sep,
html[data-agent-showcase='true'] .clean-bar__thumb-wrap,
html[data-agent-showcase='true'] .clean-paint-dock,
html[data-agent-showcase='true'] #mobile-dock [data-dock='stickers'] {
  display: none !important;
}
html.is-clean #weapon-picker[data-group='agents'] .weapon-picker__models--rows {
  grid-template-columns: minmax(0, 1fr);
}
.weapon-picker__portrait {
  width: 88px;
  height: 88px;
  object-fit: contain;
}
.weapon-picker__agent-name {
  grid-column: 2;
  display: grid;
  gap: 3px;
  min-width: 0;
  text-align: left;
}
.weapon-picker__agent-name small {
  color: var(--text-2);
  font-size: 10px;
}
html.is-clean #weapon-picker .weapon-picker__agent {
  min-height: 96px;
  justify-content: start;
  display: grid;
  grid-template-columns: 88px minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  height: auto;
  padding: 4px 10px;
  white-space: normal;
  line-height: 1.4;
}
.weapon-picker__team {
  grid-column: 1 / -1;
  padding: 14px 10px 6px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-2);
}

/* Each rail entry wraps a numbered class button (1 = rifles, etc.) plus a
   hover-revealed flyout that lists every weapon in that class. The entry
   needs position:relative so the flyout can absolute-position to its right. */
.rail__entry {
  position: relative;
}
.rail__flyout {
  position: absolute;
  left: 100%;
  top: var(--rail-flyout-offset-y, 0px);
  margin-left: 10px;
  min-width: 180px;
  max-height: calc(100vh - 24px);
  max-height: calc(100svh - 24px);
  padding: 6px 0;
  display: none;
  flex-direction: column;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: oklch(0.2 0.01 250 / 0.97);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-2);
  box-shadow: var(--shadow-2);
  backdrop-filter: blur(10px) saturate(140%);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  z-index: 12;
}
/* Bridge the visual gap between button and flyout so the cursor can cross
   it without exiting the entry's mouseleave-grace window. */
.rail__flyout::before {
  content: '';
  position: absolute;
  left: -10px;
  top: 0;
  bottom: 0;
  width: 10px;
}
.rail__entry.is-open > .rail__flyout {
  display: flex;
}
.rail__entry--knife .rail__flyout {
  min-width: 360px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-content: start;
}
.rail__entry--knife.is-open > .rail__flyout {
  display: grid;
}
.rail__flyout::-webkit-scrollbar {
  width: 6px;
}
.rail__flyout::-webkit-scrollbar-track {
  background: transparent;
}
.rail__flyout::-webkit-scrollbar-thumb {
  background: var(--line-1);
  border-radius: 999px;
}
.rail__flyout-item {
  background: transparent;
  border: 0;
  color: var(--fg-2);
  font-family: inherit;
  font-size: 12.5px;
  text-align: left;
  padding: 8px 14px;
  cursor: pointer;
  white-space: nowrap;
  transition:
    background 100ms var(--ease),
    color 100ms var(--ease);
}
.rail__flyout-item:hover {
  background: oklch(0.26 0.012 250 / 0.7);
  color: var(--fg-0);
}
.rail__flyout-item.is-on {
  color: var(--accent);
}

.rail__btn {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: 64px;
  height: 64px;
  border-radius: var(--radius-2);
  color: var(--fg-2);
  background: transparent;
  border: 1px solid transparent;
  transition:
    background 160ms var(--ease),
    color 160ms var(--ease),
    border-color 160ms var(--ease),
    transform 160ms var(--ease);
}

.rail__btn:hover:not(:disabled) {
  background: var(--bg-2);
  color: var(--fg-0);
}

.rail__btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.rail__btn[aria-pressed='true'] {
  background: var(--accent-soft);
  color: var(--fg-0);
  border-color: var(--accent-line);
  box-shadow:
    0 0 0 1px var(--accent-line),
    0 8px 24px -12px var(--accent-glow);
}

.rail__btn[aria-pressed='true']::before {
  content: '';
  position: absolute;
  left: -9px;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 24px;
  border-radius: 2px;
  background: var(--accent);
  box-shadow: 0 0 12px var(--accent-glow);
}

/* Role is now the primary label (top); number is the secondary key-hint
   below. Swap from the original "big number / small role" stack. */
.rail__role {
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--fg-1);
  text-transform: none;
}

.rail__btn[aria-pressed='true'] .rail__role {
  color: var(--fg-0);
}

.rail__num {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  line-height: 1;
  color: var(--fg-3);
  letter-spacing: 0.06em;
  margin-top: 2px;
}

.rail__btn[aria-pressed='true'] .rail__num {
  color: var(--fg-0);
}

.rail__num--glyph {
  font-size: 11px;
}

/* =========================================================================
   Bottom-right skin panel
   ========================================================================= */

.panel {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 10;
  width: 420px;
  max-height: calc(100vh - var(--nav-h) - 40px);
  display: flex;
  flex-direction: column;
  background: oklch(0.18 0.008 250 / 0.86);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-3);
  box-shadow: var(--shadow-3);
  overflow: hidden;
  transition: opacity 200ms var(--ease);
}

.panel--picker {
  left: 0;
  right: auto;
  top: var(--topbars-h);
  bottom: 0;
  width: var(--side-w);
  max-height: none;
  background: var(--bg-1);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: 0;
  border-right: 1px solid var(--line-1);
  border-radius: 0;
  box-shadow: none;
}

.panel.is-loading::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  background-size: 50% 100%;
  background-repeat: no-repeat;
  animation: panel-load 1.2s linear infinite;
  pointer-events: none;
}

@keyframes panel-load {
  0% {
    background-position: -50% 0;
  }
  100% {
    background-position: 150% 0;
  }
}

/* Head — hidden: the active-skin name + preview live in the right-side spec
   panel. The element stays in the DOM (existing JS writes to
   skin-current-name etc.), just visually collapsed. */
.panel__head {
  display: none;
}
.panel__head--legacy {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 16px;
  padding: 16px 18px 14px;
  border-bottom: 1px solid var(--line-1);
  background: linear-gradient(180deg, oklch(0.22 0.01 250 / 0.55), transparent);
}

.panel__title {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.panel__eyebrow {
  font-family: var(--font-mono);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--accent);
}

.panel__name {
  margin: 2px 0 0;
  font-size: 18px;
  font-weight: 600;
  color: var(--fg-0);
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.panel__meta {
  margin: 2px 0 0;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--fg-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.panel__preview {
  position: relative;
  width: 124px;
  height: 78px;
  border-radius: var(--radius-2);
  overflow: hidden;
  flex-shrink: 0;
  background: transparent;
}

.panel__preview-img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  background-position: center;
  background-size: contain;
  background-repeat: no-repeat;
  background-color: transparent;
}

.panel__preview-frame {
  position: absolute;
  inset: 0;
  border: 1px solid oklch(1 0 0 / 0.06);
  border-radius: inherit;
  pointer-events: none;
  box-shadow: none;
}

/* In-panel weapon picker — unused (the .rail flyouts serve weapon choice).
   Kept in the DOM so renderWeaponPicker()'s output doesn't 404, hidden
   visually. */
.weapon-picker {
  display: none;
}
.weapon-picker--legacy {
  padding: 14px 18px 12px;
  border-bottom: 1px solid var(--line-1);
  background: oklch(0.16 0.008 250 / 0.28);
}

.weapon-picker__meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 10px;
}

.weapon-picker__name {
  font-weight: 600;
  font-size: 14px;
  color: var(--fg-0);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.weapon-picker__count {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--fg-3);
  white-space: nowrap;
}

.weapon-picker__cats,
.weapon-picker__models {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
}

.weapon-picker__cats {
  margin-bottom: 10px;
}

.weapon-picker__cat,
.weapon-picker__model {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 28px;
  border-radius: var(--radius-1);
  color: var(--fg-3);
  transition:
    color 140ms var(--ease),
    background 140ms var(--ease);
}

.weapon-picker__cat {
  padding: 4px 6px;
  font-size: 12px;
  border-bottom: 1px solid transparent;
}

.weapon-picker__model {
  padding: 4px 10px;
  font-size: 12px;
  background: transparent;
}

@media (pointer: coarse), (max-width: 700px) {
  .weapon-picker__cats,
  .weapon-picker__models {
    gap: 8px;
  }

  .weapon-picker__cat,
  .weapon-picker__model {
    min-height: 38px;
    padding: 0 12px;
  }
}

.weapon-picker__cat:hover,
.weapon-picker__model:hover {
  color: var(--fg-0);
  background: var(--bg-1);
}

.weapon-picker__cat[aria-pressed='true'] {
  color: var(--fg-0);
  border-bottom-color: var(--fg-0);
  background: transparent;
}

.weapon-picker__model[aria-pressed='true'] {
  color: var(--fg-0);
  background: var(--accent-soft);
}

/* Controls */
.panel__controls {
  padding: 14px 18px;
  border-bottom: 1px solid var(--line-1);
}

.panel__search {
  position: relative;
  padding: 12px 18px;
  border-bottom: 1px solid var(--line-1);
}

.panel__search svg {
  position: absolute;
  left: 28px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--fg-3);
  pointer-events: none;
}

.panel__search input {
  width: 100%;
  padding: 8px 10px 8px 30px;
  border: 1px solid var(--line-1);
  border-radius: var(--radius-1);
  background: var(--bg-1);
  color: var(--fg-0);
  font-size: 12px;
  outline: none;
}

.panel__search input:focus {
  border-color: var(--accent-line);
}

.control {
  display: flex;
  flex-direction: column;
  gap: 9px;
  min-width: 0;
}

.control__label {
  font-family: var(--font-mono);
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--fg-3);
}

/* Wear-tier buttons — full-width 5-up grid, each colored to its wear bucket
   (green=FN through deep red=BS). The tier color shows muted as text in the
   resting state and as a solid background when the tier is active. */
.control__tiers {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 4px;
  width: 100%;
}

.control__tier {
  appearance: none;
  border: 1px solid var(--line-1);
  background: transparent;
  color: var(--fg-3);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  line-height: 1;
  padding: 10px 0;
  border-radius: 3px;
  cursor: pointer;
}
.control__tier:hover:not(:disabled),
.control__tier:active:not(:disabled) {
  background: transparent;
  border-color: var(--fg-0);
  color: var(--fg-0);
}
.control__tier:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
.control__tier[aria-pressed='true'] {
  background: var(--fg-0);
  border-color: var(--fg-0);
  color: var(--bg-0);
}
.control__tier[aria-pressed='true']:hover:not(:disabled) {
  /* Stay filled-white-on-black even when the cursor is over the active
     tier; otherwise the hover rule above would un-fill it on revisit. */
  background: var(--fg-0);
  color: var(--bg-0);
}

/* Nav row */
.panel__nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 18px;
  border-bottom: 1px solid var(--line-1);
  background: oklch(0.2 0.01 250 / 0.5);
}

.panel__nav-hint {
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--fg-3);
}

.navbtn {
  display: grid;
  place-items: center;
  width: 32px;
  height: 28px;
  border-radius: var(--radius-1);
  background: var(--bg-2);
  border: 1px solid var(--line-1);
  color: var(--fg-1);
  transition:
    background 140ms var(--ease),
    color 140ms var(--ease),
    border-color 140ms var(--ease);
}

.navbtn:hover:not(:disabled) {
  background: var(--bg-3);
  color: var(--fg-0);
  border-color: var(--accent-line);
}

.navbtn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

/* Skin list — vertical scrollable */
.skin-list {
  list-style: none;
  margin: 0;
  padding: 6px;
  overflow-y: auto;
  overscroll-behavior: contain;
  flex: 1 1 auto;
  min-height: 0;
}

.skin-list[data-thumbnails-pending='true'] {
  pointer-events: none;
}

.skin-list::-webkit-scrollbar {
  width: 8px;
}
.skin-list::-webkit-scrollbar-track {
  background: transparent;
}
.skin-list::-webkit-scrollbar-thumb {
  background: var(--bg-3);
  border-radius: 4px;
}

/* Skin card (rendered by main.js). Layout: 4px rarity stripe · 96px thumb ·
   name. Selection is signaled by tinted background + green name color. */
.skin-card {
  --skin-rarity-color: var(--line-2);
  display: grid;
  grid-template-columns: 4px 130px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 76px;
  padding: 8px 8px;
  margin: 0;
  border-radius: 4px;
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
  position: relative;
  transition: background 120ms var(--ease);
}

.skin-card::before {
  content: '';
  grid-column: 1;
  width: 4px;
  height: 64px;
  border-radius: 1px;
  background: var(--skin-rarity-color);
  align-self: center;
  justify-self: start;
}

.skin-card[data-rarity='common'] {
  --skin-rarity-color: #b0c3d9;
}
.skin-card[data-rarity='uncommon'] {
  --skin-rarity-color: #5e98d9;
}
.skin-card[data-rarity='rare'] {
  --skin-rarity-color: #4b69ff;
}
.skin-card[data-rarity='mythical'] {
  --skin-rarity-color: #8847ff;
}
.skin-card[data-rarity='legendary'] {
  --skin-rarity-color: #d32ce6;
}
.skin-card[data-rarity='ancient'] {
  --skin-rarity-color: #eb4b4b;
}
.skin-card[data-rarity='immortal'] {
  --skin-rarity-color: #e4ae39;
}
.skin-card[data-rarity='contraband'] {
  --skin-rarity-color: #e4ae39;
}

.skin-card > span:nth-child(2) {
  min-width: 0;
}

/* Case/collection icon, right-aligned on each skin card. */
.skin-card__collection-icon {
  grid-column: 4;
  width: 54px;
  height: 54px;
  margin-right: 4px;
  object-fit: contain;
  opacity: 0.92;
  justify-self: end;
}

.skin-card:hover {
  background: oklch(0.24 0.012 250 / 0.5);
}

.skin-card[aria-selected='true'] {
  background: var(--accent-soft);
}

.skin-card[aria-selected='true'] .skin-card__name {
  color: var(--fg-0);
}

.skin-card[aria-selected='true'] .skin-card__sub {
  color: var(--fg-1);
}

.skin-card.is-loading {
  outline: 1px dashed var(--accent-line);
  outline-offset: -1px;
  animation: card-pulse 1.4s ease-in-out infinite;
}

@keyframes card-pulse {
  0%,
  100% {
    opacity: 0.4;
  }
  50% {
    opacity: 1;
  }
}

.skin-card__preview {
  position: relative;
  display: block;
  width: 130px;
  height: 84px;
  contain: layout paint;
  overflow: hidden;
  background-repeat: no-repeat;
}

.skin-card__preview-img {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
}

.skin-card__preview.is-loaded .skin-card__preview-img {
  opacity: 1;
}

.skin-card__preview.is-atlas-loaded .skin-card__preview-img {
  display: none;
}

/* Two-line label cell: skin name on top, "{collection} · {rarity}" sub
   below it. Stacked in a column so the rarity stripe + thumbnail still
   align with the visual midline of the text block. */
.skin-card__label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.skin-card__name {
  font-size: 14px;
  font-weight: 600;
  color: var(--fg-0);
  letter-spacing: -0.005em;
  line-height: 1.25;
  white-space: normal;
  overflow-wrap: anywhere;
}
.skin-card__sub {
  font-size: 11.5px;
  color: var(--fg-3);
  line-height: 1.3;
  letter-spacing: 0.01em;
}

/* =========================================================================
   noscript fallback
   ========================================================================= */

.noscript {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 24px;
  background: var(--bg-0);
  color: var(--fg-1);
  z-index: 100;
}

/* =========================================================================
   Responsive — narrow screens
   ========================================================================= */

/* Mobile engages on narrow viewports AND on short coarse-pointer screens
   (large phones in landscape report >900px wide but <600px tall — without
   the second condition they'd fall back to the desktop dock). */
@media (max-width: 900px), (max-height: 600px) and (pointer: coarse) {
  :root {
    --nav-h: 88px;
    --side-w: 0px;
    --right-panel-w: 0px;
    /* Persistent bottom dock height (tab bar). The viewport and sheets
       anchor above it; the home-indicator inset is added on top. */
    --dock-h: 56px;
    /* Top class/weapon bars are too cramped on phones — hide them and
       reclaim the screen for the viewport. Weapon selection happens
       inside the bottom-sheet picker instead (the in-panel
       .weapon-picker is unhidden below). */
    --classbar-h: 0px;
    --wepbar-h: 0px;
  }

  /* ── Clean-mode mobile overrides ──────────────────────────────────────
     On desktop, clean mode uses a 380px left-docked command bar with inline
     accordion panels. On mobile (≤900px) that dock is too wide, so hide it
     and restore the native bottom-sheet + FAB launcher system. The panels
     must not be hidden so the sheet can slide them in via translateY. */
  html.is-clean .clean-bar,
  html.is-clean .clean-pop-backdrop {
    display: none !important;
  }
  /* The 3D viewport fills the screen between the nav and the bottom dock
     (plus the home-indicator inset on notched phones). */
  html.is-clean .viewport,
  html.is-clean .viewport-vignette,
  html.is-clean .viewport-loading {
    top: var(--topbars-h);
    left: 0;
    right: 0;
    bottom: calc(var(--dock-h) + env(safe-area-inset-bottom));
  }
  /* Undo desktop panel hiding for the active sheet. */
  html.is-clean body:not([data-mode='craft']) #skin-panel.panel--picker:not(.is-clean-pop),
  html.is-clean body[data-mode='craft'] #craft-panel:not(.is-clean-pop) {
    display: flex !important;
  }

  /* Restore wear/pattern controls inside the skin panel — clean mode hides
     them on desktop because they live in the dock's paint section, but on
     mobile the dock doesn't exist so the panel keeps its own controls. */
  html.is-clean #skin-panel .panel__controls {
    display: block;
  }

  /* Restore normal nav styling — clean mode's grid-template-columns override
     is too specific and breaks the mobile two-row nav. */
  html.is-clean .nav {
    grid-template-columns: auto minmax(0, 1fr);
    background: oklch(0.12 0.01 252 / 0.92);
    backdrop-filter: blur(18px) saturate(140%);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    border-bottom: 1px solid var(--line-1);
    pointer-events: auto;
  }
  /* Background picker: reset to mobile position (top-left, below nav). */
  html.is-clean .background-picker {
    top: calc(var(--nav-h) + 58px);
    bottom: auto;
    left: 12px;
  }

  .classbar,
  .wepbar,
  .viewport-loadout {
    display: none !important;
  }
  /* Restore the in-panel weapon picker so the bottom-sheet has a way to
     switch weapons. The .panel__head also comes back so users see the
     active skin name + preview thumbnail at the top of the sheet. */
  .weapon-picker {
    display: block;
  }
  .panel__head {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 16px;
    padding: 16px 18px 14px;
    border-bottom: 1px solid var(--line-1);
    background: linear-gradient(180deg, oklch(0.22 0.01 250 / 0.55), transparent);
  }
  /* Keep the explicit In-game / Model toggle discoverable above the canvas. */
  .view-tabs {
    display: inline-flex;
    top: calc(var(--nav-h) + 10px);
    left: 50%;
    transform: translateX(-50%);
  }
  .model-panel-tabs {
    display: none !important;
  }
  .background-picker {
    top: calc(var(--nav-h) + 58px);
    left: 12px;
    max-width: calc(100vw - 24px);
  }
  .panel--picker {
    top: auto;
    left: 12px;
    right: 12px;
    bottom: 10px;
    width: auto;
    max-height: 45vh;
    max-height: min(45svh, 360px);
    background: oklch(0.18 0.008 250 / 0.92);
    backdrop-filter: blur(18px) saturate(140%);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    border: 1px solid var(--line-1);
    border-radius: var(--radius-3);
    box-shadow: var(--shadow-3);
  }
  .nav {
    grid-template-columns: 1fr;
    grid-template-areas:
      'brand'
      'links';
    column-gap: 8px;
    row-gap: 6px;
    height: auto;
    padding: 8px 12px 9px;
  }
  .brand {
    grid-area: brand;
    padding-left: 0;
  }
  .brand__lockup {
    height: 28px;
  }
  .controls-helper {
    display: none !important;
  }
  .panel {
    width: calc(100vw - 24px);
    max-height: 45vh;
    max-height: min(45svh, 360px);
  }
  .rail {
    display: none;
  }
  /* On mobile the picker and craft panels become true bottom
     sheets — full-width, anchored just above the dock, sliding up via
     translateY. The dock stays layered on top so users can switch between
     sheets directly without closing first.
     The !important markers on position/width/inset preserve this geometry
     against the base panel rules later in the file. */
  .craft-panel,
  .panel--picker {
    position: fixed !important;
    left: 0 !important;
    right: 0 !important;
    bottom: var(--dock-h) !important;
    top: auto !important;
    width: auto !important;
    max-width: none;
    /* Cap the sheet so the gun stays visible above it. */
    max-height: min(68svh, calc(100svh - var(--topbars-h) - var(--dock-h) - 12px));
    border: 0;
    border-top: 1px solid var(--line-2);
    border-radius: 20px 20px 0 0;
    background: oklch(0.165 0.009 250 / 0.97);
    backdrop-filter: blur(22px) saturate(150%);
    -webkit-backdrop-filter: blur(22px) saturate(150%);
    box-shadow:
      0 -1px 0 oklch(1 0 0 / 0.05) inset,
      0 -18px 50px oklch(0 0 0 / 0.55);
    transform: translateY(calc(100% + var(--dock-h)));
    transition: transform 300ms var(--ease);
    z-index: 60 !important;
    overflow-y: auto !important;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    will-change: transform;
  }
  /* The craft sheet is shorter so more of the gun stays visible. */
  .craft-panel {
    max-height: min(56svh, calc(100svh - var(--topbars-h) - var(--dock-h) - 12px));
  }
  /* Children stay at their natural size — flex shrinking would compress
     the top sections to nothing on tall content (the picker has 5+ stacked
     sections), leaving the user with an unscrollable list. */
  .craft-panel > *,
  .panel--picker > * {
    flex-shrink: 0;
  }
  /* Disable internal scroll containers; the outer sheet scrolls instead. */
  .panel--picker .skin-list {
    overflow: visible;
    flex: 0 0 auto;
    max-height: none;
    min-height: 0;
  }
  /* Weapon view: the desktop clean-mode rules make #weapon-picker a
     flex:1 1 auto column with its OWN inner scroll (.weapon-picker__models--rows
     is overflow-y:auto). That inner-scroll model collapses to zero height in
     iOS Safari/WebKit when the sheet's height is only max-height-capped
     (indefinite), so the weapon list vanishes — "can't see weapon options".
     Blink fills it, so it only breaks on iPhone. Match the skin list above:
     natural height, let the OUTER sheet scroll. Same selector prefix as the
     clean-mode rules so source order (this @media is later) wins. */
  html.is-clean #skin-panel[data-view='weapon'] #weapon-picker {
    flex: 0 0 auto;
    overflow: visible;
  }
  html.is-clean #skin-panel[data-view='weapon'] .weapon-picker__models--rows {
    flex: 0 0 auto;
    overflow: visible;
    max-height: none;
  }
  .craft-panel .craft-panel__cols {
    flex: 0 0 auto;
    min-height: 0;
  }
  .craft-panel .craft-panel__grid {
    overflow: visible;
    max-height: none;
  }
  .craft-panel .craft-panel__placed {
    overflow: visible;
    max-height: none;
    flex: 0 0 auto;
  }
  /* Open state — set by JS via data-sheet-open. */
  .craft-panel[data-sheet-open='true'],
  .panel--picker[data-sheet-open='true'] {
    transform: translateY(0);
  }
  /* Mode-scoped visibility: skin in inspect, stickers in craft. */
  body[data-mode='craft'] .panel--picker {
    display: none !important;
  }
  body:not([data-mode='craft']) .craft-panel {
    display: none !important;
  }

  /* Picker layout tweaks for the bottom sheet form factor. The desktop
     left-column had room for a 124×78 preview tile; on mobile that just
     crowds the title, so hide it and let the title stretch. */
  .panel--picker .panel__preview {
    display: none;
  }
  .panel--picker .panel__head {
    grid-template-columns: 1fr;
    padding: 12px 14px 10px;
  }
  .panel--picker .panel__name {
    font-size: 16px;
  }
  .panel--picker .weapon-picker {
    padding: 10px 14px 8px;
  }
  .panel--picker .panel__controls {
    padding: 8px 14px;
  }
  .panel--picker .panel__search {
    padding: 8px 14px;
  }
  .panel--picker .panel__nav {
    padding: 4px 14px;
  }
  .panel--picker .skin-list {
    /* The sheet has its own scroll on .skin-list; cap the row size so the
       internal scroll still has room when the head + controls take the top. */
    padding: 4px 8px;
  }
}

/* =========================================================================
   Mobile bottom-sheet chrome — drag handle, backdrop, launcher FAB.
   All three are display:none on desktop; the @media block below switches
   them on at <=900px.
   ========================================================================= */

.sheet-handle {
  display: none;
}
.panel-backdrop {
  display: none;
}
.mobile-dock {
  display: none;
}

@media (max-width: 900px), (max-height: 600px) and (pointer: coarse) {
  /* Drag handle bar — first child of each sheet, rendered as a centered
     pill. Pointer-down on it starts a vertical drag that closes the sheet
     past a threshold; touch-action:none stops the browser from claiming
     the gesture for page scroll. */
  .sheet-handle {
    display: flex;
    flex: 0 0 auto;
    height: 26px;
    align-items: center;
    justify-content: center;
    cursor: grab;
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
  }
  .sheet-handle::before {
    content: '';
    width: 38px;
    height: 4px;
    border-radius: 999px;
    background: oklch(0.5 0.014 250 / 0.7);
    transition:
      background 160ms ease,
      width 160ms var(--ease);
  }
  .sheet-handle:active::before {
    background: oklch(0.68 0.02 250);
    width: 52px;
    cursor: grabbing;
  }

  /* Backdrop — a soft top-down dim over the gun while a sheet is open. Tap
     anywhere to close. Lighter at the top (the gun stays legible) and
     deeper toward the sheet so the seam reads as depth, not a flat curtain. */
  .panel-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: linear-gradient(to bottom, oklch(0 0 0 / 0.04) 0%, oklch(0 0 0 / 0.32) 100%);
    z-index: 55;
    opacity: 0;
    pointer-events: none;
    transition: opacity 260ms var(--ease);
  }
  .panel-backdrop[data-open='true'] {
    opacity: 1;
    pointer-events: auto;
  }
  /* In craft mode the catalog sheet floats over a still-interactive model so
     the user can tap the gun to place stickers while browsing. No backdrop —
     drag-to-close or the dock dismiss it instead. */
  body[data-mode='craft'] .panel-backdrop {
    display: none;
  }

  /* Bottom dock — two equal tabs that launch their sheets. Frosted bar
     pinned to the bottom edge with a home-indicator safe-area inset; sits
     above the sheets (z) so users can switch sheets without closing. */
  .mobile-dock {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 70;
    height: calc(var(--dock-h) + env(safe-area-inset-bottom));
    padding-bottom: env(safe-area-inset-bottom);
    background: oklch(0.13 0.009 250 / 0.92);
    backdrop-filter: blur(24px) saturate(150%);
    -webkit-backdrop-filter: blur(24px) saturate(150%);
    border-top: 1px solid var(--line-1);
    box-shadow: 0 -8px 24px oklch(0 0 0 / 0.35);
  }
  .mobile-dock__tab {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-height: 44px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--fg-2);
    font-family: var(--font-ui);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: color 180ms var(--ease);
  }
  .mobile-dock__ic {
    transition: transform 220ms var(--ease);
  }
  .mobile-dock__tab:active .mobile-dock__ic {
    transform: scale(0.86);
  }
  /* Active (open-sheet) tab lifts to the accent color with a soft glow. */
  .mobile-dock__tab.is-active {
    color: var(--accent);
  }
  .mobile-dock__tab.is-active .mobile-dock__ic {
    filter: drop-shadow(0 0 10px var(--accent-glow));
  }

  /* Sheets are flex columns so the drag handle pins to the top and content
     flows below it. */
  .craft-panel,
  .panel--picker {
    display: flex !important;
    flex-direction: column;
  }
  body[data-mode='craft'] .panel--picker {
    display: none !important;
  }
  body:not([data-mode='craft']) .craft-panel {
    display: none !important;
  }
}

/* =========================================================================
   Mobile landscape — switch the sheets from bottom-anchored to a side
   sheet on the right. Phone-landscape has tight vertical space (≤430px),
   so a 70svh bottom sheet would leave only ~120px for the gun viewport
   above. Side sheets keep the gun visible on the left half while the
   sheet uses the right half.
   ========================================================================= */

@media (max-width: 900px) and (orientation: landscape),
  (max-height: 600px) and (orientation: landscape) {
  .craft-panel,
  .panel--picker {
    /* Reset bottom-anchor → right-anchor; clear the bottom dock. */
    top: 0 !important;
    bottom: var(--dock-h) !important;
    left: auto !important;
    right: 0 !important;
    width: clamp(320px, 58vw, 460px) !important;
    max-width: none;
    max-height: none;
    border-top: 0;
    border-left: 1px solid var(--line-2);
    border-radius: 20px 0 0 0;
    box-shadow:
      -1px 0 0 oklch(1 0 0 / 0.05) inset,
      -18px 0 50px oklch(0 0 0 / 0.55);
    transform: translateX(100%);
  }
  .craft-panel[data-sheet-open='true'],
  .panel--picker[data-sheet-open='true'] {
    transform: translateX(0);
  }
  /* Drag handle shifts to a vertical bar on the LEFT edge — that's the
     edge the user grabs to swipe the sheet back off-screen. */
  .craft-panel .sheet-handle,
  .panel--picker .sheet-handle {
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    height: auto;
    width: 22px;
    z-index: 1;
  }
  .craft-panel .sheet-handle::before,
  .panel--picker .sheet-handle::before {
    width: 4px;
    height: 44px;
  }
  .craft-panel .sheet-handle:active::before,
  .panel--picker .sheet-handle:active::before {
    width: 4px;
    height: 60px;
  }
  /* Make room on the left edge of the sheet content so the vertical
     handle doesn't overlap the panel header. */
  .craft-panel > :not(.sheet-handle):first-of-type,
  .panel--picker > :not(.sheet-handle):first-of-type,
  .craft-panel .craft-panel__head,
  .panel--picker .panel__head {
    padding-left: 26px;
  }
}

/* --- Sticker Craft mode -------------------------------------------------- */

/* Body data-mode swap. In craft mode the only things that change are:
     1. How the model is rendered (side profile, see main.js)
     2. The sticker panel appears on the right
   Skin/weapon selection (left sidebar), the rail, and the view tabs all stay
   live so the user can keep configuring the model without leaving sticker
   mode. We hide the keyboard-shortcut helper because it lives in the same
   top-right slot as the craft panel. */
/* Helpers are mode-scoped via data-when-mode. Show only the matching one. */
.controls-helper[data-when-mode='craft'] {
  display: none;
}
body[data-mode='craft'] .controls-helper[data-when-mode='inspect'] {
  display: none;
}
body[data-mode='craft'] .controls-helper[data-when-mode='craft'] {
  display: flex;
}
/* Touch (coarse pointer): hide both helpers. The desktop hints (Ctrl,
   Scroll, kbd shortcuts) don't apply on touch, and the panel-side controls
   are self-explanatory. */
@media (pointer: coarse) {
  .controls-helper,
  body[data-mode='craft'] .controls-helper[data-when-mode='craft'] {
    display: none !important;
  }
}
body[data-mode='craft'] #craft-panel {
  display: flex !important;
}
body:not([data-mode='craft']) #craft-panel {
  display: none !important;
}

body.sticker-brushing .viewport canvas {
  cursor: crosshair;
}

.sticker-cursor {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 9999;
  width: 42px;
  height: 42px;
  margin-left: 14px;
  margin-top: 14px;
  pointer-events: none;
  display: none;
  opacity: 0.92;
  filter: drop-shadow(0 3px 8px rgba(0, 0, 0, 0.68));
}

.sticker-cursor.is-active {
  display: block;
}

@media (pointer: coarse) {
  .sticker-cursor,
  .sticker-cursor.is-active {
    display: none !important;
  }
}

.sticker-cursor img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.craft-panel {
  position: fixed;
  /* The craft panel occupies the right-side control column. */
  right: 0;
  top: var(--topbars-h);
  bottom: 0;
  z-index: 10;
  width: var(--right-panel-w);
  display: flex;
  flex-direction: column;
  background: oklch(0.18 0.008 250 / 0.92);
  border-left: 1px solid var(--line-1);
  color: var(--fg-1);
  overflow: hidden;
}

/* Craft mode needs more room for the sticker grid + placed-stickers list +
   per-row controls. Widen ONLY the panel (not --right-panel-w on the body),
   so the viewport keeps its 340px right offset and the panel overlays the
   extra ~140px on top — the gun stays the same size and just gets occluded
   by the panel rather than reflowing behind it. */
body[data-mode='craft'] .craft-panel {
  width: 480px;
}
.craft-panel__head {
  padding: 14px 16px 10px;
  border-bottom: 1px solid var(--line-1);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.craft-panel__title-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}
.craft-panel__title {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.craft-panel__title-actions {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
/* Stickers / Charms segmented toggle — sits on its own row in the menu header. */
.craft-panel__modes {
  align-self: flex-start;
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  border-radius: 999px;
  border: 1px solid var(--line-1);
  background: var(--bg-2);
}
.craft-panel__mode {
  appearance: none;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: -0.01em;
  padding: 6px 14px;
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  color: var(--fg-2);
  background: transparent;
  transition:
    background 140ms ease,
    color 140ms ease;
}
.craft-panel__mode:hover {
  color: var(--fg-0);
}
.craft-panel__mode.is-active {
  color: #fff;
  background: var(--accent, #4a87ff);
}
.craft-panel__mode:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.craft-panel__grid-item--none {
  align-items: center;
  justify-content: center;
  min-height: 64px;
  color: var(--fg-2);
  font-weight: 600;
}
/* Charm-pattern mode: the command dock's seed slider edits the charm pattern,
   so hide the gun-only controls (float tiers, the wear row, StatTrak). */
body.charm-seed-mode #skin-float-tiers {
  display: none !important;
}
body.charm-seed-mode .cb-stattrak {
  display: none !important;
}
body.charm-seed-mode .cb-live-row:has(#cb-live-wear) {
  display: none !important;
}

/* "Click the weapon to place the charm" hint, shown in charm mode. */
.craft-panel__charm-hint {
  margin: 0;
  padding: 0 16px 8px;
  font-size: 12px;
  font-weight: 500;
  color: var(--accent, #4a87ff);
}

/* Sticker-slab "Sticker in slab: <name> [Choose sticker]" control. The
   :not([hidden]) guard keeps the `display:flex` from overriding the hidden
   attribute (a bare class selector would beat the UA [hidden] rule). */
.craft-panel__slab:not([hidden]) {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 16px 8px;
  padding: 8px 10px;
  border: 1px solid var(--line-1);
  border-radius: var(--radius-2, 8px);
  background: var(--bg-2);
  font-size: 12px;
}
.craft-panel__slab-label {
  font-weight: 700;
  color: var(--fg-2);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: 11px;
}
.craft-panel__slab-current {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--fg-0);
  font-weight: 600;
}
.craft-panel__slab-choose {
  flex: none;
  appearance: none;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 5px 11px;
  border-radius: 999px;
  cursor: pointer;
  color: #fff;
  border: 1px solid var(--accent-line, var(--accent, #4a87ff));
  background: var(--accent, #4a87ff);
}
.craft-panel__slab-choose:hover {
  filter: brightness(1.08);
}
/* Back bar shown while picking a sticker for the slab. */
.craft-panel__slab-bar:not([hidden]) {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 16px 8px;
}
.craft-panel__slab-back {
  appearance: none;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 5px 11px;
  border-radius: 999px;
  cursor: pointer;
  color: var(--fg-1);
  border: 1px solid var(--line-1);
  background: var(--bg-2);
}
.craft-panel__slab-back:hover {
  background: var(--bg-3, #2c3342);
}
.craft-panel__slab-bar-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--fg-2);
}
.craft-panel__reset {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  appearance: none;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
  padding: 7px 12px;
  border-radius: 999px;
  cursor: pointer;
  color: var(--fg-2);
  border: 1px solid var(--line-1);
  background: var(--bg-2);
  transition:
    background 140ms ease,
    border-color 140ms ease,
    color 140ms ease,
    transform 120ms ease,
    opacity 140ms ease;
}
.craft-panel__reset-icon {
  flex: none;
}
.craft-panel__reset:hover:not(:disabled) {
  color: oklch(0.78 0.16 25);
  border-color: color-mix(in oklab, oklch(0.7 0.2 25) 50%, var(--line-1));
  background: color-mix(in oklab, oklch(0.7 0.2 25) 12%, var(--bg-2));
}
.craft-panel__reset:active:not(:disabled) {
  transform: translateY(1px);
}
.craft-panel__reset:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.craft-panel__reset:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.craft-panel__eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 10px;
  color: var(--fg-3);
}
.craft-panel__name {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--fg-0);
}
.craft-panel__brush {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 6px 8px;
  padding: 6px 10px;
  border-radius: var(--radius-1);
  background: oklch(0.22 0.01 250 / 0.9);
  border: 1px solid var(--line-1);
  font-size: 12px;
  min-width: 0;
}
.craft-panel__brush[data-empty='true'] {
  opacity: 0.6;
}
.craft-panel__brush-label {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 10px;
  color: var(--fg-3);
  flex: 0 0 auto;
}
.craft-panel__brush-name {
  color: var(--fg-0);
  font-weight: 500;
  flex: 1 1 auto;
  min-width: 0;
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Rotation row inside the brush card spans the whole row underneath the
   label/name pair, so the slider gets enough horizontal space on narrow
   panels (mobile) without crowding the brush name. */
.craft-panel__brush-rot {
  flex: 1 0 100%;
  border-top: 1px solid var(--line-1);
  padding-top: 6px;
}
.craft-panel__brush[data-empty='true'] .craft-panel__brush-rot {
  display: none;
}

.craft-panel__search {
  padding: 10px 16px;
  border-bottom: 1px solid var(--line-1);
}
.craft-panel__search-input {
  width: 100%;
  background: oklch(0.14 0.008 250 / 0.9);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-1);
  color: var(--fg-1);
  padding: 6px 10px;
  font: inherit;
  font-size: 13px;
}
.craft-panel__search-input:focus {
  outline: 1px solid var(--accent, #5cf);
}

.craft-panel__cols {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
}
.craft-panel__collections {
  width: 190px;
  flex: 0 0 auto;
  border-right: 1px solid var(--line-soft);
  overflow: hidden auto;
  padding: 6px 4px;
}
.craft-panel__col-btn {
  display: block;
  width: auto;
  margin: 1px 0;
  text-align: left;
  background: transparent;
  border: 0;
  border-radius: var(--radius-1);
  color: var(--fg-2);
  font: inherit;
  font-size: 12px;
  line-height: 1.3;
  padding: 7px 10px;
  cursor: pointer;
  /* Capsule names are long ("Half-Life: Alyx Sticker Capsule") — wrap instead
     of truncating. */
  white-space: normal;
  overflow-wrap: anywhere;
  transition:
    background 140ms var(--ease),
    color 140ms var(--ease);
}
.craft-panel__col-btn:hover {
  color: var(--fg-0);
  background: var(--bg-2);
}
.craft-panel__col-btn[aria-pressed='true'] {
  color: var(--fg-0);
  background: var(--accent-soft);
}

.craft-panel__main {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.craft-panel__finish-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line-1);
}
.craft-panel__finish-btn {
  flex: 0 0 auto;
  background: var(--bg-2);
  border: 0;
  border-radius: 999px;
  color: var(--fg-2);
  padding: 5px 12px;
  font-size: 11.5px;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background 160ms var(--ease),
    color 160ms var(--ease);
}
.craft-panel__finish-btn:hover:not(:disabled) {
  color: var(--fg-0);
  background: var(--bg-3);
}
.craft-panel__finish-btn:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}
.craft-panel__finish-btn[aria-checked='true'] {
  color: var(--accent-button-fg);
  background: var(--accent-button-bg);
}

.craft-panel__slot-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--line-1);
}
.craft-panel__slot-label {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 10px;
  color: var(--fg-3);
  margin-right: 2px;
}
.craft-panel__slot-btn {
  flex: 0 0 auto;
  position: relative;
  min-width: 28px;
  background: var(--bg-2);
  border: 1px solid var(--line-1);
  border-radius: 999px;
  color: var(--fg-2);
  padding: 4px 11px;
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background 160ms var(--ease),
    color 160ms var(--ease),
    border-color 160ms var(--ease);
}
.craft-panel__slot-btn:hover:not(:disabled) {
  color: var(--fg-0);
  background: var(--bg-3);
  border-color: var(--accent-line);
}
.craft-panel__slot-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
/* Filled slots get an accent dot so the user can see which defaults are taken. */
.craft-panel__slot-btn.is-filled {
  color: var(--fg-0);
  border-color: var(--accent-line);
  background: var(--accent-soft);
}
.craft-panel__slot-btn.is-filled::after {
  content: '';
  position: absolute;
  top: 3px;
  right: 3px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
}

.craft-panel__grid {
  flex: 1 1 auto;
  overflow: hidden auto;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  padding: 10px;
  margin: 0;
  list-style: none;
}
.craft-panel__grid-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  padding: 8px;
  border-radius: var(--radius-2);
  background: var(--bg-1);
  border: 1px solid transparent;
  cursor: pointer;
  transition:
    background 160ms var(--ease),
    border-color 160ms var(--ease),
    transform 160ms var(--ease);
  min-width: 0;
}
.craft-panel__grid-item:hover {
  border-color: var(--line-1);
  background: var(--bg-2);
  transform: translateY(-1px);
}
.craft-panel__grid-item:active {
  transform: scale(0.98);
}
.craft-panel__grid-item[aria-selected='true'] {
  border-color: var(--accent-line, var(--accent));
  background: var(--accent-soft);
}
.craft-panel__grid-item img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  background: transparent;
}
.craft-panel__grid-name {
  font-size: 11px;
  color: var(--fg-1);
  text-align: center;
  line-height: 1.25;
  max-width: 100%;
  /* Names like "3DMAX | Katowice 2014" are long — wrap to two lines instead
     of truncating. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.craft-panel__grid-empty {
  grid-column: 1 / -1;
  text-align: center;
  color: var(--fg-3);
  font-size: 12px;
  padding: 24px 8px;
}

/* Charms render as a single-column list of horizontal cards, like the skin
   browser: a thin rarity-coloured stripe down the LEFT edge · small icon · a
   two-line label (name + "collection · rarity"). Colour comes from the inline
   --charm-rarity-color; the data-rarity palette is a fallback. */
.craft-panel__grid--charms {
  grid-template-columns: 1fr;
  gap: 5px;
  /* Dark, thin scrollbar to match the skin list — never the OS light bar. */
  scrollbar-width: thin;
  scrollbar-color: var(--bg-3) transparent;
}
.craft-panel__grid--charms::-webkit-scrollbar {
  width: 8px;
}
.craft-panel__grid--charms::-webkit-scrollbar-track {
  background: transparent;
}
.craft-panel__grid--charms::-webkit-scrollbar-thumb {
  background: var(--bg-3);
  border-radius: 4px;
}
.craft-panel__grid-item--charm {
  --charm-rarity-color: var(--line-2);
  position: relative;
  overflow: hidden;
  flex-direction: row;
  align-items: center;
  gap: 14px;
  padding: 12px 14px 12px 18px;
  min-height: 76px;
  text-align: left;
}
.craft-panel__grid-item--charm::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 3px;
  background: var(--charm-rarity-color);
}
.craft-panel__grid-item--charm[data-rarity='common'] {
  --charm-rarity-color: #b0c3d9;
}
.craft-panel__grid-item--charm[data-rarity='uncommon'] {
  --charm-rarity-color: #5e98d9;
}
.craft-panel__grid-item--charm[data-rarity='rare'] {
  --charm-rarity-color: #4b69ff;
}
.craft-panel__grid-item--charm[data-rarity='mythical'] {
  --charm-rarity-color: #8847ff;
}
.craft-panel__grid-item--charm[data-rarity='legendary'] {
  --charm-rarity-color: #d32ce6;
}
.craft-panel__grid-item--charm[data-rarity='ancient'] {
  --charm-rarity-color: #eb4b4b;
}
.craft-panel__grid-item--charm[data-rarity='immortal'],
.craft-panel__grid-item--charm[data-rarity='contraband'] {
  --charm-rarity-color: #e4ae39;
}
/* Fixed-size icon — override the 2-col grid's full-width square thumb. High
   specificity + min-width so the long labels can't flex-shrink it (which, with
   aspect-ratio:1/1, would drag the height down and collapse the whole row). */
.craft-panel__grid--charms .craft-panel__grid-item--charm img {
  width: 64px;
  height: 64px;
  min-width: 64px;
  aspect-ratio: 1 / 1;
  flex: 0 0 auto;
  object-fit: contain;
}
.craft-panel__charm-label {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  flex: 1 1 auto;
}
.craft-panel__grid-item--charm .craft-panel__grid-name {
  text-align: left;
  font-size: 14px;
  font-weight: 600;
  -webkit-line-clamp: 2;
  color: var(--fg-0);
}
.craft-panel__grid-sub {
  font-size: 12px;
  font-weight: 600;
  line-height: 1.2;
  text-align: left;
  color: var(--charm-rarity-color);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* The "None" row spans the single column and stays centred. */
.craft-panel__grid--charms .craft-panel__grid-item--none {
  justify-content: center;
  min-height: 52px;
}

.craft-panel__placed {
  border-top: 1px solid var(--line-1);
  padding: 10px 16px 12px;
  flex: 0 0 auto;
  max-height: 35%;
  overflow: hidden auto;
}
.craft-panel__placed-title {
  margin: 0 0 8px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--fg-3);
}
.craft-panel__placed-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.craft-panel__placed-empty {
  color: var(--fg-3);
  font-size: 12px;
  font-style: italic;
}
.craft-panel__placed-item {
  background: oklch(0.16 0.008 250 / 0.7);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-2);
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.craft-panel__placed-head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
}
.craft-panel__placed-name {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--fg-0);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.craft-panel__placed-finish {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-3);
}
.craft-panel__placed-delete {
  background: transparent;
  border: 0;
  color: var(--fg-3);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}
.craft-panel__placed-delete:hover {
  color: #f55;
}
.craft-panel__placed-slider {
  display: grid;
  grid-template-columns: 50px 1fr 46px;
  align-items: center;
  gap: 10px;
  font-size: 11px;
}
.craft-panel__placed-slider label {
  color: var(--fg-2);
  font-family: var(--font-mono);
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.craft-panel__placed-slider input {
  width: 100%;
}
.craft-panel__placed-slider output {
  font-family: var(--font-mono, monospace);
  color: var(--fg-1);
  text-align: right;
}

/* Style the range inputs in the craft panel (placed-sticker wear/rotation
   sliders + the brush rotation slider in the header). Default browser
   ranges render as light-grey/blue native widgets that look out of place
   against the dark panel. */
.craft-panel__placed-slider input[type='range'] {
  -webkit-appearance: none;
  appearance: none;
  height: 20px;
  background: transparent;
  cursor: pointer;
  padding: 0;
  margin: 0;
}
.craft-panel__placed-slider input[type='range']::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 999px;
  background: var(--line-1);
}
.craft-panel__placed-slider input[type='range']::-moz-range-track {
  height: 4px;
  border-radius: 999px;
  border: 0;
  background: var(--line-1);
}
.craft-panel__placed-slider input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  margin-top: -7px;
  border-radius: 50%;
  background: var(--fg-0);
  border: 2px solid var(--bg-0);
  box-shadow:
    0 0 0 1px var(--line-2, var(--line-1)),
    0 2px 6px oklch(0 0 0 / 0.45);
}
.craft-panel__placed-slider input[type='range']::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--fg-0);
  border: 2px solid var(--bg-0);
  box-shadow:
    0 0 0 1px var(--line-2, var(--line-1)),
    0 2px 6px oklch(0 0 0 / 0.45);
}
.craft-panel__placed-slider input[type='range']:focus-visible {
  outline: 2px solid var(--accent, oklch(0.78 0.18 250));
  outline-offset: 2px;
}

/* ── Floating per-sticker editor (wear / rotate / remove) ───────────────────
   Opened by clicking a sticker on the model or when one is placed. Centered
   over the page with a dimming backdrop; sliders reuse .craft-panel__placed-
   slider styling above. */
.sticker-editor-backdrop {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: oklch(0 0 0 / 0.4);
}
.sticker-editor-backdrop[hidden] {
  display: none;
}
.sticker-editor {
  position: fixed;
  z-index: 91;
  left: 50%;
  bottom: 28px;
  top: auto;
  transform: translateX(-50%);
  width: min(360px, calc(100vw - 32px));
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 18px;
  background: var(--bg-1, oklch(0.18 0.008 250));
  border: 1px solid var(--line-1);
  border-radius: var(--radius-3);
  box-shadow: var(--shadow-3);
}
.sticker-editor[hidden] {
  display: none;
}
.sticker-editor__head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line-soft);
}
.sticker-editor__thumb {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  object-fit: contain;
  border-radius: var(--radius-2);
  background: oklch(0.13 0.008 250 / 0.7);
  padding: 4px;
}
.sticker-editor__thumb[hidden] {
  display: none;
}
.sticker-editor__titles {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1 1 auto;
  min-width: 0;
}
.sticker-editor__close {
  align-self: flex-start;
}
.sticker-editor__name {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--fg-0);
}
.sticker-editor__finish {
  font-family: var(--font-mono);
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--fg-2);
}
.sticker-editor__close {
  flex: 0 0 auto;
  background: transparent;
  border: 0;
  color: var(--fg-3);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
}
.sticker-editor__close:hover {
  color: var(--fg-0);
}
.sticker-editor__controls {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.sticker-editor__actions {
  display: flex;
  gap: 8px;
}
.sticker-editor__remove,
.sticker-editor__done {
  appearance: none;
  border-radius: var(--radius-2);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 9px 16px;
  cursor: pointer;
  transition:
    background 160ms var(--ease),
    color 160ms var(--ease),
    border-color 160ms var(--ease);
}
.sticker-editor__remove {
  flex: 0 0 auto;
  border: 1px solid var(--line-1);
  background: transparent;
  color: var(--fg-2);
}
.sticker-editor__remove:hover {
  color: oklch(0.72 0.18 25);
  border-color: oklch(0.72 0.18 25 / 0.6);
}
.sticker-editor__done {
  flex: 1 1 auto;
  border: 0;
  background: var(--accent-button-bg);
  color: var(--accent-button-fg);
}
.sticker-editor__done:hover {
  background: var(--accent-button-hover-bg, var(--accent-button-bg));
}

/* Dark scrollbars match the inspector's skin list and rail. */
.craft-panel__collections,
.craft-panel__grid,
.craft-panel__placed-list {
  scrollbar-width: thin;
  scrollbar-color: var(--bg-3) transparent;
}
.craft-panel__collections::-webkit-scrollbar,
.craft-panel__grid::-webkit-scrollbar,
.craft-panel__placed-list::-webkit-scrollbar {
  width: 8px;
}
.craft-panel__collections::-webkit-scrollbar-track,
.craft-panel__grid::-webkit-scrollbar-track,
.craft-panel__placed-list::-webkit-scrollbar-track {
  background: transparent;
}
.craft-panel__collections::-webkit-scrollbar-thumb,
.craft-panel__grid::-webkit-scrollbar-thumb,
.craft-panel__placed-list::-webkit-scrollbar-thumb {
  background: var(--bg-3);
  border-radius: 4px;
}
