# CULTSCALE Assets Makefile
# Workflow: src/ → out/ → imported by Astro

SHELL := /bin/bash
.PHONY: all decks clean social brand profiles diagrams legal proposals quantech-proposal tnaash-awards tnaash-acquisitions-brief tnaash-acquisitions-brief-compress tnaash-poster-composition tnaash-one-pager option-kallas-life-rights deck-cultsync deck-cultshot-index \
	cultreel-deck-public cultreel-deck-public-compress cultreel-deck-insider cultreel-deck-insider-compress \
	cultsync-deck cultsync-deck-compress \
	yusi-deck yusi-deck-compress yusi-package yusi-launch-plan \
	slate-decks slate-mo-deck slate-micha-deck slate-drybones-deck slate-drybones-deck-compress \
	perdre-le-souvenir-talent-agreement \
	help check
.DEFAULT_GOAL := help

# Directories
SRC_DIR := src
OUT_DIR := out

# Presentations
DECK_PUBLIC_SRC := $(SRC_DIR)/presentations/cultreel/cultreel-deck-public.typ
DECK_INSIDER_SRC := $(SRC_DIR)/presentations/cultreel/cultreel-deck-insider.typ
DECK_SLIDES := $(wildcard $(SRC_DIR)/presentations/cultreel/slides/*.typ) \
  $(SRC_DIR)/presentations/cultreel/cultreel-theme.typ
DECK_DIAGRAM_SVGS := $(wildcard $(SRC_DIR)/diagrams/cultreel-ill-*.svg)
DECK_PUBLIC_PDF := $(OUT_DIR)/cultreel-deck-public.pdf
DECK_PUBLIC_COMPRESSED := $(OUT_DIR)/cultreel-deck-public-compressed.pdf
DECK_INSIDER_PDF := $(OUT_DIR)/cultreel-deck-insider.pdf
DECK_INSIDER_COMPRESSED := $(OUT_DIR)/cultreel-deck-insider-compressed.pdf

# Diagrams (pre-rendered SVG assets)
DIAGRAM_SVGS := $(DECK_DIAGRAM_SVGS)

# Source files (flat, brand-prefixed)
LOGO_SVG := $(SRC_DIR)/cultscale-logo.svg
CULTSHOT_LOGO_SVG := $(SRC_DIR)/cultshot-logo.svg
CULTGUARD_LOGO_SVG := $(SRC_DIR)/cultguard-logo.svg
CULTREEL_SVG := $(SRC_DIR)/cultreel-logo.svg
CULTREEL_SILHOUETTE_SVG := $(SRC_DIR)/cultreel-logo-silhouette.svg
LIB_IMAGE := lib/images/audience-connection-original.jpg
CULTSHOT_IMAGE := $(SRC_DIR)/cultshot-director-cropped.jpg

# Social SVG sources (all depend on LIB_IMAGE)
SOCIAL_SVGS := \
$(SRC_DIR)/cultscale-social-share.svg \
$(SRC_DIR)/cultscale-twitter-header.svg \
$(SRC_DIR)/cultscale-facebook-cover.svg \
$(SRC_DIR)/cultscale-youtube-banner.svg \
$(SRC_DIR)/cultscale-linkedin-company-cover.svg \
$(SRC_DIR)/cultscale-linkedin-personal-cover.svg

# Brand outputs (flat in out/)
BRAND_LOGO_PNG := $(OUT_DIR)/cultscale-logo.png
CULTREEL_LOGO_PNG := $(OUT_DIR)/cultreel-logo.png
CULTREEL_LOGO_SILHOUETTE_PNG := $(OUT_DIR)/cultreel-logo-silhouette.png
BRAND_ICONS := \
$(OUT_DIR)/cultscale-apple-touch-icon.png \
$(OUT_DIR)/cultscale-icon-192.png \
$(OUT_DIR)/cultscale-favicon-32x32.png \
$(OUT_DIR)/cultscale-favicon-16x16.png \
$(OUT_DIR)/cultscale-favicon.ico \
$(OUT_DIR)/cultshot-apple-touch-icon.png \
$(OUT_DIR)/cultshot-icon-192.png \
$(OUT_DIR)/cultshot-favicon-32x32.png \
$(OUT_DIR)/cultshot-favicon-16x16.png \
$(OUT_DIR)/cultshot-favicon.ico \
$(OUT_DIR)/cultguard-apple-touch-icon.png \
$(OUT_DIR)/cultguard-icon-192.png \
$(OUT_DIR)/cultguard-favicon-32x32.png \
$(OUT_DIR)/cultguard-favicon-16x16.png \
$(OUT_DIR)/cultguard-favicon.ico \
$(OUT_DIR)/yusi-apple-touch-icon.png \
$(OUT_DIR)/yusi-icon-192.png \
$(OUT_DIR)/yusi-favicon-32x32.png \
$(OUT_DIR)/yusi-favicon-16x16.png \
$(OUT_DIR)/yusi-favicon.ico \
$(OUT_DIR)/micha-favicon-32x32.png \
$(OUT_DIR)/micha-favicon-16x16.png \
$(OUT_DIR)/micha-favicon.ico \
$(OUT_DIR)/micha-apple-touch-icon.png

# Profile outputs (flat in out/)
PROFILE_TARGETS := \
$(OUT_DIR)/cultscale-instagram-profile.png \
$(OUT_DIR)/cultscale-twitter-profile.png \
$(OUT_DIR)/cultscale-facebook-profile.png \
$(OUT_DIR)/cultscale-linkedin-profile.png \
$(OUT_DIR)/cultscale-youtube-profile.png \
$(OUT_DIR)/cultscale-tiktok-profile.png \
$(OUT_DIR)/cultscale-google-profile.png \
$(OUT_DIR)/cultscale-discord-profile.png \
$(OUT_DIR)/cultscale-bluesky-profile.png \
$(OUT_DIR)/cultscale-github-profile.png \
$(OUT_DIR)/cultscale-threads-profile.png

# Social cover outputs (flat in out/)
# Note: we generate both PNG (standard OG) and a lightweight JPG variant (better WhatsApp reliability).
SOCIAL_COVERS := \
$(OUT_DIR)/cultscale-social-share.png \
$(OUT_DIR)/cultscale-social-share.jpg \
$(OUT_DIR)/cultshot-social-share.png \
$(OUT_DIR)/cultshot-social-share.jpg \
$(OUT_DIR)/cultguard-social-share.png \
$(OUT_DIR)/cultguard-social-share.jpg \
$(OUT_DIR)/yusi-social-share.png \
$(OUT_DIR)/yusi-social-share.jpg \
$(OUT_DIR)/micha-social-share.png \
$(OUT_DIR)/micha-social-share.jpg \
$(OUT_DIR)/cultscale-twitter-header.png \
$(OUT_DIR)/cultscale-facebook-cover.png \
$(OUT_DIR)/cultscale-youtube-banner.png \
$(OUT_DIR)/cultscale-linkedin-company-cover.png \
$(OUT_DIR)/cultscale-linkedin-personal-cover.png

# Presentations (slide decks)
PRESENTATION_DIR := $(SRC_DIR)/presentations

CULTSYNC_DECK_SRC := $(PRESENTATION_DIR)/cultsync/cultsync-deck.typ
CULTSYNC_DECK_SLIDES := $(wildcard $(PRESENTATION_DIR)/cultsync/slides/*.typ) \
  $(PRESENTATION_DIR)/cultsync/cultsync-theme.typ
CULTSYNC_DIAGRAM_SVGS := $(wildcard $(SRC_DIR)/diagrams/cultsync-ill-*.svg)
CULTSYNC_LOGO_SVG := $(SRC_DIR)/cultsync-logo.svg
CULTSYNC_DECK_PDF := $(OUT_DIR)/cultsync-deck.pdf
CULTSYNC_DECK_COMPRESSED := $(OUT_DIR)/cultsync-deck-compressed.pdf

YUSI_DECK_SRC := $(PRESENTATION_DIR)/yusi/yusi-deck.typ
YUSI_DECK_SLIDES := $(wildcard $(PRESENTATION_DIR)/yusi/slides/*.typ) \
  $(PRESENTATION_DIR)/yusi/yusi-theme.typ
YUSI_LOGO_SVG := $(SRC_DIR)/yusi-logo.svg
MICHA_LOGO_SVG := $(SRC_DIR)/micha-logo.svg
YUSI_DECK_PDF := $(OUT_DIR)/yusi-deck.pdf
YUSI_DECK_COMPRESSED := $(OUT_DIR)/yusi-deck-compressed.pdf
YUSI_PACKAGE_SRC := $(PRESENTATION_DIR)/yusi/yusi-package.typ
YUSI_PACKAGE_PDF := $(OUT_DIR)/yusi-package.pdf
YUSI_LAUNCH_PLAN_SRC := $(PRESENTATION_DIR)/yusi/yusi-launch-plan.typ
YUSI_LAUNCH_PLAN_PDF := $(OUT_DIR)/yusi-launch-plan.pdf

SLATE_THEME := $(PRESENTATION_DIR)/slate/slate-theme.typ
SLATE_MO_SRC := $(PRESENTATION_DIR)/slate/mo/mo-deck.typ
SLATE_MICHA_SRC := $(PRESENTATION_DIR)/slate/micha/micha-deck.typ
SLATE_DRYBONES_SRC := $(PRESENTATION_DIR)/slate/drybones/drybones-deck.typ
SLATE_DRYBONES_DECK_RAW := $(OUT_DIR)/slate-drybones-deck-raw.pdf
SLATE_DRYBONES_DECK_PDF := $(OUT_DIR)/slate-drybones-deck.pdf
SLATE_DRYBONES_DECK_COMPRESSED := $(OUT_DIR)/slate-drybones-deck-compressed.pdf
SLATE_DECK_PDFS := \
  $(OUT_DIR)/slate-mo-deck.pdf \
  $(OUT_DIR)/slate-micha-deck.pdf \
  $(SLATE_DRYBONES_DECK_PDF)

# Legal (Typst)
LEGAL_DIR := $(SRC_DIR)/legal
FILM_RELEASE_MANDATE_SRC := $(LEGAL_DIR)/film-release-mandate-agreement.typ
FILM_RELEASE_MANDATE_PDF := $(OUT_DIR)/film-release-mandate-agreement.pdf
OPTION_KALLAS_SRC := $(LEGAL_DIR)/option-kallas-life-rights.typ
OPTION_KALLAS_PDF := $(OUT_DIR)/option-kallas-life-rights.pdf
TALENT_AGREEMENT_PLS_SRC := $(LEGAL_DIR)/perdre-le-souvenir-talent-agreement.typ
TALENT_AGREEMENT_PLS_PDF := $(OUT_DIR)/perdre-le-souvenir-talent-agreement.pdf

# Proposals (Typst - external to src/assets)
PROPOSALS_DIR := ../../special-projects
QUANTECH_PROPOSAL_SRC := $(PROPOSALS_DIR)/quantech-mam/proposal.typ
QUANTECH_PROPOSAL_PDF := $(PROPOSALS_DIR)/quantech-mam/cultsync-mediacentral-brief.pdf
TNAASH_BRIEF_SRC := $(PROPOSALS_DIR)/tnaash/tnaash-acquisitions-brief.typ
TNAASH_BRIEF_PDF := $(PROPOSALS_DIR)/tnaash/tnaash-acquisitions-brief.pdf
TNAASH_BRIEF_COMPRESSED := $(PROPOSALS_DIR)/tnaash/tnaash-acquisitions-brief-compressed.pdf
TNAASH_AWARDS_DIR := $(PROPOSALS_DIR)/tnaash/source/awards
TNAASH_AWARD_IDS := 01 02 03 04 05 06 07 08 09 10
TNAASH_AWARD_SVGS := $(foreach id,$(TNAASH_AWARD_IDS),$(TNAASH_AWARDS_DIR)/tnaash-award-card-$(id).svg)
TNAASH_AWARD_PROOF := $(TNAASH_AWARDS_DIR)/tnaash-awards-proof.png
TNAASH_POSTER_COMPOSITION_SVG := $(PROPOSALS_DIR)/tnaash/source/tnaash-poster-original-composition.svg
TNAASH_POSTER_COMPOSITION_PNG := $(PROPOSALS_DIR)/tnaash/source/tnaash-poster-original-composition.png
TNAASH_POSTER_LAYER_DIR := $(PROPOSALS_DIR)/tnaash/source/poster-layers
TNAASH_POSTER_BASE_PNG := $(TNAASH_POSTER_LAYER_DIR)/tnaash-poster-base-notitle.png
TNAASH_TITLE_SVG := $(TNAASH_POSTER_LAYER_DIR)/title-vector.svg

# Tools check
INKSCAPE := $(shell command -v inkscape 2>/dev/null)
MAGICK := $(shell command -v magick 2>/dev/null)
RSVG := $(shell command -v rsvg-convert 2>/dev/null)
TYPST := $(shell command -v typst 2>/dev/null)

# Colors
GREEN := \033[0;32m
BLUE := \033[0;34m
YELLOW := \033[0;33m
NC := \033[0m

## Help
help: ## Show this help message
	@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
	@echo "CULTSCALE Assets Build System"
	@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
	@echo ""
	@echo "Usage: make [target]"
	@echo ""
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "  $(BLUE)%-15s$(NC) %s\n", $$1, $$2}'
	@echo ""
	@echo "Dependencies:"
	@echo "  • inkscape    $(if $(INKSCAPE),✓ installed,✗ missing)"
	@echo "  • magick      $(if $(MAGICK),✓ installed,✗ missing)"
	@echo "  • rsvg-convert $(if $(RSVG),✓ installed,✗ missing)"
	@echo "  • typst       $(if $(TYPST),✓ installed,✗ missing)"
	@echo ""

## Check dependencies
check: ## Check if required tools are installed
	@echo "Checking dependencies..."
	@command -v magick >/dev/null 2>&1 || (echo "$(YELLOW)✗$(NC) imagemagick not found" && exit 1)
	@command -v rsvg-convert >/dev/null 2>&1 || (echo "$(YELLOW)✗$(NC) rsvg-convert not found" && exit 1)
	@command -v inkscape >/dev/null 2>&1 || echo "$(YELLOW)!$(NC) inkscape not found (will use rsvg-convert fallback)"
	@command -v typst >/dev/null 2>&1 || (echo "$(YELLOW)✗$(NC) typst not found" && exit 1)
	@command -v gs >/dev/null 2>&1 || echo "$(YELLOW)!$(NC) ghostscript not found (PDF compression will be skipped)"
	@echo "$(GREEN)✓$(NC) All dependencies installed"

## Build everything
all: check brand social profiles decks ## Build all assets (brand + social + profiles + decks)

## Build CULTREEL decks
cultreel-deck-public: $(DECK_PUBLIC_PDF) ## Build public deck
cultreel-deck-public-compress: $(DECK_PUBLIC_COMPRESSED) ## Compress public deck (optional)
cultreel-deck-insider: $(DECK_INSIDER_PDF) ## Build insider deck
cultreel-deck-insider-compress: $(DECK_INSIDER_COMPRESSED) ## Compress insider deck (optional)

# Compile public deck (Typst)
$(DECK_PUBLIC_PDF): $(DECK_PUBLIC_SRC) $(DECK_SLIDES) $(DECK_DIAGRAM_SVGS) $(CULTREEL_SVG) | $(OUT_DIR)
	@echo "→ Compiling cultreel-deck-public.pdf (Typst)..."
	@typst compile --root . --font-path=lib/fonts/static --ignore-system-fonts $< $@
	@test -f $@ || (echo "$(YELLOW)✗$(NC) PDF generation failed" && exit 1)

# Compress public PDF (requires ghostscript)
$(DECK_PUBLIC_COMPRESSED): $(DECK_PUBLIC_PDF)
	@echo "→ Compressing cultreel-deck-public.pdf..."
	@if command -v gs >/dev/null 2>&1; then \
		gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook \
			-dNOPAUSE -dQUIET -dBATCH -sOutputFile=$@ $<; \
	else \
		echo "$(YELLOW)!$(NC) ghostscript not found; copying uncompressed deck"; \
		cp $< $@; \
	fi
	@echo "$(GREEN)✓$(NC) Deck built: $@"

# Compile insider deck (Typst)
$(DECK_INSIDER_PDF): $(DECK_INSIDER_SRC) $(DECK_SLIDES) $(DECK_DIAGRAM_SVGS) $(CULTREEL_SVG) | $(OUT_DIR)
	@echo "→ Compiling cultreel-deck-insider.pdf (Typst)..."
	@typst compile --root . --font-path=lib/fonts/static --ignore-system-fonts $< $@
	@test -f $@ || (echo "$(YELLOW)✗$(NC) PDF generation failed" && exit 1)

# Compress insider PDF (requires ghostscript)
$(DECK_INSIDER_COMPRESSED): $(DECK_INSIDER_PDF)
	@echo "→ Compressing cultreel-deck-insider.pdf..."
	@if command -v gs >/dev/null 2>&1; then \
		gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook \
			-dNOPAUSE -dQUIET -dBATCH -sOutputFile=$@ $<; \
	else \
		echo "$(YELLOW)!$(NC) ghostscript not found; copying uncompressed deck"; \
		cp $< $@; \
	fi
	@echo "$(GREEN)✓$(NC) Deck built: $@"

## Build diagrams (no-op; diagrams are pre-rendered SVG assets)
diagrams: ## Diagrams are pre-rendered SVG assets in $(SRC_DIR)/diagrams/
	@echo "Diagrams are provided as SVG assets in $(SRC_DIR)/diagrams/"

## Build brand assets
brand: $(BRAND_LOGO_PNG) $(CULTREEL_LOGO_PNG) $(CULTREEL_LOGO_SILHOUETTE_PNG) $(BRAND_ICONS) ## Build logo and brand icons

## Build social profiles
profiles: $(PROFILE_TARGETS) ## Build social media profile pictures

## Build social covers
social: $(SOCIAL_COVERS) ## Build social media covers/headers

## Build decks
# "decks" is the canonical umbrella target for all slide decks.
decks: cultreel-deck-public cultreel-deck-insider cultsync-deck yusi-deck slate-decks ## Build all decks

## Build legal PDFs
legal: $(FILM_RELEASE_MANDATE_PDF) $(OPTION_KALLAS_PDF) $(TALENT_AGREEMENT_PLS_PDF) ## Build legal PDFs (Typst)

option-kallas-life-rights: $(OPTION_KALLAS_PDF) ## Build Kallas life rights option PDF

perdre-le-souvenir-talent-agreement: $(TALENT_AGREEMENT_PLS_PDF) ## Build Perdre le Souvenir talent agreement

## Build proposals
proposals: quantech-proposal tnaash-acquisitions-brief ## Build all proposals (Typst)

quantech-proposal: $(QUANTECH_PROPOSAL_PDF) ## Build Quantech MAM proposal
tnaash-awards: $(TNAASH_AWARD_PROOF) ## Build Tnaash awards proof sheet from SVG source cards
tnaash-acquisitions-brief: $(TNAASH_BRIEF_PDF) ## Build Tnaash acquisitions brief (high-quality PDF)
tnaash-acquisitions-brief-compress: $(TNAASH_BRIEF_COMPRESSED) ## Build optional compressed Tnaash share PDF
tnaash-poster-composition: $(TNAASH_POSTER_COMPOSITION_PNG) ## Render release-poster SVG composition proof
tnaash-one-pager: tnaash-acquisitions-brief ## Back-compat alias

## Back-compat aliases
deck-cultsync: cultsync-deck ## Back-compat alias
deck-cultshot-index: deck-cultsync ## Back-compat alias

cultsync-deck: $(CULTSYNC_DECK_PDF) ## Build CULTSYNC deck
cultsync-deck-compress: $(CULTSYNC_DECK_COMPRESSED) ## Compress CULTSYNC deck (optional)

yusi-deck: $(YUSI_DECK_PDF) ## Build YUSI pitch deck
yusi-deck-compress: $(YUSI_DECK_COMPRESSED) ## Compress YUSI deck (optional)
yusi-package: $(YUSI_PACKAGE_PDF) ## Build YUSI complete briefing package (A4 PDF)
yusi-launch-plan: $(YUSI_LAUNCH_PLAN_PDF) ## Build YUSI launch plan standalone PDF

## Clean build artifacts
clean: ## Remove all generated files
	@echo "Cleaning output directory..."
	@rm -rf $(OUT_DIR)
	@echo "$(GREEN)✓$(NC) Clean complete"

# Create output directory
$(OUT_DIR):
	@mkdir -p $@

$(TNAASH_AWARDS_DIR):
	@mkdir -p $@

$(TNAASH_AWARD_PROOF): $(TNAASH_AWARD_SVGS) | $(TNAASH_AWARDS_DIR)
	@echo "→ Building Tnaash awards proof sheet..."
	@tmpdir="$${TMPDIR:-/tmp}"; work="$$(mktemp -d "$$tmpdir/tnaash-awards.XXXXXX")"; \
	trap 'rm -rf "$$work"' EXIT; \
	for svg in $(TNAASH_AWARD_SVGS); do \
		name="$$(basename "$$svg" .svg)"; \
		echo "→ Rendering $$name.png..."; \
		rsvg-convert -w 1080 -h 1080 "$$svg" -o "$$work/$$name.png"; \
	done; \
	magick montage "$$work"/tnaash-award-card-*.png -tile 5x2 -geometry 320x320+18+18 \
		-background '#0F0F0F' "$@"

# CULTSYNC deck (Typst)
$(CULTSYNC_DECK_PDF): $(CULTSYNC_DECK_SRC) $(CULTSYNC_DECK_SLIDES) $(CULTSYNC_DIAGRAM_SVGS) $(CULTSYNC_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Compiling cultsync-deck.pdf (Typst)..."
	@typst compile --root . --font-path=lib/fonts/static --ignore-system-fonts $< $@
	@test -f $@ || (echo "$(YELLOW)✗$(NC) PDF generation failed" && exit 1)

# Compress CULTSYNC PDF (requires ghostscript)
$(CULTSYNC_DECK_COMPRESSED): $(CULTSYNC_DECK_PDF)
	@echo "→ Compressing cultsync-deck.pdf..."
	@if command -v gs >/dev/null 2>&1; then \
		gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook \
			-dNOPAUSE -dQUIET -dBATCH -sOutputFile=$@ $<; \
	else \
		echo "$(YELLOW)!$(NC) ghostscript not found; copying uncompressed deck"; \
		cp $< $@; \
	fi
	@echo "$(GREEN)✓$(NC) Deck built: $@"

# YUSI pitch deck (Typst)
$(YUSI_DECK_PDF): $(YUSI_DECK_SRC) $(YUSI_DECK_SLIDES) $(YUSI_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Compiling yusi-deck.pdf (Typst)..."
	@typst compile --root . --font-path=lib/fonts/static --ignore-system-fonts $< $@
	@test -f $@ || (echo "$(YELLOW)✗$(NC) PDF generation failed" && exit 1)
	@echo "$(GREEN)✓$(NC) Deck built: $@"

# Compress YUSI PDF (requires ghostscript)
$(YUSI_DECK_COMPRESSED): $(YUSI_DECK_PDF)
	@echo "→ Compressing yusi-deck.pdf..."
	@if command -v gs >/dev/null 2>&1; then \
		gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook \
			-dNOPAUSE -dQUIET -dBATCH -sOutputFile=$@ $<; \
	else \
		echo "$(YELLOW)!$(NC) ghostscript not found; copying uncompressed deck"; \
		cp $< $@; \
	fi
	@echo "$(GREEN)✓$(NC) Deck built: $@"

# YUSI briefing package — A4 combined document (Typst)
$(YUSI_PACKAGE_PDF): $(YUSI_PACKAGE_SRC) $(PRESENTATION_DIR)/yusi/yusi-theme.typ | $(OUT_DIR)
	@echo "→ Compiling yusi-package.pdf (Typst)..."
	@typst compile --root . --font-path=lib/fonts/static --ignore-system-fonts $< $@
	@test -f $@ || (echo "$(YELLOW)✗$(NC) PDF generation failed" && exit 1)
	@echo "$(GREEN)✓$(NC) Package built: $@"

$(YUSI_LAUNCH_PLAN_PDF): $(YUSI_LAUNCH_PLAN_SRC) $(PRESENTATION_DIR)/yusi/yusi-theme.typ | $(OUT_DIR)
	@echo "→ Compiling yusi-launch-plan.pdf (Typst)..."
	@typst compile --root . --font-path=lib/fonts/static --ignore-system-fonts $< $@
	@test -f $@ || (echo "$(YELLOW)✗$(NC) PDF generation failed" && exit 1)
	@echo "$(GREEN)✓$(NC) Launch plan built: $@"

# Slate decks (Typst)
slate-decks: $(SLATE_DECK_PDFS) ## Build slate decks

slate-mo-deck: $(OUT_DIR)/slate-mo-deck.pdf ## Build Mo' slate deck
slate-micha-deck: $(OUT_DIR)/slate-micha-deck.pdf ## Build Micha slate deck
slate-drybones-deck: $(SLATE_DRYBONES_DECK_PDF) $(SLATE_DRYBONES_DECK_COMPRESSED) ## Build Drybones slate deck (compressed by default)
slate-drybones-deck-compress: $(SLATE_DRYBONES_DECK_COMPRESSED) ## Build compressed copy of Drybones slate deck (email-friendly)

$(OUT_DIR)/slate-mo-deck.pdf: $(SLATE_MO_SRC) $(SLATE_THEME) | $(OUT_DIR)
	@echo "→ Compiling slate-mo-deck.pdf (Typst)..."
	@typst compile --root . --font-path=lib/fonts/static --ignore-system-fonts $< $@

$(OUT_DIR)/slate-micha-deck.pdf: $(SLATE_MICHA_SRC) $(SLATE_THEME) | $(OUT_DIR)
	@echo "→ Compiling slate-micha-deck.pdf (Typst)..."
	@typst compile --root . --font-path=lib/fonts/static --ignore-system-fonts $< $@

$(SLATE_DRYBONES_DECK_RAW): $(SLATE_DRYBONES_SRC) $(SLATE_THEME) | $(OUT_DIR)
	@echo "→ Compiling slate-drybones-deck.pdf (Typst)..."
	@typst compile --root . --font-path=lib/fonts/static --ignore-system-fonts $< $@

$(SLATE_DRYBONES_DECK_PDF): $(SLATE_DRYBONES_DECK_RAW)
	@echo "→ Compressing slate-drybones-deck.pdf (default)..."
	@if command -v gs >/dev/null 2>&1; then \
		gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook \
			-dNOPAUSE -dQUIET -dBATCH -sOutputFile=$@ $<; \
	else \
		echo "$(YELLOW)!$(NC) ghostscript not found; copying uncompressed deck"; \
		cp $< $@; \
	fi
	@echo "$(GREEN)✓$(NC) Deck built: $@"

$(SLATE_DRYBONES_DECK_COMPRESSED): $(SLATE_DRYBONES_DECK_PDF)
	@cp $< $@
	@echo "$(GREEN)✓$(NC) Deck built: $@"

# Legal PDFs (Typst)
$(FILM_RELEASE_MANDATE_PDF): $(FILM_RELEASE_MANDATE_SRC) lib/fonts/static/SpaceGrotesk-Regular.ttf lib/fonts/static/SpaceGrotesk-Bold.ttf | $(OUT_DIR)
	@echo "→ Building film-release-mandate-agreement.pdf (Typst)..."
	@if ! command -v typst >/dev/null 2>&1; then \
		echo "$(YELLOW)✗$(NC) typst not found (install typst to build legal PDFs)"; \
		exit 1; \
	fi
	@typst compile "$<" "$@" --root ../.. --font-path lib/fonts/static --ignore-system-fonts --no-pdf-tags

$(OPTION_KALLAS_PDF): $(OPTION_KALLAS_SRC) lib/fonts/static/SpaceGrotesk-Regular.ttf lib/fonts/static/SpaceGrotesk-Bold.ttf | $(OUT_DIR)
	@echo "→ Building option-kallas-life-rights.pdf (Typst)..."
	@if ! command -v typst >/dev/null 2>&1; then \
		echo "$(YELLOW)✗$(NC) typst not found (install typst to build legal PDFs)"; \
		exit 1; \
	fi
	@typst compile "$<" "$@" --root ../.. --font-path lib/fonts/static --ignore-system-fonts --no-pdf-tags

$(TALENT_AGREEMENT_PLS_PDF): $(TALENT_AGREEMENT_PLS_SRC) lib/fonts/static/SpaceGrotesk-Regular.ttf lib/fonts/static/SpaceGrotesk-Bold.ttf | $(OUT_DIR)
	@echo "→ Building perdre-le-souvenir-talent-agreement.pdf (Typst)..."
	@if ! command -v typst >/dev/null 2>&1; then \
		echo "$(YELLOW)✗$(NC) typst not found (install typst to build legal PDFs)"; \
		exit 1; \
	fi
	@typst compile "$<" "$@" --root ../.. --font-path lib/fonts/static --ignore-system-fonts --no-pdf-tags

# Proposals (Typst - compiled in place at special-projects/)
$(QUANTECH_PROPOSAL_PDF): $(QUANTECH_PROPOSAL_SRC) lib/fonts/static/SpaceGrotesk-Regular.ttf lib/fonts/static/SpaceGrotesk-Bold.ttf
	@echo "→ Building quantech-mam/cultsync-mediacentral-brief.pdf (Typst)..."
	@if ! command -v typst >/dev/null 2>&1; then \
		echo "$(YELLOW)✗$(NC) typst not found (install typst to build proposals)"; \
		exit 1; \
	fi
	@cd $(dir $<) && typst compile $(notdir $<) $(notdir $@) --root ../.. --font-path ../../src/assets/lib/fonts/static --ignore-system-fonts

$(TNAASH_BRIEF_PDF): $(TNAASH_BRIEF_SRC) lib/fonts/static/SpaceGrotesk-Regular.ttf lib/fonts/static/SpaceGrotesk-Bold.ttf lib/fonts/static/SpaceGrotesk-SemiBold.ttf $(PROPOSALS_DIR)/tnaash/source/tnaash-poster-original.png $(PROPOSALS_DIR)/tnaash/source/tnaash-still-016.png $(PROPOSALS_DIR)/tnaash/source/tnaash-still-026.png $(TNAASH_AWARD_SVGS)
	@echo "→ Building tnaash/tnaash-acquisitions-brief.pdf (Typst, high-quality)..."
	@if ! command -v typst >/dev/null 2>&1; then \
		echo "$(YELLOW)✗$(NC) typst not found (install typst to build proposals)"; \
		exit 1; \
	fi
	@cd $(dir $<) && typst compile $(notdir $<) $(notdir $@) --root ../.. --font-path ../../src/assets/lib/fonts/static --ignore-system-fonts
	@test -f $@ || (echo "$(YELLOW)✗$(NC) PDF generation failed" && exit 1)
	@echo "$(GREEN)✓$(NC) Brief built: $@"

$(TNAASH_BRIEF_COMPRESSED): $(TNAASH_BRIEF_PDF)
	@echo "→ Building tnaash/tnaash-acquisitions-brief-compressed.pdf (optional share PDF)..."
	@if ! command -v gs >/dev/null 2>&1; then \
		echo "$(YELLOW)✗$(NC) ghostscript not found (compressed Tnaash PDF requires gs)"; \
		exit 1; \
	fi
	@cd $(dir $<) && gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.6 \
		-dNOPAUSE -dQUIET -dBATCH \
		-dDetectDuplicateImages=true -dCompressFonts=true -dSubsetFonts=true \
		-dDownsampleColorImages=true -dDownsampleGrayImages=true -dDownsampleMonoImages=true \
		-dColorImageDownsampleType=/Bicubic -dGrayImageDownsampleType=/Bicubic -dMonoImageDownsampleType=/Subsample \
		-dColorImageResolution=450 -dGrayImageResolution=450 -dMonoImageResolution=600 \
		-dColorImageDownsampleThreshold=1.5 -dGrayImageDownsampleThreshold=1.5 -dMonoImageDownsampleThreshold=1.5 \
		-sOutputFile=$(notdir $@) $(notdir $<)
	@test -f $@ || (echo "$(YELLOW)✗$(NC) Compressed PDF generation failed" && exit 1)
	@echo "$(GREEN)✓$(NC) Compressed brief built: $@"

$(TNAASH_POSTER_COMPOSITION_PNG): $(TNAASH_POSTER_COMPOSITION_SVG) $(TNAASH_POSTER_BASE_PNG) $(TNAASH_TITLE_SVG) $(TNAASH_AWARD_SVGS)
	@echo "→ Rendering tnaash/source/tnaash-poster-original-composition.png..."
	@if ! command -v rsvg-convert >/dev/null 2>&1; then \
		echo "$(YELLOW)✗$(NC) rsvg-convert not found (poster composition render requires librsvg)"; \
		exit 1; \
	fi
	@rsvg-convert -w 2480 -h 3508 $< -o $@
	@test -f $@ || (echo "$(YELLOW)✗$(NC) Poster composition render failed" && exit 1)
	@echo "$(GREEN)✓$(NC) Poster composition built: $@"

# Brand logo (1024x1024)
$(OUT_DIR)/cultscale-logo.png: $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-logo.png (1024x1024)..."
	@rsvg-convert -w 1024 -h 1024 $< -o $@

# CULTREEL logo (1024x1024)
$(OUT_DIR)/cultreel-logo.png: $(CULTREEL_SVG) | $(OUT_DIR)
	@echo "→ Generating cultreel-logo.png (1024x1024)..."
	@rsvg-convert -w 1024 -h 1024 $< -o $@

# CULTREEL logo silhouette (1024x1024)
$(OUT_DIR)/cultreel-logo-silhouette.png: $(CULTREEL_SILHOUETTE_SVG) | $(OUT_DIR)
	@echo "→ Generating cultreel-logo-silhouette.png (1024x1024)..."
	@rsvg-convert -w 1024 -h 1024 $< -o $@

# Apple touch icon (180x180)
# Branding: Uses the canonical two-triangle icon (2.39:1) centered on Milky Black.
$(OUT_DIR)/cultscale-apple-touch-icon.png: $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-apple-touch-icon.png (180x180) with icon shape..."
	@magick -background '#121212' -gravity center "$<" \
		-resize 180x180 \
		-extent 180x180 \
		$@

$(OUT_DIR)/cultshot-apple-touch-icon.png: $(CULTSHOT_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultshot-apple-touch-icon.png (180x180) with icon shape..."
	@magick -background '#121212' -gravity center "$<" \
		-resize 180x180 \
		-extent 180x180 \
		$@

$(OUT_DIR)/cultguard-apple-touch-icon.png: $(CULTGUARD_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultguard-apple-touch-icon.png (180x180)..."
	@rsvg-convert -w 180 -h 180 -b '#121212' $< -o $@

# PWA icon (192x192)
$(OUT_DIR)/cultscale-icon-192.png: $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-icon-192.png (192x192) with icon shape..."
	@magick -background '#121212' -gravity center "$<" \
		-resize 192x192 \
		-extent 192x192 \
		$@

$(OUT_DIR)/cultshot-icon-192.png: $(CULTSHOT_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultshot-icon-192.png (192x192) with icon shape..."
	@magick -background '#121212' -gravity center "$<" \
		-resize 192x192 \
		-extent 192x192 \
		$@

$(OUT_DIR)/cultguard-icon-192.png: $(CULTGUARD_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultguard-icon-192.png (192x192)..."
	@rsvg-convert -w 192 -h 192 -b '#121212' $< -o $@

# Favicon 32x32
$(OUT_DIR)/cultscale-favicon-32x32.png: $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-favicon-32x32.png with icon shape..."
	@magick -background '#121212' -gravity center "$<" \
		-resize 32x32 \
		-extent 32x32 \
		$@

$(OUT_DIR)/cultshot-favicon-32x32.png: $(CULTSHOT_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultshot-favicon-32x32.png with icon shape..."
	@magick -background '#121212' -gravity center "$<" \
		-resize 32x32 \
		-extent 32x32 \
		$@

$(OUT_DIR)/cultguard-favicon-32x32.png: $(CULTGUARD_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultguard-favicon-32x32.png..."
	@rsvg-convert -w 32 -h 32 -b '#121212' $< -o $@

# Favicon 16x16
$(OUT_DIR)/cultscale-favicon-16x16.png: $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-favicon-16x16.png with icon shape..."
	@magick -background '#121212' -gravity center "$<" \
		-resize 16x16 \
		-extent 16x16 \
		$@

$(OUT_DIR)/cultshot-favicon-16x16.png: $(CULTSHOT_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultshot-favicon-16x16.png with icon shape..."
	@magick -background '#121212' -gravity center "$<" \
		-resize 16x16 \
		-extent 16x16 \
		$@

$(OUT_DIR)/cultguard-favicon-16x16.png: $(CULTGUARD_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultguard-favicon-16x16.png..."
	@rsvg-convert -w 16 -h 16 -b '#121212' $< -o $@

# Favicon ICO (16 + 32)
$(OUT_DIR)/cultscale-favicon.ico: $(OUT_DIR)/cultscale-favicon-16x16.png $(OUT_DIR)/cultscale-favicon-32x32.png
	@echo "→ Generating cultscale-favicon.ico..."
	@magick $^ $@

$(OUT_DIR)/cultshot-favicon.ico: $(OUT_DIR)/cultshot-favicon-16x16.png $(OUT_DIR)/cultshot-favicon-32x32.png
	@echo "→ Generating cultshot-favicon.ico..."
	@magick $^ $@

$(OUT_DIR)/cultguard-favicon.ico: $(OUT_DIR)/cultguard-favicon-16x16.png $(OUT_DIR)/cultguard-favicon-32x32.png
	@echo "→ Generating cultguard-favicon.ico..."
	@magick $^ $@

# YUSI brand icons (saffron #C8872A background)
$(OUT_DIR)/yusi-apple-touch-icon.png: $(YUSI_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating yusi-apple-touch-icon.png (180x180)..."
	@rsvg-convert -w 180 -h 180 -b '#C8872A' $< -o $@

$(OUT_DIR)/yusi-icon-192.png: $(YUSI_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating yusi-icon-192.png (192x192)..."
	@rsvg-convert -w 192 -h 192 -b '#C8872A' $< -o $@

$(OUT_DIR)/yusi-favicon-32x32.png: $(YUSI_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating yusi-favicon-32x32.png..."
	@rsvg-convert -w 32 -h 32 -b '#0D1824' $< -o $@

$(OUT_DIR)/yusi-favicon-16x16.png: $(YUSI_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating yusi-favicon-16x16.png..."
	@rsvg-convert -w 16 -h 16 -b '#0D1824' $< -o $@

$(OUT_DIR)/yusi-favicon.ico: $(OUT_DIR)/yusi-favicon-16x16.png $(OUT_DIR)/yusi-favicon-32x32.png
	@echo "→ Generating yusi-favicon.ico..."
	@magick $^ $@

$(OUT_DIR)/micha-favicon-32x32.png: $(MICHA_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating micha-favicon-32x32.png..."
	@rsvg-convert -w 32 -h 32 -b '#1A1A2E' $< -o $@

$(OUT_DIR)/micha-favicon-16x16.png: $(MICHA_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating micha-favicon-16x16.png..."
	@rsvg-convert -w 16 -h 16 -b '#1A1A2E' $< -o $@

$(OUT_DIR)/micha-favicon.ico: $(OUT_DIR)/micha-favicon-16x16.png $(OUT_DIR)/micha-favicon-32x32.png
	@echo "→ Generating micha-favicon.ico..."
	@magick $^ $@

$(OUT_DIR)/micha-apple-touch-icon.png: $(MICHA_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating micha-apple-touch-icon.png (180x180)..."
	@rsvg-convert -w 180 -h 180 -b '#1A1A2E' $< -o $@

# Social profiles (with Milky Black background #121212)
$(OUT_DIR)/cultscale-instagram-profile.png: $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-instagram-profile.png (110x110)..."
	@rsvg-convert -w 110 -h 110 -b '#121212' $< -o $@

$(OUT_DIR)/cultscale-twitter-profile.png: $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-twitter-profile.png (400x400)..."
	@rsvg-convert -w 400 -h 400 -b '#121212' $< -o $@

$(OUT_DIR)/cultscale-facebook-profile.png: $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-facebook-profile.png (180x180)..."
	@rsvg-convert -w 180 -h 180 -b '#121212' $< -o $@

$(OUT_DIR)/cultscale-linkedin-profile.png: $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-linkedin-profile.png (400x400)..."
	@rsvg-convert -w 400 -h 400 -b '#121212' $< -o $@

$(OUT_DIR)/cultscale-youtube-profile.png: $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-youtube-profile.png (800x800)..."
	@rsvg-convert -w 800 -h 800 -b '#121212' $< -o $@

$(OUT_DIR)/cultscale-tiktok-profile.png: $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-tiktok-profile.png (200x200)..."
	@rsvg-convert -w 200 -h 200 -b '#121212' $< -o $@

$(OUT_DIR)/cultscale-google-profile.png: $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-google-profile.png (250x250)..."
	@rsvg-convert -w 250 -h 250 -b '#121212' $< -o $@

$(OUT_DIR)/cultscale-discord-profile.png: $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-discord-profile.png (512x512)..."
	@rsvg-convert -w 512 -h 512 -b '#121212' $< -o $@

$(OUT_DIR)/cultscale-bluesky-profile.png: $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-bluesky-profile.png (1000x1000)..."
	@rsvg-convert -w 1000 -h 1000 -b '#121212' $< -o $@

$(OUT_DIR)/cultscale-github-profile.png: $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-github-profile.png (400x400)..."
	@rsvg-convert -w 400 -h 400 -b '#121212' $< -o $@

$(OUT_DIR)/cultscale-threads-profile.png: $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-threads-profile.png (400x400)..."
	@rsvg-convert -w 400 -h 400 -b '#121212' $< -o $@

# Social covers (from SVG compositions with embedded images)
# Each cover depends on its SVG source, the logo, AND the background image
$(OUT_DIR)/cultscale-social-share.png: $(SRC_DIR)/cultscale-social-share.svg $(LIB_IMAGE) $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-social-share.png (1200x630)..."
	@if command -v inkscape >/dev/null 2>&1; then \
		inkscape $< --export-filename=$@ --export-width=1200 --export-height=630 2>&1 | grep -v "^$$" || true; \
	else \
		rsvg-convert -w 1200 -h 630 $< -o $@; \
	fi

# WhatsApp sometimes fails to render previews for large PNG OG images; we ship a small JPG variant for og:image.
$(OUT_DIR)/cultscale-social-share.jpg: $(OUT_DIR)/cultscale-social-share.png | $(OUT_DIR)
	@echo "→ Generating cultscale-social-share.jpg (optimized for link previews)..."
	@magick $< -strip -interlace Plane -quality 80 $@

$(OUT_DIR)/cultshot-social-share.png: $(SRC_DIR)/cultshot-social-share.svg $(CULTSHOT_IMAGE) $(CULTSHOT_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultshot-social-share.png (1200x630)..."
	@if command -v inkscape >/dev/null 2>&1; then \
		inkscape $< --export-filename=$@ --export-width=1200 --export-height=630 2>&1 | grep -v "^$$" || true; \
	else \
		rsvg-convert -w 1200 -h 630 $< -o $@; \
	fi

$(OUT_DIR)/cultshot-social-share.jpg: $(OUT_DIR)/cultshot-social-share.png | $(OUT_DIR)
	@echo "→ Generating cultshot-social-share.jpg (optimized for link previews)..."
	@magick $< -strip -interlace Plane -quality 80 $@

$(OUT_DIR)/cultguard-social-share.png: $(SRC_DIR)/cultguard-social-share.svg $(CULTGUARD_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultguard-social-share.png (1200x630, 2x render for sharpness)..."
	@if command -v inkscape >/dev/null 2>&1; then \
		tmpdir="$${TMPDIR:-/tmp}"; \
		inkscape $< --export-filename="$$tmpdir/cultguard-social-2x.png" --export-width=2400 --export-height=1260 2>&1 | grep -v "^$$" || true; \
		magick "$$tmpdir/cultguard-social-2x.png" -resize 1200x630 -quality 100 $@; \
	else \
		rsvg-convert --zoom=2 $< | magick - -resize 1200x630 -quality 100 $@; \
	fi

$(OUT_DIR)/cultguard-social-share.jpg: $(OUT_DIR)/cultguard-social-share.png | $(OUT_DIR)
	@echo "→ Generating cultguard-social-share.jpg (high quality for link previews)..."
	@magick $< -strip -interlace Plane -quality 92 $@

$(OUT_DIR)/yusi-social-share.png: $(SRC_DIR)/yusi-social-share.svg $(YUSI_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating yusi-social-share.png (1200x630, 2x render for sharpness)..."
	@if command -v inkscape >/dev/null 2>&1; then \
		tmpdir="$${TMPDIR:-/tmp}"; \
		inkscape $< --export-filename="$$tmpdir/yusi-social-2x.png" --export-width=2400 --export-height=1260 2>&1 | grep -v "^$$" || true; \
		magick "$$tmpdir/yusi-social-2x.png" -resize 1200x630 -quality 100 $@; \
	else \
		rsvg-convert --zoom=2 $< | magick - -resize 1200x630 -quality 100 $@; \
	fi

$(OUT_DIR)/yusi-social-share.jpg: $(OUT_DIR)/yusi-social-share.png | $(OUT_DIR)
	@echo "→ Generating yusi-social-share.jpg (high quality for link previews)..."
	@magick $< -strip -interlace Plane -quality 92 $@

$(OUT_DIR)/micha-social-share.png: $(SRC_DIR)/micha-social-share.svg $(MICHA_LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating micha-social-share.png (1200x630, 2x render for sharpness)..."
	@if command -v inkscape >/dev/null 2>&1; then \
		tmpdir="$${TMPDIR:-/tmp}"; \
		inkscape $< --export-filename="$$tmpdir/micha-social-2x.png" --export-width=2400 --export-height=1260 2>&1 | grep -v "^$$" || true; \
		magick "$$tmpdir/micha-social-2x.png" -resize 1200x630 -quality 100 $@; \
	else \
		rsvg-convert --zoom=2 $< | magick - -resize 1200x630 -quality 100 $@; \
	fi

$(OUT_DIR)/micha-social-share.jpg: $(OUT_DIR)/micha-social-share.png | $(OUT_DIR)
	@echo "→ Generating micha-social-share.jpg (high quality for link previews)..."
	@magick $< -strip -interlace Plane -quality 92 $@

$(OUT_DIR)/cultscale-twitter-header.png: $(SRC_DIR)/cultscale-twitter-header.svg $(LIB_IMAGE) $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-twitter-header.png (1500x500)..."
	@if command -v inkscape >/dev/null 2>&1; then \
		inkscape $< --export-filename=$@ --export-width=1500 --export-height=500 2>&1 | grep -v "^$$" || true; \
	else \
		rsvg-convert -w 1500 -h 500 $< -o $@; \
	fi

$(OUT_DIR)/cultscale-facebook-cover.png: $(SRC_DIR)/cultscale-facebook-cover.svg $(LIB_IMAGE) $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-facebook-cover.png (820x312)..."
	@if command -v inkscape >/dev/null 2>&1; then \
		inkscape $< --export-filename=$@ --export-width=820 --export-height=312 2>&1 | grep -v "^$$" || true; \
	else \
		rsvg-convert -w 820 -h 312 $< -o $@; \
	fi

$(OUT_DIR)/cultscale-youtube-banner.png: $(SRC_DIR)/cultscale-youtube-banner.svg $(LIB_IMAGE) $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-youtube-banner.png (2560x1440)..."
	@if command -v inkscape >/dev/null 2>&1; then \
		inkscape $< --export-filename=$@ --export-width=2560 --export-height=1440 2>&1 | grep -v "^$$" || true; \
	else \
		rsvg-convert -w 2560 -h 1440 $< -o $@; \
	fi

$(OUT_DIR)/cultscale-linkedin-company-cover.png: $(SRC_DIR)/cultscale-linkedin-company-cover.svg $(LIB_IMAGE) $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-linkedin-company-cover.png (1128x191)..."
	@if command -v inkscape >/dev/null 2>&1; then \
		inkscape $< --export-filename=$@ --export-width=1128 --export-height=191 2>&1 | grep -v "^$$" || true; \
	else \
		rsvg-convert -w 1128 -h 191 $< -o $@; \
	fi

$(OUT_DIR)/cultscale-linkedin-personal-cover.png: $(SRC_DIR)/cultscale-linkedin-personal-cover.svg $(LIB_IMAGE) $(LOGO_SVG) | $(OUT_DIR)
	@echo "→ Generating cultscale-linkedin-personal-cover.png (1584x396)..."
	@if command -v inkscape >/dev/null 2>&1; then \
		inkscape $< --export-filename=$@ --export-width=1584 --export-height=396 2>&1 | grep -v "^$$" || true; \
	else \
		rsvg-convert -w 1584 -h 396 $< -o $@; \
	fi
