@import '_content/Microsoft.FluentUI.AspNetCore.Components/Microsoft.FluentUI.AspNetCore.Components.dibzmir27r.bundle.scp.css';

/* /Components/Layout/MainLayout.razor.rz.scp.css */
/* App shell wraps the whole layout. Min-height ensures the footer sits at
   the bottom on short pages without a sticky footer hack. Background and
   text color come from brand tokens (--sa-bg, --sa-text) so light/dark
   flips with the brand palette — previously --neutral-layer-2 masked the
   brand bg with Fluent's neutral, leaving the page looking off-spec. */
.app-shell[b-y1e495miy3] {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--sa-bg);
    color: var(--sa-text);
}

/* Footer is intentionally muted — informational, not interactive. */
.footer[b-y1e495miy3] {
    display: flex;
    gap: 8px;
    padding: 16px 24px;
    color: var(--neutral-foreground-hint);
    font-size: 0.8rem;
    border-top: 1px solid var(--neutral-stroke-rest);
    margin-top: auto;
}
/* /Components/Pages/Catalog.razor.rz.scp.css */
.muted[b-duoraj2h62] {
    color: var(--neutral-foreground-hint);
    font-size: 0.85rem;
    margin: 0;
}
/* /Components/Pages/Dashboard.razor.rz.scp.css */
.tile-grid[b-sahuov1wn8] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
    /* Sits inside a FluentStack which doesn't stretch flex children on the
       cross-axis by default — without explicit width the grid collapses to
       its min content and auto-fit produces a single column. */
    width: 100%;
}

.tile[b-sahuov1wn8] {
    text-decoration: none;
    color: inherit;
    transition: transform 0.12s ease;
}

.tile:hover[b-sahuov1wn8] {
    transform: translateY(-2px);
}

.tile-label[b-sahuov1wn8] {
    color: var(--neutral-foreground-hint);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.75rem;
}

.tile-value[b-sahuov1wn8] {
    font-size: 2.4rem;
    font-weight: 700;
    line-height: 1.1;
    margin: 6px 0 4px 0;
    color: var(--neutral-foreground-rest);
}

.tile-hint[b-sahuov1wn8] {
    color: var(--neutral-foreground-hint);
    font-size: 0.85rem;
}

/* Ghost-preview grid — four placeholder cards arranged like the live data
   they'll eventually hold. Faded so they read as "preview" rather than
   real, but concrete enough that the dashboard's purpose is obvious on an
   empty tenant. */
.ghost-grid[b-sahuov1wn8] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 16px;
    width: 100%;
}

.ghost-card[b-sahuov1wn8] {
    opacity: 0.55;
    pointer-events: none;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.ghost-label[b-sahuov1wn8] {
    color: var(--neutral-foreground-hint);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.7rem;
}

.ghost-row[b-sahuov1wn8] {
    display: flex;
    align-items: center;
    gap: 10px;
}

.ghost-row__title[b-sahuov1wn8] {
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--neutral-foreground-rest);
}

.ghost-row__sub[b-sahuov1wn8] {
    color: var(--neutral-foreground-hint);
    font-size: 0.78rem;
}

.ghost-foot[b-sahuov1wn8] {
    margin-top: 4px;
    color: var(--neutral-foreground-hint);
    font-size: 0.72rem;
    font-style: italic;
}

.ghost-dot[b-sahuov1wn8] {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}
.ghost-dot--ok[b-sahuov1wn8]   { background: var(--sa-status-ready); }
.ghost-dot--info[b-sahuov1wn8] { background: var(--sa-status-cut); }
.ghost-dot--warn[b-sahuov1wn8] { background: var(--sa-status-fab); }
/* /Components/Pages/Dev/ComponentsKitchenSink.razor.rz.scp.css */
.ks-section[b-4xe7du32n5] {
    margin-bottom: 40px;
    padding-bottom: 32px;
    border-bottom: 1px solid var(--neutral-stroke-rest);
}

.ks-section h2[b-4xe7du32n5] {
    margin: 0 0 4px 0;
    font-size: 1.2rem;
    font-weight: 700;
}

.ks-section p[b-4xe7du32n5] {
    color: var(--neutral-foreground-hint);
    margin: 4px 0 16px 0;
    font-size: 0.875rem;
}

.ks-row[b-4xe7du32n5] {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    align-items: center;
    margin-bottom: 12px;
}

.ks-row--col[b-4xe7du32n5] {
    flex-direction: column;
    align-items: stretch;
}

.ks-row strong[b-4xe7du32n5] {
    min-width: 100px;
    color: var(--neutral-foreground-hint);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
/* /Components/Pages/Landing.razor.rz.scp.css */
/* Public landing. Three sections, one decision.

   The hero leans on type weight + a single signature visual (the process
   beam). All colors come from existing tokens — Fluent neutrals plus the
   --sa-status-* lifecycle palette from wwwroot/app.css. No new tokens.

   Pricing styles used to live here; they moved to Pricing.razor.css when
   the four-tier comparison got its own /pricing route. */

.landing[b-rbzei9to2q] {
    max-width: 1100px;
    margin: 0 auto;
    padding: 24px 16px 80px 16px;
}

/* ──────────────────────────────────────────────────────────────────────────
   Hero
   ────────────────────────────────────────────────────────────────────────── */

.hero[b-rbzei9to2q] {
    text-align: center;
    padding: 72px 16px 56px 16px;
}

.eyebrow[b-rbzei9to2q] {
    display: inline-block;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--accent-fill-rest);
    font-size: 0.78rem;
    font-weight: 700;
    margin-bottom: 14px;
}

/* Bigger than the previous hero — this h1 carries the page on its own.
   clamp() scales smoothly from phone to ultra-wide without media queries. */
.hero h1[b-rbzei9to2q] {
    font-size: clamp(2.5rem, 5.5vw, 4.5rem);
    line-height: 1.05;
    letter-spacing: -0.02em;
    margin: 0 0 20px 0;
    max-width: 18ch;
    margin-inline: auto;
}

.lede[b-rbzei9to2q] {
    max-width: 640px;
    margin: 0 auto 28px auto;
    color: var(--neutral-foreground-hint);
    font-size: 1.15rem;
    line-height: 1.55;
}

.hero-actions[b-rbzei9to2q] {
    justify-content: center;
    margin: 16px 0 48px 0;
}

/* ──────────────────────────────────────────────────────────────────────────
   Process beam — the signature visual

   Six segments using --sa-status-* from wwwroot/app.css. Same colors
   visitors see inside the app once they sign in. Dark mode is free because
   the tokens already use light-dark() at their definition site. The hairline
   between segments gives the milled-edge feel and stays visible in both
   modes (white-translucent reads correctly over any segment color).
   ────────────────────────────────────────────────────────────────────────── */

.beam[b-rbzei9to2q] {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    height: 28px;
    max-width: 720px;
    margin: 0 auto;
    border-radius: 4px;
    overflow: hidden;
    position: relative;
    box-shadow: 0 1px 0 var(--neutral-stroke-rest);
}

.beam-seg[b-rbzei9to2q] {
    display: block;
    position: relative;
}

.beam-seg + .beam-seg[b-rbzei9to2q]::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 1px;
    background: rgba(255, 255, 255, 0.18);
}

.beam-seg[data-status="pending"][b-rbzei9to2q] { background: var(--sa-status-pending); }
.beam-seg[data-status="cut"][b-rbzei9to2q]     { background: var(--sa-status-cut); }
.beam-seg[data-status="fab"][b-rbzei9to2q]     { background: var(--sa-status-fab); }
.beam-seg[data-status="welded"][b-rbzei9to2q]  { background: var(--sa-status-welded); }
.beam-seg[data-status="painted"][b-rbzei9to2q] { background: var(--sa-status-painted); }
.beam-seg[data-status="ready"][b-rbzei9to2q]   { background: var(--sa-status-ready); }

/* One-time shimmer sweep on first load. Reduced-motion users see a static
   beam — the meaning carries either way. */
@media (prefers-reduced-motion: no-preference) {
    .beam[b-rbzei9to2q]::after {
        content: "";
        position: absolute;
        inset: 0;
        background: linear-gradient(
            100deg,
            transparent 0%,
            rgba(255, 255, 255, 0.22) 50%,
            transparent 100%
        );
        transform: translateX(-100%);
        animation: beam-shimmer-b-rbzei9to2q 1.8s ease-out 0.25s 1 forwards;
        pointer-events: none;
    }

    @keyframes beam-shimmer-b-rbzei9to2q {
        to { transform: translateX(100%); }
    }
}

.beam-labels[b-rbzei9to2q] {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    max-width: 720px;
    margin: 10px auto 0 auto;
    color: var(--neutral-foreground-hint);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.beam-labels span[b-rbzei9to2q] {
    text-align: center;
}

@media (max-width: 480px) {
    .beam-labels[b-rbzei9to2q] {
        font-size: 0.6rem;
        letter-spacing: 0.06em;
    }
}

/* ──────────────────────────────────────────────────────────────────────────
   Three pillars — replaces the previous 6-card feature grid

   No cards: just numerals, headlines, supporting lines, and a hairline
   border above each. The numbers in accent color do the structural work.
   ────────────────────────────────────────────────────────────────────────── */

.pillars[b-rbzei9to2q] {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 36px;
    margin: 96px 0 72px 0;
}

@media (max-width: 820px) {
    .pillars[b-rbzei9to2q] {
        grid-template-columns: 1fr;
        gap: 28px;
    }
}

.pillar[b-rbzei9to2q] {
    border-top: 1px solid var(--neutral-stroke-rest);
    padding-top: 20px;
}

.pillar-num[b-rbzei9to2q] {
    display: block;
    color: var(--accent-fill-rest);
    font-size: 0.85rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    margin-bottom: 10px;
}

.pillar h2[b-rbzei9to2q] {
    margin: 0 0 8px 0;
    font-size: 1.15rem;
    line-height: 1.35;
    letter-spacing: -0.005em;
}

.pillar p[b-rbzei9to2q] {
    margin: 0;
    color: var(--neutral-foreground-hint);
    line-height: 1.55;
    font-size: 0.98rem;
}

.pillar code[b-rbzei9to2q] {
    /* font-family inherited from tokens.css global `code` rule (IBM Plex Mono).
       Local rules below adjust size and chrome only. */
    font-size: 0.9em;
    padding: 1px 5px;
    border-radius: 4px;
    background: var(--neutral-fill-stealth-rest);
}

/* ──────────────────────────────────────────────────────────────────────────
   One-line pricing teaser — single anchor between pillars and closing CTA
   ────────────────────────────────────────────────────────────────────────── */

.pricing-teaser[b-rbzei9to2q] {
    text-align: center;
    margin: 0 0 72px 0;
    color: var(--neutral-foreground-hint);
    font-size: 0.98rem;
}

.pricing-teaser a[b-rbzei9to2q] {
    color: var(--accent-fill-rest);
    text-decoration: none;
    font-weight: 600;
    margin-left: 4px;
}

.pricing-teaser a:hover[b-rbzei9to2q] {
    text-decoration: underline;
}

/* ──────────────────────────────────────────────────────────────────────────
   Closing CTA panel — last thing the visitor sees
   ────────────────────────────────────────────────────────────────────────── */

.cta[b-rbzei9to2q] {
    text-align: center;
    padding: 64px 24px;
    background: var(--neutral-fill-stealth-rest);
    border-radius: 14px;
}

.cta h2[b-rbzei9to2q] {
    margin: 0 0 10px 0;
    font-size: clamp(1.5rem, 3vw, 2rem);
    letter-spacing: -0.01em;
}

.cta p[b-rbzei9to2q] {
    margin: 0 auto 24px auto;
    max-width: 540px;
    color: var(--neutral-foreground-hint);
    line-height: 1.55;
}

.reassure[b-rbzei9to2q] {
    display: block;
    color: var(--neutral-foreground-hint);
    font-size: 0.85rem;
    margin-top: 18px;
}
/* /Components/Pages/Planner.razor.rz.scp.css */
.planner-head[b-0wqmdjpj6i] {
    margin-bottom: 1rem;
}

.planner-head h1[b-0wqmdjpj6i] {
    margin-bottom: 0.2rem;
}

.planner-sub[b-0wqmdjpj6i] {
    margin: 0;
    color: var(--neutral-foreground-hint);
    font-size: 0.9rem;
}
/* /Components/Pages/Pricing.razor.rz.scp.css */
/* /pricing — owns the four-tier comparison. Styles lifted from the previous
   Landing.razor.css .pricing/.tier* block (unchanged); page-level wrapper
   added so the comparison sits in the same 1100px column as the rest of the
   public site. h2 instead of h3 on tier names because this page has its own
   H1 ("Pricing") and the tiers are second-level. */

.pricing-page[b-8yyif7bfrb] {
    max-width: 1100px;
    margin: 0 auto;
    padding: 24px 16px 80px 16px;
}

.pricing-header[b-8yyif7bfrb] {
    text-align: center;
    padding: 40px 16px 32px 16px;
}

.eyebrow[b-8yyif7bfrb] {
    display: inline-block;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--accent-fill-rest);
    font-size: 0.78rem;
    font-weight: 700;
    margin-bottom: 12px;
}

.pricing-header h1[b-8yyif7bfrb] {
    font-size: clamp(2rem, 4vw, 2.8rem);
    margin: 0 0 12px 0;
    letter-spacing: -0.01em;
    line-height: 1.1;
}

.lede[b-8yyif7bfrb] {
    max-width: 640px;
    margin: 0 auto;
    color: var(--neutral-foreground-hint);
    font-size: 1.05rem;
    line-height: 1.55;
}

.pricing[b-8yyif7bfrb] {
    text-align: center;
}

.tier-grid[b-8yyif7bfrb] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
    text-align: left;
}

.tier[b-8yyif7bfrb] {
    padding: 20px;
    position: relative;
}

.tier h2[b-8yyif7bfrb] {
    margin: 0 0 6px 0;
    font-size: 1.25rem;
}

.tier-price[b-8yyif7bfrb] {
    font-size: 1.6rem;
    font-weight: 700;
    margin: 0 0 12px 0;
}

.tier-price small[b-8yyif7bfrb] {
    font-size: 0.85rem;
    font-weight: 400;
    color: var(--neutral-foreground-hint);
}

.tier ul[b-8yyif7bfrb] {
    margin: 0 0 16px 0;
    padding-left: 18px;
    color: var(--neutral-foreground-hint);
    font-size: 0.92rem;
    line-height: 1.6;
}

.tier.highlighted[b-8yyif7bfrb] {
    outline: 2px solid var(--accent-fill-rest);
    outline-offset: -2px;
}

.tier-badge[b-8yyif7bfrb] {
    position: absolute;
    top: -10px;
    left: 16px;
    background: var(--accent-fill-rest);
    color: var(--foreground-on-accent-rest);
    padding: 2px 10px;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.pricing-note[b-8yyif7bfrb] {
    display: block;
    margin-top: 20px;
    color: var(--neutral-foreground-hint);
}
/* /Components/Pages/Procurement.razor.rz.scp.css */
.po-lines[b-8hue7lxxm1] {
    width: 100%;
    border-collapse: collapse;
}

.po-lines th[b-8hue7lxxm1],
.po-lines td[b-8hue7lxxm1] {
    padding: 4px 6px;
    vertical-align: middle;
}

.po-lines th[b-8hue7lxxm1] {
    text-align: left;
    font-weight: 600;
    border-bottom: 1px solid var(--neutral-stroke-rest);
}

.po-lines td input[b-8hue7lxxm1],
.po-lines td select[b-8hue7lxxm1] {
    width: 100%;
    box-sizing: border-box;
}
/* /Components/Pages/ProjectDetail.razor.rz.scp.css */
.project-detail[b-xnnvxgzedz] {
    display: flex;
    flex-direction: column;
    gap: 24px;
}

.project-detail__header[b-xnnvxgzedz] {
    /* Header card has a slight breathing room from the nav rail below. */
    margin-bottom: 4px;
}

/* Project info cards fill the header edge-to-edge: a flex row that wraps, with
   each card growing to fill its row — including the last row — so there's no
   trailing empty space. ::deep reaches the MetricStat component roots (their
   .metric-stat class lives in a scoped stylesheet of their own). */
.project-detail__cards[b-xnnvxgzedz] {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}

.project-detail__cards[b-xnnvxgzedz]  .metric-stat {
    flex: 1 1 160px;
}

/* Action toolbar sits on its own row (line two) under the project info, set off
   by a hairline so it reads as a distinct action bar rather than crowding the
   title. */
.project-detail__actions[b-xnnvxgzedz] {
    margin-top: 4px;
    padding-top: 16px;
    border-top: 1px solid var(--neutral-stroke-rest);
}
/* /Components/Pages/Register.razor.rz.scp.css */
.register-wrap[b-tu5qzh1500] {
    max-width: 720px;
    margin: 0 auto;
    padding: 40px 16px;
}

.register-wrap .lede[b-tu5qzh1500] {
    color: var(--neutral-foreground-hint);
    font-size: 1.05rem;
    margin: 0 0 24px 0;
    line-height: 1.55;
}

.register-wrap .fineprint[b-tu5qzh1500] {
    color: var(--neutral-foreground-hint);
    font-size: 0.85rem;
    margin: 32px 0 0 0;
    line-height: 1.5;
}
/* /Components/Shared/BackgroundTasksPill.razor.rz.scp.css */
.bg-tasks-pill[b-3fsx6k429i] {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 4px 12px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--accent-fill-rest) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent-fill-rest) 35%, transparent);
    color: var(--accent-fill-rest);
    font-size: 0.8rem;
    font-weight: 600;
}

.bg-tasks-pill__label[b-3fsx6k429i] {
    white-space: nowrap;
}
/* /Components/Shared/Brand/Monogram.razor.rz.scp.css */
.brand-monogram[b-jgnhhauaxq] {
    display: inline-flex;
    align-items: center;
    color: var(--sa-text-strong);
}

.brand-monogram svg[b-jgnhhauaxq] { display: block; }

.brand-monogram-sm svg[b-jgnhhauaxq] { height: 14px; }
.brand-monogram-md svg[b-jgnhhauaxq] { height: 22px; }
.brand-monogram-lg svg[b-jgnhhauaxq] { height: 32px; }
/* /Components/Shared/Brand/Wordmark.razor.rz.scp.css */
/* Wordmark lockup. currentColor inherits from the parent; on hover the
   anchor's color shifts to brand orange so the whole wordmark warms up
   together (the `OS` is already orange and stays put). The hover only
   touches the SteelAxis portion via currentColor — exactly the brand
   spec's intent. */
.brand-wordmark[b-ewoyhx89ul] {
    display: inline-flex;
    align-items: center;
    text-decoration: none;
    color: var(--sa-text-strong);
    transition: color 0.15s ease;
}

.brand-wordmark svg[b-ewoyhx89ul] {
    display: block;
}

/* Sizes match the brand spec's minimum-legible and recommended values:
   sm = 18px (absolute minimum — below this the mono OS loses legibility),
   md = 26px (the right size for sticky top nav),
   lg = 40px (cover pages, hero, deck title slide). */
.brand-wordmark-sm svg[b-ewoyhx89ul] { height: 18px; }
.brand-wordmark-md svg[b-ewoyhx89ul] { height: 26px; }
.brand-wordmark-lg svg[b-ewoyhx89ul] { height: 40px; }

.brand-wordmark:hover[b-ewoyhx89ul] {
    color: var(--sa-orange);
}
/* /Components/Shared/EmptyState.razor.rz.scp.css */
.empty-state[b-izl3il7h13] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 48px 24px;
    gap: 8px;
    color: var(--neutral-foreground-hint);
}

.empty-state__icon[b-izl3il7h13] {
    font-size: 32px;
    color: var(--neutral-foreground-disabled);
    margin-bottom: 4px;
}

/* Force the FluentIcon SVG inside the icon container to render at 32px;
   without this it inherits the default 16-20px size and reads as a tiny
   speck on a near-empty page. */
.empty-state__icon[b-izl3il7h13]  svg {
    width: 32px;
    height: 32px;
}

.empty-state__title[b-izl3il7h13] {
    font-size: 1rem;
    font-weight: 600;
    color: var(--neutral-foreground-rest);
}

.empty-state__hint[b-izl3il7h13] {
    font-size: 0.875rem;
    max-width: 36rem;
}

.empty-state__action[b-izl3il7h13] {
    margin-top: 12px;
}
/* /Components/Shared/ImportStatusBanner.razor.rz.scp.css */
/* Fixed top-right card. The slide-in keyframe runs once on mount. The
   z-index sits above the sticky-glass TopBar (10) but below FluentDialog
   (typically 1000+) so a dialog opening over it still wins.

   top: 72px clears the 56-64px sticky TopBar plus a small breathing gap —
   the earlier 16px slid the card UNDER the bar and clipped the nav links
   on the right side of the navbar ("Documents" → "Docun"). */
.import-banner[b-ce3dyvgcw1] {
    position: fixed;
    top: 72px;
    right: 16px;
    z-index: 50;
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 12px 16px;
    min-width: 320px;
    max-width: 420px;
    background: var(--neutral-layer-1);
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    animation: import-banner-in-b-ce3dyvgcw1 0.22s ease-out forwards;
}

@keyframes import-banner-in-b-ce3dyvgcw1 {
    from { transform: translateY(-12px) scale(0.98); opacity: 0; }
    to { transform: translateY(0) scale(1); opacity: 1; }
}

/* Tone-driven left border picks up the state. Aligns with StatusPill
   colors for visual consistency. */
.import-banner--uploading[b-ce3dyvgcw1] { border-left: 4px solid var(--sa-status-cut); }
.import-banner--ready[b-ce3dyvgcw1] { border-left: 4px solid var(--sa-status-ready); }
.import-banner--error[b-ce3dyvgcw1] { border-left: 4px solid var(--sa-status-painted); }

.import-banner__icon[b-ce3dyvgcw1] {
    flex-shrink: 0;
    color: var(--neutral-foreground-rest);
    padding-top: 2px;
}

.import-banner--ready .import-banner__icon[b-ce3dyvgcw1] { color: var(--sa-status-ready); }
.import-banner--error .import-banner__icon[b-ce3dyvgcw1] { color: var(--sa-status-painted); }

.import-banner__body[b-ce3dyvgcw1] {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.import-banner__title[b-ce3dyvgcw1] {
    font-weight: 600;
    color: var(--neutral-foreground-rest);
    font-size: 0.875rem;
}

.import-banner__subtitle[b-ce3dyvgcw1] {
    font-size: 0.75rem;
    color: var(--neutral-foreground-hint);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.import-banner__progress[b-ce3dyvgcw1] {
    margin-top: 4px;
    width: 100%;
}

.import-banner__actions[b-ce3dyvgcw1] {
    display: flex;
    gap: 4px;
    align-items: center;
    flex-shrink: 0;
}
/* /Components/Shared/KvBlock.razor.rz.scp.css */
/* Each tone resolves to one --kv-base color used for tint+border+text.
   The pattern is identical to StatusPill but with a slightly stronger tint
   (25%/55%) since KvBlock takes up more visual real estate. */
.kv-block[b-kjb8trw121] {
    --kv-base: var(--neutral-foreground-hint);
    background: color-mix(in srgb, var(--kv-base) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--kv-base) 35%, transparent);
    border-radius: 6px;
    padding: 10px 14px;
    color: var(--kv-base);
    font-size: 0.875rem;
}

.kv-block--success[b-kjb8trw121] { --kv-base: var(--sa-status-ready); }
.kv-block--warning[b-kjb8trw121] { --kv-base: var(--sa-status-fab); }
.kv-block--danger[b-kjb8trw121]  { --kv-base: var(--sa-status-painted); }
.kv-block--info[b-kjb8trw121]    { --kv-base: var(--sa-status-cut); }

.kv-block__label[b-kjb8trw121] {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    margin-bottom: 4px;
    opacity: 0.85;
}

.kv-block__value[b-kjb8trw121] {
    font-size: 1rem;
    font-weight: 600;
}

.kv-block__hint[b-kjb8trw121] {
    font-size: 0.75rem;
    opacity: 0.85;
    margin-top: 4px;
}
/* /Components/Shared/Layout/MobileNav.razor.rz.scp.css */
/* The hamburger trigger lives in TopBar now (its show/hide rule moved to
   TopBar.razor.css); this component owns only the drawer + backdrop overlay,
   rendered by MainLayout so it escapes the top bar's backdrop-filter. */

/* Backdrop dims the page underneath. Click anywhere on it to close. */
.mobile-backdrop[b-ysh1l3dj48] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    z-index: 1900;
    animation: mobile-backdrop-in-b-ysh1l3dj48 0.2s ease-out forwards;
}
@keyframes mobile-backdrop-in-b-ysh1l3dj48 {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* Drawer panel slides in from the left. 280px is the comfortable touch
   target width for a list of links on a phone. */
.mobile-drawer[b-ysh1l3dj48] {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 280px;
    max-width: 85vw;
    background: var(--neutral-layer-1);
    z-index: 2000;
    box-shadow: 4px 0 20px rgba(0, 0, 0, 0.2);
    display: flex;
    flex-direction: column;
    animation: mobile-drawer-in-b-ysh1l3dj48 0.22s ease-out forwards;
}
@keyframes mobile-drawer-in-b-ysh1l3dj48 {
    from { transform: translateX(-100%); }
    to { transform: translateX(0); }
}

.mobile-drawer-header[b-ysh1l3dj48] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    border-bottom: 1px solid var(--neutral-stroke-rest);
}

.mobile-drawer-nav[b-ysh1l3dj48] {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 12px;
    /* flex:1 + min-height:0 make this the scroll region inside the fixed
       drawer. Without them the list sizes to its content and the bottom
       items (Documents/Settings) fall past the drawer edge unreachably. */
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

.mobile-link[b-ysh1l3dj48] {
    text-decoration: none;
    color: var(--neutral-foreground-rest);
    font-size: 1rem;
    padding: 12px 16px;
    border-radius: 6px;
    transition: background-color 0.15s ease;
}
.mobile-link:hover[b-ysh1l3dj48] {
    background: var(--neutral-fill-stealth-hover);
}
.mobile-link-active[b-ysh1l3dj48] {
    background: var(--accent-fill-rest);
    color: var(--foreground-on-accent-rest);
    font-weight: 600;
}
/* /Components/Shared/Layout/TopBar.razor.rz.scp.css */
/* Sticky glass header. The backdrop-filter + semi-transparent background
   make scrolling content show through subtly — the JS demo's signature
   look. Without backdrop-filter the bar reads as a solid block and the
   page below feels disconnected from it. */
.topbar[b-q64ayospc8] {
    position: sticky;
    top: 0;
    z-index: 10;
    background: color-mix(in srgb, var(--neutral-layer-1) 80%, transparent);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--neutral-stroke-rest);
}

/* Inner container caps width at 1280px and centres so logo aligns with
   .content body padding. Padding-block matches a typical 56-64px header. */
.topbar-inner[b-q64ayospc8] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    max-width: 80rem;
    margin-inline: auto;
    padding: 12px 24px;
}

.topbar-left[b-q64ayospc8], .topbar-right[b-q64ayospc8] {
    display: flex;
    align-items: center;
    gap: 12px;
}

/* Wordmark lockup is rendered by <Wordmark /> (see
   Components/Shared/Brand/Wordmark.razor + .razor.css). The old plain-text
   .topbar-logo block lived here; it's gone now because Wordmark owns the
   typography, color, and hover behaviour per the brand spec. */

.topbar-nav[b-q64ayospc8] {
    display: flex;
    gap: 4px;
    align-items: center;
}

/* The hamburger trigger is hidden on wide screens (the top nav handles
   everything) and appears below 1180px in lockstep with the nav-hide rule. */
.mobile-nav-trigger[b-q64ayospc8] {
    display: none;
}

/* Below 1180px the top nav collapses entirely; the hamburger trigger takes
   over. 1180 avoids the 9-link nav colliding with the right-hand cluster
   between ~1025–1120px. */
@media (max-width: 1180px) {
    .topbar-nav[b-q64ayospc8] { display: none; }
    .mobile-nav-trigger[b-q64ayospc8] { display: inline-flex; }
}

.topbar-link[b-q64ayospc8] {
    text-decoration: none;
    color: var(--neutral-foreground-rest);
    font-size: 0.875rem;
    padding: 8px 12px;
    border-radius: 6px;
    transition: background-color 0.15s ease;
    /* Keep multi-word labels ("Work orders") on a single line — otherwise
       the bar gains a row and the active-underline floats away from the
       baseline of the rest of the nav. */
    white-space: nowrap;
}
.topbar-link:hover[b-q64ayospc8] {
    background: var(--neutral-fill-stealth-hover);
}

/* Active link: brand color + 2px underline. The underline is the load-bearing
   visual cue — bold-only is too subtle on a glass background. The 4px
   margin-top sits the underline below the descender line so descenders
   in "Inventory" etc. don't clip it. */
.topbar-link-active[b-q64ayospc8] {
    color: var(--accent-fill-rest);
    font-weight: 600;
}
.topbar-link-active[b-q64ayospc8]::after {
    content: "";
    display: block;
    height: 2px;
    background: var(--accent-fill-rest);
    margin-top: 4px;
    border-radius: 1px;
}

.tenant-chip[b-q64ayospc8] {
    background: var(--accent-fill-rest);
    color: var(--foreground-on-accent-rest);
    padding: 2px 12px;
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.apex-pill[b-q64ayospc8] {
    color: var(--neutral-foreground-hint);
    font-size: 0.85rem;
    letter-spacing: 0.04em;
}

.env-pill[b-q64ayospc8] {
    background: var(--warning-base);
    color: black;
    padding: 1px 8px;
    border-radius: 4px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.08em;
}

.topbar-icon-link[b-q64ayospc8] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 6px;
    color: var(--neutral-foreground-rest);
    text-decoration: none;
    transition: background-color 0.15s ease, color 0.15s ease;
}
.topbar-icon-link:hover[b-q64ayospc8] {
    background: var(--neutral-fill-stealth-hover);
    color: var(--accent-fill-rest);
}

.user-chip[b-q64ayospc8] {
    color: var(--neutral-foreground-rest);
    font-size: 0.9rem;
    padding: 2px 10px;
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 999px;
    /* "Dev User · Admin" was wrapping to two lines and pushing the topbar
       taller than the rest of the navbar — pin it to one line. */
    white-space: nowrap;
}

/* Hide the user chip on small screens — the user is implied. The dev pill
   stays since it's a critical signal even on phones. */
@media (max-width: 640px) {
    .user-chip[b-q64ayospc8] { display: none; }
    .topbar-inner[b-q64ayospc8] { padding: 12px 16px; }
}
/* /Components/Shared/MetricStat.razor.rz.scp.css */
.metric-stat[b-holiw28qlt] {
    background: var(--neutral-layer-1);
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 8px;
    padding: 16px 20px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 160px;
}

.metric-stat__label[b-holiw28qlt] {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--neutral-foreground-hint);
}

.metric-stat__value[b-holiw28qlt] {
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--neutral-foreground-rest);
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.metric-stat__hint[b-holiw28qlt] {
    font-size: 0.75rem;
    color: var(--neutral-foreground-hint);
}

/* Tones tint only the value — the label/hint stay neutral so the tile
   doesn't read as "this whole tile is in a state". The JS demo uses
   green for cost savings (remnant reuse) and warning for overdue dates. */
.metric-stat--success .metric-stat__value[b-holiw28qlt] { color: var(--sa-status-ready); }
.metric-stat--warning .metric-stat__value[b-holiw28qlt] { color: var(--sa-status-fab); }
.metric-stat--danger .metric-stat__value[b-holiw28qlt] { color: var(--sa-status-painted); }
.metric-stat--info .metric-stat__value[b-holiw28qlt] { color: var(--sa-status-cut); }

/* Optional thin progress bar (the project header's "Progress" card). */
.metric-stat__bar[b-holiw28qlt] {
    margin-top: 8px;
    height: 6px;
    border-radius: 999px;
    background: var(--neutral-fill-stealth-rest);
    overflow: hidden;
}
.metric-stat__bar-fill[b-holiw28qlt] {
    height: 100%;
    background: var(--accent-fill-rest);
    border-radius: 999px;
}
/* /Components/Shared/Nav/SideNav.razor.rz.scp.css */
.sidenav[b-czyt876gur] {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.sidenav__group[b-czyt876gur] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-top: 8px;
}

.sidenav__group-label[b-czyt876gur] {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--neutral-foreground-hint);
    padding: 6px 12px 2px;
}

/* Item base — shared by the <button> (state mode) and <a> (route mode) forms.
   Active state is a brand-orange left border + tint, the vertical analogue of
   the old Settings tab underline. */
.sidenav__item[b-czyt876gur] {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    text-align: left;
    text-decoration: none;
    background: none;
    border: 0;
    border-left: 3px solid transparent;
    border-radius: 6px;
    padding: 8px 12px;
    font: inherit;
    color: var(--neutral-foreground-rest);
    cursor: pointer;
    transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}

.sidenav__item:hover[b-czyt876gur] {
    background: var(--neutral-fill-stealth-hover);
    color: var(--accent-fill-rest);
}

.sidenav__item--child[b-czyt876gur] {
    padding-left: 24px;
    font-size: 0.92rem;
}

.sidenav__item--active[b-czyt876gur] {
    color: var(--accent-fill-rest);
    font-weight: 600;
    border-left-color: var(--accent-fill-rest);
    background: color-mix(in srgb, var(--accent-fill-rest) 8%, transparent);
}

.sidenav__label[b-czyt876gur] {
    flex: 1;
    min-width: 0;
}

.sidenav__count[b-czyt876gur] {
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
    color: var(--neutral-foreground-hint);
    background: var(--neutral-fill-stealth-rest);
    padding: 0 7px;
    border-radius: 999px;
    min-width: 1.2rem;
    text-align: center;
}

.sidenav__item--active .sidenav__count[b-czyt876gur] {
    color: var(--accent-fill-rest);
}
/* /Components/Shared/NestingBar.razor.rz.scp.css */
/* Palette tokens (--sa-palette-0..9) live in app.css — :root rules don't
   work in Blazor's scoped .razor.css (selectors get a [b-xxx] scope attr). */

.nesting-bar[b-awadl9b74q] {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin: 4px 0;
}

.nesting-bar__label[b-awadl9b74q] {
    font-size: 0.75rem;
    color: var(--neutral-foreground-hint);
    font-weight: 600;
    letter-spacing: 0.03em;
}

.nesting-bar__track[b-awadl9b74q] {
    display: flex;
    height: 36px;
    border-radius: 4px;
    overflow: hidden;
    border: 1px solid var(--neutral-stroke-rest);
    background: var(--neutral-layer-2);
}

.nesting-bar__seg[b-awadl9b74q] {
    background: color-mix(in srgb, var(--seg-color) 65%, transparent);
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.7rem;
    font-weight: 700;
    overflow: hidden;
    border-right: 1px solid var(--neutral-layer-1);
    min-width: 0;
    transition: filter 0.1s ease;
}
.nesting-bar__seg:last-child[b-awadl9b74q] { border-right: none; }
.nesting-bar__seg:hover[b-awadl9b74q] { filter: brightness(1.1); }

.nesting-bar__seg-label[b-awadl9b74q] {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 0 4px;
    /* Force readable contrast across all palette hues — light text on a 65%
       tint is readable enough but adds a subtle text-shadow for safety. */
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

/* Waste: striped fill so it's never confused with an allocated cut. The
   JS demo uses the same 5px/5px transparent/black lines at 45°. */
.nesting-bar__waste[b-awadl9b74q] {
    display: flex;
    align-items: center;
    justify-content: center;
    background: repeating-linear-gradient(
        45deg,
        transparent 0,
        transparent 5px,
        rgba(0, 0, 0, 0.18) 5px,
        rgba(0, 0, 0, 0.18) 10px
    );
    color: var(--neutral-foreground-hint);
    font-size: 0.65rem;
    font-weight: 700;
    overflow: hidden;
}

.nesting-bar__waste.is-remnant[b-awadl9b74q] {
    color: var(--sa-status-ready);
    background: repeating-linear-gradient(
        45deg,
        transparent 0,
        transparent 5px,
        color-mix(in srgb, var(--sa-status-ready) 30%, transparent) 5px,
        color-mix(in srgb, var(--sa-status-ready) 30%, transparent) 10px
    );
}

.nesting-bar__waste-label[b-awadl9b74q] {
    padding: 0 6px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* /Components/Shared/PieceStatusGrid.razor.rz.scp.css */
/* Auto-fill grid sized so 12-20 tiles show comfortably on a desktop row.
   The 40px min keeps tiles tappable on a tablet (shop floor); auto-fill
   means rows fluidly grow with container width. */
.piece-grid[b-hjzoewkykc] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(40px, 1fr));
    gap: 4px;
    padding: 8px 0;
}

.piece-grid__tile[b-hjzoewkykc] {
    aspect-ratio: 1 / 1;
    min-width: 40px;
    background: color-mix(in srgb, var(--tile-color) 18%, transparent);
    color: var(--tile-color);
    border: 1px solid color-mix(in srgb, var(--tile-color) 50%, transparent);
    border-radius: 4px;
    font-size: 0.7rem;
    font-weight: 700;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: transform 0.1s ease, background 0.1s ease;
    font-variant-numeric: tabular-nums;
}

.piece-grid__tile:hover[b-hjzoewkykc] {
    transform: scale(1.05);
    background: color-mix(in srgb, var(--tile-color) 30%, transparent);
}

.piece-grid__tile:focus-visible[b-hjzoewkykc] {
    outline: 2px solid var(--accent-fill-rest);
    outline-offset: 2px;
}
/* /Components/Shared/Planner/KanbanBoard.razor.rz.scp.css */
.kanban[b-7dyal8k21l] {
    display: flex;
    gap: 14px;
    /* 7 stage columns will outgrow the 80rem content cap on most screens —
       scroll the board horizontally rather than squeezing columns unreadably. */
    overflow-x: auto;
    padding-bottom: 8px;
    align-items: flex-start;
}

.kanban-col[b-7dyal8k21l] {
    flex: 0 0 250px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    background: var(--neutral-layer-2);
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 8px;
    padding: 10px;
}

.kanban-col__head[b-7dyal8k21l] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.kanban-col__title[b-7dyal8k21l] {
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--neutral-foreground-rest);
}

.kanban-col__count[b-7dyal8k21l] {
    font-family: var(--sa-font-mono);
    font-size: 0.78rem;
    color: var(--neutral-foreground-hint);
    background: var(--neutral-fill-stealth-rest);
    border-radius: 999px;
    padding: 1px 8px;
}

.kanban-lane[b-7dyal8k21l] {
    display: flex;
    flex-direction: column;
    gap: 8px;
    /* Give each lane a minimum drop area even when empty so a card can be
       dragged into a lane that currently has no cards. */
    min-height: 28px;
}

.kanban-draggable[b-7dyal8k21l] {
    cursor: grab;
}

.kanban-draggable:active[b-7dyal8k21l] {
    cursor: grabbing;
}

.kanban-lane__label[b-7dyal8k21l] {
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--neutral-foreground-hint);
}

.kanban-lane__empty[b-7dyal8k21l] {
    color: var(--neutral-foreground-hint);
    font-size: 0.8rem;
    padding: 2px 0 6px;
}

.kanban-done[b-7dyal8k21l] {
    border-top: 1px dashed var(--neutral-stroke-rest);
    padding-top: 8px;
}

.kanban-done > summary[b-7dyal8k21l] {
    cursor: pointer;
    font-size: 0.78rem;
    color: var(--neutral-foreground-hint);
    margin-bottom: 8px;
}

.kanban-done > :not(summary)[b-7dyal8k21l] {
    margin-bottom: 8px;
}
/* /Components/Shared/Planner/KanbanCard.razor.rz.scp.css */
.kanban-card[b-xutbg4307c] {
    background: var(--neutral-layer-1);
    border: 1px solid var(--neutral-stroke-rest);
    /* 4px colored stripe by WO type — same language as ProcessCard. */
    border-left: 4px solid var(--card-color);
    border-radius: 6px;
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.kanban-card:hover[b-xutbg4307c] {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.kanban-card__top[b-xutbg4307c] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.kanban-card__num[b-xutbg4307c] {
    font-family: var(--sa-font-mono);
    font-weight: 500;
    font-size: 0.85rem;
    color: var(--neutral-foreground-rest);
}

.kanban-card__vendor[b-xutbg4307c] {
    flex-shrink: 0;
}

.kanban-card__project[b-xutbg4307c] {
    font-size: 0.8rem;
    color: var(--neutral-foreground-hint);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kanban-card__tags[b-xutbg4307c] {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.kanban-card__op[b-xutbg4307c] {
    font-family: var(--sa-font-mono);
    font-size: 0.72rem;
    color: var(--neutral-foreground-hint);
}
/* /Components/Shared/Print/PrintFrame.razor.rz.scp.css */
.print-frame[b-39ldiimwan] {
    display: flex;
    flex-direction: column;
    align-items: center;
    background: var(--neutral-layer-2);
    min-height: 100vh;
    padding: 24px 0;
}

.print-frame__toolbar[b-39ldiimwan] {
    display: flex;
    gap: 8px;
    width: 210mm;
    max-width: 100%;
    margin-bottom: 16px;
    justify-content: flex-end;
}

/* The page itself: 210mm A4 width, white background, black text. The
   print version overrides container/page styles via @media print to drop
   the toolbar and use the printer's own page background. */
.print-frame__page[b-39ldiimwan] {
    width: 210mm;
    max-width: 100%;
    background: white;
    color: black;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.12);
    padding: 18mm 18mm 22mm 18mm;
    box-sizing: border-box;
    /* min-height A4 portrait (297mm). On screen we let content grow; print
       handles page breaks via the browser's own pagination. */
    min-height: 297mm;
}

.print-frame__header[b-39ldiimwan] { margin-bottom: 16px; padding-bottom: 12px; border-bottom: 2px solid black; }
.print-frame__body[b-39ldiimwan] { font-size: 0.85rem; line-height: 1.4; }
.print-frame__footer[b-39ldiimwan] { margin-top: 24px; padding-top: 12px; border-top: 1px solid #999; font-size: 0.75rem; }

@media print {
    .print-frame[b-39ldiimwan] { background: white; padding: 0; }
    .print-frame__toolbar[b-39ldiimwan] { display: none; }
    .print-frame__page[b-39ldiimwan] { width: 100%; box-shadow: none; padding: 0; min-height: auto; }
}
/* /Components/Shared/ProcessCard.razor.rz.scp.css */
.process-card[b-q2bwrhfsyv] {
    background: var(--neutral-layer-1);
    border: 1px solid var(--neutral-stroke-rest);
    /* Load-bearing: 4px colored stripe by WO type. The card-color CSS var
       resolves to the right --sa-wo-* token via inline style on host. */
    border-left: 4px solid var(--card-color);
    border-radius: 6px;
    overflow: hidden;
    transition: box-shadow 0.15s ease;
}

.process-card:hover[b-q2bwrhfsyv] {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.process-card__header[b-q2bwrhfsyv] {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 14px 16px;
    background: transparent;
    border: 0;
    cursor: pointer;
    text-align: left;
    color: var(--neutral-foreground-rest);
    font: inherit;
}

.process-card__header:hover[b-q2bwrhfsyv] {
    background: var(--neutral-fill-stealth-hover);
}

.process-card__chevron[b-q2bwrhfsyv] {
    flex-shrink: 0;
    color: var(--neutral-foreground-hint);
    transition: transform 0.15s ease;
}

.process-card__body[b-q2bwrhfsyv] {
    padding: 16px;
    border-top: 1px solid var(--neutral-stroke-rest);
    background: var(--neutral-layer-2);
    /* fade-in matches the JS demo's tab-change animation; a synchronous
       expand reads as snappy enough not to need a height transition. */
    animation: process-card-fade-b-q2bwrhfsyv 0.18s ease-out forwards;
}

@keyframes process-card-fade-b-q2bwrhfsyv {
    from { opacity: 0; transform: translateY(-2px); }
    to { opacity: 1; transform: translateY(0); }
}
/* /Components/Shared/Project/DeliveriesList.razor.rz.scp.css */
.deliveries-head[b-25iik0pbpl] {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 12px;
}

.deliveries-grid[b-25iik0pbpl] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
    gap: 16px;
}

.delivery-card__actions[b-25iik0pbpl] {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 4px;
    padding-top: 8px;
    border-top: 1px solid var(--neutral-stroke-divider-rest);
}

.delivery-card[b-25iik0pbpl] {
    /* Top border accent picks up the next-up color so the eye lands on
       the most-urgent delivery first when scanning. */
    border-top: 3px solid var(--accent-fill-rest);
}

.delivery-card__progress[b-25iik0pbpl] {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.delivery-card__progress-label[b-25iik0pbpl] {
    display: flex;
    justify-content: space-between;
    font-size: 0.8rem;
    color: var(--neutral-foreground-hint);
}
/* /Components/Shared/Project/FinancialsDashboard.razor.rz.scp.css */
.fd-section[b-i07ycvlmpp] {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.fd-h[b-i07ycvlmpp] {
    margin: 0;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--neutral-foreground-rest);
}

.fd-empty[b-i07ycvlmpp] {
    margin: 0;
    color: var(--neutral-foreground-hint);
    font-size: 0.9rem;
}

/* Three-column grid: label | proportional bar | amount. */
.fd-bars[b-i07ycvlmpp] {
    display: grid;
    grid-template-columns: minmax(140px, max-content) 1fr minmax(90px, max-content);
    gap: 8px 12px;
    align-items: center;
}

.fd-bar-label[b-i07ycvlmpp] {
    font-size: 0.85rem;
    color: var(--neutral-foreground-rest);
}

.fd-bar-track[b-i07ycvlmpp] {
    background: var(--neutral-fill-stealth-rest);
    border-radius: 4px;
    height: 14px;
    overflow: hidden;
}

.fd-bar-fill[b-i07ycvlmpp] {
    height: 100%;
    border-radius: 4px;
    min-width: 2px;
}

.fd-bar-amount[b-i07ycvlmpp] {
    font-family: var(--sa-font-mono);
    font-size: 0.82rem;
    text-align: right;
    color: var(--neutral-foreground-rest);
}

.fd-exp[b-i07ycvlmpp] {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
}

.fd-exp th[b-i07ycvlmpp] {
    text-align: left;
    font-weight: 600;
    color: var(--neutral-foreground-hint);
    padding: 4px 8px;
    border-bottom: 1px solid var(--neutral-stroke-rest);
}

.fd-exp td[b-i07ycvlmpp] {
    padding: 4px 8px;
    border-bottom: 1px solid var(--neutral-stroke-divider-rest);
}

.fd-num[b-i07ycvlmpp] {
    text-align: right;
    font-family: var(--sa-font-mono);
}

.fd-add[b-i07ycvlmpp] {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
    margin-top: 8px;
}

.fd-doclink[b-i07ycvlmpp] {
    margin-left: 6px;
    color: var(--accent-fill-rest);
    vertical-align: middle;
}

.fd-docs[b-i07ycvlmpp] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.fd-docs li[b-i07ycvlmpp] {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.85rem;
}

.fd-doc-when[b-i07ycvlmpp] {
    font-family: var(--sa-font-mono);
    font-size: 0.75rem;
    color: var(--neutral-foreground-hint);
}

/* /Components/Shared/Project/NcrsList.razor.rz.scp.css */
.ncr-card[b-p83qmb0qua] {
    /* Left-border severity scale — critical reds itself out hard, major is
       warning-orange, minor stays neutral. Lifted from the JS demo's tone. */
    border-left: 4px solid var(--neutral-stroke-rest);
}

.ncr-card--critical[b-p83qmb0qua] { border-left-color: var(--sa-status-painted); }
.ncr-card--major[b-p83qmb0qua]    { border-left-color: var(--sa-status-fab); }
.ncr-card--minor[b-p83qmb0qua]    { border-left-color: var(--neutral-stroke-rest); }
/* /Components/Shared/Project/ProjectWorkspace.razor.rz.scp.css */
.project-workspace[b-o6nmag2r2t] {
    display: grid;
    grid-template-columns: 220px minmax(0, 1fr);
    gap: 1.5rem;
    align-items: start;
}

.project-workspace__rail[b-o6nmag2r2t] {
    position: sticky;
    top: 1.5rem;
}

.project-workspace__panel[b-o6nmag2r2t] {
    min-width: 0;
    /* @key on the element remounts it on section/detail change; the keyframe
       re-runs to fade the new content in (matches the old tab-body fade).
       OPACITY ONLY — never a transform: a lingering `transform` (even
       translateY(0) from a fill-forwards keyframe) makes this element the
       containing block for `position: fixed`, which trapped + clipped any
       FluentDialog a section component renders inside the panel
       (AssemblyDialog, StartProductionDialog, the WorkOrders dialogs, …). */
    animation: project-panel-in-b-o6nmag2r2t 0.2s ease-out;
    min-height: 200px;
}

@keyframes project-panel-in-b-o6nmag2r2t {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* Stack the rail above the panel on narrower viewports. */
@media (max-width: 1024px) {
    .project-workspace[b-o6nmag2r2t] { grid-template-columns: 1fr; }
    .project-workspace__rail[b-o6nmag2r2t] { position: static; }
}
/* /Components/Shared/Project/UnifiedPartsTable.razor.rz.scp.css */
.unified-parts-table[b-hc0q6zncm7] {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.unified-parts-table__toolbar[b-hc0q6zncm7] {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 12px;
    background: var(--neutral-layer-2);
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 6px;
    /* Slide-in keeps the toolbar from popping the table down on first selection. */
    animation: toolbar-in-b-hc0q6zncm7 0.15s ease-out forwards;
}

@keyframes toolbar-in-b-hc0q6zncm7 {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: translateY(0); }
}

/* Subsection header row above the grid: title + hint on the left,
   action buttons (Recalculate Weights, Add Part) on the right. */
.unified-parts-table__section-header[b-hc0q6zncm7] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    padding: 4px 4px 8px;
}

.unified-parts-table__section-header h3[b-hc0q6zncm7] {
    margin: 0 0 4px;
    font-size: 1.05rem;
}

.unified-parts-table__section-header p[b-hc0q6zncm7] {
    margin: 0;
    color: var(--neutral-foreground-hint);
    font-size: 0.85rem;
}

/* The shared `.parts-grid` table chrome (sticky header, row hover, progress
   cell, etc.) now lives in app.css so the Assemblies table matches the Parts
   table exactly. */
/* /Components/Shared/SkeletonRows.razor.rz.scp.css */
.skeleton-rows[b-f7vw3lfe16] {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 4px 0;
}

.skeleton-rows__header[b-f7vw3lfe16] {
    margin-bottom: 8px;
    border-radius: 4px;
}

.skeleton-rows__row[b-f7vw3lfe16] {
    display: grid;
    /* Same grid template as a typical 6-col data grid; auto-fits to whatever
       container width it lands in. The minmax() guards against squashing
       when the page is narrow. */
    grid-template-columns: repeat(var(--skeleton-cols, 6), minmax(60px, 1fr));
    gap: 12px;
    padding: 8px 0;
    border-bottom: 1px solid var(--neutral-stroke-rest);
}
/* /Components/Shared/StatusPill.razor.rz.scp.css */
/* Tinted pill: 25% background tint, 50% border, full-color text. The
   color-mix() math gives Fluent's Appearance.Tint look without needing a
   custom Fluent token registration. The --pill-color CSS var is set via
   inline style on the host element. */
.status-pill[b-0ixza78o05] {
    display: inline-flex;
    align-items: center;
    padding: 2px 10px;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1.4;
    background: color-mix(in srgb, var(--pill-color) 18%, transparent);
    color: var(--pill-color);
    border: 1px solid color-mix(in srgb, var(--pill-color) 45%, transparent);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
}
/* /Components/Shared/Wizard/WizardElapsed.razor.rz.scp.css */
.wizard-elapsed[b-evlr7pkyfm] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--accent-fill-rest) 12%, transparent);
    color: var(--accent-fill-rest);
    font-size: 0.75rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.wizard-elapsed--slow[b-evlr7pkyfm] {
    background: color-mix(in srgb, var(--sa-status-fab) 18%, transparent);
    color: var(--sa-status-fab);
    border: 1px solid color-mix(in srgb, var(--sa-status-fab) 45%, transparent);
}

.wizard-elapsed__slow-tag[b-evlr7pkyfm] {
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.65rem;
    padding: 1px 6px;
    background: var(--sa-status-fab);
    color: white;
    border-radius: 4px;
}
/* /Components/Shared/Wizard/WizardShell.razor.rz.scp.css */
.wizard-shell[b-m1t7sn7jnd] {
    display: flex;
    flex-direction: column;
    gap: 16px;
    min-height: 320px;
}

.wizard-shell__steps[b-m1t7sn7jnd] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 0 16px 0;
    border-bottom: 1px solid var(--neutral-stroke-rest);
}

.wizard-shell__step[b-m1t7sn7jnd] {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
    min-width: 0;
}

.wizard-shell__step-num[b-m1t7sn7jnd] {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.85rem;
    font-weight: 700;
    background: var(--neutral-fill-stealth-rest);
    color: var(--neutral-foreground-hint);
    border: 2px solid var(--neutral-stroke-rest);
    transition: all 0.15s ease;
}

.wizard-shell__step--active .wizard-shell__step-num[b-m1t7sn7jnd] {
    background: var(--accent-fill-rest);
    color: var(--foreground-on-accent-rest);
    border-color: var(--accent-fill-rest);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent-fill-rest) 18%, transparent);
}

.wizard-shell__step--done .wizard-shell__step-num[b-m1t7sn7jnd] {
    background: var(--sa-status-ready);
    color: white;
    border-color: var(--sa-status-ready);
}

.wizard-shell__step-title[b-m1t7sn7jnd] {
    font-size: 0.875rem;
    color: var(--neutral-foreground-hint);
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.wizard-shell__step--active .wizard-shell__step-title[b-m1t7sn7jnd] {
    color: var(--neutral-foreground-rest);
    font-weight: 600;
}

.wizard-shell__step-rule[b-m1t7sn7jnd] {
    flex: 1;
    height: 2px;
    background: var(--neutral-stroke-rest);
    border-radius: 1px;
}

.wizard-shell__step--done + .wizard-shell__step .wizard-shell__step-rule[b-m1t7sn7jnd],
.wizard-shell__step--done .wizard-shell__step-rule[b-m1t7sn7jnd] {
    background: var(--sa-status-ready);
}

.wizard-shell__body[b-m1t7sn7jnd] {
    flex: 1;
    /* @key on this element forces a clean DOM swap on step change so the
       fade-in animation re-runs every transition. Same idea as the JS
       demo's tab fade. */
    animation: wizard-step-in-b-m1t7sn7jnd 0.2s ease-out forwards;
}

@keyframes wizard-step-in-b-m1t7sn7jnd {
    from { opacity: 0; transform: translateY(4px); }
    to { opacity: 1; transform: translateY(0); }
}

.wizard-shell__footer[b-m1t7sn7jnd] {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
    padding-top: 16px;
    border-top: 1px solid var(--neutral-stroke-rest);
}

/* Mobile "Step N of M · Title" line — hidden on desktop where the full stepper
   labels are readable. */
.wizard-shell__current[b-m1t7sn7jnd] {
    display: none;
}

/* On a phone the inline step titles truncate to single letters ("U. M. S."),
   which is useless. Collapse the rail to a numbered dot-strip and spell the
   current step out underneath instead. */
@media (max-width: 640px) {
    .wizard-shell__steps[b-m1t7sn7jnd] {
        gap: 6px;
        padding: 4px 0 10px 0;
        border-bottom: none;
    }

    .wizard-shell__step-title[b-m1t7sn7jnd] {
        display: none;
    }

    .wizard-shell__step-num[b-m1t7sn7jnd] {
        width: 24px;
        height: 24px;
        font-size: 0.72rem;
    }

    .wizard-shell__current[b-m1t7sn7jnd] {
        display: flex;
        align-items: baseline;
        gap: 8px;
        padding: 0 2px 12px 2px;
        border-bottom: 1px solid var(--neutral-stroke-rest);
    }

    .wizard-shell__current-of[b-m1t7sn7jnd] {
        flex-shrink: 0;
        font-size: 0.72rem;
        font-weight: 700;
        letter-spacing: 0.02em;
        text-transform: uppercase;
        color: var(--accent-fill-rest);
    }

    .wizard-shell__current-title[b-m1t7sn7jnd] {
        font-size: 0.95rem;
        font-weight: 600;
        color: var(--neutral-foreground-rest);
    }
}
