/* ============================================================
   KOSIS — assets/css/kosis-public.css  ·  v2.1 (hardened)

   Changes from v2.0:
    · !important on button colors so the cascade can't beat them
    · Mobile breakpoint lowered 880px → 720px + !important
      on flex-direction so iPhone Pro Max (430px) stacks
    · Preview avatar SVG forced to 32px regardless of inline
      attribute or browser default
    · Scripture footer + tertiary text use brand tokens with
      no opacity so they read against navy
    · Preview card vertically centers in the shell on desktop
    · Modal backdrop uses solid dark color (Chromium quirk
      with backdrop-filter behind cached cards)
   ============================================================ */


/* ─── 1 · RESET ───────────────────────────────────────────── */
*,
*::before,
*::after {
    box-sizing: border-box;
}


/* ─── 2 · LEGACY VARIABLES → BRAND TOKENS ─────────────────── */
:root {
    --pub-bg:           var(--ks-navy);
    --pub-card:         var(--ks-cream);
    --pub-accent:       var(--ks-sage);
    --pub-accent-hover: #3d5e4d;
    --pub-text:         var(--ks-navy);
    --pub-muted:        var(--ks-slate);
    --pub-border:       var(--ks-border);
    --pub-input-bg:     #ffffff;
    --pub-radius:       6px;
    --pub-shadow:       0 12px 32px rgba(0, 0, 0, 0.32);
}


/* ─── 3 · BODY (navy background, decorative rings) ─────────── */
html, body {
    min-height: 100vh;
    background: var(--ks-navy);
    overflow-x: hidden;
    max-width: 100vw;
}

body.kosis-auth,
body.kosis-public {
    font-family: var(--ks-font-sans);
    color: var(--ks-navy);
    min-height: 100vh;
    width: 100%;
    max-width: 100vw;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: var(--ks-space-xl) var(--ks-space-md);
    position: relative;
    overflow-x: hidden;
}

body.kosis-auth::before,
body.kosis-public::before,
body.kosis-auth::after,
body.kosis-public::after {
    display: none; /* Old static rings retired — replaced by .ks-auth-bg orbs below */
}


/* ─── 3.5 · ANIMATED BACKGROUND ORBS (Stripe-inspired, brand palette) ──
   Four blurred orbs in gold/sage/parchment slowly drift behind the
   auth cards, giving the navy backdrop the atmospheric depth Stripe's
   login has — but in Kosis's reverent brand voice.

   Insert <div class="ks-auth-bg"><span></span><span></span>
   <span></span><span></span></div> as the first child of <body> in
   each auth page (index.php, login.php, register.php).             */

.ks-auth-bg {
    position: fixed;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    z-index: 0;
}

.ks-auth-bg span {
    position: absolute;
    display: block;
    border-radius: 50%;
    filter: blur(90px);
    will-change: transform;
}

/* Orb 1 — large gold, top-right */
.ks-auth-bg span:nth-child(1) {
    background: var(--ks-gold);
    width: 540px; height: 540px;
    top: -120px; right: -120px;
    opacity: 0.42;
    animation: ks-orb-1 22s ease-in-out infinite;
}

/* Orb 2 — large sage, bottom-left */
.ks-auth-bg span:nth-child(2) {
    background: var(--ks-sage);
    width: 480px; height: 480px;
    bottom: -140px; left: -100px;
    opacity: 0.5;
    animation: ks-orb-2 28s ease-in-out infinite;
}

/* Orb 3 — mid gold, drifts through center-right */
.ks-auth-bg span:nth-child(3) {
    background: var(--ks-gold);
    width: 380px; height: 380px;
    top: 55%; left: 60%;
    opacity: 0.28;
    animation: ks-orb-3 26s ease-in-out infinite;
}

/* Orb 4 — small parchment, drifts upper-left */
.ks-auth-bg span:nth-child(4) {
    background: var(--ks-parchment);
    width: 320px; height: 320px;
    top: 25%; left: 18%;
    opacity: 0.18;
    animation: ks-orb-4 32s ease-in-out infinite;
}

@keyframes ks-orb-1 {
    0%, 100% { transform: translate(0, 0) scale(1); }
    50%      { transform: translate(-70px, 90px) scale(1.15); }
}
@keyframes ks-orb-2 {
    0%, 100% { transform: translate(0, 0) scale(1); }
    50%      { transform: translate(90px, -70px) scale(1.1); }
}
@keyframes ks-orb-3 {
    0%, 100% { transform: translate(0, 0) scale(1); }
    50%      { transform: translate(-90px, -110px) scale(0.9); }
}
@keyframes ks-orb-4 {
    0%, 100% { transform: translate(0, 0) scale(1); }
    50%      { transform: translate(110px, 80px) scale(1.25); }
}

/* Respect users who prefer reduced motion (accessibility) */
@media (prefers-reduced-motion: reduce) {
    .ks-auth-bg span {
        animation: none !important;
    }
}

/* Make sure auth content sits ABOVE the orb layer */
.ks-auth-shell,
.ks-auth-footer {
    position: relative;
    z-index: 1;
}


/* ─── 4 · TWO-COLUMN LAYOUT ────────────────────────────────── */
.ks-auth-shell {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;          /* center preview vertically with card */
    gap: var(--ks-space-xl);
    width: 100%;
    max-width: 1000px;
}

/* Mobile/tablet: stack at 1100px — covers all phones AND tablets in portrait
   (iPad Mini 768, iPad Air 820, iPad Pro 11" 834, iPad Pro 12.9" 1024).
   Side-by-side only kicks in at true desktop widths (1101px+).             */
@media (max-width: 1100px) {
    .ks-auth-shell {
        flex-direction: column !important;
        align-items: stretch !important;
        max-width: 460px !important;
        gap: var(--ks-space-md) !important;
    }
}


/* ─── 5 · CREAM CARD ───────────────────────────────────────── */
.ks-auth-card,
.card,
.join-card,
.invite-card,
.password-card {
    flex: 1 1 460px;
    max-width: 480px;
    background: var(--ks-cream);
    border: 0.5px solid var(--ks-border);
    border-radius: 14px;
    padding: 40px 36px;
    box-shadow: var(--pub-shadow);
}

@media (max-width: 1100px) {
    .ks-auth-card,
    .card,
    .join-card,
    .invite-card,
    .password-card {
        flex: 1 1 auto !important;
        max-width: 100% !important;
        width: 100% !important;
        padding: 32px 24px !important;
    }
}


/* ─── 6 · CARD HEADER ──────────────────────────────────────── */
.ks-auth-header {
    text-align: center;
    margin-bottom: var(--ks-space-lg);
}
.ks-auth-header__mark,
.ks-auth-card img.ks-auth-header__mark,
.card img.ks-auth-header__mark {
    width: 220px !important;
    height: 220px !important;
    min-width: 220px !important;
    min-height: 220px !important;
    max-width: 220px !important;
    max-height: 220px !important;
    margin: 0 auto var(--ks-space-md) !important;
    display: block !important;
    flex-shrink: 0;
    object-fit: contain;
}
.ks-auth-header__wordmark {
    font-family: var(--ks-font-serif);
    font-size: 26px;
    font-weight: 500;
    letter-spacing: 4px;
    color: var(--ks-navy);
    text-transform: uppercase;
    line-height: 1;
    margin: 0 0 6px 0;
}
.ks-auth-header__tagline {
    display: block;
    font-family: var(--ks-font-serif);
    font-size: 10px;
    font-weight: 400;
    letter-spacing: 3px;
    color: var(--ks-gold);
    text-transform: uppercase;
    margin: 0 0 var(--ks-space-md) 0;
}
.ks-auth-header__rule {
    width: 60px;
    height: 1.5px;
    background: var(--ks-gold);
    margin: 0 auto var(--ks-space-md);
    border: none;
}
.ks-auth-header__title {
    font-family: var(--ks-font-serif);
    font-size: 22px;
    font-weight: 500;
    color: var(--ks-navy);
    margin: 0;
}

.card h1,
.join-card h1,
.invite-card h1,
.password-card h1 {
    font-family: var(--ks-font-serif);
    font-size: 22px;
    font-weight: 500;
    color: var(--ks-navy);
    margin: 0 0 var(--ks-space-md);
    line-height: 1.25;
    text-align: center;
}

.card p,
.join-card p,
.invite-card p {
    color: var(--ks-slate);
    line-height: 1.55;
    margin: 0 0 var(--ks-space-md);
    font-size: 13px;
}


/* ─── 7 · FORM CONTROLS ────────────────────────────────────── */
.form-group,
.ks-auth-field {
    margin-bottom: var(--ks-space-md);
}

label {
    display: block;
    font-family: var(--ks-font-sans);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--ks-slate);
    margin-bottom: 6px;
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="tel"],
input[type="date"],
select,
textarea {
    width: 100%;
    padding: 11px 14px;
    border: 1px solid var(--ks-border);
    border-radius: var(--ks-radius-input);
    background: #ffffff;
    font-family: var(--ks-font-sans);
    font-size: 13px;
    color: var(--ks-navy);
    outline: none;
    transition: border-color 0.15s, box-shadow 0.15s;
}

input::placeholder,
textarea::placeholder {
    color: #a5b0bc;
}

input:focus,
select:focus,
textarea:focus {
    border-color: var(--ks-sage) !important;
    box-shadow: 0 0 0 3px rgba(74, 111, 92, 0.15) !important;
}


/* ─── 8 · MONOSPACE INVITATION CODE ────────────────────────── */
.ks-input--mono {
    font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace !important;
    font-size: 15px !important;
    letter-spacing: 2px !important;
    text-align: center;
}
.ks-input-wrap { position: relative; }
.ks-input-wrap__counter {
    position: absolute;
    right: 14px; top: 50%;
    transform: translateY(-50%);
    font-family: 'SF Mono', Monaco, monospace;
    font-size: 11px;
    color: var(--ks-slate);
    pointer-events: none;
}


/* ─── 9 · PASSWORD WRAP ────────────────────────────────────── */
.password-wrap { position: relative; }
.password-wrap input { padding-right: 4.5rem; }
.toggle {
    position: absolute;
    right: 8px; top: 50%;
    transform: translateY(-50%);
    border: 1px solid var(--ks-border);
    background: var(--ks-cream);
    color: var(--ks-slate);
    border-radius: 4px;
    padding: 6px 10px;
    cursor: pointer;
    font-size: 10px;
    font-family: var(--ks-font-sans);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.toggle:hover {
    background: var(--ks-parchment);
    color: var(--ks-navy);
}

.forgot {
    text-align: right;
    margin-top: 6px;
    font-size: 11px;
}
.forgot a {
    color: var(--ks-sage) !important;
    text-decoration: none;
    font-weight: 500;
}
.forgot a:hover { text-decoration: underline; }


/* ─── 10 · BUTTONS — !important to defeat any cached rules ──── */
.btn,
button[type="submit"],
.primary-btn,
.ks-auth-btn,
.btn-submit {
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    width: 100%;
    min-height: 44px;
    padding: 12px 20px;
    background: var(--ks-sage) !important;
    border: 1px solid var(--ks-sage) !important;
    border-radius: var(--ks-radius-input) !important;
    color: var(--ks-cream) !important;
    font-family: var(--ks-font-sans);
    font-size: 13px;
    font-weight: 500;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
    margin-top: var(--ks-space-md);
}

.btn:hover,
button[type="submit"]:hover,
.primary-btn:hover,
.ks-auth-btn:hover,
.btn-submit:hover {
    background: #3d5e4d !important;
    border-color: #3d5e4d !important;
    color: var(--ks-cream) !important;
    text-decoration: none;
}

/* Outlined / secondary variants */
.btn.btn--outlined,
.btn--outlined,
.btn-secondary,
.ks-auth-btn--outlined {
    background: transparent !important;
    border: 1px solid var(--ks-navy) !important;
    color: var(--ks-navy) !important;
}
.btn.btn--outlined:hover,
.btn--outlined:hover,
.btn-secondary:hover,
.ks-auth-btn--outlined:hover {
    background: var(--ks-navy) !important;
    color: var(--ks-cream) !important;
}

/* Gold "Go to dashboard" button used on create-choir success state */
.btn-go {
    background: var(--ks-gold) !important;
    border: 1px solid var(--ks-gold) !important;
    color: var(--ks-navy) !important;
}
.btn-go:hover {
    background: #c19a45 !important;
    border-color: #c19a45 !important;
    color: var(--ks-navy) !important;
}


/* ─── 11 · TERTIARY TEXT LINKS ─────────────────────────────── */
.ks-auth-tertiary {
    text-align: center;
    margin-top: var(--ks-space-md);
    font-size: 12px;
    line-height: 1.7;
    padding-top: var(--ks-space-md);
    border-top: 0.5px solid var(--ks-border);
}
.ks-auth-tertiary a {
    display: inline-block;
    color: var(--ks-sage) !important;
    text-decoration: none;
    font-weight: 500;
    padding: 4px 0;
}
.ks-auth-tertiary a:hover {
    text-decoration: underline;
    color: #3d5e4d !important;
}
.ks-auth-tertiary--stacked a {
    display: block;
}

/* Session 73: invitation-only "contact the administrator" line. Quiet
   secondary text under the tertiary links; the email stays a sage inline link
   (it overrides the tertiary block's inline-block/padding so it sits inside
   the sentence rather than on its own line). */
.ks-auth-contact {
    margin: 8px 0 0;
    color: var(--ks-slate);
    font-size: 11.5px;
    line-height: 1.6;
}
.ks-auth-tertiary .ks-auth-contact a {
    display: inline;
    padding: 0;
    font-weight: 500;
    color: var(--ks-sage) !important;
}
.ks-auth-tertiary .ks-auth-contact a:hover {
    text-decoration: underline;
    color: #3d5e4d !important;
}


/* ─── 12 · INLINE ITALIC NOTE ──────────────────────────────── */
.ks-auth-note {
    text-align: center;
    font-family: var(--ks-font-serif);
    font-style: italic;
    font-size: 11px;
    color: var(--ks-slate);
    line-height: 1.55;
    margin: var(--ks-space-md) 0 0;
}


/* ─── 13 · PREVIEW CARD ────────────────────────────────────── */
.ks-auth-preview {
    flex: 0 0 240px;
    background: var(--ks-navy-lift);
    border-radius: 14px;
    padding: 36px 28px;
    text-align: center;
    color: var(--ks-cream);
}

/* Avatar — FORCED size: inline attrs in HTML + CSS !important here.
   This is the SVG-blowup fix. */
.ks-auth-preview__avatar {
    width: 64px !important;
    height: 64px !important;
    max-width: 64px;
    max-height: 64px;
    border-radius: 50%;
    background: rgba(212, 169, 85, 0.18);
    border: 0.5px solid rgba(212, 169, 85, 0.3);
    margin: 0 auto var(--ks-space-md);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    flex-shrink: 0;
}
.ks-auth-preview__avatar svg {
    width: 32px !important;
    height: 32px !important;
    max-width: 32px;
    max-height: 32px;
    color: var(--ks-gold);
    stroke: var(--ks-gold);
    fill: none;
    flex-shrink: 0;
}

.ks-auth-preview__title {
    font-family: var(--ks-font-serif);
    font-size: 18px;
    font-weight: 500;
    letter-spacing: 2px;
    color: var(--ks-cream);
    text-transform: uppercase;
    margin: 0 0 6px 0;
}
.ks-auth-preview__rule {
    width: 36px;
    height: 1.5px;
    background: var(--ks-gold);
    margin: 0 auto var(--ks-space-md);
    border: none;
}
.ks-auth-preview__body {
    font-size: 11px;
    line-height: 1.6;
    color: rgba(253, 250, 241, 0.85);
    margin: 0 0 var(--ks-space-md);
}
.ks-auth-preview__angels {
    display: block;
    width: 36px;
    height: 18px;
    margin: 0 auto var(--ks-space-sm);
    background-image: url('/kosis/assets/brand/kosis-sidebar.svg');
    background-size: 36px 36px;
    background-position: center top;
    background-repeat: no-repeat;
}
.ks-auth-preview__ref {
    font-family: var(--ks-font-serif);
    font-size: 9px;
    letter-spacing: 2px;
    color: var(--ks-gold);
    text-transform: uppercase;
    margin: 0;
}

@media (max-width: 1100px) {
    .ks-auth-preview {
        flex: 1 1 auto !important;
        width: 100% !important;
        max-width: 100% !important;
        padding: 24px !important;
    }
}


/* ─── 14 · BOTTOM SCRIPTURE LINE — HIGH CONTRAST ───────────── */
.ks-auth-footer {
    position: relative;
    z-index: 1;
    margin-top: var(--ks-space-xl);
    text-align: center;
    font-family: var(--ks-font-serif);
    font-style: italic;
    font-size: 13px !important;
    color: var(--ks-gold) !important;
    opacity: 1 !important;
    padding: 0 var(--ks-space-md);
    line-height: 1.6;
    max-width: 600px;
}
.ks-auth-footer em {
    font-style: italic;
    color: var(--ks-gold);
}
.ks-auth-footer__ref {
    display: inline-block;
    margin-top: 4px;
    font-style: normal;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    font-size: 10px;
    color: var(--ks-gold);
}


/* ─── 15 · ALERTS ──────────────────────────────────────────── */
.alert,
.notice,
.success,
.dev,
.alert-error,
.alert-success {
    border-radius: var(--ks-radius-input);
    padding: 12px 14px;
    margin-bottom: var(--ks-space-md);
    line-height: 1.5;
    font-size: 12px;
    border: 0.5px solid transparent;
}

.alert, .alert-error {
    background: #fef2f2;
    color: #b91c1c;
    border-color: #fecaca;
}

.notice {
    background: var(--ks-parchment);
    color: var(--ks-navy);
    border-color: var(--ks-border);
}

.success, .alert-success {
    background: rgba(74, 111, 92, 0.08);
    color: var(--ks-sage);
    border-color: rgba(74, 111, 92, 0.25);
}

.dev {
    background: var(--ks-parchment);
    color: var(--ks-navy);
    border-color: var(--ks-border);
    font-size: 11px;
    word-break: break-all;
}
.dev a { color: var(--ks-sage); font-weight: 500; }


/* ─── 16 · LEGACY LINK ROWS ────────────────────────────────── */
.link-row {
    text-align: center;
    margin-top: var(--ks-space-md);
    font-size: 12px;
    color: var(--ks-slate);
}
.link-row a {
    color: var(--ks-sage) !important;
    text-decoration: none;
    font-weight: 500;
}
.link-row a:hover { text-decoration: underline; }

.back {
    display: block;
    text-align: center;
    margin-top: var(--ks-space-md);
    color: var(--ks-sage) !important;
    text-decoration: none;
    font-weight: 500;
    font-size: 12px;
}
.back:hover {
    text-decoration: underline;
    color: #3d5e4d !important;
}


/* ─── 17 · CODE BOX ────────────────────────────────────────── */
.code-box {
    background: var(--ks-parchment);
    border: 0.5px solid var(--ks-border);
    border-radius: var(--ks-radius-input);
    padding: 12px 14px;
    margin-bottom: var(--ks-space-md);
}
.code-label {
    font-size: 10px;
    letter-spacing: 1.2px;
    color: var(--ks-slate);
    text-transform: uppercase;
    margin-bottom: 4px;
}
.code {
    font-family: 'SF Mono', Monaco, monospace;
    font-weight: 600;
    letter-spacing: 0.15em;
    color: var(--ks-navy);
    font-size: 14px;
}


/* ─── 18 · MISC LEGACY ─────────────────────────────────────── */
.eyebrow {
    color: var(--ks-slate);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    margin-bottom: 4px;
    text-align: center;
}
.choir-photo {
    width: 100%;
    height: 180px;
    background: var(--ks-parchment);
    border: 0.5px solid var(--ks-border);
    border-radius: 10px;
    overflow: hidden;
    margin-bottom: var(--ks-space-md);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ks-slate);
}
.choir-photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.pub-hero {
    height: 160px;
    background: var(--ks-navy);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ks-cream);
    text-align: center;
    border-radius: 10px;
}
.pub-hero .brand-name {
    font-family: var(--ks-font-serif);
    font-size: 24px;
    font-weight: 500;
    letter-spacing: 4px;
    text-transform: uppercase;
}
.pub-hero .tagline {
    color: var(--ks-gold);
    margin-top: 6px;
    font-size: 11px;
    letter-spacing: 1.5px;
    text-transform: uppercase;
}



/* ============================================================================
   ╔══════════════════════════════════════════════════════════════════════════╗
   ║  AMBIENT BACKGROUND v2 · MUSIC NOTES + WAVES + GLOW                      ║
   ║  ────────────────────────────────────────────────────────────────────    ║
   ║  Premium ambient layer inspired by Stripe / Linear auth screens.         ║
   ║   · 24 floating gold music notes (3× previous density)                   ║
   ║   · 3 distinct animation curves so motion never feels mechanical         ║
   ║   · Always-visible opacity floor — notes never fully disappear           ║
   ║   · 2 sound-wave layers crawl horizontally at different speeds           ║
   ║   · GPU-accelerated via transform + will-change                          ║
   ║   · Respects prefers-reduced-motion                                      ║
   ╚══════════════════════════════════════════════════════════════════════════╝
   ========================================================================= */

.ks-bg {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    overflow: hidden;
}

/* Auth shell + footer always sit ABOVE the background */
.ks-auth-shell,
.ks-auth-footer { position: relative; z-index: 2; }
.ks-modal-overlay { z-index: 100; }


/* ─── Soft radial glow behind the card (depth + warmth) ───── */
.ks-bg__glow {
    position: absolute;
    width: 900px;
    height: 900px;
    border-radius: 50%;
    background: radial-gradient(
        circle,
        rgba(212, 169, 85, 0.10) 0%,
        rgba(212, 169, 85, 0.04) 35%,
        transparent 70%
    );
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    animation: ksGlowPulse 14s ease-in-out infinite;
    will-change: transform, opacity;
}
@keyframes ksGlowPulse {
    0%, 100% { transform: translate(-50%, -50%) scale(1);    opacity: 0.85; }
    50%      { transform: translate(-50%, -50%) scale(1.20); opacity: 1; }
}


/* ─── Sound waves (parallax: 2 layers, opposite directions) ─── */
.ks-bg__wave {
    position: absolute;
    left: 0;
    width: 220%;
    height: 160px;
    color: var(--ks-gold);
    will-change: transform;
}
.ks-bg__wave svg {
    width: 100%;
    height: 100%;
    display: block;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.5;
}
.ks-bg__wave--front {
    bottom: 30px;
    opacity: 0.10;
    animation: ksWaveDrift 32s linear infinite;
}
.ks-bg__wave--back {
    bottom: 130px;
    opacity: 0.06;
    animation: ksWaveDriftBack 44s linear infinite;
}
@keyframes ksWaveDrift {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-50%, 0, 0); }
}
@keyframes ksWaveDriftBack {
    from { transform: translate3d(-50%, 0, 0); }
    to   { transform: translate3d(0, 0, 0); }
}


/* ─── Music notes: base setup ─────────────────────────────── */
.ks-bg__note {
    position: absolute;
    color: var(--ks-gold);
    opacity: 0.12;            /* visible at all times — no frozen-fade look */
    will-change: transform, opacity;
    animation-iteration-count: infinite;
    animation-timing-function: ease-in-out;
}
.ks-bg__note svg {
    width: 100%;
    height: 100%;
    fill: currentColor;
    stroke: currentColor;
    stroke-width: 0;
}

/* ─── Animation A — slow drift upward with gentle sway (most notes) ─ */
@keyframes ksNoteDrift {
    0%   { transform: translate3d(0, 100vh, 0) rotate(-8deg);   opacity: 0; }
    10%  { opacity: 0.18; }
    50%  { transform: translate3d(20px, 50vh, 0) rotate(4deg);  opacity: 0.16; }
    90%  { opacity: 0.18; }
    100% { transform: translate3d(-15px, -15vh, 0) rotate(10deg); opacity: 0; }
}

/* ─── Animation B — drift with stronger horizontal motion ─────── */
@keyframes ksNoteSway {
    0%   { transform: translate3d(0, 100vh, 0) rotate(6deg);    opacity: 0; }
    15%  { opacity: 0.20; }
    35%  { transform: translate3d(-30px, 70vh, 0) rotate(-3deg); }
    65%  { transform: translate3d(35px, 30vh, 0) rotate(5deg); }
    85%  { opacity: 0.20; }
    100% { transform: translate3d(0, -12vh, 0) rotate(-8deg);   opacity: 0; }
}

/* ─── Animation C — soft pulse-in-place + gentle rise ─────────── */
@keyframes ksNotePulse {
    0%   { transform: translate3d(0, 100vh, 0) scale(0.8) rotate(0deg); opacity: 0; }
    20%  { opacity: 0.22; transform: translate3d(0, 75vh, 0) scale(1) rotate(2deg); }
    50%  { opacity: 0.10; transform: translate3d(0, 45vh, 0) scale(1.1) rotate(-2deg); }
    80%  { opacity: 0.22; transform: translate3d(0, 15vh, 0) scale(1) rotate(3deg); }
    100% { transform: translate3d(0, -12vh, 0) scale(0.85) rotate(0); opacity: 0; }
}


/* ─── 24 notes: distributed left→right with varied size/timing ────
   Format: position · size · animation type · duration · delay
   Negative delays start mid-animation so the screen is populated
   on first render (no awkward "all empty for 10 seconds" wait).    */

.ks-bg__note--1  { left:  3%; width: 22px; height: 22px; animation: ksNoteDrift  18s linear infinite;       animation-delay:  -2s; }
.ks-bg__note--2  { left:  9%; width: 30px; height: 30px; animation: ksNoteSway   22s ease-in-out infinite;  animation-delay:  -7s; }
.ks-bg__note--3  { left: 15%; width: 18px; height: 18px; animation: ksNotePulse  16s ease-in-out infinite;  animation-delay: -11s; }
.ks-bg__note--4  { left: 21%; width: 26px; height: 26px; animation: ksNoteDrift  20s linear infinite;       animation-delay:  -4s; }
.ks-bg__note--5  { left: 27%; width: 20px; height: 20px; animation: ksNoteSway   24s ease-in-out infinite;  animation-delay: -15s; }
.ks-bg__note--6  { left: 33%; width: 34px; height: 34px; animation: ksNotePulse  19s ease-in-out infinite;  animation-delay:  -8s; }
.ks-bg__note--7  { left: 39%; width: 16px; height: 16px; animation: ksNoteDrift  17s linear infinite;       animation-delay: -13s; }
.ks-bg__note--8  { left: 45%; width: 28px; height: 28px; animation: ksNoteSway   26s ease-in-out infinite;  animation-delay:  -3s; }
.ks-bg__note--9  { left: 51%; width: 22px; height: 22px; animation: ksNotePulse  21s ease-in-out infinite;  animation-delay: -17s; }
.ks-bg__note--10 { left: 57%; width: 18px; height: 18px; animation: ksNoteDrift  19s linear infinite;       animation-delay:  -6s; }
.ks-bg__note--11 { left: 63%; width: 32px; height: 32px; animation: ksNoteSway   23s ease-in-out infinite;  animation-delay: -10s; }
.ks-bg__note--12 { left: 69%; width: 20px; height: 20px; animation: ksNotePulse  18s ease-in-out infinite;  animation-delay:  -1s; }
.ks-bg__note--13 { left: 75%; width: 26px; height: 26px; animation: ksNoteDrift  22s linear infinite;       animation-delay: -14s; }
.ks-bg__note--14 { left: 81%; width: 16px; height: 16px; animation: ksNoteSway   17s ease-in-out infinite;  animation-delay:  -5s; }
.ks-bg__note--15 { left: 87%; width: 30px; height: 30px; animation: ksNotePulse  25s ease-in-out infinite;  animation-delay:  -9s; }
.ks-bg__note--16 { left: 93%; width: 22px; height: 22px; animation: ksNoteDrift  20s linear infinite;       animation-delay: -16s; }
/* Second wave — staggered offsets create deeper density */
.ks-bg__note--17 { left:  6%; width: 16px; height: 16px; animation: ksNoteSway   28s ease-in-out infinite;  animation-delay: -22s; }
.ks-bg__note--18 { left: 18%; width: 24px; height: 24px; animation: ksNotePulse  17s ease-in-out infinite;  animation-delay: -19s; }
.ks-bg__note--19 { left: 30%; width: 20px; height: 20px; animation: ksNoteDrift  23s linear infinite;       animation-delay: -25s; }
.ks-bg__note--20 { left: 42%; width: 28px; height: 28px; animation: ksNoteSway   19s ease-in-out infinite;  animation-delay: -21s; }
.ks-bg__note--21 { left: 54%; width: 18px; height: 18px; animation: ksNotePulse  22s ease-in-out infinite;  animation-delay: -27s; }
.ks-bg__note--22 { left: 66%; width: 24px; height: 24px; animation: ksNoteDrift  16s linear infinite;       animation-delay: -23s; }
.ks-bg__note--23 { left: 78%; width: 32px; height: 32px; animation: ksNoteSway   21s ease-in-out infinite;  animation-delay: -29s; }
.ks-bg__note--24 { left: 90%; width: 20px; height: 20px; animation: ksNotePulse  18s ease-in-out infinite;  animation-delay: -26s; }


/* ─── Mobile: drop note count to 12 + slower wave for battery ───── */
@media (max-width: 720px) {
    .ks-bg__note--13,
    .ks-bg__note--14,
    .ks-bg__note--15,
    .ks-bg__note--16,
    .ks-bg__note--17,
    .ks-bg__note--18,
    .ks-bg__note--19,
    .ks-bg__note--20,
    .ks-bg__note--21,
    .ks-bg__note--22,
    .ks-bg__note--23,
    .ks-bg__note--24 { display: none; }
    .ks-bg__wave--back { display: none; }
    .ks-bg__glow { width: 500px; height: 500px; }
}

/* ─── Accessibility: kill motion for users who request it ──────── */
@media (prefers-reduced-motion: reduce) {
    .ks-bg__note,
    .ks-bg__wave,
    .ks-bg__glow {
        animation: none !important;
    }
    .ks-bg__note { opacity: 0.08; }
    .ks-bg__wave--front, .ks-bg__wave--back { opacity: 0.05; }
}

/* ─── 19 · INVITATION PREVIEW PAGE (invite.php) ─────────────────────────────
   Single centred invitation card. Centering + ambient background come from the
   shared body.kosis-public / .ks-bg shell (the same one the auth pages use), so
   this only styles the card + its contents. Scoped under .kosis-invite. */
.kosis-invite .ks-invite-card {
    position: relative; z-index: 2;
    width: 100%; max-width: 440px;
    background: var(--ks-cream);
    border: 0.5px solid var(--ks-border);
    border-radius: 18px;
    padding: var(--ks-space-xl);
    text-align: center;
    box-shadow: 0 24px 70px rgba(0, 0, 0, 0.40);
}
.kosis-invite .ks-invite-brand { display: flex; flex-direction: column; align-items: center;
    gap: 6px; margin-bottom: var(--ks-space-lg); }
.kosis-invite .ks-invite-brand img { width: 200px; height: auto; max-width: 62%; display: block; }
.kosis-invite .ks-invite-word { font-family: var(--ks-font-serif); font-size: 14px; font-weight: 500;
    letter-spacing: 5px; color: var(--ks-navy); }
.kosis-invite .ks-invite-eyebrow { font-family: var(--ks-font-sans); font-size: 11px; font-weight: 600;
    letter-spacing: 1.6px; text-transform: uppercase; color: var(--ks-gold); margin: 0 0 6px; }
.kosis-invite .ks-invite-name { font-family: var(--ks-font-serif); font-size: 26px; font-weight: 500;
    line-height: 1.2; color: var(--ks-navy); margin: 0; }
.kosis-invite .ks-invite-rule { display: block; width: 40px; height: 2px; background: var(--ks-gold);
    border-radius: 2px; margin: 12px auto var(--ks-space-md); }
.kosis-invite .ks-invite-photo { width: 100%; aspect-ratio: 16 / 10; border-radius: 14px; overflow: hidden;
    background: var(--ks-parchment, #FDF3DA); border: 0.5px solid var(--ks-border);
    display: flex; align-items: center; justify-content: center; margin: 0 0 var(--ks-space-md); }
.kosis-invite .ks-invite-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.kosis-invite .ks-invite-photo span { font-family: var(--ks-font-sans); font-size: 12px; color: var(--ks-slate); }
.kosis-invite .ks-invite-desc { font-family: var(--ks-font-sans); font-size: 13px; color: var(--ks-slate);
    line-height: 1.6; margin: 0 auto var(--ks-space-md); max-width: 40ch; }
.kosis-invite .ks-invite-codebox { display: flex; flex-direction: column; align-items: center; gap: 6px;
    background: var(--ks-navy); border-radius: 12px; padding: 16px; margin: 0 0 var(--ks-space-md); }
.kosis-invite .ks-invite-codelabel { font-family: var(--ks-font-sans); font-size: 10px; letter-spacing: 1.4px;
    text-transform: uppercase; color: var(--ks-gold); }
.kosis-invite .ks-invite-code { font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace; font-size: 22px;
    font-weight: 600; letter-spacing: .18em; color: var(--ks-cream); }
.kosis-invite .ks-invite-card .btn { width: 100%; margin-top: 4px; }
.kosis-invite .ks-invite-minor { font-family: var(--ks-font-sans); font-size: 12px; color: var(--ks-slate);
    margin: var(--ks-space-md) 0 0; }
.kosis-invite .ks-invite-minor a { color: var(--ks-sage) !important; font-weight: 500; text-decoration: none; }
.kosis-invite .ks-invite-minor a:hover { text-decoration: underline; }
.kosis-invite .alert { margin-bottom: var(--ks-space-md); }
@media (max-width: 640px) {
    .kosis-invite .ks-invite-card { padding: var(--ks-space-lg); max-width: 420px; }
    .kosis-invite .ks-invite-brand img { width: 160px; height: auto; }
}


/* ─── 20 · JOIN PAGE (join.php) ─────────────────────────────────────────────
   The invite "Join Now" destination. Reuses the shared auth shell
   (body.kosis-auth.kosis-public + .ks-bg + .ks-auth-shell/.ks-auth-card) that
   the login/register pages use, so the form inherits the proven field, button
   and header styling. This block only adds the choir intro (eyebrow + name +
   photo), the two-up field grid, small hint/terms text, and the existing-
   account modal. Scoped under .kosis-join. */
.kosis-join .ks-join-eyebrow {
    font-family: var(--ks-font-sans); font-size: 11px; font-weight: 600;
    letter-spacing: 1.6px; text-transform: uppercase; color: var(--ks-gold);
    text-align: center; margin: 2px 0 4px;
}
.kosis-join .ks-join-choir {
    font-family: var(--ks-font-serif); font-size: 22px; font-weight: 500;
    line-height: 1.2; color: var(--ks-navy); text-align: center; margin: 0;
}
.kosis-join .ks-join-rule-line {
    display: block; width: 40px; height: 2px; background: var(--ks-gold);
    border-radius: 2px; margin: 12px auto var(--ks-space-md);
}
.kosis-join .ks-join-photo {
    width: 100%; aspect-ratio: 16 / 10; border-radius: 14px; overflow: hidden;
    background: var(--ks-parchment, #FDF3DA); border: 0.5px solid var(--ks-border);
    display: flex; align-items: center; justify-content: center;
    margin: 0 0 var(--ks-space-md);
}
.kosis-join .ks-join-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.kosis-join .ks-join-help {
    font-family: var(--ks-font-sans); font-size: 13px; color: var(--ks-slate);
    line-height: 1.6; text-align: center; margin: 0 auto var(--ks-space-md); max-width: 42ch;
}
.kosis-join .ks-join-grid {
    display: grid; grid-template-columns: 1fr 1fr; gap: var(--ks-space-md);
}
.kosis-join .ks-join-grid .form-group { margin-bottom: var(--ks-space-md); }
.kosis-join .ks-join-hint {
    font-family: var(--ks-font-sans); font-size: 11px; color: var(--ks-slate);
    line-height: 1.5; margin: 8px 0 0;
}
.kosis-join .ks-join-terms {
    font-family: var(--ks-font-sans); font-size: 11px; color: var(--ks-slate);
    line-height: 1.5; text-align: center; margin: var(--ks-space-md) auto 0; max-width: 42ch;
}
.kosis-join .notice { margin-bottom: var(--ks-space-md); }

/* Existing-account modal */
.kosis-join .ks-join-modal-backdrop {
    position: fixed; inset: 0; z-index: 50;
    background: rgba(15, 20, 40, 0.55); backdrop-filter: blur(3px);
    display: flex; align-items: center; justify-content: center; padding: 20px;
}
.kosis-join .ks-join-modal {
    width: 100%; max-width: 440px; background: var(--ks-cream);
    border: 0.5px solid var(--ks-border); border-radius: 16px;
    padding: var(--ks-space-lg); box-shadow: 0 24px 70px rgba(0, 0, 0, 0.40);
}
.kosis-join .ks-join-modal__head {
    display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
    margin-bottom: var(--ks-space-sm);
}
.kosis-join .ks-join-modal__head h2 {
    font-family: var(--ks-font-serif); font-size: 18px; font-weight: 500;
    color: var(--ks-navy); margin: 0; line-height: 1.3;
}
.kosis-join .ks-join-modal__x {
    border: none; background: transparent; color: var(--ks-slate);
    font-size: 22px; line-height: 1; cursor: pointer; padding: 0 4px;
}
.kosis-join .ks-join-modal__x:hover { color: var(--ks-navy); }
.kosis-join .ks-join-modal p {
    font-family: var(--ks-font-sans); font-size: 13px; color: var(--ks-slate);
    line-height: 1.6; margin: 0 0 var(--ks-space-md);
}
.kosis-join .ks-join-modal__actions {
    display: grid; grid-template-columns: 1fr 1fr; gap: var(--ks-space-sm);
}
.kosis-join .ks-join-modal__actions .btn { margin-top: 0; }

@media (max-width: 640px) {
    .kosis-join .ks-join-grid { grid-template-columns: 1fr; gap: 0; }
    .kosis-join .ks-join-modal__actions { grid-template-columns: 1fr; }
}
