/* ============================================================================
   StravixUI — design tokens and the global rules the controls depend on.
   Reference once from the host document, AFTER MudBlazor's stylesheet:

       <link rel="stylesheet" href="_content/StravixUI.Blazor/css/stravixui.css" />

   Everything mode-DEPENDENT rides the --mud-palette-* variables MudThemeProvider
   regenerates on the dark/light flip (palettes in Theming/StravixTheme.cs). Only
   mode-INVARIANT values live as --stx-* custom properties, so a host that swaps
   the palette re-skins every control with no extra wiring.

   Per-component styling is NOT here — it lives in co-located .razor.css files
   that the Blazor build bundles into the host's scoped stylesheet automatically.
   ========================================================================== */

/* ---- Self-hosted variable fonts (OFL) — no CDN, deliberately: a CDN link is a
        third-party request on every page, and it fails outright in sandboxed
        E2E environments that block non-loopback traffic. ---- */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/inter-var.woff2") format("woff2-variations");
}

@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/space-grotesk-var.woff2") format("woff2-variations");
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-var.woff2") format("woff2-variations");
}

/* ---- Mode-invariant tokens ----
   Mirrored, value for value, by tokens/stravix.tokens.json — the framework-neutral
   source a future StravixUI.React consumes. Change one, change both. */
:root {
  --stx-radius-btn: 2px;
  --stx-radius-panel: 6px;
  --stx-radius-pill: 999px;

  --stx-font-display: "Space Grotesk", "Inter", sans-serif;
  --stx-font-mono: "JetBrains Mono", SFMono-Regular, Menlo, Consolas, monospace;

  /* No colour lives here, deliberately. Colour is defined once in StravixTheme.cs
     and read back from --mud-palette-*; a second copy here would drift. */
}

/* ---- Brand bar: header plate for panels, dialogs and card headers ----
   It reads as part of the surface it caps, separated by the hairline alone — a header
   tinted away from its own panel is the thing the eye lands on first, and it is never
   the thing worth looking at. Surface, not an accent slot: accents are foreground
   colours, and borrowing one here makes every header track whatever that accent is. */
.stx-brand-bar {
  background: var(--mud-palette-surface);
  color: var(--mud-palette-text-primary);
  box-shadow: inset 0 -1px 0 var(--mud-palette-lines-default);
}

/* ---- FallbackImage ----
   There is deliberately NO placeholder drawn behind a good image: an always-present
   underlay costs an extra <img> per instance and bleeds through the letterbox bars of
   a Contain-fitted image. A missing source renders the placeholder directly, and a
   source that 404s is swapped by stxShowFallback (js/stravixui.js). */
.stx-fallback-image {
  position: relative;
  overflow: hidden;
}

.stx-fallback-image-fill {
  width: 100%;
  height: 100%;
}

.stx-fallback-image-img {
  width: 100%;
  height: 100%;
  display: block;
}

/* The "Not found" placeholder, revealed in place of an image that failed to load.
   Hidden until then via an inline display:none so it never bleeds through a loaded
   image's letterbox; stxShowFallback flips it on and hides the failed image. */
.stx-image-fallback-underlay {
  position: absolute;
  inset: 0;
}

/* An image the browser could not load, marked js-image-fallback: hidden so the
   browser's own broken-image glyph never shows. */
.js-image-fallback.stx-image-failed {
  display: none;
}

/* ---- Tooltips are positioned in VIEWPORT coordinates, not document coordinates. ----

   MudBlazor places a popover absolutely, and a body-level one (Inline="false", which the Button
   control always sets) in the document's coordinate space — so a tooltip whose box reaches past
   the right edge of the window grows documentElement.scrollWidth. A tooltip anchored near a
   right-edge action (a toolbar icon at `right: 16px`, say) can then push a horizontal scrollbar
   onto the page; the scrollbar's layout width shifts the button out from under the pointer, which
   closes the tooltip, which removes the scrollbar, which slides the button back and reopens the
   tooltip — a flicker loop.

   A fixed box contributes nothing to the document's scrollable overflow, so a viewport-positioned
   tooltip cannot start that loop at any window size. This selector is the zero-size marker
   MudBlazor leaves at the anchor site as the popover's placement handle; its own JS reads this
   element's computed position and switches the popover to viewport coordinates when it finds
   `fixed`, which is the same branch MudPopover's `Fixed` parameter takes. MudTooltip does not
   surface that parameter, which is why this is CSS: the Button control asks for it directly with
   Class="mud-popover-fixed". The handle carries no content and is already out of flow, so no
   button's layout changes. */
.mud-tooltip-root > [id^="popover-"] {
  position: fixed;
}

/* A tooltip is placed centred on its button and is then squeezed by whichever viewport edge it
   reaches, so its text has to be able to wrap into the room that is left. A label with nowhere to
   break — a reference ID, an underscored identifier, an email address — instead keeps its full
   width and hangs past the edge, where the rule above leaves it clipped rather than readable.
   `anywhere` and not `break-word` because only `anywhere` lowers the box's min-content width, and
   that is the measurement that decides whether it fits at all. */
.mud-popover.mud-tooltip {
  overflow-wrap: anywhere;
}
