/* ============================================================
   FROSTED AUTH SURFACES
   Shared by the login / forgot password / OTP modals on the
   front page and by the standalone reactivate-account page.
   Loaded AFTER bootstrap.min.css so the overrides below win
   without needing !important.
   ============================================================ */

:root {
    /* Navy matched to the front page's --fp-ink / --fp-ink-deep. */
    --auth-navy: #0B2239;
    --auth-navy-deep: #04101E;

    /* THE ACCENT. This replaced a periwinkle (#8FA6E8) that was carried over
       from the old front page. It had to go for two reasons, in this order:

         1. White text on it measured 2.39:1. The primary button is the most
            important control in both flows and it did not meet 4.5:1. The
            hover shade was 2.93:1, no better.
         2. The front page moved to teal, so the modals were the only lilac
            thing left in the product.

       --auth-accent is as light as this can go and still hold white text at
       4.5:1 (it measures 5.43:1; one step lighter drops to 4.0 and fails), so
       raise it only alongside a darker text colour. --auth-accent-lift is the
       cyan for things drawn ON the dark panel - focus rings, borders, links -
       where the contrast runs the other way. They are not interchangeable. */
    --auth-accent: #0E7490;
    --auth-accent-deep: #0A5A70;
    --auth-accent-lift: #22D3EE;

    /* Neutrals retuned from lilac-tinted to the blue-grey the front page uses,
       and made opaque so their contrast is predictable instead of depending on
       whatever the frosted panel happens to be sitting over. */
    --auth-text: #FFFFFF;
    --auth-text-dim: #B9CDDE;
    --auth-label: #9FBACF;
    --auth-line: rgba(255, 255, 255, 0.18);
    --auth-line-strong: rgba(255, 255, 255, 0.30);
    --auth-well: rgba(255, 255, 255, 0.10);
    --auth-well-focus: rgba(255, 255, 255, 0.16);
}

/* ===========================
   THE FROSTED PANEL
   =========================== */
.auth-card {
    position: relative;
    padding: 36px 34px 30px;
    border-radius: 24px;
    color: var(--auth-text);
    background: linear-gradient(160deg, rgba(18, 48, 73, 0.78), rgba(6, 21, 36, 0.86));
    border: 1px solid var(--auth-line);
    -webkit-backdrop-filter: blur(18px) saturate(130%);
    backdrop-filter: blur(18px) saturate(130%);
    box-shadow:
        0 30px 70px rgba(3, 10, 22, 0.55),
        inset 0 1px 0 rgba(255, 255, 255, 0.14);
}

/* Older Android / Samsung Internet ignore backdrop-filter and would leave the
   panel translucent enough to read the page through it. Fall back to a solid
   navy so the form stays legible. */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
    .auth-card {
        background: linear-gradient(160deg, #123049, #061524);
    }
}

/* Neutralise the Bootstrap modal chrome so .auth-card is the only surface. */
.auth-modal .modal-dialog {
    max-width: 430px;
}

/* The registration wizard carries a 4-step rail and a three-column date row. */
.auth-modal-wide .modal-dialog {
    max-width: 540px;
}

.auth-modal .modal-content {
    background: transparent;
    border: 0;
    border-radius: 24px;
    box-shadow: none;
}

/* A tall panel is scrolled by the dialog, never by the body — an inner
   scrollbar would be drawn over the blur, inside the glass. */
.auth-modal .modal-body {
    padding: 0;
    max-height: none;
    overflow: visible;
}

/* Let the hero photograph read through the scrim behind the glass. */
body:has(.auth-modal.show) .modal-backdrop.show {
    opacity: 0.38;
}

/* ===========================
   HEADER BLOCK
   =========================== */
/* 44x44 is the tap minimum, and these two are the controls most likely to be
   reached for on a phone. The glyph inside stays its old size - what grew is
   the hit area, not the mark. */
.auth-close {
    position: absolute;
    top: 10px;
    right: 12px;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: rgba(255, 255, 255, 0.62);
    font-size: 19px;
    line-height: 1;
    display: grid;
    place-items: center;
    cursor: pointer;
    transition: background 0.2s ease, color 0.2s ease;
}

.auth-close:hover,
.auth-close:focus-visible {
    background: rgba(255, 255, 255, 0.12);
    color: #ffffff;
}

.auth-mark {
    width: 52px;
    height: 52px;
    margin-bottom: 16px;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.94);
    display: grid;
    place-items: center;
    overflow: hidden;
    box-shadow:
        0 0 0 1px rgba(34, 211, 238, 0.45),
        0 0 26px rgba(34, 211, 238, 0.30);
}

.auth-mark img {
    width: 76%;
    height: 76%;
    object-fit: contain;
}

.auth-mark i {
    color: var(--auth-navy);
    font-size: 1.35rem;
}

.auth-title {
    margin: 0 0 4px;
    font-size: 1.42rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--auth-text);
}

.auth-sub {
    margin: 0 0 24px;
    font-size: 0.875rem;
    letter-spacing: 0.02em;
    color: var(--auth-text-dim);
    line-height: 1.6;
}

/* ===========================
   FIELDS
   =========================== */
.auth-field {
    display: flex;
    flex-direction: column;
    gap: 7px;
    margin-bottom: 14px;
}

.auth-label {
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--auth-label);
    margin: 0;
}

/* Explanatory line under a field, e.g. why the reactivation form drops the
   email box in patient-code mode. Dimmer than .auth-label and not uppercased,
   so it reads as prose rather than as a second label. */
.auth-hint {
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--auth-text-dim);
}

.auth-input-wrap {
    position: relative;
    display: flex;
    align-items: center;
    /* The registration script appends .invalid-feedback next to the input it
       failed, so the wrapper has to let that message drop onto its own line. */
    flex-wrap: wrap;
}

.auth-input-wrap > .invalid-feedback,
.auth-input-wrap > .auth-error {
    flex: 0 0 100%;
}

/* 1rem is a hard floor, not a style choice: iOS zooms the page in whenever a
   focused input is under 16px and does not zoom back out. This was 0.9rem
   (14.4px), so every tap into a field left a patient on a phone looking at a
   magnified, sideways-scrolling form. */
.auth-input {
    width: 100%;
    padding: 13px 18px;
    border-radius: 50px;
    font-size: 1rem;
    line-height: 1.4;
    color: var(--auth-text);
    background: var(--auth-well);
    border: 1.5px solid rgba(255, 255, 255, 0.26);
    transition: border-color 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
}

.auth-input::placeholder {
    color: rgba(200, 216, 230, 0.62);
}

.auth-input:focus {
    outline: none;
    background: var(--auth-well-focus);
    border-color: var(--auth-accent-lift);
    box-shadow: 0 0 0 3px rgba(34, 211, 238, 0.26);
    color: var(--auth-text);
}

/* Chrome paints its own near-white autofill background over the glass. */
.auth-input:-webkit-autofill,
.auth-input:-webkit-autofill:hover,
.auth-input:-webkit-autofill:focus {
    -webkit-text-fill-color: var(--auth-text);
    caret-color: var(--auth-text);
    transition: background-color 6000s ease-in-out 0s;
}

.auth-input.text-center {
    letter-spacing: 0.35em;
    padding-right: 18px;
}

/* Native select needs its own arrow and readable option list. */
select.auth-input {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    padding-right: 44px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23C4D2F0'%3E%3Cpath d='M8 11.2 3.4 6.6l1.1-1.1L8 9l3.5-3.5 1.1 1.1z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 18px center;
    background-size: 15px;
    cursor: pointer;
}

select.auth-input option {
    background: var(--auth-navy);
    color: var(--auth-text);
}

.auth-eye {
    position: absolute;
    right: 5px;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: rgba(233, 242, 249, 0.82);
    display: grid;
    place-items: center;
    cursor: pointer;
    transition: background 0.2s ease, color 0.2s ease;
}

.auth-eye:hover,
.auth-eye:focus-visible {
    background: rgba(255, 255, 255, 0.14);
    color: #ffffff;
}

/* Keyed on the eye actually being present rather than on the input being an
   only child — a validation message appended beside it must not shift padding. */
.auth-input-wrap:has(.auth-eye) .auth-input {
    padding-right: 56px;
}

/* Per-field validation message, replacing Bootstrap's .invalid-feedback look. */
.auth-field .invalid-feedback,
.auth-error {
    margin: 2px 0 0 18px;
    font-size: 0.8125rem;
    color: #FFC9C9;
}

/* .auth-error is only ever rendered when there is something to report, so it
   shows whenever it exists. */
.auth-error {
    display: block;
}

/* .invalid-feedback is the opposite: @error renders it into the page up front
   and it then stays in the DOM for the life of the modal, so its visibility has
   to track the input's .is-invalid state rather than its own existence.

   This block used to be a flat `display: block`, which overrode Bootstrap's
   `.invalid-feedback { display: none }` and made every message permanent. That
   is why a corrected Confirm Password went on showing "Password confirmation
   does not match": the script was clearing .is-invalid off the input correctly,
   and the message simply was not listening. (The login modal's "Invalid Email
   or Password" is a different element - .auth-alert - and a different fix; see
   the input listeners in FrontPageViews/login.blade.php.) */
.auth-field .invalid-feedback {
    display: none;
}

.auth-field .is-invalid ~ .invalid-feedback,
/* .d-block is Bootstrap's "show this regardless", used by the OTP and forgot
   -password modals to render a server error with no .is-invalid input beside it. */
.auth-field .invalid-feedback.d-block {
    display: block;
}

.auth-input.is-invalid {
    border-color: rgba(240, 150, 150, 0.75);
    background-image: none;
}

select.auth-input.is-invalid {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23C4D2F0'%3E%3Cpath d='M8 11.2 3.4 6.6l1.1-1.1L8 9l3.5-3.5 1.1 1.1z'/%3E%3C/svg%3E");
}

.auth-input.is-invalid:focus {
    border-color: rgba(240, 150, 150, 0.9);
    box-shadow: 0 0 0 3px rgba(201, 76, 76, 0.25);
}

.auth-input.is-valid {
    border-color: rgba(123, 224, 168, 0.7);
}

.auth-input.is-valid:focus {
    border-color: rgba(123, 224, 168, 0.9);
    box-shadow: 0 0 0 3px rgba(63, 168, 118, 0.25);
}

/* Age and Category are computed from the birth date, never typed into. */
.auth-input[readonly] {
    background: rgba(255, 255, 255, 0.05);
    border-style: dashed;
    color: rgba(214, 230, 242, 0.85);
    cursor: default;
}

.auth-input[readonly]:focus {
    background: rgba(255, 255, 255, 0.05);
    border-color: rgba(255, 255, 255, 0.26);
    box-shadow: none;
}

.auth-input:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* ===========================
   SEGMENTED CHOICE
   (reactivate: password vs patient code)
   =========================== */
.auth-seg {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px;
    padding: 4px;
    border-radius: 50px;
    background: rgba(255, 255, 255, 0.08);
    border: 1.5px solid rgba(255, 255, 255, 0.22);
}

.auth-seg label {
    margin: 0;
    padding: 9px 8px;
    border-radius: 50px;
    text-align: center;
    font-size: 0.875rem;
    font-weight: 500;
    color: rgba(233, 242, 249, 0.85);
    cursor: pointer;
    transition: background 0.18s ease, color 0.18s ease;
}

.auth-seg label:hover {
    color: #ffffff;
}

.auth-seg input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.auth-seg input:checked + label {
    background: var(--auth-accent);
    color: #ffffff;
    font-weight: 600;
    box-shadow: 0 4px 12px rgba(14, 116, 144, 0.4);
}

.auth-seg input:focus-visible + label {
    outline: 2px solid var(--auth-accent-lift);
    outline-offset: 2px;
}

/* ===========================
   BUTTONS
   =========================== */
/* The teal is dark enough against the panel that the fill alone does not read
   as a raised control, so the cyan border is doing real work here: it carries
   the button's boundary at 3.16:1 against the card. Do not drop it. */
.auth-btn {
    width: 100%;
    margin-top: 10px;
    padding: 14px;
    border-radius: 50px;
    background: var(--auth-accent);
    color: #ffffff;
    font-weight: 600;
    font-size: 0.95rem;
    line-height: 1.2;
    border: 2px solid rgba(34, 211, 238, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    cursor: pointer;
    transition: background 0.22s ease, transform 0.22s ease, box-shadow 0.22s ease;
}

.auth-btn:hover:not(:disabled) {
    background: var(--auth-accent-deep);
    color: #ffffff;
    transform: translateY(-1px);
    box-shadow: 0 12px 26px rgba(14, 116, 144, 0.45);
}

/* 0.8 was close enough to fully-lit that a disabled primary button read as
   available - which matters most on the OTP modal, where the button greying
   out IS the signal that the expired code will no longer be accepted. 0.45
   sits in the 0.38-0.5 band that reads as unavailable without becoming
   illegible, and the cursor confirms it on pointer devices. */
.auth-btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
}

.auth-input:disabled,
.auth-input[disabled] {
    cursor: not-allowed;
}

.auth-btn-ghost {
    width: 100%;
    margin-top: 14px;
    padding: 11px;
    border-radius: 50px;
    background: transparent;
    border: 1.5px solid var(--auth-line-strong);
    color: #F3F8FC;
    font-size: 0.875rem;
    font-weight: 500;
    line-height: 1.3;
    text-align: center;
    text-decoration: none;
    display: block;
    cursor: pointer;
    transition: background 0.2s ease, color 0.2s ease;
}

.auth-btn-ghost:hover,
.auth-btn-ghost:focus-visible {
    background: rgba(255, 255, 255, 0.12);
    color: #ffffff;
}

/* ===========================
   FOOTER LINKS
   =========================== */
/* align-items: center, not the flex default stretch: the links carry
   padding-block the plain <span> does not, so a stretched span renders its
   text at the top of the row while the link's sits 6px lower. */
.auth-links {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 16px;
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid rgba(255, 255, 255, 0.16);
    font-size: 0.8125rem;
}

.auth-links span {
    color: var(--auth-text-dim);
}

/* padding-block lifts these off 21px, under the 24x24 pointer-target minimum. */
.auth-links a {
    display: inline-block;
    padding-block: 6px;
    color: var(--auth-accent-lift);
    text-decoration: none;
}

.auth-links a:hover,
.auth-links a:focus-visible {
    color: #ffffff;
    text-decoration: underline;
}

/* ===========================
   ALERTS
   =========================== */
.auth-alert {
    display: flex;
    gap: 10px;
    padding: 12px 15px;
    margin-bottom: 16px;
    border-radius: 14px;
    font-size: 0.875rem;
    line-height: 1.55;
    border: 1px solid transparent;
}

.auth-alert > i,
.auth-alert > .fas {
    flex: none;
    margin-top: 3px;
}

.auth-alert strong {
    display: block;
    font-weight: 600;
    margin-bottom: 2px;
}

.auth-alert a {
    font-weight: 600;
    color: inherit;
}

.auth-alert ul {
    margin: 6px 0 0;
    padding-left: 18px;
}

.auth-alert .btn-close {
    position: static;
    margin-left: auto;
    margin-top: 2px;
    flex: none;
    padding: 0;
    width: 0.75em;
    height: 0.75em;
    background-size: 0.75em;
    filter: invert(1) grayscale(100%) brightness(220%);
    opacity: 0.65;
}

.auth-alert .btn-close:hover {
    opacity: 1;
}

.auth-alert-error {
    background: rgba(201, 76, 76, 0.20);
    border-color: rgba(240, 150, 150, 0.45);
    color: #FFD9D9;
}

.auth-alert-error strong,
.auth-alert-error a {
    color: #ffffff;
}

.auth-alert-success {
    background: rgba(63, 168, 118, 0.20);
    border-color: rgba(140, 224, 183, 0.45);
    color: #D6F7E7;
}

.auth-alert-success strong,
.auth-alert-success a {
    color: #ffffff;
}

.auth-alert-info {
    background: rgba(34, 211, 238, 0.14);
    border-color: rgba(34, 211, 238, 0.40);
    color: #DCE5FB;
    justify-content: center;
    text-align: center;
}

.auth-alert-info strong {
    display: inline;
    margin: 0;
    color: #ffffff;
}

/* ===========================
   STANDALONE PAGE GROUND
   (reactivate-account)
   =========================== */
.auth-page {
    margin: 0;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem 1rem;
    font-family: 'Poppins', sans-serif;
    background:
        linear-gradient(135deg, rgba(5, 20, 38, 0.88), rgba(10, 36, 66, 0.80)),
        var(--auth-page-image, url('../../images/clinic-bg.jpg')) center center / cover no-repeat fixed;
}

.auth-page .auth-card {
    width: 100%;
    max-width: 430px;
}

/* ===========================
   RESPONSIVE
   =========================== */
@media (max-width: 575.98px) {
    .auth-card {
        padding: 30px 22px 26px;
        border-radius: 20px;
    }

    .auth-title {
        font-size: 1.25rem;
    }

    .auth-page {
        padding: 1.25rem 1rem;
        background-attachment: scroll;
    }
}

@media (prefers-reduced-motion: reduce) {
    .auth-btn:hover:not(:disabled) {
        transform: none;
    }

    .auth-card,
    .auth-input,
    .auth-btn,
    .auth-btn-ghost,
    .auth-close,
    .auth-eye {
        transition: none;
    }
}
