/* shadcn-inspired design tokens. UnoCSS theme.colors map utility class names
   (bg-background, text-foreground, border-border, ...) to these HSL variables. */

:root {
    --background: 0 0% 100%;
    --foreground: 240 10% 3.9%;
    --card: 0 0% 100%;
    --muted: 240 4.8% 95.9%;
    --muted-foreground: 240 3.8% 46.1%;
    --border: 240 5.9% 90%;
    --primary: 221 83% 53%;
    --primary-foreground: 0 0% 100%;
    --ring: 221 83% 53%;
    --radius: 0.5rem;
}

.dark {
    --background: 240 10% 3.9%;
    --foreground: 0 0% 98%;
    --card: 240 10% 5.5%;
    --muted: 240 3.7% 15.9%;
    --muted-foreground: 240 5% 64.9%;
    --border: 240 3.7% 15.9%;
    --primary: 217 91% 60%;
    --primary-foreground: 0 0% 100%;
    --ring: 217 91% 60%;
}

html,
body {
    margin: 0;
    padding: 0;
    font-family: "Inter", "Segoe UI", ui-sans-serif, system-ui, sans-serif;
    background-color: hsl(var(--background));
    color: hsl(var(--foreground));
    -webkit-font-smoothing: antialiased;
}

* {
    box-sizing: border-box;
}

a {
    color: inherit;
    text-decoration: none;
}

/* FocusOnNavigate programmatically focuses the page <h1> on each navigation
   for screen-reader accessibility. Suppress only the visual focus ring on
   non-interactive heading elements — keyboard focus rings on buttons,
   links, and inputs are preserved. */
h1:focus,
h2:focus,
h3:focus,
h4:focus,
h5:focus,
h6:focus,
h1:focus-visible,
h2:focus-visible,
h3:focus-visible,
h4:focus-visible,
h5:focus-visible,
h6:focus-visible {
    outline: none;
}

/* Critical layout CSS — guarantees the admin shell renders with correct
   dimensions on first paint, before the UnoCSS runtime has generated any
   utility classes. */

.app-shell {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background-color: hsl(var(--background));
    color: hsl(var(--foreground));
}

.app-header {
    height: 3.5rem;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 1rem;
    padding: 0 1rem;
    border-bottom: 1px solid hsl(var(--border));
    background-color: hsl(var(--background));
    color: hsl(var(--foreground));
    position: sticky;
    top: 0;
    z-index: 30;
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 400;
    font-size: 1.125rem;
    letter-spacing: -0.01em;
    color: hsl(var(--foreground) / 0.75);
    text-decoration: none;
}

.brand:hover,
.brand:visited {
    color: hsl(var(--foreground) / 0.75);
    text-decoration: none;
}

.brand__mark {
    display: inline-block;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 0.375rem;
    background-color: hsl(var(--primary));
}

.header-search {
    width: 18rem;
    max-width: 100%;
    justify-self: center;
}

.app-body {
    display: flex;
    flex: 1;
    min-height: 0;
}

.app-sidebar {
    width: 16rem;
    flex-shrink: 0;
    border-right: 1px solid hsl(var(--border));
    background-color: hsl(var(--background));
    overflow: hidden;
    transition: width 200ms ease-out;
}

.app-sidebar--collapsed {
    width: 3.75rem;
}

/* Pre-paint collapsed state set by the inline script in App.razor, applied
   before Blazor hydrates. Removed automatically once AdminLayout takes over
   and the .app-sidebar--collapsed class on <aside> drives the width. */
html.sidebar-collapsed .app-sidebar {
    width: 3.75rem;
}

html.sidebar-collapsed .app-sidebar .nav-item__label {
    display: none;
}

/* Keep the nav block at the expanded width regardless of the sidebar's
   outer width. Combined with `overflow: hidden` on .app-sidebar, this
   pins every nav item — and its icon — at a fixed horizontal position
   during the open/close animation, so icons never shift sideways. */
.app-sidebar > nav {
    width: 16rem;
}

.app-main {
    flex: 1;
    overflow: auto;
    background-color: hsl(var(--muted) / 0.4);
    color: hsl(var(--foreground));
}

/* Sidebar nav item — fixed height + nowrap so animating sidebar width never
   reflows or shifts the items vertically. */
.nav-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    height: 2.5rem;
    padding: 0 0.75rem;
    border-radius: calc(var(--radius) - 2px);
    font-size: 0.875rem;
    font-weight: 500;
    color: hsl(var(--muted-foreground));
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    transition: background-color 120ms ease-out, color 120ms ease-out;
}

.nav-item:visited {
    color: hsl(var(--muted-foreground));
    text-decoration: none;
}

.nav-item:hover {
    background-color: hsl(var(--muted));
    color: hsl(var(--foreground));
    text-decoration: none;
}

.nav-item__icon {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    height: 1.25rem;
}

.nav-item__label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nav-link.active.nav-item,
.nav-item.nav-item-active {
    background-color: hsl(var(--foreground) / 0.08);
    color: hsl(var(--foreground));
    font-weight: 600;
}

.nav-link.active.nav-item:hover,
.nav-item.nav-item-active:hover {
    background-color: hsl(var(--foreground) / 0.12);
    color: hsl(var(--foreground));
}

/* When the sidebar is collapsed, hide labels entirely so only the icon
   column shows. Labels reappear instantly when the sidebar starts to
   expand, so the text is fully present during the width animation. */
.app-sidebar--collapsed .nav-item__label {
    display: none;
}

.card {
    background-color: hsl(var(--card));
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius);
}

/* Pre-hydration loader shown inside #app until blazor.webassembly.js mounts
   the App component. Uses the same HSL design tokens so it respects the
   pre-paint .dark class set by the inline theme script in index.html. */
.app-loading {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    background-color: hsl(var(--background));
    color: hsl(var(--foreground));
}

.app-loading-spinner {
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 50%;
    border: 3px solid hsl(var(--muted));
    border-top-color: hsl(var(--primary));
    animation: app-loading-spin 0.8s linear infinite;
}

.app-loading-text {
    margin: 0;
    font-size: 0.875rem;
    color: hsl(var(--muted-foreground));
}

@keyframes app-loading-spin {
    to { transform: rotate(360deg); }
}

/* Default-hidden Blazor error UI. blazor.webassembly.js flips display to
   block on an unhandled error and wires the .reload / .dismiss children. */
#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

