Merge branch 'embeddings-1' of https://git.cc24.dev/HSMW_CC24/forensic-pathways into embeddings-1
This commit is contained in:
		
						commit
						d3c4d7ccc4
					
				@ -91,119 +91,137 @@ const sortedTags = Object.entries(tagFrequency)
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  <!-- Advanced Filters Section -->
 | 
			
		||||
  <!-- Advanced Filters Section - COLLAPSIBLE -->
 | 
			
		||||
  <div class="filter-section">
 | 
			
		||||
    <div class="filter-card-compact">
 | 
			
		||||
      <div class="filter-header-compact">
 | 
			
		||||
        <h3>⚙️ Erweiterte Filter</h3>
 | 
			
		||||
        <button class="filter-reset" id="reset-advanced" title="Erweiterte Filter zurücksetzen">
 | 
			
		||||
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
 | 
			
		||||
            <polyline points="1 4 1 10 7 10"/>
 | 
			
		||||
            <path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/>
 | 
			
		||||
          </svg>
 | 
			
		||||
        </button>
 | 
			
		||||
        <div class="filter-header-controls">
 | 
			
		||||
          <button class="filter-reset" id="reset-advanced" title="Erweiterte Filter zurücksetzen">
 | 
			
		||||
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
 | 
			
		||||
              <polyline points="1 4 1 10 7 10"/>
 | 
			
		||||
              <path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/>
 | 
			
		||||
            </svg>
 | 
			
		||||
          </button>
 | 
			
		||||
          <button class="collapse-toggle" id="toggle-advanced" data-collapsed="true" title="Erweiterte Filter ein/ausblenden">
 | 
			
		||||
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
 | 
			
		||||
              <polyline points="6 9 12 15 18 9"></polyline>
 | 
			
		||||
            </svg>
 | 
			
		||||
          </button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      
 | 
			
		||||
      <div class="advanced-filters-compact">
 | 
			
		||||
        <div class="filter-grid-compact">
 | 
			
		||||
          <div class="filter-group">
 | 
			
		||||
            <label class="filter-label">Tool-Typ</label>
 | 
			
		||||
            <select id="type-select" class="filter-select">
 | 
			
		||||
              <option value="">Alle Typen</option>
 | 
			
		||||
              {toolTypes.map((type: string) => (
 | 
			
		||||
                <option value={type}>{type}</option>
 | 
			
		||||
              ))}
 | 
			
		||||
            </select>
 | 
			
		||||
      <div class="collapsible-content hidden" id="advanced-filters-content">
 | 
			
		||||
        <div class="advanced-filters-compact">
 | 
			
		||||
          <div class="filter-grid-compact">
 | 
			
		||||
            <div class="filter-group">
 | 
			
		||||
              <label class="filter-label">Tool-Typ</label>
 | 
			
		||||
              <select id="type-select" class="filter-select">
 | 
			
		||||
                <option value="">Alle Typen</option>
 | 
			
		||||
                {toolTypes.map((type: string) => (
 | 
			
		||||
                  <option value={type}>{type}</option>
 | 
			
		||||
                ))}
 | 
			
		||||
              </select>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div class="filter-group">
 | 
			
		||||
              <label class="filter-label">Skill Level</label>
 | 
			
		||||
              <select id="skill-select" class="filter-select">
 | 
			
		||||
                <option value="">Alle Level</option>
 | 
			
		||||
                {skillLevels.map((level: string) => (
 | 
			
		||||
                  <option value={level}>{level}</option>
 | 
			
		||||
                ))}
 | 
			
		||||
              </select>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div class="filter-group">
 | 
			
		||||
              <label class="filter-label">Plattform</label>
 | 
			
		||||
              <select id="platform-select" class="filter-select">
 | 
			
		||||
                <option value="">Alle Plattformen</option>
 | 
			
		||||
                {platforms.map((platform: string) => (
 | 
			
		||||
                  <option value={platform}>{platform}</option>
 | 
			
		||||
                ))}
 | 
			
		||||
              </select>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div class="filter-group">
 | 
			
		||||
              <label class="filter-label">Lizenztyp</label>
 | 
			
		||||
              <select id="license-select" class="filter-select">
 | 
			
		||||
                <option value="">Alle Lizenzen</option>
 | 
			
		||||
                {licenses.map((license: string) => (
 | 
			
		||||
                  <option value={license}>{license}</option>
 | 
			
		||||
                ))}
 | 
			
		||||
              </select>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div class="filter-group">
 | 
			
		||||
              <label class="filter-label">Zugangsart</label>
 | 
			
		||||
              <select id="access-select" class="filter-select">
 | 
			
		||||
                <option value="">Alle Zugangsarten</option>
 | 
			
		||||
                {accessTypes.map((access: string) => (
 | 
			
		||||
                  <option value={access}>{access}</option>
 | 
			
		||||
                ))}
 | 
			
		||||
              </select>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
          <div class="filter-group">
 | 
			
		||||
            <label class="filter-label">Skill Level</label>
 | 
			
		||||
            <select id="skill-select" class="filter-select">
 | 
			
		||||
              <option value="">Alle Level</option>
 | 
			
		||||
              {skillLevels.map((level: string) => (
 | 
			
		||||
                <option value={level}>{level}</option>
 | 
			
		||||
              ))}
 | 
			
		||||
            </select>
 | 
			
		||||
          <div class="filter-toggles-compact">
 | 
			
		||||
            <label class="toggle-wrapper">
 | 
			
		||||
              <input type="checkbox" id="hosted-only" />
 | 
			
		||||
              <span class="toggle-label">🟣 Nur CC24-Server Tools</span>
 | 
			
		||||
            </label>
 | 
			
		||||
            
 | 
			
		||||
            <label class="toggle-wrapper">
 | 
			
		||||
              <input type="checkbox" id="knowledgebase-only" />
 | 
			
		||||
              <span class="toggle-label">📖 Nur Tools mit Knowledgebase</span>
 | 
			
		||||
            </label>
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
          <div class="filter-group">
 | 
			
		||||
            <label class="filter-label">Plattform</label>
 | 
			
		||||
            <select id="platform-select" class="filter-select">
 | 
			
		||||
              <option value="">Alle Plattformen</option>
 | 
			
		||||
              {platforms.map((platform: string) => (
 | 
			
		||||
                <option value={platform}>{platform}</option>
 | 
			
		||||
              ))}
 | 
			
		||||
            </select>
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
          <div class="filter-group">
 | 
			
		||||
            <label class="filter-label">Lizenztyp</label>
 | 
			
		||||
            <select id="license-select" class="filter-select">
 | 
			
		||||
              <option value="">Alle Lizenzen</option>
 | 
			
		||||
              {licenses.map((license: string) => (
 | 
			
		||||
                <option value={license}>{license}</option>
 | 
			
		||||
              ))}
 | 
			
		||||
            </select>
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
          <div class="filter-group">
 | 
			
		||||
            <label class="filter-label">Zugangsart</label>
 | 
			
		||||
            <select id="access-select" class="filter-select">
 | 
			
		||||
              <option value="">Alle Zugangsarten</option>
 | 
			
		||||
              {accessTypes.map((access: string) => (
 | 
			
		||||
                <option value={access}>{access}</option>
 | 
			
		||||
              ))}
 | 
			
		||||
            </select>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="filter-toggles-compact">
 | 
			
		||||
          <label class="toggle-wrapper">
 | 
			
		||||
            <input type="checkbox" id="hosted-only" />
 | 
			
		||||
            <span class="toggle-label">🟣 Nur CC24-Server Tools</span>
 | 
			
		||||
          </label>
 | 
			
		||||
          
 | 
			
		||||
          <label class="toggle-wrapper">
 | 
			
		||||
            <input type="checkbox" id="knowledgebase-only" />
 | 
			
		||||
            <span class="toggle-label">📖 Nur Tools mit Knowledgebase</span>
 | 
			
		||||
          </label>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  <!-- Tag Filters Section -->
 | 
			
		||||
  <!-- Tag Filters Section - COLLAPSIBLE -->
 | 
			
		||||
  <div class="filter-section">
 | 
			
		||||
    <div class="filter-card-compact">
 | 
			
		||||
      <div class="filter-header-compact">
 | 
			
		||||
        <h3>🏷️ Tag-Filter</h3>
 | 
			
		||||
        <div class="tag-controls">
 | 
			
		||||
        <div class="filter-header-controls">
 | 
			
		||||
          <button class="filter-reset" id="reset-tags" title="Tags zurücksetzen">
 | 
			
		||||
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
 | 
			
		||||
              <polyline points="1 4 1 10 7 10"/>
 | 
			
		||||
              <path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/>
 | 
			
		||||
            </svg>
 | 
			
		||||
          </button>
 | 
			
		||||
          <button id="tag-cloud-toggle" class="tag-toggle" data-expanded="false">
 | 
			
		||||
            Mehr zeigen
 | 
			
		||||
          <button class="collapse-toggle" id="toggle-tags" data-collapsed="true" title="Tag-Filter ein/ausblenden">
 | 
			
		||||
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
 | 
			
		||||
              <polyline points="6 9 12 15 18 9"></polyline>
 | 
			
		||||
            </svg>
 | 
			
		||||
          </button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      
 | 
			
		||||
      <div class="tag-section">
 | 
			
		||||
        <div class="selected-tags" id="selected-tags"></div>
 | 
			
		||||
        <div class="tag-cloud" id="tag-cloud">
 | 
			
		||||
          {sortedTags.map((tag, index) => (
 | 
			
		||||
            <button 
 | 
			
		||||
              class="tag-cloud-item" 
 | 
			
		||||
              data-tag={tag}
 | 
			
		||||
              data-frequency={tagFrequency[tag]}
 | 
			
		||||
              data-index={index}
 | 
			
		||||
            >
 | 
			
		||||
              {tag}
 | 
			
		||||
              <span class="tag-frequency">({tagFrequency[tag]})</span>
 | 
			
		||||
      <div class="collapsible-content hidden" id="tag-filters-content">
 | 
			
		||||
        <div class="tag-section">
 | 
			
		||||
          <div class="selected-tags" id="selected-tags"></div>
 | 
			
		||||
          <div class="tag-controls">
 | 
			
		||||
            <button id="tag-cloud-toggle" class="tag-toggle" data-expanded="false">
 | 
			
		||||
              Mehr zeigen
 | 
			
		||||
            </button>
 | 
			
		||||
          ))}
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="tag-cloud" id="tag-cloud">
 | 
			
		||||
            {sortedTags.map((tag, index) => (
 | 
			
		||||
              <button 
 | 
			
		||||
                class="tag-cloud-item" 
 | 
			
		||||
                data-tag={tag}
 | 
			
		||||
                data-frequency={tagFrequency[tag]}
 | 
			
		||||
                data-index={index}
 | 
			
		||||
              >
 | 
			
		||||
                {tag}
 | 
			
		||||
                <span class="tag-frequency">({tagFrequency[tag]})</span>
 | 
			
		||||
              </button>
 | 
			
		||||
            ))}
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
@ -293,7 +311,12 @@ const sortedTags = Object.entries(tagFrequency)
 | 
			
		||||
        advanced: document.getElementById('reset-advanced'),
 | 
			
		||||
        tags: document.getElementById('reset-tags'),
 | 
			
		||||
        all: document.getElementById('reset-all-filters')
 | 
			
		||||
      }
 | 
			
		||||
      },
 | 
			
		||||
      // Collapsible elements
 | 
			
		||||
      toggleAdvanced: document.getElementById('toggle-advanced'),
 | 
			
		||||
      toggleTags: document.getElementById('toggle-tags'),
 | 
			
		||||
      advancedContent: document.getElementById('advanced-filters-content'),
 | 
			
		||||
      tagContent: document.getElementById('tag-filters-content')
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    // Verify critical elements exist
 | 
			
		||||
@ -307,6 +330,52 @@ const sortedTags = Object.entries(tagFrequency)
 | 
			
		||||
    let selectedPhase = '';
 | 
			
		||||
    let isTagCloudExpanded = false;
 | 
			
		||||
    
 | 
			
		||||
    // Collapsible functionality
 | 
			
		||||
    function toggleCollapsible(toggleBtn, content, storageKey) {
 | 
			
		||||
      const isCollapsed = toggleBtn.getAttribute('data-collapsed') === 'true';
 | 
			
		||||
      const newState = !isCollapsed;
 | 
			
		||||
      
 | 
			
		||||
      toggleBtn.setAttribute('data-collapsed', newState.toString());
 | 
			
		||||
      
 | 
			
		||||
      if (newState) {
 | 
			
		||||
        // Collapse
 | 
			
		||||
        content.classList.add('hidden');
 | 
			
		||||
        toggleBtn.style.transform = 'rotate(0deg)';
 | 
			
		||||
      } else {
 | 
			
		||||
        // Expand
 | 
			
		||||
        content.classList.remove('hidden');
 | 
			
		||||
        toggleBtn.style.transform = 'rotate(180deg)';
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      // Store state in sessionStorage
 | 
			
		||||
      sessionStorage.setItem(storageKey, newState.toString());
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Initialize collapsible sections (collapsed by default)
 | 
			
		||||
    function initializeCollapsible() {
 | 
			
		||||
      // Advanced filters
 | 
			
		||||
      const advancedCollapsed = sessionStorage.getItem('advanced-collapsed') !== 'false';
 | 
			
		||||
      elements.toggleAdvanced.setAttribute('data-collapsed', advancedCollapsed.toString());
 | 
			
		||||
      if (advancedCollapsed) {
 | 
			
		||||
        elements.advancedContent.classList.add('hidden');
 | 
			
		||||
        elements.toggleAdvanced.style.transform = 'rotate(0deg)';
 | 
			
		||||
      } else {
 | 
			
		||||
        elements.advancedContent.classList.remove('hidden');
 | 
			
		||||
        elements.toggleAdvanced.style.transform = 'rotate(180deg)';
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      // Tag filters
 | 
			
		||||
      const tagsCollapsed = sessionStorage.getItem('tags-collapsed') !== 'false';
 | 
			
		||||
      elements.toggleTags.setAttribute('data-collapsed', tagsCollapsed.toString());
 | 
			
		||||
      if (tagsCollapsed) {
 | 
			
		||||
        elements.tagContent.classList.add('hidden');
 | 
			
		||||
        elements.toggleTags.style.transform = 'rotate(0deg)';
 | 
			
		||||
      } else {
 | 
			
		||||
        elements.tagContent.classList.remove('hidden');
 | 
			
		||||
        elements.toggleTags.style.transform = 'rotate(180deg)';
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Helper function to check if tool is hosted
 | 
			
		||||
    function isToolHosted(tool) {
 | 
			
		||||
      return tool.projectUrl !== undefined && 
 | 
			
		||||
@ -418,18 +487,23 @@ const sortedTags = Object.entries(tagFrequency)
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Add/remove tags
 | 
			
		||||
    // Add/remove tags - FIXED: Update ALL matching elements
 | 
			
		||||
    function addTag(tag) {
 | 
			
		||||
      selectedTags.add(tag);
 | 
			
		||||
      document.querySelector(`[data-tag="${tag}"]`).classList.add('active');
 | 
			
		||||
      // FIXED: Use querySelectorAll to update ALL matching tag elements
 | 
			
		||||
      document.querySelectorAll(`[data-tag="${tag}"]`).forEach(element => {
 | 
			
		||||
        element.classList.add('active');
 | 
			
		||||
      });
 | 
			
		||||
      updateSelectedTags();
 | 
			
		||||
      filterTools();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function removeTag(tag) {
 | 
			
		||||
      selectedTags.delete(tag);
 | 
			
		||||
      const tagElement = document.querySelector(`[data-tag="${tag}"]`);
 | 
			
		||||
      if (tagElement) tagElement.classList.remove('active');
 | 
			
		||||
      // FIXED: Use querySelectorAll to update ALL matching tag elements
 | 
			
		||||
      document.querySelectorAll(`[data-tag="${tag}"]`).forEach(element => {
 | 
			
		||||
        element.classList.remove('active');
 | 
			
		||||
      });
 | 
			
		||||
      updateSelectedTags();
 | 
			
		||||
      filterTools();
 | 
			
		||||
    }
 | 
			
		||||
@ -553,7 +627,10 @@ const sortedTags = Object.entries(tagFrequency)
 | 
			
		||||
    
 | 
			
		||||
    function resetTags() {
 | 
			
		||||
      selectedTags.clear();
 | 
			
		||||
      elements.tagCloudItems.forEach(item => item.classList.remove('active'));
 | 
			
		||||
      // FIXED: Update ALL tag elements
 | 
			
		||||
      document.querySelectorAll('.tag-cloud-item').forEach(item => {
 | 
			
		||||
        item.classList.remove('active');
 | 
			
		||||
      });
 | 
			
		||||
      updateSelectedTags();
 | 
			
		||||
      filterTools();
 | 
			
		||||
    }
 | 
			
		||||
@ -630,11 +707,21 @@ const sortedTags = Object.entries(tagFrequency)
 | 
			
		||||
    elements.resetButtons.tags.addEventListener('click', resetTags);
 | 
			
		||||
    elements.resetButtons.all.addEventListener('click', resetAllFilters);
 | 
			
		||||
    
 | 
			
		||||
    // Collapsible toggle listeners
 | 
			
		||||
    elements.toggleAdvanced.addEventListener('click', () => {
 | 
			
		||||
      toggleCollapsible(elements.toggleAdvanced, elements.advancedContent, 'advanced-collapsed');
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    elements.toggleTags.addEventListener('click', () => {
 | 
			
		||||
      toggleCollapsible(elements.toggleTags, elements.tagContent, 'tags-collapsed');
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    // Expose functions globally for backwards compatibility
 | 
			
		||||
    window.clearTagFilters = resetTags;
 | 
			
		||||
    window.clearAllFilters = resetAllFilters;
 | 
			
		||||
    
 | 
			
		||||
    // Initialize
 | 
			
		||||
    initializeCollapsible();
 | 
			
		||||
    initTagCloud();
 | 
			
		||||
    filterTagCloud();
 | 
			
		||||
    updateSelectedTags();
 | 
			
		||||
 | 
			
		||||
@ -1263,6 +1263,12 @@ input[type="checkbox"] {
 | 
			
		||||
  gap: 0.5rem; 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.filter-header-controls {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  gap: 0.5rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Search Components */
 | 
			
		||||
.search-wrapper { 
 | 
			
		||||
  position: relative; 
 | 
			
		||||
@ -1315,6 +1321,64 @@ input[type="checkbox"] {
 | 
			
		||||
  color: var(--color-text);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.collapse-toggle {
 | 
			
		||||
  background: none;
 | 
			
		||||
  border: 1px solid var(--color-border);
 | 
			
		||||
  border-radius: 0.375rem;
 | 
			
		||||
  color: var(--color-text-secondary);
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  padding: 0.375rem;
 | 
			
		||||
  transition: var(--transition-fast);
 | 
			
		||||
  display: inline-flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  width: 32px;
 | 
			
		||||
  height: 32px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.collapse-toggle:hover {
 | 
			
		||||
  background-color: var(--color-bg-secondary);
 | 
			
		||||
  border-color: var(--color-primary);
 | 
			
		||||
  color: var(--color-text);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.collapse-toggle svg {
 | 
			
		||||
  transition: transform var(--transition-medium);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* When expanded, rotate the chevron */
 | 
			
		||||
.collapse-toggle[data-collapsed="false"] svg {
 | 
			
		||||
  transform: rotate(180deg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Collapsible Content */
 | 
			
		||||
.collapsible-content {
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  transition: all var(--transition-medium);
 | 
			
		||||
  opacity: 1;
 | 
			
		||||
  max-height: 1000px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.collapsible-content.hidden {
 | 
			
		||||
  opacity: 0;
 | 
			
		||||
  max-height: 0;
 | 
			
		||||
  padding-top: 0;
 | 
			
		||||
  padding-bottom: 0;
 | 
			
		||||
  margin-top: 0;
 | 
			
		||||
  margin-bottom: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Smooth animation for expanding content */
 | 
			
		||||
.collapsible-content:not(.hidden) {
 | 
			
		||||
  animation: expandContent 0.3s ease-out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Content spacing when expanded */
 | 
			
		||||
.collapsible-content:not(.hidden) .advanced-filters-compact,
 | 
			
		||||
.collapsible-content:not(.hidden) .tag-section {
 | 
			
		||||
  padding-top: 0.75rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Filter Grids & Groups */
 | 
			
		||||
.filter-grid-compact { 
 | 
			
		||||
  display: grid; 
 | 
			
		||||
@ -1429,11 +1493,9 @@ input[type="checkbox"] {
 | 
			
		||||
  user-select: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Tag System */
 | 
			
		||||
.tag-section {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  gap: 1rem;
 | 
			
		||||
.tag-section .tag-controls {
 | 
			
		||||
  order: -1; 
 | 
			
		||||
  margin-bottom: 0.75rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.selected-tags { 
 | 
			
		||||
@ -1574,6 +1636,14 @@ input[type="checkbox"] {
 | 
			
		||||
  transition: var(--transition-fast); 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.filter-reset {
 | 
			
		||||
  width: 32px;
 | 
			
		||||
  height: 32px;
 | 
			
		||||
  display: inline-flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.filter-reset:hover { 
 | 
			
		||||
  background-color: var(--color-bg-secondary); 
 | 
			
		||||
  border-color: var(--color-warning); 
 | 
			
		||||
@ -1591,13 +1661,6 @@ input[type="checkbox"] {
 | 
			
		||||
  opacity: 0.9;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Tag Controls */
 | 
			
		||||
.tag-controls { 
 | 
			
		||||
  display: flex; 
 | 
			
		||||
  align-items: center; 
 | 
			
		||||
  gap: 0.75rem; 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.tag-toggle { 
 | 
			
		||||
  padding: 0.375rem 0.75rem; 
 | 
			
		||||
  border: 1px solid var(--color-border); 
 | 
			
		||||
@ -2391,6 +2454,17 @@ footer {
 | 
			
		||||
  to { opacity: 1; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@keyframes expandContent {
 | 
			
		||||
  from {
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
    transform: translateY(-10px);
 | 
			
		||||
  }
 | 
			
		||||
  to {
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
    transform: translateY(0);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@keyframes fadeInUp {
 | 
			
		||||
  from {
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
@ -3385,6 +3459,23 @@ footer {
 | 
			
		||||
  .view-toggle {
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .filter-header-controls {
 | 
			
		||||
    gap: 0.375rem;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  .collapse-toggle,
 | 
			
		||||
  .filter-reset {
 | 
			
		||||
    width: 28px;
 | 
			
		||||
    height: 28px;
 | 
			
		||||
    padding: 0.25rem;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  .collapse-toggle svg,
 | 
			
		||||
  .filter-reset svg {
 | 
			
		||||
    width: 14px;
 | 
			
		||||
    height: 14px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (width <= 640px) {
 | 
			
		||||
@ -3519,6 +3610,21 @@ footer {
 | 
			
		||||
  .filter-card-compact {
 | 
			
		||||
    padding: 0.5rem;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .filter-header-compact {
 | 
			
		||||
    flex-wrap: wrap;
 | 
			
		||||
    gap: 0.5rem;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  .filter-header-compact h3 {
 | 
			
		||||
    flex: 1 1 100%;
 | 
			
		||||
    margin-bottom: 0.25rem;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  .filter-header-controls {
 | 
			
		||||
    flex: 1 1 100%;
 | 
			
		||||
    justify-content: flex-end;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user