/* ==========================================================================
   Discord widget — /assets/discord/discord-widget.css
   Theme via CSS variables. Dark mode applies when an ancestor has .dark
   ========================================================================== */

.discord-widget {
    --dw-bg: #ffffff;
    --dw-border: rgba(114, 114, 114, 0.5);
    --dw-title: #272525;
    --dw-text: #4e5157;
    --dw-accent: #4962e9;
    --dw-accent-hover: #3344a3;
    --dw-online: #22c55e;
    --dw-offline: #9ca3af;
    --dw-skeleton: rgba(0, 0, 0, 0.07);
    --dw-skeleton-shine: rgba(255, 255, 255, 0.7);
    --dw-radius: 12px;

    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    gap: 24px;
    width: 100%;
    max-width: 500px;
    margin: 40px auto;
    padding: 24px;
    background: var(--dw-bg);
    border: 1px solid var(--dw-border);
    border-radius: var(--dw-radius);
    backdrop-filter: blur(15px);
}

.dark .discord-widget {
    --dw-bg: #1b2335;
    --dw-title: #ffffff;
    --dw-text: #9ca3af;
    --dw-skeleton: rgba(255, 255, 255, 0.06);
    --dw-skeleton-shine: rgba(255, 255, 255, 0.09);
}

.discord-widget *,
.discord-widget *::before,
.discord-widget *::after {
    box-sizing: inherit;
}

/* ---- Header ------------------------------------------------------------ */
.dw-header {
    display: flex;
    align-items: center;
    gap: 16px;
    min-width: 0;
}

.dw-icon {
    flex-shrink: 0;
    width: 48px;
    height: 48px;
    overflow: hidden;
    background: var(--dw-skeleton);
    border-radius: var(--dw-radius);
}

.dw-icon img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.dw-icon img[hidden] {
    display: none;
}

.dw-info {
    min-width: 0;
}

/* margin reset: site styles on h2/p used to push things out of alignment */
.dw-name {
    margin: 0 0 4px;
    overflow: hidden;
    color: var(--dw-title);
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.3;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.dw-stats {
    display: flex;
    align-items: center;
    gap: 4px;
    margin: 0;
    color: var(--dw-text);
    font-size: 0.875rem;
    font-variant-numeric: tabular-nums;
}

/* ---- Online dot -------------------------------------------------------- */
.dw-dot {
    position: relative;
    flex-shrink: 0;
    width: 10px;
    height: 10px;
    margin-right: 4px;
    background: var(--dw-online);
    border-radius: 50%;
}

.dw-dot::before {
    content: '';
    position: absolute;
    inset: 0;
    background: inherit;
    border-radius: inherit;
    animation: dw-pulse 1.5s ease-out infinite;
}

@keyframes dw-pulse {
    to { transform: scale(2.2); opacity: 0; }
}

/* ---- Join button ------------------------------------------------------- */
.dw-join {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 16px;
    color: #ffffff;
    font-weight: 500;
    text-decoration: none;
    background: var(--dw-accent);
    border-radius: 8px;
    transition: background-color 0.2s, opacity 0.2s;
}

.dw-join:hover,
.dw-join:focus-visible {
    color: #ffffff !important;
    background: var(--dw-accent-hover);
}

.dw-join:focus-visible {
    outline: 2px solid var(--dw-accent);
    outline-offset: 2px;
}

.dw-join img {
    display: block;
}

/* ---- States ------------------------------------------------------------ */

/* ---- Skeleton (while aria-busy="true") ---------------------------------
   Every block gets the same shimmer: a soft highlight sweeping left → right.
   Real content keeps its space underneath, so nothing jumps when data arrives. */

.discord-widget[aria-busy="true"] :is(.dw-icon, .dw-name, .dw-stats, .dw-join) {
    color: transparent !important;
    background:
        linear-gradient(100deg, transparent 40%, var(--dw-skeleton-shine) 50%, transparent 60%)
        var(--dw-skeleton);
    background-size: 300% 100%;
    animation: dw-shimmer 1.6s ease-in-out infinite;
    pointer-events: none;
    user-select: none;
}

/* hide the real children (dot, text spans, button icon) but keep layout */
.discord-widget[aria-busy="true"] :is(.dw-stats, .dw-join) > * {
    visibility: hidden;
}

/* skeleton shapes */
.discord-widget[aria-busy="true"] .dw-name {
    width: min(200px, 100%);
    height: 1.25rem;
    margin-bottom: 10px;
    border-radius: 6px;
}

.discord-widget[aria-busy="true"] .dw-stats {
    width: 150px;
    height: 0.875rem;
    border-radius: 6px;
}

.discord-widget[aria-busy="true"] .dw-info {
    flex: 1;
}

/* slight stagger so the sweep travels across the card */
.discord-widget[aria-busy="true"] .dw-name  { animation-delay: 0.08s; }
.discord-widget[aria-busy="true"] .dw-stats { animation-delay: 0.16s; }
.discord-widget[aria-busy="true"] .dw-join  { animation-delay: 0.24s; }

@keyframes dw-shimmer {
    from { background-position: 100% 0; }
    to   { background-position: 0 0; }
}

/* button disabled until we have an invite link */
.discord-widget:not(.is-loaded) .dw-join {
    pointer-events: none;
}

.discord-widget:not(.is-loaded):not([aria-busy="true"]) .dw-join {
    opacity: 0.6;
}

/* content fades in when the skeleton goes away */
.discord-widget:not([aria-busy="true"]) :is(.dw-icon img, .dw-name, .dw-stats, .dw-join > *) {
    animation: dw-fade-in 0.35s ease-out both;
}

@keyframes dw-fade-in {
    from { opacity: 0; transform: translateY(2px); }
    to   { opacity: 1; transform: none; }
}

/* Error with no cached data: grey, static dot */
.discord-widget.is-error .dw-dot {
    background: var(--dw-offline);
}

.discord-widget.is-error .dw-dot::before {
    animation: none;
}

@media (prefers-reduced-motion: reduce) {
    .discord-widget *,
    .discord-widget *::before {
        animation: none !important;
        transition: none !important;
    }
}