/* ==========================================================================
   YSN — THEME "PRECISION" (Style A)
   ==========================================================================
   Loaded LAST, after style.css and ysn-ui.css. It does two jobs:

     1. Re-points every existing design token to the Precision palette. Because
        the whole site already reads var(--primary), var(--dark-2), var(--text)
        and so on, retoning the tokens retones ~80% of the interface without
        touching a single class name, id or JS hook.

     2. Restyles the components that need more than a colour change: the nav,
        header, cards, buttons, tables, forms, modals, empty states, toasts,
        clan-war scorelines and the roster.

   HARD RULES OBSERVED HERE
     - No class name, id, data-attribute or DOM structure is changed. Every
       JS selector in the 21 page scripts keeps working.
     - The role badges (.role-badge / .rb-shine) are deliberately left alone.
       The owner asked to keep them exactly as they are, including the
       running shine line. See "ROLE BADGES — PRESERVED" at the bottom.
     - Glow is not an elevation mechanic. --shadow-glow becomes a real shadow.
     - Purple has four jobs: primary action, active state, focus ring,
       accent tint. Green and red mean win and loss and nothing else.
   ========================================================================== */

/* ==================== 1. TOKENS ==================== */

:root {
    /* --- one purple, no cyan, no magenta --- */
    --primary:        #7C5CFF;
    --primary-dark:   #6A47F0;
    --primary-light:  #957AFF;
    --primary-glow:   rgba(124, 92, 255, 0.28);
    --primary-tint:   rgba(124, 92, 255, 0.10);
    --primary-line:   rgba(124, 92, 255, 0.32);

    /* --secondary and --accent used to be cyan and magenta. Folding them
       into the purple ramp is what removes the "gradient soup" look. */
    --secondary:      #957AFF;
    --accent:         #957AFF;
    --info:           #7FA6FF;

    /* --- result colours: match outcomes only --- */
    --success:        #3DDC84;
    --warning:        #FFC24B;
    --danger:         #FF5A54;

    /* --- surfaces: neutral, five even steps --- */
    --dark:           #08080A;
    --dark-2:         #0E0E12;
    --dark-3:         #14141A;
    --dark-4:         #1B1B23;
    --dark-5:         #24242F;

    /* --- ink: every step clears 4.5:1 on --dark-3 --- */
    --text:           #EEEEF4;
    --text-primary:   #EEEEF4;   /* several rules reference this name */
    --text-secondary: #A9A9B8;
    --text-muted:     #8A8A99;
    --text-dark:      #08080A;

    /* --- lines: neutral hairlines, not purple haze --- */
    --border:         rgba(255, 255, 255, 0.07);
    --border-light:   rgba(255, 255, 255, 0.05);
    --divider:        rgba(255, 255, 255, 0.12);

    /* --- gradients flattened: kept as variables so nothing breaks --- */
    --gradient-primary:     linear-gradient(180deg, #7C5CFF 0%, #6F4EF5 100%);
    --gradient-secondary:   linear-gradient(180deg, #3DDC84 0%, #2FC272 100%);
    --gradient-accent:      linear-gradient(180deg, #957AFF 0%, #7C5CFF 100%);
    --gradient-dark:        linear-gradient(180deg, #0E0E12 0%, #08080A 100%);
    --gradient-purple-blue: linear-gradient(120deg, #C9BBFF 0%, #7C5CFF 100%);

    /* --- elevation: two real shadows. Glow is retired. --- */
    --shadow-sm:          0 1px 2px rgba(0, 0, 0, 0.45);
    --shadow-md:          0 1px 2px rgba(0, 0, 0, 0.45), 0 8px 24px -12px rgba(0, 0, 0, 0.7);
    --shadow-lg:          0 2px 4px rgba(0, 0, 0, 0.5),  0 20px 48px -18px rgba(0, 0, 0, 0.8);
    --shadow-xl:          0 2px 4px rgba(0, 0, 0, 0.5),  0 32px 72px -24px rgba(0, 0, 0, 0.9);
    --shadow-glow:        0 1px 2px rgba(0, 0, 0, 0.45), 0 8px 24px -12px rgba(0, 0, 0, 0.7);
    --shadow-glow-strong: 0 2px 4px rgba(0, 0, 0, 0.5),  0 20px 48px -18px rgba(0, 0, 0, 0.8);

    /* --- tight, instrument-like corners --- */
    --radius-sm:   3px;
    --radius-md:   4px;
    --radius-lg:   6px;
    --radius-xl:   8px;
    --radius-full: 999px;

    /* --- motion --- */
    --transition-fast:   0.12s cubic-bezier(.2,.8,.2,1);
    --transition-normal: 0.20s cubic-bezier(.2,.8,.2,1);
    --transition-slow:   0.32s cubic-bezier(.2,.8,.2,1);

    /* --- type: three roles, all self-hosted --- */
    --font-primary: Barlow, system-ui, -apple-system, 'Segoe UI', sans-serif;
    --font-heading: 'Barlow Condensed', Barlow, system-ui, sans-serif;
    --font-mono:    'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

    /* ysn-ui.css scales the whole UI from this. Slightly tighter. */
    --ysn-root-size: clamp(14.5px, 0.11vw + 12.8px, 15.5px);
}

/* ==================== 2. BASE ==================== */

body {
    background: var(--dark);
    color: var(--text);
    font-family: var(--font-primary);
    line-height: 1.55;
}

/* The old ambient purple wash made every surface read as purple. */
body::before { opacity: 0.35 !important; }

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-heading);
    letter-spacing: -0.02em;
    line-height: 1.1;
}
h1 { font-weight: 800; }
h2, h3 { font-weight: 700; }

/* Numeric data is monospaced and tabular across the whole site — this is a
   SA:MP clan site and scores, ping, IPs and formats are its vocabulary. */
.stat-value, .cw-score, .cw-stat-value, .stat-box-value, .forum-stat-value,
.gallery-stat-value, .profile-stat-value, .hero-stat-value, .quick-stat-value,
.countdown-number, .admin-stat-value, .section-count, .category-count,
#currentTime, #onlineCount, .server-ping, .server-ip, .shout-time,
.news-date, .thread-meta, .cw-info, .member-meta, .admin-table td .mono {
    font-variant-numeric: tabular-nums;
}
.stat-value, .cw-stat-value, .stat-box-value, .forum-stat-value,
.gallery-stat-value, .profile-stat-value, .hero-stat-value,
.quick-stat-value, .countdown-number, .admin-stat-value {
    font-family: var(--font-heading);
    font-weight: 800;
    letter-spacing: -0.03em;
}

/* Micro-labels: uppercase mono, wide tracking. The structural device of the
   whole theme — it is what makes the interface read as an instrument. */
.stat-label, .cw-stat-label, .stat-box-label, .forum-stat-label,
.gallery-stat-label, .profile-stat-label, .hero-stat-label,
.countdown-label, .cw-detail-label, .admin-stat-label {
    font-family: var(--font-mono);
    font-size: 0.68rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* --- visible keyboard focus on everything. Previously: nothing. --- */
:where(a, button, input, select, textarea, summary, [tabindex], .member-card,
       .cw-item, .forum-thread, .forum-category, .gallery-card, .gallery-item,
       .tab-btn, .admin-nav-item, .nav-link, .server-ip):focus-visible {
    outline: 2px solid var(--primary-light);
    outline-offset: 2px;
    border-radius: var(--radius-md);
}

/* --- reduced motion: silences all six previously-infinite animations --- */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ==================== 3. TOP BAR ==================== */

.top-bar {
    background: var(--dark-2);
    border-bottom: 1px solid var(--border);
    padding: 0;
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.05em;
}
.top-bar .container { min-height: 34px; }
.top-bar-item, .top-bar-link { color: var(--text-muted); }
.top-bar-item strong { color: var(--text-secondary); font-weight: 500; }
.top-bar-link:hover { color: var(--primary-light); }
.top-bar-separator { color: var(--divider); }

/* ==================== 4. HEADER ==================== */

.site-header {
    background: var(--dark);
    border-bottom: 1px solid var(--border);
    padding: 1.15rem 0;
}
.header-bg { display: none; }

.header-logo {
    width: 44px;
    height: 44px;
    border: 1px solid var(--primary-line);
    border-radius: var(--radius-md);
    box-shadow: none;
    object-fit: cover;
}
.header-logo:hover { transform: none; border-color: var(--primary); }

.header-title { font-weight: 800; letter-spacing: -0.015em; }
.clan-tag { color: var(--primary-light); }
.header-tagline {
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* Per the agreed change: the stat strip lives on the homepage only.
   index.html carries <body class="is-home">; every other page hides it. */
.header-stats { display: none; }
body.is-home .header-stats { display: flex; }

.header-stats .stat-card {
    background: transparent;
    border: 0;
    border-left: 1px solid var(--border);
    border-radius: 0;
    padding: 0.15rem 0 0.15rem 1.25rem;
    min-width: 0;
    text-align: left;
}
.header-stats .stat-card:first-child { border-left: 0; padding-left: 0; }
.header-stats .stat-card::before { display: none; }
.header-stats .stat-card:hover {
    transform: none;
    border-color: var(--border);
    box-shadow: none;
}
.header-stats .stat-value { font-size: 1.6rem; color: var(--text); }
.header-stats .stat-label { margin-top: 0.2rem; }

/* ==================== 5. NAVIGATION ==================== */

.main-nav {
    background: var(--dark);
    border-bottom: 1px solid var(--border);
    backdrop-filter: none;
}
.nav-link {
    padding: 0.95rem 1rem;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-secondary);
    border-bottom: 2px solid transparent;
}
.nav-link::before { display: none; }
/* .nav-link:hover previews the active state: the label and its icon turn
   purple and a dim underline appears where the active page's solid one
   sits. Purple was the base stylesheet's original hover colour; the theme
   had flattened it to plain white. */
.nav-link:hover { color: var(--primary-light); background: var(--primary-tint); border-bottom-color: var(--primary-line); }
.nav-link:hover svg { opacity: 1; }
.nav-link.active { color: var(--text); border-bottom-color: var(--primary); }
.nav-link.active:hover { color: var(--primary-light); border-bottom-color: var(--primary); }
.nav-link svg { opacity: 0.55; width: 15px; height: 15px; transition: opacity var(--transition-fast); }
.nav-link.active svg { opacity: 1; color: var(--primary-light); }

.nav-btn {
    background: transparent;
    border: 1px solid var(--divider);
    border-radius: var(--radius-md);
    padding: 0.45rem 0.85rem;
    font-size: 0.8rem;
    font-weight: 500;
}
.nav-btn:hover { transform: none; background: var(--dark-3); border-color: var(--divider); color: var(--text); }
.nav-btn-primary { background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 600; }
.nav-btn-primary:hover { background: var(--primary-dark); border-color: var(--primary-dark); box-shadow: none; color: #fff; }

.user-trigger { background: transparent; border: 1px solid var(--divider); border-radius: var(--radius-md); }
.user-trigger:hover { background: var(--dark-3); }
.user-avatar { border-radius: var(--radius-sm); border: 1px solid var(--primary-line); }
.dropdown-menu { background: var(--dark-3); border: 1px solid var(--divider); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); }
.dropdown-item:hover { background: var(--dark-4); color: var(--primary-light); padding-left: var(--space-md); }

/* ==================== 6. BUTTONS ==================== */

.btn {
    border-radius: var(--radius-md);
    border: 1px solid var(--divider);
    background: transparent;
    font-family: var(--font-primary);
    font-weight: 500;
    letter-spacing: 0.01em;
}
/* the 300px expanding white circle on hover is retired */
.btn::before { display: none !important; }
.btn:hover {
    transform: none;
    background: var(--dark-4);
    border-color: var(--divider);
    color: var(--text);
    box-shadow: none;
}
.btn:active { transform: translateY(1px); }

.btn-primary { background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 600; }
.btn-primary:hover { background: var(--primary-dark); border-color: var(--primary-dark); color: #fff; box-shadow: none; transform: none; }

.btn-secondary { background: transparent; border-color: var(--primary-line); color: var(--primary-light); }
.btn-secondary:hover { background: var(--primary-tint); border-color: var(--primary); color: var(--primary-light); box-shadow: none; transform: none; }

.btn-success { background: transparent; border-color: rgba(61,220,132,.4); color: var(--success); }
.btn-success:hover { background: rgba(61,220,132,.1); color: var(--success); }

.btn-warning { background: transparent; border-color: rgba(255,194,75,.4); color: var(--warning); }
.btn-warning:hover { background: rgba(255,194,75,.1); color: var(--warning); }

.btn-danger { background: transparent; border-color: rgba(255,90,84,.4); color: var(--danger); }
.btn-danger:hover { background: rgba(255,90,84,.1); color: var(--danger); }

.btn-discord { background: #5865F2; border-color: #5865F2; color: #fff; }
.btn-discord:hover { background: #4752C4; border-color: #4752C4; color: #fff; box-shadow: none; transform: none; }

.btn-large { padding: 0.65rem 1.15rem; font-size: 0.9rem; font-weight: 600; }
.btn-sm { padding: 0.3rem 0.65rem; font-size: 0.78rem; }

/* ==================== 7. CARDS, WIDGETS, SECTIONS ==================== */

.card, .widget {
    background: var(--dark-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    transition: border-color var(--transition-fast);
}
.card:hover, .widget:hover { border-color: var(--divider); box-shadow: none; }

.card-header, .widget-header {
    background: transparent;
    border-bottom: 1px solid var(--border);
}
.card-header h3 { font-size: 0.95rem; font-weight: 700; letter-spacing: 0.01em; }
.widget-header {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--text-secondary);
}
.card-header-subtitle { font-size: 0.8rem; color: var(--text-muted); }
.card-link { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--primary-light); }
.card-link:hover { transform: none; color: var(--primary-light); text-decoration: underline; text-underline-offset: 3px; }

.page-hero {
    background: var(--dark-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    text-align: left;
}
.page-hero::before { display: none; }
.page-hero h1, .page-hero h2, .hero-title { font-weight: 800; letter-spacing: -0.035em; }
.hero-description, .page-hero p { margin-inline: 0; color: var(--text-secondary); }
.hero-actions { justify-content: flex-start; }
.gradient-text {
    background: none;
    -webkit-text-fill-color: currentColor;
    color: var(--primary-light);
}

.page-header-section { border-bottom: 1px solid var(--border); padding-bottom: var(--space-lg); }
.page-title { font-weight: 800; letter-spacing: -0.03em; }
.page-subtitle { color: var(--text-muted); font-size: 0.92rem; }

.section-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-md);
    padding-bottom: 0.7rem;
    margin-bottom: var(--space-md);
    border-bottom: 1px solid var(--border);
}
.section-count {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* stat tiles used across members / forum / gallery / profile / clanwars */
.stat-box, .forum-stat-box, .gallery-stat-box, .profile-stat-card, .cw-stat-card {
    background: var(--dark-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
}
.stat-box:hover, .forum-stat-box:hover, .gallery-stat-box:hover,
.profile-stat-card:hover, .cw-stat-card:hover {
    transform: none;
    border-color: var(--divider);
    box-shadow: none;
}
.cw-stat-card::before { display: none; }
.stat-box-icon, .forum-stat-icon, .gallery-stat-icon, .profile-stat-icon, .cw-stat-icon {
    background: var(--primary-tint);
    border-radius: var(--radius-md);
    color: var(--primary-light);
}
.cw-stat-value, .stat-box-value, .forum-stat-value, .gallery-stat-value, .profile-stat-value { color: var(--text); }
.cw-stat-wins .cw-stat-value { color: var(--success); }
.cw-stat-losses .cw-stat-value { color: var(--danger); }

.quick-stat {
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--border);
    border-radius: 0;
    padding: 0.55rem 0;
}
.quick-stat:last-child { border-bottom: 0; }
.quick-stat:hover { transform: none; background: transparent; border-color: var(--border); }
.quick-stat > span:first-child { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted); }
.quick-stat > span:last-child { font-family: var(--font-heading); font-weight: 700; color: var(--text); }

/* ==================== 8. CLAN WARS — the scoreline signature ==================== */

.cw-item {
    background: var(--dark-2);
    border: 1px solid var(--border);
    border-left: 2px solid var(--divider);
    border-radius: var(--radius-lg);
}
.cw-item:hover { transform: none; background: var(--dark-3); border-color: var(--divider); box-shadow: none; }
.cw-item.win  { border-left-color: var(--success); }
.cw-item.loss { border-left-color: var(--danger); }
.cw-item.draw { border-left-color: var(--primary); }
.cw-item.expanded { background: var(--dark-3); border-color: var(--divider); }

.cw-vs { font-family: var(--font-heading); font-weight: 700; font-size: 1.05rem; letter-spacing: -0.01em; }
.cw-score {
    font-family: var(--font-heading);
    font-weight: 900;
    font-size: 1.9rem;
    letter-spacing: -0.045em;
    font-variant-numeric: tabular-nums;
    color: var(--text);
}
.cw-item.win  .cw-score { color: var(--success); }
.cw-item.loss .cw-score { color: var(--danger); }
.cw-item.draw .cw-score { color: var(--primary-light); }

.cw-info {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
    gap: 0;
}
.cw-info span { padding-right: 0.85rem; margin-right: 0.85rem; border-right: 1px solid var(--border); }
.cw-info span:last-child { border-right: 0; margin-right: 0; padding-right: 0; }

.cw-result-badge {
    font-family: var(--font-mono);
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    border-radius: var(--radius-sm);
    border: 0;
}
.cw-result-badge.win  { background: rgba(61,220,132,.12); color: var(--success); }
.cw-result-badge.loss { background: rgba(255,90,84,.12);  color: var(--danger); }
.cw-result-badge.draw { background: var(--primary-tint); color: var(--primary-light); }

.cw-player-tag {
    background: var(--dark-4);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    color: var(--text-secondary);
}
.cw-details, .cw-details-content { background: var(--dark-3); border-color: var(--border); border-radius: var(--radius-md); }
.cw-detail-value { color: var(--text-secondary); }

.performance-timeline { background: var(--dark-2); border: 1px solid var(--border); border-radius: var(--radius-lg); }
.performance-item {
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-weight: 700;
}
.performance-item:hover { transform: none; }
.performance-item.win  { background: rgba(61,220,132,.15); color: var(--success); }
.performance-item.loss { background: rgba(255,90,84,.15);  color: var(--danger); }

.progress-bar { background: var(--dark-4); height: 4px; }
.progress-fill { background: var(--primary); }

/* ==================== 9. ROSTER ==================== */

.member-card {
    background: var(--dark-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
}
.member-card::before { display: none; }
.member-card:hover {
    transform: none;
    background: var(--dark-3);
    border-color: var(--primary-line);
    box-shadow: none;
}
.member-avatar {
    border-radius: var(--radius-md);
    border: 1px solid var(--divider);
    box-shadow: none;
}
.member-card:hover .member-avatar { transform: none; box-shadow: none; }
.member-name { font-family: var(--font-heading); font-weight: 700; letter-spacing: -0.01em; }
.member-meta {
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-muted);
    border-top-color: var(--border);
}
.presence-dot { border-color: var(--dark-2); border-radius: var(--radius-full); }
.member-card:hover .presence-dot { border-color: var(--dark-3); }

.members-category-header { border-bottom: 1px solid var(--border); }
.members-category-header h2 { font-size: 1.2rem; font-weight: 700; }
.members-category-header svg { color: var(--text-muted); }
.category-count {
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.mode-pill {
    background: var(--primary-tint);
    border: 1px solid var(--primary-line);
    border-radius: var(--radius-sm);
    color: var(--primary-light);
    font-family: var(--font-mono);
}
.activity-meter-head { font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.08em; text-transform: uppercase; }
.activity-meter-bar { height: 3px; border-radius: 2px; }
.activity-meter-bar span { border-radius: 2px; box-shadow: none !important; }

/* ==================== 10. FORUM ==================== */

.forum-category, .forum-thread {
    background: var(--dark-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
}
.forum-category:hover, .forum-thread:hover {
    transform: none;
    background: var(--dark-3);
    border-color: var(--divider);
    box-shadow: none;
}
.forum-cat-info h4, .forum-thread-info h4 { font-family: var(--font-heading); font-weight: 700; font-size: 1rem; }
.forum-cat-desc, .forum-thread-meta { color: var(--text-muted); font-size: 0.82rem; }
.forum-cat-stats .forum-stat-value, .thread-stats strong { font-family: var(--font-heading); font-weight: 700; }
.forum-cat-stats .forum-stat-label { font-size: 0.62rem; }

.thread-badge { border-radius: var(--radius-sm); font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.12em; }
.forum-thread.pinned { background: linear-gradient(90deg, rgba(255,194,75,.05), transparent 35%); border-color: rgba(255,194,75,.25); }

.thread-header {
    background: var(--dark-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 1.5rem;
    box-shadow: none;
}
.thread-header::before { display: none; }
.thread-title { font-size: 1.5rem; font-weight: 800; letter-spacing: -0.03em; color: var(--text); }
.thread-meta { font-family: var(--font-mono); font-size: 0.75rem; color: var(--text-muted); }

.forum-post {
    background: var(--dark-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: none;
    grid-template-columns: 180px 1fr;
    margin-bottom: 1rem;
}
.forum-post:hover { transform: none; border-color: var(--divider); box-shadow: none; }
.post-sidebar { background: var(--dark-3); border-right: 1px solid var(--border); padding: 1.25rem; }
.post-avatar { width: 56px; height: 56px; border-radius: var(--radius-md); border: 1px solid var(--divider); box-shadow: none; }
.forum-post:hover .post-avatar { transform: none; box-shadow: none; }
.post-author-name {
    background: none;
    -webkit-text-fill-color: currentColor;
    color: var(--text);
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 1rem;
}
.post-author-role {
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.12em;
    color: var(--text-muted);
}
.post-main { padding: 1.4rem; }
.post-meta { background: transparent; border-radius: 0; font-family: var(--font-mono); font-size: 0.72rem; padding: 0; }
.post-footer { border-top-color: var(--border); }
.forum-reply-section, .forum-thread-header { background: var(--dark-2); border: 1px solid var(--border); border-radius: var(--radius-lg); }
.forum-empty { border: 1px dashed var(--divider); border-radius: var(--radius-lg); background: var(--dark-2); }
.forum-pager { font-family: var(--font-mono); font-size: 0.75rem; letter-spacing: 0.06em; }
.rules-list svg { color: var(--primary-light); }
.rules-note { background: transparent; border: 1px solid rgba(255,194,75,.3); border-radius: var(--radius-md); color: var(--warning); }

/* ==================== 11. GALLERY ==================== */

.gallery-card, .gallery-item {
    background: var(--dark-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: none;
}
.gallery-card:hover, .gallery-item:hover {
    transform: none;
    border-color: var(--primary-line);
    box-shadow: none;
}
.gallery-card-image { background: var(--dark); }
.gallery-card:hover .gallery-card-image img, .gallery-card:hover .gallery-card-image video, .gallery-item:hover img { transform: none; }
.gallery-card-content { background: transparent; border-top: 1px solid var(--border); }
.gallery-card:hover .gallery-card-content { background: transparent; }
.gallery-card-title { font-family: var(--font-heading); font-weight: 700; font-size: 0.98rem; color: var(--text); }
.gallery-card-meta { font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.05em; text-transform: uppercase; }
.gallery-card-category { color: var(--primary-light); font-weight: 500; }

/* ==================== 12. BANNERS (recruitment / challenge / upload) ==================== */

.recruitment-banner, .challenge-banner, .upload-banner, .upload-banner-content {
    background: var(--dark-2);
    border: 1px solid var(--border);
    border-left: 2px solid var(--primary);
    border-radius: var(--radius-lg);
    box-shadow: none;
}
.recruitment-icon svg, .challenge-icon svg, .upload-icon svg { color: var(--primary-light); }
.recruitment-icon h2, .challenge-icon h2, .upload-icon h3 { font-weight: 800; letter-spacing: -0.025em; }
.recruitment-requirements li svg, .challenge-info-item svg { color: var(--success); }

/* ==================== 13. FORMS ==================== */

.form-control, .form-input, .form-textarea, .filter-input, .filter-select,
.form-group input, .form-group select, .form-group textarea, .shout-form input {
    background: var(--dark-3);
    border: 1px solid var(--divider);
    border-radius: var(--radius-md);
    font-family: var(--font-primary);
    font-size: 0.92rem;
}
.form-control:focus, .form-input:focus, .form-textarea:focus,
.filter-input:focus, .filter-select:focus,
.form-group input:focus, .form-group select:focus, .form-group textarea:focus {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-tint);
    background: var(--dark-3);
}
.form-group label, .filter-group label {
    font-family: var(--font-mono);
    font-size: 0.68rem;
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.form-group label svg, .filter-group label svg { color: var(--text-muted); }
.form-help { font-family: var(--font-mono); font-size: 0.7rem; color: var(--text-muted); }
.form-message { background: var(--dark-3); border-radius: var(--radius-md); border-left-width: 2px; font-size: 0.88rem; }
.checkbox-text { font-size: 0.88rem; }

/* ==================== 14. TABLES ==================== */

.admin-table { border-collapse: collapse; width: 100%; }
.admin-table th {
    background: var(--dark-3);
    border-bottom: 1px solid var(--divider);
    font-family: var(--font-mono);
    font-size: 0.66rem;
    font-weight: 500;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--text-muted);
    padding: 0.7rem 0.85rem;
    text-align: left;
}
.admin-table td {
    border-bottom: 1px solid var(--border);
    padding: 0.7rem 0.85rem;
    font-size: 0.88rem;
}
.admin-table tbody tr:hover { background: var(--dark-3); }

/* ==================== 15. MODALS & DIALOGS ==================== */

.modal-backdrop { background: rgba(0, 0, 0, 0.75); backdrop-filter: blur(3px); }
.modal-content { background: var(--dark-2); border: 1px solid var(--divider); border-radius: var(--radius-lg); box-shadow: var(--shadow-xl); }
.modal-header { background: transparent; border-bottom: 1px solid var(--border); }
.modal-header h3 { font-size: 1rem; font-weight: 700; }
.modal-footer { background: transparent; border-top: 1px solid var(--border); }
.modal-close:hover { background: transparent; color: var(--danger); }

/* ==================== 16. TOASTS, LOADING, EMPTY STATES ==================== */

.toast {
    background: var(--dark-3);
    border: 1px solid var(--divider);
    border-left: 2px solid var(--primary);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    backdrop-filter: none;
    padding: 0.75rem 1rem;
}
.toast strong {
    display: block;
    font-family: var(--font-mono);
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 0.15rem;
}
.toast p { font-size: 0.88rem; color: var(--text); margin: 0; }
.toast.success { border-left-color: var(--success); }
.toast.success strong { color: var(--success); }
.toast.error { border-left-color: var(--danger); }
.toast.error strong { color: var(--danger); }
.toast.warning { border-left-color: var(--warning); }
.toast.warning strong { color: var(--warning); }
.toast.info { border-left-color: var(--info); }
.toast.info strong { color: var(--info); }

.loading-overlay { background: var(--dark); }
.loading-overlay p {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-top: 1rem;
}
.loading-spinner, .loading-spinner-sm {
    border-color: var(--divider);
    border-top-color: var(--primary);
    border-width: 2px;
}
.loading-spinner { width: 34px; height: 34px; }

.empty-state {
    background: var(--dark-2);
    border: 1px dashed var(--divider);
    border-radius: var(--radius-lg);
}
.empty-state svg { color: var(--text-muted); opacity: 0.4; }
.empty-state h3 { font-family: var(--font-heading); font-weight: 700; font-size: 1.05rem; }
.empty-state p { color: var(--text-muted); font-size: 0.88rem; }

/* ==================== 17. SIDEBAR: SERVER STATUS ==================== */

.server-card {
    background: var(--dark-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}
.server-card.is-offline { background: rgba(255,90,84,.05); border-color: rgba(255,90,84,.22); }
.server-pill { border-radius: var(--radius-sm); font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.13em; }
.server-pill.online  { background: rgba(61,220,132,.12); color: var(--success); }
.server-pill.offline { background: rgba(255,90,84,.12);  color: var(--danger); }
.server-name { font-family: var(--font-primary); font-weight: 600; font-size: 0.88rem; }
.server-players-row, .server-meta-row {
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.server-players-bar { height: 3px; border-radius: 2px; }
.server-players-bar span { background: var(--primary); border-radius: 2px; }
.server-ip { border: 1px dashed var(--divider); border-radius: var(--radius-sm); font-size: 0.72rem; }
.server-ip:hover { border-color: var(--primary); color: var(--primary-light); }

/* ==================== 18. PROFILE ==================== */

.profile-header-card { background: var(--dark-2); border: 1px solid var(--border); border-radius: var(--radius-lg); }
/* the decorative cover band is removed — requested change #6 */
.profile-cover { display: none; }
.profile-info-section { margin-top: 0; }
.profile-avatar { border-radius: var(--radius-lg); border: 1px solid var(--divider); box-shadow: none; width: 104px; height: 104px; }
.avatar-edit-btn { border-radius: var(--radius-md); width: 30px; height: 30px; bottom: 4px; right: 4px; }
.avatar-edit-btn:hover { transform: none; background: var(--primary-dark); }
.profile-username { font-weight: 800; letter-spacing: -0.03em; }
.profile-role-badge {
    background: var(--primary-tint);
    border: 1px solid var(--primary-line);
    border-radius: var(--radius-sm);
    color: var(--primary-light);
    font-family: var(--font-mono);
    font-size: 0.65rem;
    letter-spacing: 0.13em;
}
.profile-details .profile-role-badges,
.admin-table .admin-user-role-badges {
    justify-content: flex-start;
    margin: 0.35rem 0 0.2rem;
}
.profile-details .profile-role-badges { align-self: flex-start; }
.profile-meta, .profile-meta-item { font-family: var(--font-mono); font-size: 0.74rem; letter-spacing: 0.04em; }
.profile-meta-item svg { color: var(--text-muted); }
.profile-info-item { background: var(--dark-3); border: 1px solid var(--border); border-radius: var(--radius-md); }
.profile-info-label { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; }

.tab-navigation { background: transparent; border-bottom: 1px solid var(--border); padding: 0; gap: 0; }
.tab-btn {
    border-radius: 0;
    border-bottom: 2px solid transparent;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    padding: 0.8rem 1.1rem;
}
.tab-btn:hover { background: transparent; color: var(--text); }
.tab-btn.active { background: transparent; color: var(--text); border-bottom-color: var(--primary); }

.settings-toggle { background: var(--dark-3); border: 1px solid var(--border); border-radius: var(--radius-md); }
.toggle-slider { background: var(--dark-5); }
.toggle-switch input:checked + .toggle-slider { background: var(--primary); }

/* ==================== 19. AUTH PAGES ==================== */

.auth-background::before { opacity: 0.45; }
.auth-card { background: var(--dark-2); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-xl); backdrop-filter: none; }
.auth-logo { border-radius: var(--radius-md); border: 1px solid var(--primary-line); box-shadow: none; animation: none; }
.auth-title { font-weight: 800; letter-spacing: -0.03em; }
.auth-tagline, .auth-subtitle { color: var(--text-muted); }
.auth-divider span { background: var(--dark-2); font-family: var(--font-mono); letter-spacing: 0.14em; }
.info-card, .demo-accounts { background: var(--dark-3); border: 1px solid var(--border); border-radius: var(--radius-md); }
.info-card svg { color: var(--primary-light); }
.strength-meter { height: 3px; background: var(--dark-4); }

/* ==================== 20. MAINTENANCE ==================== */

.maintenance-container { background: var(--dark-2); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-xl); }
.maintenance-icon { background: rgba(255,194,75,.1); border: 1px solid rgba(255,194,75,.28); border-radius: var(--radius-lg); }
.countdown-box { background: var(--dark-3); border: 1px solid var(--border); border-radius: var(--radius-md); }
.countdown-number { color: var(--text); }

/* ==================== 21. FOOTER ==================== */

.site-footer { background: var(--dark-2); border-top: 1px solid var(--border); }
.footer-brand h4, .footer-column h4, .footer-section h5 {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--text-secondary);
}
.footer-brand h4 { font-family: var(--font-heading); font-size: 1rem; font-weight: 700; letter-spacing: -0.01em; text-transform: none; color: var(--text); }
.footer-logo { border-radius: var(--radius-md); border: 1px solid var(--border); }
.footer-section a, .footer-column a { font-size: 0.88rem; color: var(--text-muted); }
.footer-section a:hover, .footer-column a:hover { color: var(--primary-light); padding-left: 0; }
.footer-bottom { border-top: 1px solid var(--border); font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.05em; color: var(--text-muted); }
/*
 * Footer social buttons.
 *
 * Three stylesheets used to fight over these: style.css gives them a lift and
 * a glow, ysn-ui.css a different lift and a blue glow, and this file cancelled
 * both with transform:none - so the button ended on a weak 14% tint that read
 * as a hover that had not finished. This is now one deliberate state.
 *
 * No vertical lift, because this theme removes them everywhere (38 other
 * transform:none rules). The motion is a clean fill plus a small icon scale,
 * which reads as intentional rather than half-applied.
 */
.site-footer .social-links .social-link {
    border-radius: var(--radius-md);
    background: var(--dark-3);
    border: 1px solid var(--border);
    color: var(--text-secondary);
    transform: none;
    box-shadow: none;
    transition: background-color 200ms ease, border-color 200ms ease, color 200ms ease;
}

.site-footer .social-links .social-link svg {
    transition: transform 200ms cubic-bezier(0.34, 1.4, 0.64, 1);
}

.site-footer .social-links .social-link:hover,
.site-footer .social-links .social-link:focus-visible {
    /* Discord blurple, solid - the brand colour is the whole point of the button. */
    background: #5865f2;
    border-color: #5865f2;
    color: #fff;
    transform: none;
    box-shadow: none;
}

.site-footer .social-links .social-link:hover svg,
.site-footer .social-links .social-link:focus-visible svg {
    transform: scale(1.12);
}

.site-footer .social-links .social-link:active {
    background: #4752c4;
    border-color: #4752c4;
}

/* Keyboard users still get a visible ring; the colour fill alone is not enough. */
.site-footer .social-links .social-link:focus-visible {
    outline: 2px solid rgba(160, 170, 255, 0.9);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .site-footer .social-links .social-link,
    .site-footer .social-links .social-link svg {
        transition: none;
    }
    .site-footer .social-links .social-link:hover svg,
    .site-footer .social-links .social-link:focus-visible svg {
        transform: none;
    }
}

/* ==================== 22. ADMIN PANEL ==================== */

.admin-header { background: var(--dark-2); border-bottom: 1px solid var(--divider); backdrop-filter: none; }
.admin-sidebar { background: var(--dark-2); border-right: 1px solid var(--border); }
.admin-nav-item {
    border-radius: var(--radius-md);
    font-family: var(--font-primary);
    font-size: 0.86rem;
    font-weight: 500;
    color: var(--text-secondary);
}
.admin-nav-item:hover { background: var(--dark-3); color: var(--text); }
.admin-nav-item.active { background: var(--primary-tint); color: var(--primary-light); border-left: 2px solid var(--primary); }
.admin-card, .admin-section-header { background: var(--dark-2); border: 1px solid var(--border); border-radius: var(--radius-lg); }
.admin-card:hover { transform: none; border-color: var(--divider); box-shadow: none; }
.admin-section-header h2 { font-weight: 800; letter-spacing: -0.03em; }
.quick-action-btn { background: var(--dark-3); border: 1px solid var(--border); border-radius: var(--radius-md); }
.quick-action-btn:hover { transform: none; background: var(--dark-4); border-color: var(--primary-line); }
.activity-item { border-bottom: 1px solid var(--border); }
.badge { border-radius: var(--radius-sm); font-family: var(--font-mono); font-size: 0.64rem; letter-spacing: 0.1em; }
.access-denied-card { background: var(--dark-2); border: 1px solid var(--border); border-radius: var(--radius-lg); }

/* ==================== 23. LIGHTBOX ==================== */


/* ==================== 24. AMBIENT GLOW REMOVAL ==================== */
/* Six decorative radial washes with infinite `pulse` animations sat behind
   the hero, the three banners, the auth pages and the admin panel. They are
   what made every surface read as purple haze. All retired; the surface
   ladder does the work now. */

.page-hero::before,
.recruitment-banner::before,
.challenge-banner::before,
.upload-banner::before,
.auth-background::before,
.admin-stat-card::before,
.admin-card::before {
    display: none !important;
    content: none !important;
    animation: none !important;
}

.recruitment-banner,
.challenge-banner,
.upload-banner {
    background: var(--dark-2);
    padding: clamp(1.5rem, 2.4vw, 2.25rem);
    margin-top: var(--space-xl);
}
.recruitment-icon,
.challenge-icon,
.upload-icon { margin-bottom: var(--space-lg); }
.recruitment-icon svg,
.challenge-icon svg,
.upload-icon svg { width: 26px; height: 26px; }
.recruitment-requirements li,
.challenge-info-item {
    background: var(--dark-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    font-size: 0.88rem;
}

/* ==================== 25. SPACING & LEFTOVERS ==================== */

/* Stat values inside the page hero were the only ones still coloured purple. */
.hero-stat-value { color: var(--text); }
.hero-stats-mini { justify-content: flex-start; gap: var(--space-xl); }

/* The homepage had a large dead gap between every section. */
.content-section { margin-bottom: 0; }
.main-content { gap: var(--space-lg); }
.main-layout > .container > * + * { margin-top: var(--space-lg); }

/* Legacy sidebar server fallback (rendered when the query fails). */
.server-item {
    background: var(--dark-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}
.server-item:hover { transform: none; background: var(--dark-3); border-color: var(--border); }

/* Shoutbox (styled but currently unused — kept consistent). */
.shout-item { background: var(--dark-3); border: 1px solid var(--border); border-radius: var(--radius-md); }
.shout-item:hover { background: var(--dark-4); border-color: var(--divider); }
.shout-author { color: var(--primary-light); font-weight: 600; }
.shout-time { font-family: var(--font-mono); font-size: 0.68rem; }

/* Quick links in the sidebar. */
.quick-link { background: var(--dark-3); border: 1px solid var(--border); border-radius: var(--radius-md); }
.quick-link:hover { transform: none; background: var(--dark-4); border-color: var(--primary-line); color: var(--primary-light); }
.quick-link svg { color: var(--text-muted); }

/* Breadcrumb. */
.breadcrumb, .breadcrumb-item {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.breadcrumb-item:hover { color: var(--primary-light); }

/* ==========================================================================
   ROLE BADGES — PRESERVED
   ==========================================================================
   .role-badge and its .rb-shine running highlight are intentionally NOT
   restyled. They keep their gradient border-box, per-role glow, ◆ ★ ▲ ● ◇ ○
   glyphs and the 3.5s shine sweep exactly as built in ysn-ui.css.
   The only change is that the sweep now stops for users who have asked their
   operating system for reduced motion — handled by the global rule in §2.
   Do not add .role-badge rules to this file.
   ========================================================================== */

/* ==========================================================================
   26. STYLE A LAYOUT — unified bar, strip, hero, scoreline, sections
   ========================================================================== */

.ysn-live-dot {
    display: inline-block;
    width: 6px; height: 6px;
    margin-right: 6px;
    border-radius: 50%;
    background: var(--success);
    vertical-align: 1px;
}

/* --- one bar: brand | nav | auth --- */
.site-header { padding: 0; }
/* Three columns rather than flex: the empty first column mirrors the account
   menu in the third, so the nav is centred on the page itself and does not
   drift when the account menu changes width (Log in / Register vs a username). */
.ysn-bar {
    display: grid;
    /* minmax(0, 1fr) rather than 1fr: a bare 1fr floors at the content width,
       which lets the scrolling nav push the account menu off-screen. */
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: stretch;
    gap: var(--space-lg);
    min-height: 60px;
}
.ysn-bar::before { content: ''; }
.ysn-bar .main-nav {
    position: static;
    background: none;
    border: 0;
    display: flex;
    align-items: stretch;
    justify-content: center;
}
.ysn-bar .nav-links { display: flex; align-items: stretch; gap: 0; }
.ysn-bar .nav-link { padding: 0 0.95rem; }
.ysn-bar .nav-user { display: flex; align-items: center; justify-content: flex-end; gap: 0.5rem; padding: 0; }

/* --- full-bleed stat strip (homepage only) --- */
.ysn-strip { background: var(--dark-2); border-bottom: 1px solid var(--border); }
.ysn-strip-grid { display: grid; grid-template-columns: repeat(4, 1fr); }
.ysn-stat { padding: 1.05rem 0; border-left: 1px solid var(--border); padding-left: 1.6rem; }
.ysn-stat:first-child { border-left: 0; padding-left: 0; }
.ysn-stat-v {
    font-family: var(--font-heading);
    font-weight: 800;
    font-size: 1.85rem;
    line-height: 1;
    letter-spacing: -0.035em;
    font-variant-numeric: tabular-nums;
    color: var(--text);
}
.ysn-stat-l {
    margin-top: 0.4rem;
    font-family: var(--font-mono);
    font-size: 0.64rem;
    font-weight: 500;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* --- eyebrow: the structural device of the whole theme --- */
.ysn-eyebrow {
    display: block;
    font-family: var(--font-mono);
    font-size: 0.62rem;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--primary-light);
}

/* --- hero --- */
.ysn-hero { border-bottom: 1px solid var(--border); padding: clamp(2.5rem, 5vw, 4.2rem) 0 clamp(2rem, 3.5vw, 3.2rem); }
.ysn-hero-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    gap: clamp(2rem, 4vw, 4rem);
    align-items: end;
}
.ysn-hero-title {
    margin: 0.9rem 0 0;
    font-family: var(--font-heading);
    font-weight: 900;
    font-size: clamp(2.6rem, 5.4vw, 4.7rem);
    line-height: 0.94;
    letter-spacing: -0.045em;
    text-transform: uppercase;
}
.ysn-hero-title em { font-style: normal; color: var(--primary-light); }
.ysn-hero-lead { margin-top: 1.05rem; max-width: 46ch; color: var(--text-secondary); font-size: 0.96rem; }
.ysn-hero-cta { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 1.5rem; }
.ysn-hero-rule { height: 1px; background: var(--border); margin-top: 1.6rem; }
.ysn-hero-meta { display: flex; flex-wrap: wrap; gap: 2.1rem; margin-top: 1.05rem; }
.ysn-hero-meta > div { display: flex; flex-direction: column; gap: 0.25rem; }
.ysn-meta-l {
    font-family: var(--font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.ysn-meta-v { font-family: var(--font-mono); font-size: 0.78rem; color: var(--text); letter-spacing: 0.03em; }

/* --- live clan-war announcement -----------------------------------------
   One strong horizontal plane between the stat strip and hero. The score is
   the focal point; phase and server controls support it without nested cards. */
.cw-live-shell {
    padding: 0.9rem 0;
    background: #0a0a0e;
    border-bottom: 1px solid var(--border);
}
.cw-live-shell[hidden] { display: none !important; }
.cw-live-card {
    position: relative;
    isolation: isolate;
    display: grid;
    grid-template-columns: minmax(11rem, 0.68fr) minmax(25rem, 1.9fr) minmax(11rem, 0.68fr);
    align-items: stretch;
    min-height: 9.6rem;
    overflow: hidden;
    border: 1px solid rgba(149, 122, 255, 0.48);
    border-radius: var(--radius-xl);
    background:
        linear-gradient(112deg, rgba(124, 92, 255, 0.035), transparent 31%, transparent 69%, rgba(124, 92, 255, 0.045)),
        #0d0d12;
    box-shadow: 0 18px 52px -34px rgba(124, 92, 255, 0.8), inset 0 1px rgba(255, 255, 255, 0.025);
    animation: cw-live-arrive 0.42s cubic-bezier(.2,.8,.2,1) both;
}
.cw-live-card::before {
    content: '';
    position: absolute;
    z-index: -1;
    inset: 0;
    pointer-events: none;
    opacity: 0.55;
    background:
        linear-gradient(127deg, transparent 0 28%, rgba(124, 92, 255, 0.16) 28.1% 28.25%, transparent 28.35% 72%, rgba(124, 92, 255, 0.13) 72.1% 72.25%, transparent 72.35%);
}
.cw-live-card::after {
    content: '';
    position: absolute;
    left: 28%;
    right: 27%;
    bottom: 0;
    height: 2px;
    background: linear-gradient(90deg, transparent, var(--primary), #c6b8ff, var(--primary), transparent);
    background-size: 180% 100%;
    animation: cw-live-trace 3.6s ease-in-out infinite;
}
.cw-live-status,
.cw-live-actions {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    padding: 1.45rem;
}
.cw-live-status {
    gap: 0.9rem;
    border-right: 1px solid var(--divider);
}
.cw-live-signal {
    position: relative;
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 2.5rem;
    height: 2.5rem;
    border: 1px solid rgba(255, 90, 84, 0.38);
    border-radius: 50%;
    background: rgba(255, 90, 84, 0.07);
}
.cw-live-signal::before,
.cw-live-signal::after {
    content: '';
    position: absolute;
    inset: 0.36rem;
    border: 1px solid rgba(255, 90, 84, 0.28);
    border-radius: inherit;
    animation: cw-live-pulse 2s ease-out infinite;
}
.cw-live-signal::after { animation-delay: 1s; }
.cw-live-signal i {
    width: 0.72rem;
    height: 0.72rem;
    border-radius: 50%;
    background: var(--danger);
    box-shadow: 0 0 18px rgba(255, 90, 84, 0.62);
}
.cw-live-status-copy { min-width: 0; display: flex; flex-direction: column; gap: 0.34rem; }
.cw-live-status-copy strong {
    color: var(--danger);
    font-family: var(--font-heading);
    font-size: 0.92rem;
    font-weight: 850;
    line-height: 1.05;
    letter-spacing: 0.045em;
    text-transform: uppercase;
}
.cw-live-status-copy > span {
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 0.59rem;
    line-height: 1.45;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.cw-live-match {
    position: relative;
    z-index: 1;
    align-self: center;
    min-width: 0;
    padding: 1.05rem clamp(1.3rem, 3vw, 3rem);
    text-align: center;
}
.cw-live-kicker {
    display: block;
    margin-bottom: 0.45rem;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 0.57rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
}
.cw-live-scoreline {
    display: grid;
    grid-template-columns: minmax(5rem, 1fr) auto auto auto minmax(5rem, 1fr);
    align-items: center;
    gap: clamp(0.65rem, 1.5vw, 1.2rem);
}
.cw-live-team { min-width: 0; display: flex; flex-direction: column; gap: 0.24rem; }
.cw-live-team.is-home { align-items: flex-end; text-align: right; }
.cw-live-team.is-away { align-items: flex-start; text-align: left; }
.cw-live-team strong {
    max-width: 100%;
    overflow: hidden;
    color: var(--text);
    font-family: var(--font-heading);
    font-size: clamp(1.2rem, 2vw, 1.72rem);
    font-weight: 850;
    line-height: 1;
    letter-spacing: -0.025em;
    text-overflow: ellipsis;
    text-transform: uppercase;
    white-space: nowrap;
}
.cw-live-team small {
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 0.55rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.cw-live-score {
    color: var(--text);
    font-family: var(--font-heading);
    font-size: clamp(2.65rem, 4.7vw, 4.3rem);
    font-weight: 900;
    font-variant-numeric: tabular-nums;
    line-height: 0.82;
    letter-spacing: -0.065em;
}
.cw-live-separator {
    color: var(--primary-light);
    font-size: 1.5rem;
    line-height: 1;
}
.cw-live-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.55rem;
    margin-top: 0.8rem;
    color: var(--text-secondary);
    font-family: var(--font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.055em;
    text-transform: uppercase;
}
.cw-live-meta i {
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--primary);
}
.cw-live-actions {
    flex-direction: column;
    justify-content: center;
    gap: 0.75rem;
    border-left: 1px solid var(--divider);
}
.cw-live-join {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.7rem;
    width: 100%;
    min-height: 3.25rem;
    padding: 0.8rem 1rem;
    border: 1px solid rgba(255,255,255,0.2);
    border-radius: var(--radius-lg);
    background: var(--primary);
    color: #fff;
    font-family: var(--font-heading);
    font-size: 0.78rem;
    font-weight: 800;
    letter-spacing: 0.075em;
    text-decoration: none;
    text-transform: uppercase;
    transition: background var(--transition-fast), transform var(--transition-fast), border-color var(--transition-fast);
}
.cw-live-join:hover {
    color: #fff;
    background: var(--primary-light);
    border-color: rgba(255,255,255,0.34);
    transform: translateY(-1px);
}
.cw-live-copy {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    max-width: 100%;
    padding: 0;
    border: 0;
    background: none;
    color: var(--text-muted);
    cursor: pointer;
    font-family: var(--font-mono);
    font-size: 0.59rem;
    letter-spacing: 0.04em;
    transition: color var(--transition-fast);
}
.cw-live-copy span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cw-live-copy:hover { color: var(--text); }
.cw-live-shell[data-phase="paused"] .cw-live-signal,
.cw-live-shell[data-phase="ready"] .cw-live-signal,
.cw-live-shell[data-phase="countdown"] .cw-live-signal { border-color: rgba(255, 194, 75, 0.4); background: rgba(255, 194, 75, 0.07); }
.cw-live-shell[data-phase="paused"] .cw-live-signal i,
.cw-live-shell[data-phase="ready"] .cw-live-signal i,
.cw-live-shell[data-phase="countdown"] .cw-live-signal i { background: var(--warning); box-shadow: 0 0 18px rgba(255, 194, 75, 0.5); }
.cw-live-shell[data-phase="paused"] .cw-live-status-copy strong,
.cw-live-shell[data-phase="ready"] .cw-live-status-copy strong,
.cw-live-shell[data-phase="countdown"] .cw-live-status-copy strong { color: var(--warning); }
.cw-live-shell[data-phase="results"] .cw-live-signal { border-color: var(--primary-line); background: var(--primary-tint); }
.cw-live-shell[data-phase="results"] .cw-live-signal i { background: var(--primary-light); box-shadow: 0 0 18px var(--primary-glow); }
.cw-live-shell[data-phase="results"] .cw-live-status-copy strong { color: var(--primary-light); }

@keyframes cw-live-arrive {
    from { opacity: 0; transform: translateY(-0.5rem); }
    to { opacity: 1; transform: translateY(0); }
}
@keyframes cw-live-pulse {
    from { opacity: 0.72; transform: scale(0.52); }
    to { opacity: 0; transform: scale(1.55); }
}
@keyframes cw-live-trace {
    0%, 100% { background-position: 0 0; opacity: 0.55; }
    50% { background-position: 100% 0; opacity: 1; }
}

@media (max-width: 980px) {
    .cw-live-card { grid-template-columns: minmax(12rem, 0.75fr) minmax(24rem, 1.8fr); }
    .cw-live-actions {
        grid-column: 1 / -1;
        flex-direction: row;
        padding: 0.75rem 1.1rem;
        border-top: 1px solid var(--divider);
        border-left: 0;
    }
    .cw-live-join { width: auto; min-width: 12rem; min-height: 2.7rem; }
    .cw-live-copy { max-width: 17rem; }
}

@media (max-width: 680px) {
    .cw-live-shell { padding: 0.65rem 0; }
    .cw-live-card { grid-template-columns: minmax(0, 1fr); }
    .cw-live-status { justify-content: center; padding: 1rem; border-right: 0; border-bottom: 1px solid var(--divider); }
    .cw-live-status-copy { flex: 0 1 auto; }
    .cw-live-match { padding: 1.2rem 0.8rem 1.3rem; }
    .cw-live-scoreline { grid-template-columns: minmax(3.4rem, 1fr) auto auto auto minmax(3.4rem, 1fr); gap: 0.5rem; }
    .cw-live-team strong { font-size: clamp(1rem, 5vw, 1.35rem); }
    .cw-live-team small { font-size: 0.5rem; }
    .cw-live-score { font-size: clamp(2.35rem, 13vw, 3.25rem); }
    .cw-live-meta { gap: 0.45rem; line-height: 1.5; }
    .cw-live-actions { grid-column: auto; flex-direction: column; }
    .cw-live-join { width: 100%; }
    .cw-live-card::after { left: 12%; right: 12%; }
}

@media (max-width: 390px) {
    .cw-live-team small { display: none; }
    .cw-live-meta i:nth-of-type(3),
    .cw-live-meta [data-cw-total] { display: none; }
}

/* --- scoreline: the signature element --- */
.ysn-scoreline {
    display: block;
    width: 100%;
    text-align: left;
    background: var(--dark-2);
    border: 1px solid var(--border);
    border-top: 2px solid var(--divider);
    border-radius: var(--radius-lg);
    padding: 1.3rem 1.4rem;
    font: inherit;
    color: inherit;
    text-decoration: none;
    transition: border-color var(--transition-fast), background var(--transition-fast);
}
.ysn-scoreline.win  { border-top-color: var(--success); }
.ysn-scoreline.loss { border-top-color: var(--danger); }
.ysn-scoreline.draw { border-top-color: var(--primary); }
button.ysn-scoreline { cursor: pointer; }
button.ysn-scoreline:hover { background: var(--dark-3); border-color: var(--divider); }
.ysn-scoreline-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-md); margin-bottom: 0.9rem; }
.ysn-scoreline-grid { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 0.9rem; }
.ysn-scoreline-grid .is-right { text-align: right; }
.ysn-side {
    display: block;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 0.2rem;
}
.ysn-num {
    display: block;
    font-family: var(--font-heading);
    font-weight: 900;
    font-size: clamp(2.4rem, 4vw, 3.6rem);
    line-height: 0.9;
    letter-spacing: -0.05em;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}
.ysn-num.is-win  { color: var(--success); }
.ysn-num.is-loss { color: var(--danger); }
.ysn-scoreline.win  .ysn-num:not(.is-win):not(.is-loss),
.ysn-scoreline.loss .ysn-num:not(.is-win):not(.is-loss) { color: var(--text-muted); }
.ysn-sep { font-family: var(--font-heading); font-weight: 700; font-size: 1.4rem; color: var(--text-muted); }
.ysn-scoreline-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0;
    margin-top: 1rem;
    padding-top: 0.85rem;
    border-top: 1px solid var(--border);
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.ysn-scoreline-foot > span { padding-right: 0.8rem; margin-right: 0.8rem; border-right: 1px solid var(--border); }
.ysn-scoreline-foot > span:last-child { border-right: 0; margin-right: 0; padding-right: 0; }
.ysn-open { color: var(--primary-light); }
.ysn-scoreline.is-empty { text-align: center; padding: 2rem 1.4rem; }
.ysn-scoreline-empty { color: var(--text-muted); font-size: 0.88rem; margin: 0.4rem 0 1.1rem; line-height: 1.7; }

/* --- sections --- */
.ysn-section { padding: clamp(2rem, 3.4vw, 3rem) 0; border-bottom: 1px solid var(--border); }
.ysn-section:last-child { border-bottom: 0; }
.main-layout > .container > .ysn-section + .ysn-section { margin-top: 0; }
.ysn-section-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-md);
    margin-bottom: 1.15rem;
}
.ysn-section-title {
    margin: 0.4rem 0 0;
    font-family: var(--font-heading);
    font-weight: 800;
    font-size: clamp(1.25rem, 1.8vw, 1.6rem);
    letter-spacing: -0.03em;
}
.ysn-section-grid { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: clamp(1.2rem, 2vw, 1.75rem); align-items: start; }
.ysn-aside { display: flex; flex-direction: column; gap: var(--space-md); }
.ysn-list { display: flex; flex-direction: column; gap: 0.7rem; }

/* --- clickable rows --- */
.ysn-clickable {
    display: block;
    width: 100%;
    text-align: left;
    font: inherit;
    color: inherit;
    cursor: pointer;
}
button.news-item, button.cw-item { border-width: 1px; }
.news-item.ysn-clickable:hover, .cw-item.ysn-clickable:hover { background: var(--dark-3); }
.ysn-us { color: var(--primary-light); }
.ysn-vs { color: var(--text-muted); font-weight: 400; font-size: 0.85em; }

/* ==================== 27. DIALOG (js/ysn-ui.js) ==================== */

.ysn-dialog {
    /* style.css has a global `* { margin: 0 }` which kills the UA stylesheet's
       `margin: auto` on <dialog> and pins it to the top-left corner. */
    margin: auto;
    inset: 0;
    width: min(38rem, calc(100vw - 2rem));
    max-height: min(86vh, 50rem);
    padding: 0;
    border: 1px solid var(--divider);
    border-radius: var(--radius-lg);
    background: var(--dark-2);
    color: var(--text);
    box-shadow: var(--shadow-xl);
    overflow: hidden;
}
.ysn-dialog.is-wide { width: min(52rem, calc(100vw - 2rem)); }
.ysn-dialog::backdrop { background: rgba(0, 0, 0, 0.72); backdrop-filter: blur(3px); }
.ysn-dialog-head {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-md);
    padding: 1rem 1.15rem;
    border-bottom: 1px solid var(--border);
}
.ysn-dialog-head h3 { margin: 0; font-family: var(--font-heading); font-weight: 700; font-size: 1rem; }
.ysn-dialog-head.tone-danger h3 { color: var(--danger); }
.ysn-dialog-x {
    background: none; border: 0; color: var(--text-muted);
    font-size: 1.25rem; line-height: 1; cursor: pointer; padding: 0.15rem 0.35rem;
    border-radius: var(--radius-sm);
}
.ysn-dialog-x:hover { color: var(--danger); }
.ysn-dialog-body { padding: 1.15rem; display: grid; gap: 0.9rem; font-size: 0.92rem; color: var(--text-secondary); }
.ysn-dialog-scroll { max-height: 62vh; overflow-y: auto; }
.ysn-dialog-warn {
    margin: 0;
    padding: 0.6rem 0.75rem;
    border-left: 2px solid var(--danger);
    background: rgba(255, 90, 84, 0.07);
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.11em;
    text-transform: uppercase;
    color: #FF9B96;
}
.ysn-dialog-foot {
    display: flex; justify-content: flex-end; gap: 0.5rem;
    padding: 0.85rem 1.15rem;
    border-top: 1px solid var(--border);
    background: var(--dark);
}
.ysn-dialog .field { display: grid; gap: 0.4rem; }
.ysn-dialog .field > label {
    font-family: var(--font-mono); font-size: 0.64rem; font-weight: 500;
    letter-spacing: 0.13em; text-transform: uppercase; color: var(--text-muted);
}
.ysn-dialog .field > input {
    padding: 0.6rem 0.7rem;
    background: var(--dark-3);
    border: 1px solid var(--divider);
    border-radius: var(--radius-md);
    color: var(--text);
    font: 400 0.92rem var(--font-primary);
}
.ysn-dialog .field > input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-tint); }

/* detail panels */
.ysn-detail-meta {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
    gap: 0.9rem 1.4rem;
    margin-top: 0.4rem;
    padding: 0.95rem 1rem;
    background: var(--dark);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}
.ysn-detail-meta > div > .ysn-meta-v { font-size: 0.8rem; }
.ysn-detail-meta > div { display: flex; flex-direction: column; gap: 0.2rem; }
.ysn-detail-h {
    margin: 0.3rem 0 -0.3rem;
    font-family: var(--font-mono); font-size: 0.64rem; font-weight: 500;
    letter-spacing: 0.15em; text-transform: uppercase; color: var(--text-muted);
}
.ysn-detail-body { color: var(--text-secondary); line-height: 1.72; }
.ysn-detail-body p { margin: 0 0 0.7rem; }
.ysn-detail-body p:last-child { margin-bottom: 0; }
.ysn-rt-gap { display: block; height: 1em; }
.ysn-detail-body blockquote {
    margin: 0 0 0.7rem; padding: 0.35rem 0 0.35rem 0.85rem;
    border-left: 2px solid var(--primary-line); color: var(--text-muted);
}
.ysn-detail-body ul, .ysn-detail-body ol { margin: 0 0 0.7rem 1.1rem; }
.ysn-detail-body code {
    font-family: var(--font-mono); font-size: 0.85em;
    background: var(--dark-4); padding: 0.1em 0.35em; border-radius: var(--radius-sm);
}
.ysn-detail-body hr { border: 0; border-top: 1px solid var(--border); margin: 0.9rem 0; }
.ysn-detail-shots { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: 0.6rem; }
.ysn-detail-shots img { width: 100%; border-radius: var(--radius-md); border: 1px solid var(--border); }
.ysn-dialog .ysn-scoreline { margin-bottom: 0.2rem; }

/* who played — two rosters side by side inside the match report */
.ysn-lineups {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.7rem;
    margin-top: 0.4rem;
}
.ysn-lineup {
    padding: 0.8rem 0.9rem;
    background: var(--dark);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}
.ysn-lineup-team {
    display: block;
    margin-bottom: 0.55rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--divider);
    font-family: var(--font-mono); font-size: 0.64rem; font-weight: 500;
    letter-spacing: 0.14em; text-transform: uppercase; color: var(--primary-light);
    overflow-wrap: anywhere;
}
.ysn-lineup-list {
    margin: 0;
    padding-left: 1.35rem;
    display: flex; flex-direction: column; gap: 0.3rem;
    font-size: 0.85rem; color: var(--text);
    /* The counters line up under each other regardless of digit width. */
    font-variant-numeric: tabular-nums;
}
.ysn-lineup-list li::marker { color: var(--text-faint, var(--text-muted)); font-size: 0.75em; }
.ysn-lineup-list li { overflow-wrap: anywhere; }
.ysn-lineup-none { margin: 0; font-size: 0.82rem; color: var(--text-muted); }

@media (max-width: 30rem) {
    .ysn-lineups { grid-template-columns: 1fr; }
}

/* segmented choice bar — admin forms (match format, etc.) */
.ysn-segmented {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    /* admin form styles stretch direct children of .form-group to 100% */
    width: fit-content;
    max-width: 100%;
    padding: 0.25rem;
    background: var(--dark-2, var(--dark));
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}
.ysn-segmented .ysn-seg { position: relative; margin: 0; cursor: pointer; }
.ysn-segmented .ysn-seg input {
    position: absolute; inset: 0; margin: 0;
    width: 100%; height: 100%;
    opacity: 0; cursor: pointer;
}
.ysn-segmented .ysn-seg span {
    display: block;
    padding: 0.42rem 0.95rem;
    border-radius: calc(var(--radius-md) - 1px);
    font: 500 0.82rem/1 var(--font-mono);
    letter-spacing: 0.04em;
    color: var(--text-muted);
    transition: background .14s ease, color .14s ease;
}
.ysn-segmented .ysn-seg:hover span { color: var(--text); background: var(--dark-4); }
.ysn-segmented .ysn-seg input:checked + span {
    background: var(--primary);
    color: #fff;
}
.ysn-segmented .ysn-seg input:focus-visible + span {
    outline: 2px solid var(--primary-light);
    outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
    .ysn-segmented .ysn-seg span { transition: none; }
}

/* ==================== 28. TOASTS (upgraded) ==================== */

.toast { display: flex; align-items: flex-start; gap: 0.65rem; }
.toast-icon { flex: 0 0 auto; margin-top: 0.1rem; }
.toast.success .toast-icon { color: var(--success); }
.toast.error   .toast-icon { color: var(--danger); }
.toast.warning .toast-icon { color: var(--warning); }
.toast.info    .toast-icon { color: var(--info); }
.toast-copy { flex: 1 1 auto; min-width: 0; }
.toast-x {
    flex: 0 0 auto; background: none; border: 0; color: var(--text-muted);
    font-size: 1.05rem; line-height: 1; cursor: pointer; padding: 0 0.1rem;
}
.toast-x:hover { color: var(--text); }
@keyframes ysnToastOut { to { opacity: 0; transform: translateX(14px); } }

/* ==================== 29. STYLE A — SMALL SCREENS ==================== */

@media (max-width: 980px) {
    .ysn-hero-grid { grid-template-columns: 1fr; align-items: start; }
    .ysn-section-grid { grid-template-columns: 1fr; }
}
@media (max-width: 780px) {
    /* On a phone the nav needs the full width to scroll, so it drops to its
       own row under the account menu and the centring spacer is dropped. */
    .ysn-bar { grid-template-columns: minmax(0, 1fr); padding: 0.6rem 0; gap: 0.55rem; }
    .ysn-bar::before { display: none; }
    .ysn-bar .main-nav { order: 3; justify-content: flex-start; min-width: 0; }
    .ysn-bar .nav-links { overflow-x: auto; scrollbar-width: none; }
    .ysn-bar .nav-links::-webkit-scrollbar { display: none; }
    .ysn-bar .nav-link { flex: 0 0 auto; padding: 0.55rem 0.7rem; }
    .ysn-strip-grid { grid-template-columns: repeat(4, 1fr); }
    .ysn-stat { padding-left: 0.9rem; }
    .ysn-stat-v { font-size: 1.35rem; }
    .ysn-hero-meta { gap: 1.2rem; }
    .ysn-scoreline-foot { font-size: 0.62rem; }
}

/* --- activity log sentences (change #10) --- */
.ysn-log-line { display: block; color: var(--text); font-size: 0.86rem; }
.ysn-log-extra {
    display: block; margin-top: 0.15rem;
    font-family: var(--font-mono); font-size: 0.68rem;
    letter-spacing: 0.04em; color: var(--text-muted);
}

/* --- homepage newest-members widget --- */
.newest-members-widget .widget-header { justify-content: space-between; }
.widget-header-link {
    color: var(--primary-light);
    font-size: 0.62rem;
    font-weight: 600;
    letter-spacing: 0.07em;
}
.widget-header-link:hover { color: var(--text); }
.newest-members-widget .widget-body { padding-top: 0.25rem; padding-bottom: 0.25rem; }
.newest-members-list { display: grid; }
.newest-member {
    display: grid;
    grid-template-columns: 2.75rem minmax(0, 1fr);
    gap: 0.7rem;
    align-items: center;
    min-width: 0;
    padding: 0.7rem 0;
    color: inherit;
    border-bottom: 1px solid var(--border);
}
.newest-member:last-child { border-bottom: 0; }
.newest-member:hover .newest-member-name { color: var(--primary-light); }
.newest-member-avatar-wrap {
    position: relative;
    display: block;
    width: 2.75rem;
    height: 2.75rem;
}
.newest-member-avatar {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border: 1px solid var(--divider);
    border-radius: var(--radius-md);
}
.newest-member-avatar-wrap .presence-dot {
    right: -0.1rem;
    bottom: -0.1rem;
    width: 0.75rem;
    height: 0.75rem;
    border-width: 2px;
}
.newest-member-info {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    min-width: 0;
}
.newest-member-name {
    max-width: 100%;
    overflow: hidden;
    color: var(--text);
    font-size: 0.86rem;
    font-weight: 700;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: color var(--transition-fast);
}
.newest-member-joined {
    margin-top: 0.12rem;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 0.6rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.newest-member-roles.role-badges {
    justify-content: flex-start;
    gap: 0.2rem;
    max-width: 100%;
    margin: 0.3rem 0 0;
}
.newest-member-roles .role-badge {
    gap: 0.18rem;
    padding: 0.15rem 0.4rem 0.15rem 0.3rem;
    border-width: 1px;
    border-radius: 999px;   /* capsule, not a rounded rectangle */
    font-size: 0.47rem;
    letter-spacing: 0.06em;
}
.newest-members-empty {
    margin: 0;
    padding: 0.7rem 0;
    color: var(--text-muted);
    font-size: 0.78rem;
}

/* --- homepage: one content column + a sticky sidebar for the whole page --- */
.ysn-home-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 20rem;
    gap: clamp(1.2rem, 2.2vw, 2rem);
    align-items: start;
}
.ysn-home-main { min-width: 0; }
.ysn-home-main > .ysn-section:first-child { padding-top: clamp(1.6rem, 2.6vw, 2.4rem); }
.ysn-home-grid > .ysn-aside {
    position: sticky;
    top: var(--space-lg);
    padding-top: clamp(1.6rem, 2.6vw, 2.4rem);
}
@media (max-width: 980px) {
    .ysn-home-grid { grid-template-columns: 1fr; }
    .ysn-home-grid > .ysn-aside { position: static; padding-top: 0; }
}
.ysn-detail-empty { color: var(--text-muted); font-size: 0.88rem; font-style: normal; margin: 0; }

/* ==========================================================================
   30. APPLICATION SUBCATEGORIES + SYSTEM REPLIES  (change #8)
   ========================================================================== */

.forum-thread-list { display: flex; flex-direction: column; gap: 0.6rem; }

.app-groups { display: flex; flex-direction: column; gap: clamp(1.6rem, 3vw, 2.6rem); }
.app-pinned { margin-bottom: clamp(1.6rem, 3vw, 2.6rem); }

.app-group-head {
    display: flex;
    align-items: baseline;
    gap: 0.7rem;
    padding-bottom: 0.6rem;
    margin-bottom: 0.9rem;
    border-bottom: 1px solid var(--border);
}
.app-group-title {
    margin: 0;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: -0.015em;
}
.app-group-count {
    font-family: var(--font-mono);
    font-size: 0.66rem;
    font-weight: 500;
    letter-spacing: 0.12em;
    padding: 0.15rem 0.5rem;
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-muted);
}
.app-group-empty {
    margin: 0;
    padding: 1.1rem 1rem;
    border: 1px dashed var(--border);
    border-radius: var(--radius-md);
    color: var(--text-muted);
    font-size: 0.86rem;
}

/* the two decided groups carry their colour on the heading and the rule */
.app-group-accepted .app-group-title { color: var(--success); }
.app-group-accepted .app-group-head  { border-bottom-color: rgba(61, 220, 132, 0.3); }
.app-group-accepted .app-group-count { background: rgba(61, 220, 132, 0.12); color: var(--success); }

.app-group-rejected .app-group-title { color: var(--danger); }
.app-group-rejected .app-group-head  { border-bottom-color: rgba(255, 90, 84, 0.3); }
.app-group-rejected .app-group-count { background: rgba(255, 90, 84, 0.12); color: var(--danger); }

/* thread rows inherit a matching left rule */
.forum-thread.app-accepted { border-left: 2px solid var(--success); }
.forum-thread.app-rejected { border-left: 2px solid var(--danger); opacity: 0.82; }
.forum-thread.app-rejected:hover { opacity: 1; }

.thread-badge.accepted { background: rgba(61, 220, 132, 0.14); color: var(--success); }
.thread-badge.rejected { background: rgba(255, 90, 84, 0.14); color: var(--danger); }
.thread-author { color: var(--primary-light); font-weight: 600; }

.app-decided {
    display: inline-flex;
    align-items: center;
    padding: 0 0.7rem;
    height: 2.1rem;
    border-radius: var(--radius-md);
    font-family: var(--font-mono);
    font-size: 0.66rem;
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}
.app-decided-accepted { background: rgba(61, 220, 132, 0.12); color: var(--success); }
.app-decided-rejected { background: rgba(255, 90, 84, 0.12); color: var(--danger); }

/* --- the system reply posted on a decision --- */
.forum-post.post-system {
    display: block;
    background: var(--dark-2);
    border: 1px solid var(--border);
    border-left: 2px solid var(--divider);
    border-radius: var(--radius-lg);
    margin-bottom: 1rem;
}
.post-system.tone-accepted { border-left-color: var(--success); background: rgba(61, 220, 132, 0.045); }
.post-system.tone-rejected { border-left-color: var(--danger);  background: rgba(255, 90, 84, 0.045); }
.post-system-inner { padding: 1.15rem 1.3rem; }
.post-system-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-md);
    margin-bottom: 0.6rem;
}
.post-system-tag {
    font-family: var(--font-mono);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.15em;
    text-transform: uppercase;
}
.post-system.tone-accepted .post-system-tag { color: var(--success); }
.post-system.tone-rejected .post-system-tag { color: var(--danger); }
.post-system-time { font-family: var(--font-mono); font-size: 0.68rem; color: var(--text-muted); }
.post-system-body { line-height: 1.7; font-size: 0.95rem; }
.post-system.tone-accepted .post-system-body { color: #A8F0C8; }
.post-system.tone-rejected .post-system-body { color: #FFB3AF; }
.post-system-body p { margin: 0 0 0.6rem; }
.post-system-body p:last-child { margin-bottom: 0; }
.post-system-by {
    margin-top: 0.75rem;
    padding-top: 0.6rem;
    border-top: 1px solid var(--border);
    font-family: var(--font-mono);
    font-size: 0.66rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* --- thread editor (Manage → Edit Thread) --- */
.ysn-dialog .field > textarea {
    padding: 0.7rem 0.8rem;
    background: var(--dark-3);
    border: 1px solid var(--divider);
    border-radius: var(--radius-md);
    color: var(--text);
    font: 400 0.9rem/1.65 var(--font-primary);
    resize: vertical;
    min-height: 9rem;
}
.ysn-dialog .field > textarea:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-tint);
}
.ysn-preview-label {
    font-family: var(--font-mono);
    font-size: 0.64rem;
    font-weight: 500;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.ysn-preview {
    min-height: 4rem;
    padding: 0.85rem 1rem;
    background: var(--dark);
    border: 1px dashed var(--divider);
    border-radius: var(--radius-md);
}

/* ==================== 31. APPLICATION FORM (bilingual) ==================== */

/* step 1 — language choice */
.app-lang { padding: 1.5rem 0 0.5rem; text-align: center; }
.app-lang-lead {
    margin: 0 0 1.4rem;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    font-weight: 500;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.app-lang-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: 0.9rem;
    max-width: 34rem;
    margin: 0 auto;
}
.app-lang-card {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.28rem;
    padding: 1.35rem 1.4rem;
    text-align: left;
    background: var(--dark-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease, transform .15s ease;
}
.app-lang-card:hover,
.app-lang-card:focus-visible {
    background: var(--dark-3, var(--dark-4));
    border-color: var(--primary);
    transform: translateY(-2px);
    outline: none;
}
.app-lang-card:focus-visible { box-shadow: 0 0 0 3px var(--primary-tint); }
.app-lang-code {
    font-family: var(--font-mono);
    font-size: 0.64rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    color: var(--primary-light);
}
.app-lang-name {
    font-family: var(--font-heading);
    font-size: 1.3rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--text);
}
.app-lang-hint { font-size: 0.82rem; color: var(--text-muted); }

@media (prefers-reduced-motion: reduce) {
    .app-lang-card { transition: none; }
    .app-lang-card:hover, .app-lang-card:focus-visible { transform: none; }
}

/* step 2 — requirements + questions */
.app-reqs {
    margin-bottom: 1.6rem;
    padding: 1.1rem 1.25rem;
    background: var(--dark);
    border: 1px solid var(--border);
    border-left: 2px solid var(--primary);
    border-radius: var(--radius-md);
}
.app-reqs h4 {
    margin: 0 0 0.7rem;
    font-family: var(--font-mono);
    font-size: 0.66rem;
    font-weight: 500;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.app-reqs ul { margin: 0; padding-left: 1.15rem; display: flex; flex-direction: column; gap: 0.45rem; }
.app-reqs li { color: var(--text-secondary); font-size: 0.9rem; line-height: 1.55; }
.app-reqs li::marker { color: var(--primary-light); }

.app-form-title {
    margin: 0 0 1.1rem;
    font-family: var(--font-heading);
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text);
}
.app-form .form-group { margin-bottom: 1.05rem; }
.app-form label { display: block; margin-bottom: 0.4rem; line-height: 1.45; }
.app-optional { color: var(--text-muted); font-weight: 400; }
.app-goodluck {
    margin: 1.2rem 0 0;
    font-family: var(--font-heading);
    font-size: 0.98rem;
    font-weight: 600;
    color: var(--primary-light);
}

/* an application read in full from the admin panel */
.ysn-app-row {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding: 0.75rem 0;
    border-top: 1px solid var(--divider);
}
.ysn-app-row:first-of-type { border-top: 0; padding-top: 0.2rem; }
.ysn-app-q {
    font-family: var(--font-mono);
    font-size: 0.64rem;
    font-weight: 500;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.ysn-app-a { color: var(--text); line-height: 1.6; }
.ysn-app-a p { margin: 0 0 0.4rem; }
.ysn-app-a p:last-child { margin-bottom: 0; }

/* ==================== 32. POST EDITOR + RICH TEXT ==================== */

.ysn-editor {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--dark-2);
    overflow: visible;
}
.ysn-editor-input {
    display: block;
    width: 100%;
    margin: 0;
    padding: 0.9rem 1rem;
    background: var(--dark-3, var(--dark));
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0 0 var(--radius-md) var(--radius-md);
    color: var(--text);
    font: 400 0.92rem/1.65 var(--font-primary);
    resize: vertical;
}
.ysn-editor-input:focus { outline: none; box-shadow: inset 0 0 0 1px var(--primary); }

/* --- toolbar --- */
.ysn-tb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.15rem;
    padding: 0.35rem 0.4rem;
}
.ysn-tb-group { display: flex; align-items: center; gap: 0.1rem; }
.ysn-tb-div {
    width: 1px;
    height: 18px;
    margin: 0 0.35rem;
    background: var(--divider);
}
.ysn-tb-spacer { flex: 1 1 auto; }

.ysn-tb-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    min-width: 30px;
    height: 30px;
    padding: 0 0.4rem;
    background: none;
    border: 0;
    border-radius: var(--radius-sm, 3px);
    color: var(--text-muted);
    font: 500 0.85rem/1 var(--font-primary);
    cursor: pointer;
    transition: background .13s ease, color .13s ease;
}
.ysn-tb-btn svg { width: 15px; height: 15px; flex: 0 0 auto; }
.ysn-tb-btn:hover { background: var(--dark-4); color: var(--text); }
.ysn-tb-btn:focus-visible { outline: 2px solid var(--primary-light); outline-offset: -1px; }
.ysn-tb-btn:active { background: var(--primary-tint); color: var(--primary-light); }

/* The letter buttons carry their own meaning, so they show it. */
.ysn-tb-btn.is-b { font-weight: 800; }
.ysn-tb-btn.is-i { font-style: italic; font-family: var(--font-heading); }
.ysn-tb-btn.is-u { text-decoration: underline; text-underline-offset: 2px; }
.ysn-tb-btn.is-s { text-decoration: line-through; }
.ysn-tb-btn.is-big { font-size: 1.05rem; font-weight: 700; }
.ysn-tb-btn.is-small { font-size: 0.68rem; font-weight: 700; }

/* --- colour pickers --- */
.ysn-tb-pop-wrap { position: relative; display: inline-flex; }
.ysn-tb-color { flex-direction: column; gap: 0; padding: 0 0.3rem; position: relative; }
.ysn-tb-color-a { font-weight: 700; font-size: 0.82rem; line-height: 1; }
.ysn-tb-color-bar {
    display: block;
    width: 15px;
    height: 3px;
    margin-top: 2px;
    border-radius: 1px;
}
.ysn-tb-chev { width: 9px !important; height: 9px !important; position: absolute; right: -1px; bottom: 2px; opacity: .7; }
.ysn-tb-pop {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 40;
    padding: 0.5rem;
    background: var(--dark-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55);
}
.ysn-tb-swatches {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 0.3rem;
}
.ysn-tb-swatch {
    width: 20px;
    height: 20px;
    padding: 0;
    background: var(--sw);
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 3px;
    cursor: pointer;
    transition: transform .12s ease;
}
.ysn-tb-swatch:hover { transform: scale(1.16); }
.ysn-tb-swatch:focus-visible { outline: 2px solid var(--primary-light); outline-offset: 2px; }

/* --- preview --- */
.ysn-tb-preview {
    padding: 0 0.7rem;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}
.ysn-tb-preview.is-on { background: var(--primary); color: #fff; }
.ysn-tb-preview.is-on:hover { background: var(--primary); color: #fff; }
.ysn-editor-preview {
    padding: 0.9rem 1rem;
    border-top: 1px dashed var(--divider);
    background: var(--dark);
    border-radius: 0 0 var(--radius-md) var(--radius-md);
}
.ysn-editor-empty { color: var(--text-muted); font-style: italic; margin: 0; }

@media (prefers-reduced-motion: reduce) {
    .ysn-tb-btn, .ysn-tb-swatch { transition: none; }
    .ysn-tb-swatch:hover { transform: none; }
}

/* --- what the tags render as --- */
.ysn-rt-big { font-size: 1.3em; font-weight: 700; line-height: 1.3; }
.ysn-rt-small { font-size: 0.82em; }
.ysn-rt-bg {
    /* Highlights are always a light colour, so the text on them must go dark. */
    padding: 0.05em 0.3em;
    border-radius: 3px;
    color: #14141A;
}
.ysn-rt-center { text-align: center; }
.ysn-rt-center > *:last-child { margin-bottom: 0; }
.ysn-rt-img {
    display: block;
    max-width: 100%;
    height: auto;
    margin: 0.5rem 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}
.ysn-rt-center .ysn-rt-img { margin-inline: auto; }
.ysn-rt-video {
    position: relative;
    width: 100%;
    max-width: 42rem;
    margin: 0.9rem 0;
    aspect-ratio: 16 / 9;
    background: #000;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: hidden;
}
.ysn-rt-video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.ysn-rt-center .ysn-rt-video { margin-inline: auto; }

/* An [img] whose address turned out to be a page, not a picture. */
.ysn-rt-imgfail {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0.4rem 0;
    padding: 0.55rem 0.8rem;
    background: var(--dark);
    border: 1px dashed var(--divider);
    border-radius: var(--radius-md);
    color: var(--text-muted);
    font-size: 0.84rem;
    text-decoration: none;
}
.ysn-rt-imgfail:hover { border-color: var(--primary); color: var(--text); }
.ysn-rt-imgfail svg { flex: 0 0 auto; }

/* ==================== 33. HOMEPAGE FEED PANEL ==================== */

/* Two framed containers, one per feed, each holding its items as cards. */
.ysn-feed {
    position: relative;
    margin: clamp(1.4rem, 2.4vw, 2.2rem) 0;
    background:
        radial-gradient(120% 100% at 50% 0%, rgba(124, 92, 255, 0.085), transparent 62%),
        linear-gradient(180deg, var(--dark-2), var(--dark));
    border: 1px solid var(--border);
    border-radius: calc(var(--radius-md) * 3);
    box-shadow:
        0 24px 60px -30px rgba(0, 0, 0, 0.9),
        inset 0 1px 0 rgba(255, 255, 255, 0.045);
    overflow: hidden;
}
/* A hairline of light along the top edge — the panel reads as one object. */
.ysn-feed::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--primary-light), transparent);
    opacity: 0.5;
}

/* Each feed is its own container, so the padding lives on the panel and the
   pane divider is gone — the gap between the two panels does that job now. */
.ysn-feed > .ysn-feed-head,
.ysn-feed > .ysn-feed-body { padding-inline: clamp(1.05rem, 1.9vw, 1.7rem); }
.ysn-feed > .ysn-feed-head { padding-top: clamp(1.25rem, 2.1vw, 1.85rem); }
.ysn-feed > .ysn-feed-body { padding-bottom: clamp(1.25rem, 2.1vw, 1.85rem); }

.ysn-feed-head {
    display: flex;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 0.5rem 0.85rem;
    margin-bottom: 1.05rem;
}
.ysn-feed-headings { display: flex; flex-direction: column; gap: 0.22rem; min-width: 0; }
.ysn-feed-eyebrow {
    font-family: var(--font-mono);
    font-size: 0.63rem;
    font-weight: 500;
    letter-spacing: 0.17em;
    text-transform: uppercase;
    color: var(--primary-light);
}
.ysn-feed-title {
    margin: 0;
    font-family: var(--font-heading);
    font-size: clamp(1.15rem, 1.9vw, 1.45rem);
    font-weight: 800;
    letter-spacing: -0.018em;
    color: var(--text);
}
/* Fills the gap between the heading and the action, tying the row together. */
.ysn-feed-rule {
    flex: 1 1 2rem;
    min-width: 1.5rem;
    height: 1px;
    margin-bottom: 0.55rem;
    background: linear-gradient(90deg, var(--divider), transparent);
}
.ysn-feed-count {
    margin-bottom: 0.42rem;
    font-family: var(--font-mono);
    font-size: 0.63rem;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.ysn-feed-body > .empty-state { border: 0; background: none; padding: 1.5rem 0; }

@media (max-width: 560px) {
    .ysn-feed-rule { display: none; }
}

/* --- the card shared by both feeds --- */
.ysn-card {
    position: relative;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 0 0.95rem;
    width: 100%;
    padding: 0.95rem 1.1rem 0.95rem 1rem;
    text-align: left;
    background: var(--dark-3);
    border: 1px solid var(--border);
    border-radius: calc(var(--radius-md) * 2);
    color: var(--text);
    text-decoration: none;
    font: inherit;
    cursor: pointer;
    overflow: hidden;
    transition: background .16s ease, border-color .16s ease, transform .16s ease;
}
.ysn-card + .ysn-card { margin-top: 0.65rem; }
/* The accent rail down the left edge; colour comes from the variant. */
.ysn-card::before {
    content: '';
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 2px;
    background: var(--card-accent, var(--primary));
    opacity: 0.45;
    transition: opacity .16s ease, width .16s ease;
}
.ysn-card:hover {
    background: var(--dark-4);
    border-color: var(--divider);
    transform: translateY(-1px);
}
.ysn-card:hover::before { opacity: 1; width: 3px; }
.ysn-card:focus-visible { outline: 2px solid var(--primary-light); outline-offset: 2px; }

.ysn-card-index {
    padding-top: 0.18rem;
    font-family: var(--font-mono);
    font-size: 0.7rem;
    font-weight: 500;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    opacity: 0.6;
}
.ysn-card-main { display: block; min-width: 0; }
.ysn-card-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
}
.ysn-card-title {
    font-family: var(--font-heading);
    font-size: 1.02rem;
    font-weight: 700;
    letter-spacing: -0.012em;
    color: var(--text);
    overflow-wrap: anywhere;
}
.ysn-card-chip {
    flex: 0 0 auto;
    padding: 0.2rem 0.45rem;
    background: var(--primary-tint);
    border: 1px solid var(--primary-line, var(--border));
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 0.6rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--primary-light);
}
.ysn-card-date {
    display: block;
    margin-top: 0.22rem;
    font-family: var(--font-mono);
    font-size: 0.65rem;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}
.ysn-card-excerpt {
    display: block;
    margin-top: 0.6rem;
    color: var(--text-secondary, var(--text-muted));
    font-size: 0.89rem;
    line-height: 1.6;
    overflow-wrap: anywhere;
}
.ysn-card-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-top: 0.75rem;
    padding-top: 0.65rem;
    border-top: 1px solid var(--border);
    font-size: 0.8rem;
    color: var(--text-muted);
}
.ysn-card-by strong { color: var(--text); font-weight: 600; }
.ysn-card-go {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-family: var(--font-mono);
    font-size: 0.65rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--primary-light);
    white-space: nowrap;
}
.ysn-card-arrow { transition: transform .16s ease; }
.ysn-card:hover .ysn-card-arrow { transform: translateX(3px); }

@media (prefers-reduced-motion: reduce) {
    .ysn-card, .ysn-card::before, .ysn-card-arrow { transition: none; }
    .ysn-card:hover { transform: none; }
    .ysn-card:hover .ysn-card-arrow { transform: none; }
}

/* --- clan war variant --- */
.ysn-card-war.win  { --card-accent: var(--success); }
.ysn-card-war.loss { --card-accent: var(--danger); }
.ysn-card-war.draw { --card-accent: var(--primary); }

.ysn-war-vs {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.4rem;
    font-family: var(--font-heading);
    font-size: 1.02rem;
    font-weight: 700;
    letter-spacing: -0.012em;
    min-width: 0;
}
.ysn-war-vs .ysn-us { color: var(--primary-light); }
.ysn-war-vs .ysn-vs {
    font-family: var(--font-primary);
    font-size: 0.78rem;
    font-weight: 400;
    color: var(--text-muted);
}
.ysn-war-vs .ysn-them { color: var(--text); overflow-wrap: anywhere; }

.ysn-war-result {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.1rem;
    flex: 0 0 auto;
}
.ysn-score {
    font-family: var(--font-heading);
    font-size: clamp(1.35rem, 2.4vw, 1.8rem);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.02em;
    /* Scores must not jitter between cards as digits change. */
    font-variant-numeric: tabular-nums;
}
.ysn-score-sep { margin: 0 0.16rem; opacity: 0.3; }
.ysn-score { color: var(--text); }
.ysn-card-war.win  .ysn-score-us { color: var(--success); }
.ysn-card-war.loss .ysn-score-us { color: var(--danger); }
.ysn-card-war.draw .ysn-score-us { color: var(--text); }
.ysn-score-them { color: var(--text); }
.ysn-result-word {
    font-family: var(--font-mono);
    font-size: 0.58rem;
    font-weight: 500;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.ysn-meta-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
    margin-top: 0.7rem;
}
.ysn-meta-chip {
    padding: 0.24rem 0.48rem;
    background: var(--dark);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
    white-space: nowrap;
}

/* Shared by both card variants, not just the war one: on a phone every card
   stacks and drops its index. Lives here because this is where section 33's
   card rules end — see .ysn-card in the base block above. */
@media (max-width: 520px) {
    .ysn-card { grid-template-columns: minmax(0, 1fr); gap: 0; }
    .ysn-card-index { display: none; }
    .ysn-card-top { flex-direction: column; align-items: flex-start; gap: 0.4rem; }
    .ysn-war-result { align-items: flex-start; }
}

/* --- account dropdown --- */
/* auth.js toggles .show on click, but style.css only ever revealed this menu
   on .user-dropdown:hover — so clicking the trigger did nothing, and on a
   touch screen there was no way to reach Profile / Admin / Logout at all. */
.dropdown-menu.show {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}
.user-trigger { cursor: pointer; }
.user-trigger[aria-expanded="true"] { background: var(--dark-4); }
/* style.css also opens this menu on hover. With a click toggle that means the
   menu pops open just from passing the cursor over the name, and will not shut
   on a second click because the pointer is still on the trigger. Click wins. */
.user-dropdown:hover .dropdown-menu:not(.show) {
    opacity: 0;
    visibility: hidden;
    transform: translateY(-10px);
}
/* style.css clips the header with overflow:hidden (it was hiding a decorative
   glow that this theme already removes). That clip also cut off the account
   dropdown, which hangs below the header — so the menu opened but was invisible. */
.site-header { overflow: visible; }

/* ==================== 34. AVATAR SIZING ==================== */

/* None of the avatar rules set object-fit, so any picture that was not already
   square got squashed into the box instead of cropped. cover + centre keeps
   the subject and the proportions; aspect-ratio guarantees the box is square
   even if one dimension is overridden somewhere. */
.profile-avatar,
.member-avatar,
.post-avatar,
.user-avatar,
.user-avatar-sm,
.member-card .member-avatar {
    object-fit: cover;
    object-position: center;
    aspect-ratio: 1 / 1;
    background: var(--dark-3);
}

/* Fixed pixel sizes meant the profile picture was the same 104px on a phone as
   on a widescreen. These scale with the viewport and stop at sensible ends. */
.profile-avatar {
    width: clamp(84px, 13vw, 140px);
    height: clamp(84px, 13vw, 140px);
}
.avatar-edit-btn {
    width: clamp(28px, 3.4vw, 36px);
    height: clamp(28px, 3.4vw, 36px);
}
.avatar-edit-btn svg { width: 55%; height: 55%; }

.member-avatar {
    width: clamp(72px, 9vw, 104px);
    height: clamp(72px, 9vw, 104px);
}
.post-avatar {
    width: clamp(56px, 7vw, 78px);
    height: clamp(56px, 7vw, 78px);
}

/* Below the tablet breakpoint the profile header stacks, so the picture no
   longer competes with the name for width and can take a little more room. */
@media (max-width: 640px) {
    .profile-avatar { width: clamp(88px, 24vw, 116px); height: clamp(88px, 24vw, 116px); }
}

/* ==================== 35. ACTIVITY DOT ==================== */

/* The dot on a roster avatar now reports how active the player is, not whether
   they have the site open. Same thresholds as the activity meter, so the dot
   and the bar always tell the same story. These override the .online/.recent/
   .offline presence colours from ysn-ui.css. */
.presence-dot.activity-dot { animation: none; }

.presence-dot.activity-dot.high {
    background: var(--success);
    box-shadow: 0 0 6px var(--success), 0 0 12px rgba(61, 220, 132, 0.45);
    animation: presencePulse 2s ease-in-out infinite;
}
.presence-dot.activity-dot.mid {
    background: var(--warning);
    box-shadow: 0 0 6px var(--warning), 0 0 12px rgba(255, 194, 75, 0.35);
}
.presence-dot.activity-dot.low {
    background: var(--danger);
    box-shadow: 0 0 6px rgba(255, 90, 84, 0.5);
}
/* No rating yet is not the same as inactive — grey says so rather than lying. */
.presence-dot.activity-dot.unset {
    background: var(--text-muted);
    box-shadow: none;
    opacity: 0.55;
}

@media (prefers-reduced-motion: reduce) {
    .presence-dot.activity-dot.high { animation: none; }
}

/* ==================== 36. ADMIN INBOX ==================== */

.admin-nav-badge {
    margin-left: auto;
    min-width: 1.25rem;
    padding: 0.1rem 0.35rem;
    background: var(--danger);
    border-radius: var(--radius-full, 999px);
    color: #fff;
    font-family: var(--font-mono);
    font-size: 0.62rem;
    font-weight: 600;
    line-height: 1.5;
    text-align: center;
}

.inbox-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-bottom: 1.1rem;
}
.inbox-toolbar #inboxSearch { flex: 1 1 16rem; min-width: 0; }
.inbox-toolbar #inboxFilter { flex: 0 0 auto; }

.inbox-item {
    position: relative;
    padding: 1.05rem 1.2rem;
    background: var(--dark-2);
    border: 1px solid var(--border);
    border-left: 2px solid transparent;
    border-radius: var(--radius-md);
}
.inbox-item + .inbox-item { margin-top: 0.7rem; }
/* Unread is the state that needs to be findable at a glance. */
.inbox-item.is-unread {
    background: var(--dark-3);
    border-left-color: var(--primary);
}

.inbox-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.4rem 0.8rem;
}
.inbox-who { display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem; min-width: 0; }
.inbox-who strong { color: var(--text); }
.inbox-dot {
    width: 7px; height: 7px;
    background: var(--primary);
    border-radius: 50%;
    flex: 0 0 auto;
}
.inbox-email { color: var(--primary-light); font-size: 0.84rem; text-decoration: none; overflow-wrap: anywhere; }
.inbox-email:hover { text-decoration: underline; }
.inbox-account {
    padding: 0.12rem 0.4rem;
    background: var(--primary-tint);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 0.6rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--primary-light);
}
.inbox-when {
    font-family: var(--font-mono);
    font-size: 0.66rem;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    white-space: nowrap;
}
.inbox-subject {
    margin: 0.6rem 0 0.4rem;
    font-family: var(--font-heading);
    font-size: 1rem;
    font-weight: 700;
    color: var(--text);
    overflow-wrap: anywhere;
}
.inbox-body {
    color: var(--text-secondary, var(--text-muted));
    font-size: 0.9rem;
    line-height: 1.65;
    overflow-wrap: anywhere;
}
.inbox-body p:last-child { margin-bottom: 0; }
.inbox-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
    margin-top: 0.9rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border);
}

/* inbox: Discord identity + sent replies */
.inbox-discord {
    padding: 0.12rem 0.4rem;
    background: rgba(88, 101, 242, 0.16);
    border: 1px solid rgba(88, 101, 242, 0.45);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 0.66rem;
    color: #A5B0FF;
}
.inbox-noreply {
    align-self: center;
    font-size: 0.8rem;
    color: var(--text-muted);
    font-style: italic;
}
.inbox-reply {
    margin-top: 0.8rem;
    padding: 0.7rem 0.9rem;
    background: var(--dark);
    border-left: 2px solid var(--success);
    border-radius: var(--radius-md);
}
.inbox-reply-head {
    display: block;
    margin-bottom: 0.35rem;
    font-family: var(--font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--success);
}
.inbox-reply p:last-child { margin-bottom: 0; }

/* ==================== 37. FOUNDER RANK ==================== */
/*
 * The account role `leader` is now shown as "Founder" and `moderator` as
 * "Leader". Both used to land on the same purple star badge, which left the
 * two top ranks looking identical the moment the names changed. Founder takes
 * gold, Leader keeps the purple that its name always implied.
 *
 * Only the colour tokens are overridden - the badge shell, the running
 * highlight (.rb-shine) and the layout all stay exactly as they are.
 */
/*
 * Founder used to be gold here to separate it from Leader. The new palette
 * puts Founder and Admin on the same gradient by design, so this override is
 * gone - the tokens in ysn-ui.css are the single source of truth again.
 * The role-pill below is a different component and keeps its own colour.
 */

.role-pill.role-founder {
    background: rgba(255, 202, 58, 0.16);
    color: #ffd76a;
    border-color: rgba(255, 202, 58, 0.38);
}

/* ==================== 38. LONG ROLE CAPTIONS ==================== */
/*
 * "ASSISTANT CL" is the longest caption a badge has ever carried, and at the
 * base 0.16em letter-spacing it wrapped onto two lines inside the forum post
 * sidebar - the narrowest place a badge appears.
 *
 * Rather than shrink every badge, the caption is kept on one line and the
 * tracking is relaxed only where space is actually tight. Everything else
 * about the badge - colours, border, the running .rb-shine highlight - is
 * untouched.
 */
.role-badge {
    white-space: nowrap;
    max-width: 100%;
}

.post-author-card .role-badge,
.member-card .role-badge {
    padding: 0.45rem 0.7rem;
    gap: 0.3rem;
    letter-spacing: 0.1em;
}

/* Two ranks share a card in the roster, so give those a little more room. */
.role-badges {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.35rem;
}

/* ==========================================================================
   39. CLAN CHAT (home page sidebar)
   --------------------------------------------------------------------------
   The sidebar is 20rem and sticky, so the box has to keep a fixed height or
   it drags the whole column past the viewport and the stickiness stops being
   worth anything. The message list is the only part that grows, and it
   scrolls inside itself.
   ========================================================================== */

.chat-widget {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.chat-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
}

.chat-online {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    text-transform: none;
    color: var(--text-muted);
}

.chat-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--success);
    box-shadow: 0 0 0 3px rgba(61, 220, 132, 0.15);
    flex: none;
}

/* --- messages --- */

.chat-list {
    max-height: 17rem;
    min-height: 8rem;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.chat-list::-webkit-scrollbar { width: 6px; }
.chat-list::-webkit-scrollbar-track { background: transparent; }
.chat-list::-webkit-scrollbar-thumb {
    background: var(--dark-5);
    border-radius: 3px;
}

.chat-empty {
    margin: 0;
    padding: 1.6rem 1rem;
    text-align: center;
    color: var(--text-muted);
    font-size: 0.82rem;
}

.chat-msg {
    padding: 0.55rem 0.85rem;
    border-bottom: 1px solid var(--border);
}
.chat-msg:last-child { border-bottom: 0; }

.chat-msg-head {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.15rem;
}

.chat-author {
    font-weight: 600;
    font-size: 0.8rem;
    color: var(--primary-light);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.chat-time {
    margin-left: auto;
    flex: none;
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 0.66rem;
    color: var(--text-muted);
}

/*
 * The role badge is the same component the roster and the forum use, running
 * highlight and all - it is only ever scaled down here, never restyled, so a
 * change to the badge keeps reaching this box too.
 */
.chat-msg-head .role-badge {
    padding: 0.12rem 0.34rem;
    font-size: 0.5rem;
    letter-spacing: 0.06em;
    gap: 0.16rem;
    flex: none;
    min-width: 0;
}

/*
 * The capsule's gem dot is sized in em, so it already shrinks with the label
 * here and needs no override. The old glyph and running-highlight rules that
 * lived at this spot are gone with them.
 */

.chat-msg-body {
    font-size: 0.83rem;
    line-height: 1.5;
    color: var(--text);
    overflow-wrap: anywhere;
}

.chat-msg-body b { font-weight: 700; color: var(--text); }
.chat-msg-body s { color: var(--text-muted); }
.chat-msg-body a { color: var(--primary-light); text-decoration: underline; }
.chat-msg-body a:hover { color: var(--text); }

.chat-msg-body code {
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 0.75rem;
    background: var(--dark);
    border: 1px solid var(--border);
    padding: 0.05rem 0.3rem;
    border-radius: var(--radius-sm, 4px);
    color: var(--primary-light);
}

.chat-quote {
    display: block;
    border-left: 2px solid var(--primary);
    padding-left: 0.55rem;
    color: var(--text-secondary);
}

/* --- emoji --- */

.ysn-emoji {
    width: 1.15em;
    height: 1.15em;
    vertical-align: -0.22em;
    margin: 0 0.05em;
    /* An emoji is decoration inside a line of text, not a target. */
    user-select: none;
}

.ysn-emoji-lg {
    width: 1.55rem;
    height: 1.55rem;
    display: block;
    pointer-events: none;
}

/* --- picker --- */

.chat-picker {
    background: var(--dark-4);
    border-top: 1px solid var(--border);
}
.chat-picker[hidden] { display: none; }

.chat-tabs {
    display: flex;
    gap: 2px;
    padding: 0.45rem 0.5rem 0;
    overflow-x: auto;
    scrollbar-width: none;
}
.chat-tabs::-webkit-scrollbar { display: none; }

.chat-tab {
    flex: none;
    background: transparent;
    border: 0;
    border-radius: var(--radius-sm, 5px) var(--radius-sm, 5px) 0 0;
    padding: 0.3rem 0.5rem;
    font-family: inherit;
    font-size: 0.68rem;
    color: var(--text-muted);
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}
.chat-tab:hover { color: var(--text-secondary); }
.chat-tab.is-on {
    background: var(--dark-3);
    color: var(--text);
}

.chat-grid {
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    gap: 2px;
    padding: 0.5rem;
    background: var(--dark-3);
    max-height: 9.5rem;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.chat-emoji-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.15rem;
    background: transparent;
    border: 0;
    border-radius: var(--radius-sm, 5px);
    cursor: pointer;
    transition: background 0.12s ease, transform 0.12s ease;
}
.chat-emoji-btn:hover {
    background: var(--dark-5);
    transform: translateY(-1px);
}

/* --- toolbar --- */

.chat-tools {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 0.4rem 0.5rem;
    border-top: 1px solid var(--border);
    background: var(--dark-2);
}

.chat-tool {
    width: 1.6rem;
    height: 1.6rem;
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--radius-sm, 5px);
    font-family: inherit;
    font-size: 0.75rem;
    line-height: 1;
    color: var(--text-muted);
    cursor: pointer;
    transition: background 0.12s ease, color 0.12s ease;
}
.chat-tool:hover { background: var(--dark-5); color: var(--text); }
.chat-tool.is-on { background: var(--dark-5); color: var(--primary-light); }
.chat-tool-b { font-weight: 800; }
.chat-tool-i { font-style: italic; }
.chat-tool-u { text-decoration: underline; }
.chat-tool-s { text-decoration: line-through; }

.chat-tool-sep {
    width: 1px;
    height: 0.95rem;
    background: var(--divider);
    margin: 0 0.2rem;
    flex: none;
}

.chat-count {
    margin-left: auto;
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 0.62rem;
    color: var(--text-muted);
}
.chat-count.is-over { color: var(--danger); }

/* --- compose --- */

.chat-compose {
    display: flex;
    gap: 0.4rem;
    padding: 0.5rem;
    border-top: 1px solid var(--border);
}

.chat-input {
    flex: 1;
    min-width: 0;
    background: var(--dark);
    border: 1px solid var(--border);
    border-radius: var(--radius-md, 7px);
    padding: 0.45rem 0.6rem;
    color: var(--text);
    font-family: inherit;
    font-size: 0.8rem;
}
.chat-input::placeholder { color: var(--text-muted); }
.chat-input:focus {
    outline: none;
    border-color: var(--primary-line);
    box-shadow: 0 0 0 3px var(--primary-tint);
}

.chat-send {
    flex: none;
    background: var(--primary);
    color: #fff;
    border: 0;
    border-radius: var(--radius-md, 7px);
    padding: 0.45rem 0.85rem;
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease;
}
.chat-send:hover { background: var(--primary-dark); }

/*
 * Below the layout breakpoint the sidebar stops being a column and stacks
 * under the feeds, where there is room for more of the conversation.
 */
@media (max-width: 980px) {
    .chat-list { max-height: 22rem; }
    .chat-grid { grid-template-columns: repeat(10, 1fr); }
}

@media (max-width: 520px) {
    .chat-grid { grid-template-columns: repeat(7, 1fr); }
}

/* ==========================================================================
   40. RESPONSIVE — PHONES AND TABLETS
   --------------------------------------------------------------------------
   The site was built for a desktop window and then squeezed. This section
   makes it scale instead, and it is deliberately the last thing in the file
   so it wins without a single !important.

   Three ideas run through all of it:

   1. SIZE FROM THE VIEWPORT, NOT FROM A BREAKPOINT. clamp() lets one rule
      cover every screen between a phone and a monitor, so there is no width
      where the layout is technically "supported" but looks wrong.
   2. A TOUCH TARGET IS 44px. Apple's and Google's floor, and the reason the
      old header was so hard to use: its links were 18px tall.
   3. A FORM FIELD IS 16px. Below that, iOS Safari zooms the whole page the
      moment you focus one, and never zooms back out.
   ========================================================================== */

:root {
    /* Where the tab row becomes a menu. Matches BREAKPOINT in js/ysn-ui.js. */
    --nav-collapse: 900px;
    --tap: 44px;
}

/* --- the page itself --------------------------------------------------- */

html {
    /* A long word or a pasted URL can otherwise make the whole document
       wider than the screen, which is what makes a page slide sideways. */
    overflow-x: hidden;
}

body {
    overflow-x: hidden;
    /* Stops iOS inflating type in landscape, which breaks careful sizing. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

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

/* --- the three-line button --------------------------------------------- */

.nav-toggle {
    display: none;               /* desktop keeps the tab row */
    width: var(--tap);
    height: var(--tap);
    flex: none;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--radius-md, 8px);
    color: var(--text);
    cursor: pointer;
    padding: 0;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.nav-toggle:hover { background: var(--dark-3); border-color: var(--divider); }
.nav-toggle:focus-visible {
    outline: none;
    border-color: var(--primary-line);
    box-shadow: 0 0 0 3px var(--primary-tint);
}

.nav-toggle-bars {
    position: relative;
    display: block;
    width: 20px;
    height: 14px;
}
.nav-toggle-bars span {
    position: absolute;
    left: 0;
    width: 100%;
    height: 2px;
    border-radius: 2px;
    background: currentColor;
    transition: transform 0.22s ease, opacity 0.16s ease, top 0.22s ease;
}
.nav-toggle-bars span:nth-child(1) { top: 0; }
.nav-toggle-bars span:nth-child(2) { top: 6px; }
.nav-toggle-bars span:nth-child(3) { top: 12px; }

/* Three lines fold into a cross, so the button says what it will do next. */
.nav-toggle.is-open .nav-toggle-bars span:nth-child(1) { top: 6px; transform: rotate(45deg); }
.nav-toggle.is-open .nav-toggle-bars span:nth-child(2) { opacity: 0; }
.nav-toggle.is-open .nav-toggle-bars span:nth-child(3) { top: 6px; transform: rotate(-45deg); }

/* --- header and menu --------------------------------------------------- */

@media (max-width: 900px) {
    .nav-toggle { display: inline-flex; }

    .ysn-bar {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-sm, 0.6rem);
        position: relative;
        min-height: 3.75rem;
        flex-wrap: nowrap;
    }

    /* The button reads first for a screen reader and sits left, the account
       controls sit right - the arrangement every phone app already taught
       people. */
    .ysn-bar .nav-toggle { order: 1; }
    .ysn-bar .nav-user { order: 3; margin-left: auto; }
    .ysn-bar .main-nav { order: 2; }

    .main-nav {
        position: static;
        flex: 0 0 auto;
    }

    /*
     * The menu itself. Anchored to the header rather than the nav element so
     * it spans the full width of the screen, which is what makes a phone menu
     * feel like a surface instead of a tooltip.
     */
    .nav-links {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        z-index: 120;
        display: flex;
        flex-direction: column;
        gap: 2px;
        padding: 0.5rem;
        margin: 0;
        background: var(--dark-2);
        border: 1px solid var(--border);
        border-top: 0;
        border-radius: 0 0 var(--radius-lg, 12px) var(--radius-lg, 12px);
        box-shadow: 0 18px 40px rgba(0, 0, 0, 0.55);

        /* Closed state. visibility (not display) so it can animate, and
           pointer-events so nothing behind the invisible panel is clickable. */
        opacity: 0;
        visibility: hidden;
        pointer-events: none;
        transform: translateY(-0.5rem);
        transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
    }

    .ysn-bar.nav-open .nav-links {
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
        transform: translateY(0);
    }

    .nav-links .nav-link {
        display: flex;
        align-items: center;
        gap: 0.7rem;
        width: 100%;
        min-height: var(--tap);
        padding: 0.55rem 0.85rem;
        border-radius: var(--radius-md, 8px);
        border-bottom: 0;
        font-size: 0.82rem;
        letter-spacing: 0.06em;
    }
    .nav-links .nav-link:hover { background: var(--primary-tint); color: var(--primary-light); }
    .nav-links .nav-link.active {
        background: var(--primary-tint);
        color: var(--primary-light);
    }
    /* The desktop tab uses an underline to mark the current page; a full-width
       row uses a bar down its leading edge instead. */
    .nav-links .nav-link.active::after {
        content: '';
        position: absolute;
        left: 0;
        top: 20%;
        bottom: 20%;
        width: 3px;
        border-radius: 0 3px 3px 0;
        background: var(--primary);
    }
    .nav-links .nav-link { position: relative; }
    .nav-links .nav-link span { font-size: 0.82rem; }
    .nav-links .nav-link svg { flex: none; opacity: 0.85; }

    /* --- the strip above the header --- */
    .top-bar { font-size: 0.7rem; }
    .top-bar .container {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 0.6rem;
        min-height: 2.25rem;
    }
    /* The clock and the "User: x" label are both repeated elsewhere on the
       page, and two lines of chrome above the header is a lot of a phone
       screen to spend on nothing. */
    .top-bar-left .top-bar-item:first-child,
    .top-bar-right .top-bar-item,
    .top-bar-separator { display: none; }
    .top-bar-link { min-height: 2rem; display: inline-flex; align-items: center; gap: 0.35rem; }

    .nav-user { gap: 0.4rem; }
    .nav-btn {
        min-height: 2.25rem;
        padding: 0 0.8rem;
        font-size: 0.8rem;
        display: inline-flex;
        align-items: center;
    }
}

/* --- fluid type and spacing -------------------------------------------- */

@media (max-width: 900px) {
    .container {
        padding-left: clamp(0.9rem, 4vw, 1.5rem);
        padding-right: clamp(0.9rem, 4vw, 1.5rem);
    }

    /* Nothing on a phone should be smaller than this and still be readable. */
    .ysn-stat-l,
    .ysn-eyebrow,
    .ysn-feed-count,
    .quick-stat,
    .stat-label,
    .form-hint,
    small { font-size: 0.72rem; }

    .ysn-hero { padding: clamp(1.8rem, 7vw, 3.2rem) 0; }
    .ysn-hero-title { font-size: clamp(2.6rem, 13vw, 4.4rem); line-height: 0.96; }
    .ysn-hero-lead { font-size: clamp(0.95rem, 3.6vw, 1.1rem); }

    .ysn-hero-cta {
        display: flex;
        flex-wrap: wrap;
        gap: 0.6rem;
    }
    .ysn-hero-cta .btn {
        flex: 1 1 auto;
        min-width: 8.5rem;
        min-height: var(--tap);
        justify-content: center;
    }

    .ysn-hero-meta {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
        gap: 0.9rem 1.2rem;
    }

    .ysn-strip-grid { gap: 0; }
    .ysn-stat { padding: 0.85rem 0.6rem; }
    .ysn-stat-v { font-size: clamp(1.1rem, 5vw, 1.6rem); }

    .page-header,
    .ysn-section-head {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.75rem;
    }
    .page-header-actions,
    .ysn-section-head .btn-group {
        display: flex;
        flex-wrap: wrap;
        gap: 0.5rem;
        width: 100%;
    }
    .page-header-actions .btn { flex: 1 1 auto; min-height: var(--tap); justify-content: center; }

    h1 { font-size: clamp(1.6rem, 6.5vw, 2.4rem); }
    h2 { font-size: clamp(1.3rem, 5.2vw, 1.9rem); }
    h3 { font-size: clamp(1.1rem, 4.4vw, 1.5rem); }
}

/* --- every tappable thing gets a thumb-sized box ------------------------ */

@media (hover: none), (max-width: 900px) {
    .btn,
    .nav-btn,
    .dropdown-item,
    .filter-btn,
    .tab-btn,
    .pagination a,
    .admin-nav-item {
        min-height: var(--tap);
    }

    .btn-sm { min-height: 2.25rem; }

    .footer-section a,
    .breadcrumb-item,
    .forgot-password-link,
    .back-home-link,
    .link-primary {
        display: inline-flex;
        align-items: center;
        min-height: 2.5rem;
    }

    /* A checkbox is a 17px box with a label beside it; the whole pair is the
       target, so the label carries the height and the box grows a little. */
    input[type="checkbox"],
    input[type="radio"] {
        width: 1.15rem;
        height: 1.15rem;
    }
}

/* --- forms: 16px, or iOS zooms the page --------------------------------- */

@media (max-width: 900px) {
    input,
    textarea,
    select,
    .form-group input,
    .form-group textarea,
    .form-group select,
    .chat-input,
    .shout-form input {
        font-size: 16px;
    }

    input:not([type="checkbox"]):not([type="radio"]),
    select {
        min-height: var(--tap);
    }

    .form-row,
    .form-grid,
    .field-row {
        grid-template-columns: 1fr;
        display: grid;
        gap: 0.85rem;
    }

    .form-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 0.6rem;
    }
    .form-actions .btn { flex: 1 1 10rem; justify-content: center; }
}

/* --- the home page ------------------------------------------------------ */

@media (max-width: 900px) {
    .ysn-home-grid { grid-template-columns: 1fr; }
    .ysn-home-grid > .ysn-aside { position: static; padding-top: 0; }

    .ysn-feed-head {
        flex-wrap: wrap;
        gap: 0.5rem 0.75rem;
    }
    .ysn-feed-title { font-size: 1.05rem; }

    /* The chat is a sidebar widget on a desktop and a full-width panel here,
       so it can afford to show more of the conversation. */
    .chat-list { max-height: 24rem; }
    .chat-grid { grid-template-columns: repeat(auto-fill, minmax(2.4rem, 1fr)); }
    .chat-tool { width: 2.35rem; height: 2.35rem; font-size: 0.9rem; }
    .chat-emoji-btn { min-height: 2.4rem; }
    .chat-send { min-height: var(--tap); padding: 0 1.1rem; }
    .chat-input { min-height: var(--tap); }
}

/* --- forum, roster, wars, gallery -------------------------------------- */

@media (max-width: 900px) {
    .forum-category,
    .forum-thread {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.6rem;
    }
    .forum-stats,
    .thread-stats {
        display: flex;
        gap: 1.25rem;
        width: 100%;
    }
    .forum-stat,
    .thread-stats > div { text-align: left; }

    .thread-meta,
    .forum-meta { font-size: 0.75rem; }

    /* The author column beside every post is a fixed 143px on a desktop.
       Stacked, it becomes a compact row above the message. */
    .post-author-card {
        width: 100%;
        display: flex;
        align-items: center;
        gap: 0.75rem;
        text-align: left;
        padding: 0.75rem;
    }
    .post-author-card img,
    .post-author-card .avatar { width: 2.75rem; height: 2.75rem; }
    .post-container,
    .forum-post { flex-direction: column; }

    .members-grid,
    .gallery-grid,
    .clanwars-grid,
    .news-grid,
    .stats-grid {
        grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
        gap: 0.9rem;
    }

    .filter-bar,
    .gallery-filters,
    .members-filters {
        display: flex;
        flex-wrap: wrap;
        gap: 0.5rem;
    }
    .filter-bar > *,
    .gallery-filters > * { flex: 1 1 8rem; }

    /* A table cannot reflow, so it scrolls on its own rather than pushing the
       page sideways - and says so with a shadow at the edge. */
    .table-wrap,
    .table-responsive {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    table { min-width: 32rem; }
}

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

@media (max-width: 900px) {
    .admin-layout,
    .admin-grid {
        display: block;
    }

    /* The sidebar becomes a scrolling row of chips across the top - the whole
       nav stays reachable with a thumb without eating half the screen. */
    .admin-sidebar {
        position: static;
        width: 100%;
        margin-bottom: 1rem;
    }
    .admin-nav {
        display: flex;
        gap: 0.4rem;
        overflow-x: auto;
        padding-bottom: 0.35rem;
        scrollbar-width: none;
    }
    .admin-nav::-webkit-scrollbar { display: none; }
    .admin-nav-item {
        flex: none;
        white-space: nowrap;
        border-radius: var(--radius-md, 8px);
        padding: 0 0.85rem;
        font-size: 0.8rem;
    }

    .admin-stats,
    .dashboard-stats {
        grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr));
    }
    .stat-card { padding: 0.9rem; }
    .stat-label { font-size: 0.72rem; }
}

/* --- modals ------------------------------------------------------------- */

@media (max-width: 900px) {
    .modal { padding: 0.75rem; align-items: flex-start; }
    .modal-content {
        width: 100%;
        max-width: none;
        max-height: calc(100vh - 1.5rem);
        margin-top: 0.75rem;
        overflow-y: auto;
    }
    .modal-header h3 { font-size: 1.05rem; }
    .modal-close { width: var(--tap); height: var(--tap); }
}

/* --- the narrow end: 380px and below ------------------------------------ */

@media (max-width: 380px) {
    .ysn-hero-cta .btn { flex: 1 1 100%; }
    .ysn-strip-grid { grid-template-columns: 1fr 1fr; }
    .nav-btn { padding: 0 0.6rem; font-size: 0.75rem; }
    .chat-grid { grid-template-columns: repeat(auto-fill, minmax(2.2rem, 1fr)); }
}

/* --- landscape on a phone: the header must not eat the screen ----------- */

@media (max-height: 480px) and (orientation: landscape) and (max-width: 900px) {
    .top-bar { display: none; }
    .nav-links { max-height: 70vh; overflow-y: auto; }
}

/* --- respect a reduced-motion preference -------------------------------- */

@media (prefers-reduced-motion: reduce) {
    .nav-links,
    .nav-toggle-bars span {
        transition: none;
    }
}

/* --------------------------------------------------------------------------
   40b. THE SMALL PRINT, MADE READABLE
   --------------------------------------------------------------------------
   Every caption on the site sits between 9.4px and 10.9px. On a desktop
   monitor that reads as restraint; held at arm's length on a phone it is
   simply too small, and it is the single thing that makes a site feel like a
   shrunken desktop page rather than something built for the device.

   These are listed one by one rather than swept up with a wildcard, because
   a blanket rule would also inflate things that are meant to be quiet - the
   role badges, the running highlight captions - and make the pages louder
   instead of clearer.
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
    .ysn-stat-l,
    .ysn-eyebrow,
    .ysn-meta-l,
    .ysn-feed-eyebrow,
    .widget-header,
    .forum-stat-label,
    .hero-stat-label,
    .stat-box-label,
    .profile-stat-label,
    .profile-info-label,
    .profile-role-badge,
    .admin-stat-label,
    .breadcrumb-item,
    .status-badge,
    .strength-text,
    .form-help,
    .chat-count,
    .current-year,
    .loading-overlay p,
    label,
    th,
    small {
        font-size: 0.75rem;
        letter-spacing: 0.05em;
    }

    /* The two that carry real numbers can afford a touch more. */
    .ysn-stat-l,
    .forum-stat-label,
    .admin-stat-label { font-size: 0.72rem; }

    /* Footer link lists were 13-15px tall rows of text. */
    .footer-section a,
    .footer-links a,
    .contact-links a {
        min-height: 2.5rem;
        display: inline-flex;
        align-items: center;
    }

    /* The top strip is the only chrome left above the header, so it can be
       thumb-sized without costing much. */
    .top-bar-link,
    .top-bar-item { min-height: 2.5rem; }

    /* The rich-text toolbar in the forum editor: eleven 30px buttons in a
       row is a lot of near-misses. */
    .ysn-tb-btn {
        min-width: 2.4rem;
        min-height: 2.4rem;
        font-size: 0.85rem;
    }

    .server-ip { min-height: 2.5rem; }

    /* Filter and search controls are inputs like any other - they were
       missed because the pages style them by their own class. */
    .filter-input,
    .filter-select,
    .form-input,
    .search-input {
        font-size: 16px;
        min-height: var(--tap);
    }

    /* A checkbox is small by nature and its label is the real target, but at
       17px it is genuinely hard to hit on its own. */
    input[type="checkbox"],
    input[type="radio"] {
        width: 1.5rem;
        height: 1.5rem;
    }
}

/* --------------------------------------------------------------------------
   40c. STOP SHRINKING THE PAGE ON PHONES
   --------------------------------------------------------------------------
   css/style.css drops the root font size to 14px below 768px. Every rem on
   the site is relative to that, so the whole page - type, padding, buttons,
   gaps - came out 12.5% smaller on the device with the least room and the
   worst viewing conditions. It is the single biggest reason the site read as
   a desktop page squeezed onto a phone rather than one built for it, and it
   is why a caption specified at 0.75rem measured 10.5px.

   Phones get 16px like everything else, and the layout does the adapting.
   -------------------------------------------------------------------------- */

@media (max-width: 768px) {
    html { font-size: 16px; }
}

/* --------------------------------------------------------------------------
   40d. THE LAST FEW, BY NAME
   --------------------------------------------------------------------------
   Each of these is set by a selector more specific than the generic one in
   40b, so it needs to be named to be reached. They are all captions that
   land between 9.9px and 11px - readable on a monitor, squinting on a phone.
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
    .form-group label,
    .filter-group label,
    .checkbox-label,
    .form-help,
    .stat-label,
    .stat-box-label,
    .hero-stat-label,
    .gallery-stat-label,
    .cw-stat-label,
    .thread-stat-label {
        font-size: 0.78rem;
        letter-spacing: 0.04em;
    }

    /* A checkbox at 18px is a coin-flip for a thumb. The label beside it is
       the generous part of the target, but the box has to be hittable too. */
    .checkbox-label input[type="checkbox"],
    .checkbox-group input[type="checkbox"] {
        width: 1.5rem;
        height: 1.5rem;
        flex: none;
    }
    .checkbox-label {
        display: inline-flex;
        align-items: center;
        gap: 0.6rem;
        min-height: var(--tap);
    }

    /* Links inside a paragraph inherit its line box, so they measure only a
       few pixels tall. Padding the line gives the thumb somewhere to land
       without changing how the sentence reads. */
    .contact-card a,
    .contact-info a,
    .info-card a,
    p > a {
        padding: 0.2rem 0;
        display: inline-block;
        min-height: 1.75rem;
    }
}

/* Anything the site declares in px stays in px, so it does not scale with
   the root - these two are the only captions left that do. */
@media (max-width: 900px) {
    .admin-stat-label,
    .admin-nav-item,
    .status-badge { font-size: 0.78rem; }
}

/* --------------------------------------------------------------------------
   40e. GRID TRACKS THAT CANNOT PUSH THE PAGE WIDER THAN THE SCREEN
   --------------------------------------------------------------------------
   `1fr` is shorthand for `minmax(auto, 1fr)`, and that `auto` floor is the
   item's min-content width - so a single wide child inside a column makes the
   whole track wider than the screen, and the page scrolls sideways. It is the
   most common way a grid layout breaks on a phone and it looks like a margin
   bug, which is why it survives so long.

   `minmax(0, 1fr)` says the track may shrink to nothing, so the content wraps
   instead of the page growing.
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
    .ysn-home-grid,
    .layout-grid,
    .admin-layout,
    .profile-grid,
    .forum-layout {
        grid-template-columns: minmax(0, 1fr);
    }

    .ysn-home-main,
    .ysn-aside,
    .ysn-feed,
    .widget,
    .sidebar { min-width: 0; max-width: 100%; }

    /* Long unbroken strings - a pasted URL, an in-game name with no spaces -
       are the other thing that widens a page. Wrap them rather than let one
       word decide the layout. */
    .ysn-feed-body,
    .chat-msg-body,
    .post-content,
    .thread-title,
    .forum-post,
    .empty-state { overflow-wrap: anywhere; }
}

/* --------------------------------------------------------------------------
   40f. TWO CAPTIONS THE EARLIER RULES COULD NOT REACH
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
    /* Set at 0.62rem by a two-class selector, so it needs the same weight. */
    .forum-cat-stats .forum-stat-label,
    .forum-stat .forum-stat-label { font-size: 0.75rem; }

    /* A link inside a hint line ("...ask us on our Discord") inherits the
       hint's line height and comes out 17px tall. */
    small a,
    .form-help a {
        display: inline-block;
        padding: 0.25rem 0;
        min-height: 1.9rem;
    }
}

/* --------------------------------------------------------------------------
   40g. THE LAST TWO
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
    /*
     * Eight toolbar buttons at a thumb-friendly size plus the character
     * counter is wider than a 360px phone, and the counter was the piece that
     * fell off the end. Letting the row wrap keeps every button full size
     * rather than shrinking them all back below the tap threshold to fit.
     */
    .chat-tools {
        flex-wrap: wrap;
        row-gap: 0.3rem;
    }
    .chat-count {
        margin-left: auto;
        flex: none;
    }
}

@media (max-width: 400px) {
    /* At the narrow end the buttons give up a little so the row still fits
       on one line more often than not. */
    .chat-tool { width: 2.15rem; height: 2.15rem; }
}

@media (max-width: 900px) {
    /* 30px was still short of the floor. */
    small a,
    .form-help a { min-height: 2.1rem; }
}

/* --------------------------------------------------------------------------
   40h. MENU POLISH
   --------------------------------------------------------------------------
   The panel sits inside the header's container, so it is inset from the screen
   edges rather than full-bleed - a card, not a sheet. That reads as
   deliberate, but it needs its own corners and something to separate it from
   the page it is floating over.
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
    .nav-links {
        top: calc(100% + 0.4rem);
        border-top: 1px solid var(--border);
        border-radius: var(--radius-lg, 12px);
        padding: 0.4rem;
    }

    /*
     * A dim behind the open menu. Without it the page keeps competing for
     * attention through the gaps, which is most of what makes a phone menu
     * feel cluttered. It is a pseudo-element on the bar rather than a real
     * element so no page needs new markup, and it is not the click-away
     * target - that is handled in js/ysn-ui.js, which also covers a tap on
     * the header itself.
     */
    .ysn-bar::after {
        content: '';
        position: fixed;
        inset: 0;
        top: 0;
        z-index: 110;
        background: rgba(4, 4, 6, 0.55);
        backdrop-filter: blur(1.5px);
        opacity: 0;
        visibility: hidden;
        pointer-events: none;
        transition: opacity 0.18s ease, visibility 0.18s;
    }
    .ysn-bar.nav-open::after {
        opacity: 1;
        visibility: visible;
    }

    /* The panel has to sit above its own dim. */
    .nav-links { z-index: 130; }

    /* While the menu is open the page behind it should not scroll away
       underneath - but only the overscroll is locked, so the menu itself can
       still scroll if a phone is short enough to need it. */
    .ysn-bar.nav-open .nav-links {
        max-height: min(70vh, 30rem);
        overflow-y: auto;
        overscroll-behavior: contain;
    }
}

@media (prefers-reduced-motion: reduce) {
    .ysn-bar::after { transition: none; }
}

@media (max-width: 900px) {
    /* The header stays lit while the menu is open - dimming the very controls
       that opened it, and the account buttons beside them, reads as a mistake
       rather than as focus. */
    .ysn-bar > .nav-toggle,
    .ysn-bar > .nav-user { position: relative; z-index: 130; }
    .site-header { position: relative; z-index: 120; }
}

/* --------------------------------------------------------------------------
   40i. STAT CARDS TWO ACROSS
   --------------------------------------------------------------------------
   One number per full-width row turns four statistics into most of a screen
   of scrolling. Two across reads as a block you take in at a glance, which is
   the point of a stat card, and halves the distance to the actual content.
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
    .member-stats-grid,
    .gallery-stats-grid,
    .cw-stats-grid,
    .forum-stats-grid,
    .profile-stats-grid,
    .admin-stats-grid,
    .admin-stats-grid-small,
    .stats-grid {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 0.7rem;
    }

    .member-stats-grid > *,
    .gallery-stats-grid > *,
    .cw-stats-grid > *,
    .forum-stats-grid > *,
    .profile-stats-grid > *,
    .admin-stats-grid > *,
    .admin-stats-grid-small > * { min-width: 0; }

    /* Stacked rather than side by side inside the card, so a long caption
       ("CW Screenshots") has the full card width to sit on. */
    .stat-card,
    .stat-box,
    .forum-stat-card,
    .admin-stat-card {
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        gap: 0.4rem;
        padding: 0.8rem;
        text-align: left;
    }
    .stat-box-icon,
    .stat-card-icon,
    .stat-icon { width: 2rem; height: 2rem; flex: none; }
    .stat-box-icon svg,
    .stat-icon svg { width: 1.1rem; height: 1.1rem; }
    .stat-box-value,
    .stat-card-value,
    .stat-value { font-size: clamp(1.2rem, 5.5vw, 1.6rem); line-height: 1.1; }
    .stat-box-content { min-width: 0; }
}

@media (max-width: 340px) {
    /* Below this two columns leave no room for the number itself. */
    .member-stats-grid,
    .gallery-stats-grid,
    .cw-stats-grid,
    .forum-stats-grid,
    .profile-stats-grid,
    .admin-stats-grid,
    .admin-stats-grid-small { grid-template-columns: minmax(0, 1fr); }
}


/* ==========================================================================
   PHONE LAYER
   --------------------------------------------------------------------------
   Everything below is the mobile pass. It lives at the END of the last
   stylesheet on purpose.

   The reason is the bug it exists to fix. style.css declares the desktop
   layouts AND, further down, a `@media (max-width: 768px)` block that
   correctly collapses them. ysn-theme.css then re-skins the same selectors at
   the top level - outside any media query - so those unconditional rules load
   later, win on source order, and silently undo the mobile block that came
   before them. The forum post was the worst case: style.css collapsed
   `.forum-post` to one column at 768px, ysn-theme.css re-declared
   `grid-template-columns: 180px 1fr` unconditionally, and ysn-theme's own
   mobile block tried to stack it with `flex-direction: column` - which does
   nothing whatever to a grid container. A phone was left rendering a 180px
   author sidebar next to a 132px column of text (64px at 320px wide), which
   is a word and a half per line.

   So: media queries last, after every unconditional rule in the project. Any
   future mobile fix belongs in here rather than in an earlier file, or the
   same shadowing starts again.

   Breakpoints, and what each is for:
     820px  tablet and below - tables stop being tables
     560px  phone - one column everywhere, stacked post headers
     380px  small phone - tighter padding, smaller type
     360px  landscape phone - shorter chrome
   ========================================================================== */

/* --------------------------------------------------------------- universal */

/* Nothing may push the page sideways. A phone that scrolls horizontally
   makes every tap target move under the thumb. */
@media (max-width: 820px) {
    html, body { max-width: 100%; overflow-x: hidden; }

    /* Long unbroken strings - an email, a URL, a pasted server address - are
       the usual culprit. Let them wrap mid-string rather than widen the page.
       `anywhere` (not `break-all`) so ordinary words still break at spaces. */
    .post-body,
    .ysn-detail-body,
    .thread-title,
    .news-title,
    .member-name { overflow-wrap: break-word; }

    /* These carry addresses and URLs - a single token with no break
       opportunity at all - so they get the stronger rule. */
    .user-email,
    .forum-post a,
    .post-body a,
    .admin-table td .mono { overflow-wrap: anywhere; }

    /* Media never overflows its box. */
    img, svg, video, canvas, iframe { max-width: 100%; }
}

/* Short labels must never hyphenate. "Pinned" split across three lines as
   "PIN / NE / D" was the most visible symptom of squeezed flex children:
   a flex item's default `min-width: auto` lets it be compressed below its
   content, and the text then breaks wherever it can. */
@media (max-width: 820px) {
    .thread-badge,
    .badge,
    .role-badge,
    .cw-result-badge,
    .stat-label,
    .ysn-meta-chip,
    .ysn-side,
    .admin-nav-item,
    .status-label,
    .system-status-item > span:last-child,
    .member-role,
    .post-author-role { white-space: nowrap; flex: 0 0 auto; }

    /* The other half of the same fix: stop the containers from squeezing. */
    .thread-badges,
    .role-badges,
    .post-author-stats,
    .stat-item,
    .ysn-scoreline-head,
    .admin-card-header { min-width: 0; flex-wrap: wrap; }
}

/* ------------------------------------------------------- forum thread post */

/* The headline fix. One column, and the author block becomes a compact strip
   above the message instead of a column beside it. */
@media (max-width: 820px) {
    .forum-post,
    .post-container {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
    }

    .post-sidebar {
        border-right: 0;
        border-bottom: 1px solid var(--border);
        padding: 0.85rem 1rem;
    }

    /* Avatar, name and badges on one line; the stats follow it. */
    .post-author-card {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr);
        grid-template-areas:
            "avatar identity"
            "stats  stats";
        align-items: center;
        gap: 0.2rem 0.75rem;
        text-align: left;
        width: 100%;
        padding: 0;
    }
    .post-author-card .post-avatar { grid-area: avatar; width: 2.6rem; height: 2.6rem; margin: 0; }
    .post-author-card .post-author-name {
        grid-area: identity;
        align-self: end;
        font-size: 0.95rem;
        margin: 0;
        min-width: 0;
        overflow-wrap: anywhere;
    }
    .post-author-card .post-author-roles {
        grid-area: identity;
        align-self: start;
        margin-top: 1.35rem;   /* sits under the name inside the same cell */
        display: flex;
        gap: 0.3rem;
    }

    /* Posts / Joined side by side under the name, as one quiet meta line
       rather than two stacked label-and-value pairs. */
    .post-author-stats {
        grid-area: stats;
        flex-direction: row;
        align-items: baseline;
        gap: 0.9rem;
        width: 100%;
        padding-top: 0.6rem;
        margin-top: 0.5rem;
        border-top: 1px solid var(--border);
    }
    .post-author-stats .stat-item {
        flex-direction: row;
        align-items: baseline;
        gap: 0.35rem;
    }
    .post-author-stats .stat-label { font-size: 0.62rem; letter-spacing: 0.1em; }
    .post-author-stats .stat-value { font-size: 0.8rem; font-weight: 600; }

    /* The message itself now gets the full width of the screen. */
    .post-main { padding: 1rem; min-height: 0; min-width: 0; }
    .post-content-wrapper { min-width: 0; }
    .post-body { font-size: 0.95rem; line-height: 1.7; min-width: 0; }
    .post-footer { margin-top: 1rem; padding-top: 0.85rem; justify-content: flex-start; }

    /* Nested lists in a long post (the application template is three levels
       deep) were indenting the text into a gutter of its own. */
    .post-body ul,
    .post-body ol { padding-left: 1.15rem; }
    .post-body pre { overflow-x: auto; }

    /* The thread header above the posts. */
    .thread-header { padding: 1rem; }
    .thread-title { font-size: 1.15rem; line-height: 1.25; }
    .thread-stats { gap: 0.5rem 0.9rem; flex-wrap: wrap; }
}

/* --------------------------------------------------------- admin panel chrome */

@media (max-width: 820px) {
    /* Header: the brand on one row, the actions on their own row underneath.
       Cramming both onto one line is what broke "Back to Site" over three
       lines and pushed the row 58px past a 320px screen. */
    .admin-header { padding: 0.7rem 0; position: static; }
    .admin-header-content {
        flex-direction: column;
        align-items: stretch;
        gap: 0.7rem;
        padding: 0 0.9rem;
        min-width: 0;
    }
    .admin-brand { gap: 0.6rem; min-width: 0; }
    .admin-brand h1 { font-size: 1.1rem; }
    .admin-brand p { font-size: 0.72rem; }

    .admin-header-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 0.45rem;
        width: 100%;
        min-width: 0;
    }
    /* Every action stays on one line and takes the width it needs; they wrap
       onto a second row instead of being compressed. */
    .admin-header-actions > * {
        flex: 1 1 auto;
        min-width: 0;
        white-space: nowrap;
        text-align: center;
        justify-content: center;
        font-size: 0.78rem;
        padding: 0.45rem 0.6rem;
    }
    .admin-user-info { flex: 0 1 auto; }

    /* The tab strip. Eight tabs will never fit, so it scrolls - but it now
       says so: a fade on the right edge, and snap points so a swipe lands on
       a tab rather than between two. */
    .admin-sidebar { position: static; width: 100%; margin: 0; }
    .admin-nav {
        display: flex;
        flex-direction: row;
        gap: 0.35rem;
        overflow-x: auto;
        overscroll-behavior-x: contain;
        -webkit-overflow-scrolling: touch;
        scroll-snap-type: x proximity;
        scrollbar-width: none;
        padding: 0.5rem 1.5rem 0.5rem 0.9rem;
        /* The fade is painted by the mask so it works on any background. */
        mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 1.75rem), transparent 100%);
        -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 1.75rem), transparent 100%);
    }
    .admin-nav::-webkit-scrollbar { display: none; }
    .admin-nav-item {
        flex: 0 0 auto;
        scroll-snap-align: start;
        border-left: 0;
        border-bottom: 2px solid transparent;
        border-radius: var(--radius-md, 8px);
        padding: 0.5rem 0.75rem;
        font-size: 0.78rem;
        gap: 0.4rem;
    }
    .admin-nav-item:hover { transform: none; padding-left: 0.75rem; }
    .admin-nav-item.active {
        border-left: 0;
        border-bottom-color: var(--primary);
    }
    .admin-nav-item svg { width: 1rem; height: 1rem; }

    .admin-layout { display: block; }
    .admin-main { padding: 0.9rem; overflow: visible; }

    /* Card headings were overflowing their own card: a gradient-clipped
       heading with no wrapping and no min-width. */
    .admin-card { min-width: 0; }
    .admin-card:hover { transform: none; }   /* no hover lift on touch */
    .admin-card-header {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.6rem;
        padding: 0.9rem;
        min-width: 0;
    }
    .admin-card-header h3 {
        font-size: 1.05rem;
        line-height: 1.25;
        min-width: 0;
        overflow-wrap: anywhere;
    }
    .admin-card-body { padding: 0.9rem; min-width: 0; }

    /* Section titles ("Content Management", "Member Roster Management") are
       gradient text, which does not shrink on its own. */
    .admin-section-header h2,
    .admin-section-title,
    .section-header h2 {
        font-size: clamp(1.2rem, 6.5vw, 1.8rem);
        line-height: 1.15;
        overflow-wrap: anywhere;
        min-width: 0;
    }

    /* Status rows: label above value rather than fighting for one line. */
    .system-status-grid { grid-template-columns: minmax(0, 1fr); }
    .system-status-item {
        flex-wrap: wrap;
        gap: 0.35rem 0.6rem;
        min-width: 0;
    }
    .system-status-item > *:first-child { min-width: 0; flex: 1 1 60%; }

    /* Quick actions: two per row, labels intact. */
    .quick-actions-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.6rem; }
    .quick-action-btn {
        padding: 0.8rem 0.5rem;
        font-size: 0.8rem;
        min-width: 0;
        text-align: center;
    }
}

/* ------------------------------------------------- admin tables as cards */

/*
 * Below tablet width a table stops being a table.
 *
 * These tables carry 7-8 columns. On a phone the wrapper's `overflow-x: auto`
 * technically let you reach them, but in practice the username and email ran
 * into each other, the right-hand columns were invisible, and reading one
 * person's row meant swiping back and forth. So each row becomes its own
 * card and each cell prints its column name beside the value.
 *
 * The column names come from the table's own <thead> at runtime (see
 * labelAdminTableCells in js/admin-v2.js), which is why there is no
 * hand-written list of labels here: add or reorder a column and the labels
 * follow automatically.
 */
@media (max-width: 820px) {
    .admin-table-wrapper { overflow: visible; }

    /*
     * The previous mobile strategy was the opposite of this one: ysn-ui.css
     * sets `.admin-table { min-width: 44rem }` and ysn-theme sets
     * `table { min-width: 32rem }`, so the table kept its desktop width and
     * the wrapper scrolled. Those floors have to be lifted here or the cards
     * inherit a 704px minimum and hang most of a second screen off to the
     * right - `display: block` on its own does nothing about a min-width.
     */
    .admin-table,
    .admin-table tbody,
    .admin-table tr,
    .admin-table td {
        display: block;
        width: auto;
        min-width: 0;
    }

    .admin-table thead { display: none; }

    .admin-table tbody tr {
        background: var(--dark-3);
        border: 1px solid var(--border);
        border-radius: var(--radius-md, 10px);
        padding: 0.7rem 0.85rem;
        margin-bottom: 0.7rem;
    }
    .admin-table tbody tr:hover { background: var(--dark-3); }
    .admin-table tbody tr:last-child { margin-bottom: 0; }

    .admin-table td {
        border-bottom: 1px solid var(--border);
        padding: 0.4rem 0;
        display: grid;
        grid-template-columns: minmax(4.25rem, 5.5rem) minmax(0, 1fr);
        align-items: baseline;
        gap: 0.6rem;
        font-size: 0.85rem;
        /* `break-word`, not `anywhere`: an address breaks only when the line
           genuinely will not hold it, so "admin@ysn-clan.com" stays whole
           instead of splitting after the hyphen with room to spare. */
        overflow-wrap: break-word;
    }

    /* A badge is a grid item here, and a grid item stretches by default -
       which turned every ADMIN / GUEST / MEMBER pill into a full-width bar.
       Size them to their text and align them with the value column. */
    .admin-table td > .badge,
    .admin-table td > .role-badge,
    .admin-table td > .cw-result-badge { justify-self: start; }
    .admin-table td:last-child { border-bottom: 0; padding-bottom: 0; }

    .admin-table td::before {
        content: attr(data-label);
        font-family: var(--font-mono);
        font-size: 0.62rem;
        letter-spacing: 0.1em;
        text-transform: uppercase;
        color: var(--text-muted);
    }

    /* Cells with nothing to label - the select checkbox, the actions - span
       the full width instead of leaving an empty label gutter. */
    .admin-table td[data-label=""],
    .admin-table td:not([data-label]) {
        display: block;
    }
    .admin-table td[data-label=""]::before,
    .admin-table td:not([data-label])::before { content: none; }

    /* The first labelled cell reads as the card's title. */
    .admin-table td.is-row-title {
        display: block;
        border-bottom: 1px solid var(--divider, var(--border));
        padding-bottom: 0.5rem;
        margin-bottom: 0.25rem;
        font-size: 1rem;
        font-weight: 700;
        color: var(--text);
    }
    .admin-table td.is-row-title::before { content: none; }

    /* Action buttons: a real row of tappable targets, not icons crushed
       into a 40px column. */
    .admin-table td.is-row-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 0.4rem;
        padding-top: 0.6rem;
    }
    .admin-table td.is-row-actions .btn {
        flex: 1 1 auto;
        min-height: 2.25rem;
        min-width: 2.75rem;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* An empty-state row ("No users found") is not a card. */
    .admin-table td[colspan] {
        display: block;
        text-align: center;
        border: 0;
        padding: 1.25rem 0;
    }
    .admin-table td[colspan]::before { content: none; }
}

/* ------------------------------------------------------------- card grids */

/*
 * One column on phones.
 *
 * Two 170px columns on a 390px screen is what cut "317 DAYS" down to
 * "31 DAY" and forced the role badges to overlap their card. Cards go
 * full width up to 430px; two columns return above that.
 */
@media (max-width: 430px) {
    .members-grid,
    .members-category-grid,
    .clanwars-grid,
    .cw-grid,
    .news-grid,
    .gallery-grid,
    .events-grid,
    .applications-grid,
    .admin-members-grid,
    .roster-grid { grid-template-columns: minmax(0, 1fr) !important; }
}

@media (max-width: 820px) {
    /* Whatever the column count, a card must not clip its own contents. */
    .member-card,
    .members-grid > *,
    .members-category-grid > *,
    .clanwars-grid > *,
    .gallery-grid > *,
    .news-grid > * { min-width: 0; }

    .member-card { padding: 0.9rem; }
    .member-card:hover { transform: none; }

    /* The stat row under each member. Wraps instead of truncating, and the
       labels shrink before the numbers do. */
    .member-stats,
    .member-card-stats {
        display: flex;
        flex-wrap: wrap;
        gap: 0.35rem 0.9rem;
        min-width: 0;
    }
    .member-stats > *,
    .member-card-stats > * { flex: 0 0 auto; min-width: 0; }

    .member-meta,
    .member-card-meta {
        flex-wrap: wrap;
        gap: 0.25rem 0.5rem;
        font-size: 0.72rem;
        min-width: 0;
    }

    /* Card action buttons: full-width targets, side by side. */
    .member-card-actions,
    .card-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 0.4rem;
    }
    .member-card-actions .btn,
    .card-actions .btn { flex: 1 1 auto; min-height: 2.25rem; }
}

/* ----------------------------------------------------------- small phones */

@media (max-width: 380px) {
    .admin-main { padding: 0.6rem; }
    .admin-card-header,
    .admin-card-body { padding: 0.7rem; }
    .admin-header-actions > * { font-size: 0.72rem; padding: 0.4rem 0.5rem; }

    /* The label gutter costs too much of the line at this width. */
    .admin-table td {
        grid-template-columns: minmax(0, 1fr);
        gap: 0.1rem;
    }
    .admin-table td::before { font-size: 0.58rem; }

    .post-main { padding: 0.8rem; }
    .post-sidebar { padding: 0.7rem 0.8rem; }
    .post-body { font-size: 0.92rem; }
    .thread-title { font-size: 1.05rem; }

    .quick-actions-grid { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------- landscape on a phone */

/* Short viewport, wide enough for two columns: the fixed chrome eats the
   screen, so trim it rather than the content. */
@media (max-height: 430px) and (orientation: landscape) {
    .admin-header { padding: 0.4rem 0; }
    .admin-brand p { display: none; }
    .admin-nav { padding-top: 0.3rem; padding-bottom: 0.3rem; }
    .post-sidebar { padding: 0.5rem 0.8rem; }
}

/* ------------------------------------------------------------ tap targets */

/* A pointer that cannot hover needs targets it can actually hit, and none of
   the hover-lift transforms (they stick on after a tap on iOS). */
@media (hover: none) {
    .admin-nav-item,
    .admin-table td.is-row-actions .btn,
    .member-card-actions .btn,
    .quick-action-btn,
    .btn-sm { min-height: 2.25rem; }

    .admin-card:hover,
    .member-card:hover,
    .forum-post:hover,
    .stat-box:hover,
    .btn:hover { transform: none; }
    .btn:hover::before { width: 0; height: 0; }
}

/* ------------------------------------------------- remaining phone overflows */

@media (max-width: 820px) {
    /* NOTE ON THE ROLE BADGES: their .rb-shine sweeps from left:-100% to
       left:200%, so its own box lands well outside the badge and an overflow
       audit flags it on every page. It is not a bug and it needs no rule
       here - .role-badge in css/ysn-ui.css already sets `overflow: hidden`,
       so the sweep is clipped to the badge and nothing is painted outside
       it. The badges are under a standing "do not restyle" note (see ROLE
       BADGES — PRESERVED above) and are left exactly as they are. */

    /* Stat tiles: the label was being clipped rather than allowed to wrap. */
    .gallery-stat-content,
    .gallery-stat-label,
    .stat-box-content,
    .stat-card-content {
        min-width: 0;
        overflow-wrap: anywhere;
    }
    .gallery-stat-label,
    .stat-box-label { white-space: normal; }

    /* Table action clusters stay inside the card. */
    .table-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 0.4rem;
        min-width: 0;
    }
    .table-actions .btn { flex: 0 1 auto; }
}

@media (max-width: 380px) {
    /* The hero's two-column intro has no room left at this width. */
    .ysn-hero-grid {
        grid-template-columns: minmax(0, 1fr);
        min-width: 0;
    }
    .ysn-hero-grid > * { min-width: 0; }
}

@media (max-width: 820px) {
    /* The breadcrumb above a thread ran 8px past a 320px screen. Let it wrap
       rather than clip - the trail is how you get back out of a thread. */
    .breadcrumb {
        flex-wrap: wrap;
        gap: 0.15rem 0.35rem;
        min-width: 0;
        font-size: 0.68rem;
    }
    .breadcrumb > * { min-width: 0; }

    /* Forum category cards: icon and title on one line, description under
       it, the delete button pinned to the title row. The three parts used to
       fight for one row and the title lost. */
    .forum-category-card {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr) auto;
        grid-template-areas:
            "icon title actions"
            ".    body  body";
        align-items: center;
        gap: 0.2rem 0.7rem;
        padding: 0.85rem;
        min-width: 0;
    }
    .forum-category-card:hover { transform: none; }
    .forum-category-card .fcc-icon { grid-area: icon; margin: 0; }
    .forum-category-card .fcc-icon svg { width: 1.5rem; height: 1.5rem; }
    .forum-category-card .fcc-actions { grid-area: actions; }
    .forum-category-card .fcc-body {
        grid-area: title;
        display: contents;      /* h4 to the title row, the rest below it */
    }
    .forum-category-card .fcc-body h4 {
        grid-area: title;
        margin: 0;
        font-size: 0.95rem;
        min-width: 0;
        overflow-wrap: break-word;
        hyphens: manual;        /* "Off-Topic" is not a hyphenation point */
    }
    .forum-category-card .fcc-body p,
    .forum-category-card .fcc-body small {
        grid-area: body;
        min-width: 0;
        font-size: 0.74rem;
    }
    .forum-category-card .fcc-body p { margin: 0.15rem 0 0; }
}

/* The desktop rendering of the forum-category card, restored from the inline
   styles the renderer used to emit. Unchanged appearance, now overridable. */
.forum-category-card .fcc-icon {
    font-size: 32px;
    margin-right: 15px;
    color: #8f5bff;
}
.forum-category-card .fcc-body { flex: 1; }

@media (max-width: 820px) {
    /* 3px of overflow on a 320px screen, from padding on a box with no
       min-width of its own. */
    .forum-thread-header,
    .forum-thread-header > * { min-width: 0; }
    .forum-thread-header { padding: 0.9rem; }
}

@media (max-width: 820px) {
    /* The stat tiles on the forum and clan-war pages clipped their captions
       by a few pixels at some widths. Same shape of fix as the gallery
       tiles: the caption wraps instead of being cut, and the tile stops
       imposing a min-width on its own text. */
    .forum-stat-content,
    .cw-stat-content,
    .member-stat-content,
    .profile-stat-content,
    .gallery-stat-content { min-width: 0; }

    /*
     * Stat captions are a mix: one word ("Victories") and two
     * ("Registered users", "CW screenshots"). Neither nowrap nor break-word
     * suits both - nowrap clips the two-word ones, break-word splits
     * "Victories" down the middle. The default wrapping behaviour is
     * exactly right: break at spaces, never inside a word. All that is
     * needed on top is a caption that scales down a little so the longest
     * single word still fits a two-column tile.
     */
    .forum-stat-label,
    .cw-stat-label,
    .member-stat-label,
    .profile-stat-label,
    .gallery-stat-label {
        min-width: 0;
        white-space: normal;
        overflow-wrap: normal;
        word-break: normal;
        hyphens: none;
        font-size: clamp(0.58rem, 2.5vw, 0.72rem);
        letter-spacing: 0.05em;
        line-height: 1.25;
    }

    /* And the tile has to be allowed to grow taller for a wrapped caption
       rather than clipping it. */
    .forum-stat-box,
    .forum-stat-card,
    .cw-stat-card,
    .member-stat-card,
    .gallery-stat-card,
    .profile-stat-card {
        min-width: 0;
        height: auto;
        min-height: 0;
        align-items: start;
    }

    /* Roster stat rows wrap rather than clip - this is the row that was
       cutting "317 DAYS" down to "31 DAY". */
    .admin-member-stats,
    .member-stats-row {
        display: flex;
        flex-wrap: wrap;
        gap: 0.3rem 0.8rem;
        min-width: 0;
    }
    .admin-member-stats > *,
    .member-stats-row > * { min-width: 0; flex: 0 0 auto; }
}

@media (max-width: 820px) {
    /*
     * Roster card actions: three across, not three stacked.
     *
     * ysn-ui.css drops .admin-member-actions to a single column on small
     * screens, which made sense when the cards sat two-per-row and were
     * ~170px wide. Now that a card takes the full width of the phone,
     * "Profile / Edit / Remove" fit comfortably on one line, and stacking
     * them cost three rows of height per member - the roster became a very
     * long scroll for four people.
     */
    /* auto-fit rather than a hard `repeat(3, ...)`: in landscape the roster
       is back to two cards per row, and three fixed columns squeezed the
       labels until "Profile" and "Remove" clipped. This fits three when
       three fit and folds to two when they do not. */
    .admin-member-actions {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(4.75rem, 1fr));
        gap: 0.35rem;
    }
    .admin-member-actions .btn {
        width: 100%;
        min-height: 2.25rem;
        padding: 0.4rem 0.25rem;
        font-size: 0.72rem;
        white-space: nowrap;
    }
}

@media (max-width: 340px) {
    /* Three labels genuinely stop fitting here. */
    .admin-member-actions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --------------------------------------------- flex-basis in a column container */

/*
 * The tall empty gap under every page title, and the 160px-tall form buttons.
 *
 * Both are the same mistake, and it is worth naming because it is easy to
 * repeat. `flex: 1 1 320px` sets flex-BASIS to 320px, and flex-basis applies
 * along the container's main axis - so in a row it is a width (which is what
 * was meant) and in a column it is a HEIGHT.
 *
 *   css/ysn-ui.css:112   .page-header-content { flex: 1 1 320px }
 *   css/ysn-ui.css:1883  @media (max-width: 780px) .page-header-section
 *                        { flex-direction: column }
 *
 * Below 780px the container becomes a column, so that 320px stopped being a
 * comfortable minimum width and became a fixed height: a 320px block holding
 * a title and one line of subtitle - about 65px of content - leaving ~250px
 * of dead space between the heading and everything below it, on Clan Wars,
 * Forum, Gallery and Contact.
 *
 * The same pair does it again to buttons:
 *   css/ysn-theme.css:3174  .form-actions .btn { flex: 1 1 10rem }
 *   css/ysn-ui.css:1974     @media (max-width: 780px) .form-actions
 *                           { flex-direction: column }
 * 10rem = 160px, which is why "Send Message" on the contact page was a
 * 160px-tall slab with 20px of label in the middle of it.
 *
 * The fix in both cases is a basis of `auto` - let the box be as tall as its
 * contents - rather than fighting it with an explicit height.
 */
@media (max-width: 820px) {
    .page-header-section {
        flex-direction: column;
        align-items: stretch;
        gap: 0.75rem;
        padding-bottom: 0.9rem;
    }

    /* The 320px was only ever a minimum WIDTH. As a height it is dead space. */
    .page-header-content {
        flex: 0 1 auto;
        min-width: 0;
    }
    .page-title { font-size: clamp(1.45rem, 7vw, 2rem); gap: 0.6rem; }
    .page-title svg { flex: none; width: 1.6rem; height: 1.6rem; }
    .page-subtitle { font-size: 0.88rem; line-height: 1.45; }

    .page-header-actions {
        width: 100%;
        display: flex;
        flex-wrap: wrap;
        gap: 0.5rem;
        min-width: 0;
    }
    .page-header-actions > .btn {
        flex: 1 1 9rem;      /* a width here: this container is still a row */
        min-width: 0;
        justify-content: center;
    }

    /* Buttons in a stacked form row: full width, and only as tall as a
       button needs to be. */
    .form-actions .btn,
    .form-actions > .btn {
        flex: 0 0 auto;
        width: 100%;
        min-height: 2.75rem;
        height: auto;
    }
}

/* -------------------------------------------------------------- the footer */

/*
 * The Connect column, and the Discord button in it.
 *
 * At <=900px css/ysn-ui.css centres the whole footer (.footer-content becomes
 * one column with `text-align: center`) and drops .footer-links to
 * `repeat(2, 1fr)`. There are THREE columns of links, so Quick Links and
 * Community fill row one and Connect is left on its own in row two, column
 * one - a heading and a small Discord pill hugging the left edge, under a
 * centred logo and above a centred copyright line. Nothing lines up with it.
 *
 * Giving Connect the full width and centring its contents puts the button on
 * the footer's centre line, with the logo, the tagline and the copyright.
 */
@media (max-width: 900px) {
    .footer-links {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 1.4rem 1rem;
        justify-items: center;
        text-align: center;
    }
    .footer-column { min-width: 0; }

    /* Connect is the odd one out: span the row and centre it. `last-child`
       rather than a hard-coded position so it follows the markup if a
       column is added or removed. */
    .footer-links .footer-column:last-child {
        grid-column: 1 / -1;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 0.2rem;
    }
    .footer-links .footer-column:last-child h4 { margin-bottom: 0.7rem; }

    .social-links {
        display: flex;
        justify-content: center;
        width: 100%;
    }
    /* A single Discord button reads better with real width behind it than as
       a small pill floating in the middle of the footer. */
    .social-links .social-link {
        flex: 0 1 14rem;
        justify-content: center;
    }
}

@media (max-width: 380px) {
    /* Two columns of links stop fitting comfortably here. */
    .footer-links { grid-template-columns: minmax(0, 1fr); gap: 1.1rem; }
    .footer-links .footer-column:last-child { grid-column: auto; }
    .social-links .social-link { flex: 1 1 auto; }
}

/* ------------------------------------------------------------ card headers */

/*
 * A card header is `display: flex; justify-content: space-between`, which on a
 * desktop puts the title on the left and either a description or an action on
 * the right. On a phone there is no room for both: on the contact page the
 * "Send us a Message" heading was squeezed to about 60px - wrapping to three
 * lines - while the description sat on top of it.
 *
 * Rather than forcing every card header to stack (plenty are just a title and
 * a small button, which is fine side by side), let the row wrap and give the
 * DESCRIPTION a full-width basis so it always drops onto its own line. Title
 * and button pairs are untouched.
 */
@media (max-width: 820px) {
    .card-header {
        flex-wrap: wrap;
        row-gap: 0.4rem;
        min-width: 0;
    }
    .card-header > * { min-width: 0; }
    .card-header h3 {
        flex: 0 1 auto;
        min-width: 0;
        line-height: 1.3;
    }
    .card-header h3 svg { flex: none; }
    .card-header > p,
    .card-header .card-header-subtitle {
        flex: 1 1 100%;
        margin: 0;
        font-size: 0.84rem;
        line-height: 1.5;
    }
}

/*
 * Footer links, one per row again.
 *
 * There are two footer markups in this project. Contact uses
 * .footer-links > .footer-column > ul > li > a; every other page uses
 * .footer-section with bare <a> children and `display: block` from
 * css/style.css.
 *
 * Two rules above (§ tap targets, and "Footer link lists were 13-15px tall")
 * give those links a 2.5rem tap height with `display: inline-flex` - which
 * also made them INLINE, so the block stacking was lost and "Join YSN Home
 * Members" ran together on a single line. `flex` keeps the tap height and
 * the row-per-link layout, because a block-level flex box still fills its
 * line. Centred, to match the centred footer on a phone.
 *
 * Scoped to .footer-section: the contact page's links sit in list items that
 * were stacking correctly already.
 */
@media (max-width: 900px) {
    .footer-section a {
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 2.5rem;
    }
}


/* --- forum board list: clickable row + latest-threads preview --- */

/*
 * The row is a flex line of info + stats. The preview is a third child that
 * has to sit UNDER both, so the row wraps and the panel claims a full line
 * of its own. Without the wrap it would be squeezed in beside the counters.
 */
.forum-category { flex-wrap: wrap; }

/* The row moves 5px on hover, which drags an open panel with it and makes
   the thread links hard to hit. Hold it still while it is expanded. */
.forum-category.is-expanded:hover { transform: none; }
.forum-category:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

.forum-cat-latest {
    margin-top: 0.5rem;
    color: var(--text-muted);
    font-size: 0.875rem;
}

.forum-cat-stats { align-items: center; }

.forum-cat-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.03);
    color: var(--text-muted);
    cursor: pointer;
    transition: transform 0.18s ease, color 0.18s ease,
                background 0.18s ease, border-color 0.18s ease;
}
.forum-cat-toggle:hover {
    border-color: var(--primary);
    background: rgba(143, 91, 255, 0.16);
    color: var(--text);
}
.forum-cat-toggle:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}
.forum-cat-toggle[aria-expanded="true"] { transform: rotate(180deg); }

.forum-cat-peek {
    flex: 1 0 100%;
    display: grid;
    gap: 0.35rem;
    margin-top: 0.9rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--border);
}
.forum-cat-peek[hidden] { display: none; }

.forum-cat-peek-row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.15rem 0.5rem;
    padding: 0.5rem 0.65rem;
    border: 1px solid transparent;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.02);
    color: inherit;
    text-decoration: none;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.forum-cat-peek-row:hover {
    border-color: var(--primary);
    background: rgba(143, 91, 255, 0.12);
}
.forum-cat-peek-row:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}
.forum-cat-peek-pin { font-size: 0.75rem; }
.forum-cat-peek-title {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    color: var(--text);
    font-size: 0.85rem;
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.forum-cat-peek-meta {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.02em;
}

@media (max-width: 560px) {
    .forum-cat-peek-meta { flex-basis: 100%; }
}


/* ==========================================================================
   De-AI pass, 31 Aug 2026
   --------------------------------------------------------------------------
   Three of the twenty "your app looks vibecoded" tells that this site
   actually had. Kept together at the end of the file, after everything they
   override, so each one is a single place to look and a single place to undo.

   NOT done, deliberately:
     - the purple gradients (#1) stay: purple is the brand
     - glassmorphism (#6) stays: it is only on modal backdrops, the gallery
       lightbox and the admin panel, all of which want it
   ========================================================================== */

/* --- #9 badge above the headline ------------------------------------------
   The eyebrow is a good device and it stays everywhere it does real work:
   // NEWS DESK, // WAR LOG, // MATCH REPORT are section labels.

   The HERO one was different. A short coloured label sitting directly on top
   of a big headline is the badge-above-the-headline pattern, and the purple
   plus the // made it read as decoration rather than information. It is now
   the same muted caps as every other micro-label on the site, and the // is
   gone from the markup. The headline leads.                                */
.ysn-hero .ysn-eyebrow,
.ysn-eyebrow-hero {
    color: var(--text-muted);
}

/* --- #8 three icon boxes in a row ----------------------------------------
   Leaders / Activity / Countries were three separate cards, each with a
   tinted icon square. That is the AI stat-trio, and the icons carried no
   information the label did not already carry.

   They are now one bordered strip divided by hairlines - the same device as
   the stat bar at the top of the homepage, so the two pages agree with each
   other instead of each inventing their own way to show three numbers.     */
.member-stats-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--dark-2);
    overflow: hidden;
}
.member-stats-grid .stat-box {
    background: none;
    border: 0;
    border-left: 1px solid var(--border);
    border-radius: 0;
    padding: 1.1rem 1.25rem;
    display: block;
}
.member-stats-grid .stat-box:first-child { border-left: 0; }
.member-stats-grid .stat-box:hover { background: none; border-color: var(--border); }
.member-stats-grid .stat-box-icon { display: none; }
.member-stats-grid .stat-box-value { font-size: 1.75rem; line-height: 1; margin-bottom: 0.35rem; }

@media (max-width: 640px) {
    /* Three columns of numbers is still readable on a phone; three stacked
       cards was not, and cost a full screen of scrolling. */
    .member-stats-grid .stat-box { padding: 0.85rem 0.6rem; }
    .member-stats-grid .stat-box-value { font-size: 1.25rem; }
}

/* --- #2 gradient text ----------------------------------------------------
   admin-modern.css paints .stat-value and the section headings with
   #a855f7 -> #ec4899 and clips it to the text. The public site had already
   grown out of this - ysn-theme kills the same effect on .gradient-text and
   .post-author-name - but the admin panel never did. Flat colour now, so
   the numbers are the same white as every other number on the site.        */
.stat-value,
.admin-stat-value,
.admin-section-header h2 {
    background: none;
    -webkit-text-fill-color: currentColor;
    color: var(--text);
}

/* ==================== 43. HOMEPAGE MATCHDAY PULSE ==================== */

.ysn-activity {
    margin: clamp(1.4rem, 2.4vw, 2.2rem) 0;
}

.ysn-activity-panel {
    position: relative;
    display: grid;
    grid-template-columns: minmax(12.5rem, 24%) minmax(0, 1fr);
    min-height: 15rem;
    background: linear-gradient(180deg, rgba(20, 19, 27, .98), rgba(12, 12, 17, .98));
    border: 1px solid var(--border);
    border-radius: calc(var(--radius-md) * 3);
    box-shadow: 0 24px 60px -32px rgba(0, 0, 0, .9), inset 0 1px 0 rgba(255, 255, 255, .035);
    overflow: hidden;
}

.ysn-activity-panel::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--primary-light), transparent);
    opacity: .6;
}

.ysn-activity-metrics {
    display: flex;
    flex-direction: column;
    gap: .8rem;
    min-width: 0;
    padding: 1.35rem 1.2rem 1.1rem;
    border-right: 1px solid var(--border);
}

.ysn-activity-kicker,
.ysn-activity-chart-head,
.ysn-activity-status,
.ysn-activity-stats dt,
.ysn-activity-address,
.ysn-activity-collecting {
    font-family: var(--font-mono);
    text-transform: uppercase;
    letter-spacing: .12em;
}

.ysn-activity-kicker {
    display: block;
    margin-bottom: .22rem;
    color: var(--primary-light);
    font-size: .59rem;
}

.ysn-activity-metrics h2,
.ysn-activity-unavailable h2 {
    margin: 0;
    color: var(--text);
    font-family: var(--font-heading);
    font-size: 1.28rem;
    letter-spacing: -.02em;
}

.ysn-activity-status {
    display: flex;
    align-items: center;
    gap: .42rem;
    color: var(--success);
    font-size: .62rem;
    font-weight: 700;
}

.ysn-activity-status i {
    width: .48rem;
    height: .48rem;
    border-radius: 50%;
    background: currentColor;
    box-shadow: 0 0 0 4px rgba(61, 220, 132, .1), 0 0 12px rgba(61, 220, 132, .4);
}

.ysn-activity-status span {
    margin-left: auto;
    color: var(--text-muted);
    font-weight: 500;
}

.ysn-activity-panel.is-offline .ysn-activity-status { color: var(--danger); }
.ysn-activity-panel.is-offline .ysn-activity-status i { box-shadow: 0 0 0 4px rgba(255, 90, 84, .08); }

.ysn-activity-stats {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0;
    margin: 0;
    border-top: 1px solid var(--divider);
}

.ysn-activity-stats > div {
    padding: .65rem .5rem .58rem 0;
    border-bottom: 1px solid var(--divider);
}

.ysn-activity-stats > div:nth-child(even) {
    padding-left: .75rem;
    border-left: 1px solid var(--divider);
}

.ysn-activity-stats dt {
    margin-bottom: .22rem;
    color: var(--text-muted);
    font-size: .53rem;
    line-height: 1.35;
}

.ysn-activity-stats dd {
    margin: 0;
    color: var(--text);
    font-family: var(--font-heading);
    font-size: 1.08rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}

.ysn-activity-stats dd small {
    margin-left: .25rem;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: .62rem;
    font-weight: 500;
}

.ysn-activity-address {
    max-width: 100%;
    margin-top: auto;
    overflow: hidden;
    color: var(--text-muted);
    font-size: .52rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ysn-activity-chart {
    position: relative;
    min-width: 0;
    padding: 1.2rem 1.2rem .7rem .9rem;
}

.ysn-activity-chart-head {
    display: flex;
    justify-content: space-between;
    padding: 0 .7rem .15rem 2.25rem;
    color: var(--text-muted);
    font-size: .55rem;
}

.ysn-activity-chart-head span:first-child { color: var(--text); }
.ysn-activity-svg { display: block; width: 100%; height: 12.4rem; overflow: visible; }
.ysn-activity-gridline { stroke: rgba(142, 139, 160, .15); stroke-width: 1; stroke-dasharray: 2 5; }
.ysn-activity-gridline.is-vertical { opacity: .58; }
.ysn-activity-axis { fill: var(--text-muted); font-family: var(--font-mono); font-size: 8px; }
.ysn-activity-area { fill: url(#ysnActivityFill); }
.ysn-activity-line { fill: none; stroke: var(--primary-light); stroke-width: 2.25; stroke-linecap: round; stroke-linejoin: round; filter: drop-shadow(0 0 4px rgba(143, 91, 255, .4)); }
.ysn-activity-point { fill: var(--primary-light); filter: drop-shadow(0 0 4px rgba(143, 91, 255, .6)); }
.ysn-activity-event line { stroke: var(--primary-light); stroke-width: 1; stroke-dasharray: 2 2; }
.ysn-activity-event rect { fill: var(--dark); stroke: var(--primary-light); stroke-width: 1; }
.ysn-activity-event text { fill: var(--text); font-family: var(--font-mono); font-size: 8px; font-weight: 800; }

.ysn-activity-collecting {
    position: absolute;
    right: 1.5rem;
    bottom: .75rem;
    color: var(--text-muted);
    font-size: .49rem;
}

.ysn-activity-loading,
.ysn-activity-unavailable {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .75rem;
    min-height: 12rem;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: .68rem;
    letter-spacing: .06em;
}

.ysn-activity-loading .loading-spinner { width: 1.5rem; height: 1.5rem; }
.ysn-activity-panel.is-unavailable { display: block; min-height: 10rem; }
.ysn-activity-unavailable { flex-direction: column; min-height: 10rem; }
.ysn-activity-unavailable p { margin: 0; }

@media (max-width: 680px) {
    .ysn-activity-panel { grid-template-columns: 1fr; }
    .ysn-activity-metrics {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        gap: .75rem 1rem;
        padding: 1.1rem;
        border-right: 0;
        border-bottom: 1px solid var(--border);
    }
    .ysn-activity-status { align-self: start; margin-top: .25rem; }
    .ysn-activity-status span { display: none; }
    .ysn-activity-stats { grid-column: 1 / -1; grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .ysn-activity-stats > div,
    .ysn-activity-stats > div:nth-child(even) { padding: .58rem .45rem; border-left: 1px solid var(--divider); }
    .ysn-activity-stats > div:first-child { border-left: 0; padding-left: 0; }
    .ysn-activity-address { grid-column: 1 / -1; }
    .ysn-activity-chart { padding: .9rem .55rem .65rem .2rem; }
    .ysn-activity-svg { height: 11rem; }
    .ysn-activity-axis { font-size: 12px; }
    .ysn-activity-x-tick.is-minor { display: none; }
}

@media (max-width: 440px) {
    .ysn-activity-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ysn-activity-stats > div:nth-child(3) { border-left: 0; }
    .ysn-activity-chart-head { padding-left: 2.4rem; }
    .ysn-activity-chart-head span:last-child { display: none; }
    .ysn-activity-collecting { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .ysn-activity-line { filter: none; }
}
