/*
 * Zak Expo Hub motion (owner, 18 Oct 2026): loading, waiting, processing and celebrations, all drawn from the
 * Expo Hub sign (app/Support/HubMark.php). Short, quiet and never in the way; everything stops for people
 * who ask their device for reduced motion.
 */
:root { --hub-c0: #1A6FA8; --hub-c1: #2F7A4D; --hub-c2: #D62828; --hub-c3: #C60F83; --hub-ink: #141414; }
.dark { --hub-ink: #F6F2EC; }

.hub-mark { display: inline-block; overflow: visible; }
.hub-mark .hub-dot { fill: var(--hub-ink); }
.fi-icon.hub-mark { width: 1.25rem; height: 1.25rem; }
.fi-icon.hub-mark.fi-size-sm { width: 1rem; height: 1rem; }
.fi-icon.hub-mark.fi-size-lg { width: 1.5rem; height: 1.5rem; }
.fi-icon.hub-mark.fi-size-xl { width: 1.75rem; height: 1.75rem; }
.fi-icon.hub-mark.fi-size-2xl { width: 2rem; height: 2rem; }
.fi-icon.hub-mark.animate-spin { animation: none; }

/* Loading: the colours march along every arc, one step at a time (the sign's own "shifting"). */
@keyframes hub-march {
    0%, 24.99% { fill: var(--hub-c0); }
    25%, 49.99% { fill: var(--hub-c3); }
    50%, 74.99% { fill: var(--hub-c2); }
    75%, 100% { fill: var(--hub-c1); }
}
.hub-spin .hub-seg { animation: hub-march 1.2s infinite; }
.hub-spin .hub-c0 { animation-delay: 0s; }
.hub-spin .hub-c3 { animation-delay: -0.3s; }
.hub-spin .hub-c2 { animation-delay: -0.6s; }
.hub-spin .hub-c1 { animation-delay: -0.9s; }

/* On a solid coloured button the sign takes the button's text colour and the arcs breathe in turn. */
@keyframes hub-mono { 0%, 100% { opacity: .35; } 40% { opacity: 1; } }
.fi-btn.fi-color:not(.fi-outlined) .hub-spin .hub-seg,
.fi-badge .hub-spin .hub-seg { fill: currentColor; animation: hub-mono 1.2s infinite; animation-delay: calc(var(--r) * 0.15s + var(--s) * 0.05s); }

/* Waiting: the arcs light up outward from the hub, like reach going out. */
@keyframes hub-out { 0%, 100% { opacity: .16; } 35% { opacity: 1; } }
@keyframes hub-beat { 0%, 100% { transform: scale(1); } 35% { transform: scale(1.18); } }
.hub-wait .hub-seg { animation: hub-out 1.6s ease-in-out infinite; animation-delay: calc(var(--r) * 0.18s); }
.hub-wait .hub-dot { transform-box: fill-box; transform-origin: center; animation: hub-beat 1.6s ease-in-out infinite; }

/* Bloom: the segments grow out of the hub, ring by ring (celebrations, first load). */
@keyframes hub-grow { from { transform: scale(0); opacity: 0; } 60% { opacity: 1; } to { transform: scale(1); opacity: 1; } }
.hub-bloom .hub-seg { transform-box: view-box; transform-origin: 10px 110px; animation: hub-grow .55s cubic-bezier(.2, .9, .25, 1.25) both;
    animation-delay: calc(var(--r) * 0.11s + var(--s) * 0.045s); }
.hub-bloom .hub-dot { transform-box: fill-box; transform-origin: center; animation: hub-grow .4s ease-out both; }

/* The loader component: sign alone, or sign with a label, a line and steps (processing). */
.hub-loader { display: inline-flex; align-items: center; gap: .9rem; color: var(--zak-graphite, #3A3630); text-align: left; }
.hub-loader-process { display: flex; padding: 1rem 1.1rem; border: 1px solid var(--zak-line, #EBE5DC); border-radius: .75rem; background: var(--zak-paper, #FFFFFF); }
.hub-loader-label { font-weight: 500; color: var(--zak-ink, #141414); }
.hub-loader-line { font-size: .875rem; color: var(--zak-stone, #8A8378); }
.hub-loader-steps { margin: .4rem 0 0; padding: 0; list-style: none; font-size: .8125rem; color: var(--zak-stone, #8A8378); display: grid; gap: .15rem; }
.hub-loader-steps li::before { content: ""; display: inline-block; width: .5rem; height: .5rem; margin-right: .5rem; border-radius: 50%; border: 1px solid currentColor; vertical-align: .05rem; }
.hub-loader-steps li.done { color: var(--zak-graphite, #3A3630); }
.hub-loader-steps li.done::before { background: var(--hub-c1); border-color: var(--hub-c1); }
.hub-loader-steps li.now { color: var(--zak-ink, #141414); font-weight: 500; }
.hub-loader-steps li.now::before { background: var(--hub-c0); border-color: var(--hub-c0); animation: hub-out 1.2s infinite; }

/* Busy: while the CRM talks to the server the hairline under the top bar marches; after a while a small note says
   it is still working. */
@keyframes hub-rule-march { from { background-position: 0 0; } to { background-position: 160px 0; } }
.hub-busy .fi-topbar::after { background: repeating-linear-gradient(90deg, var(--hub-c0) 0 40px, var(--hub-c1) 40px 80px, var(--hub-c2) 80px 120px, var(--hub-c3) 120px 160px);
    animation: hub-rule-march .8s linear infinite; }
.hub-busy-note { position: fixed; right: max(1rem, env(safe-area-inset-right, 0px)); bottom: max(1rem, env(safe-area-inset-bottom, 0px)); z-index: 60;
    display: flex; align-items: center; gap: .6rem; padding: .55rem .9rem .55rem .65rem; border-radius: 999px; font-size: .875rem;
    background: var(--zak-paper, #FFFFFF); color: var(--zak-ink, #141414); border: 1px solid var(--zak-line, #EBE5DC);
    box-shadow: 0 6px 24px rgba(20, 20, 20, .10); opacity: 0; transform: translateY(8px); transition: opacity .2s, transform .2s; pointer-events: none; }
.hub-busy-note.on { opacity: 1; transform: none; }
.hub-busy-note .hub-mark { width: 1.4rem; height: 1.4rem; }

/* Celebration: the sign blooms, pieces of the arcs burst out and fall, and a short line says what happened. */
.hub-party { position: fixed; inset: 0; z-index: 80; display: grid; place-items: center; pointer-events: none; }
.hub-party-card { pointer-events: auto; display: flex; flex-direction: column; align-items: center; gap: .6rem; padding: 1.6rem 2rem 1.4rem; min-width: 18rem; max-width: min(28rem, calc(100vw - 2rem));
    border-radius: 1rem; background: var(--zak-paper, #FFFFFF); color: var(--zak-ink, #141414); border: 1px solid var(--zak-line, #EBE5DC);
    box-shadow: 0 24px 80px rgba(20, 20, 20, .18); text-align: center; animation: hub-card-in .45s cubic-bezier(.2, .9, .25, 1.15) both; }
.hub-party-card.out { animation: hub-card-out .35s ease-in both; }
@keyframes hub-card-in { from { opacity: 0; transform: translateY(16px) scale(.96); } to { opacity: 1; transform: none; } }
@keyframes hub-card-out { to { opacity: 0; transform: translateY(-10px) scale(.98); } }
.hub-party-card .hub-mark { width: 5.5rem; height: 5.5rem; }
.hub-party-eyebrow { font-size: .72rem; font-weight: 500; letter-spacing: .08em; text-transform: uppercase; color: var(--zak-stone, #8A8378); }
.hub-party-title { font-size: 1.5rem; font-weight: 700; letter-spacing: -.01em; line-height: 1.2; }
.hub-party-line { font-size: .95rem; color: var(--zak-graphite, #3A3630); }
.hub-party-rule { width: 6rem; height: 3px; border-radius: 2px; background: linear-gradient(90deg, var(--hub-c0) 0 25%, var(--hub-c1) 25% 50%, var(--hub-c2) 50% 75%, var(--hub-c3) 75%); }
.hub-party-close { margin-top: .2rem; font: inherit; font-size: .8125rem; color: var(--zak-stone, #8A8378); background: none; border: 0; cursor: pointer; padding: .4rem .8rem; }
.hub-party-close:hover { color: var(--zak-ink, #141414); }
.hub-bit { position: fixed; left: var(--x); top: var(--y); width: var(--w); height: var(--h); border-radius: 2px; background: var(--col);
    animation: hub-fly var(--t) cubic-bezier(.15, .7, .3, 1) forwards; will-change: transform, opacity; }
.hub-bit.arc { border-radius: var(--w) 0 0 0; }
@keyframes hub-fly {
    0% { transform: translate(0, 0) rotate(0deg) scale(.6); opacity: 1; }
    70% { opacity: 1; }
    100% { transform: translate(var(--dx), var(--dy)) rotate(var(--rot)) scale(1); opacity: 0; }
}

/* A smaller moment (a payment received): the sign blooms in a toast-sized chip, no burst. */
.hub-chip { position: fixed; left: 50%; bottom: max(1.5rem, env(safe-area-inset-bottom, 0px)); transform: translateX(-50%); z-index: 80;
    display: flex; align-items: center; gap: .7rem; padding: .6rem 1.1rem .6rem .7rem; border-radius: 999px;
    background: var(--zak-paper, #FFFFFF); color: var(--zak-ink, #141414); border: 1px solid var(--zak-line, #EBE5DC); box-shadow: 0 10px 36px rgba(20, 20, 20, .14);
    animation: hub-card-in .4s cubic-bezier(.2, .9, .25, 1.15) both; font-size: .9rem; }
.hub-chip.out { animation: hub-card-out .3s ease-in both; }
.hub-chip .hub-mark { width: 1.9rem; height: 1.9rem; }
.hub-chip strong { font-weight: 500; }

@media (prefers-reduced-motion: reduce) {
    .hub-spin .hub-seg, .hub-wait .hub-seg, .hub-wait .hub-dot, .hub-bloom .hub-seg, .hub-bloom .hub-dot,
    .hub-busy .fi-topbar::after, .hub-loader-steps li.now::before { animation: none !important; }
    .hub-spin .hub-seg { opacity: .9; }
    .hub-party-card, .hub-chip, .hub-busy-note { animation: none !important; transition: none !important; }
    .hub-bit { display: none; }
}
@media print { .hub-party, .hub-chip, .hub-busy-note { display: none !important; } }
