/* Snap CD theme v2.4 — derived from design/brand/tokens/tokens.json */

@font-face { font-family: 'Geist Sans'; font-weight: 400; font-style: normal; font-display: swap; src: url('/_content/SnapCd.Server.Core/fonts/GeistSans-Regular.woff2') format('woff2'); }
@font-face { font-family: 'Geist Sans'; font-weight: 500; font-style: normal; font-display: swap; src: url('/_content/SnapCd.Server.Core/fonts/GeistSans-Medium.woff2') format('woff2'); }
@font-face { font-family: 'Geist Sans'; font-weight: 600; font-style: normal; font-display: swap; src: url('/_content/SnapCd.Server.Core/fonts/GeistSans-SemiBold.woff2') format('woff2'); }
@font-face { font-family: 'Geist Sans'; font-weight: 700; font-style: normal; font-display: swap; src: url('/_content/SnapCd.Server.Core/fonts/GeistSans-Bold.woff2') format('woff2'); }
@font-face { font-family: 'Geist Mono'; font-weight: 400; font-style: normal; font-display: swap; src: url('/_content/SnapCd.Server.Core/fonts/GeistMono-Regular.woff2') format('woff2'); }

:root {
  --snap-ink: #12171D;
  --snap-steel: #4A5561;
  --snap-fog: #8B96A0;
  --snap-mist: #DDE3E8;
  --snap-surface: #F2F4F6;
  --snap-paper: #FAFBFB;

  --snap-accent: #E85D1A;
  --snap-accent-hover: #DC5414;
  --snap-accent-deep: #C1470C;
  --snap-accent-tint: #FDEEE3;
  /* Text on a solid accent fill. Sourced from the palette (SecondaryContrastText in
     SnapCdTheme.cs): white in light mode, ink in dark — flips with the theme. */
  --snap-on-accent: var(--mud-palette-secondary-text, #FFFFFF);

  /* Semantic colours. These mirror the MudBlazor palette in SnapCdTheme.cs and
     drive module state (Applied -> success, ApplyFailed/DestroyFailed -> error,
     Cancelled/Timeout/NotApproved -> warning, everything else -> neutral).
     NOTE: warning IS the accent — amber clashes with ember, so rather than add a
     second warm colour the app reuses the accent for the warning state. */
  --snap-success: #00B368;
  --snap-success-tint: #DFF7EC;
  --snap-error: #DB4A3F;
  --snap-error-tint: #FBE7E5;
  --snap-info: #4E8AF4;
  --snap-warning: #E85D1A;

  /* Job status dots: warning (= accent) and error read as the same colour at
     dot size, so running gets a lighter accent and failed a deeper red */
  --snap-running: #EB753C;
  --snap-failed: #C62828;

  --snap-bg: #FAFBFB;
  --snap-bg-raised: #FFFFFF;
  --snap-bg-inset: #F2F4F6;
  --snap-bg-sidebar: #12171D;
  --snap-border: #DDE3E8;
  --snap-text: #12171D;
  --snap-text-2: #4A5561;
  --snap-text-3: #8B96A0;
  --snap-code-bg: #12171D;
  --snap-code-text: #E8ECEF;

  --snap-sidebar-text: #E8ECEF;

  --snap-shadow-sm: 0 1px 2px rgba(18,23,29,0.06);
  --snap-shadow-md: 0 2px 4px rgba(18,23,29,0.08), 0 1px 2px rgba(18,23,29,0.04);
  --snap-shadow-lg: 0 4px 8px rgba(18,23,29,0.10), 0 2px 4px rgba(18,23,29,0.05);

  --snap-font-sans: 'Geist Sans', system-ui, -apple-system, sans-serif;
  --snap-font-mono: 'Geist Mono', ui-monospace, 'Cascadia Code', monospace;
}

.mud-dark {
  --snap-bg: #000000;
  --snap-bg-raised: #171D24;
  --snap-bg-inset: #0E1216;
  --snap-bg-sidebar: #0E1216;
  --snap-border: #262E37;
  --snap-text: #E8ECEF;
  --snap-text-2: #9AA5B0;
  --snap-text-3: #6B7681;
  --snap-code-bg: #000000;
  --snap-code-text: #E8ECEF;

  --snap-success-tint: #0a2618;
  --snap-error-tint: #2a0a0a;

  --snap-shadow-sm: 0 1px 2px rgba(0,0,0,0.3);
  --snap-shadow-md: 0 2px 4px rgba(0,0,0,0.35), 0 1px 2px rgba(0,0,0,0.2);
  --snap-shadow-lg: 0 4px 8px rgba(0,0,0,0.4), 0 2px 4px rgba(0,0,0,0.25);
}

/* Global overrides */

/* Until the circuit's first render (prerender is off) the MudBlazor palette vars
   don't exist yet, so body has no background — without this the viewport flashes
   white on every full page load in dark mode. */
html {
  background-color: var(--snap-bg);
  color: var(--snap-text);
}

/* Blazor's <FocusOnNavigate Selector="h1"> moves focus to the page heading after
   navigation so screen readers announce the new page. On a fresh page load (typed
   URL, refresh) browsers treat that programmatic focus as :focus-visible and draw
   a focus ring around the heading; suppress the visual ring, as the stock Blazor
   template does. */
h1:focus {
  outline: none;
}

.mud-button-root .mud-button-label {
  text-transform: lowercase !important;
}

.mud-button-root {
  border-radius: 0px !important;
}

/* Dialog action buttons never touch. .mud-dialog-actions is MudBlazor's own
   container for them, so this catches every dialog by construction; it lays them
   out as a flex row with no gap, leaving Cancel/Submit flush. A gap on the
   container (rather than a margin on .mud-button-root) keeps this off the
   elements MudBlazor builds switches out of — a blanket button margin knocked
   the switch thumb out of its track. Other button rows already set their own gap. */
.mud-dialog-actions {
  gap: 8px;
}

.mud-tabs .mud-tabs-tabbar {
  text-transform: lowercase !important;
}

.mud-tabs .mud-tab {
  font-size: 14px !important;
}

.mud-expand-panel .mud-expand-panel-header .mud-expand-panel-text {
  font-size: 14px !important;
}

/* Inputs holding a system object: an address, a module path, a runner, an id.
   MudBlazor sets `font: inherit` on .mud-input > input.mud-input-root, and the
   shorthand takes the family with it, so these have to outrank that selector. */
.snapcd-mono input,
.snapcd-mono textarea,
.snapcd-mono .mud-input > input.mud-input-root,
.snapcd-mono .mud-input > textarea.mud-input-root {
  font-family: var(--snap-font-mono, monospace);
}

/* A placeholder teaching an indentation-sensitive format has to align like the text
   that replaces it, and ::placeholder does not inherit the rule above. */
.snapcd-mono input::placeholder,
.snapcd-mono textarea::placeholder,
.snapcd-mono .mud-input > input.mud-input-root::placeholder,
.snapcd-mono .mud-input > textarea.mud-input-root::placeholder {
  font-family: var(--snap-font-mono, monospace);
}

/* Stack/namespace/module lists: expanded panel content shows the page background;
   only the panel header keeps the surface color */
.stack-list .mud-expand-panel,
.namespace-list .mud-expand-panel,
.module-list .mud-expand-panel {
  background-color: transparent !important;
}

.stack-list .mud-expand-panel > .mud-expand-panel-header,
.namespace-list .mud-expand-panel > .mud-expand-panel-header,
.module-list .mud-expand-panel > .mud-expand-panel-header {
  background-color: var(--mud-palette-surface) !important;
}

/* Compact rows: MudBlazor defaults these headers to min-height 48px / padding
   16px 24px, which is too airy for a dense stack > namespace > module tree.
   Halve the vertical padding and let the row size to its content. */
.stack-list .mud-expand-panel > .mud-expand-panel-header,
.namespace-list .mud-expand-panel > .mud-expand-panel-header,
.module-list .mud-expand-panel > .mud-expand-panel-header {
  min-height: 0 !important;
  padding-top: 8px !important;
  padding-bottom: 8px !important;
}

/* Nested lists run flush to the right edge. MudBlazor's default gutters put
   24px of padding on BOTH sides of a panel's content, so each nesting level
   (stack > namespace > module) inset its child another 24px: the stack row
   reached the edge, the namespace row stopped 24px short, the module row 48px.
   Keep the left gutter — that is the indent that shows depth — and drop the
   right one, at both the content and the header, so every row runs flush. */
.stack-list .mud-expand-panel-content,
.namespace-list .mud-expand-panel-content,
.module-list .mud-expand-panel-content {
  padding-right: 0 !important;
}

.stack-list .mud-expand-panel-header,
.namespace-list .mud-expand-panel-header,
.module-list .mud-expand-panel-header {
  padding-right: 12px !important;
}

/* Dashboard starred card: the unstar affordance is hidden until its row is hovered */
.row-star {
  visibility: hidden;
}

.attn-row:hover .row-star {
  visibility: visible;
}

/* Clickable breadcrumbs highlight in accent on hover (same as dashboard links) */
.mud-breadcrumbs a:hover,
.mud-breadcrumbs a:hover * {
  color: var(--snap-accent) !important;
  text-decoration: underline;
}

/* MudLink (dependency graph nodes, list links, ...) highlights in accent on hover */
a.mud-link:hover {
  color: var(--snap-accent) !important;
}

/* Scalar API reference (/ApiReference): map Scalar's theme variables onto the
   snap tokens so the reference is indistinguishable from the rest of the app.
   The --snap-* values flip via .mud-dark on <html>, so one block covers both
   modes. Scalar puts its mode class (light-mode/dark-mode) on <body> and
   re-declares variables closer to some consumers (.t-doc__sidebar, .scalar-card),
   so the override must land on body level AND on those re-declaration points —
   a rule on the mount div alone is beaten by any closer re-declaration. */
body.light-mode,
body.dark-mode,
#scalar-api-reference,
#scalar-api-reference .t-doc__sidebar,
body.light-mode .scalar-card,
body.dark-mode .scalar-card {
  --scalar-background-1: var(--snap-bg);
  --scalar-background-2: var(--snap-bg-inset);
  --scalar-background-3: var(--snap-bg-raised);
  --scalar-color-1: var(--snap-text);
  --scalar-color-2: var(--snap-text-2);
  --scalar-color-3: var(--snap-text-3);
  --scalar-color-accent: var(--snap-accent);
  --scalar-background-accent: color-mix(in srgb, var(--snap-accent) 12%, transparent);
  --scalar-border-color: var(--snap-border);

  --scalar-sidebar-background-1: var(--snap-bg);
  --scalar-sidebar-color-1: var(--snap-text);
  --scalar-sidebar-color-2: var(--snap-text-2);
  --scalar-sidebar-color-active: var(--snap-accent);
  --scalar-sidebar-item-hover-background: var(--snap-bg-inset);
  --scalar-sidebar-item-active-background: color-mix(in srgb, var(--snap-accent) 12%, transparent);
  --scalar-sidebar-border-color: var(--snap-border);
  --scalar-sidebar-search-background: var(--snap-bg-inset);
  --scalar-sidebar-search-color: var(--snap-text-2);
  --scalar-sidebar-search-border-color: var(--snap-border);

  --scalar-font: var(--snap-font-sans);
  --scalar-font-code: var(--snap-font-mono);

  --scalar-sidebar-width: 340px;

  --scalar-button-1: var(--snap-accent);
  --scalar-button-1-color: var(--snap-on-accent);
  --scalar-button-1-hover: var(--snap-accent-hover);

  --scalar-color-green: var(--snap-success);
  --scalar-color-red: var(--snap-error);
  --scalar-color-blue: var(--snap-info);
  --scalar-color-orange: var(--snap-accent);
  --scalar-color-yellow: var(--snap-warning);
  --scalar-color-purple: var(--snap-fog);

  /* Scalar derives -md/-2xl/... from --scalar-radius where THEY are declared,
     so zeroing the base alone doesn't reach them — zero the derived set too.
     --scalar-radius-full is left alone: it draws the genuinely-circular bits. */
  --scalar-radius: 0;
  --scalar-radius-md: 0;
  --scalar-radius-lg: 0;
  --scalar-radius-xl: 0;
  --scalar-radius-2xl: 0;
  --scalar-radius-3xl: 0;
}

/* Scalar action buttons (Test Request, Authorize, ...) follow the app's button
   idiom (lowercase labels). Scoped to .scalar-button: schema rows, enum values,
   and paths are also <button> elements and must keep their casing. */
#scalar-api-reference .scalar-button {
  text-transform: lowercase;
}

/* Squared corners, unconditionally: Scalar rounds through several independent
   paths (radius variables, utility classes, scoped component rules), so the
   variable overrides above aren't sufficient on their own. Spared: genuinely
   circular elements (rounded-full) and the header badges (version / spec
   chips), which stay chips. */
#scalar-api-reference *:not([class*="rounded-full"]):not(.badge),
.z-context *:not([class*="rounded-full"]):not(.badge),
.scalar-app *:not([class*="rounded-full"]):not(.badge) {
  border-radius: 0 !important;
}

/* Client Libraries: no "...more" overflow tile; the selected library gets the
   same treatment as an active tab (accent slider + accent label) instead of
   Scalar's 1px text-colored underline. */
#scalar-api-reference .client-libraries-more,
#scalar-api-reference a[href="https://www.scalar.com"] {
  display: none !important;
}

#scalar-api-reference .client-libraries__active {
  border-bottom: 2px solid var(--snap-accent);
}

#scalar-api-reference .client-libraries__active .client-libraries-text {
  color: var(--snap-accent);
}

/* Outlined Scalar buttons (Authorize, Clear) follow the app's only button
   variant: filled accent. */
#scalar-api-reference .scalar-button-outlined {
  background: var(--snap-accent) !important;
  color: var(--snap-on-accent) !important;
  border-color: transparent !important;
}

/* "required" markers (authentication card, schema properties) in accent */
#scalar-api-reference .required,
#scalar-api-reference .property-required,
#scalar-api-reference .request-body-required {
  color: var(--snap-accent) !important;
}

/* "Authentication required" badges — the intro card one (.authenticationRequired)
   and the per-operation "auth required" indicator: accented, and clickable
   (scalar-interop.js forwards the click to the Authorize button). */
#scalar-api-reference .authenticationRequired,
#scalar-api-reference [data-testid="auth-indicator"] {
  color: var(--snap-accent) !important;
  cursor: pointer;
}

/* Section label above ListStacks / ListNamespaces / ListModules. The same rule
   serves all three so a nested list (stack > namespace > module) reads as the
   same kind of heading at every depth. */
.list-heading {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--snap-text-3);
  margin-bottom: 8px;
}

/* Blazor injects these itself, so the ids and classes below are the framework's, not the app's. */

#components-reconnect-modal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 2000;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.55);
  font-family: var(--snap-font-sans);
}

/* The element carries an inline display:none so it stays hidden before this sheet loads, which
   is what these overrides are declared against. */
#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected {
  display: flex !important;
}

#components-reconnect-modal.components-reconnect-hide {
  display: none !important;
}

#components-reconnect-modal > div {
  min-width: 320px;
  max-width: 420px;
  padding: 24px 28px;
  border: 1px solid var(--snap-border);
  border-radius: 8px;
  background: var(--snap-bg-raised);
  box-shadow: var(--snap-shadow-lg);
  color: var(--snap-text);
  text-align: center;
}

#components-reconnect-modal svg circle {
  stroke: var(--snap-accent);
}

/* Which sentence applies is the dialog's own state, so each is shown only for its state. */
#components-reconnect-modal .components-reconnect-dialog-text {
  display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt,
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-retry,
#components-reconnect-modal.components-reconnect-failed .components-reconnect-give-up,
#components-reconnect-modal.components-reconnect-rejected .components-reconnect-give-up {
  display: block !important;
}

#components-reconnect-modal.components-reconnect-retrying .components-reconnect-first-attempt {
  display: none !important;
}


#components-reconnect-modal .components-reconnect-dialog-text {
  color: var(--snap-text);
  font-size: 0.95rem;
  line-height: 1.5;
}

#components-reconnect-modal a,
#components-reconnect-modal button {
  display: inline-block;
  margin-top: 16px;
  padding: 6px 16px;
  border: none;
  border-radius: 4px;
  background: var(--snap-accent);
  color: var(--snap-on-accent);
  font-family: var(--snap-font-sans);
  font-size: 0.875rem;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
}

#components-reconnect-modal a:hover,
#components-reconnect-modal button:hover {
  background: var(--snap-accent-hover);
}

/* Reloading is the only way out of a failure, so the button is offered only then. Declared after
   the rules that style it, which set a display of their own. */
#components-reconnect-modal button {
  display: none;
}

#components-reconnect-modal.components-reconnect-failed button,
#components-reconnect-modal.components-reconnect-rejected button {
  display: inline-block !important;
}

#blazor-error-ui {
  display: none;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 2001;
  padding: 12px 20px;
  background: var(--snap-error);
  color: #FFFFFF;
  font-family: var(--snap-font-sans);
  font-size: 0.875rem;
  box-shadow: var(--snap-shadow-md);
}

#blazor-error-ui .reload,
#blazor-error-ui .dismiss {
  color: #FFFFFF;
  text-decoration: underline;
  cursor: pointer;
}

#blazor-error-ui .dismiss {
  float: right;
  text-decoration: none;
}

/* Stack trace inside the error alert. The alert's message element is a flex child, which
   does not shrink below its content unless min-width is reset. */
.mud-alert-message {
  min-width: 0;
}

.snapcd-stack-trace {
  display: block;
  margin: 8px 0 0;
  padding: 8px 12px;
  max-width: 100%;
  max-height: 320px;
  overflow: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-family: var(--snap-font-mono, monospace);
  font-size: 0.75rem;
  line-height: 1.5;
  color: inherit;
  background: rgba(0, 0, 0, 0.25);
  border-radius: 4px;
}

.snapcd-error-header {
  white-space: pre-line;
}
