// Raryum website — shared components
// All components defined here are exported to window at the bottom so
// page-level <script type="text/babel"> can use them without re-importing.

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

// ------------------------------------------------------------------
// Button
// ------------------------------------------------------------------
function Button({ variant = 'primary', size = 'md', children, leftIcon, rightIcon, as = 'button', href, onClick, className = '', style = {}, ...rest }) {
  const Comp = as;
  const cls = [
    'rar-btn',
    `rar-btn--${variant}`,
    `rar-btn--${size}`,
    className,
  ].filter(Boolean).join(' ');
  const props = as === 'a' ? { href, onClick, ...rest } : { onClick, ...rest };
  return (
    <Comp className={cls} style={style} {...props}>
      {leftIcon ? <span className="rar-btn__icon">{leftIcon}</span> : null}
      <span>{children}</span>
      {rightIcon ? <span className="rar-btn__icon">{rightIcon}</span> : null}
    </Comp>
  );
}

// ------------------------------------------------------------------
// ElementTile — small periodic-table-style square. Used everywhere:
//   - logo (when size >= 56) — pass showName={false}
//   - phase markers in the EndToEndFlow — showName=true to label KEŞİF / STRATEJİ etc.
//   - product card badges
// ------------------------------------------------------------------
function ElementTile({ symbol = 'Ry', number = '121', name = '', showName = true, size = 56, accent = 'var(--rar-em-4)', className = '', style = {} }) {
  const s = { width: size, height: size, color: accent, ...style };
  const labelled = showName && !!name;
  return (
    <div className={`rar-tile ${labelled ? '' : 'rar-tile--mono'} ${className}`} style={s} aria-label={`${name || symbol} element tile`}>
      <span className="rar-tile__num">{number}</span>
      <span className="rar-tile__sym">{symbol}</span>
      {labelled ? <span className="rar-tile__name">{name}</span> : null}
    </div>
  );
}

// ------------------------------------------------------------------
// Logo lockup — tile + wordmark
// Wordmark is rendered as an inline <svg> with <text> so the brand
// can never be auto-translated by browser/extension layers.
// ------------------------------------------------------------------
function Logo({ size = 36, showWord = true, href = 'index.html' }) {
  const wordSize = Math.round(size * 0.62);
  return (
    <a className="rar-logo" href={href} aria-label="Raryum" translate="no">
      <ElementTile size={size} showName={false} />
      {showWord ? (
        <svg
          className="rar-logo__svg-word"
          width={wordSize * 4.2}
          height={size}
          viewBox={`0 0 ${wordSize * 4.2} ${size}`}
          aria-hidden="true"
        >
          <text
            x="0"
            y={size * 0.72}
            fontFamily="'Plus Jakarta Sans', system-ui, sans-serif"
            fontWeight="700"
            fontSize={wordSize}
            letterSpacing="-0.025em"
            fill="currentColor"
          >Raryum</text>
        </svg>
      ) : null}
    </a>
  );
}

// ------------------------------------------------------------------
// Nav — transparent over hero, opaque after scroll
// ------------------------------------------------------------------
function Nav({ activeKey, overHero = true }) {
  const [scrolled, setScrolled] = useState(!overHero);
  const [open, setOpen] = useState(false);
  useEffect(() => {
    if (!overHero) return;
    const onScroll = () => setScrolled(window.scrollY > 80);
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, [overHero]);

  const items = [
    { key: 'home', label: 'Anasayfa', href: 'index.html' },
    { key: 'hizmetler', label: 'Hizmetler', href: 'hizmetler.html' },
    { key: 'urunler', label: 'Ürünlerimiz', href: 'urunler.html' },
    { key: 'blog', label: 'Blog', href: 'blog.html' },
    { key: 'videolar', label: 'Videolar', href: 'videolar.html' },
    { key: 'iletisim', label: 'İletişim', href: 'iletisim.html' },
  ];

  return (
    <header className={`rar-nav ${scrolled ? 'is-scrolled' : ''}`}>
      <div className="rar-nav__inner">
        <Logo size={36} />
        <nav className="rar-nav__menu" aria-label="Ana navigasyon">
          {items.map(it => (
            <a
              key={it.key}
              href={it.href}
              className={`rar-nav__link ${activeKey === it.key ? 'is-active' : ''}`}
            >{it.label}</a>
          ))}
        </nav>
        <div className="rar-nav__cta">
          <Button as="a" href="iletisim.html" variant="spark" size="sm">
            Keşif görüşmesi
          </Button>
        </div>
        <button className="rar-nav__burger" aria-label="Menü" onClick={() => setOpen(o => !o)}>
          <span /><span /><span />
        </button>
      </div>
      {open ? (
        <div className="rar-nav__mobile">
          {items.map(it => (
            <a key={it.key} href={it.href} className="rar-nav__mobile-link">{it.label}</a>
          ))}
        </div>
      ) : null}
    </header>
  );
}

// ------------------------------------------------------------------
// Hero — fullscreen YouTube iframe with scrim, eyebrow, slogan, scroll cue
// ------------------------------------------------------------------
function Hero({ videoId = 'sn2YHeXaNL8', eyebrow = 'IT DANIŞMANLIK · UÇTAN UCA', title, lede, primaryCTA, secondaryCTA, videoOnly = false }) {
  const iframeRef = useRef(null);
  // enablejsapi=1 lets us control the player via postMessage / YT.Player.
  // hd=1 and vq=hd1080 are best-effort quality hints (YouTube may override).
  const src = `https://www.youtube.com/embed/${videoId}?autoplay=1&mute=1&loop=1&controls=0&modestbranding=1&playsinline=1&rel=0&showinfo=0&iv_load_policy=3&hd=1&vq=hd1080&enablejsapi=1&playlist=${videoId}`;

  useEffect(() => {
    if (!iframeRef.current) return;

    // Load YouTube IFrame API once (shared across all Hero instances)
    if (!window.YT || !window.YT.Player) {
      if (!document.querySelector('script[src="https://www.youtube.com/iframe_api"]')) {
        const tag = document.createElement('script');
        tag.src = 'https://www.youtube.com/iframe_api';
        document.head.appendChild(tag);
      }
    }

    let player;
    let raf;
    function init() {
      if (!window.YT || !window.YT.Player) {
        raf = setTimeout(init, 150);
        return;
      }
      try {
        player = new window.YT.Player(iframeRef.current, {
          events: {
            onReady: (e) => {
              // Best-effort: request highest available quality.
              // 'hd1080' may be silently downgraded by YouTube based on bandwidth/viewport.
              try { e.target.setPlaybackQuality('hd1080'); } catch (_) {}
            },
            onPlaybackQualityChange: (e) => {
              // If YouTube auto-downgraded, try once more to push back up.
              if (e.data && e.data !== 'hd1080' && e.data !== 'highres') {
                try { e.target.setPlaybackQuality('hd1080'); } catch (_) {}
              }
            },
          },
        });
      } catch (_) {}
    }
    init();

    return () => {
      if (raf) clearTimeout(raf);
      try { player && player.destroy && player.destroy(); } catch (_) {}
    };
  }, [videoId]);

  return (
    <section className={`rar-hero ${videoOnly ? 'rar-hero--video-only' : ''}`}>
      <div className="rar-hero__video-wrap" aria-hidden="true">
        <iframe
          ref={iframeRef}
          className="rar-hero__video"
          src={src}
          title="Raryum hero"
          frameBorder="0"
          allow="autoplay; encrypted-media; picture-in-picture"
          allowFullScreen
        />
      </div>
      <div className="rar-hero__scrim" aria-hidden="true" />
      {videoOnly ? null : (
        <div className="rar-hero__content">
          <div className="rar-eyebrow">{eyebrow}</div>
          <h1 className="rar-hero__title">{title}</h1>
          <p className="rar-hero__lede">{lede}</p>
          <div className="rar-hero__ctas">
            {primaryCTA}
            {secondaryCTA}
          </div>
        </div>
      )}
      <a href="#slogan" className="rar-hero__cue" aria-label="Aşağı kaydır">
        <span className="rar-meta">aşağı kaydır</span>
        <svg width="14" height="20" viewBox="0 0 14 20" fill="none">
          <path d="M7 1V18M7 18L1 12M7 18L13 12" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      </a>
    </section>
  );
}

// ------------------------------------------------------------------
// Reveal — IntersectionObserver-driven scroll reveal wrapper
// ------------------------------------------------------------------
// Global rAF-based reveal: avoids IntersectionObserver flakiness in some preview
// environments and works regardless of scroll-event coalescing.
if (typeof window !== 'undefined' && !window.__rarRevealLoop) {
  window.__rarRevealLoop = true;
  const tick = () => {
    const els = document.querySelectorAll('.rar-reveal:not(.is-shown)');
    if (els.length) {
      const vh = window.innerHeight || document.documentElement.clientHeight;
      els.forEach(el => {
        const r = el.getBoundingClientRect();
        // Reveal once the element has crossed into the lower 92% of the viewport
        // (and stay revealed once scrolled past — handles fast/instant scrolls cleanly).
        if (r.top < vh * 0.92) {
          el.classList.add('is-shown');
        }
      });
    }
    requestAnimationFrame(tick);
  };
  requestAnimationFrame(tick);
}

function Reveal({ children, delay = 0, as: As = 'div', className = '', style = {} }) {
  return (
    <As className={`rar-reveal ${className}`} style={{ animationDelay: `${delay}ms`, ...style }}>
      {children}
    </As>
  );
}

// ------------------------------------------------------------------
// SectionHeader — eyebrow + title + lede
// ------------------------------------------------------------------
function SectionHeader({ eyebrow, title, lede, align = 'left' }) {
  return (
    <header className={`rar-section-head rar-section-head--${align}`}>
      {eyebrow ? <div className="rar-eyebrow">{eyebrow}</div> : null}
      <h2 className="rar-section-head__title">{title}</h2>
      {lede ? <p className="rar-section-head__lede">{lede}</p> : null}
    </header>
  );
}

// ------------------------------------------------------------------
// EndToEndFlow — the 6-phase pipeline, scroll-revealed
// ------------------------------------------------------------------
const PHASES = [
  { n: '01', sym: 'Ka', name: 'Keşif & Analiz',         sub: 'Mevcut durum, ihtiyaç, hedef.',           color: 'var(--rar-co-5)' },
  { n: '02', sym: 'Sm', name: 'Strateji & Mimari',      sub: 'Yol haritası, tasarım, fizibilite.',      color: 'var(--rar-co-5)' },
  { n: '03', sym: 'Pt', name: 'Planlama & Tedarik',     sub: 'Lisans, donanım, kaynak planı.',          color: 'var(--rar-em-5)' },
  { n: '04', sym: 'Ke', name: 'Kurulum & Entegrasyon',  sub: 'İnşa, geliştirme, DevOps.',               color: 'var(--rar-em-5)' },
  { n: '05', sym: 'Td', name: 'Test & Devreye Alma',    sub: 'Güvenlik doğrulama, go-live.',            color: 'var(--rar-cu-5)' },
  { n: '06', sym: 'İo', name: 'İşletme & Optimizasyon', sub: 'İzleme, SLA, sürekli iyileştirme.',       color: '#afa9ec' },
];

function EndToEndFlow() {
  return (
    <section id="flow" className="rar-flow">
      <div className="rar-container">
        <Reveal>
          <SectionHeader
            eyebrow="UÇTAN UCA SÜREÇ · 06 AŞAMA"
            title="Keşiften sürekli optimizasyona — tek bir döngü."
            lede="Son adım bir bitiş değil. 1. adıma geri besleme yapan, işinizi sürekli ilişkiye dönüştüren bir döngüdür."
          />
        </Reveal>
        <ol className="rar-flow__list">
          {PHASES.map((p, i) => (
            <Reveal key={p.n} delay={i * 80} as="li" className="rar-flow__item">
              <ElementTile symbol={p.sym} number={p.n} size={72} accent={p.color} />
              <div className="rar-flow__text">
                <h3 className="rar-flow__name">{p.name}</h3>
                <p className="rar-flow__sub">{p.sub}</p>
              </div>
              {i < PHASES.length - 1 ? (
                <svg className="rar-flow__arrow" width="24" height="48" viewBox="0 0 24 48" aria-hidden="true">
                  <path d="M12 2v40M12 42l-6-6M12 42l6-6" stroke="var(--line-strong)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
                </svg>
              ) : null}
            </Reveal>
          ))}
        </ol>
        <Reveal delay={120}>
          <div className="rar-flow__loop">
            <svg width="16" height="16" viewBox="0 0 16 16" aria-hidden="true">
              <path d="M2 8a6 6 0 1 1 2 4.5" stroke="var(--rar-violet-5, #afa9ec)" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeDasharray="3 3"/>
              <path d="M1 11l3 1.5L5 9" stroke="var(--rar-violet-5, #afa9ec)" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
            <span>Geri besleme · yeni döngü</span>
          </div>
        </Reveal>
      </div>
    </section>
  );
}

// ------------------------------------------------------------------
// ServiceTiers — 3 big cards: Beyin / Eller / Kalp
// ------------------------------------------------------------------
const TIERS = [
  {
    n: '01',
    label: 'BEYİN',
    title: 'Strateji & Danışmanlık',
    body: 'IT stratejisi, dijital dönüşüm yol haritası, mimari tasarım, fizibilite, denetim. Önce düşünüyoruz.',
    bullets: ['IT strateji & dönüşüm yol haritası', 'Kurumsal mimari tasarımı', 'Fizibilite & denetim', 'KVKK / GDPR / ISO 27001 uyum'],
    color: 'var(--rar-co-5)',
  },
  {
    n: '02',
    label: 'ELLER',
    title: 'İnşa & Entegrasyon',
    body: 'Data center, ağ, sunucu, bulut, yazılım geliştirme, DevOps, otomasyon, AI/RPA kurulumu. Sonra kuruyoruz.',
    bullets: ['Data center & sunucu odası', 'Bulut / hibrit / multi-cloud', 'Yazılım geliştirme & DevOps', 'AI ajanları & RPA otomasyonu'],
    color: 'var(--rar-em-5)',
  },
  {
    n: '03',
    label: 'KALP',
    title: 'İşletme & Optimizasyon',
    body: 'Yönetilen hizmetler, güvenlik operasyonları, sürekli iyileştirme, performans, raporlama. Yaşatıyoruz.',
    bullets: ['7/24 izleme & SLA yönetimi', 'Güvenlik operasyonları (SOC)', 'Performans & maliyet optimizasyonu (FinOps)', 'Raporlama & BI dashboard\u2019ları'],
    color: '#afa9ec',
  },
];

function ServiceTiers() {
  return (
    <section className="rar-tiers">
      <div className="rar-container">
        <Reveal>
          <SectionHeader
            eyebrow="3 KATMANLI MODEL"
            title="Düşünüyoruz → Kuruyoruz → Yaşatıyoruz."
            lede="Onlarca farklı tedarikçiyle uğraşmayın. Raryum bir elementin saflığıyla; strateji, inşa ve işletmeyi tek bir bütünde sunar."
          />
        </Reveal>
        <div className="rar-tiers__grid">
          {TIERS.map((t, i) => (
            <Reveal key={t.n} delay={i * 100} as="article" className="rar-tier-card">
              <div className="rar-tier-card__head">
                <span className="rar-meta">KATMAN · {t.n}</span>
                <span className="rar-eyebrow" style={{ color: t.color }}>{t.label}</span>
              </div>
              <h3 className="rar-tier-card__title">{t.title}</h3>
              <p className="rar-tier-card__body">{t.body}</p>
              <ul className="rar-tier-card__bullets">
                {t.bullets.map(b => <li key={b}>{b}</li>)}
              </ul>
            </Reveal>
          ))}
        </div>
      </div>
    </section>
  );
}

// ------------------------------------------------------------------
// PRODUCTS data
// ------------------------------------------------------------------
const PRODUCTS = [
  { slug: 'it-talep',     sym: 'It', n: '01', name: 'IT Talep Yazılımı',       cat: 'HELPDESK',       lede: 'Çalışanların IT taleplerini tek yerden takip eden, SLA tabanlı ticket sistemi.', features: ['SLA tabanlı ticket akışı', 'Otomatik kategori & öncelik', 'Aktif Dizin entegrasyonu', 'KPI dashboard\u2019u'] },
  { slug: 'deprem',       sym: 'Dp', n: '02', name: 'Deprem Yardım Yazılımı',  cat: 'KRİZ & OPS',     lede: 'Afet anında ihtiyaç-arz eşleşmesi, gönüllü koordinasyonu, lojistik takibi.',     features: ['İhtiyaç ↔ arz eşleştirme', 'Gönüllü görev kartları', 'Lojistik & dağıtım izleme', 'Açık API'] },
  { slug: 'monitoring',   sym: 'Mn', n: '03', name: 'Monitoring',              cat: 'OBSERVABILITY',  lede: 'Sunucu, ağ, uygulama ve servis sağlığını tek panodan izleyin.',                  features: ['Çoklu protokol (SNMP, ICMP, HTTP)', 'Akıllı eşik & anomali alarmı', 'Olay duvarı & on-call', 'Tarihsel metrik & rapor'] },
  { slug: 'pam',          sym: 'Pa', n: '04', name: 'PAM · Jump Server',       cat: 'GÜVENLİK',       lede: 'Ayrıcalıklı erişim yönetimi: kim, ne zaman, nereye bağlandı — kayıt altında.', features: ['Oturum kaydı (video + komut)', 'Just-in-time erişim', 'MFA & onay akışları', 'Audit & SIEM dışa aktarım'] },
  { slug: 'relay-mail',   sym: 'Rl', n: '05', name: 'Relay Mail · Postal',     cat: 'ALTYAPI',        lede: 'Kurumsal posta relay altyapısı: yüksek teslimat oranı, tam log, DKIM/SPF/DMARC.', features: ['DKIM / SPF / DMARC yönetimi', 'Kuyruk & bounce analitiği', 'Webhook & SMTP API', 'Çoklu alan adı yönetimi'] },
  { slug: 'log',          sym: 'Lg', n: '06', name: 'Log Tutma · Graylog',     cat: 'OBSERVABILITY',  lede: 'Tüm sistem ve uygulama logları tek yerde — arama, korelasyon, uyarı.',          features: ['Yapılandırılmış arama', 'Streams & alert kuralları', 'KVKK uyumlu saklama', 'Dashboard widget seti'] },
  { slug: 'reporting',    sym: 'Rp', n: '07', name: 'Raporlama Dashboard\u2019ları', cat: 'BI', lede: 'İş birimlerine özel KPI panoları, otomatik dağıtım, beyaz etiket.',           features: ['Sürükle-bırak panel', 'Çoklu kaynak (DB, API, CSV)', 'Zamanlı e-posta & Teams', 'Beyaz etiket & SSO'] },
];

// ------------------------------------------------------------------
// ProductTile — large product card
// ------------------------------------------------------------------
function ProductTile({ product, layout = 'card' }) {
  return (
    <article className={`rar-product rar-product--${layout}`}>
      <div className="rar-product__head">
        <ElementTile symbol={product.sym} number={product.n} showName={false} size={72} />
        <span className="rar-meta">{product.cat}</span>
      </div>
      <h3 className="rar-product__name">{product.name}</h3>
      <p className="rar-product__lede">{product.lede}</p>
      <ul className="rar-product__features">
        {product.features.map(f => <li key={f}>{f}</li>)}
      </ul>
      <div className="rar-product__actions">
        <Button as="a" href={`#demo-${product.slug}`} variant="spark" size="sm" rightIcon={<Arrow/>}>
          Online demo
        </Button>
        <Button as="a" href="iletisim.html" variant="ghost" size="sm">
          Bilgi al
        </Button>
      </div>
    </article>
  );
}

function Arrow() {
  return (
    <svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-hidden="true">
      <path d="M2 7h10M8 3l4 4-4 4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}

// ------------------------------------------------------------------
// POSTS — full blog content (used by blog.html, index.html teaser, blog-post.html)
// ------------------------------------------------------------------
const POSTS = [
  {
    slug: 'kvkk-uyum',
    category: 'GÜVENLİK',
    date: '12 May 2026',
    minutes: 7,
    title: 'KVKK uyumu bir denetim değil, bir mimari kararıdır.',
    lede: 'Bir CISO’nun denetim öncesi son hafta sorduğu sorular yerine, ilk gün sorması gerekenler.',
    accent: 'var(--rar-em-5)',
    accent2: 'var(--rar-em-8)',
    body: [
      { type: 'p', text: 'KVKK denetimlerinin büyük çoğunluğu son hafta yaşanır. Klasör doldurulur, log’lar derlenir, politika dokümanları imzalanır. Sonra denetçi gelir, eksikler çıkar, taahhütler verilir — ve bir sonraki yıla kadar bu çevrim aynen tekrar eder. Her seferinde aynı insanlar, aynı klasörler, aynı eksikler.' },
      { type: 'p', text: 'Sorun denetimin kendisinde değil. Sorun, uyumu bir denetime hazırlık olarak görmek — bir mimari kararı olarak değil.' },
      { type: 'pull', text: 'KVKK uyumu, sistemin mimarisinde değilse; her denetim öncesi onu yeniden inşa etmek zorunda kalırsınız.' },
      { type: 'h2', text: 'Yanlış soru: "Denetime ne yetiştiririz?"' },
      { type: 'p', text: 'Çoğu CISO denetim öncesi şu üç soruyu sorar: hangi kayıtlar eksik, hangi politikalar imzasız, hangi log’ları toparlayabiliriz. Bu sorular hayatınızı son bir hafta kurtarır — sonraki on iki ayı kurtarmaz.' },
      { type: 'h2', text: 'Doğru sorular ilk gün başlar' },
      { type: 'list', items: [
        'Hangi veri, hangi sistemde, hangi amaçla tutuluyor — ve bu kaç yıl saklanmalı?',
        'Bir veri sahibi "beni unutun" derse, kaç sistemden silinmesi gerekiyor? Bu silmeyi otomatik yapan bir akışımız var mı?',
        'Bir ihlal anında olay zincirini geri saracak log’lar var mı; varsa kim, ne zaman, neye erişti — bunu sorgulayabilir miyiz?',
        'Ayrıcalıklı erişim hangi sistemlerde MFA + onay akışı arkasında? Hangileri hâlâ "her IT’cinin root’u var" durumunda?',
      ] },
      { type: 'h2', text: 'Mimari ne demek?' },
      { type: 'p', text: 'Bir log mimarisi — Graylog ya da benzeri — kurmuşsanız, denetime hazırlık bir SQL sorgusudur. Bir PAM çözümünüz varsa, "ayrıcalıklı erişim nasıl yönetiliyor" sorusu bir ekran görüntüsüdür. Bir veri envanteriniz varsa, "hangi veri nerede" sorusu bir rapor butonudur.' },
      { type: 'p', text: 'Yoksa — denetim her seferinde bir Excel macerasıdır.' },
      { type: 'callout', title: 'Üç katmanlık bir başlangıç', text: 'Log toplama (Graylog), ayrıcalıklı erişim kaydı (PAM/Jump Server), veri envanteri ve yaşam döngüsü politikası. Bu üçü oturduktan sonra denetim, bir hafta değil bir öğleden sonra alır.' },
      { type: 'h2', text: 'Sonuç' },
      { type: 'p', text: 'KVKK uyumu, yılda bir kez geçilen bir sınav değildir. Mimarinizin bir özelliği olabilir — ya da her yıl size pahalıya patlayan bir vergi. Hangisi olduğuna bugün karar verirsiniz.' },
    ],
  },
  {
    slug: 'on-prem-cloud',
    category: 'ALTYAPI',
    date: '28 Nis 2026',
    minutes: 9,
    title: 'On-prem öldü mü? Orta ölçekli kurumlar için hibrit gerçeği.',
    lede: 'Saf bulut göçü her zaman doğru cevap değildir — KVKK ve maliyet matematiği devreye girdiğinde.',
    accent: 'var(--rar-co-5)',
    accent2: 'var(--rar-em-5)',
    body: [
      { type: 'p', text: '"Bulut’a geçelim" cümlesi, 2020 sonrasında neredeyse her IT toplantısında duyulur oldu. Bir kısmı haklı, bir kısmı pazarlama. Türkiye’deki orta ölçekli kurumlar için bu cümlenin arkasındaki matematik, ABD’deki bir startup’tan tamamen farklı çalışıyor.' },
      { type: 'h2', text: 'Bulut’un cazibesi nereden geliyor?' },
      { type: 'p', text: 'CapEx yerine OpEx, hızlı ölçeklenme, sıfır donanım bakımı, global erişim. Bunlar gerçek faydalar — ve eğer iş yükünüz bu özelliklerden gerçekten yararlanıyorsa, bulut doğru cevaptır.' },
      { type: 'p', text: 'Ama bir orta ölçekli kurumun günlük iş yükü genellikle sabittir: belirli sayıda çalışan, belirli sayıda ERP işlemi, belirli bir veritabanı büyüklüğü. Ölçeklenme kelimesi pazarlama broşüründe iyidir; fatura geldiğinde değil.' },
      { type: 'pull', text: 'Orta ölçekli kurumun iş yükü elastik değildir. Bulut’un en pahalı özelliğini — anlık ölçeklenmeyi — siz çoğunlukla kullanmazsınız ama hep ödersiniz.' },
      { type: 'h2', text: 'KVKK matematiği' },
      { type: 'p', text: 'Veri ikametgâhı (data residency) Türk düzenleyici çerçevesinde ciddi bir konu. Belirli veri türleri yurtdışı sunucularda durduğunda sözleşmesel ve operasyonel yük doğuyor. Hyperscaler’ların Türkiye bölgeleri sınırlı, fiyatları ise standart Avrupa bölgesinden çoğu zaman yüksek.' },
      { type: 'h2', text: 'Hibrit aslında ne demek?' },
      { type: 'list', items: [
        'Sıcak veri (sık erişilen, üretim veritabanı, kullanıcı dosyaları) → on-prem ya da yerel veri merkezi.',
        'Yedek + arşiv → şifreli halde bulut nesne depolama. Birim maliyet uçurum kadar düşük.',
        'Web önyüzü ve API gateway → bulut. Trafik dalgalı, ölçeklenme gerçek.',
        'Geliştirme & test → bulut, anlık aç-kapa.',
        'Kimlik & log altyapısı → on-prem (denetim ve gizlilik için), bulut’a replikasyon.',
      ] },
      { type: 'h2', text: 'Üç yıllık TCO’yu hesaplamayan, bulut’a "ucuz" diyemez' },
      { type: 'p', text: 'Aylık fatura küçük görünür, üç yıl sonra toplam toplandığında — kendi donanımınızı amortize edip bir destek sözleşmesi yapmanın açık ara önüne geçtiği orta ölçekli kurum profilleri var. Her iş yükü bir tablo doldurmadan bulut’a taşınmamalı.' },
      { type: 'callout', title: 'Karar matrisi', text: 'Veri hassasiyeti × yük elastikiyeti × üç yıllık TCO × yetenek mevcudiyeti. Dördünü aynı tabloda görmeden karar vermek — pazarlama dinlemek demektir.' },
      { type: 'p', text: 'On-prem ölmedi. Sadece artık tek başına yeterli değil. Hibrit, orta ölçekli kurumlar için varsayılan haline geldi — ve doğru tasarlandığında, hem KVKK hem fatura tarafını rahatlatıyor.' },
    ],
  },
  {
    slug: 'ai-ajan-rpa',
    category: 'AI & OTOMASYON',
    date: '14 Nis 2026',
    minutes: 6,
    title: 'AI ajanları vs. RPA: hangisi nerede kazanır?',
    lede: 'İç süreçleri otomatize etmenin iki yolu. Bir tanesi ucuz görünür, diğeri 18. ayda kazanmaya başlar.',
    accent: '#afa9ec',
    accent2: 'var(--rar-co-5)',
    body: [
      { type: 'p', text: 'RPA — yıllardır var, çalışıyor. "Bot ekranda tıklıyor" diye özetlenebilir. AI ajanları ise daha yeni: bir hedef veriyorsunuz, ajan plan yapıyor, araçları çağırıyor, sonucu doğruluyor. İkisi rakip değil — farklı problem sınıflarına uygun.' },
      { type: 'h2', text: 'RPA ne zaman kazanır?' },
      { type: 'list', items: [
        'Süreç stabilize, ekran değişmiyor.',
        'Karar mantığı deterministik (if-then-else ile yazılabilir).',
        'Hacim yüksek, hata maliyeti düşük.',
        'Sistemler arası entegrasyon API ile mümkün değil — bot tıklayacak.',
      ] },
      { type: 'p', text: 'Bordro dosyası indir, ERP’ye yükle, doğrula, mail at. Klasik RPA örneği. Üç haftada kurulur, üç yıl çalışır.' },
      { type: 'h2', text: 'AI ajanları ne zaman kazanır?' },
      { type: 'list', items: [
        'Girdi yarı-yapılandırılmış (e-posta, PDF, sohbet).',
        'Karar her seferinde biraz farklı — saf kural yazılamıyor.',
        'Süreçte muhakeme + araç kullanımı gerekiyor.',
        'Hacim makul, çıktı kalitesinin önemi yüksek.',
      ] },
      { type: 'pull', text: 'RPA kuralları otomatize eder. AI ajanı muhakemeyi otomatize eder. İkisinin sınırını bilmek, bütçenizi kurtarır.' },
      { type: 'h2', text: 'Maliyet eğrisi neden farklı?' },
      { type: 'p', text: 'RPA’nın CapEx’i düşüktür ama bakım maliyeti gizlidir: her ekran değişikliği botu kırar. AI ajanı ilk kurulumda daha pahalıdır, model maliyeti devam eder ama UI değişikliklerine RPA’dan çok daha dayanıklıdır.' },
      { type: 'p', text: 'Bir orta ölçekli kurum için ortalama: 24 ay sonunda RPA, beklenmedik bakım masraflarıyla AI ajanının önüne çıkamaz — eğer süreç değişiyorsa. Süreç sabitse, RPA hep ucuz kalır.' },
      { type: 'callout', title: 'Karma yaklaşım', text: 'Çoğu olgun ekip ikisini birlikte kullanıyor: AI ajanı muhakeme + kararı yapıyor, RPA son adımdaki eski sistem etkileşimini hallediyor. Saf seçimden çok, doğru noktada doğru aleti kullanmak — kazanan tarif bu.' },
    ],
  },
  {
    slug: 'sla-ne-degil',
    category: 'YÖNETİLEN HİZMET',
    date: '02 Nis 2026',
    minutes: 5,
    title: 'SLA nedir? Daha önemlisi: SLA ne değildir?',
    lede: 'Yüzdelik garantiler bazen güven verir, çoğu zaman aldatır. Doğru SLA tasarımının üç temel kuralı.',
    accent: 'var(--rar-cu-5)',
    accent2: 'var(--rar-em-5)',
    body: [
      { type: 'p', text: '"%99.9 uptime garantili." Sözleşmenin ön sayfasında bu cümleyi gördüğünüzde — durup üç şeyi sormadan imzalamayın.' },
      { type: 'h2', text: 'Birinci soru: Neyin uptime’ı?' },
      { type: 'p', text: '%99.9 — neyin? Sunucunun mu? Uygulamanın mı? Veritabanının mı? Bütün sistemin mi? Çoğu sözleşme "altyapı uptime’ı" diyor. Yani sunucu ayakta, uygulamanız çökmüş — sözleşme açısından her şey yolunda.' },
      { type: 'pull', text: 'Uptime, bileşenin değil iş çıktısının ölçülmesi gerektiğinde anlamlı olur. "Müşteri ödeme yapabiliyor mu" — gerçek SLA budur.' },
      { type: 'h2', text: 'İkinci soru: Nasıl ölçülüyor?' },
      { type: 'p', text: 'Sağlayıcı kendi sistemiyle mi ölçüyor? Ya da dışarıdan, sentetik bir monitör mü? İlk seçenekte sağlayıcı hem oyuncudur hem hakem. Ciddi sözleşmeler bağımsız ölçümü şart koşar.' },
      { type: 'h2', text: 'Üçüncü soru: İhlalde ne oluyor?' },
      { type: 'list', items: [
        'Hizmet kredisi (service credit) — genelde aylık ücretin %10’u. İşinizi durdurdu, %10 indirim aldınız.',
        'Tazminat tavanı — yıllık ücretin %X’i. Gerçek iş kaybını karşılamaz.',
        'Tek taraflı fesih hakkı — pratikte hiç kullanılmaz.',
      ] },
      { type: 'p', text: 'Yani SLA aslında ne diyor: "biz bu hizmeti vereceğiz; vermezsek size bu kadar geri ödeyeceğiz." Bir performans sözü değil — bir tazminat tarifesi.' },
      { type: 'callout', title: 'İyi SLA üç şeyi yapar', text: '(1) İş çıktısını ölçer, bileşeni değil. (2) Ölçümü bağımsız bir kaynaktan alır. (3) İhlal sonucunu gerçek kayıp ile orantılı tasarlar — sembolik krediler yerine, eskalasyon prosedürü ve gerçek tazminat.' },
    ],
  },
  {
    slug: 'log-mimarisi',
    category: 'OBSERVABILITY',
    date: '19 Mar 2026',
    minutes: 8,
    title: 'Graylog’dan başlayan bir log mimarisi nasıl ölçeklenir?',
    lede: 'Tek node’dan başlayıp 12 milyon olay/gün’e çıkan bir kurulumun anlattıkları.',
    accent: 'var(--rar-em-5)',
    accent2: 'var(--rar-co-5)',
    body: [
      { type: 'p', text: 'İki yıl önce bir orta ölçekli kurumda tek Graylog node’u ile başladık. Bugün üç node’luk bir küme, günde 12 milyon olay alıyor. Aradaki yolculuk lineer değildi — bazı dersler ancak çıktığı anda ortaya çıktı.' },
      { type: 'h2', text: '1. Önce ne topladığını bil' },
      { type: 'p', text: 'Birinci hafta her şeyi loglamak isteyeceksiniz. İkinci ay disk dolmaya başlayacak. Üçüncü ayda artık kimsenin bakmadığı debug log’lar yüzünden gerçek olayları bulamayacaksınız.' },
      { type: 'pull', text: 'Log mimarisinin birinci kuralı: ne tuttuğunu bilmek. İkincisi: tutmaman gerekenleri çöpe yönlendirmek.' },
      { type: 'h2', text: '2. Index tasarımı kaderdir' },
      { type: 'list', items: [
        'Günlük rotasyon → küçük sistemler için iyi, milyonlarca olayda fragmantasyon yaratır.',
        'Boyut bazlı rotasyon (10–20 GB) → orta ölçek için en istikrarlı.',
        'Streams ile mantıksal ayrım: güvenlik, uygulama, ağ, sistem. Saklama süreleri farklı olabilir.',
        'Sıcak/soğuk katman: son 30 gün SSD, ötesi arşiv.',
      ] },
      { type: 'h2', text: '3. Alarm yorgunluğu sessiz katildir' },
      { type: 'p', text: 'Bir ekipte ilk üç ay 80 alarm kuralı yazıldı. Altıncı ayda kimse alarm e-postalarını okumuyordu. Doğru kural sayısı bizim için 12 oldu — kalitesi düşük olanı silmek, yenisini eklemek kadar önemli.' },
      { type: 'h2', text: '4. KVKK saklama süresi ihtiyari değildir' },
      { type: 'p', text: 'Kişisel veri içeren log’ları sonsuza kadar tutamazsınız. Aynı zamanda denetim için yeterli süre tutmak zorundasınız. Streams + saklama politikası kombinasyonu, bu çelişkiyi tek noktada çözer.' },
      { type: 'h2', text: '5. Kümeye geçiş — ne zaman?' },
      { type: 'p', text: 'Tek node’un dolduğu anda değil. Aramaların yavaşladığı, indeksleme gecikmelerinin görüldüğü anda. Bizim için yaklaşık 4 milyon olay/gün eşiğiydi. Daha önce küme kurmak, hem fazladan iş hem fazladan bütçedir.' },
      { type: 'callout', title: 'Bugün için pratik öneri', text: 'Orta ölçekli kurum ölçeğinde başlangıç: tek Graylog + OpenSearch node’u, 2 stream (güvenlik / uygulama), 90 günlük sıcak, 1 yıllık soğuk saklama, S3-uyumlu arşiv. 12 alarm kuralından fazlasını ilk altı ay yazma. Sonra ölçeklendir.' },
    ],
  },
  {
    slug: 'pam-jump',
    category: 'GÜVENLİK',
    date: '05 Mar 2026',
    minutes: 7,
    title: 'Ayrıcalıklı erişim: "kim, ne zaman, nereye?"',
    lede: 'Jump server PAM kurulumu, oturum kaydı ve KVKK uyumlu denetim için pratik bir blueprint.',
    accent: 'var(--rar-em-5)',
    accent2: 'var(--rar-em-8)',
    body: [
      { type: 'p', text: 'Ayrıcalıklı erişim, çoğu orta ölçekli kurumda hâlâ "IT ekibinin Telegram’dan paylaştığı root parolası" düzeyinde. Bir denetim geldiğinde "kim ne zaman neye bağlandı" sorusuna kimse net cevap veremez. Bir ihlal olduğunda — zaten geç.' },
      { type: 'h2', text: 'PAM ne yapar, ne yapmaz?' },
      { type: 'p', text: 'PAM (Privileged Access Management) — ayrıcalıklı kullanıcıların oturumlarını aracı bir sunucu (jump server) üzerinden geçirir, kim-ne zaman-nereye bilgisini kaydeder, gerektiğinde MFA ve onay akışı ekler, kritik oturumları video + komut düzeyinde kayıt altına alır.' },
      { type: 'p', text: 'PAM bir antivirüs değildir. Saldırıyı engellemez — ama her saldırının kayıt altında olmasını sağlar. Denetim, soruşturma ve sorumluluk için gereken yegane veridir.' },
      { type: 'pull', text: 'Önleme — hep arzudur. Kayıt — her zaman gereklidir. PAM’ın değeri ikincisindedir.' },
      { type: 'h2', text: 'Pratik blueprint' },
      { type: 'list', items: [
        '1. Jump server’ı kimlik sağlayıcıya (AD/LDAP/SSO) bağla. Doğrudan parola yönetme.',
        '2. Tüm sunuculara doğrudan SSH/RDP erişimini ağ seviyesinde kapat. Sadece jump server’dan geçsin.',
        '3. Yüksek riskli sistemler (DB, finans, KVKK kapsamı) için just-in-time erişim + onay akışı.',
        '4. Tüm oturumları video + komut düzeyinde kaydet. KVKK uyumlu süre kadar sakla.',
        '5. SIEM / Graylog’a olayları aktar. Anormal saatlere, anormal kaynaklara alarm kur.',
      ] },
      { type: 'h2', text: 'Yaygın hata: PAM’ı kuruyorlar, ağ tarafını açık bırakıyorlar' },
      { type: 'p', text: 'Eğer admin doğrudan SSH ile bağlanabiliyorsa, PAM bir tiyatrodur. Ağ seviyesinde "sadece jump’dan" zorlanmadıkça, yan kapı her zaman açık kalır.' },
      { type: 'callout', title: 'KVKK + ISO 27001 bonusu', text: 'PAM denetim raporlarınızın yarısını tek başına temin eder: erişim kontrolü, log retansiyonu, oturum kaydı, ayrıcalıklı hesap yönetimi. Üç farklı çözüm yerine bir doğru kurulum.' },
      { type: 'p', text: 'Ayrıcalıklı erişim yönetimi şık bir lüks değil. Bir denetimin, soruşturmanın ya da basit bir "ne oldu" sorusunun ardından kalanlardan biri — onu var etmenin maliyeti, hep bir defa cevap verememekten ucuzdur.' },
    ],
  },
];

// ------------------------------------------------------------------
// BlogCover — themed inline SVG illustration per post slug
// ------------------------------------------------------------------
function BlogCover({ slug, accent = 'var(--rar-em-5)', accent2 = 'var(--rar-em-8)' }) {
  const common = { width: '100%', height: '100%', viewBox: '0 0 400 220', preserveAspectRatio: 'xMidYMid slice', xmlns: 'http://www.w3.org/2000/svg' };
  const bg = (
    <>
      <defs>
        <linearGradient id={`bg-${slug}`} x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor={accent2} stopOpacity="0.45" />
          <stop offset="100%" stopColor={accent} stopOpacity="0.15" />
        </linearGradient>
        <pattern id={`grid-${slug}`} width="24" height="24" patternUnits="userSpaceOnUse">
          <path d="M24 0 L0 0 0 24" fill="none" stroke="rgba(255,255,255,0.06)" strokeWidth="1" />
        </pattern>
      </defs>
      <rect width="400" height="220" fill={`url(#bg-${slug})`} />
      <rect width="400" height="220" fill={`url(#grid-${slug})`} />
    </>
  );

  if (slug === 'kvkk-uyum') {
    return (
      <svg {...common}>
        {bg}
        <g transform="translate(200 110)">
          <path d="M0 -60 L48 -42 L48 12 C48 38 26 56 0 66 C-26 56 -48 38 -48 12 L-48 -42 Z" fill="none" stroke={accent} strokeWidth="2.5" />
          <path d="M0 -50 L40 -36 L40 10 C40 30 22 46 0 54 C-22 46 -40 30 -40 10 L-40 -36 Z" fill={accent} fillOpacity="0.12" />
          <path d="M-18 4 L-6 16 L20 -12" fill="none" stroke={accent} strokeWidth="3.5" strokeLinecap="round" strokeLinejoin="round" />
        </g>
        <g fill="rgba(255,255,255,0.5)" fontFamily="JetBrains Mono, monospace" fontSize="9" letterSpacing="0.14em">
          <text x="20" y="200">KVKK · ISO 27001 · GDPR</text>
        </g>
      </svg>
    );
  }
  if (slug === 'on-prem-cloud') {
    return (
      <svg {...common}>
        {bg}
        <g transform="translate(110 110)">
          {[0,1,2,3].map(i => (
            <g key={i} transform={`translate(${i*22 - 33} 0)`}>
              <rect x="-8" y="-40" width="16" height="80" rx="2" fill="none" stroke={accent} strokeWidth="1.5" />
              {[0,1,2,3,4].map(j => <rect key={j} x="-5" y={-32 + j*14} width="10" height="2" fill={accent} fillOpacity="0.7" />)}
            </g>
          ))}
        </g>
        <g transform="translate(290 90)">
          <path d="M-50 10 Q-50 -18 -22 -18 Q-18 -36 6 -36 Q34 -36 38 -12 Q56 -12 56 6 Q56 22 38 22 L-30 22 Q-50 22 -50 10 Z" fill="none" stroke={accent2} strokeWidth="2.5" />
          <path d="M-50 10 Q-50 -18 -22 -18 Q-18 -36 6 -36 Q34 -36 38 -12 Q56 -12 56 6 Q56 22 38 22 L-30 22 Q-50 22 -50 10 Z" fill={accent2} fillOpacity="0.15" />
        </g>
        <path d="M155 110 L240 100" stroke={accent} strokeWidth="1.5" strokeDasharray="4 4" />
        <g fill="rgba(255,255,255,0.5)" fontFamily="JetBrains Mono, monospace" fontSize="9" letterSpacing="0.14em">
          <text x="20" y="200">ON-PREM ⇄ CLOUD · HYBRID</text>
        </g>
      </svg>
    );
  }
  if (slug === 'ai-ajan-rpa') {
    const nodes = [[120,70],[200,50],[280,80],[150,130],[230,150],[300,140],[80,130]];
    return (
      <svg {...common}>
        {bg}
        <g stroke={accent} strokeWidth="1" strokeOpacity="0.55">
          {nodes.map((a, i) => nodes.slice(i+1).map(([bx,by], j) => (
            <line key={`${i}-${j}`} x1={a[0]} y1={a[1]} x2={bx} y2={by} />
          )))}
        </g>
        {nodes.map(([x,y], i) => (
          <g key={i}>
            <circle cx={x} cy={y} r="10" fill={accent} fillOpacity="0.18" stroke={accent} strokeWidth="1.5" />
            <circle cx={x} cy={y} r="3" fill={accent} />
          </g>
        ))}
        <g fill="rgba(255,255,255,0.5)" fontFamily="JetBrains Mono, monospace" fontSize="9" letterSpacing="0.14em">
          <text x="20" y="200">PLAN · TOOL · ACT · VERIFY</text>
        </g>
      </svg>
    );
  }
  if (slug === 'sla-ne-degil') {
    return (
      <svg {...common}>
        {bg}
        <g transform="translate(200 130)">
          <path d="M-80 0 A 80 80 0 0 1 80 0" fill="none" stroke="rgba(255,255,255,0.12)" strokeWidth="10" strokeLinecap="round" />
          <path d="M-80 0 A 80 80 0 0 1 65 -45" fill="none" stroke={accent} strokeWidth="10" strokeLinecap="round" />
          {[-80,-40,0,40,80].map((deg, i) => {
            const r = (deg + 90) * Math.PI / 180;
            return <line key={i} x1={Math.cos(r)*88} y1={-Math.sin(r)*88} x2={Math.cos(r)*98} y2={-Math.sin(r)*98} stroke="rgba(255,255,255,0.4)" strokeWidth="2" />;
          })}
          <line x1="0" y1="0" x2="40" y2="-50" stroke={accent2} strokeWidth="3" strokeLinecap="round" />
          <circle cx="0" cy="0" r="6" fill={accent2} />
          <text x="0" y="-72" textAnchor="middle" fill={accent} fontFamily="JetBrains Mono, monospace" fontSize="14" fontWeight="600">99.9%</text>
        </g>
        <g fill="rgba(255,255,255,0.5)" fontFamily="JetBrains Mono, monospace" fontSize="9" letterSpacing="0.14em">
          <text x="20" y="200">UPTIME · CREDITS · ESCALATION</text>
        </g>
      </svg>
    );
  }
  if (slug === 'log-mimarisi') {
    return (
      <svg {...common}>
        {bg}
        <g transform="translate(0 60)">
          {[0,1,2,3,4].map(i => {
            const y = i * 22;
            const op = 0.25 + i * 0.12;
            return (
              <g key={i}>
                <path d={`M30 ${y} Q 100 ${y - 8 + i*2} 200 ${y + 4} T 380 ${y}`} fill="none" stroke={i % 2 ? accent : accent2} strokeWidth="2" strokeOpacity={op} />
                {[60, 140, 220, 300].map((cx, k) => (
                  <circle key={k} cx={cx} cy={y + ((cx-200)/100)*1.5 + i*0.3} r="2.5" fill={i % 2 ? accent : accent2} fillOpacity={op + 0.2} />
                ))}
              </g>
            );
          })}
        </g>
        <g fill="rgba(255,255,255,0.5)" fontFamily="JetBrains Mono, monospace" fontSize="9" letterSpacing="0.14em">
          <text x="20" y="200">INGEST · INDEX · QUERY · ALERT</text>
        </g>
      </svg>
    );
  }
  if (slug === 'pam-jump') {
    return (
      <svg {...common}>
        {bg}
        <g transform="translate(200 105)">
          <rect x="-30" y="-50" width="60" height="100" rx="6" fill="none" stroke={accent} strokeWidth="2" />
          <rect x="-30" y="-50" width="60" height="100" rx="6" fill={accent} fillOpacity="0.08" />
          <circle cx="0" cy="-5" r="9" fill="none" stroke={accent} strokeWidth="2.5" />
          <path d="M0 -5 L0 22 L-7 22 M0 14 L6 14" stroke={accent} strokeWidth="2.5" strokeLinecap="round" fill="none" />
          <text x="0" y="-62" textAnchor="middle" fill={accent} fontFamily="JetBrains Mono, monospace" fontSize="9" letterSpacing="0.14em">JUMP</text>
        </g>
        <g stroke={accent2} strokeWidth="1.5" strokeDasharray="3 3" strokeOpacity="0.7">
          <path d="M70 110 L168 105" />
          <path d="M232 105 L330 110" />
        </g>
        {[70, 330].map((x, i) => (
          <g key={i} transform={`translate(${x} 110)`}>
            <rect x="-14" y="-18" width="28" height="36" rx="2" fill="none" stroke={accent2} strokeWidth="1.5" />
            {[0,1,2].map(j => <rect key={j} x="-9" y={-12 + j*10} width="18" height="2" fill={accent2} fillOpacity="0.7" />)}
          </g>
        ))}
        <g fill="rgba(255,255,255,0.5)" fontFamily="JetBrains Mono, monospace" fontSize="9" letterSpacing="0.14em">
          <text x="20" y="200">USER · JUMP · TARGET · LOG</text>
        </g>
      </svg>
    );
  }
  return (
    <svg {...common}>{bg}</svg>
  );
}

// ------------------------------------------------------------------
// BlogCard
// ------------------------------------------------------------------
function BlogCard({ post }) {
  return (
    <a className="rar-blog-card" href={`blog-post.html?slug=${post.slug}`} aria-label={post.title}>
      <div className="rar-blog-card__cover">
        <BlogCover slug={post.slug} accent={post.accent} accent2={post.accent2} />
        <span className="rar-blog-card__cat rar-meta">{post.category}</span>
      </div>
      <div className="rar-blog-card__body">
        <div className="rar-meta">{post.date} · {post.minutes} dk okuma</div>
        <h3 className="rar-blog-card__title">{post.title}</h3>
        <p className="rar-blog-card__lede">{post.lede}</p>
        <span className="rar-blog-card__link">Yazıyı oku <Arrow /></span>
      </div>
    </a>
  );
}

// ------------------------------------------------------------------
// VideoCard
// ------------------------------------------------------------------
function VideoCard({ video }) {
  const thumb = `https://i.ytimg.com/vi/${video.id}/hqdefault.jpg`;
  return (
    <a className="rar-video-card" href={`https://www.youtube.com/watch?v=${video.id}`} target="_blank" rel="noreferrer">
      <div className="rar-video-card__thumb">
        <img src={thumb} alt={video.title} loading="lazy" />
        <span className="rar-video-card__play" aria-hidden="true">
          <svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor"><path d="M6 4l10 6-10 6z"/></svg>
        </span>
        <span className="rar-meta rar-video-card__dur">{video.duration}</span>
      </div>
      <div className="rar-video-card__meta">
        <h3 className="rar-video-card__title">{video.title}</h3>
        <div className="rar-meta">{video.channel} · {video.date}</div>
      </div>
    </a>
  );
}

// ------------------------------------------------------------------
// Footer
// ------------------------------------------------------------------
function Footer() {
  return (
    <footer className="rar-footer">
      <div className="rar-container">
        <div className="rar-footer__top">
          <div className="rar-footer__brand">
            <Logo size={48} />
            <p className="rar-editorial rar-footer__slogan">
              <em>Bütünün tek elementi.</em>
            </p>
          </div>
          <div className="rar-footer__cols">
            <div className="rar-footer__col">
              <div className="rar-meta">HİZMETLER</div>
              <a href="hizmetler.html">Strateji & Danışmanlık</a>
              <a href="hizmetler.html">İnşa & Entegrasyon</a>
              <a href="hizmetler.html">İşletme & Optimizasyon</a>
            </div>
            <div className="rar-footer__col">
              <div className="rar-meta">ÜRÜNLER</div>
              <a href="urunler.html">IT Talep</a>
              <a href="urunler.html">Monitoring</a>
              <a href="urunler.html">PAM · Jump Server</a>
              <a href="urunler.html">Graylog</a>
            </div>
            <div className="rar-footer__col">
              <div className="rar-meta">KAYNAKLAR</div>
              <a href="blog.html">Blog</a>
              <a href="videolar.html">Videolar</a>
              <a href="iletisim.html">İletişim</a>
            </div>
          </div>
        </div>
        <hr className="rar-rule" />
        <div className="rar-footer__bottom">
          <span className="rar-meta">© {new Date().getFullYear()} RARYUM TEKNOLOJİ A.Ş. · TÜM HAKLARI SAKLIDIR</span>
          <span className="rar-meta">121 · Ry · [326]</span>
        </div>
      </div>
    </footer>
  );
}

// ------------------------------------------------------------------
// CTA Block — used at end of most pages
// ------------------------------------------------------------------
function CTABlock({ title = 'Bütünün tek elementi olmaya hazır mısınız?', body = 'Bir keşif görüşmesinde mevcut altyapınızı, ihtiyaçlarınızı ve hedeflerinizi birlikte konuşalım. 30 dakika.', primary = 'Keşif görüşmesi al' }) {
  return (
    <section className="rar-cta">
      <div className="rar-container">
        <Reveal>
          <div className="rar-cta__inner">
            <ElementTile size={80} />
            <h2 className="rar-cta__title">{title}</h2>
            <p className="rar-cta__body">{body}</p>
            <div className="rar-cta__actions">
              <Button as="a" href="iletisim.html" variant="spark" size="lg" rightIcon={<Arrow/>}>{primary}</Button>
              <Button as="a" href="hizmetler.html" variant="ghost" size="lg">Hizmetleri incele</Button>
            </div>
          </div>
        </Reveal>
      </div>
    </section>
  );
}

// ------------------------------------------------------------------
// Export to window
// ------------------------------------------------------------------
Object.assign(window, {
  Button, ElementTile, Logo, Nav, Hero, Reveal, SectionHeader,
  EndToEndFlow, ServiceTiers, ProductTile, BlogCard, VideoCard,
  Footer, CTABlock, Arrow, PRODUCTS, PHASES, TIERS, POSTS, BlogCover,
});
