/* /Components/HolyTable.razor.rz.scp.css */
/* ══════════════════════════════════════════════════════════════════
   Holy Table — line art for the portal backdrop.

   Everything is drawn in strokes only, at low opacity, so it reads as
   an engraving glimpsed behind the content rather than as an image
   competing with it. Stroke widths are in viewBox units and so scale
   with the drawing; vector-effect is deliberately NOT used, because
   hairlines that stay 1px at every size look like UI chrome, not like
   a plate.
   ══════════════════════════════════════════════════════════════════ */

.holy-table[b-a07brfn13f] {
    position: absolute;
    top: 50%;
    left: 50%;
    /* The figure is square and must not be cropped, or the border band stops
       reading as a border. Sizing by width with a max-height lets the aspect
       ratio drive whichever dimension is scarcer — full-height on the login
       page, full-width in the short home hero. */
    width: var(--ht-size, 94%);
    max-height: var(--ht-size, 94%);
    aspect-ratio: 1;
    transform: translate(-50%, -50%);
    overflow: visible;
    opacity: var(--ht-opacity, 0.34);
    color: var(--lp-accent, #2ae6c8);
    animation: ht-breathe-b-a07brfn13f 24s ease-in-out infinite alternate;
}

.holy-table :is(rect, line, polygon, circle)[b-a07brfn13f] {
    fill: none;
    stroke: currentColor;
    stroke-linejoin: round;
}

.ht-border rect[b-a07brfn13f] {
    stroke-width: 2.4;
}

.ht-border line[b-a07brfn13f] {
    stroke-width: 1.6;
    opacity: 0.85;
}

/* The hexagram is the figure's spine, so it carries the second colour and
   a little more weight than the ruling around it. */
.ht-hexagram polygon[b-a07brfn13f] {
    stroke: var(--lp-accent2, #8d4bff);
    stroke-width: 2.6;
    opacity: 1;
}

.ht-ensigns :is(rect, circle)[b-a07brfn13f] {
    stroke-width: 1.8;
}

.ht-ruling line[b-a07brfn13f] {
    stroke-width: 1;
    opacity: 0.55;
}

.ht-centre rect[b-a07brfn13f] {
    stroke-width: 2.6;
}

.ht-centre line[b-a07brfn13f] {
    stroke-width: 1.6;
}

/* The glyph <text> elements come from a MarkupString (see HolyTable.razor), and
   Blazor only stamps its scope attribute onto compile-time markup — so a plain
   `.ht-glyph` rule would be rewritten to `.ht-glyph[b-xxx]` and never match.
   ::deep moves the attribute onto the preceding selector instead. */
.ht-centre[b-a07brfn13f]  .ht-glyph {
    font-family: 'GDEnochian', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    font-size: 46px;
    fill: currentColor;
    stroke: none;
    text-anchor: middle;
    dominant-baseline: central;
    opacity: 0.9;
}

@keyframes ht-breathe-b-a07brfn13f {
    from { opacity: calc(var(--ht-opacity, 0.34) * 0.72); }
    to   { opacity: var(--ht-opacity, 0.34); }
}

@media (prefers-reduced-motion: reduce) {
    .holy-table[b-a07brfn13f] {
        animation: none;
    }
}
/* /Components/Layout/LoginLayout.razor.rz.scp.css */
/* ── Login Layout Root ────────────────────────────────────────────── */
.login-layout-root[b-v6lk6huz6q] {
    margin: 0;
    padding: 0;
    width: 100vw;
    min-height: 100vh;
    overflow: hidden;
}
/* /Components/Layout/MainLayout.razor.rz.scp.css */
.page[b-30t8ueter8] {
    position: relative;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    background: var(--page-bg);
    color: var(--page-text);
}

main[b-30t8ueter8] {
    flex: 1;
    /* `flex: 1` leaves min-width at `auto`, so in the ≥641px row layout main
       refuses to shrink below its content's min-content width. Measured at
       768px: main demanded 568px of the 524px beside the nav, pushing the
       document to 797px and squeezing the nav from its intended 250px down to
       229px. Opening the Watch Towers names sidebar made it far worse (1037px).
       min-width: 0 lets main take the width actually available; the inner
       scroll containers (.wt-page, .wt-table-viewport) then handle any content
       that is still too wide, which is what they were built for. */
    min-width: 0;
}

.sidebar[b-30t8ueter8] {
    background: var(--sidebar-bg);
}

.top-row[b-30t8ueter8] {
    background: var(--top-row-bg);
    border-bottom: 1px solid var(--top-row-border);
    justify-content: flex-end;
    height: 3.5rem;
    display: flex;
    align-items: center;
    color: var(--top-row-text);
}

    .top-row[b-30t8ueter8]  a, .top-row[b-30t8ueter8]  .btn-link {
        white-space: nowrap;
        margin-left: 1.5rem;
        text-decoration: none;
    }

    .top-row[b-30t8ueter8]  a:hover, .top-row[b-30t8ueter8]  .btn-link:hover {
        text-decoration: underline;
    }

    .top-row[b-30t8ueter8]  a:first-child {
        overflow: hidden;
        text-overflow: ellipsis;
    }

@media (max-width: 640.98px) {
    .top-row[b-30t8ueter8] {
        justify-content: space-between;
    }

    .top-row[b-30t8ueter8]  a, .top-row[b-30t8ueter8]  .btn-link {
        margin-left: 0;
    }
}

@media (min-width: 641px) {
    .page[b-30t8ueter8] {
        flex-direction: row;
    }

    .sidebar[b-30t8ueter8] {
        width: 250px;
        height: 100vh;
        position: sticky;
        top: 0;
    }

    .top-row[b-30t8ueter8] {
        position: sticky;
        top: 0;
        z-index: 1;
    }

    .top-row.auth[b-30t8ueter8]  a:first-child {
        flex: 1;
        text-align: right;
        width: 0;
    }

    .top-row[b-30t8ueter8], article[b-30t8ueter8] {
        padding-left: 2rem !important;
        padding-right: 1.5rem !important;
    }
}

#blazor-error-ui[b-30t8ueter8] {
    color-scheme: normal;
    background: var(--error-bg);
    color: var(--error-text);
    bottom: 0;
    box-shadow: 0 -1px 2px var(--error-border);
    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[b-30t8ueter8] {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }
/* /Components/Layout/NavMenu.razor.rz.scp.css */
.navbar-toggler[b-7s4y1rr017] {
    appearance: none;
    cursor: pointer;
    width: 3.5rem;
    height: 2.5rem;
    color: var(--sidebar-link);
    position: absolute;
    top: 0.5rem;
    right: 1rem;
    border: 1px solid var(--surface-border);
    background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.72%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem color-mix(in srgb, var(--sidebar-link) 12%, transparent);
}

.navbar-toggler:checked[b-7s4y1rr017] {
    background-color: color-mix(in srgb, var(--sidebar-link) 18%, transparent);
}

.top-row[b-7s4y1rr017] {
    min-height: 3.5rem;
    background-color: rgba(0, 0, 0, 0.18);
    color: var(--sidebar-link);
}

.navbar-brand[b-7s4y1rr017] {
    /* Bootstrap's .navbar-brand carries its own colour (--bs-navbar-brand-color,
       which resolves to white), and it beat the inherited --sidebar-link. That
       was invisible on the light theme's pale sidebar. */
    color: var(--sidebar-link);
    font-size: 1.1rem;
    font-family: 'GDEnochian', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    letter-spacing: 0.06em;
}

/* ── Nav icons ───────────────────────────────────────────────
   Icons are rendered as CSS masks over a solid colour, so every
   glyph inherits the active theme (or its plugin accent) instead
   of being baked to white. */
.bi[b-7s4y1rr017] {
    display: inline-block;
    position: relative;
    flex: 0 0 auto;
    width: 1.4rem;
    height: 1.4rem;
    margin-right: 0.7rem;
    top: -1px;
    background-color: var(--nav-icon-color, currentColor);
    -webkit-mask: var(--nav-icon) no-repeat center / contain;
    mask: var(--nav-icon) no-repeat center / contain;
    opacity: 0.72;
    transform: translateZ(0);
    transition: opacity 0.18s ease, transform 0.18s ease, filter 0.18s ease;
}

.nav-item[b-7s4y1rr017]  .nav-link:hover .bi {
    opacity: 1;
    transform: scale(1.1);
    filter: drop-shadow(0 0 5px color-mix(in srgb, var(--nav-icon-color, currentColor) 55%, transparent));
}

.nav-item[b-7s4y1rr017]  a.active .bi {
    opacity: 1;
    filter: drop-shadow(0 0 6px color-mix(in srgb, var(--nav-icon-color, currentColor) 65%, transparent));
}

@media (prefers-reduced-motion: reduce) {
    .bi[b-7s4y1rr017] {
        transition: none;
    }

    .nav-item[b-7s4y1rr017]  .nav-link:hover .bi {
        transform: none;
    }
}

.nav-item[b-7s4y1rr017] {
    font-size: 0.9rem;
    padding-bottom: 0.5rem;
}

    .nav-item:first-of-type[b-7s4y1rr017] {
        padding-top: 1rem;
    }

    .nav-item:last-of-type[b-7s4y1rr017] {
        padding-bottom: 1rem;
    }

    .nav-item[b-7s4y1rr017]  .nav-link {
        color: var(--sidebar-link);
        background: none;
        border: none;
        border-radius: 4px;
        height: 3rem;
        display: flex;
        align-items: center;
        line-height: 3rem;
        width: 100%;
    }

.nav-item[b-7s4y1rr017]  a.active {
    background-color: var(--sidebar-active-bg);
    color: var(--sidebar-link);
}

.nav-item[b-7s4y1rr017]  .nav-link:hover {
    background-color: var(--sidebar-hover-bg);
    color: var(--sidebar-link);
}

.nav-scrollable[b-7s4y1rr017] {
    display: none;
}

.navbar-toggler:checked ~ .nav-scrollable[b-7s4y1rr017] {
    display: block;
}

@media (min-width: 641px) {
    .navbar-toggler[b-7s4y1rr017] {
        display: none;
    }

    .nav-scrollable[b-7s4y1rr017] {
        /* Never collapse the sidebar for wide screens */
        display: block;

        /* Allow sidebar to scroll for tall menus */
        height: calc(100vh - 3.5rem);
        overflow-y: auto;
    }
}

/* ── Login display (top-row) ── */
[b-7s4y1rr017] .login-display {
    display: flex;
    align-items: center;
    gap: .65rem;
    padding: 0 .9rem;
    font-size: .8rem;
}

[b-7s4y1rr017] .login-display__name {
    opacity: .65;
    color: var(--sidebar-link, #ccc);
    max-width: 140px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

[b-7s4y1rr017] .login-display__link {
    color: var(--sidebar-link, #ccc);
    text-decoration: none;
    border: 1px solid color-mix(in srgb, currentColor 35%, transparent);
    border-radius: 5px;
    padding: .15rem .55rem;
    transition: background .18s, border-color .18s;
    white-space: nowrap;
}
[b-7s4y1rr017] .login-display__link:hover {
    background: color-mix(in srgb, var(--sidebar-link, #ccc) 15%, transparent);
    border-color: currentColor;
}

/* The `--nav-icon` glyph definitions now live in wwwroot/app.css so that both this menu and the
   Home page cards can draw them. Only the sizing/colour rule above is scoped here, because the
   two call sites want different sizes. */
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-1ycocoktfx],
.components-reconnect-repeated-attempt-visible[b-1ycocoktfx],
.components-reconnect-failed-visible[b-1ycocoktfx],
.components-pause-visible[b-1ycocoktfx],
.components-resume-failed-visible[b-1ycocoktfx],
.components-rejoining-animation[b-1ycocoktfx] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-1ycocoktfx],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-1ycocoktfx],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-1ycocoktfx],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-1ycocoktfx],
#components-reconnect-modal.components-reconnect-retrying[b-1ycocoktfx],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-1ycocoktfx],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-1ycocoktfx],
#components-reconnect-modal.components-reconnect-failed[b-1ycocoktfx],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-1ycocoktfx] {
    display: block;
}


#components-reconnect-modal[b-1ycocoktfx] {
    background-color: white;
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: 0.5rem;
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-1ycocoktfx 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-1ycocoktfx 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-1ycocoktfx 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-1ycocoktfx]::backdrop {
    background-color: rgba(0, 0, 0, 0.4);
    animation: components-reconnect-modal-fadeInOpacity-b-1ycocoktfx 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-1ycocoktfx {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-1ycocoktfx {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-1ycocoktfx {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-1ycocoktfx] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-1ycocoktfx] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-1ycocoktfx] {
    border: 0;
    background-color: #6b9ed2;
    color: white;
    padding: 4px 24px;
    border-radius: 4px;
}

    #components-reconnect-modal button:hover[b-1ycocoktfx] {
        background-color: #3b6ea2;
    }

    #components-reconnect-modal button:active[b-1ycocoktfx] {
        background-color: #6b9ed2;
    }

.components-rejoining-animation[b-1ycocoktfx] {
    position: relative;
    width: 80px;
    height: 80px;
}

    .components-rejoining-animation div[b-1ycocoktfx] {
        position: absolute;
        border: 3px solid #0087ff;
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-1ycocoktfx 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

        .components-rejoining-animation div:nth-child(2)[b-1ycocoktfx] {
            animation-delay: -0.5s;
        }

@keyframes components-rejoining-animation-b-1ycocoktfx {
    0% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    4.9% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    5% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 1;
    }

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
/* /Components/Pages/Home.razor.rz.scp.css */
/* ══════════════════════════════════════════════════════════════════
   Home page — echoes the /login portal, then hands off to the
   theme-aware surface for the plugin cards.

   The hero draws on the --lp-* portal palette and the cards below on
   the ordinary theme tokens, but both now follow the selected theme:
   every theme overrides --lp-* in wwwroot/app.css.
   ══════════════════════════════════════════════════════════════════ */

.home[b-l88a2huc1b] {
    display: flex;
    flex-direction: column;
    gap: 2rem;
}

/* ── Hero ─────────────────────────────────────────────────────────── */
.home-hero[b-l88a2huc1b] {
    /* Quieter than the login page, because the hero carries body copy over the
       figure — but not so quiet it cannot be seen. At 0.18 the plate combined
       with the backdrop's own opacity to an effective 0.14 and read as noise;
       measured against the title, which is the only thing that overlaps the
       central letter grid. Inherits down to the SVG, which lives in a
       different component and so cannot be reached by a scoped selector. */
    --ht-opacity: 0.4;
    position: relative;
    overflow: hidden;
    border-radius: 18px;
    border: 1px solid var(--lp-card-border);
    background: var(--lp-bg);
    box-shadow: 0 18px 48px rgba(4, 4, 12, 0.45);
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

.home-hero__inner[b-l88a2huc1b] {
    position: relative;
    z-index: 10;
    display: flex;
    align-items: center;
    gap: 2.5rem;
    padding: 2.75rem 2.5rem;
    flex-wrap: wrap;
    justify-content: center;
}

.home-hero__text[b-l88a2huc1b] {
    flex: 1 1 22rem;
    min-width: 0;
}

.home-title[b-l88a2huc1b] {
    font-family: 'GDEnochian', 'Helvetica Neue', sans-serif;
    font-size: 2.9rem;
    line-height: 1.15;
    letter-spacing: 0.14em;
    margin: 0;
    color: var(--lp-accent);
    text-shadow: 0 0 18px var(--lp-accent-glow);
}

.home-subtitle[b-l88a2huc1b] {
    margin: 0.65rem 0 0;
    font-size: 0.82rem;
    letter-spacing: 0.28em;
    text-transform: uppercase;
    color: var(--lp-muted);
}

.home-sep[b-l88a2huc1b] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 1.25rem 0;
    max-width: 22rem;
}

.home-sep__line[b-l88a2huc1b] {
    flex: 1;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--lp-accent-dim), transparent);
}

.home-sep__glyph[b-l88a2huc1b] {
    color: var(--lp-accent2);
    font-size: 0.9rem;
    text-shadow: 0 0 10px var(--lp-accent2-dim);
}

.home-greeting[b-l88a2huc1b] {
    margin: 0 0 0.6rem;
    color: var(--lp-text);
    font-size: 0.95rem;
}

.home-greeting strong[b-l88a2huc1b] {
    color: var(--lp-accent);
    font-weight: 600;
}

.home-lead[b-l88a2huc1b] {
    margin: 0;
    max-width: 34rem;
    color: var(--lp-muted);
    font-size: 0.92rem;
    line-height: 1.65;
}

/* ── Plugin cards ─────────────────────────────────────────────────── */
.home-grid[b-l88a2huc1b] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 1rem;
}

.home-card[b-l88a2huc1b] {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    padding: 1.25rem 1.35rem;
    border-radius: 14px;
    border: 1px solid var(--surface-border);
    background: var(--surface-bg);
    box-shadow: var(--surface-shadow);
    color: var(--page-text);
    text-decoration: none;
    transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}

.home-card:hover[b-l88a2huc1b],
.home-card:focus-visible[b-l88a2huc1b] {
    transform: translateY(-3px);
    border-color: var(--link-color);
    box-shadow: 0 16px 34px rgba(0, 0, 0, 0.16);
    text-decoration: none;
}

.home-card:focus-visible[b-l88a2huc1b] {
    outline: 3px solid var(--focus-ring);
    outline-offset: 2px;
}

.home-card__icon[b-l88a2huc1b] {
    width: 1.7rem;
    height: 1.7rem;
    background-color: var(--nav-icon-color, var(--link-color));
    -webkit-mask: var(--nav-icon) no-repeat center / contain;
    mask: var(--nav-icon) no-repeat center / contain;
    opacity: 0.85;
}

.home-card__label[b-l88a2huc1b] {
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--link-color);
}

.home-card__desc[b-l88a2huc1b] {
    font-size: 0.86rem;
    line-height: 1.55;
    color: var(--muted-text);
}

.home-card--muted .home-card__label[b-l88a2huc1b] {
    color: var(--page-text);
}

/* ── Narrow viewports ─────────────────────────────────────────────── */
@media (max-width: 640px) {
    .home-hero__inner[b-l88a2huc1b] {
        padding: 2rem 1.35rem;
        gap: 1.75rem;
    }

    .home-title[b-l88a2huc1b] {
        font-size: 2.1rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    .home-card[b-l88a2huc1b] {
        transition: none;
    }

    .home-card:hover[b-l88a2huc1b],
    .home-card:focus-visible[b-l88a2huc1b] {
        transform: none;
    }
}
/* /Components/Pages/Login.razor.rz.scp.css */
/* ══════════════════════════════════════════════════════════════════
   Login page — dark plasma occult Enochian theme
   ══════════════════════════════════════════════════════════════════ */

/* Colour tokens live in wwwroot/app.css, not here. Blazor CSS isolation rewrites every
   selector to end in the scope attribute, so a `:root` rule in this file becomes
   `:root[b-xxxxxxxxxx]` — which never matches <html>, leaving every var() undefined. The
   portal palette is shared with the Home hero anyway, so a global home is the right one. */

/* ── Full-screen wrapper ──────────────────────────────────────────── */
.login-bg[b-n07le0z36v] {
    position: relative;
    width: 100vw;
    min-height: 100vh;
    background: var(--lp-bg);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

/* ── Card wrapper / centring ──────────────────────────────────────── */
.login-wrap[b-n07le0z36v] {
    position: relative;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 100vh;
    padding: 2rem 1rem;
    box-sizing: border-box;
}

/* ── Glass card ───────────────────────────────────────────────────── */
.login-card[b-n07le0z36v] {
    width: 100%;
    max-width: 440px;
    background: var(--lp-card-bg);
    border: 1px solid var(--lp-card-border);
    border-radius: 16px;
    padding: 2.5rem 2rem 2.25rem;
    text-align: center;
    backdrop-filter: blur(24px);
    -webkit-backdrop-filter: blur(24px);
    box-shadow:
        0 0 0 1px color-mix(in srgb, var(--lp-accent, #2ae6c8) 6%, transparent),
        0 0 40px color-mix(in srgb, var(--lp-accent, #2ae6c8) 10%, transparent),
        0 0 120px color-mix(in srgb, var(--lp-accent2, #8d4bff) 8%, transparent),
        0 30px 80px rgba(0,0,0,0.6);
    animation: card-in-b-n07le0z36v 0.8s cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes card-in-b-n07le0z36v {
    from { opacity: 0; transform: translateY(24px) scale(0.97); }
    to   { opacity: 1; transform: translateY(0)    scale(1); }
}

/* ── Title ────────────────────────────────────────────────────────── */
.login-title[b-n07le0z36v] {
    font-family: 'GDEnochian', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    font-size: 2.2rem;
    letter-spacing: 0.18em;
    color: var(--lp-accent);
    text-shadow:
        0 0 12px color-mix(in srgb, var(--lp-accent, #2ae6c8) 70%, transparent),
        0 0 32px color-mix(in srgb, var(--lp-accent, #2ae6c8) 35%, transparent);
    margin: 0 0 0.5rem;
    animation: glow-pulse-b-n07le0z36v 4s ease-in-out infinite alternate;
}

@keyframes glow-pulse-b-n07le0z36v {
    from { text-shadow: 0 0 10px color-mix(in srgb, var(--lp-accent, #2ae6c8) 60%, transparent), 0 0 28px color-mix(in srgb, var(--lp-accent, #2ae6c8) 30%, transparent); }
    to   { text-shadow: 0 0 18px color-mix(in srgb, var(--lp-accent, #2ae6c8) 90%, transparent), 0 0 52px color-mix(in srgb, var(--lp-accent, #2ae6c8) 50%, transparent), 0 0 80px color-mix(in srgb, var(--lp-accent2, #8d4bff) 25%, transparent); }
}

/* ── Subtitle ─────────────────────────────────────────────────────── */
.login-subtitle[b-n07le0z36v] {
    font-size: 0.85rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--lp-muted);
    margin: 0 0 1.8rem;
}

/* ── Separator ────────────────────────────────────────────────────── */
.login-sep[b-n07le0z36v] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 2rem;
}

.login-sep__line[b-n07le0z36v] {
    flex: 1;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--lp-card-border), transparent);
}

.login-sep__glyph[b-n07le0z36v] {
    color: var(--lp-accent);
    font-size: 0.9rem;
    opacity: 0.6;
}

/* ── Action buttons ───────────────────────────────────────────────── */
.login-actions[b-n07le0z36v] {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    margin-bottom: 2rem;
}

.btn-portal[b-n07le0z36v] {
    display: block;
    padding: 0.8rem 1.5rem;
    border-radius: 8px;
    font-size: 0.92rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-decoration: none;
    transition: all 0.22s ease;
    cursor: pointer;
}

.btn-portal--primary[b-n07le0z36v] {
    /* Shaded from the accent rather than from two fixed teals, so the primary
       action stays the theme's own colour. The label takes the portal ground,
       which is the darkest surface in every theme except light — and there the
       accent is dark enough that the pale ground reads correctly against it. */
    background: linear-gradient(135deg, var(--lp-accent, #2ae6c8) 0%, color-mix(in srgb, var(--lp-accent, #2ae6c8) 82%, #000) 100%);
    color: var(--lp-bg, #04040c);
    border: 1px solid transparent;
    box-shadow: 0 0 16px color-mix(in srgb, var(--lp-accent, #2ae6c8) 40%, transparent), 0 4px 16px rgba(0,0,0,0.4);
}

.btn-portal--primary:hover[b-n07le0z36v] {
    background: linear-gradient(135deg, color-mix(in srgb, var(--lp-accent, #2ae6c8) 82%, #fff) 0%, var(--lp-accent, #2ae6c8) 100%);
    box-shadow: 0 0 28px color-mix(in srgb, var(--lp-accent, #2ae6c8) 65%, transparent), 0 6px 24px rgba(0,0,0,0.5);
    transform: translateY(-2px);
    color: var(--lp-bg, #04040c);
    text-decoration: none;
}

.btn-portal--outline[b-n07le0z36v] {
    background: transparent;
    color: var(--lp-accent);
    border: 1px solid var(--lp-card-border);
    box-shadow: inset 0 0 0 0 var(--lp-accent-dim);
}

.btn-portal--outline:hover[b-n07le0z36v] {
    background: var(--lp-accent-dim);
    border-color: color-mix(in srgb, var(--lp-accent, #2ae6c8) 50%, transparent);
    box-shadow: 0 0 20px color-mix(in srgb, var(--lp-accent, #2ae6c8) 20%, transparent);
    transform: translateY(-2px);
    color: var(--lp-accent);
    text-decoration: none;
}

/* ── Footer caption ───────────────────────────────────────────────── */
.login-caption[b-n07le0z36v] {
    font-size: 0.7rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--lp-muted);
    margin: 0;
    opacity: 0.6;
}

/* Source note for the wind rose. */
.login-attrib[b-n07le0z36v] {
    margin: 0.6rem 0 0;
    font-size: 0.62rem;
    letter-spacing: 0.08em;
    color: var(--lp-muted);
    opacity: 0.5;
}

.login-attrib em[b-n07le0z36v] {
    font-style: italic;
}

/* ── Responsive ───────────────────────────────────────────────────── */
@media (max-width: 480px) {
    .login-card[b-n07le0z36v] {
        padding: 2.5rem 1.5rem 2rem;
    }

    .login-title[b-n07le0z36v] {
        font-size: 1.75rem;
    }
}
/* /Components/Pages/Settings.razor.rz.scp.css */
.theme-home[b-ps1v3abk9m] {
    display: grid;
    gap: 1.5rem;
    align-items: start;
    max-width: 72rem;
}

.theme-home__intro[b-ps1v3abk9m] {
    padding-top: 0.75rem;
    max-width: 44rem;
}

.theme-kicker[b-ps1v3abk9m] {
    margin: 0 0 0.5rem;
    color: var(--muted-text);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 0.75rem;
}

.theme-home h1[b-ps1v3abk9m] {
    margin: 0;
    font-size: clamp(2rem, 3vw, 3rem);
    line-height: 1.05;
}

.theme-lead[b-ps1v3abk9m] {
    margin: 0.9rem 0 0;
    max-width: 36rem;
    color: var(--muted-text);
    font-size: 1rem;
    line-height: 1.6;
}

.theme-panel[b-ps1v3abk9m] {
    display: grid;
    gap: 1rem;
    padding: 1.25rem;
    border: 1px solid var(--surface-border);
    border-radius: 8px;
    background: var(--surface-bg);
    box-shadow: var(--surface-shadow);
}

.theme-panel__header[b-ps1v3abk9m] {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    justify-content: space-between;
    align-items: center;
}

.theme-panel__header h2[b-ps1v3abk9m] {
    margin: 0;
    font-size: 1.1rem;
}

.theme-panel__header p[b-ps1v3abk9m] {
    margin: 0.25rem 0 0;
    color: var(--muted-text);
}

.theme-badge[b-ps1v3abk9m] {
    display: inline-flex;
    align-items: center;
    min-height: 2rem;
    padding: 0 0.75rem;
    border-radius: 999px;
    border: 1px solid var(--surface-border);
    background: var(--chip-bg);
    color: var(--page-text);
    font-size: 0.875rem;
}

.theme-switcher[b-ps1v3abk9m] {
    flex-wrap: wrap;
    gap: 0.5rem;
}

.theme-switcher__button[b-ps1v3abk9m] {
    min-width: 7rem;
}

.theme-preview[b-ps1v3abk9m] {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.75rem;
}

.theme-preview__tile[b-ps1v3abk9m] {
    display: grid;
    gap: 0.35rem;
    padding: 0.9rem;
    border-radius: 8px;
    border: 1px solid var(--surface-border);
    background: var(--preview-bg);
}

.theme-preview__tile span[b-ps1v3abk9m] {
    color: var(--muted-text);
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.theme-preview__tile strong[b-ps1v3abk9m] {
    font-size: 0.98rem;
    font-weight: 600;
}

@media (max-width: 700px) {
    .theme-preview[b-ps1v3abk9m] {
        grid-template-columns: 1fr;
    }
}
/* /Components/PortalBackdrop.razor.rz.scp.css */
/* ══════════════════════════════════════════════════════════════════
   Portal backdrop — plasma orbs, grid and drifting motes.
   Shared by the login page and the home hero.
   ══════════════════════════════════════════════════════════════════ */

.portal-backdrop[b-3xu4qv1gcj] {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    z-index: 0;
}

/* ── Animated plasma orbs ─────────────────────────────────────────── */
.plasma-orb[b-3xu4qv1gcj] {
    position: absolute;
    border-radius: 50%;
    filter: blur(clamp(28px, 8%, 80px));
    will-change: transform, opacity;
}

/* Sizes and offsets are percentages of .portal-backdrop, not viewport units. The login page
   fills the viewport so the two agree there, but the home hero is a few hundred pixels tall —
   a 70vmax orb inside it would be an untextured wash. Percentages keep the composition the
   same at both scales. Translate percentages resolve against the orb's own box, likewise. */
.plasma-orb--1[b-3xu4qv1gcj] {
    width: 90%;
    aspect-ratio: 1;
    background: radial-gradient(circle, color-mix(in srgb, var(--lp-accent, #2ae6c8) 18%, transparent) 0%, transparent 68%);
    top: -30%;
    left: -20%;
    animation: plasma1-b-3xu4qv1gcj 14s ease-in-out infinite alternate;
}

.plasma-orb--2[b-3xu4qv1gcj] {
    width: 72%;
    aspect-ratio: 1;
    background: radial-gradient(circle, color-mix(in srgb, var(--lp-accent2, #8d4bff) 20%, transparent) 0%, transparent 65%);
    bottom: -28%;
    right: -16%;
    animation: plasma2-b-3xu4qv1gcj 18s ease-in-out infinite alternate;
}

.plasma-orb--3[b-3xu4qv1gcj] {
    width: 52%;
    aspect-ratio: 1;
    background: radial-gradient(circle, var(--lp-orb-3, rgba(0,180,255,0.12)) 0%, transparent 70%);
    top: 30%;
    left: 52%;
    animation: plasma3-b-3xu4qv1gcj 22s ease-in-out infinite alternate;
}

@keyframes plasma1-b-3xu4qv1gcj {
    0%   { transform: translate(0,    0)   scale(1);    opacity: 1; }
    33%  { transform: translate(12%,  9%)  scale(1.12); opacity: 0.8; }
    66%  { transform: translate(6%,   20%) scale(0.95); opacity: 0.95; }
    100% { transform: translate(-9%,  12%) scale(1.08); opacity: 0.75; }
}

@keyframes plasma2-b-3xu4qv1gcj {
    0%   { transform: translate(0,    0)    scale(1);    opacity: 1; }
    40%  { transform: translate(-14%, -12%) scale(1.15); opacity: 0.75; }
    70%  { transform: translate(-7%,  -23%) scale(0.9);  opacity: 0.9; }
    100% { transform: translate(10%,  -9%)  scale(1.1);  opacity: 0.8; }
}

@keyframes plasma3-b-3xu4qv1gcj {
    0%   { transform: translate(0,    0)   scale(1); }
    50%  { transform: translate(-12%, 15%) scale(1.2); }
    100% { transform: translate(8%,   8%)  scale(0.88); }
}

/* ── Grid overlay ─────────────────────────────────────────────────── */
.grid-overlay[b-3xu4qv1gcj] {
    position: absolute;
    inset: 0;
    background-image:
        /* Orbs and grid are mixed from the two theme accents rather than being
           tokens of their own: three more variables per theme to hand-tune would
           drift out of step with the accents they are meant to echo. */
        linear-gradient(color-mix(in srgb, var(--lp-accent, #2ae6c8) 3%, transparent) 1px, transparent 1px),
        linear-gradient(90deg, color-mix(in srgb, var(--lp-accent, #2ae6c8) 3%, transparent) 1px, transparent 1px);
    background-size: 64px 64px;
}

/* ── Floating particles ───────────────────────────────────────────── */
.particles[b-3xu4qv1gcj] {
    position: absolute;
    inset: 0;
    overflow: hidden;
}

.particle[b-3xu4qv1gcj] {
    position: absolute;
    bottom: -8px;
    left: calc(var(--i) * 5.1%);
    width: 2px;
    height: 2px;
    border-radius: 50%;
    background: var(--lp-accent, #2ae6c8);
    opacity: 0;
    animation: float-up-b-3xu4qv1gcj calc(6s + var(--i) * 0.7s) ease-in calc(var(--i) * 0.5s) infinite;
}

.particle:nth-child(even)[b-3xu4qv1gcj] {
    background: var(--lp-accent2, #8d4bff);
    width: 1.5px;
    height: 1.5px;
}

@keyframes float-up-b-3xu4qv1gcj {
    0%   { transform: translateY(0) translateX(0);       opacity: 0; }
    10%  { opacity: 0.7; }
    80%  { opacity: 0.3; }
    100% { transform: translateY(-100%) translateX(calc((var(--i) - 10) * 3px)); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .plasma-orb[b-3xu4qv1gcj],
    .particle[b-3xu4qv1gcj] {
        animation: none;
    }

    .particle[b-3xu4qv1gcj] {
        opacity: 0.35;
    }
}
/* /Components/WindRose.razor.rz.scp.css */
/* ══════════════════════════════════════════════════════════════════
   Wind rose — the twelve winds of Isidore around the four banners.
   Element accents are declared locally so the rose does not depend on
   the WatchTowers plugin stylesheet, which the login page never loads.
   ══════════════════════════════════════════════════════════════════ */

.wind-rose[b-0hkvwdqxjs] {
    /* Structure follows the portal palette so the rose changes with the theme.
       It used to hold its own copy of the occult teal, which left the wind
       names all but invisible on the light theme's pale ground. */
    --wr-line:  color-mix(in srgb, var(--lp-accent, #2ae6c8) 55%, transparent);
    --wr-faint: color-mix(in srgb, var(--lp-accent, #2ae6c8) 18%, transparent);
    --wr-text:  var(--lp-text, #d5f9f1);
    --wr-muted: var(--lp-muted, #7baaa0);

    /* The four element accents do NOT follow the theme. They are Dee's
       elemental attributions, not decoration, and they stay legible in every
       theme because each sits on its own dark medallion. */
    --wr-air: #f0e020;
    --wr-water: #4aa8ff;
    --wr-earth: #4ade9a;
    --wr-fire: #ff6a4a;

    display: flex;
    justify-content: center;
    margin-bottom: 1.4rem;
}

.wind-rose__svg[b-0hkvwdqxjs] {
    width: 340px;
    max-width: 100%;
    height: auto;
    overflow: visible;
    filter: drop-shadow(0 0 10px color-mix(in srgb, var(--lp-accent, #2ae6c8) 25%, transparent));
}

/* ── Rings and spokes ─────────────────────────────────────────────── */
.wr-rim[b-0hkvwdqxjs],
.wr-spoke[b-0hkvwdqxjs],
.wr-wind-mark[b-0hkvwdqxjs],
.wr-tick[b-0hkvwdqxjs] {
    fill: none;
    stroke: var(--wr-line);
    vector-effect: non-scaling-stroke;
}

.wr-rim[b-0hkvwdqxjs] {
    stroke-width: 1.2;
    opacity: 0.65;
}

.wr-rim--inner[b-0hkvwdqxjs] {
    stroke-width: 0.9;
    opacity: 0.4;
}

.wr-rim--faint[b-0hkvwdqxjs] {
    stroke-width: 0.6;
    opacity: 0.22;
}

.wr-spoke[b-0hkvwdqxjs] {
    stroke-width: 0.7;
    opacity: 0.3;
}

.wr-tick[b-0hkvwdqxjs] {
    stroke-width: 0.8;
    opacity: 0.35;
}

.wr-wind-mark[b-0hkvwdqxjs] {
    stroke-width: 1;
    opacity: 0.5;
}

.wr-wind--cardinal .wr-wind-mark[b-0hkvwdqxjs] {
    stroke-width: 1.8;
    opacity: 0.95;
}

/* The tick collar turns once every four minutes — slow enough to read past. */
.wind-rose__orbit[b-0hkvwdqxjs] {
    transform-origin: 170px 170px;
    animation: wr-spin-b-0hkvwdqxjs 240s linear infinite;
}

@keyframes wr-spin-b-0hkvwdqxjs {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

/* ── Wind names ───────────────────────────────────────────────────── */
.wr-wind-name[b-0hkvwdqxjs],
.wr-wind-compass[b-0hkvwdqxjs],
.wr-banner-word[b-0hkvwdqxjs],
.wr-banner-sigil[b-0hkvwdqxjs] {
    text-anchor: middle;
    dominant-baseline: middle;
    pointer-events: none;
}

.wr-wind-name[b-0hkvwdqxjs] {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    font-size: 8px;
    letter-spacing: 0.07em;
    fill: var(--wr-text);
}

.wr-wind--cardinal .wr-wind-name[b-0hkvwdqxjs] {
    font-size: 8.8px;
    font-weight: 600;
    letter-spacing: 0.07em;
}

.wr-wind-compass[b-0hkvwdqxjs] {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    font-size: 6px;
    letter-spacing: 0.16em;
    fill: var(--wr-muted);
}

.wr-wind[b-0hkvwdqxjs] {
    cursor: help;
}

.wr-wind:hover .wr-wind-name[b-0hkvwdqxjs] {
    fill: var(--lp-accent, #eafcf6);
}

/* ── Elemental sectors and banner medallions ──────────────────────── */
.wr-sector[b-0hkvwdqxjs] {
    stroke: none;
    opacity: 0.13;
}

.wr-sector.wt-air[b-0hkvwdqxjs]   { fill: var(--wr-air); }
.wr-sector.wt-water[b-0hkvwdqxjs] { fill: var(--wr-water); }
.wr-sector.wt-earth[b-0hkvwdqxjs] { fill: var(--wr-earth); }
.wr-sector.wt-fire[b-0hkvwdqxjs]  { fill: var(--wr-fire); }

.wr-banner[b-0hkvwdqxjs] {
    cursor: help;
}

.wr-banner-disc[b-0hkvwdqxjs] {
    /* Deliberately dark in every theme, including light: it is the ground the
       element colours are read against, and those do not change. */
    fill: rgba(4, 6, 14, 0.75);
}

.wr-banner-ring[b-0hkvwdqxjs] {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.3;
    vector-effect: non-scaling-stroke;
    opacity: 0.85;
}

.wr-banner-sigil[b-0hkvwdqxjs] {
    font-size: 15px;
    fill: currentColor;
    opacity: 0.95;
}

.wr-banner-word[b-0hkvwdqxjs] {
    /* Enochian face, matching the title. The Latin reading (ORO / MPH / MOR / OIP)
       stays available in the group's <title> tooltip and the SVG aria-label. */
    font-family: 'GDEnochian', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    font-size: 10px;
    letter-spacing: 0.12em;
    fill: currentColor;
}

.wr-banner.wt-air[b-0hkvwdqxjs]   { color: var(--wr-air); }
.wr-banner.wt-water[b-0hkvwdqxjs] { color: var(--wr-water); }
.wr-banner.wt-earth[b-0hkvwdqxjs] { color: var(--wr-earth); }
.wr-banner.wt-fire[b-0hkvwdqxjs]  { color: var(--wr-fire); }

.wr-banner:hover .wr-banner-ring[b-0hkvwdqxjs] {
    stroke-width: 2;
    opacity: 1;
}

/* ── Centre hub ───────────────────────────────────────────────────── */
.wr-hub[b-0hkvwdqxjs] {
    fill: rgba(4, 6, 14, 0.8);
}

.wr-hub-ring[b-0hkvwdqxjs] {
    fill: none;
    stroke: var(--wr-line);
    stroke-width: 1.2;
    vector-effect: non-scaling-stroke;
    opacity: 0.8;
}

/* Isidore's two ianuae caeli: the sunrise half lit, the sunset half dark. */
.wr-hub-half[b-0hkvwdqxjs] {
    fill: var(--wr-faint);
}

.wr-hub-dot[b-0hkvwdqxjs] {
    fill: var(--wr-line);
    opacity: 0.95;
}

@media (prefers-reduced-motion: reduce) {
    .wind-rose__orbit[b-0hkvwdqxjs] {
        animation: none;
    }
}

@media (max-width: 460px) {
    .wind-rose__svg[b-0hkvwdqxjs] {
        width: 100%;
    }
}
