@import '_content/Torch.Shared.DesignSystem/Torch.Shared.DesignSystem.jkxfcwcfjh.bundle.scp.css';

/* /Components/Layout/MainLayout.razor.rz.scp.css */
/* The ambient ember canvas sits above every page surface (header and footer included) so embers
   rise from the true bottom of the viewport and persist across scrolling, while pointer-events
   stay off so nothing underneath becomes unclickable. */
.torch-ambient-layer[b-jmunyelzh3] {
    position: fixed;
    inset: 0;
    z-index: 45;
    pointer-events: none;
}

.torch-skip-link[b-jmunyelzh3] {
    position: absolute;
    left: var(--torch-space-4);
    top: var(--torch-space-4);
    z-index: 100;
    padding: var(--torch-space-2) var(--torch-space-4);
    background: var(--torch-surface-2);
    border: 1px solid var(--torch-accent);
    border-radius: var(--torch-radius-sm);
    color: var(--torch-text-primary);
    text-decoration: none;
    transform: translateY(-200%);
    transition: transform var(--torch-duration-fast) var(--torch-ease-out);
}

.torch-skip-link:focus-visible[b-jmunyelzh3] {
    transform: translateY(0);
}

/*
 * Site chrome is deliberately flat: a solid surface, one hairline, a shy shadow. No texture and
 * no gradient — the geometric pattern belongs to accent panels only (see .torch-panel in the
 * design system's components.css), and a gradient here read as "plasticky" in review.
 *
 * The translucency plus blur is the one liberty taken: it lets the hero art and rising embers
 * show faintly through a sticky bar instead of cutting them off with a hard band.
 */
.torch-header[b-jmunyelzh3] {
    position: sticky;
    top: 0;
    z-index: 10;
    /* Dialled back from 88% so the hero's mountains and the rising embers actually ghost through
       the bar instead of being cut off by a flat band across the top of the composition — over a
       cinematic hero the old value read as an opaque strip laid on the artwork. */
    background-color: color-mix(in srgb, var(--torch-surface-1) 80%, transparent);
    backdrop-filter: blur(14px) saturate(125%);
    border-bottom: 1px solid var(--torch-border);
    box-shadow: var(--torch-shadow-sm);
}

/* A single ember hairline under the header, brightest at the centre — the same motif as the
   footer's top edge, so the page is bracketed by the accent rather than by two grey rules. */
.torch-header[b-jmunyelzh3]::after {
    content: "";
    position: absolute;
    inset: auto 0 -1px 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(201, 151, 63, 0.35), transparent);
    pointer-events: none;
}

.torch-header__inner[b-jmunyelzh3] {
    max-width: var(--torch-content-width);
    margin: 0 auto;
    padding: var(--torch-space-4) var(--torch-space-8);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--torch-space-6);
}

/* Hover feedback is the ember cast brightening on the img below, not a dim — the two together
   cancelled out, the mark getting simultaneously brighter and more transparent. */
.torch-header__brand[b-jmunyelzh3] {
    display: inline-flex;
    align-items: center;
    text-decoration: none;
}

/* A faint ember cast under the wordmark, so the brand reads as lit by the same source as
   everything else in the bar rather than as a flat PNG dropped in the corner. */
.torch-header__brand img[b-jmunyelzh3] {
    height: 2rem;
    width: auto;
    filter: drop-shadow(0 0 7px rgba(201, 151, 63, 0.14));
    transition: filter var(--torch-duration-normal) var(--torch-ease-out);
}

.torch-header__brand:hover img[b-jmunyelzh3] {
    filter: drop-shadow(0 0 11px rgba(224, 180, 99, 0.3));
}

.torch-header__nav[b-jmunyelzh3] {
    display: flex;
    align-items: center;
    gap: var(--torch-space-6);
}

/*
 * Nav links get an ember underline that grows from the centre on hover, and stays put on the
 * current page — enough state to orient without adding a second colour.
 *
 * These rules go through ::deep because the anchors are rendered by <NavLink>, a child
 * component: Blazor's CSS isolation only stamps its scope attribute on markup this layout
 * renders itself, so a plain `.torch-header__link { … }` here would compile to
 * `.torch-header__link[b-xxxx]` and match nothing. With ::deep the attribute lands on the
 * <nav> above instead and the anchors match unscoped.
 */
.torch-header__nav[b-jmunyelzh3]  .torch-header__link {
    position: relative;
    color: var(--torch-text-secondary);
    text-decoration: none;
    font-size: var(--torch-text-base);
    padding-block: var(--torch-space-1);
    transition: color var(--torch-duration-fast) var(--torch-ease-out);
}

/* The underline fades out at both ends rather than stopping dead at the text bounds — the same
   flanked-hairline motif as the section ornaments and the header's own ember rule, so the nav
   belongs to the set instead of carrying a plain bar. */
.torch-header__nav[b-jmunyelzh3]  .torch-header__link::after {
    content: "";
    position: absolute;
    inset: auto 0 0 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--torch-accent) 30%,
            var(--torch-accent) 70%, transparent);
    transform: scaleX(0);
    transition: transform var(--torch-duration-normal) var(--torch-ease-out);
}

.torch-header__nav[b-jmunyelzh3]  .torch-header__link:hover {
    color: var(--torch-text-primary);
}

.torch-header__nav[b-jmunyelzh3]  .torch-header__link:hover::after {
    transform: scaleX(1);
}

.torch-header__nav[b-jmunyelzh3]  .torch-header__link--active {
    color: var(--torch-text-primary);
}

.torch-header__nav[b-jmunyelzh3]  .torch-header__link--active::after {
    transform: scaleX(1);
}

/*
 * Sign-out was the boldest thing in the bar — a 600-weight ghost button next to 400-weight nav
 * links, so the eye landed on "leave" before it landed on anywhere to go. It keeps its <button>
 * (it posts a form; it is not a link) but takes the nav links' weight, size and muted colour,
 * set behind a hairline so it reads as a separate group rather than as a fifth destination.
 *
 * No ::deep here, unlike the nav rules above: this form and its button are both rendered by this
 * layout, so both carry the scope attribute already.
 */
.torch-header__logout-form[b-jmunyelzh3] {
    position: relative;
    display: inline-flex;
    align-items: center;
    margin: 0;
    padding-left: var(--torch-space-6);
}

.torch-header__logout-form[b-jmunyelzh3]::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    width: 1px;
    height: 1.15rem;
    transform: translateY(-50%);
    background: linear-gradient(180deg, transparent, var(--torch-border-strong), transparent);
}

.torch-header__logout-form .torch-button[b-jmunyelzh3] {
    padding: var(--torch-space-1) 0;
    font-size: var(--torch-text-base);
    font-weight: 400;
    color: var(--torch-text-muted);
}

.torch-header__logout-form .torch-button:hover[b-jmunyelzh3] {
    background: transparent;
    color: var(--torch-text-primary);
}

/*
 * The language switcher is the trailing group, so it gets the same hairline the logout form has.
 * ::deep is required here and *not* in CultureSelector.razor.css: this rule targets markup a child
 * component renders, which never carries this layout's scope attribute. .torch-header__nav does
 * carry it, so the descendant combinator crosses the boundary.
 */
.torch-header__nav[b-jmunyelzh3]  .torch-culture-selector {
    position: relative;
    display: inline-flex;
    align-items: center;
    padding-left: var(--torch-space-6);
}

.torch-header__nav[b-jmunyelzh3]  .torch-culture-selector::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    width: 1px;
    height: 1.15rem;
    transform: translateY(-50%);
    background: linear-gradient(180deg, transparent, var(--torch-border-strong), transparent);
}

@media (max-width: 48rem) {
    .torch-header__inner[b-jmunyelzh3] {
        padding-inline: var(--torch-space-4);
        flex-wrap: wrap;
    }

    .torch-header__nav[b-jmunyelzh3] {
        gap: var(--torch-space-4);
        font-size: var(--torch-text-sm);
    }
}

#blazor-error-ui[b-jmunyelzh3] {
    background: var(--torch-surface-2);
    color: var(--torch-text-primary);
    border-top: 1px solid var(--torch-danger);
    bottom: 0;
    box-shadow: var(--torch-shadow-lg);
    box-sizing: border-box;
    display: none;
    padding: var(--torch-space-3) var(--torch-space-6);
    position: fixed;
    left: 0;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss[b-jmunyelzh3] {
    cursor: pointer;
    position: absolute;
    right: var(--torch-space-3);
    top: var(--torch-space-2);
}
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
/*
 * The circuit-reconnect dialog, restyled onto the design system.
 *
 * The visibility machinery below is the stock template's, kept verbatim and deliberately: Blazor's
 * runtime toggles those five class names on the dialog and nothing else drives what is on screen.
 * Only the materials underneath it have changed.
 */

.components-reconnect-first-attempt-visible[b-ifs3harzk0],
.components-reconnect-repeated-attempt-visible[b-ifs3harzk0],
.components-reconnect-failed-visible[b-ifs3harzk0],
.components-pause-visible[b-ifs3harzk0],
.components-resume-failed-visible[b-ifs3harzk0],
.components-rejoining-animation[b-ifs3harzk0] {
    display: none;
}

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

/*
 * The buttons are caught by the same `display: block` rule as the text blocks above, which would
 * stretch a forged plate across the whole dialog and throw away .torch-button's inline-flex
 * centring. Restated at a higher specificity rather than by reordering, so the framework's block
 * above can stay exactly as the template ships it.
 */
#components-reconnect-modal .components-reconnect-failed-visible.torch-button[b-ifs3harzk0],
#components-reconnect-modal .components-pause-visible.torch-button[b-ifs3harzk0],
#components-reconnect-modal .components-resume-failed-visible.torch-button[b-ifs3harzk0] {
    display: none;
}

#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible.torch-button[b-ifs3harzk0],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible.torch-button[b-ifs3harzk0],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible.torch-button[b-ifs3harzk0] {
    display: inline-flex;
}

/* ---------------------------------------------------------------- the panel */

/*
 * A raised obsidian panel, same as any card in the product: a surface a step above the page, a
 * hairline rim, the chisel groove just inside it. The white card this replaces was the single most
 * out-of-place surface in the app, and it only ever appeared at the worst possible moment.
 */
#components-reconnect-modal[b-ifs3harzk0] {
    position: fixed;
    inset: 0;
    width: min(27rem, calc(100vw - 2rem));
    height: fit-content;
    margin: auto;
    padding: var(--torch-space-8);
    color: var(--torch-text-primary);
    background-color: var(--torch-surface-1);
    border: 1px solid var(--torch-border-strong);
    border-radius: var(--torch-radius-lg);
    box-shadow: var(--torch-shadow-lg), var(--torch-chisel);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-ifs3harzk0 0.5s both;
}

#components-reconnect-modal[open][b-ifs3harzk0] {
    animation:
        components-reconnect-modal-slideUp-b-ifs3harzk0 1.5s cubic-bezier(0.05, 0.89, 0.25, 1.02) 0.3s,
        components-reconnect-modal-fadeInOpacity-b-ifs3harzk0 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

/* The gold hairline set in from the rim — the same "struck plate carries a border a few millimetres
   in from its edge" detail as .torch-button--hero and the architecture slabs. */
#components-reconnect-modal[b-ifs3harzk0]::before {
    content: "";
    position: absolute;
    inset: 4px;
    border: 1px solid var(--torch-engraving);
    border-radius: calc(var(--torch-radius-lg) - 2px);
    pointer-events: none;
}

/* Blurred, not just dimmed: the page behind this is frozen and unusable, and saying so with depth
   of field is gentler than dropping a flat black sheet over it. */
#components-reconnect-modal[b-ifs3harzk0]::backdrop {
    background-color: rgba(4, 3, 2, 0.66);
    backdrop-filter: blur(5px) saturate(0.9);
    animation: components-reconnect-modal-fadeInOpacity-b-ifs3harzk0 0.5s ease-in-out;
    opacity: 1;
}

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

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

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

    100% {
        opacity: 1;
    }
}

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

    100% {
        opacity: 0;
    }
}

/* ---------------------------------------------------------------- contents */

.components-reconnect-container[b-ifs3harzk0] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--torch-space-5, 1.25rem);
}

/* The ember diamond that opens every other composition in the product — a section heading, the
   footer's closing mark, the hero's breath. Here it is the one thing still alight while the
   connection is not. */
.torch-reconnect__mark[b-ifs3harzk0] {
    width: 0.5rem;
    height: 0.5rem;
    flex: 0 0 auto;
    background: var(--torch-accent);
    transform: rotate(45deg);
    box-shadow: 0 0 10px rgba(201, 151, 63, 0.55);
    animation: torch-reconnect-mark-b-ifs3harzk0 2.4s ease-in-out infinite;
}

@keyframes torch-reconnect-mark-b-ifs3harzk0 {
    0%,
    100% {
        box-shadow: 0 0 8px rgba(201, 151, 63, 0.4);
        opacity: 0.8;
    }

    50% {
        box-shadow: 0 0 18px rgba(201, 151, 63, 0.85);
        opacity: 1;
    }
}

.torch-reconnect__state[b-ifs3harzk0] {
    text-align: center;
}

#components-reconnect-modal h2[b-ifs3harzk0] {
    /* Down from the global h2 scale: this is a dialog title, not a page section, and at
       --torch-text-xl it crowded a 27rem panel. */
    font-size: var(--torch-text-md);
    margin: 0 0 var(--torch-space-2);
}

#components-reconnect-modal p[b-ifs3harzk0] {
    margin: 0;
    text-align: center;
    color: var(--torch-text-secondary);
    font-size: var(--torch-text-base);
}

/* The countdown is a number that changes in place, so it takes the face the product uses for every
   other changing figure — without tabular digits the whole line jitters once a second. */
#components-seconds-to-next-attempt[b-ifs3harzk0] {
    font-family: var(--torch-font-mono);
    font-variant-numeric: tabular-nums;
    color: var(--torch-accent-strong);
}

/* ---------------------------------------------------------------- the sweep */

/*
 * Two expanding blue rings replaced by an ember travelling a hairline — the same motif as the
 * loading screen's progress shimmer and the roadmap spine on /about, so "working on it" looks the
 * same everywhere in the product.
 *
 * Indeterminate on purpose. There is no progress to report here: the app is waiting for a server
 * that may be mid-deploy, and a bar that fills would be inventing a number.
 */
.torch-reconnect__track[b-ifs3harzk0] {
    position: relative;
    width: 100%;
    height: 1px;
    overflow: hidden;
    background: linear-gradient(90deg,
            transparent,
            var(--torch-border-strong) 18%,
            var(--torch-border-strong) 82%,
            transparent);
}

.torch-reconnect__track div[b-ifs3harzk0] {
    position: absolute;
    inset: 0 auto 0 0;
    width: 38%;
    background: linear-gradient(90deg, transparent, var(--torch-accent), transparent);
    animation: torch-reconnect-sweep-b-ifs3harzk0 2.1s ease-in-out infinite;
}

/* Half a cycle behind the first, and dimmer, so the hairline is never entirely dark. */
.torch-reconnect__track div:nth-child(2)[b-ifs3harzk0] {
    animation-delay: -1.05s;
    opacity: 0.4;
}

@keyframes torch-reconnect-sweep-b-ifs3harzk0 {
    0% {
        transform: translateX(-110%);
    }

    100% {
        transform: translateX(375%);
    }
}
/* /Components/Pages/About.razor.rz.scp.css */
/*
 * The showcase page. The architecture picture and its own motion live in ArchitectureDiagram;
 * this file owns the page frame and the timeline.
 *
 * The spine pulse is deliberately slow (22 s end to end) and idle for most of that — it should
 * read as a heartbeat noticed out of the corner of the eye, not as a loading indicator.
 * base.css collapses it under prefers-reduced-motion.
 */

.torch-roadmap[b-8j75fg1ubl] {
    max-width: var(--torch-content-width);
    margin: 0 auto;
    padding: var(--torch-space-16) var(--torch-space-8);
}

.torch-roadmap__hero[b-8j75fg1ubl] {
    max-width: var(--torch-prose-width);
}

.torch-roadmap__lead[b-8j75fg1ubl] {
    color: var(--torch-text-secondary);
    font-size: var(--torch-text-md);
    margin-bottom: 0;
}

/* The panel spans the viewport; only its content is centred. Splitting the two is what keeps the
   texture from being clipped to the centring wrapper's width. */
.torch-roadmap__arch-section[b-8j75fg1ubl] {
    padding: var(--torch-space-16) 0;
}

.torch-roadmap__arch-inner[b-8j75fg1ubl] {
    max-width: var(--torch-content-width);
    margin: 0 auto;
    padding: 0 var(--torch-space-8);
}

.torch-roadmap__note[b-8j75fg1ubl] {
    color: var(--torch-text-secondary);
    max-width: 66ch;
    margin: 0 auto var(--torch-space-12);
    text-align: center;
}

/* ---------------------------------------------------------------- timeline */

.torch-roadmap__timeline-wrap[b-8j75fg1ubl] {
    --spine-x: 0.5rem;
    --timeline-gutter: 2.75rem;
    position: relative;
    padding-left: var(--timeline-gutter);
    max-width: var(--torch-prose-width);
    margin: 0 auto;
}

.torch-roadmap__spine[b-8j75fg1ubl] {
    position: absolute;
    left: var(--spine-x);
    top: 0.5rem;
    bottom: 2rem;
    width: 1px;
    overflow: hidden;
    background: linear-gradient(180deg,
            transparent 0%,
            var(--torch-border-strong) 8%,
            var(--torch-border-strong) 88%,
            transparent 100%);
}

/* One ember travelling the length of the spine. `top` is animated rather than a transform because
   the distance is the container's height, which is content-dependent and unknown here. */
.torch-roadmap__spine[b-8j75fg1ubl]::after {
    content: "";
    position: absolute;
    left: 0;
    width: 1px;
    height: 8rem;
    background: linear-gradient(180deg,
            transparent 0%,
            var(--torch-accent-muted) 35%,
            var(--torch-accent-strong) 55%,
            transparent 100%);
    animation: torch-spine-pulse-b-8j75fg1ubl 22s ease-in-out infinite;
}

@keyframes torch-spine-pulse-b-8j75fg1ubl {
    0% {
        top: -10%;
        opacity: 0;
    }

    8% {
        opacity: 1;
    }

    52% {
        opacity: 1;
    }

    60%,
    100% {
        top: 102%;
        opacity: 0;
    }
}

.torch-roadmap__timeline[b-8j75fg1ubl] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--torch-space-12);
}

.torch-roadmap__milestone[b-8j75fg1ubl] {
    position: relative;
}

.torch-roadmap__milestone h3[b-8j75fg1ubl] {
    margin: 0 0 var(--torch-space-3);
    font-size: var(--torch-text-lg);
}

/* A rotated diamond, not a circle — the same mark the section headings and the hero rule use. */
.torch-roadmap__dot[b-8j75fg1ubl] {
    position: absolute;
    left: calc(var(--spine-x) - var(--timeline-gutter) - 5px);
    top: 0.45rem;
    width: 10px;
    height: 10px;
    background: var(--torch-accent);
    transform: rotate(45deg);
    box-shadow: 0 0 10px rgba(201, 151, 63, 0.5);
    animation: torch-dot-pulse-b-8j75fg1ubl 14s ease-in-out infinite;
}

.torch-roadmap__milestone:nth-child(2) .torch-roadmap__dot[b-8j75fg1ubl] {
    animation-delay: 4.5s;
}

.torch-roadmap__milestone:nth-child(3) .torch-roadmap__dot[b-8j75fg1ubl] {
    animation-delay: 9s;
}

/* The open marker is the one that has not happened yet: no fill, no heat. */
.torch-roadmap__dot--hollow[b-8j75fg1ubl] {
    background: var(--torch-surface-0);
    border: 1px solid var(--torch-accent-muted);
    box-shadow: none;
    animation: none;
}

@keyframes torch-dot-pulse-b-8j75fg1ubl {
    0%,
    82%,
    100% {
        box-shadow: 0 0 10px rgba(201, 151, 63, 0.5);
    }

    90% {
        box-shadow: 0 0 22px rgba(201, 151, 63, 0.9);
    }
}

.torch-roadmap__marker[b-8j75fg1ubl] {
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-xs);
    font-weight: 600;
    letter-spacing: var(--torch-tracking-eyebrow);
    text-transform: uppercase;
    color: var(--torch-accent);
    margin: 0 0 var(--torch-space-2);
}

.torch-roadmap__milestone-lead[b-8j75fg1ubl] {
    color: var(--torch-text-secondary);
    margin: 0;
}

.torch-roadmap__chips[b-8j75fg1ubl] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--torch-space-2);
    list-style: none;
    margin: var(--torch-space-4) 0 0;
    padding: 0;
}

.torch-roadmap__chip[b-8j75fg1ubl] {
    background: var(--torch-surface-2);
    border: 1px solid var(--torch-border);
    border-radius: var(--torch-radius-sm);
    box-shadow: var(--torch-chisel);
    color: var(--torch-text-secondary);
    font-family: var(--torch-font-mono);
    font-size: var(--torch-text-xs);
    padding: var(--torch-space-1) var(--torch-space-3);
}

/* The planned milestone reads as a drawing, not a photograph: open marker, dimmed heading, and
   chips that are outlines rather than filled stone. Nothing here has been built yet. */
.torch-roadmap__milestone--next .torch-roadmap__marker[b-8j75fg1ubl] {
    color: var(--torch-text-muted);
}

.torch-roadmap__milestone--next h3[b-8j75fg1ubl] {
    color: var(--torch-text-secondary);
}

.torch-roadmap__milestone--next .torch-roadmap__chip[b-8j75fg1ubl] {
    background: none;
    border-style: dashed;
    box-shadow: none;
    color: var(--torch-text-muted);
}

.torch-roadmap__footnote[b-8j75fg1ubl] {
    color: var(--torch-text-muted);
    font-size: var(--torch-text-sm);
    font-style: italic;
    margin: var(--torch-space-4) 0 0;
}

@media (max-width: 40rem) {
    .torch-roadmap[b-8j75fg1ubl] {
        padding: var(--torch-space-12) var(--torch-space-4);
    }

    .torch-roadmap__arch-inner[b-8j75fg1ubl] {
        padding-inline: var(--torch-space-4);
    }

    .torch-roadmap__timeline-wrap[b-8j75fg1ubl] {
        --timeline-gutter: 2rem;
    }
}
/* /Components/Pages/Account.razor.rz.scp.css */
.torch-account-page[b-uw0avx9i45] {
    max-width: 42rem;
    margin: 0 auto;
    padding: var(--torch-space-16) var(--torch-space-8);
    display: flex;
    flex-direction: column;
    gap: var(--torch-space-6);
}

.torch-account-page h1[b-uw0avx9i45] {
    margin: 0;
}

.torch-account-page__card dl[b-uw0avx9i45] {
    margin: 0;
}

.torch-account-page__fields[b-uw0avx9i45] {
    display: grid;
    grid-template-columns: 8rem 1fr;
    row-gap: var(--torch-space-4);
    column-gap: var(--torch-space-6);
    align-items: baseline;
}

.torch-account-page__fields dt[b-uw0avx9i45] {
    color: var(--torch-text-muted);
    font-size: var(--torch-text-sm);
    letter-spacing: 0.04em;
}

.torch-account-page__fields dd[b-uw0avx9i45] {
    margin: 0;
    color: var(--torch-text-primary);
}

.torch-account-page__hint[b-uw0avx9i45] {
    display: block;
    margin-top: var(--torch-space-1);
    font-size: var(--torch-text-sm);
    color: var(--torch-text-muted);
}

.torch-account-page__roles[b-uw0avx9i45] {
    display: flex;
    gap: var(--torch-space-2);
    flex-wrap: wrap;
}

.torch-account-page__actions[b-uw0avx9i45] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--torch-space-3);
}

@media (max-width: 40rem) {
    .torch-account-page[b-uw0avx9i45] {
        padding-inline: var(--torch-space-4);
    }

    .torch-account-page__fields[b-uw0avx9i45] {
        grid-template-columns: 1fr;
        row-gap: var(--torch-space-2);
    }
}
/* /Components/Pages/AccountCharacters.razor.rz.scp.css */
.torch-account-characters__empty[b-1nofc0zb6b] {
    margin: 0;
    color: var(--torch-text-muted);
}

.torch-account-characters__list[b-1nofc0zb6b] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--torch-space-3);
}

.torch-account-characters__item[b-1nofc0zb6b] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--torch-space-3);
    padding: var(--torch-space-3) var(--torch-space-4);
    border: 1px solid var(--torch-border);
    border-radius: var(--torch-radius-md);
    background: var(--torch-surface-2);
}

.torch-account-characters__identity[b-1nofc0zb6b] {
    display: flex;
    flex-direction: column;
    gap: var(--torch-space-1);
    min-width: 0;
}

.torch-account-characters__name[b-1nofc0zb6b] {
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-md);
    color: var(--torch-text-primary);
}

.torch-account-characters__meta[b-1nofc0zb6b] {
    font-size: var(--torch-text-sm);
    color: var(--torch-text-muted);
}

.torch-account-characters__controls[b-1nofc0zb6b] {
    display: flex;
    align-items: center;
    gap: var(--torch-space-2);
}

.torch-account-characters__confirm[b-1nofc0zb6b] {
    margin-top: var(--torch-space-4);
    padding: var(--torch-space-4);
    border: 1px solid var(--torch-danger);
    border-radius: var(--torch-radius-md);
    background: var(--torch-surface-2);
}

.torch-account-characters__confirm-question[b-1nofc0zb6b] {
    margin: 0 0 var(--torch-space-2);
    color: var(--torch-text-primary);
}

.torch-account-characters__confirm-detail[b-1nofc0zb6b] {
    margin: 0 0 var(--torch-space-4);
    color: var(--torch-text-secondary);
    font-size: var(--torch-text-sm);
    line-height: var(--torch-leading-body);
}

.torch-account-characters__confirm-actions[b-1nofc0zb6b] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--torch-space-3);
}
/* /Components/Pages/AccountPublicIdentity.razor.rz.scp.css */
.torch-account-identity__intro[b-go7v4qypzf] {
    margin: 0 0 var(--torch-space-4);
    color: var(--torch-text-secondary);
    line-height: var(--torch-leading-body);
}

.torch-account-identity__current[b-go7v4qypzf] {
    margin: 0 0 var(--torch-space-4);
}

.torch-account-identity__unset[b-go7v4qypzf] {
    color: var(--torch-text-muted);
    font-size: var(--torch-text-sm);
}

.torch-account-identity__actions[b-go7v4qypzf] {
    display: flex;
    gap: var(--torch-space-3);
    margin-bottom: var(--torch-space-4);
}

.torch-account-identity__note[b-go7v4qypzf] {
    margin: var(--torch-space-2) 0 0;
    color: var(--torch-text-muted);
    font-size: var(--torch-text-sm);
    line-height: var(--torch-leading-body);
}
/* /Components/Pages/Admin/WorldDial.razor.rz.scp.css */
/*
 * The world dial. Scoped rather than global: every selector below matches an element this
 * component renders itself, which is the one case CSS isolation actually reaches (see the trap
 * list in Web/AGENTS.md).
 *
 * Font sizes are tokens even inside the SVG. A rem inside a viewBox resolves against the root font
 * size and then scales with the drawing, so 0.75rem is 12 user units of a 260-unit dial — which is
 * why the face is capped at 17rem rather than left to fill its column: past that the numerals grow
 * with the artwork instead of staying engraved into it.
 */

.world-dial[b-m89lmio475] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--torch-space-2);
}

.world-dial__face[b-m89lmio475] {
    display: block;
    width: 100%;
    max-width: 17rem;
    overflow: visible;
}

.world-dial__caption[b-m89lmio475] {
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-md);
    letter-spacing: var(--torch-tracking-display);
    color: var(--torch-text-secondary);
    margin: 0;
}

.world-dial__note[b-m89lmio475] {
    font-size: var(--torch-text-xs);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--torch-text-muted);
    margin: 0;
}

/* ---------------------------------------------------------------- the one colour */

/*
 * The sampled sky, spent twice and no more: a soft light around whichever body is up, and a thin
 * band under the numerals. Not a full-bleed background — a coloured rectangle behind an instrument
 * turns it back into a picture of the weather.
 */
.world-dial__glow[b-m89lmio475] {
    fill: var(--torch-dial-sky);
    opacity: 0.5;
    filter: blur(12px);
}

.world-dial__band[b-m89lmio475] {
    fill: none;
    stroke: var(--torch-dial-sky);
    stroke-width: 2;
    opacity: 0.75;
}

/* ---------------------------------------------------------------- engraved line-work */

.world-dial__ring[b-m89lmio475] {
    fill: none;
    stroke: var(--torch-accent-muted);
    stroke-width: 1;
    opacity: 0.34;
    animation: world-dial-breathe-b-m89lmio475 7s var(--torch-ease-out) infinite;
}

.world-dial__ring--slow[b-m89lmio475] {
    animation-duration: 9s;
    animation-delay: -3s;
}

.world-dial__ring--slower[b-m89lmio475] {
    animation-duration: 11s;
    animation-delay: -6s;
}

@keyframes world-dial-breathe-b-m89lmio475 {
    0%,
    100% {
        opacity: 0.22;
    }

    50% {
        opacity: 0.55;
    }
}

.world-dial__horizon[b-m89lmio475] {
    stroke: var(--torch-border-strong);
    stroke-width: 1;
}

.world-dial__tick[b-m89lmio475] {
    stroke: var(--torch-accent-muted);
    stroke-width: 1;
    opacity: 0.4;
}

.world-dial__tick.is-cardinal[b-m89lmio475] {
    stroke: var(--torch-accent);
    stroke-width: 1.5;
    opacity: 0.75;
}

.world-dial__numeral[b-m89lmio475] {
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-xs);
    letter-spacing: var(--torch-tracking-display);
    fill: var(--torch-text-muted);
    text-anchor: middle;
    dominant-baseline: central;
}

.world-dial__clock[b-m89lmio475] {
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-lg);
    letter-spacing: var(--torch-tracking-display);
    fill: var(--torch-text-primary);
    text-anchor: middle;
    dominant-baseline: central;
}

/* ---------------------------------------------------------------- the rete */

.world-dial__rete[b-m89lmio475] {
    fill: none;
    stroke: var(--torch-border);
    stroke-width: 1;
}

/*
 * One hand per body. The angle they open is the moon's elongation, which is the same number that
 * draws its phase — so the instrument shows why the disc looks the way it does.
 */
.world-dial__hand[b-m89lmio475] {
    stroke: var(--torch-accent-muted);
    stroke-width: 1;
    opacity: 0.45;
    stroke-dasharray: 2 5;
}

.world-dial__body[b-m89lmio475] {
    transition: opacity var(--torch-duration-slow) var(--torch-ease-out);
}

/* Below the horizon is not hidden — an instrument shows the whole mechanism, dimly. */
.world-dial__body.is-below[b-m89lmio475] {
    opacity: 0.3;
}

.world-dial__glyph[b-m89lmio475] {
    fill: none;
    stroke: var(--torch-accent-strong);
    stroke-width: 1.25;
}

.world-dial__ray[b-m89lmio475] {
    stroke: var(--torch-accent-strong);
    stroke-width: 1.25;
    stroke-linecap: round;
}

/* The lit share of the disc, engraved rather than painted: a wash, not a filled coin. */
.world-dial__moon-lit[b-m89lmio475] {
    fill: var(--torch-accent-strong);
    opacity: 0.42;
}

@media (prefers-reduced-motion: reduce) {

    /* base.css already collapses the duration; this stops the ring landing on a keyframe value. */
    .world-dial__ring[b-m89lmio475] {
        animation: none;
        opacity: 0.34;
    }
}
/* /Components/Pages/Admin/WorldYearRing.razor.rz.scp.css */
/*
 * The year ring. Same language as WorldDial: thin gold line-work, engraved ticks, Cinzel numerals,
 * one slow breath. Scoped is safe here because every selector matches markup this component
 * renders itself.
 */

.world-year[b-fx5hjwnh5x] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--torch-space-2);
}

.world-year__face[b-fx5hjwnh5x] {
    display: block;
    width: 100%;
    max-width: 12rem;
}

.world-year__note[b-fx5hjwnh5x] {
    font-size: var(--torch-text-xs);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--torch-text-muted);
    margin: 0;
}

.world-year__ring[b-fx5hjwnh5x] {
    fill: none;
    stroke: var(--torch-accent-muted);
    stroke-width: 1;
    opacity: 0.34;
    animation: world-year-breathe-b-fx5hjwnh5x 9s var(--torch-ease-out) infinite;
}

.world-year__ring--slow[b-fx5hjwnh5x] {
    animation-duration: 12s;
    animation-delay: -4s;
}

@keyframes world-year-breathe-b-fx5hjwnh5x {
    0%,
    100% {
        opacity: 0.22;
    }

    50% {
        opacity: 0.5;
    }
}

/* Seasons group the months; they do not label them. The one in force is the only lit arc. */
.world-year__season[b-fx5hjwnh5x] {
    fill: none;
    stroke: var(--torch-accent-muted);
    stroke-width: 2;
    stroke-linecap: round;
    opacity: 0.6;
    transition: stroke var(--torch-duration-normal) var(--torch-ease-out);
}

.world-year__season.is-current[b-fx5hjwnh5x] {
    stroke: var(--torch-accent);
    opacity: 0.85;
}

.world-year__tick[b-fx5hjwnh5x] {
    stroke: var(--torch-accent-muted);
    stroke-width: 1;
    opacity: 0.4;
}

.world-year__tick.is-quarter[b-fx5hjwnh5x] {
    stroke: var(--torch-accent);
    stroke-width: 1.5;
    opacity: 0.7;
}

.world-year__marker-stem[b-fx5hjwnh5x] {
    stroke: var(--torch-accent-strong);
    stroke-width: 1;
    opacity: 0.5;
}

.world-year__marker[b-fx5hjwnh5x] {
    fill: var(--torch-accent-strong);
}

.world-year__day[b-fx5hjwnh5x] {
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-lg);
    letter-spacing: var(--torch-tracking-display);
    fill: var(--torch-text-primary);
    text-anchor: middle;
    dominant-baseline: central;
}

.world-year__month[b-fx5hjwnh5x] {
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-xs);
    letter-spacing: var(--torch-tracking-eyebrow);
    fill: var(--torch-text-muted);
    text-anchor: middle;
    dominant-baseline: central;
}

@media (prefers-reduced-motion: reduce) {

    .world-year__ring[b-fx5hjwnh5x] {
        animation: none;
        opacity: 0.34;
    }
}
/* /Components/Pages/BindingRules.razor.rz.scp.css */
.torch-rules__hero[b-zcl6a2ogy6] {
    max-width: var(--torch-prose-width);
    margin: 0 auto;
    padding: var(--torch-space-16) var(--torch-space-8) var(--torch-space-12);
    text-align: center;
}

.torch-rules__hero h1[b-zcl6a2ogy6] {
    margin-bottom: var(--torch-space-4);
}

.torch-rules__lead[b-zcl6a2ogy6] {
    color: var(--torch-text-secondary);
    font-size: var(--torch-text-md);
    margin: 0;
}

.torch-rules__updated[b-zcl6a2ogy6] {
    color: var(--torch-text-muted);
    font-family: var(--torch-font-mono);
    font-size: var(--torch-text-xs);
    margin: var(--torch-space-4) 0 0;
}

.torch-rules__summary[b-zcl6a2ogy6] {
    padding-block: var(--torch-space-8);
}

.torch-rules__summary-inner[b-zcl6a2ogy6] {
    max-width: var(--torch-prose-width);
    margin: 0 auto;
    padding-inline: var(--torch-space-8);
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: var(--torch-space-6);
}

.torch-rules__seal[b-zcl6a2ogy6] {
    display: block;
    width: var(--torch-space-12);
    height: var(--torch-space-12);
    border: 1px solid var(--torch-accent-muted);
    transform: rotate(45deg);
    box-shadow: var(--torch-shadow-glow), var(--torch-chisel);
}

.torch-rules__seal[b-zcl6a2ogy6]::after {
    content: "";
    display: block;
    width: var(--torch-space-2);
    height: var(--torch-space-2);
    margin: calc(50% - var(--torch-space-1));
    background: var(--torch-accent);
    transform: rotate(45deg);
}

.torch-rules__summary h2[b-zcl6a2ogy6] {
    font-size: var(--torch-text-lg);
    margin: 0 0 var(--torch-space-2);
}

.torch-rules__summary p[b-zcl6a2ogy6] {
    color: var(--torch-text-secondary);
    margin: 0;
}

.torch-rules__principles[b-zcl6a2ogy6] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--torch-space-2) var(--torch-space-8);
    margin: var(--torch-space-4) 0 0;
    padding-left: var(--torch-space-6);
    color: var(--torch-text-secondary);
}

.torch-rules__principles li[b-zcl6a2ogy6]::marker {
    color: var(--torch-accent-muted);
}

.torch-rules__layout[b-zcl6a2ogy6] {
    max-width: var(--torch-content-width);
    margin: 0 auto;
    padding: var(--torch-space-16) var(--torch-space-8);
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 3fr);
    align-items: start;
    gap: var(--torch-space-12);
}

.torch-rules__toc[b-zcl6a2ogy6] {
    position: sticky;
    top: calc(var(--torch-space-16) + var(--torch-space-6));
    max-height: calc(100vh - var(--torch-space-16) - var(--torch-space-12));
    overflow-y: auto;
    scrollbar-color: var(--torch-accent-muted) var(--torch-surface-2);
    scrollbar-width: thin;
    padding: var(--torch-space-6);
    background: var(--torch-surface-1);
    border: 1px solid var(--torch-border);
    border-radius: var(--torch-radius-md);
    box-shadow: var(--torch-chisel);
}

.torch-rules__toc[b-zcl6a2ogy6]::-webkit-scrollbar {
    width: var(--torch-space-2);
}

.torch-rules__toc[b-zcl6a2ogy6]::-webkit-scrollbar-track {
    background: var(--torch-surface-2);
    border-radius: var(--torch-radius-md);
}

.torch-rules__toc[b-zcl6a2ogy6]::-webkit-scrollbar-thumb {
    background: var(--torch-accent-muted);
    border-radius: var(--torch-radius-md);
}

.torch-rules__toc[b-zcl6a2ogy6]::-webkit-scrollbar-thumb:hover {
    background: var(--torch-accent-strong);
}

.torch-rules__toc > p[b-zcl6a2ogy6] {
    color: var(--torch-accent);
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-xs);
    font-weight: 600;
    letter-spacing: var(--torch-tracking-eyebrow);
    text-transform: uppercase;
    margin: 0 0 var(--torch-space-4);
}

.torch-rules__toc ol[b-zcl6a2ogy6] {
    display: flex;
    flex-direction: column;
    gap: var(--torch-space-3);
    margin: 0;
    padding-left: var(--torch-space-6);
    color: var(--torch-text-muted);
    font-family: var(--torch-font-mono);
    font-size: var(--torch-text-xs);
}

.torch-rules__toc a[b-zcl6a2ogy6] {
    color: var(--torch-text-secondary);
    text-decoration: none;
    transition: color var(--torch-duration-fast) var(--torch-ease-out);
}

.torch-rules__toc a:hover[b-zcl6a2ogy6] {
    color: var(--torch-accent-strong);
}

.torch-rules__document[b-zcl6a2ogy6] {
    min-width: 0;
    background: var(--torch-surface-1);
    border: 1px solid var(--torch-border);
    border-radius: var(--torch-radius-lg);
    box-shadow: var(--torch-shadow-md), var(--torch-chisel);
    padding: 0 var(--torch-space-8);
}

.torch-rules__section[b-zcl6a2ogy6] {
    position: relative;
    scroll-margin-top: calc(var(--torch-space-16) + var(--torch-space-6));
    padding: var(--torch-space-12) 0;
}

.torch-rules__section + .torch-rules__section[b-zcl6a2ogy6] {
    border-top: 1px solid var(--torch-border);
}

.torch-rules__number[b-zcl6a2ogy6] {
    color: var(--torch-accent-muted);
    font-family: var(--torch-font-mono);
    font-size: var(--torch-text-xs);
    margin: 0 0 var(--torch-space-2);
}

.torch-rules__section h2[b-zcl6a2ogy6] {
    margin: 0 0 var(--torch-space-4);
    font-size: var(--torch-text-xl);
}

.torch-rules__section:target h2[b-zcl6a2ogy6] {
    color: var(--torch-accent-strong);
}

.torch-rules__section p[b-zcl6a2ogy6],
.torch-rules__section li[b-zcl6a2ogy6] {
    color: var(--torch-text-secondary);
}

.torch-rules__section > p:not(.torch-rules__number, .torch-rules__note)[b-zcl6a2ogy6] {
    margin: 0 0 var(--torch-space-4);
}

.torch-rules__section > p:last-child[b-zcl6a2ogy6] {
    margin-bottom: 0;
}

.torch-rules__section ul[b-zcl6a2ogy6],
.torch-rules__section ol[b-zcl6a2ogy6] {
    display: flex;
    flex-direction: column;
    gap: var(--torch-space-3);
    margin: var(--torch-space-4) 0 0;
    padding-left: var(--torch-space-6);
}

.torch-rules__section li[b-zcl6a2ogy6]::marker {
    color: var(--torch-accent-muted);
}

.torch-rules__clauses[b-zcl6a2ogy6] {
    font-variant-numeric: tabular-nums;
}

.torch-rules__clauses li[b-zcl6a2ogy6] {
    padding-left: var(--torch-space-2);
}

.torch-rules__table-wrap[b-zcl6a2ogy6] {
    margin-top: var(--torch-space-6);
    overflow-x: auto;
    border: 1px solid var(--torch-border);
    border-radius: var(--torch-radius-sm);
}

.torch-rules__table-wrap table[b-zcl6a2ogy6] {
    width: 100%;
    border-collapse: collapse;
}

.torch-rules__table-wrap th[b-zcl6a2ogy6],
.torch-rules__table-wrap td[b-zcl6a2ogy6] {
    padding: var(--torch-space-4);
    text-align: left;
    vertical-align: top;
}

.torch-rules__table-wrap th[b-zcl6a2ogy6] {
    color: var(--torch-accent);
    background: var(--torch-surface-2);
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-xs);
    letter-spacing: var(--torch-tracking-eyebrow);
    text-transform: uppercase;
}

.torch-rules__table-wrap td[b-zcl6a2ogy6] {
    color: var(--torch-text-secondary);
}

.torch-rules__table-wrap tr + tr[b-zcl6a2ogy6],
.torch-rules__table-wrap tbody[b-zcl6a2ogy6] {
    border-top: 1px solid var(--torch-border);
}

.torch-rules__table-wrap th + th[b-zcl6a2ogy6],
.torch-rules__table-wrap td + td[b-zcl6a2ogy6] {
    border-left: 1px solid var(--torch-border);
}

.torch-rules__note[b-zcl6a2ogy6] {
    margin: var(--torch-space-6) 0 0;
    padding: var(--torch-space-4) var(--torch-space-6);
    color: var(--torch-text-primary);
    background: var(--torch-surface-2);
    border-left: var(--torch-space-1) solid var(--torch-accent-muted);
    border-radius: var(--torch-radius-sm);
    box-shadow: var(--torch-chisel);
}

@media (max-width: 52rem) {
    .torch-rules__hero[b-zcl6a2ogy6] {
        padding: var(--torch-space-12) var(--torch-space-4);
    }

    .torch-rules__summary-inner[b-zcl6a2ogy6] {
        padding-inline: var(--torch-space-4);
    }

    .torch-rules__layout[b-zcl6a2ogy6] {
        grid-template-columns: 1fr;
        padding: var(--torch-space-12) var(--torch-space-4);
        gap: var(--torch-space-8);
    }

    .torch-rules__toc[b-zcl6a2ogy6] {
        position: static;
        max-height: none;
    }

    .torch-rules__document[b-zcl6a2ogy6] {
        padding-inline: var(--torch-space-6);
    }

    .torch-rules__principles[b-zcl6a2ogy6] {
        grid-template-columns: 1fr;
    }
}
/* /Components/Pages/Design.razor.rz.scp.css */
.torch-design-page[b-k2vxzd8r1y] {
    max-width: 60rem;
    margin: 0 auto;
    padding: var(--torch-space-16) var(--torch-space-8);
    display: flex;
    flex-direction: column;
    gap: var(--torch-space-16);
}

.torch-design-page__hero p[b-k2vxzd8r1y] {
    color: var(--torch-text-secondary);
    max-width: 60ch;
}

.torch-design-page__note[b-k2vxzd8r1y] {
    color: var(--torch-text-secondary);
    max-width: 68ch;
    margin-bottom: var(--torch-space-6);
}

.torch-design-page__swatches[b-k2vxzd8r1y] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--torch-space-4);
}

.torch-design-page__swatch[b-k2vxzd8r1y] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--torch-space-1);
    font-size: var(--torch-text-sm);
    color: var(--torch-text-secondary);
}

.torch-design-page__swatch code[b-k2vxzd8r1y] {
    font-size: var(--torch-text-xs);
    color: var(--torch-text-muted);
}

.torch-design-page__swatch-color[b-k2vxzd8r1y] {
    width: 72px;
    height: 72px;
    border-radius: var(--torch-radius-md);
    border: 1px solid var(--torch-border);
    box-shadow: var(--torch-shadow-sm);
}

.torch-design-page__type > * + *[b-k2vxzd8r1y] {
    margin-top: var(--torch-space-4);
}

/* The panel demo is inset from the page so its own hairlines and vignette are visible; on a
   real page it spans the full viewport width. */
.torch-design-page__panel[b-k2vxzd8r1y] {
    border-radius: var(--torch-radius-lg);
    padding: var(--torch-space-12) var(--torch-space-8);
    text-align: center;
}

.torch-design-page__panel p[b-k2vxzd8r1y] {
    color: var(--torch-text-secondary);
    margin: 0;
}

.torch-design-page__row[b-k2vxzd8r1y] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--torch-space-3);
    align-items: center;
}

.torch-design-page__row + .torch-design-page__row[b-k2vxzd8r1y] {
    margin-top: var(--torch-space-4);
}

.torch-design-page__stack[b-k2vxzd8r1y] {
    display: flex;
    flex-direction: column;
    gap: var(--torch-space-3);
}

@media (max-width: 40rem) {
    .torch-design-page[b-k2vxzd8r1y] {
        padding-inline: var(--torch-space-4);
    }
}
/* /Components/Pages/Error.razor.rz.scp.css */
.torch-error-page__request-id[b-dk40ax6u1h] {
    font-size: var(--torch-text-sm);
    color: var(--torch-text-muted);
}

.torch-error-page__request-id code[b-dk40ax6u1h] {
    font-family: var(--torch-font-mono);
}
/* /Components/Pages/Home.razor.rz.scp.css */
.torch-hero[b-y1ktyqxnbw] {
    position: relative;
    /* Tall enough to read as a poster rather than as a banner, but still short enough that the
       news panel's top edge shows at the fold on a laptop — the promise of more below is what
       stops a full-viewport hero feeling like a dead end. */
    min-height: min(84vh, 46rem);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: #07111c;
}

/*
 * Fades the hero into the panel below instead of cutting between two differently-lit blocks.
 *
 * Taller than it was, and with a stop in the middle, because a two-stop linear ramp resolves in a
 * straight line while the artwork's foreground darkens on a curve — the two disagreed somewhere
 * around the fold and left a visible flat band above the news panel. Landing 45% of the way to
 * the surface colour at 58% of the height bends the ramp to match the picture.
 */
.torch-hero[b-y1ktyqxnbw]::after {
    content: "";
    position: absolute;
    inset: auto 0 0 0;
    height: 15rem;
    background: linear-gradient(180deg,
            transparent 0%,
            color-mix(in srgb, var(--torch-surface-1) 45%, transparent) 58%,
            var(--torch-surface-1) 100%);
    pointer-events: none;
}

.torch-hero__bg-pan[b-y1ktyqxnbw] {
    position: absolute;
    inset: 0;
}

.torch-hero__bg-image[b-y1ktyqxnbw] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
}

/*
 * The grade. Colour and depth only — legibility is the focus layer's job now, and separating the
 * two is what let both get much lighter.
 *
 * Gone: a warm bloom at 50%/74%. The intent was the tower's firelight spilling forward, but the
 * tower's fire is at 47% and the bloom was seated a quarter of the frame below it, over foreground
 * rock that has no light source at all. Orange haze on unlit stone does not read as firelight, it
 * reads as a smudge on the lens — and it landed exactly behind the welcome line and the CTA, so
 * the two most important elements sat in the one part of the frame that looked dirty. The heat in
 * this hero now comes only from sources that are actually in the picture: the wordmark's own
 * cast, the ember diamonds, the plate's heat bloom, and the rising particles.
 *
 * The vignette stays but at roughly two-thirds strength with a much wider clear centre (44% vs
 * 36%). At the old values it was doing double duty — shaping the frame *and* buying text contrast
 * — and the second job had crushed the mountains and the aurora, which is most of what makes the
 * artwork look expensive. The focus layer buys that contrast locally instead.
 */
.torch-hero__scrim[b-y1ktyqxnbw] {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(126% 90% at 50% 44%, transparent 44%, rgba(2, 6, 12, 0.42) 100%),
        linear-gradient(90deg, rgba(3, 9, 17, 0.46) 0%, rgba(3, 9, 17, 0.08) 48%, rgba(3, 9, 17, 0.36) 100%),
        linear-gradient(180deg, rgba(3, 9, 17, 0.34) 0%, rgba(3, 9, 17, 0.04) 32%, rgba(3, 9, 17, 0.58) 100%);
}

/*
 * The focus pull — a defocused bed for the copy instead of a coloured wash over it.
 *
 * This is how the shot would be taken with a real lens: the subject (the wordmark and the words
 * under it) stays sharp and the scene behind it falls out of focus, so type separates from art by
 * *sharpness* rather than by having something tinted laid on top. A blur cannot introduce a hue
 * the picture does not already have, which is exactly why it succeeds where the amber bloom
 * failed.
 *
 * Three filters, each doing one job:
 *   blur       — the separation itself.
 *   brightness — the contrast the vignette used to buy, now spent only where text actually is
 *                rather than across the whole frame.
 *   saturate   — a touch out, because blurring alone leaves the defocused region reading slightly
 *                more colourful than its surroundings.
 *
 * The radial mask is load-bearing: without it the blur ends on a hard rectangle edge, which is the
 * single most obvious way this effect gives itself away. It fades to nothing well inside the
 * element's own box so the edge-clamping artefacts a backdrop blur produces at its boundary are
 * never composited at a visible alpha.
 *
 * Cost: this composites a blur over an animated background every frame. That is already an
 * accepted cost in this product — the sticky header runs backdrop-filter: blur(14px) over this
 * same panning artwork — and the region is bounded rather than full-bleed.
 */
.torch-hero__focus[b-y1ktyqxnbw] {
    position: absolute;
    left: 50%;
    top: 50%;
    width: min(72rem, 124%);
    height: min(44rem, 108%);
    transform: translate(-50%, -50%);
    pointer-events: none;
    -webkit-backdrop-filter: blur(16px) brightness(0.74) saturate(0.92);
    backdrop-filter: blur(16px) brightness(0.74) saturate(0.92);
    -webkit-mask-image: radial-gradient(closest-side,
            rgba(0, 0, 0, 1) 0%,
            rgba(0, 0, 0, 0.95) 30%,
            rgba(0, 0, 0, 0.55) 62%,
            rgba(0, 0, 0, 0) 100%);
    mask-image: radial-gradient(closest-side,
            rgba(0, 0, 0, 1) 0%,
            rgba(0, 0, 0, 0.95) 30%,
            rgba(0, 0, 0, 0.55) 62%,
            rgba(0, 0, 0, 0) 100%);
}

/* Without backdrop-filter there is nothing to mask, so drop the mask too and let a plain radial
   darkening do the legibility job on its own — the same shape, minus the depth of field. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .torch-hero__focus[b-y1ktyqxnbw] {
        -webkit-mask-image: none;
        mask-image: none;
        background: radial-gradient(closest-side,
                rgba(3, 8, 14, 0.6) 0%,
                rgba(3, 8, 14, 0.42) 54%,
                rgba(3, 8, 14, 0) 100%);
    }
}

/*
 * The proscenium: four hairline corner marks set in from the edge of the frame.
 *
 * Same move as the inner rim on .torch-button--hero and the gold inlay on the architecture slabs —
 * a line held a few millimetres inside the rim is what makes a struck plate read as finished
 * rather than as cut. At full-bleed scale it turns the artwork from a photograph the page happens
 * to be sitting on into a plate the page is presenting, which is the whole difference between a
 * stock header image and a title card.
 *
 * Eight background layers rather than four elements or a masked border: corner marks are the one
 * ornament where the markup cost of doing it "properly" exceeds the cost of the gradients, and
 * this stays a single empty div.
 *
 * Deliberately at 0.14 alpha. Loud enough to register once, quiet enough that nobody can say what
 * it is — pushed further it stops being a frame and starts being a table border.
 */
.torch-hero__frame[b-y1ktyqxnbw] {
    --torch-hero-corner: rgba(224, 180, 99, 0.14);
    --torch-hero-corner-len: clamp(1.5rem, 3.5vw, 2.75rem);
    position: absolute;
    inset: clamp(0.75rem, 2.2vw, 2rem);
    z-index: 2;
    pointer-events: none;
    background:
        linear-gradient(var(--torch-hero-corner), var(--torch-hero-corner)) 0 0 / var(--torch-hero-corner-len) 1px no-repeat,
        linear-gradient(var(--torch-hero-corner), var(--torch-hero-corner)) 0 0 / 1px var(--torch-hero-corner-len) no-repeat,
        linear-gradient(var(--torch-hero-corner), var(--torch-hero-corner)) 100% 0 / var(--torch-hero-corner-len) 1px no-repeat,
        linear-gradient(var(--torch-hero-corner), var(--torch-hero-corner)) 100% 0 / 1px var(--torch-hero-corner-len) no-repeat,
        linear-gradient(var(--torch-hero-corner), var(--torch-hero-corner)) 0 100% / var(--torch-hero-corner-len) 1px no-repeat,
        linear-gradient(var(--torch-hero-corner), var(--torch-hero-corner)) 0 100% / 1px var(--torch-hero-corner-len) no-repeat,
        linear-gradient(var(--torch-hero-corner), var(--torch-hero-corner)) 100% 100% / var(--torch-hero-corner-len) 1px no-repeat,
        linear-gradient(var(--torch-hero-corner), var(--torch-hero-corner)) 100% 100% / 1px var(--torch-hero-corner-len) no-repeat;
    animation: torch-hero-frame-in-b-y1ktyqxnbw 1.4s var(--torch-ease-out) 520ms both;
}

/* The frame arrives last, after the copy has finished rising — it closes the composition, so it
   cannot be there before there is anything to close. It only fades: a 14px rise like .torch-rise
   would be read as the whole page settling rather than as one element arriving. */
@keyframes torch-hero-frame-in-b-y1ktyqxnbw {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

/*
 * Optically centred, not mathematically centred. The logo carries almost all of the block's visual
 * mass at its top, so a stack that is centred by box lands *low* to the eye; the extra bottom
 * padding lifts it back onto the upper third and hands the foreground rock the space it wants.
 *
 * `width`, not `max-width`. This is the hero's only flex item, so with a max-width alone its
 * flex-basis resolves to `auto` — shrink-to-fit — and the column silently becomes exactly as wide
 * as its longest line of copy. That went unnoticed while the tagline was a long sentence; the
 * moment it became four words, the column collapsed to about 330px and took the nameplate's
 * hairlines down with it, because they are `flex: 1 1 auto` and there was no free space left to
 * grow into. The measuring stick for this column is the design, not the copy.
 */
.torch-hero__content[b-y1ktyqxnbw] {
    position: relative;
    z-index: 1;
    text-align: center;
    width: min(40rem, 100%);
    padding: var(--torch-space-16) var(--torch-space-8) var(--torch-space-24);
}

.torch-hero__logo-heading[b-y1ktyqxnbw] {
    /* The logo art carries its own "Legendy dračí hlídky" subtitle, so the tagline needs real
       separation from it or the two small lines read as one crowded stack. */
    margin: 0 0 var(--torch-space-6);
}

.torch-hero__logo[b-y1ktyqxnbw] {
    height: clamp(96px, 22vh, 220px);
    width: auto;
    max-width: 80vw;
}

/*
 * Four words, so it can afford to be set as a line of a title card rather than as a sentence: the
 * display face, tracked out, and given room. It also carries the cast that every piece of hero
 * copy now needs — with the vignette down to two-thirds strength the type no longer has a
 * uniformly dark plate under it, so each element earns its own contrast locally.
 */
.torch-hero__tagline[b-y1ktyqxnbw] {
    color: var(--torch-text-secondary);
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-lg);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-wrap: balance;
    text-shadow: 0 1px 14px rgba(2, 6, 12, 0.75);
    max-width: 38rem;
    margin: 0 auto var(--torch-space-8);
}

/*
 * The ornament between the promise and the action, sized down from the section-heading version by
 * .torch-rule in the design system — a beat, not a divider.
 *
 * It overrides the flank colour because every other ornament in the product sits on a flat
 * surface, where --torch-border is a visible hairline. Here it sits on a photograph, where that
 * value disappears completely and leaves the diamond floating on its own as a stray speck. Warm
 * translucent amber survives whatever the artwork is doing behind it.
 */
.torch-hero__rule[b-y1ktyqxnbw] {
    --torch-rule-flank: rgba(224, 180, 99, 0.4);
    margin: 0 auto var(--torch-space-6);
    max-width: 20rem;
}

.torch-hero__rule .torch-rule__diamond[b-y1ktyqxnbw] {
    background: var(--torch-accent);
    box-shadow: 0 0 10px rgba(201, 151, 63, 0.6);
}

/*
 * The nameplate — the flanked ornament's fourth volume, and the signed-in hero's answer to the
 * bare .torch-hero__rule above.
 *
 * It replaces "Vítej zpět, <name>." as a grey sentence floating between the rule and the button.
 * That line had three problems at once: it was a fourth element in a stack that already read as
 * crowded, it was the least considered typography on the page, and it sat directly under an
 * ornament that was occupying the same slot for no reason. Folding the two into one element
 * removes a row *and* upgrades the thing it removes it in favour of — the ornament simply earns a
 * label once we know who is looking, exactly the way .torch-section-heading is this same
 * composition with an <h2> in it.
 *
 * Set in the display face at eyebrow tracking so it reads as struck into the plate rather than
 * typed onto it, and kept off the accent entirely: gold is spent on the diamonds and on the CTA
 * below, and a player's name competing with the one button in the frame would be a poor trade.
 * The name is bone white with a faint warm cast, so it is clearly the brighter of the two words
 * without introducing a third colour.
 */
.torch-hero__nameplate[b-y1ktyqxnbw] {
    /* Longer flanks than any other member of the family (.torch-rule uses 4.5rem). The hairlines
       are gradients that only become visible over their last third, so at the shorter length they
       rendered as two dashes bumped up against the diamonds rather than as lines running out of
       them — and this ornament is carrying a label, which needs the extra span to sit inside. */
    --torch-rule-flank: rgba(224, 180, 99, 0.34);
    --torch-rule-flank-max: 8.5rem;
    max-width: 100%;
    margin: 0 auto var(--torch-space-8);
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-xs);
    font-weight: 600;
    letter-spacing: var(--torch-tracking-eyebrow);
    text-transform: uppercase;
}

/* Full-strength diamonds, unlike the bare rule's muted ones: this is the ornament in its loud
   volume, the same as the ones flanking a section heading. */
.torch-hero__nameplate .torch-rule__diamond[b-y1ktyqxnbw] {
    background: var(--torch-accent);
    box-shadow: 0 0 10px rgba(201, 151, 63, 0.55);
}

.torch-hero__nameplate-label[b-y1ktyqxnbw] {
    position: relative;
    color: var(--torch-text-muted);
    text-shadow: 0 1px 10px rgba(2, 6, 12, 0.7);
    padding-right: var(--torch-space-3);
}

/*
 * A hairline between the greeting and the name — the same fading vertical divider the header uses
 * to fence sign-out off from the nav, so the two read as one motif.
 *
 * It is doing real work, not decoration. The greeting rotates, and several of them end in a word
 * that could plausibly *be* a name ("Hlídka hlásí: žiješ", then "Dev Admin"); at eyebrow tracking,
 * in uppercase, with only a colour change separating them, a gap alone left it ambiguous where
 * the world stopped talking and the player began.
 */
.torch-hero__nameplate-label[b-y1ktyqxnbw]::after {
    content: "";
    position: absolute;
    right: 0;
    top: 50%;
    width: 1px;
    height: 0.85rem;
    transform: translateY(-50%);
    background: linear-gradient(180deg, transparent, var(--torch-border-strong), transparent);
}

/* Player names are user-supplied and can be long; `min-width: 0` lets this shrink and break
   instead of forcing the flanks past the content column and out of the frame. */
.torch-hero__nameplate-name[b-y1ktyqxnbw] {
    min-width: 0;
    overflow-wrap: anywhere;
    color: var(--torch-text-primary);
    text-shadow: 0 0 18px rgba(224, 180, 99, 0.2), 0 1px 10px rgba(2, 6, 12, 0.7);
}

/* ---------------------------------------------------------------- news teaser */

.torch-news-teaser[b-y1ktyqxnbw] {
    padding-block: var(--torch-space-16);
}

.torch-news-teaser__inner[b-y1ktyqxnbw] {
    max-width: var(--torch-content-width);
    margin: 0 auto;
    padding-inline: var(--torch-space-8);
    text-align: center;
}

.torch-news-teaser__empty[b-y1ktyqxnbw] {
    color: var(--torch-text-muted);
}

.torch-news-teaser__list[b-y1ktyqxnbw] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
    gap: var(--torch-space-4);
    margin-bottom: var(--torch-space-8);
    text-align: left;
}

/* The whole card is the link target — a small "read more" affordance inside a card that is
   already clickable is just a second thing to aim at. */
.torch-news-teaser__link[b-y1ktyqxnbw] {
    display: block;
    text-decoration: none;
    color: inherit;
    border-radius: var(--torch-radius-lg);
}

/* TorchCard renders this element, so the rule needs ::deep: the scope attribute lands on the
   link above it, and the card is matched unscoped below. Without this the equal-height row
   silently does nothing. */
.torch-news-teaser__link[b-y1ktyqxnbw]  .torch-card {
    height: 100%;
}

.torch-news-teaser__meta[b-y1ktyqxnbw] {
    display: flex;
    align-items: center;
    gap: var(--torch-space-3);
    color: var(--torch-text-muted);
    font-size: var(--torch-text-xs);
}

.torch-news-teaser__item h3[b-y1ktyqxnbw] {
    margin: var(--torch-space-3) 0 0;
}

.torch-news-teaser__excerpt[b-y1ktyqxnbw] {
    color: var(--torch-text-secondary);
    font-size: var(--torch-text-base);
    margin: 0;
}

@media (max-width: 40rem) {
    /* On a phone the content column is nearly the whole frame, so the focus ellipse has no room to
       fade before the edges — shrink it and soften the blur so it stays a depth cue rather than
       becoming a full-screen frosted panel. */
    .torch-hero__focus[b-y1ktyqxnbw] {
        width: 132%;
        height: 76%;
        -webkit-backdrop-filter: blur(10px) brightness(0.78) saturate(0.94);
        backdrop-filter: blur(10px) brightness(0.78) saturate(0.94);
    }

    /* Corner marks 24px apart on a narrow screen read as a box drawn around the page. Below this
       width the frame has nothing left to frame. */
    .torch-hero__frame[b-y1ktyqxnbw] {
        display: none;
    }

    .torch-hero__content[b-y1ktyqxnbw] {
        padding-bottom: var(--torch-space-16);
    }

    /* The flanks are the first thing to give: a name plus two 5rem hairlines does not fit a phone,
       and the ornament still reads with the diamonds alone. */
    .torch-hero__nameplate[b-y1ktyqxnbw] {
        --torch-rule-flank-max: 1.25rem;
    }

    .torch-news-teaser__inner[b-y1ktyqxnbw] {
        padding-inline: var(--torch-space-4);
    }
}
/* /Components/Pages/News.razor.rz.scp.css */
.torch-news-page[b-m71bbo6aiv] {
    max-width: 56rem;
    margin: 0 auto;
    padding: var(--torch-space-16) var(--torch-space-8);
}

.torch-news-page__header[b-m71bbo6aiv] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--torch-space-4);
    margin-bottom: var(--torch-space-12);
}

.torch-news-page__header h1[b-m71bbo6aiv] {
    margin: 0;
}

.torch-news-page__list[b-m71bbo6aiv] {
    display: flex;
    flex-direction: column;
    gap: var(--torch-space-6);
}

/* The whole card is the link — a separate "read more" anchor inside an already-clickable card
   is just a second, smaller target for the same destination. The visible "Číst dál" is a cue,
   not its own link. */
.torch-news-page__link[b-m71bbo6aiv] {
    display: block;
    text-decoration: none;
    color: inherit;
    border-radius: var(--torch-radius-lg);
}

.torch-news-page__meta[b-m71bbo6aiv] {
    display: flex;
    align-items: center;
    gap: var(--torch-space-3);
    font-size: var(--torch-text-xs);
    color: var(--torch-text-muted);
}

.torch-news-page__card h2[b-m71bbo6aiv] {
    font-size: var(--torch-text-lg);
    color: var(--torch-text-primary);
    margin: var(--torch-space-3) 0 0;
    transition: color var(--torch-duration-fast) var(--torch-ease-out);
}

.torch-news-page__link:hover .torch-news-page__card h2[b-m71bbo6aiv] {
    color: var(--torch-accent-strong);
}

.torch-news-page__excerpt[b-m71bbo6aiv] {
    color: var(--torch-text-secondary);
    margin: 0;
}

.torch-news-page__more[b-m71bbo6aiv] {
    display: inline-block;
    margin-top: var(--torch-space-4);
    font-size: var(--torch-text-sm);
    font-weight: 600;
    color: var(--torch-accent-strong);
}

@media (max-width: 40rem) {
    .torch-news-page[b-m71bbo6aiv] {
        padding: var(--torch-space-12) var(--torch-space-4);
    }
}
/* /Components/Pages/NewsDetail.razor.rz.scp.css */
.torch-news-detail-page[b-xy67utcjo9] {
    max-width: var(--torch-prose-width);
    margin: 0 auto;
    padding: var(--torch-space-12) var(--torch-space-8) var(--torch-space-16);
}

.torch-news-detail-page__back[b-xy67utcjo9] {
    margin-bottom: var(--torch-space-8);
}

.torch-news-detail-page__header[b-xy67utcjo9] {
    padding-bottom: var(--torch-space-6);
    border-bottom: 1px solid var(--torch-border);
    margin-bottom: var(--torch-space-8);
}

.torch-news-detail-page__header h1[b-xy67utcjo9] {
    margin: var(--torch-space-4) 0 0;
}

.torch-news-detail-page__meta[b-xy67utcjo9] {
    display: flex;
    align-items: center;
    gap: var(--torch-space-3);
    font-size: var(--torch-text-xs);
    color: var(--torch-text-muted);
}

.torch-news-detail-page__image[b-xy67utcjo9] {
    width: 100%;
    border-radius: var(--torch-radius-lg);
    border: 1px solid var(--torch-border);
    box-shadow: var(--torch-shadow-md);
    margin-bottom: var(--torch-space-8);
}

/* Long-form copy gets a slightly looser measure than UI text. */
.torch-news-detail-page__body[b-xy67utcjo9] {
    font-size: var(--torch-text-md);
    line-height: 1.75;
}

@media (max-width: 40rem) {
    .torch-news-detail-page[b-xy67utcjo9] {
        padding-inline: var(--torch-space-4);
    }
}
/* /Components/Pages/Play.razor.rz.scp.css */
.torch-play[b-jhwgisk101] {
    position: relative;
    min-height: 100vh;
}

.torch-play__bg[b-jhwgisk101] {
    position: fixed;
    inset: 0;
    z-index: 46;
}

.torch-play__bg-image[b-jhwgisk101] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
}

.torch-play__scrim[b-jhwgisk101] {
    position: fixed;
    inset: 0;
    z-index: 47;
    background:
        linear-gradient(90deg, rgba(3, 9, 17, 0.65) 0%, rgba(3, 9, 17, 0.25) 48%, rgba(3, 9, 17, 0.5) 100%),
        linear-gradient(180deg, rgba(3, 9, 17, 0.18) 0%, rgba(3, 9, 17, 0.72) 100%);
}

.torch-play__panel[b-jhwgisk101] {
    position: relative;
    z-index: 48;
    display: flex;
    min-height: 100vh;
    max-width: 26rem;
    margin: 0 auto;
    align-items: center;
    justify-content: center;
}

.torch-play__panel[b-jhwgisk101]  .torch-card__body {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--torch-space-4);
    text-align: center;
    width: 100%;
}

.torch-play__logo[b-jhwgisk101] {
    height: clamp(96px, 22vh, 200px);
    width: auto;
    max-width: 70vw;
}

/* The CTA class is handed to TorchButton, so it needs ::deep — the scope attribute lands on
   the wrapper above, and the button element itself is matched unscoped. */
.torch-play__panel[b-jhwgisk101]  .torch-play__cta {
    width: 100%;
}
/* /Components/Pages/ReportBug.razor.rz.scp.css */
.torch-report-bug[b-5a3gujfdjg] {
    max-width: 42rem;
    margin: 0 auto;
    padding: var(--torch-space-16) var(--torch-space-8);
    display: flex;
    flex-direction: column;
    gap: var(--torch-space-6);
}

.torch-report-bug h1[b-5a3gujfdjg] {
    margin: 0;
}

.torch-report-bug__intro[b-5a3gujfdjg] {
    color: var(--torch-text-muted);
}

.torch-report-bug__description[b-5a3gujfdjg] {
    min-height: 8rem;
    resize: vertical;
}

.torch-report-bug__suggestions[b-5a3gujfdjg] {
    border: 1px solid var(--torch-border);
    border-radius: var(--torch-radius-md);
    padding: var(--torch-space-3) var(--torch-space-4);
}

.torch-report-bug__suggestions-heading[b-5a3gujfdjg] {
    margin: 0 0 var(--torch-space-2);
    font-size: var(--torch-text-sm);
    color: var(--torch-text-muted);
}

.torch-report-bug__suggestions ul[b-5a3gujfdjg] {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--torch-space-2);
}

.torch-report-bug__suggestions li[b-5a3gujfdjg] {
    display: flex;
    align-items: center;
    gap: var(--torch-space-2);
}

.torch-report-bug__context summary[b-5a3gujfdjg] {
    cursor: pointer;
    color: var(--torch-text-muted);
    font-size: var(--torch-text-sm);
}

.torch-report-bug__context dl[b-5a3gujfdjg] {
    margin: var(--torch-space-3) 0 0;
    display: grid;
    grid-template-columns: 10rem 1fr;
    row-gap: var(--torch-space-2);
    column-gap: var(--torch-space-6);
    font-size: var(--torch-text-sm);
}

.torch-report-bug__context dt[b-5a3gujfdjg] {
    color: var(--torch-text-muted);
}

.torch-report-bug__context dd[b-5a3gujfdjg] {
    margin: 0;
    color: var(--torch-text-primary);
}

.torch-report-bug__actions[b-5a3gujfdjg] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--torch-space-3);
}

@media (max-width: 40rem) {
    .torch-report-bug[b-5a3gujfdjg] {
        padding-inline: var(--torch-space-4);
    }

    .torch-report-bug__context dl[b-5a3gujfdjg] {
        grid-template-columns: 1fr;
        row-gap: var(--torch-space-1);
    }
}
/* /Components/Shared/ArchitectureDiagram.razor.rz.scp.css */
/*
 * The frame, the connectors and the legend. Slab styling lives with ArchitectureSlab, which
 * renders it.
 *
 * Motion is atmosphere, not information: a pulse crossing a connector says nothing the static line
 * does not. 14 s per connector, mostly idle. base.css collapses it under prefers-reduced-motion.
 */

.torch-arch__scroll[b-8zbvqevfm4] {
    overflow-x: auto;
    padding-bottom: var(--torch-space-2);
}

/* Below this the labels shrink past legibility, so the diagram scrolls rather than shrinking. */
.torch-arch__svg[b-8zbvqevfm4] {
    display: block;
    width: 100%;
    min-width: 52rem;
    height: auto;
}

/* ---------------------------------------------------------------- connectors */

.arch-line[b-8zbvqevfm4] {
    stroke: var(--torch-border-strong);
    stroke-width: 1.5;
    stroke-linejoin: round;
}

.arch-line--socket[b-8zbvqevfm4] {
    stroke-dasharray: 7 6;
}

.arch-line--trust[b-8zbvqevfm4] {
    stroke-dasharray: 2 7;
    stroke-linecap: round;
    opacity: 0.7;
}

/* Drawn but not yet carrying anything: the same crawling line as the scaffolding. */
.arch-line--planned[b-8zbvqevfm4] {
    stroke: var(--torch-accent-muted);
    stroke-dasharray: 8 8;
    opacity: 0.55;
    animation: torch-arch-crawl-b-8zbvqevfm4 9s linear infinite;
}

@keyframes torch-arch-crawl-b-8zbvqevfm4 {
    to {
        stroke-dashoffset: -32;
    }
}

/*
 * The dash gap (194) deliberately exceeds the normalised path length of 100 so the pattern never
 * wraps around and shows a second dash at the far end of the connector.
 */
.arch-pulse[b-8zbvqevfm4] {
    stroke-width: 2.5;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-dasharray: 6 194;
    opacity: 0;
    animation: torch-arch-pulse-b-8zbvqevfm4 14s linear infinite;
    animation-delay: var(--arch-delay, 0s);
}

.arch-pulse--http[b-8zbvqevfm4] {
    stroke: var(--torch-accent-strong);
}

.arch-pulse--socket[b-8zbvqevfm4] {
    stroke: var(--torch-accent);
}

.arch-pulse--trust[b-8zbvqevfm4] {
    stroke: var(--torch-text-secondary);
}

@keyframes torch-arch-pulse-b-8zbvqevfm4 {
    0% {
        stroke-dashoffset: 6;
        opacity: 0;
    }

    5% {
        opacity: 1;
    }

    24% {
        opacity: 1;
    }

    28% {
        stroke-dashoffset: -106;
        opacity: 0;
    }

    100% {
        stroke-dashoffset: -106;
        opacity: 0;
    }
}

/* ---------------------------------------------------------------- legend */

.torch-arch__legend[b-8zbvqevfm4] {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--torch-space-6);
    list-style: none;
    margin: var(--torch-space-8) 0 0;
    padding: 0;
    color: var(--torch-text-muted);
    font-size: var(--torch-text-sm);
}

.torch-arch__legend li[b-8zbvqevfm4] {
    display: flex;
    align-items: center;
    gap: var(--torch-space-2);
}

.torch-arch__legend-line[b-8zbvqevfm4] {
    width: 2rem;
    height: 0;
    border-top: 2px solid var(--torch-border-strong);
}

.torch-arch__legend-line--http[b-8zbvqevfm4] {
    border-color: var(--torch-accent-strong);
}

.torch-arch__legend-line--socket[b-8zbvqevfm4] {
    border-style: dashed;
    border-color: var(--torch-accent);
}

.torch-arch__legend-line--trust[b-8zbvqevfm4] {
    border-style: dotted;
    border-color: var(--torch-text-secondary);
}

.torch-arch__legend-line--planned[b-8zbvqevfm4] {
    border-style: dashed;
    border-color: var(--torch-accent-muted);
}
/* /Components/Shared/ArchitectureSlab.razor.rz.scp.css */
/*
 * Every node is a stone slab. Its definition comes from line-work, not from a lit gradient: a dark
 * chisel line under the rim (a cut is a shadow, not a highlight), a faint gold hairline frame set
 * in from the edge the way a struck plate carries one, and a rune cut into the face. Same
 * treatment tokens.css describes for the rest of the product — --torch-engraving is exactly this.
 */

.arch-slab[b-10nliusxap] {
    fill: var(--torch-surface-2);
    stroke: var(--torch-border);
    stroke-width: 1;
    /* The crisp dark line is the chisel under the rim; the soft one is the slab's weight. Both
       are deliberately shy — pushed further, nine lit boxes stop reading as carved stone and start
       reading as a HUD. */
    filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.4)) drop-shadow(0 3px 8px rgba(8, 5, 2, 0.38));
}

.arch-slab__inlay[b-10nliusxap] {
    fill: none;
    stroke: var(--torch-engraving);
    stroke-width: 1;
}

.arch-node--client .arch-slab[b-10nliusxap] {
    fill: var(--torch-surface-1);
}

.arch-node--gateway .arch-slab[b-10nliusxap] {
    fill: var(--torch-surface-3);
    stroke: var(--torch-border-strong);
}

/*
 * One stroke, not two: a dark drop-shadow directly under a single dim line is what reads as a
 * groove cut into stone. Drawing a second darker copy underneath looks embossed instead — raised,
 * not carved — which is the opposite of the intent. The rune is the only place the accent is
 * spent on this diagram; names are stone-coloured and inscriptions are quieter still.
 */
.arch-rune[b-10nliusxap] {
    fill: none;
    stroke: var(--torch-accent-muted);
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: 0.7;
    filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.75));
}

.arch-node__title[b-10nliusxap] {
    fill: var(--torch-text-primary);
    font-family: var(--torch-font-display);
    font-size: 19px;
    font-weight: 600;
    letter-spacing: var(--torch-tracking-display);
    text-anchor: middle;
}

.arch-node__sub[b-10nliusxap] {
    fill: var(--torch-text-secondary);
    font-family: var(--torch-font-body);
    font-size: 13px;
    text-anchor: middle;
}

/* The inscription: the technology, in the mono face the rest of the product uses for versions and
   identifiers. Smaller and dimmer than the description above it, with no rule between them — a
   divider here crowded the shorter slabs and crossed their text outright. */
.arch-node__tech[b-10nliusxap] {
    fill: var(--torch-text-muted);
    font-family: var(--torch-font-mono);
    font-size: 11px;
    letter-spacing: 0.04em;
    text-anchor: middle;
}

/*
 * Scaffolding: a line that keeps crawling around anything still being built. Slow on purpose —
 * it should register as "alive, not finished", not as a selection marquee. The dash offset ends
 * on an exact multiple of the pattern so the loop has no visible seam.
 */
.arch-scaffold[b-10nliusxap] {
    fill: none;
    stroke: var(--torch-accent-muted);
    stroke-width: 1.5;
    stroke-dasharray: 8 8;
    opacity: 0.55;
    animation: torch-arch-crawl-b-10nliusxap 9s linear infinite;
}

@keyframes torch-arch-crawl-b-10nliusxap {
    to {
        stroke-dashoffset: -32;
    }
}
/* /Components/Shared/CultureSelector.razor.rz.scp.css */
/* No ::deep needed: this component renders the <select> itself, so it carries the scope
   attribute. .torch-select is width: 100% by default, which would swallow the header row. */
.torch-culture-selector .torch-select[b-ktz06624hb] {
    width: auto;
    padding: var(--torch-space-1) var(--torch-space-2);
    font-size: var(--torch-text-sm);
}
/* /Components/Shared/GameBuildSelector.razor.rz.scp.css */
.torch-game-build-selector[b-1r54enkvit] {
    display: flex;
    flex-direction: column;
    gap: var(--torch-space-2);
    text-align: left;
    width: 100%;
}

/* The legend reads as a marking stamped next to the control, not as a web form label: small
   tracked display caps in the accent, the same treatment as .torch-eyebrow elsewhere. */
.torch-game-build-selector label[b-1r54enkvit] {
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-xs);
    font-weight: 600;
    letter-spacing: var(--torch-tracking-eyebrow);
    text-transform: uppercase;
    color: var(--torch-accent);
}

/*
 * A native <select> renders as an OS widget — platform radius, platform chevron, platform blue
 * focus — and it was the one control on the launcher that gave the whole thing away as a web
 * form sitting inside a game.
 *
 * Stripping `appearance` and rebuilding it makes it the inverse of the primary button: where
 * that is a plate standing proud of the surface, this is a socket cut into it. Same materials,
 * opposite direction of light — a deep inset groove, a face a step darker than the card behind
 * it, and no lift on hover, because a recess cannot rise.
 *
 * The chevron is an inline SVG data URI rather than a background PNG or an icon font: it costs
 * no extra request, it is authored in the accent colour instead of inheriting whatever grey the
 * OS would have drawn, and it stays a true hairline at any DPI.
 */
.torch-game-build-selector select[b-1r54enkvit] {
    appearance: none;
    -webkit-appearance: none;
    height: 2.5rem;
    padding-inline: var(--torch-space-3) var(--torch-space-8);
    background-color: var(--torch-surface-1);
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='7' viewBox='0 0 11 7'%3E%3Cpath d='M1 1l4.5 4.5L10 1' fill='none' stroke='%23c9973f' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--torch-space-3) center;
    background-size: 11px 7px;
    box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.5), inset 0 -1px 0 rgba(255, 235, 205, 0.04);
    cursor: pointer;
}

.torch-game-build-selector select:hover[b-1r54enkvit] {
    border-color: var(--torch-border-strong);
}

/*
 * Both of these restate the box-shadow rather than leaning on .torch-select's own :hover/:focus
 * rules in base.css. They have to: the scoped selector above is one specificity step higher than
 * the shared class, so its deeper inset would otherwise win *during* focus and quietly erase the
 * ember ring — a focus state that silently does not render is worse than one that never existed.
 */
.torch-game-build-selector select:focus-visible[b-1r54enkvit] {
    outline: none;
    border-color: var(--torch-accent);
    box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.5), 0 0 0 3px rgba(201, 151, 63, 0.18);
}

/* The popup list is drawn by the OS, so this is as far as styling reaches — Windows and Linux
   honour it, macOS ignores it. Worth setting anyway: without it those platforms render a white
   list out of a black control. */
.torch-game-build-selector option[b-1r54enkvit] {
    background-color: var(--torch-surface-2);
    color: var(--torch-text-primary);
}
/* /Components/Shared/GameSplash.razor.rz.scp.css */
.torch-game-splash[b-8cz5i8gd9j] {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: #07111c;
    transition: opacity var(--torch-duration-slow) var(--torch-ease-out);
}

.torch-game-splash--ready[b-8cz5i8gd9j] {
    opacity: 0;
    pointer-events: none;
}

.torch-game-splash__bg[b-8cz5i8gd9j] {
    position: absolute;
    inset: 0;
}

.torch-game-splash__bg-image[b-8cz5i8gd9j] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
}

/* The centre used to be fully transparent, which is precisely where every piece of text sits —
   the tip landed on whatever the panning artwork happened to put behind it. A light tint across
   the middle costs almost nothing in the artwork and steadies the whole readout. */
.torch-game-splash__scrim[b-8cz5i8gd9j] {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse at center, rgba(4, 9, 16, 0.18) 0%, rgba(4, 9, 16, 0.55) 62%, rgba(4, 9, 16, 0.94) 100%),
        linear-gradient(180deg, rgba(0, 0, 0, 0.5) 0%, transparent 50%, rgba(0, 0, 0, 0.7) 100%);
    pointer-events: none;
}

/*
 * A soft focus pool behind the readout: a shallow depth-of-field blur plus a little more shadow,
 * feathered out with a mask so there is no visible edge where it stops. The blur is what does the
 * real work — it takes the high-frequency detail out of the artwork directly behind the type,
 * which is what made the tips hard to read, without darkening the scene enough to lose the tower.
 *
 * z-index: -1 keeps it inside the stacking context this element already creates, so it paints over
 * the scrim but under the logo, bar and tip.
 */
.torch-game-splash__content[b-8cz5i8gd9j]::before {
    content: "";
    position: absolute;
    inset: -16% -32%;
    z-index: -1;
    pointer-events: none;
    background: radial-gradient(ellipse at center,
            rgba(4, 8, 14, 0.55) 0%,
            rgba(4, 8, 14, 0.38) 45%,
            rgba(4, 8, 14, 0) 72%);
    backdrop-filter: blur(7px);
    -webkit-backdrop-filter: blur(7px);
    mask-image: radial-gradient(ellipse at center, #000 0%, #000 42%, transparent 73%);
    -webkit-mask-image: radial-gradient(ellipse at center, #000 0%, #000 42%, transparent 73%);
}

.torch-game-splash__content[b-8cz5i8gd9j] {
    position: relative;
    z-index: 1;
    display: flex;
    width: min(420px, 80vw);
    max-width: 28rem;
    flex-direction: column;
    align-items: center;
    gap: var(--torch-space-4);
    text-align: center;
    padding: 0 var(--torch-space-6);
}

.torch-game-splash__logo[b-8cz5i8gd9j] {
    height: clamp(140px, 34vh, 420px);
    width: auto;
    max-width: 70vw;
}

.torch-game-splash__progress-wrap[b-8cz5i8gd9j] {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: var(--torch-space-2);
}

/* A channel sunk into the plate, not a capsule floating on it. tokens.css rules out pill radii
   outright ("never pill"), and a 999px track is the single detail that made this screen read as
   a web app rather than a game client. */
.torch-game-splash__progress-track[b-8cz5i8gd9j] {
    position: relative;
    height: 0.5rem;
    width: 100%;
    overflow: hidden;
    border-radius: 1px;
    border: 1px solid #241f19;
    background: linear-gradient(180deg, #080706 0%, #100d0b 100%);
    box-shadow:
        inset 0 1px 2px rgba(0, 0, 0, 0.85),
        0 1px 0 rgba(255, 226, 178, 0.05);
}

.torch-game-splash__progress-bar[b-8cz5i8gd9j] {
    position: relative;
    height: 100%;
    background: linear-gradient(90deg, #7a4a1c 0%, #b8802f 45%, #d9a648 100%);
    box-shadow: 0 0 12px rgba(206, 140, 52, 0.5);
    transition: width var(--torch-duration-normal) linear;
}

/* The molten head. The leading edge is the hottest part of a pour, and it is what makes the bar
   read as fire filling a channel instead of a div getting wider. */
.torch-game-splash__progress-bar[b-8cz5i8gd9j]::after {
    content: "";
    position: absolute;
    inset: 0 0 0 auto;
    width: 3px;
    background: #ffe9bd;
    box-shadow:
        0 0 8px 2px rgba(255, 198, 112, 0.85),
        0 0 18px 5px rgba(226, 130, 40, 0.5);
}

/* Warm, not white: the scene's only light sources are torches, so a white sheen belongs to a
   different room. */
.torch-game-splash__progress-shimmer[b-8cz5i8gd9j] {
    position: absolute;
    inset: 0 auto 0 0;
    width: 28%;
    background: linear-gradient(90deg, transparent, rgba(255, 214, 150, 0.22), transparent);
}

.torch-game-splash__progress-labels[b-8cz5i8gd9j] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--torch-space-4);
}

/* Instrumentation, not two equal spans: the stage recedes into tracked-out caps and the
   percentage is set in the display face, so the number carries the screen. */
.torch-game-splash__stage[b-8cz5i8gd9j] {
    font-size: var(--torch-text-xs);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--torch-text-muted);
    text-align: left;
}

.torch-game-splash__percent[b-8cz5i8gd9j] {
    flex: 0 0 auto;
    font-family: var(--torch-font-display);
    font-weight: 600;
    font-size: var(--torch-text-md);
    letter-spacing: 0.04em;
    color: var(--torch-accent-strong);
    font-variant-numeric: tabular-nums;
}

/* The tips are the one deliberately light-hearted thing on the screen, so they get treated as an
   inscription: centred and closed off by a diamond at each end, matching .torch-section-heading's
   ornament language rather than inventing a second one. */
.torch-game-splash__tip[b-8cz5i8gd9j] {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--torch-space-3);
    min-height: 2.75rem;
    margin: var(--torch-space-2) 0 0;
    text-align: center;
}

.torch-game-splash__tip-diamond[b-8cz5i8gd9j] {
    flex: 0 0 auto;
    width: 0.3125rem;
    height: 0.3125rem;
    background: var(--torch-accent);
    box-shadow: 0 0 8px rgba(201, 151, 63, 0.6);
    transform: rotate(45deg);
}

.torch-game-splash__tip p[b-8cz5i8gd9j] {
    margin: 0;
    font-size: var(--torch-text-sm);
    line-height: 1.55;
    color: var(--torch-text-secondary);
}
/* /Components/Shared/SiteFooter.razor.rz.scp.css */
/* Like the header: flat surface, hairline, no texture. The ember line along the top edge is the
   only accent, mirroring the one under the header so the page reads as bracketed. */
/*
 * `sticky` with a full-viewport offset is the sticky-footer trick, and it is here because a short
 * page — /not-found, /forbidden, an empty news list — left the footer floating a third of the way
 * down a desktop screen with the page background running on below it, which reads as the page
 * having failed to load the rest of itself.
 *
 * How it works: the offset asks the footer to stay a whole viewport below the top of the
 * scrollport, and sticky positioning then clamps it to its containing block, which is <body> —
 * already `min-height: 100vh` in base.css. On a short page that clamp lands the footer's *bottom*
 * edge exactly on the bottom of the viewport. On a page taller than the viewport the footer's
 * natural position is already past the offset, so nothing moves and it scrolls normally.
 *
 * Chosen over the conventional fix — `display: flex` on <body> with the main region flex-grown —
 * because <body> is shared with /admin, whose <MudLayout> does its own full-height layout and
 * would become a flex item of a container it knows nothing about. This is one property, on the
 * one component that has the problem, and it cannot reach the admin app at all.
 *
 * Depends on no ancestor establishing a scroll container or a containing block for it; <body> and
 * <html> are both plain, and the ambient ember canvas and the error bar are `fixed`, so they are
 * out of flow and cannot become one.
 */
.torch-footer[b-mv4q5stp5c] {
    position: sticky;
    top: 100vh;
    /* Was space-24. Stacked on top of the news panel's own 4rem of bottom padding it opened a
       6rem band of bare page between the last card and the footer, which read as the page having
       ended early rather than as breathing room. */
    margin-top: var(--torch-space-12);
    background-color: var(--torch-surface-1);
    border-top: 1px solid var(--torch-border);
}

.torch-footer__accent-line[b-mv4q5stp5c] {
    position: absolute;
    inset: -1px 0 auto 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(201, 151, 63, 0.45), transparent);
}

/* A single diamond seated on the ember line, echoing the section-heading ornament — the page's
   closing punctuation, and the visual answer to the heading that opened it. */
.torch-footer__accent-line[b-mv4q5stp5c]::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 6px;
    height: 6px;
    transform: translate(-50%, -50%) rotate(45deg);
    background: var(--torch-accent);
    box-shadow: 0 0 10px rgba(201, 151, 63, 0.5);
}

.torch-footer__inner[b-mv4q5stp5c] {
    position: relative;
    max-width: var(--torch-content-width);
    margin: 0 auto;
    padding-inline: var(--torch-space-8);
}

.torch-footer__main[b-mv4q5stp5c] {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 12fr) minmax(0, 4fr);
    align-items: center;
    min-height: calc(var(--torch-space-24) * 2);
    padding-block: var(--torch-space-8);
}

.torch-footer__brand[b-mv4q5stp5c] {
    display: flex;
    min-width: 0;
    align-self: stretch;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--torch-space-2);
    padding-inline: var(--torch-space-8);
    text-align: center;
}

.torch-footer__brand img[b-mv4q5stp5c] {
    display: block;
    width: min(100%, calc(var(--torch-space-24) * 2.5));
    height: auto;
}

.torch-footer__brand p[b-mv4q5stp5c] {
    width: 100%;
    max-width: 100%;
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-xs);
    letter-spacing: var(--torch-tracking-eyebrow);
    white-space: normal;
    overflow-wrap: break-word;
    text-wrap: balance;
    text-transform: uppercase;
    color: var(--torch-text-secondary);
    margin: 0;
}

.torch-footer__copyright[b-mv4q5stp5c] {
    margin: 0;
    color: var(--torch-accent-muted);
    font-family: var(--torch-font-body);
    font-size: var(--torch-text-xs);
    text-align: center;
}

.torch-footer__nav[b-mv4q5stp5c] {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    justify-content: stretch;
    align-items: start;
    gap: var(--torch-space-6);
    padding: var(--torch-space-8);
    border-inline: 1px solid var(--torch-border);
}

.torch-footer__nav-group[b-mv4q5stp5c] {
    display: flex;
    min-width: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--torch-space-3);
}

.torch-footer__nav-legal[b-mv4q5stp5c] {
    width: auto;
}

.torch-footer__nav-heading[b-mv4q5stp5c] {
    margin: 0 0 var(--torch-space-2);
    color: var(--torch-accent-muted);
    font-family: var(--torch-font-display);
    font-size: var(--torch-text-sm);
    font-weight: 600;
    letter-spacing: var(--torch-tracking-eyebrow);
    text-transform: uppercase;
}

.torch-footer__nav a[b-mv4q5stp5c] {
    position: relative;
    color: var(--torch-text-secondary);
    text-decoration: none;
    font-size: var(--torch-text-base);
    padding-block: var(--torch-space-1);
    white-space: nowrap;
    transition: color var(--torch-duration-fast) var(--torch-ease-out);
}

.torch-footer__nav a:hover[b-mv4q5stp5c] {
    color: var(--torch-accent-strong);
}

.torch-footer__nav-legal a[b-mv4q5stp5c] {
    color: var(--torch-text-secondary);
    font-size: var(--torch-text-base);
}

.torch-footer__studio[b-mv4q5stp5c] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--torch-space-2);
    padding-inline: var(--torch-space-8);
    text-align: center;
}

.torch-footer__studio-logo[b-mv4q5stp5c] {
    display: block;
    width: min(100%, calc(var(--torch-space-24) + var(--torch-space-12)));
    height: auto;
}

.torch-footer__social-icons[b-mv4q5stp5c] {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--torch-space-3);
}

.torch-footer__social-icons a[b-mv4q5stp5c] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--torch-space-12);
    height: var(--torch-space-12);
    border: 1px solid var(--torch-accent-muted);
    border-radius: 50%;
    color: var(--torch-accent-strong);
    font-family: var(--torch-font-mono);
    font-size: var(--torch-text-xs);
    box-shadow: var(--torch-chisel);
    cursor: pointer;
    text-decoration: none;
    transition:
        color var(--torch-duration-fast) var(--torch-ease-out),
        background-color var(--torch-duration-fast) var(--torch-ease-out),
        border-color var(--torch-duration-fast) var(--torch-ease-out),
        box-shadow var(--torch-duration-normal) var(--torch-ease-out),
        transform var(--torch-duration-normal) var(--torch-ease-out);
}

.torch-footer__social-icons a:hover[b-mv4q5stp5c],
.torch-footer__social-icons a:focus-visible[b-mv4q5stp5c] {
    color: var(--torch-plate-label-hot);
    background-color: var(--torch-surface-2);
    border-color: var(--torch-accent-strong);
    box-shadow: var(--torch-shadow-glow);
    transform: scale(1.06);
}

.torch-footer__social-icons svg[b-mv4q5stp5c] {
    width: calc(var(--torch-space-4) + var(--torch-space-1));
    height: calc(var(--torch-space-4) + var(--torch-space-1));
    fill: currentColor;
}

.torch-footer__social-icons .torch-footer__social-icon--outline[b-mv4q5stp5c] {
    fill: none;
}

.torch-footer__contact[b-mv4q5stp5c] {
    font-family: var(--torch-font-mono);
    font-size: var(--torch-text-xs);
}

@media (min-width: 80rem) {
    .torch-footer__inner[b-mv4q5stp5c] {
        max-width: calc(var(--torch-content-width) + var(--torch-space-24) * 2);
    }

    .torch-footer__main[b-mv4q5stp5c] {
        grid-template-columns: minmax(0, 5fr) minmax(0, 11fr) minmax(0, 4fr);
    }

    .torch-footer__brand[b-mv4q5stp5c] {
        padding-inline: var(--torch-space-4);
    }

    .torch-footer__brand p[b-mv4q5stp5c] {
        white-space: nowrap;
    }
}

@media (max-width: 64rem) {
    .torch-footer__inner[b-mv4q5stp5c] {
        padding-inline: var(--torch-space-4);
    }

    .torch-footer__main[b-mv4q5stp5c] {
        grid-template-columns: 1fr;
        min-height: 0;
        padding-block: 0;
    }

    .torch-footer__brand[b-mv4q5stp5c],
    .torch-footer__studio[b-mv4q5stp5c] {
        padding: var(--torch-space-8) var(--torch-space-4);
    }

    .torch-footer__nav[b-mv4q5stp5c] {
        padding: var(--torch-space-8) var(--torch-space-4);
        border-inline: 0;
        border-block: 1px solid var(--torch-border);
    }

}

@media (max-width: 36rem) {
    .torch-footer__nav[b-mv4q5stp5c] {
        grid-template-columns: 1fr;
        gap: var(--torch-space-8);
    }

    .torch-footer__nav-group[b-mv4q5stp5c] {
        align-items: center;
    }
}
/* /Components/Shared/StatusPage.razor.rz.scp.css */
/*
 * The status-page frame: a two-column plate with the message set against the torch that lights it.
 *
 * It was centred copy on an empty page. Centring is right when the block is the whole composition,
 * but the moment there is an illustration beside it the two are competing for the same axis — and
 * a ragged-right column reading towards the light is what makes the pair read as one picture
 * rather than as a paragraph with a decoration bolted to it.
 */

.torch-status-page[b-rq9bklh008] {
    /* Not a viewport fraction. The sticky footer already guarantees the page fills the screen (see
       SiteFooter.razor.css), so this only has to be tall enough that the torch has room to hang
       and its smoke has somewhere to go. */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--torch-space-16) var(--torch-space-8);
}

.torch-status-page__inner[b-rq9bklh008] {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(var(--torch-space-8), 6vw, var(--torch-space-24));
    max-width: 56rem;
    width: 100%;
}

.torch-status-page__content[b-rq9bklh008] {
    max-width: 32rem;
    /* `min-width: 0` so the text column, not the drawing, is what gives when the row is tight —
       an SVG with an intrinsic aspect ratio will otherwise happily squeeze the prose to nothing. */
    min-width: 0;
}

/*
 * The status code is set in the display face at a large size and low contrast — it reads as a
 * watermark behind the message rather than shouting a number at someone who already knows
 * something went wrong.
 *
 * The negative margin pulls the heading up into the numeral's shoulder so the two lock together as
 * one masthead. Display type carries far more space above its cap height than a line box accounts
 * for, so without it the pair reads as two unrelated lines that happen to be stacked.
 */
/* Fully qualified deliberately. `.torch-status-page__content p` below is class-plus-type, so both
   a bare `.torch-status-page__eyebrow` and a `p.torch-status-page__eyebrow` tie with it on
   specificity and lose on source order — the numeral had been rendering at full body-copy contrast
   rather than as a watermark at all. Matching the parent too breaks the tie for good. */
.torch-status-page__content p.torch-status-page__eyebrow[b-rq9bklh008] {
    font-family: var(--torch-font-display);
    font-size: clamp(3.5rem, 9vw, 5rem);
    line-height: 0.9;
    letter-spacing: 0.06em;
    color: var(--torch-border-strong);
    margin: 0 0 var(--torch-space-2);
}

.torch-status-page__content h1[b-rq9bklh008] {
    margin-bottom: var(--torch-space-4);
}

.torch-status-page__content p[b-rq9bklh008] {
    color: var(--torch-text-secondary);
    margin-bottom: var(--torch-space-8);
    max-width: 40ch;
}

.torch-status-page__actions[b-rq9bklh008] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--torch-space-3);
}

/*
 * Below this the two columns stop fitting side by side. The torch goes *above* the message rather
 * than below it: it is the thing that establishes what kind of page this is, and an illustration
 * that only appears after the reader has already finished reading has arrived too late to do that
 * job. Everything re-centres, which is where the design started before there was a second column.
 */
@media (max-width: 52rem) {
    .torch-status-page[b-rq9bklh008] {
        padding: var(--torch-space-12) var(--torch-space-4);
    }

    .torch-status-page__inner[b-rq9bklh008] {
        flex-direction: column-reverse;
        gap: var(--torch-space-8);
    }

    .torch-status-page__content[b-rq9bklh008] {
        text-align: center;
    }

    .torch-status-page__content p[b-rq9bklh008] {
        margin-inline: auto;
    }

    .torch-status-page__actions[b-rq9bklh008] {
        justify-content: center;
    }
}
/* /Components/Shared/TorchSconce.razor.rz.scp.css */
/*
 * The painted sconce on the status pages.
 *
 * Nothing here animates. The illustration used to be a twelve-frame sprite stepped through in CSS;
 * see the note in TorchSconce.razor for why that came out and what replaced it. What is left is a
 * single image, sized and placed — which is all it ever needed to be once variety moved from
 * "twelve frames a second" to "a different still each visit".
 */

.torch-sconce[b-iw96snemp4] {
    flex: 0 0 auto;
    display: block;
    /* Ceiling a little under the text column's width so the drawing never out-measures the message
       it belongs to; floor generous enough that the flame is still legible on a phone. */
    width: clamp(9.5rem, 26vw, 17rem);
    height: auto;
}

@media (max-width: 52rem) {
    .torch-sconce[b-iw96snemp4] {
        width: clamp(8rem, 38vw, 12rem);
    }
}
/* /Components/Shared/UnityLauncher.razor.rz.scp.css */
.torch-unity-launcher[b-h2q3p0ljry] {
    position: fixed;
    inset: 0;
    z-index: 55;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #000;
    transition: opacity 0.3s ease;
}

.torch-unity-launcher--hidden[b-h2q3p0ljry] {
    opacity: 0;
    pointer-events: none;
}

.torch-unity-launcher__container[b-h2q3p0ljry] {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}

.torch-unity-launcher__canvas[b-h2q3p0ljry] {
    display: block;
    outline: none;
}
