# comparison-pages-content Full Instructions

## Annual Year Update

Each year, update comparison pages for the new calendar year. **Update to new year:**

- **Hero H1:** `Vergleich & Bewertung 20XX` (marketing/SEO copy)
- **FAQ section titles:** `Alternativen 20XX` (e.g. "Häufige Fragen zu {name} & {category} Alternativen 20XX")
- **Schema datePublished fallbacks:** `ordio_get_page_published_iso('20XX-01-01T00:00:00+01:00')` for generic fallbacks
- **competitor_template_data.php:** default FAQ title "Alternativen 20XX"
- **Meta/OG/Twitter titles:** "Vergleich & Bewertung 20XX" and "Alternativen 20XX" where used

**Preserve (do NOT change):**

- **Notice note:** "Stand: [Month] 20XX" – indicates when OMR comparison data was last verified (e.g. "Stand: Oktober 2025", "Stand: November 2025")

**Files:** `v2/data/competitor_template_data.php`, all `v2/pages/compare_*.php`. Use bulk search/replace; verify Stand lines are excluded.

## Edge Cases & Gotchas

### Competitor Name Variations

Some competitors have complex names or capitalization:

- Use official capitalization in visible text (e.g., "planday" vs "Planday")
- Use lowercase-hyphenated in URLs and file names (e.g., `compare_planday.php`)
- Check competitor's official website for correct spelling

### Missing Competitor Data

If competitor data unavailable:

- Focus on Ordio's strengths without direct comparison
- Use "Viele Alternativen..." patterns instead of direct claims
- Avoid empty table cells; rephrase to show Ordio's features

### Outdated Competitor Info

- Review competitor website/pricing page before updating
- Note date of last verification in internal comment (optional)
- When in doubt, use "ab €X/Monat" (starting at) instead of exact pricing

### Multi-Competitor Pages

Some pages compare Ordio to multiple competitors (e.g., overview pages):

- Follow same patterns for each competitor
- Ensure hero logo section handles multiple logos cleanly
- Table schema may reference multiple competitors

---

## Complete Page Structure

### Required Sections (in order):

1. **Head Section**

   - Meta tags (title, description, keywords)
   - Canonical URL
   - Open Graph tags
   - Twitter Card tags
   - CSS includes (comparison-pages.css)
   - Image preload (competitor logo)
   - Schema JSON-LD

2. **Header**

   - Include via `../base/header.php`

3. **Hero Section**

   - Competitor name and description
   - Competitor logo image
   - CTA buttons

4. **Company Logos Section**

   - Scrolling logo carousel

5. **Comparison Section**

   - Section header ("Vergleich" badge, heading)
   - Comparison grid (Ordio | Competitor cards)

6. **Ordio Verteiler Section**

   - Feature cards (4 cards desktop, mobile carousel)
   - Testimonial

7. **In bester Gesellschaft Section**

   - Customer stories (3 cards)
   - CTA buttons

8. **Comparison Carousel**

   - Other comparison pages

9. **FAQs Section**

   - Competitor-specific questions/answers

10. **Footer**

    - Include via `../base/footer.php`

11. **Lead Capture Popup**
    - Include via `../components/lead-capture-popup.php`

## Competitors Data Structure

### Data File Location

**File:** `v2/data/competitors_data.php`  
**Function:** `getAllCompetitorsData()` returns array of competitor data

### Required Fields Per Competitor

```php
'{slug}' => [
    'slug' => '{slug}',
    'name' => '{Name}',
    'rating' => '{rating}',        // Real value, not placeholder
    'reviews' => '{count}',        // Real count, not placeholder
    'description' => '{...}',      // Min 200 words, competitor-specific
    'category' => '{Category}',
    'focus' => '{Focus}',
    'target' => '{Target}',
    'logo_alt' => '{Alt}',
    'logo_class' => '',
    'pricing' => [
        'starting_price' => '{price}',  // Keep for backward compatibility
        'price_unit' => '{unit}',       // Fallback if no plans
        'currency' => '{EUR|USD}',
        'plans' => [                     // Optional: array of pricing plans
            [
                'name' => '{Plan Name}',                    // Required: e.g., 'Starter', 'Basic', 'Professional'
                'description' => '{Description}',            // Optional: plan description
                'price' => '{price}',                       // Required: numeric string (e.g., '89.00') or text ('Auf Anfrage', 'Kostenlos')
                'price_text' => '{Formatted Price}',        // Optional: formatted display text (e.g., '€89,00')
                'frequency' => '{Frequency}',               // Optional: e.g., '/ User / Monat', '/ Standort / Monat'
                'recommendation' => '{Recommendation}',     // Optional: e.g., 'Empfohlen für 1-5 User'
            ],
            // ... more plans
        ],
    ],
    'faq' => [                     // Min 6 items
        ['question' => '...', 'answer' => '...'],
        // ...
    ],
    'rating_distribution' => [     // Must sum to 100%
        '5' => ['percentage' => X, 'count' => Y],
        // ...
    ],
    'schema' => [
        'name' => '{Name}',
        'description' => '{...}',
        'url' => '{slug}-vergleich',
    ],
    'has_details' => true|false,
    'details' => [ // Only if has_details is true
        'sections' => [
            [
                'title' => '{Section Title}',
                'type' => 'list'|'paragraph'|'mixed',
                'items' => ['Item 1', 'Item 2'], // for list type
                'content' => '{Paragraph content}', // for paragraph type
                'items_with_descriptions' => [ // for mixed type
                    [
                        'title' => '{Item Title}',
                        'description' => '{Item Description}',
                    ],
                ],
            ],
        ],
    ],
]
```

### Data Quality Standards

**Never Use Placeholders:**

- ❌ Rating: '4.9' (placeholder)
- ❌ Reviews: '54' (placeholder)
- ❌ Pricing: '89 EUR' (Ordio's price, not competitor's)

**Always Use Real Data:**

- ✅ Extract from comparison page schema.org JSON-LD
- ✅ Research from OMR Reviews or competitor websites
- ✅ Use actual competitor pricing, not Ordio's

**Validation Requirements:**

- Rating distributions must sum to exactly 100%
- Minimum 6 FAQ items per competitor
- Descriptions minimum 200 words
- All required fields must be present

### Data Extraction & Updates

**Extract Data:**

```bash
python3 scripts/data/extract_competitor_data.py
```

**Validate Extracted Data:**

```bash
python3 scripts/data/validate_extracted_data.py
php scripts/data/validate_and_compare.php
```

**Update Data File:**

```bash
# Automated update (creates backup automatically)
php scripts/data/update_competitors_data.php

# Manual update may be required for some entries
```

**Validation Requirements:**

- Rating distribution counts must sum to total reviews
- Rating percentages must sum to ~100% (allow 95-105% range)
- All required fields present (rating, reviews, description, pricing)
- Descriptions must be full text, not placeholders
- Details sections must have correct structure (if `has_details` is true)
- PHP syntax must be valid after updates

### Common Issues

1. **Placeholder Values:** Replace '4.9' ratings, '54' reviews, '89 EUR' pricing with real values
2. **Rating Distribution:** Ensure percentages sum to 100% (not 98% or 94%)
3. **Missing FAQ:** Ensure all competitors have minimum 6 FAQ items
4. **Short Descriptions:** Expand descriptions to minimum 200 words
5. **Schema URLs:** Ensure schema URLs match slug pattern (`{slug}-vergleich`)
6. **Details Sections:** Verify `has_details` flag matches actual page content
7. **Details Structure:** Ensure Details sections use correct structure (sections array with title, type, content)
8. **String Escaping:** Properly escape single quotes, backslashes, and newlines in PHP strings
9. **Double Commas:** Watch for syntax errors from double commas (`,,`) in arrays
10. **Pricing Extraction:** Some pages may show `0.00` if pricing not clearly displayed - verify manually
11. **Pricing Plans Structure:** Ensure plans array has required fields (name, price). Validate price format (numeric or known text values like "Auf Anfrage", "Kostenlos")
12. **Pricing Plans Migration:** Use `migrate_pricing_plans.php` to migrate from simple pricing to multi-plan structure

### Data Migration Workflow

When migrating competitor data:

1. **Extract:** Run `extract_competitor_data.py` to extract all data from old pages
2. **Validate:** Run validation scripts to check data quality
3. **Compare:** Run `validate_and_compare.php` to identify discrepancies
4. **Update:** Use `update_competitors_data.php` or manual updates
5. **Verify:** Re-run comparison to confirm updates
6. **Test:** Visual verification in browser

See `docs/guides/DATA_MIGRATION_GUIDE.md` for detailed migration process.

## Component Dependencies

### hero.php (New Template)

- **Location:** `v2/components/comparison/hero.php`
- **Data Source:** `$competitor` array (name, category, focus), `$generator` (ComparisonPageGenerator)
- **Usage:** `<?php $generator = $pageGenerator; include __DIR__ . '/../components/comparison/hero.php'; ?>`
- **Features:**
  - Auto-generates H1: `{Competitor} Alternativen: Vergleich & Bewertung 2026`
  - Competitor-specific description
  - Ordio Schichtplanung illustration (SVG)
  - CTA buttons
  - Responsive design
  - Fallback values for missing data
- **Image:** `/v2/img/svg/comparison/hero-schichtplanung-card.svg` (214x262px, `fetchpriority="high"`)

### ordio_comparison_content.php

- **Location:** `v2/components/ordio_comparison_content.php`
- **Data Source:** `v2/data/ordio_comparison_data.php`
- **Usage:** `<?php include '../components/ordio_comparison_content.php'; ?>`
- **Features:** Product description, expandable details, features list

### compare_carousel.php

- **Location:** `v2/base/compare_carousel.php` (legacy) or `v2/components/comparison/compare_carousel.php` (new)
- **Data Source:** `v2/data/tools_data.php`
- **Usage:** `<?php include '../base/compare_carousel.php'; ?>` (legacy) or `<?php include __DIR__ . '/../components/comparison/compare_carousel.php'; ?>` (new)
- **Features:** Auto-rotates every 6s, filters current competitor, responsive (4/2/1 cards)

### Data Files

- **tools_data.php:** Competitor list for carousel (name, slug, description, logo, tags)
- **ordio_comparison_data.php:** Ordio content (description, features, pricing, target audience)

## Alpine.js Patterns

### Height Synchronization

```php
<div class="comparison-grid" x-data="{ ordioDetailsHeight: 0 }" @height-changed="ordioDetailsHeight = $event.detail.height">
```

### Expandable Details

```php
<div x-data="{ open: false }" x-init="
    $nextTick(() => { $dispatch('height-changed', { height: $el.offsetHeight }); });
    $watch('open', () => {
        $nextTick(() => {
            setTimeout(() => { $dispatch('height-changed', { height: $el.offsetHeight }); }, 350);
        });
    });
">
```

## Image Generation Workflow

1. **Add source images:**

   - `{competitor}-logo.webp` (160x160px square)
   - `{competitor}-vergleich-logo.webp` (320x64px, ~5:1 aspect ratio)

2. **Generate variants:**

   ```bash
   node scripts/generate_responsive_logos.js
   ```

3. **Verify variants created:**
   - Regular logos: 64w, 80w, 128w, 160w
   - Vergleich logos: 160w, 320w

## Reference Documentation

For detailed step-by-step workflows:

- `docs/guides/comparison-pages/COMPARISON_PAGES_GUIDE.md` – Complete creation workflow, image generation, testing
- `docs/guides/comparison-pages/COMPARISON_PAGES_STRUCTURE.md` – Complete structure breakdown
- `docs/guides/comparison-pages/COMPARISON_PAGES_QUICK_REFERENCE.md` – Copy-paste snippets and templates
- `docs/guides/comparison-pages/COMPARISON_PAGES_MIGRATION.md` – Migration guide for old design pages
- `docs/ai/cursor-playbook.md` – Cursor-specific prompting patterns

For similar page types:

- Product pages (product-pages.mdc) – Similar schema/CTA patterns
- Industry pages (industry-pages.mdc) – Similar audience-specific messaging

## Text-HTML Ratio Optimization

### Performance Targets

- **Text-HTML Ratio:** Target >25% (Semrush methodology)
- **HTML Size Reduction:** Target 30-40% reduction
- **Performance:** Maintain LCP <2.5s, CLS <0.1
- **JavaScript:** All inline scripts externalized and minified

### Optimization Best Practices

**JavaScript Externalization:**

- All inline scripts moved to `/v2/js/comparison-pages.js`
- Scripts minified to `/v2/js/comparison-pages.min.js`
- Use `defer` attribute for non-critical scripts
- Reference: `<script src="/v2/js/comparison-pages.min.js?v=<?php echo filemtime(__DIR__ . '/../js/comparison-pages.min.js'); ?>" defer></script>`

**SVG Optimization:**

- Large illustration SVGs (>10KB) should be externalized to `/v2/img/svg/`
- Repeated icons (stars, arrows) use sprite sheet `/v2/img/svg/star-icons.svg`
- Small interactive SVGs can remain inline but should be optimized
- Use `<img>` tags for static SVGs: `<img src="/v2/img/svg/icon.svg" alt="..." loading="lazy">`

**Resource Hints:**

- Add preconnect for external fonts and analytics
- Use dns-prefetch for third-party domains
- Preload LCP images with `fetchpriority="high"`

**Content Enhancement:**

- Hero descriptions: Minimum 2 sentences, expand with context
- Product descriptions: Include target audience and use cases
- FAQ sections: Minimum 5-7 detailed questions with comprehensive answers
- Comparison tables: Add descriptive text above/below tables

**HTML Structure:**

- Use semantic HTML5 elements (`<section>`, `<article>`, `<aside>`) where appropriate
- Reduce unnecessary wrapper divs
- Consolidate CSS classes to reduce HTML size
- Remove empty or unnecessary elements

**Schema Optimization:**

- Keep schema valid and complete
- Remove redundant fields
- Use `@graph` structure for multiple schema types
- Ensure all URLs are absolute and correct

### Optimization Checklist

When creating or updating comparison pages:

- [ ] All inline scripts externalized to `/v2/js/comparison-pages.min.js`
- [ ] Large SVGs (>10KB) externalized to `/v2/img/svg/`
- [ ] Resource hints added (preconnect, dns-prefetch)
- [ ] Hero description expanded (minimum 2 sentences)
- [ ] Product description includes target audience and use cases
- [ ] FAQ section has minimum 5-7 detailed questions
- [ ] Schema markup optimized and validated
- [ ] Text-HTML ratio measured and >25%
- [ ] Performance tested (LCP <2.5s, CLS <0.1)

## Related Documentation

See [docs/ai/RULE_TO_DOC_MAPPING.md](../../docs/ai/RULE_TO_DOC_MAPPING.md) for complete mapping.
