hikari-components 0.3.12

Core UI components (buttons, inputs, tables, modals) for the Hikari design system
// Use theme variables with namespace to avoid conflicts
@use '../../../../theme/styles/variables.scss' as vars;
@use '../../../../theme/styles/mixins.scss' as mix;

// ============================================
// Hikari Glow Component - Single Glow Color System
// ============================================
//
// IMPORTANT: All glow states are controlled by AnimationBuilder via inline styles.
// CSS does NOT provide any default hover/active/focus behavior.
// The --glow-intensity-scale variable is set inline:
// - Idle: 0 (no glow)
// - Hover: 0.5 (subtle glow)
// - Focus: 0.7 (medium glow)
// - Active: 1.0 (intense glow)
//
// CSS only provides:
// 1. Base structure (::before pseudo-element)
// 2. Intensity classes (dim/soft/bright) for base opacity multiplier
// 3. Transition timing

// Base glow wrapper styles
.hi-glow-wrapper,
.hi-glow-wrapper-block {
  position: relative;

  // Initialize scale factors - default to 0 (hidden)
  --glow-intensity-scale: 0;
  --glow-spread-scale: 1.0;

  // Create dynamic glow overlay using CSS variables (spotlight effect)
  &::before {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 2;
    border-radius: inherit;
    // Use inline style value directly, no fallback
    // AnimationBuilder controls this via --glow-intensity-scale
    opacity: calc(var(--glow-base-opacity, 1) * var(--glow-intensity-scale));

    // Use radial-gradient for acrylic spotlight effect
    background: radial-gradient(
      circle at var(--glow-x, 50%) var(--glow-y, 50%),
      var(--hi-glow-color) 0%,
      transparent calc(var(--glow-spread, 1.5) * 100%)
    );

    // Transition for smooth state changes
    transition: opacity 100ms ease-out;
  }

  // Ensure children (links, buttons) are always clickable
  > * {
    pointer-events: auto;
    position: relative;
    z-index: 1;
  }
}

// ============================================
// Glow Intensity Levels (Opacity & Spread)
// ============================================

// These classes define the BASE opacity for different glow intensities
// The actual visibility is controlled by --glow-intensity-scale (0 = hidden, 1 = full intensity)
// IMPORTANT: --glow-base-opacity must be defined on the parent, not on ::before
//
// Opacity calculation: base-opacity * intensity-scale
// - Hover (0.5): subtle glow
// - Active (1.0): intense glow (2x hover)

// 30% intensity (subtle, for large surfaces: cards, panels, containers)
.hi-glow-dim {
  --glow-spread: 2.4;
  --glow-base-opacity: 0.15;
}

// 70% intensity (medium, default for interactive elements: buttons, inputs)
// Hover: 0.30 * 0.5 = 0.15
// Active: 0.30 * 1.0 = 0.30 (visible difference)
.hi-glow-soft {
  --glow-spread: 1.6;
  --glow-base-opacity: 0.30;
}

// 100% intensity (intense, for emphasis: active states, focus rings)
.hi-glow-bright {
  --glow-spread: 1.3;
  --glow-base-opacity: 0.50;
}

.hi-glow-wrapper {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  align-self: flex-start;

  // 统一使用 4px 圆角
  border-radius: 4px;

  overflow: visible;
}

// Block variant for wrapping block-level elements (like Card)
.hi-glow-wrapper-block {
  display: flex;
  flex-direction: column;
  width: 100%;

  // 统一使用 4px 圆角
  border-radius: 4px;
  overflow: visible;
}

// ============================================
// Button Enhancement (Managed by AnimationBuilder)
// ============================================

// Remove transform translateY from button hover when wrapped in glow
.hi-glow-wrapper .hi-button:hover {
  transform: none;
}

// Default: No box-shadow - controlled by AnimationBuilder via CSS variables
// The glow wrapper handles all visual feedback through --glow-intensity-scale
.hi-glow-wrapper .hi-button:focus-visible {
  box-shadow: none;
}

.hi-glow-wrapper .hi-button:active:not(:disabled) {
  box-shadow: none;
  transform: none;
}

// Input hover enhancement
.hi-glow-wrapper .hi-input-wrapper:hover {
  // No hover effect - handled by glow overlay
}

// ============================================
// Glow Animation Presets
// ============================================
//
// These presets add continuous animation effects to the glow component.
// They are activated by adding the corresponding class to the wrapper.
//
// Note: Preset animations pause during mouse interaction to maintain performance.

// Pulse animation - heartbeat-like pulsing glow
@keyframes glow-pulse {
  0%, 100% {
    --glow-intensity-scale: 0.5;
  }
  50% {
    --glow-intensity-scale: 1.0;
  }
}

.hi-glow-wrapper.pulse::before {
  animation: glow-pulse 2s ease-in-out infinite;
}

// Breathe animation - slow, smooth intensity variation
@keyframes glow-breathe {
  0%, 100% {
    --glow-intensity-scale: 0.3;
  }
  50% {
    --glow-intensity-scale: 1.0;
  }
}

.hi-glow-wrapper.breathe::before {
  animation: glow-breathe 4s ease-in-out infinite;
}

// Shimmer animation - moving light spot across the element
@keyframes glow-shimmer {
  0% {
    --glow-x: 20%;
    --glow-y: 50%;
  }
  25% {
    --glow-x: 50%;
    --glow-y: 80%;
  }
  50% {
    --glow-x: 80%;
    --glow-y: 50%;
  }
  75% {
    --glow-x: 50%;
    --glow-y: 20%;
  }
  100% {
    --glow-x: 20%;
    --glow-y: 50%;
  }
}

.hi-glow-wrapper.shimmer::before {
  animation: glow-shimmer 3s linear infinite;
}

// Pause preset animations during mouse interaction
.hi-glow-wrapper.pulse:has(:hover)::before,
.hi-glow-wrapper.pulse:has(:active)::before,
.hi-glow-wrapper.breathe:has(:hover)::before,
.hi-glow-wrapper.breathe:has(:active)::before,
.hi-glow-wrapper.shimmer:has(:hover)::before,
.hi-glow-wrapper.shimmer:has(:active)::before {
  animation-play-state: paused;
}