/* ────────────────────────────────────────────────
   POLYMESH · studio.css — the app
   ──────────────────────────────────────────────── */

.studio-body { overflow: hidden; height: 100vh; height: 100svh; }

.shell { display: flex; height: 100%; }

/* ═══════════ RAIL ═══════════ */
.rail {
  width: 68px; flex-shrink: 0;
  display: flex; flex-direction: column; align-items: center;
  padding: 16px 0 14px; gap: 10px;
  background: var(--bg1);
  border-right: 1px solid var(--line);
  z-index: 40;
}
.rail-logo {
  width: 42px; height: 42px; border-radius: var(--r-lg);
  display: flex; align-items: center; justify-content: center;
  background: var(--glass); border: 1px solid var(--line);
  transition: 0.3s;
}
.rail-logo:hover { border-color: rgba(94, 106, 210, 0.55); }

.rail-nav { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.rail-sep { height: 1px; margin: 8px 10px; background: var(--line); }

.rail-btn {
  position: relative;
  width: 46px; height: 46px; border-radius: var(--r-lg);
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-faint);
  transition: all 0.22s var(--ease-out);
}
.rail-btn:hover { color: var(--ink-dim); background: var(--glass-2); }
.rail-btn.active {
  color: var(--on-brand);
  background: var(--brand-soft); box-shadow: inset 0 0 0 1px rgba(94, 106, 210, .55);
}
.rail-btn.active::before {
  content: ''; position: absolute; left: -11px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 22px; border-radius: 0 3px 3px 0;
  background: var(--grad);

}

.rail-tip {
  position: absolute; left: calc(100% + 14px); top: 50%; transform: translateY(-50%) translateX(-6px);
  padding: 7px 13px; border-radius: var(--r-sm); white-space: nowrap;
  background: var(--bg3); border: 1px solid var(--line-2);
  font-size: 12.5px; font-weight: 500; color: var(--ink);
  opacity: 0; pointer-events: none;
  transition: 0.25s var(--ease-out);
  z-index: 60;
}
.rail-btn:hover .rail-tip, .rail-credits:hover .rail-tip, .rail-avatar:hover .rail-tip {
  opacity: 1; transform: translateY(-50%) translateX(0);
}

.rail-bottom { margin-top: auto; display: flex; flex-direction: column; align-items: center; gap: 14px; }
.rail-credits { position: relative; display: flex; align-items: center; justify-content: center; cursor: default; }
.rail-credits b {
  position: absolute; font-size: 8.5px; color: var(--ink-dim); letter-spacing: -0.02em;
}
#creditArc { transition: stroke-dashoffset 0.9s var(--ease-out); }
.rail-avatar {
  position: relative;
  width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #241d59, #0e2f4e);
  border: 1.5px solid var(--line-2);
  color: #fff;   /* the gradient is always dark-ish by design, in both themes */
  font-family: var(--font-display); font-weight: 500; font-size: 13px;
  transition: 0.25s;
}
.rail-avatar:hover, .rail-avatar.active, .rail-avatar.open {
  border-color: rgba(94, 106, 210, 0.55);
}
.rail-avatar.open .rail-tip { opacity: 0; }

/* ── account menu ── */
.acct-menu {
  position: fixed; left: 78px; bottom: 16px; z-index: 120;
  width: 258px;
  padding: 8px;
  border-radius: var(--r-lg);
  background: var(--overlay);
  color: var(--overlay-ink);
  border: 1px solid var(--overlay-line);
  backdrop-filter: blur(20px) saturate(1.3);
  box-shadow: var(--shadow-xl);
  animation: acct-in 0.32s var(--ease-spring);
}
@keyframes acct-in {
  from { opacity: 0; transform: translateY(10px) scale(0.96); }
  to { opacity: 1; transform: none; }
}
.acct-head {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 12px 14px;
}
.acct-av {
  width: 40px; height: 40px; border-radius: var(--r-lg); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-weight: 500; font-size: 14px;
  border: 1px solid var(--line-2);
  color: #fff;   /* avatarGradient() always produces a dark-ish hsl background */
}
.acct-who { min-width: 0; display: flex; flex-direction: column; }
.acct-who b { font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct-who span { font-size: 11.5px; color: var(--ink-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.acct-plan {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin: 0 4px 8px; padding: 9px 11px;
  border-radius: var(--r-sm);
  background: var(--glass);
  border: 1px solid var(--line);
}
.acct-plan-tag {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.18em;
  padding: 4px 9px; border-radius: 6px;
  background: var(--grad); color: #fff;
}
.acct-plan span:last-child { font-size: 10.5px; color: var(--ink-faint); }

.acct-item {
  display: flex; align-items: center; gap: 11px; width: 100%;
  padding: 10px 12px; border-radius: var(--r-sm);
  font-size: 13.5px; font-weight: 500; color: var(--ink-dim);
  transition: 0.18s;
}
.acct-item:hover { background: var(--glass-2); color: var(--ink); }
.acct-item svg { flex-shrink: 0; opacity: 0.8; }
.acct-item.danger { color: var(--err); }
.acct-item.danger:hover { background: var(--err-wash); color: var(--err-ink); }
.acct-sep { height: 1px; margin: 6px 10px; background: var(--line); }

/* ═══════════ STAGE ═══════════
   .stage holds the active tab's view (left) and the permanent Asset Library (right) side by side. */
.stage { flex: 1; min-width: 0; display: flex; overflow: hidden; }
.stage-views { flex: 1; min-width: 0; position: relative; }
.view { position: absolute; inset: 0; display: flex; animation: view-in 0.45s var(--ease-out); }
.view[hidden] { display: none; }
@keyframes view-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* ═══════════ SHARED PANEL (left control column, all tabs) ═══════════ */
.panel {
  width: 330px; flex-shrink: 0;
  display: flex; flex-direction: column;
  border-right: 1px solid var(--line);
  background: var(--bg1);
}
.panel-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px 22px 14px;
}
.panel-head h2 { font-family: var(--font-display); font-size: 20px; font-weight: 510; letter-spacing: -0.024em; }
.panel-scroll { flex: 1; overflow-y: auto; padding: 4px 22px 20px; }

.pgroup { margin-bottom: 24px; }
.plabel {
  display: block;
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.22em;
  color: var(--ink-faint); text-transform: uppercase;
  margin-bottom: 10px;
}
.plabel-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.plabel-row .plabel { margin-bottom: 0; }

.ptext, .pinput {
  width: 100%;
  background: var(--bg1);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  padding: 13px 15px;
  font-size: 14px; line-height: 1.5;
  color: var(--ink);
  resize: vertical;
  transition: border-color 0.25s, box-shadow 0.25s, background 0.25s;
}
.ptext, .pinput { background: var(--glass); border-color: var(--line); }
.ptext::placeholder, .pinput::placeholder { color: var(--ink-faint); }
.ptext:focus, .pinput:focus {
  outline: none;
  border-color: rgba(94, 106, 210, 0.55);
  box-shadow: 0 0 0 3px rgba(94, 106, 210, 0.22);
  background: rgba(94, 106, 210, 0.04);
}

/* segmented control — quality picker, sub-tabs use their own .subtab style below */
/* while a seg's options are still being fetched (3D format lists come from the server), it
   shimmers at its final height so the panel doesn't jump when the buttons arrive */
.seg.skeleton { min-height: 44px; }
.seg {
  display: flex; gap: 4px; padding: 4px;
  background: var(--glass); border: 1px solid var(--line);
  border-radius: 12px;
}
.seg-btn {
  flex: 1;
  padding: 8px 10px; border-radius: var(--r-sm);
  font-size: 13px; font-weight: 500; color: var(--ink-faint);
  transition: 0.22s;
  white-space: nowrap;
}
.seg-btn:hover { color: var(--ink-dim); }
.seg-btn.on {
  color: var(--on-brand);
  background: var(--brand-soft);
  box-shadow: inset 0 0 0 1px rgba(94, 106, 210, 0.45);
}

.panel-foot { padding: 16px 22px 20px; border-top: 1px solid var(--line); }
.gen-btn { width: 100%; justify-content: center; position: relative; overflow: hidden; }
.gen-btn .gen-cost { font-size: 11.5px; opacity: 0.85; font-weight: 500; }
.gen-btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none !important; }
.gen-btn.busy::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 40%, var(--sheen) 50%, transparent 60%);
  animation: shimmer 1.4s ease infinite;
}
@keyframes shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }

/* ── sub-tabs (Image Edit: By Prompt / With Reference) ── */
.subtabs {
  display: flex; gap: 4px; margin: 0 22px 4px;
  padding: 4px;
  background: var(--glass); border: 1px solid var(--line);
  border-radius: 12px;
}
.subtab {
  flex: 1; padding: 9px 10px; border-radius: var(--r-sm);
  font-size: 12.5px; font-weight: 500; color: var(--ink-faint);
  transition: 0.22s;
}
.subtab:hover { color: var(--ink-dim); }
.subtab.on { color: var(--on-brand); background: var(--brand-soft); box-shadow: inset 0 0 0 1px var(--brand-edge); }
.edit-sub[hidden] { display: none; }

/* ── dropzone (image upload, Image Edit) ── */
.dropzone {
  position: relative;
  border: 1px dashed var(--line-2);
  border-radius: var(--r-md);
  background: rgba(94, 106, 210, 0.04);
  min-height: 130px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; overflow: hidden;
  transition: 0.25s;
}
.dropzone:hover, .dropzone.over { border-color: var(--accent-ink); background: rgba(94, 106, 210, 0.06); }
.dz-idle { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 20px; text-align: center; }
.dz-idle svg { color: var(--accent-ink); margin-bottom: 2px; }
.dz-idle b { font-size: 13.5px; }
.dz-idle span { font-size: 11.5px; color: var(--ink-faint); }
.dz-preview { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.dropzone-sm { min-height: 84px; }
.dropzone-sm .dz-idle { padding: 10px; }
.dropzone-sm .dz-idle span { font-size: 11px; color: var(--ink-faint); }

/* ── toggle switch (Shift to T-pose) ── */
.toggle-row {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  cursor: pointer;
}
.toggle-row > span:first-child { display: flex; flex-direction: column; font-size: 14px; font-weight: 500; }
.toggle-row i { font-style: normal; font-size: 11.5px; font-weight: 400; color: var(--ink-faint); margin-top: 1px; }
.switch { position: relative; width: 40px; height: 23px; flex-shrink: 0; }
.switch input { opacity: 0; width: 100%; height: 100%; position: absolute; cursor: pointer; z-index: 2; margin: 0; }
.switch i {
  position: absolute; inset: 0; border-radius: 999px;
  background: var(--glass-2);
  transition: 0.3s var(--ease-out);
}
.switch i::after {
  content: ''; position: absolute; top: 3px; left: 3px;
  width: 17px; height: 17px; border-radius: 50%;
  background: var(--bg1);
  transition: 0.3s var(--ease-spring);
}
.switch input:checked + i { background: var(--brand); }
.switch input:checked + i::after { transform: translateX(17px); background: #fff; }

/* ── polygon count (numeric input + quick-select presets) ── */
.poly-num { font-family: var(--font-mono); text-align: right; }
.poly-presets { display: flex; gap: 6px; margin-top: 8px; }
.poly-preset {
  flex: 1;
  padding: 8px 4px; border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: var(--bg1);
  color: var(--ink-dim); font-size: 12px; font-weight: 500; font-family: var(--font-mono);
  transition: 0.2s;
}
.poly-preset { background: var(--glass); }
.poly-preset:hover { color: var(--ink); border-color: var(--line-2); background: var(--glass-2); }
.poly-preset:active { transform: scale(0.96); }

/* ── multi-view 4-slot grid ── */
.mv-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.mv-slot .plabel { margin-bottom: 6px; }

/* ═══════════ RESULT AREA (Text to Image / Image Edit output) ═══════════ */
/* --viewport is the recessed stage colour generated images and 3D canvases sit against —
   deliberately a touch deeper than --bg0 so the artwork reads as the focal object */
.result-area {
  flex: 1; min-width: 0; position: relative;
  background:
    radial-gradient(90% 90% at 50% 100%, rgba(94, 106, 210, 0.05), transparent 60%),
    var(--viewport);
  display: flex;
}
.result-stage {
  flex: 1; position: relative;
  display: flex; align-items: center; justify-content: center;
  padding: 32px;
}
.result-empty {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  text-align: center; pointer-events: none;
}
.result-empty svg { margin-bottom: 8px; animation: float-y 5s ease-in-out infinite; }
@keyframes float-y { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
.result-empty b { font-family: var(--font-display); font-size: 19px; font-weight: 500; }
.result-empty span { font-size: 13.5px; color: var(--ink-faint); line-height: 1.6; }

.result-image {
  max-width: 100%; max-height: 100%;
  border-radius: var(--r-md);
  box-shadow: var(--shadow-xl);
  animation: view-in 0.5s var(--ease-out);
}

/* the in-place progress indicator — mounted once per generation and only ever mutated
   afterwards (a single .result-stage-label textContent update), never rebuilt, so it can't
   flicker. Deliberately small and anchored to the top edge (not a big centered card) so it
   stays out of the way of whatever's progressively appearing underneath (views strip, an
   interim mesh preview, ...) instead of covering the whole stage. */
.result-progress {
  position: absolute; top: 16px; left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: 9px;
  padding: 7px 16px 7px 12px;
  border-radius: 999px;
  background: var(--overlay);
  color: var(--overlay-ink);
  border: 1px solid var(--overlay-line);
  box-shadow: var(--shadow-md);
  backdrop-filter: blur(14px);
  pointer-events: none;
  animation: view-in 0.35s var(--ease-out);
}
.result-spinner {
  width: 15px; height: 15px; border-radius: 50%; flex-shrink: 0;
  border: 2px solid var(--line-2);
  border-top-color: var(--accent-ink);
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.result-stage-label { font-size: 10px; letter-spacing: 0.2em; color: currentColor; text-align: center; white-space: nowrap; }
.result-overlay { pointer-events: none; }   /* lets interim 3D content underneath stay orbit/zoom-able while it's up */

/* ═══════════ 3D GENERATOR RESULT AREA ═══════════ */
.result-area-3d { flex-direction: column; }
#threeDStage canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.result-overlay { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; z-index: 2; }
.views-strip {
  display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px;
  padding: 16px 16px 0;
}
.view-thumb {
  border-radius: var(--r-sm); overflow: hidden;
  border: 1px solid var(--line);
  background: var(--bg1);
  aspect-ratio: 1; position: relative;
}
.view-thumb img { width: 100%; height: 100%; object-fit: cover; }
.view-thumb:has(img) { cursor: pointer; transition: transform 0.25s var(--ease-out); }
.view-thumb:has(img):hover { transform: translateY(-2px); border-color: rgba(94, 106, 210, 0.55); }
.view-thumb span {
  position: absolute; bottom: 0; left: 0; right: 0;
  padding: 4px 6px;
  background: linear-gradient(transparent, rgba(0,0,0,0.75));
  font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.08em;
  color: #fff; text-align: center;
}
.view-thumb.pending { display: flex; align-items: center; justify-content: center; }
.view-thumb.pending::before {
  content: ''; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--line-2); border-top-color: var(--accent-ink);
  animation: spin 0.9s linear infinite;
}

/* viewport HUD — floats over the 3D canvas, follows the page theme like everything else */
.vp-tools {
  position: absolute; top: 18px; right: 18px; z-index: 3;
  display: flex; align-items: center; gap: 4px;
  padding: 6px;
  border-radius: var(--r-lg);
  background: var(--overlay);
  color: var(--overlay-ink);
  border: 1px solid var(--overlay-line);
  backdrop-filter: blur(14px);
  box-shadow: var(--shadow-md);
  flex-wrap: wrap; max-width: min(420px, calc(100% - 36px)); justify-content: flex-end;
}
.vtool {
  display: flex; align-items: center; gap: 7px;
  height: 36px; min-width: 36px; padding: 0 9px;
  border-radius: var(--r-sm);
  color: var(--ink-dim); font-size: 12px; font-weight: 500;
  transition: 0.2s; justify-content: center;
}
.vtool:hover { color: var(--ink); background: var(--glass-2); }
.vtool.on { color: var(--on-brand); background: var(--brand-soft); }
.vtool-sep { width: 1px; height: 20px; background: var(--line-2); margin: 0 3px; }

/* ── lighting intensity slider ── */
.vtool-light { display: flex; align-items: center; gap: 7px; padding: 0 10px 0 8px; }
.vtool-light svg { flex-shrink: 0; opacity: 0.8; }
.vtool-light input[type="range"] {
  -webkit-appearance: none; appearance: none;
  width: 64px; height: 3px; border-radius: 999px;
  background: var(--line-2);
  outline: none;
}
.vtool-light input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--accent-ink); cursor: pointer;
}
.vtool-light input[type="range"]::-moz-range-thumb {
  width: 12px; height: 12px; border-radius: 50%; border: none;
  background: var(--accent-ink); cursor: pointer;
}

/* ═══════════ 3D GENERATOR PLACEHOLDER ═══════════ */
.placeholder-view {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
  text-align: center; padding: 40px;
}
.placeholder-view b { font-family: var(--font-display); font-size: 21px; font-weight: 500; }
.placeholder-view span { font-size: 14px; color: var(--ink-faint); line-height: 1.7; max-width: 420px; }

/* ═══════════ ASSET LIBRARY (persistent right panel) ═══════════ */
.library-panel {
  width: 280px; flex-shrink: 0;
  display: flex; flex-direction: column;
  border-left: 1px solid var(--line);
  background: var(--bg1);
}
.stage.no-library .library-panel { display: none; }
.library-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px 18px 14px;
}
.library-head h4 { font-family: var(--font-display); font-size: 15px; font-weight: 500; }
.library-head span { font-size: 10.5px; color: var(--ink-faint); }

.library-grid {
  flex: 1;
  /* min-height: 0 is load-bearing: a flex child's default min-height is `auto` (its content
     height), so without this the grid refuses to shrink to the panel and the rows squash on
     top of each other instead of overflowing into this element's own scrollbar */
  min-height: 0;
  overflow-y: auto; overscroll-behavior: contain;
  padding: 4px 14px 16px;
  display: grid; grid-template-columns: 1fr 1fr; gap: 9px;
  /* rows are sized by the tiles' own aspect-ratio, never stretched/compressed to fit */
  grid-auto-rows: max-content;
  align-content: start;
}
.lib-item {
  position: relative; aspect-ratio: 1; width: 100%;
  border-radius: var(--r-sm); overflow: hidden;
  border: 1px solid var(--line);
  background: var(--bg2);
  transition: transform 0.3s var(--ease-out), border-color 0.25s;
  animation: lib-item-in 0.4s var(--ease-spring);
}
@keyframes lib-item-in { from { opacity: 0; transform: scale(0.92); } to { opacity: 1; transform: none; } }
.lib-item:hover { transform: translateY(-2px); border-color: rgba(94, 106, 210, 0.55); }
.lib-item-thumb { position: absolute; inset: 0; }
.lib-item-thumb img { width: 100%; height: 100%; object-fit: cover; }
.lib-item-type {
  position: absolute; top: 6px; left: 6px;
  font-family: var(--font-mono); font-size: 8px; letter-spacing: 0.1em;
  padding: 3px 6px; border-radius: 5px;
  background: var(--overlay); border: 1px solid var(--line-2);
  color: var(--accent-ink);
}
.lib-item-del {
  position: absolute; top: 6px; right: 6px; z-index: 2;
  width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--overlay); border: 1px solid var(--line-2);
  color: var(--overlay-ink);
  opacity: 0; transition: 0.2s;
}
.lib-item:hover .lib-item-del { opacity: 0.85; }
.lib-item-del:hover { opacity: 1 !important; color: var(--err); border-color: color-mix(in srgb, var(--err) 40%, transparent); }

.library-empty {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  padding: 24px; text-align: center;
}
.library-empty span { font-size: 12px; color: var(--ink-faint); line-height: 1.6; }
.library-grid:not(:empty) + .library-empty { display: none; }

/* ═══════════ PROFILE ═══════════ */
.view-profile { overflow-y: auto; }
.profile-wrap { width: 100%; max-width: 1060px; margin: 0 auto; padding: 30px 34px 60px; }

.pf-hero { border-radius: var(--r-xl); overflow: hidden; border: 1px solid var(--line); background: var(--bg1); }
.pf-banner {
  height: 150px;
  background:
    radial-gradient(70% 160% at 20% 0%, rgba(94, 106, 210, 0.55), transparent 55%),
    radial-gradient(60% 150% at 85% 20%, rgba(94, 106, 210, 0.35), transparent 55%),
    radial-gradient(50% 120% at 55% 100%, rgba(255, 92, 158, 0.18), transparent 60%),
    var(--bg2);
  position: relative;
}
.pf-banner::after {
  content: ''; position: absolute; inset: 0;
  background-image:
    linear-gradient(var(--line) 1px, transparent 1px),
    linear-gradient(90deg, var(--line) 1px, transparent 1px);
  background-size: 34px 34px;
  mask-image: linear-gradient(to bottom, #000, transparent);
  -webkit-mask-image: linear-gradient(to bottom, #000, transparent);
}
.pf-id { display: flex; align-items: flex-end; gap: 20px; padding: 0 28px 24px; margin-top: -44px; position: relative; flex-wrap: wrap; }
.pf-avatar {
  width: 92px; height: 92px; border-radius: var(--r-xl);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-size: 30px; font-weight: 500;
  background: linear-gradient(135deg, #2b2270, #0e3a5e);
  color: #fff;   /* the gradient is always dark-ish by design, in both themes */
  border: 3px solid var(--bg1);
  box-shadow: var(--shadow-lg);
}
.pf-name { flex: 1; padding-bottom: 4px; }
.pf-name h2 { font-family: var(--font-display); font-size: 25px; font-weight: 500; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.pf-plan {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.2em;
  padding: 5px 11px; border-radius: 7px;
  background: var(--grad); color: #fff;
  box-shadow: 0 2px 12px rgba(94, 106, 210, 0.4);
}
.pf-name p { font-size: 12px; color: var(--ink-faint); margin-top: 3px; }
.pf-actions { display: flex; gap: 8px; margin-bottom: 6px; flex-wrap: wrap; }
.danger-btn { color: #ff8b99; border-color: rgba(255, 92, 114, 0.3); }
.danger-btn:hover { background: rgba(255, 92, 114, 0.1); border-color: rgba(255, 92, 114, 0.5); color: #ffb3bd; }

.plan-switch { display: flex; flex-direction: column; gap: 7px; margin-top: 16px; }
.plan-opt {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 14px; border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: var(--glass);
  text-align: left;
  transition: 0.22s;
}
.plan-opt:hover { border-color: var(--line-2); background: var(--glass-2); }
.plan-opt b { font-size: 14px; font-weight: 500; }
.plan-opt span { font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-faint); }
.plan-opt.on {
  border-color: rgba(94, 106, 210, 0.55);
  background: var(--brand-soft);
  box-shadow: inset 0 0 0 1px rgba(94, 106, 210, 0.25);
}
.plan-opt.on::after {
  content: 'CURRENT';
  font-family: var(--font-mono); font-size: 8.5px; letter-spacing: 0.16em;
  color: var(--on-brand);
}
.plan-opt.on span { display: none; }
.plan-opt.on b { color: var(--on-brand); }   /* --brand-soft is a solid gradient in light mode — keep the label legible */

.pf-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px;
  margin-top: 18px;
}
.pf-card {
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--bg1);
  padding: 24px;
}
.pf-card h4 {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--ink-faint); font-weight: 500;
  margin-bottom: 18px;
}
.pf-usage { grid-row: span 2; display: flex; flex-direction: column; align-items: center; }
.usage-ring-wrap { position: relative; display: flex; align-items: center; justify-content: center; margin: auto 0; }
.usage-num {
  position: absolute; display: flex; flex-direction: column; align-items: center;
}
.usage-num b { font-size: 26px; }
.usage-num span { font-size: 11px; color: var(--ink-faint); }
.pf-note { font-size: 11px; color: var(--ink-faint); margin-top: 14px; }

.pf-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.pf-stats div { display: flex; flex-direction: column; gap: 2px; }
.pf-stats b { font-size: 22px; }
.pf-stats span { font-size: 11.5px; color: var(--ink-faint); }

.pf-plan-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.pf-plan-row b { font-family: var(--font-display); font-size: 19px; font-weight: 500; display: block; }
.pf-plan-row span { font-size: 12px; color: var(--ink-faint); }

.api-row {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 14px; border-radius: var(--r-sm);
  background: var(--glass); border: 1px solid var(--line);
}
.api-row code { flex: 1; font-size: 12px; color: var(--ink-dim); overflow: hidden; text-overflow: ellipsis; }

.pf-history { grid-column: span 2; }
.hist-table { display: flex; flex-direction: column; }
.hist-row {
  display: grid; grid-template-columns: 1fr auto auto auto;
  gap: 16px; align-items: center;
  padding: 11px 4px;
  border-bottom: 1px solid var(--line);
  font-size: 13px;
}
.hist-row:last-child { border-bottom: none; }
.hist-row b { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hist-row .mono { font-size: 10.5px; color: var(--ink-faint); }
.hist-kind {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.12em;
  padding: 3px 8px; border-radius: 6px;
  border: 1px solid var(--line-2); color: var(--ink-dim);
}
.hist-empty { padding: 20px 4px; font-size: 13px; color: var(--ink-faint); }

/* ═══════════ MODAL ═══════════ */
.modal-back {
  position: fixed; inset: 0; z-index: 180;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: var(--scrim);
  backdrop-filter: blur(10px);
  animation: fade-in 0.28s ease;
}
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
.modal {
  width: 100%; max-width: 400px;
  padding: 28px;
  border-radius: var(--r-xl);
  background: var(--bg1);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-xl);
  animation: acct-in 0.4s var(--ease-spring);
}
.modal { background: var(--bg2); border-color: var(--line-2); }
.modal h3 { font-family: var(--font-display); font-size: 21px; font-weight: 500; margin-bottom: 22px; }
.modal-field { display: flex; flex-direction: column; gap: 8px; margin-bottom: 18px; }
.modal-field label {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--ink-faint);
}
.modal-field input:disabled { opacity: 0.5; cursor: not-allowed; }
.modal-hint { font-size: 11.5px; color: var(--ink-faint); }
.modal-acts { display: flex; justify-content: flex-end; gap: 9px; margin-top: 24px; }

/* ── asset preview modal ── */
.asset-modal { max-width: 560px; position: relative; padding: 20px; }
.modal-x {
  position: absolute; top: 14px; right: 14px; z-index: 2;
  width: 32px; height: 32px; border-radius: var(--r-sm);
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-dim); background: var(--glass); border: 1px solid var(--line);
  transition: 0.2s;
}
.modal-x:hover { color: var(--ink); background: var(--glass-2); }
.asset-modal-preview {
  border-radius: var(--r-md); overflow: hidden;
  background: var(--viewport);
  display: flex; align-items: center; justify-content: center;
  max-height: 60vh;
}
.asset-modal-preview img { max-width: 100%; max-height: 60vh; display: block; }
.asset-modal-meta { padding: 16px 4px 4px; display: flex; flex-direction: column; gap: 4px; }
.asset-modal-meta b { font-family: var(--font-display); font-size: 16px; font-weight: 500; }
.asset-modal-meta span { font-size: 11.5px; color: var(--ink-faint); }
.asset-modal .modal-acts { padding: 0 4px; margin-top: 18px; }

/* ── single view-image preview modal ── */
.view-image-modal { max-width: 640px; position: relative; padding: 20px; }
.view-image-preview {
  border-radius: var(--r-md); overflow: hidden;
  background: var(--viewport);
  display: flex; align-items: center; justify-content: center;
  max-height: 66vh;
}
.view-image-preview img { max-width: 100%; max-height: 66vh; display: block; }

/* ═══════════ TOASTS ═══════════ */
.toasts {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  z-index: 200; pointer-events: none;
}
.toast {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 20px;
  border-radius: 999px;
  background: var(--overlay);
  color: var(--overlay-ink);
  border: 1px solid var(--overlay-line);
  backdrop-filter: blur(16px);
  font-size: 13.5px; font-weight: 500;
  box-shadow: var(--shadow-lg);
  animation: toast-in 0.45s var(--ease-spring);
}
.toast.out { animation: toast-out 0.35s ease forwards; }
.toast i { font-style: normal; }
@keyframes toast-in { from { opacity: 0; transform: translateY(16px) scale(0.94); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateY(10px) scale(0.96); } }

/* ═══════════ RESPONSIVE ═══════════ */
@media (max-width: 1180px) {
  .library-panel { width: 230px; }
  .library-grid { grid-template-columns: 1fr; }
  .pf-grid { grid-template-columns: 1fr 1fr; }
  .pf-usage { grid-row: auto; }
  .pf-history { grid-column: span 2; }
}
@media (max-width: 860px) {
  .stage { flex-direction: column; overflow-y: auto; }
  .view { position: static; flex-direction: column; animation: none; }
  .panel { width: 100%; border-right: none; border-bottom: 1px solid var(--line); }
  .panel-scroll { max-height: none; overflow: visible; }
  .result-area { min-height: 50vh; }
  .library-panel { width: 100%; border-left: none; border-top: 1px solid var(--line); max-height: 40vh; }
  .library-grid { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
  .pf-grid { grid-template-columns: 1fr; }
  .pf-history { grid-column: span 1; }
  .hist-row { grid-template-columns: 1fr auto; }
  .hist-row .hist-time { display: none; }
  .profile-wrap { padding: 20px 16px 50px; }
  .rail { width: 58px; }
}

/* ═══════════ LIGHT-THEME ELEVATION ═══════════
   Dark separates surfaces with hairline borders alone; on light that reads flat, so the
   raised surfaces get a soft lift instead. Dark opts back out of every one of these. */
.pf-card, .pf-hero, .lib-item, .dropzone { box-shadow: var(--shadow-sm); }
.panel { box-shadow: 1px 0 0 var(--line); }
.library-panel { box-shadow: -1px 0 0 var(--line); }
.result-image { box-shadow: var(--shadow-xl); }
.lib-item:hover { box-shadow: var(--shadow-md); }

/* The 6-view thumbnails and library tiles hold generated artwork, which is usually dark —
   a light tile behind a transparent PNG needs its own recessed fill so alpha reads right. */
.view-thumb, .lib-item-thumb { background: var(--viewport-2); }

/* ── model version selector (Normal Map / White Mesh / V1 / V2), bottom-center ──
   Each slot is either a clickable version button or, while that version is still rendering
   server-side, a shimmering placeholder of the exact same size — swapping the two never
   reflows the row. Normal Map has no server-side wait (it's a render-mode toggle on whatever
   mesh is already loaded), so it never shows a loading slot — just disabled until any mesh
   has loaded at all. */
.ver-seg {
  position: absolute; bottom: 18px; left: 50%; transform: translateX(-50%); z-index: 3;
  display: flex; gap: 4px; padding: 4px;
  border-radius: 999px;
  background: var(--overlay);
  border: 1px solid var(--overlay-line);
  backdrop-filter: blur(14px);
  box-shadow: var(--shadow-md);
}
.ver-btn {
  padding: 8px 14px; border-radius: 999px;
  font-size: 12.5px; font-weight: 500; color: var(--overlay-ink);
  opacity: 0.7;
  transition: 0.2s;
}
.ver-btn:hover { opacity: 1; background: var(--glass-2); }
.ver-btn.on { opacity: 1; background: var(--brand-soft); color: var(--on-brand); }
.ver-slot-loading {
  width: 62px; height: 33px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
}
.ver-slot-loading i {
  width: 12px; height: 12px; border-radius: 50%;
  border: 2px solid var(--line-2); border-top-color: var(--accent-ink);
  animation: spin 0.8s linear infinite;
}

/* ── download — bottom-right corner, independent of the version selector ── */
.vp-download { position: absolute; bottom: 18px; right: 18px; z-index: 3; }
.vp-dl { box-shadow: var(--shadow-lg), 0 4px 18px rgba(94, 106, 210, 0.3); }
.vp-dl b { font-size: 11px; opacity: 0.85; font-weight: 500; }

/* ── library tiles mid-generation ──
   A card is written the moment its generation starts, so the grid has to render three states,
   not one: still running, finished, and failed. */
.lib-item.is-pending { cursor: default; }
.lib-item.is-pending .lib-item-thumb,
.lib-item.is-failed .lib-item-thumb {
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--surface-2) 70%, transparent);
}
.lib-item.is-failed { opacity: .6; cursor: default; }

.lib-item-spinner {
  width: 24px; height: 24px; border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--txt-dim) 25%, transparent);
  border-top-color: var(--accent);
  animation: lib-spin .8s linear infinite;
}
@keyframes lib-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .lib-item-spinner { animation-duration: 2.4s; } }

.lib-item-state {
  position: absolute; left: 6px; bottom: 6px; z-index: 2;
  padding: 2px 7px; border-radius: 999px;
  font-size: 10px; font-weight: 500; letter-spacing: .02em;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  color: var(--txt-dim); border: 1px solid var(--border);
  backdrop-filter: blur(4px);
}
.lib-item-state.is-failed { color: var(--err); border-color: color-mix(in srgb, var(--err) 40%, transparent); }
