/* ============================================================================
   auth.css — the VarsityBlog authentication design system.
   ============================================================================

   One stylesheet behind every auth surface: login, the two signup steps and the
   Google finish screen. Before this file each of those templates carried its own
   200-line <style> block, which is exactly why they drifted apart.

   Everything is namespaced `af-` (auth form) so it can be dropped into a page
   that already extends base.html without colliding.

   Motion principles used throughout:
     - durations 120-320ms; nothing functional waits on an animation
     - a single decelerating easing curve (--af-ease) so every surface agrees
     - geometry morphs instead of blinking, so the eye can track state
     - every animation is disabled under prefers-reduced-motion
   ========================================================================= */

/* Animating a conic-gradient angle needs a typed custom property. Where
   @property is unsupported the ring renders static — still a gradient border,
   just not a travelling one. */
@property --af-angle {
    syntax: '<angle>';
    initial-value: 0deg;
    inherits: false;
}

:root {
    --af-primary:        #ff4500;
    --af-primary-light:  #ff8a4c;
    --af-primary-dark:   #cc3700;
    --af-navy:           #1a365d;

    --af-ink:            #111827;
    --af-ink-soft:       #4b5563;
    --af-muted:          #6b7280;
    --af-line:           #e5e7eb;
    --af-surface:        #ffffff;
    --af-surface-sunken: #f9fafb;

    --af-danger:         #dc2626;
    --af-danger-soft:    #fef2f2;
    --af-success:        #16a34a;
    --af-warning-bg:     #fffbeb;
    --af-warning-line:   #fde68a;
    --af-warning-ink:    #92400e;

    --af-radius:         12px;
    --af-radius-lg:      20px;

    /* "Ease-out power 4" — starts fast, settles gently. One curve everywhere is
       what makes the whole surface feel like a single piece of hardware. */
    --af-ease:           cubic-bezier(0.22, 1, 0.36, 1);
    --af-fast:           140ms;
    --af-base:           220ms;
    --af-slow:           320ms;
}

*, *::before, *::after { box-sizing: border-box; }

.af-body {
    margin: 0;
    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem 1rem;
    background: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #0f172a 100%);
    background-attachment: fixed;
    font-family: 'Segoe UI', system-ui, -apple-system, 'Helvetica Neue', sans-serif;
    color: var(--af-ink);
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

/* Ambient light. Fixed + pointer-events:none so it never eats a click. */
.af-body::before {
    content: '';
    position: fixed;
    inset: -50%;
    pointer-events: none;
    background:
        radial-gradient(ellipse at 62% 38%, rgba(255, 69, 0, 0.10) 0%, transparent 52%),
        radial-gradient(ellipse at 22% 82%, rgba(26, 54, 93, 0.38) 0%, transparent 55%);
    animation: af-drift 18s ease-in-out infinite alternate;
}

@keyframes af-drift {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to   { transform: translate3d(-2%, 2%, 0) scale(1.06); }
}

/* ── Card ────────────────────────────────────────────────────────────────── */

.af-card {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 460px;
    background: var(--af-surface);
    border-radius: var(--af-radius-lg);
    box-shadow:
        0 32px 80px rgba(0, 0, 0, 0.42),
        0 0 0 1px rgba(255, 255, 255, 0.06);
    overflow: hidden;
    animation: af-card-in var(--af-slow) var(--af-ease) both;
}

@keyframes af-card-in {
    from { opacity: 0; transform: translateY(14px) scale(0.985); }
    to   { opacity: 1; transform: none; }
}

.af-card__header {
    position: relative;
    overflow: hidden;
    padding: 2.1rem 2rem 1.75rem;
    text-align: center;
    background: linear-gradient(135deg, var(--af-navy) 0%, #2d4a7a 100%);
}
.af-card__header::before,
.af-card__header::after {
    content: '';
    position: absolute;
    border-radius: 50%;
    pointer-events: none;
}
.af-card__header::before {
    top: -42px; right: -42px;
    width: 132px; height: 132px;
    background: rgba(255, 255, 255, 0.05);
}
.af-card__header::after {
    bottom: -32px; left: -32px;
    width: 104px; height: 104px;
    background: rgba(255, 69, 0, 0.10);
}

.af-brand {
    position: relative;
    font-size: 1.6rem;
    font-weight: 800;
    letter-spacing: -0.5px;
    margin: 0 0 0.35rem;
}
.af-brand__mark { color: var(--af-primary); }
.af-brand__word { color: #fff; }

.af-card__header h2 {
    position: relative;
    margin: 0 0 0.2rem;
    font-size: 1.1rem;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.92);
}
.af-card__header p {
    position: relative;
    margin: 0;
    font-size: 0.85rem;
    color: rgba(255, 255, 255, 0.58);
}

.af-card__body { padding: 1.9rem 2rem 2rem; }

.af-title {
    margin: 0 0 0.3rem;
    text-align: center;
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--af-navy);
}
.af-sub {
    margin: 0 0 1.4rem;
    text-align: center;
    font-size: 0.875rem;
    color: var(--af-muted);
}

/* ── Progress ────────────────────────────────────────────────────────────── */

.af-progress {
    height: 5px;
    background: #eef0f3;
    overflow: hidden;
}
.af-progress__fill {
    height: 100%;
    background: linear-gradient(90deg, var(--af-primary) 0%, var(--af-primary-light) 100%);
    border-radius: 0 3px 3px 0;
    transform-origin: left center;
    transition: width var(--af-slow) var(--af-ease);
    animation: af-progress-in 520ms var(--af-ease) both;
}
@keyframes af-progress-in {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
}
/* Inside the card body the step counter sits above the title, not under the
   progress bar, so it needs its own rhythm. */
.af-card__body > .af-step { margin: -0.35rem 0 1.15rem; }

.af-step {
    margin: 0.7rem 0 0;
    text-align: center;
    font-size: 0.78rem;
    letter-spacing: 0.04em;
    color: var(--af-muted);
}

/* ── Fields: the floating label + kinetic border ─────────────────────────── */

.af-group { margin-bottom: 1.15rem; }

.af-row { display: flex; gap: 0.75rem; }
.af-row > * { flex: 1; min-width: 0; }

/* The input's own label is the floating one; `.af-legend` labels groups
   (radios, panels) that have nothing to float. */
.af-legend {
    display: block;
    margin-bottom: 0.5rem;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--af-ink-soft);
}
.af-optional {
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    color: var(--af-muted);
}

.af-field {
    position: relative;
    border-radius: var(--af-radius);
    isolation: isolate;
}

/* The travelling light. Sits a hair outside the input and is covered by the
   input's own opaque background, so only the rim shows. */
.af-field::before {
    content: '';
    position: absolute;
    inset: -1.5px;
    z-index: 0;
    border-radius: inherit;
    opacity: 0;
    transition: opacity var(--af-base) var(--af-ease);
    background: conic-gradient(
        from var(--af-angle),
        transparent 0deg 232deg,
        rgba(255, 138, 76, 0.55) 288deg,
        var(--af-primary) 334deg,
        rgba(255, 69, 0, 0.35) 352deg,
        transparent 360deg
    );
    animation: af-orbit 2.6s linear infinite;
    animation-play-state: paused;
}
.af-field:focus-within::before {
    opacity: 1;
    animation-play-state: running;
}
@keyframes af-orbit {
    to { --af-angle: 360deg; }
}

.af-input,
.af-select {
    position: relative;
    z-index: 1;
    width: 100%;
    padding: 1.15rem 1rem 0.75rem;
    border: 1.5px solid var(--af-line);
    border-radius: var(--af-radius);
    background: var(--af-surface-sunken);
    font: inherit;
    font-size: 0.9375rem;
    color: var(--af-ink);
    outline: none;
    transition:
        border-color var(--af-fast) var(--af-ease),
        background var(--af-fast) var(--af-ease),
        box-shadow var(--af-base) var(--af-ease);
}
.af-input:hover:not(:focus),
.af-select:hover:not(:focus) { border-color: #d3d8df; }

.af-input:focus,
.af-select:focus {
    border-color: transparent;
    background: var(--af-surface);
    /* padding-box clipping lets the transparent border reveal the ring behind
       it, so the rim reads as ~3px of light instead of a 1.5px hairline. */
    background-clip: padding-box;
    box-shadow: 0 0 0 4px rgba(255, 69, 0, 0.10);
}

/* Room for the eye / status icon. */
.af-field--icon .af-input { padding-right: 3rem; }

.af-select {
    appearance: none;
    -webkit-appearance: none;
    padding-right: 2.5rem;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 1rem center;
}

.af-label {
    position: absolute;
    z-index: 2;
    left: 1rem;
    top: calc(50% + 0.2rem);
    transform: translateY(-50%);
    transform-origin: left center;
    font-size: 0.9375rem;
    line-height: 1;
    font-weight: 500;
    color: var(--af-muted);
    pointer-events: none;
    white-space: nowrap;
    max-width: calc(100% - 2.5rem);
    overflow: hidden;
    text-overflow: ellipsis;
    transition:
        transform var(--af-base) var(--af-ease),
        color var(--af-fast) var(--af-ease);
}

/* The float. Inputs carry placeholder=" " so :placeholder-shown is the
   "is it empty?" signal — the core behaviour needs no JS at all. */
.af-input:focus + .af-label,
.af-input:not(:placeholder-shown) + .af-label,
.af-select + .af-label,
.af-field.is-filled .af-label {
    transform: translateY(calc(-50% - 1.34rem)) scale(0.78);
}
.af-input:focus + .af-label,
.af-select:focus + .af-label {
    color: var(--af-primary);
}

/* Chrome paints autofilled inputs before our JS runs; force the label up. */
.af-input:-webkit-autofill + .af-label {
    transform: translateY(calc(-50% - 1.34rem)) scale(0.78);
}
.af-input:-webkit-autofill {
    -webkit-text-fill-color: var(--af-ink);
    -webkit-box-shadow: 0 0 0 40px var(--af-surface) inset;
}

/* Real placeholders (the example under a floated label) fade in on focus only,
   so the label and the hint never fight for the same pixels. */
.af-input::placeholder { color: transparent; transition: color var(--af-fast) var(--af-ease); }
.af-input:focus::placeholder { color: #b6bcc6; }

/* ── Invalid state ───────────────────────────────────────────────────────── */

.af-field.is-invalid .af-input,
.af-field.is-invalid .af-select { border-color: var(--af-danger); background: var(--af-danger-soft); }
.af-field.is-invalid .af-label  { color: var(--af-danger); }
.af-field.is-invalid::before    { opacity: 0 !important; }

.af-error {
    display: block;
    margin: 0.4rem 0 0;
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--af-danger);
    animation: af-fade-up var(--af-fast) var(--af-ease) both;
}
.af-error:empty { display: none; }

.af-hint {
    margin: 0.45rem 0 0;
    font-size: 0.79rem;
    line-height: 1.5;
    color: var(--af-muted);
}
.af-hint--ok  { color: var(--af-success); font-weight: 600; }
.af-hint--bad { color: var(--af-danger); font-weight: 600; }

@keyframes af-fade-up {
    from { opacity: 0; transform: translateY(-3px); }
    to   { opacity: 1; transform: none; }
}

/* The head-shake. Sharp, 380ms, decaying amplitude — a "no", not a wobble. */
@keyframes af-shake {
    0%, 100% { transform: translateX(0); }
    15%      { transform: translateX(-9px); }
    30%      { transform: translateX(8px); }
    45%      { transform: translateX(-6px); }
    60%      { transform: translateX(4px); }
    80%      { transform: translateX(-2px); }
}
.af-shake { animation: af-shake 380ms cubic-bezier(0.36, 0.07, 0.19, 0.97) both; }

/* A red pulse behind the card so the shake still reads in peripheral vision. */
@keyframes af-flash {
    0%   { box-shadow: 0 32px 80px rgba(0,0,0,.42), 0 0 0 1px rgba(255,255,255,.06), 0 0 0 0 rgba(220,38,38,.55); }
    100% { box-shadow: 0 32px 80px rgba(0,0,0,.42), 0 0 0 1px rgba(255,255,255,.06), 0 0 0 16px rgba(220,38,38,0); }
}
.af-shake.af-card {
    animation:
        af-shake 380ms cubic-bezier(0.36, 0.07, 0.19, 0.97) both,
        af-flash 620ms var(--af-ease) both;
}

/* ── Banners ─────────────────────────────────────────────────────────────── */

.af-banner {
    border-radius: var(--af-radius);
    padding: 0.85rem 1rem;
    margin-bottom: 1.15rem;
    font-size: 0.86rem;
    line-height: 1.55;
    animation: af-fade-up var(--af-base) var(--af-ease) both;
}
.af-banner--error {
    background: var(--af-danger-soft);
    border: 1.5px solid #fecaca;
    color: #b91c1c;
}
.af-banner--error ul { margin: 0; padding-left: 1.1rem; }
.af-banner--warn {
    background: var(--af-warning-bg);
    border: 1.5px solid var(--af-warning-line);
    color: var(--af-warning-ink);
}
.af-banner--warn strong { display: block; margin-bottom: 0.15rem; }
.af-banner[hidden] { display: none; }

.af-banner__btn {
    margin-top: 0.6rem;
    background: transparent;
    border: 1.5px solid #f97316;
    color: #f97316;
    padding: 0.4rem 1rem;
    border-radius: 8px;
    font: inherit;
    font-size: 0.8125rem;
    font-weight: 600;
    cursor: pointer;
    transition: background var(--af-fast) var(--af-ease), color var(--af-fast) var(--af-ease);
}
.af-banner__btn:hover { background: #f97316; color: #fff; }

/* ── Icon button (password eye) + caps-lock notice ───────────────────────── */

.af-icon-btn {
    position: absolute;
    z-index: 3;
    right: 0.75rem;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: none;
    border-radius: 8px;
    background: none;
    color: #9ca3af;
    cursor: pointer;
    transition: color var(--af-fast) var(--af-ease), background var(--af-fast) var(--af-ease);
}
.af-icon-btn:hover { color: var(--af-primary); background: rgba(255, 69, 0, 0.08); }
.af-icon-btn:focus-visible { outline: 2px solid var(--af-primary); outline-offset: 2px; }
.af-icon-btn svg { width: 19px; height: 19px; }

.af-caps {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    margin: 0.4rem 0 0;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--af-warning-ink);
    animation: af-fade-up var(--af-fast) var(--af-ease) both;
}
.af-caps[hidden] { display: none; }

/* ── Password strength ───────────────────────────────────────────────────── */

.af-strength { margin-top: 0.55rem; }
.af-strength[hidden] { display: none; }
.af-strength__track { display: flex; gap: 4px; }
.af-strength__seg {
    flex: 1;
    height: 4px;
    border-radius: 99px;
    background: var(--af-line);
    transform-origin: center;
    transition: background var(--af-base) var(--af-ease), transform var(--af-base) var(--af-ease);
}
.af-strength__seg.is-on { transform: scaleY(1.5); }
.af-strength[data-score="1"] .af-strength__seg.is-on { background: #ef4444; }
.af-strength[data-score="2"] .af-strength__seg.is-on { background: #f59e0b; }
.af-strength[data-score="3"] .af-strength__seg.is-on { background: #3b82f6; }
.af-strength[data-score="4"] .af-strength__seg.is-on { background: var(--af-success); }
.af-strength__label {
    margin: 0.35rem 0 0;
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--af-muted);
}

/* ── Choice cards (student / professional) ───────────────────────────────── */

.af-choices { display: flex; gap: 0.65rem; }
.af-choice {
    position: relative;
    flex: 1;
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.85rem 0.9rem;
    border: 2px solid var(--af-line);
    border-radius: var(--af-radius);
    background: var(--af-surface);
    cursor: pointer;
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--af-ink-soft);
    transition:
        border-color var(--af-fast) var(--af-ease),
        background var(--af-fast) var(--af-ease),
        transform var(--af-fast) var(--af-ease),
        box-shadow var(--af-fast) var(--af-ease);
}
.af-choice:hover { border-color: var(--af-primary-light); transform: translateY(-1px); }
.af-choice:active { transform: translateY(0) scale(0.99); }
.af-choice.is-selected {
    border-color: var(--af-primary);
    background: rgba(255, 69, 0, 0.05);
    color: var(--af-ink);
    box-shadow: 0 4px 14px rgba(255, 69, 0, 0.14);
}
.af-choice:focus-within { outline: 2px solid rgba(255, 69, 0, 0.45); outline-offset: 2px; }
.af-choice input { accent-color: var(--af-primary); margin: 0; }

/* Radios have no field wrapper of their own, so the row carries the error. */
.af-choices.is-invalid .af-choice { border-color: var(--af-danger); }
.af-choices.is-invalid + .af-error { display: block; }

/* ── Buttons ─────────────────────────────────────────────────────────────── */

.af-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    margin-top: 1.5rem;
}
.af-actions--single { justify-content: center; }

.af-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 50px;
    padding: 0 1.5rem;
    border: none;
    border-radius: var(--af-radius);
    font: inherit;
    font-size: 0.975rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    cursor: pointer;
    overflow: hidden;
    /* width + border-radius are what make the morph read as one object changing
       shape rather than two elements swapping places. */
    transition:
        width var(--af-slow) var(--af-ease),
        transform var(--af-fast) var(--af-ease),
        box-shadow var(--af-base) var(--af-ease),
        background var(--af-base) var(--af-ease),
        border-radius var(--af-slow) var(--af-ease);
}
.af-btn--primary {
    background: linear-gradient(135deg, var(--af-primary) 0%, #e03d00 100%);
    color: #fff;
    box-shadow: 0 6px 20px rgba(255, 69, 0, 0.30);
}
.af-btn--primary:hover { transform: translateY(-1px); box-shadow: 0 10px 28px rgba(255, 69, 0, 0.40); }
.af-btn--primary:active { transform: translateY(0); box-shadow: 0 3px 10px rgba(255, 69, 0, 0.30); }
.af-btn--ghost {
    background: transparent;
    border: 1.5px solid var(--af-line);
    color: var(--af-muted);
    font-weight: 600;
}
.af-btn--ghost:hover { background: #f3f4f6; color: var(--af-ink-soft); }
.af-btn--link {
    background: none;
    border: none;
    color: var(--af-muted);
    font-weight: 600;
    font-size: 0.875rem;
    text-decoration: underline;
    text-underline-offset: 3px;
    min-height: 44px;
    padding: 0 0.35rem;
}
.af-btn--link:hover { color: var(--af-navy); }
.af-btn--full { display: flex; width: 100%; }
.af-btn:focus-visible { outline: 2px solid var(--af-navy); outline-offset: 3px; }

/* A single light sweep across the CTA on hover. No loop — loops feel cheap. */
.af-btn--primary::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(105deg, transparent 38%, rgba(255, 255, 255, 0.28) 50%, transparent 62%);
    transform: translateX(-120%);
    transition: transform 620ms var(--af-ease);
    pointer-events: none;
}
.af-btn--primary:hover::after { transform: translateX(120%); }
.af-btn.is-busy::after, .af-btn.is-done::after { display: none; }

/* Morph: full-width pill -> circle -> spinner -> check. */
.af-btn__label,
.af-btn__spinner,
.af-btn__check {
    display: inline-flex;
    align-items: center;
    transition: opacity var(--af-fast) var(--af-ease), transform var(--af-base) var(--af-ease);
}
.af-btn__spinner,
.af-btn__check {
    position: absolute;
    opacity: 0;
    transform: scale(0.6);
}
.af-btn__spinner svg { width: 22px; height: 22px; animation: af-spin 720ms linear infinite; }
.af-btn__check svg { width: 24px; height: 24px; }
@keyframes af-spin { to { transform: rotate(360deg); } }

.af-btn.is-busy {
    display: flex;
    width: 50px;
    min-width: 50px;
    max-width: 50px;
    padding: 0;
    border-radius: 50%;
    margin-inline: auto;
    pointer-events: none;
    transform: none;
    box-shadow: 0 6px 20px rgba(255, 69, 0, 0.30);
}
.af-btn.is-busy .af-btn__label   { opacity: 0; transform: scale(0.75); }
.af-btn.is-busy .af-btn__spinner { opacity: 1; transform: scale(1); }
.af-btn.is-done {
    background: linear-gradient(135deg, #16a34a 0%, #15803d 100%);
    box-shadow: 0 6px 20px rgba(22, 163, 74, 0.35);
}
.af-btn.is-done .af-btn__spinner { opacity: 0; transform: scale(0.6); }
.af-btn.is-done .af-btn__check   { opacity: 1; transform: scale(1); animation: af-pop var(--af-slow) var(--af-ease); }
@keyframes af-pop {
    0%   { transform: scale(0.4); }
    60%  { transform: scale(1.18); }
    100% { transform: scale(1); }
}

/* While the CTA is a circle, its siblings step back instead of jumping.
   `:has()` is progressive — without it the row simply stays put. */
.af-actions:has(.af-btn.is-busy) { justify-content: center; }
.af-actions:has(.af-btn.is-busy) .af-btn--link,
.af-actions:has(.af-btn.is-busy) .af-btn--ghost {
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--af-fast) var(--af-ease);
}

/* ── Social + dividers ───────────────────────────────────────────────────── */

.af-social { margin-bottom: 1.35rem; }
.af-google {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.625rem;
    min-height: 50px;
    padding: 0 1rem;
    background: #fff;
    border: 1.5px solid #dadce0;
    border-radius: var(--af-radius);
    font: inherit;
    font-size: 0.9375rem;
    font-weight: 600;
    color: #3c4043;
    cursor: pointer;
    transition:
        background var(--af-fast) var(--af-ease),
        box-shadow var(--af-base) var(--af-ease),
        transform var(--af-fast) var(--af-ease),
        border-color var(--af-fast) var(--af-ease);
}
.af-google:hover {
    background: #fafafa;
    border-color: #c6cbd1;
    transform: translateY(-1px);
    box-shadow: 0 6px 18px rgba(60, 64, 67, 0.16);
}
.af-google:active { transform: translateY(0); }
.af-google:focus-visible { outline: 2px solid #4285F4; outline-offset: 2px; }
.af-google svg { flex-shrink: 0; }
.af-google.is-busy { pointer-events: none; color: var(--af-muted); }
.af-google.is-busy svg { animation: af-pulse 900ms ease-in-out infinite; }
@keyframes af-pulse { 50% { opacity: 0.35; } }

.af-google-hint {
    margin: 0.5rem 0.15rem 0;
    font-size: 0.78rem;
    line-height: 1.45;
    color: var(--af-muted);
    text-align: center;
}

.af-divider {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 1.35rem 0 0;
}
.af-divider::before,
.af-divider::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--af-line);
}
.af-divider span {
    font-size: 0.78rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #9ca3af;
    white-space: nowrap;
}

/* ── Links / footers ─────────────────────────────────────────────────────── */

.af-meta {
    margin: 1.35rem 0 0;
    text-align: center;
    font-size: 0.875rem;
    color: var(--af-muted);
}
.af-meta a,
.af-link {
    color: var(--af-primary);
    font-weight: 600;
    text-decoration: none;
    transition: color var(--af-fast) var(--af-ease);
}
.af-meta a:hover,
.af-link:hover { color: var(--af-primary-dark); text-decoration: underline; }

.af-forgot {
    display: flex;
    justify-content: flex-end;
    margin: -0.35rem 0 1.25rem;
}
.af-forgot a { font-size: 0.8125rem; }

/* Toasts live in toasts.css — they are a site-wide component now, not an
   auth-only one. Auth pages load both stylesheets. */

/* ── Reveal panel (suggest-a-university) ─────────────────────────────────── */

.af-reveal {
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    margin-top: 0;
    transition:
        grid-template-rows var(--af-slow) var(--af-ease),
        opacity var(--af-base) var(--af-ease),
        margin-top var(--af-slow) var(--af-ease);
}
/* visibility (not just clipping) so a collapsed panel is out of the tab order;
   delayed on close so it disappears only after the collapse finishes. */
.af-reveal > * {
    overflow: hidden;
    min-height: 0;
    visibility: hidden;
    transition: visibility 0s linear var(--af-slow);
}
.af-reveal.is-open { grid-template-rows: 1fr; opacity: 1; margin-top: 0.75rem; }
.af-reveal.is-open > * { visibility: visible; transition-delay: 0s; }

/* ── Motion & contrast preferences ───────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
    /* Motion is the whole point of the orbiting rim, so swap it for a plain
       high-contrast focus border rather than leaving a static smear. */
    .af-field:focus-within::before { opacity: 0 !important; }
    .af-input:focus,
    .af-select:focus { border-color: var(--af-primary); }
}

@media (prefers-contrast: more) {
    .af-input, .af-select { border-color: #6b7280; }
    .af-label { color: #374151; }
}

/* ── Small screens ───────────────────────────────────────────────────────── */

@media (max-width: 520px) {
    .af-body { padding: 0; align-items: flex-start; }
    .af-card {
        max-width: none;
        min-height: 100dvh;
        border-radius: 0;
        box-shadow: none;
    }
    .af-card__header { padding: 1.75rem 1.35rem 1.5rem; }
    .af-card__body { padding: 1.5rem 1.35rem 2.25rem; }
    .af-row { flex-direction: column; gap: 0; }
    .af-actions { flex-direction: column-reverse; align-items: stretch; }
    .af-actions .af-btn { width: 100%; }
    .af-actions:has(.af-btn.is-busy) .af-btn.is-busy { width: 50px; align-self: center; }
    .af-toasts { top: 0.75rem; right: 0.75rem; left: 0.75rem; max-width: none; }
}
