/* 0. Layout guards — load LAST so they win on cascade.
 *
 * premium.css defines `.app-shell { display: grid;
 * grid-template-columns: 240px 1fr }`. For logged-in users the first
 * column holds <aside class="sidebar"> and the second holds <main>.
 * For guests the sidebar isn't rendered (the _sidebar.html.twig
 * template is gated behind {% if app.user %}), so <main> lands in
 * the first column — 240 px wide — and the second column is empty
 * dead space.
 *
 * The visible symptom on legal / auth pages was a ~240 px column with
 * every word wrapping to its own line. On pages with wide intrinsic
 * content (user grids, admin tables) the symptom was hidden by the
 * content forcing the column wider via min-content.
 *
 * Fix: keep the two-column grid when the shell actually has a
 * sidebar; collapse to a single column when it doesn't. Uses :has()
 * — Baseline 2023, supported by every browser we target.
 */
.app-shell { grid-template-columns: 1fr !important; }
.app-shell:has(> aside.sidebar) { grid-template-columns: 240px 1fr !important; }

/* polish.css — micro-interaction layer.
 *
 * Pure-CSS animations + a few utility classes that the rest of the site
 * can opt into. Loaded last in base.html.twig so it can override anything
 * in tokens / premium / bridges. Every rule respects
 * `prefers-reduced-motion: reduce` so accessibility users get static.
 *
 * Sections:
 *   1. Card hover lift + smooth transitions
 *   2. Button press feedback
 *   3. Confetti burst (.confetti, fires on .has-confetti elements)
 *   4. Like-action heart bounce
 *   5. Birthday card halo pulse
 *   6. Skeleton shimmer (replaces the older skeleton-pulse)
 *   7. Twinkle / sparkle decorations
 *   8. Page enter fade (turbo:render)
 */

/* 1. Card hover lift — applied to .card, .user-card, .adm-userrow.
   Cards already have transitions in places; this normalises them so
   every list looks the same on hover. */
.user-card, .card, .adm-userrow {
    transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.user-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 8px 20px -8px rgba(92, 35, 64, 0.18);
}

/* 2. Button press feedback — tactile little press on tap so the user
   knows the click registered even on slow networks. */
.btn { transition: transform 0.08s ease, background 0.15s ease, box-shadow 0.15s ease; }
.btn:active { transform: scale(0.97); }

/* 3. Confetti burst — small particles falling from an anchor point.
   Trigger by adding .has-confetti class to a wrapper that contains
   six .confetti spans. JS / template wires this up where needed
   (birthday cards do it inline). */
@keyframes confetti-fall {
    0%   { transform: translate(0, -20px) rotate(0deg);    opacity: 1 }
    100% { transform: translate(var(--cx, 30px), 200px) rotate(var(--cr, 540deg)); opacity: 0 }
}
.confetti {
    position: absolute; top: 0; left: 50%;
    width: 8px; height: 12px;
    background: var(--coral);
    border-radius: 2px;
    pointer-events: none;
    animation: confetti-fall 2.2s cubic-bezier(0.2, 0.7, 0.4, 1) forwards;
}
.confetti:nth-child(1) { --cx: -90px; --cr: -480deg; background: var(--coral);     animation-delay: 0s }
.confetti:nth-child(2) { --cx: -40px; --cr: 360deg;  background: var(--plum);      animation-delay: 0.1s }
.confetti:nth-child(3) { --cx:  10px; --cr: -240deg; background: #F5B400;          animation-delay: 0.05s }
.confetti:nth-child(4) { --cx:  50px; --cr: 600deg;  background: var(--coral);     animation-delay: 0.15s }
.confetti:nth-child(5) { --cx:  90px; --cr: -360deg; background: var(--plum);      animation-delay: 0.2s }
.confetti:nth-child(6) { --cx: 130px; --cr: 480deg;  background: #00C896;          animation-delay: 0.1s }

/* 4. Like action — apply .liked to a button/icon to play a one-shot pulse.
   The "broken heart" (unlike) is also there, for symmetry. */
@keyframes heart-bounce {
    0%, 100% { transform: scale(1) }
    20%      { transform: scale(0.85) }
    50%      { transform: scale(1.35) }
    75%      { transform: scale(0.95) }
}
.liked, .like-pulse { animation: heart-bounce 0.6s ease-in-out 1; transform-origin: center; }

/* 5. Birthday card halo — soft coral glow on cards where today is the
   user's birthday. Distinguishes them visually without screaming. */
.user-card.is-birthday {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--coral) 60%, transparent),
                0 8px 24px -10px color-mix(in srgb, var(--coral) 30%, transparent);
}

/* 6. Skeleton shimmer — gradient sweep across loading placeholders.
   Uses the surface tones so it adapts to both light + dark themes. */
@keyframes skeleton-sweep {
    0%   { background-position: -200px 0 }
    100% { background-position: calc(200px + 100%) 0 }
}
.skeleton {
    background: linear-gradient(
        90deg,
        var(--surface-alt) 0%,
        color-mix(in srgb, var(--surface-alt) 60%, var(--surface)) 50%,
        var(--surface-alt) 100%
    );
    background-size: 200px 100%;
    background-repeat: no-repeat;
    animation: skeleton-sweep 1.4s linear infinite;
}

/* 7. Twinkle utility — for any small decorative element that should pulse
   gently. Combine with inline `style="animation-delay: ..."` to stagger. */
@keyframes twinkle {
    from { opacity: 0.4; transform: scale(0.94) }
    to   { opacity: 1;   transform: scale(1.06) }
}
.twinkle { animation: twinkle 2.6s ease-in-out infinite alternate; }

/* 8. Page enter — subtle fade-in after each Turbo navigation. Tied to
   <main> so the chrome (top nav, drawers) stays steady. */
@keyframes page-fade-in {
    from { opacity: 0; transform: translateY(2px) }
    to   { opacity: 1; transform: translateY(0) }
}
main, .layout__main, .content-container {
    animation: page-fade-in 0.22s ease-out;
}

/* 9. Toast slide-up — for the bottom-center #toast element used by
   user_profile.html.twig and elsewhere. JS still toggles
   `style.display = block | none`; this CSS gives the show a smooth
   entrance and bounce so it doesn't snap on. */
@keyframes toast-pop {
    0%   { opacity: 0; transform: translate(-50%, 16px) scale(0.95) }
    60%  { opacity: 1; transform: translate(-50%, -4px) scale(1.02) }
    100% { opacity: 1; transform: translate(-50%, 0)    scale(1) }
}
#toast { animation: toast-pop 0.32s cubic-bezier(0.16, 0.84, 0.44, 1) }

/* 10. Flash messages — applied to any element with the .flash class so
    the green "saved" or red "error" banners glide in from the top. */
@keyframes flash-slide-in {
    from { opacity: 0; transform: translateY(-8px) }
    to   { opacity: 1; transform: translateY(0) }
}
.flash { animation: flash-slide-in 0.28s ease-out }

/* 11. Locale pill — dual-flag segmented control in the top nav.
    Compact (~96 px wide), works on mobile (flag-only on narrow viewports)
    and accessible (each option is a real <a>, aria-current marks active). */
.locale-pill {
    display: inline-flex;
    background: var(--surface-alt);
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 2px;
    gap: 1px;
}
.locale-pill__opt {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 4px 10px;
    border-radius: 999px;
    text-decoration: none;
    font-size: 12px; font-weight: 600;
    color: var(--ink-muted);
    transition: background 0.15s ease, color 0.15s ease, transform 0.12s ease;
}
.locale-pill__opt:hover { color: var(--ink); text-decoration: none; transform: translateY(-1px); }
.locale-pill__opt.is-active {
    background: var(--surface);
    color: var(--ink);
    box-shadow: 0 1px 2px rgba(0,0,0,0.06);
    cursor: default;
}
.locale-pill__opt.is-active:hover { transform: none }
.locale-pill__flag { font-size: 14px; line-height: 1; }
@media (max-width: 480px) {
    /* Tight mobile — hide the two-letter code, keep just the flag.
       Active state still readable via the surface contrast. */
    .locale-pill__code { display: none }
    .locale-pill__opt { padding: 4px 8px }
}

/* 12. Sparkle ring — small spinning halo for VIP / star badges.
    Opt-in: add .sparkle-ring to any element you want to halo. */
@keyframes sparkle-ring {
    from { transform: rotate(0deg) }
    to   { transform: rotate(360deg) }
}
.sparkle-ring::before {
    content: '';
    position: absolute; inset: -4px;
    border-radius: inherit;
    background: conic-gradient(from 0deg, transparent 0deg, color-mix(in srgb, var(--coral) 50%, transparent) 90deg, transparent 180deg, color-mix(in srgb, var(--plum) 50%, transparent) 270deg, transparent 360deg);
    z-index: -1;
    animation: sparkle-ring 4s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
    .sparkle-ring::before { animation: none }
}

/* Accessibility — disable all of the above for users with the reduced-
   motion preference. They keep colours and layout, lose animation. */
@media (prefers-reduced-motion: reduce) {
    .user-card, .card, .adm-userrow, .btn { transition: none !important }
    .confetti, .liked, .like-pulse, .skeleton, .twinkle, main,
    #toast, .flash {
        animation: none !important;
    }
    .user-card:hover { transform: none !important }
}
