/* /Components/Layout/MainLayout.razor.rz.scp.css */
/* Layout styling lives in wwwroot/css/mh-theme.css (scoped under .mh-app).
   Only the unhandled-error banner remains here. */

#blazor-error-ui[b-tb1px8v0x2] {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss[b-tb1px8v0x2] {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }
/* /Components/Layout/NavMenu.razor.rz.scp.css */
.navbar-toggler[b-rmnr9m84wh] {
    appearance: none;
    cursor: pointer;
    width: 3.5rem;
    height: 2.5rem;
    color: white;
    position: absolute;
    top: 0.5rem;
    right: 1rem;
    border: 1px solid rgba(255, 255, 255, 0.1);
    background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
}

.navbar-toggler:checked[b-rmnr9m84wh] {
    background-color: rgba(255, 255, 255, 0.5);
}

.top-row[b-rmnr9m84wh] {
    min-height: 3.5rem;
    background-color: rgba(0,0,0,0.4);
}

.navbar-brand[b-rmnr9m84wh] {
    font-size: 1.1rem;
}

.bi[b-rmnr9m84wh] {
    display: inline-block;
    position: relative;
    width: 1.25rem;
    height: 1.25rem;
    margin-right: 0.75rem;
    top: -1px;
    background-size: cover;
}

.bi-house-door-fill-nav-menu[b-rmnr9m84wh] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
}

.bi-plus-square-fill-nav-menu[b-rmnr9m84wh] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
}

.bi-list-nested-nav-menu[b-rmnr9m84wh] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
}

.nav-item[b-rmnr9m84wh] {
    font-size: 0.9rem;
    padding-bottom: 0.5rem;
}

    .nav-item:first-of-type[b-rmnr9m84wh] {
        padding-top: 1rem;
    }

    .nav-item:last-of-type[b-rmnr9m84wh] {
        padding-bottom: 1rem;
    }

    .nav-item[b-rmnr9m84wh]  .nav-link {
        color: #d7d7d7;
        background: none;
        border: none;
        border-radius: 4px;
        height: 3rem;
        display: flex;
        align-items: center;
        line-height: 3rem;
        width: 100%;
    }

.nav-item[b-rmnr9m84wh]  a.active {
    background-color: rgba(255,255,255,0.37);
    color: white;
}

.nav-item[b-rmnr9m84wh]  .nav-link:hover {
    background-color: rgba(255,255,255,0.1);
    color: white;
}

.nav-scrollable[b-rmnr9m84wh] {
    display: none;
}

.navbar-toggler:checked ~ .nav-scrollable[b-rmnr9m84wh] {
    display: block;
}

@media (min-width: 641px) {
    .navbar-toggler[b-rmnr9m84wh] {
        display: none;
    }

    .nav-scrollable[b-rmnr9m84wh] {
        /* Never collapse the sidebar for wide screens */
        display: block;

        /* Allow sidebar to scroll for tall menus */
        height: calc(100vh - 3.5rem);
        overflow-y: auto;
    }
}
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
/* =============================================================================
   Maintenance / reconnection overlay - "Maintenance Screen 01" (clean).
   Ported + adapted from _handoff/Maintenance screen/Maintenance Screen 01/styles.css.

   ISOLATION CONTRACT (do NOT break the app):
   - The design's GLOBAL selectors (:root{--bg-page...}, html/body{...}, .ui-btn,
     .variant-tag, .devmodal ...) are NOT reproduced globally. Everything is
     re-authored under ONE overlay root (.mh-maint-overlay) with a unique mnt-*
     class vocabulary + --mnt-* props, so no app :root token, body rule, or shared
     class is touched. (Also Razor-scoped [b-xxx], a second isolation layer.)
   - The overlay FILLS THE WHOLE VIEWPORT with the app's WHITE surface
     (var(--mh-surface) = #FFFFFF light / #222B27 dark). NOT the cool cream
     (#E8EBF0, which reads grey) and NOT the design's #F4EFE4. The content sits
     centered directly on that white page - there is NO card frame/border/shadow.
   - No pet / cat. Just logo, title, message, the live countdown pill, two buttons.
   ============================================================================= */

.mh-maint-overlay[b-grf0dmhwfp] {
    --mnt-sans:  "Hanken Grotesk", ui-sans-serif, system-ui, -apple-system, sans-serif;
    --mnt-serif: "Source Serif 4", Georgia, serif;
    --mnt-mono:  "IBM Plex Mono", ui-monospace, Menlo, monospace;
}

/* =========================================================
   FULL-SCREEN WHITE SHELL
   The framework element is a <dialog> opened with showModal(): it lands in the top
   layer above everything. When closed the UA rule dialog:not([open]){display:none}
   keeps it hidden. Open, we override every UA default (max-width/height, margin,
   centering, border) and pin it to the viewport with inset:0 so it fills the WHOLE
   screen edge-to-edge - no gaps, no scrollbar overshoot. MudBlazor.min.css sets
   background-color:var(--mud-palette-background) !important on this id, so ours must
   be !important to win the white.
   ========================================================= */
#components-reconnect-modal.mh-maint-overlay[open][b-grf0dmhwfp] {
    position: fixed;
    inset: 0;
    width: auto;
    height: auto;
    max-width: none;
    max-height: none;
    margin: 0;
    padding: 24px;
    border: 0;
    border-radius: 0;
    z-index: 4000;
    display: grid;
    place-items: center;
    overflow: auto;
    color: var(--mh-ink);
    font-family: var(--mnt-sans);
    -webkit-font-smoothing: antialiased;
    background: var(--mh-surface);
    background-color: var(--mh-surface) !important;
}
#components-reconnect-modal.mh-maint-overlay[b-grf0dmhwfp]::backdrop { background: transparent; }
.mh-maint-overlay *[b-grf0dmhwfp] { box-sizing: border-box; }

/* logo theme-swap: pine on light, cream on dark (one pair, CSS toggles) */
.mh-maint-overlay .mnt-logo.is-dark[b-grf0dmhwfp] { display: none; }
body.dark .mh-maint-overlay .mnt-logo.is-light[b-grf0dmhwfp] { display: none; }
body.dark .mh-maint-overlay .mnt-logo.is-dark[b-grf0dmhwfp] { display: block; }

@keyframes mnt-spin-b-grf0dmhwfp { to { transform: rotate(360deg); } }

/* =========================================================
   CENTERED CONTENT  (no card chrome - it lives directly on the white page)
   ========================================================= */
.mh-maint-overlay .mnt-content[b-grf0dmhwfp] {
    width: min(560px, 100%);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    text-align: center;
    background: transparent;
    border: 0;
    box-shadow: none;
    animation: mnt-fade-in-b-grf0dmhwfp .5s cubic-bezier(.2, .7, .25, 1);
}
@keyframes mnt-fade-in-b-grf0dmhwfp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.mh-maint-overlay .mnt-ic[b-grf0dmhwfp] {
    position: relative;
    width: 104px;
    height: 104px;
    border-radius: 999px;
    display: grid;
    place-items: center;
    flex: none;
    background: color-mix(in srgb, var(--mh-green) 8%, var(--mh-surface));
    border: 1px solid color-mix(in srgb, var(--mh-green) 24%, transparent);
    box-shadow: inset 0 1px 2px color-mix(in srgb, var(--mh-green) 14%, transparent);
    color: var(--mh-green-d);
}
.mh-maint-overlay .mnt-ring[b-grf0dmhwfp] {
    position: absolute;
    inset: 7px;
    border-radius: 999px;
    border: 3px solid color-mix(in srgb, var(--mh-green) 20%, transparent);
    border-top-color: var(--mh-green);
    animation: mnt-spin-b-grf0dmhwfp .95s linear infinite;
}
.mh-maint-overlay .mnt-logo[b-grf0dmhwfp] { position: relative; width: 50px; height: auto; object-fit: contain; }
.mh-maint-overlay .mnt-title[b-grf0dmhwfp] { font-family: var(--mnt-serif); font-size: 27px; font-weight: 600; color: var(--mh-ink); margin: 4px 0 0; }
.mh-maint-overlay .mnt-sub[b-grf0dmhwfp] { font-size: 15px; line-height: 1.6; color: var(--mh-muted); max-width: 440px; margin: 0; }

.mh-maint-overlay .mnt-meta[b-grf0dmhwfp] {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-top: 4px;
    padding: 7px 16px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--mh-warning) 18%, var(--mh-surface));
    color: var(--mh-warning-d);
    font-size: 12.5px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.mh-maint-overlay .mnt-dot[b-grf0dmhwfp] { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--mh-warning); animation: mnt-pulse-b-grf0dmhwfp 1.5s ease infinite; }
@keyframes mnt-pulse-b-grf0dmhwfp { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

/* =========================================================
   BUTTONS  (overlay-local vocabulary; #id-prefixed so they outrank MudBlazor's
   `#components-reconnect-modal button` rule - which forces uppercase, its own
   padding/colour and a margin:40px auto !important).
   ========================================================= */
.mh-maint-overlay .mnt-btnrow[b-grf0dmhwfp] { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-top: 8px; }
#components-reconnect-modal.mh-maint-overlay .mnt-btn[b-grf0dmhwfp] {
    height: 44px;
    padding: 0 20px;
    min-width: 0;
    margin: 0 !important;
    border-radius: var(--mh-r-btn);
    cursor: pointer;
    font-family: var(--mnt-sans);
    font-size: 14.5px;
    font-weight: 700;
    letter-spacing: normal;
    line-height: 1;
    text-transform: none;
    color: var(--mh-ink);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    white-space: nowrap;
    border: 1px solid transparent;
    transition: background .2s, border-color .2s, transform .2s, box-shadow .2s, color .2s;
}
#components-reconnect-modal.mh-maint-overlay .mnt-btn svg[b-grf0dmhwfp] { width: 18px; height: 18px; stroke: currentColor; stroke-width: 2; fill: none; stroke-linecap: round; stroke-linejoin: round; }
#components-reconnect-modal.mh-maint-overlay .mnt-btn.secondary[b-grf0dmhwfp] { background: var(--mh-surface); border-color: color-mix(in srgb, var(--mh-green) 32%, transparent); color: var(--mh-green-d); box-shadow: var(--mh-shadow-sm); }
#components-reconnect-modal.mh-maint-overlay .mnt-btn.secondary:hover[b-grf0dmhwfp] { background: color-mix(in srgb, var(--mh-green) 8%, var(--mh-surface)); border-color: color-mix(in srgb, var(--mh-green) 46%, transparent); transform: translateY(-1px); }
#components-reconnect-modal.mh-maint-overlay .mnt-btn.ghost[b-grf0dmhwfp] { background: transparent; color: var(--mh-muted); }
#components-reconnect-modal.mh-maint-overlay .mnt-btn.ghost:hover[b-grf0dmhwfp] { background: color-mix(in srgb, var(--mh-ink) 7%, transparent); color: var(--mh-ink); }
#components-reconnect-modal.mh-maint-overlay .mnt-btn:focus-visible[b-grf0dmhwfp] { outline: none; box-shadow: var(--mh-ctrl-focus-ring); }

/* =========================================================
   DEVELOPER CONTACT MODAL  (mnt-devmodal - NOT the global .devmodal)
   ========================================================= */
.mh-maint-overlay .mnt-devmodal[b-grf0dmhwfp] { position: fixed; inset: 0; z-index: 200; display: grid; place-items: center; padding: 24px; }
.mh-maint-overlay .mnt-devmodal[hidden][b-grf0dmhwfp] { display: none; }
.mh-maint-overlay .mnt-dm-backdrop[b-grf0dmhwfp] {
    position: absolute;
    inset: 0;
    background: color-mix(in srgb, var(--mh-slate-2) 55%, transparent);
    backdrop-filter: blur(3px);
    opacity: 0;
    transition: opacity .24s cubic-bezier(.2, .7, .25, 1);
}
.mh-maint-overlay .mnt-devmodal.open .mnt-dm-backdrop[b-grf0dmhwfp] { opacity: 1; }
.mh-maint-overlay .mnt-dm-card[b-grf0dmhwfp] {
    position: relative;
    width: 380px;
    max-width: 100%;
    background: var(--mh-surface);
    border: 1px solid color-mix(in srgb, var(--mh-green) 22%, transparent);
    border-radius: var(--mh-r-card);
    box-shadow: var(--mh-shadow-lg);
    padding: 30px 28px 26px;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    opacity: 0;
    transform: translateY(14px) scale(.97);
    transition: opacity .24s cubic-bezier(.2, .7, .25, 1), transform .24s cubic-bezier(.2, .7, .25, 1);
}
.mh-maint-overlay .mnt-devmodal.open .mnt-dm-card[b-grf0dmhwfp] { opacity: 1; transform: translateY(0) scale(1); }
.mh-maint-overlay .mnt-dm-eyebrow[b-grf0dmhwfp] { font-family: var(--mnt-mono); font-size: 10.5px; font-weight: 600; letter-spacing: .22em; text-transform: uppercase; color: var(--mh-green-d); }
.mh-maint-overlay .mnt-dm-avatar[b-grf0dmhwfp] {
    position: relative;
    width: 84px;
    height: 84px;
    margin: 8px 0 8px;
    border-radius: 999px;
    overflow: hidden;
    display: grid;
    place-items: center;
    flex: none;
    background: linear-gradient(165deg, var(--mh-sage-300) 0%, var(--mh-green) 100%);
    box-shadow: 0 0 0 3px var(--mh-surface), 0 0 0 4px color-mix(in srgb, var(--mh-green) 32%, transparent), 0 10px 24px color-mix(in srgb, var(--mh-green) 30%, transparent);
}
/* initials sit behind as a graceful fallback if the photo is missing */
.mh-maint-overlay .mnt-dm-initials[b-grf0dmhwfp] {
    font-family: var(--mnt-serif);
    font-size: 29px;
    font-weight: 600;
    color: #F4F1E8;
    letter-spacing: .02em;
}
/* the photo masks into the circle - cover-fit, biased up to frame the face */
.mh-maint-overlay .mnt-dm-photo[b-grf0dmhwfp] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 999px;
    display: block;
    /* source is square going into a square circle, so cover shows the whole scene;
       scale up + bias toward the head to crop a proper head-and-shoulders portrait. */
    transform: scale(1.6);
    transform-origin: 50% 20%;
}
.mh-maint-overlay .mnt-dm-name[b-grf0dmhwfp] { font-family: var(--mnt-serif); font-size: 22px; font-weight: 600; color: var(--mh-ink); margin: 0; }
.mh-maint-overlay .mnt-dm-role[b-grf0dmhwfp] { font-size: 13px; color: var(--mh-muted); margin: 0 0 16px; }
.mh-maint-overlay .mnt-dm-rows[b-grf0dmhwfp] { display: flex; flex-direction: column; gap: 10px; width: 100%; }
.mh-maint-overlay .mnt-dm-row[b-grf0dmhwfp] {
    display: flex;
    align-items: center;
    gap: 13px;
    text-align: left;
    text-decoration: none;
    padding: 12px 14px;
    border-radius: var(--mh-r-card);
    border: 1px solid color-mix(in srgb, var(--mh-green) 26%, transparent);
    background: color-mix(in srgb, var(--mh-green) 6%, var(--mh-surface));
    box-shadow: var(--mh-shadow-sm);
    transition: background .2s, transform .2s, box-shadow .2s, border-color .2s;
}
.mh-maint-overlay .mnt-dm-row:hover[b-grf0dmhwfp] { background: color-mix(in srgb, var(--mh-green) 12%, var(--mh-surface)); border-color: color-mix(in srgb, var(--mh-green) 40%, transparent); transform: translateY(-1px); box-shadow: var(--mh-shadow); }
.mh-maint-overlay .mnt-dm-ic[b-grf0dmhwfp] {
    flex: none;
    width: 38px;
    height: 38px;
    display: grid;
    place-items: center;
    border-radius: 10px;
    background: color-mix(in srgb, var(--mh-green) 16%, var(--mh-surface));
    color: var(--mh-green-d);
}
.mh-maint-overlay .mnt-dm-ic svg[b-grf0dmhwfp] { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.mh-maint-overlay .mnt-dm-txt[b-grf0dmhwfp] { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.mh-maint-overlay .mnt-dm-label[b-grf0dmhwfp] { font-family: var(--mnt-mono); font-size: 10px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--mh-muted); }
.mh-maint-overlay .mnt-dm-val[b-grf0dmhwfp] { font-size: 14.5px; font-weight: 600; color: var(--mh-ink); overflow: hidden; text-overflow: ellipsis; }

/* =========================================================
   RESPONSIVE + reduced motion
   ========================================================= */
@media (max-width: 480px) {
    .mh-maint-overlay .mnt-title[b-grf0dmhwfp] { font-size: 24px; }
    .mh-maint-overlay .mnt-btnrow[b-grf0dmhwfp] { width: 100%; }
    #components-reconnect-modal.mh-maint-overlay .mnt-btn[b-grf0dmhwfp] { flex: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .mh-maint-overlay .mnt-ring[b-grf0dmhwfp],
    .mh-maint-overlay .mnt-dot[b-grf0dmhwfp],
    .mh-maint-overlay .mnt-content[b-grf0dmhwfp] {
        animation: none !important;
    }
}
/* /Components/Shared/CountryFilter.razor.rz.scp.css */
/* =========================================================
   CountryFilter - ported from the "All Countries Dropdown" design (styles.css),
   SCOPED (Blazor .razor.css) with LOCAL css vars on .country-combo (NOT :root) so it
   cannot clobber app tokens. Accent = app PINE. Fonts inherit (no Google Fonts).
   Light values are the design's literals; a body.dark block flips surfaces for dark mode.
   ========================================================= */
.country-combo[b-o9efg5nbc4] {
  --cf-canvas: #E8EBF0;
  --cf-ink-1: #1C2733;
  --cf-ink-3: #677579;
  --cf-ink-4: #9AA7B3;
  --cf-accent: #4E7C72;          /* app pine (D-PALETTE) */
  --cf-rest-bg: #DFE4EA;
  --cf-rest-bd: rgba(40,60,80,.10);
  --cf-rest-sh: inset 0 1px 2px rgba(40,60,80,.10);
  --cf-hover-bg: #E4E8ED;
  --cf-focus-bg: #FFFFFF;
  --cf-focus-bd: rgba(40,60,80,.16);
  --cf-focus-sh: 0 10px 28px rgba(40,60,80,.14);
  --cf-menu-bg: #FFFFFF;
  --cf-sep: rgba(40,60,80,.1);
  /* Placeholder colour = the SAME as the search box's placeholder (.bigbar input::placeholder,
     mh-theme.css): a literal #9AA7B3 in light, var(--mh-ctrl-ico) in dark. Mirrored here so the
     default "All Countries" summary reads exactly like the search placeholder next to it. */
  --cf-placeholder: #9AA7B3;
  --cf-r-md: 13px;
  --cf-r-pill: 999px;
  --cf-ease: cubic-bezier(.2,.7,.25,1);
  --cf-t: .2s var(--cf-ease);
}
body.dark .country-combo[b-o9efg5nbc4] {
  --cf-canvas: #2b3330;
  --cf-ink-1: #EEF1EE;
  --cf-ink-3: #9fb0ab;
  --cf-ink-4: #6f817b;
  --cf-rest-bg: #1f2724;
  --cf-rest-bd: rgba(255,255,255,.10);
  --cf-rest-sh: inset 0 1px 2px rgba(0,0,0,.30);
  --cf-hover-bg: #273330;
  --cf-focus-bg: #232b28;
  --cf-focus-bd: rgba(120,160,150,.35);
  --cf-focus-sh: 0 10px 28px rgba(0,0,0,.35);
  --cf-menu-bg: #232b28;
  --cf-sep: rgba(255,255,255,.10);
  --cf-placeholder: var(--mh-ctrl-ico);   /* matches the search box's dark placeholder exactly */
}

/* ---- combo wrapper + menu ---- */
.combo[b-o9efg5nbc4] { position: relative; }
.cselect.pill-wrap[b-o9efg5nbc4] { flex: none; }
.cf-backdrop[b-o9efg5nbc4] { position: fixed; inset: 0; z-index: 19; background: transparent; border: none; }

.combo .menu[b-o9efg5nbc4] {
  position: absolute; top: calc(100% + 8px); left: 0; right: 0; z-index: 20;
  background: var(--cf-menu-bg); border: 1px solid var(--cf-focus-bd); border-radius: var(--cf-r-md);
  box-shadow: 0 18px 40px rgba(40,60,80,.18); padding: 7px;
  opacity: 0; transform: translateY(-4px); pointer-events: none;
  transition: opacity .16s var(--cf-ease), transform .16s var(--cf-ease);
  /* The menu grew with its option count and had no cap: at 17 program types it stood 851px
     tall in a 720px viewport and "Clear Filter" sat 326px BELOW the screen, unreachable. It
     only ever looked fine on Clients because the seed has 7 countries in use - in production
     that list is unbounded, so this was a latent bug there too.
     --mh-vh, never bare vh: the app-wide zoom inflates the bare unit (Display resolution). */
  max-height: min(calc(44 * var(--mh-vh)), 440px);
  display: flex; flex-direction: column;
}
/* min-height:0 so the list can actually shrink inside the capped flex column. */
.menu .clist[b-o9efg5nbc4] { overflow: auto; min-height: 0; display: flex; flex-direction: column; }
.menu .clist[b-o9efg5nbc4]::-webkit-scrollbar { width: 8px; }
.menu .clist[b-o9efg5nbc4]::-webkit-scrollbar-thumb { background: var(--cf-rest-bg); border-radius: 99px; }
.menu .allrow[b-o9efg5nbc4], .menu .sep[b-o9efg5nbc4], .menu .clearrow[b-o9efg5nbc4] { flex: none; }
.combo.open .menu[b-o9efg5nbc4] { opacity: 1; transform: translateY(0); pointer-events: auto; }
.combo.open .chev[b-o9efg5nbc4] { transform: rotate(180deg); }

/* ---- the pill trigger (.icf) ---- */
.icf[b-o9efg5nbc4] {
  display: flex; align-items: center; gap: 11px;
  min-height: 48px; padding: 0 15px;
  background: var(--cf-rest-bg);
  border: 1px solid var(--cf-rest-bd);
  box-shadow: var(--cf-rest-sh);
  border-radius: var(--cf-r-md);
  color: var(--cf-ink-1);
  transition: background var(--cf-t), border-color var(--cf-t), box-shadow var(--cf-t);
}
.icf:hover:not(:focus-within)[b-o9efg5nbc4] { background: var(--cf-hover-bg); }
.icf:focus-within[b-o9efg5nbc4],
.icf[aria-expanded="true"][b-o9efg5nbc4] {
  background: var(--cf-focus-bg); border-color: var(--cf-focus-bd); box-shadow: var(--cf-focus-sh);
}
.ic[b-o9efg5nbc4] { width: 19px; height: 19px; flex: none; display: grid; place-items: center; color: var(--cf-ink-3); }
.ic svg[b-o9efg5nbc4] { width: 100%; height: 100%; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; fill: none; }
.chev[b-o9efg5nbc4] { transition: transform var(--cf-t); }

/* Height/padding matched to the toolbar Search box (.cl-srchbar in mh-theme.css: height 40px,
   padding 0 16px) so the pill and the search field line up exactly side by side. */
.icf.pill[b-o9efg5nbc4] { border-radius: var(--cf-r-pill); height: 40px; min-height: 40px; padding: 0 16px; }
.icf.pill.country[b-o9efg5nbc4] { flex: none; min-width: 210px; cursor: pointer; }

.combo-summary[b-o9efg5nbc4] {
  flex: 1; min-width: 0; font-size: 15px; font-weight: 500; color: var(--cf-ink-1);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Default state ("All Countries", nothing selected) reads as a PLACEHOLDER: same muted colour +
   weight as the search box's placeholder. The moment a country is picked the class drops and the
   summary returns to full-strength ink. */
.combo-summary.is-placeholder[b-o9efg5nbc4] { color: var(--cf-placeholder); font-weight: 400; }

/* ---- menu rows ---- */
.menu .item[b-o9efg5nbc4] {
  padding: 9px 12px; border-radius: 8px; font-size: 14px; color: var(--cf-ink-1); cursor: pointer;
  display: flex; align-items: center; gap: 9px;
}
.menu .item:hover[b-o9efg5nbc4], .menu .item.active[b-o9efg5nbc4] { background: var(--cf-canvas); }
.menu .item .tick[b-o9efg5nbc4] { width: 15px; height: 15px; color: var(--cf-accent); opacity: 0; margin-left: auto; }
.menu .item.sel .tick[b-o9efg5nbc4] { opacity: 1; }
.menu .sep[b-o9efg5nbc4] { height: 1px; background: var(--cf-sep); margin: 5px 6px; }

/* ---- country rows: name (single) + checkbox (multi) ---- */
.country-menu[b-o9efg5nbc4] { min-width: 0; left: 0; right: 0; top: calc(100% + 8px); width: auto; }
.country-menu .crow .cname[b-o9efg5nbc4] { flex: 1; min-width: 0; }
.country-menu .cbx[b-o9efg5nbc4] {
  width: 20px; height: 20px; flex: none; border-radius: 6px; margin-left: auto;
  background: var(--cf-rest-bg); border: 1px solid var(--cf-rest-bd); box-shadow: var(--cf-rest-sh);
  display: grid; place-items: center; cursor: pointer;
  transition: background var(--cf-t), border-color var(--cf-t), box-shadow var(--cf-t);
}
.country-menu .cbx svg[b-o9efg5nbc4] {
  width: 12px; height: 12px; stroke: #fff; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; fill: none;
  opacity: 0; transform: scale(.6); transition: opacity var(--cf-t), transform var(--cf-t);
}
.country-menu .cbx:hover[b-o9efg5nbc4] { background: var(--cf-hover-bg); }
.country-menu .cbx.on[b-o9efg5nbc4] { background: var(--cf-accent); border-color: var(--cf-accent); box-shadow: inset 0 1px 2px rgba(0,0,0,.14); }
.country-menu .cbx.on svg[b-o9efg5nbc4] { opacity: 1; transform: scale(1); }

.country-menu .clearrow[b-o9efg5nbc4] {
  padding: 9px 12px; border-radius: 8px; font-size: 13.5px; font-weight: 600; color: var(--cf-accent);
  cursor: pointer; transition: background var(--cf-t);
}
.country-menu .clearrow:hover[b-o9efg5nbc4] { background: var(--cf-canvas); }
.country-menu .clearrow.dis[b-o9efg5nbc4] { color: var(--cf-ink-4); font-weight: 500; pointer-events: none; }
/* /Components/Shared/FilterSelect.razor.rz.scp.css */
/* =========================================================
   FilterSelect - the SINGLE-SELECT filter dropdown.

   The trigger + menu design is CountryFilter's, reproduced here rather than shared:
   Blazor scopes .razor.css per component, so a sibling component cannot inherit
   another's scoped rules. Keeping the two in step by copy is the cost of scoping;
   the alternative (a global stylesheet) would put these class names - .icf, .menu,
   .item - into the global namespace, where .icf already means the FIELD KIT and the
   collision would be immediate.

   What differs from CountryFilter: no checkbox column and no Clear row (single
   select), plus a search box and an optional per-row sub-label.
   ========================================================= */

.country-combo[b-89kpf6uzhp] {
  --cf-canvas: #E8EBF0;
  --cf-ink-1: #1C2733;
  --cf-ink-3: #677579;
  --cf-ink-4: #9AA7B3;
  --cf-accent: #4E7C72;          /* app pine (D-PALETTE) */
  --cf-rest-bg: #DFE4EA;
  --cf-rest-bd: rgba(40,60,80,.10);
  --cf-rest-sh: inset 0 1px 2px rgba(40,60,80,.10);
  --cf-hover-bg: #E4E8ED;
  --cf-focus-bg: #FFFFFF;
  --cf-focus-bd: rgba(40,60,80,.16);
  --cf-focus-sh: 0 10px 28px rgba(40,60,80,.14);
  --cf-menu-bg: #FFFFFF;
  --cf-sep: rgba(40,60,80,.1);
  /* Placeholder colour = the SAME as the search box's placeholder (.bigbar input::placeholder,
     mh-theme.css): a literal #9AA7B3 in light, var(--mh-ctrl-ico) in dark. Mirrored here so the
     default "All Countries" summary reads exactly like the search placeholder next to it. */
  --cf-placeholder: #9AA7B3;
  --cf-r-md: 13px;
  --cf-r-pill: 999px;
  --cf-ease: cubic-bezier(.2,.7,.25,1);
  --cf-t: .2s var(--cf-ease);
}
body.dark .country-combo[b-89kpf6uzhp] {
  --cf-canvas: #2b3330;
  --cf-ink-1: #EEF1EE;
  --cf-ink-3: #9fb0ab;
  --cf-ink-4: #6f817b;
  --cf-rest-bg: #1f2724;
  --cf-rest-bd: rgba(255,255,255,.10);
  --cf-rest-sh: inset 0 1px 2px rgba(0,0,0,.30);
  --cf-hover-bg: #273330;
  --cf-focus-bg: #232b28;
  --cf-focus-bd: rgba(120,160,150,.35);
  --cf-focus-sh: 0 10px 28px rgba(0,0,0,.35);
  --cf-menu-bg: #232b28;
  --cf-sep: rgba(255,255,255,.10);
  --cf-placeholder: var(--mh-ctrl-ico);   /* matches the search box's dark placeholder exactly */
}

/* ---- combo wrapper + menu ---- */
.combo[b-89kpf6uzhp] { position: relative; }
.cselect.pill-wrap[b-89kpf6uzhp] { flex: none; }
.cf-backdrop[b-89kpf6uzhp] { position: fixed; inset: 0; z-index: 19; background: transparent; border: none; }

.combo .menu[b-89kpf6uzhp] {
  position: absolute; top: calc(100% + 8px); left: 0; right: 0; z-index: 20;
  background: var(--cf-menu-bg); border: 1px solid var(--cf-focus-bd); border-radius: var(--cf-r-md);
  box-shadow: 0 18px 40px rgba(40,60,80,.18); padding: 7px;
  opacity: 0; transform: translateY(-4px); pointer-events: none;
  transition: opacity .16s var(--cf-ease), transform .16s var(--cf-ease);
  /* The menu grew with its option count and had no cap: at 17 program types it stood 851px
     tall in a 720px viewport and "Clear Filter" sat 326px BELOW the screen, unreachable. It
     only ever looked fine on Clients because the seed has 7 countries in use - in production
     that list is unbounded, so this was a latent bug there too.
     --mh-vh, never bare vh: the app-wide zoom inflates the bare unit (Display resolution). */
  max-height: min(calc(44 * var(--mh-vh)), 440px);
  display: flex; flex-direction: column;
}
/* min-height:0 so the list can actually shrink inside the capped flex column. */
.menu .clist[b-89kpf6uzhp] { overflow: auto; min-height: 0; display: flex; flex-direction: column; }
.menu .clist[b-89kpf6uzhp]::-webkit-scrollbar { width: 8px; }
.menu .clist[b-89kpf6uzhp]::-webkit-scrollbar-thumb { background: var(--cf-rest-bg); border-radius: 99px; }
.menu .allrow[b-89kpf6uzhp], .menu .sep[b-89kpf6uzhp], .menu .clearrow[b-89kpf6uzhp] { flex: none; }
.combo.open .menu[b-89kpf6uzhp] { opacity: 1; transform: translateY(0); pointer-events: auto; }
.combo.open .chev[b-89kpf6uzhp] { transform: rotate(180deg); }

/* ---- the pill trigger (.icf) ---- */
.icf[b-89kpf6uzhp] {
  display: flex; align-items: center; gap: 11px;
  min-height: 48px; padding: 0 15px;
  background: var(--cf-rest-bg);
  border: 1px solid var(--cf-rest-bd);
  box-shadow: var(--cf-rest-sh);
  border-radius: var(--cf-r-md);
  color: var(--cf-ink-1);
  transition: background var(--cf-t), border-color var(--cf-t), box-shadow var(--cf-t);
}
.icf:hover:not(:focus-within)[b-89kpf6uzhp] { background: var(--cf-hover-bg); }
.icf:focus-within[b-89kpf6uzhp],
.icf[aria-expanded="true"][b-89kpf6uzhp] {
  background: var(--cf-focus-bg); border-color: var(--cf-focus-bd); box-shadow: var(--cf-focus-sh);
}
.ic[b-89kpf6uzhp] { width: 19px; height: 19px; flex: none; display: grid; place-items: center; color: var(--cf-ink-3); }
.ic svg[b-89kpf6uzhp] { width: 100%; height: 100%; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; fill: none; }
.chev[b-89kpf6uzhp] { transition: transform var(--cf-t); }

/* Height/padding matched to the toolbar Search box (.cl-srchbar in mh-theme.css: height 40px,
   padding 0 16px) so the pill and the search field line up exactly side by side. */
.icf.pill[b-89kpf6uzhp] { border-radius: var(--cf-r-pill); height: 40px; min-height: 40px; padding: 0 16px; }
.icf.pill.country[b-89kpf6uzhp] { flex: none; min-width: 210px; cursor: pointer; }

.combo-summary[b-89kpf6uzhp] {
  flex: 1; min-width: 0; font-size: 15px; font-weight: 500; color: var(--cf-ink-1);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Default state ("All Countries", nothing selected) reads as a PLACEHOLDER: same muted colour +
   weight as the search box's placeholder. The moment a country is picked the class drops and the
   summary returns to full-strength ink. */
.combo-summary.is-placeholder[b-89kpf6uzhp] { color: var(--cf-placeholder); font-weight: 400; }

/* ---- menu rows ---- */
.menu .item[b-89kpf6uzhp] {
  padding: 9px 12px; border-radius: 8px; font-size: 14px; color: var(--cf-ink-1); cursor: pointer;
  display: flex; align-items: center; gap: 9px;
}
.menu .item:hover[b-89kpf6uzhp], .menu .item.active[b-89kpf6uzhp] { background: var(--cf-canvas); }
.menu .item .tick[b-89kpf6uzhp] { width: 15px; height: 15px; color: var(--cf-accent); opacity: 0; margin-left: auto; }
.menu .item.sel .tick[b-89kpf6uzhp] { opacity: 1; }
.menu .sep[b-89kpf6uzhp] { height: 1px; background: var(--cf-sep); margin: 5px 6px; }

/* ---- country rows: name (single) + checkbox (multi) ---- */
.country-menu[b-89kpf6uzhp] { min-width: 0; left: 0; right: 0; top: calc(100% + 8px); width: auto; }
.country-menu .crow .cname[b-89kpf6uzhp] { flex: 1; min-width: 0; }
.country-menu .cbx[b-89kpf6uzhp] {
  width: 20px; height: 20px; flex: none; border-radius: 6px; margin-left: auto;
  background: var(--cf-rest-bg); border: 1px solid var(--cf-rest-bd); box-shadow: var(--cf-rest-sh);
  display: grid; place-items: center; cursor: pointer;
  transition: background var(--cf-t), border-color var(--cf-t), box-shadow var(--cf-t);
}
.country-menu .cbx svg[b-89kpf6uzhp] {
  width: 12px; height: 12px; stroke: #fff; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; fill: none;
  opacity: 0; transform: scale(.6); transition: opacity var(--cf-t), transform var(--cf-t);
}
.country-menu .cbx:hover[b-89kpf6uzhp] { background: var(--cf-hover-bg); }
.country-menu .cbx.on[b-89kpf6uzhp] { background: var(--cf-accent); border-color: var(--cf-accent); box-shadow: inset 0 1px 2px rgba(0,0,0,.14); }
.country-menu .cbx.on svg[b-89kpf6uzhp] { opacity: 1; transform: scale(1); }

.country-menu .clearrow[b-89kpf6uzhp] {
  padding: 9px 12px; border-radius: 8px; font-size: 13.5px; font-weight: 600; color: var(--cf-accent);
  cursor: pointer; transition: background var(--cf-t);
}
.country-menu .clearrow:hover[b-89kpf6uzhp] { background: var(--cf-canvas); }
.country-menu .clearrow.dis[b-89kpf6uzhp] { color: var(--cf-ink-4); font-weight: 500; pointer-events: none; }


/* ---- single-select additions ---- */
.fsel .fsel-lead[b-89kpf6uzhp] { color: var(--cf-ink-3); }
.fsel .icf[aria-expanded="true"] .fsel-lead[b-89kpf6uzhp] { color: var(--cf-accent); }

.fsel-search[b-89kpf6uzhp] {
  display: flex; align-items: center; gap: 8px; flex: none;
  padding: 7px 10px; margin-bottom: 4px;
  background: var(--cf-rest-bg); border: 1px solid var(--cf-rest-bd);
  box-shadow: var(--cf-rest-sh); border-radius: 9px;
}
.fsel-search svg[b-89kpf6uzhp] { width: 15px; height: 15px; flex: none; color: var(--cf-ink-4); }
.fsel-search input[b-89kpf6uzhp] {
  flex: 1; min-width: 0; border: 0; outline: none; background: transparent;
  font-family: inherit; font-size: 14px; color: var(--cf-ink-1);
}
.fsel-search input[b-89kpf6uzhp]::placeholder { color: var(--cf-placeholder); font-weight: 400; }

/* the row carries a name and an optional sub-line, so it is a column not a single line */
.fsel-row[b-89kpf6uzhp] { align-items: flex-start; }
.fsel-main[b-89kpf6uzhp] { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.fsel-main .cname[b-89kpf6uzhp] { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fsel-sub[b-89kpf6uzhp] { font-size: 11.5px; color: var(--cf-ink-4); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fsel-row.sel .cname[b-89kpf6uzhp] { font-weight: 700; color: var(--cf-ink-1); }
/* The selected row's TEXT stays ink. Painting it brand-green was my own addition and it is not
   what our control does: CountryFilter marks the selection with the TICK alone and leaves the
   label in normal ink. A green label reads as a link or a status, not as "this is the one you
   picked", and it was the only green in the menu. The tick keeps the accent - that is the
   standard, and it is the same green `#mhDetail .sel-opt.on` uses for its check. */
.fsel-row .tick[b-89kpf6uzhp] { margin-top: 2px; }

.fsel-empty[b-89kpf6uzhp] { padding: 12px; font-size: 13.5px; color: var(--cf-ink-3); }

/* a picker that must always hold a value is wider than a facet pill - it shows a real
   record name, not a one-word facet. */
.fsel .icf.pill.country[b-89kpf6uzhp] { min-width: 260px; }

/* ---- SPECIFICITY: the trigger must out-rank the GLOBAL field kit ----
   `.icf` is not ours alone - the field kit defines `.mh-app .icf` (0,2,0) with the LIGHT
   #DFE4EA fill. Blazor's scope attribute makes our rule `.icf[b-xxx]`, also (0,2,0), so the
   winner came down to stylesheet ORDER and the global one won: the trigger stayed light-grey
   in dark mode while this component's own menu flipped correctly around it. Qualifying with
   `.fsel` takes it to (0,3,0) and settles it on merit rather than load order.
   Found by measuring the computed fill in dark, not by reading the cascade. */
.fsel .icf.pill.country[b-89kpf6uzhp] {
  background: var(--cf-rest-bg);
  border: 1px solid var(--cf-rest-bd);
  box-shadow: var(--cf-rest-sh);
  color: var(--cf-ink-1);
}
.fsel .icf.pill.country:hover:not([aria-expanded="true"])[b-89kpf6uzhp] { background: var(--cf-hover-bg); }
.fsel .icf.pill.country[aria-expanded="true"][b-89kpf6uzhp] {
  background: var(--cf-focus-bg); border-color: var(--cf-focus-bd); box-shadow: var(--cf-focus-sh);
}
/* /Components/Shared/PinPad.razor.rz.scp.css */
/* =============================================================================
   PinPad.razor.css  -  scoped styles for the shared popup keypad. App tokens only
   (Pine dots = --mh-green, keys = --mh-ctrl-fill, errors = --mh-danger); light +
   dark flip automatically through the tokens. Layout faithful to the kiosk
   #pinOverlay: 74px keys, 16px radius, six 18px dots. The card shake is gated by
   prefers-reduced-motion. Plain hyphens only.
   ========================================================================== */

.pk-ov[b-tb360xytgj] {
    position: fixed;
    inset: 0;
    z-index: 100046;                 /* above the crop studio (100045) + lightbox (100040) */
    background: rgba(20, 32, 28, .62);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
    display: grid;
    place-items: center;
    padding: 20px;
    animation: pkFade-b-tb360xytgj .2s ease both;
}

.pk-card[b-tb360xytgj] {
    width: min(380px, 92vw);
    max-height: 92vh;
    overflow: auto;
    box-sizing: border-box;
    background: var(--mh-cream);
    border: 1px solid var(--mh-line);
    border-radius: 20px;
    padding: 22px 24px 24px;
    box-shadow: 0 30px 90px rgba(20, 34, 30, .5);
    outline: none;
    animation: pkPop-b-tb360xytgj .24s cubic-bezier(.2, .7, .3, 1.2) both;
}

.pk-head[b-tb360xytgj] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.pk-head h2[b-tb360xytgj] {
    margin: 0;
    font-family: var(--mh-font-head);
    font-size: 20px;
    font-weight: 800;
    letter-spacing: -.01em;
    color: var(--mh-ink);
}

.pk-x[b-tb360xytgj] {
    border: none;
    background: transparent;
    color: var(--mh-muted);
    font-size: 26px;
    line-height: 1;
    cursor: pointer;
    padding: 0 4px;
    border-radius: 8px;
    transition: color .15s, background .15s;
}

.pk-x:hover[b-tb360xytgj] {
    color: var(--mh-ink);
    background: var(--mh-cream-2);
}

.pk-sub[b-tb360xytgj] {
    margin: 8px 0 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--mh-muted);
}

.pk-dots[b-tb360xytgj] {
    display: flex;
    justify-content: center;
    gap: 18px;
    margin: 22px 0 24px;
}

.pk-dots span[b-tb360xytgj] {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 2px solid var(--mh-ctrl-border);
    background: transparent;
    transition: .15s;
}

.pk-dots span.on[b-tb360xytgj] {
    background: var(--mh-green);
    border-color: var(--mh-green);
    transform: scale(1.08);
}

.pk-pad[b-tb360xytgj] {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 14px;
}

.pk-key[b-tb360xytgj] {
    height: 74px;
    border: 1px solid var(--mh-ctrl-border);
    border-radius: 16px;
    background: var(--mh-ctrl-fill);
    font-family: var(--mh-font-head);
    font-size: 28px;
    font-weight: 700;
    color: var(--mh-ink);
    cursor: pointer;
    transition: background .12s, border-color .12s, transform .08s;
}

.pk-key:hover[b-tb360xytgj] {
    background: var(--mh-ctrl-fill-2);
    border-color: var(--mh-ctrl-focus-border);
}

.pk-key:active[b-tb360xytgj] {
    transform: scale(.96);
}

.pk-key:focus-visible[b-tb360xytgj] {
    outline: none;
    border-color: var(--mh-ctrl-focus-border);
    box-shadow: var(--mh-ctrl-focus-ring);
}

.pk-aux[b-tb360xytgj] {
    font-family: var(--mh-font-body);
    font-size: 16px;
    font-weight: 700;
    color: var(--mh-ctrl-ico);
}

.pk-msg[b-tb360xytgj] {
    text-align: center;
    min-height: 20px;
    margin-top: 18px;
    font-size: 14px;
    font-weight: 700;
    color: var(--mh-danger);
}

/* Error replays a one-shot horizontal shake (replaces the spent pop; pop is a
   mount-only animation, so by error time it has already finished). */
.pk-card.pk-shake[b-tb360xytgj] {
    animation: pkShake-b-tb360xytgj .42s cubic-bezier(.36, .07, .19, .97) both;
}

@keyframes pkFade-b-tb360xytgj {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes pkPop-b-tb360xytgj {
    from { opacity: 0; transform: translateY(8px) scale(.97); }
    to   { opacity: 1; transform: none; }
}

@keyframes pkShake-b-tb360xytgj {
    10%, 90%       { transform: translateX(-1px); }
    20%, 80%       { transform: translateX(2px); }
    30%, 50%, 70%  { transform: translateX(-6px); }
    40%, 60%       { transform: translateX(6px); }
}

/* Reduced motion: keep the danger message + state change, drop all motion. */
@media (prefers-reduced-motion: reduce) {
    .pk-ov[b-tb360xytgj],
    .pk-card[b-tb360xytgj],
    .pk-card.pk-shake[b-tb360xytgj] { animation: none; }
    .pk-dots span[b-tb360xytgj],
    .pk-key[b-tb360xytgj] { transition: none; }
}
