/* ============================================================================
   Abyss Floors — web portal styles.
   Dark-fantasy identity matched to the game client's design tokens (AbyssTokens):
   ember-gold primary, teal secondary, violet-black ground. The /Account flow uses
   the two-column "descent" shell (AuthLayout + the .auth-* system below); the rest
   of the portal (Home / Play / Manage, via MainLayout) shares the same palette
   through the .portal-* chrome.
   ============================================================================ */

:root {
    /* ground + panels */
    --bg: #131219;
    --bg-2: #0D0C12;
    --panel: #191820;
    --panel-2: #211F2A;
    --field: #14131A;

    /* text */
    --ink: #ECEAF2;
    --muted: #9A96A8;          /* violet-biased grey — chosen, not a default mid-grey */

    /* brand accents (from AbyssTokens) */
    --accent: #E0A14B;         /* ember gold — primary */
    --accent-bright: #F2C879;
    --accent-deep: #A8762F;
    --accent-2: #43C9C2;       /* teal — secondary */
    --ember-wash: rgba(224, 161, 75, 0.12);

    /* semantics */
    --ok: #5FB86A;
    --err: #E0605A;

    /* lines */
    --line: rgba(224, 161, 75, 0.16);
    --line-soft: rgba(236, 234, 242, 0.08);
    --shadow: rgba(0, 0, 0, 0.55);

    /* the abyss shaft — always dark */
    --shaft-top: #1B1926;
    --shaft-bottom: #07060B;
    --shaft-muted: #8E8A9E;

    --radius: 14px;
    --ease: cubic-bezier(.22, .61, .36, 1);
    color-scheme: dark;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

/* ============================ Shared portal chrome (MainLayout pages) ======== */

.portal-shell {
    max-width: 860px;
    margin: 0 auto;
    padding: 1rem;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

.portal-nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--line-soft);
}

.portal-brand {
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--accent);
    text-decoration: none;
}

.portal-nav-links {
    display: flex;
    gap: 1.1rem;
    align-items: center;
}

.portal-nav-links a { color: var(--ink); text-decoration: none; }
.portal-nav-links a:hover { color: var(--accent); }
.portal-nav-user { color: var(--muted); font-size: 0.9rem; }

/* CSS-only burger: hidden control + burger glyph. Desktop shows the flat link row;
   Terms/Privacy stay in the footer (hidden here) until the mobile menu is opened. */
.portal-nav-checkbox { display: none; }
.portal-burger {
    display: none;
    cursor: pointer; user-select: none;
    font-size: 1.4rem; line-height: 1;
    color: var(--ink); padding: 2px 6px;
}
.portal-nav-legal { display: none; }

@media (max-width: 640px) {
    .portal-nav { flex-wrap: wrap; }
    .portal-burger { display: block; }
    .portal-nav-links {
        display: none;
        flex-basis: 100%;
        flex-direction: column;
        align-items: flex-start;
        gap: 0.7rem;
        padding: 0.7rem 0 0.2rem;
    }
    .portal-nav-checkbox:checked ~ .portal-nav-links { display: flex; }
    .portal-nav-user { overflow-wrap: anywhere; max-width: 100%; }
    .portal-nav-legal { display: block; }
}

.portal-main { flex: 1; padding: 1.75rem 0; }

.portal-footer {
    padding: 1.1rem 0;
    color: var(--muted);
    font-size: 0.82rem;
    letter-spacing: 0.02em;
    border-top: 1px solid var(--line-soft);
}

.portal-card {
    background: linear-gradient(180deg, var(--panel-2), var(--panel));
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 1.1rem 1.35rem;
    margin: 1rem 0;
}

.portal-note { color: var(--muted); font-size: 0.9rem; }
/* teal link colour for real links only — NOT the .portal-cta buttons (which set their own dark/ink text on the fill) */
.portal-note a, .portal-main a:not(.portal-cta) { color: var(--accent-2); }

.portal-inline-form { display: inline; }

.portal-link-button {
    background: none; border: none; color: var(--accent-2);
    cursor: pointer; padding: 0; font: inherit; text-decoration: underline;
}

/* ---- form controls (shared by /Account forms AND Manage) ------------------- */

.portal-field {
    margin-bottom: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.portal-field label {
    font-size: 0.72rem;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 600;
}

.portal-field input {
    padding: 0.72rem 0.85rem;
    background: var(--field);
    border: 1px solid var(--line-soft);
    color: var(--ink);
    border-radius: 10px;
    font-size: 0.95rem;
    transition: border-color .18s, box-shadow .18s;
}

.portal-field input::placeholder { color: color-mix(in srgb, var(--muted) 70%, transparent); }

.portal-field input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--ember-wash);
}

.portal-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.8rem 1.2rem;
    background: linear-gradient(180deg, var(--accent-bright), var(--accent));
    color: #1a140a;
    border: 1px solid transparent;
    border-radius: 11px;
    text-decoration: none;
    cursor: pointer;
    font-size: 0.95rem;
    font-weight: 650;
    letter-spacing: 0.02em;
    box-shadow: 0 14px 30px -14px var(--accent), inset 0 1px 0 rgba(255, 255, 255, .35);
    transition: transform .12s var(--ease), filter .2s;
}

.portal-cta:hover { transform: translateY(-1px); filter: brightness(1.04); }
.portal-cta:active { transform: translateY(0); }

.portal-cta-secondary {
    background: var(--field);
    color: var(--ink);
    border-color: var(--line);
    box-shadow: none;
}

.portal-cta-secondary:hover { border-color: var(--accent); color: var(--accent); filter: none; }

.portal-cta-row { display: flex; gap: 0.75rem; }

/* a CTA that is deliberately unavailable (ADR-0158: "Steam sign-up — coming soon") — visibly inert, no hover lift */
.portal-cta:disabled, .portal-cta[aria-disabled="true"] {
    opacity: 0.55; cursor: not-allowed; filter: grayscale(1);
    box-shadow: none; transform: none;
}
.portal-cta:disabled:hover, .portal-cta[aria-disabled="true"]:hover {
    transform: none; filter: grayscale(1); border-color: var(--line); color: var(--ink);
}

/* a submit button that must READ as a link (a form POST is required for the antiforgery token, but the affordance is
   a secondary escape hatch, not a CTA) */
.portal-linkbutton {
    background: none; border: 0; padding: 0; margin: 0;
    color: var(--accent-2); font: inherit; font-size: 0.86rem;
    cursor: pointer; text-decoration: none;
}
.portal-linkbutton:hover { text-decoration: underline; }
/* This link is the ONLY keyboard path for a linked tester (the button beside it is disabled) — it MUST show a focus
   ring (review gate 2026-08-10 accessibility note). */
.portal-linkbutton:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; text-decoration: underline; }

/* ---- status + validation -------------------------------------------------- */

.portal-status {
    padding: 0.7rem 0.95rem;
    border-radius: 10px;
    margin: 0 0 1rem;
    font-size: 0.9rem;
}

.portal-status-ok { background: rgba(95, 184, 106, 0.14); border: 1px solid rgba(95, 184, 106, 0.5); color: #bfe9c6; }
.portal-status-error { background: rgba(224, 96, 90, 0.14); border: 1px solid rgba(224, 96, 90, 0.5); color: #f2b7b3; }

.validation-message { color: var(--err); font-size: 0.82rem; }

/* ============================================================================
   The /Account descent shell (AuthLayout)
   ============================================================================ */

.auth-stage {
    min-height: 100vh;
    display: grid;
    grid-template-columns: 1.08fr 0.92fr;
}

/* ---- LEFT: the abyss / descent -------------------------------------------- */

.auth-abyss {
    position: relative;
    overflow: hidden;
    color: var(--ink);
    padding: clamp(28px, 4.4vw, 64px);
    display: flex;
    flex-direction: column;
    border-right: 1px solid var(--line);
    background:
        radial-gradient(120% 90% at 30% 6%, rgba(224, 161, 75, 0.10), transparent 60%),
        linear-gradient(180deg, var(--shaft-top), var(--shaft-bottom) 92%);
}

/* faint vertical shaft rules + a slow rising ember shimmer (CSS-only, no JS) */
.auth-abyss::before {
    content: "";
    position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(90deg, transparent 0 11%, rgba(255,255,255,.03) 11% 11.15%, transparent 11.15% 89%, rgba(255,255,255,.03) 89% 89.15%, transparent 89.15%);
    -webkit-mask: linear-gradient(180deg, #000, transparent 96%);
    mask: linear-gradient(180deg, #000, transparent 96%);
}

.auth-abyss::after {
    content: "";
    position: absolute; left: 0; right: 0; bottom: 0; height: 62%; pointer-events: none;
    background: radial-gradient(60% 40% at 50% 100%, rgba(224, 161, 75, 0.14), transparent 70%);
    animation: abyssGlow 7s ease-in-out infinite alternate;
}

@keyframes abyssGlow { from { opacity: .5; } to { opacity: 1; } }

.auth-abyss__inner { position: relative; display: flex; flex-direction: column; flex: 1; }

.auth-brand { display: flex; align-items: center; gap: 14px; }

.auth-sigil {
    width: 40px; height: 40px; flex: 0 0 auto;
    display: grid; place-items: center;
    border: 1px solid var(--accent); border-radius: 11px; color: var(--accent);
    font-family: Georgia, serif; font-weight: 700; font-size: 1.25rem;
    box-shadow: 0 0 22px -6px var(--accent), inset 0 0 14px -8px var(--accent);
}

.auth-wordmark {
    font-family: Georgia, "Iowan Old Style", "Times New Roman", serif;
    font-size: clamp(1.5rem, 2.2vw, 2rem);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    /* engraved metallic gold */
    background: linear-gradient(180deg, #F7E6BE 0%, var(--accent) 55%, var(--accent-deep) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.auth-tagline {
    margin: 26px 0 0;
    font-size: 0.8rem; letter-spacing: 0.34em; text-transform: uppercase;
    color: var(--accent); font-weight: 600;
}

.auth-lede {
    margin: 12px 0 0;
    max-width: 36ch;
    color: var(--shaft-muted);
    font-size: 1.02rem; line-height: 1.62;
}

.auth-depths {
    list-style: none;
    position: relative;
    margin: auto 0 0; padding: 26px 0 0;
    display: flex; flex-direction: column; gap: 2px;
}

.auth-depths::before {
    content: "THE DESCENT";
    font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
    font-size: 0.64rem; letter-spacing: 0.34em;
    color: var(--shaft-muted); opacity: .7;
    margin-bottom: 10px;
}

/* the spine threading the descent — sits BEHIND the floor nodes so each opaque
   circle masks the line inside it and the connector shows only between nodes */
.auth-depths::after {
    content: ""; position: absolute; left: 8px; top: 44px; bottom: 10px; width: 1px; z-index: 0;
    background: linear-gradient(180deg, var(--accent-deep), transparent 92%);
}

.auth-floor {
    position: relative; z-index: 1;
    display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 14px;
    padding: 8px 12px 8px 26px; border-radius: 9px;
    color: var(--shaft-muted); border: 1px solid transparent;
}

/* the node on the spine at each floor; the current floor's node glows */
.auth-floor::before {
    content: ""; position: absolute; left: 5px; top: 50%; transform: translateY(-50%);
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--shaft-bottom); border: 1px solid var(--shaft-muted);
}
.auth-floor.is-current::before {
    background: var(--accent); border-color: var(--accent);
    box-shadow: 0 0 10px var(--accent);
}

.auth-floor .code { font-family: ui-monospace, Consolas, monospace; font-size: 0.72rem; letter-spacing: 0.06em; opacity: .75; }
.auth-floor .name { font-size: 0.95rem; }
.auth-floor .depth { font-family: ui-monospace, Consolas, monospace; font-size: 0.74rem; font-variant-numeric: tabular-nums; opacity: .7; }

.auth-floor.is-current {
    color: var(--ink);
    background: var(--ember-wash);
    border-color: var(--line);
    box-shadow: inset 2px 0 0 var(--accent);
}
.auth-floor.is-current .code, .auth-floor.is-current .depth { color: var(--accent); opacity: 1; }

.auth-floor.d1 { opacity: .84; }
.auth-floor.d2 { opacity: .60; }
.auth-floor.d3 { opacity: .38; }

.auth-features {
    list-style: none;
    margin: 26px 0 0; padding: 20px 0 0;
    border-top: 1px solid var(--line-soft);
    display: flex; flex-wrap: wrap; gap: 8px;
}

.auth-features li {
    font-size: 0.76rem; color: var(--shaft-muted);
    padding: 6px 12px; border: 1px solid var(--line-soft); border-radius: 999px;
}
.auth-features li b { color: var(--ink); font-weight: 600; }

/* ---- RIGHT: the gate (form card) ------------------------------------------ */

.auth-gate {
    position: relative;
    background: var(--bg);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 16px;
    padding: clamp(28px, 4vw, 56px) clamp(20px, 3.5vw, 52px);
}

/* a soft vignette so the card sits in a pool of light */
.auth-gate::before {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background: radial-gradient(130% 90% at 50% -8%, transparent 55%, rgba(0, 0, 0, 0.22));
}

.auth-status {
    position: absolute; top: 22px; left: 0; right: 0; margin: auto; width: max-content;
    display: inline-flex; align-items: center; gap: 8px;
    font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted);
}
.auth-status .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 8px var(--ok); }

.auth-card {
    position: relative;
    width: 100%; max-width: 412px;
    background: linear-gradient(180deg, var(--panel-2), var(--panel));
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 26px;
    box-shadow: 0 30px 60px -30px var(--shadow);
}

/* a thin gold crown accent along the card's top edge */
.auth-card::before {
    content: ""; position: absolute; top: -1px; left: 26px; right: 26px; height: 1px;
    background: linear-gradient(90deg, transparent, var(--accent), transparent);
    opacity: 0.55;
}

.auth-switch {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px;
    padding: 4px; margin-bottom: 22px;
    background: var(--field); border: 1px solid var(--line-soft); border-radius: 11px;
}

.auth-tab {
    display: flex; align-items: center; justify-content: center; min-height: 100%;
    text-align: center; text-decoration: none;
    padding: 9px 6px; border-radius: 8px;
    color: var(--muted); font-size: 0.82rem; font-weight: 600;
    transition: color .2s, background .2s;
}
.auth-tab:hover { color: var(--ink); }
.auth-tab.is-active {
    color: #1a140a;
    background: linear-gradient(180deg, var(--accent-bright), var(--accent));
    box-shadow: 0 6px 16px -8px var(--accent);
}

/* the page body rendered inside the card */
.auth-body h1 {
    margin: 0;
    font-family: Georgia, "Iowan Old Style", "Times New Roman", serif;
    font-weight: 400; font-size: 1.6rem; letter-spacing: 0.01em;
    text-wrap: balance;
}

/* auth forms get full-width CTAs; non-auth pages (Home/Play/Manage) keep inline buttons */
.auth-body .portal-cta { width: 100%; }
.auth-body .portal-field:last-of-type { margin-bottom: 1.25rem; }

.auth-body > p { color: var(--muted); font-size: 0.92rem; margin: 6px 0 20px; }
.auth-body a { color: var(--accent-2); text-decoration: none; }
.auth-body a:hover { text-decoration: underline; }
.auth-body ul { color: var(--muted); font-size: 0.92rem; padding-left: 1.1rem; }
.auth-body strong { color: var(--ink); font-weight: 600; }
.auth-body ol.auth-steps { color: var(--muted); font-size: 0.92rem; padding-left: 1.25rem; display: flex; flex-direction: column; gap: 0.6rem; margin: 0 0 1.25rem; }
.auth-body ol.auth-steps li::marker { color: var(--accent); font-weight: 700; }

/* pre-release opt-in checkboxes (Register) */
.auth-optins { display: flex; flex-direction: column; gap: 12px; margin: 4px 0 20px; }
.auth-check { display: grid; grid-template-columns: auto 1fr; gap: 10px; align-items: start; cursor: pointer; }
.auth-check input[type="checkbox"] { width: 16px; height: 16px; margin-top: 3px; accent-color: var(--accent); }
.auth-check span { display: flex; flex-direction: column; gap: 2px; }
.auth-check strong { color: var(--ink); font-weight: 600; font-size: 0.9rem; }
.auth-check small { color: var(--muted); font-size: 0.8rem; line-height: 1.4; }

/* the progress-policy statement above the Register button (ReleaseFacts.ProgressPolicy). Deliberately a bordered
   callout, not a muted footnote: it is the one thing a player must have read before creating an account. */
.auth-progress-note {
    display: flex; flex-direction: column; gap: 4px;
    margin: 0 0 18px; padding: 12px 14px;
    border: 1px solid var(--line-soft); border-left: 3px solid var(--accent); border-radius: 8px;
    background: color-mix(in srgb, var(--accent) 6%, transparent);
}
.auth-progress-note strong { color: var(--ink); font-weight: 600; font-size: 0.9rem; }
.auth-progress-note span { color: var(--muted); font-size: 0.82rem; line-height: 1.45; }

/* the Early-Access-date + prizes line beside the progress callout (Register / Play). A quieter footnote than the callout above
   it on purpose: the progress promise is a commitment a player must read, this is marketing. */
.auth-phase-note { margin: -8px 0 18px; color: var(--muted); font-size: 0.82rem; line-height: 1.45; }

/* the "Sign in with Steam" block */
.portal-external { margin-top: 4px; }
.portal-external > p, .auth-or {
    display: flex; align-items: center; gap: 14px;
    margin: 16px 0; color: var(--muted);
    font-size: 0.72rem; letter-spacing: 0.16em; text-transform: uppercase;
}
.portal-external > p::before, .portal-external > p::after,
.auth-or::before, .auth-or::after { content: ""; height: 1px; flex: 1; background: var(--line-soft); }

/* the "already linked? sign in" escape hatch under a disabled Steam CTA (ADR-0158) */
.portal-external__signin { margin-top: 10px; text-align: center; }

/* a tidy footer link row + line */
.auth-links { display: flex; flex-wrap: wrap; gap: 4px 18px; margin-top: 18px; font-size: 0.86rem; }
.auth-foot { text-align: center; color: var(--muted); font-size: 0.88rem; margin: 16px 0 0; }
.auth-foot a { color: var(--accent); font-weight: 600; }

.auth-legal { max-width: 412px; text-align: center; color: var(--muted); font-size: 0.76rem; line-height: 1.5; margin: 0; }
.auth-legal a { color: var(--muted); text-decoration: underline; }

/* ---- focus + motion ------------------------------------------------------- */

:where(a, button, input):focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }

@media (prefers-reduced-motion: reduce) {
    * { animation: none !important; transition: none !important; }
}

/* ---- responsive: stack the descent above the form ------------------------- */

@media (max-width: 900px) {
    .auth-stage { grid-template-columns: 1fr; }
    .auth-abyss { border-right: none; border-bottom: 1px solid var(--line); }
    .auth-abyss__inner { flex: none; }
    .auth-depths { margin-top: 0; }
    .auth-status { position: static; margin: 4px auto -4px; }
}

/* ============================================================================
   Signed-in / landing portal (MainLayout: Home / Play / Manage)
   ============================================================================ */

body {
    background: radial-gradient(120% 70% at 50% -12%, rgba(224, 161, 75, 0.06), transparent 55%), var(--bg);
    background-attachment: fixed;
}

.portal-shell { max-width: 940px; }

.portal-brand {
    font-family: Georgia, "Iowan Old Style", "Times New Roman", serif;
    font-size: 1.05rem; letter-spacing: 0.16em;
}

.portal-main h1 {
    font-family: Georgia, "Iowan Old Style", "Times New Roman", serif;
    font-weight: 400; font-size: clamp(1.6rem, 3vw, 2.1rem);
    letter-spacing: 0.01em; margin: 0.2rem 0 0.6rem; text-wrap: balance;
}
.portal-main h2 {
    font-family: Georgia, "Iowan Old Style", serif; font-weight: 400;
    font-size: 1.12rem; margin: 0 0 0.5rem; color: var(--ink);
}
.portal-main > p, .portal-card > p { color: var(--muted); }

.portal-card h2 { padding-bottom: 0.5rem; margin-bottom: 0.75rem; border-bottom: 1px solid var(--line-soft); }
.portal-card ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.45rem; color: var(--muted); }
.portal-card strong { color: var(--accent); font-weight: 600; }

/* ---- Home: the landing hero ---- */
.portal-hero {
    max-width: 660px; margin: clamp(2rem, 6vh, 4.5rem) auto;
    display: flex; flex-direction: column; align-items: center; text-align: center; gap: 0;
}
.hero-crest {
    width: 64px; height: 64px; display: grid; place-items: center; color: var(--accent);
    border: 1px solid var(--line); border-radius: 16px; margin-bottom: 22px;
    box-shadow: 0 0 40px -14px var(--accent), inset 0 0 20px -12px var(--accent);
    background: radial-gradient(120% 120% at 50% 0%, var(--ember-wash), transparent 70%);
}
.portal-hero h1 {
    font-size: clamp(2.4rem, 6vw, 3.6rem); letter-spacing: 0.14em; text-transform: uppercase; margin: 0;
    background: linear-gradient(180deg, #F7E6BE 0%, var(--accent) 55%, var(--accent-deep) 100%);
    -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero-tag { margin: 14px 0 0; font-size: 0.82rem; letter-spacing: 0.36em; text-transform: uppercase; color: var(--accent); font-weight: 600; }
.hero-lede { margin: 16px 0 0; max-width: 46ch; color: var(--muted); font-size: 1.06rem; line-height: 1.6; }
.portal-hero .portal-cta-row { justify-content: center; margin-top: 1.6rem; }
.hero-features { list-style: none; display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 2rem 0 0; padding: 0; }
.hero-features li { font-size: 0.78rem; color: var(--muted); padding: 7px 14px; border: 1px solid var(--line-soft); border-radius: 999px; }
.hero-features li b { color: var(--ink); font-weight: 600; }

/* ---- Play: the launch gateway ---- */
.portal-launch {
    max-width: 480px; margin: clamp(2rem, 6vh, 4rem) auto; text-align: center;
    background: linear-gradient(180deg, var(--panel-2), var(--panel));
    border: 1px solid var(--line); border-radius: var(--radius);
    padding: 2.2rem 2rem; box-shadow: 0 30px 60px -30px var(--shadow);
}
.portal-launch h1 { margin-top: 0; }
.portal-launch form { margin: 1.3rem 0 0; }
.portal-launch .portal-cta { min-width: 220px; }
.portal-launch .portal-note { margin-top: 1rem; }

/* ---- legal documents (Terms / Privacy) ---- */
.legal-doc { max-width: 72ch; margin: 0.5rem auto 3rem; }
.legal-head { border-bottom: 1px solid var(--line); padding-bottom: 1rem; margin-bottom: 1.5rem; }
.legal-doc h1 { margin: 0 0 0.4rem; }
.legal-meta { color: var(--muted); font-size: 0.82rem; margin: 0; font-family: ui-monospace, Consolas, monospace; letter-spacing: 0.02em; }
.legal-doc h2 {
    font-family: Georgia, "Iowan Old Style", serif; font-weight: 400; font-size: 1.18rem; color: var(--ink);
    margin: 2rem 0 0.5rem;
}
.legal-doc p, .legal-doc li { color: var(--muted); line-height: 1.7; }
.legal-doc ul { padding-left: 1.2rem; display: flex; flex-direction: column; gap: 0.35rem; margin: 0.5rem 0; }
.legal-doc a { color: var(--accent-2); }
.legal-doc strong { color: var(--ink); font-weight: 600; }
.legal-toc { display: flex; flex-wrap: wrap; gap: 0.4rem 1.1rem; margin: 1.25rem 0 0; font-size: 0.88rem; }
.legal-toc a { color: var(--accent-2); text-decoration: none; }
.legal-toc a:hover { text-decoration: underline; }

.portal-footer { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; justify-content: space-between; align-items: center; }
.portal-footer-links a { color: var(--muted); text-decoration: none; }
.portal-footer-links a:hover { color: var(--accent); }

/* ---- admin: sign-up requests ---- */
.admin-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 1rem 0 1.5rem; }
.admin-chip { padding: 8px 14px; border: 1px solid var(--line); border-radius: 999px; color: var(--muted); font-size: 0.85rem; }
.admin-chip b { color: var(--accent); font-weight: 700; }
.admin-table { width: 100%; border-collapse: collapse; margin-top: 0.5rem; font-size: 0.9rem; }
.admin-table th { text-align: left; color: var(--muted); font-weight: 600; font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; padding: 0.5rem 0.6rem; border-bottom: 1px solid var(--line); }
.admin-table td { padding: 0.55rem 0.6rem; border-bottom: 1px solid var(--line-soft); color: var(--ink); }
.admin-table tr:last-child td { border-bottom: none; }
.admin-export { display: block; margin-top: 1rem; color: var(--muted); font-size: 0.8rem; }
.admin-export textarea { display: block; width: 100%; margin-top: 0.4rem; background: var(--field); border: 1px solid var(--line-soft); border-radius: 8px; color: var(--ink); font-family: ui-monospace, Consolas, monospace; font-size: 0.82rem; padding: 0.6rem; resize: vertical; }
.admin-approve { appearance: none; border: 1px solid var(--accent); background: transparent; color: var(--accent); font: 600 0.78rem/1 system-ui, sans-serif; padding: 6px 14px; border-radius: 8px; cursor: pointer; transition: background .18s, color .18s; }
.admin-approve:hover { background: var(--accent); color: #1a140a; }
.admin-badge { color: var(--ok); font-size: 0.82rem; font-weight: 600; }

/* ============================================================================
   Alerot STUDIO front (Home + /games/*) — "Living Systems" direction.
   The identity is grounded in what the studio makes: systems that keep running
   whether or not you're watching. The hero is a live counter (studio-live.js)
   that never stops; ornament is stripped (no mono micro-labels, no numbered
   section counts, no hairline-rule headers, no grid texture). Display is a
   tight sans; monospace appears ONLY on live numbers, where it's honest. The
   three game accents carry the colour. Everything scoped under .studio.
   ============================================================================ */
.studio {
    /* raw palette */
    --ink:#0E1014; --panel:#161A22; --line:#262C38; --mist:#8A93A6; --ivory:#ECE7DA; --brass:#C8A24A;
    --factory:#43B7A4; --entropy:#C664A6; --abyss:#D0473A;

    /* semantic tokens — default = dark */
    --bg:var(--ink); --surface:var(--panel); --border:var(--line);
    --text:var(--ivory); --muted:var(--mist); --accent:var(--brass);
    --glow:rgba(200,162,74,.10);

    --sans:system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
    --mono:ui-monospace,"Cascadia Code","SF Mono","Segoe UI Mono",Menlo,Consolas,monospace;
    --maxw:1120px; --radius:6px;

    position:relative; min-height:100vh; display:flex; flex-direction:column;
    background:var(--bg); color:var(--text);
    font-family:var(--sans); font-size:1.0625rem; line-height:1.6;
    -webkit-font-smoothing:antialiased;
}
@media (prefers-color-scheme: light) {
    .studio:not(.theme-dark) {
        --bg:#F4F1E9; --surface:#FBFAF5; --border:#E0DACB;
        --text:#181A1E; --muted:#5C6270; --accent:#8A6A17; --glow:rgba(138,106,23,.10);
    }
}
.studio.theme-light {
    --bg:#F4F1E9; --surface:#FBFAF5; --border:#E0DACB;
    --text:#181A1E; --muted:#5C6270; --accent:#8A6A17; --glow:rgba(138,106,23,.10);
}

.studio *, .studio *::before, .studio *::after { box-sizing:border-box; }
.studio a { color:inherit; text-decoration:none; }
.studio .wrap { width:100%; max-width:var(--maxw); margin:0 auto; padding:0 clamp(20px,5vw,44px); }
.studio :focus-visible { outline:2px solid var(--accent); outline-offset:3px; border-radius:3px; }
.studio .studio-main { flex:1; }
.studio section { padding:clamp(44px,8vh,88px) 0; }
.studio .sec-title { font-size:clamp(1.15rem,2.6vw,1.5rem); font-weight:700; letter-spacing:-.01em; margin:0 0 28px; color:var(--text); }
/* Per-game accent as CLASSES (not inline style="--c:…"): the strict portal CSP is style-src 'self' with no
   'unsafe-inline', so inline style attributes are blocked — a class is the only way to set --c per game. */
.studio .accent-factory { --c:var(--factory); }
.studio .accent-entropy { --c:var(--entropy); }
.studio .accent-abyss { --c:var(--abyss); }

/* ---------- top bar ---------- */
.studio .topbar { position:sticky; top:0; z-index:20; background:color-mix(in srgb, var(--bg) 88%, transparent); -webkit-backdrop-filter:blur(9px); backdrop-filter:blur(9px); border-bottom:1px solid var(--border); }
.studio .topbar .wrap { display:flex; align-items:center; justify-content:space-between; min-height:62px; gap:16px; }
/* Brand mark — the arcade-cabinet emblem + ALEROT wordmark (Components/Shared/AlerotMark.razor).
   That SVG deliberately carries no <style> element and no style="" attributes: the portal CSP is
   style-src 'self' with no 'unsafe-inline', so either would be blocked and the mark would render
   as solid black. Its colour therefore lives HERE, and because it reads the studio's own theme
   variables it tracks the light/dark toggle for free — same behaviour the old text mark had
   (wordmark in --text, accent in --accent). */
.studio .mark { display:inline-flex; align-items:center; }
.studio .alerot-mark { display:block; height:34px; width:auto; }
.studio .alerot-mark .am-emblem { fill:var(--accent); fill-rule:evenodd; }
.studio .alerot-mark .am-word { fill:var(--text); }
.studio .topnav { display:flex; align-items:center; gap:22px; }
.studio .topnav a { font-size:.95rem; color:var(--muted); transition:color .16s ease; }
.studio .topnav a:hover { color:var(--text); }
.studio .theme-btn { font:inherit; font-size:.9rem; color:var(--muted); background:transparent; border:1px solid var(--border); border-radius:999px; padding:6px 13px; cursor:pointer; transition:color .16s ease, border-color .16s ease; }
.studio .theme-btn:hover { color:var(--text); border-color:var(--accent); }

/* ---------- hero: the living counter ---------- */
.studio .lead-hero { padding:clamp(64px,13vh,132px) 0 clamp(36px,6vh,64px); position:relative; }
/* The hero tints to the per-load game accent (--c set by the .accent-* class on .lead-hero), falling back to the
   studio brass when no game class is present. */
.studio .lead-hero::before { content:""; position:absolute; inset:-10% -20% 30% 30%; z-index:0; background:radial-gradient(60% 60% at 70% 20%, color-mix(in srgb, var(--c, var(--accent)) 13%, transparent), transparent 70%); pointer-events:none; }
.studio .lead-hero .wrap { position:relative; z-index:1; max-width:960px; }
/* Hero mark. Was a text wordmark at clamp(3.4rem,13vw,7.5rem); the lockup is sized to
   keep roughly the same optical weight, its own wordmark landing near the old cap height.
   Uses the FULL cabinet (AlerotLockup) rather than the chrome's simplified icon — there
   is room for the detail here. The LEDs are semantic colour, so they are literals rather
   than theme tokens; everything else follows --accent / --text like the rest of the mark. */
.studio .wordmark { margin:0; line-height:0; }
/* Width-driven, not height-driven. Sizing these by height looked right on desktop but the
   wide aspect then demanded more width than a 360px phone's content column, so the page
   scrolled sideways. Capping the WIDTH makes overflow impossible by construction. */
.studio .alerot-lockup { display:block; width:min(100%,720px); height:auto; }
/* The animated hero logo carries its own circuit field, so it runs wider than the lockup
   and needs no extra breathing room around it. Centred on purpose: the mark sits in the
   middle of its own viewBox with the trace field spread symmetrically around it, so
   flush-left would leave it looking shunted rather than aligned. Width-capped, so it can
   never outgrow the column. */
.studio .wordmark .alerot-logo { display:block; width:min(100%,820px); height:auto;
                                 margin:-14px auto -22px; }
/* Deliberately --accent, NOT the per-load game tint --c that the old glyph used. Tinting a
   single letter read as an accent; tinting the whole emblem reads as "the logo is pink this
   time". The per-game colour still carries the counter, the caret and the game link below. */
.studio .alerot-lockup .am-emblem { fill:var(--accent); fill-rule:evenodd; }
.studio .alerot-lockup .am-word { fill:var(--text); }
.studio .alerot-lockup .am-led-red { fill:#D0473A; }
.studio .alerot-lockup .am-led-green { fill:#3FA96B; }

.studio .live { margin:34px 0 0; display:flex; flex-direction:column; gap:8px; }
.studio .live-num { font-family:var(--mono); font-weight:600; font-variant-numeric:tabular-nums; font-size:clamp(1.9rem,6vw,3.4rem); line-height:1; letter-spacing:-.01em; color:var(--text); }
.studio .live-num .caret { color:var(--c, var(--accent)); }
.studio .live-cap { font-size:.98rem; color:var(--muted); }
.studio .live-cap b { color:var(--c, var(--accent)); font-weight:600; }
.studio .live-sub { font-family:var(--mono); font-variant-numeric:tabular-nums; font-size:.86rem; color:var(--muted); min-height:1.2em; }
.studio .live-link { align-self:flex-start; margin-top:4px; font-size:.9rem; font-weight:600; color:var(--c, var(--accent)); }
.studio .live-link:hover { text-decoration:underline; text-underline-offset:3px; }
.studio .tickstream { height:22px; margin:26px 0 0; border-radius:3px; background:repeating-linear-gradient(90deg, var(--muted) 0 1px, transparent 1px 13px); opacity:.32; -webkit-mask-image:linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); mask-image:linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); animation:studio-drift 5.5s linear infinite; }
@keyframes studio-drift { from { background-position-x:0; } to { background-position-x:-13px; } }

.studio .hero-copy { margin:30px 0 0; max-width:56ch; font-size:1.12rem; line-height:1.62; color:var(--text); }
.studio .hero-copy .muted { color:var(--muted); }

/* ---------- games ---------- */
.studio .games { display:grid; gap:22px; grid-template-columns:repeat(auto-fit, minmax(290px,1fr)); }
.studio .card { --c:var(--accent); position:relative; background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); overflow:hidden; display:flex; flex-direction:column; color:inherit; transition:transform .22s ease, border-color .22s ease, box-shadow .22s ease; }
.studio a.card:hover { transform:translateY(-4px); border-color:color-mix(in srgb, var(--c) 55%, var(--border)); box-shadow:0 20px 44px -26px color-mix(in srgb, var(--c) 75%, transparent); }
.studio .card::before { content:""; position:absolute; top:0; left:0; right:0; height:3px; background:var(--c); z-index:3; }
.studio .capsule { position:relative; aspect-ratio:16/9; overflow:hidden; border-bottom:1px solid var(--border); }
.studio .capsule svg { position:absolute; inset:0; width:100%; height:100%; display:block; }
/* Theme-adaptive capsule art: art uses currentColor (= accent --c); background gradient stops are CSS-driven
   so the header pictures flip with the theme — tinted-dark in dark mode, warm-paper tint in light mode. */
.studio .capsule { color:var(--c); }
.studio .capsule .cap-a { stop-color:color-mix(in srgb, var(--c) 16%, var(--bg)); }
.studio .capsule .cap-b { stop-color:color-mix(in srgb, var(--c) 4%, var(--bg)); }
.studio .capsule .cap-hi { color:color-mix(in srgb, var(--c) 55%, var(--text)); }
.studio .cap-tag { position:absolute; left:13px; bottom:11px; z-index:2; font-size:.82rem; color:var(--text); background:color-mix(in srgb, var(--bg) 74%, transparent); border:1px solid var(--border); padding:3px 10px; border-radius:999px; -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px); }
.studio .cap-status { position:absolute; right:13px; top:13px; z-index:2; font-size:.8rem; font-weight:600; color:var(--c); }
/* The release-date tease chip, directly under the status chip on the Abyss Floors capsule
   (ReleaseFacts.CapsuleReleaseTease). Its top offset is COMPUTED from the status chip above it — 13px (that chip's own
   top) + 1.6em of its line box — not a fixed 35px: .cap-status is sized in rem, so a browser/user root font larger than
   16px would grow it straight through a hard-coded offset and overlap the two chips. The em here resolves against THIS
   element's font-size, which is set on the same line, so the two scale together. */
.studio .cap-when { position:absolute; right:13px; top:calc(13px + 1.6em); z-index:2; font-size:.74rem; font-weight:600; color:var(--text); background:color-mix(in srgb, var(--bg) 74%, transparent); border:1px solid var(--border); padding:2px 9px; border-radius:999px; -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px); }
.studio .card-body { padding:20px 22px 22px; display:flex; flex-direction:column; gap:11px; flex:1; }
.studio .card h3 { font-weight:700; font-size:1.4rem; line-height:1.1; margin:0; letter-spacing:-.01em; color:var(--text); }
.studio .tags { font-size:.9rem; color:var(--muted); margin:-3px 0 0; }
.studio .pitch { margin:0; color:var(--muted); font-size:.98rem; line-height:1.6; }
.studio .pitch strong { color:var(--text); font-weight:600; }
.studio .card-foot { margin-top:auto; padding-top:8px; display:flex; align-items:center; justify-content:space-between; gap:12px; }
.studio .card-foot .avail { font-size:.88rem; color:var(--muted); }
.studio .card-foot .more { font-size:.95rem; font-weight:600; color:var(--c); }
.studio a.card:hover .more { text-decoration:underline; text-underline-offset:3px; }

/* ---------- CTA button (detail pages) ---------- */
.studio .cta { font-size:.98rem; font-weight:650; color:var(--bg); background:var(--c); padding:12px 20px; border-radius:var(--radius); display:inline-flex; align-items:center; gap:9px; border:1px solid transparent; transition:transform .16s ease, filter .16s ease; }
.studio a.cta:hover { filter:brightness(1.07); transform:translateY(-1px); }
.studio .cta svg { width:14px; height:14px; }
.studio .cta.ghost { color:var(--text); background:transparent; border-color:var(--border); }
.studio a.cta.ghost:hover { border-color:var(--accent); filter:none; }

/* ---------- game detail page ---------- */
.studio .gdetail { --c:var(--accent); }
.studio .gdetail .wrap { max-width:900px; }
.studio .gback { display:inline-flex; align-items:center; gap:7px; font-size:.95rem; color:var(--muted); margin-bottom:26px; }
.studio .gback:hover { color:var(--text); }
.studio .gdetail .capsule { aspect-ratio:21/9; border:1px solid var(--border); border-radius:var(--radius); margin-bottom:30px; }
.studio .gdetail h1 { font-weight:800; font-size:clamp(2.1rem,5.6vw,3.1rem); line-height:1.02; letter-spacing:-.02em; margin:0; color:var(--text); }
.studio .gdetail .genre { font-size:1rem; color:var(--c); font-weight:600; margin:12px 0 0; }
.studio .gdetail .desc { margin:22px 0 0; max-width:66ch; }
.studio .gdetail .desc p { margin:0 0 1.05em; color:var(--text); font-size:1.08rem; line-height:1.7; }
.studio .gdetail .desc p:last-child { margin-bottom:0; }
.studio .gdetail .desc em { color:var(--c); font-style:normal; font-weight:600; }
.studio .soon-badge { display:inline-flex; align-items:center; gap:8px; font-size:.9rem; font-weight:600; color:var(--abyss); border:1px solid color-mix(in srgb, var(--abyss) 55%, var(--border)); background:color-mix(in srgb, var(--abyss) 10%, transparent); border-radius:999px; padding:5px 14px; margin:16px 0 0; }
.studio .soon-badge::before { content:""; width:7px; height:7px; border-radius:50%; background:var(--abyss); }
/* the release announcement block on the game page (Early Access date / 1.0 date / prize tease — all from ReleaseFacts).
   Reads as a pinned note next to the status badge, in the accent the rest of the page already uses. */
.studio .announce { margin:20px 0 0; max-width:66ch; padding:14px 16px; border:1px solid color-mix(in srgb, var(--abyss) 40%, var(--border)); border-left:3px solid var(--abyss); border-radius:var(--radius); background:color-mix(in srgb, var(--abyss) 7%, transparent); }
/* NOT a mono uppercase micro-label: the studio direction reserves monospace for live numbers "where it's honest"
   and strips mono micro-labels (see the .studio block comment). Plain accent-coloured sans, like .genre. */
.studio .an-kicker { display:block; font-size:.8rem; font-weight:700; letter-spacing:.02em; color:var(--abyss); margin-bottom:8px; }
.studio .an-list { margin:0; padding:0; list-style:none; display:flex; flex-direction:column; gap:5px; }
.studio .an-list li { font-size:.96rem; line-height:1.5; color:var(--muted); }
.studio .an-list li.an-date { color:var(--text); font-weight:600; }
.studio .facts { display:flex; flex-wrap:wrap; gap:8px; margin:22px 0 0; padding:0; list-style:none; }
.studio .facts li { font-size:.9rem; color:var(--muted); border:1px solid var(--border); border-radius:999px; padding:5px 13px; }
.studio .gcta { display:flex; flex-wrap:wrap; gap:12px; margin:30px 0 0; }

/* ---------- game detail: lore + feature sections + screenshots ----------
   The page is one <section class="gdetail">, so these blocks are DIVs/ARTICLEs on purpose: `.studio section` carries
   clamp(44px,8vh,88px) of vertical padding and a nested <section> would inherit it and shove the page apart. */
.studio .gsec-title { font-size:clamp(1.2rem,3vw,1.6rem); font-weight:700; line-height:1.2; letter-spacing:-.01em; margin:0 0 12px; color:var(--text); }

/* The lore blurb (LoreCopy / docs/game/lore-blurb.md). Set apart from the marketing copy by a rule and the accent
   bar — it is the only block on the page speaking in the game's voice rather than about the game. */
.studio .lore { margin:44px 0 0; padding:24px 0 4px; border-top:1px solid var(--border); max-width:66ch; }
.studio .lore p { margin:0 0 1.05em; color:var(--muted); font-size:1.06rem; line-height:1.75; }
.studio .lore p:first-of-type { color:var(--text); }
.studio .lore .lore-tag { margin:18px 0 0; color:var(--c); font-weight:700; letter-spacing:.06em; font-size:1rem; }

/* A sub-heading INSIDE a feature section (the Forge note under "An economy players own"): smaller than the section
   title and in the page accent, so the section reads as one subject with two halves rather than two sections. */
.studio .gsub-title { font-size:1.02rem; font-weight:700; letter-spacing:-.005em; margin:26px 0 8px; color:var(--c); }

.studio .gsecs { margin:8px 0 0; }
.studio .gsec { padding:36px 0 0; }
.studio .gsec p { margin:0 0 1.05em; max-width:66ch; color:var(--text); font-size:1.04rem; line-height:1.7; }
.studio .gsec p:last-of-type { margin-bottom:0; }
/* Short supporting bullets for the sections that carry no screenshot, so a text-only section still has structure. */
.studio .gspecs { margin:16px 0 0; padding:0; list-style:none; max-width:66ch; display:flex; flex-direction:column; gap:7px; }
.studio .gspecs li { position:relative; padding-left:18px; font-size:.98rem; line-height:1.55; color:var(--muted); }
.studio .gspecs li::before { content:""; position:absolute; left:0; top:.62em; width:6px; height:1px; background:var(--c); }
.studio .gspecs b { color:var(--text); font-weight:600; }

/* Screenshots. Real client renders (docs/marketing/assets), never mock-ups. width/height are on every <img> so the
   aspect ratio is reserved before the bytes land — a lazy image without them reflows the whole page as it decodes. */
.studio .shot { margin:20px 0 0; }
.studio .shot img { display:block; width:100%; height:auto; border:1px solid var(--border); border-radius:var(--radius); background:#0E0E13; }
.studio .shot figcaption { margin:9px 2px 0; font-size:.88rem; line-height:1.5; color:var(--muted); }

/* ---------- "watch a fight" combat demo (combat-demo.js) ----------
   A fixed-dark game "screen" (reads as an embedded viewport in either studio theme). Bar widths + log lines are
   driven by JS via CSSOM property setters (CSP-safe); colours mirror the real combat view. */
.studio .combat-demo {
    --cd-green:#5FB86A; --cd-greenb:#8DE6A6; --cd-red:#E0605A; --cd-gold:#E6B45C; --cd-teal:#43C9C2; --cd-loot:#8FB8E8;
    --cd-ink:#100F17; --cd-panel:#171622; --cd-line:rgba(255,255,255,.09); --cd-dim:#8C8798; --cd-fg:#E8E6F0;
    margin:26px 0 0; border:1px solid var(--cd-line); border-radius:var(--radius); overflow:hidden; background:var(--cd-ink); color:var(--cd-fg);
}
.studio .cd-head { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:11px 16px; border-bottom:1px solid var(--cd-line); background:var(--cd-panel); }
.studio .cd-title { font-family:var(--mono); font-size:.74rem; letter-spacing:.14em; text-transform:uppercase; color:var(--cd-gold); display:inline-flex; align-items:center; gap:9px; }
.studio .cd-title::before { content:""; width:7px; height:7px; border-radius:50%; background:var(--cd-red); box-shadow:0 0 7px var(--cd-red); }
.studio .cd-zone { font-family:var(--mono); font-size:.74rem; color:var(--cd-dim); }
.studio .cd-bars { padding:14px 16px 6px; display:flex; flex-direction:column; gap:11px; }
.studio .cd-bar-label { display:flex; justify-content:space-between; gap:12px; font-family:var(--mono); font-size:.73rem; color:var(--cd-dim); margin-bottom:4px; }
.studio .cd-bar-label .nm { color:var(--cd-fg); }
.studio .cd-track { height:9px; border-radius:5px; background:rgba(255,255,255,.06); overflow:hidden; }
.studio .cd-fill { height:100%; width:100%; border-radius:5px; }
.studio .cd-fill-enemy { background:linear-gradient(90deg,#B23A34,#E0605A); transition:width .18s linear; }
.studio .cd-fill-player { background:linear-gradient(90deg,#3E8F49,#5FB86A); transition:width .18s linear; }
.studio .cd-swing .cd-track { height:6px; }
.studio .cd-fill-swing { width:0; background:linear-gradient(90deg,#B07A2A,#E6B45C); }
.studio .cd-swing.is-respawn .cd-fill-swing { background:linear-gradient(90deg,#2E8F8A,#43C9C2); }
.studio .cd-log { list-style:none; margin:0; padding:12px 16px 16px; font-family:var(--mono); font-size:.82rem; line-height:1.7; min-height:11.9em; }
.studio .cd-line { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.studio .cd-hit { color:var(--cd-green); }
.studio .cd-crit { color:var(--cd-greenb); font-weight:700; }
.studio .cd-ehit { color:var(--cd-red); }
.studio .cd-kill { color:var(--cd-greenb); }
.studio .cd-reward { color:var(--cd-gold); }
.studio .cd-loot { color:var(--cd-loot); }
.studio .cd-level { color:var(--cd-gold); font-weight:700; letter-spacing:.03em; }
.studio .cd-respawn { color:var(--cd-teal); }
@media (prefers-reduced-motion: reduce) { .studio .cd-fill-enemy, .studio .cd-fill-player { transition:none; } }

/* ---------- studio / about ---------- */
.studio .about .wrap { max-width:820px; }
.studio .about p { font-size:clamp(1.15rem,2.4vw,1.4rem); line-height:1.55; margin:0; color:var(--text); }
.studio .about p .k { color:var(--accent); font-weight:600; }
.studio .focus-list { margin:30px 0 0; padding:0; list-style:none; display:grid; gap:0; }
.studio .focus-list li { display:flex; gap:18px; padding:16px 0; border-top:1px solid var(--border); }
.studio .focus-list li:last-child { border-bottom:1px solid var(--border); }
.studio .focus-list .ft { flex:0 0 8.5rem; font-weight:600; color:var(--text); }
.studio .focus-list .fd { color:var(--muted); }

/* ---------- footer ---------- */
.studio footer { border-top:1px solid var(--border); padding:52px 0 44px; margin-top:24px; }
.studio footer .wrap { display:flex; flex-wrap:wrap; gap:34px; justify-content:space-between; align-items:flex-start; }
.studio .fmark { display:flex; }
.studio .fmark .alerot-mark { height:29px; }
.studio .tag { color:var(--muted); font-size:.98rem; margin:10px 0 0; max-width:34ch; }
.studio .flinks { display:flex; flex-direction:column; gap:9px; }
.studio .flinks .lab { font-size:.82rem; color:var(--muted); margin-bottom:2px; }
.studio .flinks a { color:var(--text); font-size:.98rem; transition:color .16s ease; }
.studio .flinks a:hover { color:var(--accent); }
.studio .legal { margin-top:38px; padding-top:20px; border-top:1px solid var(--border); font-size:.85rem; color:var(--muted); display:flex; flex-wrap:wrap; gap:6px 18px; justify-content:space-between; }

@media (max-width:560px) { .studio .topnav { gap:14px; } .studio .topnav .nav-link { display:none; } }
@media (prefers-reduced-motion: reduce) { .studio *, .studio *::before { animation:none !important; transition:none !important; } }

/* ---- /store (ADR-0182 P1) --------------------------------------------------
   The v1 purchase UI (owner decision OD-4). Same panel/ember system as the rest
   of the portal chrome — no new palette, no new radii. */

.portal-store { max-width: 46rem; }

.portal-store-grid { display: grid; gap: 1rem; }

.portal-store-sku h2 { margin: 0 0 0.35rem; font-size: 1.15rem; }

.portal-store-buy {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem;
    margin-top: 0.9rem;
}

/* The price, as a plain figure. There is ONE price worldwide (owner 2026-08-30),
   so the currency <select> that used to sit here is gone — nothing to choose. */
.portal-store-price {
    margin: 0;
    font-size: 1.35rem;
    font-weight: 600;
    color: var(--ink);
    line-height: 1.1;
}

/* The EU withdrawal-waiver acknowledgement (owner 2026-08-30). It takes the whole
   width of the flex row ON PURPOSE, so it always sits ABOVE the button instead of
   beside it: a consent a buyer scrolls past is not the express consent art. 16(m)
   asks for. Do not shrink it into fine print. */
.portal-store-ack {
    display: flex;
    flex-basis: 100%;
    align-items: flex-start;
    gap: 0.55rem;
    color: var(--muted);
    font-size: 0.9rem;
    line-height: 1.45;
    cursor: pointer;
}

.portal-store-ack input {
    flex: none;
    margin-top: 0.22rem;
}

/* A disabled Buy is a STATE ("not yet"), not a broken control — it has to send the
   buyer's eye back up to the box. */
.portal-store-buy .portal-cta[disabled] {
    opacity: 0.55;
    cursor: not-allowed;
}

/* The sandbox banner is deliberately loud: a tester must never wonder whether a
   real card was charged. */
.portal-store-sandbox {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    border: 1px dashed var(--accent-2);
    border-radius: 10px;
    padding: 0.7rem 0.95rem;
    color: var(--muted);
    font-size: 0.9rem;
}

.portal-store-sandbox strong { color: var(--accent-2); }

/* Empty until the script has something honest to say — never a pre-baked
   "success" that markup alone could imply. */
.portal-store-status:empty { display: none; }

.portal-store-status {
    margin-top: 1rem;
    padding: 0.7rem 0.95rem;
    border-radius: 10px;
    border: 1px solid var(--line-soft);
    background: var(--panel);
    font-size: 0.95rem;
}

.portal-store-status[data-kind="ok"] { border-color: var(--ok); color: var(--ok); }
.portal-store-status[data-kind="error"] { border-color: var(--err); color: var(--err); }

@media (max-width: 520px) {
    .portal-store-buy { align-items: stretch; }
    .portal-store-buy .portal-cta { width: 100%; }
    .portal-store-price { width: 100%; }
}
