/*
 * The shared top bar (assets/wkx-topbar.js). Everything is scoped to
 * .pt-topbar; colours read the app's --pt-* tokens where a page defines them
 * and fall back to the same values elsewhere.
 */
.pt-topbar {
  container: pt-topbar / inline-size;
  margin: 0 0 var(--pt-space-5, 20px);
  min-width: 0;
  color: var(--pt-text-primary, #f7f5ff);
  font-family: inherit;
}
.pt-topbar .pt-topbar-inner { display: flex; align-items: center; gap: 16px; min-width: 0; }
.pt-topbar [hidden] { display: none !important; }

/* Search: the app's one text search (Ctrl/⌘+K or /). */
.pt-topbar .pt-topbar-search {
  flex: 1 1 560px; max-width: 640px; min-width: 0; height: 44px; box-sizing: border-box;
  display: flex; align-items: center; gap: 10px; margin: 0; padding: 0 8px 0 14px;
  border: 1px solid var(--pt-border-strong, rgba(255, 255, 255, .13)); border-radius: var(--pt-radius-control, 12px);
  background: rgba(14, 12, 26, .74);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .04);
  transition: border-color 180ms ease, box-shadow 180ms ease, background-color 180ms ease;
}
.pt-topbar .pt-topbar-search:hover { border-color: rgba(255, 255, 255, .2); }
.pt-topbar .pt-topbar-search:focus-within {
  border-color: var(--pt-border-active, rgba(167, 139, 250, .62)); background: rgba(18, 15, 34, .92);
  box-shadow: 0 0 0 3px rgba(124, 92, 255, .2);
}
.pt-topbar .pt-topbar-search-icon { width: 18px; height: 18px; flex: 0 0 auto; color: var(--pt-text-muted, rgba(228, 224, 246, .6)); }
.pt-topbar input.pt-topbar-input,
.pt-topbar input.pt-topbar-input:focus,
.pt-topbar input.pt-topbar-input:focus-visible {
  flex: 1 1 auto; min-width: 0; height: 100%; padding: 0; margin: 0;
  border: 0; border-radius: 0; outline: none; box-shadow: none; background: transparent;
  color: var(--pt-text-primary, #f7f5ff); font: inherit; font-size: 14px;
  text-overflow: ellipsis;   /* a narrow field ends its placeholder on "…", never mid-word */
}
.pt-topbar input.pt-topbar-input::placeholder { color: var(--pt-text-muted, rgba(228, 224, 246, .6)); opacity: 1; }
.pt-topbar input.pt-topbar-input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.pt-topbar .pt-topbar-kbd { display: inline-flex; gap: 4px; flex: 0 0 auto; font: inherit; }
.pt-topbar .pt-topbar-kbd span {
  min-width: 24px; height: 24px; padding: 0 7px; box-sizing: border-box; display: inline-grid; place-items: center;
  border: 1px solid var(--pt-border-strong, rgba(255, 255, 255, .13)); border-radius: 7px; background: rgba(255, 255, 255, .04);
  color: var(--pt-text-secondary, rgba(228, 224, 246, .68)); font-size: 11px; font-weight: 600; line-height: 1;
}
/* Clear (×): only for a host with onClear, only while the field holds text. */
.pt-topbar .pt-topbar-clear {
  width: 28px; height: 28px; flex: 0 0 auto; display: inline-grid; place-items: center; margin: 0; padding: 0;
  border: 0; border-radius: 8px; background: transparent; color: var(--pt-text-muted, rgba(228, 224, 246, .6)); cursor: pointer;
}
.pt-topbar .pt-topbar-clear:hover { background: rgba(255, 255, 255, .07); color: var(--pt-text-primary, #f7f5ff); }
.pt-topbar .pt-topbar-clear:focus-visible { outline: 2px solid var(--pt-border-active, rgba(167, 139, 250, .62)); outline-offset: 1px; }
.pt-topbar .pt-topbar-clear svg { width: 16px; height: 16px; }

.pt-topbar .pt-topbar-right { display: flex; align-items: center; gap: 16px; flex: 0 0 auto; margin-left: auto; min-width: 0; }

/* Menu (the app's navigation): only on a phone-width window, where the
   sidebar is an off-canvas drawer (index.html, the responsive shell). */
.pt-topbar .pt-topbar-nav {
  display: none; place-items: center; flex: 0 0 auto;
  width: 44px; height: 44px; padding: 0; margin: 0; box-sizing: border-box;
  border: 1px solid var(--pt-border-strong, rgba(255, 255, 255, .13)); border-radius: var(--pt-radius-control, 12px);
  background: rgba(14, 12, 26, .74); color: var(--pt-text-secondary, rgba(228, 224, 246, .68)); cursor: pointer;
}
.pt-topbar .pt-topbar-nav svg { width: 20px; height: 20px; }
.pt-topbar .pt-topbar-nav:hover { color: var(--pt-text-primary, #f7f5ff); border-color: rgba(255, 255, 255, .2); }
.pt-topbar .pt-topbar-nav:focus-visible { outline: none; box-shadow: var(--pt-focus-ring, 0 0 0 2px #0b0916, 0 0 0 4px rgba(167, 139, 250, .9)); }
@media (max-width: 600px) {
  .pt-topbar .pt-topbar-nav { display: inline-grid; }
}

/* Engine status: ready / loading / unavailable, and "All systems online"
   under it only when the engine is ready and the song worker is alive. */
.pt-topbar .pt-topbar-engine {
  display: inline-flex; align-items: center; gap: 9px; flex: 0 0 auto;
  height: 40px; box-sizing: border-box; padding: 0 14px;
  border: 1px solid var(--pt-border-strong, rgba(255, 255, 255, .13)); border-radius: 12px;
  background: rgba(14, 12, 26, .74); color: var(--pt-text-secondary, rgba(228, 224, 246, .68));
  white-space: nowrap;
}
.pt-topbar .pt-topbar-engine-text { display: flex; flex-direction: column; justify-content: center; gap: 2px; min-width: 0; }
.pt-topbar .pt-topbar-engine-label { font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; line-height: 1.15; }
.pt-topbar .pt-topbar-systems {
  font-size: 10.5px; font-weight: 500; letter-spacing: 0; text-transform: none; line-height: 1.15;
  color: var(--pt-text-muted, rgba(228, 224, 246, .6));
}
.pt-topbar .pt-topbar-dot {
  width: 8px; height: 8px; flex: 0 0 auto; border-radius: 50%;
  background: var(--pt-text-muted, rgba(228, 224, 246, .6));
}
.pt-topbar .pt-topbar-engine.is-ready { color: #5eead4; border-color: rgba(45, 212, 191, .36); background: rgba(13, 148, 136, .14); }
/* The READY dot is still: an infinite animation here made the compositor draw
   every vsync through the app's full-window glass (measured 2026-09-28: the
   idle app's GPU process at 13-75% and its renderer at 35% CPU, in the
   desktop shell and in a plain Chromium tab alike; nothing else on the page
   was running). Activity states (loading, generating) still pulse. */
.pt-topbar .pt-topbar-engine.is-ready .pt-topbar-dot {
  background: var(--pt-success, #2dd4bf); box-shadow: 0 0 10px rgba(45, 212, 191, .75);
}
/* Activity (loading, generating, embedding) is shown by a slow blink that
   wkx-topbar.js drives by flipping .is-dim on the dot about every 700 ms: one
   composited frame per flip instead of one per vsync. Any infinite CSS
   animation in this bar made the compositor redraw the whole window through
   its glass effects 60 times a second (measured 2026-09-28: the idle desktop
   app's GPU process at 13-160% and its renderer at 35-45% CPU). */
/* no transition on the dot: a blink flip must cost one frame, not a 350 ms animation (measured 2026-09-28) */
.pt-topbar .pt-topbar-dot.is-dim { opacity: .35; }
.pt-topbar .pt-topbar-engine.is-loading { color: var(--pt-text-accent, #ddd6fe); border-color: rgba(167, 139, 250, .38); background: var(--pt-accent-soft, rgba(124, 92, 255, .16)); }
.pt-topbar .pt-topbar-engine.is-loading .pt-topbar-dot {
  background: var(--pt-accent-bright, #a78bfa); box-shadow: 0 0 10px rgba(167, 139, 250, .7);
}
.pt-topbar .pt-topbar-engine.is-offline { color: #cbb3b8; border-color: rgba(203, 179, 184, .24); background: rgba(80, 60, 70, .16); }
.pt-topbar .pt-topbar-engine.is-offline .pt-topbar-dot { background: #a8878e; }
/* failed: ENGINE ERROR, a clear red */
.pt-topbar .pt-topbar-engine.is-error { color: #fca5a5; border-color: rgba(248, 113, 113, .4); background: rgba(127, 29, 29, .2); }
.pt-topbar .pt-topbar-engine.is-error .pt-topbar-dot { background: var(--pt-danger, #f05252); }
/* Stopped but startable: amber, as Create's "isn't running" banner. */
.pt-topbar .pt-topbar-engine.is-stopped { color: #fde68a; border-color: rgba(251, 191, 36, .3); background: rgba(251, 191, 36, .07); }
.pt-topbar .pt-topbar-engine.is-stopped .pt-topbar-dot { background: var(--pt-warning, #fbbf24); }
@keyframes ptTopbarBreathe {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: .55; transform: scale(.78); }
}
@keyframes ptTopbarPulse { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }

/* Embedding (admins only): samples embedding, waiting or failed; opens
   Processing. Its full breakdown is the tooltip and the accessible name. */
.pt-topbar .pt-topbar-embed {
  display: inline-flex; align-items: center; gap: 8px; flex: 0 1 auto; min-width: 0;
  height: 40px; box-sizing: border-box; padding: 0 12px; margin: 0;
  border: 1px solid rgba(167, 139, 250, .3); border-radius: 12px;
  background: rgba(124, 92, 255, .1); color: var(--pt-text-accent, #ddd6fe);
  font: inherit; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; line-height: 1;
  white-space: nowrap; cursor: pointer;
}
.pt-topbar .pt-topbar-embed-text { overflow: hidden; text-overflow: ellipsis; }
.pt-topbar .pt-topbar-embed-short { display: none; font-variant-numeric: tabular-nums; }
.pt-topbar .pt-topbar-embed .pt-topbar-dot { background: var(--pt-accent-bright, #a78bfa); }
.pt-topbar .pt-topbar-embed[data-state="running"] .pt-topbar-dot {
  box-shadow: 0 0 10px rgba(167, 139, 250, .7);
}
.pt-topbar .pt-topbar-embed[data-state="failed"] { color: #fca5a5; border-color: rgba(248, 113, 113, .34); background: rgba(127, 29, 29, .18); }
.pt-topbar .pt-topbar-embed[data-state="failed"] .pt-topbar-dot { background: var(--pt-danger, #f87171); }
.pt-topbar .pt-topbar-embed[data-state="stale"] {
  color: var(--pt-text-muted, rgba(228, 224, 246, .6)); border-color: var(--pt-border-strong, rgba(255, 255, 255, .13)); background: rgba(14, 12, 26, .74);
}
.pt-topbar .pt-topbar-embed[data-state="stale"] .pt-topbar-dot { background: var(--pt-text-muted, rgba(228, 224, 246, .6)); }
.pt-topbar .pt-topbar-embed:hover { border-color: rgba(167, 139, 250, .55); }
.pt-topbar .pt-topbar-embed:focus-visible { outline: none; box-shadow: var(--pt-focus-ring, 0 0 0 2px #0b0916, 0 0 0 4px rgba(167, 139, 250, .9)); }

/* Machine stats: label over value, a thin meter for how full each one is. */
.pt-topbar .pt-topbar-stats { display: flex; align-items: stretch; gap: 24px; flex: 0 0 auto; }
.pt-topbar .pt-topbar-stat {
  display: flex; flex-direction: column; justify-content: center; gap: 4px;
  min-width: 36px; cursor: default;
}
.pt-topbar .pt-topbar-stat-label {
  font-size: 10px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; line-height: 1;
  color: var(--pt-text-muted, rgba(228, 224, 246, .6)); white-space: nowrap;
}
.pt-topbar .pt-topbar-stat-value {
  font-size: 13px; font-weight: 700; line-height: 1.1; white-space: nowrap;
  color: var(--pt-text-primary, #f7f5ff); font-variant-numeric: tabular-nums;
}
.pt-topbar .pt-topbar-meter {
  display: block; width: 100%; height: 2px; border-radius: 2px; overflow: hidden;
  background: rgba(255, 255, 255, .08);
}
.pt-topbar .pt-topbar-meter b {
  display: block; width: 0; height: 100%; border-radius: inherit;
  background: linear-gradient(90deg, #7c5cff, #a78bfa);
  /* no width transition: a 2 px meter updated every poll animated 4 bars for
     0.4 s each time -- continuous repaints on an idle window (2026-09-28) */
}
/* A GPU reading older than one poll: dimmed, with its age by the label. */
.pt-topbar .pt-topbar-stat-age { font-weight: 500; letter-spacing: 0; text-transform: none; }
.pt-topbar .pt-topbar-stat.is-stale .pt-topbar-stat-value { color: var(--pt-text-muted, rgba(228, 224, 246, .6)); }
.pt-topbar .pt-topbar-stat.is-stale .pt-topbar-meter b { opacity: .4; }

/* Bell (the app's notifications) and the signed-in account. */
.pt-topbar .pt-topbar-bell {
  position: relative; display: inline-grid; place-items: center; flex: 0 0 auto;
  width: 40px; height: 40px; padding: 0; margin: 0 6px 0 0; box-sizing: border-box;
  border: 1px solid transparent; border-radius: 12px; background: transparent;
  color: var(--pt-text-secondary, rgba(228, 224, 246, .68)); cursor: pointer;
  transition: color 180ms ease, background-color 180ms ease, border-color 180ms ease;
}
.pt-topbar .pt-topbar-bell svg { width: 20px; height: 20px; }
.pt-topbar .pt-topbar-bell:hover { color: var(--pt-text-primary, #f7f5ff); background: rgba(255, 255, 255, .05); border-color: var(--pt-border-subtle, rgba(255, 255, 255, .075)); }
/* the badge sits on the bell's top-right shoulder, clear of the glyph */
.pt-topbar .pt-topbar-badge {
  position: absolute; top: 2px; left: 23px; min-width: 16px; height: 16px; padding: 0 4px; box-sizing: border-box;
  display: inline-grid; place-items: center; border-radius: 999px;
  background: linear-gradient(135deg, #8b5cf6, #6d28d9); color: #fff;
  font-size: 9.5px; font-weight: 700; line-height: 1; letter-spacing: 0; box-shadow: 0 0 0 2px #0b0916;
  pointer-events: none;
}
.pt-topbar .pt-topbar-account { display: inline-flex; flex: 0 0 auto; }
.pt-topbar .pt-topbar-avatar {
  position: relative; display: inline-grid; place-items: center; overflow: hidden;
  width: 38px; height: 38px; padding: 0; margin: 0; box-sizing: border-box;
  border: 0; border-radius: 50%;
  background: linear-gradient(135deg, #7c4dff, #6f8bff 60%, #b388ff);
  box-shadow: 0 0 0 2px rgba(180, 140, 255, .22), 0 0 16px rgba(124, 77, 255, .35);
  color: #fff; font: inherit; font-size: 12px; font-weight: 800; letter-spacing: .04em;
}
button.pt-topbar-avatar { cursor: pointer; transition: box-shadow 180ms ease, transform 150ms ease; }
button.pt-topbar-avatar:hover { box-shadow: 0 0 0 2px rgba(196, 181, 253, .55), 0 0 18px rgba(124, 77, 255, .5); }
button.pt-topbar-avatar.is-open { box-shadow: 0 0 0 2px rgba(196, 181, 253, .75), 0 0 18px rgba(124, 77, 255, .55); }
.pt-topbar .pt-topbar-avatar img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.pt-topbar .pt-topbar-bell:focus-visible,
.pt-topbar .pt-topbar-avatar:focus-visible {
  outline: none; box-shadow: var(--pt-focus-ring, 0 0 0 2px #0b0916, 0 0 0 4px rgba(167, 139, 250, .9));
}

/* Short windows: a tighter rhythm under the bar (as Create had). */
@media (max-height: 940px) {
  .pt-topbar { margin-bottom: var(--pt-space-3, 12px); }
}

/* Narrower bars keep the search usable: the stats tighten, then the two
   capacity tiles go, then the stats and the systems line. */
/* The embedding chip (an admin, samples embedding, waiting or failed) says
   its short form beside the dot on a bar under 1,400 px (a 1,440 px window
   with the sidebar is a 1,156 px bar): a count and what it counts ("40K to
   embed"); the words stay its tooltip and name. An old GPU reading's age
   ("· 7s ago") stays the tile's tooltip there (the tile is still dimmed), so
   the four stat tiles and the search keep their room: with the chip shown,
   the right-hand group sits a little closer (a member's bar is unchanged). */
@container pt-topbar (max-width: 1400px) {
  .pt-topbar .pt-topbar-embed-text { display: none; }
  .pt-topbar .pt-topbar-embed-short { display: inline; text-transform: none; letter-spacing: 0; }
  .pt-topbar .pt-topbar-embed-short:empty { display: none; }
  .pt-topbar .pt-topbar-embed { padding: 0 10px; gap: 7px; }
  .pt-topbar .pt-topbar-stat-age { display: none; }
  .pt-topbar:has(.pt-topbar-embed:not([hidden])) .pt-topbar-right { gap: 12px; }
  .pt-topbar:has(.pt-topbar-embed:not([hidden])) .pt-topbar-stats { gap: 16px; }
}
@container pt-topbar (max-width: 1120px) {
  .pt-topbar .pt-topbar-right { gap: 12px; }
  .pt-topbar .pt-topbar-stats { gap: 16px; }
  .pt-topbar .pt-topbar-stat-value { font-size: 12.5px; }
}
@container pt-topbar (max-width: 980px) {
  .pt-topbar .pt-topbar-stat[data-stat="vram"],
  .pt-topbar .pt-topbar-stat[data-stat="ram"] { display: none; }
}
@container pt-topbar (max-width: 780px) {
  .pt-topbar .pt-topbar-stats { display: none; }
}
/* Two rows: the search (with the menu button before it on a phone), then
   the engine on the left and the bell and account on the right. Nothing is
   clipped and nothing scrolls sideways. */
@container pt-topbar (max-width: 640px) {
  .pt-topbar .pt-topbar-inner { flex-wrap: wrap; gap: 12px; }
  .pt-topbar .pt-topbar-search { flex: 1 1 0; max-width: none; }
  .pt-topbar .pt-topbar-right { flex: 1 1 100%; margin-left: 0; }
  .pt-topbar .pt-topbar-engine { margin-right: auto; }
}
@container pt-topbar (max-width: 560px) {
  .pt-topbar .pt-topbar-systems { display: none; }
  .pt-topbar .pt-topbar-kbd { display: none; }
  .pt-topbar .pt-topbar-right { gap: 8px; }
  .pt-topbar .pt-topbar-engine { padding: 0 10px; }
}
/* A very narrow bar: the engine's label gives way (ellipsis, the full text
   stays its tooltip and live-region text) before anything overflows. */
@container pt-topbar (max-width: 400px) {
  .pt-topbar .pt-topbar-inner { gap: 10px; }
  .pt-topbar .pt-topbar-search { padding: 0 6px 0 12px; }
  .pt-topbar .pt-topbar-engine { flex: 0 1 auto; min-width: 0; height: 36px; gap: 7px; }
  .pt-topbar .pt-topbar-engine-text { overflow: hidden; }
  .pt-topbar .pt-topbar-engine-label { overflow: hidden; text-overflow: ellipsis; letter-spacing: .06em; }
  .pt-topbar .pt-topbar-bell { width: 36px; height: 36px; margin: 0; }
  .pt-topbar .pt-topbar-avatar { width: 34px; height: 34px; }
}
@media (prefers-reduced-motion: reduce) {
  .pt-topbar .pt-topbar-dot { animation: none !important; }
  .pt-topbar .pt-topbar-search,
  .pt-topbar .pt-topbar-bell { transition: none; }
}
