/* Shared "auth card" shell for every standalone account page: Login, Register, Forgot/Reset
   Password. One definition so these pages can't visually drift apart the way Login and Register
   previously had (a single centered card vs. an unrelated two-panel dark layout). Page-specific
   extras (Register's step indicator, password-strength meter, etc.) stay in that page's own
   <style> block and build on top of these classes rather than duplicating them.

   BUG FIX: every selector below is scoped under .login-container. This file is loaded globally
   (App.razor), and several of the class names it needs (.form-group, .form-control,
   .footer-links, .form-row, .validation-message, ...) are common enough that they already exist,
   with different rules, in the app's own dashboard stylesheets (layout.css, app.css) - loading
   this file unscoped after them silently overrode the real dashboard header avatar size and the
   dashboard's own form-label styling app-wide. Caught live from a screenshot showing the
   dashboard header's avatar rendering wrong. Scoping under .login-container (present on every
   page that uses this file, and nowhere else in the app) makes that class of leak structurally
   impossible regardless of what other stylesheets choose to name things. */

.login-container {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--qm-primary);
    padding: 20px;
    position: relative;
    overflow: hidden;
}

.login-container .login-card {
    background: var(--qm-bg-card);
    border-radius: var(--qm-radius-xl);
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
    padding: 48px;
    width: 100%;
    max-width: 480px;
    position: relative;
    z-index: 1;
    animation: authCardSlideUp 0.5s ease-out;
    transition: all 0.3s ease;
}

.login-container .login-card.wide {
    max-width: 620px;
}

.login-container .login-card.loading {
    opacity: 0.7;
    pointer-events: none;
}

@keyframes authCardSlideUp {
    from {
        opacity: 0;
        transform: translateY(30px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.login-container .login-header {
    text-align: center;
    margin-bottom: 32px;
    position: relative;
}

.login-container .btn-back {
    position: absolute;
    left: 0;
    top: 0;
    background: var(--qm-bg-elevated);
    border: none;
    border-radius: var(--qm-radius-lg);
    padding: 8px;
    cursor: pointer;
    color: var(--qm-text-secondary);
    transition: all 0.2s;
    display: flex;
    align-items: center;
    justify-content: center;
}

.login-container .btn-back:hover {
    background: var(--qm-border);
    color: var(--qm-primary);
}

.login-container .logo-wrapper {
    margin-bottom: 20px;
}

.login-container .logo-circle {
    width: 80px;
    height: 80px;
    margin: 0 auto;
    background: var(--qm-primary);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
}

/* A tenant's own logo in the sign-in disc. `contain` rather than `cover` because a school's crest
   is usually taller than it is wide and cropping it is worse than letterboxing it; the disc keeps
   the tenant's primary colour behind it, so a transparent PNG still reads. */
.login-container .logo-circle .brand-logo-img {
    max-width: 64px;
    max-height: 64px;
    object-fit: contain;
}

/* The mark on the password step. QBrandMark owns the tile itself — its size, its ring and its
   fallback icon — so all that is left here is the gap to the address underneath it, which is
   tighter than the 20px the mark uses above a heading.

   What was here before was a hand-rolled 80px disc with `color: white` baked into it. That is the
   token rule this project keeps relearning: white on a tenant's own brand colour is a guess, and
   QBrandMark reads var(--qm-text-on-primary), which BrandPalette derives from the brand's own
   luminance. A school that picks a pale colour gets readable text rather than a guess. */
.login-container .login-header__mark {
    margin-bottom: 16px;
}

.login-container .user-email {
    font-size: 18px;
    font-weight: 600;
    color: var(--qm-text-primary);
    margin: 0 0 12px 0;
}

.login-container .org-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--qm-bg-elevated);
    padding: 6px 12px;
    border-radius: var(--qm-radius-full);
    font-size: 13px;
    color: var(--qm-text-secondary);
}

.login-container .login-header h1 {
    font-size: 28px;
    font-weight: 700;
    color: var(--qm-text-primary);
    /* 14px above: the heading sits under the mark (QBrandMark), and a 0 here put "Welcome" flush on the tile. */
    margin: 14px 0 8px 0;
}

.login-container .login-header p {
    color: var(--qm-text-secondary);
    margin: 0;
    font-size: 15px;
}

.login-container .auth-alert {
    padding: 16px;
    border-radius: var(--qm-radius-lg);
    margin-bottom: 24px;
    display: flex;
    align-items: flex-start;
    gap: 12px;
    position: relative;
}

.login-container .auth-animate-in {
    animation: authAlertFadeInDown 0.3s ease-out;
}

@keyframes authAlertFadeInDown {
    from {
        opacity: 0;
        transform: translateY(-10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.login-container .auth-alert-icon {
    flex-shrink: 0;
    font-size: 20px;
}

.login-container .auth-alert-content {
    flex: 1;
}

.login-container .auth-alert-content strong {
    display: block;
    margin-bottom: 4px;
    font-size: 14px;
}

.login-container .auth-alert-content p {
    margin: 0;
    font-size: 13px;
    line-height: 1.5;
}

.login-container .auth-alert-close {
    background: none;
    border: none;
    cursor: pointer;
    padding: 0;
    color: inherit;
    opacity: 0.6;
    transition: opacity 0.2s;
}

.login-container .auth-alert-close:hover {
    opacity: 1;
}

.login-container .auth-alert-danger {
    background-color: color-mix(in srgb, var(--qm-danger) 12%, var(--qm-bg-card));
    color: var(--qm-danger);
    border: 1px solid color-mix(in srgb, var(--qm-danger) 30%, transparent);
}

.login-container .auth-alert-success {
    background-color: color-mix(in srgb, var(--qm-success) 12%, var(--qm-bg-card));
    color: var(--qm-success);
    border: 1px solid color-mix(in srgb, var(--qm-success) 30%, transparent);
}

/* ---- The two doors, and the duplicate-school warning (2026-09-20) ----------------------------
   Added with the sign-in page's second door ("use your join link") and the registration warning
   that names an organization already using Q-Mgr at the same email domain. Shared stylesheet
   rather than a component <style> block, because these sit on Login, Register and Join alike. */

.login-container .auth-alert-warning {
    background-color: color-mix(in srgb, var(--qm-warning) 12%, var(--qm-bg-card));
    color: var(--qm-text-primary);
    border: 1px solid color-mix(in srgb, var(--qm-warning) 40%, transparent);
    text-align: left;
}

.login-container .auth-alert-sub {
    margin: 4px 0 0;
    font-size: var(--qm-text-sm);
    color: var(--qm-text-secondary);
}

.login-container .auth-alert-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
}

.login-container .btn-login--sm {
    width: auto;
    min-height: var(--q-control-h-lg);
    padding: 0 14px;
    font-size: var(--q-control-font);
    margin: 0;
}

.login-container .btn-ghost-sm {
    background: none;
    border: 1px solid var(--qm-border);
    border-radius: var(--qm-radius-md);
    color: var(--qm-text-secondary);
    font: inherit;
    font-size: var(--q-control-font-sm);
    min-height: var(--q-control-h);
    padding: 0 12px;
    cursor: pointer;
}

.login-container .btn-ghost-sm:hover:not(:disabled) { border-color: var(--qm-primary); color: var(--qm-text-primary); }
.login-container .btn-ghost-sm:disabled { opacity: 0.6; cursor: default; }

/* The line under the registration heading that says what this page actually creates. */
.login-container .auth-subnote {
    margin: 10px 0 0;
    font-size: var(--qm-text-sm);
    color: var(--qm-text-secondary);
    line-height: 1.45;
}

.login-container .login-footer__secondary {
    margin-top: 2px;
}

/* The two doors, as buttons. Side by side where there is room, stacked on a phone. */
.login-container .auth-doors {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    justify-content: center;
}

.login-container .auth-door {
    flex: 1 1 160px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: var(--q-control-h-lg);
    padding: 0 14px;
    border: 1px solid var(--qm-border);
    border-radius: var(--qm-radius-md);
    background: var(--qm-bg-card);
    color: var(--qm-text-primary);
    font-size: var(--q-control-font);
    font-weight: 600;
    text-decoration: none;
}

.login-container .auth-door:hover {
    border-color: var(--qm-primary);
    color: var(--qm-primary);
}

/* One line under the doors, platform host only: the landing page for somebody who does not know the product yet. */
.login-container .login-welcome {
    margin: 10px 0 0;
    text-align: center;
    font-size: var(--qm-text-sm);
}

.login-container .login-welcome a {
    color: var(--qm-primary);
    font-weight: 600;
}

.login-container .form-group {
    margin-bottom: 20px;
}

.login-container .form-group label {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    font-weight: 500;
    color: var(--qm-text-primary);
    font-size: 14px;
}

.login-container .input-wrapper {
    position: relative;
}

/* Scoped under .login-card so this beats the dashboard's generic .form-group .form-control
   rule in app.css (both reuse Bootstrap's class names). */
.login-container .login-card .form-control {
    width: 100%;
    padding: 12px 40px 12px 16px;
    border: 2px solid var(--qm-border);
    border-radius: var(--qm-radius-lg);
    font-size: 15px;
    transition: all 0.2s;
    background: var(--qm-bg-elevated);
    color: var(--qm-text-primary);
}

.login-container .login-card .form-control:hover {
    border-color: var(--qm-border-hover);
    background: var(--qm-bg-card);
}

.login-container .login-card .form-control:focus {
    outline: none;
    border-color: var(--qm-primary);
    background: var(--qm-bg-card);
    box-shadow: 0 0 0 4px var(--qm-primary-light);
}

.login-container .login-card .form-control:disabled {
    background-color: var(--qm-bg-elevated);
    cursor: not-allowed;
    opacity: 0.6;
}

.login-container .input-toggle,
.login-container .input-clear {
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    cursor: pointer;
    color: var(--qm-text-secondary);
    padding: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: color 0.2s;
}

.login-container .input-toggle:hover,
.login-container .input-clear:hover {
    color: var(--qm-primary);
}

.login-container .form-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 24px;
    flex-wrap: wrap;
    gap: 12px;
}

.login-container .checkbox-wrapper {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    user-select: none;
}

.login-container .checkbox-label {
    font-size: 14px;
    color: var(--qm-text-secondary);
}

.login-container .link-forgot {
    color: var(--qm-primary);
    text-decoration: none;
    font-size: 14px;
    font-weight: 500;
    transition: color 0.2s;
}

.login-container .link-forgot:hover {
    color: var(--qm-primary-dark);
    text-decoration: underline;
}

.login-container .btn-login {
    width: 100%;
    padding: 14px;
    background: var(--qm-primary);
    color: white;
    border: none;
    border-radius: var(--qm-radius-lg);
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
}

.login-container .btn-login:hover:not(:disabled) {
    background: var(--qm-primary-dark);
}

.login-container .btn-login:active:not(:disabled) {
    transform: translateY(0);
}

.login-container .btn-login:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    transform: none;
}

.login-container .auth-spinner {
    width: 18px;
    height: 18px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: authSpinnerRotate 0.75s linear infinite;
}

@keyframes authSpinnerRotate {
    to { transform: rotate(360deg); }
}

.login-container .login-footer {
    text-align: center;
    padding-top: 24px;
    border-top: 1px solid var(--qm-border);
}

.login-container .login-footer p {
    margin: 0 0 16px 0;
    font-size: 14px;
    color: var(--qm-text-secondary);
}

.login-container .link-register {
    color: var(--qm-primary);
    text-decoration: none;
    font-weight: 600;
    transition: color 0.2s;
}

.login-container .link-register:hover {
    color: var(--qm-primary-dark);
    text-decoration: underline;
}

/* The gap the retired .get-app-row used to provide. Without it the legal links butt
   straight against the buttons above them — on every auth page, since they all share this
   footer, which is the reason it is set here rather than on the one page that lost the row. */
.login-container .footer-links {
    margin-top: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    font-size: 12px;
}

.login-container .footer-links a {
    color: var(--qm-text-secondary);
    text-decoration: none;
    transition: color 0.2s;
}

.login-container .footer-links a:hover {
    color: var(--qm-primary);
}

.login-container .footer-links span {
    color: var(--qm-border-hover);
}

.login-container .login-footer p.powered-by {
    margin: 12px 0 0 0;
    font-size: 11px;
    color: var(--qm-text-muted);
    letter-spacing: 0.02em;
}

/* QCopyright renders a bare <p class="q-copyright">; the class a caller passes is how each surface
   places it, the same way the legal pages pass .doc-copyright.

   Scoped to .login-container rather than to .login-footer because GetApp renders the line directly
   inside the card — it has no footer block — and a rule that only reached six of the seven pages
   would be the drift this sweep is closing. */
.login-container .login-copyright {
    margin: 8px 0 0 0;
    text-align: center;
    font-size: 11px;
    color: var(--qm-text-muted);
    letter-spacing: 0.02em;
}

.login-container .validation-message {
    color: var(--qm-danger);
    font-size: 12px;
    margin-top: 6px;
    display: block;
    animation: authValidationShake 0.3s ease-in-out;
}

/* A field the page has marked wrong. Bootstrap ships .is-invalid, but these pages restyle
   .form-control heavily enough that its border loses, so the rule is stated here rather than
   relied on. The message under the field says what is wrong; this only says which field. */
.login-container .form-control.is-invalid,
.login-container .form-control.is-invalid:focus {
    border-color: var(--qm-danger);
    box-shadow: none;
}

@keyframes authValidationShake {
    0%, 100% { transform: translateX(0); }
    25% { transform: translateX(-5px); }
    75% { transform: translateX(5px); }
}

/* Password-strength meter - shared by Register and ResetPassword */
.login-container .password-strength {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-top: 8px;
}

.login-container .strength-bar {
    flex: 1;
    height: 4px;
    background: var(--qm-bg-elevated);
    border-radius: var(--qm-radius-sm);
    overflow: hidden;
}

.login-container .strength-fill {
    height: 100%;
    transition: all 0.3s ease;
}

.login-container .strength-fill.weak { background: var(--qm-danger); }
.login-container .strength-fill.fair { background: var(--qm-warning); }
.login-container .strength-fill.good { background: var(--qm-primary); }
.login-container .strength-fill.strong { background: var(--qm-success); }

.login-container .strength-text {
    font-size: 12px;
    color: var(--qm-text-secondary);
    min-width: 40px;
}

/* Mobile Responsive */
@media (max-width: 600px) {
    .login-container .login-card {
        padding: 32px 24px;
    }

    .login-container .login-header h1 {
        font-size: 24px;
    }

    .login-container .logo-circle {
        width: 64px;
        height: 64px;
    }

    .login-container .form-row {
        flex-direction: column;
        align-items: flex-start;
    }

    .login-container .link-forgot {
        margin-left: auto;
    }
}

/* A suggestion offered inline in a hint — the app name on sign-up (rebrand 2026-09-24). A button,
   because it changes the field; drawn as a link, because it is a suggestion rather than an action. */
.form-hint .link-button {
    background: none;
    border: none;
    padding: 0;
    margin-left: 4px;
    color: var(--qm-primary);
    font: inherit;
    font-weight: 600;
    text-decoration: underline;
    cursor: pointer;
}
