/** * Reusable UI Components * * Base styles for buttons, cards, forms, and other UI elements * * @package ThinkRank * @since 1.0.0 */ // Import shared variables for access to design tokens @use '../../shared/styles/variables' as *; @use 'components/index'; /* Scoped base styles for ThinkRank UI */ .thinkrank-ui { /* Reset and base styles only within ThinkRank components */ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; line-height: 1.5; color: #1f2937; /* Ensure box-sizing is border-box for all ThinkRank elements */ *, *::before, *::after { box-sizing: border-box; } /* ========================================================================== ENHANCED CARD SYSTEM ========================================================================== */ // Base card class with common properties .thinkrank-card { background: $white; border-radius: $radius-lg; border: 1px solid $border-light; transition: all $transition-normal; overflow: hidden; // Base shadow box-shadow: $shadow-sm; // Variants &--elevated { box-shadow: $shadow-md; &:hover { box-shadow: $shadow-lg; } } &--interactive { cursor: pointer; &:hover { border-color: $border-medium; box-shadow: $shadow-md; } &:active { box-shadow: $shadow-sm; } } &--flat { box-shadow: none; border: 1px solid $border-light; } &--bordered { border: 2px solid $border-medium; box-shadow: none; } // Size variants &--compact { border-radius: $radius-md; } &--large { border-radius: $radius-xl; } // Color variants &--primary { border-color: rgba($primary-blue, 0.2); background: linear-gradient(135deg, rgba($primary-blue, 0.02), $white); &.thinkrank-card--interactive:hover { border-color: rgba($primary-blue, 0.3); box-shadow: 0 4px 12px rgba($primary-blue, 0.15); } } &--success { border-color: rgba($success-green, 0.2); background: linear-gradient(135deg, rgba($success-green, 0.02), $white); &.thinkrank-card--interactive:hover { border-color: rgba($success-green, 0.3); box-shadow: 0 4px 12px rgba($success-green, 0.15); } } &--warning { border-color: rgba($warning-orange, 0.2); background: linear-gradient(135deg, rgba($warning-orange, 0.02), $white); &.thinkrank-card--interactive:hover { border-color: rgba($warning-orange, 0.3); box-shadow: 0 4px 12px rgba($warning-orange, 0.15); } } &--danger { border-color: rgba($error-red, 0.2); background: linear-gradient(135deg, rgba($error-red, 0.02), $white); &.thinkrank-card--interactive:hover { border-color: rgba($error-red, 0.3); box-shadow: 0 4px 12px rgba($error-red, 0.15); } } // Card sections &__header { padding: $spacing-2xl $spacing-2xl $spacing-lg; border-bottom: 1px solid $border-light; background: $gray-50; &:last-child { border-bottom: none; padding-bottom: $spacing-2xl; } h1, h2, h3, h4, h5, h6 { margin: 0 0 $spacing-sm 0; color: $text-primary; font-weight: $font-weight-semibold; } p { margin: 0; color: $text-secondary; font-size: $font-size-sm; } } &__body { // Default padding - utilities can override this padding: $spacing-2xl; &:first-child { padding-top: $spacing-2xl; } &:last-child { padding-bottom: $spacing-2xl; } // Compact padding for nested cards .thinkrank-card & { padding: $spacing-lg; } } &__footer { padding: $spacing-lg $spacing-2xl $spacing-2xl; border-top: 1px solid $border-light; background: $gray-50; &:last-child { border-top: none; padding-top: $spacing-2xl; } // Common footer patterns &--actions { display: flex; align-items: center; justify-content: space-between; gap: $spacing-md; @media (max-width: $breakpoint-sm) { flex-direction: column; align-items: stretch; .thinkrank-btn { width: 100%; justify-content: center; } } } } // Special card types &--stat { text-align: center; .stat-number { font-size: $font-size-3xl; font-weight: $font-weight-bold; color: $text-primary; line-height: 1; margin-bottom: $spacing-sm; } .stat-label { font-size: $font-size-sm; color: $text-secondary; text-transform: uppercase; letter-spacing: 0.05em; font-weight: $font-weight-medium; } } &--feature { text-align: center; .feature-icon { width: 3rem; height: 3rem; margin: 0 auto $spacing-lg; background: $gray-100; border-radius: $radius-lg; display: flex; align-items: center; justify-content: center; color: $gray-600; font-size: 1.5rem; } .feature-title { font-size: $font-size-lg; font-weight: $font-weight-semibold; color: $text-primary; margin-bottom: $spacing-sm; } .feature-description { color: $text-secondary; font-size: $font-size-sm; line-height: $line-height-relaxed; } } } /* ========================================================================== ENHANCED BUTTON SYSTEM ========================================================================== */ // Base button class with common properties .thinkrank-btn { display: inline-flex; align-items: center; justify-content: center; border-radius: $radius-md; font-weight: $font-weight-medium; font-size: $font-size-sm; transition: all $transition-fast; cursor: pointer; border: 1px solid transparent; text-decoration: none; line-height: 1; // Remove default button styles background: none; outline: none; // Focus styles &:focus { outline: none; box-shadow: 0 0 0 2px $primary-blue; } // Disabled state &:disabled, &.disabled { opacity: 0.5; cursor: not-allowed; transform: none !important; box-shadow: none !important; } // Icon spacing svg, .dashicon { margin-right: $spacing-sm; flex-shrink: 0; &:last-child { margin-right: 0; margin-left: $spacing-sm; } &:only-child { margin: 0; } } // Size variants &--xs { padding: $spacing-xs $spacing-sm; font-size: $font-size-xs; height: 1.5rem; // 24px min-height: 1.5rem; } &--sm { padding: $spacing-sm $spacing-md; font-size: $font-size-xs; height: $button-height-sm; min-height: $button-height-sm; } &--base { padding: $spacing-md $spacing-lg; height: $button-height-md; min-height: $button-height-md; } &--lg { padding: $spacing-lg $spacing-xl; height: $button-height-lg; min-height: $button-height-lg; font-size: $font-size-base; } // Style variants &--primary { background: $primary-blue; color: $white; border-color: $primary-blue; &:hover:not(:disabled) { background: $primary-blue-dark; border-color: $primary-blue-dark; transform: translateY(-1px); box-shadow: 0 4px 12px rgba($primary-blue, 0.3); } &:active { transform: translateY(0); box-shadow: 0 2px 4px rgba($primary-blue, 0.3); } } &--secondary { background: $white; color: $gray-700; border-color: $gray-300; &:hover:not(:disabled) { background: $gray-50; border-color: $gray-400; transform: translateY(-1px); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } &:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); } } &--success { background: $success-green; color: $white; border-color: $success-green; &:hover:not(:disabled) { background: $success-green-dark; border-color: $success-green-dark; transform: translateY(-1px); box-shadow: 0 4px 12px rgba($success-green, 0.3); } } &--warning { background: $warning-orange; color: $white; border-color: $warning-orange; &:hover:not(:disabled) { background: $warning-orange-dark; border-color: $warning-orange-dark; transform: translateY(-1px); box-shadow: 0 4px 12px rgba($warning-orange, 0.3); } } &--danger { background: $white; color: $error-red; border-color: $error-red; &:hover:not(:disabled) { background: $error-red; color: $white; transform: translateY(-1px); box-shadow: 0 4px 12px rgba($error-red, 0.3); } } &--ghost { background: transparent; color: $gray-600; border-color: transparent; &:hover:not(:disabled) { background: $gray-100; color: $gray-800; } } &--link { background: transparent; color: $primary-blue; border-color: transparent; text-decoration: underline; &:hover:not(:disabled) { color: $primary-blue-dark; text-decoration: none; } } // Loading state &--loading { position: relative; color: transparent; &::after { content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 1rem; height: 1rem; border: 2px solid currentColor; border-radius: 50%; border-top-color: transparent; animation: spin 1s linear infinite; } } // Full width &--full { width: 100%; } } // Legacy button classes (for backward compatibility) .thinkrank-button-primary { @extend .thinkrank-btn; @extend .thinkrank-btn--primary; @extend .thinkrank-btn--base; } .thinkrank-button-secondary { @extend .thinkrank-btn; @extend .thinkrank-btn--secondary; @extend .thinkrank-btn--base; } // Spin animation for loading state @keyframes spin { to { transform: translate(-50%, -50%) rotate(360deg); } } /* Loading states */ .thinkrank-loading { display: flex; align-items: center; justify-content: center; padding: 2rem; .spinner { margin-right: 0.5rem; } } /* Error states */ .thinkrank-error-notice { margin-bottom: 1rem; } /* Form elements */ .thinkrank-form-group { margin-bottom: 1rem; label { display: block; margin-bottom: 0.25rem; font-weight: 500; color: #374151; } .description { margin-top: 0.25rem; font-size: 0.75rem; color: #6b7280; } } /* Input fields */ .thinkrank-input { width: 100%; padding: 0.5rem 0.75rem; border: 1px solid #d1d5db; border-radius: 6px; font-size: 0.875rem; line-height: 1.5; &:focus { outline: none; border-color: #2563eb; box-shadow: 0 0 0 1px #2563eb; } &:disabled { background-color: #f9fafb; color: #6b7280; cursor: not-allowed; } } /* Select fields */ .thinkrank-select { width: 100%; padding: 0.5rem 0.75rem; border: 1px solid #d1d5db; border-radius: 6px; font-size: 0.875rem; background-color: white; background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3e%3c/svg%3e"); background-position: right 0.5rem center; background-repeat: no-repeat; background-size: 1.5em 1.5em; padding-right: 2.5rem; &:focus { outline: none; border-color: #2563eb; box-shadow: 0 0 0 1px #2563eb; } } /* Textarea */ .thinkrank-textarea { width: 100%; padding: 0.5rem 0.75rem; border: 1px solid #d1d5db; border-radius: 6px; font-size: 0.875rem; line-height: 1.5; resize: vertical; min-height: 2.75rem; &:focus { outline: none; border-color: #2563eb; box-shadow: 0 0 0 1px #2563eb; } } /* Notices */ .thinkrank-notice { padding: 0.75rem 1rem; border-radius: 6px; margin-bottom: 1rem; border-left: 4px solid; &.notice-success { background-color: #f0fdf4; border-left-color: #22c55e; color: #166534; } &.notice-error { background-color: #fef2f2; border-left-color: #ef4444; color: #dc2626; } &.notice-warning { background-color: #fffbeb; border-left-color: #f59e0b; color: #92400e; } &.notice-info { background-color: #eff6ff; border-left-color: #3b82f6; color: #1d4ed8; } p { margin: 0; } } /* Badges */ .thinkrank-badge { display: inline-flex; align-items: center; padding: 0.25rem 0.75rem; border-radius: 12px; font-size: 0.75rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.025em; &.badge-success { background-color: #dcfce7; color: #166534; border: 1px solid #bbf7d0; } &.badge-error { background-color: #fef2f2; color: #dc2626; border: 1px solid #fecaca; } &.badge-warning { background-color: #fef3c7; color: #92400e; border: 1px solid #fde68a; } &.badge-info { background-color: #dbeafe; color: #1d4ed8; border: 1px solid #bfdbfe; } } /* Model Badge Styles */ .model-badge { display: inline-flex; align-items: center; padding: 0.25rem 0.5rem; border-radius: 0.375rem; font-size: 0.75rem; font-weight: 500; text-transform: none; letter-spacing: 0; white-space: nowrap; vertical-align: middle; &.openai { background-color: rgba($openai-green, 0.1); color: $openai-green-dark; border: 1px solid rgba($openai-green, 0.2); } &.claude { background-color: rgba($claude-orange, 0.1); color: $claude-orange-dark; border: 1px solid rgba($claude-orange, 0.2); } &.gemini { background-color: rgba($purple, 0.1); color: darken($purple, 20%); border: 1px solid rgba($purple, 0.2); } } /* Tooltips */ .thinkrank-tooltip { position: relative; display: inline-block; .tooltip-content { visibility: hidden; width: 200px; background-color: #1f2937; color: white; text-align: center; border-radius: 6px; padding: 0.5rem; position: absolute; z-index: 1000; bottom: 125%; left: 50%; margin-left: -100px; opacity: 0; transition: opacity 0.3s; font-size: 0.75rem; &::after { content: ""; position: absolute; top: 100%; left: 50%; margin-left: -5px; border-width: 5px; border-style: solid; border-color: #1f2937 transparent transparent transparent; } } &:hover .tooltip-content { visibility: visible; opacity: 1; } } /* ========================================================================== AI-INSPIRED COMPONENTS ========================================================================== */ .thinkrank-ai-card { background: #ffffff; border: 2px solid transparent; border-radius: 16px; position: relative; overflow: hidden; // Purple gradient border effect &::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border-radius: 16px; padding: 2px; background: linear-gradient(135deg, #8b5cf6 0%, #a855f7 25%, #c084fc 50%, #e879f9 75%, #f0abfc 100%); mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); mask-composite: xor; -webkit-mask-composite: xor; pointer-events: none; } &__header { display: flex; align-items: center; gap: 16px; padding: 24px 24px 0; margin-bottom: 24px; } &__title { h3 { font-size: 20px; font-weight: 600; color: #1e293b; margin: 0 0 4px 0; } p { font-size: 14px; color: #64748b; margin: 0; } } &__body { padding: 0 24px; } &__footer { padding: 24px; border-top: 1px solid #e2e8f0; margin-top: 24px; background: #ffffff; } } .thinkrank-ai-icon { width: 48px; height: 48px; border-radius: 12px; background: linear-gradient(135deg, #8b5cf6 0%, #a855f7 100%); display: flex; align-items: center; justify-content: center; flex-shrink: 0; .thinkrank-sparkles { font-size: 20px; filter: drop-shadow(0 0 8px rgba(139, 92, 246, 0.3)); } } // WordPress Icon Styling .thinkrank-icon { display: inline-flex; align-items: center; justify-content: center; svg { width: 20px; height: 20px; fill: currentColor; } } .thinkrank-ai-section { margin-top: 32px; padding-top: 24px; border-top: 1px solid #e2e8f0; &__title { font-size: 16px; font-weight: 600; color: #374151; margin: 0 0 16px 0; display: flex; align-items: center; gap: 8px; &::before { content: '⚡'; font-size: 14px; } } } .thinkrank-ai-btn { width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 16px 24px; background: linear-gradient(135deg, #1e293b 0%, #334155 100%); color: white; border: none; border-radius: 12px; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; &::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent); transition: left 0.5s ease; } &:hover:not(:disabled) { background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%); transform: translateY(-1px); box-shadow: 0 8px 25px rgba(30, 41, 59, 0.3); &::before { left: 100%; } .thinkrank-sparkles { transform: scale(1.05); } } &:disabled { opacity: 0.7; cursor: not-allowed; transform: none; &:hover { transform: none; box-shadow: none; } } &--loading { .components-spinner { margin-right: 8px; } } } .thinkrank-sparkles { display: inline-block; transition: transform 0.3s ease; } /* Responsive utilities */ @media (max-width: 768px) { .thinkrank-hide-mobile { display: none !important; } } @media (min-width: 769px) { .thinkrank-hide-desktop { display: none !important; } } /* ========================================================================== BUSINESS HOURS COMPONENT ========================================================================== */ .business-hours-control { .day-hours-row { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; padding: 8px; border: 1px solid #ddd; border-radius: 4px; background: #fafafa; &:hover { background: #f0f0f0; } span:first-child { min-width: 80px; font-weight: 500; text-transform: capitalize; color: #1e1e1e; } .components-toggle-control { margin: 0; min-width: 60px; } input[type="time"] { padding: 4px 8px; border: 1px solid #ccd0d4; border-radius: 3px; font-size: 13px; &:focus { border-color: #007cba; box-shadow: 0 0 0 1px #007cba; outline: none; } &:disabled { background: #f6f7f7; color: #a7aaad; } } span:not(:first-child) { color: #646970; font-size: 13px; } } } }