/*
    Auth shell — the split-screen chrome shared by every standalone auth route.

    Imported by: /login (login-page.css) and /register/individual (register-page.css).
    Owns the two-panel grid, the image panel, the font vars, the field recipe, the button
    recipe, the links, the banner, and the motion primitives. A route's own stylesheet holds
    ONLY what is genuinely unique to it (login's password/reveal, register's sections/phone).

    Deliberately OFF-THEME: these routes load no Metronic (plugins/style/scripts bundle) and
    no Bootstrap, so this file carries its own reset — nothing upstream can reach in and undo
    the rules below. The only shared dependency is core/variables.css for the design tokens.

    NOTE ON --primary: styles/app.css redefines --primary to Metronic blue and is loaded AFTER
    variables.css by _AuthLayout. These routes never load app.css, so var(--primary) resolves
    to the brand purple here. That is why they must stay standalone.
*/

/* ---- Minimal reset: replaces the global stylesheets these routes intentionally skip ---- */
*,
*::before,
*::after {
    box-sizing: border-box;
}

html,
body {
    margin: 0;
    padding: 0;
}

.auth-page {
    /*
        Josefin is loaded as ONE FAMILY PER WEIGHT (see the @font-face block in
        core/utilities.css), not one family with a weight axis. A real 500 and a real 600 are
        therefore two different families, and `font-weight` alone cannot reach them — it would
        synthesize faux-bold from the Regular face and smear a thin geometric sans. Hence two
        body vars, both reusing the existing variables.css stacks verbatim.
    */
    --page-font-heading: 'Times New Roman', Times, serif;
    --page-font-body: var(--Josefin-medium);           /* real 500 face */
    --page-font-body-strong: var(--Josefin-semiBold);  /* real 600 face */

    --page-ease: cubic-bezier(0.16, 1, 0.3, 1);

    /* Radius scale: input + button 10 / icon 8 / link 4. Nothing above 16. */
    --page-radius-control: 10px;
    --page-radius-icon: 8px;
    --page-radius-link: 4px;

    /* One focus recipe, applied to every focusable control on every auth route. */
    --page-focus-ring: 0 0 0 3px rgba(98, 0, 238, 0.12); /* --primary at 12% */

    font-family: var(--page-font-body);
    color: var(--text-1);
    background-color: var(--white);
}

/* ---- Split screen ---- */
/* dvh, not vh: mobile browser chrome would otherwise push the panel past the viewport. */
.auth-page__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    min-height: 100dvh;
}

/*
    position:relative is load-bearing, not decoration. It makes the panel the containing block
    for its absolutely-positioned descendants — above all .sr-only, which has auto offsets.
    Without a positioned ancestor those resolve against the INITIAL containing block, so each
    one is painted at its static position deep inside the scrolled form yet counts toward the
    DOCUMENT's scrollable overflow. Twelve of them added ~219px of phantom page scroll on
    /register/individual and put a second scrollbar beside the panel's own.
*/
.auth-page__panel--form {
    position: relative;
    background-color: var(--white);
}

.auth-page__form-col {
    width: 100%;
}

/* ---- Image panel: decorative only, full bleed, never a white void ---- */
/*
    The primary fill sits under the image, so a failed/slow webp shows brand colour rather
    than white-on-white against the form panel.
*/
.auth-page__panel--image {
    position: relative;
    background-color: var(--primary);
    background-image: url('/images/tecnology-services-bg.webp');
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

/* Scrim: stops the panel competing with the form for attention. */
.auth-page__panel--image::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg,
                rgba(7, 20, 55, 0) 0%,       /* --heading at 0% */
                rgba(7, 20, 55, 0.12) 100%); /* --heading at 12% */
}

/* ---- Brand ---- */
/* Left-aligned: this is a page, not a modal. */
.auth-page__logo {
    display: inline-block;
    margin-bottom: 40px;
}

.auth-page__logo img {
    display: block;
    height: 32px;
    width: auto;
}

/* ---- Header ---- */
.auth-page__title {
    font-family: var(--page-font-heading);
    font-size: 32px;
    font-weight: var(--fw-600);
    letter-spacing: -0.01em;
    color: var(--heading);
    margin: 0 0 10px;
}

/* The one word that carries the brand. Same size, same weight — colour is the only change. */
.auth-page__title-accent {
    color: var(--primary);
}

/* Josefin's x-height is short, so 1.6 rather than the usual 1.5. */
.auth-page__subtitle {
    font-family: var(--page-font-body);
    font-size: 14px;
    font-weight: 500; /* no --fw-500 token exists; the Medium face carries the weight */
    line-height: 1.6;
    color: var(--text-3);
    max-width: 340px;
    margin: 0 0 36px;
}

/* ---- Form-level error: a submit-level fact, never a per-field one ---- */
/*
    Not reserved — it animates open instead. grid-template-rows 0fr -> 1fr is the height
    transition that works on auto-height content.
*/
.auth-page__banner {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 200ms ease, margin-bottom 200ms ease;
    margin-bottom: 0;
}

.auth-page__banner > * {
    overflow: hidden;
}

.auth-page__banner--shown {
    grid-template-rows: 1fr;
    margin-bottom: 24px;
}

.auth-page__banner-inner {
    border: 1px solid rgba(232, 38, 70, 0.2); /* --error-active at 20% */
    border-radius: var(--page-radius-control);
    background-color: var(--error-10);
    padding: 12px 14px;
    font-family: var(--page-font-body);
    font-size: 13px;
    font-weight: 500;
    line-height: 1.6;
    color: var(--error-active);
    margin: 0;
}

/* A collapsed banner must not keep its padding/border visible during the transition. */
.auth-page__banner:not(.auth-page__banner--shown) .auth-page__banner-inner {
    border-width: 0;
    padding-top: 0;
    padding-bottom: 0;
}

/* ---- Fields ---- */
.auth-field {
    display: flex;
    flex-direction: column;
    min-width: 0; /* lets a field shrink inside a grid row instead of overflowing it */
}

/* 600, not 500: Josefin's mid weights read light at label size. */
.auth-field__label {
    font-family: var(--page-font-body-strong);
    font-size: 14px;
    font-weight: var(--fw-600);
    color: var(--text-2);
    margin: 0 0 8px;
}

/*
    Red, not brand: an asterisk is a warning about the field, not a piece of branding.
    The adjacent .sr-only "required" carries the meaning — a bare "*" announces as "star".
*/
.auth-field__req {
    color: var(--error-active);
    margin-left: 4px;
    font-size: 14px;
}

.auth-field__control {
    position: relative;
    display: flex;
}

/* Form controls never inherit font-family in any browser — it is set explicitly. */
.auth-field__input {
    width: 100%;
    height: 48px;
    padding: 0 14px;
    border: 1px solid transparent;
    border-radius: var(--page-radius-control);
    background-color: var(--input-bg);
    font-family: var(--page-font-body);
    font-size: 15px;
    font-weight: 500;
    color: var(--text-1);
    transition: border-color 150ms ease;
}

.auth-field__input::placeholder {
    color: var(--text-4);
    font-weight: 500;
}

.auth-field__input:hover {
    border-color: var(--text-5);
}

/*
    The outline is replaced, never merely removed: the border carries focus on its own.
    Inputs deliberately take no focus ring — the --dark-border to --primary swap is the whole
    indicator here. Buttons, links and the reveal toggle keep the ring, since they have no
    border to change.
*/
.auth-field__input:focus {
    background-color: var(--white);
    outline: none;
    /* Inverted like every portal field: the fill goes white and a quiet border appears; the
       ring is what actually announces focus. */
    border-color: var(--dark-border);
    box-shadow: var(--page-focus-ring);
}

.auth-field__input:disabled {
    background-color: var(--dark-bg);
    border-color: var(--light-border);
    color: var(--text-5);
}

.auth-field--invalid .auth-field__input,
.auth-field--invalid .auth-field__input:hover {
    border-color: var(--error-active);
}

/*
    Reserved slot: 6px gap + 18px min-height, held whether or not an error is showing, so
    validation fires into space that was always there and nothing jumps.
*/
.auth-field__error {
    display: block;
    min-height: 18px;
    margin: 6px 0 0;
    font-family: var(--page-font-body);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.01em;
    line-height: 18px;
    color: var(--error-active);
}

/* ---- Links ---- */
.auth-link {
    font-family: var(--page-font-body-strong);
    color: var(--primary);
    text-decoration: none;
    border-radius: var(--page-radius-link);
}

.auth-link:hover {
    color: var(--primary);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.auth-link:focus {
    outline: none;
}

.auth-link:focus-visible {
    box-shadow: var(--page-focus-ring);
    outline: 2px solid transparent; /* keeps a ring in forced-colors mode */
    outline-offset: 2px;
}

/*
    Legal footer, not a call to action: it reads as body text and only signals its linkness on
    hover/focus, so it never competes with the primary action.
*/
.auth-link--muted {
    font-family: var(--page-font-body);
    font-size: 13px;
    font-weight: 500;
    color: var(--text-3);
}

.auth-link--muted:hover {
    color: var(--text-2);
}

/* ---- Submit ---- */
.auth-submit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 48px;
    padding: 0 28px;
    border: none;
    border-radius: var(--page-radius-control);
    background-color: var(--primary);
    font-family: var(--page-font-body-strong);
    font-size: 15px;
    font-weight: var(--fw-600);
    color: var(--white);
    cursor: pointer;
    /* Colour only — stillness. No lift anywhere on these routes. */
    transition: background-color 150ms ease;
}

.auth-submit:hover {
    background-color: var(--button-hover);
}

.auth-submit:active {
    background-color: var(--button-pressed);
}

.auth-submit:focus {
    outline: none;
}

.auth-submit:focus-visible {
    box-shadow: var(--page-focus-ring);
    outline: 2px solid transparent; /* keeps a ring in forced-colors mode */
    outline-offset: 2px;
}

.auth-submit:disabled {
    background-color: var(--dark-border);
    color: var(--text-5);
    cursor: not-allowed;
}

/* ---- Loading: label swaps; the button holds its width so nothing reflows ---- */
.auth-submit__spinner {
    display: none;
    flex: none;
    width: 16px;
    height: 16px;
    border: 2px solid rgba(255, 255, 255, 0.32); /* --white at 32% */
    border-top-color: var(--white);
    border-radius: 50%;
    animation: auth-spin 600ms linear infinite;
}

.auth-submit[aria-busy="true"] {
    pointer-events: none;
}

.auth-submit[aria-busy="true"] .auth-submit__spinner {
    display: block;
}

@keyframes auth-spin {
    to { transform: rotate(360deg); }
}

/* ---- Checkbox: a real <input>, drawn ---- */
/*
    The whole label is the click target and carries the 44px touch minimum via its own min-height —
    the visible box stays 20px. The native input is hidden but focusable; the ring and checked state
    are driven off its :checked/:focus-visible so keyboard and pointer behave identically.
*/
.auth-check {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    min-height: 44px;
    padding: 4px 0;
    cursor: pointer;
}

/* Visually hidden, not display:none — it must stay focusable and hit-testable. */
.auth-check__input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    margin: 0;
    pointer-events: none;
}

.auth-check__box {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    margin-top: 2px; /* optically centres the box against the first line of label text */
    border: 1.5px solid var(--text-5);
    border-radius: 5px;
    background-color: var(--white);
    color: var(--white); /* the tick inherits this */
    transition: background-color 150ms ease, border-color 150ms ease;
}

/* The tick is painted only when checked; scaled from 0 so the check reads as a confirmation. */
.auth-check__tick {
    opacity: 0;
    transform: scale(0.6);
    transition: opacity 150ms ease, transform 150ms var(--page-ease);
}

.auth-check:hover .auth-check__input:not(:checked) + .auth-check__box {
    border-color: var(--text-4);
}

.auth-check__input:checked + .auth-check__box {
    background-color: var(--primary);
    border-color: var(--primary);
}

.auth-check__input:checked + .auth-check__box .auth-check__tick {
    opacity: 1;
    transform: none;
}

.auth-check__input:focus-visible + .auth-check__box {
    box-shadow: var(--page-focus-ring);
}

.auth-check__input[aria-invalid="true"] + .auth-check__box {
    border-color: var(--error-active);
}

.auth-check__text {
    font-family: var(--page-font-body);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.5;
    color: var(--text-1);
}

@media (prefers-reduced-motion: reduce) {
    .auth-check__tick {
        transition: opacity 150ms ease;
        transform: none;
    }

    .auth-check__input:checked + .auth-check__box .auth-check__tick {
        transform: none;
    }
}

/* ---- Motion primitives: routes bind their own targets + delays ---- */
@keyframes auth-rise {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}

@keyframes auth-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* The image sets a mood; it fades, it does not move. */
.auth-page__panel--image {
    animation: auth-fade 400ms ease backwards;
}

/* ---- Accessibility ---- */
/*
    Visually hidden but announced. Used for the "required" beside each asterisk and for the
    <legend> of each section (the eyebrow carries the same words visually).
*/
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ---- Responsive ---- */
/* The form needs the room more than the image does. */
@media (max-width: 1023px) {
    .auth-page__grid {
        grid-template-columns: 1fr 0.7fr;
    }
}

/*
    Below 768px the image is removed, not stacked: a decorative panel that pushes the form
    below the fold is a real cost with no benefit.
*/
@media (max-width: 767px) {
    .auth-page__grid {
        grid-template-columns: 1fr;
    }

    .auth-page__panel--image {
        display: none;
    }
}

/* ---- Motion is dropped; the states themselves stay ---- */
@media (prefers-reduced-motion: reduce) {
    .auth-page__banner {
        transition: none;
    }

    .auth-submit__spinner {
        animation-duration: 1800ms;
    }
}
