<?php
// =================================================================
// 1. CATÁLOGO PRO (Tablas Inteligentes + Formularios Avanzados)
// =================================================================

$catalog = [
    'Layout' => [
        ['type' => 'row', 'label' => 'Fila (Row)', 'icon' => 'bi-layout-three-columns', 'desc' => 'Contenedor horizontal'],
        ['type' => 'col', 'label' => 'Columna', 'icon' => 'bi-layout-column', 'desc' => 'Espacio vertical'],
        ['type' => 'container', 'label' => 'Contenedor', 'icon' => 'bi-box', 'desc' => 'Container fluido o fijo'],
    ],
    'Tablas de Datos' => [
        ['type' => 'smart_table', 'label' => 'Tabla JSON', 'icon' => 'bi-table', 'desc' => 'Tabla generada por datos'],
    ],
    'Formularios' => [
        ['type' => 'form_label', 'label' => 'Label', 'icon' => 'bi-fonts', 'desc' => 'Etiqueta de campo'],
        ['type' => 'input', 'label' => 'Input Texto', 'icon' => 'bi-input-cursor-text', 'desc' => 'Campo simple'],
        ['type' => 'input_group', 'label' => 'Input Group', 'icon' => 'bi-collection', 'desc' => 'Input con icono/texto'],
        ['type' => 'floating_input', 'label' => 'Floating Label', 'icon' => 'bi-card-text', 'desc' => 'Etiqueta flotante'],
        ['type' => 'select', 'label' => 'Select', 'icon' => 'bi-menu-button', 'desc' => 'Lista desplegable'],
        ['type' => 'checkbox', 'label' => 'Checkbox', 'icon' => 'bi-check-square', 'desc' => 'Selección única'],
        ['type' => 'switch', 'label' => 'Switch', 'icon' => 'bi-toggle-on', 'desc' => 'Interruptor'],
        ['type' => 'textarea', 'label' => 'Textarea', 'icon' => 'bi-textarea-resize', 'desc' => 'Texto largo'],
        ['type' => 'button', 'label' => 'Botón Submit', 'icon' => 'bi-hand-index-thumb', 'desc' => 'Botón de envío'],
    ],
    'Componentes UI' => [
        ['type' => 'card', 'label' => 'Tarjeta', 'icon' => 'bi-card-heading', 'desc' => 'Panel contenedor'],
        ['type' => 'alert', 'label' => 'Alerta', 'icon' => 'bi-exclamation-circle', 'desc' => 'Mensaje aviso'],
        ['type' => 'badge', 'label' => 'Badge', 'icon' => 'bi-tag', 'desc' => 'Etiqueta'],
        ['type' => 'img', 'label' => 'Imagen', 'icon' => 'bi-image', 'desc' => 'Imagen URL'],
        ['type' => 'h3', 'label' => 'Título', 'icon' => 'bi-type-h3', 'desc' => 'Texto encabezado'],
        ['type' => 'p', 'label' => 'Párrafo', 'icon' => 'bi-paragraph', 'desc' => 'Texto normal'],
    ]
];
?>

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>App Builder v3.0 - Tablas & Forms</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css">

    <style>
        body { background-color: #f8f9fa; height: 100vh; overflow: hidden; }
        
        /* Workspace con Grid */
        #editor-area {
            height: calc(100vh - 60px);
            overflow-y: auto;
            background-color: #ffffff;
            background-image: 
                linear-gradient(#e9ecef 1px, transparent 1px), 
                linear-gradient(90deg, #e9ecef 1px, transparent 1px);
            background-size: 20px 20px;
            padding: 40px;
        }

        /* Componente en Editor */
        .editable-component {
            position: relative;
            border: 1px dashed transparent;
            min-height: 40px;
            cursor: pointer;
            transition: all 0.2s;
        }
        .editable-component:hover { 
            border: 1px dashed #0d6efd; 
            background-color: rgba(13, 110, 253, 0.02);
        }
        
        /* Estado Seleccionado */
        .editable-component.active-selection {
            outline: 2px solid #0d6efd;
            background-color: rgba(13, 110, 253, 0.05);
            z-index: 100;
        }

        /* Etiqueta Tipo Componente */
        .comp-label {
            display: none; position: absolute; top: -20px; left: -2px;
            background: #0d6efd; color: white; font-size: 9px; padding: 2px 6px;
            border-radius: 4px 4px 0 0; font-weight: bold; letter-spacing: 0.5px;
            text-transform: uppercase; z-index: 101;
        }
        .active-selection > .comp-label { display: block; }

        /* Botón Eliminar */
        .delete-btn {
            display: none; position: absolute; top: -15px; right: -10px;
            z-index: 102; border-radius: 50%; width: 24px; height: 24px;
            padding: 0; line-height: 22px; text-align: center;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
        }
        .active-selection > .delete-btn { display: block; }

        /* Estilo Botones Menú */
        .tool-btn { 
            text-align: left; transition: all 0.2s; 
            border: 1px solid #e9ecef; background: white; 
            font-size: 0.85rem; padding: 8px 12px; margin-bottom: 4px;
        }
        .tool-btn:hover { 
            background-color: #f0f8ff; border-color: #0d6efd; 
            color: #0d6efd; padding-left: 15px; 
        }
        
        /* Placeholder visual para columnas vacías */
        .empty-placeholder {
            border: 2px dashed #dee2e6; color: #adb5bd; padding: 20px; 
            text-align: center; border-radius: 8px; font-size: 0.8rem;
            background: #fdfdfd; margin: 5px;
        }

        /* JSON Editor Estilo */
        textarea.code-editor {
            font-family: 'Courier New', Courier, monospace;
            font-size: 0.85rem;
            background-color: #212529;
            color: #00ff9d;
            border: none;
        }
    </style>
</head>
<body>

<nav class="navbar navbar-dark bg-dark px-3 shadow-sm" style="height: 60px;">
    <div class="d-flex align-items-center">
        <span class="navbar-brand mb-0 h1"><i class="bi bi-layers-half"></i> AppBuilder 3.0</span>
    </div>
    <div>
        <button class="btn btn-outline-light btn-sm me-2" onclick="exportJSON()"><i class="bi bi-filetype-json"></i> JSON</button>
        <button class="btn btn-outline-warning btn-sm" onclick="resetWorkspace()"><i class="bi bi-trash3"></i> Limpiar</button>
    </div>
</nav>

<div class="container-fluid h-100">
    <div class="row h-100">
        
        <div class="col-md-2 p-0 border-end bg-white d-flex flex-column shadow-sm" style="height: calc(100vh - 60px); z-index: 5;">
            <div class="p-3 bg-light border-bottom">
                <input type="text" class="form-control form-control-sm" placeholder="🔍 Buscar componente..." id="searchTool" onkeyup="filterTools()">
            </div>
            
            <div class="flex-grow-1 overflow-auto p-2" id="toolsContainer">
                <?php foreach ($catalog as $category => $items): ?>
                    <h6 class="text-secondary fw-bold mt-3 mb-2 ps-2" style="font-size: 0.7rem; text-transform: uppercase; letter-spacing: 1px;">
                        <?= $category ?>
                    </h6>
                    <div class="d-grid">
                        <?php foreach ($items as $item): ?>
                            <button class="btn btn-sm tool-btn rounded" onclick="addComponent('<?= $item['type'] ?>')" title="<?= $item['desc'] ?>">
                                <i class="bi <?= $item['icon'] ?> me-2"></i> <?= $item['label'] ?>
                            </button>
                        <?php endforeach; ?>
                    </div>
                <?php endforeach; ?>
            </div>
        </div>

        <div class="col-md-10 p-0">
            <div id="editor-area">
                <div id="workspace" class="container pb-5"></div>
            </div>
        </div>

    </div>
</div>

<div class="offcanvas offcanvas-end shadow" data-bs-scroll="true" data-bs-backdrop="false" tabindex="-1" id="propPanel" style="width: 350px;">
    <div class="offcanvas-header bg-dark text-white border-bottom border-secondary">
        <h5 class="offcanvas-title fs-6"><i class="bi bi-sliders2"></i> PROPIEDADES</h5>
        <button type="button" class="btn-close btn-close-white" data-bs-dismiss="offcanvas"></button>
    </div>
    <div class="offcanvas-body bg-light">
        
        <div class="row g-2 mb-3">
            <div class="col-12">
                <label class="small fw-bold text-muted">TIPO</label>
                <input type="text" id="prop-type" class="form-control form-control-sm bg-white fw-bold text-primary" disabled readonly>
            </div>
        </div>

        <div id="table-data-section" class="mb-3" style="display:none;">
            <label class="small fw-bold text-success"><i class="bi bi-database"></i> DATOS DE TABLA (JSON)</label>
            <div class="form-text small mb-1">Array de objetos. Las claves serán las cabeceras.</div>
            <textarea id="prop-table-data" class="form-control code-editor p-2 rounded" rows="8" oninput="updateTableData(this.value)"></textarea>
            
            <label class="small fw-bold mt-3">Estilos de Tabla</label>
            <select id="prop-table-style" class="form-select form-select-sm mt-1" onchange="updateProp('className', this.value)">
                <option value="table table-bordered">Básica con bordes</option>
                <option value="table table-striped">Rayada (Striped)</option>
                <option value="table table-hover">Hover</option>
                <option value="table table-dark table-striped">Oscura</option>
                <option value="table table-borderless">Sin bordes</option>
            </select>
        </div>

        <div id="general-text-section" class="mb-3">
            <label class="small fw-bold text-dark" id="lbl-content">Contenido / Texto</label>
            <textarea id="prop-text" class="form-control" rows="2" oninput="updateProp('text', this.value)"></textarea>
        </div>

        <div id="input-config-section" class="mb-3 p-3 bg-white border rounded" style="display:none;">
            <h6 class="small fw-bold text-muted border-bottom pb-2">CONFIGURACIÓN INPUT</h6>
            
            <label class="small mt-2">Tipo de Input</label>
            <select id="prop-input-type" class="form-select form-select-sm" onchange="updateProp('inputType', this.value)">
                <option value="text">Texto</option>
                <option value="email">Email</option>
                <option value="password">Password</option>
                <option value="number">Número</option>
                <option value="date">Fecha</option>
                <option value="color">Color</option>
                <option value="file">Archivo</option>
            </select>

            <label class="small mt-2">Placeholder</label>
            <input type="text" id="prop-placeholder" class="form-control form-control-sm" oninput="updateProp('placeholder', this.value)">
        </div>

        <div id="col-settings" class="card p-3 mb-3 border-secondary" style="display:none;">
            <label class="d-flex justify-content-between small fw-bold mb-2">
                <span>Ancho Columna (1-12)</span>
                <span class="badge bg-secondary" id="col-display">12</span>
            </label>
            <input type="range" class="form-range" min="1" max="12" id="prop-col-size" oninput="updateProp('colSize', this.value)">
        </div>

        <div class="mb-3">
            <label class="small fw-bold">Clases CSS</label>
            <input type="text" id="prop-class" class="form-control form-control-sm" placeholder="Ej: mt-3 text-center shadow" oninput="updateProp('className', this.value)">
        </div>

        <div id="variant-settings" class="mb-4" style="display:none;">
            <label class="small fw-bold">Color / Tema</label>
            <select id="prop-variant" class="form-select form-select-sm" onchange="updateProp('variant', this.value)">
                <option value="primary">Primary</option>
                <option value="secondary">Secondary</option>
                <option value="success">Success</option>
                <option value="danger">Danger</option>
                <option value="warning">Warning</option>
                <option value="info">Info</option>
                <option value="dark">Dark</option>
                <option value="light">Light</option>
            </select>
        </div>

        <button class="btn btn-danger w-100" onclick="deleteCurrent()">
            <i class="bi bi-trash"></i> Eliminar Componente
        </button>
    </div>
</div>

<div class="modal fade" id="jsonModal" tabindex="-1">
    <div class="modal-dialog modal-xl">
        <div class="modal-content">
            <div class="modal-header bg-dark text-white">
                <h5 class="modal-title">Estructura JSON</h5>
                <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body p-0">
                <textarea id="json-output" class="form-control code-editor w-100" style="height: 600px;"></textarea>
            </div>
        </div>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
    // 1. DATA INICIAL
    // Ejemplo con una tabla precargada
    let layout = [
        { id: 'root', type: 'container', className: 'mt-5', children: [
            { id: 'r1', type: 'row', children: [
                { id: 'c1', type: 'col', colSize: '12', children: [
                    { id: 'h1', type: 'h3', text: 'Gestión de Usuarios', className: 'mb-4 border-bottom pb-2' },
                    { 
                        id: 'tbl1', 
                        type: 'smart_table', 
                        className: 'table table-striped table-hover',
                        // DATOS DE EJEMPLO PARA LA TABLA
                        tableData: JSON.stringify([
                            { "ID": 101, "Nombre": "Carlos Pérez", "Rol": "Admin", "Estado": "Activo" },
                            { "ID": 102, "Nombre": "Maria Lopez", "Rol": "Editor", "Estado": "Inactivo" },
                            { "ID": 103, "Nombre": "Juan Diaz", "Rol": "User", "Estado": "Activo" }
                        ], null, 2)
                    }
                ]}
            ]}
        ]}
    ];

    let selectedId = null;
    let offcanvas = null;

    document.addEventListener('DOMContentLoaded', () => {
        offcanvas = new bootstrap.Offcanvas(document.getElementById('propPanel'));
        render();
    });

    // 2. MOTOR DE RENDERIZADO
    function render() {
        const ws = document.getElementById('workspace');
        ws.innerHTML = '';
        layout.forEach(node => ws.appendChild(createEl(node)));
    }

    function createEl(node) {
        let el = document.createElement('div');
        el.dataset.id = node.id;
        el.className = `editable-component ${node.id === selectedId ? 'active-selection' : ''}`;
        el.onclick = (e) => { e.stopPropagation(); select(node.id); };

        // Etiqueta Tipo
        el.innerHTML = `
            <div class="comp-label">${node.type.replace('_', ' ')}</div>
            <button class="btn btn-danger btn-sm delete-btn" onclick="event.stopPropagation(); del('${node.id}')"><i class="bi bi-x"></i></button>
        `;

        let content = null;
        let txt = node.text || '';
        let variant = node.variant || 'primary';
        
        switch(node.type) {
            // --- ESTRUCTURA ---
            case 'container':
                el.classList.add('container', 'border', 'border-light', 'p-3', 'bg-white', 'shadow-sm');
                if(node.className) el.classList.add(...node.className.split(' '));
                break;
            case 'row':
                el.classList.add('row');
                if(node.className) el.classList.add(...node.className.split(' '));
                el.style.border = "1px dashed #ccc"; el.style.padding = "10px";
                break;
            case 'col':
                el.classList.add(`col-md-${node.colSize || 12}`);
                if(node.className) el.classList.add(...node.className.split(' '));
                if(!node.children?.length) el.innerHTML += `<div class="empty-placeholder">Columna Vacía</div>`;
                break;

            // --- TABLAS INTELIGENTES ---
            case 'smart_table':
                let table = document.createElement('table');
                table.className = node.className || 'table table-bordered';
                try {
                    let data = JSON.parse(node.tableData || '[]');
                    if(Array.isArray(data) && data.length > 0) {
                        // Generar THEAD
                        let thead = document.createElement('thead');
                        let trHead = document.createElement('tr');
                        Object.keys(data[0]).forEach(key => {
                            let th = document.createElement('th');
                            th.textContent = key;
                            trHead.appendChild(th);
                        });
                        thead.appendChild(trHead);
                        table.appendChild(thead);

                        // Generar TBODY
                        let tbody = document.createElement('tbody');
                        data.forEach(row => {
                            let tr = document.createElement('tr');
                            Object.values(row).forEach(val => {
                                let td = document.createElement('td');
                                td.textContent = val;
                                tr.appendChild(td);
                            });
                            tbody.appendChild(tr);
                        });
                        table.appendChild(tbody);
                    } else {
                        table.innerHTML = `<tr><td class="text-center text-muted p-3">La tabla no tiene datos o el JSON es inválido.</td></tr>`;
                    }
                } catch(e) {
                    table.innerHTML = `<tr><td class="text-danger p-3">Error en JSON: ${e.message}</td></tr>`;
                }
                el.appendChild(table);
                break;

            // --- FORMULARIOS ---
            case 'form_label':
                content = document.createElement('label'); content.className = `form-label ${node.className||''}`;
                content.textContent = txt; el.appendChild(content); break;
                
            case 'input':
                content = document.createElement('input'); 
                content.type = node.inputType || 'text';
                content.className = `form-control ${node.className||''}`;
                content.placeholder = node.placeholder || 'Placeholder...';
                content.disabled = true; el.appendChild(content); break;

            case 'input_group':
                // Ejemplo: [@] [Input]
                let grp = document.createElement('div'); grp.className = "input-group mb-3";
                grp.innerHTML = `<span class="input-group-text"><i class="bi bi-person"></i></span>
                                 <input type="text" class="form-control" placeholder="${txt}" disabled>`;
                el.appendChild(grp); break;

            case 'floating_input':
                let flt = document.createElement('div'); flt.className = "form-floating mb-3";
                flt.innerHTML = `<input type="email" class="form-control" id="flt-${node.id}" placeholder="name@example.com" disabled>
                                 <label for="flt-${node.id}">${txt}</label>`;
                el.appendChild(flt); break;

            case 'select':
                content = document.createElement('select'); content.className = `form-select ${node.className||''}`;
                content.innerHTML = `<option selected>${txt}</option><option>Opción 2</option><option>Opción 3</option>`;
                content.disabled = true; el.appendChild(content); break;

            case 'checkbox':
                el.innerHTML += `<div class="form-check"><input class="form-check-input" type="checkbox" disabled> <label class="form-check-label">${txt}</label></div>`; break;
            
            case 'switch':
                el.innerHTML += `<div class="form-check form-switch"><input class="form-check-input" type="checkbox" disabled> <label class="form-check-label">${txt}</label></div>`; break;

            case 'textarea':
                content = document.createElement('textarea'); content.className = `form-control ${node.className||''}`;
                content.placeholder = txt; content.rows = 3; content.disabled = true; el.appendChild(content); break;

            // --- UI STANDARD ---
            case 'h3':
                content = document.createElement('h3'); content.textContent = txt; content.className = node.className||''; el.appendChild(content); break;
            case 'p':
                content = document.createElement('p'); content.textContent = txt; content.className = node.className||''; el.appendChild(content); break;
            case 'button':
                content = document.createElement('button'); content.className = `btn btn-${variant} ${node.className||''}`;
                content.textContent = txt; el.appendChild(content); break;
            case 'alert':
                content = document.createElement('div'); content.className = `alert alert-${variant} ${node.className||''}`;
                content.textContent = txt; el.appendChild(content); break;
            case 'badge':
                content = document.createElement('span'); content.className = `badge bg-${variant} ${node.className||''}`;
                content.textContent = txt; el.appendChild(content); el.classList.add('d-inline-block'); break;
            case 'card':
                content = document.createElement('div'); content.className = `card ${node.className||''}`;
                content.innerHTML = `<div class="card-body"><h5 class="card-title">Título</h5><p class="card-text">${txt}</p></div>`;
                el.appendChild(content); break;
            case 'img':
                content = document.createElement('img'); content.className = `img-fluid rounded ${node.className||''}`;
                content.src = txt || 'https://via.placeholder.com/150'; el.appendChild(content); break;
        }

        if (node.children) node.children.forEach(child => el.appendChild(createEl(child)));
        return el;
    }

    // 3. LÓGICA DE NEGOCIO
    function find(id, list=layout) {
        for(let n of list) {
            if(n.id === id) return n;
            if(n.children) { let f = find(id, n.children); if(f) return f; }
        }
        return null;
    }

    function addComponent(type) {
        let node = { id: `n-${Date.now()}`, type, text: '', children: [] };
        
        // Config Default
        if(type === 'smart_table') {
            node.tableData = JSON.stringify([
                {"#": 1, "Producto": "Laptop", "Precio": "$1200"}, 
                {"#": 2, "Producto": "Mouse", "Precio": "$25"}
            ], null, 2);
            node.className = "table table-bordered";
        }
        else if(type === 'input') node.placeholder = "Escribe algo...";
        else if(type === 'h3') node.text = "Nuevo Título";
        else if(type === 'button') node.text = "Enviar";
        else if(type === 'floating_input') node.text = "Correo Electrónico";
        else if(type === 'form_label') node.text = "Etiqueta:";
        else node.text = "Contenido";

        if(!selectedId) {
            if(type !== 'container') return alert("Empieza con un 'Contenedor'.");
            layout.push(node);
        } else {
            let p = find(selectedId);
            // Validaciones básicas de anidación
            if(p.type === 'row' && type !== 'col') return alert("Fila solo acepta Columnas.");
            if(p.type !== 'row' && type === 'col') return alert("Columna solo va en Fila.");
            
            // Elementos terminales que no aceptan hijos
            const terminals = ['input','select','textarea','button','h3','p','img','alert','badge','checkbox','switch','form_label','floating_input','input_group','smart_table'];
            if(terminals.includes(p.type)) return alert("Este elemento no puede contener otros componentes. Selecciona la Columna o Contenedor.");

            if(!p.children) p.children = [];
            p.children.push(node);
        }
        render();
    }

    function select(id) {
        selectedId = id;
        render();
        let n = find(id);
        
        // Reset Inputs
        document.getElementById('prop-type').value = n.type.toUpperCase();
        document.getElementById('prop-text').value = n.text || '';
        document.getElementById('prop-class').value = n.className || '';
        document.getElementById('prop-placeholder').value = n.placeholder || '';
        document.getElementById('prop-input-type').value = n.inputType || 'text';

        // LÓGICA DE VISIBILIDAD DE PANELES
        
        // 1. Panel Tablas
        const isTable = (n.type === 'smart_table');
        document.getElementById('table-data-section').style.display = isTable ? 'block' : 'none';
        document.getElementById('general-text-section').style.display = isTable ? 'none' : 'block'; // Ocultar texto general si es tabla
        
        if(isTable) {
            document.getElementById('prop-table-data').value = n.tableData;
            document.getElementById('prop-table-style').value = n.className || 'table table-bordered';
        }

        // 2. Panel Inputs
        const isInput = ['input', 'floating_input'].includes(n.type);
        document.getElementById('input-config-section').style.display = isInput ? 'block' : 'none';

        // 3. Panel Columnas
        const isCol = (n.type === 'col');
        document.getElementById('col-settings').style.display = isCol ? 'block' : 'none';
        if(isCol) {
            document.getElementById('prop-col-size').value = n.colSize || 12;
            document.getElementById('col-display').innerText = n.colSize || 12;
        }

        // 4. Panel Variantes
        const hasVariant = ['button','alert','badge'].includes(n.type);
        document.getElementById('variant-settings').style.display = hasVariant ? 'block' : 'none';
        if(hasVariant) document.getElementById('prop-variant').value = n.variant || 'primary';

        offcanvas.show();
    }

    function updateProp(key, val) {
        if(!selectedId) return;
        let n = find(selectedId);
        n[key] = val;
        if(key === 'colSize') document.getElementById('col-display').innerText = val;
        render();
    }

    function updateTableData(val) {
        if(!selectedId) return;
        let n = find(selectedId);
        n.tableData = val;
        // Intentamos renderizar. Si el JSON es malo, el render lo capturará en el try/catch
        render();
    }

    function del(id) {
        if(!confirm('¿Borrar?')) return;
        const remove = (list) => {
            let idx = list.findIndex(x => x.id === id);
            if(idx > -1) { list.splice(idx, 1); return true; }
            for(let x of list) if(x.children && remove(x.children)) return true;
        };
        remove(layout);
        if(selectedId === id) { selectedId = null; offcanvas.hide(); }
        render();
    }
    
    function deleteCurrent() { if(selectedId) del(selectedId); }

    function exportJSON() {
        document.getElementById('json-output').value = JSON.stringify(layout, null, 2);
        new bootstrap.Modal(document.getElementById('jsonModal')).show();
    }
    
    function resetWorkspace() {
        if(confirm('¿Reiniciar todo?')) { layout = []; selectedId = null; offcanvas.hide(); render(); }
    }
    
    function filterTools() {
        let term = document.getElementById('searchTool').value.toLowerCase();
        let btns = document.querySelectorAll('.tool-btn');
        btns.forEach(btn => {
            let txt = btn.textContent.toLowerCase();
            btn.parentElement.style.display = txt.includes(term) ? 'block' : 'none';
        });
    }
</script>

</body>
</html>