*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  color-scheme: dark;   /* native popups (select lists, colour and file pickers, scrollbars) in the dark theme */
  --bg:         #0c0e13;
  --surface:    #13151c;
  --surface2:   #191c25;
  --surface3:   #1e2230;
  --border:     #252a38;
  --text:       #d4d9e8;
  --muted:      #a3adbf;   /* was #58637a: 1.8:1 on the glass; now at least 4.5:1 over the daylight sky */
  --accent:     #4fcb9d;
  --accent-dim: #163d2d;
  --success:    #6fcf97;
  --warn:       #e8c97a;
  --caution:    #e6e35a;   /* yellow, milder than --warn's amber (hue 59 against 43): 12.6:1 on --surface2 */
  --danger:     #e87a7a;
  /* legacy alias shims used in inline styles */
  --bg2:        #191c25;
  --fg:         #d4d9e8;
  --mono: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
  --ui:   system-ui, -apple-system, sans-serif;
  --r:    7px;
  --r-sm: 5px;

  /* ── Tokens (UI phase P1): the values the rules below use, by name; the next shell builds on them ── */
  /* Colour: the accent and the danger colour at the strengths used; white veils and black shades on the glass */
  --accent-a12: rgba(79, 203, 157, 0.12);
  --accent-a15: rgba(79, 203, 157, 0.15);
  --accent-a18: rgba(79, 203, 157, 0.18);
  --accent-a20: rgba(79, 203, 157, 0.2);
  --accent-a30: rgba(79, 203, 157, 0.3);
  --accent-a55: rgba(79, 203, 157, 0.55);
  --danger-a20: rgba(232, 122, 122, 0.2);
  --warn-a25:   rgba(232, 201, 122, 0.25);
  --caution-a25: rgba(230, 227, 90, 0.25);
  --veil-05:    rgba(255, 255, 255, 0.05);
  --veil-10:    rgba(255, 255, 255, 0.1);
  --veil-15:    rgba(255, 255, 255, 0.15);
  --veil-20:    rgba(255, 255, 255, 0.2);
  --veil-30:    rgba(255, 255, 255, 0.3);
  --shade-20:   rgba(0, 0, 0, 0.2);
  --shade-30:   rgba(0, 0, 0, 0.3);
  --shade-50:   rgba(0, 0, 0, 0.5);
  --shade-60:   rgba(0, 0, 0, 0.6);
  --shade-80:   rgba(0, 0, 0, 0.8);
  --text-strong:  #fff;
  --text-disabled: #6f7889;   /* a disabled option: 3.8:1 on --surface2 */
  --blocked-bg:   rgba(42, 10, 10, 0.95);   /* the placement-blocked toast */
  --blocked-line: #ff4444;
  --blocked-text: #ff6666;
  --storey-line:  rgba(255, 106, 61, 0.6);  /* walls taller than their storey (outlined in the viewport in the same colour) */
  --storey-text:  #ff8a63;
  /* Glass: the floating panels */
  --glass-bg:      rgba(19, 21, 28, 0.78);  /* 0.65 let the daylight sky wash out the text */
  --glass-bg-thin: rgba(19, 21, 28, 0.65);
  --glass-blur:    blur(16px);
  --glass-blur-sm: blur(4px);
  --glass-line:    rgba(255, 255, 255, 0.08);
  --glass-shadow:  0 8px 32px rgba(0, 0, 0, 0.4);
  /* Radii (with --r and --r-sm above) */
  --r-2xs:  2px;
  --r-xs:   6px;
  --r-md:   8px;
  --r-lg:   10px;
  --r-xl:   12px;
  --r-2xl:  16px;
  --r-pill: 999px;
  /* Spacing */
  --sp-1: 2px;
  --sp-2: 4px;
  --sp-3: 8px;
  --sp-4: 12px;
  --sp-5: 16px;
  --sp-6: 24px;
  --sp-7: 32px;
  /* Type sizes (families: --mono, --ui) */
  --fs-2xs: 9px;
  --fs-xs:  11px;
  --fs-sm:  12px;
  --fs-md:  13px;
  --fs-lg:  14px;
  /* Controls */
  --btn-size:  48px;
  --icon-size: 24px;
  /* Motion */
  --t-fast: 0.12s;
  --t-mid:  0.15s;
  --t:      0.2s;
  --ease-glass: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --ease-pop:   cubic-bezier(0.16, 1, 0.3, 1);
  /* The new shell (UI phase P2, ?ui=next): its frame */
  --shell-edge:     12px;    /* the floating glass's distance from the window's edges */
  --shell-top-h:    48px;    /* the top bar */
  --shell-below:    72px;    /* under the top bar: the mode banner, the view cluster */
  --thumb-bg: radial-gradient(120% 95% at 50% 30%, #4a5163 0%, #2e3340 58%, #232733 100%);
  --cc0:      #8fd3ff;
  --cc0-a35:  rgba(143, 211, 255, 0.35);
  /* The floating surfaces (WL1, owner rulings 25 Oct 2026; ?ui=next): opaque, no blur, one elevation for controls, a deeper one for cards */
  --float-bg:        rgba(24, 27, 36, 0.94);
  --float-hi:        inset 0 1px 0 rgba(255, 255, 255, 0.06);
  --float-shadow:    0 6px 18px rgba(0, 0, 0, 0.38), 0 1px 3px rgba(0, 0, 0, 0.30);
  --float-shadow-up: 0 9px 24px rgba(0, 0, 0, 0.44), 0 2px 5px rgba(0, 0, 0, 0.32);
  --float-shadow-card: 0 12px 32px rgba(0, 0, 0, 0.42);
  --float-text:      #e8ecf3;
  --float-on-accent: #0f1419;
  --r-btn:   14px;
  --r-card:  18px;
  --r-key:   5px;
  --gap-in:  8px;    /* between neighbouring buttons of a group */
  /* ── Design tokens (UX round R1, 1 Nov 2026): the scales the UX spike names, where a control's size is decided ── */
  --tk-sp-1: 4px;  --tk-sp-2: 8px;  --tk-sp-3: 12px;  --tk-sp-4: 16px;  --tk-sp-5: 24px;   /* spacing: gap in a group 8, between groups 16, card padding 12 */
  --tk-r-field: 8px;  --tk-r-card: 18px;                                                    /* radii */
  --tk-fs-cap: 12px;  --tk-fs-body: 13px;  --tk-fs-title: 15px;                             /* type: one sans family, numbers tabular */
  --tk-icon-inline: 16px;  --tk-icon-utility: 22px;  --tk-icon-tool: 24px;  --tk-icon-category: 28px;
  --tk-card-s: 248px;  --tk-card-m: 320px;  --tk-card-l: 392px;                             /* card widths */
  --tk-hit-min: 28px;                                                                       /* no hit target is smaller */
  --tk-h-chip: 28px;  --tk-h-field: 28px;                                                   /* a chip / segment; a field (number box, menu button) */
  --gap-out: 16px;   /* between groups */
  --cat-btn:  56px;  --cat-icon:  30px;
  --tool-btn: 48px;  --tool-icon: 26px;
  --util-btn: 44px;  --util-icon: 22px;
}

html, body { height: 100%; background: var(--bg); color: var(--text); font-family: var(--ui); font-size: var(--fs-md); overflow: hidden; }

/* ── App shell ──────────────────────────────────────── */
#app { display: flex; flex-direction: column; height: 100vh; }

/* ── Fields ─────────────────────────────────────────── */
.field { margin-bottom: 10px; }
.field:last-child { margin-bottom: 0; }
.field label { display: block; font-size: var(--fs-xs); color: var(--muted); margin-bottom: 5px; font-weight: 500; }
.field input[type=number],
.field input[type=text] {
  width: 100%; background: var(--bg); border: 1px solid var(--border);
  color: var(--text); padding: 6px 10px; border-radius: var(--r-sm);
  font-size: var(--fs-sm); font-family: var(--mono); outline: none;
  transition: border-color var(--t-mid), box-shadow var(--t-mid);
}
.field input[type=number]:focus,
.field input[type=text]:focus { border-color: var(--accent); box-shadow: 0 0 0 var(--sp-1) var(--accent-a12); }

/* ── Color inputs ───────────────────────────────────── */
input[type=color] {
  width: 44px; height: 28px; border: 1px solid var(--border);
  border-radius: var(--r-sm); background: none; cursor: pointer; padding: 1px 2px;
  transition: border-color var(--t-mid);
}
input[type=color]:hover { border-color: var(--accent); }

/* ── Canvas wrap ────────────────────────────────────── */
#canvas-wrap { flex: 1; position: relative; overflow: hidden; min-width: 0; }
#builder-canvas { width: 100%; height: 100%; display: block; }

/* ── Dimension label ────────────────────────────────── */
#dim-label {
  position: absolute; top: 0; left: 0; pointer-events: none;
  font-family: var(--mono); font-size: var(--fs-sm); font-weight: 600;
  color: var(--text-strong); text-shadow: 0 1px 4px var(--shade-80);
  white-space: nowrap; display: none;
  background: var(--shade-60); padding: var(--sp-1) var(--sp-3); border-radius: var(--r-sm);
}

/* ── Hint overlay ───────────────────────────────────── */
#canvas-hint {
  position: absolute; bottom: var(--sp-3); left: var(--sp-5); max-width: calc(100vw - 260px);
  font-family: var(--mono); font-size: var(--fs-xs); line-height: 1.4;
  color: var(--text); background: var(--glass-bg); border-radius: var(--r-xs); padding: 3px var(--sp-3);
  pointer-events: none; user-select: none;
}

/* ── Buttons ────────────────────────────────────────── */
.btn {
  padding: 6px 14px; border-radius: var(--r-sm); border: 1px solid var(--border);
  background: var(--surface2); color: var(--text); cursor: pointer; font-size: var(--fs-sm);
  font-family: var(--ui); transition: border-color var(--t-fast), color var(--t-fast), background var(--t-fast);
  white-space: nowrap;
}
.btn:hover { border-color: var(--accent); color: var(--accent); }
.btn.primary { background: var(--accent-dim); border-color: var(--accent); color: var(--accent); }
.btn.primary:hover { background: var(--accent-a18); }
.btn:disabled { opacity: .4; pointer-events: none; }

/* ── Placement-blocked toast ────────────────────────── */
#place-warn {
  display: none; position: absolute; top: 44px; left: 50%; transform: translateX(-50%);
  background: var(--blocked-bg); border: 1px solid var(--blocked-line); border-radius: var(--r-sm);
  padding: 5px var(--sp-5); font-size: var(--fs-xs); font-family: var(--mono); color: var(--blocked-text);
  pointer-events: none; white-space: nowrap; z-index: 20; transition: opacity 0.4s;
  backdrop-filter: var(--glass-blur-sm);
}

/* ── A loaded scene's duplicates (a note with "Clean up duplicates"; builder-ui.js showDuplicates) ── */
#dup-notice {
  position: absolute; bottom: var(--sp-5); left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: var(--sp-3);
  background: var(--glass-bg); border: 1px solid var(--storey-line); border-radius: var(--r-sm);
  padding: 4px 6px 4px 14px; font-size: var(--fs-xs); font-family: var(--mono); color: var(--storey-text);
  white-space: nowrap; z-index: 20;
  backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
}

/* ── Walls taller than their storey (persistent note; the walls are outlined in the same colour) ── */
#storey-warning {
  position: absolute; top: var(--sp-4); left: 50%; transform: translateX(-50%);
  background: var(--glass-bg); border: 1px solid var(--storey-line); border-radius: var(--r-sm);
  padding: 5px 14px; font-size: var(--fs-xs); font-family: var(--mono); color: var(--storey-text);
  pointer-events: none; white-space: nowrap; z-index: 20;
  backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
}

/* ── What a wall move left to look at (persistent note under the storey warning; Select tool) ── */
#wall-warning {
  position: absolute; top: calc(var(--sp-4) + 34px); left: 50%; transform: translateX(-50%);
  background: var(--glass-bg); border: 1px solid var(--storey-line); border-radius: var(--r-sm);
  padding: 5px 14px; font-size: var(--fs-xs); font-family: var(--mono); color: var(--storey-text);
  pointer-events: none; white-space: nowrap; z-index: 20;
  backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
}
/* A wall drag held at a refusal: its label in the blocked colours. */
#dim-label.refused { color: var(--blocked-text); background: var(--blocked-bg); border: 1px solid var(--blocked-line); }

/* ── Bottom toolbar ──────────────────────────────────── */

#level-indicator {
  font-size: var(--fs-md); font-weight: 700; font-family: var(--mono);
  color: var(--text); min-width: 28px; text-align: center;
}
/* The ghost level (the empty level above the top one, not built yet): dimmed */
#level-indicator.level-ghost { opacity: 0.5; font-style: italic; }

#bt-export-wrap { display: flex; align-items: center; gap: var(--sp-3); padding: 0 14px; flex-shrink: 0; position: relative; }

#bt-export-flyout {
  display: none; position: absolute; bottom: calc(100% + 6px); right: 0;
  width: 272px; background: var(--surface2); border: 1px solid var(--border);
  border-radius: var(--r); padding: 14px var(--sp-5); z-index: 100;
  box-shadow: 0 -8px 32px var(--shade-50);
}
#bt-export-flyout.open { display: block; }

/* ── Scrollbar ──────────────────────────────────────── */
::-webkit-scrollbar { width: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb:hover { background: var(--muted); }

/* ── Glassmorphic UI Overlays ───────────────────────── */
.glass-panel {
  position: absolute;
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-line);
  border-radius: var(--r-2xl);
  box-shadow: var(--glass-shadow);
  display: flex;
  z-index: 100;
  padding: var(--sp-3);
  gap: var(--sp-3);
}
.glass-panel.vertical {
  flex-direction: column;
  align-items: center;
}
.glass-panel.horizontal {
  flex-direction: row;
  align-items: center;
}

.bottom-strip {
  bottom: var(--sp-7);
  left: 50%;
  transform: translateX(-50%);
  /* Clear of the Export button on the right (and of the same width on the left, to stay centred): a long
     context bar (painting) wraps onto a second row instead of running under Export. */
  max-width: calc(100vw - 2 * (var(--export-w, 150px) + 40px));
  flex-wrap: wrap;
  justify-content: center;
}
.bottom-strip > div { min-width: 0; }
#paint-preset-hint { flex: 0 1 260px; min-width: 80px; }
/* The Export button on its own glass, legible over a light sky */
#btn-toggle-export { background: var(--glass-bg); border: 1px solid var(--accent-a55); color: var(--accent); }
#btn-toggle-export .glass-text { color: var(--accent); }

.right-strip {
  top: var(--sp-6);
  right: var(--sp-6);
}

.glass-btn {
  background: transparent;
  border: none;
  color: var(--text);
  cursor: pointer;
  width: var(--btn-size);
  height: var(--btn-size);
  border-radius: var(--r-xl);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all var(--t) var(--ease-glass);
  position: relative;
}
.glass-btn i {
  width: var(--icon-size);
  height: var(--icon-size);
  opacity: 0.7;
  transition: opacity var(--t);
  pointer-events: none; /* ensure click hits the button */
}
.glass-btn:hover {
  background: var(--veil-10);
  transform: translateY(calc(-1 * var(--sp-2)));
  box-shadow: 0 6px 12px var(--shade-20);
}
.glass-btn:hover i {
  opacity: 1;
}
.glass-btn.active {
  background: var(--accent-a20);
  color: var(--accent);
}
.glass-btn.active i {
  opacity: 1;
}
.glass-btn:disabled {
  opacity: 0.3;
  pointer-events: none;
}
.glass-btn.danger:hover {
  background: var(--danger-a20);
  color: var(--danger);
}

.glass-sep {
  width: 1px;
  height: var(--sp-7);
  background: var(--veil-10);
  margin: 0 var(--sp-2);
}

.glass-text {
  font-family: var(--mono);
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--text);
  padding: var(--sp-3) 0;
  text-align: center;
}

/* ── New UI Extensions ────────────────────────────── */
.left-gallery {
  top: 50%;
  left: var(--sp-6);
  transform: translateY(-50%);
  max-height: min(70vh, calc(100vh - 300px));   /* centred, and clear of a two-row bottom bar on short screens */
  width: 260px;
  align-items: stretch;
}

.gallery-header {
  font-size: var(--fs-sm);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  text-align: left;
  padding: var(--sp-2) var(--sp-3) var(--sp-3);
  border-bottom: 1px solid var(--veil-10);
  margin-bottom: var(--sp-3);
}

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);   /* two large tiles a row (256 px thumbnails): fewer per scroll */
  grid-auto-rows: max-content;   /* square tiles keep their height: the rows used to shrink and the tiles overlap */
  align-self: stretch;           /* the panel's full width before any thumbnail loads (.vertical centres; the tiles were 4 px) */
  flex: 1 1 auto;
  min-height: 0;
  gap: var(--sp-3);
  overflow-y: auto;
  padding: var(--sp-2);
}

.gallery-grid::-webkit-scrollbar { width: 4px; }
.gallery-sentinel { grid-column: 1 / -1; height: 1px; }   /* after the last tile: the next page loads when it shows */
.gallery-grid::-webkit-scrollbar-thumb { background: var(--veil-20); border-radius: var(--r-2xs); }

/* Asset loading toast — shown while a placed prop/attachment's real model resolves. */
#asset-loading {
  position: absolute;
  top: var(--sp-6); left: 50%;
  transform: translateX(-50%);
  display: none;
  align-items: center;
  gap: var(--sp-3);
  padding: 7px 14px;
  background: var(--glass-bg-thin);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-line);
  border-radius: var(--r-pill);
  box-shadow: var(--glass-shadow);
  color: var(--text);
  font-family: var(--mono);
  font-size: var(--fs-sm);
  z-index: 120;
  pointer-events: none;
}
.asset-spinner {
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 2px solid var(--veil-20);
  border-top-color: var(--accent);
  animation: asset-spin 0.7s linear infinite;
}
@keyframes asset-spin { to { transform: rotate(360deg); } }

/* The "Loading world detail" chip (ui/load-chip.js, roadmap 628): a floating pill at the top centre under the top bar, shown while the view's planned
 * detail (ghosts, ground, map overlay, Game look) is not all drawn; it takes no input. Opaque, no glass: the look of the other pills. */
.world-loading {
  position: absolute; top: calc(var(--sp-6) + 44px); left: 50%; transform: translateX(-50%); z-index: 105; pointer-events: none;
  display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-2) var(--sp-4); border-radius: var(--r-pill);
  background: var(--float-bg); box-shadow: var(--float-shadow); color: var(--float-text); font: 600 var(--fs-sm) var(--ui); white-space: nowrap;
}
.world-loading[hidden], .world-loading-count[hidden] { display: none; }
.world-loading .asset-spinner { flex: none; }
.world-loading-count { color: var(--muted); font-weight: 500; font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) { .world-loading .asset-spinner { animation: none; } }


.gallery-item {
  aspect-ratio: 1;
  display: block;
  width: 100%;
  padding: 0;
  font: inherit;
  color: var(--text);
  border-radius: var(--r-md);
  background: var(--veil-05);
  border: 2px solid transparent;
  cursor: pointer;
  overflow: hidden;
  transition: all var(--t);
  position: relative;
}

.gallery-item:hover {
  border-color: var(--veil-30);
  transform: scale(1.05);
}

.gallery-item:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.gallery-item.active {
  border-color: var(--accent);
  box-shadow: 0 0 12px var(--accent-a30);
}

.gallery-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.gallery-item .item-label {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: var(--shade-60);
  backdrop-filter: var(--glass-blur-sm);
  font-size: var(--fs-2xs);
  padding: var(--sp-1) var(--sp-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: center;
}

.glass-input {
  background: var(--shade-30);
  border: 1px solid var(--veil-10);
  color: var(--text);
  padding: 6px 10px;
  border-radius: var(--r-md);
  font-size: var(--fs-md);
  font-family: var(--mono);
  outline: none;
  width: 64px;
  transition: all var(--t);
  text-align: center;
}

select.glass-input { text-align: left; cursor: pointer; }
/* The drop-down lists of every select: a native popup can't draw the glass (Chrome on Windows put the
   translucent select over white, and the options' light text was unreadable), so the options get a solid
   dark background. On --surface2: option text 12.1:1, group labels 7.5:1, the checked option 9.5:1. */
select option, select optgroup { background-color: var(--surface2); color: var(--text); }
select option { font-weight: 400; }
select optgroup { font-weight: 700; font-style: normal; color: var(--muted); }
select option:disabled { color: var(--text-disabled); }
select option:checked { background-color: var(--accent); color: var(--bg); }
/* A colour field on the glass bars */
.glass-color { width: 36px; height: 26px; padding: var(--sp-1); border: 1px solid var(--veil-15); border-radius: var(--r-md); background: var(--shade-30); cursor: pointer; }
.glass-color:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* A section of the Settings flyout (Handles): a caption over label + control rows */
.settings-section { display: flex; flex-direction: column; gap: var(--sp-1); align-self: stretch; margin-top: var(--sp-1); padding-top: var(--sp-2); border-top: 1px solid var(--veil-10); }
.settings-caption { padding: var(--sp-1) var(--sp-4) 0; font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.settings-row { display: flex; align-items: center; gap: 6px; padding: var(--sp-2) var(--sp-4); }
.settings-row > label { font-size: var(--fs-xs); padding: 0; flex: none; }
.settings-row input[type=range] { flex: 1; min-width: 60px; margin: 0; }
.settings-row select.glass-input { flex: 1; width: auto; min-width: 0; font-size: var(--fs-xs); padding: 2px 4px; }
input[type=range] { accent-color: var(--accent); }
input[type=checkbox], input[type=radio] { accent-color: var(--accent); }
.settings-row > input[type=checkbox] { margin: 0; flex: none; }
/* The Settings flyout scrolls when it is taller than the room above the current UI's tool bar (the Ghosts section, 25 Oct 2026) */
#settings-panel { max-height: calc(100vh - 300px); overflow-y: auto; }
#settings-panel > * { flex-shrink: 0; }

/* ── Device health (device-health-ui.js): the indicator, the stats overlay (top centre, clear of the gallery and the view cluster), the software-rendering notice, the context-loss note ── */
.health-btn .health-dot {
  width: 10px; height: 10px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-a20); pointer-events: none;
}
/* The dot's colour (data-level): the worse of the quality state and the CPU pressure (device-health.js healthLevel) */
.health-btn[data-level="yellow"] .health-dot { background: var(--caution); box-shadow: 0 0 0 3px var(--caution-a25); }
.health-btn[data-level="amber"] .health-dot { background: var(--warn); box-shadow: 0 0 0 3px var(--warn-a25); }
.health-btn[data-level="red"] .health-dot { background: var(--danger); box-shadow: 0 0 0 3px var(--danger-a20); }
.health-overlay {
  position: absolute; top: var(--sp-6); left: 50%; transform: translateX(-50%); z-index: 95; margin: 0; padding: var(--sp-3) var(--sp-4);
  background: var(--glass-bg); backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-line); border-radius: var(--r-md); box-shadow: var(--glass-shadow);
  font-family: var(--mono); font-size: var(--fs-xs); line-height: 1.45; color: var(--text); white-space: pre; pointer-events: none;
}
.health-overlay[hidden], .health-notice[hidden], .health-toast[hidden] { display: none; }
.health-notice {
  position: absolute; top: 76px; left: 50%; transform: translateX(-50%); z-index: 110; width: min(560px, calc(100vw - 48px));
  display: grid; grid-template-columns: 1fr auto; gap: var(--sp-2) var(--sp-4); align-items: start; padding: var(--sp-4) var(--sp-5);
  background: var(--glass-bg); backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-line); border-left: 3px solid var(--danger); border-radius: var(--r-md); box-shadow: var(--glass-shadow);
}
.health-notice-title { grid-column: 1; font-size: var(--fs-md); font-weight: 700; color: var(--text-strong); }
.health-notice-body { grid-column: 1; font-size: var(--fs-xs); line-height: 1.45; color: var(--text); }
.health-notice-close { grid-column: 2; grid-row: 1 / span 2; width: auto; height: 32px; padding: 0 var(--sp-5); font-size: var(--fs-xs); border: 1px solid var(--veil-15); }
.health-toast {
  position: absolute; top: 76px; left: 50%; transform: translateX(-50%); z-index: 110; padding: var(--sp-3) var(--sp-5);
  background: var(--glass-bg); backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-line); border-left: 3px solid var(--warn); border-radius: var(--r-md); box-shadow: var(--glass-shadow);
  font-size: var(--fs-xs); color: var(--text);
}

.glass-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 var(--sp-1) var(--accent-a15);
}

/* Hide native number spinners */
.glass-input::-webkit-outer-spin-button,
.glass-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.glass-input[type=number] {
  -moz-appearance: textfield;
}

.glass-input-group {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  background: var(--shade-20);
  border-radius: var(--r-lg);
  padding: var(--sp-1);
  border: 1px solid var(--veil-05);
}

.glass-spin-btn {
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  width: var(--icon-size);
  height: var(--icon-size);
  border-radius: var(--r-xs);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all var(--t-mid) ease;
}

.glass-spin-btn i {
  width: 14px;
  height: 14px;
}

.glass-spin-btn:hover {
  background: var(--veil-10);
  color: var(--text);
}

.glass-spin-btn:active {
  background: var(--veil-05);
  transform: scale(0.95);
}

.glass-input-group .glass-input {
  background: transparent;
  border: none;
  width: 44px;
  padding: var(--sp-2);
  box-shadow: none !important;
}

/* Time Play: both icons are rendered; the button's state shows one */
#btn-time-play .icon-playing { display: none; }
#btn-time-play.playing .icon-playing { display: block; }
#btn-time-play.playing .icon-paused { display: none; }

/* Time of Day Panel */
#time-panel {
  transform-origin: right center;
  animation: slideInRight var(--t) var(--ease-pop) forwards;
}
@keyframes slideInRight {
  from { opacity: 0; transform: translateX(10px) scale(0.95); }
  to { opacity: 1; transform: translateX(0) scale(1); }
}

/* Wall display option flyout */
#wall-display-panel button {
  width: -webkit-fill-available;
}

/* The selected placed fixture's group (fixtures F2): a value of the placement's own, and the picked colour. */
#fixture-context .fx-own { box-shadow: inset 0 0 0 1px var(--accent); }
#fixture-context .fx-sw[aria-pressed="true"] { outline: 2px solid var(--accent); outline-offset: 1px; }

/* The Game textures tool (T4 round 8) is the new shell's: hidden here, in the current (classic) UI, shown by the shell's section below */
#tex-area-row, #tex-area-note { display: none; }

/* ── The new shell (UI phase P2): shown with ?ui=next (ui/flag.js marks <html data-ui="next">) ── */
/* Every rule below matches only in the new shell: its own .tn- elements, or [data-ui="next"]. */
html[data-ui="next"] [hidden] { display: none !important; }
html[data-ui="next"] .right-strip,
html[data-ui="next"] .bottom-strip,
html[data-ui="next"] #bt-export-wrap,
html[data-ui="next"] #canvas-hint { display: none; }
html[data-ui="next"] #storey-warning { top: var(--shell-below); }
html[data-ui="next"] #wall-warning { top: calc(var(--shell-below) + 34px); }
html[data-ui="next"] #asset-loading { top: calc(var(--shell-below) + 68px); }
html[data-ui="next"] #bt-export-flyout { z-index: 120; }
/* The gallery and the catalog card sit in the left stack (.tn-left), under the flyout and the Options card: they take what height is left and scroll */
html[data-ui="next"] .tn-left > .left-gallery { position: relative; top: auto; left: auto; transform: none; width: 100%; max-height: none; box-sizing: border-box; flex: 0 1 auto; min-height: 0; }
/* A card never renders smaller than its content (UX round R0, 1 Nov 2026): the Options card does not shrink; it scrolls inside a max height
   tied to the window (what is left under the cards above it, less the gallery's or the catalog card's least height when one is open), and the
   gallery or the catalog card gives up its height first. (--tn-above-h: the height of the cards above it, set by ui/shell.js.) */
html[data-ui="next"] .tn-left > .tn-options { flex: 0 0 auto; min-height: 0; }
.tn-left { --tn-below-reserve: 0px; }
.tn-left:has(> .left-gallery[style*="display: flex"]), .tn-left:has(> .tn-catalog:not([hidden])) { --tn-below-reserve: calc(128px + var(--gap-in)); }   /* the least the gallery keeps, when the window has it */
html[data-ui="next"] #prop-tint-panel { bottom: 16px !important; }   /* no dock under it */

.tn-glass {
  position: absolute;
  z-index: 105;
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-line);
  border-radius: var(--r-xl);
  box-shadow: var(--glass-shadow);
  color: var(--text);
  font-family: var(--ui);
}
.tn-cat:focus-visible, .tn-util:focus-visible, .tn-export:focus-visible, .tn-tool:focus-visible,
.tn-level:focus-visible, .tn-mini-btn:focus-visible, .tn-seg button:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

.tn-brand { display: flex; align-items: center; gap: var(--sp-3); font-size: var(--fs-lg); font-weight: 700; letter-spacing: 0.03em; color: var(--text-strong); white-space: nowrap; }
.tn-brand-mark { width: 12px; height: 12px; border-radius: var(--r-2xs); background: var(--accent); transform: rotate(45deg); box-shadow: 0 0 10px var(--accent-a55); }
.tn-field {
  height: 30px; padding: 0 var(--sp-3);
  background: var(--shade-30); border: 1px solid var(--veil-10); border-radius: var(--r-md);
  color: var(--text); font-family: var(--ui); font-size: var(--fs-md); outline: none;
  transition: border-color var(--t-mid), box-shadow var(--t-mid);
}
.tn-field:hover { border-color: var(--veil-20); }
.tn-field:focus { border-color: var(--accent); box-shadow: 0 0 0 var(--sp-1) var(--accent-a15); }
.tn-project { width: 168px; min-width: 72px; flex: 0 1 auto; }
.tn-saved { font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; }
.tn-saved.dirty { color: var(--warn); }


/* View cluster */
.tn-view { position: absolute; z-index: 105; top: var(--shell-below); right: var(--shell-edge); width: auto; display: flex; flex-direction: column; align-items: flex-end; gap: var(--gap-out); }
/* The view cluster: its buttons in rows of four (the 8 of the 3D view: two rows), right-aligned under Undo / Redo / Export */
.tn-view-row { display: grid; grid-template-columns: repeat(4, var(--util-btn)); justify-content: end; gap: var(--gap-in); }
html[data-ui="next"] .tn-view-row .glass-btn {
  width: var(--util-btn); height: var(--util-btn); padding: 0; border-radius: var(--r-btn); border: none;
  background: var(--float-bg); color: var(--float-text); box-shadow: var(--float-shadow), var(--float-hi);
}
html[data-ui="next"] .tn-view-row .glass-btn svg { width: var(--util-icon); height: var(--util-icon); }
html[data-ui="next"] .tn-view-row .glass-btn.active, html[data-ui="next"] .tn-view-row .glass-btn[aria-pressed="true"] { background: var(--accent); color: var(--float-on-accent); }
/* A split button: the body acts, the arrow in its corner opens the options (the Ghosts button of the view cluster). The arrow is its own control (focusable, labelled), not a nested one. */
.tn-split { position: relative; display: block; width: var(--util-btn); height: var(--util-btn); }
.tn-split-more {
  position: absolute; right: 3px; bottom: 3px; width: 18px; height: 18px; padding: 0; display: flex; align-items: center; justify-content: center;
  border: none; border-radius: var(--r-xs); background: var(--shade-30); color: var(--float-text); cursor: pointer;
}
.tn-split-more svg { width: 14px; height: 14px; }
.tn-split-more:hover, .tn-split-more[aria-expanded="true"] { background: var(--shade-50); }
.tn-split-more:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.tn-levels-card { position: relative; width: 236px; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--sp-3); padding: var(--sp-3); }
.tn-levels-head { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-1) var(--sp-2) 0; }
.tn-caption { font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.tn-levels-head .tn-caption { flex: 1; }
.tn-mini-btn {
  width: 26px; height: 26px; display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--veil-10); border-radius: var(--r-xs); background: var(--veil-05); color: var(--text); cursor: pointer;
}
.tn-mini-btn svg { width: 14px; height: 14px; }
.tn-mini-btn:hover { background: var(--veil-15); }
.tn-mini-btn:disabled { opacity: 0.35; cursor: default; }
.tn-levels { display: flex; flex-direction: column; gap: var(--sp-1); max-height: calc(0.3 * var(--tn-vh)); overflow-y: auto; }
.tn-level {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); min-height: 32px; padding: 0 var(--sp-3);
  border: none; border-radius: var(--r-md); background: transparent; color: var(--text); font-family: var(--ui); cursor: pointer;
}
.tn-level:hover { background: var(--veil-10); }
.tn-level.active { background: var(--accent-a20); color: var(--accent); }
.tn-level-name { font-family: var(--mono); font-size: var(--fs-md); font-weight: 700; }
.tn-level-meta { font-size: var(--fs-xs); color: var(--muted); }
.tn-level-row { display: flex; align-items: center; gap: var(--sp-2); }
.tn-level-row .tn-level { flex: 1; min-width: 0; }
.tn-level-del {
  flex: none; width: 28px; height: 28px; display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--danger-a20); border-radius: var(--r-xs); background: transparent; color: var(--danger); cursor: pointer;
}
.tn-level-del svg { width: 15px; height: 15px; }
.tn-level-del:hover { background: var(--danger-a20); }
.tn-level-del:focus-visible { outline: 2px solid var(--danger); outline-offset: 2px; }
.tn-level-del[aria-disabled="true"] { opacity: 0.35; cursor: not-allowed; background: transparent; }
/* The ghost level's row: the empty level above the top one, built by the first thing placed on it */
.tn-level.ghost { opacity: 0.55; border: 1px dashed var(--veil-20); }
.tn-level.ghost .tn-level-meta { font-style: italic; }
.tn-level.ghost.active { opacity: 0.8; border-color: var(--accent); }
.tn-level-del-spacer { flex: none; width: 28px; }
/* The question before a level is deleted: beside its row, left of the view cluster */
.tn-confirm { position: fixed; z-index: 120; width: 300px; padding: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-3); }
.tn-confirm-title { font-weight: 700; font-size: var(--fs-md); color: var(--text-strong); }
.tn-confirm-text { margin: 0; font-size: var(--fs-sm); line-height: 1.45; color: var(--text); }
.tn-confirm-actions { display: flex; flex-direction: column; gap: var(--sp-2); }
.tn-confirm-btn {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px; padding: 7px var(--sp-4); text-align: left;
  border: 1px solid var(--veil-10); border-radius: var(--r-md); background: var(--veil-05); color: var(--text);
  font-family: var(--ui); font-size: var(--fs-sm); cursor: pointer;
}
.tn-confirm-btn:hover { background: var(--veil-15); }
.tn-confirm-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tn-confirm-btn.primary { border-color: var(--accent-a55); }
.tn-confirm-btn.danger { border-color: var(--danger); color: var(--danger); }
.tn-confirm-btn.danger:hover { background: var(--danger-a20); }
.tn-confirm-btn.danger:focus-visible { outline-color: var(--danger); }
.tn-confirm-btn:disabled { opacity: 0.4; cursor: default; }
.tn-confirm-label { font-weight: 600; }
.tn-confirm-detail { font-size: var(--fs-xs); color: var(--muted); }
/* WL6: Edit all / Make this one unique sits top centre; the selected lot's chip sits in Lots › Select's card (3D since 27 Oct 2026). */
.tn-confirm.tn-lot-share { top: 72px; left: 50%; transform: translateX(-50%); width: 320px; }
/* WL9: World's home card, at the right under the view cluster where the plan tool's options card sits (the confirm card's buttons):
   the view's middle and the palette stay clear; its gallery scrolls inside the window's height */
.tn-confirm.tn-home { top: calc(var(--shell-below) + 96px); right: var(--shell-edge); left: auto; width: 320px; max-height: calc(100vh - var(--shell-below) - 160px); overflow: auto; }
.tn-confirm.tn-home[hidden] { display: none; }
.tn-home-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.tn-home-gallery { display: flex; flex-direction: column; gap: var(--sp-2); }
.tn-home-gallery[hidden] { display: none; }
.tn-home-map { display: flex; align-items: flex-start; gap: var(--sp-3); padding: var(--sp-2); border: 1px solid var(--veil-10); border-radius: var(--r-md); background: var(--veil-05); }
.tn-home-map-text { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; font-size: var(--fs-sm); }
.tn-home-map-name { font-weight: 600; color: var(--text-strong); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tn-home-map-meta { font-size: var(--fs-xs); color: var(--muted); }
.tn-home-site { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); font-size: var(--fs-xs); color: var(--text); }
.tn-home-site .tn-link-btn, .tn-home-open { font-size: var(--fs-xs); }
.tn-home-thumb { flex: none; }
.tn-home-thumb-bg { fill: var(--shade-30); stroke: var(--veil-10); }
.tn-home-thumb-site { fill: var(--warn-a25); stroke: var(--warn); stroke-width: 1; }
.tn-wm-lot-chip { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); white-space: nowrap; font-size: var(--fs-sm); }
.tn-wm-lot-chip[hidden] { display: none; }
.tn-wm-lot-chip-name { font-weight: 600; color: var(--text-strong); }
.tn-wm-lot-edit { display: inline-flex; align-items: center; gap: var(--sp-2); padding: 4px var(--sp-3); border: 1px solid var(--accent-a55); border-radius: var(--r-md); background: var(--veil-05); color: var(--text); font-family: var(--ui); font-size: var(--fs-sm); cursor: pointer; }
.tn-wm-lot-edit:hover, .tn-wm-lot-follow:hover { background: var(--veil-15); }
.tn-wm-lot-base { display: inline-flex; align-items: center; gap: var(--sp-2); color: var(--muted); font-size: var(--fs-xs); }
.tn-wm-lot-base input { width: 72px; padding: 3px var(--sp-2); font-size: var(--fs-sm); }
.tn-wm-lot-follow { padding: 4px var(--sp-3); border: 1px solid var(--veil-10); border-radius: var(--r-md); background: var(--veil-05); color: var(--text); font-family: var(--ui); font-size: var(--fs-xs); cursor: pointer; }
.tn-wm-lot-follow[aria-pressed="true"] { border-color: var(--accent-a55); background: var(--accent-a30); color: var(--text-strong); }
.tn-wm-lot-follow:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tn-wm-lot-edit:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tn-wm-lot-edit kbd { padding: 0 var(--sp-2); border-radius: var(--r-key); background: var(--shade-30); color: var(--muted); font-family: var(--mono); font-size: var(--fs-2xs); line-height: 16px; }
.tn-storey { border-top: 1px solid var(--veil-10); padding-top: var(--sp-2); }
html[data-ui="next"] .tn-storey > div { padding: var(--sp-2) !important; }
html[data-ui="next"] .tn-storey label { white-space: nowrap; }
.tn-dev-group { display: flex; flex-direction: column; gap: var(--sp-1); align-self: stretch; }
.tn-prefs { display: flex; flex-direction: column; gap: var(--sp-2); align-self: stretch; padding: var(--sp-3) var(--sp-4); border-top: 1px solid var(--veil-10); }
.tn-prefs h3 { margin: 0; font-size: var(--fs-2xs); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.tn-prefs-row { display: flex; flex-direction: column; gap: var(--sp-1); }
.tn-prefs-row > label, .tn-prefs-row > .tn-prefs-name { font-size: var(--fs-xs); color: var(--text); }
.tn-prefs .tn-seg button { flex: 1 1 0; min-width: 0; padding: 0 var(--sp-2); height: 26px; white-space: nowrap; }
/* The Settings card (WL1b): see "One home per control" at the end of this file */

/* The left stack (floating tool UI, owner 27 Oct 2026; no bottom dock): under the category column's top, right of it: the flyout (a grid),
   the active tool's Options card (shown only while a group of it is), the catalog card or the Textures gallery. One column, 8 px apart. */
.tn-left {
  position: absolute; z-index: 105; top: var(--shell-below); left: calc(var(--shell-edge) + var(--cat-btn) + 2 * var(--gap-in) + var(--gap-out));
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--gap-in);
  max-height: calc(var(--tn-vh) - var(--shell-below) - var(--shell-edge)); width: max-content; max-width: 320px; pointer-events: none;
}
html[data-ui="next"] .tn-left > * { pointer-events: auto; flex: none; position: relative; top: auto; left: auto; right: auto; transform: none; }
.tn-left button, .tn-left select { font-family: var(--ui); }   /* the moved option groups' buttons too: never the browser's font */
.tn-tool {
  position: relative; width: 32px; height: 30px; display: flex; align-items: center; justify-content: center;
  border: none; border-radius: var(--r-md); background: transparent; color: var(--muted); cursor: pointer;
  font-family: var(--ui); font-size: var(--fs-xs); font-weight: 600; line-height: 1;
  transition: background var(--t-fast), color var(--t-fast);
}
.tn-tool svg { width: 17px; height: 17px; }
.tn-tool:hover { background: var(--veil-10); color: var(--text); }
.tn-tool.active { background: var(--accent-a20); color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent-a30); }
.tn-tool-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.tn-tool-key { position: absolute; top: -1px; right: 1px; font-family: var(--mono); font-size: var(--fs-2xs); color: var(--text-disabled); }
.tn-tool.active .tn-tool-key { color: var(--accent); }
.tn-soon { cursor: not-allowed; }
.tn-soon svg { opacity: 0.4; }
.tn-soon:hover { background: transparent; color: var(--muted); }
.tn-soon-badge { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.tn-soon[data-tip]:hover::after, .tn-soon[data-tip]:focus-visible::after {
  content: attr(data-tip); position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%); z-index: 2;
  padding: var(--sp-2) var(--sp-3); border-radius: var(--r-xs); background: var(--shade-80); border: 1px solid var(--veil-15);
  color: var(--text-strong); font-size: var(--fs-xs); font-weight: 600; white-space: nowrap; pointer-events: none;
}
.tn-pair { display: inline-flex; align-items: center; gap: var(--sp-3); white-space: nowrap; }
.tn-crumb { font-size: var(--fs-md); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tn-crumb b { color: var(--text-strong); font-weight: 600; }
.tn-cat-count { margin-left: auto; font-family: var(--mono); font-size: var(--fs-xs); color: var(--text-disabled); white-space: nowrap; }

/* The Options card: the active tool's groups, stacked (a bar of the dock's width wrapped in rows before): sliders keep their value boxes */
.tn-options {
  display: flex; flex-direction: column; align-items: stretch; gap: var(--sp-3); width: auto; align-self: stretch; box-sizing: border-box;
  padding: var(--sp-4); overflow-y: auto; min-width: 0;
  max-height: max(120px, calc(var(--tn-vh) - var(--shell-below) - var(--shell-edge) - var(--tn-above-h, 300px) - var(--gap-in) - var(--tn-below-reserve)));
}
html[data-ui="next"] .tn-options > div { margin-left: 0 !important; flex-wrap: wrap; }
html[data-ui="next"] .tn-options > div > .glass-sep:first-child,
html[data-ui="next"] #tile-target-context > .glass-input-group { display: none; }
.tn-options .tn-land, .tn-options .tn-land .tn-ctx, .tn-options #tn-land-context { justify-content: flex-start; }
.tn-options #tn-land-brush[style*="flex"], .tn-options #tn-land-genbar { display: contents !important; }
.tn-options #tn-land-context { flex-direction: column; align-items: stretch; gap: var(--sp-3); padding-bottom: 0; }
.tn-options .tn-land-val#tn-land-readout { width: auto; text-align: left; }
.tn-options .tn-nf { gap: 4px; }
.tn-options .tn-nf-slider { width: 88px; }
.tn-options .tn-nf-box { width: 62px; }
/* The card hugs its content (the stack is as wide as its widest card, 320 px at most) and is never narrower than the flyout above it
   (the stack's own width is at least the flyout's); the catalog card and the gallery keep their 276 px. */
html[data-ui="next"] .tn-left > .left-gallery, .tn-left > .tn-catalog { width: 276px; }
/* The terrain brush's Size, Strength, Falloff and Hardness: two to a row, the caption over its slider and box */
.tn-options #tn-land-context { flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--sp-1) var(--sp-3); }
.tn-options #tn-land-context > *, .tn-options #tn-land-brush > *, .tn-options #tn-land-genbar > * { flex: 1 1 100%; min-width: 0; }
.tn-options #tn-land-genbar > .tn-land-btn { flex: 0 0 auto; }
.tn-options #tn-land-context .tn-nf-half { flex: 1 1 calc(50% - var(--sp-3)); display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 0 var(--sp-2); }
.tn-options #tn-land-context .tn-nf-half-low { margin-top: 6px; }   /* the first pair's step buttons (below the boxes) clear the second pair's (above) */
.tn-options #tn-land-brush > .tn-nf > .tn-nf-label { grid-column: 1; grid-row: 1; }
.tn-options #tn-land-brush > .tn-nf > .tn-nf-extra { grid-column: 2; grid-row: 1; width: auto; text-align: right; }
.tn-options #tn-land-brush > .tn-nf > .tn-nf-slider { grid-column: 1; grid-row: 2; width: auto; min-width: 0; }
.tn-options #tn-land-brush > .tn-nf > .tn-nf-box { grid-column: 2; grid-row: 2; }

/* The catalog card: the Textures gallery's own panel (a column of 2-up tiles) with a head, a category menu and the pick */
.tn-catalog { display: flex; flex-direction: column; width: 100%; box-sizing: border-box; padding: var(--sp-3); gap: var(--sp-3); min-height: 0; flex: 0 1 auto; }
.tn-catalog-head { display: flex; align-items: center; gap: var(--sp-3); margin: 0; padding: var(--sp-2) var(--sp-3); }
.tn-catalog-bar { display: flex; flex-direction: column; gap: var(--sp-3); }
.tn-catalog-bar .tn-select { width: 100%; }
.tn-cat-switch { display: grid; grid-template-columns: 1fr 1fr; }
.tn-cat-grid { min-height: 72px; }
.tn-tile .tn-tile-thumb { position: absolute; inset: 0; display: grid; place-items: center; background: var(--thumb-bg); }
.tn-tile-ph { font-family: var(--ui); font-size: var(--fs-lg); font-weight: 700; letter-spacing: 0.04em; color: var(--veil-30); }
.tn-tile .tn-tile-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tn-tile-badge { position: absolute; left: 5px; top: 5px; padding: 1px 5px; border-radius: var(--r-sm); background: var(--shade-60); font-size: var(--fs-2xs); font-weight: 600; color: var(--text); }
.tn-tile-badge.own { color: var(--accent); }
.tn-tile-badge.cc0, .tn-tile-badge.ccby { color: var(--cc0); }
.tn-tile-missing { position: absolute; right: 5px; bottom: 5px; padding: 1px 5px; border-radius: var(--r-sm); background: var(--shade-60); font-size: var(--fs-2xs); color: var(--danger); }
.tn-tile .item-label { z-index: 1; }
.tn-empty { margin: 0; padding: var(--sp-3); font-size: var(--fs-sm); line-height: 1.45; color: var(--muted); }
.tn-pick { display: flex; flex-direction: column; gap: var(--sp-2); flex: none; padding: var(--sp-2) var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--glass-line); }
.tn-pick-head { display: flex; align-items: center; gap: var(--sp-3); }
.tn-pick-name { flex: 1; min-width: 0; font-size: var(--fs-md); font-weight: 600; color: var(--text-strong); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tn-pick-actions { display: flex; align-items: center; gap: var(--sp-4); }
.tn-pick-meta { flex: 1; min-width: 0; font-family: var(--mono); font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tn-tag { padding: 1px 6px; border: 1px solid var(--veil-15); border-radius: var(--r-sm); font-size: var(--fs-2xs); font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); }
.tn-tag.own { color: var(--accent); border-color: var(--accent-a30); }
.tn-tag.cc0, .tn-tag.ccby { color: var(--cc0); border-color: var(--cc0-a35); }
.tn-ctx { display: flex; align-items: center; gap: var(--sp-3); }
.tn-seg { display: flex; gap: var(--sp-1); padding: var(--sp-1); background: var(--shade-20); border: 1px solid var(--veil-05); border-radius: var(--r-lg); }
.tn-seg button {
  height: 28px; padding: 0 var(--sp-4); border: none; border-radius: var(--r-md); background: transparent; color: var(--muted);
  font-family: var(--ui); font-size: var(--fs-xs); font-weight: 600; cursor: pointer;
}
.tn-seg button:hover { color: var(--text); background: var(--veil-05); }
.tn-seg button[aria-pressed="true"] { color: var(--accent); background: var(--accent-a20); }
.tn-select { width: auto; font-size: var(--fs-xs); padding: var(--sp-2) var(--sp-3); }

/* Floating tips (ui/tips.js): cards at the bottom right (no dock under them), two at most */
.tn-tips {
  position: absolute; right: var(--shell-edge); bottom: var(--shell-edge); z-index: 104; width: 272px;
  display: flex; flex-direction: column; gap: var(--sp-3); pointer-events: none;
}
.tn-world-on .tn-tips { right: calc(var(--shell-edge) + 252px + var(--sp-4)); }   /* World mode: left of the World panel */
.tn-tip {
  display: flex; align-items: flex-start; gap: var(--sp-3); padding: var(--sp-3) var(--sp-4);
  background: var(--glass-bg); backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-line); border-radius: var(--r-xl); box-shadow: var(--glass-shadow);
  color: var(--text); font-family: var(--ui); font-size: var(--fs-sm); line-height: 1.35;
  opacity: 0; transform: translateY(6px); transition: opacity var(--t) var(--ease-glass), transform var(--t) var(--ease-pop);
}
.tn-tip.tn-tip-in { opacity: 1; transform: none; }
.tn-tip-mark {
  flex: none; width: 18px; height: 18px; margin-top: 1px; border-radius: 50%; display: grid; place-items: center;
  font-size: var(--fs-2xs); font-weight: 700; color: var(--accent); background: var(--accent-a20);
}
.tn-tip-refusal { border-color: var(--danger); background: linear-gradient(var(--danger-a20), var(--danger-a20)), var(--glass-bg); color: var(--text-strong); }
.tn-tip-refusal .tn-tip-mark { color: var(--danger); background: var(--danger-a20); }
/* A burst of refusals: the first two are cards, the rest are this count; hovering (or focusing) it lists them, left of the cards */
.tn-tip-more {
  align-self: flex-end; pointer-events: auto; cursor: default; outline: none;
  padding: var(--sp-1) var(--sp-3); border: 1px solid var(--danger); border-radius: var(--r-xl); color: var(--text-strong);
  background: linear-gradient(var(--danger-a20), var(--danger-a20)), var(--glass-bg); font: var(--fs-xs) var(--ui);
}
.tn-tip-more[hidden] { display: none; }
.tn-tip-more-list {
  display: none; position: absolute; right: calc(100% + var(--sp-3)); bottom: 0; width: 272px; flex-direction: column; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4); background: var(--glass-bg); backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--danger); border-radius: var(--r-xl); box-shadow: var(--glass-shadow); font-size: var(--fs-sm); line-height: 1.35;
}
.tn-tip-more:hover .tn-tip-more-list, .tn-tip-more:focus .tn-tip-more-list { display: flex; }
@media (prefers-reduced-motion: reduce) { .tn-tip { transition: opacity var(--t-fast) linear; transform: none; } }

/* Shortcut sheet */
.tn-sheet {
  position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 130;
  width: min(780px, calc(var(--tn-vw) - 48px)); max-height: calc(var(--tn-vh) - 160px);
  flex-direction: column; gap: var(--sp-4); padding: var(--sp-5) var(--sp-6); overflow: hidden;
}
.tn-sheet-title { font-size: var(--fs-lg); font-weight: 700; color: var(--text-strong); }
.tn-sheet-body { columns: 2 300px; column-gap: var(--sp-6); overflow-y: auto; }
.tn-sheet-sec { break-inside: avoid; margin-bottom: var(--sp-5); }
.tn-sheet-sec h3 { margin-bottom: var(--sp-3); font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.tn-sheet-row { display: flex; align-items: baseline; gap: var(--sp-4); padding: 3px 0; }
.tn-sheet-row dt { flex: 0 0 150px; }
.tn-sheet-row dd { font-size: var(--fs-sm); color: var(--text); }
.tn-sheet kbd {
  display: inline-block; padding: 1px var(--sp-2); border: 1px solid var(--veil-15); border-radius: var(--r-xs);
  background: var(--veil-10); color: var(--text-strong); font-family: var(--mono); font-size: var(--fs-xs); font-weight: 600;
}

/* Device health in the shell: the notes and the stats overlay under the top bar */
html[data-ui="next"] .health-notice, html[data-ui="next"] .health-toast, html[data-ui="next"] .health-overlay { top: calc(var(--shell-below) + 8px); }
/* World mode (5): the map of the target game build over the viewport (world/world-view.js) */
.tn-world { position: fixed; inset: 0; z-index: 104; }
.tn-world[hidden] { display: none; }
.tn-world-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; cursor: grab; touch-action: none; }
.tn-world-canvas:active { cursor: grabbing; }
.tn-world-canvas.placing { cursor: crosshair; }
.tn-world-canvas.focusing { cursor: crosshair; }   /* the Focus tool: a click jumps the 3D view there */
.tn-world-labels { position: absolute; inset: 0; width: 100%; height: 100%; display: block; pointer-events: none; }
.tn-world-labels[hidden] { display: none; }
html[data-ui="next"] .tn-world-on .tn-view { display: none; }
.tn-world-badge {
  top: calc(var(--shell-below) + 64px); left: var(--shell-edge); padding: var(--sp-2) var(--sp-4);
  font-size: var(--fs-xs); font-weight: 600; color: var(--accent); border-left: 3px solid var(--accent);
}
.tn-world-badge.err { color: var(--danger); border-left-color: var(--danger); }
.tn-world-panel {
  top: var(--shell-below); right: var(--shell-edge); width: 252px; max-height: calc(var(--tn-vh) - var(--shell-below) - 60px); overflow-y: auto;
  padding: var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-3);
}
.tn-world-build { width: 100%; }
.tn-world-layers { display: flex; flex-direction: column; gap: var(--sp-1); }
.tn-world-layer { display: flex; align-items: center; gap: var(--sp-3); font-size: var(--fs-sm); color: var(--text); cursor: pointer; padding: 2px 0; }
.tn-world-layer input { margin: 0; }
.tn-world-layer[hidden] { display: none; }
.tn-world-advanced { margin-top: var(--sp-2); padding-top: var(--sp-2); border-top: 1px solid var(--veil-10); }
.tn-world-swatch { width: 12px; height: 12px; border-radius: var(--r-xs); flex: none; }
.tn-world-count { margin-left: auto; font-family: var(--mono); font-size: var(--fs-xs); color: var(--muted); }
.tn-world-layer.missing { opacity: 0.45; cursor: not-allowed; }   /* a layer the loaded world database lacks */
.tn-world-site { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); }
.tn-world-site label { display: flex; flex-direction: column; gap: 2px; font-size: var(--fs-xs); color: var(--muted); }
.tn-world-site .glass-input { width: 100%; padding: var(--sp-2); font-size: var(--fs-xs); }
.tn-world-warnings { margin: 0; padding: 0; list-style: none; font-size: var(--fs-xs); color: var(--muted); display: flex; flex-direction: column; gap: 2px; }
.tn-world-warnings .warn { color: var(--warn); }
.tn-world-regions { font-size: var(--fs-xs); color: var(--text); line-height: 1.4; }
.tn-world-clear-sel { width: 100%; height: 30px; font-size: var(--fs-xs); justify-content: center; }
/* Saved world maps (worldmaps/worldmaps-view.js): the Maps list and the open map's tools, at the top of the World panel. */
.tn-wm, .tn-wm-open, .tn-wm-form { display: flex; flex-direction: column; gap: var(--sp-2); }
.tn-wm[hidden], .tn-wm-open[hidden], .tn-wm-form[hidden] { display: none; }
.tn-wm { padding-bottom: var(--sp-3); border-bottom: 1px solid var(--border); }
.tn-wm-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.tn-wm-row .tn-select { flex: 1; min-width: 0; }
.tn-wm-btn { height: 28px; padding: 0 var(--sp-3); font-size: var(--fs-xs); font-weight: 600; justify-content: center; white-space: nowrap; }
.tn-wm-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.tn-wm-wide { width: 100%; }
.tn-wm .glass-input { font-size: var(--fs-xs); padding: var(--sp-2); }
.tn-wm-list { display: flex; flex-direction: column; gap: var(--sp-1); }
.tn-wm-item { display: flex; flex-wrap: wrap; align-items: center; gap: 2px var(--sp-2); font-size: var(--fs-xs); color: var(--text); line-height: 1.4; }
.tn-wm-item.flagged { border-left: 2px solid var(--danger); padding-left: var(--sp-2); }
.tn-wm-item .tn-link-btn { font-size: var(--fs-xs); }
.tn-wm-note { font-size: var(--fs-xs); color: var(--muted); line-height: 1.4; }
.tn-wm-note.warn, .tn-wm-note[data-kind="warn"] { color: var(--warn); }
.tn-wm-note.err, .tn-wm-note[data-kind="err"] { color: var(--danger); }
.tn-wm-note[data-kind="ok"] { color: var(--accent); }
.tn-status-map { color: var(--accent); font-size: var(--fs-xs); }
.tn-status-map:empty { display: none; }
.tn-land-val#tn-land-draft:empty { display: none; }
.tn-world-tip { position: absolute; z-index: 106; max-width: 260px; padding: var(--sp-3) var(--sp-4); font-size: var(--fs-xs); line-height: 1.45; pointer-events: none; }
.tn-world-tip[hidden] { display: none; }
.tn-world-tip-title { font-weight: 700; color: var(--text-strong); font-size: var(--fs-sm); }
.tn-world-tip-src { margin-top: var(--sp-1); color: var(--muted); font-style: italic; }
/* The Land mode's Options card (terrain editor T1): the site form, the brush bar, the editing aids. */
.tn-land, .tn-land .tn-ctx { flex-wrap: wrap; justify-content: center; gap: var(--sp-2) var(--sp-3); }
.tn-land-val { min-width: 40px; color: var(--muted); font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }
/* Fixed widths (owner's report, 22 Oct 2026): no readout, however long, moves the bar's other controls. */
.tn-land-val#tn-land-readout { width: 240px; min-width: 0; flex: none; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: center; }
/* The numeric field (ui/num-field.js): an exact box with its unit, step buttons floating above and below it, and a
   relative slider for coarse changes. Every part has a fixed width. */
.tn-nf { display: inline-flex; align-items: center; gap: 6px; flex: none; }
.tn-nf-slider { position: relative; display: flex; align-items: center; width: 60px; height: 22px; flex: none; cursor: ew-resize; touch-action: none; outline: none; border-radius: var(--r-sm); }
.tn-nf-track { position: relative; width: calc(100% - 12px); margin: 0 6px; height: 4px; border-radius: 2px; background: var(--veil-10); }
.tn-nf-fill { position: absolute; left: 0; top: 0; bottom: 0; width: calc(var(--p, 0) * 100%); border-radius: 2px; background: var(--accent); opacity: 0.7; }
.tn-nf-thumb { position: absolute; top: 50%; left: calc(var(--p, 0) * 100%); width: 12px; height: 12px; margin: -6px 0 0 -6px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 0 2px var(--shade-30); transition: box-shadow var(--t); }
.tn-nf-slider:hover .tn-nf-thumb, .tn-nf-slider:focus-visible .tn-nf-thumb, .tn-nf-slider.dragging .tn-nf-thumb { box-shadow: 0 0 0 4px var(--accent-a20); }
.tn-nf-slider:focus-visible { outline: 1px solid var(--accent-a55); outline-offset: 3px; }
.tn-nf-box { position: relative; display: inline-flex; align-items: center; width: 66px; flex: none; }
.tn-nf-box .glass-input.tn-nf-input { width: 100%; height: 24px; padding: 0 28px 0 4px; border-radius: var(--r-sm); font-size: var(--fs-xs); text-align: right; font-variant-numeric: tabular-nums; }
.tn-nf-unit { position: absolute; right: 0; width: 26px; padding-left: 2px; font-size: var(--fs-xs); color: var(--muted); text-align: left; white-space: nowrap; pointer-events: none; }
.tn-nf-step { position: absolute; left: 9px; right: 9px; height: 11px; padding: 0; display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--veil-15); border-radius: 6px; background: var(--glass-bg); color: var(--muted); cursor: pointer;
  transition: color var(--t), background var(--t), border-color var(--t), opacity var(--t); z-index: 2; opacity: 0; }
.tn-nf:hover .tn-nf-step, .tn-nf:focus-within .tn-nf-step { opacity: 0.85; }
.tn-nf-up { bottom: calc(100% + 2px); }
.tn-nf-down { top: calc(100% + 2px); }
.tn-nf .tn-nf-step:hover { opacity: 1; color: var(--accent); border-color: var(--accent-a55); background: var(--accent-a20); }
.tn-nf-step:active { background: var(--accent-a55); color: var(--text-strong); }
.tn-nf-step svg { width: 20px; height: 9px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.tn-nf-extra { width: 36px; min-width: 0; flex: none; }
.tn-land-btn { height: 30px; padding: 0 var(--sp-4); font-size: var(--fs-xs); font-weight: 600; }
.tn-land-sites { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.tn-land-sites:empty { display: none; }
.tn-land-site-row { display: inline-flex; align-items: center; gap: var(--sp-2); padding: 2px var(--sp-2) 2px var(--sp-3); border-radius: var(--r-md);
  background: var(--shade-20); border: 1px solid var(--veil-05); color: var(--muted); font-size: var(--fs-xs); }
.tn-land-aids { margin-left: var(--sp-3); }
.tn-land-swatch { display: inline-block; width: 12px; height: 12px; margin-right: var(--sp-2); vertical-align: -2px; border-radius: 3px;
  background-size: 48px 48px; border: 1px solid var(--veil-15); }
.tn-land-swatch.none { background: repeating-linear-gradient(45deg, var(--veil-05) 0 2px, transparent 2px 4px); }
/* The ground material library (round 4): one thumbnail per material, its name and surface beside the row. */
.tn-land-mats { flex-wrap: wrap; max-width: 520px; }
.tn-land-mats .tn-land-mat { position: relative; padding: 3px; line-height: 0; }
.tn-land-slots { display: inline-grid; grid-template-columns: 14px 14px; gap: 2px; padding: 2px; border-radius: var(--r-sm); background: var(--veil-05); }
.tn-land-slots .tn-land-swatch { width: 14px; height: 14px; margin: 0; vertical-align: 0; background-size: cover; }
.tn-land-mats .tn-land-swatch { width: 24px; height: 24px; margin: 0; vertical-align: 0; background-size: cover; border-radius: var(--r-sm); }
.tn-land-mats .tn-land-mat[aria-pressed="true"] .tn-land-swatch { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.tn-land-prov { position: absolute; right: 2px; top: 2px; width: 6px; height: 6px; border-radius: 50%; background: var(--warn); border: 1px solid var(--shade-20); }
.tn-land-val#tn-land-mat-name { width: 220px; min-width: 0; flex: none; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Land mode with no scene site (owner ruling 22 Oct: warn, don't block). */
.tn-land-notice { flex-basis: 100%; display: flex; align-items: center; justify-content: center; gap: var(--sp-3); padding: var(--sp-1) var(--sp-3);
  border-radius: var(--r-md); border: 1px solid var(--warn-a25); background: var(--shade-20); color: var(--warn); font-size: var(--fs-xs); }
.tn-land-notice[hidden] { display: none; }
.tn-link-btn { background: none; border: none; padding: 0; color: var(--accent); font: inherit; font-weight: 600; text-decoration: underline; cursor: pointer; }
.tn-link-btn:hover { color: var(--text-strong); }
.tn-link-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }

/* Terrain generation (TG1): the Layers popover, the Template row, the status and budget rows */
.tn-land-layers { position: fixed; top: 132px; right: 24px; z-index: 120; width: min(560px, calc(var(--tn-vw) - 48px)); max-height: calc(var(--tn-vh) - 200px); overflow-y: auto; flex-direction: column; gap: var(--sp-3); padding: var(--sp-4) var(--sp-5); }
.tn-land-layers-title { font-size: var(--fs-md); font-weight: 700; color: var(--text-strong); }
.tn-land-layers-site h3 { margin: 0 0 var(--sp-2); font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.tn-land-layer-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); padding: 2px 0; }
.tn-land-layer-name { flex: 1 1 200px; font-size: var(--fs-xs); color: var(--text); }
.tn-land-layer-row .tn-mini-btn { width: auto; padding: 0 var(--sp-2); font-size: var(--fs-xs); }
.tn-land-layer-row .tn-mini-btn[aria-pressed="true"] { color: var(--accent); }
.tn-land-layer-meta, .tn-land-layers-empty { font-size: var(--fs-xs); color: var(--muted); margin: 2px 0; }
/* The generation status shares the budget line's slot: while it has text (Checking the layers, Generating 37 %, a refusal) it takes the slot and the budget line steps aside,
   so the status is one line tall as well (clipped with an ellipsis, the whole text is its title) and the Layers row, the template card and Apply never move. */
.tn-land-val#tn-land-gen-status { display: block; box-sizing: border-box; height: 16px; line-height: 16px; max-width: 520px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tn-land-val#tn-land-gen-status:empty { display: none; }
.tn-land-val#tn-land-gen-status:not(:empty) ~ #tn-land-budget { display: none; }
/* The terrain budget line is a fixed slot: one line tall from the start (empty or filled, never wrapping), so the rows below it
   (the template card and its Apply) stay where they are when it fills or changes; the full detail is its title and description. */
.tn-land-val#tn-land-budget { display: block; box-sizing: border-box; height: 16px; line-height: 16px; max-width: 520px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* In the Options card it shares the Layers button's row (the row is the button's height whether the line is empty or full): no row of its own. */
.tn-options #tn-land-genbar > #tn-land-budget, .tn-options #tn-land-genbar > #tn-land-gen-status { flex: 1 1 0; align-self: center; }
.tn-land-val.tn-tpl-note { max-width: 360px; white-space: normal; color: var(--warn); }

/* ── The floating shell (WL1, owner rulings 25 Oct 2026) ──
 * Separate opaque surfaces over the 3D view: no shared background, no blur, soft shadows, 14 px buttons and 18 px cards,
 * 8 px between neighbours and 16 px between groups; the active tool filled with the accent. Icons only: the label is a
 * chip on hover (after 300 ms) or keyboard focus. The glass tokens are opaque in this shell, so the moved controls'
 * panels and flyouts are opaque too, without blur. */
html[data-ui="next"] {
  --glass-bg: var(--float-bg); --glass-bg-thin: var(--float-bg); --glass-blur: none; --glass-blur-sm: none;
  --glass-shadow: var(--float-shadow-card); --glass-line: var(--veil-05);
  --shell-below: 72px;
}
.tn-float {
  position: absolute; z-index: 105;
  background: var(--float-bg); color: var(--float-text); font-family: var(--ui);
  border: none; border-radius: var(--r-btn); box-shadow: var(--float-shadow), var(--float-hi);
}
.tn-card { border-radius: var(--r-card); box-shadow: var(--float-shadow-card), var(--float-hi); }
.tn-view > .tn-float, .tn-topright > .tn-float { position: relative; }
.tn-sheet.tn-float, .tn-confirm.tn-float { position: fixed; }
.tn-float.tn-util { background: var(--float-bg); }
html[data-ui="next"] .tn-tip, html[data-ui="next"] .tn-tip-more-list { border-radius: var(--r-card); }
/* Top left: the project chip, the category column, the strip beside it */
.tn-cats { z-index: 107; top: var(--shell-below); left: var(--shell-edge); display: flex; flex-direction: column; gap: var(--gap-in); padding: var(--gap-in); border-radius: var(--r-card); }
/* The flyout: a grid, 2 columns by default (ui/shell.js sets --tn-strip-cols from the rail's height), row-major in the strip's order */
.tn-strip { display: block; width: max-content; padding: var(--gap-in); border-radius: var(--r-card); }
.tn-strip-list { display: grid; grid-template-columns: repeat(var(--tn-strip-cols, 2), var(--tool-btn)); gap: var(--gap-in); }
.tn-gap { flex: none; width: var(--gap-in); height: var(--tool-btn); }   /* a separator: the group gap (8 + 8 + 8 = 24 px between groups) */
.tn-cat, .tn-tool, .tn-util {
  position: relative; display: flex; align-items: center; justify-content: center; flex: none;
  border: none; border-radius: var(--r-btn); background: transparent; color: var(--float-text); cursor: pointer;
  font-family: var(--ui); font-size: var(--fs-xs); font-weight: 600; line-height: 1;
  transition: background var(--t-fast), color var(--t-fast), transform var(--t-fast), box-shadow var(--t-fast);
}
.tn-cat { width: var(--cat-btn); height: var(--cat-btn); }
.tn-cat svg { width: var(--cat-icon); height: var(--cat-icon); }
.tn-tool { width: var(--tool-btn); height: var(--tool-btn); }
.tn-tool svg { width: var(--tool-icon); height: var(--tool-icon); }
.tn-util { width: var(--util-btn); height: var(--util-btn); }
.tn-util svg { width: var(--util-icon); height: var(--util-icon); }
.tn-cat:hover, .tn-tool:hover, .tn-util:not(:disabled):hover { background: var(--veil-10); }
.tn-cat.active, .tn-tool.active { background: var(--accent); color: var(--float-on-accent); box-shadow: 0 2px 8px var(--shade-30); }
.tn-cat:active, .tn-tool:active { transform: translateY(1px); }
.tn-util:disabled { opacity: 0.38; cursor: default; }
.tn-tool-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.tn-tool-key {
  position: absolute; top: 3px; right: 4px; padding: 0 3px; border-radius: var(--r-key);
  font-family: var(--mono); font-size: var(--fs-2xs); line-height: 13px; color: var(--muted); background: var(--shade-30);
}
.tn-tool.active .tn-tool-key { color: var(--float-on-accent); background: var(--veil-30); }
.tn-soon { cursor: not-allowed; }
.tn-soon svg { opacity: 0.4; }
.tn-soon:hover { background: transparent; }
.tn-soon-badge { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
/* The label chip: beside a category (right), under a strip's or a utility's button */
.tn-cat[data-tip]::after, .tn-tool[data-tip]::after, .tn-util[data-tip]::after {
  content: attr(data-tip); position: absolute; z-index: 3; pointer-events: none; white-space: nowrap;
  padding: var(--sp-2) var(--sp-3); border-radius: var(--r-pill); background: var(--float-bg); box-shadow: var(--float-shadow);
  color: var(--float-text); font: 600 var(--fs-sm) var(--ui); opacity: 0; visibility: hidden; transition: opacity var(--t-fast) 0s, visibility 0s var(--t-fast);
}
.tn-cat[data-tip]::after { left: calc(100% + 12px); top: 50%; transform: translateY(-50%); }
.tn-tool[data-tip]::after, .tn-util[data-tip]::after { top: calc(100% + 10px); left: 50%; transform: translateX(-50%); }
/* A flyout button's label: to the RIGHT of the whole flyout, level with the button (ui/shell.js sets --tn-tip-x, the button's distance to the flyout's right edge), so it never covers the button below */
.tn-strip .tn-tool[data-tip]::after { top: 50%; bottom: auto; left: calc(100% + var(--tn-tip-x, 0px) + var(--gap-in) + 12px); transform: translateY(-50%); }
.tn-topright .tn-util[data-tip]::after { left: auto; right: 0; transform: none; }
.tn-cat:hover::after, .tn-tool:hover::after, .tn-util:hover::after { opacity: 1; visibility: visible; transition: opacity var(--t-fast) 300ms, visibility 0s 300ms; }
.tn-cat:focus-visible::after, .tn-tool:focus-visible::after, .tn-util:focus-visible::after { opacity: 1; visibility: visible; transition: none; }
.tn-cat:focus-visible, .tn-tool:focus-visible, .tn-util:focus-visible, .tn-export:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* The strip's overflow menu: the folded tools with their labels */
/* Top right: Undo · Redo, Shortcuts, Export */
.tn-topright { position: absolute; z-index: 106; top: var(--shell-edge); right: var(--shell-edge); display: flex; align-items: center; gap: var(--gap-out); }
.tn-util-pair { display: flex; gap: 0; border-radius: var(--r-btn); }
.tn-export {
  height: var(--util-btn); display: flex; align-items: center; gap: var(--sp-3); padding: 0 var(--sp-5);
  border-radius: var(--r-btn); background: var(--accent); color: var(--float-on-accent); font: 700 var(--fs-md) var(--ui); cursor: pointer;
}
.tn-export svg { width: 20px; height: 20px; }
.tn-export:hover, .tn-export[aria-expanded="true"] { box-shadow: var(--float-shadow-up), var(--float-hi); transform: translateY(-1px); }
.tn-float.tn-util:hover, .tn-view-row .glass-btn:hover { box-shadow: var(--float-shadow-up), var(--float-hi); transform: translateY(-1px); }
.tn-field { background: var(--shade-30); }
/* Paint only paints (roadmap 593): the Textures gallery shows behind the paint brush only */
html[data-ui="next"] #app:not(.tn-paint-on) #material-gallery { display: none !important; }
@media (prefers-reduced-motion: reduce) {
  .tn-cat, .tn-tool, .tn-util, .tn-export { transition: none; }
  .tn-cat::after, .tn-tool::after, .tn-util::after { transition: none !important; }
}

/* ── One home per control (WL1b, owner rulings 25 Oct 2026) ──
 * Top left, row 1: the project menu button and the breadcrumb, each its own pill. The Settings card at the centre of the
 * view (Preferences, Developer); the Ghosts popover under its button; the dock's chevron beside its grip; the storey
 * height as the level's chip. */
.tn-topleft { position: absolute; z-index: 106; top: var(--shell-edge); left: var(--shell-edge); display: flex; align-items: center; gap: var(--gap-in); }
.tn-topleft > .tn-float { position: relative; }
.tn-menu-btn, .tn-crumbs { height: var(--util-btn); display: flex; align-items: center; border-radius: var(--r-pill); box-sizing: border-box; }
.tn-menu-btn { gap: var(--sp-3); padding: 0 var(--sp-4) 0 var(--sp-5); cursor: pointer; font: 700 var(--fs-lg) var(--ui); letter-spacing: 0.03em; color: var(--text-strong); border: none; }
.tn-menu-btn svg { width: 16px; height: 16px; color: var(--muted); }
.tn-menu-btn:hover, .tn-menu-btn[aria-expanded="true"] { box-shadow: var(--float-shadow-up), var(--float-hi); transform: translateY(-1px); }
.tn-menu-btn:focus-visible, .tn-crumb:focus-visible, .tn-menu-item:focus-visible, .tn-set-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tn-crumbs { gap: var(--sp-4); padding: 0 var(--sp-5) 0 var(--sp-3); }
.tn-crumb-list { display: flex; align-items: center; }
.tn-crumb { height: 32px; max-width: 220px; padding: 0 var(--sp-4); border: none; border-radius: var(--r-pill); background: transparent; color: var(--text-strong); cursor: text;
  font: 600 var(--fs-md) var(--ui); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tn-crumb:hover { background: var(--veil-10); }
.tn-crumbs .tn-project { width: 168px; height: 32px; border-radius: var(--r-pill); }
.tn-saved-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); flex: none; }
.tn-saved-dot.dirty { background: var(--warn); }
.tn-menu { position: fixed; z-index: 121; top: calc(var(--shell-edge) + var(--util-btn) + 8px); left: var(--shell-edge); flex-direction: column; gap: var(--sp-1); padding: var(--gap-in); min-width: 232px; }
.tn-menu-item { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-6); min-height: 40px; padding: 0 var(--sp-4); border: none; border-radius: var(--r-md); background: transparent;
  color: var(--float-text); font: 600 var(--fs-md) var(--ui); cursor: pointer; text-align: left; }
.tn-menu-item:hover { background: var(--veil-10); }
.tn-menu-item kbd { padding: 0 var(--sp-2); border-radius: var(--r-key); background: var(--shade-30); color: var(--muted); font-family: var(--mono); font-size: var(--fs-2xs); line-height: 16px; }
.tn-menu-sep { height: 1px; margin: var(--sp-1) var(--sp-3); background: var(--veil-10); }
.tn-saved { font-size: var(--fs-sm); }

/* The Settings card: centred over the view, at most 80 % of the window's height, two tabs */
html[data-ui="next"] #settings-panel.tn-settings { position: fixed; z-index: 125 !important; left: 50%; top: 50%; right: auto; bottom: auto; transform: translate(-50%, -50%);
  width: min(540px, calc(var(--tn-vw) - 48px)); max-height: calc(0.8 * var(--tn-vh)); padding: 0; gap: 0; overflow: hidden; flex-direction: column; align-items: stretch; }
html[data-ui="next"] #settings-panel.tn-settings > * { flex-shrink: 0; }
html[data-ui="next"] #settings-panel.tn-settings > .tn-set-body { flex: 0 1 auto; min-height: 0; overflow-y: auto; }
.tn-set-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); padding: var(--sp-4) var(--sp-5) var(--sp-3); }
.tn-set-tabs { display: flex; gap: var(--sp-2); padding: var(--sp-1); border-radius: var(--r-pill); background: var(--shade-30); }
.tn-set-tab { height: 32px; padding: 0 var(--sp-6); border: none; border-radius: var(--r-pill); background: transparent; color: var(--float-text); font: 600 var(--fs-md) var(--ui); cursor: pointer; }
.tn-set-tab:hover { background: var(--veil-10); }
.tn-set-tab[aria-selected="true"] { background: var(--accent); color: var(--float-on-accent); }
.tn-set-body { display: flex; flex-direction: column; gap: var(--sp-3); padding: 0 var(--sp-5) var(--sp-5); }
.tn-set-body[hidden] { display: none; }
.tn-set-sec { display: flex; flex-direction: column; gap: var(--sp-1); padding-top: var(--sp-3); border-top: 1px solid var(--veil-10); }
.tn-set-sec h3 { margin: 0 0 var(--sp-1); font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
html[data-ui="next"] #settings-panel .tn-prefs { padding: 0 var(--sp-5) var(--sp-5); border-top: none; align-self: stretch; }
html[data-ui="next"] #settings-panel .tn-prefs-row { display: grid; grid-template-columns: 104px minmax(0, 1fr); align-items: center; gap: var(--sp-3); }
html[data-ui="next"] #settings-panel .tn-prefs-row > .tn-prefs-name, .tn-set-line > .tn-prefs-name { font-size: var(--fs-sm); color: var(--text); }
html[data-ui="next"] #settings-panel .tn-seg button { height: 30px; font-size: var(--fs-xs); }
html[data-ui="next"] #settings-panel .settings-row { padding: 2px 0; display: grid; grid-template-columns: 104px minmax(0, 1fr) auto; align-items: center; gap: var(--sp-3); }
html[data-ui="next"] #settings-panel .settings-row > label { font-size: var(--fs-sm); color: var(--text); text-align: left; justify-self: start; }
html[data-ui="next"] #settings-panel .settings-row:has(> input[type=checkbox]) { grid-template-columns: auto minmax(0, 1fr); }
html[data-ui="next"] #settings-panel .settings-row > input[type=checkbox] { grid-column: 1; justify-self: start; }
.tn-set-line { display: grid; grid-template-columns: 104px minmax(0, 1fr); align-items: center; gap: var(--sp-3); padding-top: var(--sp-2); }
.tn-health-line { font-size: var(--fs-xs); color: var(--muted); }
.tn-dev-group { display: flex; flex-direction: column; gap: var(--sp-2); align-self: stretch; }
.tn-set-body .tn-dev-group > .glass-btn { height: 34px !important; font-family: var(--ui); }
.tn-set-body .tn-dev-group > .glass-btn { background: var(--veil-05); border: 1px solid var(--veil-10); border-radius: var(--r-md); color: var(--float-text); }
.tn-set-body .tn-dev-group > .glass-btn:hover { background: var(--veil-10); }
.tn-set-body .tn-dev-group > .glass-btn.active { background: var(--accent-a20); border-color: var(--accent-a55); color: var(--accent); }

/* The Ghosts popover (the view cluster's Ghosts button: click toggles, right-click or a long press opens this) */
.tn-ghosts-panel { position: fixed; z-index: 121; width: 260px; flex-direction: column; gap: var(--sp-3); padding: var(--sp-4); }
.tn-ghosts-note { font-size: var(--fs-xs); color: var(--muted); line-height: 1.4; }
.tn-ghosts-panel .settings-row { padding: 0; }
/* The ghosts' Look (Ghost, Materials): a segmented row */
.tn-ghosts-look-row { display: flex; align-items: center; gap: var(--sp-3); }
.tn-ghosts-look-row .tn-seg { flex: 1 1 auto; }
.tn-ghosts-look-row .tn-seg button { flex: 1 1 0; min-width: 0; padding: 0 var(--sp-2); }
.tn-seg button[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
.tn-seg button[aria-disabled="true"]:hover { color: var(--muted); background: transparent; }
.tn-ghosts-panel #ghosts-status { padding: 0 !important; }
/* The Game textures tool (T4 round 8): its caption over its four buttons, the note under them; a chip at the pointer while drawing (the warning colour; danger at the cap) */
.tn-tex-area-row { display: flex; flex-direction: column; align-items: stretch; gap: var(--sp-2); }
.tn-tex-area-row .tn-seg { display: flex; }
.tn-tex-area-row .tn-seg button { flex: 1 1 0; min-width: 0; padding: 0 var(--sp-2); }
.tn-tex-area-note { font-size: var(--fs-xs); color: var(--muted); line-height: 1.35; white-space: normal; text-align: left; }
.tn-area-chip { position: fixed; z-index: 130; pointer-events: none; padding: 3px 8px; border-radius: 6px; background: var(--surface2); color: var(--fg);
  border: 1px solid var(--warn); font-size: 11px; line-height: 1.3; white-space: nowrap; box-shadow: var(--float-shadow); }
.tn-area-chip.at-cap { border-color: var(--danger); color: var(--danger); }
/* the tool is the new shell's (its Ghosts panel): the current (classic) UI keeps its Settings as before, with the row hidden by the rule above the shell's section */
html[data-ui="next"] #tex-area-row { display: flex; }
html[data-ui="next"] #tex-area-note { display: block; }


/* The selected level's height chip, in the Levels card: where it is edited (the walls' arrows are the other end of the same value) */
.tn-storey { border-top: none; padding-top: 0; }
html[data-ui="next"] .tn-storey > div { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-1) var(--sp-4) !important; border-radius: var(--r-pill); background: var(--shade-30); }
html[data-ui="next"] .tn-storey label { font-size: var(--fs-xs) !important; color: var(--muted) !important; flex: 1; }
.tn-land-ground { display: inline-flex; align-items: center; gap: var(--sp-3); }
.tn-land-ground select { width: auto; max-width: 150px; }
/* The export sheet's name is the breadcrumb's, read-only here */
html[data-ui="next"] #export-name[readonly] { color: var(--muted); cursor: default; }

/* ── WL2: the World / Lot switch, the breadcrumb's World and Site crumbs, the World options (owner rulings 25 Oct 2026) ── */
.tn-space { height: var(--util-btn); display: flex; align-items: center; gap: 2px; padding: 4px; border-radius: var(--r-pill); box-sizing: border-box; }
.tn-space-btn { height: 36px; min-width: 64px; padding: 0 var(--sp-5); border: none; border-radius: var(--r-pill); background: transparent; color: var(--float-text);
  font: 600 var(--fs-md) var(--ui); cursor: pointer; transition: background var(--t-fast), color var(--t-fast); }
.tn-space-btn:hover { background: var(--veil-10); }
.tn-space-btn[aria-checked="true"] { background: var(--accent); color: var(--float-on-accent); }
.tn-space-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tn-crumb-menu { display: inline-flex; align-items: center; gap: var(--sp-2); cursor: pointer; }
.tn-crumb-menu svg { width: 14px; height: 14px; color: var(--muted); flex: none; }
.tn-crumb-build { color: var(--muted); font-weight: 500; }
.tn-crumb[hidden], .tn-crumb-sep[hidden] { display: none; }
.tn-world-menu, .tn-site-menu { width: 300px; max-height: calc(var(--tn-vh) - 120px); overflow-y: auto; gap: var(--sp-3); }
.tn-wmenu-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); }
.tn-wmenu-row .tn-select { width: auto; min-width: 110px; }
.tn-world-menu .tn-wm { border-bottom: none; padding-bottom: 0; }
.tn-site-group { display: flex; flex-direction: column; gap: var(--sp-2); }
.tn-site-group[hidden], .tn-site-menu #tn-site-menu-none[hidden] { display: none; }
.tn-site-menu .tn-land-sites { display: flex; flex-direction: column; gap: var(--sp-2); }
.tn-layers-pop { position: fixed; z-index: 121; flex-direction: column; gap: var(--sp-3); padding: var(--sp-4); width: 220px; }
.tn-terrain-aids { padding: 4px; border-radius: var(--r-pill); display: flex; }
.tn-terrain-aids[hidden] { display: none; }
.tn-terrain-aids .tn-seg button { min-height: 32px; }
.tn-cursor-chip { position: fixed; z-index: 120; pointer-events: none; padding: 4px 10px; border-radius: var(--r-pill); font: 600 var(--fs-xs) var(--mono); white-space: nowrap; }
.tn-cursor-chip[hidden] { display: none; }
/* World's cursor readout (plan tip and the 3D chip): the coordinates first, mono, a hairline under them */
.tn-world-readout { font: 600 var(--fs-xs) var(--mono); line-height: 1.5; }
.tn-world-readout[hidden], .tn-cursor-chip.tn-chip-world > :not(.tn-world-readout) { display: none; }
.tn-world-readout-xy { color: var(--text-strong); padding-bottom: 2px; margin-bottom: 2px; border-bottom: 1px solid var(--veil-15); }
.tn-world-tip .tn-world-readout { margin-bottom: var(--sp-2); }
.tn-cursor-chip.tn-chip-world { border-radius: var(--r-md); padding: var(--sp-2) var(--sp-3); }
/* The 3D view's Layers: only what the map overlay draws there (roads, water) */
.tn-layers-pop.tn-layers-3d .tn-world-layer:not(:has([data-layer="roads"])):not(:has([data-layer="water"])):not(:has([data-layer="buildings"])) { display: none; }
/* Go to place: the World menu's first row, its matches under it */
.tn-goto { display: flex; flex-direction: column; gap: var(--sp-2); }
/* WL9: the world menu's Start a world… (the home card) beside the Go to field: the menu keeps its height */
.tn-goto-row { display: flex; align-items: center; gap: var(--sp-2); }
.tn-goto-row .tn-goto-field { flex: 1; min-width: 0; }
.tn-wmenu-home { flex: none; width: 36px; height: 36px; }
.tn-goto-field { width: 100%; min-height: 36px; font-size: var(--fs-sm); }
.tn-goto-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; max-height: 260px; overflow-y: auto; }
.tn-goto-list[hidden] { display: none; }
.tn-goto-item { display: flex; flex-direction: column; gap: 1px; padding: var(--sp-2) var(--sp-3); border-radius: var(--r-sm); cursor: pointer; font-size: var(--fs-sm); color: var(--text); }
.tn-goto-item small { font-size: var(--fs-2xs); color: var(--muted); }
.tn-goto-item:hover, .tn-goto-item[aria-selected="true"] { background: var(--accent-a20); color: var(--text-strong); }
.tn-goto-item.error { cursor: default; color: var(--danger); background: none; }
.tn-land-typed[hidden], .tn-wctx-map[hidden], .tn-export-pos[hidden], .tn-export-where[hidden], .tn-export-rebuild[hidden] { display: none; }
.tn-wctx { flex-direction: column; align-items: stretch; gap: var(--sp-3); min-width: 260px; max-width: 420px; }
.tn-wctx-map { display: flex; flex-direction: column; gap: var(--sp-2); }
.tn-export-where { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); margin-bottom: 16px; font-size: var(--fs-xs); color: var(--muted); }
/* The one Export (WL8): what it exports, one primary button (Rebuild all beside it for a world map), Other formats closed below */
.tn-export-subject { display: flex; flex-direction: column; gap: 2px; margin-bottom: 12px; }
.tn-export-title { font: 700 var(--fs-md) var(--ui); color: var(--text-strong); overflow-wrap: anywhere; }
.tn-export-note { font-size: var(--fs-xs); color: var(--muted); line-height: 1.35; }
.tn-export-main { display: flex; gap: var(--sp-3); margin-bottom: 8px; }
.tn-export-go { flex: 1; height: 40px; border-radius: var(--r-md); font: 700 var(--fs-sm) var(--ui); background: var(--accent) !important; color: var(--float-on-accent) !important; justify-content: center; width: auto; }
.tn-export-go:disabled { opacity: 0.6; cursor: progress; }
.tn-export-rebuild { height: 40px; padding: 0 var(--sp-4); border-radius: var(--r-md); border: 1px solid var(--veil-15); background: var(--shade-20); color: var(--muted); font: 600 var(--fs-xs) var(--ui); cursor: pointer; }
.tn-export-rebuild[aria-pressed="true"] { color: var(--accent); background: var(--accent-a20); border-color: var(--accent); }
.tn-export-rebuild:focus-visible, .tn-export-go:focus-visible, .tn-export-other summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tn-export-other { margin-top: 12px; border-top: 1px solid var(--veil-10); padding-top: 8px; }
.tn-export-other summary { cursor: pointer; font: 600 var(--fs-xs) var(--ui); color: var(--muted); padding: 6px 0; line-height: 16px; min-height: 28px; box-sizing: border-box; }
.tn-export-other summary:hover { color: var(--text); }
.tn-export-other-list { display: flex; flex-wrap: wrap; gap: var(--sp-2); padding-top: 8px; }
.tn-export-fmt { flex: 1 1 calc(50% - var(--sp-2)); height: 32px; font-size: var(--fs-xs); border-radius: var(--r-sm); width: auto; justify-content: center; }
/* World: no levels and no wall display (buildings are the Lot's); the view cluster and the options stay over the plan */
.tn-in-world #tn-levels-card, .tn-in-world #btn-wall-display { display: none; }
html[data-ui="next"] .tn-world-on .tn-view { display: flex; }
html[data-ui="next"] .tn-world-badge { top: calc(var(--shell-below) + 56px); left: auto; right: var(--shell-edge); }
html[data-ui="next"] .tn-world-panel.tn-world-opts { top: calc(var(--shell-below) + 96px); width: 272px; max-height: calc(var(--tn-vh) - var(--shell-below) - 160px); }
.tn-world-opts[hidden] { display: none; }
.tn-world-opts .tn-wctx { min-width: 0; max-width: none; }
/* The Terrain bar's last row is now its brush fields (the aids float): room for their step buttons under the boxes */
.tn-in-world .tn-land-ground { display: none; }   /* the lot's default ground: the Lot's Terrain only */

/* The Game look's placeholder names (textured mode T4, development only): a small floating list at the viewport's corner. */
.tn-tex-gaps { position: fixed; left: 12px; bottom: 12px; z-index: 40; max-width: 420px; max-height: calc(0.4 * var(--tn-vh)); overflow: auto;
  background: var(--surface2); color: var(--fg); border: 1px solid var(--border); border-radius: 8px; padding: 6px 10px;
  font-size: 11px; line-height: 1.35; box-shadow: var(--float-shadow); }
.tn-tex-gaps summary { cursor: pointer; color: var(--muted); }
.tn-tex-gaps ul { margin: 6px 0 0; padding-left: 16px; }


/* The Loading world detail chip in the new shell (ui/load-chip.js): under the top bar; World's map covers the 3D view */
html[data-ui="next"] .world-loading { top: var(--shell-below); }
.tn-world-on .world-loading { display: none; }   /* World's map covers the 3D view */

/* ══ UX round R1 (1 Nov 2026): design tokens, and one control per kind of value ══════════════════════════════════════════
   The sizes the controls below are built from, in one place. The older --sp-* / --fs-* / --r-* scales above stay (the rest of
   the page is built on them); these are the scales the UX spike names, and where a control's size is decided. */

/* The number field (ui/num-field.js): the box is a field tall, its caption scrubs; the step buttons are the hover aids of the keyboard's arrows and the caption's scrub (not counted in the 28 px rule) */
.tn-nf-box .glass-input.tn-nf-input { height: var(--tk-h-field); border-radius: var(--tk-r-field); font-family: var(--ui); font-size: var(--tk-fs-cap); }
.tn-nf-nounit .tn-nf-input { padding-right: 6px !important; }
.tn-nf-label { cursor: ew-resize; user-select: none; white-space: nowrap; }
.tn-nf-label.scrubbing { color: var(--accent); }

.tn-nf:has(.tn-nf-input:disabled) { opacity: 0.55; pointer-events: none; }
/* A field in a row of a card (settings, the level's storey height): the caption to the left, the box at the right edge */
.tn-nf-row { padding: 0; display: flex; align-items: center; justify-content: space-between; gap: var(--tk-sp-2); width: 100%; }
.tn-nf-row .tn-nf-label { flex: 1 1 auto; text-transform: none; letter-spacing: 0; font-weight: 400; color: var(--text); }
.tn-nf-row .tn-nf-slider { width: 96px; }
.tn-nf-wide .tn-nf-slider { width: 150px; }
.tn-nf-compact { gap: var(--tk-sp-1); flex: 1 1 0; min-width: 0; }
.tn-nf-compact .tn-nf-box { flex: 1 1 0; width: auto; min-width: 0; }
.tn-nf-compact .tn-nf-input { min-width: 0; }
.tn-nf-compact .tn-nf-label { font-weight: 700; }
.tn-nf.fx-own .tn-nf-input { border-color: var(--accent-a55); }

/* A choice (ui/choice.js): the <select> stays in the page as the value's store and is never shown */
.tn-native { display: none !important; }
.tn-choice { display: inline-flex; align-items: center; min-width: 0; }
.tn-choice[hidden] { display: none !important; }
.tn-choice.tn-choice-wide { display: flex; width: 100%; }
.tn-choice.disabled { opacity: 0.55; }
.tn-choice.tn-seg { display: inline-flex; flex-wrap: nowrap; }
.tn-choice.tn-seg .tn-seg-btn { flex: 1 1 auto; min-width: 0; height: var(--tk-h-chip); padding: 0 var(--tk-sp-3); white-space: nowrap; font-size: var(--tk-fs-cap); }
.tn-choice.tn-choice-wide.tn-seg { width: 100%; }
.tn-pick-btn.glass-input { display: inline-flex; align-items: center; justify-content: space-between; gap: var(--tk-sp-2); width: 100%; min-width: 0; height: var(--tk-h-field);
  padding: 0 var(--tk-sp-3); border-radius: var(--tk-r-field); font-family: var(--ui); font-size: var(--tk-fs-cap); text-align: left; cursor: pointer; }
.tn-pick-btn:disabled { cursor: not-allowed; }
.tn-pick-val { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tn-pick-chev { flex: none; display: inline-flex; color: var(--muted); }
.tn-pick-chev svg { width: 10px; height: 7px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.tn-pick-list { position: fixed; z-index: 400; overflow-y: auto; padding: var(--tk-sp-1); background: var(--float-bg); border: 1px solid var(--glass-line); border-radius: var(--tk-r-field);
  box-shadow: var(--float-shadow-up); box-sizing: border-box; }
.tn-pick-opt { display: flex; align-items: center; min-height: var(--tk-hit-min); padding: 0 var(--tk-sp-3); border-radius: var(--r-xs); font-size: var(--tk-fs-cap); color: var(--text); cursor: pointer; white-space: nowrap; outline: none; }
.tn-pick-opt:hover, .tn-pick-opt:focus-visible { background: var(--veil-10); }
.tn-pick-opt.on { color: var(--accent); background: var(--accent-a15); }
.tn-pick-opt[aria-disabled="true"] { color: var(--text-disabled); cursor: not-allowed; }
.tn-pick-group { padding: var(--tk-sp-2) var(--tk-sp-3) var(--tk-sp-1); font-size: var(--fs-2xs); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
/* Colour swatches are 28 px targets (the door card's colours) */
html[data-ui="next"] #fx-swatches .fx-sw { width: var(--tk-hit-min) !important; height: var(--tk-hit-min) !important; min-width: var(--tk-hit-min) !important; }

/* ── The selection card (UX round R2, 1 Nov 2026; ui/selection-card.js): one skeleton for every selection ─────────────────────────────
   Header, Shape (numbers, two to a row), Finish, On this, Actions. Beside the selection (data-place="beside", placed by script) or docked
   at the bottom edge (data-place="dock"). It never grows past the window: a long card scrolls inside itself. */
.tn-selcard {
  position: fixed; z-index: 106; width: 292px; box-sizing: border-box; padding: var(--sp-4) var(--sp-5) var(--sp-4);
  display: flex; flex-direction: column; gap: var(--sp-4); max-height: calc(var(--tn-vh) - 24px); overflow-y: auto;
}
.tn-selcard[hidden], .tn-selcard [hidden] { display: none !important; }
.tn-selcard[data-place="dock"] { box-shadow: var(--float-shadow-up), var(--float-hi); }
.tn-sc-head { display: grid; grid-template-columns: auto minmax(0, 1fr) var(--tk-hit-min); align-items: center; column-gap: var(--sp-3); row-gap: 0; }
.tn-sc-type { font-size: var(--tk-fs-title); font-weight: 700; color: var(--text-strong); }
.tn-sc-name { font-size: var(--tk-fs-cap); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tn-sc-where { grid-column: 1 / 3; grid-row: 2; font-size: var(--fs-xs); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tn-sc-close { grid-column: 3; grid-row: 1 / 3; width: var(--tk-hit-min); height: var(--tk-hit-min); display: flex; align-items: center; justify-content: center; justify-self: end;
  border: none; border-radius: var(--r-md); background: transparent; color: var(--muted); cursor: pointer; }
.tn-sc-close:hover { background: var(--veil-10); color: var(--text-strong); }
.tn-sc-close:focus-visible, .tn-sc-btn:focus-visible, .tn-sc-sw:focus-visible, .tn-sc-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tn-sc-close svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.tn-sc-sec { display: flex; flex-direction: column; gap: var(--sp-3); padding-top: var(--sp-4); border-top: 1px solid var(--veil-10); }
.tn-sc-h { margin: 0; }
.tn-sc-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 18px var(--sp-4); }
.tn-sc-grid[hidden] { display: none; }
.tn-selcard .tn-nf { display: flex; flex-direction: column; align-items: stretch; gap: 3px; min-width: 0; }
.tn-selcard .tn-nf-label { white-space: nowrap; text-transform: none; letter-spacing: 0; font-weight: 400; color: var(--muted); font-size: var(--fs-xs); }
.tn-selcard .tn-nf-box { width: 100%; }
.tn-selcard .tn-nf-box .glass-input.tn-nf-input { height: var(--tk-hit-min); }
.tn-selcard .tn-nf-up { bottom: calc(100% - 2px); }
.tn-selcard .tn-nf-down { top: calc(100% - 2px); }
.tn-sc-segrow { grid-column: 1 / -1; display: flex; flex-direction: column; gap: 3px; }
.tn-sc-segrow .tn-caption { text-transform: none; letter-spacing: 0; font-weight: 400; }
.tn-selcard .tn-choice, .tn-selcard .tn-choice.tn-choice-wide { display: flex; width: 100%; }
.tn-selcard .tn-choice.tn-seg .tn-seg-btn { flex: 1 1 0; min-width: 0; height: var(--tk-hit-min); }
.tn-selcard .tn-pick-btn.glass-input { height: var(--tk-hit-min); }
.tn-sc-note { grid-column: 1 / -1; margin: 0; font-size: var(--fs-xs); color: var(--muted); line-height: 1.3; }
.tn-sc-note:empty { display: none; }
.tn-sc-read { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.tn-sc-read .tn-caption { text-transform: none; letter-spacing: 0; font-weight: 400; font-size: var(--fs-xs); }
.tn-sc-val { height: var(--tk-hit-min); display: flex; align-items: center; font-size: var(--fs-xs); color: var(--text); font-variant-numeric: tabular-nums; }
.tn-sc-fin { display: flex; flex-direction: column; gap: var(--sp-3); }
.tn-sc-fin .tn-caption { text-transform: none; letter-spacing: 0; font-weight: 400; }
.tn-sc-swatches { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.tn-sc-sw { width: var(--tk-hit-min); height: var(--tk-hit-min); padding: 0; border: 1px solid var(--veil-20); border-radius: var(--r-md); background: var(--sw, var(--shade-30)); cursor: pointer; color: var(--text); font: 600 var(--fs-xs) var(--ui); }
.tn-sc-sw:hover { border-color: var(--veil-30); }
.tn-sc-sw[aria-pressed="true"] { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-a30); }
.tn-sc-sw:disabled { opacity: 0.45; cursor: not-allowed; }
/* A wall's face rows (UX R3a): swatch, what the face looks at, Browse…, then the 5 recent materials */
.tn-sc-faces { display: flex; flex-direction: column; gap: var(--sp-3); }
.tn-sc-face { display: grid; grid-template-columns: var(--tk-hit-min) minmax(0, 1fr) auto; align-items: center; gap: var(--sp-2) var(--sp-3); }
.tn-sc-face[hidden] { display: none; }
.tn-sc-fsw { width: var(--tk-hit-min); height: var(--tk-hit-min); border: 1px solid var(--veil-20); border-radius: var(--r-md); background: var(--shade-30); }
.tn-sc-flabel { text-transform: none; letter-spacing: 0; font-weight: 400; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tn-sc-recent { grid-column: 2 / -1; display: flex; gap: var(--sp-2); }
.tn-sc-recent:empty { display: none; }
.tn-sc-recent-sw { background: var(--sw, var(--shade-30)); }
.tn-sc-name { display: flex; flex-direction: column; gap: 3px; margin-bottom: var(--sp-3); }
.tn-sc-name[hidden] { display: none; }
.tn-sc-name .tn-caption { text-transform: none; letter-spacing: 0; font-weight: 400; }
.tn-sc-text { height: 32px; padding: 0 var(--sp-3); text-align: left; font: 400 var(--fs-xs) var(--ui); }
.tn-sc-text:disabled { opacity: 0.55; cursor: not-allowed; }
.tn-sc-variant { background: var(--shade-30); }
.tn-selcard #sc-obj-variants { gap: var(--sp-2); }
.tn-sc-list { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.tn-sc-item { display: inline-flex; align-items: center; gap: var(--sp-3); max-width: 100%; height: var(--tk-hit-min); padding: 0 var(--sp-4); border: none; border-radius: var(--r-md); background: var(--shade-30); color: var(--text); font: 500 var(--fs-xs) var(--ui); cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tn-sc-item:hover { background: var(--veil-10); }
.tn-sc-item-kind { font-size: var(--fs-2xs); letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.tn-sc-empty { font-size: var(--fs-xs); color: var(--muted); }
.tn-sc-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.tn-sc-btn { height: var(--tk-hit-min); padding: 0 var(--sp-4); border: none; border-radius: var(--r-md); background: var(--shade-30); color: var(--text); font: 600 var(--fs-xs) var(--ui); cursor: pointer; white-space: nowrap; }
.tn-sc-btn:hover { background: var(--veil-10); }
.tn-sc-btn[aria-pressed="true"] { color: var(--accent); background: var(--accent-a20); }
.tn-sc-btn[data-danger] { color: var(--danger); }
.tn-sc-btn[data-danger]:hover { background: var(--danger-a20); }
.tn-sc-btn:disabled, .tn-sc-btn[aria-disabled="true"] { color: var(--text-disabled); cursor: not-allowed; }
.tn-sc-btn:disabled:hover, .tn-sc-btn[aria-disabled="true"]:hover { background: var(--shade-30); }
.tn-sc-padwrap:empty { display: none; }
.tn-selcard .tn-sc-pad { flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--sp-3); }
.tn-selcard .tn-sc-pad > .glass-sep { display: none; }
.tn-selcard .tn-sc-pad .glass-btn { height: var(--tk-hit-min) !important; }

/* ── Size tiers and the UI scale (UX round R6, 5 Nov 2026; ui/size-tier.js) ──────────────────────────────────────────────────────────────
 * The tier by the window's shorter side in the shell's own pixels (L >= 900, M >= 720, S below) is a class on <body> (.tn-tier-l / -m / -s);
 * the UI scale (Settings > Interface: Auto, 80-125 %) is CSS zoom on the shell's top-level surfaces (never the 3D view, the map or a chip at
 * the pointer). A zoomed surface's 100vh is the window's height times its zoom, so the shell's heights and widths use --tn-vh / --tn-vw,
 * the window in the surfaces' own pixels. L and M are the layout as it was; S is the small layout (the in-game window, 1024 x 576). */
html[data-ui="next"] { --tn-vh: calc(100vh / var(--ui-scale, 1)); --tn-vw: calc(100vw / var(--ui-scale, 1)); }
html[data-ui="next"] #app > .tn-float:not(.tn-cursor-chip),
html[data-ui="next"] #app > .tn-topleft,
html[data-ui="next"] #app > .tn-topright,
html[data-ui="next"] #app > .tn-left,
html[data-ui="next"] #app > .tn-view,
html[data-ui="next"] #app > .tn-tips,
html[data-ui="next"] #app > .tn-fold-pop,
html[data-ui="next"] #app > #settings-panel,
html[data-ui="next"] #app > #time-panel,
html[data-ui="next"] #app > #wall-display-panel,
html[data-ui="next"] #app > #bt-export-flyout,
html[data-ui="next"] body > .tn-pick-list { zoom: var(--ui-scale, 1); }
/* The pop-ups of the folded levels and view cluster (S only): plain holders, the cards inside are the surfaces */
.tn-fold-pop { position: fixed; z-index: 121; top: var(--shell-below); display: none; flex-direction: column; align-items: flex-end; gap: var(--gap-in); }
.tn-level-chip, .tn-view-more { display: none; }
.tn-fold-pop > .tn-float { position: relative; }
/* Settings > Interface > UI scale: one line (the caption, the menu) */
.tn-prefs #tn-ui-scale-row { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.tn-view-row.tn-view-menu { padding: var(--gap-in); }

/* S: smaller buttons (category 44, tool 40, utility 36), tighter edges, the top row 36 px high */
.tn-tier-s {
  --cat-btn: 44px; --cat-icon: 24px; --tool-btn: 40px; --tool-icon: 22px; --util-btn: 36px; --util-icon: 20px;
  --shell-edge: 8px; --shell-below: 52px; --gap-out: 12px;
}
.tn-tier-s .tn-brand-name { display: none; }
.tn-tier-s .tn-menu-btn { padding: 0 var(--sp-3) 0 var(--sp-4); }
.tn-tier-s .tn-saved { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }   /* the dot says it; read by screen readers */
.tn-tier-s .tn-export { padding: 0 var(--sp-4); }
/* The levels fold into an "L1" chip in the top row, the view cluster into a "..." button beside Undo / Redo: each opens its pop-up */
.tn-tier-s .tn-level-chip { display: flex; align-items: center; gap: var(--sp-2); height: var(--util-btn); padding: 0 var(--sp-3) 0 var(--sp-4); border-radius: var(--r-pill); cursor: pointer;
  font: 700 var(--fs-md) var(--mono); color: var(--text-strong); }
.tn-tier-s .tn-level-chip svg { width: 14px; height: 14px; color: var(--muted); }
.tn-tier-s .tn-level-chip:hover, .tn-tier-s .tn-level-chip[aria-expanded="true"] { box-shadow: var(--float-shadow-up), var(--float-hi); }
.tn-tier-s .tn-level-chip:focus-visible, .tn-tier-s .tn-view-more:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tn-tier-s .tn-view-more { display: flex; }
.tn-tier-s .tn-view { display: none; }
.tn-tier-s .tn-fold-pop .tn-levels-card { width: 220px; }
.tn-tier-s .tn-fold-pop .tn-levels { max-height: calc(var(--tn-vh) - var(--shell-below) - 140px); }
/* The flyout grows to 3 columns (ui/shell.js layoutStrip); the left stack is narrower */
.tn-tier-s .tn-left { left: calc(var(--shell-edge) + var(--cat-btn) + 2 * var(--gap-in) + var(--gap-in)); max-width: 292px; }
/* The selection card (and the stair card) docks at the bottom as one row: the header, the Shape / Finish / Openings tabs, the tab's controls,
   the actions at the right (ui/selection-card.js marks it data-compact). --tn-dock-h: its height, so the tips and the sheets sit above it. */
.tn-sc-tabs { display: none; }
.tn-selcard[data-compact] {
  left: calc(var(--shell-edge) + var(--cat-btn) + 3 * var(--gap-in)) !important; right: var(--shell-edge); top: auto !important; bottom: var(--shell-edge);
  width: auto; max-height: calc(0.5 * var(--tn-vh)); flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--sp-3) var(--sp-4); padding: var(--sp-4) var(--sp-4) 14px;   /* 14 px: a field's step-down button under its box */
}
.tn-selcard[data-compact] .tn-sc-head { display: flex; align-items: baseline; gap: var(--sp-3); min-width: 96px; max-width: 180px; }
.tn-selcard[data-compact] .tn-sc-where { display: none; }
.tn-selcard[data-compact] .tn-sc-close { order: 99; align-self: center; }
.tn-selcard[data-compact] .tn-sc-tabs { display: flex; }
.tn-selcard[data-compact] .tn-sc-tabs[hidden] { display: none !important; }
.tn-selcard[data-compact] .tn-sc-sec { flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--sp-3); padding: 0; border-top: none; min-width: 0; }
.tn-selcard[data-compact] .tn-sc-sec[data-off] { display: none; }
.tn-selcard[data-compact] .tn-sc-h { display: none; }
.tn-selcard[data-compact] .tn-sc-grid { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--sp-3); }
.tn-selcard[data-compact] .tn-sc-grid[hidden] { display: none; }
.tn-selcard[data-compact] .tn-nf { width: 92px; }
.tn-selcard[data-compact] .tn-sc-segrow { min-width: 120px; }
.tn-selcard[data-compact] #sc-room-name-row { margin-bottom: 0; min-width: 140px; }
.tn-selcard[data-compact] .tn-sc-faces { flex-direction: row; flex-wrap: wrap; gap: var(--sp-3) var(--sp-4); }
.tn-selcard[data-compact] .tn-sc-face { display: flex; align-items: center; gap: var(--sp-2); }
.tn-selcard[data-compact] .tn-sc-flabel { max-width: 96px; }
.tn-selcard[data-compact] .tn-sc-recent > :nth-child(n+4) { display: none; }   /* three recent materials a row at S; Browse… has them all */
.tn-selcard[data-compact] .tn-sc-fin { flex-direction: row; align-items: center; flex-wrap: wrap; }
.tn-selcard[data-compact] .tn-sc-swatches { flex-wrap: nowrap; }
.tn-selcard[data-compact] .tn-sc-list { flex-wrap: wrap; }
.tn-selcard[data-compact] .tn-sc-note { flex-basis: 100%; }
.tn-selcard[data-compact] #sc-wall-note { display: none; }   /* a row at S: why Length or Height is fixed is the field's own title */
.tn-selcard[data-compact] .tn-sc-actions { margin-left: auto; }
.tn-sc-tabs { gap: var(--sp-1); padding: var(--sp-1); background: var(--shade-20); border: 1px solid var(--veil-05); border-radius: var(--r-lg); }
.tn-sc-tab { height: var(--tk-hit-min); padding: 0 var(--sp-4); border: none; border-radius: var(--r-md); background: transparent; color: var(--muted);
  font: 600 var(--fs-xs) var(--ui); cursor: pointer; white-space: nowrap; }
.tn-sc-tab:hover { color: var(--text); background: var(--veil-05); }
.tn-sc-tab[aria-selected="true"] { color: var(--accent); background: var(--accent-a20); }
.tn-sc-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* The stair card: the selected stair's controls (stairs-ui.js #stair-context) in a card of their own (bottom centre; docked as a row at S) */
.tn-stair-card { position: fixed; z-index: 106; left: 50%; bottom: var(--shell-edge); transform: translateX(-50%); max-width: min(720px, calc(var(--tn-vw) - 2 * var(--shell-edge)));
  box-sizing: border-box; padding: var(--sp-3) var(--sp-4); max-height: calc(0.5 * var(--tn-vh)); overflow-y: auto; }
.tn-stair-card:not(:has(#stair-context[style*="display: flex"])) { display: none; }
.tn-stair-card #stair-context > .glass-sep:first-child { display: none; }
.tn-tier-s .tn-stair-card { left: calc(var(--shell-edge) + var(--cat-btn) + 3 * var(--gap-in)); right: var(--shell-edge); transform: none; max-width: none; }
/* The material picker becomes a bottom sheet at S (45 % of the height): Paint's gallery and the card's Browse…; its filters at the left, the tiles at the right */
html[data-ui="next"] .tn-tier-s .tn-left > #material-gallery, html[data-ui="next"] .tn-tier-s #tn-mp-pop.tn-mp-pop {
  position: fixed; left: calc(var(--shell-edge) + var(--cat-btn) + 3 * var(--gap-in)) !important; right: var(--shell-edge) !important; top: auto !important;
  bottom: calc(var(--shell-edge) + var(--tn-dock-h, 0px)) !important; width: auto; max-width: none; height: calc(0.45 * var(--tn-vh)); max-height: none; z-index: 108;
}
/* The left stack keeps clear of the sheet: the Options card's max height leaves the sheet's height (ui/shell.js) */
.tn-tier-s .tn-left:has(> .left-gallery[style*="display: flex"]) { --tn-below-reserve: calc(0.45 * var(--tn-vh) + var(--gap-in)); }
/* Tips: one line (the whole text is the card's title), above the docked card */
.tn-tier-s .tn-tips { width: min(420px, calc(var(--tn-vw) - 160px)); bottom: calc(var(--shell-edge) + var(--tn-dock-h, 0px)); }
.tn-tier-s .tn-tip { padding: var(--sp-2) var(--sp-4); align-items: center; }
.tn-tier-s .tn-tip-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
