"use client"
/**
* AuthShell — the two-column frame every pre-auth surface wears.
*
* Left: a promo rail. Right: the form, and a support footer that stays reachable
* whether or not sign-in succeeds.
*
* The rail is the first thing to go below `lg`. It carries no task, so on a
* phone it would push the one control that matters below the fold; the brand
* lockup moves inline above the form instead so the page still identifies itself.
*
* Heading contract: the rail's promo is an `h2` and the page supplies the single
* `h1`, because the reason you are here is signing in, not the conference.
*/
import * as React from "react"
import { MarketingBanner } from "@/components/ui/marketing-banner"
import { ProductMark, ProductWordmark } from "@/components/product-wordmark"
import { EXXAT_CORPORATE_BRAND } from "@/lib/product-brand"
import { cn } from "@/lib/utils"
/**
* One promo, held in code rather than rotated.
*
* A carousel here would move the page under someone mid-password and give a
* screen reader three competing pitches beside a single form. When this needs to
* change per season, change the object.
*/
const AUTH_PROMO = {
title: "Exxat User Conference 2026",
description: "Baltimore, MD. September 23 to 25, 2026.",
action: { label: "Register Today", href: "https://www.exxat.com/" },
/**
* Which slide artwork the promo wears. Production ships one of these per
* carousel slide; both live in `public/auth`, so swapping the promo to the
* Prism story is this line plus the copy above, not a layout change:
* `/auth/exxat-prism-visual.svg`.
*
* Purely decorative, so the alt text is empty and the overlay is `aria-hidden`
* — the promo already says what it is in the heading beside it.
*/
visual: "/auth/cohere-slide-visual.svg",
} as const
/** Corporate lockup: mark plus the word "Exxat", no product suffix. */
export function AuthBrandLockup({ className }: { className?: string }) {
return (
Exxat
)
}
/**
* The slide: a pastel canvas with the artwork laid over it, filling the panel
* from the top-left, which is how the production rail composes it. The vector is
* drawn to sit *on* that wash rather than to replace it — its own pink wedge
* supplies the saturated colour, and the canvas is what shows through wherever
* `contain` leaves the panel uncovered.
*
* Both layers live in one `decorativeOverlay` so they stay a single ordered
* stack under the copy. Painting the canvas on the banner root instead would put
* it behind the border and corner radius, and leave the wash and the art it
* belongs to in two different files.
*/
function AuthPromoVisual({ src }: { src: string }) {
return (
<>
{/* Bottom-anchored, where the reference says top. Identical on any panel
wider than the art's 0.87 ratio, because `contain` then fits by height
and there is no vertical gap to place. On a taller panel it fits by
width instead and letterboxes, and top-anchoring drops that gap under
the copy — bare pastel behind white text, which measured 1.11:1. Putting
the gap above the art instead costs nothing: no copy sits up there. */}
{/* The copy is white because the slide is, and the art's wedge is a
mid-pink that gives white only 3.9:1 at its deepest — over the 3:1 a
large title needs, under the 4.5:1 the meta line needs. Deepening the
wedge under the copy with its own hue family buys that back without
reading as a grey veil dropped on the artwork. Nothing here is
decorative: at 15% it is the difference between a passing and a failing
line, and axe cannot see it, because it does not evaluate what an image
paints behind text. */}
>
)
}
function AuthPromoRail() {
return (
)
}
function AuthSupportFooter() {
return (
// `text-xs`, not `text-sm`. The form column is under half the width now, and
// at 14px the help line wrapped to a second row, which turned a two-line
// footer into three and pushed the seam up into the form.
)
}
export function AuthShell({ children }: { children: React.ReactNode }) {
return (
// `data-auth-surface` remaps `--primary` to the corporate indigo for this
// subtree (see globals.css), so every step's primary button is Exxat's
// rather than the workspace charcoal, without a Button variant or a class
// on each step.
{/* Desktop only. Below `lg` the rail is gone and the full lockup
already sits above the form, so a second mark would say the
same thing twice. Decorative either way: the rail names Exxat
in text and the heading names the task. */}
{children}