// Search functionality for Claude Code Templates
let searchActive = false;
let searchResults = [];
let allComponents = {};
let searchTimeout = null;
/**
* Toggle search bar visibility
*/
function toggleSearch() {
const container = document.getElementById('searchBarContainer');
const input = document.getElementById('searchInput');
const searchBtn = document.getElementById('searchToggleBtn');
const categoryLabels = document.querySelectorAll('.category-filter-label');
if (searchActive) {
// Hide search and show category sections
container.style.display = 'none';
searchActive = false;
searchBtn.classList.remove('active');
clearSearch();
// Show category filter labels/sections
categoryLabels.forEach(label => {
label.style.display = '';
});
} else {
// Show search and hide category sections
container.style.display = 'block';
searchActive = true;
searchBtn.classList.add('active');
input.focus();
// Hide category filter labels/sections only (keep filter buttons visible)
categoryLabels.forEach(label => {
label.style.display = 'none';
});
// Ensure components are loaded
if (Object.keys(allComponents).length === 0) {
loadComponentsForSearch();
}
}
}
/**
* Handle search input - now only shows/hides clear button, doesn't trigger search
*/
function handleSearchInput(event) {
const query = event.target.value;
const clearBtn = document.getElementById('clearSearchBtn');
// Show/hide clear button
if (query.length > 0) {
clearBtn.style.display = 'flex';
} else {
clearBtn.style.display = 'none';
// If input is empty, restore previous view
restorePreviousView();
}
}
/**
* Handle keyboard shortcuts in search
*/
function handleSearchKeydown(event) {
if (event.key === 'Escape') {
clearSearch();
} else if (event.key === 'Enter') {
event.preventDefault();
const query = event.target.value.trim();
if (query.length >= 3) {
performSearch(query);
} else if (query.length === 0) {
restorePreviousView();
}
}
}
/**
* Clear search and reset view
*/
function clearSearch() {
const input = document.getElementById('searchInput');
const clearBtn = document.getElementById('clearSearchBtn');
input.value = '';
clearBtn.style.display = 'none';
// Clear search timeout
if (searchTimeout) {
clearTimeout(searchTimeout);
searchTimeout = null;
}
// Clear URL parameter
updateURLWithSearch('');
// Restore previous view
restorePreviousView();
searchResults = [];
}
/**
* Restore the previous view (before search was active)
*/
function restorePreviousView() {
const resultsInfo = document.getElementById('searchResultsInfo');
resultsInfo.style.display = 'none';
// Show filters again
showFilters();
// Reset to current filter view
const activeFilter = document.querySelector('.component-type-filters .filter-chip.active');
if (activeFilter) {
const filterType = activeFilter.getAttribute('data-filter');
if (window.indexManager) {
window.indexManager.displayCurrentFilter();
}
} else {
// Fallback to agents if no active filter found
if (window.indexManager) {
window.indexManager.setFilter('agents');
}
}
}
/**
* Load all components for search functionality
*/
async function loadComponentsForSearch() {
try {
// Check if dataLoader is available and use it
if (window.dataLoader) {
const data = await window.dataLoader.loadAllComponents();
if (data) {
// Process each category for search
const categories = ['agents', 'commands', 'settings', 'hooks', 'mcps', 'skills'];
for (const category of categories) {
if (data[category] && Array.isArray(data[category])) {
// Process components to make them search-friendly
allComponents[category] = data[category].map(component => ({
...component,
// Normalize fields for better searching
title: component.name || component.title || 'Untitled',
displayName: (component.name || component.title || '').replace(/[-_]/g, ' '),
category: category,
searchableText: [
component.name || component.title,
component.description,
component.category,
...(component.tags || []),
...(Array.isArray(component.keywords) ? component.keywords : [component.keywords || '']),
component.path || ''
].filter(Boolean).join(' ').toLowerCase(),
// Ensure tags exist
tags: component.tags || [component.category].filter(Boolean)
}));
}
}
return;
}
}
// Fallback: direct fetch if DataLoader not available
const response = await fetch('components.json');
if (response.ok) {
const data = await response.json();
// Process each category for search
const categories = ['agents', 'commands', 'settings', 'hooks', 'mcps', 'skills'];
for (const category of categories) {
if (data[category] && Array.isArray(data[category])) {
// Process components to make them search-friendly
allComponents[category] = data[category].map(component => ({
...component,
// Normalize fields for better searching
title: component.name || component.title || 'Untitled',
displayName: (component.name || component.title || '').replace(/[-_]/g, ' '),
category: category,
searchableText: [
component.name || component.title,
component.description,
component.category,
...(component.tags || []),
...(Array.isArray(component.keywords) ? component.keywords : [component.keywords || '']),
component.path || ''
].filter(Boolean).join(' ').toLowerCase(),
// Ensure tags exist
tags: component.tags || [component.category].filter(Boolean)
}));
}
}
} else {
console.error('Failed to load components.json');
}
} catch (error) {
console.error('Error loading components for search:', error);
// Fallback: try to use cached data if available
if (window.getSearchData) {
const categories = ['agents', 'commands', 'settings', 'hooks', 'mcps', 'skills'];
for (const category of categories) {
const data = window.getSearchData(category);
if (data && data.length > 0) {
allComponents[category] = data;
}
}
}
}
}
/**
* Update URL with search parameter
*/
function updateURLWithSearch(query) {
const url = new URL(window.location);
if (query && query.length >= 3) {
url.searchParams.set('search', encodeURIComponent(query));
} else {
url.searchParams.delete('search');
}
window.history.replaceState({}, '', url);
}
/**
* Get search query from URL parameters
*/
function getSearchQueryFromURL() {
const params = new URLSearchParams(window.location.search);
return params.get('search') ? decodeURIComponent(params.get('search')) : null;
}
/**
* Update URL with filter using path-based routing
*/
function updateURLWithFilter(filter) {
const currentSearch = window.location.search; // Preserve search parameters
const newPath = `/${filter}${currentSearch}`;
window.history.pushState({}, '', newPath);
}
/**
* Get filter from URL path
*/
function getFilterFromURL() {
const path = window.location.pathname;
const segments = path.split('/').filter(segment => segment);
// Check if first segment is a valid filter
const validFilters = ['agents', 'commands', 'settings', 'hooks', 'mcps', 'skills', 'templates', 'plugins'];
const firstSegment = segments[0];
if (firstSegment && validFilters.includes(firstSegment)) {
return firstSegment;
}
// If no valid filter found and we're on root, default to skills
if (path === '/' || path === '') {
return 'skills';
}
return 'skills'; // Default fallback
}
/**
* Perform search across all loaded components
*/
function performSearch(query) {
if (!query || query.length < 3) {
updateSearchResults([]);
showFilters(); // Show filters when no search
updateURLWithSearch(''); // Clear URL parameter
return;
}
// Update URL with search query
updateURLWithSearch(query);
// Hide filters during search
hideFilters();
const normalizedQuery = query.toLowerCase().trim();
const results = [];
const categoryMatches = new Set();
// Search across all categories except templates
Object.keys(allComponents).forEach(category => {
if (category === 'templates') return; // Skip templates
const components = allComponents[category];
if (!components || !Array.isArray(components)) return;
components.forEach(component => {
const matchScore = calculateMatchScore(component, normalizedQuery, category);
if (matchScore > 0) {
results.push({
...component,
category: category,
matchScore: matchScore,
matchType: getMatchType(component, normalizedQuery, category)
});
categoryMatches.add(category);
}
});
});
// Sort by match score (highest first)
results.sort((a, b) => b.matchScore - a.matchScore);
searchResults = results;
updateSearchResults(results, categoryMatches);
displaySearchResults(results);
// Track search event
window.eventTracker?.track('search', {
query: query,
results_count: results.length,
categories_matched: Array.from(categoryMatches)
});
}
/**
* Calculate match score for a component
*/
function calculateMatchScore(component, query, category) {
let score = 0;
// Category name match (highest priority)
if (category.includes(query)) {
score += 100;
}
// Component name/title match
const name = (component.name || component.title || '').toLowerCase();
if (name.includes(query)) {
score += name.startsWith(query) ? 80 : 60;
}
// Description match
const description = (component.description || '').toLowerCase();
if (description.includes(query)) {
score += 30;
}
// Tags match
if (component.tags && Array.isArray(component.tags)) {
const tagMatch = component.tags.some(tag =>
tag.toLowerCase().includes(query)
);
if (tagMatch) {
score += 40;
}
}
// Keywords match (for settings/hooks)
if (component.keywords) {
const keywords = Array.isArray(component.keywords)
? component.keywords.join(' ').toLowerCase()
: String(component.keywords).toLowerCase();
const keywordMatch = keywords.includes(query);
if (keywordMatch) {
score += 25;
}
}
// Path match (for file-based components)
if (component.path) {
const pathMatch = component.path.toLowerCase().includes(query);
if (pathMatch) {
score += 15;
}
}
return score;
}
/**
* Get match type for display
*/
function getMatchType(component, query, category) {
const name = (component.name || component.title || '').toLowerCase();
const description = (component.description || '').toLowerCase();
if (category.includes(query)) return 'category';
if (name.includes(query)) return 'name';
if (description.includes(query)) return 'description';
if (component.tags && component.tags.some(tag => tag.toLowerCase().includes(query))) return 'tag';
if (component.keywords) {
const keywords = Array.isArray(component.keywords)
? component.keywords.join(' ').toLowerCase()
: String(component.keywords).toLowerCase();
if (keywords.includes(query)) return 'keyword';
}
if (component.path && component.path.toLowerCase().includes(query)) return 'path';
return 'other';
}
/**
* Update search results info display
*/
function updateSearchResults(results, categoryMatches = new Set()) {
const resultsInfo = document.getElementById('searchResultsInfo');
const resultsCount = document.getElementById('resultsCount');
const filterTags = document.getElementById('searchFilterTags');
if (results.length === 0) {
resultsInfo.style.display = 'none';
return;
}
resultsInfo.style.display = 'block';
// Update count with terminal-style format
const count = results.length;
resultsCount.textContent = `Found(${count} result${count !== 1 ? 's' : ''})`;
// Update category tags
if (categoryMatches.size > 0) {
const categoryIcons = {
agents: '🤖',
commands: '⚡',
settings: '⚙️',
hooks: '🪝',
mcps: '🔌',
skills: '🎨'
};
filterTags.innerHTML = '';
Array.from(categoryMatches).forEach(category => {
const icon = categoryIcons[category] || '';
const name = category.charAt(0).toUpperCase() + category.slice(1);
const span = document.createElement('span');
span.className = 'search-category-tag';
span.textContent = `${icon} ${name}`;
filterTags.appendChild(span);
});
} else {
filterTags.innerHTML = '';
}
}
/**
* Display search results in the grid
*/
function displaySearchResults(results) {
const unifiedGrid = document.getElementById('unifiedGrid');
if (!unifiedGrid) {
console.error('Unified grid not found');
return;
}
// Clear current content
unifiedGrid.innerHTML = '';
if (results.length === 0) {
// Show no results message
unifiedGrid.innerHTML = `
🔍
No components found
Try searching for:
- Categories: agents, commands, settings, hooks, mcps
- Technologies: react, python, git, telegram, api
- Features: security, performance, automation, notifications
`;
return;
}
// Group results by category for better organization
const groupedResults = {};
results.forEach(result => {
if (!groupedResults[result.category]) {
groupedResults[result.category] = [];
}
groupedResults[result.category].push(result);
});
// Render grouped results in specific order
let html = '';
const categoryOrder = ['agents', 'commands', 'settings', 'hooks', 'mcps', 'skills'];
categoryOrder.forEach(category => {
if (!groupedResults[category]) return;
const categoryResults = groupedResults[category];
const categoryIcon = getCategoryIcon(category);
const categoryName = category.charAt(0).toUpperCase() + category.slice(1);
html += `
`;
categoryResults.forEach(component => {
html += generateComponentCard(component, category);
});
html += `
`;
});
unifiedGrid.innerHTML = html;
}
/**
* Get category icon
*/
function getCategoryIcon(category) {
const icons = {
agents: '🤖',
commands: '⚡',
settings: '⚙️',
hooks: '🪝',
mcps: '🔌',
skills: '🎨'
};
return icons[category] || '📦';
}
/**
* Generate component card HTML (matching existing template-card format)
*/
function generateComponentCard(component, category) {
// Generate install command - remove .md extension from path
let componentPath = component.path || component.name;
// Remove .md or .json extensions from path
if (componentPath.endsWith('.md') || componentPath.endsWith('.json')) {
componentPath = componentPath.replace(/\.(md|json)$/, '');
}
const installCommand = `npx claude-code-templates@latest --${component.type}=${componentPath} --yes`;
const typeConfig = {
agent: { icon: '🤖', color: '#ff6b6b' },
command: { icon: '⚡', color: '#4ecdc4' },
mcp: { icon: '🔌', color: '#45b7d1' },
setting: { icon: '⚙️', color: '#9c88ff' },
hook: { icon: '🪝', color: '#ff8c42' },
skill: { icon: '🎨', color: '#f59e0b' }
};
const config = typeConfig[component.type];
// Escape quotes and special characters for onclick attributes
const escapedType = component.type.replace(/'/g, "\\'");
const escapedName = (component.name || '').replace(/'/g, "\\'");
const escapedPath = (component.path || component.name || '').replace(/'/g, "\\'");
const escapedCategory = (component.category || 'general').replace(/'/g, "\\'");
const escapedCommand = installCommand.replace(/'/g, "\\'");
// Create category label (use "General" if no category)
const categoryName = escapeHTML(component.category || 'general');
const categoryLabel = `${categoryName.charAt(0).toUpperCase() + categoryName.slice(1)}
`;
// Format component name
const formattedName = escapeHTML((component.name || '').split(/[-_]/).map(word =>
word.charAt(0).toUpperCase() + word.slice(1)
).join(' '));
// Get description
const description = component.description || 'Component for enhanced development workflow';
const truncatedDescription = escapeHTML(description.length > 80 ? description.substring(0, 80) + '...' : description);
return `
${categoryLabel}
${config.icon}
${formattedName}
${truncatedDescription}
Installation Command
${escapeHTML(installCommand)}
`;
}
/**
* Generate installation command for component
*/
function generateInstallCommand(component, category) {
let name = component.name || component.path || component.title;
let categoryParam = category.slice(0, -1); // Remove 's' from category name
// Handle special cases for category parameters
if (category === 'settings' || category === 'hooks') {
// Use the path if available for settings and hooks
if (component.path) {
name = component.path.replace(/\.(json|md)$/, ''); // Remove file extension
}
categoryParam = category.slice(0, -1); // 'setting' or 'hook'
}
return `npx claude-code-templates@latest --${categoryParam}=${name} --yes`;
}
/**
* Show all components except templates
*/
function showAllComponents() {
// This function should integrate with existing filter logic
if (typeof setUnifiedFilter === 'function') {
setUnifiedFilter('agents'); // Default to agents
}
}
// Search result cards now use the global click handler from index-events.js
// No need for custom toggleCard function
/**
* Initialize filter from URL parameters on page load
*/
function initializeFilterFromURL() {
const urlFilter = getFilterFromURL();
if (urlFilter && typeof setUnifiedFilter === 'function') {
setUnifiedFilter(urlFilter);
}
}
/**
* Initialize search from URL parameters on page load
*/
function initializeSearchFromURL() {
const urlQuery = getSearchQueryFromURL();
if (urlQuery) {
const searchInput = document.getElementById('searchInput');
if (searchInput) {
searchInput.value = urlQuery;
// Show search interface
const resultsInfo = document.getElementById('searchResultsInfo');
if (resultsInfo) {
resultsInfo.style.display = 'block';
}
// Show clear button
const clearBtn = document.getElementById('clearSearchBtn');
if (clearBtn) {
clearBtn.style.display = 'flex';
}
// Ensure components are loaded before searching
let attempts = 0;
const maxAttempts = 25; // 5 seconds total (200ms * 25)
const trySearch = () => {
attempts++;
if (Object.keys(allComponents).length > 0) {
performSearch(urlQuery);
} else if (attempts < maxAttempts) {
// If components not loaded, wait and try again
setTimeout(trySearch, 200);
} else {
console.error('Failed to load components for URL search after maximum attempts');
// Force load components and try one more time
loadComponentsForSearch().then(() => {
if (Object.keys(allComponents).length > 0) {
performSearch(urlQuery);
}
});
}
};
// Start trying to search
trySearch();
}
}
}
// Initialize search functionality when DOM is loaded
document.addEventListener('DOMContentLoaded', function() {
// Load components for search
loadComponentsForSearch();
// Initialize filter from URL if present
initializeFilterFromURL();
// Initialize search from URL if present
initializeSearchFromURL();
// Add CSS for search functionality if not already present
if (!document.getElementById('search-styles')) {
const searchStyles = document.createElement('style');
searchStyles.id = 'search-styles';
searchStyles.textContent = `
.search-btn.active {
background-color: var(--accent-color, #00d4aa) !important;
color: var(--bg-color, #0a0e0f) !important;
}
.search-bar-container {
margin-top: 1rem;
padding: 0 1rem;
animation: slideDown 0.3s ease-out;
}
@keyframes slideDown {
from { opacity: 0; transform: translateY(-10px); }
to { opacity: 1; transform: translateY(0); }
}
.search-input-wrapper {
position: relative;
display: flex;
align-items: center;
background: var(--card-bg, #1a1f23);
border: 1px solid var(--border-color, #2a3338);
border-radius: 8px;
padding: 0.75rem 1rem;
transition: border-color 0.2s ease;
}
.search-input-wrapper:focus-within {
border-color: var(--accent-color, #00d4aa);
box-shadow: 0 0 0 2px var(--accent-color, #00d4aa)20;
}
.search-icon {
margin-right: 0.75rem;
color: var(--text-dim, #8892a0);
}
.search-input {
flex: 1;
background: transparent;
border: none;
outline: none;
color: var(--text-color, #ffffff);
font-size: 1rem;
font-family: 'Inter', sans-serif;
}
.search-input::placeholder {
color: var(--text-dim, #8892a0);
}
.clear-search-btn {
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
margin-left: 0.5rem;
background: transparent;
border: none;
border-radius: 4px;
color: var(--text-dim, #8892a0);
cursor: pointer;
transition: all 0.2s ease;
}
.clear-search-btn:hover {
background: var(--hover-bg, #2a3338);
color: var(--text-color, #ffffff);
}
.search-results-info {
margin-top: 1rem;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 1rem;
}
.results-count {
color: var(--text-dim, #8892a0);
font-size: 0.9rem;
}
.search-filters {
display: flex;
align-items: center;
gap: 0.5rem;
flex-wrap: wrap;
}
.search-filter-label {
color: var(--text-dim, #8892a0);
font-size: 0.85rem;
}
.search-category-tag {
background: var(--accent-color, #00d4aa)20;
color: var(--accent-color, #00d4aa);
padding: 0.25rem 0.5rem;
border-radius: 4px;
font-size: 0.75rem;
font-weight: 500;
}
.no-search-results {
text-align: center;
padding: 3rem 2rem;
color: var(--text-dim, #8892a0);
}
.no-results-icon {
font-size: 4rem;
margin-bottom: 1rem;
}
.no-search-results h3 {
color: var(--text-color, #ffffff);
margin-bottom: 1rem;
}
.search-suggestions {
text-align: left;
max-width: 400px;
margin: 1.5rem auto 0;
}
.search-suggestions li {
margin-bottom: 0.5rem;
padding-left: 1rem;
}
.search-category-section {
margin-bottom: 2rem;
}
.search-category-header {
display: flex;
align-items: center;
gap: 0.75rem;
margin-bottom: 1rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid var(--border-color, #2a3338);
color: var(--text-color, #ffffff);
font-size: 1.25rem;
font-weight: 600;
}
.category-icon {
font-size: 1.5rem;
}
.search-category-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
}
.search-result-card {
transition: all 0.3s ease;
cursor: pointer;
}
/* Ensure search result cards inherit flip behavior */
.search-result-card .card-inner {
transition: transform 0.6s;
transform-style: preserve-3d;
}
.search-result-card.flipped .card-inner {
transform: rotateY(180deg);
}
.search-result-card .component-type-badge {
background: var(--accent-color, #00d4aa)20;
color: var(--accent-color, #00d4aa);
font-size: 0.75rem;
font-weight: 600;
text-transform: capitalize;
}
.search-result-card .card-title {
color: var(--text-primary, #ffffff);
font-size: 1.1rem;
font-weight: normal;
margin: 0.75rem 0 0.5rem 0;
text-transform: capitalize;
}
.search-result-card .card-description {
color: var(--text-secondary, #8892a0);
font-size: 0.8rem;
line-height: 1.4;
text-align: center;
margin-bottom: 1rem;
}
/* Card back should match main template card styles */
.search-result-card .card-back {
background: var(--bg-tertiary);
padding: 1.5rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
.search-result-card .card-tags {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-top: auto;
}
.search-result-card .tag {
background: var(--hover-bg, #2a3338);
color: var(--text-dim, #8892a0);
padding: 0.25rem 0.5rem;
border-radius: 4px;
font-size: 0.7rem;
font-weight: 500;
}
.search-result-card .tag-more {
background: var(--accent-color, #00d4aa)30;
color: var(--accent-color, #00d4aa);
padding: 0.25rem 0.5rem;
border-radius: 4px;
font-size: 0.7rem;
font-weight: 600;
}
.search-result-card .card-back h3 {
color: var(--text-primary, #ffffff);
font-size: 0.85rem;
font-weight: normal;
margin-bottom: 0.5rem;
text-align: center;
}
.search-result-card .command-display {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 0.5rem;
padding: 0;
}
.search-result-card .command-code-container {
position: relative;
width: 100%;
display: flex;
align-items: center;
background: var(--bg-tertiary);
border: 1px solid var(--border-secondary);
border-radius: 4px;
padding: 8px 12px;
margin-bottom: 0.5rem;
flex-shrink: 0;
}
.search-result-card .command-code {
flex: 1;
color: var(--text-primary, #ffffff);
font-size: 0.75rem;
font-family: 'Monaco', 'Menlo', monospace;
overflow-x: auto;
white-space: nowrap;
padding-right: 8px;
}
.search-result-card .copy-overlay-btn {
background: var(--text-accent, #00d4aa);
border: none;
color: var(--bg-primary, #0a0e0f);
padding: 4px 8px;
border-radius: 3px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 10px;
font-weight: 500;
display: flex;
align-items: center;
gap: 4px;
opacity: 0;
transform: translateX(10px);
position: absolute;
right: 6px;
z-index: 2;
}
.search-result-card .command-code-container:hover .copy-overlay-btn {
opacity: 1;
transform: translateX(0);
}
.search-result-card .copy-overlay-btn:hover {
background: var(--text-success, #22c55e);
transform: translateX(0) translateY(-1px);
box-shadow: 0 2px 8px rgba(0, 212, 170, 0.3);
}
.search-result-card .btn {
background: var(--accent-color, #00d4aa);
color: var(--bg-color, #0a0e0f);
border: none;
padding: 0.75rem 1rem;
border-radius: 6px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
width: 100%;
}
.search-result-card .btn:hover {
background: var(--accent-color, #00d4aa)90;
transform: translateY(-1px);
}
/* View Details and Add to Stack buttons */
.search-result-card .view-files-btn {
background: rgba(0, 255, 0, 0.2); /* Debug background */
border: 2px solid lime; /* Debug border */
color: var(--text-color, #ffffff);
padding: 0.4rem 0.6rem;
border-radius: 4px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
gap: 0.3rem;
width: 100%;
margin-bottom: 0;
font-size: 0.75rem;
}
.search-result-card .view-files-btn:hover {
background: var(--hover-bg, #2a3338);
border-color: var(--accent-color, #00d4aa);
transform: translateY(-1px);
}
.search-result-card .add-to-cart-btn {
background: rgba(255, 255, 0, 0.5); /* Debug background */
border: 2px solid yellow; /* Debug border */
color: black; /* Debug text color */
padding: 0.4rem 0.6rem;
border-radius: 4px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
gap: 0.3rem;
width: 100%;
font-size: 0.75rem;
}
.search-result-card .add-to-cart-btn:hover {
background: var(--accent-color, #00d4aa)90;
transform: translateY(-1px);
}
.search-result-card .add-to-cart-btn.added {
background: var(--success-color, #22c55e);
color: var(--bg-color, #0a0e0f);
}
/* Card actions container */
.search-result-card .card-actions {
display: flex;
flex-direction: column;
gap: 0.4rem;
width: 100%;
margin-top: auto;
background: rgba(255, 0, 0, 0.1); /* Debug background */
border: 1px solid red; /* Debug border */
padding: 4px; /* Debug padding */
}
@media (max-width: 768px) {
.search-results-info {
flex-direction: column;
align-items: flex-start;
}
.search-category-grid {
grid-template-columns: 1fr;
}
}
`;
document.head.appendChild(searchStyles);
}
});
/**
* Hide filter elements during search
*/
function hideFilters() {
const filterGroup = document.querySelector('.filter-group');
const componentCategories = document.getElementById('componentCategories');
if (filterGroup) {
filterGroup.style.display = 'none';
}
if (componentCategories) {
componentCategories.style.display = 'none';
}
}
/**
* Show filter elements when search is cleared
*/
function showFilters() {
const filterGroup = document.querySelector('.filter-group');
const componentCategories = document.getElementById('componentCategories');
if (filterGroup) {
filterGroup.style.display = 'flex';
}
if (componentCategories) {
componentCategories.style.display = 'block';
}
}