Dokumentasi untuk blog minimalis saya, the timeline.

Saya mengganti tema dengan dark mode alasannya tidak tau hanya terlihat baik saja, lalu saya juga mengubah typeface dengan Jetbrain Mono yang karakternya tebal jadi harus disesuaikan, sebelumnya saya pakai IBM Plex Mono yang kecil itu.

the timeline, minimalis blog

Layout lebih awal sudah berubah total, awalnya hanya pure long notes jadi semua notes akan muncul dari yang terbaru sampai terlama, kemudian tidak ada navbar yang sticky hanya ada icon blog di kiri dan jam di kanan.

Lalu berubah jadi navbar sticky dengan icon blog di kiri dan jam di kanan dan ditambah sticky tag togle yang bisa scrolling ke horizontal untuk menghemat ruang.

Fitur tag dinamis, begitu tag baru muncul dri post artikel maka tag togle yang baru akan muncul seketika, ini bisa jadi saringan kedua dalam blog untuk menyaring blog post hanya untuk topic dengan tag yang sama.

Saringan pertama adalah fitur pencarian di tengah navbar yang sticky dan ya itu juga fitur baru yang saya tambah. Jadi ketik kata apapun kalau kata tersebut sebut ada di judul atau isi artikel maka akan muncul post artikel tersebut.

Berikut adalah potongan kode — fungsi filter + search:

function matchNote(note) {
  const query = searchInput.value.trim().toLowerCase();
  const noteTags = (note.dataset.tags || '').split(',').map(function(t) {
    return t.trim().replace(/^#/, '');
  }).filter(Boolean);
  const tagMatch = (activeTag === null) || noteTags.includes(activeTag);

  let searchMatch = true;
  if (query !== '') {
    const textPool = (note.innerText || '').toLowerCase();
    searchMatch = textPool.includes(query);
  }
  return tagMatch && searchMatch;
}

Apakah akan berat karena blog punya layout long notes tanpa url unik tiap post dengan fitur pencarian dan tag dinamis ini? Tidak (insyaallah).

Karena blog ini dibatasi hanya me-render 12 post diawal lalu kalau sudah mau masuk ke post 12 makan akan render lagi 8 post (Infinite scroll atau lazy load notes), Menggunakan IntersectionObserver dengan root Margin: 400px untuk preload.

const sentinel = document.getElementById('load-sentinel');
if ('IntersectionObserver' in window && sentinel) {
  const loadObserver = new IntersectionObserver(function(entries) {
    if (entries[0].isIntersecting && pool.length > 0) {
      revealNext(BATCH);
      applyFilter();
    }
  }, { rootMargin: '400px 0px' });
  loadObserver.observe(sentinel);
}

Di blog ini juga sudah ada lazy loading untuk Gambar jadi gambar dalam konten tidak langsung dimuat, src dipindahkan ke data-src dan observer memuatnya saat hampir masuk viewport lalu dilengkapi pula dengan native loading=lazy sebagai fallback. Serta sedikit animasi transisi opasitas saat gambar selesai dimuat.

document.querySelectorAll('.content img').forEach(function(img) {
  if (!img.src) return;
  img.alt = img.alt || '';            // aksesibilitas
  img.loading = 'lazy';               // fallback native
  img.dataset.src = img.src;
  img.removeAttribute('src');
  img.classList.add('img-lazy');
  if (lazyImgObserver) lazyImgObserver.observe(img);
  else { img.src = img.dataset.src; }
});

Sudah ada meta tag, meta description, open graph yanga mana itu adalah standar industri. Serta menyimpan setting warna di root jadi memudahkan kalau suatu saat mau ganti warna. Untuk pewarnaan code saya pakai css highlights.js dengan tema github-dark.

Jam diletakan dipaling atas script agar langsung muncul instan tanpa menunggu DOMContentLoaded, lalu disusul tag togle dan script sisanya mengikuti. Script kecil inline untuk jam langsung memperbarui setiap detik.

```html
<span id="clock"></span>
<script>
  (function() {
    function tick() {
      const n = new Date();
      document.getElementById('clock').textContent =
        String(n.getHours()).padStart(2,'0') + ':' +
        String(n.getMinutes()).padStart(2,'0') + ':' +
        String(n.getSeconds()).padStart(2,'0');
    }
    tick();
    setInterval(tick, 1000);
  })();
</script>

Design yang responsif & Fluid Typography yang bisa di capai dengan lebar konten dibatasi dengan max-width 680px dalam satuan rem. Ukuran font menggunakan clamp() agar menyesuaikan layar dari user serta breakpoint media query menggunakan satuan em (bukan px) sesuai standar aksesibilitas.

body {
  font-size: clamp(0.875rem, 0.82rem + 0.25vw, 1rem);
  max-width: var(--max-content-width);
  padding: 0 1.25rem 5rem;
}

@media (max-width: 25em) {
  .aff-card { font-size: 0.7rem; }
}

Untuk desain & aksesibilitas yang lebih baik lagi saya pakai kontras teks yang memenuhi WCAG AA (rasio >4.5:1) serta og ini sudah menghormati preferensi pengguna seperti: jika sistem mengaktifkan reduced motion, semua animasi dan transisi dimatikan.

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

Saya merubah blog ini dari pure html ke Eleventy yang static (ya walau hasil akhir juga pure html tanpa database) karena ingin menulis via markdown (saya bukan lulusan Dev asli) yang lumayan simple itu.

Jadi saya menulis di Github apps yang sudah cukup untuk but post baru dan update kode yang simple. Untuk kode disimpan di Github lalu blog ini di hosting di Netlify (CDN) jadi total biaya yang saya keluarkan untuk blog ini adalah nol rupiah.

Sekian dulu nanti kalau ada tambahan saya update lagi insyaallah.