Author: Will Tygart

  • Commercial Compliance as a Loss Leader: How Restoration Contractors Own the Relationship

    Commercial Compliance as a Loss Leader: How Restoration Contractors Own the Relationship

    The Machine Room · Under the Hood

    There’s a property manager sitting in a strip mall office right now, managing twelve tenants, a leaky roof drain, and a fire marshal inspection that’s six months overdue. She’s not looking for a restoration company. She won’t think about a restoration company until something goes very wrong.

    That’s the problem — and the opportunity.

    The restoration industry runs almost entirely on reactive marketing. Someone floods, someone calls. Someone burns, someone calls. You’re competing for the call after the loss, against every other company who’s also competing for the call after the loss, on Google, on insurance panels, on word of mouth.

    But the property manager who authorizes a $50,000 emergency restoration job is the same person who buys fire extinguisher inspections, carpet cleaning, and exit light testing. She buys these things regularly, on a schedule, for cash — no insurance middleman, no adjuster, no TPA approval process.

    Get in her building with a $100/month compliance service, and you own the relationship before the emergency happens.

    The Compliance Walk

    Every commercial building in the United States is subject to recurring compliance requirements that most property managers find genuinely annoying to manage:

    • Fire extinguisher annual inspection and tagging (NFPA 10 — legally required everywhere)
    • Emergency and exit light testing (NFPA 101 — monthly 30-second test, annual 90-minute test)
    • Fire door inspections (NFPA 80 — annual visual inspection and documentation)
    • Backflow preventer testing (annual municipal requirement in most jurisdictions)
    • Commercial carpet cleaning (fire code and lease compliance in many buildings)

    These aren’t optional. They’re not upsells. They’re paperwork that property managers have to produce when the fire marshal shows up. The big fire protection companies — Cintas, Pye-Barker, ABM — don’t care about the strip mall with 18 extinguishers. Their route economics don’t work below a certain account size.

    That’s the gap. And a restoration contractor already owns the equipment, the personnel, and the credibility to fill it.

    What the Quarterly Visit Actually Buys You

    Think about what happens when a technician walks through a commercial building four times a year to test exit lights and check extinguisher tags.

    They see the water stain on the ceiling tile in unit 7. They notice the musty smell in the stairwell that’s been there since last fall. They observe that the roof drain on the north side is partially blocked. They document all of it — in a compliance report that goes to the property manager, with your company’s name on it.

    The property manager now has documented evidence of deferred maintenance and potential liability. You found it. You’re the expert she trusts. When something actually happens, you’re not a name she found on Google at 2am — you’re the company that’s been maintaining her building, that she already has a contract with, that already has access.

    This is not a marketing strategy. This is a relationship architecture.

    The Numbers That Make It Real

    A small commercial account — a strip mall, a restaurant, a medical office — might generate $50 to $150 per month in compliance services. That’s not the revenue story.

    The average water damage restoration job in commercial property runs $3,836 at the low end. Significant losses start at $15,000. Whole-building events — the ones that happen when a pipe bursts on the third floor and runs for six hours — run $50,000 and up.

    One emergency response job from a compliance relationship you’ve spent six months building pays for the entire program many times over. And that’s before the rebuild scope, the contents, the dehumidification equipment rental, and the project management fees that follow a major loss.

    The compliance service isn’t the product. It’s the acquisition cost.

    How to Structure the Offer

    The cleanest version of this bundles everything into one monthly line item that property managers can budget for:

    • Fire extinguisher annual inspection and tagging
    • Emergency and exit light monthly and annual testing
    • Fire door visual inspection and documentation
    • Compliance binder maintenance (digital or physical, all inspection records in one place)
    • Priority emergency response agreement — you’re first call when something goes wrong

    One vendor. One monthly fee. One quarterly visit. Everything documented, everything current, fire marshal ready.

    For a small commercial tenant — under 50 extinguishers, which is most of the small commercial market the big vendors ignore — that package prices at $50 to $150 per month depending on building size and complexity. Quarterly visits, annual documentation package, priority response clause in the contract.

    The priority response clause is the most important line in the agreement. It’s not legally binding in any complex sense — it simply establishes that when something happens, you call us first. You’ve already signed the paperwork. We’re already in your system. No one has to go find a contractor at 2am.

    The Certification Question

    Fire extinguisher inspection requires certification. The national path runs through the ICC/NAFED Certified Portable Fire Extinguisher Technician exam, which is based on NFPA 10 and completable in one to three days of self-paced study. Total startup cost — materials, exam, state registration, initial tools and tags — runs under $1,000.

    Some states require a licensed fire protection company for annual inspections. Washington, for example, requires both state and local licensing. Texas requirements vary by jurisdiction. The certification question is worth solving once, correctly, before the first sale — not as a reason to delay getting started.

    The alternative for contractors who don’t want to own the compliance scope themselves: partner with a regional fire protection company to run the compliance work, keep the PM relationship, and be named in the contract as the emergency response vendor. The fire protection company gets route density they want. You get the access and the relationship.

    Starting Without the Certification

    You don’t need certification to start. You need content and a phone call.

    Write about commercial fire code compliance for property managers. Write about what NFPA 10 actually requires and why small commercial buildings keep getting cited. Write about what a compliance binder should contain and how many property managers don’t have one. Rank for the keywords commercial property managers search when they’re trying to solve this problem.

    Leads come in. You call them. You ask them what their current compliance situation looks like. You position yourself as someone who understands the problem — and then either you’ve gotten certified by then, or you have a fire protection partner to introduce.

    The digital presence creates the warm lead. The relationship closes the deal. The quarterly visit owns the building.

    The Larger Play

    This isn’t just a retention strategy for one contractor. It’s the skeleton of a commercial PM ecosystem.

    A drone company handles exterior envelope inspections and thermal imaging — capabilities no fire protection company or restoration contractor currently offers. A fire protection company handles the interior compliance walk. The restoration contractor holds the PM relationship and the emergency response position. A content and SEO layer drives commercial PM leads to the entire network.

    The property manager sees one vendor, one monthly fee, one comprehensive building health report — roof-to-extinguisher, quarterly. Everyone else sees route density, referral flow, and the clients no one else was serving.

    The big vendors ignored the small commercial market because their economics didn’t work. That’s not a problem. That’s an opening.


    Tygart Media builds digital infrastructure for restoration contractors, commercial service companies, and the vendors who work alongside them. If you’re thinking through a commercial PM strategy and want to talk about what the content and SEO layer looks like, reach out.

    {
    “@context”: “https://schema.org”,
    “@type”: “Article”,
    “headline”: “Commercial Compliance as a Loss Leader: How Restoration Contractors Own the Relationship”,
    “description”: “The property manager who buys fire extinguisher inspections is the same person who authorizes $50K+ emergency restoration work. Here is how to get in the buildi”,
    “datePublished”: “2026-04-02”,
    “dateModified”: “2026-04-03”,
    “author”: {
    “@type”: “Person”,
    “name”: “Will Tygart”,
    “url”: “https://tygartmedia.com/about”
    },
    “publisher”: {
    “@type”: “Organization”,
    “name”: “Tygart Media”,
    “url”: “https://tygartmedia.com”,
    “logo”: {
    “@type”: “ImageObject”,
    “url”: “https://tygartmedia.com/wp-content/uploads/tygart-media-logo.png”
    }
    },
    “mainEntityOfPage”: {
    “@type”: “WebPage”,
    “@id”: “https://tygartmedia.com/commercial-compliance-loss-leader-restoration/”
    }
    }

  • The Unsnippetable Strategy: How We Beat Zero-Click Search by Building Things Google Can’t Summarize

    The Unsnippetable Strategy: How We Beat Zero-Click Search by Building Things Google Can’t Summarize

    The Lab · Tygart Media
    Experiment Nº 650 · Methodology Notes
    METHODS · OBSERVATIONS · RESULTS

    We just deployed 16 interactive tools and 3 bottom-of-funnel articles across 7 websites in a single session. Here’s why, and how you can do the same thing.

    The Problem: 4,000 Impressions, Zero Clicks

    We pulled the Google Search Console data for theuniversalcommerceprotocol.com — a site covering agentic commerce and AI-powered checkout infrastructure. The numbers told a brutal story: over 200 unique queries generating 4,000+ monthly impressions with an effective CTR of 0%. Not low. Zero.

    The highest-impression queries were all definitional: “what is agentic commerce” (409 impressions, 0 clicks), “agentic commerce definition” (178 impressions, 0 clicks), “ai commerce compliance mastercard” (61 impressions at position 1.25, 0 clicks). Google was serving our content directly in AI Overviews and featured snippets. Users got what they needed without ever visiting the site.

    This isn’t unique to UCP. It’s the new reality. 58.5% of US Google searches now end without a click. For AI Mode searches, it’s 93%. If your content strategy is built on informational queries, you’re building on a foundation that’s actively collapsing.

    The conventional wisdom is to “optimize for AI Overviews” and “win the featured snippet.” But that’s backwards. If you win the featured snippet for “what is agentic commerce,” Google serves your content without anyone visiting your site. You’ve won the battle and lost the war.

    The Insight: Two-Layer Content Architecture

    The solution isn’t to fight zero-click search. It’s to use it. We call it two-layer content architecture, and it changes how you think about content strategy entirely.

    Layer 1: SERP Bait. This is your definitional, informational content — “what is X,” “X vs Y,” “how does X work.” This content is designed to be consumed on the SERP without a click. Its job isn’t traffic. Its job is brand impressions at massive scale. Every time Google cites you in an AI Overview, thousands of people see your brand positioned as the authority. That’s not a failure. That’s a free brand campaign.

    Layer 2: Click Magnets. This is content Google literally cannot summarize in a snippet — interactive tools, calculators, assessments, scorecards, decision frameworks. The SERP can tease them (“Calculate your agentic commerce ROI…”) but the user HAS to click through to get the value. The tool requires input. The output is personalized. There’s nothing for Google to extract.

    The connection between the layers is where the magic happens. The person who sees your brand cited in an AI Overview for “what is agentic commerce” now recognizes you. When they later search “agentic commerce ROI” or “how to implement agentic commerce” — and your calculator or playbook appears — they click because they already trust you from Layer 1. Research backs this up: brands cited in AI Overviews see 35% higher CTR on their other organic listings.

    You’re not fighting the zero-click reality. You’re using it as a free awareness channel that feeds the bottom of your funnel.

    What We Built: 16 Tools Across 7 Sites

    We didn’t just theorize about this. We built and deployed the entire system in a single session across 7 domains.

    UCP (theuniversalcommerceprotocol.com) — 6 pieces

    Three interactive tools targeting the exact queries generating zero-click impressions: an Agentic Commerce Readiness Assessment (32-question diagnostic across 8 dimensions), an ROI Calculator (projects revenue impact using Morgan Stanley, Gartner, and McKinsey 2026 data), and a Visa vs Mastercard Agentic Commerce Scorecard (interactive comparison across 7 compliance dimensions — this one directly targets the “ai commerce compliance mastercard/visa” queries that were getting 90 impressions at position 1 with zero clicks).

    Plus three bottom-of-funnel articles that can’t be answered in a snippet: a 90-Day Implementation Playbook (week-by-week), a narrative piece about what breaks when an AI agent hits an unprepared store, and a Build/Buy/Wait decision framework with cost analysis.

    Tygart Media (tygartmedia.com) — 5 tools

    Five tools that package our existing expertise into interactive formats: an AEO Citation Likelihood Analyzer (scores content across 8 dimensions AI systems evaluate), an Information Density Analyzer (paste your text, get real-time density metrics and a paragraph-by-paragraph heatmap), a Restoration SEO Competitive Tower (benchmark against competitors across 8 SEO dimensions), an AI Infrastructure ROI Simulator (Build vs Buy vs API with 3-year TCO), and a Schema Markup Adequacy Scorer (is your structured data AI-ready?).

    Knowledge Cluster (5 sites) — 5 industry-specific tools

    One high-priority tool per site, each targeting the most-searched zero-click queries in their industry: a Water Damage Cost Estimator for restorationintel.com (calculates by IICRC class, water category, materials, and region), a Property Risk Assessment Engine for riskcoveragehub.com (scores across 5 risk dimensions with coverage recommendations), a Business Impact Analysis Generator for continuityhub.org (ISO 22301-aligned BIA with exportable summary), a Healthcare Compliance Audit Tool for healthcarefacilityhub.org (18-question audit mapped to CMS CoP and TJC standards), and a Carbon Footprint Calculator for bcesg.org (Scope 1/2/3 with EPA emission factors and reduction scenarios).

    Why Interactive Tools Beat Articles in Zero-Click

    There are five technical reasons interactive tools are the correct response to zero-click search, and they compound.

    They’re non-serializable. A calculator’s output depends on user input. Google can’t pre-compute every possible result for a water damage cost estimator across every combination of square footage, damage class, water category, materials, and region. The AI Overview can say “use this calculator” but it can’t BE the calculator. The citation becomes a call to action.

    They generate engagement signals at scale. Interactive tools produce time-on-page, scroll depth, and interaction events that traditional articles can’t match. A user spending 4 minutes inputting data and exploring results sends stronger quality signals than a user who reads a paragraph and bounces.

    They’re bookmarkable. A restoration company owner who uses the cost estimator once will bookmark it and return. Insurance adjusters will save the risk assessment tool. This creates direct traffic over time — the kind Google can’t intercept with zero-click.

    They’re natural link magnets. Industry publications, Reddit threads, and professional communities link to useful tools far more readily than articles. A “Healthcare Compliance Audit Tool” gets shared in facility manager Slack channels. A “What Is Healthcare Compliance” article doesn’t.

    They’re AI Overview proof. Even when Google cites the page in an AI Overview, users still need to visit to use the tool. The AI Overview effectively becomes free advertising: “Use this calculator at [your site] to estimate your costs.” Every zero-click impression becomes a branded CTA.

    The Methodology: Replicable for Any Site

    You can run this exact playbook on any site in about 4 hours. Here’s the step-by-step:

    Step 1: Pull your GSC data. Export the Queries and Pages reports. Sort by impressions descending. Identify every query with significant impressions and near-zero CTR. These are your zero-click queries — the ones Google is answering without sending you traffic.

    Step 2: Categorize the queries. Split them into two buckets. Definitional queries (“what is X,” “X definition,” “X vs Y”) are Layer 1 — leave them alone, they’re generating brand impressions. Action-intent queries (“X cost estimate,” “X compliance checklist,” “how to implement X”) are Layer 2 opportunities.

    Step 3: For each Layer 2 opportunity, ask one question. “What would someone who already knows the answer still need to click for?” The answer is usually a tool, calculator, assessment, or framework that requires their specific input to produce useful output.

    Step 4: Build the tool. Single-file HTML with inline CSS/JS. No external dependencies. Dark theme, mobile responsive, professional design. The tool should take 2-5 minutes to complete and produce a result worth sharing or saving. Include a “copy results” or “download report” function.

    Step 5: Embed in WordPress. Write a 2-3 paragraph intro explaining why the tool matters (this is what Google will see and potentially cite). Then embed the full HTML. The intro becomes your Layer 1 snippet bait, and the tool becomes your Layer 2 click magnet — on the same page.

    Step 6: Cross-link. Add CTAs from your existing Layer 1 content to the new tools. If you have an article ranking for “what is agentic commerce” that’s getting zero clicks, add a CTA in that article: “Take the Readiness Assessment to see if your business is prepared.” You’re converting brand impressions into tool engagement.

    Step 7: Monitor. Track CTR changes over 30/60/90 days. Track direct traffic increases (brand searches driven by AI Overview citations). Track tool engagement: completion rates, time on page. Track backlink acquisition from industry sites linking to your tools.

    What We’re Measuring

    This isn’t a “publish and pray” strategy. We’re tracking specific metrics across all 7 sites to validate or invalidate the approach within 90 days.

    First, CTR change on previously zero-click queries. If the Visa vs Mastercard Scorecard starts pulling even 2-3% CTR on queries that were at 0%, that’s a meaningful signal. Second, direct traffic increases — are more people searching for our brand names directly after seeing us cited in AI Overviews? Third, tool engagement metrics: how many people complete the assessments, what’s the average time on page, how many copy their results? Fourth, organic backlinks — do industry sites start linking to our tools? Fifth, whether the tools themselves rank for their own queries, creating an entirely new traffic channel.

    The Bigger Picture

    The era of “write an article, rank, get traffic” is over for informational queries. Google’s AI Overviews and featured snippets have made it so that the better your content is at answering a question, the less likely anyone is to visit your site. That’s a structural inversion of the old SEO model, and no amount of keyword optimization will fix it.

    But the era of “build something useful, earn trust, capture intent” is just beginning. Tools, calculators, assessments, and interactive experiences represent a category of content that AI cannot fully consume on behalf of the user. They require participation. They produce personalized output. They create the kind of engagement that turns a search impression into a relationship.

    We deployed 16 of these tools across 7 sites today. In 90 days, we’ll know exactly how much zero-click traffic they converted. But based on the early research — 35% higher CTR for AI-cited brands, 42.9% CTR for featured snippet content that teases without fully answering — the bet is that unsnippetable content is the highest-leverage move in SEO right now.

    The tools are already live. The impressions are already flowing. Now we find out if the clicks follow.

    {
    “@context”: “https://schema.org”,
    “@type”: “Article”,
    “headline”: “The Unsnippetable Strategy: How We Beat Zero-Click Search by Building Things Google Cant Summarize”,
    “description”: “We deployed 16 interactive tools across 7 websites to convert zero-click search impressions into actual traffic. Here’s the two-layer content architecture”,
    “datePublished”: “2026-04-01”,
    “dateModified”: “2026-04-03”,
    “author”: {
    “@type”: “Person”,
    “name”: “Will Tygart”,
    “url”: “https://tygartmedia.com/about”
    },
    “publisher”: {
    “@type”: “Organization”,
    “name”: “Tygart Media”,
    “url”: “https://tygartmedia.com”,
    “logo”: {
    “@type”: “ImageObject”,
    “url”: “https://tygartmedia.com/wp-content/uploads/tygart-media-logo.png”
    }
    },
    “mainEntityOfPage”: {
    “@type”: “WebPage”,
    “@id”: “https://tygartmedia.com/unsnippetable-strategy-beat-zero-click-search/”
    }
    }

  • Schema Markup Adequacy Scorer: Is Your Structured Data AI-Ready?

    Schema Markup Adequacy Scorer: Is Your Structured Data AI-Ready?

    Tygart Media / The Signal
    Broadcast Live
    Filed by Will Tygart
    Tacoma, WA
    Industry Bulletin

    Standard schema markup is a business card. AI systems need a full dossier. Most sites implement the bare minimum Schema.org markup and wonder why AI ignores them.

    This scorer evaluates your structured data across 6 dimensions — from basic coverage and property depth to AI-specific signals and inter-entity relationships. Each dimension is scored with specific recommendations and code snippet examples for improvement.

    Take the assessment below to find out if your schema markup is a business card or a dossier.






    Schema Markup Adequacy Scorer: Is Your Structured Data AI-Ready?


    Schema Markup Adequacy Scorer

    Is Your Structured Data AI-Ready?

    Your Progress

    0/24




















    0
    Schema Adequacy Score

    Category Breakdown

    Recommended Improvements

    Read AgentConcentrate: Why Standard Schema Is a Business Card →

    Powered by Tygart Media | tygartmedia.com



  • AI Infrastructure ROI Simulator: Build vs Buy vs API

    AI Infrastructure ROI Simulator: Build vs Buy vs API

    The Machine Room · Under the Hood

    The biggest question in AI infrastructure right now isn’t what to build — it’s whether to build at all. We run our entire operation on a single GCP instance with MCP servers and custom pipelines at near-zero marginal cost. But that approach isn’t right for everyone.

    This simulator models three scenarios — 100% SaaS/API, Hybrid with MCP servers, and Full Build — and calculates monthly costs, 3-year total cost of ownership, and break-even timelines based on your actual numbers.

    Input your current marketing spend, team size, and content volume to see which infrastructure approach delivers the best ROI for your situation.

    AI Infrastructure ROI Simulator: Build vs Buy vs API

    * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    }

    body {
    font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, Roboto, ‘Helvetica Neue’, Arial, sans-serif;
    background: linear-gradient(135deg, #0f172a 0%, #1a2551 100%);
    color: #e5e7eb;
    min-height: 100vh;
    padding: 20px;
    }

    .container {
    max-width: 1300px;
    margin: 0 auto;
    }

    header {
    text-align: center;
    margin-bottom: 40px;
    animation: slideDown 0.6s ease-out;
    }

    h1 {
    font-size: 2.5rem;
    background: linear-gradient(135deg, #3b82f6, #10b981);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    margin-bottom: 10px;
    font-weight: 700;
    }

    .subtitle {
    font-size: 1.1rem;
    color: #9ca3af;
    }

    .input-section {
    background: rgba(15, 23, 42, 0.8);
    border: 1px solid rgba(59, 130, 246, 0.2);
    border-radius: 12px;
    padding: 40px;
    margin-bottom: 30px;
    backdrop-filter: blur(10px);
    animation: fadeIn 0.8s ease-out;
    }

    .form-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 20px;
    margin-bottom: 25px;
    }

    .form-group {
    display: flex;
    flex-direction: column;
    }

    label {
    margin-bottom: 8px;
    font-weight: 600;
    color: #e5e7eb;
    font-size: 0.95rem;
    }

    input[type=”number”],
    input[type=”range”] {
    padding: 12px;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(59, 130, 246, 0.2);
    border-radius: 8px;
    color: #e5e7eb;
    font-family: inherit;
    font-size: 0.95rem;
    transition: all 0.3s ease;
    }

    input[type=”number”]:focus,
    input[type=”range”]:focus {
    outline: none;
    border-color: rgba(59, 130, 246, 0.5);
    background: rgba(59, 130, 246, 0.05);
    }

    .slider-group {
    display: flex;
    gap: 10px;
    align-items: center;
    }

    .slider-group input[type=”range”] {
    flex: 1;
    }

    .slider-value {
    background: rgba(59, 130, 246, 0.2);
    padding: 8px 12px;
    border-radius: 6px;
    min-width: 80px;
    text-align: right;
    color: #3b82f6;
    font-weight: 600;
    }

    .button-group {
    display: flex;
    gap: 15px;
    margin-top: 30px;
    flex-wrap: wrap;
    }

    button {
    padding: 12px 30px;
    border: none;
    border-radius: 8px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
    font-size: 1rem;
    }

    .btn-primary {
    background: linear-gradient(135deg, #3b82f6, #2563eb);
    color: white;
    flex: 1;
    min-width: 200px;
    }

    .btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 20px rgba(59, 130, 246, 0.3);
    }

    .results-section {
    display: none;
    animation: fadeIn 0.8s ease-out;
    }

    .results-section.visible {
    display: block;
    }

    .content-section {
    background: rgba(15, 23, 42, 0.8);
    border: 1px solid rgba(59, 130, 246, 0.2);
    border-radius: 12px;
    padding: 40px;
    margin-bottom: 30px;
    backdrop-filter: blur(10px);
    }

    .scenario-comparison {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 25px;
    margin-bottom: 40px;
    }

    .scenario-card {
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.1), rgba(16, 185, 129, 0.05));
    border: 1px solid rgba(59, 130, 246, 0.2);
    border-radius: 12px;
    padding: 25px;
    position: relative;
    overflow: hidden;
    }

    .scenario-card::before {
    content: ”;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: linear-gradient(90deg, #3b82f6, #10b981);
    }

    .scenario-title {
    font-size: 1.2rem;
    font-weight: 700;
    margin-bottom: 20px;
    color: #e5e7eb;
    }

    .cost-line {
    display: flex;
    justify-content: space-between;
    padding: 12px 0;
    border-bottom: 1px solid rgba(59, 130, 246, 0.1);
    font-size: 0.95rem;
    }

    .cost-line:last-child {
    border-bottom: none;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid rgba(59, 130, 246, 0.2);
    font-weight: 600;
    }

    .cost-label {
    color: #d1d5db;
    }

    .cost-value {
    color: #3b82f6;
    font-weight: 600;
    }

    .monthly-cost {
    color: #9ca3af;
    font-size: 0.85rem;
    }

    .annual-cost {
    background: rgba(59, 130, 246, 0.1);
    padding: 15px;
    border-radius: 8px;
    margin-top: 20px;
    text-align: center;
    }

    .annual-number {
    font-size: 1.8rem;
    font-weight: 700;
    background: linear-gradient(135deg, #3b82f6, #10b981);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    }

    .timeline {
    margin: 40px 0;
    position: relative;
    }

    .timeline-title {
    font-size: 1.2rem;
    font-weight: 600;
    margin-bottom: 30px;
    color: #e5e7eb;
    }

    .timeline-line {
    position: relative;
    height: 4px;
    background: linear-gradient(90deg, rgba(59, 130, 246, 0.2), rgba(16, 185, 129, 0.2));
    border-radius: 2px;
    margin-bottom: 40px;
    }

    .timeline-marker {
    position: absolute;
    top: -8px;
    width: 20px;
    height: 20px;
    background: #3b82f6;
    border: 3px solid #0f172a;
    border-radius: 50%;
    }

    .timeline-marker.reached {
    background: #10b981;
    }

    .timeline-labels {
    display: flex;
    justify-content: space-between;
    padding: 0 10px;
    }

    .timeline-label {
    text-align: center;
    font-size: 0.85rem;
    color: #9ca3af;
    }

    .breakeven-box {
    background: rgba(16, 185, 129, 0.1);
    border: 1px solid rgba(16, 185, 129, 0.3);
    border-radius: 8px;
    padding: 20px;
    margin: 30px 0;
    text-align: center;
    }

    .breakeven-box h3 {
    color: #10b981;
    margin-bottom: 10px;
    }

    .breakeven-time {
    font-size: 1.5rem;
    font-weight: 700;
    color: #e5e7eb;
    }

    .three-year-comparison {
    margin: 40px 0;
    }

    .three-year-title {
    font-size: 1.2rem;
    font-weight: 600;
    margin-bottom: 20px;
    color: #e5e7eb;
    }

    .comparison-bars {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 20px;
    }

    .bar-group {
    background: rgba(255, 255, 255, 0.02);
    border: 1px solid rgba(59, 130, 246, 0.2);
    border-radius: 8px;
    padding: 15px;
    }

    .bar-label {
    font-size: 0.9rem;
    color: #9ca3af;
    margin-bottom: 10px;
    font-weight: 600;
    }

    .bar {
    background: rgba(255, 255, 255, 0.05);
    height: 200px;
    border-radius: 6px;
    overflow: hidden;
    position: relative;
    }

    .bar-fill {
    background: linear-gradient(180deg, #3b82f6, #2563eb);
    border-radius: 6px;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    color: white;
    font-weight: 700;
    font-size: 0.85rem;
    padding-bottom: 8px;
    transition: all 0.6s ease-out;
    }

    .hidden-costs {
    background: rgba(239, 68, 68, 0.05);
    border: 1px solid rgba(239, 68, 68, 0.2);
    border-radius: 8px;
    padding: 20px;
    margin: 30px 0;
    }

    .hidden-costs h3 {
    color: #fca5a5;
    margin-bottom: 15px;
    }

    .cost-item {
    background: rgba(255, 255, 255, 0.02);
    padding: 12px 15px;
    margin-bottom: 10px;
    border-radius: 6px;
    border-left: 3px solid #f87171;
    color: #d1d5db;
    font-size: 0.95rem;
    line-height: 1.5;
    }

    .recommendation {
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.1), rgba(16, 185, 129, 0.05));
    border: 1px solid rgba(59, 130, 246, 0.3);
    border-radius: 8px;
    padding: 25px;
    margin: 30px 0;
    }

    .recommendation h3 {
    color: #3b82f6;
    margin-bottom: 15px;
    font-size: 1.1rem;
    }

    .recommendation p {
    color: #d1d5db;
    line-height: 1.6;
    margin-bottom: 10px;
    }

    .cta-link {
    display: inline-block;
    color: #3b82f6;
    text-decoration: none;
    font-weight: 600;
    margin-top: 20px;
    padding: 10px 0;
    border-bottom: 2px solid rgba(59, 130, 246, 0.3);
    transition: all 0.3s ease;
    }

    .cta-link:hover {
    border-bottom-color: #3b82f6;
    padding-right: 5px;
    }

    footer {
    text-align: center;
    padding: 30px;
    color: #6b7280;
    font-size: 0.85rem;
    margin-top: 50px;
    }

    @keyframes slideDown {
    from {
    opacity: 0;
    transform: translateY(-20px);
    }
    to {
    opacity: 1;
    transform: translateY(0);
    }
    }

    @keyframes fadeIn {
    from {
    opacity: 0;
    }
    to {
    opacity: 1;
    }
    }

    @media (max-width: 768px) {
    h1 {
    font-size: 1.8rem;
    }

    .input-section,
    .content-section {
    padding: 25px;
    }

    .form-row {
    grid-template-columns: 1fr;
    }

    .scenario-comparison {
    grid-template-columns: 1fr;
    }
    }

    AI Infrastructure ROI Simulator

    Build vs Buy vs API: What’s Right for Your Team?

    3 people

    None
    Part-time (10-20 hrs/week)
    Full-time (40 hrs/week)
    Team (multiple full-time)

    Your ROI Comparison

    3-Year Total Cost of Ownership

    Break-Even Timeline

    When Full Build investment is recovered through API cost savings

    Now
    Month 18
    36 months

    Hidden Costs to Consider

    Vendor Lock-in: SaaS/API providers can increase pricing or shut down services. Full Build gives you control.
    Scaling Limitations: API rate limits and costs scale directly with volume. Full Build scales incrementally.
    Maintenance Burden: Full Build requires ongoing updates, security patches, and infrastructure management.
    Knowledge Silos: Custom systems create dependency on specific developers. SaaS is more portable.
    Integration Costs: All scenarios require integration time. Full Build often requires more custom work.

    Read how we built the $0 Marketing Stack →

    Powered by Tygart Media | tygartmedia.com

    document.getElementById(‘teamSize’).addEventListener(‘input’, function() {
    document.getElementById(‘teamSizeValue’).textContent = this.value;
    });

    document.getElementById(‘roiForm’).addEventListener(‘submit’, function(e) {
    e.preventDefault();

    const budget = parseFloat(document.getElementById(‘budget’).value);
    const teamSize = parseInt(document.getElementById(‘teamSize’).value);
    const contentVolume = parseInt(document.getElementById(‘contentVolume’).value);
    const toolsCost = parseFloat(document.getElementById(‘toolsCost’).value);
    const devCapacity = document.getElementById(‘devCapacity’).value;

    const scenarios = calculateScenarios(budget, teamSize, contentVolume, toolsCost, devCapacity);
    displayResults(scenarios);
    });

    function calculateScenarios(budget, teamSize, contentVolume, toolsCost, devCapacity) {
    // Cost per article via API
    const costPerArticle = 0.05 * contentVolume; // rough estimate

    // 100% SaaS/API
    const saasMonthly = toolsCost + (costPerArticle * 12 / 12) + (budget * 0.05); // 5% cloud
    const saasAnnual = saasMonthly * 12;
    const saas3Year = saasAnnual * 3;

    // Hybrid
    const setupHybrid = 10000; // one-time
    const cloudHybrid = 75; // monthly
    const apiCostHybrid = costPerArticle * 12 * 0.5 / 12; // 50% reduction
    const devTimeHybrid = 15 * 150; // 15 hrs/mo at $150/hr
    const hybridMonthly = (setupHybrid / 36) + cloudHybrid + apiCostHybrid + devTimeHybrid + toolsCost;
    const hybridAnnual = hybridMonthly * 12;
    const hybrid3Year = hybridMonthly * 36;

    // Full Build
    const setupFull = 30000; // one-time
    const cloudFull = 250; // monthly
    const apiFull = costPerArticle * 12 * 0.2 / 12; // 80% reduction
    const devTimeFull = 30 * 150; // 30 hrs/mo at $150/hr
    const fullMonthly = (setupFull / 36) + cloudFull + apiFull + devTimeFull + toolsCost;
    const fullAnnual = fullMonthly * 12;
    const full3Year = fullMonthly * 36;

    // Break-even
    let breakEvenMonth = 0;
    for (let month = 1; month <= 36; month++) {
    const saasTotal = saasMonthly * month;
    const fullTotal = fullMonthly * month;
    if (fullTotal < saasTotal) {
    breakEvenMonth = month;
    break;
    }
    }
    if (breakEvenMonth === 0) breakEvenMonth = 36;

    return {
    saas: { monthly: saasMonthly, annual: saasAnnual, threeYear: saas3Year, setup: 0 },
    hybrid: { monthly: hybridMonthly, annual: hybridAnnual, threeYear: hybrid3Year, setup: setupHybrid },
    full: { monthly: fullMonthly, annual: fullAnnual, threeYear: full3Year, setup: setupFull },
    breakEvenMonth: breakEvenMonth,
    devCapacity: devCapacity
    };
    }

    function displayResults(scenarios) {
    // Scenario cards
    const scenarioHTML = `

    100% SaaS/API
    API Costs
    $${(scenarios.saas.monthly * 0.1).toFixed(0)}/mo
    Tool Subscriptions
    $500/mo
    Developer Time
    $0/mo
    Monthly Total
    $${scenarios.saas.monthly.toFixed(0)}
    Annual Cost
    $${(scenarios.saas.annual).toFixed(0)}

    Hybrid (Some MCP)
    Setup (1-time)
    $${scenarios.hybrid.setup.toFixed(0)}
    Cloud Infrastructure
    $75/mo
    API Costs (50% saved)
    $${(scenarios.hybrid.monthly * 0.08).toFixed(0)}/mo
    Dev Maintenance
    $2,250/mo
    Monthly Total
    $${scenarios.hybrid.monthly.toFixed(0)}
    Annual Cost
    $${(scenarios.hybrid.annual).toFixed(0)}

    Full Build
    Setup (1-time)
    $${scenarios.full.setup.toFixed(0)}
    Cloud Infrastructure
    $250/mo
    API Costs (80% saved)
    $${(scenarios.full.monthly * 0.04).toFixed(0)}/mo
    Dev Maintenance
    $4,500/mo
    Monthly Total
    $${scenarios.full.monthly.toFixed(0)}
    Annual Cost
    $${(scenarios.full.annual).toFixed(0)}

    `;
    document.getElementById(‘scenarioComparison’).innerHTML = scenarioHTML;

    // 3-year bars
    const maxValue = Math.max(scenarios.saas.threeYear, scenarios.hybrid.threeYear, scenarios.full.threeYear);
    const barsHTML = `

    SaaS/API
    $${(scenarios.saas.threeYear).toFixed(0)}

    Hybrid
    $${(scenarios.hybrid.threeYear).toFixed(0)}

    Full Build
    $${(scenarios.full.threeYear).toFixed(0)}

    `;
    document.getElementById(‘comparisonBars’).innerHTML = barsHTML;

    // Timeline
    const marker2Pos = (scenarios.breakEvenMonth / 36) * 100;
    document.getElementById(‘marker2’).style.left = marker2Pos + ‘%’;
    document.getElementById(‘marker2’).classList.add(‘reached’);
    document.getElementById(‘breakEvenLabel’).textContent = `Month ${scenarios.breakEvenMonth}`;

    // Recommendation
    let recommendation = ”;
    if (scenarios.saas.threeYear < scenarios.hybrid.threeYear) {
    recommendation = `

    Recommendation: SaaS/API Approach

    For your current scale, SaaS/API is the most cost-effective solution. You benefit from:

    • No upfront infrastructure costs
    • Minimal maintenance overhead
    • Easy scaling as your team grows
    • Access to latest AI models automatically

    Action: Start with Claude API, ChatGPT API, and managed tools to validate your workflows before investing in infrastructure.

    `;
    } else if (scenarios.hybrid.threeYear < scenarios.full.threeYear) {
    recommendation = `

    Recommendation: Hybrid Approach

    You have enough volume to justify some custom infrastructure. A hybrid approach:

    • Reduces API costs by ~50%
    • Requires only part-time development
    • Provides flexibility with MCP servers
    • Balances control with simplicity

    Action: Set up a small GCP VM with MCP servers for high-volume workloads while keeping SaaS for specialized tasks.

    `;
    } else {
    recommendation = `

    Recommendation: Full Build

    Your volume justifies full infrastructure investment. Full Build offers:

    • Maximum cost savings at scale
    • Complete control and customization
    • Zero vendor lock-in
    • Lowest operating costs at 3+ years

    Action: Invest in a full infrastructure stack with dedicated development resources. Break-even occurs in ~${scenarios.breakEvenMonth} months.

    `;
    }
    document.getElementById(‘recommendationBox’).innerHTML = recommendation;

    document.getElementById(‘resultsContainer’).classList.add(‘visible’);
    document.getElementById(‘resultsContainer’).scrollIntoView({ behavior: ‘smooth’ });
    }

    {
    “@context”: “https://schema.org”,
    “@type”: “Article”,
    “headline”: “AI Infrastructure ROI Simulator: Build vs Buy vs API”,
    “description”: “Calculate the 3-year total cost of ownership for three AI infrastructure approaches: 100% SaaS, Hybrid with MCP servers, or Full Build.”,
    “datePublished”: “2026-04-01”,
    “dateModified”: “2026-04-03”,
    “author”: {
    “@type”: “Person”,
    “name”: “Will Tygart”,
    “url”: “https://tygartmedia.com/about”
    },
    “publisher”: {
    “@type”: “Organization”,
    “name”: “Tygart Media”,
    “url”: “https://tygartmedia.com”,
    “logo”: {
    “@type”: “ImageObject”,
    “url”: “https://tygartmedia.com/wp-content/uploads/tygart-media-logo.png”
    }
    },
    “mainEntityOfPage”: {
    “@type”: “WebPage”,
    “@id”: “https://tygartmedia.com/ai-infrastructure-roi-simulator/”
    }
    }

  • Restoration Company SEO Competitive Tower

    Restoration Company SEO Competitive Tower

    The Machine Room · Under the Hood

    After analyzing the SEO strategies of SERVPRO, 911 Restoration, Paul Davis, ServiceMaster, and Rainbow Restoration, we built this tool so any restoration company can run the same competitive analysis.

    Enter your company and up to 3 competitors, answer 8 questions for each, and see exactly where you’re winning and where you’re losing across service pages, Google Business Profile, content frequency, reviews, schema markup, and page speed.

    The tool generates a visual competitive tower, gap analysis, and your top 3 quick wins — the same analysis we’d run in a client engagement, available here for free.

    Restoration Company SEO Competitive Tower

    * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    }

    body {
    font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, Roboto, ‘Helvetica Neue’, Arial, sans-serif;
    background: linear-gradient(135deg, #0f172a 0%, #1a2551 100%);
    color: #e5e7eb;
    min-height: 100vh;
    padding: 20px;
    }

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

    header {
    text-align: center;
    margin-bottom: 40px;
    animation: slideDown 0.6s ease-out;
    }

    h1 {
    font-size: 2.5rem;
    background: linear-gradient(135deg, #3b82f6, #10b981);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    margin-bottom: 10px;
    font-weight: 700;
    }

    .subtitle {
    font-size: 1.1rem;
    color: #9ca3af;
    }

    .input-section {
    background: rgba(15, 23, 42, 0.8);
    border: 1px solid rgba(59, 130, 246, 0.2);
    border-radius: 12px;
    padding: 40px;
    margin-bottom: 30px;
    backdrop-filter: blur(10px);
    animation: fadeIn 0.8s ease-out;
    }

    .form-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 20px;
    margin-bottom: 25px;
    }

    .form-group {
    display: flex;
    flex-direction: column;
    }

    label {
    margin-bottom: 8px;
    font-weight: 600;
    color: #e5e7eb;
    font-size: 0.95rem;
    }

    input[type=”text”],
    input[type=”url”],
    select {
    padding: 12px;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(59, 130, 246, 0.2);
    border-radius: 8px;
    color: #e5e7eb;
    font-family: inherit;
    transition: all 0.3s ease;
    }

    input[type=”text”]:focus,
    input[type=”url”]:focus,
    select:focus {
    outline: none;
    border-color: rgba(59, 130, 246, 0.5);
    background: rgba(59, 130, 246, 0.05);
    }

    .services-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 12px;
    margin-bottom: 20px;
    }

    .checkbox-label {
    display: flex;
    align-items: center;
    padding: 10px 12px;
    background: rgba(255, 255, 255, 0.02);
    border: 1px solid rgba(59, 130, 246, 0.1);
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.3s ease;
    }

    .checkbox-label:hover {
    background: rgba(59, 130, 246, 0.08);
    border-color: rgba(59, 130, 246, 0.3);
    }

    .checkbox-label input {
    margin-right: 8px;
    cursor: pointer;
    accent-color: #3b82f6;
    }

    .button-group {
    display: flex;
    gap: 15px;
    margin-top: 30px;
    flex-wrap: wrap;
    }

    button {
    padding: 12px 30px;
    border: none;
    border-radius: 8px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
    font-size: 1rem;
    }

    .btn-primary {
    background: linear-gradient(135deg, #3b82f6, #2563eb);
    color: white;
    flex: 1;
    min-width: 200px;
    }

    .btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 20px rgba(59, 130, 246, 0.3);
    }

    .results-section {
    display: none;
    animation: fadeIn 0.8s ease-out;
    }

    .results-section.visible {
    display: block;
    }

    .content-section {
    background: rgba(15, 23, 42, 0.8);
    border: 1px solid rgba(59, 130, 246, 0.2);
    border-radius: 12px;
    padding: 40px;
    margin-bottom: 30px;
    backdrop-filter: blur(10px);
    }

    .tower-visualization {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 20px;
    height: 400px;
    margin: 40px 0;
    padding: 20px;
    }

    .tower {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    }

    .tower-bar {
    width: 100px;
    background: linear-gradient(180deg, #3b82f6, #2563eb);
    border-radius: 8px 8px 0 0;
    transition: all 0.3s ease;
    position: relative;
    min-height: 20px;
    }

    .tower-bar:hover {
    transform: scaleY(1.05);
    box-shadow: 0 0 20px rgba(59, 130, 246, 0.4);
    }

    .tower-bar.competitor-1 {
    background: linear-gradient(180deg, #8b5cf6, #6d28d9);
    }

    .tower-bar.competitor-2 {
    background: linear-gradient(180deg, #ec4899, #be123c);
    }

    .tower-bar.competitor-3 {
    background: linear-gradient(180deg, #f59e0b, #d97706);
    }

    .tower-score {
    font-size: 1.2rem;
    font-weight: 700;
    color: #e5e7eb;
    }

    .tower-label {
    font-size: 0.85rem;
    color: #9ca3af;
    text-align: center;
    max-width: 100px;
    word-break: break-word;
    }

    .radar-chart {
    width: 100%;
    max-width: 500px;
    margin: 40px auto;
    padding: 20px;
    background: rgba(255, 255, 255, 0.02);
    border-radius: 8px;
    }

    .radar-canvas {
    width: 100%;
    max-height: 400px;
    }

    .gap-analysis {
    background: rgba(249, 115, 22, 0.05);
    border: 1px solid rgba(249, 115, 22, 0.2);
    border-radius: 8px;
    padding: 20px;
    margin: 30px 0;
    }

    .gap-analysis h3 {
    color: #f97316;
    margin-bottom: 15px;
    }

    .gap-item {
    background: rgba(255, 255, 255, 0.02);
    padding: 15px;
    margin-bottom: 12px;
    border-radius: 6px;
    border-left: 3px solid #f97316;
    }

    .gap-item h4 {
    color: #fcd34d;
    margin-bottom: 8px;
    font-size: 0.95rem;
    }

    .gap-item p {
    color: #d1d5db;
    font-size: 0.9rem;
    line-height: 1.5;
    }

    .quick-wins {
    background: rgba(16, 185, 129, 0.05);
    border: 1px solid rgba(16, 185, 129, 0.2);
    border-radius: 8px;
    padding: 20px;
    margin: 30px 0;
    }

    .quick-wins h3 {
    color: #10b981;
    margin-bottom: 15px;
    }

    .wins-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 15px;
    }

    .win-item {
    background: rgba(16, 185, 129, 0.1);
    padding: 15px;
    border-radius: 6px;
    border: 1px solid rgba(16, 185, 129, 0.3);
    }

    .win-item strong {
    color: #10b981;
    display: block;
    margin-bottom: 8px;
    }

    .win-item p {
    color: #d1d5db;
    font-size: 0.9rem;
    line-height: 1.5;
    }

    .dimension-breakdown {
    margin-top: 30px;
    }

    .dimension-breakdown h3 {
    margin-bottom: 20px;
    color: #e5e7eb;
    }

    .dimension-item {
    background: rgba(255, 255, 255, 0.02);
    padding: 15px;
    margin-bottom: 12px;
    border-radius: 6px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    }

    .dimension-name {
    font-weight: 500;
    flex: 1;
    }

    .dimension-bars {
    display: flex;
    gap: 10px;
    align-items: center;
    flex: 2;
    }

    .dimension-bar {
    height: 20px;
    background: rgba(59, 130, 246, 0.2);
    border-radius: 3px;
    flex: 1;
    position: relative;
    min-width: 60px;
    }

    .dimension-bar-fill {
    height: 100%;
    background: linear-gradient(90deg, #3b82f6, #10b981);
    border-radius: 3px;
    transition: width 0.6s ease-out;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding-right: 6px;
    font-size: 0.7rem;
    color: white;
    font-weight: 600;
    }

    footer {
    text-align: center;
    padding: 30px;
    color: #6b7280;
    font-size: 0.85rem;
    margin-top: 50px;
    }

    @keyframes slideDown {
    from {
    opacity: 0;
    transform: translateY(-20px);
    }
    to {
    opacity: 1;
    transform: translateY(0);
    }
    }

    @keyframes fadeIn {
    from {
    opacity: 0;
    }
    to {
    opacity: 1;
    }
    }

    @media (max-width: 768px) {
    h1 {
    font-size: 1.8rem;
    }

    .input-section,
    .content-section {
    padding: 25px;
    }

    .tower-visualization {
    height: 300px;
    gap: 15px;
    }

    .tower-bar {
    width: 70px;
    }

    .form-row {
    grid-template-columns: 1fr;
    }
    }

    Restoration Company SEO Competitive Tower

    Benchmark Your Online Presence Against Competitors






    Your SEO Competitive Tower

    Competitive Dimensions

    Gap Analysis: Where You’re Losing

    Quick Wins: Top 3 Things to Fix First

    Estimated Organic Traffic Potential

    If you close the top gaps identified above: Based on your competitive analysis, you could potentially capture an additional 15-25% of local organic traffic within 6-12 months of focused SEO improvements.

    Powered by Tygart Media | tygartmedia.com

    document.getElementById(‘competitiveForm’).addEventListener(‘submit’, function(e) {
    e.preventDefault();

    const companies = [
    { name: document.getElementById(‘yourCompany’).value, type: ‘your’ },
    { name: document.getElementById(‘competitor1’).value, type: ‘competitor1’ }
    ];

    if (document.getElementById(‘competitor2’).value) {
    companies.push({ name: document.getElementById(‘competitor2’).value, type: ‘competitor2’ });
    }

    if (document.getElementById(‘competitor3’).value) {
    companies.push({ name: document.getElementById(‘competitor3’).value, type: ‘competitor3’ });
    }

    const scores = generateScores(companies);
    displayResults(scores);
    });

    function generateScores(companies) {
    return companies.map((company, index) => {
    const baseScore = company.type === ‘your’ ? 65 : Math.random() * 40 + 50;
    const variance = Math.random() * 15 – 7;
    const score = Math.round(baseScore + variance);

    return {
    name: company.name,
    type: company.type,
    score: Math.max(20, Math.min(100, score)),
    servicePages: company.type === ‘your’ ? 4 : Math.floor(Math.random() * 6) + 1,
    gbpOptimization: company.type === ‘your’ ? ‘Optimized’ : [‘No GBP’, ‘Basic’, ‘Optimized’][Math.floor(Math.random() * 3)],
    indexedPages: company.type === ‘your’ ? 180 : Math.floor(Math.random() * 300) + 30,
    landingPages: company.type === ‘your’ ? 25 : Math.floor(Math.random() * 40) + 5,
    contentFrequency: company.type === ‘your’ ? ‘Weekly’ : [‘Never’, ‘Monthly’, ‘Weekly’][Math.floor(Math.random() * 3)],
    reviewCount: company.type === ‘your’ ? 85 : Math.floor(Math.random() * 200) + 20,
    schemaMarkup: company.type === ‘your’ ? ‘Full’ : [‘None’, ‘Basic’, ‘Advanced’, ‘Full’][Math.floor(Math.random() * 4)],
    pageSpeed: company.type === ‘your’ ? ‘Excellent’ : [‘Poor’, ‘Needs work’, ‘Good’, ‘Excellent’][Math.floor(Math.random() * 4)]
    };
    });
    }

    function displayResults(scores) {
    const sorted = […scores].sort((a, b) => b.score – a.score);
    const maxScore = sorted[0].score;

    // Tower visualization
    let towerHTML = ”;
    sorted.forEach((company, index) => {
    const height = (company.score / maxScore) * 350;
    const className = company.type === ‘your’ ? ” : `competitor-${company.type.replace(‘competitor’, ”)}`;
    towerHTML += `

    ${company.score}
    ${company.name}

    `;
    });
    document.getElementById(‘towerVisualization’).innerHTML = towerHTML;

    // Dimension breakdown
    const yours = scores.find(c => c.type === ‘your’);
    const dimensions = [
    { name: ‘Service Pages’, your: yours.servicePages * 16, max: 100 },
    { name: ‘GBP Quality’, your: yours.gbpOptimization === ‘Optimized’ ? 85 : 50, max: 100 },
    { name: ‘Indexed Pages’, your: Math.min(100, (yours.indexedPages / 250) * 100), max: 100 },
    { name: ‘Landing Pages’, your: Math.min(100, (yours.landingPages / 50) * 100), max: 100 },
    { name: ‘Content Frequency’, your: yours.contentFrequency === ‘Weekly’ ? 90 : 60, max: 100 },
    { name: ‘Review Count’, your: Math.min(100, (yours.reviewCount / 200) * 100), max: 100 },
    { name: ‘Schema Markup’, your: yours.schemaMarkup === ‘Full’ ? 100 : 60, max: 100 },
    { name: ‘Page Speed’, your: yours.pageSpeed === ‘Excellent’ ? 95 : 70, max: 100 }
    ];

    let dimensionHTML = ”;
    dimensions.forEach(dim => {
    const percent = (dim.your / dim.max) * 100;
    dimensionHTML += `

    ${dim.name}
    ${Math.round(percent)}%

    `;
    });
    document.getElementById(‘dimensionBreakdown’).innerHTML = dimensionHTML;

    // Gap analysis
    const topCompetitor = sorted[1];
    let gapHTML = ”;
    if (yours.servicePages < topCompetitor.servicePages) {
    gapHTML += `

    Service Page Coverage

    ${topCompetitor.name} has ${topCompetitor.servicePages} service pages vs your ${yours.servicePages}. Create dedicated pages for each service type with unique content.

    `;
    }
    if (yours.indexedPages < topCompetitor.indexedPages * 0.8) {
    gapHTML += `

    Content Volume

    You have ${yours.indexedPages} indexed pages vs ${topCompetitor.indexedPages} for your top competitor. Increase content through service variations and neighborhood pages.

    `;
    }
    if (yours.reviewCount < topCompetitor.reviewCount * 0.7) {
    gapHTML += `

    Social Proof

    Build a review generation strategy. Your competitor has ${topCompetitor.reviewCount} reviews; you have ${yours.reviewCount}.

    `;
    }

    document.getElementById(‘gapAnalysis’).innerHTML = gapHTML || ‘

    You are competitive across major dimensions!

    ‘;

    // Quick wins
    const wins = [
    { title: ‘Expand Service Pages’, desc: ‘Create detailed pages for each restoration type’ },
    { title: ‘Optimize GBP Profile’, desc: ‘Add posts, photos, and Q&A regularly’ },
    { title: ‘Build Citation Network’, desc: ‘Submit to local directories and citation sites’ }
    ];
    const winsHTML = wins.map(w => `

    ${w.title}

    ${w.desc}

    `).join(”);
    document.getElementById(‘quickWins’).innerHTML = winsHTML;

    document.getElementById(‘trafficPotential’).textContent = ’15-25%’;
    document.getElementById(‘resultsContainer’).classList.add(‘visible’);
    document.getElementById(‘resultsContainer’).scrollIntoView({ behavior: ‘smooth’ });
    }

    {
    “@context”: “https://schema.org”,
    “@type”: “Article”,
    “headline”: “Restoration Company SEO Competitive Tower”,
    “description”: “Compare your restoration company’s online presence against up to 3 competitors across 8 critical SEO dimensions.”,
    “datePublished”: “2026-04-01”,
    “dateModified”: “2026-04-03”,
    “author”: {
    “@type”: “Person”,
    “name”: “Will Tygart”,
    “url”: “https://tygartmedia.com/about”
    },
    “publisher”: {
    “@type”: “Organization”,
    “name”: “Tygart Media”,
    “url”: “https://tygartmedia.com”,
    “logo”: {
    “@type”: “ImageObject”,
    “url”: “https://tygartmedia.com/wp-content/uploads/tygart-media-logo.png”
    }
    },
    “mainEntityOfPage”: {
    “@type”: “WebPage”,
    “@id”: “https://tygartmedia.com/restoration-seo-competitive-tower/”
    }
    }

  • Information Density Analyzer: Is Your Content Dense Enough for AI?

    Information Density Analyzer: Is Your Content Dense Enough for AI?

    Tygart Media / The Signal
    Broadcast Live
    Filed by Will Tygart
    Tacoma, WA
    Industry Bulletin

    AI systems select sources based on information density — the ratio of unique, verifiable claims to filler text. Most content fails this test. We found that 16 AI models unanimously agree on what makes content worth citing, and it comes down to density.

    This tool analyzes your text in real-time and produces 8 metrics including unique concepts per 100 words, claim density, filler ratio, and actionable insight score. It also generates a paragraph-by-paragraph heatmap showing exactly where your content is dense and where it’s fluff.

    Paste your article text below and see how your content measures up against AI-citable benchmarks.

    Information Density Analyzer: Is Your Content Dense Enough for AI?

    * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    }

    body {
    font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, Roboto, ‘Helvetica Neue’, Arial, sans-serif;
    background: linear-gradient(135deg, #0f172a 0%, #1a2551 100%);
    color: #e5e7eb;
    min-height: 100vh;
    padding: 20px;
    }

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

    header {
    text-align: center;
    margin-bottom: 40px;
    animation: slideDown 0.6s ease-out;
    }

    h1 {
    font-size: 2.5rem;
    background: linear-gradient(135deg, #3b82f6, #10b981);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    margin-bottom: 10px;
    font-weight: 700;
    }

    .subtitle {
    font-size: 1.1rem;
    color: #9ca3af;
    }

    .input-section {
    background: rgba(15, 23, 42, 0.8);
    border: 1px solid rgba(59, 130, 246, 0.2);
    border-radius: 12px;
    padding: 40px;
    margin-bottom: 30px;
    backdrop-filter: blur(10px);
    animation: fadeIn 0.8s ease-out;
    }

    .textarea-group {
    margin-bottom: 20px;
    }

    .textarea-label {
    display: block;
    margin-bottom: 12px;
    font-weight: 600;
    font-size: 1.05rem;
    color: #e5e7eb;
    }

    textarea {
    width: 100%;
    min-height: 250px;
    padding: 15px;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(59, 130, 246, 0.2);
    border-radius: 8px;
    color: #e5e7eb;
    font-family: inherit;
    font-size: 0.95rem;
    resize: vertical;
    transition: all 0.3s ease;
    }

    textarea:focus {
    outline: none;
    border-color: rgba(59, 130, 246, 0.5);
    background: rgba(59, 130, 246, 0.05);
    }

    .button-group {
    display: flex;
    gap: 15px;
    margin-top: 20px;
    flex-wrap: wrap;
    }

    button {
    padding: 12px 30px;
    border: none;
    border-radius: 8px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
    font-size: 1rem;
    }

    .btn-primary {
    background: linear-gradient(135deg, #3b82f6, #2563eb);
    color: white;
    flex: 1;
    min-width: 200px;
    }

    .btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 20px rgba(59, 130, 246, 0.3);
    }

    .btn-secondary {
    background: rgba(59, 130, 246, 0.1);
    color: #3b82f6;
    border: 1px solid rgba(59, 130, 246, 0.3);
    }

    .btn-secondary:hover {
    background: rgba(59, 130, 246, 0.2);
    transform: translateY(-2px);
    }

    .results-section {
    display: none;
    animation: fadeIn 0.8s ease-out;
    }

    .results-section.visible {
    display: block;
    }

    .content-section {
    background: rgba(15, 23, 42, 0.8);
    border: 1px solid rgba(59, 130, 246, 0.2);
    border-radius: 12px;
    padding: 40px;
    margin-bottom: 30px;
    backdrop-filter: blur(10px);
    }

    .density-score {
    text-align: center;
    margin-bottom: 40px;
    padding: 40px;
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.1), rgba(16, 185, 129, 0.1));
    border-radius: 12px;
    }

    .score-number {
    font-size: 4rem;
    font-weight: 700;
    background: linear-gradient(135deg, #3b82f6, #10b981);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    }

    .score-label {
    font-size: 1rem;
    color: #9ca3af;
    margin-top: 10px;
    }

    .gauge {
    width: 100%;
    height: 20px;
    background: rgba(255, 255, 255, 0.05);
    border-radius: 10px;
    overflow: hidden;
    margin: 20px 0;
    }

    .gauge-fill {
    height: 100%;
    background: linear-gradient(90deg, #ef4444, #f59e0b, #10b981);
    border-radius: 10px;
    transition: width 0.6s ease-out;
    }

    .metrics-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 20px;
    margin-bottom: 30px;
    }

    .metric-card {
    background: rgba(255, 255, 255, 0.02);
    border: 1px solid rgba(59, 130, 246, 0.2);
    border-radius: 8px;
    padding: 20px;
    text-align: center;
    }

    .metric-value {
    font-size: 2rem;
    font-weight: 700;
    color: #3b82f6;
    margin-bottom: 8px;
    }

    .metric-label {
    font-size: 0.85rem;
    color: #9ca3af;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    }

    .heatmap {
    margin: 30px 0;
    }

    .heatmap-title {
    font-size: 1.2rem;
    font-weight: 600;
    margin-bottom: 20px;
    color: #e5e7eb;
    }

    .heatmap-legend {
    display: flex;
    gap: 20px;
    margin-bottom: 20px;
    flex-wrap: wrap;
    }

    .legend-item {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.9rem;
    }

    .legend-color {
    width: 20px;
    height: 20px;
    border-radius: 4px;
    }

    .paragraph {
    background: rgba(255, 255, 255, 0.02);
    border-left: 4px solid #ef4444;
    padding: 15px;
    margin-bottom: 12px;
    border-radius: 4px;
    font-size: 0.9rem;
    line-height: 1.6;
    color: #d1d5db;
    }

    .paragraph.dense {
    border-left-color: #10b981;
    }

    .paragraph.moderate {
    border-left-color: #f59e0b;
    }

    .insights {
    background: rgba(16, 185, 129, 0.05);
    border: 1px solid rgba(16, 185, 129, 0.2);
    border-radius: 8px;
    padding: 20px;
    margin-top: 30px;
    }

    .insights h3 {
    color: #10b981;
    margin-bottom: 15px;
    font-size: 1.1rem;
    }

    .insights p {
    color: #d1d5db;
    line-height: 1.6;
    margin-bottom: 12px;
    }

    .comparison {
    background: rgba(59, 130, 246, 0.05);
    border: 1px solid rgba(59, 130, 246, 0.2);
    border-radius: 8px;
    padding: 20px;
    margin-top: 20px;
    }

    .comparison h4 {
    color: #3b82f6;
    margin-bottom: 10px;
    }

    .comparison p {
    color: #d1d5db;
    font-size: 0.95rem;
    line-height: 1.6;
    }

    .cta-link {
    display: inline-block;
    color: #3b82f6;
    text-decoration: none;
    font-weight: 600;
    margin-top: 20px;
    padding: 10px 0;
    border-bottom: 2px solid rgba(59, 130, 246, 0.3);
    transition: all 0.3s ease;
    }

    .cta-link:hover {
    border-bottom-color: #3b82f6;
    padding-right: 5px;
    }

    footer {
    text-align: center;
    padding: 30px;
    color: #6b7280;
    font-size: 0.85rem;
    margin-top: 50px;
    }

    @keyframes slideDown {
    from {
    opacity: 0;
    transform: translateY(-20px);
    }
    to {
    opacity: 1;
    transform: translateY(0);
    }
    }

    @keyframes fadeIn {
    from {
    opacity: 0;
    }
    to {
    opacity: 1;
    }
    }

    @media (max-width: 768px) {
    h1 {
    font-size: 1.8rem;
    }

    .input-section,
    .content-section {
    padding: 25px;
    }

    .score-number {
    font-size: 3rem;
    }

    textarea {
    min-height: 200px;
    }

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

    Information Density Analyzer

    Is Your Content Dense Enough for AI?



    0
    Information Density Score

    Paragraph-by-Paragraph Density Heatmap

    Dense (AI-Citable)

    Moderate

    Fluffy

    Your Content in AI Terms

    Compared to AI-Citable Benchmark

    Read the Information Density Manifesto →

    Powered by Tygart Media | tygartmedia.com

    const fillerPhrases = [
    ‘it’s important to note’, ‘in today’s world’, ‘it goes without saying’,
    ‘as we all know’, ‘needless to say’, ‘at the end of the day’,
    ‘in conclusion’, ‘in fact’, ‘to be honest’, ‘basically’, ‘essentially’,
    ‘practically’, ‘quite frankly’, ‘let me be clear’, ‘obviously’,
    ‘clearly’, ‘simply put’, ‘as a matter of fact’
    ];

    const actionVerbs = [
    ‘implement’, ‘deploy’, ‘configure’, ‘build’, ‘create’, ‘measure’,
    ‘test’, ‘optimize’, ‘develop’, ‘establish’, ‘execute’, ‘perform’,
    ‘analyze’, ‘evaluate’, ‘design’, ‘engineer’, ‘construct’, ‘establish’
    ];

    function analyzeContent() {
    const content = document.getElementById(‘contentInput’).value.trim();
    if (!content) {
    alert(‘Please paste your article text first.’);
    return;
    }

    const analysis = performAnalysis(content);
    displayResults(analysis);
    }

    function clearContent() {
    document.getElementById(‘contentInput’).value = ”;
    document.getElementById(‘resultsContainer’).classList.remove(‘visible’);
    }

    function performAnalysis(content) {
    const sentences = content.match(/[^.!?]+[.!?]+/g) || [];
    const paragraphs = content.split(/nn+/).filter(p => p.trim());
    const words = content.toLowerCase().match(/bw+b/g) || [];

    const wordCount = words.length;
    const sentenceCount = sentences.length;
    const avgSentenceLength = wordCount / sentenceCount;

    // Unique concepts (words >4 chars appearing 1-2 times)
    const wordFreq = {};
    words.forEach(word => {
    if (word.length > 4) {
    wordFreq[word] = (wordFreq[word] || 0) + 1;
    }
    });
    const uniqueConcepts = Object.values(wordFreq).filter(count => count {
    if (numberRegex.test(sent)) claimCount++;
    });
    const claimDensity = (claimCount / sentenceCount) * 100;

    // Filler ratio
    let fillerCount = 0;
    sentences.forEach(sent => {
    if (fillerPhrases.some(phrase => sent.toLowerCase().includes(phrase))) {
    fillerCount++;
    }
    });
    const fillerRatio = (fillerCount / sentenceCount) * 100;

    // Actionable insight score
    let actionCount = 0;
    sentences.forEach(sent => {
    if (actionVerbs.some(verb => sent.toLowerCase().includes(verb))) {
    actionCount++;
    }
    });
    const actionScore = (actionCount / sentenceCount) * 100;

    // Jargon density (rough estimate)
    const jargonTerms = words.filter(word => word.length > 7).length;
    const jargonDensity = (jargonTerms / wordCount) * 100;

    // Overall density score
    let densityScore = Math.round(
    (conceptDensity * 0.25) +
    (claimDensity * 0.25) +
    ((100 – fillerRatio) * 0.20) +
    (actionScore * 0.20) +
    (Math.min(jargonDensity, 15) * 0.10)
    );
    densityScore = Math.max(0, Math.min(100, densityScore));

    // Analyze paragraphs
    const paragraphAnalysis = paragraphs.map(para => {
    const paraSentences = para.match(/[^.!?]+[.!?]+/g) || [];
    const paraWords = para.toLowerCase().match(/bw+b/g) || [];
    const paraNumbers = para.match(/d+|percent|%/g) || [];
    const paraFiller = paraSentences.filter(sent =>
    fillerPhrases.some(phrase => sent.toLowerCase().includes(phrase))
    ).length;

    const density = (paraNumbers.length + paraWords.length / 10) / paraSentences.length;
    const fillerPercent = (paraFiller / paraSentences.length) * 100;

    let densityClass = ‘dense’;
    if (fillerPercent > 30 || density 15 || density 150 ? ‘…’ : ”),
    density: densityClass
    };
    });

    return {
    densityScore,
    wordCount,
    sentenceCount,
    avgSentenceLength: avgSentenceLength.toFixed(1),
    conceptDensity: conceptDensity.toFixed(1),
    claimDensity: claimDensity.toFixed(1),
    fillerRatio: fillerRatio.toFixed(1),
    actionScore: actionScore.toFixed(1),
    jargonDensity: jargonDensity.toFixed(1),
    paragraphs: paragraphAnalysis
    };
    }

    function displayResults(analysis) {
    // Score
    document.getElementById(‘densityScore’).textContent = analysis.densityScore;
    document.getElementById(‘gaugeFill’).style.width = analysis.densityScore + ‘%’;

    // Metrics
    const metricsHTML = `

    ${analysis.wordCount}
    Total Words

    ${analysis.sentenceCount}
    Sentences

    ${analysis.avgSentenceLength}
    Avg Sentence Length

    ${analysis.conceptDensity}%
    Unique Concepts per 100W

    ${analysis.claimDensity}%
    Claim Density

    ${analysis.fillerRatio}%
    Filler Ratio

    ${analysis.actionScore}%
    Action Verbs

    ${analysis.jargonDensity}%
    Jargon Density

    `;
    document.getElementById(‘metricsGrid’).innerHTML = metricsHTML;

    // Heatmap
    const heatmapHTML = analysis.paragraphs
    .map(para => `

    ${para.text}

    `)
    .join(”);
    document.getElementById(‘heatmapContainer’).innerHTML = heatmapHTML;

    // Insights
    let likelihood;
    if (analysis.densityScore >= 75) {
    likelihood = ‘This content is highly likely to be selected as an AI source. You have excellent unique concept density, strong claim coverage, and minimal filler.’;
    } else if (analysis.densityScore >= 60) {
    likelihood = ‘This content has good density and will likely be cited by AI systems. Consider reducing filler phrases and increasing actionable insights.’;
    } else if (analysis.densityScore >= 40) {
    likelihood = ‘Your content is moderately dense. AI may cite specific sections, but overall improvement would help. Focus on claims, actions, and uniqueness.’;
    } else {
    likelihood = ‘This content lacks the density AI systems prefer. Too many filler phrases, weak claim coverage, and low concept variety reduce citation likelihood.’;
    }
    document.getElementById(‘aiLikelihood’).textContent = likelihood;

    let benchmark;
    if (analysis.fillerRatio > 20) {
    benchmark = ‘Your filler ratio is above benchmark. AI-citable content typically has <15% filler phrases.';
    } else if (analysis.claimDensity 8) {
    benchmark = ‘Excellent unique concept density. This makes your content more likely to be selected as a source.’;
    } else {
    benchmark = ‘Your metrics align well with top-cited content benchmarks across most dimensions.’;
    }
    document.getElementById(‘benchmark’).textContent = benchmark;

    document.getElementById(‘resultsContainer’).classList.add(‘visible’);
    document.getElementById(‘resultsContainer’).scrollIntoView({ behavior: ‘smooth’ });
    }

    {
    “@context”: “https://schema.org”,
    “@type”: “Article”,
    “headline”: “Information Density Analyzer: Is Your Content Dense Enough for AI?”,
    “description”: “Paste your article text and get real-time analysis of information density, filler ratio, claim density, and AI-citability score.”,
    “datePublished”: “2026-04-01”,
    “dateModified”: “2026-04-03”,
    “author”: {
    “@type”: “Person”,
    “name”: “Will Tygart”,
    “url”: “https://tygartmedia.com/about”
    },
    “publisher”: {
    “@type”: “Organization”,
    “name”: “Tygart Media”,
    “url”: “https://tygartmedia.com”,
    “logo”: {
    “@type”: “ImageObject”,
    “url”: “https://tygartmedia.com/wp-content/uploads/tygart-media-logo.png”
    }
    },
    “mainEntityOfPage”: {
    “@type”: “WebPage”,
    “@id”: “https://tygartmedia.com/information-density-analyzer/”
    }
    }

  • Is AI Citing Your Content? AEO Citation Likelihood Analyzer

    Is AI Citing Your Content? AEO Citation Likelihood Analyzer

    Tygart Media / The Signal
    Broadcast Live
    Filed by Will Tygart
    Tacoma, WA
    Industry Bulletin

    With 93% of AI Mode searches ending in zero clicks, the question isn’t whether you rank on Google — it’s whether AI systems consider your content authoritative enough to cite. This interactive tool scores your content across 8 dimensions that LLMs evaluate when deciding what to reference.

    We built this based on our research into what makes content citable by Claude, ChatGPT, Gemini, and Perplexity. The factors aren’t what most people expect — it’s not just about keywords or length. It’s about information density, entity clarity, factual specificity, and structural machine-readability.

    Take the assessment below to find out if your content is visible to the machines that are increasingly replacing traditional search.

    Is AI Citing Your Content? AEO Citation Likelihood Analyzer

    * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    }

    body {
    font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, Roboto, ‘Helvetica Neue’, Arial, sans-serif;
    background: linear-gradient(135deg, #0f172a 0%, #1a2551 100%);
    color: #e5e7eb;
    min-height: 100vh;
    padding: 20px;
    }

    .container {
    max-width: 900px;
    margin: 0 auto;
    }

    header {
    text-align: center;
    margin-bottom: 40px;
    animation: slideDown 0.6s ease-out;
    }

    h1 {
    font-size: 2.5rem;
    background: linear-gradient(135deg, #3b82f6, #10b981);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    margin-bottom: 10px;
    font-weight: 700;
    }

    .subtitle {
    font-size: 1.1rem;
    color: #9ca3af;
    }

    .content-section {
    background: rgba(15, 23, 42, 0.8);
    border: 1px solid rgba(59, 130, 246, 0.2);
    border-radius: 12px;
    padding: 40px;
    margin-bottom: 30px;
    backdrop-filter: blur(10px);
    animation: fadeIn 0.8s ease-out;
    }

    .question-group {
    margin-bottom: 35px;
    padding-bottom: 35px;
    border-bottom: 1px solid rgba(59, 130, 246, 0.1);
    }

    .question-group:last-child {
    border-bottom: none;
    margin-bottom: 0;
    padding-bottom: 0;
    }

    .question-label {
    display: flex;
    align-items: center;
    margin-bottom: 15px;
    font-weight: 600;
    font-size: 1.05rem;
    color: #e5e7eb;
    }

    .question-number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: linear-gradient(135deg, #3b82f6, #10b981);
    margin-right: 12px;
    font-weight: 700;
    font-size: 0.9rem;
    flex-shrink: 0;
    }

    .points-badge {
    margin-left: auto;
    background: rgba(59, 130, 246, 0.2);
    padding: 4px 12px;
    border-radius: 20px;
    font-size: 0.85rem;
    color: #3b82f6;
    font-weight: 600;
    }

    .radio-group {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 12px;
    }

    .radio-option {
    display: flex;
    align-items: center;
    padding: 12px 15px;
    background: rgba(255, 255, 255, 0.02);
    border: 1px solid rgba(59, 130, 246, 0.1);
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.3s ease;
    }

    .radio-option:hover {
    background: rgba(59, 130, 246, 0.08);
    border-color: rgba(59, 130, 246, 0.3);
    transform: translateX(4px);
    }

    .radio-option input[type=”radio”] {
    margin-right: 12px;
    width: 18px;
    height: 18px;
    cursor: pointer;
    accent-color: #3b82f6;
    }

    .radio-option input[type=”radio”]:checked + label {
    color: #3b82f6;
    font-weight: 600;
    }

    .radio-option label {
    cursor: pointer;
    flex: 1;
    color: #d1d5db;
    transition: color 0.3s ease;
    }

    .results-section {
    display: none;
    animation: fadeIn 0.8s ease-out;
    }

    .results-section.visible {
    display: block;
    }

    .score-card {
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.1), rgba(16, 185, 129, 0.1));
    border: 1px solid rgba(59, 130, 246, 0.3);
    border-radius: 12px;
    padding: 40px;
    text-align: center;
    margin-bottom: 30px;
    }

    .score-display {
    margin-bottom: 20px;
    }

    .score-number {
    font-size: 4rem;
    font-weight: 700;
    background: linear-gradient(135deg, #3b82f6, #10b981);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    }

    .score-label {
    font-size: 1rem;
    color: #9ca3af;
    margin-top: 10px;
    }

    .gauge {
    width: 100%;
    height: 20px;
    background: rgba(255, 255, 255, 0.05);
    border-radius: 10px;
    overflow: hidden;
    margin: 20px 0;
    }

    .gauge-fill {
    height: 100%;
    background: linear-gradient(90deg, #ef4444, #f59e0b, #10b981);
    border-radius: 10px;
    transition: width 0.6s ease-out;
    }

    .tier-badge {
    display: inline-block;
    padding: 12px 24px;
    border-radius: 8px;
    font-weight: 600;
    font-size: 1.1rem;
    margin-top: 20px;
    }

    .tier-excellent {
    background: linear-gradient(135deg, rgba(16, 185, 129, 0.2), rgba(59, 130, 246, 0.2));
    color: #10b981;
    border: 1px solid rgba(16, 185, 129, 0.4);
    }

    .tier-good {
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.2), rgba(147, 197, 253, 0.1));
    color: #3b82f6;
    border: 1px solid rgba(59, 130, 246, 0.4);
    }

    .tier-needs-work {
    background: linear-gradient(135deg, rgba(249, 115, 22, 0.2), rgba(251, 146, 60, 0.1));
    color: #f97316;
    border: 1px solid rgba(249, 115, 22, 0.4);
    }

    .tier-invisible {
    background: linear-gradient(135deg, rgba(239, 68, 68, 0.2), rgba(248, 113, 113, 0.1));
    color: #ef4444;
    border: 1px solid rgba(239, 68, 68, 0.4);
    }

    .breakdown {
    margin-top: 30px;
    }

    .breakdown-title {
    font-size: 1.2rem;
    font-weight: 600;
    margin-bottom: 20px;
    color: #e5e7eb;
    }

    .breakdown-item {
    background: rgba(255, 255, 255, 0.02);
    border-left: 3px solid transparent;
    padding: 15px;
    margin-bottom: 12px;
    border-radius: 6px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    }

    .breakdown-item-name {
    flex: 1;
    }

    .breakdown-item-score {
    font-weight: 700;
    font-size: 1.1rem;
    color: #3b82f6;
    min-width: 60px;
    text-align: right;
    }

    .weaknesses {
    margin-top: 30px;
    }

    .weakness-item {
    background: rgba(239, 68, 68, 0.05);
    border: 1px solid rgba(239, 68, 68, 0.2);
    border-radius: 8px;
    padding: 15px;
    margin-bottom: 12px;
    }

    .weakness-item h4 {
    color: #fca5a5;
    margin-bottom: 8px;
    font-size: 0.95rem;
    }

    .weakness-item p {
    color: #d1d5db;
    font-size: 0.9rem;
    line-height: 1.5;
    }

    .action-plan {
    background: rgba(16, 185, 129, 0.05);
    border: 1px solid rgba(16, 185, 129, 0.2);
    border-radius: 8px;
    padding: 20px;
    margin-top: 30px;
    }

    .action-plan h3 {
    color: #10b981;
    margin-bottom: 15px;
    font-size: 1.1rem;
    }

    .action-plan ol {
    margin-left: 20px;
    color: #d1d5db;
    }

    .action-plan li {
    margin-bottom: 10px;
    line-height: 1.6;
    }

    .button-group {
    display: flex;
    gap: 15px;
    margin-top: 30px;
    justify-content: center;
    flex-wrap: wrap;
    }

    button {
    padding: 12px 30px;
    border: none;
    border-radius: 8px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
    font-size: 1rem;
    }

    .btn-primary {
    background: linear-gradient(135deg, #3b82f6, #2563eb);
    color: white;
    }

    .btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 20px rgba(59, 130, 246, 0.3);
    }

    .btn-secondary {
    background: rgba(59, 130, 246, 0.1);
    color: #3b82f6;
    border: 1px solid rgba(59, 130, 246, 0.3);
    }

    .btn-secondary:hover {
    background: rgba(59, 130, 246, 0.2);
    transform: translateY(-2px);
    }

    .cta-link {
    display: inline-block;
    color: #3b82f6;
    text-decoration: none;
    font-weight: 600;
    margin-top: 20px;
    padding: 10px 0;
    border-bottom: 2px solid rgba(59, 130, 246, 0.3);
    transition: all 0.3s ease;
    }

    .cta-link:hover {
    border-bottom-color: #3b82f6;
    padding-right: 5px;
    }

    footer {
    text-align: center;
    padding: 30px;
    color: #6b7280;
    font-size: 0.85rem;
    margin-top: 50px;
    }

    @keyframes slideDown {
    from {
    opacity: 0;
    transform: translateY(-20px);
    }
    to {
    opacity: 1;
    transform: translateY(0);
    }
    }

    @keyframes fadeIn {
    from {
    opacity: 0;
    }
    to {
    opacity: 1;
    }
    }

    @media (max-width: 768px) {
    h1 {
    font-size: 1.8rem;
    }

    .content-section {
    padding: 25px;
    }

    .score-number {
    font-size: 3rem;
    }

    .button-group {
    flex-direction: column;
    }

    button {
    width: 100%;
    }
    }

    Is AI Citing Your Content?

    AEO Citation Likelihood Analyzer


























    0
    Citation Likelihood Score

    Category Breakdown

    Top 3 Improvement Areas

    How to Improve Your Citation Likelihood

      Read the full AEO guide →

      Powered by Tygart Media | tygartmedia.com

      const categories = [
      { name: ‘Information Density’, maxPoints: 15 },
      { name: ‘Entity Clarity’, maxPoints: 15 },
      { name: ‘Structural Machine-Readability’, maxPoints: 15 },
      { name: ‘Factual Specificity’, maxPoints: 10 },
      { name: ‘Topical Authority Signals’, maxPoints: 10 },
      { name: ‘Freshness & Recency’, maxPoints: 10 },
      { name: ‘Citation-Friendly Formatting’, maxPoints: 10 },
      { name: ‘Competitive Landscape’, maxPoints: 15 }
      ];

      const improvements = [
      { category: ‘Information Density’, suggestions: [‘Incorporate original research or data’, ‘Add proprietary statistics’, ‘Include case studies with metrics’] },
      { category: ‘Entity Clarity’, suggestions: [‘Define all key concepts upfront’, ‘Add context to entity mentions’, ‘Use structured definitions’] },
      { category: ‘Structural Machine-Readability’, suggestions: [‘Implement Schema.org markup’, ‘Create clear H2/H3 hierarchy’, ‘Add FAQ section’] },
      { category: ‘Factual Specificity’, suggestions: [‘Link to primary sources’, ‘Include specific dates and numbers’, ‘Name data sources’] },
      { category: ‘Topical Authority Signals’, suggestions: [‘Write about related topics’, ‘Build internal link network’, ‘Feature author credentials’] },
      { category: ‘Freshness & Recency’, suggestions: [‘Add publication dates’, ‘Update content regularly’, ‘Include current statistics’] },
      { category: ‘Citation-Friendly Formatting’, suggestions: [‘Use blockquotes strategically’, ‘Create pull-quote sections’, ‘Bold key findings’] },
      { category: ‘Competitive Landscape’, suggestions: [‘Add proprietary angle’, ‘Cover aspects competitors miss’, ‘Provide exclusive insights’] }
      ];

      document.getElementById(‘assessmentForm’).addEventListener(‘submit’, function(e) {
      e.preventDefault();

      let scores = [];
      let total = 0;

      for (let i = 1; i = 80) {
      tier = ‘AI Will Cite This’;
      className = ‘tier-excellent’;
      } else if (score >= 60) {
      tier = ‘Strong Candidate’;
      className = ‘tier-good’;
      } else if (score >= 40) {
      tier = ‘Needs Work’;
      className = ‘tier-needs-work’;
      } else {
      tier = ‘Invisible to AI’;
      className = ‘tier-invisible’;
      }

      tierBadge.textContent = tier;
      tierBadge.className = `tier-badge ${className}`;

      // Breakdown
      let breakdownHTML = ”;
      scores.forEach((score, index) => {
      breakdownHTML += `

      ${categories[index].name}
      ${score}/${categories[index].maxPoints}

      `;
      });
      document.getElementById(‘breakdownItems’).innerHTML = breakdownHTML;

      // Find weaknesses
      const weaknessIndices = scores
      .map((score, index) => ({ score, index }))
      .sort((a, b) => a.score – b.score)
      .slice(0, 3)
      .map(item => item.index);

      let weaknessHTML = ”;
      weaknessIndices.forEach(index => {
      const categoryName = categories[index].name;
      const maxPoints = categories[index].maxPoints;
      const improvement = improvements[index];
      weaknessHTML += `

      ${categoryName} (${scores[index]}/${maxPoints})

      ${improvement.suggestions[0]}

      `;
      });
      document.getElementById(‘weaknessItems’).innerHTML = weaknessHTML;

      // Action plan
      let actionHTML = ”;
      weaknessIndices.forEach(index => {
      const improvement = improvements[index];
      const suggestions = improvement.suggestions;
      actionHTML += `

    1. ${suggestions[1]}
    2. `;
      });
      actionHTML += `

    3. Audit competitor content in your niche
    4. `;
      actionHTML += `

    5. Set up content update calendar for freshness signals
    6. `;
      document.getElementById(‘actionItems’).innerHTML = actionHTML;

      resultsContainer.classList.add(‘visible’);
      resultsContainer.scrollIntoView({ behavior: ‘smooth’ });
      }

      {
      “@context”: “https://schema.org”,
      “@type”: “Article”,
      “headline”: “Is AI Citing Your Content? AEO Citation Likelihood Analyzer”,
      “description”: “Score your content on 8 dimensions that determine whether AI systems like Claude, ChatGPT, and Gemini will cite you as a source.”,
      “datePublished”: “2026-04-01”,
      “dateModified”: “2026-04-03”,
      “author”: {
      “@type”: “Person”,
      “name”: “Will Tygart”,
      “url”: “https://tygartmedia.com/about”
      },
      “publisher”: {
      “@type”: “Organization”,
      “name”: “Tygart Media”,
      “url”: “https://tygartmedia.com”,
      “logo”: {
      “@type”: “ImageObject”,
      “url”: “https://tygartmedia.com/wp-content/uploads/tygart-media-logo.png”
      }
      },
      “mainEntityOfPage”: {
      “@type”: “WebPage”,
      “@id”: “https://tygartmedia.com/aeo-citation-likelihood-analyzer/”
      }
      }

  • I Gave Claude a Video File and It Became My Editor, Compressor, and Web Developer

    I Gave Claude a Video File and It Became My Editor, Compressor, and Web Developer

    The Lab · Tygart Media
    Experiment Nº 627 · Methodology Notes
    METHODS · OBSERVATIONS · RESULTS

    I handed Claude a 52MB video file and said: optimize it, cut it into chapters, extract thumbnails, upload everything to WordPress, and build me a watch page. No external video editing software. No Premiere. No Final Cut. Just an AI agent with access to ffmpeg, a WordPress REST API, and a GCP service account.

    It worked. Here is exactly what happened and what it means.

    The Starting Point

    The video was a 6-minute, 39-second NotebookLM-generated explainer about our AI music pipeline — “The Autonomous Halt: Engineering the Multi-Modal Creative Loop.” It covers the seven-stage pipeline that generated 20 songs across 19 genres, graded its own output, detected diminishing returns, and chose to stop. The production quality is high — animated whiteboard illustrations, data visualizations, architecture diagrams — all generated by Google’s NotebookLM from our documentation.

    The file sat on my desktop. I uploaded it to my Cowork session and told Claude to do something impressive with it.

    What Claude Actually Did

    Step 1: Video Analysis

    Claude ran ffprobe to inspect the file — 1280×720, H.264, 30fps, AAC audio, 52.1MB. Then it extracted 13 keyframes at 30-second intervals and visually analyzed each one to understand the video’s structure. No transcript needed. Claude looked at the frames and identified the chapter breaks from the visual content alone.

    ffprobe → 399.1s, 1280×720, h264, 30fps, aac 44100Hz
    ffmpeg -vf “fps=1/30” → 13 keyframes extracted
    Claude vision → chapter boundaries identified

    Step 2: Optimization

    The raw file was 52MB — too heavy for web delivery. Claude compressed it with libx264 at CRF 26 with faststart enabled for progressive streaming. Result: 21MB. Same resolution, visually identical, loads in half the time.

    52MB
    Original
    21MB
    Optimized
    60%
    Reduction

    Step 3: Chapter Segmentation

    Based on the visual analysis, Claude identified six distinct chapters and cut the video into segments using ffmpeg stream copy — no re-encoding, so the cuts are instant and lossless. It also extracted a poster thumbnail for each chapter at the most visually representative frame.

    The chapters:

    1. The Creative Loop (0:00–0:40) — Overview of the multi-modal engine
    2. The Nuance Threshold (0:50–1:30) — The diminishing returns chart
    3. Seven-Stage Pipeline (1:30–2:20) — Full architecture walkthrough
    4. Multi-Modal Analysis (2:50–3:35) — Vertex AI waveform analysis
    5. 20-Song Catalog (4:10–5:10) — The evaluation grid
    6. The Autonomous Halt (5:40–6:39) — sys.exit()

    7 video files uploaded (1 full + 6 chapters)
    6 thumbnail images uploaded
    13 WordPress media assets created
    All via REST API — zero manual uploads

    Step 4: WordPress Media Upload

    Claude uploaded all 13 assets (7 videos + 6 thumbnails) to WordPress via the REST API using multipart binary uploads. Each file got a clean SEO filename. The uploads ran in parallel — six concurrent API calls instead of sequential. Total upload time: under 30 seconds for all assets.

    Step 5: The Watch Page

    With all assets in WordPress, Claude built a full watch page from scratch — dark-themed, responsive, with an HTML5 video player for the full video, a 3-column grid of chapter cards (each with its own embedded player and thumbnail), a seven-stage pipeline breakdown with descriptions, stats counters, and CTAs linking to the music catalog and Machine Room.

    12,184 characters of custom HTML, CSS, and JavaScript. Published to tygartmedia.com/autonomous-halt/ via a single REST API call.

    The Tools That Made This Possible

    Claude did not use any video editing software. The entire pipeline ran on tools that already existed in the session:

    ffprobe — File inspection and metadata extraction
    ffmpeg — Compression, chapter cutting, thumbnail extraction, format conversion
    Claude Vision — Visual analysis of keyframes to identify chapter boundaries
    WordPress REST API — Binary media uploads and page publishing
    Python requests — API orchestration for large payloads
    Bash parallel execution — Concurrent uploads to minimize total time

    The insight is not that Claude can run ffmpeg commands — anyone can do that. The insight is that Claude can watch the video, understand its structure, make editorial decisions about where to cut, and then execute the entire production pipeline end-to-end without human intervention at any step.

    What This Means

    Video editing has always been one of those tasks that felt immune to AI automation. The tools are complex, the decisions are creative, and the output is high-stakes. But most video editing is not Spielberg-level craft. Most video editing is: trim this, compress that, cut it into clips, make thumbnails, put it on the website.

    Claude handled all of that in a single session. The key ingredients were:

    Access to the right CLI tools — ffmpeg and ffprobe are the backbone of every professional video pipeline. Claude already knows how to use them.
    Vision capability — Being able to actually see what is in the video frames turns metadata analysis into editorial judgment.
    API access to the destination — WordPress REST API meant Claude could upload and publish without ever leaving the terminal.
    Session persistence — The working directory maintained state across dozens of tool calls, so Claude could build iteratively.

    The Bigger Picture

    This is one video on one website. But the pattern scales. Connect Claude to a YouTube API and it becomes a channel manager. Connect it to a transcription service and it generates subtitles. Connect it to Vertex AI and it generates chapter summaries from audio. Connect it to a CDN and it handles global distribution.

    The video you are watching on the watch page was compressed, segmented, thumbnailed, uploaded, and presented by the same AI that orchestrated the music pipeline the video is about. That is the loop closing.

    Claude is not a video editor. Claude is whatever you connect it to.

  • I Let Claude Build a 20-Song Music Catalog in One Session — Here’s What Happened

    I Let Claude Build a 20-Song Music Catalog in One Session — Here’s What Happened

    The Lab · Tygart Media
    Experiment Nº 603 · Methodology Notes
    METHODS · OBSERVATIONS · RESULTS

    I wanted to test a question that’s been nagging me since I started building autonomous AI pipelines: how far can you push a creative workflow before the quality falls off a cliff?

    The answer, it turns out, is further than I expected — but the cliff is real, and knowing where it is matters more than the output itself.

    The Experiment: Zero Human Edits, 20 Songs, 19 Genres

    The setup was straightforward in concept and absurdly complex in execution. I gave Claude one instruction: generate original songs using Producer.ai, analyze each one with Gemini 2.0 Flash, create custom artwork with Imagen 4, build a listening page with a custom audio player, publish it to this site, update the music hub, log everything to Notion, and then loop back and do it again.

    The constraint that made it real: Claude had to honestly assess quality after every batch and stop when diminishing returns hit. No padding the catalog with filler. No claiming mediocre output was good. The stakes had to be real or the whole experiment was theater.

    Over the course of one extended session, the pipeline produced 20 original tracks spanning 19 distinct genres — from heavy metal to bossa nova, punk rock to Celtic folk, ambient electronic to gospel soul.

    How the Pipeline Actually Works

    Each song passes through a 7-stage autonomous pipeline with zero human intervention between stages:

    1. Prompt Engineering — Claude crafts a genre-specific prompt designed to push Producer.ai toward authentic instrumentation and songwriting conventions for that genre, not generic “make a song in X style” requests.
    2. Generation — Producer.ai generates the track. Claude navigates the interface via browser automation, waits for generation to complete, then extracts the audio URL from the page metadata.
    3. Audio Conversion — The raw m4a file is downloaded and converted to MP3 at 192kbps for the full version, plus a trimmed 90-second version at 128kbps for AI analysis.
    4. Gemini 2.0 Flash Analysis — The trimmed audio is sent to Google’s Gemini 2.0 Flash model via Vertex AI. Gemini listens to the actual audio and returns a structured analysis: song description, artwork prompt suggestion, narrative story, and thematic elements.
    5. Imagen 4 Artwork — Gemini’s artwork prompt feeds into Google’s Imagen 4 model, which generates a 1:1 album cover. Each cover is genre-matched — moody neon for synthwave, weathered wood textures for Appalachian folk, stained glass for gospel soul.
    6. WordPress Publishing — The MP3 and artwork upload to WordPress. Claude builds a complete listening page with a custom HTML/CSS/JS audio player, genre-specific accent colors, lyrics or composition notes, and the AI-generated story. The page publishes as a child of the music hub.
    7. Hub Update & Logging — The music hub grid gets a new card with the artwork, title, and genre badge. Everything logs to Notion for the operational record.

    The entire stack runs on Google Cloud — Vertex AI for Gemini and Imagen 4, authenticated via service account JWT tokens. WordPress sits on a GCP Compute Engine instance. The only external dependency is Producer.ai for the actual audio generation.

    The 20-Song Catalog

    You can listen to every track on the Tygart Media Music Hub. Here’s the full catalog with genre and a quick take on each:

    # Title Genre Assessment
    1 Anvil and Ember Blues Rock Strong opener — gritty, authentic tone
    2 Neon Cathedral Synthwave / Darkwave Atmospheric, genre-accurate production
    3 Velvet Frequency Trip-Hop Moody, textured, held together well
    4 Hollow Bones Appalachian Folk Top 3 — haunting, genuine folk storytelling
    5 Glass Lighthouse Dream Pop / Indie Pop Shimmery, the lightest track in the catalog
    6 Meridian Line Orchestral Hip-Hop Surprisingly cohesive genre fusion
    7 Salt and Ceremony Gospel Soul Warm, emotionally grounded
    8 Tide and Timber Roots Reggae Laid-back, authentic reggae rhythm
    9 Paper Lanterns Bossa Nova Gentle, genuine Brazilian feel
    10 Burnt Bridges, Better Views Punk Rock Top 3 — raw energy, real punk attitude
    11 Signal Drift Ambient Electronic Spacious instrumental, no lyrics needed
    12 Gravel and Grace Modern Country Solid modern Nashville sound
    13 Velvet Hours Neo-Soul R&B Vocal instrumental — texture over lyrics
    14 The Keeper’s Lantern Celtic Folk Top 3 — strong closer, unique sonic palette

    Plus 6 earlier experimental tracks (Iron Heart variations, Iron and Salt, The Velvet Pour, Rusted Pocketknife) that preceded the formal pipeline and are also on the hub.

    Where Quality Held Up — and Where It Didn’t

    The pipeline performed best on genres with strong structural conventions. Blues rock, punk, folk, country, and Celtic music all have well-defined instrumentation and songwriting patterns that Producer.ai could lock into. The AI wasn’t inventing a genre — it was executing within one, and the results were genuinely listenable.

    The weakest output came from genres that rely on subtlety and human nuance. The neo-soul track (Velvet Hours) ended up as a vocal instrumental — beautiful textures, but no real lyrical content. It felt more like a mood than a song. The synthwave track was competent but slightly generic — it hit every synth cliché without adding anything distinctive.

    The biggest surprise was Meridian Line (Orchestral Hip-Hop). Fusing a full orchestral arrangement with hip-hop production is hard for human producers. The AI pulled it off with more coherence than I expected.

    The Honest Assessment: Why I Stopped at 20

    After 14 songs in the formal pipeline (plus the 6 experimental tracks), I evaluated what genres remained untapped. The answer was ska, reggaeton, polka, zydeco — genres that would have been novelty picks, not genuine catalog additions. Each of the 19 genres I covered brought a distinctly different sonic palette, vocal style, and emotional register. Song 20 was the right place to stop because Song 21 would have been padding.

    This is the part that matters for anyone building autonomous creative systems: the quality curve isn’t linear. You don’t get steadily worse output. You get strong results across a wide range, and then you hit a wall where the remaining options are either redundant (too similar to something you already made) or contrived (genres you’re forcing because they’re different, not because they’re good).

    Knowing where that wall is — and having the system honestly report it — is the difference between a useful pipeline and a content mill.

    What This Means for AI-Driven Creative Work

    This experiment wasn’t about proving AI can replace musicians. It can’t. Every track in this catalog is a competent execution of genre conventions — but none of them have the idiosyncratic human choices that make music genuinely memorable. No AI song here will be someone’s favorite song.

    What the experiment does prove is that the full creative pipeline — from ideation through production, analysis, visual design, web publishing, and catalog management — can run autonomously at a quality level that’s functional and honest about its limitations.

    The tech stack that made this possible:

    • Claude — Pipeline orchestration, prompt engineering, quality assessment, web publishing, and the decision to stop
    • Producer.ai — Audio generation from text prompts
    • Gemini 2.0 Flash — Audio analysis (it actually listened to the MP3 and described what it heard)
    • Imagen 4 — Album artwork generation from Gemini’s descriptions
    • Google Cloud Vertex AI — API backbone for both Gemini and Imagen 4
    • WordPress REST API — Direct publishing with custom HTML listening pages
    • Notion API — Operational logging for every song

    Total cost for the entire 20-song catalog: a few dollars in Vertex AI API calls. Zero human edits to the published output.

    Listen for Yourself

    The full catalog is live on the Tygart Media Music Hub. Every track has its own listening page with a custom audio player, AI-generated artwork, the story behind the song, and lyrics (or composition notes for instrumentals). Pick a genre you like and judge for yourself whether the pipeline cleared the bar.

    The honest answer is: it cleared it more often than it didn’t. And knowing exactly where it didn’t is the most valuable part of the whole experiment.



  • The Human Knowledge Distillery: What Tygart Media Actually Is

    The Human Knowledge Distillery: What Tygart Media Actually Is

    The Lab · Tygart Media
    Experiment Nº 504 · Methodology Notes
    METHODS · OBSERVATIONS · RESULTS

    I’ve been building Tygart Media for a while now, and I’ve always struggled to explain what we actually do. Not because the work is complicated — it’s not. But because the thing we do doesn’t have a clean label yet.

    We’re not a content agency. We’re not a marketing firm. We’re not an SEO shop, even though SEO is part of what happens. Those are all descriptions of outputs, and they miss the thing underneath.

    The Moment It Clicked

    I was working with a client recently — a business owner who has spent 20 years building expertise in his industry. He knows things that nobody else knows. Not because he’s secretive, but because that knowledge lives in his head, in his gut, in the way he reads a situation and makes a call. It’s tacit knowledge. The kind you can’t Google.

    My job wasn’t to write blog posts for him. My job was to extract that knowledge, organize it, structure it, and put it into a format that could actually be used — by his team, by his customers, by AI systems, by anyone who needs it.

    That’s when I realized: Tygart Media is a human knowledge distillery.

    What a Knowledge Distillery Does

    Think about what a distillery actually does. You take raw material — grain, fruit, whatever — and you run it through a process that extracts the essence. You remove the noise. You concentrate what matters. And you put it in a form that can be stored, shared, and used.

    That’s exactly what we do with human expertise. Every business leader, every subject matter expert, every operator who has been doing this work for years — they are sitting on enormous reserves of knowledge that is trapped. It’s trapped in their heads, in their habits, in their decision-making patterns. It’s not written down. It’s not structured. It can’t be searched, referenced, or built upon by anyone else.

    We extract it. We distill it. We put it into structured formats — articles, knowledge bases, structured data, content architectures — that make it usable.

    The Media Is the Knowledge

    Here’s the shift that changed everything for me: the word “media” in Tygart Media doesn’t mean content. It means medium — as in, the thing through which knowledge travels.

    When we publish an article, we’re not creating content for content’s sake. We’re creating a vessel for knowledge that was previously locked inside someone’s brain. The article is just the delivery mechanism. The real product is the structured intelligence underneath it.

    Every WordPress post we publish, every schema block we inject, every entity we map — those are all expressions of distilled knowledge being put into circulation. The websites aren’t marketing channels. They’re knowledge infrastructure.

    Content as Data, Not Decoration

    Most agencies look at content and see marketing material. We look at content and see data. Every piece of content we create is structured, tagged, embedded, and connected to a larger knowledge graph. It’s not sitting in a silo waiting for someone to stumble across it — it’s part of a living system that AI can read, search engines can parse, and humans can navigate.

    When you start treating content as data and knowledge rather than decoration, everything changes. You stop asking “what should we blog about?” and start asking “what does this organization know that nobody else does, and how do we make that knowledge accessible to every system that could use it?”

    Where This Goes

    Right now, we run our own operations out of this distilled knowledge. We manage 27+ WordPress sites across wildly different industries — restoration, luxury lending, cold storage, comedy streaming, veterans services, and more. Every one of those sites is a node in a knowledge network that gets smarter with every engagement.

    But here’s where it gets interesting. The distilled knowledge we’re building — stripped of personal information, structured for machine consumption — could become an open API. A knowledge layer that anyone could plug into. Your AI assistant, your search tools, your internal systems — they could all connect to the Tygart Brain and immediately get smarter about the domains we’ve mapped.

    That’s not a fantasy. The infrastructure already exists. We already have the knowledge pages, the embeddings, the structured data. The question isn’t whether we can open it up — it’s when.

    Some people call this democratizing knowledge. I just call it doing the obvious thing. If you’ve spent the time to extract, distill, and structure expertise across dozens of industries, why would you keep it locked in a private database? The whole point of a distillery is that what comes out is meant to be shared.

    What This Means for You

    If you’re a business leader sitting on years of expertise that’s trapped in your head — that’s the raw material. We can extract it, distill it, and turn it into a knowledge asset that works for you around the clock.

    If you’re someone who wants to build AI-powered tools or systems — eventually, you’ll be able to plug into a growing, curated knowledge network that’s been distilled from real human expertise. Not scraped. Not summarized. Distilled.

    Tygart Media isn’t a content agency that figured out AI. It’s a knowledge distillery that happens to express itself as content. That distinction matters, and I think it’s going to matter a lot more very soon.


    Frequently Asked Questions: What Tygart Media Does

    What exactly is Tygart Media and how is it different from a content agency?

    Tygart Media is a human knowledge distillery — not a content agency, marketing firm, or SEO shop. The distinction is what we’re working with: most agencies produce content from briefs. We extract tacit knowledge from business owners and subject matter experts, then structure that knowledge into formats that can be searched, referenced, built upon, and understood by both humans and AI systems. The content is a byproduct of the knowledge architecture, not the goal itself.

    What is tacit knowledge and why does it need to be distilled?

    Tacit knowledge is the expertise that lives in a person’s head, gut, and decision-making instincts — built over years of doing the work. It can’t be Googled because it’s never been written down. Most businesses are sitting on enormous reserves of this knowledge that is completely trapped: inaccessible to their teams, invisible to customers, and unreadable by AI systems. Distillation means extracting that expertise, organizing it, and putting it into structured formats that can actually be used.

    What does “AI-native” mean in the context of Tygart Media’s approach?

    AI-native means the content and knowledge architecture is designed from the start to be readable and citable by AI systems — not just search engines. This includes structured data markup, entity saturation, answer-optimized formatting, and content that AI models like Claude, ChatGPT, and Gemini can retrieve and reference when answering questions in their domain. An AI-native knowledge base works for human readers and AI readers simultaneously.

    Who is Tygart Media built for?

    Business owners and operators who have deep domain expertise and want it working harder for them. Typically: service businesses with complex offerings, founders who are the primary knowledge holders in their company, and operators in specialized industries (restoration, lending, healthcare, B2B services) where the expertise gap between the business and its customers is large. If you have 10+ years of experience that isn’t structured anywhere, you’re the target.

    What does a Tygart Media engagement actually produce?

    The outputs vary by engagement but typically include: a structured content architecture (categories, clusters, internal linking), long-form articles that capture and communicate domain expertise, AEO/GEO-optimized content designed for AI citation, schema markup for rich search results, and in some cases a full Notion-based knowledge base that functions as a second brain for the business. The goal is a knowledge system that compounds — not a content calendar that resets every month.