/*
 * The signed-out client screens: a photograph on the left, a form on the right.
 *
 * Plain CSS for the same reason as contact.css, wallet.css and order-cards.css:
 * the panels have no Vite build and serve Filament's pre-compiled app.css, so
 * `class="flex gap-4"` written in a Blade view here is inert markup. Anything
 * bespoke brings its own rules.
 *
 * Registered on the client panel only, in ClientPanelProvider:
 *
 *     Css::make('auth', resource_path('css/auth.css'))
 *
 * which `php artisan filament:assets` copies to public/css/app/auth.css. Editing
 * this file therefore needs that command re-run — composer's post-autoload-dump
 * does it too, by way of `filament:upgrade`.
 *
 * Every colour is a variable FilamentColor writes into :root at runtime
 * (--gray-*, --primary-*) and every size comes from Filament's own theme block
 * (--radius-lg, --text-sm, --container-2xl), so the screen tracks the operator's
 * palette and their dark mode instead of defining a second one. Dark mode is the
 * `.dark` class on <html>.
 *
 * The namespace is `au-`, kept apart from `wl-`, `oc-`, `sv-`, `ct-`, `tk-` and
 * `db-` for the reason contact.css gives: several of these files load on the same
 * request and a shared prefix would let a rule written for one screen silently
 * restyle another.
 *
 * ------------------------------------------------------------------------------
 * Two things to know before editing.
 *
 * FIRST: the form itself is Filament's. This file restyles `.fi-` classes *inside*
 * `.au-shell` and nothing outside it, so the same inputs and buttons keep their
 * validation, their focus rings, their disabled states and their dark mode. That
 * is the whole reason the shadcn look costs a stylesheet instead of a rewrite of
 * the login page.
 *
 * SECOND: Filament writes its dark-mode rules as `:where(.dark, .dark *)`, and
 * `:where()` contributes NOTHING to specificity. `.au-shell .fi-input-wrp` beats
 * `.fi-input-wrp:where(.dark, .dark *)` outright — so any colour set here must be
 * set for both themes or the light value will leak into dark mode. Every colour
 * below comes in a pair for that reason.
 */

/* ------------------------------------------------------------------ *
 * The shell — two halves above 1024px, one below
 *
 * `height` rather than `min-height`, and `overflow: hidden` under it: this screen
 * does not scroll. A page-level scrollbar here is not a small ugliness — it is a
 * bar down the right-hand edge of a two-column design, and scrolling the *page*
 * slides the photograph up out of its half while the form moves past it. What
 * scrolls, when there is genuinely more form than screen, is `.au-main` alone.
 *
 * `100dvh` and not `100vh`, so a phone's collapsing address bar changes the height
 * of the shell instead of leaving the bottom of it underneath the browser chrome.
 * ------------------------------------------------------------------ */

.au-shell {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    height: 100dvh;
    overflow: hidden;
}

@media (min-width: 64rem) {
    .au-shell {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    }
}

/* ------------------------------------------------------------------ *
 * The left half — imagery, the logo, and the operator's words
 *
 * `display: none` below 1024px is the deliberate mobile answer: a phone gets a
 * clean single-column form rather than a letterboxed photograph above one. The
 * logo is not lost when this goes — see the `.fi-simple-header` rules further
 * down, which hand it back to the top of the form.
 * ------------------------------------------------------------------ */

.au-aside {
    display: none;
    position: relative;
    overflow: hidden;
    isolation: isolate;

    /*
     * The fallback, and it is the default rather than the exception. No slides
     * configured, or a database restored without its uploads, leaves this
     * gradient and the wordmark over it — because a sign-in screen that fails to
     * render is an outage that also locks the operator out of the panel they
     * would fix it from.
     */
    background-color: var(--primary-950, #111827);
    background-image: linear-gradient(
        150deg,
        var(--primary-700, #1d4ed8) 0%,
        var(--primary-950, #111827) 55%,
        var(--gray-950, #030712) 100%
    );
}

@media (min-width: 64rem) {
    .au-aside {
        display: block;
    }
}

.au-aside-media {
    position: absolute;
    inset: 0;
}

.au-slide-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/*
 * The scrim, darkest at top and bottom.
 *
 * Not decoration: the logo sits in the top-left corner and the copy in the
 * bottom-left, both over a photograph the operator chose and neither of which we
 * can guarantee the contrast of. This is what keeps white text legible over a
 * bright sky.
 */
.au-aside-scrim {
    position: absolute;
    inset: 0;
    background-image: linear-gradient(
        to bottom,
        rgb(0 0 0 / 45%) 0%,
        rgb(0 0 0 / 12%) 28%,
        rgb(0 0 0 / 18%) 52%,
        rgb(0 0 0 / 72%) 100%
    );
}

.au-aside-body {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 2rem;
    height: 100%;
    padding: 2.5rem;
    color: var(--color-white, #fff);
}

@media (min-width: 80rem) {
    .au-aside-body {
        padding: 3rem;
    }
}

/*
 * The logo, top-left.
 *
 * The aside is dark whichever theme the browser is in, so it wants the operator's
 * dark-mode logo — which is exactly the inverse of what Filament's own rules do.
 * When only one logo is configured the component renders a single `.fi-logo` with
 * neither modifier class and both rules below miss it, which is the right
 * outcome. Selectors are three classes deep on purpose: Filament's own pair is
 * two deep and `:where(.dark, …)` adds nothing, so anything shallower would be a
 * tie decided by stylesheet order.
 */
.au-shell .au-aside-logo .fi-logo {
    color: var(--color-white, #fff);
}

.au-shell .au-aside-logo .fi-logo-light {
    display: none;
}

.au-shell .au-aside-logo .fi-logo-dark {
    display: flex;
}

/* The wordmark when no slides are configured — the empty state's only content. */
.au-aside-fallback {
    font-size: clamp(1.75rem, 3.2vw, 2.75rem);
    font-weight: var(--font-weight-bold, 700);
    line-height: 1.15;
    letter-spacing: -0.02em;
    color: rgb(255 255 255 / 92%);
}

.au-aside-foot {
    display: grid;
}

/*
 * The per-slide copy, stacked in a single grid cell.
 *
 * One cell rather than absolute positioning, so the block is as tall as its
 * tallest slide and the fixed note underneath does not jump when the copy
 * changes length. `x-show` toggles `display` on the children; the cell keeps
 * their geometry.
 */
.au-aside-copy {
    display: grid;
}

.au-slide-copy {
    grid-area: 1 / 1;
}

.au-slide-heading {
    font-size: var(--text-2xl, 1.5rem);
    font-weight: var(--font-weight-semibold, 600);
    line-height: 1.25;
    letter-spacing: -0.01em;
    color: var(--color-white, #fff);
}

.au-slide-body {
    max-width: 46ch;
    margin-top: 0.625rem;
    font-size: var(--text-sm, 0.875rem);
    line-height: 1.6;
    color: rgb(255 255 255 / 78%);
}

.au-aside-dots {
    display: flex;
    gap: 0.375rem;
    margin-top: 1.5rem;
}

.au-dot {
    width: 1.5rem;
    height: 0.25rem;
    border-radius: 9999px;
    background-color: rgb(255 255 255 / 30%);
    cursor: pointer;
    transition:
        width 0.25s var(--ease-out, ease),
        background-color 0.25s var(--ease-out, ease);
}

.au-dot:hover {
    background-color: rgb(255 255 255 / 55%);
}

.au-dot-on {
    width: 2.25rem;
    background-color: rgb(255 255 255 / 92%);
}

.au-dot:focus-visible {
    outline: 2px solid var(--color-white, #fff);
    outline-offset: 3px;
}

/* The one line that does not fade with the pictures. */
.au-aside-note {
    margin-top: 1.5rem;
    font-size: var(--text-xs, 0.75rem);
    line-height: 1.5;
    color: rgb(255 255 255 / 62%);
}

/* ------------------------------------------------------------------ *
 * The right half — the form's column
 *
 * The one element on this screen that scrolls, and the only one that should.
 *
 * `min-height: 0` is the line to leave alone. A grid item defaults to
 * `min-height: auto`, which is its content's height — so a tall form would push
 * the row past the shell's `height: 100dvh`, and the shell's `overflow: hidden`
 * would then clip the bottom of it with nothing able to scroll there: the submit
 * button, gone. The `overflow` below happens to resolve that automatic minimum to
 * zero on its own, which is to say the two declarations are each other's
 * insurance, and stating it explicitly is what stops somebody removing one of
 * them from also removing the other's effect.
 *
 * `hidden auto` and not bare `overflow-y`, because setting one axis and leaving
 * the other `visible` is a combination CSS does not have: the `visible` computes
 * to `auto`, which would put a horizontal scrollbar under a form that has no need
 * of one the first time a validation message ran a pixel wide.
 * ------------------------------------------------------------------ */

.au-main {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden auto;
    padding: 1.25rem;
    background-color: var(--color-white, #fff);
}

.dark .au-main {
    background-color: var(--gray-950);
}

@media (min-width: 40rem) {
    .au-main {
        padding: 1.75rem;
    }
}

.au-main-head {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.75rem;
    min-height: 2.25rem;
}

/*
 * The card, which is not a card.
 *
 * On the split layout the form sits directly on the column — no border, no
 * shadow, no second panel inside a panel. That is the single biggest difference
 * from Filament's centred box, and it is why this element carries the width and
 * the centring but no surface of its own.
 *
 * `fi-width-*` classes come from the page's own `$maxWidth`, and Filament's rules
 * for them only match `.fi-main` / `.fi-simple-main`, so they need honouring
 * here. Only the widths wider than the default are worth a rule — the public
 * contact directory is the page that asks for one.
 */
.au-card {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 26rem;

    /*
     * Centred vertically by auto margins rather than by `justify-content: center`
     * on the column, and the difference only shows on the form that does not fit.
     * Centred content that overflows overflows in *both* directions, and a scroll
     * container cannot scroll backwards past its start — so the top of a long
     * sign-up form would be cut off and unreachable, which is precisely the clipped
     * heading this file's `overflow` rules were changed to stop. Auto margins
     * resolve to zero when there is no free space to share out, so the form falls
     * back to starting at the top and scrolling normally.
     */
    margin: auto;
    padding-block: 1.5rem;
}

.au-card.fi-width-xl {
    max-width: var(--container-xl, 36rem);
}

.au-card.fi-width-2xl {
    max-width: var(--container-2xl, 42rem);
}

.au-card.fi-width-3xl {
    max-width: var(--container-3xl, 48rem);
}

.au-main-foot {
    display: grid;
    gap: 0.75rem;
}

/* ------------------------------------------------------------------ *
 * Filament's own page content, restyled inside the shell only
 * ------------------------------------------------------------------ */

.au-shell .fi-simple-page-content {
    row-gap: 1.75rem;
}

/*
 * Left-aligned, which is most of what makes this read as a modern auth screen
 * rather than a dialog box. Filament centres the header because it is drawing a
 * card in the middle of a page; here the column has an edge to align to.
 */
.au-shell .fi-simple-header {
    align-items: flex-start;
}

.au-shell .fi-simple-header-heading {
    text-align: start;
    letter-spacing: -0.02em;
}

.au-shell .fi-simple-header-subheading {
    margin-top: 0.5rem;
    text-align: start;
    line-height: 1.6;
}

/*
 * The page renders a logo of its own, because `SimplePage::hasLogo()` is true.
 * Above 1024px the aside is already showing it, so this is the duplicate — and
 * below 1024px, where the aside is gone, it is the only one. Suppressing it here
 * rather than overriding `hasLogo()` on seven pages is what makes that responsive
 * hand-off free.
 *
 * Four classes deep because Filament's dark-logo rule is three and would
 * otherwise tie.
 */
@media (min-width: 64rem) {
    .au-shell .fi-simple-page .fi-simple-header .fi-logo {
        display: none;
    }
}

/* ------------------------------------------------------------------ *
 * Fields and buttons
 *
 * Filament's inputs are already close to what was asked for — 14px medium
 * labels, an 8px radius, a two-pixel primary focus ring. What they are not is
 * tall enough: 36px reads as a dense admin table, and an auth form wants 40.
 * ------------------------------------------------------------------ */

.au-shell .fi-input-wrp :is(input, select, textarea).fi-input {
    padding-block: 0.5rem;
}

/*
 * The same 40px for a dropdown, which the rule above cannot reach: a select's
 * inner element carries `fi-select-input`, not `fi-input`. Without this a country
 * dropdown sits 36px beside a 40px text input — four pixels, on the two fields
 * that are side by side in the sign-up grid, which reads as a mistake rather than
 * as a difference.
 *
 * Both forms a `Select` can take, because which one Filament renders is decided
 * by `->searchable()` rather than by anything visible here: a native `<select>`
 * when it is off, and a button that opens a listbox when it is on. Both start from
 * 6px of padding against a 24px line-height, so the arithmetic is the same one the
 * inputs use — and `min-height: 2.25rem` on the button is a floor at 36, so
 * growing past it needs no override.
 *
 * Three classes deep to beat Filament's two.
 */
.au-shell .fi-input-wrp select.fi-select-input,
.au-shell .fi-input-wrp .fi-select-input-btn {
    padding-block: 0.5rem;
}

.au-shell .fi-fo-field .fi-fo-field-label-content {
    letter-spacing: -0.005em;
}

.au-shell .au-card .fi-btn {
    padding-block: 0.5625rem;
}

/* ------------------------------------------------------------------ *
 * The theme switcher
 *
 * Filament's active state is `--gray-50`, which is invisible on the white column
 * this now sits on — the component was drawn for the inside of a dropdown. A
 * plate behind it turns the three buttons into the segmented control the rest of
 * the design implies.
 * ------------------------------------------------------------------ */

.au-theme .fi-theme-switcher {
    padding: 0.1875rem;
    border-radius: calc(var(--radius-md, 0.375rem) + 0.1875rem);
    background-color: var(--gray-100);
}

.dark .au-theme .fi-theme-switcher {
    background-color: var(--gray-800);
}

.au-theme .fi-theme-switcher-btn:not(.fi-active):hover {
    background-color: var(--gray-200);
}

.dark .au-theme .fi-theme-switcher-btn:not(.fi-active):hover {
    background-color: var(--gray-700);
}

.au-theme .fi-theme-switcher-btn.fi-active {
    background-color: var(--color-white, #fff);
    box-shadow: 0 1px 2px 0 rgb(0 0 0 / 8%);
}

.dark .au-theme .fi-theme-switcher-btn.fi-active {
    background-color: var(--gray-700);
    box-shadow: none;
}

/* ------------------------------------------------------------------ *
 * Reduced motion
 *
 * The carousel's timer is already skipped in JavaScript when this is set, so
 * these two rules only cover the transition Alpine writes inline on the element
 * — which needs `!important` to beat an inline style, and is the one place in
 * this file that earns it.
 * ------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
    .au-slide-img,
    .au-slide-copy,
    .au-dot {
        transition: none !important;
    }
}
