/* Import Google Fonts */
@import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@400;500;700&display=swap');

html, body {
    font-family: 'Ubuntu', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

h1:focus {
    outline: none;
}

a, .btn-link {
    color: #0071c1;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.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."
    }

/* LFZ Loading Screen (replaces old Blazor loading-progress) */
.lfz-loading-screen {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #ffffff;
    z-index: 10000;
}

.lfz-loading-spinner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

/* Spinner ring - matches LfzSpinner component */
.lfz-loading-screen .lfz-spinner-ring {
    position: relative;
    width: 48px;
    height: 48px;
    border-radius: 999px;
    border-style: solid;
    border-width: 3px;
    border-color: rgba(0, 0, 0, 0.1);
    border-top-color: #f04925; /* LFZ orange/red */
    border-right-color: #7a7d84; /* LFZ grey */
    border-bottom-color: #002b5c; /* LFZ deep blue */
    animation: lfz-spinner-spin 0.9s linear infinite;
    box-shadow: 0 0 12px rgba(0, 0, 0, 0.35);
    display: flex;
    align-items: center;
    justify-content: center;
    background: radial-gradient(circle at 30% 20%, rgba(255,255,255,0.35), transparent 60%);
}

/* Inner core */
.lfz-loading-screen .lfz-spinner-core {
    width: 34px;
    height: 34px;
    border-radius: 999px;
    background: linear-gradient(135deg, #002b5c, #0c264a);
    box-shadow:
        0 6px 16px rgba(0, 0, 0, 0.45),
        0 0 14px rgba(0, 75, 160, 0.8);
    display: flex;
    align-items: center;
    justify-content: center;
}

/* LFZ initials */
.lfz-loading-screen .lfz-spinner-initials {
    font-size: 0.85rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #ffffff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
}

/* Text block */
.lfz-loading-screen .lfz-spinner-text {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    align-items: center;
}

/* Main caption */
.lfz-loading-screen .lfz-spinner-caption {
    font-size: 0.86rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #4b5563;
    opacity: 0.95;
}

/* Rotating keywords */
.lfz-loading-screen .lfz-spinner-subcaption {
    font-size: 0.78rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #9ca3af;
    opacity: 0.98;
}

/* Slim animated load bar */
.lfz-loading-screen .lfz-spinner-progress {
    margin-top: 0.4rem;
    width: 140px;
    height: 4px;
    border-radius: 999px;
    background: rgba(156, 163, 175, 0.4);
    overflow: hidden;
    position: relative;
}

.lfz-loading-screen .lfz-spinner-progress-inner {
    position: absolute;
    inset: 0;
    transform: translateX(-80%);
    background: linear-gradient(90deg, #f04925, #f97316, #22c55e, #0ea5e9);
    animation: lfz-progress-slide 1.4s ease-in-out infinite;
}

/* Loading percentage display */
.lfz-loading-percentage {
    margin-top: 0.5rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: #6b7280;
    letter-spacing: 0.05em;
}

/* Portal Navigation Loader */
.portal-navigation-loader {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.98);
    backdrop-filter: blur(4px);
    z-index: 10000;
    animation: fadeIn 0.2s ease-in;
}

.portal-navigation-loader-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

@keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

code {
    color: #c02d76;
}

/* Toast notifications.
   z-index bumped to 10000 so it overlays the admin role-editor's edit panel
   (z-index 2000) and the similarity-warning modal (z-index 3000) — without
   this the green "Role permissions saved." toast painted behind those
   modals and looked invisible. */
.toast {
    position: fixed;
    top: 20px;
    right: 20px;
    padding: 12px 20px;
    border-radius: 8px;
    color: white;
    font-weight: 500;
    z-index: 10000;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    animation: slideIn 0.3s ease-out;
    max-width: 400px;
    word-wrap: break-word;
}

.toast-success {
    background-color: #28a745;
}

.toast-error {
    background-color: #dc3545;
}

.toast-info {
    background-color: #17a2b8;
}

.toast-warning {
    background-color: #ffc107;
    color: #212529;
}

@keyframes slideIn {
    from {
        transform: translateX(100%);
        opacity: 0;
    }
    to {
        transform: translateX(0);
        opacity: 1;
    }
}

/* LFZ Spinner Component */
/* Base container */
.lfz-spinner {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    color: #111827;
}

/* Block vs inline mode */
.lfz-spinner-block {
    justify-content: center;
    padding: 0; /* no background container, just the spinner */
}

.lfz-spinner-inline {
    display: inline-flex;
    padding: 0;
}

/* Spinner ring */
.lfz-spinner-ring {
    position: relative;
    border-radius: 999px;
    border-style: solid;
    border-color: rgba(0, 0, 0, 0.1);
    border-top-color: #f04925; /* LFZ orange/red */
    border-right-color: #7a7d84; /* LFZ grey */
    border-bottom-color: #002b5c; /* LFZ deep blue */
    animation: lfz-spinner-spin 0.9s linear infinite;
    box-shadow: 0 0 12px rgba(0, 0, 0, 0.35);
    display: flex;
    align-items: center;
    justify-content: center;
    background: radial-gradient(circle at 30% 20%, rgba(255,255,255,0.35), transparent 60%);
}

/* Inner core */
.lfz-spinner-core {
    border-radius: 999px;
    background: linear-gradient(135deg, #002b5c, #0c264a);
    box-shadow:
        0 6px 16px rgba(0, 0, 0, 0.45),
        0 0 14px rgba(0, 75, 160, 0.8);
    display: flex;
    align-items: center;
    justify-content: center;
}

/* LFZ initials */
.lfz-spinner-initials {
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #ffffff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
}

/* Text block */
.lfz-spinner-text {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

/* Main caption */
.lfz-spinner-caption {
    font-size: 0.86rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #4b5563;
    opacity: 0.95;
}

/* Rotating keywords */
.lfz-spinner-subcaption {
    font-size: 0.78rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #9ca3af;
    opacity: 0.98;
}

/* Slim animated load bar */
.lfz-spinner-progress {
    margin-top: 0.4rem;
    width: 140px;
    height: 4px;
    border-radius: 999px;
    background: rgba(156, 163, 175, 0.4);
    overflow: hidden;
    position: relative;
}

.lfz-spinner-progress-inner {
    position: absolute;
    inset: 0;
    transform: translateX(-80%);
    background: linear-gradient(90deg, #f04925, #f97316, #22c55e, #0ea5e9);
    animation: lfz-progress-slide 1.4s ease-in-out infinite;
}

/* Sizes */
.lfz-spinner-sm .lfz-spinner-ring {
    width: 26px;
    height: 26px;
    border-width: 2px;
}

.lfz-spinner-sm .lfz-spinner-core {
    width: 18px;
    height: 18px;
}

.lfz-spinner-sm .lfz-spinner-initials {
    font-size: 0.55rem;
}

.lfz-spinner-md .lfz-spinner-ring {
    width: 36px;
    height: 36px;
    border-width: 3px;
}

.lfz-spinner-md .lfz-spinner-core {
    width: 26px;
    height: 26px;
}

.lfz-spinner-md .lfz-spinner-initials {
    font-size: 0.7rem;
}

.lfz-spinner-lg .lfz-spinner-ring {
    width: 48px;
    height: 48px;
    border-width: 3px;
}

.lfz-spinner-lg .lfz-spinner-core {
    width: 34px;
    height: 34px;
}

.lfz-spinner-lg .lfz-spinner-initials {
    font-size: 0.85rem;
}

/* Animations */
@keyframes lfz-spinner-spin {
    0%   { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

@keyframes lfz-progress-slide {
    0%   { transform: translateX(-80%); }
    50%  { transform: translateX(-10%); }
    100% { transform: translateX(100%); }
}

/* ============================================================================
   OnePortal — Cross-cutting responsive helpers
   --------------------------------------------------------------------------
   Lives in the GLOBAL stylesheet (no Blazor CSS isolation) so the rules
   below apply to elements rendered by any component, regardless of which
   .razor file declares the class. Per-page polish (padding, font sizes,
   OTP cell widths) is still done in each page's *.razor.css.
   --------------------------------------------------------------------------
   Breakpoint ladder used across the app (mobile-first reads bottom-up):
     ≤ 480px      small phones    (iPhone SE, Galaxy S small)
     ≤ 600px      large phones    (iPhone 14/15, Pixel)
     ≤ 768px     tablet portrait  (iPad portrait, Surface portrait)
     ≤ 1024px    tablet landscape (iPad landscape, Surface landscape)
     1025px +    desktop
   ========================================================================= */

/* Reusable touch-target helper. Apply where a button/icon needs to clear
   the WCAG 2.1 minimum 44×44 CSS-px target. Composable with existing
   icon-button styles. */
.touch-target {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Auth pages: hide the dark <SideImagePanel> on tablet-portrait and below
   so the form takes the full width. The per-page CSS already collapses
   the 55%/45% grid to a single column at 960px (stacking the side image
   on top of the form); this rule removes the stack on phones so the user
   never has to scroll past the marketing image to reach the inputs.
   The selector deliberately uses each shell name as the parent because
   `.side-image-panel` is a global class shared by 8 auth pages. */
@media (max-width: 768px) {
    .login-shell .side-image-panel,
    .reset-shell .side-image-panel,
    .forgot-shell .side-image-panel,
    .twofa-shell .side-image-panel,
    .mfa-shell .side-image-panel,
    .mfa-setup-shell .side-image-panel,
    .change-password-shell .side-image-panel,
    .verify-otp-shell .side-image-panel {
        display: none;
    }
}

/* Toast: top-right is fine on tablet+. On phones it can crowd the action
   bar of the page below; bottom-aligned + edge-to-edge is more usable. */
@media (max-width: 480px) {
    .toast {
        top: auto;
        bottom: 16px;
        left: 12px;
        right: 12px;
        max-width: none;
        animation: slideInBottom 0.3s ease-out;
    }
}

@keyframes slideInBottom {
    from { transform: translateY(100%); opacity: 0; }
    to   { transform: translateY(0);    opacity: 1; }
}

/* Long-form copy and form labels stay readable on small phones — never
   shrink below 14px in body text, never below 16px on inputs (iOS
   focus-zoom kicks in at <16 in Safari). */
@media (max-width: 480px) {
    /* Inputs inside any form panel — bumped to 16px to suppress iOS zoom-in
       on focus. Per-page CSS often sets 15px which is the trigger point. */
    .login-right .input,        .login-right .form-control,
    .reset-right .input,        .reset-right .form-control,
    .forgot-right .input,       .forgot-right .form-control,
    .twofa-right .input,        .twofa-right .form-control,
    .mfa-right .input,          .mfa-right .form-control {
        font-size: 16px;
    }
}

/* iOS Safari address-bar fix. `100vh` doesn't account for the URL bar
   sliding in/out, which clips bottom content. `100dvh` (dynamic vh) is
   the modern fix; the cascade keeps the older `100vh` as a fallback for
   browsers that don't yet support `dvh`. Apply to any full-page shell. */
.login-shell,
.reset-shell,
.forgot-shell,
.twofa-shell,
.mfa-shell,
.mfa-setup-shell,
.change-password-shell,
.verify-otp-shell {
    min-height: 100vh;        /* fallback */
    min-height: 100dvh;
}

/* Generic .table-responsive wrapper for any component that wraps a wide
   data table. Adds horizontal scroll on phones with momentum scroll on
   iOS. Pages can opt in by wrapping <table> in a div with this class. */
.table-responsive,
.scroll-x-mobile {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* Disallow horizontal page overflow caused by stray child elements.
   Defence-in-depth — if any single rule above misfires, the whole page
   should still not gain a horizontal scrollbar. Belt + braces. */
@media (max-width: 480px) {
    html, body {
        overflow-x: hidden;
    }

    /* WCAG 2.1 minimum touch target. Applies to every `.btn-icon`,
       `.icon-button`, and `.nav-toggle` across the app — these are
       commonly 24–28px on desktop, which is too small to tap reliably
       on touch screens. Per-page CSS can still override if needed. */
    .btn-icon,
    .icon-button,
    .nav-toggle,
    .close-btn {
        min-width: 44px;
        min-height: 44px;
    }
}