/* /Components/Avatar.razor.rz.scp.css */
.lk-avatar[b-qhpphv986s] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: var(--lk-avatar-size);
    height: var(--lk-avatar-size);
    border-radius: var(--lk-radius-pill);
    font-family: var(--lk-font-display);
    font-weight: 700;
    font-size: calc(var(--lk-avatar-size) * 0.36);
    letter-spacing: 0.0125em;
    user-select: none;
}

.lk-avatar-neutral[b-qhpphv986s] {
    background: var(--lk-navy-soft);
    color: var(--lk-ink);
}

.lk-avatar-accent[b-qhpphv986s] {
    background: var(--lk-magenta-soft);
    color: var(--lk-magenta-ink);
}
/* /Components/Badge.razor.rz.scp.css */
.lk-badge[b-4d36yz96f1] {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    min-height: 1.5rem;
    padding: 0.125rem 0.625rem;
    border-radius: var(--lk-radius-pill);
    font-family: var(--lk-font-ui);
    font-weight: 600;
    font-size: 0.75rem;
    line-height: 1.3;
}

.lk-badge-dot[b-4d36yz96f1] {
    flex: 0 0 auto;
    width: 0.375rem;
    height: 0.375rem;
    border-radius: var(--lk-radius-pill);
    background: currentColor;
}

.lk-badge-neutral[b-4d36yz96f1] {
    background: var(--lk-navy-soft);
    color: var(--lk-text-sec);
}

.lk-badge-ok[b-4d36yz96f1] {
    background: var(--lk-ok-soft);
    color: var(--lk-ok);
}

.lk-badge-warn[b-4d36yz96f1] {
    background: var(--lk-warn-soft);
    color: var(--lk-warn);
}

.lk-badge-error[b-4d36yz96f1] {
    background: var(--lk-err-soft);
    color: var(--lk-err);
}

.lk-badge-info[b-4d36yz96f1] {
    background: var(--lk-info-soft);
    color: var(--lk-info);
}

.lk-badge-accent[b-4d36yz96f1] {
    background: var(--lk-magenta-soft);
    color: var(--lk-magenta-ink);
}
/* /Components/BankIdGlyph.razor.rz.scp.css */
.lk-bankid[b-1pzepbe9xq] {
    display: block;
    flex: 0 0 auto;
    width: var(--lk-bankid-size, 1.25rem);
    /* 20 by 19 in the original, so the height follows rather than being set. */
    height: auto;
}
/* /Components/Button.razor.rz.scp.css */
.lk-button[b-l9e0sq8dmx] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5625rem;
    box-sizing: border-box;
    border-radius: var(--lk-radius-control);
    border: var(--lk-border-width) solid transparent;
    font-family: var(--lk-font-ui);
    font-weight: 600;
    letter-spacing: 0.00625em;
    cursor: pointer;
    user-select: none;
    /* The label may wrap in a language with longer words — Finnish especially — but the
       button must not collapse. Height grows instead of text being cut off (ADR 0002). */
    text-align: center;
    transition: background var(--lk-transition), border-color var(--lk-transition), color var(--lk-transition), box-shadow var(--lk-transition);
}

.lk-button-label[b-l9e0sq8dmx] {
    min-width: 0;
}

.lk-button-full[b-l9e0sq8dmx] {
    display: flex;
    width: 100%;
}

/* Square, with the padding removed so the icon sits in the middle. */
.lk-button-icon-only[b-l9e0sq8dmx] {
    padding: 0;
    aspect-ratio: 1;
}

.lk-button-icon-only.lk-button-small[b-l9e0sq8dmx] {
    width: var(--lk-control-height-sm);
}

.lk-button-icon-only.lk-button-medium[b-l9e0sq8dmx] {
    width: var(--lk-control-height-md);
}

.lk-button-icon-only.lk-button-large[b-l9e0sq8dmx] {
    width: var(--lk-control-height-lg);
}

/* ── Sizes ──────────────────────────────────────────────── */

.lk-button-small[b-l9e0sq8dmx] {
    min-height: var(--lk-control-height-sm);
    padding: 0 var(--lk-control-padding-sm);
    font-size: var(--lk-font-size-label);
}

.lk-button-medium[b-l9e0sq8dmx] {
    min-height: var(--lk-control-height-md);
    padding: 0 var(--lk-control-padding-md);
    font-size: var(--lk-font-size-ui);
}

.lk-button-large[b-l9e0sq8dmx] {
    min-height: var(--lk-control-height-lg);
    padding: 0 var(--lk-control-padding-lg);
    font-size: 0.969rem;
}

/* ── Variants ───────────────────────────────────────────── */

.lk-button-primary[b-l9e0sq8dmx] {
    background: var(--lk-navy);
    color: var(--lk-navy-contrast);
    border-color: var(--lk-navy);
}

.lk-button-primary:hover:not(:disabled)[b-l9e0sq8dmx] {
    background: var(--lk-navy-hover);
    border-color: var(--lk-navy-hover);
}

.lk-button-accent[b-l9e0sq8dmx] {
    background: var(--lk-magenta);
    color: var(--lk-magenta-contrast);
    border-color: var(--lk-magenta);
}

.lk-button-accent:hover:not(:disabled)[b-l9e0sq8dmx] {
    background: var(--lk-magenta-hover);
    border-color: var(--lk-magenta-hover);
}

.lk-button-secondary[b-l9e0sq8dmx] {
    background: var(--lk-surface);
    color: var(--lk-ink);
    border-color: var(--lk-line-strong);
}

.lk-button-secondary:hover:not(:disabled)[b-l9e0sq8dmx] {
    background: var(--lk-surface-alt);
}

.lk-button-secondary:active:not(:disabled)[b-l9e0sq8dmx] {
    background: var(--lk-sunken);
}

.lk-button-ghost[b-l9e0sq8dmx] {
    background: transparent;
    color: var(--lk-ink);
    border-color: transparent;
}

.lk-button-ghost:hover:not(:disabled)[b-l9e0sq8dmx] {
    background: var(--lk-ghost-hover);
}

.lk-button-ghost:active:not(:disabled)[b-l9e0sq8dmx] {
    background: var(--lk-sunken);
}

.lk-button-danger[b-l9e0sq8dmx] {
    background: var(--lk-err-soft);
    color: var(--lk-err);
    border-color: transparent;
}

.lk-button-danger:hover:not(:disabled)[b-l9e0sq8dmx],
.lk-button-danger:active:not(:disabled)[b-l9e0sq8dmx] {
    background: var(--lk-err);
    /* On the solid error surface the label flips to the color that pairs with a strong
       fill, which is the same one the accent button uses. */
    color: var(--lk-magenta-contrast);
}

/* ── States ─────────────────────────────────────────────── */

/* focus-visible rather than focus: the keyboard user needs the ring, the mouse user
   should not get one after every click (ADR 0007). */
.lk-button:focus-visible[b-l9e0sq8dmx] {
    outline: none;
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-focus);
}

.lk-button:disabled[b-l9e0sq8dmx] {
    opacity: 0.45;
    cursor: not-allowed;
}

.lk-button[aria-busy="true"][b-l9e0sq8dmx] {
    /* Waiting is not the same as unavailable, so it keeps full contrast. */
    opacity: 1;
    cursor: progress;
}
/* /Components/Card.razor.rz.scp.css */
.lk-card[b-27ecwn1k71] {
    box-sizing: border-box;
    background: var(--lk-surface);
    border: var(--lk-border-hairline) solid var(--lk-line);
    border-radius: var(--lk-radius-card);
    box-shadow: var(--lk-shadow-sm);
}

.lk-card-padded[b-27ecwn1k71] {
    padding: var(--lk-space-5);
}

.lk-card-elevated[b-27ecwn1k71] {
    box-shadow: var(--lk-shadow-md);
}
/* /Components/CardHeader.razor.rz.scp.css */
/*
    The design's .card-head: a row across the top of a card, with a rule under it.

    It reaches the card's edges, so the card it sits in must be Card Padded="false" and the
    card's body must carry its own padding. That is how the design builds these — .card without
    .pad, a head with its own padding, a body with its own — and it is what makes the rule span
    the full width instead of stopping short of it.
*/
.lk-card-head[b-m6teou5kwl] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
}

/* The design's 16/20/14, rounded to the spacing scale (#528). Only when the head pads itself —
   inside an already-padded card it would be padding twice. */
.lk-card-head-inset[b-m6teou5kwl] {
    padding: var(--lk-space-4) var(--lk-space-5) var(--lk-space-3);
}

/* Space under a head that has no rule and no padding of its own, so the body does not start
   against the heading. */
.lk-card-head:not(.lk-card-head-inset)[b-m6teou5kwl] {
    margin-bottom: var(--lk-space-4);
}

.lk-card-head-divided[b-m6teou5kwl] {
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
}

/*
    15.5px in the design, not the 26px a page title takes. line-height: normal rather than the
    body's 1.6 for the reason the overview's panel heading records: 1.6 made the row taller than
    the design's and put the whole header block on a different rhythm.
*/
/* The text block takes the row's spare width, so title and subtitle stack while the icon and
   the actions keep their size. */
.lk-card-head-text[b-m6teou5kwl] {
    flex: 1;
    min-width: 0;
}

.lk-card-head-title[b-m6teou5kwl] {
    margin: 0;
    font-family: var(--lk-font-display);
    font-weight: 700;
    font-size: var(--lk-font-size-card-title);
    line-height: normal;
    color: var(--lk-ink);
}

.lk-card-head-subtitle[b-m6teou5kwl] {
    margin: var(--lk-space-1) 0 0;
    font-size: var(--lk-font-size-label);
    line-height: normal;
    color: var(--lk-text-sec);
}

/* Aligns with the title rather than the middle of a two-line text block. */
.lk-card-head:has(.lk-card-head-subtitle)[b-m6teou5kwl] {
    align-items: flex-start;
}

/* The icon takes the row's colour by default; the tone below overrides it. */
.lk-card-head-icon[b-m6teou5kwl] {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    color: var(--lk-ink);
}

.lk-card-head-icon-accent[b-m6teou5kwl] {
    color: var(--lk-magenta-ink);
}

.lk-card-head-actions[b-m6teou5kwl] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
    flex: 0 0 auto;
}
/* /Components/Checkbox.razor.rz.scp.css */
.lk-checkbox[b-r7a4xajjzv] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 1.25rem;
    height: 1.25rem;
    padding: 0;
    background: var(--lk-surface);
    border: var(--lk-border-width) solid var(--lk-line-strong);
    border-radius: var(--lk-radius-checkbox);
    cursor: pointer;
    transition: background var(--lk-transition), border-color var(--lk-transition);
}

.lk-checkbox-checked[b-r7a4xajjzv],
.lk-checkbox-mixed[b-r7a4xajjzv] {
    background: var(--lk-navy);
    border-color: var(--lk-navy);
}

.lk-checkbox:disabled[b-r7a4xajjzv] {
    opacity: 0.5;
    cursor: not-allowed;
}

.lk-checkbox:focus-visible[b-r7a4xajjzv] {
    outline: none;
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-focus);
}

.lk-checkbox-dash[b-r7a4xajjzv] {
    width: 0.5625rem;
    height: 0.125rem;
    border-radius: 0.125rem;
    background: var(--lk-navy-contrast);
}

/* The tick belongs to the Icon component's markup, so reaching it needs ::deep. */
[b-r7a4xajjzv] .lk-checkbox-tick {
    color: var(--lk-navy-contrast);
}

/* ── The box with its label ─────────────────────────────── */

/*
    Rendered whether or not there is a label, so the component has one shape. With no label it
    contains the button alone and lays out exactly as the bare button did.
*/
.lk-checkbox-field[b-r7a4xajjzv] {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

/*
    Clickable, so the words are part of the target the way a native label's are. The cursor says
    so, and the text does not select on a double click that was meant as two ticks.
*/
.lk-checkbox-text[b-r7a4xajjzv] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    line-height: var(--lk-line-height-body);
    color: var(--lk-text);
    cursor: pointer;
    user-select: none;
}

/* Disabled is the button's state, and the label has to follow it or it invites a click that
   does nothing. :has so the rule stays with the box that owns the state. */
.lk-checkbox-field:has(.lk-checkbox:disabled) .lk-checkbox-text[b-r7a4xajjzv] {
    opacity: 0.5;
    cursor: not-allowed;
}
/* /Components/Dialog.razor.rz.scp.css */
/* The element itself is only the box. It carries no padding or background, so the panel
   inside can scroll while the header and footer stay put. */
.lk-dialog[b-iu68ykzdbk] {
    box-sizing: border-box;
    width: calc(100vw - var(--lk-space-8));
    max-height: calc(100vh - var(--lk-space-10));
    padding: 0;
    background: transparent;
    border: 0;
    overflow: hidden;
}

.lk-dialog-narrow[b-iu68ykzdbk] {
    max-width: 24rem;
}

.lk-dialog-medium[b-iu68ykzdbk] {
    max-width: 32rem;
}

.lk-dialog-wide[b-iu68ykzdbk] {
    max-width: 48rem;
}

/* The same scrim as the reconnect overlay in app.css, which is the portal's only other
   full-screen dimming and the precedent worth matching. It is not a theme token because
   it has to read as "behind" in both themes, and a token would invite two values. */
.lk-dialog[b-iu68ykzdbk]::backdrop {
    background: rgb(0 0 0 / 45%);
}

.lk-dialog-panel[b-iu68ykzdbk] {
    display: flex;
    flex-direction: column;
    /* Inherited from the element, so the panel can never be taller than the viewport. */
    max-height: inherit;
    background: var(--lk-surface);
    border: var(--lk-border-hairline) solid var(--lk-line);
    border-radius: var(--lk-radius-card);
    box-shadow: var(--lk-shadow-lg);
}

.lk-dialog-head[b-iu68ykzdbk] {
    display: flex;
    align-items: flex-start;
    gap: var(--lk-space-4);
    flex: 0 0 auto;
    padding: var(--lk-space-5) var(--lk-space-5) var(--lk-space-4);
}

.lk-dialog-heading[b-iu68ykzdbk] {
    flex: 1;
    min-width: 0;
}

.lk-dialog-title[b-iu68ykzdbk] {
    margin: 0;
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-title);
    line-height: var(--lk-line-height-tight);
    color: var(--lk-ink);
}

.lk-dialog-subtitle[b-iu68ykzdbk] {
    margin: var(--lk-space-2) 0 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    line-height: var(--lk-line-height-body);
    color: var(--lk-text-mut);
}

.lk-dialog-head[b-iu68ykzdbk]  .lk-dialog-close {
    flex: 0 0 auto;
    /* Pulled back so the icon lines up with the panel's edge rather than the button's box. */
    margin: calc(var(--lk-space-1) * -1) calc(var(--lk-space-2) * -1) 0 0;
}

/* The only part that scrolls. A long form keeps its title and its buttons in view. */
.lk-dialog-body[b-iu68ykzdbk] {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 0 var(--lk-space-5) var(--lk-space-5);
}

.lk-dialog-foot[b-iu68ykzdbk] {
    display: flex;
    justify-content: flex-end;
    gap: var(--lk-space-3);
    flex: 0 0 auto;
    padding: var(--lk-space-4) var(--lk-space-5);
    background: var(--lk-surface-alt);
    border-top: var(--lk-border-hairline) solid var(--lk-line);
    border-radius: 0 0 var(--lk-radius-card) var(--lk-radius-card);
}

/* Narrow screens: the dialog sits at the bottom, where a thumb reaches, and gives up its
   bottom corners to sit flush with the edge. */
@media (max-width: 30rem) {
    .lk-dialog[b-iu68ykzdbk] {
        width: 100vw;
        max-width: none;
        max-height: 90vh;
        margin: auto auto 0;
    }

    .lk-dialog-panel[b-iu68ykzdbk] {
        border-radius: var(--lk-radius-card) var(--lk-radius-card) 0 0;
    }

    .lk-dialog-foot[b-iu68ykzdbk] {
        border-radius: 0;
    }
}
/* /Components/EmptyState.razor.rz.scp.css */
.lk-empty[b-c4mposjmk4] {
    max-width: 23.75rem;
    margin: 0 auto;
    padding: var(--lk-space-12) var(--lk-space-6);
    text-align: center;
}

.lk-empty-mark[b-c4mposjmk4] {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3.75rem;
    height: 3.75rem;
    margin: 0 auto var(--lk-space-4);
    border-radius: var(--lk-radius-tile);
    background: var(--lk-navy-soft);
    color: var(--lk-text-sec);
}

.lk-empty-title[b-c4mposjmk4] {
    margin: 0 0 var(--lk-space-2);
    font-family: var(--lk-font-display);
    font-weight: 700;
    font-size: 1.125rem;
    color: var(--lk-ink);
}

.lk-empty-body[b-c4mposjmk4] {
    margin: 0;
    font-size: var(--lk-font-size-ui);
    line-height: var(--lk-line-height-body);
    color: var(--lk-text-sec);
    text-wrap: pretty;
}

.lk-empty-action[b-c4mposjmk4] {
    display: flex;
    justify-content: center;
    margin-top: var(--lk-space-5);
}

/* ── Compact ────────────────────────────────────────────────
   The in-panel variant. The design draws it smaller, with a dashed mark and a rule above,
   so that a panel with nothing in it still reads as part of its card rather than as a
   second screen inside one.

   The rule replaces the border the panel's rows would have drawn. Without it the empty
   state floats directly under the heading with nothing separating them, which is the one
   thing that made it look broken rather than empty.

   ASSUMPTION (#529): the padding follows the design's own small-variant block, not what
   that variant actually renders. The design defines .empty-state twice and the later rule
   wins on padding, so the small variant is drawn with the large one's 48px 28px. That reads
   as an oversight rather than an intention, so this is built to the block that declares the
   dashed mark and the smaller type. If @niklas says otherwise it is these two values. */

/* The 23.75rem cap, the auto margins and the padding are all inherited from .lk-empty on
   purpose: the design keeps the compact one a narrow centred column too, 380px inside a 663px
   panel, and gives it the same 48px of vertical room. Overriding max-width to none stretched
   the block across the whole panel; overriding the padding down to 32/20 then made the card
   half the height of the design's. What is actually smaller in the compact one is the mark and
   the type, plus the rule above — not the box around them. */
.lk-empty-compact[b-c4mposjmk4] {
    border-top: var(--lk-border-hairline) solid var(--lk-line);
}

/* Dashed and on the alternate surface, not the solid navy tile of the full-size one —
   the design uses the dash to say "nothing here yet" rather than "here is a thing". */
.lk-empty-compact .lk-empty-mark[b-c4mposjmk4] {
    width: 2.875rem;
    height: 2.875rem;
    margin-bottom: var(--lk-space-2);
    border: var(--lk-border-hairline) dashed var(--lk-line-strong);
    border-radius: 0.875rem;
    background: var(--lk-surface-alt);
    color: var(--lk-text-mut);
}

.lk-empty-compact .lk-empty-title[b-c4mposjmk4] {
    margin-bottom: var(--lk-space-2);
    font-size: 0.875rem;
    /* A heading sets its own leading. Inheriting the body's 1.6 made every one-line title
       six pixels taller than the design's, which is small until it happens on every card. */
    line-height: normal;
    color: var(--lk-text);
}

.lk-empty-compact .lk-empty-body[b-c4mposjmk4] {
    max-width: 15rem;
    margin: 0 auto;
    font-size: var(--lk-font-size-caption);
    line-height: 1.5;
    color: var(--lk-text-mut);
}
/* /Components/ErrorBanner.razor.rz.scp.css */
/*
    The Prototype's .error-banner.

    Colours come from tokens, and so do the measurements the scale already carries exactly — the
    12px gap is --lk-space-3, the 16px side padding is --lk-space-4, the 1.5px rule is
    --lk-border-width. Where the design asks for something the scale does not have (14px of
    vertical padding, a 14px corner, 13.5px of text) the value is written out, as EmptyState
    writes out its own sizes. Inventing a token for one component would put a number in the
    theme that only this file ever reads.

    The banner owns no outer margin. Where it sits is the calling screen's business, and a
    component that reserves space below itself is one every caller then has to work around.
*/

.lk-error-banner[b-qsj2icnbkr] {
    display: flex;
    align-items: flex-start;
    gap: var(--lk-space-3);
    padding: 14px var(--lk-space-4);
    border: var(--lk-border-width) solid var(--lk-err);
    border-radius: 14px;
    background: var(--lk-err-soft);
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--lk-text);
}

/* Does not shrink, and sits a hair below the cap height of the first line of text. */
.lk-error-banner-mark[b-qsj2icnbkr] {
    flex: 0 0 auto;
    margin-top: 1px;
    color: var(--lk-err);
}

.lk-error-banner-body[b-qsj2icnbkr] {
    min-width: 0;
}

.lk-error-banner-title[b-qsj2icnbkr] {
    display: block;
    margin-bottom: 2px;
    font-size: 14px;
    font-weight: 700;
    color: var(--lk-err);
}

/*
    The message is in the ordinary text colour, not the error colour. Two weights of red in one
    box makes the sentence harder to read than it makes it urgent, and the heading and the border
    have already said that something is wrong.
*/
.lk-error-banner-message[b-qsj2icnbkr] {
    display: block;
}
/* /Components/FieldGroupComponent.razor.rz.scp.css */
.lk-field-group-head[b-d88yvh335g] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    margin-bottom: var(--lk-space-4);
}

.lk-field-group-mark[b-d88yvh335g] {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2rem;
    height: 2rem;
    border-radius: var(--lk-radius-sm);
    background: var(--lk-navy-soft);
    color: var(--lk-ink);
}

.lk-field-group-title[b-d88yvh335g] {
    flex: 1;
    min-width: 0;
    margin: 0;
    font-family: var(--lk-font-display);
    font-weight: 700;
    font-size: 0.969rem;
    color: var(--lk-ink);
}

.lk-field-group-body[b-d88yvh335g] {
    display: grid;
    gap: var(--lk-space-3);
}

.lk-field-group-action[b-d88yvh335g] {
    margin-top: var(--lk-space-4);
}
/* /Components/Icon.razor.rz.scp.css */
.lk-icon[b-w4d9x3m5jo] {
    display: block;
    flex: 0 0 auto;
}
/* /Components/ImpersonationBanner.razor.rz.scp.css */
/*
    Magenta, which nothing else in the portal uses as a surface. That is the point: acting as
    somebody else must not be mistakable for part of the furniture, in any of the four layouts
    this appears in. The design's own accent, not a colour picked here.
*/
.lk-impersonation[b-4zwi4xyo96] {
    display: flex;
    flex-direction: column;
    gap: var(--lk-space-1);
    padding: var(--lk-space-3);
    border-radius: var(--lk-radius-control);
    background: var(--lk-magenta);
    color: var(--lk-magenta-contrast);
}

.lk-impersonation-label[b-4zwi4xyo96] {
    font-size: 0.719rem;
    opacity: 0.85;
}

.lk-impersonation-row[b-4zwi4xyo96] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
}

/* Takes the spare width so the stop button stays at the far edge, however wide the layout is. */
.lk-impersonation-name[b-4zwi4xyo96] {
    flex: 1;
    min-width: 0;
    font-weight: 700;
    font-size: var(--lk-font-size-label);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/*
    The button sits on magenta rather than on the surrounding surface, so it cannot inherit the
    ghost variant's colours and stay legible. ::deep because the element belongs to Button, and
    the class lands on the <button> itself — Splat merges it into that component's class list.
*/
[b-4zwi4xyo96] button.lk-impersonation-stop {
    background: var(--lk-magenta-hover);
    color: var(--lk-magenta-contrast);
}

[b-4zwi4xyo96] button.lk-impersonation-stop:hover {
    background: var(--lk-magenta-ink);
}
/* /Components/Logo.razor.rz.scp.css */
.lk-logo[b-mk9jumdll2] {
    display: inline-flex;
    align-items: center;
    gap: calc(var(--lk-logo-size) * 0.32);
}

.lk-logo-tile[b-mk9jumdll2] {
    position: relative;
    flex: 0 0 auto;
    width: var(--lk-logo-size);
    height: var(--lk-logo-size);
    border-radius: calc(var(--lk-logo-size) * 0.28);
    background: var(--lk-logo-tile);
    display: flex;
    align-items: center;
    justify-content: center;
}

.lk-logo-glyph[b-mk9jumdll2] {
    display: block;
    width: calc(var(--lk-logo-size) * 0.56);
    height: calc(var(--lk-logo-size) * 0.56);
    /* The glyph sits on the navy tile in both themes, so its contrast color is the one
       that pairs with navy — never the page's text color. */
    color: var(--lk-rail-text);
}

.lk-logo-word[b-mk9jumdll2] {
    font-family: var(--lk-font-display);
    font-weight: 800;
    font-size: calc(var(--lk-logo-size) * 0.5);
    letter-spacing: -0.025em;
    white-space: nowrap;
    color: var(--lk-ink);
}
/* /Components/MicrosoftMark.razor.rz.scp.css */
/*
    The only place in the portal that names colours outside the theme, and deliberately so:
    these belong to Microsoft. Theming them would make the mark wrong rather than consistent.
*/

.lk-ms-mark[b-3s8litruku] {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2px;
    flex: 0 0 auto;
    width: var(--lk-ms-size, 1.0625rem);
    height: var(--lk-ms-size, 1.0625rem);
}

.lk-ms-square[b-3s8litruku] {
    border-radius: 1px;
}

.lk-ms-red[b-3s8litruku] {
    background: #f25022;
}

.lk-ms-green[b-3s8litruku] {
    background: #7fba00;
}

.lk-ms-blue[b-3s8litruku] {
    background: #00a4ef;
}

.lk-ms-yellow[b-3s8litruku] {
    background: #ffb900;
}
/* /Components/NameChoiceComponent.razor.rz.scp.css */
/*
    The onboarding card's spacing, moved here with the markup (#530). Nothing about the card is
    styled from here — the component contributes the question and its own rhythm, and the screen
    around it owns the surface it sits on.
*/

.lk-name-choice-label[b-ce92kq9z22] {
    display: block;
    margin-bottom: 7px;
    font-size: 13px;
    font-weight: 600;
    color: var(--lk-text-sec);
}

.lk-name-choice-description[b-ce92kq9z22] {
    margin: 6px 0 0;
    font-size: 12.5px;
    line-height: var(--lk-line-height-body);
    color: var(--lk-text-mut);
}

.lk-name-choice-options[b-ce92kq9z22] {
    display: grid;
    gap: 10px;
    margin-top: 6px;
}

.lk-name-choice-row[b-ce92kq9z22] {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin-top: 6px;
}

/* The field takes the row; the button keeps its own width. TextField renders its own markup, so
   reaching its root needs ::deep — without it this rule matches nothing, silently. */
.lk-name-choice[b-ce92kq9z22]  .lk-name-choice-field {
    flex: 1;
}
/* /Components/NavigationMenu.razor.rz.scp.css */
/*
    The links are rendered by NavLink, so they sit in that component's markup and do not
    carry this component's scope attribute. Every rule that targets a link therefore needs
    ::deep — without it these rules would look correct and do nothing.
*/

.lk-nav[b-em4efasvds] {
    display: flex;
    gap: var(--lk-space-1);
}

.lk-nav-rail[b-em4efasvds] {
    flex-direction: column;
}

.lk-nav-bar[b-em4efasvds] {
    flex-direction: row;
    flex-wrap: wrap;
}

.lk-nav[b-em4efasvds]  .lk-nav-item {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    padding: var(--lk-space-3);
    border-radius: var(--lk-radius-control);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 500;
    text-decoration: none;
    transition: background var(--lk-transition), color var(--lk-transition);
}

.lk-nav[b-em4efasvds]  .lk-nav-item.active {
    font-weight: 600;
}

.lk-nav[b-em4efasvds]  .lk-nav-item:focus-visible {
    outline: none;
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-focus);
}

/* The label may wrap onto a second line in a language with longer words rather than being
   cut off (ADR 0002). */
.lk-nav[b-em4efasvds]  .lk-nav-label {
    min-width: 0;
}

/* ── In the navy rail ───────────────────────────────────── */

.lk-nav-rail[b-em4efasvds]  .lk-nav-item {
    color: var(--lk-rail-text-sec);
}

.lk-nav-rail[b-em4efasvds]  .lk-nav-item:hover {
    background: var(--lk-rail-surface);
    color: var(--lk-rail-text);
}

.lk-nav-rail[b-em4efasvds]  .lk-nav-item.active {
    background: var(--lk-rail-surface-strong);
    color: var(--lk-rail-text);
}

/* The magenta marker reaches out to the edge of the rail. The rail publishes its own
   horizontal padding so this does not have to guess at it. */
.lk-nav-rail[b-em4efasvds]  .lk-nav-item.active::before {
    content: "";
    position: absolute;
    left: calc(-1 * var(--lk-rail-padding-x, var(--lk-space-4)));
    top: var(--lk-space-2);
    bottom: var(--lk-space-2);
    width: 0.25rem;
    border-radius: 0 0.25rem 0.25rem 0;
    background: var(--lk-magenta);
}

/* ── In the top bar ─────────────────────────────────────── */

.lk-nav-bar[b-em4efasvds]  .lk-nav-item {
    padding: var(--lk-space-2) var(--lk-space-4);
    color: var(--lk-text-sec);
}

.lk-nav-bar[b-em4efasvds]  .lk-nav-item:hover {
    background: var(--lk-surface-alt);
    color: var(--lk-ink);
}

.lk-nav-bar[b-em4efasvds]  .lk-nav-item.active {
    background: var(--lk-navy-soft);
    color: var(--lk-ink);
}

/* ── Group heading ──────────────────────────────────────── */

/*
    The design's "ADMIN" label over Lyker's own entries, in the same manner as "ORGANISATION"
    over the switcher — same size, weight, tracking and muted rail colour, so the two read as
    the same kind of thing rather than as two labels that happen to be small.

    A <p> and not a heading element: the nav already carries its own label as a landmark, and
    an h2 inside it would put a heading in the document outline for a grouping that is a visual
    aid, not a section of the page.

    No ::deep. This element is written by NavigationMenu itself, unlike .lk-nav-item, which
    NavLink renders.
*/
.lk-nav-group[b-em4efasvds] {
    margin: var(--lk-space-4) 0 var(--lk-space-1);
    padding: 0 var(--lk-space-3);
    font-size: 0.688rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--lk-rail-text-mut);
}

/* The first heading needs no space above it — there is nothing for it to separate from. */
.lk-nav-group:first-child[b-em4efasvds] {
    margin-top: 0;
}
/* /Components/NotFoundComponent.razor.rz.scp.css */
.not-found-home[b-kni8quw4tm] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-1);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-sec);
    text-decoration: none;
    transition: color var(--lk-transition);
}

.not-found-home:hover[b-kni8quw4tm] {
    color: var(--lk-ink);
}
/* /Components/OrganizationRequiredComponent.razor.rz.scp.css */
/*
    The sentence shown above content that is rendered read-only. The replacement shape has no
    styling of its own — it is an EmptyState, which already carries it.

    Quiet on purpose: it explains why the screen is as it is, and it is not the thing the reader
    came for. Same weight as the other notes on the key detail, so a screen that shows one of each
    does not look like two different kinds of message.
*/

.lk-organization-required-note[b-pwzaij8q0q] {
    margin: 0 0 var(--lk-space-3);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    line-height: var(--lk-line-height-tight);
    color: var(--lk-text-mut);
}

/*
    Beside the actions instead of above them, on the same line as the buttons the sentence is
    about — a SectionHeader action row, which is a centred flex row.

    The margin above would lift the text off that line, and without a width the sentence takes
    its natural one and pushes the buttons aside. Both rules used to live on the screens, four
    copies of them (#320); the placement is the component's now, so the screens keep only the
    choice of where the note goes.

    18rem because three of the four copies had it and the fourth had 16rem for no recorded
    reason. One value, chosen once, rather than a fourth guess on the next screen.
*/
.lk-organization-required-note-beside[b-pwzaij8q0q] {
    margin: 0;
    max-width: 18rem;
}
/* /Components/OrganizationSwitcherComponent.razor.rz.scp.css */
/* The menu is positioned against this, so it needs to be the containing block. */
.lk-org-switcher[b-azetjkxx7l] {
    position: relative;
}

.lk-org-rail-switcher[b-azetjkxx7l] {
    width: 100%;
}

.lk-org[b-azetjkxx7l] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    box-sizing: border-box;
    padding: var(--lk-space-2) var(--lk-space-3);
    border-radius: var(--lk-radius-control);
    border: var(--lk-border-hairline) solid transparent;
    font-family: var(--lk-font-ui);
    text-align: left;
}

.lk-org-interactive[b-azetjkxx7l] {
    cursor: pointer;
}

.lk-org-interactive:focus-visible[b-azetjkxx7l] {
    outline: none;
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-focus);
}

.lk-org-mark[b-azetjkxx7l] {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    border-radius: var(--lk-radius-sm);
}

.lk-org-text[b-azetjkxx7l] {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.lk-org-caption[b-azetjkxx7l] {
    font-size: 0.688rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.lk-org-name[b-azetjkxx7l] {
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── In the navy rail ───────────────────────────────────── */

.lk-org-rail[b-azetjkxx7l] {
    width: 100%;
    background: var(--lk-rail-surface);
    color: var(--lk-rail-text);
}

.lk-org-rail .lk-org-mark[b-azetjkxx7l] {
    width: 1.875rem;
    height: 1.875rem;
    background: var(--lk-rail-surface-strong);
    color: var(--lk-rail-text);
}

.lk-org-rail .lk-org-caption[b-azetjkxx7l] {
    color: var(--lk-rail-text-mut);
}

.lk-org-rail.lk-org-interactive:hover[b-azetjkxx7l] {
    background: var(--lk-rail-surface-strong);
}

/* ── In the top bar ─────────────────────────────────────── */

.lk-org-bar[b-azetjkxx7l] {
    max-width: 16.25rem;
    background: var(--lk-surface);
    border-color: var(--lk-line-strong);
    color: var(--lk-ink);
}

.lk-org-bar .lk-org-mark[b-azetjkxx7l] {
    width: 1.625rem;
    height: 1.625rem;
    background: var(--lk-navy-soft);
    color: var(--lk-ink);
}

.lk-org-bar.lk-org-interactive:hover[b-azetjkxx7l] {
    background: var(--lk-surface-alt);
}

/* ── The menu ───────────────────────────────────────────── */

/*
    A light surface in both shells: in the rail it is a panel laid over the navy, not a piece
    of it, so it takes the page's surface colours rather than the rail's.

    Above the rail and the top bar, which both sit at 10, and below the dialog overlay at
    1000 — a menu must cover the shell it belongs to and never a modal.
*/
.lk-org-menu[b-azetjkxx7l] {
    position: absolute;
    left: 0;
    right: 0;
    z-index: 20;
    display: flex;
    flex-direction: column;
    gap: var(--lk-space-1);
    box-sizing: border-box;
    margin-top: var(--lk-space-1);
    padding: var(--lk-space-1);
    max-height: 20rem;
    overflow-y: auto;
    background: var(--lk-surface);
    border: var(--lk-border-hairline) solid var(--lk-line-strong);
    border-radius: var(--lk-radius-control);
    box-shadow: var(--lk-shadow-lg);
}

/* The pill sits at the right-hand end of the bar, so the menu hangs from that edge rather
   than stretching the width of the actions. It opens downward here as it does in the rail,
   which is an assumption rather than a ported behaviour — the Prototype has only one shell.
   #341.

   The floor is wider than the pill on purpose: the pill is only as wide as the organisation
   it happens to be showing, and a menu that inherited that width wrapped "Alla organisationer"
   onto two lines. Longer words in Finnish and the other Nordic languages (ADR 0002) would
   have been worse, and the wrap is not visible in a bUnit test. */
.lk-org-bar-switcher .lk-org-menu[b-azetjkxx7l] {
    left: auto;
    min-width: max(100%, 13rem);
    max-width: 20rem;
}

.lk-org-menu-item[b-azetjkxx7l] {
    padding: var(--lk-space-2) var(--lk-space-3);
    border-radius: var(--lk-radius-sm);
    background: none;
    border: none;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    color: var(--lk-text);
    text-align: left;
    cursor: pointer;
    transition: background var(--lk-transition), color var(--lk-transition);
}

.lk-org-menu-item:hover[b-azetjkxx7l] {
    background: var(--lk-surface-alt);
}

.lk-org-menu-item:focus-visible[b-azetjkxx7l] {
    outline: none;
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-focus);
}

/* The same marking the navigation uses for the page you are on, for the same reason. */
.lk-org-menu-item-on[b-azetjkxx7l] {
    background: var(--lk-navy-soft);
    color: var(--lk-ink);
    font-weight: 600;
}

/* The chevron belongs to the Icon component's markup, so it needs ::deep to be reached. */
[b-azetjkxx7l] .lk-org-chevron {
    flex: 0 0 auto;
    margin-left: auto;
    opacity: 0.7;
}
/* /Components/Pagination.razor.rz.scp.css */
.lk-pagination[b-mms9z4g0ms] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    /* Wraps rather than squeezing: the range text grows with the word for "showing", and
       Finnish is the long one (ADR 0002). */
    flex-wrap: wrap;
    padding: var(--lk-space-3) var(--lk-space-4);
    border-top: var(--lk-border-width) solid var(--lk-line);
}

.lk-pagination-range[b-mms9z4g0ms] {
    /* Takes the slack, so the size picker and the arrows sit together at the far end. */
    flex: 1 1 auto;
    margin: 0;
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-sec);
}

.lk-pagination[b-mms9z4g0ms]  .lk-pagination-size {
    flex: none;
    width: 8rem;
}

.lk-pagination-steps[b-mms9z4g0ms] {
    display: flex;
    flex: none;
    gap: var(--lk-space-2);
}
/* /Components/ReadOnlyFieldComponent.razor.rz.scp.css */
.lk-read-only-field[b-1dhghqcchc] {
    display: block;
}

.lk-read-only-field-label[b-1dhghqcchc] {
    display: block;
    margin-bottom: var(--lk-space-2);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-sec);
}

/* The frame of a field that cannot be typed into: the sunken surface rather than the raised
   one a TextField uses, so the difference is visible before anyone clicks it. */
.lk-read-only-field-frame[b-1dhghqcchc] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
    box-sizing: border-box;
    min-height: var(--lk-field-height);
    padding: 0 var(--lk-space-3);
    background: var(--lk-surface-alt);
    border: var(--lk-border-hairline) solid var(--lk-line);
    border-radius: var(--lk-radius-control);
}

.lk-read-only-field-value[b-1dhghqcchc] {
    flex: 1;
    min-width: 0;
    font-family: var(--lk-font-ui);
    font-size: 0.938rem;
    color: var(--lk-text);
    /* A long address wraps rather than pushing the badge out of the card. */
    overflow-wrap: anywhere;
}

.lk-read-only-field-empty[b-1dhghqcchc] {
    color: var(--lk-text-mut);
}

[b-1dhghqcchc] .lk-read-only-field-icon {
    flex: 0 0 auto;
    color: var(--lk-text-mut);
}
/* /Components/SectionHeader.razor.rz.scp.css */
/*
    The actions drop to their own row before the heading is squeezed.

    Without the wrap they competed with the title for the same row, and the title is the half
    that cannot give: a greeting is one long unbreakable token when the account has no name
    claim and falls back to the e-mail address (#211). At the widths this is actually looked
    at, "Hej martin.bjorkvall@schotte.se 👋" broke across three lines — the greeting, the
    address, and the waving hand alone on the last one — while the design fitted it on one.

    flex-wrap on the container and flex-shrink: 0 on the actions, rather than a breakpoint:
    where the wrap happens depends on how long the name is, and no width knows that.
*/
.lk-section-header[b-h8ecj9rn0b] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--lk-space-4);
    margin-bottom: var(--lk-space-5);
}

/*
    The heading gets a whole line before the actions get any of it.

    min-width: max-content is what does it. flex-wrap alone was not enough: a flex item with
    min-width: 0 shrinks as far as it is told to, so the actions kept their place on the row and
    the heading wrapped instead — "Hej", the address, and the waving hand on three lines. With
    max-content the text refuses to go below its single-line width, so the line cannot hold both
    and the actions move down. Decision by @martin 2026-09-02: sooner the buttons on their own
    row than three lines of greeting.

    It only bites when the greeting is long, which is when the account has no name claim and it
    falls back to the whole e-mail address (#211). A "Hej Martin" leaves room for both and
    nothing moves.

    Released again below 56rem. max-content cannot shrink, so on a screen narrower than the
    heading itself it would push the page sideways — and a horizontal scrollbar is worse than a
    wrapped greeting. 56rem is where this heading stops fitting beside the rail; the phone
    answer proper is still #198.
*/
.lk-section-header-text[b-h8ecj9rn0b] {
    flex: 1 1 auto;
    min-width: max-content;
}

@media (max-width: 56rem) {
    .lk-section-header-text[b-h8ecj9rn0b] {
        min-width: 0;
    }
}

.lk-section-header-eyebrow[b-h8ecj9rn0b] {
    margin: 0 0 var(--lk-space-2);
    font-family: var(--lk-font-display);
    font-weight: 700;
    font-size: var(--lk-font-size-eyebrow);
    /* normal, not a ratio, and not the body's 1.6. The design sets no line-height on the header
       block at all, so each line takes its own face's metrics. Measured side by side at 1920 the
       eyebrow was 18px tall against the design's 14, the heading 30 against 35 and the subtitle
       23 against 17 — the whole block on a different rhythm. */
    line-height: normal;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--lk-magenta-ink);
}

/* One rule for every level: the level says where the section sits, the styling says how
   it looks, and the two are deliberately not tied together. */
.lk-section-header-title[b-h8ecj9rn0b] {
    margin: 0;
    font-family: var(--lk-font-display);
    font-weight: 800;
    font-size: var(--lk-font-size-title);
    letter-spacing: -0.02em;
    line-height: normal;
    color: var(--lk-ink);
}

/*
    A heading with something beside it gets a row to share. The design's gap is 12px, and it
    wraps rather than pushing the badge off the edge when the name is long.

    The element only exists when there is an aside, so every other heading in the portal keeps
    the markup it had. That matters here: min-width: max-content above is a tuned rule with a
    recorded decision behind it, and a layout change in this component reaches every screen.
*/
.lk-section-header-heading[b-h8ecj9rn0b] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--lk-space-3);
}

/* The badge keeps its own type — it is not part of the 26px display heading it sits next to. */
.lk-section-header-aside[b-h8ecj9rn0b] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-2);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 400;
    letter-spacing: normal;
}

/*
    Emoji do not follow the display font's weight or letter-spacing, so the flourish is left
    at its natural size rather than stretched to match the heading.

    The gap is a margin rather than a space in the markup: a literal space would be left
    behind in every heading that has no decoration, which is most of them.
*/
.lk-section-header-decoration[b-h8ecj9rn0b] {
    margin-left: 0.3em;
    font-weight: 400;
    letter-spacing: normal;
}

.lk-section-header-subtitle[b-h8ecj9rn0b] {
    margin: var(--lk-space-2) 0 0;
    font-size: var(--lk-font-size-ui);
    line-height: normal;
    color: var(--lk-text-sec);
}

.lk-section-header-actions[b-h8ecj9rn0b] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
    flex: 0 0 auto;
}

/* On a narrow screen the actions drop under the heading rather than squeezing it. */
@media (max-width: 40rem) {
    .lk-section-header[b-h8ecj9rn0b] {
        flex-direction: column;
        align-items: stretch;
    }
}
/* /Components/Select.razor.rz.scp.css */
/*
    The frame, the label and the message below are the same shapes as TextField's, and they
    are written out again here rather than shared.

    The reason: CSS isolation scopes every rule to its own component, so sharing would mean
    lifting the field frame into app.css and rewriting TextField to use it. That is a change
    to a component that is already built and tested, for the benefit of the second control
    that needs it.

    It is a duplication with a real cost — change the focus ring here and TextField keeps the
    old one. Worth consolidating when a third control wants the same frame, which is the point
    at which the rewrite pays for itself. Written here rather than filed as an issue: there is
    nothing for anyone to go and do until that third control exists, and this is where whoever
    builds it will be standing.
*/

.lk-select[b-rjti2r8w5u] {
    display: block;
}

.lk-select-label[b-rjti2r8w5u] {
    display: block;
    margin-bottom: var(--lk-space-2);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-sec);
}

/* Off the screen but still in the accessibility tree, so the control keeps its name. Not
   display:none and not visibility:hidden — both remove it from the tree as well, which is the
   thing this must not do. */
.lk-select-label-hidden[b-rjti2r8w5u] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.lk-select-required[b-rjti2r8w5u] {
    margin-left: 0.125rem;
    color: var(--lk-magenta-ink);
}

.lk-select-frame[b-rjti2r8w5u] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
    box-sizing: border-box;
    min-height: var(--lk-field-height);
    padding: 0 var(--lk-space-3);
    background: var(--lk-surface);
    border: var(--lk-border-width) solid var(--lk-line-strong);
    border-radius: var(--lk-radius-control);
    transition: border-color var(--lk-transition), box-shadow var(--lk-transition);
}

/* Soft glow, matching TextField — see the note there for why it is not --lk-focus. */
.lk-select-frame:focus-within[b-rjti2r8w5u] {
    border-color: var(--lk-magenta);
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-magenta-soft);
}

.lk-select-input[b-rjti2r8w5u] {
    flex: 1;
    min-width: 0;
    /* The browser's own arrow cannot be styled and sits somewhere different in each one, so
       it is removed and replaced with the design's chevron. */
    appearance: none;
    border: 0;
    padding: 0;
    background: transparent;
    font-family: var(--lk-font-ui);
    font-size: 0.938rem;
    color: var(--lk-text);
    cursor: pointer;
}

.lk-select-input:focus[b-rjti2r8w5u] {
    /* The frame carries focus for the whole control. */
    outline: none;
}

.lk-select-input:disabled[b-rjti2r8w5u] {
    cursor: not-allowed;
}

/* The list itself is drawn by the operating system, which does not inherit the page's
   colours. Setting both keeps a dark-theme portal from opening a white list. */
.lk-select-input option[b-rjti2r8w5u] {
    background: var(--lk-surface);
    color: var(--lk-text);
}

.lk-select-message[b-rjti2r8w5u] {
    margin: var(--lk-space-2) 0 0;
    font-size: var(--lk-font-size-caption);
    color: var(--lk-text-mut);
}

.lk-select-message-error[b-rjti2r8w5u] {
    color: var(--lk-err);
}

/* ── States ─────────────────────────────────────────────── */

.lk-select-invalid .lk-select-frame[b-rjti2r8w5u] {
    border-color: var(--lk-err);
}

.lk-select-invalid .lk-select-frame:focus-within[b-rjti2r8w5u] {
    border-color: var(--lk-err);
}

.lk-select-disabled .lk-select-frame[b-rjti2r8w5u] {
    background: var(--lk-surface-alt);
    opacity: 0.6;
}

/* ::deep, because these belong to the Icon component's markup and do not carry this
   component's scope attribute. Without it the rules would silently do nothing. */
[b-rjti2r8w5u] .lk-select-icon {
    color: var(--lk-text-mut);
}

[b-rjti2r8w5u] .lk-select-chevron {
    flex: 0 0 auto;
    color: var(--lk-text-mut);
    pointer-events: none;
}
/* /Components/Skeleton.razor.rz.scp.css */
.lk-skeleton[b-xrq8sutiee] {
    display: block;
    background: linear-gradient(
        90deg,
        var(--lk-skeleton-base) 0%,
        var(--lk-skeleton-highlight) 40%,
        var(--lk-skeleton-base) 80%
    );
    background-size: 800px 100%;
    animation: lk-shimmer-b-xrq8sutiee 1.4s linear infinite;
}

/* A sweeping highlight across a whole page of placeholders is a lot of movement for
   someone who is sensitive to it. The shape still reads as "not here yet" without it. */
@media (prefers-reduced-motion: reduce) {
    .lk-skeleton[b-xrq8sutiee] {
        animation: none;
        background: var(--lk-skeleton-base);
    }
}

@keyframes lk-shimmer-b-xrq8sutiee {
    0% {
        background-position: -400px 0;
    }

    100% {
        background-position: 400px 0;
    }
}
/* /Components/SortableColumnHeader.razor.rz.scp.css */
.lk-sort-header[b-ostd1ev94b] {
    padding: 0;
    text-align: left;
}

.lk-sort-button[b-ostd1ev94b] {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    width: 100%;
    box-sizing: border-box;
    padding: var(--lk-space-2) var(--lk-space-3);
    background: transparent;
    border: none;
    border-radius: var(--lk-radius-control);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-mut);
    text-align: left;
    cursor: pointer;
    transition: background var(--lk-transition), color var(--lk-transition);
}

.lk-sort-button:hover[b-ostd1ev94b] {
    background: var(--lk-ghost-hover);
    color: var(--lk-ink);
}

/* focus-visible rather than focus, as on Button: the keyboard user needs the ring, the
   mouse user should not get one after every click (ADR 0007). */
.lk-sort-button:focus-visible[b-ostd1ev94b] {
    outline: none;
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-focus);
}

.lk-sort-label[b-ostd1ev94b] {
    min-width: 0;
}

/* One chevron, turned. Descending points down, ascending is the same glyph rotated, so no
   icon needs adding to IconPaths for this (ADR 0006). */
.lk-sort-indicator[b-ostd1ev94b] {
    flex: none;
    transition: transform var(--lk-transition), opacity var(--lk-transition);
}

.lk-sort-indicator-ascending[b-ostd1ev94b] {
    transform: rotate(180deg);
}

/* The unsorted column keeps the chevron so the heading does not change width when it becomes
   the sorted one, but fades it until it means something. It returns on hover, because that is
   when the heading is about to be pressed. */
.lk-sort-indicator-inactive[b-ostd1ev94b] {
    opacity: 0;
}

.lk-sort-button:hover .lk-sort-indicator-inactive[b-ostd1ev94b],
.lk-sort-button:focus-visible .lk-sort-indicator-inactive[b-ostd1ev94b] {
    opacity: 0.5;
}
/* /Components/Spinner.razor.rz.scp.css */
.lk-spinner[b-nspu40jy4i] {
    display: inline-block;
    flex: 0 0 auto;
    width: var(--lk-spinner-size, 1rem);
    height: var(--lk-spinner-size, 1rem);
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: lk-spin-b-nspu40jy4i 0.7s linear infinite;
}

/* Respect a reader who has asked the system to reduce motion. The spinner still reads as
   "busy" through its shape; it simply stops turning. */
@media (prefers-reduced-motion: reduce) {
    .lk-spinner[b-nspu40jy4i] {
        animation-duration: 2.4s;
    }
}

@keyframes lk-spin-b-nspu40jy4i {
    to {
        transform: rotate(360deg);
    }
}
/* /Components/StatusDot.razor.rz.scp.css */
.lk-status-dot[b-aopgvmqfwe] {
    display: inline-flex;
    align-items: center;
    gap: 0.4375rem;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-sec);
}

.lk-status-dot-mark[b-aopgvmqfwe] {
    flex: 0 0 auto;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: var(--lk-radius-pill);
}

.lk-status-dot-ok .lk-status-dot-mark[b-aopgvmqfwe] {
    background: var(--lk-ok);
}

.lk-status-dot-warn .lk-status-dot-mark[b-aopgvmqfwe] {
    background: var(--lk-warn);
}

.lk-status-dot-error .lk-status-dot-mark[b-aopgvmqfwe] {
    background: var(--lk-err);
}

.lk-status-dot-idle .lk-status-dot-mark[b-aopgvmqfwe] {
    background: var(--lk-text-mut);
}
/* /Components/TextArea.razor.rz.scp.css */
/*
    Shaped after TextField's input, from the same tokens, so a screen carrying both does not look
    like it borrowed one of them from somewhere else. No colour or spacing literals — everything
    comes from PortalTheme, which is what keeps light and dark honest without a second set of
    rules.
*/

.lk-textarea[b-0gw3h60m0d] {
    display: block;
    width: 100%;
}

.lk-textarea-label[b-0gw3h60m0d] {
    display: block;
    margin-bottom: var(--lk-space-2);
    font-family: var(--lk-font-ui);
    font-weight: 600;
    font-size: var(--lk-font-size-caption);
    color: var(--lk-text-sec);
}

.lk-textarea-input[b-0gw3h60m0d] {
    display: block;
    width: 100%;
    padding: var(--lk-space-3);
    border: 1px solid var(--lk-line);
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-body);
    line-height: 1.6;
    color: var(--lk-text);

    /* Vertical only. Horizontal resizing lets the box out of the page's grid, and a field wider
       than its container is a layout bug the reader made themselves. */
    resize: vertical;
}

.lk-textarea-input:focus-visible[b-0gw3h60m0d] {
    outline: 2px solid var(--lk-focus);
    outline-offset: 1px;
}

/* A pseudo-class rather than a Disabled modifier class, the way Button does it: the state is
   already on the element and a second source for it can only go out of step. */
.lk-textarea-input:disabled[b-0gw3h60m0d] {
    cursor: not-allowed;
    color: var(--lk-text-mut);
}

.lk-textarea-hint[b-0gw3h60m0d] {
    margin: var(--lk-space-1) 0 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
    color: var(--lk-text-mut);
}
/* /Components/TextField.razor.rz.scp.css */
.lk-field[b-bzhvd21l7g] {
    display: block;
}

.lk-field-label-row[b-bzhvd21l7g] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    margin-bottom: var(--lk-space-2);
}

.lk-field-label[b-bzhvd21l7g] {
    flex: 1;
    min-width: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-sec);
}

.lk-field-label-action[b-bzhvd21l7g] {
    flex: 0 0 auto;
}

.lk-field-required[b-bzhvd21l7g] {
    margin-left: 0.125rem;
    color: var(--lk-magenta-ink);
}

.lk-field-frame[b-bzhvd21l7g] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
    box-sizing: border-box;
    min-height: var(--lk-field-height);
    padding: 0 var(--lk-space-3);
    background: var(--lk-surface);
    border: var(--lk-border-width) solid var(--lk-line-strong);
    border-radius: var(--lk-radius-control);
    transition: border-color var(--lk-transition), box-shadow var(--lk-transition);
}

/* The ring sits on the frame, not the input, so the icon and suffix are inside it.

   The glow is --lk-magenta-soft, not --lk-focus. --lk-focus is the button ring; on a field
   it is loud enough to read as an error, which is what the invalid state next to it means.
   The Prototype uses the soft token here (portal app.css .f-input:focus-within) and that is
   what runs today.

   It shows on mouse click too, and cannot be made keyboard-only: a click into a text input
   matches :focus-visible in every browser, by design, because the element is about to be
   typed into. The Prototype hit the same wall and wrote it down at app.css:30-33. Softening
   is the fix; hiding it on mouse would need modality tracking in JavaScript, portal-wide. */
.lk-field-frame:focus-within[b-bzhvd21l7g] {
    border-color: var(--lk-magenta);
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-magenta-soft);
}

.lk-field-input[b-bzhvd21l7g] {
    flex: 1;
    min-width: 0;
    border: 0;
    padding: 0;
    background: transparent;
    font-family: var(--lk-font-ui);
    font-size: 0.938rem;
    color: var(--lk-text);
}

.lk-field-input:focus[b-bzhvd21l7g] {
    /* The frame shows focus for the whole control; a second ring inside it would be noise. */
    outline: none;
}

.lk-field-input[b-bzhvd21l7g]::placeholder {
    color: var(--lk-text-mut);
    opacity: 1;
}

.lk-field-suffix[b-bzhvd21l7g] {
    flex: 0 0 auto;
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
}

.lk-field-message[b-bzhvd21l7g] {
    margin: var(--lk-space-2) 0 0;
    font-size: var(--lk-font-size-caption);
    color: var(--lk-text-mut);
}

.lk-field-message-error[b-bzhvd21l7g] {
    color: var(--lk-err);
}

/* ── States ─────────────────────────────────────────────── */

.lk-field-invalid .lk-field-frame[b-bzhvd21l7g] {
    border-color: var(--lk-err);
}

.lk-field-invalid .lk-field-frame:focus-within[b-bzhvd21l7g] {
    /* Focus must not hide the fact that the value is wrong. */
    border-color: var(--lk-err);
}

.lk-field-disabled .lk-field-frame[b-bzhvd21l7g] {
    background: var(--lk-surface-alt);
    opacity: 0.6;
}

.lk-field-disabled .lk-field-input[b-bzhvd21l7g] {
    cursor: not-allowed;
}

/* ::deep, because these elements belong to the Icon component's markup and do not carry
   this component's scope attribute. Without it the rules would silently do nothing. */
[b-bzhvd21l7g] .lk-field-icon {
    color: var(--lk-text-mut);
}

[b-bzhvd21l7g] .lk-field-alert {
    color: var(--lk-err);
}
/* /Components/ThemeProvider.razor.rz.scp.css */
/*
    Tokens that do not change between themes: type, radii, control heights, borders — and
    the spacing scale derived from the density variable.

    They are declared here rather than in a global stylesheet for one concrete reason: a
    custom property whose value contains var() is resolved on the element where it is
    declared. --lk-space-4 must therefore be declared on the same element that carries
    --lk-density, which is this one. Declared at :root it would silently resolve against
    the wrong density.
*/

.lk-theme[b-mbcelru2gm] {
    /* Type. The families are loaded in wwwroot; the stack degrades to system fonts. */
    --lk-font-display: "Montserrat", "Segoe UI", system-ui, sans-serif;
    --lk-font-ui: "Inter", "Segoe UI", system-ui, sans-serif;

    --lk-font-size-eyebrow: 0.719rem;
    --lk-font-size-caption: 0.781rem;
    --lk-font-size-label: 0.813rem;
    --lk-font-size-ui: 0.906rem;
    --lk-font-size-body: 1rem;
    --lk-font-size-title-sm: 1.125rem;
    /* 15.5px. The design's heading inside a card, which is a different size from the page's own
       heading and was missing from this table — so card headings were given --lk-font-size-title
       and rendered at the page title's size (#562). The overview's panel heading found the same
       number first and wrote it as a literal. */
    --lk-font-size-card-title: 0.969rem;
    --lk-font-size-title: 1.625rem;
    --lk-font-size-display: 2.125rem;

    --lk-line-height-tight: 1.15;
    --lk-line-height-body: 1.6;

    /* Controls. Fixed on purpose: density changes the rhythm around a control,
       never the control itself. */
    --lk-control-height-sm: 2.125rem;
    --lk-control-height-md: 2.75rem;
    --lk-control-height-lg: 3.25rem;
    --lk-field-height: 3rem;

    --lk-radius-sm: 0.5rem;
    --lk-radius-checkbox: 0.375rem;
    --lk-radius-control: 0.75rem;
    --lk-radius-card: 1rem;
    --lk-radius-tile: 1.125rem;
    --lk-radius-pill: 999px;

    --lk-border-hairline: 1px;
    --lk-border-width: 1.5px;
    --lk-focus-ring-width: 3px;

    /* Spacing. Every step scales with density (ADR 0005), so no component ever
       writes a fixed pixel value for margin, padding or gap.

       ADR 0005's rule is about pixels inlined in markup, which the design does everywhere in
       its style="..." attributes — not about pixels in CSS. This scale is a separate choice,
       and it costs something: the design's hand-tuned 14/18/15/13px round to 16/20/16/12 here.
       That divergence is accepted and written up in #528, so that a screen sitting 1-2px off
       the design on spacing is not reported as a fault every time one is compared. */
    --lk-density: 1;
    --lk-space-1: calc(0.25rem * var(--lk-density));
    --lk-space-2: calc(0.5rem * var(--lk-density));
    --lk-space-3: calc(0.75rem * var(--lk-density));
    --lk-space-4: calc(1rem * var(--lk-density));
    --lk-space-5: calc(1.25rem * var(--lk-density));
    --lk-space-6: calc(1.5rem * var(--lk-density));
    --lk-space-8: calc(2rem * var(--lk-density));
    --lk-space-10: calc(2.5rem * var(--lk-density));
    --lk-space-12: calc(3rem * var(--lk-density));
    /* 56px. The design's wide-screen shell padding, and the only place it is used so far. */
    --lk-space-14: calc(3.5rem * var(--lk-density));

    /* Padding inside controls does not scale — it is part of the control's shape. */
    --lk-control-padding-sm: 0.75rem;
    --lk-control-padding-md: 1.125rem;
    --lk-control-padding-lg: 1.5rem;

    --lk-transition: 0.15s ease;

    min-height: 100vh;
    background: var(--lk-canvas);
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);

    /*
        normal, not the body ratio — and that is the design's shape rather than a smaller number
        picked to close a gap.

        The design sets no line-height on the body at all. It applies 1.5 or 1.6 per element, and
        only where there is prose: a hero subtitle, an empty state's sentence, an error banner.
        A label, a field value, a table cell and a heading are single lines and take the font's
        own metrics.

        This declared 1.6 for everything, so every one-line row in the portal was about 6px
        taller than the design's and the difference accumulated down a page — measured at 927px
        against 844 on the kiosk detail. The cost was also paid piecemeal: three components had
        already found this on their own and set line-height: normal to escape it, each recording
        the same discovery separately (SectionHeader's eyebrow, PanelCard's title, CardHeader).

        Prose is unaffected. Every place that wants the ratio already asks for it by name —
        EmptyState, Dialog, Checkbox, AuthLayout, LoginPage, LoanApprovalPage and the rest — which
        is opting in, the way the design does it. --lk-line-height-body stays exactly as it was
        for them.
    */
    line-height: normal;
}
/* /Components/Toggle.razor.rz.scp.css */
.lk-toggle[b-7b82rw2wpy] {
    position: relative;
    flex: 0 0 auto;
    width: 2.75rem;
    height: 1.625rem;
    padding: 0;
    border: 0;
    border-radius: var(--lk-radius-pill);
    background: var(--lk-track-off);
    cursor: pointer;
    transition: background 0.18s ease;
}

.lk-toggle-on[b-7b82rw2wpy] {
    background: var(--lk-magenta);
}

.lk-toggle:disabled[b-7b82rw2wpy] {
    opacity: 0.5;
    cursor: not-allowed;
}

.lk-toggle:focus-visible[b-7b82rw2wpy] {
    outline: none;
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-focus);
}

.lk-toggle-knob[b-7b82rw2wpy] {
    position: absolute;
    top: 0.1875rem;
    left: 0.1875rem;
    width: 1.25rem;
    height: 1.25rem;
    border-radius: var(--lk-radius-pill);
    background: var(--lk-knob);
    box-shadow: 0 1px 3px rgb(0 0 0 / 25%);
    transition: left 0.18s ease;
}

.lk-toggle-on .lk-toggle-knob[b-7b82rw2wpy] {
    left: 1.3125rem;
}

/* The state is carried by position and colour, not by the movement. Someone who has asked
   for less motion still sees which way the switch is set. */
@media (prefers-reduced-motion: reduce) {
    .lk-toggle[b-7b82rw2wpy],
    .lk-toggle-knob[b-7b82rw2wpy] {
        transition: none;
    }
}
/* /Layouts/AuthLayout.razor.rz.scp.css */
.auth-shell[b-ys77xg55ar] {
    display: flex;
    min-height: 100vh;
    background: var(--lk-canvas);
}

/* ── The brand panel ────────────────────────────────────── */

.auth-brand[b-ys77xg55ar] {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    flex: 0 0 46%;
    padding: var(--lk-space-12) var(--lk-space-12) var(--lk-space-10);
    background: var(--lk-rail);
    color: var(--lk-rail-text);
}

/* The glows sit behind everything, so the content is lifted above them rather than the
   glows being pushed back — position:relative on the children is enough. */
.auth-brand-logo[b-ys77xg55ar],
.auth-brand-body[b-ys77xg55ar],
.auth-brand-footer[b-ys77xg55ar] {
    position: relative;
}

.auth-glow[b-ys77xg55ar] {
    position: absolute;
    border-radius: 50%;
    pointer-events: none;
}

.auth-glow-magenta[b-ys77xg55ar] {
    top: -7.5rem;
    right: -7.5rem;
    width: 28.75rem;
    height: 28.75rem;
    background: radial-gradient(circle, rgb(237 30 121 / 35%), transparent 70%);
}

.auth-glow-blue[b-ys77xg55ar] {
    bottom: -5rem;
    left: -3.75rem;
    width: 20rem;
    height: 20rem;
    background: radial-gradient(circle, rgb(41 171 226 / 18%), transparent 70%);
}

.auth-brand-body[b-ys77xg55ar] {
    display: flex;
    flex-direction: column;
    justify-content: center;
    flex: 1;
    max-width: 26.25rem;
}

.auth-brand-headline[b-ys77xg55ar] {
    margin: 0;
    font-family: var(--lk-font-display);
    font-weight: 800;
    font-size: 2.5rem;
    line-height: 1.1;
    letter-spacing: -0.025em;
}

.auth-brand-text[b-ys77xg55ar] {
    margin: var(--lk-space-4) 0 0;
    font-size: var(--lk-font-size-body);
    line-height: var(--lk-line-height-body);
    color: var(--lk-rail-text-sec);
    text-wrap: pretty;
}

.auth-brand-points[b-ys77xg55ar] {
    display: flex;
    flex-direction: column;
    gap: var(--lk-space-3);
    margin: var(--lk-space-8) 0 0;
    padding: 0;
    list-style: none;
}

.auth-brand-point[b-ys77xg55ar] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    font-size: var(--lk-font-size-ui);
}

.auth-brand-point-mark[b-ys77xg55ar] {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2.125rem;
    height: 2.125rem;
    border-radius: var(--lk-radius-sm);
    background: var(--lk-rail-surface-strong);
}

.auth-brand-footer[b-ys77xg55ar] {
    margin: 0;
    font-size: var(--lk-font-size-caption);
    color: var(--lk-rail-text-mut);
}

/* The logo sits on the navy panel in both themes, so its wordmark needs the contrast
   colour rather than the page's ink. ::deep because it belongs to Logo (ADR 0007). */
.auth-brand[b-ys77xg55ar]  .lk-logo-word {
    color: var(--lk-rail-text);
}

/* ── The form side ──────────────────────────────────────── */

.auth-main[b-ys77xg55ar] {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1;
    padding: var(--lk-space-10);
}

/* ── Narrow screens ─────────────────────────────────────── */

/*
    The brand panel is decoration; the form is the job. Below the breakpoint the panel is
    dropped entirely rather than stacked, so a phone shows the form straight away instead of
    a screen of marketing to scroll past. The proper design for phones is still open (#198).
*/
@media (max-width: 60rem) {
    .auth-brand[b-ys77xg55ar] {
        display: none;
    }

    .auth-main[b-ys77xg55ar] {
        padding: var(--lk-space-6) var(--lk-space-4);
        align-items: flex-start;
    }
}

/*
    Acting as somebody else. Placement only — the look belongs to ImpersonationBanner. Reachable
    here because the shell sends an impersonated person without a chosen organisation to
    /choose-organization.
*/
.auth-main[b-ys77xg55ar]  .auth-impersonation {
    width: min(100%, 24rem);
    margin: 0 auto var(--lk-space-4);
}
/* /Layouts/PublicLayout.razor.rz.scp.css */
.public-shell[b-xymiwwp8ys] {
    display: flex;
    flex-direction: column;
    align-items: center;
    /* dvh and not vh: on a phone, vh is the viewport with the browser chrome hidden, so a page
       sized to it is a page that scrolls by exactly the height of the address bar. */
    min-height: 100dvh;
    padding: var(--lk-space-6) var(--lk-space-4) var(--lk-space-10);
    background: var(--lk-canvas);
}

.public-brand[b-xymiwwp8ys] {
    display: flex;
    align-items: center;
    justify-content: center;
}

.public-main[b-xymiwwp8ys] {
    width: 100%;
    /* The card stops growing well before the page does. A terms paragraph set across a desktop
       window is a line nobody's eye can follow back. */
    max-width: 30rem;
    margin-top: var(--lk-space-5);
}

/*
    Acting as somebody else. Only placement here; the look is ImpersonationBanner's, so the
    same block appears in all four layouts. Above the card and inside the shell's own width,
    because this layout is mobile first and the card is what the eye lands on.
*/
.public-shell[b-xymiwwp8ys]  .public-impersonation {
    width: min(100%, 26rem);
    margin: 0 auto var(--lk-space-4);
}
/* /Layouts/SidebarLayout.razor.rz.scp.css */
.lk-shell[b-dzcqylndpd] {
    --lk-rail-width: 15.625rem;

    display: flex;
    min-height: 100vh;

    /*
        The rail's navy is painted here, by the shell, and not by the rail itself.

        The rail is no longer as tall as the page — it is a screen tall, so that the signed-in
        person can sit at the foot of the screen rather than the foot of the document. Something
        still has to carry the colour the rest of the way down on a long page, or the column
        would end mid-scroll and the canvas would show through beneath it.

        A gradient with a hard stop rather than a pseudo-element: it needs no stacking context,
        nothing to position, and it cannot end up over the content.
    */
    background: linear-gradient(
        to right,
        var(--lk-rail) 0 var(--lk-rail-width),
        var(--lk-canvas) var(--lk-rail-width));
}

/* ── The rail ───────────────────────────────────────────── */

.lk-rail[b-dzcqylndpd] {
    /* Published so the navigation's active marker can reach the rail's edge without
       guessing at this value. */
    --lk-rail-padding-x: var(--lk-space-4);

    display: flex;
    flex-direction: column;
    flex: 0 0 auto;
    width: var(--lk-rail-width);
    padding: var(--lk-space-5) var(--lk-rail-padding-x);

    /*
        A screen tall, not a page tall.

        align-self keeps it from stretching to the shell's height, which is the whole document;
        min-height then makes it at least a screenful. That is what lets the block below sit at
        the foot of the screen when the menu is short, and grow past it when the menu is long.

        The background is the shell's (above), because this box no longer reaches the bottom of a
        long page.
    */
    align-self: flex-start;
    min-height: 100vh;
}

/* A link now, so it needs to lay out like the block it replaced rather than like text. */
.lk-rail-brand[b-dzcqylndpd] {
    display: block;
    padding: 0 var(--lk-space-2) var(--lk-space-5);
}

.lk-rail-organization[b-dzcqylndpd] {
    padding-bottom: var(--lk-space-4);
}

/*
    The nav element belongs to NavigationMenu, so reaching it needs ::deep.

    It takes the height of its entries and no more. It used to be flex: 1, which made it grow to
    fill the rail — and the rail is as tall as the page, not as tall as the screen. On a screen
    with a long list the signed-in person and the way out were pushed to the foot of the whole
    page, far below the last menu entry and out of sight until you scrolled to the very bottom.

    Decision by @martin 2026-09-02, after comparing against the Prototype at a short window
    height. Two other shapes were considered and rejected: a rail that scrolls on its own, as the
    Prototype does, hides entries with nothing to say they are there; and pinning the block to the
    bottom of the viewport leaves it stranded away from the menu it belongs to. Sitting directly
    under the last entry is what keeps it findable — "if we don't pin logout close to the menu, it
    can be perceived as lost."

    The page still scrolls as one, which is deliberate: nothing here scrolls independently, so
    there is no second scrollbar and nothing can be hidden without the page saying so.
*/
.lk-rail[b-dzcqylndpd]  .lk-rail-navigation {
    flex: 0 0 auto;
}

/*
    Two positions, and which one it takes depends on how long the menu is.

    margin-top: auto eats whatever room is left in the rail, so:

    * menu shorter than the screen — the block is pushed to the foot of the screen
    * menu longer than the screen — there is no room left, the margin collapses to nothing, and
      the block sits directly under the last entry, reached by scrolling the page

    Both are what was asked for, and one property covers them because the rail is exactly a
    screen tall until its own contents make it taller.
*/
.lk-rail-user[b-dzcqylndpd] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    margin-top: auto;
    padding-top: var(--lk-space-4);
    border-top: var(--lk-border-hairline) solid var(--lk-rail-line);
}

/* The avatar and the name are one link to the profile. It takes the row's spare width so the
   sign-out icon stays pinned to the far edge. */
.lk-rail-user-link[b-dzcqylndpd] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    flex: 1;
    min-width: 0;
    border-radius: var(--lk-radius-control);
    text-decoration: none;
}

.lk-rail-user-link:hover .lk-rail-user-name[b-dzcqylndpd] {
    text-decoration: underline;
}

.lk-rail-user-link:focus-visible[b-dzcqylndpd] {
    outline: none;
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-focus);
}

.lk-rail-user-text[b-dzcqylndpd] {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.lk-rail-user-name[b-dzcqylndpd] {
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-rail-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.lk-rail-user-role[b-dzcqylndpd] {
    font-size: 0.719rem;
    color: var(--lk-rail-text-mut);
}

/* Pushed to the far edge of the row, away from the name it sits beside. */
.lk-rail-user[b-dzcqylndpd]  .lk-rail-signout {
    margin-left: auto;
}

/*
    The rail stays dark in both themes, so the components inside it cannot use the page's
    ink and surface colors. ::deep is required because these elements belong to the
    components' own markup — without it these rules would do nothing at all (ADR 0007).
*/

.lk-rail[b-dzcqylndpd]  .lk-logo-word {
    color: var(--lk-rail-text);
}

.lk-rail[b-dzcqylndpd]  .lk-avatar-neutral {
    background: var(--lk-rail-surface-strong);
    color: var(--lk-rail-text);
}

.lk-rail[b-dzcqylndpd]  .lk-signout .lk-button {
    color: var(--lk-rail-text-mut);
}

.lk-rail[b-dzcqylndpd]  .lk-signout .lk-button:hover {
    background: var(--lk-rail-surface);
    color: var(--lk-rail-text);
}

/* ── Acting as somebody else ──────────────────────── */

/*
    Only where it sits. What it looks like belongs to ImpersonationBanner, which draws the
    same block in all four layouts — the rail must not own the appearance of something three
    other layouts also show.
*/
.lk-rail[b-dzcqylndpd]  .lk-rail-impersonation {
    margin-bottom: var(--lk-space-3);
}

/* ── Content ────────────────────────────────────────────── */

.lk-main[b-dzcqylndpd] {
    flex: 1;
    min-width: 0;
    overflow: auto;
    padding: var(--lk-space-8) var(--lk-space-10) var(--lk-space-10);
}

/*
    The column cap is the Prototype's, 1720px — `app.css:83`, `.main-inner { max-width: 1720px }`.

    This carried max-width: 62.5rem (1000px), taken faithfully from the design export:
    shell-auth.jsx:100 has exactly `maxWidth: 1000, margin: '0 auto'` on ShellA. Measured against
    the Prototype at 1440 the difference was not subtle — content 1000 against 1110, starting 55px
    further right, so the gap between the rail and the first card was 95px where the Prototype has
    40. Every screen sat too narrow and too far over, not just the overview.

    CLAUDE.md settles which source wins: "Där exporten och Prototypen drar åt olika håll vinner
    Prototypen — den är byggd och genomförd hela vägen, medan exporten är ett förslag." No ADR
    covers content width.

    1720 and not "no cap": the first reading of this said the Prototype had none, from measuring
    at 1440 where a 1720px cap does not bind. It binds above roughly 2080px of viewport. Worth
    remembering as a method note — a single width cannot tell a missing rule from a dormant one.

    The origin is `fa617c1` in the Prototype, "Use full screen width", @niklas 2026-07-09. Its
    message settles why the export says something else: "The design artboards were fixed at
    1320px (hence the 1000px content cap), but on real screens the content should use the width."
    The same commit carries the wide-screen padding below, and the cabinet grid's 420px minimum
    in Pages/Keyboxes/KeyboxListComponent.razor.css — all three were one decision.
*/
.lk-main-inner[b-dzcqylndpd] {
    max-width: 107.5rem;
    margin: 0 auto;
    min-width: 0;
}

/*
    Wide screens get more air, as in the Prototype:
    `@media (min-width: 1800px) { .main { padding: 40px 56px 48px } }`.

    Without it v2's content started 16px further left than the design's at 1920, which is where
    this is actually looked at. 56px needs --lk-space-14; it sits on the same 4px grid as every
    other step, it was simply never needed before.
*/
@media (min-width: 1800px) {
    .lk-main[b-dzcqylndpd] {
        padding: var(--lk-space-10) var(--lk-space-14) var(--lk-space-12);
    }
}

/* ── Skip link ──────────────────────────────────────────── */

/*
    Off-screen until it is focused. Someone navigating by keyboard should not have to tab
    through eight navigation entries on every page to reach the content.
*/
.lk-skip-link[b-dzcqylndpd] {
    position: absolute;
    left: -9999px;
    z-index: 10;
    padding: var(--lk-space-3) var(--lk-space-4);
    background: var(--lk-surface);
    color: var(--lk-ink);
    border-radius: var(--lk-radius-control);
    box-shadow: var(--lk-shadow-md);
    font-weight: 600;
    text-decoration: none;
}

.lk-skip-link:focus[b-dzcqylndpd] {
    left: var(--lk-space-3);
    top: var(--lk-space-3);
}

/* ── Narrow screens ─────────────────────────────────────── */

/*
    The design is drawn at 1320 wide and says nothing about small screens. Rather than
    inventing a mobile navigation, the rail becomes a horizontal band above the content so
    the portal stays usable. A real responsive design is a separate question for the
    designer.
*/
@media (max-width: 60rem) {
    .lk-shell[b-dzcqylndpd] {
        flex-direction: column;
    }

    /* The rail is a band across the top here, so none of the full-height arrangement applies:
       it carries its own colour again, takes its natural height, and the block below follows
       the entries rather than being pushed anywhere. */
    .lk-shell[b-dzcqylndpd] {
        background: var(--lk-canvas);
    }

    .lk-rail[b-dzcqylndpd] {
        width: auto;
        align-self: auto;
        min-height: 0;
        background: var(--lk-rail);
    }

    .lk-rail-user[b-dzcqylndpd] {
        margin-top: 0;
    }

    .lk-rail[b-dzcqylndpd]  .lk-rail-navigation {
        flex: 0 0 auto;
        flex-direction: row;
        flex-wrap: wrap;
    }

    .lk-main[b-dzcqylndpd] {
        padding: var(--lk-space-6) var(--lk-space-4) var(--lk-space-8);
    }
}
/* /Layouts/TopbarLayout.razor.rz.scp.css */
.lk-shell[b-5p3s7hq6nm] {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    background: var(--lk-canvas);
}

/* ── The bar ────────────────────────────────────────────── */

.lk-topbar[b-5p3s7hq6nm] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-6);
    flex: 0 0 auto;
    min-height: 4.5rem;
    padding: var(--lk-space-2) var(--lk-space-8);
    background: var(--lk-surface);
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
}

/* The nav element belongs to NavigationMenu, so reaching it needs ::deep. */
.lk-topbar[b-5p3s7hq6nm]  .lk-topbar-navigation {
    flex: 1;
    justify-content: center;
}

.lk-topbar-actions[b-5p3s7hq6nm] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
}

.lk-topbar-notifications[b-5p3s7hq6nm] {
    position: relative;
    display: inline-flex;
}

/* The avatar is a link to the profile. The ring goes on the link rather than the avatar,
   because the link is what takes focus. */
.lk-topbar-profile[b-5p3s7hq6nm] {
    display: inline-flex;
    border-radius: var(--lk-radius-pill);
    text-decoration: none;
}

.lk-topbar-profile:focus-visible[b-5p3s7hq6nm] {
    outline: none;
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-focus);
}

.lk-topbar-unread[b-5p3s7hq6nm] {
    position: absolute;
    top: 0.5625rem;
    right: 0.5625rem;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: var(--lk-radius-pill);
    background: var(--lk-magenta);
    border: 2px solid var(--lk-surface);
}

/* ── Content ────────────────────────────────────────────── */

/* The design gives this shell more air and a slightly wider column than the sidebar one. */
.lk-main[b-5p3s7hq6nm] {
    flex: 1;
    min-width: 0;
    overflow: auto;
    padding: var(--lk-space-10) var(--lk-space-10) var(--lk-space-12);
}

/*
    Same 1720px cap as the sidebar shell, and for the same reason — see SidebarLayout.razor.css.

    This said 66.25rem (1060px), the design export's ShellB value. Both shells took their cap
    from `design/shell-auth.jsx`, which is locked to the artboard's 1320px width; the Prototype
    left that behind in `fa617c1` ("Use full screen width", @niklas 2026-07-09), whose message
    says the cap "was an artboard artefact". Raising only the sidebar shell would have left this
    one narrow, and the two shells are meant to differ in placement, not in how much of the
    screen they use.
*/
.lk-main-inner[b-5p3s7hq6nm] {
    max-width: 107.5rem;
    margin: 0 auto;
}

/* The wide-screen padding from the same commit. */
@media (min-width: 1800px) {
    .lk-main[b-5p3s7hq6nm] {
        padding: var(--lk-space-10) var(--lk-space-14) var(--lk-space-12);
    }
}

/* ── Skip link ──────────────────────────────────────────── */

.lk-skip-link[b-5p3s7hq6nm] {
    position: absolute;
    left: -9999px;
    z-index: 10;
    padding: var(--lk-space-3) var(--lk-space-4);
    background: var(--lk-surface);
    color: var(--lk-ink);
    border-radius: var(--lk-radius-control);
    box-shadow: var(--lk-shadow-md);
    font-weight: 600;
    text-decoration: none;
}

.lk-skip-link:focus[b-5p3s7hq6nm] {
    left: var(--lk-space-3);
    top: var(--lk-space-3);
}

/* ── Narrow screens ─────────────────────────────────────── */

/*
    As in the sidebar shell: the design says nothing about small screens, so the bar wraps
    rather than a mobile navigation being invented here.
*/
@media (max-width: 60rem) {
    .lk-topbar[b-5p3s7hq6nm] {
        flex-wrap: wrap;
        gap: var(--lk-space-3);
        padding: var(--lk-space-3) var(--lk-space-4);
    }

    .lk-topbar[b-5p3s7hq6nm]  .lk-topbar-navigation {
        order: 3;
        flex-basis: 100%;
        justify-content: flex-start;
    }

    .lk-topbar-actions[b-5p3s7hq6nm] {
        margin-left: auto;
    }

    .lk-main[b-5p3s7hq6nm] {
        padding: var(--lk-space-6) var(--lk-space-4) var(--lk-space-8);
    }
}

/*
    Acting as somebody else. Placement only — the look belongs to ImpersonationBanner, which
    draws the same block in the rail shell (ADR 0005).
*/
.lk-main-inner[b-5p3s7hq6nm]  .lk-topbar-impersonation {
    margin-bottom: var(--lk-space-5);
}
/* /Pages/Account/LoginPage.razor.rz.scp.css */
.login[b-pbk63zqe07] {
    width: 100%;
    max-width: 23.75rem;
}

.login-title[b-pbk63zqe07] {
    margin: 0;
    font-family: var(--lk-font-display);
    font-weight: 800;
    font-size: 1.75rem;
    letter-spacing: -0.02em;
    color: var(--lk-ink);
}

.login-intro[b-pbk63zqe07] {
    margin: var(--lk-space-3) 0 0;
    font-size: var(--lk-font-size-ui);
    line-height: var(--lk-line-height-body);
    color: var(--lk-text-sec);
}

/* ── Messages ───────────────────────────────────────────── */

/*
    One style for every outcome — wrong password, unconfirmed email, two-step verification.
    They are all "this did not sign you in, here is why", and colouring some of them as errors
    and others as information would suggest a difference that does not help the reader.
*/
.login-message[b-pbk63zqe07] {
    margin: var(--lk-space-5) 0 0;
    padding: var(--lk-space-3) var(--lk-space-4);
    border-radius: var(--lk-radius-control);
    background: var(--lk-warn-soft);
    color: var(--lk-warn);
    font-size: var(--lk-font-size-label);
    line-height: var(--lk-line-height-body);
}

.login-handover[b-pbk63zqe07] {
    margin-top: var(--lk-space-3);
}

/* ── Methods ────────────────────────────────────────────── */

.login-methods[b-pbk63zqe07] {
    display: grid;
    gap: var(--lk-space-2);
    margin-top: var(--lk-space-6);
}

.login-divider[b-pbk63zqe07] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    margin: var(--lk-space-5) 0;
}

/* The rules are drawn with pseudo-elements so the text stays the only real content —
   nothing for a screen reader to read out as an element. */
.login-divider[b-pbk63zqe07]::before,
.login-divider[b-pbk63zqe07]::after {
    content: "";
    flex: 1;
    height: var(--lk-border-hairline);
    background: var(--lk-line);
}

.login-divider-text[b-pbk63zqe07] {
    font-size: var(--lk-font-size-caption);
    color: var(--lk-text-mut);
}

/* ── The email form ─────────────────────────────────────── */

.login[b-pbk63zqe07]  .login-form {
    display: grid;
    gap: var(--lk-space-3);
}

.login-link[b-pbk63zqe07] {
    font-size: var(--lk-font-size-caption);
    font-weight: 600;
    color: var(--lk-magenta-ink);
    text-decoration: none;
}

.login-link:hover[b-pbk63zqe07] {
    text-decoration: underline;
}

/* ── Waiting for BankID ─────────────────────────────────── */

.login-bankid[b-pbk63zqe07] {
    text-align: center;
}

.login-bankid-mark[b-pbk63zqe07] {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 5.25rem;
    height: 5.25rem;
    margin: 0 auto var(--lk-space-6);
    border-radius: 1.5rem;
    background: var(--lk-navy);
    color: var(--lk-navy-contrast);
}

/* The ring the design draws around the mark while waiting. */
.login-bankid-mark[b-pbk63zqe07]::after {
    content: "";
    position: absolute;
    inset: -0.375rem;
    border: 2px solid var(--lk-magenta);
    border-radius: 1.75rem;
    opacity: 0.5;
}

/*
    The code brings its own white ground and its own quiet zone — it is a PNG, not markup — so
    what is styled here is the frame around it and nothing else. Deliberately nothing that
    tints or inverts the image itself: a recoloured code is one a phone gives up on, and the
    dark theme would otherwise be the place that happens.
*/
.login-bankid-qr[b-pbk63zqe07] {
    display: block;
    width: 12.25rem;
    height: auto;
    margin: var(--lk-space-5) auto 0;
    padding: var(--lk-space-3);
    border: var(--lk-border-hairline) solid var(--lk-line);
    border-radius: var(--lk-radius-card);
    background: var(--lk-surface);
}

.login-bankid-device[b-pbk63zqe07] {
    margin-top: var(--lk-space-5);
}

.login-bankid-status[b-pbk63zqe07] {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--lk-space-2);
    margin: var(--lk-space-6) 0;
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);

    /* The line was one short sentence until the hint codes got their own words (#445), and
       "BankID-appen har inte startat…" wraps in this column. Without this the wrapped half
       sits flush left beside a centred spinner and reads as a layout fault. */
    text-align: center;
}
/* /Pages/Colleagues/ColleagueDetailPage.razor.rz.scp.css */
/* The Prototype's 1.2fr / 1fr split — contact on the left, role on the right. It collapses
   early rather than at a phone width, for the same reason the profile does: the right column
   holds a single control, and two narrow columns read worse than one wide one well before the
   layout runs out of room. */
.colleague-detail[b-w6z5xthobv] {
    display: grid;
    grid-template-columns: 1.2fr 1fr;
    gap: var(--lk-space-4);
    align-items: start;
}

@media (max-width: 60rem) {
    .colleague-detail[b-w6z5xthobv] {
        grid-template-columns: 1fr;
    }
}

/* ── Back link ──────────────────────────────────────────── */

.colleague-detail-back[b-w6z5xthobv] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-1);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-sec);
    text-decoration: none;
}

.colleague-detail-back:hover[b-w6z5xthobv] {
    color: var(--lk-text);
}

/* ── Role ───────────────────────────────────────────────── */

.colleague-detail-role[b-w6z5xthobv] {
    display: grid;
    gap: var(--lk-space-3);
}

.colleague-detail-role-readonly[b-w6z5xthobv],
.colleague-detail-no-role[b-w6z5xthobv] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
}

/* The outcome of a role change. Both live in the flow rather than over the control, so neither
   covers the picker the reader may want to try again. */
.colleague-detail-status[b-w6z5xthobv] {
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-ok);
}

.colleague-detail-error[b-w6z5xthobv] {
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-err);
}

/* ── What the role may do ───────────────────────────────── */

.colleague-detail-capabilities[b-w6z5xthobv] {
    padding: var(--lk-space-3);
    background: var(--lk-surface-alt);
    border-radius: var(--lk-radius-control);
}

.colleague-detail-capabilities-title[b-w6z5xthobv] {
    margin: 0 0 var(--lk-space-2);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-sec);
}

.colleague-detail-capabilities ul[b-w6z5xthobv] {
    display: grid;
    gap: var(--lk-space-1);
    margin: 0;
    padding: 0;
    list-style: none;
}

.colleague-detail-capabilities li[b-w6z5xthobv] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-body);
    color: var(--lk-text);
}

[b-w6z5xthobv] .colleague-detail-capabilities li .lk-icon {
    flex: 0 0 auto;
    color: var(--lk-ok);
}

/* ── Loading ────────────────────────────────────────────── */

.colleague-detail-loading[b-w6z5xthobv] {
    display: grid;
    gap: var(--lk-space-3);
}
/* /Pages/Colleagues/ColleagueListComponent.razor.rz.scp.css */
/* The Prototype draws these rows as flex divs. They are a real table here, because the data is
   tabular and a table announces row and column without anything being written for it — the same
   reasoning as SortableColumnHeader, which owns the header cells. Same shape as the key list. */

.colleague-list[b-wi7b6f68ea] {
    display: grid;
    gap: var(--lk-space-4);
}

.colleague-table[b-wi7b6f68ea] {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    color: var(--lk-text);
}

.colleague-table th[b-wi7b6f68ea],
.colleague-table td[b-wi7b6f68ea] {
    text-align: left;
    padding: var(--lk-space-3) var(--lk-space-2);
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
    vertical-align: middle;
}

.colleague-table tbody tr:last-child th[b-wi7b6f68ea],
.colleague-table tbody tr:last-child td[b-wi7b6f68ea] {
    border-bottom: none;
}

.colleague-table tbody tr:hover[b-wi7b6f68ea] {
    background: var(--lk-ghost-hover);
}

.colleague-table-heading[b-wi7b6f68ea] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-sec);
}

/* The row heading is the person — it is what identifies the row, so it is a <th> and not a cell.
   The avatar and the two lines of text sit beside each other. */
.colleague-table-name[b-wi7b6f68ea] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    font-weight: 400;
}

.colleague-table-identity[b-wi7b6f68ea] {
    display: grid;
    min-width: 0;
}

.colleague-table-person[b-wi7b6f68ea] {
    font-weight: 600;
    color: var(--lk-text);
}

/* The address under the name. It wraps rather than being clipped: an address cut off halfway is
   worse than one on two lines, because the visible half looks like the whole of it. */
.colleague-table-contact[b-wi7b6f68ea] {
    margin-top: 2px;
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
    overflow-wrap: anywhere;
}

.colleague-table-muted[b-wi7b6f68ea] {
    color: var(--lk-text-sec);
    white-space: nowrap;
}

.colleague-table-actions[b-wi7b6f68ea] {
    text-align: right;
    white-space: nowrap;
}

.colleague-table-actions-heading[b-wi7b6f68ea] {
    text-align: right;
}

/* Present for a screen reader, gone for everyone else. clip-path rather than display:none, which
   would take the label out of the accessibility tree as well. */
.colleague-table-visually-hidden[b-wi7b6f68ea] {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* A link rather than a Button, and therefore styled here rather than inherited — Button renders a
   <button> whose CSS leans on :disabled, which does nothing to an <a>. Same trade recorded in
   KeyListComponent.razor.css. */
.colleague-row-action[b-wi7b6f68ea] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--lk-radius-control);
    color: var(--lk-text-mut);
    text-decoration: none;
    transition: var(--lk-transition);
}

.colleague-row-action:hover[b-wi7b6f68ea] {
    background: var(--lk-ghost-hover);
    color: var(--lk-ink);
}

.colleague-row-action:focus-visible[b-wi7b6f68ea] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

/* ── Loading ────────────────────────────────────────────── */

.colleague-list-loading[b-wi7b6f68ea] {
    display: grid;
    gap: var(--lk-space-4);
}

.colleague-list-loading-row[b-wi7b6f68ea] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
}
/* /Pages/Colleagues/ColleagueMainPage.razor.rz.scp.css */
/* The Prototype's .toolbar. Only a search field here — the status filter is not ported (#321),
   so there is nothing to sit beside it yet. Kept as a flex row rather than collapsed to a bare
   field, because the filter comes back if #321 is answered that way. */

.colleagues-toolbar[b-wn4hevi0uu] {
    display: flex;
    align-items: flex-end;
    gap: var(--lk-space-3);
    margin-bottom: var(--lk-space-4);
}

.colleagues-toolbar[b-wn4hevi0uu]  .colleagues-search {
    flex: 1;
    min-width: 12rem;
}

@media (max-width: 48rem) {
    .colleagues-toolbar[b-wn4hevi0uu] {
        flex-direction: column;
        align-items: stretch;
    }
}

/* The note beside the invite button carries its own placement now — the component takes
   Placement="BesideActions" and shapes itself for a header row (#320).

   This screen held the third of the four copies. */
.colleagues-loading[b-wn4hevi0uu] {
    margin-top: var(--lk-space-4);
}
/* /Pages/Colleagues/InviteColleagueDialog.razor.rz.scp.css */
/* Fields stacked in one column. The Prototype's modal does the same; a two-column form here
   would put the contact field beside the way of reaching them, which is the one pair that has
   to be read in order. */

.invite-form[b-7n23o54tnd] {
    display: grid;
    gap: var(--lk-space-4);
}

/* A failure that is nobody's fault. Field-level problems go on the field instead, so this is
   only ever the API being unreachable or broken. */
.invite-failure[b-7n23o54tnd] {
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-err);
}
/* /Pages/DesignLanguage/DesignLanguagePage.razor.rz.scp.css */
/*
    Page-scoped styling for the internal design-language sheet.

    Same rules as everywhere else: colours and spacing come from variables only. The colour
    swatches below reference tokens, which is why they are allowed to set a background at all.
*/

.dl-header h1[b-y50ek5ju56] {
    margin: 0;
    font-family: var(--lk-font-display);
    font-weight: 800;
    font-size: var(--lk-font-size-display);
    letter-spacing: -0.025em;
    line-height: var(--lk-line-height-tight);
    color: var(--lk-ink);
}

.dl-intro[b-y50ek5ju56] {
    max-width: 44rem;
    margin: var(--lk-space-3) 0 0;
    color: var(--lk-text-sec);
}

.dl-section[b-y50ek5ju56] {
    margin-top: var(--lk-space-10);
}

.dl-section h2[b-y50ek5ju56] {
    margin: 0 0 var(--lk-space-4);
    font-family: var(--lk-font-display);
    font-weight: 700;
    font-size: var(--lk-font-size-eyebrow);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--lk-magenta-ink);
}

.dl-note[b-y50ek5ju56] {
    max-width: 44rem;
    margin: 0 0 var(--lk-space-4);
    font-size: var(--lk-font-size-caption);
    color: var(--lk-text-mut);
}

.dl-row[b-y50ek5ju56] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--lk-space-3);
    margin-bottom: var(--lk-space-4);
}

.dl-row-label[b-y50ek5ju56] {
    flex: 0 0 7rem;
    font-size: var(--lk-font-size-caption);
    font-weight: 600;
    color: var(--lk-text-mut);
}

.dl-grid[b-y50ek5ju56] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: var(--lk-space-4);
}

/* ── Preference switches ────────────────────────────────── */

.design-language[b-y50ek5ju56]  .dl-switches {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-6);
    margin-top: var(--lk-space-6);
}

.dl-switch-group[b-y50ek5ju56] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
}

.dl-switch-label[b-y50ek5ju56] {
    font-size: var(--lk-font-size-caption);
    font-weight: 600;
    color: var(--lk-text-mut);
}

.dl-switches a[b-y50ek5ju56] {
    color: var(--lk-magenta-ink);
    font-weight: 600;
    font-size: var(--lk-font-size-label);
}

/* ── Colour ─────────────────────────────────────────────── */

.dl-swatches[b-y50ek5ju56] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-4);
}

.dl-swatch[b-y50ek5ju56] {
    width: 8.25rem;
}

.dl-swatch-chip[b-y50ek5ju56] {
    height: 3.75rem;
    border-radius: var(--lk-radius-control);
    border: var(--lk-border-hairline) solid var(--lk-line);
}

.dl-swatch-name[b-y50ek5ju56] {
    display: block;
    margin-top: var(--lk-space-2);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-ink);
}

.dl-chip-navy[b-y50ek5ju56] { background: var(--lk-navy); }
.dl-chip-magenta[b-y50ek5ju56] { background: var(--lk-magenta); }
.dl-chip-canvas[b-y50ek5ju56] { background: var(--lk-canvas); }
.dl-chip-surface[b-y50ek5ju56] { background: var(--lk-surface); }
.dl-chip-text-sec[b-y50ek5ju56] { background: var(--lk-text-sec); }
.dl-chip-ok[b-y50ek5ju56] { background: var(--lk-ok); }
.dl-chip-warn[b-y50ek5ju56] { background: var(--lk-warn); }
.dl-chip-err[b-y50ek5ju56] { background: var(--lk-err); }
.dl-chip-info[b-y50ek5ju56] { background: var(--lk-info); }

/* ── Typography ─────────────────────────────────────────── */

.dl-type-display[b-y50ek5ju56],
.dl-type-title[b-y50ek5ju56],
.dl-card-title[b-y50ek5ju56] {
    margin: 0 0 var(--lk-space-2);
    font-family: var(--lk-font-display);
    color: var(--lk-ink);
    letter-spacing: -0.02em;
}

.dl-type-display[b-y50ek5ju56] {
    font-weight: 800;
    font-size: var(--lk-font-size-display);
}

.dl-type-title[b-y50ek5ju56] {
    font-weight: 800;
    font-size: var(--lk-font-size-title);
}

.dl-card-title[b-y50ek5ju56] {
    font-weight: 700;
    font-size: 1.125rem;
}

.dl-type-body[b-y50ek5ju56] {
    max-width: 34rem;
    margin: 0 0 var(--lk-space-2);
    font-size: var(--lk-font-size-body);
    color: var(--lk-text);
}

.dl-type-label[b-y50ek5ju56] {
    margin: 0;
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-sec);
}

/* ── Loading placeholders ───────────────────────────────── */

.dl-skeleton-row[b-y50ek5ju56] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    margin-bottom: var(--lk-space-4);
}

.dl-skeleton-row:last-child[b-y50ek5ju56] {
    margin-bottom: 0;
}

.dl-skeleton-lines[b-y50ek5ju56] {
    display: flex;
    flex-direction: column;
    gap: var(--lk-space-2);
    flex: 1;
}

/* ── Icons ──────────────────────────────────────────────── */

.dl-icons[b-y50ek5ju56] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-2);
}

.dl-icon[b-y50ek5ju56] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface);
    border: var(--lk-border-hairline) solid var(--lk-line);
    color: var(--lk-text-sec);
}
/* /Pages/Devices/DeviceMainPage.razor.rz.scp.css */
/*
    Scoped to the page. Tokens only — no colour or spacing literals.

    The card is a two-column split: everything known about the hardware on the left, the
    timestamps and the one action on the right. It collapses to one column early, because the
    hardware line carries a lot of small facts and they stop being readable before the card
    itself gets narrow.
*/

/* Same gap as the list below, so the rows do not shift when the skeletons are replaced. */
.devices-loading[b-qckadcl76f] {
    display: grid;
    gap: var(--lk-space-3);
}

.devices-list[b-qckadcl76f] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    /* The design's 12px. space-4 is 16 — a step out, not the #528 rounding. */
    gap: var(--lk-space-3);
}

/*
    ::deep, because "devices-card" is a class handed to the Card component and lands on Card's
    own root element — which carries Card's scope id, not this page's. Without ::deep the rule
    matched nothing and said nothing: the card fell back to display:block, the aside stacked
    under the main column instead of beside it, and every row was 232px where the design draws
    141. It went unseen from 2026-09-02 to 2026-09-07 because the Agents table was empty
    locally, so the card had never once been rendered with data in it.

    The two rules below this one work without ::deep, and that contrast is the trap: they are
    aimed at .devices-card-main and .devices-card-aside, which are this page's own markup passed
    in as ChildContent, so they carry this page's scope. Same file, same-looking selectors, two
    different outcomes.
*/
.devices-list[b-qckadcl76f]  .devices-card {
    display: flex;
    align-items: flex-start;
    /* The design's 18px, which the scale rounds to 20 (#528). space-6 is 24 — a whole step
       past it, which is the difference between rounding and drift. */
    gap: var(--lk-space-5);
    flex-wrap: wrap;
}

.devices-card-main[b-qckadcl76f] {
    flex: 1;
    min-width: 17rem;
}

.devices-card-aside[b-qckadcl76f] {
    display: grid;
    gap: var(--lk-space-3);
    justify-items: end;
    text-align: right;
    min-width: 11rem;
}

.devices-card-heading[b-qckadcl76f] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    flex-wrap: wrap;
}

/*
    The enrolment code is read off the device's own waiting screen and typed into nothing — it
    is matched by eye against the physical board. Monospace and letter-spacing so that O and 0
    are told apart at a glance, which is the whole job of this element, and the reason this is
    a span rather than a Badge.

    Everything else about it comes from the badge: in the design it is a .badge.info, the same
    badge as the hardware tags beside it, so it takes the pill radius and 0.75rem — the literal
    Badge.razor.css writes. Not --lk-font-size-caption (12.5px), because the code sits inline
    with real Badge components and half a pixel apart from them would show. That 12px has no
    token is a real gap in the type scale, now written in two places; issue raised.
*/
.devices-code[b-qckadcl76f] {
    font-family: var(--lk-font-mono, ui-monospace, "Cascadia Mono", "SFMono-Regular", Consolas, monospace);
    letter-spacing: 0.08em;
    padding: var(--lk-space-1) var(--lk-space-2);
    border-radius: var(--lk-radius-pill);
    background: var(--lk-info-soft);
    color: var(--lk-info);
    font-size: 0.75rem;
    font-weight: 600;
}

/* The design's card heading size, 15.5px — the token added in #562. Without it the model name
   inherited the body size and sat a step below the code badge it is meant to lead. */
.devices-model[b-qckadcl76f] {
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-card-title);
    font-weight: 700;
    color: var(--lk-ink);
}

.devices-meta[b-qckadcl76f],
.devices-network[b-qckadcl76f],
.devices-seen[b-qckadcl76f] {
    margin: var(--lk-space-2) 0 0;
    color: var(--lk-text-sec);
    font-size: var(--lk-font-size-label);
}

.devices-network[b-qckadcl76f] {
    color: var(--lk-text-mut);
}

.devices-seen[b-qckadcl76f] {
    display: grid;
    gap: var(--lk-space-1);
    margin: 0;
}

.devices-tags[b-qckadcl76f] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-2);
    margin-top: var(--lk-space-3);
}

/* Confirmation of something that just happened, not a warning — quiet, and it goes away on
   the next action rather than needing dismissal. */
.devices-notice[b-qckadcl76f] {
    margin-bottom: var(--lk-space-4);
    padding: var(--lk-space-3) var(--lk-space-4);
    border-radius: var(--lk-radius-control);
    background: var(--lk-ok-soft);
    color: var(--lk-text);
    font-size: var(--lk-font-size-label);
}

.devices-form[b-qckadcl76f] {
    display: grid;
    gap: var(--lk-space-4);
}

.devices-form-lead[b-qckadcl76f],
.devices-form-empty[b-qckadcl76f],
.devices-form-info[b-qckadcl76f] {
    margin: 0;
    color: var(--lk-text-sec);
    font-size: var(--lk-font-size-label);
}

.devices-form-info[b-qckadcl76f] {
    padding: var(--lk-space-3) var(--lk-space-4);
    border-radius: var(--lk-radius-control);
    background: var(--lk-info-soft);
    color: var(--lk-text-sec);
}

@media (max-width: 44rem) {
    .devices-card-aside[b-qckadcl76f] {
        justify-items: start;
        text-align: left;
        min-width: 0;
    }
}

/* The design's empty queue: one card, 28px of padding, centred text and no icon.

   ::deep because .lk-empty belongs to EmptyState — a page-scoped rule aimed at another
   component's markup matches nothing without it, and fails silently (CLAUDE.md). The card is
   unpadded so this is the only padding in play rather than a second one added to it: the
   component's own 48px on top of the card's 20 put the heading 68px down, against the design's
   28. */
.devices-empty[b-qckadcl76f]  .lk-empty {
    padding: var(--lk-space-8);
}
/* /Pages/Events/EventListComponent.razor.rz.scp.css */
/* The Prototype draws these rows as flex divs. They are a real table here, because the data is
   tabular and a table announces row and column without anything being written for it — the same
   reasoning as SortableColumnHeader, which owns the header cells. Same shape as the identity
   list. */

.event-list[b-z8r5thwtj7] {
    display: grid;
    gap: var(--lk-space-4);
}

.event-table[b-z8r5thwtj7] {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    color: var(--lk-text);
}

.event-table th[b-z8r5thwtj7],
.event-table td[b-z8r5thwtj7] {
    text-align: left;
    padding: var(--lk-space-3) var(--lk-space-2);
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
    vertical-align: middle;
}

.event-table tbody tr:last-child th[b-z8r5thwtj7],
.event-table tbody tr:last-child td[b-z8r5thwtj7] {
    border-bottom: none;
}

.event-table tbody tr:hover[b-z8r5thwtj7] {
    background: var(--lk-ghost-hover);
}

/* The timestamp identifies the row, so it is a <th> rather than a cell — the event's own id is
   never shown. Tabular figures so a column of times lines up digit under digit, which is what
   makes a log scannable; without them a 1 is narrower than a 7 and the minutes drift. */
.event-table-time[b-z8r5thwtj7] {
    font-weight: 500;
    color: var(--lk-text-sec);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Icon and badge on one line. The icon is decoration — the word is in the badge beside it — so
   it is allowed to be the part that goes if the row is squeezed. */
.event-table-kind[b-z8r5thwtj7] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
}

.event-table-muted[b-z8r5thwtj7] {
    color: var(--lk-text-sec);
    overflow-wrap: anywhere;
}

/* ── Loading ────────────────────────────────────────────── */

.event-list-loading[b-z8r5thwtj7] {
    display: grid;
    gap: var(--lk-space-4);
}

.event-list-loading-row[b-z8r5thwtj7] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
}
/* /Pages/Events/EventMainPage.razor.rz.scp.css */
/* The Prototype's .toolbar: a search field with the type, keybox and date filters beside it.
   Same shape as the identities toolbar, with five controls rather than three. */

.events-toolbar[b-9estwvxm2d] {
    display: flex;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: var(--lk-space-3);
    margin-bottom: var(--lk-space-4);
}

.events-toolbar[b-9estwvxm2d]  .events-search {
    flex: 1;
    min-width: 12rem;
}

/* Wide enough for the longest event word in any of the six languages, so the box does not
   resize as the selection changes. */
.events-toolbar[b-9estwvxm2d]  .events-filter {
    min-width: 12rem;
}

/* A date input renders its own picker, and browsers size it from the control rather than from
   the box — narrower than this and the placeholder text clips on Firefox. */
.events-toolbar[b-9estwvxm2d]  .events-date {
    min-width: 9.5rem;
}

/* The toolbar wraps on its own above; below this the filters are worth a full line each rather
   than two cramped columns, because a date field that has wrapped mid-pair reads as one range
   split across rows. */
@media (max-width: 48rem) {
    .events-toolbar[b-9estwvxm2d] {
        flex-direction: column;
        align-items: stretch;
    }
}

.events-loading[b-9estwvxm2d] {
    margin-top: var(--lk-space-4);
}
/* /Pages/Identities/IdentityListComponent.razor.rz.scp.css */
/* The Prototype draws these rows as flex divs. They are a real table here, because the data is
   tabular and a table announces row and column without anything being written for it — the same
   reasoning as SortableColumnHeader, which owns the header cells. Same shape as the colleague
   list. */

.identity-list[b-347kia1i4s] {
    display: grid;
    gap: var(--lk-space-4);
}

.identity-table[b-347kia1i4s] {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    color: var(--lk-text);
}

.identity-table th[b-347kia1i4s],
.identity-table td[b-347kia1i4s] {
    text-align: left;
    padding: var(--lk-space-3) var(--lk-space-2);
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
    vertical-align: middle;
}

.identity-table tbody tr:last-child th[b-347kia1i4s],
.identity-table tbody tr:last-child td[b-347kia1i4s] {
    border-bottom: none;
}

.identity-table tbody tr:hover[b-347kia1i4s] {
    background: var(--lk-ghost-hover);
}

.identity-table-heading[b-347kia1i4s] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-sec);
}

/* The name identifies the row, so it is a <th> rather than a cell. */
.identity-table-name[b-347kia1i4s] {
    font-weight: 600;
    color: var(--lk-text);
    overflow-wrap: anywhere;
}

/* Roles come several to a row and wrap rather than clip: a truncated list of roles looks like a
   complete one, which is the wrong way for this screen to be wrong. */
.identity-table-badges[b-347kia1i4s] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-1);
}

.identity-table-muted[b-347kia1i4s] {
    color: var(--lk-text-sec);
}

/* ── Loading ────────────────────────────────────────────── */

.identity-list-loading[b-347kia1i4s] {
    display: grid;
    gap: var(--lk-space-4);
}

.identity-list-loading-row[b-347kia1i4s] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
}

/* The Act-as column. Right-aligned so the buttons form one edge rather than a ragged one,
   and narrow so it takes no width from the name. */
.identity-table-action[b-347kia1i4s] {
    width: 1%;
    text-align: right;
    white-space: nowrap;
}
/* /Pages/Identities/IdentityMainPage.razor.rz.scp.css */
/* The Prototype's .toolbar: a search field with the type and role filters beside it. Same shape
   as the colleagues toolbar, with the two selects the Prototype has and that screen does not. */

.identities-toolbar[b-ysh998pt4i] {
    display: flex;
    align-items: flex-end;
    gap: var(--lk-space-3);
    margin-bottom: var(--lk-space-4);
}

.identities-toolbar[b-ysh998pt4i]  .identities-search {
    flex: 1;
    min-width: 12rem;
}

/* Wide enough for the longest role name the API defines — keylendingterminal — so the box does
   not resize as the selection changes. */
.identities-toolbar[b-ysh998pt4i]  .identities-filter {
    min-width: 11rem;
}

@media (max-width: 60rem) {
    .identities-toolbar[b-ysh998pt4i] {
        flex-wrap: wrap;
    }

    .identities-toolbar[b-ysh998pt4i]  .identities-search {
        flex-basis: 100%;
    }
}

@media (max-width: 48rem) {
    .identities-toolbar[b-ysh998pt4i] {
        flex-direction: column;
        align-items: stretch;
    }
}

.identities-loading[b-ysh998pt4i] {
    margin-top: var(--lk-space-4);
}

/* The line inside the confirmation. */
.identities-confirm-body[b-ysh998pt4i] {
    margin: 0;
    color: var(--lk-ink-mut);
    line-height: 1.5;
}
/* /Pages/Keyboxes/KeyboxDetailPage.razor.rz.scp.css */
/* The way back to the list. An anchor styled as a quiet action rather than a Button, for the
   reason the markup gives — the same arrangement as the key detail's back link. */
/* Its own line above the eyebrow, as the Prototype's BackLink sits — the same spacing the kiosk
   detail already uses for the same row (#561). */
.keybox-detail-back-row[b-t7otgu0rym] {
    margin-bottom: var(--lk-space-3);
}

.keybox-detail-back[b-t7otgu0rym] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-1);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-sec);
    text-decoration: none;
    transition: color var(--lk-transition);
}

.keybox-detail-back:hover[b-t7otgu0rym] {
    color: var(--lk-ink);
}

.keybox-detail-loading[b-t7otgu0rym] {
    display: grid;
    gap: var(--lk-space-3);
    margin-top: var(--lk-space-4);
}
/* /Pages/Keyboxes/KeyboxKeyListComponent.razor.rz.scp.css */
/* Same shape as the colleague and key tables: a real table, because the data is tabular and a
   table announces row and column without anything being written for it. */

.keybox-key-list[b-og5ib2af1e] {
    display: grid;
    gap: var(--lk-space-4);
}

.keybox-key-list-toolbar[b-og5ib2af1e] {
    display: flex;
    align-items: flex-end;
    gap: var(--lk-space-3);
}

.keybox-key-list-toolbar[b-og5ib2af1e]  .keybox-key-list-search {
    max-width: 22rem;
    flex: 1;
}

.keybox-key-table[b-og5ib2af1e] {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    color: var(--lk-text);
}

.keybox-key-table th[b-og5ib2af1e],
.keybox-key-table td[b-og5ib2af1e] {
    text-align: left;
    padding: var(--lk-space-3) var(--lk-space-2);
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
    vertical-align: middle;
}

.keybox-key-table tbody tr:last-child td[b-og5ib2af1e] {
    border-bottom: none;
}

.keybox-key-table tbody tr:hover[b-og5ib2af1e] {
    background: var(--lk-ghost-hover);
}

/* The slot number is the column people scan down, so it is set in the display face and given a
   fixed width — a number that moves left and right between rows is harder to read than one that
   does not. */
.keybox-key-table-slot[b-og5ib2af1e] {
    width: 6rem;
    font-family: var(--lk-font-display);
    font-weight: 700;
    color: var(--lk-ink);
}

/* Quieter than a number, because it is the absence of one. */
.keybox-key-table-no-slot[b-og5ib2af1e] {
    font-family: var(--lk-font-ui);
    font-weight: 400;
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
}

.keybox-key-table-name[b-og5ib2af1e] {
    color: var(--lk-ink);
    font-weight: 600;
    text-decoration: none;
}

.keybox-key-table-name:hover[b-og5ib2af1e] {
    text-decoration: underline;
}

@media (max-width: 48rem) {
    .keybox-key-list-toolbar[b-og5ib2af1e] {
        flex-direction: column;
        align-items: stretch;
    }

    .keybox-key-list-toolbar[b-og5ib2af1e]  .keybox-key-list-search {
        max-width: none;
    }
}
/* /Pages/Keyboxes/KeyboxListComponent.razor.rz.scp.css */
/* Cards rather than rows, following the Prototype's grid. A cabinet is a physical object with a
   place and a state, and there are a handful of them — a table would give it columns it does not
   have and an ordering nobody asked for. */

.keybox-list[b-07gl9rc10k] {
    display: grid;
    gap: var(--lk-space-4);
}

/* auto-fill with a minimum, as the Prototype does: one column on a phone, as many as fit on a
   wide screen, without a breakpoint per size.

   26.25rem is the Prototype's 420px. This said 20rem (320px), which took the pattern from
   `fa617c1` ("Use full screen width", @niklas 2026-07-09) but not its number — that commit set
   the minimum precisely so that a wide screen gets three columns of a readable width. At 320px
   it gets more columns, each narrower. The loading grid below carries the same value so the
   layout does not jump when the real cards arrive. */
.keybox-grid[b-07gl9rc10k] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(26.25rem, 1fr));
    gap: var(--lk-space-4);
    list-style: none;
    margin: 0;
    padding: 0;
}

/* The whole card is one anchor. Grid rather than flex so the identity column is the one that
   gives way when the name is long — the mark and the status keep their size. */
.keybox-card[b-07gl9rc10k] {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--lk-space-3);
    /* The Prototype's .card.pad.hover: 20px of padding and the medium shadow at rest — .hover is
       a static class there, not a pointer state. Both were a step short here, which made the
       cards read flatter and tighter than every other card on the screen. */
    padding: var(--lk-space-5);
    border: var(--lk-border-hairline) solid var(--lk-line);
    border-radius: var(--lk-radius-card);
    background: var(--lk-surface);
    box-shadow: var(--lk-shadow-md);
    text-decoration: none;
    color: inherit;
    transition: var(--lk-transition);
}

.keybox-card:hover[b-07gl9rc10k] {
    background: var(--lk-ghost-hover);
    border-color: var(--lk-line-strong);
}

.keybox-card:focus-visible[b-07gl9rc10k] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

.keybox-card-mark[b-07gl9rc10k] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    border-radius: var(--lk-radius-tile);
    background: var(--lk-navy-soft);
    color: var(--lk-ink);
    flex: none;
}

.keybox-card-identity[b-07gl9rc10k] {
    display: grid;
    gap: var(--lk-space-1);
    min-width: 0;
}

/* The display font, as the Prototype gives the cabinet name on its card — it is the one thing
   read from across a room. Truncated rather than wrapped: a name that takes two lines pushes the
   place out of alignment with every neighbouring card. */
.keybox-card-name[b-07gl9rc10k] {
    font-family: var(--lk-font-display);
    font-weight: 800;
    font-size: var(--lk-font-size-title-sm);
    color: var(--lk-ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.keybox-card-place[b-07gl9rc10k] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-1);
    min-width: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-sec);
}

.keybox-card-place span[b-07gl9rc10k] {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.keybox-card-status[b-07gl9rc10k] {
    display: grid;
    justify-items: end;
    gap: var(--lk-space-1);
    flex: none;
}

/* Tabular figures so the eight characters line up card to card — it is an identifier being
   scanned down a column, not prose. */
.keybox-card-reference[b-07gl9rc10k] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
    font-variant-numeric: tabular-nums;
    color: var(--lk-text-mut);
}

/* ── Loading ────────────────────────────────────────────── */

.keybox-list-loading[b-07gl9rc10k] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(26.25rem, 1fr));
    gap: var(--lk-space-4);
}

/* The skeleton borrows the card's frame so the grid does not resize when the real cards arrive. */
.keybox-card-skeleton[b-07gl9rc10k] {
    grid-template-columns: auto minmax(0, 1fr);
}

.keybox-card-skeleton:hover[b-07gl9rc10k] {
    background: var(--lk-surface);
    border-color: var(--lk-line);
}

.keybox-card-skeleton-lines[b-07gl9rc10k] {
    display: grid;
    gap: var(--lk-space-2);
    min-width: 0;
}
/* /Pages/Keyboxes/KeyboxMainPage.razor.rz.scp.css */
/* The Prototype's .toolbar, with one control instead of two: the status filter is not ported
   (#329), so the search field has the row to itself. */

.keyboxes-toolbar[b-ygqo8937oy] {
    display: flex;
    align-items: flex-end;
    gap: var(--lk-space-3);
    margin-bottom: var(--lk-space-4);
}

.keyboxes-toolbar[b-ygqo8937oy]  .keyboxes-search {
    flex: 1;
    min-width: 12rem;
}

.keyboxes-loading[b-ygqo8937oy] {
    margin-top: var(--lk-space-4);
}
/* /Pages/Keys/BookingTimeline.razor.rz.scp.css */
/* The day as a bar. Taken stretches are outlined and dashed, the chosen one is filled — a
   difference in shape as well as in colour, so it survives being read by someone who does not
   separate the two hues. Same reasoning as the key list's status dots. */

.booking-timeline-track[b-ghh0eoffq2] {
    position: relative;
    height: var(--lk-control-height-lg);
    border-radius: var(--lk-radius-control);
    background: var(--lk-sunken);
    border: var(--lk-border-width) solid var(--lk-line);
    overflow: hidden;
}

.booking-timeline-busy[b-ghh0eoffq2],
.booking-timeline-chosen[b-ghh0eoffq2] {
    position: absolute;
    top: var(--lk-space-1);
    bottom: var(--lk-space-1);
    display: flex;
    align-items: center;
    padding: 0 var(--lk-space-2);
    border-radius: var(--lk-radius-sm);
    overflow: hidden;
}

.booking-timeline-busy[b-ghh0eoffq2] {
    background: var(--lk-surface-alt);
    border: var(--lk-border-width) dashed var(--lk-text-sec);
}

/* Draggable, so it says so with the cursor. touch-action:none stops the browser scrolling the
   page instead of handing us the pointer moves on a touch screen. */
.booking-timeline-chosen[b-ghh0eoffq2] {
    background: var(--lk-magenta);
    justify-content: center;
    box-shadow: var(--lk-shadow-sm);
    cursor: grab;
    touch-action: none;
    user-select: none;
}

.booking-timeline-chosen-dragging[b-ghh0eoffq2] {
    cursor: grabbing;
}

/* The two edges. Wide enough to hit without magnifying the block, and inside it so they never
   overlap a neighbouring booking. */
.booking-timeline-handle[b-ghh0eoffq2] {
    position: absolute;
    top: var(--lk-space-1);
    bottom: var(--lk-space-1);
    width: var(--lk-space-2);
    border-radius: var(--lk-radius-sm);
    background: var(--lk-magenta-contrast);
    opacity: 0.55;
    cursor: ew-resize;
}

.booking-timeline-handle-start[b-ghh0eoffq2] {
    left: 3px;
}

.booking-timeline-handle-end[b-ghh0eoffq2] {
    right: 3px;
}

/* The track owns the gesture once a drag starts, so it must not scroll under the pointer. */
.booking-timeline-track[b-ghh0eoffq2] {
    touch-action: none;
}

.booking-timeline-busy-label[b-ghh0eoffq2],
.booking-timeline-chosen-label[b-ghh0eoffq2] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
    font-weight: 600;
    white-space: nowrap;
}

.booking-timeline-busy-label[b-ghh0eoffq2] {
    color: var(--lk-text);
}

.booking-timeline-chosen-label[b-ghh0eoffq2] {
    color: var(--lk-magenta-contrast);
}

.booking-timeline-scale[b-ghh0eoffq2] {
    display: flex;
    justify-content: space-between;
    margin-top: var(--lk-space-1);
}

.booking-timeline-hour[b-ghh0eoffq2] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
    color: var(--lk-text-mut);

    /* Digits of equal width, so the scale does not jitter between hours. */
    font-variant-numeric: tabular-nums;
}
/* /Pages/Keys/KeyBookingPage.razor.rz.scp.css */
/* Calendar beside the summary, as the Prototype has it — the calendar is where the work
   happens, so it takes the wider column. They stack on a narrow screen: two columns of this
   width would leave the day tiles too small to hit. */
.key-booking-layout[b-8x70nregh4] {
    display: grid;
    grid-template-columns: 1.6fr 1fr;
    gap: var(--lk-space-4);
    align-items: start;
}

@media (max-width: 900px) {
    .key-booking-layout[b-8x70nregh4] {
        grid-template-columns: 1fr;
    }
}

.key-booking-loading[b-8x70nregh4] {
    display: grid;
    grid-template-columns: 1.6fr 1fr;
    gap: var(--lk-space-4);
    align-items: start;
}

@media (max-width: 900px) {
    .key-booking-loading[b-8x70nregh4] {
        grid-template-columns: 1fr;
    }
}

.key-booking-back[b-8x70nregh4] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-1);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-sec);
    text-decoration: none;
    border-radius: var(--lk-radius-sm);
    padding: var(--lk-space-2) var(--lk-space-3);
}

.key-booking-back:hover[b-8x70nregh4] {
    color: var(--lk-ink);
    background: var(--lk-navy-soft);
}

.key-booking-back:focus-visible[b-8x70nregh4] {
    outline: none;
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-focus);
}

/* ── The fortnight ──────────────────────────────────────── */

.key-booking-week[b-8x70nregh4] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    margin-bottom: var(--lk-space-4);
}

.key-booking-week-title[b-8x70nregh4] {
    flex: 1;
    margin: 0;
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-title);
    font-weight: 700;
    color: var(--lk-ink);
}

.key-booking-week-nav[b-8x70nregh4] {
    display: flex;
    gap: var(--lk-space-1);
}

.key-booking-days[b-8x70nregh4] {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: var(--lk-space-2);
    margin-bottom: var(--lk-space-5);
}

.key-booking-day[b-8x70nregh4] {
    display: grid;
    justify-items: center;
    gap: var(--lk-space-1);
    padding: var(--lk-space-3) var(--lk-space-1);
    border: var(--lk-border-width) solid var(--lk-line);
    border-radius: var(--lk-radius-tile);
    background: var(--lk-surface);
    cursor: pointer;
    transition: var(--lk-transition);
}

.key-booking-day:hover:not(:disabled)[b-8x70nregh4] {
    border-color: var(--lk-line-strong);
}

.key-booking-day:focus-visible[b-8x70nregh4] {
    outline: none;
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-focus);
}

/* Chosen is a thicker border and a tinted ground, not colour alone — the tile has to read as
   picked without relying on hue. */
.key-booking-day-selected[b-8x70nregh4] {
    border-color: var(--lk-magenta);
    background: var(--lk-magenta-soft);
}

.key-booking-day:disabled[b-8x70nregh4] {
    background: var(--lk-surface-alt);
    cursor: default;
    opacity: 0.55;
}

.key-booking-day-name[b-8x70nregh4] {
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-caption);
    font-weight: 700;
    letter-spacing: 0.5px;
    color: var(--lk-text-mut);
}

.key-booking-day-number[b-8x70nregh4] {
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-title);
    font-weight: 800;
    color: var(--lk-ink);
    font-variant-numeric: tabular-nums;
}

.key-booking-day-selected .key-booking-day-number[b-8x70nregh4] {
    color: var(--lk-magenta-ink);
}

.key-booking-day-note[b-8x70nregh4] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
    color: var(--lk-text-mut);
    min-height: 1em;
}

/* ── The day ────────────────────────────────────────────── */

.key-booking-day-header[b-8x70nregh4] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    flex-wrap: wrap;
    margin-bottom: var(--lk-space-3);
}

.key-booking-day-title[b-8x70nregh4] {
    flex: 1;
    margin: 0;
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-body);
    font-weight: 700;
    color: var(--lk-ink);
}

.key-booking-legend[b-8x70nregh4] {
    display: flex;
    gap: var(--lk-space-3);
    flex-wrap: wrap;
}

.key-booking-legend-item[b-8x70nregh4] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-1);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
    color: var(--lk-text-sec);
}

.key-booking-swatch[b-8x70nregh4] {
    width: var(--lk-space-5);
    height: var(--lk-space-3);
    border-radius: var(--lk-radius-sm);
}

.key-booking-swatch-busy[b-8x70nregh4] {
    background: var(--lk-surface-alt);
    border: var(--lk-border-width) dashed var(--lk-text-sec);
}

.key-booking-swatch-chosen[b-8x70nregh4] {
    background: var(--lk-magenta);
}

.key-booking-times[b-8x70nregh4] {
    display: flex;
    align-items: flex-end;
    gap: var(--lk-space-3);
    flex-wrap: wrap;
    margin-top: var(--lk-space-4);
}

/* The field element belongs to the TextField component, so reaching it needs ::deep — without
   it these two rules would read as correct and do nothing at all (ADR 0007). */
.key-booking-times[b-8x70nregh4]  .lk-field {
    flex: 1;
    min-width: 130px;
}

.key-booking-allday[b-8x70nregh4] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    padding-bottom: var(--lk-space-3);
}

.key-booking-allday-label[b-8x70nregh4] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text);
}

.key-booking-status[b-8x70nregh4] {
    margin: var(--lk-space-3) 0 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-sec);
}

/* ── The summary ────────────────────────────────────────── */

/* The card element belongs to the Card component, hence ::deep — same as PanelCard. */
[b-8x70nregh4] .key-booking-summary {
    display: grid;
    gap: var(--lk-space-4);
}

.key-booking-summary-title[b-8x70nregh4] {
    margin: 0;
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-body);
    font-weight: 700;
    color: var(--lk-ink);
}

.key-booking-facts[b-8x70nregh4] {
    margin: 0;
    display: grid;
    gap: var(--lk-space-2);
}

.key-booking-fact[b-8x70nregh4] {
    display: flex;
    align-items: baseline;
    gap: var(--lk-space-3);
}

.key-booking-fact-label[b-8x70nregh4] {
    flex: 1;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
}

.key-booking-fact-value[b-8x70nregh4] {
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text);
    text-align: right;
}

/* ── Who it is booked for ───────────────────────────────── */

.key-booking-person[b-8x70nregh4] {
    display: grid;
    gap: var(--lk-space-2);
}

.key-booking-person-label[b-8x70nregh4] {
    display: block;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text);
    margin-bottom: var(--lk-space-2);
}

/* The chosen person, marked the way the chosen day is: a tinted ground and a stronger border,
   so it reads as settled rather than as another field waiting to be filled in. */
.key-booking-person-row[b-8x70nregh4] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
    padding: var(--lk-space-2) var(--lk-space-3);
    border: var(--lk-border-width) solid var(--lk-magenta);
    border-radius: var(--lk-radius-control);
    background: var(--lk-magenta-soft);
}

.key-booking-matches[b-8x70nregh4] {
    list-style: none;
    margin: 0;
    padding: 0;
    border: var(--lk-border-width) solid var(--lk-line);
    border-radius: var(--lk-radius-control);
    overflow: hidden;
}

.key-booking-match[b-8x70nregh4] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
    width: 100%;
    padding: var(--lk-space-2) var(--lk-space-3);
    background: var(--lk-surface);
    text-align: left;
    cursor: pointer;
}

.key-booking-matches li + li .key-booking-match[b-8x70nregh4] {
    border-top: var(--lk-border-width) solid var(--lk-line);
}

.key-booking-match:hover[b-8x70nregh4] {
    background: var(--lk-ghost-hover);
}

.key-booking-match:focus-visible[b-8x70nregh4] {
    outline: none;
    box-shadow: inset 0 0 0 var(--lk-focus-ring-width) var(--lk-focus);
}

.key-booking-match-text[b-8x70nregh4] {
    flex: 1;
    min-width: 0;
}

.key-booking-match-name[b-8x70nregh4],
.key-booking-match-mail[b-8x70nregh4] {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.key-booking-match-name[b-8x70nregh4] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text);
}

.key-booking-match-mail[b-8x70nregh4] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
    color: var(--lk-text-mut);
}

.key-booking-note[b-8x70nregh4] {
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
    line-height: var(--lk-line-height-body);
}

.key-booking-failure[b-8x70nregh4] {
    margin: 0;
    padding: var(--lk-space-3);
    background: var(--lk-err-soft);
    border-radius: var(--lk-radius-sm);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-err);
}

/* ── The receipt ────────────────────────────────────────── */

.key-booking-receipt-line[b-8x70nregh4] {
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-sec);
    text-align: center;
}

.key-booking-code[b-8x70nregh4] {
    display: grid;
    justify-items: center;
    gap: var(--lk-space-1);
    margin-top: var(--lk-space-4);
    padding: var(--lk-space-3) var(--lk-space-5);
    border-radius: var(--lk-radius-card);
    background: var(--lk-info-soft);
}

.key-booking-code-label[b-8x70nregh4] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
    font-weight: 600;
    color: var(--lk-text-sec);
}

/* Wide spacing and equal-width digits: this is read off a screen and typed into a cabinet
   keypad, so the digits have to be told apart at a glance. */
.key-booking-code-value[b-8x70nregh4] {
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-display);
    font-weight: 800;
    letter-spacing: 3px;
    color: var(--lk-ink);
    font-variant-numeric: tabular-nums;
}

/* The day's taken stretches in words. The timeline beside it is aria-hidden by design, so
   this is where the same information is actually readable — see the note in the markup. */
.key-booking-taken-list[b-8x70nregh4] {
    display: flex;
    flex-direction: column;
    gap: var(--lk-space-1);
    margin: var(--lk-space-2) 0 0;
    padding: 0;
    list-style: none;
}

.key-booking-taken-item[b-8x70nregh4] {
    display: flex;
    gap: var(--lk-space-2);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
}

.key-booking-taken-time[b-8x70nregh4] {
    color: var(--lk-text-sec);
    font-variant-numeric: tabular-nums;
}

.key-booking-taken-name[b-8x70nregh4] {
    color: var(--lk-text-pri);
}
/* /Pages/Keys/KeyDetailPage.razor.rz.scp.css */
/* One column of groups. The Prototype's detail tab is a single stack too — the fields are
   related to each other top to bottom, and a second column would put the cabinet beside the
   name rather than after it. */
.key-detail-form[b-v1ykaundio] {
    display: grid;
    gap: var(--lk-space-4);
}

.key-detail-back[b-v1ykaundio] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-1);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-sec);
    text-decoration: none;
    border-radius: var(--lk-radius-sm);
    padding: var(--lk-space-2) var(--lk-space-3);
}

.key-detail-back:hover[b-v1ykaundio] {
    color: var(--lk-ink);
    background: var(--lk-navy-soft);
}

/* Keyboard focus has to stay visible: this is a link in a row of buttons, and it is the way
   back off a form. */
.key-detail-back:focus-visible[b-v1ykaundio] {
    outline: none;
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-focus);
}

/* Says why something is missing or fixed — the read-only note, and the one that stands in for
   an unreadable category picker. */
.key-detail-note[b-v1ykaundio] {
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
}

.key-detail-saved[b-v1ykaundio] {
    margin: 0;
    padding: var(--lk-space-3);
    background: var(--lk-ok-soft);
    border-radius: var(--lk-radius-sm);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-ok);
}

/* A failure the person cannot fix, so it sits with the form rather than on a field. */
.key-detail-failure[b-v1ykaundio] {
    margin: 0;
    padding: var(--lk-space-3);
    background: var(--lk-err-soft);
    border-radius: var(--lk-radius-sm);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-err);
}

/* ── Loading ────────────────────────────────────────────── */

.key-detail-loading[b-v1ykaundio] {
    display: grid;
    gap: var(--lk-space-4);
}

.key-detail-skeleton-field[b-v1ykaundio] {
    margin-top: var(--lk-space-4);
}

.key-detail-skeleton-gap[b-v1ykaundio] {
    margin-top: var(--lk-space-2);
}
/* /Pages/Keys/KeyListComponent.razor.rz.scp.css */
/* The Prototype draws these rows as flex divs. They are a real table here, because the data is
   tabular and a table announces row and column without anything being written for it — the same
   reasoning as SortableColumnHeader, which owns the header cells. */

.key-list[b-ak21si0kdz] {
    display: grid;
    gap: var(--lk-space-4);
}

.key-table[b-ak21si0kdz] {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    color: var(--lk-text);
}

.key-table th[b-ak21si0kdz],
.key-table td[b-ak21si0kdz] {
    text-align: left;
    padding: var(--lk-space-3) var(--lk-space-2);
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
    vertical-align: middle;
}

.key-table tbody tr:last-child th[b-ak21si0kdz],
.key-table tbody tr:last-child td[b-ak21si0kdz] {
    border-bottom: none;
}

.key-table tbody tr:hover[b-ak21si0kdz] {
    background: var(--lk-ghost-hover);
}

.key-table-heading[b-ak21si0kdz] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-sec);
}

/* The row heading is the key's name — it is what identifies the row, so it is a <th> and not a
   cell. It still has to read as a name rather than as a heading. */
.key-table-name[b-ak21si0kdz] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    font-weight: 600;
    color: var(--lk-text);
}

.key-table-mark[b-ak21si0kdz] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: var(--lk-radius-tile);
    background: var(--lk-navy-soft);
    color: var(--lk-ink);
    flex: none;
}

.key-table-muted[b-ak21si0kdz] {
    color: var(--lk-text-sec);
}

.key-table-actions[b-ak21si0kdz] {
    text-align: right;
    white-space: nowrap;
}

.key-table-actions-heading[b-ak21si0kdz] {
    text-align: right;
}

/* Present for a screen reader, gone for everyone else. clip-path rather than display:none, which
   would take the label out of the accessibility tree as well — the same reason Select's hidden
   label uses it. */
.key-table-visually-hidden[b-ak21si0kdz] {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ── Row actions ────────────────────────────────────────── */

/* Links rather than Buttons, and therefore styled here rather than inherited. Button renders a
   <button> and its CSS leans on :disabled, which does nothing to an <a> — giving it an Href would
   mean rewriting a finished, tested primitive to serve two rows. The cost is these few rules,
   written out the same way Select.razor.css records its duplicated field frame. */

.key-row-action[b-ak21si0kdz],
.key-row-book[b-ak21si0kdz] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--lk-radius-control);
    transition: var(--lk-transition);
    text-decoration: none;
}

.key-row-action[b-ak21si0kdz] {
    width: 32px;
    height: 32px;
    color: var(--lk-text-sec);
}

.key-row-action:hover[b-ak21si0kdz] {
    background: var(--lk-ghost-hover);
    color: var(--lk-ink);
}

.key-row-book[b-ak21si0kdz] {
    height: var(--lk-control-height-sm);
    padding: 0 var(--lk-space-3);
    margin-left: var(--lk-space-2);
    border: var(--lk-border-width) solid var(--lk-line-strong);
    background: var(--lk-surface);
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
}

.key-row-book:hover[b-ak21si0kdz] {
    background: var(--lk-ghost-hover);
}

/* A key with no keybox cannot be booked. Rendered as text rather than a link, so it cannot be
   followed by keyboard or middle-click either — a dimmed link that still works is worse than no
   link at all. */
.key-row-book-unavailable[b-ak21si0kdz] {
    opacity: 0.4;
    cursor: default;
}

.key-row-book-unavailable:hover[b-ak21si0kdz] {
    background: var(--lk-surface);
}

.key-row-action:focus-visible[b-ak21si0kdz],
.key-row-book:focus-visible[b-ak21si0kdz] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

/* ── Loading ────────────────────────────────────────────── */

.key-list-loading[b-ak21si0kdz] {
    display: grid;
    gap: var(--lk-space-4);
}

.key-list-loading-row[b-ak21si0kdz] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
}
/* /Pages/Keys/KeyMainPage.razor.rz.scp.css */
/* The Prototype's .toolbar: a search field that takes the room, and the filters beside it. */

.keys-toolbar[b-febxwrguny] {
    display: flex;
    align-items: flex-end;
    gap: var(--lk-space-3);
    margin-bottom: var(--lk-space-4);
}

.keys-toolbar[b-febxwrguny]  .keys-search {
    flex: 1;
    min-width: 12rem;
}

.keys-toolbar[b-febxwrguny]  .keys-keybox-filter {
    width: 14rem;
    flex: none;
}

/* One column well before a phone width: the search field is unusable at a third of a narrow
   screen, and a filter beside it makes both too small to read. */
@media (max-width: 48rem) {
    .keys-toolbar[b-febxwrguny] {
        flex-direction: column;
        align-items: stretch;
    }

    .keys-toolbar[b-febxwrguny]  .keys-keybox-filter {
        width: 100%;
    }
}

/* The note beside the create button shapes itself — Placement="BesideActions" (#320). This
   screen's copy had max-width: 16rem where the other three had 18rem; the component now carries
   the one value. */

.keys-loading[b-febxwrguny] {
    margin-top: var(--lk-space-4);
}
/* /Pages/Kiosks/KioskDetailPage.razor.rz.scp.css */
/* The design's BackLink: a 13px/600 text link on its own line with 12px under it. The same
   values the keybox detail's back link already uses. */
.kiosk-detail-back-row[b-adw4tx6nmg] {
    margin-bottom: var(--lk-space-3);
}

.kiosk-detail-back[b-adw4tx6nmg] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-1);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-sec);
    text-decoration: none;
    transition: color var(--lk-transition);
}

.kiosk-detail-back:hover[b-adw4tx6nmg] {
    color: var(--lk-ink);
}

.kiosk-detail[b-adw4tx6nmg] {
    display: flex;
    flex-direction: column;
    gap: var(--lk-space-5);
    max-width: 40rem;
}

.kiosk-detail-loading[b-adw4tx6nmg] {
    display: flex;
    flex-direction: column;
    gap: var(--lk-space-4);
    max-width: 40rem;
}

/* No top margin: it was the gap under the heading this card no longer has, and left in place it
   would push the first field away from the card's own padding for no reason. */
.kiosk-detail-fields[b-adw4tx6nmg] {
    display: flex;
    flex-direction: column;
    gap: var(--lk-space-4);
}

.kiosk-detail-actions[b-adw4tx6nmg] {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--lk-space-3);
    margin-top: var(--lk-space-5);
}

/* The card is unpadded so the head's rule reaches its edges, so the rows carry the padding.
   Sideways only: the first row sits directly under the rule, as the design has it. */
.kiosk-events[b-adw4tx6nmg] {
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    list-style: none;
}

.kiosk-event[b-adw4tx6nmg] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    padding: var(--lk-space-3) var(--lk-space-5);
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
}

/* The design's one muted line where a log has nothing in it yet. */
.kiosk-events-empty[b-adw4tx6nmg] {
    margin: 0;
    padding: var(--lk-space-5);
    font-size: var(--lk-font-size-ui);
    color: var(--lk-text-mut);
}

/* ── Installation code ──────────────────────────────────── */

.kiosk-setup[b-adw4tx6nmg] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-5);
    flex-wrap: wrap;
    padding: var(--lk-space-5);
}

.kiosk-setup-code[b-adw4tx6nmg] {
    flex: 1 1 14rem;
    min-width: 0;
}

/* Big, spaced and tabular: this is read off a screen and typed into a device across the room,
   so the digits are the content rather than decoration on it. */
.kiosk-setup-pin[b-adw4tx6nmg] {
    margin: 0;
    font-family: var(--lk-font-display);
    font-weight: 800;
    font-size: var(--lk-font-size-title);
    /* Raw, like every other letter-spacing in the portal — there is no scale for it, and
       SectionHeader's -0.02em and the eyebrow's 0.12em are written the same way. */
    letter-spacing: 0.125rem;
    font-variant-numeric: tabular-nums;
    line-height: normal;
    color: var(--lk-ink);
}

.kiosk-setup-none[b-adw4tx6nmg] {
    margin: 0;
    font-size: var(--lk-font-size-ui);
    color: var(--lk-text-mut);
}

/* The design's .f-hint: 12.5px in the muted ink, not 13px in the secondary. Half a pixel sounds
   like nothing and was not — at 13px this sentence wrapped to a second line beside the button,
   making the card 17px taller than the design's. */
.kiosk-setup-hint[b-adw4tx6nmg] {
    margin: var(--lk-space-2) 0 0;
    font-size: var(--lk-font-size-caption);
    line-height: normal;
    color: var(--lk-text-mut);
}

.kiosk-setup-error[b-adw4tx6nmg] {
    padding: 0 var(--lk-space-5) var(--lk-space-5);
}

.kiosk-event:last-child[b-adw4tx6nmg] {
    border-bottom: none;
}

.kiosk-event-body[b-adw4tx6nmg] {
    display: flex;
    flex-direction: column;
    gap: var(--lk-space-1);
    flex: 1;
    min-width: 0;
}

.kiosk-event-subject[b-adw4tx6nmg] {
    font-family: var(--lk-font-ui);
    color: var(--lk-ink);
}

.kiosk-event-meta[b-adw4tx6nmg] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
}
/* /Pages/Kiosks/KioskListComponent.razor.rz.scp.css */
/* The kiosk cards. Tokens only — no colour, spacing or radius values live here. */

/* 26.25rem is the Prototype's 420px, the same track the keybox grid uses — that number is
   chosen so a wide screen gets three columns of a readable width, not rounded to a whole rem.
   The min() guard keeps a 420px track from overflowing a narrower column than itself. */
.kiosk-list[b-c9e0q7kha8] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 26.25rem), 1fr));
    gap: var(--lk-space-4);
}

.kiosk-card[b-c9e0q7kha8] {
    display: flex;
    flex-direction: column;
    gap: var(--lk-space-4);
    width: 100%;
    box-sizing: border-box;
    padding: var(--lk-space-5);
    border: var(--lk-border-hairline) solid var(--lk-line);
    border-radius: var(--lk-radius-card);
    background: var(--lk-surface);
    /* The Prototype's card carries .hover as a static class, so these cards sit at the medium
       shadow at rest rather than lifting to it on pointer. */
    box-shadow: var(--lk-shadow-md);
    font: inherit;
    /* A <button> does not inherit text colour — it defaults to the platform's buttontext, which
       measured as pure black against the portal's #2B2B4E. Nothing renders black today because
       every line inside sets its own colour, so this is the trap rather than the symptom: the
       next line added to this card would be black and look like a theme fault. The keybox
       card's <a> already sets colour: inherit for the same reason. */
    color: var(--lk-text);
    text-align: start;
    cursor: pointer;
    transition: var(--lk-transition);
}

/* The border carries the hover, not the shadow: the card already rests at the Prototype's
   elevation, so lifting it further would be an invention rather than a port. */
.kiosk-card:hover[b-c9e0q7kha8] {
    border-color: var(--lk-line-strong);
}

.kiosk-card:focus-visible[b-c9e0q7kha8] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

.kiosk-card-head[b-c9e0q7kha8] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
}

.kiosk-card-icon[b-c9e0q7kha8] {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2.875rem;
    height: 2.875rem;
    border-radius: var(--lk-radius-tile);
    /* The Prototype's .itile, the same pair the keybox card's mark uses. It read as a disabled
       control in the sunken grey with muted ink. */
    background: var(--lk-navy-soft);
    color: var(--lk-ink);
}

/* min-width:0 so a long name ellipses instead of pushing the status out of the card. */
.kiosk-card-identity[b-c9e0q7kha8] {
    display: flex;
    flex-direction: column;
    gap: var(--lk-space-1);
    flex: 1;
    min-width: 0;
}

/* --lk-font-size-subtitle was never a token: the declaration was invalid, so the name fell back
   to the inherited body size at normal weight. The Prototype gives it 800/18px, which is
   --lk-font-size-title-sm and the weight the keybox card's name already carries. */
.kiosk-card-name[b-c9e0q7kha8] {
    font-family: var(--lk-font-display);
    font-weight: 800;
    font-size: var(--lk-font-size-title-sm);
    color: var(--lk-ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.kiosk-card-kind[b-c9e0q7kha8] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
}

.kiosk-card-status[b-c9e0q7kha8] {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--lk-space-1);
    flex: 0 0 auto;
}

.kiosk-card-short-id[b-c9e0q7kha8] {
    font-family: var(--lk-font-mono);
    font-size: var(--lk-font-size-caption);
    font-variant-numeric: tabular-nums;
    color: var(--lk-text-mut);
}

.kiosk-card-version[b-c9e0q7kha8] {
    display: flex;
    justify-content: space-between;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-sec);
}

.kiosk-card-version-value[b-c9e0q7kha8] {
    color: var(--lk-text);
}
/* /Pages/Kiosks/KioskMainPage.razor.rz.scp.css */
.kiosks-toolbar[b-7j1bg1rtjx] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-4);
    margin-bottom: var(--lk-space-5);
}

.kiosks-toolbar[b-7j1bg1rtjx]  .kiosks-search {
    flex: 1 1 18rem;
    min-width: 0;
}

/* Skeleton cards in the same grid the real ones land in, so the page does not jump when they
   are replaced. */
.kiosks-loading[b-7j1bg1rtjx] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 26rem), 1fr));
    gap: var(--lk-space-4);
}
/* /Pages/Loans/BookingListComponent.razor.rz.scp.css */
/* The booking table. Mirrors the loan table next door on purpose: the two sit in the same
   module, one click apart, and a reader moving between them should not feel the density or
   the alignment change. Kept as its own file rather than a shared one because the columns
   differ — sharing would mean a stylesheet with two shapes in it. */
/* The Prototype draws these rows as flex divs. They are a real table here, because the data is
   tabular and a table announces row and column without anything being written for it — the same
   reasoning as SortableColumnHeader, which owns the header cells, and the same shape the key list
   already uses. */

.booking-list[b-ksadpykq7r] {
    display: grid;
    gap: var(--lk-space-4);
}

.booking-table[b-ksadpykq7r] {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    color: var(--lk-text);
}

.booking-table th[b-ksadpykq7r],
.booking-table td[b-ksadpykq7r] {
    text-align: left;
    padding: var(--lk-space-3) var(--lk-space-2);
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
    vertical-align: middle;
}

.booking-table tbody tr:last-child th[b-ksadpykq7r],
.booking-table tbody tr:last-child td[b-ksadpykq7r] {
    border-bottom: none;
}

.booking-table tbody tr:hover[b-ksadpykq7r] {
    background: var(--lk-ghost-hover);
}

.booking-table-heading[b-ksadpykq7r] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-sec);
}

/* The row heading is the key's name — it is what identifies the row, so it is a <th> and not a
   cell. It still has to read as a name rather than as a heading. */
.booking-table-name[b-ksadpykq7r] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    font-weight: 600;
    color: var(--lk-text);
}

.booking-table-mark[b-ksadpykq7r] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: var(--lk-radius-tile);
    background: var(--lk-navy-soft);
    color: var(--lk-ink);
    flex: none;
}

.booking-table-muted[b-ksadpykq7r] {
    color: var(--lk-text-sec);
}

/* The date columns hold "Today 17:00" and "Fri 11 Jul 09:30", which wrap badly in a narrow
   column and read as two rows when they do. */
.booking-table td.booking-table-muted[b-ksadpykq7r] {
    white-space: nowrap;
}

/* The borrower and the keybox are names, and names are allowed to be long. Only the dates are
   held on one line, so this puts wrapping back for the two that need it. */
.booking-table tbody td.booking-table-muted:nth-child(2)[b-ksadpykq7r],
.booking-table tbody td.booking-table-muted:nth-child(3)[b-ksadpykq7r] {
    white-space: normal;
}

.booking-table-actions[b-ksadpykq7r] {
    text-align: right;
    white-space: nowrap;
}

.booking-table-actions-heading[b-ksadpykq7r] {
    text-align: right;
}

/* Present for a screen reader, gone for everyone else. clip-path rather than display:none, which
   would take the label out of the accessibility tree as well. */
.booking-table-visually-hidden[b-ksadpykq7r] {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ── Loading ────────────────────────────────────────────── */

.booking-list-loading[b-ksadpykq7r] {
    display: grid;
    gap: var(--lk-space-4);
}

.booking-list-loading-row[b-ksadpykq7r] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
}

/* The access code. Tabular figures so the digits line up between rows, and never wrapped —
   a code broken across two lines is a code somebody reads wrong. */
.booking-table-code[b-ksadpykq7r] {
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.08em;
    white-space: nowrap;
}

.booking-table-status[b-ksadpykq7r] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-1);
    flex-wrap: wrap;
}
/* /Pages/Loans/LoanApprovalPage.razor.rz.scp.css */
.approve-loading[b-19189d4l29] {
    display: grid;
    gap: var(--lk-space-4);
}

.approve-title[b-19189d4l29] {
    margin: 0;
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-title);
    font-weight: 800;
    line-height: var(--lk-line-height-tight);
    color: var(--lk-ink);
}

.approve-lead[b-19189d4l29] {
    margin: var(--lk-space-2) 0 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-body);
    line-height: var(--lk-line-height-body);
    color: var(--lk-text-sec);
}

/* ── The field labels ───────────────────────────────────── */

.approve-label[b-19189d4l29] {
    margin: var(--lk-space-5) 0 var(--lk-space-2);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-mut);
}

.approve-keys[b-19189d4l29] {
    display: grid;
    gap: var(--lk-space-2);
    margin: 0;
    padding: 0;
    list-style: none;
}

.approve-row[b-19189d4l29] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    box-sizing: border-box;
    padding: var(--lk-space-2) var(--lk-space-3);
    border: var(--lk-border-width) solid var(--lk-line);
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface);
    color: var(--lk-magenta-ink);
}

/* The row's colour is the icon's, through currentColor. The text sets its own, so a key name
   does not come out magenta. */
.approve-row-text[b-19189d4l29] {
    min-width: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    /* Long key names wrap rather than being cut off — the borrower has to be able to read
       which keys they are agreeing to. */
    overflow-wrap: anywhere;
    color: var(--lk-text);
}

/* ── The terms ──────────────────────────────────────────── */

.approve-terms[b-19189d4l29] {
    max-height: 11.25rem;
    overflow-y: auto;
    padding: var(--lk-space-4);
    border: var(--lk-border-width) solid var(--lk-line);
    border-radius: var(--lk-radius-card);
    background: var(--lk-surface);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-body);
    line-height: var(--lk-line-height-body);
    color: var(--lk-text-sec);
    /* The lender typed paragraphs into a settings field. Keep them. */
    white-space: pre-line;
}

.approve-terms:focus-visible[b-19189d4l29] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

/* ── Approving ──────────────────────────────────────────── */

.approve-action[b-19189d4l29] {
    margin-top: var(--lk-space-5);
}

.approve-error[b-19189d4l29] {
    display: block;
    margin: var(--lk-space-4) 0 0;
    padding: var(--lk-space-3) var(--lk-space-4);
    border: var(--lk-border-width) solid var(--lk-err);
    border-radius: var(--lk-radius-control);
    background: var(--lk-err-soft);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    line-height: var(--lk-line-height-body);
    color: var(--lk-text-sec);
}

.approve-waiting[b-19189d4l29] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    margin: var(--lk-space-5) 0 0;
    padding: var(--lk-space-4);
    border: var(--lk-border-width) solid var(--lk-info);
    border-radius: var(--lk-radius-control);
    background: var(--lk-info-soft);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    line-height: var(--lk-line-height-body);
    color: var(--lk-text-sec);
}

/* ── Approved ───────────────────────────────────────────── */

.approve-done[b-19189d4l29] {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: var(--lk-space-3) 0 var(--lk-space-2);
}

.approve-done-mark[b-19189d4l29] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 4rem;
    height: 4rem;
    margin-bottom: var(--lk-space-4);
    border-radius: var(--lk-radius-tile);
    background: var(--lk-ok);
    color: var(--lk-navy-contrast);
}
/* /Pages/Loans/LoanBookingPage.razor.rz.scp.css */
/* ── Loading ────────────────────────────────────────────── */

.bookings-loading[b-l54hqsl7vr] {
    display: grid;
    gap: var(--lk-space-4);
}

/* ── The link across to the other screen ────────────────── */

/* A link and not a Button: the module's screens are separate addresses, and this is how you get from
   one to the other. Button renders a <button>, which would be the wrong element for going
   somewhere — no middle-click, no open in a new tab, and the wrong thing announced. */
.booking-loans-link[b-l54hqsl7vr] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-2);
    height: var(--lk-control-height-sm);
    padding: 0 var(--lk-space-3);
    border: var(--lk-border-width) solid var(--lk-line-strong);
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface);
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    text-decoration: none;
    transition: var(--lk-transition);
}

.booking-loans-link:hover[b-l54hqsl7vr] {
    background: var(--lk-ghost-hover);
}

.booking-loans-link:focus-visible[b-l54hqsl7vr] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

/* ── The remove dialog ──────────────────────────────────── */

/* A description list, because that is what these are: a label and the value it names. The rows
   read as "Key: 996" to a screen reader without anything being written to say so. */
.booking-remove-summary[b-l54hqsl7vr] {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--lk-space-2) var(--lk-space-4);
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
}

.booking-remove-summary dt[b-l54hqsl7vr] {
    color: var(--lk-text-sec);
}

.booking-remove-summary dd[b-l54hqsl7vr] {
    margin: 0;
    font-weight: 600;
    color: var(--lk-text);
}

.booking-remove-error[b-l54hqsl7vr] {
    margin: var(--lk-space-4) 0 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-err);
}

/* ── The toolbar ────────────────────────────────────────── */

/* The same shape as the loan screens' toolbar, which lives in LoanScreenComponent. Not shared
   with it: that component is the chrome around a list of loans, and reusing it here would
   mean teaching it a second list type. See the note at the top of LoanBookingPage. */
.booking-toolbar[b-l54hqsl7vr] {
    display: flex;
    align-items: flex-end;
    gap: var(--lk-space-3);
    flex-wrap: wrap;
    margin-bottom: var(--lk-space-4);
}

.booking-toolbar[b-l54hqsl7vr]  .booking-search {
    flex: 1 1 260px;
    max-width: 420px;
}
/* /Pages/Loans/LoanHistoryPage.razor.rz.scp.css */
/* Scoped CSS does not cross from LoanMainPage to here, so the two rules this page shares with it
   are written out rather than reached for. Lifting them into the shared LoanScreenComponent would
   not work either: the link is rendered by the pages, above the component, so component-scoped CSS
   would never reach it. */

.loans-loading[b-2n3ouomlgb] {
    display: grid;
    gap: var(--lk-space-4);
}

.loan-history-link[b-2n3ouomlgb] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-2);
    height: var(--lk-control-height-sm);
    padding: 0 var(--lk-space-3);
    border: var(--lk-border-width) solid var(--lk-line-strong);
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface);
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    text-decoration: none;
    transition: var(--lk-transition);
}

.loan-history-link:hover[b-2n3ouomlgb] {
    background: var(--lk-ghost-hover);
}

.loan-history-link:focus-visible[b-2n3ouomlgb] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}
/* /Pages/Loans/LoanListComponent.razor.rz.scp.css */
/* The Prototype draws these rows as flex divs. They are a real table here, because the data is
   tabular and a table announces row and column without anything being written for it — the same
   reasoning as SortableColumnHeader, which owns the header cells, and the same shape the key list
   already uses. */

.loan-list[b-5xxgxu13m8] {
    display: grid;
    gap: var(--lk-space-4);
}

.loan-table[b-5xxgxu13m8] {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    color: var(--lk-text);
}

.loan-table th[b-5xxgxu13m8],
.loan-table td[b-5xxgxu13m8] {
    text-align: left;
    padding: var(--lk-space-3) var(--lk-space-2);
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
    vertical-align: middle;
}

.loan-table tbody tr:last-child th[b-5xxgxu13m8],
.loan-table tbody tr:last-child td[b-5xxgxu13m8] {
    border-bottom: none;
}

.loan-table tbody tr:hover[b-5xxgxu13m8] {
    background: var(--lk-ghost-hover);
}

.loan-table-heading[b-5xxgxu13m8] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-sec);
}

/* The row heading is the key's name — it is what identifies the row, so it is a <th> and not a
   cell. It still has to read as a name rather than as a heading. */
.loan-table-name[b-5xxgxu13m8] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    font-weight: 600;
    color: var(--lk-text);
}

.loan-table-mark[b-5xxgxu13m8] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: var(--lk-radius-tile);
    background: var(--lk-navy-soft);
    color: var(--lk-ink);
    flex: none;
}

.loan-table-muted[b-5xxgxu13m8] {
    color: var(--lk-text-sec);
}

/* The date columns hold "Today 17:00" and "Fri 11 Jul 09:30", which wrap badly in a narrow
   column and read as two rows when they do. */
.loan-table td.loan-table-muted[b-5xxgxu13m8] {
    white-space: nowrap;
}

/* The borrower and the keybox are names, and names are allowed to be long. Only the dates are
   held on one line, so this puts wrapping back for the two that need it. */
.loan-table tbody td.loan-table-muted:nth-child(2)[b-5xxgxu13m8],
.loan-table tbody td.loan-table-muted:nth-child(3)[b-5xxgxu13m8] {
    white-space: normal;
}

.loan-table-actions[b-5xxgxu13m8] {
    text-align: right;
    white-space: nowrap;
}

.loan-table-actions-heading[b-5xxgxu13m8] {
    text-align: right;
}

/* Present for a screen reader, gone for everyone else. clip-path rather than display:none, which
   would take the label out of the accessibility tree as well. */
.loan-table-visually-hidden[b-5xxgxu13m8] {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ── Loading ────────────────────────────────────────────── */

.loan-list-loading[b-5xxgxu13m8] {
    display: grid;
    gap: var(--lk-space-4);
}

.loan-list-loading-row[b-5xxgxu13m8] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
}
/* /Pages/Loans/LoanMainPage.razor.rz.scp.css */
/* ── Loading ────────────────────────────────────────────── */

.loans-loading[b-jkvhz3at5t] {
    display: grid;
    gap: var(--lk-space-4);
}

/* ── The link across to the other screen ────────────────── */

/* A link and not a Button: the two loan screens are two addresses, and this is how you get from
   one to the other. Button renders a <button>, which would be the wrong element for going
   somewhere — no middle-click, no open in a new tab, and the wrong thing announced. */
.loan-history-link[b-jkvhz3at5t] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-2);
    height: var(--lk-control-height-sm);
    padding: 0 var(--lk-space-3);
    border: var(--lk-border-width) solid var(--lk-line-strong);
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface);
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    text-decoration: none;
    transition: var(--lk-transition);
}

.loan-history-link:hover[b-jkvhz3at5t] {
    background: var(--lk-ghost-hover);
}

.loan-history-link:focus-visible[b-jkvhz3at5t] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

/* ── The return dialog ──────────────────────────────────── */

/* A description list, because that is what these are: a label and the value it names. The rows
   read as "Key: 996" to a screen reader without anything being written to say so. */
.loan-return-summary[b-jkvhz3at5t] {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--lk-space-2) var(--lk-space-4);
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
}

.loan-return-summary dt[b-jkvhz3at5t] {
    color: var(--lk-text-sec);
}

.loan-return-summary dd[b-jkvhz3at5t] {
    margin: 0;
    font-weight: 600;
    color: var(--lk-text);
}

/* The choice of who handed the key back, under the summary it belongs to. */
.loan-return-returner[b-jkvhz3at5t] {
    display: grid;
    gap: var(--lk-space-3);
    margin-top: var(--lk-space-5);
}

.loan-return-error[b-jkvhz3at5t] {
    margin: var(--lk-space-4) 0 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-err);
}
/* /Pages/Loans/LoanScreenComponent.razor.rz.scp.css */
/* The toolbar above the table: the search field, and the status filter beside it on the active
   screen. The Prototype's keybox filter is still not here, and the reason is recorded in
   docs/work/portal-loans.md — it is a lookup the loan screens have no other use for.

   ::deep on both rules because the classes are handed to Select and TextField, and a scoped rule
   aimed at another component's markup matches nothing without it (#568). */

.loan-toolbar[b-fqtql25sd4] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--lk-space-3);
    margin-bottom: var(--lk-space-4);
}

.loan-toolbar[b-fqtql25sd4]  .loan-search {
    flex: 1 1 260px;
    max-width: 380px;
}

/* Its own width rather than sharing the search field's stretch: the three status words are short
   and a field as wide as the search box reads as though it took free text. */
.loan-toolbar[b-fqtql25sd4]  .loan-status-filter {
    flex: 0 1 200px;
}
/* /Pages/Loans/NewLoanPage.razor.rz.scp.css */
.new-loan-loading[b-2s9ib3o7wb] {
    display: grid;
    gap: var(--lk-space-4);
}

/* ── The two columns ────────────────────────────────────── */

/* The picker gets the room, the summary is the narrow column beside it — the Prototype's
   1.6fr / 1fr. It collapses to one column early: the summary is what the reader acts on, and a
   summary squeezed to half a phone is worse than a summary underneath. */
.new-loan-layout[b-2s9ib3o7wb] {
    display: grid;
    grid-template-columns: 1.6fr 1fr;
    gap: var(--lk-space-4);
    align-items: start;
}

@media (max-width: 60rem) {
    .new-loan-layout[b-2s9ib3o7wb] {
        grid-template-columns: 1fr;
    }
}

.new-loan-picker[b-2s9ib3o7wb] {
    min-width: 0;
}

/* Sticky so the summary stays in view while a long key list scrolls past it. Dropped along with
   the two columns — sticky inside a single column would pin it over the list it belongs to.

   ::deep because the element carrying this class is Card's own <div>, not one written here, so it
   does not get this page's scope attribute. Without it the rule compiles and matches nothing —
   the same trap KeyBookingPage's summary card documents. What Card *contains* is written in this
   page, so everything below needs no ::deep. */
[b-2s9ib3o7wb] .new-loan-summary {
    position: sticky;
    top: var(--lk-space-4);
}

@media (max-width: 60rem) {
    [b-2s9ib3o7wb] .new-loan-summary {
        position: static;
    }
}

.new-loan-summary-title[b-2s9ib3o7wb] {
    margin: 0 0 var(--lk-space-4);
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-subtitle);
    font-weight: 700;
    color: var(--lk-ink);
}

/* ── Searching and the rows ─────────────────────────────── */

.new-loan-picker[b-2s9ib3o7wb]  .new-loan-search {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    margin-bottom: var(--lk-space-4);
}

.new-loan-picker[b-2s9ib3o7wb]  .new-loan-search > :first-child {
    flex: 1;
    min-width: 0;
}

.new-loan-picker[b-2s9ib3o7wb]  .new-loan-rows {
    display: grid;
    gap: var(--lk-space-2);
    margin: 0;
    padding: 0;
    list-style: none;
}

/* A row is a button, so it needs the button reset — the browser's own background, border and
   centred text would otherwise fight every rule below. */
.new-loan-picker[b-2s9ib3o7wb]  .new-loan-row {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    width: 100%;
    box-sizing: border-box;
    padding: var(--lk-space-3);
    border: var(--lk-border-width) solid var(--lk-line);
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface);
    font: inherit;
    text-align: start;
    cursor: pointer;
}

.new-loan-picker[b-2s9ib3o7wb]  .new-loan-row:hover:not(:disabled) {
    border-color: var(--lk-line-strong);
}

.new-loan-picker[b-2s9ib3o7wb]  .new-loan-row:focus-visible {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

/* Chosen and unavailable are pseudo-free because they are not states of the control — they are
   what the row is. Button.razor's rule about pseudo-classes is about hover, focus and disabled. */
.new-loan-picker[b-2s9ib3o7wb]  .new-loan-row-chosen {
    border-color: var(--lk-magenta);
    background: var(--lk-magenta-soft);
}

.new-loan-picker[b-2s9ib3o7wb]  .new-loan-row-unavailable {
    cursor: default;
    opacity: 0.55;
}

.new-loan-picker[b-2s9ib3o7wb]  .new-loan-row-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--lk-radius-tile);
    background: var(--lk-navy-soft);
    color: var(--lk-magenta-ink);
}

.new-loan-picker[b-2s9ib3o7wb]  .new-loan-row-text {
    display: grid;
    flex: 1;
    min-width: 0;
    gap: 2px;
}

.new-loan-picker[b-2s9ib3o7wb]  .new-loan-row-name {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 600;
    color: var(--lk-ink);
    overflow-wrap: anywhere;
}

.new-loan-picker[b-2s9ib3o7wb]  .new-loan-row-sub {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
    overflow-wrap: anywhere;
}

.new-loan-picker[b-2s9ib3o7wb]  .new-loan-row-add {
    display: inline-flex;
    align-items: center;
    flex: none;
    gap: var(--lk-space-1);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-magenta-ink);
}

/* ── The summary's fields ───────────────────────────────── */

.new-loan-field-label[b-2s9ib3o7wb] {
    margin: var(--lk-space-5) 0 var(--lk-space-2);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-mut);
}

.new-loan-field-label:first-of-type[b-2s9ib3o7wb] {
    margin-top: 0;
}

/* Dashed, so an empty slot reads as somewhere something goes rather than as a finished box. */
.new-loan-placeholder[b-2s9ib3o7wb] {
    margin: 0;
    padding: var(--lk-space-5) var(--lk-space-4);
    border: var(--lk-border-width) dashed var(--lk-line-strong);
    border-radius: var(--lk-radius-control);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    text-align: center;
    color: var(--lk-text-mut);
}

.new-loan-chosen[b-2s9ib3o7wb] {
    display: grid;
    gap: var(--lk-space-2);
    margin: 0;
    padding: 0;
    list-style: none;
}

.new-loan-chip[b-2s9ib3o7wb] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    padding: var(--lk-space-2) var(--lk-space-3);
    border: var(--lk-border-width) solid var(--lk-line);
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface);
    color: var(--lk-magenta-ink);
}

.new-loan-chip-text[b-2s9ib3o7wb] {
    display: grid;
    flex: 1;
    min-width: 0;
    gap: 2px;
}

.new-loan-chip-name[b-2s9ib3o7wb] {
    flex: 1;
    min-width: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 600;
    color: var(--lk-ink);
    overflow-wrap: anywhere;
}

.new-loan-chip-sub[b-2s9ib3o7wb] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
    overflow-wrap: anywhere;
}

/* ── Notices: the terms warning and the two bars ────────── */

.new-loan-notice[b-2s9ib3o7wb] {
    display: flex;
    align-items: flex-start;
    gap: var(--lk-space-3);
    margin: var(--lk-space-4) 0 0;
    padding: var(--lk-space-3) var(--lk-space-4);
    border: var(--lk-border-width) solid var(--lk-line);
    border-radius: var(--lk-radius-control);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    line-height: var(--lk-line-height-body);
    color: var(--lk-text-sec);
}

.new-loan-notice strong[b-2s9ib3o7wb] {
    display: block;
    color: var(--lk-ink);
}

/* The link onwards is what keeps a bar from being a dead end, so it has to look like one. */
.new-loan-notice a[b-2s9ib3o7wb] {
    display: inline-block;
    margin-top: var(--lk-space-1);
    font-weight: 600;
    color: var(--lk-magenta-ink);
}

.new-loan-notice-info[b-2s9ib3o7wb] {
    border-color: var(--lk-info);
    background: var(--lk-info-soft);
    color: var(--lk-text-sec);
}

.new-loan-notice-warn[b-2s9ib3o7wb] {
    border-color: var(--lk-warn);
    background: var(--lk-warn-soft);
}

.new-loan-notice-error[b-2s9ib3o7wb] {
    border-color: var(--lk-err);
    background: var(--lk-err-soft);
}

.new-loan-notice-error strong[b-2s9ib3o7wb] {
    color: var(--lk-err);
}

/* The borrower picker shows a notice of its own, and its markup is in that component rather than
   in this page — so the rules above, which are scoped to this page, do not reach it. Repeated
   through ::deep rather than copied into the picker's own stylesheet: the same three classes then
   have one definition instead of two that drift. */
.new-loan-picker[b-2s9ib3o7wb]  .new-loan-notice {
    display: flex;
    align-items: flex-start;
    gap: var(--lk-space-3);
    margin: 0 0 var(--lk-space-4);
    padding: var(--lk-space-3) var(--lk-space-4);
    border: var(--lk-border-width) solid var(--lk-line);
    border-radius: var(--lk-radius-control);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    line-height: var(--lk-line-height-body);
    color: var(--lk-text-sec);
}

.new-loan-picker[b-2s9ib3o7wb]  .new-loan-notice-info {
    border-color: var(--lk-info);
    background: var(--lk-info-soft);
}

/* ── The BankID tick and the actions ────────────────────── */

/* The box and its wording side by side. The wording is not a <label for=...>: Checkbox is a
   button carrying role="checkbox", not an <input>, so there is no form control for a label to
   point at. The box stays the only control. */
.new-loan-bankid[b-2s9ib3o7wb] {
    display: flex;
    align-items: flex-start;
    gap: var(--lk-space-3);
    margin-top: var(--lk-space-4);
}

.new-loan-bankid-text[b-2s9ib3o7wb] {
    display: grid;
    min-width: 0;
    gap: 2px;
}

.new-loan-bankid-label[b-2s9ib3o7wb] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 600;
    color: var(--lk-ink);
}

/* The hint is a <span> in this block rather than the <p> it is elsewhere, so it needs the margin
   reset that the paragraph rule was carrying. */
.new-loan-bankid-text .new-loan-hint[b-2s9ib3o7wb] {
    margin: 0;
}

.new-loan-hint[b-2s9ib3o7wb] {
    margin: var(--lk-space-1) 0 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    line-height: var(--lk-line-height-body);
    color: var(--lk-text-mut);
}

.new-loan-policy-note[b-2s9ib3o7wb] {
    margin-top: var(--lk-space-5);
    padding-top: var(--lk-space-4);
    border-top: var(--lk-border-width) solid var(--lk-line);
}

.new-loan-actions[b-2s9ib3o7wb] {
    display: grid;
    gap: var(--lk-space-2);
    margin-top: var(--lk-space-4);
}

/* ── The dialogs ────────────────────────────────────────── */

.new-loan-dialog-body[b-2s9ib3o7wb] {
    margin: 0 0 var(--lk-space-3);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-body);
    line-height: var(--lk-line-height-body);
    color: var(--lk-text-sec);
}

.new-loan-waiting[b-2s9ib3o7wb] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    margin: 0 0 var(--lk-space-4);
    padding: var(--lk-space-4);
    border: var(--lk-border-width) solid var(--lk-info);
    border-radius: var(--lk-radius-control);
    background: var(--lk-info-soft);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 600;
    color: var(--lk-text-sec);
}

.new-loan-resent[b-2s9ib3o7wb] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
    margin: var(--lk-space-3) 0 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-ok);
}

.new-loan-done[b-2s9ib3o7wb] {
    display: flex;
    justify-content: center;
    margin: 0 0 var(--lk-space-3);
}

.new-loan-done-mark[b-2s9ib3o7wb] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.5rem;
    height: 3.5rem;
    border-radius: var(--lk-radius-tile);
    background: var(--lk-ok);
    color: var(--lk-navy-contrast);
}
/* /Pages/Onboarding/OnboardingPage.razor.rz.scp.css */
/*
    The Prototype's onboarding card: a heading, a sentence, two sections one under the other,
    and the button that opens the portal.

    The measurements are the Prototype's own, written out as it writes them (26px, 19px, 13px,
    12.5px, 7px, 6px, 8px, 160px) rather than mapped onto the nearest --lk-space-* and
    --lk-font-size-*. The tokens are a scale of their own and land 1–6px away on almost every
    line, which on one card is the difference between a port and a redraw. This is a page's own
    stylesheet and the scope is this screen; the token rule stands for the components in
    Components/, which are shared and have to agree with each other.

    Colours stay on tokens throughout, so the card follows the theme like every other screen —
    it is the geometry that is being matched, not the palette.

    Density does not reach this card. --lk-space-* multiplies by --lk-density and a literal does
    not, so the airy setting leaves this screen where it is. That is the same behaviour the
    Prototype has, and this screen is seen once.
*/

/*
    Card renders its own markup, so its padding is only reachable through ::deep. The Prototype
    passes padding:26px here; Card's own --lk-space-5 is 20px.
*/
.onboarding[b-9q6co9vn33]  .lk-card {
    padding: 26px;
}

.onboarding-title[b-9q6co9vn33] {
    margin: 0;
    font-family: var(--lk-font-display);
    font-weight: 800;
    font-size: 19px;
    color: var(--lk-ink);
}

.onboarding-intro[b-9q6co9vn33] {
    margin: 6px 0 0;
    font-size: 13px;
    line-height: 1.55;
    color: var(--lk-text-mut);
}

/*
    ErrorBanner owns no outer margin, so the screen places it. The Prototype's is 16px below and
    nothing above, which puts it directly under the intro — read as cramped, but it is what the
    screen does, and the sections below keep their own 20px because adjacent margins collapse.
*/
.onboarding[b-9q6co9vn33]  .onboarding-error {
    margin: 0 0 16px;
}

/* ── Sections ───────────────────────────────────────────── */

.onboarding-section[b-9q6co9vn33] {
    margin-top: 20px;
}

/*
    The Prototype's .f-label. Its 7px and the row's 6px are adjacent sibling margins and
    collapse to 7px, which is what the two sit apart by — both there and here.
*/
.onboarding-label[b-9q6co9vn33] {
    display: block;
    margin-bottom: 7px;
    font-size: 13px;
    font-weight: 600;
    color: var(--lk-text-sec);
}

/*
    Field and button side by side. align-items so the button keeps its own height rather than
    stretching when the field grows a message underneath — invisible while nothing is wrong,
    which is the state the Prototype draws.
*/
.onboarding-row[b-9q6co9vn33] {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin-top: 6px;
}

/* The value takes the row; the code is short and is given only what a code needs. */
.onboarding[b-9q6co9vn33]  .onboarding-value {
    flex: 1;
}

.onboarding[b-9q6co9vn33]  .onboarding-code {
    width: 160px;
}

.onboarding-sent[b-9q6co9vn33] {
    margin: 6px 0 0;
    font-size: 12.5px;
    line-height: var(--lk-line-height-body);
    color: var(--lk-text-mut);
}

.onboarding[b-9q6co9vn33]  .onboarding-badge {
    margin-top: 6px;
}

/* ── Done ───────────────────────────────────────────────── */

.onboarding-done[b-9q6co9vn33] {
    margin-top: 26px;
}

/* ── The name ───────────────────────────────────────────── */

/* The list of names and the free text row are NameChoiceComponent's, and are styled there
   (#530). What stays here is the hint below them, which is this screen's own. */

/*
    The Prototype's hint under the list, at its 12px. Set apart from .onboarding-sent, which is
    12.5px and says something about the step in progress rather than about the choice.
*/
.onboarding-hint[b-9q6co9vn33] {
    margin: 16px 0 0;
    font-size: 12px;
    line-height: 1.5;
    color: var(--lk-text-sec);
}

/* ── The way out ────────────────────────────────────────── */

/*
    Under the Done button and set apart from it, so nothing about the row competes with the step
    the screen is actually for (#505). One line: the sentence, then the button that acts on it.

    ::deep on the button because the markup is SignOutComponent's — a rule aimed straight at
    .onboarding-exit-action from here matches nothing and reports nothing.
*/
.onboarding-exit[b-9q6co9vn33] {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 18px;
}

.onboarding-exit-text[b-9q6co9vn33] {
    font-size: 12px;
    line-height: 1.5;
    color: var(--lk-text-mut);
}

.onboarding-exit[b-9q6co9vn33]  .onboarding-exit-action {
    display: inline-flex;
}
/* /Pages/Organizations/ChooseOrganizationPage.razor.rz.scp.css */
/* The choice sits in the AuthLayout's right-hand panel, so it sets its own width rather than
   filling the column — a list of three companies stretched across a desktop reads as a table. */
.choose[b-ubkm8od5eo] {
    display: flex;
    flex-direction: column;
    gap: var(--lk-space-6);
    width: 100%;
    max-width: 30rem;
    margin: 0 auto;
}

.choose-list[b-ubkm8od5eo] {
    display: grid;
    gap: var(--lk-space-2);
}

/* A row, not a button in the design's sense — full width, left aligned, with the chevron
   pinned to the end. It uses the same surface and hairline as Card so the two read as the
   same family without Card's padding. */
.choose-option[b-ubkm8od5eo] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-4);
    width: 100%;
    box-sizing: border-box;
    padding: var(--lk-space-4);
    border: var(--lk-border-hairline) solid var(--lk-line);
    border-radius: var(--lk-radius-card);
    background: var(--lk-surface);
    color: var(--lk-ink);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    text-align: left;
    cursor: pointer;
    transition: var(--lk-transition);
}

.choose-option:hover[b-ubkm8od5eo] {
    border-color: var(--lk-line-strong);
    background: var(--lk-surface-alt);
}

.choose-option:focus-visible[b-ubkm8od5eo] {
    outline: none;
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-focus);
}

.choose-mark[b-ubkm8od5eo] {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--lk-radius-tile);
    background: var(--lk-navy-soft);
    color: var(--lk-navy);
}

.choose-text[b-ubkm8od5eo] {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}

.choose-name[b-ubkm8od5eo] {
    font-weight: 600;
    line-height: var(--lk-line-height-tight);
}

/* The organisation number under the name, and the explanation under "All organisations". */
.choose-meta[b-ubkm8od5eo] {
    color: var(--lk-text-sec);
    font-size: var(--lk-font-size-label);
}

.choose-option[b-ubkm8od5eo]  .choose-chevron {
    flex: 0 0 auto;
    color: var(--lk-text-sec);
}
/* /Pages/Overview/KpiCard.razor.rz.scp.css */
/*
    kpi-inner carries the card's padding, because the Card is rendered with Padded="false".
    See the comment in the markup for why: the watermark needs a clipping box with the card's
    shape, and that box has to be an element this component owns.

    It is also what every ::deep rule below anchors to. ::deep compiles to
    "[this component's scope id] <selector>", so without an element of our own in the tree
    there is nothing for it to hang off and the rules match nothing at all — silently.
*/

.kpi-inner[b-jp9fmrep3j] {
    position: relative;
    overflow: hidden;
    padding: var(--lk-space-5);
    /* The same radius as Card's own, so the watermark is cut off by the corner's curve
       rather than by a square edge sitting just inside it. */
    border-radius: var(--lk-radius-card);
}

/* ── Watermark ──────────────────────────────────────────────
   The oversized icon behind the number. It sits under everything, tipped and pushed past
   the bottom-right corner so only a corner of it shows.

   ::deep because the icon is the Icon component's own <svg>. Everything below it needs a
   stacking context of its own, or the number renders behind the decoration — hence the
   position on the three text elements rather than a z-index on this one, which would need
   the same rules anyway and would put the ordering somewhere less obvious. */
[b-jp9fmrep3j] .kpi-watermark {
    position: absolute;
    right: -1rem;
    bottom: -1.375rem;
    transform: rotate(-14deg);
    color: var(--lk-navy-soft);
    pointer-events: none;
}

[b-jp9fmrep3j] .kpi-watermark-accent {
    color: var(--lk-magenta-soft);
}

[b-jp9fmrep3j] .kpi-watermark-info {
    color: var(--lk-info-soft);
}

[b-jp9fmrep3j] .kpi-watermark-ok {
    color: var(--lk-ok-soft);
}

/* ── Tile ───────────────────────────────────────────────────  */

.kpi-mark[b-jp9fmrep3j] {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    margin-bottom: var(--lk-space-3);
    border-radius: 0.6875rem;
    background: var(--lk-navy-soft);
    color: var(--lk-ink);
}

.kpi-mark-accent[b-jp9fmrep3j] {
    background: var(--lk-magenta-soft);
    color: var(--lk-magenta-ink);
}

.kpi-mark-info[b-jp9fmrep3j] {
    background: var(--lk-info-soft);
    color: var(--lk-info);
}

.kpi-mark-ok[b-jp9fmrep3j] {
    background: var(--lk-ok-soft);
    color: var(--lk-ok);
}

/* ── Text ───────────────────────────────────────────────────  */

.kpi-value[b-jp9fmrep3j] {
    position: relative;
    margin: 0;
    font-family: var(--lk-font-display);
    font-weight: 800;
    font-size: var(--lk-font-size-display);
    letter-spacing: -0.03em;
    line-height: 1;
    color: var(--lk-ink);
    /* Lined-up digits, so three cards side by side do not look ragged. */
    font-variant-numeric: tabular-nums;
}

/*
    Both of these take the font's own leading rather than inheriting the body's 1.6, which is
    for paragraphs. Inheriting it made the label 21px tall against the design's 16 and the note
    20 against 15, pushing the whole card 8px taller.

    normal, not a ratio: the design sets no line-height on these at all, so each one gets its
    face's own metrics — measured between 1.19 and 1.29 across its display and UI faces. No
    single number reproduces that, and --lk-line-height-tight (1.15) undershot every one.
*/

.kpi-label[b-jp9fmrep3j] {
    position: relative;
    margin: var(--lk-space-2) 0 0;
    font-size: var(--lk-font-size-label);
    line-height: normal;
    color: var(--lk-text-sec);
}

.kpi-note[b-jp9fmrep3j] {
    position: relative;
    margin: var(--lk-space-1) 0 0;
    font-size: var(--lk-font-size-caption);
    line-height: normal;
    color: var(--lk-text-mut);
}
/* /Pages/Overview/OverviewPage.razor.rz.scp.css */
.overview-kpis[b-lja7w0e7wb] {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--lk-space-4);
    margin-bottom: var(--lk-space-5);
}

/* The design gives the loans panel roughly half again the width of the side column.

   No align-items, so the loans card stretches to the height of the side column — that is the
   grid's default and what the design does. Setting it to start made the loans card only as tall
   as its own content: 263px against the design's 438 at the same width, so the left half of the
   row stopped short while the right ran on. The side column below keeps align-content: start,
   which is a different thing: it stops the two cards *inside* it from stretching to fill. */
.overview-panels[b-lja7w0e7wb] {
    display: grid;
    grid-template-columns: 1.55fr 1fr;
    gap: var(--lk-space-4);
}

.overview-side[b-lja7w0e7wb] {
    display: grid;
    gap: var(--lk-space-4);
    align-content: start;
}

/* ── Rows ───────────────────────────────────────────────── */

.overview-list[b-lja7w0e7wb] {
    margin: 0;
    padding: 0;
    list-style: none;
}

.overview-row[b-lja7w0e7wb] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    padding: var(--lk-space-4) var(--lk-space-5);
    border-top: var(--lk-border-hairline) solid var(--lk-line);
}

.overview-row-tight[b-lja7w0e7wb] {
    padding-top: var(--lk-space-3);
    padding-bottom: var(--lk-space-3);
}

.overview-row-mark[b-lja7w0e7wb] {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 0.6875rem;
    background: var(--lk-navy-soft);
    color: var(--lk-ink);
}

.overview-row-mark-ok[b-lja7w0e7wb] {
    width: 1.875rem;
    height: 1.875rem;
    border-radius: var(--lk-radius-pill);
    background: var(--lk-ok-soft);
    color: var(--lk-ok);
}

/* The date column in the bookings panel. */
.overview-row-when[b-lja7w0e7wb] {
    flex: 0 0 3.625rem;
    font-family: var(--lk-font-display);
    font-weight: 800;
    font-size: 0.688rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    text-align: center;
    color: var(--lk-magenta-ink);
}

.overview-row-text[b-lja7w0e7wb] {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}

/* Key names are long and the column is narrow, so one line with an ellipsis beats a
   name that wraps to three. The full name is on the key's own screen. */
.overview-row-title[b-lja7w0e7wb] {
    font-size: var(--lk-font-size-ui);
    font-weight: 600;
    color: var(--lk-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.overview-row-meta[b-lja7w0e7wb] {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin-top: 0.1875rem;
    font-size: var(--lk-font-size-caption);
    color: var(--lk-text-mut);
}

.overview-row-aside[b-lja7w0e7wb] {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.3125rem;
    flex: 0 0 auto;
    text-align: right;
}

.overview-row-note[b-lja7w0e7wb] {
    font-size: 0.75rem;
    color: var(--lk-text-sec);
    white-space: nowrap;
}

/* The clock sits in the Icon component's markup, so it needs ::deep. */
[b-lja7w0e7wb] .overview-row-icon {
    color: var(--lk-text-mut);
}

/* ── Loading ────────────────────────────────────────────── */

.overview-skeleton-gap[b-lja7w0e7wb] {
    margin: var(--lk-space-4) 0 var(--lk-space-3);
}

.overview-skeleton-row[b-lja7w0e7wb] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    margin-top: var(--lk-space-4);
}

.overview-skeleton-lines[b-lja7w0e7wb] {
    display: flex;
    flex-direction: column;
    gap: var(--lk-space-2);
    flex: 1;
}

/* The explanation beside the switched-off actions is the component's own business now: it takes
   Placement="BesideActions" and shapes itself for a header row (#320). The wrapper and the two
   ::deep rules that used to sit here are gone, along with the colour override they carried —
   nothing recorded why the note was a shade darker here than on the three other screens. */

/* ── Narrow screens ─────────────────────────────────────── */

/* Both grids collapse to one column rather than squeezing. The proper answer for phones
   is still an open question for the designer (#198). */
@media (max-width: 60rem) {
    .overview-kpis[b-lja7w0e7wb],
    .overview-panels[b-lja7w0e7wb] {
        grid-template-columns: 1fr;
    }
}
/* /Pages/Overview/PanelCard.razor.rz.scp.css */
/* The card element belongs to the Card component, hence ::deep (ADR 0007). */
[b-gay46zcepm] .panel {
    display: flex;
    flex-direction: column;
}

.panel-head[b-gay46zcepm] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    padding: var(--lk-space-4) var(--lk-space-5) var(--lk-space-3);
}

/* Both set their own leading rather than inheriting the body's 1.6, which is for prose. It
   made the heading 25px tall against the design's 19 and the link 21 against 16, so every
   panel header sat taller than the design's. */

.panel-title[b-gay46zcepm] {
    flex: 1;
    min-width: 0;
    margin: 0;
    font-family: var(--lk-font-display);
    font-weight: 700;
    font-size: 0.969rem;
    line-height: normal;
    color: var(--lk-ink);
}

.panel-link[b-gay46zcepm] {
    flex: 0 0 auto;
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    line-height: normal;
    color: var(--lk-magenta-ink);
    text-decoration: none;
}

.panel-link:hover[b-gay46zcepm] {
    text-decoration: underline;
}
/* /Pages/Partners/PartnerDetailPage.razor.rz.scp.css */
/* The access tab: the chips that grant, and the list of what is granted. */

.partner-detail-loading[b-7b65t907z9] {
    display: grid;
    gap: var(--lk-space-3);
}

.partner-grant[b-7b65t907z9] {
    padding: var(--lk-space-4) 0;
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
}

.partner-grant-chips[b-7b65t907z9] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-2);
}

/* The Prototype's .pick-chip. A toggle that acts on click rather than a field that is saved, so
   it is a button — the pressed state is on aria-pressed, and the fill and the tick are what carry
   it visually. */
.partner-chip[b-7b65t907z9] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-1);
    padding: var(--lk-space-2) var(--lk-space-3);
    border: var(--lk-border-width) solid var(--lk-line-strong);
    border-radius: var(--lk-radius-pill);
    background: var(--lk-surface);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-sec);
    cursor: pointer;
    transition: var(--lk-transition);
}

.partner-chip:hover:not(:disabled)[b-7b65t907z9] {
    border-color: var(--lk-navy);
    color: var(--lk-ink);
}

.partner-chip:focus-visible[b-7b65t907z9] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

.partner-chip:disabled[b-7b65t907z9] {
    opacity: 0.6;
    cursor: default;
}

.partner-chip-on[b-7b65t907z9] {
    border-color: var(--lk-navy);
    background: var(--lk-navy-soft);
    color: var(--lk-ink);
}

.partner-grant-note[b-7b65t907z9],
.partner-grant-empty[b-7b65t907z9] {
    margin: var(--lk-space-3) 0 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
}

.partner-grant-empty[b-7b65t907z9] {
    margin-top: 0;
}

/* ── What is granted ────────────────────────────────────── */

.partner-granted-list[b-7b65t907z9] {
    margin: 0;
    padding: 0;
    list-style: none;
}

.partner-granted-item[b-7b65t907z9] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    padding: var(--lk-space-3) 0;
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
}

.partner-granted-item:last-child[b-7b65t907z9] {
    border-bottom: none;
}

.partner-granted-mark[b-7b65t907z9] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface-alt);
    color: var(--lk-text-sec);
}

.partner-granted-name[b-7b65t907z9] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    color: var(--lk-text);
}
/* /Pages/Partners/PartnerHeaderComponent.razor.rz.scp.css */
/* The back link, the notices and the tab row — everything both tab pages draw before their own
   content. */

/* A link rather than a Button, and therefore styled here: Button renders a <button> whose states
   rest on :disabled, which does nothing to an <a>. Same trade as the cabinet detail's back link. */
.partner-detail-back[b-e2bhnqo2kj] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-1);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-sec);
    text-decoration: none;
    border-radius: var(--lk-radius-control);
}

.partner-detail-back:hover[b-e2bhnqo2kj] {
    color: var(--lk-ink);
    text-decoration: underline;
}

.partner-detail-back:focus-visible[b-e2bhnqo2kj] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

/* ── Notices ────────────────────────────────────────────── */

.partner-notice[b-e2bhnqo2kj] {
    margin-bottom: var(--lk-space-4);
}

.partner-notice-title[b-e2bhnqo2kj] {
    margin: 0 0 var(--lk-space-2);
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-title-sm);
    font-weight: 700;
    color: var(--lk-ink);
}

.partner-notice-body[b-e2bhnqo2kj] {
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    line-height: 1.55;
    color: var(--lk-text-sec);
}

.partner-notice-actions[b-e2bhnqo2kj] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-2);
    margin-top: var(--lk-space-3);
}

.partner-detail-error[b-e2bhnqo2kj] {
    margin-bottom: var(--lk-space-4);
    color: var(--lk-err);
}

.partner-detail-error p[b-e2bhnqo2kj] {
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
}

/* ── Tabs ───────────────────────────────────────────────── */

/* The Prototype's .tabs row. Links rather than buttons, because these are two addresses: they
   open in a new tab, they are bookmarkable, and the browser's back button works through them. */
.partner-tabs[b-e2bhnqo2kj] {
    display: flex;
    gap: var(--lk-space-1);
    margin-bottom: var(--lk-space-4);
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
}

.partner-tab[b-e2bhnqo2kj] {
    padding: var(--lk-space-2) var(--lk-space-3);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 600;
    color: var(--lk-text-sec);
    text-decoration: none;

    /* The current tab is marked by a line under it. The line is 2px on both states so that
       switching does not move the row by a pixel. */
    border-bottom: 2px solid transparent;
}

.partner-tab:hover[b-e2bhnqo2kj] {
    color: var(--lk-ink);
}

.partner-tab:focus-visible[b-e2bhnqo2kj] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: -2px;
    border-radius: var(--lk-radius-control) var(--lk-radius-control) 0 0;
}

/* Colour is not the only carrier: aria-current="page" is on the same element, so a screen reader
   is told which tab is current without seeing the underline. */
.partner-tab-current[b-e2bhnqo2kj] {
    color: var(--lk-ink);
    border-bottom-color: var(--lk-accent);
}
/* /Pages/Partners/PartnerInvitePage.razor.rz.scp.css */
/* The invitation flow: three steps, two branches, one receipt. The Prototype centres it in a
   narrow column, which is right — it is a form, not a table, and a full-width form makes the eye
   travel further than the fields do. */

.invite-page[b-8t75n22zcm] {
    max-width: 45rem;
    margin: 0 auto;
}

.invite-loading[b-8t75n22zcm] {
    margin-top: var(--lk-space-4);
}

/* The same back link the tab pages have, defined again rather than shared: scoped CSS does not
   cross component boundaries, and lifting one link's styling into a component would be a bigger
   change than the four rules it saves. */
.invite-back[b-8t75n22zcm] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-1);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-sec);
    text-decoration: none;
    border-radius: var(--lk-radius-control);
}

.invite-back:hover[b-8t75n22zcm] {
    color: var(--lk-ink);
    text-decoration: underline;
}

.invite-back:focus-visible[b-8t75n22zcm] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

/* ── The step row ───────────────────────────────────────── */

.invite-steps[b-8t75n22zcm] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    margin: 0 0 var(--lk-space-5);
    padding: 0;
    list-style: none;
}

.invite-step[b-8t75n22zcm] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
}

/* The number in the circle. A step that is done shows a tick instead, and aria-current marks the
   one being worked on — the colour is not the only carrier. */
.invite-step-mark[b-8t75n22zcm] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: var(--lk-radius-pill);
    background: var(--lk-surface-alt);
    font-weight: 700;
}

.invite-step-current[b-8t75n22zcm] {
    color: var(--lk-ink);
    font-weight: 600;
}

.invite-step-current .invite-step-mark[b-8t75n22zcm] {
    background: var(--lk-navy);
    color: var(--lk-navy-contrast);
}

.invite-step-done .invite-step-mark[b-8t75n22zcm] {
    background: var(--lk-ok-soft);
    color: var(--lk-ok);
}

/* ── Search results ─────────────────────────────────────── */

.invite-page[b-8t75n22zcm]  .invite-search {
    margin-bottom: var(--lk-space-3);
}

.invite-hits[b-8t75n22zcm] {
    margin: 0 0 var(--lk-space-2);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
}

.invite-hit-list[b-8t75n22zcm] {
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: var(--lk-border-hairline) solid var(--lk-line);
}

/* A button rather than a link: choosing a company sends a request (the lookup) rather than going
   somewhere, and the address does not change. */
.invite-hit[b-8t75n22zcm] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    width: 100%;
    padding: var(--lk-space-3) var(--lk-space-2);
    border: none;
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
    background: transparent;
    text-align: left;
    color: var(--lk-text);
    cursor: pointer;
    transition: var(--lk-transition);
}

.invite-hit:hover:not(:disabled)[b-8t75n22zcm] {
    background: var(--lk-ghost-hover);
}

.invite-hit:focus-visible[b-8t75n22zcm] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: -2px;
}

.invite-hit:disabled[b-8t75n22zcm] {
    opacity: 0.6;
    cursor: default;
}

.invite-hit-mark[b-8t75n22zcm],
.invite-admins-mark[b-8t75n22zcm] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface-alt);
    color: var(--lk-text-sec);
}

.invite-admins-mark[b-8t75n22zcm] {
    border-radius: var(--lk-radius-pill);
}

.invite-hit-text[b-8t75n22zcm] {
    display: grid;
    flex: 1;
    min-width: 0;
}

.invite-hit-name[b-8t75n22zcm] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 600;
}

.invite-hit-detail[b-8t75n22zcm] {
    margin-top: 2px;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
}

/* ── How it works ───────────────────────────────────────── */

.invite-how[b-8t75n22zcm] {
    margin-top: var(--lk-space-5);
}

.invite-how-heading[b-8t75n22zcm] {
    margin: 0 0 var(--lk-space-3);
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-eyebrow);
    font-weight: 700;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--lk-magenta-ink);
}

.invite-how-cards[b-8t75n22zcm] {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--lk-space-3);
}

@media (max-width: 48rem) {
    .invite-how-cards[b-8t75n22zcm] {
        grid-template-columns: 1fr;
    }
}

.invite-how-mark[b-8t75n22zcm] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    margin-bottom: var(--lk-space-3);
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface-alt);
    color: var(--lk-text-sec);
}

.invite-how-title[b-8t75n22zcm] {
    margin: 0 0 var(--lk-space-1);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 700;
    color: var(--lk-ink);
}

.invite-how-body[b-8t75n22zcm] {
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    line-height: 1.5;
    color: var(--lk-text-mut);
}

/* ── The chosen company, notices and actions ────────────── */

.invite-page[b-8t75n22zcm]  .invite-chosen,
.invite-page[b-8t75n22zcm]  .invite-admins {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    margin-bottom: var(--lk-space-3);
}

.invite-page[b-8t75n22zcm]  .invite-notice {
    margin-bottom: var(--lk-space-3);
}

.invite-notice-title[b-8t75n22zcm] {
    margin: 0 0 var(--lk-space-2);
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-title-sm);
    font-weight: 700;
    color: var(--lk-ink);
}

.invite-notice-body[b-8t75n22zcm] {
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    line-height: 1.55;
    color: var(--lk-text-sec);
}

.invite-page[b-8t75n22zcm]  .invite-error {
    margin-bottom: var(--lk-space-3);
    color: var(--lk-err);
}

.invite-error p[b-8t75n22zcm] {
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
}

.invite-link[b-8t75n22zcm] {
    color: var(--lk-navy);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
}

.invite-contact[b-8t75n22zcm] {
    display: grid;
    gap: var(--lk-space-3);
}

.invite-actions[b-8t75n22zcm] {
    display: flex;
    justify-content: flex-end;
    gap: var(--lk-space-2);
    margin-top: var(--lk-space-4);
}

/* ── The receipt ────────────────────────────────────────── */

.invite-page[b-8t75n22zcm]  .invite-sent {
    margin-bottom: var(--lk-space-3);
    text-align: center;
}

.invite-sent-mark[b-8t75n22zcm] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 58px;
    height: 58px;
    margin-bottom: var(--lk-space-4);
    border-radius: var(--lk-radius-pill);
    background: var(--lk-ok-soft);
    color: var(--lk-ok);
}

.invite-sent-title[b-8t75n22zcm] {
    margin: 0 0 var(--lk-space-2);
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-title);
    font-weight: 800;
    color: var(--lk-ink);
}

.invite-sent-body[b-8t75n22zcm] {
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    line-height: 1.55;
    color: var(--lk-text-sec);
}

.invite-timeline[b-8t75n22zcm] {
    margin: 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: var(--lk-space-4);
}

.invite-timeline-step[b-8t75n22zcm] {
    display: flex;
    gap: var(--lk-space-3);
}

.invite-timeline-mark[b-8t75n22zcm] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 24px;
    height: 24px;
    border-radius: var(--lk-radius-pill);
    background: var(--lk-navy-soft);
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-label);
    font-weight: 700;
    color: var(--lk-ink);
}

.invite-timeline-text[b-8t75n22zcm] {
    display: grid;
}

.invite-timeline-title[b-8t75n22zcm] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 600;
    color: var(--lk-text);
}

.invite-timeline-body[b-8t75n22zcm] {
    margin-top: 3px;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    line-height: 1.5;
    color: var(--lk-text-mut);
}
/* /Pages/Partners/PartnerListComponent.razor.rz.scp.css */
/* The Prototype draws these rows as flex divs. They are a real table here, because the data is
   tabular and a table announces row and column without anything being written for it — the same
   reasoning as SortableColumnHeader, which owns the header cells. Same shape as the colleague
   list, and deliberately so: two lists that answer "who" should not look like two designs. */

.partner-list[b-6pgi6lijv5] {
    display: grid;
    gap: var(--lk-space-4);
}

.partner-table[b-6pgi6lijv5] {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    color: var(--lk-text);
}

.partner-table th[b-6pgi6lijv5],
.partner-table td[b-6pgi6lijv5] {
    text-align: left;
    padding: var(--lk-space-3) var(--lk-space-2);
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
    vertical-align: middle;
}

.partner-table tbody tr:last-child td[b-6pgi6lijv5] {
    border-bottom: none;
}

.partner-table tbody tr:hover[b-6pgi6lijv5] {
    background: var(--lk-ghost-hover);
}

/* An invitation has nothing to open, so its row does not pretend otherwise: no hover lift, and
   the name is plain text rather than a link. */
.partner-table tbody tr.partner-row-inert:hover[b-6pgi6lijv5] {
    background: transparent;
}

.partner-identity[b-6pgi6lijv5] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
}

/* The building mark, as the Prototype's tile. Square with a soft radius rather than the round
   avatar the colleague list uses — this is a company, not a person, and the shape is the only
   thing carrying that at a glance. */
.partner-mark[b-6pgi6lijv5] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface-alt);
    color: var(--lk-text-sec);
}

.partner-identity-text[b-6pgi6lijv5] {
    display: grid;
    min-width: 0;
}

.partner-name[b-6pgi6lijv5] {
    font-weight: 600;
    color: var(--lk-text);
    text-decoration: none;
}

a.partner-name:hover[b-6pgi6lijv5] {
    color: var(--lk-ink);
    text-decoration: underline;
}

a.partner-name:focus-visible[b-6pgi6lijv5] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
    border-radius: var(--lk-radius-control);
}

/* The registration number under the name. It wraps rather than being clipped: half a number
   looks like a whole one. */
.partner-registration-number[b-6pgi6lijv5] {
    margin-top: 2px;
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
    overflow-wrap: anywhere;
}

.partner-direction[b-6pgi6lijv5],
.partner-people[b-6pgi6lijv5] {
    color: var(--lk-text-sec);
    white-space: nowrap;
}

.partner-people-none[b-6pgi6lijv5] {
    color: var(--lk-text-mut);
}

/* ── Loading ────────────────────────────────────────────── */

.partner-list-loading[b-6pgi6lijv5] {
    display: grid;
    gap: var(--lk-space-3);
}

.partner-list-loading-row[b-6pgi6lijv5] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    padding: var(--lk-space-3) var(--lk-space-2);
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
}

.partner-list-loading-row:last-child[b-6pgi6lijv5] {
    border-bottom: none;
}
/* /Pages/Partners/PartnerMainPage.razor.rz.scp.css */
/* The Prototype's .toolbar. Only a search field here: the Prototype has no other control on this
   screen either, and the two lists it holds — partnerships and pending invitations — are one
   question rather than two filters. */

.partners-toolbar[b-cx7dff483k] {
    display: flex;
    align-items: flex-end;
    gap: var(--lk-space-3);
    margin-bottom: var(--lk-space-4);
}

.partners-toolbar[b-cx7dff483k]  .partners-search {
    flex: 1;
    min-width: 12rem;
}

@media (max-width: 48rem) {
    .partners-toolbar[b-cx7dff483k] {
        flex-direction: column;
        align-items: stretch;
    }
}

.partners-loading[b-cx7dff483k] {
    margin-top: var(--lk-space-4);
}
/* /Pages/Partners/PartnerPeoplePage.razor.rz.scp.css */
/* The people tab: who at the partner is covered, and who has been blocked. */

.partner-detail-loading[b-t9lbusgudm] {
    display: grid;
    gap: var(--lk-space-3);
}

.partner-people-note[b-t9lbusgudm] {
    margin: 0 0 var(--lk-space-3);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
}

.partner-people-list[b-t9lbusgudm] {
    margin: 0;
    padding: 0;
    list-style: none;
}

.partner-person[b-t9lbusgudm] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    padding: var(--lk-space-3) 0;
    border-bottom: var(--lk-border-hairline) solid var(--lk-line);
}

.partner-person:last-child[b-t9lbusgudm] {
    border-bottom: none;
}

/* Dimmed, as the Prototype dims a blocked row — but the badge beside the name is what actually
   says it. Opacity alone would leave the state invisible to anyone who cannot compare two rows. */
.partner-person-blocked[b-t9lbusgudm] {
    opacity: 0.65;
}

.partner-person-identity[b-t9lbusgudm] {
    display: grid;
    flex: 1;
    min-width: 0;
}

.partner-person-name[b-t9lbusgudm] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 600;
    color: var(--lk-text);
}

.partner-person-blocked-at[b-t9lbusgudm] {
    margin-top: 2px;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-mut);
}
/* /Pages/Profile/AddContactDialog.razor.rz.scp.css */
.add-contact-form[b-f9le0dzsxg] {
    display: grid;
    gap: var(--lk-space-4);
}

.add-contact-sent[b-f9le0dzsxg] {
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-text-sec);
    overflow-wrap: anywhere;
}

/* A failure the person cannot fix, so it sits with the form rather than on a field. */
.add-contact-failure[b-f9le0dzsxg] {
    margin: 0;
    padding: var(--lk-space-3);
    background: var(--lk-err-soft);
    border-radius: var(--lk-radius-sm);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-err);
}
/* /Pages/Profile/ChangeNameDialog.razor.rz.scp.css */
.change-name-gap[b-ikpf4zque4] {
    margin-top: var(--lk-space-2);
}

/* The same voice as the onboarding's hint under the name: 12px, secondary, set off from the
   question rather than beside it. */
.change-name-hint[b-ikpf4zque4] {
    margin: 16px 0 0;
    font-size: 12px;
    line-height: 1.5;
    color: var(--lk-text-sec);
}

/* The add-contact dialog's failure box, unchanged: a problem the person cannot fix sits with
   the form rather than on a field, and the two dialogs on this screen should not differ in how
   that looks. */
.change-name-failure[b-ikpf4zque4] {
    margin: var(--lk-space-3) 0 0;
    padding: var(--lk-space-3);
    background: var(--lk-err-soft);
    border-radius: var(--lk-radius-sm);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    color: var(--lk-err);
}
/* /Pages/Profile/ProfilePage.razor.rz.scp.css */
/* The Prototype's 1.2fr / 1fr split. It collapses early rather than at a phone width: the
   right column holds a single control, and two narrow columns read worse than one wide one
   well before the layout actually runs out of room. */
.profile-grid[b-27dwxic8nr] {
    display: grid;
    grid-template-columns: 1.2fr 1fr;
    gap: var(--lk-space-4);
    align-items: start;
}

.profile-column[b-27dwxic8nr] {
    display: grid;
    gap: var(--lk-space-4);
}

@media (max-width: 60rem) {
    .profile-grid[b-27dwxic8nr] {
        grid-template-columns: 1fr;
    }
}

/* ── Loading ────────────────────────────────────────────── */

.profile-skeleton-field[b-27dwxic8nr] {
    margin-top: var(--lk-space-4);
}

.profile-skeleton-gap[b-27dwxic8nr] {
    margin-top: var(--lk-space-2);
}
/* /Pages/Settings/SettingsCategoryPage.razor.rz.scp.css */
/* Two columns: the tree on the left at a fixed width, the selected category on the right. The
   Prototype uses grid-template-columns: 320px 1fr; the same shape, with the width in a token-sized
   unit so it tracks the type scale rather than a pixel guess. */

.categories-layout[b-7t5osxkapq] {
    display: grid;
    grid-template-columns: 20rem 1fr;
    gap: var(--lk-space-4);
    align-items: start;
}

/* One column below this: side by side, the detail column gets too narrow for a labelled field
   before the tree gets too narrow for a nested name. */
@media (max-width: 62rem) {
    .categories-layout[b-7t5osxkapq] {
        grid-template-columns: 1fr;
    }
}

.categories-loading[b-7t5osxkapq] {
    margin-top: var(--lk-space-4);
}

/* ── The tree ───────────────────────────────────────────── */

.categories-tree-heading[b-7t5osxkapq],
.categories-detail-heading[b-7t5osxkapq] {
    margin: 0 0 var(--lk-space-3);
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-title);
    font-weight: 700;
    color: var(--lk-ink);
    overflow-wrap: anywhere;
}

.categories-tree-list[b-7t5osxkapq] {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* A button, not a div with an onclick: the rows are the navigation of this screen and the
   keyboard has to reach them. Full width so the whole row is the target. */
.categories-tree-row[b-7t5osxkapq] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
    width: 100%;
    padding: var(--lk-space-3);
    /* The depth arrives as a custom property from the markup, which knows the nesting; the size of
       one step is design and stays here. */
    padding-left: calc(var(--lk-space-3) + var(--category-depth, 0) * var(--lk-space-5));
    border: none;
    border-radius: var(--lk-radius-control);
    background: transparent;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 600;
    color: var(--lk-text);
    text-align: left;
    cursor: pointer;
}

.categories-tree-row:hover[b-7t5osxkapq] {
    background: var(--lk-ghost-hover);
}

/* The same ring the buttons use, so a keyboard user sees one focus style on the screen. */
.categories-tree-row:focus-visible[b-7t5osxkapq] {
    outline: none;
    box-shadow: 0 0 0 var(--lk-focus-ring-width) var(--lk-focus);
}

.categories-tree-row-selected[b-7t5osxkapq] {
    background: var(--lk-magenta-soft);
    color: var(--lk-magenta-ink);
}

.categories-tree-name[b-7t5osxkapq] {
    flex: 1;
    overflow-wrap: anywhere;
}

.categories-tree-footer[b-7t5osxkapq] {
    margin-top: var(--lk-space-3);
    padding-top: var(--lk-space-3);
    border-top: var(--lk-border-hairline) solid var(--lk-line);
}

/* ── The selected category ──────────────────────────────── */

.categories-layout[b-7t5osxkapq]  .categories-detail {
    display: grid;
    gap: var(--lk-space-4);
}

/* Remove sits away from Save rather than beside it: they are a destructive action and the
   ordinary one, and a mis-click between them costs a category. */
.categories-detail-actions[b-7t5osxkapq] {
    display: flex;
    justify-content: space-between;
    gap: var(--lk-space-3);
    flex-wrap: wrap;
}

.categories-detail-note[b-7t5osxkapq] {
    margin: 0;
    color: var(--lk-text-mut);
    font-size: var(--lk-font-size-label);
    line-height: 1.5;
}

/* The right-hand column is two cards now — the category and its fields — so it needs a stack of
   its own rather than being a single grid cell. */
.categories-detail-column[b-7t5osxkapq] {
    display: grid;
    gap: var(--lk-space-4);
    align-content: start;
    /* Without this the column refuses to shrink below the widest field label, and the tree gets
       squeezed instead of the card wrapping. */
    min-width: 0;
}

/* ── The category's metadata fields ─────────────────────── */

.categories-layout[b-7t5osxkapq]  .categories-meta {
    display: grid;
    gap: var(--lk-space-3);
}

.categories-meta-head[b-7t5osxkapq] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--lk-space-3);
    flex-wrap: wrap;
}

.categories-meta-heading[b-7t5osxkapq] {
    margin: 0;
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-title);
    font-weight: 700;
    color: var(--lk-ink);
    overflow-wrap: anywhere;
}

.categories-meta-sub[b-7t5osxkapq],
.categories-meta-empty[b-7t5osxkapq] {
    margin: var(--lk-space-1) 0 0;
    color: var(--lk-text-mut);
    font-size: var(--lk-font-size-label);
    line-height: 1.5;
}

.categories-meta-empty[b-7t5osxkapq] {
    margin: 0;
}

.categories-meta-list[b-7t5osxkapq] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
}

.categories-meta-row[b-7t5osxkapq] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    padding: var(--lk-space-3) 0;
    border-top: var(--lk-border-hairline) solid var(--lk-line);
}

/* The first row sits under the heading, which is separation enough. */
.categories-meta-row:first-child[b-7t5osxkapq] {
    border-top: none;
}

.categories-meta-name[b-7t5osxkapq] {
    flex: 1;
    min-width: 0;
    font-weight: 600;
    color: var(--lk-text);
    overflow-wrap: anywhere;
}

/* ── The new-field dialog ───────────────────────────────── */

.categories-field[b-7t5osxkapq] {
    display: grid;
    gap: var(--lk-space-4);
}

.categories-field-existing[b-7t5osxkapq] {
    display: grid;
    gap: var(--lk-space-2);
}

.categories-field-subheading[b-7t5osxkapq] {
    margin: 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    color: var(--lk-text-mut);
}

/* "or create a new one", with a rule either side. The rules are drawn on the pseudo-elements so
   the text stays one element and a screen reader reads it as one phrase. */
.categories-field-divider[b-7t5osxkapq] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    margin: 0;
    color: var(--lk-text-mut);
    font-size: var(--lk-font-size-label);
}

.categories-field-divider[b-7t5osxkapq]::before,
.categories-field-divider[b-7t5osxkapq]::after {
    content: "";
    flex: 1;
    height: var(--lk-border-hairline);
    background: var(--lk-line);
}

.categories-field-note[b-7t5osxkapq] {
    margin: 0;
    color: var(--lk-text-mut);
    font-size: var(--lk-font-size-label);
    line-height: 1.5;
}

.categories-create[b-7t5osxkapq] {
    display: grid;
    gap: var(--lk-space-4);
}

.categories-confirm-body[b-7t5osxkapq] {
    margin: 0;
    color: var(--lk-text-mut);
    line-height: 1.5;
}
/* /Pages/Settings/SettingsLendingPage.razor.rz.scp.css */
.lending-grid[b-c3t9r6eqtl] {
    display: grid;
    gap: var(--lk-space-4);
    align-content: start;
}

.lending-fields[b-c3t9r6eqtl] {
    display: grid;
    gap: var(--lk-space-4);
    align-content: start;
}

/* Off, not merely faded: every field inside also carries disabled, so this is the visible half of
   a state the markup states properly. */
.lending-fields-inactive[b-c3t9r6eqtl] {
    opacity: 0.5;
}

.lending-field-wide[b-c3t9r6eqtl] {
    grid-column: 1 / -1;
}

/* ── The policy switch ──────────────────────────────────── */

.lending-toggle-row[b-c3t9r6eqtl] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    flex-wrap: wrap;
}

.lending-toggle-mark[b-c3t9r6eqtl] {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--lk-radius-tile);
    background: var(--lk-magenta-soft);
    color: var(--lk-magenta-ink);
}

.lending-toggle-text[b-c3t9r6eqtl] {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: var(--lk-space-1);
}

.lending-toggle-title[b-c3t9r6eqtl] {
    font-family: var(--lk-font-display);
    font-weight: 700;
    font-size: var(--lk-font-size-body);
    color: var(--lk-ink);
}

.lending-toggle-note[b-c3t9r6eqtl] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
    color: var(--lk-text-mut);
}

.lending-toggle-state[b-c3t9r6eqtl] {
    font-family: var(--lk-font-ui);
    font-weight: 600;
    font-size: var(--lk-font-size-caption);
    color: var(--lk-text-mut);
}

/* ── A switch with its own sentence beside it ───────────── */

.lending-switch-row[b-c3t9r6eqtl] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
}

.lending-switch-label[b-c3t9r6eqtl] {
    font-family: var(--lk-font-ui);
    font-weight: 600;
    font-size: var(--lk-font-size-body);
    color: var(--lk-text);
}

/* ── Loading ────────────────────────────────────────────── */

.lending-skeleton-row[b-c3t9r6eqtl] {
    display: grid;
    gap: var(--lk-space-2);
    margin-top: var(--lk-space-4);
}
/* /Pages/Settings/SettingsMainPage.razor.rz.scp.css */
/* The Prototype's 1.3fr / 1fr split. Same reasoning as the profile's: the right column holds
   two selects and a switch, and it reads worse as a narrow column than as a full-width one well
   before the page actually runs out of room. */
.settings-grid[b-zi5kkharxr] {
    display: grid;
    grid-template-columns: 1.3fr 1fr;
    gap: var(--lk-space-4);
    align-items: start;
}

.settings-side[b-zi5kkharxr] {
    display: grid;
    gap: var(--lk-space-4);
    align-content: start;
}

/* The street address takes the full width of the field group's two columns — a postal address is
   longer than a postcode, and the Prototype gives it the same span. */
.settings-field-wide[b-zi5kkharxr] {
    grid-column: 1 / -1;
}

@media (max-width: 60rem) {
    .settings-grid[b-zi5kkharxr] {
        grid-template-columns: 1fr;
    }
}

/* ── The SMS gate ───────────────────────────────────────── */

.settings-toggle-row[b-zi5kkharxr] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
}

.settings-toggle-mark[b-zi5kkharxr] {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--lk-radius-tile);
    background: var(--lk-info-soft);
    color: var(--lk-info);
}

.settings-toggle-text[b-zi5kkharxr] {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: var(--lk-space-1);
}

.settings-toggle-title[b-zi5kkharxr] {
    font-family: var(--lk-font-display);
    font-weight: 700;
    font-size: var(--lk-font-size-body);
    color: var(--lk-ink);
}

.settings-toggle-note[b-zi5kkharxr] {
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
    color: var(--lk-text-mut);
}

/* ── Loading ────────────────────────────────────────────── */

.settings-loading[b-zi5kkharxr] {
    display: grid;
    grid-template-columns: 1.3fr 1fr;
    gap: var(--lk-space-4);
    align-items: start;
}

.settings-skeleton-row[b-zi5kkharxr] {
    display: grid;
    gap: var(--lk-space-2);
    margin-top: var(--lk-space-4);
}

@media (max-width: 60rem) {
    .settings-loading[b-zi5kkharxr] {
        grid-template-columns: 1fr;
    }
}

/* The note beside the save button carries its own placement now — the component takes
   Placement="BesideActions" and shapes itself for a header row (#320). This screen held the
   fourth and last copy of the two rules that used to sit here. */
/* /Pages/Settings/SettingsTabsComponent.razor.rz.scp.css */
/* The Prototype's tab row: a line of plain text links with the current one marked, sitting between
   the page header and the content.

   Every rule below the nav itself needs ::deep, and that is not decoration. The tabs are NavLink,
   which is a component, so the anchors it renders are not part of this component's own markup and
   never receive the b-* scope attribute. Without ::deep the nav gets styled, the anchors do not,
   and nothing anywhere reports it — the row renders as plain underlined links. Caught in the
   browser; no test saw it, because a test that asserted styling would have been the wrong test
   (CLAUDE.md). The rule itself is in CLAUDE.md under CSS. */
.settings-tabs[b-5o582nv05o] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-1);
    margin-bottom: var(--lk-space-5);
    border-bottom: 1px solid var(--lk-line);
}

.settings-tabs[b-5o582nv05o]  .settings-tab {
    padding: var(--lk-space-2) var(--lk-space-3);
    border: 0;
    border-bottom: 2px solid transparent;
    background: none;
    font-family: var(--lk-font-ui);
    font-weight: 600;
    font-size: var(--lk-font-size-body);
    color: var(--lk-text-mut);
    text-decoration: none;

    /* Down by the border rather than centred in the box, so the underline of the current tab reads
       as one line with the rule below the row. */
    margin-bottom: -1px;
}

.settings-tabs[b-5o582nv05o]  .settings-tab:hover {
    color: var(--lk-ink);
}

.settings-tabs[b-5o582nv05o]  .settings-tab:focus-visible {
    outline: 2px solid var(--lk-focus);
    outline-offset: 2px;
    border-radius: var(--lk-radius-control);
}

/* Colour and a border, not colour alone: the current tab has to be findable without seeing the
   difference between two greys. */
.settings-tabs[b-5o582nv05o]  .settings-tab-current {
    border-bottom-color: var(--lk-magenta-ink);
    color: var(--lk-magenta-ink);
}
/* /Pages/Shop/ShopAdminCategoryPage.razor.rz.scp.css */
/*
    Scoped to the page. No colour or spacing literals — everything comes from the tokens in
    PortalTheme, which is what keeps light and dark honest without a second set of rules.
*/

.shop-categories-loading[b-ojs4lxmgom] {
    display: grid;
    gap: var(--lk-space-3);
}

.shop-categories-actions[b-ojs4lxmgom] {
    display: flex;
    justify-content: flex-end;
    margin-bottom: var(--lk-space-3);
}

.shop-categories-list[b-ojs4lxmgom] {
    list-style: none;
    margin: 0;
    padding: 0;
}

.shop-categories-row[b-ojs4lxmgom] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    padding: var(--lk-space-3) 0;
    border-bottom: 1px solid var(--lk-line);
}

.shop-categories-row:last-child[b-ojs4lxmgom] {
    border-bottom: none;
}

/*
    The row opener fills the space so the whole row is the target, not just the words. It is a
    button rather than a div with an onclick — the Prototype's shape — so that the keyboard
    reaches the rows in order and a screen reader announces them as actions.
*/
.shop-categories-open[b-ojs4lxmgom] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    flex: 1;
    min-width: 0;
    padding: 0;
    background: none;
    border: none;
    text-align: left;
    cursor: pointer;
    color: inherit;
    font: inherit;
}

.shop-categories-open-static[b-ojs4lxmgom] {
    cursor: default;
}

.shop-categories-open:hover .shop-categories-name[b-ojs4lxmgom] {
    color: var(--lk-magenta);
}

.shop-categories-open:focus-visible[b-ojs4lxmgom] {
    outline: 2px solid var(--lk-focus);
    outline-offset: 2px;
    border-radius: var(--lk-radius-sm);
}

.shop-categories-tone[b-ojs4lxmgom] {
    width: 10px;
    height: 10px;
    border-radius: var(--lk-radius-pill);
    flex: 0 0 auto;
}

/*
    The four tones the shop knows. A class each rather than an interpolated inline style: the
    set is fixed at compile time, and Tone arrives from the API as an unvalidated string.
*/
.tone-info[b-ojs4lxmgom] {
    background: var(--lk-info);
}

.tone-accent[b-ojs4lxmgom] {
    background: var(--lk-magenta);
}

.tone-navy[b-ojs4lxmgom] {
    background: var(--lk-navy);
}

.tone-ok[b-ojs4lxmgom] {
    background: var(--lk-ok);
}

.shop-categories-name[b-ojs4lxmgom] {
    color: var(--lk-text);
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.shop-categories-count[b-ojs4lxmgom],
.shop-categories-locked[b-ojs4lxmgom] {
    color: var(--lk-text-sec);
    font-size: var(--lk-font-size-label);
    flex: 0 0 auto;
}

.shop-categories-locked[b-ojs4lxmgom] {
    max-width: 22ch;
    text-align: right;
    line-height: 1.4;
}

.shop-categories-form[b-ojs4lxmgom] {
    display: grid;
    gap: var(--lk-space-4);
}

.shop-categories-tones-label[b-ojs4lxmgom] {
    display: block;
    margin-bottom: var(--lk-space-2);
    color: var(--lk-text-sec);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
}

.shop-categories-tone-options[b-ojs4lxmgom] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-2);
}

.shop-categories-tone-option[b-ojs4lxmgom] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-2);
    padding: var(--lk-space-2) var(--lk-space-3);
    border: 1px solid var(--lk-line);
    border-radius: var(--lk-radius-pill);
    background: var(--lk-surface);
    color: var(--lk-text);
    cursor: pointer;
    font: inherit;
}

.shop-categories-tone-option:hover[b-ojs4lxmgom] {
    border-color: var(--lk-line-strong);
}

.shop-categories-tone-option:focus-visible[b-ojs4lxmgom] {
    outline: 2px solid var(--lk-focus);
    outline-offset: 2px;
}

.shop-categories-tone-option.is-chosen[b-ojs4lxmgom] {
    border-color: var(--lk-navy);
    background: var(--lk-navy);
    color: var(--lk-navy-contrast);
}

/*
    The chosen swatch would vanish into the navy fill, so it turns into the contrast colour and
    keeps the chip readable as "this one" rather than as a colour sample.
*/
.shop-categories-tone-option.is-chosen .shop-categories-tone[b-ojs4lxmgom] {
    background: var(--lk-navy-contrast);
}

@media (max-width: 640px) {
    .shop-categories-row[b-ojs4lxmgom] {
        flex-wrap: wrap;
    }

    .shop-categories-locked[b-ojs4lxmgom] {
        max-width: none;
        text-align: left;
    }
}
/* /Pages/Shop/ShopAdminOrderPage.razor.rz.scp.css */
/*
    Scoped to the page. No colour or spacing literals — everything comes from the tokens in
    PortalTheme, as the other three shop administration stylesheets do.

    The row is a grid so that the header and every row share one set of columns; the Prototype
    hand-widths each span, which drifts as soon as one row's content differs.

    EVERY COLUMN IS minmax(0, …) AND NOT A BARE FRACTION. A bare 1fr means minmax(auto, 1fr), and
    an auto minimum refuses to shrink below its content — a long customer name or a wide status
    selector then pushes the table past the card and the page scrolls sideways. The product
    dialog shipped with that fault and it was found in the browser, not by a test; the same rule
    is written down there.
*/

.shop-orders-loading[b-jd1ds99onq] {
    display: grid;
    gap: var(--lk-space-3);
}

.shop-orders-filter[b-jd1ds99onq] {
    display: flex;
    justify-content: flex-end;
    margin-bottom: var(--lk-space-3);
}

/* ::deep because .lk-select is the component's own root — the same rule without it matches
   nothing and reports nothing. */
.shop-orders-filter[b-jd1ds99onq]  .lk-select {
    min-width: 15rem;
}

/*
    The status cell is `auto` so the selector keeps its natural width, and the four text columns
    share what is left.
*/
.shop-orders-head[b-jd1ds99onq],
.shop-orders-line[b-jd1ds99onq] {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr) minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--lk-space-3);
}

.shop-orders-head[b-jd1ds99onq] {
    padding: 0 0 var(--lk-space-2);
    border-bottom: 1px solid var(--lk-line);
    color: var(--lk-text-sec);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
}

.shop-orders-head-total[b-jd1ds99onq] {
    text-align: right;
}

.shop-orders-list[b-jd1ds99onq] {
    list-style: none;
    margin: 0;
    padding: 0;
}

.shop-orders-row[b-jd1ds99onq] {
    border-bottom: 1px solid var(--lk-line);
}

.shop-orders-row:last-child[b-jd1ds99onq] {
    border-bottom: none;
}

/*
    The opener spans the five text columns of the grid it sits in, so the whole row up to the
    status is one target. A button rather than a div with an onclick — the Prototype's shape —
    so the keyboard reaches the rows in order.
*/
.shop-orders-open[b-jd1ds99onq] {
    display: grid;
    grid-column: 1 / 6;
    grid-template-columns: subgrid;
    align-items: center;
    gap: var(--lk-space-3);
    width: 100%;
    min-width: 0;
    padding: var(--lk-space-3) 0;
    border: none;
    background: none;
    color: inherit;
    cursor: pointer;
    font: inherit;
    text-align: left;
}

.shop-orders-open:focus-visible[b-jd1ds99onq] {
    outline: 2px solid var(--lk-focus);
    outline-offset: 2px;
    border-radius: var(--lk-radius-tile);
}

.shop-orders-number[b-jd1ds99onq] {
    color: var(--lk-text);
    font-weight: 600;
}

.shop-orders-date[b-jd1ds99onq],
.shop-orders-customer[b-jd1ds99onq],
.shop-orders-by[b-jd1ds99onq] {
    overflow: hidden;
    color: var(--lk-text-sec);
    font-size: var(--lk-font-size-label);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.shop-orders-total[b-jd1ds99onq] {
    color: var(--lk-text);
    font-weight: 700;
    text-align: right;
}

.shop-orders-status[b-jd1ds99onq] {
    display: flex;
    justify-content: flex-end;
    padding: var(--lk-space-3) 0;
}

/* ── The expanded row ────────────────────────────────────── */

.shop-orders-detail[b-jd1ds99onq] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-5);
    padding: 0 0 var(--lk-space-4) var(--lk-space-4);
}

.shop-orders-lines[b-jd1ds99onq] {
    flex: 1 1 17rem;
    list-style: none;
    margin: 0;
    padding: 0;
    min-width: 0;
}

.shop-orders-item[b-jd1ds99onq] {
    display: flex;
    align-items: baseline;
    gap: var(--lk-space-2);
    padding: var(--lk-space-1) 0;
    font-size: var(--lk-font-size-label);
}

/* An option belongs to the product above it, and the indent is what says so. */
.shop-orders-item-option[b-jd1ds99onq] {
    padding-left: var(--lk-space-5);
    color: var(--lk-text-sec);
}

.shop-orders-qty[b-jd1ds99onq] {
    color: var(--lk-text-sec);
    font-variant-numeric: tabular-nums;
}

.shop-orders-name[b-jd1ds99onq] {
    flex: 1;
    min-width: 0;
    color: var(--lk-text);
}

.shop-orders-price[b-jd1ds99onq] {
    color: var(--lk-text);
    font-weight: 600;
}

/*
    A definition list: every row here is a label and its value, which is what dl means. The grid
    keeps the values aligned without the labels needing a fixed width.
*/
.shop-orders-facts[b-jd1ds99onq] {
    display: grid;
    flex: 0 1 20rem;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--lk-space-2) var(--lk-space-3);
    margin: 0;
    font-size: var(--lk-font-size-label);
}

.shop-orders-facts dt[b-jd1ds99onq] {
    color: var(--lk-text);
    font-weight: 600;
}

.shop-orders-facts dd[b-jd1ds99onq] {
    margin: 0;
    color: var(--lk-text-sec);
}

.shop-orders-empty[b-jd1ds99onq],
.shop-orders-failed[b-jd1ds99onq] {
    padding: var(--lk-space-5) 0;
}

/*
    Narrow: the grid becomes one column per row, so each cell stacks. The head is meaningless
    then — it labels columns that no longer exist — and it is aria-hidden anyway.
*/
@media (max-width: 900px) {
    .shop-orders-head[b-jd1ds99onq] {
        display: none;
    }

    .shop-orders-line[b-jd1ds99onq] {
        grid-template-columns: minmax(0, 1fr);
    }

    .shop-orders-open[b-jd1ds99onq] {
        grid-column: 1;
        grid-template-columns: minmax(0, 1fr);
        gap: var(--lk-space-1);
        padding-bottom: var(--lk-space-2);
    }

    .shop-orders-total[b-jd1ds99onq] {
        text-align: left;
    }

    .shop-orders-status[b-jd1ds99onq] {
        justify-content: flex-start;
        padding-top: 0;
    }

    .shop-orders-detail[b-jd1ds99onq] {
        padding-left: 0;
    }
}
/* /Pages/Shop/ShopAdminProductDialog.razor.rz.scp.css */
/*
    Scoped to the dialog. No colour or spacing literals — everything comes from the tokens in
    PortalTheme, as the category page's stylesheet does.

    The child components (TextField, Select, Button, Checkbox) style themselves; nothing here
    reaches into them, so no ::deep is needed. The rules lay the form out and style the two
    things that are this file's own markup: the price-type radio group and the image row.

    EVERY GRID COLUMN BELOW IS minmax(0, …) AND NOT A BARE FRACTION. A bare 1fr means
    minmax(auto, 1fr), and an auto minimum refuses to shrink below the column's content — so a
    long select option or a field label pushed the form wider than the dialog and the whole
    thing scrolled sideways with the right-hand column cut off. Found in the browser; no test
    would have caught it, because the markup and the state were correct throughout.
*/

.shop-product-form[b-9klyijkvqh] {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--lk-space-4);
}

.shop-product-two[b-9klyijkvqh] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--lk-space-4);
}

.shop-product-label[b-9klyijkvqh] {
    display: block;
    margin-bottom: var(--lk-space-2);
    color: var(--lk-text-sec);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
}

/* The price type — the same chip shape the category tones use. */
.shop-product-type-options[b-9klyijkvqh] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-2);
}

.shop-product-type-option[b-9klyijkvqh] {
    display: inline-flex;
    align-items: center;
    padding: var(--lk-space-2) var(--lk-space-3);
    border: 1px solid var(--lk-line);
    border-radius: var(--lk-radius-pill);
    background: var(--lk-surface);
    color: var(--lk-text);
    cursor: pointer;
    font: inherit;
}

.shop-product-type-option:hover[b-9klyijkvqh] {
    border-color: var(--lk-line-strong);
}

.shop-product-type-option:focus-visible[b-9klyijkvqh] {
    outline: 2px solid var(--lk-focus);
    outline-offset: 2px;
}

.shop-product-type-option.is-chosen[b-9klyijkvqh] {
    border-color: var(--lk-navy);
    background: var(--lk-navy);
    color: var(--lk-navy-contrast);
}

.shop-product-active[b-9klyijkvqh] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
}

.shop-product-active-text[b-9klyijkvqh] {
    color: var(--lk-text-sec);
    font-size: var(--lk-font-size-label);
}

/* Packs and options: a heading with its add button, then one row per line. */
.shop-product-lines[b-9klyijkvqh] {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--lk-space-3);
    padding-top: var(--lk-space-3);
    border-top: 1px solid var(--lk-line);
}

.shop-product-lines-head[b-9klyijkvqh] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--lk-space-3);
}

.shop-product-lines-head .shop-product-label[b-9klyijkvqh] {
    margin-bottom: 0;
}

.shop-product-line[b-9klyijkvqh] {
    display: grid;
    align-items: end;
    gap: var(--lk-space-3);
}

.shop-product-pack[b-9klyijkvqh] {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr) auto;
}

.shop-product-option[b-9klyijkvqh] {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) auto auto;
}

/* The gap between box and words belongs to Checkbox since #463; what is left here is the row's
   own alignment. The padding matches the space a TextField's label takes above its input, so the
   box sits on the same line as the fields beside it. */
.shop-product-option-required[b-9klyijkvqh] {
    display: inline-flex;
    align-items: center;
    padding-bottom: var(--lk-space-2);
    white-space: nowrap;
}

/* This row is an annotation beside two labelled fields, not a field of its own, so it keeps the
   smaller secondary type it has always had rather than the component's default. ::deep because
   the element is Checkbox's markup — the same rule without it matches nothing and reports
   nothing. Same shape as the two customer-facing option lists. */
.shop-product-option-required[b-9klyijkvqh]  .lk-checkbox-text {
    color: var(--lk-text-sec);
    font-size: var(--lk-font-size-label);
}

.shop-product-line[b-9klyijkvqh]  .shop-product-line-remove {
    margin-bottom: var(--lk-space-1);
}

/* Images. */
.shop-product-images[b-9klyijkvqh] {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--lk-space-3);
    padding-top: var(--lk-space-3);
    border-top: 1px solid var(--lk-line);
}

.shop-product-images .shop-product-label[b-9klyijkvqh] {
    margin-bottom: 0;
}

.shop-product-thumbs[b-9klyijkvqh] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-3);
}

.shop-product-thumb[b-9klyijkvqh] {
    position: relative;
    display: inline-block;
}

.shop-product-thumb img[b-9klyijkvqh] {
    display: block;
    width: 74px;
    height: 74px;
    object-fit: cover;
    border: 1px solid var(--lk-line);
    border-radius: var(--lk-radius-tile);
}

.shop-product-thumb[b-9klyijkvqh]  .shop-product-thumb-delete {
    position: absolute;
    top: calc(-1 * var(--lk-space-2));
    right: calc(-1 * var(--lk-space-2));
    background: var(--lk-surface);
    border-radius: var(--lk-radius-pill);
}

.shop-product-upload[b-9klyijkvqh] {
    display: grid;
    gap: var(--lk-space-2);
    color: var(--lk-text-sec);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
}

.shop-product-upload[b-9klyijkvqh]  .shop-product-file {
    color: var(--lk-text);
    font: inherit;
    font-weight: 400;
}

.shop-product-hint[b-9klyijkvqh] {
    margin: 0;
    padding: var(--lk-space-3);
    border-radius: var(--lk-radius-tile);
    background: var(--lk-info-soft);
    color: var(--lk-info);
    font-size: var(--lk-font-size-label);
    line-height: 1.5;
}

.shop-product-image-error[b-9klyijkvqh] {
    margin: 0;
    color: var(--lk-err);
    font-size: var(--lk-font-size-label);
}

@media (max-width: 640px) {
    .shop-product-two[b-9klyijkvqh],
    .shop-product-pack[b-9klyijkvqh],
    .shop-product-option[b-9klyijkvqh] {
        grid-template-columns: 1fr;
    }
}
/* /Pages/Shop/ShopAdminProductPage.razor.rz.scp.css */
/*
    Scoped to the page. No colour or spacing literals — everything comes from the tokens in
    PortalTheme, as the category page's stylesheet does.

    The row is a grid so that the header and every row share one set of columns; the Prototype
    hand-widths each span, which drifts as soon as one row's content differs.
*/

.shop-products-loading[b-nod8aoqtxe] {
    display: grid;
    gap: var(--lk-space-3);
}

.shop-products-actions[b-nod8aoqtxe] {
    display: flex;
    justify-content: flex-end;
    margin-bottom: var(--lk-space-3);
}

.shop-products-head[b-nod8aoqtxe],
.shop-products-row[b-nod8aoqtxe] {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) auto auto auto;
    align-items: center;
    gap: var(--lk-space-3);
}

.shop-products-head[b-nod8aoqtxe] {
    padding: 0 0 var(--lk-space-2);
    border-bottom: 1px solid var(--lk-line);
    color: var(--lk-text-sec);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
}

.shop-products-list[b-nod8aoqtxe] {
    list-style: none;
    margin: 0;
    padding: 0;
}

.shop-products-row[b-nod8aoqtxe] {
    padding: var(--lk-space-3) 0;
    border-bottom: 1px solid var(--lk-line);
}

.shop-products-row:last-child[b-nod8aoqtxe] {
    border-bottom: none;
}

/*
    The row opener fills its column so the whole cell is the target. A button rather than a div
    with an onclick — the Prototype's shape — so the keyboard reaches the rows in order.
*/
.shop-products-open[b-nod8aoqtxe] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    min-width: 0;
    padding: 0;
    background: none;
    border: none;
    text-align: left;
    cursor: pointer;
    color: inherit;
    font: inherit;
}

.shop-products-open:hover .shop-products-name[b-nod8aoqtxe] {
    color: var(--lk-magenta);
}

.shop-products-open:focus-visible[b-nod8aoqtxe] {
    outline: 2px solid var(--lk-focus);
    outline-offset: 2px;
    border-radius: var(--lk-radius-sm);
}

.shop-products-thumb[b-nod8aoqtxe] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    overflow: hidden;
    border-radius: var(--lk-radius-tile);
    background: var(--lk-surface-alt);
}

.shop-products-thumb img[b-nod8aoqtxe] {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The glyph draws itself at 32px; the thumb is a box around it, not a scale. */
.shop-products-thumb[b-nod8aoqtxe]  .shop-glyph {
    display: inline-flex;
    color: var(--lk-text-sec);
}

.shop-products-text[b-nod8aoqtxe] {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.shop-products-name[b-nod8aoqtxe] {
    color: var(--lk-text);
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.shop-products-description[b-nod8aoqtxe] {
    color: var(--lk-text-sec);
    font-size: var(--lk-font-size-label);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.shop-products-price[b-nod8aoqtxe] {
    color: var(--lk-text);
    font-family: var(--lk-font-display);
    font-weight: 700;
    white-space: nowrap;
    text-align: right;
}

.shop-products-head-price[b-nod8aoqtxe] {
    text-align: right;
}

@media (max-width: 720px) {
    .shop-products-head[b-nod8aoqtxe] {
        display: none;
    }

    .shop-products-row[b-nod8aoqtxe] {
        grid-template-columns: minmax(0, 1fr) auto;
    }

    .shop-products-open[b-nod8aoqtxe] {
        grid-column: 1 / -1;
    }

    .shop-products-price[b-nod8aoqtxe] {
        text-align: left;
    }
}
/* /Pages/Shop/ShopAdminTabsComponent.razor.rz.scp.css */
/* The Prototype's tab row: a line of plain text links with the current one marked, sitting between
   the page header and the content. Same shape as the settings row, from the same tokens.

   Every rule below the nav itself needs ::deep, and that is not decoration. The tabs are NavLink,
   which is a component, so the anchors it renders are not part of this component's own markup and
   never receive the b-* scope attribute. Without ::deep the nav gets styled, the anchors do not,
   and nothing anywhere reports it — the row renders as plain underlined links. That is #339's
   !305, found in the browser and not by a test, because a test asserting styling would have been
   the wrong test (CLAUDE.md). The rule itself is in CLAUDE.md under CSS. */
.shop-admin-tabs[b-hoo2hbcpll] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-1);
    margin-bottom: var(--lk-space-5);
    border-bottom: 1px solid var(--lk-line);
}

.shop-admin-tabs[b-hoo2hbcpll]  .shop-admin-tab {
    padding: var(--lk-space-2) var(--lk-space-3);
    border: 0;
    border-bottom: 2px solid transparent;
    background: none;
    font-family: var(--lk-font-ui);
    font-weight: 600;
    font-size: var(--lk-font-size-body);
    color: var(--lk-text-mut);
    text-decoration: none;

    /* Down by the border rather than centred in the box, so the underline of the current tab reads
       as one line with the rule below the row. */
    margin-bottom: -1px;
}

.shop-admin-tabs[b-hoo2hbcpll]  .shop-admin-tab:hover {
    color: var(--lk-ink);
}

.shop-admin-tabs[b-hoo2hbcpll]  .shop-admin-tab:focus-visible {
    outline: 2px solid var(--lk-focus);
    outline-offset: 2px;
    border-radius: var(--lk-radius-control);
}

/* Colour and a border, not colour alone: the current tab has to be findable without seeing the
   difference between two greys. */
.shop-admin-tabs[b-hoo2hbcpll]  .shop-admin-tab-current {
    border-bottom-color: var(--lk-magenta-ink);
    color: var(--lk-magenta-ink);
}
/* /Pages/Shop/ShopAdminTermsPage.razor.rz.scp.css */
/*
    Scoped to the page. No colour or spacing literals — everything comes from the tokens in
    PortalTheme, which is what keeps light and dark honest without a second set of rules.
*/

.shop-terms-loading[b-8w5oef8ock] {
    display: grid;
    gap: var(--lk-space-3);
}

.shop-terms-head[b-8w5oef8ock] {
    display: flex;
    align-items: center;
    margin-bottom: var(--lk-space-3);
}

.shop-terms-none[b-8w5oef8ock] {
    color: var(--lk-text-sec);
    font-size: var(--lk-font-size-label);
}

.shop-terms-actions[b-8w5oef8ock] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    margin-top: var(--lk-space-4);
}

/* Takes the room, so the button stays at the right edge and the confirmation sits beside it
   rather than pushing it around when it appears. */
.shop-terms-hint[b-8w5oef8ock] {
    flex: 1;
    color: var(--lk-text-mut);
    font-size: var(--lk-font-size-caption);
    line-height: 1.5;
}

.shop-terms-saved[b-8w5oef8ock] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-1);
    flex: 0 0 auto;
    color: var(--lk-ok);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
}

@media (max-width: 640px) {
    .shop-terms-actions[b-8w5oef8ock] {
        flex-wrap: wrap;
    }

    .shop-terms-hint[b-8w5oef8ock] {
        flex: 1 0 100%;
    }
}
/* /Pages/Shop/ShopCartPage.razor.rz.scp.css */
/* ── Back to the catalogue ──────────────────────────────── */

.shop-cart-back[b-oi4l6rxkre] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-2);
    height: var(--lk-control-height-sm);
    padding: 0 var(--lk-space-3);
    border: var(--lk-border-width) solid var(--lk-line-strong);
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface);
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    text-decoration: none;
    transition: var(--lk-transition);
}

.shop-cart-back:hover[b-oi4l6rxkre] {
    background: var(--lk-ghost-hover);
}

.shop-cart-back:focus-visible[b-oi4l6rxkre],
.shop-cart-empty-link:focus-visible[b-oi4l6rxkre] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

.shop-cart-empty-link[b-oi4l6rxkre] {
    display: inline-flex;
    align-items: center;
    height: var(--lk-control-height-md);
    padding: 0 var(--lk-space-4);
    border-radius: var(--lk-radius-control);
    background: var(--lk-navy);
    color: var(--lk-navy-contrast);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    text-decoration: none;
    transition: var(--lk-transition);
}

.shop-cart-empty-link:hover[b-oi4l6rxkre] {
    background: var(--lk-navy-hover);
}

/* ── Layout ─────────────────────────────────────────────── */

.shop-cart[b-oi4l6rxkre] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 20rem;
    align-items: start;
    gap: var(--lk-space-5);
    margin-top: var(--lk-space-4);
}

/* The summary drops under the lines before the rows themselves have to reflow — a row that
   wraps loses the column the eye reads the totals down. */
@media (max-width: 60rem) {
    .shop-cart[b-oi4l6rxkre] {
        grid-template-columns: minmax(0, 1fr);
    }
}

.shop-cart-lines[b-oi4l6rxkre] {
    display: grid;
    gap: var(--lk-space-4);
    min-width: 0;
}

/* ── Group headings ─────────────────────────────────────── */

.shop-cart-group[b-oi4l6rxkre] {
    margin: 0;
    color: var(--lk-text);
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-ui);
    font-weight: 700;
}

.shop-cart-group-row[b-oi4l6rxkre] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
}

.shop-cart-group-total[b-oi4l6rxkre] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--lk-space-3);
    padding-top: var(--lk-space-3);
    margin-top: var(--lk-space-2);
    border-top: var(--lk-border-width) solid var(--lk-line);
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
}

.shop-cart-group-total b[b-oi4l6rxkre] {
    color: var(--lk-text);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* ── One line ───────────────────────────────────────────── */

.shop-cart-line[b-oi4l6rxkre] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    padding: var(--lk-space-3) 0;
    border-bottom: var(--lk-border-width) solid var(--lk-line);
}

.shop-cart-line:last-of-type[b-oi4l6rxkre] {
    border-bottom: none;
}

.shop-cart-thumb[b-oi4l6rxkre] {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    overflow: hidden;
    border-radius: var(--lk-radius-tile);
    background: var(--lk-navy-soft);
}

.shop-cart-thumb img[b-oi4l6rxkre] {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.shop-cart-what[b-oi4l6rxkre] {
    display: grid;
    flex: 1 1 auto;
    gap: 0.125rem;
    min-width: 0;
}

.shop-cart-name[b-oi4l6rxkre] {
    overflow: hidden;
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.shop-cart-meta[b-oi4l6rxkre] {
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
}

.shop-cart-total[b-oi4l6rxkre] {
    flex: 0 0 auto;
    min-width: 6rem;
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 700;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.shop-cart-unit[b-oi4l6rxkre] {
    color: var(--lk-text-mut);
    font-size: var(--lk-font-size-caption);
    font-weight: 600;
}

/* ── The bin ────────────────────────────────────────────── */

.shop-cart-remove[b-oi4l6rxkre] {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    padding: var(--lk-space-1);
    border: none;
    border-radius: var(--lk-radius-sm);
    background: none;
    color: var(--lk-text-mut);
    cursor: pointer;
    transition: var(--lk-transition);
}

.shop-cart-remove:hover[b-oi4l6rxkre] {
    background: var(--lk-ghost-hover);
    color: var(--lk-err);
}

.shop-cart-remove:focus-visible[b-oi4l6rxkre] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

/* Holds the column open where a required option has no bin, so the prices above and below it
   stay in one line rather than stepping sideways around the gap. */
.shop-cart-remove-spacer[b-oi4l6rxkre] {
    flex: 0 0 auto;
    width: 1.75rem;
}

/* ── Options under a subscription ───────────────────────── */

.shop-cart-options[b-oi4l6rxkre] {
    display: grid;
    gap: var(--lk-space-2);
    padding: var(--lk-space-2) 0 var(--lk-space-3) var(--lk-space-6);
}

.shop-cart-option[b-oi4l6rxkre] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
}

.shop-cart-option-label[b-oi4l6rxkre] {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
}

.shop-cart-option-kind[b-oi4l6rxkre] {
    color: var(--lk-text-mut);
}

.shop-cart-option-kind[b-oi4l6rxkre]::before {
    content: " · ";
}

.shop-cart-option-price[b-oi4l6rxkre] {
    flex: 0 0 auto;
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* ── Summary column ─────────────────────────────────────── */

.shop-cart-summary[b-oi4l6rxkre] {
    min-width: 0;
}

.shop-cart-summary-title[b-oi4l6rxkre] {
    margin: 0 0 var(--lk-space-4);
    color: var(--lk-text);
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-title-sm);
    font-weight: 800;
}

/* ── On to the checkout ─────────────────────────────────── */

.shop-cart-checkout[b-oi4l6rxkre] {
    margin-top: var(--lk-space-4);
}

.shop-cart-checkout-link[b-oi4l6rxkre] {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--lk-space-2);
    height: var(--lk-control-height-lg);
    border-radius: var(--lk-radius-control);
    background: var(--lk-magenta);
    color: var(--lk-magenta-contrast);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 600;
    text-decoration: none;
    transition: var(--lk-transition);
}

.shop-cart-checkout-link:hover[b-oi4l6rxkre] {
    background: var(--lk-magenta-hover);
}

.shop-cart-checkout-link:focus-visible[b-oi4l6rxkre] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}
/* /Pages/Shop/ShopCheckoutPage.razor.rz.scp.css */
/* ── Back to the cart ───────────────────────────────────── */

.checkout-back[b-x3jz7trdkr] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-2);
    height: var(--lk-control-height-sm);
    padding: 0 var(--lk-space-3);
    border: var(--lk-border-width) solid var(--lk-line-strong);
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface);
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    text-decoration: none;
    transition: var(--lk-transition);
}

.checkout-back:hover[b-x3jz7trdkr] {
    background: var(--lk-ghost-hover);
}

.checkout-back:focus-visible[b-x3jz7trdkr],
.checkout-blocked-link:focus-visible[b-x3jz7trdkr] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

.checkout-blocked-link[b-x3jz7trdkr] {
    display: inline-flex;
    align-items: center;
    height: var(--lk-control-height-md);
    padding: 0 var(--lk-space-4);
    border-radius: var(--lk-radius-control);
    background: var(--lk-navy);
    color: var(--lk-navy-contrast);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    text-decoration: none;
}

/* ── Layout ─────────────────────────────────────────────── */

.checkout[b-x3jz7trdkr] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 21rem;
    align-items: start;
    gap: var(--lk-space-5);
    margin-top: var(--lk-space-4);
}

@media (max-width: 64rem) {
    .checkout[b-x3jz7trdkr] {
        grid-template-columns: minmax(0, 1fr);
    }
}

.checkout-main[b-x3jz7trdkr] {
    display: grid;
    gap: var(--lk-space-4);
    min-width: 0;
}

.checkout-aside[b-x3jz7trdkr] {
    min-width: 0;
}

.checkout-error[b-x3jz7trdkr] {
    margin: 0;
    color: var(--lk-err);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
}

/* ── Sections ───────────────────────────────────────────── */

.checkout-section[b-x3jz7trdkr] {
    margin: 0 0 var(--lk-space-3);
    color: var(--lk-text);
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-ui);
    font-weight: 800;
}

.checkout-section-row[b-x3jz7trdkr] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--lk-space-3);
}

.checkout-section-note[b-x3jz7trdkr] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-2);
    color: var(--lk-text-mut);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
}

.checkout-subsection[b-x3jz7trdkr] {
    margin: var(--lk-space-4) 0 var(--lk-space-2);
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
}

/* ── Buyer ──────────────────────────────────────────────── */

.checkout-buyer[b-x3jz7trdkr],
.checkout-payment[b-x3jz7trdkr] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
}

.checkout-buyer-who[b-x3jz7trdkr] {
    display: grid;
    flex: 1 1 auto;
    gap: 0.125rem;
    min-width: 0;
}

.checkout-buyer-name[b-x3jz7trdkr] {
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 600;
}

.checkout-buyer-org[b-x3jz7trdkr] {
    color: var(--lk-text-mut);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
}

/* ── Address fields ─────────────────────────────────────── */

.checkout-fields[b-x3jz7trdkr] {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--lk-space-3);
}

.checkout-field-wide[b-x3jz7trdkr] {
    grid-column: 1 / -1;
}

@media (max-width: 30rem) {
    .checkout-fields[b-x3jz7trdkr] {
        grid-template-columns: 1fr;
    }
}

/* ── Invoice choice ─────────────────────────────────────── */

.checkout-invoice-choice[b-x3jz7trdkr] {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--lk-space-3);
}

@media (max-width: 30rem) {
    .checkout-invoice-choice[b-x3jz7trdkr] {
        grid-template-columns: 1fr;
    }
}

.checkout-choice[b-x3jz7trdkr] {
    display: grid;
    gap: 0.125rem;
    padding: var(--lk-space-3);
    border: var(--lk-border-width) solid var(--lk-line-strong);
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface);
    text-align: left;
    cursor: pointer;
    transition: var(--lk-transition);
}

.checkout-choice:hover[b-x3jz7trdkr] {
    background: var(--lk-ghost-hover);
}

.checkout-choice.is-active[b-x3jz7trdkr] {
    border-color: var(--lk-magenta);
    background: var(--lk-magenta-soft);
}

.checkout-choice:focus-visible[b-x3jz7trdkr] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

.checkout-choice-title[b-x3jz7trdkr] {
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
}

.checkout-choice-note[b-x3jz7trdkr] {
    color: var(--lk-text-mut);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
}

/* ── Order summary column ───────────────────────────────── */

.checkout-summary-title[b-x3jz7trdkr] {
    margin: 0 0 var(--lk-space-4);
    color: var(--lk-text);
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-title-sm);
    font-weight: 800;
}

.checkout-lines[b-x3jz7trdkr] {
    display: grid;
    gap: var(--lk-space-2);
    padding-bottom: var(--lk-space-3);
    margin-bottom: var(--lk-space-3);
    border-bottom: var(--lk-border-width) solid var(--lk-line);
}

.checkout-line[b-x3jz7trdkr] {
    display: flex;
    align-items: baseline;
    gap: var(--lk-space-2);
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
}

.checkout-line.is-option[b-x3jz7trdkr] {
    padding-left: var(--lk-space-5);
    color: var(--lk-text-sec);
}

.checkout-line-quantity[b-x3jz7trdkr] {
    flex: 0 0 auto;
    color: var(--lk-text-mut);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.checkout-line-name[b-x3jz7trdkr] {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.checkout-line-price[b-x3jz7trdkr] {
    flex: 0 0 auto;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* ── Terms ──────────────────────────────────────────────── */

.checkout-terms[b-x3jz7trdkr] {
    display: flex;
    align-items: flex-start;
    gap: var(--lk-space-2);
    margin-top: var(--lk-space-4);
}

/* Checkbox renders no visible text of its own — Label becomes aria-label only (#463) — so the
   words sit beside it and the component keeps the accessible name. */
.checkout-terms-text[b-x3jz7trdkr] {
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    line-height: 1.5;
}

.checkout-terms-link[b-x3jz7trdkr] {
    padding: 0;
    border: none;
    background: none;
    color: var(--lk-magenta-ink);
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
}

.checkout-terms-link:focus-visible[b-x3jz7trdkr] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

.checkout-terms-error[b-x3jz7trdkr],
.checkout-terms-changed[b-x3jz7trdkr] {
    margin: var(--lk-space-2) 0 0;
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
    line-height: 1.5;
}

.checkout-terms-error[b-x3jz7trdkr] {
    color: var(--lk-err);
}

.checkout-terms-changed[b-x3jz7trdkr] {
    color: var(--lk-warn);
}

.checkout-terms-missing[b-x3jz7trdkr] {
    margin: var(--lk-space-4) 0 0;
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    line-height: 1.5;
}

.checkout-terms-body[b-x3jz7trdkr] {
    margin: 0;
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    line-height: 1.7;
    white-space: pre-wrap;
}

/* ── Place the order ────────────────────────────────────── */

.checkout-place[b-x3jz7trdkr] {
    margin-top: var(--lk-space-4);
}

/* What the button is waiting for, under the button (#485). Muted like the note below it: it
   reports progress, it is not a warning. */
.checkout-placing[b-x3jz7trdkr] {
    margin: var(--lk-space-3) 0 0;
    color: var(--lk-text-mut);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
    line-height: 1.5;
    text-align: center;
}

.checkout-sign-note[b-x3jz7trdkr] {
    margin: var(--lk-space-3) 0 0;
    color: var(--lk-text-mut);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
    line-height: 1.5;
    text-align: center;
}
/* /Pages/Shop/ShopMainPage.razor.rz.scp.css */
/* ── Loading ────────────────────────────────────────────── */

.shop-loading[b-f2ntoje01i] {
    display: grid;
    gap: var(--lk-space-4);
}

.shop-skeleton-gap[b-f2ntoje01i] {
    margin: var(--lk-space-3) 0 var(--lk-space-2);
}

/* ── Why the buy path is missing ────────────────────────── */

/* Said once, above everything, rather than repeated on every card. */
.shop-notice[b-f2ntoje01i] {
    margin: 0;
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
}

/* ── Category chips ─────────────────────────────────────── */

.shop-chips[b-f2ntoje01i] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-2);
    margin: var(--lk-space-4) 0;
}

.shop-chip[b-f2ntoje01i] {
    height: var(--lk-control-height-sm);
    padding: 0 var(--lk-space-3);
    border: var(--lk-border-width) solid var(--lk-line-strong);
    border-radius: var(--lk-radius-pill, 999px);
    background: var(--lk-surface);
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    cursor: pointer;
    transition: var(--lk-transition);
}

.shop-chip:hover[b-f2ntoje01i] {
    background: var(--lk-ghost-hover);
}

/* State as a class driven by aria-pressed's own value would be neater, but the chip is a
   button and :focus-visible already carries the keyboard story — this is the selected one. */
.shop-chip.is-active[b-f2ntoje01i] {
    background: var(--lk-magenta-soft);
    border-color: var(--lk-magenta);
    color: var(--lk-magenta-ink);
}

.shop-chip:focus-visible[b-f2ntoje01i] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

/* ── Category headings ──────────────────────────────────── */

.shop-category-heading[b-f2ntoje01i] {
    display: flex;
    align-items: baseline;
    gap: var(--lk-space-2);
    margin: var(--lk-space-5) 0 var(--lk-space-3);
}

.shop-category-name[b-f2ntoje01i] {
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 700;
}

.shop-category-count[b-f2ntoje01i] {
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
}

/* ── The grid ───────────────────────────────────────────── */

/* auto-fill with a minimum rather than a column count: the sidebar and the viewport both move,
   and a fixed count would either crush the cards or leave a gap at the end. */
.shop-grid[b-f2ntoje01i] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: var(--lk-space-4);
}

.shop-card[b-f2ntoje01i] {
    display: flex;
    flex-direction: column;
    gap: var(--lk-space-3);
    height: 100%;
}

/* The thumbnail is a button because clicking it opens the product. A div with an onclick would
   not be reachable by keyboard and would announce nothing. */
.shop-thumb[b-f2ntoje01i] {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 4 / 3;
    padding: 0;
    border: none;
    border-radius: var(--lk-radius-control);
    background: var(--lk-ghost-hover);
    cursor: pointer;
    overflow: hidden;
}

.shop-thumb img[b-f2ntoje01i] {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.shop-thumb:focus-visible[b-f2ntoje01i] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

.shop-card-body[b-f2ntoje01i] {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: var(--lk-space-2);
}

.shop-card-name[b-f2ntoje01i] {
    margin: 0;
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 700;
}

.shop-card-description[b-f2ntoje01i] {
    margin: 0;
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
}

/* ── Packs and options ──────────────────────────────────── */

.shop-packs[b-f2ntoje01i] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-2);
}

.shop-pack[b-f2ntoje01i] {
    height: var(--lk-control-height-sm);
    padding: 0 var(--lk-space-3);
    border: var(--lk-border-width) solid var(--lk-line-strong);
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface);
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    cursor: pointer;
    transition: var(--lk-transition);
}

.shop-pack.is-active[b-f2ntoje01i] {
    border-color: var(--lk-magenta);
    font-weight: 700;
}

.shop-pack:focus-visible[b-f2ntoje01i] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

.shop-options[b-f2ntoje01i] {
    display: grid;
    gap: var(--lk-space-2);
}

.shop-options-caption[b-f2ntoje01i] {
    margin: 0;
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
}

.shop-option[b-f2ntoje01i] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
}

/* Checkbox renders its own Label since #463. What stays here is the card's smaller type for the
   option rows, reached with ::deep because the element belongs to the component's markup. */
.shop-option[b-f2ntoje01i]  .lk-checkbox-text {
    font-size: var(--lk-font-size-label);
}

/* ── Price row ──────────────────────────────────────────── */

/* margin-top:auto pins this to the bottom of the card so the buttons line up across a row of
   cards whose descriptions are different lengths. */
.shop-price-row[b-f2ntoje01i] {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--lk-space-3);
    margin-top: auto;
    padding-top: var(--lk-space-2);
}

.shop-price[b-f2ntoje01i] {
    margin: 0;
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 700;
}

.shop-price-note[b-f2ntoje01i] {
    margin: 0;
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
}

/* ── The way to the cart ────────────────────────────────── */

.shop-cart-link[b-f2ntoje01i] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-2);
    height: var(--lk-control-height-sm);
    padding: 0 var(--lk-space-3);
    border-radius: var(--lk-radius-pill);
    background: var(--lk-magenta-soft);
    color: var(--lk-magenta-ink);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    text-decoration: none;
    transition: var(--lk-transition);
}

.shop-cart-link:hover[b-f2ntoje01i] {
    background: var(--lk-magenta);
    color: var(--lk-magenta-contrast);
}

.shop-cart-link:focus-visible[b-f2ntoje01i] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}
/* /Pages/Shop/ShopOrderListPage.razor.rz.scp.css */
/* ── Back to the catalogue ──────────────────────────────── */

.orders-back[b-omvqo3fh7w] {
    display: inline-flex;
    align-items: center;
    gap: var(--lk-space-2);
    height: var(--lk-control-height-sm);
    padding: 0 var(--lk-space-3);
    border: var(--lk-border-width) solid var(--lk-line-strong);
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface);
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    text-decoration: none;
    transition: var(--lk-transition);
}

.orders-back:hover[b-omvqo3fh7w] {
    background: var(--lk-ghost-hover);
}

.orders-back:focus-visible[b-omvqo3fh7w],
.orders-empty-link:focus-visible[b-omvqo3fh7w] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

.orders-empty-link[b-omvqo3fh7w] {
    display: inline-flex;
    align-items: center;
    height: var(--lk-control-height-md);
    padding: 0 var(--lk-space-4);
    border-radius: var(--lk-radius-control);
    background: var(--lk-navy);
    color: var(--lk-navy-contrast);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    text-decoration: none;
}

.orders-skeleton[b-omvqo3fh7w] {
    padding: var(--lk-space-4);
    border-bottom: var(--lk-border-width) solid var(--lk-line);
}

/* ── The table ──────────────────────────────────────────── */

/* One shared column definition for the header and every row, so the two cannot drift apart. */
.orders-head[b-omvqo3fh7w],
.orders-row[b-omvqo3fh7w] {
    display: grid;
    grid-template-columns:
        minmax(0, 1.2fr)
        8.5rem
        minmax(0, 1fr)
        minmax(9rem, auto)
        7rem
        2rem;
    align-items: center;
    gap: var(--lk-space-3);
    padding: var(--lk-space-3) var(--lk-space-4);
    text-align: left;
}

.orders-head[b-omvqo3fh7w] {
    border-bottom: var(--lk-border-width) solid var(--lk-line);
    color: var(--lk-text-mut);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
}

.orders-row[b-omvqo3fh7w] {
    width: 100%;
    border: none;
    border-bottom: var(--lk-border-width) solid var(--lk-line);
    background: none;
    font: inherit;
    cursor: pointer;
    transition: var(--lk-transition);
}

.orders-row:hover[b-omvqo3fh7w],
.orders-row.is-open[b-omvqo3fh7w] {
    background: var(--lk-ghost-hover);
}

.orders-row:focus-visible[b-omvqo3fh7w] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: -2px;
}

.orders-col-number[b-omvqo3fh7w] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-3);
    min-width: 0;
}

.orders-tile[b-omvqo3fh7w] {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 2.125rem;
    height: 2.125rem;
    border-radius: var(--lk-radius-sm);
    background: var(--lk-navy-soft);
    color: var(--lk-text-sec);
}

.orders-number[b-omvqo3fh7w] {
    overflow: hidden;
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.orders-col-date[b-omvqo3fh7w],
.orders-col-by[b-omvqo3fh7w] {
    overflow: hidden;
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.orders-org[b-omvqo3fh7w]::before {
    content: " · ";
}

.orders-org[b-omvqo3fh7w] {
    color: var(--lk-text-mut);
}

.orders-col-total[b-omvqo3fh7w] {
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 700;
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.orders-col-status[b-omvqo3fh7w] {
    display: flex;
    justify-content: flex-start;
}

.orders-col-chevron[b-omvqo3fh7w] {
    display: flex;
    justify-content: center;
    color: var(--lk-text-mut);
}

/* The columns beyond the number stop earning their width before the row does — the number and
   the chevron are what the eye needs to keep scanning and expanding. */
@media (max-width: 64rem) {
    .orders-head[b-omvqo3fh7w] {
        display: none;
    }

    .orders-row[b-omvqo3fh7w] {
        grid-template-columns: minmax(0, 1fr) auto 2rem;
        row-gap: var(--lk-space-1);
    }

    .orders-col-date[b-omvqo3fh7w],
    .orders-col-by[b-omvqo3fh7w] {
        grid-column: 1 / -1;
    }
}

/* ── The expanded row ───────────────────────────────────── */

.orders-detail[b-omvqo3fh7w] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-6);
    padding: var(--lk-space-2) var(--lk-space-4) var(--lk-space-5) var(--lk-space-10);
    border-bottom: var(--lk-border-width) solid var(--lk-line);
}

.orders-detail-lines[b-omvqo3fh7w] {
    display: grid;
    flex: 1 1 17rem;
    gap: var(--lk-space-2);
    min-width: 0;
}

.orders-line[b-omvqo3fh7w] {
    display: flex;
    align-items: baseline;
    gap: var(--lk-space-2);
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
}

.orders-line.is-option[b-omvqo3fh7w] {
    padding-left: var(--lk-space-5);
    color: var(--lk-text-sec);
}

.orders-line-quantity[b-omvqo3fh7w] {
    flex: 0 0 auto;
    color: var(--lk-text-mut);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.orders-line-name[b-omvqo3fh7w] {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.orders-line-price[b-omvqo3fh7w] {
    flex: 0 0 auto;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.orders-detail-facts[b-omvqo3fh7w] {
    display: grid;
    flex: 0 1 19rem;
    gap: var(--lk-space-2);
    align-content: start;
}

.orders-fact[b-omvqo3fh7w] {
    margin: 0;
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    line-height: 1.5;
}

.orders-fact b[b-omvqo3fh7w] {
    color: var(--lk-text);
}

.orders-signed[b-omvqo3fh7w] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
    margin: var(--lk-space-1) 0 0;
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
}
/* /Pages/Shop/ShopOrderPlacedPage.razor.rz.scp.css */
.placed[b-a0ci7tpa44] {
    max-width: 36rem;
    margin: var(--lk-space-5) auto 0;
}

.placed-head[b-a0ci7tpa44] {
    margin-bottom: var(--lk-space-5);
    text-align: center;
}

.placed-check[b-a0ci7tpa44] {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 4.5rem;
    height: 4.5rem;
    margin: 0 auto var(--lk-space-4);
    border-radius: var(--lk-radius-pill);
    background: var(--lk-ok-soft);
    color: var(--lk-ok);
}

.placed-title[b-a0ci7tpa44] {
    margin: 0;
    color: var(--lk-text);
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-display);
    font-weight: 800;
}

.placed-subtitle[b-a0ci7tpa44] {
    margin: var(--lk-space-3) 0 0;
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    line-height: 1.6;
}

.placed-number-row[b-a0ci7tpa44] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--lk-space-3);
    padding-bottom: var(--lk-space-3);
    border-bottom: var(--lk-border-width) solid var(--lk-line);
}

.placed-number-caption[b-a0ci7tpa44] {
    margin: 0;
    color: var(--lk-text-mut);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
}

.placed-number[b-a0ci7tpa44] {
    margin: 0;
    color: var(--lk-text);
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-title-sm);
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}

.placed-lines[b-a0ci7tpa44] {
    display: grid;
    gap: var(--lk-space-2);
    padding: var(--lk-space-3) 0;
    margin-bottom: var(--lk-space-3);
    border-bottom: var(--lk-border-width) solid var(--lk-line);
}

.placed-line[b-a0ci7tpa44] {
    display: flex;
    align-items: baseline;
    gap: var(--lk-space-2);
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
}

.placed-line.is-option[b-a0ci7tpa44] {
    padding-left: var(--lk-space-5);
    color: var(--lk-text-sec);
}

.placed-line-quantity[b-a0ci7tpa44] {
    flex: 0 0 auto;
    color: var(--lk-text-mut);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.placed-line-name[b-a0ci7tpa44] {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.placed-line-price[b-a0ci7tpa44] {
    flex: 0 0 auto;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.placed-delivery[b-a0ci7tpa44] {
    display: flex;
    align-items: flex-start;
    gap: var(--lk-space-3);
    padding: var(--lk-space-3);
    margin-top: var(--lk-space-4);
    border-radius: var(--lk-radius-control);
    background: var(--lk-info-soft);
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    line-height: 1.5;
}

.placed-delivery > :first-child[b-a0ci7tpa44] {
    flex: 0 0 auto;
    color: var(--lk-info);
}

.placed-onward[b-a0ci7tpa44] {
    margin-top: var(--lk-space-4);
}

.placed-link[b-a0ci7tpa44] {
    display: flex;
    align-items: center;
    justify-content: center;
    height: var(--lk-control-height-lg);
    border-radius: var(--lk-radius-control);
    background: var(--lk-navy);
    color: var(--lk-navy-contrast);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    font-weight: 600;
    text-decoration: none;
    transition: var(--lk-transition);
}

.placed-link:hover[b-a0ci7tpa44] {
    background: var(--lk-navy-hover);
}

.placed-link:focus-visible[b-a0ci7tpa44] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}
/* /Pages/Shop/ShopProductDialog.razor.rz.scp.css */
/* CSS isolation is per component, so the pack and option styles on ShopMainPage do not reach
   this markup — the two files carry near-identical rules on purpose rather than by oversight.
   The alternative, a shared pack/option component, is worth doing the moment a third surface
   needs them; with two it would be an abstraction built for its own sake. */

.shop-dialog-image[b-s5ntb61l1e] {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 16 / 9;
    margin-bottom: var(--lk-space-4);
    border-radius: var(--lk-radius-control);
    background: var(--lk-ghost-hover);
    overflow: hidden;
}

.shop-dialog-image img[b-s5ntb61l1e] {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.shop-dialog-text[b-s5ntb61l1e] {
    margin: 0 0 var(--lk-space-4);
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    line-height: 1.55;
}

.shop-packs[b-s5ntb61l1e] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--lk-space-2);
    margin-bottom: var(--lk-space-4);
}

.shop-pack[b-s5ntb61l1e] {
    height: var(--lk-control-height-sm);
    padding: 0 var(--lk-space-3);
    border: var(--lk-border-width) solid var(--lk-line-strong);
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface);
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    cursor: pointer;
    transition: var(--lk-transition);
}

.shop-pack.is-active[b-s5ntb61l1e] {
    border-color: var(--lk-magenta);
    font-weight: 700;
}

.shop-pack:focus-visible[b-s5ntb61l1e] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 2px;
}

.shop-options[b-s5ntb61l1e] {
    display: grid;
    gap: var(--lk-space-2);
}

.shop-options-caption[b-s5ntb61l1e] {
    margin: 0;
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 600;
}

.shop-option[b-s5ntb61l1e] {
    display: flex;
    align-items: center;
    gap: var(--lk-space-2);
}

/* Checkbox renders its own Label since #463, so what is left here is the one thing this screen
   wants differently: the option list is a dense row inside a card, at the smaller label size
   rather than the component's own. ::deep because the element is the component's markup — the
   same rule without it matches nothing and reports nothing. */
.shop-option[b-s5ntb61l1e]  .lk-checkbox-text {
    font-size: var(--lk-font-size-label);
}
/* /Pages/Shop/ShopQuantityStepper.razor.rz.scp.css */
.shop-stepper[b-iquqylq27u] {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    gap: var(--lk-space-1);
    padding: 0.125rem;
    border: var(--lk-border-width) solid var(--lk-line-strong);
    border-radius: var(--lk-radius-control);
    background: var(--lk-surface);
}

.shop-stepper-button[b-iquqylq27u] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    border: none;
    border-radius: var(--lk-radius-sm);
    background: none;
    color: var(--lk-text-sec);
    cursor: pointer;
    transition: var(--lk-transition);
}

.shop-stepper-button:hover:not(:disabled)[b-iquqylq27u] {
    background: var(--lk-ghost-hover);
    color: var(--lk-text);
}

.shop-stepper-button:disabled[b-iquqylq27u] {
    color: var(--lk-text-mut);
    cursor: not-allowed;
}

.shop-stepper-button:focus-visible[b-iquqylq27u] {
    outline: var(--lk-focus-ring-width) solid var(--lk-focus);
    outline-offset: 1px;
}

.shop-stepper-count[b-iquqylq27u] {
    min-width: 1.75rem;
    color: var(--lk-text);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 700;
    text-align: center;
    font-variant-numeric: tabular-nums;
}
/* /Pages/Shop/ShopSigningDialog.razor.rz.scp.css */
.signing-veil[b-5ogz23tdut] {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--lk-space-4);
    background: rgb(0 0 0 / 45%);
}

.signing-panel[b-5ogz23tdut] {
    width: min(25rem, 100%);
    max-height: 100%;
    padding: var(--lk-space-6);
    overflow-y: auto;
    border-radius: var(--lk-radius-card);
    background: var(--lk-surface);
    box-shadow: var(--lk-shadow-lg);
    text-align: center;
}

.signing-qr[b-5ogz23tdut] {
    display: block;
    width: 13rem;
    height: 13rem;
    margin: 0 auto var(--lk-space-4);
    border-radius: var(--lk-radius-sm);
}

/* Shown when the order has no QR tokens, which means this device is the only way in. */
.signing-glyph[b-5ogz23tdut] {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 5.25rem;
    height: 5.25rem;
    margin: 0 auto var(--lk-space-5);
    border-radius: var(--lk-radius-tile);
    background: var(--lk-navy);
    color: var(--lk-navy-contrast);
}

.signing-title[b-5ogz23tdut] {
    margin: 0;
    color: var(--lk-text);
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-title);
    font-weight: 800;
}

.signing-body[b-5ogz23tdut] {
    margin: var(--lk-space-2) 0 0;
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
    line-height: 1.6;
}

.signing-device[b-5ogz23tdut] {
    margin-top: var(--lk-space-3);
}

.signing-status[b-5ogz23tdut] {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--lk-space-2);
    margin: var(--lk-space-4) 0;
    color: var(--lk-text-mut);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
}
/* /Pages/Shop/ShopSummaryComponent.razor.rz.scp.css */
.shop-summary[b-bfqryya5ej] {
    display: grid;
    gap: var(--lk-space-3);
}

.shop-summary-group[b-bfqryya5ej] {
    display: grid;
    gap: var(--lk-space-2);
}

.shop-summary-caption[b-bfqryya5ej] {
    margin: 0;
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-label);
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.shop-summary-caption.is-accent[b-bfqryya5ej] {
    color: var(--lk-magenta-ink);
}

.shop-summary-line[b-bfqryya5ej] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--lk-space-3);
    color: var(--lk-text-sec);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-ui);
}

.shop-summary-line b[b-bfqryya5ej] {
    color: var(--lk-text);
    font-weight: 600;
    /* Figures line up in a column only if they share a width per digit. */
    font-variant-numeric: tabular-nums;
}

.shop-summary-line.is-total[b-bfqryya5ej] {
    padding-top: var(--lk-space-2);
    border-top: var(--lk-border-width) solid var(--lk-line);
    color: var(--lk-text);
    font-weight: 700;
}

.shop-summary-line.is-total b[b-bfqryya5ej] {
    font-family: var(--lk-font-display);
    font-size: var(--lk-font-size-title-sm);
    font-weight: 800;
}

.shop-summary-line.is-total.is-accent b[b-bfqryya5ej] {
    color: var(--lk-magenta-ink);
}

.shop-summary-divider[b-bfqryya5ej] {
    height: var(--lk-border-width);
    background: var(--lk-line);
}

.shop-summary-note[b-bfqryya5ej] {
    margin: 0;
    color: var(--lk-text-mut);
    font-family: var(--lk-font-ui);
    font-size: var(--lk-font-size-caption);
    line-height: 1.6;
}
