/* Setup progress banner (SetupProgressBanner.razor).
   Implements design "2b — A persistent setup banner across the record" from the
   Client Setup Onboarding design doc: a full-width info strip under the page header
   with a rocket, a milestone chip journey (done / current / todo) and a bottom
   progress bar, plus the staggered entrance animations from the mock.

   Colours are held in banner-scoped custom properties so the strip matches the
   DEFEX design tokens exactly and still flips for dark mode. */

.setup-banner {
    /* Design tokens (light) */
    --sb-info-bg: #EFF6FF;
    --sb-info-border: #B8D5F9;
    --sb-accent: #155DFC;
    --sb-primary: #0F172B;
    --sb-fg-2: #4B5563;
    --sb-fg-3: #6B7280;
    --sb-border-strong: #C5CCD9;
    --sb-done-bg: #E8F5ED;
    --sb-done-border: #BFE0CB;
    --sb-done-fg: #005A24;
    --sb-current-dot: #8FB6FF;
    --sb-glow: rgba(21, 93, 252, 0.24);
    --sb-track: rgba(21, 93, 252, 0.14);

    position: relative;
    /* Lift the whole banner's stacking context above the following <MudTabs> so the hover
       popover (which drops down into the tab area) is not painted over by the tab content. */
    z-index: 30;
    background: var(--sb-info-bg);
    border-bottom: 1px solid var(--sb-info-border);
    border-top: 1px solid var(--mud-palette-table-lines);
    animation: sb-bnr-in 0.45s var(--ease-out, cubic-bezier(0, 0, 0.2, 1)) both;
}

.defex-theme-dark .setup-banner,
.mud-theme-dark .setup-banner {
    --sb-info-bg: rgba(0, 115, 234, 0.12);
    --sb-info-border: #3A4A5C;
    --sb-accent: #0073EA;
    --sb-primary: #0073EA;
    --sb-fg-2: rgba(255, 255, 255, 0.80);
    --sb-fg-3: rgba(255, 255, 255, 0.60);
    --sb-border-strong: rgba(255, 255, 255, 0.26);
    --sb-current-dot: #8FB6FF;
    --sb-track: rgba(0, 115, 234, 0.20);
}

/* Exit: slide up + collapse the row to nothing (grid 1fr -> 0fr gives a smooth
   height collapse without needing to measure), then the host removes it. */
.setup-banner--exiting {
    display: grid;
    grid-template-rows: 1fr;
    border-color: transparent;
    pointer-events: none;
    animation: sb-bnr-out 0.34s var(--ease-in, cubic-bezier(0.4, 0, 1, 1)) forwards;
}

    .setup-banner--exiting .setup-banner__inner {
        overflow: hidden;
    }

@keyframes sb-bnr-out {
    to {
        grid-template-rows: 0fr;
        opacity: 0;
        transform: translateY(-8px);
    }
}

.setup-banner__row {
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 14px 24px;
}

.setup-banner__icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    color: var(--sb-accent);
}

    .setup-banner__icon .mud-icon-root {
        font-size: 26px;
    }

.setup-banner__text {
    flex: 1 1 auto;
    min-width: 0;
}

.setup-banner__title {
    font: 600 14px var(--font-base, inherit);
    color: var(--sb-primary);
    margin-bottom: 2px;
}

.setup-banner__subtitle {
    font: 400 12.5px var(--font-base, inherit);
    color: var(--sb-fg-2);
}

.setup-banner__steps {
    flex: 0 1 auto;
    display: flex;
    align-items: center;
    gap: 7px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.setup-banner__chevron {
    color: var(--sb-info-border);
    font-size: 15px !important;
    animation: sb-step-in 0.35s var(--ease-out, cubic-bezier(0, 0, 0.2, 1)) var(--sb-d, 0s) both;
}

/* Chips are <button>s — strip native chrome, keep the pill shape from the mock. */
.setup-banner__pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font: 500 11.5px var(--font-base, inherit);
    padding: 4px 10px;
    border-radius: 999px;
    white-space: nowrap;
    border: 1px solid transparent;
    background: transparent;
    cursor: pointer;
    animation: sb-step-in 0.4s var(--ease-out, cubic-bezier(0, 0, 0.2, 1)) var(--sb-d, 0s) both;
}

    .setup-banner__pill:disabled {
        cursor: default;
    }

.setup-banner__pill--done {
    background: var(--sb-done-bg);
    border-color: var(--sb-done-border);
    color: var(--sb-done-fg);
}

.setup-banner__pill--current {
    background: var(--sb-primary);
    color: #fff;
    animation: sb-step-in 0.4s var(--ease-out, cubic-bezier(0, 0, 0.2, 1)) var(--sb-d, 0s) both,
               sb-chip-pulse 2.4s var(--ease-standard, cubic-bezier(0.4, 0, 0.2, 1)) calc(var(--sb-d, 0s) + 1.25s) infinite;
}

.setup-banner__pill--todo {
    background: var(--color-surface, #fff);
    border: 1px dashed var(--sb-border-strong);
    color: var(--sb-fg-3);
}

.setup-banner__check {
    font-size: 14px !important;
    animation: sb-check-pop 0.42s var(--ease-out, cubic-bezier(0, 0, 0.2, 1)) calc(var(--sb-d, 0s) + 0.3s) both;
}

.setup-banner__radio {
    font-size: 14px !important;
}

.setup-banner__dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--sb-current-dot);
    display: inline-block;
    animation: sb-dot-pulse 1.6s var(--ease-standard, cubic-bezier(0.4, 0, 0.2, 1)) calc(var(--sb-d, 0s) + 1.25s) infinite;
}

.setup-banner__close {
    flex: 0 0 auto;
    color: var(--sb-fg-3);
}

/* Hover popover — explains the step and where clicking will take you. GSAP animates the
   card (.setup-banner__pop); the anchor owns the centering so the tween's transform can't
   fight it. The anchor's padding-bottom bridges the gap to the chip so the pointer stays
   within the step while moving up onto the card. */
.setup-banner__step {
    position: relative;
    display: inline-flex;
}

.setup-banner__pop-anchor {
    position: absolute;
    left: 50%;
    top: 100%;
    transform: translateX(-50%);
    padding-top: 9px;
    z-index: 50;
}

.setup-banner__pop {
    visibility: hidden;
    box-sizing: border-box;
    width: 230px;
    max-width: calc(100vw - 32px);
    background: var(--color-surface, #fff);
    border: 1px solid var(--sb-info-border);
    border-radius: 10px;
    box-shadow: 0 12px 30px rgba(15, 23, 43, 0.18);
    padding: 12px 14px;
    text-align: left;
    white-space: normal;
    cursor: default;
}

.setup-banner__pop-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 6px;
}

.setup-banner__pop-badge {
    flex: 0 0 auto;
    font: 600 9px var(--font-base, inherit);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 2px 6px;
    border-radius: 4px;
}

.setup-banner__pop-badge--done {
    background: var(--sb-done-bg);
    color: var(--sb-done-fg);
}

.setup-banner__pop-badge--current {
    background: var(--sb-primary);
    color: #fff;
}

.setup-banner__pop-badge--todo {
    background: rgba(21, 93, 252, 0.10);
    color: var(--sb-accent);
}

.setup-banner__pop-title {
    font: 600 13px var(--font-base, inherit);
    color: var(--sb-primary);
}

.setup-banner__pop-desc {
    font: 400 12px/1.5 var(--font-base, inherit);
    color: var(--sb-fg-2);
}

.setup-banner__pop-dest {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--color-border, #e6e6e6);
    font: 500 11.5px var(--font-base, inherit);
    color: var(--sb-accent);
}

    .setup-banner__pop-dest-icon {
        font-size: 14px !important;
    }

.setup-banner__pop-arrow {
    position: absolute;
    left: 50%;
    top: -5px;
    width: 10px;
    height: 10px;
    background: var(--color-surface, #fff);
    border-left: 1px solid var(--sb-info-border);
    border-top: 1px solid var(--sb-info-border);
    transform: translateX(-50%) rotate(45deg);
}

/* Bottom progress bar — track + fill that grows to the completed fraction. */
.setup-banner__bar {
    height: 3px;
    background: var(--sb-track);
}

.setup-banner__bar-fill {
    height: 100%;
    width: var(--sb-pct, 0%);
    background: var(--sb-accent);
    animation: sb-bar-fill 1.1s var(--ease-out, cubic-bezier(0, 0, 0.2, 1)) 0.35s both;
}

@keyframes sb-bnr-in {
    from { opacity: 0; transform: translateY(-10px); }
    to   { opacity: 1; transform: none; }
}

@keyframes sb-step-in {
    from { opacity: 0; transform: translateY(7px) scale(0.95); }
    to   { opacity: 1; transform: none; }
}

@keyframes sb-check-pop {
    0%   { transform: scale(0); }
    62%  { transform: scale(1.18); }
    100% { transform: scale(1); }
}

@keyframes sb-chip-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(21, 93, 252, 0); }
    50%      { box-shadow: 0 0 0 4px var(--sb-glow); }
}

@keyframes sb-dot-pulse {
    0%, 100% { opacity: 0.35; transform: scale(0.7); }
    50%      { opacity: 1; transform: scale(1); }
}

@keyframes sb-bar-fill {
    from { width: 0; }
    to   { width: var(--sb-pct, 0%); }
}

/* Stack the chip row under the text on narrow viewports. */
@media (max-width: 960px) {
    .setup-banner__row {
        flex-wrap: wrap;
    }

    .setup-banner__steps {
        flex-basis: 100%;
        justify-content: flex-start;
    }
}

@media (prefers-reduced-motion: reduce) {
    .setup-banner,
    .setup-banner__pill,
    .setup-banner__chevron,
    .setup-banner__check,
    .setup-banner__dot,
    .setup-banner__bar-fill {
        animation: none !important;
    }
}

/* ---------------------------------------------------------------------------
   SetupHeaderChips.razor — design 3b. The journey compressed into the page
   header: no rocket, no connectors, no progress bar. Each actionable pill is a
   single hit target that opens a menu (navigate / mark complete / not
   applicable), so the caret is part of the pill rather than a second control.
   Colours are the mock's, held as tokens so dark mode can swap them.
   --------------------------------------------------------------------------- */

/* PageHeader's SetupContent slot. Shrinks (and eventually hides) before the
   actions block, which is flex-shrink-0. The rule separates the strip from
   ACTIONS, as drawn. */
/* The vertical padding + matching negative margin are load-bearing: overflow:hidden clips at
   the padding box, and the current pill's attention glow is a 4px box-shadow ring that sits
   OUTSIDE the pill's border box. Without the padding the ring is clipped top and bottom and
   renders as two side arcs — reading as a pill whose border is missing its top and bottom.
   The negative margin cancels the padding so layout is unchanged. */
/* flex-basis 0 with grow is load-bearing, not styling: it makes the slot's width a function of
   the TITLE and the actions only, never of the chips inside it. With `flex: 0 1 auto` the box
   was content-sized, so every pill the fitter dropped shrank the box it had just measured — the
   fitter oscillated between compact and not instead of converging. The MudSpacer before us is
   neutralised (utilities.css) so this slot takes the whole gap rather than half of it, and the
   chips hug the actions via justify-content below.
   min-width keeps the counter + the "+N" pill whole at any title length: below that the title
   truncates instead, which is the one case where the strip has nothing useful left to give. */
.page-header__setup {
    display: flex;
    align-items: center;
    min-width: 132px;
    overflow: hidden;
    flex: 1 1 0;
    padding: 8px 12px 8px 0;
    margin: -4px 12px -8px 0;
    position: relative;
}

    /* The rule separating the strip from ACTIONS is a pseudo-element rather than a border so
       it keeps its original height instead of stretching with the padding above. */
    .page-header__setup::after {
        content: "";
        position: absolute;
        top: 8px;
        bottom: 8px;
        right: 0;
        width: 1px;
        background: var(--sc-rule, #DEE2ED);
    }

.defex-theme-dark .page-header__setup,
.mud-theme-dark .page-header__setup {
    --sc-rule: rgba(255, 255, 255, 0.16);
}

.setup-chips {
    /* Design tokens (light) — values straight from the 3b mock. */
    --sc-accent: #155DFC;
    --sc-accent-bg: #EFF6FF;
    --sc-accent-fg: #1E55C4;
    --sc-muted: #6B7280;
    --sc-body: #4B5563;
    --sc-todo-bg: #F4F6FA;
    --sc-border: #DEE2ED;
    --sc-border-strong: #C5CCD9;
    --sc-done-bg: #E8F5ED;
    --sc-done-fg: #005A24;
    --sc-done-icon: #007E33;
    --sb-glow: rgba(21, 93, 252, 0.20);

    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
    flex: 1 1 0;
    min-width: 0;
    overflow: hidden;
    /* Same reason as .page-header__setup: leave room inside the clip box for the current
       pill's glow ring, then cancel it so nothing moves. */
    padding: 8px 0;
    margin: -8px 0;
}

.defex-theme-dark .setup-chips,
.mud-theme-dark .setup-chips {
    --sc-accent: #0073EA;
    --sc-accent-bg: rgba(0, 115, 234, 0.16);
    --sc-accent-fg: #8FB6FF;
    --sc-muted: rgba(255, 255, 255, 0.60);
    --sc-body: rgba(255, 255, 255, 0.80);
    --sc-todo-bg: rgba(255, 255, 255, 0.06);
    --sc-border: rgba(255, 255, 255, 0.16);
    --sc-border-strong: rgba(255, 255, 255, 0.28);
    --sc-done-bg: rgba(0, 138, 60, 0.18);
    --sc-done-fg: #7BD69F;
    --sc-done-icon: #57C88A;
    --sb-glow: rgba(0, 115, 234, 0.28);
}

.setup-chips__count {
    font: 400 12px var(--font-base, inherit);
    color: var(--sc-muted);
    white-space: nowrap;
    margin-right: 4px;
}

/* Chips are <button>s — strip native chrome, keep the pill shape from the mock. */
.setup-chips__pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font: 500 11.5px var(--font-base, inherit);
    padding: 3px 9px;
    border-radius: 999px;
    white-space: nowrap;
    border: 1px solid transparent;
    background: transparent;
    cursor: pointer;
    /* box-shadow is deliberately absent: gsapInterop.setupChipsAttend tweens it on the
       current pill, and a CSS transition on the same property would double-ease it. */
    transition: filter 140ms ease;
}

    .setup-chips__pill:disabled {
        cursor: default;
    }

    .setup-chips__pill:not(:disabled):hover {
        filter: brightness(0.97);
    }

    .setup-chips__pill:focus-visible {
        outline: 2px solid var(--sc-accent);
        outline-offset: 1px;
    }

.setup-chips__pill--done {
    background: var(--sc-done-bg);
    color: var(--sc-done-fg);
}

/* Satisfied because the record has data (a contract, pricing, properties, routines, assets).
   Blue rather than green, so the strip reads as "these areas have records". It carries no border,
   which is what keeps it distinct from the bordered, dotted current pill. */
.setup-chips__pill--done-data {
    background: var(--sc-accent-bg);
    color: var(--sc-accent-fg);
}

.setup-chips__pill--current {
    background: var(--sc-accent-bg);
    border-color: var(--sc-accent);
    color: var(--sc-accent-fg);
    padding-right: 8px;
}

.setup-chips__pill--todo {
    background: var(--sc-todo-bg);
    border-color: var(--sc-border);
    color: var(--sc-body);
    font-weight: 400;
    padding-left: 10px;
    padding-right: 8px;
}

/* The step immediately after the current one keeps a stronger edge so the eye
   reads the journey's direction; later steps recede. */
.setup-chips__pill--next {
    border-color: var(--sc-border-strong);
}

/* Waived step: still listed (it stays part of the record's story) but visibly
   out of the running. */
.setup-chips__pill--na {
    background: var(--sc-todo-bg);
    border-color: var(--sc-border);
    color: var(--sc-muted);
    font-weight: 400;
    text-decoration: line-through;
    text-decoration-color: var(--sc-border-strong);
}

/* Locked step: the milestone it hangs off (a contract for pricing, a property for routines and
   assets) doesn't exist yet, so there is nothing to open. Reads quieter than todo and takes no
   pointer events, which also lets the wrapping tooltip — explaining what has to come first —
   receive the hover the disabled button itself would swallow. */
.setup-chips__pill--blocked {
    background: transparent;
    border-color: var(--sc-border);
    border-style: dashed;
    color: var(--sc-muted);
    font-weight: 400;
    padding-left: 10px;
    padding-right: 8px;
    opacity: 0.7;
    pointer-events: none;
}

.setup-chips__check,
.setup-chips__block,
.setup-chips__lock,
.setup-chips__caret {
    font-size: 14px !important;
}

.setup-chips__check {
    color: var(--sc-done-icon);
}

.setup-chips__check--data {
    color: var(--sc-accent);
}

.setup-chips__caret {
    color: currentColor;
    opacity: 0.85;
}

.setup-chips__block,
.setup-chips__lock {
    color: var(--sc-muted);
}

/* The current step's breathing dot. The motion is owned by GSAP
   (setupChipsAttend) rather than a keyframe, so it stays in step with the
   pill's glow. Static when GSAP is unavailable. */
.setup-chips__dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--sc-accent);
    display: inline-block;
}

.setup-chips__dot--todo {
    background: var(--sc-border-strong);
}

/* --- Fitting the strip onto one line -------------------------------------------
   The strip shares its row with an arbitrarily long entity title, so it degrades in two
   steps rather than clipping (which drew a half pill). Both are driven by
   gsapInterop.setupChipsFit; this file only describes what each step looks like.

   Step 1, compact: completed and waived pills drop to their icon. The tick already carries
   the meaning, the pill's `title` carries the name, and the menu head repeats it — so this
   is the least informative text on the strip and buys ~100px before anything is dropped.
   Step 2 (whole pills moving into the "+N" menu) is a render change, not a style one. */
.setup-chips[data-sc-compact] .setup-chips__pill--done > span,
.setup-chips[data-sc-compact] .setup-chips__pill--done-data > span,
.setup-chips[data-sc-compact] .setup-chips__pill--na > span {
    display: none;
}

.setup-chips[data-sc-compact] .setup-chips__pill--done,
.setup-chips[data-sc-compact] .setup-chips__pill--done-data,
.setup-chips[data-sc-compact] .setup-chips__pill--na {
    gap: 0;
    padding-left: 6px;
    padding-right: 6px;
}

/* The caret only ever said "this opens a menu", which the pill's own affordance covers. */
.setup-chips[data-sc-compact] .setup-chips__caret {
    display: none;
}

/* Overflow pill. Reads as a todo pill deliberately — what is behind it is outstanding work,
   not a control. */
.setup-chips__pill--more {
    background: var(--sc-todo-bg);
    border-color: var(--sc-border-strong);
    color: var(--sc-body);
    padding-left: 8px;
    padding-right: 8px;
    flex: 0 0 auto;
}

/* --- The step menu (3b) ---------------------------------------------------- */

/* The popover paper owns the card: border, radius and the mock's two-layer shadow. overflow
   is clipped so the tinted primary row and the header/footer rules meet the rounded corners. */
.setup-chip-menu-pop .mud-popover,
.setup-chip-menu-pop.mud-popover {
    border: 1px solid var(--sc-menu-border, var(--mud-palette-lines-default));
    border-radius: 5px;
    box-shadow: 0 10px 20px rgba(0, 0, 0, .08), 0 3px 6px rgba(0, 0, 0, .06) !important;
    overflow: hidden;
}

.defex-theme-dark .setup-chip-menu-pop .mud-popover,
.mud-theme-dark .setup-chip-menu-pop .mud-popover,
.defex-theme-dark .setup-chip-menu-pop.mud-popover,
.mud-theme-dark .setup-chip-menu-pop.mud-popover {
    --sc-menu-border: rgba(255, 255, 255, 0.16);
    box-shadow: 0 10px 20px rgba(0, 0, 0, .45), 0 3px 6px rgba(0, 0, 0, .35) !important;
}

.setup-chip-menu {
    width: 272px;
    padding: 0 !important;
}

.setup-chip-menu__head {
    padding: 12px 14px;
    border-bottom: 1px solid var(--sc-menu-border, var(--mud-palette-lines-default));
}

.setup-chip-menu__title {
    font: 600 13px var(--font-base, inherit);
    color: var(--mud-palette-text-primary, #252525);
}

.setup-chip-menu__desc {
    font: 400 12px/1.45 var(--font-base, inherit);
    color: var(--mud-palette-text-secondary, #6B7280);
    margin-top: 2px;
    white-space: normal;
}

/* Rows are MudMenuItems so they close the menu and keep keyboard support; the
   inner span carries the mock's icon / label / trailing-arrow layout. */
.setup-chip-menu__row {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
}

.setup-chip-menu__row-label {
    flex: 1;
    font: 400 13px var(--font-base, inherit);
}

.setup-chip-menu__row-icon {
    font-size: 18px !important;
    color: var(--mud-palette-text-secondary, #4B5563);
}

.setup-chip-menu__row-go {
    font-size: 16px !important;
    color: #155DFC;
}

/* Primary row — the one that navigates, tinted so it reads first. */
.setup-chip-menu__go {
    background: #EFF6FF;
}

    .setup-chip-menu__go .setup-chip-menu__row-label {
        font-weight: 500;
        color: #1E55C4;
    }

    .setup-chip-menu__go .setup-chip-menu__row-icon {
        color: #155DFC;
    }

.defex-theme-dark .setup-chip-menu__go,
.mud-theme-dark .setup-chip-menu__go {
    background: rgba(0, 115, 234, 0.16);
}

    .defex-theme-dark .setup-chip-menu__go .setup-chip-menu__row-label,
    .mud-theme-dark .setup-chip-menu__go .setup-chip-menu__row-label,
    .defex-theme-dark .setup-chip-menu__go .setup-chip-menu__row-icon,
    .mud-theme-dark .setup-chip-menu__go .setup-chip-menu__row-icon,
    .defex-theme-dark .setup-chip-menu__row-go,
    .mud-theme-dark .setup-chip-menu__row-go {
        color: #8FB6FF;
    }

/* Heading above the list of contracts / properties a step can be finished on. */
.setup-chip-menu__pick {
    padding: 8px 14px 4px;
    /* Longhands, not the `font:` shorthand the rest of this file uses — its
       `var(--font-base, inherit)` family is invalid at computed-value time (the variable is
       not defined anywhere), which drops the whole declaration and leaves the text at 14px. */
    font-size: 11px;
    font-weight: 600;
    line-height: 1.4;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary, #6B7280);
}

/* A target that already satisfies the step — listed last and ticked, so the outstanding
   ones read first. */
.setup-chip-menu__row-icon--done {
    color: #16A34A;
}

.defex-theme-dark .setup-chip-menu__row-icon--done,
.mud-theme-dark .setup-chip-menu__row-icon--done {
    color: #4ADE80;
}

.setup-chip-menu__foot {
    padding: 9px 14px 11px;
    border-top: 1px solid var(--sc-menu-border, var(--mud-palette-lines-default));
    font: 400 11.5px/1.4 var(--font-base, inherit);
    color: var(--mud-palette-text-secondary, #6B7280);
    white-space: normal;
}

.defex-theme-dark .setup-chip-menu__head,
.mud-theme-dark .setup-chip-menu__head,
.defex-theme-dark .setup-chip-menu__foot,
.mud-theme-dark .setup-chip-menu__foot {
    --sc-menu-border: rgba(255, 255, 255, 0.16);
}

/* Below this width the title and the actions menu need the whole row. */
@media (max-width: 1200px) {
    .page-header__setup {
        display: none;
    }
}

/* Reduced motion is handled JS-side: gsapInterop bails out of every setup-chip tween when
   the media query matches, leaving the pills in their rendered state. */
