{{-- Contextual miniature illustration for service cards (outcomes, features, process). Types: stack | checkout | seo | modules | ads | analytics | brand | social | email | content | local | cro | timeline | integrations | deliverable When optional title + body (aliases headline / support) yield non-empty normalized copy, the graphic is derived from crc32(copy) and keyword chips — legacy `type` is ignored for that card. Decorative only — parent sets aria-hidden where appropriate. --}} @props([ 'type' => 'deliverable', 'title' => null, 'body' => null, 'headline' => null, 'support' => null, ]) @php return; @endphp @php $title = $title ?? $headline; $body = $body ?? $support; $rawTitle = trim((string) ($title ?? '')); $rawBody = trim((string) ($body ?? '')); if ($rawTitle === '' && $rawBody !== '') { $w = preg_split('/\s+/u', $rawBody); $rawTitle = implode(' ', array_slice($w, 0, min(10, count($w)))); } $normalized = mb_strtolower(preg_replace('/\s+/u', ' ', $rawTitle.' '.$rawBody)); $normalized = trim($normalized); $useCopyDerived = $normalized !== ''; if ($useCopyDerived) { $h = crc32($normalized); $layoutId = (($h % 8) + 8) % 8; $motifIdx = (int) (($h >> 7) % 6); $density = 3 + (int) (($h >> 11) % 4); $stop = array_flip([ 'the', 'a', 'an', 'and', 'or', 'but', 'if', 'then', 'else', 'when', 'at', 'from', 'by', 'for', 'with', 'about', 'into', 'through', 'during', 'before', 'after', 'above', 'below', 'between', 'under', 'again', 'further', 'of', 'to', 'in', 'on', 'as', 'is', 'was', 'are', 'were', 'been', 'be', 'being', 'have', 'has', 'had', 'having', 'do', 'does', 'did', 'doing', 'will', 'would', 'could', 'should', 'may', 'might', 'must', 'shall', 'can', 'this', 'that', 'these', 'those', 'it', 'its', 'we', 'you', 'your', 'our', 'their', 'they', 'them', 'not', 'no', 'nor', 'so', 'than', 'too', 'very', 'just', 'also', 'only', 'own', 'same', 'such', 'here', 'there', 'all', 'each', 'every', 'both', 'few', 'more', 'most', 'other', 'some', 'any', 'such', 'what', 'which', 'who', 'whom', 'how', 'why', 'where', 'i', 'me', 'my', 'he', 'him', 'his', 'she', 'her', 'hers', 'get', 'gets', 'got', 'make', 'made', 'use', 'uses', 'using', 'used', 'let', 'lets', 'say', 'said', 'way', 'ways', 'new', 'like', 'well', 'back', 'over', ]); $blob = mb_strtolower($rawTitle.' '.$rawBody); $blob = preg_replace('/[^\p{L}\p{N}\s]/u', ' ', $blob); $tokens = preg_split('/\s+/u', trim($blob), -1, PREG_SPLIT_NO_EMPTY); $freq = []; foreach ($tokens as $tok) { $tok = mb_strtolower($tok); if (mb_strlen($tok) < 3) { continue; } if (isset($stop[$tok])) { continue; } $freq[$tok] = ($freq[$tok] ?? 0) + 1; } $candidates = array_keys($freq); usort($candidates, static function (string $a, string $b) use ($freq): int { $la = mb_strlen($a); $lb = mb_strlen($b); if ($lb !== $la) { return $lb <=> $la; } return ($freq[$b] ?? 0) <=> ($freq[$a] ?? 0); }); $keywords = array_slice(array_values(array_unique($candidates)), 0, 4); if (count($keywords) < 2) { foreach ($tokens as $tok) { $lt = mb_strtolower($tok); if (mb_strlen($lt) >= 2 && ! isset($stop[$lt])) { $keywords[] = $lt; } if (count($keywords) >= 4) { break; } } $keywords = array_slice(array_values(array_unique($keywords)), 0, 4); } if (count($keywords) < 2) { $keywords = array_slice($tokens, 0, min(4, count($tokens))); } if (count($keywords) === 1) { $one = $keywords[0]; $cut = max(3, (int) floor(mb_strlen($one) / 2)); $tail = mb_substr($one, $cut); $keywords[] = $tail !== '' ? $tail : mb_substr($one, 0, $cut); } // Accent rotates by hash; keyword chips stay editorial neutral (set in copy partial). $paletteBank = [ ['badge' => 'bg-criazo-primary/[0.09]', 'icon' => 'text-criazo-primary', 'stroke' => 'text-criazo-primary', 'fillSoft' => 'text-criazo-primary/20', 'barBg' => 'bg-neutral-200/75', 'barStrong' => 'bg-gradient-to-r from-neutral-400/55 to-neutral-300/40', 'dot' => 'bg-criazo-primary', 'softCol' => 'bg-neutral-50', 'accentSlash' => 'bg-criazo-primary', 'mini' => 'bg-neutral-300/60', 'pillOn' => 'bg-criazo-primary text-white shadow-sm shadow-criazo-primary/15', 'pillOff' => 'bg-white border border-neutral-200 text-neutral-400', 'num' => 'text-criazo-primary'], ['badge' => 'bg-slate-500/[0.08]', 'icon' => 'text-slate-700', 'stroke' => 'text-slate-600', 'fillSoft' => 'text-slate-400/22', 'barBg' => 'bg-neutral-200/75', 'barStrong' => 'bg-gradient-to-r from-slate-400/45 to-neutral-300/35', 'dot' => 'bg-slate-500', 'softCol' => 'bg-slate-50/90', 'accentSlash' => 'bg-slate-500', 'mini' => 'bg-slate-300/45', 'pillOn' => 'bg-slate-700 text-white shadow-sm shadow-slate-700/15', 'pillOff' => 'bg-white border border-neutral-200 text-neutral-400', 'num' => 'text-slate-800'], ['badge' => 'bg-sky-500/[0.08]', 'icon' => 'text-sky-800', 'stroke' => 'text-sky-600', 'fillSoft' => 'text-sky-400/22', 'barBg' => 'bg-neutral-200/75', 'barStrong' => 'bg-gradient-to-r from-sky-400/35 to-neutral-300/35', 'dot' => 'bg-sky-500', 'softCol' => 'bg-sky-50/80', 'accentSlash' => 'bg-sky-500', 'mini' => 'bg-sky-200/50', 'pillOn' => 'bg-sky-700 text-white shadow-sm shadow-sky-700/15', 'pillOff' => 'bg-white border border-neutral-200 text-neutral-400', 'num' => 'text-sky-900'], ['badge' => 'bg-neutral-800/[0.07]', 'icon' => 'text-neutral-800', 'stroke' => 'text-neutral-600', 'fillSoft' => 'text-neutral-400/20', 'barBg' => 'bg-neutral-200/75', 'barStrong' => 'bg-gradient-to-r from-neutral-500/40 to-neutral-300/38', 'dot' => 'bg-neutral-600', 'softCol' => 'bg-neutral-50', 'accentSlash' => 'bg-neutral-600', 'mini' => 'bg-neutral-300/55', 'pillOn' => 'bg-neutral-900 text-white shadow-sm shadow-neutral-900/15', 'pillOff' => 'bg-white border border-neutral-200 text-neutral-400', 'num' => 'text-neutral-900'], ]; $palette = $paletteBank[((int) (($h >> 4) & 7)) % count($paletteBank)]; $kw = array_values(array_filter(array_map( static fn (string $s): string => \Illuminate\Support\Str::limit(trim($s), 14, ''), $keywords ?? [] ))); $kw = array_slice($kw, 0, 4); $lineCount = min(6, max(3, (int) ($density ?? 4))); $micro = (int) (($h ?? 0) & 255); $displayTitle = trim($rawTitle) !== '' ? \Illuminate\Support\Str::limit(trim($rawTitle), 38, '…') : ''; if ($displayTitle === '' && count($kw) > 0) { $displayTitle = \Illuminate\Support\Str::limit(implode(' ', $kw), 38, ''); } } @endphp @if($useCopyDerived) @include('components.partials.service-outcome-visual-copy', [ 'layoutId' => $layoutId, 'motifIdx' => $motifIdx, 'density' => $density, 'keywords' => $keywords, 'palette' => $palette, 'h' => $h, 'kw' => $kw, 'lineCount' => $lineCount, 'micro' => $micro, 'displayTitle' => $displayTitle ?? '', 'rawTitle' => $rawTitle, 'rawBody' => $rawBody, 'normalizedCopy' => $normalized, ]) @else @php $t = $type; @endphp @if($t === 'stack') {{-- Layered platform architecture: core CMS → commerce → extensions --}}
{{ __('messages.service_detail.visual_stack_layer_cms') }}
{{ __('messages.service_detail.visual_stack_layer_commerce') }}
{{ __('messages.service_detail.visual_stack_layer_extensions') }}
{{ __('messages.service_detail.visual_tag_sync') }} {{ __('messages.service_detail.visual_tag_ship') }} +
@elseif($t === 'checkout') {{-- Checkout path: steps + summary + secure pay — compact for h-36 / md:h-40 parents; soft skeleton bars --}}
@foreach([__('messages.service_detail.visual_step_cart'), __('messages.service_detail.visual_step_delivery'), __('messages.service_detail.visual_step_pay')] as $si => $stepLabel)
@if($si > 0)@endif @if($si < 2)@endif {{ $stepLabel }}
@endforeach
{{ __('messages.service_detail.visual_qty') }} 1
{{ __('messages.service_detail.visual_subtotal') }} € ···
{{ __('messages.service_detail.visual_shipping') }}
{{ __('messages.service_detail.visual_pay_secure') }}
@elseif($t === 'seo') {{-- Organic search: soft query strip + result snippets (brand-aligned, not fake SERP chrome) --}}
{{ __('messages.service_detail.visual_indexed') }}
@foreach([1 => '92', 2 => '88'] as $pos => $score)
$pos === 1, 'bg-neutral-50/80 border-neutral-100/80' => $pos !== 1, ])>
{{ $pos }} {{ $score }}
@endforeach
@elseif($t === 'modules') {{-- Merchandising modules: icon | label per cell (no stacked header/dot). Sized for parent h-32 + p-4 (~90px grid) — tight padding. --}}
@php $tiles = [ ['icon' => 'gift', 'label' => __('messages.service_detail.visual_tile_bundles'), 'tile' => 'bg-violet-50/95 border-violet-100/80 text-violet-900', 'iconBg' => 'bg-white border-violet-200/70 text-violet-600'], ['icon' => 'repeat', 'label' => __('messages.service_detail.visual_tile_subs'), 'tile' => 'bg-sky-50/95 border-sky-100/80 text-sky-900', 'iconBg' => 'bg-white border-sky-200/70 text-sky-600'], ['icon' => 'megaphone', 'label' => __('messages.service_detail.visual_tile_campaigns'), 'tile' => 'bg-amber-50/95 border-amber-100/80 text-amber-950', 'iconBg' => 'bg-white border-amber-200/70 text-amber-700'], ['icon' => 'layers', 'label' => __('messages.service_detail.visual_tile_ranges'), 'tile' => 'bg-emerald-50/95 border-emerald-100/80 text-emerald-950', 'iconBg' => 'bg-white border-emerald-200/70 text-emerald-700'], ]; @endphp @foreach($tiles as $tile)
@if($tile['icon'] === 'gift') @elseif($tile['icon'] === 'repeat') @elseif($tile['icon'] === 'megaphone') @else @endif {{ $tile['label'] }}
@endforeach
@elseif($t === 'ads') {{-- Paid campaigns — named rows, soft rhythm bars, pacing readout (no ink slabs) --}}
{{ __('messages.service_detail.visual_ads_title') }} {{ __('messages.service_detail.visual_ads_live') }}
@php $adsRows = [ ['tone' => 'bg-criazo-primary/[0.035]', 'dot' => 'bg-emerald-500 ring-2 ring-emerald-500/20', 'name' => __('messages.service_detail.visual_ads_row_prospecting'), 'pill' => __('messages.service_detail.visual_ads_delta_up'), 'pillStyle' => 'text-emerald-800 bg-emerald-50 border-emerald-100', 'barW' => 'w-[78%]', 'subW' => 'w-[52%]'], ['tone' => 'bg-white', 'dot' => 'bg-amber-400 ring-2 ring-amber-400/25', 'name' => __('messages.service_detail.visual_ads_row_remarketing'), 'pill' => __('messages.service_detail.visual_ads_delta_stable'), 'pillStyle' => 'text-amber-900 bg-amber-50/90 border-amber-100', 'barW' => 'w-[68%]', 'subW' => 'w-[44%]'], ]; @endphp @foreach($adsRows as $r)
{{ $r['name'] }}
{{ $r['pill'] }}
@endforeach
{{ __('messages.service_detail.visual_ads_budget') }} {{ __('messages.service_detail.visual_ads_pacing_value') }}
@elseif($t === 'analytics') {{-- Measurement — funnel-friendly metrics --}}
@foreach([__('messages.service_detail.visual_metric_sessions'), __('messages.service_detail.visual_metric_conv'), __('messages.service_detail.visual_metric_rev')] as $mi => $mlabel) {{ $mlabel }} {{ ['24k', '3.4%', '↑'][$mi] }} @endforeach
{{ __('messages.service_detail.visual_analytics_events') }}
@elseif($t === 'brand') {{-- Brand system — colour + wordmark rhythm --}}
{{ __('messages.service_detail.visual_brand_lockup') }}
@elseif($t === 'social') {{-- Social surfaces — named platforms only (compact 3×2, modules-style rows) --}}
@php $socialCells = [ ['abbr' => 'Ig', 'skin' => 'bg-gradient-to-br from-fuchsia-50/95 to-white border-fuchsia-100/85 text-fuchsia-950', 'chip' => 'bg-gradient-to-br from-purple-500 to-pink-500 text-white border-0', 'label' => __('messages.service_detail.visual_social_platform_instagram')], ['abbr' => 'f', 'skin' => 'bg-gradient-to-br from-blue-50/95 to-white border-blue-100/85 text-blue-950', 'chip' => 'bg-[#1877F2] text-white border-0', 'label' => __('messages.service_detail.visual_social_platform_facebook')], ['abbr' => 'in', 'skin' => 'bg-gradient-to-br from-sky-50/95 to-white border-sky-100/85 text-sky-950', 'chip' => 'bg-[#0A66C2] text-white border-0', 'label' => __('messages.service_detail.visual_social_platform_linkedin')], ['abbr' => 'TT', 'skin' => 'bg-gradient-to-br from-neutral-50 to-white border-neutral-200/90 text-neutral-900', 'chip' => 'bg-neutral-900 text-white border-0', 'label' => __('messages.service_detail.visual_social_platform_tiktok')], ['abbr' => '▶', 'skin' => 'bg-gradient-to-br from-red-50/95 to-white border-red-100/85 text-red-950', 'chip' => 'bg-red-600 text-white border-0', 'label' => __('messages.service_detail.visual_social_platform_youtube')], ['abbr' => 'X', 'skin' => 'bg-gradient-to-br from-neutral-50 to-white border-neutral-200/90 text-neutral-900', 'chip' => 'bg-neutral-950 text-white border-0', 'label' => __('messages.service_detail.visual_social_platform_x')], ]; @endphp
{{ __('messages.service_detail.visual_social_surface') }}
@foreach($socialCells as $cell)
{{ $cell['abbr'] }} {{ $cell['label'] }}
@endforeach
@elseif($t === 'email') {{-- Lifecycle email — performance hints --}}
{{ __('messages.service_detail.visual_email_automation') }} {{ __('messages.service_detail.visual_email_open') }}
@elseif($t === 'content') {{-- Editorial canvas — soft column rhythm, no ink-black bars; QA reads as brand approval --}}
I B {{ __('messages.service_detail.visual_content_draft') }}
{{-- Headline: layered mid-tone lines (reads as typography, not a black slab) --}}
{{ __('messages.service_detail.visual_content_words') }} {{ __('messages.service_detail.visual_content_review') }}
@elseif($t === 'local') {{-- Local discovery — soft map pin + labelled pack rows (fits h-36 / md:h-40 slot) --}}
{{ __('messages.service_detail.visual_local_map') }}
@php $localRows = [ ['n' => '1', 'bar' => 'w-[90%]', 'sub' => 'w-[64%]', 'label' => __('messages.service_detail.visual_local_pack_rank')], ['n' => '2', 'bar' => 'w-[82%]', 'sub' => 'w-[58%]', 'label' => __('messages.service_detail.visual_local_signals')], ['n' => '3', 'bar' => 'w-[76%]', 'sub' => 'w-[52%]', 'label' => __('messages.service_detail.visual_local_nap')], ]; @endphp @foreach($localRows as $lr)
{{ $lr['n'] }}
{{ $lr['label'] }}
@endforeach
@elseif($t === 'cro') {{-- Experiment — variant lift --}}
{{ __('messages.service_detail.visual_cro_a') }}
{{ __('messages.service_detail.visual_cro_lift') }}
{{ __('messages.service_detail.visual_cro_b') }}
@elseif($t === 'timeline') {{-- Phases — horizontal milestones --}}
{{ __('messages.service_detail.visual_timeline_label') }}
@foreach([1,2,3,4] as $mi)
{{ $mi }}
@endforeach
@elseif($t === 'integrations') {{-- Hub + satellites — systems talking --}}
@php $dots = [ ['-translate-x-1/2 left-[12%] top-[8%]', 'CRM'], ['left-[88%] -translate-x-1/2 top-[8%]', 'ERP'], ['-translate-x-1/2 left-[12%] bottom-[12%]', 'Ads'], ['left-[88%] -translate-x-1/2 bottom-[12%]', 'Ship'], ]; @endphp @foreach($dots as $d) {{ $d[1] }} @endforeach
@else {{-- Deliverable / roadmap fallback — crisp, not generic charts --}}
{{ __('messages.service_detail.visual_scope') }}
@foreach(range(1,4) as $r)
{{ $r }}
@endforeach
{{ __('messages.service_detail.visual_acceptance') }}
{{ __('messages.service_detail.visual_ready_launch') }}
@endif @endif