/* Nexus – authentication pages.
   "Diprella" sliding sign-in / sign-up design adapted to the Nexus flow.
   Night-blue gradient overlay, rounded white card, pill buttons. */

/* ---- Font (Lexend variable) ---------------------------------------------- */
@font-face {
    font-family: 'Lexend';
    src: url('/assets/fonts/Lexend-VariableFont_wght.ttf') format('truetype-variations');
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

:root {
    --bg: #05060f;
    --card-bg: #ffffff;
    --text: #1f2433;
    --text-muted: #7a8194;
    --field-bg: #eef0f5;
    --night-1: #01020a;
    --night-2: #181a36;
    /* Marine (structure: links, focus, overlay, structural elements). */
    --navy: #20306e;
    --navy-2: #2b3e8c;
    --navy-hover: #18254f;
    /* Coral (primary actions, dynamic accents: CTAs, progress, active step). */
    --coral: #ff6f5e;
    --coral-hover: #ec5747;
    --coral-soft: #ffe9e6;
    /* `--accent*` kept pointing at marine for all the structural usages. */
    --accent: #20306e;
    --accent-2: #2b3e8c;
    --accent-hover: #18254f;
    --accent-soft: #e7eaf6;
    --valid: #2dd49a;
    --error-bg: #fdecec;
    --error-text: #9b2226;
    --success-bg: #e6f7ee;
    --success-text: #1e6b38;
    --battlenet: #0a1c3b;
    --battlenet-accent: #1b59a6;
    --bnet: #1b59a6;
    --discord: #3b43a8;
    --shadow: 0 22px 50px rgba(1, 2, 10, 0.45), 0 10px 18px rgba(1, 2, 10, 0.3);
}

/* ---- Cross-document step transitions (progressive enhancement) ------------
   Browsers that support the multi-document View Transitions API will fade /
   slide between the registration step pages. Unsupported browsers simply
   navigate normally. This does not affect the same-document /login <-> /register
   slide handled in JS via pushState. */
@view-transition {
    navigation: auto;
}

::view-transition-old(root) {
    animation: nexus-slide-out 0.45s ease both;
}

::view-transition-new(root) {
    animation: nexus-slide-in 0.45s ease both;
}

@keyframes nexus-slide-out {
    to {
        opacity: 0;
        transform: translateX(-3%);
    }
}

@keyframes nexus-slide-in {
    from {
        opacity: 0;
        transform: translateX(3%);
    }
}

@media (prefers-reduced-motion: reduce) {
    ::view-transition-old(root),
    ::view-transition-new(root) {
        animation: none;
    }
}



html {
    height: 100%;
}

body {
    margin: 0;
    /* min-height (not height): on mobile, pages taller than the viewport must
       scroll normally instead of being cut off. */
    min-height: 100%;
}

body {
    font-family: 'Lexend', system-ui, -apple-system, "Segoe UI", sans-serif;
    background: radial-gradient(circle at 50% 0%, #11142b 0%, #05060f 60%, #03040a 100%);
    color: var(--text);
    font-weight: 400;
    -webkit-font-smoothing: antialiased;
}

/* Form elements don't always inherit the family. */
input,
button,
textarea,
select,
a.btn-pill,
a.btn-ghost,
a.btn-ghost-dark {
    font-family: 'Lexend', system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* ---- Page layout ---------------------------------------------------------- */
.page {
    box-sizing: border-box;
    min-height: 100vh;
    display: flex;
    /* Column: the card stays centred and the legal footer flows below it. */
    flex-direction: column;
    align-items: center;
    justify-content: center;
    /* Extra top padding keeps the card clear of the absolute lang-switcher. */
    padding: 64px 24px 32px;
    position: relative;
}

/* ---- Language switcher ---------------------------------------------------- */
.lang-switcher {
    position: absolute;
    top: 20px;
    right: 24px;
    display: flex;
    gap: 8px;
    font-size: 13px;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.7);
    z-index: 200;
}

.lang-switcher a {
    color: rgba(255, 255, 255, 0.7);
    text-decoration: none;
    transition: color 0.15s ease;
}

.lang-switcher a:hover {
    color: #fff;
}

.lang-switcher a.active {
    color: #fff;
    text-decoration: underline;
}

.lang-switcher span {
    color: rgba(255, 255, 255, 0.4);
}

/* ---- Card / container ----------------------------------------------------- */
.container {
    position: relative;
    width: 1040px;
    max-width: 100%;
    /* Tall enough for the signup form with the CGU row and the expanded
       password-criteria panel, but never taller than the viewport (the page
       padding is subtracted). When content is taller than the card, the
       form panels scroll internally instead of overlapping/clipping. */
    min-height: min(640px, calc(100vh - 96px));
    background: var(--card-bg);
    border-radius: 18px;
    box-shadow: var(--shadow);
    overflow: hidden;
}

/* Sliding form containers (only used on the auth-landing page). */
.form-container {
    position: absolute;
    top: 0;
    height: 100%;
    width: 60%;
    transition: transform 0.6s ease-in-out, opacity 0.6s ease-in-out;
    display: flex;
    /* Content taller than the card scrolls inside the panel instead of
       being clipped by the container's overflow:hidden. The inner form uses
       margin:auto (overflow-safe centring) rather than align/justify-center. */
    overflow-y: auto;
}

.sign-in-container {
    left: 0;
    z-index: 2;
    opacity: 1;
}

.sign-up-container {
    left: 0;
    z-index: 1;
    opacity: 0;
    pointer-events: none;
    /* Fully remove the hidden panel from hit-testing/painting once the slide
       is over; the 0.6s delay keeps it paintable during the transition. */
    visibility: hidden;
    transition: transform 0.6s ease-in-out, opacity 0.6s ease-in-out,
                visibility 0s linear 0.6s;
}

.auth-form,
.form-inner {
    box-sizing: border-box;
    width: 100%;
    max-width: 460px;
    padding: 28px 40px;
    margin: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

/* ---- Headings ------------------------------------------------------------- */
.form-title {
    margin: 0 0 18px;
    font-size: 26px;
    font-weight: 700;
    color: var(--accent);
    letter-spacing: -0.01em;
}

.info-text {
    color: var(--text-muted);
    font-size: 14px;
    line-height: 1.55;
    margin: 8px 0;
    text-align: left;
    width: 100%;
}

.form-hint {
    font-size: 12px;
    color: var(--text-muted);
    margin: 6px 0 12px;
}

/* Email verification: centred "code sent to" line + highlighted address. */
.verify-instruction {
    text-align: justify;
}

.verify-sent {
    text-align: center;
    margin: 2px 0 4px;
}

.verify-email-address {
    width: 100%;
    margin: 0 0 18px;
    font-size: 16px;
    font-weight: 700;
    color: var(--coral);
    text-align: center;
    word-break: break-all;
}

/* ---- Inputs --------------------------------------------------------------- */
.input-group {
    width: 100%;
    position: relative;
    display: flex;
    align-items: center;
    background: var(--field-bg);
    border-radius: 10px;
    margin: 7px 0;
    transition: box-shadow 0.15s ease;
}

.input-group:focus-within {
    box-shadow: 0 0 0 2px var(--accent);
}

.input-group .input-icon {
    color: var(--text-muted);
    margin: 0 10px;
    flex: 0 0 auto;
}

/* Google Material Symbols webfont, sized as a soft-grey input adornment. */
.material-symbols-outlined {
    font-family: 'Material Symbols Outlined';
    font-weight: normal;
    font-style: normal;
    line-height: 1;
    letter-spacing: normal;
    white-space: nowrap;
    direction: ltr;
    -webkit-font-feature-settings: 'liga';
    -webkit-font-smoothing: antialiased;
    font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;
}

.input-group .input-icon.material-symbols-outlined {
    font-size: 20px;
    color: var(--text-muted);
}

.input-group input {
    flex: 1 1 auto;
    width: 100%;
    border: none;
    background: transparent;
    padding: 12px 12px 12px 0;
    font-size: 14px;
    color: var(--text);
    outline: none;
}

.input-group input::placeholder {
    color: var(--text-muted);
}

/* Show / hide password toggle, sitting inside the input pill. */
.pw-toggle {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: transparent;
    color: var(--text-muted);
    padding: 4px;
    margin-right: 8px;
    border-radius: 50%;
    cursor: pointer;
    transition: color 0.15s ease;
}

.pw-toggle:hover {
    color: var(--navy);
}

.pw-toggle .material-symbols-outlined {
    font-size: 20px;
    line-height: 1;
}

/* ---- Registration field grid (email full width, passwords side by side) --- */
.field-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.75rem;
    width: 100%;
}

.field-row .input-group {
    margin: 7px 0 0;
}

/* ---- Pill + ghost buttons ------------------------------------------------- */
.btn-pill {
    display: inline-block;
    width: 100%;
    margin-top: 16px;
    padding: 12px 40px;
    border: none;
    border-radius: 999px;
    background: linear-gradient(135deg, var(--coral), var(--coral-hover));
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    box-shadow: 0 8px 18px rgba(255, 111, 94, 0.28);
    transition: transform 0.12s ease, filter 0.15s ease, box-shadow 0.15s ease;
}

.btn-pill:hover {
    filter: brightness(1.04);
    box-shadow: 0 10px 22px rgba(255, 111, 94, 0.36);
}

.btn-pill:active {
    transform: scale(0.97);
}

/* Provider link buttons: brand colour with the provider logo as a large,
   faint watermark. Text stays readable on top. border-box keeps the
   width:100% pill inside its container (no right-edge overflow). */
.btn-pill.btn-battlenet,
.btn-pill.btn-discord {
    position: relative;
    z-index: 0;
    overflow: hidden;
    box-shadow: none;
    box-sizing: border-box;
    width: 100%;
    max-width: 100%;
}

.btn-pill.btn-battlenet::after,
.btn-pill.btn-discord::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 66%;
    width: 64px;
    height: 64px;
    transform: translate(-50%, -50%);
    opacity: 0.18;
    background-position: center;
    background-repeat: no-repeat;
    background-size: contain;
    pointer-events: none;
    /* Behind the button label, above the brand-coloured background. */
    z-index: -1;
}

.btn-pill.btn-battlenet {
    background: var(--battlenet-accent);
}

.btn-pill.btn-battlenet::after {
    background-image: url('/assets/img/battle-net-logo.svg');
}

.btn-pill.btn-discord {
    background: var(--discord);
}

.btn-pill.btn-discord::after {
    background-image: url('/assets/img/discord-logo.svg');
}

.btn-ghost {
    display: inline-block;
    margin-top: 18px;
    padding: 12px 44px;
    border: 3px solid #fff;
    border-radius: 999px;
    background: transparent;
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}

.btn-ghost:hover {
    background: rgba(255, 255, 255, 0.16);
}

.btn-ghost-dark {
    display: inline-block;
    width: 100%;
    margin-top: 12px;
    padding: 11px 28px;
    border: 1px solid var(--accent);
    border-radius: 999px;
    background: transparent;
    color: var(--accent);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}

.btn-ghost-dark:hover {
    background: var(--accent);
    color: #fff;
}

.form-link {
    font-size: 13px;
    color: var(--text-muted);
    text-decoration: none;
    margin: 12px 0 4px;
}

.form-link:hover {
    color: var(--accent);
}

/* ---- Social round buttons ------------------------------------------------- */
.social-round {
    display: flex;
    gap: 12px;
    margin: 4px 0 6px;
}

.social-btn {
    --brand: var(--accent);
    width: 46px;
    height: 46px;
    border-radius: 50%;
    border: 3px solid var(--brand);
    background: color-mix(in srgb, var(--brand) 12%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    transition: transform 0.12s ease, background 0.15s ease, box-shadow 0.15s ease;
}

/* Icon recoloured to the brand colour via CSS mask (source SVGs are white). */
.social-btn .icon {
    width: 22px;
    height: 22px;
    display: block;
    background-color: var(--brand);
}

.social-btn .icon-battlenet {
    -webkit-mask: url('/assets/img/battle-net-logo.svg') center / contain no-repeat;
    mask: url('/assets/img/battle-net-logo.svg') center / contain no-repeat;
}

.social-btn .icon-discord {
    -webkit-mask: url('/assets/img/discord-logo.svg') center / contain no-repeat;
    mask: url('/assets/img/discord-logo.svg') center / contain no-repeat;
}

.social-btn:hover {
    transform: translateY(-2px);
    background: color-mix(in srgb, var(--brand) 22%, transparent);
    box-shadow: 0 6px 12px rgba(0, 0, 0, 0.18);
}

.social-battlenet {
    --brand: var(--bnet);
}

.social-discord {
    --brand: var(--discord);
}

/* ---- "──── or ────" divider on the sign-in form --------------------------- */
.divider {
    display: flex;
    align-items: center;
    width: 100%;
    margin: 10px 0 6px;
    color: var(--text-muted);
}

.divider::before,
.divider::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: #d8dce6;
}

.divider-label {
    padding: 0 12px;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

/* ---- Password rules checklist (live) -------------------------------------- */
.pw-rules {
    list-style: none;
    margin: 0;
    padding: 0;
    width: 100%;
    text-align: left;
}

.pw-rules li {
    position: relative;
    padding-left: 26px;
    margin: 6px 0;
    font-size: 12.5px;
    color: var(--text-muted);
    transition: color 0.2s ease;
}

/* Unmet marker — Material Symbol drawn via ::before. */
.pw-rules li::before {
    content: "radio_button_unchecked";
    font-family: 'Material Symbols Outlined';
    font-size: 18px;
    line-height: 1;
    position: absolute;
    left: 0;
    top: -1px;
    color: #c2c8d6;
    transition: color 0.2s ease;
}

.pw-rules li.met {
    color: var(--success-text);
}

.pw-rules li.met::before {
    content: "check_circle";
    color: var(--valid);
}

/* ---- Password rules as a focus-anchored popover --------------------------- */
.pw-field-group {
    position: relative;
    width: 100%;
}

/* Inline-expanding panel: collapsed (max-height:0) until a password field
   inside the group gains focus, then it expands IN FLOW below the fields.
   Being in flow means it can never be clipped by the card's overflow:hidden
   nor cover the CGU checkbox / submit button — content below is pushed down
   (the form panel scrolls if needed). */
.pw-popover {
    box-sizing: border-box;
    width: 100%;
    max-height: 0;
    overflow: hidden;
    opacity: 0;
    margin: 0;
    padding: 0 16px;
    background: #f6f7fc;
    border-radius: 12px;
    transition: max-height 0.25s ease, opacity 0.2s ease,
                margin 0.25s ease, padding 0.25s ease;
}

/* Show while either password field (inside the group) is focused. */
.pw-field-group:focus-within .pw-popover {
    max-height: 260px;
    opacity: 1;
    margin: 10px 0 2px;
    padding: 12px 16px;
}

/* ---- Identity card (link confirmation) ------------------------------------ */
.identity-card {
    --brand: var(--accent);
    box-sizing: border-box;
    width: 100%;
    max-width: 100%;
    display: flex;
    flex-direction: row;
    /* Actions wrap below the info block when the card runs out of width. */
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    border: 1px solid #dfe3f2;
    background: #f4f6ff;
    border-radius: 14px;
    padding: 16px 18px;
    margin: 16px 0;
    text-align: left;
    box-shadow: 0 8px 20px rgba(1, 2, 10, 0.06);
}

.identity-card.identity-battlenet {
    --brand: var(--bnet);
}

.identity-card.identity-discord {
    --brand: var(--discord);
}

/* Provider badge: same masked-icon technique as the social round buttons. */
.identity-badge {
    flex: 0 0 auto;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    border: 3px solid var(--brand);
    background: color-mix(in srgb, var(--brand) 12%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
}

.identity-badge .icon {
    width: 26px;
    height: 26px;
    display: block;
    background-color: var(--brand);
}

.identity-badge .icon-battlenet {
    -webkit-mask: url('/assets/img/battle-net-logo.svg') center / contain no-repeat;
    mask: url('/assets/img/battle-net-logo.svg') center / contain no-repeat;
}

.identity-badge .icon-discord {
    -webkit-mask: url('/assets/img/discord-logo.svg') center / contain no-repeat;
    mask: url('/assets/img/discord-logo.svg') center / contain no-repeat;
}

.identity-info {
    flex: 1 1 auto;
    min-width: 0;
}

.identity-label {
    margin: 0 0 4px;
    font-size: 13px;
    color: var(--text-muted);
}

.identity-value {
    margin: 0;
    font-size: 19px;
    font-weight: 700;
    color: var(--brand);
    word-break: break-word;
}

.identity-actions {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* Button with a leading Material Symbol icon. */
.btn-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    white-space: nowrap;
}

.btn-icon .material-symbols-outlined {
    font-size: 19px;
    line-height: 1;
    flex: 0 0 auto;
}

/* Compact pill/ghost variants used inside the identity card actions. */
.identity-actions .btn-pill,
.identity-actions .btn-ghost-dark {
    width: auto;
    margin-top: 0;
    padding: 9px 18px;
    font-size: 12px;
    text-transform: none;
    letter-spacing: 0.02em;
}

/* ---- Reassurance box ------------------------------------------------------ */
.reassurance {
    width: 100%;
    border-left: 4px solid var(--accent);
    background: #f4f6ff;
    border-radius: 8px;
    padding: 12px 14px;
    margin: 14px 0;
    font-size: 12.5px;
    color: var(--text-muted);
    line-height: 1.5;
    text-align: left;
}

.reassurance p {
    margin: 0;
}

/* ---- Alerts --------------------------------------------------------------- */
.alert {
    width: 100%;
    padding: 10px 12px;
    border-radius: 8px;
    font-size: 13px;
    margin-bottom: 12px;
    text-align: left;
}

.alert-error {
    background: var(--error-bg);
    color: var(--error-text);
}

.alert-success {
    background: var(--success-bg);
    color: var(--success-text);
}

.alert-info {
    background: var(--accent-soft);
    color: #20306e;
}

.field-error {
    width: 100%;
    margin: 2px 0 4px;
    color: var(--error-text);
    font-size: 12px;
    text-align: left;
}

/* ---- Actions / footer ----------------------------------------------------- */
.actions {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 8px;
}

.inline-form {
    margin: 0;
    width: 100%;
}

.card-footer {
    margin: 18px 0 0;
    font-size: 13px;
    color: var(--text-muted);
}

.card-footer a {
    color: var(--accent);
    text-decoration: none;
    font-weight: 600;
}

.card-footer a:hover {
    text-decoration: underline;
}

/* ---- Overlay (sliding night-blue panel) ----------------------------------- */
.overlay-container {
    position: absolute;
    top: 0;
    left: 60%;
    width: 40%;
    height: 100%;
    overflow: hidden;
    transition: transform 0.6s ease-in-out;
    z-index: 100;
}

.overlay {
    position: relative;
    left: -100%;
    width: 200%;
    height: 100%;
    /* Night-blue gradient + an ALIGNED grid of small FILLED hexagon dots
       (straight rows and columns, no quincunx). The pattern is an inline SVG
       data-URI: a single 42×42 transparent tile holding ONE ~5px hexagon
       centred, light grey (#CFCFD1) at low opacity, tiled via
       background-repeat → a regular, well-spaced grid over the marine
       gradient. */
    background-color: #181a36;
    background-image:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='42' height='42' viewBox='0 0 42 42'%3E%3Cpolygon fill='%23CFCFD1' fill-opacity='0.10' points='21,18.4 23.25,19.7 23.25,22.3 21,23.6 18.75,22.3 18.75,19.7'/%3E%3C/svg%3E"),
        linear-gradient(135deg, #01020a 0%, #181a36 33%, #181a36 66%, #01020a 100%);
    background-repeat: repeat, no-repeat;
    color: #fff;
    transform: translateX(0);
    transition: transform 0.6s ease-in-out;
}

/* Guild logo as a discreet centred watermark behind the overlay text. */
.overlay-watermark {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    height: 80%;
    width: auto;
    max-width: 70%;
    object-fit: contain;
    opacity: 0.07;
    pointer-events: none;
    z-index: 0;
}

.overlay-panel {
    box-sizing: border-box;
    position: absolute;
    top: 0;
    width: 50%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    /* Comfortable side gutters: title/text/hint never touch the panel edges. */
    padding: 0 32px;
    text-align: center;
    z-index: 1;
    transition: transform 0.6s ease-in-out;
}

.overlay-panel h1 {
    margin: 12px 0 10px;
    font-size: 26px;
    font-weight: 700;
}

.overlay-panel p {
    margin: 0 0 8px;
    font-size: 14px;
    line-height: 1.6;
    font-weight: 300;
}

.overlay-panel .overlay-hint {
    font-size: 12px;
    opacity: 0.85;
}

.overlay-left {
    left: 0;
    transform: translateX(0);
}

.overlay-right {
    right: 0;
    transform: translateX(0);
}

/* ---- Slide animation state (auth-landing only) ---------------------------- */
.container.right-panel-active .sign-in-container {
    transform: translateX(66.667%);
    opacity: 0;
    z-index: 1;
    pointer-events: none;
    /* Hidden once the slide completes (delayed so the cross-fade still shows). */
    visibility: hidden;
    transition: transform 0.6s ease-in-out, opacity 0.6s ease-in-out,
                visibility 0s linear 0.6s;
}

.container.right-panel-active .sign-up-container {
    transform: translateX(66.667%);
    opacity: 1;
    z-index: 5;
    pointer-events: auto;
    visibility: visible;
    transition: transform 0.6s ease-in-out, opacity 0.6s ease-in-out,
                visibility 0s linear 0s;
    animation: show 0.6s;
}

.container.right-panel-active .overlay-container {
    transform: translateX(-150%);
}

.container.right-panel-active .overlay {
    transform: translateX(50%);
}

.container.right-panel-active .overlay-left {
    transform: translateX(0);
}

.container.right-panel-active .overlay-right {
    transform: translateX(0);
}

@keyframes show {
    0%, 49.99% {
        opacity: 0;
        z-index: 1;
    }
    50%, 100% {
        opacity: 1;
        z-index: 5;
    }
}

/* ---- Shell pages (fixed overlay on the left, content on the right) --------- */
.shell-overlay {
    width: 40%;
    left: 0;
}

.shell-overlay .overlay {
    left: 0;
    width: 100%;
}

.shell-overlay .overlay-left {
    width: 100%;
    transform: none;
}

.shell-content {
    width: 60%;
    left: 40%;
    opacity: 1;
    z-index: 2;
    overflow-y: auto;
}

/* Shell content uses a wider measure than the landing forms (560px) so the
   step pages exploit the 60% column instead of leaving large side gutters.
   margin:auto = overflow-safe centring inside the scrollable panel. */
.shell-content .form-inner {
    max-width: 560px;
    margin: auto;
    padding: 36px 44px;
}

/* Direct-child wrapper divs (conditional blocks around identity cards /
   provider buttons) stretch to the full measure. */
.shell-content .form-inner > div {
    width: 100%;
}

/* ---- Stepper / timeline (registration steps) ------------------------------ */
.stepper {
    width: 100%;
    margin: 0 0 22px;
}

.stepper-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
}

.stepper-item {
    position: relative;
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    text-align: center;
    min-width: 0;
}

/* Connecting track between bullets (drawn from the centre to the right). */
.stepper-item:not(:last-child)::after {
    content: "";
    position: absolute;
    top: 15px;
    left: calc(50% + 16px);
    right: calc(-50% + 16px);
    height: 2px;
    background: #dfe3f2;
    z-index: 0;
}

.stepper-item.is-done:not(:last-child)::after {
    background: var(--navy);
}

.stepper-bullet {
    position: relative;
    z-index: 1;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #eef0f5;
    color: #b3bacb;
    border: 2px solid #dfe3f2;
    transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.stepper-bullet .material-symbols-outlined {
    font-size: 18px;
    line-height: 1;
}

/* Real provider logos for the Battle.net / Discord steps, recoloured with the
   same CSS-mask technique as .social-btn .icon. currentColor follows the
   bullet's state colour (todo grey, active white-on-coral); validated steps
   keep the Material check like every other step. */
.stepper-bullet .step-logo {
    width: 16px;
    height: 16px;
    display: block;
    background-color: currentColor;
}

.stepper-bullet .step-logo-battlenet {
    -webkit-mask: url('/assets/img/battle-net-logo.svg') center / contain no-repeat;
    mask: url('/assets/img/battle-net-logo.svg') center / contain no-repeat;
}

.stepper-bullet .step-logo-discord {
    -webkit-mask: url('/assets/img/discord-logo.svg') center / contain no-repeat;
    mask: url('/assets/img/discord-logo.svg') center / contain no-repeat;
}

.stepper-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    line-height: 1.2;
    word-break: break-word;
}

/* Done: marine bullet with a check. */
.stepper-item.is-done .stepper-bullet {
    background: var(--navy);
    border-color: var(--navy);
    color: #fff;
}

.stepper-item.is-done .stepper-label {
    color: var(--navy);
}

/* Active: coral bullet, emphasised. */
.stepper-item.is-active .stepper-bullet {
    background: var(--coral);
    border-color: var(--coral);
    color: #fff;
    box-shadow: 0 0 0 4px var(--coral-soft);
}

.stepper-item.is-active .stepper-label {
    color: var(--coral-hover);
    font-weight: 700;
}

/* ---- Verification code entry --------------------------------------------- */
.code-form {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
}

/* Repurposed as the centred instruction above the digit cells. */
.code-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
    margin: 4px 0 14px;
    text-align: center;
}

/* ---- Per-digit lozenge code cells ---------------------------------------- */
/* Each cell is a parallelogram leaning the same way as the countdown bar just
   below it, so the digit row and the progress bar read as one continuous unit.
   `--cell-slant` drives the lean and is shared by the bar (overridden on small
   screens). */
.code-boxes {
    display: flex;
    justify-content: center;
    gap: 9px;
    width: 100%;
    --cell-slant: 14px;
}

.code-cell {
    position: relative;
    display: inline-grid;
    place-items: center;
    flex: 1 1 0;
    max-width: 62px;
    height: 56px;
    /* Lozenge: flat top/bottom, parallel edges slanted like "/". */
    clip-path: polygon(var(--cell-slant) 0, 100% 0, calc(100% - var(--cell-slant)) 100%, 0 100%);
    background: #dfe3f2;
    transition: background 0.15s ease, filter 0.15s ease;
}

/* Inner fill, inset by the cell so the parent reads as a slanted border. */
.code-cell::before {
    content: "";
    position: absolute;
    inset: 1.5px;
    z-index: 0;
    clip-path: inherit;
    background: var(--field-bg);
}

.code-box {
    position: relative;
    z-index: 1;
    box-sizing: border-box;
    width: 100%;
    height: 100%;
    border: none;
    outline: none;
    background: transparent;
    text-align: center;
    font-size: 24px;
    font-weight: 700;
    color: var(--text);
    caret-color: var(--coral);
}

.code-cell:focus-within {
    background: var(--accent);
    filter: drop-shadow(0 4px 10px rgba(32, 48, 110, 0.25));
}

.code-cell.is-filled {
    background: var(--coral);
}

.code-boxes:has(.code-box:disabled) {
    opacity: 0.55;
}

.code-box:disabled {
    cursor: not-allowed;
}

/* ---- Resend / change-email action row ------------------------------------ */
.verify-actions {
    display: flex;
    gap: 12px;
    width: 100%;
    margin-top: 16px;
}

.verify-actions .inline-form {
    flex: 1 1 0;
    width: auto;
}

.verify-actions .btn-ghost-dark {
    width: 100%;
    margin-top: 0;
    padding: 11px 14px;
}

.verify-actions > .btn-ghost-dark {
    flex: 1 1 0;
}

/* ---- Countdown progress bar ---------------------------------------------- */
/* Sits right under the digit row and shares its "/" slant, so the lozenge
   cells appear to rest on a continuous slanted base. */
.code-countdown {
    width: 100%;
    margin: 9px 0 4px;
}

.progress-track {
    width: 100%;
    height: 9px;
    border-radius: 0;
    clip-path: polygon(3px 0, 100% 0, calc(100% - 3px) 100%, 0 100%);
    background: #eef0f5;
    overflow: hidden;
}

.progress-bar {
    height: 100%;
    width: 100%;
    border-radius: 0;
    background: linear-gradient(90deg, var(--coral), var(--coral-hover));
    /* Width is driven by JS; keep the transition smooth. */
    transition: width 0.5s linear, background 0.3s ease;
}

.code-countdown.is-low .progress-bar {
    background: linear-gradient(90deg, #f0a23a, var(--coral-hover));
}

.countdown-text {
    margin: 8px 0 0;
    font-size: 12.5px;
    color: var(--text-muted);
    text-align: center;
}

.countdown-text [data-countdown-text] {
    font-weight: 700;
    color: var(--navy);
}

.countdown-expired {
    display: none;
    margin: 8px 0 0;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--error-text);
    text-align: center;
}

.code-countdown.is-expired .countdown-text {
    display: none;
}

.code-countdown.is-expired .countdown-expired {
    display: block;
}

/* ---- Terms (CGU) checkbox ------------------------------------------------- */
.terms-check {
    width: 100%;
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 12px 0 2px;
    text-align: left;
    font-size: 13px;
    color: var(--text-muted);
    cursor: pointer;
}

.terms-check input[type="checkbox"] {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    margin-top: 1px;
    accent-color: var(--coral);
    cursor: pointer;
}

.terms-text a {
    color: var(--navy);
    font-weight: 600;
    text-decoration: underline;
}

.terms-text a:hover {
    color: var(--coral-hover);
}

.brand {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    margin-bottom: 22px;
    max-width: 100%;
}

.brand-icon {
    height: 150px;
    max-width: 100%;
    width: auto;
    display: block;
}

.brand-wordmark {
    height: 56px;
    max-width: 100%;
    width: auto;
    display: block;
}

/* ---- Legal footer (below the card, on the dark page background) ------------ */
.legal-footer {
    margin-top: 22px;
    font-size: 12px;
    line-height: 1.7;
    color: rgba(255, 255, 255, 0.55);
    text-align: center;
}

.legal-footer p {
    margin: 0;
}

.legal-footer a {
    color: rgba(255, 255, 255, 0.55);
    text-decoration: none;
    transition: color 0.15s ease;
}

.legal-footer a:hover {
    color: rgba(255, 255, 255, 0.85);
    text-decoration: underline;
}

.legal-footer a:focus-visible {
    outline-color: #fff;
}

.legal-footer .legal-sep {
    margin: 0 7px;
    color: rgba(255, 255, 255, 0.3);
}

/* ---- Visible keyboard focus (consistent marine ring) ----------------------- */
a:focus-visible,
button:focus-visible,
input[type="checkbox"]:focus-visible {
    outline: 2px solid var(--navy);
    outline-offset: 2px;
}

/* Elements sitting on the night-blue overlay / page background get a white
   ring instead (marine would be invisible). */
.btn-ghost:focus-visible,
.lang-switcher a:focus-visible,
.overlay-panel a:focus-visible {
    outline-color: #fff;
}

/* Text inputs keep their existing pill focus ring (box-shadow). */
.input-group input:focus-visible,
.code-box:focus-visible {
    outline: none;
}

/* ---- Submitting state (double-click guard + spinner) ----------------------- */
button.is-loading {
    opacity: 0.75;
    pointer-events: none;
    cursor: wait;
}

button.is-loading::after {
    content: "";
    display: inline-block;
    width: 13px;
    height: 13px;
    margin-left: 8px;
    vertical-align: -2px;
    border-radius: 50%;
    border: 2px solid color-mix(in srgb, currentColor 35%, transparent);
    border-top-color: currentColor;
    animation: nexus-spin 0.7s linear infinite;
}

@keyframes nexus-spin {
    to {
        transform: rotate(360deg);
    }
}

/* ---- Responsive: stacked layout on phones / small tablets (≤768px) --------- */
/* The sliding card becomes a vertical stack: the night-blue overlay turns into
   a compact banner at the TOP (reduced brand, title, short text and — on the
   landing page — the visible sign-in/sign-up toggle), with the active form
   below at full width. There is no horizontal slide on mobile: auth.js only
   intercepts the toggle links on ≥769px, so here they perform a normal server
   navigation and the server renders the requested mode. */
@media (max-width: 768px) {
    /* The page scrolls normally (min-heights only, never a fixed height);
       tighter gutters leave more width for the card on 360-420px screens.
       The 56px top padding keeps the card clear of the lang-switcher. */
    .page {
        padding: 56px 14px 28px;
    }

    /* Top-right of the dark page background, above the overlay banner and
       overlapping nothing (the card starts below the page's top padding). */
    .lang-switcher {
        top: 16px;
        right: 16px;
    }

    /* The card becomes a flex column so the overlay banner can be reordered
       ABOVE the forms (on the landing page the overlay sits LAST in the DOM). */
    .container {
        width: 100%;
        min-height: 0;
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }

    /* Disable sliding / absolute positioning: every panel becomes a normal
       block stacked in flow, transforms and slide transitions are off. */
    .form-container,
    .overlay-container,
    .overlay,
    .overlay-panel {
        position: relative;
        width: 100%;
        left: 0;
        right: 0;
        transform: none !important;
        transition: none;
        height: auto;
    }

    /* No inner scroll area on mobile: the whole page scrolls instead (also
       avoids a stray horizontal scrollbar from overflow-y:auto panels). */
    .form-container {
        overflow: visible;
    }

    .overlay {
        left: 0;
    }

    /* Compact banner at the top of the card. */
    .overlay-container {
        order: -1;
        z-index: 1;
        border-radius: 18px 18px 0 0;
    }

    /* width:100% + padding must not overflow: border-box (the desktop panels
       are absolutely positioned and clipped, mobile ones are in flow). */
    .overlay-panel {
        box-sizing: border-box;
        padding: 24px 20px 26px;
    }

    .overlay-panel h1 {
        margin: 8px 0;
        font-size: 21px;
    }

    .overlay-panel p {
        font-size: 13px;
    }

    /* Brand reduced to banner size. */
    .overlay-panel .brand {
        gap: 8px;
        margin-bottom: 10px;
    }

    .brand-icon {
        height: 64px;
    }

    .brand-wordmark {
        height: 28px;
    }

    /* Full-width form column with ~20px side padding. The .shell-content
       variant is repeated to outrank the desktop `.shell-content .form-inner`
       rule (36px/44px padding, 560px measure). */
    .auth-form,
    .form-inner,
    .shell-content .form-inner {
        padding: 28px 20px 32px;
        max-width: 100%;
    }

    /* Tap-friendly fields: ≥16px font (prevents iOS auto-zoom on focus) and a
       ≥44px tall pill (13+13px padding + 19px line). */
    .input-group input {
        font-size: 16px;
        padding: 13px 12px 13px 0;
    }

    /* Larger tap target for the show/hide password toggle. */
    .pw-toggle {
        padding: 8px;
        margin-right: 4px;
    }

    /* Full-width padded blocks: border-box so they cannot push past the
       narrower mobile form column. */
    .alert,
    .reassurance {
        box-sizing: border-box;
    }

    /* Tap-friendly buttons (≈44px incl. borders). border-box keeps the
       width:100% pills inside the form's content box (on desktop they
       deliberately bleed into the form padding). */
    .btn-pill,
    .btn-ghost,
    .btn-ghost-dark {
        box-sizing: border-box;
    }

    .btn-pill {
        padding: 14px 24px;
    }

    .btn-ghost {
        padding: 11px 36px;
    }

    .btn-ghost-dark {
        padding: 13px 20px;
    }

    /* Passwords stack in a single column on mobile. */
    .field-row {
        grid-template-columns: 1fr;
        gap: 0;
    }

    /* Stepper: compact — icon-only bullets, only the ACTIVE step keeps its
       label. Items are flex:1 / min-width:0, so 5 steps fit in 360px with no
       horizontal overflow. */
    .stepper {
        margin-bottom: 18px;
    }

    .stepper-bullet {
        width: 28px;
        height: 28px;
    }

    .stepper-bullet .material-symbols-outlined {
        font-size: 16px;
    }

    .stepper-bullet .step-logo {
        width: 14px;
        height: 14px;
    }

    /* 28px bullet + 2px borders = 32px outer box: track recentred at 15px. */
    .stepper-item:not(:last-child)::after {
        top: 15px;
        left: calc(50% + 14px);
        right: calc(-50% + 14px);
    }

    .stepper-label {
        display: none;
    }

    .stepper-item.is-active .stepper-label {
        display: block;
    }

    /* Identity card stacks: badge, info, then full-width actions. border-box
       so width:100% + padding stays inside the form column. */
    .identity-card {
        box-sizing: border-box;
        flex-direction: column;
        align-items: stretch;
        text-align: center;
        gap: 12px;
    }

    .identity-badge {
        margin: 0 auto;
    }

    .identity-actions {
        flex-direction: column;
    }

    /* Both action buttons are .btn-icon (inline-flex): min-height centres the
       label and guarantees a ≥44px tap target. */
    .identity-actions .btn-pill,
    .identity-actions .btn-ghost-dark {
        width: 100%;
        min-height: 44px;
        padding: 10px 18px;
    }

    /* On mobile the checklist is always expanded (no focus dance) and stays
       inside the form column (no side padding to overflow). */
    .pw-popover {
        max-height: none;
        opacity: 1;
        background: transparent;
        padding: 8px 0 0;
        margin: 4px 0 0;
    }

    .pw-field-group:focus-within .pw-popover {
        margin: 4px 0 0;
        padding: 8px 0 0;
    }

    /* Landing page: show only the active form and its matching overlay panel;
       the inactive form/panel is fully removed (no slide). `animation:none`
       and `transition:none` neutralise the desktop slide rules that still
       match in the right-panel-active state. */
    .sign-in-container,
    .sign-up-container {
        opacity: 1;
        pointer-events: auto;
    }

    .sign-up-container {
        display: none;
    }

    .container.right-panel-active .sign-up-container {
        display: flex;
        opacity: 1;
        pointer-events: auto;
        animation: none;
        transition: none;
    }

    .container.right-panel-active .sign-in-container {
        display: none;
        transition: none;
    }

    .container.right-panel-active .overlay-right {
        display: flex;
    }

    .overlay-left {
        display: flex;
    }

    .container.right-panel-active .overlay-left {
        display: none;
    }

    .overlay-right {
        display: none;
    }
}

/* ---- Responsive: very small phones (≤420px) -------------------------------- */
@media (max-width: 420px) {
    .page {
        padding: 52px 10px 24px;
    }

    .overlay-panel {
        padding: 20px 16px 22px;
    }

    .overlay-panel h1 {
        font-size: 19px;
    }

    .overlay-panel p {
        font-size: 12.5px;
    }

    .brand-icon {
        height: 56px;
    }

    .brand-wordmark {
        height: 24px;
    }

    /* Step pages: drop the overlay copy, keep the brand as a minimal banner.
       The landing page keeps its text + toggle button (needed to switch
       between sign-in and sign-up). */
    .shell-overlay .overlay-panel {
        padding: 18px 16px;
    }

    .shell-overlay .overlay-panel h1,
    .shell-overlay .overlay-panel p {
        display: none;
    }

    .shell-overlay .brand {
        margin-bottom: 0;
    }

    .auth-form,
    .form-inner,
    .shell-content .form-inner {
        padding: 24px 16px 28px;
    }

    .form-title {
        font-size: 22px;
    }

    /* Icon-only stepper: even the active label goes on very narrow screens. */
    .stepper-item.is-active .stepper-label {
        display: none;
    }

    /* 6-digit code: tighter gap, shorter cells and a gentler slant so the
       lozenge row never overflows on narrow screens. */
    .code-boxes {
        gap: 6px;
        --cell-slant: 10px;
    }

    .code-cell {
        height: 50px;
    }

    .code-box {
        font-size: 21px;
    }

    /* Stack the resend / change-email actions on very narrow screens. */
    .verify-actions {
        flex-direction: column;
    }
}
