*, *::before, *::after {
  margin: 0; padding: 0; box-sizing: border-box;
  -webkit-user-select: none; user-select: none;
  -webkit-tap-highlight-color: transparent;
}

html, body {
  width: 100%; height: 100%; overflow: hidden;
  font-family: var(--text);
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  background: var(--shell-bg); color: var(--fg);
  transition: background .45s;
}

:root {
  /* Section typography — every section's own style.css repoints these families;
     the values here are the engine's defaults. */
  --display: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  /* Pinned so the browser never fakes a bolder cut than the section ships. */
  --display-weight: 700;
  --text: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* App shell geometry */
  --shell-gap: 16px;      /* gutter between the window and the shell edges */
  --header-h: 74px;       /* header row: also the window's top inset */
  --window-radius: 16px;
  --island-gap: 12px;     /* inset of the open sidebar island from the edges */
  /* The shell sits a touch under the sidebar so the panel still reads as raised. */
  --shell-bg: color-mix(in srgb, var(--menu-bg) 78%, #05050a);

  --scene-bg: #0a0a14;
  --scene-accent: #6366f1;
  --menu-bg: #0a0a14;
  --menu-orb: #6366f1;
  --menu-orb-fg: #fff;
  --fg: #f4f2ff;
  --fg-a05: rgba(244, 242, 255, 0.05);
  --fg-a08: rgba(244, 242, 255, 0.08);
  --fg-a12: rgba(244, 242, 255, 0.12);
  --fg-a25: rgba(244, 242, 255, 0.25);
  --fg-a40: rgba(244, 242, 255, 0.4);
  --fg-a55: rgba(244, 242, 255, 0.55);
  --fg-a75: rgba(244, 242, 255, 0.75);
  --surface: color-mix(in srgb, var(--scene-bg) 30%, rgba(10, 10, 20, 0.85));
  --surface-solid: color-mix(in srgb, var(--scene-bg) 20%, #111218);
  --sidebar-w: 296px;
  --peek: 10px;
  --dock-h: 118px;
  --transition-fast: .18s;
  --transition-med: .28s cubic-bezier(.2, .8, .2, 1);
}

:root[data-mode="light"] {
  --shell-bg: color-mix(in srgb, var(--menu-bg) 74%, #ffffff);
  --fg: #15151a;
  --fg-a05: rgba(21, 21, 26, 0.05);
  --fg-a08: rgba(21, 21, 26, 0.08);
  --fg-a12: rgba(21, 21, 26, 0.12);
  --fg-a25: rgba(21, 21, 26, 0.25);
  --fg-a40: rgba(21, 21, 26, 0.4);
  --fg-a55: rgba(21, 21, 26, 0.55);
  --fg-a75: rgba(21, 21, 26, 0.75);
  --surface: color-mix(in srgb, var(--scene-bg) 25%, rgba(252, 252, 250, 0.82));
  --surface-solid: color-mix(in srgb, var(--scene-bg) 15%, #fefefe);
  color: var(--fg);
}

.scroll::-webkit-scrollbar { width: 6px; height: 6px; }
.scroll::-webkit-scrollbar-track { background: transparent; }
.scroll::-webkit-scrollbar-thumb { background: var(--fg-a12); border-radius: 3px; }
.scroll::-webkit-scrollbar-thumb:hover { background: var(--fg-a25); }

button { font-family: inherit; color: inherit; border: none; background: none; cursor: pointer; }
button:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
iframe { color-scheme: normal; background-color: inherit; border: none; }

/* ===== APP HEADER =====
   The shell's title row: identity on the left, every action on the right.
   It stops at the sidebar's edge, so pinning the list narrows the header and
   the window together and the two right edges stay flush. */
.app-header {
  position: fixed;
  top: 0; left: 0;
  right: var(--stage-right, 0px);
  height: var(--header-h);
  display: flex; align-items: center; gap: 14px;
  padding: 0 var(--shell-gap);
  z-index: 30;
  color: var(--fg);
  /* The row is transparent and reaches over the sidebar's peek strip, so only
     its real contents may take the pointer — otherwise the empty middle of the
     header swallows the hover and the clicks meant for the diamond handle. */
  pointer-events: none;
  transition: right var(--transition-med), height var(--transition-med), opacity .25s;
}
.app-header > * { pointer-events: auto; }

/* A hover-opened sidebar is raised above the header so the action cluster does
   not paint over its own head row — which would then bury a dropdown opened
   from that same cluster. While one is open the header takes the top layer back. */
.app-header:has(.lang-selector.open),
.app-header:has(.scene-help.open) { z-index: 40; }

.header-actions {
  margin-left: auto;
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 6px;
}

/* ===== STAGE — the inset window =====
   The experiment is not full-bleed any more: it is a separate rounded surface
   sitting inside our chrome, which is what makes the whole thing read as one
   application with an app loaded into it. */
.stage {
  position: fixed;
  top: var(--header-h);
  left:   calc(var(--stage-left,   0px) + var(--shell-gap));
  right:  calc(var(--stage-right,  0px) + var(--shell-gap));
  bottom: calc(var(--stage-bottom, 0px) + var(--shell-gap));
  padding: 0;
  background: var(--scene-bg);
  border: 1px solid var(--fg-a05);
  border-radius: var(--window-radius);
  overflow: hidden;
  isolation: isolate;
  box-shadow: 0 30px 70px -30px rgba(0,0,0,.7), 0 2px 12px -6px rgba(0,0,0,.45);
  transition:
    top var(--transition-med), left var(--transition-med),
    right var(--transition-med), bottom var(--transition-med),
    border-radius var(--transition-med), background .6s;
}

.stage-slot {
  position: absolute; inset: 0;
  border-radius: inherit; overflow: hidden;
  opacity: 0;
  transform: scale(1.04);
  filter: blur(12px);
  transition:
    opacity 450ms cubic-bezier(.4, 0, .2, 1),
    transform 600ms cubic-bezier(.4, 0, .2, 1),
    filter 450ms cubic-bezier(.4, 0, .2, 1);
  pointer-events: none;
}
.stage-slot.visible {
  opacity: 1; transform: scale(1); filter: blur(0);
  pointer-events: auto;
}
.stage-slot iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  background: var(--scene-bg);
}

.stage-flash {
  position: absolute; inset: 0;
  background: var(--scene-bg);
  opacity: 0; pointer-events: none;
  transition: opacity 180ms ease-out;
  z-index: 5;
}
.stage-flash.active { opacity: 0.35; }

/* ===== STAGE LOADER =====
   Engine-built overlay shown while a scene loads with preloading off; it sits
   between the slots and the flash layer and fades once the crossfade starts. */
.stage-loader {
  position: absolute; inset: 0;
  z-index: 3;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px;
  background: var(--scene-bg);
  opacity: 0;
  pointer-events: none;
  transition: opacity .3s ease;
}
.stage-loader.show { opacity: 1; }
.stage-loader-spin { position: relative; width: 42px; height: 42px; }
.stage-loader-halo {
  position: absolute; inset: -16px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--scene-accent) 0%, transparent 68%);
  opacity: .2;
  filter: blur(8px);
  animation: stage-loader-halo 1.8s ease-in-out infinite;
}
.stage-loader-ring {
  position: absolute; inset: 0;
  border-radius: 50%;
  border: 2px solid var(--fg-a12);
  border-top-color: var(--scene-accent);
  animation: stage-loader-spin .9s linear infinite;
}
.stage-loader-name {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--fg-a55);
}
@keyframes stage-loader-spin { to { transform: rotate(360deg); } }
@keyframes stage-loader-halo {
  0%, 100% { opacity: .12; transform: scale(.92); }
  50%      { opacity: .3;  transform: scale(1.08); }
}
@keyframes stage-loader-pulse {
  0%, 100% { opacity: .35; }
  50%      { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  /* No spin — a gentle opacity pulse carries the "still working" signal. */
  .stage-loader-ring { animation: stage-loader-pulse 1.6s ease-in-out infinite; }
  .stage-loader-halo { animation: none; }
}

#spec-frame {
  position: fixed; width: 0; height: 0;
  top: -9999px; left: -9999px; pointer-events: none;
}

/* ===== SCENE LABEL =====
   A header child, not an overlay: it sits on the shell, so it simply follows
   --fg like the rest of the chrome. */
.scene-label {
  position: relative; top: auto; left: auto; z-index: auto;
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; gap: 12px;
  padding: 0;
  color: var(--fg);
  text-shadow: none;
  transition: opacity .25s;
}

/* ===== BACK TO THE LAB =====
   Sits immediately left of the current scene's icon and copies its size and shape,
   so the two read as one control: "this scene · leave it". The label unfurls on
   hover (0fr → 1fr) instead of permanently stealing width from the scene title —
   and because the column is content-sized, it fits every one of the 12 locales. */
.lab-home {
  flex: 0 0 auto;
  height: 36px;
  border-radius: 10px;
  background: var(--fg-a05);
  border: 1px solid var(--fg-a05);
  color: var(--fg-a75);
  text-decoration: none;
  overflow: hidden;
  display: inline-grid;
  grid-template-columns: 36px minmax(0, 0fr);
  align-items: center;
  transition: grid-template-columns var(--transition-med),
    background var(--transition-fast),
    color var(--transition-fast), border-color var(--transition-fast);
}
.lab-home > svg { grid-column: 1; justify-self: center; }
.lab-home-label {
  grid-column: 2;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  padding-right: 12px;
  font-size: 12px; font-weight: 600; letter-spacing: .02em;
}
.lab-home:hover,
.lab-home:focus-visible {
  grid-template-columns: 36px minmax(0, 1fr);
  background: var(--fg-a12);
  color: var(--fg);
  border-color: var(--fg-a25);
}
@media (prefers-reduced-motion: reduce) {
  .lab-home { transition: color var(--transition-fast); }
}

.scene-label-icon {
  flex: 0 0 auto;
  width: 36px; height: 36px; border-radius: 10px;
  background: var(--surface);
  backdrop-filter: blur(20px) saturate(1.2);
  -webkit-backdrop-filter: blur(20px) saturate(1.2);
  border: 1px solid var(--fg-a05);
  display: grid; place-items: center;
  font-size: 17px; overflow: hidden;
  position: relative;
}
.scene-label-icon .ico-slot {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  opacity: 0; transform: scale(0.82); filter: blur(4px);
  transition:
    opacity .45s cubic-bezier(.4,0,.2,1),
    transform .5s cubic-bezier(.4,0,.2,1),
    filter .45s cubic-bezier(.4,0,.2,1);
  pointer-events: none;
}
.scene-label-icon .ico-slot.visible { opacity: 1; transform: scale(1); filter: blur(0); }
.scene-label-icon .ico-slot img { width: 100%; height: 100%; object-fit: cover; }

/* The slots inside are absolutely positioned, so the column has no intrinsic
   width of its own — it takes the header's leftover room instead. */
.scene-label-text {
  flex: 1 1 auto; min-width: 0;
  display: flex; flex-direction: column; gap: 1px;
}

.scene-label-name,
.scene-label-meta {
  overflow: hidden; position: relative; white-space: nowrap;
}
.scene-label-name { height: 22px; }
.scene-label-meta { height: 16px; }

/* left+right rather than shrink-to-fit: the slot has to inherit the column's
   width, otherwise it sizes itself to the text, never overflows, and the
   ellipsis never fires — the parent just hard-clips the name mid-letter. */
.label-slot {
  position: absolute; left: 0; right: 0; top: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  opacity: 0;
  transform: translateY(-25%);
  filter: blur(4px);
  transition:
    opacity .45s cubic-bezier(.4,0,.2,1),
    transform .45s cubic-bezier(.4,0,.2,1),
    filter .45s cubic-bezier(.4,0,.2,1);
  pointer-events: none;
}
.label-slot.visible {
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
}
.label-slot.leaving {
  opacity: 0;
  transform: translateY(25%);
  filter: blur(4px);
}

/* Capped so a long title can never push the action cluster off the header. */
.scene-label-name .label-slot {
  max-width: 34vw;
  font-size: 14px;
  color: var(--fg); letter-spacing: -.01em;
}
.scene-label-meta .label-slot {
  font-size: 11px; font-family: var(--mono);
  color: var(--fg-a55); letter-spacing: .04em;
}

/* ===== NAV ARROWS ===== */
.nav-arrow {
  position: fixed;
  /* Centred inside the window: the header inset above, the dock / gutter below.
     The duplicated declaration is a dvh progressive enhancement. */
  top: calc((var(--header-h) + 100vh  - var(--stage-bottom, 0px) - var(--shell-gap)) / 2);
  top: calc((var(--header-h) + 100dvh - var(--stage-bottom, 0px) - var(--shell-gap)) / 2);
  transform: translateY(-50%);
  width: 52px; height: 52px; border-radius: 50%;
  background: var(--surface);
  backdrop-filter: blur(20px) saturate(1.2);
  -webkit-backdrop-filter: blur(20px) saturate(1.2);
  border: 1px solid var(--fg-a05);
  color: var(--fg);
  z-index: 20; display: grid; place-items: center;
  transition: background var(--transition-fast), border-color var(--transition-fast),
              color var(--transition-fast), opacity var(--transition-fast),
              transform var(--transition-fast),
              top var(--transition-med), left var(--transition-med), right var(--transition-med);
}
.nav-arrow:hover { background: var(--scene-accent); border-color: var(--scene-accent); color: #fff; }
.nav-arrow:hover:not(:disabled) { transform: translateY(-50%) scale(1.04); }
.nav-arrow:disabled { opacity: 0.25; pointer-events: none; }

.nav-left  { left:  calc(var(--stage-left,  0px) + var(--shell-gap) + 14px); }
.nav-right { right: calc(var(--stage-right, 0px) + var(--shell-gap) + 14px); }

/* Nav hints tooltip */
.nav-tip {
  position: absolute;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 7px 10px; border-radius: 8px;
  background: rgba(20, 22, 30, 0.92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--fg-a12);
  color: var(--fg); font-size: 12px; font-weight: 500;
  white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity .2s;
  z-index: 1;
}
.nav-left  .nav-tip { left: calc(100% + 10px); }
.nav-right .nav-tip { right: calc(100% + 10px); }
.nav-tip kbd {
  font-family: var(--mono);
  font-size: 10px; color: var(--fg-a55);
  letter-spacing: .04em;
}
:root:not(.nav-hints-dismissed) .nav-arrow:hover .nav-tip { opacity: 1; }

/* ===== HEADER BUTTONS =====
   Tips, open-in-new-tab and every action share one control: same box, same
   surface, same hover — the header reads as a single row of switches. */
.action-btn,
.scene-help-btn,
.scene-open-btn {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  width: 36px; height: 36px; padding: 0;
  border-radius: 10px;
  border: 1px solid var(--fg-a05);
  background: var(--fg-a05);
  color: var(--fg);
  font-family: var(--mono);
  font-size: 11px; letter-spacing: .1em;
  box-shadow: none; opacity: 1;
  transition: background .2s, border-color .2s, color .2s;
}
.action-btn:hover,
.scene-help-btn:hover,
.scene-open-btn:hover { background: var(--fg-a12); }
.action-pill { width: auto; padding: 0 10px; }

.action-bar { display: flex; align-items: center; gap: 6px; color: var(--fg); }
.scene-help    { position: relative; }
.scene-open-btn{ position: relative; }
.scene-help[hidden], .scene-open-btn[hidden] { display: none; }
.scene-help.open .scene-help-btn {
  background: color-mix(in srgb, var(--menu-orb) 26%, var(--fg-a08));
  border-color: var(--fg-a25);
}

/* Lang selector */
.lang-selector { position: relative; }
.lang-dropdown {
  position: absolute;
  top: calc(100% + 10px); right: 0; left: auto; bottom: auto;
  width: 240px; max-height: min(420px, 60vh); overflow-y: auto;
  display: flex; flex-direction: column; gap: 1px;
  background: var(--surface-solid);
  border: 1px solid var(--fg-a12);
  border-radius: 14px;
  padding: 6px;
  box-shadow: 0 24px 60px -18px rgba(0,0,0,.55);
  transform-origin: top right;
  opacity: 0; visibility: hidden; transform: translateY(-6px) scale(.98);
  z-index: 40;
  scrollbar-width: thin;
  transition: opacity var(--transition-fast), visibility var(--transition-fast), transform var(--transition-fast);
}
.lang-selector.open .lang-dropdown { opacity: 1; visibility: visible; transform: translateY(0) scale(1); }
.lang-option {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; border-radius: 8px;
  font-size: 13px; color: var(--fg-a75);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.lang-option:hover { background: var(--fg-a08); color: var(--fg); }
.lang-option.active { color: var(--fg); font-weight: 600; }
.lang-option.active::after {
  content: '✓';
  margin-left: auto;
  color: var(--scene-accent);
  font-weight: 700;
}
.flag-icon { width: 18px; height: 14px; object-fit: cover; border-radius: 2px; }

/* ===== SIDEBAR ===== */
.sidebar {
  position: fixed; top: 0; right: 0; bottom: 0;
  width: var(--sidebar-w);
  z-index: 25;
  pointer-events: none;
}
/* Hovered open, the panel slides out across the header row, so it has to win the
   stacking order — otherwise the header's action cluster paints over the
   sidebar's own head and swallows the clicks meant for the pin button. Pinned,
   the header already stops at the panel's edge, and collapsed it must stay under
   the header so the top-right corner (the hide-UI toggle) keeps its clicks. */
.sidebar.open:not(.pinned) { z-index: 35; }
.sidebar-hover-zone,
.sidebar-handle,
.sidebar-panel { pointer-events: auto; }
.sidebar-hover-zone {
  position: absolute; top: 0; bottom: 0;
  right: 0;
  width: 28px;
  z-index: 0; /* stay under the panel/handle so it never intercepts their clicks */
  transition: width var(--transition-med);
}
.sidebar.open .sidebar-hover-zone { width: calc(var(--sidebar-w) + 22px); }

/* Reveal handle — a small diamond tab pinned to the peek strip, vertically
   centred on the header row. Fades out once the panel is open or pinned. */
.sidebar-handle {
  --size: 30px;
  position: absolute;
  top: calc((var(--header-h) - var(--size)) / 2);
  right: calc(var(--peek) - (var(--size) / 2));
  width: var(--size);
  height: var(--size);
  background: var(--surface);
  border-bottom-left-radius: 4px;
  backdrop-filter: blur(20px) saturate(1.2);
  -webkit-backdrop-filter: blur(20px) saturate(1.2);
  border: 1px solid var(--fg-a05);
  border-right: none;
  color: var(--fg);
  display: grid; place-items: center;
  z-index: 2;
  opacity: 1;
  box-shadow: -4px 8px 20px -6px rgba(0,0,0,0.25);
  transform: rotate(45deg);
  transition:
    opacity .25s,
    top var(--transition-med),
    right var(--transition-med),
    transform var(--transition-med),
    background .35s;
}
.sidebar-handle > svg { transform: rotate(-45deg) translateX(-6px); }
.sidebar-handle:hover { opacity: 0; scale: .95; }
.sidebar.open .sidebar-handle { opacity: 0; pointer-events: none; scale: 0.95; }
.sidebar.pinned .sidebar-handle { display: none; }

.sidebar-panel {
  position: absolute; top: 0; right: calc(-1 * (var(--sidebar-w) - var(--peek))); bottom: 0;
  width: var(--sidebar-w);
  background: var(--menu-bg);
  backdrop-filter: blur(24px) saturate(1.2);
  -webkit-backdrop-filter: blur(24px) saturate(1.2);
  /* Collapsed only the left edge shows; the border exists on all four sides but
     transparent, so opening into the island animates just the color. */
  border: 1px solid transparent;
  border-left-color: var(--fg-a08);
  border-radius: 0;
  display: flex; flex-direction: column;
  gap: 0;
  overflow: hidden;
  isolation: isolate;
  transition: top var(--transition-med), bottom var(--transition-med),
              right var(--transition-med), border-radius var(--transition-med),
              border-color var(--transition-med), box-shadow var(--transition-med),
              background .35s, backdrop-filter .35s;
}
/* Open — hovered or pinned — the panel floats free of the viewport edges as a
   rounded island, matching the stage window. Collapsed it stays a full-height
   flush strip with square corners (the 10px peek). */
.sidebar.open .sidebar-panel {
  top: var(--island-gap); bottom: var(--island-gap); right: var(--island-gap);
  border-color: var(--fg-a05);
  border-radius: var(--window-radius);
  box-shadow: 0 30px 70px -30px rgba(0,0,0,.7);
}
.sidebar.open:not(.pinned) .sidebar-panel {
  backdrop-filter: blur(32px) saturate(1.5);
  -webkit-backdrop-filter: blur(32px) saturate(1.5);
}

/* Orb blobs */
.sidebar-panel::before,
.sidebar-panel::after {
  content: '';
  position: absolute;
  border-radius: 50%;
  filter: blur(60px);
  opacity: 0.45;
  pointer-events: none;
  z-index: -1;
  background: var(--menu-orb);
  transition: background .6s;
}
.sidebar-panel::before { width: 200px; height: 200px; top: -60px; right: -60px; }
.sidebar-panel::after  { width: 160px; height: 160px; bottom: 60px; left: -40px; opacity: 0.3; }

.sidebar-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 16px 14px;
  flex-shrink: 0;
}
.sidebar-brand { display: flex; align-items: center; gap: 10px; min-width: 0; }

.sidebar-logo {
  width: 36px; height: 36px; border-radius: 9px;
  background: var(--menu-orb);
  color: var(--menu-orb-fg);
  display: grid; place-items: center;
  font-size: 16px; font-weight: 700;
  flex-shrink: 0; overflow: hidden;
  position: relative;
  transition: background .6s, color .3s;
}
.sidebar-logo .ico-slot {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  opacity: 0; transform: scale(0.82); filter: blur(4px);
  transition:
    opacity .45s cubic-bezier(.4,0,.2,1),
    transform .5s cubic-bezier(.4,0,.2,1),
    filter .45s cubic-bezier(.4,0,.2,1);
  pointer-events: none;
}
.sidebar-logo .ico-slot.visible { opacity: 1; transform: scale(1); filter: blur(0); }
.sidebar-logo .ico-slot img { width: 100%; height: 100%; object-fit: cover; }
.sidebar-brand-text { min-width: 0; }
.sidebar-title {
  font-size: 14px;
  color: var(--fg); letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sidebar-subtitle {
  font-size: 11px; color: var(--fg-a55);
  white-space: nowrap; margin-top: 1px;
}

.sidebar-pin {
  width: 30px; height: 30px; border-radius: 7px;
  display: grid; place-items: center;
  color: var(--fg-a40); flex-shrink: 0;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.sidebar-pin:hover { background: var(--fg-a08); color: var(--fg); }
.sidebar-pin .icon-collapse { display: none; }
.sidebar.pinned .sidebar-pin .icon-pin     { display: none; }
.sidebar.pinned .sidebar-pin .icon-collapse { display: inline; }

/* ===== TAG CLOUD ===== */
.tag-cloud-wrap {
  padding: 4px 14px 8px;
  flex-shrink: 0;
}

.tag-cloud {
  position: relative;
  display: flex; flex-wrap: wrap; gap: 5px;
  padding: 3px;
}

/* Sliding indicator for the "All" chip — an opaque pill the active label rides
   on top of. JS sets top/left/width/height to the active chip's own box, so it
   tracks a single chip even when the chips wrap onto a second row (otherwise it
   would span the full cloud height and bleed over the row below). */
.filter-indicator {
  position: absolute;
  top: 3px; height: 24px;
  border-radius: 7px;
  background: var(--menu-orb);
  opacity: 1;
  pointer-events: none;
  transition: left .2s cubic-bezier(.2,.8,.2,1), top .2s cubic-bezier(.2,.8,.2,1),
              width .2s cubic-bezier(.2,.8,.2,1), height .2s cubic-bezier(.2,.8,.2,1),
              opacity .2s, background .35s;
  z-index: 0;
}

.tag-chip {
  position: relative; z-index: 1;
  padding: 4px 9px;
  border-radius: 7px;
  font-size: 11px; font-weight: 500;
  background: var(--fg-a05);
  border: 1px solid var(--fg-a05);
  color: var(--fg-a75);
  transition: background var(--transition-fast), color var(--transition-fast),
              border-color var(--transition-fast);
  cursor: pointer;
}
.tag-chip:hover {
  background: var(--fg-a08);
  color: var(--fg);
}
.tag-chip.active {
  background: transparent;
  border-color: transparent;
  color: var(--menu-orb-fg);
  font-weight: 600;
}
/* The sliding pill only ever tracks the "all" chip (the filter is multi-select,
   one pill cannot cover several chips), so every other active tag paints the
   same pill itself — without it the label would sit on bare sidebar and turn
   unreadable on light scenes. */
.tag-chip.active:not([data-tag="all"]) {
  background: var(--menu-orb);
  border-color: var(--menu-orb);
}

/* ===== SIDEBAR CONTENT ===== */
.sidebar-meta {
  display: flex; justify-content: space-between; align-items: center;
  padding: 4px 16px 6px;
  font-size: 11px; color: var(--fg-a40);
  letter-spacing: .04em; text-transform: uppercase;
  flex-shrink: 0;
}
.sidebar-list {
  flex: 1;
  overflow-y: auto; overflow-x: hidden;
  padding: 4px 8px 8px;
  display: flex; flex-direction: column; gap: 2px;
}
.sidebar-footer {
  flex-shrink: 0;
  display: flex; align-items: center;
  padding: 10px 12px;
  border-top: 1px solid var(--fg-a05);
}
/* On mobile the action bar rides in the header — a footer left without it must
   not keep a bordered gap (:empty would miss the leftover whitespace nodes). */
.sidebar-footer:not(:has(.action-bar)) { display: none; }
.sidebar-footer .action-bar { display: flex; width: 100%; gap: 6px; }
.sidebar-footer .lang-selector { margin-left: auto; }
/* Inside the island (overflow: hidden) the dropdown opens upward. */
.sidebar-footer .lang-dropdown {
  top: auto; bottom: calc(100% + 10px);
  transform-origin: bottom right;
  transform: translateY(6px) scale(.98);
}

/* Scene list items */
.scene-item {
  display: flex; align-items: center; gap: 14px;
  padding: 10px;
  border-radius: 12px;
  color: var(--fg-a75);
  width: 100%;
  text-align: left;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.scene-item:hover { background: var(--fg-a05); color: var(--fg); }
.scene-item.active {
  background: color-mix(in srgb, var(--menu-orb) 14%, var(--fg-a05));
  color: var(--fg);
}

.scene-thumb {
  width: 82px; height: 54px;
  border-radius: 8px;
  background: var(--sc-bg, #0a0a14);
  outline: 1px solid var(--fg-a08);
  flex-shrink: 0; overflow: hidden;
  position: relative;
  transition: outline .2s;
}
.scene-item.active .scene-thumb {
  outline: 1.5px solid var(--fg-a55);
  outline-offset: 1px;
}
.scene-thumb img {
  width: 100%; height: 100%; object-fit: cover;
  display: block;
}
.scene-thumb-fallback {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-size: 22px;
}
.scene-thumb-overlay {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 40%, rgba(0,0,0,.35) 100%);
}
.scene-thumb.intro {
  background: linear-gradient(135deg, var(--sc-bg, #0a0a14), color-mix(in srgb, var(--sc-accent, #6366f1) 30%, var(--sc-bg, #0a0a14)));
}
.intro-label {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; font-size: 10px;
  color: var(--fg-a55); letter-spacing: .1em; text-transform: uppercase;
}
.intro-mark { font-size: 18px; }

.scene-info { min-width: 0; flex: 1; }
.scene-name {
  font-size: 12px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: inherit;
}
.scene-num {
  font-size: 10px;
  font-family: var(--mono);
  color: var(--fg-a40); letter-spacing: .04em;
  margin-top: 2px;
}

/* Hidden by filter */
.scene-item.hidden, .dock-item.hidden { display: none; }
.scene-item, .dock-item {
  animation: filter-in .28s cubic-bezier(.2,.8,.2,1) both;
}
@keyframes filter-in {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ===== MOBILE DOCK ===== */
.mobile-dock {
  display: none;
  position: fixed; bottom: 0; left: 0; right: 0;
  height: var(--dock-h, 118px);
  z-index: 20;
  background: var(--surface);
  backdrop-filter: blur(20px) saturate(1.2);
  -webkit-backdrop-filter: blur(20px) saturate(1.2);
  border-top: 1px solid var(--fg-a08);
  padding: 10px 0 14px;
}

.mobile-dock-track {
  display: flex; align-items: flex-start; gap: 8px;
  overflow-x: auto; overflow-y: hidden;
  padding: 0 12px;
  height: 100%;
  scroll-snap-type: x mandatory;
}
.dock-item {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  flex-shrink: 0;
  scroll-snap-align: center;
  padding: 2px;
  border-radius: 10px;
  transition: background var(--transition-fast);
}
.dock-item:hover { background: var(--fg-a05); }
.dock-item.active { background: color-mix(in srgb, var(--menu-orb) 14%, var(--fg-a05)); }

.dock-thumb {
  width: 56px; height: 56px; border-radius: 10px;
  background: var(--sc-bg, #0a0a14);
  border: 1px solid var(--fg-a08);
  overflow: hidden; flex-shrink: 0;
  display: grid; place-items: center;
  font-size: 20px;
}
.dock-thumb.intro {
  background: linear-gradient(135deg, var(--sc-bg, #0a0a14), color-mix(in srgb, var(--sc-accent, #6366f1) 30%, var(--sc-bg, #0a0a14)));
}
.dock-thumb img { width: 100%; height: 100%; object-fit: cover; }
.dock-name {
  font-size: 9px; font-weight: 500; color: var(--fg-a55);
  max-width: 60px; text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ===== SHORTCUTS MODAL ===== */
.modal-backdrop {
  position: fixed; inset: 0;
  z-index: 60;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(8px);
  display: grid;
  place-items: center;
  opacity: 0;
  visibility: hidden;
  scale: 1.1;
  filter: blur(8px);
  transition: opacity .18s, visibility .18s, transform .25s, scale .25s, filter .25s;
}
.modal-backdrop.open {
  opacity: 1;
  visibility: visible;
  scale: 1;
  filter: blur(0);
}

.modal {
  background: var(--surface-solid);
  border: 1px solid var(--fg-a12);
  border-radius: 18px;
  padding: 24px;
  width: min(400px, calc(100vw - 32px));
  box-shadow: 0 24px 64px rgba(0,0,0,.5);
}
.modal-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  margin-bottom: 20px;
}
.modal-eyebrow {
  font-size: 10px; letter-spacing: .15em;
  text-transform: uppercase; color: var(--fg-a40);
  margin-bottom: 4px;
}
.modal-title { font-size: 20px; color: var(--fg); }
.modal-close {
  width: 30px; height: 30px; border-radius: 8px;
  display: grid; place-items: center;
  color: var(--fg-a55);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.modal-close:hover { background: var(--fg-a08); color: var(--fg); }

.shortcut-list { display: flex; flex-direction: column; gap: 6px; }
.shortcut-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 10px; border-radius: 8px;
  background: var(--fg-a05);
  font-size: 13px; color: var(--fg-a75);
}
.shortcut-row kbd {
  font-family: var(--mono);
  font-size: 11px; color: var(--fg-a55);
  background: var(--fg-a08);
  border: 1px solid var(--fg-a12);
  border-radius: 5px;
  padding: 2px 7px;
}

/* ===== SCENE HELP PANEL =====
   Anchored under the tips button in the header, so it opens downward. */
.scene-help-panel {
  position: absolute;
  top: calc(100% + 10px); right: 0; left: auto; bottom: auto;
  width: 320px; max-width: calc(100vw - 2 * var(--shell-gap));
  background: var(--surface-solid);
  border: 1px solid var(--fg-a12);
  border-radius: 14px;
  padding: 14px 16px 16px;
  box-shadow: 0 24px 60px -18px rgba(0,0,0,.55);
  transform-origin: top right;
  transform: scale(.92); opacity: 0; pointer-events: none;
  display: block;
  z-index: 40;
  transition: opacity .2s cubic-bezier(.2,.8,.2,1), transform .22s cubic-bezier(.2,.8,.2,1);
}
.scene-help.open .scene-help-panel { opacity: 1; transform: scale(1); pointer-events: auto; }

.scene-help-head {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 10px;
}
.scene-help-title { font-size: 13px; color: var(--fg); }
.scene-help-close {
  width: 24px; height: 24px; border-radius: 6px;
  display: grid; place-items: center;
  color: var(--fg-a40);
  transition: background var(--transition-fast), color var(--transition-fast);
}
.scene-help-close:hover { background: var(--fg-a08); color: var(--fg); }

.scene-help-list {
  list-style: none; display: flex; flex-direction: column; gap: 6px;
}
.scene-help-list li {
  font-size: 12px; line-height: 1.55; color: var(--fg-a75);
  padding-left: 12px; position: relative;
}
.scene-help-list li::before {
  content: '→';
  position: absolute; left: 0;
  color: var(--scene-accent);
  font-size: 10px;
}

/* ===== TOAST ===== */
.toast {
  position: fixed;
  bottom: calc(var(--stage-bottom, 0px) + var(--shell-gap) + 18px);
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: var(--surface-solid);
  border: 1px solid var(--fg-a12);
  border-radius: 12px;
  padding: 10px 16px;
  font-size: 13px; font-weight: 500;
  color: var(--fg);
  z-index: 100;
  opacity: 0; pointer-events: none;
  transition: opacity .22s, transform .22s cubic-bezier(.2,.8,.2,1), bottom var(--transition-med);
  box-shadow: 0 8px 24px rgba(0,0,0,.3);
  max-width: calc(100vw - 32px);
}
.toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}
.toast--copy {
  display: flex; align-items: flex-start; gap: 10px;
}
.toast-icon { flex-shrink: 0; margin-top: 1px; }
.toast-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.toast-url {
  font-size: 11px;
  font-family: var(--mono);
  color: var(--fg-a55);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 240px;
}

/* ===== CUSTOM TOOLTIP =====
   One floating singleton fed from data-tip; replaces the native title bubbles
   on all chrome controls. Positioned by the engine with fixed coordinates. */
.ui-tip {
  position: fixed; left: 0; top: 0;
  max-width: min(280px, calc(100vw - 16px));
  padding: 6px 10px;
  border-radius: 8px;
  background: var(--surface-solid);
  border: 1px solid var(--fg-a08);
  color: var(--fg);
  font-size: 11px; font-weight: 500;
  box-shadow: 0 12px 32px -14px rgba(0,0,0,.5);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  pointer-events: none;
  z-index: 80;
  opacity: 0;
  transform: translateY(4px) scale(.97);
  transition: opacity .18s cubic-bezier(.2,.8,.2,1), transform .18s cubic-bezier(.2,.8,.2,1);
}
.ui-tip.above { transform: translateY(-4px) scale(.97); }
.ui-tip.show { opacity: 1; transform: translateY(0) scale(1); }

/* Scene credit in the help panel */
.scene-help-list li.scene-help-credit {
  margin-top: 8px; padding-top: 8px; padding-left: 0;
  border-top: 1px solid var(--fg-a08);
  color: var(--fg-a40); font-size: 11px;
}
.scene-help-list li.scene-help-credit::before { content: none; }

/* ===== MOBILE ===== */
@media (max-width: 760px) {
  :root { --shell-gap: 10px; --header-h: 58px; --window-radius: 12px; }
  .app-header { right: 0; gap: 8px; padding: 0 var(--shell-gap); }
  .scene-label { gap: 8px; }
  .lab-home, .scene-label-icon { width: 34px; height: 34px; }
  .lab-home { grid-template-columns: 34px minmax(0, 0fr); }
  .lab-home:hover, .lab-home:focus-visible { grid-template-columns: 34px minmax(0, 1fr); }
  .scene-label-name .label-slot { font-size: 12px; max-width: 40vw; }
  .action-btn, .scene-help-btn, .scene-open-btn { width: 32px; height: 32px; border-radius: 9px; }
  /* The language pill is text-sized, not a square. */
  .action-pill { width: auto; }
  #actFullscreen, #actShortcuts { display: none; }
  .sidebar { display: none; }
  .mobile-dock { display: block; }
  .nav-arrow { width: 44px; height: 44px; }
  .nav-tip { display: none; }
}

/* ===== HIDE THE INTERFACE =====
   One switch clears the chrome around the window, because a lab's own controls
   frequently live under ours. The window itself goes full-bleed and a single
   faint toggle is left floating in the corner. The iframe is never touched. */
.ui-toggle .icon-show { display: none; }
.ui-toggle[aria-pressed="true"] .icon-hide { display: none; }
.ui-toggle[aria-pressed="true"] .icon-show { display: block; }
.ui-toggle[aria-pressed="true"] {
  background: color-mix(in srgb, var(--menu-orb) 20%, var(--fg-a08));
  color: var(--fg);
}

:root.ui-hidden { --header-h: 0px; --shell-gap: 0px; --window-radius: 0px; }
:root.ui-hidden .stage { border-color: transparent; box-shadow: none; }
/* The zeroed --window-radius is for the full-bleed stage; the floating island
   keeps its own rounding. */
:root.ui-hidden .sidebar.open .sidebar-panel { border-radius: 16px; }

/* The whole header goes away; the floating restore button and the sidebar
   remain as the ways back in. */
:root.ui-hidden .app-header { display: none; }

/* Floating restore control — engine-built, appended to <body>. */
.ui-restore {
  display: none;
  position: fixed; top: 10px; right: 10px;
  z-index: 50;
  background: var(--surface);
  border-color: var(--fg-a12);
  backdrop-filter: blur(20px) saturate(1.2);
  -webkit-backdrop-filter: blur(20px) saturate(1.2);
  opacity: .45;
  transition: opacity var(--transition-fast), background .2s, border-color .2s;
}
.ui-restore:hover,
.ui-restore:focus-visible { opacity: 1; background: var(--fg-a12); }
:root.ui-hidden .ui-restore { display: inline-flex; }

/* The handle centres itself in the header row — with --header-h at 0 that would
   put it half off the top edge, under the restore button. Drop it below the
   button so the sidebar keeps a visible way in. */
:root.ui-hidden .sidebar-handle { top: 54px; }

/* visibility, not opacity alone: a fully transparent overlay would still eat
   the clicks meant for the lab underneath. */
:root.ui-hidden .nav-arrow,
:root.ui-hidden .mobile-dock {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--transition-fast) ease, visibility 0s var(--transition-fast);
}

/* ===== SECTION TYPOGRAPHY =====
   The engine only names the roles; each section's style.css supplies the faces
   through --display / --text / --mono. */
.sidebar-title,
.modal-title,
.modal-eyebrow,
.scene-help-title,
.toast-label,
.intro-label,
.scene-label-name .label-slot,
.action-btn.action-pill {
  font-family: var(--display);
  font-weight: var(--display-weight);
}
