/* ===== css/visual.css — visual design features (group 'visual') =====
   Every rule is scoped under html.f-<id>; anything that moves is also gated by html.cx-motion.
   Colours derive from core's --accent (style.css), so f-theme-presets-seasonal recolours everything
   here; each derived token starts as a plain colour for engines without color-mix().
   Glass surfaces turn solid (no backdrop blur) on the lite tier (html.lite), with
   prefers-reduced-transparency, and where backdrop-filter is missing. */

/* ===== Shared tokens (exist only while a visual feature is on) ===== */
/* Plain values = the token values at the default electric blue (#0033ff), measured in Chrome. */
html:is(.f-v-liquid-glass-card, .f-v-night-window-banner, .f-v-sky-grade, .f-v-display-typeface,
        .f-v-avatar-ring-decoration, .f-v-badge-row, .f-v-brand-hover-socials, .f-v-vinyl-player,
        .f-v-glass-stat-chips, .f-v-glass-dock-controls, .f-v-grain-texture) {
    --vx-night: #030c29;                            /* page night, ~#020b26 */
    --vx-deep: #02061c;                             /* deep card shadow */
    --vx-accent-400: #3e78ff;                       /* rings, glows */
    --vx-accent-300: #89b2ff;                       /* accent text on dark */
    --vx-ice: #caddff;                              /* sparkle / highlight */
    --vx-text: #f1f7ff;
    --vx-text-soft: rgba(241, 247, 255, 0.9);
    --vx-text-dim: #b3bcd0;
    --vx-violet: #8658e1;                           /* the lightning in the illustration */
    --vx-glass: rgba(3, 12, 41, 0.58);
    --vx-glass-strong: rgba(3, 12, 41, 0.82);
    --vx-glass-solid: rgb(3, 12, 41);               /* a panel with no blur behind it (lite tier): solid, no page text shows through */
    --vx-glass-chip: rgba(3, 12, 41, 0.55);
    --vx-glass-soft: rgba(3, 12, 41, 0.4);
    --vx-stroke: rgba(255, 255, 255, 0.14);
    --vx-hairline: rgba(62, 120, 255, 0.7);
    --vx-glow: rgba(62, 120, 255, 0.6);
    --vx-ice-glow: rgba(202, 221, 255, 0.7);
    --vx-ring-glow: rgba(0, 51, 255, 0.7);
    --vx-aurora-blue: rgba(0, 51, 255, 0.75);
    --vx-aurora-violet: rgba(134, 88, 225, 0.55);
    --vx-sky-top: rgba(0, 51, 255, 0.38);
    --vx-sky-mid: rgba(0, 51, 255, 0.16);
    --vx-sky-low: rgba(3, 12, 41, 0.6);
    --vx-vignette: rgba(0, 1, 15, 0.7);
    --vx-halo: rgba(0, 51, 255, 0.42);
    --vx-radius: 24px;
    --vx-blur: 10px;                                /* phones; 16px from 621px */
}

@media (min-width: 621px) {
    html:is(.f-v-liquid-glass-card, .f-v-vinyl-player) {
        --vx-blur: 16px;
    }
}

@supports (color: color-mix(in oklch, red, blue)) {
    html:is(.f-v-liquid-glass-card, .f-v-night-window-banner, .f-v-sky-grade, .f-v-display-typeface,
            .f-v-avatar-ring-decoration, .f-v-badge-row, .f-v-brand-hover-socials, .f-v-vinyl-player,
            .f-v-glass-stat-chips, .f-v-glass-dock-controls, .f-v-grain-texture) {
        --vx-night: color-mix(in oklch, var(--accent, #0033ff) 21%, #020202);
        --vx-deep: color-mix(in oklch, var(--vx-night) 80%, black);
        --vx-accent-400: color-mix(in oklch, var(--accent, #0033ff) 75%, white);
        --vx-accent-300: color-mix(in oklch, var(--accent, #0033ff) 45%, white);
        --vx-ice: color-mix(in oklch, var(--accent, #0033ff) 20%, white);
        --vx-text: color-mix(in oklch, var(--accent, #0033ff) 5%, white);
        --vx-text-soft: color-mix(in oklch, var(--vx-text) 90%, transparent);
        --vx-text-dim: color-mix(in oklch, var(--accent, #0033ff) 10%, #c7c7c7);
        --vx-violet: oklch(58% 0.2 295);
        --vx-glass: color-mix(in oklch, var(--vx-night) 58%, transparent);
        --vx-glass-strong: color-mix(in oklch, var(--vx-night) 82%, transparent);
        --vx-glass-solid: var(--vx-night);
        --vx-glass-chip: color-mix(in oklch, var(--vx-night) 55%, transparent);
        --vx-glass-soft: color-mix(in oklch, var(--vx-night) 40%, transparent);
        --vx-hairline: color-mix(in oklch, var(--vx-accent-400) 70%, transparent);
        --vx-glow: color-mix(in oklch, var(--vx-accent-400) 60%, transparent);
        --vx-ice-glow: color-mix(in oklch, var(--vx-ice) 70%, transparent);
        --vx-ring-glow: color-mix(in oklch, var(--accent, #0033ff) 70%, transparent);
        --vx-aurora-blue: color-mix(in oklch, var(--accent, #0033ff) 75%, transparent);
        --vx-aurora-violet: color-mix(in oklch, var(--vx-violet) 55%, transparent);
        --vx-sky-top: color-mix(in oklch, var(--accent, #0033ff) 38%, transparent);
        --vx-sky-mid: color-mix(in oklch, var(--accent, #0033ff) 16%, transparent);
        --vx-sky-low: color-mix(in oklch, var(--vx-night) 60%, transparent);
        --vx-vignette: color-mix(in oklch, color-mix(in oklch, var(--accent, #0033ff) 17%, black) 70%, transparent);
        --vx-halo: color-mix(in oklch, var(--accent, #0033ff) 42%, transparent);
    }
}

html.f-v-glass-stat-chips .vx-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ===== 1. v-liquid-glass-card ===== */
html.f-v-liquid-glass-card .profile-card {
    border-radius: var(--vx-radius);
    background: var(--vx-glass);
    -webkit-backdrop-filter: blur(var(--vx-blur)) saturate(140%);
    backdrop-filter: blur(var(--vx-blur)) saturate(140%);
    box-shadow:
        inset 0 1px 0 rgb(255 255 255 / 0.22),
        0 30px 60px -20px var(--vx-deep);
}

/* 1px gradient hairline: bright top-left fading to accent bottom-right (masked ring, static) */
html.f-v-liquid-glass-card .profile-card::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 3000;
    padding: 1px;
    border-radius: inherit;
    background: linear-gradient(160deg, rgb(255 255 255 / 0.5), rgb(255 255 255 / 0.06) 35%, var(--vx-hairline));
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
}

html.f-v-liquid-glass-card .banner-section,
html.f-v-liquid-glass-card .banner-gradient {
    border-radius: var(--vx-radius) var(--vx-radius) 0 0;
}

html.f-v-liquid-glass-card .profile-content {
    background: none;
    border-radius: 0 0 var(--vx-radius) var(--vx-radius);
}

/* three heavy navy lines become two quiet hairlines */
html.f-v-liquid-glass-card .divider-line {
    width: 72%;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgb(255 255 255 / 0.2), transparent);
    box-shadow: none;
}

html.f-v-liquid-glass-card .profile-content > .divider-line:first-child {
    display: none;
}

/* the card-tilt glare (motion module) follows the 24 px glass radius */
html.f-v-liquid-glass-card.f-m-card-tilt-glare .profile-card > .mx-glare {
    border-radius: inherit;
}

/* lite tier, reduced transparency, no backdrop-filter: a solid, darker glass */
html.lite.f-v-liquid-glass-card .profile-card {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: var(--vx-glass-strong);
}

@media (prefers-reduced-transparency: reduce) {
    html.f-v-liquid-glass-card .profile-card {
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        background: var(--vx-glass-strong);
    }
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    html.f-v-liquid-glass-card .profile-card {
        background: var(--vx-glass-strong);
    }
}

/* ===== 2. v-night-window-banner ===== */
html.f-v-night-window-banner .banner-section {
    background: transparent;
}

html.f-v-night-window-banner .banner-img {
    display: none;
}

/* The sky: a dedicated 3:1 crop of the starry part of the background (never the full image a second
   time), picked by screen density, with the concept's saturate(1.25) brightness(1.15) grade baked in.
   A pseudo-element, so it starts loading with the first paint, before any JS.
   Fallback order: plain WebP, then density-only image-set, then AVIF/WebP by type. */
html.f-v-night-window-banner .banner-section::before {
    content: '';
    position: absolute;
    inset: 0;
    background: url('/assets/img/banner-sky-800.webp') center / cover no-repeat;
    background-image: -webkit-image-set(
        url('/assets/img/banner-sky-800.webp') 1x,
        url('/assets/img/banner-sky-1600.webp') 2x);
    background-image: image-set(
        url('/assets/img/banner-sky-800.avif') type('image/avif') 1x,
        url('/assets/img/banner-sky-1600.avif') type('image/avif') 2x,
        url('/assets/img/banner-sky-800.webp') type('image/webp') 1x,
        url('/assets/img/banner-sky-1600.webp') type('image/webp') 2x);
    -webkit-mask-image: linear-gradient(#000 55%, transparent);
    mask-image: linear-gradient(#000 55%, transparent);
    pointer-events: none;
}

/* the aurora reuses the replica's gradient layer: electric blue top-left, lightning violet top-right
   (same grade as the sky: a static layer, rasterised once) */
html.f-v-night-window-banner .banner-gradient {
    background:
        radial-gradient(70% 130% at 10% 0%, var(--vx-aurora-blue), transparent 70%),
        radial-gradient(50% 110% at 95% 10%, var(--vx-aurora-violet), transparent 70%);
    filter: saturate(1.25) brightness(1.15);
    -webkit-mask-image: linear-gradient(#000 55%, transparent);
    mask-image: linear-gradient(#000 55%, transparent);
    pointer-events: none;
}

/* The motto as live text (lang="tr"): crisp at any density, read by screen readers. Centred in the banner;
   when the chips along the top edge reach down into it, visual.js narrows the box to the free band
   (--vx-motto-top / --vx-motto-bottom), shrinks the type a little if needed, or fades it out (.is-hidden). */
html.f-v-night-window-banner .vx-motto {
    position: absolute;
    inset: var(--vx-motto-top, 0px) 0 var(--vx-motto-bottom, 0px);
    z-index: 13;
    display: grid;
    place-items: center;
    margin: 0;
    padding: 0 16px;
    font: 300 var(--vx-motto-size, clamp(18px, 5.6vw, 32px))/1.15 'Unbounded', 'Inter', sans-serif;
    letter-spacing: 0.04em;
    text-align: center;
    text-wrap: balance;
    color: var(--vx-text);
    text-shadow: 0 0 2px rgb(0 0 0 / 0.8), 0 2px 12px rgb(0 0 0 / 0.6), 0 0 18px var(--vx-ice-glow);
    pointer-events: none;
    transition: opacity 0.2s ease;
}

html.f-v-night-window-banner .vx-motto-text {
    display: block;
}

html.f-v-night-window-banner .vx-motto.is-hidden {
    opacity: 0;
}

/* ===== 3. v-sky-grade ===== */
/* (the sparkles' ice tint belongs in the krist.mp4 encode, baked once — never a live multiply layer
   over the playing video, which would cost a full-screen blend on every frame) */
html.f-v-sky-grade body {
    background: var(--vx-night);
}

html.f-v-sky-grade .bg-overlay {
    background:
        radial-gradient(110% 75% at 50% 40%, transparent 35%, var(--vx-vignette) 100%),
        linear-gradient(180deg, var(--vx-sky-top), var(--vx-sky-mid) 60%, var(--vx-sky-low));
}

/* ===== 4. v-display-typeface ===== */
html.f-v-display-typeface .display-name {
    font: 600 clamp(21px, 6vw, 28px)/1.1 'Unbounded', 'Inter', sans-serif;
    letter-spacing: -0.01em;
    color: var(--vx-text);
    text-shadow: 0 0 24px var(--vx-glow);
}

html.f-v-display-typeface .username {
    margin-top: 6px;
    font: 500 13px/1.2 'Geist Mono', ui-monospace, monospace;
    letter-spacing: 0.02em;
    color: var(--vx-text-dim);
    text-shadow: none;
}

html.f-v-display-typeface .bio-text {
    color: var(--vx-text-soft);
    text-shadow: none;
    text-wrap: balance;
}

html.f-v-display-typeface :where(.stat-item > span) {
    font: 500 12px/1 'Geist Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
}

html.f-v-display-typeface .time {
    font: 500 11px/1 'Geist Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
}

/* ===== 5. v-avatar-ring-decoration ===== */
/* 3 px conic ring + 3 px night gap. The ring is a disc behind the photo that the compositor turns
   (rotate), so it never repaints; it turns only while the music plays and rests where it stopped. */
html.f-v-avatar-ring-decoration .avatar-container {
    position: relative;
    isolation: isolate;
    padding: 3px;
    border: 0;
    overflow: visible;
    box-shadow: 0 0 28px var(--vx-ring-glow);
}

html.f-v-avatar-ring-decoration .avatar-container::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: 50%;
    background: conic-gradient(var(--accent, #0033ff), var(--vx-ice), var(--vx-accent-400), var(--vx-violet), var(--accent, #0033ff));
    pointer-events: none;
}

@keyframes vx-ring-spin {
    to { rotate: 1turn; }
}

html.cx-motion.f-v-avatar-ring-decoration .avatar-container::before {
    animation: vx-ring-spin 8s linear infinite paused;
}

html.cx-motion.cx-playing.f-v-avatar-ring-decoration .avatar-container::before {
    animation-play-state: running;
}

html.f-v-avatar-ring-decoration .avatar-img {
    border: 3px solid var(--vx-night);
    border-radius: 50%;
}

/* Discord-style avatar decoration: four crisp pixel '+' sparkles (the krist.mp4 grammar), static */
html.f-v-avatar-ring-decoration .vx-avatar-sparkles {
    position: absolute;
    inset: -16%;
    z-index: 1;
    background: var(--vx-ice);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' shape-rendering='crispEdges'%3E%3Cpath d='M85 4h3v4h4v3h-4v4h-3v-4h-4V8h4z'/%3E%3Cpath d='M9 78h2v3h3v2h-3v3H9v-3H6v-2h3z'/%3E%3Cpath d='M93 70h2v2h2v2h-2v2h-2v-2h-2v-2h2z'/%3E%3Cpath d='M14 10h2v2h2v2h-2v2h-2v-2h-2v-2h2z'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' shape-rendering='crispEdges'%3E%3Cpath d='M85 4h3v4h4v3h-4v4h-3v-4h-4V8h4z'/%3E%3Cpath d='M9 78h2v3h3v2h-3v3H9v-3H6v-2h3z'/%3E%3Cpath d='M93 70h2v2h2v2h-2v2h-2v-2h-2v-2h2z'/%3E%3Cpath d='M14 10h2v2h2v2h-2v2h-2v-2h-2v-2h2z'/%3E%3C/svg%3E") center / contain no-repeat;
    pointer-events: none;
}

/* ===== 6. v-badge-row ===== */
html.f-v-badge-row .name-section {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 6px 10px;
}

/* name, badges and @username each get their own centred line: the badge pill sits under the name */
html.f-v-badge-row .name-section .display-name {
    flex-basis: 100%;
    text-align: center;
}

html.f-v-badge-row .name-section .username {
    flex-basis: 100%;
    margin-top: 0;
}

/* flex: none on the pill and every badge: the row never shrinks */
html.f-v-badge-row .vx-badges {
    display: inline-flex;
    flex: none;
    align-items: center;
    gap: 1px;
    margin: 0;
    padding: 3px 4px;
    list-style: none;
    border-radius: 999px;
    background: var(--vx-glass-chip);
    border: 1px solid var(--vx-stroke);
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.08);
}

html.f-v-badge-row .vx-badges > li {
    display: flex;
    flex: none;
}

html.f-v-badge-row .vx-badge {
    --badge: var(--vx-accent-300);
    position: relative;
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-width: 23px;
    height: 23px;
    padding: 0 2px;
    margin: 0;
    border: 0;
    border-radius: 999px;
    background: none;
    color: var(--vx-text);
    font: inherit;
    line-height: 1;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: color 0.15s ease;
}

html.f-v-badge-row .vx-badge[data-badge="business"] { --badge: #fec84b; }
html.f-v-badge-row .vx-badge[data-badge="creator"] { --badge: #25f4ee; }
html.f-v-badge-row .vx-badge[data-badge="azpx"] { --badge: #ffc300; }

html.f-v-badge-row .vx-badge > svg {
    display: block;
    flex: none;
    width: 15px;
    height: 15px;
    transition: filter 0.15s ease;
}

html.f-v-badge-row .vx-badge .vx-cut {
    fill: none;
    stroke: var(--vx-night);
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* AZPX: a Discord-style server tag in AzPixel's own colours (#ffc300 on #0083ff) */
html.f-v-badge-row .vx-badge.vx-tag {
    gap: 3px;
    height: 19px;
    margin: 0 2px;
    padding: 0 5px 0 4px;
    border-radius: 6px;
    font: 700 10px/1 'Inter', sans-serif;
    letter-spacing: 0.05em;
    color: #ffc300;
    background: rgba(0, 131, 255, 0.38);
    box-shadow: inset 0 0 0 1px rgba(0, 131, 255, 0.45);
}

/* about 25 px of hit area around the 19 px tag */
html.f-v-badge-row .vx-badge.vx-tag::before {
    content: '';
    position: absolute;
    inset: -3px -2px;
}

html.f-v-badge-row .vx-badge.vx-tag > svg {
    width: 11px;
    height: 11px;
}

@media (max-width: 400px) {
    html.f-v-badge-row .name-section {
        column-gap: 8px;
    }
}

html.f-v-badge-row .vx-badge:is(:focus-visible, .is-open) {
    color: var(--badge);
}

html.f-v-badge-row .vx-badge:is(:focus-visible, .is-open) > svg {
    filter: drop-shadow(0 0 6px var(--badge));
}

html.f-v-badge-row .vx-badge:focus-visible {
    outline: 2px solid var(--vx-accent-300);
    outline-offset: 2px;
}

@media (hover: hover) {
    html.f-v-badge-row .vx-badge:hover {
        color: var(--badge);
    }

    html.f-v-badge-row .vx-badge:hover > svg {
        filter: drop-shadow(0 0 6px var(--badge));
    }
}

/* Tooltip: mouse hover, keyboard focus and tap (.is-open, set by visual.js). It opens below the badge:
   above it would slide under the avatar (z 2000). Solid glass: nothing blurs inside the glass card. */
html.f-v-badge-row .vx-tip {
    position: absolute;
    left: 50%;
    top: calc(100% + 9px);
    z-index: 30;
    padding: 6px 9px;
    border-radius: 9px;
    font: 500 11.5px/1.2 'Inter', sans-serif;
    letter-spacing: 0;
    white-space: nowrap;
    color: var(--vx-text);
    background: var(--vx-glass-strong);
    border: 1px solid var(--vx-stroke);
    box-shadow: 0 10px 24px rgb(0 0 0 / 0.4);
    /* hidden with display: none (not visibility), so a closed tooltip never widens a scrollable page */
    display: none;
    translate: calc(-50% + var(--vx-tip-dx, 0px)) -4px;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease, translate 0.15s ease, display 0.15s allow-discrete;
}

html.f-v-badge-row .vx-badge:is(:focus-visible, .is-open) .vx-tip {
    display: block;
    translate: calc(-50% + var(--vx-tip-dx, 0px)) 0;
    opacity: 1;
}

@starting-style {
    html.f-v-badge-row .vx-badge:is(:focus-visible, .is-open) .vx-tip {
        translate: calc(-50% + var(--vx-tip-dx, 0px)) -4px;
        opacity: 0;
    }
}

@media (hover: hover) {
    html.f-v-badge-row .vx-badge:hover .vx-tip {
        display: block;
        translate: calc(-50% + var(--vx-tip-dx, 0px)) 0;
        opacity: 1;
    }

    @starting-style {
        html.f-v-badge-row .vx-badge:hover .vx-tip {
            translate: calc(-50% + var(--vx-tip-dx, 0px)) -4px;
            opacity: 0;
        }
    }
}

html.cx-reduced.f-v-badge-row .vx-tip {
    translate: calc(-50% + var(--vx-tip-dx, 0px)) 0;
    transition: opacity 0.15s ease, display 0.15s allow-discrete;
}

/* Escape pressed: every tooltip stays closed until focus or the pointer moves (visual.js) */
html.f-v-badge-row .vx-badges.is-quiet .vx-badge .vx-tip {
    display: none;
}

/* ===== 7. v-brand-hover-socials ===== */
/* The link itself never gets a transform or filter (anchor-positioned tooltips rely on that):
   the lift and the TikTok split live on the icon. */
html.f-v-brand-hover-socials .social-links {
    gap: 8px;
}

html.f-v-brand-hover-socials .social-link {
    --vx-brand: #ffffff;
    width: clamp(40px, 11.5vw, 46px);
    height: clamp(40px, 11.5vw, 46px);
    border-radius: 14px;
    background: var(--vx-glass-soft);
    border: 1px solid var(--vx-stroke);
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.1);
    filter: none;
    -webkit-tap-highlight-color: transparent;
    transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

html.f-v-brand-hover-socials .social-link .icon {
    width: 20px;
    height: 20px;
    filter: none;
}

/* the 2 px lift (m-social-icon-feel, when on, moves the icon itself) */
html.cx-motion.f-v-brand-hover-socials:not(.f-m-social-icon-feel) .social-link .icon {
    transition: transform 0.2s ease, translate 0.2s ease;
}

html.f-v-brand-hover-socials .social-link[data-brand="discord"] { --vx-brand: #5865f2; }
html.f-v-brand-hover-socials .social-link[data-brand="telegram"] { --vx-brand: #26a5e4; }
html.f-v-brand-hover-socials .social-link[data-brand="tiktok"] { --vx-brand: #25f4ee; }
html.f-v-brand-hover-socials .social-link[data-brand="youtube"] { --vx-brand: #ff0000; }
html.f-v-brand-hover-socials .social-link[data-brand="instagram"] { --vx-brand: #ff0069; }
html.f-v-brand-hover-socials .social-link[data-brand="threads"] { --vx-brand: #ffffff; }

/* brand washes need color-mix(); older engines keep the quiet glass chips */
@supports (color: color-mix(in oklch, red, blue)) {
    html.f-v-brand-hover-socials .social-link:is(:focus-visible, :active) {
        background: color-mix(in oklch, var(--vx-brand) 24%, transparent);
        border-color: color-mix(in oklch, var(--vx-brand) 70%, transparent);
        box-shadow: 0 0 22px color-mix(in oklch, var(--vx-brand) 45%, transparent), inset 0 1px 0 rgb(255 255 255 / 0.2);
    }

    html.f-v-brand-hover-socials .social-link:focus-visible {
        outline: 2px solid color-mix(in oklch, var(--vx-brand) 75%, white);
        outline-offset: 3px;
    }

    @media (hover: hover) {
        html.f-v-brand-hover-socials .social-link:hover {
            background: color-mix(in oklch, var(--vx-brand) 24%, transparent);
            border-color: color-mix(in oklch, var(--vx-brand) 70%, transparent);
            box-shadow: 0 0 22px color-mix(in oklch, var(--vx-brand) 45%, transparent), inset 0 1px 0 rgb(255 255 255 / 0.2);
        }
    }

    /* touch screens have no hover: a thin brand border at rest */
    @media (hover: none) {
        html.f-v-brand-hover-socials .social-link {
            border-color: color-mix(in oklch, var(--vx-brand) 42%, transparent);
        }
    }
}

html.f-v-brand-hover-socials .social-link[data-brand="tiktok"]:is(:focus-visible, :active) .icon {
    filter: drop-shadow(-1.5px -1px 0 #25f4ee) drop-shadow(1.5px 1px 0 #fe2c55);
}

/* Threads keeps the same soft white wash as the business chip (no solid white fill) */

@media (hover: hover) {
    html.f-v-brand-hover-socials .social-link[data-brand="tiktok"]:hover .icon {
        filter: drop-shadow(-1.5px -1px 0 #25f4ee) drop-shadow(1.5px 1px 0 #fe2c55);
    }

    html.cx-motion.f-v-brand-hover-socials:not(.f-m-social-icon-feel) .social-link:hover .icon {
        translate: 0 -2px;
    }
}

html.cx-motion.f-v-brand-hover-socials:not(.f-m-social-icon-feel) .social-link:focus-visible .icon {
    translate: 0 -2px;
}

html.f-v-brand-hover-socials .social-link .tooltip {
    top: -38px;
    padding: 5px 9px;
    border-radius: 8px;
    font-weight: 500;
    background: var(--vx-glass-strong);
    border: 1px solid var(--vx-stroke);
}

/* with m-social-icon-feel the links become 52 px magnets with -8 px margins: the chips keep their own
   size and spacing (the magnet, halo and ripple still work inside them) */
html.f-v-brand-hover-socials.f-m-social-icon-feel .social-link {
    width: clamp(40px, 11.5vw, 46px);
    height: clamp(40px, 11.5vw, 46px);
    margin: 0;
}

html.f-v-brand-hover-socials.f-m-social-icon-feel .social-link .tooltip {
    top: -38px;
}

html.f-v-brand-hover-socials.f-m-social-icon-feel .social-link .mx-halo {
    border-radius: inherit;
}

/* ===== 8. v-vinyl-player ===== */
html.f-v-vinyl-player .music-player {
    --vx-disc: 52px;
}

/* the player wears the card's glass (same blur, same lite / reduced-transparency fallbacks) */
html.f-v-vinyl-player .player-inner {
    position: relative;
    border-radius: var(--vx-radius);
    background: var(--vx-glass);
    -webkit-backdrop-filter: blur(var(--vx-blur)) saturate(140%);
    backdrop-filter: blur(var(--vx-blur)) saturate(140%);
    border: 1px solid var(--vx-stroke);
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.16), 0 20px 40px -24px var(--vx-deep);
}

html.lite.f-v-vinyl-player .player-inner {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: var(--vx-glass-strong);
}

@media (prefers-reduced-transparency: reduce) {
    html.f-v-vinyl-player .player-inner {
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        background: var(--vx-glass-strong);
    }
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    html.f-v-vinyl-player .player-inner {
        background: var(--vx-glass-strong);
    }
}

html.f-v-vinyl-player .player-content {
    position: relative;
    z-index: 2;
}

/* the disc (grooves + a fixed sheen) sits behind the cover; the cover itself is the label */
html.f-v-vinyl-player .vx-disc {
    position: absolute;
    left: 0;
    top: 50%;
    z-index: 0;
    width: var(--vx-disc);
    height: var(--vx-disc);
    margin-top: calc(var(--vx-disc) / -2);
    border-radius: 50%;
    background:
        conic-gradient(from 25deg, transparent 0 7%, rgb(255 255 255 / 0.1) 12%, transparent 18% 50%, rgb(255 255 255 / 0.07) 62%, transparent 68%),
        repeating-radial-gradient(circle, #0b0e17 0 1px, #1a1f2e 1px 3px);
    box-shadow: 0 0 0 1px rgb(255 255 255 / 0.08), 0 6px 18px rgb(0 0 0 / 0.5);
    pointer-events: none;
}

html.f-v-vinyl-player .album-cover {
    position: relative;
    z-index: 1;
    flex: none;
    width: calc(var(--vx-disc) / 2);
    height: calc(var(--vx-disc) / 2);
    margin: calc(var(--vx-disc) / 4);
    border-radius: 50%;
    box-shadow: 0 0 0 2px var(--vx-accent-400);
}

html.f-v-vinyl-player .vx-spindle {
    position: absolute;
    left: calc(var(--vx-disc) / 2 - 2.5px);
    top: calc(50% - 2.5px);
    z-index: 3;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--vx-night);
    box-shadow: 0 0 0 1px rgb(255 255 255 / 0.12);
    pointer-events: none;
}

/* m-play-state-vinyl owns the rotation and cuts its own centre hole */
html.f-v-vinyl-player.f-m-play-state-vinyl .vx-spindle {
    display: none;
}

@keyframes vx-vinyl-spin {
    to { rotate: 360deg; }
}

html.cx-motion.f-v-vinyl-player:not(.f-m-play-state-vinyl) .album-cover {
    animation: vx-vinyl-spin 4s linear infinite;
    animation-play-state: paused;
}

html.cx-motion.f-v-vinyl-player:not(.f-m-play-state-vinyl).cx-playing .album-cover {
    animation-play-state: running;
}

html.f-v-vinyl-player .track-title {
    display: none;
}

html.f-v-vinyl-player .vx-meta {
    flex: 1 1 auto;
    min-width: 0;
}

html.f-v-vinyl-player .vx-meta-title {
    margin: 0;
    overflow: hidden;
    font: 600 15px/1.25 'Inter', sans-serif;
    color: var(--vx-text);
    white-space: nowrap;
    text-overflow: ellipsis;
}

html.f-v-vinyl-player .vx-meta-artist {
    margin: 1px 0 0;
    overflow: hidden;
    font: 400 12px/1.25 'Inter', sans-serif;
    color: var(--vx-text-dim);
    white-space: nowrap;
    text-overflow: ellipsis;
}

html.f-v-vinyl-player .vx-meta-artist[hidden] {
    display: none;
}

/* prev / next keep their 24 px look but get a 40 px hit area (44 px on touch screens: style.css) */
html.f-v-vinyl-player .control-btn {
    position: relative;
}

html.f-v-vinyl-player .control-btn:not(.play)::before {
    content: '';
    position: absolute;
    inset: -8px;
}

/* one clear primary button; its glow lights only while the music plays */
html.f-v-vinyl-player .control-btn.play {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--vx-text);
    transition: box-shadow 0.3s ease;
}

html.f-v-vinyl-player.cx-playing .control-btn.play {
    box-shadow: 0 0 18px var(--vx-glow);
}

html.f-v-vinyl-player .control-btn.play :is(path, rect) {
    fill: var(--vx-night);
}

html.f-v-vinyl-player .control-btn:focus-visible {
    outline: 2px solid var(--vx-accent-300);
    outline-offset: 2px;
    border-radius: 50%;
}

html.f-v-vinyl-player .progress-bar {
    height: 4px;
    background: rgb(255 255 255 / 0.12);
}

/* accent → ice fill, no glow (m-progress-scrub owns the bar's motion) */
html.f-v-vinyl-player .progress {
    background: linear-gradient(90deg, var(--accent, #0033ff), var(--vx-accent-400), var(--vx-ice));
}

html.f-v-vinyl-player .progress-handle {
    width: 12px;
    height: 12px;
    box-shadow: 0 0 0 3px var(--vx-halo), 0 0 10px rgb(255 255 255 / 0.35);
}

html.f-v-vinyl-player .time {
    color: var(--vx-text-dim);
}

@media (max-width: 620px) {
    html.f-v-vinyl-player .music-player {
        --vx-disc: 46px;
    }

    html.f-v-vinyl-player .vx-meta-title {
        font-size: 14px;
    }
}

/* ===== 9. v-glass-stat-chips ===== */
/* night tint, hairline and inset highlight; no backdrop blur (the chips sit inside the glass card) */
html.f-v-glass-stat-chips .stats-container {
    gap: 6px;
}

html.f-v-glass-stat-chips .stat-item {
    gap: 6px;
    padding: 4px 10px;
    background: var(--vx-glass-chip);
    border: 1px solid var(--vx-stroke);
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.12);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    color: var(--vx-ice);
}

html.f-v-glass-stat-chips .stat-item :is(svg, .stat-icon) {
    filter: none;
}

html.f-v-glass-stat-chips .stat-item[data-stat="views"] svg path {
    fill: currentColor;
}

html.f-v-glass-stat-chips :where(.stat-item > span) {
    color: var(--vx-text);
    text-shadow: none;
}

/* the fake '# 1' and the always-'0' fire pill go; the view count is shown compact */
html.f-v-glass-stat-chips .stat-item:is([data-stat="hash"], [data-stat="fire"]),
html.f-v-glass-stat-chips #viewCount {
    display: none;
}

html.f-v-glass-stat-chips .vx-loc svg {
    width: 13px;
    height: 13px;
}

/* the Baku clock pill (features module) already says 'Bakı' */
html.f-v-glass-stat-chips.f-f-baku-clock-status .vx-loc {
    display: none;
}

/* m-view-counter-roll owns the number while it is on (its odometer gets the glass chip around it) */
html.f-v-glass-stat-chips.f-m-view-counter-roll .vx-views {
    display: none;
}

/* ===== 10. v-glass-dock-controls ===== */
/* 16 px + the safe area, like the language pill and the palette on the left (20 px + the safe area):
   both groups stay centred on the same line above an iPhone's home indicator */
html.f-v-glass-dock-controls .fixed-controls {
    right: calc(16px + env(safe-area-inset-right, 0px));
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    gap: 2px;
    padding: 4px;
    border-radius: 999px;
}

/* the glass lives on ::before, so the EQ panel inside the dock can still blur the page behind it
   (a backdrop-filter on the dock itself would make it the panel's backdrop root) */
html.f-v-glass-dock-controls .fixed-controls::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: var(--vx-glass);
    -webkit-backdrop-filter: blur(12px) saturate(160%);
    backdrop-filter: blur(12px) saturate(160%);
    border: 1px solid var(--vx-stroke);
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.16), 0 10px 30px rgb(0 0 0 / 0.45);
}

html.f-v-glass-dock-controls .fixed-btn {
    border: 0;
    background: transparent;
    -webkit-tap-highlight-color: transparent;
    transition: background-color 0.2s ease;
}

/* muted is shown by the crossed speaker, not by fading the whole button */
html.f-v-glass-dock-controls #volumeBtn {
    opacity: 1 !important;
}

html.f-v-glass-dock-controls .fixed-btn:focus-visible {
    background: rgb(255 255 255 / 0.1);
    outline: 2px solid var(--vx-accent-300);
    outline-offset: 1px;
}

@media (hover: hover) {
    html.f-v-glass-dock-controls .fixed-btn:hover {
        background: rgb(255 255 255 / 0.1);
    }
}

/* open mixer: a soft wash on its button (aria-expanded, the .active fallback or the native popover) */
html.f-v-glass-dock-controls .fixed-controls :is(#mixerBtn[aria-expanded="true"],
        .mixer-wrapper:has(.equalizer-panel.active) #mixerBtn,
        .mixer-wrapper:has(.equalizer-panel:popover-open) #mixerBtn) {
    background: rgb(255 255 255 / 0.14);
    border-color: transparent;
}

html.f-v-glass-dock-controls #volumeBtn .volume-icon,
html.f-v-glass-dock-controls #mixerBtn .mixer-icon {
    display: none;
}

html.f-v-glass-dock-controls .vx-vol {
    display: grid;
    width: 20px;
    height: 20px;
    color: #fff;
}

html.f-v-glass-dock-controls .vx-vol svg {
    grid-area: 1 / 1;
    width: 20px;
    height: 20px;
}

html.f-v-glass-dock-controls .vx-vol .vx-vol-off,
html.f-v-glass-dock-controls .vx-vol[data-muted="true"] .vx-vol-on {
    display: none;
}

html.f-v-glass-dock-controls .vx-vol[data-muted="true"] .vx-vol-off {
    display: block;
    opacity: 0.6;
}

/* the sliders glyph replaces the hamburger lines */
html.f-v-glass-dock-controls .vx-mix {
    display: block;
    width: 20px;
    height: 20px;
    color: #fff;
}

/* in-place panel (no native popover): aligned with the capsule's edge, just above it */
html.f-v-glass-dock-controls .equalizer-panel:not([popover]) {
    right: -4px;
    bottom: 58px;
}

html.f-v-glass-dock-controls .equalizer-panel {
    background: var(--vx-glass-strong);
    -webkit-backdrop-filter: blur(16px) saturate(160%);
    backdrop-filter: blur(16px) saturate(160%);
    border-color: var(--vx-stroke);
    border-radius: 22px;
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.12), 0 14px 34px rgb(0 0 0 / 0.45);
}

/* the effects (sparkle) column is marked with the pixel '+' (visual.js puts it right after the camera
   icon and marks that one .vx-swapped while the feature is on) */
html.f-v-glass-dock-controls .eq-header .eq-icon.vx-swapped {
    display: none;
}

html.f-v-glass-dock-controls .vx-eq-plus {
    display: block;
    flex: none;
    width: 10px;
    height: 10px;
    color: #fff;
    opacity: 0.9;
}

html.f-v-glass-dock-controls .eq-slider-track {
    width: 8px;
    background: rgb(255 255 255 / 0.12);
}

html.f-v-glass-dock-controls .eq-slider-fill {
    background: linear-gradient(0deg, var(--accent, #0033ff), var(--vx-ice));
}

html.f-v-glass-dock-controls .eq-slider-handle {
    box-shadow: 0 0 0 3px var(--vx-halo), 0 0 12px var(--vx-accent-400);
}

html.lite.f-v-glass-dock-controls .fixed-controls::before,
html.lite.f-v-glass-dock-controls .equalizer-panel {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: var(--vx-glass-strong);
}

/* the open panel sits over the player and the AzPixel card: without blur it needs a nearly solid fill */
html.lite.f-v-glass-dock-controls .equalizer-panel {
    background: var(--vx-glass-solid);
}

@media (prefers-reduced-transparency: reduce) {
    html.f-v-glass-dock-controls .fixed-controls::before,
    html.f-v-glass-dock-controls .equalizer-panel {
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        background: var(--vx-glass-strong);
    }

    html.f-v-glass-dock-controls .equalizer-panel {
        background: var(--vx-glass-solid);
    }
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    html.f-v-glass-dock-controls .fixed-controls::before {
        background: var(--vx-glass-strong);
    }

    html.f-v-glass-dock-controls .equalizer-panel {
        background: var(--vx-glass-solid);
    }
}

/* ===== 11. v-grain-texture ===== */
/* card only, 4 %: a tiny inline feTurbulence tile, rasterised once, never animated, no blend mode */
html.f-v-grain-texture .vx-grain {
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: inherit;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .6 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E") 0 0 / 180px 180px;
    opacity: 0.04;
    pointer-events: none;
}
