/* Worlds — roster + wizard + 3D view. Reuses .gpanel / .roster-grid / .roster-card / .btn from
   theme.css + character.css; this adds the world-specific layout (thumbnails, knob sliders, the
   side-by-side wizard form+preview, and the full-bleed forge/view stage). */

.world-roster, .world-wizard, .world-view { max-width: var(--content-max); margin: 0 auto; padding: 1.125rem 0; }

.roster-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-9); }

/* roster cards get a wide equirect thumbnail on top */
.world-card-thumb { display: block; aspect-ratio: 2 / 1; overflow: hidden; border-radius: var(--r-lg) var(--r-lg) 0 0;
  background: var(--bg-deep); margin: -0.0625rem -0.0625rem var(--sp-5); border-bottom: 0.0625rem solid var(--border); }
.world-card-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.world-roster .roster-card { padding: 0 0 var(--sp-6); overflow: hidden; }
.world-roster .roster-card-main { display: block; padding: 0 var(--sp-7); }
.world-roster .roster-card-foot { padding: var(--sp-5) var(--sp-7) 0; }

/* ── wizard ── */
.wiz-head { margin-bottom: var(--sp-8); }
.world-wiz-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-9); align-items: start; }
@media (max-width: 820px) { .world-wiz-body { grid-template-columns: 1fr; } }

.world-wiz-form { padding: var(--sp-9) 1.125rem; display: flex; flex-direction: column; gap: var(--sp-8); }
.wiz-name { display: block; color: var(--muted); font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .05em; text-transform: uppercase; }
/* text/number inputs in the wizard — the global baseline themes them, these just set width/spacing
   (the refactor renamed .world-wiz-form → .wiz-knobs, which had orphaned the seed input's sizing). */
.wiz-name input, .wiz-knob input[type=number], .wiz-knob input[type=text] {
  width: 100%; margin-top: 0.3125rem; }
.wiz-knob .row { display: flex; gap: var(--sp-5); align-items: center; }
.wiz-knob .row input[type=number] { width: 8.125rem; margin-top: 0; }
/* validation checklist on the Create step (the to-fix list sits above the Save bar) */
.world-create-viol { flex: 0 0 auto; margin: var(--sp-3) 0 0; padding: 0 var(--sp-1); }
.world-create-viol .pv-todo { margin-top: 0; }

.wiz-knob label { display: flex; justify-content: space-between; color: var(--muted); font-family: var(--font-mono);
  font-size: var(--fs-2xs); letter-spacing: .05em; text-transform: uppercase; margin-bottom: var(--sp-3); }
.wiz-knob label .v { color: var(--gold); font-variant-numeric: tabular-nums; }
.wiz-knob input[type=range] { width: 100%; accent-color: var(--accent); }
.wiz-knob-ends { display: flex; justify-content: space-between; color: var(--muted); font-size: var(--fs-2xs); margin-top: var(--sp-1); opacity: .8; }

.wiz-adv-toggle { background: none; border: 0; color: var(--accent); font-family: var(--font-mono); font-size: var(--fs-sm);
  text-align: left; cursor: pointer; padding: var(--sp-3) 0; }
.wiz-adv { display: flex; flex-direction: column; gap: var(--sp-8); border-top: 0.0625rem solid var(--border-soft); padding-top: var(--sp-7); }
/* Society & cosmology controls (selects, textarea, peoples chips) */
.wiz-knob select, .wiz-name textarea {
  width: 100%; margin-top: 0.3125rem; background: var(--bg); border: 0.0625rem solid var(--border); color: var(--text);
  padding: var(--sp-5) var(--sp-6); border-radius: var(--r-md); font: inherit; }
.wiz-name textarea { resize: vertical; min-height: 2.75rem; }
.wiz-subhead { font-family: var(--font-mono); font-size: var(--fs-2xs); letter-spacing: .08em; text-transform: uppercase;
  color: var(--gold); border-top: 0.0625rem solid var(--border-soft); padding-top: var(--sp-7); margin-top: var(--sp-1); }
/* Large book-sourced lists (gods/lands) — keep the chip cloud scrollable so the step stays compact. */

.world-wiz-preview { padding: var(--sp-8); position: sticky; top: 0.875rem; }
.wiz-pv-label { font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: .05em; text-transform: uppercase;
  color: var(--muted); margin-bottom: var(--sp-5); }
.wiz-pv-frame { position: relative; width: 100%; aspect-ratio: 2 / 1; border-radius: var(--r-lg); overflow: hidden;
  border: 0.0625rem solid var(--border); background: var(--bg-deep); }
.wiz-pv-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.wiz-pv-spin { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: var(--sp-6); color: var(--gold); font-family: var(--font-mono); font-size: var(--fs-sm);
  letter-spacing: .04em; background: rgba(11, 8, 5, .55); backdrop-filter: blur(0.0625rem); }
.pv-ring { width: 1.625rem; height: 1.625rem; border-radius: var(--r-round); border: 0.1875rem solid rgba(var(--gold-rgb), .25);
  border-top-color: var(--gold); animation: pv-spin .8s linear infinite; }
@keyframes pv-spin { to { transform: rotate(360deg); } }
.wiz-hint { color: var(--muted); font-size: var(--fs-xs); margin: var(--sp-5) 0 0; }

.wiz-nav { display: flex; justify-content: space-between; gap: var(--sp-6); margin-top: var(--sp-9); }

/* ── forge step + per-world view: full-bleed stage ── */
.world-wizard.forge, .world-view { max-width: none; padding: var(--sp-7); }
.world-wizard.forge .globe-stage, .world-view .globe-stage { height: calc(100dvh - var(--topbar-h,3.5rem) - 9.375rem); min-height: 28.75rem; }

/* ============================================================================
   No-scroll frame for the WORLD wizard — the SCREEN never scrolls; the design
   form (step 0) or the forge globe (step 1) fills the available space, and the
   nav (Settings · Save) is ALWAYS visible. Without this the forge step's fixed-
   height globe + the nav/hint below it overflowed the viewport, hiding the
   buttons behind the pinned footer. Mirrors the character & campaign wizards
   (character.css `body:has(.char-wizard)`). Scoped to the wizard only — the
   roster (.world-roster) and per-world view (.world-view) keep normal scroll.
   ============================================================================ */
body:has(.world-wizard) main.app-main {
  flex: 0 0 auto;
  height: calc(100dvh - var(--topbar-h, 3.5rem));
  max-height: calc(100dvh - var(--topbar-h, 3.5rem));
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
body:has(.world-wizard) main.app-main > #app {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
}
/* width:100% is MANDATORY — in the flex column, `margin:0 auto` (from line 5) would otherwise shrink
   this to its content width instead of stretching to the full Library width (var(--content-max)). */
.world-wizard { flex: 1 1 auto; min-height: 0; width: 100%; display: flex; flex-direction: column; overflow: hidden; }
.world-wizard .wiz-head, .world-wizard .wiz-nav, .world-wizard .wiz-hint { flex: 0 0 auto; }
/* step 0: the form + preview grid is the internal scroll region */
.world-wizard .world-wiz-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
/* step 1: the globe fills whatever's left (override the fixed calc height so the nav stays on-screen) */
.world-wizard.forge .globe-stage { flex: 1 1 auto; min-height: 0; height: auto; }

.world-view-bar { display: flex; gap: var(--sp-5); margin-bottom: var(--sp-5); align-items: center; flex-wrap: wrap; }
.world-bar-spacer { flex: 1 1 auto; }
.camp-worldbanner { margin-top: var(--sp-5); padding: var(--sp-5) var(--sp-7); background: rgba(var(--accent-rgb), .08);
  border: 0.0625rem solid var(--border); border-radius: var(--r-lg); font-size: var(--fs-base); color: var(--text); }
.globe-title { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-lg); color: var(--gold);
  margin-bottom: var(--sp-4); line-height: 1; }

/* forge progress bar inside the "Forging the world" loader (segmented pct + ETA, fed by the
   /api/world/rebuild stream — so the long bake shows real movement, not just a spinner). */
.globe-load-bar { width: 16.25rem; max-width: 72vw; height: 0.375rem; border-radius: var(--r-sm); margin: 1.125rem auto 0;
  background: rgba(var(--gold-rgb), .15); overflow: hidden; }
.globe-load-fill { height: 100%; border-radius: var(--r-sm); transition: width .45s ease;
  background: linear-gradient(90deg, var(--accent), var(--gold)); }
.globe-load-pct { margin-top: var(--sp-5); color: var(--gold); font-family: var(--font-mono); font-size: var(--fs-sm);
  letter-spacing: .04em; font-variant-numeric: tabular-nums; }

/* the wizard's forge screen (explicit forge → progress → only then the 3D globe, so no black world) */
.forge-panel { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; align-items: center;
  justify-content: center; text-align: center; gap: var(--sp-3); padding: 1.875rem; }
.forge-panel .globe-load-sub { max-width: 27.5rem; }

/* World wizard now rides the shared Character/Campaign wizard scaffolding (.char-wizard no-scroll frame +
   .wiz-steps rail + .wiz-layout). These adapt the world-specific bits to that shell. */
.wiz-knobs { display: flex; flex-direction: column; gap: var(--sp-8); }
.wiz-layout-solo { grid-template-columns: 1fr; }   /* the Documents step: full-width content picker */
.wiz-knob-empty { margin-top: 0.3125rem; padding: var(--sp-5) var(--sp-6); border: 0.0625rem dashed var(--border); border-radius: var(--r-md);
  color: var(--muted); font-size: var(--fs-sm); }
.char-wizard .world-wiz-preview { position: static; align-self: stretch; min-height: 0; overflow-y: auto; margin: 0; }
.char-wizard.world-wizard.forge .wiz-steps { margin-bottom: var(--sp-7); }

/* ── Genre presets (world wizard Name step) ─────────────────────────────── */
.wiz-presets { margin: 0 0 1.125rem; }
.wiz-presets-h { font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: .06em;
  text-transform: uppercase; color: var(--gold); margin-bottom: 0.5625rem; }
.wiz-presets-sub { color: var(--muted); text-transform: none; letter-spacing: 0; font-weight: 400; margin-left: var(--sp-4); }
.wiz-presets-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(9.375rem, 1fr)); gap: var(--sp-5); }
.wiz-preset { display: flex; flex-direction: column; gap: var(--sp-1); text-align: left; cursor: pointer; font: inherit;
  padding: var(--sp-6) var(--sp-7); border-radius: var(--r-lg); background: rgba(18,13,9,.7); border: 0.0625rem solid var(--border-soft); color: var(--text);
  transition: border-color .14s var(--ease-soft), background .14s var(--ease-soft), transform .12s var(--ease-soft); }
.wiz-preset:hover { border-color: var(--accent); background: rgba(var(--accent-rgb), .08); transform: translateY(-0.0625rem); }
/* the preset matching the current knobs (Layout/Climate) is highlighted as selected */
.wiz-preset.on { border-color: var(--accent); background: rgba(var(--accent-rgb), .14); box-shadow: inset 0 0 0 0.0625rem var(--accent); }
.wiz-preset-ico { font-size: var(--fs-sub); line-height: 1; }
.wiz-preset-name { font-family: var(--font-mono); font-size: var(--fs-smplus); font-weight: 600; color: var(--text); }
.wiz-preset:hover .wiz-preset-name, .wiz-preset.on .wiz-preset-name { color: var(--accent); }
.wiz-preset-bl { font-size: var(--fs-xs); color: var(--muted); line-height: 1.3; }
