﻿/* Dialog shell (root_templates/base_dialog.html): a framed card with the club
   header on top, in the visual language of the club setup wizard.
   Typography is the setup wizard's: sizes and weights come from the global
   rules (gui_components_base.css), this file only resets spacing. */


/* -------- ---- -------- */
/* -------- Page -------- */

/* base.css builds the app shell: html/body are 100% high, body does not
   scroll and <main> is the scroll container. The dialog pages scroll the
   document instead, so the footer sits below the card. The longhand keeps
   base.css' overflow-x: clip on body. */
html.dialog-page,
.dialog-page body {
    height: auto;
}

.dialog-page body {
    min-height: 100dvh;
    overflow-y: visible;
    font-family: 'Inter', sans-serif;
}

/* Top-aligned on purpose: a vertically centred card would move its header
   every time the card height changes between steps.
   At least one screen high, like the setup wizard's <main>, so the footer
   only shows once the user scrolls down. */
.dialog-main {
    min-height: 100vh;
    flex: 1 0 auto;
    overflow: visible;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: var(--large-gap) var(--pill-gap);
}

/* The document scrolls now, so an absolute toast would scroll out of view. */
.dialog-page .toast-container {
    position: fixed;
}


/* -------- ---------- -------- */
/* -------- Frame/card -------- */

.dialog-frame {
    width: 100%;
    max-width: calc(57.6rem + 2 * var(--pill-gap) + 2px);
    padding: var(--pill-gap);
    border: 1px solid var(--text-color);
}

/* overflow: clip keeps the sliding steps from poking out of the card */
.dialog-card {
    background-color: var(--gray-bg);
    border-radius: var(--pill-gap);
    box-shadow: 0 4px 12px rgb(0 0 0 / 0.25);
    overflow: clip;
}


/* -------- ------ -------- */
/* -------- Header -------- */

.dialog-header {
    position: relative;
    isolation: isolate; /* keeps the banner's z-index inside the header */
    display: flex;
    align-items: center;
    gap: var(--medium-gap);
    padding: var(--pill-gap) var(--medium-gap);
    border-radius: var(--pill-gap);
    background-color: var(--dark-gray-bg); /* while the banner loads */
    box-shadow: 0 4px 12px rgb(0 0 0 / 0.25);
}

.dialog-header__banner {
    position: absolute;
    inset: 0;
    z-index: -1;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: inherit;
}

.dialog-header__pill {
    flex: 1 1 auto;
    min-width: 0; /* lets the club name shrink and clip */
    height: var(--pill-h);
    display: flex;
    align-items: center;
    gap: var(--medium-gap);
    padding: 0 var(--medium-gap);
    background-color: var(--white-bg);
    border-radius: calc(var(--pill-h) / 2);
    box-shadow: 0 4px 12px rgb(0 0 0 / 0.25);
}

.dialog-header__logo {
    flex: 0 0 auto;
    width: calc(var(--pill-h) - var(--pill-gap));
    height: calc(var(--pill-h) - var(--pill-gap));
    border-radius: 50%;
    object-fit: cover;
}

/* Size from the global h1 (2.4rem, Bootstrap weight 500), like setup's header */
.dialog-header__name {
    min-width: 0;
    margin: 0;
    padding: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}


/* -------- ------------- -------- */
/* -------- Progress ring -------- */

.progress-ring {
    position: relative;
    flex: 0 0 auto;
    width: var(--pill-h);
    height: var(--pill-h);
    display: grid;
    place-items: center;
    border-radius: 50%;
    background-color: var(--white-bg);
    box-shadow: 0 4px 12px rgb(0 0 0 / 0.25);
}

/* rotated so the arc starts at 12 o'clock */
.progress-ring__svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    transform: rotate(-90deg);
}

.progress-ring__track,
.progress-ring__value {
    fill: none;
    stroke-width: 4;
}

.progress-ring__track {
    stroke: #e6e6e6;
    transition: opacity 220ms ease;
}

    /* no progress yet: a plain white circle, as in the design */
    .progress-ring[data-progress="0"] .progress-ring__track {
        opacity: 0;
    }

/* The arc length is 2 * pi * 22 = 138.23. The offsets below are written for
   the 3 counted steps of the registration dialog (data-progress-total="3");
   a dialog with another step count needs its own rules. Butt caps, because
   round caps would draw a dot at 0%. The gap is longer than the circle, so
   the next dash can't peek through as a hairline at 0%. */
.progress-ring__value {
    stroke-linecap: butt;
    stroke-dasharray: 138.23 1000;
    stroke-dashoffset: 138.23;
    transition: stroke-dashoffset 820ms cubic-bezier(.16, 1, .3, 1);
}

    .progress-ring[data-progress="1"] .progress-ring__value {
        stroke-dashoffset: 92.15;
    }

    .progress-ring[data-progress="2"] .progress-ring__value {
        stroke-dashoffset: 46.08;
    }

    .progress-ring[data-progress="3"] .progress-ring__value,
    .progress-ring[data-progress="done"] .progress-ring__value {
        stroke-dashoffset: 0;
    }

/* same gradient as the .btn-primary border */
.progress-ring__stop-start {
    stop-color: var(--primary-color-2);
}

.progress-ring__stop-end {
    stop-color: var(--primary-color-3);
}

.progress-ring__label {
    position: relative; /* paints above the absolutely placed svg */
    font-size: 1.4rem;
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

    .progress-ring__label svg {
        display: block;
        width: 2rem;
        height: 2rem;
    }


/* -------- ---------- -------- */
/* -------- Typography -------- */

/* Spacing only: the global h2/h3 carry a large padding for the app pages */
.dialog-body {
    padding: var(--large-gap) var(--medium-gap);
}

    .dialog-body h2 {
        margin: 0 0 var(--medium-gap);
        padding: 0;
        hyphens: auto; /* "Nutzungsbedingungen" is wider than a small phone */
        overflow-wrap: break-word;
    }

    .dialog-body h3 {
        margin: var(--large-gap) 0 var(--small-gap);
        padding: 0;
        hyphens: auto;
        overflow-wrap: break-word;
    }

    /* a section right under the step heading doesn't need the section gap */
    .dialog-body h2 + h3 {
        margin-top: 0;
    }

    .dialog-body p {
        margin: 0;
    }

/* The step headings get focus after every step change: show the ring only
   for keyboard users. */
.step-dialog__heading:focus:not(:focus-visible) {
    outline: none;
}

.step-dialog__heading:focus-visible {
    outline: 2px solid var(--primary-color-2);
    outline-offset: 4px;
    border-radius: 4px;
}


/* -------- ------ -------- */
/* -------- Fields -------- */

.dialog-field {
    margin-top: var(--medium-gap);
}

    .dialog-field > label {
        display: block;
        margin: 0;
    }

    .dialog-field > input:not([type="checkbox"]) {
        margin: var(--small-gap) 0 0;
    }

/* A label that shares its row with something else, e.g. the login dialog's
   "Passwort vergessen?" link. The .dialog-field > label reset above is a
   child selector, so the nested label needs its own. */
.dialog-field > .dialog-field__label-row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--pill-gap);
}

    .dialog-field__label-row > label {
        margin: 0;
    }

.dialog-field--checkbox > input[type="checkbox"] {
    margin: var(--pill-gap) 0 0;
}

/* scoped like `.dialog-body p`, which would reset the margin otherwise */
.dialog-body .dialog-hint {
    margin-top: var(--medium-gap);
}

.dialog-hint ul {
    margin: var(--small-gap) 0 0;
    padding-left: var(--medium-gap);
}

/* scoped like `.dialog-body p`, which would reset the margin otherwise */
.dialog-body .dialog-note {
    margin-top: var(--medium-gap);
    font-weight: 700;
}

/* Errors use the framed .alert box (classes_base.css), like the setup wizard.
   Only Django's list inside it loses the bullets and trailing margin, so the
   box stays evenly padded. */
.dialog-body .alert .errorlist {
    list-style: none;
    margin: 0;
    padding: 0;
}

    .dialog-body .alert .errorlist li + li {
        margin-top: var(--small-gap);
    }


/* -------- ------- -------- */
/* -------- Actions -------- */

.dialog-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--pill-gap);
    margin-top: var(--medium-gap);
}

.dialog-actions--center {
    justify-content: center;
}

/* Zurück left, the primary action right. Hidden buttons drop out through
   Bootstrap's [hidden] { display: none !important }. */
.dialog-actions--split {
    justify-content: space-between;
}

.dialog-actions--end {
    justify-content: flex-end;
}


/* -------- ----- -------- */
/* -------- Steps -------- */

/* Only the current step is in flow and sets the height. The others wait,
   absolutely placed, on the left (before) or right (after) of it, so the
   slide direction follows from the order: forward, the leaving step exits
   to the left and the next one enters from the right; back is mirrored.
   Timing is the setup wizard's (form.css .form-step). */
.step-dialog__steps {
    position: relative;
    overflow-anchor: none; /* don't anchor scrolling on a leaving step */
}

    /* While step_dialog.js animates the height: clip at the animated edge,
       but leave room for focus rings and input shadows. */
    .step-dialog__steps--resizing {
        clip-path: inset(-1.6rem -2.4rem);
    }

.step-dialog__step {
    display: flow-root; /* margins can't collapse differently in and out of flow */
    transition:
        transform 820ms cubic-bezier(.16, 1, .3, 1),
        opacity 220ms ease,
        filter 420ms ease,
        visibility 0s linear 0s;
}

    /* visibility switches after the fade, so the leaving step stays visible
       while it slides out */
    .step-dialog__step:not([data-state="current"]) {
        position: absolute;
        inset: 0 0 auto 0;
        transform: translateX(32px);
        opacity: 0;
        filter: blur(6px);
        visibility: hidden;
        transition-delay: 0s, 0s, 0s, 420ms;
    }

    /* must come after the rule above (same specificity) */
    .step-dialog__step[data-state="before"] {
        transform: translateX(-32px);
    }


/* -------- ------ -------- */
/* -------- Mobile -------- */

@media (max-width: 480px) {
    .dialog-main {
        padding: var(--medium-gap) var(--pill-gap);
    }

    .dialog-frame {
        padding: var(--small-gap);
    }

    .dialog-header,
    .dialog-header__pill {
        gap: var(--pill-gap);
    }

    .dialog-header {
        padding: var(--pill-gap);
    }

    .dialog-header__pill {
        padding: 0 var(--pill-gap);
    }

    /* "Registrierung abschließen" and "Zurück" don't fit next to each other.
       Stacked in DOM order, so the tab order matches what is on screen. */
    .dialog-actions--split {
        flex-direction: column;
        align-items: stretch;
    }
}


/* -------- -------------- -------- */
/* -------- Reduced motion -------- */

/* Keep last: overrides the step and ring motion above. The leaving step
   disappears at once, the entering one fades in briefly. step_dialog.js
   skips the height animation. */
@media (prefers-reduced-motion: reduce) {
    .step-dialog__step,
    .step-dialog__step[data-state] {
        transform: none;
        filter: none;
    }

    .step-dialog__step:not([data-state="current"]) {
        transition: none;
    }

    .step-dialog__step[data-state="current"] {
        transition: opacity 150ms ease;
    }

    .progress-ring__value,
    .progress-ring__track {
        transition: none;
    }
}
