clusev/resources/views/livewire/onboarding/tour.blade.php

71 lines
4.8 KiB
PHP

<div x-data="onboardingTour(@js($steps), @js($autostart))">
{{-- The whole overlay only exists while the tour is open. --}}
<div x-show="open" x-cloak class="fixed inset-0 z-[80]" role="dialog" aria-modal="true" aria-label="{{ __('onboarding.aria') }}">
{{-- Click-catcher: blocks the app underneath (no accidental skip dismissal is explicit). --}}
<div class="absolute inset-0"></div>
{{-- Centred steps (welcome / finish, or when the target isn't visible) get a full dim + blur. --}}
<div x-show="! rect" x-transition.opacity class="absolute inset-0 bg-void/80 backdrop-blur-sm"></div>
{{-- Spotlight: a transparent box whose huge box-shadow dims everything around the target. --}}
<div x-show="rect" x-cloak :style="spotStyle()"
class="pointer-events-none absolute rounded-lg ring-2 ring-accent/70 shadow-[0_0_0_9999px_color-mix(in_srgb,var(--color-void)_84%,transparent)] transition-all duration-300 ease-out"></div>
{{-- The description card. --}}
<div x-cloak
:class="rect ? '' : 'left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2'"
:style="rect ? cardStyle() : ''"
class="pointer-events-auto absolute w-[min(92vw,380px)] overflow-hidden rounded-xl border border-line bg-surface shadow-panel"
x-transition:enter="transition ease-out duration-300" x-transition:enter-start="opacity-0 translate-y-1" x-transition:enter-end="opacity-100 translate-y-0">
{{-- Accent hairline top edge. --}}
<div class="h-0.5 w-full bg-gradient-to-r from-accent via-accent/40 to-transparent"></div>
<div class="p-5">
<button type="button" @click="skip()" aria-label="{{ __('onboarding.skip') }}"
class="absolute right-3 top-3 grid h-7 w-7 place-items-center rounded-md text-ink-4 transition-colors hover:bg-raised hover:text-ink-2">
<x-icon name="x" class="h-3.5 w-3.5" />
</button>
<div class="flex items-start gap-3">
<span class="grid h-10 w-10 shrink-0 place-items-center rounded-lg border border-accent/25 bg-accent/10 text-accent shadow-[0_0_18px_-4px_var(--color-accent)]">
<x-icon name="command" class="h-4 w-4" x-show="step.icon==='command'" />
<x-icon name="dashboard" class="h-4 w-4" x-show="step.icon==='dashboard'" x-cloak />
<x-icon name="server" class="h-4 w-4" x-show="step.icon==='server'" x-cloak />
<x-icon name="terminal" class="h-4 w-4" x-show="step.icon==='terminal'" x-cloak />
<x-icon name="settings" class="h-4 w-4" x-show="step.icon==='settings'" x-cloak />
<x-icon name="shield" class="h-4 w-4" x-show="step.icon==='shield'" x-cloak />
</span>
<div class="min-w-0 flex-1 pr-6">
<p class="font-mono text-[10px] uppercase tracking-[0.2em] text-accent-text">
<span x-text="'0' + (i + 1)"></span><span class="text-ink-4"> / 0<span x-text="steps.length"></span></span>
<span class="text-ink-4"> · </span><span x-text="step.eyebrow"></span>
</p>
<h2 class="mt-1 font-display text-lg font-semibold leading-tight text-ink" x-text="step.title"></h2>
</div>
</div>
<p class="mt-3 text-sm leading-relaxed text-ink-2" x-text="step.body"></p>
{{-- Progress bar. --}}
<div class="mt-4 h-1 w-full overflow-hidden rounded-full bg-inset">
<div class="h-full rounded-full bg-accent transition-all duration-300" :style="'width:' + Math.round(((i + 1) / steps.length) * 100) + '%'"></div>
</div>
<div class="mt-4 flex items-center justify-between gap-2">
<button type="button" @click="skip()" class="font-mono text-[11px] text-ink-4 transition-colors hover:text-ink-2">{{ __('onboarding.skip') }}</button>
<div class="flex items-center gap-2">
<x-btn variant="secondary" size="sm" x-show="i > 0" x-cloak @click="prev()">
<x-icon name="chevron-left" class="h-3.5 w-3.5" />{{ __('onboarding.back') }}
</x-btn>
<x-btn variant="primary" size="sm" @click="next()">
<span x-show="! isLast">{{ __('onboarding.next') }}</span>
<span x-show="isLast" x-cloak>{{ __('onboarding.done') }}</span>
<x-icon name="chevron-right" class="h-3.5 w-3.5" x-show="! isLast" />
</x-btn>
</div>
</div>
</div>
</div>
</div>
</div>