/* Generated from styles.css by scripts/build-public-css.js. Do not edit. */
:root {
    color-scheme: dark;
    --bg: #08090d;
    --surface: #0d0e14;
    --surface-2: #12131b;
    --panel: #11121a;
    --panel-strong: #151622;
    --line: rgba(139, 92, 246, 0.26);
    --line-soft: color-mix(in srgb, var(--text) 9%, transparent);
    --text: #f3f0fa;
    --muted: #9a94a8;
    --text-main: var(--text);
    --text-muted: var(--muted);
    --purple: #8b5cf6;
    --brand: var(--purple);
    --purple-2: #c084fc;
    --pink: #f472b6;
    --cyan: #22d3ee;
    --green: #22c55e;
    --red: #ef4444;
    /* Corner scale: every radius on the site is one of these or a pill (999px).
       Discord look-alikes (embeds, Discord buttons) keep Discord's own radii. */
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 16px;
}

/* `hidden` always wins: a class that sets display (flex, block) silently undid it,
   leaving empty embed buttons, image gaps and the API key tab row on screen. */
[hidden]:not([hidden="until-found"]) { display: none !important; }

* {
    scrollbar-color: rgba(139, 92, 246, 0.55) color-mix(in srgb, var(--text) 4%, transparent);
}

body {
    min-height: 100vh;
    background: var(--bg);
    /* The theme's own text colour: a fixed near-black went invisible on every
       dark theme for anything that inherited from body. */
    color: var(--text, #111827);
    font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    letter-spacing: 0;
}

a,
button,
input,
textarea,
select {
    letter-spacing: 0;
}

/* Phone feel: no grey flash on tap (buttons have their own press state), and
   16px text in fields on touch screens, below which iOS Safari zooms the page. */
html {
    -webkit-tap-highlight-color: transparent;
}

@media (pointer: coarse), (max-width: 820px) {
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
    select,
    textarea {
        font-size: 16px;
    }
}

/* A button with no background of its own fell back to the browser's control
   grey (rgb(107,107,107) + white border in dark mode): "Chat with us",
   "Remove token", the sidebar close. :where() keeps this at zero specificity,
   so any class that styles a button still wins. */
:where(button) {
    background-color: transparent;
    border: 0;
    color: inherit;
}

.shell {
    width: min(1480px, 100%);
    margin: 0 auto;
}

.topbar {
    border-bottom: 1px solid var(--line-soft);
    background: rgba(8, 9, 13, 0.94);
    backdrop-filter: blur(12px);
}

.panel {
    background: var(--panel);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-md);
    box-shadow: none;
}

.panel-strong {
    background: var(--panel-strong);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-md);
}

.app-sidebar {
    background: #090a0f;
}

.brand-link:hover .brand-text {
    color: #F4F4F4;
}

.brand-mark {
    background: #151322;
    border: 1px solid rgba(139, 92, 246, 0.24);
}

.user-chip {
    max-width: min(16rem, 42vw);
}

.user-chip span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.brand-text {
    color: #f5f3ff;
}

.muted {
    color: var(--muted);
}

.hint {
    display: block;
    margin-top: 0.35rem;
    color: var(--muted);
    font-size: 0.78rem;
    line-height: 1.4;
}

.role-checklist {
    display: grid;
    gap: 0.15rem;
    max-height: 15rem;
    overflow-y: auto;
    padding: 0.55rem;
    background: rgba(var(--surface-rgb), 0.72);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    box-shadow: inset 0 0 0 1px rgba(var(--surface-rgb), 0.24);
    scrollbar-color: #b58dff transparent;
    scrollbar-width: thin;
}

.role-checklist::-webkit-scrollbar {
    width: 0.65rem;
}

.role-checklist::-webkit-scrollbar-track {
    background: transparent;
}

.role-checklist::-webkit-scrollbar-thumb {
    background: #b58dff;
    border-radius: 999px;
}

.role-checklist.is-disabled {
    opacity: 0.62;
    background: rgba(var(--surface-rgb), 0.42);
}

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 2.5rem;
    border-radius: var(--radius-md); /* one radius for every button (the md step) */
    padding: 0.6rem 0.9rem;
    font-weight: 700;
    transition: transform 160ms ease, border-color 160ms ease, background 160ms ease;
}

@media (hover: hover) and (pointer: fine) {
.btn:hover {
    transform: none;
}
}

.btn-primary {
    background: #7c3aed;
    color: #F4F4F4;
    box-shadow: none;
}

.btn-secondary {
    background: #171821;
    border: 1px solid var(--line-soft);
    color: #F4F4F4;
}

.btn-danger,
.btn-bad {
    background: rgba(239, 68, 68, 0.12);
    border: 1px solid rgba(239, 68, 68, 0.32);
    color: #fecaca;
}

.btn-disabled {
    background: color-mix(in srgb, var(--text) 4%, transparent);
    border: 1px solid color-mix(in srgb, var(--text) 8%, transparent);
    color: #8b819c;
    cursor: not-allowed;
}

@media (hover: hover) and (pointer: fine) {
.btn-disabled:hover {
    transform: none;
}
}

.icon-btn {
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
}

.field,
.select,
.textarea {
    width: 100%;
    border-radius: var(--radius-md);
    border: 1px solid var(--line-soft);
    background: #0b0c12;
    color: var(--text);
    outline: none;
    padding: 0.75rem 0.85rem;
}

.textarea {
    min-height: 7rem;
    resize: vertical;
}

.field:focus,
.select:focus,
.textarea:focus {
    border-color: rgba(139, 92, 246, 0.7);
    box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.14);
}

.label {
    display: block;
    margin-bottom: 0.4rem;
    color: #d8ccff;
    font-size: 0.78rem;
    font-weight: 800;
    text-transform: uppercase;
}

.help {
    margin-top: 0.35rem;
    color: var(--muted);
    font-size: 0.78rem;
}

.badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    min-height: 1.75rem;
    border-radius: var(--radius-sm);
    border: 1px solid var(--line-soft);
    background: color-mix(in srgb, var(--text) 6%, transparent);
    padding: 0.25rem 0.65rem;
    font-size: 0.75rem;
    font-weight: 800;
    line-height: 1;
    white-space: nowrap;
}

.badge-good {
    border-color: rgba(34, 197, 94, 0.34);
    background: rgba(34, 197, 94, 0.12);
    color: #86efac;
}

.badge-warn {
    border-color: rgba(251, 191, 36, 0.34);
    background: rgba(251, 191, 36, 0.1);
    color: #fde68a;
}

.badge-bad {
    border-color: rgba(239, 68, 68, 0.34);
    background: rgba(239, 68, 68, 0.1);
    color: #fecaca;
}

.table-wrap {
    width: 100%;
    overflow-x: auto;
}

.data-table {
    width: 100%;
    border-collapse: collapse;
    min-width: 720px;
}

.data-table th {
    color: var(--muted);
    font-size: 0.72rem;
    text-align: left;
    text-transform: uppercase;
    padding: 0.9rem 1rem;
    border-bottom: 1px solid rgba(var(--surface-rgb), 0.1);
}

.data-table td {
    padding: 0.95rem 1rem;
    border-bottom: 1px solid color-mix(in srgb, var(--text) 5%, transparent);
}

.nav-link {
    display: flex;
    align-items: center;
    gap: 0.72rem;
    border-radius: var(--radius-md);
    color: #bdb6ca;
    padding: 0.64rem 0.72rem;
    font-weight: 700;
}

@media (hover: hover) and (pointer: fine) {
.nav-link:hover {
    background: #12131b;
    color: #F4F4F4;
}
}

.nav-link-active,
.nav-pill {
    background: #17142a;
    color: #F4F4F4;
    border: 1px solid rgba(139, 92, 246, 0.28);
}

.info-list {
    padding: 0;
}

.info-row {
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    gap: 0.75rem;
    align-items: center;
    min-height: 1.8rem;
    border-top: 1px solid color-mix(in srgb, var(--text) 6%, transparent);
    color: var(--muted);
    font-size: 0.76rem;
}

.info-row:first-child {
    border-top: 0;
}

.info-row strong {
    display: inline-flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.4rem;
    min-width: 0;
    color: #efeaf8;
    font-weight: 700;
    text-align: right;
}

.status-dot {
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 999px;
    background: #22c55e;
}

.sidebar-invoices {
    box-shadow: none;
}

.invoice-mini {
    display: block;
    border-radius: var(--radius-md);
    border: 1px solid color-mix(in srgb, var(--text) 7%, transparent);
    background: rgba(0, 0, 0, 0.2);
    padding: 0.65rem;
    color: #eee9ff;
}

.invoice-mini-thumb {
    width: 2.8rem;
    height: 2.8rem;
    flex: 0 0 auto;
    border-radius: var(--radius-md);
    border: 1px solid rgba(var(--surface-rgb), 0.12);
    object-fit: cover;
    background: color-mix(in srgb, var(--text) 5%, transparent);
}

.invoice-mini-thumb-empty,
.invoice-thumb-empty {
    display: inline-grid;
    place-items: center;
    color: var(--muted);
}

@media (hover: hover) and (pointer: fine) {
.invoice-mini:hover {
    border-color: rgba(192, 132, 252, 0.35);
    background: rgba(139, 92, 246, 0.12);
}
}

.invoice-mini-top,
.invoice-mini-bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.7rem;
    min-width: 0;
}

.invoice-mini-top {
    font-size: 0.72rem;
}

.invoice-mini-bottom {
    margin-top: 0.3rem;
    color: var(--muted);
    font-size: 0.68rem;
}

.sidebar-empty {
    border-radius: var(--radius-md);
    border: 1px dashed rgba(var(--surface-rgb), 0.12);
    color: var(--muted);
    font-size: 0.78rem;
    padding: 0.9rem;
    text-align: center;
}

.setup-progress {
    height: 0.45rem;
    overflow: hidden;
    border-radius: 999px;
    border: 1px solid color-mix(in srgb, var(--text) 8%, transparent);
    background: color-mix(in srgb, var(--text) 5%, transparent);
}

.setup-progress span {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: #22c55e;
}

.toggle-row {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    color: var(--text);
    cursor: pointer;
}

.toggle-row input {
    margin-top: 0.2rem;
    width: 1rem;
    height: 1rem;
    accent-color: var(--purple);
}

.toggle-row strong,
.toggle-row small {
    display: block;
}

.toggle-row small {
    margin-top: 0.15rem;
    color: var(--muted);
    font-size: 0.78rem;
}

.ticket-panel-card,
.ticket-v2-card,
.ticket-link-card {
    border: 1px solid color-mix(in srgb, var(--text) 8%, transparent);
    border-radius: var(--radius-md);
    background: #0f1017;
    padding: 1rem;
}

.ticket-v2-card .badge {
    width: auto;
    height: auto;
    min-width: 0;
    min-height: 0;
    aspect-ratio: auto;
    justify-content: center;
    white-space: nowrap;
    border-radius: var(--radius-md);
    padding: 0.35rem 0.65rem;
}

.modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: rgba(0, 0, 0, 0.78);
    backdrop-filter: blur(10px);
}

.toast {
    position: fixed;
    right: 1rem;
    /* Above the live-chat launcher (3.5rem, pinned to the same corner at
       z-index 1200) - at bottom:1rem the toast was hidden behind it. */
    bottom: 5.75rem;
    z-index: 1300;
    max-width: min(24rem, calc(100vw - 2rem));
    border-radius: var(--radius-md);
    border: 1px solid rgba(192, 132, 252, 0.36);
    background: rgba(20, 15, 34, 0.98);
    color: #F4F4F4;
    padding: 0.9rem 1rem;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.42);
}

.hidden {
    display: none !important;
}

@media (max-width: 768px) {
    .data-table {
        min-width: 640px;
    }

}

/* Claude black/white dashboard integration */
:root {
    color-scheme: light;
    --bg: #F4F4F4;
    --surface: rgba(var(--surface-rgb), 0.86);
    --surface-2: rgba(var(--surface-rgb), 0.86);
    --panel: rgba(var(--surface-rgb), 0.88);
    --panel-strong: rgba(var(--surface-rgb), 0.9);
    --hover: color-mix(in srgb, var(--brand, #0062ff) 8%, transparent);
    --line: rgba(18, 24, 38, 0.12);
    --line-soft: rgba(18, 24, 38, 0.16);
    --line-strong: #171717;
    --text: #0a0a0a;
    --muted: #5f5d57;
    --faint: #858178;
    --blue: #0062ff;
    --brand: var(--blue);
    --violet: #6853ed;
    --purple: #6853ed;
    --purple-2: #0062ff;
    --pink: #0a0a0a;
    --cyan: #0a0a0a;
    --green: #1f8a4c;
    --red: #b4321e;
}

html,
body {
    height: 100%;
}

body {
    /* Page gradient lives on body::before so it is theme-driven and survives view transitions. */
    color: var(--text);
    font-size: 13px;
    letter-spacing: 0;
}

body,
button,
input,
textarea,
select {
    font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

.dashboard-root {
    min-height: 100vh;
    display: grid;
    grid-template-rows: 56px 1fr;
}

.dashboard-frame {
    min-height: 0;
    display: grid;
    grid-template-columns: 220px minmax(0, 1fr) 300px;
    /* clip, not hidden: `hidden` makes this a scroll container, which turns the
       sticky side columns' `top: 56px` into an offset inside the frame. They then
       started 56px too low and their last block sat below the screen edge. */
    overflow: clip;
}

.dashboard-root.no-guild .dashboard-frame {
    display: block;
    overflow-y: auto;
}

.dashboard-root.no-guild .app-main {
    min-height: calc(100vh - 56px);
}

.topbar {
    position: sticky;
    top: 0;
    z-index: 50;
    height: 56px;
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 0 16px;
    border-bottom: 1px solid var(--line);
    background: rgba(var(--surface-rgb), 0.78);
    backdrop-filter: blur(14px);
}

.brand-link {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 200px;
    height: 100%;
    padding-right: 14px;
    border-right: 1px solid var(--line);
}
/* The 200px is there to line the brand up over the guild sidebar. Without a
   sidebar it is just a hole between the logo and the first nav word. */
.no-guild .brand-link { min-width: 0; }

.brand-mark {
    width: 24px;
    height: 24px;
    border-radius: var(--radius-sm);
    display: grid;
    place-items: center;
    background: linear-gradient(135deg, var(--blue), var(--violet));
    color: var(--surface);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 12px;
    font-weight: 700;
    border: 0;
}

.brand-logo-mark {
    overflow: hidden;
    background: var(--theme-white);
    border: 1px solid rgba(18, 24, 38, 0.14);
}

.brand-logo-mark img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transform: scale(1.16);
}

.brand-copy {
    display: flex;
    align-items: baseline;
    gap: 7px;
    min-width: 0;
}

.brand-text {
    color: var(--text);
    font-size: 13px;
    font-weight: 700;
}

.topbar-search {
    position: relative;
    flex: 0 1 auto;
    width: min(320px, 26vw);
    min-width: 0;
}

.topbar-search input {
    width: 100%;
    height: 32px;
    padding: 0 32px 0 30px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: rgba(var(--surface-rgb), 0.58);
    color: var(--text);
    outline: 0;
}

.topbar-search input:focus {
    background: var(--surface);
    border-color: var(--blue);
    box-shadow: none;
}

.topbar-search svg {
    position: absolute;
    left: 9px;
    top: 8px;
    color: var(--muted);
}

.topbar-search kbd {
    position: absolute;
    top: 7px;
    right: 8px;
    padding: 1px 5px;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--muted);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 10px;
}

.topbar-spacer {
    flex: 1;
}
/* Desktop: the word nav sits beside the brand and the tools (vote, search,
   account) push to the far edge, so the spacer that does the pushing is the one
   inside .topbar-actions, not the one before it. mobile-layout.css flips this
   back once the nav collapses into the phone panel. */
.topbar > .topbar-spacer { flex: 0 0 0; }
.topbar-actions { flex: 1 0 auto; }
/* Wide guild pages: the jump-to field is the search, the icon would be a
   duplicate. Below 1460px the field no longer fits beside the word nav (brand
   + switcher + field + nav + tools ran ~1450px and pushed the account chip off
   the edge), so the field goes and the icon takes over. */
.has-guild .topbar-search-btn { display: none; }
@media (max-width: 1460px) {
    .has-guild .topbar-search { display: none; }
    .has-guild .topbar-search-btn { display: grid; }
}

.user-chip {
    display: flex;
    align-items: center;
    gap: 9px;
    max-width: min(18rem, 44vw);
    padding: 4px 6px 4px 4px;
    border-radius: var(--radius-sm);
    background: transparent;
    border: 0;
}

@media (hover: hover) and (pointer: fine) {
.user-chip:hover {
    background: var(--hover);
}
}

.user-chip img {
    border: 1px solid var(--line);
}

.user-copy {
    display: flex;
    flex-direction: column;
    line-height: 1.15;
    min-width: 0;
}

.icon-btn {
    width: 30px;
    height: 30px;
    display: grid;
    place-items: center;
    border-radius: var(--radius-sm);
    color: var(--muted);
}

@media (hover: hover) and (pointer: fine) {
.icon-btn:hover {
    background: var(--hover);
    color: var(--text);
}
}

.app-sidebar,
.app-rightbar {
    min-height: 0;
    overflow-y: auto;
    background: rgba(var(--surface-rgb), 0.72);
    backdrop-filter: blur(14px);
}

.app-sidebar {
    border-inline-end: 1px solid var(--line);
    /* Generous bottom padding so the last nav item never sits flush against the
       edge of the scroll box and read as cut off. */
    padding: 14px 10px 40px;
    /* The desktop rule below (min-width:1024px) owns height and overflow: the
       sidebar is a sticky, independently scrolling column. Setting max-height
       here as well fought that rule and produced a shorter box than intended. */
    scrollbar-gutter: stable;
}

.app-rightbar {
    border-left: 1px solid var(--line);
}

.app-main {
    min-width: 0;
    min-height: 0;
    overflow-y: auto;
    padding: 28px;
    background: transparent;
}
/* The support chat button floats in the bottom-right corner: leave room under the
   last row so its buttons (Delete, Save) can scroll clear of it. */
body:has(.nxchat) .app-main { padding-bottom: calc(28px + 4.5rem); }

.app-main > .mb-8:first-child,
.app-main > form,
.app-main > section,
.app-main > nav,
.app-main > a,
.app-main > div,
.app-main > p {
    max-width: 1200px;
    margin-left: auto;
    margin-right: auto;
}

.nav-server-mini {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px 14px;
    border-bottom: 1px solid var(--line);
    margin-bottom: 6px;
}

.nav-server-icon {
    width: 32px;
    height: 32px;
    border-radius: var(--radius-md);
    border: 1px solid var(--line);
    object-fit: cover;
    flex: 0 0 auto;
}

.nav-server-fallback {
    display: grid;
    place-items: center;
    background: linear-gradient(135deg, var(--blue), var(--violet));
    color: var(--surface);
    font-weight: 800;
}

.nav-server-name,
.nav-server-id {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.nav-server-name {
    font-size: 13px;
    font-weight: 700;
}

.nav-server-id {
    color: var(--muted);
    font-size: 10px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}

.nav-section,
.side-title,
.sidebar-heading {
    padding: 14px 10px 6px;
    color: var(--faint);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

/* Sidebar categories used to run together as one long list, which made it hard to
   tell where one ended and the next began. Every category after the first gets a
   rule above it, and the heading is brightened so it reads as a heading.
   Written to cover both nav layouts: flat `.nav-section` headings and the
   collapsible `.nav-group` wrapper. */
.nav-menu > .nav-section:not(:first-child),
.nav-menu > .nav-group + .nav-group {
    margin-top: 8px;
    border-top: 1px solid rgba(148, 163, 184, .22);
}

.nav-menu .nav-section {
    color: var(--muted);
}

.nav-menu .nav-group.has-active > .nav-section {
    color: #b65cff;
}

.nav-link {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 32px;
    padding: 7px 10px;
    border-radius: var(--radius-sm);
    color: var(--text);
    font-weight: 600;
    border: 0;
}

@media (hover: hover) and (pointer: fine) {
/* Neutral grey, like the active row: the accent (red in dark themes) on hover read
   as "selected" and stayed on the clicked row while the page switched. */
.nav-link:hover {
    background: var(--hover);
    color: var(--text);
}
}

.nav-link-active,
.nav-pill {
    background: linear-gradient(135deg, var(--blue), var(--violet));
    color: var(--surface);
    border: 0;
    box-shadow: 0 10px 28px color-mix(in srgb, var(--brand, #0062ff) 16%, transparent);
}

.nav-link svg {
    opacity: 0.72;
}

.nav-link-active svg {
    opacity: 1;
}

.resource-provider {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 10px;
    padding: 8px;
    border: 1px solid rgba(18, 24, 38, 0.1);
    border-radius: var(--radius-md);
    background:
        linear-gradient(135deg, rgba(var(--surface-rgb), 0.72), rgba(var(--surface-rgb), 0.52)),
        linear-gradient(135deg, color-mix(in srgb, var(--brand, #0062ff) 8%, transparent), rgba(104, 83, 237, 0.09));
    color: var(--faint);
    text-decoration: none;
}

.resource-provider span {
    color: var(--faint);
    font-size: 9px;
    font-weight: 900;
    text-transform: uppercase;
}

.resource-provider img {
    display: block;
    width: auto;
    max-width: 104px;
    height: 18px;
    object-fit: contain;
}

@media (hover: hover) and (pointer: fine) {
.resource-provider:hover {
    border-color: color-mix(in srgb, var(--brand, #0062ff) 24%, transparent);
    background: rgba(var(--surface-rgb), 0.76);
}
}

.side-block {
    padding: 16px;
    border-bottom: 1px solid var(--line);
}

.server-card {
    display: flex;
    align-items: flex-start;
    gap: 12px;
}

.server-icon,
.server-icon-img {
    width: 48px;
    height: 48px;
    border-radius: var(--radius-md);
    flex: 0 0 auto;
}

.server-icon {
    display: grid;
    place-items: center;
    background: linear-gradient(135deg, var(--blue), var(--violet));
    color: var(--surface);
    font-size: 18px;
    font-weight: 800;
}

.server-icon-img {
    object-fit: cover;
    border: 1px solid var(--line);
}

.server-name {
    color: var(--text);
    font-size: 14px;
    font-weight: 800;
}

.server-id {
    margin-top: 2px;
    color: var(--muted);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 11px;
}

.server-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
}

.panel,
.panel-strong,
.guild-info,
.guild-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    box-shadow: 0 1px 0 rgba(10, 10, 10, 0.04), 0 1px 2px rgba(10, 10, 10, 0.04);
}

.muted,
.help {
    color: var(--muted);
}

.label {
    color: var(--muted);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 10px;
    letter-spacing: 0.06em;
}

.field,
.select,
.textarea {
    border: 1px solid var(--line-soft);
    background: var(--surface);
    color: var(--text);
    border-radius: var(--radius-sm);
}

.field:focus,
.select:focus,
.textarea:focus {
    border-color: var(--blue);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand, #0062ff) 10%, transparent);
}

.btn {
    font-weight: 700;
}

.btn-primary {
    background: linear-gradient(135deg, var(--blue), var(--violet));
    color: var(--surface);
}

@media (hover: hover) and (pointer: fine) {
.btn-primary:hover {
    filter: brightness(0.96);
}
}

.btn-secondary {
    background: var(--surface);
    border: 1px solid var(--line-soft);
    color: var(--text);
}

@media (hover: hover) and (pointer: fine) {
.btn-secondary:hover {
    background: var(--hover);
}
}

.btn-danger,
.btn-bad {
    background: #f4e8e5;
    border-color: #efc5bc;
    color: var(--red);
}

.badge {
    border-radius: var(--radius-sm);
    border: 1px solid var(--line);
    background: var(--surface-2);
    color: var(--text);
    font-size: 11px;
}

.badge-good {
    border-color: #cfe4d4;
    background: #e4eee5;
    color: var(--green);
}

.badge-warn {
    border-color: #ecd8ad;
    background: #efe6cf;
    color: #8a5b12;
}

.badge-bad {
    border-color: #edc6bf;
    background: #edddd9;
    color: var(--red);
}

.brand-text,
.text-white,
.text-purple-200,
.text-cyan-200,
.text-pink-200 {
    color: var(--text) !important;
}

.text-green-200,
.text-green-300 {
    color: var(--green) !important;
}

.text-zinc-400 {
    color: var(--muted) !important;
}

.info-list {
    gap: 0;
}

.info-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 28px;
    padding: 5px 0;
    border: 0;
    color: var(--muted);
    font-size: 12px;
}

.info-row strong {
    min-width: 0;
    color: var(--text);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 11px;
    font-weight: 700;
}

.status-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 999px;
    margin-right: 7px;
    background: var(--green);
    vertical-align: middle;
}

.status-dot.off {
    background: var(--red);
}

.status-dot.on {
    background: var(--green);
}

.divider {
    height: 1px;
    margin: 8px 0;
    background: var(--line);
}

.sidebar-empty {
    border: 1px dashed var(--line-soft);
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--muted);
    padding: 1rem;
    text-align: center;
}

.invoice-mini {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 0;
    border: 0;
    border-bottom: 1px solid var(--line);
    border-radius: 0;
    background: transparent;
}

@media (hover: hover) and (pointer: fine) {
.invoice-mini:hover {
    background: transparent;
}
}

.invoice-mini-thumb {
    width: 38px;
    height: 38px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--line);
    object-fit: cover;
}

.invoice-mini-body {
    min-width: 0;
    flex: 1;
}

.invoice-mini-top,
.invoice-mini-bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
}

.invoice-mini-top {
    color: var(--text);
    font-size: 11px;
    font-weight: 700;
}

.invoice-mini-bottom {
    margin-top: 2px;
    color: var(--muted);
    font-size: 11px;
}

.data-table th {
    color: var(--muted);
    background: var(--surface-2);
    border-bottom: 1px solid var(--line);
}

.data-table td {
    border-bottom: 1px solid var(--line);
}

.table-wrap {
    border-color: var(--line);
    background: var(--surface);
}

.setup-progress,
.setup-progress span {
    background: var(--line);
}

.setup-progress span {
    background: var(--text);
}

.setup-check-item,
.ticket-panel-card,
.ticket-v2-card,
.ticket-link-card,
.item-list-row,
.verify-preview,
.invoice-filter-panel {
    border-color: var(--line);
    background: var(--surface);
}

@media (hover: hover) and (pointer: fine) {
.setup-check-item:hover,
.ticket-panel-card:hover,
.ticket-v2-card:hover,
.ticket-link-card:hover {
    background: var(--surface-2);
}
}

.invoice-thumb-empty,
.invoice-mini-thumb-empty,
.sidebar-empty,
.setup-check-icon {
    background: var(--surface-2);
    border-color: var(--line);
}

.module-switch input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.module-switch span {
    display: block;
    position: relative;
    width: 44px;
    height: 24px;
    border-radius: 999px;
    background: #d8d8d8;
    transition: background 160ms ease;
}

.module-switch span::after {
    content: "";
    position: absolute;
    top: 3px;
    left: 3px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--theme-white);
    box-shadow: 0 2px 8px rgba(18, 24, 38, 0.18);
    transition: transform 160ms ease;
}

.module-switch input:checked + span {
    background: linear-gradient(135deg, var(--blue), var(--violet));
}

.module-switch input:checked + span::after {
    transform: translateX(20px);
}

.modal-backdrop {
    background: rgba(20, 20, 18, 0.42);
}

.toast {
    background: var(--text);
    color: var(--surface);
    border-color: var(--text);
    box-shadow: 0 8px 24px rgba(10, 10, 10, 0.12), 0 2px 6px rgba(10, 10, 10, 0.08);
}

body.is-navigating {
    cursor: progress;
}

body.is-navigating::before {
    content: "";
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1000;
    width: 42%;
    height: 3px;
    border-radius: 0 999px 999px 0;
    background: linear-gradient(90deg, var(--blue), var(--violet));
    animation: dashboard-load-bar 900ms ease-in-out infinite;
}

@keyframes dashboard-load-bar {
    0% {
        transform: translateX(-100%);
    }

    55% {
        transform: translateX(130%);
    }

    100% {
        transform: translateX(240%);
    }

}

.skeleton-line,
.skeleton-block,
.skeleton-card,
.skeleton-panel {
    display: block;
    overflow: hidden;
    position: relative;
    border-radius: var(--radius-sm);
    background: color-mix(in srgb, var(--text) 7%, transparent);
}

.skeleton-line::after,
.skeleton-block::after,
.skeleton-card::after,
.skeleton-panel::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--brand, #0062ff) 14%, transparent), transparent);
    animation: skeleton-shimmer 1.15s ease-in-out infinite;
}

@keyframes skeleton-shimmer {
    100% {
        transform: translateX(100%);
    }

}

.skeleton-line {
    height: 14px;
}

.skeleton-line.w-45 {
    width: 45%;
}

.skeleton-line.w-70 {
    width: 70%;
}

.invoice-mini-skeleton .invoice-mini {
    pointer-events: none;
}

.invoice-mini-skeleton .invoice-mini-thumb {
    border: 0;
}

html {
    scroll-behavior: smooth;
}

.app-main > .home-page {
    max-width: none;
    margin: 0;
}

.home-page {
    overflow: hidden;
    color: var(--text);
}

.home-hero {
    min-height: calc(100vh - 56px);
    display: grid;
    place-items: center;
    padding: clamp(44px, 7vw, 92px) 22px;
    background:
        linear-gradient(120deg, rgba(var(--surface-rgb), 0.94), rgba(var(--surface-rgb), 0.72) 45%, color-mix(in srgb, var(--brand, #0062ff) 18%, transparent) 72%, rgba(104, 83, 237, 0.2)),
        linear-gradient(rgba(18, 24, 38, 0.035) 1px, transparent 1px),
        linear-gradient(90deg, rgba(18, 24, 38, 0.035) 1px, transparent 1px);
    background-size: auto, 42px 42px, 42px 42px;
}

.home-hero-inner {
    width: min(1180px, 100%);
    margin: 0 auto;
    text-align: center;
}

.home-eyebrow,
.home-kicker {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--blue);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 11px;
    font-weight: 900;
    text-transform: uppercase;
}

.home-title {
    margin-top: 22px;
    color: var(--text);
    font-size: clamp(58px, 10vw, 136px);
    font-weight: 950;
    line-height: 0.9;
    letter-spacing: 0;
}

.home-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;
    margin-top: 30px;
}

.home-hosting-provider {
    width: fit-content;
    max-width: min(100%, 360px);
    min-height: 46px;
    margin: 18px auto 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    border: 1px solid rgba(18, 24, 38, 0.12);
    border-radius: 999px;
    background: rgba(var(--surface-rgb), 0.74);
    box-shadow: 0 14px 46px rgba(18, 24, 38, 0.08);
    padding: 8px 14px 8px 16px;
    color: var(--muted);
    text-decoration: none;
    transition:
        transform 180ms ease,
        border-color 180ms ease,
        box-shadow 180ms ease,
        background 180ms ease;
}

@media (hover: hover) and (pointer: fine) {
.home-hosting-provider:hover {
    transform: translateY(-1px);
    border-color: color-mix(in srgb, var(--brand, #0062ff) 26%, transparent);
    background: rgba(var(--surface-rgb), 0.9);
    box-shadow: 0 18px 56px color-mix(in srgb, var(--brand, #0062ff) 12%, transparent);
}
}

.home-hosting-provider span {
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 10px;
    font-weight: 950;
    letter-spacing: 0;
    text-transform: uppercase;
}

.home-hosting-provider img {
    display: block;
    width: auto;
    max-width: 156px;
    height: 24px;
    object-fit: contain;
}

.home-limited {
    width: min(760px, 100%);
    margin: 24px auto 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    border: 1px solid rgba(18, 24, 38, 0.14);
    border-radius: var(--radius-lg);
    background:
        linear-gradient(135deg, rgba(var(--surface-rgb), 0.86), rgba(var(--surface-rgb), 0.62)),
        linear-gradient(135deg, color-mix(in srgb, var(--brand, #0062ff) 14%, transparent), rgba(104, 83, 237, 0.14));
    box-shadow: 0 20px 70px rgba(18, 24, 38, 0.12);
    padding: 16px;
    text-align: left;
}

.home-limited strong {
    display: block;
    margin-top: 9px;
    color: var(--text);
    font-size: clamp(26px, 3.4vw, 42px);
    font-weight: 950;
    line-height: 1;
}

.home-limited p {
    margin-top: 6px;
    color: var(--muted);
    font-size: 14px;
    font-weight: 700;
}

/* Three live numbers under the copy and buttons. Members reached sits in the
   middle, larger and in the accent colour; servers and commands flank it. */
.home-limited { flex-wrap: wrap; }
.home-limited dl.home-limited-trust {
    flex: 1 1 100%;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 12px;
    margin: 6px 0 0;
    padding: 16px 8px 8px;
    border-top: 1px solid color-mix(in srgb, var(--brand, #0062ff) 16%, transparent);
    text-align: center;
}
.home-limited-trust > div { display: flex; flex-direction: column; align-items: center; gap: 3px; }
.home-limited-trust dt {
    margin: 0;
    color: var(--muted);
    font-size: 12px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.home-limited-trust dd {
    margin: 0;
    color: var(--text);
    font-size: clamp(24px, 3.2vw, 34px);
    font-weight: 900;
    line-height: 1;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}
.home-limited-trust .is-main {
    padding: 0 clamp(16px, 4vw, 40px);
    border-left: 1px solid color-mix(in srgb, var(--brand, #0062ff) 16%, transparent);
    border-right: 1px solid color-mix(in srgb, var(--brand, #0062ff) 16%, transparent);
}
.home-limited-trust .is-main dd {
    color: var(--blue);
    font-size: clamp(38px, 5.6vw, 62px);
}
@media (max-width: 560px) {
    .home-limited dl.home-limited-trust { grid-template-columns: 1fr; gap: 18px; }
    .home-limited-trust .is-main { border: 0; padding: 0; }
}

.home-section {
    width: min(1180px, calc(100% - 48px));
    margin: 0 auto;
    padding: clamp(72px, 9vw, 128px) 0;
}

.home-section-head {
    max-width: 780px;
    margin-bottom: clamp(36px, 4vw, 56px);
}

/* No kicker above section headings any more (it read as template scaffolding), so
   the heading carries the section on its own: one step smaller, lighter, balanced. */
.home-section-head h2 {
    color: var(--text);
    font-size: clamp(28px, 3.6vw, 46px);
    line-height: 1.04;
    letter-spacing: -0.028em;
    text-wrap: balance;
}

.home-cta h2 {
    margin-top: 10px;
    color: var(--text);
    font-size: clamp(30px, 4.6vw, 58px);
    font-weight: 950;
    line-height: 1;
}

/* Buttons under a left-aligned section head line up with its text; .home-actions
   alone centres them (built for the centred hero), which floated them mid-page on
   /features, /leaderboard and the feature guides. */
.home-section-head .home-actions {
    justify-content: flex-start;
    margin-top: 1.4rem;
}

.home-section-head p {
    max-width: 58ch;
    margin-top: 16px;
    color: var(--muted);
    font-size: 17px;
    line-height: 1.7;
    text-wrap: pretty;
}

/* Subpage heroes (status, donors, compare, endercloud) end in a soft wave where the
   ribbon image stops, instead of a hard straight line. The home hero is left out:
   its preview card sits on that edge. */
.home-page[class*="site-"] > .home-hero.nx-hero {
    --hero-wave: clamp(40px, 5vw, 76px);
    -webkit-mask:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 80' preserveAspectRatio='none'%3E%3Cpath d='M0 0H1440V40C1265 62 1100 76 915 64C715 50 555 18 340 20C200 22 90 34 0 46Z'/%3E%3C/svg%3E") bottom / 100% var(--hero-wave) no-repeat,
        linear-gradient(#000 0 0) top / 100% calc(100% - var(--hero-wave) + 1px) no-repeat;
    mask:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 80' preserveAspectRatio='none'%3E%3Cpath d='M0 0H1440V40C1265 62 1100 76 915 64C715 50 555 18 340 20C200 22 90 34 0 46Z'/%3E%3C/svg%3E") bottom / 100% var(--hero-wave) no-repeat,
        linear-gradient(#000 0 0) top / 100% calc(100% - var(--hero-wave) + 1px) no-repeat;
}

/* Room for the wave, so it never trims the last row of hero content. */
.home-page[class*="site-"] > .home-hero.nx-hero > .home-hero-inner {
    padding-bottom: calc(var(--hero-wave) * 0.6);
}

/* Home "100% free, forever" band: one big line, a short promise, three proof points. */
.home-free-band { display: grid; justify-items: center; gap: 18px; text-align: center; }
.home-free-title { margin: 0; color: var(--text); font-family: "Funnel Display", Assistant, Inter, sans-serif; font-size: clamp(44px, 8vw, 96px); font-weight: 650; line-height: 1; letter-spacing: -0.035em; text-wrap: balance; }
.home-free-title .nx-cursive { color: #ffcf6e; }
.home-free-sub { max-width: 52ch; margin: 0; color: var(--muted); font-size: 17px; line-height: 1.65; text-wrap: pretty; }
.home-free-points { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin: 8px 0 0; padding: 0; list-style: none; }
.home-free-points li { display: inline-flex; align-items: center; gap: 8px; padding: 9px 14px; border: 1px solid var(--line-soft); border-radius: 999px; color: var(--text); font-size: 14px; font-weight: 600; }
.home-free-points svg { width: 16px; height: 16px; color: #22c55e; }

/* "Why use this bot": heading beside a calm list, not three numbered cards
   (the numbers suggested steps; these are reasons). */
.home-why-section {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: clamp(32px, 5vw, 72px);
    align-items: start;
}

.home-why-section .home-section-head {
    margin-bottom: 0;
}

.home-why-item {
    display: grid;
    grid-template-columns: 36px 1fr;
    column-gap: 14px;
    padding: 22px 0;
    border-top: 1px solid var(--line-soft);
}

.home-why-icon {
    grid-row: span 2;
    padding-top: 2px;
    color: var(--text);
    opacity: 0.85;
}

.home-why-icon svg {
    width: 20px;
    height: 20px;
}

.home-why-item h3 {
    margin: 0;
    color: var(--text);
    font-size: 17px;
    font-weight: 650;
}

.home-why-item p {
    margin-top: 4px;
    color: var(--muted);
    line-height: 1.6;
}

@media (max-width: 900px) {
    .home-why-section {
        grid-template-columns: 1fr;
    }
}

.home-feature-grid {
    display: grid;
    gap: 22px;
}

.home-feature-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}



.home-feature-card {
    min-height: 100%;
    border: 1px solid rgba(18, 24, 38, 0.12);
    border-radius: var(--radius-lg);
    background: rgba(var(--surface-rgb), 0.66);
    padding: 28px;
}

.home-feature-icon {
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    border-radius: var(--radius-md);
    background: linear-gradient(135deg, var(--blue), var(--violet));
    color: #F4F4F4;
    font-weight: 900;
}

.home-feature-card h3 {
    margin-top: 18px;
    color: var(--text);
    font-size: 18px;
    font-weight: 900;
}

.home-feature-card p {
    margin-top: 9px;
    color: var(--muted);
    line-height: 1.6;
}



.home-cta {
    width: min(1180px, calc(100% - 44px));
    margin: 0 auto clamp(44px, 7vw, 84px);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    border: 1px solid rgba(18, 24, 38, 0.12);
    border-radius: var(--radius-lg);
    background: linear-gradient(135deg, rgba(var(--surface-rgb), 0.78), color-mix(in srgb, var(--brand, #0062ff) 10%, transparent), rgba(104, 83, 237, 0.12));
    padding: clamp(24px, 5vw, 42px);
}

.motion-ready [data-animate] {
    opacity: 0;
    transform: translateY(10px);
    /* No blur: filter on dozens of cards made fast scrolling stutter.
       Short, sharp rise: a 40px / 800ms lift on every block felt floaty and
       slowed reading. Stagger is kept but tightened. */
    transition:
        opacity 420ms cubic-bezier(.23, 1, .32, 1),
        transform 420ms cubic-bezier(.23, 1, .32, 1);
    transition-delay: calc(var(--animate-delay, 0ms) * 0.55);
}

/* Revealed during a fast scroll: no stagger, short fade, so cards are already
   there when the scroll stops instead of trickling in behind it. */
.motion-ready [data-animate].is-quick {
    transition-duration: 160ms;
    transition-delay: 0ms;
}

/* On screen at first paint (layout.ejs): just there, no fade. */
.motion-ready [data-animate].is-instant {
    transition: none;
}

.motion-ready [data-animate="scale-in"] {
    transform: translateY(10px) scale(0.97);
}

.motion-ready [data-animate].is-visible {
    opacity: 1;
    transform: none;
}

.panel,
.panel-strong,
.guild-card,
.setup-check-item,
.item-list-row,
.resource-widget,
.home-feature-card,
.module-card,
.home-preview,
.server-card,
.invoice-mini {
    transition:
        transform 180ms ease,
        border-color 180ms ease,
        box-shadow 180ms ease,
        background 180ms ease,
        filter 180ms ease;
}

.btn,
.nav-link,
.icon-btn,
.brand-link,
.data-table tbody tr {
    transition:
        transform 160ms ease,
        background 160ms ease,
        color 160ms ease,
        border-color 160ms ease,
        box-shadow 160ms ease,
        filter 160ms ease;
}

@media (hover: hover) and (pointer: fine) {
.btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 12px 26px color-mix(in srgb, var(--brand, #0062ff) 14%, transparent);
}
}

@media (hover: hover) and (pointer: fine) {
.panel:hover,
.panel-strong:hover,
.home-feature-card:hover,
/* No lift: panels jumping under the cursor while working through settings
   was distracting (user feedback 2026-10-17). Highlight only. */
.module-card:hover {
    border-color: color-mix(in srgb, var(--brand, #0062ff) 26%, transparent);
    box-shadow: 0 18px 48px rgba(18, 24, 38, 0.1);
}
}

@media (hover: hover) and (pointer: fine) {
.nav-link:hover {
    transform: translateX(3px);
}
}

@media (hover: hover) and (pointer: fine) {
.data-table tbody tr:hover {
    background: color-mix(in srgb, var(--brand, #0062ff) 4.5%, transparent);
}
}

@keyframes home-bar-rise {
    from {
        transform: scaleY(0.15);
        transform-origin: bottom;
    }

    to {
        transform: scaleY(1);
        transform-origin: bottom;
    }

}

.reduce-motion *,
.reduce-motion *::before,
.reduce-motion *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-duration: 0.001ms !important;
}

@media (max-width: 1180px) {
    .dashboard-frame {
        grid-template-columns: 220px minmax(0, 1fr);
    }

    .app-rightbar {
        display: none;
    }

}

@media (max-width: 760px) {
    .dashboard-root {
        display: block;
    }

    .topbar {
        position: static;
        height: auto;
        min-height: 56px;
        flex-wrap: wrap;
        padding: 10px;
    }

    .brand-link {
        min-width: 0;
        border-right: 0;
    }

    .topbar-search {
        order: 4;
        width: 100%;
    }

    .dashboard-frame {
        display: block;
        overflow: visible;
    }

    .app-sidebar {
        border-right: 0;
        border-bottom: 1px solid var(--line);
    }

    .app-main {
        overflow: visible;
        padding: 18px;
    }

    .home-feature-grid,
    .home-stats {
        grid-template-columns: 1fr;
    }

    .home-title {
        font-size: clamp(48px, 18vw, 80px);
    }

    .home-cta {
        align-items: flex-start;
        flex-direction: column;
    }

    .home-limited {
        align-items: stretch;
        flex-direction: column;
        text-align: center;
    }

    .home-hosting-provider {
        width: 100%;
        max-width: 100%;
        border-radius: var(--radius-lg);
    }

    .home-hosting-provider img {
        max-width: 140px;
    }

}

/* Responsive polish pass: 720p through 4K, tablet, and phones */
:root {
    --dashboard-sidebar-w: clamp(212px, 11.5vw, 258px);
    --dashboard-rightbar-w: clamp(280px, 16vw, 360px);
    --dashboard-content-max: 1560px;
}

html,
body {
    max-width: 100%;
    overflow-x: clip;
}

img,
video,
canvas,
svg {
    max-width: 100%;
}

.app-main,
.app-sidebar,
.app-rightbar,
.panel,
.panel-strong,
.server-card,
.table-wrap {
    min-width: 0;
}

.table-wrap {
    max-width: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
}

.dashboard-frame {
    grid-template-columns: var(--dashboard-sidebar-w) minmax(0, 1fr) var(--dashboard-rightbar-w);
}

.app-main {
    --main-pad: clamp(18px, 1.45vw, 36px);
    padding: var(--main-pad);
    /* The page itself scrolls. overflow-y: auto made .app-main a second scroll
       container that never scrolled: wheel scrolling stuck at edges and every
       position: sticky inside the page (editor previews) was pinned to it and
       never stuck (Mike's video, 2026-10-28). clip keeps wide content cut off
       sideways without creating a scroll container. */
    overflow-x: clip;
    overflow-y: visible;
}

.app-main > .mb-8:first-child,
.app-main > form,
.app-main > section,
.app-main > nav,
.app-main > a,
.app-main > div,
.app-main > p {
    max-width: min(var(--dashboard-content-max), 100%);
}

/* A short page note ("Discord may take a little while"): spans the page column like
   the cards under it, so on wide screens it no longer hangs off the left edge. */
.nx-note {
    display: flex; align-items: flex-start; gap: 10px;
    margin-top: -6px; margin-bottom: 18px;
    padding: 12px 16px;
    border-radius: var(--radius-md);
    border: 1px solid color-mix(in srgb, #3b82f6 35%, transparent);
    background: color-mix(in srgb, #3b82f6 9%, transparent);
    color: var(--muted); font-size: 14px; line-height: 1.5;
}
.nx-note > i, .nx-note > svg { flex: none; width: 18px; height: 18px; margin-top: 1px; color: #3b82f6; }
.nx-note strong { color: var(--text); }

.home-hero-inner,
.home-section,
.home-cta {
    width: min(1440px, calc(100% - 44px));
}

@media (min-width: 1920px) {
    :root {
        --dashboard-content-max: 1680px;
    }

    .dashboard-root.has-guild .dashboard-frame {
        max-width: 2200px;
        width: 100%;
        margin: 0 auto;
        border-left: 1px solid var(--line);
        border-right: 1px solid var(--line);
    }

    .home-hero-inner,
    .home-section,
    .home-cta {
        width: min(1520px, calc(100% - 88px));
    }

}

@media (max-width: 1360px) and (min-width: 921px) {
    .dashboard-frame {
        grid-template-columns: 218px minmax(0, 1fr);
    }

    .app-rightbar {
        display: none;
    }

    .topbar-search {
        width: min(300px, 32vw);
    }

    .app-main {
        --main-pad: 20px;
    }

}

@media (max-height: 760px) and (min-width: 921px) {
    .topbar {
        height: 50px;
    }

    .dashboard-root {
        grid-template-rows: 50px 1fr;
    }

    .app-sidebar {
        padding-top: 10px;
    }

    .nav-section,
    .side-title,
    .sidebar-heading {
        padding-top: 10px;
    }

    .nav-link {
        min-height: 30px;
        padding-top: 6px;
        padding-bottom: 6px;
    }

    .app-main {
        --main-pad: 18px;
    }

    .home-hero {
        min-height: auto;
        padding-top: 42px;
        padding-bottom: 42px;
    }

}

@media (max-width: 920px) {
    .dashboard-root {
        display: block;
        min-height: 100vh;
    }

    .topbar {
        position: sticky;
        top: 0;
        height: auto;
        min-height: 54px;
        flex-wrap: wrap;
        padding: 9px 12px;
    }

    .brand-link {
        min-width: 0;
        height: 38px;
        border-right: 0;
        padding-right: 0;
    }

    .topbar-search {
        order: 5;
        width: 100%;
    }

    .dashboard-frame {
        display: block;
        overflow: visible;
    }

    /* Sidebar becomes an off-canvas slide-in drawer (keeps the vertical nav). */
    .nav-hamburger { display: inline-flex; }

    .app-sidebar {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        z-index: 70;
        width: min(310px, 84vw);
        min-height: 0;
        max-height: none;
        overflow-y: auto;
        border-right: 1px solid var(--line);
        border-bottom: 0;
        padding: 16px 12px 28px;
        background: var(--surface);
        box-shadow: 0 30px 80px rgba(8, 9, 13, 0.35);
        transform: translateX(-102%);
        visibility: hidden;
        transition: transform .28s cubic-bezier(.22, 1, .36, 1), visibility .28s;
    }
    .dashboard-root.sidebar-open .app-sidebar {
        transform: none;
        visibility: visible;
    }

    .sidebar-backdrop {
        position: fixed;
        inset: 0;
        z-index: 65;
        background: rgba(8, 9, 13, 0.45);
        backdrop-filter: blur(2px);
        opacity: 0;
        visibility: hidden;
        transition: opacity .25s ease, visibility .25s;
    }
    .dashboard-root.sidebar-open .sidebar-backdrop {
        opacity: 1;
        visibility: visible;
    }

    .app-main {
        --main-pad: 16px;
        overflow: visible;
        padding: var(--main-pad);
    }

    .app-main > .mb-8:first-child {
        margin-bottom: 18px;
    }

    .app-main > .grid,
    .app-main > form.grid,
    .app-main > section.grid,
    .app-main .grid {
        grid-template-columns: minmax(0, 1fr) !important;
    }

    .table-wrap {
        border-radius: var(--radius-md);
        -webkit-overflow-scrolling: touch;
    }

    .data-table {
        min-width: 680px;
    }

    .invoice-filter-panel,
    .module-grid,
    .home-feature-grid,
    .home-stats {
        grid-template-columns: 1fr;
    }

    .home-hero {
        min-height: auto;
        padding: 52px 18px;
    }

    .home-section,
    .home-cta {
        width: min(calc(100% - 32px), 900px);
    }

}

@media (max-width: 560px) {
    body {
        font-size: 12px;
    }

    .topbar {
        gap: 8px;
    }

    .brand-copy {
        gap: 5px;
    }

    .brand-version,
    .user-copy,
    .topbar-search {
        display: none;
    }

    .topbar .btn {
        min-height: 36px;
        padding: 0.5rem 0.68rem;
        font-size: 12px;
    }

    .app-sidebar {
        padding: 9px 10px;
    }

    .nav-server-mini {
        gap: 8px;
    }

    .nav-server-icon {
        width: 28px;
        height: 28px;
    }

    .nav-server-name {
        font-size: 12px;
    }

    .nav-server-id {
        max-width: 11rem;
    }

    .nav-link {
        min-height: 36px;
        gap: 8px;
        padding: 7px 10px;
        font-size: 12px;
    }

    .app-main {
        --main-pad: 12px;
    }

    .app-main .grid {
        grid-template-columns: 1fr !important;
    }

    .panel,
    .panel-strong {
        border-radius: var(--radius-md);
    }

    .btn {
        min-height: 38px;
        padding: 0.56rem 0.72rem;
    }

    .data-table {
        min-width: 620px;
        font-size: 12px;
    }

    .data-table th,
    .data-table td {
        padding: 0.72rem 0.78rem;
    }

    .invoice-filter-actions,
    .module-actions,
    .home-actions {
        width: 100%;
    }

    .invoice-filter-actions .btn,
    .module-actions .btn,
    .home-actions .btn {
        flex: 1 1 100%;
    }

    .home-title {
        font-size: 3.2rem;
        line-height: 0.95;
    }

    .home-preview,
    .home-feature-card,
    .home-cta {
        border-radius: var(--radius-md);
    }

    .modal-backdrop {
        align-items: flex-end;
        padding: 10px;
    }

    .modal-backdrop > form,
    .modal-backdrop > div {
        max-height: calc(100vh - 24px);
        overflow-y: auto;
    }

}

@media (max-width: 380px) {
    .brand-text {
        max-width: 8.2rem;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .home-title {
        font-size: 2.75rem;
    }

}

.emoji-input-wrap {
    position: relative;
    display: flex;
    align-items: stretch;
    width: 100%;
}

.emoji-input-wrap .field {
    width: 100%;
    padding-right: 3rem;
}

.emoji-input-button {
    position: absolute;
    right: .35rem;
    top: 50%;
    transform: translateY(-50%);
    width: 2.25rem;
    height: 2.25rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(17, 24, 39, .12);
    border-radius: var(--radius-md);
    background: rgba(var(--surface-rgb), .72);
    color: var(--text);
    cursor: pointer;
    transition: background .16s ease, border-color .16s ease, color .16s ease, transform .16s ease;
}

@media (hover: hover) and (pointer: fine) {
.emoji-input-button:hover {
    background: var(--theme-white);
    border-color: color-mix(in srgb, var(--brand, #0062ff) 34%, transparent);
    color: var(--brand, #0062ff);
}
}

.emoji-input-button svg {
    width: 1rem;
    height: 1rem;
}

/* Emoji picker (public/emoji-picker.js). Painted from the theme's own tokens, so it
   matches Blue, Dark, Midnight and the glass / solid looks instead of being a fixed
   dark box. Search, one row of categories, the section, then a preview bar. */
.emoji-picker {
    position: fixed;
    z-index: 3200;
    display: flex;
    flex-direction: column;
    width: 352px;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: linear-gradient(var(--surface), var(--surface)), var(--bg);
    color: var(--text);
    box-shadow: 0 1px 2px rgb(0 0 0 / .12), 0 16px 40px -8px rgb(0 0 0 / .35);
    overflow: hidden;
    transform-origin: top center;
    animation: nxEmojiIn 160ms cubic-bezier(.23, 1, .32, 1);
}
.emoji-picker[data-place="above"] { transform-origin: bottom center; }
.emoji-picker.hidden { display: none; }
@keyframes nxEmojiIn { from { opacity: 0; transform: scale(.97) translateY(-4px); } }
.emoji-picker[data-place="above"] { animation-name: nxEmojiInUp; }
@keyframes nxEmojiInUp { from { opacity: 0; transform: scale(.97) translateY(4px); } }
@media (prefers-reduced-motion: reduce) {
    .emoji-picker, .emoji-picker[data-place="above"] { animation: nxEmojiFade 120ms ease-out; }
    @keyframes nxEmojiFade { from { opacity: 0; } }
}

.emoji-picker-head {
    display: grid;
    gap: 8px;
    padding: 10px 10px 8px;
    border-bottom: 1px solid var(--line);
}

.emoji-picker-searchbox { position: relative; display: block; }
.emoji-picker-searchbox svg {
    position: absolute; left: 10px; top: 50%; translate: 0 -50%;
    width: 15px; height: 15px;
    fill: none; stroke: var(--muted); stroke-width: 2; stroke-linecap: round;
    pointer-events: none;
}
.emoji-picker-search {
    width: 100%;
    height: 34px;
    padding: 0 10px 0 32px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: color-mix(in srgb, var(--text) 4%, transparent);
    color: var(--text);
    font: inherit;
    font-size: 14px;
    outline: none;
    transition: border-color 150ms ease, box-shadow 150ms ease;
}
.emoji-picker-search::placeholder { color: var(--muted); }
.emoji-picker-search::-webkit-search-cancel-button { display: none; }
.emoji-picker-search:focus,
.emoji-picker-search:focus-visible {
    outline: none;
    border-color: var(--brand, #0062ff);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand, #0062ff) 18%, transparent);
}

/* All categories on one row, equal widths: no wrapping onto a lopsided second row. */
.emoji-picker-tabs {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 2px;
}
.emoji-picker-tab {
    display: grid;
    place-items: center;
    height: 30px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    transition: color 150ms ease, background-color 150ms ease;
}
.emoji-picker-tab svg { width: 16px; height: 16px; stroke-width: 2; }
@media (hover: hover) and (pointer: fine) {
    .emoji-picker-tab:hover { color: var(--text); background: color-mix(in srgb, var(--text) 6%, transparent); }
}
.emoji-picker-tab.is-active {
    color: var(--brand, #0062ff);
    background: color-mix(in srgb, var(--brand, #0062ff) 14%, transparent);
}
.emoji-picker-tab:focus-visible,
.emoji-picker-item:focus-visible {
    outline: 2px solid var(--brand, #0062ff);
    outline-offset: -2px;
}

.emoji-picker-title {
    padding: 10px 14px 4px;
    color: var(--muted);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.emoji-picker-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(36px, 1fr));
    align-content: start;
    gap: 2px;
    flex: 1 1 auto;
    min-height: 0;
    max-height: 15rem;
    padding: 2px 10px 10px;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
}
.emoji-picker-item {
    display: grid;
    place-items: center;
    height: 36px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    font-size: 22px;
    line-height: 1;
    font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", system-ui, sans-serif;
    cursor: pointer;
    transition: background-color 120ms ease, transform 100ms ease-out;
}
@media (hover: hover) and (pointer: fine) {
    .emoji-picker-item:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
}
.emoji-picker-item:active { transform: scale(.92); }
.emoji-picker-custom-item img { width: 26px; height: 26px; object-fit: contain; border-radius: 6px; display: block; }

.emoji-picker-empty {
    grid-column: 1 / -1;
    margin: 0;
    padding: 2rem .75rem;
    color: var(--muted);
    font-size: 13px;
    text-align: center;
}

/* The hovered emoji, big, with its name: a check before the click. */
.emoji-picker-foot {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 6px 14px;
    border-top: 1px solid var(--line);
    color: var(--muted);
    font-size: 13px;
}
.emoji-picker-preview {
    display: grid;
    place-items: center;
    width: 28px;
    font-size: 24px;
    line-height: 1;
    font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", system-ui, sans-serif;
}
.emoji-picker-preview:empty { display: none; }
.emoji-picker-preview img { width: 26px; height: 26px; object-fit: contain; }
.emoji-picker-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); font-weight: 600; }

.dashboard-dialog-backdrop {
    position: fixed;
    inset: 0;
    z-index: 2500;
    display: grid;
    place-items: center;
    padding: 1rem;
    background: rgba(15, 23, 42, .54);
    backdrop-filter: blur(10px);
}

.dashboard-dialog-backdrop.hidden {
    display: none;
}

.dashboard-dialog {
    width: min(440px, 100%);
    border: 1px solid rgba(17, 24, 39, .12);
    border-radius: var(--radius-lg);
    background: rgba(var(--surface-rgb), .96);
    box-shadow: 0 26px 80px rgba(15, 23, 42, .28);
    color: var(--text);
    padding: 1.25rem;
    animation: emojiPickerIn .14s ease-out;
}

.dashboard-dialog-icon {
    width: 2.6rem;
    height: 2.6rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-lg);
    color: var(--brand, #0062ff);
    background: linear-gradient(135deg, color-mix(in srgb, var(--brand, #0062ff) 12%, transparent), rgba(104, 83, 237, .18));
    margin-bottom: 1rem;
}

.dashboard-dialog-copy h2,
.dashboard-dialog-copy .dashboard-dialog-title {
    margin: 0;
    font-size: 1.2rem;
    font-weight: 900;
}

.dashboard-dialog-copy p {
    margin: .45rem 0 0;
    /* Confirm/warning text: theme muted, readable on dark and light. */
    color: var(--muted, #4b5563);
    line-height: 1.55;
    white-space: pre-line;
}

.dashboard-dialog-input {
    margin-top: 1rem;
}

.dashboard-dialog-actions {
    display: flex;
    justify-content: flex-end;
    gap: .75rem;
    margin-top: 1.2rem;
}

.dashboard-dialog-actions .btn {
    min-width: 6.25rem;
}

@keyframes emojiPickerIn {
    from {
        opacity: 0;
        transform: translateY(-4px) scale(.98);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }

}

@media (max-width: 520px) {
    .emoji-picker {
        position: fixed;
        left: 10px !important;
        right: 10px;
        top: auto !important;
        bottom: 10px;
        width: auto !important;
    }

    .emoji-picker { transform-origin: bottom center; }
    .emoji-picker-grid { max-height: 13rem; }

}

html,
body {
    min-height: 100%;
}

/* Flat base only. The canvas background is NOT captured by a view transition, so any colour
   here would snap instead of wiping, the themed gradient goes on body::before. */
html {
    background: var(--bg);
}

/* Must stay transparent: body's own background paints over its negative z-index ::before. */
body {
    background: transparent;
}

.dashboard-root,
.dashboard-root.has-guild .dashboard-frame {
    width: 100%;
}

@media (min-width: 1920px) {
    .dashboard-root.has-guild .dashboard-frame {
        max-width: none;
        margin: 0;
        border-left: 0;
        border-right: 0;
    }

}

.auto-currency-toggle {
    display: grid;
    grid-template-columns: auto auto 1fr;
    align-items: center;
    gap: .85rem;
    padding: .85rem 1rem;
    border: 1px solid rgba(17, 24, 39, .12);
    border-radius: var(--radius-lg);
    background: rgba(var(--surface-rgb), .64);
    cursor: pointer;
    transition: border-color .16s ease, box-shadow .16s ease, background .16s ease;
}

@media (hover: hover) and (pointer: fine) {
.auto-currency-toggle:hover {
    border-color: color-mix(in srgb, var(--brand, #0062ff) 32%, transparent);
    background: rgba(var(--surface-rgb), .86);
}
}

.auto-currency-toggle input {
    width: 1.05rem;
    height: 1.05rem;
    accent-color: var(--brand, #0062ff);
}

.auto-currency-icon {
    width: 2.15rem;
    height: 2.15rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-md);
    background: linear-gradient(135deg, color-mix(in srgb, var(--brand, #0062ff) 12%, transparent), rgba(104, 83, 237, .16));
    color: var(--brand, #0062ff);
}

.auto-currency-toggle strong,
.auto-currency-toggle small {
    display: block;
}

.auto-currency-toggle small {
    margin-top: .12rem;
    color: rgba(17, 24, 39, .58);
    font-weight: 700;
}

.channel-native-hidden {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    opacity: 0 !important;
    pointer-events: none !important;
    overflow: hidden !important;
}

.channel-combobox {
    position: relative;
    width: 100%;
}

.channel-combo-control {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 2.75rem;
}

.channel-combo-input {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

.channel-combo-input::-webkit-search-cancel-button {
    cursor: pointer;
}

.channel-combo-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--line-soft);
    border-left: 0;
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
    background: rgba(var(--surface-rgb), .78);
    color: var(--muted);
    cursor: pointer;
    transition: background .16s ease, border-color .16s ease, color .16s ease;
}

@media (hover: hover) and (pointer: fine) {
.channel-combo-toggle:hover {
    background: var(--theme-white);
    color: var(--brand, #0062ff);
    border-color: color-mix(in srgb, var(--brand, #0062ff) 34%, transparent);
}
}

.channel-combo-toggle svg {
    width: 1rem;
    height: 1rem;
    transition: transform .16s ease;
}

.channel-combobox.is-open .channel-combo-toggle svg {
    transform: rotate(180deg);
}

.channel-combo-menu {
    position: absolute;
    z-index: 1300;
    left: 0;
    right: 0;
    top: calc(100% + .42rem);
    display: none;
    overflow: hidden;
    border: 1px solid color-mix(in srgb, var(--text) 14%, transparent);
    border-radius: var(--radius-lg);
    background: rgba(var(--surface-rgb), .98);
    box-shadow: 0 24px 70px rgba(15, 23, 42, .2);
}

.channel-combobox.is-open .channel-combo-menu {
    display: block;
    animation: comboIn .14s ease-out;
}

.channel-combo-list {
    max-height: 17rem;
    overflow-y: auto;
    padding: .45rem;
}

.channel-combo-option {
    width: 100%;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: .16rem .75rem;
    align-items: center;
    padding: .7rem .75rem;
    border: 0;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--text);
    text-align: left;
    cursor: pointer;
    transition: background .14s ease, color .14s ease, transform .14s ease;
}

.channel-combo-option:focus {
    outline: 0;
    background: color-mix(in srgb, var(--brand, #0062ff) 8%, transparent);
}
@media (hover: hover) and (pointer: fine) {
.channel-combo-option:hover {
    outline: 0;
    background: color-mix(in srgb, var(--brand, #0062ff) 8%, transparent);
}
}

.channel-combo-option.is-selected {
    background: linear-gradient(135deg, color-mix(in srgb, var(--brand, #0062ff) 13%, transparent), rgba(104, 83, 237, .16));
}

.channel-combo-option.is-empty {
    color: var(--muted);
}

.channel-combo-text {
    grid-column: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 800;
}

.channel-combo-id {
    grid-column: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--muted);
    font-size: .72rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
}

.channel-combo-check {
    grid-column: 2;
    grid-row: 1 / span 2;
    padding: .2rem .5rem;
    border-radius: 999px;
    border: 1px solid color-mix(in srgb, var(--text) 12%, transparent);
    color: var(--muted);
    font-size: .7rem;
    font-weight: 800;
}

.channel-combo-option.is-selected .channel-combo-check {
    border-color: color-mix(in srgb, var(--brand, #0062ff) 24%, transparent);
    background: color-mix(in srgb, var(--brand, #0062ff) 10%, transparent);
    color: var(--brand, #0062ff);
}

.channel-combo-empty {
    padding: 1.25rem .75rem;
    color: var(--muted);
    font-weight: 800;
    text-align: center;
}

.channel-combo-meta {
    border-top: 1px solid color-mix(in srgb, var(--text) 10%, transparent);
    padding: .6rem .8rem;
    background: var(--theme-soft);
    color: var(--muted);
    font-size: .72rem;
    font-weight: 700;
}

@keyframes comboIn {
    from {
        opacity: 0;
        transform: translateY(-4px) scale(.99);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }

}

/* Phones: menu sits in flow under the input. A fixed bottom sheet ends up
   behind the on-screen keyboard, so the list looked like it never loaded. */
@media (max-width: 640px) {
    .channel-combo-menu {
        position: static;
        margin-top: .42rem;
    }

    .channel-combo-list {
        max-height: min(17rem, 45vh);
        overscroll-behavior: contain;
    }

    .channel-combo-option {
        min-height: 44px;
    }
}

.discord-preview-card,
.verify-preview {
    /* A mock of Discord's own dark chat, so it stays dark on every theme and
       carries its own foreground rather than the page's --surface-rgb. */
    --panel-fg: 242, 243, 245;
    background: #313338 !important;
    border-color: rgba(0, 0, 0, .36) !important;
    color: #f2f3f5 !important;
}

.discord-preview-card .text-white,
.discord-preview-card .font-bold,
.discord-preview-card #previewTitle,
.discord-preview-card #tosPreviewTitle,
.verify-preview #previewTitle {
    color: #f2f3f5 !important;
}

.discord-preview-card .text-zinc-300,
.discord-preview-card #previewDescription,
.discord-preview-card #tosPreviewText,
.verify-preview .verify-preview-message {
    color: #dbdee1 !important;
}

.discord-preview-card .text-zinc-400,
.discord-preview-card .muted,
.discord-preview-card #previewFooter,
.discord-preview-card #tosPreviewFooter,
.discord-preview-note,
.verify-preview .muted {
    color: #b5bac1 !important;
}

.discord-preview-card .badge {
    background: #f2f3f5 !important;
    border-color: rgba(17, 24, 39, .14) !important;
    color: #111827 !important;
}

.discord-preview-select {
    background: #1e1f22 !important;
    border: 1px solid rgba(var(--panel-fg), .08);
    color: #dbdee1 !important;
}

.server-search-panel {
    position: sticky;
    top: 70px;
    z-index: 5;
}

.server-search-box {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: .75rem;
}

.server-search-box > svg {
    color: var(--muted);
}

.server-search-box .field {
    min-height: 2.75rem;
}

@media (max-width: 640px) {
    .server-search-panel {
        position: static;
    }

    .server-search-box {
        grid-template-columns: auto minmax(0, 1fr);
    }

    .server-search-box .badge {
        grid-column: 1 / -1;
        justify-self: start;
    }

}

.ticket-stat-card {
    display: grid;
    gap: 0.45rem;
}

.ticket-stat-icon {
    width: 2.4rem;
    height: 2.4rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    color: var(--brand);
    background: var(--surface-2);
}

.ticket-stat-card strong {
    font-size: clamp(1.7rem, 4vw, 2.4rem);
    line-height: 1;
}

.ticket-stat-card small,
.ticket-mini-stat small {
    color: var(--muted);
    font-weight: 700;
}

.ticket-stat-card small span {
    display: inline-flex;
    margin-right: 0.35rem;
    padding: 0.08rem 0.42rem;
    border-radius: var(--radius-sm);
    color: var(--ok-text);
    background: rgba(34, 197, 94, 0.14);
}

.ticket-mini-stat {
    display: grid;
    gap: 0.35rem;
}

.ticket-mini-stat > span {
    color: var(--muted);
    font-weight: 800;
}

.ticket-mini-stat strong {
    font-size: 1.55rem;
}

.ticket-chart-card svg {
    width: 100%;
    height: auto;
    min-height: 210px;
    overflow: visible;
}

.ticket-line {
    fill: none;
    stroke-width: 3;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.ticket-line.opened { stroke: #818cf8; }
.ticket-line.claimed { stroke: #6853ED; }
.ticket-line.closed { stroke: #22c55e; }
.ticket-line.response { stroke: #7c8cff; }
.ticket-line.messages { stroke: #f59e0b; }

.ticket-chart-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.55rem;
    align-items: center;
    color: var(--muted);
    font-size: 0.8rem;
    font-weight: 800;
}

.ticket-chart-legend span {
    width: 0.7rem;
    height: 0.7rem;
    border-radius: var(--radius-sm);
}

.ticket-chart-legend .opened { background: #818cf8; }
.ticket-chart-legend .claimed { background: #6853ED; }
.ticket-chart-legend .closed { background: #22c55e; }
.ticket-chart-legend .response { background: #7c8cff; }
.ticket-chart-legend .messages { background: #f59e0b; }

.ticket-chart-days {
    display: flex;
    justify-content: space-between;
    gap: 0.65rem;
    overflow-x: auto;
    color: var(--muted);
    font-size: 0.8rem;
    font-weight: 800;
    margin-top: -0.4rem;
    scrollbar-width: none;
}

.ticket-chart-days::-webkit-scrollbar {
    display: none;
}

.ticket-chart-days span {
    flex: 0 0 auto;
}

.ticket-staff-row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) repeat(3, minmax(6rem, auto));
    gap: 1rem;
    align-items: center;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--surface);
    padding: 1rem;
}

.ticket-staff-person {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.ticket-staff-avatar {
    width: 2.6rem;
    height: 2.6rem;
    border-radius: 999px;
    object-fit: cover;
    flex: none;
    border: 1px solid var(--line);
    background: var(--surface-2);
}

.ticket-staff-avatar-fallback {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--brand);
    font-weight: 900;
}

.ticket-staff-rank {
    width: 1.6rem;
    height: 1.6rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    color: var(--text);
    background: #f59e0b;
    font-weight: 900;
}

.ticket-staff-row div:not(.min-w-0) span {
    display: block;
    color: var(--muted);
    font-size: 0.75rem;
    font-weight: 800;
}

.ticket-staff-row div:not(.min-w-0) strong {
    display: block;
    margin-top: 0.2rem;
}

@media (max-width: 760px) {
    .ticket-staff-row {
        grid-template-columns: auto minmax(0, 1fr);
    }

}

.discord-button-preview-row {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    padding: 10px;
    border: 1px solid var(--line-soft);
    border-radius: 8px;
    background: #313338;
}

.discord-button-preview {
    min-height: 34px;
    border: 0;
    border-radius: 3px;
    color: #F4F4F4;
    cursor: default;
    font-weight: 700;
    padding: 0 14px;
}

.discord-button-primary {
    background: #5865f2;
}

.discord-button-success {
    background: #248046;
}

.discord-button-secondary {
    background: #4e5058;
}

.discord-button-danger {
    background: #da373c;
}

#productForm .field:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* Theme switcher */
:root {
    --font-cursive: "Playfair Display", "Iowan Old Style", Georgia, serif;
    --blue-rgb: 0, 98, 255;
    --violet-rgb: 104, 83, 237;
    --surface-rgb: 244, 244, 244;
    --theme-white: #F4F4F4;
    --theme-soft: #F4F4F4;
    --theme-wipe-color: var(--brand, #0062ff);
    --theme-focus-ring: color-mix(in srgb, var(--brand, #0062ff) 16%, transparent);
    --page-bg:
        linear-gradient(135deg, #F4F4F4 0%, #F4F4F4 36%, color-mix(in srgb, var(--brand, #0062ff) 16%, transparent) 66%, rgba(104, 83, 237, 0.22) 100%);
    /* Aurora mesh hero: soft colour blooms that fade to a clean --bg at the bottom edge,
       so there is no seam into the next section. Built from --blue-rgb/--violet-rgb/--bg,
       so every theme gets its own version from this one declaration. */
    /* --hero-tint scales every bloom at once: mono's "colour" is near-black, so it needs
       roughly half the strength of a chromatic theme to stay clean instead of dirty grey. */
    --hero-tint: 1;
    --hero-bg:
        radial-gradient(120% 78% at 50% 118%, var(--bg) 40%, rgba(0, 0, 0, 0) 74%),
        radial-gradient(48% 46% at 14% 2%, rgba(var(--blue-rgb), calc(0.26 * var(--hero-tint))), rgba(0, 0, 0, 0) 66%),
        radial-gradient(46% 44% at 88% -4%, rgba(var(--violet-rgb), calc(0.28 * var(--hero-tint))), rgba(0, 0, 0, 0) 66%),
        radial-gradient(58% 48% at 62% 46%, rgba(var(--violet-rgb), calc(0.12 * var(--hero-tint))), rgba(0, 0, 0, 0) 70%),
        radial-gradient(52% 44% at 26% 62%, rgba(var(--blue-rgb), calc(0.10 * var(--hero-tint))), rgba(0, 0, 0, 0) 70%),
        var(--bg);
    --soft-card-gradient:
        linear-gradient(135deg, rgba(var(--surface-rgb), 0.86), rgba(var(--surface-rgb), 0.62)),
        linear-gradient(135deg, color-mix(in srgb, var(--brand, #0062ff) 14%, transparent), rgba(104, 83, 237, 0.14));
    --cta-bg:
        linear-gradient(135deg, rgba(var(--surface-rgb), 0.78), color-mix(in srgb, var(--brand, #0062ff) 10%, transparent), rgba(104, 83, 237, 0.12));
}

/* Status words (Open, Active, Accepted, Live / Waiting / Closed, Rejected): bright on the
   dark themes, deep on the light ones, where the bright shades read 1.5-2.8:1 on white. */
:root { --ok-text: #15803d; --warn-text: #b45309; --bad-text: #b91c1c; }
html:is([data-theme="dyno"], [data-theme="super"], [data-theme="dusk"]) { --ok-text: #4ade80; --warn-text: #f59e0b; --bad-text: #f87171; }

/* A light picked accent (yellow, lime) on the bright themes: its darker ink, so accent
   text ("New", headings, pills) stays readable on white. layout.ejs/customize set it. */
html[data-look-ink]:not([data-theme="dyno"], [data-theme="super"], [data-theme="dusk"]) {
    --brand: var(--brand-ink) !important;
    --blue: var(--brand-ink) !important;
    --purple: var(--brand-ink) !important;
    --blue-rgb: var(--brand-ink-rgb) !important;
}

html[data-theme="red"] {
    color-scheme: light;
    --bg: #F4F4F4;
    --surface: rgba(var(--surface-rgb), 0.92);
    --surface-2: rgba(var(--surface-rgb), 0.9);
    --panel: rgba(var(--surface-rgb), 0.92);
    --panel-strong: rgba(var(--surface-rgb), 0.94);
    --hover: rgba(220, 38, 38, 0.08);
    --line: rgba(127, 29, 29, 0.14);
    --line-soft: rgba(127, 29, 29, 0.18);
    --line-strong: #1f1111;
    --text: #1f1111;
    --muted: #6f5555;
    --faint: #967676;
    --blue: #dc2626;
    --violet: #fb7185;
    --purple: #dc2626;
    --purple-2: #fb7185;
    --pink: #be123c;
    --cyan: #991b1b;
    --green: #15803d;
    --red: #b91c1c;
    --blue-rgb: 220, 38, 38;
    --violet-rgb: 251, 113, 133;
    --theme-wipe-color: #dc2626;
    --theme-focus-ring: rgba(220, 38, 38, 0.16);
    --page-bg:
        linear-gradient(135deg, #F4F4F4 0%, #F4F4F4 38%, rgba(220, 38, 38, 0.12) 68%, rgba(251, 113, 133, 0.18) 100%);
    /* --hero-bg comes from :root and rebuilds itself from this theme's --blue-rgb/--violet-rgb. */
    --soft-card-gradient:
        linear-gradient(135deg, rgba(var(--surface-rgb), 0.9), rgba(var(--surface-rgb), 0.72)),
        linear-gradient(135deg, rgba(220, 38, 38, 0.12), rgba(251, 113, 133, 0.12));
    --cta-bg:
        linear-gradient(135deg, rgba(var(--surface-rgb), 0.84), rgba(220, 38, 38, 0.1), rgba(251, 113, 133, 0.12));
}

html[data-theme="mono"] {
    color-scheme: light;
    --bg: #F4F4F4;
    --surface: rgba(var(--surface-rgb), 0.94);
    --surface-2: rgba(var(--surface-rgb), 0.92);
    --panel: rgba(var(--surface-rgb), 0.94);
    --panel-strong: rgba(var(--surface-rgb), 0.96);
    --hover: rgba(17, 17, 17, 0.06);
    --line: rgba(17, 17, 17, 0.14);
    --line-soft: rgba(17, 17, 17, 0.16);
    --line-strong: #111111;
    --text: #080808;
    --muted: #525252;
    --faint: #737373;
    --blue: #111111;
    --violet: #555555;
    --purple: #111111;
    --purple-2: #555555;
    --pink: #222222;
    --cyan: #111111;
    --green: #166534;
    --red: #991b1b;
    --blue-rgb: 17, 17, 17;
    --violet-rgb: 85, 85, 85;
    --theme-wipe-color: #111111;
    --theme-focus-ring: rgba(17, 17, 17, 0.16);
    --hero-tint: 0.5;
    --page-bg:
        linear-gradient(135deg, #F4F4F4 0%, #F4F4F4 42%, rgba(17, 17, 17, 0.08) 100%);
    /* --hero-bg comes from :root and rebuilds itself from this theme's --blue-rgb/--violet-rgb. */
    --soft-card-gradient:
        linear-gradient(135deg, rgba(var(--surface-rgb), 0.92), rgba(var(--surface-rgb), 0.74)),
        linear-gradient(135deg, rgba(17, 17, 17, 0.08), rgba(85, 85, 85, 0.08));
    --cta-bg:
        linear-gradient(135deg, rgba(var(--surface-rgb), 0.86), rgba(17, 17, 17, 0.08), rgba(85, 85, 85, 0.08));
}

/* Dyno: the dyno.gg look. Near-black page, charcoal panels, crimson accent. Only dark
   theme in the set, so the light-surface overrides for red/mono do not apply here and
   anything hardcoded to #F4F4F4 below gets its own html[data-theme="dyno"] rule. */
html[data-theme="dyno"] {
    color-scheme: dark;
    --bg: #111111;
    --surface: #1e1e1e;
    --surface-2: #262626;
    --panel: #1e1e1e;
    --panel-strong: #242424;
    --hover: rgba(255, 36, 66, 0.14);
    --line: rgba(255, 255, 255, 0.08);
    --line-soft: rgba(255, 255, 255, 0.1);
    --line-strong: #3a3a3a;
    --text: #ffffff;
    --muted: #b3b3b3;
    --faint: #7a7a7a;
    --blue: #ff2442;
    --violet: #ff4d64;
    --purple: #ff2442;
    --purple-2: #ff4d64;
    --pink: #ff4d64;
    --cyan: #00a2f8;
    --green: #4bd48a;
    --red: #ff2442;
    --blue-rgb: 255, 36, 66;
    --violet-rgb: 255, 77, 100;
    --surface-rgb: 30, 30, 30;
    --theme-white: #1e1e1e;
    --theme-soft: #262626;
    --theme-wipe-color: #ff2442;
    --theme-focus-ring: rgba(255, 36, 66, 0.3);
    /* Flat like carl.gg: no colour blooms on the page or hero. */
    --hero-tint: 0;
    --page-bg: #111111;
    --soft-card-gradient:
        linear-gradient(135deg, #1e1e1e, #1e1e1e);
    --cta-bg:
        linear-gradient(135deg, #1e1e1e, #1e1e1e);
}
/* EnderCloud wordmark is dark text; dark theme swaps in the white version. */
html[data-theme="dyno"] .ec-logo { content: url("/brand/endercloud-logo-dark.png"); }
html[data-theme="dyno"] .home-hero::before,
html[data-theme="dyno"] .home-hero::after {
    display: none;
}
html[data-theme="dyno"] * {
    scrollbar-color: rgba(255, 36, 66, 0.7) rgba(255, 255, 255, 0.05);
}
html[data-theme="dyno"] .topbar,
html[data-theme="dyno"] .app-sidebar,
html[data-theme="dyno"] .app-rightbar {
    background: rgba(24, 24, 24, 0.96);
    border-color: var(--line);
}
html[data-theme="dyno"] .brand-logo-mark,
html[data-theme="dyno"] .brand-preview-logo,
html[data-theme="dyno"] .resource-provider,
html[data-theme="dyno"] .home-hosting-provider,
html[data-theme="dyno"] .home-eyebrow,
html[data-theme="dyno"] .home-limited-kicker {
    background: #1e1e1e;
    border-color: var(--line);
}
html[data-theme="dyno"] .badge-good { border-color: rgba(34, 197, 94, .35); background: rgba(34, 197, 94, .14); color: #4ade80; }
html[data-theme="dyno"] .badge-warn { border-color: rgba(245, 158, 11, .35); background: rgba(245, 158, 11, .14); color: #fbbf24; }
html[data-theme="dyno"] .badge-bad,
html[data-theme="dyno"] :is(.btn-danger, .btn-bad) { border-color: rgba(255, 36, 66, .4); background: rgba(255, 36, 66, .14); color: #ff4d64; }
html[data-theme="dyno"] .app-switch,
html[data-theme="dyno"] .app-switch.is-split .app-switch-btn {
    border-color: #ff2442;
}
html[data-theme="dyno"] .app-switch-btn.is-active,
html[data-theme="dyno"] .app-switch.is-split .app-switch-btn {
    background: #ff2442;
}
/* Flat red fills, white text, no gradients: the launcher look. */
html[data-theme="dyno"] .btn-primary,
html[data-theme="dyno"] .nav-link-active,
html[data-theme="dyno"] .nav-pill {
    background: #ff2442;
    color: #fff;
    box-shadow: none;
}
@media (hover: hover) and (pointer: fine) {
html[data-theme="dyno"] .btn-primary:hover { background: #ff3d58; }
}

/* Superuser: the superuser.app look. Pure black page, soft charcoal cards on a big
   radius, white pill buttons and one vivid green accent, with a warm-to-violet bloom
   behind the hero instead of a flat colour. Dark, like dyno - so it is excluded from
   the "last light theme" the sky switch goes back to. */
html[data-theme="super"] {
    color-scheme: dark;
    --bg: #101010;
    --surface: #181818;
    --surface-2: #202022;
    --panel: #181818;
    --panel-strong: #202022;
    --hover: rgba(255, 255, 255, 0.07);
    --line: rgba(255, 255, 255, 0.08);
    --line-soft: rgba(255, 255, 255, 0.12);
    --line-strong: #303033;
    --text: #ffffff;
    --muted: #a2a2a8;
    --faint: #6e6e76;
    --blue: #ff3950;
    --violet: #cc80ff;
    --purple: #ff3950;
    --purple-2: #cc80ff;
    --pink: #ff6f81;
    --cyan: #4d8bff;
    --green: #0bd468;
    --red: #ff3950;
    --blue-rgb: 255, 57, 80;
    --violet-rgb: 204, 128, 255;
    --surface-rgb: 24, 24, 24;
    --theme-white: #181818;
    --theme-soft: #202022;
    --theme-wipe-color: #ff3950;
    --theme-focus-ring: rgba(255, 57, 80, 0.3);
    --page-bg: #101010;
    /* The one place this theme spends colour: a warm sunrise on the left running
       through pink into violet and blue, dying into the black page before the next
       section starts. Written out rather than built from --blue-rgb/--violet-rgb,
       because the point is that it is four hues, not two. */
    --hero-bg:
        radial-gradient(140% 94% at 50% 134%, var(--bg) 38%, rgba(16, 16, 16, 0) 72%),
        radial-gradient(72% 66% at 0% -2%, rgba(255, 140, 26, 0.95), rgba(255, 140, 26, 0) 62%),
        radial-gradient(62% 58% at 38% 12%, rgba(255, 105, 132, 0.62), rgba(255, 105, 132, 0) 66%),
        radial-gradient(68% 64% at 88% -8%, rgba(162, 118, 255, 0.88), rgba(162, 118, 255, 0) 66%),
        radial-gradient(72% 62% at 106% 40%, rgba(72, 120, 255, 0.6), rgba(72, 120, 255, 0) 68%),
        var(--bg);
    --soft-card-gradient:
        linear-gradient(135deg, #1c1c1e, #161617);
    --cta-bg:
        linear-gradient(135deg, #181818, rgba(255, 57, 80, 0.12), rgba(204, 128, 255, 0.08));
}

/* Dark spends one accent: red. Green stays only where it means something (status up,
   a live store, Discord mock-ups, the changelog's New tag, brand swatches); the
   "free" ticks and banners are decoration, so they take the accent. The compare
   table's "Included free" column and the custom bot table's "Yes" stay green: comparison
   marks keep their meaning (user call, 2026-10-16). */
html[data-theme="super"] :is(.home-free-points svg, .home-compare-note i, .compare-free-banner i, .home-showcase-points li svg, .dn-promise > i, .dn-promise > svg) { color: var(--red); }
html[data-theme="super"] :is(.home-compare-note, .compare-free-banner) { border-color: rgba(var(--blue-rgb), .32); background: rgba(var(--blue-rgb), .08); }
html[data-theme="super"] .nx-peek-head img { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--red); }
/* Funnel Display for headings, Assistant for text - the two faces the site uses, on
   every theme (they used to be the Dark theme's only, so switching theme swapped
   the whole site to Inter). The :is() matches any html and keeps the attribute
   selector's specificity the old html[data-theme="super"] rules had. The fonts
   are linked in layout.ejs. */
html:is([data-theme], :not([data-theme])) body,
html:is([data-theme], :not([data-theme])) a,
html:is([data-theme], :not([data-theme])) button,
html:is([data-theme], :not([data-theme])) input,
html:is([data-theme], :not([data-theme])) textarea,
html:is([data-theme], :not([data-theme])) select {
    font-family: Assistant, Inter, ui-sans-serif, system-ui, -apple-system, sans-serif;
}
html:is([data-theme], :not([data-theme])) h1,
html:is([data-theme], :not([data-theme])) h2,
html:is([data-theme], :not([data-theme])) h3 {
    font-family: "Funnel Display", Assistant, Inter, ui-sans-serif, system-ui, sans-serif;
    font-weight: 600;
    letter-spacing: -0.02em;
}
html[data-theme="super"] .ec-logo { content: url("/brand/endercloud-logo-dark.png"); }
/* The hero's own decorative blobs are built for a light page; --hero-bg is the show here. */
html[data-theme="super"] .home-hero::before,
html[data-theme="super"] .home-hero::after {
    display: none;
}
html[data-theme="super"] * {
    scrollbar-color: rgba(255, 255, 255, 0.22) rgba(255, 255, 255, 0.05);
}
html[data-theme="super"] .topbar,
html[data-theme="super"] .app-sidebar,
html[data-theme="super"] .app-rightbar {
    background: rgba(16, 16, 16, 0.96);
    border-color: var(--line);
}
html[data-theme="super"] .brand-logo-mark,
html[data-theme="super"] .brand-preview-logo,
html[data-theme="super"] .resource-provider,
html[data-theme="super"] .home-hosting-provider,
html[data-theme="super"] .home-eyebrow,
html[data-theme="super"] .home-limited-kicker {
    background: #181818;
    border-color: var(--line);
}
/* Soft, generous corners on every card - closer to 20px than the site's default. */
html[data-theme="super"] .panel,
html[data-theme="super"] .home-feature-card,
html[data-theme="super"] .status-grid-block,
html[data-theme="super"] .status-card {
    border-radius: var(--radius-lg);
}
html[data-theme="super"] .badge-good { border-color: rgba(11, 212, 104, .35); background: rgba(11, 212, 104, .14); color: #0bd468; }
html[data-theme="super"] .badge-warn { border-color: rgba(255, 175, 15, .35); background: rgba(255, 175, 15, .14); color: #ffaf0f; }
html[data-theme="super"] .badge-bad,
html[data-theme="super"] :is(.btn-danger, .btn-bad) { border-color: rgba(255, 57, 80, .45); background: rgba(255, 57, 80, .16); color: #ff6f81; }
/* White pill primaries with black text: the one button style the whole site is built on. */
html[data-theme="super"] .btn-primary {
    background: #ffffff;
    color: #101011;
    border-color: #ffffff;
    box-shadow: none;
}
@media (hover: hover) and (pointer: fine) {
html[data-theme="super"] .btn-primary:hover { background: #e8e8e8; color: #101011; }
}
html[data-theme="super"] .btn-secondary {
    background: #202022;
    border-color: var(--line-strong);
    color: #ffffff;
}
@media (hover: hover) and (pointer: fine) {
html[data-theme="super"] .btn-secondary:hover { background: #2a2a2d; }
}
html[data-theme="super"] .nx-btn-primary {
    background: #ffffff !important;
    color: #101011 !important;
    box-shadow: none !important;
}
html[data-theme="super"] .nx-btn-secondary {
    background: #202022 !important;
    border-color: var(--line-strong) !important;
    color: #ffffff !important;
}
html[data-theme="super"] .nav-link-active,
html[data-theme="super"] .nav-pill {
    background: rgba(255, 255, 255, 0.1);
    color: #ffffff;
    box-shadow: none;
}
html[data-theme="super"] .app-switch,
html[data-theme="super"] .app-switch.is-split .app-switch-btn {
    border-color: var(--line-strong);
}
html[data-theme="super"] .app-switch-btn.is-active,
html[data-theme="super"] .app-switch.is-split .app-switch-btn {
    background: #ffffff;
    color: #101011;
}
html[data-theme="super"] .status-tile { background: #0c0c0c; }

/* Dusk: a dark theme built from colour theory rather than copied from a site.
   - Base: one hue (indigo, ~255deg) at very low saturation for page, cards and
     lines, so neutrals feel related instead of dead grey. 60/30/10: page, cards, accent.
   - Accent: violet (~255deg), the brand's own hue, at full saturation - used sparingly.
   - Complement: amber (~38deg) sits opposite violet on the wheel; warnings and highlights.
   - Triad: violet / amber / mint (~160deg) are evenly spaced, so success reads as part
     of the same set. Error is coral, pulled toward amber so it stays warm, not clashing.
   Text passes AA on every surface (body ~16:1, muted ~7:1, accent ~6:1). */
html[data-theme="dusk"] {
    color-scheme: dark;
    --bg: #0e0c17;
    --surface: #16131f;
    --surface-2: #1d1929;
    --panel: #16131f;
    --panel-strong: #221d31;
    --hover: rgba(155, 123, 255, 0.12);
    --line: rgba(196, 180, 255, 0.08);
    --line-soft: rgba(196, 180, 255, 0.12);
    --line-strong: #332c47;
    --text: #f1eefc;
    --muted: #aaa3c2;
    --faint: #726b8c;
    --blue: #9b7bff;
    --violet: #c29bff;
    --purple: #9b7bff;
    --purple-2: #c29bff;
    --pink: #ff8a9a;
    --cyan: #6cc8ff;
    --green: #3ddc97;
    --red: #ff6b7d;
    --blue-rgb: 155, 123, 255;
    --violet-rgb: 194, 155, 255;
    --surface-rgb: 22, 19, 31;
    --theme-white: #16131f;
    --theme-soft: #1d1929;
    --theme-wipe-color: #9b7bff;
    --theme-focus-ring: rgba(155, 123, 255, 0.35);
    --page-bg: #0e0c17;
    /* The accent and its complement meeting at dusk: violet from the right, a low
       amber glow from the left, both fading into the page. */
    --hero-bg:
        radial-gradient(140% 94% at 50% 134%, var(--bg) 38%, rgba(14, 12, 23, 0) 72%),
        radial-gradient(70% 62% at 0% -4%, rgba(255, 181, 71, 0.38), rgba(255, 181, 71, 0) 62%),
        radial-gradient(72% 68% at 92% -8%, rgba(155, 123, 255, 0.6), rgba(155, 123, 255, 0) 66%),
        var(--bg);
    --soft-card-gradient:
        linear-gradient(135deg, #1a1624, #14111c);
    --cta-bg:
        linear-gradient(135deg, #16131f, rgba(155, 123, 255, 0.14), rgba(255, 181, 71, 0.06));
}
html[data-theme="dusk"] .ec-logo { content: url("/brand/endercloud-logo-dark.png"); }
html[data-theme="dusk"] .home-hero::before,
html[data-theme="dusk"] .home-hero::after { display: none; }
html[data-theme="dusk"] * { scrollbar-color: rgba(155, 123, 255, 0.6) rgba(196, 180, 255, 0.05); }
html[data-theme="dusk"] .topbar,
html[data-theme="dusk"] .app-sidebar,
html[data-theme="dusk"] .app-rightbar {
    background: rgba(18, 15, 27, 0.96);
    border-color: var(--line);
}
html[data-theme="dusk"] .brand-logo-mark,
html[data-theme="dusk"] .brand-preview-logo,
html[data-theme="dusk"] .resource-provider,
html[data-theme="dusk"] .home-hosting-provider,
html[data-theme="dusk"] .home-eyebrow,
html[data-theme="dusk"] .home-limited-kicker {
    background: var(--surface);
    border-color: var(--line);
}
html[data-theme="dusk"] .badge-good { border-color: rgba(61, 220, 151, .35); background: rgba(61, 220, 151, .13); color: #3ddc97; }
html[data-theme="dusk"] .badge-warn { border-color: rgba(255, 181, 71, .38); background: rgba(255, 181, 71, .13); color: #ffb547; }
html[data-theme="dusk"] .badge-bad,
html[data-theme="dusk"] :is(.btn-danger, .btn-bad) { border-color: rgba(255, 107, 125, .4); background: rgba(255, 107, 125, .14); color: #ff8a9a; }
html[data-theme="dusk"] .btn-primary,
html[data-theme="dusk"] .nav-link-active,
html[data-theme="dusk"] .nav-pill {
    background: #7c5cff;
    color: #fff;
    box-shadow: none;
}
@media (hover: hover) and (pointer: fine) {
html[data-theme="dusk"] .btn-primary:hover { background: #8d71ff; }
}
html[data-theme="dusk"] .app-switch,
html[data-theme="dusk"] .app-switch.is-split .app-switch-btn { border-color: #7c5cff; }
html[data-theme="dusk"] .app-switch-btn.is-active,
html[data-theme="dusk"] .app-switch.is-split .app-switch-btn { background: #7c5cff; color: #fff; }
html[data-theme="dusk"] .status-tile { background: #120f1b; }

/* Themed page gradient as a real painted layer (not the canvas), so it follows the theme
   and gets clipped by the theme view transition along with everything else. */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    background: var(--page-bg);
    background-size: 100% 100%;
    pointer-events: none;
}

.home-hero {
    background: var(--hero-bg);
}

.home-limited {
    background: var(--soft-card-gradient);
}

.home-cta {
    background: var(--cta-bg);
}

.home-eyebrow-dot,
.brand-mark,
.nav-server-fallback,
.nav-link-active,
.nav-pill,
.resource-meter span,
.module-card-on .module-icon,
.module-switch input:checked + span,
.home-mini-chart span,
.home-feature-icon,
.btn-primary {
    background: linear-gradient(135deg, var(--blue), var(--violet));
}

.btn-primary,
.nav-link-active,
.module-card-on .module-icon,
.home-feature-icon,
.brand-mark,
.nav-server-fallback {
    color: #F4F4F4;
}

.field:focus,
.select:focus,
.textarea:focus,
.topbar-search input:focus {
    border-color: var(--blue);
    box-shadow: 0 0 0 3px var(--theme-focus-ring);
}

.nav-link-active,
.nav-pill {
    box-shadow: 0 10px 28px rgba(var(--blue-rgb), 0.16);
}

@media (hover: hover) and (pointer: fine) {
.btn:hover {
    box-shadow: 0 12px 26px rgba(var(--blue-rgb), 0.14);
}
}

@media (hover: hover) and (pointer: fine) {
.panel:hover,
.panel-strong:hover,
.home-feature-card:hover,
.module-card:hover {
    border-color: rgba(var(--blue-rgb), 0.26);
}
}

@media (hover: hover) and (pointer: fine) {
.home-hosting-provider:hover {
    border-color: rgba(var(--blue-rgb), 0.26);
    box-shadow: 0 18px 56px rgba(var(--blue-rgb), 0.12);
}
}

.skeleton-line::after,
.skeleton-block::after,
.skeleton-card::after,
.skeleton-panel::after {
    background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--text) 6%, transparent), transparent);
}

.theme-toggle {
    position: relative;
    isolation: isolate;
    /* The five theme icons stack in one cell; only the active one is visible. */
    display: grid;
    place-items: center;
    border: 1px solid var(--line);
    background: var(--surface);
    color: var(--blue);
    overflow: visible;
}

.theme-toggle::before {
    content: "";
    position: absolute;
    inset: -10px;
    z-index: -1;
    border-radius: 999px;
    background: radial-gradient(circle, rgba(var(--blue-rgb), 0.22), transparent 68%);
    opacity: 0;
    transform: scale(0.62);
}

@media (hover: hover) and (pointer: fine) {
.theme-toggle:hover {
    border-color: rgba(var(--blue-rgb), 0.3);
    color: var(--blue);
}
}

.theme-toggle-pop::before {
    animation: theme-toggle-radius 360ms cubic-bezier(.2, .8, .2, 1);
}

.theme-icon {
    /* Absolutely centred, so the five icons overlap whatever display the
       button has at a given breakpoint (grid on desktop, inline-flex below 1180px). */
    position: absolute; inset: 0; margin: auto;
    width: 1rem; height: 1rem; flex: none;
    transition: opacity 160ms ease, transform 160ms ease;
}

/* Theme picker: dropdown under the theme button, every theme grouped bright / dark.
   Same shell as .profile-menu-panel; mobile-layout.css pins it like the other menus. */
.theme-menu { position: relative; display: inline-flex; }
.theme-menu-panel {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    z-index: 85;
    width: 220px;
    padding: 0.5rem;
    border-radius: var(--radius-lg);
    border: 1px solid var(--line);
    background: var(--surface, #12131a);
    color: var(--text);
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.4);
    animation: switcherIn 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}
.theme-menu-panel[hidden] { display: none; }
.theme-menu-group + .theme-menu-group {
    margin-top: 0.35rem;
    padding-top: 0.35rem;
    border-top: 1px solid var(--line);
}
.theme-menu-title {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.6rem 0.3rem;
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
}
.theme-menu-option {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    padding: 0.5rem 0.6rem;
    border: none;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 0.85rem;
    font-weight: 700;
    text-align: left;
    cursor: pointer;
    transition: background 140ms ease;
}
.theme-menu-option:focus-visible { background: rgba(var(--blue-rgb, 0, 98, 255), 0.1); outline: none; }
@media (hover: hover) and (pointer: fine) {
.theme-menu-option:hover { background: rgba(var(--blue-rgb, 0, 98, 255), 0.1); outline: none; }
}
.theme-menu-option[aria-checked="true"] { background: rgba(var(--blue-rgb, 0, 98, 255), 0.14); }
.theme-menu-option[aria-checked="true"]::after {
    content: "";
    margin-left: auto;
    width: 7px;
    height: 7px;
    border-radius: 999px;
    background: var(--blue);
}
.theme-menu-swatch {
    flex: none;
    display: inline-grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border-radius: var(--radius-md);
    color: #fff;
    background: var(--swatch-bg, #444);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), inset 0 -1px 0 rgba(0, 0, 0, 0.25), 0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 1px var(--line);
    transition: transform 160ms ease, box-shadow 160ms ease;
}
.theme-menu-swatch { overflow: hidden; }
.theme-menu-swatch > .tsw { display: block; width: 100%; height: 100%; }
.theme-menu-option:hover .theme-menu-swatch,
.theme-menu-option[aria-checked="true"] .theme-menu-swatch {
    transform: scale(1.08);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 4px 12px var(--swatch-glow, rgba(0, 0, 0, 0.4)), 0 0 0 1px var(--line);
}
/* One tile per theme, painted in that theme's own palette. */
.theme-menu-swatch[data-swatch="default"] { --swatch-bg: linear-gradient(145deg, #3b82f6, #0062ff 55%, #1d4ed8); --swatch-glow: rgba(0, 98, 255, .55); }
.theme-menu-swatch[data-swatch="red"] { --swatch-bg: linear-gradient(145deg, #f97316, #dc2626 55%, #b91c1c); --swatch-glow: rgba(220, 38, 38, .55); }
.theme-menu-swatch[data-swatch="mono"] { --swatch-bg: linear-gradient(135deg, #0a0a0a 50%, #f4f4f4 50%); --swatch-glow: rgba(255, 255, 255, .25); color: #fff; }
.theme-menu-swatch[data-swatch="dyno"] { --swatch-bg: radial-gradient(circle at 30% 30%, #2a2a2a, #111 70%); --swatch-glow: rgba(255, 36, 66, .45); color: #ff4d64; }
.theme-menu-swatch[data-swatch="dusk"] { --swatch-bg: radial-gradient(circle at 25% 20%, #ffb547 0, rgba(255, 181, 71, 0) 42%), radial-gradient(circle at 75% 30%, #9b7bff 0, #221d31 55%, #0e0c17 85%); --swatch-glow: rgba(155, 123, 255, .5); color: #f1eefc; }
.theme-menu-swatch[data-swatch="super"] { --swatch-bg: radial-gradient(circle at 70% 25%, #ff3950 0, #2a0a10 38%, #0c0c0c 75%); --swatch-glow: rgba(255, 57, 80, .55); color: #ffb3bc; }
@media (prefers-reduced-motion: reduce) {
    .theme-menu-panel { animation: none; }
}

/* Day/night switch, liquid glass: a frosted track showing a faint sun and moon,
   and a thumb that springs across with an overshoot and swaps its sun for a
   moon. Day = the last light theme, night = the default dark one. The theme
   change itself (radial wipe from the click) is theme-toggle.js. */
.sky-switch {
    --sky-w: 68px;
    --sky-h: 34px;
    --sky-thumb: 26px;
    --sky-pad: 3px;
    position: relative;
    flex: none;
    display: flex;
    align-items: center;
    width: var(--sky-w);
    height: var(--sky-h);
    padding: 0;
    border: 1px solid rgba(255, 255, 255, .4);
    border-radius: 999px;
    background: rgba(255, 255, 255, .25);
    -webkit-backdrop-filter: blur(24px) saturate(180%);
    backdrop-filter: blur(24px) saturate(180%);
    box-shadow: 0 6px 20px rgba(0, 0, 0, .1), inset 0 2px 4px rgba(255, 255, 255, .6);
    cursor: pointer;
    transition: background .5s cubic-bezier(.25, .8, .25, 1), border-color .5s ease, box-shadow .5s ease;
}
.sky-switch:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.sky-track-icons {
    display: flex;
    justify-content: space-between;
    width: 100%;
    padding: 0 9px;
    opacity: .5;
    pointer-events: none;
}
.sky-track-icons svg {
    width: 14px;
    height: 14px;
    color: var(--text);
}
.sky-thumb {
    position: absolute;
    top: 50%;
    left: var(--sky-pad);
    display: grid;
    place-items: center;
    width: var(--sky-thumb);
    height: var(--sky-thumb);
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 3px 10px rgba(0, 0, 0, .2), inset 0 -2px 4px rgba(0, 0, 0, .1);
    transform: translateY(-50%);
    transition: transform .6s cubic-bezier(.34, 1.56, .64, 1), background .5s ease, box-shadow .5s ease;
    z-index: 2;
}
.sky-thumb svg {
    grid-area: 1 / 1;
    width: 15px;
    height: 15px;
    transition: opacity .4s ease, transform .4s ease;
}
.sky-icon-sun { color: #fbbf24; }
.sky-icon-moon { color: #a5b4fc; opacity: 0; transform: scale(.5) rotate(-90deg); }
/* Night */
.sky-switch.is-night {
    border-color: rgba(255, 255, 255, .15);
    background: rgba(0, 0, 0, .35);
    box-shadow: 0 6px 20px rgba(0, 0, 0, .6), inset 0 2px 4px rgba(255, 255, 255, .2);
}
.sky-switch.is-night .sky-thumb {
    background: #1a1a2e;
    box-shadow: 0 3px 10px rgba(0, 0, 0, .5), inset 0 2px 4px rgba(255, 255, 255, .1);
    transform: translate(calc(var(--sky-w) - var(--sky-thumb) - var(--sky-pad) * 2 - 2px), -50%);
}
.sky-switch.is-night .sky-icon-sun { opacity: 0; transform: scale(.5) rotate(90deg); }
.sky-switch.is-night .sky-icon-moon { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
    .sky-switch *, .sky-switch { transition: none !important; }
}

@keyframes theme-toggle-radius {
    0% {
        opacity: 0;
        transform: scale(0.5);
    }

    45% {
        opacity: 1;
    }

    100% {
        opacity: 0;
        transform: scale(1.4);
    }

}

::view-transition-old(root),
::view-transition-new(root) {
    animation: none;
    mix-blend-mode: normal;
}

.theme-view-transition::view-transition-old(root) {
    z-index: 1;
}

.theme-view-transition::view-transition-new(root) {
    z-index: 2;
}

.theme-wipe {
    pointer-events: none;
    position: fixed;
    left: var(--theme-wipe-x);
    top: var(--theme-wipe-y);
    z-index: 9999;
    width: var(--theme-wipe-size);
    height: var(--theme-wipe-size);
    border-radius: 50%;
    background: var(--theme-wipe-color);
    transform: translate(-50%, -50%) scale(0);
    opacity: 0.22;
    animation: theme-wipe-grow 650ms cubic-bezier(.22, 1, .36, 1) forwards;
}

.theme-wipe-red {
    background: #dc2626;
}

.theme-wipe-default {
    background: var(--brand, #0062ff);
}

.theme-wipe-mono {
    background: #111111;
}

.theme-wipe-dyno {
    background: #ff2442;
}

.theme-wipe-super {
    background: #ff3950;
}

.theme-wipe-dusk {
    background: #9b7bff;
}

.theme-wipe.is-done {
    opacity: 0;
    transition: opacity 220ms ease;
}

@keyframes theme-wipe-grow {
    to {
        transform: translate(-50%, -50%) scale(1);
    }

}

html[data-theme="red"] .topbar,
html[data-theme="red"] .app-sidebar,
html[data-theme="red"] .app-rightbar,
html[data-theme="mono"] .topbar,
html[data-theme="mono"] .app-sidebar,
html[data-theme="mono"] .app-rightbar {
    background: rgba(var(--surface-rgb), 0.78);
}

html[data-theme="red"] .brand-logo-mark,
html[data-theme="red"] .brand-preview-logo,
html[data-theme="mono"] .brand-logo-mark,
html[data-theme="mono"] .brand-preview-logo {
    background: var(--theme-white);
    border-color: rgba(127, 29, 29, 0.14);
}

html[data-theme="red"] .resource-provider,
html[data-theme="red"] .home-hosting-provider,
html[data-theme="red"] .home-eyebrow,
html[data-theme="red"] .home-limited-kicker,
html[data-theme="mono"] .resource-provider,
html[data-theme="mono"] .home-hosting-provider,
html[data-theme="mono"] .home-eyebrow,
html[data-theme="mono"] .home-limited-kicker {
    background: rgba(var(--surface-rgb), 0.78);
}

html[data-theme="mono"] .brand-logo-mark,
html[data-theme="mono"] .brand-preview-logo {
    background: var(--theme-white);
    border-color: rgba(17, 17, 17, 0.14);
}

.dashboard-dialog-icon,
.auto-currency-icon {
    color: var(--blue);
    background: linear-gradient(135deg, rgba(var(--blue-rgb), 0.12), rgba(var(--violet-rgb), 0.18));
}

@media (hover: hover) and (pointer: fine) {
.emoji-input-button:hover,
.channel-combo-toggle:hover {
    border-color: rgba(var(--blue-rgb), 0.34);
    color: var(--blue);
}
}

@media (hover: hover) and (pointer: fine) {
.auto-currency-toggle:hover {
    border-color: rgba(var(--blue-rgb), 0.32);
}
}

.auto-currency-toggle input {
    accent-color: var(--blue);
}

.ticket-line.claimed {
    stroke: var(--violet);
}

.ticket-chart-legend .claimed {
    background: var(--violet);
}

/* Softer dashboard controls: compact rectangle buttons, not circles. */
.dashboard-root .btn {
    padding: 0.48rem 0.82rem;
    line-height: 1;
    box-shadow: none;
}

@media (hover: hover) and (pointer: fine) {
.dashboard-root .btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 8px 18px rgba(var(--blue-rgb), 0.12);
}
}

.dashboard-root .btn-secondary {
    background: rgba(var(--surface-rgb), 0.58);
    border-color: rgba(18, 24, 38, 0.12);
    color: var(--text);
}

@media (hover: hover) and (pointer: fine) {
.dashboard-root .btn-secondary:hover {
    background: rgba(var(--surface-rgb), 0.82);
}
}

.dashboard-root .btn-primary {
    border-color: transparent;
}

/* ---- Homepage motion graphics (ambient orbs, sheen, glow) ---- */

.home-hero {
    position: relative;
    overflow: hidden;
}

/* Drifting blooms on top of the aurora mesh: wider and softer than the mesh itself,
   so the hero keeps moving without reading as two separate layers. */
.home-hero::before,
.home-hero::after {
    content: "";
    position: absolute;
    width: clamp(420px, 58vw, 760px);
    height: clamp(420px, 58vw, 760px);
    border-radius: 50%;
    filter: blur(130px);
    pointer-events: none;
    z-index: 0;
}

.home-hero::before {
    top: -180px;
    left: -160px;
    background: radial-gradient(circle, rgba(var(--blue-rgb), 0.3), transparent 66%);
    animation: home-orb-drift 22s ease-in-out infinite alternate;
}

.home-hero::after {
    right: -160px;
    bottom: -200px;
    background: radial-gradient(circle, rgba(var(--violet-rgb), 0.28), transparent 66%);
    animation: home-orb-drift 28s ease-in-out infinite alternate-reverse;
}

.home-hero-inner {
    position: relative;
    z-index: 1;
}

@keyframes home-orb-drift {
    from {
        transform: translate3d(0, 0, 0) scale(1);
    }

    to {
        transform: translate3d(90px, 60px, 0) scale(1.18);
    }

}

@keyframes home-dot-pulse {
    0%,
    100% {
        box-shadow: 0 0 0 4px rgba(var(--blue-rgb), 0.16);
    }

    50% {
        box-shadow: 0 0 0 10px rgba(var(--blue-rgb), 0.04);
    }

}

@keyframes home-preview-glow {
    0%,
    100% {
        background-position: 0% 50%;
        opacity: 0.3;
    }

    50% {
        background-position: 100% 50%;
        opacity: 0.55;
    }

}

.home-actions .btn-primary {
    position: relative;
    overflow: hidden;
}

.home-actions .btn-primary::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: -60%;
    width: 40%;
    background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.38), transparent);
    transform: skewX(-18deg);
    pointer-events: none;
    display: none;
}

@keyframes home-cta-sheen {
    0% {
        left: -60%;
    }

    55%,
    100% {
        left: 130%;
    }

}

.site-list-page,
.tool-page,
.article-page {
    padding-top: clamp(36px, 5vw, 64px);
}

.site-list-title {
    font-size: clamp(30px, 4.6vw, 46px);
    font-weight: 950;
    line-height: 1.08;
    color: var(--text);
}

a.article-card[hidden] { display: none; }
a.article-card {
    display: block;
    color: inherit;
    text-decoration: none;
}

.article-card-tag {
    display: inline-block;
    margin: 10px 0 2px;
    padding: 3px 9px;
    border: 1px solid rgba(var(--blue-rgb), 0.28);
    border-radius: 999px;
    color: var(--blue);
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 10px;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.article-card-meta {
    display: block;
    margin-top: 12px;
    color: var(--muted);
    font-size: 12px;
    font-weight: 700;
}

.site-list-cta {
    margin-top: 34px;
    color: var(--muted);
    text-align: center;
}

.site-list-cta a {
    color: var(--blue);
    font-weight: 800;
}

.article-breadcrumb {
    margin-bottom: 18px;
}

.article-breadcrumb a {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    color: var(--muted);
    font-size: 13px;
    font-weight: 800;
}

@media (hover: hover) and (pointer: fine) {
.article-breadcrumb a:hover {
    color: var(--text);
}
}

.article-page {
    width: min(820px, calc(100% - 44px));
}

.article-header h1 {
    margin: 10px 0 12px;
    font-size: clamp(28px, 4.4vw, 44px);
    font-weight: 950;
    line-height: 1.12;
    color: var(--text);
}

.article-body {
    margin-top: 26px;
    color: var(--text);
    font-size: 17px;
    line-height: 1.75;
}

.article-body h2 {
    margin: 34px 0 12px;
    font-size: clamp(20px, 2.6vw, 26px);
    font-weight: 900;
    line-height: 1.25;
}

.article-body p {
    margin: 0 0 16px;
}

.article-body ul {
    margin: 0 0 16px;
    padding-left: 22px;
    display: grid;
    gap: 8px;
    list-style: disc;
}

.article-body ol {
    margin: 0 0 16px;
    padding-left: 22px;
    display: grid;
    gap: 8px;
    list-style: decimal;
}

.article-body h3 {
    margin: 22px 0 6px;
    font-size: 18px;
    font-weight: 800;
    line-height: 1.35;
}

/* Scrolls inside itself on a phone instead of widening the page. */
.article-body table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
    margin: 0 0 16px;
    border-collapse: collapse;
    font-size: 15px;
    line-height: 1.5;
}

.article-body th,
.article-body td {
    padding: 8px 12px;
    border-bottom: 1px solid var(--line);
    text-align: left;
    vertical-align: top;
}

.article-body th {
    font-weight: 800;
    white-space: nowrap;
}

.article-body a {
    color: var(--blue);
    font-weight: 700;
    text-decoration: underline;
    text-decoration-color: rgba(var(--blue-rgb), 0.35);
}

.article-cta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-top: 40px;
    padding: 22px;
    border: 1px solid rgba(var(--blue-rgb), 0.22);
    border-radius: var(--radius-lg);
    background: var(--soft-card-gradient, rgba(var(--blue-rgb), 0.06));
}

.article-cta strong {
    display: block;
    font-size: 17px;
    font-weight: 900;
    color: var(--text);
}

.article-cta p {
    margin: 4px 0 0;
    color: var(--muted);
    font-size: 14px;
}

.article-related {
    margin-top: 48px;
}

.article-related h2 {
    margin-bottom: 18px;
    font-size: 22px;
    font-weight: 900;
    color: var(--text);
}





/* Tool pages */

.tool-page {
    width: min(880px, calc(100% - 44px));
}

.tool-panel {
    margin-top: 26px;
    padding: clamp(18px, 3vw, 28px);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface);
}

.tool-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 14px;
}

.tool-controls > div {
    flex: 1 1 240px;
}

.tool-two-col {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
    gap: 24px;
}

@media (max-width: 760px) {
    .tool-two-col {
        grid-template-columns: 1fr;
    }

}

.tool-controls-stack {
    display: grid;
    gap: 14px;
    align-content: start;
}

.tool-results {
    display: grid;
    gap: 8px;
    margin-top: 20px;
}

.tool-result-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-md);
    background: var(--panel);
    color: var(--text);
    text-align: left;
    cursor: pointer;
    font: inherit;
}

@media (hover: hover) and (pointer: fine) {
.tool-result-row:hover {
    border-color: rgba(var(--blue-rgb), 0.35);
}
}

.tool-result-name {
    flex: 0 0 130px;
    color: var(--muted);
    font-size: 12px;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.tool-result-row code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 13px;
    color: var(--blue);
}

.tool-result-preview {
    flex: 1 1 auto;
    min-width: 140px;
    font-size: 15px;
}

.tool-font-preview {
    font-size: 18px;
}

.tool-copy-label {
    margin-left: auto;
    color: var(--muted);
    font-size: 12px;
    font-weight: 800;
}

.tool-result-row:hover .tool-copy-label {
    color: var(--blue);
}

.tool-output {
    min-height: 120px;
    padding: 16px;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-md);
    background: var(--panel);
    color: var(--text);
    font-size: 15px;
    line-height: 1.6;
    white-space: pre-wrap;
    word-break: break-word;
}

.tool-copy-btn {
    margin-top: 12px;
}

.tool-hint {
    margin-top: 16px;
    color: var(--muted);
    font-size: 13px;
}

/* ---- Tool components (v2 tools) ---- */

.perm-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 8px;
    margin-top: 20px;
}

.perm-item {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 9px 12px;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-md);
    background: var(--panel);
    color: var(--text);
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
.perm-item:hover {
    border-color: rgba(var(--blue-rgb), 0.35);
}
}

.tool-output-rows {
    display: grid;
    gap: 8px;
    margin-top: 20px;
}

.tool-code-wrap {
    word-break: break-all;
    flex: 1 1 200px;
}

.tool-result-row.is-static {
    cursor: default;
}

.color-input {
    width: 100%;
    height: 46px;
    padding: 4px;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-md);
    background: var(--panel);
    cursor: pointer;
}

.color-swatches {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.color-swatch {
    width: 30px;
    height: 30px;
    border: 1px solid rgba(0, 0, 0, 0.15);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: transform 140ms ease;
}

@media (hover: hover) and (pointer: fine) {
.color-swatch:hover {
    transform: scale(1.12);
}
}

.embed-preview {
    padding: 18px;
    border-radius: 12px;
    background: #313338;
}

.embed-preview-inner {
    border-left: 4px solid #dc2626;
    border-radius: 4px;
    background: #2b2d31;
    padding: 12px 14px;
    color: #dbdee1;
}

.embed-preview-inner strong {
    display: block;
    color: #f2f3f5;
    margin-bottom: 6px;
}

.embed-preview-inner p {
    margin: 0;
    font-size: 14px;
    line-height: 1.5;
}

.md-textarea {
    min-height: 320px;
    resize: vertical;
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 13px;
    line-height: 1.6;
}

.md-preview {
    min-height: 320px;
    padding: 16px;
    border-radius: var(--radius-md);
    background: #313338;
    color: #dbdee1;
    font-size: 15px;
    line-height: 1.55;
    word-break: break-word;
}

.md-preview h2,
.md-preview h3,
.md-preview h4 {
    margin: 10px 0 6px;
    color: #f2f3f5;
    font-weight: 800;
}

.md-preview h2 { font-size: 22px; }
.md-preview h3 { font-size: 18px; }
.md-preview h4 { font-size: 15px; }

.md-preview blockquote {
    margin: 4px 0;
    padding-left: 10px;
    border-left: 4px solid #4e5058;
    color: #b5bac1;
}

.md-preview code {
    padding: 2px 5px;
    border-radius: var(--radius-sm);
    background: #1e1f22;
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 13px;
}

.md-codeblock {
    margin: 6px 0;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    background: #1e1f22;
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 13px;
    white-space: pre-wrap;
}

.md-subtext {
    color: #949ba4;
    font-size: 12px;
}

.md-li {
    padding-left: 8px;
}

.md-spoiler {
    padding: 0 4px;
    border-radius: var(--radius-sm);
    background: #1e1f22;
    color: transparent;
    cursor: pointer;
}

.md-spoiler.is-open {
    color: inherit;
    background: rgba(30, 31, 34, 0.6);
}

.role-preview {
    margin-bottom: 14px;
    padding: 16px;
    border-radius: var(--radius-md);
}

.role-preview-dark {
    background: #313338;
}

.role-preview-light {
    background: #ffffff;
    border: 1px solid rgba(0, 0, 0, 0.08);
}

.role-preview-label {
    display: block;
    margin-bottom: 8px;
    font-size: 11px;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #949ba4;
}

.role-preview-chat {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 8px;
}

.role-preview-name {
    font-weight: 800;
}

.role-preview-dark .role-preview-msg {
    color: #dbdee1;
}

.role-preview-light .role-preview-msg {
    color: #313338;
}

.emoji-result {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 20px;
    margin-top: 20px;
}

.emoji-result.hidden {
    display: none;
}

.emoji-preview-wrap {
    display: grid;
    gap: 8px;
    justify-items: center;
}

.emoji-canvas {
    width: 128px;
    height: 128px;
    border: 1px dashed var(--line);
    border-radius: var(--radius-md);
    background:
        repeating-conic-gradient(rgba(127, 127, 127, 0.14) 0% 25%, transparent 0% 50%) 0 0 / 16px 16px;
}

.tool-output-tall {
    min-height: 280px;
}

.name-grid {
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}

/* ============================================================
   ANIMATED BUTTON SYSTEM (v2 redesign)
   Pill-shaped, spring hover lift, shine sweep, ripple + glow.
   Declared last so it wins over the earlier .btn rules.
   ============================================================ */

.btn {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    padding: 0.6rem 1.25rem;
    letter-spacing: 0.01em;
    will-change: transform;
    transition:
        transform 140ms cubic-bezier(.23, 1, .32, 1),
        background 200ms ease,
        color 200ms ease,
        border-color 200ms ease,
        box-shadow 260ms ease,
        filter 200ms ease;
}

/* Glare removed: no light band on buttons. */
.btn::after { display: none; }
@media (hover: hover) and (pointer: fine) {
.btn:hover {
    transform: translateY(-2px) scale(1.02);
    box-shadow: 0 10px 28px rgba(var(--blue-rgb, 0, 98, 255), 0.28);
}
}

.btn:active,
.icon-btn:active {
    transform: scale(0.97);
    transition-duration: 140ms;
}

/* Two button sizes: 40px everywhere (base .btn), 48px for the main calls to action. */
.home-hero .home-actions .btn,
.home-cta .btn {
    min-height: 48px;
    padding-inline: 1.35rem;
}

.btn:focus-visible {
    outline: none;
    box-shadow:
        0 0 0 2px var(--surface, #0b0c12),
        0 0 0 4px rgba(var(--blue-rgb, 0, 98, 255), 0.65);
}

/* Primary - animated gradient that drifts on hover + breathing glow */
.btn-primary {
    background: linear-gradient(135deg, var(--blue), var(--violet), var(--blue));
    background-size: 220% 220%;
    background-position: 0% 50%;
    border: none;
    animation: btnGradientIdle 6s ease-in-out infinite;
}

@media (hover: hover) and (pointer: fine) {
.btn-primary:hover {
    background-position: 100% 50%;
    animation-play-state: paused;
    box-shadow:
        0 10px 30px rgba(var(--blue-rgb, 0, 98, 255), 0.4),
        0 0 0 1px rgba(255, 255, 255, 0.08) inset;
}
}

@keyframes btnGradientIdle {
    0%, 100% { background-position: 0% 50%; }
    50% { background-position: 60% 50%; }

}

@media (hover: hover) and (pointer: fine) {
.btn-secondary:hover {
    border-color: rgba(var(--blue-rgb, 0, 98, 255), 0.5);
    box-shadow: 0 8px 22px rgba(var(--blue-rgb, 0, 98, 255), 0.16);
}
}

@media (hover: hover) and (pointer: fine) {
.btn-danger:hover,
.btn-bad:hover {
    border-color: rgba(239, 68, 68, 0.6);
    box-shadow: 0 8px 22px rgba(239, 68, 68, 0.24);
}
}

/* Icons inside buttons nudge with the hover */
.btn svg,
.btn i {
    transition: transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

.btn:hover svg,
.btn:hover i {
    transform: scale(1.12) rotate(-3deg);
}

/* Click ripple (span injected by ui-effects.js) */
.btn-ripple {
    position: absolute;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.35);
    transform: scale(0);
    animation: btnRipple 550ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
    pointer-events: none;
    z-index: -1;
}

@keyframes btnRipple {
    to { transform: scale(2.6); opacity: 0; }

}

.btn-disabled,
.btn:disabled {
    animation: none;
}

@media (hover: hover) and (pointer: fine) {
.btn-disabled:hover,
.btn:disabled:hover {
    transform: none;
    box-shadow: none;
}
}

.btn-disabled::after,
.btn:disabled::after {
    display: none;
}

.icon-btn {
    border-radius: 999px;
    transition:
        transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1),
        background 200ms ease,
        color 200ms ease,
        border-color 200ms ease,
        box-shadow 260ms ease;
}

@media (hover: hover) and (pointer: fine) {
.icon-btn:hover {
    transform: translateY(-1px) scale(1.08);
}
}

@media (prefers-reduced-motion: reduce) {
    .btn,
    .btn-primary,
    .icon-btn,
    .btn svg,
    .btn i {
        animation: none !important;
        transition-duration: 1ms !important;
    }
    @media (hover: hover) and (pointer: fine) {
.btn:hover,
.icon-btn:hover {
        transform: none;
    }
}
    .btn::after {
        display: none;
    }
    .btn-ripple {
        display: none;
    }

}

/* ============================================================
   DASHBOARD UX UPGRADES
   Collapsible nav groups, guild switcher, command palette,
   sparkline widget, module state labels, empty states.
   ============================================================ */

/* Collapsible sidebar sections */
.nav-group-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    background: transparent;
    border: none;
    cursor: pointer;
    color: inherit;
    font: inherit;
    text-transform: inherit;
    letter-spacing: inherit;
}
.nav-group-chevron {
    transition: transform 240ms cubic-bezier(0.22, 1, 0.36, 1);
    opacity: 0.6;
}
.nav-group.collapsed .nav-group-chevron {
    transform: rotate(-90deg);
}
.nav-group-links {
    display: grid;
    grid-template-rows: 1fr;
    transition: grid-template-rows 280ms cubic-bezier(0.22, 1, 0.36, 1);
}
.nav-group-links-inner {
    /* Clipping is only needed while the group animates shut. Leaving it on an
       open group cuts the last link and swallows focus rings. */
    overflow: visible;
    min-width: 0;
}
.nav-group.collapsed .nav-group-links-inner {
    overflow: hidden;
    /* Closed groups leave the tab order once the close animation ends. */
    visibility: hidden;
    transition: visibility 0s 280ms;
}
.nav-group.is-off { opacity: .62; }
.nav-group.is-off:focus-within,
.nav-group.is-off.has-active { opacity: 1; }
@media (hover: hover) and (pointer: fine) {
.nav-group.is-off:hover { opacity: 1; }
}
.nav-off-head { margin-top: .75rem; }
.nav-group.collapsed .nav-group-links {
    grid-template-rows: 0fr;
}

.nav-support-email {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.45rem 0.75rem;
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--muted);
    transition: color 160ms ease;
}
@media (hover: hover) and (pointer: fine) {
.nav-support-email:hover { color: var(--text); }
}

/* Guild switcher */
.guild-switcher { position: relative; }
.guild-switcher-btn {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    max-width: 220px;
    padding: 0.35rem 0.6rem;
    border-radius: var(--radius-md);
    border: 1px solid var(--line);
    background: transparent;
    color: var(--text);
    font-weight: 700;
    font-size: 0.85rem;
    cursor: pointer;
    transition: border-color 160ms ease, background 160ms ease, transform 160ms ease;
}
@media (hover: hover) and (pointer: fine) {
.guild-switcher-btn:hover {
    border-color: rgba(var(--blue-rgb, 0, 98, 255), 0.5);
    background: rgba(var(--blue-rgb, 0, 98, 255), 0.06);
}
}
.guild-switcher-btn img,
.guild-switcher-fallback {
    height: 1.5rem;
    width: 1.5rem;
    border-radius: var(--radius-sm);
    flex-shrink: 0;
}
.guild-switcher-fallback {
    display: grid;
    place-items: center;
    background: rgba(var(--blue-rgb, 0, 98, 255), 0.2);
    font-size: 0.62rem;
    font-weight: 800;
}
.guild-switcher-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.guild-switcher-menu {
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    z-index: 80;
    min-width: 240px;
    max-height: 60vh;
    overflow-y: auto;
    padding: 0.4rem;
    border-radius: var(--radius-lg);
    border: 1px solid var(--line);
    background: var(--surface, #12131a);
    box-shadow: 0 18px 44px rgba(0, 0, 0, 0.4);
    animation: switcherIn 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes switcherIn {
    from { opacity: 0; transform: translateY(-6px) scale(0.98); }
    to { opacity: 1; transform: translateY(0) scale(1); }

}
.guild-switcher-label {
    padding: 0.4rem 0.6rem 0.3rem;
    font-size: 0.65rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--muted);
}
.guild-switcher-item {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.45rem 0.6rem;
    border-radius: var(--radius-md);
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text);
    transition: background 140ms ease;
}
@media (hover: hover) and (pointer: fine) {
.guild-switcher-item:hover { background: rgba(var(--blue-rgb, 0, 98, 255), 0.1); }
}
.guild-switcher-item.is-current {
    background: rgba(var(--blue-rgb, 0, 98, 255), 0.12);
    font-weight: 800;
}
.guild-switcher-item img { height: 1.5rem; width: 1.5rem; border-radius: var(--radius-sm); }
.guild-switcher-item .truncate { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.guild-switcher-all {
    border-top: 1px solid var(--line);
    margin-top: 0.3rem;
    padding-top: 0.55rem;
    color: var(--muted);
}
#topbarSearch { cursor: pointer; }
#topbarSearch input { cursor: pointer; }

/* Command palette */
.cmd-palette-backdrop {
    position: fixed;
    inset: 0;
    z-index: 95;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding-top: 14vh;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(4px);
}
.cmd-palette-backdrop[hidden] { display: none; }
.cmd-palette {
    width: min(560px, calc(100vw - 2rem));
    border-radius: var(--radius-lg);
    border: 1px solid var(--line);
    background: var(--surface, #12131a);
    box-shadow: 0 24px 70px rgba(0, 0, 0, 0.5);
    overflow: hidden;
    animation: switcherIn 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}
.cmd-palette-input {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.85rem 1rem;
    border-bottom: 1px solid var(--line);
}
.cmd-palette-input input {
    flex: 1;
    background: transparent;
    border: none;
    outline: none;
    color: var(--text);
    font-size: 0.95rem;
    font-weight: 600;
}
.cmd-palette-input kbd {
    font-size: 0.65rem;
    font-weight: 700;
    color: var(--muted);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: 0.15rem 0.4rem;
}
.cmd-palette-list {
    max-height: 46vh;
    overflow-y: auto;
    padding: 0.4rem;
}
.cmd-palette-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.55rem 0.7rem;
    border-radius: var(--radius-md);
    color: var(--text);
    font-size: 0.88rem;
    font-weight: 600;
}
.cmd-palette-item.is-selected {
    background: rgba(var(--blue-rgb, 0, 98, 255), 0.14);
}
.cmd-palette-item-section {
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
}
.cmd-palette-empty {
    padding: 1.4rem;
    text-align: center;
    color: var(--muted);
    font-weight: 600;
    font-size: 0.85rem;
}

/* Empty states with CTAs */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.45rem;
    padding: 2.2rem 1rem;
    text-align: center;
    border: 1px dashed var(--line);
    border-radius: var(--radius-lg);
}
.empty-state > i,
.empty-state > svg {
    opacity: 0.35;
    margin-bottom: 0.2rem;
}

/* Overview compact stat cards + quick actions */
.overview-stat-card {
    transition: transform 200ms cubic-bezier(0.34, 1.56, 0.64, 1), border-color 180ms ease, box-shadow 220ms ease;
}
@media (hover: hover) and (pointer: fine) {
.overview-stat-card:hover {
    border-color: rgba(var(--blue-rgb, 0, 98, 255), 0.4);
}
}

@media (max-width: 900px) {
    .guild-switcher-name { display: none; }
    .guild-switcher-btn { max-width: none; }

}

@media (prefers-reduced-motion: reduce) {
    .nav-group-links, .nav-group-chevron, .guild-switcher-menu, .cmd-palette, .overview-stat-card { transition: none; animation: none; }
    @media (hover: hover) and (pointer: fine) {
.overview-stat-card:hover { transform: none; }
}

}

/* Sidebar group icons + hosting block + topbar report */
.nav-group-title {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}
.nav-group-icon {
    color: currentColor;
    opacity: 0.75;
    flex-shrink: 0;
}
.nav-hosting-provider {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    margin: 0.25rem 0.35rem 0.5rem;
    padding: 0.55rem 0.75rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--muted);
    transition: border-color 160ms ease, color 160ms ease;
}
@media (hover: hover) and (pointer: fine) {
.nav-hosting-provider:hover {
    border-color: rgba(var(--blue-rgb, 0, 98, 255), 0.4);
    color: var(--text);
}
}
.nav-hosting-provider img { height: 1.1rem; }
/* Gold vote button. Deliberately theme-independent - gold is the point, and it has to
   out-rank the neutral nav buttons sitting beside it in every theme. */
.topbar-vote-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    height: 2.125rem;
    padding: 0 0.85rem 0 0.7rem;
    border-radius: 999px;
    font-size: 0.8125rem;
    line-height: 1;
    white-space: nowrap;
    text-decoration: none;
    flex: none;
    border: 1px solid #d99b1a;
    background: linear-gradient(160deg, #ffd77a, #f5b427 46%, #e09a12);
    color: #3d2704;
    font-weight: 700;
    box-shadow: 0 1px 2px rgba(120, 78, 5, 0.24), 0 0 0 3px rgba(245, 180, 39, 0.14);
}
@media (hover: hover) and (pointer: fine) {
.topbar-vote-btn:hover {
    background: linear-gradient(160deg, #ffe098, #f8bf3c 46%, #e8a418);
    box-shadow: 0 3px 10px rgba(120, 78, 5, 0.28), 0 0 0 4px rgba(245, 180, 39, 0.2);
    color: #3d2704;
}
}
.topbar-vote-btn svg { color: #6b4405; }
.topbar-more-panel,
.topbar-more-panel > * {
    flex: none;
}
/* The <details> wrapper too, not just what is inside it. It was the one thing
   still allowed to shrink, so on a crowded logged-out header it collapsed to
   less than its panel needed and the panel drew straight over the site nav -
   the language picker and theme toggle landing on top of "Features" and
   "Articles". A container narrower than its own contents is the overlap. */
.topbar-more {
    flex: none;
}
/* Every button in the header is a label on one line. "Add Bot" and "Login with
   Discord" were breaking mid-phrase and dragging the whole bar taller. */
.topbar .btn {
    white-space: nowrap;
    flex: none;
}

/* Hover polish: no icon wobble inside buttons, stable active nav link */
.btn:hover svg,
.btn:hover i {
    transform: none;
}
.nav-link,
.nav-link-active {
    transition: background 160ms ease, color 160ms ease, box-shadow 160ms ease;
}
@media (hover: hover) and (pointer: fine) {
.nav-link:hover {
    transform: none;
}
}

/* Vote: keeps the gold shadow instead of the blue one, and the star spins rather
   than tilting; it is the odd one out on purpose. */
@media (hover: hover) and (pointer: fine) {
.topbar-vote-btn.topbar-vote-btn:hover {
    border-color: #c98a10;
    box-shadow: 0 6px 16px rgba(120, 78, 5, 0.32), 0 0 0 4px rgba(245, 180, 39, 0.22);
}
}
.topbar-vote-btn.topbar-vote-btn:hover svg {
    transform: scale(1.18) rotate(72deg);
}

@keyframes mg-deal-in {
    from { opacity: 0; transform: translateY(-10px) scale(0.94); }
    to { opacity: 1; transform: none; }

}
.topbar-vote-btn.topbar-vote-btn:hover .lucide-star {
    animation: mg-spin-pop 700ms cubic-bezier(.34, 1.56, .64, 1);
}

@keyframes mg-skitter {
    0% { transform: scale(1) rotate(0); }
    25% { transform: scale(1.16) rotate(-15deg); }
    50% { transform: scale(1.16) rotate(9deg); }
    75% { transform: scale(1.16) rotate(-11deg); }
    100% { transform: scale(1.16) rotate(-6deg); }

}
@keyframes mg-flip {
    0% { transform: perspective(120px) rotateY(0) scale(1); }
    55% { transform: perspective(120px) rotateY(180deg) scale(1.22); }
    100% { transform: perspective(120px) rotateY(360deg) scale(1.16) rotate(-6deg); }

}
@keyframes mg-turn {
    0% { transform: scale(1) rotate(0); }
    35% { transform: scale(1.16) rotate(-28deg); }
    100% { transform: scale(1.16) rotate(15deg); }

}
@keyframes mg-bob {
    0% { transform: translateY(0) rotate(0) scale(1); }
    30% { transform: translateY(-3px) rotate(14deg) scale(1.16); }
    62% { transform: translateY(2px) rotate(-9deg) scale(1.16); }
    100% { transform: translateY(0) rotate(-6deg) scale(1.16); }

}
@keyframes mg-spin-pop {
    0% { transform: rotate(0) scale(1); }
    60% { transform: rotate(300deg) scale(1.36); }
    /* 432deg lands on the same angle as the 72deg resting state, one turn later. */
    100% { transform: rotate(432deg) scale(1.18); }

}

/* Gold breathing ring, offset until after the deal-in finishes. Hover cancels it so
   the hover shadow is not fighting a running animation. */
/* Doubled so the nth-child animation-delay above cannot flatten both delays to 40ms. */
.topbar-vote-btn.topbar-vote-btn {
    animation:
        mg-deal-in 520ms cubic-bezier(.22, 1, .36, 1) 40ms backwards,
        mg-gold-pulse 3.2s ease-in-out 700ms infinite;
}
/* Only the pulse stops. `animation: none` also dropped the finished deal-in, so
   every mouse-out replayed it from opacity 0 and the button flashed dark. Keeping
   the same name in the list means the browser does not restart it. */
@media (hover: hover) and (pointer: fine) {
.topbar-vote-btn.topbar-vote-btn:hover {
    animation: mg-deal-in 520ms cubic-bezier(.22, 1, .36, 1) 40ms backwards;
}
}
@keyframes mg-tutorial-pulse {
    0%, 100% { box-shadow: 0 1px 2px rgba(120, 5, 30, 0.28), 0 0 0 3px rgba(232, 54, 93, 0.16),
                           0 0 10px rgba(232, 54, 93, 0.3); }
    50%      { box-shadow: 0 2px 8px rgba(120, 5, 30, 0.32), 0 0 0 5px rgba(232, 54, 93, 0.12),
                           0 0 22px rgba(232, 54, 93, 0.6); }

}

@keyframes mg-gold-pulse {
    0%, 100% { box-shadow: 0 1px 2px rgba(120, 78, 5, 0.24), 0 0 0 3px rgba(245, 180, 39, 0.14); }
    50% { box-shadow: 0 2px 7px rgba(120, 78, 5, 0.3), 0 0 0 7px rgba(245, 180, 39, 0.05); }

}

@media (prefers-reduced-motion: reduce) {
    .topbar-vote-btn,
    .topbar-vote-btn.topbar-vote-btn:hover .lucide-star {
        animation: none;
    }

}

/* Sticky, independently-scrolling sidebars - sidebar keeps its own scroll
   position instead of riding the page scrollbar (root fix for scroll reset). */
@media (min-width: 1024px) {
    .app-sidebar,
    .app-rightbar {
        position: sticky;
        top: 56px;
        /* dvh, so mobile browser chrome does not push the bottom of the column
           past the screen edge and hide the last few nav items. */
        height: calc(100dvh - 56px);
        align-self: start;
        overflow-y: auto;
        overscroll-behavior: contain;
    }

}

/* Profile menu (topbar avatar dropdown) */
.profile-menu { position: relative; }
.profile-menu-btn {
    border: none;
    background: transparent;
    cursor: pointer;
    font: inherit;
    color: inherit;
}
.profile-menu-chevron {
    opacity: 0.6;
    transition: transform 200ms cubic-bezier(0.22, 1, 0.36, 1);
}
.profile-menu-btn[aria-expanded="true"] .profile-menu-chevron {
    transform: rotate(180deg);
}
.profile-menu-panel {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    z-index: 85;
    width: 280px;
    padding: 0.5rem;
    border-radius: var(--radius-lg);
    border: 1px solid var(--line);
    background: var(--surface, #12131a);
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.4);
    animation: switcherIn 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}
.profile-menu-panel[hidden] { display: none; }
.profile-menu-head {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.6rem 0.7rem 0.7rem;
    border-bottom: 1px solid var(--line);
}
.profile-menu-head img {
    height: 2.6rem;
    width: 2.6rem;
    border-radius: 999px;
    flex-shrink: 0;
}
.profile-menu-rows {
    padding: 0.55rem 0.35rem;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    border-bottom: 1px solid var(--line);
}
.profile-menu-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0 0.4rem;
    font-size: 0.78rem;
}
.profile-menu-row span {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--muted);
    font-weight: 600;
}
.profile-menu-row strong { font-weight: 800; }
/* Donor plan pill in the profile menu (free users have no row). */
.profile-menu-plan { display: inline-flex; align-items: baseline; gap: 6px; padding: 2px 9px; border-radius: 999px; background: color-mix(in srgb, #8b5cf6 18%, transparent); color: color-mix(in srgb, #8b5cf6 65%, var(--text)); font-weight: 800; text-decoration: none; white-space: nowrap; }
.profile-menu-plan small { color: var(--muted); font-size: 11px; font-weight: 600; }
.profile-menu-plan.is-lifetime { background: linear-gradient(135deg, color-mix(in srgb, #8b5cf6 26%, transparent), color-mix(in srgb, #ec4899 22%, transparent)); color: color-mix(in srgb, #d946ef 65%, var(--text)); }
.profile-menu-plan.is-ended { background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--muted); }
.profile-menu-plan-note { margin: -2px 0 2px; padding: 0 0 4px 22px; font-size: 12px; line-height: 1.45; color: var(--muted); }
.profile-menu-plan-note p { margin: 0; }
.profile-menu-plan-note a { display: inline-block; margin-top: 3px; color: color-mix(in srgb, #8b5cf6 65%, var(--text)); font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }
.profile-menu-plan-note a.profile-menu-plan-buy { display: inline-flex; align-items: center; gap: 6px; margin-top: 8px; padding: 6px 12px; border-radius: 999px; background: #8b5cf6; color: #fff; text-decoration: none; }

.profile-menu-actions {
    padding-top: 0.45rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}
.profile-menu-action {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.5rem 0.6rem;
    border-radius: var(--radius-md);
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--text);
    transition: background 140ms ease, color 140ms ease;
}
@media (hover: hover) and (pointer: fine) {
.profile-menu-action:hover { background: rgba(var(--blue-rgb, 0, 98, 255), 0.1); }
}
.profile-menu-logout { color: #ef4444; }
@media (hover: hover) and (pointer: fine) {
.profile-menu-logout:hover { background: rgba(239, 68, 68, 0.1); }
}

@media (prefers-reduced-motion: reduce) {
    .profile-menu-panel { animation: none; }
    .profile-menu-chevron { transition: none; }

}

/* ── Hero redesign: ticket-dashboard landing (theme-aware) ──────────────────
   Uses theme variables throughout so it follows the theme toggle. */
.nx-hero {
    position: relative;
    overflow: hidden;
    background: var(--hero-bg);
}
.nx-hero-inner { position: relative; z-index: 1; }

.nx-badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 16px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--surface);
    color: var(--blue);
    font-size: 13px;
    font-weight: 600;
    backdrop-filter: blur(8px);
}
.nx-badge i { color: var(--violet); }

.nx-title {
    margin-top: 26px;
    color: var(--text);
    font-size: clamp(40px, 7vw, 88px);
    font-weight: 800;
    line-height: 1.02;
    letter-spacing: -0.02em;
}
.nx-title-grad {
    position: relative;
    /* The rose end of the red theme is too light to read at display size on a near-white
       hero, so the far stop is pulled back toward --blue. */
    background: linear-gradient(120deg, var(--blue), color-mix(in srgb, var(--violet) 70%, var(--blue)));
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}
.nx-title-grad::after {
    content: "";
    position: absolute;
    left: 4%;
    right: 0;
    bottom: 0.02em;
    height: 0.06em;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--blue), var(--violet));
    opacity: 0.7;
}

/* Cursive accent - one word per heading, keeps the rest of the type system intact. */
.nx-cursive,
.nx-title-grad {
    font-family: var(--font-cursive);
    font-style: italic;
    font-weight: 500;
    letter-spacing: 0;
    /* ponytail: Playfair sits smaller than Inter at the same px, so nudge it back up */
    font-size: 1.08em;
}
.nx-title-grad { padding-right: 0.06em; }

.nx-subtitle {
    width: min(680px, 100%);
    margin: 24px auto 0;
    /* Grey --muted went muddy on the red hero; theme text, slightly softened. */
    color: color-mix(in srgb, var(--text) 82%, transparent);
    font-size: clamp(16px, 1.6vw, 20px);
    line-height: 1.55;
}

.nx-actions { margin-top: 34px; }
.nx-btn-primary, .nx-btn-secondary { text-decoration: none !important; }
.nx-btn-primary {
    background: linear-gradient(135deg, var(--blue), var(--violet)) !important;
    color: #fff !important;
    border: none !important;
    box-shadow: 0 12px 34px rgba(var(--violet-rgb), 0.32) !important;
}
@media (hover: hover) and (pointer: fine) {
.nx-btn-primary:hover { transform: translateY(-1px); }
}
.nx-btn-secondary {
    border: 1px solid var(--line) !important;
    background: var(--surface) !important;
    color: var(--text) !important;
    backdrop-filter: blur(8px);
}
@media (hover: hover) and (pointer: fine) {
.nx-btn-secondary:hover { border-color: rgba(var(--blue-rgb), 0.4) !important; }
}

.nx-chips {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;
    margin-top: 26px;
}
.nx-chips span {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 16px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--surface);
    color: var(--muted);
    font-size: 13px;
    font-weight: 600;
}
.nx-chips i { color: var(--blue); }

/* Dashboard mockup */
.nx-dash {
    display: grid;
    grid-template-columns: 208px minmax(0, 1fr);
    gap: 0;
    width: min(1040px, 100%);
    margin: 56px auto 0;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--surface);
    box-shadow: 0 30px 90px rgba(var(--violet-rgb), 0.14);
    text-align: left;
}
.nx-dash-side {
    padding: 20px 14px;
    background: var(--surface-2);
    border-right: 1px solid var(--line);
}
.nx-dash-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 8px 18px;
}
.nx-dash-logo {
    width: 30px; height: 30px;
    border-radius: var(--radius-md);
    overflow: hidden;
    display: grid; place-items: center;
    background: linear-gradient(135deg, var(--blue), var(--violet));
}
.nx-dash-logo img { width: 100%; height: 100%; object-fit: cover; }
.nx-dash-brand strong { color: var(--text); font-size: 17px; font-weight: 800; }
.nx-dash-nav { display: grid; gap: 3px; }
.nx-dash-nav span {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 11px;
    border-radius: var(--radius-md);
    color: var(--muted);
    font-size: 13px;
    font-weight: 600;
}
.nx-dash-nav span i { width: 16px; height: 16px; }
.nx-dash-nav .is-active {
    background: rgba(var(--blue-rgb), 0.12);
    color: var(--text);
}
.nx-dash-nav .is-active i { color: var(--blue); }

.nx-dash-main { padding: 22px; min-width: 0; }
.nx-dash-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 18px;
}
.nx-dash-head h3 { color: var(--text); font-size: 20px; font-weight: 800; }
.nx-dash-head p { color: var(--muted); font-size: 13px; margin-top: 4px; }
.nx-dash-range {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    flex: 0 0 auto;
    padding: 7px 13px;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--muted);
    font-size: 12px;
    font-weight: 600;
}

.nx-dash-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 12px;
    margin-bottom: 16px;
}
.nx-dash-stats div {
    padding: 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--surface);
}
.nx-dash-stats span { color: var(--muted); font-size: 12px; }
.nx-dash-stats strong {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-top: 8px;
    color: var(--text);
    font-size: 22px;
    font-weight: 800;
}
.nx-dash-stats em { font-size: 11px; font-weight: 700; font-style: normal; }
.nx-dash-stats em.up { color: var(--green); }
.nx-dash-stats em.down { color: var(--red); }

.nx-dash-charts {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    gap: 12px;
}
.nx-dash-card {
    padding: 16px;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--surface);
}
.nx-dash-card > strong { display: block; color: var(--text); font-size: 14px; font-weight: 700; margin-bottom: 12px; }
.nx-area { color: var(--violet); }
.nx-area svg { width: 100%; height: 120px; display: block; }

.nx-tags { display: flex; align-items: center; gap: 16px; }
.nx-donut {
    position: relative;
    width: 108px; height: 108px;
    flex: 0 0 auto;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: conic-gradient(
        var(--violet) 0 48%,
        color-mix(in srgb, var(--violet) 68%, #fff) 48% 72%,
        color-mix(in srgb, var(--violet) 42%, #fff) 72% 87%,
        color-mix(in srgb, var(--violet) 16%, #fff) 87% 100%);
}
.nx-donut::after {
    content: "";
    position: absolute;
    inset: 26px;
    border-radius: 50%;
    background: var(--surface);
}
.nx-donut span { position: relative; z-index: 1; color: var(--text); font-size: 17px; font-weight: 800; }
.nx-legend { display: grid; gap: 9px; min-width: 0; }
.nx-legend li {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--muted);
    font-size: 12px;
    list-style: none;
}
.nx-legend li i { width: 10px; height: 10px; border-radius: var(--radius-sm); flex: 0 0 auto; }
.nx-legend li:nth-child(1) i { background: var(--violet); }
.nx-legend li:nth-child(2) i { background: color-mix(in srgb, var(--violet) 68%, #fff); }
.nx-legend li:nth-child(3) i { background: color-mix(in srgb, var(--violet) 42%, #fff); }
.nx-legend li:nth-child(4) i { background: color-mix(in srgb, var(--violet) 16%, #fff); }
.nx-legend li b { margin-left: auto; color: var(--text); }

/* Kept blocks already use theme vars via .home-limited / .home-hosting-provider */

@media (max-width: 860px) {
    .nx-dash { grid-template-columns: 1fr; }
    .nx-dash-side {
        display: flex;
        gap: 6px;
        overflow-x: auto;
        border-right: none;
        border-bottom: 1px solid var(--line);
    }
    /* Swipeable tab strip: no scrollbar, a fade on the right says "more". */
    .nx-dash-side { scrollbar-width: none; -webkit-mask-image: linear-gradient(90deg, #000 88%, transparent); mask-image: linear-gradient(90deg, #000 88%, transparent); }
    .nx-dash-side::-webkit-scrollbar { display: none; }
    .nx-dash-brand { display: none; }
    .nx-dash-nav { grid-auto-flow: column; gap: 6px; }
    .nx-dash-nav span { white-space: nowrap; }
    .nx-dash-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .nx-dash-charts { grid-template-columns: 1fr; }

}
@media (max-width: 520px) {
    .nx-tags { flex-direction: column; align-items: flex-start; }

}

/* ── Hero motion: dashboard entrance + "Business." treatment ────────────────
   All motion gated behind no-preference so reduced-motion users see final state. */
@media (prefers-reduced-motion: no-preference) {
    /* Armed initial states (only when JS added .nx-anim) */
    .nx-dash.nx-anim .nx-dash-stats div,
    .nx-dash.nx-anim .nx-dash-nav span,
    .nx-dash.nx-anim .nx-dash-card,
    .nx-dash.nx-anim .nx-dash-head > div,
    .nx-dash.nx-anim .nx-dash-range { opacity: 0; }
    .nx-dash.nx-anim .nx-line { stroke-dasharray: 1; stroke-dashoffset: 1; }
    .nx-dash.nx-anim .nx-fill { opacity: 0; }
    .nx-dash.nx-anim .nx-donut { opacity: 0; transform: scale(0.82) rotate(-90deg); }

    /* Play: staggered reveal */
    .nx-dash.nx-play .nx-dash-head > div { animation: nxRise .55s .05s both; }
    .nx-dash.nx-play .nx-dash-range { animation: nxRise .55s .12s both; }
    .nx-dash.nx-play .nx-dash-nav span { animation: nxRise .5s both; }
    .nx-dash.nx-play .nx-dash-nav span:nth-child(1) { animation-delay: .10s; }
    .nx-dash.nx-play .nx-dash-nav span:nth-child(2) { animation-delay: .15s; }
    .nx-dash.nx-play .nx-dash-nav span:nth-child(3) { animation-delay: .20s; }
    .nx-dash.nx-play .nx-dash-nav span:nth-child(4) { animation-delay: .25s; }
    .nx-dash.nx-play .nx-dash-nav span:nth-child(5) { animation-delay: .30s; }
    .nx-dash.nx-play .nx-dash-nav span:nth-child(6) { animation-delay: .35s; }
    .nx-dash.nx-play .nx-dash-nav span:nth-child(7) { animation-delay: .40s; }
    .nx-dash.nx-play .nx-dash-nav span:nth-child(8) { animation-delay: .45s; }
    .nx-dash.nx-play .nx-dash-stats div { animation: nxPop .55s both; }
    .nx-dash.nx-play .nx-dash-stats div:nth-child(1) { animation-delay: .18s; }
    .nx-dash.nx-play .nx-dash-stats div:nth-child(2) { animation-delay: .28s; }
    .nx-dash.nx-play .nx-dash-stats div:nth-child(3) { animation-delay: .38s; }
    .nx-dash.nx-play .nx-dash-stats div:nth-child(4) { animation-delay: .48s; }
    .nx-dash.nx-play .nx-dash-card { animation: nxRise .6s both; }
    .nx-dash.nx-play .nx-dash-card:nth-child(1) { animation-delay: .55s; }
    .nx-dash.nx-play .nx-dash-card:nth-child(2) { animation-delay: .65s; }
    /* Chart line draws, fill fades, donut spins into place */
    .nx-dash.nx-play .nx-line { animation: nxDraw 1.1s .7s ease-out forwards; }
    .nx-dash.nx-play .nx-fill { animation: nxFade .8s 1.25s ease-out forwards; }
    .nx-dash.nx-play .nx-donut { animation: nxDonut .8s .8s cubic-bezier(.22,1,.36,1) forwards; }

    @keyframes nxRise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } 
}
    @keyframes nxPop { from { opacity: 0; transform: translateY(16px) scale(.96); } to { opacity: 1; transform: none; } 
}
    @keyframes nxDraw { to { stroke-dashoffset: 0; } 
}
    @keyframes nxFade { to { opacity: 1; } 
}
    @keyframes nxDonut { to { opacity: 1; transform: none; } 
}

    /* "Business." - flowing gradient shimmer + underline draw-in */
    .nx-title-grad {
        background-image: linear-gradient(110deg,
            var(--blue) 0%,
            color-mix(in srgb, var(--violet) 70%, var(--blue)) 38%,
            color-mix(in srgb, var(--violet) 78%, #fff) 50%,
            color-mix(in srgb, var(--violet) 70%, var(--blue)) 62%,
            var(--blue) 100%);
        background-size: 220% 100%;
        animation: nxShimmer 5s linear infinite;
    }
    .nx-title-grad::after {
        transform: scaleX(0);
        transform-origin: left center;
        animation: nxUnderline .7s .5s cubic-bezier(.22,1,.36,1) forwards;
    }
    @keyframes nxShimmer { to { background-position: 220% 0; } 
}
    @keyframes nxUnderline { to { transform: scaleX(1); } 
}

}

/* ── Live Commands: Discord-style chat demo ─────────────────────────────────
   Intentionally Discord-dark in every theme; it represents the Discord client. */
.nx-chatwrap { width: min(920px, 100%); margin: 0 auto; }
.nx-chat {
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: #313338;
    border: 1px solid rgba(0, 0, 0, 0.4);
    box-shadow: 0 40px 110px rgba(15, 16, 24, 0.5);
    font-family: "gg sans", Inter, ui-sans-serif, system-ui, sans-serif;
}
.nx-chat-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    background: #1e1f22;
    border-bottom: 1px solid rgba(0, 0, 0, 0.3);
}
.nx-dot { width: 12px; height: 12px; border-radius: 50%; flex: 0 0 auto; }
.nx-dot-red { background: #ff5f57; }
.nx-dot-amber { background: #febc2e; }
.nx-dot-green { background: #28c840; }
.nx-chat-title {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-left: 10px;
    color: #f2f3f5;
    font-size: 14px;
    font-weight: 700;
}
.nx-chat-title i { color: #80848e; width: 16px; height: 16px; }

.nx-chat-body {
    height: 440px;
    overflow: hidden;
    padding: 20px 20px 6px;
    display: flex;
    flex-direction: column;
    gap: 16px;
    background: #313338;
}
.nx-msg { display: flex; gap: 14px; animation: nxMsgIn .32s ease both; }
@keyframes nxMsgIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } 
}
.nx-msg-av {
    flex: 0 0 auto;
    width: 40px; height: 40px;
    border-radius: 50%;
    display: grid; place-items: center;
    background: #5865f2;
    color: #fff; font-weight: 800; font-size: 15px;
    overflow: hidden;
}
.nx-msg-av.is-bot { background: linear-gradient(135deg, #2f6bff, #8b5cf6); }
.nx-msg-av img { width: 100%; height: 100%; object-fit: cover; }
.nx-msg-main { min-width: 0; }
.nx-msg-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 3px; }
.nx-msg-name { color: #f2f3f5; font-size: 15px; font-weight: 600; }
.nx-msg-name.is-bot { color: #c8b6ff; }
.nx-msg-badge {
    padding: 1px 5px;
    border-radius: var(--radius-sm);
    background: #5865f2;
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .3px;
    transform: translateY(-1px);
}
.nx-msg-time { color: #949ba4; font-size: 12px; }
.nx-msg-body { color: #dbdee1; font-size: 15px; line-height: 1.4; }

.nx-cmd-chip {
    display: inline;
    padding: 1px 5px;
    border-radius: var(--radius-sm);
    background: rgba(88, 101, 242, 0.28);
    color: #c9cdfb;
    font-weight: 600;
    white-space: pre-wrap;
}
.nx-caret {
    display: inline-block;
    width: 2px; height: 15px;
    margin-left: 2px;
    background: #dbdee1;
    transform: translateY(2px);
    animation: nxCaret 1s steps(1) infinite;
}
@keyframes nxCaret { 50% { opacity: 0; } 
}

.nx-typing { display: inline-flex; gap: 5px; padding: 6px 2px; }
.nx-typing i { width: 7px; height: 7px; border-radius: 50%; background: #b5bac1; animation: nxTyping 1.2s infinite ease-in-out; }
.nx-typing i:nth-child(2) { animation-delay: .18s; }
.nx-typing i:nth-child(3) { animation-delay: .36s; }
@keyframes nxTyping { 0%, 60%, 100% { transform: translateY(0); opacity: .5; } 30% { transform: translateY(-5px); opacity: 1; } 
}

.nx-embed {
    margin-top: 4px;
    max-width: 440px;
    padding: 12px 16px;
    border-left: 4px solid var(--embed-accent, #5865f2);
    border-radius: 4px 8px 8px 4px;
    background: #2b2d31;
    animation: nxMsgIn .3s ease both;
}
.nx-embed-title { color: #f2f3f5; font-size: 15px; font-weight: 700; }
.nx-embed-desc { margin-top: 5px; color: #c4c9ce; font-size: 14px; line-height: 1.45; }
.nx-embed-fields { display: flex; flex-wrap: wrap; gap: 8px 22px; margin-top: 11px; }
.nx-embed-field { display: flex; flex-direction: column; gap: 2px; }
.nx-embed-fn { color: #f2f3f5; font-size: 12px; font-weight: 700; }
.nx-embed-fv { color: #b5bac1; font-size: 13px; }

.nx-chat-input {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 4px 16px 16px;
    padding: 11px 16px;
    border-radius: var(--radius-md);
    background: #383a40;
}
.nx-chat-plus, .nx-chat-send { color: #b5bac1; display: inline-flex; }
.nx-chat-plus i, .nx-chat-send i { width: 18px; height: 18px; }
.nx-chat-placeholder { flex: 1; min-width: 0; color: #6d7178; font-size: 15px; }
.nx-chat-send { color: #5865f2; }

@media (max-width: 520px) {
    .nx-embed { max-width: 100%; }
    .nx-chat-body { height: 340px; }

}

/* ── Section motion: System Preview + How It Works ─────────────────────────*/
@media (prefers-reduced-motion: no-preference) {
    @keyframes nxTplMorph { from { opacity: .35; transform: translateY(8px) scale(.99); } to { opacity: 1; transform: none; } 
}

    /* System preview: the proof points stagger in on reveal. */
    
    
    
    
    

    /* How It Works: number circles pop with a soft ring */
    
    

    @keyframes nxNumPop {
        0% { opacity: 0; transform: scale(.5); }
        60% { opacity: 1; transform: scale(1.12); }
        100% { opacity: 1; transform: scale(1); }

}
    @keyframes nxItemIn { to { opacity: 1; transform: none; } 
}

}

/* ── Guild config: premade Templates button + modal ─────────────────────────*/
.nx-tpl-trigger { gap: 8px; }

.nx-tplm-overlay {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: grid;
    place-items: center;
    padding: 20px;
    background: rgba(8, 9, 13, 0.55);
    backdrop-filter: blur(3px);
    opacity: 0;
    transition: opacity .2s ease;
}
.nx-tplm-overlay.is-open { opacity: 1; }
.nx-tplm-panel {
    width: min(560px, 100%);
    max-height: 88vh;
    overflow: auto;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: 0 40px 120px rgba(8, 9, 13, 0.5);
    padding: 22px;
    transform: translateY(10px) scale(.98);
    transition: transform .22s cubic-bezier(.22,1,.36,1);
}
.nx-tplm-overlay.is-open .nx-tplm-panel { transform: none; }
.nx-tplm-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 18px; }
.nx-tplm-head strong { display: block; color: var(--text); font-size: 18px; font-weight: 800; }
.nx-tplm-head span { display: block; margin-top: 3px; color: var(--muted); font-size: 13px; }
.nx-tplm-close {
    flex: 0 0 auto;
    width: 32px; height: 32px;
    border-radius: var(--radius-md);
    border: 1px solid var(--line);
    background: var(--surface-2);
    color: var(--muted);
    cursor: pointer;
    transition: border-color .16s ease, color .16s ease;
}
@media (hover: hover) and (pointer: fine) {
.nx-tplm-close:hover { border-color: rgba(var(--blue-rgb), .4); color: var(--text); }
}
.nx-tplm-grid { display: grid; gap: 12px; }
.nx-tplm-card {
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    padding: 15px;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface-2);
    text-align: left;
    cursor: pointer;
    transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}
@media (hover: hover) and (pointer: fine) {
.nx-tplm-card:hover {
    transform: translateY(-2px);
    border-color: var(--tpl-accent);
    box-shadow: 0 12px 30px rgba(0,0,0,.14);
}
}
.nx-tplm-swatch {
    flex: 0 0 auto;
    width: 42px; height: 42px;
    border-radius: var(--radius-md);
    background: linear-gradient(135deg, var(--tpl-accent), color-mix(in srgb, var(--tpl-accent) 40%, #000 12%));
    box-shadow: 0 6px 16px rgba(0,0,0,.18);
    display: grid;
    place-items: center;
}
.nx-tplm-swatch i { width: 20px; height: 20px; color: #fff; }
.nx-tplm-swatch svg { width: 20px; height: 20px; }
.nx-tplm-text { flex: 1; min-width: 0; }
.nx-tplm-text strong { display: block; color: var(--text); font-size: 15px; font-weight: 800; }
.nx-tplm-text em { display: block; margin-top: 2px; color: var(--muted); font-style: normal; font-size: 13px; }
.nx-tplm-use {
    flex: 0 0 auto;
    padding: 6px 14px;
    border-radius: 999px;
    background: var(--tpl-accent);
    color: #fff;
    font-size: 12px;
    font-weight: 800;
}

/* ── Mobile sidebar drawer: base (hidden on desktop; shown ≤920 via media) ──*/
.nav-hamburger {
    display: none;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    flex: 0 0 auto;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--text);
    cursor: pointer;
    transition: border-color .16s ease, background .16s ease;
}
@media (hover: hover) and (pointer: fine) {
.nav-hamburger:hover { border-color: rgba(var(--blue-rgb), 0.4); }
}
.sidebar-backdrop { display: none; }
@media (max-width: 920px) {
    .sidebar-backdrop { display: block; }
    .nav-hamburger { display: inline-flex; }

}

.btn-sm { padding: 0.3rem 0.6rem; font-size: 0.78rem; }

/* --- Custom confirm modal --- */
.nx-modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.18s ease;
}

/* /compare table: grouped rows, this bot's column lifted out
   with a badge, check / cross marks with the wording under them. On phones each
   row reflows to the feature on top and the two answers side by side. */
.cmp { --cmp-lift: color-mix(in srgb, var(--text) 5%, transparent); }

.home-compare-list {
    display: grid;
    gap: .5rem;
    max-width: 60rem;
    margin: 0 auto;
}
.home-compare-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, .9fr) minmax(0, 1.1fr);
    gap: .75rem;
    align-items: center;
    padding: .7rem .9rem;
    border: 1px solid rgba(148, 163, 184, .16);
    border-radius: var(--radius-md);
    background: rgba(148, 163, 184, .04);
}
.home-compare-feature {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-weight: 800;
}
.home-compare-us,
.home-compare-them {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    font-size: .85rem;
}
.home-compare-us { color: #22c55e; font-weight: 700; }
.home-compare-them { color: var(--muted, #94a3b8); }
.home-compare-note {
    display: flex;
    align-items: center;
    gap: .5rem;
    justify-content: center;
    max-width: 60rem;
    margin: 1rem auto 0;
    padding: .7rem 1rem;
    border-radius: var(--radius-md);
    background: rgba(34, 197, 94, .1);
    border: 1px solid rgba(34, 197, 94, .3);
    font-size: .86rem;
    text-align: center;
}
.home-compare-note i { color: #22c55e; flex-shrink: 0; }
.home-compare-actions { display: flex; justify-content: center; margin-top: 1rem; }

@media (max-width: 780px) {
    .home-compare-row {
        grid-template-columns: 1fr;
        gap: .35rem;
    }

}
.status-tile {
    position: relative;
    display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: .05rem;
    min-width: 2.6rem; height: 2.75rem; padding: 0 .35rem;
    border-radius: var(--radius-md);
    background: var(--bg);
    border: 1px solid var(--line);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-weight: 800; font-size: .85rem;
    --tile: #22c55e;
    color: var(--tile);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.status-tile > b { font-weight: 800; line-height: 1; }
.status-tile > small { font-family: Inter, ui-sans-serif, system-ui, sans-serif; font-weight: 600; font-size: .62rem; line-height: 1; color: var(--muted); }
.status-tile.is-warn { --tile: #f59e0b; }
.status-tile.is-down { --tile: #ef4444; }
/* The node hosting the signed-in user's custom bot. */
.status-tile.is-mine {
    border-color: var(--brand, var(--blue));
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand, var(--blue)) 35%, transparent), 0 0 14px color-mix(in srgb, var(--brand, var(--blue)) 45%, transparent);
}
/* The shard a searched server is on: its own ring, since a signed-in user's shards already glow (is-mine). */
.status-tile.is-found { outline: 2px solid var(--text); outline-offset: 3px; }
html[data-theme="dyno"] .status-tile { background: #1a1a1a; }

/* /status "What these numbers mean": one bordered grid of live panels (bot
   uptime over a dotted map, support chat, the 30-day uptime line, latency per
   shard and node as a stepped chart). Cells share borders, no cards. */
.f9 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); border: 1px solid var(--line-soft); }
@keyframes f9Pulse { 70% { box-shadow: 0 0 0 8px rgba(34, 197, 94, 0); } 100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); } }
@media (max-width: 760px) {
    .f9 { grid-template-columns: 1fr; }
}
.status-hosting-link { text-decoration: underline; }

/* ---------------------------------------------------------------------------
   Home showcase: alternating copy / mock-Discord rows under the free-tier list.
   The mock cards borrow Discord's palette on purpose so the screenshot reads as
   "this is what it looks like in Discord", not as site chrome.
--------------------------------------------------------------------------- */
.home-showcase-list {
    display: grid;
    gap: clamp(2.5rem, 6vw, 5rem);
    max-width: 68rem;
    margin: 0 auto;
}
.home-showcase-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
    gap: clamp(1.5rem, 4vw, 3.5rem);
    align-items: center;
}
.home-showcase-row.is-flipped .home-showcase-copy { order: 2; }
.home-showcase-row.is-flipped .home-showcase-art { order: 1; }
.home-showcase-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--radius-lg);
    border: 1px solid var(--line, rgba(18, 24, 38, .12));
    background: color-mix(in srgb, var(--brand, #0062ff) 10%, transparent);
    color: var(--brand, #0062ff);
    margin-bottom: 1rem;
}
.home-showcase-copy h3 {
    margin: 0 0 .6rem;
    font-size: clamp(1.35rem, 2.6vw, 1.9rem);
    line-height: 1.2;
}
.home-showcase-copy p {
    margin: 0;
    color: var(--muted, #9a94a8);
    line-height: 1.65;
}
.home-showcase-points {
    list-style: none;
    margin: 1.1rem 0 0;
    padding: 0;
    display: grid;
    gap: .5rem;
}
.home-showcase-points li {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: .9rem;
    font-weight: 600;
}
.home-showcase-points li svg { color: var(--green, #22c55e); flex: none; }

/* mock Discord surfaces */
.dc-card {
    --dc-chat: var(--surface, #0d0e14);
    --dc-embed-bg: var(--surface-2, #12131b);
    --dc-line: var(--line-soft, color-mix(in srgb, var(--text) 9%, transparent));
    --dc-text: var(--text, #f3f0fa);
    --dc-muted: var(--muted, #9a94a8);
    --dc-brand: #5865f2;
    /* The site ships light in every theme, so these are tuned for a near-white
       card. They stay variables so a future dark theme overrides only here. */
    --dc-btn-bg: rgba(18, 24, 38, .08);
    --dc-mention-bg: rgba(88, 101, 242, .14);
    --dc-mention-text: #3d45b8;
    background: var(--dc-chat);
    border: 1px solid var(--line, rgba(139, 92, 246, .26));
    border-radius: .9rem;
    padding: 1rem;
    color: var(--dc-text);
    font-size: .9rem;
    line-height: 1.4;
    box-shadow: 0 18px 44px rgba(18, 24, 38, .10);
    overflow: hidden;
}
.dc-chat-bar {
    display: flex;
    align-items: center;
    gap: .4rem;
    margin: -1rem -1rem .85rem;
    padding: .65rem 1rem;
    background: rgba(18, 24, 38, .03);
    border-bottom: 1px solid var(--dc-line);
    color: var(--dc-muted);
    font-size: .82rem;
    font-weight: 600;
}
.dc-pill {
    margin-left: auto;
    background: rgba(34, 197, 94, .14);
    color: var(--green, #22c55e);
    border-radius: .35rem;
    padding: .1rem .4rem;
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .03em;
}
.dc-msg { display: flex; gap: .75rem; align-items: flex-start; }
.dc-msg + .dc-msg { margin-top: .9rem; }
.dc-msg > div { min-width: 0; flex: 1; }
.dc-avatar {
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    background: var(--dc-brand);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: .85rem;
    flex: none;
    overflow: hidden;
}
.dc-avatar img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.dc-avatar-b { background: #f0b132; color: #241a00; }
.dc-avatar-c { background: #1f8a4c; color: #fff; }
.dc-name { font-weight: 600; color: var(--dc-text); margin-bottom: .25rem; }
.dc-name time { color: var(--dc-muted); font-size: .72rem; font-weight: 400; margin-left: .4rem; }
.dc-tag {
    background: var(--dc-brand);
    color: #fff;
    border-radius: .2rem;
    padding: .05rem .28rem;
    font-size: .6rem;
    font-weight: 600;
    vertical-align: middle;
}
.dc-text { margin: 0; color: var(--dc-text); }
.dc-mention {
    background: var(--dc-mention-bg);
    color: var(--dc-mention-text);
    border-radius: .2rem;
    padding: 0 .15rem;
    font-weight: 500;
}
.dc-embed {
    border-left: 4px solid var(--dc-brand);
    border-radius: .3rem;
    background: var(--dc-embed-bg);
    padding: .7rem .85rem;
}
.dc-embed-green { border-left-color: #23a55a; }
.dc-embed strong { display: block; color: var(--dc-text); margin-bottom: .3rem; }
.dc-embed p { margin: 0; color: var(--dc-muted); font-size: .85rem; }
.dc-embed small { display: block; margin-top: .55rem; color: var(--dc-muted); font-size: .72rem; opacity: .8; }
.dc-rows { display: grid; gap: .3rem; margin-top: .2rem; }
.dc-rows span { display: flex; gap: .5rem; font-size: .82rem; color: var(--dc-text); }
.dc-rows b { color: var(--dc-muted); font-weight: 600; min-width: 4.5rem; }
.dc-buttons { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .7rem; }
.dc-btn {
    background: var(--dc-btn-bg);
    color: var(--dc-text);
    border-radius: .3rem;
    padding: .35rem .7rem;
    font-size: .78rem;
    font-weight: 500;
}
.dc-btn-primary { background: var(--dc-brand); color: #fff; }

@media (max-width: 860px) {
    .home-showcase-row { grid-template-columns: minmax(0, 1fr); }
    .home-showcase-row.is-flipped .home-showcase-copy,
    .home-showcase-row.is-flipped .home-showcase-art { order: initial; }

}

/* ---------------------------------------------------------------------------
   How It Works: the four steps are a sequence, so make them read as one.

   The step cards already carry data-animate + a stagger delay from the site's
   own reveal script, so this does NOT re-animate them - doing that would fight
   the existing system and, if `is-visible` never landed, leave them invisible.
   This only adds what is missing: a rail joining the steps, and a badge that
   pops as its card arrives.
--------------------------------------------------------------------------- */


/* Sits behind the badges, level with their centres (28px padding + 18px half). */




/* The ring punches the rail out from behind each badge. */




@media (prefers-reduced-motion: no-preference) {
    /* Rail draws once the first step has been revealed. */
    

    

    /* Badge pops with its own card, never independently of it. */
    

    

}

/* No :has() support means no rail animation, but the rail still draws. */


@keyframes nxFlowRail {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }

}

@keyframes nxFlowBadge {
    from { opacity: 0; transform: scale(.7); }
    to   { opacity: 1; transform: scale(1); }

}

/* The rail only reads as a sequence while the steps sit in one row. */


/* ===========================================================================
   LIVE CARDS
   One hover + reveal language across every card grid, so ~67 boxes read as one
   product instead of a dozen hover styles.

   Pure CSS on purpose: no cursor spotlight and no 3D tilt, so there is no
   pointer tracking, no per-frame JS and nothing to go stale on scroll. Only
   transform/opacity/box-shadow animate, so none of it touches layout.
   =========================================================================== */

.home-compare-row,
.home-showcase-row .dc-card,
.home-live-card,
.home-feature-card,
.home-module-grid article,
.nx-tpl-card {
    position: relative;
    isolation: isolate;
    transition:
        transform .38s cubic-bezier(.22, 1, .36, 1),
        box-shadow .38s cubic-bezier(.22, 1, .36, 1),
        border-color .3s ease;
}

/* A soft brand wash that fades up from the card's own surface on hover. */
.home-compare-row::after,
.home-showcase-row .dc-card::after,
.home-live-card::after,
.home-feature-card::after,
.home-module-grid article::after,
.nx-tpl-card::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    opacity: 0;
    pointer-events: none;
    transition: opacity .38s ease;
    background: linear-gradient(
        160deg,
        color-mix(in srgb, var(--brand, #0062ff) 9%, transparent),
        transparent 62%
    );
}

@media (hover: hover) and (pointer: fine) {
    .home-compare-row:hover,
    .home-showcase-row .dc-card:hover,
    .home-live-card:hover,
    .home-feature-card:hover,
    .home-module-grid article:hover,
    .nx-tpl-card:hover {
        border-color: color-mix(in srgb, var(--brand, #0062ff) 40%, transparent);
        box-shadow:
            0 16px 34px color-mix(in srgb, var(--brand, #0062ff) 13%, transparent),
            0 2px 8px rgba(18, 24, 38, .05);
    }

    .home-compare-row:hover::after,
    .home-showcase-row .dc-card:hover::after,
    .home-live-card:hover::after,
    .home-feature-card:hover::after,
    .home-module-grid article:hover::after,
    .nx-tpl-card:hover::after { opacity: 1; }

}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
    /* The lift is the only transform, so it can never fight the reveal, which
       owns transform until it lands. */
    .home-showcase-row .dc-card:hover,
    .home-live-card:hover,
    .home-feature-card.is-visible:hover,
    .home-module-grid article:hover,
    .nx-tpl-card:hover {
        transform: translateY(-4px);
    }

    /* Icons and number badges answer the hover with a small pop. */
    .home-feature-icon,
    .home-module-grid article > span {
        transition: transform .38s cubic-bezier(.34, 1.56, .64, 1);
    }

    .home-feature-card:hover .home-feature-icon,
    .home-module-grid article:hover > span {
        transform: scale(1.09) rotate(-4deg);
    }

    /* Compare rows sit in a list, so they slide rather than lift. */
    .home-compare-row:hover { transform: translateX(4px); }

}

@media (prefers-reduced-motion: reduce) {
    .home-compare-row,
    .home-showcase-row .dc-card,
    .home-live-card,
    .home-feature-card,
    .home-module-grid article,
    .nx-tpl-card { transition: none; transform: none !important; }

}

/* Footer note at the end of the server picker: why a server may be missing,
   and the one action that fixes it. */
/* .server-missing-note is styled with the rainbow CTA further down. */

/* ===========================================================================
   MEMBER TICKET DESK  (/tickets)
   Three panes: my tickets | conversation | details - the shape support tools
   converge on, and the same shape as the transcript page so the two read as
   one product.
   =========================================================================== */
.tk-desk {
    display: grid;
    grid-template-columns: 310px minmax(0, 1fr) 260px;
    gap: 1rem;
    height: calc(100vh - 8rem);
    min-height: 32rem;
}

.tk-list, .tk-thread, .tk-side {
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface);
    min-height: 0;
}

.tk-list { display: flex; flex-direction: column; }
.tk-list-head {
    display: flex; align-items: center; justify-content: space-between; gap: .75rem;
    padding: 1rem 1rem .75rem;
}
.tk-list-head h1 { margin: 0; font-size: 1.05rem; font-weight: 800; }
.tk-new { padding: .4rem .7rem; font-size: .82rem; }

.tk-tabs { display: flex; gap: .4rem; padding: 0 1rem .75rem; }
.tk-tab {
    flex: 1; padding: .4rem .6rem; border-radius: var(--radius-md);
    border: 1px solid var(--line); background: transparent;
    color: var(--muted); font: inherit; font-size: .82rem; font-weight: 700; cursor: pointer;
}
.tk-tab.active {
    background: color-mix(in srgb, var(--brand, #0062ff) 12%, transparent);
    border-color: color-mix(in srgb, var(--brand, #0062ff) 34%, transparent);
    color: var(--text);
}
.tk-tab span { opacity: .7; margin-left: .2rem; }

/* Every dashboard tab row: the ticket panel editor's boxed tabs, raised a little
   (top light edge + soft drop shadow) - Mike 2026-10-31. `body` outranks each
   page's own <style>. Fill is background-color (not only a gradient) so the
   nx-kit glide still slides a filled pill between tabs. */
body :is(.tk-tabs, .mg-tabs, .mu-tabs, .app-tabs, .inv-tabs, .wse-tabs) { border-bottom: 0; background: none; gap: .4rem; }
body .inv-tabs, body .wse-tabs { padding: 0; border: 0; }
body :is(.tk-tabs .tk-tab, .mg-tabs .mg-tab, .mu-tabs .mu-tab, .app-tabs > a, .inv-tabs > a, .wse-tabs > button) {
    margin-bottom: 0;
    border: 1px solid color-mix(in srgb, var(--text) 16%, transparent);
    border-radius: var(--radius-md);
    background-color: color-mix(in srgb, var(--text) 8%, transparent);
    background-image: linear-gradient(180deg, color-mix(in srgb, var(--text) 12%, transparent), transparent);
    box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text) 16%, transparent), 0 1px 2px rgb(0 0 0 / .22), 0 3px 8px -3px rgb(0 0 0 / .3);
    color: color-mix(in srgb, var(--text) 80%, var(--muted));
    text-transform: none;
    letter-spacing: normal;
    transition: color .15s ease, background-color .15s ease, border-color .15s ease, box-shadow .15s ease;
}
body :is(.tk-tabs .tk-tab.active, .mg-tabs .mg-tab.is-active, .mu-tabs .mu-tab.is-active, .app-tabs > a.active, .inv-tabs > a[aria-current="page"], .wse-tabs > button.is-active) {
    border-color: color-mix(in srgb, var(--brand, #0062ff) 48%, transparent);
    background-color: color-mix(in srgb, var(--brand, #0062ff) 18%, transparent);
    background-image: linear-gradient(180deg, color-mix(in srgb, #fff 9%, transparent), transparent);
    box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 16%, transparent), 0 1px 2px rgb(0 0 0 / .25), 0 6px 14px -6px color-mix(in srgb, var(--brand, #0062ff) 55%, transparent);
    color: var(--text);
}
@media (hover: hover) and (pointer: fine) {
    body :is(.tk-tabs .tk-tab, .mg-tabs .mg-tab, .mu-tabs .mu-tab, .app-tabs > a, .inv-tabs > a, .wse-tabs > button):hover { color: var(--text); border-color: color-mix(in srgb, var(--text) 18%, transparent); }
}
body :is(.tk-tabs .tk-tab, .mg-tabs .mg-tab, .mu-tabs .mu-tab, .app-tabs > a, .inv-tabs > a, .wse-tabs > button):active { box-shadow: inset 0 1px 3px rgb(0 0 0 / .35); }

.tk-items { flex: 1; overflow-y: auto; padding: 0 .6rem 1rem; display: grid; gap: .35rem; align-content: start; }
.tk-item {
    display: grid; gap: .15rem; width: 100%; text-align: left;
    padding: .65rem .7rem; border-radius: var(--radius-md);
    border: 1px solid transparent; background: transparent;
    font: inherit; cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
.tk-item:hover { background: color-mix(in srgb, var(--brand, #0062ff) 7%, transparent); }
}
.tk-item.active {
    background: color-mix(in srgb, var(--brand, #0062ff) 11%, transparent);
    border-color: color-mix(in srgb, var(--brand, #0062ff) 30%, transparent);
}
.tk-item-top { display: flex; align-items: center; gap: .4rem; }
.tk-item-top b { font-size: .9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tk-dot { width: .5rem; height: .5rem; border-radius: 50%; flex: none; margin-left: auto; }
.tk-dot.is-open { background: var(--green, #1f8a4c); }
.tk-dot.is-closed { background: var(--muted); opacity: .55; }
.tk-item-meta, .tk-item-when {
    font-size: .74rem; color: var(--muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tk-none { padding: 1.5rem 1rem; text-align: center; font-size: .85rem; }
.tk-skeleton { display: grid; gap: .5rem; padding: .5rem; }
.tk-skeleton span {
    height: 3.1rem; border-radius: var(--radius-md);
    background: color-mix(in srgb, var(--text) 7%, transparent);
    animation: tkPulse 1.4s ease-in-out infinite;
}
.tk-skeleton span:nth-child(2) { animation-delay: .15s; }
.tk-skeleton span:nth-child(3) { animation-delay: .3s; }
@keyframes tkPulse { 0%, 100% { opacity: .5; } 50% { opacity: .9; } 
}

/* centre */
.tk-thread { display: flex; flex-direction: column; min-height: 0; }
.tk-empty { margin: auto; text-align: center; max-width: 22rem; padding: 2rem; }
.tk-empty h2 { margin: 0 0 .35rem; font-size: 1.05rem; font-weight: 800; }
.tk-empty p { margin: 0; font-size: .88rem; line-height: 1.55; }

.tk-convo { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.tk-convo-head {
    display: flex; align-items: center; gap: 1rem;
    padding: .9rem 1.1rem; border-bottom: 1px solid var(--line); flex: none;
}
.tk-convo-head h2 { margin: 0; font-size: 1rem; font-weight: 800; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tk-convo-head p { margin: .1rem 0 0; font-size: .78rem; }
.tk-status {
    margin-left: auto; flex: none; padding: .2rem .55rem; border-radius: 999px;
    font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .03em;
}
.tk-status.is-open { background: color-mix(in srgb, var(--green, #1f8a4c) 14%, transparent); color: var(--green, #1f8a4c); }
.tk-status.is-closed { background: color-mix(in srgb, var(--muted) 16%, transparent); color: var(--muted); }

.tk-messages { flex: 1; overflow-y: auto; padding: 1rem 1.1rem; display: grid; gap: .9rem; align-content: start; }
.tk-msg { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .7rem; }
.tk-avatar {
    width: 2.1rem; height: 2.1rem; border-radius: 50%; flex: none; overflow: hidden;
    display: flex; align-items: center; justify-content: center;
    background: var(--brand, #0062ff); color: #fff; font-size: .8rem; font-weight: 700;
}
.tk-avatar img { width: 100%; height: 100%; object-fit: cover; }
.tk-msg-head { display: flex; align-items: baseline; gap: .45rem; flex-wrap: wrap; }
.tk-msg-head b { font-size: .87rem; }
.tk-msg-head time { font-size: .7rem; color: var(--muted); }
.tk-bot-tag {
    background: var(--brand, #0062ff); color: #fff; border-radius: var(--radius-sm);
    padding: .02rem .25rem; font-size: .58rem; font-weight: 700;
}
.tk-msg-text { margin: .2rem 0 0; font-size: .9rem; line-height: 1.55; white-space: pre-wrap; overflow-wrap: anywhere; }
.tk-msg.mine .tk-msg-body { }
.tk-file {
    display: inline-flex; align-items: center; gap: .3rem; margin-top: .4rem;
    font-size: .8rem; color: var(--brand, #0062ff);
}
.tk-file.is-image { display: block; }
.tk-file img { max-width: min(320px, 100%); max-height: 240px; border-radius: var(--radius-md); margin-top: .4rem; }

.tk-composer {
    display: flex; gap: .6rem; align-items: flex-end; flex: none;
    padding: .8rem 1.1rem 1rem; border-top: 1px solid var(--line);
}
.tk-composer textarea {
    flex: 1; resize: none; min-height: 2.6rem; max-height: 10rem;
    padding: .6rem .8rem; border-radius: var(--radius-md);
    border: 1px solid var(--line); background: var(--bg); color: var(--text);
    font: inherit; font-size: .9rem; line-height: 1.5;
}
.tk-composer textarea:focus { outline: none; border-color: color-mix(in srgb, var(--brand, #0062ff) 55%, transparent); }
.tk-composer textarea:disabled { opacity: .55; }
.tk-composer-note { margin: -.4rem 1.1rem .9rem; font-size: .78rem; }
.tk-attach { flex: none; height: 2.6rem; width: 2.6rem; padding: 0; justify-content: center; }

/* right */
.tk-side { padding: 1rem; overflow-y: auto; }
.tk-side h3 {
    margin: 0 0 .6rem; font-size: .72rem; font-weight: 800;
    letter-spacing: .06em; text-transform: uppercase; color: var(--muted);
}
.tk-detail { padding: .35rem 0 .6rem; font-size: .85rem; }
.tk-detail b { display: block; font-weight: 700; word-break: break-word; }
.tk-detail span { font-size: .7rem; color: var(--muted); }
.tk-side-actions { display: grid; gap: .5rem; margin-top: 1rem; }

/* new-ticket dialog */
.tk-dialog {
    border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 0;
    width: min(30rem, calc(100vw - 2rem)); background: var(--surface); color: var(--text);
}
.tk-dialog::backdrop { background: rgba(10, 10, 10, .5); }
.tk-dialog-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 1rem 1.1rem; border-bottom: 1px solid var(--line);
}
.tk-dialog-head h2 { margin: 0; font-size: 1rem; font-weight: 800; }
.tk-dialog-x { border: 0; background: transparent; font-size: 1.4rem; line-height: 1; color: var(--muted); cursor: pointer; }
.tk-dialog-body { padding: 1rem 1.1rem 1.2rem; display: grid; gap: 1rem; max-height: 60vh; overflow-y: auto; }

@media (max-width: 1100px) {
    .tk-desk { grid-template-columns: 280px minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) auto; }
    /* The side column held the only Close ticket button, so it can't just go:
       it becomes a strip under the conversation. :not([hidden]) keeps it away
       until a ticket is picked. */
    .tk-side:not([hidden]) {
        grid-column: 1 / -1;
        display: grid; grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr)); gap: .5rem 1rem;
        overflow: visible;
    }
    .tk-side h3, .tk-side .tk-side-actions { grid-column: 1 / -1; margin: 0; }
}
@media (max-width: 780px) {
    .tk-desk { grid-template-columns: minmax(0, 1fr); height: auto; }
    /* One pane at a time on a phone: the list, or the ticket you picked. */
    .tk-list { max-height: 22rem; }
    .tk-thread { min-height: 26rem; }

}

/* ===========================================================================
   LIVE CHAT WIDGET
   Fixed bottom-right. z-index sits above the page but below modal dialogs, and
   the launcher reserves its own space so nothing can sit under it.
   =========================================================================== */
.nxchat {
    position: fixed;
    right: clamp(.85rem, 2vw, 1.5rem);
    bottom: clamp(.85rem, 2vw, 1.5rem);
    z-index: 1200;
    display: flex;
    /* column-reverse so the panel opens upward from the launcher, which stays
       pinned to the corner. */
    flex-direction: column-reverse;
    align-items: flex-end;
    gap: .7rem;
    font-family: inherit;
}

/* Never over a control (Mike 2026-10-30): the music player's full-screen lyrics,
   its side panel and reaction picker hide it; the Listening now bar lifts it
   (--nx-chat-lift, set by partials/musicPlayer.ejs); a page's last row can
   scroll clear of it (.app-main padding below). */
.nxchat { transition: bottom .3s ease; }
/* "Translate" under a staff/AI reply in the website chat (public/live-chat.js). */
.nxchat-tr-box { display: grid; justify-items: start; gap: .25rem; margin-top: .2rem; max-width: 85%; }
.nxchat-tr { padding: .45rem .65rem; border-radius: 12px; border: 1px dashed color-mix(in srgb, var(--brand) 45%, transparent); background: color-mix(in srgb, var(--brand) 7%, transparent); font-size: .82rem; line-height: 1.45; white-space: pre-wrap; word-break: break-word; }
.nxchat-tr-btn { padding: .1rem .3rem; border: 0; border-radius: 6px; background: none; color: var(--muted); font-size: .7rem; font-weight: 700; cursor: pointer; }
.nxchat-tr-btn:hover, .nxchat-tr-btn:focus-visible { color: var(--text); background: color-mix(in srgb, var(--text) 8%, transparent); }
.nxchat-tr-btn:disabled { opacity: .6; cursor: default; }
html.has-np-bar .nxchat { bottom: calc(var(--nx-chat-lift, 0px) + clamp(.85rem, 2vw, 1.5rem)); }
body:has(.np-full:not([hidden]), .np.is-queue-open, .np-react-pick:not([hidden]), .np-djs-list:not([hidden])) .nxchat { visibility: hidden; pointer-events: none; }
body:has(.nxchat) .app-main { padding-bottom: max(var(--main-pad, 28px), 5.5rem); }

.nxchat-launcher {
    position: relative;
    width: 3.5rem;
    height: 3.5rem;
    border: 0;
    border-radius: 50%;
    background: var(--brand, #0062ff);
    color: #fff;
    cursor: pointer;
    display: grid;
    place-items: center;
    box-shadow: 0 12px 28px color-mix(in srgb, var(--brand, #0062ff) 38%, transparent);
    transition: transform .25s cubic-bezier(.34, 1.56, .64, 1), box-shadow .25s ease;
}
@media (hover: hover) and (pointer: fine) {
.nxchat-launcher:hover { transform: scale(1.06); }
}
.nxchat-launcher:active { transform: scale(.97); }
.nxchat-launcher svg { width: 1.6rem; height: 1.6rem; }

/* A quiet pulse only while something is unread, never idle. */
.nxchat-launcher.has-unread::before {
    content: "";
    position: absolute;
    inset: -.35rem;
    border-radius: 50%;
    border: 2px solid var(--brand, #0062ff);
    opacity: .55;
    animation: nxchatPulse 1.9s ease-out infinite;
}
@keyframes nxchatPulse {
    0% { transform: scale(.92); opacity: .55; }
    70% { transform: scale(1.18); opacity: 0; }
    100% { opacity: 0; }

}

.nxchat-badge[hidden],
.nxchat-panel[hidden],
.nxchat-typing[hidden] { display: none !important; }

.nxchat-badge {
    position: absolute;
    top: -.15rem; right: -.15rem;
    min-width: 1.25rem; height: 1.25rem;
    padding: 0 .3rem;
    border-radius: 999px;
    background: var(--red, #b4321e);
    color: #fff;
    font-size: .7rem; font-weight: 800;
    display: grid; place-items: center;
    border: 2px solid var(--bg, #F4F4F4);
}

.nxchat-panel {
    /* Roomier, Crisp-sized (Mike 2026-11-14: "a little bigger"): was 23rem x 31rem. */
    width: min(26rem, calc(100vw - 1.7rem));
    height: min(44rem, calc(100vh - 7rem));
    display: flex;
    flex-direction: column;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: 0 24px 60px rgba(18, 24, 38, .18);
    overflow: hidden;
    transform-origin: bottom right;
    animation: nxchatIn .26s cubic-bezier(.22, 1, .36, 1);
}
@keyframes nxchatIn {
    from { opacity: 0; transform: translateY(10px) scale(.97); }
    to { opacity: 1; transform: none; }

}

.nxchat-head {
    display: flex; align-items: center; justify-content: space-between; gap: .75rem;
    padding: .9rem 1rem;
    background: var(--brand, #0062ff);
    color: #fff;
    flex: none;
}
.nxchat-head strong { display: block; font-size: .95rem; font-weight: 800; }
.nxchat-sub { display: block; font-size: .75rem; opacity: .85; }
.nxchat-close {
    border: 0; background: transparent; color: #fff;
    font-size: 1.5rem; line-height: 1; cursor: pointer; opacity: .85;
}
@media (hover: hover) and (pointer: fine) {
.nxchat-close:hover { opacity: 1; }
}
.nxchat-mute {
    border: 0; background: transparent; color: #fff;
    font-size: 1rem; line-height: 1; cursor: pointer; opacity: .8;
    padding: 0 .3rem;
}
@media (hover: hover) and (pointer: fine) {
.nxchat-mute:hover { opacity: 1; }
}
.nxchat-mute:focus-visible { outline: 2px solid rgba(255,255,255,.7); outline-offset: 2px; border-radius: var(--radius-sm); }

.nxchat-body {
    flex: 1; overflow-y: auto; padding: 1rem;
    display: flex; flex-direction: column; gap: .5rem;
    background: var(--bg);
}
.nxchat-greeting { margin: auto 0; text-align: center; padding: 1rem .5rem; }
.nxchat-greeting strong { display: block; font-size: 1.15rem; margin-bottom: .35rem; }
.nxchat-greeting p { margin: 0; color: var(--muted); font-size: .86rem; line-height: 1.55; }

.nxchat-msg { display: flex; flex-direction: column; align-items: flex-start; max-width: 85%; }
.nxchat-msg.mine { align-self: flex-end; align-items: flex-end; }
.nxchat-bubble {
    margin: 0; padding: .6rem .85rem;
    border-radius: var(--radius-lg) var(--radius-lg) var(--radius-lg) var(--radius-sm);
    background: var(--surface-2, rgba(var(--surface-rgb), .9));
    border: 1px solid var(--line);
    font-size: .95rem; line-height: 1.5;
    white-space: pre-wrap; overflow-wrap: anywhere;
}
.nxchat-msg.mine .nxchat-bubble {
    border-radius: var(--radius-lg) var(--radius-lg) var(--radius-sm) var(--radius-lg);
    background: var(--brand, #0062ff);
    border-color: transparent;
    color: #fff;
}
.nxchat-msg time { font-size: .65rem; color: var(--muted); margin-top: .15rem; }
.nxchat-helpful { display: flex; align-items: center; gap: .3rem; margin-top: .25rem; font-size: .7rem; color: var(--muted); }
.nxchat-helpful button { border: 1px solid var(--line); border-radius: 99px; background: transparent; padding: .1rem .45rem; font-size: .8rem; line-height: 1.4; cursor: pointer; opacity: .75; transition: opacity .15s, background-color .15s, border-color .15s; }
.nxchat-helpful button:hover { opacity: 1; }
.nxchat-helpful button[aria-pressed="true"] { opacity: 1; border-color: var(--accent, #5865f2); background: rgba(88, 101, 242, .15); }

.nxchat-system {
    align-self: center; text-align: center;
    font-size: .74rem; color: var(--muted);
    padding: .3rem .6rem;
}
.nxchat-error { color: var(--red, #b4321e); }

/* Call island (nx-kit, music group) while staff is in the chat. */
.nxchat-island { display: flex; justify-content: center; padding: .5rem 1rem 0; background: var(--bg); }
.nxchat-island .nx-island-dot.is-big { width: 2.4rem; height: 2.4rem; }

/* Typing dots: the nx-kit bounce loader (squash on landing, stretch in the air). */
.nxchat-typing { display: flex; align-items: flex-end; gap: .3rem; height: 1.35rem; padding: 0 1rem .5rem; background: var(--bg); }
.nxchat-typing span {
    width: .45rem; height: .45rem; border-radius: 50%;
    background: var(--muted);
    transform-origin: 50% 100%;
    animation: nxchatDot 1s infinite cubic-bezier(.3, 0, .3, 1);
}
.nxchat-typing span:nth-child(2) { animation-delay: .14s; }
.nxchat-typing span:nth-child(3) { animation-delay: .28s; }
@keyframes nxchatDot {
    0%, 60%, 100% { transform: translateY(0) scale(1.25, .75); }
    30% { transform: translateY(-.55rem) scale(.9, 1.1); }
    45% { transform: translateY(0) scale(1, 1); }

}

.nxchat-email { display: flex; align-items: center; gap: .4rem; padding: .5rem .75rem; border-top: 1px solid var(--line); background: var(--surface); }
.nxchat-email[hidden] { display: none; }
.nxchat-email input { flex: 1; min-width: 0; padding: .45rem .65rem; border: 1px solid var(--line); border-radius: .6rem; background: transparent; color: inherit; font: inherit; font-size: 16px; }
.nxchat-email input:focus { outline: none; border-color: var(--brand, #0062ff); }
.nxchat-email button { flex: none; padding: .45rem .75rem; border: 0; border-radius: .6rem; background: var(--brand, #0062ff); color: #fff; font: inherit; font-weight: 700; cursor: pointer; }
.nxchat-email .nxchat-email-later { padding: .45rem .55rem; background: transparent; color: var(--muted); }
.nxchat-composer {
    display: flex; gap: .5rem; align-items: flex-end; flex: none;
    padding: .7rem .8rem .8rem;
    border-top: 1px solid var(--line);
    background: var(--surface);
}
.nxchat-composer textarea {
    flex: 1; resize: none; min-height: 2.3rem; max-height: 7.5rem;
    padding: .5rem .7rem; border-radius: var(--radius-md);
    border: 1px solid var(--line); background: var(--bg); color: var(--text);
    font: inherit; font-size: .87rem; line-height: 1.5;
}
.nxchat-composer textarea:focus {
    outline: none;
    border-color: color-mix(in srgb, var(--brand, #0062ff) 55%, transparent);
}
.nxchat-composer button {
    flex: none; width: 2.3rem; height: 2.3rem;
    border: 0; border-radius: var(--radius-md);
    background: var(--brand, #0062ff); color: #fff;
    display: grid; place-items: center; cursor: pointer;
}
.nxchat-composer button:disabled { opacity: .6; cursor: default; }
.nxchat-composer button svg { width: 1.05rem; height: 1.05rem; }

/* Attach button: same size as send, quiet until hovered. */
.nxchat-composer .nxchat-attach {
    background: transparent; color: var(--muted);
    border: 1px solid var(--line);
}
@media (hover: hover) and (pointer: fine) {
.nxchat-composer .nxchat-attach:hover:not(:disabled) { color: var(--text); border-color: color-mix(in srgb, var(--brand, #0062ff) 45%, var(--line)); }
}
.nxchat-bubble.is-ai, .chat-bubble.is-ai { border-style: dashed; }

/* Message content shared by the widget and the admin console (chat-content.js). */
.nxc-text { white-space: pre-wrap; overflow-wrap: anywhere; }
.nxc-link { color: inherit; text-decoration: underline; text-underline-offset: 2px; font-weight: 600; }
/* Link preview, laid out like Discord's link embed: red bar, site, blue title, text, big card. */
.nxc-preview {
    display: flex; flex-direction: column; gap: .3rem;
    margin-top: .5rem; padding: .7rem .85rem .85rem;
    border: 1px solid var(--line); border-left: 4px solid #e11d48; border-radius: var(--radius-sm);
    background: var(--bg); color: var(--text);
    text-decoration: none; white-space: normal; width: min(26rem, 100%); box-sizing: border-box;
}
.nxc-preview.is-topgg { border-left-color: #ff3366; }
.nxc-preview-site { font-size: .72rem; color: var(--muted); }
.nxc-preview-title { font-size: .92rem; line-height: 1.3; font-weight: 700; color: #2f7cf6; }
.nxc-preview-desc { font-size: .8rem; line-height: 1.4; color: var(--text); opacity: .86; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.nxc-preview-img { display: block; width: 100%; height: auto; aspect-ratio: 1200 / 630; object-fit: cover; margin-top: .4rem; border-radius: var(--radius-sm); background: var(--line); }
@media (hover: hover) and (pointer: fine) {
.nxc-preview:hover .nxc-preview-title { text-decoration: underline; text-underline-offset: 2px; }
}
.nxc-file { margin-top: .4rem; display: flex; flex-direction: column; gap: .3rem; white-space: normal; }
.nxc-file:first-child { margin-top: 0; }
.nxc-file img, .nxc-file video { display: block; max-width: min(18rem, 100%); max-height: 16rem; border-radius: var(--radius-md); background: #000; }
.nxc-file audio { width: min(16rem, 100%); }
.nxc-file-name { font-size: .74rem; color: inherit; opacity: .85; word-break: break-all; }
.nxc-file.is-expired { font-size: .75rem; font-style: italic; opacity: .75; }

/* Nothing else may sit under the launcher. */
.analytics-consent, .cookie-banner, .toast-stack { padding-right: 5rem; }

@media (prefers-reduced-motion: reduce) {
    .nxchat-panel { animation: none; }
    .nxchat-launcher { transition: none; }
    .nxchat-launcher.has-unread::before { animation: none; opacity: .4; }
    .nxchat-typing span { animation: none; opacity: .6; }

}

@media (max-width: 480px) {
    .nxchat { right: .7rem; bottom: .7rem; }
    .nxchat-panel { width: calc(100vw - 1.4rem); height: min(40rem, calc(100vh - 6rem)); }

}

.nxchat-signin {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-top: .9rem;
    padding: .5rem 1rem;
    border-radius: var(--radius-md);
    background: var(--brand, #0062ff);
    color: #fff;
    font-size: .85rem;
    font-weight: 700;
    text-decoration: none;
}
@media (hover: hover) and (pointer: fine) {
.nxchat-signin:hover { filter: brightness(1.08); text-decoration: none; }
}
.nxchat-composer[hidden] { display: none !important; }

/* ===========================================================================
   FLOATING TOP BAR
   Site-wide alternative to the default flush bar, picked in the admin panel.
   Only the chrome changes: every nav element inside keeps its own styling, so
   the two modes stay in sync as the bar's contents change.
   =========================================================================== */
.topbar-floating {
    /* Fixed, not sticky: sticky keeps the bar in the document flow, which left
       a band of empty page above the hero and a hard edge where the hero's
       gradient began. Out of flow, the hero bleeds to the top of the viewport
       and the bar floats over it, which is the whole point of the style. */
    position: fixed;
    top: var(--nav-float-gap);
    left: 50%;
    transform: translateX(-50%);
    width: min(76rem, calc(100% - clamp(1rem, 4vw, 2.5rem)));
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: color-mix(in srgb, var(--surface) 88%, transparent);
    box-shadow: 0 10px 30px rgba(18, 24, 38, .10);
    z-index: 60;
}

.nav-floating {
    --nav-float-gap: clamp(.5rem, 1.4vw, 1rem);
    /* Bar height plus the gap above and below it. */
    --nav-float-clear: calc(3.5rem + (var(--nav-float-gap) * 2));
}

/* .dashboard-root is `grid-template-rows: 56px 1fr` with the header as row 1.
   Taking the header out of flow left the content as the only child, so it
   landed in the fixed 56px row and overflow-y clipped the entire page to one
   viewport. With no header in the grid there must be no header row. */
.dashboard-root.nav-floating { grid-template-rows: 1fr; }

/* Clearance is added ONCE, on the outermost content container. The markup
   nests main.app-main > section.home-page > section.home-hero, so padding any
   two of them stacks: an earlier version applied it to all three and pushed the
   hero down by 264px. Backgrounds are painted by the page and the hero itself,
   so they still reach the top of the viewport behind the bar. */
.nav-floating .app-main { padding-top: calc(var(--nav-float-clear) + .5rem); }

/* Anchor links must not land underneath the floating bar. */
.nav-floating { scroll-padding-top: var(--nav-float-clear); }

/* The blur is what sells it as floating, but it is expensive, so it is only
   applied where the browser actually supports it. */
@supports (backdrop-filter: blur(12px)) or (-webkit-backdrop-filter: blur(12px)) {
    .topbar-floating {
        /* Glass: see-through tint, strong blur, a light top edge and a soft
           border so it reads as a pane over the page in both themes. */
        backdrop-filter: blur(20px) saturate(1.7);
        -webkit-backdrop-filter: blur(20px) saturate(1.7);
        background: linear-gradient(180deg, color-mix(in srgb, var(--surface) 62%, transparent), color-mix(in srgb, var(--surface) 52%, transparent));
        border-color: color-mix(in srgb, var(--text, #fff) 12%, transparent);
        box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 14%, transparent), 0 12px 32px rgba(0, 0, 0, .18);
    }

}

@media (max-width: 640px) {
    .nav-floating { --nav-float-gap: .4rem; }
    .topbar-floating {
        width: calc(100% - .8rem);
        border-radius: var(--radius-lg);
    }

}

@media (prefers-reduced-motion: reduce) {
    .topbar-floating { transition: none; }

}

/* Ticket list grouping: Support / Bug report / Suggestion. */
.tk-group {
    display: flex; align-items: center; justify-content: space-between; gap: .5rem;
    margin: .75rem .25rem .15rem; padding: 0 .45rem;
    font-size: .68rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
    color: var(--muted);
}
.tk-group:first-child { margin-top: 0; }
.tk-group b {
    font-size: .68rem; font-weight: 800;
    color: var(--brand, #0062ff);
    background: color-mix(in srgb, var(--brand, #0062ff) 12%, transparent);
    border-radius: 999px; padding: .05rem .4rem;
}

/* --- widget: header identity, start screen, recent list ------------------- */
.nxchat-head { gap: .65rem; }
.nxchat-avatar {
    width: 2rem; height: 2rem; border-radius: 50%; flex: none; overflow: hidden;
    display: grid; place-items: center;
    background: rgba(255, 255, 255, .22); color: #fff; font-weight: 700; font-size: .8rem;
}
.nxchat-avatar img { width: 100%; height: 100%; object-fit: cover; }
.nxchat-head-text { min-width: 0; }
.nxchat-title { display: block; font-size: .95rem; font-weight: 800; }

.nxchat-start { display: grid; gap: .5rem; align-content: start; }
.nxchat-start-title { font-size: .95rem; font-weight: 800; margin-top: .35rem; }
.nxchat-start-title:first-child { margin-top: 0; }
.nxchat-newchat {
    display: flex; align-items: center; gap: .75rem; width: 100%; text-align: left;
    padding: .8rem .9rem; border-radius: var(--radius-lg);
    border: 1px solid color-mix(in srgb, var(--brand, #0062ff) 40%, transparent);
    background: var(--surface); font: inherit; cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
.nxchat-newchat:hover { border-color: var(--brand, #0062ff); }
}
.nxchat-newchat > span:first-child { flex: 1; min-width: 0; }
.nxchat-newchat b { display: block; font-size: .88rem; }
.nxchat-newchat small { display: block; color: var(--muted); font-size: .75rem; }
.nxchat-newchat-go { color: var(--brand, #0062ff); font-size: 1.1rem; font-weight: 700; }
.nxchat-recent {
    display: grid; gap: .1rem; width: 100%; text-align: left;
    padding: .6rem .7rem; border-radius: var(--radius-md);
    border: 1px solid var(--line); background: transparent; font: inherit; cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
.nxchat-recent:hover { border-color: color-mix(in srgb, var(--brand, #0062ff) 40%, transparent); }
}
.nxchat-recent b { font-size: .84rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nxchat-recent small { color: var(--muted); font-size: .72rem; }
.nxchat-none { text-align: center; color: var(--muted); font-size: .82rem; padding: .75rem 0; }
.nxchat-back {
    align-self: flex-start; border: 0; background: transparent; cursor: pointer;
    color: var(--brand, #0062ff); font: inherit; font-size: .78rem; font-weight: 700;
    padding: 0 0 .4rem;
}
.nxchat-who { font-size: .7rem; color: var(--muted); margin-bottom: .1rem; }
.nxchat-composer[hidden] { display: none !important; }

/* ===========================================================================
   THEMED DIALOGS  (replaces window.confirm / prompt / alert)
   Built on <dialog>, so focus trapping, Esc and the top layer come for free.
   =========================================================================== */
.nxdlg {
    width: min(26rem, calc(100vw - 2rem));
    padding: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface);
    color: var(--text);
    box-shadow: 0 24px 60px rgba(18, 24, 38, .22);
}
.nxdlg::backdrop { background: rgba(10, 10, 10, .45); }

.nxdlg-head { padding: 1.1rem 1.25rem .35rem; }
.nxdlg-head strong { font-size: 1rem; font-weight: 800; }
.nxdlg-body { padding: 0 1.25rem 1rem; }
.nxdlg-body p { margin: .35rem 0 0; color: var(--muted); font-size: .88rem; line-height: 1.6; }

.nxdlg-input {
    width: 100%; margin-top: .85rem; resize: vertical;
    min-height: 4.5rem; padding: .6rem .75rem;
    border: 1px solid var(--line); border-radius: var(--radius-md);
    background: var(--bg); color: var(--text);
    font: inherit; font-size: .88rem; line-height: 1.5;
}
.nxdlg-input:focus {
    outline: none;
    border-color: color-mix(in srgb, var(--brand, #0062ff) 55%, transparent);
}

.nxdlg-actions {
    display: flex; justify-content: flex-end; gap: .5rem;
    padding: .85rem 1.25rem 1.1rem;
    border-top: 1px solid var(--line);
}

.nxdlg.is-danger .nxdlg-head strong { color: var(--red, #b4321e); }

@media (prefers-reduced-motion: no-preference) {
    .nxdlg[open] { animation: nxdlgIn .16s cubic-bezier(.22, 1, .36, 1); }
    @keyframes nxdlgIn {
        from { opacity: 0; transform: translateY(6px) scale(.98); }
        to { opacity: 1; transform: none; }

}

}

/* ---- Chat identity: Discord avatar for people, shield mark for staff ---- */
.nxchat-who, .chat-msg-who {
    display: flex; align-items: center; gap: .35rem;
}
/* Own messages sit right, but the avatar stays left of the name either way. */
.nxchat-msg.mine .nxchat-who, .chat-msg.mine .chat-msg-who { justify-content: flex-end; }
.nxchat-who b, .chat-msg-who b { font-weight: 700; }

.nxchat-who-av, .chat-msg-av {
    width: 1.35rem; height: 1.35rem; flex: 0 0 auto;
    border-radius: 999px; overflow: hidden;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: .6rem; font-weight: 800; line-height: 1;
    background: color-mix(in srgb, var(--brand) 14%, transparent);
    color: var(--brand);
}
.nxchat-who-av img, .chat-msg-av img { width: 100%; height: 100%; object-fit: cover; }

/* The staff mark carries the brand colour rather than a photo. */
.nxchat-who-av.is-admin, .chat-msg-av.is-admin {
    background: color-mix(in srgb, var(--brand) 12%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--brand) 32%, transparent);
}
.nxchat-who-av.is-admin svg, .chat-msg-av.is-admin svg {
    width: .95rem; height: .95rem; display: block;
}

/* The header mark is the logo itself, so it keeps its own colours rather than
   sitting on the translucent circle the initial fallback needs. */
.nxchat-avatar.is-brand { background: #fff; }
.nxchat-brandmark { width: 100%; height: 100%; object-fit: contain; padding: .15rem; }

/* Staff are shown by role, glowing so the visitor can tell them from a bot. */
.nxchat-admin-name {
    color: var(--brand);
    letter-spacing: .01em;
    text-shadow:
        0 0 4px color-mix(in srgb, var(--brand) 55%, transparent),
        0 0 10px color-mix(in srgb, var(--brand) 30%, transparent);
}
@media (prefers-reduced-motion: no-preference) {
    .nxchat-admin-name { animation: nxchat-admin-glow 2.6s ease-in-out infinite; }

}
@keyframes nxchat-admin-glow {
    0%, 100% { text-shadow: 0 0 4px color-mix(in srgb, var(--brand) 45%, transparent),
                            0 0 10px color-mix(in srgb, var(--brand) 22%, transparent); }
    50%      { text-shadow: 0 0 6px color-mix(in srgb, var(--brand) 70%, transparent),
                            0 0 16px color-mix(in srgb, var(--brand) 40%, transparent); }

}

/* ===========================================================================
   /features - the full capability list.
   Category cards carrying their own command list, then a plain grid for the
   things that are not commands at all.
   =========================================================================== */
.features-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: .75rem;
    margin: 2rem 0 2.75rem;
}
.features-stat {
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 1rem 1.1rem;
    background: var(--panel);
}
.features-stat b { display: block; font-size: 1.6rem; font-weight: 800; line-height: 1.1; }
.features-stat span { font-size: .78rem; color: var(--muted); }
.features-stat-free b { color: var(--brand); }

.features-band-head { margin: 3rem 0 1.25rem; }
.features-band-head h2 { font-size: 1.45rem; font-weight: 800; margin: 0 0 .3rem; }
.features-band-head p { color: var(--muted); font-size: .9rem; margin: 0; }

.features-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
    gap: 1rem;
}
.features-card {
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 1.25rem;
    background: var(--panel);
    display: flex;
    flex-direction: column;
    gap: .9rem;
}
.features-card-head { display: flex; gap: .75rem; align-items: flex-start; }
.features-card-head h3 { font-size: 1.02rem; font-weight: 800; margin: 0 0 .2rem; }
.features-card-head p { font-size: .82rem; color: var(--muted); margin: 0; }

.features-cmds { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.features-cmds li {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: baseline;
    gap: .5rem;
    font-size: .82rem;
    padding-top: .5rem;
    border-top: 1px solid var(--line);
}
.features-cmds li code {
    font-weight: 700;
    color: var(--brand);
    background: color-mix(in srgb, var(--brand) 9%, transparent);
    border-radius: var(--radius-sm);
    padding: .08rem .35rem;
    white-space: nowrap;
}
.features-cmds li span { color: var(--muted); }
.features-tag {
    font-style: normal; font-size: .66rem; font-weight: 800;
    white-space: nowrap; border-radius: 999px; padding: .1rem .45rem;
    background: color-mix(in srgb, var(--brand) 13%, transparent);
    color: var(--brand);
}
.features-tag-quiet {
    background: color-mix(in srgb, var(--muted) 12%, transparent);
    color: var(--muted);
}

.features-links { display: flex; flex-wrap: wrap; gap: .6rem; }
.features-link {
    display: inline-flex; align-items: center; gap: .5rem;
    border: 1px solid var(--line); border-radius: 999px;
    padding: .5rem .9rem; font-size: .85rem; font-weight: 700;
    background: var(--panel); text-decoration: none; color: inherit;
    transition: border-color .18s ease, transform .18s ease;
}
@media (hover: hover) and (pointer: fine) {
.features-link:hover {
    border-color: color-mix(in srgb, var(--brand) 42%, transparent);
    transform: translateY(-1px);
}
}
.features-link-go { color: var(--brand); }
@media (prefers-reduced-motion: reduce) {
    .features-link { transition: none; }
    @media (hover: hover) and (pointer: fine) {
.features-link:hover { transform: none; }
}

}

@media (max-width: 640px) {
    .features-stats { grid-template-columns: repeat(2, 1fr); }
    .features-card { padding: 1rem; }
    /* The action count would squeeze the description to nothing on a phone. */
    .features-cmds li { grid-template-columns: auto 1fr; }
    .features-cmds li .features-tag { grid-column: 2; justify-self: start; }

}
/* display:none rather than a class-specific value, so it works for both a
   table row and a grid card. */
.is-search-hidden { display: none !important; }

/* ---- Home: "Everything It Does" summary band ------------------------- */








/* Main action + side link: the white primary is the one button, "Browse all
   commands" is plain text with an arrow so the two never read as twins. */







/* Feature icon tiles: each card gets its own hue instead of the same theme
   gradient on every tile. --tile is cycled per card; icon colour leans toward
   the text colour so it stays readable on light and dark themes. */
.home-feature-grid > * { --tile: #f59e0b; }
.home-feature-grid > :nth-child(9n+2) { --tile: #38bdf8; }
.home-feature-grid > :nth-child(9n+3) { --tile: #34d399; }
.home-feature-grid > :nth-child(9n+4) { --tile: #a78bfa; }
.home-feature-grid > :nth-child(9n+5) { --tile: #fb7185; }
.home-feature-grid > :nth-child(9n+6) { --tile: #2dd4bf; }
.home-feature-grid > :nth-child(9n+7) { --tile: #fb923c; }
.home-feature-grid > :nth-child(9n+8) { --tile: #818cf8; }
.home-feature-grid > :nth-child(9n+9) { --tile: #a3e635; }
.home-feature-grid .home-feature-icon {
    background: color-mix(in srgb, var(--tile) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--tile) 34%, transparent);
    color: color-mix(in srgb, var(--tile) 82%, var(--text));
}




/* ===========================================================================
   Setup progress (server grid) and the "on but unfinished" banner.
   =========================================================================== */
.nxsetup {
    border: 1px solid var(--line); border-radius: var(--radius-md);
    padding: .7rem .8rem; display: grid; gap: .45rem;
    background: color-mix(in srgb, var(--brand) 4%, transparent);
}
.nxsetup.is-complete { background: transparent; }
.nxsetup-head {
    display: flex; align-items: center; justify-content: space-between;
    font-size: .74rem; font-weight: 700; color: var(--muted);
}
.nxsetup-head span { display: inline-flex; align-items: center; gap: .3rem; }
.nxsetup.is-complete .nxsetup-head { color: var(--brand); }
.nxsetup-head b { color: var(--brand); }
.nxsetup-bar {
    height: 5px; border-radius: 999px; overflow: hidden;
    background: color-mix(in srgb, var(--muted) 18%, transparent);
}
.nxsetup-bar span {
    display: block; height: 100%; border-radius: 999px;
    background: var(--brand); transition: width .5s ease;
}
.nxsetup-next {
    display: inline-flex; align-items: center; gap: .3rem;
    font-size: .74rem; font-weight: 700; color: var(--brand); text-decoration: none;
}
@media (hover: hover) and (pointer: fine) {
.nxsetup-next:hover { text-decoration: underline; }
}
.nxsetup-next.is-warn { color: #b45309; }

.setup-alert {
    border: 1px solid color-mix(in srgb, #f59e0b 45%, var(--line));
    background: color-mix(in srgb, #f59e0b 8%, transparent);
    border-radius: var(--radius-lg); margin: -1rem 0 1.5rem;
}

/* ===========================================================================
   Command palette (⌘K)
   =========================================================================== */
body.nxpal-open { overflow: hidden; }
.nxpal { position: fixed; inset: 0; z-index: 3000; }
.nxpal[hidden] { display: none; }
.nxpal-backdrop { position: absolute; inset: 0; background: rgba(10, 10, 10, .45); }
.nxpal-panel {
    position: relative; margin: 8vh auto 0; width: min(38rem, calc(100vw - 2rem));
    max-height: 74vh; display: flex; flex-direction: column;
    background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-lg);
    box-shadow: 0 24px 60px rgba(0, 0, 0, .22); overflow: hidden;
}
.nxpal-input-wrap {
    display: flex; align-items: center; gap: .6rem;
    padding: .85rem 1rem; border-bottom: 1px solid var(--line);
}
.nxpal-input-wrap svg { width: 1.1rem; height: 1.1rem; color: var(--muted); flex: none; }
.nxpal-input {
    flex: 1; min-width: 0; border: 0; background: transparent;
    font-size: 1rem; outline: none; color: inherit;
}
.nxpal-close { flex: none; display: inline-flex; align-items: center; justify-content: center; min-width: 32px; min-height: 32px; padding: 0; border: 0; background: transparent; color: var(--muted); cursor: pointer; }
.nxpal-x { display: none; font-size: 1.5rem; line-height: 1; }
/* Phones have no Esc key, and the panel covers nearly all of the backdrop. */
@media (pointer: coarse) {
    .nxpal-close { min-width: 40px; min-height: 40px; }
    .nxpal-close kbd { display: none; }
    .nxpal-x { display: inline; }
}
.nxpal kbd {
    font: inherit; font-size: .66rem; font-weight: 700;
    padding: .1rem .35rem; border-radius: var(--radius-sm);
    border: 1px solid var(--line); color: var(--muted); background: transparent;
}
.nxpal-results { overflow-y: auto; padding: .4rem; }
.nxpal-group {
    font-size: .66rem; font-weight: 800; text-transform: uppercase;
    letter-spacing: .05em; color: var(--muted); padding: .6rem .6rem .3rem;
}
.nxpal-row {
    display: flex; align-items: center; gap: .65rem;
    padding: .5rem .6rem; border-radius: var(--radius-md);
    text-decoration: none; color: inherit;
}
.nxpal-row.is-active { background: color-mix(in srgb, var(--brand) 12%, transparent); }
.nxpal-mark {
    width: 1.6rem; height: 1.6rem; flex: none; border-radius: var(--radius-sm);
    display: grid; place-items: center; overflow: hidden;
    font-size: .7rem; font-weight: 800;
    background: color-mix(in srgb, var(--brand) 14%, transparent); color: var(--brand);
}
.nxpal-mark img { width: 100%; height: 100%; object-fit: cover; }
.nxpal-text { min-width: 0; display: flex; flex-direction: column; }
.nxpal-text b { font-size: .87rem; font-weight: 700; }
.nxpal-text small { font-size: .7rem; color: var(--muted); }
.nxpal-none { padding: 1.5rem; text-align: center; color: var(--muted); font-size: .85rem; }
.nxpal-foot {
    display: flex; gap: 1rem; padding: .55rem 1rem;
    border-top: 1px solid var(--line); font-size: .7rem; color: var(--muted);
}
.nxpal-foot span { display: inline-flex; align-items: center; gap: .25rem; }
@media (max-width: 640px) {
    .nxpal-panel { margin-top: 4vh; max-height: 84vh; }
    .nxpal-foot { display: none; }

}

/* ===========================================================================
   Undo toast - a reversible delete beats a modal asking "are you sure".
   =========================================================================== */
.nxundo-stack {
    position: fixed; left: 50%; bottom: 1.25rem; transform: translateX(-50%);
    z-index: 3100; display: flex; flex-direction: column; gap: .5rem;
    width: min(24rem, calc(100vw - 2rem));
}
.nxundo {
    display: flex; align-items: center; gap: .75rem;
    padding: .7rem .8rem .7rem 1rem; border-radius: var(--radius-md);
    background: var(--panel); border: 1px solid var(--line);
    box-shadow: 0 12px 30px rgba(0, 0, 0, .18);
    font-size: .85rem;
    animation: nxundo-in .18s ease-out;
}
.nxundo-text { flex: 1; min-width: 0; }
.nxundo-undo {
    flex: none; border: 0; background: transparent; cursor: pointer;
    font: inherit; font-weight: 800; color: var(--brand); padding: .2rem .4rem;
}
@media (hover: hover) and (pointer: fine) {
.nxundo-undo:hover { text-decoration: underline; }
}
.nxundo-timer {
    flex: none; width: 1.5rem; height: 1.5rem; border-radius: 50%;
    display: grid; place-items: center; font-size: .66rem; font-weight: 800;
    color: var(--muted); border: 1px solid var(--line);
}
@keyframes nxundo-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } 
}
@media (prefers-reduced-motion: reduce) { .nxundo { animation: none; } 
}

/* The topbar's palette trigger. The shortcut hint hides where it would crowd. */
.topbar-search-btn { gap: .4rem; }
@media (max-width: 720px) { .topbar-search-btn span { display: none; } 
}

/* ===========================================================================
   Live Discord embed preview (welcome, leave, reviews).
   Deliberately dark: it mimics Discord, not the dashboard, so people can see
   what the message will actually look like where it lands.
   =========================================================================== */
.dc-preview {
    border-radius: 10px;
    background: #313338;
    padding: .9rem;
    transition: opacity .2s ease;
}
/* No dimming when the module is off: the badge already says so, and a faded
   preview read as a broken render rather than a state. */
.dc-preview-label {
    display: flex; align-items: center; justify-content: space-between;
    font-size: .68rem; font-weight: 800; text-transform: uppercase;
    letter-spacing: .05em; color: #b5bac1; margin-bottom: .6rem;
}

.dc-preview-row { display: flex; gap: .65rem; align-items: flex-start; }
.dc-preview-avatar {
    width: 2.2rem; height: 2.2rem; border-radius: 50%; flex: none;
    background: var(--brand); color: #fff;
    display: grid; place-items: center; font-weight: 800; font-size: .8rem;
    overflow: hidden;
}
.dc-preview-avatar img { width: 100%; height: 100%; object-fit: contain; padding: .12rem; }
.dc-preview-avatar:has(img) { background: #fff; }
.dc-preview-main { min-width: 0; flex: 1; }
.dc-preview-author { display: flex; align-items: center; gap: .4rem; margin-bottom: .25rem; }
.dc-preview-name { color: #f2f3f5; font-weight: 700; font-size: .85rem; }
.dc-preview-bot {
    background: #5865f2; color: #fff; font-size: .58rem; font-weight: 800;
    padding: .05rem .25rem; border-radius: 3px; text-transform: uppercase;
}
.dc-preview-time { color: #949ba4; font-size: .68rem; }

/* The embed itself: dark card with the accent stripe Discord draws. */
.dc-preview-embed {
    --dc-accent: #5865f2;
    background: #2b2d31;
    border-left: 4px solid var(--dc-accent);
    border-radius: 4px;
    padding: .7rem .8rem;
    max-width: 30rem;
}
.dc-preview-embed p { margin: 0; }
.dc-preview-title {
    color: #f2f3f5; font-weight: 700; font-size: .88rem; margin-bottom: .25rem;
    white-space: pre-wrap; word-break: break-word;
}
.dc-preview-body {
    color: #dbdee1; font-size: .82rem; line-height: 1.45;
    white-space: pre-wrap; word-break: break-word;
}
.dc-preview-embed .is-empty { color: #6d6f78; font-style: italic; }
.dc-preview-img {
    display: block; max-width: 100%; border-radius: 4px; margin-top: .6rem;
    max-height: 11rem; object-fit: cover;
}
.dc-preview-btn {
    display: inline-block; margin-top: .6rem;
    background: #4e5058; color: #fff; font-size: .78rem; font-weight: 600;
    padding: .35rem .8rem; border-radius: 3px; text-decoration: none;
}
.dc-preview-parts { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .5rem; }
.dc-preview-parts:empty { display: none; }
.dc-preview-parts .dc-preview-btn { display: inline-flex; align-items: center; gap: .3rem; margin-top: 0; }
.dc-preview-menu { flex: 1 1 100%; max-width: 26rem; padding: .5rem .7rem; border-radius: 4px; background: #1e1f22; color: #b5bac1; font-size: .8rem; }
.dc-preview-menu::after { content: "⌄"; float: right; }
.dc-preview-react { display: inline-flex; align-items: center; gap: .25rem; padding: .1rem .45rem; border: 1px solid #5865f2; border-radius: 8px; background: rgba(88, 101, 242, .15); color: #dbdee1; font-size: .78rem; }
.dc-preview-emoji { width: 1.1em; height: 1.1em; object-fit: contain; }
/* Thumbnail sits top-right of the embed body, the way Discord draws it. */
.dc-preview-embed-top { display: flex; gap: .8rem; align-items: flex-start; }
.dc-preview-embed-text { min-width: 0; flex: 1; }
.dc-preview-thumb {
    width: 4.5rem; height: 4.5rem; flex: none;
    border-radius: 4px; object-fit: cover;
}
.dc-preview-note {
    margin: .55rem 0 0; font-size: .7rem; color: #949ba4;
}

/* ---------------------------------------------------------------
   Documentation (/docs and /docs/:slug)
---------------------------------------------------------------- */
.docs-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 1rem;
    margin-top: 2rem;
}
.docs-card[hidden] { display: none; }
.docs-card {
    display: flex;
    flex-direction: column;
    gap: .4rem;
    padding: 1.35rem;
    border-radius: var(--radius-lg);
    text-decoration: none;
    color: inherit;
    border: 1px solid var(--line, rgba(148, 163, 184, .2));
    background: var(--surface, rgba(148, 163, 184, .04));
    transition: border-color .15s ease, transform .15s ease;
}
@media (hover: hover) and (pointer: fine) {
.docs-card:hover { border-color: color-mix(in srgb, var(--brand, #0062ff) 55%, transparent); transform: translateY(-2px); }
}
@media (prefers-reduced-motion: reduce) { @media (hover: hover) and (pointer: fine) {
.docs-card:hover { transform: none; }
} 
}
.docs-card-icon {
    height: 40px; width: 40px; border-radius: var(--radius-md);
    display: inline-flex; align-items: center; justify-content: center;
    background: color-mix(in srgb, var(--brand, #0062ff) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--brand, #0062ff) 30%, transparent);
    color: var(--brand, #0062ff);
    margin-bottom: .35rem;
}
.docs-card-title { font-weight: 800; font-size: 1.02rem; }
.docs-card-desc { font-size: .86rem; opacity: .68; line-height: 1.5; }
.docs-card-go {
    display: inline-flex; align-items: center; gap: .35rem;
    margin-top: .6rem; font-size: .82rem; font-weight: 700;
    color: color-mix(in srgb, var(--brand, #0062ff) 82%, var(--text, #0a0a0a));
}

.docs-cta {
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: 1rem;
    margin-top: 2.5rem; padding: 1.5rem;
    border-radius: var(--radius-lg);
    border: 1px solid var(--line, rgba(148, 163, 184, .2));
    background: color-mix(in srgb, var(--brand, #0062ff) 7%, transparent);
}
.docs-cta h2 { margin: 0 0 .25rem; font-size: 1.1rem; }
.docs-cta p { margin: 0; font-size: .88rem; opacity: .7; }

.docs-crumbs {
    display: flex; gap: .5rem; align-items: center;
    font-size: .84rem; opacity: .65; margin-bottom: 1.25rem;
}
.docs-crumbs a { color: inherit; }

.docs-layout { display: grid; grid-template-columns: 232px 1fr; gap: 2.5rem; align-items: start; }
.docs-side { position: sticky; top: 90px; max-height: calc(100vh - 110px); overflow-y: auto; scrollbar-width: thin; }
.docs-side-head {
    font-size: .72rem; text-transform: uppercase; letter-spacing: .08em;
    opacity: .72; font-weight: 800; margin: 0 0 .6rem;
}
.docs-side ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .15rem; }
.docs-side a {
    display: flex; align-items: center; gap: .55rem;
    padding: .5rem .65rem; border-radius: var(--radius-md);
    font-size: .86rem; text-decoration: none; color: inherit; opacity: .72;
}
.docs-side a i { height: 15px; width: 15px; flex-shrink: 0; }
@media (hover: hover) and (pointer: fine) {
.docs-side a:hover { background: rgba(148, 163, 184, .09); opacity: 1; }
}
.docs-side a.is-current {
    background: color-mix(in srgb, var(--brand, #0062ff) 14%, transparent);
    color: color-mix(in srgb, var(--brand, #0062ff) 82%, var(--text, #0a0a0a));
    opacity: 1; font-weight: 700;
}

.docs-body { min-width: 0; }
.docs-body-head { margin-bottom: 2rem; }
.docs-body-head h1 { margin: .5rem 0 .35rem; font-size: 2rem; }
.docs-body-head p { margin: 0; opacity: .7; font-size: .96rem; }
.docs-body-head .docs-byline { margin-top: .45rem; font-size: .84rem; color: var(--muted); }

.docs-section { margin-bottom: 2.25rem; }
.docs-section h2 { font-size: 1.15rem; margin: 0 0 .65rem; }
.docs-section h2 a { color: inherit; text-decoration: none; }
@media (hover: hover) and (pointer: fine) {
.docs-section h2 a:hover::after { content: ' #'; opacity: .35; }
}
.docs-section p { margin: 0 0 .75rem; line-height: 1.7; font-size: .93rem; opacity: .82; }

.docs-steps { margin: 0 0 .75rem; padding-inline-start: 1.15rem; display: flex; flex-direction: column; gap: .4rem; }
.docs-steps li { line-height: 1.6; font-size: .92rem; opacity: .82; }

.docs-defs { margin: .25rem 0 .75rem; display: flex; flex-direction: column; gap: .5rem; }
.docs-defs > div {
    padding: .75rem .9rem; border-radius: var(--radius-md);
    border: 1px solid var(--line, rgba(148, 163, 184, .16));
    background: rgba(148, 163, 184, .04);
}
.docs-defs dt { font-weight: 700; font-size: .87rem; margin-bottom: .15rem; }
.docs-defs dd { margin: 0; font-size: .85rem; opacity: .68; line-height: 1.55; }

.docs-note {
    display: flex; gap: .6rem; align-items: flex-start;
    padding: .8rem .95rem; border-radius: var(--radius-md);
    border: 1px solid color-mix(in srgb, var(--brand, #0062ff) 30%, transparent);
    background: color-mix(in srgb, var(--brand, #0062ff) 8%, transparent);
    font-size: .87rem !important; opacity: 1 !important;
}
.docs-note i { flex-shrink: 0; height: 17px; width: 17px; color: var(--brand, #0062ff); margin-top: .1rem; }

.docs-pager {
    display: flex; justify-content: space-between; gap: 1rem;
    margin-top: 3rem; padding-top: 1.5rem;
    border-top: 1px solid var(--line, rgba(148, 163, 184, .16));
}
.docs-pager-link {
    display: flex; flex-direction: column; gap: .15rem;
    padding: .85rem 1.1rem; border-radius: var(--radius-md);
    text-decoration: none; color: inherit;
    border: 1px solid var(--line, rgba(148, 163, 184, .2));
    max-width: 48%;
}
@media (hover: hover) and (pointer: fine) {
.docs-pager-link:hover { border-color: color-mix(in srgb, var(--brand, #0062ff) 55%, transparent); }
}
.docs-pager-next { text-align: end; margin-inline-start: auto; }
.docs-pager-link span { font-size: .74rem; opacity: .55; text-transform: uppercase; letter-spacing: .06em; }
.docs-pager-link strong { font-size: .92rem; }

@media (max-width: 900px) {
    .docs-layout { grid-template-columns: 1fr; gap: 1.5rem; }
    /* The topic list (100+ links) came first and pushed the article below the
       screen; on one column the article leads and the list follows it. */
    .docs-side { position: static; order: 2; max-height: none; }
    .docs-side ul { flex-direction: row; flex-wrap: wrap; }
    .docs-side a { border: 1px solid var(--line, rgba(148, 163, 184, .18)); }

}

/* ---------------------------------------------------------------
   Language switcher (partials/langSwitcher.ejs)
   A <details> menu so it works without JavaScript.
---------------------------------------------------------------- */
.langsw { position: relative; flex: none; }
.langsw > summary {
    display: inline-flex; align-items: center; gap: .35rem;
    padding: .4rem .6rem; border-radius: var(--radius-md); cursor: pointer;
    border: 1px solid var(--line, rgba(148, 163, 184, .22));
    font-size: .8rem; font-weight: 700; list-style: none;
    color: inherit; white-space: nowrap;
}
.langsw > summary::-webkit-details-marker { display: none; }
@media (hover: hover) and (pointer: fine) {
.langsw > summary:hover { background: rgba(148, 163, 184, .12); }
}
.langsw > summary:focus-visible { outline: 2px solid var(--brand, #0062ff); outline-offset: 2px; }
/* SVG flags (public/flags): emoji flags show as "GB" letters on Windows. */
.langsw-flag { display: block; flex: none; width: 20px; height: 14px; border-radius: 3px; object-fit: cover; box-shadow: 0 0 0 1px color-mix(in srgb, var(--text) 14%, transparent); }
i.langsw-flag, svg.langsw-flag { width: 16px; height: 16px; box-shadow: none; border-radius: 0; }
.langsw-tick { width: 1rem; height: 1rem; }
.langsw-code { letter-spacing: .02em; }

.langsw-menu {
    position: absolute; top: calc(100% + .4rem); inset-inline-end: 0; z-index: 60;
    min-width: 216px; max-height: 60vh; overflow-y: auto;
    padding: .35rem; border-radius: var(--radius-lg);
    border: 1px solid var(--line, rgba(148, 163, 184, .22));
    background: var(--panel-strong, var(--bg, #fff));
    box-shadow: 0 18px 44px rgba(0, 0, 0, .22);
}
/* In right-to-left pages the menu hangs off the other edge. */
.langsw-head {
    margin: .2rem .5rem .35rem; font-size: .68rem; font-weight: 800;
    text-transform: uppercase; letter-spacing: .07em; opacity: .72;
}
.langsw-menu a {
    display: flex; align-items: center; gap: .55rem;
    padding: .5rem .6rem; border-radius: var(--radius-md);
    font-size: .86rem; text-decoration: none; color: inherit;
}
@media (hover: hover) and (pointer: fine) {
.langsw-menu a:hover { background: rgba(148, 163, 184, .12); }
}
.langsw-menu a.is-current { background: color-mix(in srgb, var(--brand, #0062ff) 16%, transparent); font-weight: 700; }
.langsw-name { flex: 1; }
.langsw-tick { opacity: .7; }

@media (max-width: 640px) {
    .langsw-code { display: none; }
    .langsw-menu { position: fixed; inset-inline-end: .75rem; inset-inline-start: auto; top: 62px; }

}

/* In the top bar it stands beside the Vote pill and the theme button, so it
   borrows their height and pill shape instead of the boxy default. */
.topbar-langsw { display: inline-flex; flex: none; }
.topbar-langsw .langsw > summary {
    height: 2.125rem;
    padding: 0 .7rem;
    border-radius: 999px;
}

/* ---------------------------------------------------------------
   Home: "Make it yours" branding showcase.
   Everything tinted is driven by --nxbrand, which the swatch buttons
   rewrite, so one variable recolours the whole preview.
---------------------------------------------------------------- */
.nxbrand-section { --nxbrand: #DC2626; }

.nxbrand-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    gap: 2.5rem;
    align-items: center;
    margin-top: 2rem;
}

.nxbrand-label {
    font-size: .72rem; font-weight: 800; letter-spacing: .09em;
    text-transform: uppercase; opacity: .72; margin: 0 0 .6rem;
}
.nxbrand-swatches { display: flex; flex-wrap: wrap; gap: .55rem; margin-bottom: 1.75rem; }
.nxbrand-swatch {
    height: 38px; width: 38px; border-radius: var(--radius-md); cursor: pointer;
    background: var(--swatch);
    border: 2px solid transparent;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, .1) inset;
    transition: transform .15s ease, box-shadow .15s ease;
}
@media (hover: hover) and (pointer: fine) {
.nxbrand-swatch:hover { transform: translateY(-2px); }
}
.nxbrand-swatch.is-active {
    box-shadow: 0 0 0 3px var(--bg, #fff), 0 0 0 5px var(--swatch);
}
.nxbrand-swatch:focus-visible { outline: 2px solid var(--text); outline-offset: 3px; }

.nxbrand-points { list-style: none; margin: 0 0 1.75rem; padding: 0; display: flex; flex-direction: column; gap: .8rem; }
.nxbrand-points li { display: flex; gap: .7rem; align-items: flex-start; font-size: .93rem; line-height: 1.55; }
.nxbrand-points i { color: var(--nxbrand); flex-shrink: 0; margin-top: .2rem; }
.nxbrand-points strong { font-weight: 700; }
.nxbrand-actions { display: flex; gap: .7rem; flex-wrap: wrap; }

/* --- preview column --- */
.nxbrand-preview { display: flex; flex-direction: column; gap: 1.1rem; min-width: 0; }

.nxbrand-discord {
    background: #1e1f22; border-radius: 16px; padding: 1.1rem 1.15rem;
    box-shadow: 0 18px 44px rgba(0, 0, 0, .22);
}
.nxbrand-msg { display: flex; gap: .75rem; }
.nxbrand-avatar {
    height: 38px; width: 38px; border-radius: 50%; flex-shrink: 0;
    object-fit: cover; display: block;
    /* The ring picks up the brand colour so the avatar still reacts to a swatch. */
    box-shadow: 0 0 0 2px var(--nxbrand);
}
.nxbrand-msg-body { min-width: 0; flex: 1; }
.nxbrand-msg-name { margin: 0 0 .45rem; font-size: .88rem; font-weight: 700; color: #f2f3f5; }
.nxbrand-msg-name span {
    margin-inline-start: .4rem; padding: .05rem .3rem; border-radius: var(--radius-sm);
    background: #5865f2; color: #fff; font-size: .62rem; vertical-align: middle;
}
.nxbrand-embed { display: flex; border-radius: 6px; overflow: hidden; background: #2b2d31; }
.nxbrand-embed-bar { width: 4px; background: var(--nxbrand); flex-shrink: 0; }
.nxbrand-embed-body { padding: .8rem .9rem; min-width: 0; }
.nxbrand-embed-title { margin: 0 0 .3rem; font-size: .92rem; font-weight: 700; color: #f2f3f5; }
.nxbrand-embed-text { margin: 0 0 .7rem; font-size: .82rem; color: #b5bac1; line-height: 1.5; }
.nxbrand-embed-btns { display: flex; gap: .4rem; }
.nxbrand-btn {
    padding: .3rem .7rem; border-radius: var(--radius-sm); font-size: .76rem; font-weight: 600;
    background: #4e5058; color: #fff;
}
.nxbrand-btn.is-brand { background: var(--nxbrand); }

.nxbrand-invoice {
    position: relative; overflow: hidden;
    background: #ffffff; color: #111827; border-radius: var(--radius-lg); padding: 1.1rem 1.2rem 1.2rem 1.5rem;
    box-shadow: 0 18px 44px rgba(0, 0, 0, .18);
}
.nxbrand-inv-spine { position: absolute; inset-block: 0; inset-inline-start: 0; width: 8px; background: var(--nxbrand); }
.nxbrand-inv-head { display: flex; align-items: center; gap: .7rem; margin-bottom: .9rem; }
.nxbrand-inv-logo {
    height: 34px; width: 34px; border-radius: var(--radius-md); flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: color-mix(in srgb, var(--nxbrand) 18%, #fff);
    border: 1px solid color-mix(in srgb, var(--nxbrand) 35%, transparent);
    /* currentColor drives the mark, so it follows the brand swatch. */
    color: var(--nxbrand);
}
.nxbrand-inv-logo svg { width: 20px; height: 20px; display: block; }
.nxbrand-inv-brand { margin: 0; font-size: .95rem; font-weight: 800; letter-spacing: .01em; }
.nxbrand-inv-tag { margin: 0; font-size: .72rem; color: #6b7280; }
.nxbrand-inv-word { margin: 0 0 0 auto; font-size: 1.05rem; font-weight: 800; letter-spacing: .02em; }
.nxbrand-inv-band {
    display: grid; grid-template-columns: 1fr auto auto; gap: 1rem;
    background: var(--nxbrand); color: #fff;
    padding: .45rem .7rem; border-radius: var(--radius-sm) var(--radius-sm) 0 0;
    font-size: .66rem; font-weight: 800; letter-spacing: .06em;
}
.nxbrand-inv-row {
    display: grid; grid-template-columns: 1fr auto auto; gap: 1rem;
    padding: .6rem .7rem; font-size: .82rem; border-bottom: 1px solid #e5e7eb;
}
.nxbrand-inv-total {
    display: flex; align-items: center; justify-content: space-between;
    margin-top: .7rem; padding: .6rem .8rem; border-radius: var(--radius-md);
    background: color-mix(in srgb, var(--nxbrand) 10%, transparent);
    font-size: .72rem; font-weight: 800; letter-spacing: .05em;
    color: color-mix(in srgb, var(--nxbrand) 78%, #111827);
}
.nxbrand-inv-total strong { font-size: 1.1rem; color: #111827; letter-spacing: 0; }

@media (max-width: 900px) {
    .nxbrand-grid { grid-template-columns: 1fr; gap: 1.75rem; }

}
@media (prefers-reduced-motion: reduce) {
    .nxbrand-swatch { transition: none; transform: none; }
@media (hover: hover) and (pointer: fine) {
.nxbrand-swatch:hover { transition: none; transform: none; }
}

}

/* Real invoice screenshots under the branding showcase. */
.nxbrand-invoices { margin-top: 3rem; }
.nxbrand-invoices-head { text-align: center; max-width: 62ch; margin: 0 auto 1.75rem; }
.nxbrand-invoices-head h3 { font-size: 1.35rem; margin: 0 0 .5rem; }
.nxbrand-invoices-head p { margin: 0; color: var(--muted); line-height: 1.6; font-size: .95rem; }

/* The invoices are white images (that is what Discord gets), so they sit on an
   always-dark stage, a little dimmed and fanned, instead of two bright sheets. */
.nxbrand-invoice-shots {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.75rem;
    align-items: start;
    padding: clamp(1.25rem, 4vw, 2.75rem);
    border-radius: 22px;
    border: 1px solid rgba(255, 255, 255, .07);
    background:
        radial-gradient(70% 55% at 50% 0%, color-mix(in srgb, var(--nxbrand) 24%, transparent), transparent 70%),
        #141519;
}
.nxbrand-invoice-shots figure { margin: 0; transition: transform .5s cubic-bezier(.22, 1, .36, 1); }
.nxbrand-invoice-shots img {
    display: block; width: 100%; height: auto;
    border-radius: var(--radius-md);
    filter: brightness(.9) saturate(.95);
    box-shadow: 0 24px 50px -12px rgba(0, 0, 0, .7), 0 0 0 1px rgba(255, 255, 255, .06);
    transition: filter .3s ease;
}
.nxbrand-invoice-shots figure:hover img { filter: none; }
.nxbrand-invoice-shots figcaption {
    display: flex; align-items: center; gap: .55rem; flex-wrap: wrap;
    margin-top: .8rem; font-size: .86rem; color: #a1a1aa;
}
/* Side by side: fanned and overlapping a little; hover straightens one and
   brings it to the front. */
@media (min-width: 640px) {
    .nxbrand-invoice-shots { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0; }
    .nxbrand-invoice-shots figure { position: relative; }
    .nxbrand-invoice-shots figure:first-child { transform: translateX(4%) rotate(-2.5deg); z-index: 1; }
    .nxbrand-invoice-shots figure:last-child { transform: translateX(-4%) translateY(1.5rem) rotate(2deg); }
    .nxbrand-invoice-shots figure:last-child img { filter: brightness(.78) saturate(.9); }
    @media (hover: hover) and (pointer: fine) {
.nxbrand-invoice-shots figure:hover { transform: translateY(-.4rem) rotate(0); z-index: 2; }
}
    .nxbrand-invoice-shots figure:hover img { filter: none; }
}
@media (prefers-reduced-motion: reduce) {
    .nxbrand-invoice-shots figure { transition: none; }
}
.nxbrand-invoice-shots .nxbrand-pill { color: color-mix(in srgb, var(--nxbrand) 55%, #fff); }
.nxbrand-pill {
    padding: .2rem .6rem; border-radius: 99px;
    background: color-mix(in srgb, var(--nxbrand) 14%, transparent);
    color: color-mix(in srgb, var(--nxbrand) 78%, var(--text));
    font-size: .74rem; font-weight: 800; letter-spacing: .03em;
}

/* Colour picker beside a hex field. `.field` sets width:100%%, which a utility
   class cannot beat, so the swatch needs its own rule to stay square. */
.color-swatch {
    inline-size: 56px;
    flex: 0 0 56px;
    block-size: 44px;
    padding: 3px;
    cursor: pointer;
}
.color-swatch::-webkit-color-swatch-wrapper { padding: 0; }
.color-swatch::-webkit-color-swatch { border: 0; border-radius: var(--radius-sm); }
.color-swatch::-moz-color-swatch { border: 0; border-radius: var(--radius-sm); }

/* ---------------------------------------------------------------- bidi ----
   Each text element takes its direction from its own content, the way dir="auto"
   does, so an Arabic or Hebrew string reads right-to-left inside the left-to-right
   page instead of having its punctuation and numbers pushed to the wrong end.

   This is what lets Arabic read correctly inside the left-to-right layout (see
   layoutDirection in dashboard/lib/i18n.js), and an Arabic name inside an English
   page. It changes ordering only - no boxes move - so it is inert for plain
   English.                                                                       */
h1, h2, h3, h4, h5, h6,
p, li, dd, dt, td, th,
label, legend, summary, figcaption, blockquote,
button, a, option, .badge, .muted, .chip, .server-chip,
input, textarea, select {
    unicode-bidi: plaintext;
}

/* ----------------------------------------------------------------- rtl ----
   Inactive while RTL_LAYOUT_READY is false in dashboard/lib/i18n.js. Flex, grid and
   text mirror on their own under <html dir="rtl">; these are the few things that do
   not. Everything here is scoped to [dir="rtl"], so an ltr page is untouched.

   `scale`, not `transform`: it composes with the hover nudges already on these icons,
   and flips the nudge along with the arrow.                                       */
[dir="rtl"] :is(.lucide-arrow-right, .lucide-arrow-left, .lucide-chevron-right, .lucide-chevron-left) {
    scale: -1 1;
}
/* Code, ids and commands read left to right in every language. */
[dir="rtl"] :is(code, kbd, samp, pre) { direction: ltr; unicode-bidi: isolate; }
[dir="rtl"] pre { text-align: left; }
/* Sliders and seek bars: their JS measures from the left edge and their fill starts
   there. */
[dir="rtl"] :is(input[type="range"], .tv-segs, .nx-np-bar, .nx-sp-line) { direction: ltr; }
/* Loops that slide by -50% need their copies laid out left to right, and the flow
   editor stores node positions from the left. Their contents still read rtl. */
[dir="rtl"] :is(.rv-wall, .wsl-car, .cc-canvas) { direction: ltr; }
[dir="rtl"] :is(.rv-set, .cc-canvas) > * { direction: rtl; }
/* Tables and blocks that hardcode a left edge. `html` lifts the rule over `.x th`. */
html[dir="rtl"] :is(th, td, .tool-result-row, .home-limited, .nx-custombot-text, .im-compact, .te-mp-box) { text-align: right; }
html[dir="rtl"] .tool-copy-label { margin-left: 0; margin-right: auto; }
/* The dashboard sidebar sits on the right, so its edge line and its phone drawer do too.
   The !important and `.dashboard-root` match the rules they override. */
html[dir="rtl"] .app-sidebar { border-right: 0 !important; border-left: 1px solid var(--sb-edge) !important; }
@media (max-width: 920px) {
    html[dir="rtl"] .dashboard-root .app-sidebar { inset: 0 0 0 auto; transform: translateX(102%); }
    html[dir="rtl"] .dashboard-root.sidebar-open .app-sidebar { transform: none; }
}

/* ── Top bar: text nav ───────────────────────────────────────────────────────
   Destinations are words. The nine unlabelled icon buttons that used to fill
   this row are now two named menus, Resources and Support, so the bar can be
   read instead of hovered. Markup: views/layout.ejs; the phone treatment lives
   in mobile-layout.css, which reuses the same #topbarMore <details>. */
.topnav {
    display: flex;
    align-items: center;
    gap: clamp(0.5rem, 1.4vw, 1.25rem);
    min-width: 0;
}

/* Custom Bot | Dashboard switch: one brand-outlined pill beside the account, the
   current product filled. Reads as "which app am I in", not as two more links. */
.app-switch {
    display: inline-flex;
    flex: none;
    padding: 2px;
    border: 2px solid var(--brand, #0062ff);
    border-radius: var(--radius-md);
    background: var(--panel, #fff);
    box-shadow:
        0 0 0 3px rgba(var(--blue-rgb, 0, 98, 255), .14),
        0 0 14px rgba(var(--blue-rgb, 0, 98, 255), .6),
        0 0 32px rgba(var(--blue-rgb, 0, 98, 255), .3);
    transition: box-shadow .2s ease;
}
@media (hover: hover) and (pointer: fine) {
.app-switch:hover {
    box-shadow:
        0 0 0 3px rgba(var(--blue-rgb, 0, 98, 255), .2),
        0 0 16px rgba(var(--blue-rgb, 0, 98, 255), .65),
        0 0 40px rgba(var(--blue-rgb, 0, 98, 255), .35);
}
}
.app-switch-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    height: 2.125rem;
    padding: 0 0.9rem;
    border-radius: var(--radius-md);
    color: var(--text);
    font-size: 0.9375rem;
    font-weight: 800;
    line-height: 1;
    white-space: nowrap;
    text-decoration: none;
    transition: background .14s ease, color .14s ease;
}
@media (hover: hover) and (pointer: fine) {
.app-switch-btn:hover { background: var(--hover, rgba(0, 98, 255, .08)); }
}
.app-switch-btn.is-active {
    color: #fff;
    background: linear-gradient(135deg, var(--brand, #0062ff), var(--brand-2, var(--brand, #0062ff)));
}
@media (hover: hover) and (pointer: fine) {
.app-switch-btn.is-active:hover {
    color: #fff;
    background: linear-gradient(135deg, var(--brand, #0062ff), var(--brand-2, var(--brand, #0062ff)));
}
}
.app-switch-btn svg { flex: none; }
/* Off both products (support, docs, articles...) nothing is "current", so the
   shared pill reads as one broken button. Split it into two outlined buttons. */
.app-switch.is-split { padding: 0; border: 0; background: transparent; box-shadow: none; gap: .5rem; }
.app-switch.is-split .app-switch-btn {
    border: 2px solid var(--brand, #0062ff);
    border-radius: var(--radius-md);
    color: #fff;
    background: linear-gradient(135deg, var(--brand, #0062ff), var(--brand-2, var(--brand, #0062ff)));
    box-shadow:
        0 0 14px rgba(var(--blue-rgb, 0, 98, 255), .6),
        0 0 32px rgba(var(--blue-rgb, 0, 98, 255), .3),
        inset 0 0 10px rgba(var(--blue-rgb, 0, 98, 255), .14);
    transition: box-shadow .2s ease, background .14s ease, color .14s ease, transform .14s ease;
}
@media (hover: hover) and (pointer: fine) {
.app-switch.is-split .app-switch-btn:hover {
    transform: translateY(-1px);
    color: #fff;
    background: linear-gradient(135deg, var(--brand, #0062ff), var(--brand-2, var(--brand, #0062ff)));
    filter: brightness(1.08);
    box-shadow:
        0 0 20px rgba(var(--blue-rgb, 0, 98, 255), .85),
        0 0 48px rgba(var(--blue-rgb, 0, 98, 255), .45),
        inset 0 0 12px rgba(var(--blue-rgb, 0, 98, 255), .22);
}
}
.app-switch .app-switch-btn svg { filter: drop-shadow(0 0 4px rgba(var(--blue-rgb, 0, 98, 255), .6)); }
.app-switch.is-split .app-switch-btn span { text-shadow: 0 0 8px rgba(0, 0, 0, .25); }
@media (prefers-reduced-motion: reduce) {
    .app-switch, .app-switch.is-split .app-switch-btn { transition: none; }
    @media (hover: hover) and (pointer: fine) {
.app-switch.is-split .app-switch-btn:hover { transform: none; }
}
}

.topnav-link {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.5rem 0.15rem;
    border: 0;
    border-bottom: 2px solid transparent;
    background: none;
    color: var(--muted);
    font-family: inherit;
    font-size: 0.875rem;
    font-weight: 700;
    line-height: 1.2;
    /* A nav link is a label, not a paragraph: "Custom Bot" wrapping used to drag
       the whole header 20px taller. */
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    transition: color .14s ease, border-color .14s ease;
}

.topnav-link:focus-visible {
    color: var(--text);
}
@media (hover: hover) and (pointer: fine) {
.topnav-link:hover {
    color: var(--text);
}
}

.topnav-link.is-active {
    color: var(--text);
    border-bottom-color: var(--brand, #0062ff);
}

.topnav-caret {
    width: 0.875rem;
    height: 0.875rem;
    flex: none;
    opacity: .7;
    transition: transform .16s ease;
}

.topnav-group {
    position: relative;
    flex: none;
}

.topnav-group > summary {
    list-style: none;
}

.topnav-group > summary::-webkit-details-marker {
    display: none;
}

.topnav-group[open] > summary {
    color: var(--text);
}

.topnav-group[open] .topnav-caret {
    transform: rotate(180deg);
}

.topnav-menu {
    position: absolute;
    top: calc(100% + 0.55rem);
    inset-inline-start: 0;
    z-index: 86;
    display: grid;
    gap: 1px;
    min-width: 14rem;
    padding: 0.375rem;
    background: var(--panel, #fff);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    box-shadow: 0 1px 2px rgba(17, 17, 17, .05), 0 18px 38px -18px rgba(17, 17, 17, .38);
    animation: topnav-menu-in .13s ease-out;
}

@keyframes topnav-menu-in {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .topnav-menu { animation: none; }
    .topnav-caret { transition: none; }
}

.topnav-menu-head {
    padding: 0.45rem 0.55rem 0.3rem;
    color: var(--muted);
    font-size: 0.625rem;
    font-weight: 800;
    letter-spacing: .09em;
    text-transform: uppercase;
}

.topnav-menu a {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.55rem;
    border-radius: var(--radius-md);
    color: var(--text);
    font-size: 0.875rem;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
}

.topnav-menu a:focus-visible {
    background: var(--hover, rgba(0, 98, 255, .08));
}
@media (hover: hover) and (pointer: fine) {
.topnav-menu a:hover {
    background: var(--hover, rgba(0, 98, 255, .08));
}
}

.topnav-menu a > svg,
.topnav-menu a > i {
    width: 1rem;
    height: 1rem;
    flex: none;
    color: var(--muted);
}

.topnav-menu a:hover > svg,
.topnav-menu a:hover > i {
    color: var(--brand, #0062ff);
}

/* The outward arrow on a link that leaves the site (the Discord server). */
.topnav-menu-out {
    margin-inline-start: auto;
    width: 0.75rem;
    height: 0.75rem;
    opacity: .55;
}

/* ── Superuser-style chrome (2026-09-13) ─────────────────────────────────────
   Nav links sit in one frosted pill; every primary button is an inverted pill
   (white on dark themes, dark on the light one); the hero mesh drifts. */
@media (min-width: 1181px) {
    .topbar .topnav {
        gap: .15rem;
        padding: .3rem .45rem;
        border: 1px solid color-mix(in srgb, var(--text) 10%, transparent);
        border-radius: 999px;
        background: color-mix(in srgb, var(--surface) 62%, transparent);
        -webkit-backdrop-filter: blur(16px) saturate(1.3);
        backdrop-filter: blur(16px) saturate(1.3);
        box-shadow: 0 6px 24px rgba(0, 0, 0, .12), inset 0 1px 0 rgba(255, 255, 255, .06);
    }
    .topbar .topnav-link,
    .topbar .topnav-group > summary.topnav-link {
        padding: .5rem .85rem;
        border-bottom: 0;
        border-radius: 999px;
        transition: color .14s ease, background .14s ease;
    }
    .topbar .topnav-link:focus-visible,
.topbar .topnav-link.is-active {
        border-bottom-color: transparent;
        background: color-mix(in srgb, var(--text) 9%, transparent);
    }
@media (hover: hover) and (pointer: fine) {
.topbar .topnav-link:hover {
        border-bottom-color: transparent;
        background: color-mix(in srgb, var(--text) 9%, transparent);
    }
}
}

.btn.btn-primary,
.nx-btn-primary {
    background: var(--text) !important;
    color: var(--bg) !important;
    border: 1px solid transparent !important;
    box-shadow: 0 10px 28px rgba(0, 0, 0, .22) !important;
    animation: none !important;
    transition: transform .18s ease, box-shadow .18s ease, filter .18s ease;
}
.btn.btn-primary:focus-visible,
.nx-btn-primary:focus-visible {
    background: var(--text) !important;
    color: var(--bg) !important;
    transform: translateY(-1px);
    filter: brightness(.94);
    box-shadow: 0 14px 34px rgba(0, 0, 0, .28) !important;
}
@media (hover: hover) and (pointer: fine) {
.btn.btn-primary:hover,
.nx-btn-primary:hover {
    background: var(--text) !important;
    color: var(--bg) !important;
    transform: translateY(-1px);
    filter: brightness(.94);
    box-shadow: 0 14px 34px rgba(0, 0, 0, .28) !important;
}
}
.btn.btn-primary:active,
.nx-btn-primary:active { transform: translateY(0); }
.btn.btn-primary svg,
.nx-btn-primary svg { color: inherit; }

/* The rainbow mesh slowly breathes instead of sitting still. */
@keyframes nx-mesh-drift {
    0% { background-position: 0% 0%, 0% 0%, 100% 0%, 60% 50%, 25% 60%, 0 0; }
    50% { background-position: 0% 0%, 8% 6%, 92% 4%, 54% 44%, 32% 66%, 0 0; }
    100% { background-position: 0% 0%, 0% 0%, 100% 0%, 60% 50%, 25% 60%, 0 0; }
}
.nx-hero,
.home-hero {
    background-size: 100% 100%, 130% 130%, 130% 130%, 140% 140%, 140% 140%, auto;
    animation: nx-mesh-drift 18s ease-in-out infinite;
}

/* Rainbow card: closing CTAs, the "can't find your server" note, the article,
   tool, docs and tutorial call-outs all share it. */
.home-cta.nx-cta,
.server-missing-note,
.article-cta,
.docs-cta {
    position: relative;
    overflow: hidden;
    border: 0;
    border-radius: var(--radius-lg);
    background:
        radial-gradient(60% 80% at 8% 30%, #e8a02a 0%, rgba(232, 160, 42, 0) 60%),
        radial-gradient(50% 70% at 40% 80%, #3b5bff 0%, rgba(59, 91, 255, 0) 60%),
        radial-gradient(55% 75% at 78% 20%, #b33cf0 0%, rgba(179, 60, 240, 0) 62%),
        radial-gradient(45% 60% at 60% 40%, #d0a4f2 0%, rgba(208, 164, 242, 0) 60%),
        linear-gradient(120deg, #e8a02a, #b06ac8 45%, #6f3bff 75%, #a63cf0);
    background-size: 160% 160%, 160% 160%, 160% 160%, 160% 160%, 100% 100%;
    animation: nx-cta-drift 10s ease-in-out infinite alternate;
}
.home-cta.nx-cta {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 22px;
    min-height: 320px;
}
.home-cta.nx-cta .home-cta-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: .75rem; width: 100%; }
@keyframes nx-cta-drift {
    /* Same spots as the static card, each bloom wobbling a little around its home. */
    0% { background-position: 0% 30%, 40% 80%, 78% 20%, 60% 40%, 0 0; background-size: 160% 160%, 160% 160%, 160% 160%, 160% 160%, 100% 100%; }
    50% { background-position: 18% 45%, 25% 62%, 92% 38%, 45% 58%, 0 0; background-size: 175% 175%, 150% 150%, 172% 172%, 150% 150%, 100% 100%; }
    100% { background-position: 6% 12%, 55% 95%, 65% 5%, 75% 25%, 0 0; background-size: 150% 150%, 172% 172%, 155% 155%, 170% 170%, 100% 100%; }
}
.home-cta.nx-cta h2 {
    max-width: 14ch;
    margin: 0 auto;
    color: #fff;
    font-size: clamp(30px, 5vw, 56px);
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1.05;
    text-shadow: 0 2px 24px rgba(0, 0, 0, .18);
}
.home-cta.nx-cta .btn.btn-primary,
.server-missing-note .btn.btn-primary {
    background: #f4f4f4 !important;
    color: #101011 !important;
    font-size: 1.05rem;
    padding: .9rem 1.5rem;
}
.home-cta.nx-cta .btn.btn-primary svg,
.server-missing-note .btn.btn-primary svg { width: 1.1rem; height: 1.1rem; }
/* Servers page note, same card: centred title, body, one white button. */
.server-missing-note {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 1rem;
    padding: clamp(28px, 5vw, 48px) clamp(20px, 4vw, 40px);
}
.server-missing-note .server-missing-body { max-width: 60ch; }
.server-missing-note .server-missing-body h2 {
    margin: 0 0 .5rem;
    color: #fff;
    font-size: clamp(24px, 3.4vw, 36px);
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1.1;
    text-shadow: 0 2px 24px rgba(0, 0, 0, .18);
}
.server-missing-note .server-missing-body p { color: rgba(255, 255, 255, .86); font-size: .95rem; }
.server-missing-note .server-missing-action { white-space: normal; }
@media (max-width: 720px) {
    .server-missing-note { border-radius: var(--radius-lg); }
    .home-cta.nx-cta { border-radius: var(--radius-lg); min-height: 260px; }
    .home-cta.nx-cta .btn.btn-primary, .server-missing-note .btn.btn-primary { width: 100%; max-width: 22rem; justify-content: center; }
}
/* Article / tool / docs / tutorial call-outs: same card, centred. */
.article-cta,
.docs-cta {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 1.1rem;
    padding: clamp(28px, 5vw, 48px) clamp(20px, 4vw, 40px);
}
.article-cta > div,
.docs-cta > div { max-width: 60ch; }
.article-cta strong,
.docs-cta h2 {
    display: block;
    margin: 0 0 .5rem;
    color: #fff;
    font-size: clamp(22px, 3vw, 32px);
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1.1;
    text-shadow: 0 2px 24px rgba(0, 0, 0, .18);
}
.article-cta p,
.docs-cta p { margin: 0; color: rgba(255, 255, 255, .86); font-size: .95rem; opacity: 1; }
.article-cta .btn.btn-primary,
.docs-cta .btn.btn-primary {
    background: #f4f4f4 !important;
    color: #101011 !important;
    font-size: 1.05rem;
    padding: .9rem 1.5rem;
}
.tut-cta-actions,
.home-cta.nx-cta .home-cta-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: .75rem; }
/* A second, quieter button on the rainbow: frosted white outline. */
.home-cta.nx-cta .btn.btn-secondary,
.docs-cta .btn.btn-secondary,
.article-cta .btn.btn-secondary {
    background: rgba(255, 255, 255, .14) !important;
    border: 1px solid rgba(255, 255, 255, .4) !important;
    color: #fff !important;
    font-size: 1.05rem;
    padding: .9rem 1.5rem;
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}
@media (hover: hover) and (pointer: fine) {
.home-cta.nx-cta .btn.btn-secondary:hover,
.docs-cta .btn.btn-secondary:hover,
.article-cta .btn.btn-secondary:hover { background: rgba(255, 255, 255, .24) !important; }
}
@media (max-width: 720px) {
    .article-cta, .docs-cta { border-radius: var(--radius-lg); }
    .article-cta .btn, .docs-cta .btn, .home-cta.nx-cta .btn { width: 100%; max-width: 22rem; justify-content: center; }
}
@media (prefers-reduced-motion: reduce) {
    .nx-hero, .home-hero, .home-cta.nx-cta, .server-missing-note, .article-cta, .docs-cta { animation: none; }
}

/* Footer: brand + tagline on the left, link columns on the right, then a
   divider with the copyright and icon links. Same partial on every site page. */
.site-footer { margin-top: 40px; color: var(--muted); }
/* Same width formula as .home-section / .home-cta, so the edges line up with the cards above. */
.site-footer-inner { width: min(1440px, calc(100% - 44px)); margin: 0 auto; padding: 8px 0 24px; }
/* The home CTA card already ends with a big bottom margin. */
.home-page > .site-footer { margin-top: 0; }
.site-footer-top { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.7fr); gap: 32px 48px; align-items: start; }
.site-footer .site-footer-logo { display: inline-flex; align-items: center; gap: 12px; color: var(--text); text-decoration: none; font-weight: 900; font-size: 1.35rem; letter-spacing: .02em; }
.site-footer-logo img { width: 36px; height: 36px; border-radius: var(--radius-md); object-fit: cover; }
.site-footer-brand p { margin: 12px 0 0; max-width: 260px; font-size: .9rem; line-height: 1.55; }
.site-footer-cols { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 28px 24px; }
.site-footer-cols h2, .site-footer-cols .site-footer-heading { margin: 0 0 12px; color: var(--text); font-size: 1rem; font-weight: 700; }
.site-footer-cols ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }
.site-footer a { color: inherit; text-decoration: none; transition: color .16s ease; }
.site-footer-cols a { font-size: .88rem; }
.site-footer a:focus-visible { color: var(--text); }
@media (hover: hover) and (pointer: fine) {
.site-footer a:hover { color: var(--text); }
}
.site-footer-bottom { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; margin-top: 32px; padding-top: 18px; border-top: 1px solid color-mix(in srgb, var(--text) 10%, transparent); }
.site-footer-bottom p { margin: 0; color: var(--text); font-size: .88rem; font-weight: 600; }
.site-footer-social { display: flex; align-items: center; gap: 6px; }
.site-footer-social a { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: var(--radius-md); color: var(--text); }
@media (hover: hover) and (pointer: fine) {
.site-footer-social a:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
}
.site-footer-social svg { width: 22px; height: 22px; }

/* Back to top: quiet text button at the start of the icon row. */
.site-footer-totop { display: inline-flex; align-items: center; gap: 6px; height: 40px; margin-inline-end: 6px; padding: 0 12px; border-radius: var(--radius-md); color: var(--text); font-size: .82rem; font-weight: 600; letter-spacing: .04em; cursor: pointer; transition: transform 140ms cubic-bezier(.23, 1, .32, 1), background-color .16s ease; }
.site-footer-totop svg { width: 15px; height: 15px; }
.site-footer-totop:active { transform: scale(0.97); }
@media (hover: hover) and (pointer: fine) {
.site-footer-totop:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
}

/* Halftone wordmark (footer-mark.js sizes it to this box and draws it), a little
   narrower than the footer and centred. No grain layer: on the dark themes it lifted
   the footer a shade above the page, so it read as a separate panel. */
.site-footer { position: relative; overflow: hidden; }
.site-footer-mark { position: relative; width: min(82%, 1100px); margin: clamp(24px, 4vw, 56px) auto 0; color: var(--text); cursor: crosshair; touch-action: pan-y; }
.site-footer-mark canvas { display: block; }

@media (max-width: 900px) {
    .site-footer-top { grid-template-columns: 1fr; }
    .site-footer-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 480px) {
    .site-footer-inner { width: auto; padding: 8px 0 20px; }
    .site-footer-cols { gap: 28px 20px; }
    .site-footer-bottom { flex-direction: column-reverse; align-items: flex-start; }
}

/* Home hero: full-bleed, with the theme's normal text. Escapes .app-main's padding. */
/* .home-page clips overflow, so the page itself grows to the viewport edge
   and the hero fills it; every other section keeps its own centred width. */
.app-main > .home-page:has(> .home-hero.nx-hero) {
    --hero-top: var(--main-pad);
    margin: calc(var(--hero-top) * -1) calc(var(--main-pad) * -1) 0;
    width: calc(100% + (var(--main-pad) * 2));
    padding: 0 var(--main-pad);
}
.home-page .home-hero.nx-hero {
    margin: 0 calc(var(--main-pad) * -1);
    width: calc(100% + (var(--main-pad) * 2));
    border-radius: 0;
    /* Background: the ribbons image, further down. */
    animation: none;
}
/* Still used by the /music hero (views/site-music.ejs). */
@keyframes nx-hero-rainbow {
    0% { background-position: 0 0, 0% 30%, 40% 80%, 78% 20%, 60% 40%, 0 0; background-size: 100% 100%, 160% 160%, 160% 160%, 160% 160%, 160% 160%, 100% 100%; }
    50% { background-position: 0 0, 18% 45%, 25% 62%, 92% 38%, 45% 58%, 0 0; background-size: 100% 100%, 175% 175%, 150% 150%, 172% 172%, 150% 150%, 100% 100%; }
    100% { background-position: 0 0, 6% 12%, 55% 95%, 65% 5%, 75% 25%, 0 0; background-size: 100% 100%, 150% 150%, 172% 172%, 155% 155%, 170% 170%, 100% 100%; }
}
.home-page .home-hero.nx-hero::before,
.home-page .home-hero.nx-hero::after { display: none; }
@media (max-width: 1180px) {
    .app-main > .home-page:has(> .home-hero.nx-hero) { --hero-top: 20px; }
}

/* Motion illustrations in articles + docs (views/partials/motion/*.svg) */
.docs-motion {
    margin: 0 0 1.25rem; padding: 1rem; border-radius: var(--radius-lg);
    border: 1px solid var(--line, rgba(148, 163, 184, .16));
    background: rgba(148, 163, 184, .04);
    overflow: hidden;
}
.docs-motion svg { display: block; width: 100%; height: auto; max-height: 340px; margin: 0 auto; }
@media (prefers-reduced-motion: reduce) {
    .docs-motion * { animation: none !important; transition: none !important; }
}

/* Sidebar active pill. The highlight lives on its own element so a page switch
   can glide just the pill to the new link (view transition in layout.ejs) while
   the labels stay still. The link itself drops its fill whenever it has a pill. */
.app-sidebar .nav-link-active:has(> .nav-pill) {
    isolation: isolate;
    background: none;
    border-color: transparent;
    box-shadow: none;
}
.nav-pill {
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    pointer-events: none;
}
.app-sidebar .nav-link:active { transform: scale(.985); }

/* Pages outside the Control group have no server panel on the right. */
@media (min-width: 1361px) {
    .dashboard-frame.no-rightbar { grid-template-columns: var(--dashboard-sidebar-w, 220px) minmax(0, 1fr); }
}

/* motion-ready is now set before the first paint (layout.ejs), so data-animate
   blocks start hidden. If ui-effects.js never runs, show them anyway. */
html.motion-ready:not(.fx-ready) [data-animate]:not(.is-visible) { animation: animate-failsafe 0s 2.5s forwards; }
@keyframes animate-failsafe { to { opacity: 1; transform: none; filter: none; } }

/* Long server lists (dashboard, custom bot): cards off screen skip layout and
   paint until scrolled near. Hundreds of servers took over a second to lay out
   on a phone. The size hint keeps the scrollbar honest. */
.server-card,
.cb-server {
    content-visibility: auto;
    contain-intrinsic-size: auto 190px;
}

/* ===========================================================================
   TOP NAV MEGA MENUS (views/partials/topnavMega.ejs)
   In the phone panel the columns flatten into a plain list. At desktop width
   each menu opens on hover as one wide panel: a featured row on top, then
   headed columns of title + subtitle links. The site bar (.topbar-home) centres
   it as glass; the dashboard bar (2026-10-20) hangs it, near-solid, under its button.
   =========================================================================== */
.topnav-mega-cols,
.topnav-mega-col,
.topnav-mega-text { display: contents; }
.topnav-mega-head,
.topnav-mega-text small,
.topnav-mega-go { display: none; }

@media (min-width: 1181px) {
    .topbar-home > .topbar-spacer,
    .topbar-home .topbar-actions > .topbar-spacer { flex: 1 1 0; }
    .topbar-home .topnav {
        padding: 0;
        border: 0;
        background: none;
        box-shadow: none;
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }
    .topbar-home .topnav-link,
    .topbar-home .topnav-group > summary.topnav-link {
        border: 1px solid transparent;
        border-radius: var(--radius-md);
        color: var(--text);
    }
    .topbar .topnav-group[open] > summary.topnav-link {
        border-color: var(--line);
        background: color-mix(in srgb, var(--text) 7%, transparent);
    }
    /* The panel hangs off the whole bar, not the button that opened it. */
    .topbar .topnav-group { position: static; }
    .topbar .topnav-mega {
        inset-inline: 0;
        top: calc(100% + .6rem);
        width: min(68rem, calc(100% - 1rem)); /* four columns since Community */
        min-width: 0;
        margin-inline: auto;
        gap: .5rem;
        padding: .5rem;
        border-radius: var(--radius-lg);
        /* Solid: any see-through let the hero headline show behind the links. */
        background: var(--panel, #fff);
        -webkit-backdrop-filter: blur(24px) saturate(1.4);
        backdrop-filter: blur(24px) saturate(1.4);
        box-shadow: 0 24px 60px -20px rgba(0, 0, 0, .45);
    }
    .topbar .topnav-mega:has(.topnav-mega-col:only-child) { width: min(30rem, calc(100% - 1rem)); }
    .topbar .topnav-mega:has(.topnav-mega-col:nth-child(2):last-child) { width: min(40rem, calc(100% - 1rem)); }
    /* Dashboard bar: flush, over busy pages, so the panel is near-solid and hangs
       under the menu that opened it (layout.ejs sets --mega-x) instead of mid-bar. */
    .topbar:not(.topbar-home) .topnav-mega {
        inset-inline: auto;
        left: var(--mega-x, .5rem);
        margin: 0;
        background: color-mix(in srgb, var(--panel, #fff) 97%, transparent);
    }
    .topbar .topnav-mega > .topnav-menu-head { display: none; }

    .topbar .topnav-mega a { white-space: normal; }
    .topbar .topnav-mega-text small {
        display: block;
        color: var(--muted);
        font-size: .8rem;
        font-weight: 400;
        line-height: 1.4;
    }
    .topbar .topnav-mega-feature {
        padding: 1rem 1.1rem;
        border: 1px solid var(--line);
        border-radius: var(--radius-md);
    }
    .topbar .topnav-mega-feature .topnav-mega-text {
        display: flex;
        align-items: baseline;
        gap: .85rem;
    }
    .topbar .topnav-mega-text > span { font-weight: 700; }
    .topbar .topnav-mega-go {
        display: block;
        margin-inline-start: auto;
        transition: transform .16s ease;
    }
    .topbar .topnav-mega-feature:hover .topnav-mega-go { transform: translateX(3px); }

    .topbar .topnav-mega-cols {
        display: grid;
        grid-auto-flow: column;
        grid-auto-columns: minmax(0, 1fr);
        border: 1px solid var(--line);
        border-radius: var(--radius-md);
    }
    .topbar .topnav-mega-col {
        display: flex;
        flex-direction: column;
        gap: .15rem;
        padding: 1.1rem .85rem;
    }
    .topbar .topnav-mega-col + .topnav-mega-col { border-inline-start: 1px solid var(--line); }
    .topbar .topnav-mega-head {
        display: flex;
        align-items: center;
        gap: .75rem;
        padding: 0 .55rem .65rem;
        color: var(--muted);
        font-size: .68rem;
        font-weight: 800;
        letter-spacing: .12em;
        text-transform: uppercase;
    }
    .topbar .topnav-mega-head::after {
        content: '';
        flex: 1;
        height: 1px;
        background: var(--line);
    }
    .topbar .topnav-mega-col a { align-items: flex-start; padding: .6rem .55rem; }
    .topbar .topnav-mega-col a > svg,
    .topbar .topnav-mega-col a > i { margin-top: .15rem; }
    .topbar .topnav-mega-col .topnav-mega-text {
        display: flex;
        flex-direction: column;
        gap: .15rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    .topbar .topnav-mega-go { transition: none; }
}

/* Menu motion, after x.ai/bot (2026-10-20). The panel rises in and its links
   follow in a short diagonal stagger (--i from topnavMega.ejs). Sliding the
   pointer along the bar to the next menu keeps the panel still and slides the
   new links in from that side (layout.ejs sets data-nav-from), and a closing
   panel fades out (.is-closing) instead of vanishing. A soft pill glides under
   the pointer between the bar's links (.topnav-glide, also layout.ejs). */
@media (min-width: 1181px) {
    .topbar .topnav-mega {
        transform-origin: top center;
        animation: nx-mega-in .26s cubic-bezier(.16, 1, .3, 1);
    }
    .topbar .topnav-mega > a,
    .topbar .topnav-mega-head,
    .topbar .topnav-mega-col > a {
        animation: nx-mega-item .38s cubic-bezier(.16, 1, .3, 1) both;
        animation-delay: calc(var(--i, 0) * 28ms);
    }
    .topbar .topnav-group[data-nav-from] .topnav-mega { animation: none; }
    .topbar .topnav-group[data-nav-from="right"] .topnav-mega :is(.topnav-mega > a, .topnav-mega-head, .topnav-mega-col > a) { animation-name: nx-mega-from-right; }
    .topbar .topnav-group[data-nav-from="left"] .topnav-mega :is(.topnav-mega > a, .topnav-mega-head, .topnav-mega-col > a) { animation-name: nx-mega-from-left; }
    .topbar .topnav-group.is-closing .topnav-mega { animation: nx-mega-out .14s ease-in forwards; pointer-events: none; }
    .topbar .topnav-group.is-closing .topnav-caret { transform: none; }

    .topbar .topnav.has-glide > .topnav-link,
    .topbar .topnav.has-glide > .topnav-group > summary { position: relative; z-index: 1; }
    /* The pill is the hover (and open-menu) highlight now, so the links drop theirs. */
    .topbar .topnav.has-glide > .topnav-link:not(.is-active),
    .topbar .topnav.has-glide > .topnav-group > summary.topnav-link:not(.is-active) { background: transparent; border-color: transparent; }
    .topnav-glide {
        position: absolute;
        top: 0;
        left: 0;
        z-index: 0;
        border-radius: 999px;
        background: color-mix(in srgb, var(--text) 9%, transparent);
        box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 8%, transparent);
        opacity: 0;
        pointer-events: none;
        transition: transform .32s cubic-bezier(.16, 1, .3, 1), width .32s cubic-bezier(.16, 1, .3, 1), height .32s cubic-bezier(.16, 1, .3, 1), opacity .18s ease;
    }
    .topnav-glide.is-on { opacity: 1; }
}
@media (max-width: 1180px) { .topnav-glide { display: none; } }
@keyframes nx-mega-in { from { opacity: 0; transform: translateY(-8px) scale(.985); } }
@keyframes nx-mega-item { from { opacity: 0; transform: translateY(6px); } }
@keyframes nx-mega-from-right { from { opacity: 0; transform: translateX(22px); filter: blur(3px); } }
@keyframes nx-mega-from-left { from { opacity: 0; transform: translateX(-22px); filter: blur(3px); } }
@keyframes nx-mega-out { to { opacity: 0; transform: translateY(-6px) scale(.985); } }
@media (prefers-reduced-motion: reduce) {
    .topbar .topnav-mega,
    .topbar .topnav-mega :is(.topnav-mega > a, .topnav-mega-head, .topnav-mega-col > a) { animation: none !important; }
    .topnav-glide { transition: opacity .18s ease; }
}

/* Floating bar: the hero runs up under the bar instead of starting below it.
   .app-main is padded by the bar's clearance, so the hero escapes that padding
   (not just --main-pad) and adds the clearance to its own top padding. Without
   this a band of page background sat behind the bar. */
.nav-floating .app-main > .home-page:has(> .home-hero.nx-hero) { --hero-top: calc(var(--nav-float-clear) + .5rem); }
.nav-floating .home-page > .home-hero.nx-hero { padding-top: calc(clamp(44px, 7vw, 92px) + var(--nav-float-clear)); }

/* Home page bar: a little taller and wider, and see-through glass. */
.nav-floating:has(.topbar-home) { --nav-float-clear: calc(4.25rem + (var(--nav-float-gap) * 2)); }
:root .topbar.topbar-home {
    height: 4.25rem;
    width: min(84rem, calc(100% - clamp(1rem, 4vw, 2.5rem)));
    padding-inline: 1.25rem;
    border-radius: var(--radius-lg);
    border-color: color-mix(in srgb, #fff 14%, transparent);
    /* The glass lives on ::before, not the bar: an element with backdrop-filter
       becomes a backdrop root, and then the mega menu inside it could not blur
       the page behind it (it showed through, sharp). */
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 16%, transparent), 0 12px 40px rgba(0, 0, 0, .22);
}
/* Clear glass (Mike 2026-10-31): a thin tint over a blurred, slightly dimmed
   page, so the page colour shows through but white text stays readable over
   white cards and bright photos. */
:root .topbar.topbar-home::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: linear-gradient(180deg, color-mix(in srgb, #fff 7%, transparent), transparent 60%), color-mix(in srgb, var(--surface) 20%, transparent);
    -webkit-backdrop-filter: blur(24px) saturate(1.8) brightness(.78);
    backdrop-filter: blur(24px) saturate(1.8) brightness(.78);
    pointer-events: none;
}
.topbar-home .brand-link { min-width: 0; border-right: 0; }
.topbar-home .brand-text { font-size: 1.15rem; }
@media (min-width: 1181px) {
    .topbar-home .topnav-link,
    .topbar-home .topnav-group > summary.topnav-link { font-size: .95rem; }
}

/* The live card is just the stats row now (no title or buttons above it). */
.home-limited dl.home-limited-trust:first-child { margin-top: 0; padding-top: 8px; border-top: 0; }

/* "Business." underline: a hand-drawn scribble (one long stroke with a
   little Z kink) instead of the straight gradient bar. It draws in left to
   right with a clip, since scaling it would squash the scribble. */
.nx-title-grad::after {
    left: 2%;
    right: -2%;
    bottom: -0.16em;
    height: 0.3em;
    border-radius: 0;
    opacity: 0.95;
    /* The stroke is a mask over the theme text colour: white on dark, black on light. */
    background: var(--text);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 26' preserveAspectRatio='none'%3E%3Cpath d='M4 17 C 50 9 110 6 168 9 C 186 10 198 12 204 14 L 158 21 C 190 19 240 16 296 15' fill='none' stroke='%23fff' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 26' preserveAspectRatio='none'%3E%3Cpath d='M4 17 C 50 9 110 6 168 9 C 186 10 198 12 204 14 L 158 21 C 190 19 240 16 296 15' fill='none' stroke='%23fff' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
}
@media (prefers-reduced-motion: no-preference) {
    .nx-title-grad::after {
        transform: none;
        clip-path: inset(0 100% 0 0);
        animation: nxScribble .9s .5s cubic-bezier(.65, 0, .35, 1) forwards;
    }
    @keyframes nxScribble { to { clip-path: inset(0 0 0 0); } }
}

/* Home hero, every theme: soft crimson light ribbons (Fal nano-banana-pro/edit,
   5056x3392 original in ~/Ai work/Fal ai/2026-10-08-noxyr-hero-red-ribbons, served
   as a 3840x2576 WebP with a Gaussian blur, sigma 28, baked in by sharp).
   It sits at the top of the (very tall) hero at full width
   (min 1200px, centred and cropped on narrow screens) instead of covering the
   whole hero, and fades into the page colour at its bottom edge,
   max(100vw, 1200px) * 3392/5056 down. On the light themes the
   bottom fades into their light page colour, and the copy that sits on the image
   takes dark-theme colours (below). */
.home-page .home-hero.nx-hero {
    background:
        linear-gradient(180deg, rgba(0, 0, 0, 0) 60%, var(--bg) 100%) center top / 100% calc(max(100vw, 1200px) * .671) no-repeat,
        /* The dim only covers the image: on the whole hero it darkened the plain
           area below the image into a black band. */
        linear-gradient(rgba(0, 0, 0, .25), rgba(0, 0, 0, .25)) center top / 100% calc(max(100vw, 1200px) * .671) no-repeat,
        url("/brand/hero-ribbons-red-blur.webp") center top / max(100%, 1200px) auto no-repeat,
        var(--bg);
}

/* "Business." on the hero (every theme): white to warm gold instead of the brand
   pink/violet, which clashed with the red ribbons behind it. Only the colours
   change; the shimmer keeps its size and animation. */
.home-page .home-hero .nx-title-grad {
    background-image: linear-gradient(110deg, #fff6e0 0%, #ffcf6e 30%, #fff6e0 50%, #ffcf6e 70%, #fff6e0 100%);
}

/* Light themes: the hero copy sits on the dark red image, so the parts on it
   (badge, headline, subtitle, buttons, pill, chips) get the dark-theme colours.
   The cards further down sit below the image and keep the theme's own. */
html:not([data-theme="super"], [data-theme="dyno"], [data-theme="dusk"]) .nx-hero-inner > :is(.nx-badge, .nx-title, .nx-subtitle, .nx-actions, .nx-custombot-pill, .nx-chips),
/* Same for the subpage heroes (donors, compare, endercloud, status): their copy sits on the image too. */
html:not([data-theme="super"], [data-theme="dyno"], [data-theme="dusk"]) .home-hero.nx-hero > .home-hero-inner {
    --text: #ffffff;
    --text-main: #ffffff;
    --muted: rgba(255, 255, 255, .78);
    --text-muted: rgba(255, 255, 255, .78);
    --faint: rgba(255, 255, 255, .55);
    --bg: #101010;
    --surface: #1a1a1a;
    --panel: #1a1a1a;
    --line: rgba(255, 255, 255, .14);
    --hover: rgba(255, 255, 255, .08);
    color: var(--text);
}
html:not([data-theme="super"], [data-theme="dyno"], [data-theme="dusk"]) .home-hero.nx-hero .ec-logo { content: url("/brand/endercloud-logo-dark.png"); }
/* Light themes, subpage heroes: on a phone the copy runs past the image into the
   light fade, where the white text vanished. The image covers the whole hero
   instead and only the empty bottom padding fades into the page. */
html:not([data-theme="super"], [data-theme="dyno"], [data-theme="dusk"]) .home-page .home-hero.nx-hero:has(> .home-hero-inner) {
    padding-bottom: 6rem;
    background:
        linear-gradient(180deg, rgba(0, 0, 0, 0) calc(100% - 5rem), var(--bg) 100%),
        linear-gradient(rgba(0, 0, 0, .25), rgba(0, 0, 0, .25)),
        url("/brand/hero-ribbons-red-blur.webp") center top / cover no-repeat,
        var(--bg);
}
/* Light themes: the home bar's text is dark, and the bar floats over the dark
   red image at the top, so its glass is mostly the theme's own light surface. */
html:not([data-theme="super"], [data-theme="dyno"], [data-theme="dusk"]) .topbar.topbar-home::before {
    background: color-mix(in srgb, var(--surface) 58%, transparent);
    -webkit-backdrop-filter: blur(24px) saturate(1.6) brightness(1.12);
    backdrop-filter: blur(24px) saturate(1.6) brightness(1.12);
}

/* ===========================================================================
   NAV BAR: ONE CONTROL SYSTEM (desktop, every page)
   The bar had six control heights (30-44px), three corner styles (pill, circle,
   12px) and four competing effects (gold pulse ring, glowing white buttons,
   a glass switch, a two-line profile). Now, on the home page and the
   dashboard alike: brand and links on the left;
   on the right quiet utilities, a divider, then account and actions. Every
   control is --hc tall with the --hr radius, nothing glows, and colours come
   from the theme (white primary on dark themes, black on light ones).
   =========================================================================== */
@media (min-width: 1181px) {
    .topbar {
        --hc: 36px;
        --hr: 10px;
    }
    .topbar.topbar-home { gap: 0; }
    /* Links sit beside the brand; the gap before the right side takes the slack. */
    .topbar > .topbar-spacer { flex: 0 0 2rem; }
    .topbar .topbar-actions { gap: .5rem; }
    .topbar .topbar-actions > .topbar-spacer { flex: 1 1 0; }

    .topbar.topbar-home .brand-link { gap: .6rem; padding: 0; }
    .topbar .topnav { gap: .25rem; }
    .topbar .topnav-link,
    .topbar .topnav-group > summary.topnav-link {
        height: var(--hc);
        padding: 0 .8rem;
        border: 0;
        border-radius: var(--hr);
        color: color-mix(in srgb, var(--text) 78%, transparent);
        font-size: .9375rem;
        font-weight: 600;
    }
    .topbar .topnav-group[open] > summary.topnav-link {
        color: var(--text);
        background: color-mix(in srgb, var(--text) 8%, transparent);
    }
@media (hover: hover) and (pointer: fine) {
.topbar .topnav-link:hover {
        color: var(--text);
        background: color-mix(in srgb, var(--text) 8%, transparent);
    }
}

    /* Utilities: ghost buttons, same height, no borders or glows. */
    .topbar .langsw > summary,
    .topbar .theme-toggle {
        height: var(--hc);
        min-width: var(--hc);
        padding: 0 .65rem;
        border: 0;
        border-radius: var(--hr);
        background: transparent;
        box-shadow: none;
        color: color-mix(in srgb, var(--text) 78%, transparent);
    }
    .topbar .theme-toggle { width: var(--hc); padding: 0; }
    .topbar .theme-toggle::before { display: none; }
    @media (hover: hover) and (pointer: fine) {
.topbar .langsw > summary:hover,
.topbar .theme-toggle:hover {
        color: var(--text);
        background: color-mix(in srgb, var(--text) 8%, transparent);
    }
}
    .topbar .sky-switch {
        --sky-w: 62px;
        --sky-h: var(--hc);
        --sky-thumb: 28px;
        --sky-pad: 3px;
    }

    /* Vote keeps its gold (the only thing that unlocks a custom bot) but drops
       the pulsing ring and matches the rest. */
    .topbar .topbar-vote-btn.topbar-vote-btn {
        height: var(--hc);
        padding: 0 .85rem;
        border-radius: var(--hr);
        animation: mg-deal-in 520ms cubic-bezier(.22, 1, .36, 1) 40ms backwards;
        box-shadow: none;
    }
@media (hover: hover) and (pointer: fine) {
.topbar .topbar-vote-btn.topbar-vote-btn:hover {
        height: var(--hc);
        padding: 0 .85rem;
        border-radius: var(--hr);
        animation: mg-deal-in 520ms cubic-bezier(.22, 1, .36, 1) 40ms backwards;
        box-shadow: none;
    }
}
    /* Ghost in gold (like Tickety's Premium): no fill or border, gold label and
       a filled star; a soft gold wash on hover. Darker gold on light themes. */
    .topbar .topbar-vote-btn.topbar-vote-btn {
        --vote-gold: #f5c542;
        border-color: transparent;
        background: transparent;
        color: var(--vote-gold);
        font-weight: 700;
    }
    .topbar .topbar-vote-btn.topbar-vote-btn svg {
        color: var(--vote-gold);
        fill: currentColor;
    }
    @media (hover: hover) and (pointer: fine) {
.topbar .topbar-vote-btn.topbar-vote-btn:hover {
        background: color-mix(in srgb, var(--vote-gold) 14%, transparent);
        filter: none;
    }
}
    html:not([data-theme="super"], [data-theme="dyno"], [data-theme="dusk"]) .topbar .topbar-vote-btn.topbar-vote-btn { --vote-gold: #a8730c; }
    /* Divider between the utilities and the account / actions. Logged out there
       is no account, so Add Bot just gets the extra room. */
    .topbar .topbar-actions > .profile-menu {
        margin-inline-start: .5rem;
        position: relative;
    }
    .topbar .topbar-actions > .profile-menu::before {
        content: '';
        position: absolute;
        inset-inline-start: calc(-.5rem - 5px);
        top: 50%;
        width: 1px;
        height: 20px;
        background: color-mix(in srgb, var(--text) 16%, transparent);
        transform: translateY(-50%);
    }
    .topbar .topbar-add-bot { margin-inline-start: 1rem; }

    /* Account: the avatar alone; name and ID are in the menu it opens. */
    .topbar .profile-menu-btn {
        height: var(--hc);
        gap: .35rem;
        padding: 0 .4rem 0 .25rem;
        border-radius: var(--hr);
    }
    @media (hover: hover) and (pointer: fine) {
.topbar .profile-menu-btn:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
}
    .topbar .profile-menu-btn img { width: 28px; height: 28px; }
    .topbar .user-copy { display: none; }

    /* Actions: Dashboard is the one solid button, Custom Bot the outlined one.
       Logged out, Add Bot and Login stay the same solid colour, as asked. */
    .topbar .app-switch.is-split { gap: .5rem; }
    .topbar .app-switch.is-split .app-switch-btn {
        height: var(--hc);
        padding: 0 .9rem;
        border: 1px solid color-mix(in srgb, var(--text) 18%, transparent);
        border-radius: var(--hr);
        background: transparent;
        color: var(--text);
        box-shadow: none;
        filter: none;
        transform: none;
        font-size: .875rem;
        font-weight: 700;
    }
@media (hover: hover) and (pointer: fine) {
.topbar .app-switch.is-split .app-switch-btn:hover {
        height: var(--hc);
        padding: 0 .9rem;
        border: 1px solid color-mix(in srgb, var(--text) 18%, transparent);
        border-radius: var(--hr);
        background: transparent;
        color: var(--text);
        box-shadow: none;
        filter: none;
        transform: none;
        font-size: .875rem;
        font-weight: 700;
    }
}
    @media (hover: hover) and (pointer: fine) {
.topbar .app-switch.is-split .app-switch-btn:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
}
    .topbar .app-switch.is-split .app-switch-btn[href="/dashboard"] {
        border-color: transparent;
        background: var(--text);
        color: var(--bg);
    }
@media (hover: hover) and (pointer: fine) {
.topbar .app-switch.is-split .app-switch-btn[href="/dashboard"]:hover {
        border-color: transparent;
        background: var(--text);
        color: var(--bg);
    }
}
    @media (hover: hover) and (pointer: fine) {
.topbar .app-switch.is-split .app-switch-btn[href="/dashboard"]:hover { opacity: .9; }
}
    .topbar .app-switch .app-switch-btn svg { filter: none; }
    .topbar .app-switch.is-split .app-switch-btn span { text-shadow: none; }
    .topbar .btn {
        height: var(--hc);
        padding: 0 .9rem;
        border-radius: var(--hr) !important;
        box-shadow: none !important;
        font-size: .875rem;
    }
}

/* Hero badge: frosted glass on the ribbons instead of a solid dark pill with red
   text (red on red). Light copy, and the two gold accents of the hero - the
   sparkle and "business" - match the gold "Business." and the Vote button. */
.home-page .home-hero .nx-badge {
    gap: .55rem;
    padding: .45rem 1rem .45rem .8rem;
    border: 1px solid rgba(255, 255, 255, .14);
    background: rgba(255, 255, 255, .06);
    -webkit-backdrop-filter: blur(14px) saturate(1.4);
    backdrop-filter: blur(14px) saturate(1.4);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08);
    color: rgba(255, 255, 255, .86);
    font-size: .875rem;
    font-weight: 500;
    letter-spacing: .01em;
}
.home-page .home-hero .nx-badge svg,
.home-page .home-hero .nx-badge i { color: #f5c542; }
.home-page .home-hero .nx-badge .nx-cursive { color: #ffcf6e; }

@media (min-width: 1181px) {
    /* The links were a frosted pill of their own; they sit straight on the bar. */
    .topbar .topnav {
        padding: 0;
        border: 0;
        background: none;
        box-shadow: none;
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }
    .topbar .topbar-search-btn {
        width: var(--hc);
        height: var(--hc);
        border: 0;
        border-radius: var(--hr);
        background: transparent;
        color: color-mix(in srgb, var(--text) 78%, transparent);
    }
    @media (hover: hover) and (pointer: fine) {
.topbar .topbar-search-btn:hover { color: var(--text); background: color-mix(in srgb, var(--text) 8%, transparent); }
}
    .topbar .topbar-search input { height: var(--hc); border-radius: var(--hr); }
    /* On /dashboard and /custombot the two actions are one joined switch with the
       current app filled: a quiet outline, no glow, same height as the rest. */
    .topbar .app-switch:not(.is-split) {
        height: var(--hc);
        align-items: center;
        padding: 2px;
        border: 1px solid color-mix(in srgb, var(--text) 18%, transparent);
        border-radius: var(--hr);
        background: transparent;
        box-shadow: none;
    }
@media (hover: hover) and (pointer: fine) {
.topbar .app-switch:not(.is-split):hover {
        height: var(--hc);
        align-items: center;
        padding: 2px;
        border: 1px solid color-mix(in srgb, var(--text) 18%, transparent);
        border-radius: var(--hr);
        background: transparent;
        box-shadow: none;
    }
}
    .topbar .app-switch:not(.is-split) .app-switch-btn {
        height: calc(var(--hc) - 6px);
        padding: 0 .8rem;
        border-radius: calc(var(--hr) - 3px);
        color: color-mix(in srgb, var(--text) 78%, transparent);
        font-size: .875rem;
        font-weight: 700;
    }
    @media (hover: hover) and (pointer: fine) {
.topbar .app-switch:not(.is-split) .app-switch-btn:hover { color: var(--text); background: color-mix(in srgb, var(--text) 8%, transparent); }
}
    .topbar .app-switch:not(.is-split) .app-switch-btn.is-active {
        background: var(--text);
        color: var(--bg);
    }
@media (hover: hover) and (pointer: fine) {
.topbar .app-switch:not(.is-split) .app-switch-btn.is-active:hover {
        background: var(--text);
        color: var(--bg);
    }
}
}
/* Server pages also carry the server switcher, and between 1181 and 1400px the
   right side ran past the bar (Dashboard was clipped off). The two app buttons
   drop to their icons there; the label stays for screen readers. */
@media (min-width: 1181px) and (max-width: 1400px) {
    .has-guild .topbar .app-switch-btn { padding: 0 .65rem; }
    .has-guild .topbar .app-switch-btn span {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }
}

/* Above the fold, reveal with CSS on first paint. The scroll reveal waits for
   ui-effects.js, which is deferred until the whole page has parsed: on the big
   home page over a slow link the hero images showed while its text sat invisible.
   Delays mirror ui-effects.js (capped at 240ms). Must stay after, and outrank, the failsafe above. */
html.motion-ready:not(.reduce-motion) .nx-hero [data-animate],
html.motion-ready:not(.reduce-motion) .home-page > section:first-child > .home-section-head[data-animate] {
    animation: animate-in 800ms cubic-bezier(.22, 1, .36, 1) var(--animate-delay, 0ms) both;
}
@keyframes animate-in { from { opacity: 0; transform: translateY(40px); } to { opacity: 1; transform: none; } }
[data-animate-delay="55"], [data-animate-delay="60"] { --animate-delay: 60ms; }
[data-animate-delay="80"] { --animate-delay: 80ms; }
[data-animate-delay="110"], [data-animate-delay="120"] { --animate-delay: 120ms; }
[data-animate-delay="140"] { --animate-delay: 140ms; }
[data-animate-delay="160"], [data-animate-delay="180"] { --animate-delay: 170ms; }
[data-animate-delay="200"], [data-animate-delay="220"], [data-animate-delay="230"] { --animate-delay: 210ms; }
[data-animate-delay="260"], [data-animate-delay="320"], [data-animate-delay="380"], [data-animate-delay="420"] { --animate-delay: 240ms; }

/* Sidebar labels wrap onto a second line instead of being cut off when the
   column is tight (big system fonts, long translations). No change when they fit. */
.app-sidebar .nav-link > span {
    min-width: 0;
    overflow-wrap: break-word;
}

/* Donors: Vote's purple twin, right of it in the top bar (/donors). */
.topbar-donors-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    height: 2.125rem;
    padding: 0 0.85rem 0 0.7rem;
    border-radius: 999px;
    font-size: 0.8125rem;
    line-height: 1;
    white-space: nowrap;
    text-decoration: none;
    flex: none;
    border: 1px solid #7c3aed;
    background: linear-gradient(160deg, #a78bfa, #8b5cf6 46%, #7c3aed);
    color: #fff;
    font-weight: 700;
    box-shadow: 0 1px 2px rgba(76, 29, 149, 0.28), 0 0 0 3px rgba(139, 92, 246, 0.16);
}
@media (hover: hover) and (pointer: fine) {
.topbar-donors-btn:hover { color: #fff; background: linear-gradient(160deg, #b9a3fb, #9a70f7 46%, #8448ef); }
}
.topbar-donors-btn svg { color: #fff; fill: currentColor; }
@media (min-width: 1181px) {
    .topbar .topbar-donors-btn {
        --donor-purple: #a78bfa;
        height: var(--hc);
        padding: 0 .85rem;
        border-radius: var(--hr);
        border-color: transparent;
        background: transparent;
        box-shadow: none;
        color: var(--donor-purple);
    }
    .topbar .topbar-donors-btn svg { color: var(--donor-purple); }
    .topbar .topbar-donors-btn.is-active { background: color-mix(in srgb, var(--donor-purple) 14%, transparent); color: var(--donor-purple); }
@media (hover: hover) and (pointer: fine) {
.topbar .topbar-donors-btn:hover { background: color-mix(in srgb, var(--donor-purple) 14%, transparent); color: var(--donor-purple); }
}
    html:not([data-theme="super"], [data-theme="dyno"], [data-theme="dusk"]) .topbar .topbar-donors-btn { --donor-purple: #7c3aed; }
}

/* A disabled button must look disabled. Themes paint .btn-primary the same
   whether or not it can be clicked, so "New Product" with no categories looked
   live and simply did nothing. */
.btn:disabled,
.btn[aria-disabled="true"] {
    opacity: .5;
    cursor: not-allowed;
    filter: saturate(.6);
}

/* Light themes share one warm, quiet neutral palette (soft stone greys, near-white
   cards, ink text); each theme keeps only its own accent colour. Dark themes
   (dyno, super, dusk) are untouched. The :not() chain outranks the per-theme
   blocks above (html[data-theme="red"] etc.), so this wins wherever it applies. */
html:not([data-theme="dyno"]):not([data-theme="super"]):not([data-theme="dusk"]) {
    --bg: #ECEBE8;
    --surface-rgb: 248, 248, 246;
    --theme-white: #F7F7F5;
    --theme-soft: #F1F0EE;
    --line: rgba(28, 27, 25, 0.09);
    --line-soft: rgba(28, 27, 25, 0.12);
    --line-strong: #1B1B1A;
    --text: #1B1B1A;
    --text-main: #1B1B1A;
    --muted: #6B6A66;
    --text-muted: #6B6A66;
    --faint: #9A9893;
    --hero-tint: 0.55;
    --page-bg: linear-gradient(180deg, #EFEEEB 0%, #E8E7E4 100%);
}

/* Drag and drop on upload spots (public/file-drop.js): the spot under the dragged file. */
[data-file-drop] { transition: outline-color .15s, background-color .15s; }
.is-file-over {
    outline: 2px dashed var(--brand) !important;
    outline-offset: 3px;
    background-color: color-mix(in srgb, var(--brand) 8%, transparent) !important;
}

/* Icon-only buttons: `.dashboard-root .btn` padding outranks `.icon-btn { padding: 0 }`,
   and on wide screens (30px buttons) it squeezed the 16px icon to a dot. */
.dashboard-root .btn.icon-btn, .btn.icon-btn { padding: 0; }
.icon-btn > svg, .icon-btn > i { flex-shrink: 0; max-width: none; }

/* Server pages, 1181-1460px (2026-10-20): logo, server picker, both menus and the
   nine actions ran up to 110px wider than the screen and pushed Custom Bot /
   Dashboard off the edge. There Vote and Donors go icon-only (their title says
   which) and the server picker narrows first. */
@media (min-width: 1181px) and (max-width: 1460px) {
    .has-guild .topbar .topbar-vote-btn > span,
    .has-guild .topbar .topbar-donors-btn > span { display: none; }
    .has-guild .topbar :is(.topbar-vote-btn, .topbar-donors-btn) { width: 2.125rem; padding: 0; justify-content: center; }
    .has-guild .topbar .guild-switcher-btn { max-width: 170px; }
}
/* Site bar, 1181-1400px (2026-11-01, Company menu added): logged out, the six nav
   items plus Vote, Donors, Add Bot and Login ran ~120px past the edge and squeezed
   the logo to nothing. Same fix as server pages: Vote and Donors go icon-only, and
   the nav items sit a little tighter. */
@media (min-width: 1181px) and (max-width: 1400px) {
    .topbar-home .topbar-vote-btn > span,
    .topbar-home .topbar-donors-btn > span { display: none; }
    .topbar.topbar-home :is(.topbar-vote-btn.topbar-vote-btn, .topbar-donors-btn.topbar-donors-btn) { flex: none; width: 2.125rem; padding: 0; justify-content: center; }
    .topbar-home .topnav > .topnav-link,
    .topbar-home .topnav > .topnav-group > summary.topnav-link { padding-inline: .55rem; }
}
/* The logo never gives up width to the nav: squeezed, the picture went thin and
   "Noxyr" ran under "Features". */
@media (min-width: 1181px) { .topbar-home .brand-link { flex: none; } }

/* Build with AI: a light sweep runs across the button until the draft is in
   (.is-generating), and each field the AI filled glows once (.nx-ai-filled). */
.btn.is-generating { position: relative; overflow: hidden; pointer-events: none; }
.btn.is-generating::after { content: ""; position: absolute; inset: 0; background: linear-gradient(100deg, transparent 20%, rgba(167, 139, 250, .35) 45%, rgba(244, 114, 182, .35) 55%, transparent 80%); transform: translateX(-100%); animation: nx-ai-sweep 1.1s ease-in-out infinite; }
@keyframes nx-ai-sweep { to { transform: translateX(100%); } }
.nx-ai-filled { animation: nx-ai-filled 1.4s ease-out; }
@keyframes nx-ai-filled { from { box-shadow: 0 0 0 3px rgba(167, 139, 250, .55); } to { box-shadow: 0 0 0 3px transparent; } }
@media (prefers-reduced-motion: reduce) { .btn.is-generating::after, .nx-ai-filled { animation: none; } .btn.is-generating { opacity: .7; } }

/* text-in (titles, intros) comes in with CSS from the first paint. Hero titles used to sit
   invisible until deferred nx-kit + nxkit/motion.js split them (pages without the motion
   group: 1.2 s, then a pop), and text outside the hero painted, vanished, then replayed.
   nxkit/motion.js leaves anything already on screen shown (.nx-tin-shown) and only
   replays it on click; below the fold it still plays word by word on scroll. */
html.motion-ready:not(.reduce-motion) [data-kit="text-in"] { animation: nx-hero-title-in 900ms cubic-bezier(.22, 1, .36, 1) both; }
@keyframes nx-hero-title-in { from { opacity: 0; filter: blur(10px); transform: translateY(16px); } }
.nx-tin.nx-tin-shown:not(.is-in) .nx-tin-w { opacity: 1; }

/* What the customer really paid, under an amount shown in the viewer's currency
   (lib/viewerMoney.js moneyHtml/moneySum, layout.ejs nxMoney). */
.nx-paid { display: block; margin-top: 2px; color: var(--muted); font-size: .72em; font-weight: 500; letter-spacing: 0; }
.inv-sum .is-conv { color: var(--muted); font-size: .85em; }

/* Everyday name under a time zone field (public/tz-pick.js). */
.nx-tz-hint { display: block; margin-top: 4px; color: var(--muted); font-size: .78rem; }

/* Multi pickers (public/multi-pick.js): every <select multiple> and .role-checklist. */
.nx-mp-native { display: none !important; }
.nx-mp { display: grid; gap: .55rem; padding: .65rem; border: 1px solid var(--line); border-radius: var(--radius-md); background: color-mix(in srgb, var(--surface) 88%, transparent); }
.nx-mp.is-disabled { opacity: .6; pointer-events: none; }
.nx-mp-head { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.nx-mp-chips { display: contents; }
.nx-mp-chip { display: inline-flex; align-items: center; gap: .3rem; max-width: 100%; padding: .22rem .3rem .22rem .6rem; border-radius: 999px; background: color-mix(in srgb, var(--brand, #0062ff) 16%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--brand, #0062ff) 40%, transparent); color: var(--text); font-size: .8rem; font-weight: 650; }
.nx-mp-chip > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 14rem; }
.nx-mp-x { display: grid; place-items: center; width: 1.15rem; height: 1.15rem; border-radius: 999px; color: var(--muted); font-size: .95rem; line-height: 1; }
.nx-mp-x:hover, .nx-mp-x:focus-visible { background: color-mix(in srgb, var(--text) 12%, transparent); color: var(--text); outline: none; }
.nx-mp-search { flex: 1 1 10rem; min-width: 8rem; height: 2.1rem; padding: 0 .7rem; border: 1px solid var(--line); border-radius: var(--radius-sm); background: color-mix(in srgb, var(--text) 4%, transparent); color: var(--text); font: inherit; font-size: .85rem; }
.nx-mp-search:focus { outline: none; border-color: color-mix(in srgb, var(--brand, #0062ff) 60%, var(--line)); }
.nx-mp-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); gap: .2rem .5rem; max-height: 15rem; overflow-y: auto; padding-right: .2rem; scrollbar-width: thin; }
.nx-mp-row { position: relative; display: flex; align-items: center; gap: .55rem; min-width: 0; padding: .42rem .55rem; border-radius: var(--radius-sm); color: var(--text); font-size: .88rem; font-weight: 600; cursor: pointer; transition: background-color .15s; }
.nx-mp-row[hidden] { display: none; }
.nx-mp-row input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.nx-mp-mark { flex: none; display: grid; place-items: center; width: 1.05rem; height: 1.05rem; border-radius: 5px; box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--text) 35%, transparent); transition: background-color .15s, box-shadow .15s; }
.nx-mp-row.is-on .nx-mp-mark { background: var(--brand, #0062ff); box-shadow: none; }
.nx-mp-row.is-on .nx-mp-mark::after { content: ""; width: .32rem; height: .58rem; margin-top: -.12rem; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.nx-mp-row input:focus-visible + .nx-mp-mark { outline: 2px solid var(--brand, #0062ff); outline-offset: 2px; }
.nx-mp-row.is-on { background: color-mix(in srgb, var(--brand, #0062ff) 9%, transparent); }
.nx-mp-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nx-mp-row.is-divider { opacity: .45; font-size: .75rem; letter-spacing: -.04em; }
.nx-mp-row.has-note .nx-mp-name { white-space: normal; }
.nx-mp-note { display: block; margin-top: .1rem; color: var(--red, #ef4444); font-size: .74rem; font-weight: 500; }
.nx-mp-row.is-locked:not(.is-on) { opacity: .6; cursor: not-allowed; }
.nx-mp-empty, .nx-mp-count { margin: 0; color: var(--muted); font-size: .78rem; }
@media (hover: hover) and (pointer: fine) { .nx-mp-row:hover { background: color-mix(in srgb, var(--text) 6%, transparent); } .nx-mp-row.is-on:hover { background: color-mix(in srgb, var(--brand, #0062ff) 14%, transparent); } }
@media (max-width: 560px) { .nx-mp-list { grid-template-columns: 1fr; } }

/* ---------- Boxes stand apart from the page (Mike 2026-10-30) ----------
   Cards used rgba(var(--surface-rgb), .03): 3% of the surface colour itself,
   invisible on the page in every theme. Now: light themes = white boxes on the
   grey page; dark themes = one clear step lighter than the page, a visible edge
   and a soft top highlight. Glass / solid looks (partials/userLook.ejs) and the
   V2 style build on the same tokens. */
:root { --card-bg: #fff; --card-line: rgba(18, 24, 38, .1); --card-hi: 0 1px 2px rgba(18, 24, 38, .05); }
html:is([data-theme="dyno"], [data-theme="super"], [data-theme="dusk"]) { --card-bg: color-mix(in srgb, #fff 5.5%, var(--bg)); --card-line: rgba(255, 255, 255, .1); --card-hi: inset 0 1px 0 rgba(255, 255, 255, .05); }
.panel, .panel-strong { background: var(--card-bg); border-color: var(--card-line); box-shadow: var(--card-hi); }

/* Dashboard page entrance (layout.ejs enter()): blocks rise, fade and sharpen in turn. */
.app-main.nx-enter [data-nx-enter] { animation: nxPageIn .52s cubic-bezier(.16, 1, .3, 1) backwards; animation-delay: calc(var(--nx-i, 0) * 45ms + var(--nx-t, 0ms)); }
@keyframes nxPageIn { from { opacity: 0; transform: translateY(14px) scale(.988); filter: blur(5px); } }
/* Phones: no blur (cheaper on small GPUs), a shorter rise. */
@media (max-width: 640px) { @keyframes nxPageIn { from { opacity: 0; transform: translateY(10px); } } }
@media (prefers-reduced-motion: reduce) { .app-main.nx-enter [data-nx-enter] { animation: none; } }

/* Discord markdown inside previews (embed-preview.js setText). Discord's own sizes/colours. */
:is(.dc-preview-body, .dc-preview-text) .dc-md-h1, :is(.dc-preview-body, .dc-preview-text) .dc-md-h2, :is(.dc-preview-body, .dc-preview-text) .dc-md-h3 { display: block; margin: .3rem 0 .15rem; font-weight: 700; line-height: 1.25; color: #f2f3f5; }
:is(.dc-preview-body, .dc-preview-text) .dc-md-h1 { font-size: 1.5em; }
:is(.dc-preview-body, .dc-preview-text) .dc-md-h2 { font-size: 1.25em; }
:is(.dc-preview-body, .dc-preview-text) .dc-md-h3 { font-size: 1.05em; }
:is(.dc-preview-body, .dc-preview-text) .dc-md-sub { display: block; font-size: .78em; color: #949ba4; }
:is(.dc-preview-body, .dc-preview-text) .dc-md-quote { display: block; padding-left: .7rem; border-left: 4px solid #4e5058; }
:is(.dc-preview-body, .dc-preview-text) .dc-md-list { margin: .15rem 0; padding-left: 1.2rem; list-style: disc; }
.dc-md-code { padding: .05rem .25rem; border-radius: 4px; background: #2b2d31; font-family: ui-monospace, Menlo, monospace; font-size: .85em; }
.dc-md-link { color: #00a8fc; }
.dc-md-mention { padding: 0 .15rem; border-radius: 3px; background: rgba(88, 101, 242, .3); color: #c9cdfb; font-weight: 500; }
.dc-preview-text { margin: 0; color: #dbdee1; font-size: .9rem; line-height: 1.4; white-space: pre-wrap; overflow-wrap: anywhere; }
.dc-preview-text + .dc-preview-embed { margin-top: .35rem; }
.dc-preview-text.is-empty { color: #6d6f78; font-style: italic; }
.dc-preview-dm { display: inline-flex; margin-bottom: .45rem; padding: .1rem .5rem; border-radius: 999px; background: rgba(255, 255, 255, .06); color: #949ba4; font-size: .7rem; font-weight: 700; }

/* Dashboard sidebar, the /admin look (was the V2 style; Mike 2026-10-30 made it
   the only one): glass rail, icon tiles, gradient pill on the active page. */
.app-sidebar {
    --sb-card: color-mix(in srgb, var(--text) 4.5%, transparent);
    --sb-card-2: color-mix(in srgb, var(--text) 8%, transparent);
    --sb-edge: color-mix(in srgb, var(--text) 11%, transparent);
    --sb-glow: color-mix(in srgb, var(--brand) 40%, transparent);
    --sb-grad: linear-gradient(135deg, var(--brand), color-mix(in srgb, var(--brand) 72%, #fff));
}
/* Light themes: glass would be grey on grey. */
html:not([data-theme="dyno"], [data-theme="super"], [data-theme="dusk"]) .app-sidebar { --sb-card: color-mix(in srgb, #fff 82%, transparent); --sb-card-2: color-mix(in srgb, var(--text) 6%, transparent); --sb-edge: color-mix(in srgb, var(--text) 10%, transparent); }
.app-sidebar { background: var(--sb-card) !important; border-right: 1px solid var(--sb-edge) !important; backdrop-filter: blur(22px) saturate(140%); -webkit-backdrop-filter: blur(22px) saturate(140%); }
.app-sidebar .nav-link { display: flex; align-items: center; gap: .65rem; min-height: 40px; padding: .35rem .5rem; border-radius: 13px; color: color-mix(in srgb, var(--text) 82%, transparent); font-weight: 600; transition: background .15s ease, color .15s ease, box-shadow .2s ease; }
.app-sidebar .nav-link > svg { box-sizing: border-box; flex: none; width: 30px; height: 30px; padding: 7px; border-radius: 10px; background: var(--sb-card-2); color: color-mix(in srgb, var(--text) 70%, transparent); transition: background .15s ease, color .15s ease; }
@media (hover: hover) and (pointer: fine) { .app-sidebar .nav-link:hover { background: var(--sb-card-2); color: var(--text); } }
.app-sidebar .nav-link.nav-link-active { background: var(--sb-grad) !important; color: #fff !important; box-shadow: 0 10px 26px -10px var(--sb-glow); }
.app-sidebar .nav-link.nav-link-active > svg { background: rgba(255, 255, 255, .2); color: #fff; }
.app-sidebar .nav-pill { display: none !important; }
.app-sidebar .nav-group-toggle { font-size: .72rem; font-weight: 700; letter-spacing: 0; text-transform: none; color: var(--muted); }
.app-sidebar .nav-group.has-active > .nav-group-toggle { color: var(--text); }

/* Signed-in account card at the bottom of the dashboard sidebar. */
.nav-account { display: flex; align-items: center; gap: .45rem; margin-top: .6rem; padding: .55rem .55rem .55rem .6rem; border: 1px solid var(--sb-edge, var(--line)); border-radius: 16px; background: var(--sb-card-2, var(--panel)); }
.nav-account img { flex: none; width: 34px; height: 34px; border-radius: 50%; object-fit: cover; box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand) 55%, transparent); }
.nav-account-copy { display: grid; flex: 1; min-width: 0; line-height: 1.2; }
.nav-account-copy strong { overflow: hidden; font-size: .85rem; font-weight: 800; color: var(--text); white-space: nowrap; text-overflow: ellipsis; }
.nav-account-copy small { overflow: hidden; font-size: .72rem; color: var(--muted); white-space: nowrap; text-overflow: ellipsis; }
.nav-account-btn { display: grid; flex: none; place-items: center; width: 28px; height: 28px; border-radius: 10px; color: var(--muted); transition: background .15s ease, color .15s ease; }
@media (hover: hover) and (pointer: fine) {
    .nav-account-btn:hover { background: var(--sb-card, var(--panel)); color: var(--text); }
    .nav-account-btn.is-out:hover { color: #ef4444; }
}
.nav-account-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
/* Mini sidebar: just the picture. */
html.nx-side-mini .app-sidebar .nav-account { justify-content: center; padding: .4rem; border-color: transparent; background: none; }
html.nx-side-mini .app-sidebar :is(.nav-account-copy, .nav-account-btn) { display: none; }

/* Page + sidebar scrollbar: white pill with a thin outline (Mike 2026-10-30, was purple).
   Chrome ignores ::-webkit-scrollbar while scrollbar-color is set, so those two drop it. */
html, .app-sidebar { scrollbar-color: auto !important; }
:is(html, .app-sidebar)::-webkit-scrollbar { width: 14px; height: 14px; background: transparent; }
:is(html, .app-sidebar)::-webkit-scrollbar-track { background: transparent; }
:is(html, .app-sidebar)::-webkit-scrollbar-thumb { min-height: 48px; border: 3px solid transparent; border-radius: 999px; background: #fff padding-box; box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--text) 45%, var(--bg)); }
:is(html, .app-sidebar)::-webkit-scrollbar-thumb:hover { background-color: #f1f1f1; }
.app-sidebar::-webkit-scrollbar { width: 10px; }
@supports not selector(::-webkit-scrollbar) { html, .app-sidebar { scrollbar-color: #fff transparent !important; } }
/* Light themes (Blue, Red, Mono): a black pill, the white one vanished on the light page (Mike 2026-11-02). */
html:not([data-theme="super"]):not([data-theme="dyno"]):not([data-theme="dusk"])::-webkit-scrollbar-thumb,
html:not([data-theme="super"]):not([data-theme="dyno"]):not([data-theme="dusk"]) .app-sidebar::-webkit-scrollbar-thumb { background-color: #141414; box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .35); }
html:not([data-theme="super"]):not([data-theme="dyno"]):not([data-theme="dusk"])::-webkit-scrollbar-thumb:hover,
html:not([data-theme="super"]):not([data-theme="dyno"]):not([data-theme="dusk"]) .app-sidebar::-webkit-scrollbar-thumb:hover { background-color: #000; }
@supports not selector(::-webkit-scrollbar) { html:not([data-theme="super"]):not([data-theme="dyno"]):not([data-theme="dusk"]) :is(html, .app-sidebar), html:not([data-theme="super"]):not([data-theme="dyno"]):not([data-theme="dusk"]) { scrollbar-color: #141414 transparent !important; } }

/* Top bar: always glass, every page and theme (Mike 2026-10-30). A picture look's
   own glass (partials/userLook.ejs) is more specific and still wins there.
   Not the floating site bar: its clear glass lives on .topbar-home::before. */
.topbar:not(.topbar-home) {
    background: color-mix(in srgb, var(--bg) 58%, transparent) !important;
    -webkit-backdrop-filter: blur(20px) saturate(160%) !important;
    backdrop-filter: blur(20px) saturate(160%) !important;
    border-bottom: 1px solid color-mix(in srgb, var(--text) 10%, transparent);
}
@media (prefers-reduced-transparency: reduce) {
    .topbar { background: var(--bg) !important; -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
}

/* ---------- Glass never blurs the wrong thing (Mike 2026-10-31) ----------
   Chrome draws a backdrop-filter inside a page-switch snapshot live: the old
   page's glass sidebar / right panel blurred the NEW page under them while it
   faded in ("glass flash" left and right). And a glass shell (topbar, sidebar,
   right panel) stayed sharp and undimmed above a full-screen overlay, whose own
   blur could not reach it. So while a page switch animates or any overlay is
   open, glass stops blurring: overlays then cover the whole window evenly. */
html:active-view-transition *,
html:active-view-transition *::before,
html:active-view-transition *::after { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
html:has(.modal-backdrop:not(.hidden), .dashboard-dialog-backdrop:not(.hidden), .cmd-palette-backdrop:not([hidden]), .nx-tplm-overlay.is-open, .wz:not([hidden]), .cb-launch.is-on, dialog[open]) :is(.topbar, .app-sidebar, .app-rightbar, .app-rightbar .panel) {
    -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
}

/* Animations switched off in /customize (layout.ejs data-no-motion, 2026-10-31). Duration 0
   instead of animation:none, so anything waiting for animationend still lands in its end state. */
html[data-no-motion] *,
html[data-no-motion] *::before,
html[data-no-motion] *::after,
html[data-no-motion]::view-transition-group(*),
html[data-no-motion]::view-transition-old(*),
html[data-no-motion]::view-transition-new(*) {
    animation-duration: 0s !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0s !important;
    transition-delay: 0s !important;
}
html[data-no-motion] { scroll-behavior: auto !important; }

/* Overview "Do this next" card, continue chip, Focus mode note (partials/nextStep.ejs, 2026-10-31). */
.nx-next { display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; gap: 1rem; padding: 1rem 1.25rem; margin-bottom: 1rem; }
.nx-next-ic { width: 2.5rem; height: 2.5rem; border-radius: 12px; display: grid; place-items: center; color: var(--brand); background: color-mix(in srgb, var(--text) 6%, transparent); }
.nx-next-copy { min-width: 0; display: grid; gap: .1rem; }
.nx-next-label { font-size: .78rem; font-weight: 600; color: var(--muted); }
.nx-next-copy b { font-size: 1.05rem; line-height: 1.3; }
.nx-next-copy small { color: var(--muted); font-size: .85rem; overflow-wrap: anywhere; }
.nx-next-side { display: grid; gap: .35rem; justify-items: end; min-width: 7rem; }
.nx-next-count { font-size: .82rem; font-weight: 600; color: var(--muted); white-space: nowrap; }
.nx-next-side .setup-progress { display: block; width: 7rem; margin: 0; }
.nx-next-go { white-space: nowrap; }
@media (max-width: 640px) {
    .nx-next { grid-template-columns: auto minmax(0, 1fr); }
    .nx-next-side { grid-column: 1 / -1; grid-row: 2; justify-items: start; grid-auto-flow: column; align-items: center; }
    .nx-next-go { grid-column: 1 / -1; justify-content: center; }
}
.nx-next-done { display: flex; align-items: center; gap: .5rem; color: var(--muted); margin: 0 0 1rem; }
.nx-next-done svg { color: #16a34a; }
.nx-continue { display: inline-flex; align-items: center; gap: .4rem; max-width: 100%; margin: 0 0 1rem; padding: .4rem .8rem; border-radius: 999px; font-size: .85rem; font-weight: 600;
    color: var(--text); background: color-mix(in srgb, var(--text) 6%, transparent); border: 1px solid var(--card-line, var(--line)); }
.nx-continue:hover { background: color-mix(in srgb, var(--text) 10%, transparent); }
.nx-continue span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nx-continue small { color: var(--muted); font-weight: 500; flex: none; }
.nx-focus-note { font-size: .82rem; color: var(--muted); margin: 0 0 1rem; }
.nx-focus-note a { color: var(--brand-ink, var(--brand)); font-weight: 600; }

/* Save tick (layout.ejs apiFetch) + "Unsaved changes · Save" bar (unsaved-guard.js), 2026-10-31. */
.nx-saved { position: relative; box-shadow: 0 0 0 2px #16a34a !important; }
.nx-saved::after { content: ""; position: absolute; top: -7px; right: -7px; width: 18px; height: 18px; border-radius: 50%; pointer-events: none; z-index: 2;
    background: #16a34a url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / 11px no-repeat;
    box-shadow: 0 0 0 2px var(--bg, #fff); animation: nxSavedPop .22s cubic-bezier(.2, .8, .2, 1.3); }
@keyframes nxSavedPop { from { transform: scale(.4); opacity: 0; } }
.nx-unsaved-bar { position: fixed; z-index: 1100; left: 50%; bottom: calc(16px + env(safe-area-inset-bottom, 0px)); transform: translateX(-50%);
    display: flex; align-items: center; gap: .9rem; max-width: calc(100vw - 32px); padding: .5rem .5rem .5rem 1rem; border-radius: 14px;
    background: var(--card-bg, var(--surface)); border: 1px solid var(--card-line, var(--line)); box-shadow: 0 12px 32px -12px rgba(0, 0, 0, .45);
    font-size: .9rem; font-weight: 600; animation: nxBarIn .2s ease-out; }
.nx-unsaved-bar[hidden] { display: none; }
.nx-unsaved-bar span::before { content: ""; display: inline-block; width: .5rem; height: .5rem; border-radius: 50%; background: #f59e0b; margin-right: .5rem; vertical-align: middle; }
@keyframes nxBarIn { from { opacity: 0; transform: translate(-50%, 8px); } }
@media (max-width: 640px) {
    /* Leaves the chat bubble (bottom right) free. */
    .nx-unsaved-bar { left: 16px; right: 84px; transform: none; justify-content: space-between; }
    @keyframes nxBarIn { from { opacity: 0; transform: translateY(8px); } }
}

/* Long helper text: one line + "?" to open (focus-text.js), 2026-10-31. */
.nx-clamp { position: relative; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; line-clamp: 1; overflow: hidden; padding-right: 1.6rem; }
.nx-clamp.is-open { display: block; -webkit-line-clamp: unset; line-clamp: unset; overflow: visible; }
.nx-clamp-more { position: absolute; right: 0; top: 50%; translate: 0 -50%; width: 1.15rem; height: 1.15rem; border-radius: 50%; display: grid; place-items: center;
    font-size: .7rem; font-weight: 700; line-height: 1; color: var(--muted); background: color-mix(in srgb, var(--text) 8%, transparent); border: 0; cursor: pointer; }
.nx-clamp.is-open .nx-clamp-more { top: auto; bottom: .1em; translate: none; }
.nx-clamp-more:hover, .nx-clamp-more:focus-visible { color: var(--text); background: color-mix(in srgb, var(--text) 14%, transparent); }
@media (pointer: coarse) { .nx-clamp-more { width: 1.5rem; height: 1.5rem; } .nx-clamp { padding-right: 2rem; } }
/* "Start from a preset" cards while a feature is still empty (guild-templates.js, 2026-10-31). */
.nx-tpl-strip { margin: -1rem 0 1.5rem; padding: 1rem; border-radius: 14px; border: 1px dashed var(--card-line, var(--line)); }
.nx-tpl-strip > p { margin: 0 0 .75rem; font-weight: 600; }

/* Settings page side rail (partials/sideRail.ejs, 2026-10-31): beside the form once the
   content area fits both, under it otherwise. Server pages scroll the window, so sticky holds. */
.nx-rail-wrap { container-type: inline-size; }
.nx-rail-grid > :first-child { min-width: 0; }
.nx-rail { display: grid; gap: .9rem; margin-top: 1rem; align-content: start; }
@container (min-width: 1060px) {
    .nx-rail-grid { display: grid; grid-template-columns: minmax(0, 760px) minmax(280px, 340px); gap: 1.5rem; align-items: start; }
    .nx-rail-grid > .nx-rail { position: sticky; top: calc(var(--topbar-height, 64px) + 16px); margin-top: 0; max-height: calc(100vh - var(--topbar-height, 64px) - 32px); overflow: auto; overscroll-behavior: contain; }
}
.nx-rail-card { border: 1px solid var(--card-line, var(--line)); border-radius: var(--radius-md, 14px); background: var(--card-bg); box-shadow: var(--card-hi); padding: 1rem 1.1rem; display: grid; gap: .7rem; }
.nx-rail-card[hidden] { display: none; }
.nx-rail-card h3 { font-weight: 800; font-size: .95rem; margin: 0; }
.nx-rail-stat { display: grid; gap: .45rem; font-size: .875rem; margin: 0; padding: 0; list-style: none; }
.nx-rail-stat li { display: flex; justify-content: space-between; gap: 1rem; }
.nx-rail-stat span { color: var(--muted); }
.nx-rail-stat b { font-weight: 700; text-align: right; }
.nx-rail-stat b.is-on::before, .nx-rail-stat b.is-off::before { content: ""; display: inline-block; width: .5rem; height: .5rem; border-radius: 50%; margin-right: .4rem; vertical-align: middle; background: #16a34a; }
.nx-rail-stat b.is-off::before { background: var(--muted); }
.nx-rail-links { display: grid; gap: .15rem; }
.nx-rail-links a { display: flex; align-items: center; gap: .6rem; padding: .45rem .55rem; border-radius: 10px; color: var(--text); font-size: .875rem; text-decoration: none; }
.nx-rail-links a svg { width: 16px; height: 16px; color: var(--muted); flex: none; }
.nx-rail-links a[aria-current] { background: color-mix(in srgb, var(--brand, #0062ff) 14%, transparent); font-weight: 700; }
@media (hover: hover) and (pointer: fine) { .nx-rail-links a:not([aria-current]):hover { background: color-mix(in srgb, var(--text) 6%, transparent); } }
/* A Discord embed as Discord shows it (dark Discord colours on purpose, in every theme). */
.nx-dm { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .6rem 1rem; padding: .75rem .9rem .85rem 1rem; border-radius: 6px; border-left: 4px solid var(--nx-dm, #0062FF); background: #2b2d31; color: #dbdee1; font-size: .85rem; line-height: 1.375; }
.nx-dm-title { font-weight: 700; color: #f2f3f5; margin-bottom: .2rem; }
.nx-dm-desc { white-space: pre-wrap; word-break: break-word; }
.nx-dm-desc b { color: #f2f3f5; } .nx-dm-desc b.h { font-size: 1rem; } .nx-dm-desc .m { color: #c9cdfb; background: rgba(88, 101, 242, .3); border-radius: 3px; padding: 0 2px; }
.nx-dm-thumb { grid-row: 1 / 3; grid-column: 2; width: 64px; height: 64px; border-radius: 4px; object-fit: cover; }
.nx-dm-img { grid-column: 1 / -1; max-width: 100%; border-radius: 4px; }
.nx-dm-btn { grid-column: 1 / -1; justify-self: start; padding: .35rem .9rem; border-radius: 4px; background: #4e5058; color: #fff; font-weight: 600; font-size: .85rem; }

/* Bar A (layout.ejs .topbar-a, 2026-10-31): app pages, signed in. Noxyr and server on the
   left, search mid-bar, then Resources, Support, Vote, Donors and the picture. Language, theme
   and the Custom Bot | Dashboard switch sit in the picture menu. */
/* No divider line after the brand (Mike), and a bigger wordmark. */
.topbar.topbar-a .brand-link { border-right: 0; min-width: 0; padding-right: 4px; flex: none; } /* picker sits right after "Noxyr", no 200px sidebar gap (Mike 2026-11-05) */
@media (min-width: 641px) { .topbar.topbar-a .brand-text { font-size: 18px; font-weight: 800; } } /* phones keep their own 21px */
.topbar-a .user-copy { display: none; }
.topbar.topbar-a .profile-menu-btn { width: auto; gap: 4px; }
.topbar.topbar-a .profile-menu-chevron { display: block; flex: none; width: 14px; transition: transform .15s ease; } /* the arrow stays at every width (mobile-layout.css hides it below 1180px) */
.topbar-a .profile-menu-btn[aria-expanded="true"] .profile-menu-chevron { transform: rotate(180deg); }
@media (min-width: 1181px) {
    .topbar.topbar-a > .topbar-spacer { flex: 1 1 0; }
    .topbar.topbar-a .topbar-actions { flex: 0 0 auto; }
    .topbar.topbar-a .topbar-actions > .topbar-spacer { display: none; }
    .has-guild .topbar.topbar-a .topbar-search { display: block; width: min(420px, 30vw); }
    .has-guild .topbar.topbar-a .topbar-search-btn { display: none; }
    /* Room enough now: Vote keeps its word (the 1181-1460px rule above made it icon-only). */
    .has-guild .topbar.topbar-a .topbar-vote-btn.topbar-vote-btn { width: auto; padding: 0 .85rem 0 .65rem; }
    .has-guild .topbar.topbar-a .topbar-vote-btn > span { display: inline; }
}
.profile-menu-panel .app-switch { display: flex; margin: .5rem .15rem; box-shadow: none; }
.profile-menu-panel .app-switch > a, .profile-menu-panel .app-switch > .nx-peek { flex: 1 1 0; }
.profile-menu-panel .app-switch .app-switch-btn { width: 100%; justify-content: center; }
/* The bar's 1181-1400px rule shrinks the switch to icons; in the menu there is room. */
.has-guild .topbar .profile-menu-panel .app-switch-btn span { position: static; width: auto; height: auto; overflow: visible; clip-path: none; }
.profile-menu-panel .nx-peek-card { display: none; }
.profile-menu-look { display: flex; align-items: center; gap: .5rem; margin-top: .35rem; padding: .5rem .35rem; border-top: 1px solid var(--line); }
.profile-menu-look #themeSky { order: -1; margin-inline-end: auto; }
/* mobile-layout.css hides the bar's switch below 1180px and the day/night switch below
   480px (the bar had no room); inside the menu both stay. */
@media (max-width: 1180px) { .dashboard-root .topbar .profile-menu-panel .app-switch { display: flex; } }
@media (min-width: 1181px) { .profile-menu-panel .app-switch { display: none; } } /* in the bar there */
.dashboard-root .topbar .profile-menu-look #themeSky { display: flex; }

/* Vote: solid gold star, gold pill. Light themes get a pale gold button; dark themes a
   gold-tinted glass one. Beats server-unslop.css, which greys bar promos out. */
.dashboard-root .topbar.topbar-a .topbar-vote-btn.topbar-vote-btn {
    gap: .4rem; font-weight: 800; letter-spacing: .01em;
    color: #8a5a00 !important; border: 1px solid #f3c64f;
    background: linear-gradient(180deg, #fff6d8, #ffe9a8); box-shadow: inset 0 1px 0 #fff;
    animation: none; transition: background .15s ease, border-color .15s ease;
}
html:is([data-theme="dyno"], [data-theme="super"], [data-theme="dusk"]) .dashboard-root .topbar.topbar-a .topbar-vote-btn.topbar-vote-btn {
    color: #ffd86b !important; border-color: rgba(255, 200, 61, .35);
    background: linear-gradient(180deg, rgba(255, 200, 61, .16), rgba(242, 154, 0, .08));
    box-shadow: inset 0 1px 0 rgba(255, 236, 170, .18);
}
@media (hover: hover) and (pointer: fine) {
    .dashboard-root .topbar.topbar-a .topbar-vote-btn.topbar-vote-btn:hover { background: linear-gradient(180deg, #fff1c2, #ffdc80); border-color: #e8b130; animation: none; }
    html:is([data-theme="dyno"], [data-theme="super"], [data-theme="dusk"]) .dashboard-root .topbar.topbar-a .topbar-vote-btn.topbar-vote-btn:hover {
        background: linear-gradient(180deg, rgba(255, 200, 61, .26), rgba(242, 154, 0, .14)); border-color: rgba(255, 200, 61, .6);
    }
}
.topbar-vote-btn .vstar { width: 1.2rem; height: 1.2rem; flex: none; color: inherit !important; filter: drop-shadow(0 1px 2px rgba(242, 154, 0, .45)); transition: transform .35s cubic-bezier(.34, 1.56, .64, 1); }
.topbar-vote-btn.topbar-vote-btn:hover .vstar { transform: rotate(72deg) scale(1.12); }
@media (prefers-reduced-motion: reduce) { .topbar-vote-btn .vstar { transition: none; } .topbar-vote-btn.topbar-vote-btn:hover .vstar { transform: none; } }
html[data-no-motion] .topbar-vote-btn.topbar-vote-btn:hover .vstar { transform: none; }

/* Business button (2026-11-04). Signed out it sits before Add Bot / Log in; below
   1181px the menu already lists Business, so the bar drops it and never overflows. */
.topbar .topbar-biz { flex: none; margin-inline-start: .75rem; }
.topbar .topbar-biz + .topbar-add-bot { margin-inline-start: .5rem; }
@media (max-width: 1180px) { .topbar .topbar-biz { display: none; } }

/* Server picker on bars with no server open (layout.ejs .guild-switcher-none, Mike
   2026-11-05). The site bar is full between 1181 and 1600px (menus + Vote + Donors +
   language + picture + Custom Bot | Business | Dashboard): the picker shows its icon
   only there, so the switch never spills off the right edge. */
.guild-switcher-none .guild-switcher-fallback { display: inline-grid; place-items: center; }
@media (min-width: 1181px) and (max-width: 1600px) {
    .topbar-home .guild-switcher-none .guild-switcher-name { display: none; }
}

/* Payment marks (views/partials/payLogo.ejs, public/pay-logos). */
.pay-logos { display: inline-flex; align-items: center; gap: 3px; height: 22px; padding: 0 5px; margin-inline-end: 6px; vertical-align: middle; border-radius: 6px; background: #fff; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .08); }
.pay-logos .pay-logo, .dn-co-logos .pay-logo { display: block; height: 15px; width: auto; max-width: 40px; object-fit: contain; }
.pay-logos .pay-logo-upi { height: 13px; max-width: 44px; }

/* Discord, YouTube and X under the logo in the site footer. */
.site-footer-social { display: flex; gap: .5rem; margin-top: .9rem; }
.site-footer-social a { display: grid; place-items: center; width: 2.5rem; height: 2.5rem; border: 1px solid var(--line); border-radius: 12px; color: var(--muted); transition: color .15s ease, border-color .15s ease; }
.site-footer-social a:hover { color: var(--text); border-color: color-mix(in srgb, var(--brand) 55%, var(--line)); }
.site-footer-social a:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* "By Mike" on docs and articles (views/partials/authorByline.ejs). */
.author-byline { display: inline-flex; align-items: center; gap: .35em; color: inherit; text-decoration: none; vertical-align: bottom; }
.author-byline:hover span { text-decoration: underline; }
.author-byline img { width: 1.5em; height: 1.5em; border-radius: 50%; object-fit: cover; }

/* Official sources under an article. */
.article-sources { margin-top: 2rem; }
.article-sources h2 { font-size: 1.1rem; margin-bottom: .5rem; }
.article-sources ul { display: flex; flex-wrap: wrap; gap: .4rem 1.1rem; padding: 0; list-style: none; }
.article-sources a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

/* Written intro above a tutorial lesson's steps. */
.tut-lesson-about { margin: 0 0 1rem; line-height: 1.6; }

/* "Updated" pill + date on docs, articles, tutorials and tools (partials/updatedBadge.ejs). */
.nx-updated { display: inline-flex; align-items: center; gap: .45rem; vertical-align: middle; color: var(--muted); font-size: 12px; font-weight: 700; }
.nx-updated-badge {
    display: inline-flex; align-items: center; gap: .3rem;
    padding: 2px 8px; border-radius: 999px;
    border: 1px solid color-mix(in srgb, var(--muted) 35%, transparent);
    font-size: 10px; font-weight: 900; letter-spacing: .04em; text-transform: uppercase; line-height: 1.5;
}
.nx-updated.is-fresh .nx-updated-badge {
    color: var(--brand, #0062ff);
    border-color: color-mix(in srgb, var(--brand, #0062ff) 40%, transparent);
    background: color-mix(in srgb, var(--brand, #0062ff) 10%, transparent);
}
.nx-updated.is-fresh .nx-updated-badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.docs-card .nx-updated { display: flex; margin-top: .55rem; }
.tut-lesson-head .nx-updated { margin-top: .4rem; }
