/* =============================================================================
   NETZERO AQUA — CONSOLE SIGN-IN
   =============================================================================
   One stylesheet, one door. The farmer, farm buddy and admin consoles now
   share a single sign-in page at /login.html, and the console you land in is
   decided by the role on your user document, not by which URL you opened.

   WHAT THIS REPLACED
   ------------------
   Three separate designs. The farmer page ran the v1 marketing template —
   bootstrap 3, owl carousel, meanmenu, wow.js — with a modern card bolted on
   in auth-flow.css. The buddy page was a centred card in a `bu-` vocabulary.
   The admin page was a third split panel in an `admin-` vocabulary. Three
   prefixes, three type stacks, and two of them still on the pre-rebrand lime
   because buddy/css/nz-palette.css and admin/css/nz-palette.css were stale
   copies nobody had resynced. A farmer, a buddy and an administrator could not
   have told they were signing in to the same company.

   ONE ORIGIN
   ----------
   This file lives once, at css/na-auth.css, and that is only possible because
   firebase.json now serves buddy/ and admin/ as PATHS on the farmer origin
   rather than as their own hosting sites. That was the prerequisite, not a
   side effect: Firebase Auth persists a session per origin, so three origins
   meant three sessions and a role-routing sign-in page could not work at all.

   Paths here are root-relative (/css/…, /img/…) for the same reason — they
   have to resolve identically from /login.html, /buddy/index.html and
   /admin/index.html.

   TOKENS
   ------
   Every colour comes from nz-palette.css. This file declares no hex values
   outside the dev bar, which is deliberately not brand-coloured. If you are
   typing a `#` into this file, stop: the value you want is already a token, or
   it does not belong in the brand.

   THE COLOUR RULE, RESTATED
   -------------------------
   Blue leads. It owns every fill, border, focus ring and primary button. The
   role accent — lime for admin, amber for buddy, blue for farmer — survives as
   a single pill, shown on the console pages and in the local dev bar, never on
   the sign-in form itself. One door has no role to advertise.
   ========================================================================== */


/* =============================================================================
   1 — PAGE
   ========================================================================== */

.na-auth-body {
    margin: 0;
    min-height: 100vh;
    min-height: 100dvh;
    background: var(--nz-navy-deep);
    color: var(--nz-text);
    font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    font-size: 16px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

.na-auth-body *,
.na-auth-body *::before,
.na-auth-body *::after { box-sizing: border-box; }

/* Skip link. An auth page is two panels and the second one is the point;
   a keyboard user should not have to tab the marketing copy first. */
.na-auth-skip {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    padding: 12px 18px;
    background: var(--nz-surface);
    color: var(--nz-blue);
    font-weight: 600;
    border-radius: 0 0 var(--nz-radius-sm) 0;
}

.na-auth-skip:focus { left: 0; }

.na-auth {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    min-height: 100vh;
    min-height: 100dvh;
}


/* =============================================================================
   2 — THE BRAND PANEL
   -----------------------------------------------------------------------------
   A photograph of real ponds under a navy scrim, with the measured grid from
   the marketing hero over it. The grid is what stops the panel reading as a
   stock photo: it is the same motif the platform uses to say "this water is
   being measured", and it is the one visual idea the three doors share.
   ========================================================================== */

.na-auth__panel {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 40px;
    padding: 48px;
    overflow: hidden;
    background: var(--nz-navy);
    color: var(--nz-text-on-dark);
    isolation: isolate;
}

.na-auth__media {
    position: absolute;
    inset: 0;
    z-index: -2;
}

.na-auth__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    display: block;
}

/* Two layers, not one. A flat overlay at the opacity needed to carry white
   text washes the photograph out completely; a vertical gradient keeps the
   water readable at the top and buys the contrast where the copy actually
   sits. Measured: white on the darkest point is 14.6:1. */
.na-auth__scrim {
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
        linear-gradient(180deg,
            rgba(0, 24, 48, 0.62) 0%,
            rgba(0, 24, 48, 0.78) 45%,
            rgba(0, 24, 48, 0.94) 100%),
        radial-gradient(90% 60% at 20% 15%,
            rgba(0, 74, 247, 0.22) 0%, transparent 70%);
}

.na-auth__grid {
    position: absolute;
    inset: 0;
    z-index: -1;
    background-image:
        linear-gradient(to right, rgba(255, 255, 255, 0.055) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(255, 255, 255, 0.055) 1px, transparent 1px);
    background-size: 62px 62px;
    mask-image: radial-gradient(120% 100% at 15% 0%, #000 0%, transparent 78%);
    -webkit-mask-image: radial-gradient(120% 100% at 15% 0%, #000 0%, transparent 78%);
}

/* ---- Brand lockup ---- */

.na-auth__brand {
    display: inline-flex;
    align-items: center;
    gap: 14px;
    text-decoration: none;
    color: inherit;
    width: fit-content;
    border-radius: var(--nz-radius-sm);
}

.na-auth__brand img {
    height: 46px;
    width: auto;
    display: block;
}

.na-auth__brand:focus-visible {
    outline: 2px solid var(--nz-blue-lift);
    outline-offset: 6px;
}

/* ---- The role pill: the ONE place a role accent appears ---- */

.na-auth__role {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 7px 15px 7px 12px;
    border-radius: var(--nz-radius-pill);
    background: rgba(255, 255, 255, 0.07);
    border: 1px solid rgba(255, 255, 255, 0.16);
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 0.11em;
    text-transform: uppercase;
    color: var(--nz-text-on-dark);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

.na-auth__role::before {
    content: '';
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--na-auth-accent, var(--nz-role-farmer));
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--na-auth-accent, var(--nz-role-farmer)) 26%, transparent);
    flex: none;
}

/* The three consoles. This is the entire role theming — see the header. */
.na-auth-body[data-console="farmer"] { --na-auth-accent: var(--nz-role-farmer); }
.na-auth-body[data-console="buddy"]  { --na-auth-accent: var(--nz-role-buddy); }
.na-auth-body[data-console="admin"]  { --na-auth-accent: var(--nz-role-admin); }

/* ---- Panel copy ---- */

.na-auth__copy { max-width: 30ch; }

.na-auth__copy h2 {
    margin: 18px 0 0;
    font-family: 'Space Grotesk', 'Inter', system-ui, sans-serif;
    font-size: clamp(30px, 3.1vw, 44px);
    line-height: 1.1;
    letter-spacing: -0.02em;
    font-weight: 700;
    /* The marketing site's hero pairing, carried onto the sign-in panel so the
       two do not look like two products: logo green for the sentence, logo
       blue for the <em>. Both are legible only because this panel is the
       photograph under a near-opaque navy scrim — see .na-auth__scrim.

       The form panel beside it is white, and its own h1 ("Log in") keeps
       --nz-text. #3BD304 is 2.00:1 on white; sending this colour across the
       divide is the one mistake this comment exists to prevent. */
    color: var(--nz-lime);
    text-wrap: balance;
}

.na-auth__copy h2 em {
    font-style: normal;
    /* Not --nz-blue-lift. That token is #80A6FF, which the buddy console reads
       outdoors and deliberately keeps at 6.69:1. Here the brief was the logo
       blue itself, lifted no further than it has to be to clear AA on navy —
       the same value the marketing site carries as --na-aqua. */
    color: var(--nz-blue-lift-min);
}

.na-auth__lede {
    margin: 16px 0 0;
    max-width: 44ch;
    font-size: 15.5px;
    line-height: 1.6;
    color: var(--nz-text-on-dark-2);
}

/* ---- Capability list ----
   Deliberately capability statements, never live figures. Farm counts are
   customer data and must not be readable by an unauthenticated visitor. */

.na-auth__points {
    margin: 0;
    padding: 26px 0 0;
    list-style: none;
    border-top: 1px solid rgba(255, 255, 255, 0.13);
    display: grid;
    gap: 15px;
}

.na-auth__points li {
    display: grid;
    grid-template-columns: 30px 1fr;
    align-items: center;
    gap: 13px;
    font-size: 14.5px;
    color: var(--nz-text-on-dark-2);
}

.na-auth__points svg {
    width: 30px;
    height: 30px;
    padding: 7px;
    border-radius: 9px;
    background: rgba(76, 130, 255, 0.14);
    border: 1px solid rgba(76, 130, 255, 0.28);
    color: var(--nz-blue-lift);
    stroke: currentColor;
    fill: none;
    stroke-width: 1.9;
    stroke-linecap: round;
    stroke-linejoin: round;
}


/* =============================================================================
   3 — THE FORM PANEL
   ========================================================================== */

.na-auth__form-panel {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 48px 40px;
    background: var(--nz-surface);
}

.na-auth__form {
    width: 100%;
    max-width: 424px;
}

.na-auth__back {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 28px;
    font-size: 14px;
    font-weight: 500;
    color: var(--nz-text-3);
    text-decoration: none;
    transition: color var(--nz-fast) var(--nz-ease);
}

.na-auth__back svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.na-auth__back:hover { color: var(--nz-blue); }

.na-auth__form h1 {
    margin: 0;
    font-family: 'Space Grotesk', 'Inter', system-ui, sans-serif;
    font-size: 32px;
    line-height: 1.15;
    letter-spacing: -0.02em;
    font-weight: 700;
    color: var(--nz-text);
}

.na-auth__sub {
    margin: 10px 0 30px;
    font-size: 15px;
    color: var(--nz-text-2);
}


/* =============================================================================
   4 — ALERTS
   -----------------------------------------------------------------------------
   Two regions, both live. The error region is role="alert" (interrupts); the
   notice region is role="status" (waits for a gap). Both are `hidden` until a
   script fills them, which is a real absence from the accessibility tree — not
   opacity:0, which announces an empty box.
   ========================================================================== */

.na-auth__alert {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    margin-bottom: 20px;
    padding: 13px 15px;
    border-radius: var(--nz-radius-sm);
    border: 1px solid;
    font-size: 14px;
    line-height: 1.5;
}

.na-auth__alert[hidden] { display: none; }

.na-auth__alert--error {
    background: var(--nz-danger-soft);
    border-color: color-mix(in srgb, var(--nz-danger) 28%, transparent);
    color: var(--nz-danger);
}

.na-auth__alert--info {
    background: var(--nz-info-soft);
    border-color: color-mix(in srgb, var(--nz-info) 26%, transparent);
    color: var(--nz-info);
}

.na-auth__alert svg { width: 17px; height: 17px; flex: none; margin-top: 2px; }


/* =============================================================================
   5 — FIELDS
   ========================================================================== */

.na-auth__field { margin-bottom: 18px; }

.na-auth__field label,
.na-auth__labelrow label {
    display: block;
    margin-bottom: 7px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--nz-text);
}

.na-auth__labelrow {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.na-auth__input {
    position: relative;
    display: flex;
    align-items: center;
    background: var(--nz-surface-alt);
    border: 1px solid var(--nz-border);
    border-radius: var(--nz-radius-sm);
    transition: border-color var(--nz-fast) var(--nz-ease),
                box-shadow var(--nz-fast) var(--nz-ease),
                background var(--nz-fast) var(--nz-ease);
}

/* The ring is on the wrapper, not the input, so the icon and the reveal
   button sit inside the focused boundary rather than beside it. */
.na-auth__input:focus-within {
    background: var(--nz-surface);
    border-color: var(--nz-blue);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--nz-blue) 18%, transparent);
}

.na-auth__input > svg:first-child,
.na-auth__input > i:first-child {
    flex: none;
    width: 17px;
    height: 17px;
    margin-left: 14px;
    color: var(--nz-text-3);
    stroke: currentColor;
    fill: none;
    stroke-width: 1.9;
    stroke-linecap: round;
    stroke-linejoin: round;
    font-size: 15px;
    text-align: center;
}

.na-auth__input input {
    flex: 1;
    min-width: 0;
    padding: 13px 14px;
    border: 0;
    background: transparent;
    font: inherit;
    font-size: 15px;
    color: var(--nz-text);
}

.na-auth__input input:focus { outline: none; }
.na-auth__input input::placeholder { color: var(--nz-text-3); }

/* Chrome paints its own yellow over autofilled inputs and ignores
   background-color. An inset shadow the height of the field is the only
   reliable way to keep the surface on-brand. */
.na-auth__input input:-webkit-autofill,
.na-auth__input input:-webkit-autofill:focus {
    -webkit-box-shadow: 0 0 0 40px var(--nz-surface) inset;
    -webkit-text-fill-color: var(--nz-text);
    caret-color: var(--nz-text);
}

.na-auth__reveal {
    flex: none;
    display: grid;
    place-items: center;
    width: 42px;
    align-self: stretch;
    border: 0;
    background: transparent;
    color: var(--nz-text-3);
    cursor: pointer;
    border-radius: 0 var(--nz-radius-sm) var(--nz-radius-sm) 0;
    transition: color var(--nz-fast) var(--nz-ease);
}

.na-auth__reveal:hover { color: var(--nz-blue); }
.na-auth__reveal:focus-visible { outline: 2px solid var(--nz-blue); outline-offset: -2px; }
.na-auth__reveal svg { width: 17px; height: 17px; stroke: currentColor; fill: none; stroke-width: 1.8; }
.na-auth__reveal i { font-size: 15px; }

/* Per-field validation message, written by the sign-in script. Empty until
   then, so it must not reserve space or the form jumps as it fills. */
.nz-msg {
    display: block;
    margin-top: 6px;
    font-size: 12.5px;
    line-height: 1.45;
    color: var(--nz-danger);
}

.nz-msg:empty { display: none; }


/* =============================================================================
   6 — OPTIONS ROW, CHECKBOX, LINKS
   ========================================================================== */

.na-auth__options {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin: 20px 0 22px;
}

.na-auth__check {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-size: 14px;
    color: var(--nz-text-2);
    cursor: pointer;
    user-select: none;
}

.na-auth__check input {
    width: 17px;
    height: 17px;
    margin: 0;
    accent-color: var(--nz-blue);
    cursor: pointer;
}

.na-auth__link,
.nz-linkbtn {
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    color: var(--nz-blue);
    text-decoration: none;
    cursor: pointer;
    border-radius: 4px;
}

.na-auth__link:hover,
.nz-linkbtn:hover { text-decoration: underline; }

.na-auth__link:focus-visible,
.nz-linkbtn:focus-visible { outline: 2px solid var(--nz-blue); outline-offset: 3px; }


/* =============================================================================
   7 — BUTTONS
   ========================================================================== */

.na-auth__btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    width: 100%;
    padding: 14px 20px;
    border: 1px solid transparent;
    border-radius: var(--nz-radius-sm);
    font: inherit;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    transition: background var(--nz-fast) var(--nz-ease),
                border-color var(--nz-fast) var(--nz-ease),
                color var(--nz-fast) var(--nz-ease),
                transform var(--nz-fast) var(--nz-ease),
                box-shadow var(--nz-fast) var(--nz-ease);
}

.na-auth__btn--primary {
    background: var(--nz-blue);
    color: #FFFFFF;                      /* 6.32:1 on the blue */
    box-shadow: var(--nz-shadow);
}

.na-auth__btn--primary:hover {
    background: var(--nz-blue-deep);
    box-shadow: var(--nz-shadow-lg);
    transform: translateY(-1px);
}

.na-auth__btn--primary:active { transform: translateY(0); box-shadow: var(--nz-shadow-sm); }

.na-auth__btn:focus-visible { outline: 2px solid var(--nz-blue); outline-offset: 3px; }

.na-auth__btn[disabled],
.na-auth__btn[aria-busy="true"] { opacity: 0.62; cursor: not-allowed; transform: none; }

.na-auth__btn svg { width: 17px; height: 17px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.na-auth__btn--primary svg { transition: transform var(--nz-normal) var(--nz-ease); }
.na-auth__btn--primary:hover svg { transform: translateX(3px); }


/* =============================================================================
   8 — THE DIVIDER
   -----------------------------------------------------------------------------
   This section used to hold the Microsoft and Google sign-in buttons. They were
   removed: this is a single-credential door now. A third-party OAuth button on
   it was offering farmers a way in that most of them cannot use, and that buddy
   and admin accounts were never provisioned for.

   The divider survives because the note below still wants a rule above it, and
   because a second credential path added later — an OTP, say — would want this
   separator rather than a new one.
   ========================================================================== */

.na-auth__divider {
    display: flex;
    align-items: center;
    gap: 14px;
    margin: 24px 0 18px;
    font-size: 13px;
    color: var(--nz-text-3);
}

.na-auth__divider::before,
.na-auth__divider::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--nz-border);
}


/* =============================================================================
   9 — FOOT NOTES
   ========================================================================== */

.na-auth__note {
    margin: 26px 0 0;
    padding-top: 22px;
    border-top: 1px solid var(--nz-border);
    font-size: 13.5px;
    line-height: 1.55;
    color: var(--nz-text-3);
    text-align: center;
}

.na-auth__note a { color: var(--nz-blue); font-weight: 600; text-decoration: none; }
.na-auth__note a:hover { text-decoration: underline; }

.na-auth__secnote {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    margin: 24px 0 0;
    padding: 12px 14px;
    border-radius: var(--nz-radius-sm);
    background: var(--nz-surface-alt);
    border: 1px solid var(--nz-border);
    font-size: 13px;
    line-height: 1.5;
    color: var(--nz-text-2);
    text-align: left;
}

.na-auth__secnote svg { width: 15px; height: 15px; flex: none; margin-top: 2px; color: var(--nz-text-3); }

.na-auth__copyright {
    margin: 18px 0 0;
    font-size: 12.5px;
    color: var(--nz-text-3);
    text-align: center;
}

.na-auth__copyright a { color: var(--nz-text-2); text-decoration: none; }
.na-auth__copyright a:hover { color: var(--nz-blue); }


/* =============================================================================
   10 — MODALS (farmer console only)
   -----------------------------------------------------------------------------
   `.modal-overlay` and the ids inside are queried by js/login-modals.js, which
   toggles a `.show` class. Kept on those names for that reason.
   ========================================================================== */

.modal-overlay {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: rgba(0, 24, 48, 0.62);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}

.modal-overlay.show { display: flex; }

.signup-modal,
.modal-content {
    position: relative;
    width: 100%;
    max-width: 452px;
    padding: 30px;
    border-radius: var(--nz-radius);
    background: var(--nz-surface);
    box-shadow: var(--nz-shadow-xl);
}

.signup-modal h2,
.modal-content h3 {
    margin: 0 0 10px;
    font-family: 'Space Grotesk', 'Inter', system-ui, sans-serif;
    font-size: 21px;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--nz-text);
}

.signup-modal p,
.modal-content p {
    margin: 0 0 22px;
    font-size: 14.5px;
    line-height: 1.6;
    color: var(--nz-text-2);
}

.modal-close {
    position: absolute;
    top: 14px;
    right: 14px;
    width: 32px;
    height: 32px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    font-size: 22px;
    line-height: 1;
    color: var(--nz-text-3);
    cursor: pointer;
}

.modal-close:hover { background: var(--nz-surface-alt); color: var(--nz-text); }

.modal-actions,
.mini-modal-actions {
    display: flex;
    gap: 11px;
    flex-wrap: wrap;
}

.modal-actions .btn,
.mini-modal-actions button {
    flex: 1;
    min-width: 128px;
    padding: 11px 18px;
    border: 1px solid var(--nz-border);
    border-radius: var(--nz-radius-sm);
    background: var(--nz-surface);
    font: inherit;
    font-size: 14.5px;
    font-weight: 600;
    color: var(--nz-text);
    text-align: center;
    text-decoration: none;
    cursor: pointer;
}

.modal-actions .btn-primary,
.mini-modal-actions .confirm-btn {
    background: var(--nz-blue);
    border-color: var(--nz-blue);
    color: #FFFFFF;
}

.modal-actions .btn:hover,
.mini-modal-actions button:hover { box-shadow: var(--nz-shadow); }


/* =============================================================================
   11 — RESPONSIVE
   -----------------------------------------------------------------------------
   Below 980px the brand panel stops being a column and becomes a band above
   the form: the lockup, the role pill and the headline, with the lede and the
   capability list dropped. They are reassurance for someone deciding whether
   to sign in; a person on a phone at the pond edge has already decided.

   The form is never the thing that shrinks. It stays full width with its
   touch targets intact all the way down.
   ========================================================================== */

@media (max-width: 980px) {

    .na-auth { grid-template-columns: 1fr; min-height: 0; }

    .na-auth__panel {
        gap: 22px;
        padding: 28px 24px 30px;
        min-height: 0;
    }

    .na-auth__grid {
        mask-image: radial-gradient(140% 120% at 10% 0%, #000 0%, transparent 85%);
        -webkit-mask-image: radial-gradient(140% 120% at 10% 0%, #000 0%, transparent 85%);
    }

    .na-auth__brand img { height: 38px; }

    .na-auth__copy { max-width: none; }
    .na-auth__copy h2 { font-size: clamp(23px, 6vw, 30px); margin-top: 14px; }

    /* Dropped, not hidden mid-sentence: see the note above. */
    .na-auth__lede,
    .na-auth__points { display: none; }

    .na-auth__form-panel { padding: 32px 22px 44px; }
    .na-auth__form { max-width: 460px; }
    .na-auth__back { margin-bottom: 20px; }
    .na-auth__form h1 { font-size: 26px; }
}

@media (max-width: 420px) {
    .na-auth__panel { padding: 24px 18px 26px; }
    .na-auth__form-panel { padding: 28px 18px 40px; }
    .na-auth__social { grid-template-columns: 1fr; }
    .na-auth__options { gap: 12px; }
}


/* =============================================================================
   12 — REDUCED MOTION
   -----------------------------------------------------------------------------
   nz-palette.css already zeroes --nz-fast and --nz-normal under this query, so
   every transition above collapses on its own. What is left is the one
   transform that is not driven by a token.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    .na-auth__btn--primary:hover { transform: none; }
    .na-auth__btn--primary:hover svg { transform: none; }
}


/* =============================================================================
   13 — SCRIPT-DRIVEN STATES
   -----------------------------------------------------------------------------
   Everything below is a contract with a sign-in script, not a design choice.
   Rename any of these and the corresponding script stops working silently.

     .nz-field.is-invalid      js/login.js — set on the field WRAPPER
     .na-auth__input.is-invalid admin/js/admin-login.js — set on the input's
                               direct PARENT, which is why both spellings exist
     .is-loading               all three — set on the submit button
     .na-auth__alert i + span  admin injects '<i class="fa …"></i><span>…</span>'

   The alerts also arrive as innerHTML from the scripts, so the layout has to
   work for markup this stylesheet never wrote.
   ========================================================================== */

.na-auth__alert i {
    flex: none;
    margin-top: 2px;
    font-size: 15px;
    line-height: 1.4;
}

.na-auth__alert span { min-width: 0; }

.na-auth__input.is-invalid,
.nz-field.is-invalid .na-auth__input {
    border-color: var(--nz-danger);
    background: var(--nz-danger-soft);
}

.na-auth__input.is-invalid:focus-within,
.nz-field.is-invalid .na-auth__input:focus-within {
    border-color: var(--nz-danger);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--nz-danger) 18%, transparent);
}

.na-auth__btn.is-loading {
    opacity: 0.72;
    cursor: progress;
    transform: none;
    box-shadow: var(--nz-shadow-sm);
}

/* The one looping animation in this file, and it earns it: a spinner during a
   network round trip is feedback, not decoration. Reduced motion removes the
   spin and keeps the disabled state and the changed label, so the person is
   still told the form is working. */
@keyframes na-auth-spin { to { transform: rotate(360deg); } }

.admin-submit__icon.fa-circle-notch,
.na-auth__btn.is-loading .na-auth__spin {
    animation: na-auth-spin 0.9s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
    .admin-submit__icon.fa-circle-notch,
    .na-auth__btn.is-loading .na-auth__spin { animation: none; }
}
