/* A&S v4: feedback. Toasts, alert dialogs and loaders. Served by the system itself: no CDN.
   The JavaScript is public/assets/js/app-feedback.js. The colours come from app.css. */

/* ---------------------------------------------------------------- top progress bar */
.nprog { position: fixed; z-index: 200; top: 0; left: 0; right: 0; height: 3px; pointer-events: none; opacity: 0; transition: opacity 0.3s ease 0.15s; }
.nprog.is-on { opacity: 1; transition: none; }
.nprog i { display: block; height: 100%; width: 0; background: var(--pulse); border-radius: 0 3px 3px 0; transition: width 0.25s ease; }

/* ---------------------------------------------------------------- toasts (toastr) */
.toastr { position: fixed; z-index: 150; display: flex; flex-direction: column; gap: 0.625rem; width: min(23.5rem, calc(100vw - 2rem)); pointer-events: none; }
.toastr.toast-top-right { top: 1rem; right: 1rem; }
.toastr.toast-top-left { top: 1rem; left: 1rem; }
.toastr.toast-top-center { top: 1rem; left: 50%; transform: translateX(-50%); }
.toastr.toast-bottom-right { bottom: 1rem; right: 1rem; flex-direction: column-reverse; }
.toastr.toast-bottom-left { bottom: 1rem; left: 1rem; flex-direction: column-reverse; }
.toastr.toast-bottom-center { bottom: 1rem; left: 50%; transform: translateX(-50%); flex-direction: column-reverse; }
.tst { position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: start; gap: 0.75rem; padding: 0.875rem 0.875rem 0.9375rem 0.9375rem; overflow: hidden; pointer-events: auto; cursor: default;
    color: var(--text); background: var(--surface); border: 1px solid var(--line); border-radius: 0.875rem; box-shadow: 0 10px 30px -8px rgba(15, 23, 19, 0.28), 0 2px 6px rgba(15, 23, 19, 0.08);
    animation: tst-in 0.32s cubic-bezier(0.2, 0.9, 0.3, 1.2); }
.tst.is-leaving { animation: tst-out 0.22s ease-in forwards; }
.tst-icon { display: grid; place-items: center; width: 2rem; height: 2rem; border-radius: 50%; color: #fff; flex: none; }
.tst-icon svg { width: 1.125rem; height: 1.125rem; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.tst-title { font-weight: 700; font-size: 0.875rem; line-height: 1.3; }
.tst-msg { font-size: 0.875rem; line-height: 1.4; color: var(--text-2); overflow-wrap: anywhere; }
.tst-title + .tst-msg { margin-top: 0.125rem; }
.tst-msg:only-child, .tst-body > .tst-msg:first-child { color: var(--text); font-weight: 500; padding-top: 0.3125rem; }
.tst-x { width: 1.625rem; height: 1.625rem; margin: -0.125rem -0.125rem 0 0; display: grid; place-items: center; font-size: 1.125rem; line-height: 1; color: var(--text-3); background: none; border: 0; border-radius: 50%; cursor: pointer; }
.tst-x:hover { background: var(--surface-3); color: var(--text); }
.tst-bar { position: absolute; left: 0; bottom: 0; height: 3px; width: 100%; transform-origin: left; animation: tst-bar linear forwards; }
.tst:hover .tst-bar { animation-play-state: paused; }
.tst-success .tst-icon, .tst-success .tst-bar { background: var(--ok); }
.tst-error .tst-icon, .tst-error .tst-bar { background: var(--danger); }
.tst-warning .tst-icon, .tst-warning .tst-bar { background: #d98a00; }
.tst-info .tst-icon, .tst-info .tst-bar { background: var(--info); }
.tst-success { border-color: color-mix(in srgb, var(--ok) 35%, var(--line)); }
.tst-error { border-color: color-mix(in srgb, var(--danger) 40%, var(--line)); }
@keyframes tst-in { from { opacity: 0; transform: translateX(1.5rem) scale(0.96); } }
@keyframes tst-out { to { opacity: 0; transform: translateX(1.5rem) scale(0.96); } }
@keyframes tst-bar { to { transform: scaleX(0); } }

/* ---------------------------------------------------------------- alert dialogs (Swal.fire) */
.swal-overlay { position: fixed; inset: 0; z-index: 120; display: grid; place-items: center; padding: 1rem; background: rgba(9, 14, 11, 0.6); backdrop-filter: blur(3px); animation: fade 0.16s ease-out; }
.swal-overlay.is-leaving { animation: swal-fade-out 0.14s ease-in forwards; }
.swal { width: min(27rem, 100%); max-height: calc(100vh - 2rem); overflow-y: auto; padding: 2rem 1.75rem 1.5rem; text-align: center; color: var(--text); background: var(--surface); border-radius: 1.375rem; box-shadow: var(--shadow-pop);
    animation: swal-pop 0.34s cubic-bezier(0.2, 0.9, 0.3, 1.25); }
.swal-overlay.is-leaving .swal { animation: swal-out 0.14s ease-in forwards; }
.swal-icon { position: relative; width: 5rem; height: 5rem; margin: 0 auto 1.125rem; border-radius: 50%; display: grid; place-items: center; }
.swal-icon svg { width: 5rem; height: 5rem; fill: none; stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; }
.swal-icon circle { stroke-dasharray: 240; stroke-dashoffset: 240; animation: swal-draw 0.55s ease-out 0.05s forwards; opacity: 0.28; }
.swal-icon path { stroke-dasharray: 80; stroke-dashoffset: 80; animation: swal-draw 0.4s ease-out 0.4s forwards; }
.swal-icon.is-success { color: var(--ok); background: var(--ok-soft); }
.swal-icon.is-error { color: var(--danger); background: var(--danger-soft); animation: swal-shake 0.5s ease 0.25s; }
.swal-icon.is-warning { color: #d98a00; background: var(--warn-soft); }
.swal-icon.is-info { color: var(--info); background: var(--info-soft); }
.swal-icon.is-question { color: var(--green); background: var(--green-soft); }
.swal-icon svg { stroke: currentColor; }
.swal-title { margin: 0 0 0.5rem; font-family: var(--font-display); font-size: 1.4375rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.2; }
.swal-text { margin: 0; font-size: 0.9375rem; line-height: 1.5; color: var(--text-2); overflow-wrap: anywhere; }
.swal-text strong { color: var(--text); }
.swal-field { margin-top: 1.125rem; text-align: left; }
.swal-field label { display: block; margin-bottom: 0.375rem; font-size: 0.8125rem; font-weight: 600; }
.swal-error { margin-top: 0.5rem; padding: 0.5rem 0.75rem; font-size: 0.8125rem; font-weight: 500; text-align: left; color: var(--danger); background: var(--danger-soft); border-radius: var(--radius-s); }
.swal-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.625rem; margin-top: 1.5rem; }
.swal-actions .btn { min-width: 7rem; min-height: 2.75rem; justify-content: center; }
.swal-footer { margin-top: 1.125rem; padding-top: 0.875rem; border-top: 1px solid var(--line); font-size: 0.8125rem; color: var(--text-3); }
.swal-timer { height: 3px; margin: 1.25rem -1.75rem -1.5rem; background: var(--pulse); transform-origin: left; animation: tst-bar linear forwards; }
.swal-big { font-family: var(--font-display); font-size: 2.5rem; font-weight: 700; letter-spacing: -0.03em; line-height: 1.1; color: var(--text); font-variant-numeric: tabular-nums; }
.swal-big small { display: block; margin-bottom: 0.25rem; font-family: var(--font); font-size: 0.75rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-3); }
@keyframes swal-pop { from { opacity: 0; transform: scale(0.82) translateY(0.75rem); } }
@keyframes swal-out { to { opacity: 0; transform: scale(0.94); } }
@keyframes swal-fade-out { to { opacity: 0; } }
@keyframes swal-draw { to { stroke-dashoffset: 0; } }
@keyframes swal-shake { 20%, 60% { transform: translateX(-0.375rem); } 40%, 80% { transform: translateX(0.375rem); } }

/* ---------------------------------------------------------------- loaders */
/* Full screen: the club's bolt, pulsing, with a ring turning round it. */
.loader-overlay { position: fixed; inset: 0; z-index: 140; display: grid; place-items: center; background: color-mix(in srgb, var(--bg) 78%, transparent); backdrop-filter: blur(4px); animation: fade 0.18s ease-out; }
.loader-box { display: grid; justify-items: center; gap: 1rem; padding: 1.75rem 2.25rem; text-align: center; }
.loader-ring { position: relative; width: 4.75rem; height: 4.75rem; display: grid; place-items: center; }
.loader-ring::before, .loader-ring::after { content: ""; position: absolute; inset: 0; border-radius: 50%; }
.loader-ring::before { border: 4px solid var(--surface-3); }
.loader-ring::after { border: 4px solid transparent; border-top-color: var(--green); animation: spin 0.8s cubic-bezier(0.5, 0.15, 0.5, 0.85) infinite; }
.loader-text { font-weight: 600; color: var(--text); }
.loader-sub { margin-top: -0.625rem; font-size: 0.8125rem; color: var(--text-3); }
@keyframes loader-pulse { 50% { transform: scale(0.82); opacity: 0.55; } }

/* Inline: three dots, for inside a panel or a button-sized space. */
.dots { display: inline-flex; gap: 0.3125rem; align-items: center; vertical-align: middle; }
.dots i { width: 0.4375rem; height: 0.4375rem; border-radius: 50%; background: var(--green); animation: dots 1s ease-in-out infinite; }
.dots i:nth-child(2) { animation-delay: 0.14s; }
.dots i:nth-child(3) { animation-delay: 0.28s; }
@keyframes dots { 0%, 80%, 100% { transform: scale(0.55); opacity: 0.35; } 40% { transform: scale(1); opacity: 1; } }

/* Skeleton: grey bars that shimmer where content is about to appear. */
.skeleton { display: block; height: 0.875rem; margin: 0.5rem 0; border-radius: 0.375rem; background: linear-gradient(90deg, var(--surface-3) 25%, var(--surface-2) 37%, var(--surface-3) 63%); background-size: 400% 100%; animation: shimmer 1.3s ease infinite; }
.skeleton.is-title { height: 1.25rem; width: 45%; margin-bottom: 0.875rem; }
.skeleton.is-short { width: 60%; }
.skeleton.is-tile { height: 6rem; margin: 0; border-radius: 0.75rem; }
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }

/* A panel that is refreshing: dimmed, with a bar sliding along its top edge. */
.is-loading { position: relative; pointer-events: none; }
.is-loading > * { opacity: 0.45; transition: opacity 0.15s ease; }
.is-loading::before { content: ""; position: absolute; z-index: 2; top: 0; left: 0; height: 3px; width: 35%; border-radius: 3px; background: var(--pulse); animation: slide-bar 1s ease-in-out infinite; }
@keyframes slide-bar { from { left: -35%; } to { left: 100%; } }

/* Pages arrive with a short rise, so moving between screens feels smooth. */
.page > *, .term-body { animation: page-in 0.28s ease-out both; }
.page > *:nth-child(2) { animation-delay: 0.03s; }
.page > *:nth-child(3) { animation-delay: 0.06s; }
.page > *:nth-child(n+4) { animation-delay: 0.09s; }
@keyframes page-in { from { opacity: 0; transform: translateY(0.5rem); } }

/* A number that just changed gives a small bump. */
.bump { animation: bump 0.3s ease-out; }
@keyframes bump { 40% { transform: scale(1.09); } }

/* Buttons: a soft press. */
.btn { transition: transform 0.08s ease, background-color 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease; }
.btn:active:not(:disabled) { transform: translateY(1px) scale(0.985); }

@media (prefers-reduced-motion: reduce) {
    .tst, .swal, .swal-overlay, .page > *, .term-body, .bump,     .swal-icon circle, .swal-icon path { animation: none; stroke-dashoffset: 0; }
    .loader-ring::after, .dots i, .skeleton, .is-loading::before { animation-duration: 2.4s; }
}
@media print { .toastr, .swal-overlay, .loader-overlay, .nprog { display: none !important; } }
