<!DOCTYPE html>
<html lang="no">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Søkbar inventarliste</title>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
            line-height: 1.6;
            color: #333;
            background: #f5f5f5;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }

        header {
            background: white;
            padding: 20px;
            margin-bottom: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }

        h1 {
            color: #2c3e50;
            margin-bottom: 10px;
        }

        /* Intro section markdown styling */
        #introText h3 {
            color: #2c3e50;
            font-size: 16px;
            margin-top: 15px;
            margin-bottom: 8px;
            font-weight: 600;
        }

        #introText p {
            margin-bottom: 10px;
        }

        #introText ul {
            margin-left: 20px;
            margin-bottom: 10px;
        }

        #introText li {
            margin-bottom: 4px;
        }

        .search-container {
            background: white;
            padding: 20px;
            margin-bottom: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }

        .search-box {
            width: 100%;
            padding: 12px 20px;
            font-size: 16px;
            border: 2px solid #ddd;
            border-radius: 6px;
            margin-bottom: 15px;
            transition: border-color 0.3s;
        }

        .search-box:focus {
            outline: none;
            border-color: #3498db;
        }

        .filters {
            display: flex;
            gap: 10px;
            flex-wrap: wrap;
        }

        .filter-btn {
            padding: 8px 16px;
            background: #ecf0f1;
            border: 2px solid transparent;
            border-radius: 6px;
            cursor: pointer;
            transition: all 0.3s;
            font-size: 14px;
        }

        .filter-btn:hover {
            background: #d5dbdd;
        }

        .filter-btn.active {
            background: #3498db;
            color: white;
            border-color: #2980b9;
        }

        .view-toggle {
            display: flex;
            gap: 10px;
            margin-top: 15px;
            flex-wrap: wrap;
        }

        .view-btn {
            padding: 10px 20px;
            background: #ecf0f1;
            border: 2px solid transparent;
            border-radius: 6px;
            cursor: pointer;
            transition: all 0.3s;
            font-size: 15px;
            font-weight: 500;
        }

        .view-btn:hover {
            background: #d5dbdd;
        }

        .view-btn.active {
            background: #2ecc71;
            color: white;
            border-color: #27ae60;
        }

        .gallery-view {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }

        .gallery-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
            gap: 20px;
        }

        /* Shopping list styles */
        .shopping-list {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }

        .shopping-list h1 {
            color: #2c3e50;
            margin-bottom: 10px;
            font-size: 1.5em;
        }

        .shopping-list h2 {
            color: #34495e;
            margin-top: 20px;
            margin-bottom: 10px;
            font-size: 1.2em;
            border-bottom: 2px solid #ecf0f1;
            padding-bottom: 5px;
        }

        .shopping-list p {
            color: #7f8c8d;
            margin-bottom: 15px;
        }

        .shopping-item {
            padding: 8px 12px;
            margin: 4px 0;
            border-radius: 4px;
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .shopping-item.missing {
            background: #ffebee;
            border-left: 4px solid #e74c3c;
        }

        .shopping-item.low {
            background: #fff8e1;
            border-left: 4px solid #f39c12;
        }

        .shopping-item input[type="checkbox"] {
            width: 18px;
            height: 18px;
            cursor: pointer;
        }

        .shopping-item.checked {
            opacity: 0.5;
            text-decoration: line-through;
        }

        .shopping-summary {
            margin-top: 20px;
            padding: 15px;
            background: #ecf0f1;
            border-radius: 4px;
            font-weight: 500;
        }

        .gallery-image-wrapper {
            position: relative;
            background: #f0f0f0;
            border-radius: 8px;
            overflow: hidden;
            cursor: pointer;
            transition: transform 0.2s, box-shadow 0.2s;
        }

        .gallery-image-wrapper:hover {
            transform: translateY(-4px);
            box-shadow: 0 6px 12px rgba(0,0,0,0.15);
        }

        .gallery-image-wrapper img {
            width: 100%;
            height: 200px;
            object-fit: cover;
            display: block;
            opacity: 0;
            transition: opacity 0.3s;
        }

        .gallery-image-wrapper img.loaded {
            opacity: 1;
        }

        .image-metadata {
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
            background: linear-gradient(to top, rgba(0,0,0,0.8), transparent);
            padding: 30px 10px 8px;
            color: white;
            font-size: 13px;
        }

        .image-container-id {
            font-weight: bold;
            font-size: 14px;
        }

        .image-number {
            opacity: 0.8;
            font-size: 11px;
        }

        .lightbox-nav {
            position: absolute;
            top: 50%;
            transform: translateY(-50%);
            background: rgba(255, 255, 255, 0.2);
            border: 2px solid white;
            color: white;
            font-size: 30px;
            padding: 10px 20px;
            cursor: pointer;
            user-select: none;
            border-radius: 4px;
            transition: background 0.3s;
        }

        .lightbox-nav:hover {
            background: rgba(255, 255, 255, 0.3);
        }

        .lightbox-prev {
            left: 20px;
        }

        .lightbox-next {
            right: 20px;
        }

        .lightbox-info {
            position: absolute;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            background: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 10px 20px;
            border-radius: 6px;
            font-size: 14px;
        }

        .stats {
            margin-top: 15px;
            padding: 10px;
            background: #f8f9fa;
            border-radius: 6px;
            font-size: 14px;
            color: #666;
        }

        .container-card {
            background: white;
            margin-bottom: 15px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            overflow: hidden;
            transition: box-shadow 0.3s;
        }

        .container-card:hover {
            box-shadow: 0 4px 8px rgba(0,0,0,0.15);
        }

        .container-header {
            padding: 15px 20px;
            background: #34495e;
            color: white;
            cursor: pointer;
            display: flex;
            justify-content: space-between;
            align-items: center;
            user-select: none;
        }

        .container-header:hover {
            background: #2c3e50;
        }

        .container-id {
            font-weight: bold;
            font-size: 18px;
        }

        .container-title {
            flex: 1;
            margin-left: 15px;
            font-size: 14px;
            opacity: 0.9;
        }

        .toggle-icon {
            font-size: 20px;
            transition: transform 0.3s;
        }

        .container-card.expanded .toggle-icon {
            transform: rotate(180deg);
        }

        .container-content {
            max-height: 0;
            overflow: hidden;
            transition: max-height 0.3s ease-out;
        }

        .container-card.expanded .container-content {
            max-height: 10000px;
            transition: max-height 0.5s ease-in;
        }

        .container-details {
            padding: 20px;
        }

        .container-description {
            margin-bottom: 15px;
            padding: 10px;
            background: #f8f9fa;
            border-left: 4px solid #3498db;
            border-radius: 4px;
        }

        .items-list {
            margin-bottom: 20px;
        }

        .items-list h3 {
            font-size: 16px;
            margin-bottom: 10px;
            color: #2c3e50;
        }

        .items-list ul {
            list-style-position: inside;
            padding-left: 10px;
        }

        .items-list li {
            margin-bottom: 5px;
            color: #555;
        }

        .items-list li.item-matches-filter {
            background: linear-gradient(90deg, #fff3e0 0%, transparent 100%);
            border-left: 3px solid #ff9800;
            padding-left: 8px;
            margin-left: -11px;
        }

        .highlight {
            background: yellow;
            padding: 2px 4px;
            border-radius: 2px;
        }

        .images-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
            gap: 15px;
            margin-top: 15px;
        }

        .image-wrapper {
            position: relative;
            padding-bottom: 75%;
            background: #f0f0f0;
            border-radius: 6px;
            overflow: hidden;
            cursor: pointer;
        }

        .image-wrapper img {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            object-fit: cover;
            opacity: 0;
            transition: opacity 0.3s;
        }

        .image-wrapper img.loaded {
            opacity: 1;
        }

        .image-wrapper:hover img {
            transform: scale(1.05);
        }

        .photos-link {
            display: inline-block;
            margin-bottom: 10px;
            padding: 8px 16px;
            background: #3498db;
            color: white;
            text-decoration: none;
            border-radius: 6px;
            font-size: 14px;
            transition: background 0.3s;
        }

        .photos-link:hover {
            background: #2980b9;
        }

        .no-results {
            text-align: center;
            padding: 40px;
            background: white;
            border-radius: 8px;
            color: #999;
        }

        .loading {
            text-align: center;
            padding: 40px;
            color: #666;
        }

        .lightbox {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.9);
            z-index: 1000;
            justify-content: center;
            align-items: center;
        }

        .lightbox.active {
            display: flex;
        }

        .lightbox img {
            max-width: 90%;
            max-height: 90%;
            object-fit: contain;
        }

        .lightbox-close {
            position: absolute;
            top: 20px;
            right: 40px;
            font-size: 40px;
            color: white;
            cursor: pointer;
            user-select: none;
        }

        /* Error Modal */
        .error-modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            z-index: 2000;
            justify-content: center;
            align-items: center;
        }

        .error-modal.active {
            display: flex;
        }

        .error-modal-content {
            background: white;
            padding: 24px;
            border-radius: 8px;
            max-width: 600px;
            max-height: 80vh;
            overflow-y: auto;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
        }

        .error-modal-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 16px;
        }

        .error-modal-title {
            font-size: 18px;
            font-weight: 600;
            color: #d32f2f;
        }

        .error-modal-close {
            font-size: 28px;
            cursor: pointer;
            color: #666;
            line-height: 1;
            user-select: none;
        }

        .error-modal-close:hover {
            color: #333;
        }

        .error-modal-message {
            background: #ffebee;
            border-left: 4px solid #d32f2f;
            padding: 12px;
            border-radius: 4px;
            font-family: monospace;
            white-space: pre-wrap;
            word-break: break-word;
            user-select: text;
            cursor: text;
            max-height: 400px;
            overflow-y: auto;
        }

        .error-modal-actions {
            margin-top: 16px;
            display: flex;
            justify-content: flex-end;
            gap: 8px;
        }

        .error-modal-btn {
            padding: 8px 16px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: background 0.2s;
        }

        .error-modal-btn-copy {
            background: #2196f3;
            color: white;
        }

        .error-modal-btn-copy:hover {
            background: #1976d2;
        }

        .error-modal-btn-close {
            background: #f5f5f5;
            color: #333;
        }

        .error-modal-btn-close:hover {
            background: #e0e0e0;
        }

        /* Category Detail Modal */
        .category-modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            z-index: 2000;
            justify-content: center;
            align-items: center;
        }

        .category-modal.active {
            display: flex;
        }

        .category-modal-content {
            background: white;
            padding: 24px;
            border-radius: 8px;
            max-width: 650px;
            width: 90%;
            max-height: 85vh;
            overflow-y: auto;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
        }

        .category-modal-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 16px;
        }

        .category-modal-title {
            font-size: 18px;
            font-weight: 600;
            color: #333;
        }

        .category-modal-close {
            font-size: 28px;
            cursor: pointer;
            color: #666;
            line-height: 1;
            user-select: none;
        }

        .category-modal-close:hover {
            color: #333;
        }

        .category-modal-section {
            margin-bottom: 14px;
        }

        .category-modal-section-title {
            font-weight: 600;
            font-size: 13px;
            color: #555;
            text-transform: uppercase;
            letter-spacing: 0.5px;
            margin-bottom: 4px;
        }

        .category-modal-description {
            line-height: 1.5;
            color: #444;
            font-style: italic;
        }

        .category-modal-links {
            display: flex;
            flex-wrap: wrap;
            gap: 6px;
        }

        .category-modal-links a {
            color: #0066cc;
            text-decoration: none;
            padding: 2px 8px;
            background: #f0f4f8;
            border-radius: 4px;
            font-size: 13px;
        }

        .category-modal-links a:hover {
            background: #dce6f0;
        }

        .parent-link {
            color: #3498db;
            text-decoration: none;
            padding: 2px 6px;
            border-radius: 3px;
            transition: background 0.2s;
            display: inline-block;
            margin-left: 10px;
        }

        .parent-link:hover {
            background: rgba(52, 152, 219, 0.1);
            text-decoration: none;
        }

        .item-link {
            color: #3498db;
            text-decoration: none;
            cursor: pointer;
            transition: background 0.2s;
            display: inline-block;
        }

        .item-link:hover {
            text-decoration: underline;
        }

        .item-link .item-id {
            background: #e3f2fd;
            color: #1976d2;
        }

        .item-link:hover .item-id {
            background: #bbdefb;
        }

        .tag-badge {
            display: inline-block;
            background: #e8f5e9;
            color: #2e7d32;
            padding: 2px 8px;
            border-radius: 12px;
            font-size: 11px;
            margin-left: 4px;
            font-weight: 500;
        }

        .tag-badge:hover {
            background: #c8e6c9;
            cursor: pointer;
        }

        .item-photo-btn {
            cursor: pointer;
            font-size: 14px;
            padding: 2px 4px;
            border-radius: 4px;
            transition: background 0.2s;
        }

        .item-photo-btn:hover {
            background: #e3f2fd;
        }

        .tag-filter-btn {
            padding: 6px 12px;
            border: 1px solid #ddd;
            background: white;
            border-radius: 16px;
            cursor: pointer;
            font-size: 13px;
            transition: all 0.2s;
        }

        .tag-filter-btn:hover {
            background: #f5f5f5;
            border-color: #aaa;
        }

        .tag-filter-btn.active {
            background: #e8f5e9;
            border-color: #2e7d32;
            color: #2e7d32;
            font-weight: 500;
        }

        /* ==================== CATEGORY BROWSER ==================== */

        .category-browser {
            margin-top: 15px;
            background: #fafafa;
            border: 1px solid #e0e0e0;
            border-radius: 8px;
            overflow: hidden;
        }

        .category-browser-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 12px 15px;
            background: #f5f5f5;
            border-bottom: 1px solid #e0e0e0;
            cursor: pointer;
            user-select: none;
        }

        .category-browser-header:hover {
            background: #eeeeee;
        }

        .category-browser-title {
            font-weight: 500;
            color: #333;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .category-browser-clear {
            padding: 4px 10px;
            font-size: 12px;
            background: #fff;
            border: 1px solid #ddd;
            border-radius: 4px;
            cursor: pointer;
            color: #666;
        }

        .category-browser-clear:hover {
            background: #f5f5f5;
            border-color: #aaa;
        }

        .category-browser-content {
            max-height: 300px;
            overflow-y: auto;
            padding: 10px 0;
        }

        .category-browser.collapsed .category-browser-content {
            display: none;
        }

        .category-browser.collapsed .category-browser-header::after {
            transform: rotate(-90deg);
        }

        .category-browser-header::after {
            content: '▼';
            font-size: 10px;
            color: #666;
            transition: transform 0.2s;
        }

        .category-node {
            padding: 4px 0;
        }

        .category-node-header {
            display: flex;
            align-items: center;
            padding: 6px 15px;
            cursor: pointer;
            transition: background 0.15s;
        }

        .category-node-header:hover {
            background: #e8f5e9;
        }

        .category-node-header.selected {
            background: #c8e6c9;
            font-weight: 500;
        }

        .category-toggle {
            width: 20px;
            height: 20px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 10px;
            color: #666;
            flex-shrink: 0;
            transition: transform 0.2s;
        }

        .category-toggle.expanded {
            transform: rotate(90deg);
        }

        .category-toggle.empty {
            visibility: hidden;
        }

        .category-label {
            flex: 1;
            padding: 2px 8px;
            border-radius: 4px;
        }

        .category-count {
            font-size: 11px;
            color: #888;
            margin-left: 8px;
        }

        .category-children {
            display: none;
            padding-left: 20px;
        }

        .category-children.expanded {
            display: block;
        }

        .category-badge {
            display: inline-block;
            background: #e3f2fd;
            color: #1565c0;
            padding: 2px 8px;
            border-radius: 12px;
            font-size: 11px;
            margin-left: 4px;
            font-weight: 500;
        }

        .category-badge:hover {
            background: #bbdefb;
            cursor: pointer;
        }

        .category-search-result:hover {
            background: #f5f5f5;
        }

        /* ==================== MOBILE OVERHAUL ==================== */

        /* Mobile-first: ensure minimum touch targets (44x44px) */
        @media (max-width: 768px) {
            /* Sticky search header */
            .search-container {
                position: sticky;
                top: 0;
                z-index: 100;
                margin: 0 -20px 20px -20px;
                padding: 15px 20px;
                border-radius: 0;
                box-shadow: 0 2px 8px rgba(0,0,0,0.15);
            }

            .container {
                padding: 10px;
            }

            /* Larger search box for mobile */
            .search-box {
                font-size: 18px;
                padding: 16px 20px;
                border-radius: 8px;
                margin-bottom: 12px;
            }

            /* Header adjustments */
            header {
                padding: 15px;
                margin-bottom: 0;
                border-radius: 0;
                margin: -10px -10px 0 -10px;
            }

            h1 {
                font-size: 22px;
            }

            /* View toggle buttons - larger touch targets */
            .view-toggle {
                display: grid;
                grid-template-columns: 1fr 1fr;
                gap: 8px;
                margin-top: 12px;
            }

            .view-btn {
                min-height: 48px;
                font-size: 14px;
                padding: 12px 16px;
                display: flex;
                align-items: center;
                justify-content: center;
            }

            /* Filter buttons - stack and full width */
            .filters {
                flex-direction: column;
                gap: 8px;
            }

            .filter-btn {
                width: 100%;
                min-height: 48px;
                font-size: 15px;
                padding: 12px 16px;
            }

            /* Collapsible tag filter */
            .tag-filter {
                margin-top: 12px;
            }

            .tag-filter-header {
                display: flex;
                align-items: center;
                justify-content: space-between;
                padding: 12px;
                background: #f8f9fa;
                border-radius: 8px;
                cursor: pointer;
                min-height: 48px;
            }

            .tag-filter-header::after {
                content: '▼';
                font-size: 12px;
                transition: transform 0.3s;
            }

            .tag-filter.collapsed .tag-filter-header::after {
                transform: rotate(-90deg);
            }

            .tag-filter.collapsed .tag-filter-content {
                display: none;
            }

            .tag-filter-content {
                padding-top: 10px;
            }

            .tag-filter-btn {
                min-height: 44px;
                padding: 10px 14px;
                font-size: 14px;
                margin: 4px;
            }

            /* Container cards - larger tap targets */
            .container-header {
                padding: 18px 15px;
                min-height: 60px;
            }

            .container-id {
                font-size: 16px;
            }

            .container-title {
                font-size: 13px;
                margin-left: 10px;
            }

            .toggle-icon {
                font-size: 18px;
                padding: 10px;
                margin: -10px;
            }

            .container-details {
                padding: 15px;
            }

            /* Image grids */
            .images-grid {
                grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
                gap: 10px;
            }

            .gallery-grid {
                grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
                gap: 12px;
            }

            .gallery-image-wrapper img {
                height: 160px;
            }

            /* Items list - better touch targets for links */
            .items-list li {
                padding: 8px 0;
                border-bottom: 1px solid #f0f0f0;
            }

            .items-list li:last-child {
                border-bottom: none;
            }

            .items-list li.item-matches-filter {
                background: linear-gradient(90deg, #fff3e0 0%, transparent 100%);
                border-left: 3px solid #ff9800;
                padding-left: 12px;
                margin-left: -10px;
            }

            .item-link {
                padding: 8px 4px;
                margin: -8px -4px;
            }

            .tag-badge {
                padding: 6px 12px;
                font-size: 12px;
                min-height: 32px;
                display: inline-flex;
                align-items: center;
            }

            /* Parent link - larger touch target */
            .parent-link {
                padding: 8px 12px;
                margin-left: 5px;
                background: rgba(52, 152, 219, 0.1);
                border-radius: 6px;
                min-height: 36px;
                display: inline-flex;
                align-items: center;
            }

            /* Stats bar */
            .stats {
                font-size: 13px;
                padding: 8px;
            }

            /* Lightbox mobile optimizations */
            .lightbox img {
                max-width: 100%;
                max-height: 80%;
            }

            .lightbox-close {
                top: 10px;
                right: 15px;
                font-size: 36px;
                padding: 10px;
                background: rgba(0, 0, 0, 0.5);
                border-radius: 50%;
                width: 56px;
                height: 56px;
                display: flex;
                align-items: center;
                justify-content: center;
            }

            /* Move nav buttons to bottom corners for thumb reach */
            .lightbox-nav {
                top: auto;
                bottom: 80px;
                transform: none;
                font-size: 24px;
                padding: 16px 24px;
                min-width: 64px;
                min-height: 64px;
                display: flex;
                align-items: center;
                justify-content: center;
                background: rgba(0, 0, 0, 0.6);
                border: none;
                border-radius: 12px;
            }

            .lightbox-prev {
                left: 15px;
            }

            .lightbox-next {
                right: 15px;
            }

            .lightbox-info {
                bottom: 15px;
                padding: 12px 16px;
                font-size: 13px;
                max-width: calc(100% - 30px);
                text-align: center;
            }

            /* Photos link - larger button */
            .photos-link {
                min-height: 48px;
                padding: 12px 20px;
                font-size: 15px;
                display: inline-flex;
                align-items: center;
            }

            /* Error modal mobile */
            .error-modal-content {
                margin: 20px;
                max-width: calc(100% - 40px);
                max-height: calc(100vh - 40px);
            }

            .error-modal-btn {
                min-height: 48px;
                padding: 12px 20px;
            }

            /* Category modal mobile */
            .category-modal-content {
                margin: 20px;
                max-width: calc(100% - 40px);
                max-height: calc(100vh - 40px);
            }

            /* No results message */
            .no-results {
                padding: 30px 20px;
            }

            /* Intro section */
            #intro {
                padding: 12px;
            }

            #introToggle {
                min-height: 44px;
                padding: 10px;
                margin: -10px;
                font-size: 15px;
            }
        }

        /* Small phones (under 400px) */
        @media (max-width: 400px) {
            .search-box {
                font-size: 16px;
                padding: 14px 16px;
            }

            .container-header {
                flex-wrap: wrap;
            }

            .container-title {
                width: 100%;
                margin-left: 0;
                margin-top: 8px;
                font-size: 12px;
            }

            .images-grid {
                grid-template-columns: 1fr 1fr;
            }

            .gallery-grid {
                grid-template-columns: 1fr 1fr;
            }
        }

        /* Swipe indicator for lightbox */
        .swipe-indicator {
            position: absolute;
            bottom: 130px;
            left: 50%;
            transform: translateX(-50%);
            color: rgba(255, 255, 255, 0.6);
            font-size: 12px;
            display: none;
        }

        @media (max-width: 768px) {
            .swipe-indicator {
                display: block;
            }
        }

        /* Prevent body scroll when lightbox is open on mobile */
        body.lightbox-open {
            overflow: hidden;
            position: fixed;
            width: 100%;
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1 id="pageTitle"></h1>
            <p id="pageSubtitle"></p>
            <div id="intro" style="display: none; margin-top: 15px; padding: 15px; background: #f8f9fa; border-left: 4px solid #3498db; border-radius: 4px;">
                <button id="introToggle" onclick="document.getElementById('introText').style.display = document.getElementById('introText').style.display === 'none' ? 'block' : 'none'" style="cursor: pointer; background: none; border: none; color: #3498db; font-size: 14px;"></button>
                <div id="introText" style="display: none; margin-top: 10px; font-size: 14px; line-height: 1.6;"></div>
            </div>
        </header>

        <div class="search-container">
            <input
                type="text"
                id="searchBox"
                class="search-box"
                placeholder=""
                autocomplete="off"
            >

            <div class="filters" id="filters">
                <!-- Filters will be dynamically generated -->
            </div>

            <div class="view-toggle">
                <button class="view-btn active" data-view="containers" id="containerViewBtn"></button>
                <button class="view-btn" data-view="gallery" id="galleryViewBtn"></button>
                <button class="view-btn" data-view="shopping" id="shoppingViewBtn" style="display: none;"></button>
            </div>

            <div class="tag-filter" id="tagFilter" style="margin-top: 15px;">
                <!-- Tag filter buttons will be inserted here -->
            </div>

            <div class="category-search" id="categorySearch" style="display: none; margin-top: 15px;">
                <div style="position: relative;">
                    <input type="text"
                           id="categorySearchInput"
                           placeholder="🏷️ Search categories..."
                           autocomplete="off"
                           style="width: 100%; padding: 10px 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 14px;">
                    <div id="categorySearchResults"
                         style="display: none; position: absolute; top: 100%; left: 0; right: 0; background: white; border: 1px solid #ddd; border-top: none; border-radius: 0 0 6px 6px; max-height: 250px; overflow-y: auto; z-index: 100; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">
                    </div>
                </div>
            </div>

            <div class="category-browser" id="categoryBrowser" style="display: none;">
                <div class="category-browser-header" onclick="toggleCategoryBrowser()">
                    <span class="category-browser-title" id="categoryBrowserTitle"></span>
                    <span id="languageSelectorContainer" style="display: none; margin-left: auto; margin-right: 10px;" onclick="event.stopPropagation();"></span>
                    <button class="category-browser-clear" onclick="clearCategoryFilter(event)" id="categoryClearBtn" style="display: none;" data-i18n="clear">Clear</button>
                </div>
                <div class="category-browser-content" id="categoryTree">
                    <!-- Category tree will be inserted here -->
                </div>
            </div>

            <div class="stats" id="stats">
            </div>
        </div>

        <div id="results" class="loading">
        </div>

        <div id="gallery-view" style="display: none;">
            <div class="gallery-grid" id="galleryGrid"></div>
        </div>

        <div id="shopping-view" style="display: none;">
            <div class="shopping-list" id="shoppingList"></div>
        </div>
    </div>

    <div class="lightbox" id="lightbox">
        <span class="lightbox-close" onclick="closeLightbox()">&times;</span>
        <span class="lightbox-nav lightbox-prev" onclick="navigateLightbox(-1)">‹</span>
        <span class="lightbox-nav lightbox-next" onclick="navigateLightbox(1)">›</span>
        <img id="lightboxImg" src="" alt="">
        <div class="swipe-indicator" id="swipeIndicator"></div>
        <div class="lightbox-info" id="lightboxInfo"></div>
    </div>

    <!-- Error Modal -->
    <div class="error-modal" id="errorModal">
        <div class="error-modal-content">
            <div class="error-modal-header">
                <div class="error-modal-title">❌ Feil</div>
                <span class="error-modal-close" onclick="closeErrorModal()">&times;</span>
            </div>
            <div class="error-modal-message" id="errorMessage"></div>
            <div class="error-modal-actions">
                <button class="error-modal-btn error-modal-btn-copy" onclick="copyErrorMessage()">📋 Kopier</button>
                <button class="error-modal-btn error-modal-btn-close" onclick="closeErrorModal()">Lukk</button>
            </div>
        </div>
    </div>

    <!-- Category Detail Modal -->
    <div class="category-modal" id="categoryModal">
        <div class="category-modal-content">
            <div class="category-modal-header">
                <div class="category-modal-title" id="categoryModalTitle"></div>
                <span class="category-modal-close" onclick="closeCategoryModal()">&times;</span>
            </div>
            <div id="categoryModalBody"></div>
        </div>
    </div>

    <script>
        // LANGUAGE CONFIGURATION
        // Language is determined by: 1) inventory.json 'lang' field, 2) browser language, 3) fallback to 'en'
        const browserLang = navigator.language || navigator.userLanguage || 'en';
        let LANGUAGE = browserLang.startsWith('no') || browserLang.startsWith('nb') || browserLang.startsWith('nn') ? 'no' : 'en';

        const translations = {
            en: {
                title: '🏠 Inventory List',
                subtitle: 'Searchable database of containers and contents',
                aboutToggle: '▼ About the inventory',
                searchPlaceholder: 'Search for ID, contents, description...',
                filterAll: 'All',
                containerView: '📦 Container View',
                galleryView: '🖼️ Gallery View',
                shoppingView: '🛒 Shopping List',
                shoppingLoading: 'Loading shopping list...',
                shoppingError: 'Could not load shopping list. It may not exist yet.',
                tagFilterLabel: 'Filter by tags (click multiple for AND filter):',
                tagFilterClearAll: 'Clear all',
                statsShowing: 'Showing',
                statsOf: 'of',
                statsContainers: 'containers',
                statsImages: 'images',
                noResults: 'No containers matched the search',
                noImages: 'No images matched the search',
                loading: 'Loading inventory data...',
                errorLoading: 'Error loading data. Check that inventory.json exists.',
                contents: 'Contents:',
                viewPhotos: '📷 View all photos in full resolution',
                goTo: 'Go to',
                imageOf: 'Image',
                container: 'Container',
                swipeHint: '← swipe to browse →',
                tagsSelected: 'selected',
                tagsAvailable: 'available',
                categories: 'Categories',
                items: 'items',
                clear: 'Clear',
                noCategoriesFound: 'No categories found'
            },
            no: {
                title: '🏠 Inventarliste',
                subtitle: 'Søkbar database over containere og innhold',
                aboutToggle: '▼ Om inventarlisten',
                searchPlaceholder: 'Søk etter ID, innhold, beskrivelse...',
                filterAll: 'Alle',
                containerView: '📦 Containervisning',
                galleryView: '🖼️ Bildevisning',
                shoppingView: '🛒 Handleliste',
                shoppingLoading: 'Laster handleliste...',
                shoppingError: 'Kunne ikke laste handleliste. Den eksisterer kanskje ikke ennå.',
                tagFilterLabel: 'Filter etter emneord (klikk flere for AND-filter):',
                tagFilterClearAll: 'Nullstill alle',
                statsShowing: 'Viser',
                statsOf: 'av',
                statsContainers: 'containere',
                statsImages: 'bilder',
                noResults: 'Ingen containere matchet søket',
                noImages: 'Ingen bilder matchet søket',
                loading: 'Laster inventardata...',
                errorLoading: 'Feil ved lasting av data. Sjekk at inventory.json eksisterer.',
                contents: 'Innhold:',
                viewPhotos: '📷 Se alle bilder i full oppløsning',
                goTo: 'Gå til',
                imageOf: 'Bilde',
                container: 'Container',
                swipeHint: '← sveip for å bla →',
                tagsSelected: 'valgt',
                tagsAvailable: 'tilgjengelig',
                categories: 'Kategorier',
                items: 'gjenstander',
                clear: 'Nullstill',
                noCategoriesFound: 'Ingen kategorier funnet'
            }
        };

        let t = translations[LANGUAGE];

        // Initialize UI text with translations
        function initializeUI() {
            document.getElementById('pageTitle').textContent = t.title;
            document.getElementById('pageSubtitle').textContent = t.subtitle;
            document.getElementById('introToggle').textContent = t.aboutToggle;
            document.getElementById('searchBox').placeholder = t.searchPlaceholder;
            document.getElementById('containerViewBtn').textContent = t.containerView;
            document.getElementById('galleryViewBtn').textContent = t.galleryView;
            document.getElementById('shoppingViewBtn').textContent = t.shoppingView;
            document.getElementById('stats').textContent = t.loading;
            document.getElementById('results').textContent = t.loading;
            document.getElementById('swipeIndicator').textContent = t.swipeHint;
            document.getElementById('categoryClearBtn').textContent = t.clear;
        }

        // Call initializeUI on page load
        initializeUI();

        let inventoryData = null;
        let currentFilter = 'all';
        let searchTerm = '';
        let currentView = 'containers';
        let allImages = [];
        let currentLightboxIndex = -1;
        let aliasData = null;
        let photoRegistry = null; // photo-to-item mappings from photo-registry.json
        let searchIndex = new Map();
        let searchDebounceTimeout = null;
        let containerIds = new Set();
        let allTags = new Map(); // tag -> count
        let selectedTags = new Set(); // currently selected tag filters (AND logic)
        let containerPrefixes = new Map(); // prefix -> count
        let vocabularyData = null; // SKOS vocabulary for categories
        let selectedCategory = null; // currently selected category path
        let categoryCounts = new Map(); // category -> item count
        let expandedCategories = new Set(); // expanded tree nodes
        let currentLanguage = 'en'; // selected language for category labels
        let availableLanguages = []; // languages with translations in vocabulary

        // Get photos for a specific item from photo registry
        function getItemPhotos(itemId) {
            if (!photoRegistry || !photoRegistry.items) return [];
            const itemIdLower = itemId.toLowerCase();
            return photoRegistry.items[itemIdLower] || [];
        }

        // Check if item has photos in registry
        function itemHasPhotos(itemId) {
            return getItemPhotos(itemId).length > 0;
        }

        // Get photo info from registry
        function getPhotoInfo(filename) {
            if (!photoRegistry || !photoRegistry.photos) return null;
            return photoRegistry.photos[filename] || null;
        }

        // Show item photos in lightbox
        function showItemPhotos(itemId) {
            const photos = getItemPhotos(itemId);
            if (photos.length === 0) return;

            // Build image data for lightbox
            const itemPhotoImages = photos.map((filename, idx) => {
                const photoInfo = getPhotoInfo(filename);
                const container = photoInfo?.container || 'unknown';
                return {
                    containerId: container,
                    containerHeading: `Photos of ${itemId}`,
                    imageIndex: idx + 1,
                    totalInContainer: photos.length,
                    image: {
                        thumb: `resized/${container}/${filename}`,
                        full: `photos/${container}/${filename}`,
                        alt: `${itemId} - ${filename}`
                    },
                    itemId: itemId,
                    notes: photoInfo?.notes
                };
            });

            // Store for lightbox navigation
            window.currentItemPhotos = itemPhotoImages;
            window.currentItemPhotoIndex = 0;
            updateItemPhotoLightbox();
        }

        // Update lightbox for item photos
        function updateItemPhotoLightbox() {
            const photos = window.currentItemPhotos;
            const index = window.currentItemPhotoIndex;
            if (!photos || photos.length === 0) return;

            const imgData = photos[index];
            const lightbox = document.getElementById('lightbox');
            const lightboxImg = document.getElementById('lightboxImg');
            const lightboxInfo = document.getElementById('lightboxInfo');

            lightboxImg.src = imgData.image.full;
            let info = `${t.imageOf} ${index + 1} ${t.statsOf} ${photos.length} | ID: ${imgData.itemId}`;
            if (imgData.notes) {
                info += ` | ${imgData.notes}`;
            }
            lightboxInfo.innerHTML = info;
            lightbox.classList.add('active');

            // Override navigation for item photos
            window.itemPhotoMode = true;
        }

        // Navigate item photos
        function navigateItemPhotos(direction) {
            const photos = window.currentItemPhotos;
            if (!photos || photos.length === 0) return;

            window.currentItemPhotoIndex += direction;
            if (window.currentItemPhotoIndex < 0) {
                window.currentItemPhotoIndex = photos.length - 1;
            } else if (window.currentItemPhotoIndex >= photos.length) {
                window.currentItemPhotoIndex = 0;
            }
            updateItemPhotoLightbox();
        }

        // Build flat image index for gallery view
        function buildImageIndex() {
            allImages = [];
            if (!inventoryData) return;

            inventoryData.containers.forEach(container => {
                container.images.forEach((img, idx) => {
                    allImages.push({
                        containerId: container.id,
                        containerHeading: container.heading,
                        imageIndex: idx + 1,
                        totalInContainer: container.images.length,
                        image: img
                    });
                });
            });
        }

        // Build tag collection with counts
        function buildTagCollection() {
            allTags.clear();
            if (!inventoryData) return;

            inventoryData.containers.forEach(container => {
                container.items.forEach(item => {
                    if (item.metadata && item.metadata.tags) {
                        item.metadata.tags.forEach(tag => {
                            allTags.set(tag, (allTags.get(tag) || 0) + 1);
                        });
                    }
                });
            });
        }

        // Expand a category to its SKOS hierarchy paths using categoryMappings
        function expandCategoryToSkosPaths(category) {
            // If vocabularyData has categoryMappings, use them to expand
            if (vocabularyData && vocabularyData.categoryMappings) {
                // Try the full category path first (for path-based categories)
                if (vocabularyData.categoryMappings[category]) {
                    return vocabularyData.categoryMappings[category];
                }
                // Then try leaf label lookup (for SKOS-expanded categories)
                const leafLabel = category.includes('/') ? category.split('/').pop() : category;
                const normalizedLabel = leafLabel.toLowerCase().replace(/-/g, ' ').replace(/_/g, ' ');
                if (vocabularyData.categoryMappings[normalizedLabel]) {
                    return vocabularyData.categoryMappings[normalizedLabel];
                }
            }
            // Fall back to original category
            return [category];
        }

        // Build category counts from inventory
        function buildCategoryCounts() {
            categoryCounts.clear();
            if (!inventoryData) return;

            inventoryData.containers.forEach(container => {
                container.items.forEach(item => {
                    if (item.metadata && item.metadata.categories) {
                        item.metadata.categories.forEach(category => {
                            // Expand category to SKOS paths if categoryMappings available
                            const expandedPaths = expandCategoryToSkosPaths(category);

                            expandedPaths.forEach(expandedCategory => {
                                // Count the category itself
                                categoryCounts.set(expandedCategory, (categoryCounts.get(expandedCategory) || 0) + 1);
                                // Also count parent categories
                                const parts = expandedCategory.split('/');
                                for (let i = 0; i < parts.length - 1; i++) {
                                    const parent = parts.slice(0, i + 1).join('/');
                                    categoryCounts.set(parent, (categoryCounts.get(parent) || 0) + 1);
                                }
                            });
                        });
                    }
                });
            });
        }

        // Toggle category browser collapse
        function toggleCategoryBrowser() {
            const browser = document.getElementById('categoryBrowser');
            if (browser) {
                browser.classList.toggle('collapsed');
            }
        }

        // Clear category filter
        function clearCategoryFilter(event) {
            if (event) {
                event.stopPropagation();
            }
            selectedCategory = null;
            updateCategoryBrowserTitle();
            renderCategoryTree();
            showCategoryInfo(null); // Hide info panel
            displayResults();
        }

        // Update category browser title
        function updateCategoryBrowserTitle() {
            const titleEl = document.getElementById('categoryBrowserTitle');
            const clearBtn = document.getElementById('categoryClearBtn');

            if (selectedCategory && vocabularyData && vocabularyData.concepts[selectedCategory]) {
                const concept = vocabularyData.concepts[selectedCategory];
                const count = categoryCounts.get(selectedCategory) || 0;
                titleEl.innerHTML = `📁 ${getConceptLabel(concept)} <span style="color: #666; font-weight: normal;">(${count} ${t.items})</span>`;
                if (clearBtn) clearBtn.style.display = 'block';
            } else {
                const totalCategories = vocabularyData ? Object.keys(vocabularyData.concepts).length : 0;
                titleEl.textContent = `📁 ${t.categories} (${totalCategories})`;
                if (clearBtn) clearBtn.style.display = 'none';
            }
        }

        // Toggle category tree node expansion
        function toggleCategoryNode(categoryId, event) {
            if (event) {
                event.stopPropagation();
            }
            if (expandedCategories.has(categoryId)) {
                expandedCategories.delete(categoryId);
            } else {
                expandedCategories.add(categoryId);
            }
            renderCategoryTree();
        }

        // Select a category for filtering
        function selectCategory(categoryId, event) {
            if (event) {
                event.stopPropagation();
            }
            if (selectedCategory === categoryId) {
                // Clicking same category clears the filter
                selectedCategory = null;
            } else {
                selectedCategory = categoryId;
                // Auto-expand parent categories
                if (vocabularyData && vocabularyData.concepts[categoryId]) {
                    const parts = categoryId.split('/');
                    for (let i = 0; i < parts.length - 1; i++) {
                        expandedCategories.add(parts.slice(0, i + 1).join('/'));
                    }
                }
            }
            updateCategoryBrowserTitle();
            renderCategoryTree();
            showCategoryInfo(categoryId);
            displayResults();
        }

        // Show category information panel
        function showCategoryInfo(categoryId) {
            let infoEl = document.getElementById('categoryInfo');
            if (!infoEl) {
                // Create info panel if it doesn't exist
                const browserEl = document.getElementById('categoryBrowser');
                if (browserEl) {
                    infoEl = document.createElement('div');
                    infoEl.id = 'categoryInfo';
                    infoEl.style.cssText = 'margin-top: 10px; padding: 12px; background: #f8f9fa; border-radius: 6px; font-size: 13px; display: none;';
                    browserEl.appendChild(infoEl);
                }
            }
            if (!infoEl) return;

            if (!categoryId || !vocabularyData || !vocabularyData.concepts[categoryId]) {
                infoEl.style.display = 'none';
                return;
            }

            const concept = vocabularyData.concepts[categoryId];
            const count = categoryCounts.get(categoryId) || 0;

            let html = `<div style="margin-bottom: 8px;"><strong>${getConceptLabel(concept)}</strong> <span onclick="showCategoryModal('${categoryId}')" style="cursor: pointer; margin-left: 6px; font-size: 14px;" title="Show full details">\u2139\uFE0F</span></div>`;
            html += `<div style="color: #666; margin-bottom: 4px;">Path: <code style="background: #e9ecef; padding: 2px 6px; border-radius: 3px;">${categoryId}</code></div>`;

            // Source badges — show all sources from source_uris, or fall back to single source
            let sourceHtml = '';
            if (concept.source_uris && Object.keys(concept.source_uris).length > 0) {
                for (const [src, uri] of Object.entries(concept.source_uris)) {
                    let badge = `<span style="background: ${getSourceColor(src)}; color: white; padding: 2px 6px; border-radius: 3px; font-size: 11px;">${src}</span>`;
                    if (uri && !uri.startsWith('off:')) {
                        badge = `<a href="${uri}" target="_blank" style="text-decoration: none;">${badge}</a>`;
                    }
                    sourceHtml += badge + ' ';
                }
            } else {
                let badge = `<span style="background: ${getSourceColor(concept.source)}; color: white; padding: 2px 6px; border-radius: 3px; font-size: 11px;">${concept.source}</span>`;
                if (concept.uri) {
                    badge = `<a href="${concept.uri}" target="_blank" style="text-decoration: none;">${badge}</a>`;
                }
                sourceHtml = badge;
            }
            html += `<div style="color: #666; margin-bottom: 4px;">Source: ${sourceHtml}</div>`;
            html += `<div style="color: #666; margin-bottom: 4px;">Items: ${count}</div>`;

            // Wikipedia link
            if (concept.wikipediaUrl) {
                // Generate language-specific Wikipedia URL
                let wikiUrl = concept.wikipediaUrl;
                if (currentLanguage !== 'en' && concept.uri && concept.uri.includes('dbpedia.org')) {
                    // Try to construct localized Wikipedia URL
                    const articleName = concept.uri.split('/resource/').pop();
                    wikiUrl = `https://${currentLanguage}.wikipedia.org/wiki/${articleName}`;
                }
                html += `<div style="margin-bottom: 4px;"><a href="${wikiUrl}" target="_blank" style="color: #0066cc; text-decoration: none;">📖 Wikipedia</a></div>`;
            }

            // Description (try current language, fall back to default)
            let description = null;
            if (concept.descriptions && concept.descriptions[currentLanguage]) {
                description = concept.descriptions[currentLanguage];
            } else if (concept.description) {
                description = concept.description;
            }
            if (description) {
                // Truncate long descriptions
                const maxLen = 200;
                const truncated = description.length > maxLen ? description.substring(0, maxLen) + '...' : description;
                html += `<div style="color: #555; margin-top: 8px; font-style: italic; line-height: 1.4;">${truncated}</div>`;
            }

            // Broader categories as clickable links
            if (concept.broader && concept.broader.length > 0) {
                const broaderLinks = concept.broader.map(b => {
                    const bc = vocabularyData.concepts[b];
                    const label = bc ? getConceptLabel(bc) : b;
                    // Check if broader is a local category (selectable) or external URI
                    if (bc) {
                        return `<a href="#" onclick="selectCategory('${b}', event); return false;" style="color: #0066cc;">${label}</a>`;
                    } else if (b.startsWith('http')) {
                        return `<a href="${b}" target="_blank" style="color: #0066cc;">${label}</a>`;
                    }
                    return label;
                }).join(', ');
                html += `<div style="color: #666; margin-bottom: 4px;">Broader: ${broaderLinks}</div>`;
            }

            // Narrower categories as clickable links
            if (concept.narrower && concept.narrower.length > 0) {
                const narrowerLinks = concept.narrower.slice(0, 5).map(n => {
                    const nc = vocabularyData.concepts[n];
                    const label = nc ? getConceptLabel(nc) : n;
                    return `<a href="#" onclick="selectCategory('${n}', event); return false;" style="color: #0066cc;">${label}</a>`;
                });
                let narrowerHtml = narrowerLinks.join(', ');
                if (concept.narrower.length > 5) {
                    narrowerHtml += ` <span style="color: #999;">+${concept.narrower.length - 5} more</span>`;
                }
                html += `<div style="color: #666;">Children: ${narrowerHtml}</div>`;
            }

            infoEl.innerHTML = html;
            infoEl.style.display = 'block';
        }

        function getSourceColor(source) {
            switch(source) {
                case 'agrovoc': return '#4caf50';
                case 'dbpedia': return '#2196f3';
                case 'wikidata': return '#e91e63';
                case 'off': return '#ff5722';
                case 'local': return '#9c27b0';
                case 'package': return '#795548';
                case 'skos': return '#ff9800';
                default: return '#757575';
            }
        }

        // Get available languages from vocabulary
        function getAvailableLanguages() {
            if (!vocabularyData || !vocabularyData.concepts) return ['en'];
            const langs = new Set(['en']); // Always include English
            for (const concept of Object.values(vocabularyData.concepts)) {
                if (concept.labels) {
                    Object.keys(concept.labels).forEach(lang => langs.add(lang));
                }
            }
            return Array.from(langs).sort();
        }

        // Get label for concept in current language
        function getConceptLabel(concept) {
            if (!concept) return '';
            // Try current language first
            if (concept.labels && concept.labels[currentLanguage]) {
                return concept.labels[currentLanguage];
            }
            // Fall back to prefLabel
            return concept.prefLabel || '';
        }

        // Category detail modal
        function showCategoryModal(categoryId) {
            if (!vocabularyData || !vocabularyData.concepts[categoryId]) return;
            const concept = vocabularyData.concepts[categoryId];
            const count = categoryCounts.get(categoryId) || 0;

            document.getElementById('categoryModalTitle').textContent = getConceptLabel(concept);

            let html = '';

            // Path
            html += `<div class="category-modal-section">
                <div class="category-modal-section-title">Path</div>
                <code style="background: #e9ecef; padding: 2px 6px; border-radius: 3px;">${categoryId}</code>
            </div>`;

            // Alt labels (dict format: {lang: [labels]} or legacy array)
            const altLabels = concept.altLabels || {};
            let altLabelItems = [];
            if (Array.isArray(altLabels)) {
                // Legacy flat array format
                altLabelItems = altLabels;
            } else if (typeof altLabels === 'object') {
                // New language-tagged dict format: show current language first, then others
                const curLang = currentLanguage || 'en';
                if (altLabels[curLang]) {
                    altLabelItems.push(...altLabels[curLang]);
                }
                for (const [lang, labels] of Object.entries(altLabels)) {
                    if (lang !== curLang && labels.length > 0) {
                        altLabelItems.push(...labels.map(l => `${l} [${lang}]`));
                    }
                }
            }
            if (altLabelItems.length > 0) {
                html += `<div class="category-modal-section">
                    <div class="category-modal-section-title">Also known as</div>
                    <div>${altLabelItems.join(', ')}</div>
                </div>`;
            }

            // Sources
            let sourceHtml = '';
            if (concept.source_uris && Object.keys(concept.source_uris).length > 0) {
                for (const [src, uri] of Object.entries(concept.source_uris)) {
                    let badge = `<span style="background: ${getSourceColor(src)}; color: white; padding: 2px 8px; border-radius: 3px; font-size: 12px; display: inline-block;">${src}</span>`;
                    if (uri && !uri.startsWith('off:')) {
                        badge = `<a href="${uri}" target="_blank" style="text-decoration: none;">${badge}</a>`;
                    }
                    sourceHtml += badge + ' ';
                }
            } else {
                let badge = `<span style="background: ${getSourceColor(concept.source)}; color: white; padding: 2px 8px; border-radius: 3px; font-size: 12px; display: inline-block;">${concept.source}</span>`;
                if (concept.uri) {
                    badge = `<a href="${concept.uri}" target="_blank" style="text-decoration: none;">${badge}</a>`;
                }
                sourceHtml = badge;
            }
            html += `<div class="category-modal-section">
                <div class="category-modal-section-title">Sources</div>
                <div>${sourceHtml}</div>
            </div>`;

            // Item count
            html += `<div class="category-modal-section">
                <div class="category-modal-section-title">Items</div>
                <div>${count}</div>
            </div>`;

            // Wikipedia link
            if (concept.wikipediaUrl) {
                let wikiUrl = concept.wikipediaUrl;
                if (currentLanguage !== 'en' && concept.uri && concept.uri.includes('dbpedia.org')) {
                    const articleName = concept.uri.split('/resource/').pop();
                    wikiUrl = `https://${currentLanguage}.wikipedia.org/wiki/${articleName}`;
                }
                html += `<div class="category-modal-section">
                    <div class="category-modal-section-title">Wikipedia</div>
                    <div><a href="${wikiUrl}" target="_blank" style="color: #0066cc;">${wikiUrl}</a></div>
                </div>`;
            }

            // Full description
            let description = null;
            if (concept.descriptions && concept.descriptions[currentLanguage]) {
                description = concept.descriptions[currentLanguage];
            } else if (concept.description) {
                description = concept.description;
            }
            if (description) {
                html += `<div class="category-modal-section">
                    <div class="category-modal-section-title">Description</div>
                    <div class="category-modal-description">${description}</div>
                </div>`;
            }

            // Broader (all parents)
            if (concept.broader && concept.broader.length > 0) {
                const links = concept.broader.map(b => {
                    const bc = vocabularyData.concepts[b];
                    const label = bc ? getConceptLabel(bc) : b;
                    if (bc) {
                        return `<a href="#" onclick="closeCategoryModal(); selectCategory('${b}', event); return false;">${label}</a>`;
                    } else if (b.startsWith('http')) {
                        return `<a href="${b}" target="_blank">${label}</a>`;
                    }
                    return `<span>${label}</span>`;
                });
                html += `<div class="category-modal-section">
                    <div class="category-modal-section-title">Broader</div>
                    <div class="category-modal-links">${links.join('')}</div>
                </div>`;
            }

            // Narrower (ALL children, sorted alphabetically)
            if (concept.narrower && concept.narrower.length > 0) {
                const sorted = [...concept.narrower].sort((a, b) => {
                    const la = vocabularyData.concepts[a] ? getConceptLabel(vocabularyData.concepts[a]) : a;
                    const lb = vocabularyData.concepts[b] ? getConceptLabel(vocabularyData.concepts[b]) : b;
                    return la.localeCompare(lb);
                });
                const links = sorted.map(n => {
                    const nc = vocabularyData.concepts[n];
                    const label = nc ? getConceptLabel(nc) : n;
                    return `<a href="#" onclick="closeCategoryModal(); selectCategory('${n}', event); return false;">${label}</a>`;
                });
                html += `<div class="category-modal-section">
                    <div class="category-modal-section-title">Children (${concept.narrower.length})</div>
                    <div class="category-modal-links">${links.join('')}</div>
                </div>`;
            }

            document.getElementById('categoryModalBody').innerHTML = html;
            document.getElementById('categoryModal').classList.add('active');
        }

        function closeCategoryModal() {
            document.getElementById('categoryModal').classList.remove('active');
        }

        // Change display language
        function setLanguage(lang) {
            currentLanguage = lang;
            // Update UI
            renderCategoryTree();
            updateCategoryBrowserTitle();
            if (selectedCategory) {
                showCategoryInfo(selectedCategory);
            }
            // Update language selector
            const selector = document.getElementById('languageSelector');
            if (selector) selector.value = lang;
        }

        // Render language selector
        function renderLanguageSelector() {
            const container = document.getElementById('languageSelectorContainer');
            if (!container || availableLanguages.length <= 1) {
                if (container) container.style.display = 'none';
                return;
            }

            const langNames = {
                'en': 'English', 'nb': 'Norsk (bokmål)', 'nn': 'Norsk (nynorsk)',
                'no': 'Norsk', 'de': 'Deutsch', 'fr': 'Français', 'es': 'Español',
                'it': 'Italiano', 'pt': 'Português', 'nl': 'Nederlands',
                'sv': 'Svenska', 'da': 'Dansk', 'dk': 'Dansk', 'fi': 'Suomi',
                'pl': 'Polski', 'cs': 'Čeština', 'ru': 'Русский',
                'uk': 'Українська', 'bg': 'Български',
                'zh': '中文', 'ja': '日本語', 'ko': '한국어',
                'ar': 'العربية', 'he': 'עברית', 'tr': 'Türkçe',
                'el': 'Ελληνικά', 'hu': 'Magyar', 'ro': 'Română',
                'sk': 'Slovenčina', 'hr': 'Hrvatski', 'sr': 'Српски',
                'sl': 'Slovenščina', 'et': 'Eesti', 'lv': 'Latviešu',
                'lt': 'Lietuvių', 'th': 'ไทย', 'vi': 'Tiếng Việt',
                'id': 'Bahasa Indonesia', 'ms': 'Bahasa Melayu'
            };

            let html = '<select id="languageSelector" onchange="setLanguage(this.value)">';
            for (const lang of availableLanguages) {
                const selected = lang === currentLanguage ? 'selected' : '';
                const name = langNames[lang] || lang.toUpperCase();
                html += `<option value="${lang}" ${selected}>${name}</option>`;
            }
            html += '</select>';

            container.innerHTML = html;
            container.style.display = 'block';
        }

        // Render category tree node recursively
        function renderCategoryNode(conceptId, depth = 0) {
            const concept = vocabularyData.concepts[conceptId];
            if (!concept) return '';

            const hasChildren = concept.narrower && concept.narrower.length > 0;
            const isExpanded = expandedCategories.has(conceptId);
            const isSelected = selectedCategory === conceptId;
            const count = categoryCounts.get(conceptId) || 0;

            // Skip categories with no items
            if (count === 0) return '';

            let html = `<div class="category-node" data-category="${conceptId}">`;
            html += `<div class="category-node-header ${isSelected ? 'selected' : ''}" onclick="selectCategory('${conceptId}', event)">`;

            // Toggle arrow
            if (hasChildren) {
                html += `<span class="category-toggle ${isExpanded ? 'expanded' : ''}" onclick="toggleCategoryNode('${conceptId}', event)">▶</span>`;
            } else {
                html += `<span class="category-toggle empty"></span>`;
            }

            // Label
            html += `<span class="category-label">${getConceptLabel(concept)}</span>`;
            html += `<span class="category-count">(${count})</span>`;
            html += `</div>`;

            // Children
            if (hasChildren) {
                html += `<div class="category-children ${isExpanded ? 'expanded' : ''}">`;
                // Sort children alphabetically
                const sortedChildren = concept.narrower
                    .filter(childId => vocabularyData.concepts[childId] && (categoryCounts.get(childId) || 0) > 0)
                    .sort((a, b) => {
                        const labelA = getConceptLabel(vocabularyData.concepts[a]) || a;
                        const labelB = getConceptLabel(vocabularyData.concepts[b]) || b;
                        return labelA.localeCompare(labelB);
                    });
                for (const childId of sortedChildren) {
                    html += renderCategoryNode(childId, depth + 1);
                }
                html += `</div>`;
            }

            html += `</div>`;
            return html;
        }

        // Render full category tree
        function renderCategoryTree() {
            const treeEl = document.getElementById('categoryTree');
            if (!treeEl || !vocabularyData || !vocabularyData.roots) {
                return;
            }

            let html = '';
            // Sort roots alphabetically
            const sortedRoots = vocabularyData.roots
                .filter(rootId => vocabularyData.concepts[rootId] && (categoryCounts.get(rootId) || 0) > 0)
                .sort((a, b) => {
                    const labelA = getConceptLabel(vocabularyData.concepts[a]) || a;
                    const labelB = getConceptLabel(vocabularyData.concepts[b]) || b;
                    return labelA.localeCompare(labelB);
                });

            for (const rootId of sortedRoots) {
                html += renderCategoryNode(rootId);
            }

            treeEl.innerHTML = html || `<div style="padding: 15px; color: #666;">${t.noCategoriesFound}</div>`;
        }

        // Display category browser
        function displayCategoryBrowser() {
            const browserEl = document.getElementById('categoryBrowser');
            const searchEl = document.getElementById('categorySearch');
            if (!browserEl) return;

            // Hide if no vocabulary or no categories with items
            if (!vocabularyData || categoryCounts.size === 0) {
                browserEl.style.display = 'none';
                if (searchEl) searchEl.style.display = 'none';
                return;
            }

            browserEl.style.display = 'block';
            if (searchEl) searchEl.style.display = 'block';
            updateCategoryBrowserTitle();
            renderCategoryTree();
            initCategorySearch();
        }

        // Category search functionality
        function initCategorySearch() {
            const input = document.getElementById('categorySearchInput');
            if (!input || input.hasAttribute('data-initialized')) return;
            input.setAttribute('data-initialized', 'true');

            input.addEventListener('input', function() {
                const query = this.value.toLowerCase().trim();
                if (query.length < 2) {
                    hideCategorySearchResults();
                    return;
                }
                showCategorySearchResults(query);
            });

            input.addEventListener('blur', function() {
                // Delay to allow click on results
                setTimeout(hideCategorySearchResults, 200);
            });

            input.addEventListener('focus', function() {
                const query = this.value.toLowerCase().trim();
                if (query.length >= 2) {
                    showCategorySearchResults(query);
                }
            });
        }

        function showCategorySearchResults(query) {
            const resultsEl = document.getElementById('categorySearchResults');
            if (!resultsEl || !vocabularyData) return;

            // Search through all concepts
            const matches = [];
            for (const [id, concept] of Object.entries(vocabularyData.concepts)) {
                const count = categoryCounts.get(id) || 0;
                if (count === 0) continue; // Skip empty categories

                // Check prefLabel
                if (concept.prefLabel.toLowerCase().includes(query)) {
                    matches.push({ id, concept, count, matchType: 'prefLabel' });
                    continue;
                }
                // Check translated labels
                if (concept.labels) {
                    const labelMatch = Object.values(concept.labels).some(label =>
                        label.toLowerCase().includes(query)
                    );
                    if (labelMatch) {
                        matches.push({ id, concept, count, matchType: 'translation' });
                        continue;
                    }
                }
                // Check altLabels (dict format: {lang: [labels]} or legacy array)
                const alts = concept.altLabels || {};
                const allAlts = Array.isArray(alts) ? alts : Object.values(alts).flat();
                if (allAlts.some(alt => alt.toLowerCase().includes(query))) {
                    matches.push({ id, concept, count, matchType: 'altLabel' });
                    continue;
                }
                // Check ID (path)
                if (id.toLowerCase().includes(query)) {
                    matches.push({ id, concept, count, matchType: 'path' });
                }
            }

            // Sort by count (descending) and limit
            matches.sort((a, b) => b.count - a.count);
            const topMatches = matches.slice(0, 15);

            if (topMatches.length === 0) {
                resultsEl.innerHTML = `<div style="padding: 10px; color: #666;">${t.noCategoriesFound}</div>`;
            } else {
                resultsEl.innerHTML = topMatches.map(m => {
                    const pathDisplay = m.id.includes('/') ? `<span style="color: #888; font-size: 12px;"> (${m.id})</span>` : '';
                    return `<div class="category-search-result" onclick="selectCategoryFromSearch('${m.id}')" style="padding: 8px 12px; cursor: pointer; border-bottom: 1px solid #eee;">
                        <span style="font-weight: 500;">${getConceptLabel(m.concept)}</span>${pathDisplay}
                        <span style="float: right; color: #666; font-size: 12px;">${m.count} items</span>
                    </div>`;
                }).join('');
            }

            resultsEl.style.display = 'block';
        }

        function hideCategorySearchResults() {
            const resultsEl = document.getElementById('categorySearchResults');
            if (resultsEl) resultsEl.style.display = 'none';
        }

        function selectCategoryFromSearch(categoryId) {
            const input = document.getElementById('categorySearchInput');
            if (input) input.value = '';
            hideCategorySearchResults();
            selectCategory(categoryId);
        }

        // Check if item matches selected category (including children)
        function itemMatchesCategory(item) {
            if (!selectedCategory) return true;
            if (!item.metadata || !item.metadata.categories) return false;

            // Check if any of the item's categories match or are children of the selected category
            return item.metadata.categories.some(cat => {
                // Expand category to SKOS paths if categoryMappings available
                const expandedPaths = expandCategoryToSkosPaths(cat);

                return expandedPaths.some(expandedCat => {
                    return expandedCat === selectedCategory || expandedCat.startsWith(selectedCategory + '/');
                });
            });
        }

        // Build container prefix collection
        function buildContainerPrefixes() {
            containerPrefixes.clear();
            if (!inventoryData) return;

            inventoryData.containers.forEach(container => {
                // Extract prefix from container ID
                // Common patterns: A1, Box1, Tower-A, Shelf-1, Garasje, etc.
                const id = container.id || '';

                // Try to match common patterns
                let prefix = null;

                // Pattern 1: Letter(s) + Number (e.g., A1, AA12, Box1)
                const match1 = id.match(/^([A-Za-z]+)\d+/);
                if (match1) {
                    prefix = match1[1];
                }
                // Pattern 2: Word with dash/underscore (e.g., Tower-A, Shelf_1)
                else if (id.includes('-') || id.includes('_')) {
                    prefix = id.split(/[-_]/)[0];
                }
                // Pattern 3: Single word (e.g., Garasje, Workbench)
                else if (id.match(/^[A-Za-z]+$/)) {
                    prefix = id;
                }

                if (prefix) {
                    containerPrefixes.set(prefix, (containerPrefixes.get(prefix) || 0) + 1);
                }
            });
        }

        // Display dynamic filters
        function displayFilters() {
            const filtersDiv = document.getElementById('filters');
            if (!filtersDiv) return;

            let html = `<button class="filter-btn active" data-filter="all">${t.filterAll}</button>`;

            // Sort prefixes by count (descending) then alphabetically
            const sortedPrefixes = Array.from(containerPrefixes.entries())
                .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]));

            // Add filter buttons for each prefix (limit to top 10)
            sortedPrefixes.slice(0, 10).forEach(([prefix, count]) => {
                html += `<button class="filter-btn" data-filter="${prefix}">${prefix} (${count})</button>`;
            });

            filtersDiv.innerHTML = html;
        }

        // Check if mobile device
        function isMobile() {
            return window.innerWidth <= 768;
        }

        // Display tag filter UI
        function displayTagFilter() {
            const tagFilterDiv = document.getElementById('tagFilter');
            if (!tagFilterDiv || allTags.size === 0) {
                if (tagFilterDiv) tagFilterDiv.style.display = 'none';
                return;
            }

            tagFilterDiv.style.display = 'block';

            // Sort tags by count (descending) then alphabetically
            const sortedTags = Array.from(allTags.entries())
                .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]));

            // Check if we should show collapsible UI (mobile) or regular (desktop)
            const isCollapsible = isMobile();
            const isCollapsed = tagFilterDiv.classList.contains('collapsed');
            const hasSelectedTags = selectedTags.size > 0;

            let html = '';

            if (isCollapsible) {
                // Mobile: collapsible layout
                const tagSummary = hasSelectedTags
                    ? `${selectedTags.size} ${t.tagsSelected}`
                    : `${allTags.size} ${t.tagsAvailable}`;

                html += `<div class="tag-filter-header" onclick="toggleTagFilter()">`;
                html += `<span>${t.tagFilterLabel.replace(':', '')} (${tagSummary})</span>`;
                html += `</div>`;
                html += `<div class="tag-filter-content">`;
            } else {
                // Desktop: regular layout
                html += '<div style="font-size: 12px; color: #666; margin-bottom: 5px;">';
                html += t.tagFilterLabel;
            }

            if (hasSelectedTags) {
                html += ` <button class="tag-filter-btn" data-tag="" style="font-size: 11px; padding: 3px 8px;">${t.tagFilterClearAll}</button>`;
            }

            if (!isCollapsible) {
                html += '</div>';
            }

            html += '<div style="display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px;">';

            // Add individual tag buttons (limit to top 20 tags)
            sortedTags.slice(0, 20).forEach(([tag, count]) => {
                const isSelected = selectedTags.has(tag);
                html += `<button class="tag-filter-btn ${isSelected ? 'active' : ''}" data-tag="${tag}">`;
                html += `${tag} (${count})`;
                html += `</button>`;
            });

            html += '</div>';

            if (isCollapsible) {
                html += '</div>'; // Close tag-filter-content
            }

            tagFilterDiv.innerHTML = html;

            // Apply collapsed class if on mobile and was collapsed
            if (isCollapsible && isCollapsed) {
                tagFilterDiv.classList.add('collapsed');
            } else if (!isCollapsible) {
                tagFilterDiv.classList.remove('collapsed');
            }
        }

        // Toggle tag filter collapse on mobile
        function toggleTagFilter() {
            const tagFilterDiv = document.getElementById('tagFilter');
            if (tagFilterDiv) {
                tagFilterDiv.classList.toggle('collapsed');
            }
        }

        // Build search index for faster lookups
        function buildSearchIndex() {
            searchIndex.clear();
            if (!inventoryData) return;

            inventoryData.containers.forEach(container => {
                const containerId = container.id;
                const searchableText = [
                    container.id,  // Include container ID in search
                    container.heading,
                    container.description,
                    ...container.items.map(item => {
                        // Include item ID and text
                        const parts = [item.raw_text || item.name || item];
                        if (item.id) parts.unshift(item.id);
                        return parts.join(' ');
                    })
                ].join(' ').toLowerCase();

                searchIndex.set(containerId, searchableText);
            });
        }

        // Expand search terms with aliases
        function expandSearchWithAliases(term) {
            if (!aliasData) return [term];

            const lowerTerm = term.toLowerCase();
            const terms = [lowerTerm];

            // Add aliases if the term exists in the alias data
            if (aliasData[lowerTerm]) {
                terms.push(...aliasData[lowerTerm].map(alias => alias.toLowerCase()));
            }

            return terms;
        }

        // Simple markdown to HTML converter for intro section
        function markdownToHtml(markdown) {
            let html = '';
            const lines = markdown.split('\n');
            let inList = false;
            let currentParagraph = '';

            for (let i = 0; i < lines.length; i++) {
                const line = lines[i];
                const trimmed = line.trim();

                // Headings
                if (trimmed.startsWith('## ')) {
                    if (currentParagraph) {
                        html += `<p>${currentParagraph}</p>\n`;
                        currentParagraph = '';
                    }
                    if (inList) {
                        html += '</ul>\n';
                        inList = false;
                    }
                    html += `<h3>${trimmed.substring(3)}</h3>\n`;
                }
                // List items
                else if (trimmed.startsWith('* ')) {
                    if (currentParagraph) {
                        html += `<p>${currentParagraph}</p>\n`;
                        currentParagraph = '';
                    }
                    if (!inList) {
                        html += '<ul>\n';
                        inList = true;
                    }
                    html += `<li>${trimmed.substring(2)}</li>\n`;
                }
                // Empty line - end current paragraph or list
                else if (trimmed === '') {
                    if (currentParagraph) {
                        html += `<p>${currentParagraph}</p>\n`;
                        currentParagraph = '';
                    }
                    if (inList) {
                        html += '</ul>\n';
                        inList = false;
                    }
                }
                // Regular text - accumulate into paragraph
                else {
                    if (inList) {
                        html += '</ul>\n';
                        inList = false;
                    }
                    if (currentParagraph) {
                        currentParagraph += ' ';
                    }
                    currentParagraph += trimmed;
                }
            }

            // Close any remaining paragraph or list
            if (currentParagraph) {
                html += `<p>${currentParagraph}</p>\n`;
            }
            if (inList) {
                html += '</ul>\n';
            }

            return html;
        }

        // Load JSON data
        async function loadData() {
            try {
                // Load inventory data
                const response = await fetch('inventory.json');
                inventoryData = await response.json();

                // Update language from inventory if specified
                if (inventoryData.lang && translations[inventoryData.lang]) {
                    LANGUAGE = inventoryData.lang;
                    t = translations[LANGUAGE];
                    initializeUI();
                    console.log('📝 Using language from inventory:', LANGUAGE);
                }

                // Load aliases (optional - don't fail if not available)
                try {
                    const aliasResponse = await fetch('aliases.json');
                    aliasData = await aliasResponse.json();
                    console.log('✅ Loaded', Object.keys(aliasData).length, 'search aliases');
                } catch (aliasError) {
                    console.log('⚠️  Alias search disabled:', aliasError.message);
                }

                // Load photo registry (optional - don't fail if not available)
                try {
                    const photoResponse = await fetch('photo-registry.json');
                    photoRegistry = await photoResponse.json();
                    console.log('✅ Loaded photo registry:', Object.keys(photoRegistry.items || {}).length, 'items with photos');
                } catch (photoError) {
                    console.log('⚠️  Photo registry not available:', photoError.message);
                }

                // Load vocabulary (optional - don't fail if not available)
                try {
                    const vocabResponse = await fetch('vocabulary.json');
                    vocabularyData = await vocabResponse.json();
                    console.log('✅ Loaded vocabulary:', Object.keys(vocabularyData.concepts || {}).length, 'categories');
                    // Initialize available languages
                    availableLanguages = getAvailableLanguages();
                    if (availableLanguages.length > 1) {
                        console.log('✅ Available languages:', availableLanguages.join(', '));
                    }
                    // Set category label language from inventory config
                    if (LANGUAGE && LANGUAGE !== 'en') {
                        // Map general language codes to specific ones available in vocabulary
                        // e.g. 'no' -> 'nb' (Norwegian bokmål)
                        const langMap = {'no': 'nb'};
                        const mapped = langMap[LANGUAGE] || LANGUAGE;
                        if (availableLanguages.includes(mapped)) {
                            currentLanguage = mapped;
                        } else if (availableLanguages.includes(LANGUAGE)) {
                            currentLanguage = LANGUAGE;
                        }
                    }
                } catch (vocabError) {
                    console.log('⚠️  Vocabulary not available:', vocabError.message);
                }

                // Show shopping list button only if shopping-list.md exists
                try {
                    const shoppingResponse = await fetch('shopping-list.md', {method: 'HEAD'});
                    if (shoppingResponse.ok) {
                        document.getElementById('shoppingViewBtn').style.display = '';
                    }
                } catch (e) { /* no shopping list */ }

                // Display intro text if available
                if (inventoryData.intro) {
                    document.getElementById('intro').style.display = 'block';
                    document.getElementById('introText').innerHTML = markdownToHtml(inventoryData.intro);
                }

                buildImageIndex();
                buildSearchIndex();
                buildTagCollection();
                buildContainerPrefixes();
                buildCategoryCounts();

                // Build set of all container IDs for linking
                containerIds.clear();
                inventoryData.containers.forEach(container => {
                    if (container.id) {
                        containerIds.add(container.id);
                    }
                });

                displayFilters();
                displayTagFilter();
                displayCategoryBrowser();
                renderLanguageSelector();
                displayResults();
            } catch (error) {
                document.getElementById('results').innerHTML =
                    `<div class="no-results">${t.errorLoading}</div>`;
            }
        }

        // Highlight search terms in text (including aliases)
        function highlightText(text, term) {
            if (!term) return text;

            // Get all search terms including aliases
            const searchTerms = expandSearchWithAliases(term);

            // Escape special regex characters and create pattern for all terms
            const escapedTerms = searchTerms.map(t => t.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
            const regex = new RegExp(`(${escapedTerms.join('|')})`, 'gi');

            return text.replace(regex, '<span class="highlight">$1</span>');
        }

        // Clean heading by removing ID: prefix and other metadata
        function cleanHeading(heading) {
            // Remove patterns like "ID:xxx", "parent:xxx", etc.
            return heading.replace(/\(?(?:ID|parent|type):[^\s)]+\)?/gi, '').replace(/\s+/g, ' ').trim();
        }

        // Scroll to a container by ID
        function scrollToContainer(containerId) {
            // Check if target exists in current view
            let targetCard = document.querySelector(`[data-container-id="${containerId}"]`);

            // If not found, clear search to show all containers
            if (!targetCard) {
                // Clear search and switch to container view if needed
                searchTerm = '';
                const searchBox = document.getElementById('searchBox');
                if (searchBox) searchBox.value = '';

                // Switch to container view if in gallery mode
                if (currentView === 'gallery') {
                    currentView = 'containers';
                    document.querySelectorAll('.view-btn').forEach(btn => {
                        btn.classList.toggle('active', btn.dataset.view === 'containers');
                    });
                }

                displayResults();

                // Wait for DOM to update, then scroll
                // Use requestAnimationFrame for better timing
                requestAnimationFrame(() => {
                    setTimeout(() => {
                        const target = document.querySelector(`[data-container-id="${containerId}"]`);
                        if (target) {
                            // Expand the container if it's collapsed
                            if (!target.classList.contains('expanded')) {
                                target.classList.add('expanded');
                            }

                            target.scrollIntoView({ behavior: 'smooth', block: 'center' });

                            // Highlight with background color and border
                            const originalBg = target.style.backgroundColor;
                            const originalBorder = target.style.border;
                            target.style.backgroundColor = '#e3f2fd';
                            target.style.border = '3px solid #2196F3';
                            target.style.transition = 'all 0.3s ease';

                            setTimeout(() => {
                                target.style.backgroundColor = originalBg;
                                target.style.border = originalBorder;
                            }, 3000);
                        } else {
                            console.error(`Container ${containerId} not found in DOM after clearing filters`);
                            console.log('Available containers:', Array.from(document.querySelectorAll('[data-container-id]')).map(el => el.dataset.containerId));
                            showError(`Container ${containerId} ikke funnet`);
                        }
                    }, 200);
                });
            } else {
                // Expand the container if it's collapsed
                if (!targetCard.classList.contains('expanded')) {
                    targetCard.classList.add('expanded');
                }

                targetCard.scrollIntoView({ behavior: 'smooth', block: 'center' });

                // Highlight with background color and border
                const originalBg = targetCard.style.backgroundColor;
                const originalBorder = targetCard.style.border;
                targetCard.style.backgroundColor = '#e3f2fd';
                targetCard.style.border = '3px solid #2196F3';
                targetCard.style.transition = 'all 0.3s ease';

                setTimeout(() => {
                    targetCard.style.backgroundColor = originalBg;
                    targetCard.style.border = originalBorder;
                }, 3000);
            }
            return false; // Extra safeguard to prevent default behavior
        }

        // Check if container matches current filters
        function containerMatchesFilters(container) {
            // Filter by prefix
            if (currentFilter !== 'all') {
                const id = container.id || '';

                // Extract prefix from this container's ID
                let prefix = null;
                const match1 = id.match(/^([A-Za-z]+)\d+/);
                if (match1) {
                    prefix = match1[1];
                } else if (id.includes('-') || id.includes('_')) {
                    prefix = id.split(/[-_]/)[0];
                } else if (id.match(/^[A-Za-z]+$/)) {
                    prefix = id;
                }

                if (prefix !== currentFilter) return false;
            }

            // Filter by selected tags (AND logic - must have ALL selected tags)
            if (selectedTags.size > 0) {
                // Collect all tags from all items in this container
                const containerTags = new Set();
                container.items.forEach(item => {
                    if (item.metadata && item.metadata.tags) {
                        item.metadata.tags.forEach(tag => containerTags.add(tag));
                    }
                });

                // Check if container has ALL selected tags
                for (const tag of selectedTags) {
                    if (!containerTags.has(tag)) {
                        return false;
                    }
                }
            }

            // Filter by selected category
            if (selectedCategory) {
                // Check if any item in container matches the selected category
                const hasMatchingItem = container.items.some(item => itemMatchesCategory(item));
                if (!hasMatchingItem) {
                    return false;
                }
            }

            // Filter by search term
            if (searchTerm) {
                // Expand search term with aliases
                const searchTerms = expandSearchWithAliases(searchTerm);

                // Use pre-built search index for faster lookups
                const indexedText = searchIndex.get(container.id);
                if (indexedText) {
                    // Check if any of the search terms (original + aliases) match
                    return searchTerms.some(term => indexedText.includes(term));
                }

                // Fallback to direct search if not in index (shouldn't happen)
                const searchLower = searchTerm.toLowerCase();
                const matchInHeading = container.heading.toLowerCase().includes(searchLower);
                const matchInDescription = container.description.toLowerCase().includes(searchLower);
                const matchInItems = container.items.some(item => {
                    // Handle both string (old format) and object (new format)
                    if (typeof item === 'string') {
                        return item.toLowerCase().includes(searchLower);
                    }
                    return (
                        item.name?.toLowerCase().includes(searchLower) ||
                        item.id?.toLowerCase().includes(searchLower) ||
                        item.parent?.toLowerCase().includes(searchLower)
                    );
                });

                return matchInHeading || matchInDescription || matchInItems;
            }

            return true;
        }

        // Display gallery view
        function displayGalleryView() {
            const galleryDiv = document.getElementById('galleryGrid');
            const filteredContainers = inventoryData.containers.filter(containerMatchesFilters);

            // Get images from filtered containers
            const filteredImages = allImages.filter(img =>
                filteredContainers.some(container => container.id === img.containerId)
            );

            // Update stats
            document.getElementById('stats').innerHTML = `
                ${t.statsShowing} ${filteredImages.length} ${t.statsImages} ${t.statsOf} ${filteredContainers.length} ${t.statsContainers}
            `;

            if (filteredImages.length === 0) {
                galleryDiv.innerHTML = `<div class="no-results">${t.noImages}</div>`;
                return;
            }

            galleryDiv.innerHTML = filteredImages.map((imgData, globalIndex) => `
                <div class="gallery-image-wrapper" onclick="openLightboxAtIndex(${globalIndex})">
                    <img
                        data-src="${imgData.image.thumb}"
                        alt="${imgData.image.alt}"
                        class="lazy-image"
                    >
                    <div class="image-metadata">
                        <div class="image-container-id">${imgData.containerId}</div>
                        <div class="image-number">Bilde ${imgData.imageIndex}/${imgData.totalInContainer}</div>
                    </div>
                </div>
            `).join('');

            // Setup lazy loading
            setupLazyLoading();
        }

        // Shopping list view
        let shoppingListData = null;
        let shoppingListLoaded = false;

        async function loadShoppingList() {
            if (shoppingListLoaded) return;
            try {
                const response = await fetch('shopping-list.md');
                if (!response.ok) throw new Error('Not found');
                shoppingListData = await response.text();
                shoppingListLoaded = true;
            } catch (e) {
                shoppingListData = null;
            }
        }

        function parseShoppingListMarkdown(md) {
            const lines = md.split('\n');
            let html = '';
            let currentSection = '';
            let itemId = 0;

            for (const line of lines) {
                // Headers
                if (line.startsWith('# ')) {
                    html += `<h1>${line.substring(2)}</h1>`;
                } else if (line.startsWith('## ')) {
                    currentSection = line.substring(3);
                    html += `<h2>${currentSection}</h2>`;
                } else if (line.startsWith('Generated:')) {
                    html += `<p>${line}</p>`;
                } else if (line.startsWith('[!]')) {
                    // Missing/urgent item
                    const text = line.substring(4).trim();
                    const checked = localStorage.getItem(`shopping-${itemId}`) === 'true';
                    html += `<div class="shopping-item missing ${checked ? 'checked' : ''}" data-item-id="${itemId}">
                        <input type="checkbox" ${checked ? 'checked' : ''} onchange="toggleShoppingItem(${itemId}, this.checked)">
                        <span>${text}</span>
                    </div>`;
                    itemId++;
                } else if (line.startsWith('[ ]')) {
                    // Low stock item
                    const text = line.substring(4).trim();
                    const checked = localStorage.getItem(`shopping-${itemId}`) === 'true';
                    html += `<div class="shopping-item low ${checked ? 'checked' : ''}" data-item-id="${itemId}">
                        <input type="checkbox" ${checked ? 'checked' : ''} onchange="toggleShoppingItem(${itemId}, this.checked)">
                        <span>${text}</span>
                    </div>`;
                    itemId++;
                } else if (line.startsWith('**Summary:**')) {
                    html += `<div class="shopping-summary">${line.replace(/\*\*/g, '')}</div>`;
                } else if (line === '---') {
                    html += '<hr>';
                }
            }
            return html;
        }

        function toggleShoppingItem(itemId, checked) {
            localStorage.setItem(`shopping-${itemId}`, checked);
            const item = document.querySelector(`.shopping-item[data-item-id="${itemId}"]`);
            if (item) {
                item.classList.toggle('checked', checked);
            }
        }

        async function displayShoppingView() {
            const shoppingDiv = document.getElementById('shoppingList');
            document.getElementById('stats').innerHTML = '';

            if (!shoppingListLoaded) {
                shoppingDiv.innerHTML = `<p>${t.shoppingLoading}</p>`;
                await loadShoppingList();
            }

            if (shoppingListData) {
                shoppingDiv.innerHTML = parseShoppingListMarkdown(shoppingListData);
            } else {
                shoppingDiv.innerHTML = `<p>${t.shoppingError}</p>`;
            }
        }

        // Display results
        function displayResults() {
            if (currentView === 'gallery') {
                document.getElementById('results').style.display = 'none';
                document.getElementById('gallery-view').style.display = 'block';
                document.getElementById('shopping-view').style.display = 'none';
                displayGalleryView();
                return;
            }

            if (currentView === 'shopping') {
                document.getElementById('results').style.display = 'none';
                document.getElementById('gallery-view').style.display = 'none';
                document.getElementById('shopping-view').style.display = 'block';
                displayShoppingView();
                return;
            }

            // Container view
            document.getElementById('results').style.display = 'block';
            document.getElementById('gallery-view').style.display = 'none';
            document.getElementById('shopping-view').style.display = 'none';

            const resultsDiv = document.getElementById('results');
            const filteredContainers = inventoryData.containers.filter(containerMatchesFilters);

            // Update stats
            const imageCount = filteredContainers.reduce((sum, container) => sum + container.images.length, 0);
            document.getElementById('stats').innerHTML = `
                ${t.statsShowing} ${filteredContainers.length} ${t.statsOf} ${inventoryData.containers.length} ${t.statsContainers}
                (${imageCount} ${t.statsImages})
            `;

            if (filteredContainers.length === 0) {
                resultsDiv.innerHTML = `<div class="no-results">${t.noResults}</div>`;
                return;
            }

            resultsDiv.innerHTML = filteredContainers.map(container => `
                <div class="container-card" data-container-id="${container.id}">
                    <div class="container-header" onclick="toggleContainer(this, event)" title="${container.heading}">
                        <span class="container-id" title="Container ID: ${container.id}">${container.id}</span>
                        <span class="container-title">
                            ${highlightText(cleanHeading(container.heading), searchTerm)}
                            ${container.parent ? `<a href="#${container.parent}" class="parent-link" data-parent-id="${container.parent}" title="${t.goTo} ${container.parent}">📍 ${container.parent}</a>` : ''}
                        </span>
                        <span class="toggle-icon">▼</span>
                    </div>
                    <div class="container-content">
                        <div class="container-details">
                            ${container.description ? `
                                <div class="container-description">
                                    ${highlightText(container.description, searchTerm)}
                                </div>
                            ` : ''}

                            ${container.items.length > 0 ? `
                                <div class="items-list">
                                    <h3>${t.contents}</h3>
                                    <ul>
                                        ${container.items.map(item => {
                                            // Handle both string (old) and object (new) formats
                                            if (typeof item === 'string') {
                                                return `<li>${highlightText(item, searchTerm)}</li>`;
                                            }

                                            // Check if item matches category/tag filter for highlighting
                                            const matchesFilter = selectedCategory && itemMatchesCategory(item);

                                            // New format with metadata
                                            let html = matchesFilter ? '<li class="item-matches-filter">' : '<li>';
                                            if (item.id) {
                                                // Check if this item ID matches a container - make it clickable
                                                if (containerIds.has(item.id)) {
                                                    html += `<a href="#${item.id}" class="item-link" data-container-id="${item.id}" title="${t.goTo} ${item.id}">`;
                                                    html += `<code class="item-id">${item.id}</code>`;
                                                    html += `</a> `;
                                                } else {
                                                    html += `<code class="item-id">${item.id}</code> `;
                                                }
                                                // Add photo icon if item has photos in registry
                                                const photoCount = getItemPhotos(item.id).length;
                                                if (photoCount > 0) {
                                                    html += `<span class="item-photo-btn" onclick="showItemPhotos('${item.id}')" title="${photoCount} photo(s)">📷</span> `;
                                                }
                                            }
                                            html += `<span class="item-name">${highlightText(item.name, searchTerm)}</span>`;
                                            if (item.parent) {
                                                html += ` <span class="item-parent">↑ ${item.parent}</span>`;
                                            }
                                            // Display tags as badges
                                            if (item.metadata && item.metadata.tags && item.metadata.tags.length > 0) {
                                                html += ' <span class="item-tags">';
                                                item.metadata.tags.forEach(tag => {
                                                    html += `<span class="tag-badge">${tag}</span>`;
                                                });
                                                html += '</span>';
                                            }
                                            // Display categories as badges
                                            if (item.metadata && item.metadata.categories && item.metadata.categories.length > 0) {
                                                html += ' <span class="item-categories">';
                                                item.metadata.categories.forEach(cat => {
                                                    // Expand to SKOS path if available
                                                    const expandedPaths = expandCategoryToSkosPaths(cat);
                                                    const expandedCat = expandedPaths[0] || cat;
                                                    const concept = vocabularyData?.concepts?.[expandedCat];
                                                    const label = concept ? getConceptLabel(concept) : cat.split('/').pop();
                                                    html += `<span class="category-badge" onclick="selectCategory('${expandedCat}', event)" title="${expandedCat}">${label}</span>`;
                                                });
                                                html += '</span>';
                                            }
                                            html += '</li>';
                                            return html;
                                        }).join('')}
                                    </ul>
                                </div>
                            ` : ''}

                            ${container.photos_link ? `
                                <a href="${container.photos_link}" class="photos-link" target="_blank">
                                    ${t.viewPhotos}
                                </a>
                            ` : ''}

                            ${container.images.length > 0 ? `
                                <div class="images-grid">
                                    ${container.images.map(img => `
                                        <div class="image-wrapper" onclick="openLightbox('${img.full}')">
                                            <img
                                                data-src="${img.thumb}"
                                                alt="${img.alt}"
                                                class="lazy-image"
                                            >
                                        </div>
                                    `).join('')}
                                </div>
                            ` : ''}
                        </div>
                    </div>
                </div>
            `).join('');

            // Setup lazy loading for images
            setupLazyLoading();
        }

        // Toggle container expansion
        function toggleContainer(header, event) {
            // Check if click came from a link - if so, ignore and let the link handler deal with it
            if (event && (event.target.tagName === 'A' || event.target.closest('a'))) {
                return;
            }

            const card = header.parentElement;
            const wasExpanded = card.classList.contains('expanded');

            card.classList.toggle('expanded');

            // If expanding, load images
            if (!wasExpanded) {
                loadVisibleImages(card);
            }
        }

        // Setup Intersection Observer for lazy loading
        function setupLazyLoading() {
            const imageObserver = new IntersectionObserver((entries, observer) => {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        const img = entry.target;
                        img.src = img.dataset.src;
                        img.onload = () => {
                            img.classList.add('loaded');
                        };
                        observer.unobserve(img);
                    }
                });
            }, {
                rootMargin: '50px'
            });

            document.querySelectorAll('.lazy-image').forEach(img => {
                imageObserver.observe(img);
            });
        }

        // Load images for a specific box
        function loadVisibleImages(card) {
            const images = card.querySelectorAll('.lazy-image');
            images.forEach(img => {
                if (!img.src || img.src === window.location.href) {
                    img.src = img.dataset.src;
                    img.onload = () => {
                        img.classList.add('loaded');
                    };
                }
            });
        }

        // Lightbox functions
        function openLightbox(src) {
            currentLightboxIndex = -1;
            const lightbox = document.getElementById('lightbox');
            const lightboxImg = document.getElementById('lightboxImg');
            const lightboxInfo = document.getElementById('lightboxInfo');
            lightboxImg.src = src;
            lightboxInfo.innerHTML = '';
            lightbox.classList.add('active');
        }

        function openLightboxAtIndex(index) {
            if (currentView !== 'gallery') {
                // If opening from box view, find the image in allImages
                currentLightboxIndex = index;
            } else {
                // In gallery view, use the filtered images
                const filteredContainers = inventoryData.containers.filter(containerMatchesFilters);
                const filteredImages = allImages.filter(img =>
                    filteredContainers.some(container => container.id === img.containerId)
                );
                currentLightboxIndex = index;
            }

            updateLightbox();
        }

        function updateLightbox() {
            const filteredContainers = inventoryData.containers.filter(containerMatchesFilters);
            const filteredImages = allImages.filter(img =>
                filteredContainers.some(container => container.id === img.containerId)
            );

            if (currentLightboxIndex < 0 || currentLightboxIndex >= filteredImages.length) {
                return;
            }

            const imgData = filteredImages[currentLightboxIndex];
            const lightbox = document.getElementById('lightbox');
            const lightboxImg = document.getElementById('lightboxImg');
            const lightboxInfo = document.getElementById('lightboxInfo');

            lightboxImg.src = imgData.image.full;
            lightboxInfo.innerHTML = `
                ${t.imageOf} ${currentLightboxIndex + 1} ${t.statsOf} ${filteredImages.length} |
                ${t.container}: ${imgData.containerId} (${imgData.imageIndex}/${imgData.totalInContainer})
            `;
            lightbox.classList.add('active');
        }

        function navigateLightbox(direction) {
            // Check if we're in item photo mode
            if (window.itemPhotoMode && window.currentItemPhotos) {
                navigateItemPhotos(direction);
                return;
            }

            const filteredContainers = inventoryData.containers.filter(containerMatchesFilters);
            const filteredImages = allImages.filter(img =>
                filteredContainers.some(container => container.id === img.containerId)
            );

            currentLightboxIndex += direction;

            // Wrap around
            if (currentLightboxIndex < 0) {
                currentLightboxIndex = filteredImages.length - 1;
            } else if (currentLightboxIndex >= filteredImages.length) {
                currentLightboxIndex = 0;
            }

            updateLightbox();
        }

        function closeLightbox() {
            document.getElementById('lightbox').classList.remove('active');
            currentLightboxIndex = -1;
            // Clear item photo mode
            window.itemPhotoMode = false;
            window.currentItemPhotos = null;
            window.currentItemPhotoIndex = 0;
        }

        // Error Modal Functions
        function showError(message) {
            const errorModal = document.getElementById('errorModal');
            const errorMessage = document.getElementById('errorMessage');
            errorMessage.textContent = message;
            errorModal.classList.add('active');
        }

        function closeErrorModal() {
            document.getElementById('errorModal').classList.remove('active');
        }

        function copyErrorMessage() {
            const errorMessage = document.getElementById('errorMessage').textContent;
            navigator.clipboard.writeText(errorMessage).then(() => {
                const btn = event.target;
                const originalText = btn.textContent;
                btn.textContent = '✅ Kopiert!';
                setTimeout(() => {
                    btn.textContent = originalText;
                }, 2000);
            }).catch(err => {
                console.error('Failed to copy:', err);
            });
        }

        // Close error modal on background click
        document.getElementById('errorModal').addEventListener('click', (e) => {
            if (e.target.id === 'errorModal') {
                closeErrorModal();
            }
        });

        // Close category modal on background click
        document.getElementById('categoryModal').addEventListener('click', (e) => {
            if (e.target.id === 'categoryModal') {
                closeCategoryModal();
            }
        });

        // Close modals on Escape key
        document.addEventListener('keydown', (e) => {
            if (e.key === 'Escape') {
                closeErrorModal();
                closeCategoryModal();
            }
        });

        // Search functionality with debouncing
        document.getElementById('searchBox').addEventListener('input', (e) => {
            searchTerm = e.target.value.trim();

            // Clear existing timeout
            if (searchDebounceTimeout) {
                clearTimeout(searchDebounceTimeout);
            }

            // Debounce: wait 150ms after user stops typing
            searchDebounceTimeout = setTimeout(() => {
                displayResults();
            }, 150);
        });

        // Filter functionality
        document.getElementById('filters').addEventListener('click', (e) => {
            if (e.target.classList.contains('filter-btn')) {
                document.querySelectorAll('.filter-btn').forEach(btn => {
                    btn.classList.remove('active');
                });
                e.target.classList.add('active');
                currentFilter = e.target.dataset.filter;
                displayResults();
            }
        });

        // Tag filter functionality
        document.addEventListener('click', (e) => {
            if (e.target.classList.contains('tag-filter-btn')) {
                const tag = e.target.dataset.tag;

                if (!tag) {
                    // Clear all button clicked
                    selectedTags.clear();
                } else {
                    // Toggle tag selection
                    if (selectedTags.has(tag)) {
                        selectedTags.delete(tag);
                    } else {
                        selectedTags.add(tag);
                    }
                }

                displayTagFilter(); // Update button states
                displayResults();
            }
        });

        // View toggle functionality
        document.querySelectorAll('.view-btn').forEach(btn => {
            btn.addEventListener('click', (e) => {
                document.querySelectorAll('.view-btn').forEach(b => b.classList.remove('active'));
                e.target.classList.add('active');
                currentView = e.target.dataset.view;
                displayResults();
            });
        });

        // Keyboard navigation for lightbox
        document.addEventListener('keydown', (e) => {
            if (e.key === 'Escape') {
                closeLightbox();
            } else if (e.key === 'ArrowLeft' && currentLightboxIndex >= 0) {
                navigateLightbox(-1);
            } else if (e.key === 'ArrowRight' && currentLightboxIndex >= 0) {
                navigateLightbox(1);
            }
        });

        // Close lightbox on background click
        document.getElementById('lightbox').addEventListener('click', (e) => {
            if (e.target.id === 'lightbox') {
                closeLightbox();
            }
        });

        // ==================== SWIPE GESTURES FOR LIGHTBOX ====================
        let touchStartX = 0;
        let touchStartY = 0;
        let touchEndX = 0;
        let touchEndY = 0;
        const MIN_SWIPE_DISTANCE = 50;
        const MAX_VERTICAL_DISTANCE = 100;

        const lightboxElement = document.getElementById('lightbox');

        lightboxElement.addEventListener('touchstart', (e) => {
            touchStartX = e.changedTouches[0].screenX;
            touchStartY = e.changedTouches[0].screenY;
        }, { passive: true });

        lightboxElement.addEventListener('touchend', (e) => {
            touchEndX = e.changedTouches[0].screenX;
            touchEndY = e.changedTouches[0].screenY;
            handleSwipe();
        }, { passive: true });

        function handleSwipe() {
            const deltaX = touchEndX - touchStartX;
            const deltaY = Math.abs(touchEndY - touchStartY);

            // Only handle horizontal swipes (not vertical scrolls)
            if (Math.abs(deltaX) > MIN_SWIPE_DISTANCE && deltaY < MAX_VERTICAL_DISTANCE) {
                if (deltaX > 0) {
                    // Swiped right - previous image
                    navigateLightbox(-1);
                } else {
                    // Swiped left - next image
                    navigateLightbox(1);
                }

                // Hide swipe indicator after first successful swipe
                const indicator = document.getElementById('swipeIndicator');
                if (indicator) {
                    indicator.style.display = 'none';
                }
            }
        }

        // Track scroll position for body lock
        let scrollPosition = 0;

        // Enhanced openLightbox with body scroll lock
        const originalOpenLightbox = openLightbox;
        openLightbox = function(src) {
            scrollPosition = window.pageYOffset;
            document.body.classList.add('lightbox-open');
            document.body.style.top = `-${scrollPosition}px`;
            originalOpenLightbox(src);
        };

        // Enhanced openLightboxAtIndex with body scroll lock
        const originalOpenLightboxAtIndex = openLightboxAtIndex;
        openLightboxAtIndex = function(index) {
            scrollPosition = window.pageYOffset;
            document.body.classList.add('lightbox-open');
            document.body.style.top = `-${scrollPosition}px`;
            originalOpenLightboxAtIndex(index);
        };

        // Enhanced closeLightbox with body scroll restore
        const originalCloseLightbox = closeLightbox;
        closeLightbox = function() {
            document.body.classList.remove('lightbox-open');
            document.body.style.top = '';
            window.scrollTo(0, scrollPosition);
            originalCloseLightbox();
        };

        // Event delegation for parent and item links
        document.addEventListener('click', (e) => {
            // Handle parent links
            if (e.target.classList.contains('parent-link') || e.target.closest('.parent-link')) {
                e.preventDefault();
                e.stopPropagation();
                const link = e.target.classList.contains('parent-link') ? e.target : e.target.closest('.parent-link');
                const parentId = link.dataset.parentId;
                if (parentId) {
                    scrollToContainer(parentId);
                }
            }
            // Handle item links (items with IDs that match containers)
            else if (e.target.classList.contains('item-link') || e.target.closest('.item-link')) {
                e.preventDefault();
                e.stopPropagation();
                const link = e.target.classList.contains('item-link') ? e.target : e.target.closest('.item-link');
                const containerId = link.dataset.containerId;
                if (containerId) {
                    scrollToContainer(containerId);
                }
            }
        });

        // Handle window resize - re-render tag filter for responsive layout
        let resizeTimeout = null;
        window.addEventListener('resize', () => {
            if (resizeTimeout) clearTimeout(resizeTimeout);
            resizeTimeout = setTimeout(() => {
                displayTagFilter();
            }, 150);
        });

        // Initialize tag filter as collapsed on mobile
        document.addEventListener('DOMContentLoaded', () => {
            if (isMobile()) {
                const tagFilterDiv = document.getElementById('tagFilter');
                if (tagFilterDiv) {
                    tagFilterDiv.classList.add('collapsed');
                }
            }
        });

        // Load data on page load
        loadData();
    </script>
</body>
</html>
