:root {
    --color-bg-gradient: linear-gradient(90deg, rgba(7, 0, 31, 1) 0%, rgba(22, 0, 28, 1) 35%, rgba(43, 1, 35, 1) 100%);
    --color-aubergine: #4B1248;
    --color-purple: #7C3AED;
    --color-turquoise: #2DD4BF;
    --color-light-purple: #C084FC;
    --color-text: #E5E1F0;
}

body {
    background: var(--color-bg-gradient);
    color: var(--color-text);
    margin: 0;
}
html {
    scroll-behavior: smooth;
}

/* The coverflow positions its side cards with translateX, which pushes them
   past the viewport edge on narrow screens and creates a horizontal scroll
   region full of empty page.

   "clip" rather than "hidden" matters: overflow: hidden turns the element
   into a scroll container, which breaks position: sticky and scroll-margin
   anchor offsets. overflow: clip simply stops the overflow being reachable
   and leaves scrolling behaviour alone. */
html,
body {
    overflow-x: clip;
    max-width: 100%;
}

.galaxy-canvas {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    z-index: -1;
    pointer-events: none;
}

/* Standard "skip link" pattern: invisible until a keyboard user tabs to
   it, at which point it becomes visible so they can jump straight past
   the nav to the main content instead of tabbing through every link
   on every single page visit. */
.skip-link {
    position: absolute;
    top: -100px;
    left: 1rem;
    background: var(--color-turquoise);
    color: #07001F;
    padding: 0.5rem 1rem;
    border-radius: 0 0 6px 6px;
    z-index: 1000;
    text-decoration: none;
    font-weight: 600;
}

.skip-link:focus {
    top: 0;
}

/* A visible focus outline for keyboard users on any interactive element
   that doesn't already define its own - dark themes very easily end up
   accidentally invisible-on-focus if this isn't set explicitly. */
a:focus-visible,
button:focus-visible {
    outline: 2px solid var(--color-turquoise);
    outline-offset: 2px;
}

/* Basic responsive breathing room: less padding on small screens so
   content isn't fighting the edges of the viewport. */
@media (max-width: 600px) {
    .content {
        padding: 0.75rem 1rem;
    }
}

html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

h1:focus {
    outline: none;
}

a, .btn-link {
    color: #0071c1;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    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;
    }

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

/* Full-screen loading state. A WebAssembly app has a real download before
   anything can render, so this screen is visible far longer than a typical
   site's flash of blank page - it is the genuine first impression and worth
   treating as part of the design rather than as template debris. */
.app-loader {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.5rem;
    background: var(--color-bg-gradient);
}

.app-loader-ring {
    position: relative;
    width: 7.5rem;
    height: 7.5rem;
}

.loading-progress {
    display: block;
    width: 100%;
    height: 100%;
}

    .loading-progress circle {
        fill: none;
        /* The faint full circle behind the progress arc - it shows how far
           there is left to go, which a lone arc cannot. */
        stroke: rgba(192, 132, 252, 0.15);
        stroke-width: 3px;
        transform-origin: 50% 50%;
        transform: rotate(-90deg);
    }

        .loading-progress circle:last-child {
            /* Referencing an SVG gradient by id, so the arc runs turquoise to
               purple rather than a flat colour. */
            stroke: url(#loaderGradient);
            stroke-linecap: round;
            stroke-width: 4px;
            /* Blazor sets --blazor-load-percentage as the runtime downloads.
               The 3.141 is pi: circumference = pi x diameter, and the radius
               is 40% of the box, so this converts a percentage into the arc
               length to draw. */
            stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
            transition: stroke-dasharray 0.15s ease-in-out;
        }

.loading-progress-text {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--color-turquoise);
    font-variant-numeric: tabular-nums;
}

    .loading-progress-text:after {
        content: var(--blazor-load-percentage-text, "Loading");
    }

.app-loader-name {
    margin: 0;
    font-size: 1.35rem;
    font-weight: 800;
    background: linear-gradient(90deg, var(--color-light-purple), var(--color-turquoise));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.app-loader-sub {
    margin: -0.9rem 0 0;
    font-size: 0.78rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: rgba(229, 225, 240, 0.45);
}

code {
    color: #c02d76;
}
