﻿/*
 * BrandSync Component Styles — Membercare.SelfService.Web
 *
 * Uses semantic tokens defined in Variables.css and ConfiguredVariables.css.
 * Customer CSS provides the actual color values — never hardcode hex here.
 *
 * Token layers:
 *   ConfiguredVariables.css  → defines --color-* semantic tokens
 *   This file                → BEM class names consume those tokens
 */

/*
 * File organisation (multi-consumer CSS only — single-consumer CSS lives in the
 * owning component's scoped .razor.css; promote here on the second consumer):
 *   1. Utilities            — single-purpose helper classes
 *   2. Component library    — Bs* component styles
 *   3. Dashboard framework  — shared chassis for dashboard pages and modules
 *   4. Cross-component overrides — rules that must stay global because they
 *      target other components' internals
 *   5. Pages                — page-level shared styles
 */

/* ################################################################
   1. UTILITIES
   ################################################################ */

/* ============================================================
   Content width cap (bs-content-container)
   Single source of truth for the max content width used to keep
   page content readable on wide screens. Apply .bs-content-container
   to any top-level flow/page container that should be capped and
   centred (e.g. the dashboard rows, the enrollment flow root).
   Below the cap the container stays full-width; margin-inline:auto
   only centres once the viewport exceeds --bs-content-max-width.
   ============================================================ */

:root {
    --bs-content-max-width: 1280px;
}

.bs-content-container {
    max-width: var(--bs-content-max-width);
    margin-inline: auto;
}

/* ============================================================
   Screen-reader-only utility (sr-only)
   Visually hides content while keeping it in the accessibility tree,
   for labels announced to screen readers (e.g. BsBadge / BsChip
   AriaLabel). Bootstrap 5 renamed its own helper to .visually-hidden,
   so this project defines .sr-only globally as the shared utility.
   ============================================================ */

.sr-only {
    position: absolute;
    width: 0.0625rem;
    height: 0.0625rem;
    padding: 0;
    margin: -0.0625rem;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ============================================================
   Touch-target utility (.bs-tap-target)
   BrandSync requires interactive elements to offer a tap area of
   at least 44x44px (2.75rem) with >=8px spacing on this
   mobile-first portal. Apply to small text/icon buttons (btn-link,
   icon-only remove buttons, breadcrumb links) whose content would
   otherwise collapse below that. Composes with any display/layout
   utilities — it only enforces the minimum hit area.
   ============================================================ */
.bs-tap-target {
    min-height: 2.75rem;
    min-width: 2.75rem;
}

/* ============================================================
   Pill surface utility (.bs-pill)
   Shared rounded "pill" surface: a lightly primary-tinted chip shape used for
   compact, secondary information (e.g. the enrollment subtotal pill and the
   companion chips). Consumers add their own content layout, typography and any
   interactive children on top of this surface.
   WCAG pair: place --color-primary-default / --color-neutrals-pressed text on
   the --color-primary-container background.
   ============================================================ */
.bs-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    max-width: 100%;
    padding: 4px 12px;
    border: 1px solid var(--color-primary-container-hover);
    border-radius: 100px;
    background: var(--color-primary-container);
}

/* ============================================================
   Shared text utilities (.bs-heading-sm / .bs-body-text-muted)
   Promoted from the enrollment-flow step components (MEM-8246), where the
   identical rules were duplicated across several scoped stylesheets.
   ============================================================ */

/* Small step/section heading (heading-sm scale). Margin reset so it can sit on
   any <h1>–<h6> element without UA margins breaking the flex-gap rhythm.
   WCAG pair: --color-neutrals-pressed text on the page / card background. */
.bs-heading-sm {
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-heading-sm-size, 24px);
    line-height: var(--font-heading-sm-line-height, 32px);
    font-weight: 600;
    color: var(--color-neutrals-pressed);
    margin: 0;
}

/* Muted body text for empty states, hints and secondary notices.
   WCAG pair: --color-neutrals-hover text on the page / card background. */
.bs-body-text-muted {
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-body-md-regular-size, 16px);
    line-height: var(--font-body-md-regular-line-height, 24px);
    color: var(--color-neutrals-hover);
    margin: 0;
}

/* Quiet inline marker for a secondary fact about an item — "Obligatorisk" on a service,
   hotel room or session. Deliberately not a badge: the fact is worth stating but should not
   compete with the item name for attention.
   WCAG pair: --color-neutrals-hover text on the page / card background. */
.bs-item-meta {
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-caption-md-size, 14px);
    line-height: var(--font-caption-md-line-height, 20px);
    font-weight: 400;
    color: var(--color-neutrals-hover);
}

/* ============================================================
   Fieldset utility (.bs-fieldset / .bs-fieldset__legend)
   A bordered group whose label sits as a legend on the top border; the surface background shows
   through behind the label to cut the border line. Shared by the Interests group and the
   custom-fields group (whose markup comes from the shared BsSelectCustomFields component, so its
   classes are hooked in here rather than by editing that markup). Consumers add their own
   padding/typography.
   ============================================================ */
.bs-fieldset,
.custom-fields-detail-module div.bs-select-custom-fields__group {
    position: relative;
    border: 1px solid var(--color-primary-default);
    border-radius: 8px;
}

/* WCAG pair: --color-primary-default text on --color-neutrals-container (surface) background.
   max-width keeps a long legend inside the box (no horizontal overflow on narrow viewports). */
.bs-fieldset__legend,
.custom-fields-detail-module div.bs-select-custom-fields__group-header {
    position: absolute;
    top: -12px;
    left: 12px;
    z-index: 1;
    max-width: calc(100% - 24px);
    padding: 0 8px;
    background-color: var(--color-neutrals-container);
    color: var(--color-primary-default);
    font-family: var(--font-family, Roboto, sans-serif);
    /* Keep a long legend on one line and inside the box (no horizontal overflow on mobile).
       white-space inherits to a nested title element; text-overflow needs to sit on whichever
       element directly holds the text (the span here; the <h3> for the custom-fields variant). */
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}


/* ################################################################
   2. COMPONENT LIBRARY
   ################################################################ */

/* ============================================================
   Shared input element styles (bs-input__*)
   Used by BsInputText, BsInputTextArea, etc.
   Each component owns only its wrapper class (e.g. .bs-input-text).
   ============================================================ */

/* Shared layout wrapper for all input components */
.bs-input {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* Component-specific wrappers — add overrides here as needed */
.bs-input-text { }

.bs-input-email { }

.bs-input-cellphone { }

.bs-input-password { }

.bs-input-date { }

.bs-input-number { }

.bs-input-textarea { }

.bs-input-file { }

.bs-input-textarea .bs-input__control {
    resize: vertical;
    min-height: 80px;
}

/* ============================================================
   BsInputFile (bs-input-file)
   Drop zone wrapper for <input type="file">. The native input is
   positioned absolutely over the zone so the whole area is clickable.
   ============================================================ */

.bs-input-file__dropzone {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 24px 16px;
    border: 2px dashed var(--color-neutrals-hover);
    border-radius: 4px;
    background-color: var(--color-neutrals-container);
    cursor: pointer;
    text-align: center;
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

.bs-input-file__dropzone:hover {
    border-color: var(--color-primary-focused);
    background-color: var(--color-primary-container);
}

.bs-input-file__dropzone:has(.bs-input-file__native:focus-visible) {
    border-color: var(--color-primary-focused);
    background-color: var(--color-primary-container);
    outline: 2px solid var(--color-primary-focused);
    outline-offset: 2px;
}

/* WCAG pair: --color-error-default border on --color-neutrals-container background */
.bs-input--error .bs-input-file__dropzone {
    border-color: var(--color-error-default);
    box-shadow: 0 0 0 3px var(--color-error-container);
}

.bs-input-file__dropzone:has(.bs-input-file__native:disabled) {
    background-color: var(--color-neutrals-container-hover);
    border-color: var(--color-neutrals-hover);
    cursor: not-allowed;
}

.bs-input-file__icon {
    font-size: 24px;
    color: var(--color-primary-default);
}

.bs-input-file__prompt {
    font-family: var(--font-family, Roboto, sans-serif);
    font-weight: 400;
    font-size: var(--font-body-md-regular-size, 16px);
    line-height: var(--font-body-md-regular-line-height, 24px);
    color: var(--color-neutrals-hover);
}

.bs-input-file__selected {
    font-family: var(--font-family, Roboto, sans-serif);
    font-weight: 500;
    font-size: var(--font-body-md-regular-size, 16px);
    line-height: var(--font-body-md-regular-line-height, 24px);
    color: var(--color-neutrals-default);
}

.bs-input-file__native {
    opacity: 0;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    cursor: pointer;
}

.bs-input-file__native:disabled {
    cursor: not-allowed;
}

.bs-input__label {
    font-family: var(--font-family, Roboto, sans-serif);
    font-weight: 500;
    font-size: var(--font-caption-lg-size, 16px);
    line-height: var(--font-caption-lg-line-height, 24px);
    color: var(--color-neutrals-default);
}

/* Optional BsIcon hint before the label text (BsInputText/BsMultiSelect's LabelIcon fragment).
   8px gap matches the icon-text spacing already used elsewhere (e.g. .bs-card-detail-row). */
.bs-input__label .bs-icon {
    margin-right: 8px;
    color: var(--color-neutrals-hover);
}

.bs-input__required,
.bs-checkbox__required {
    color: var(--color-error-default);
    margin-left: 2px;
}

.bs-input__control {
    font-family: var(--font-family, Roboto, sans-serif);
    font-weight: 400;
    font-size: var(--font-body-md-regular-size, 16px);
    line-height: var(--font-body-md-regular-line-height, 24px);
    padding: 8px 12px;
    border: 1px solid var(--color-neutrals-hover);
    border-radius: 4px;
    background-color: var(--color-neutrals-container);
    color: var(--color-neutrals-default);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
    width: 100%;
    box-sizing: border-box;
}

.bs-input__control::placeholder {
    font-weight: 400;
    color: var(--color-neutrals-hover);
}

.bs-input__control:focus-visible {
    border-color: var(--color-primary-focused);
    outline: 2px solid var(--color-primary-focused);
    outline-offset: 2px;
}

.bs-input__control:disabled {
    background-color: var(--color-neutrals-container-hover);
    color: var(--color-neutrals-hover);
    border-color: var(--color-neutrals-hover);
    cursor: not-allowed;
}

.bs-input__control[readonly] {
    background-color: color-mix(in srgb, var(--color-neutrals-container-focused) 25%, var(--color-page-background));
    color: var(--color-neutrals-focused);
    border-color: var(--color-neutrals-hover);
}

/* WCAG pair: --color-neutrals-default text on --color-neutrals-container background */
.bs-input--error .bs-input__control {
    border-color: var(--color-error-default);
    box-shadow: 0 0 0 3px var(--color-error-container);
}

.bs-input--error .bs-input__control:focus-visible {
    border-color: var(--color-error-default);
    outline: 2px solid var(--color-error-default);
    outline-offset: 2px;
    box-shadow: 0 0 0 3px var(--color-error-container);
}

.bs-input__feedback {
    font-family: var(--font-family, Roboto, sans-serif);
    font-weight: 400;
    font-size: var(--font-caption-md-size, 14px);
    line-height: var(--font-caption-md-line-height, 20px);
    color: var(--color-neutrals-hover);
}

/* WCAG pair: --color-error-default on --color-neutrals-container background */
.bs-input__feedback--error {
    color: var(--color-error-default);
}

/* ============================================================
   BsCheckBox (bs-checkbox)
   ============================================================ */

.bs-checkbox {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.bs-checkbox__field {
    display: flex;
    align-items: flex-start;
    gap: 8px;
}

/* Nudge the box onto the label's first line ((24px line box - 16px control) / 2), so a wrapping
   label keeps it pinned there instead of centring on the whole block. Scoped to BsCheckBox's own
   markup: .bs-checkbox__field is also borrowed by HotelRoomCard and .bs-checkbox__control by
   BsCheckBoxList, both of which centre a single-line row and must not get the offset. */
.bs-checkbox > .bs-checkbox__field > .bs-checkbox__control {
    margin-top: 0.25rem;
}

.bs-checkbox__control {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    accent-color: var(--color-primary-default);
    cursor: pointer;
    transition: outline 0.15s ease, outline-offset 0.15s ease;
}

.bs-checkbox__control:hover:not(:disabled) {
    outline: 2px solid var(--color-primary-container);
    outline-offset: 2px;
}

.bs-checkbox__control:focus-visible {
    outline: 2px solid var(--color-primary-focused);
    outline-offset: 2px;
}

.bs-checkbox__control:disabled {
    cursor: not-allowed;
    opacity: 0.5;
}

.bs-checkbox__control:checked:disabled {
    opacity: 0.5;
    accent-color: var(--color-neutrals-hover);
}

.bs-checkbox__label {
    font-family: var(--font-family, Roboto, sans-serif);
    font-weight: 400;
    font-size: var(--font-body-md-regular-size, 16px);
    line-height: var(--font-body-md-regular-line-height, 24px);
    color: var(--color-neutrals-default);
    cursor: pointer;
}

.bs-checkbox:has(.bs-checkbox__control:disabled) .bs-checkbox__label {
    cursor: not-allowed;
}

/* Opt-in for a checkbox standing on its own in the page flow (terms, consent declarations). Not on
   .bs-checkbox itself — that would shift every checkbox already laid out by its container. */
.bs-checkbox--spaced {
    margin-block: 1rem;
}

.bs-checkbox--error .bs-checkbox__control {
    outline: 2px solid var(--color-error-default);
    outline-offset: 2px;
}

.bs-checkbox--error .bs-checkbox__control:focus-visible {
    outline: 2px solid var(--color-error-default);
    outline-offset: 2px;
}

.bs-checkbox__feedback {
    font-family: var(--font-family, Roboto, sans-serif);
    font-weight: 400;
    font-size: var(--font-caption-md-size, 14px);
    line-height: var(--font-caption-md-line-height, 20px);
    color: var(--color-neutrals-hover);
    padding-left: 24px;
}

/* WCAG pair: --color-error-default on --color-neutrals-container background */
.bs-checkbox__feedback--error {
    color: var(--color-error-default);
}

/* ============================================================
   BsButton (bs-button)
   ============================================================ */

.bs-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.375rem 0.75rem;
    font-family: var(--font-family, Roboto, sans-serif);
    font-weight: 500;
    font-size: var(--font-body-md-regular-size, 1rem);
    line-height: var(--font-body-md-regular-line-height, 1.5rem);
    border-radius: 0.375rem;
    border: 1px solid transparent;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
    white-space: nowrap;
    user-select: none;
    text-decoration: none;
}

.bs-button:disabled,
.bs-button--loading {
    cursor: not-allowed;
    opacity: 0.5;
}

/* Size modifiers */
.bs-button--small {
    padding: 0.25rem 0.5rem;
    font-size: var(--font-body-md-regular-size, 1rem);
    line-height: var(--font-body-md-regular-line-height, 1.5rem);
}

.bs-button--large {
    padding: 0.75rem 1.5rem;
    font-size: var(--font-body-lg-size, 1.125rem);
    line-height: var(--font-body-lg-line-height, 1.75rem);
}

/* Primary */
.bs-button--primary {
    background-color: var(--color-primary-default);
    color: var(--color-neutrals-container);
    border-color: var(--color-primary-default);
}

.bs-button--primary:hover:not(:disabled) {
    background-color: var(--color-primary-hover);
    border-color: var(--color-primary-hover);
}

.bs-button--primary:focus-visible {
    outline: 2px solid var(--color-primary-focused);
    outline-offset: 2px;
}

.bs-button--primary:active:not(:disabled) {
    background-color: var(--color-primary-pressed);
    border-color: var(--color-primary-pressed);
}

/* Neutral */
.bs-button--neutral {
    background-color: var(--color-neutrals-container-hover);
    color: var(--color-neutrals-default);
    border-color: var(--color-neutrals-container-hover);
}

.bs-button--neutral:hover:not(:disabled) {
    background-color: var(--color-neutrals-container-pressed);
    border-color: var(--color-neutrals-container-pressed);
}

.bs-button--neutral:focus-visible {
    outline: 2px solid var(--color-primary-focused);
    outline-offset: 2px;
}

.bs-button--neutral:active:not(:disabled) {
    background-color: var(--color-neutrals-pressed);
    color: var(--color-neutrals-container);
    border-color: var(--color-neutrals-pressed);
}

/* Outlined */
.bs-button--outlined {
    background-color: transparent;
    color: var(--color-primary-default);
    border-color: var(--color-primary-default);
}

.bs-button--outlined:hover:not(:disabled) {
    background-color: var(--color-primary-container);
}

.bs-button--outlined:focus-visible {
    outline: 2px solid var(--color-primary-focused);
    outline-offset: 2px;
}

.bs-button--outlined:active:not(:disabled) {
    background-color: var(--color-primary-container-hover);
}

/* Subtle */
.bs-button--subtle {
    background-color: transparent;
    color: var(--color-primary-default);
    border-color: transparent;
}

.bs-button--subtle:hover:not(:disabled) {
    background-color: var(--color-primary-container);
}

.bs-button--subtle:focus-visible {
    outline: 2px solid var(--color-primary-focused);
    outline-offset: 2px;
}

.bs-button--subtle:active:not(:disabled) {
    background-color: var(--color-primary-container-hover);
}

/* Success */
.bs-button--success {
    background-color: var(--color-success-default);
    color: var(--color-neutrals-container);
    border-color: var(--color-success-default);
}

.bs-button--success:hover:not(:disabled) {
    filter: brightness(0.9);
}

.bs-button--success:active:not(:disabled) {
    filter: brightness(0.8);
}

.bs-button--success:focus-visible {
    outline: 2px solid var(--color-success-default);
    outline-offset: 2px;
}

/* Warning */
.bs-button--warning {
    background-color: var(--color-warning-default);
    color: var(--color-neutrals-container);
    border-color: var(--color-warning-default);
}

.bs-button--warning:hover:not(:disabled) {
    background-color: var(--color-warning-hover);
    border-color: var(--color-warning-hover);
}

.bs-button--warning:active:not(:disabled) {
    background-color: var(--color-warning-pressed);
    border-color: var(--color-warning-pressed);
}

.bs-button--warning:focus-visible {
    outline: 2px solid var(--color-warning-default);
    outline-offset: 2px;
}

/* Error */
.bs-button--error {
    background-color: var(--color-error-default);
    color: var(--color-neutrals-container);
    border-color: var(--color-error-default);
}

.bs-button--error:hover:not(:disabled) {
    filter: brightness(0.9);
}

.bs-button--error:active:not(:disabled) {
    filter: brightness(0.8);
}

.bs-button--error:focus-visible {
    outline: 2px solid var(--color-error-default);
    outline-offset: 2px;
}

/* Loading spinner */
.bs-button__spinner {
    width: 1rem;
    height: 1rem;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: bs-button-spin 0.6s linear infinite;
    flex-shrink: 0;
}

@keyframes bs-button-spin {
    to { transform: rotate(360deg); }
}

/* ============================================================
   BsCheckBoxList (bs-checkbox-list)
   ============================================================ */

.bs-checkbox-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.bs-checkbox-list__label {
    font-family: var(--font-family, Roboto, sans-serif);
    font-weight: 500;
    font-size: var(--font-caption-lg-size, 16px);
    line-height: var(--font-caption-lg-line-height, 24px);
    color: var(--color-neutrals-default);
}

.bs-checkbox-list__items {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.bs-checkbox-list__items--horizontal {
    flex-direction: row;
    flex-wrap: wrap;
}

.bs-checkbox-list__item {
    display: flex;
    align-items: center;
    gap: 8px;
}

.bs-checkbox-list__feedback {
    font-family: var(--font-family, Roboto, sans-serif);
    font-weight: 400;
    font-size: var(--font-caption-md-size, 14px);
    line-height: var(--font-caption-md-line-height, 21px);
    color: var(--color-neutrals-hover);
}

.bs-checkbox-list__feedback--error {
    color: var(--color-error-default);
}

/* Cross-block dependency: targets .bs-checkbox__control from the bs-checkbox block.
   If bs-checkbox element names change, update these selectors accordingly. */
.bs-checkbox-list--error .bs-checkbox__control {
    outline: 2px solid var(--color-error-default);
    outline-offset: 2px;
}

.bs-checkbox-list--error .bs-checkbox__control:focus-visible {
    outline: 2px solid var(--color-error-default);
    outline-offset: 2px;
}

.bs-checkbox-list__item:has(.bs-checkbox__control:disabled) .bs-checkbox__label {
    cursor: not-allowed;
}

/* ============================================================
   BsRadioGroup (bs-radio-group)
   ============================================================ */

.bs-radio-group {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.bs-radio-group__label {
    font-family: var(--font-family, Roboto, sans-serif);
    font-weight: 500;
    font-size: var(--font-caption-lg-size, 16px);
    line-height: var(--font-caption-lg-line-height, 24px);
    color: var(--color-neutrals-default);
}

/* Keeps the Label accessible to screen readers (via aria-labelledby) without showing
   it visually — for radio groups that act as a modifier on an adjacent labeled field. */
.bs-radio-group--label-visually-hidden .bs-radio-group__label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.bs-radio-group__items {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.bs-radio-group__items--horizontal {
    flex-direction: row;
    flex-wrap: wrap;
}

.bs-radio-group__item {
    display: flex;
    align-items: center;
    gap: 8px;
}

.bs-radio-group__feedback {
    font-family: var(--font-family, Roboto, sans-serif);
    font-weight: 400;
    font-size: var(--font-caption-md-size, 14px);
    line-height: var(--font-caption-md-line-height, 24px);
    color: var(--color-neutrals-hover);
}

.bs-radio-group__feedback--error {
    color: var(--color-error-default);
}

/* Cross-block dependency: targets .bs-radio__control from the bs-radio block.
   If bs-radio element names change, update these selectors accordingly. */
.bs-radio-group--error .bs-radio__control {
    outline: 2px solid var(--color-error-default);
    outline-offset: 2px;
}

.bs-radio-group--error .bs-radio__control:focus-visible {
    outline: 2px solid var(--color-error-default);
    outline-offset: 2px;
}

.bs-radio-group__item:has(.bs-radio__control:disabled) .bs-radio__label {
    cursor: not-allowed;
}

/* ============================================================
   BsRadio (bs-radio)
   Individual radio control — used inside BsRadioGroup.
   ============================================================ */

.bs-radio__control {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    accent-color: var(--color-primary-default);
    cursor: pointer;
    transition: outline 0.15s ease, outline-offset 0.15s ease;
}

.bs-radio__control:hover:not(:disabled) {
    outline: 2px solid var(--color-primary-container);
    outline-offset: 2px;
}

.bs-radio__control:focus-visible {
    outline: 2px solid var(--color-primary-focused);
    outline-offset: 2px;
}

.bs-radio__control:disabled {
    cursor: not-allowed;
    opacity: 0.5;
}

.bs-radio__control:checked:disabled {
    opacity: 0.5;
    accent-color: var(--color-neutrals-hover);
}

.bs-radio__label {
    font-family: var(--font-family, Roboto, sans-serif);
    font-weight: 400;
    font-size: var(--font-body-md-regular-size, 16px);
    line-height: var(--font-body-md-regular-line-height, 24px);
    color: var(--color-neutrals-default);
    cursor: pointer;
}

/* MEM-8581: multi-line ItemTemplate content (e.g. a category card with seats + price) needs the
   label to grow full-width and top-align with the radio input, instead of the single-line
   center-aligned default. Additive — only applies when ItemTemplate is set. */
.bs-radio-group__item:has(.bs-radio__label--template) {
    align-items: flex-start;
}

.bs-radio__label--template {
    display: block;
    width: 100%;
}

/* ============================================================
   BsRadioGroup — SelectionCard variant (bs-radio-group--selection-card)
   Opt-in. Every selector below is prefixed with the variant modifier so the
   default radio groups are untouched.
   The native input stays in the DOM (focusable, arrow-key navigable) but is
   visually hidden; the label becomes the full-width click target, and selection
   is conveyed by an accent border plus a check mark — never by colour alone.
   ============================================================ */

.bs-radio-group--selection-card .bs-radio-group__items {
    flex-direction: column;
    gap: 8px;
}

/* MEM-9133: mobile-first — the base rule above always keeps SelectionCard options stacked,
   regardless of BsRadioGroup's Direction parameter (its own bs-radio-group__items--horizontal rule
   has lower specificity than the selector above and would otherwise never win). From the tablet
   breakpoint up, a group that opted into Direction="Horizontal" lays its cards out side by side and
   wraps to further rows as needed — auto-fit sizes each card from the number of options actually
   present (1-6 categories) instead of a fixed column count, so 2 options split the row evenly and 6
   wrap across multiple rows without needing per-count markup. */
@media (min-width: 768px) {
    .bs-radio-group--selection-card .bs-radio-group__items--horizontal {
        flex-direction: row;
        flex-wrap: wrap;
    }

    .bs-radio-group--selection-card .bs-radio-group__items--horizontal .bs-radio-group__item--selection-card {
        flex: 1 1 12rem;
        max-width: 18rem;
    }
}

.bs-radio-group--selection-card .bs-radio-group__item--selection-card {
    display: block;
    position: relative;
}

/* Clipped rather than display:none/visibility:hidden — those remove the input from the
   tab order and break the browser's native arrow-key navigation within the group. */
.bs-radio-group--selection-card .bs-radio-group__item--selection-card .bs-radio__control {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    padding: 0;
    opacity: 0;
    pointer-events: none;
}

/* The base block paints hover/focus/error outlines on the control itself; on a 1px clipped
   element that renders as a stray dot, so the affordances move to the card below. */
.bs-radio-group--selection-card .bs-radio-group__item--selection-card .bs-radio__control,
.bs-radio-group--selection-card .bs-radio-group__item--selection-card .bs-radio__control:hover:not(:disabled),
.bs-radio-group--selection-card .bs-radio-group__item--selection-card .bs-radio__control:focus-visible {
    outline: none;
}

.bs-radio-group--selection-card .bs-radio__label--selection-card {
    display: block;
    width: 100%;
    position: relative;
    /* Inline-end padding reserves room for the check mark so long option text cannot run under it. */
    padding: 16px 48px 16px 16px;
    border: 1px solid var(--color-neutrals-container-hover);
    border-radius: 8px;
    background: var(--color-neutrals-container);
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}

.bs-radio-group--selection-card .bs-radio-group__item--selection-card:hover .bs-radio__label--selection-card {
    border-color: var(--color-primary-container);
}

.bs-radio-group--selection-card .bs-radio-group__item--selection-card:has(.bs-radio__control:focus-visible) .bs-radio__label--selection-card {
    outline: 2px solid var(--color-primary-focused);
    outline-offset: 2px;
}

/* Selected: heavier accent border (inset ring keeps the box size stable) + the check mark. */
.bs-radio-group--selection-card .bs-radio-group__item--selection-card:has(.bs-radio__control:checked) .bs-radio__label--selection-card {
    border-color: var(--color-primary-default);
    box-shadow: inset 0 0 0 1px var(--color-primary-default);
}

.bs-radio-group--selection-card .bs-radio-group__item--selection-card:has(.bs-radio__control:disabled) .bs-radio__label--selection-card {
    cursor: not-allowed;
    opacity: 0.5;
}

.bs-radio-group--selection-card.bs-radio-group--error .bs-radio__label--selection-card {
    border-color: var(--color-error-default);
}

.bs-radio-group--selection-card .bs-radio__check {
    position: absolute;
    top: 16px;
    right: 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    color: var(--color-primary-default);
}

.bs-radio-group--selection-card .bs-radio__check svg {
    width: 16px;
    height: 16px;
}

/* ============================================================
   BsSelect (bs-select)
   ============================================================ */

.bs-select { }

.bs-select .bs-select__control {
    font-family: var(--font-family, Roboto, sans-serif);
    font-weight: 400;
    font-size: var(--font-body-md-regular-size, 16px);
    line-height: var(--font-body-md-regular-line-height, 24px);
    border: 1px solid var(--color-neutrals-hover);
    border-radius: 4px;
    background-color: var(--color-neutrals-container);
    color: var(--color-neutrals-default);
    width: 100%;
    box-sizing: border-box;
}

.bs-select .bs-select__control .dxbl-text-edit-input {
    font-family: inherit;
    font-weight: inherit;
    font-size: inherit;
    line-height: inherit;
    color: inherit;
    background-color: transparent;
    padding: 8px 12px;
}

.bs-select .bs-select__control .dxbl-text-edit-input::placeholder {
    color: var(--color-neutrals-hover);
}

.bs-select .bs-select__control.dxbl-disabled {
    background-color: var(--color-neutrals-container-hover);
    border-color: var(--color-neutrals-hover);
    cursor: not-allowed;
}

.bs-select .bs-select__control.dxbl-disabled .dxbl-text-edit-input {
    color: var(--color-neutrals-hover);
    cursor: not-allowed;
}

.bs-select .bs-select__control:focus-within,
.bs-select .bs-select__control.dxbl-focused {
    border-color: var(--color-primary-focused);
    box-shadow: none;
}

.bs-input--error .bs-select__control {
    border-color: var(--color-error-default);
    box-shadow: 0 0 0 3px var(--color-error-container);
}

dxbl-dropdown-dialog.dxbl-edit-dropdown {
    background-color: var(--color-neutrals-container);
    border-color: var(--color-neutrals-container-pressed);
}

.dxbl-list-item.dxbl-list-item-selected {
    background-color: var(--color-primary-default);
    color: #fff;
}

.dxbl-list-item.dxbl-list-item-focused:not(.dxbl-list-item-selected) {
    background-color: var(--color-primary-container);
    color: var(--color-neutrals-default);
}

/* WCAG pair: --color-neutrals-default on --color-neutrals-container. */
dxbl-dropdown-dialog.dxbl-edit-dropdown .dxbl-listbox {
    background-color: var(--color-neutrals-container);
    color: var(--color-neutrals-default);
}

dxbl-dropdown-dialog.dxbl-edit-dropdown .dxbl-list-item {
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-body-md-regular-size, 1rem);
    line-height: var(--font-body-md-regular-line-height, 1.5rem);
    color: var(--color-neutrals-default);
    padding: 0.5rem 0.75rem;
}

dxbl-dropdown-dialog.dxbl-edit-dropdown .dxbl-list-item:hover:not(.dxbl-list-item-selected) {
    background-color: var(--color-neutrals-container-hover);
    color: var(--color-neutrals-default);
}

/* ============================================================
   BsMultiSelect (bs-multi-select)
   ============================================================ */

.bs-multi-select { }

.bs-multi-select .bs-multi-select__control {
    font-family: var(--font-family, Roboto, sans-serif);
    font-weight: 400;
    font-size: var(--font-body-md-regular-size, 1rem);
    line-height: var(--font-body-md-regular-line-height, 1.5rem);
    border: 1px solid var(--color-neutrals-hover);
    border-radius: 0.25rem;
    background-color: var(--color-neutrals-container);
    color: var(--color-neutrals-default);
    width: 100%;
    box-sizing: border-box;
    padding: 8px 12px;
    /* Matches .bs-input__control's implicit height (line-height + padding + border) so text
       inputs and the multiselect line up, without restating the sum as a magic number. */
    min-height: calc(var(--font-body-md-regular-line-height, 1.5rem) + 2 * 8px + 2 * 1px);
}

.bs-multi-select .bs-multi-select__control .dxbl-text-edit-input {
    font-family: inherit;
    font-weight: inherit;
    font-size: inherit;
    line-height: inherit;
    color: inherit;
    background-color: transparent;
    padding: 0;
}

.bs-multi-select .bs-multi-select__control .dxbl-text-edit-input::placeholder {
    color: var(--color-neutrals-hover);
}

.bs-multi-select .bs-multi-select__control.dxbl-disabled {
    background-color: var(--color-neutrals-container-hover);
    border-color: var(--color-neutrals-hover);
    cursor: not-allowed;
}

.bs-multi-select .bs-multi-select__control.dxbl-disabled .dxbl-text-edit-input {
    color: var(--color-neutrals-hover);
    cursor: not-allowed;
}

.bs-multi-select .bs-multi-select__control:focus-within,
.bs-multi-select .bs-multi-select__control.dxbl-focused {
    border-color: var(--color-primary-focused);
    box-shadow: none;
}

.bs-input--error .bs-multi-select__control {
    border-color: var(--color-error-default);
    box-shadow: 0 0 0 0.1875rem var(--color-error-container);
}

/* WCAG pair: --color-error-default on --color-neutrals-container background */
.bs-input--error .bs-multi-select__control:focus-within,
.bs-input--error .bs-multi-select__control.dxbl-focused {
    border-color: var(--color-error-default);
    box-shadow: 0 0 0 0.1875rem var(--color-error-container);
}


/* ============================================================
   Alert / Snackbar (bs-alert)
   Inline feedback banner styled after the BrandSync Snackbar spec.
   Color pairs: *-default text on *-container background.
   ============================================================ */
.bs-alert {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 16px;
    border-radius: 4px;
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-body-md-size, 16px);
    line-height: var(--font-body-md-line-height, 24px);
}

.bs-alert__body {
    flex: 1;
    padding-right: 8px;
}

.bs-alert__action {
    background: none;
    border: none;
    cursor: pointer;
    font-family: inherit;
    font-size: var(--font-body-md-size, 16px);
    font-weight: 500;
    color: inherit;
    padding: 0 16px;
    min-height: 44px;
    align-self: center;
    white-space: nowrap;
    text-decoration: underline;
    transition: opacity 0.15s ease;
}

.bs-alert__action:hover          { opacity: 0.8; }
.bs-alert__action:active         { opacity: 0.7; }
.bs-alert__action:focus-visible  { outline: 2px solid currentColor; outline-offset: 2px; }

.bs-alert__close {
    background: none;
    border: none;
    cursor: pointer;
    padding: 0 16px;
    min-height: 44px;
    min-width: 44px;
    align-self: center;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: var(--font-h6-size, 20px);
    line-height: var(--font-h6-line-height, 32px);
    color: inherit;
    transition: opacity 0.15s ease;
}

.bs-alert__close:hover          { opacity: 0.8; }
.bs-alert__close:active         { opacity: 0.9; }
.bs-alert__close:focus-visible  { outline: 2px solid currentColor; outline-offset: 2px; }

/* WCAG pair: --color-information-default text on --color-information-container background — customer must ensure 4.5:1 */
.bs-alert--information { background-color: var(--color-information-container); color: var(--color-information-default); }
/* WCAG pair: --color-success-default text on --color-success-container background — customer must ensure 4.5:1 */
.bs-alert--success     { background-color: var(--color-success-container); color: var(--color-success-default); }
/* WCAG pair: --color-warning-default text on --color-warning-container background — customer must ensure 4.5:1 */
.bs-alert--warning     { background-color: var(--color-warning-container); color: var(--color-warning-default); }
/* WCAG pair: --color-error-default text on --color-error-container background — customer must ensure 4.5:1 */
.bs-alert--error       { background-color: var(--color-error-container); color: var(--color-error-default); }
/* WCAG pair: --color-neutrals-default text on --color-neutrals-container-pressed background — customer must ensure 4.5:1 */
.bs-alert--neutral     { background-color: var(--color-neutrals-container-pressed); color: var(--color-neutrals-default); }

/* ============================================================
   Badge (bs-badge)
   Pill-shaped label for status, categories, and highlights.
   Color pairs: *-default text on *-container background.
   Sized in em relative to its own font-size (line-height: 1 + em padding),
   not a fixed px box, so it never renders taller than the text beside it.
   ============================================================ */
.bs-badge {
    display: inline-flex;
    align-items: center;
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-caption-md-size, 14px);
    line-height: 1;
    font-weight: 400;
    padding: 0.25em 0.65em;
    border-radius: 100px;
    white-space: nowrap;
}

.bs-badge--primary {
    background-color: var(--color-primary-container);
    color: var(--color-primary-default);
}

.bs-badge--neutral {
    background-color: var(--color-neutrals-container-pressed);
    color: var(--color-neutrals-default);
}

.bs-badge--success {
    background-color: var(--color-success-container);
    color: var(--color-success-default);
}


.bs-badge--error {
    background-color: var(--color-error-container);
    color: var(--color-error-default);
}

.bs-badge--warning {
    background-color: var(--color-warning-container);
    color: var(--color-warning-default);
}

.bs-badge--information {
    background-color: var(--color-information-container);
    color: var(--color-information-default);
}

/* ============================================================
   Event number (bs-event-number)
   Hashtag icon + arrangement number, shared by every member-facing
   surface that shows an event's InternalId (MEM-9113).
   WCAG: --color-neutrals-hover text on the surrounding container background.
   ============================================================ */
.bs-event-number {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: var(--font-caption-md-size, 14px);
    line-height: var(--font-caption-md-line-height, 20px);
    font-weight: 400;
    color: var(--color-neutrals-hover);
}

.bs-event-number__icon {
    font-size: 12px;
    width: 14px;
    text-align: center;
    flex-shrink: 0;
    color: var(--color-primary-default);
}

/* ============================================================
   BsIcon (bs-icon)
   Renders a <use> reference into the BrandSync icon sprite
   (Membercare.SelfService.Web.Components/wwwroot/icons/brandsync.svg,
   fill="currentColor" on each symbol) sized by font-size, so it inherits
   color from its context like a font icon would. Size is null by default
   (no modifier class), so the icon matches the surrounding text size -
   only Small/Medium/Large opt into a fixed BrandSync tier (16/24/32).
   The element itself is the <svg> root (see BsIcon.razor), so
   vertical-align applies directly - no flex wrapper needed.
   ============================================================ */
.bs-icon {
    display: inline-block;
    width: 1em;
    height: 1em;
    vertical-align: -0.125em;
}

.bs-icon--small {
    font-size: 1rem; /* BrandSync 16 */
}

.bs-icon--medium {
    font-size: 1.5rem; /* BrandSync 24 */
}

.bs-icon--large {
    font-size: 2rem; /* BrandSync 32 */
}

/* ============================================================
   BsProfileAvatar (bs-profile-avatar)
   Shows a member's picture or initials. Fills its parent, which
   owns the diameter, background and border.
   ============================================================ */

.bs-profile-avatar__image {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
}

/* WCAG pair: --color-neutrals-container text on the frame's --color-primary-default background.
   Initials size scales with the frame via a token so a smaller avatar can shrink the text. */
.bs-profile-avatar__initials {
    font-size: var(--profile-avatar-initials-size, 34px);
    font-weight: 600;
    color: var(--color-neutrals-container);
    line-height: 1; /* single-token avatar text, centered by the flex frame */
    text-transform: uppercase;
}

/* Opt-in (ColorKey supplied): the component paints its own circular background instead of relying on
   the parent frame's fixed colour, so it fills the same space regardless of the frame's own background. */
.bs-profile-avatar__initials--decorative {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    border-radius: 50%;
}

.bs-profile-avatar--decorative-1 { background-color: var(--color-decorative-1); }
.bs-profile-avatar--decorative-2 { background-color: var(--color-decorative-2); }
.bs-profile-avatar--decorative-3 { background-color: var(--color-decorative-3); }
.bs-profile-avatar--decorative-4 { background-color: var(--color-decorative-4); }
.bs-profile-avatar--decorative-5 { background-color: var(--color-decorative-5); }
.bs-profile-avatar--decorative-6 { background-color: var(--color-decorative-6); }

/* ============================================================
   Collapsible — shared across SelfService pages
   ============================================================ */

.collapsible-chevron {
    flex-shrink: 0;
    font-size: 16px;
    transition: transform 0.2s ease;
}

.collapsible-chevron--expanded {
    transform: rotate(180deg);
}

.collapsible-body {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.3s ease;
}

.collapsible-body.expanded {
    grid-template-rows: 1fr;
    border-top: var(--bs-border-width) solid var(--color-border, var(--bs-border-color));
}

.collapsible-body__inner {
    overflow: hidden;
    min-height: 0;
}

@media (prefers-reduced-motion: reduce) {
    .collapsible-chevron,
    .collapsible-body {
        transition: none;
    }
}

/* ============================================================
   BrandSync card — opt-in shadow/radius
   Add `bs-card` alongside Bootstrap's `card` where the BrandSync look is
   wanted. Never restyle the bare `.card` selector: a global override silently
   restyles every card in the app.
   ============================================================ */
.bs-card {
    box-shadow: var(--shadow-card);
    border-radius: var(--brand-border-radius, 1rem);
    border: none;
}

/* Add `bs-card--interactive` alongside `bs-card` on cards that respond to the pointer by
   elevating. A consumer that also transitions other properties (e.g. background-color) overrides
   the transition wholesale — its own transition list must restate box-shadow. */
.bs-card--interactive {
    transition: box-shadow 0.15s ease;
}

.bs-card--interactive:hover {
    box-shadow: var(--shadow-card-hover);
}

/* ============================================================
   BrandSync outline card — bordered, rounded, clipped list item
   Add `bs-outline-card` for bordered card rows (e.g. list items) that
   need rounded corners with clipped content, without the bs-card shadow.
   ============================================================ */
.bs-outline-card {
    border: 1px solid var(--color-border, var(--bs-border-color));
    border-radius: 0.5rem;
    overflow: hidden;
}

/* ============================================================
   BrandSync card row header — clickable/expandable card header
   Add `bs-card-row-header` to the clickable header row of a bs-outline-card
   list item (e.g. an expandable row). Combine with `bs-card-row-header--active`
   when expanded.
   ============================================================ */
.bs-card-row-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 1rem;
    cursor: pointer;
    user-select: none;
}

.bs-card-row-header:hover {
    /* WCAG pair: --color-neutrals-default on --color-neutrals-container-hover */
    background-color: var(--color-neutrals-container-hover);
}

.bs-card-row-header:focus-visible {
    outline: 2px solid var(--color-primary-focused);
    outline-offset: -2px;
}

.bs-card-row-header--active {
    /* WCAG pair: --color-primary-default on --color-primary-container */
    background-color: var(--color-primary-container);
    color: var(--color-primary-default);
}

/* ============================================================
   BrandSync card header — stacks on mobile, splits at tablet width
   Add `bs-card-header` to a card's top row (e.g. title/category on one
   side, a value like an amount on the other). Stacks in a single column
   below md; becomes a row with the two sides pushed to opposite ends at
   md and up.
   ============================================================ */
.bs-card-header {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

@media (min-width: 768px) {
    .bs-card-header {
        flex-direction: row;
        align-items: flex-start;
        justify-content: space-between;
    }
}

/* ============================================================
   BrandSync card detail row — icon + text list line
   Add `bs-card-detail-row` to a line inside a card body that pairs a
   Bootstrap icon with a text value (e.g. contact info, dates, address).
   Add `bs-card-detail-row--wrap` when several such items should sit on
   the same line when there's room, wrapping to their own lines
   otherwise — each direct child becomes its own icon+text pair.
   ============================================================ */
/* WCAG pair: --color-neutrals-default text on the card's light surface
   background (the shared .bs-card/.card box). */
.bs-card-detail-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-caption-md-size, 14px);
    line-height: var(--font-caption-md-line-height, 20px);
    color: var(--color-neutrals-default);
}

.bs-card-detail-row--wrap {
    flex-wrap: wrap;
    row-gap: 8px;
    column-gap: 16px;
}

.bs-card-detail-row--wrap > * {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* ============================================================
   BrandSync card amount — emphasized numeric value, e.g. a balance
   Add `bs-card-amount` to a card's headline numeric value. Combine with
   `bs-card-amount--negative` when the value is negative (e.g. arrears).
   ============================================================ */
.bs-card-amount {
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-body-lg-size, 18px);
    line-height: var(--font-body-lg-line-height, 28px);
}

/* WCAG pair: --color-error-default text on the card's light surface
   background (the shared .bs-card/.card box). */
.bs-card-amount--negative {
    color: var(--color-error-default);
}

/* ################################################################
   3. DASHBOARD FRAMEWORK
   ################################################################ */

/* ============================================================
   Dashboard grid (dashboard-grid*)
   Two-column layout; height equalization comes from the fixed
   height on .dashboard-module, not from grid-auto-rows.
   ============================================================ */

/* Extend the dashboard background through the layout shell's padding */
#page-content-wrapper:has(.dashboard-page) {
    background-color: var(--color-page-background);
    padding-left: 0 !important;
    padding-right: 0 !important;
}

#page-body-container:has(.dashboard-page) {
    padding-top: 0 !important;
}

.dashboard-page {
    background-color: var(--color-page-background);
    min-height: 100%;
    padding: 0 24px;
}

.dashboard-grid {
    display: flex;
    flex-direction: column;
}

.dashboard-row {
    padding: 0;
    margin-left: -24px;
    margin-right: -24px;
}

.dashboard-row--shade-0 {
    background-color: color-mix(in srgb, var(--color-neutrals-container-focused) 20%, var(--color-page-background));
}

.dashboard-row--shade-1 {
    background-color: color-mix(in srgb, var(--color-neutrals-container-focused) 5%, var(--color-page-background));
}

.dashboard-row--shade-2 {
    background-color: color-mix(in srgb, var(--color-neutrals-container-focused) 35%, var(--color-page-background));
}

.dashboard-row--shade-3 {
    background-color: color-mix(in srgb, var(--color-neutrals-container-focused) 5%, var(--color-page-background));
}

.dashboard-row__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
    padding-block: 24px;
    padding-inline: 24px;
    max-width: var(--bs-content-max-width);
    margin-inline: auto;
}

.dashboard-row__full-content {
    max-width: var(--bs-content-max-width);
    margin-inline: auto;
    padding-block: 24px;
    padding-inline: 24px;
}

@media (min-width: 1024px) {
    .dashboard-row__inner {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* ============================================================
   Dashboard list card (dashboard-list-card*)
   Framework-locked shell for list-style dashboard modules.
   Header (icon + title + optional action) is always rendered.
   Body shows skeleton, empty state, or <ul> with items.
   ============================================================ */

.dashboard-list-card {
    background-color: var(--color-neutrals-container);
    border-radius: var(--brand-border-radius, 16px);
    box-shadow: var(--shadow-card);
    display: flex;
    flex-direction: column;
    height: var(--dashboard-module-height, 264px);
    overflow: hidden;
}

.dashboard-list-card__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 24px;
    gap: 8px;
    background-color: var(--color-primary-container);
    flex-shrink: 0;
}

.dashboard-list-card__heading {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}

/* WCAG pair: --color-primary-default text on --color-neutrals-container background */
.dashboard-list-card__action {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin-top: auto;
    padding-top: 16px;
    padding-bottom: 16px;
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-body-md-size, 16px);
    line-height: var(--font-body-md-line-height, 24px);
    font-weight: 500;
}

.dashboard-list-card__action-link {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--color-primary-default);
    text-decoration: none;
}

.dashboard-list-card__action-link:hover {
    color: var(--color-primary-hover);
    text-decoration: underline;
}

.dashboard-list-card__action-link:active {
    color: var(--color-primary-pressed);
}

.dashboard-list-card__action-link:focus-visible {
    outline: 2px solid var(--color-primary-focused);
    outline-offset: 2px;
    border-radius: 2px;
}

.dashboard-list-card__action-icon {
    font-size: var(--font-caption-md-size, 14px);
}

/* WCAG pair: --color-primary-hover text on --color-neutrals-container background */
.dashboard-list-card__action-count {
    color: var(--color-primary-hover);
    font-weight: 400;
}

.dashboard-list-card__action-separator {
    color: var(--color-neutrals-hover);
}

.dashboard-list-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    color: var(--color-primary-default);
    font-size: 20px;
}

/* WCAG pair: --color-neutrals-default text on --color-primary-container background */
.dashboard-list-card__title {
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-h6-size, 20px);
    line-height: var(--font-h6-line-height, 32px);
    font-weight: 600;
    color: var(--color-neutrals-default);
    margin: 0;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dashboard-list-card__body {
    padding: 16px 24px 0;
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

/* WCAG pair: --color-neutrals-hover text on --color-neutrals-container background */
.dashboard-list-card__empty {
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-body-md-size, 16px);
    line-height: var(--font-body-md-line-height, 24px);
    color: var(--color-neutrals-hover);
    margin: auto;
    text-align: center;
    align-self: center;
}

/* WCAG pair: --color-primary-default on --color-neutrals-container background */
.dashboard-list-card__empty a {
    color: var(--color-primary-default);
    text-decoration: underline;
}

.dashboard-list-card__empty a:hover {
    color: var(--color-primary-hover);
}

.dashboard-list-card__skeleton {
    flex: 1;
    border-radius: 8px;
    background: linear-gradient(
        90deg,
        var(--color-neutrals-container-hover) 25%,
        var(--color-neutrals-container-focused) 50%,
        var(--color-neutrals-container-hover) 75%
    );
    background-size: 200% 100%;
    animation: dashboard-shimmer 1.5s infinite;
}

/* ============================================================
   Dashboard detail card (dashboard-detail-card*)
   Flexible shell for detail-style dashboard modules.
   No enforced header — module controls internal layout.
   CSS token contract only.
   ============================================================ */

/* Shared primary item name style for detail modules (group name, board name, event name, etc.).
   Simple/list modules are excluded — they use a colored header band with a different text treatment. */
.dashboard-detail-module__item-name {
    color: var(--color-primary-default);
}

.dashboard-detail-card {
    background-color: var(--color-neutrals-container);
    border-radius: var(--brand-border-radius, 16px);
    box-shadow: var(--shadow-card);
    display: flex;
    flex-direction: column;
    height: var(--dashboard-module-details-height, 288px);
    overflow: hidden;
    padding: 24px;
    transition: box-shadow 0.15s ease;
}

.dashboard-detail-card:hover {
    box-shadow: var(--shadow-card-hover);
}

.dashboard-detail-card.personal-info-module:hover {
    box-shadow: var(--shadow-card);
}

/* Narrower side padding than the default card: leaves more row width for
   the field list. The banner bleed margins in the module's scoped CSS mirror this. */
.dashboard-detail-card.personal-info-module {
    padding-left: 16px;
    padding-right: 16px;
}

.dashboard-detail-card__skeleton {
    flex: 1;
    border-radius: 8px;
    background: linear-gradient(
        90deg,
        var(--color-neutrals-container-hover) 25%,
        var(--color-neutrals-container-focused) 50%,
        var(--color-neutrals-container-hover) 75%
    );
    background-size: 200% 100%;
    animation: dashboard-shimmer 1.5s infinite;
}

@keyframes dashboard-shimmer {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
    .dashboard-list-card__skeleton,
    .dashboard-detail-card__skeleton,
    .skeleton-block,
    .skeleton-line,
    .dashboard-list__skeleton-block,
    .dashboard-list__skeleton-line {
        animation: none;
    }
}

/* ============================================================
   Dashboard layout (dashboard-layout*)
   Sidebar + main content layout for pages with a Sidebar module.
   ============================================================ */

.dashboard-layout {
    display: flex;
    flex-direction: column;
    gap: 24px;
    /* Mirror the content cap: 400px sidebar (≥1440px) + 24px gap + content column */
    max-width: calc(var(--bs-content-max-width) + 400px + 24px);
    margin-inline: auto;
}

.dashboard-layout__sidebar {
    min-width: 0;
}

.dashboard-layout__content {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
    min-width: 0;
}

@media (min-width: 1024px) {
    .dashboard-layout {
        flex-direction: row;
        align-items: flex-start;
    }

    .dashboard-layout__sidebar {
        /* Wide enough for the personal info field list (longest labels + phone numbers)
           without wrapping in the common case */
        flex: 0 0 360px;
    }

    .dashboard-layout__content {
        flex: 1;
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 1440px) {
    .dashboard-layout__sidebar {
        flex: 0 0 400px;
    }
}

.dashboard-layout__content-item--full {
    grid-column: 1 / -1;
}

/* ============================================================
   Dashboard summary (dashboard-details*)
   Responsive grid container for detail-module field layouts.
   Consumers define their own field/label/value markup.
   ============================================================ */

.dashboard-details {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 16px;
    width: 100%;
    align-content: start;
}

/* ============================================================
   Dashboard list (dashboard-list*)
   Item list for Employment, Education, and similar modules.
   ============================================================ */

.dashboard-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    width: 100%;
    flex: 1;
    min-height: 0;
    overflow: hidden;
}

.dashboard-list__item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 0;
}

.dashboard-list__item:first-child {
    padding-top: 0;
}

.dashboard-list__item-icon,
.dashboard-list__skeleton-icon {
    width: 32px;
    height: 32px;
    flex-shrink: 0;
}

.dashboard-list__item-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--color-primary-default);
    font-size: 14px;
}

.dashboard-list__item-content {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1;
}

/* WCAG pair: --color-neutrals-pressed text on --color-neutrals-container background */
.dashboard-list__item-name {
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-body-md-size, 16px);
    line-height: var(--font-body-md-line-height, 24px);
    font-weight: 500;
    color: var(--color-neutrals-pressed);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dashboard-list__item-subname {
    font-weight: normal;
    font-size: var(--font-caption-md-size, 0.875rem);
    margin-left: 0.5rem;
}

/* WCAG pair: --color-neutrals-hover text on --color-neutrals-container background */
.dashboard-list__item-description {
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-caption-md-size, 14px);
    line-height: var(--font-caption-md-line-height, 20px);
    font-weight: 400;
    color: var(--color-neutrals-hover);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dashboard-list__item-description::before {
    content: '\2013\00A0';
}


/* ============================================================
   Event detail module (event-detail-module__)
   Detail-style dashboard module for upcoming event enrollments.
   ============================================================ */

.event-detail-module {
    font-family: var(--font-family, Roboto, sans-serif);
}

.event-detail-module__participation {
    background-color: var(--color-neutrals-container);
    border-radius: var(--brand-border-radius, 16px);
    padding: 16px;
    box-shadow: var(--shadow-card);
}

.event-detail-module__participation--featured {
    padding-bottom: 0;
}

.event-detail-module__actions {
    margin-top: auto;
    padding-top: 16px;
    padding-bottom: 16px;
}

.event-detail-module__nav-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 40px;
    padding: 0 16px;
    border: 1.5px solid var(--color-primary-default);
    border-radius: 8px;
    background: transparent;
    color: var(--color-primary-default);
    font-size: var(--font-caption-md-size, 14px);
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    transition: background-color 0.15s, color 0.15s;
}

.event-detail-module__nav-button:hover {
    background-color: var(--color-primary-container);
}

.event-detail-module__nav-button:active {
    color: var(--color-primary-pressed);
}

.event-detail-module__nav-button:focus-visible {
    outline: 2px solid var(--color-primary-focused);
    outline-offset: 2px;
}

.event-detail-module__icon-button {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    min-width: 56px;
    min-height: 56px;
    padding: 8px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--color-primary-default);
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s;
}

.event-detail-module__icon-button:hover {
    background-color: var(--color-primary-container);
}

.event-detail-module__icon-button:focus-visible {
    outline: 2px solid var(--color-primary-focused);
    outline-offset: 2px;
}

.event-detail-module__icon-button-glyph {
    font-size: 18px;
    line-height: 1;
}

.event-detail-module__icon-button-label {
    font-size: var(--font-caption-sm-size, 12px);
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
}

.event-detail-module__icon-button--danger {
    color: var(--color-error-default);
}

.event-detail-module__icon-button--danger:hover {
    background-color: var(--color-error-container);
    color: var(--color-error-default);
}

.event-detail-module__action-divider {
    align-self: stretch;
    width: 1px;
    margin: 8px 4px;
    background-color: var(--color-border, #dde3e9);
}

.event-detail-module__title {
    font-size: var(--font-h6-size, 16px);
    line-height: var(--font-h6-line-height, 24px);
    font-weight: 600;
    color: var(--color-primary-default);
}

.event-detail-module__icon {
    width: 24px;
    color: var(--color-primary-default);
    font-size: 16px;
}


.event-detail-module__date {
    width: 48px;
    min-width: 48px;
    height: 48px;
    background-color: var(--color-primary-container);
    border-radius: 8px;
}

.event-detail-module__date-day {
    font-size: 18px;
    line-height: 1.2;
    font-weight: 700;
    color: var(--color-primary-default);
}

.event-detail-module__date-month {
    font-size: 12px;
    line-height: var(--font-caption-md-line-height, 20px);
    font-weight: 500;
    color: var(--color-primary-default);
}

.event-detail-module__name {
    font-size: var(--font-body-md-size, 16px);
    line-height: var(--font-body-md-line-height, 24px);
    font-weight: 500;
}

.event-detail-module__badges {
    /* Only the loading skeleton uses this now — the real card renders badges in the title row.
       Reserves one badge-row of height so the skeleton matches the loaded card's height.
       28px = 20px line-height + 2×4px vertical padding. */
    min-height: 28px;
}

.event-detail-module__recurring-icon {
    margin-left: 8px;
    font-size: 14px;
    color: var(--color-primary-default);
}

/* Event id sits on the title row; muted like the meta rows.
   WCAG: --color-neutrals-hover text on the card's --color-neutrals-container background. */
.event-detail-module__event-id {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: var(--font-caption-md-size, 14px);
    line-height: var(--font-caption-md-line-height, 20px);
    font-weight: 400;
    color: var(--color-neutrals-hover);
}

.event-detail-module__skeleton-date {
    width: 48px;
    min-width: 48px;
    height: 48px;
    border-radius: 8px;
}

.event-detail-module__row-action {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: flex-end;
    width: 24px;
    height: 24px;
    font-size: 16px;
    color: var(--color-primary-default);
    background: transparent;
    border: none;
    border-radius: 8px;
    padding: 0;
    cursor: pointer;
}

.event-detail-module__row-action:hover {
    color: var(--color-primary-hover);
    background-color: var(--color-primary-container);
}

.event-detail-module__row-action:active {
    color: var(--color-primary-pressed);
}

.event-detail-module__row-action:focus-visible {
    outline: 2px solid var(--color-primary-focused);
    outline-offset: 2px;
}

.event-detail-module__qr-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: none;
    border-radius: 8px;
    background-color: var(--color-primary-container);
    color: var(--color-primary-default);
    font-size: 18px;
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s;
}

.event-detail-module__qr-button:hover {
    background-color: var(--color-primary-container-hover);
    color: var(--color-primary-hover);
}

.event-detail-module__qr-button:active {
    color: var(--color-primary-pressed);
}

.event-detail-module__qr-button:focus-visible {
    outline: 2px solid var(--color-primary-focused);
    outline-offset: 2px;
}

.event-detail-module__empty {
    min-height: 160px;
    font-size: var(--font-body-md-size, 16px);
    line-height: var(--font-body-md-line-height, 24px);
    color: var(--color-neutrals-hover);
}

.event-detail-module__date--featured {
    width: 56px;
    min-width: 56px;
    height: 56px;
    background-color: var(--color-primary-default);
}

.event-detail-module__date--featured .event-detail-module__date-day {
    font-size: 24px;
    color: var(--color-neutrals-container);
}

.event-detail-module__date--featured .event-detail-module__date-month {
    font-size: 12px;
    color: var(--color-neutrals-container);
    opacity: 0.85;
}

.event-detail-module__name--featured {
    font-size: var(--font-body-lg-size, 18px);
    font-weight: 600;
}

.event-detail-module__skeleton-date--featured {
    width: 56px;
    min-width: 56px;
    height: 56px;
}

.event-detail-module__meta-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: var(--font-caption-md-size, 14px);
    line-height: var(--font-caption-md-line-height, 20px);
    color: var(--color-neutrals-hover);
}

.event-detail-module__meta-icon {
    font-size: 12px;
    width: 14px;
    text-align: center;
    flex-shrink: 0;
    color: var(--color-primary-default);
}

.event-detail-module__split {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: 16px;
    align-items: stretch;
    min-width: 0;
}

.event-detail-module__split .event-detail-module__participation--featured {
    grid-row: span 2;
}

.event-detail-module__split .event-detail-module__participation--compact {
    align-self: stretch;
}

@media (max-width: 767px) {
    .event-detail-module__split {
        grid-template-columns: minmax(0, 1fr);
        align-items: start;
    }

    .event-detail-module__split .event-detail-module__participation--featured {
        grid-row: span 1;
    }

    .event-detail-module__split .event-detail-module__featured-body {
        height: auto;
    }

    .event-detail-module__split .event-detail-module__participation--compact {
        flex: unset;
    }
}

/* ============================================================
   Simple module shared — date stamp and meta row
   Reusable across EventParticipationsSimpleModule and future list modules.
   ============================================================ */

/* WCAG pair: --color-primary-default text on --color-primary-container background */
.simple-module__date {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 40px;
    min-width: 40px;
    height: 40px;
    background-color: var(--color-primary-container);
    border-radius: 8px;
    flex-shrink: 0;
    overflow: hidden;
}

.simple-module__date-day {
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-body-md-size, 16px);
    line-height: 1.2; /* layout exception: decorative date digit constrained to 40px box */
    font-weight: 700;
    color: var(--color-primary-default);
}

/* WCAG pair: --color-primary-default text on --color-primary-container background */
.simple-module__date-month {
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-caption-sm-size, 11px);
    line-height: var(--font-caption-sm-line-height, 16px);
    font-weight: 500;
    color: var(--color-primary-default);
    text-transform: uppercase;
}

.simple-module__meta {
    display: flex;
    align-items: center;
    gap: 4px;
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-caption-md-size, 14px);
    line-height: var(--font-caption-md-line-height, 20px);
    font-weight: 400;
    color: var(--color-neutrals-hover);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* WCAG pair: --color-primary-default icon on --color-neutrals-container background */
.simple-module__meta-icon {
    font-size: 11px;
    color: var(--color-primary-default);
    flex-shrink: 0;
}


/* ################################################################
   4. CROSS-COMPONENT OVERRIDES
   ################################################################ */

/* ============================================================
   Custom fields detail module
   Hosts the shared BsSelectCustomFields inside a DashboardListCard so it shares the dashboard's
   white-card chrome (primary-tinted header bar, shadow, radius). Two adjustments are scoped here:
   1) the list card is fixed-height/clipping by design — let this full-width form grow instead;
   2) flatten BsSelectCustomFields from its page grid of shadowed cards into a single-column,
      transparent form so it reads as one card body, not nested cards.
   Stays global: these selectors target DashboardListCard/BsSelectCustomFields internals, so under
   CSS isolation they cannot live in a scoped file without a ::deep redesign (planned follow-up).
   ============================================================ */

/* Let the form grow with its content instead of clipping to the fixed module height. */
.custom-fields-detail-module .dashboard-list-card {
    height: auto;
}

.custom-fields-detail-module .dashboard-list-card__body {
    padding-bottom: 24px;
}

.custom-fields-detail-module .dashboard-list {
    overflow: visible;
}

/* Element tags outweigh BsSelectCustomFields' scoped (.x[b-hash]) rules, which otherwise win the
   cascade at equal specificity. */
.custom-fields-detail-module div.bs-select-custom-fields {
    display: flex;
    flex-direction: column;
    gap: 24px;
    /* Room for the first group's legend, which overhangs the top border. */
    padding-top: 8px;
}

/* Box + legend mechanic come from the shared .bs-fieldset utility above; these override only the
   BsSelectCustomFields page defaults (filled background, shadow, clipping, wide padding). */
.custom-fields-detail-module div.bs-select-custom-fields__group {
    background: transparent;
    box-shadow: none;
    overflow: visible;
    padding: 16px;
}

/* WCAG pair: --color-primary-default text on --color-neutrals-container (card) background.
   Truncation lives on the shared .bs-fieldset__legend; the ellipsis is repeated here because this
   variant's text is the inner <h3>, and text-overflow only truncates the element directly holding
   the text (the header's nowrap is inherited; the ellipsis must be on the title). */
.custom-fields-detail-module h3.bs-select-custom-fields__group-title {
    font-size: var(--font-body-md-size, 16px);
    line-height: var(--font-body-md-line-height, 24px);
    font-weight: 700;
    color: var(--color-primary-default);
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
}

.custom-fields-detail-module div.bs-select-custom-fields__group-body {
    padding: 0;
}

/* Use the full-width module's horizontal space: lay each group's fields out in two columns on
   wider viewports. Mobile-first — single column at the base, two columns from 768px up. */
.custom-fields-detail-module div.bs-select-custom-fields__fields {
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px 24px;
}

@media (min-width: 768px) {
    .custom-fields-detail-module div.bs-select-custom-fields__fields {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Interest module
   The wrapper class is scoped on a div that wraps the whole card (present in every state,
   including loading), so the auto-height + bottom spacing apply to the skeleton too — otherwise
   the loading skeleton sat flush against the card bottom. Mirrors .custom-fields-detail-module. */
.interest-detail-module .dashboard-list-card {
    height: auto;
}

/* Bottom breathing room below the last group / footer (and below the skeleton while loading),
   matching the custom-fields module (the framework body has 0 bottom padding for fixed-height
   list cards). */
.interest-detail-module .dashboard-list-card__body {
    padding-bottom: 24px;
}

/* Groups stack in a single full-width column; padding-top gives the group labels room. The
   interests inside each group flow onto shared rows on wider screens — see .dashboard-list__interests
   below. */
.dashboard-list:has(.dashboard-list__group) {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    padding-top: 1rem;
    overflow: visible;
    min-height: auto;
}

/* Box + legend mechanic come from .bs-fieldset / .bs-fieldset__legend (in the markup); these add
   only the Interests-specific layout and label typography. */
.dashboard-list__group {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    list-style: none;
    padding: 1rem 0.75rem 0.75rem;
    min-width: 0;
}

.dashboard-list__group-label {
    font-size: var(--font-body-sm-size, 0.875rem);
    line-height: var(--font-body-sm-line-height, 1.25rem);
    font-weight: 600;
}

/* Interests within a group. Mobile-first: stacked one per row at the base so long names get the
   full width. From 768px up they flow onto shared rows wherever there's room, putting this
   full-width module's horizontal space to use instead of leaving it empty. */
/* Collapsed interest lists clamp by ROWS (max-height + overflow), not by item count, so a wide screen
   — where interests wrap several per row — shows more interests than a narrow one for the same height.
   "Vis mere" lifts the clamp; InterestModule.razor.js reports how many items each clamp hides so the
   expander only appears when something is actually clipped. Base = mobile (column) ≈ 3 rows; the 768px
   rule below switches to wrap and ≈ 2 rows. The Bootstrap info tooltip is portaled to <body>, so this
   overflow clip does not affect it. */
.dashboard-list__interests {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    overflow: hidden;
    /* 3 rows: 3 × 2.75rem interest height + 2 × 0.5rem row gap */
    max-height: calc(3 * 2.75rem + 2 * 0.5rem);
}

/* One interest = the star/name toggle plus its optional info trigger, presented as a single
   hoverable unit. The padding, rounding and hover background live here (not on the toggle) so the
   highlight envelops the info icon too. The 0.5rem gap matches the star-to-name gap inside the
   toggle, so the info icon sits the same distance from the name as the star does. */
.dashboard-list__interest {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    min-width: 0;
    padding-inline: 0.5rem;
    border-radius: 0.5rem;
    transition: background-color 0.15s;
}

@media (min-width: 768px) {
    .dashboard-list__interests {
        flex-direction: row;
        flex-wrap: wrap;
        /* row 8px, column 16px */
        gap: 0.5rem 1rem;
        /* 2 rows where interests pack several per row: 2 × 2.75rem + 1 × 0.5rem row gap */
        max-height: calc(2 * 2.75rem + 0.5rem);
    }

    /* Size to content with no grow, so short interests pack several per row and the leftover space
       stays empty; a long name wraps inside the toggle rather than claiming the whole row. */
    .dashboard-list__interest {
        flex: 0 1 auto;
        max-width: 100%;
    }
}

/* Expander lifts the row clamp to reveal the rest. Placed after the 768px rule so it overrides the
   desktop max-height too (equal specificity → later in source wins). */
.dashboard-list__interests--expanded {
    max-height: none;
    overflow: visible;
}

/* Star + name are the toggle target (min 2.75rem/44px tall for touch). It sizes to its content
   (flex-grow 0) so the info icon sits right after the name rather than being pushed to the far
   right; it can still shrink (min-width 0) so long names wrap instead of overflowing. No border and
   no background — the inline padding and hover highlight live on .dashboard-list__interest so they
   wrap the info icon too. The block padding stays here: it gives wrapped multi-line names breathing
   room from the top/bottom of the hover pill (a single line is unaffected — min-height sets its
   height). align-items:flex-start keeps the star beside the first line of a wrapped name. */
.dashboard-list__interest-toggle {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    flex: 0 1 auto;
    min-width: 0;
    min-height: 2.75rem;
    padding-block: 0.5rem;
    border: none;
    background-color: transparent;
    cursor: pointer;
    text-align: left;
    color: var(--color-neutrals-default);
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-body-md-size, 1rem);
    line-height: var(--font-body-md-line-height, 1.5rem);
}

.dashboard-list__interest-toggle:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Unselected interests show an outlined star in a muted tone; selected ones a filled brand star.
   The outline/fill swap is the far/fas icon in the markup; this sets the matching colour. */
.dashboard-list__interest-star {
    flex-shrink: 0;
    color: var(--color-neutrals-hover);
    line-height: var(--font-body-md-line-height, 1.5rem);
}

.dashboard-list__interest-toggle[aria-pressed="true"] .dashboard-list__interest-star {
    color: var(--color-primary-default);
}

.dashboard-list__interest-name {
    min-width: 0;
    overflow-wrap: break-word;
    hyphens: none;
}

/* The info tooltip trigger (the focusable wrapper from MembersiteTooltip): keeps the 44px-tall tap
   target but hugs the name (no wide centred box) so it sits one 0.5rem gap from the name — the same
   distance the star sits from the name. The inline padding widens the hit area toward the WCAG AAA
   44px target without reintroducing the wide centred box. */
.dashboard-list__interest-info {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    padding-inline: 0.5rem;
    color: var(--color-primary-default);
    cursor: pointer;
}

/* Both expanders are borderless, brand-coloured text buttons with a 44px tap height. */
.dashboard-list__group-show-more,
.dashboard-list__show-more {
    align-items: center;
    gap: 0.5rem;
    min-height: 2.75rem;
    border: none;
    background-color: transparent;
    cursor: pointer;
    color: var(--color-primary-default);
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-body-sm-size, 0.875rem);
    line-height: var(--font-body-sm-line-height, 1.25rem);
    font-weight: 600;
}

/* Per-group expander: left-aligned inside the box. */
.dashboard-list__group-show-more {
    display: inline-flex;
    align-self: flex-start;
    padding: 0.25rem 0.5rem;
}

/* Module-level expander: centred under the groups. */
.dashboard-list__show-more {
    display: flex;
    width: fit-content;
    margin: 0.75rem auto 0;
    padding: 0.5rem 0.75rem;
}

/* Shared focus ring for every interactive element in the module. */
.dashboard-list__interest-toggle:focus-visible,
.dashboard-list__interest-info:focus-visible,
.dashboard-list__group-show-more:focus-visible,
.dashboard-list__show-more:focus-visible {
    outline: 2px solid var(--color-primary-focused);
    outline-offset: 2px;
}

/* Rotating chevron shared by both expanders. */
.dashboard-list__show-more-icon {
    transition: transform 0.15s;
}

.dashboard-list__show-more-icon--expanded {
    transform: rotate(180deg);
}

@media (hover: hover) {
    /* Highlight the whole unit (star + name + info icon), but not while it is saving (toggle disabled). */
    .dashboard-list__interest:has(.dashboard-list__interest-toggle:not(:disabled)):hover {
        background-color: var(--color-neutrals-container-hover);
    }

    /* Underline only the label, not the chevron icon. */
    .dashboard-list__group-show-more:hover span,
    .dashboard-list__show-more:hover span {
        text-decoration: underline;
    }
}

/* WCAG pair: --color-primary-default text on --color-primary-container background */
.dashboard-list__badge {
    flex-shrink: 0;
    background-color: var(--color-primary-container);
    color: var(--color-primary-default);
    font-family: var(--font-family, Roboto, sans-serif);
    font-size: var(--font-caption-md-size, 14px);
    line-height: var(--font-caption-md-line-height, 20px);
    font-weight: 500;
    padding: 4px 8px;
    border-radius: 100px;
    white-space: nowrap;
}

.skeleton-block,
.dashboard-list__skeleton-block {
    border-radius: 8px;
    background: linear-gradient(
        90deg,
        var(--color-neutrals-container-hover) 25%,
        var(--color-neutrals-container-focused) 50%,
        var(--color-neutrals-container-hover) 75%
    );
    background-size: 200% 100%;
    animation: dashboard-shimmer 1.5s infinite;
}

.skeleton-line,
.dashboard-list__skeleton-line {
    height: 16px;
    border-radius: 4px;
    background: linear-gradient(
        90deg,
        var(--color-neutrals-container-hover) 25%,
        var(--color-neutrals-container-focused) 50%,
        var(--color-neutrals-container-hover) 75%
    );
    background-size: 200% 100%;
    animation: dashboard-shimmer 1.5s infinite;
}

.skeleton-line--short,
.dashboard-list__skeleton-line--short {
    width: 55%;
}

@media (max-width: 1023px) {
    .dashboard-list__badge {
        width: 8px;
        height: 8px;
        padding: 0;
        border-radius: 50%;
        font-size: 0;
        line-height: 0;
        background-color: var(--color-primary-default);
    }
}


/* ============================================================
   PersonStatusBadges alignment patch
   ============================================================ */

/* PersonStatusBadges hardcodes ms-2 (for legacy non-flex callers) and its tooltip wrapper has no
   line-height of its own — both cause misalignment next to a sibling badge in a gap-based row.
   Cancel the margin and make the wrapper hug its badge. */
.d-flex.gap-2 > .person-status-badges__tooltip > .badge {
    margin-left: 0;
}

.d-flex.gap-2 > .person-status-badges__tooltip {
    display: inline-flex;
    align-items: center;
}

/* ============================================================
   BoardMemberSearchResultCard chip size
   ============================================================ */

/* Shrinks the board-function chip for this card only — BsChip sets the BrandSync-spec "Large" pill
   (32px/16px padding), used as-is everywhere else. The class reaches the chip through BsChip's Class
   passthrough, so BsChip renders the element and a scoped rule in the card can never match it; the
   override has to be global until BsChip grows a size parameter of its own.
   Stays within BrandSync minimums: 12px caption floor, line-height >= 1.5x font size, 8px-grid spacing. */
.bs-board-member-card__badge.bs-chip {
    min-height: 1.5rem;
    padding: 0 0.5rem;
    font-size: 12px;
    line-height: 18px;
    gap: 0;
}

/* ################################################################
   5. PAGES
   ################################################################ */

/* ============================================================
   Info pages (contact, about, ...) — card rendering customer-configured HTML.
   Padding is handled by Bootstrap p-3 / p-md-4 utilities on the element.
   ============================================================ */

.info-page__card {
    background-color: var(--color-neutrals-container);
    border-radius: var(--brand-border-radius, 16px);
    box-shadow: var(--shadow-card);
    color: var(--color-neutrals-default);
    font-family: var(--font-family, 'Roboto', sans-serif);
    font-size: var(--font-body-md-size, 16px);
    line-height: var(--font-body-md-line-height, 1.5);
}

