// Cover generator — tier-specific + comparison
// Theme system: CSS variables + per-component visibility flags

const { useState, useEffect, useRef, useMemo } = React;

const PLATFORMS = {
  upwork:  { w: 1200, h: 900,  label: 'Upwork',  ratio: '4:3' },
  fiverr:  { w: 1280, h: 769,  label: 'Fiverr',  ratio: '16:9' },
  square:  { w: 1080, h: 1080, label: 'Square',  ratio: '1:1' },
};

const MIN_TIERS = 1;
const MAX_TIERS = 6;
const DEFAULT_TIER_COUNT = 3;
const TIER_KEYS = ['starter', 'standard', 'advanced', 'tier4', 'tier5', 'tier6'];

const PRICE_TAG_ICONS = [
  { id: 'none', name: 'None', glyph: '' },
  { id: 'tag', name: 'Tag', glyph: '◆' },
  { id: 'star', name: 'Star', glyph: '★' },
  { id: 'spark', name: 'Spark', glyph: '✦' },
  { id: 'bolt', name: 'Bolt', glyph: '↯' },
  { id: 'check', name: 'Check', glyph: '✓' },
  { id: 'dot', name: 'Dot', glyph: '●' },
  { id: 'diamond', name: 'Diamond', glyph: '◇' },
  { id: 'crown', name: 'Crown', glyph: '♛' },
];

const DESCRIPTION_POSITION_OPTIONS = [
  { id: 'auto', name: 'Style default' },
  { id: 'up', name: 'Higher' },
  { id: 'down', name: 'Lower' },
  { id: 'left', name: 'Left' },
  { id: 'right', name: 'Right' },
];

const DESCRIPTION_OFFSETS = {
  auto: { x: '0px', y: '0px', flowY: '0px' },
  up: { x: '0px', y: '-30px', flowY: '-18px' },
  down: { x: '0px', y: '30px', flowY: '18px' },
  left: { x: '-36px', y: '0px', flowY: '0px' },
  right: { x: '36px', y: '0px', flowY: '0px' },
};

const LAYOUT_OPTIONS = [
  { id: 'auto', name: 'Style default' },
  { id: 'compact', name: 'Compact' },
  { id: 'spacious', name: 'Spacious' },
  { id: 'stacked', name: 'Stacked' },
  { id: 'wide', name: 'Wide' },
];

const THEME_PRESETS = {
  terminal: [
    { id: 'matrix',  name: 'Matrix',  bg: '#0a0a0c', text: '#e8e8e3', muted: '#8a8a92', accent: '#7CFFB2', accent2: '#5B8DEF' },
    { id: 'amber',   name: 'Amber',   bg: '#0c0a05', text: '#f5e9c8', muted: '#9a8a6a', accent: '#FFB347', accent2: '#FF6B35' },
    { id: 'cyber',   name: 'Cyber',   bg: '#0a0014', text: '#f0e8ff', muted: '#8a7aa8', accent: '#FF3DC8', accent2: '#5DEFFF' },
    { id: 'mint',    name: 'Mint',    bg: '#06120e', text: '#e0f5ec', muted: '#7aa090', accent: '#5DEFC8', accent2: '#5B8DEF' },
    { id: 'crimson', name: 'Crimson', bg: '#0e0608', text: '#f5e0e0', muted: '#9a7080', accent: '#FF3366', accent2: '#FFB347' },
    { id: 'ocean',   name: 'Ocean',   bg: '#04101a', text: '#dceaf5', muted: '#6a8aa0', accent: '#3DD9FF', accent2: '#7CFFB2' },
    { id: 'mocha',   name: 'Mocha',   bg: '#1a1410', text: '#ebe0d2', muted: '#a89280', accent: '#D4A574', accent2: '#9CC4A8' },
  ],
  editorial: [
    { id: 'cream',   name: 'Cream',   bg: '#f5f5f0', text: '#0a0a0c', muted: '#6a6a62', accent: '#FFE600', accent2: '#FF6B35' },
    { id: 'paper',   name: 'Paper',   bg: '#faf8f3', text: '#1a1a1a', muted: '#7a7a72', accent: '#3340FF', accent2: '#FF3366' },
    { id: 'sage',    name: 'Sage',    bg: '#e8ebe2', text: '#1a2418', muted: '#5a6852', accent: '#2C5530', accent2: '#FFB347' },
    { id: 'rose',    name: 'Rose',    bg: '#f4e8e4', text: '#2a1410', muted: '#8a6862', accent: '#C73E3A', accent2: '#3340FF' },
    { id: 'noir',    name: 'Noir',    bg: '#1a1a1a', text: '#f0eee8', muted: '#8a8880', accent: '#FFE600', accent2: '#FF3366' },
    { id: 'bone',    name: 'Bone',    bg: '#ede6d8', text: '#2a1a14', muted: '#7a6a5c', accent: '#8B4513', accent2: '#2C5530' },
    { id: 'sky',     name: 'Sky',     bg: '#e4eef5', text: '#0a1a2a', muted: '#5a7088', accent: '#1A4D8F', accent2: '#FF6B35' },
  ],
  brutalist: [
    { id: 'caution', name: 'Caution', bg: '#FFE600', text: '#0a0a0c', muted: '#3a3a30', accent: '#FF3366', accent2: '#0a0a0c' },
    { id: 'risk',    name: 'Risk',    bg: '#FF6B35', text: '#0a0a0c', muted: '#3a1a10', accent: '#FFE600', accent2: '#0a0a0c' },
    { id: 'pop',     name: 'Pop',     bg: '#5DEFFF', text: '#0a0a0c', muted: '#1a3a40', accent: '#FF3DC8', accent2: '#0a0a0c' },
    { id: 'mono',    name: 'Mono',    bg: '#e8e8e3', text: '#0a0a0c', muted: '#6a6a62', accent: '#0a0a0c', accent2: '#FF3366' },
    { id: 'lime',    name: 'Lime',    bg: '#C6FF3D', text: '#0a0a0c', muted: '#2a3a10', accent: '#FF3366', accent2: '#0a0a0c' },
    { id: 'klein',   name: 'Klein',   bg: '#1A1AFF', text: '#FFFFFF', muted: '#9a9aff', accent: '#FFE600', accent2: '#FFFFFF' },
    { id: 'blood',   name: 'Blood',   bg: '#0a0a0c', text: '#FFE600', muted: '#6a6a30', accent: '#FF3366', accent2: '#FFE600' },
  ],
  sticker: [
    { id: 'bubble',  name: 'Bubble',  bg: '#FFE9F0', text: '#2A0A1A', muted: '#A07080', accent: '#FF4D8F', accent2: '#5DEFFF' },
    { id: 'candy',   name: 'Candy',   bg: '#E8F4FF', text: '#0A1F4A', muted: '#7090B8', accent: '#FF8800', accent2: '#3DD9FF' },
    { id: 'punch',   name: 'Punch',   bg: '#FFF2D6', text: '#3A1A05', muted: '#A07050', accent: '#FF3DC8', accent2: '#5B8DEF' },
    { id: 'fresh',   name: 'Fresh',   bg: '#E0FFE8', text: '#0A2A14', muted: '#608070', accent: '#22BB55', accent2: '#FF6B35' },
    { id: 'arcade',  name: 'Arcade',  bg: '#1A0A2E', text: '#FFE9F0', muted: '#9080A8', accent: '#FF3DC8', accent2: '#5DEFFF' },
    { id: 'bubblegum',name:'Bubblegum',bg:'#FFC2D8', text: '#2A0A1A', muted: '#806070', accent: '#3340FF', accent2: '#FFE600' },
    { id: 'cream2',  name: 'Vanilla', bg: '#FFF8E8', text: '#2A1A05', muted: '#9A8A6A', accent: '#FF6B35', accent2: '#5B8DEF' },
  ],
  blueprint: [
    { id: 'cyan',    name: 'Cyan',    bg: '#0A2A4A', text: '#E0F0FF', muted: '#7090B8', accent: '#FFE600', accent2: '#5DEFFF' },
    { id: 'paper2',  name: 'Vellum',  bg: '#F0EAD8', text: '#1A2438', muted: '#7080A0', accent: '#1A4D8F', accent2: '#C73E3A' },
    { id: 'graphite',name: 'Graphite',bg: '#1A1A24', text: '#E0E4F0', muted: '#7080A0', accent: '#5DEFFF', accent2: '#FFB347' },
    { id: 'navy',    name: 'Navy',    bg: '#0A1A3A', text: '#E0E8FF', muted: '#6080A8', accent: '#FF8800', accent2: '#5DEFFF' },
    { id: 'mint2',   name: 'Sage',    bg: '#D8E8DE', text: '#0A2418', muted: '#608070', accent: '#1A4D8F', accent2: '#C73E3A' },
    { id: 'rust',    name: 'Rust',    bg: '#2A1810', text: '#F0E0CC', muted: '#A08070', accent: '#FFB347', accent2: '#5DEFFF' },
    { id: 'arctic',  name: 'Arctic',  bg: '#E8F4F8', text: '#0A2438', muted: '#608090', accent: '#1A4D8F', accent2: '#C73E3A' },
  ],
  magazine: [
    { id: 'classic', name: 'Classic', bg: '#F0EAD8', text: '#1A1410', muted: '#8a7868', accent: '#C73E3A', accent2: '#1A2438' },
    { id: 'vogue',   name: 'Vogue',   bg: '#FFFFFF', text: '#0a0a0c', muted: '#888880', accent: '#0a0a0c', accent2: '#C73E3A' },
    { id: 'velvet',  name: 'Velvet',  bg: '#1A0A14', text: '#F0E8D8', muted: '#A08070', accent: '#D4A574', accent2: '#C73E3A' },
    { id: 'salmon',  name: 'Salmon',  bg: '#FFE0D2', text: '#2A1410', muted: '#A07060', accent: '#1A2438', accent2: '#C73E3A' },
    { id: 'forest',  name: 'Forest',  bg: '#E8E4D8', text: '#0A1A14', muted: '#607060', accent: '#2C5530', accent2: '#C73E3A' },
    { id: 'midnight',name: 'Midnight',bg: '#0A0A14', text: '#E8E4D8', muted: '#807868', accent: '#D4A574', accent2: '#FFE600' },
    { id: 'porcelain',name:'Porcelain',bg:'#FAF8F3', text: '#1A1410', muted: '#9a8878', accent: '#1A2438', accent2: '#C73E3A' },
  ],
};

const FONT_OPTIONS = {
  display: [
    { id: 'space-grotesk', name: 'Space Grotesk', stack: "'Space Grotesk', sans-serif" },
    { id: 'bricolage',     name: 'Bricolage Grotesque', stack: "'Bricolage Grotesque', sans-serif" },
    { id: 'sora',          name: 'Sora', stack: "'Sora', sans-serif" },
    { id: 'fraunces',      name: 'Fraunces', stack: "'Fraunces', Georgia, serif" },
    { id: 'playfair',      name: 'Playfair Display', stack: "'Playfair Display', Georgia, serif" },
    { id: 'instrument',    name: 'Instrument Serif', stack: "'Instrument Serif', Georgia, serif" },
    { id: 'libre-baskerville', name: 'Libre Baskerville', stack: "'Libre Baskerville', Georgia, serif" },
    { id: 'archivo',       name: 'Archivo Black', stack: "'Archivo Black', sans-serif" },
    { id: 'bebas',         name: 'Bebas Neue', stack: "'Bebas Neue', sans-serif" },
    { id: 'oswald',        name: 'Oswald', stack: "'Oswald', sans-serif" },
    { id: 'manrope',       name: 'Manrope', stack: "'Manrope', sans-serif" },
    { id: 'inter',         name: 'Inter', stack: "'Inter', sans-serif" },
  ],
  body: [
    { id: 'inter',         name: 'Inter', stack: "'Inter', sans-serif" },
    { id: 'dm-sans',       name: 'DM Sans', stack: "'DM Sans', sans-serif" },
    { id: 'manrope',       name: 'Manrope', stack: "'Manrope', sans-serif" },
    { id: 'sora',          name: 'Sora', stack: "'Sora', sans-serif" },
    { id: 'space-grotesk', name: 'Space Grotesk', stack: "'Space Grotesk', sans-serif" },
    { id: 'bricolage',     name: 'Bricolage Grotesque', stack: "'Bricolage Grotesque', sans-serif" },
    { id: 'ibm-plex',      name: 'IBM Plex Sans', stack: "'IBM Plex Sans', sans-serif" },
    { id: 'fraunces',      name: 'Fraunces', stack: "'Fraunces', Georgia, serif" },
    { id: 'ibm-plex-serif', name: 'IBM Plex Serif', stack: "'IBM Plex Serif', Georgia, serif" },
    { id: 'libre-baskerville', name: 'Libre Baskerville', stack: "'Libre Baskerville', Georgia, serif" },
  ],
  mono: [
    { id: 'jetbrains',     name: 'JetBrains Mono', stack: "'JetBrains Mono', monospace" },
    { id: 'roboto-mono',   name: 'Roboto Mono', stack: "'Roboto Mono', monospace" },
    { id: 'ibm-plex-mono', name: 'IBM Plex Mono', stack: "'IBM Plex Mono', monospace" },
  ],
};

const COMPONENT_KEYS = [
  { id: 'chrome',     label: 'Window chrome / tape' },
  { id: 'tierNumber', label: 'Tier number' },
  { id: 'tierStamp',  label: 'Tier stamp / label' },
  { id: 'description',label: 'Description text' },
  { id: 'days',       label: 'Delivery days' },
  { id: 'revisions',  label: 'Revisions count' },
  { id: 'features',   label: 'Feature checklist' },
  { id: 'price',      label: 'Price' },
  { id: 'brand',      label: 'Brand name' },
  { id: 'tagline',    label: 'Tagline' },
  { id: 'cursor',     label: 'Blinking cursor (terminal)' },
  { id: 'grid',       label: 'Background grid / noise' },
];

// Per-style visible components — only show what's actually on that cover.
// Each entry: id (matches CSS hide-* hook) + label specific to the style's vocabulary.
const STYLE_COMPONENTS = {
  terminal: [
    { id: 'chrome',      label: 'Terminal chrome (dots + path)' },
    { id: 'tierNumber',  label: '[01/N] tier number' },
    { id: 'tierStamp',   label: 'tier --package stamp' },
    { id: 'description', label: 'Comment block (// description)' },
    { id: 'days',        label: 'Delivery days metric' },
    { id: 'revisions',   label: 'Revisions metric' },
    { id: 'features',    label: 'Feature checklist (✓ lines)' },
    { id: 'price',       label: 'Price line ($echo)' },
    { id: 'brand',       label: 'Brand name' },
    { id: 'tagline',     label: 'Tagline (// comment)' },
    { id: 'cursor',      label: 'Blinking cursor ▮' },
    { id: 'grid',        label: 'Scanline overlay' },
  ],
  editorial: [
    { id: 'chrome',      label: 'Header rule + masthead' },
    { id: 'tierNumber',  label: '№ tier number meta' },
    { id: 'tierStamp',   label: 'Tier stamp meta' },
    { id: 'description', label: 'Lede paragraph' },
    { id: 'days',        label: 'Delivery days stat' },
    { id: 'revisions',   label: 'Revisions stat' },
    { id: 'features',    label: 'Feature list (numbered)' },
    { id: 'price',       label: 'Price block' },
    { id: 'brand',       label: 'Masthead brand' },
    { id: 'tagline',     label: 'Footer tagline' },
    { id: 'grid',        label: 'Light grid background' },
  ],
  brutalist: [
    { id: 'chrome',      label: 'Tape banner (top)' },
    { id: 'tierNumber',  label: 'Stamp number' },
    { id: 'tierStamp',   label: 'PACKAGE stamp label' },
    { id: 'description', label: 'Description block' },
    { id: 'days',        label: 'Days slab' },
    { id: 'revisions',   label: 'Revisions slab' },
    { id: 'features',    label: 'Feature pills' },
    { id: 'price',       label: 'Big price' },
    { id: 'brand',       label: 'Brand stamp' },
    { id: 'tagline',     label: 'Tagline strip' },
    { id: 'grid',        label: 'Halftone / noise' },
  ],
  sticker: [
    { id: 'tierNumber',  label: 'Tier number blob' },
    { id: 'tierStamp',   label: 'Tier pill (top)' },
    { id: 'description', label: 'Description bubble' },
    { id: 'days',        label: 'Days sticker' },
    { id: 'revisions',   label: 'Revisions sticker' },
    { id: 'features',    label: 'Feature stickers' },
    { id: 'price',       label: 'Price burst' },
    { id: 'brand',       label: 'Brand badge' },
    { id: 'tagline',     label: 'Tagline ribbon' },
    { id: 'grid',        label: 'Polka / pop background' },
  ],
  blueprint: [
    { id: 'chrome',      label: 'Title block (top bar)' },
    { id: 'tierNumber',  label: 'SPEC.0X marker' },
    { id: 'tierStamp',   label: 'CLASS label' },
    { id: 'description', label: 'Notes paragraph' },
    { id: 'days',        label: '∇ DELIV. cell' },
    { id: 'revisions',   label: '↻ REVISIONS cell' },
    { id: 'features',    label: 'Spec list' },
    { id: 'price',       label: 'Price cell' },
    { id: 'brand',       label: 'DRAWING brand' },
    { id: 'tagline',     label: 'Footer note' },
    { id: 'grid',        label: 'Drafting grid' },
  ],
  magazine: [
    { id: 'chrome',      label: 'Masthead bar' },
    { id: 'tierNumber',  label: 'ISSUE №0X marker' },
    { id: 'tierStamp',   label: 'Volume label' },
    { id: 'description', label: 'Pull quote / lede' },
    { id: 'days',        label: 'Days stat' },
    { id: 'revisions',   label: 'Revisions stat' },
    { id: 'features',    label: 'Feature list' },
    { id: 'price',       label: 'Cover price' },
    { id: 'brand',       label: 'Masthead brand' },
    { id: 'tagline',     label: 'Byline / tagline' },
    { id: 'grid',        label: 'Paper grain' },
  ],
};

const DEFAULTS = /*EDITMODE-BEGIN*/{
  "brand": "SEMKIV/LABS",
  "tagline": "",
  "platform": "fiverr",
  "style": "terminal",
  "previewScale": 0.92,
  "tierCount": 3,
  "focusTier": "advanced",
  "launchPricing": false,
  "theme": {
    "bg": "#0a0a0c",
    "text": "#e8e8e3",
    "muted": "#8a8a92",
    "accent": "#7CFFB2",
    "accent2": "#5B8DEF",
    "patternColor": "#7CFFB2",
    "patternColor2": "#5B8DEF",
    "displayFont": "'Space Grotesk', sans-serif",
    "bodyFont": "'Inter', sans-serif",
    "monoFont": "'JetBrains Mono', monospace",
    "fontScale": 1,
    "background": "auto",
    "descriptionPosition": "auto",
    "layout": "auto",
    "show": {
      "chrome": true, "tierNumber": true, "tierStamp": true, "description": true,
      "days": true, "revisions": true, "features": true, "price": true,
      "brand": true, "tagline": true, "cursor": true, "grid": true
    }
  },
  "tiers": {
    "starter":  { "num": "01", "label": "Starter",  "showTierNumber": true, "showTierStamp": true, "showPriceTag": true, "priceTag": "Quick audit",  "priceTagIcon": "tag", "title": "App Audit & Quick Fix",       "desc": "Audit app, fix 1-2 issues, and give a clear action plan.", "days": 3,  "revisions": 1, "price": 250,  "launchPrice": 199,  "features": { "bug": true, "docs": false, "comments": false } },
    "standard": { "num": "02", "label": "Standard", "showTierNumber": true, "showTierStamp": true, "showPriceTag": true, "priceTag": "Best value",   "priceTagIcon": "tag", "title": "Deploy & Core Fixes",         "desc": "Deploy app, set env/database, and fix core launch issues.", "days": 7,  "revisions": 2, "price": 600,  "launchPrice": 499,  "features": { "bug": true, "docs": true,  "comments": false } },
    "advanced": { "num": "03", "label": "Advanced", "showTierNumber": true, "showTierStamp": true, "showPriceTag": true, "priceTag": "Recommended",  "priceTagIcon": "tag", "title": "Stabilize Production App",    "desc": "Stabilize app with CI/CD, monitoring basics, docs, and cleanup.", "days": 14, "revisions": 3, "price": 1200, "launchPrice": 999,  "features": { "bug": true, "docs": true,  "comments": true  } },
    "tier4":    { "num": "04", "label": "Premium",  "showTierNumber": true, "showTierStamp": true, "showPriceTag": true, "priceTag": "Scale up",     "priceTagIcon": "star", "title": "Scale & Automation",        "desc": "Extend the app with automation, QA cleanup, and smoother release flow.", "days": 21, "revisions": 4, "price": 1800, "launchPrice": 1499, "features": { "bug": true, "docs": true,  "comments": true  } },
    "tier5":    { "num": "05", "label": "Enterprise","showTierNumber": true, "showTierStamp": true, "showPriceTag": true, "priceTag": "Priority",     "priceTagIcon": "bolt", "title": "Enterprise Launch System", "desc": "Plan, harden, and launch a larger production workflow with priority fixes.", "days": 30, "revisions": 5, "price": 3000, "launchPrice": 2499, "features": { "bug": true, "docs": true,  "comments": true  } },
    "tier6":    { "num": "06", "label": "Custom",   "showTierNumber": true, "showTierStamp": true, "showPriceTag": true, "priceTag": "Tailored",     "priceTagIcon": "crown","title": "Custom Product Sprint",    "desc": "A tailored implementation sprint for complex scopes and launch goals.", "days": 45, "revisions": 6, "price": 5000, "launchPrice": 3999, "features": { "bug": true, "docs": true,  "comments": true  } }
  },
  "featureLabels": {
    "bug": "Bug investigation",
    "docs": "Fix documentation",
    "comments": "Detailed code comments"
  },
  "featureOrder": ["bug", "docs", "comments"],
  "combineHeadlines": {
    "terminal":  "Pick a package.\nShip faster.",
    "editorial": "Three ways\nto ship.",
    "brutalist": "PICK ONE.\nSHIP IT.",
    "sticker":   "Pick\nyour\nvibe.",
    "blueprint": "Three configurations.\nOne ship date.",
    "magazine":  "Three\nvolumes."
  }
}/*EDITMODE-END*/;

const FEATURE_LABELS = { bug: 'Bug investigation', docs: 'Fix documentation', comments: 'Detailed code comments' };
const STYLES = [
  { id: 'terminal',  name: 'Terminal',  sub: 'dark · mono · code' },
  { id: 'editorial', name: 'Editorial', sub: 'light · grid · numbers' },
  { id: 'brutalist', name: 'Brutalist', sub: 'yellow · heavy · tape' },
  { id: 'sticker',   name: 'Sticker',   sub: 'playful · rounded · pop' },
  { id: 'blueprint', name: 'Blueprint', sub: 'technical · drafted · grid' },
  { id: 'magazine',  name: 'Magazine',  sub: 'fashion · serif · asymmetric' },
];
const TIER_META = {
  starter:  { num: '01', label: 'STARTER' },
  standard: { num: '02', label: 'STANDARD' },
  advanced: { num: '03', label: 'ADVANCED' },
  tier4:    { num: '04', label: 'PREMIUM' },
  tier5:    { num: '05', label: 'ENTERPRISE' },
  tier6:    { num: '06', label: 'CUSTOM' },
};

function cleanTierText(value, fallback = '') {
  const text = String(value == null ? '' : value).trim();
  return text || fallback;
}

function clampTierCount(value) {
  const count = parseInt(value, 10);
  if (!Number.isFinite(count)) return DEFAULT_TIER_COUNT;
  return Math.min(MAX_TIERS, Math.max(MIN_TIERS, count));
}

function tierCount(data) {
  return clampTierCount(data && data.tierCount != null ? data.tierCount : DEFAULT_TIER_COUNT);
}

function tierKeys(data) {
  const keys = TIER_KEYS.slice(0, tierCount(data));
  if (!data || !data.tiers) return keys;
  return keys.filter(key => data.tiers[key]);
}

function tierTotal(data) {
  return String(tierCount(data)).padStart(2, '0');
}

function tierLabel(data, tier, options = {}) {
  const fallback = TIER_META[tier] ? TIER_META[tier].label : tier;
  const label = cleanTierText(data && data.tiers && data.tiers[tier] && data.tiers[tier].label, fallback);
  return options.case === 'title' ? label : label.toUpperCase();
}

function tierNumber(data, tier) {
  const fallback = TIER_META[tier] ? TIER_META[tier].num : tier;
  return cleanTierText(data && data.tiers && data.tiers[tier] && data.tiers[tier].num, fallback);
}

function tierPartVisible(data, tier, key) {
  const tierData = data && data.tiers && data.tiers[tier];
  return !tierData || tierData[key] !== false;
}

function tierPriceTag(data, tier, fallback = '') {
  return cleanTierText(data && data.tiers && data.tiers[tier] && data.tiers[tier].priceTag, fallback);
}

function tierPriceTagIcon(data, tier, fallback = 'tag') {
  const id = cleanTierText(data && data.tiers && data.tiers[tier] && data.tiers[tier].priceTagIcon, fallback);
  return PRICE_TAG_ICONS.find(icon => icon.id === id) || PRICE_TAG_ICONS.find(icon => icon.id === fallback) || PRICE_TAG_ICONS[0];
}

function featureLabels(data) {
  const custom = data && data.featureLabels ? data.featureLabels : {};
  const orderedKeys = Array.isArray(data && data.featureOrder) ? data.featureOrder : Object.keys(FEATURE_LABELS);
  const tierFeatureKeys = data && data.tiers
    ? Object.values(data.tiers).flatMap(tier => Object.keys((tier && tier.features) || {}))
    : [];
  const keys = [...new Set([...orderedKeys, ...Object.keys(custom), ...tierFeatureKeys])];
  return keys.reduce((labels, key) => ({
    ...labels,
    [key]: cleanTierText(custom[key], FEATURE_LABELS[key] || 'Feature'),
  }), {});
}

function PriceTag({ data, tier, text, className = '' }) {
  if (!text) return null;
  if (!tierPartVisible(data, tier, 'showPriceTag')) return null;
  const icon = tierPriceTagIcon(data, tier);
  return (
    <div className={`c-price-tag ${className}`.trim()}>
      {icon.glyph && <span className="price-tag-icon">{icon.glyph}</span>}
      <span className="price-tag-text">{text}</span>
    </div>
  );
}

// Build CSS variable + visibility class string from theme
function themeStyle(theme) {
  return {
    '--theme-bg': theme.bg,
    '--theme-text': theme.text,
    '--theme-muted': theme.muted,
    '--theme-accent': theme.accent,
    '--theme-accent2': theme.accent2,
    '--theme-pattern': theme.patternColor || theme.accent,
    '--theme-pattern2': theme.patternColor2 || theme.accent2,
    '--desc-x': DESCRIPTION_OFFSETS[theme.descriptionPosition] ? DESCRIPTION_OFFSETS[theme.descriptionPosition].x : DESCRIPTION_OFFSETS.auto.x,
    '--desc-y': DESCRIPTION_OFFSETS[theme.descriptionPosition] ? DESCRIPTION_OFFSETS[theme.descriptionPosition].y : DESCRIPTION_OFFSETS.auto.y,
    '--desc-flow-y': DESCRIPTION_OFFSETS[theme.descriptionPosition] ? DESCRIPTION_OFFSETS[theme.descriptionPosition].flowY : DESCRIPTION_OFFSETS.auto.flowY,
    '--theme-display': theme.displayFont,
    '--theme-body': theme.bodyFont,
    '--theme-mono': theme.monoFont,
    '--theme-scale': theme.fontScale != null ? theme.fontScale : 1,
  };
}
function visClass(theme) {
  const show = theme.show || {};
  const classes = COMPONENT_KEYS.map(c => show[c.id] === false ? `hide-${c.id}` : '');
  if (theme.descriptionPosition && theme.descriptionPosition !== 'auto') {
    classes.push(`desc-pos-${theme.descriptionPosition}`);
  }
  if (theme.layout && theme.layout !== 'auto') {
    classes.push(`layout-${theme.layout}`);
  }
  return classes.filter(Boolean).join(' ');
}

// Render a string with \n line breaks as JSX with <br/>
function renderMultiline(s) {
  if (!s) return null;
  const parts = s.split('\n');
  return parts.map((line, i) => (
    <React.Fragment key={i}>
      {line}
      {i < parts.length - 1 && <br />}
    </React.Fragment>
  ));
}

const BACKGROUND_OPTIONS = [
  { id: 'auto',         name: 'Auto (style default)' },
  { id: 'none',         name: 'None' },
  { id: 'dots',         name: 'Dots' },
  { id: 'dots-fine',    name: 'Dots — fine' },
  { id: 'grid',         name: 'Grid' },
  { id: 'grid-accent',  name: 'Grid — accent' },
  { id: 'lines-h',      name: 'Lines — horizontal' },
  { id: 'lines-v',      name: 'Lines — vertical' },
  { id: 'diagonal',     name: 'Diagonal stripes' },
  { id: 'checker',      name: 'Checker' },
  { id: 'scanlines',    name: 'Scanlines' },
  { id: 'cross',        name: 'Crosshatch' },
  { id: 'corners',      name: 'Big grid' },
  { id: 'accent-glow',  name: 'Glow gradient' },
  { id: 'noise',        name: 'Noise' },
];

// Default background per style when 'auto'
const STYLE_DEFAULT_BG = {
  terminal:  'grid',
  editorial: 'none',
  brutalist: 'noise',
  sticker:   'dots',
  blueprint: 'grid',
  magazine:  'none',
};

function BgPattern({ theme, style }) {
  const bg = theme.background || 'auto';
  // 'auto' = let the style render its own default decoration (no overlay)
  // 'none' = handled by parent via .bg-none class hiding default
  if (bg === 'auto' || bg === 'none') return null;
  return <div className={`c-grid cover-bg-pattern cover-bg-pattern--${bg}`} />;
}

// Class added to cover root to hide default style decoration when user picks a custom bg
function bgClass(theme) {
  const bg = theme.background || 'auto';
  if (bg === 'auto') return '';
  return 'bg-override';
}

// ============================================================
// STYLE 1 — TERMINAL
// ============================================================
function TerminalCover({ tier, data, platform, combined }) {
  const t = data.tiers[tier];
  const price = data.launchPricing ? t.launchPrice : t.price;
  const priceTag = tierPriceTag(data, tier, data.launchPricing ? 'Launch price' : '');
  const theme = data.theme;

  if (combined) return <TerminalCombined data={data} platform={platform} />;

  return (
    <div className={`cover cover-terminal ${bgClass(theme)} ${visClass(theme)}`} data-platform={platform} style={themeStyle(theme)}>
      <BgPattern theme={theme} style="terminal" />
      <div className="c-grid term-grid" />
      <div className="c-grid term-scanline" />

      <div className="c-chrome term-chrome">
        <div className="term-dots"><span /><span /><span /></div>
        <div className="term-path">~/{data.brand.toLowerCase()}/services/{tier}.sh</div>
        <div className="term-meta">v1.0 · stable</div>
      </div>

      <div className="term-body">
        <div className="term-header">
          <div className="term-tier-num"><span className="term-prompt">$</span>{tierPartVisible(data, tier, 'showTierStamp') && <span className="c-tier-stamp">tier --{tierLabel(data, tier, { case: 'title' }).toLowerCase()}</span>}</div>
          {tierPartVisible(data, tier, 'showTierNumber') && <div className="c-tier-number term-tier-id">[{tierNumber(data, tier)}/{tierTotal(data)}]</div>}
        </div>

        <div className="term-title-block">
          <div className="term-comment"># package.title</div>
          <h1 className="term-title">{t.title}</h1>
        </div>

        <div className="c-description term-desc">
          <div className="term-comment"># package.description</div>
          <p>&gt; {t.desc}</p>
        </div>

        <div className="term-stats">
          <div className="c-days term-stat">
            <div className="term-stat-key">delivery_days</div>
            <div className="term-stat-val term-stat-val--accent">{t.days}<span className="term-unit">d</span></div>
          </div>
          <div className="c-revisions term-stat">
            <div className="term-stat-key">revisions</div>
            <div className="term-stat-val term-stat-val--accent">{t.revisions}<span className="term-unit">x</span></div>
          </div>
          <div className="c-price term-stat term-stat--price">
            <div className="term-stat-key">price_usd</div>
            <div className="term-stat-val">${price.toLocaleString()}</div>
            <PriceTag data={data} tier={tier} text={priceTag} className="term-price-tag" />
          </div>
        </div>

        <div className="c-features term-features">
          {Object.entries(featureLabels(data)).map(([k, label]) => (
            <div key={k} className={`term-feat ${t.features[k] ? 'on' : 'off'}`}>
              <span className="term-feat-mark">{t.features[k] ? '[✓]' : '[ ]'}</span>
              <span className="term-feat-label">{label}</span>
            </div>
          ))}
        </div>

        <div className="term-footer">
          <div className="c-brand term-brand-mark">
            <div className="term-brand-bracket">{'>_'}</div>
            <div className="term-brand-name">{data.brand}</div>
          </div>
          <div className="c-tagline term-tagline">{data.tagline}</div>
          <div className="c-cursor term-cursor" />
        </div>
      </div>
    </div>
  );
}

function TerminalCombined({ data, platform }) {
  const theme = data.theme;
  return (
    <div className={`cover cover-terminal cover-terminal--combined ${bgClass(theme)} ${visClass(theme)}`} data-platform={platform} style={themeStyle(theme)}>
      <BgPattern theme={theme} style="terminal" />
      <div className="c-grid term-grid" />
      <div className="c-grid term-scanline" />

      <div className="c-chrome term-chrome">
        <div className="term-dots"><span /><span /><span /></div>
        <div className="term-path">~/{data.brand.toLowerCase()}/services/compare.sh</div>
        <div className="term-meta">v1.0 · stable</div>
      </div>

      <div className="term-body term-body--combined">
        <div className="term-combined-header">
          <div className="term-tier-num"><span className="term-prompt">$</span> ./compare-tiers</div>
          <h1 className="term-combined-title">{renderMultiline(data.combineHeadlines && data.combineHeadlines.terminal || 'Pick a package.\nShip faster.')}</h1>
          <div className="c-tagline term-tagline">{data.tagline}</div>
        </div>

        <div className="term-tiers">
          {tierKeys(data).map(k => {
            const t = data.tiers[k];
            const price = data.launchPricing ? t.launchPrice : t.price;
            const isFocus = data.focusTier === k;
            const priceTag = tierPriceTag(data, k, isFocus ? 'Recommended' : '');
            return (
              <div key={k} className={`term-tier ${isFocus ? 'is-focus' : ''}`}>
                <PriceTag data={data} tier={k} text={priceTag} className="term-tier-badge" />
                <div className="term-tier-head">
                  {tierPartVisible(data, k, 'showTierNumber') && <div className="c-tier-number term-tier-num-sm">{tierNumber(data, k)}</div>}
                  {tierPartVisible(data, k, 'showTierStamp') && <div className="c-tier-stamp term-tier-name">{tierLabel(data, k)}</div>}
                </div>
                <div className="term-tier-title">{t.title}</div>
                <p className="c-description term-tier-desc">{t.desc}</p>
                <div className="c-price term-tier-price">${price.toLocaleString()}</div>
                <div className="term-tier-meta">
                  <span className="c-days">{t.days}d</span><span className="dot">·</span><span className="c-revisions">{t.revisions} rev</span>
                </div>
                <div className="c-features term-tier-feats">
                  {Object.entries(featureLabels(data)).map(([fk, label]) => (
                    <div key={fk} className={`tf ${t.features[fk] ? 'on' : 'off'}`}>
                      <span>{t.features[fk] ? '[✓]' : '[ ]'}</span>
                      <span>{label}</span>
                    </div>
                  ))}
                </div>
              </div>
            );
          })}
        </div>

        <div className="term-footer term-footer--combined">
          <div className="c-brand term-brand-mark">
            <div className="term-brand-bracket">{'>_'}</div>
            <div className="term-brand-name">{data.brand}</div>
          </div>
          <div className="c-cursor term-cursor" />
        </div>
      </div>
    </div>
  );
}

// ============================================================
// STYLE 2 — EDITORIAL
// ============================================================
function EditorialCover({ tier, data, platform, combined }) {
  const t = data.tiers[tier];
  const price = data.launchPricing ? t.launchPrice : t.price;
  const priceTag = tierPriceTag(data, tier, data.launchPricing ? 'Launch pricing' : '');
  const theme = data.theme;

  if (combined) return <EditorialCombined data={data} platform={platform} />;

  return (
    <div className={`cover cover-editorial ${bgClass(theme)} ${visClass(theme)}`} data-platform={platform} style={themeStyle(theme)}>
      <BgPattern theme={theme} style="editorial" />
      <div className="ed-rule ed-rule--top" />
      <div className="c-chrome ed-header">
        <div className="c-brand ed-brand">
          <div className="ed-brand-mark" />
          <div className="ed-brand-name">{data.brand}</div>
        </div>
        <div className="ed-meta">
          {tierPartVisible(data, tier, 'showTierNumber') && <span className="c-tier-number">№ {tierNumber(data, tier)}</span>}
          {tierPartVisible(data, tier, 'showTierNumber') && tierPartVisible(data, tier, 'showTierStamp') && <span>·</span>}
          {tierPartVisible(data, tier, 'showTierStamp') && <span className="c-tier-stamp">{tierLabel(data, tier)}</span>}
        </div>
      </div>

      <div className="ed-body">
        <div className="ed-left">
          <div className="ed-kicker">Service package</div>
          <h1 className="ed-title">{t.title}</h1>
          <p className="c-description ed-desc">{t.desc}</p>

          <div className="c-features ed-features">
            {Object.entries(featureLabels(data)).map(([k, label]) => (
              <div key={k} className={`ed-feat ${t.features[k] ? 'on' : 'off'}`}>
                <span className="ed-feat-mark">
                  {t.features[k] ? (
                    <svg viewBox="0 0 24 24" width="18" height="18">
                      <circle cx="12" cy="12" r="11" fill={theme.accent}/>
                      <path d="M7 12.5 L10.5 16 L17 9" stroke={theme.bg} strokeWidth="2.4" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
                    </svg>
                  ) : (
                    <svg viewBox="0 0 24 24" width="18" height="18">
                      <circle cx="12" cy="12" r="11" fill="none" stroke={theme.muted} strokeWidth="1.5" opacity="0.5"/>
                    </svg>
                  )}
                </span>
                <span className="ed-feat-label">{label}</span>
              </div>
            ))}
          </div>
        </div>

        <div className="ed-right">
          <div className="c-price ed-price-block">
            <div className="ed-price-label">Price</div>
            <div className="ed-price">
              <span className="ed-price-currency">$</span>
              <span className="ed-price-amount">{price.toLocaleString()}</span>
            </div>
            <PriceTag data={data} tier={tier} text={priceTag} className="ed-price-note" />
          </div>

          <div className="ed-grid">
            <div className="c-days ed-cell">
              <div className="ed-cell-label">Delivery</div>
              <div className="ed-cell-value">{t.days}<span className="ed-cell-unit">days</span></div>
            </div>
            <div className="c-revisions ed-cell">
              <div className="ed-cell-label">Revisions</div>
              <div className="ed-cell-value">{t.revisions}</div>
            </div>
          </div>
        </div>
      </div>

      <div className="ed-footer">
        <div className="c-tagline ed-tagline">{data.tagline}</div>
        {tierPartVisible(data, tier, 'showTierNumber') && <div className="c-tier-number ed-page">{tierNumber(data, tier)} / {tierTotal(data)}</div>}
      </div>

      <div className="ed-rule ed-rule--bot" />
    </div>
  );
}

function EditorialCombined({ data, platform }) {
  const theme = data.theme;
  return (
    <div className={`cover cover-editorial cover-editorial--combined ${bgClass(theme)} ${visClass(theme)}`} data-platform={platform} style={themeStyle(theme)}>
      <BgPattern theme={theme} style="editorial" />
      <div className="ed-rule ed-rule--top" />
      <div className="c-chrome ed-header">
        <div className="c-brand ed-brand">
          <div className="ed-brand-mark" />
          <div className="ed-brand-name">{data.brand}</div>
        </div>
        <div className="ed-meta"><span>Service tiers</span><span>·</span><span>Compare</span></div>
      </div>

      <div className="ed-comb-body">
        <div className="ed-comb-intro">
          <div>
            <div className="ed-kicker">Choose a package</div>
            <h1 className="ed-comb-title">{renderMultiline(data.combineHeadlines && data.combineHeadlines.editorial || 'Three ways\nto ship.')}</h1>
          </div>
          <p className="c-tagline ed-comb-tagline">{data.tagline}</p>
        </div>

        <div className="ed-comb-grid">
          {tierKeys(data).map(k => {
            const t = data.tiers[k];
            const price = data.launchPricing ? t.launchPrice : t.price;
            const isFocus = data.focusTier === k;
            const priceTag = tierPriceTag(data, k, isFocus ? 'Recommended' : '');
            return (
              <div key={k} className={`ed-comb-tier ${isFocus ? 'is-focus' : ''}`}>
                <div className="ed-comb-tier-head">
                  {tierPartVisible(data, k, 'showTierNumber') && <div className="c-tier-number ed-comb-tier-num">№ {tierNumber(data, k)}</div>}
                  <PriceTag data={data} tier={k} text={priceTag} className="ed-comb-tier-tag" />
                </div>
                {tierPartVisible(data, k, 'showTierStamp') && <div className="c-tier-stamp ed-comb-tier-name">{tierLabel(data, k)}</div>}
                <div className="ed-comb-tier-title">{t.title}</div>
                <p className="c-description ed-comb-tier-desc">{t.desc}</p>
                <div className="c-price ed-comb-tier-price"><span className="cur">$</span>{price.toLocaleString()}</div>
                <div className="ed-comb-tier-meta">
                  <div className="c-days"><span className="lbl">Delivery</span><span className="val">{t.days}d</span></div>
                  <div className="c-revisions"><span className="lbl">Revisions</span><span className="val">{t.revisions}</span></div>
                </div>
                <div className="c-features ed-comb-tier-feats">
                  {Object.entries(featureLabels(data)).map(([fk, label]) => (
                    <div key={fk} className={`ed-comb-feat ${t.features[fk] ? 'on' : 'off'}`}>
                      <span className="ed-comb-feat-mark">{t.features[fk] ? '●' : '○'}</span>
                      <span>{label}</span>
                    </div>
                  ))}
                </div>
              </div>
            );
          })}
        </div>
      </div>

      <div className="ed-footer">
        <div className="c-tagline ed-tagline">{data.tagline}</div>
      </div>
      <div className="ed-rule ed-rule--bot" />
    </div>
  );
}

// ============================================================
// STYLE 3 — BRUTALIST
// ============================================================
function BrutalistCover({ tier, data, platform, combined }) {
  const t = data.tiers[tier];
  const price = data.launchPricing ? t.launchPrice : t.price;
  const priceTag = tierPriceTag(data, tier, data.launchPricing ? 'Launch price' : '');
  const theme = data.theme;

  if (combined) return <BrutalistCombined data={data} platform={platform} />;

  return (
    <div className={`cover cover-brutalist ${bgClass(theme)} ${visClass(theme)}`} data-platform={platform} style={themeStyle(theme)}>
      <BgPattern theme={theme} style="brutalist" />
      <div className="c-grid br-noise" />
      <div className="c-chrome br-tape">
        <span>{data.brand}</span><span>·</span><span>{tierLabel(data, tier)}</span><span>·</span>
        <span>{data.brand}</span><span>·</span><span>{tierLabel(data, tier)}</span><span>·</span>
        <span>{data.brand}</span><span>·</span><span>{tierLabel(data, tier)}</span>
      </div>

      {(tierPartVisible(data, tier, 'showTierNumber') || tierPartVisible(data, tier, 'showTierStamp')) && (
        <div className="br-stamp">
          {tierPartVisible(data, tier, 'showTierNumber') && <div className="c-tier-number br-stamp-num">{tierNumber(data, tier)}</div>}
          {tierPartVisible(data, tier, 'showTierStamp') && <div className="c-tier-stamp br-stamp-lbl">{tierLabel(data, tier)}</div>}
        </div>
      )}

      <div className="br-body">
        <div className="br-title-row"><h1 className="br-title">{t.title}</h1></div>
        <div className="c-description br-desc-row">
          <div className="br-arrow">→</div>
          <p className="br-desc">{t.desc}</p>
        </div>

        <div className="br-mid">
          <div className="c-price br-price-block">
            <div className="br-price-curr">USD</div>
            <div className="br-price">${price.toLocaleString()}</div>
            <PriceTag data={data} tier={tier} text={priceTag} className="br-price-tag" />
          </div>
          <div className="br-stats">
            <div className="c-days br-stat">
              <div className="br-stat-num">{t.days}</div>
              <div className="br-stat-lbl">DAYS</div>
            </div>
            <div className="c-revisions br-stat">
              <div className="br-stat-num">{t.revisions}</div>
              <div className="br-stat-lbl">REV.</div>
            </div>
          </div>
        </div>

        <div className="c-features br-feats">
          {Object.entries(featureLabels(data)).map(([k, label]) => (
            <div key={k} className={`br-feat ${t.features[k] ? 'on' : 'off'}`}>
              <span className="br-feat-box">{t.features[k] ? '✕' : ''}</span>
              <span className="br-feat-label">{label}</span>
            </div>
          ))}
        </div>

        <div className="br-footer">
          <div className="c-brand br-brand">{data.brand}</div>
          <div className="c-tagline br-tagline">{data.tagline}</div>
        </div>
      </div>
    </div>
  );
}

function BrutalistCombined({ data, platform }) {
  const theme = data.theme;
  return (
    <div className={`cover cover-brutalist cover-brutalist--combined ${bgClass(theme)} ${visClass(theme)}`} data-platform={platform} style={themeStyle(theme)}>
      <BgPattern theme={theme} style="brutalist" />
      <div className="c-grid br-noise" />
      <div className="c-chrome br-tape">
        <span>{data.brand}</span><span>·</span><span>COMPARE</span><span>·</span>
        <span>{data.brand}</span><span>·</span><span>COMPARE</span><span>·</span>
        <span>{data.brand}</span><span>·</span><span>COMPARE</span>
      </div>

      <div className="br-comb-head">
        <h1 className="br-comb-title">{renderMultiline(data.combineHeadlines && data.combineHeadlines.brutalist || 'PICK ONE.\nSHIP IT.')}</h1>
        <div className="c-tagline br-comb-sub">{data.tagline}</div>
      </div>

      <div className="br-comb-grid">
        {tierKeys(data).map(k => {
          const t = data.tiers[k];
          const price = data.launchPricing ? t.launchPrice : t.price;
          const isFocus = data.focusTier === k;
          const priceTag = tierPriceTag(data, k, isFocus ? 'Best value' : '');
          return (
            <div key={k} className={`br-comb-tier ${isFocus ? 'is-focus' : ''}`}>
              <PriceTag data={data} tier={k} text={priceTag} className="br-comb-tag" />
              {tierPartVisible(data, k, 'showTierNumber') && <div className="c-tier-number br-comb-num">{tierNumber(data, k)}</div>}
              {tierPartVisible(data, k, 'showTierStamp') && <div className="c-tier-stamp br-comb-name">{tierLabel(data, k)}</div>}
              <div className="br-comb-tt">{t.title}</div>
              <p className="c-description br-comb-desc">{t.desc}</p>
              <div className="c-price br-comb-price">${price.toLocaleString()}</div>
              <div className="br-comb-meta">
                <span className="c-days">{t.days} DAYS</span>
                <span className="sep">|</span>
                <span className="c-revisions">{t.revisions} REV.</span>
              </div>
              <div className="c-features br-comb-feats">
                {Object.entries(featureLabels(data)).map(([fk, label]) => (
                  <div key={fk} className={`br-comb-feat ${t.features[fk] ? 'on' : 'off'}`}>
                    <span>{t.features[fk] ? '✕' : '·'}</span>
                    <span>{label}</span>
                  </div>
                ))}
              </div>
            </div>
          );
        })}
      </div>

      <div className="br-comb-footer">
        <div className="c-brand br-brand">{data.brand}</div>
      </div>
    </div>
  );
}

function Cover({ style, ...props }) {
  if (style === 'terminal')  return <TerminalCover {...props} />;
  if (style === 'editorial') return <EditorialCover {...props} />;
  if (style === 'brutalist') return <BrutalistCover {...props} />;
  if (style === 'sticker')   return <window.StickerCover {...props} />;
  if (style === 'blueprint') return <window.BlueprintCover {...props} />;
  if (style === 'magazine')  return <window.MagazineCover {...props} />;
  return null;
}

Object.assign(window, {
  Cover, PLATFORMS, TIER_KEYS, TIER_META, FEATURE_LABELS, STYLES, DEFAULTS,
  themeStyle, visClass, BgPattern, bgClass, BACKGROUND_OPTIONS, tierLabel, tierNumber,
  tierPartVisible, tierPriceTag, tierKeys, tierCount, tierTotal, clampTierCount,
  tierPriceTagIcon, PriceTag, PRICE_TAG_ICONS, DESCRIPTION_POSITION_OPTIONS,
  MIN_TIERS, MAX_TIERS, DEFAULT_TIER_COUNT,
  LAYOUT_OPTIONS, THEME_PRESETS, FONT_OPTIONS, COMPONENT_KEYS, STYLE_COMPONENTS, renderMultiline,
  featureLabels,
});
