/* ── Utilitas Invitnesia (inv-*) ────────────────────────────────
   Framework utilitas custom untuk markup layout & section body — dibuat
   sendiri, bukan Bootstrap. Prefix `inv-` sengaja dipakai agar tidak bentrok
   dengan bootstrap.css yang juga di-load, dan supaya jelas ini milik engine
   tema sendiri.

   Prinsip:
   · Satu kelas = satu pekerjaan (spacing, ukuran teks, warna, dll).
   · Nilai memakai CSS custom property tema (--inv-*, --font-*, --menu-*) —
     bukan warna menggantung — sehingga peka terhadap tema yang sedang aktif.
   · Class pemakaian-padat memakai `!important` supaya menang atas aturan
     komponen/konten tanpa perang specificity (pola sama dgn Bootstrap).
   · Animasi memakai keyframes sendiri (inv-anim-*) — tidak bergantung pada
     plugin Animate.css.

   Dipakai oleh: editor layout & section (autocomplete layout-snippets.ts),
   halaman tamu, dan kedua preview editor. Dimuat via AssetVersion::url.
   Dokumentasi lengkap: resources/views/admin/theme-documentation.blade.php.
   ────────────────────────────────────────────────────────────── */

/* Basis skala utilitas. --inv-util-spacer ikut dipakai documentasi sebagai
   referensi jarak; nilai default setara Bootstrap (0.25rem per langkah). */
:root {
    --inv-util-spacer: 0.25rem;
}

/* ── Spacing (margin & padding) ─────────────────────────────────
   Skala: 0=0, 1=0.25rem, 2=0.5rem, 3=1rem, 4=1.5rem, 5=3rem.
   Arah: t=top, b=bottom, s=start (kiri), e=end (kanan), x=kir-kanan, y=atas-bawah. */
.inv-m-0 { margin: 0 !important; }
.inv-m-1 { margin: calc(var(--inv-util-spacer) * 1) !important; }
.inv-m-2 { margin: calc(var(--inv-util-spacer) * 2) !important; }
.inv-m-3 { margin: calc(var(--inv-util-spacer) * 4) !important; }
.inv-m-4 { margin: calc(var(--inv-util-spacer) * 6) !important; }
.inv-m-5 { margin: calc(var(--inv-util-spacer) * 12) !important; }
.inv-mt-0 { margin-top: 0 !important; }
.inv-mt-1 { margin-top: calc(var(--inv-util-spacer) * 1) !important; }
.inv-mt-2 { margin-top: calc(var(--inv-util-spacer) * 2) !important; }
.inv-mt-3 { margin-top: calc(var(--inv-util-spacer) * 4) !important; }
.inv-mt-4 { margin-top: calc(var(--inv-util-spacer) * 6) !important; }
.inv-mt-5 { margin-top: calc(var(--inv-util-spacer) * 12) !important; }
.inv-mb-0 { margin-bottom: 0 !important; }
.inv-mb-1 { margin-bottom: calc(var(--inv-util-spacer) * 1) !important; }
.inv-mb-2 { margin-bottom: calc(var(--inv-util-spacer) * 2) !important; }
.inv-mb-3 { margin-bottom: calc(var(--inv-util-spacer) * 4) !important; }
.inv-mb-4 { margin-bottom: calc(var(--inv-util-spacer) * 6) !important; }
.inv-mb-5 { margin-bottom: calc(var(--inv-util-spacer) * 12) !important; }
.inv-ms-0 { margin-left: 0 !important; }
.inv-ms-1 { margin-left: calc(var(--inv-util-spacer) * 1) !important; }
.inv-ms-2 { margin-left: calc(var(--inv-util-spacer) * 2) !important; }
.inv-ms-3 { margin-left: calc(var(--inv-util-spacer) * 4) !important; }
.inv-ms-4 { margin-left: calc(var(--inv-util-spacer) * 6) !important; }
.inv-ms-5 { margin-left: calc(var(--inv-util-spacer) * 12) !important; }
.inv-me-0 { margin-right: 0 !important; }
.inv-me-1 { margin-right: calc(var(--inv-util-spacer) * 1) !important; }
.inv-me-2 { margin-right: calc(var(--inv-util-spacer) * 2) !important; }
.inv-me-3 { margin-right: calc(var(--inv-util-spacer) * 4) !important; }
.inv-me-4 { margin-right: calc(var(--inv-util-spacer) * 6) !important; }
.inv-me-5 { margin-right: calc(var(--inv-util-spacer) * 12) !important; }
.inv-mx-0 { margin-left: 0 !important; margin-right: 0 !important; }
.inv-mx-1 { margin-left: calc(var(--inv-util-spacer) * 1) !important; margin-right: calc(var(--inv-util-spacer) * 1) !important; }
.inv-mx-2 { margin-left: calc(var(--inv-util-spacer) * 2) !important; margin-right: calc(var(--inv-util-spacer) * 2) !important; }
.inv-mx-3 { margin-left: calc(var(--inv-util-spacer) * 4) !important; margin-right: calc(var(--inv-util-spacer) * 4) !important; }
.inv-mx-4 { margin-left: calc(var(--inv-util-spacer) * 6) !important; margin-right: calc(var(--inv-util-spacer) * 6) !important; }
.inv-mx-5 { margin-left: calc(var(--inv-util-spacer) * 12) !important; margin-right: calc(var(--inv-util-spacer) * 12) !important; }
.inv-mx-auto { margin-left: auto !important; margin-right: auto !important; }
.inv-my-0 { margin-top: 0 !important; margin-bottom: 0 !important; }
.inv-my-1 { margin-top: calc(var(--inv-util-spacer) * 1) !important; margin-bottom: calc(var(--inv-util-spacer) * 1) !important; }
.inv-my-2 { margin-top: calc(var(--inv-util-spacer) * 2) !important; margin-bottom: calc(var(--inv-util-spacer) * 2) !important; }
.inv-my-3 { margin-top: calc(var(--inv-util-spacer) * 4) !important; margin-bottom: calc(var(--inv-util-spacer) * 4) !important; }
.inv-my-4 { margin-top: calc(var(--inv-util-spacer) * 6) !important; margin-bottom: calc(var(--inv-util-spacer) * 6) !important; }
.inv-my-5 { margin-top: calc(var(--inv-util-spacer) * 12) !important; margin-bottom: calc(var(--inv-util-spacer) * 12) !important; }

.inv-p-0 { padding: 0 !important; }
.inv-p-1 { padding: calc(var(--inv-util-spacer) * 1) !important; }
.inv-p-2 { padding: calc(var(--inv-util-spacer) * 2) !important; }
.inv-p-3 { padding: calc(var(--inv-util-spacer) * 4) !important; }
.inv-p-4 { padding: calc(var(--inv-util-spacer) * 6) !important; }
.inv-p-5 { padding: calc(var(--inv-util-spacer) * 12) !important; }
.inv-pt-0 { padding-top: 0 !important; }
.inv-pt-1 { padding-top: calc(var(--inv-util-spacer) * 1) !important; }
.inv-pt-2 { padding-top: calc(var(--inv-util-spacer) * 2) !important; }
.inv-pt-3 { padding-top: calc(var(--inv-util-spacer) * 4) !important; }
.inv-pt-4 { padding-top: calc(var(--inv-util-spacer) * 6) !important; }
.inv-pt-5 { padding-top: calc(var(--inv-util-spacer) * 12) !important; }
.inv-pb-0 { padding-bottom: 0 !important; }
.inv-pb-1 { padding-bottom: calc(var(--inv-util-spacer) * 1) !important; }
.inv-pb-2 { padding-bottom: calc(var(--inv-util-spacer) * 2) !important; }
.inv-pb-3 { padding-bottom: calc(var(--inv-util-spacer) * 4) !important; }
.inv-pb-4 { padding-bottom: calc(var(--inv-util-spacer) * 6) !important; }
.inv-pb-5 { padding-bottom: calc(var(--inv-util-spacer) * 12) !important; }
.inv-ps-0 { padding-left: 0 !important; }
.inv-ps-1 { padding-left: calc(var(--inv-util-spacer) * 1) !important; }
.inv-ps-2 { padding-left: calc(var(--inv-util-spacer) * 2) !important; }
.inv-ps-3 { padding-left: calc(var(--inv-util-spacer) * 4) !important; }
.inv-ps-4 { padding-left: calc(var(--inv-util-spacer) * 6) !important; }
.inv-ps-5 { padding-left: calc(var(--inv-util-spacer) * 12) !important; }
.inv-pe-0 { padding-right: 0 !important; }
.inv-pe-1 { padding-right: calc(var(--inv-util-spacer) * 1) !important; }
.inv-pe-2 { padding-right: calc(var(--inv-util-spacer) * 2) !important; }
.inv-pe-3 { padding-right: calc(var(--inv-util-spacer) * 4) !important; }
.inv-pe-4 { padding-right: calc(var(--inv-util-spacer) * 6) !important; }
.inv-pe-5 { padding-right: calc(var(--inv-util-spacer) * 12) !important; }
.inv-px-0 { padding-left: 0 !important; padding-right: 0 !important; }
.inv-px-1 { padding-left: calc(var(--inv-util-spacer) * 1) !important; padding-right: calc(var(--inv-util-spacer) * 1) !important; }
.inv-px-2 { padding-left: calc(var(--inv-util-spacer) * 2) !important; padding-right: calc(var(--inv-util-spacer) * 2) !important; }
.inv-px-3 { padding-left: calc(var(--inv-util-spacer) * 4) !important; padding-right: calc(var(--inv-util-spacer) * 4) !important; }
.inv-px-4 { padding-left: calc(var(--inv-util-spacer) * 6) !important; padding-right: calc(var(--inv-util-spacer) * 6) !important; }
.inv-px-5 { padding-left: calc(var(--inv-util-spacer) * 12) !important; padding-right: calc(var(--inv-util-spacer) * 12) !important; }
.inv-py-0 { padding-top: 0 !important; padding-bottom: 0 !important; }
.inv-py-1 { padding-top: calc(var(--inv-util-spacer) * 1) !important; padding-bottom: calc(var(--inv-util-spacer) * 1) !important; }
.inv-py-2 { padding-top: calc(var(--inv-util-spacer) * 2) !important; padding-bottom: calc(var(--inv-util-spacer) * 2) !important; }
.inv-py-3 { padding-top: calc(var(--inv-util-spacer) * 4) !important; padding-bottom: calc(var(--inv-util-spacer) * 4) !important; }
.inv-py-4 { padding-top: calc(var(--inv-util-spacer) * 6) !important; padding-bottom: calc(var(--inv-util-spacer) * 6) !important; }
.inv-py-5 { padding-top: calc(var(--inv-util-spacer) * 12) !important; padding-bottom: calc(var(--inv-util-spacer) * 12) !important; }

/* ── Ukuran teks (font-size) ────────────────────────────────────
   Skala berbasis rem, diukur terhadap ukuran dasar undangan. */
.inv-fs-xs { font-size: 0.75rem !important; }
.inv-fs-sm { font-size: 0.875rem !important; }
.inv-fs-base { font-size: 1rem !important; }
.inv-fs-md { font-size: 1.125rem !important; }
.inv-fs-lg { font-size: 1.25rem !important; }
.inv-fs-xl { font-size: 1.5rem !important; }
.inv-fs-2xl { font-size: 1.875rem !important; }
.inv-fs-3xl { font-size: 2.25rem !important; }
.inv-fs-4xl { font-size: 3rem !important; }
.inv-fs-5xl { font-size: 3.75rem !important; }

/* ── Ketebalan huruf (font-weight) ────────────────────────────── */
.inv-fw-light { font-weight: 300 !important; }
.inv-fw-normal { font-weight: 400 !important; }
.inv-fw-medium { font-weight: 500 !important; }
.inv-fw-semibold { font-weight: 600 !important; }
.inv-fw-bold { font-weight: 700 !important; }
.inv-fw-bolder { font-weight: bolder !important; }

/* ── Perataan teks (text-align) ───────────────────────────────── */
.inv-text-start { text-align: left !important; }
.inv-text-center { text-align: center !important; }
.inv-text-end { text-align: right !important; }

/* ── Warna teks & latar ─────────────────────────────────────────
   Warna mengambang di atas token tema, jadi ikut berubah saat tema
   diganti. inv-text-surface = warna untuk teks di atas permukaan aksen. */
.inv-text-base { color: var(--inv-base) !important; }
.inv-text-accent { color: var(--inv-accent) !important; }
.inv-text-muted { color: color-mix(in srgb, var(--inv-base) 60%, transparent) !important; }
.inv-text-surface { color: var(--btn-color) !important; }
.inv-bg-accent { background-color: var(--inv-accent) !important; color: var(--btn-color) !important; }
.inv-bg-surface { background-color: var(--btn-color) !important; color: var(--inv-base) !important; }
.inv-bg-base { background-color: var(--inv-base) !important; color: var(--inv-bg) !important; }
.inv-bg-transparent { background-color: transparent !important; }

/* ── Sudut membulat ───────────────────────────────────────────── */
.inv-rounded-0 { border-radius: 0 !important; }
.inv-rounded-sm { border-radius: 0.25rem !important; }
.inv-rounded { border-radius: 0.375rem !important; }
.inv-rounded-lg { border-radius: 0.75rem !important; }
.inv-rounded-xl { border-radius: 1rem !important; }
.inv-rounded-pill { border-radius: 50rem !important; }
.inv-rounded-circle { border-radius: 50% !important; }

/* ── Tampilan (display) ───────────────────────────────────────── */
.inv-d-none { display: none !important; }
.inv-d-inline { display: inline !important; }
.inv-d-inline-block { display: inline-block !important; }
.inv-d-block { display: block !important; }
.inv-d-grid { display: grid !important; }
.inv-d-table { display: table !important; }
.inv-d-table-cell { display: table-cell !important; }
.inv-d-flex { display: flex !important; }
.inv-d-inline-flex { display: inline-flex !important; }

/* ── Flexbox ──────────────────────────────────────────────────── */
.inv-flex-row { flex-direction: row !important; }
.inv-flex-row-reverse { flex-direction: row-reverse !important; }
.inv-flex-column { flex-direction: column !important; }
.inv-flex-column-reverse { flex-direction: column-reverse !important; }
.inv-flex-fill { flex: 1 1 auto !important; }
.inv-flex-wrap { flex-wrap: wrap !important; }
.inv-flex-nowrap { flex-wrap: nowrap !important; }

.inv-justify-start { justify-content: flex-start !important; }
.inv-justify-end { justify-content: flex-end !important; }
.inv-justify-center { justify-content: center !important; }
.inv-justify-between { justify-content: space-between !important; }
.inv-justify-around { justify-content: space-around !important; }
.inv-justify-evenly { justify-content: space-evenly !important; }

.inv-items-start { align-items: flex-start !important; }
.inv-items-end { align-items: flex-end !important; }
.inv-items-center { align-items: center !important; }
.inv-items-baseline { align-items: baseline !important; }
.inv-items-stretch { align-items: stretch !important; }

.inv-align-self-start { align-self: flex-start !important; }
.inv-align-self-end { align-self: flex-end !important; }
.inv-align-self-center { align-self: center !important; }

/* Jarak antar-elemen (gap) — skala sama dengan spacing. */
.inv-gap-0 { gap: 0 !important; }
.inv-gap-1 { gap: calc(var(--inv-util-spacer) * 1) !important; }
.inv-gap-2 { gap: calc(var(--inv-util-spacer) * 2) !important; }
.inv-gap-3 { gap: calc(var(--inv-util-spacer) * 4) !important; }
.inv-gap-4 { gap: calc(var(--inv-util-spacer) * 6) !important; }
.inv-gap-5 { gap: calc(var(--inv-util-spacer) * 12) !important; }

/* ── Posisi & lapisan ─────────────────────────────────────────── */
.inv-pos-static { position: static !important; }
.inv-pos-relative { position: relative !important; }
.inv-pos-absolute { position: absolute !important; }
.inv-pos-fixed { position: fixed !important; }
.inv-pos-sticky { position: sticky !important; }
.inv-top-0 { top: 0 !important; }
.inv-end-0 { right: 0 !important; }
.inv-bottom-0 { bottom: 0 !important; }
.inv-start-0 { left: 0 !important; }
.inv-z-1 { z-index: 1 !important; }
.inv-z-2 { z-index: 2 !important; }
.inv-z-10 { z-index: 10 !important; }
.inv-z-999 { z-index: 999 !important; }

/* ── Lebar & tinggi ───────────────────────────────────────────── */
.inv-w-25 { width: 25% !important; }
.inv-w-50 { width: 50% !important; }
.inv-w-75 { width: 75% !important; }
.inv-w-100 { width: 100% !important; }
.inv-w-auto { width: auto !important; }
.inv-mw-100 { max-width: 100% !important; }
.inv-h-25 { height: 25% !important; }
.inv-h-50 { height: 50% !important; }
.inv-h-75 { height: 75% !important; }
.inv-h-100 { height: 100% !important; }
.inv-h-auto { height: auto !important; }
.inv-mh-100 { max-height: 100% !important; }

/* ── Opasitas ─────────────────────────────────────────────────── */
.inv-opacity-0 { opacity: 0 !important; }
.inv-opacity-25 { opacity: 0.25 !important; }
.inv-opacity-50 { opacity: 0.5 !important; }
.inv-opacity-75 { opacity: 0.75 !important; }
.inv-opacity-100 { opacity: 1 !important; }

/* ── Bayangan ─────────────────────────────────────────────────── */
.inv-shadow-sm { box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12) !important; }
.inv-shadow { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15) !important; }
.inv-shadow-lg { box-shadow: 0 12px 28px rgba(0, 0, 0, 0.22) !important; }
.inv-shadow-none { box-shadow: none !important; }

/* ── Teks lain-lain ───────────────────────────────────────────── */
.inv-text-truncate {
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    white-space: nowrap !important;
}
.inv-text-nowrap { white-space: nowrap !important; }
.inv-text-lowercase { text-transform: lowercase !important; }
.inv-text-uppercase { text-transform: uppercase !important; }
.inv-text-capitalize { text-transform: capitalize !important; }
.inv-text-decoration-none { text-decoration: none !important; }
.inv-lh-1 { line-height: 1 !important; }
.inv-lh-sm { line-height: 1.25 !important; }
.inv-lh-base { line-height: 1.5 !important; }
.inv-lh-lg { line-height: 2 !important; }
.inv-letter-spacing { letter-spacing: 0.08em !important; }
.inv-user-select-none { user-select: none !important; }

/* ── Overflow ─────────────────────────────────────────────────── */
.inv-overflow-hidden { overflow: hidden !important; }
.inv-overflow-auto { overflow: auto !important; }
.inv-overflow-scroll { overflow: scroll !important; }
.inv-overflow-visible { overflow: visible !important; }

/* ════════════════════════════════════════════════════════════════
   ANIMASI (inv-anim-*)
   Keyframes buatan sendiri — tidak bergantung Animate.css. Semua
   .inv-anim-* berjalan dengan konfigurasi dasar yang sama (durasi,
   easing, isi), lalu bisa digeser oleh class modifier:
   · inv-anim-fast / inv-anim-slower  → ubah durasi
   · inv-anim-infinite                → ulang terus
   · inv-anim-delay-1..5              → tunda 0.1s–0.5s (step 0.1s)
   · inv-anim-ease-linear             → easing linier
   ════════════════════════════════════════════════════════════════ */

@keyframes inv-fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}
@keyframes inv-fade-in-up {
    from { opacity: 0; transform: translateY(calc(var(--inv-anim-shift, 24px) * 1)); }
    to { opacity: 1; transform: none; }
}
@keyframes inv-fade-in-down {
    from { opacity: 0; transform: translateY(calc(var(--inv-anim-shift, 24px) * -1)); }
    to { opacity: 1; transform: none; }
}
@keyframes inv-fade-in-left {
    from { opacity: 0; transform: translateX(calc(var(--inv-anim-shift, 24px) * 1)); }
    to { opacity: 1; transform: none; }
}
@keyframes inv-fade-in-right {
    from { opacity: 0; transform: translateX(calc(var(--inv-anim-shift, 24px) * -1)); }
    to { opacity: 1; transform: none; }
}
@keyframes inv-zoom-in {
    from { opacity: 0; transform: scale(0.6); }
    to { opacity: 1; transform: none; }
}
@keyframes inv-zoom-in-soft {
    from { opacity: 0; transform: scale(0.9); }
    to { opacity: 1; transform: none; }
}
@keyframes inv-slide-in-up {
    from { opacity: 0; transform: translateY(100%); }
    to { opacity: 1; transform: none; }
}
@keyframes inv-slide-in-down {
    from { opacity: 0; transform: translateY(-100%); }
    to { opacity: 1; transform: none; }
}
@keyframes inv-slide-in-left {
    from { opacity: 0; transform: translateX(100%); }
    to { opacity: 1; transform: none; }
}
@keyframes inv-slide-in-right {
    from { opacity: 0; transform: translateX(-100%); }
    to { opacity: 1; transform: none; }
}
@keyframes inv-flip-in {
    from { opacity: 0; transform: perspective(400px) rotateY(90deg) scale(0.8); }
    to { opacity: 1; transform: none; }
}
@keyframes inv-rotate-in {
    from { opacity: 0; transform: rotate(-200deg); }
    to { opacity: 1; transform: none; }
}
@keyframes inv-bounce {
    0%, 100% { transform: none; }
    30% { transform: translateY(-18%); }
    50% { transform: none; }
    70% { transform: translateY(-9%); }
    90% { transform: none; }
}
@keyframes inv-pulse {
    0%, 100% { transform: none; }
    50% { transform: scale(1.06); }
}
@keyframes inv-shake {
    0%, 100% { transform: none; }
    20% { transform: translateX(-8%); }
    40% { transform: translateX(8%); }
    60% { transform: translateX(-5%); }
    80% { transform: translateX(5%); }
}
@keyframes inv-swing {
    20% { transform: rotate(15deg); }
    40% { transform: rotate(-10deg); }
    60% { transform: rotate(5deg); }
    80% { transform: rotate(-5deg); }
    100% { transform: none; }
}
@keyframes inv-float {
    0%, 100% { transform: none; }
    50% { transform: translateY(-18%); }
}
@keyframes inv-twinkle {
    0%, 100% { opacity: 1; transform: none; }
    50% { opacity: 0.25; transform: scale(0.85); }
}
@keyframes inv-blink {
    0%, 49% { opacity: 1; }
    50%, 100% { opacity: 0; }
}
@keyframes inv-spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}
@keyframes inv-heartbeat {
    0%, 28%, 70%, 100% { transform: scale(1); }
    14%, 42% { transform: scale(1.15); }
}

@keyframes inv-sway {
    0%, 100% { transform: rotate(-6deg); }
    50% { transform: rotate(6deg); }
}
@keyframes inv-sway-x {
    0%, 100% { transform: translateX(-14%) rotate(-3deg); }
    50% { transform: translateX(14%) rotate(3deg); }
}
@keyframes inv-sway-x-soft {
    0%, 100% { transform: translateX(-8%) rotate(-2deg); }
    50% { transform: translateX(8%) rotate(2deg); }
}
@keyframes inv-sway-soft {
    0%, 100% { transform: rotate(-3deg); }
    50% { transform: rotate(3deg); }
}
/* Sway diagonal berporos pada sudut — daun tertiup angin. arah = sudut tempat
   elemen berporos (tl/tr/bl/br). Dipadukan dengan inv-anim-infinite. */
@keyframes inv-sway-tl {
    0%, 100% { transform: translate(-10%, -8%) rotate(-10deg) scaleY(0.97); }
    50% { transform: translate(8%, 6%) rotate(8deg) scaleY(1.02); }
}
@keyframes inv-sway-tr {
    0%, 100% { transform: translate(10%, -8%) rotate(10deg) scaleY(0.97); }
    50% { transform: translate(-8%, 6%) rotate(-8deg) scaleY(1.02); }
}
@keyframes inv-sway-bl {
    0%, 100% { transform: translate(-8%, 8%) rotate(-8deg) scaleY(0.97); }
    50% { transform: translate(8%, -6%) rotate(10deg) scaleY(1.02); }
}
@keyframes inv-sway-br {
    0%, 100% { transform: translate(8%, 8%) rotate(8deg) scaleY(0.97); }
    50% { transform: translate(-8%, -6%) rotate(-10deg) scaleY(1.02); }
}
@keyframes inv-wiggle {
    0%, 100% { transform: rotate(-8deg) translateX(-2%); }
    25% { transform: rotate(8deg) translateX(2%); }
    50% { transform: rotate(-6deg) translateX(-1%); }
    75% { transform: rotate(6deg) translateX(1%); }
}
@keyframes inv-bob {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-12%); }
}
@keyframes inv-grow {
    0% { opacity: 0; transform: scale(0); }
    70% { opacity: 1; transform: scale(1.12); }
    100% { opacity: 1; transform: scale(1); }
}
@keyframes inv-pop {
    0% { opacity: 0; transform: scale(0.4); }
    60% { opacity: 1; transform: scale(1.15); }
    80% { transform: scale(0.94); }
    100% { opacity: 1; transform: scale(1); }
}
@keyframes inv-tada {
    0%, 100% { transform: scale(1) rotate(0); }
    10%, 20% { transform: scale(0.9) rotate(-3deg); }
    30%, 50%, 70%, 90% { transform: scale(1.1) rotate(3deg); }
    40%, 60%, 80% { transform: scale(1.1) rotate(-3deg); }
}
@keyframes inv-jello {
    0%, 100% { transform: none; }
    22% { transform: skewX(-8deg) skewY(-4deg); }
    44% { transform: skewX(6deg) skewY(3deg); }
    66% { transform: skewX(-3deg) skewY(-2deg); }
    88% { transform: skewX(3deg) skewY(1deg); }
}
@keyframes inv-dance {
    0%, 100% { transform: rotate(0) translateX(0); }
    15% { transform: rotate(-8deg) translateX(-12%); }
    35% { transform: rotate(7deg) translateX(10%); }
    55% { transform: rotate(-6deg) translateX(-8%); }
    75% { transform: rotate(5deg) translateX(6%); }
    90% { transform: rotate(-2deg) translateX(-3%); }
}
@keyframes inv-flip-in-y {
    from { opacity: 0; transform: perspective(400px) rotateX(90deg); }
    to { opacity: 1; transform: none; }
}

.inv-anim-fade-in,
.inv-anim-fade-in-up,
.inv-anim-fade-in-down,
.inv-anim-fade-in-left,
.inv-anim-fade-in-right,
.inv-anim-zoom-in,
.inv-anim-zoom-in-soft,
.inv-anim-slide-in-up,
.inv-anim-slide-in-down,
.inv-anim-slide-in-left,
.inv-anim-slide-in-right,
.inv-anim-flip-in,
.inv-anim-rotate-in,
.inv-anim-bounce,
.inv-anim-pulse,
.inv-anim-shake,
.inv-anim-swing,
.inv-anim-float,
.inv-anim-twinkle,
.inv-anim-blink,
.inv-anim-spin,
.inv-anim-heartbeat,
.inv-anim-sway,
.inv-anim-sway-x,
.inv-anim-sway-x-soft,
.inv-anim-sway-soft,
.inv-anim-sway-tl,
.inv-anim-sway-tr,
.inv-anim-sway-bl,
.inv-anim-sway-br,
.inv-anim-wiggle,
.inv-anim-bob,
.inv-anim-grow,
.inv-anim-pop,
.inv-anim-tada,
.inv-anim-jello,
.inv-anim-dance,
.inv-anim-flip-in-y {
    animation-duration: var(--inv-anim-duration, 0.9s);
    animation-timing-function: var(--inv-anim-ease, ease-in-out);
    animation-fill-mode: both;
    /* Animasi masuk (entrance) default: sekali jalan lalu berhenti.
       Elemen di luar canvas tetap punya transform dari keyframes. */
    animation-iteration-count: 1;
}

.inv-anim-fade-in { animation-name: inv-fade-in; }
.inv-anim-fade-in-up { animation-name: inv-fade-in-up; }
.inv-anim-fade-in-down { animation-name: inv-fade-in-down; }
.inv-anim-fade-in-left { animation-name: inv-fade-in-left; }
.inv-anim-fade-in-right { animation-name: inv-fade-in-right; }
.inv-anim-zoom-in { animation-name: inv-zoom-in; }
.inv-anim-zoom-in-soft { animation-name: inv-zoom-in-soft; }
.inv-anim-slide-in-up { animation-name: inv-slide-in-up; }
.inv-anim-slide-in-down { animation-name: inv-slide-in-down; }
.inv-anim-slide-in-left { animation-name: inv-slide-in-left; }
.inv-anim-slide-in-right { animation-name: inv-slide-in-right; }
.inv-anim-flip-in { animation-name: inv-flip-in; }
.inv-anim-rotate-in { animation-name: inv-rotate-in; }
.inv-anim-bounce { animation-name: inv-bounce; }
.inv-anim-pulse { animation-name: inv-pulse; }
.inv-anim-shake { animation-name: inv-shake; }
.inv-anim-swing { animation-name: inv-swing; }
.inv-anim-float { animation-name: inv-float; }
.inv-anim-twinkle { animation-name: inv-twinkle; }
.inv-anim-blink { animation-name: inv-blink; }
.inv-anim-spin { animation-name: inv-spin; }
.inv-anim-heartbeat { animation-name: inv-heartbeat; }
.inv-anim-sway { animation-name: inv-sway; transform-origin: 50% 100%; }
.inv-anim-sway-x { animation-name: inv-sway-x; transform-origin: 50% 100%; }
.inv-anim-sway-x-soft { animation-name: inv-sway-x-soft; transform-origin: 50% 100%; }
.inv-anim-sway-soft { animation-name: inv-sway-soft; transform-origin: 50% 100%; }
.inv-anim-sway-tl { animation-name: inv-sway-tl; transform-origin: 0% 0%; }
.inv-anim-sway-tr { animation-name: inv-sway-tr; transform-origin: 100% 0%; }
.inv-anim-sway-bl { animation-name: inv-sway-bl; transform-origin: 0% 100%; }
.inv-anim-sway-br { animation-name: inv-sway-br; transform-origin: 100% 100%; }
.inv-anim-wiggle { animation-name: inv-wiggle; transform-origin: 50% 100%; }
.inv-anim-bob { animation-name: inv-bob; }
.inv-anim-grow { animation-name: inv-grow; }
.inv-anim-pop { animation-name: inv-pop; }
.inv-anim-tada { animation-name: inv-tada; }
.inv-anim-jello { animation-name: inv-jello; }
.inv-anim-dance { animation-name: inv-dance; }
.inv-anim-flip-in-y { animation-name: inv-flip-in-y; }

/* Modifier durasi & pengulangan. */
.inv-anim-fast { --inv-anim-duration: 0.4s !important; }
.inv-anim-slower { --inv-anim-duration: 1.6s !important; }
.inv-anim-infinite { animation-iteration-count: infinite !important; }
/* Bolak-balik halus: animasi maju lalu mundur tanpa loncatan di titik balik.
   Paling enak dipakai bersama inv-anim-infinite (ornamen kiri-kanan). */
.inv-anim-alternate { animation-direction: alternate !important; }
.inv-anim-ease-linear { --inv-anim-ease: linear !important; }

/* Penundaan masuk berjenjang (stagger) — 0.1s per langkah. */
.inv-anim-delay-1 { animation-delay: 0.1s !important; }
.inv-anim-delay-2 { animation-delay: 0.2s !important; }
.inv-anim-delay-3 { animation-delay: 0.3s !important; }
.inv-anim-delay-4 { animation-delay: 0.4s !important; }
.inv-anim-delay-5 { animation-delay: 0.5s !important; }

/* Aksesibilitas: pengguna yang meminta gerakan minim melihat konten
   langsung, tanpa animasi transit. Delay tetap nol (fill-mode both
   pada delay bisa menyembunyikan elemen sebelum mulai). */
@media (prefers-reduced-motion: reduce) {
    .inv-anim-fade-in,
    .inv-anim-fade-in-up,
    .inv-anim-fade-in-down,
    .inv-anim-fade-in-left,
    .inv-anim-fade-in-right,
    .inv-anim-zoom-in,
    .inv-anim-zoom-in-soft,
    .inv-anim-slide-in-up,
    .inv-anim-slide-in-down,
    .inv-anim-slide-in-left,
    .inv-anim-slide-in-right,
    .inv-anim-flip-in,
    .inv-anim-rotate-in,
    .inv-anim-bounce,
    .inv-anim-pulse,
    .inv-anim-shake,
    .inv-anim-swing,
    .inv-anim-float,
    .inv-anim-twinkle,
    .inv-anim-blink,
    .inv-anim-spin,
    .inv-anim-heartbeat,
    .inv-anim-sway,
    .inv-anim-sway-x,
    .inv-anim-sway-x-soft,
    .inv-anim-sway-soft,
    .inv-anim-sway-tl,
    .inv-anim-sway-tr,
    .inv-anim-sway-bl,
    .inv-anim-sway-br,
    .inv-anim-wiggle,
    .inv-anim-bob,
    .inv-anim-grow,
    .inv-anim-pop,
    .inv-anim-tada,
    .inv-anim-jello,
    .inv-anim-dance,
    .inv-anim-flip-in-y {
        animation: none !important;
    }
}