hikari-components 0.1.8

Core UI components (40+) for the Hikari design system
// Hikari Radio Component Styles
// Use theme variables with namespace to avoid conflicts
@use 'variables' as vars;
@use 'mixins' as mix;

// ============================================
// Hikari Radio Component
// Features: FUI styling, smooth transitions, glow effects
// Uses Layer 2 CSS variables (--hi-component-selection-*)
// ============================================

// ============================================
// Radio Group
// ============================================

.hi-radio-group {
  display: flex;
  gap: 12px;
}

.hi-radio-group-vertical {
  flex-direction: column;
}

.hi-radio-group-horizontal {
  flex-direction: row;
  align-items: center;
}

// ============================================
// Radio Label (wraps input + indicator + text)
// ============================================

.hi-radio-label {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  user-select: none;
  padding: 4px 0;

  &:hover .hi-radio-indicator:not([disabled]) {
    border-color: var(--hi-primary);
    box-shadow: 0 0 8px var(--hi-component-selection-glow);
  }
}

// ============================================
// Hidden native input
// ============================================

.hi-radio-label input[type="radio"] {
  position: absolute;
  opacity: 0;
  cursor: pointer;
  width: 0;
  height: 0;
  margin: 0;
  padding: 0;
}

// ============================================
// Custom radio indicator (circle)
// Uses Layer 2 variables
// ============================================

.hi-radio-indicator {
  position: relative;
  display: inline-block;
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--hi-component-selection-border);
  border-radius: 50%;
  background: var(--hi-component-selection-surface);
  transition: all vars.$hikari-duration-fast vars.$hikari-ease-smooth;
  box-sizing: border-box;
}

// ============================================
// Inner dot (uses Layer 2 gradient)
// ============================================

.hi-radio-dot {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 8px;
  height: 8px;
  background: var(--hi-component-selection-bg);
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(0);
  transition: transform 200ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

// ============================================
// Checked state - dot becomes visible
// ============================================

.hi-radio-label input[type="radio"]:checked + .hi-radio-indicator {
  border-color: var(--hi-primary);
  box-shadow:
    0 0 6px var(--hi-component-selection-glow),
    inset 0 0 3px rgba(255, 255, 255, 0.1);
}

.hi-radio-label input[type="radio"]:checked + .hi-radio-indicator .hi-radio-dot {
  transform: translate(-50%, -50%) scale(1);
}

// ============================================
// Hover effect on checked
// ============================================

.hi-radio-label:hover input[type="radio"]:checked + .hi-radio-indicator {
  box-shadow:
    0 0 10px var(--hi-component-selection-glow),
    inset 0 0 4px rgba(255, 255, 255, 0.2);
}

// ============================================
// Disabled state
// ============================================

.hi-radio-label input[type="radio"]:disabled + .hi-radio-indicator {
  opacity: 0.4;
  cursor: not-allowed;
}

.hi-radio-label:has(input[type="radio"]:disabled) {
  cursor: not-allowed;
  opacity: 0.6;
}

// ============================================
// Label text
// ============================================

.hi-radio-text {
  font-family: vars.$hikari-font-family-sans;
  font-size: vars.$hikari-font-size-base;
  font-weight: 400;
  color: var(--hi-text-primary);
  line-height: 1.5;
  white-space: nowrap;
}