@props([
    // [[route, icon, translation key], …] or [['label' => …, 'items' => [...]], …]
    'groups',
    // dot-prefix for the labels, e.g. 'dashboard.nav' or 'admin.nav'
    'prefix',
    // console routes are matched through AdminArea so recovery hostnames still
    // highlight; the portal uses the router directly
    'console' => false,
    'footer' => null,
])
{{--
    The sidebar, shared by both shells.

    Light, like everything else. The console used to be dark, which made it a
    second product: two ideas of what a card is, two oranges, two status
    palettes. What actually differs between an operator and a customer is
    density, and that lives in the tokens — not here.
--}}
<aside
    class="fixed inset-y-0 left-0 z-50 flex w-[15.5rem] flex-col border-r border-line bg-surface px-3 py-4 shadow-md transition-transform lg:static lg:h-screen lg:translate-x-0 lg:shadow-none"
    :class="nav ? 'translate-x-0' : '-translate-x-full'"
>
    <div class="flex shrink-0 items-center justify-between gap-2 px-2.5 pb-5">
        <a href="{{ $console ? \App\Support\AdminArea::home() : route('dashboard') }}" class="flex items-center gap-2.5">
            <x-ui.brand size="md" />
            @if ($console)
                <span class="rounded-sm bg-accent-subtle px-1.5 py-0.5 font-mono text-[9.5px] font-semibold uppercase tracking-[0.1em] text-accent-text">{{ __('admin.badge') }}</span>
            @endif
        </a>
        <button type="button" class="lg:hidden -mr-1 inline-flex min-h-11 min-w-11 items-center justify-center rounded text-muted"
                @click="nav = false" aria-label="{{ __('dashboard.close_nav') }}">
            <x-ui.icon name="x" />
        </button>
    </div>

    {{-- The only scroll region in the sidebar: header above and footer below
         stay put (operator requirement), only the nav list itself scrolls
         when it is taller than the viewport. overflow-y-auto (not -hidden)
         on a flex-1 child resolves its automatic min-height to 0, which is
         what lets it shrink to the available space instead of stretching the
         aside past the viewport — same mechanism <main> already relies on. --}}
    <div class="min-h-0 flex-1 overflow-y-auto">
        @foreach ($groups as $group)
            @if (! empty($group['label']))
                <p class="px-3 pb-2 pt-5 lbl">{{ $group['label'] }}</p>
            @endif
            <nav class="space-y-0.5">
                @foreach ($group['items'] as [$route, $icon, $key, $capability])
                    {{-- $capability is a single ability name, an array of
                         ability names meaning "any of these" (App\Support\
                         Navigation documents which entries use that), or
                         null for "everyone". Laravel's own can() treats an
                         array as "all of these", which is the wrong logic
                         for an entry reachable with either of two
                         capabilities — hence the explicit branch instead of
                         a bare ->can($capability) for both shapes. --}}
                    @continue($capability !== null && ! (is_array($capability)
                        ? collect($capability)->contains(fn ($one) => auth()->user()?->can($one))
                        : auth()->user()?->can($capability)))
                    <x-ui.nav-item
                        :href="route($route)"
                        :active="$console ? \App\Support\AdminArea::routeIs($route) : request()->routeIs($route)"
                        @click="nav = false"
                    >
                        <x-slot:icon><x-ui.icon :name="$icon" class="size-[1.15rem]" /></x-slot:icon>
                        {{ __($prefix.'.'.$key) }}
                    </x-ui.nav-item>
                @endforeach
            </nav>
        @endforeach
    </div>

    @if ($footer)
        <p class="shrink-0 px-3 pt-6 font-mono text-[11px] leading-relaxed text-muted">{{ $footer }}</p>
    @endif
</aside>

{{-- Backdrop. Tapping it closes the drawer, which is the behaviour every
     phone user tries first. --}}
<div x-show="nav" x-cloak @click="nav = false" class="fixed inset-0 z-40 bg-[color-mix(in_srgb,var(--plate)_42%,transparent)] lg:hidden"></div>
