/* ======================
   FONTS
   ====================== */

@font-face {
    font-family: "Roboto";
    src: url("/fonts/Roboto-VariableFont_wdth_wght.ttf") format("truetype");
    font-weight: 100 900;
    font-stretch: 75% 100%;
    font-display: swap;
}

@font-face {
    font-family: "Roboto";
    src: url("/fonts/Roboto-Italic-VariableFont_wdth_wght.ttf") format("truetype");
    font-style: italic;
    font-weight: 100 900;
    font-stretch: 75% 100%;
    font-display: swap;
}

@font-face {
    font-family: "Retina";
    src: url("/fonts/Retina-Book.woff2") format("woff2"),
         url("/fonts/Retina-Book.woff") format("woff");
    font-weight: 400;
    font-display: swap;
}

@font-face {
    font-family: "Retina";
    src: url("/fonts/Retina-Medium.woff2") format("woff2"),
         url("/fonts/Retina-Medium.woff") format("woff");
    font-weight: 500;
    font-display: swap;
}

@font-face {
    font-family: "Retina";
    src: url("/fonts/Retina-Bold.woff2") format("woff2"),
         url("/fonts/Retina-Bold.woff") format("woff");
    font-weight: 700 800;
    font-display: swap;
}

/* ======================
   BASE STYLES
   ====================== */

html, body {
    font-family: "Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    color: #e3e3e3;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* App-wide background. The dark base + three radial-gradient blobs of brand cyan match the
   anonymous landing page; background-attachment:fixed keeps the gradient stationary so it
   doesn't slide when content scrolls — important for the glassmorphic chrome to read
   consistently regardless of scroll position. MudBlazor's layout / main-content / paper
   containers are overridden below to be transparent (or semi-transparent + blurred) so the
   gradient shows through everywhere. */
body {
    background-color: #0a0e14;
    background-image:
        radial-gradient(circle at 20% 30%, rgba(77, 184, 232, 0.07), transparent 55%),
        radial-gradient(circle at 80% 70%, rgba(90, 210, 220, 0.05), transparent 60%),
        radial-gradient(circle at 50% 100%, rgba(77, 184, 232, 0.035), transparent 65%);
    background-attachment: fixed;
    background-size: cover;
}

/* Per-tab background tint for the org views (root OrganizationDetail + customer OrgOverview).
   A full-viewport fixed overlay, rendered only by those pages, paints the same dark base + three
   radial blobs as the body, but its blob COLORS are driven by registered custom properties so they
   can animate. (CSS can't transition a `background-image` gradient directly; transitioning a typed
   `@property <color>` that the gradient references is the way to get a smooth crossfade.) The page
   adds a modifier class as the active tab changes: Members (and every non-org view) keep the brand
   cyan; Plan shifts to a warm orange; Settings to purple. The overlay sits behind content
   (z-index:-1) and the glass papers' backdrop-filter blurs it, so the tint reads everywhere. It
   only exists while an org page is mounted, so navigating away restores the body's cyan with no
   cleanup. */
@property --tab-bg-1 { syntax: "<color>"; inherits: false; initial-value: rgba(77, 184, 232, 0.07); }
@property --tab-bg-2 { syntax: "<color>"; inherits: false; initial-value: rgba(90, 210, 220, 0.05); }
@property --tab-bg-3 { syntax: "<color>"; inherits: false; initial-value: rgba(77, 184, 232, 0.035); }

.vim-tab-bg {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-color: #0a0e14;
    background-image:
        radial-gradient(circle at 20% 30%, var(--tab-bg-1), transparent 55%),
        radial-gradient(circle at 80% 70%, var(--tab-bg-2), transparent 60%),
        radial-gradient(circle at 50% 100%, var(--tab-bg-3), transparent 65%);
    background-size: cover;
    /* Crossfade the blob colors when the tab (and thus the modifier class) changes. */
    transition: --tab-bg-1 0.8s ease, --tab-bg-2 0.8s ease, --tab-bg-3 0.8s ease;
}

/* Plan — warm golden yellow (brighter than the other tints). Listed after the base rule so it wins
   at equal specificity. */
.vim-tab-bg--plan {
    --tab-bg-1: rgba(240, 200, 50, 0.11);
    --tab-bg-2: rgba(245, 208, 60, 0.08);
    --tab-bg-3: rgba(238, 195, 48, 0.065);
}

/* Settings — bright purple. */
.vim-tab-bg--settings {
    --tab-bg-1: rgba(178, 120, 255, 0.11);
    --tab-bg-2: rgba(195, 140, 255, 0.08);
    --tab-bg-3: rgba(172, 115, 252, 0.065);
}

/* The technical-blueprint grid (dots + faint lines) used to live on body::before so it showed
   app-wide. The signed-in interface already has plenty of structure (top bar, drawer, page
   cards) and the pattern read as visual noise there, so it's been moved down onto
   .vim-anon-shell::before — see the anonymous-landing block lower in this file. Signed-in
   pages now get only the body's subtle cyan radial-gradient blobs, no grid. */

/* Let the body gradient show through MudBlazor's outer chrome. */
.mud-layout,
.mud-main-content,
.mud-drawer-container {
    background-color: transparent;
}

/* MudMainContent reserves padding-top equal to the appbar height (64px) by default so
   content doesn't slide under a fixed appbar. In this layout, .drawer-container-fixed is
   already positioned at top: 64px (sitting below the appbar), so MudMainContent inside it
   doesn't need that reservation — without this override the total top offset doubles to
   128px and the pages look like they have wasted vertical space. */
.mud-main-content {
    padding-top: 0;
}

/* ======================
   GLASSMORPHISM
   ====================== */

/* ======================
   GLASSMORPHIC CHROME
   ====================== */

/* All major surfaces — top bar, left nav, content cards, tab panels, list-view containers —
   share the same recipe: semi-transparent dark fill + backdrop-filter blur. The body gradient
   shows through the blur, producing a frosted-glass look. Alphas are tuned per surface: the
   top bar is the most solid (95%) because it has the highest contrast burden (logo + text),
   the drawer + page papers are softer (60-70%) so the gradient reads behind them. */

.glassmorphic-appbar {
    background: rgba(21, 26, 35, 0.95);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--mud-palette-divider);
}

.mud-drawer {
    background-color: rgba(21, 26, 35, 0.45);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-right: 1px solid var(--mud-palette-divider);
}

/* MudPaper backs almost every visible "card" surface in the app (page cards, tab panels,
   MudTable containers, etc.) — applying glass here gives the effect uniformly without
   per-page changes. Dialog and popover papers have their own backdrop-blur rules below
   that stack on top; the effect remains intentional rather than doubled-up. */
.mud-paper {
    background-color: rgba(21, 26, 35, 0.25);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid var(--mud-palette-divider);
}

/* MudTabs is NOT a MudPaper. With ApplyEffectsToContainer="true" the outline/rounded
   styling applies to the outer .mud-tabs, so the glass bg + blur land there. */
.mud-tabs {
    background-color: rgba(21, 26, 35, 0.45);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
}

/* MudBlazor 8.x calls the tab strip `.mud-tabs-tabbar` (NOT `.mud-tabs-toolbar` — that name
   doesn't exist and was the reason the previous override didn't take effect). The tabbar
   has a hardcoded `background-color: var(--mud-palette-surface)` which is what was painting
   the tabs container black. Forcing every internal MudTabs container transparent — and
   stripping inherited backdrop-filter — exposes the outer .mud-tabs glass cleanly. */
.mud-tabs-tabbar,
.mud-tabs-tabbar-inner,
.mud-tabs-tabbar-content,
.mud-tabs-tabbar-wrapper,
.mud-tabs-panels,
.mud-tab-panel {
    background-color: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

/* MudTable rows/cells inherit the parent paper's glass; force their own backgrounds to
   transparent so striping / hover don't paint over the blur. Hover state uses a subtle
   tint that reads as a row highlight without disrupting the glass. */
.mud-table-row,
.mud-table-cell,
.mud-table thead,
.mud-table tbody,
.mud-table th,
.mud-table tr {
    background-color: transparent;
}

.mud-table-row:hover {
    background-color: rgba(77, 184, 232, 0.06) !important;
}

/* Uniform row height across ALL list views (members, invitations, plan history, home orgs,
   root users/orgs). td height behaves as a MINIMUM in table layout, so rows whose tallest cell
   is a single line (e.g. a member with no first/last name — email only) get the same height as
   rows with two-line stacked content (name over email), chips, or inline selects; anything
   naturally taller still grows. 56px = the two-line name+email stack with breathing room,
   matching MudBlazor's non-dense row height. Headers are untouched. */
.mud-table tbody td.mud-table-cell {
    height: 56px;
}

/* Notification bell badge — Origin.BottomRight places the counter at the bottom-right of the
   icon button; this translate pulls the badge inward so the circle sits inside the bell's
   rectangle rather than spilling beyond it. */
.vim-bell-badge .mud-badge {
    transform: translate(-30%, -30%);
}

/* ======================
   CARD STYLES
   ====================== */

.vim-card {
    background-color: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-divider);
    border-radius: 12px;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.vim-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.4);
    border-color: rgba(77, 184, 232, 0.25);
}

/* Plan card (PlanFields): label-over-value meta stats + one tile per INCLUDED entitlement.
   The uppercase micro-label gives the stats a spec-sheet read; the tiles sit on the glass
   paper with a faint brand-cyan fill + border so they register as "granted" without needing
   a green check. The grid auto-fills so 1-4 tiles share the row and wrap gracefully. */
.vim-plan-meta-label {
    color: var(--mud-palette-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.6px;
}

.vim-entitlement-grid {
    display: grid;
    /* Fixed-width tracks, NOT minmax(..., 1fr): fr tracks oscillate between the minimum and
       ~2x as the viewport crosses each column-count boundary, which made card captions wrap
       and unwrap while resizing. A constant 280px fits the longest caption ("Base product
       entitlements") with room to spare; leftover row space simply stays empty. The min(...)
       lets the single column shrink below 280px on very narrow screens instead of overflowing. */
    grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 280px));
    gap: 12px;
}

/* The Expires / Auto-Renew row reuses .vim-entitlement-grid so its cells snap to the same
   column tracks as the tiles above (same container width → identical auto-fill tracks): the
   expiry occupies column 1, the auto-renew control starts flush with column 2. */
.vim-plan-renewal {
    align-items: center;
}

.vim-entitlement-tile {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 14px;
    padding: 14px 16px;
    border: 1px solid rgba(77, 184, 232, 0.18);
    border-radius: 12px;
    background-color: rgba(77, 184, 232, 0.05);
}

/* Tooltip-wrapped cards: MudTooltip inserts a .mud-tooltip-root wrapper between the grid and
   the card, which would otherwise become an unstretched inline grid item. Make the wrapper a
   block and the card fill it, so wrapped and bare cards lay out identically. */
.vim-entitlement-grid > .mud-tooltip-root {
    display: block;
}

.vim-entitlement-grid > .mud-tooltip-root .vim-entitlement-tile {
    width: 100%;
    height: 100%;
}

/* Pin the icon's box in every card variant: no flex-driven shrink/stretch, block display (kills
   the inline-SVG baseline gap), and explicit self-centering against the text column — so the
   icon sits identically whether the card is a <div>, <a>, or <button>. */
.vim-entitlement-tile .mud-icon-root {
    flex: none;
    display: block;
    align-self: center;
}

/* <button>-rendered cards (EntitlementCard with OnClick): normalize the UA button styling so
   they size and align exactly like their <a>/<div> siblings. Buttons carry their own UA rules
   that the shared .vim-entitlement-tile recipe doesn't automatically defeat everywhere (Chrome
   sets align-items: flex-start on <button>; MudBlazor's normalize adds more), so the full flex
   layout is restated here verbatim rather than inherited by faith. */
button.vim-entitlement-tile {
    appearance: none;
    -webkit-appearance: none;
    margin: 0;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 14px;
    line-height: inherit;
}

/* Actionable tile (the Offline-license download / root's New Plan): same shape as its
   entitlement siblings, but filled with a solid theme color + white icon/text so it reads as a
   button among the static cards. Rendered as an <a> or a <button>, so reset both elements'
   default styling; hover darkens like a filled MudButton. */
.vim-entitlement-tile--action {
    background-color: var(--mud-palette-primary);
    border: 1px solid var(--mud-palette-primary);
    color: #ffffff;
    font: inherit;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

/* White icon + text on the blue fill. The detail line's .mud-text-secondary would otherwise
   paint theme-gray; soften to translucent white instead. */
.vim-entitlement-tile--action .mud-icon-root,
.vim-entitlement-tile--action .mud-typography {
    color: #ffffff;
}

.vim-entitlement-tile--action .mud-typography.mud-text-secondary {
    color: rgba(255, 255, 255, 0.78);
}

.vim-entitlement-tile--action:hover {
    background-color: var(--mud-palette-primary-darken);
    border-color: var(--mud-palette-primary-darken);
}

.vim-entitlement-tile--action:focus-visible {
    outline: 2px solid #ffffff;
    outline-offset: 2px;
}

/* New Plan (root only): the theme's secondary green instead of primary blue. Listed after the
   base --action rule so the green wins at equal specificity. */
.vim-entitlement-tile--create {
    background-color: var(--mud-palette-secondary);
    border-color: var(--mud-palette-secondary);
}

.vim-entitlement-tile--create:hover:not(:disabled) {
    background-color: var(--mud-palette-secondary-darken);
    border-color: var(--mud-palette-secondary-darken);
}

.vim-entitlement-tile--create:disabled {
    opacity: 0.55;
    cursor: default;
}

/* Empty-state placeholder ("this plan includes no product entitlements"): muted gray with a
   dashed border so it reads as an absence, not a grant. */
.vim-entitlement-tile--empty {
    border: 1px dashed var(--mud-palette-divider);
    background-color: rgba(255, 255, 255, 0.02);
    color: var(--mud-palette-text-disabled);
}

.vim-entitlement-tile--empty .mud-typography,
.vim-entitlement-tile--empty .mud-icon-root {
    color: var(--mud-palette-text-disabled);
}

/* Auto-renew ON/OFF toggle: tighter than MudBlazor's Size.Small so it reads as a status pill
   beside the Expires stat. Fixed width so the button doesn't shift when toggling ON ↔ OFF. */
.vim-autorenew.mud-button-root {
    width: 52px;
    min-width: 52px;
    padding: 2px 0;
    font-size: 0.72rem;
}

/* ======================
   LOADING SKELETONS
   ====================== */

/* Wave-animated placeholders (TableSkeleton / OrgViewSkeleton / DetailFormSkeleton) shown while
   a view loads. MudBlazor's defaults are tuned for opaque surfaces; on the glass theme the fill
   is dropped to a faint white and the wave highlight kept gentle so it reads as a subtle
   gradient sweep, not a shimmer. */
.mud-skeleton {
    background-color: rgba(255, 255, 255, 0.05);
}

.mud-skeleton-wave::after {
    background: linear-gradient(90deg,
        transparent,
        rgba(255, 255, 255, 0.07),
        transparent);
}

/* Shape variants matching the surfaces they stand in for: cards/chips use the 12px card radius,
   table rows and form fields the squarer 4px. */
.vim-skeleton-tile {
    border-radius: 12px;
}

.vim-skeleton-chip {
    border-radius: 12px;
}

.vim-skeleton-bar {
    border-radius: 4px;
}

/* ======================
   MUDBLAZOR OVERRIDES
   ====================== */

/* Top-anchored snackbars/toasts must clear the fixed 64px glassmorphic app bar. MudBlazor anchors
   them at top:24px by default, which slides them under the bar; push the anchor below it (64px +
   16px gap). Covers all three top positions so it holds regardless of the configured corner. */
.mud-snackbar-location-top-left,
.mud-snackbar-location-top-center,
.mud-snackbar-location-top-right {
    top: 80px;
}

.mud-overlay-dialog {
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}

/* MudBlazor gives the dialog actions only 8px of padding, so the buttons hug the bottom/right edges
   while the title uses 16px 24px. Match the actions' right + bottom to the title (24px / 16px) for
   consistent dialog margins; keep a smaller top so the buttons don't drift too far from the content.
   Selector mirrors MudBlazor's own `.mud-dialog .mud-dialog-actions` (specificity 0,2,0) so this wins
   the tie by source order (app.css loads after MudBlazor) — no !important needed. */
.mud-dialog .mud-dialog-actions {
    padding: 8px 24px 16px 24px;
}

.mud-popover .mud-list {
    background-color: var(--mud-palette-surface);
}

.mud-popover.mud-paper {
    border: 1px solid var(--mud-palette-divider);
}

.mud-tab-panel .mud-paper {
    border-top-left-radius: 0;
    border-top-right-radius: 0;
}

/* Tooltips use the squarer 4px corner (matching buttons/inputs) instead of MudBlazor's default
   border radius. Single-class selector, same specificity as MudBlazor's `.mud-tooltip`, so it wins
   by source order (app.css loads after MudBlazor). */
.mud-tooltip {
    border-radius: 4px;
}

/* Invite-member dialog: sized so Email + Role + the VIM Flex group + gaps + dialog
   padding all fit on ONE row at full width. The callers pass MaxWidth.Small + FullWidth; this two-class selector
   outweighs MudBlazor's .mud-dialog-width-sm 600px cap. On smaller viewports the dialog
   shrinks with the screen and the row wraps in order (Flex first, then Role). */
.mud-dialog.vim-invite-dialog {
    max-width: 720px;
}

/* Email | Role | VIM Flex on one wrapping row. The email field absorbs leftover width; its
   flex-basis keeps it comfortably wide for real addresses. align-items: flex-end lines
   the dropdowns' bottoms up with the email input's bottom, since the outlined field is taller
   than the caption + select stacks beside it. */
.vim-invite-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px 16px;
}

.vim-invite-row .vim-invite-email {
    flex: 1 1 300px;
    min-width: 0;
}

/* Muted neutral-gray chip (e.g. a low-emphasis "Free" tier badge). The MudBlazor Color enum has no
   neutral gray, so this uses the theme's disabled tones: gray label text on a faint gray fill. Apply
   Class="vim-chip-muted" — the chip's Color then doesn't matter, since this two-class selector wins
   over MudBlazor's `.mud-chip-text.mud-chip-color-*` rules at equal specificity by source order. */
.vim-chip-muted.mud-chip {
    color: var(--mud-palette-text-disabled);
    background-color: var(--mud-palette-action-disabled-background);
}

::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: var(--mud-palette-background);
}

::-webkit-scrollbar-thumb {
    background: var(--mud-palette-divider);
    border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
    background: #2a3040;
}

.mud-table-cell {
    vertical-align: middle;
}

.mud-typography-h1,
.mud-typography-h2,
.mud-typography-h3,
.mud-typography-h4,
.mud-typography-h5,
.mud-typography-h6 {
    color: #e3e3e3;
}

/* Consistent vertical breathing room for page-level titles (e.g. "Home", "Pending
   Invitations", "Users", "Organizations"). Applied via an explicit class rather than a
   blanket .mud-typography-h4 rule so card titles and section headings inside the org detail
   pages aren't unintentionally pushed apart. */
.vim-page-title {
    margin-top: 24px;
    margin-bottom: 24px;
}

/* ======================
   FORM CONTROLS (squarer corners)
   ====================== */

/* The theme's DefaultBorderRadius is 12px for cards/papers — keep that.
   Buttons and form fields look more "square" at 4px per the UX pass. */
.mud-button-root,
.mud-icon-button {
    border-radius: 4px !important;
}

.mud-input-control .mud-input.mud-input-outlined,
.mud-input-control .mud-input.mud-input-filled,
.mud-input-slot {
    border-radius: 4px !important;
}

.mud-input-outlined-border {
    border-radius: 4px !important;
}

/* Base style for inline row dropdowns (e.g. the member list). A subtle FILLED box with 4px corners
   and centered value, instead of an outline or underline — "change the fill color, not the border"
   per the UX pass. The selects use Variant.Text + Underline="false" so MudBlazor draws no border/
   underline of its own; this class supplies the fill + shape. Reusable: add `vim-select` to any
   MudSelect that should adopt this look. */
.vim-select .mud-input {
    background-color: rgba(255, 255, 255, 0.06);
    border-radius: 4px;
    padding-left: 12px;
    padding-right: 6px;
    min-height: 32px;
    align-items: center; /* center the value text + arrow within the box */
}

/* Members table is width:auto (content-sized), so inter-column spacing is defined by cell padding.
   8px each side → a minimum of 16px between adjacent columns. */
.vim-members-table .mud-table-cell {
    padding-left: 8px;
    padding-right: 8px;
}

/* Variant.Text reserves top padding for a (here absent) floating label, which pushes the value
   toward the bottom; zero the slot's vertical padding/margin so the value sits centered. */
.vim-select .mud-input-slot {
    margin-top: 0 !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

/* Assigned Flex Pro seat: a primary-blue fill with white value text + dropdown arrow, signalling the
   active state against the neutral-filled siblings. Built on top of .vim-select (same shape/size), so
   the select carries both classes. Listed AFTER .vim-select so the blue background wins at equal
   specificity. */
.vim-flex-seat-assigned .mud-input {
    background-color: var(--mud-palette-primary);
}
.vim-flex-seat-assigned .mud-input,
.vim-flex-seat-assigned .mud-input-slot,
.vim-flex-seat-assigned .mud-select-input,
.vim-flex-seat-assigned .mud-input-adornment,
.vim-flex-seat-assigned .mud-input .mud-icon-root,
.vim-flex-seat-assigned .mud-input svg {
    color: #ffffff !important;
    fill: #ffffff !important;
}

/* Pending (saving) state for a row select while ITS own async change is in flight: a neutral gray
   fill with muted text/arrow, so just that control reads as "saving…" without affecting siblings.
   Listed AFTER the assigned rule, and the two are mutually exclusive on the element (the class helper
   returns one or the other), so this defines the look on its own. */
.vim-select-pending .mud-input {
    background-color: var(--mud-palette-action-disabled-background);
}
.vim-select-pending .mud-input,
.vim-select-pending .mud-input-slot,
.vim-select-pending .mud-select-input,
.vim-select-pending .mud-input-adornment,
.vim-select-pending .mud-input .mud-icon-root,
.vim-select-pending .mud-input svg {
    color: var(--mud-palette-text-disabled) !important;
    fill: var(--mud-palette-text-disabled) !important;
}

/* Active | Pending segmented toggle (Members tab header). A custom control built from two plain
   buttons in a filled pill — not MudToggleGroup, whose internal delimiter/border styling fought our
   overrides. Shares the neutral filled look of .vim-select above (subtle white fill, 4px corners),
   NOT a primary-blue selected state. The container clips to 4px so the OUTER corners are rounded and
   the seam between the two segments is square; no per-segment radius needed. */
.vim-segmented {
    display: inline-flex;
    border-radius: 4px;
    overflow: hidden;
    background-color: rgba(255, 255, 255, 0.06);
}
.vim-segmented .vim-seg {
    border: none;
    background: transparent;
    color: var(--mud-palette-text-secondary);
    /* Inherit the surrounding MudBlazor typography (family/size/weight/line-height/letter-spacing)
       so the labels match the default text used elsewhere — a bare <button> would otherwise use the
       browser's default font metrics. */
    font: inherit;
    padding: 6px 18px;        /* breathing room so labels aren't tight against the edges */
    cursor: pointer;
}
.vim-segmented .vim-seg:hover {
    color: var(--mud-palette-text-primary);
}
/* Selected segment: a slightly brighter neutral fill + brighter text (no primary blue). */
.vim-segmented .vim-seg.vim-seg-on {
    background-color: rgba(255, 255, 255, 0.14);
    color: var(--mud-palette-text-primary);
}

/* MudSelect's popover-anchor input shares the input class above; the dropdown
   list rendered below it inherits the 12px paper radius — left alone on purpose,
   only the clickable form control itself needs the squarer corner. */

/* ======================
   POINTER ON CLICKABLE ROWS
   ====================== */

/* Scoped to tables that opt in via .vim-clickable-rows so we don't paint the
   pointer cursor onto rows that contain inline edit controls (e.g. the
   Members tab's role dropdown) — a misleading affordance there since the row
   itself isn't navigable. Tables that bind OnRowClick should add this class
   on the MudTable wrapper. */
.vim-clickable-rows tbody tr.mud-table-row {
    cursor: pointer;
}

/* ======================
   TOP-BAR LOGO BUTTON
   ====================== */

/* The logo is a navigation control to /, but we don't want MudBlazor's
   circular ripple/highlight around it — it should read as a brand mark, not
   a button. Wrapping the <img> in a plain <a> with this class gives it the
   click target without the visual chrome.

   display: flex (not inline-flex) so the link itself becomes a flex item of
   the MudAppBar's toolbar and the toolbar's align-items: center vertically
   centers the IMG inside the link. Padding is horizontal-only — vertical
   padding produced an off-center look in the signed-in top bar where the
   appbar height is driven by taller siblings (avatar, notifications). */
.vim-logo-link {
    display: flex;
    align-items: center;
    text-decoration: none;
    color: inherit;
    padding: 0 8px;
    border-radius: 0;
    transition: opacity 0.15s ease;
}

.vim-logo-link img {
    /* display: block removes the inline-baseline gap that <img> inherits from
       its default vertical-align: baseline — the gap was the source of the
       perceived vertical offset relative to the avatar and notifications icon
       on the right side of the bar. */
    display: block;
    height: 28px;
    width: auto;
    /* The wordmark PNG has extra bottom whitespace below the glyph baseline,
       so even when the image bounding box is vertically centered the visible
       text appears to sit too low. translateY pulls the pixels up by 4px to
       match the baseline of the OrgSwitcher button text to its right. Using
       transform (not margin) so the link's hit area / layout stays put. */
    transform: translateY(-4px);
}

.vim-logo-link:hover {
    opacity: 0.85;
    background: transparent;
}

.vim-logo-link:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
}

/* ======================
   ANONYMOUS LANDING (full-viewport, no chrome)
   ====================== */

/* MainLayout swaps to a chromeless mode for unauthenticated users so the
   landing page can fill the viewport without competing with a top bar or
   nav drawer. Background is inherited from body — no need to duplicate the
   gradient stack here. box-sizing accounts for padding inside the 100vh
   container so we don't trigger a needless vertical scrollbar. */
.vim-anon-shell {
    position: relative;
    height: 100vh;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 32px;
}

/* Technical-blueprint grid: 40px tile with a brand-cyan dot at each intersection and faint
   horizontal + vertical lines connecting them. Scoped to the anonymous landing only — see the
   commented-out body::before earlier in this file for the rationale (the pattern read as
   visual noise once the user was signed in). The mask emphasizes the upper-center but never
   fully hides the pattern (~40% opacity in the corners) so the grid stays softly visible
   across the whole landing viewport. Pointer-events:none keeps it click-through; the card
   above is painted later in the DOM order so it sits on top without an explicit z-index. */
.vim-anon-shell::before {
    content: '';
    position: absolute;
    inset: 0;
    background-image:
        radial-gradient(circle, rgba(77, 184, 232, 0.28) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(77, 184, 232, 0.08) 1px, transparent 1px),
        linear-gradient(to right,  rgba(77, 184, 232, 0.08) 1px, transparent 1px);
    background-size: 40px 40px;
    pointer-events: none;
    mask-image: radial-gradient(ellipse 100% 100% at 50% 30%, black 0%, rgba(0, 0, 0, 0.4) 100%);
    -webkit-mask-image: radial-gradient(ellipse 100% 100% at 50% 30%, black 0%, rgba(0, 0, 0, 0.4) 100%);
}

/* Outer card: 2:1 rectangle. Two inner panes (left + right) fill the interior, so the card
   itself only contributes the border specular and the rounded outline. overflow:hidden clips
   the panes' corners to the card's radius. */
.vim-anon-card {
    position: relative;
    display: flex;
    flex-direction: row;
    width: 100%;
    max-width: 1100px;
    aspect-ratio: 2 / 1;
    border-radius: 12px;
    overflow: hidden;
}

/* Border-only gradient via a masked pseudo-element. The ::before sits at inset:0 with a 1px
   padding and a linear-gradient background; the mask-composite trick subtracts the inner
   content-box, leaving only the 1px padding ring visible — that ring is the "border". This
   replaces the earlier background-clip:border-box approach which painted the gradient under
   the whole card (relying on the inner panes to cover everything but the 1px edge). With the
   mask, the gradient is genuinely only on the thin border. */
.vim-anon-card::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    background: linear-gradient(110deg,
        rgba(77, 184, 232, 0.04) 0%,
        rgba(77, 184, 232, 0.18) 50%,
        rgba(77, 184, 232, 0.04) 100%);
    -webkit-mask:
        linear-gradient(#fff 0 0) content-box,
        linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
    z-index: 2;
}

/* LEFT — transparent pane with backdrop blur. No fill of its own; backdrop-filter blurs the
   body gradient sitting behind the card, producing a frosted look that contrasts with the
   matte right pane. */
.vim-anon-card-left {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
}

.vim-anon-card-left img {
    width: 100%;
    max-width: 280px;
    height: auto;
    display: block;
}

/* RIGHT — matte CTA pane. Flat near-opaque fill, no blur, so it reads as a calm surface
   anchoring the title + caption + button against the more atmospheric left half. Left-justified
   text and items so the layout reads as a labelled column, not a centered hero. Generous gap
   and padding so the title / caption / buttons aren't visually jammed together. */
.vim-anon-card-right {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    gap: 24px;
    padding: 48px 56px;
    background-color: rgba(15, 20, 28, 0.92);
    text-align: left;
}

.vim-anon-caption {
    color: var(--mud-palette-text-secondary);
    line-height: 1.55;
}

/* Side-format mobile logo is hidden by default — the wide layout has the top/bottom logo in
   the left pane so a second logo here would be redundant. The narrow breakpoint below flips
   the visibility: left pane disappears, this logo appears above the title. */
.vim-anon-mobile-logo {
    display: none;
    max-width: 220px;
    height: auto;
}

/* Narrow viewport: collapse the two-pane card into a single right-pane column with a side-
   format logo stacked above the title. Breakpoint at 720px — below this the 2:1 aspect-
   ratio card would squeeze the right pane below ~360px content width, where "Customer
   Portal" wraps and the buttons feel cramped. Releasing the aspect-ratio lets the card grow
   vertically to fit its column of content. */
@media (max-width: 720px) {
    .vim-anon-card {
        aspect-ratio: auto;
        max-width: 480px;
    }

    .vim-anon-card-left {
        display: none;
    }

    .vim-anon-card-right {
        padding: 40px 32px;
    }

    .vim-anon-mobile-logo {
        display: block;
    }
}

/* ======================
   CHOOSE-PLAN CARDS
   ====================== */

/* The two "Choose your Plan" cards (VIM Flex Pro / VIM Enterprise). width:100% so each fills its
   half-width MudGrid column (equal widths — without it the card shrink-wraps its content and the two
   end up different widths with dead space beside the narrower one). Flex column + height:100% so both
   stretch to the taller card's height — that's what makes them equal-size. The benefit list
   (.plan-card-benefits) grows to fill, bottom-aligning the action button across both. */
.plan-card {
    --card-dark: var(--mud-palette-surface);
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    padding: 24px;
    border-radius: 12px;
}

/* Green checkmark glyph prefixing each benefit (literal ✓, not an icon). */
.plan-check {
    color: #3fb950;
    font-weight: 700;
    line-height: 1.4;
}

/* VIM Flex Pro — primary brand (blue) border. */
.plan-card-flex {
    border: 1px solid var(--mud-palette-primary);
}

/* VIM Enterprise — gold conic-gradient outline. The padding-box layer fills the interior with the card
   surface color while the border-box layer paints the gradient, so the gradient shows ONLY on the 2px
   transparent border. */
.plan-card-enterprise {
    border: 2px solid transparent;
    background:
        linear-gradient(var(--card-dark), var(--card-dark)) padding-box,
        conic-gradient(from -15deg, #ffd32a, #ff9f43, #ffd32a) border-box;
}

/* Grows to fill so the action button after it bottom-aligns regardless of how many benefits each card lists. */
.plan-card-benefits {
    flex: 1 1 auto;
}

.plan-card-tagline {
    font-style: italic;
    color: var(--mud-palette-primary);
}

.plan-card-enterprise .plan-card-tagline {
    color: #ffd32a;
}

/* Gold (outlined) Enterprise "Contact Us" action — the same #d4a017 as the card's gradient accent. */
.plan-card-enterprise-btn.mud-button-root {
    color: #d4a017;
    border-color: rgba(212, 160, 23, 0.5);
}

.plan-card-enterprise-btn.mud-button-root:hover {
    border-color: #d4a017;
    background-color: rgba(212, 160, 23, 0.08);
}

/* ======================
   FLEX PRO SELF-SERVE — CONFIGURE STEP
   ====================== */

/* +/- seat stepper: the count sits between two icon buttons, tabular figures so it doesn't jitter. */
.seat-stepper {
    display: flex;
    align-items: center;
    gap: 20px;
}

.seat-stepper .seat-count {
    min-width: 72px;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

/* "Let's Chat!" replaces the price once seats exceed the self-serve cap — gold, to match the
   Contact Us CTA. */
.lets-chat {
    font-weight: 700;
    color: #d4a017;
}

/* The price/"Let's Chat!" panel and the trial-message slot below it reserve fixed vertical space so the
   dialog DOESN'T resize when the content swaps (price ↔ "Let's Chat!", or the trial alert ↔ the
   single-seat hint ↔ nothing). Content is vertically centered within the reserved space. */
/* min-height must exceed the NATURAL height of the tallest state (the price layout: overline + amount +
   per-seat caption ≈ 144px) so BOTH the price and "Let's Chat!" states clamp to the same height — else
   the shorter "Let's Chat!" panel shrinks the dialog and shifts it (it's vertically centred). */
.total-panel.mud-paper {
    min-height: 148px;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.trial-slot {
    min-height: 76px;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

/* When showing "Let's Chat!", the panel border uses the same gold conic-gradient as the VIM Enterprise
   card (padding-box fill + border-box gradient → gradient only on the 2px border). The two-class
   selector outranks MudBlazor's .mud-paper-outlined border. */
.lets-chat-panel.mud-paper {
    border: 2px solid transparent;
    background:
        linear-gradient(var(--mud-palette-surface), var(--mud-palette-surface)) padding-box,
        conic-gradient(from -15deg, #ffd32a, #ff9f43, #ffd32a) border-box;
}

/* Filled-gold "Contact Us" CTA (seats over the cap) — same #d4a017 as the Enterprise card's action,
   with white text for contrast on the bright fill. */
.contact-us-btn.mud-button-root {
    background-color: #d4a017;
    color: #fff;
}

.contact-us-btn.mud-button-root:hover {
    background-color: #b8860b;
}

/* Subtle pulsing glow on the empty-home hero "Create Organization" CTA only (scoped via the
   vim-cta-glow class added in EmptyHome.razor — not the regular HomeHeader button). Uses the VIM
   action blue (#4db8e8). The animation's box-shadow outranks MudBlazor's filled-button shadow;
   honours prefers-reduced-motion. */
@keyframes vim-cta-glow-pulse {
    0%, 100% { box-shadow: 0 0 10px 1px rgba(77, 184, 232, 0.30); }
    50%      { box-shadow: 0 0 20px 5px rgba(77, 184, 232, 0.58); }
}

.vim-cta-glow.mud-button-root {
    animation: vim-cta-glow-pulse 3.6s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
    .vim-cta-glow.mud-button-root {
        animation: none;
    }
}
