/* Admin / account portal — shares the client font + brand tokens (cool palette).
   C# mirror of these values lives in Common/BrandPalette.cs (MudTheme + ApexCharts
   can't read CSS vars). Change both together. */
:root {
    --lms-text: #050316;
    --lms-bg: #f7f7f7;
    --lms-primary: #e0eaf5;   /* light blue surfaces */
    --lms-lavender: #f1e8f3;  /* lavender tint — page chrome */
    --lms-lavender-soft: #faf7fb; /* half-strength lavender — panels sitting on the page tint */
    --lms-accent: #f15d39;    /* orange CTA */
    --lms-accent-edge: #c0431f; /* darker accent — 3D button bottom edge */
    --lms-accent-top: #ff8a63;  /* lighter accent — top stop of accent gradients */
    --lms-dark: #050316;      /* brand / primary button fill */
    --lms-dark-warm: #1c1442; /* violet-shifted dark — end stop of the dark panel gradient */
    --lms-dark-mid: #3f3576;  /* mid violet — chart bar top stop, secondary bar fills */
    --lms-pure-white: #f5f5f5; /* headings on the dark panels (softer than #fff) */
    --lms-ink: #080619;       /* portal sidebar — one step deeper than --lms-dark */
    --lms-ink-text: #cfcbdd;  /* default text on the ink sidebar */
    --lms-line: rgba(5, 3, 22, 0.12);
    --lms-line-light: rgba(5, 3, 22, 0.08);
    --lms-line-input: rgba(5, 3, 22, 0.20);
    --lms-muted: rgba(5, 3, 22, 0.55);
    --lms-faint: rgba(5, 3, 22, 0.40);
}

body {
    font-family: "Poppins", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* Set by PortalChrome while the mobile nav drawer is open, so the page behind it stays put.
   Global rather than isolated CSS: <body> is outside every component's scope. */
body.portal-noscroll {
    overflow: hidden;
}

/* ── Generic text utilities ─────────────────────────────────────────────── */
.text-accent {
    color: var(--lms-accent);
}

/* ── Auth / account page shell ─────────────────────────────────────────────
   Centered card used by Login, Register, password + email flows, 2fa, etc. */
.auth-wrapper {
    display: flex;
    min-height: 85vh;
    align-items: center;
    justify-content: center;
    padding: 2.5rem 1rem;
    font-family: "Poppins", ui-sans-serif, system-ui, sans-serif;
}

.auth-inner {
    width: 100%;
    max-width: 400px;
}

/* Wider variant for content-heavy pages (recovery codes, personal data, 2fa lists) */
.auth-inner--wide {
    max-width: 560px;
}

.auth-card {
    background: #ffffff;
    border: 1px solid rgba(5, 3, 22, 0.08);
    border-radius: 1.25rem;
    padding: 2rem;
    box-shadow: 0 20px 40px rgba(5, 3, 22, 0.06);
}

.auth-title {
    color: var(--lms-text);
    font-size: 1.5rem;
    font-weight: 700;
    text-align: center;
    margin: 0 0 0.25rem 0;
}

.auth-subtitle {
    color: var(--lms-muted);
    font-size: 0.875rem;
    font-weight: 400;
    text-align: center;
    margin: 0 0 1.5rem 0;
}

.auth-field {
    margin-bottom: 1rem;
}

.auth-field-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.375rem;
}

.auth-label {
    display: block;
    color: var(--lms-text);
    font-size: 0.875rem;
    font-weight: 500;
}

.auth-forgot,
.auth-link {
    color: var(--lms-muted);
    font-size: 0.75rem;
    text-decoration: none;
    transition: color 0.15s;
}

.auth-forgot:hover,
.auth-link:hover {
    color: var(--lms-text);
}

.auth-input {
    width: 100%;
    border: 1px solid rgba(5, 3, 22, 0.18);
    border-radius: 1rem;
    background: rgba(224, 234, 245, 0.25);
    padding: 0.8rem 1.1rem;
    font-size: 0.9rem;
    font-family: inherit;
    color: var(--lms-text);
    outline: none;
    transition: border-color 0.15s, box-shadow 0.15s;
    box-sizing: border-box;
    display: block;
}

.auth-input::placeholder {
    color: rgba(5, 3, 22, 0.3);
}

.auth-input:focus,
.auth-input:focus-visible {
    outline: none;
    border-color: rgba(5, 3, 22, 0.6);
    box-shadow: 0 0 0 3px rgba(5, 3, 22, 0.1), 0 1px 3px rgba(5, 3, 22, 0.06);
}

.auth-validation {
    color: #ef4444;
    font-size: 0.75rem;
    margin-top: 0.25rem;
    display: block;
}

.auth-remember {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 1.25rem;
}

.auth-remember input {
    width: 1rem;
    height: 1rem;
    border-radius: 0.25rem;
    accent-color: var(--lms-dark);
    cursor: pointer;
}

.auth-remember label {
    color: var(--lms-muted);
    font-size: 0.875rem;
    cursor: pointer;
}

/* Primary action — calm dark fill */
.auth-btn {
    width: 100%;
    background: var(--lms-dark);
    color: #f5f5f5;
    border: none;
    border-radius: 0.75rem;
    padding: 0.75rem 1rem;
    font-size: 0.875rem;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    transition: background 0.15s, filter 0.15s;
    text-align: center;
    text-decoration: none;
    display: block;
    box-sizing: border-box;
}

.auth-btn:hover {
    background: rgba(5, 3, 22, 0.85);
}

/* Accent action — orange, when a click needs pulling toward it */
.auth-btn--accent {
    background: var(--lms-accent);
    color: #ffffff;
}

.auth-btn--accent:hover {
    background: var(--lms-accent);
    filter: brightness(0.95);
}

/* Secondary / outline action */
.auth-btn-secondary {
    display: flex;
    width: 100%;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    border: 1.5px solid rgba(5, 3, 22, 0.25);
    border-radius: 0.75rem;
    padding: 0.7rem 1rem;
    font-size: 0.875rem;
    font-weight: 600;
    font-family: inherit;
    color: var(--lms-text);
    background: rgba(224, 234, 245, 0.4);
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s, border-color 0.15s;
    box-sizing: border-box;
}

.auth-btn-secondary:hover {
    background: rgba(224, 234, 245, 0.8);
    border-color: rgba(5, 3, 22, 0.4);
}

.auth-divider {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 1.25rem 0;
}

.auth-divider-line {
    flex: 1;
    border: none;
    border-top: 1px solid var(--lms-line);
}

.auth-divider-text {
    color: rgba(5, 3, 22, 0.4);
    font-size: 0.75rem;
}

.auth-footer {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid rgba(5, 3, 22, 0.1);
}

.auth-footer a {
    color: var(--lms-muted);
    font-size: 0.75rem;
    text-decoration: none;
    transition: color 0.15s;
}

.auth-footer a:hover {
    color: var(--lms-text);
}

/* Recovery codes / plain info lists */
.auth-code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    background: rgba(224, 234, 245, 0.5);
    border: 1px solid var(--lms-line);
    border-radius: 0.5rem;
    padding: 0.4rem 0.6rem;
    font-size: 0.85rem;
    color: var(--lms-text);
    display: inline-block;
}

/* ── Bootstrap primitives, branded only inside an auth card ────────────────
   Lets the default Identity scaffolds inherit the look just by being wrapped,
   without rewriting every input/button in their markup. */
.auth-card h1,
.auth-card h2 {
    color: var(--lms-text);
    text-align: center;
    font-weight: 700;
}

.auth-card h1 {
    font-size: 1.5rem;
    margin: 0 0 0.25rem 0;
}

.auth-card h2 {
    font-size: 0.9rem;
    font-weight: 400;
    color: var(--lms-muted);
    margin: 0 0 1.5rem 0;
}

.auth-card hr {
    border: none;
    border-top: 1px solid var(--lms-line);
    margin: 1.25rem 0;
}

.auth-card .row,
.auth-card [class^="col-"],
.auth-card [class*=" col-"] {
    width: 100%;
    max-width: 100%;
    flex: 0 0 100%;
    margin: 0;
    padding: 0;
}

.auth-card .form-floating {
    margin-bottom: 1rem;
}

.auth-card .form-control {
    width: 100%;
    border: 1px solid rgba(5, 3, 22, 0.18);
    border-radius: 1rem;
    background: rgba(224, 234, 245, 0.25);
    padding: 1rem 1.1rem;
    font-size: 0.9rem;
    color: var(--lms-text);
    box-sizing: border-box;
}

.auth-card .form-control:focus {
    outline: none;
    border-color: rgba(5, 3, 22, 0.6);
    box-shadow: 0 0 0 3px rgba(5, 3, 22, 0.1);
}

.auth-card .form-floating > label {
    color: var(--lms-muted);
    padding: 1rem 1.1rem;
}

.auth-card label,
.auth-card p {
    color: var(--lms-text);
}

.auth-card .btn {
    width: 100%;
    border-radius: 0.75rem;
    padding: 0.75rem 1rem;
    font-size: 0.875rem;
    font-weight: 600;
    cursor: pointer;
    box-shadow: none;
}

.auth-card .btn-primary,
.auth-card .btn-lg.btn-primary {
    background: var(--lms-dark);
    border-color: var(--lms-dark);
    color: #f5f5f5;
}

.auth-card .btn-primary:hover {
    background: rgba(5, 3, 22, 0.85);
    border-color: rgba(5, 3, 22, 0.85);
}

.auth-card .btn-danger {
    background: var(--lms-accent);
    border-color: var(--lms-accent);
    color: #ffffff;
}

.auth-card a {
    color: var(--lms-text);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.auth-card a:hover {
    color: var(--lms-accent);
}

/* Anchors styled as buttons must keep the button's text color, not the link color */
.auth-card a.auth-btn,
.auth-card a.auth-btn:hover {
    color: #f5f5f5;
    text-decoration: none;
}

.auth-card a.auth-btn--accent,
.auth-card a.auth-btn--accent:hover {
    color: #ffffff;
}

.auth-card a.auth-btn-secondary,
.auth-card a.auth-btn-secondary:hover {
    color: var(--lms-text);
    text-decoration: none;
}

.auth-card .alert {
    border-radius: 0.75rem;
    font-size: 0.8rem;
    padding: 0.75rem 1rem;
    border: none;
}

.auth-card .alert-danger {
    background: #fef2f2;
    color: #dc2626;
}

.auth-card .alert-success {
    background: rgba(224, 234, 245, 0.6);
    color: var(--lms-text);
}

.auth-card .text-danger,
.auth-card .validation-message {
    color: #ef4444;
    font-size: 0.75rem;
}

/* ── Manage account (settings dashboard) ───────────────────────────────────
   Sidebar-nav settings area used by the Account/Manage pages. Shares the same
   cool palette + Poppins as the auth cards, but laid out as a page heading +
   left nav menu + a content panel, not a single centered card. */
.manage-shell {
    max-width: 880px;
    margin: 0 auto;
    padding: 2.5rem 1rem 3.5rem;
    font-family: "Poppins", ui-sans-serif, system-ui, sans-serif;
}

.manage-title {
    color: var(--lms-text);
    font-size: 1.75rem;
    font-weight: 700;
    margin: 0 0 0.35rem 0;
}

.manage-subtitle {
    color: var(--lms-muted);
    font-size: 0.9rem;
    margin: 0 0 2rem 0;
}

.manage-layout {
    display: flex;
    gap: 1.5rem;
    align-items: flex-start;
}

.manage-nav {
    flex: 0 0 220px;
    background: #ffffff;
    border: 1px solid var(--lms-line);
    border-radius: 1rem;
    padding: 0.5rem;
    box-shadow: 0 10px 30px rgba(5, 3, 22, 0.04);
}

.manage-nav ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.manage-nav a {
    display: block;
    padding: 0.6rem 0.9rem;
    border-radius: 0.6rem;
    color: var(--lms-text);
    font-size: 0.875rem;
    font-weight: 500;
    text-decoration: none;
    transition: background 0.15s, color 0.15s;
}

.manage-nav a:hover {
    background: rgba(224, 234, 245, 0.55);
}

.manage-nav a.active {
    background: var(--lms-dark);
    color: #f5f5f5;
}

.manage-panel {
    flex: 1 1 auto;
    min-width: 0;
    background: #ffffff;
    border: 1px solid var(--lms-line);
    border-radius: 1rem;
    padding: 2rem;
    box-shadow: 0 20px 40px rgba(5, 3, 22, 0.06);
}

@media (max-width: 767px) {
    .manage-layout {
        flex-direction: column;
    }

    .manage-nav {
        flex-basis: auto;
        width: 100%;
    }

    .manage-nav ul {
        flex-direction: row;
        flex-wrap: wrap;
    }
}

/* Section headings inside the panel */
.manage-panel h3,
.manage-panel h4 {
    color: var(--lms-text);
    font-weight: 700;
    margin: 0 0 1rem 0;
}

.manage-panel h3 {
    font-size: 1.25rem;
}

.manage-panel h4 {
    font-size: 1rem;
    margin-top: 1.5rem;
}

.manage-panel hr {
    border: none;
    border-top: 1px solid var(--lms-line);
    margin: 1.25rem 0;
}

.manage-panel p {
    color: var(--lms-text);
    font-size: 0.9rem;
}

.manage-lead {
    color: var(--lms-muted);
    font-size: 0.9rem;
    margin-bottom: 1.25rem;
}

/* Branded Bootstrap primitives, scoped to the panel — lets the default
   Identity scaffolds inherit the look just by living inside .manage-panel. */
.manage-panel .row,
.manage-panel [class^="col-"],
.manage-panel [class*=" col-"] {
    width: 100%;
    max-width: 100%;
    flex: 0 0 100%;
    margin: 0;
    padding: 0;
}

.manage-panel .form-floating {
    margin-bottom: 1rem;
}

.manage-panel .form-control {
    width: 100%;
    border: 1px solid rgba(5, 3, 22, 0.18);
    border-radius: 1rem;
    background: rgba(224, 234, 245, 0.25);
    padding: 1rem 1.1rem;
    font-size: 0.9rem;
    color: var(--lms-text);
    box-sizing: border-box;
}

.manage-panel .form-control:focus {
    outline: none;
    border-color: rgba(5, 3, 22, 0.6);
    box-shadow: 0 0 0 3px rgba(5, 3, 22, 0.1);
}

.manage-panel .form-control:disabled {
    background: rgba(5, 3, 22, 0.04);
    color: var(--lms-muted);
}

.manage-panel .form-floating > label {
    color: var(--lms-muted);
    padding: 1rem 1.1rem;
}

.manage-panel label {
    color: var(--lms-text);
}

.manage-panel .btn {
    border-radius: 0.75rem;
    padding: 0.65rem 1.2rem;
    font-size: 0.875rem;
    font-weight: 600;
    cursor: pointer;
    box-shadow: none;
    margin: 0 0.25rem 0.25rem 0;
}

.manage-panel .btn.w-100 {
    margin-right: 0;
}

.manage-panel .btn-primary,
.manage-panel .btn-lg.btn-primary {
    background: var(--lms-dark);
    border-color: var(--lms-dark);
    color: #f5f5f5;
}

.manage-panel .btn-primary:hover {
    background: rgba(5, 3, 22, 0.85);
    border-color: rgba(5, 3, 22, 0.85);
}

/* Destructive / danger — orange */
.manage-panel .btn-danger {
    background: var(--lms-accent);
    border-color: var(--lms-accent);
    color: #ffffff;
}

.manage-panel .btn-danger:hover {
    background: var(--lms-accent);
    border-color: var(--lms-accent);
    filter: brightness(0.95);
}

.manage-panel .btn-link {
    background: none;
    border: none;
    color: var(--lms-text);
    text-decoration: underline;
    text-underline-offset: 2px;
    padding: 0.35rem 0;
    font-weight: 500;
}

.manage-panel .btn-link:hover {
    color: var(--lms-accent);
}

.manage-panel a:not(.btn) {
    color: var(--lms-text);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.manage-panel a:not(.btn):hover {
    color: var(--lms-accent);
}

.manage-panel .table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9rem;
}

.manage-panel .table td,
.manage-panel .table th {
    padding: 0.75rem 0.5rem;
    border-bottom: 1px solid var(--lms-line);
    color: var(--lms-text);
    vertical-align: middle;
}

.manage-panel .alert {
    border-radius: 0.75rem;
    font-size: 0.85rem;
    padding: 0.85rem 1.1rem;
    border: none;
}

.manage-panel .alert p {
    margin-bottom: 0.35rem;
}

.manage-panel .alert p:last-child {
    margin-bottom: 0;
}

.manage-panel .alert-warning {
    background: rgba(241, 93, 57, 0.1);
    color: var(--lms-text);
}

.manage-panel .alert-danger {
    background: #fef2f2;
    color: #dc2626;
}

.manage-panel .alert-info {
    background: rgba(224, 234, 245, 0.6);
    color: var(--lms-text);
}

.manage-panel .alert-success {
    background: rgba(224, 234, 245, 0.6);
    color: var(--lms-text);
}

.manage-panel .text-danger,
.manage-panel .validation-message {
    color: #ef4444;
    font-size: 0.75rem;
}

.manage-panel .text-info {
    color: var(--lms-muted);
}

.manage-panel kbd {
    background: rgba(224, 234, 245, 0.6);
    border: 1px solid var(--lms-line);
    border-radius: 0.4rem;
    padding: 0.2rem 0.45rem;
    color: var(--lms-text);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

.manage-panel .recovery-code {
    display: inline-block;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    background: rgba(224, 234, 245, 0.5);
    border: 1px solid var(--lms-line);
    border-radius: 0.5rem;
    padding: 0.4rem 0.6rem;
    font-size: 0.85rem;
    color: var(--lms-text);
    margin: 0.2rem 0;
}

/* ── Framework defaults (kept) ─────────────────────────────────────────────*/
h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

/* ══════════════════════════════════════════════════════════════════════════
   Portal UI primitives (.pui-*) — the Partner Portaal design's shared kit
   (admin/portal-ui.jsx), translated to plain CSS.

   Global rather than isolated: every portal page needs the same buttons, pills
   and table chrome, and CSS isolation is per-component. Hand-written rather
   than Tailwind for the same reason as the dashboard — portal pages load
   MudBlazor's stylesheet and Tailwind's preflight would reset the baseline it
   depends on.

   Design token → portal token:
     secondary  → --lms-dark        quaternary → --lms-accent
     blue       → --lms-primary     lavender   → --lms-lavender
     cream      → --lms-bg
   ══════════════════════════════════════════════════════════════════════════ */

.pui-page {
    padding-bottom: 40px;
    /* No entrance animation: Blazor replaces this island's DOM on the prerender->interactive
       handoff, which replays the animation and reads as a "double render" flash. Pages without
       an animation (e.g. the dashboard's .db) swap invisibly. Keep this element animation-free. */
}

@keyframes pui-fade-up {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .pui-page {
        animation: none;
    }
}

/* ── Page heading ───────────────────────────────────────────────────────── */
.pui-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .18em;
    color: var(--lms-accent);
}

.pui-head {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-bottom: 20px;
}

.pui-head-main {
    min-width: 0;
}

.pui-head-title {
    margin: 4px 0 0;
    font-family: "Fraunces", ui-serif, Georgia, serif;
    font-size: 26px;
    font-weight: 500;
    line-height: 1.2;
    color: var(--lms-dark);
}

.pui-head-italic {
    font-style: italic;
    color: var(--lms-accent);
}

.pui-head-sub {
    margin: 2px 0 0;
    font-size: 13.5px;
    color: var(--lms-muted);
}

/* On phones the row is split evenly — two buttons take half each, filling the width. Back to
   content-width buttons from sm. */
.pui-head-actions {
    display: flex;
    align-items: stretch;
    gap: 8px;
    flex-shrink: 0;
}

.pui-head-actions > * {
    flex: 1 1 0;
    min-width: 0;
}

/* ── Buttons ────────────────────────────────────────────────────────────── */
/* The 3px bottom edge is part of every variant's box, transparent unless a variant colours it.
   Otherwise the primary button stands 3px taller than the ghost button beside it. */
.pui-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    border: 0 solid transparent;
    border-bottom-width: 3px;
    border-radius: 12px;
    padding: 10px 16px;
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    transition: filter .15s ease, background .15s ease, box-shadow .15s ease, color .15s ease;
}

.pui-btn:disabled {
    opacity: .4;
    cursor: not-allowed;
}

/* For a <label> that acts as a button — one pointing at a hidden file input, say. `disabled` does nothing on a
   label, and the click would still reach the input and open the picker, so pointer events are what has to go.
   Pair it with aria-disabled in the markup: this rule is the behaviour, not the announcement. */
.pui-btn.is-disabled {
    opacity: .4;
    cursor: not-allowed;
    pointer-events: none;
}

.pui-btn--sm {
    padding: 8px 12px;
    font-size: 12.5px;
}

.pui-btn--primary {
    background: var(--lms-accent);
    color: #ffffff;
    border-bottom-color: var(--lms-accent-edge);
}

.pui-btn--dark {
    background: var(--lms-dark);
    color: #ffffff;
    border-bottom-color: #000000;
}

/* Colour only — clearing the width here would resize the button. */
.pui-btn--primary:disabled,
.pui-btn--dark:disabled {
    border-bottom-color: transparent;
}

.pui-btn--danger {
    background: #e11d48;
    color: #ffffff;
    border-bottom-color: #9f1239;
}

/* Darker ring + its own bottom edge, so it reads as a sibling of the primary button rather than a
   washed-out white rectangle next to it. */
.pui-btn--ghost {
    background: #ffffff;
    color: var(--lms-dark);
    border-bottom-color: var(--lms-line-input);
    box-shadow: inset 0 0 0 1px var(--lms-line-input);
}

/* Square action button used inside table rows. */
.pui-iconbtn {
    display: flex;
    height: 32px;
    width: 32px;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 8px;
    background: #ffffff;
    padding: 0;
    color: var(--lms-muted);
    cursor: pointer;
    box-shadow: inset 0 0 0 1px var(--lms-line);
    transition: color .15s ease, background .15s ease, box-shadow .15s ease;
}

.pui-iconbtn:disabled {
    opacity: .3;
    cursor: not-allowed;
}

/* Filled confirm action — used where accept and reject sit side by side and the pair has to read
   as opposites rather than as two neutral icons. */
.pui-iconbtn--ok {
    background: #10b981;
    color: #ffffff;
    box-shadow: none;
    border-bottom: 2px solid #047857;
}

/* An action that still has to happen before the form can be submitted — amber rather than neutral, so a
   required step does not look like an optional one. */
.pui-iconbtn--todo {
    background: #fffbeb;
    color: #b45309;
    box-shadow: inset 0 0 0 1px #fde68a;
}

@media (hover: hover) {
    .pui-btn--primary:hover:not(:disabled) { filter: brightness(1.05); }
    .pui-btn--dark:hover:not(:disabled)    { filter: brightness(1.25); }
    .pui-btn--danger:hover:not(:disabled)  { filter: brightness(1.08); }

    .pui-btn--ghost:hover:not(:disabled) {
        background: var(--lms-primary);
        box-shadow: inset 0 0 0 1px var(--lms-line-input);
    }

    .pui-iconbtn:hover:not(:disabled) {
        color: var(--lms-dark);
        box-shadow: inset 0 0 0 1px var(--lms-line-input);
    }

    .pui-iconbtn--ok:hover:not(:disabled) {
        background: #059669;
        color: #ffffff;
        box-shadow: none;
    }

    .pui-iconbtn--no:hover:not(:disabled) {
        background: #fff1f2;
        color: #be123c;
        box-shadow: inset 0 0 0 1px #fecdd3;
    }
}

/* ── Surfaces ───────────────────────────────────────────────────────────── */
.pui-card {
    border-radius: 16px;
    background: #ffffff;
    box-shadow: 0 0 0 1px var(--lms-line-light);
}

/* ── Section card header/body ────────────────────────────────────────────────
   The design's Section (admin/centra.jsx): a .pui-card with an eyebrow + optional subtitle in a
   bordered header and the form below. Additive to the kit — nothing existing renders these. */
.pui-sec-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    border-bottom: 1px solid var(--lms-line-light);
    padding: 14px 20px;
}

.pui-sec-head-main {
    min-width: 0;
}

.pui-sec-sub {
    margin: 4px 0 0;
    font-size: 12.5px;
    color: var(--lms-muted);
}

.pui-sec-body {
    padding: 20px;
}

/* ── Radio option list ──────────────────────────────────────────────────────
   The design's StatusPicker: one option per row, each with a title and an explanation. A button
   rather than an <input type=radio> because the whole card is the target; the group carries
   role="radiogroup" and each button aria-checked. */
.pui-radios {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.pui-radio {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    border: none;
    border-radius: 12px;
    background: #ffffff;
    padding: 12px 16px;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    box-shadow: inset 0 0 0 1px var(--lms-line-light);
    transition: box-shadow .15s ease;
}

.pui-radio.active {
    box-shadow: inset 0 0 0 2px var(--lms-accent);
}

.pui-radio-dot {
    display: flex;
    height: 16px;
    width: 16px;
    flex-shrink: 0;
    margin-top: 2px;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    box-shadow: inset 0 0 0 1px var(--lms-line-input);
}

.pui-radio.active .pui-radio-dot {
    background: var(--lms-accent);
    box-shadow: none;
}

.pui-radio-dot span {
    height: 6px;
    width: 6px;
    border-radius: 999px;
    background: #ffffff;
}

.pui-radio-body {
    min-width: 0;
}

.pui-radio-title {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--lms-dark);
}

.pui-radio-sub {
    font-size: 12.5px;
    color: var(--lms-muted);
}

@media (hover: hover) {
    .pui-radio:hover:not(.active) {
        box-shadow: inset 0 0 0 1px var(--lms-line-input);
    }
}

/* ── Label/value row ────────────────────────────────────────────────────────
   The design's Row: a label on the left, the value right-aligned, hairline between rows. Used for
   the create wizard's recap and read-only detail blocks. */
.pui-drow {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    border-bottom: 1px solid var(--lms-line-light);
    padding: 10px 0;
}

.pui-drow:last-child {
    border-bottom: 0;
}

.pui-drow-label {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    color: var(--lms-muted);
}

.pui-drow-label svg {
    flex-shrink: 0;
    color: var(--lms-faint);
}

.pui-drow-value {
    min-width: 0;
    text-align: right;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--lms-dark);
    overflow-wrap: anywhere;
}

.pui-drow-value--num {
    font-variant-numeric: tabular-nums;
}

.pui-drow-value--empty {
    font-weight: 400;
    font-style: italic;
    color: var(--lms-faint);
}

/* ── Stat strip ─────────────────────────────────────────────────────────── */
/* Two per row on phones: wrapping flex left an uneven 3+1 with a ragged gap. From sm there is room
   for a single line, so it goes back to flex.
   justify-items: start keeps each stat against the left of its cell rather than floating in the
   middle of it — only the figure is centred, and that happens inside .pui-stat. */
.pui-statstrip {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: center;
    justify-items: start;
    gap: 12px 16px;
    border-radius: 16px;
    background: #ffffff;
    box-shadow: 0 0 0 1px var(--lms-line-light);
    padding: 14px 20px;
    margin-bottom: 16px;
}

/* Figure to the left of its label, on a shared baseline, at every width. */
/* Centred, not baseline-aligned: the figure and its label differ enough in size that a shared
   baseline leaves the label sitting visibly low. Both sides carry line-height 1 so each box hugs
   its text — otherwise the label's ascender/descender space re-introduces the same offset. */
.pui-stat {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Poppins, not the display serif: these are figures to be read at a glance, and Fraunces'
   numerals get muddy at this size. */
.pui-stat-value {
    font-size: 20px;
    font-weight: 700;
    line-height: 1;
    color: var(--lms-dark);
    font-variant-numeric: tabular-nums;
}

.pui-stat-value--muted { color: var(--lms-muted); }
.pui-stat-value--accent { color: var(--lms-accent); }

.pui-stat-label {
    font-size: 12px;
    line-height: 1;
    color: var(--lms-muted);
}

/* ── Filter chips ───────────────────────────────────────────────────────── */
.pui-chips {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    margin: 0 -4px;
    padding: 0 4px;
    -ms-overflow-style: none;
    scrollbar-width: none;
}

.pui-chips::-webkit-scrollbar {
    display: none;
}

.pui-chip {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    gap: 6px;
    border: none;
    border-radius: 12px;
    background: #ffffff;
    padding: 8px 12px;
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--lms-muted);
    cursor: pointer;
    box-shadow: inset 0 0 0 1px var(--lms-line-light);
    transition: color .15s ease, background .15s ease, box-shadow .15s ease;
}

.pui-chip.active {
    background: var(--lms-dark);
    color: #ffffff;
    box-shadow: none;
}

/* Plain .pui-chip carries no disabled look of its own (no chip is ever disabled elsewhere) — a
   bulk-delete chip needs one for when there is nothing to delete. */
.pui-chip:disabled {
    opacity: .4;
    cursor: not-allowed;
}

.pui-chip-count {
    border-radius: 999px;
    background: var(--lms-primary);
    padding: 0 6px;
    font-size: 11px;
    font-weight: 700;
    color: var(--lms-muted);
    font-variant-numeric: tabular-nums;
}

.pui-chip.active .pui-chip-count {
    background: rgba(255, 255, 255, .15);
    color: #ffffff;
}

@media (hover: hover) {
    .pui-chip:hover:not(.active):not(:disabled) {
        color: var(--lms-dark);
        box-shadow: inset 0 0 0 1px var(--lms-line);
    }
}

/* ── Inputs (filter row) ────────────────────────────────────────────────── */
.pui-search {
    display: flex;
    align-items: center;
    gap: 8px;
    border: none;
    border-radius: 12px;
    background: #ffffff;
    padding: 8px 12px;
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--lms-muted);
    box-shadow: inset 0 0 0 1px var(--lms-line-light);
    transition: box-shadow .15s ease;
}

.pui-search:focus-within {
    outline: none;
    box-shadow: inset 0 0 0 1px rgba(241, 93, 57, .4);
}

.pui-search input {
    min-width: 0;
    flex: 1;
    border: none;
    background: transparent;
    padding: 0;
    font-family: inherit;
    font-size: 12.5px;
    color: var(--lms-dark);
    outline: none;
}

.pui-search input::placeholder {
    color: var(--lms-faint);
}

/* ── Custom dropdown (PortalSelect) ─────────────────────────────────────── */
/* min-width:0 so it can shrink inside a flex row — a flex item won't go below its content's
   min-content width by default, and the trigger's label is nowrap. */
.pui-dd {
    position: relative;
    min-width: 0;
}

/* height:100% so the trigger fills a stretched flex cell and matches whatever sits beside it. */
.pui-dd-trigger {
    display: flex;
    width: 100%;
    height: 100%;
    align-items: center;
    gap: 8px;
    border: none;
    border-radius: 12px;
    background: #ffffff;
    padding: 8px 12px;
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--lms-muted);
    cursor: pointer;
    box-shadow: inset 0 0 0 1px var(--lms-line-light);
    transition: box-shadow .15s ease, color .15s ease;
}

.pui-dd-trigger.open {
    color: var(--lms-dark);
    box-shadow: inset 0 0 0 1px var(--lms-line-input);
}

.pui-dd-trigger-icon {
    flex-shrink: 0;
    color: var(--lms-faint);
}

.pui-dd-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-align: left;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pui-dd-chevron {
    flex-shrink: 0;
    color: var(--lms-faint);
    transition: transform .2s ease;
}

.pui-dd-trigger.open .pui-dd-chevron {
    transform: rotate(180deg);
}

/* Catches the outside click. Transparent, and under the panel. */
.pui-dd-backdrop {
    position: fixed;
    inset: 0;
    z-index: 30;
}

/* Opens rightwards from the trigger's left edge. Anchoring right meant a narrow trigger sitting
   near the left of the row threw the panel past the container's left edge, where .portal-container's
   overflow-x: clip cut it off. */
.pui-dd-panel {
    position: absolute;
    z-index: 31;
    top: calc(100% + 6px);
    left: 0;
    min-width: 100%;
    width: max-content;
    max-width: 220px;
    overflow: hidden;
    border-radius: 12px;
    background: #ffffff;
    box-shadow: 0 0 0 1px var(--lms-line-light), 0 18px 30px -12px rgba(5, 3, 22, .25);
}

/* Searchable variant (PortalCenterSwitch): a filter box pinned above the option list, which then
   scrolls on its own so a long center list doesn't push the panel off-screen. */
.pui-dd-panel--searchable {
    max-height: 320px;
    overflow-y: auto;
}

.pui-dd-search {
    position: sticky;
    top: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 8px;
    background: #ffffff;
    padding: 10px 14px;
    border-bottom: 1px solid var(--lms-line-light);
    color: var(--lms-faint);
}

.pui-dd-search input {
    min-width: 0;
    flex: 1;
    border: none;
    background: transparent;
    padding: 0;
    font-family: inherit;
    font-size: 12.5px;
    color: var(--lms-dark);
    outline: none;
}

.pui-dd-search input::placeholder {
    color: var(--lms-faint);
}

.pui-dd-empty {
    padding: 10px 14px;
    font-size: 12.5px;
    color: var(--lms-faint);
}

.pui-dd-option {
    display: flex;
    width: 100%;
    align-items: center;
    gap: 10px;
    border: none;
    background: transparent;
    padding: 10px 14px;
    font-family: inherit;
    font-size: 13px;
    text-align: left;
    color: var(--lms-muted);
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
}

.pui-dd-option.active {
    background: rgba(224, 234, 245, .7);
    font-weight: 600;
    color: var(--lms-dark);
}

.pui-dd-option-icon {
    flex-shrink: 0;
    color: var(--lms-faint);
}

.pui-dd-option.active .pui-dd-option-icon,
.pui-dd-check {
    flex-shrink: 0;
    color: var(--lms-accent);
}

.pui-dd-option-label {
    flex: 1;
    min-width: 0;
}

@media (hover: hover) {
    .pui-dd-trigger:hover {
        color: var(--lms-dark);
        box-shadow: inset 0 0 0 1px var(--lms-line);
    }

    .pui-dd-option:hover:not(.active) {
        background: rgba(224, 234, 245, .4);
        color: var(--lms-dark);
    }
}

/* ── Toggle ─────────────────────────────────────────────────────────────── */
.pui-toggle {
    position: relative;
    height: 24px;
    width: 44px;
    flex-shrink: 0;
    border: none;
    border-radius: 999px;
    background: rgba(5, 3, 22, .2);
    padding: 0;
    cursor: pointer;
    transition: background .2s ease;
}

.pui-toggle.on {
    background: #10b981;
}

.pui-toggle:disabled {
    opacity: .45;
    cursor: not-allowed;
}

.pui-toggle::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    height: 20px;
    width: 20px;
    border-radius: 999px;
    background: #ffffff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .2);
    transition: transform .2s ease;
}

.pui-toggle.on::after {
    transform: translateX(20px);
}

/* ── Status pills ───────────────────────────────────────────────────────── */
.pui-pill {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    gap: 5px;
    border-radius: 999px;
    padding: 4px 10px;
    font-size: 11.5px;
    font-weight: 600;
    white-space: nowrap;
}

.pui-pill::before {
    content: "";
    height: 6px;
    width: 6px;
    border-radius: 999px;
    background: currentColor;
    opacity: .7;
}

.pui-pill--active {
    background: #ecfdf5;
    color: #047857;
    box-shadow: inset 0 0 0 1px #a7f3d0;
}

.pui-pill--pending {
    background: #fffbeb;
    color: #b45309;
    box-shadow: inset 0 0 0 1px #fde68a;
}

.pui-pill--rejected {
    background: #fff1f2;
    color: #be123c;
    box-shadow: inset 0 0 0 1px #fecdd3;
}

.pui-pill--booked {
    background: var(--lms-lavender);
    color: var(--lms-muted);
    box-shadow: inset 0 0 0 1px var(--lms-line);
}

.pui-pill--expired {
    background: var(--lms-line-light);
    color: var(--lms-faint);
    box-shadow: inset 0 0 0 1px var(--lms-line);
}

/* ── Price tag ──────────────────────────────────────────────────────────── */
.pui-price {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    border-radius: 12px;
    background: #ffffff;
    /* Same soft 1px inset border every other pill/chip in this kit uses (.pui-pill--booked etc.)
       instead of a hard 2px border — the design's own border-2 border-secondary read as too heavy. */
    box-shadow: inset 0 0 0 1px var(--lms-line), 0 1px 2px rgba(5, 3, 22, .05);
    padding: 4px 10px;
    line-height: 1.1;
}

.pui-price-orig {
    font-size: 10px;
    color: var(--lms-faint);
    text-decoration: line-through;
}

.pui-price-now {
    font-size: 14px;
    font-weight: 700;
    color: var(--lms-dark);
    font-variant-numeric: tabular-nums;
}

/* ── Category chip ──────────────────────────────────────────────────────── */
.pui-cat {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border-radius: 8px;
    background: var(--lms-primary);
    padding: 4px 8px;
    font-size: 11px;
    font-weight: 500;
    color: var(--lms-muted);
}

.pui-cat svg {
    flex-shrink: 0;
    color: var(--lms-accent);
}

/* ── Modal ──────────────────────────────────────────────────────────────────
   z-index sits above the portal chrome (topbar 1080, sidebar 1100) but below MudBlazor's dialog
   layer (1400), so a MudDialog opened on top of one — the delete confirmation — still wins. */
.pui-modal {
    position: fixed;
    inset: 0;
    z-index: 1300;
    display: flex;
    align-items: flex-end;
    justify-content: center;
}

.pui-modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(5, 3, 22, .55);
    backdrop-filter: blur(2px);
}

/* Bottom sheet on phones, centred card from sm up. */
.pui-modal-panel {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    max-height: 92dvh;
    border-radius: 24px 24px 0 0;
    background: var(--lms-bg);
    box-shadow: 0 0 0 1px var(--lms-line-light), 0 25px 50px -12px rgba(5, 3, 22, .4);
}

/* Dashboard tour on a phone (DashboardTourHost, onboarding-tour.js toggles the class on <html>):
   the tour's tooltip is itself a bottom sheet, --dth-sheet-h tall, which would cover a modal's
   own bottom sheet exactly where it starts. So while the tour runs the modal stands on top of
   the tooltip instead — lifted by the sheet's height, capped to the space left, fully rounded —
   and its body scrolls. Global rather than in the tour's scoped CSS because the modal is not
   the tour's own markup. */
:root {
    --dth-sheet-h: 236px;
}

@media (max-width: 767px) {
    /* Room to scroll past the end of the page: without it, anything in the last sheet-height of
       a short page (the only row of an otherwise empty list) can never be scrolled up out from
       under the sheet — the page's scroll range simply ends there. */
    html.dth-tour-on body {
        padding-bottom: var(--dth-sheet-h);
    }

    html.dth-tour-on .pui-modal {
        padding: 16px 8px var(--dth-sheet-h);
    }

    html.dth-tour-on .pui-modal-panel {
        max-height: 100%;
        border-radius: 24px;
    }
}

.pui-modal-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-shrink: 0;
    border-bottom: 1px solid var(--lms-line-light);
    padding: 16px 20px;
}

.pui-modal-title {
    margin: 2px 0 0;
    font-family: "Fraunces", ui-serif, Georgia, serif;
    font-size: 21px;
    font-weight: 600;
    line-height: 1.2;
    color: var(--lms-dark);
}

.pui-modal-body {
    flex: 1;
    overflow-y: auto;
    padding: 20px;
}

/* Same treatment as the page header actions: split evenly across the width on phones. */
.pui-modal-foot {
    display: flex;
    align-items: stretch;
    gap: 8px;
    flex-shrink: 0;
    border-top: 1px solid var(--lms-line-light);
    padding: 16px 20px;
}

.pui-modal-foot > * {
    flex: 1 1 0;
    min-width: 0;
}

/* ── Form fields ────────────────────────────────────────────────────────── */
.pui-form {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.pui-form-grid2 {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
}

.pui-field-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 6px;
}

.pui-field-label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--lms-muted);
}

.pui-field-label svg {
    flex-shrink: 0;
    color: var(--lms-accent);
}

.pui-field-count {
    font-size: 11px;
    color: var(--lms-faint);
    font-variant-numeric: tabular-nums;
}

.pui-field-count.near {
    color: var(--lms-accent);
}

.pui-input {
    display: flex;
    align-items: center;
    overflow: hidden;
    border: 1px solid var(--lms-line-input);
    border-radius: 12px;
    background: #ffffff;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.pui-input:focus-within {
    border-color: var(--lms-accent);
    box-shadow: 0 0 0 2px rgba(241, 93, 57, .15);
}

.pui-input input,
.pui-input select,
.pui-textarea {
    width: 100%;
    min-width: 0;
    flex: 1;
    border: none;
    background: transparent;
    padding: 11px 14px;
    font-family: inherit;
    font-size: 14px;
    color: var(--lms-dark);
    outline: none;
}

.pui-input input::placeholder,
.pui-textarea::placeholder {
    color: var(--lms-faint);
}

.pui-textarea {
    display: block;
    border: 1px solid var(--lms-line-input);
    border-radius: 12px;
    background: #ffffff;
    line-height: 1.6;
    resize: vertical;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.pui-textarea:focus {
    border-color: var(--lms-accent);
    box-shadow: 0 0 0 2px rgba(241, 93, 57, .15);
}

.pui-input-affix {
    flex-shrink: 0;
    padding: 0 14px;
    font-size: 13px;
    font-weight: 500;
    color: var(--lms-faint);
}

/* Leading icon inside a field — the globe on a website URL, say. Icon counterpart of the text affix,
   and it sits before the input so the input's own left padding becomes the gap. */
.pui-input-icon {
    flex-shrink: 0;
    margin-left: 14px;
    color: var(--lms-faint);
}

.pui-field-hint {
    margin: 6px 0 0;
    font-size: 11.5px;
    color: var(--lms-muted);
}

/* ── Date / time pickers ────────────────────────────────────────────────────
   The panel is a small centred overlay, not a panel in the flow and not an absolute popover:
   in-flow pushes the whole form down as it opens, and absolute gets clipped by .pui-modal-body's
   overflow-y: auto. A fixed overlay needs no JS positioning and can't be clipped by anything. */
.pui-picker-trigger {
    display: flex;
    width: 100%;
    align-items: center;
    gap: 8px;
    border: 1px solid var(--lms-line-input);
    border-radius: 12px;
    background: #ffffff;
    padding: 11px 14px;
    font-family: inherit;
    font-size: 14px;
    text-align: left;
    color: var(--lms-dark);
    cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.pui-picker-trigger.open {
    border-color: var(--lms-accent);
    box-shadow: 0 0 0 2px rgba(241, 93, 57, .15);
}

.pui-picker-value {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.pui-picker-value.empty {
    color: var(--lms-faint);
}

.pui-picker-trigger svg {
    flex-shrink: 0;
    color: var(--lms-faint);
}

/* Above PortalModal (1300) so it floats over the form it belongs to. */
.pui-pickpop {
    position: fixed;
    inset: 0;
    z-index: 1320;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
}

.pui-pickpop-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(5, 3, 22, .35);
}

/* 288px = the client CustomDatePicker's w-72, so the calendar reads identically. */
.pui-pickpop-panel {
    position: relative;
    width: 100%;
    max-width: 288px;
    max-height: 86dvh;
    overflow-y: auto;
    border-radius: 16px;
    background: #ffffff;
    padding: 14px;
    box-shadow: 0 0 0 1px var(--lms-line-light), 0 25px 50px -12px rgba(5, 3, 22, .4);
}

.pui-pickpop-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
}

.pui-pickpop-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--lms-dark);
}

.pui-pickpop-head-actions {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* "Wissen" text button — same treatment as the calendar's, which is where it started. */
.pui-pickpop-clear {
    border: none;
    background: transparent;
    padding: 4px 2px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 500;
    color: var(--lms-faint);
    cursor: pointer;
    transition: color .15s ease;
}

/* Calendar */
.pui-cal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 10px;
}

.pui-cal-nav {
    display: flex;
    align-items: center;
    gap: 2px;
}

.pui-cal-navbtn {
    display: flex;
    height: 28px;
    width: 28px;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--lms-dark);
    cursor: pointer;
    transition: background .15s ease;
}

/* PortalIcon has no chevronLeft — the previous-month arrow is chevronRight, flipped. */
.pui-cal-prev {
    transform: rotate(180deg);
}

.pui-cal-month {
    min-width: 128px;
    text-align: center;
    font-size: 14px;
    font-weight: 600;
    color: var(--lms-dark);
    text-transform: capitalize;
}

.pui-cal-clear {
    border: none;
    background: transparent;
    padding: 4px 2px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 500;
    color: var(--lms-faint);
    cursor: pointer;
    transition: color .15s ease;
}

.pui-cal-dows,
.pui-cal-grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 1px;
}

.pui-cal-dows {
    margin-bottom: 2px;
    text-align: center;
    font-size: 12px;
    font-weight: 500;
    color: var(--lms-faint);
}

.pui-cal-day {
    width: 100%;
    border: none;
    border-radius: 8px;
    background: transparent;
    padding: 8px 0;
    font-family: inherit;
    font-size: 13px;
    text-align: center;
    color: var(--lms-dark);
    cursor: pointer;
    font-variant-numeric: tabular-nums;
    transition: background .15s ease, color .15s ease;
}

.pui-cal-day.other {
    color: var(--lms-faint);
}

/* Out of range (a picker with Min set, e.g. no past dates on a new last minute). */
.pui-cal-day:disabled {
    color: var(--lms-faint);
    cursor: not-allowed;
    text-decoration: line-through;
}

/* Ring rather than fill, so "today" never reads as the selection. */
.pui-cal-day.today {
    box-shadow: inset 0 0 0 1px var(--lms-accent);
}

.pui-cal-day.selected {
    background: var(--lms-dark);
    font-weight: 600;
    color: #ffffff;
    box-shadow: none;
}

/* Time — the familiar two-column scroller: hours on the left, minutes on the right. */
.pui-timewheel {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: start;
    gap: 8px;
}

.pui-timewheel-label {
    margin-bottom: 6px;
    text-align: center;
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .14em;
    color: var(--lms-faint);
}

.pui-timewheel-sep {
    align-self: center;
    padding-top: 18px;
    font-size: 18px;
    font-weight: 700;
    color: var(--lms-faint);
}

.pui-timewheel-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
    height: 208px;
    overflow-y: auto;
    scroll-behavior: smooth;
    border-radius: 10px;
    background: var(--lms-bg);
    padding: 4px;
    -ms-overflow-style: none;
    scrollbar-width: none;
}

.pui-timewheel-list::-webkit-scrollbar {
    display: none;
}

.pui-time-opt {
    flex-shrink: 0;
    border: none;
    border-radius: 8px;
    background: transparent;
    padding: 9px 0;
    font-family: inherit;
    font-size: 14px;
    color: var(--lms-dark);
    cursor: pointer;
    font-variant-numeric: tabular-nums;
    transition: background .15s ease, color .15s ease;
}

.pui-time-opt.selected {
    background: var(--lms-dark);
    font-weight: 700;
    color: #ffffff;
}

.pui-timewheel-preview {
    margin-top: 12px;
    text-align: center;
    font-size: 20px;
    font-weight: 700;
    color: var(--lms-dark);
    font-variant-numeric: tabular-nums;
}

.pui-pickpop-confirm {
    width: 100%;
    margin-top: 10px;
}

@media (hover: hover) {
    .pui-picker-trigger:hover:not(.open),
    .pui-cal-navbtn:hover {
        border-color: var(--lms-line-input);
        background: var(--lms-primary);
    }

    .pui-cal-clear:hover,
    .pui-pickpop-clear:hover {
        color: var(--lms-dark);
    }

    .pui-cal-day:hover:not(.selected):not(:disabled),
    .pui-time-opt:hover:not(.selected) {
        background: var(--lms-primary);
    }
}

/* ── Choice grid (category picker) ──────────────────────────────────────── */
.pui-choices {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
}

/* One per row — for lists where the label is a full name rather than a short category. */
.pui-choices--stack {
    grid-template-columns: minmax(0, 1fr);
}

.pui-choice {
    display: flex;
    align-items: center;
    gap: 8px;
    border: none;
    border-radius: 12px;
    background: #ffffff;
    padding: 10px 12px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 500;
    text-align: left;
    color: var(--lms-dark);
    cursor: pointer;
    box-shadow: inset 0 0 0 1px var(--lms-line);
    transition: background .15s ease, color .15s ease, box-shadow .15s ease;
}

.pui-choice svg {
    flex-shrink: 0;
    color: var(--lms-accent);
}

.pui-choice-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pui-choice.active {
    background: var(--lms-dark);
    color: #ffffff;
    box-shadow: none;
}

@media (hover: hover) {
    .pui-choice:hover:not(.active) {
        box-shadow: inset 0 0 0 1px var(--lms-line-input);
    }
}

/* ── Switch row ─────────────────────────────────────────────────────────── */
.pui-switchrow {
    display: flex;
    align-items: center;
    gap: 12px;
    border-radius: 12px;
    background: #ffffff;
    padding: 12px 16px;
    box-shadow: inset 0 0 0 1px var(--lms-line-light);
}

.pui-switchrow-icon {
    display: flex;
    height: 36px;
    width: 36px;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    background: rgba(241, 93, 57, .1);
    color: var(--lms-accent);
}

.pui-switchrow-body {
    flex: 1;
    min-width: 0;
}

.pui-switchrow-title {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--lms-dark);
}

.pui-switchrow-sub {
    font-size: 11.5px;
    color: var(--lms-muted);
}

/* ── Toasts ─────────────────────────────────────────────────────────────────
   Portal rendering of the client's ToastService queue (LMS.Web.Client/State/ToastService.cs), so
   both halves of the app use one toast bus. Above every modal — a toast reporting the result of a
   save has to be visible over whatever is still open. */
/* Values below are the client ToastHost's Tailwind classes resolved 1:1, so the two match:
     container  fixed inset-x-0 bottom-4 flex flex-col items-center gap-2 px-4
     toast      w-[min(92vw,380px)] gap-3 rounded-xl px-4 py-3 shadow-lg ring-1, text-[14px]
     animation  slideUpIn 0.32s cubic-bezier(.2,.8,.2,1) from translateY(100%)
   No left accent bar, no bold text, no heavy shadow — the client has none of those. */
/* Top-anchored at every width, just under the 64px topbar.
   Bottom placement is off the table on mobile: iOS Safari tints its bottom toolbar from the page
   content behind it and never re-samples, so an orange toast within ~50px of the bottom edge turns
   the browser chrome orange and leaves it that way. The only offsets that avoided it sat the toast
   uncomfortably high, so the top — where the fixed topbar already gives Safari a stable surface —
   is the placement that works on both. */
.pui-toasts {
    position: fixed;
    inset-inline: 0;
    top: 80px;
    z-index: 1400;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 0 16px;
    pointer-events: none;
}

/* Orange fill is the default here, not just the warning level: the portal wanted the brand colour
   carrying the whole toast. Taller than the client's too. */
.pui-toast {
    display: flex;
    width: min(92vw, 380px);
    min-height: 60px;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    border-radius: 12px;
    padding: 16px 18px;
    background: var(--lms-accent);
    font-size: 14.5px;
    line-height: 1.4;
    color: #ffffff;
    pointer-events: auto;
    /* shadow-lg, plus the 1px ring as a second inset layer (Tailwind's ring-1). */
    box-shadow: 0 0 0 1px rgba(0, 0, 0, .1),
                0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -4px rgba(0, 0, 0, .1);
    animation: pui-toast-slide-up .32s cubic-bezier(.2, .8, .2, 1) both;
}

/* Mirror of the client's slideUpIn — same curve and distance, entering from above. */
@keyframes pui-toast-slide-up {
    from { opacity: 0; transform: translateY(-100%); }
    to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .pui-toast {
        animation: none;
    }
}

/* info / success / warning all take the base orange fill.

   Error stays the dark brand fill: a failure that looks identical to a confirmation is the one
   case where matching the others actively misleads. */
.pui-toast--error {
    background: var(--lms-dark);
}

/* -mr-1 rounded-full px-1 text-lg leading-none opacity-70 */
.pui-toast-close {
    flex-shrink: 0;
    margin-right: -4px;
    border: none;
    border-radius: 999px;
    background: transparent;
    padding: 0 4px;
    font-family: inherit;
    font-size: 18px;
    line-height: 1;
    color: inherit;
    opacity: .7;
    cursor: pointer;
    transition: opacity .15s ease;
}

.pui-toast-close:hover {
    opacity: 1;
}

/* Centre over the content column rather than the viewport, so the permanent sidebar does not
   push the stack visually off-centre. */
@media (min-width: 1024px) {
    .pui-toasts {
        inset-inline-start: 262px;
    }
}

/* ── Confirmation body ──────────────────────────────────────────────────── */
.pui-confirm {
    display: flex;
    align-items: flex-start;
    gap: 14px;
}

.pui-confirm-icon {
    display: flex;
    height: 44px;
    width: 44px;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    background: #fff1f2;
    color: #be123c;
    box-shadow: inset 0 0 0 1px #fecdd3;
}

.pui-confirm-text {
    margin: 0;
    font-size: 14px;
    line-height: 1.5;
    color: var(--lms-dark);
}

.pui-confirm-detail {
    margin: 6px 0 0;
    font-size: 12.5px;
    color: var(--lms-muted);
}

/* ── Inline note (neutral counterpart to .pui-alert) ────────────────────── */
.pui-note {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    border-radius: 12px;
    background: rgba(224, 234, 245, .6);
    padding: 12px 14px;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--lms-muted);
}

.pui-note svg {
    flex-shrink: 0;
    margin-top: 1px;
    color: var(--lms-accent);
}

.pui-note strong {
    color: var(--lms-dark);
}

.pui-note-sub {
    margin-top: 2px;
    font-size: 11.5px;
    color: var(--lms-faint);
    font-variant-numeric: tabular-nums;
}

/* ── Inline alert ───────────────────────────────────────────────────────── */
.pui-alert {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    border-radius: 12px;
    background: #fff1f2;
    padding: 10px 14px;
    font-size: 12.5px;
    line-height: 1.5;
    color: #be123c;
    box-shadow: inset 0 0 0 1px #fecdd3;
}

.pui-alert svg {
    flex-shrink: 0;
    margin-top: 1px;
}

/* ── Section divider inside a form ──────────────────────────────────────── */
.pui-section {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 4px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .18em;
    color: var(--lms-accent);
}

.pui-section::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--lms-line-light);
}

/* ── Checkbox row ───────────────────────────────────────────────────────── */
.pui-check {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--lms-muted);
    cursor: pointer;
}

.pui-check input {
    height: 16px;
    width: 16px;
    flex-shrink: 0;
    accent-color: var(--lms-accent);
    cursor: pointer;
}

/* ── Pager ──────────────────────────────────────────────────────────────── */
.pui-pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-top: 14px;
}

.pui-pager-info {
    font-size: 12px;
    color: var(--lms-muted);
    font-variant-numeric: tabular-nums;
}

.pui-pager-controls {
    display: flex;
    align-items: center;
    gap: 4px;
}

.pui-pager-btn {
    display: flex;
    min-width: 32px;
    height: 32px;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 8px;
    background: #ffffff;
    padding: 0 8px;
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--lms-muted);
    cursor: pointer;
    box-shadow: inset 0 0 0 1px var(--lms-line-light);
    font-variant-numeric: tabular-nums;
    transition: color .15s ease, background .15s ease, box-shadow .15s ease;
}

.pui-pager-btn:disabled {
    opacity: .35;
    cursor: not-allowed;
}

.pui-pager-btn.active {
    background: var(--lms-dark);
    color: #ffffff;
    box-shadow: none;
}

.pui-pager-gap {
    padding: 0 2px;
    font-size: 12.5px;
    color: var(--lms-faint);
}

@media (hover: hover) {
    .pui-pager-btn:hover:not(:disabled):not(.active) {
        color: var(--lms-dark);
        box-shadow: inset 0 0 0 1px var(--lms-line);
    }
}

/* ── Empty state ────────────────────────────────────────────────────────── */
.pui-empty {
    border: 2px dashed var(--lms-line);
    border-radius: 16px;
    background: rgba(255, 255, 255, .6);
    padding: 48px 24px;
    text-align: center;
}

.pui-empty-icon {
    display: flex;
    height: 56px;
    width: 56px;
    margin: 0 auto 16px;
    align-items: center;
    justify-content: center;
    border-radius: 16px;
    background: var(--lms-primary);
    color: var(--lms-accent);
}

.pui-empty-title {
    margin: 0;
    font-family: "Fraunces", ui-serif, Georgia, serif;
    font-size: 20px;
    font-weight: 600;
    color: var(--lms-dark);
}

.pui-empty-text {
    max-width: 24rem;
    margin: 6px auto 0;
    font-size: 13.5px;
    line-height: 1.6;
    color: var(--lms-muted);
}

.pui-empty-action {
    margin-top: 16px;
}

/* ── Breakpoints ────────────────────────────────────────────────────────── */
/* iOS Safari zooms the page whenever a focused field's text is under 16px, and never zooms back
   out. Raising the fields to 16px on small screens is the fix — unlike maximum-scale=1 on the
   viewport meta, it leaves pinch-zoom working for people who need it. */
@media (max-width: 767px) {
    .pui-page input,
    .pui-page select,
    .pui-page textarea,
    .pui-modal input,
    .pui-modal select,
    .pui-modal textarea,
    .pui-pickpop input,
    .pui-pickpop select,
    .pui-pickpop textarea,
    /* Not inputs, so they never triggered the zoom — but they sit beside fields that just grew,
       and a control that is 3px shorter than its neighbour reads as a mistake. */
    .pui-page .pui-dd-trigger,
    .pui-modal .pui-dd-trigger,
    .pui-modal .pui-picker-trigger {
        font-size: 16px;
    }
}

@media (min-width: 640px) {
    .pui-head {
        flex-direction: row;
        align-items: flex-end;
        justify-content: space-between;
    }

    .pui-statstrip {
        display: flex;
        flex-wrap: wrap;
        gap: 8px 28px;
    }

    .pui-modal {
        align-items: center;
        padding: 24px;
    }

    .pui-modal-panel {
        max-width: 640px;
        border-radius: 16px;
    }

    .pui-head-actions {
        flex-wrap: wrap;
        align-items: center;
    }

    .pui-modal-foot {
        align-items: center;
        justify-content: flex-end;
    }

    /* Content-width again — the even split is a phone-only layout. */
    .pui-head-actions > *,
    .pui-modal-foot > * {
        flex: 0 0 auto;
    }

    .pui-form-grid2 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 768px) {
    .pui-head-title {
        font-size: 30px;
    }
}

/* ── reCAPTCHA badge ──
   Google renders the badge bottom-right by default, which is exactly where the booking
   drawer sits (right-anchored, full height), so it lands on top of the panel. Moved to the
   bottom-left, clear of the drawer.

   Anchoring left also drops the collapse-to-the-edge animation, which relied on a negative
   `right`. Left collapsed it would hide the logo and leave the text half showing, so the
   badge stays fully expanded instead.

   Hidden while no booking flow is open: the badge is only meaningful on the form it guards,
   and enterprise.js loads on every page. Hiding it obliges the inline "Beveiligd door
   reCAPTCHA" attribution in BookingFlowPanel, which is there and carries both Google links —
   that line is what keeps this compliant on the pages where the badge never appears. */
.grecaptcha-badge {
    right: auto !important;
    left: 4px !important;
    /* Google ships the badge without a z-index, so it lands at the bottom of the page's
       stacking context and any positioned content (cards carry `relative z-10`, the booking
       backdrop `z-[90]`) paints straight over it — which is why it looked absent. Lifted above
       the highest layer in use (navbar `z-9999`, grain overlay `z-9999`); no visual conflict,
       since those sit elsewhere on the screen. */
    z-index: 10000 !important;
    /* There is no smaller badge to ask Google for — 256x60 is the only size the script
       renders. Scaled down instead, anchored on the corner it sits in. */
    transform: scale(0.75);
    transform-origin: bottom left;
    visibility: hidden !important;
    opacity: 0 !important;
    transition: opacity 0.2s ease, visibility 0.2s ease;
}

/* Class lives on <html>, set by lmsRecaptchaBooking.register when the panel opens and dropped
   on unregister. md and up only: under md the drawer is full-width, so a bottom-left fixed
   badge would sit on top of the form — and it is clickable, so it would eat taps on the
   "Terug" button. Mobile relies on the inline attribution line inside the panel instead. */
@media (min-width: 768px) {
    html.recaptcha-visible .grecaptcha-badge {
        visibility: visible !important;
        opacity: 1 !important;
    }
}

/* Partner-embedded widgets never get the floating badge — the card is inline in the partner's
   page, not a right-anchored full-height drawer, so a fixed bottom-left badge just floats free of
   it and reads as misplaced. The inline "Beveiligd door reCAPTCHA" line in BookingFlowPanel's own
   step 1 (rendered right above the submit button, in-flow) is the attribution for these pages
   instead — same two Google links, no floating badge needed. Wins over the rule above on source
   order (equal specificity), so this also cancels the md-and-up reveal for frame pages. */
html:has(.frame-shell) .grecaptcha-badge {
    display: none !important;
}

/* ── Public embed frames (LMS.Web/Frames) ──────────────────────────────────────
   Partner-embedded <iframe> widgets: last minutes + arrangements for one center.
   Global (not isolated CSS) because the classes are shared by both frame pages and
   the styles must reach elements the FrameLayout's child pages render. Reuses the
   brand tokens + the .pui-price / .pui-cat kit above. */
/* The host page's own background shows through around the .frame panel: a full-bleed embed painted
   in our lavender would fight whatever the partner's site uses behind it. The inline background on
   <html> (App.razor) can only be beaten with !important, and :has() keeps it scoped to the frame
   pages — FrameLayout's .frame-shell wrapper is what marks them. */
html:has(.frame-shell),
html:has(.frame-shell) body,
.frame-shell {
    background: transparent !important;
}

/* The partner's <iframe> is a fixed height we do not control — the embed snippet lives on their site
   and hard-codes one (the legacy .aspx URLs date back far enough that plenty also set
   scrolling="no"). So a center with a long list had nowhere to put it and the tail was simply cut off
   at the frame edge, with no scrollbar to reveal it.

   The panel is bound to the iframe's own viewport height instead, and the list scrolls inside it.
   Head, centre name and footer stay put whatever the height is, and it needs nothing from the
   partner: the inner document scrolls, which scrolling="no" does not govern.

   A height chain rather than 100vh — inside an iframe they resolve to the same number, but the chain
   also keeps the panel shrinking to its content when the list is short, where a vh height would
   stretch it. The margin reset moves the default 8px body gutter onto .frame-shell so it lands inside
   the chain instead of adding to it; total inset either side stays 24px. */
html:has(.frame-shell),
html:has(.frame-shell) body {
    margin: 0;
    height: 100%;
}

.frame-shell {
    box-sizing: border-box;
    height: 100%;
    padding: 8px;
    /* Last resort: an iframe too short for head + footer + one card would otherwise clip again. */
    overflow-y: auto;
    /* .frame is capped at max-width: 620px, but never wider than the shell itself — this is the
       last-resort clip for width the same way overflow-y above is for height. */
    overflow-x: hidden;
}

/* The widget carries its own light surface rather than trusting the host's background: the header,
   the centre name and the footer are dark text, so on a partner page with a dark background (a real
   dark theme, or just a dark main colour) they would sit near-invisible. A panel makes the embed
   legible on any host without sniffing the host's colours — which an iframe cannot do anyway.
   Barely-tinted rather than pure white so the white cards keep reading as cards on top of it.
   Padding, max-width and margin are unchanged, so the card count fitting the partner's fixed
   700px iframe stays the same. */
.frame {
    font-family: "Poppins", ui-sans-serif, system-ui, sans-serif;
    color: var(--lms-text);
    max-width: 620px;
    margin: 0 auto;
    padding: 18px 16px 24px;
    box-sizing: border-box;
    /* Column so .frame-list is the one part that gives when the list outgrows the frame. max-height,
       not height: a short list still sizes the panel to its content. */
    display: flex;
    flex-direction: column;
    max-height: 100%;
    background: #f8f4f9;
    border-radius: 20px;
    box-shadow: inset 0 0 0 1px rgba(5, 3, 22, .06), 0 1px 3px rgba(5, 3, 22, .05);
    /* Belt-and-braces: the partner's iframe is a fixed size we don't control, and every list/
       booking-flow step below scrolls its own overflow internally. Clipping here means a step that
       ever misses that (a long validation message, a wide grid on a narrow embed) is cut off instead
       of visually pushing the card past the iframe's own max width/height. */
    overflow: hidden;
}

/* Set while the booking flow has taken over the card (BookingFlowPanel Embedded="true"/BookingModal
   Embedded="true"): its own step markup already carries px-6 padding, sized for a full-bleed panel —
   .frame's own padding on top of that would double up and squeeze the form in a narrow embed. */
.frame--flush {
    padding: 0;
}

.frame-load,
.frame-msg,
.frame-empty {
    padding: 28px 16px;
    text-align: center;
    color: var(--lms-muted);
    font-size: 14px;
}

/* flex: none on the head and the foot — only the list is allowed to shrink. */
.frame-head {
    flex: none;
    margin-bottom: 16px;
}

.frame-eyebrow {
    display: block;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--lms-accent);
}

/* Fraunces, like every heading on the public site (see input.css h1/h2). 500 rather than 700:
   the serif reads heavier at the same weight than Poppins did. */
.frame-title {
    margin: 2px 0 0;
    font-family: "Fraunces", ui-serif, Georgia, "Times New Roman", serif;
    font-size: 22px;
    font-weight: 500;
    letter-spacing: -.01em;
    color: var(--lms-dark);
}

/* The scrolling part. min-height: 0 is what actually lets it shrink below its content — a flex item's
   default min-height: auto would keep it at full content height and push the overflow back out to the
   panel. The negative margin against equal padding widens the scroll box past the cards without
   moving them, so the hover scale(1.01) and the scrollbar gutter both have room to live in.
   overscroll-behavior: contain stops a flick at the end of the list from scrolling the partner's
   page behind the embed. */
.frame-list {
    list-style: none;
    margin: 0 -6px;
    padding: 2px 6px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    flex: 0 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: rgba(5, 3, 22, .25) transparent;
}

/* Visible on purpose, unlike the .pui-* lists above that hide theirs: in an embed of unknown height a
   cut-off list has to advertise that it continues. Slim and neutral so it reads as part of the panel.
   background-clip: content-box with a transparent border is what insets the thumb from the track. */
.frame-list::-webkit-scrollbar {
    width: 8px;
}

.frame-list::-webkit-scrollbar-track {
    background: transparent;
}

.frame-list::-webkit-scrollbar-thumb {
    border-radius: 999px;
    border: 2px solid transparent;
    background: rgba(5, 3, 22, .22);
    background-clip: content-box;
}

.frame-list::-webkit-scrollbar-thumb:hover {
    background: rgba(5, 3, 22, .38);
    background-clip: content-box;
}

/* Matches the public deal card (LastMinuteCardDeluxePage): rounded-2xl, a hairline black/5 border
   and shadow-sm, on white. Padding stays as it was so card height — and therefore how many fit in
   the partner's fixed 700px iframe — does not change. */
.frame-card {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 14px;
    align-items: center;
    background: #ffffff;
    border-radius: 16px;
    padding: 12px 14px;
    box-shadow: inset 0 0 0 1px rgba(5, 3, 22, .05), 0 1px 2px rgba(5, 3, 22, .05);
    transition: box-shadow .3s ease, transform .3s ease;
}

/* The site scales its cards on hover (hover:scale-101) rather than lifting them. */
.frame-card:hover {
    box-shadow: inset 0 0 0 1px rgba(5, 3, 22, .05), 0 8px 20px rgba(5, 3, 22, .08);
    transform: scale(1.01);
}

.frame-card--wide {
    grid-template-columns: 1fr auto;
}

/* Accent-tinted panel with a matching hairline, the same treatment the deluxe card gives its
   "Wanneer" block (bg-quaternary/5 + border-quaternary/15). */
.frame-date {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 54px;
    padding: 6px 0;
    border-radius: 12px;
    background: rgba(241, 93, 57, .05);
    box-shadow: inset 0 0 0 1px rgba(241, 93, 57, .15);
    line-height: 1.05;
}

.frame-date-month {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    color: var(--lms-accent);
}

.frame-date-day {
    font-size: 20px;
    font-weight: 700;
    color: var(--lms-dark);
}

.frame-date-dow {
    font-size: 10px;
    color: var(--lms-muted);
    text-transform: capitalize;
}

.frame-body {
    min-width: 0;
}

.frame-card-title {
    font-size: 15.5px;
    font-weight: 600;
    line-height: 1.25;
    color: var(--lms-dark);
}

.frame-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 5px;
}

/* Pills, like the date/time pills on the public deal card: fully rounded, white, black/10 hairline.
   Scoped inside .frame so the portal's own .pui-cat / .pui-price keep their kit styling elsewhere. */
.frame-time {
    display: inline-flex;
    align-items: center;
    border-radius: 999px;
    background: #ffffff;
    box-shadow: inset 0 0 0 1px rgba(5, 3, 22, .10);
    padding: 2px 9px;
    font-size: 12px;
    font-weight: 500;
    color: rgba(5, 3, 22, .70);
    font-variant-numeric: tabular-nums;
}

.frame .pui-cat {
    border-radius: 999px;
    background: #ffffff;
    box-shadow: inset 0 0 0 1px rgba(5, 3, 22, .10);
    padding: 2px 9px;
    font-size: 12px;
    color: rgba(5, 3, 22, .70);
}

/* Bare price, no chip — the site sets it in accent on the card surface itself. */
.frame .pui-price {
    background: none;
    box-shadow: none;
    padding: 0;
    gap: 5px;
}

.frame .pui-price-now {
    font-size: 20px;
    font-weight: 600;
    color: var(--lms-accent);
}

.frame .pui-price-orig {
    font-size: 12px;
    color: rgba(5, 3, 22, .40);
}

/* Accent-tinted pill, the site's treatment for a flag sitting next to neutral pills. */
.frame-flag {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    border-radius: 999px;
    background: rgba(241, 93, 57, .08);
    padding: 2px 9px;
    font-size: 12px;
    font-weight: 500;
    color: var(--lms-accent);
}

.frame-desc {
    margin: 6px 0 0;
    font-size: 13px;
    line-height: 1.5;
    color: rgba(5, 3, 22, .70);
    white-space: pre-line;
}

.frame-cta {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
}

/* The site's CTA: flat accent fill, rounded-xl, no 3D bottom edge, and it fades on hover
   (hover:bg-quaternary/90) instead of lightening to a different colour. */
.frame-btn {
    display: inline-block;
    padding: 8px 16px;
    border-radius: 12px;
    background: var(--lms-accent);
    color: #ffffff;
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    transition: opacity .3s ease;
    white-space: nowrap;
    /* .frame-btn now also lands on a <button> (opens the in-widget booking flow, no href to
       navigate to) alongside the plain links it always styled — reset the UA button chrome so
       both render identically. */
    border: none;
    font-family: inherit;
    cursor: pointer;
}

.frame-btn:hover {
    opacity: .9;
}

.frame-foot {
    flex: none;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    margin-top: 18px;
    padding-top: 14px;
    border-top: 1px solid rgba(5, 3, 22, .08);
}

.frame-foot-link {
    font-size: 13px;
    font-weight: 600;
    color: var(--lms-accent);
    text-decoration: none;
}

.frame-foot-link:hover {
    text-decoration: underline;
}

.frame-foot-brand {
    font-size: 12px;
    color: var(--lms-faint);
    text-decoration: none;
}

@media (max-width: 480px) {
    .frame-card {
        grid-template-columns: auto 1fr;
    }

    .frame-card .frame-cta {
        grid-column: 1 / -1;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }

    .frame-card--wide {
        grid-template-columns: 1fr;
    }
}
