/* Public server pages — servers.cubsoftware.site/<vanity>

   Deliberately standalone: this page is served to people who have never seen
   CUB Software and may be on a phone on mobile data, so it pulls in no shared
   stylesheet, no font, and no script. One file, no requests beyond the images.

   It also renders in whatever theme the visitor's device prefers, because a
   shared link opens wherever it opens. */

:root {
    --sp-bg: #f6f7fb;
    --sp-card: #ffffff;
    --sp-text: #15181d;
    --sp-muted: #5b6070;
    --sp-line: rgba(21, 24, 29, .10);
    --sp-accent: #a50f12;
    --sp-accent-text: #ffffff;
    --sp-shadow: 0 1px 2px rgba(14, 16, 19, .06), 0 8px 24px rgba(14, 16, 19, .06);
}

@media (prefers-color-scheme: dark) {
    :root {
        --sp-bg: #0e1013;
        --sp-card: #15181d;
        --sp-text: #eef0f6;
        --sp-muted: #9aa1b4;
        --sp-line: rgba(255, 255, 255, .09);
        --sp-shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 8px 24px rgba(0, 0, 0, .35);
    }
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--sp-bg);
    color: var(--sp-text);
    font: 16px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
}

.sp {
    max-width: 720px;
    margin: 0 auto;
    padding: 2.5rem 1.1rem 4rem;
}

/* ── hero ─────────────────────────────────────────────────────────────── */
.sp-hero { text-align: center; margin-bottom: 2.5rem; }

.sp-icon {
    width: 96px; height: 96px;
    border-radius: 24px;
    object-fit: cover;
    box-shadow: var(--sp-shadow);
}

.sp-icon-blank {
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--sp-accent); color: var(--sp-accent-text);
    font-size: 2.5rem; font-weight: 700;
}

.sp-name {
    margin: 1rem 0 .35rem;
    font-size: clamp(1.6rem, 5vw, 2.25rem);
    line-height: 1.2;
    letter-spacing: -.02em;
}

.sp-tagline {
    margin: 0 auto;
    max-width: 46ch;
    color: var(--sp-muted);
}

.sp-counts {
    display: flex; flex-wrap: wrap; gap: 1.1rem;
    justify-content: center;
    margin-top: 1rem;
    color: var(--sp-muted);
    font-size: .92rem;
}
.sp-counts strong { color: var(--sp-text); }

/* The online count reads as a status, so it carries the usual live dot. */
.sp-online::before {
    content: '';
    display: inline-block;
    width: .5rem; height: .5rem;
    margin-right: .4rem;
    border-radius: 50%;
    background: #3ba55d;
    vertical-align: baseline;
}

/* In voice right now: the same kind of live status as "online", so the same
   dot — pulsing, because a voice count is the most "right now" figure here. */
.sp-voice::before {
    content: '';
    display: inline-block;
    width: .5rem; height: .5rem;
    margin-right: .4rem;
    border-radius: 50%;
    background: #3ba55d;
    vertical-align: baseline;
    animation: sp-pulse 2s infinite;
}
@media (prefers-reduced-motion: reduce) { .sp-voice::before { animation: none; } }

.sp-join {
    display: inline-block;
    margin-top: 1.5rem;
    padding: .8rem 1.6rem;
    border-radius: 999px;
    background: var(--sp-accent);
    color: var(--sp-accent-text);
    font-weight: 600;
    text-decoration: none;
    box-shadow: var(--sp-shadow);
}
.sp-join:hover {
    filter: brightness(1.08);
    /* shared.css sets `a:hover { color: var(--primary-color) }`, which is the
       same colour as this button's background — the label vanished on hover.
       .sp-join:hover (0,2,0) outranks a:hover (0,1,1), but only for properties
       it actually declares, so the colour has to be restated here. */
    color: var(--sp-accent-text);
}
.sp-join-small { margin-top: 0; padding: .6rem 1.25rem; font-size: .95rem; }

/* ── sections ─────────────────────────────────────────────────────────── */
.sp-section {
    background: var(--sp-card);
    border: 1px solid var(--sp-line);
    border-radius: 16px;
    padding: 1.5rem;
    margin-bottom: 1.1rem;
    box-shadow: var(--sp-shadow);
}

.sp-section h2 {
    margin: 0 0 .2rem;
    font-size: 1.15rem;
    letter-spacing: -.01em;
}

.sp-sub {
    margin: 0 0 1.15rem;
    color: var(--sp-muted);
    font-size: .9rem;
}

.sp-emoji { margin-right: .35rem; }

/* ── self-roles ───────────────────────────────────────────────────────── */
.sp-cats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 1rem;
}

.sp-cat h3 { margin: 0 0 .3rem; font-size: 1rem; }
.sp-cat-desc { margin: 0 0 .5rem; color: var(--sp-muted); font-size: .87rem; }

.sp-roles { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem; }
.sp-roles li {
    padding: .25rem .6rem;
    border: 1px solid var(--sp-line);
    border-radius: 999px;
    font-size: .85rem;
}

/* ── leaderboard ──────────────────────────────────────────────────────── */
.sp-board { list-style: none; margin: 0; padding: 0; }

.sp-row {
    display: grid;
    grid-template-columns: 1.75rem 32px 1fr auto auto;
    align-items: center;
    gap: .7rem;
    padding: .55rem 0;
    border-top: 1px solid var(--sp-line);
}
.sp-row:first-child { border-top: 0; }

.sp-rank { color: var(--sp-muted); font-variant-numeric: tabular-nums; text-align: right; font-size: .9rem; }
.sp-rank-1 { color: #d4a017; font-weight: 700; }
.sp-rank-2 { color: #9099ad; font-weight: 700; }
.sp-rank-3 { color: #b06f3c; font-weight: 700; }

.sp-avatar { width: 32px; height: 32px; border-radius: 50%; object-fit: cover; }
.sp-avatar-blank {
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--sp-line); color: var(--sp-muted);
    font-size: .85rem; font-weight: 600;
}

.sp-member { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sp-level { color: var(--sp-muted); font-size: .85rem; }
.sp-xp { color: var(--sp-muted); font-size: .85rem; font-variant-numeric: tabular-nums; }

/* On a narrow screen the XP column is the first thing worth dropping — the
   level already says the same thing in fewer characters. */
@media (max-width: 460px) {
    .sp-row { grid-template-columns: 1.5rem 28px 1fr auto; }
    .sp-avatar, .sp-avatar-blank { width: 28px; height: 28px; }
    .sp-xp { display: none; }
}

/* ── rules ────────────────────────────────────────────────────────────── */
.sp-rules { margin: 0; padding-left: 1.2rem; }
.sp-rules li { margin-bottom: .9rem; }
.sp-rules li:last-child { margin-bottom: 0; }
.sp-rules h3 { margin: 0 0 .15rem; font-size: .98rem; }
.sp-rules p { margin: 0; color: var(--sp-muted); font-size: .92rem; }

/* ── footer ───────────────────────────────────────────────────────────── */
.sp-footer { text-align: center; margin-top: 2rem; }
.sp-by { margin: 1.2rem 0 0; color: var(--sp-muted); font-size: .82rem; }
.sp-by a { color: inherit; }


/* ── Links inside the page body ────────────────────────────────────────────
   shared.css styles bare `a` and `a:hover` for the main site. This page has its
   own palette, so anchors inside it are re-anchored to the page's tokens rather
   than picking up the site's white-then-accent behaviour. */
.sp a:not(.sp-join) {
    color: var(--sp-accent);
    text-decoration: none;
}
.sp a:not(.sp-join):hover {
    color: var(--sp-accent);
    text-decoration: underline;
}

/* ══ Sections added 14 Aug 2026 ═══════════════════════════════════════════
   Everything here fills from data the bot already has, so a server switching
   one on sees content immediately rather than waiting for it to accumulate. */

/* ── Tags: what the server is about, at a glance ────────────────────────── */
.sp-tags { display: flex; flex-wrap: wrap; justify-content: center; gap: .4rem; margin: .9rem 0 0; }
.sp-tag {
    padding: .25rem .7rem;
    border-radius: 999px;
    background: var(--sp-card);
    border: 1px solid var(--sp-line);
    font-size: .82rem;
}

/* ── Live row: the "is anyone here" signals, kept close to the hero ─────── */
.sp-live {
    display: flex; flex-wrap: wrap; gap: 1rem;
    margin: 1rem 0 0; font-size: .9rem; opacity: .9;
}
.sp-live-item { display: inline-flex; align-items: center; gap: .4rem; }
/* A pulsing dot reads as "now" far faster than the word does. */
.sp-dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: #3ba55d;
    box-shadow: 0 0 0 0 rgba(59, 165, 93, .7);
    animation: sp-pulse 2s infinite;
}
@keyframes sp-pulse {
    70%  { box-shadow: 0 0 0 7px rgba(59, 165, 93, 0); }
    100% { box-shadow: 0 0 0 0 rgba(59, 165, 93, 0); }
}
@media (prefers-reduced-motion: reduce) { .sp-dot { animation: none; } }

/* ── Events ─────────────────────────────────────────────────────────────── */
.sp-events { list-style: none; padding: 0; margin: 0; display: grid; gap: .9rem; }
.sp-event { display: flex; gap: .9rem; align-items: flex-start; }
.sp-event-cover { width: 96px; border-radius: 10px; flex-shrink: 0; }
.sp-event-body h3 { margin: 0 0 .2rem; font-size: 1rem; }
.sp-event-when { margin: 0 0 .3rem; font-size: .85rem; opacity: .75; }
.sp-event-desc { margin: 0; font-size: .9rem; }
.sp-event-count { margin: .3rem 0 0; font-size: .8rem; opacity: .6; }

/* ── Giveaways ──────────────────────────────────────────────────────────── */
.sp-giveaways { list-style: none; padding: 0; margin: 0; display: grid; gap: .6rem; }
.sp-giveaway {
    display: flex; justify-content: space-between; align-items: center;
    flex-wrap: wrap; gap: .4rem;
    padding: .7rem .9rem; border-radius: 10px;
    background: var(--sp-card); border: 1px solid var(--sp-line);
}
.sp-prize { font-weight: 600; }
.sp-giveaway-meta { font-size: .82rem; opacity: .7; }

/* ── Activity sparkline ──────────────────────────────────────────────────
   Bars are percentage heights set inline, so there is no chart library and
   nothing to load. */
.sp-activity-lead { margin: 0 0 .8rem; font-size: .92rem; }
.sp-spark {
    display: flex; align-items: flex-end; gap: 2px;
    height: 64px; padding: 0;
}
.sp-spark-bar {
    flex: 1; min-height: 2px;
    background: var(--sp-accent);
    border-radius: 2px 2px 0 0;
    opacity: .75;
}

/* ── Staff ──────────────────────────────────────────────────────────────── */
/* One card per person, stacked: avatar, role, then name.
   The previous layout put all three on one line, which fell apart the moment a
   server used a decorated role name — "╭───𒌋𒀖 「🜲・Admin」" wrapped across the
   card and collided with the one beside it. Stacking removes the failure mode
   entirely rather than tuning widths around it. */
.sp-staff {
    list-style: none; padding: 0; margin: 0;
    display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: .6rem;
}
.sp-staff-member {
    display: flex; flex-direction: column; align-items: center; text-align: center;
    gap: .35rem;
    padding: .9rem .5rem .8rem; border-radius: 12px;
    background: var(--sp-card); border: 1px solid var(--sp-line);
}
.sp-staff-member img,
.sp-staff-blank {
    width: 48px; height: 48px; border-radius: 50%; flex-shrink: 0;
}
/* No avatar set — an initial reads better than a broken image frame. */
.sp-staff-blank {
    display: grid; place-items: center;
    background: var(--sp-accent); color: var(--sp-accent-text);
    font-weight: 700; font-size: 1.1rem;
}
.sp-staff-role {
    font-size: .68rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
    color: var(--sp-accent);
    line-height: 1.2;
}
.sp-staff-name {
    font-size: .85rem; font-weight: 600;
    /* Names can be long. One line with an ellipsis keeps every card the same
       height, which is what makes the grid read as a grid. */
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ── Channels ───────────────────────────────────────────────────────────── */
.sp-channels { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: .4rem; }
.sp-channel {
    padding: .3rem .65rem; border-radius: 8px;
    background: var(--sp-card); border: 1px solid var(--sp-line);
    font-size: .84rem;
}
.sp-channel-voice { opacity: .85; }

/* ── Emojis ─────────────────────────────────────────────────────────────── */
.sp-emojis { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: .5rem; }
.sp-emojis img { width: 32px; height: 32px; }

/* ── FAQ ────────────────────────────────────────────────────────────────── */
.sp-faq { margin: 0; }
.sp-faq dt { font-weight: 600; margin-top: .8rem; }
.sp-faq dt:first-child { margin-top: 0; }
.sp-faq dd { margin: .25rem 0 0; opacity: .85; font-size: .92rem; }

/* ── Links ──────────────────────────────────────────────────────────────── */
.sp-links { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: .5rem; }
.sp-links a {
    display: inline-block; padding: .4rem .8rem;
    border-radius: 999px; background: var(--sp-card);
    border: 1px solid var(--sp-line); font-size: .88rem;
}

/* ── Narrow screens ─────────────────────────────────────────────────────── */
@media (max-width: 600px) {
    .sp-event { flex-direction: column; }
    .sp-event-cover { width: 100%; }
    .sp-staff { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
    .sp-spark { height: 48px; }
}
