/* BlackVaultMods — shared visual FX (loaded on every page) */

/* Custom cursor */
body{cursor:url('/assets/Cursor.png') 0 0, auto}

/* Nav links float up on hover */
.bvm-navlinks a{transition:transform .2s ease, text-shadow .2s ease !important;will-change:transform}
.bvm-navlinks a:hover{transform:translateY(-3px)}

/* Logo: slow infinite shine sweep (off-hover). The mask has to sit on a
   STATIONARY element sized/positioned exactly over the V (inset:0) — masking
   a sliding element instead would drag the V-shaped cutout along with the
   slide. The sweep motion comes from animating background-position on a
   background 6x the element's size with a narrow highlight band and
   background-repeat:no-repeat, so a single light streak travels across the
   fixed V-shaped window (peaking mid-cycle, dark the rest of the loop)
   instead of the whole rectangular logo box lighting up. */
.bvm-logo-shine{position:relative}
.bvm-logo-shine::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(105deg,transparent 47%,rgba(255,255,255,.95) 50%,transparent 53%);
  background-size:600% 600%;background-repeat:no-repeat;pointer-events:none;
  animation:bvm-logo-sweep 4.5s ease-in-out infinite;
  -webkit-mask-image:url('/assets/V.png');-webkit-mask-size:contain;-webkit-mask-repeat:no-repeat;-webkit-mask-position:center;
  mask-image:url('/assets/V.png');mask-size:contain;mask-repeat:no-repeat;mask-position:center
}
@keyframes bvm-logo-sweep{0%{background-position:0% 50%}55%{background-position:100% 50%}100%{background-position:100% 50%}}

/* 3D corner sticker for product cards (hot/featured) */
.bvm-sticker{position:absolute;top:-9px;right:-9px;z-index:3;font-size:9px;font-weight:900;letter-spacing:.06em;
  color:#0a0a0a;padding:5px 10px;border-radius:8px;transform:rotate(8deg);
  box-shadow:0 4px 0 rgba(0,0,0,.4), 0 6px 12px rgba(0,0,0,.4)}

/* Announcement ticker (moving bar) */
@keyframes bvm-ticker{from{transform:translateX(0)}to{transform:translateX(-50%)}}
.bvm-ticker-wrap:hover .bvm-ticker-track{animation-play-state:paused}

/* Shop: 3 cols → 2 → 1 */
@media (max-width:820px){.bvm-shop-grid{grid-template-columns:repeat(2,minmax(0,1fr)) !important;gap:28px !important}}
@media (max-width:520px){.bvm-shop-grid{grid-template-columns:1fr !important}}

/* Shop: Bundle cards — sized to match the product grid at every breakpoint above (3 → 2 → 1) */
.bvm-bundle-card{flex:0 1 calc((100% - 180px)/3)}
@media (max-width:820px){.bvm-bundle-grid{gap:28px !important}.bvm-bundle-card{flex:0 1 calc((100% - 28px)/2) !important}}
@media (max-width:520px){.bvm-bundle-card{flex:0 1 100% !important}}

/* Account: Vault grid — 3 cols → 2 → 1 */
@media (max-width:820px){.bvm-vault-grid{grid-template-columns:repeat(2,minmax(0,1fr)) !important}}
@media (max-width:520px){.bvm-vault-grid{grid-template-columns:1fr !important}}

/* Header logo: starts pure white, reveals into its real colors on load.
   brightness(0) invert(1) collapses the image to a solid white silhouette
   (works because the logo has a transparent background), then eases to filter:none. */
@keyframes bvm-logo-reveal{0%{filter:brightness(0) invert(1)}100%{filter:none}}
.bvm-logo-reveal{animation:bvm-logo-reveal 1.6s ease-out forwards}

/* Smooth dark/light theme switch — same timing as the Memberships nav-link
   hover (transition:color .2s), which is the reference this was tuned to
   match. Getting an ACTUAL smooth fill (not a snap) out of a var()-driven
   theme swap needs two separate fixes, confirmed by live testing:

   1) A plain, UNREGISTERED custom property does not carry a smoothly
      animatable computed value across the point where its own value
      changes (e.g. :root vs html[data-theme="black"]) — only registering
      it via @property with a real syntax makes the browser treat that
      value as animatable. Verified live: an unregistered --var flip always
      snapped instantly no matter the transition duration; registering the
      same property via CSS.registerProperty produced a mathematically
      exact mid-transition value. Every solid-color and RGB-triple custom
      property theme-wide is registered below for exactly this reason.

   2) Gradients are the one case @property can't rescue: <image> is a
      legal registration syntax, but two DIFFERENT gradients still don't
      interpolate through a registered custom property (verified live —
      still snapped instantly even registered and even with matching
      angle/stop-count/positions). Browsers only crossfade a background
      gradient when the literal declaration itself changes (e.g. a class/
      attribute selector overriding a base rule), not when a custom
      property feeding that declaration changes. So every themed gradient
      background below is applied directly on a class instead of through
      a custom property, with light/dark as two literal, structurally
      matched (same angle, stop count and positions) declarations. */

@property --bvm-accent-rgb{syntax:'<number>#';inherits:true;initial-value:201,63,208}
@property --bvm-accent{syntax:'<color>';inherits:true;initial-value:#c93fd0}
@property --bvm-accent-light{syntax:'<color>';inherits:true;initial-value:#ff8fe0}
@property --bvm-nav-scrolled-bg{syntax:'<color>';inherits:true;initial-value:rgba(11,7,16,.92)}
@property --bvm-box-shadow-1{syntax:'<color>';inherits:true;initial-value:#c93fd0}
@property --bvm-box-shadow-2{syntax:'<color>';inherits:true;initial-value:rgba(201,63,208,.35)}
@property --bvm-rev-border{syntax:'<color>';inherits:true;initial-value:rgba(201,63,208,.5)}
@property --bvm-rev-hover-border{syntax:'<color>';inherits:true;initial-value:rgba(201,63,208,.85)}
@property --bvm-rev-overlay{syntax:'<color>';inherits:true;initial-value:rgba(201,63,208,.16)}
@property --bvm-icon-fg{syntax:'<color>';inherits:true;initial-value:#ffffff}
@property --bvm-input-bg{syntax:'<color>';inherits:true;initial-value:#150d19}
@property --bvm-input-fg{syntax:'<color>';inherits:true;initial-value:#fff}
@property --bvm-input-border{syntax:'<color>';inherits:true;initial-value:rgba(201,63,208,.25)}
@property --bvm-input-focus{syntax:'<color>';inherits:true;initial-value:#c93fd0}
@property --bvm-featured-badge{syntax:'<color>';inherits:true;initial-value:#ffb3ef}
@property --bvm-featured-cat{syntax:'<color>';inherits:true;initial-value:#c98fd9}
@property --bvm-vault-glow{syntax:'<color>';inherits:true;initial-value:#c93fd0}
@property --bvm-vault-glow-rgb{syntax:'<number>#';inherits:true;initial-value:201,63,208}
@property --bvm-clear-bg{syntax:'<color>';inherits:true;initial-value:rgba(255,255,255,.08)}
@property --bvm-clear-fg{syntax:'<color>';inherits:true;initial-value:#c9c9c9}
@property --bvm-clear-hover-bg{syntax:'<color>';inherits:true;initial-value:rgba(255,255,255,.16)}
@property --bvm-clear-hover-fg{syntax:'<color>';inherits:true;initial-value:#fff}
@property --bvm-seg-border{syntax:'<color>';inherits:true;initial-value:transparent}
@property --bvm-product-border{syntax:'<color>';inherits:true;initial-value:rgba(201,63,208,.4)}
@property --bvm-product-hover-border{syntax:'<color>';inherits:true;initial-value:rgba(201,63,208,.7)}
@property --bvm-buy-fg{syntax:'<color>';inherits:true;initial-value:#fff}
@property --bvm-addcart-fg{syntax:'<color>';inherits:true;initial-value:#fff}
@property --bvm-whiteglove{syntax:'<color>';inherits:true;initial-value:#ff6fd8}
@property --bvm-bar-start{syntax:'<color>';inherits:true;initial-value:#7a2f9e}
@property --bvm-muted-fg{syntax:'<color>';inherits:true;initial-value:#c9a9c4}
@property --bvm-reply-fg{syntax:'<color>';inherits:true;initial-value:#f0d9ec}
@property --bvm-avatar-a{syntax:'<color>';inherits:true;initial-value:#a83fc9}
@property --bvm-avatar-b{syntax:'<color>';inherits:true;initial-value:#7a2f9e}
@property --bvm-tier4-label{syntax:'<color>';inherits:true;initial-value:#d99fe0}

html.bvm-theme-fade,html.bvm-theme-fade *{
  transition:background-color .2s ease,color .2s ease,
    border-color .2s ease,box-shadow .2s ease,fill .2s ease,stroke .2s ease !important
}

/* Themed gradients — crossfade overlay, NOT a background-image transition.
   Verified live, twice: neither a plain background-image transition (even
   with identical angle/stop-count/positions) nor a registered <image>
   custom property actually interpolates two different gradients — real
   Chrome just snaps instantly either way, full stop. The only technique
   that genuinely works: keep the light gradient as the element's own
   background, lay a ::after over it holding the dark gradient at
   opacity:0, and transition OPACITY (which — confirmed live, mathematically
   exact mid-transition values — always interpolates smoothly regardless of
   what images are involved). html[data-theme="black"] just raises that
   opacity to 1. isolation:isolate + the ::after's z-index:-1 guarantees it
   paints below the element's real content without touching that content's
   own stacking — confirmed live with visible text on top. */
#bvm-nav,.bvm-card-el,.bvm-pillar-card,.bvm-icon-circle,.bvm-rev-box{
  position:relative;isolation:isolate
}
#bvm-nav::after,.bvm-card-el::after,.bvm-pillar-card::after,
.bvm-icon-circle::after,.bvm-rev-box::after{
  content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;
  opacity:0;transition:opacity .2s ease;pointer-events:none
}
/* .bvm-icon-circle carries no border of its own, so it's safe to overshoot
   its ::after by 1px past the padding edge — this closes the hairline
   anti-aliasing gap at the rounded edge that let the permanently-purple base
   gradient peek through as a faint pink rim in dark mode (confirmed live: a
   56px icon circle showed exactly this on its curve).
   #bvm-nav/.bvm-card-el/.bvm-pillar-card/.bvm-rev-box keep inset:0 above since
   they have a real visible border that this overshoot would paint over.
   #bvm-enter-vault and .bvm-buy-btn are intentionally excluded from this whole
   crossfade system — they're plain outline buttons with no fill in either
   theme, so they have no need for a per-theme background layer at all. */
.bvm-icon-circle::after{inset:-1px}
html[data-theme="black"] #bvm-nav::after,
html[data-theme="black"] .bvm-card-el::after,html[data-theme="black"] .bvm-pillar-card::after,
html[data-theme="black"] .bvm-icon-circle::after,html[data-theme="black"] .bvm-rev-box::after{opacity:1}

#bvm-nav{background:linear-gradient(180deg, #2e1f3d 0%, #0b0710 55%, #050308 100%)}
#bvm-nav::after{background:linear-gradient(180deg, #1c1c1c 0%, #0b0b0b 55%, #050505 100%)}
html[data-theme="black"] #bvm-nav{background:linear-gradient(180deg, #1c1c1c 0%, #0b0b0b 55%, #050505 100%)}
.bvm-pillar-card{background:linear-gradient(165deg,#1c1420 0%,#150f19 55%,#100b14 100%)}
.bvm-pillar-card::after{background:linear-gradient(165deg,#161616 0%,#0a0a0a 55%,#000 100%)}
.bvm-card-el{background:linear-gradient(165deg,#161616 0%,#0a0a0a 55%,#000 100%)}
.bvm-card-el::after{background:linear-gradient(165deg,#161616 0%,#0a0a0a 55%,#000 100%)}
.bvm-icon-circle{background:linear-gradient(165deg,#3d1450 0%,#7a1f9e 55%,#c93fd0 100%)}
.bvm-icon-circle::after{background:linear-gradient(165deg,#161616 0%,#0a0a0a 55%,#000 100%)}
.bvm-rev-box{background:radial-gradient(120% 100% at 50% 25%,var(--bvm-rev-overlay),transparent 62%),linear-gradient(165deg,#0b0710 0%,#0b0710 55%,#0b0710 100%)}
.bvm-rev-box::after{background:radial-gradient(120% 100% at 50% 25%,var(--bvm-rev-overlay),transparent 62%),linear-gradient(165deg,#161616 0%,#0a0a0a 55%,#000 100%)}
.bvm-buy-btn{background:transparent;border:1px solid var(--bvm-accent) !important;box-shadow:none !important}
.bvm-buy-btn:hover{background:rgba(var(--bvm-accent-rgb),.12)}

@media (prefers-reduced-motion:reduce){
  .bvm-logo-shine::after,.bvm-free-card,.bvm-hero-franklin,.bvm-logo-reveal{animation:none}
  html.bvm-theme-fade,html.bvm-theme-fade *{transition:none !important}
  #bvm-nav::after,.bvm-card-el::after,.bvm-pillar-card::after,
  .bvm-icon-circle::after,.bvm-rev-box::after{transition:none !important}
}

/* Border-draw hover button (shared sitewide). Outline is a traced SVG rect
   (not the element's own border) so it can visibly undraw/redraw via
   stroke-dashoffset on hover, sized to the button's real pixel box in JS
   (setupDrawButtons, added per-page) so its corner radius matches exactly
   with no distortion. Arrow, where present, just nudges right on hover. */
.bvm-draw-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:10px;border:none !important;background:transparent;color:#fff}
.bvm-draw-btn .bvm-draw-outline{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}
.bvm-draw-btn .bvm-draw-outline rect{fill:none;stroke:var(--bvm-accent);stroke-width:1;stroke-dasharray:100 100;stroke-dashoffset:0;transition:stroke-dashoffset .45s cubic-bezier(.22,1,.36,1)}
.bvm-draw-btn.bvm-btn-secondary .bvm-draw-outline rect{stroke:rgba(255,255,255,.6)}
.bvm-draw-btn .bvm-draw-label{position:relative;z-index:1}
.bvm-draw-btn .bvm-draw-arrow{position:relative;z-index:1;flex:none;transform:translateX(0);transition:transform .3s cubic-bezier(.22,1,.36,1)}
.bvm-draw-btn:hover .bvm-draw-arrow{transform:translateX(5px)}
@media (prefers-reduced-motion:reduce){.bvm-draw-btn .bvm-draw-outline rect,.bvm-draw-btn .bvm-draw-arrow{transition:none}}
