diff --git a/Dockerfile b/Dockerfile
index 379154a..92351e0 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,8 +2,8 @@ FROM --platform=$BUILDPLATFORM python:3.10-alpine AS builder
 
 WORKDIR /app
 
-# Install openssl
-RUN apk add --no-cache openssl
+# Install openssl and delv
+RUN apk add --no-cache openssl bind-tools
 
 COPY requirements.txt /app
 RUN --mount=type=cache,target=/root/.cache/pip \
diff --git a/hsd-ksk b/hsd-ksk
new file mode 100644
index 0000000..3de0c8f
--- /dev/null
+++ b/hsd-ksk
@@ -0,0 +1,3 @@
+trust-anchors {
+  . initial-key 257 3 13 "T9cURJ2M/Mz9q6UsZNY+Ospyvj+Uv+tgrrWkLtPQwgU/Xu5Yk0l02Sn5ua2xAQfEYIzRO6v5iA+BejMeEwNP4Q==";
+};
\ No newline at end of file
diff --git a/templates/assets/js/index.js b/templates/assets/js/index.js
index 6194bcb..8bb76ad 100644
--- a/templates/assets/js/index.js
+++ b/templates/assets/js/index.js
@@ -13,6 +13,20 @@ document.getElementById("domain").addEventListener("keyup", function (event) {
 function getSSL() {
     // Get the input value
     const domain = document.getElementById("domain").value;
+    // Set the domain parameter
+    const params = new URLSearchParams();
+    params.append("domain", domain);
+    // Add the parameters to the URL
+    const url = `/?${params.toString()}`;
+    // Push the URL to the history
+    history.pushState(null, null, url);
+
+    // Add a loading spinner
+    document.getElementById("results").innerHTML = `<div class="spinner-border text-primary" role="status">
+  <span class="visually-hidden">Loading...</span>
+</div>`;
+
+
     // Send a GET request to the API
     fetch(`/api/v1/ssl/${domain}`)
         .then(response => response.json())
@@ -20,30 +34,110 @@ function getSSL() {
             // Check if the request was successful
             if (data.success) {
                 // Display the results
-                // document.getElementById("results").innerHTML = `<h2>SSL Certificate Details</h2>
-                // <p>IP Address: ${data.ip}</p>
-                // <p>Webserver TLSA: <code>${data.tlsa.server}</code></p>
-                // <p>Nameserver TLSA: <code>${data.tlsa.nameserver}</code> ${data.tlsa.match ? "(Match)" : "(No Match)"}</p>
-                // <p>Certificate Names: ${data.cert.domains.join(", ")}</p>
-                // <p>Expiry Date: ${data.cert.expiry_date} UTC</p>
-                // <p>Valid: ${data.cert.valid ? "Yes" : "No"}</p>`;
                 document.getElementById("results").innerHTML = `
     <div class="card shadow-sm p-4" style="max-width: 950px;margin: auto;">
         <h2 class="mb-3">SSL Certificate Details</h2>
         <ul class="list-group">
             <li class="list-group-item"><strong>IP Address:</strong> ${data.ip}</li>
-            <li class="list-group-item"><strong>Webserver TLSA:</strong> <code>${data.tlsa.server}</code></li>
-            <li class="list-group-item"><strong>Nameserver TLSA:</strong> <code>${data.tlsa.nameserver}</code> 
-                ${data.tlsa.match ? '<span class="badge bg-success">Match</span>' : '<span class="badge bg-danger">No Match</span>'}
+            
+            <li class="list-group-item">
+                <div class="d-flex justify-content-between align-items-center">
+                    <div>
+                        <strong>TLSA Records:</strong> 
+                        ${data.tlsa.match ? '<span class="badge bg-success">Match</span>' : '<span class="badge bg-danger">No Match</span>'}
+                    </div>
+                    <button class="btn btn-sm btn-outline-secondary tlsa-toggle" type="button">
+                        Show Details
+                    </button>
+                </div>
+                <div class="tlsa-details mt-2" style="display:none;">
+                    <div class="card card-body bg-light">
+                        <div><strong>Webserver TLSA:</strong><br><code>${data.tlsa.server}</code></div>
+                        <div class="mt-2"><strong>Nameserver TLSA:</strong><br><code>${data.tlsa.nameserver}</code></div>
+                    </div>
+                </div>
             </li>
-            <li class="list-group-item"><strong>Certificate Names:</strong> ${data.cert.domains.join(", ")} ${data.cert.domain ? '<span class="badge bg-success">Match</span>' : '<span class="badge bg-danger">No Match</span>'}</li>
-            <li class="list-group-item"><strong>Expiry Date:</strong> ${data.cert.expiry_date} UTC ${data.cert.expired ? '<span class="badge bg-danger">Expired</span>' : '<span class="badge bg-success">Valid</span>'}</li>
-            <li class="list-group-item"><strong>Valid:</strong> 
-                ${data.valid ? '<span class="badge bg-success">Yes</span>' : '<span class="badge bg-danger">No</span>'}
+            
+            <li class="list-group-item">
+                <div class="d-flex justify-content-between align-items-center">
+                    <div>
+                        <strong>Certificate:</strong> 
+                        ${!data.cert.expired && data.cert.domain ? '<span class="badge bg-success">Valid</span>' : '<span class="badge bg-danger">Invalid</span>'}
+                    </div>
+                    <button class="btn btn-sm btn-outline-secondary cert-toggle" type="button">
+                        Show Details
+                    </button>
+                </div>
+                <div class="cert-details mt-2" style="display:none;">
+                    <div class="card card-body bg-light">
+                        <div><strong>Subject Names:</strong> ${data.cert.domains.join(", ")} 
+                            ${data.cert.domain ? '<span class="badge bg-success">Match</span>' : '<span class="badge bg-danger">No Match</span>'}
+                        </div>
+                        <div class="mt-2"><strong>Expiry Date:</strong> ${data.cert.expiry_date} UTC 
+                            ${data.cert.expired ? '<span class="badge bg-danger">Expired</span>' : '<span class="badge bg-success">Valid</span>'}
+                        </div>
+                        <div class="mt-2"><strong>Certificate Content:</strong></div>
+                        <pre class="mt-1 mb-0" style="white-space: pre-wrap; font-size: 0.8rem; max-height: 300px; overflow-y: auto;">${data.cert.cert}</pre>
+                    </div>
+                </div>
+            </li>
+            
+            <li class="list-group-item">
+                <div class="d-flex justify-content-between align-items-center">
+                    <div>
+                        <strong>DNSSEC Chain:</strong> 
+                        ${data.dnssec.valid ? '<span class="badge bg-success">Valid</span>' : '<span class="badge bg-danger">Invalid</span>'}
+                    </div>
+                    <button class="btn btn-sm btn-outline-secondary dnssec-toggle" type="button">
+                        Show Details
+                    </button>
+                </div>
+                <div class="dnssec-details mt-2" style="display:none;">
+                    <div class="card card-body bg-light"><pre class="mb-0" style="white-space: pre-wrap; text-align: left;">${data.dnssec.errors}${data.dnssec.output}</pre>
+                    </div>
+                </div>
+            </li>
+            
+            <li class="list-group-item"><strong>Overall Status:</strong> 
+                ${data.valid ? '<span class="badge bg-success">Valid</span>' : '<span class="badge bg-danger">Invalid</span>'}
             </li>
         </ul>
     </div>`;
 
+// Add event listeners for all toggle buttons
+document.querySelector('.tlsa-toggle').addEventListener('click', function() {
+    const detailsDiv = document.querySelector('.tlsa-details');
+    if (detailsDiv.style.display === 'none') {
+        detailsDiv.style.display = 'block';
+        this.textContent = 'Hide Details';
+    } else {
+        detailsDiv.style.display = 'none';
+        this.textContent = 'Show Details';
+    }
+});
+
+document.querySelector('.cert-toggle').addEventListener('click', function() {
+    const certDiv = document.querySelector('.cert-details');
+    if (certDiv.style.display === 'none') {
+        certDiv.style.display = 'block';
+        this.textContent = 'Hide Details';
+    } else {
+        certDiv.style.display = 'none';
+        this.textContent = 'Show Details';
+    }
+});
+
+document.querySelector('.dnssec-toggle').addEventListener('click', function() {
+    const dnssecDiv = document.querySelector('.dnssec-details');
+    if (dnssecDiv.style.display === 'none') {
+        dnssecDiv.style.display = 'block';
+        this.textContent = 'Hide Details';
+    } else {
+        dnssecDiv.style.display = 'none';
+        this.textContent = 'Show Details';
+    }
+});
+
             } else {
                 // Display an error message
                 document.getElementById("results").innerHTML = `<h2>Error</h2>
diff --git a/tools.py b/tools.py
index ad3e8be..2b0a857 100644
--- a/tools.py
+++ b/tools.py
@@ -1,3 +1,4 @@
+import random
 import dns.resolver
 import subprocess
 import tempfile
@@ -30,9 +31,7 @@ def check_ssl(domain: str):
         if len(records) > 1:
             returns["other_ips"] = records[1:]
 
-        result, details = validate_dnssec(domain, trace=True)
-        returns["dnssec"] = details
-        returns["dnssec"]["valid"] = result
+        returns["dnssec"] = validate_dnssec(domain)
 
 
         # Get the first A record        
@@ -146,7 +145,7 @@ def check_ssl(domain: str):
             return returns
 
         # Check if valid
-        if returns["cert"]["valid"] and returns["tlsa"]["match"]:
+        if returns["cert"]["valid"] and returns["tlsa"]["match"] and returns["dnssec"]["valid"]:
             returns["valid"] = True
         
         returns["success"] = True
@@ -158,254 +157,13 @@ def check_ssl(domain: str):
         return returns
     
 
-def validate_dnssec(domain, trace=False):
-    """
-    Validate DNSSEC for a given domain by following the chain of trust.
-    
-    Args:
-        domain (str): The domain to validate
-        trace (bool): Enable detailed tracing of validation steps
-    
-    Returns:
-        bool: True if DNSSEC validation succeeds, False otherwise
-        dict: Details about the validation process
-    """
-    
-    domain = dns.name.from_text(domain)
-    if not domain.is_absolute():
-        domain = domain.concatenate(dns.name.root)
-    
-    # Start with root servers
-    trusted_keys = get_root_trust_anchors()
-    
-    result = {
-        'domain': str(domain),
-        'validation_time': time.time(),
-        'validated': False,
-        'validation_chain': [],
-        'errors': []
-    }
-    
-    try:
-        # Walk the DNS hierarchy to validate the chain
-        current = dns.name.root
-        while current != domain and current.is_subdomain(domain):
-            # Determine the next label in the chain
-            next_part = domain.relativize(current).split()[0]
-            next_domain = dns.name.Name([next_part]) + current
-            
-            
-            # Get DNSKEY records for the current zone
-            dnskey_response = query_dns(current, dns.rdatatype.DNSKEY)
-            dnskey_rrset = extract_rrset_from_response(dnskey_response, current, dns.rdatatype.DNSKEY)
-            
-            if not dnskey_rrset:
-                error = f"No DNSKEY found for {current}"
-                result['errors'].append(error)
-                return False, result
-            
-            # Validate current zone's DNSKEY against trusted keys
-            if not validate_rrset(dnskey_rrset, trusted_keys):
-                error = f"Failed to validate DNSKEY for {current}"
-                result['errors'].append(error)
-                return False, result
-            
-            # Get DS records for the next domain
-            ds_response = query_dns(current, dns.rdatatype.DS, next_domain)
-            ds_rrset = extract_rrset_from_response(ds_response, next_domain, dns.rdatatype.DS)
-            
-            if not ds_rrset:
-                error = f"No DS records found for {next_domain}"
-                result['errors'].append(error)
-                return False, result
-            
-            # Validate DS records with the trusted keys from the parent zone
-            if not validate_rrset(ds_rrset, trusted_keys):
-                error = f"Failed to validate DS records for {next_domain}"
-                result['errors'].append(error)
-                return False, result
-            
-            # Now get DNSKEYs for the next domain level
-            next_dnskey_response = query_dns(next_domain, dns.rdatatype.DNSKEY)
-            next_dnskey_rrset = extract_rrset_from_response(next_dnskey_response, next_domain, dns.rdatatype.DNSKEY)
-            
-            if not next_dnskey_rrset:
-                error = f"No DNSKEY found for {next_domain}"
-                result['errors'].append(error)
-                return False, result
-            
-            # Verify the DNSKEY matches the DS record hash
-            if not match_ds_to_dnskey(ds_rrset, next_dnskey_rrset):
-                error = f"DS record does not match DNSKEY for {next_domain}"
-                result['errors'].append(error)
-                return False, result
-            
-            # The next domain's DNSKEYs become our trusted keys
-            trusted_keys = next_dnskey_rrset
-            current = next_domain
-            
-            result['validation_chain'].append({
-                'zone': str(current),
-                'validated': True,
-                'timestamp': time.time()
-            })
-        
-        # Finally, validate the actual records we're interested in (A, AAAA, etc)
-        for rdtype in [dns.rdatatype.A, dns.rdatatype.TLSA]:
-            if rdtype == dns.rdatatype.TLSA:
-                record_response = query_dns(f"_443._tcp.{domain}", rdtype)
-            else:
-                record_response = query_dns(domain, rdtype)
-            if record_response.answer:
-                record_rrset = extract_rrset_from_response(record_response, domain, rdtype)
-                if record_rrset and not validate_rrset(record_rrset, trusted_keys):
-                    error = f"Failed to validate {dns.rdatatype.to_text(rdtype)} records for {domain}"
-                    result['errors'].append(error)
-                    return False, result
-        
-        result['validated'] = True
-        return True, result
-    
-    except Exception as e:
-        error = f"Validation error: {str(e)}"
-        result['errors'].append(error)
-        return False, result
-
-
-def get_root_trust_anchors():
-    """
-    Get the root trust anchors (usually the root DNSKEY)
-    In practice, this would be configured or obtained from a trusted source.
-    """
-    try:
-        # For production use, you should use properly validated root anchors
-        # This is a simplified example
-        response = resolver.query('.', dns.rdatatype.DNSKEY)
-        return response.rrset
-    except Exception as e:
-        # Fallback to hardcoded root KSK if needed
-        # This should be updated when the root KSK changes
-        from dns.rdtypes.ANY.DNSKEY import DNSKEY
-        from dns.rdata import from_text
-        
-        # Root KSK-2017 (hardcoded as fallback only - you should obtain this securely)
-        root_ksk = ". IN DNSKEY 257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU="
-        
-        # Create a DNS rrset
-        dnskey_rdata = from_text(dns.rdataclass.IN, dns.rdatatype.DNSKEY, root_ksk)
-        rrset = dns.rrset.RRset(dns.name.root, dns.rdataclass.IN, dns.rdatatype.DNSKEY)
-        rrset.add(dnskey_rdata)
-        return rrset
-
-
-def query_dns(domain, rdtype, qname=None):
-    """
-    Query DNS for specific record types
-    
-    Args:
-        domain (dns.name.Name): Domain to query from (name server authority)
-        rdtype (int): DNS record type
-        qname (dns.name.Name, optional): Specific name to query. If None, uses domain
-    
-    Returns:
-        dns.message.Message: DNS response
-    """
-    if qname is None:
-        qname = domain
-        
-    try:
-        # For more control, you could use dns.query directly to a specific server
-        response = resolver.query(qname, rdtype, raise_on_no_answer=False)
-        return response.response
-    except dns.resolver.NXDOMAIN:
-        # Create an empty response with NXDOMAIN code
-        response = dns.message.make_response(dns.message.make_query(qname, rdtype))
-        response.set_rcode(dns.rcode.NXDOMAIN)
-        return response
-    except Exception as e:
-        # Return empty response
-        response = dns.message.make_response(dns.message.make_query(qname, rdtype))
-        response.set_rcode(dns.rcode.SERVFAIL)
-        return response
-
-
-def extract_rrset_from_response(response, name, rdtype):
-    """
-    Extract the RRset from a DNS response
-    
-    Args:
-        response (dns.message.Message): DNS response
-        name (dns.name.Name): Name of the RRset
-        rdtype (int): Record type
-    
-    Returns:
-        dns.rrset.RRset or None: The requested RRset or None if not found
-    """
-    if response.rcode() != dns.rcode.NOERROR:
-        return None
-        
-    for section in [response.answer, response.authority, response.additional]:
-        for rrset in section:
-            if rrset.name == name and rrset.rdtype == rdtype:
-                return rrset
-    
-    return None
-
-
-def validate_rrset(rrset, keys):
-    """
-    Validate a DNS RRset using DNSSEC
-    
-    Args:
-        rrset (dns.rrset.RRset): The RRset to validate
-        keys (dns.rrset.RRset): The DNSKEY rrset to validate against
-    
-    Returns:
-        bool: True if the RRset validates, False otherwise
-    """
-    try:
-        # Get the RRSIG for this RRset
-        for rrsig in [r for r in rrset.rrsigs]:
-            # Find the corresponding key
-            key = None
-            for dnskey in keys:
-                if dnskey.key_tag() == rrsig.key_tag:
-                    key = dnskey
-                    break
-            
-            if key:
-                # Perform the validation
-                dns.dnssec.validate_rrsig(rrset, rrsig, {(keys.name, keys.rdtype): keys})
-                return True
-        return False
-    except dns.dnssec.ValidationFailure as e:
-        return False
-    except Exception as e:
-        return False
-
-
-def match_ds_to_dnskey(ds_rrset, dnskey_rrset):
-    """
-    Verify that a DS record matches a DNSKEY
-    
-    Args:
-        ds_rrset (dns.rrset.RRset): DS record set
-        dnskey_rrset (dns.rrset.RRset): DNSKEY record set
-    
-    Returns:
-        bool: True if any DS matches any DNSKEY, False otherwise
-    """
-    for ds in ds_rrset:
-        for dnskey in dnskey_rrset:
-            # Calculate the DS from the DNSKEY
-            calculated_ds = dns.dnssec.make_ds(dnskey_rrset.name, dnskey, ds.digest_type)
-            
-            # Compare the calculated DS to the actual DS
-            if (ds.key_tag == calculated_ds.key_tag and
-                ds.algorithm == calculated_ds.algorithm and
-                ds.digest_type == calculated_ds.digest_type and
-                ds.digest == calculated_ds.digest):
-                return True
-    
-    return False
-
+def validate_dnssec(domain):
+    # Pick a random resolver
+    resolverIP = random.choice(resolver.nameservers)
+    # delv @194.50.5.28 -a hsd-ksk nathan.woodburn A +rtrace +vtrace
+    command = f"delv @{resolverIP} -a hsd-ksk {domain} A +rtrace +vtrace"
+    result = subprocess.run(command, shell=True, capture_output=True, text=True)
+    if "; fully validated" in result.stdout:
+        return {"valid": True, "message": "DNSSEC is valid", "output": result.stdout, "errors": result.stderr}
+    else:
+        return {"valid": False, "message": "DNSSEC is not valid", "output": result.stdout, "errors": result.stderr}
\ No newline at end of file