/* ToolGlue design tokens on top of MudBlazor (doc 08). Dark is default; no white flash. */

:root {
  --mud-typography-default-family: 'Inter', -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
  --tg-radius: 12px;
  /* Falls back to the dark hairline before MudBlazor mounts; flips with the active palette after. */
  --tg-hairline: var(--mud-palette-lines-default, rgba(255, 255, 255, 0.07));
  --tg-glow: 0 0 24px rgba(34, 211, 238, 0.12);
}

html,
body {
  background: #0B0D12;
  min-height: 100%;
  -webkit-tap-highlight-color: transparent;
}

/* Wordmark */
.tg-wordmark {
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: 0.02em;
  color: var(--mud-palette-text-primary) !important;
}

.tg-wordmark-dot {
  color: var(--mud-palette-primary);
}

/* Surfaces */
.tg-card,
.tg-stat,
.tg-empty {
  border: 1px solid var(--tg-hairline);
  border-radius: var(--tg-radius);
  background: var(--mud-palette-surface);
}

.tg-stat .tg-stat-value {
  font-variant-numeric: tabular-nums;
  /* Never wrap a figure mid-number, and never let it paint outside the tile. A balance carries up to
     six decimals (MicroUsd), so "$99,999.999999" is 14 glyphs — at a fixed h5 that ran past the right
     edge of a half-width tile on a phone.
     cqi is 1% of the tile's own inline size, so the figure is measured against the box that has to
     hold it rather than against the viewport, which is what keeps it inside at every breakpoint and
     in the 2-up mobile grid. 12.5cqi is the widest that still fits 14 tabular glyphs.
     min() and not clamp(): a rem floor grows with the reader's text-size setting while the tile does
     not, so a floor is exactly what puts the figure back outside the box on a phone at 150% text.
     Here the reader's preference is honoured up to 1.5rem wherever the tile is roomy enough to hold
     it, and the tile wins only at the point where the number would otherwise not fit at all. */
  font-size: min(1.5rem, 12.5cqi);
  white-space: nowrap;
  min-width: 0;
}

.tg-stat {
  height: 100%;
  min-height: 110px;
  /* Establishes the containment context the cqi sizing above measures against. */
  container-type: inline-size;
  /* Belt and braces: whatever the content, nothing paints past the rounded border. */
  overflow: hidden;
}

/* Below this width, sizing the figure to fit all fourteen glyphs would shrink it past reading. The
   sub-cent digits are exact accounting precision rather than spendable coin (see TgUsd), so they are
   what gives way — the dollars and cents stay legible instead of the whole number becoming a smudge.
   With four glyphs gone the remaining ten can take a larger share of the tile, hence the step up. */
@container (max-width: 132px) {
  .tg-stat .tg-stat-value .tg-usd-sub {
    display: none;
  }

  .tg-stat .tg-stat-value {
    font-size: min(1.5rem, 17cqi);
  }
}

.tg-stat-hint {
  display: block;
  min-height: 1.25rem;
}

.tg-empty-icon {
  width: 56px;
  height: 56px;
  border-radius: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(34, 211, 238, 0.08);
  box-shadow: var(--tg-glow);
}

.tg-code {
  border: 1px solid var(--tg-hairline);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.03);
  padding: 8px 12px;
  overflow-x: auto;
}

.tg-code code {
  font-family: ui-monospace, 'Cascadia Code', Consolas, monospace;
  font-size: 0.85rem;
  color: var(--mud-palette-primary);
  white-space: nowrap;
}

/* Billing */
.tg-money-value {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.1;
}

.tg-money-lg .tg-money-value {
  /* Same reasoning as the stat tile above, including why this is min() and not clamp(): the card is
     wider, so it can carry a larger share, but a rem floor would still break it under text scaling.
     2.75rem stays the ceiling wherever the card is roomy enough to hold the figure at that size. */
  font-size: min(2.75rem, 11cqi);
  white-space: nowrap;
}

.tg-money-lg {
  container-type: inline-size;
}

.tg-money-usd {
  font-variant-numeric: tabular-nums;
  color: var(--mud-palette-text-secondary);
}

/* M14: decimals 3-6 are exact accounting precision, not spendable coin — same size, visibly dimmer. */
.tg-usd {
  font-variant-numeric: tabular-nums;
}

.tg-usd-sub {
  opacity: 0.55;
}

.tg-ledger-amount {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.tg-pack {
  border: 1px solid var(--tg-hairline);
  border-radius: var(--tg-radius);
  background: var(--mud-palette-surface);
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

.tg-pack:hover {
  border-color: var(--mud-palette-primary);
  box-shadow: var(--tg-glow);
}

/* Tool bundles (M8 WS-C): responsive card grid, mobile-first single column */
.tg-bundle-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}

@media (min-width: 600px) {
  .tg-bundle-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 960px) {
  .tg-bundle-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.tg-bundle-card {
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

.tg-bundle-card:hover {
  border-color: var(--mud-palette-primary);
  box-shadow: var(--tg-glow);
}

.tg-bundle-desc {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.5em;
}

/* Memories page: clamp long content in the list row, full text still shown in the edit dialog. */
.tg-memory-content {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  white-space: pre-wrap;
}

.tg-picker-row {
  border-top: 1px solid var(--tg-hairline);
}

.tg-picker-row:first-of-type {
  border-top: none;
}

/* Save bar for staged tool changes: sticky above the mobile bottom nav */
.tg-savebar {
  position: sticky;
  bottom: 16px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  margin-top: 16px;
  border: 1px solid var(--mud-palette-primary);
  border-radius: var(--tg-radius);
  background: var(--mud-palette-surface);
  box-shadow: var(--tg-glow);
}

@media (max-width: 959px) {
  .tg-savebar {
    bottom: 80px;
  }
}

/* Mobile bottom navigation (thumb-first, ≥44px targets) */
.tg-bottomnav {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1300;
  justify-content: space-around;
  padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--mud-palette-background) 88%, transparent);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--tg-hairline);
}

.tg-bottomnav-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 56px;
  min-height: 44px;
  padding: 4px 8px;
  border-radius: 10px;
  font-size: 0.65rem;
  text-decoration: none;
  color: var(--mud-palette-text-secondary);
}

.tg-bottomnav-item.active {
  color: var(--mud-palette-primary);
  background: rgba(34, 211, 238, 0.08);
}

/* Give the main content room above the bottom bar on mobile */
@media (max-width: 959px) {
  .tg-main {
    padding-bottom: 76px;
  }
}

/* ---------------------------------------------------------------------------
   Auth pages (static SSR, doc 08). Dark by default, mobile-first, thumb-friendly,
   plain HTML form elements — the first impression, so it carries the full bar.
   These tokens are self-contained (no MudBlazor at render time on /account).
---------------------------------------------------------------------------- */
.tg-auth-shell {
  --tg-bg: #0B0D12;
  --tg-surface: #12151D;
  --tg-hair: rgba(255, 255, 255, 0.08);
  --tg-primary: #22D3EE;
  --tg-text: #E6EAF2;
  --tg-muted: #98A2B3;
  --tg-error: #FB7185;
  --tg-success: #34D399;
  min-height: 100dvh;
  display: flex;
  /* Column so the card and the M10 "Docs and help" foot link stack; centering is unchanged
     (justify-content centers vertically, align-items horizontally in a column flex). */
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 24px 16px calc(24px + env(safe-area-inset-bottom));
  background:
    radial-gradient(60% 50% at 50% 0%, rgba(34, 211, 238, 0.10), transparent 70%),
    var(--tg-bg);
  color: var(--tg-text);
  font-family: 'Inter', -apple-system, 'Segoe UI', Roboto, sans-serif;
}

/* The help-center pointer under the auth card (M10): quiet, out of the sign-in flow's way. */
.tg-auth-foot {
  margin: 16px 0 0;
  font-size: 0.86rem;
}

.tg-auth-foot a {
  color: var(--tg-muted);
  text-decoration: none;
}

.tg-auth-foot a:hover {
  color: var(--tg-text);
}

.tg-auth-card {
  width: 100%;
  max-width: 400px;
  background: var(--tg-surface);
  border: 1px solid var(--tg-hair);
  border-radius: 16px;
  padding: 28px 24px 24px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
}

.tg-auth-wordmark {
  display: inline-block;
  font-weight: 700;
  font-size: 1.25rem;
  letter-spacing: 0.02em;
  color: var(--tg-text);
  text-decoration: none;
  margin-bottom: 20px;
}

.tg-auth-wordmark span {
  color: var(--tg-primary);
}

.tg-auth-title {
  font-size: 1.35rem;
  font-weight: 650;
  margin: 0 0 4px;
}

.tg-auth-sub {
  color: var(--tg-muted);
  font-size: 0.9rem;
  margin: 0 0 20px;
}

.tg-auth-field {
  margin-bottom: 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.tg-auth-field label {
  font-size: 0.82rem;
  color: var(--tg-muted);
}

.tg-auth-input {
  width: 100%;
  min-height: 48px;
  padding: 0 14px;
  border-radius: 10px;
  border: 1px solid var(--tg-hair);
  background: rgba(255, 255, 255, 0.03);
  color: var(--tg-text);
  font-size: 1rem;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.tg-auth-input:focus {
  outline: none;
  border-color: var(--tg-primary);
  box-shadow: 0 0 0 3px rgba(34, 211, 238, 0.18);
}

.tg-auth-input::placeholder {
  color: #5b6675;
}

.tg-auth-check {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--tg-muted);
  font-size: 0.9rem;
  margin-bottom: 16px;
}

.tg-auth-check input {
  width: 18px;
  height: 18px;
  accent-color: var(--tg-primary);
}

.tg-auth-btn {
  width: 100%;
  min-height: 48px;
  border: none;
  border-radius: 10px;
  background: var(--tg-primary);
  color: #06222A;
  font-size: 1rem;
  font-weight: 650;
  cursor: pointer;
  transition: filter 0.15s;
}

.tg-auth-btn:hover {
  filter: brightness(1.08);
}

.tg-auth-btn:focus-visible {
  outline: 2px solid var(--tg-text);
  outline-offset: 2px;
}

.tg-auth-btn.secondary {
  background: transparent;
  color: var(--tg-text);
  border: 1px solid var(--tg-hair);
}

.tg-auth-sso {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 18px;
}

.tg-auth-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--tg-muted);
  font-size: 0.78rem;
  margin: 18px 0;
}

.tg-auth-divider::before,
.tg-auth-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--tg-hair);
}

.tg-auth-links {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 18px;
  font-size: 0.86rem;
}

.tg-auth-links a {
  color: var(--tg-primary);
  text-decoration: none;
}

.tg-auth-msg {
  border-radius: 10px;
  padding: 10px 14px;
  font-size: 0.86rem;
  margin-bottom: 16px;
  border: 1px solid var(--tg-hair);
}

.tg-auth-msg.error {
  color: var(--tg-error);
  background: rgba(251, 113, 133, 0.08);
  border-color: rgba(251, 113, 133, 0.35);
}

.tg-auth-msg.info {
  color: var(--tg-text);
  background: rgba(34, 211, 238, 0.06);
  border-color: rgba(34, 211, 238, 0.25);
}

.tg-auth-validation {
  color: var(--tg-error);
  font-size: 0.8rem;
}

.tg-auth-mono {
  font-family: ui-monospace, 'Cascadia Code', Consolas, monospace;
  font-size: 0.82rem;
  word-break: break-all;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--tg-hair);
  border-radius: 8px;
  padding: 10px 12px;
  color: var(--tg-primary);
}

.tg-auth-qr {
  display: flex;
  justify-content: center;
  padding: 16px;
  background: #fff;
  border-radius: 12px;
  margin: 8px 0 16px;
}

.tg-auth-qr svg {
  width: 200px;
  height: 200px;
}

/* Boot splash (avoid a flash of unstyled/empty layout while the circuit resolves auth) */
.tg-boot {
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0B0D12;
}

/* Workspace switcher menu */
.tg-ws-menu {
  display: flex;
  flex-direction: column;
  min-width: 220px;
  padding: 6px;
}

.tg-ws-menu form {
  margin: 0;
}

.tg-ws-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  min-height: 44px;
  padding: 8px 12px;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--mud-palette-text-primary);
  font-size: 0.9rem;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.tg-ws-item:hover {
  background: rgba(255, 255, 255, 0.05);
}

.tg-ws-item.active {
  color: var(--mud-palette-primary);
}

.tg-ws-role {
  font-size: 0.72rem;
  color: var(--mud-palette-text-secondary);
  text-transform: lowercase;
}

.tg-ws-new {
  color: var(--mud-palette-primary);
  border-top: 1px solid var(--tg-hairline);
  margin-top: 4px;
  border-radius: 0 0 8px 8px;
}

.tg-logout-form {
  display: inline-flex;
  margin: 0;
}

/* One-time key reveal + snippets */
.tg-reveal {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  border: 1px solid var(--tg-hairline);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.03);
  padding: 10px 12px;
}

.tg-reveal code,
.tg-reveal pre {
  flex: 1;
  margin: 0;
  font-family: ui-monospace, 'Cascadia Code', Consolas, monospace;
  font-size: 0.8rem;
  color: var(--mud-palette-primary);
  white-space: pre-wrap;
  word-break: break-all;
  overflow-x: auto;
}

.tg-key-prefix {
  font-family: ui-monospace, 'Cascadia Code', Consolas, monospace;
  font-size: 0.8rem;
  color: var(--mud-palette-text-secondary);
}

/* Connect wizard: searchable connector grid (doc 08 — initials avatar, no external images) */
.tg-connector-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 12px;
}

.tg-connector-card {
  border: 1px solid var(--tg-hairline);
  border-radius: var(--tg-radius);
  background: var(--mud-palette-surface);
  padding: 14px 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  text-align: center;
  cursor: pointer;
  min-height: 44px;
  min-width: 0;
  overflow: hidden;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.tg-connector-card:hover,
.tg-connector-card:focus-visible {
  border-color: var(--mud-palette-primary);
  box-shadow: var(--tg-glow);
}

/* Long connector names (AI drafts especially) clamp to two lines instead of stretching the card. */
.tg-connector-name {
  font-size: 0.8125rem;
  line-height: 1.3;
  max-width: 100%;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

/* Provenance chips must never widen a card past its grid track. */
.tg-connector-card .mud-chip {
  max-width: 100%;
}

.tg-connector-card .mud-chip .mud-chip-content {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: block;
}

/* The always-visible "generate a connector with AI" entry row at the top of the connect wizard. */
.tg-generate-row {
  border: 1px dashed var(--tg-hairline);
  border-radius: var(--tg-radius);
  background: var(--mud-palette-surface);
  padding: 12px 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.tg-generate-row:hover,
.tg-generate-row:focus-visible {
  border-color: var(--mud-palette-secondary);
  box-shadow: var(--tg-glow);
}

/* Playground ad-hoc bench: the "AI fills the form" assist block. */
.tg-assist {
  border: 1px dashed var(--tg-hairline);
  border-radius: var(--tg-radius);
}

.tg-connector-avatar {
  width: 40px;
  height: 40px;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(34, 211, 238, 0.12);
  color: var(--mud-palette-primary);
  font-weight: 600;
  font-size: 0.9rem;
}

/* Connection status chips (doc 10: Active=glow, Disconnected=warning, Pending=secondary) */
.tg-status-active {
  box-shadow: var(--tg-glow);
}

/* OAuth consent (doc 08: the claude.ai onboarding moment — phone-first, plain language) */
.tg-consent-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  margin-bottom: 18px;
  border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--tg-error) 45%, transparent);
  background: color-mix(in srgb, var(--tg-error) 12%, transparent);
  color: var(--tg-text);
  font-size: 0.85rem;
}

.tg-consent-section {
  margin-bottom: 18px;
}

.tg-consent-label {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--tg-muted);
  margin-bottom: 8px;
}

.tg-consent-workspaces {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tg-consent-workspace {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--tg-hair);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}

.tg-consent-workspace:has(input:checked) {
  border-color: var(--tg-primary);
  background: rgba(34, 211, 238, 0.08);
}

.tg-consent-workspace input {
  accent-color: var(--tg-primary);
  width: 18px;
  height: 18px;
}

.tg-consent-workspace-name {
  flex: 1;
  font-weight: 600;
}

.tg-consent-workspace-role {
  font-size: 0.75rem;
  color: var(--tg-muted);
}

.tg-consent-scopes {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tg-consent-scopes li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.92rem;
}

.tg-consent-check {
  color: var(--tg-success);
  font-weight: 700;
}

.tg-consent-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 22px;
}

.tg-consent-foot {
  margin-top: 16px;
  font-size: 0.78rem;
  text-align: center;
}

/* Runs list + detail (doc 10: redacted exchange rendered nicely) */
.tg-run-row {
  cursor: pointer;
  transition: border-color 0.15s;
}

.tg-run-row:hover {
  border-color: var(--tg-primary);
}

.tg-run-url {
  word-break: break-all;
}

.tg-run-pre {
  margin: 0;
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--tg-bg);
  color: var(--tg-text);
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.8rem;
  white-space: pre-wrap;
  word-break: break-word;
  overflow-x: auto;
}

.tg-run-panels {
  background: transparent;
}

/* ---------------------------------------------------------------------------
   The living wire — motion + realtime design language. Everything below reads
   from theme tokens; honors prefers-reduced-motion.
---------------------------------------------------------------------------- */

/* Page enter: content rises into place. */
.tg-enter {
  animation: tg-rise 240ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

@keyframes tg-rise {
  from {
    opacity: 0;
    transform: translateY(6px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

/* The pulse dot: idle ember next to the wordmark that flares on live agent traffic. */
.tg-pulse-dot {
  width: 8px;
  height: 8px;
  margin-left: 10px;
  border-radius: 999px;
  background: var(--mud-palette-text-disabled);
  transition: background 300ms ease, box-shadow 300ms ease;
}

.tg-pulse-dot.live {
  background: var(--mud-palette-primary);
  box-shadow: 0 0 0 0 rgba(34, 211, 238, 0.7);
  animation: tg-pulse 1.4s ease-out;
}

@keyframes tg-pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(34, 211, 238, 0.7);
  }

  100% {
    box-shadow: 0 0 0 14px rgba(34, 211, 238, 0);
  }
}

/* Command palette */
.tg-palette-overlay {
  position: fixed;
  inset: 0;
  z-index: 1500;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: min(18vh, 160px) 16px 16px;
  background: color-mix(in srgb, var(--mud-palette-black, #07080C) 55%, transparent);
  backdrop-filter: blur(6px);
  animation: tg-fade 140ms ease;
}

@keyframes tg-fade {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

.tg-palette {
  width: 100%;
  max-width: 560px;
  border: 1px solid var(--tg-hairline);
  border-radius: 16px;
  background: var(--mud-palette-surface);
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.55), var(--tg-glow);
  overflow: hidden;
  animation: tg-rise 180ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.tg-palette-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--tg-hairline);
}

.tg-palette-input {
  flex: 1;
  min-height: 28px;
  border: none;
  outline: none;
  background: transparent;
  color: var(--mud-palette-text-primary);
  font-size: 1rem;
  font-family: inherit;
}

.tg-palette-input::placeholder {
  color: var(--mud-palette-text-disabled);
}

.tg-palette-glyph {
  color: var(--mud-palette-text-secondary);
  flex-shrink: 0;
}

.tg-palette-list {
  max-height: min(50vh, 420px);
  overflow-y: auto;
  padding: 6px;
}

.tg-palette-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  border: none;
  border-radius: 10px;
  background: transparent;
  color: var(--mud-palette-text-primary);
  font-size: 0.92rem;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

.tg-palette-item.selected {
  background: rgba(34, 211, 238, 0.10);
}

.tg-palette-item.selected .tg-palette-glyph {
  color: var(--mud-palette-primary);
}

.tg-palette-label {
  flex-shrink: 0;
}

.tg-palette-hint {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--mud-palette-text-secondary);
  font-size: 0.78rem;
  text-align: right;
}

.tg-palette-empty {
  padding: 22px 16px;
  text-align: center;
  color: var(--mud-palette-text-secondary);
  font-size: 0.9rem;
}

.tg-palette-foot {
  display: flex;
  gap: 16px;
  align-items: center;
  padding: 8px 16px;
  border-top: 1px solid var(--tg-hairline);
  color: var(--mud-palette-text-secondary);
  font-size: 0.72rem;
}

.tg-palette-foot-brand {
  margin-left: auto;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.tg-kbd {
  display: inline-block;
  padding: 1px 6px;
  border: 1px solid var(--tg-hairline);
  border-bottom-width: 2px;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--mud-palette-text-secondary);
  font-family: inherit;
  font-size: 0.72rem;
  line-height: 1.5;
}

.tg-palette-opener {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 34px;
  margin-right: 12px;
  padding: 4px 12px;
  border: 1px solid var(--tg-hairline);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.03);
  color: var(--mud-palette-text-secondary);
  font-size: 0.82rem;
  font-family: inherit;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}

.tg-palette-opener:hover {
  border-color: var(--mud-palette-primary);
  color: var(--mud-palette-text-primary);
}

/* Skeleton shimmer: loading surfaces breathe instead of spinning. */
.tg-skeleton {
  position: relative;
  overflow: hidden;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.05);
  min-height: 16px;
}

.tg-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.06), transparent);
  animation: tg-shimmer 1.6s infinite;
}

@keyframes tg-shimmer {
  100% {
    transform: translateX(100%);
  }
}

/* Status glow semantics: Active hums, Pending waits, Disconnected warns. */
.tg-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.78rem;
}

.tg-status::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: currentColor;
}

.tg-status.active {
  color: var(--mud-palette-success);
}

.tg-status.active::before {
  box-shadow: 0 0 8px 1px color-mix(in srgb, var(--mud-palette-success) 70%, transparent);
}

.tg-status.pending {
  color: var(--mud-palette-warning);
}

.tg-status.disconnected {
  color: var(--mud-palette-error);
}

/* Drawer footer version stamp */
.tg-version {
  font-family: ui-monospace, 'Cascadia Code', Consolas, monospace;
  font-size: 0.68rem;
  color: var(--mud-palette-text-disabled);
}

/* Blazor reconnect overlay: match the brand instead of the stock gray modal. */
#components-reconnect-modal {
  background: color-mix(in srgb, #07080C 78%, transparent) !important;
  backdrop-filter: blur(4px);
  color: #E6EAF2 !important;
  font-family: 'Inter', -apple-system, 'Segoe UI', Roboto, sans-serif;
}

/* Live tickers */
.tg-ticker-row {
  animation: tg-rise 300ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

@media (prefers-reduced-motion: reduce) {

  .tg-enter,
  .tg-palette,
  .tg-palette-overlay,
  .tg-ticker-row,
  .tg-pulse-dot.live {
    animation: none;
  }

  .tg-skeleton::after {
    animation: none;
  }
}

/* The hardcoded dark body is only the pre-boot flash guard; once MudBlazor mounts, the layout
   must paint from the active palette or light mode keeps a dark page body. */
.mud-layout {
  background: var(--mud-palette-background);
  min-height: 100dvh;
}

/* FocusOnNavigate moves focus to the page title on every navigation (screen readers announce the
   new page), but the browser's default focus ring drew a white box around the header on every page
   load. The programmatic focus stays; the ring goes. */
.tg-page-title:focus,
.tg-page-title:focus-visible {
  outline: none;
  box-shadow: none;
}

/* System map — the living wire */
.tg-sysmap svg {
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--mud-default-borderradius);
  background:
    radial-gradient(circle at 49% 50%, color-mix(in srgb, var(--mud-palette-primary) 7%, transparent), transparent 22%),
    radial-gradient(circle at 85% 50%, color-mix(in srgb, var(--mud-palette-success) 4%, transparent), transparent 24%);
}

.tg-sysmap-wire {
  fill: none;
  stroke: var(--tg-hairline);
  stroke-width: 1.5;
  transition: stroke 300ms ease;
}

.tg-sysmap.live .tg-sysmap-wire {
  stroke: var(--mud-palette-primary);
  stroke-dasharray: 6 10;
  animation: tg-flow 900ms linear infinite;
  filter: drop-shadow(0 0 4px rgba(34, 211, 238, 0.5));
}

.tg-sysmap.building .tg-sysmap-wire {
  stroke: var(--mud-palette-secondary);
  stroke-dasharray: 6 10;
  animation: tg-flow 900ms linear infinite;
}

/* M19 "visualize just it": when the completed run resolved to one app node, the untargeted
   hub-to-app wires stay hairlines and only the hot wire carries the pulse (faster + brighter). */
.tg-sysmap.live.targeted .tg-sysmap-wire {
  stroke: var(--tg-hairline);
  stroke-dasharray: none;
  animation: none;
  filter: none;
}

.tg-sysmap.live.targeted .tg-sysmap-wire:first-of-type,
.tg-sysmap.live.targeted .tg-sysmap-wire.hot {
  stroke: var(--mud-palette-primary);
  stroke-dasharray: 6 10;
  animation: tg-flow 450ms linear infinite;
  filter: drop-shadow(0 0 5px rgba(34, 211, 238, 0.6));
}

.tg-sysmap.live .tg-sysmap-circle.app.hot {
  stroke: var(--mud-palette-primary);
  filter: drop-shadow(0 0 6px rgba(34, 211, 238, 0.55));
}

/* M20 "signs of life": while ANY tool executes — built-ins and Smart Tools included — traffic
   flows from the agents into the hub and the hub breathes. A tool riding a visible connection
   additionally drives just that wire; a connection-less tool pulses the hub alone, which reads
   as "working inside tool·glue". */
.tg-sysmap.running .tg-sysmap-wire:first-of-type,
.tg-sysmap.running .tg-sysmap-wire.hot {
  stroke: var(--mud-palette-primary);
  stroke-dasharray: 6 10;
  animation: tg-flow 700ms linear infinite;
  filter: drop-shadow(0 0 4px rgba(34, 211, 238, 0.5));
}

.tg-sysmap.running .tg-sysmap-circle.hub {
  animation: tg-hub-breathe 1400ms ease-in-out infinite;
}

.tg-sysmap.running .tg-sysmap-circle.app.hot {
  stroke: var(--mud-palette-primary);
  filter: drop-shadow(0 0 6px rgba(34, 211, 238, 0.55));
}

/* The tool running (or just finished), named above the hub with a small activity dot. */
.tg-sysmap-toolname {
  fill: var(--mud-palette-primary);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.2px;
  text-anchor: middle;
  opacity: 0;
  transition: opacity 250ms ease;
}

.tg-sysmap-tooldot {
  fill: var(--mud-palette-primary);
  opacity: 0;
}

.tg-sysmap.live .tg-sysmap-toolname,
.tg-sysmap.live .tg-sysmap-tooldot {
  opacity: 1;
}

.tg-sysmap.running .tg-sysmap-toolname {
  opacity: 1;
}

.tg-sysmap.running .tg-sysmap-tooldot {
  opacity: 1;
  animation: tg-dot-blink 1200ms ease-in-out infinite;
}

.tg-sysmap-toolname.failed,
.tg-sysmap-tooldot.failed {
  fill: var(--mud-palette-error);
}

@keyframes tg-flow {
  to {
    stroke-dashoffset: -16;
  }
}

@keyframes tg-hub-breathe {

  0%,
  100% {
    filter: drop-shadow(0 0 10px rgba(34, 211, 238, 0.3));
  }

  50% {
    filter: drop-shadow(0 0 18px rgba(34, 211, 238, 0.6));
  }
}

@keyframes tg-dot-blink {

  0%,
  100% {
    opacity: 1;
  }

  50% {
    opacity: 0.25;
  }
}

.tg-sysmap-circle {
  fill: var(--mud-palette-surface);
  stroke: var(--tg-hairline);
  stroke-width: 1.5;
  transition: stroke 200ms ease, filter 200ms ease;
}

.tg-sysmap-circle.hub {
  stroke: var(--mud-palette-primary);
  filter: drop-shadow(0 0 12px rgba(34, 211, 238, 0.32));
}

.tg-sysmap.building .tg-sysmap-circle.hub {
  stroke: var(--mud-palette-secondary);
  filter: drop-shadow(0 0 12px rgba(167, 139, 250, 0.4));
}

.tg-sysmap-circle.app.active {
  stroke: var(--mud-palette-success);
}

.tg-sysmap-circle.app.pending {
  stroke: var(--mud-palette-warning);
}

.tg-sysmap-circle.app.disconnected {
  stroke: var(--mud-palette-error);
}

.tg-sysmap-circle.ghost {
  stroke-dasharray: 4 4;
}

.tg-sysmap-node:hover .tg-sysmap-circle {
  stroke: var(--mud-palette-primary);
}

.tg-sysmap-glyph,
.tg-sysmap-initials {
  fill: var(--mud-palette-text-primary);
  font-size: 10px;
  font-weight: 600;
  text-anchor: middle;
  dominant-baseline: middle;
}

.tg-sysmap-glyph.ghost {
  fill: var(--mud-palette-text-secondary);
  font-size: 16px;
}

.tg-sysmap-hubword {
  fill: var(--mud-palette-text-primary);
  font-size: 10px;
  font-weight: 700;
  text-anchor: middle;
}

.tg-sysmap-hubruns {
  fill: var(--mud-palette-text-secondary);
  font-size: 7.5px;
  text-anchor: middle;
}

/* Node labels: readable size, breathing room from their circles (the y offsets in the markup),
   and clamped text (AppSlot.Label) so neighboring labels never collide. */
.tg-sysmap-label {
  fill: var(--mud-palette-text-secondary);
  font-size: 8px;
  letter-spacing: 0.2px;
  text-anchor: middle;
}

/* Sparkline */
.tg-spark {
  width: 100%;
  height: 44px;
  display: block;
}

.tg-spark-line {
  fill: none;
  stroke: var(--mud-palette-primary);
  stroke-width: 1.6;
  vector-effect: non-scaling-stroke;
}

.tg-spark-area {
  fill: rgba(34, 211, 238, 0.12);
  stroke: none;
}

.tg-spark-dot {
  fill: var(--mud-palette-primary);
}

.tg-spark-flat {
  stroke: var(--tg-hairline);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}

/* Live runs feed */
.tg-feed-row {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  padding: 8px 10px;
  border-radius: 10px;
  cursor: pointer;
  text-decoration: none;
  color: var(--mud-palette-text-primary);
}

.tg-feed-row:hover {
  background: rgba(255, 255, 255, 0.04);
}

.tg-feed-time {
  font-family: ui-monospace, 'Cascadia Code', Consolas, monospace;
  font-size: 0.72rem;
  color: var(--mud-palette-text-secondary);
  min-width: 58px;
}

.tg-feed-what {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.85rem;
}

.tg-feed-credits {
  font-variant-numeric: tabular-nums;
  font-size: 0.78rem;
  color: var(--mud-palette-text-secondary);
}

@media (prefers-reduced-motion: reduce) {

  .tg-sysmap.live .tg-sysmap-wire,
  .tg-sysmap.building .tg-sysmap-wire,
  .tg-sysmap.live.targeted .tg-sysmap-wire.hot,
  .tg-sysmap.live.targeted .tg-sysmap-wire:first-of-type,
  .tg-sysmap.running .tg-sysmap-wire:first-of-type,
  .tg-sysmap.running .tg-sysmap-wire.hot,
  .tg-sysmap.running .tg-sysmap-circle.hub,
  .tg-sysmap.running .tg-sysmap-tooldot {
    animation: none;
  }
}

/* Mobile "More" sheet: the rest of the nav within thumb reach. */
.tg-more-overlay {
  position: fixed;
  inset: 0;
  z-index: 1295;
  background: color-mix(in srgb, #07080C 45%, transparent);
}

.tg-more-sheet {
  position: absolute;
  right: 8px;
  bottom: calc(72px + env(safe-area-inset-bottom));
  min-width: 200px;
  /* The sheet is anchored above the bottom nav and grows upward, so a long nav
     list would push its top item under the app bar with no way to reach it.
     Clamp to the space between the app bar and the bottom nav, then scroll. Use
     svh (the viewport WITH the browser toolbar shown, the smallest state) not dvh:
     dvh is the toolbar-hidden height, so while the address bar is visible it
     overestimates and the sheet still rides up under the app bar. */
  max-height: calc(100vh - 136px - env(safe-area-inset-top) - env(safe-area-inset-bottom));
  max-height: calc(100svh - 136px - env(safe-area-inset-top) - env(safe-area-inset-bottom));
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 6px;
  border: 1px solid var(--tg-hairline);
  border-radius: 14px;
  background: var(--mud-palette-surface);
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.5);
  animation: tg-rise 160ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* Circuit error bars: brand-styled, impossible to miss, never silent. */
#blazor-error-ui,
#tg-dead-ui {
  display: none;
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: calc(12px + env(safe-area-inset-bottom));
  z-index: 2000;
  padding: 12px 16px;
  border: 1px solid color-mix(in srgb, #FB7185 45%, transparent);
  border-radius: 12px;
  background: #1a1016;
  color: #E6EAF2;
  font-family: 'Inter', -apple-system, 'Segoe UI', Roboto, sans-serif;
  font-size: 0.9rem;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
}

#blazor-error-ui .reload,
#tg-dead-ui .reload {
  color: #22D3EE;
  margin-left: 8px;
}

#blazor-error-ui .dismiss,
#tg-dead-ui .dismiss {
  float: right;
  cursor: pointer;
  color: #98A2B3;
}

#tg-dead-ui.show {
  display: block;
}

/* M12 tags: chip rows wrap and stay compact across the editor, catalog, and lists. */
.tg-tag-editor .tg-tag-chips,
.catalog-card-tags,
.catalog-active-tags,
.smart-card-tags,
.actions-row-tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  margin-top: 6px;
}

.catalog-active-tags {
  margin: 4px 0 0;
}

.smart-card-tag,
.actions-row-tag {
  font-size: 0.72rem;
  line-height: 1.4;
  padding: 1px 8px;
  border-radius: 999px;
  color: var(--mud-palette-text-secondary);
  background: var(--mud-palette-action-default-hover);
}

/* M19: the toolbars host a "Show archived" switch beside the search, so the width cap moves
   from the row onto the search field itself. */
.smart-toolbar,
.actions-toolbar {
  margin-bottom: 12px;
}

.smart-toolbar .mud-input-control,
.actions-toolbar .mud-input-control {
  max-width: 420px;
  flex: 1 1 260px;
}

.catalog-pager,
.smart-pager,
.actions-pager {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  margin-top: 20px;
}

/* ---- M37 Dashboards: widget grid + smart cards -------------------------------------------- */

.tg-dash-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 12px;
}

.tg-dash-span-small { grid-column: span 4; min-width: 0; }
.tg-dash-span-wide { grid-column: span 8; min-width: 0; }
.tg-dash-span-full { grid-column: span 12; min-width: 0; }

@media (max-width: 960px) {
  .tg-dash-span-small { grid-column: span 6; }
  .tg-dash-span-wide { grid-column: span 12; }
}

@media (max-width: 600px) {
  .tg-dash-span-small { grid-column: span 12; }
}

/* M43: titles used to be a single nowrap line, so "SOURCE · smartTool (needs scope)" rendered as
   "SOURCE · smartTool (needs s..." on a phone — the half that says what the card IS got cut. Two
   wrapped lines fit the real titles and still bound a runaway one. */
.tg-widget-title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
  min-width: 0;
}

.tg-widget-error { word-break: break-word; }

.tg-widget-json {
  max-height: 260px;
  overflow: auto;
  margin: 0;
}

.tg-widget-foot {
  color: var(--mud-palette-text-secondary);
  font-size: 0.72rem;
}

.tg-widget-price { white-space: nowrap; }

.tg-mono input, .tg-mono textarea {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.82rem;
}

/* Smart card: every color is a theme token; the accent tints the left edge, never the text. */
.tg-smartcard {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.tg-smartcard.accent-primary { box-shadow: inset 2px 0 0 var(--mud-palette-primary); padding-left: 10px; }
.tg-smartcard.accent-secondary { box-shadow: inset 2px 0 0 var(--mud-palette-secondary); padding-left: 10px; }
.tg-smartcard.accent-success { box-shadow: inset 2px 0 0 var(--mud-palette-success); padding-left: 10px; }
.tg-smartcard.accent-warning { box-shadow: inset 2px 0 0 var(--mud-palette-warning); padding-left: 10px; }
.tg-smartcard.accent-error { box-shadow: inset 2px 0 0 var(--mud-palette-error); padding-left: 10px; }

.tg-smartcard-label {
  color: var(--mud-palette-text-secondary);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.tg-smartcard-value {
  font-size: 1.6rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  word-break: break-word;
}

.tg-smartcard-hint {
  color: var(--mud-palette-text-secondary);
  font-size: 0.75rem;
}

/* M40 interactive blocks: a control and its price sit on one line, wrapping on narrow cards so the
   price is never cut off (it has to be readable before the tap). */
.tg-smartcard-control {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 2px;
}

.tg-smartcard-delta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-variant-numeric: tabular-nums;
}

.tg-smartcard-delta.tone-success, .tg-smartcard-badge.tone-success { color: var(--mud-palette-success); }
.tg-smartcard-delta.tone-error, .tg-smartcard-badge.tone-error { color: var(--mud-palette-error); }
.tg-smartcard-delta.tone-neutral { color: var(--mud-palette-text-secondary); }
.tg-smartcard-badge.tone-warning { color: var(--mud-palette-warning); }
.tg-smartcard-badge.tone-info { color: var(--mud-palette-info); }
.tg-smartcard-badge.tone-neutral { color: var(--mud-palette-text-secondary); }

.tg-smartcard-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.tg-smartcard-badge {
  border: 1px solid var(--tg-hairline);
  border-radius: 999px;
  padding: 1px 10px;
  font-size: 0.72rem;
  white-space: nowrap;
}

.tg-smartcard-list {
  display: flex;
  flex-direction: column;
}

.tg-smartcard-list-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 5px 0;
  border-bottom: 1px solid var(--tg-hairline);
  min-width: 0;
}

.tg-smartcard-list-row:last-child { border-bottom: none; }

/* M43: list rows were single-line nowrap, which on a phone cut most rows mid-sentence ("savedAction
   and smartTool cards cost a no..."). The primary now wraps to two lines, and the secondary is
   width-bounded with its own ellipsis so it can never be pushed past the card's right edge. */
.tg-smartcard-list-primary {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
  font-size: 0.85rem;
  flex: 1 1 auto;
  min-width: 0;
}

.tg-smartcard-list-secondary {
  color: var(--mud-palette-text-secondary);
  font-size: 0.78rem;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  flex: 0 1 auto;
  min-width: 0;
  max-width: 45%;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tg-smartcard-divider {
  border-top: 1px solid var(--tg-hairline);
}

/* M41 link block: an outbound anchor with its destination host beside it. Same honesty rule as
   prices on controls — where a click goes is visible before the click. */
.tg-smartcard-linkrow {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  min-width: 0;
}

.tg-smartcard-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--mud-palette-primary);
  font-size: 0.85rem;
  text-decoration: none;
  min-width: 0;
}

.tg-smartcard-link:hover { text-decoration: underline; }

/* M43: the hint sat inline after the anchor and wrapped mid-phrase, reading as part of the link
   text ("Hacker News front page the source this card pulls from"). Its own line, always. */
.tg-smartcard-linkrow > .tg-smartcard-hint {
  flex: 1 0 100%;
  margin-top: -2px;
}

.tg-smartcard-link span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tg-smartcard.accent-custom .tg-smartcard-link { color: hsl(var(--tg-card-hue, 190) 75% 62%); }

.tg-smartcard-list-link {
  color: var(--mud-palette-primary);
  text-decoration: none;
}

.tg-smartcard-list-link:hover { text-decoration: underline; }

/* M41 select + input controls: the field takes the room, the price stays readable beside it. */
.tg-smartcard-select { min-width: 160px; flex: 1 1 160px; }

.tg-smartcard-inputrow { align-items: center; }

.tg-smartcard-input { min-width: 160px; flex: 1 1 160px; }

/* ---- M37b Dashboard themes: every value below is portal-owned; agent choices arrive only as
   validated enum classes and the two integer hue custom properties. ------------------------- */

.tg-smartcard-heading {
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.25;
  word-break: break-word;
}

.tg-smartcard.accent-custom {
  box-shadow: inset 2px 0 0 hsl(var(--tg-card-hue, 190) 80% 55%);
  padding-left: 10px;
}

.tg-smartcard.accent-custom .tg-smartcard-heading { color: hsl(var(--tg-card-hue, 190) 75% 62%); }

.tg-smartcard-meter {
  height: 6px;
  border-radius: 999px;
  background: var(--tg-hairline);
  overflow: hidden;
}

.tg-smartcard-meter-fill {
  height: 100%;
  border-radius: 999px;
  background: hsl(var(--tg-card-hue, 190) 80% 55%);
}

/* The themed board: hue drives an accent, backdrop picks a page treatment, the rest are knobs. */
.tg-dash-theme {
  --tg-dash-accent: hsl(var(--tg-dash-hue, 190) 80% 55%);
  --tg-dash-accent-soft: hsl(var(--tg-dash-hue, 190) 70% 55% / 0.14);
  --tg-dash-accent-line: hsl(var(--tg-dash-hue, 190) 60% 50% / 0.35);
  border-radius: var(--tg-radius);
}

.tg-dash-theme .tg-card {
  border-color: var(--tg-dash-accent-line);
}

.tg-dash-theme .tg-widget-title { color: var(--tg-dash-accent); }

.tg-dash-theme .tg-smartcard:not(.accent-custom) { --tg-card-hue: var(--tg-dash-hue); }

.tg-dash-theme .tg-smartcard.accent-neutral {
  box-shadow: inset 2px 0 0 var(--tg-dash-accent);
  padding-left: 10px;
}

/* Backdrops. Deep sinks the board into darkness; glow haloes it from the accent; grid draws a
   faint blueprint; aurora blends the two hues. All read fine over either app theme because they
   are translucent layers, not opaque grounds. */
.tg-dash-theme.backdrop-deep,
.tg-dash-theme.backdrop-glow,
.tg-dash-theme.backdrop-grid,
.tg-dash-theme.backdrop-aurora {
  padding: 14px;
  margin: -6px;
}

.tg-dash-theme.backdrop-deep { background: rgba(0, 0, 0, 0.28); }

.tg-dash-theme.backdrop-glow {
  background: radial-gradient(120% 90% at 50% 0%, var(--tg-dash-accent-soft), transparent 62%);
}

.tg-dash-theme.backdrop-grid {
  background-image:
    linear-gradient(var(--tg-dash-accent-soft) 1px, transparent 1px),
    linear-gradient(90deg, var(--tg-dash-accent-soft) 1px, transparent 1px);
  background-size: 28px 28px;
}

.tg-dash-theme.backdrop-aurora {
  background:
    radial-gradient(70% 60% at 12% 0%, var(--tg-dash-accent-soft), transparent 60%),
    radial-gradient(70% 60% at 88% 8%, hsl(var(--tg-dash-hue2, 260) 70% 55% / 0.12), transparent 60%);
}

/* Shape. */
.tg-dash-theme.shape-sharp .tg-card, .tg-dash-theme.shape-sharp .tg-smartcard-meter { border-radius: 4px; }
.tg-dash-theme.shape-round .tg-card { border-radius: 22px; }

/* Density. */
.tg-dash-theme.density-compact .tg-dash-grid { gap: 8px; }
.tg-dash-theme.density-compact .tg-card { padding: 8px !important; }
.tg-dash-theme.density-compact .tg-smartcard { gap: 6px; }
.tg-dash-theme.density-compact .tg-smartcard-value { font-size: 1.3rem; }

/* Typeface: system stacks only, never a downloaded font. */
.tg-dash-theme.type-mono,
.tg-dash-theme.type-mono .tg-smartcard-value,
.tg-dash-theme.type-mono .tg-widget-title {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

.tg-dash-theme.type-display .tg-smartcard-value,
.tg-dash-theme.type-display .tg-smartcard-heading {
  font-family: Georgia, 'Times New Roman', serif;
  letter-spacing: -0.02em;
}

/* M43: an auto-rendered STRING snapshot that is prose, not a figure — readable body copy with its
   own line breaks kept, instead of the 1.6rem headline face. */
.tg-widget-prose {
  font-size: 0.85rem;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  color: var(--mud-palette-text-primary);
  max-height: 22rem;
  overflow-y: auto;
}

/* M43: the mobile FAB is fixed above the bottom bar and was landing on the last card's content.
   Clear its footprint as well as the bar's. */
@media (max-width: 959px) {
  .tg-dash-body {
    padding-bottom: 72px;
  }
}

/* M42 webhook triggers: the last-delivery outcome stays one truncated line in the row footer. */
.tg-webhook-outcome {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 50%;
}
