/* ─── CSS Custom Properties ──────────────────────────────────────────────────── */
:root {
  --color-bg:        #0a0a0a;
  --color-card:      #111111;
  --color-accent:    #00ff88;
  --color-accent-dk: #00aa55;
  --color-text:      #ffffff;
  --color-subtext:   #888888;
  --color-border:    #1e1e1e;

  /* Border toggle: 0px = off, 1px = on */
  --border-width:    0px;

  /* Card shadow — overridden by JS */
  --card-box-shadow: 0 4px 24px rgba(0, 0, 0, 0.35);

  /* Avatar image shape — completely independent of ring */
  --avatar-size:        100px;
  --avatar-img-shape:   50%;      /* image border-radius only */

  /* Ring — purely decorative, never affects image position */
  --ring-color1:        #00ff88;
  --ring-color2:        #00aa55;
  --ring-thickness:     3px;
  --ring-gap:           3px;
  --ring-shape:         50%;      /* ring border-radius — separate from image */

  --color-icon:         var(--color-accent);

  /* Typography — per element */
  --name-font-family:   var(--font-family);
  --name-font-size:     28px;
  --name-font-weight:   700;
  --name-letter-spacing: -0.03em;
  --name-transform:     none;

  --tag-font-family:    var(--font-family);
  --tag-font-size:      14px;
  --tag-font-weight:    400;
  --tag-letter-spacing: 0.02em;

  --bio-font-family:    var(--font-family);
  --bio-font-size:      13px;
  --bio-font-weight:    400;

  --link-font-family:   var(--font-family);
  --link-font-size:     15px;
  --link-font-weight:   500;
  --link-gap:           12px;

  --max-width:          480px;
  --card-radius:        14px;
  --card-padding:       16px;
  --font-family:        'Space Grotesk', 'Inter', sans-serif;

  /* Gradient background animation speed */
  --gradient-speed:     8s;
}

/* ─── Reset ─────────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { height: 100%; }

body {
  min-height: 100vh;
  font-family: var(--font-family);
  background-color: var(--color-bg);
  color: var(--color-text);
  overflow-x: hidden;
}

/* ─── Background Layers ─────────────────────────────────────────────────────── */
.bg-solid {
  position: fixed;
  top: 0; left: 0;
  width: 100vw; height: 100vh; height: 100dvh;
  background-color: var(--color-bg);
  z-index: 0;
}

.bg-gradient {
  position: fixed;
  top: 0; left: 0;
  width: 100vw; height: 100vh; height: 100dvh;
  z-index: 0;
  /* background-image set by JS — keep size separate so shorthand can't clobber it */
  background-size: 400% 400%;
  opacity: 0;
  transition: opacity 0.6s ease;
}

.bg-gradient.active { opacity: 1; }

/* ── Gradient animation variants ────────────────────────────────────────── */
.bg-gradient.anim-flow     { animation: grad-flow     var(--gradient-speed) ease infinite; }
.bg-gradient.anim-aurora   { animation: grad-aurora   var(--gradient-speed) ease infinite; }
.bg-gradient.anim-pulse    { animation: grad-pulse    var(--gradient-speed) ease infinite; }
.bg-gradient.anim-wave     { animation: grad-wave     var(--gradient-speed) ease infinite; }
.bg-gradient.anim-diagonal { animation: grad-diagonal var(--gradient-speed) ease infinite; }
.bg-gradient.anim-hue      { animation: grad-hue      var(--gradient-speed) linear infinite; }

@keyframes grad-flow {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}
@keyframes grad-aurora {
  0%   { background-position: 0% 0%; }
  25%  { background-position: 100% 0%; }
  50%  { background-position: 100% 100%; }
  75%  { background-position: 0% 100%; }
  100% { background-position: 0% 0%; }
}
@keyframes grad-pulse {
  0%, 100% { background-position: 50% 50%; opacity: 1; }
  50%       { background-position: 50% 50%; opacity: 0.6; }
}
@keyframes grad-wave {
  0%   { background-position: 50% 0%; }
  50%  { background-position: 50% 100%; }
  100% { background-position: 50% 0%; }
}
@keyframes grad-diagonal {
  0%   { background-position: 0% 0%; }
  50%  { background-position: 100% 100%; }
  100% { background-position: 0% 0%; }
}
@keyframes grad-hue {
  0%   { filter: hue-rotate(0deg); }
  100% { filter: hue-rotate(360deg); }
}

.bg-image {
  position: fixed;
  top: 0; left: 0;
  width: 100vw;
  height: 100vh;
  height: 100dvh; /* dynamic viewport — prevents resize on mobile address bar show/hide */
  background-size: cover;
  background-repeat: no-repeat;
  z-index: 0;
  opacity: 0;
  transition: opacity 0.6s ease;
  will-change: transform; /* promotes to its own compositor layer — no repaints on scroll */
}

.bg-image.active { opacity: 1; }

.bg-overlay {
  position: fixed;
  top: 0; left: 0;
  width: 100vw; height: 100vh; height: 100dvh;
  background-color: var(--color-bg);
  z-index: 1;
  pointer-events: none;
}

/* ─── Vanta Background ──────────────────────────────────────────────────────── */
.bg-vanta {
  position: fixed;
  top: 0; left: 0;
  width: 100vw; height: 100vh; height: 100dvh;
  z-index: 0;
  opacity: 0;
  transition: opacity 0.6s ease;
}
.bg-vanta.active { opacity: 1; }

/* ─── Page Wrapper ──────────────────────────────────────────────────────────── */
.page-wrapper {
  position: relative;
  z-index: 10;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  min-height: 100vh;
  padding: 48px 16px 80px;
}

/* ─── Profile Container ─────────────────────────────────────────────────────── */
.profile-container {
  width: 100%;
  max-width: var(--max-width);
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* ─── Avatar ─────────────────────────────────────────────────────────────────── */
.avatar-wrapper {
  position: relative;
  width: var(--avatar-size);
  height: var(--avatar-size);
  margin-bottom: 20px;
  flex-shrink: 0;
}

/*
 * Ring: purely decorative layer, extends OUTSIDE the wrapper via negative inset.
 * Uses the CSS gradient-border mask technique to create a transparent-center ring.
 * It is completely decoupled from the avatar image — image always uses inset:0.
 */
.avatar-ring {
  position: absolute;
  inset: calc(-1 * (var(--ring-gap) + var(--ring-thickness)));
  border-radius: var(--ring-shape);
  padding: var(--ring-thickness);

  /* Default gradient — overridden per effect class */
  background: conic-gradient(
    var(--ring-color1) 0deg,
    var(--ring-color2) 180deg,
    var(--ring-color1) 360deg
  );

  /* Gradient-border technique: punch a transparent hole in the center */
  -webkit-mask:
    linear-gradient(#fff 0 0) content-box,
    linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;

  z-index: 0;
}

/* ── Ring Effect Classes ─────────────────────────────────────────────────────── */
.avatar-ring.effect-none   { opacity: 0; pointer-events: none; }
.avatar-ring.effect-static { /* inherits base conic-gradient — just shown statically */ }

/*
 * Avatar image & fallback: always inset:0, fills wrapper exactly.
 * Shape is --avatar-img-shape — FULLY independent of ring variables.
 */
.avatar-img,
.avatar-fallback {
  position: absolute;
  inset: 0;
  border-radius: var(--avatar-img-shape);
  z-index: 1;
}

.avatar-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.avatar-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--color-card), #1a1a1a);
  font-size: calc(var(--avatar-size) * 0.38);
  font-weight: 700;
  color: var(--color-accent);
  font-family: var(--font-family);
}

/* ─── Profile Text ──────────────────────────────────────────────────────────── */
.profile-name {
  font-family: var(--name-font-family, var(--font-family));
  font-size: var(--name-font-size);
  font-weight: var(--name-font-weight);
  letter-spacing: var(--name-letter-spacing);
  text-transform: var(--name-transform);
  text-align: center;
  margin-bottom: 8px;
  color: var(--color-text);
  line-height: 1.2;
}

/* Name effects */
.profile-name.effect-none {
  background: none;
  -webkit-text-fill-color: var(--color-text);
  filter: none;
  text-shadow: none;
}

.profile-name.effect-gradient {
  background: linear-gradient(135deg, var(--color-text) 30%, var(--color-accent));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.profile-name.effect-glow {
  color: var(--color-text);
  background: none;
  -webkit-text-fill-color: var(--color-text);
  text-shadow: 0 0 20px var(--color-accent), 0 0 60px color-mix(in srgb, var(--color-accent) 40%, transparent);
  filter: none;
}

.profile-name.effect-gradient-glow {
  background: linear-gradient(135deg, var(--color-text) 30%, var(--color-accent));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  filter: drop-shadow(0 0 10px var(--color-accent-dk));
}

.profile-tagline {
  font-family: var(--tag-font-family, var(--font-family));
  font-size: var(--tag-font-size);
  font-weight: var(--tag-font-weight);
  letter-spacing: var(--tag-letter-spacing);
  color: var(--color-subtext);
  text-align: center;
  margin-bottom: 10px;
}

.profile-bio {
  font-family: var(--bio-font-family, var(--font-family));
  font-size: var(--bio-font-size);
  font-weight: var(--bio-font-weight);
  color: var(--color-subtext);
  text-align: center;
  line-height: 1.6;
  max-width: 340px;
  margin-bottom: 28px;
}

/* Hide bio when empty */
.profile-bio:empty { display: none; margin-bottom: 0; }

/* If bio has content, ensure spacing */
.profile-bio:not(:empty) { margin-bottom: 28px; }
/* tagline margin when bio is present vs absent */
.profile-tagline { margin-bottom: 8px; }

/* ─── Links Container ───────────────────────────────────────────────────────── */
.links-container {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--link-gap);
}

/* ─── Link Card ─────────────────────────────────────────────────────────────── */
.link-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: var(--card-padding, 14px) calc(var(--card-padding, 14px) + 4px);
  /* Always use --color-card — glass only adds backdrop filter, not a bg override */
  background: var(--color-card);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--card-radius);
  text-decoration: none;
  color: var(--color-text);
  font-size: var(--link-font-size);
  font-weight: var(--link-font-weight);
  font-family: var(--link-font-family, var(--font-family));
  cursor: pointer;
  transition: box-shadow 0.22s cubic-bezier(0.4,0,0.2,1),
              border-color 0.22s ease;
  position: relative;
  transform: translateZ(0);
  will-change: box-shadow;
  isolation: isolate;
  -webkit-tap-highlight-color: transparent;
  tap-highlight-color: transparent;
  outline: none;
  user-select: none;
  -webkit-user-select: none;
}

/* Glass: semi-transparent tinted background so blur is actually visible */
.link-card.glass {
  background: color-mix(in srgb, var(--color-card) 35%, transparent);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

/* Shadow — controlled by --card-box-shadow */
.link-card.with-shadow {
  box-shadow: var(--card-box-shadow);
}

.link-card:hover .link-arrow { opacity: 0.8; transform: translateX(3px); }

/* ── Card ::after — lift bottom line, extends from center ──────────────────── */
.link-card::after {
  content: '';
  position: absolute;
  bottom: 0; left: 0; right: 0;
  height: 2px;
  background: var(--color-accent);
  border-radius: 0 0 var(--card-radius) var(--card-radius);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ── Hover Effects ───────────────────────────────────────────────────────────── */
.link-card.hover-lift:hover::after {
  transform: scaleX(1);
}
.link-card.hover-lift:hover {
  box-shadow: 0 4px 24px rgba(0,0,0,0.28);
}
.link-card.hover-neon:hover {
  border-color: var(--color-accent) !important;
  box-shadow:
    0 0 0 1px var(--color-accent),
    0 0 18px color-mix(in srgb, var(--color-accent) 45%, transparent),
    inset 0 0 18px color-mix(in srgb, var(--color-accent) 8%, transparent);
}

/* ── Card Layouts ────────────────────────────────────────────────────────────── */

/* Compact — tighter padding, smaller icon, slightly smaller text */
.links-container.layout-compact .link-card {
  padding: 8px 12px;
}
.links-container.layout-compact .link-icon { width: 24px; height: 24px; }
.links-container.layout-compact .link-icon svg { width: 16px; height: 16px; }
.links-container.layout-compact .link-label { font-size: 0.88em; }

/* Feature — accent-tinted icon panel on the left */
.links-container.layout-feature .link-card {
  padding: 0;
  gap: 0;
  align-items: stretch;
}
.links-container.layout-feature .link-icon {
  width: 58px;
  height: auto;
  background: color-mix(in srgb, var(--color-accent) 16%, transparent);
  border-right: 1px solid color-mix(in srgb, var(--color-accent) 22%, transparent);
  border-radius: calc(var(--card-radius) - 2px) 0 0 calc(var(--card-radius) - 2px);
  color: var(--color-icon);
  flex-shrink: 0;
}
.links-container.layout-feature.icon-right .link-card { flex-direction: row-reverse; }
.links-container.layout-feature.icon-right .link-icon {
  border-radius: 0 calc(var(--card-radius) - 2px) calc(var(--card-radius) - 2px) 0;
  border-right: none;
  border-left: 1px solid color-mix(in srgb, var(--color-accent) 22%, transparent);
}
.links-container.layout-feature .link-label { padding: var(--card-padding); }
.links-container.layout-feature .link-card::after { display: none; }

/* Minimal — text rows, no card box, bottom border only */
.links-container.layout-minimal .link-card {
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  border: none !important;
  border-bottom: 1px solid color-mix(in srgb, var(--color-text) 14%, transparent) !important;
  border-radius: 0 !important;
  padding-left: 0 !important;
  padding-right: 0 !important;
  box-shadow: none !important;
  transition: color 0.2s ease, border-bottom-color 0.2s ease !important;
}
.links-container.layout-minimal .link-card::after { display: none !important; }
.links-container.layout-minimal .link-card:hover {
  color: var(--color-accent) !important;
  border-bottom-color: var(--color-accent) !important;
  transform: none !important;
  box-shadow: none !important;
}
.links-container.layout-minimal .link-card:hover .link-label { color: var(--color-accent); }
.links-container.layout-minimal .link-icon { color: inherit !important; }
.links-container.layout-minimal .link-arrow { display: none; }

/* Grid — 2 column equal squares */
.links-container.layout-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: 1fr;
}
.links-container.layout-grid::before {
  content: '';
  width: 0;
  padding-bottom: 100%;
  grid-row: 1;
  grid-column: 1;
}
.links-container.layout-grid > *:first-child {
  grid-row: 1;
  grid-column: 1;
}
.links-container.layout-grid .link-card {
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 16px 10px;
  text-align: center;
  gap: 8px;
  aspect-ratio: 1;
  width: 100%;
}
.links-container.layout-grid .link-icon { width: 36px; height: 36px; }
.links-container.layout-grid .link-icon svg { width: 24px; height: 24px; }
.links-container.layout-grid .link-arrow { display: none; }
.links-container.layout-grid .link-label { flex: unset; font-size: 12px; }
.links-container.layout-grid .link-card:last-child:nth-child(odd) { grid-column: span 1; }

/* ── Global Layout Options ───────────────────────────────────────────────────── */

/* Icon position */
.links-container.icon-right .link-card { flex-direction: row-reverse; }

/* Text alignment */
.links-container.text-left   .link-label { text-align: left; }
.links-container.text-center .link-label { text-align: center; }
.links-container.text-right  .link-label { text-align: right; }

/* Icon */
.link-icon {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-icon);
}

.link-icon svg  { width: 22px; height: 22px; fill: currentColor; }
.link-icon img  { width: 22px; height: 22px; object-fit: contain; }

/* Custom icon with color tinting — mask technique works for PNG + SVG */
.link-icon-mask {
  display: inline-block;
  width: 22px;
  height: 22px;
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* Icon size overrides */
.links-container.icon-sm .link-icon       { width: 20px; height: 20px; }
.links-container.icon-sm .link-icon svg,
.links-container.icon-sm .link-icon img,
.links-container.icon-sm .link-icon-mask  { width: 14px; height: 14px; }
.links-container.icon-lg .link-icon       { width: 44px; height: 44px; }
.links-container.icon-lg .link-icon svg,
.links-container.icon-lg .link-icon img,
.links-container.icon-lg .link-icon-mask  { width: 28px; height: 28px; }
.links-container.icon-none .link-icon     { display: none; }

.link-icon,
.link-label,
.link-arrow { position: relative; z-index: 1; }

.link-label { flex: 1; }

.link-arrow {
  flex-shrink: 0;
  opacity: 0.3;
  color: var(--color-icon);
  transition: opacity 0.2s, transform 0.2s;
}

.link-card:hover .link-arrow { opacity: 0.8; transform: translateX(3px); }

/* ─── Responsive ────────────────────────────────────────────────────────────── */
@media (max-width: 520px) {
  .page-wrapper { padding: 36px 12px 60px; }
}

/* ─── Title Animations ───────────────────────────────────────────────────────── */
/*
 * All animations use filter/transform/background-position — NOT text-shadow.
 * This ensures they work correctly on gradient-clipped text.
 * Speed is controlled by --name-anim-speed CSS var set by JS.
 */
:root { --name-anim-speed: 2.5s; }

/* Glow Pulse — filter drop-shadow breathes. Works on any text style. */
.profile-name.anim-glow-pulse {
  animation: name-glow-pulse var(--name-anim-speed) ease-in-out infinite;
}
@keyframes name-glow-pulse {
  0%, 100% { filter: drop-shadow(0 0 2px var(--color-accent)); }
  50%       { filter: drop-shadow(0 0 16px var(--color-accent)) drop-shadow(0 0 40px var(--color-accent-dk)); }
}

/* Shine — metallic light sweep across text via background-position.
   Works perfectly on gradient-clipped text. */
.profile-name.anim-shine {
  background: linear-gradient(
    105deg,
    var(--color-text)   20%,
    rgba(255,255,255,0) 38%,
    rgba(255,255,255,1) 48%,
    var(--color-accent) 50%,
    rgba(255,255,255,1) 52%,
    rgba(255,255,255,0) 62%,
    var(--color-text)   80%
  ) !important;
  background-size: 250% 100% !important;
  -webkit-background-clip: text !important;
  background-clip: text !important;
  -webkit-text-fill-color: transparent !important;
  animation: name-shine var(--name-anim-speed) ease-in-out infinite;
}
@keyframes name-shine {
  0%   { background-position: 250% center; }
  100% { background-position: -250% center; }
}

/* Float — vertical drift */
.profile-name.anim-float {
  animation: name-float var(--name-anim-speed) ease-in-out infinite;
}
@keyframes name-float {
  0%, 100% { transform: translateY(0px); }
  50%       { transform: translateY(-8px); }
}

/* Blur Breathe — filter blur pulse, creates a mystical hazy effect */
.profile-name.anim-blur-breathe {
  animation: name-blur-breathe var(--name-anim-speed) ease-in-out infinite;
}
@keyframes name-blur-breathe {
  0%, 100% { filter: blur(0px) brightness(1); }
  50%       { filter: blur(0.8px) brightness(1.4) drop-shadow(0 0 10px var(--color-accent)); }
}

/* Hue Shift — cycles all colors via filter hue-rotate */
.profile-name.anim-hue-shift {
  animation: name-hue-shift var(--name-anim-speed) linear infinite;
}
@keyframes name-hue-shift {
  from { filter: hue-rotate(0deg); }
  to   { filter: hue-rotate(360deg); }
}

/* Flicker — neon sign effect via opacity + drop-shadow combos */
.profile-name.anim-flicker {
  animation: name-flicker calc(var(--name-anim-speed) * 1.5) ease-in-out infinite;
}
@keyframes name-flicker {
  0%, 18%, 22%, 26%, 30%, 100% {
    opacity: 1;
    filter: drop-shadow(0 0 6px var(--color-accent)) drop-shadow(0 0 20px var(--color-accent-dk));
  }
  20%, 24%, 28% { opacity: 0.4; filter: none; }
  80%, 86%, 90% {
    opacity: 1;
    filter: drop-shadow(0 0 6px var(--color-accent));
  }
  83%, 88% { opacity: 0.6; filter: none; }
}

/* Letter Spacing Pulse — elegant expansion/contraction */
.profile-name.anim-letter-stretch {
  animation: name-letter-stretch var(--name-anim-speed) ease-in-out infinite;
}
@keyframes name-letter-stretch {
  0%, 100% { letter-spacing: var(--name-letter-spacing); }
  50%       { letter-spacing: calc(var(--name-letter-spacing) + 0.12em); }
}

/* Scale Breathe — very subtle scale with glow */
.profile-name.anim-scale-breathe {
  animation: name-scale-breathe var(--name-anim-speed) ease-in-out infinite;
}
@keyframes name-scale-breathe {
  0%, 100% { transform: scale(1);    filter: drop-shadow(0 0 0px var(--color-accent)); }
  50%       { transform: scale(1.06); filter: drop-shadow(0 0 12px var(--color-accent)); }
}

/* Gradient Flow — animates background-position on the gradient itself.
   Most impactful when combined with Gradient or Gradient+Glow effect. */
.profile-name.anim-gradient-flow {
  background-size: 300% 300% !important;
  animation: name-gradient-flow var(--name-anim-speed) ease infinite;
}
@keyframes name-gradient-flow {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

/* Depth Pulse — scale + Y skew for a 3D breathing feel */
.profile-name.anim-depth-pulse {
  animation: name-depth-pulse var(--name-anim-speed) ease-in-out infinite;
}
@keyframes name-depth-pulse {
  0%, 100% { transform: perspective(400px) rotateX(0deg)   scale(1); }
  50%       { transform: perspective(400px) rotateX(4deg) scale(1.04); filter: drop-shadow(0 6px 12px rgba(0,0,0,.4)); }
}
