/* ClashWise loading states (owned; replaces the cinematic boot splash and the
   "One moment" authorizing screen).

   One vocabulary, from the spatial design system's loading spec:
   - .cw-loader__track    indeterminate activity track (never a fake percentage)
   - .cw-loader__spinner  small inline spinner for compact spots
   - .cw-loader__rows     skeleton rows that reserve the content's footprint
   - .cw-shell-skel       the app frame before Blazor starts (index.html boot)
   - .cw-page-skel        the page area while a route or page is loading

   Loaded render-blocking in <head> so the boot markup is styled on first paint, before
   the spatial token sheet or any framework CSS. Colours therefore carry the spatial
   night values as fallbacks. Skeleton shapes are aria-hidden; each loader exposes one
   role="status" label instead. */

.cw-loader,
.cw-shell-skel,
.cw-page-skel {
    --cwl-canvas: var(--cw-surface-canvas, #141c30);
    --cwl-panel: var(--cw-surface-panel, #1c273e);
    --cwl-raised: var(--cw-surface-raised, #25324b);
    --cwl-line: var(--cw-border-subtle, #34405a);
    --cwl-accent: var(--cw-text-link, #91a6ff);
}

.cw-loader__label {
    position: absolute !important;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* ── indeterminate track ── */
.cw-loader__track {
    display: block;
    height: 3px;
    border-radius: 3px;
    overflow: hidden;
    background: var(--cwl-raised);
}
.cw-loader__track::before {
    content: "";
    display: block;
    width: 32%;
    height: 100%;
    border-radius: inherit;
    background: var(--cwl-accent);
    animation: cw-loader-sweep 1.4s cubic-bezier(0.45, 0, 0.35, 1) infinite;
}
@keyframes cw-loader-sweep {
    from { transform: translateX(-100%); }
    to { transform: translateX(320%); }
}

/* ── spinner ── */
.cw-loader__spinner {
    display: inline-block;
    flex: none;
    width: 18px;
    height: 18px;
    border: 2px solid var(--cwl-line);
    border-top-color: var(--cwl-accent);
    border-right-color: var(--cwl-accent);
    border-radius: 50%;
    animation: cw-loader-turn 0.9s linear infinite;
}
@keyframes cw-loader-turn { to { transform: rotate(360deg); } }

/* ── skeleton shapes ── */
.cw-loader__bone {
    display: block;
    border-radius: 6px;
    background: linear-gradient(100deg, var(--cwl-raised) 30%, color-mix(in srgb, var(--cwl-raised) 55%, var(--cwl-line)) 50%, var(--cwl-raised) 70%);
    background-size: 220% 100%;
    animation: cw-loader-shimmer 1.8s ease-in-out infinite;
}
@keyframes cw-loader-shimmer {
    from { background-position: 100% 0; }
    to { background-position: -100% 0; }
}

.cw-loader__rows { display: grid; }
.cw-loader__row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 16px;
    border-top: 1px solid var(--cwl-line);
}
.cw-loader__row:first-child { border-top: 0; }
.cw-loader__row .cw-loader__bone:nth-child(1) { width: 40px; height: 14px; flex: none; }
.cw-loader__row .cw-loader__bone:nth-child(2) { flex: 1 1 auto; max-width: 46%; height: 12px; }
.cw-loader__row .cw-loader__bone:nth-child(3) { width: 14%; height: 12px; margin-left: auto; }
.cw-loader__row .cw-loader__bone:nth-child(4) { width: 10%; height: 12px; }
.cw-loader__row:nth-child(3n + 2) .cw-loader__bone:nth-child(2) { max-width: 34%; }
.cw-loader__row:nth-child(3n + 3) .cw-loader__bone:nth-child(2) { max-width: 52%; }

/* ── page area skeleton (route authorizing, in-page first loads) ── */
.cw-page-skel {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 16px;
    min-height: calc(100vh - var(--cw-shell-topbar-height, 0px) - var(--cw-envbar-height, 0px));
    min-height: calc(100dvh - var(--cw-shell-topbar-height, 0px) - var(--cw-envbar-height, 0px));
    padding: 24px;
    background: var(--cwl-canvas);
}
.cw-page-skel--inset { min-height: 0; padding: 0; background: transparent; flex: 1 1 auto; }
.cw-page-skel__panel {
    border: 1px solid var(--cwl-line);
    border-radius: 12px;
    background: var(--cwl-panel);
    overflow: hidden;
}
.cw-page-skel__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    padding: 20px 24px;
}
.cw-page-skel__head .cw-loader__bone:nth-child(1) { width: min(320px, 60%); height: 22px; }
.cw-page-skel__head .cw-loader__bone:nth-child(2) { width: 120px; height: 34px; margin-left: auto; border-radius: 8px; }
.cw-page-skel__head .cw-loader__bone:nth-child(3) { width: 96px; height: 34px; border-radius: 8px; }
.cw-page-skel__bar { padding: 0 24px 18px; }
.cw-page-skel__bar .cw-loader__bone { width: 100%; height: 40px; border-radius: 8px; }
.cw-page-skel__list { flex: 1 1 auto; }
.cw-page-skel > .cw-loader__track {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2000;
    border-radius: 0;
}

/* In-page loaders sit under the navigation and environment banner stacking layers.
   Paint their track from the app root so it remains visible across the viewport. */
.cw-page-skel--inset > .cw-loader__track { visibility: hidden; }
#app:has(.cw-page-skel--inset) {
    --cwl-page-track: #25324b;
    --cwl-page-accent: #91a6ff;
}
#app:has([data-cw-system][data-theme="day"] .cw-page-skel--inset) {
    --cwl-page-track: #e6ebf4;
    --cwl-page-accent: #355cff;
}
#app:has(.cw-page-skel--inset)::before,
#app:has(.cw-page-skel--inset)::after {
    content: "";
    position: fixed;
    top: 0;
    height: 3px;
    pointer-events: none;
}
#app:has(.cw-page-skel--inset)::before {
    left: 0;
    right: 0;
    z-index: 20000;
    background: var(--cwl-page-track);
}
#app:has(.cw-page-skel--inset)::after {
    left: 0;
    width: 32%;
    z-index: 20001;
    background: var(--cwl-page-accent);
    animation: cw-loader-sweep 1.4s cubic-bezier(0.45, 0, 0.35, 1) infinite;
}

/* ── boot shell (index.html, before Blazor) ── */
.cw-shell-skel {
    position: fixed;
    inset: 0;
    z-index: 1;
    display: flex;
    background: var(--cwl-canvas);
    color: var(--cw-text-primary, #eef0f8);
}
.cw-shell-skel__rail {
    display: none;
    flex: none;
    flex-direction: column;
    align-items: center;
    gap: 18px;
    width: 64px;
    padding: 16px 0;
    border-right: 1px solid var(--cwl-line);
    background: var(--cwl-canvas);
}
.cw-shell-skel__mark { width: 32px; height: 32px; border-radius: 7px; opacity: 0.9; }
.cw-shell-skel__rail .cw-loader__bone { width: 22px; height: 22px; border-radius: 6px; }
.cw-shell-skel__rail .cw-loader__bone:first-of-type { margin-top: 18px; }
.cw-shell-skel__main { position: relative; flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.cw-shell-skel__main .cw-page-skel { flex: 1 1 auto; min-height: 0; }
.cw-shell-skel__main .cw-page-skel__panel:last-child { flex: 1 1 auto; }

/* App routes show the navigation rail (mirrors MainLayout.ShowDrawer via boot-shell.js);
   the saved "expanded" drawer preference widens it like the real drawer. */
.cw-shell-skel.is-app .cw-shell-skel__rail { display: flex; }
html.cw-nav-expanded .cw-shell-skel.is-app .cw-shell-skel__rail { width: 240px; align-items: flex-start; padding-left: 20px; }
html.cw-nav-expanded .cw-shell-skel.is-app .cw-shell-skel__rail .cw-loader__bone { width: 150px; height: 14px; }

/* Public routes (marketing, auth, shares) never flash an app frame: just the track. */
.cw-shell-skel:not(.is-app) .cw-page-skel__panel { display: none; }
.cw-shell-skel:not(.is-app) .cw-page-skel { background: transparent; }

@media (max-width: 767.98px) {
    /* Phones use the temporary drawer (a floating button), never a rail. */
    .cw-shell-skel.is-app .cw-shell-skel__rail { display: none; }
    .cw-page-skel { padding: 12px; gap: 12px; }
    .cw-page-skel__head { padding: 16px; }
    .cw-page-skel__head .cw-loader__bone:nth-child(3) { display: none; }
    .cw-page-skel__bar { padding: 0 16px 14px; }
    .cw-loader__row .cw-loader__bone:nth-child(4) { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .cw-loader__track::before { animation: none; width: 100%; opacity: 0.55; }
    #app:has(.cw-page-skel--inset)::after { animation: none; width: 100%; opacity: 0.55; }
    .cw-loader__spinner { animation-duration: 2.4s; }
    .cw-loader__bone { animation: none; }
}

/* ── inline spinner with a visible label ── */
.cw-loader--spinner {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    color: var(--cw-text-secondary, #a0acc1);
    font-size: 13px;
}
