/* Shared, app-wide UI primitives - Card/Button/Badge/EmptyState/Timeline/DetailsPanel - backing
   the components in Components/Shared/. Same approach as wwwroot/css/app-table.css: every root
   class computes its own --app-* custom properties from var(--brand-*, <light fallback>), so a
   component looks right automatically whether the page is under a per-event BOOST-style theme
   (ThemedHead sets --brand-*) or a plain page using only InuniNav (falls back to these light
   defaults) - no per-page "--themed" modifier class needed, unlike the older .iam-card pattern
   this file supersedes. */

/* ---- Required mark - shared by every field-like component's Required parameter ---- */

.app-required-mark {
    color: #b91c1c;
    margin-left: 0.15rem;
}

/* ---- Card ---- */

.app-card {
    --app-card-surface: var(--brand-surface, #fff);
    --app-card-border: var(--brand-border, #d8e8e8);
    --app-card-text: var(--brand-text-main, #232323);
    --app-card-text-muted: var(--brand-text-muted, #5d7a7a);

    background: var(--app-card-surface);
    border: 1px solid var(--app-card-border);
    border-radius: var(--brand-radius, 0.75rem);
    padding: 1.25rem 1.25rem;
    color: var(--app-card-text);
    margin-bottom: 1.25rem;
}

/* position: relative only applies here (not on the base .app-card) - it's only needed as the
   containing block for .app-card__link below, and giving every plain card a positioned stacking
   context regressed unrelated absolutely-positioned overlays elsewhere on the page (e.g. it made
   an ordinary card paint above InuniNav's dropdown menu). */
.app-card--clickable {
    position: relative;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.app-card--clickable:hover {
    border-color: var(--brand-primary, #185354);
    box-shadow: 0 2px 6px rgba(16, 24, 40, 0.1), 0 1px 3px rgba(16, 24, 40, 0.08);
}

/* Filled = solid brand background instead of the default plain surface + border, same
   filled-vs-outline distinction Button.razor's own Brand/Outline variants already make. Overrides
   the --app-card-* custom properties (not just .app-card's own background) so title/actions/body
   text inherited from them stay readable against the now-dark background. */
.app-card--filled {
    --app-card-surface: var(--brand-primary, #185354);
    --app-card-border: var(--brand-primary, #185354);
    --app-card-text: var(--brand-primary-contrast, #fff);
    --app-card-text-muted: color-mix(in srgb, var(--brand-primary-contrast, #fff) 70%, transparent);

    background: var(--app-card-surface);
    border-color: var(--app-card-border);
    color: var(--app-card-text);
}

.app-card--filled.app-card--clickable:hover {
    border-color: var(--app-card-border);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
    filter: brightness(1.05);
}

/* Loading's skeleton stretches to occupy the card's own content area (not a small fixed-size
   snippet floating inside a big card) - min-height is a deliberately loose approximation of
   "about as tall as real content would be", not an exact match to any particular layout. */
.app-card__skeleton {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: 4.5rem;
}

/* SkeletonLoader's Card variant (.app-skeleton--card) draws its OWN border/background/padding -
   correct when it stands alone (e.g. a list of loading cards), wrong here: nested inside a real
   .app-card that already has all three, it rendered as a second, independently-colored mini-card
   floating inside the outer one instead of the loading state simply BEING the card's content. */
.app-card__skeleton .app-skeleton--card {
    padding: 0;
    border: none;
    border-radius: 0;
    background: none;
}

/* Filled cards need their skeleton shimmer to read against the fill color instead of the default
   light-gray .app-skeleton palette (which is nearly invisible on a dark/colored background) - tint
   relative to --app-card-surface (which Filled already points at the fill, custom FillColor
   included) so the shimmer always matches whatever color the card actually ends up filled with. */
.app-card--filled .app-skeleton__line,
.app-card--filled .app-skeleton__avatar,
.app-card--filled .app-skeleton__box,
.app-card--filled .app-skeleton__pill,
.app-card--filled .app-skeleton__image {
    background: linear-gradient(
        90deg,
        color-mix(in srgb, var(--app-card-surface) 60%, white) 25%,
        color-mix(in srgb, var(--app-card-surface) 40%, white) 37%,
        color-mix(in srgb, var(--app-card-surface) 60%, white) 63%
    );
    background-size: 400% 100%;
}

/* ---- Card layouts (Stat / Media) ---- */

.app-card__stat-label {
    margin: 0 0 0.35rem;
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--app-card-text-muted);
}

.app-card__stat-value {
    margin: 0;
    font-size: 1.75rem;
    font-weight: 700;
    color: var(--app-card-text);
    font-variant-numeric: tabular-nums;
}

.app-card__stat-trend {
    margin: 0.35rem 0 0;
    font-size: 0.8rem;
    font-weight: 600;
}

.app-card__stat-trend--good { color: #16a34a; }
.app-card__stat-trend--warn { color: #a16207; }
.app-card__stat-trend--bad { color: #b91c1c; }
.app-card__stat-trend--info { color: var(--brand-primary, #185354); }
.app-card__stat-trend--neutral { color: var(--app-card-text-muted); }

.app-card__media {
    display: block;
    width: calc(100% + 2.5rem);
    margin: -1.25rem -1.25rem 1rem;
    max-width: none;
    height: 10rem;
    object-fit: cover;
    border-radius: var(--brand-radius, 0.75rem) var(--brand-radius, 0.75rem) 0 0;
}

.app-card__description {
    margin: 0 0 0.5rem;
    font-size: 0.88rem;
    color: var(--app-card-text-muted);
}

.app-card__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.app-card__title {
    font-family: var(--brand-font-serif, 'Libre Baskerville', Georgia, serif);
    font-size: 1.25rem;
    font-weight: 400;
    margin: 0;
    color: var(--app-card-text);
}

.app-card__actions {
    /* Sits above .app-card__link (a whole-card overlay) so HeaderActions stays independently
       clickable even when the card itself is also clickable - same layering TimelineItem doesn't
       need (it has no nested interactive content), but Card does. */
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

/* Invisible overlay covering the whole card - the actual click/keyboard-focus target, same
   technique as .app-timeline__link. Sits behind .app-card__actions (see its own comment) so a
   HeaderActions button placed inside a clickable card still gets its own clicks. */
.app-card__link {
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
    display: block;
    width: 100%;
    margin: 0;
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
}

.app-card__link:focus-visible {
    outline: 2px solid var(--brand-primary, #185354);
    outline-offset: -2px;
}

@media (max-width: 640px) {
    .app-card__head {
        flex-direction: column;
        align-items: stretch;
    }
}

/* ---- Button ---- */

.app-btn {
    --app-btn-accent: var(--brand-primary, #185354);
    --app-btn-accent-contrast: var(--brand-primary-contrast, #fff);
    --app-btn-text: var(--brand-text-main, #232323);
    --app-btn-text-muted: var(--brand-text-muted, #5d7a7a);
    --app-btn-border: var(--brand-border, #d8e8e8);

    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.55rem 1.15rem;
    border-radius: var(--brand-radius, 0.5rem);
    font-size: 0.72rem;
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    border: 1px solid transparent;
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
    background: none;
}

.app-btn--sm {
    padding: 0.4rem 0.85rem;
    font-size: 0.66rem;
}

/* Button.razor's Loading state - reshapes SkeletonLoader's generic .app-skeleton__pill (normally
   999px/fully round) to match a real button's actual rounded-rect shape and height instead. */
.app-btn-skeleton .app-skeleton__pill {
    width: 5.5rem;
    height: 2.15rem;
    border-radius: var(--brand-radius, 0.5rem);
}

.app-btn-skeleton--sm .app-skeleton__pill {
    width: 4.5rem;
    height: 1.65rem;
    border-radius: var(--brand-radius, 0.5rem);
}

.app-btn:disabled,
.app-btn[aria-disabled="true"] {
    opacity: 0.6;
    cursor: default;
}

.app-btn--brand {
    background: var(--app-btn-accent);
    color: var(--app-btn-accent-contrast);
}

.app-btn--brand:hover:not(:disabled) {
    filter: brightness(0.94);
}

.app-btn--outline {
    background: transparent;
    border-color: var(--app-btn-border);
    color: var(--app-btn-text-muted);
}

.app-btn--outline:hover:not(:disabled) {
    color: var(--app-btn-text);
    border-color: color-mix(in srgb, var(--app-btn-text) 30%, transparent);
}

.app-btn--ghost {
    background: transparent;
    border-color: color-mix(in srgb, var(--app-btn-text) 20%, transparent);
    color: var(--app-btn-text);
}

.app-btn--ghost:hover:not(:disabled) {
    background: color-mix(in srgb, var(--app-btn-text) 8%, transparent);
}

.app-btn--danger {
    background: transparent;
    border-color: #dc2626;
    color: #dc2626;
}

.app-btn--danger:hover:not(:disabled) {
    background: color-mix(in srgb, #dc2626 10%, transparent);
}

.app-btn--busy {
    position: relative;
    color: transparent !important;
}

.app-btn--busy::after {
    content: "";
    position: absolute;
    width: 0.9rem;
    height: 0.9rem;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-top-color: transparent;
    color: var(--app-btn-text);
    animation: app-btn-spin 0.6s linear infinite;
}

.app-btn--brand.app-btn--busy::after {
    color: var(--app-btn-accent-contrast);
}

@keyframes app-btn-spin {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .app-btn--busy::after { animation: none; }
}

/* ---- Badge ---- */

.app-badge {
    --app-badge-good-bg: color-mix(in srgb, #22c55e 18%, transparent);
    --app-badge-good-fg: #16a34a;
    --app-badge-warn-bg: color-mix(in srgb, #eab308 18%, transparent);
    --app-badge-warn-fg: #a16207;
    --app-badge-bad-bg: color-mix(in srgb, #ef4444 18%, transparent);
    --app-badge-bad-fg: #b91c1c;
    --app-badge-info-bg: color-mix(in srgb, var(--brand-accent, #2563eb) 18%, transparent);
    --app-badge-info-fg: var(--brand-accent, #2563eb);
    --app-badge-neutral-bg: color-mix(in srgb, var(--brand-text-muted, #5d7a7a) 16%, transparent);
    --app-badge-neutral-fg: var(--brand-text-muted, #5d7a7a);

    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.65rem;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 600;
    white-space: nowrap;
}

.app-badge::before {
    content: "";
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 50%;
    background: currentColor;
    flex: none;
}

.app-badge--good { background: var(--app-badge-good-bg); color: var(--app-badge-good-fg); }
.app-badge--warn { background: var(--app-badge-warn-bg); color: var(--app-badge-warn-fg); }
.app-badge--bad { background: var(--app-badge-bad-bg); color: var(--app-badge-bad-fg); }
.app-badge--info { background: var(--app-badge-info-bg); color: var(--app-badge-info-fg); }
.app-badge--neutral { background: var(--app-badge-neutral-bg); color: var(--app-badge-neutral-fg); }

/* ---- Empty state ---- */

.app-empty-state {
    background: color-mix(in srgb, var(--brand-surface, #fff) 92%, transparent);
    border: 1px solid var(--brand-border, #d8e8e8);
    border-radius: var(--brand-radius, 1rem);
    padding: 2.25rem 1.25rem;
    text-align: center;
    color: var(--brand-text-muted, #5d7a7a);
}

.app-empty-state__icon {
    font-size: 1.75rem;
    margin-bottom: 0.5rem;
    line-height: 1;
}

.app-empty-state__message {
    margin: 0;
}

/* ---- Timeline ---- */

.app-timeline__head {
    margin-bottom: 0.75rem;
}

.app-timeline__title {
    font-size: 1.05rem;
    font-weight: 600;
    margin: 0 0 0.2rem;
    color: var(--brand-text-main, #232323);
}

.app-timeline__description {
    font-size: 0.85rem;
    color: var(--brand-text-muted, #5d7a7a);
    margin: 0;
}

.app-timeline {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

.app-timeline__item {
    position: relative;
    display: flex;
    align-items: stretch;
    gap: 0.75rem;
    padding: 0.55rem 0.5rem;
    margin: 0 -0.5rem;
    border-radius: var(--brand-radius, 0.4rem);
}

.app-timeline__item--linked:hover {
    background: var(--brand-accent-soft, #eef6f6);
}

.app-timeline__marker {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex: none;
}

.app-timeline__dot {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: var(--brand-primary, #185354);
    flex: none;
    margin-top: 0.4rem;
}

.app-timeline__dot--good { background: #16a34a; }
.app-timeline__dot--warn { background: #a16207; }
.app-timeline__dot--bad { background: #b91c1c; }

/* The vertical time axis - one segment per row, running from just under this row's dot down to
   the next row's dot, so the line still looks continuous however tall each row's own content is.
   The last row has nothing below it to connect to. */
.app-timeline__line {
    flex: 1;
    width: 2px;
    min-height: 0.4rem;
    margin-top: 0.2rem;
    background: var(--brand-border, #d8e8e8);
}

.app-timeline__item:last-child .app-timeline__line {
    display: none;
}

.app-timeline__body {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    min-width: 0;
    flex: 1;
}

.app-timeline__meta {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.75rem;
    color: var(--brand-text-muted, #5d7a7a);
}

.app-timeline__actor {
    font-weight: 600;
}

.app-timeline__when {
    font-variant-numeric: tabular-nums;
}

.app-timeline__details {
    flex: none;
    align-self: flex-start;
    margin-top: 0.05rem;
    color: var(--brand-primary, #185354);
    font-size: 1.1rem;
    line-height: 1.2;
}

/* Invisible overlay covering the whole row - the actual click/keyboard-focus target, so a
   consumer isn't limited to clicking the small arrow. The arrow itself (above) is purely the
   visual affordance and has no href of its own. */
.app-timeline__link {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    /* Resets so a <button> (OnDetailsClick) looks identical to an <a> (DetailsHref) here - both
       are otherwise invisible, full-row overlays, not visible controls in their own right. */
    display: block;
    width: 100%;
    margin: 0;
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
}

.app-timeline__link:focus-visible {
    outline: 2px solid var(--brand-primary, #185354);
    outline-offset: -2px;
}

.app-timeline__label {
    font-size: 0.88rem;
    color: var(--brand-text-main, #232323);
}

.app-timeline__actor {
    margin-right: 0.35rem;
    color: var(--brand-text-main, #232323);
}

.app-timeline__actions {
    flex: none;
    margin-left: auto;
}

/* ---- Details / slide-over panel ---- */

/* No dimming backdrop and click-through by default (pointer-events: none) - the rest of the page
   stays fully usable while the panel is open. Only .app-panel itself (below) re-enables pointer
   events, and only once it's actually slid into view. */
.app-panel-host {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: flex;
    justify-content: flex-end;
    pointer-events: none;
}

.app-panel {
    --app-panel-surface: var(--brand-surface, #fff);
    --app-panel-border: var(--brand-border, #d8e8e8);
    --app-panel-text: var(--brand-text-main, #232323);
    --app-panel-text-muted: var(--brand-text-muted, #5d7a7a);

    /* Up to 45% of the viewport, with a floor so form fields stay usable on narrower desktops. */
    width: clamp(28rem, 45vw, 42rem);
    height: 100%;
    background: var(--app-panel-surface);
    color: var(--app-panel-text);
    box-shadow: -4px 0 16px rgba(21, 23, 26, 0.18);
    display: flex;
    flex-direction: column;
    transform: translateX(100%);
    transition: transform 200ms ease-out;
    pointer-events: none;
}

.app-panel-host.is-open .app-panel {
    transform: translateX(0);
    pointer-events: auto;
}

@media (max-width: 640px) {
    .app-panel {
        width: 100%;
    }
}

.app-panel__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 1rem;
    border-bottom: 1px solid var(--app-panel-border);
    flex: none;
}

.app-panel__title {
    font-family: var(--brand-font-serif, 'Libre Baskerville', Georgia, serif);
    font-size: 1.2rem;
    font-weight: 400;
    margin: 0;
}

.app-panel__head-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: none;
}

.app-panel__close {
    border: none;
    background: none;
    color: var(--app-panel-text-muted);
    width: 1.75rem;
    height: 1.75rem;
    border-radius: var(--brand-radius, 0.4rem);
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    cursor: pointer;
}

.app-panel__close:hover {
    background: color-mix(in srgb, var(--app-panel-text) 8%, transparent);
    color: var(--app-panel-text);
}

.app-panel__body {
    flex: 1;
    overflow-y: auto;
    padding: 1.25rem;
}

@media (prefers-reduced-motion: reduce) {
    .app-panel { transition: none; }
}

.app-expandable {
    --app-expandable-border: var(--brand-border, #d8e8e8);
    --app-expandable-text-muted: var(--brand-text-muted, #93a5a5);

    display: block;
    border: 1px solid var(--app-expandable-border);
    border-radius: var(--brand-radius, 0.5rem);
    padding: 0.5rem 0.7rem;
    margin-bottom: 0.5rem;
}

.app-expandable:last-child {
    margin-bottom: 0;
}

.app-expandable__summary {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    font-weight: 500;
    list-style: none;
}

.app-expandable__summary::-webkit-details-marker {
    display: none;
}

.app-expandable__summary::before {
    content: "▸";
    color: var(--app-expandable-text-muted);
    transition: transform 150ms ease-out;
}

.app-expandable[open] > .app-expandable__summary::before {
    transform: rotate(90deg);
}

.app-expandable__body {
    margin-top: 0.6rem;
    padding-top: 0.6rem;
    border-top: 1px dashed var(--app-expandable-border);
}

@media (prefers-reduced-motion: reduce) {
    .app-expandable__summary::before { transition: none; }
}

/* ---- Checkbox ---- */

.app-checkbox {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

/* Custom-drawn rather than relying on the native control's own chrome (which accent-color alone
   still leaves in charge of) - border-radius on a native checkbox isn't reliably honored across
   browsers (Safari in particular keeps it square regardless), so the round-for-single-select
   variant below needs the box fully under this file's own CSS instead. */
.app-checkbox__input {
    appearance: none;
    -webkit-appearance: none;
    width: 1.05rem;
    height: 1.05rem;
    margin: 0;
    flex: none;
    display: inline-grid;
    place-content: center;
    border: 1.5px solid var(--brand-border, #cbd5e1);
    border-radius: var(--brand-radius, 0.25rem);
    background: var(--brand-surface, #fff);
    cursor: pointer;
    transition: background-color 0.1s ease, border-color 0.1s ease;
}

.app-checkbox__input::before {
    content: "";
    width: 0.6rem;
    height: 0.6rem;
    transform: scale(0);
    transition: transform 0.1s ease-in-out;
    background: var(--brand-primary-contrast, #fff);
    clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
}

.app-checkbox__input:checked {
    background: var(--brand-primary, #185354);
    border-color: var(--brand-primary, #185354);
}

.app-checkbox__input:checked::before {
    transform: scale(1);
}

.app-checkbox__input:focus-visible {
    outline: 2px solid var(--brand-primary, #185354);
    outline-offset: 2px;
}

.app-checkbox__label {
    font-size: 0.9rem;
    color: var(--brand-text-main, #232323);
    cursor: pointer;
    user-select: none;
}

.app-checkbox--disabled .app-checkbox__input,
.app-checkbox--disabled .app-checkbox__label {
    cursor: not-allowed;
    opacity: 0.6;
}

/* "Pick exactly one" groups (CheckboxGroup with MaxSelectable=1) read like a radio choice, so the
   box itself reads that way too - still a real checkbox underneath, only the shape changes. */
.app-checkbox--round .app-checkbox__input {
    border-radius: 50%;
}

/* ---- Checkbox group ---- */

.app-checkbox-group {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.app-checkbox-group__label {
    margin: 0;
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--brand-text-muted, #5d7a7a);
}

.app-checkbox-group__hint {
    margin: 0.15rem 0 0;
    font-size: 0.8rem;
    color: var(--brand-text-muted, #5d7a7a);
}

/* ---- Field (TextInput / TextArea / Select) ---- */

.app-field {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin-bottom: 1rem;
}

.app-field__label {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--brand-text-main, #232323);
}

/* TextInput's own control wrapper - floats its label INSIDE the input's box instead of above it
   (see TextInput.razor's own comment). Not used by TextArea/Select, which keep the label above. */
.app-field__control {
    position: relative;
}

.app-field__control .app-field__input {
    padding-top: 1.15rem;
    padding-bottom: 0.35rem;
}

.app-field__control .app-field__label {
    position: absolute;
    left: 0.7rem;
    top: 50%;
    transform: translateY(-50%);
    margin: 0;
    font-size: 0.9rem;
    font-weight: 400;
    color: var(--brand-text-muted, #93a5a5);
    background: transparent;
    pointer-events: none;
    transition: top 0.12s ease, transform 0.12s ease, font-size 0.12s ease, font-weight 0.12s ease, color 0.12s ease;
}

.app-field__control .app-field__input:focus + .app-field__label,
.app-field__control .app-field__input:not(:placeholder-shown) + .app-field__label {
    top: 0.5rem;
    transform: translateY(0);
    font-size: 0.7rem;
    font-weight: 600;
}

.app-field__control .app-field__input:focus + .app-field__label {
    color: var(--brand-primary, #185354);
}

@media (prefers-reduced-motion: reduce) {
    .app-field__control .app-field__label { transition: none; }
}

.app-field__input {
    width: 100%;
    padding: 0.45rem 0.7rem;
    font-size: 0.9rem;
    color: var(--brand-text-main, #232323);
    background: var(--brand-surface, #fff);
    border: 1px solid var(--brand-border, #cbd5e1);
    border-radius: var(--brand-radius, 0.5rem);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.app-field__input::placeholder {
    color: var(--brand-text-muted, #93a5a5);
}

.app-field__input:focus {
    outline: none;
    border-color: var(--brand-primary, #185354);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-primary, #185354) 20%, transparent);
}

.app-field__input:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

.app-field__input--textarea {
    resize: vertical;
    min-height: 2.5rem;
}

.app-field__input--select {
    cursor: pointer;
}

.app-field__input--select[multiple] {
    padding: 0.3rem;
}

.app-field__input--select[multiple] option {
    padding: 0.3rem 0.5rem;
    border-radius: var(--brand-radius, 0.3rem);
}

.app-field__input--error {
    border-color: #b91c1c;
}

.app-field__input--error:focus {
    box-shadow: 0 0 0 3px rgba(185, 28, 28, 0.2);
}

.app-field__error {
    margin: 0;
    font-size: 0.8rem;
    color: #b91c1c;
}

/* ---- Switch ---- */

.app-switch {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

.app-switch__input {
    appearance: none;
    -webkit-appearance: none;
    position: relative;
    flex: none;
    width: 2.25rem;
    height: 1.25rem;
    margin: 0;
    border-radius: 999px;
    background: var(--brand-border, #cbd5e1);
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.app-switch__input::before {
    content: "";
    position: absolute;
    top: 0.15rem;
    left: 0.15rem;
    width: 0.95rem;
    height: 0.95rem;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    transition: transform 0.15s ease;
}

.app-switch__input:checked {
    background: var(--brand-primary, #185354);
}

.app-switch__input:checked::before {
    transform: translateX(1rem);
}

.app-switch__input:focus-visible {
    outline: 2px solid var(--brand-primary, #185354);
    outline-offset: 2px;
}

.app-switch__label {
    font-size: 0.9rem;
    color: var(--brand-text-main, #232323);
    cursor: pointer;
    user-select: none;
}

.app-switch--disabled .app-switch__input,
.app-switch--disabled .app-switch__label {
    cursor: not-allowed;
    opacity: 0.6;
}

/* ---- Alert ---- */

.app-alert {
    --app-alert-accent: var(--brand-primary, #185354);
    --app-alert-bg: color-mix(in srgb, var(--app-alert-accent) 10%, var(--brand-surface, #fff));

    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.75rem 1rem;
    border-radius: var(--brand-radius, 0.6rem);
    border: 1px solid var(--app-alert-accent);
    background: var(--app-alert-bg);
    color: var(--brand-text-main, #232323);
    margin-bottom: 1rem;
}

.app-alert--good { --app-alert-accent: #16a34a; }
.app-alert--warn { --app-alert-accent: #a16207; }
.app-alert--bad { --app-alert-accent: #b91c1c; }
.app-alert--info { --app-alert-accent: var(--brand-primary, #185354); }
.app-alert--neutral { --app-alert-accent: var(--brand-border, #93a5a5); }

.app-alert__body {
    flex: 1;
    min-width: 0;
    font-size: 0.9rem;
}

.app-alert__close {
    flex: none;
    border: none;
    background: none;
    color: inherit;
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    padding: 0;
    opacity: 0.6;
}

.app-alert__close:hover {
    opacity: 1;
}

/* Pinned to the very top of the viewport, full-width, no rounded top corners or top border - the
   "systemowy error u gory" (system-error-style bar) look, e.g. a browser permission prompt. */
.app-alert--top {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1000;
    margin-bottom: 0;
    border-radius: 0;
    border-width: 0 0 1px 0;
    justify-content: center;
    box-shadow: 0 2px 10px rgba(16, 24, 40, 0.12);
}

/* Dims everything behind a Center alert so it reads as blocking, not just another banner. */
.app-alert-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background: rgba(15, 23, 23, 0.5);
}

.app-alert--center {
    max-width: 28rem;
    width: 100%;
    margin-bottom: 0;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.3);
}

/* ---- Skeleton loader ---- */

.app-skeleton {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.app-skeleton--listitem,
.app-skeleton--avatar {
    flex-direction: row;
    align-items: center;
    gap: 0.75rem;
}

.app-skeleton--card {
    padding: 1.25rem 1.5rem;
    border: 1px solid var(--brand-border, #d8e8e8);
    border-radius: var(--brand-radius, 0.75rem);
    background: var(--brand-surface, #fff);
}

.app-skeleton__line,
.app-skeleton__avatar,
.app-skeleton__box,
.app-skeleton__pill,
.app-skeleton__image {
    flex: none;
    background: linear-gradient(
        90deg,
        var(--brand-border, #e2e8f0) 25%,
        color-mix(in srgb, var(--brand-border, #e2e8f0) 40%, white) 37%,
        var(--brand-border, #e2e8f0) 63%
    );
    background-size: 400% 100%;
    animation: app-skeleton-shimmer 1.4s ease infinite;
    border-radius: var(--brand-radius, 0.25rem);
}

.app-skeleton__line {
    height: 0.75rem;
    width: 100%;
}

.app-skeleton__line--title {
    height: 1rem;
    width: 55%;
}

.app-skeleton__avatar {
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
}

.app-skeleton__line--label {
    height: 0.7rem;
    width: 35%;
}

.app-skeleton__box {
    height: 2.25rem;
    width: 100%;
    border-radius: var(--brand-radius, 0.5rem);
}

.app-skeleton__pill {
    height: 2rem;
    width: 6rem;
    border-radius: 999px;
}

.app-skeleton__image {
    width: 100%;
    height: 8rem;
    border-radius: var(--brand-radius, 0.5rem);
}

.app-skeleton__lines {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

@keyframes app-skeleton-shimmer {
    0% { background-position: 100% 0; }
    100% { background-position: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
    .app-skeleton__line,
    .app-skeleton__avatar {
        animation: none;
    }
}

/* ---- Search input ---- */

.app-search {
    position: relative;
    display: flex;
    align-items: center;
}

.app-search__icon {
    position: absolute;
    left: 0.7rem;
    font-size: 0.85rem;
    opacity: 0.6;
    pointer-events: none;
}

.app-search__input {
    width: 100%;
    padding: 0.45rem 2.2rem;
    font-size: 0.9rem;
    color: var(--brand-text-main, #232323);
    background: var(--brand-surface, #fff);
    border: 1px solid var(--brand-border, #cbd5e1);
    border-radius: var(--brand-radius, 0.5rem);
}

.app-search__input:focus {
    outline: none;
    border-color: var(--brand-primary, #185354);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-primary, #185354) 20%, transparent);
}

.app-search__clear {
    position: absolute;
    right: 0.5rem;
    border: none;
    background: none;
    color: var(--brand-text-muted, #5d7a7a);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    padding: 0.2rem;
}

.app-search__clear:hover {
    color: var(--brand-text-main, #232323);
}

/* ---- Form layout (Form / FormRow / FormActions) ---- */

.app-form {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.app-form-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    gap: 1rem;
    align-items: start;
}

.app-form-actions {
    display: flex;
    gap: 0.5rem;
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--brand-border, #d8e8e8);
}

/* ---- Info list ---- */

/* Horizontal (default): every item is one flex child ("Label: Value" as a unit, via
   .app-info-list__item below) flowing left-to-right on a shared row, wrapping onto additional
   rows only once they no longer all fit - not one row per item. */
.app-info-list {
    display: flex;
    flex-wrap: wrap;
    column-gap: 1.5rem;
    row-gap: 0.5rem;
    margin: 0;
}

/* Grouping each dt/dd pair in its own div (valid HTML5 inside a <dl>) keeps a label and its value
   as one atomic flex child, so a line wrap can never separate them. */
.app-info-list__item {
    display: flex;
    align-items: baseline;
    gap: 0.3rem;
}

.app-info-list__label {
    margin: 0;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--brand-text-muted, #5d7a7a);
    white-space: nowrap;
}

.app-info-list:not(.app-info-list--vertical) .app-info-list__label::after {
    content: ":";
}

.app-info-list__value {
    margin: 0;
    font-size: 0.9rem;
    color: var(--brand-text-main, #232323);
}

/* Vertical: items stack in a column instead of sharing one row, and each item's own label sits
   above its value instead of beside it. */
.app-info-list--vertical {
    flex-direction: column;
    row-gap: 0.7rem;
}

.app-info-list--vertical .app-info-list__item {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.1rem;
}

@media (max-width: 560px) {
    .app-info-list {
        flex-direction: column;
        row-gap: 0.5rem;
    }

    .app-info-list__item {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.1rem;
    }

    .app-info-list:not(.app-info-list--vertical) .app-info-list__label::after {
        content: "";
    }
}

/* ---- Confirmation dialog ---- */
/* Same backdrop-dimmed, centered-over-everything shell as .app-alert-backdrop/.app-alert--center
   (Alert's own Position="Center") - kept as separate classes since a confirmation always needs
   its own Confirm/Cancel action row, unlike a plain Alert. */

.app-confirm-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background: rgba(15, 23, 23, 0.5);
}

.app-confirm {
    max-width: 26rem;
    width: 100%;
    background: var(--brand-surface, #fff);
    border-radius: var(--brand-radius, 0.75rem);
    padding: 1.25rem;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.3);
    color: var(--brand-text-main, #232323);
}

.app-confirm__title {
    font-family: var(--brand-font-serif, 'Libre Baskerville', Georgia, serif);
    font-size: 1.25rem;
    font-weight: 400;
    margin: 0 0 0.5rem;
}

.app-confirm__body {
    font-size: 0.9rem;
    color: var(--brand-text-muted, #5d7a7a);
}

.app-confirm__actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 1.25rem;
}

/* ---- Statistics card ---- */

.app-stat-card {
    background: var(--brand-surface, #fff);
    border: 1px solid var(--brand-border, #d8e8e8);
    border-radius: var(--brand-radius, 0.75rem);
    padding: 1.1rem 1rem;
}

.app-stat-card__label {
    margin: 0 0 0.35rem;
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--brand-text-muted, #5d7a7a);
}

.app-stat-card__value {
    margin: 0;
    font-size: 1.75rem;
    font-weight: 700;
    color: var(--brand-text-main, #232323);
    font-variant-numeric: tabular-nums;
}

.app-stat-card__trend {
    margin: 0.35rem 0 0;
    font-size: 0.8rem;
    font-weight: 600;
}

.app-stat-card__trend--good { color: #16a34a; }
.app-stat-card__trend--warn { color: #a16207; }
.app-stat-card__trend--bad { color: #b91c1c; }
.app-stat-card__trend--info { color: var(--brand-primary, #185354); }
.app-stat-card__trend--neutral { color: var(--brand-text-muted, #5d7a7a); }

/* ---- Data table ---- */

.app-datatable-wrap {
    overflow-x: auto;
}

.app-datatable {
    width: 100%;
    /* Fixed layout - once a column's width is settled (from its <col>, or evenly among the rest
       on first paint) it stays put, so switching a cell from CellTemplate to a bordered
       EditTemplate input never reflows sibling columns. */
    table-layout: fixed;
    border-collapse: collapse;
    font-size: 0.9rem;
}

.app-datatable th,
.app-datatable td {
    padding: 0.6rem 0.75rem;
    text-align: left;
    border-bottom: 1px solid var(--brand-border, #d8e8e8);
    /* No overflow/text-overflow here on purpose - setting a non-"visible" overflow on a table
       cell makes browsers size that cell from its own content instead of stretching it to match
       the row's tallest sibling, so a wrapped multi-line cell ends up taller than the rest of its
       row and the shared border-bottom stops lining up across columns. Wrapping (the default
       white-space: normal) combined with the fixed Width from DataTableColumn is enough to keep
       columns from blowing out on their own. */
    overflow-wrap: break-word;
}

.app-datatable--compact th,
.app-datatable--compact td {
    padding: 0.3rem 0.6rem;
}

.app-datatable th {
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--brand-text-muted, #5d7a7a);
}

.app-datatable tbody tr:hover {
    background: color-mix(in srgb, var(--brand-text-main, #000) 4%, transparent);
}

.app-datatable__sort-btn {
    all: unset;
    display: inline-flex;
    align-items: center;
    gap: 0.15rem;
    cursor: pointer;
    font: inherit;
    text-transform: inherit;
    letter-spacing: inherit;
    color: inherit;
}

.app-datatable__sort-btn:hover {
    color: var(--brand-text-main, #232323);
}

.app-datatable__sort-btn:focus-visible {
    outline: 2px solid var(--brand-primary, #185354);
    outline-offset: 2px;
    border-radius: var(--brand-radius, 0.2rem);
}

.app-datatable__drag-handle {
    display: inline-block;
    cursor: grab;
    color: var(--brand-text-muted, #5d7a7a);
    margin-right: 0.35rem;
    user-select: none;
}

.app-datatable__drag-handle:active {
    cursor: grabbing;
}

.app-datatable__th--dragging {
    opacity: 0.4;
    outline: 2px dashed var(--brand-primary, #185354);
    outline-offset: -3px;
}

/* Body cells only need the grayed-out treatment, not the outline (which would draw a dashed box
   around every single cell down the column - the header outline alone is already enough to mark
   which column is being moved). */
.app-datatable__td--dragging {
    opacity: 0.4;
}

/* Painted by datatable-drag.js on whichever header is currently under the pointer, showing which
   side of it the dragged column would land on if dropped there - inset so it never shifts layout
   the way a real border would under border-collapse: collapse. */
.app-datatable__th--drop-before {
    box-shadow: inset 3px 0 0 0 var(--brand-primary, #185354);
}

.app-datatable__th--drop-after {
    box-shadow: inset -3px 0 0 0 var(--brand-primary, #185354);
}

.app-datatable__actions-head {
    text-align: right;
}

.app-datatable__row-actions {
    display: flex;
    gap: 0.4rem;
    justify-content: flex-end;
    flex-wrap: nowrap;
    white-space: nowrap;
}

.app-datatable__empty {
    text-align: center;
    padding: 1.5rem 0.75rem;
}

.app-datatable__error {
    color: #b91c1c;
    font-size: 0.85rem;
    padding-top: 0;
}

/* ---- Data table toolbar (search / Widoki / sort / Kolumny / quick filters / Filtry / density) ---- */

.app-datatable__toolbar {
    margin-bottom: 0.75rem;
}

.app-datatable__toolbar-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0.5rem;
}

/* Every Select/SearchInput dropped straight into the toolbar row - both wrap their control in
   .app-field, which carries its own stacked-label spacing (margin-bottom, column layout) that
   reads as a misaligned gap when the field sits inline next to plain buttons instead of stacked
   in a form. */
.app-datatable__toolbar-row .app-field {
    margin-bottom: 0;
    min-width: 9rem;
}

.app-datatable__search {
    min-width: 14rem;
    flex: 1 1 14rem;
    max-width: 22rem;
}

.app-datatable__sort-quick {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.app-datatable__toolbar-actions {
    margin-left: auto;
}

.app-datatable__chips {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.6rem;
}

.app-datatable__chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.25rem 0.4rem 0.25rem 0.65rem;
    border-radius: 999px;
    background: var(--brand-accent-soft, #eef6f6);
    color: var(--brand-text-main, #232323);
    font-size: 0.8rem;
}

.app-datatable__chip button {
    border: none;
    background: none;
    color: var(--brand-text-muted, #5d7a7a);
    cursor: pointer;
    font-size: 0.75rem;
    line-height: 1;
    padding: 0.15rem;
    border-radius: 50%;
}

.app-datatable__chip button:hover {
    background: color-mix(in srgb, var(--brand-text-main, #000) 10%, transparent);
    color: var(--brand-text-main, #232323);
}

.app-datatable__summary {
    margin-top: 0.5rem;
}

.app-datatable__popover {
    position: relative;
}

.app-datatable__popover-menu {
    position: absolute;
    z-index: 20;
    top: 100%;
    left: 0;
    margin: 0.25rem 0 0;
    padding: 0.75rem;
    min-width: 16rem;
    background: var(--brand-surface, #fff);
    border: 1px solid var(--brand-border, #d8e8e8);
    border-radius: var(--brand-radius, 0.5rem);
    box-shadow: 0 4px 16px rgba(16, 24, 40, 0.12);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.app-datatable__sort-level {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.app-datatable__sort-builder-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.app-datatable__views-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.app-datatable__views-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.4rem;
}

.app-datatable__views-list li > button:first-child {
    flex: 1;
    text-align: left;
    padding: 0.4rem 0.5rem;
    border: none;
    background: none;
    border-radius: var(--brand-radius, 0.4rem);
    font-size: 0.85rem;
    color: var(--brand-text-main, #232323);
    cursor: pointer;
}

.app-datatable__views-list li > button:first-child:hover {
    background: var(--brand-accent-soft, #eef6f6);
}

.app-datatable__views-delete {
    border: none;
    background: none;
    color: var(--brand-text-muted, #5d7a7a);
    cursor: pointer;
    padding: 0.2rem 0.4rem;
    border-radius: var(--brand-radius, 0.3rem);
}

.app-datatable__views-delete:hover {
    background: color-mix(in srgb, #ef4444 12%, transparent);
    color: #b91c1c;
}

.app-datatable__save-view-form {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--brand-border, #d8e8e8);
}

.app-datatable__filter-panel {
    margin-top: 0.5rem;
    padding: 0.75rem;
    background: var(--brand-surface, #fff);
    border: 1px solid var(--brand-border, #d8e8e8);
    border-radius: var(--brand-radius, 0.5rem);
}

/* Below this width the table degrades to one card per row (label/value pairs from each cell's
   data-label) instead of a horizontally-scrolled table - matches the .app-table legacy pattern
   this component is meant to replace, since most admin tables here run 3-6 columns where
   stacking reads better than scrolling. */
@media (max-width: 720px) {
    .app-datatable thead {
        display: none;
    }

    .app-datatable, .app-datatable tbody, .app-datatable tr, .app-datatable td {
        display: block;
        width: 100%;
    }

    .app-datatable tbody tr {
        background: var(--brand-surface, #fff);
        border: 1px solid var(--brand-border, #d8e8e8);
        border-radius: var(--brand-radius, 0.9rem);
        padding: 0.85rem 1rem;
        margin-bottom: 0.75rem;
    }

    .app-datatable tbody tr:hover {
        background: var(--brand-surface, #fff);
    }

    .app-datatable td {
        padding: 0.3rem 0;
        border-bottom: none;
        white-space: normal;
    }

    .app-datatable td[data-label]::before {
        content: attr(data-label);
        display: block;
        font-size: 0.68rem;
        text-transform: uppercase;
        letter-spacing: 0.05em;
        color: var(--brand-text-muted, #5d7a7a);
        margin-bottom: 0.15rem;
    }

    .app-datatable__row-actions {
        justify-content: flex-start;
    }

    .app-datatable__error {
        padding-top: 0.3rem;
    }
}

/* ---- Bulk actions toolbar ---- */

.app-bulk-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.75rem;
    padding: 0.6rem 1rem;
    background: var(--brand-accent-soft, #eef6f6);
    border: 1px solid var(--brand-border, #d8e8e8);
    border-radius: var(--brand-radius, 0.6rem);
    margin-bottom: 1rem;
}

.app-bulk-toolbar__count {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--brand-text-main, #232323);
}

.app-bulk-toolbar__actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

/* ---- Stepper ---- */

.app-stepper {
    display: flex;
    align-items: center;
    list-style: none;
    margin: 0;
    padding: 0;
}

.app-stepper__step {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 1;
    position: relative;
}

.app-stepper__step:not(:last-child)::after {
    content: "";
    flex: 1;
    height: 2px;
    margin: 0 0.5rem;
    background: var(--brand-border, #d8e8e8);
}

.app-stepper__step--done:not(:last-child)::after {
    background: var(--brand-primary, #185354);
}

.app-stepper__marker {
    flex: none;
    display: grid;
    place-content: center;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    font-size: 0.8rem;
    font-weight: 700;
    background: var(--brand-border, #d8e8e8);
    color: var(--brand-text-muted, #5d7a7a);
}

.app-stepper__step--done .app-stepper__marker {
    background: var(--brand-primary, #185354);
    color: var(--brand-primary-contrast, #fff);
}

.app-stepper__step--current .app-stepper__marker {
    background: var(--brand-surface, #fff);
    border: 2px solid var(--brand-primary, #185354);
    color: var(--brand-primary, #185354);
}

.app-stepper__step--error .app-stepper__marker {
    background: #b91c1c;
    color: #fff;
}

.app-stepper__label {
    font-size: 0.82rem;
    color: var(--brand-text-main, #232323);
    white-space: nowrap;
}

.app-stepper__step--upcoming .app-stepper__label {
    color: var(--brand-text-muted, #5d7a7a);
}

@media (max-width: 640px) {
    .app-stepper__label {
        display: none;
    }
}

/* ---- Requirements list ---- */

.app-requirements {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.app-requirements__item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--brand-border, #d8e8e8);
    border-radius: var(--brand-radius, 0.5rem);
}

.app-requirements__icon {
    flex: none;
    font-size: 0.9rem;
    color: var(--brand-text-muted, #93a5a5);
}

.app-requirements__item--done .app-requirements__icon {
    color: #16a34a;
}

.app-requirements__label {
    flex: 1;
    min-width: 0;
    font-size: 0.88rem;
    color: var(--brand-text-main, #232323);
}

.app-requirements__item--done .app-requirements__label {
    color: var(--brand-text-muted, #5d7a7a);
    text-decoration: line-through;
}

/* ---- Document viewer ---- */

.app-document-viewer {
    width: 100%;
    min-height: 24rem;
    border: 1px solid var(--brand-border, #d8e8e8);
    border-radius: var(--brand-radius, 0.6rem);
}

.app-document-viewer--fallback {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 1.5rem;
    min-height: auto;
    color: var(--brand-text-main, #232323);
}

/* ---- Currency input ---- */

.app-currency-input {
    position: relative;
}

.app-currency-input .app-field__input {
    padding-right: 2.75rem;
}

.app-currency-input__suffix {
    position: absolute;
    right: 0.7rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.85rem;
    color: var(--brand-text-muted, #5d7a7a);
    pointer-events: none;
}

/* ---- File upload ---- */

.app-file-upload__input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    overflow: hidden;
}

.app-file-upload__dropzone {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    padding: 1.5rem;
    border: 2px dashed var(--brand-border, #cbd5e1);
    border-radius: var(--brand-radius, 0.6rem);
    color: var(--brand-text-muted, #5d7a7a);
    font-size: 0.85rem;
    text-align: center;
    cursor: pointer;
}

.app-file-upload__input:focus-visible + .app-file-upload__dropzone {
    outline: 2px solid var(--brand-primary, #185354);
    outline-offset: 2px;
}

.app-file-upload__dropzone:hover {
    border-color: var(--brand-primary, #185354);
    color: var(--brand-text-main, #232323);
}

.app-file-upload__icon {
    font-size: 1.3rem;
}

.app-file-upload__list {
    margin: 0.5rem 0 0;
    padding-left: 1.2rem;
    font-size: 0.85rem;
    color: var(--brand-text-main, #232323);
}

/* ---- User picker ---- */

.app-user-picker {
    position: relative;
}

.app-user-picker__results {
    position: absolute;
    z-index: 10;
    top: 100%;
    left: 0;
    right: 0;
    margin: 0.25rem 0 0;
    padding: 0.25rem;
    list-style: none;
    background: var(--brand-surface, #fff);
    border: 1px solid var(--brand-border, #d8e8e8);
    border-radius: var(--brand-radius, 0.5rem);
    box-shadow: 0 4px 16px rgba(16, 24, 40, 0.12);
    max-height: 16rem;
    overflow-y: auto;
}

.app-user-picker__result {
    display: flex;
    flex-direction: column;
    width: 100%;
    text-align: left;
    padding: 0.5rem 0.6rem;
    border: none;
    background: none;
    border-radius: var(--brand-radius, 0.4rem);
    cursor: pointer;
}

.app-user-picker__result:hover {
    background: var(--brand-accent-soft, #eef6f6);
}

.app-user-picker__name {
    font-size: 0.88rem;
    color: var(--brand-text-main, #232323);
}

.app-user-picker__subtitle {
    font-size: 0.75rem;
    color: var(--brand-text-muted, #5d7a7a);
}

.app-user-picker__selected {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--brand-border, #d8e8e8);
    border-radius: var(--brand-radius, 0.5rem);
    font-size: 0.88rem;
}

.app-user-picker__clear {
    border: none;
    background: none;
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    color: var(--brand-text-muted, #5d7a7a);
    padding: 0;
}

.app-user-picker__clear:hover {
    color: var(--brand-text-main, #232323);
}

/* ---- Filter bar ---- */

.app-filter-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.app-filter-bar__search {
    flex: 1;
    min-width: 12rem;
}

.app-filter-bar__filters {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

/* ---- Advanced filters ---- */

.app-advanced-filters {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.app-advanced-filters__logic {
    max-width: 16rem;
}

.app-advanced-filters__row {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr auto;
    gap: 0.5rem;
    align-items: start;
}

@media (max-width: 640px) {
    .app-advanced-filters__row {
        grid-template-columns: 1fr;
    }
}

/* ---- Radio group ---- */

.app-radio-group {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.app-radio-group__label {
    margin: 0;
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--brand-text-muted, #5d7a7a);
}

.app-radio {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.9rem;
    color: var(--brand-text-main, #232323);
    cursor: pointer;
}

.app-radio input[type="radio"] {
    accent-color: var(--brand-primary, #185354);
    width: 1.05rem;
    height: 1.05rem;
    cursor: pointer;
}

/* ---- Form section ---- */

.app-form-section {
    margin-bottom: 1.5rem;
}

.app-form-section__title {
    font-family: var(--brand-font-serif, 'Libre Baskerville', Georgia, serif);
    font-size: 1.1rem;
    font-weight: 400;
    margin: 0 0 0.25rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--brand-border, #d8e8e8);
}

.app-form-section__description {
    font-size: 0.85rem;
    color: var(--brand-text-muted, #5d7a7a);
    margin: 0 0 0.75rem;
}

.app-form-section__body {
    margin-top: 0.75rem;
}

/* ---- Page header ---- */

.app-page-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.app-page-header__title {
    font-family: var(--brand-font-serif, 'Libre Baskerville', Georgia, serif);
    font-size: 1.75rem;
    font-weight: 400;
    margin: 0;
    color: var(--brand-text-main, #232323);
}

.app-page-header__subtitle {
    margin: 0.25rem 0 0;
    font-size: 0.9rem;
    color: var(--brand-text-muted, #5d7a7a);
}

.app-page-header__actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

/* ---- Pagination ---- */

.app-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1rem;
}

.app-pagination__info {
    font-size: 0.85rem;
    color: var(--brand-text-muted, #5d7a7a);
    font-variant-numeric: tabular-nums;
}

/* ---- Progress indicator ---- */

.app-progress {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.app-progress__label {
    display: flex;
    justify-content: space-between;
    font-size: 0.8rem;
    color: var(--brand-text-muted, #5d7a7a);
}

.app-progress__track {
    height: 0.5rem;
    border-radius: 999px;
    background: var(--brand-border, #d8e8e8);
    overflow: hidden;
}

.app-progress__fill {
    height: 100%;
    border-radius: 999px;
    background: var(--brand-primary, #185354);
    transition: width 0.2s ease;
}

@media (prefers-reduced-motion: reduce) {
    .app-progress__fill { transition: none; }
}

/* ---- Action dropdown ---- */

.app-action-dropdown {
    position: relative;
    display: inline-block;
}

.app-action-dropdown__trigger {
    border: 1px solid transparent;
    background: none;
    font-size: 1.1rem;
    line-height: 1;
    padding: 0.3rem 0.6rem;
    border-radius: var(--brand-radius, 0.4rem);
    cursor: pointer;
    color: var(--brand-text-muted, #5d7a7a);
}

.app-action-dropdown__trigger:hover {
    background: var(--brand-accent-soft, #eef6f6);
    color: var(--brand-text-main, #232323);
}

.app-action-dropdown__menu {
    position: absolute;
    z-index: 10;
    top: 100%;
    right: 0;
    margin: 0.25rem 0 0;
    padding: 0.25rem;
    list-style: none;
    min-width: 10rem;
    background: var(--brand-surface, #fff);
    border: 1px solid var(--brand-border, #d8e8e8);
    border-radius: var(--brand-radius, 0.5rem);
    box-shadow: 0 4px 16px rgba(16, 24, 40, 0.12);
}

.app-action-dropdown__item {
    display: block;
    width: 100%;
    text-align: left;
    padding: 0.45rem 0.6rem;
    border: none;
    background: none;
    border-radius: var(--brand-radius, 0.4rem);
    font-size: 0.85rem;
    color: var(--brand-text-main, #232323);
    cursor: pointer;
}

.app-action-dropdown__item:hover {
    background: var(--brand-accent-soft, #eef6f6);
}

/* ---- Quick filters ---- */

.app-quick-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.app-quick-filter {
    border: 1px solid var(--brand-border, #d8e8e8);
    background: var(--brand-surface, #fff);
    color: var(--brand-text-main, #232323);
    font-size: 0.82rem;
    padding: 0.35rem 0.8rem;
    border-radius: 999px;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.app-quick-filter:hover {
    border-color: var(--brand-primary, #185354);
}

.app-quick-filter--active {
    background: var(--brand-primary, #185354);
    border-color: var(--brand-primary, #185354);
    color: var(--brand-primary-contrast, #fff);
}

/* ---- Toast ---- */

.app-toast {
    --app-toast-accent: var(--brand-primary, #185354);

    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    max-width: 22rem;
    padding: 0.75rem 1rem;
    border-radius: var(--brand-radius, 0.6rem);
    border-left: 4px solid var(--app-toast-accent);
    background: var(--brand-surface, #fff);
    box-shadow: 0 8px 24px rgba(16, 24, 40, 0.18);
    color: var(--brand-text-main, #232323);
}

.app-toast--good { --app-toast-accent: #16a34a; }
.app-toast--warn { --app-toast-accent: #a16207; }
.app-toast--bad { --app-toast-accent: #b91c1c; }
.app-toast--info { --app-toast-accent: var(--brand-primary, #185354); }
.app-toast--neutral { --app-toast-accent: var(--brand-border, #93a5a5); }

.app-toast__body {
    flex: 1;
    min-width: 0;
    font-size: 0.88rem;
}

.app-toast__close {
    flex: none;
    border: none;
    background: none;
    color: inherit;
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    padding: 0;
    opacity: 0.6;
}

.app-toast__close:hover {
    opacity: 1;
}

/* A caller showing several Toasts at once wraps them in this - fixed to a screen corner, stacked
   with a gap. Not applied by Toast.razor itself, since one Toast alone has no stacking to do. */
.app-toast-host {
    position: fixed;
    bottom: 1.5rem;
    right: 1.5rem;
    z-index: 1000;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

/* ---- Signature status ---- */

.app-signature-status {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--brand-border, #d8e8e8);
    border-radius: var(--brand-radius, 0.5rem);
    color: inherit;
    text-decoration: none;
}

.app-signature-status--linked {
    cursor: pointer;
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

.app-signature-status--linked:hover {
    border-color: var(--brand-primary, #185354);
    background: var(--brand-accent-soft, #eef6f6);
}

.app-signature-status__body {
    min-width: 0;
}

.app-signature-status__label {
    margin: 0;
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--brand-text-main, #232323);
}

.app-signature-status__detail {
    margin: 0.1rem 0 0;
    font-size: 0.78rem;
    color: var(--brand-text-muted, #5d7a7a);
}

.app-signature-status__signers {
    list-style: none;
    margin: 0.15rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.app-signature-status__signer {
    font-size: 0.78rem;
    color: var(--brand-text-main, #232323);
    display: flex;
    align-items: baseline;
    gap: 0.35rem;
}

.app-signature-status__signer--pending {
    color: var(--brand-text-muted, #5d7a7a);
}

.app-signature-status__signer-date {
    font-size: 0.72rem;
    color: var(--brand-text-muted, #5d7a7a);
    font-variant-numeric: tabular-nums;
}

/* ---- Validation summary ---- */
/* Styling only for Blazor's own built-in <ValidationSummary> - no wrapper component needed since
   it already owns the validation logic; this class just makes it match the rest of the library
   instead of Bootstrap's default red-list look. Apply via class="app-validation-summary". */
.app-validation-summary {
    display: block;
    padding: 0.75rem 1rem;
    border: 1px solid #b91c1c;
    border-radius: var(--brand-radius, 0.6rem);
    background: color-mix(in srgb, #b91c1c 8%, var(--brand-surface, #fff));
    color: var(--brand-text-main, #232323);
    font-size: 0.85rem;
}

.app-validation-summary ul {
    margin: 0;
    padding-left: 1.1rem;
}

/* ---- Navbar preview ---- */
/* InuniNav.razor is a real top-of-page header, not a positioned element (no fixed/sticky in its
   own CSS) - inside the boxed, padded .complib-preview/preview-window it read as broken (squeezed
   into a bordered card instead of a real navbar). This wrapper fixes it to the very top of the
   viewport, full width, so it actually hovers over the page the way it does in production. */
.app-navbar-preview {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1000;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
}
