/* =============================================================
   ez-platform auth layout styles
   Not linked by default - add to App.razor head only on auth pages.
   Depends on ez-platform.css (brand token vars must be loaded first).
   ============================================================= */

/* Logo variant used on auth/login pages. Height (max-height) is applied inline from the admin
   settings; width stays auto so the logo scales responsively while keeping its aspect ratio. */
.auth-brand-logo {
    width: auto;
    max-width: 100%;
}

/* Auth layout */
.auth-shell {
    min-height: 100vh;
    display: flex;
    /* The ground is the theme's page ground; raised surfaces (the phone sheet, the logo tiles, the
       account chip) lift a little off it toward the text colour, so they read as raised in any theme. */
    --ez-auth-raised:       color-mix(in srgb, var(--bs-body-color) 6%, var(--bs-body-bg));
    --ez-auth-raised-hover: color-mix(in srgb, var(--bs-body-color) 10%, var(--bs-body-bg));
}

/* The shell pins data-bs-theme="dark" on itself. Every brand theme's dark block also matches an element
   that does that (themes/brands/*.css), so everything in here - links, surfaces, text, borders - takes
   the active theme's dark palette, not Bootstrap's stock one. The surfaces below are tokens for the
   same reason: the auth pages, the maintenance/deploy pages and the signing page follow the theme. */
/* Bootstrap < lg */
@media (max-width: 991.98px) {
    .auth-shell { flex-direction: column; }
}

/* Left: brand panel (desktop, mock 06c). The logo sits top-left, the admin's hero copy sits at the
   bottom in a big headline, and the ground is a dark wash tinted with the brand colour from the top
   corner. An <img class="auth-hero-photo"> anywhere in the hero HTML becomes a full-bleed background
   photo with a dark fade under the text. The panel is forced dark regardless of the user's theme
   (data-bs-theme is pinned to "dark" on the auth shell), and takes the active theme's dark ground,
   headline and tint. */
.auth-hero {
    flex: 0 0 50%;
    position: relative;
    overflow: hidden;
    background:
        radial-gradient(120% 80% at 20% 0%, rgba(var(--bs-primary-rgb), .22) 0%, rgba(var(--bs-primary-rgb), .05) 50%, transparent 75%),
        var(--bs-tertiary-bg);
    display: flex;
    align-items: flex-end;
    padding: 3rem 3.5rem;
    color: var(--bs-body-color);
}
.auth-hero-inner { width: 100%; max-width: 34rem; }
.auth-hero .auth-brand { position: absolute; top: 2.25rem; left: 3.5rem; z-index: 2; }
/* The copy stacks above the photo and its fade. The body and its two wrappers stay unpositioned, so
   a photo inside them is positioned against the whole panel rather than against the text block. */
.auth-hero-page > *, .auth-hero-admin > :not(.auth-hero-photo), .auth-hero-foot { position: relative; z-index: 2; }
/* A page's own hero copy (AuthHero) replaces the admin hero; with none, its wrapper is empty. */
.auth-hero-page:empty { display: none; }
.auth-hero-body:has(> .auth-hero-page:not(:empty)) > .auth-hero-admin { display: none; }
/* AuthHero PhoneOnly (sign-in): from lg up the panel has room for the pitch, so the admin hero comes
   back and the page's short phone heading steps aside. Same specificity as the rule above, so it wins
   by coming after it. */
@media (min-width: 992px) {
    .auth-hero-page:has(> .auth-hero-phone) { display: none; }
    .auth-hero-body:has(> .auth-hero-page > .auth-hero-phone) > .auth-hero-admin { display: block; }
}
/* The photo shows only on a page that opts in (AuthHeroPhoto: sign-in only); everywhere else the
   panel is the brand gradient. Hidden and lazy, it is never downloaded. */
.auth-hero-flags { display: none; }
.auth-hero-photo { display: none; }
.auth-hero:has(.auth-hero-show-photo) .auth-hero-photo {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 20%;
    z-index: 0;
}
/* Only with a photo: fade it to the page ground behind the headline so the copy stays legible, and
   shade the top edge a little so the logo reads on a light photo too. */
.auth-hero:has(.auth-hero-show-photo):has(.auth-hero-photo)::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--bs-tertiary-bg) 60%, transparent) 0%,
        transparent 22%,
        transparent 35%,
        color-mix(in srgb, var(--bs-tertiary-bg) 55%, transparent) 55%,
        color-mix(in srgb, var(--bs-tertiary-bg) 94%, transparent) 100%);
}
.auth-hero-title {
    font-size: 2.75rem;
    font-weight: 800;
    letter-spacing: -.035em;
    line-height: 1.08;
    margin: 0 0 0.875rem;
    color: var(--bs-emphasis-color);
}
/* Words the admin wraps in a <span> take the brand colour ("See it <span>on you</span>"). */
.auth-hero-title span { color: var(--bs-primary); }
.auth-hero-sub {
    color: var(--bs-tertiary-color);
    font-size: 1.0625rem;
    line-height: 1.55;
    margin: 0 0 1.75rem;
    max-width: 40ch;
}
.auth-hero-points {
    list-style: none;
    padding: 0;
    margin: 0 0 2.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
}
.auth-hero-points li {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    color: var(--bs-tertiary-color);
}
.auth-hero-points i {
    width: 1.75rem;
    height: 1.75rem;
    display: grid;
    place-items: center;
    border-radius: var(--bs-border-radius-lg);
    background: rgba(var(--bs-primary-rgb), .14);
    /* The brand accent, matching the primary-tinted tile background above. */
    color: var(--bs-primary);
    flex-shrink: 0;
}
.auth-hero-foot {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--bs-secondary-color);
    padding: 0.375rem 0.625rem;
    border: 1px solid var(--bs-border-color);
    border-radius: var(--bs-border-radius-pill);
    background: rgba(0, 0, 0, .25);
    -webkit-backdrop-filter: blur(0.375rem);
    backdrop-filter: blur(0.375rem);
}
.auth-hero-dot {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: var(--bs-success);
}
/* Status tones - the indicator dot colour on the maintenance / deploy holding page (StandalonePageChrome). */
.auth-hero-dot--operational { background: var(--bs-success); }
.auth-hero-dot--degraded    { background: var(--bs-warning); }
.auth-hero-dot--maintenance { background: var(--bs-info); }
.auth-hero-dot--outage      { background: var(--bs-danger); }

/* Right: form column */
.auth-main {
    flex: 1;
    display: grid;
    place-items: center;
    padding: 3rem 1.5rem;
    /* Right pane: the theme's dark page ground (the auth shell is data-bs-theme="dark"). */
    background: var(--bs-tertiary-bg);
}
/* No card chrome (mock 06c): the form sits straight on the right-hand ground, left-aligned, at a
   comfortable reading width. The tiles and fields carry their own edges. */
.auth-card {
    width: 100%;
    max-width: 25rem;
    color: var(--bs-body-color);
}

/* Desktop: the brand panel is fixed at the full height of the window and only the right column
   scrolls, when a long form (register with the email form open) needs it. Auto margins centre the
   form rather than place-items, so a form taller than the window scrolls from its top instead of
   being centred with its top cut off out of reach. */
@media (min-width: 992px) {
    .auth-shell { height: 100vh; height: 100dvh; min-height: 0; overflow: hidden; }
    .auth-main { display: flex; overflow-y: auto; }
    .auth-card { margin: auto; }
    /* The document itself never scrolls behind an auth page: anything else in the body (the toast
       host, Blazor's reconnect UI, a banner) could otherwise add a few pixels below the full-height
       shell and put a SECOND scrollbar beside the form column's own. */
    html:has(.auth-shell), html:has(.auth-shell) body { overflow: hidden; }
}

/* Page titles wrap as balanced lines rather than leaving one word on a line of its own. */
.auth-card h1 { text-wrap: balance; }

/* The page heading (AuthHeading): sentence case, white, left-aligned, with the line under it muted. */
.auth-title {
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: -.02em;
    line-height: 1.2;
    color: var(--bs-emphasis-color);
    margin: 0 0 .375rem;
}
.auth-subtitle { color: var(--bs-secondary-color); font-size: .9375rem; margin: 0; }
.auth-head { margin-bottom: 1.75rem; }

.auth-brand {
    display: flex;
    align-items: center;
}

.auth-foot { color: var(--bs-secondary-color); font-size: 0.875em; text-align: center; margin-top: 1.125rem; }
.auth-foot a:not(.btn) { color: var(--bs-link-color); }

/* Code-entry inputs (recovery code, authenticator code): the placeholder is a format
   mask, not prose, so space the glyphs so it reads as a template. The dimming comes from
   the global .form-control::placeholder rule in ez-platform.css. */
.ez-code-input::placeholder {
    letter-spacing: 0.25em;
}

/* Bootstrap < lg */
@media (max-width: 991.98px) {
    .auth-hero { display: none; }
    .auth-main { padding: 2rem 1.25rem; }
}

/* ── Social sign-in (ExternalLoginButtons) ──────────────────────────────
   Moved out of a page-level <style> block so the auth theme owns it. Each provider's
   admin-configured brand colours arrive as --ez-social-bg / --ez-social-fg custom
   properties on the button, so no colour rule is ever written inline. */
.ez-social-divider { display: flex; align-items: center; gap: .75rem; margin: 1.5rem 0; }
.ez-social-divider::before,
.ez-social-divider::after { content: ''; flex: 1 1 0; height: 1px; background: var(--bs-border-color); }
.ez-social-divider span { font-size: .75rem; color: var(--bs-secondary-color); font-weight: 500;
    letter-spacing: .04em; text-transform: uppercase; flex-shrink: 0; }

/* One button per row at every width: the "Continue with {provider}" labels need the full row. */
.ez-social-grid { display: grid; grid-template-columns: 1fr; gap: .5rem; }
.ez-social-btn { display: flex; align-items: center; justify-content: center; gap: .5rem;
    height: 2.5rem; padding: 0 .75rem; font-size: .8125rem; font-weight: 600;
    border-radius: var(--bs-border-radius); border: none; text-decoration: none; line-height: 1;
    transition: filter .15s, transform .1s;
    background: var(--ez-social-bg, var(--bs-secondary-bg));
    color: var(--ez-social-fg, var(--bs-body-color)); }
/* The provider's text colour holds on hover (brand guidelines; the global a:hover would otherwise
   recolour it). Darken rather than brighten: most provider buttons are white, where brightening is a no-op. */
.ez-social-btn:hover { color: var(--ez-social-fg, var(--bs-body-color)); filter: brightness(.94); transform: translateY(-1px); }
.ez-social-btn .ez-social-icon { flex-shrink: 0; width: 1.1rem; height: 1.1rem; }

/* Logo tiles ("Icon-only buttons" setting, mock 06b): equal neutral tiles sharing one row, however
   many providers are on. The surface is the card's own, so the brand marks carry all the colour. */
.ez-social-iconrow { display: grid; grid-template-columns: repeat(auto-fit, minmax(3.5rem, 1fr)); gap: .625rem; }
.ez-social-iconbtn { height: 3.25rem; border-radius: var(--bs-border-radius-lg);
    border: 1px solid var(--bs-border-color); background: var(--ez-auth-raised);
    display: grid; place-items: center; text-decoration: none;
    transition: border-color .15s, background-color .15s; }
.ez-social-iconbtn:hover { border-color: var(--bs-secondary-color); background: var(--ez-auth-raised-hover); }
.ez-social-iconbtn .ez-social-icon { width: 1.375rem; height: 1.375rem; }

/* "Use your existing account" lead-in above the buttons, and register's perks under them. Centred in
   the phone sheet, left-aligned with the heading on a desktop (mocks 06b/06c). */
.ez-social-lead { text-align: center; margin-bottom: 1rem; }
@media (min-width: 992px) {
    .ez-social-lead { text-align: left; }
}
.ez-social-lead-title { font-size: 1.0625rem; font-weight: 700; margin: 0 0 .25rem; color: var(--bs-emphasis-color); }
.ez-social-lead-text { margin: 0; font-size: .8125rem; color: var(--bs-secondary-color); }
.ez-social-perks { list-style: none; padding: 0; margin: .875rem 0 0; display: flex; flex-wrap: wrap;
    justify-content: center; gap: .375rem 1rem; font-size: .75rem; color: var(--bs-secondary-color); }
.ez-social-perks i { color: var(--bs-success); margin-right: .3rem; }

/* ── Two-step register (mock 09) ───────────────────────────────────────
   Progress dots at the top of each step, and on step 2 a chip naming the account being created with
   a way back to step 1. While step 2 shows, the social buttons, the email toggle and the confirmation
   note above the form step aside: the visitor already chose email, and step 2 is about finishing. */
.auth-steps { display: flex; gap: .375rem; margin: 0 0 1.25rem; }
.auth-steps span { width: 1.5rem; height: .25rem; border-radius: var(--bs-border-radius-pill); background: var(--bs-border-color); }
.auth-steps span.on { background: var(--bs-primary); }
.auth-step-who { display: flex; align-items: center; gap: .625rem; margin: 0 0 .75rem; padding: .25rem .25rem .25rem .875rem;
    border: 1px solid var(--bs-border-color); border-radius: var(--bs-border-radius-pill); background: var(--ez-auth-raised); font-size: .875rem; }
.auth-step-who i { color: var(--bs-secondary-color); }
.auth-step-who-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.auth-sheet:has([data-ez-step="2"]:not([hidden])) :is(.ez-social, [data-ez-disclosure], .auth-note) { display: none; }
.auth-sheet:has([data-ez-step="2"]:not([hidden])) #ez-email-form { margin-top: 0 !important; }

/* A small muted aside inside an auth form: register's "we'll email you a link to confirm". Quieter than an EzAlert on purpose - it informs, it
   does not warn. */
.auth-note { display: flex; gap: .5rem; align-items: flex-start; font-size: .75rem; line-height: 1.45;
    color: var(--bs-secondary-color); background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color);
    border-radius: var(--bs-border-radius); padding: .5rem .625rem; margin-bottom: 1rem; }
.auth-note i { color: var(--bs-primary); margin-top: .125rem; }

/* ── Phone sheet (mock 06b) ─────────────────────────────────────────────
   Below lg a page that wraps its working part in .auth-sheet gets the app-style split. The brand panel
   itself becomes the top of the screen - logo, the hero headline and line, and the system status -
   centred in whatever height the sheet leaves, and every control sits in a sheet anchored to the
   bottom, where a thumb reaches. The page's own heading is visually hidden (still there for screen
   readers): the hero says the same thing bigger. A page without .auth-sheet renders as before (hero
   hidden, logo above the form). From lg up the sheet is plain content beside the brand panel.
   The hero is pinned (sticky) and the sheet scrolls up OVER it (owner decision 2026-10-13): a long form
   such as register keeps scrolling, and a focused field scrolled into view slides the sheet over the
   hero rather than squeezing under it. The sheet is opaque, so it covers the hero cleanly. */
@media (max-width: 991.98px) {
    .auth-shell:has(.auth-sheet) {
        min-height: 100vh;
        min-height: 100dvh;
        background: var(--bs-tertiary-bg);
    }
    /* In the iOS app's WebView 100vh stops short of the home indicator, so the page ends above the true
       bottom and the body shows through there. Painting the body the sheet's colour makes that strip read
       as the sheet running to the edge of the screen, as it was designed to. The body sits outside the
       shell, so it mixes the page's own tokens - the same values as the sheet whenever the page is in dark
       mode, which the apps that ship this WebView always are. */
    body:has(.auth-sheet) { background: color-mix(in srgb, var(--bs-body-color) 6%, var(--bs-body-bg)); }
    /* The brand glow is painted on the pinned hero, not the scrolling page, so it stays behind the logo. */
    .auth-shell:has(.auth-sheet) .auth-hero {
        display: flex;
        flex: 1 0 auto;
        align-items: center;
        justify-content: center;
        text-align: center;
        /* The top inset clears the status bar in the edge-to-edge mobile app (0 elsewhere). */
        padding: calc(1.5rem + env(safe-area-inset-top)) 1.5rem 1.5rem;
        background: radial-gradient(120% 100% at 50% 0%, rgba(var(--bs-primary-rgb), .16) 0%, var(--bs-tertiary-bg) 90%);
        position: sticky;
        top: 0;
        z-index: 0;
    }
    .auth-shell:has(.auth-sheet) .auth-main { position: relative; z-index: 1; }
    /* A little smaller than the desktop panel's mark, so the heading and the first controls share one screen. */
    .auth-shell:has(.auth-sheet) .auth-hero .brand-logo { max-height: calc(var(--ez-logo-max-h, 2.5rem) * .8); }
    /* The admin hero (register) is headline only on a phone: the pitch paragraph pushed the form down. */
    .auth-shell:has(.auth-sheet) .auth-hero-admin .auth-hero-sub { display: none; }
    .auth-shell:has(.auth-sheet) .auth-hero-inner {
        max-width: 26rem;
        display: flex;
        flex-direction: column;
        align-items: center;
    }
    .auth-shell:has(.auth-sheet) .auth-hero .auth-brand { position: static; margin-bottom: 1rem; }
    .auth-shell:has(.auth-sheet) .auth-hero-photo,
    .auth-shell:has(.auth-sheet) .auth-hero-points { display: none; }
    .auth-shell:has(.auth-sheet) .auth-hero::before { display: none; }
    .auth-shell:has(.auth-sheet) .auth-hero-title { font-size: 1.75rem; margin-bottom: .5rem; }
    .auth-shell:has(.auth-sheet) .auth-hero-sub { font-size: .9375rem; color: var(--bs-secondary-color); margin: 0 auto 1rem; }
    .auth-shell:has(.auth-sheet) .auth-hero-foot { font-size: .75rem; padding: .25rem .625rem; }

    .auth-main:has(.auth-sheet) { flex: 0 0 auto; display: block; padding: 0; background: transparent; }
    .auth-card:has(> .auth-sheet) { max-width: none; }
    .auth-card:has(> .auth-sheet) > .auth-brand { display: none !important; }
    .auth-card:has(> .auth-sheet) > .auth-head {
        position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
        overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
    }
    /* Full width on any phone or tablet; the content inside keeps the phone column width, centred. */
    .auth-sheet {
        padding: 1.5rem max(1.25rem, calc((100% - 26rem) / 2)) calc(1.75rem + env(safe-area-inset-bottom));
        background: var(--ez-auth-raised);
        border: 1px solid var(--bs-border-color);
        border-bottom: 0;
        border-radius: 1.5rem 1.5rem 0 0;
    }
}
