Codebase-wide sweep bringing the web client into strict compliance with the AGENTS.md TypeScript and Mantine/React conventions: ~170 inline 2+-static-prop elements extracted to named .withProps() constants across ~77 files, the AGENTS.md rule wording tightened to match (static-prop boundary + Accordion/Transition/data-*/Box exemptions), a real ScreenStage Box->Flex layout regression fixed (direction: column) with a Storybook regression guard, and an App.tsx double-cast tightened. Closes #1762.
585 lines
26 KiB
CSS
585 lines
26 KiB
CSS
/*
|
|
* App.css — Global styles that CANNOT be expressed in the Mantine theme.
|
|
*
|
|
* Only the following belong here:
|
|
* - :root CSS custom properties (--inspector-* design tokens)
|
|
* - @keyframes animations
|
|
* - Pseudo-selectors (:hover, :focus) that cross component boundaries
|
|
* - Nested child-element selectors for third-party HTML output
|
|
* - Styles for native HTML elements (img, iframe, etc.)
|
|
*
|
|
* Everything else (margin, padding, background, border, color, font-size)
|
|
* belongs in the Mantine theme via Component.extend() or .withProps().
|
|
*/
|
|
|
|
:root {
|
|
/* ── Brand ─────────────────────────────────────────────── */
|
|
--inspector-brand-primary: var(--mantine-primary-color-filled);
|
|
|
|
/* ── Text ──────────────────────────────────────────────── */
|
|
--inspector-text-primary: var(--mantine-color-text);
|
|
--inspector-text-secondary: var(--mantine-color-dimmed);
|
|
--inspector-text-inverse: var(--mantine-color-white);
|
|
/* Danger action text (Remove / Disconnect subtle buttons). A deep red on
|
|
light surfaces; a lighter red on the dark card/header (see dark override) —
|
|
`red-6` fell just under WCAG AA on both. */
|
|
--inspector-danger-text: var(--mantine-color-red-7);
|
|
|
|
/* ── Surfaces ──────────────────────────────────────────── */
|
|
/* Light-grey app background so the white cards read as raised. Drives
|
|
Mantine's `--mantine-color-body` (the actual page background), which
|
|
otherwise defaults to pure white. */
|
|
--inspector-surface-body: var(--mantine-color-gray-1);
|
|
--inspector-surface-card: var(--mantine-color-white);
|
|
/* Server-card fill: a hair lighter than the grey app background (`gray-0` vs
|
|
the body's `gray-1`) so the cards read as faintly raised on the white
|
|
Servers box. Light mode only; dark tracks the standard card surface. */
|
|
--inspector-surface-card-server: var(--mantine-color-gray-0);
|
|
/* Entry-card surface (Protocol / Network / Task message cards): the faint
|
|
`gray-0` grey — a hair lighter than the `gray-1` app background and matching
|
|
the server cards — so the entries read as soft cards on their white panel
|
|
(their inner Code blocks are raised to white via the `inset` variant). Keeps
|
|
the standard card tone in dark (overridden below). */
|
|
--inspector-surface-inset: var(--mantine-color-gray-0);
|
|
/* Code/content surfaces match the light-grey body so they stay distinct
|
|
against the white cards (the Code block has no border of its own). Dark
|
|
mode keeps the darker `dark-9` inset below. */
|
|
--inspector-surface-code: var(--inspector-surface-body);
|
|
/* Raised content surface used for content views that sit ON a grey inset
|
|
message card (Protocol/Network): white in light mode so they read as
|
|
raised above the grey card — the inverse of the grey-on-white insets
|
|
elsewhere. Applied via the Card `inset` variant (see theme/Card.ts). */
|
|
--inspector-surface-code-oncard: var(--mantine-color-white);
|
|
/* Subtle inset surface for modal call-outs / summary panels. Mantine's
|
|
`default-hover` already adapts to color scheme, so no dark override. */
|
|
--inspector-surface-subtle: var(--mantine-color-default-hover);
|
|
|
|
/* ── Inputs ────────────────────────────────────────────── */
|
|
--inspector-input-background: var(--mantine-color-white);
|
|
|
|
/* ── Borders ───────────────────────────────────────────── */
|
|
--inspector-border-default: var(--mantine-color-default-border);
|
|
--inspector-border-subtle: var(--mantine-color-gray-3);
|
|
|
|
/* ── Scrollbar ─────────────────────────────────────────── */
|
|
/* Matches Mantine ScrollArea's thumb so native scrollbars (used where a
|
|
ScrollArea would break flex sizing, e.g. the Resources accordion) blend in. */
|
|
--inspector-scrollbar-thumb: rgba(0, 0, 0, 0.4);
|
|
|
|
/* ── Connection status ─────────────────────────────────── */
|
|
--inspector-status-connected: var(--mantine-color-green-6);
|
|
--inspector-status-connecting: var(--mantine-color-yellow-6);
|
|
--inspector-status-disconnected: var(--mantine-color-gray-5);
|
|
--inspector-status-error: var(--mantine-color-red-6);
|
|
|
|
/* Red glow pulsed around a newly appearing tab's label (#1450) */
|
|
--inspector-glow-red: var(--mantine-color-red-6);
|
|
|
|
/* Green border drawn around a freshly-added/highlighted server card (#1535) */
|
|
--inspector-highlight-border: var(--mantine-color-green-6);
|
|
|
|
/* Red border drawn around a server card whose last connection attempt failed,
|
|
until another server is connected/attempted (#1621) */
|
|
--inspector-error-border: var(--mantine-color-red-6);
|
|
|
|
/* ── Log levels (RFC 5424) ─────────────────────────────── */
|
|
--inspector-log-debug: var(--mantine-color-gray-6);
|
|
--inspector-log-info: var(--mantine-color-blue-6);
|
|
--inspector-log-notice: var(--mantine-color-teal-6);
|
|
--inspector-log-warning: var(--mantine-color-yellow-6);
|
|
--inspector-log-error: var(--mantine-color-red-6);
|
|
--inspector-log-critical: var(--mantine-color-red-8);
|
|
--inspector-log-alert: var(--mantine-color-red-9);
|
|
--inspector-log-emergency: var(--mantine-color-red-9);
|
|
|
|
/* ── Task status ───────────────────────────────────────── */
|
|
--inspector-task-waiting: var(--mantine-color-gray-5);
|
|
--inspector-task-running: var(--mantine-color-blue-6);
|
|
--inspector-task-completed: var(--mantine-color-green-6);
|
|
--inspector-task-failed: var(--mantine-color-red-6);
|
|
--inspector-task-cancelled: var(--mantine-color-yellow-6);
|
|
|
|
/* ── History ───────────────────────────────────────────── */
|
|
--inspector-history-success: var(--mantine-color-green-6);
|
|
--inspector-history-error: var(--mantine-color-red-6);
|
|
|
|
/* ── Protocol / Network badges ─────────────────────────── */
|
|
/* Direction (client→server / server→client) and method chips. Light mode
|
|
keeps the tinted "light variant" look via Mantine's *-light tokens. */
|
|
--inspector-badge-outgoing-bg: var(--mantine-color-green-light);
|
|
--inspector-badge-outgoing-fg: var(--mantine-color-green-light-color);
|
|
--inspector-badge-incoming-bg: var(--mantine-color-violet-light);
|
|
--inspector-badge-incoming-fg: var(--mantine-color-violet-light-color);
|
|
/* Method: a neutral gray chip that adapts to the scheme — light-gray with
|
|
dark text in light mode, dark-gray with light text in dark mode (see the
|
|
dark override below). Matches the surrounding surface family. */
|
|
--inspector-badge-method-bg: var(--mantine-color-gray-2);
|
|
--inspector-badge-method-fg: var(--mantine-color-gray-7);
|
|
/* Network request category chips — `transport` (blue) / `auth` (violet). Same
|
|
treatment as the direction badges: a tinted light-variant fill here, a deep
|
|
saturated fill with light text in dark mode (below). */
|
|
--inspector-badge-transport-bg: var(--mantine-color-blue-light);
|
|
--inspector-badge-transport-fg: var(--mantine-color-blue-light-color);
|
|
--inspector-badge-auth-bg: var(--mantine-color-violet-light);
|
|
--inspector-badge-auth-fg: var(--mantine-color-violet-light-color);
|
|
|
|
/* Accent for the modern MCP-mirrored header names (Mcp-Method / Mcp-Name /
|
|
Mcp-Param-* / MCP-Protocol-Version) in the Network tab's header tables. */
|
|
--inspector-mcp-header-accent: var(--mantine-color-violet-7);
|
|
}
|
|
|
|
/* Dark mode overrides — tokens that need adjustment in dark scheme */
|
|
[data-mantine-color-scheme="dark"] {
|
|
/* Charcoal body matched to the header's segmented tab control (`dark-8`, the
|
|
Mantine SegmentedControl fill) — mirrors light mode, where the body and the
|
|
tab bar share `gray-1`. Cards (`gray-9`) still sit a step above it. */
|
|
--inspector-surface-body: var(--mantine-color-dark-8);
|
|
--inspector-surface-card: var(--mantine-color-gray-9);
|
|
/* Dark keeps server cards at the standard card surface (the lighter grey is a
|
|
light-mode-only treatment). */
|
|
--inspector-surface-card-server: var(--inspector-surface-card);
|
|
/* Dark keeps the message cards at the standard card tone (they already
|
|
contrast against the darker panel/body), so only light mode goes grey. */
|
|
--inspector-surface-inset: var(--mantine-color-gray-9);
|
|
/* On a dark message card, content views stay the darker `dark-9` inset (they
|
|
already contrast against the `gray-9` card) — only light mode inverts to
|
|
white. */
|
|
--inspector-surface-code-oncard: var(--mantine-color-dark-9);
|
|
--inspector-surface-code: var(--mantine-color-dark-9);
|
|
--inspector-border-subtle: var(--mantine-color-gray-4);
|
|
--inspector-input-background: var(--mantine-color-dark-9);
|
|
--inspector-scrollbar-thumb: rgba(255, 255, 255, 0.4);
|
|
|
|
/* The semantic status/log/task colors use the same `*-6` shade in both
|
|
schemes, which sits too dark on charcoal — lift them one to two steps so
|
|
they stay legible in dark mode. Light-mode `:root` keeps the `*-6` values. */
|
|
|
|
/* Status */
|
|
--inspector-status-connected: var(--mantine-color-green-4);
|
|
--inspector-status-connecting: var(--mantine-color-yellow-4);
|
|
--inspector-status-error: var(--mantine-color-red-4);
|
|
|
|
/* Log levels (RFC 5424) */
|
|
--inspector-log-info: var(--mantine-color-blue-4);
|
|
--inspector-log-notice: var(--mantine-color-teal-4);
|
|
--inspector-log-warning: var(--mantine-color-yellow-4);
|
|
--inspector-log-error: var(--mantine-color-red-4);
|
|
--inspector-log-critical: var(--mantine-color-red-5);
|
|
--inspector-log-alert: var(--mantine-color-red-6);
|
|
--inspector-log-emergency: var(--mantine-color-red-7);
|
|
|
|
/* Task status */
|
|
--inspector-task-running: var(--mantine-color-blue-4);
|
|
--inspector-task-completed: var(--mantine-color-green-4);
|
|
--inspector-task-failed: var(--mantine-color-red-4);
|
|
--inspector-task-cancelled: var(--mantine-color-yellow-4);
|
|
|
|
/* History */
|
|
--inspector-history-success: var(--mantine-color-green-4);
|
|
--inspector-history-error: var(--mantine-color-red-4);
|
|
|
|
/* Protocol/Network badges — solid fills with light text on charcoal (the
|
|
`*-light` tints from `:root` render washed-out here). Direction: a deep
|
|
green (distinct from the brighter green-6 "OK" status chip) and a saturated
|
|
violet; method: a dark-slate chip a step above the card. */
|
|
--inspector-badge-outgoing-bg: var(--mantine-color-green-8);
|
|
--inspector-badge-outgoing-fg: var(--mantine-color-green-0);
|
|
--inspector-badge-incoming-bg: var(--mantine-color-violet-6);
|
|
--inspector-badge-incoming-fg: var(--mantine-color-violet-0);
|
|
--inspector-badge-method-bg: var(--mantine-color-dark-5);
|
|
--inspector-badge-method-fg: var(--mantine-color-gray-2);
|
|
/* Category chips: deep blue (transport) / violet (auth) fills with light
|
|
text, matching the server→client direction badge. */
|
|
--inspector-badge-transport-bg: var(--mantine-color-blue-6);
|
|
--inspector-badge-transport-fg: var(--mantine-color-blue-0);
|
|
--inspector-badge-auth-bg: var(--mantine-color-violet-6);
|
|
--inspector-badge-auth-fg: var(--mantine-color-violet-0);
|
|
--inspector-mcp-header-accent: var(--mantine-color-violet-4);
|
|
|
|
/* ── A11y contrast (dark) ──────────────────────────────── */
|
|
/* Mantine's dark `dimmed` (dark-2) drops below AA on the lighter dark
|
|
surfaces (selected/hover rows); lift it one step. `!important` because
|
|
Mantine injects this var at runtime at this same specificity and would
|
|
otherwise win the cascade tie (see the light-scheme block below). */
|
|
--mantine-color-dimmed: var(--mantine-color-dark-1) !important;
|
|
/* Lighter danger red for the dark card/header (deep red would fail AA). */
|
|
--inspector-danger-text: var(--mantine-color-red-4);
|
|
}
|
|
|
|
/* A11y contrast (light): Mantine sets these per-scheme on a selector more
|
|
specific than `:root`, so override them at matching specificity (App.css
|
|
loads after Mantine, so it wins). Darkens the `dimmed` secondary text and the
|
|
`*-light` variant text so both clear WCAG AA (4.5:1) on light surfaces —
|
|
fixes ~600 of the axe color-contrast hits (dimmed text + tinted
|
|
badges/buttons/alerts). Dark mode keeps Mantine's lighter light-variant text.
|
|
*/
|
|
:root[data-mantine-color-scheme="light"] {
|
|
/* `!important`: Mantine injects the `*-light-color` variables at runtime at
|
|
the same specificity as this rule, so it wins the cascade tie without this.
|
|
A justified override of a third-party variable to meet WCAG AA — not a lint
|
|
workaround. `dimmed` already wins on specificity but is flagged for parity. */
|
|
--mantine-color-dimmed: var(--mantine-color-gray-7) !important;
|
|
--mantine-color-inspector-light-color: var(
|
|
--mantine-color-inspector-8
|
|
) !important;
|
|
--mantine-color-blue-light-color: var(--mantine-color-blue-8) !important;
|
|
--mantine-color-green-light-color: var(--mantine-color-green-8) !important;
|
|
--mantine-color-teal-light-color: var(--mantine-color-teal-8) !important;
|
|
--mantine-color-red-light-color: var(--mantine-color-red-8) !important;
|
|
--mantine-color-violet-light-color: var(--mantine-color-violet-8) !important;
|
|
--mantine-color-orange-light-color: var(--mantine-color-orange-8) !important;
|
|
--mantine-color-yellow-light-color: var(--mantine-color-yellow-9) !important;
|
|
}
|
|
|
|
/* The app background. Mantine paints `body` with `--mantine-color-body` (pure
|
|
white in light mode); override it here — App.css loads after Mantine's
|
|
styles, so this wins — so the light-grey `--inspector-surface-body` shows and
|
|
the white cards read as raised. Scheme-aware via the token's dark override. */
|
|
body {
|
|
background-color: var(--inspector-surface-body);
|
|
}
|
|
|
|
/* Floor the app at 1280px so the header, split panes, and footer never reflow
|
|
into a broken layout; below this the whole app scrolls horizontally instead.
|
|
Scoped to the app mount (#root) rather than `body` so it doesn't leak into
|
|
Storybook, which shares App.css but renders stories into its own root.
|
|
|
|
The `transform` makes #root the containing block for the AppShell's
|
|
position:fixed header + footer, so they honor the 1280px floor too — spanning
|
|
the full 1280 and scrolling horizontally with the content — instead of staying
|
|
pinned to a narrower viewport. Body-portalled overlays (modals, tooltips,
|
|
dropdowns) render outside #root, so they stay viewport-fixed as intended. */
|
|
#root {
|
|
min-width: 1280px;
|
|
transform: translateZ(0);
|
|
}
|
|
|
|
/* ── Animations ──────────────────────────────────────────── */
|
|
|
|
@keyframes inspector-pulse {
|
|
0%,
|
|
100% {
|
|
opacity: 1;
|
|
}
|
|
50% {
|
|
opacity: 0.4;
|
|
}
|
|
}
|
|
|
|
/* Both motions travel downward: enter descends from above into place, exit
|
|
descends from place to below — used for the header crossfade (#1450). */
|
|
@keyframes inspector-fade-slide-in {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-0.5rem);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
@keyframes inspector-fade-slide-out {
|
|
from {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
to {
|
|
opacity: 0;
|
|
transform: translateY(0.5rem);
|
|
}
|
|
}
|
|
|
|
/* A red glow around a tab label's text that starts at full intensity the
|
|
moment a content-gated tab appears and fades out (#1450). */
|
|
@keyframes inspector-tab-glow {
|
|
from {
|
|
text-shadow:
|
|
0 0 6px var(--inspector-glow-red),
|
|
0 0 12px var(--inspector-glow-red);
|
|
}
|
|
to {
|
|
text-shadow: none;
|
|
}
|
|
}
|
|
|
|
/* ── Status dot animations ───────────────────────────────── */
|
|
|
|
.inspector-pulse {
|
|
animation: inspector-pulse 1.5s ease-in-out infinite;
|
|
}
|
|
|
|
/* Applied (via the `tabGlow` Text variant) to a tab label; the glow starts full
|
|
and fades, running only while `data-glow="on"` on a freshly-appeared tab. */
|
|
.tab-glow[data-glow="on"] {
|
|
animation: inspector-tab-glow 325ms ease-in;
|
|
}
|
|
|
|
/* ── Header connect/disconnect animations (#1450) ────────── */
|
|
/* Any header region that appears on connect / leaves on disconnect — the
|
|
center title↔tab-bar crossfade, the server name (left), and the status +
|
|
Disconnect controls (right). The element leaving ([data-anim="out"]) slides
|
|
down + fades out immediately; the appearing one ([data-anim="in"]) is delayed
|
|
by half the duration so they're staggered. Keep the 300ms/150ms here in sync
|
|
with HEADER_ANIM_MS in ViewHeader.tsx. */
|
|
.header-anim[data-anim="in"] {
|
|
animation: inspector-fade-slide-in 300ms ease 150ms both;
|
|
}
|
|
|
|
.header-anim[data-anim="out"] {
|
|
animation: inspector-fade-slide-out 300ms ease both;
|
|
}
|
|
|
|
/* Honor reduced-motion for the header animations this PR adds (#1450): skip the
|
|
fade/slide and the new-tab glow, leaving the elements at their resting state.
|
|
Selectors match the originals' specificity so they win inside the query. */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.header-anim[data-anim="in"],
|
|
.header-anim[data-anim="out"],
|
|
.tab-glow[data-glow="on"] {
|
|
animation: none;
|
|
}
|
|
}
|
|
|
|
/* ── Accordion disclosure chevron (right when closed, down when open) ──
|
|
*
|
|
* Mantine's default chevron rotation flips 180° on open (e.g. down → up). For
|
|
* the `disclosure` Accordion variant we use a right-pointing chevron and rotate
|
|
* it only 90° so closed sections point right and open sections point down — the
|
|
* standard disclosure direction, matching ResourceLink's chevron (issue #1462).
|
|
* `[data-rotate]` is set by Mantine on the chevron slot when the item is open;
|
|
* the class+attribute selector outranks Mantine's `:where()`-wrapped default. */
|
|
|
|
/* Restore a smooth rotation: the accordion sets `transitionDuration={0}` to
|
|
* disable its panel height animation (which fights the flex layout), and that
|
|
* zeroes the shared `--accordion-transition-duration` the chevron would use.
|
|
* The 200ms restates Mantine's default accordion duration — keep it in sync if
|
|
* accordion timing is ever themed. */
|
|
.disclosure-chevron {
|
|
transition: transform 200ms ease;
|
|
}
|
|
|
|
.disclosure-chevron[data-rotate] {
|
|
transform: rotate(90deg);
|
|
}
|
|
|
|
/* ── Full-height sectioned accordion (Resources) ─────────────────
|
|
*
|
|
* The `disclosure` Accordion fills its full-height card as a flex column. The
|
|
* section controls (headers) stay pinned while each OPEN section's panel scrolls
|
|
* within its own share of the remaining height — the per-item `flex` weight
|
|
* (set in ResourceControls) hands space from long sections to short ones. With
|
|
* `flex-grow: 0`, nothing expands or scrolls until the combined content
|
|
* overflows the panel, so sections never scroll while the panel has free space
|
|
* (issue #1462). Closed sections collapse to their header height.
|
|
*
|
|
* The per-section scroll uses a NATIVE scrollbar, styled below to match
|
|
* Mantine's ScrollArea thumb (#1466). A Mantine `ScrollArea` component can't be
|
|
* used here: its viewport has no intrinsic height, which would collapse the
|
|
* panel's content-based `flex-basis` that the per-section sizing above depends
|
|
* on, so the sections would no longer size to their content. */
|
|
|
|
.disclosure-sections {
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 0;
|
|
}
|
|
|
|
.disclosure-sections > .mantine-Accordion-item[data-active] {
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 0;
|
|
}
|
|
|
|
.disclosure-sections .mantine-Accordion-control {
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.disclosure-sections
|
|
> .mantine-Accordion-item[data-active]
|
|
.mantine-Accordion-panel {
|
|
flex: 1 1 auto;
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
scrollbar-width: thin;
|
|
scrollbar-color: var(--inspector-scrollbar-thumb) transparent;
|
|
}
|
|
|
|
.disclosure-sections
|
|
> .mantine-Accordion-item[data-active]
|
|
.mantine-Accordion-panel::-webkit-scrollbar {
|
|
width: 8px;
|
|
}
|
|
|
|
.disclosure-sections
|
|
> .mantine-Accordion-item[data-active]
|
|
.mantine-Accordion-panel::-webkit-scrollbar-thumb {
|
|
background-color: var(--inspector-scrollbar-thumb);
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.disclosure-sections
|
|
> .mantine-Accordion-item[data-active]
|
|
.mantine-Accordion-panel::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
|
|
/* ── List item hover ────────────────────────────────────── */
|
|
|
|
.list-item:hover {
|
|
background-color: var(--mantine-primary-color-light);
|
|
}
|
|
|
|
[data-mantine-color-scheme="dark"] .list-item:hover {
|
|
background-color: var(--mantine-primary-color-light);
|
|
}
|
|
|
|
/* ── Filter toggle buttons (Logging / History / Network) ─────────
|
|
*
|
|
* Shared by the FilterToggleButton element, the History list's collapsible
|
|
* section headers (the `sectionHeader` Group variant), and the Resources
|
|
* disclosure accordion controls (the `disclosure` Accordion variant). The
|
|
* active (on / open) state is keyed off `aria-pressed` for the toggle buttons
|
|
* and `aria-expanded` for the accordion controls. Unlike `.list-item`,
|
|
* hover is a thin border rather than a background fill, and the active (on)
|
|
* state is the filled background. Keeping the two states distinct means
|
|
* toggling a button off while the cursor is still over it is immediately
|
|
* visible, instead of the hover background masking the removal of the active
|
|
* background (issue #1460). The 1px transparent border is reserved here (not as
|
|
* an inline style in the theme variant — inline styles outrank stylesheet
|
|
* `:hover` rules) so the hover border doesn't shift layout. */
|
|
|
|
.filter-toggle {
|
|
border: 1px solid transparent;
|
|
border-radius: var(--mantine-radius-md);
|
|
}
|
|
|
|
.filter-toggle:hover {
|
|
border-color: var(--inspector-brand-primary);
|
|
}
|
|
|
|
.filter-toggle[aria-pressed="true"],
|
|
.filter-toggle[aria-expanded="true"] {
|
|
background-color: var(--mantine-primary-color-light);
|
|
}
|
|
|
|
/* ── Select / Autocomplete dropdown / option (dark mode) ─────────
|
|
*
|
|
* Select and Autocomplete each render with their own static selector
|
|
* (`mantine-Select-*` / `mantine-Autocomplete-*`) — they share the
|
|
* Combobox primitive but don't emit a shared `mantine-Combobox-*`
|
|
* class on the dropdown root. List both so the argument-completion
|
|
* Autocompletes get the same gray surface + primary-light hover as
|
|
* the filter dropdowns. */
|
|
|
|
[data-mantine-color-scheme="dark"] .mantine-Select-dropdown,
|
|
[data-mantine-color-scheme="dark"] .mantine-Autocomplete-dropdown {
|
|
background-color: var(--mantine-color-gray-8);
|
|
}
|
|
|
|
[data-mantine-color-scheme="dark"] .mantine-Select-option:hover,
|
|
[data-mantine-color-scheme="dark"] .mantine-Autocomplete-option:hover {
|
|
background-color: var(--mantine-primary-color-light);
|
|
}
|
|
|
|
/* ── Menu dropdown / option (dark mode) ──────────────────────── */
|
|
|
|
[data-mantine-color-scheme="dark"] .mantine-Menu-dropdown {
|
|
background-color: var(--mantine-color-gray-8);
|
|
}
|
|
|
|
[data-mantine-color-scheme="dark"] .mantine-Menu-item:hover {
|
|
background-color: var(--mantine-primary-color-light);
|
|
}
|
|
|
|
/* ── Segmented control label (dark mode) ──────────────────────── */
|
|
|
|
[data-mantine-color-scheme="dark"] .mantine-SegmentedControl-indicator {
|
|
background-color: var(--mantine-primary-color-light);
|
|
}
|
|
|
|
/* ── Accordion button hover ─────────────────────────────── */
|
|
|
|
/* Default accordions (e.g. Server Settings) keep the background-fill hover.
|
|
* The Resources `disclosure` accordion opts out via `.filter-toggle` (added to
|
|
* its control slot in theme/Accordion.ts) so it gets the outline-on-hover
|
|
* treatment instead — see the `.filter-toggle` rules above. */
|
|
.mantine-Accordion-control:not(.filter-toggle):hover {
|
|
background-color: var(--mantine-primary-color-light-hover);
|
|
}
|
|
|
|
/* ── Markdown content (third-party HTML from react-markdown) ───── */
|
|
|
|
.markdown-content {
|
|
max-width: 100%;
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.markdown-content > :first-child {
|
|
margin-top: 0;
|
|
}
|
|
|
|
.markdown-content > :last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.markdown-content pre {
|
|
max-width: 100%;
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.markdown-content code {
|
|
word-break: break-word;
|
|
}
|
|
|
|
.markdown-content table {
|
|
display: block;
|
|
max-width: 100%;
|
|
overflow-x: auto;
|
|
}
|
|
|
|
.markdown-content img {
|
|
max-width: 100%;
|
|
height: auto;
|
|
}
|
|
|
|
/*
|
|
* Reorder grip on ServerCard. The grab/grabbing cursor is a draggability
|
|
* affordance that can't be expressed as a Mantine prop (and the active-press
|
|
* state is a pseudo-selector), so the whole grab-cursor unit lives here rather
|
|
* than split across the theme.
|
|
*/
|
|
.server-drag-handle {
|
|
cursor: grab;
|
|
}
|
|
|
|
.server-drag-handle:active {
|
|
cursor: grabbing;
|
|
}
|
|
|
|
/*
|
|
* Draggable vertical divider between the primary screen area and the pinned
|
|
* monitoring column (#1616). The col-resize cursor, the hover/active accent,
|
|
* and the drag-time user-select suppression are all pseudo-selector / cursor /
|
|
* cross-element concerns that can't be expressed as Mantine props, so the whole
|
|
* unit lives here rather than split across the theme.
|
|
*/
|
|
.resize-handle {
|
|
flex: 0 0 auto;
|
|
width: 6px;
|
|
cursor: col-resize;
|
|
background-color: var(--inspector-border-default);
|
|
transition: background-color 120ms ease;
|
|
touch-action: none;
|
|
}
|
|
|
|
.resize-handle:hover,
|
|
.resize-handle:focus-visible {
|
|
background-color: var(--mantine-primary-color-filled);
|
|
}
|
|
|
|
/* Suppress text selection anywhere on the page while a drag is in progress. */
|
|
body.resizing-col {
|
|
user-select: none;
|
|
cursor: col-resize;
|
|
}
|