/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
#components-reconnect-modal[b-x67ypxo4x4] {
    display: none;
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1400;
    overflow: hidden;
    background-color: transparent;
    border: none;
    width: 100%;
    max-width: 100%;
    max-height: 100%;
    margin: 0;
    padding: 0;
}

    #components-reconnect-modal[b-x67ypxo4x4]::backdrop {
        background: rgba(10, 16, 28, 0.5);
    }

    #components-reconnect-modal.components-reconnect-show[b-x67ypxo4x4],
    #components-reconnect-modal[open][b-x67ypxo4x4],
    #components-reconnect-modal.components-reconnect-failed[b-x67ypxo4x4],
    #components-reconnect-modal.components-reconnect-repeated-attempt[b-x67ypxo4x4],
    #components-reconnect-modal.components-reconnect-paused[b-x67ypxo4x4],
    #components-reconnect-modal.components-reconnect-resume-failed[b-x67ypxo4x4],
    #components-reconnect-modal.components-pause[b-x67ypxo4x4],
    #components-reconnect-modal.components-resume-failed[b-x67ypxo4x4] {
        display: flex;
        align-items: center;
        justify-content: center;
    }

.components-reconnect-backdrop[b-x67ypxo4x4] {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: radial-gradient(90% 60% at 80% 0%, color-mix(in srgb, var(--mud-palette-primary, #594AE2) 12%, transparent), transparent 60%), radial-gradient(80% 55% at 0% 100%, color-mix(in srgb, var(--mud-palette-info, #2196f3) 16%, transparent), transparent 62%), rgba(8, 12, 20, 0.5);
}

.components-reconnect-surface[b-x67ypxo4x4] {
    width: min(480px, 100%);
    border-radius: var(--mud-default-borderradius, 12px);
    border: 1px solid color-mix(in srgb, var(--mud-palette-lines-default, #e0e0e0) 70%, transparent);
    background: var(--mud-palette-surface, #fff);
    box-shadow: var(--mud-elevation-24, 0 16px 30px rgba(0, 0, 0, 0.28));
    color: var(--mud-palette-text-primary, #1f2937);
    padding: 20px 20px 18px;
}

.components-reconnect-header[b-x67ypxo4x4] {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 8px;
}

    .components-reconnect-header h2[b-x67ypxo4x4] {
        margin: 0;
        font-size: 1.05rem;
        font-weight: 600;
        line-height: 1.3;
    }

.components-reconnect-status-dot[b-x67ypxo4x4] {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--mud-palette-warning, #f59e0b);
    box-shadow: 0 0 0 6px color-mix(in srgb, var(--mud-palette-warning, #f59e0b) 25%, transparent);
}

.components-reconnect-supporting[b-x67ypxo4x4],
.components-reconnect-message[b-x67ypxo4x4] {
    margin: 0;
    line-height: 1.45;
    font-size: 0.95rem;
}

.components-reconnect-supporting[b-x67ypxo4x4] {
    color: var(--mud-palette-text-secondary, #52607a);
    margin-bottom: 14px;
}

.components-reconnect-message[b-x67ypxo4x4] {
    font-weight: 500;
}

.components-reconnect-danger[b-x67ypxo4x4] {
    color: var(--mud-palette-error, #b00020);
}

.components-reconnect-actions[b-x67ypxo4x4] {
    margin-top: 14px;
    display: flex;
    gap: 10px;
    justify-content: flex-end;
}

.components-reconnect-first-attempt-visible[b-x67ypxo4x4],
.components-reconnect-repeated-attempt-visible[b-x67ypxo4x4],
.components-reconnect-failed-visible[b-x67ypxo4x4],
.components-pause-visible[b-x67ypxo4x4],
.components-resume-failed-visible[b-x67ypxo4x4] {
    display: none;
}

dialog[open].components-reconnect-show .components-reconnect-first-attempt-visible[b-x67ypxo4x4] {
    display: block;
}

dialog[open].components-reconnect-show .components-rejoin-loader[b-x67ypxo4x4] {
    display: inline-flex;
}

dialog[open].components-reconnect-failed .components-reconnect-failed-visible[b-x67ypxo4x4] {
    display: block;
}

dialog[open].components-reconnect-failed #components-reconnect-button[b-x67ypxo4x4] {
    display: block;
}

dialog[open].components-reconnect-repeated-attempt .components-reconnect-repeated-attempt-visible[b-x67ypxo4x4] {
    display: block;
}

dialog[open].components-reconnect-repeated-attempt .components-rejoin-loader[b-x67ypxo4x4] {
    display: inline-flex;
}

dialog[open].components-reconnect-paused .components-pause-visible[b-x67ypxo4x4],
dialog[open].components-pause .components-pause-visible[b-x67ypxo4x4] {
    display: block;
}

dialog[open].components-reconnect-paused #components-resume-button[b-x67ypxo4x4],
dialog[open].components-pause #components-resume-button[b-x67ypxo4x4],
dialog[open].components-reconnect-resume-failed #components-resume-button[b-x67ypxo4x4],
dialog[open].components-resume-failed #components-resume-button[b-x67ypxo4x4] {
    display: block;
}

dialog[open].components-reconnect-resume-failed .components-resume-failed-visible[b-x67ypxo4x4],
dialog[open].components-resume-failed .components-resume-failed-visible[b-x67ypxo4x4] {
    display: block;
}

.components-rejoin-loader[b-x67ypxo4x4] {
    display: none;
    margin-bottom: 10px;
    gap: 8px;
}

    .components-rejoin-loader div[b-x67ypxo4x4] {
        width: 9px;
        height: 9px;
        border-radius: 50%;
        background-color: var(--mud-palette-primary, #594AE2);
        animation: reconnect-pulse-b-x67ypxo4x4 1.2s infinite ease-in-out both;
    }

        .components-rejoin-loader div:nth-child(1)[b-x67ypxo4x4] {
            animation-delay: -0.24s;
        }

        .components-rejoin-loader div:nth-child(2)[b-x67ypxo4x4] {
            animation-delay: -0.12s;
        }

@keyframes reconnect-pulse-b-x67ypxo4x4 {
    0%, 80%, 100% {
        transform: scale(0);
    }

    40% {
        transform: scale(1);
    }
}

#components-reconnect-button[b-x67ypxo4x4],
#components-resume-button[b-x67ypxo4x4] {
    display: none;
    min-width: 92px;
    cursor: pointer;
    padding: 8px 16px;
    border: 1px solid transparent;
    border-radius: 999px;
    background-color: var(--mud-palette-primary, #594AE2);
    color: #fff;
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1.2;
    transition: filter 140ms ease, transform 140ms ease;
}

    #components-reconnect-button:hover[b-x67ypxo4x4],
    #components-resume-button:hover[b-x67ypxo4x4] {
        filter: brightness(0.95);
    }

    #components-reconnect-button:active[b-x67ypxo4x4],
    #components-resume-button:active[b-x67ypxo4x4] {
        transform: translateY(1px);
    }

@media (max-width: 600px) {
    .components-reconnect-backdrop[b-x67ypxo4x4] {
        padding: 14px;
    }

    .components-reconnect-surface[b-x67ypxo4x4] {
        padding: 16px;
    }
}
/* /Components/Pages/Billing/Budgets/BudgetEditor.razor.rz.scp.css */
/* The budget editor: its columns and the sum that matters.

   Colour is doing a job here rather than decorating. The spreadsheet this replaces used green,
   red and yellow to say which column a number was in, and a reader who has kept that sheet for
   years reads the colour before the heading. The tints come from the theme's own success, error
   and warning colours, so a theme that recolours the app recolours this with it. */

/* Reached through .pf-budget-editor: the totals are a MudPaper, whose root carries none of this
   file's scope, so a bare .pf-budget-totals rule never applied and the bar scrolled away. */
.pf-budget-editor[b-b5wlqwj9ag]  .pf-budget-totals {
    position: sticky;
    /* Below the app bar, not under it: --pf-appbar-height is what the chrome publishes its own
       height as, so this follows a theme that makes the bar taller. */
    top: calc(var(--pf-appbar-height, 64px) + 8px);
    z-index: 3;
}

.pf-budget-totals-row[b-b5wlqwj9ag] {
    display: flex;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 16px;
}

.pf-budget-total[b-b5wlqwj9ag] {
    display: flex;
    flex-direction: column;
    min-width: 96px;
}

.pf-budget-total-label[b-b5wlqwj9ag] {
    font-size: 11px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

.pf-budget-total-value[b-b5wlqwj9ag] {
    font-size: 1.15rem;
    font-weight: 600;
}

/* The operators are the explanation: income minus expenses minus savings equals surplus. Spelling
   the sum out beats a legend, and it is why the totals sit in a row rather than a grid of cards. */
.pf-budget-op[b-b5wlqwj9ag] {
    font-size: 1.15rem;
    color: var(--mud-palette-text-secondary);
    padding-bottom: 2px;
}

.pf-budget-total.is-surplus[b-b5wlqwj9ag] {
    margin-inline-start: auto;
    text-align: right;
}

/* Debit orders / pay manually / not set, under the sum. */
.pf-budget-payments[b-b5wlqwj9ag] {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 20px;
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px solid var(--mud-palette-lines-default);
    font-size: 13px;
    color: var(--mud-palette-text-secondary);
}

.pf-budget-payment[b-b5wlqwj9ag] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.pf-budget-payment b[b-b5wlqwj9ag] {
    color: var(--mud-palette-text-primary);
}

.pf-budget-payment.is-unset[b-b5wlqwj9ag]  .mud-icon-root {
    opacity: .5;
}

/* ---- the columns ----
   As many as fit at 340px or wider, then wrapping. A fixed three-up grid made sense when there
   were always three; with any number, a breakpoint cannot know how many will be side by side, and
   below about 340px the line names are squeezed out by the amount and the three line controls.
   min(100%, ...) keeps a phone narrower than 340px to one full-width column. */
.pf-budget-columns[b-b5wlqwj9ag] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr));
    gap: 16px;
    align-items: stretch;
}

/* MudPaper is a child component, so its root carries none of this file's scope; reached through
   the grid, which does. */
.pf-budget-columns[b-b5wlqwj9ag]  .pf-budget-col {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.pf-budget-head[b-b5wlqwj9ag] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 4px 6px 14px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

/* The column name is a field, set as a heading: MudBlazor's own underline removed, a dotted one
   in its place like the section names below, so it still says "you can click into this". */
.pf-budget-head[b-b5wlqwj9ag]  .pf-budget-col-name {
    flex: 1;
    min-width: 0;
    margin: 0;
}

.pf-budget-head[b-b5wlqwj9ag]  .pf-budget-col-name .mud-input:before,
.pf-budget-head[b-b5wlqwj9ag]  .pf-budget-col-name .mud-input:after {
    border-bottom: none !important;
}

.pf-budget-head[b-b5wlqwj9ag]  .pf-budget-col-name input {
    padding: 4px 0;
    font-size: .875rem;
    font-weight: 600;
    border-bottom: 1px dotted var(--mud-palette-lines-default);
}

.pf-budget-head[b-b5wlqwj9ag]  .pf-budget-col-name input:focus {
    border-bottom-color: var(--mud-palette-primary);
}

.pf-budget-head[b-b5wlqwj9ag]  .pf-budget-col-total {
    white-space: nowrap;
}

/* color-mix against transparent rather than a fixed pale hex: the same 12% tint then reads
   correctly on a light theme and a dark one, instead of glowing on one of them. */
.pf-budget-head.is-income[b-b5wlqwj9ag] { background: color-mix(in srgb, var(--mud-palette-success) 12%, transparent); }
.pf-budget-head.is-expense[b-b5wlqwj9ag] { background: color-mix(in srgb, var(--mud-palette-error) 12%, transparent); }
.pf-budget-head.is-saving[b-b5wlqwj9ag] { background: color-mix(in srgb, var(--mud-palette-warning) 12%, transparent); }

.pf-budget-lines[b-b5wlqwj9ag] {
    flex: 1;
    padding: 4px 0;
}

.pf-budget-line[b-b5wlqwj9ag] {
    display: grid;
    /* Name takes the room, amount takes what it needs, the remove button takes a fixed corner.
       minmax(0,1fr) rather than 1fr so a long line name shrinks instead of pushing the amount out
       of the card. */
    grid-template-columns: minmax(0, 1fr) 96px 32px 32px;
    gap: 4px;
    align-items: center;
    padding: 0 8px 0 14px;
}

/* Expense and saving columns lead each line with how it is paid. The icon sits in the gutter the
   other columns leave empty, so the names still line up with the column heading. */
.pf-budget-lines.has-payment .pf-budget-line[b-b5wlqwj9ag] {
    grid-template-columns: 26px minmax(0, 1fr) 96px 32px 32px;
    padding-left: 4px;
}

.pf-budget-line[b-b5wlqwj9ag]  .pf-budget-pay .mud-icon-button {
    padding: 3px;
}

.pf-budget-line[b-b5wlqwj9ag]  .pf-budget-pay.is-unset .mud-icon-button {
    opacity: .45;
}

.pf-budget-line[b-b5wlqwj9ag]  .pf-budget-pay.is-unset .mud-icon-button:hover,
.pf-budget-line[b-b5wlqwj9ag]  .pf-budget-pay.is-unset .mud-icon-button:focus-visible {
    opacity: 1;
}

.pf-budget-section[b-b5wlqwj9ag] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    padding: 10px 14px 2px;
    font-size: 11px;
    letter-spacing: .08em;
    text-transform: uppercase;
    font-weight: 600;
    color: var(--mud-palette-text-secondary);
}

/* The group name is editable, so it has to read as a heading while still looking like something
   you can click into. A dotted underline does both: it is quieter than an input's own border, and
   it is the one affordance that survives being set in small caps. */
/* Through .pf-budget-section, a plain element of this page: the field's own root is MudBlazor's
   and carries no scope, so selectors starting at it matched nothing. MudBlazor's underline goes,
   as on the column names, so the dotted one is the only one. */
.pf-budget-section[b-b5wlqwj9ag]  .pf-budget-section-name .mud-input:before,
.pf-budget-section[b-b5wlqwj9ag]  .pf-budget-section-name .mud-input:after {
    border-bottom: none !important;
}

.pf-budget-section[b-b5wlqwj9ag]  .pf-budget-section-name input {
    font-size: 11px;
    letter-spacing: .08em;
    text-transform: uppercase;
    font-weight: 600;
    color: var(--mud-palette-text-secondary);
    border-bottom: 1px dotted var(--mud-palette-lines-default);
}

.pf-budget-section[b-b5wlqwj9ag]  .pf-budget-section-name input:focus {
    border-bottom-color: var(--mud-palette-primary);
}

.pf-budget-empty[b-b5wlqwj9ag] {
    padding: 16px 14px;
    font-size: 13px;
    color: var(--mud-palette-text-secondary);
}

.pf-budget-actions[b-b5wlqwj9ag] {
    display: flex;
    gap: 4px;
    padding: 4px 8px 8px;
    border-top: 1px solid var(--mud-palette-lines-default);
}

/* Amounts line up on their right edge, the way a column of money has to be read. MudBlazor's
   input sets its own alignment, so this has to reach the element itself. */
.pf-budget-line[b-b5wlqwj9ag]  input[type="text"] {
    text-align: inherit;
}

.pf-budget-line[b-b5wlqwj9ag]  .pf-budget-amount input {
    text-align: right;
}

/* The per-group add, inset so it reads as belonging to the group above it rather than to the
   column. Quiet on purpose: it is there when you want it and not competing with the totals. */
.pf-budget-subadd[b-b5wlqwj9ag] {
    padding: 0 8px 4px 22px;
    opacity: .75;
}
/* /Components/Pages/Kitchen/CookTonight.razor.rz.scp.css */
/* What can I cook. Colour carries the verdict here, so it is doing work rather than decorating:
   green is dinner, amber is one item away, and the further bands fade out. All three come from the
   theme's own palette through color-mix, so a recoloured app recolours this with it. */

.pf-cook-head[b-hdjyrpg2i9] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

/* ---- buy one thing ---- */
.pf-cook-unlocks[b-hdjyrpg2i9] {
    background: color-mix(in srgb, var(--mud-palette-info) 7%, transparent);
}

.pf-cook-unlock-row[b-hdjyrpg2i9] {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    padding: 12px 14px;
}

.pf-cook-unlock[b-hdjyrpg2i9] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 12px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--mud-default-borderradius);
    background: var(--mud-palette-surface);
}

.pf-cook-unlock-name[b-hdjyrpg2i9] {
    font-weight: 600;
    font-size: 14px;
}

.pf-cook-unlock-count[b-hdjyrpg2i9] {
    font-size: 11px;
    color: var(--mud-palette-text-secondary);
}

/* ---- bands ---- */
.pf-cook-band[b-hdjyrpg2i9] {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-block: 8px 4px;
}

.pf-cook-band-title[b-hdjyrpg2i9] { font-weight: 700; letter-spacing: .1em; }

.pf-cook-band-title.is-now[b-hdjyrpg2i9] { color: var(--mud-palette-success); }
.pf-cook-band-title.is-one[b-hdjyrpg2i9] { color: var(--mud-palette-warning); }
.pf-cook-band-title.is-few[b-hdjyrpg2i9],
.pf-cook-band-title.is-far[b-hdjyrpg2i9] { color: var(--mud-palette-text-secondary); }

/* ---- cards ---- */
.pf-cook-card[b-hdjyrpg2i9] {
    height: 100%;
    /* A left edge rather than a full tint: the card still has to be readable, and a coloured bar
       reads as a status at a glance without turning the text green. */
    border-inline-start: 3px solid transparent;
    transition: border-color .15s ease;
}

.pf-cook-card.is-now[b-hdjyrpg2i9] { border-inline-start-color: var(--mud-palette-success); }
.pf-cook-card.is-one[b-hdjyrpg2i9] { border-inline-start-color: var(--mud-palette-warning); }
.pf-cook-card.is-few[b-hdjyrpg2i9] { border-inline-start-color: var(--mud-palette-lines-default); }

/* The tail is dimmed rather than hidden: it is still your recipe book, just not tonight's part. */
.pf-cook-card.is-far[b-hdjyrpg2i9] { opacity: .62; }

.pf-cook-meta[b-hdjyrpg2i9] {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-block-start: 8px;
    font-size: 11px;
    color: var(--mud-palette-text-secondary);
}

.pf-cook-missing[b-hdjyrpg2i9] {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-block-start: 10px;
}

.pf-cook-missing-item[b-hdjyrpg2i9] {
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 11px;
    background: color-mix(in srgb, var(--mud-palette-error) 14%, transparent);
    color: var(--mud-palette-text-primary);
}
/* /Components/Pages/Kitchen/Ingredients.razor.rz.scp.css */
/* The catalogue, and the duplicate-spotting panel above it. */

.pf-ing-head[b-edgcv9kpnv] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

/* Tinted with the theme's warning colour rather than its error: two names for one thing is
   untidy, not broken, and the panel should read as a suggestion rather than an alarm. */
.pf-ing-dupes[b-edgcv9kpnv] {
    background: color-mix(in srgb, var(--mud-palette-warning) 8%, transparent);
}

.pf-ing-dupe[b-edgcv9kpnv] {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 8px 14px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.pf-ing-dupe:last-child[b-edgcv9kpnv] { border-bottom: 0; }

.pf-ing-dupe-names[b-edgcv9kpnv] {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    flex: 1;
    min-width: 0;
}

.pf-ing-dupe-name[b-edgcv9kpnv] {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    padding: 3px 10px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--mud-default-borderradius);
    background: var(--mud-palette-surface);
    font-size: 13px;
}

/* The usage count is the tie-breaker when choosing which spelling to keep, so it travels with the
   name rather than sitting in a column somewhere else. */
.pf-ing-dupe-use[b-edgcv9kpnv] {
    font-size: 10px;
    color: var(--mud-palette-text-secondary);
}
/* /Components/Pages/Kitchen/Pantry.razor.rz.scp.css */
/* The cupboard list. Dense on purpose — the whole point is to scan forty names and tap six. */

.pf-pantry-head[b-jl81k0iiho] {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 10px 14px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.pf-pantry-list[b-jl81k0iiho] {
    max-height: 68vh;
    overflow-y: auto;
}

.pf-pantry-row[b-jl81k0iiho] {
    display: grid;
    grid-template-columns: 40px minmax(0, 1fr) auto;
    gap: 8px;
    align-items: center;
    padding: 2px 14px 2px 6px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.pf-pantry-row:last-child[b-jl81k0iiho] { border-bottom: 0; }

/* In stock reads as a state of the row, not as a tick you have to go looking for. Tinted from the
   theme's success colour via color-mix so it lands correctly on light and dark alike. */
.pf-pantry-row.is-in[b-jl81k0iiho] { background: color-mix(in srgb, var(--mud-palette-success) 9%, transparent); }

.pf-pantry-name[b-jl81k0iiho] {
    display: flex;
    flex-direction: column;
    min-width: 0;
    font-size: 14px;
}

.pf-pantry-meta[b-jl81k0iiho] {
    display: flex;
    gap: 6px;
    font-size: 11px;
    color: var(--mud-palette-text-secondary);
}

.pf-pantry-empty[b-jl81k0iiho] {
    padding: 24px 14px;
    text-align: center;
    font-size: 13px;
    color: var(--mud-palette-text-secondary);
}
/* /Components/Pages/Kitchen/Recipes/RecipeEditor.razor.rz.scp.css */
/* The ingredient list: a row per item, laid out as a recipe book writes them — quantity, unit,
   what it is, then how it is prepared. */

.pf-recipe-items[b-id506pp4w9] {
    display: flex;
    flex-direction: column;
    height: 100%;
}

.pf-recipe-head[b-id506pp4w9] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.pf-recipe-lines[b-id506pp4w9] {
    flex: 1;
    padding: 4px 0;
}

.pf-recipe-line[b-id506pp4w9] {
    display: grid;
    /* Quantity and unit are narrow and fixed — they hold "250" and "g", not sentences. The name
       gets the room, the note gets what is left, and the two controls at the end are fixed so the
       rows line up down the column however long the names are. */
    grid-template-columns: 62px 58px minmax(0, 1.4fr) minmax(0, 1fr) 36px 32px;
    gap: 4px;
    align-items: center;
    padding: 0 8px 0 14px;
}

.pf-recipe-empty[b-id506pp4w9] {
    padding: 16px 14px;
    font-size: 13px;
    color: var(--mud-palette-text-secondary);
}

.pf-recipe-actions[b-id506pp4w9] {
    padding: 4px 8px 8px;
    border-top: 1px solid var(--mud-palette-lines-default);
}

/* Quantities read right-aligned, the way any column of numbers does. */
.pf-recipe-line > :first-child[b-id506pp4w9]  input {
    text-align: right;
}

@media (max-width: 959.95px) {
    /* Below md the card is full width but still not wide enough for six columns, so the note and
       the optional flag wrap under the name rather than squeezing it to nothing. */
    .pf-recipe-line[b-id506pp4w9] {
        grid-template-columns: 62px 58px minmax(0, 1fr) 36px 32px;
    }

    .pf-recipe-line > :nth-child(4)[b-id506pp4w9] {
        grid-column: 1 / -1;
        padding-inline-start: 120px;
    }
}
/* /Components/Pages/ThemeAnatomy.razor.rz.scp.css */
/* Theme Anatomy. A property list, a diagram of where those properties land, and a token board for
   the values that have nowhere to land.

   Both drawings paint from --a-* custom properties set in one place on their root (see AppStyle)
   rather than from --mud-palette-*: this page previews a theme that is usually NOT the one the app
   is wearing, and reusing MudBlazor's own variable names inside a page themed by MudBlazor would
   mean redefining them mid-document and fighting the cascade. */

.pf-anat-head[b-8sgso4vkas] {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.pf-anat-filters[b-8sgso4vkas] { padding-block: 4px; }

.pf-anat-sticky[b-8sgso4vkas] {
    position: sticky;
    top: calc(var(--pf-appbar-height, 64px) + 16px);
}

/* ---- property list ---- */
/* A fixed height, not a cap. Pinning a region takes the list from sixty-seven rows to two, and
   with a cap that collapsed the column and moved the diagram beside it 350px up the page — the
   thing you had just clicked jumping out from under the pointer, and a stray mouseenter on
   whatever landed there instead. The panel scrolls inside itself and the page never moves. */
.pf-anat-list[b-8sgso4vkas] {
    height: 62vh;
    overflow-y: auto;
}

.pf-anat-group[b-8sgso4vkas] {
    font-size: 10px;
    letter-spacing: .1em;
    text-transform: uppercase;
    font-weight: 600;
    color: var(--mud-palette-text-secondary);
    padding: 10px 14px 4px;
    background: var(--mud-palette-background-gray);
    position: sticky;
    top: 0;
    z-index: 1;
}

.pf-anat-row[b-8sgso4vkas] {
    display: grid;
    grid-template-columns: 16px minmax(0, 1fr) auto auto;
    gap: 10px;
    align-items: center;
    padding: 6px 14px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
    cursor: default;
}

.pf-anat-row:last-child[b-8sgso4vkas] { border-bottom: 0; }

.pf-anat-row:hover[b-8sgso4vkas],
.pf-anat-row.is-lit[b-8sgso4vkas] { background: var(--mud-palette-action-default-hover); }

.pf-anat-row.is-lit[b-8sgso4vkas] { box-shadow: inset 3px 0 0 var(--mud-palette-primary); }

/* A row this theme gives nothing to do: either nothing on the page can show it, or the layout it
   is wearing does not draw the thing it paints. Dimmed rather than hidden — "your sidebar colour
   does nothing in a top-nav theme" is the answer, and hiding the row would withhold it. */
.pf-anat-row.is-idle .pf-anat-name[b-8sgso4vkas],
.pf-anat-row.is-idle .pf-anat-val[b-8sgso4vkas] { opacity: .55; }

.pf-anat-row.is-idle .pf-anat-sw[b-8sgso4vkas] { opacity: .35; }

/* ---- the type specimen ---- */
.pf-anat-specimen[b-8sgso4vkas] {
    padding: 4px 0;
    border-radius: 0 0 4px 4px;
}

.pf-anat-spec-row[b-8sgso4vkas] {
    display: grid;
    grid-template-columns: 96px minmax(0, 1fr) auto;
    gap: 10px;
    align-items: baseline;
    padding: 6px 14px;
}

.pf-anat-spec-row.is-lit[b-8sgso4vkas] { background: color-mix(in srgb, var(--mud-palette-primary) 16%, transparent); }

.pf-anat-spec-key[b-8sgso4vkas] {
    font-size: 10px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--a-text2);
}

/* The specimen is the one place the drawing must not clip or wrap: a variant set at 6rem has to be
   allowed to look like 6rem, and a line that wrapped would misreport its line height. */
.pf-anat-spec-line[b-8sgso4vkas] {
    color: var(--a-text);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* What a pinned region leaves above the list, and what is there instead when the layer chips have
   filtered every one of its properties away. */
.pf-anat-pin[b-8sgso4vkas] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 14px 4px 10px;
    font-size: 12px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
    background: color-mix(in srgb, var(--mud-palette-primary) 8%, transparent);
}

.pf-anat-none[b-8sgso4vkas] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    padding: 16px 14px;
    font-size: 13px;
    color: var(--mud-palette-text-secondary);
}

.pf-anat-sw[b-8sgso4vkas] {
    inline-size: 16px;
    block-size: 16px;
    border-radius: 4px;
    border: 1px solid var(--mud-palette-lines-default);
    /* An opacity swatch is a tint of the row's own text colour — see Swatch(). */
    color: var(--mud-palette-text-primary);
}

.pf-anat-name[b-8sgso4vkas] { font-size: 13px; min-width: 0; }

.pf-anat-help[b-8sgso4vkas] {
    display: block;
    font-size: 11px;
    color: var(--mud-palette-text-secondary);
    /* Help text is a sentence, not a label: let it wrap rather than clipping mid-word. */
    overflow-wrap: anywhere;
}

.pf-anat-val[b-8sgso4vkas] {
    font-family: var(--mud-typography-caption-family, monospace);
    font-size: 11px;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
}

.pf-anat-tag[b-8sgso4vkas] {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    padding: 2px 6px;
    border-radius: 4px;
    white-space: nowrap;
}

.pf-set[b-8sgso4vkas] { background: var(--mud-palette-primary); color: var(--mud-palette-primary-text); }
.pf-derived[b-8sgso4vkas] { background: var(--mud-palette-tertiary); color: var(--mud-palette-tertiary-text); }
.pf-mud[b-8sgso4vkas] { border: 1px solid var(--mud-palette-lines-default); color: var(--mud-palette-text-secondary); }

/* The settings floor. Drawn like the MudBlazor one because it means the same thing — nobody said
   anything — and differs only in which layer answered, which the word on the chip carries. */
.pf-app[b-8sgso4vkas] { border: 1px solid var(--mud-palette-lines-default); color: var(--mud-palette-text-secondary); }

/* ---- shared drawing rules ---- */
.pf-anat-app[b-8sgso4vkas],
.pf-anat-board[b-8sgso4vkas] {
    background: var(--a-bg);
    color: var(--a-text);
    font-size: 12.5px;
}

.pf-anat-app[b-8sgso4vkas] { border-radius: 0 0 4px 4px; overflow: hidden; }
.pf-anat-board[b-8sgso4vkas] { border-radius: 0 0 4px 4px; padding: 14px; display: grid; gap: 14px; }

.pf-anat-app [class*="pf-anat-"][b-8sgso4vkas],
.pf-anat-board [class*="pf-anat-"][b-8sgso4vkas] { position: relative; }

/* Every region is clickable: a click pins it and the property list narrows to what paints it. */
.pf-anat-z[b-8sgso4vkas] { cursor: pointer; }

/* A region is reachable by keyboard too, so it needs a ring that does not depend on the circuit.
   Focus also lights it through the server, but that is a round trip later and the ring must be
   there the instant the caret lands. Outside the box rather than inset, so it cannot be confused
   with the lit ring drawn within. */
.pf-anat-z:focus-visible[b-8sgso4vkas] {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
    z-index: 4;
}

/* One highlight treatment everywhere, so "lit" reads the same wherever it appears. Pinned is in
   this list too rather than riding on .is-lit: hovering another region takes the lit class off the
   pinned one, and a pin you cannot see while you look around is not a pin. */
.pf-anat-app .is-lit[b-8sgso4vkas]::after,
.pf-anat-app .is-pinned[b-8sgso4vkas]::after,
.pf-anat-board .is-lit[b-8sgso4vkas]::after,
.pf-anat-board .is-pinned[b-8sgso4vkas]::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: -2px;
    background: color-mix(in srgb, var(--mud-palette-primary) 16%, transparent);
    border-radius: inherit;
    z-index: 3;
}

/* Pinned is lit, turned up: the same treatment rather than a second vocabulary, because it is the
   same statement — this is the region being answered about — just one that stays. Must follow the
   rule above, which it matches for specificity. */
.pf-anat-app .is-pinned[b-8sgso4vkas]::after,
.pf-anat-board .is-pinned[b-8sgso4vkas]::after {
    outline-width: 3px;
    background: color-mix(in srgb, var(--mud-palette-primary) 28%, transparent);
}

/* ---- the app mock ---- */
/* A hairline is one property's work, so it is drawn as its own element rather than as a border on
   whatever it runs along — otherwise hovering "Lines" would light the bar, which AppbarBackground
   fills. content-box plus a transparent border gives a 7px hit area around a 1px line, and the
   negative margin keeps that padding out of the layout. */
.pf-anat-bar-edge[b-8sgso4vkas],
.pf-anat-side-edge[b-8sgso4vkas],
.pf-anat-table-rule[b-8sgso4vkas] {
    box-sizing: content-box;
    background-clip: content-box;
}

.pf-anat-bar-edge[b-8sgso4vkas] {
    position: absolute;
    inset-inline: 0;
    inset-block-end: 0;
    block-size: 1px;
    background-color: var(--a-lines);
    border-block: 3px solid transparent;
    margin-block-end: -3px;
}

.pf-anat-side-edge[b-8sgso4vkas] {
    position: absolute;
    inset-block: 0;
    inset-inline-end: 0;
    inline-size: 1px;
    background-color: var(--a-lines);
    border-inline: 3px solid transparent;
    margin-inline-end: -3px;
}

/* The drawing is roughly a third scale, so the theme's real dimensions are scaled rather than used.
   The factors are chosen so the shipped defaults land on the sizes this mock was drawn at — 64px of
   bar becomes 44, 240px of drawer becomes 136 — which means a theme that changes neither looks
   exactly as it always did, and one that does is visibly taller or wider by the right proportion. */
.pf-anat-appbar[b-8sgso4vkas] {
    block-size: calc(var(--a-bar-px, 64px) * 0.6875);
    background: var(--a-appbar);
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 12px;
}

.pf-anat-brand[b-8sgso4vkas] { font-weight: 600; }
.pf-anat-bar-text[b-8sgso4vkas] { color: var(--a-text); }
.pf-anat-spacer[b-8sgso4vkas] { margin-left: auto; }

.pf-anat-bar-icon[b-8sgso4vkas] {
    inline-size: 14px;
    block-size: 14px;
    border-radius: 3px;
    background: var(--a-action);
}

.pf-anat-avatar[b-8sgso4vkas] {
    inline-size: 26px;
    block-size: 26px;
    border-radius: 50%;
    background: var(--a-primary);
    color: var(--a-on-primary);
    display: grid;
    place-items: center;
    font-size: 10px;
    font-weight: 600;
}

.pf-anat-body[b-8sgso4vkas] { display: flex; min-block-size: 420px; }

.pf-anat-side[b-8sgso4vkas] {
    inline-size: calc(var(--a-drawer-px, 240px) * 0.567);
    flex: 0 0 auto;
    background: var(--a-drawer);
    padding: 8px 6px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.pf-anat-nav[b-8sgso4vkas] {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: var(--a-radius);
    font-size: 12px;
    color: var(--a-drawer-text);
}

.pf-anat-nav i[b-8sgso4vkas],
.pf-anat-nav-icon[b-8sgso4vkas] {
    inline-size: 12px;
    block-size: 12px;
    border-radius: 3px;
    background: var(--a-drawer-icon);
    flex: 0 0 auto;
}

.pf-anat-nav-text[b-8sgso4vkas] { color: var(--a-drawer-text); }

/* The active item — the primary's work, not the drawer's. */
.pf-anat-nav-active[b-8sgso4vkas] {
    background: color-mix(in srgb, var(--a-primary) 15%, transparent);
    color: var(--a-primary);
    font-weight: 500;
}

.pf-anat-nav-active i[b-8sgso4vkas] { background: var(--a-primary); }

/* The hover tint MudBlazor derives: the action colour at the hover opacity. */
.pf-anat-hover[b-8sgso4vkas] { background: color-mix(in srgb, var(--a-action) var(--a-hover-op), transparent); }

.pf-anat-divider[b-8sgso4vkas] {
    block-size: 1px;
    background: var(--a-divider);
    margin: 6px 8px;
    border-radius: 0;
}

.pf-anat-page[b-8sgso4vkas] { flex: 1 1 auto; padding: 12px; min-inline-size: 0; color: var(--a-text); }
.pf-anat-h4[b-8sgso4vkas] { font-size: 18px; font-weight: 600; }
.pf-anat-page-text[b-8sgso4vkas] { color: var(--a-text); }
.pf-anat-sub[b-8sgso4vkas] { font-size: 11.5px; margin-block-start: 2px; }
.pf-anat-page-text2[b-8sgso4vkas] { color: var(--a-text2); }

.pf-anat-tiles[b-8sgso4vkas] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    margin-block-start: 12px;
}

.pf-anat-surface[b-8sgso4vkas] {
    background: var(--a-surface);
    border: 1px solid var(--a-lines);
    border-radius: var(--a-radius);
    padding: 8px 10px;
}

.pf-anat-cap[b-8sgso4vkas] { font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--a-text2); }
.pf-anat-num[b-8sgso4vkas] { font-size: 18px; font-weight: 600; font-variant-numeric: tabular-nums; }

.pf-anat-btns[b-8sgso4vkas] { display: flex; gap: 6px; flex-wrap: wrap; margin-block-start: 12px; }

.pf-anat-btns > span[b-8sgso4vkas] {
    font-size: 11.5px;
    font-weight: 500;
    padding: 5px 11px;
    border-radius: var(--a-radius);
}

.pf-anat-primary[b-8sgso4vkas] { background: var(--a-primary); color: var(--a-on-primary); }
.pf-anat-secondary[b-8sgso4vkas] { background: var(--a-secondary); color: var(--a-on-secondary); }
.pf-anat-tertiary[b-8sgso4vkas] { background: var(--a-tertiary); color: var(--a-on-tertiary); }
.pf-anat-error[b-8sgso4vkas] { background: var(--a-error); color: var(--a-on-error); }
.pf-anat-neutral[b-8sgso4vkas] { background: var(--a-neutral); color: var(--a-on-neutral); }
.pf-anat-disabled[b-8sgso4vkas] { background: var(--a-disabled-bg); }
.pf-anat-disabled-text[b-8sgso4vkas] { color: var(--a-disabled); }

/* Border opacity is an alpha, so it shows as the strength of an outline rather than as a fill. */
.pf-anat-border[b-8sgso4vkas] {
    background: transparent;
    color: var(--a-primary);
    border: 2px solid color-mix(in srgb, var(--a-primary) var(--a-border-op), transparent);
}

.pf-anat-ripple[b-8sgso4vkas] { background: color-mix(in srgb, var(--a-action) var(--a-ripple-op), transparent); }

.pf-anat-ripple-fill[b-8sgso4vkas] {
    background: var(--a-primary);
    color: var(--a-on-primary);
    overflow: hidden;
}

/* The ripple where it lands on a filled button: white at the secondary ripple opacity. */
.pf-anat-ripple-fill[b-8sgso4vkas]::before {
    content: "";
    position: absolute;
    inset-inline-start: 6px;
    inset-block-start: 50%;
    translate: 0 -50%;
    inline-size: 26px;
    block-size: 26px;
    border-radius: 50%;
    background: rgb(255 255 255 / var(--a-ripple-fill-op));
}

.pf-anat-field[b-8sgso4vkas] {
    margin-block-start: 12px;
    max-inline-size: 220px;
    border: 1px solid var(--a-lines-inputs);
    border-radius: var(--a-radius);
    padding: 6px 9px;
    font-size: 11.5px;
}

.pf-anat-field-text[b-8sgso4vkas] { color: var(--a-text-disabled); }

.pf-anat-alerts[b-8sgso4vkas] { display: grid; gap: 6px; margin-block-start: 12px; }

.pf-anat-success[b-8sgso4vkas],
.pf-anat-warning[b-8sgso4vkas],
.pf-anat-info[b-8sgso4vkas] {
    border-radius: var(--a-radius);
    padding: 6px 10px;
    font-size: 11.5px;
}

.pf-anat-success[b-8sgso4vkas] { background: var(--a-success); color: var(--a-on-success); }
.pf-anat-warning[b-8sgso4vkas] { background: var(--a-warning); color: var(--a-on-warning); }
.pf-anat-info[b-8sgso4vkas] { background: var(--a-info); color: var(--a-on-info); }

.pf-anat-table[b-8sgso4vkas] {
    margin-block-start: 12px;
    background: var(--a-surface);
    border: 1px solid var(--a-lines);
    border-radius: var(--a-radius);
    overflow: hidden;
}

.pf-anat-tr[b-8sgso4vkas] {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 6px 10px;
    border-bottom: 1px solid var(--a-table-lines);
    font-size: 11.5px;
}

.pf-anat-tr:last-child[b-8sgso4vkas] { border-bottom: 0; }

/* The rule element stands in for the border of the row above it, so that row drops its own —
   otherwise the table would draw two lines a pixel apart. */
.pf-anat-tr:has(+ .pf-anat-table-rule)[b-8sgso4vkas] { border-bottom: 0; }

.pf-anat-table-rule[b-8sgso4vkas] {
    block-size: 1px;
    background-color: var(--a-table-lines);
    border-block: 4px solid transparent;
    margin-block: -4px;
    position: relative;
    z-index: 1;
}

.pf-anat-table-stripe[b-8sgso4vkas] { background: var(--a-stripe); }
.pf-anat-table-hover[b-8sgso4vkas] { background: var(--a-table-hover); }

.pf-anat-tr.is-head[b-8sgso4vkas] {
    font-size: 9.5px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--a-text2);
    font-weight: 600;
}

/* ---- the token board ---- */
.pf-anat-tokengroup[b-8sgso4vkas] { display: grid; gap: 5px; min-width: 0; }

.pf-anat-tokenlabel[b-8sgso4vkas] {
    font-size: 9.5px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--a-text2);
    font-weight: 600;
}

.pf-anat-tokenrow[b-8sgso4vkas] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
}

.pf-anat-greys[b-8sgso4vkas] {
    display: flex;
    border-radius: var(--a-radius);
    overflow: hidden;
    border: 1px solid var(--a-lines);
}

.pf-anat-step[b-8sgso4vkas] { flex: 1 1 0; min-inline-size: 0; block-size: 34px; }

.pf-anat-backgroundgray[b-8sgso4vkas] {
    block-size: 62px;
    background: var(--a-bg-gray);
    border: 1px solid var(--a-lines);
    border-radius: var(--a-radius);
}

.pf-anat-skeleton[b-8sgso4vkas] {
    block-size: 62px;
    border: 1px solid var(--a-lines);
    border-radius: var(--a-radius);
    padding: 10px;
    display: grid;
    gap: 7px;
    align-content: start;
}

.pf-anat-skeleton > span[b-8sgso4vkas] {
    block-size: 9px;
    border-radius: 4px;
    background: var(--a-skeleton);
}

.pf-anat-skeleton > span:nth-child(2)[b-8sgso4vkas] { inline-size: 72%; }
.pf-anat-skeleton > span:nth-child(3)[b-8sgso4vkas] { inline-size: 45%; }

/* The scrims need a ground of their own to sit over: an overlay drawn on the page's own background
   shows nothing, which is the whole reason these two are hard to judge in a list. */
.pf-anat-scrimbase[b-8sgso4vkas] {
    block-size: 62px;
    border-radius: var(--a-radius);
    border: 1px solid var(--a-lines);
    overflow: hidden;
}

.pf-anat-scrimbase.is-light[b-8sgso4vkas] { background: #fff; }
.pf-anat-scrimbase.is-dark[b-8sgso4vkas] { background: #1b1b1f; }

.pf-anat-overlay-dark[b-8sgso4vkas],
.pf-anat-overlay-light[b-8sgso4vkas] {
    block-size: 100%;
    display: grid;
    place-items: center;
    font-size: 10px;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.pf-anat-overlay-dark[b-8sgso4vkas] { background: var(--a-overlay-dark); color: #fff; }
.pf-anat-overlay-light[b-8sgso4vkas] { background: var(--a-overlay-light); color: #1b1b1f; }

/* Below the md breakpoint the grid has already stacked the drawing under the list, so it only has
   to stop the sidebar squeezing the page to nothing. */
@media (max-width: 599px) {
    .pf-anat-side[b-8sgso4vkas] { inline-size: 64px; }
    .pf-anat-nav[b-8sgso4vkas], .pf-anat-hover[b-8sgso4vkas] { font-size: 0; gap: 0; justify-content: center; }
    .pf-anat-tiles[b-8sgso4vkas], .pf-anat-tokenrow[b-8sgso4vkas] { grid-template-columns: 1fr; }
}

/* ---- the three layouts ----
   The drawing wears whichever chrome the theme does, because the alternative is drawing a sidebar
   for a theme that has none and letting six palette properties claim to paint it. */

/* Mini rail: the same drawer, narrower, with the brand living in it rather than in the bar. Not a
   separate structure — a rail is still a drawer, so every drawer property still has somewhere to
   land, and only the width changes. */
.pf-anat-app.is-rail .pf-anat-side[b-8sgso4vkas] {
    inline-size: calc(var(--a-drawer-px, 240px) * 0.36);
}

.pf-anat-app.is-rail .pf-anat-nav[b-8sgso4vkas] { font-size: 11px; }

/* Top navigation: no drawer at all. The nav moves into the bar as plain bar content, deliberately
   not tagged as regions — it is painted by the bar's own text colour, and the drawer properties
   that would otherwise claim it are precisely the ones this layout leaves with nothing to do. */
.pf-anat-topnav[b-8sgso4vkas] {
    font-size: 11px;
    opacity: .85;
    white-space: nowrap;
}

.pf-anat-app.is-topnav .pf-anat-body[b-8sgso4vkas] { display: block; }
