/* Dunia Anura — shared site styles.
   Tokens come from ds/styles.css; this file carries page behaviour styles:
   keyframes, hover states, nav
   responsiveness, and small-screen layout fixes. */

html { overflow-x: clip; }
body { margin: 0; overflow-x: clip; }
[data-reveal] { opacity: 0; }
html.no-motion [data-reveal] { opacity: 1; }

/* — scrollbars — */
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--color-accent-300); border-radius: 999px; border: 2px solid var(--color-bg); }
::-webkit-scrollbar-thumb:hover { background: var(--color-accent-500); }
aside::-webkit-scrollbar { width: 6px; }
aside::-webkit-scrollbar-thumb { border: none; }
* { scrollbar-width: thin; scrollbar-color: var(--color-accent-300) transparent; }
/* Phones and tablets (<=940): no drawn scrollbars at all. The green thumb sat as a
   bar down the side of every inner scroller — the account menu, the filter sheets —
   and touch screens do not need one; the page's own bar is the overlay the OS draws. */
@media (max-width: 940px) {
  * { scrollbar-width: none; }
  *::-webkit-scrollbar { display: none; width: 0; height: 0; }
}

a { text-decoration: none; color: var(--color-accent-700); }
a:hover { color: var(--color-accent); }

/* — keyframes — */
@keyframes marq { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes floaty { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-16px) rotate(2deg); } }
@keyframes floaty2 { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(14px); } }
@keyframes spinSlow { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes blobMorph { 0%, 100% { border-radius: 58% 42% 55% 45%/50% 58% 42% 50%; } 33% { border-radius: 45% 55% 48% 52%/58% 44% 56% 42%; } 66% { border-radius: 52% 48% 60% 40%/45% 55% 45% 55%; } }
@keyframes drift1 { 0%, 100% { transform: translate(0, 0) scale(1); } 50% { transform: translate(10vw, 7vh) scale(1.25); } }
@keyframes drift2 { 0%, 100% { transform: translate(0, 0) scale(1); } 33% { transform: translate(-8vw, -6vh) scale(1.15); } 66% { transform: translate(4vw, -9vh) scale(.9); } }
@keyframes drift3 { 0%, 100% { transform: translate(0, 0) scale(1); } 50% { transform: translate(-9vw, 8vh) scale(1.3); } }
@keyframes cartIn { from { transform: translateX(44px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes ringPulse { 0%, 100% { transform: scale(1); opacity: .85; } 50% { transform: scale(1.055); opacity: .35; } }
@keyframes ringPulse2 { 0%, 100% { transform: scale(1); opacity: .5; } 50% { transform: scale(1.09); opacity: .15; } }
@keyframes spin { to { transform: rotate(360deg); } }

/* — buttons — */
.btn, button.btn { transition: transform .35s cubic-bezier(.22, 1, .36, 1), box-shadow .35s ease, background-color .3s ease, color .3s ease, border-color .3s ease; }
.btn:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.btn:active { transform: translateY(-1px) scale(.95); transition-duration: .12s; box-shadow: var(--shadow-sm); }
.btn-cta { position: relative; overflow: hidden; }
.btn-cta .shine { position: absolute; top: 0; bottom: 0; left: -45%; width: 45%; background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .5), transparent); transform: skewX(-20deg); transition: left .65s cubic-bezier(.22, 1, .36, 1); pointer-events: none; }
.btn-cta:hover .shine { left: 115%; }
.btn-cta:hover { transform: translateY(-3px) scale(1.03); box-shadow: var(--shadow-lg); }
.btn-cta:active { transform: translateY(0) scale(.92); transition-duration: .1s; box-shadow: var(--shadow-sm); }
.btn-cta .arr { display: inline-flex; transition: transform .35s cubic-bezier(.22, 1, .36, 1); }
.btn-cta:hover .arr { transform: translateX(4px); }
a.btn-primary:hover, a.btn-primary:active { color: var(--color-neutral-100); }
.wa-white:hover { background: var(--color-accent-100) !important; }
.cta-outline:hover { background: var(--color-accent-600) !important; }

/* — tags — */
.tag { transition: transform .3s cubic-bezier(.22, 1, .36, 1), background-color .3s ease, color .3s ease; }
.tag:hover { transform: translateY(-2px) rotate(-1deg); }

/* — nav — */
nav.da-nav { width: max-content; max-width: calc(100vw - 24px); z-index: 60; }
/* while the phone menu or the account menu hangs from the pill, the pill goes
   above Dara (#daChat is 180) and stays under the cart drawer (230). z-index
   left the nav's style attribute for this: a class cannot beat an inline value. */
nav.da-nav.is-open { z-index: 200; }
nav a { transition: color .25s ease, transform .3s cubic-bezier(.22, 1, .36, 1); }
nav a:active { transform: scale(.95); }
.nav-link { color: var(--color-text); }
.nav-link:hover { color: var(--color-accent); }
body[data-page="home"] .nav-link[data-nav="home"],
body[data-page="species"] .nav-link[data-nav="species"],
body[data-page="species-detail"] .nav-link[data-nav="species"],
body[data-page="products"] .nav-link[data-nav="products"],
body[data-page="product-detail"] .nav-link[data-nav="products"],
body[data-page="blog"] .nav-link[data-nav="blog"],
body[data-page="blog-post"] .nav-link[data-nav="blog"],
body[data-page="equipment"] .nav-link[data-nav="equipment"] { color: var(--color-accent); font-weight: 700; }
.nav-signin-btn:hover { color: var(--color-accent) !important; }
.cart-btn:hover { background: var(--color-accent-200) !important; }
.search-hit:hover { background: var(--color-accent-100); }
.lang-opt:hover { background: var(--color-accent-100); }
.lang-btn:hover { background: var(--color-accent-100) !important; }
@media (max-width: 1460px) { nav.da-nav { gap: 14px !important; } nav.da-nav .nav-links { gap: 12px !important; } nav.da-nav .nav-search input { width: 104px !important; } }
@media (max-width: 1300px) { nav.da-nav .nav-lang { display: none !important; } }  /* the nav links used to be forced down to 13.5px here, with the only font-size override of its kind on the site. The floor made it unnecessary: 14px links measure 239px inside 520px of nav slack at 1300. */
@media (max-width: 1180px) { nav.da-nav .nav-search { display: none !important; } }
@media (max-width: 1020px) { nav.da-nav .nav-signin-btn { display: none !important; } }
@media (max-width: 860px) { nav.da-nav .nav-links { display: none !important; } }
/* The menu button stands in for every block hidden above: at 861-1300 that is
   language (and search, sign-in), on a phone everything but the cart. Above
   1300 the pill is complete and the button goes. */
@media (max-width: 1300px) { nav.da-nav .nav-menu-btn { display: inline-flex; } }
@media (min-width: 1301px) { nav.da-nav .nav-sheet { display: none !important; } }   /* a sheet left open before a rotate */
/* Phone targets: the cart was 38px, the avatar chip 40x38, the logo link 34px
   tall and Adopt 41.7px — the two most-used controls sat 8px apart under the
   44px guideline. Only the cart size and the Adopt padding are inline, so only
   they need !important. The pill grows from 63.7 to 64px. */
@media (max-width: 860px) {
  nav.da-nav { gap: 8px !important; padding: 10px 10px 10px 14px !important; }
  nav.da-nav .cart-btn { width: 44px !important; height: 44px !important; }
  nav.da-nav .si-chip { padding: 7px; }                       /* 30px avatar + 14 = 44 */
  nav.da-nav .nav-cta { min-height: 44px; padding: 0 18px !important; }
  nav.da-nav > a.nav-link { min-height: 44px; }
}
/* Below 600 the pill spans the screen: as max-content it was 252px wide, and
   full-width rows scrolling under it showed their rounded ends on both sides
   at the same height. Same selector as the rule above, later, so no !important. */
@media (max-width: 600px) { nav.da-nav { width: calc(100vw - 24px); justify-content: space-between; } }
/* Signed in at 320 the pill needs 332px for logo + chip + cart + Adopt + menu
   and has 296. Adopt goes (the sheet has Species); signed out it fits and stays. */
@media (max-width: 360px) { nav.da-nav #siUser:not([hidden]) ~ .nav-cta { display: none !important; } }

/* — cards — */
.card-anim { transition: transform .45s cubic-bezier(.22, 1, .36, 1), box-shadow .45s ease; }
.card-anim:hover { transform: translateY(-8px) rotate(-.5deg); box-shadow: var(--shadow-lg); }
.card-anim .cimg { transition: transform .7s cubic-bezier(.22, 1, .36, 1), filter .5s ease; display: block; }
.card-anim:hover .cimg { transform: scale(1.07) rotate(.6deg); filter: none; }
.card-anim:hover .tag { transform: translateY(-2px) rotate(-1.5deg); }
.card-anim .btn-primary { transition: background-color .3s ease, transform .35s cubic-bezier(.22, 1, .36, 1); }
.card-anim:hover .btn-primary { background: var(--color-accent-600); transform: translateY(-2px); }
.hover-rise, .hover-rise-l, .hover-rise-r { transition: transform .45s cubic-bezier(.22, 1, .36, 1), box-shadow .45s ease; }
.hover-rise:hover { transform: translateY(-6px); box-shadow: var(--shadow-lg); }
.hover-rise-l:hover { transform: translateY(-6px) rotate(-.5deg); box-shadow: var(--shadow-lg); }
.hover-rise-r:hover { transform: translateY(-6px) rotate(.5deg); box-shadow: var(--shadow-lg); }
.zoom-tile .zimg { transition: transform .6s cubic-bezier(.22, 1, .36, 1); }
.zoom-tile:hover .zimg { transform: scale(1.05); }

/* — home specifics — */
.split-a { transition: background-color .35s ease, color .35s ease; }
.split-a:hover { background: var(--color-accent); color: var(--color-bg) !important; }
.split-b { transition: background-color .35s ease, color .35s ease; }
.split-b:hover { background: var(--color-accent-2-600); color: var(--color-bg) !important; }
.plist-row { transition: background-color .25s ease, color .25s ease; }
.plist-row:hover { background: var(--color-accent-100); color: var(--color-accent-800) !important; }
.gallery-cta { transition: background-color .3s ease, transform .45s cubic-bezier(.22, 1, .36, 1), box-shadow .45s ease, border-radius .45s cubic-bezier(.22, 1, .36, 1); }
.gallery-cta:hover { background: var(--color-accent-600) !important; transform: translateY(-6px) scale(1.02) rotate(-.6deg); box-shadow: var(--shadow-lg); border-radius: calc(var(--radius-lg)*1.4) !important; }

/* — footer — */
.foot-link { color: var(--color-accent-200); }
.foot-link:hover { color: var(--color-accent-300); }
.foot-tel:hover { background: var(--color-accent-700) !important; }
.soc { background: var(--color-accent-700); color: var(--color-accent-100); }
.soc:hover { background: var(--color-accent); color: var(--color-bg); }
.yt-card { transition: transform .35s cubic-bezier(.22, 1, .36, 1), box-shadow .35s ease; }
.yt-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }

/* — cart drawer — */
.cart-root { position: fixed; inset: 0; z-index: 230; display: none; }
.cart-root.open { display: block; }
.close-pill:hover { background: var(--color-accent-100) !important; color: var(--color-accent-800) !important; }
.cart-row-btn { transition: border-color .2s ease, color .2s ease; }
.cart-row-btn:hover { border-color: var(--color-accent) !important; color: var(--color-accent-700) !important; }
.cart-del:hover { color: #96442b !important; }
/* The page used to scroll behind the open drawer (a swipe on the backdrop or
   past the end of the list moved it 300px). main.js locks html while the
   drawer is open; these stop the touch from reaching the page at all. */
#cartBackdrop { touch-action: none; }
#cartRows { overscroll-behavior: contain; }
/* A cart row on a phone: the name column was 120px at 390 / 93px at 360, so
   real names wrapped 5-6 lines and the unit price broke in two. Under 480 the
   price/trash column drops to its own tier under the text (68 = 56px image +
   12px gap) and the name column grows to ~240px. Desktop is untouched. */
@media (max-width: 480px) {
  .cart-row { flex-wrap: wrap; }
  .cart-row__name { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  .cart-row__side { flex-direction: row-reverse !important; align-items: center !important; justify-content: space-between; width: 100%; padding-left: 68px; box-sizing: border-box; }
}
.cart-continue:hover { color: var(--color-accent) !important; }

/* — dropdown panels (search / lang / sign-in) — */
.nav-pop { display: none; }
.nav-pop.open { display: block; }
.nav-pop-flex.open { display: flex; }

/* — the phone menu: a 44px button in the pill, and a sheet in the .nav-pop idiom —
   The nav has a translateX transform, so it is the containing block: the sheet
   is absolute inside it and centred the same way the pill is. The pill sets
   white-space:nowrap inline and is max-content wide; the sheet resets both. */
.nav-menu-btn { display: none; align-items: center; justify-content: center; width: 44px; height: 44px; flex: none;
  border: none; border-radius: 50%; cursor: pointer; background: rgba(255, 247, 230, .12); color: var(--dv-cream);
  font-family: var(--font-body); transition: background-color .25s ease; }
.nav-menu-btn svg { width: 20px; height: 20px; }
.nav-menu-btn:hover { background: rgba(255, 247, 230, .24); }
.nav-menu-btn[aria-expanded="true"] { background: var(--dv-cream); color: var(--dv-ink); }
.nav-sheet { position: absolute; top: calc(100% + 10px); left: 50%; transform: translateX(-50%);
  width: calc(100vw - 24px); max-width: 420px; box-sizing: border-box; background: var(--color-bg); color: var(--color-text);
  border-radius: calc(var(--radius-lg) * 1.1); box-shadow: var(--shadow-lg); padding: 14px;
  white-space: normal; text-align: left; max-height: calc(100vh - 100px); overflow: auto; overscroll-behavior: contain; }
.nav-sheet__search { display: flex; align-items: center; gap: 8px; background: var(--color-surface); border-radius: 999px; padding: 0 8px 0 16px; margin-bottom: 8px; }
.nav-sheet__search svg { width: 16px; height: 16px; flex: none; color: var(--color-accent); }
/* 16px: below that iOS Safari zooms the page on focus */
.nav-sheet__search input { flex: 1; min-width: 0; border: none; outline: none; background: transparent; font: 500 16px var(--font-body); color: var(--color-text); padding: 13px 0; }
.nav-sheet__hits { display: flex; flex-direction: column; gap: 2px; margin-bottom: 8px; }
.nav-sheet__hits:empty { display: none; }
.nav-sheet__links { display: flex; flex-direction: column; }
.nav-sheet__links a { display: flex; align-items: center; min-height: 48px; padding: 0 12px; border-radius: 14px; font: 600 15px var(--font-body); color: var(--color-text); text-decoration: none; }
.nav-sheet__links a:hover { background: color-mix(in srgb, var(--color-text) 5%, transparent); }
.nav-sheet__links a[aria-current="page"] { background: var(--color-accent-100); color: var(--color-accent-800); font-weight: 700; }
.nav-sheet__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-start; gap: 10px; margin-top: 8px; padding-top: 12px; border-top: 1px solid var(--color-divider); }
/* the language row + list: same 48px row as the page links, the list under it
   as 44px rows with a tick; folded by `hidden` (display lives here, so it holds) */
.nav-sheet__lang { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--color-divider); }
.nav-sheet__langbtn { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 48px; padding: 0 12px; border: 0; border-radius: 14px; background: transparent; color: var(--color-text); font: 600 15px var(--font-body); text-align: left; cursor: pointer; }
.nav-sheet__langbtn > svg:first-child { width: 18px; height: 18px; flex: none; color: var(--color-accent-700); }
.nav-sheet__langk { flex: none; }
.nav-sheet__langv { flex: 1; min-width: 0; text-align: right; font-weight: 500; color: var(--color-neutral-600); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-sheet__chev { width: 14px; height: 14px; flex: none; color: var(--color-neutral-600); transition: transform .16s ease; }
.nav-sheet__langbtn[aria-expanded="true"] .nav-sheet__chev { transform: rotate(180deg); }
.nav-sheet__langlist { display: flex; flex-direction: column; gap: 2px; padding: 2px 0 4px 12px; }
.nav-sheet__langlist[hidden] { display: none; }
.nav-sheet__langlist button { display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 12px; border: 0; border-radius: 12px; background: transparent; color: var(--color-text); font: 500 15px var(--font-body); text-align: left; cursor: pointer; }
.nav-sheet__langlist button span { flex: 1; }
.nav-sheet__langlist button i { font-style: normal; font-weight: 800; color: var(--color-accent-700); visibility: hidden; }
.nav-sheet__langlist button[aria-pressed="true"] { background: var(--color-accent-100); color: var(--color-accent-800); font-weight: 700; }
.nav-sheet__langlist button[aria-pressed="true"] i { visibility: visible; }
.nav-sheet__langlist img { width: 20px; height: 15px; border-radius: 3px; flex: none; }
.nav-sheet__auth { display: flex; gap: 8px; }
.nav-sheet__auth[hidden] { display: none; }            /* display lives here, never in the style attribute */
.nav-sheet__auth .in, .nav-sheet__auth .reg { display: inline-flex; align-items: center; min-height: 40px; padding: 0 16px; border-radius: 999px; font: 700 14px var(--font-body); white-space: nowrap; text-decoration: none; cursor: pointer; }
.nav-sheet__auth .in { background: var(--color-accent); color: var(--color-bg); border: none; }
.nav-sheet__auth .reg { background: transparent; border: 1px solid var(--color-divider); color: var(--color-text); }
/* Between 861 and 1300 the sheet carries only what the pill lacks: each block
   hides at the width where its pill twin comes back (site.css rules at the
   top of the nav section). After the base rules above so the cascade holds. */
@media (min-width: 861px) { .nav-sheet__links { display: none; } }
@media (min-width: 1021px) { .nav-sheet__auth { display: none; } }
@media (min-width: 1181px) { .nav-sheet__search, .nav-sheet__hits { display: none; } }

/* — filter sidebars, detail pages — */
.frow { transition: background-color .2s ease; }
.frow:hover { background: var(--color-accent-100) !important; }
.frow2 { transition: background-color .2s ease; }
.frow2:hover { background: var(--color-accent-2-100) !important; }
.qty-btn { transition: background-color .2s ease; }
.qty-btn:hover { background: var(--color-surface) !important; }
.thumb-btn { transition: border-color .25s ease, transform .25s ease; }
.thumb-btn:hover { transform: translateY(-2px); }
.vplay { transition: transform .25s ease, background-color .25s ease; }
.vplay:hover { transform: scale(1.08); background: var(--color-accent-600) !important; }
.tool-btn { transition: background-color .25s ease, color .25s ease, border-color .25s ease, transform .3s cubic-bezier(.22, 1, .36, 1); }
.tool-btn:hover { transform: translateX(4px); }
.pick-btn { transition: background-color .25s ease, color .25s ease, border-color .25s ease; }

/* — DARA chat widget: its fixed flex container spans the hidden panel's box,
     which would swallow clicks on content underneath — let clicks through. — */
#daChat { pointer-events: none; }
#daChat > * { pointer-events: auto; }

/* — auth pages — */
/* 21.7px tall as authored; the padding makes it a 44px target and the negative
   margin gives the height back, so the header stays 82px and nothing moves. */
.back-link { transition: color .25s ease; padding: 11px 0 11px 12px; margin: -11px 0; min-height: 44px; box-sizing: border-box; }
.back-link:hover { color: var(--color-accent) !important; }
.eye-btn { transition: background-color .2s ease, color .2s ease; }
.eye-btn:hover { background: var(--color-accent-100); color: var(--color-accent-800); }

/* — the products grid: three to a row —
   The sidebar takes 270 + 40 of the 1240 measure, so the grid is 786px and a
   third of it is a 251px tile — the photo and the full product name both get
   room a 185px quarter never had. An explicit count rather than auto-fill,
   because "three" is the design and auto-fill would quietly make it two at
   1280 and four on a wide monitor. A third still holds at 1100 (216px) with
   the sidebar in place; at 940 site.css collapses the sidebar and the grid
   takes the full measure, so the next step down is 760. */
#cgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* 941–1100 is the one band where the rail is still there and a third of what
   is left is a 190–216px tile: measured at 1024, price + arrow wrapped onto a
   second line on all 24 cards. Two to a row there instead — 260px at 941,
   332px at 1100. Below 941 the rail folds into the sheet and the grid takes
   the whole measure, so three fit again. */
@media (min-width: 941px) and (max-width: 1100px) { #cgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 760px)  { #cgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 460px)  { #cgrid { grid-template-columns: minmax(0, 1fr); } }

/* — the product card: the Species card in a shop's clothing —
   Owner: "card product dibuat seperti card pada spesies". The same cream
   body under a 24px radius and a 3px hard shadow, the same white plate, the
   same foot rule with the marigold arrow. Copied rather than shared with
   .sp-card because the two grids break at different widths — Species at
   940/640/520, Products at 940/760/460 — and the species card's responsive
   rules live inside those blocks. This block and the one at :895 move together. */
.pr-card { position: relative; display: flex; flex-direction: column; border-radius: 24px; background: var(--dv-cream); border: 1.5px solid rgba(23, 63, 39, .12); box-shadow: 0 3px 0 rgba(23, 63, 39, .14); color: var(--dv-ink); text-decoration: none; overflow: hidden; --pr-ink: #264e25; transition: transform .45s cubic-bezier(.22, 1, .36, 1), box-shadow .45s ease; }
.pr-card:hover { color: var(--dv-ink); }
.pr-card:focus-visible { outline: 3px solid var(--dv-ink); outline-offset: 3px; }
.pr-card__plate { display: block; position: relative; aspect-ratio: 1; margin: 10px 10px 0; border-radius: 18px; background: #fff; box-shadow: inset 0 0 0 1px rgba(23, 63, 39, .08); overflow: hidden; }
.pr-card__img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .7s cubic-bezier(.22, 1, .36, 1); }
/* 83 of the 183 are out of stock: the photo goes quiet, the pill says why */
.pr-card__img.is-out { opacity: .62; filter: saturate(.7); }
.pr-card__initial { display: flex; width: 100%; height: 100%; align-items: center; justify-content: center; font-family: var(--font-heading); font-size: 56px; opacity: .85; }
.pr-card__body { display: flex; flex-direction: column; gap: 6px; padding: 14px 16px 16px; flex: 1; }
.pr-card__shelf { display: flex; align-items: center; gap: 8px; font: 800 var(--fs-min)/1 var(--font-body); letter-spacing: .14em; text-transform: uppercase; color: var(--pr-ink); }
.pr-card__shelf > span:not(.pr-stock) { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pr-stock { margin-left: auto; flex: none; font: 800 var(--fs-min)/1 var(--font-body); letter-spacing: .08em; padding: 3px 6px; border-radius: 6px; border: 1.5px solid currentColor; color: #A63D2A; }
.pr-card__name { margin-top: 2px; font: 400 20px/1.12 var(--font-heading); transition: color .3s ease; }
.pr-card__by { font: 400 var(--fs-read)/1.35 var(--font-body); color: #5c6356; }
.pr-var { display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0 0; padding: 0; list-style: none; }
/* the pill sizes to its own label, as the phase pill does; a variant name is
   the one string here that can run long, so the label clips inside the pill
   rather than pushing the pill past the column */
.pr-var li { flex: 0 1 auto; min-width: 0; padding: 0 8px; display: flex; align-items: center; gap: 5px; height: 26px; border-radius: 7px; background: var(--color-accent-100); color: var(--color-accent-800); font: 700 var(--fs-read)/1 var(--font-body); }
.pr-var li::before { content: ''; width: 5px; height: 5px; flex: none; border-radius: 50%; background: var(--pr-ink); }
.pr-var li > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pr-var li.pr-var__more { flex: none; background: transparent; border: 1.5px dashed rgba(23, 63, 39, .28); color: #5c6356; }
.pr-var li.pr-var__more::before { display: none; }
/* nowrap, not wrap: the price and the arrow stay on one line (owner: "harga
   tidak diatas tombol"). Two bands are tight enough to have broken it — the
   two-column grid just over 520 (a 214px tile at 521) and the three-column one
   just over 760 (223px at 761), where the foot had 182–191px for a 147px price
   plus a 44px arrow. So the price is the part that gives: it may shrink and,
   at the very bottom, set "mulai" above the figure inside its own box, while
   the arrow keeps its place in the row. */
.pr-card__foot { display: flex; flex-wrap: nowrap; justify-content: flex-end; align-items: center; gap: 10px; margin-top: auto; padding-top: 10px; border-top: 1px solid rgba(23, 63, 39, .10); }
.pr-card__price { display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 0 4px; min-width: 0; margin-left: auto; font: 400 17px/1 var(--font-heading); color: var(--color-accent-700); }
.pr-card__price > span { white-space: nowrap; }
.pr-card__price small { font: 600 var(--fs-read)/1 var(--font-body); color: #5c6356; }
/* .sr-only is scoped per page in this file (:594, :863); the card carries the
   whole price range for a screen reader, so it needs its own copy here */
.pr-card .sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.pr-card__go { display: grid; place-items: center; width: 34px; height: 34px; flex: none; border-radius: 50%; background: var(--dv-sun); color: var(--dv-ink); box-shadow: 0 3px 0 rgba(23, 63, 39, .16); transition: transform .35s cubic-bezier(.22, 1, .36, 1); }
.pr-card__go svg { width: 16px; height: 16px; }
/* 521–940: three to a row on the full measure bottoms out at a 218px tile at
   761, where a seven-figure price at 17px pushed "mulai" onto its own line
   inside the foot. The same step down the species card takes at 940 — smaller
   figure, smaller arrow — puts it back on one line with room to spare. */
@media (min-width: 521px) and (max-width: 940px) {
  .pr-card__price { font-size: 16px; }
  .pr-card__go { width: 30px; height: 30px; }
  .pr-card__go svg { width: 15px; height: 15px; }
}
@media (hover: hover) and (pointer: fine) {
  .pr-card:hover, .pr-card:focus-visible { transform: translateY(-6px) rotate(-.4deg); box-shadow: 0 8px 0 rgba(23, 63, 39, .14), 0 22px 44px rgba(23, 63, 39, .16); }
  .pr-card:hover .pr-card__img { transform: scale(1.05); }
  .pr-card:hover .pr-card__go { transform: translateX(4px) rotate(-8deg); }
  .pr-card:hover .pr-card__name { color: var(--color-accent-700); }
}
@media (hover: none) { .pr-card:active { transform: scale(.985); } }
@media (prefers-reduced-motion: reduce) {
  .pr-card, .pr-card__img, .pr-card__go, .pr-card__name { transition-duration: .01ms !important; }
  .pr-card:hover { transform: none; }
}

/* — Products on a phone —
   Three things measured at 390×844 before this block: the filter rail flowed
   as a 1,144px checkbox list above the search box, so the first product sat
   at y=1712 and a tapped category changed nothing on screen; the desktop
   card was stretched to one 351px column (484px a tile, 1.7 products a
   screen); and all 183 tiles rendered at once (95,922px, 114 screens).

   The rail's markup is shared: on desktop <aside.filt-rail> is the sticky
   scrolling column and .filt its flex stack; at ≤940 the aside is
   display:contents (so the grid gets no empty track and site.css's
   `.layout-sidebar > aside` rule has nothing to act on) and .filt is a fixed
   bottom sheet. z-index 220/221: above Dara's launcher (180), under the cart
   (230) and the page curtain (300). */
.filt { display: flex; flex-direction: column; gap: 26px; }
.filt-scrim { display: none; }
@media (min-width: 941px) {
  body[data-page=products] .filt-rail { position: sticky; top: 100px; max-height: calc(100vh - 130px); overflow: auto; padding-right: 4px; }
  .filt-head, .filt-foot, .filt-btn, .filt-scrim { display: none; }
  body[data-page=species] .sp-filt { display: none; }   /* Species has no rail on a desktop: the trail and the chips are the filter there */
}
@media (max-width: 940px) {
  body[data-page=products] .filt-rail { display: contents; }
  body[data-page=products] .filt, body[data-page=species] .filt {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 221;
    max-height: 82vh; overflow: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
    gap: 22px; padding: 10px 5vw 0; background: var(--color-bg);
    border-radius: 22px 22px 0 0; box-shadow: 0 -12px 40px rgba(0, 0, 0, .18);
    transform: translateY(102%); visibility: hidden;
    transition: transform .32s cubic-bezier(.22, 1, .36, 1), visibility 0s .32s;
  }
  body[data-page=products] .filt.is-open, body[data-page=species] .filt.is-open { transform: none; visibility: visible; transition: transform .32s cubic-bezier(.22, 1, .36, 1); }
  .filt:focus { outline: none; }
  .filt-head { display: grid; grid-template-columns: 1fr auto; align-items: center; position: relative; padding-top: 12px; }
  .filt-handle { position: absolute; top: 0; left: 50%; width: 40px; height: 4px; margin-left: -20px; border-radius: 999px; background: var(--color-neutral-300); }
  .filt-title { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 22px; }
  .filt-x { width: 44px; height: 44px; margin-right: -8px; border: 0; border-radius: 999px; background: var(--color-surface); color: var(--color-text); font-size: 16px; font-weight: 700; cursor: pointer; }
  .filt-foot { position: sticky; bottom: 0; margin-top: -4px; padding: 12px 0 calc(14px + env(safe-area-inset-bottom, 0px)); background: var(--color-bg); }
  #filtApply { width: 100%; height: 48px; border-radius: 999px; font-size: 15px; }
  .filt-scrim { display: block; position: fixed; inset: 0; z-index: 220; background: rgba(10, 28, 14, .45); touch-action: none; opacity: 0; visibility: hidden; transition: opacity .3s ease, visibility 0s .3s; }
  .filt-scrim.is-on { opacity: 1; visibility: visible; transition: opacity .3s ease; }
  html.filt-lock { overflow: hidden; }

  /* the search row: the pill owns the row with the Filter button beside
     it (the inline min-width:min(280px,100%) made anything else wrap under
     it); the count lives in the sheet's apply button here. A 140px basis
     keeps "Filter (12)" (≈126px) on the pill's line in a 324px column at
     360. The pill grows to 44px so the input is a real tap band (it was
     19px). */
  body[data-page=products] .c-search { flex: 1 1 140px !important; min-width: 0 !important; max-width: none !important; min-height: 44px; padding: 8px 8px 8px 16px !important; }
  body[data-page=products] #fq { height: 28px; }
  body[data-page=products] #fqClear { width: 32px !important; height: 32px !important; }
  body[data-page=products] .c-count { display: none; }
  .filt-btn { display: inline-flex; align-items: center; gap: 7px; flex: none; height: 44px; padding: 0 14px; border-radius: 999px; border: 1.5px solid var(--color-neutral-300); background: var(--color-surface); color: var(--color-text); font: 700 var(--fs-read) var(--font-body); cursor: pointer; }
  .filt-btn svg { width: 18px; height: 18px; color: var(--color-accent-700); }
  .filt-btn b { color: var(--color-accent-700); }
  .filt-btn[aria-expanded=true] { border-color: var(--color-accent); }
}
/* the "Muat 24 lagi" line under the grid, every width */
.c-more { display: flex; flex-direction: column; align-items: center; gap: 10px; }
/* the display here beats the wrapper's hidden attribute, so "Muat 0 lagi ·
   0 tersisa" sat under the last page of the grid */
.c-more[hidden] { display: none; }
.c-more .btn { padding: 12px 26px; border-radius: 999px; }
.c-more__left { font-size: var(--fs-read); color: var(--color-neutral-600); }

/* the compact two-column tile: 167px wide at 390, four products a screen
   instead of 1.7. It starts at 520, where the species card's compact tile
   starts, because that is where the foot stops holding price and arrow in one
   row (199px of column at 461, 167px of it inside the padding). Trimmed the
   same way the species card is trimmed there — the variant
   pills go, the arrow goes (the whole card is the link), the foot stacks —
   plus the category after the brand, which the category filter in the sheet
   already covers. The name clamps to two lines; the tile's title attribute
   keeps the whole of it. */
@media (max-width: 520px) {
  body[data-page=products] #cgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  body[data-page=products] .pr-card { border-radius: 20px; }
  body[data-page=products] .pr-card__plate { margin: 8px 8px 0; border-radius: 14px; }
  body[data-page=products] .pr-card__body { padding: 10px 10px 12px; gap: 4px; }
  body[data-page=products] .pr-card__shelf { gap: 6px; letter-spacing: .1em; }
  body[data-page=products] .pr-card__name { font-size: 15px; line-height: 1.15; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  body[data-page=products] .pr-card__by { font-size: 13px; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  body[data-page=products] .pr-card__cat, body[data-page=products] .pr-var, body[data-page=products] .pr-card__go { display: none; }
  body[data-page=products] .pr-card__foot { flex-direction: column; align-items: flex-start; gap: 6px; padding-top: 8px; }
  body[data-page=products] .pr-card__price { margin-left: 0; font-size: 14px; }
  body[data-page=products] .pr-card__price small { font-size: 13px; }
}

/* — small screens: collapse the desktop-first grids — */
@media (max-width: 940px) {
  .layout-sidebar { grid-template-columns: 1fr !important; }
  .layout-sidebar > aside { position: static !important; max-height: none !important; }
  .detail-grid { grid-template-columns: 1fr !important; }
  .detail-grid > .detail-media { position: static !important; }
  .detail-body-grid { grid-template-columns: 1fr !important; }
  .reviews-grid { grid-template-columns: 1fr !important; }
  .auth-grid { grid-template-columns: 1fr !important; gap: 40px !important; padding-bottom: 40px !important; }
  /* Stacked, the figure is decoration after the form, so it sizes to the
     blob: 34px top clears the outer ring (inset -26px), 30px bottom the
     figcaption (bottom -22px). The old 380px floor left 50px (390) / 60px
     (360) of bare cream above and below the blob; with the inline gap 56
     and padding-bottom 70 that was ~150px of nothing after the last field. */
  .auth-grid .auth-figure { min-height: 0 !important; padding: 34px 0 30px; }
}
/* Phones: the rotating picture goes ABOVE the form (owner: "gambar yang berada di
   bawah ... diletakkan di atas"), small enough that the title and the first field
   still land on the first screen — a 200px blob in a 260px tint, rings and caption
   included, is ~300px between the header and the h1. */
@media (max-width: 640px) {
  .auth-grid { gap: 22px !important; padding-top: 4px !important; }
  .auth-grid .auth-figure { order: -1; width: 260px; max-width: 100%; margin: 0 auto; padding: 30px 0 36px; box-sizing: border-box; }   /* a fixed width: the figure inside is a % of it */
  .auth-grid .auth-figure figure { width: 200px !important; }
}

/* ════════════════════════════════════════════════════════════════════════
   DESCENT v2 — tema "Penurunan" (redesign home + chrome semua halaman).
   Token dv-* dipakai nav/footer di 12 halaman dan seluruh band home page.
   ════════════════════════════════════════════════════════════════════════ */
:root {
  --dv-sky: #C4E7EF; --dv-sky2: #A8DCD4; --dv-sun: #FFD66B; --dv-cloud: #EFF9F6;
  --dv-canopy1: #6FB268; --dv-canopy2: #4B9A54; --dv-canopy3: #2E7A41; --dv-canopy4: #1F5D33;
  --dv-floor: #1E5233; --dv-floor-dk: #153B25; --dv-moss: #7CB56B;
  --dv-trunk: #7A5240; --dv-trunk-dk: #59392C; --dv-bark: #8F6449;
  --dv-bank: #177E6A; --dv-bank-dk: #0F5E52;
  --dv-water-lite: #3FC9C0; --dv-aqua: #1B9AA8;
  --dv-reef: #0F6E96; --dv-reef-dk: #0B577C; --dv-deep: #0A3A5C; --dv-deep-dk: #062B47; --dv-abyss: #04182B;
  --dv-coral: #FF7A59; --dv-coral2: #E85D75; --dv-coral3: #FFAF63;
  --dv-sand: #E8C97E; --dv-sand-dk: #D2AE5F; --dv-weed: #2FBF8F;
  --dv-biolum: #59F2CE; --dv-navy-ink: #B8F1FF; --dv-cream: #FFF7E6; --dv-ink: #173F27;
  --dv-leaf-bright: #9BE38B;
}
@keyframes dvBob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-9px); } }
@keyframes dvBub { 0% { transform: translateY(0) translateX(0); opacity: 0; } 10% { opacity: .9; } 50% { transform: translateY(-46vh) translateX(10px); } 100% { transform: translateY(-92vh) translateX(-6px); opacity: 0; } }
@keyframes dvWaveL { 0% { transform: translateX(0); } 100% { transform: translateX(-180px); } }
@keyframes dvWaveR { 0% { transform: translateX(-180px); } 100% { transform: translateX(0); } }
@keyframes dvBlink { 0%, 86%, 100% { opacity: .12; } 92% { opacity: 1; } }
@keyframes dvPulse { 0%, 100% { opacity: .5; transform: scale(1); } 50% { opacity: 1; transform: scale(1.12); } }
@keyframes dvSway { 0%, 100% { transform: rotate(-2.5deg); } 50% { transform: rotate(2.5deg); } }
@keyframes dvDrift { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(14px, -10px); } }
@keyframes dvMarq { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes dvSplash { 0% { transform: scale(.4); opacity: .9; } 100% { transform: scale(1.9); opacity: 0; } }

/* — NAV v2 (semua halaman): pil hutan gelap, CTA marigold ala pethouse — */
nav.da-nav {
  background: color-mix(in srgb, var(--dv-canopy4) 88%, transparent) !important;
  border: 1px solid rgba(255, 247, 230, .22) !important;
  box-shadow: 0 10px 30px rgba(10, 30, 18, .35), inset 0 1px 0 rgba(255, 247, 230, .12) !important;
}
nav.da-nav .nav-link { color: var(--dv-cream); }
nav.da-nav .nav-link:hover { color: var(--dv-leaf-bright); }
body[data-page="home"] nav.da-nav .nav-link[data-nav="home"],
body[data-page="species"] nav.da-nav .nav-link[data-nav="species"],
body[data-page="species-detail"] nav.da-nav .nav-link[data-nav="species"],
body[data-page="products"] nav.da-nav .nav-link[data-nav="products"],
body[data-page="product-detail"] nav.da-nav .nav-link[data-nav="products"],
body[data-page="blog"] nav.da-nav .nav-link[data-nav="blog"],
body[data-page="blog-post"] nav.da-nav .nav-link[data-nav="blog"],
body[data-page="equipment"] nav.da-nav .nav-link[data-nav="equipment"] { color: var(--dv-leaf-bright); font-weight: 700; }
nav.da-nav .nav-search > div { background: rgba(255, 247, 230, .12) !important; }
nav.da-nav .nav-search input { color: var(--dv-cream) !important; }
nav.da-nav .nav-search input::placeholder { color: rgba(255, 247, 230, .55); }
nav.da-nav .nav-search svg { color: var(--dv-leaf-bright) !important; }
nav.da-nav .lang-btn { background: rgba(255, 247, 230, .12) !important; color: var(--dv-cream) !important; }
nav.da-nav .lang-btn:hover { background: rgba(255, 247, 230, .22) !important; }
nav.da-nav .nav-signin-btn { color: var(--dv-cream) !important; }
nav.da-nav .nav-signin-btn:hover { color: var(--dv-leaf-bright) !important; }
nav.da-nav .cart-btn { background: rgba(255, 247, 230, .12) !important; }
nav.da-nav .cart-btn:hover { background: rgba(255, 247, 230, .24) !important; }
nav.da-nav .cart-btn svg { color: var(--dv-cream) !important; }
nav.da-nav #cartBadge { background: var(--dv-coral) !important; color: #fff !important; }
nav.da-nav .nav-cta {
  background: var(--dv-sun); color: var(--dv-ink);
  font-family: var(--font-body); font-weight: 800;
  box-shadow: 0 3px 0 rgba(0, 0, 0, .22);
}
nav.da-nav .nav-cta:hover { background: #FFE08A; color: var(--dv-ink); }
/* mode selam (home, setelah menembus garis air) */
body.dv-under nav.da-nav { background: color-mix(in srgb, var(--dv-deep) 90%, transparent) !important; }
body.dv-under nav.da-nav .nav-link:hover,
body.dv-under nav.da-nav .nav-search svg { color: var(--dv-biolum) !important; }

/* — FOOTER v2 (semua halaman): dasar palung bioluminesens — */
footer.dv-abyss {
  position: relative; overflow: hidden;
  background: linear-gradient(var(--dv-deep-dk), var(--dv-abyss) 55%, #020F1D);
  color: var(--dv-navy-ink);
  border-radius: calc(var(--radius-lg) * 1.6) calc(var(--radius-lg) * 1.6) 0 0;
  padding: 90px 5vw 30px;
}
footer.dv-abyss .dv-foot-scene { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
footer.dv-abyss .foot-link { color: rgba(184, 241, 255, .72); }
footer.dv-abyss .foot-link:hover { color: var(--dv-biolum); }
footer.dv-abyss .dv-col-title { font-family: var(--font-heading); font-size: 15px; color: var(--dv-cream); margin-bottom: 4px; }
footer.dv-abyss .soc { background: rgba(89, 242, 206, .1); color: var(--dv-biolum); border: 1px solid rgba(89, 242, 206, .35); }
footer.dv-abyss .soc:hover { background: var(--dv-biolum); color: #04282B; }
/* The footer wordmark is the logo itself. Sized to sit where the old two
   lines of display type sat (175px tall at 1920, 91px at 390), and given
   a plain drop shadow for depth — no added halo, because this artwork
   brings its own blue rim light. */
footer.dv-abyss .dv-wordmark-img {
  display: block; width: clamp(212px, 22vw, 336px); height: auto;
  filter: drop-shadow(0 4px 14px rgba(0, 0, 0, .5));
}
footer.dv-abyss .dv-radio { border: 1px solid rgba(89, 242, 206, .4); color: var(--dv-navy-ink); }
footer.dv-abyss .dv-radio:hover { background: rgba(89, 242, 206, .12); }
footer.dv-abyss .dv-surface-btn { background: var(--dv-biolum); color: #04282B; box-shadow: 0 0 24px rgba(89, 242, 206, .45); font-weight: 800; }
/* Ikon baris dasar hanya dipakai di ponsel (blok 620 di bawah): di desktop
   kelima tautan sosial dan tombol naik tetap berlabel teks seperti semula. */
footer.dv-abyss .foot-ico { display: none; }
.dv-ico { width: 15px; height: 15px; flex: none; }   /* ikon telepon, menggantikan emoji */
footer.dv-abyss .dv-surface-btn:hover { background: #7FF6DC; color: #04282B; }

/* — HOME "Penurunan": band, bingkai, ornamen — */
body[data-page="home"] { background: var(--dv-abyss); }
.dv-band { position: relative; overflow: hidden; }
.dv-band .dv-scene { position: absolute; inset: 0; width: 100%; height: 100%; display: block; pointer-events: none; }
.dv-pill {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--dv-cream); color: var(--dv-ink);
  font-weight: 800; font-size: 14px; border-radius: 999px; padding: 12px 22px;
  box-shadow: 0 3px 0 rgba(0, 0, 0, .16);
  transition: transform .3s cubic-bezier(.22, 1, .36, 1), box-shadow .3s ease, background-color .25s ease;
}
.dv-pill:hover { transform: translateY(-3px); box-shadow: 0 6px 0 rgba(0, 0, 0, .16); color: var(--dv-ink); }
.dv-pill:active { transform: translateY(-1px) scale(.96); }
.dv-pill.sun { background: var(--dv-sun); }
.dv-pill.sun:hover { background: #FFE08A; }
.dv-pill.leafy { background: var(--dv-canopy3); color: var(--dv-cream); box-shadow: 0 3px 0 rgba(0, 0, 0, .3); }
.dv-pill.leafy:hover { background: var(--dv-canopy2); color: var(--dv-cream); }
.dv-pill.navy { background: var(--dv-deep); color: var(--dv-navy-ink); box-shadow: 0 3px 0 rgba(0, 0, 0, .35); }
.dv-pill.navy:hover { background: #0D4A75; color: var(--dv-navy-ink); }
.dv-kicker { font-size: var(--fs-read); letter-spacing: .22em; text-transform: uppercase; font-weight: 800; }
.dv-h { font-family: var(--font-heading); font-weight: 400; line-height: 1.02; letter-spacing: -.01em; margin: 0; text-wrap: balance; }
.dv-frame { position: relative; display: block; animation: dvBob 5.5s ease-in-out infinite; }
.dv-frame img { position: absolute; object-fit: cover; }
.dv-frame .dv-label {
  position: absolute; left: 50%; bottom: -16px; transform: translateX(-50%);
  white-space: nowrap; font-size: var(--fs-read); padding: 8px 15px; z-index: 2;
  transition: transform .3s cubic-bezier(.22, 1, .36, 1);
}
a.dv-frame { transition: filter .3s ease; }
a.dv-frame:hover .dv-label { transform: translateX(-50%) translateY(-3px) rotate(-1.5deg); }
a.dv-frame:hover { filter: brightness(1.06); }
.dv-bubbles i {
  position: absolute; bottom: -30px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .55);
  background: radial-gradient(circle at 34% 30%, rgba(255, 255, 255, .5), rgba(255, 255, 255, .05) 60%);
  animation: dvBub linear infinite;
}
.dv-rays { position: absolute; inset: 0; pointer-events: none; background:
  linear-gradient(112deg, transparent 34%, rgba(255, 255, 255, .09) 38%, transparent 46%),
  linear-gradient(112deg, transparent 55%, rgba(255, 255, 255, .07) 60%, transparent 68%),
  linear-gradient(112deg, transparent 76%, rgba(255, 255, 255, .05) 80%, transparent 86%); }
.dv-sway { animation: dvSway 7s ease-in-out infinite; }
.dv-splash-ring {
  position: absolute; border: 4px solid rgba(255, 255, 255, .85); border-radius: 50%;
  width: 120px; height: 46px; pointer-events: none; opacity: 0;
}
.dv-wood-sign {
  position: relative; background: var(--dv-trunk); border-radius: 26px;
  padding: clamp(28px, 4vw, 54px);
  box-shadow: inset 0 0 0 8px var(--dv-bark), inset 0 0 0 11px var(--dv-trunk-dk), 0 14px 38px rgba(0, 0, 0, .35);
}
.dv-stat-mush { text-align: center; position: relative; padding-top: 14px; }
.dv-stat-mush .num { font-family: var(--font-heading); font-size: clamp(34px, 3.6vw, 52px); color: var(--dv-sun); text-shadow: 0 0 22px rgba(255, 175, 99, .45); }
.dv-stat-mush .lbl { font-size: 15px; color: rgba(255, 247, 230, .82); margin-top: 6px; line-height: 1.4; }
.dv-sonar {
  background: rgba(4, 24, 43, .55); border: 1.5px solid rgba(184, 241, 255, .35);
  border-radius: 24px; padding: 22px 26px; backdrop-filter: blur(3px);
}
.dv-sonar .ping { width: 10px; height: 10px; border-radius: 50%; background: var(--dv-biolum); animation: dvPulse 2s infinite; }
.dv-brand-chip {
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255, 247, 230, .92); border-radius: 18px; padding: 12px 20px;
  box-shadow: 0 0 22px rgba(89, 242, 206, .25);
}
.dv-brand-chip img { height: 34px; width: auto; max-width: none; flex: none; }
.dv-quote-paper { background: #F3E7C8; color: #4A3A22; border-radius: 10px; }
/* grid & responsive band content */
.dv-portal-grid { display: flex; gap: 56px 44px; flex-wrap: wrap; justify-content: center; align-items: center; }
.dv-content { position: relative; z-index: 3; max-width: 1240px; margin: 0 auto; padding: 0 5vw; }
@media (max-width: 760px) {
  .dv-portal-grid { gap: 48px 26px; }
  .dv-frame { transform: scale(.92); }
}


/* ════════════════════════════════════════════════════════════════════════
   HERO ATMOSFER — lapisan gerak di band pembuka.
   Kunang-kunang, debu naik, burung, daun jatuh, kilau sinar, kupu-kupu,
   dan kelopak mata katak. Dipakai oleh band #dv-puncak.
   ════════════════════════════════════════════════════════════════════════ */
@keyframes ffWander{0%{transform:translate(0,0)}25%{transform:translate(26px,-34px)}50%{transform:translate(-14px,-58px)}75%{transform:translate(-38px,-22px)}100%{transform:translate(0,0)}}
@keyframes ffGlow{0%,100%{opacity:.12}45%{opacity:1}60%{opacity:.35}80%{opacity:.85}}
@keyframes moteRise{0%{transform:translateY(0);opacity:0}15%{opacity:.7}85%{opacity:.5}100%{transform:translateY(-46vh);opacity:0}}
.ff{position:absolute;width:6px;height:6px;border-radius:50%;background:#FFE9A0;box-shadow:0 0 12px 4px rgba(255,233,160,.8),0 0 26px 10px rgba(255,233,160,.35);pointer-events:none;animation:ffWander var(--d,11s) ease-in-out infinite,ffGlow var(--g,3.4s) ease-in-out infinite}
.mote{position:absolute;width:3px;height:3px;border-radius:50%;background:rgba(255,246,210,.85);pointer-events:none;animation:moteRise var(--d,14s) linear infinite}
.ffw{position:absolute;transition:transform .5s cubic-bezier(.22,1,.36,1);will-change:transform}
.lid{transform-box:fill-box;transform-origin:50% 50%;transform:translateY(-106%);animation:daBlink 6.4s linear infinite 2.2s}
@keyframes daBlink{0%,91%{transform:translateY(-106%)}93.5%,95.5%{transform:translateY(-4%)}98%,100%{transform:translateY(-106%)}}
.bird{position:absolute;left:0;pointer-events:none;animation:birdX var(--bx,30s) linear infinite;animation-delay:var(--bdel,0s)}
.bird>span{display:block;animation:birdY 2.4s ease-in-out infinite}
.bird svg{display:block;animation:wingBeat .5s ease-in-out infinite alternate;transform-origin:50% 50%}
@keyframes birdX{0%,55%{transform:translateX(-10vw);opacity:0}58%{opacity:.75}97%{opacity:.75}100%{transform:translateX(114vw);opacity:0}}
@keyframes birdY{0%,100%{transform:translateY(0)}50%{transform:translateY(-12px)}}
@keyframes wingBeat{from{transform:scaleY(1)}to{transform:scaleY(.45)}}
.fleaf{position:absolute;top:-8vh;pointer-events:none;animation:leafFall var(--lf,16s) linear infinite;animation-delay:var(--ld,0s)}
.fleaf svg{display:block;animation:leafSway 3.2s ease-in-out infinite}
@keyframes leafFall{0%{transform:translateY(-8vh);opacity:0}6%{opacity:.95}90%{opacity:.9}100%{transform:translateY(112vh);opacity:0}}
@keyframes leafSway{0%,100%{transform:translateX(-16px) rotate(-28deg)}50%{transform:translateX(22px) rotate(24deg)}}
.rayGlow{position:absolute;inset:0;pointer-events:none;background:radial-gradient(ellipse 62% 55% at 74% 12%, rgba(255,244,190,.42), transparent 62%);mix-blend-mode:soft-light;animation:rayPulse 7s ease-in-out infinite}
@keyframes rayPulse{0%,100%{opacity:.4}50%{opacity:1}}
.bfly{position:absolute;left:0;top:0;display:none;pointer-events:none}
@supports (offset-path: path('M0 0 L1 1')){.bfly{display:block;offset-path:path('M -60 560 C 260 420 520 660 820 480 C 1040 350 1240 560 1560 420');offset-rotate:auto 90deg;animation:bflyGo var(--dur,26s) linear infinite}}
@keyframes bflyGo{0%{offset-distance:0%;opacity:0}4%{opacity:1}52%{offset-distance:100%;opacity:1}53%,100%{offset-distance:100%;opacity:0}}
.wingL{transform-box:fill-box;transform-origin:100% 50%;animation:wingFlap .3s ease-in-out infinite alternate}
.wingR{transform-box:fill-box;transform-origin:0% 50%;animation:wingFlap .3s ease-in-out infinite alternate}
@keyframes wingFlap{from{transform:scaleX(1)}to{transform:scaleX(.45)}}


/* — reduced motion: kill the decorative loops — */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}


/* ══════════════════════════════════════════════════════════════════════
   DUNIA PANJANG — dua ilustrasi tinggi sebagai latar bersambung.
   Dua ilustrasi tinggi (#dv-forest, #dv-sea) jadi latar bersama; blok ini berisi
   gerak penghuninya: siput, daun jatuh panjang, karang & rumput laut yang bergoyang,
   ubur-ubur, kawanan ikan, gelembung, katak di daun teratai, dan komponen band laut
   (kartu blog porthole, pill laut, pita brand).
   ══════════════════════════════════════════════════════════════════════ */
.fleaf.long{animation-name:leafFallLong}
@keyframes leafFallLong{0%{transform:translateY(-8vh);opacity:0}4%{opacity:.95}88%{opacity:.95}97%{opacity:.7}100%{transform:translateY(var(--lfd,215vh));opacity:0}}
.snail{position:absolute;pointer-events:none;animation:snailWalk var(--sw,52s) linear infinite;animation-delay:var(--sdel,0s)}
.snail>svg{display:block;animation:snailBob 1.9s ease-in-out infinite}
.snail .horn{transform-box:fill-box;transform-origin:0% 100%;animation:snailHorn 3.4s ease-in-out infinite}
.snail .horn2{transform-box:fill-box;transform-origin:0% 100%;animation:snailHorn 3.4s .5s ease-in-out infinite}
@keyframes snailWalk{0%{transform:translateX(-8vw);opacity:0}4%{opacity:1}94%{opacity:1}100%{transform:translateX(104vw);opacity:0}}
@keyframes snailBob{0%,100%{transform:translateY(0) rotate(-.6deg)}50%{transform:translateY(-2px) rotate(.6deg)}}
@keyframes snailHorn{0%,100%{transform:rotate(-7deg)}50%{transform:rotate(9deg)}}
.dv-stones{display:flex;gap:20px;flex-wrap:wrap;justify-content:center;margin-top:70px}
.dv-stone{position:relative;display:block;width:98px;height:98px;border-radius:50%;border:4px solid #4B9A54;box-shadow:0 8px 16px rgba(10,28,14,.35);overflow:hidden;animation:dvBob 5.5s ease-in-out infinite;transition:transform .35s cubic-bezier(.22,1,.36,1), border-color .3s ease}
.dv-stone img{width:100%;height:100%;object-fit:cover;display:block}
.dv-stone:hover{transform:translateY(-6px) scale(1.07);border-color:var(--dv-sun)}
.swy{transform-box:fill-box;transform-origin:50% 100%;animation:swy var(--sy,6s) ease-in-out infinite;animation-delay:var(--sd,0s)}
@keyframes swy{0%,100%{transform:rotate(-3.2deg)}50%{transform:rotate(3.2deg)}}
.tent{transform-box:fill-box;transform-origin:50% 100%;animation:tent var(--sy,3.6s) ease-in-out infinite;animation-delay:var(--sd,0s)}
@keyframes tent{0%,100%{transform:scale(1,1)}50%{transform:scale(.88,1.12)}}
.jlyP{transform-box:fill-box;transform-origin:50% 30%;animation:jlyP var(--sy,4.2s) ease-in-out infinite;animation-delay:var(--sd,0s)}
@keyframes jlyP{0%,100%{transform:scale(1,1)}50%{transform:scale(1.12,.86)}}
.jlyD{animation:jlyD var(--sy,16s) ease-in-out infinite;animation-delay:var(--sd,0s)}
@keyframes jlyD{0%,100%{transform:translate(0,0)}50%{transform:translate(30px,-120px)}}
.schoolA{animation:schoolA var(--sy,38s) linear infinite;animation-delay:var(--sd,0s)}
@keyframes schoolA{0%{transform:translateX(2700px)}100%{transform:translateX(-700px)}}
.schoolB{animation:schoolB var(--sy,46s) linear infinite;animation-delay:var(--sd,0s)}
@keyframes schoolB{0%{transform:translateX(-700px)}100%{transform:translateX(2700px)}}
.bubU{animation:bubU var(--sy,11s) linear infinite;animation-delay:var(--sd,0s)}
@keyframes bubU{0%{transform:translateY(0);opacity:0}12%{opacity:.85}88%{opacity:.6}100%{transform:translateY(-900px);opacity:0}}
.seaFrog{animation:seaFrog 5.2s ease-in-out infinite}
.padLid{transform-box:fill-box;transform-origin:50% 0%;animation:padBlink 5.6s ease-in-out infinite}
.padLid.b2{animation-delay:.06s}
@keyframes padBlink{0%,88%{transform:scaleY(0)}92%,95%{transform:scaleY(1)}99%,100%{transform:scaleY(0)}}
@keyframes seaFrog{0%,100%{transform:translateY(0) rotate(-.5deg)}50%{transform:translateY(-5px) rotate(.5deg)}}
/* Over the reef sand these sit on a background measured at luminance 217
   while the type is 246 — invisible. Every forest heading already carries
   a shadow for the same reason; this is that rule, in the water. */
.dv-sea-h{font-family:var(--font-heading);color:#EAF9FF;line-height:1.04;margin:0;
  text-shadow:0 1px 2px rgba(3,29,42,.85), 0 2px 18px rgba(3,29,42,.8), 0 0 34px rgba(3,29,42,.6)}
/* The lede is 15px on the same sand and needs a tighter, denser halo than the
   54px heading: at that size a wide soft shadow spreads out from between the
   strokes instead of behind them. Measured over the real pixels, this takes the
   ink-vs-ground spread from 125 to the heading's own range. */
.dv-sea-lede{text-shadow:0 1px 2px rgba(3,29,42,.92), 0 1px 8px rgba(3,29,42,.85), 0 0 18px rgba(3,29,42,.7)}
.sea-kick{display:inline-flex;align-items:center;gap:9px;font-size:var(--fs-read);font-weight:800;letter-spacing:.22em;text-transform:uppercase;color:#9FE3F0}
.sea-kick i{display:block;width:26px;height:2px;background:#9FE3F0;border-radius:2px}
.sea-kick.surf{color:#0B4A5A}
.sea-kick.surf i{background:#0B4A5A;opacity:.55}
.reef-hero{position:relative;width:min(360px,64vw);aspect-ratio:1;margin:0 auto}
.reef-hero svg{position:absolute;inset:0;width:100%;height:100%}
.reef-hero img{position:absolute;left:16.5%;top:16.5%;width:67%;height:67%;object-fit:cover;border-radius:50%;filter:saturate(1.02)}
.reef-hero:hover img{transform:scale(1.03)}
.reef-hero img{transition:transform .6s cubic-bezier(.22,1,.36,1)}
.sea-pill{display:inline-flex;align-items:center;gap:8px;border:none;cursor:pointer;font-family:var(--font-body);font-size:15px;font-weight:700;padding:14px 26px;border-radius:999px;background:#EAF9FF;color:#0B3A55;box-shadow:0 10px 22px rgba(3,26,44,.35);transition:transform .35s cubic-bezier(.22,1,.36,1),background-color .3s ease,color .3s ease}
.sea-pill:hover{transform:translateY(-3px);background:#8EE6D2;color:#062B41}
.sea-pill.ghost{background:rgba(9,40,58,.5);backdrop-filter:blur(7px);-webkit-backdrop-filter:blur(7px);color:#EAF9FF;border:2px solid rgba(207,238,247,.45);box-shadow:none}
.sea-pill.ghost:hover{background:rgba(142,230,210,.22);border-color:#8EE6D2;color:#EAF9FF}
.port{position:relative;display:block;width:100%;max-width:250px;aspect-ratio:1;margin:0 auto 14px}
.port svg{position:absolute;inset:0;width:100%;height:100%}
.port img{position:absolute;left:18%;top:18%;width:64%;height:64%;object-fit:cover;border-radius:50%;transition:transform .6s cubic-bezier(.22,1,.36,1)}
.pcard{display:block;color:#DCEFF7;text-align:center;transition:transform .4s cubic-bezier(.22,1,.36,1)}
.pcard:hover{transform:translateY(-8px)}
.pcard:hover .port img{transform:scale(1.05)}
.pcard b{display:block;font-family:var(--font-heading);font-weight:400;font-size:17px;line-height:1.3;color:#EAF9FF;max-width:250px;margin:0 auto 6px}
.pcard span{font-size:var(--fs-read);font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:#7FD6E8}
.plank{overflow:hidden;white-space:nowrap;padding:16px 0;border-top:1px solid rgba(255,255,255,.12);border-bottom:1px solid rgba(255,255,255,.12)}
.plank>div{display:flex;width:max-content;gap:18px;align-items:center;animation:plankM 42s linear infinite}
@keyframes plankM{from{transform:translateX(0)}to{transform:translateX(calc(-50% - 9px))}}
.plank span{background:rgba(234,249,255,.92);border-radius:999px;padding:9px 24px;display:inline-flex;flex:none}
.plank img{height:30px;width:auto;display:block}


/* ══════════════════════════════════════════════════════════════════════
   TERUMBU VECTOR — gerak penghuni terumbu.
   Gerak penghuni terumbu di dalam #dv-sea: lonceng/lengan/benang ubur-ubur,
   lambaian kelp dan rumput laut, denyut karang & spons, dan debu laut yang naik.
   Catatan: aturan .mote di sini SENGAJA menimpa .mote dari blok sebelumnya
   (urutan aslinya dipertahankan), jadi debu di hutan ikut memakai
   animasi baru ini.
   ══════════════════════════════════════════════════════════════════════ */
.jBell{transform-box:fill-box;transform-origin:50% 94%;animation:jBell var(--sy,4.6s) ease-in-out infinite}
@keyframes jBell{0%,100%{transform:scale(1,1)}42%{transform:scale(.9,1.15)}70%{transform:scale(1.06,.94)}}
.jArm{transform-box:fill-box;transform-origin:50% 0%;animation:jArm var(--sy,6s) ease-in-out infinite}
@keyframes jArm{0%,100%{transform:rotate(-4.5deg) scaleY(.98)}50%{transform:rotate(4.5deg) scaleY(1.05)}}
.jThr{transform-box:fill-box;transform-origin:50% 0%;animation:jThr var(--sy,7.6s) ease-in-out infinite}
@keyframes jThr{0%,100%{transform:rotate(-7deg)}50%{transform:rotate(7deg)}}
.kelpB{transform-box:fill-box;transform-origin:50% 100%;animation:kelpB var(--sy,9s) ease-in-out infinite;animation-delay:var(--sd,0s)}
@keyframes kelpB{0%,100%{transform:rotate(-3.6deg) skewX(2.6deg)}50%{transform:rotate(3.6deg) skewX(-2.6deg)}}
.grsB{transform-box:fill-box;transform-origin:50% 100%;animation:grsB var(--sy,5.4s) ease-in-out infinite;animation-delay:var(--sd,0s)}
@keyframes grsB{0%,100%{transform:rotate(-5deg)}50%{transform:rotate(5deg)}}
.mote{animation:mote var(--sy,13s) linear infinite;animation-delay:var(--sd,0s)}
@keyframes mote{0%{transform:translate(0,40px);opacity:0}14%{opacity:.9}86%{opacity:.7}100%{transform:translate(28px,-420px);opacity:0}}
.corB{transform-box:fill-box;transform-origin:50% 100%;animation:corB var(--sy,11s) ease-in-out infinite;animation-delay:var(--sd,0s)}
@keyframes corB{0%,100%{transform:rotate(-1.3deg) scale(1)}50%{transform:rotate(1.3deg) scale(1.014)}}
.spgB{transform-box:fill-box;transform-origin:50% 100%;animation:spgB var(--sy,13s) ease-in-out infinite;animation-delay:var(--sd,0s)}
@keyframes spgB{0%,100%{transform:scale(1,1)}50%{transform:scale(1.018,.986)}}
.jTilt{transform-box:fill-box;transform-origin:50% 8%;animation:jTilt var(--sy,17s) ease-in-out infinite;animation-delay:var(--sd,0s)}
@keyframes jTilt{0%,100%{transform:rotate(calc(var(--t,14deg) - 5deg))}50%{transform:rotate(calc(var(--t,14deg) + 5deg))}}


/* ══════════════════════════════════════════════════════════════════════
   SPECIES MAP — peta habitat "Explore" di puncak halaman Species.
   Markup: site-src/pages/species.html (#smap). Hit element (#smapHits) dirender
   species.js dari DA_MAP + DA_SPECIES; scene WebGL, label kanvas, lensa, dan mode
   (.is-gl / .is-strip) diatur js/species-map.js. Semua aturan di-scope ke
   body[data-page="species"].
   Lapisan (z): stage 1 · hits 2 · zone chip 5 · skip 6 · hint 50 (fixed) ·
   bar 55 (fixed, di bawah nav 60; chat #daChat 180 tetap kanan-bawah).
   ══════════════════════════════════════════════════════════════════════ */
body[data-page="species"] .smap { position: relative; height: 100svh; min-height: 560px; overflow: hidden; background: var(--color-bg); user-select: none; -webkit-user-select: none; touch-action: pan-y; outline: none; }
body[data-page="species"] .smap:focus-visible { box-shadow: inset 0 0 0 3px var(--dv-sun); }
/* Poster = the whole world at low res, laid out like the GL world (125vw wide, centred,
   top-aligned) so the cross-fade to the canvas does not jump in scale. */
body[data-page="species"] .smap-poster { position: absolute; top: 0; left: -12.5%; width: 125%; height: auto; max-width: none; z-index: 0; pointer-events: none; transition: opacity .8s ease; }
body[data-page="species"] .smap.is-strip .smap-poster { left: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 12%; }   /* 12%: frog towers, not the sky */
body[data-page="species"] .smap-stage { position: absolute; inset: 0; z-index: 1; opacity: 0; transition: opacity .8s ease; }
body[data-page="species"] .smap.is-gl .smap-stage { opacity: 1; }
body[data-page="species"] .smap-stage canvas { display: block; width: 100%; height: 100%; cursor: grab; }
body[data-page="species"] .smap.is-dragging .smap-stage canvas { cursor: grabbing; }
body[data-page="species"] .smap.is-hot .smap-stage canvas { cursor: pointer; }

/* — hit elements: percent-anchored inside the world-sized #smapHits — */
body[data-page="species"] .smap-hits { position: absolute; left: 0; top: 0; z-index: 2; pointer-events: none; will-change: transform; }
body[data-page="species"] .smap-hits > * { position: absolute; pointer-events: auto; display: flex; flex-direction: column; align-items: flex-start; gap: 2px; margin: 0; padding: 0; border: 0; background: none; color: transparent; text-decoration: none; text-align: left; white-space: nowrap; font-family: var(--font-body); cursor: pointer; -webkit-tap-highlight-color: transparent; }
body[data-page="species"] .smap-hits > *:focus-visible { outline: 2px solid var(--dv-sun); outline-offset: 6px; border-radius: 8px; }
body[data-page="species"] .smap-hits .smap-hit__k { font-size: var(--fs-read); font-weight: 700; letter-spacing: .16em; text-transform: uppercase; }
body[data-page="species"] .smap-hits .smap-hit__t { font-family: var(--font-heading); font-weight: 400; font-size: 26px; line-height: 1.05; }
body[data-page="species"] .smap-hits .smap-hit__c { font-size: var(--fs-read); font-weight: 600; }
body[data-page="species"] .smap-hits > .is-dim { opacity: .35; }
/* GL mode: the text is drawn by the shader; the DOM box only carries hover/focus/click. */
body[data-page="species"] .smap.is-gl .smap-hits > * { color: transparent !important; background: none !important; text-shadow: none; }
body[data-page="species"] .smap.is-gl .smap-hits > .is-dim { opacity: 1; }

/* — skip link (visually hidden until focused) — */
body[data-page="species"] .smap-skip { position: absolute; left: 16px; top: 16px; z-index: 6; padding: 10px 16px; border-radius: 999px; background: var(--dv-sun); color: var(--dv-ink); font-weight: 700; font-size: var(--fs-read); box-shadow: 0 3px 0 rgba(0, 0, 0, .16); clip: rect(0 0 0 0); clip-path: inset(50%); width: 1px; height: 1px; overflow: hidden; white-space: nowrap; }
body[data-page="species"] .smap-skip:focus { clip: auto; clip-path: none; width: auto; height: auto; overflow: visible; outline: 2px solid var(--dv-ink); outline-offset: 2px; }

/* — "Geser untuk menjelajah" pill follows the pointer (positioned by the module) — */
body[data-page="species"] .smap-hint { position: fixed; left: 0; top: -22px; z-index: 50; display: flex; align-items: center; gap: 10px; height: 44px; padding: 0 18px 0 4px; border-radius: 999px; background: var(--dv-sun); color: var(--dv-ink); font: 700 14px/1 var(--font-body); box-shadow: 0 3px 0 rgba(0, 0, 0, .16); pointer-events: none; transform-origin: center; will-change: transform, opacity; white-space: nowrap; }
body[data-page="species"] .smap-hint[hidden] { display: none; }
body[data-page="species"] .smap-hint__dot { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%; background: var(--dv-ink); color: var(--dv-cream); flex: none; }
body[data-page="species"] .smap-hint__dot svg { width: 18px; height: 18px; }

/* — zone chip (bottom-left): which "Dunia" is in the middle of the stage — */
body[data-page="species"] .smap-zone { position: absolute; left: calc(max(5vw, 50vw - 620px + 5vw) + 28px); bottom: 28px; z-index: 5; transition: background-color .35s ease; display: flex; flex-direction: column; gap: 2px; padding: 12px 22px 14px; border-radius: 999px; background: var(--dv-cream); color: var(--dv-ink); box-shadow: 0 3px 0 rgba(0, 0, 0, .16); pointer-events: none; }
body[data-page="species"] .smap-zone[hidden] { display: none; }
body[data-page="species"] .smap-zone small { font: 700 var(--fs-read)/1 var(--font-body); letter-spacing: .16em; text-transform: uppercase; color: var(--color-accent-700); }
body[data-page="species"] .smap-zone b { font-family: var(--font-heading); font-weight: 400; font-size: 26px; line-height: 1.05; color: var(--dv-ink); }

/* — Peta | Daftar bar: marigold pill with a dark round knob, fixed bottom-centre — */
body[data-page="species"] .smap-bar { position: fixed; left: 50%; bottom: 20px; z-index: 55; width: 300px; height: 60px; margin-left: -150px; display: grid; grid-template-columns: 1fr 1fr; align-items: stretch; border-radius: 999px; background: var(--dv-sun); box-shadow: 0 3px 0 rgba(0, 0, 0, .16); transition: transform .45s cubic-bezier(.22, 1, .36, 1), opacity .3s ease; }
body[data-page="species"] .smap-bar:hover { transform: translateY(-2px); }
body[data-page="species"] .smap-bar__btn { appearance: none; border: 0; background: none; margin: 0; padding: 0; font: 700 var(--fs-read)/1 var(--font-body); letter-spacing: .04em; text-transform: uppercase; color: var(--dv-ink); cursor: pointer; opacity: .55; transition: opacity .3s ease; display: flex; align-items: center; }
body[data-page="species"] .smap-bar__btn:first-child { justify-content: flex-end; padding-right: 46px; border-radius: 999px 0 0 999px; opacity: 1; }
body[data-page="species"] .smap-bar__btn:last-child { justify-content: flex-start; padding-left: 46px; border-radius: 0 999px 999px 0; }
body[data-page="species"] .smap-bar.is-list .smap-bar__btn:first-child { opacity: .55; }
body[data-page="species"] .smap-bar.is-list .smap-bar__btn:last-child { opacity: 1; }
body[data-page="species"] .smap-bar__btn:hover { opacity: 1; color: var(--dv-ink); }
body[data-page="species"] .smap-bar__btn:focus-visible { outline: 2px solid var(--dv-ink); outline-offset: -6px; }
body[data-page="species"] .smap-bar__knob { position: absolute; left: 50%; top: 50%; width: 64px; height: 64px; margin: -32px 0 0 -32px; border-radius: 50%; background: var(--color-accent-900, #193218); color: var(--dv-cream); display: grid; place-items: center; box-shadow: 0 3px 0 rgba(0, 0, 0, .16); pointer-events: none; }
body[data-page="species"] .smap-bar__knob svg { width: 26px; height: 26px; }
/* keep clear of the DARA chat panel (bottom-right) while it is open */
body[data-page="species"]:has(#daChat.open) .smap-bar { opacity: 0; pointer-events: none; }
/* — reveal state (.is-full): whole frame in colour, the bottom melts into the paper — */
body[data-page="species"] .smap.is-full .smap-zone { background: var(--dv-sun); }
body[data-page="species"] .smap.is-full .smap-stage canvas { cursor: default; }
body[data-page="species"] .smap-veil { position: absolute; left: 0; right: 0; bottom: 0; height: 38%; z-index: 3; opacity: 0; pointer-events: none; background: linear-gradient(transparent, var(--color-bg)); transition: opacity .6s ease; }
body[data-page="species"] .smap.is-full .smap-veil { opacity: 1; }
body[data-page="species"] .smap-bar__knob { overflow: hidden; }
body[data-page="species"] .smap-bar__ico { position: absolute; transition: opacity .25s ease; }
body[data-page="species"] .smap-bar__ico--list { opacity: 0; }
body[data-page="species"] .smap-bar.is-list .smap-bar__ico--map { opacity: 0; }
body[data-page="species"] .smap-bar.is-list .smap-bar__ico--list { opacity: 1; }
@keyframes spHop { 0%, 100% { transform: translateY(0); } 40% { transform: translateY(-6px); } }
body[data-page="species"] .smap-bar.is-landing .smap-bar__knob { animation: spHop .5s cubic-bezier(.22, 1, .36, 1) 1; }
body[data-page="species"] .smap-bar.is-landing .smap-bar__btn:last-child { opacity: 1; }
body[data-page="species"] .smap.is-strip .smap-zone-hit { position: relative; }
body[data-page="species"] .smap.is-strip .smap-zone-hit[aria-pressed="true"] { background: var(--dv-sun); }
body[data-page="species"] .smap.is-strip .smap-zone-hit.is-pop::after { content: ''; position: absolute; inset: -6px; border-radius: 999px; border: 3px solid var(--dv-sun); animation: dvSplash .5s ease-out 1 forwards; pointer-events: none; }
@media (max-width: 940px) {
  body[data-page="species"] .smap-bar { display: none; }
}
@media (hover: none) {
  body[data-page="species"] .smap-hint { display: none !important; }
}

/* — strip fallback (touch / narrow / reduced motion / no WebGL2 / save-data) — */
body[data-page="species"] .smap.is-strip { height: clamp(320px, 52svh, 480px); min-height: 0; }
body[data-page="species"] .smap.is-strip::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 140px; z-index: 1; background: linear-gradient(transparent, rgba(25, 50, 24, .55)); pointer-events: none; }
body[data-page="species"] .smap.is-strip .smap-stage,
body[data-page="species"] .smap.is-strip .smap-bar,
body[data-page="species"] .smap.is-strip .smap-hint,
body[data-page="species"] .smap.is-strip .smap-zone,
body[data-page="species"] .smap.is-strip .smap-veil,
body[data-page="species"] .smap.is-strip .smap-pin-hit { display: none !important; }
body[data-page="species"] .smap.is-strip .smap-poster { opacity: 1 !important; }
/* The scrollbar is hidden, so the row's only "there is more" cue was a half-cut chip
   (chip 3 cut at x 390): a 40px fade on the right edge, and the same 40px of end
   padding so the last chip is not dimmed once the row is scrolled to its end. */
body[data-page="species"] .smap.is-strip .smap-hits { position: absolute; left: 0; right: 0; top: auto; bottom: 14px; width: auto !important; height: auto !important; transform: none !important; display: flex; gap: 8px; overflow-x: auto; overflow-y: hidden; padding: 0 40px 0 16px; pointer-events: auto; touch-action: pan-x pan-y; scrollbar-width: none; -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity; scroll-padding-inline: 16px; -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 40px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 40px), transparent); }
body[data-page="species"] .smap.is-strip .smap-hits::-webkit-scrollbar { display: none; }
body[data-page="species"] .smap.is-strip .smap-zone-hit { position: static; flex: none; width: auto !important; height: auto !important; padding: 9px 18px 10px; border-radius: 999px; background: var(--dv-cream); color: var(--dv-ink); box-shadow: 0 3px 0 rgba(0, 0, 0, .16); scroll-snap-align: start; transition: transform .3s cubic-bezier(.22, 1, .36, 1); }
body[data-page="species"] .smap.is-strip .smap-zone-hit:hover { transform: translateY(-2px); }
body[data-page="species"] .smap.is-strip .smap-zone-hit .smap-hit__k { font-size: var(--fs-min); color: var(--color-accent-700); }
body[data-page="species"] .smap.is-strip .smap-zone-hit .smap-hit__t { font-size: 18px; }
body[data-page="species"] .smap.is-strip .smap-hits > .is-dim { opacity: .45; }
@media (prefers-reduced-motion: reduce) {
  body[data-page="species"] .smap-stage, body[data-page="species"] .smap-poster, body[data-page="species"] .smap-bar, body[data-page="species"] .smap-bar__btn, body[data-page="species"] .smap-veil, body[data-page="species"] .smap-zone { transition: none; }
  body[data-page="species"] .smap-zone-hit.is-pop::after, body[data-page="species"] .smap-bar.is-landing .smap-bar__knob { animation: none !important; }
  body[data-page="species"] .smap-hint { display: none !important; }
}


/* ══════════════════════════════════════════════════════════════════════
   SPECIES LIST — "Kelanjutan dunia" (2026-09-06). Setelah lensa menelan layar, LIST
   melanjutkan dunia yang sama: hero = potongan ubin warna distrik yang diklik, plakat
   krem (keluarga #smapZone), jalur enam dunia, kartu penghuni di atas kertas.
   Semua di-scope body[data-page="species"]. Token per dunia hanya dua: --sp-tint (latar
   hero) dan --sp-accent-ink (kicker, nomor stop aktif, asal kartu, titik fase).
   ══════════════════════════════════════════════════════════════════════ */
body[data-page="species"] .sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
body[data-page="species"] .sp { position: relative; padding-top: 22px; background: var(--color-bg); --sp-accent-ink: #264e25; --sp-tint: #EAF0E4; }
body[data-page="species"] .sp[data-world="amfibi"]    { --sp-accent-ink: #2E7A41; --sp-tint: #EEF5E6; }
body[data-page="species"] .sp[data-world="tanaman"]   { --sp-accent-ink: #366d33; --sp-tint: #EDF6E0; }
body[data-page="species"] .sp[data-world="mikro"]     { --sp-accent-ink: #59392C; --sp-tint: #F3ECE0; }
body[data-page="species"] .sp[data-world="kesehatan"] { --sp-accent-ink: #A63D2A; --sp-tint: #FFF0E6; }
body[data-page="species"] .sp[data-world="reptil"]    { --sp-accent-ink: #1F5D33; --sp-tint: #F5EEDB; }
body[data-page="species"] .sp[data-world="akuatik"]   { --sp-accent-ink: #0B577C; --sp-tint: #E2F3F3; }

/* — hero: potongan dunia yang sama — */
body[data-page="species"] .sp-hero { position: relative; width: calc(100% - 10vw); max-width: calc(1240px - 10vw); margin: 0 auto; height: clamp(360px, 46vh, 520px); border-radius: calc(var(--radius-lg) * 1.6); overflow: hidden; background: var(--sp-tint); transition: background-color .6s ease; contain: paint; }
body[data-page="species"] .sp-hero__cam { position: absolute; inset: -24px; }
body[data-page="species"] .sp-hero__poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 12%; max-width: none; }
body[data-page="species"] .sp-hero__strip { position: absolute; left: 24px; top: 24px; display: flex; aspect-ratio: 2 / 1; width: 160%; }
body[data-page="species"] .sp-hero__strip.is-b { opacity: 0; }
body[data-page="species"] .sp-hero__tile { flex: none; width: 50%; height: 100%; object-fit: fill; max-width: none; opacity: 0; transition: opacity .45s ease; }
body[data-page="species"] .sp-hero__tile:first-child { width: calc(50% + 1px); }
body[data-page="species"] .sp-hero__tile.is-loaded { opacity: 1; }
body[data-page="species"] .sp-hero__grain { position: absolute; inset: 0; background: url(../assets/species-map/noise-512.png) 0 0 / 512px; mix-blend-mode: multiply; opacity: .14; pointer-events: none; }
body[data-page="species"] .sp-hero__wash { position: absolute; inset: 0; background: linear-gradient(transparent 55%, rgba(23, 63, 39, .30)), radial-gradient(120% 90% at 50% 40%, transparent 62%, rgba(23, 63, 39, .16)); pointer-events: none; }
body[data-page="species"] .sp-plaque { position: absolute; left: 28px; bottom: 28px; z-index: 2; max-width: min(560px, calc(100% - 56px)); padding: 20px 26px 22px; border-radius: 28px; background: var(--dv-cream); color: var(--dv-ink); box-shadow: 0 3px 0 rgba(23, 63, 39, .18), 0 18px 40px rgba(23, 63, 39, .16); }
body[data-page="species"] .sp-crumb { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; font-size: var(--fs-read); color: #5c6356; margin-bottom: 10px; }
body[data-page="species"] .sp-crumb a, body[data-page="species"] .sp-crumb__lnk { color: #5c6356; }
body[data-page="species"] .sp-crumb__lnk { appearance: none; border: 0; background: none; padding: 0; margin: 0; font: inherit; cursor: pointer; }
body[data-page="species"] .sp-crumb__lnk[aria-current="page"] { cursor: default; }
body[data-page="species"] .sp-crumb a:hover, body[data-page="species"] .sp-crumb__lnk:not([aria-current]):hover { color: var(--color-accent-700); }
body[data-page="species"] .sp-crumb__cur { color: var(--dv-ink); font-weight: 700; }
body[data-page="species"] .sp-plaque__kicker { display: block; color: var(--sp-accent-ink); transition: color .6s ease; }
body[data-page="species"] .sp-plaque__tail { color: inherit; }   /* the accent tail only exists on phones (<=640 block) */
body[data-page="species"] .sp-plaque__title { font-family: var(--font-heading); font-weight: 400; font-size: clamp(40px, 5vw, 76px); line-height: .98; letter-spacing: -.01em; margin: 6px 0 8px; text-wrap: balance; outline: none; scroll-margin-top: calc(var(--sp-stick, 84px) + 12px); }
body[data-page="species"] .sp-plaque__title:focus-visible { outline: 3px solid var(--dv-ink); outline-offset: 6px; border-radius: 6px; }
body[data-page="species"] .sp-plaque__lede { margin: 0; font-size: 15.5px; line-height: 1.55; color: rgba(23, 63, 39, .82); max-width: 46ch; }
body[data-page="species"] .sp-plaque__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin-top: 14px; font: 600 var(--fs-read)/1 var(--font-body); color: #5c6356; }
body[data-page="species"] .sp-plaque__stat { display: inline-flex; align-items: baseline; gap: 5px; }
body[data-page="species"] .sp-plaque__stat b { font-family: var(--font-heading); font-weight: 400; font-size: 20px; color: var(--sp-accent-ink); transition: color .6s ease; }
body[data-page="species"] .sp-plaque__tag { border: 1.5px solid var(--dv-ink); border-radius: 999px; padding: 5px 10px; font-size: var(--fs-read); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--dv-ink); }
body[data-page="species"] .sp-plaque__back { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 4px; color: var(--dv-ink); font-weight: 700; text-decoration: underline dotted; text-underline-offset: 4px; }
body[data-page="species"] .sp-plaque__back:hover { color: var(--color-accent-700); }

/* — jalur enam dunia (sticky di bawah nav) — */
body[data-page="species"] .sp-trail { position: sticky; top: var(--sp-stick, 84px); z-index: 40; margin: 22px auto 0; max-width: 1240px; padding: 8px 5vw; background: color-mix(in srgb, var(--color-bg) 90%, transparent); }
@media (min-width: 941px) { body[data-page="species"] .sp-trail { backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); } }
body[data-page="species"] .sp-trail::before { content: ''; position: absolute; left: 5vw; right: 5vw; top: 50%; border-top: 3px dotted rgba(23, 63, 39, .22); }
body[data-page="species"] .sp-trail__stops { position: relative; display: flex; gap: 8px; align-items: center; overflow-x: auto; scroll-snap-type: x proximity; scrollbar-width: none; padding: 2px 0; }
body[data-page="species"] .sp-trail__stops::-webkit-scrollbar { display: none; }
body[data-page="species"] .sp-trail__marker { position: absolute; left: 0; top: 0; width: 0; height: 44px; border-radius: 999px; background: var(--dv-sun); box-shadow: 0 3px 0 rgba(23, 63, 39, .16); pointer-events: none; opacity: 0; }
body[data-page="species"] .sp-stop { position: relative; z-index: 1; flex: none; display: inline-flex; align-items: center; gap: 8px; height: 44px; padding: 0 13px 0 7px; border-radius: 999px; border: 1.5px solid rgba(23, 63, 39, .16); background: var(--dv-cream); color: var(--dv-ink); font: 700 var(--fs-read)/1 var(--font-body); cursor: pointer; box-shadow: 0 3px 0 rgba(23, 63, 39, .12); scroll-snap-align: center; transition: transform .3s cubic-bezier(.22, 1, .36, 1), box-shadow .3s ease, background-color .3s ease, border-color .3s ease; }
body[data-page="species"] .sp-stop__n { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--dv-ink); color: var(--dv-cream); font: 400 13px/1 var(--font-heading); transition: background-color .3s ease; }
body[data-page="species"] .sp-stop__n svg { width: 14px; height: 14px; }
body[data-page="species"] .sp-stop__c { font-size: var(--fs-min); font-weight: 600; color: #5c6356; }
body[data-page="species"] .sp-stop__c.is-zero { color: #5c6356; }
body[data-page="species"] .sp-stop[aria-pressed="true"] { background: transparent; border-color: transparent; box-shadow: none; }
body[data-page="species"] .sp-stop[aria-pressed="true"] .sp-stop__n { background: var(--sp-accent-ink); }
body[data-page="species"] .sp-trail.is-scroll .sp-stop[aria-pressed="true"] { background: var(--dv-sun); border-color: transparent; box-shadow: 0 3px 0 rgba(23, 63, 39, .16); }
body[data-page="species"] .sp-stop:focus-visible, body[data-page="species"] .sp-chip:focus-visible, body[data-page="species"] .sp-card:focus-visible, body[data-page="species"] .sp-plaque__back:focus-visible { outline: 3px solid var(--dv-ink); outline-offset: 3px; }

/* — toolbar: cari, jumlah, reset, tag — */
body[data-page="species"] .sp-toolbar { max-width: 1240px; margin: 14px auto 0; padding: 0 5vw; }
body[data-page="species"] .sp-toolbar__row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
body[data-page="species"] .sp-search { display: flex; align-items: center; gap: 10px; flex: 1 1 280px; max-width: 440px; height: 46px; padding: 0 8px 0 16px; border-radius: 999px; border: 1.5px solid rgba(23, 63, 39, .14); background: var(--dv-cream); box-shadow: 0 3px 0 rgba(23, 63, 39, .10); cursor: text; }
body[data-page="species"] .sp-search__ico { width: 16px; height: 16px; color: var(--color-accent-700); flex: none; }
body[data-page="species"] .sp-search input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; font: 400 14px var(--font-body); color: var(--color-text); }
body[data-page="species"] .sp-search input::placeholder { color: #5c6356; opacity: 1; }
body[data-page="species"] .sp-search:focus-within { outline: 2px solid var(--sp-accent-ink); outline-offset: 2px; }
body[data-page="species"] #fqClear { width: 26px; height: 26px; flex: none; border: 0; border-radius: 999px; background: var(--dv-ink); color: var(--dv-cream); font-size: var(--fs-min); font-weight: 700; cursor: pointer; }
body[data-page="species"] #fqClear[hidden] { display: none; }
body[data-page="species"] .sp-found { display: inline-flex; align-items: baseline; gap: 5px; margin: 0; font: 600 var(--fs-read)/1 var(--font-body); color: #5c6356; }
body[data-page="species"] .sp-found b { font: 400 16px/1 var(--font-heading); color: var(--dv-ink); }
body[data-page="species"] .sp-reset { display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 14px; border: 0; border-radius: 999px; background: var(--color-accent-100); color: var(--color-accent-800); font: 700 var(--fs-read) var(--font-body); cursor: pointer; transition: background-color .25s ease; }
body[data-page="species"] .sp-reset:hover { background: var(--color-accent-200); }
body[data-page="species"] .sp-reset[hidden] { display: none; }
body[data-page="species"] .sp-toolbar__tags { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
body[data-page="species"] .sp-toolbar__tags[hidden] { display: none; }
body[data-page="species"] .sp-tags { display: contents; }
body[data-page="species"] .sp-chip { display: inline-flex; flex: none; white-space: nowrap; align-items: center; gap: 6px; height: 34px; padding: 0 14px; border-radius: 999px; border: 1.5px solid rgba(23, 63, 39, .16); background: var(--dv-cream); color: var(--dv-ink); font: 700 var(--fs-read)/1 var(--font-body); cursor: pointer; text-decoration: none; transition: transform .3s cubic-bezier(.22, 1, .36, 1), background-color .25s ease, border-color .25s ease, color .25s ease; }
body[data-page="species"] .sp-chip i { font-style: normal; font-size: var(--fs-min); color: #5c6356; }
body[data-page="species"] .sp-chip[aria-pressed="true"] { background: var(--color-accent-2-100); border-color: var(--color-accent-2-600); color: var(--color-accent-2-800); }
body[data-page="species"] .sp-chip--more { border-style: dashed; background: transparent; }
body[data-page="species"] .sp-chip--more[hidden] { display: none; }

/* — grid + kartu penghuni — */
body[data-page="species"] .sp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(264px, 1fr)); gap: 22px; max-width: 1240px; margin: 22px auto 0; padding: 0 5vw; }
body[data-page="species"] .sp-grid.is-pending > * { opacity: 0; }
html.no-motion body[data-page="species"] .sp-grid.is-pending > * { opacity: 1; }
body[data-page="species"] .sp-card { position: relative; display: flex; flex-direction: column; border-radius: 24px; background: var(--dv-cream); border: 1.5px solid rgba(23, 63, 39, .12); box-shadow: 0 3px 0 rgba(23, 63, 39, .14); color: var(--dv-ink); text-decoration: none; overflow: hidden; scroll-margin-top: calc(var(--sp-stick, 84px) + 70px); transition: transform .45s cubic-bezier(.22, 1, .36, 1), box-shadow .45s ease; }
body[data-page="species"] .sp-card:hover { color: var(--dv-ink); }
body[data-page="species"] .sp-card__plate { display: block; position: relative; aspect-ratio: 1; margin: 10px 10px 0; border-radius: 18px; background: #fff; box-shadow: inset 0 0 0 1px rgba(23, 63, 39, .08); overflow: hidden; }
body[data-page="species"] .sp-card__img { display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .45s ease, transform .7s cubic-bezier(.22, 1, .36, 1); }
body[data-page="species"] .sp-card__img.is-loaded, html.no-motion body[data-page="species"] .sp-card__img { opacity: 1; }
body[data-page="species"] .sp-card__body { display: flex; flex-direction: column; gap: 6px; padding: 14px 16px 16px; flex: 1; }
body[data-page="species"] .sp-card__origin { display: flex; align-items: center; gap: 8px; font: 800 var(--fs-min)/1 var(--font-body); letter-spacing: .14em; text-transform: uppercase; color: var(--sp-accent-ink); }
body[data-page="species"] .sp-flag { width: 17px; height: 12.75px; border-radius: 2.5px; background-size: cover; background-position: center; box-shadow: 0 0 0 1px rgba(23, 63, 39, .2); flex: none; }
body[data-page="species"] .sp-iucn { margin-left: auto; font: 800 var(--fs-min)/1 var(--font-body); letter-spacing: .08em; padding: 3px 6px; border-radius: 6px; border: 1.5px solid currentColor; color: var(--dv-ink); }
body[data-page="species"] .sp-iucn.is-vu { color: #A66A00; }
body[data-page="species"] .sp-iucn.is-en, body[data-page="species"] .sp-iucn.is-cr { color: #A63D2A; }
body[data-page="species"] .sp-iucn.is-ne, body[data-page="species"] .sp-iucn.is-dd { color: #5c6356; }
body[data-page="species"] .sp-card__name { margin-top: 2px; font: 400 20px/1.12 var(--font-heading); transition: color .3s ease; }
body[data-page="species"] .sp-card__sci { font: italic 400 var(--fs-read)/1.35 var(--font-body); color: #5c6356; }
body[data-page="species"] .sp-phase { display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0 0; padding: 0; list-style: none; }
/* the pill sizes to its own label instead of to a 72px grid cell: at 10.5px in
   the old repeat(4,1fr) 199 of 965 labels already ran over their dashed border
   (overflow is visible, so scrollWidth reported nothing), and at the floor it
   would have been 221. Below 941 the dots at :783 take over and win. */
body[data-page="species"] .sp-phase li { flex: 0 0 auto; padding: 0 8px; display: flex; align-items: center; justify-content: center; gap: 5px; height: 26px; border-radius: 7px; border: 1.5px dashed rgba(23, 63, 39, .28); font: 700 var(--fs-read)/1 var(--font-body); color: #5c6356; text-decoration: line-through; white-space: nowrap; }
body[data-page="species"] .sp-phase li.on { border: 0; background: var(--color-accent-100); color: var(--color-accent-800); text-decoration: none; }
body[data-page="species"] .sp-phase li.on::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--sp-accent-ink); }
body[data-page="species"] .sp-avail { align-self: flex-start; margin-top: 6px; }
body[data-page="species"] .sp-card__foot { display: flex; flex-wrap: wrap; row-gap: 8px; justify-content: flex-end; align-items: center; gap: 10px; margin-top: auto; padding-top: 10px; border-top: 1px solid rgba(23, 63, 39, .10); }
/* wraps above 520 too: between 1025 and 1100 .sp-grid still uses minmax(264px)
   but the column has narrowed to ~292px, and that band sat above the ceiling
   of a @media-scoped fix. justify-content:flex-end (not margin-left:auto on
   .sp-card__go) is what keeps the arrow on the right when the row breaks: the
   price already owns the free space with margin-left:auto, so a second auto
   margin would split it and move the price at every width. At <=520 the foot
   is a fixed two-row grid instead (see the 520 block): there the 220px foot
   never held pill + price + arrow and the arrow floated alone on row 2. */
body[data-page="species"] .sp-diff { white-space: nowrap; }
body[data-page="species"] .sp-card__price { display: inline-flex; align-items: baseline; gap: 4px; margin-left: auto; font: 400 17px/1 var(--font-heading); color: var(--color-accent-700); white-space: nowrap; }
body[data-page="species"] .sp-card__price small { font: 600 var(--fs-read)/1 var(--font-body); color: #5c6356; }
body[data-page="species"] .sp-card__go { display: grid; place-items: center; width: 34px; height: 34px; flex: none; border-radius: 50%; background: var(--dv-sun); color: var(--dv-ink); box-shadow: 0 3px 0 rgba(23, 63, 39, .16); transition: transform .35s cubic-bezier(.22, 1, .36, 1); }
body[data-page="species"] .sp-card__go svg { width: 16px; height: 16px; }
@media (hover: hover) and (pointer: fine) {
  body[data-page="species"] .sp-card:hover, body[data-page="species"] .sp-card:focus-visible { transform: translateY(-6px) rotate(-.4deg); box-shadow: 0 8px 0 rgba(23, 63, 39, .14), 0 22px 44px rgba(23, 63, 39, .16); }
  body[data-page="species"] .sp-card:hover .sp-card__img { transform: scale(1.05); }
  body[data-page="species"] .sp-card:hover .sp-card__go { transform: translateX(4px) rotate(-8deg); }
  body[data-page="species"] .sp-card:hover .sp-card__name { color: var(--color-accent-700); }
  body[data-page="species"] .sp-stop:hover { transform: translateY(-3px); box-shadow: 0 6px 0 rgba(23, 63, 39, .12); }
  body[data-page="species"] .sp-stop[aria-pressed="true"]:hover { transform: none; box-shadow: none; }
  body[data-page="species"] .sp-chip:hover { transform: translateY(-2px) rotate(-1deg); }
}
@media (hover: none) { body[data-page="species"] .sp-card:active { transform: scale(.985); } }

/* — running head (mode "Semua dunia"), empty state, kartu sketsa, papan katalog — */
body[data-page="species"] .sp-runhead { grid-column: 1 / -1; display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding-top: 10px; border-top: 1px solid var(--color-divider); color: var(--dv-ink); }
body[data-page="species"] .sp-runhead:first-child { border-top: 0; padding-top: 0; }
body[data-page="species"] .sp-runhead .dv-kicker { display: inline-flex; gap: 8px; color: var(--dv-ink); }
body[data-page="species"] .sp-runhead__c { display: inline-flex; align-items: baseline; gap: 5px; font: 600 var(--fs-read)/1 var(--font-body); color: #5c6356; }
body[data-page="species"] .sp-runhead__c b { font: 400 16px/1 var(--font-heading); color: var(--dv-ink); }
body[data-page="species"] .sp-runhead.is-empty .dv-kicker { color: #5c6356; }
body[data-page="species"] .sp-runhead.is-empty a { display: inline-flex; gap: 6px; font-size: var(--fs-read); font-weight: 700; color: var(--color-accent-700); }
body[data-page="species"] .sp-empty { grid-column: 1 / -1; display: grid; grid-template-columns: 1.1fr .9fr; gap: 28px; align-items: center; }
body[data-page="species"] .sp-empty__sign { padding: 30px 34px; border-radius: 28px; background: var(--dv-cream); box-shadow: 0 3px 0 rgba(23, 63, 39, .14); color: var(--dv-ink); }
body[data-page="species"] .sp-empty__sign .dv-kicker { display: inline-flex; gap: 8px; color: var(--sp-accent-ink); }
body[data-page="species"] .sp-empty__h { margin: 8px 0 10px; font: 400 26px/1.1 var(--font-heading); color: var(--dv-ink); }
body[data-page="species"] .sp-empty__sign p { margin: 0; font-size: 14.5px; line-height: 1.55; color: rgba(23, 63, 39, .82); max-width: 52ch; }
body[data-page="species"] .sp-empty__tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
body[data-page="species"] .sp-empty__acts { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }
body[data-page="species"] .sp-empty__try { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 14px; font: 600 var(--fs-read)/1 var(--font-body); color: #5c6356; }
body[data-page="species"] .sp-empty__acts .dv-pill { border: 0; cursor: pointer; font-family: var(--font-body); }
body[data-page="species"] .sp-empty__acts .dv-pill span + span { margin-left: 2px; }
body[data-page="species"] .sp-empty.is-search { display: block; padding: 34px; text-align: center; border-radius: 28px; background: var(--dv-cream); box-shadow: 0 3px 0 rgba(23, 63, 39, .14); }
body[data-page="species"] .sp-empty.is-search .sp-empty__acts { justify-content: center; }
body[data-page="species"] .sp-ghosts { position: relative; display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
body[data-page="species"] .sp-ghost { min-height: 300px; border-radius: 24px; border: 1.5px dashed rgba(23, 63, 39, .3); background: color-mix(in srgb, var(--dv-cream) 60%, var(--color-bg)); }
body[data-page="species"] .sp-ghost:nth-child(2) { transform: translateY(-12px); }
body[data-page="species"] .sp-ghost__plate { aspect-ratio: 1; margin: 10px 10px 0; border-radius: 18px; background: repeating-linear-gradient(135deg, transparent 0 6px, rgba(23, 63, 39, .06) 6px 7px); }
body[data-page="species"] .sp-ghost i { display: block; height: 8px; margin: 12px 16px 0; border-radius: 4px; background: rgba(23, 63, 39, .10); }
body[data-page="species"] .sp-ghost i + i { width: 60%; }
body[data-page="species"] .sp-cta { margin-top: 90px; }
/* — "Muat N lagi": the list is paged (species.js pageSize), the button sits under the grid — */
body[data-page="species"] .sp-more-wrap { display: flex; justify-content: center; max-width: 1240px; margin: 0 auto; padding: 28px 5vw 0; }
body[data-page="species"] .sp-more-wrap[hidden] { display: none; }
body[data-page="species"] .sp-more { flex-direction: column; gap: 2px; min-height: 48px; padding: 10px 26px; border: 0; cursor: pointer; font-family: var(--font-body); line-height: 1.2; text-align: center; }
body[data-page="species"] .sp-more__t b { font-weight: 800; }
body[data-page="species"] .sp-more__c { font-style: normal; font-weight: 600; font-size: var(--fs-min); opacity: .78; }
body[data-page="species"] .sp-more__c b { font-weight: 600; }
body[data-page="species"] .sp-more:focus-visible { outline: 3px solid var(--dv-ink); outline-offset: 3px; }

/* — responsif — */
@media (max-width: 1024px) {
  body[data-page="species"] .sp-plaque { max-width: min(480px, calc(100% - 56px)); }
  body[data-page="species"] .sp-grid { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
}
@media (max-width: 940px) {
  body[data-page="species"] .sp { padding-top: 0; }
  body[data-page="species"] .sp-hero { width: auto; max-width: none; margin: 0; height: auto; min-height: 0; border-radius: 0 0 28px 28px; contain: none; }
  body[data-page="species"] .sp-trail__marker { display: none; }
  body[data-page="species"] .sp-stop[aria-pressed="true"] { background: var(--dv-sun); border-color: transparent; box-shadow: 0 3px 0 rgba(23, 63, 39, .16); }
  body[data-page="species"] .sp-hero__cam { position: relative; inset: auto; height: clamp(220px, 46vw, 300px); }
  body[data-page="species"] .sp-hero__strip { display: none; }
  body[data-page="species"] .sp-plaque { position: relative; left: auto; bottom: auto; margin: -34px 16px 22px; max-width: none; padding: 18px 20px 20px; }
  /* "Semua dunia": the cam shows the poster in the SAME crop as the strip right above it
     (both 50% 12%), so stacked on a phone the first screen was the picture twice — strip
     439px + cam 220px — and the H1 sat at y 702 of 844. Drop the cam until a world is
     chosen (then it shows that district's crop), and shorten the strip here only: the
     unscoped .is-strip rule is also the desktop fallback (reduced motion / no WebGL2).
     H1 now lands at y ~430 at 390, the lede above the chat launcher's corner. */
  body[data-page="species"] .smap.is-strip { height: clamp(280px, 40svh, 400px); }
  body[data-page="species"] .sp[data-world="all"] .sp-hero__cam { display: none; }
  body[data-page="species"] .sp[data-world="all"] .sp-plaque { margin-top: 16px; }
  body[data-page="species"] .sp-plaque__title { font-size: clamp(36px, 11vw, 52px); }
  body[data-page="species"] .sp-trail { top: var(--sp-stick, 64px); margin-top: 0; }
  body[data-page="species"] .sp-trail::before { display: none; }
  /* stops row: hidden scrollbar, the '02' stop cut at the edge was the only cue — same
     40px fade + 40px end padding as the strip chips (32 would leave the last 8px dimmed) */
  body[data-page="species"] .sp-trail__stops { padding-right: 40px; -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 40px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 40px), transparent); }
  /* the grid keeps its 72px bottom padding; the button climbs into it (28px under the last card) */
  body[data-page="species"] .sp-more-wrap { margin-top: -44px; padding: 0 16px; }
  /* Identical to Products here: the world trail (1124px of chips in a 351px row —
     Reptiles and Aquatic animals out of sight) and the tag chips fold into the
     bottom sheet (#filt), opened by the Filter button beside the search pill;
     the count lives in the sheet's apply button, like products.html. */
  body[data-page="species"] .sp-trail, body[data-page="species"] .sp-toolbar__tags, body[data-page="species"] .sp-found, body[data-page="species"] .sp-reset { display: none; }
  body[data-page="species"] .sp-toolbar__row { flex-wrap: nowrap; gap: 10px; }
  body[data-page="species"] .sp-search { flex: 1 1 140px; min-width: 0; max-width: none; height: 44px; }
  body[data-page="species"] .sp-toolbar__tags { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding: 0 40px 4px 0; -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 40px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 40px), transparent); }
  body[data-page="species"] .sp-toolbar__tags::-webkit-scrollbar { display: none; }
  body[data-page="species"] .sp-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; padding: 0 16px 72px; }
  body[data-page="species"] .sp-card__plate { margin: 8px 8px 0; }
  body[data-page="species"] .sp-card__body { padding: 12px 12px 14px; }
  body[data-page="species"] .sp-card__name { font-size: 17px; }
  body[data-page="species"] .sp-card__sci { font-size: var(--fs-read); }
  body[data-page="species"] .sp-card__price { font-size: 15px; }
  body[data-page="species"] .sp-card__go { width: 30px; height: 30px; }
  body[data-page="species"] .sp-phase { display: grid; grid-template-columns: repeat(4, 8px); gap: 5px; }  /* the base rule is flex now; below 941 these are dots, so put the grid back */
  body[data-page="species"] .sp-phase li { padding: 0; font-size: 0; height: 8px; width: 8px; border-radius: 50%; border-width: 1.5px; }
  body[data-page="species"] .sp-phase li.on::before { display: none; }
  body[data-page="species"] .sp-phase li.on { background: var(--sp-accent-ink); }
  body[data-page="species"] .sp-empty { grid-template-columns: 1fr; }
  body[data-page="species"] .sp-ghosts { display: none; }
}
/* — Ponsel (<=640): tanpa seni peta —
   Keputusan pemilik: di ponsel halaman ini untuk MENCARI hewan, bukan melihat
   kampus. Strip poster (40svh) + potongan distrik di atas plakat memakan satu
   layar penuh sebelum kartu pertama (y=1156 di 390), dan enam chip dunia di
   strip itu mengulang jalur lengket persis di bawahnya. Yang hilang di sini:
   #smap, potongan distrik untuk semua dunia, tautan "kembali ke peta", dan
   kicker/lede 'Semua dunia' yang bicara soal peta. Plakat jadi kepala halaman
   biasa: remah roti, judul, lede dunia (kalau ada), lalu jalur dunia lengket,
   pencarian, tag, daftar. Poster.webp (388 KB) tidak diunduh sama sekali:
   <picture> di species.html memberi ponsel gif 1x1, preload-nya ber-media. */
@media (max-width: 640px) {
  body[data-page="species"] .smap { display: none; }
  body[data-page="species"] .sp-hero__cam { display: none; }
  body[data-page="species"] .sp-hero { background: none; border-radius: 0; }
  /* The head is the products page's head, measure for measure (owner: "header-nya
     disamakan seperti pada halaman product"): 120px above the crumb, the crumb 14px
     under, the 48px ink title with an accent tail ("Spec|ies" as "Prod|ucts"), the
     16px lede, 28px below. The 'all' lede is a map-free sentence (species.js). */
  body[data-page="species"] .sp-plaque,
  body[data-page="species"] .sp[data-world="all"] .sp-plaque { margin: 0; padding: 120px 20px 28px; border-radius: 0; background: transparent; box-shadow: none; }
  body[data-page="species"] .sp[data-world="all"] .sp-plaque__kicker,
  body[data-page="species"] .sp-plaque__meta { display: none; }
  body[data-page="species"] .sp-crumb { margin-bottom: 14px; color: var(--color-neutral-600); }   /* the products crumb's grey */
  body[data-page="species"] .sp-plaque__title { font-size: 48px; line-height: .95; letter-spacing: -.015em; margin: 0; color: var(--color-text); }
  body[data-page="species"] .sp-plaque__tail { color: var(--color-accent); }
  body[data-page="species"] .sp-plaque__lede { margin-top: 22px; max-width: none; font-size: 16px; line-height: 1.6; color: var(--color-neutral-700); }
  body[data-page="species"] .sp-toolbar { margin-top: 20px; }
  body[data-page="species"] .sp-trail { margin-top: 8px; }
  body[data-page="species"] .sp-chip { height: 40px; }
}
@media (max-width: 520px) {
  /* Dua ubin kotak besar per baris, seperti grid produk di ponsel (permintaan
     pemilik): plate 112px di daftar satu kolom pergi, kartunya kartu vertikal
     yang sama dengan 521-940, dirapatkan untuk kolom 174px di 390 (150px di
     dalam): asal satu baris, nama maksimal dua baris, harga di barisnya sendiri,
     tanpa panah — seluruh kartu adalah tautannya. */
  body[data-page="species"] .sp-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  body[data-page="species"] .sp-card { border-radius: 20px; }
  body[data-page="species"] .sp-card__plate { margin: 8px 8px 0; border-radius: 14px; }
  body[data-page="species"] .sp-card__body { padding: 10px 10px 12px; gap: 4px; }
  body[data-page="species"] .sp-card__origin { gap: 6px; letter-spacing: .1em; }
  body[data-page="species"] .sp-card__origin > span:not(.sp-iucn) { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  body[data-page="species"] .sp-card__name { font-size: 15px; line-height: 1.15; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  body[data-page="species"] .sp-card__sci { font-size: 13px; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  body[data-page="species"] .sp-phase { display: none; }
  body[data-page="species"] .sp-card__foot { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding-top: 8px; }
  body[data-page="species"] .sp-card__go { display: none; }
  body[data-page="species"] .sp-card__price { margin-left: 0; font-size: 14px; white-space: normal; }
  body[data-page="species"] .sp-card__price small { font-size: 13px; }
}

/* — tanpa gerak: marker digantikan latar marigold pada stop aktif — */
html.no-motion body[data-page="species"] .sp-stop[aria-pressed="true"] { background: var(--dv-sun); border-color: transparent; box-shadow: 0 3px 0 rgba(23, 63, 39, .16); }
html.no-motion body[data-page="species"] .sp-trail__marker { display: none; }
@media (prefers-reduced-motion: reduce) {
  body[data-page="species"] .sp *, body[data-page="species"] .sp *::before, body[data-page="species"] .sp *::after { transition-duration: .01ms !important; animation: none !important; }
  body[data-page="species"] .sp-card:hover { transform: none; }
  body[data-page="species"] .sp-stop[aria-pressed="true"] { background: var(--dv-sun); border-color: transparent; box-shadow: 0 3px 0 rgba(23, 63, 39, .16); }
  body[data-page="species"] .sp-trail__marker { display: none; }
  body[data-page="species"] .sp-grid.is-pending > * { opacity: 1; }
}


/* ══════════════════════════════════════════════════════════════════════
   FOOTER "LANTAI HUTAN" (2026-09-06) — semua halaman kecuali home (home tetap dv-abyss).
   Ilustrasi lantai hutan (assets/bg-footer-forest.webp, 3172×1344) ditambatkan ke tepi
   bawah dengan rasio tetap; pelat scrim RATA rgba(16,32,16,.46) (bukan gradasi — gradasi
   luruh di belakang baris tautan bawah dan kontras gagal); jahitan 74 px ke warna dasar
   di atasnya; semua teks memakai text-shadow supaya ≥ 4.5:1 di kanopi paling terang.
   Lapisan kehidupan (mata katak, kunang-kunang, daun, kupu-kupu, kabut, parallax) dipasang
   js/footer-life.js dalam koordinat gambar; keyframes-nya di sini (.dfl-*).
   ══════════════════════════════════════════════════════════════════════ */
footer.dv-forest { position: relative; overflow: hidden; background: var(--color-accent-800); color: var(--color-accent-100); border-radius: calc(var(--radius-lg) * 1.6) calc(var(--radius-lg) * 1.6) 0 0; padding: 80px 5vw 30px; }
footer.dv-forest .ff-art { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; border-radius: inherit; }
footer.dv-forest .ff-art__box { position: absolute; left: 0; right: 0; bottom: 0; aspect-ratio: 3172 / 1344; }
footer.dv-forest .ff-art__img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; display: block; opacity: 1 !important; transition: none !important; }
footer.dv-forest .ff-art__scrim { position: absolute; inset: 0; background: rgba(16, 32, 16, .46); }
footer.dv-forest .ff-art__seam { position: absolute; left: 0; right: 0; top: 0; height: 74px; background: linear-gradient(180deg, #284d26, rgba(40, 77, 38, 0)); }
footer.dv-forest .ff-row { position: relative; display: flex; justify-content: space-between; gap: 44px; flex-wrap: wrap; }
footer.dv-forest .ff-row--main { margin-bottom: 60px; }
footer.dv-forest .ff-row--legal { align-items: center; gap: 16px; padding-top: 22px; }
footer.dv-forest .ff-brand { flex: 1 1 340px; min-width: 280px; }
/* Sized to match the trench footer exactly, so the two footers read as one
   brand at any width. The old two lines of display type stood about 170px
   tall here; 336px wide of a 2:1 mark is 168px. */
footer.dv-forest .ff-wordmark-img {
  display: block; width: clamp(212px, 22vw, 336px); height: auto; margin-bottom: 20px;
  filter: drop-shadow(0 4px 14px rgba(10, 32, 14, .45));
}
footer.dv-forest .ff-addr { max-width: 340px; font-size: 14px; line-height: 1.6; opacity: .8; margin: 0; }
footer.dv-forest .ff-cta { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }
footer.dv-forest .ff-tel { border: 1px solid var(--color-accent-600); color: var(--color-accent-100); }
footer.dv-forest .ff-tel:hover { background: var(--color-accent-700); color: var(--color-accent-100); }
footer.dv-forest .btn-primary:hover { color: var(--color-bg); }
footer.dv-forest .ff-cols { display: flex; gap: 56px; flex-wrap: wrap; }
footer.dv-forest .ff-col { display: flex; flex-direction: column; gap: 10px; font-size: 14px; }
/* the three link groups are <details>: on a desktop the summary is the plain
   column title (no marker, cannot be folded); the phone block turns it into
   an accordion row */
footer.dv-forest details.ff-col > summary, footer.dv-abyss details.ff-col > summary { list-style: none; pointer-events: none; }
footer.dv-forest details.ff-col > summary::-webkit-details-marker, footer.dv-abyss details.ff-col > summary::-webkit-details-marker { display: none; }
footer.dv-forest .ff-col__links, footer.dv-abyss .ff-col__links { display: flex; flex-direction: column; gap: 10px; }
footer.dv-abyss details.ff-col { display: flex; flex-direction: column; gap: 10px; font-size: 14px; }
footer.dv-forest .dv-col-title { font-family: var(--font-heading); font-size: 15px; color: var(--color-bg); margin-bottom: 4px; }
footer.dv-forest .foot-link { color: var(--color-accent-200); }
footer.dv-forest .foot-link:hover { color: var(--color-accent-300); }
footer.dv-forest .ff-yt { position: relative; display: block; width: 212px; border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--shadow-md); }
footer.dv-forest .ff-yt img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; display: block; filter: brightness(.62) saturate(.9); }
footer.dv-forest .ff-yt__play { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 44px; height: 31px; background: #f03; border-radius: 9px; display: flex; align-items: center; justify-content: center; }
footer.dv-forest .ff-yt__play svg { width: 15px; height: 15px; margin-left: 2px; }
footer.dv-forest .ff-yt__cap { position: absolute; left: 10px; bottom: 8px; display: flex; flex-direction: column; gap: 1px; }
footer.dv-forest .ff-yt__cap b { font-weight: 700; font-size: var(--fs-read); color: #fff; }
footer.dv-forest .ff-yt__cap small { font-size: var(--fs-read); color: rgba(255, 255, 255, .85); }
footer.dv-forest .ff-copy { font-size: var(--fs-read); }                     /* opacity 1: di .7 kontras < 4.5:1 apa pun scrim-nya */
footer.dv-forest .ff-soc { display: flex; gap: 8px; flex-wrap: wrap; }
footer.dv-forest .soc { background: var(--color-accent-700); color: var(--color-accent-100); }
footer.dv-forest .soc:hover { background: var(--color-accent); color: var(--color-bg); }
footer.dv-forest a, footer.dv-forest span, footer.dv-forest p, footer.dv-forest div { text-shadow: 0 1px 3px rgba(8, 18, 8, .7); }
footer.dv-forest img, footer.dv-forest .ff-art, footer.dv-forest .ff-art * { text-shadow: none; }

/* — lapisan kehidupan (footer-life.js): keyframes dalam koordinat gambar — */
footer.dv-forest .dfl-wrap { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
footer.dv-forest .dfl-svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; overflow: visible; }
footer.dv-forest .dfl-lid { animation: dflBlink 6.4s ease-in-out infinite; }
footer.dv-forest .dfl-lid2 { animation-duration: 5.1s; animation-delay: -2.4s; }
@keyframes dflBlink { 0%, 88%, 100% { transform: translateY(-120%); } 93%, 95.5% { transform: translateY(0); } 98% { transform: translateY(-120%); } }
footer.dv-forest .dfl-ff { animation: dflFf var(--p, 5s) ease-in-out infinite; animation-delay: var(--d, 0s); }
@keyframes dflFf { 0%, 100% { opacity: .08; } 42% { opacity: .95; } 68% { opacity: .3; } }
footer.dv-forest .dfl-ffm { animation: dflFfm var(--m, 17s) ease-in-out infinite; animation-delay: var(--d, 0s); }
@keyframes dflFfm { 0%, 100% { transform: translate(0, 0); } 33% { transform: translate(26px, -20px); } 66% { transform: translate(-18px, 14px); } }
footer.dv-forest .dfl-mist { animation: dflMist var(--m, 44s) linear infinite; animation-delay: var(--d, 0s); }
@keyframes dflMist { 0% { transform: translateX(-16%); } 100% { transform: translateX(116%); } }
footer.dv-forest .dfl-leaf { animation: dflLeaf var(--m, 15s) linear infinite; animation-delay: var(--d, 0s); transform-box: fill-box; transform-origin: 50% 50%; }
@keyframes dflLeaf { 0% { transform: translate(0, -120px) rotate(0deg); opacity: 0; } 8% { opacity: .9; } 88% { opacity: .85; } 100% { transform: translate(var(--dx, 40px), var(--dy, 760px)) rotate(var(--rot, 420deg)); opacity: 0; } }
footer.dv-forest .dfl-bfly { animation: dflBfly var(--m, 26s) linear infinite; animation-delay: var(--d, 0s); }
@keyframes dflBfly { 0% { transform: translate(var(--x0, -8%), 0); } 50% { transform: translate(50%, var(--rise, -90px)); } 100% { transform: translate(var(--x1, 112%), 0); } }
footer.dv-forest .dfl-bob { animation: dflBob var(--m, 3.4s) ease-in-out infinite; }
@keyframes dflBob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-16px); } }
footer.dv-forest .dfl-wing { transform-box: fill-box; transform-origin: 100% 50%; animation: dflWing .34s ease-in-out infinite alternate; }
footer.dv-forest .dfl-wing.r { transform-origin: 0% 50%; }
@keyframes dflWing { from { transform: scaleX(1); } to { transform: scaleX(.28); } }
@media (prefers-reduced-motion: reduce) {
  footer.dv-forest .dfl-wrap { display: none; }
  footer.dv-forest .ff-art__img { transform: none !important; }
}
/* #daChat is fixed at right 22px / bottom 22px with z-index 180, so it floats
   over whatever is in the footer's bottom-right corner — which is the social
   row. Reserve the launcher's width rather than letting it sit on Facebook
   and X. */
footer.dv-forest .ff-row--legal { padding-right: 128px; }

@media (max-width: 1160px) {
  /* The four columns behave as ONE rigid 653px block, because the YouTube
     card is a fixed 212px. Below about 1160px that block can no longer sit
     beside the wordmark, so it wraps to its own row and strands up to 392px
     of empty ground on the right. Two-by-two keeps it beside the brand and
     lets it shrink. */
  footer.dv-forest .ff-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 26px 40px; }
  footer.dv-forest .ff-brand { flex: 1 1 300px; }
  footer.dv-forest .ff-yt { width: min(212px, 100%); }
}
@media (max-width: 760px) {
  footer.dv-forest { padding: 64px 5vw 26px; }
  footer.dv-forest .ff-row--main { margin-bottom: 44px; }
  footer.dv-forest .ff-cols { gap: 28px 40px; }
}
@media (max-width: 620px) {
  /* — Footer di ponsel: satu kolom rapi, bukan desktop yang dipadatkan —
     Diukur di 390 sebelum blok ini: 1.242px tinggi, logo 212px, dua pil kontak
     berbeda lebar, Support sendirian di kolom kiri dengan sel kosong di kanan,
     kartu YouTube 212px dengan ruang kosong di sebelahnya, sosial + hak cipta
     bertumpuk. Sekarang: logo 176px, dua pil kontak selebar layar, Collections
     (6 tautan) di kolom kiri berdampingan dengan Company + Support (4 + 3)
     bertumpuk di kanan — tinggi kolom seimbang, tidak ada sel kosong —
     lalu kartu YouTube mendatar selebar layar, garis pemisah, sosial di atas
     hak cipta. */
  footer.dv-forest { padding: 48px 5vw 26px; border-radius: 0; }   /* kotak, tanpa lengkung atas (pemilik) */
  footer.dv-forest .ff-row--main { margin-bottom: 30px; gap: 32px; }
  /* Logo dirata-tengahkan (pemilik). Hanya logonya: alamat, pil kontak, dan
     akordeon tautan tetap rata kiri supaya barisnya tetap mudah dipindai. */
  footer.dv-forest .ff-wordmark-img { width: 176px; margin: 0 auto 14px; }
  footer.dv-forest .ff-addr { max-width: none; }
  footer.dv-forest .ff-cta { flex-direction: column; gap: 8px; margin-top: 16px; }
  footer.dv-forest .ff-cta .btn { width: 100%; box-sizing: border-box; justify-content: center; min-height: 44px; }
  /* the link groups: one column of accordions, closed (main.js), 52px rows with a
     chevron; open, 40px link rows. No column balancing to get wrong, and the
     footer is ~560px instead of ~1,040. The YouTube card follows as a full row. */
  footer.dv-forest .ff-cols { display: block; width: 100%; border-top: 1px solid rgba(255, 255, 255, .14); }
  footer.dv-forest .ff-col { display: block; border-bottom: 1px solid rgba(255, 255, 255, .14); }
  footer.dv-forest details.ff-col > summary { pointer-events: auto; cursor: pointer; display: flex; align-items: center; justify-content: space-between; min-height: 52px; margin: 0; font-size: 16px; }
  footer.dv-forest details.ff-col > summary::after { content: ''; width: 9px; height: 9px; margin: -5px 6px 0 0; border-right: 2px solid var(--color-accent-200); border-bottom: 2px solid var(--color-accent-200); transform: rotate(45deg); transition: transform .16s ease; }
  footer.dv-forest details.ff-col[open] > summary::after { transform: rotate(225deg); margin-top: 4px; }
  footer.dv-forest .ff-col__links { gap: 0; padding: 0 0 10px; }
  footer.dv-forest .foot-link { padding: 9px 0; }
  footer.dv-forest .ff-col:last-child { border: 0; padding-top: 18px; }
  /* the YouTube card lies down: thumb left, caption right, one full-width row */
  footer.dv-forest .ff-col:last-child .dv-col-title { display: none; }
  footer.dv-forest .ff-yt { display: flex; align-items: center; gap: 12px; width: 100%; padding: 8px; box-sizing: border-box; background: rgba(0, 0, 0, .18); border-radius: 16px; box-shadow: none; }
  footer.dv-forest .ff-yt img { width: 112px; flex: none; border-radius: 10px; }
  footer.dv-forest .ff-yt__play { left: 64px; }                                /* 8px padding + half of the 112px thumb */
  footer.dv-forest .ff-yt__cap { position: static; gap: 2px; }
  footer.dv-forest .ff-yt__cap b { font-family: var(--font-heading); font-size: 15px; }
  /* legal row: a hairline above, the social pills first, the copyright under
     them. The launcher (72px figure at a 14px offset, da-chat.js <=640) owns
     the bottom-right corner: the pills stay left of its column (76px = 72 + 14)
     and the copyright line is shorter than that column, so nothing needs a
     reservation under it — only the phone's own safe area. */
  footer.dv-forest .ff-row--legal { flex-direction: column; align-items: flex-start; gap: 14px; padding: 20px 0 calc(8px + env(safe-area-inset-bottom, 0px)); border-top: 0; }
  footer.dv-forest .ff-soc { order: -1; max-width: calc(100% - 76px); }
  footer.dv-forest .ff-copy { opacity: .82; }
  /* Tanpa gambar dan efek di ponsel (keputusan pemilik): panorama, scrim,
     seam, dan lapisan kehidupan (mata katak, kunang-kunang, kabut, parallax)
     semuanya di dalam .ff-art — satu display:none menyingkirkan semuanya, dan
     footer tinggal hijau polos --color-accent-800. Gambarnya tidak diunduh
     (partials/footer-forest.html memberi ponsel gif 1x1), dan footer-life.js
     tidak membangun lapisannya sama sekali di lebar ini. */
  footer.dv-forest .ff-art { display: none; }
}


/* ══════════════════════════════════════════════════════════════════════
   HOME — BAND HUTAN (6 September 2026)

   Urutan aturan di blok ini disengaja dan tidak boleh diacak: beberapa di
   antaranya bertumpuk pada selektor yang sama, jadi cascade-nya yang
   menentukan. Komponen yang dibawanya:
     .frstHead .spGrid .spHang .cord .spDisc .vig .spMeta   - grid spesies gantung
     .catRow .catChip                                        - baris kategori
     .prodGrid .pTile .pShot .glare .ic .pVar .pBody .pName
     .pCat .pStars .pPrice .pBuy                             - tile produk
     .brandGrid .bBub .sheen .pop                            - grid merek
     .mz .mz-t .mz-i .mz-cap .mz-art .mz-cta                 - kartu mezzanine
   Override pratinjau design-tool pada html/body sengaja TIDAK ikut: ia hanya
   membuat artboard bisa digulir di dalam alat desain.
   ══════════════════════════════════════════════════════════════════════ */
.mz{display:grid;grid-template-columns:repeat(auto-fill,minmax(168px,1fr));grid-auto-rows:168px;grid-auto-flow:dense;gap:12px}
.mz-t{position:relative;display:block;border-radius:20px;overflow:hidden;box-shadow:0 8px 20px rgba(10,28,14,.28)}
.mz-t.big{grid-column:span 2;grid-row:span 2}
.mz-i{position:absolute;inset:0;background-size:cover;background-position:center;filter:grayscale(1) saturate(.85);transition:filter .5s ease, transform .65s cubic-bezier(.22,1,.36,1)}
.mz-t:hover .mz-i{filter:none;transform:scale(1.055)}
.mz-cap{position:absolute;left:10px;bottom:10px;background:var(--dv-cream);color:#1F3D24;border-radius:999px;padding:6px 13px;font-size:var(--fs-read);font-weight:700;opacity:0;transform:translateY(8px);transition:opacity .35s ease, transform .35s ease;pointer-events:none;max-width:calc(100% - 20px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mz-t:hover .mz-cap{opacity:1;transform:none}
.mz-art{display:flex;align-items:center;justify-content:center}
.mz-cta{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;border:2.5px dashed rgba(255,243,220,.55);background:transparent;box-shadow:none;color:var(--dv-cream);text-align:center;transition:background-color .3s ease, transform .35s cubic-bezier(.22,1,.36,1)}
.mz-cta:hover{background:rgba(255,243,220,.14);transform:scale(1.03)}
.mz-cta b{font-family:var(--font-heading);font-size:42px;line-height:1;font-weight:400}
.mz-cta span{font-size:var(--fs-read);font-weight:700}
.mz-sea .mz-cap{color:#0A3550}
.mz-sea .mz-cta{border-color:rgba(191,233,242,.5);color:#BFE9F2}
.mz-sea .mz-cta:hover{background:rgba(191,233,242,.12)}
footer.dv-abyss > *:not([aria-hidden="true"]){position:relative;z-index:1}
/* Peluncur DARA fixed di kanan bawah (96x116 + 22 px) menabrak tombol "kembali ke
   permukaan" begitu dasar footer masuk layar. Barisnya diberi ruang, bukan tombolnya
   yang dipindah — urutannya bagian dari desain. */
@media (min-width:721px){ footer.dv-abyss .dv-foot-base{ padding-right:150px } }
.brandGrid{display:grid;grid-template-columns:repeat(6,1fr);gap:26px 22px;max-width:1080px;margin:0 auto}
.bBub{position:relative;display:flex;align-items:center;justify-content:center;aspect-ratio:1;border-radius:50%;background:radial-gradient(circle at 32% 24%,#FFFFFF 0%,#F6FCFE 38%,rgba(228,246,251,.96) 70%,rgba(198,231,242,.92) 100%);box-shadow:inset 0 2px 3px rgba(255,255,255,.95),inset 0 -14px 22px -10px rgba(103,183,206,.5),inset 0 0 0 1px rgba(255,255,255,.85),0 14px 30px -8px rgba(4,28,42,.42),0 0 0 1px rgba(142,230,210,.14),0 0 26px -6px rgba(127,214,232,.28);animation:bBubF var(--bf,7s) ease-in-out infinite;animation-delay:var(--bd,0s);transition:transform .55s cubic-bezier(.22,1,.36,1),box-shadow .5s ease}
.bBub::after{content:"";position:absolute;inset:0;border-radius:50%;pointer-events:none;background:radial-gradient(ellipse 26% 15% at 24% 15%,rgba(255,255,255,.95),transparent 70%),radial-gradient(ellipse 9% 6% at 41% 25%,rgba(255,255,255,.8),transparent 70%),radial-gradient(ellipse 34% 12% at 62% 88%,rgba(180,232,246,.55),transparent 72%);transition:opacity .5s ease}
.bBub::before{content:"";position:absolute;inset:-9px;border-radius:50%;pointer-events:none;background:radial-gradient(circle,rgba(142,230,210,.28),transparent 62%);opacity:0;transform:scale(.86);transition:opacity .55s ease,transform .65s cubic-bezier(.22,1,.36,1)}
.bBub:hover{transform:translateY(-11px) scale(1.07);animation-play-state:paused;box-shadow:inset 0 2px 3px rgba(255,255,255,1),inset 0 -16px 26px -10px rgba(103,183,206,.55),inset 0 0 0 1px rgba(255,255,255,.95),0 22px 44px -10px rgba(4,28,42,.5),0 0 0 2px rgba(142,230,210,.6),0 0 40px -4px rgba(142,230,210,.5)}
.bBub:hover::before{opacity:1;transform:scale(1)}
.bBub:hover::after{opacity:.75}
.bBub:active{transform:translateY(-6px) scale(1.02);transition-duration:.14s}
.bBub .sheen{position:absolute;inset:0;border-radius:50%;overflow:hidden;pointer-events:none}
.bBub .sheen i{position:absolute;top:-30%;left:-60%;width:42%;height:170%;background:linear-gradient(100deg,transparent,rgba(255,255,255,.85),transparent);transform:skewX(-18deg);transition:left .75s cubic-bezier(.3,.9,.3,1)}
.bBub:hover .sheen i{left:130%}
.bBub .pop{position:absolute;inset:-2px;border-radius:50%;border:1.5px solid rgba(142,230,210,.7);opacity:0;pointer-events:none}
.bBub:hover .pop{animation:bPop 1.5s ease-out infinite}
@keyframes bPop{0%{opacity:.7;transform:scale(1)}100%{opacity:0;transform:scale(1.22)}}
.bBub img{position:relative;z-index:2;width:64%;height:auto;max-height:46%;object-fit:contain;opacity:.86;transition:opacity .4s ease,transform .55s cubic-bezier(.22,1,.36,1)}
.bBub:hover img{opacity:1;transform:scale(1.1) translateY(-1px)}
.bBub b{position:absolute;left:50%;bottom:-26px;transform:translate(-50%,6px);white-space:nowrap;font-size:var(--fs-read);font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:#8EE6D2;opacity:0;pointer-events:none;transition:opacity .4s ease,transform .5s cubic-bezier(.22,1,.36,1)}
.bBub:hover b{opacity:1;transform:translate(-50%,0)}
@keyframes bBubF{0%,100%{transform:translateY(0) rotate(-.6deg)}50%{transform:translateY(-8px) rotate(.6deg)}}
/* z-index 5 dan bantalan bawah 46px, keduanya untuk satu hal: label yang muncul
   saat hover. Tanpa z-index, .catRow di bawahnya (z-index 3, tapi lebih
   belakangan di DOM) menimpanya; tanpa bantalan, label baris terakhir tidak
   punya tempat sama sekali — diukur di 1440, jaraknya 43px untuk label
   setinggi 76px. Tinggi band tidak ikut bertambah: syncArt() membagi ulang
   sisa ruang ilustrasi begitu isi blok ini tumbuh. */
.spGrid{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(24px,2.4vw,42px) clamp(18px,2vw,34px);width:var(--spW,min(920px,66vw));max-width:100%;position:relative;z-index:5;padding-bottom:48px}
.spHang{position:relative;display:block;padding-top:clamp(20px,2.2vw,40px);color:#F3F7E9;text-align:center;transform-origin:50% 0;animation:spSway var(--sw,7s) ease-in-out infinite;animation-delay:var(--sd,0s)}
.spHang .cord{position:absolute;left:50%;top:0;width:2px;height:clamp(20px,2.2vw,40px);margin-left:-1px;background:linear-gradient(180deg,rgba(120,168,96,0),#4E7A38 45%,#3E6A2C);border-radius:2px}
.spHang .cord::after{content:"";position:absolute;left:-4px;bottom:-3px;width:10px;height:10px;border-radius:50%;background:#3E6A2C;box-shadow:0 1px 0 rgba(255,255,255,.25) inset}
/* display:block wajib di sini: .spDisc adalah <span>, dan
   pada kotak inline aspect-ratio, border-radius dan overflow:hidden tidak berlaku sama
   sekali, sehingga medalion bulat tampil sebagai foto persegi berlatar putih. */
.spDisc{display:block;position:relative;aspect-ratio:1;border-radius:50%;overflow:hidden;background:#1D3A1B;box-shadow:0 0 0 3px rgba(240,247,225,.85),0 0 0 6px rgba(62,106,44,.55),0 16px 30px -10px rgba(10,32,14,.6);transition:transform .5s cubic-bezier(.22,1,.36,1),box-shadow .5s ease}
.spDisc > img:not(.spx-flag){width:100%;height:100%;object-fit:cover;transition:transform .7s cubic-bezier(.22,1,.36,1),filter .5s ease;filter:saturate(.92)}
.spHang:hover{animation-play-state:paused;z-index:5}
.spHang:hover .spDisc{transform:translateY(-6px) scale(1.06);box-shadow:0 0 0 3px #F6FBEA,0 0 0 7px rgba(142,197,110,.85),0 24px 42px -12px rgba(10,32,14,.7)}
.spHang:hover .spDisc img{transform:scale(1.1);filter:saturate(1.08)}
.spDisc .vig{position:absolute;inset:0;border-radius:50%;background:radial-gradient(circle at 50% 116%,rgba(10,32,14,.6),transparent 58%);pointer-events:none}
/* Plakat spesimen, bukan teks telanjang: label ini mendarat di atas lukisan
   hutan yang ramai, kadang di atas katak lain, kadang di atas baris chip.
   pointer-events:none supaya plakatnya sendiri tidak pernah merebut hover
   dari ubin sebelah. */
.spMeta{position:absolute;left:50%;right:auto;width:max-content;max-width:min(224px,46vw);top:calc(100% + 2px);display:block;padding:5px 11px 6px;border-radius:13px;background:rgba(14,38,18,.82);backdrop-filter:blur(7px);-webkit-backdrop-filter:blur(7px);box-shadow:0 12px 26px -14px rgba(4,16,8,.8),inset 0 0 0 1px rgba(201,229,166,.18);pointer-events:none;opacity:0;transform:translate(-50%,7px);transition:opacity .4s ease,transform .45s cubic-bezier(.22,1,.36,1)}
.spHang:hover .spMeta{opacity:1;transform:translate(-50%,0)}
.spMeta b{display:block;font-family:var(--font-heading);font-weight:400;font-size:clamp(var(--fs-read),1.05vw,15.5px);line-height:1.18;color:#F6FBEA}
.spMeta i{display:block;font-size:var(--fs-read);font-style:normal;font-weight:700;letter-spacing:.06em;color:#C9E5A6;margin-top:1px}
/* Baris stok di dalam plakat. Ia SUDAH tampil di desktop sejak ubin spesimen
   dibuat, bukan karena diminta melainkan karena .spMeta i (0,1,1) menang atas
   .spx-stock{display:none} (0,1,0) — pola kegagalan yang sama seperti bendera
   asal dulu. Informasinya berguna, jadi dipertahankan; tapi dijadikan baris
   ketiga yang jelas lebih rendah supaya harga tetap yang menonjol. Dikurung
   min-width:1200px: di bawah itu medalionnya sendiri sudah menyusut ke 79-104px
   dan plakat tiga baris akan menjulang melewati baris chip. */
@media (min-width:1200px){
  .spMeta > i.spx-stock{font-size:var(--fs-min);letter-spacing:.03em;font-weight:700;color:rgba(201,229,166,.66);margin-top:3px}
}
@keyframes spSway{0%,100%{transform:rotate(-2.6deg)}50%{transform:rotate(2.6deg)}}
.catRow{display:flex;gap:10px;flex-wrap:wrap;position:relative;z-index:3}
.catChip{display:inline-flex;align-items:center;gap:9px;background:rgba(20,48,22,.5);backdrop-filter:blur(7px);-webkit-backdrop-filter:blur(7px);border:1.5px solid rgba(201,229,166,.4);border-radius:999px;padding:12px 21px;font-size:15px;font-weight:700;color:#EDF6DE;transition:transform .35s cubic-bezier(.22,1,.36,1),background-color .3s ease,border-color .3s ease}
.catChip svg{width:15px;height:15px;color:#A9D488}
.catChip:hover{transform:translateY(-3px);background:rgba(78,122,56,.72);border-color:#A9D488;color:#FBFEF5}
.catChip:active{transform:translateY(-1px) scale(.96)}
.frstHead{position:relative;z-index:4;max-width:560px}
@media (max-width:760px) {
  .spGrid{grid-template-columns:repeat(3,1fr);max-width:74vw}
}
@media (max-width:520px) {
  .spGrid{grid-template-columns:repeat(2,1fr);max-width:80vw}
}
.prodGrid{display:grid;grid-template-columns:repeat(5,1fr);gap:26px 20px;max-width:1160px;margin:0 auto;position:relative;z-index:4}
.pTile{position:relative;display:flex;flex-direction:column;border-radius:calc(var(--radius-lg)*1.25);background:linear-gradient(170deg,rgba(251,254,255,.97),rgba(226,244,250,.93));box-shadow:inset 0 1px 0 rgba(255,255,255,.95),0 14px 30px -10px rgba(4,28,42,.42),0 0 0 1px rgba(255,255,255,.5);overflow:hidden;color:#0A3D4E;transition:transform .5s cubic-bezier(.22,1,.36,1),box-shadow .5s ease}
.pTile:hover{transform:translateY(-9px);box-shadow:inset 0 1px 0 rgba(255,255,255,1),0 24px 46px -12px rgba(4,28,42,.5),0 0 0 2px rgba(142,230,210,.65),0 0 34px -6px rgba(142,230,210,.4)}
.pTile:active{transform:translateY(-4px) scale(.99);transition-duration:.14s}
.pShot{position:relative;aspect-ratio:1;overflow:hidden;background:radial-gradient(circle at 44% 34%,#FFFFFF,#EAF6FA 62%,#D5EBF3)}
.pShot img{position:absolute;inset:7%;width:86%;height:86%;object-fit:contain;transition:transform .65s cubic-bezier(.22,1,.36,1)}
.pTile:hover .pShot img{transform:scale(1.09) rotate(-1.5deg)}
.pShot .ic{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#8FB9C6;transition:transform .65s cubic-bezier(.22,1,.36,1),color .4s ease}
.pTile:hover .pShot .ic{transform:scale(1.08);color:#3E93A8}
.pShot .ic svg{width:44%;height:44%}
.pShot .glare{position:absolute;inset:0;pointer-events:none;background:linear-gradient(103deg,transparent 32%,rgba(255,255,255,.7) 46%,transparent 60%);transform:translateX(-120%);transition:transform .85s cubic-bezier(.3,.9,.3,1)}
.pTile:hover .pShot .glare{transform:translateX(120%)}
.pVar{position:absolute;left:9px;top:9px;display:inline-flex;align-items:center;gap:5px;background:rgba(10,61,78,.86);color:#EAF9FF;border-radius:999px;padding:4px 10px;font-size:var(--fs-min);font-weight:800;letter-spacing:.06em;backdrop-filter:blur(4px)}
.pVar svg{width:11px;height:11px}
.pBody{display:flex;flex-direction:column;gap:5px;padding:13px 15px 16px;flex:1}
.pName{font-family:var(--font-heading);font-weight:400;font-size:15.5px;line-height:1.3;color:#08313F;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;white-space:normal;overflow:hidden;min-height:calc(2 * 1.3em)}
.pCat{font-size:var(--fs-min);font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#4E93A6}
.pStars{display:flex;align-items:center;gap:3px;color:#C9DCE3}
.pStars svg{width:11px;height:11px}
.pStars b{font-size:var(--fs-min);font-weight:700;color:#93AEB8;margin-left:3px}
.pPrice{margin-top:auto;padding-top:8px;font-size:14px;font-weight:800;color:#0B4A5A;letter-spacing:-.01em}
.pBuy{position:absolute;right:10px;bottom:10px;width:34px;height:34px;border-radius:50%;background:#0B4A5A;color:#EAF9FF;display:flex;align-items:center;justify-content:center;opacity:0;transform:translateY(8px) scale(.85);transition:opacity .4s ease,transform .45s cubic-bezier(.22,1,.36,1),background-color .3s ease}
.pBuy svg{width:15px;height:15px}
.pTile:hover .pBuy{opacity:1;transform:none}
.pBuy:hover{background:#8EE6D2;color:#062B41}
@media (max-width:1180px) {
  .prodGrid{grid-template-columns:repeat(4,1fr)}
}
@media (max-width:900px) {
  .prodGrid{grid-template-columns:repeat(3,1fr)}
}
@media (max-width:640px) {
  .prodGrid{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:1000px) {
  .brandGrid{grid-template-columns:repeat(4,1fr)}
}
@media (max-width:640px) {
  .brandGrid{grid-template-columns:repeat(3,1fr)}
}


/* ══════════════════════════════════════════════════════════════════════
   HOME — DUA BAGIAN TAMBAHAN (10 September 2026)

   Hanya aturan baru untuk dua bagian ini, lengkap dengan pembungkus @media
   masing-masing: tanpa itu .nsGrid dan .aqGrid yang dideklarasikan tiga kali
   akan runtuh jadi satu kolom di desktop.
     .nsWrap .nsHead .nsGrid .nsCard .badge .disc .txt .mt      - spesies terbaru
     .aqFish .swim .aqGrid .aqCard .art .flag .sci .soon        - terumbu
     .btBody .btTail .btPec .btPel                              - anatomi blue tang
     .abFx .abBub .abSnow .abGlow .abSpark .fMist .fMistBand    - palung di footer
   ══════════════════════════════════════════════════════════════════════ */
@keyframes abBub{0%{transform:translate(0,0) scale(.85);opacity:0}12%{opacity:.5}70%{opacity:.38}100%{transform:translate(var(--dx,18px),calc(-1 * var(--rise,760px))) scale(1.06);opacity:0}}

@keyframes abGlow{0%,100%{opacity:.16;transform:translate(0,0) scale(.9)}50%{opacity:.4;transform:translate(var(--dx,20px),var(--dy,-26px)) scale(1.12)}}

@keyframes abSnow{0%{transform:translate(0,0);opacity:0}14%{opacity:.42}88%{opacity:.3}100%{transform:translate(var(--dx,14px),var(--fall,780px));opacity:0}}

@keyframes abSpark{0%,100%{opacity:.1;transform:translate(0,0)}45%{opacity:.5}72%{opacity:.24;transform:translate(var(--dx,9px),var(--dy,-13px))}}

@keyframes btBody{0%,100%{transform:translateY(0) rotate(-2deg)}50%{transform:translateY(-11px) rotate(2deg)}}

@keyframes btPec{0%,100%{transform:rotate(-12deg) scaleY(1)}50%{transform:rotate(10deg) scaleY(.78)}}

@keyframes btSwim{0%{transform:translateX(108vw)}100%{transform:translateX(-34vw)}}

@keyframes btTail{0%,100%{transform:rotate(-13deg) scaleX(1)}50%{transform:rotate(13deg) scaleX(.85)}}

@keyframes fMistBand{0%,100%{transform:translateX(-9%) skewX(-2deg)}30%{transform:translateX(-1%) skewX(1.4deg)}62%{transform:translateX(7%) skewX(-1deg)}}

@keyframes fMistX{0%{transform:translateX(-140%)}100%{transform:translateX(340%)}}

@keyframes fMistY{0%,100%{translate:0 -9px;scale:1.02 .9}50%{translate:0 9px;scale:.9 1.14}}

@keyframes fMistP{0%,100%{opacity:.34;filter:blur(24px)}45%{opacity:.92;filter:blur(17px)}72%{opacity:.6;filter:blur(21px)}}

@keyframes fMistBandP{0%,100%{opacity:.55;filter:blur(20px)}40%{opacity:1;filter:blur(13px)}70%{opacity:.72;filter:blur(17px)}}

.aqFish {position:absolute;left:0;right:0;bottom:0;height:clamp(210px,20vw,330px);overflow:hidden;pointer-events:none;z-index:1}
.aqFish .swim {position:absolute;left:0;animation:btSwim var(--sy,58s) linear infinite;animation-delay:var(--sd,0s)}
.btBody {transform-box:fill-box;transform-origin:86% 50%;animation:btBody var(--by,3.6s) ease-in-out infinite;animation-delay:var(--sd,0s)}
.btTail {transform-box:fill-box;transform-origin:100% 50%;animation:btTail var(--ty,1.25s) ease-in-out infinite;animation-delay:var(--sd,0s)}
.btPec {transform-box:fill-box;transform-origin:98% 8%;animation:btPec 1.6s ease-in-out infinite}
.btPel {transform-box:fill-box;transform-origin:88% 0%;animation:btPec 2.1s ease-in-out infinite}
.aqGrid {display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(18px,2vw,30px);max-width:1180px;position:relative;z-index:4}
.aqCard {position:relative;display:flex;flex-direction:column;gap:14px;padding:22px;border-radius:calc(var(--radius-lg)*1.4);background:linear-gradient(160deg,rgba(12,58,78,.72),rgba(8,38,56,.6));border:1px solid rgba(159,227,240,.26);box-shadow:0 16px 34px rgba(2,18,30,.4);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);color:#EAF9FF;transition:transform .4s cubic-bezier(.22,1,.36,1),border-color .3s ease,box-shadow .4s ease}
.aqCard:hover {transform:translateY(-7px);border-color:rgba(159,227,240,.62);box-shadow:0 22px 44px rgba(2,18,30,.5);color:#EAF9FF}
.aqCard .art {position:relative;border-radius:calc(var(--radius-lg)*1.1);overflow:hidden;aspect-ratio:4/3;background:radial-gradient(circle at 40% 30%,rgba(159,227,240,.2),rgba(6,32,48,.65));display:flex;align-items:center;justify-content:center}
.aqCard .art > img:not(.spx-flag) {width:100%;height:100%;object-fit:cover;display:block;transition:transform .6s cubic-bezier(.22,1,.36,1)}
.aqCard:hover .art > img:not(.spx-flag) {transform:scale(1.06)}
.aqCard .art svg {width:86%;height:auto;display:block;transition:transform .6s cubic-bezier(.22,1,.36,1)}
.aqCard:hover .art svg {transform:translateX(-6px) scale(1.04)}
.aqCard .cat {font-size:var(--fs-read);font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:#7FD6E8}
.aqCard .nm {font-family:var(--font-heading);font-weight:400;font-size:clamp(19px,1.6vw,25px);line-height:1.15}
.aqCard .sci {font-size:var(--fs-read);font-style:italic;color:#A7CEDC}
.aqCard .pr {margin-top:auto;font-size:15px;font-weight:700;color:#FFE9A8}
.aqCard .soon {margin-top:auto;font-size:var(--fs-read);font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#9FE3F0}
.aqCard .flag.out {background:rgba(233,244,248,.16);color:#BBD8E4;box-shadow:inset 0 0 0 1px rgba(187,216,228,.34)}   /* versi redup: menandai, tanpa mengundang */
.aqCard .flag {position:absolute;top:-11px;right:20px;background:#9FE3F0;color:#06283A;font-size:var(--fs-min);font-weight:800;letter-spacing:.14em;padding:4px 12px;border-radius:999px;box-shadow:0 4px 12px rgba(2,18,30,.45)}
.abFx {position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:0}
.abBub {position:absolute;bottom:-40px;border-radius:50%;border:1.5px solid rgba(159,227,240,.2);background:radial-gradient(circle at 34% 28%,rgba(159,227,240,.12),rgba(159,227,240,.03) 62%,transparent);animation:abBub var(--d,16s) linear infinite;animation-delay:var(--dl,0s)}
.abSnow {position:absolute;top:-12px;width:3px;height:3px;border-radius:50%;background:rgba(166,204,220,.34);animation:abSnow var(--d,22s) linear infinite;animation-delay:var(--dl,0s)}
.abGlow {position:absolute;border-radius:50%;filter:blur(26px);animation:abGlow var(--d,17s) ease-in-out infinite;animation-delay:var(--dl,0s)}
.abSpark {position:absolute;width:5px;height:5px;border-radius:50%;background:rgba(127,214,232,.42);box-shadow:0 0 14px 5px rgba(127,214,232,.16);animation:abSpark var(--d,6s) ease-in-out infinite;animation-delay:var(--dl,0s)}
.fMist {position:absolute;border-radius:50%;filter:blur(20px);pointer-events:none;animation:fMistX var(--d,64s) linear infinite, fMistY var(--dy2,17s) ease-in-out infinite, fMistP var(--dp,9s) ease-in-out infinite;animation-delay:var(--dl,0s),var(--dl2,0s),var(--dl3,0s)}
.fMistBand {position:absolute;left:-16%;right:-16%;pointer-events:none;animation:fMistBand var(--d,48s) ease-in-out infinite, fMistBandP var(--dp,13s) ease-in-out infinite;animation-delay:var(--dl,0s),var(--dl3,0s)}
.nsWrap {position:relative;z-index:4;display:flex;flex-direction:column;gap:clamp(18px,2vw,30px)}
.nsHead {display:flex;justify-content:space-between;align-items:flex-end;gap:20px;flex-wrap:wrap}
.nsGrid {display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(20px,2.2vw,38px);max-width:1420px}
.nsCard {position:relative;display:flex;align-items:center;gap:24px;min-width:0;padding:26px 34px 26px 26px;border-radius:calc(var(--radius-lg)*1.35);background:linear-gradient(150deg,rgba(26,64,32,.78),rgba(15,42,21,.66));border:1px solid rgba(201,229,166,.28);box-shadow:0 12px 28px rgba(8,26,12,.4);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);color:#F6FBEA;transition:transform .4s cubic-bezier(.22,1,.36,1),border-color .3s ease,box-shadow .4s ease}
.nsCard:hover {transform:translateY(-6px);border-color:rgba(201,229,166,.6);box-shadow:0 18px 38px rgba(8,26,12,.5);color:#F6FBEA}
.nsCard .disc {position:relative;flex:none;width:clamp(74px,8.4vw,136px);height:clamp(74px,8.4vw,136px);border-radius:50%;overflow:hidden;border:2px solid rgba(201,229,166,.5);background:#20431F}
.nsCard .disc > img:not(.spx-flag) {width:100%;height:100%;object-fit:cover;display:block;transition:transform .6s cubic-bezier(.22,1,.36,1)}
.nsCard:hover .disc > img:not(.spx-flag) {transform:scale(1.09)}
.nsCard .txt {display:flex;flex-direction:column;gap:5px;min-width:0}
.nsCard .nm {font-family:var(--font-heading);font-weight:400;font-size:clamp(20px,1.75vw,28px);line-height:1.2;white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.nsCard .mt {font-size:15px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;color:#A9D488}
.nsCard .pr {font-size:17.5px;font-weight:700;color:#F2E3AE}
/* Kartu lebih besar hanya di atas 1500px. Di bawah itu lukisan hutan sudah
   kehabisan sisa (padTop band tinggal 36px), dan tiap piksel tambahan di sini
   dibayar dengan medalion spesies yang menyusut lewat penjaga --spW. */
@media (min-width:1501px){
  /* Cakramnya TIDAK dibesarkan. Kartu ini mendatar dan wadahnya dibatasi 1240px,
     jadi di 1920 lebarnya hanya 324px; cakram 150px menyisakan 80px untuk teks
     dan namanya terpotong di tengah kata. Yang dilebarkan wadahnya, supaya
     kolom teksnya yang bertambah. */
  #dv-baru > .dv-content {max-width:1460px}
  .nsCard {gap:28px;padding:38px 34px 38px 34px}
  .nsCard .disc {width:150px;height:150px}
  .taKitI {padding:22px 14px 24px;gap:10px}
}
/* Alasan yang sama untuk dua hal DI DALAM band spesies: lede-nya dan bantalan
   chip kategori. Keduanya masuk hitungan ch yang dipakai penjaga --spW, jadi
   di bawah 1500px keduanya dikembalikan ke ukuran semula. !important pada
   lede karena ukurannya ditulis inline di markup. */
@media (max-width:1500px){
  .frstHead p {font-size:15px !important;line-height:1.65 !important}
  .catChip {padding:10px 18px}
}
.nsCard .badge {position:absolute;top:-12px;right:22px;background:#FFD98A;color:#25501F;font-size:var(--fs-min);font-weight:800;letter-spacing:.15em;padding:4px 12px;border-radius:999px;box-shadow:0 4px 10px rgba(8,26,12,.4)}

@media (prefers-reduced-motion:reduce) {
.aqFish .swim {animation:none;transform:translateX(62vw)}
.abBub,.abSnow,.abGlow,.abSpark {animation:none}
.abBub,.abSnow {opacity:.4}
}

@media (max-width:900px) {
.aqGrid {grid-template-columns:1fr 1fr}
}

@media (max-width:600px) {
.aqGrid {grid-template-columns:1fr}
}

@media (max-width:820px) {
.nsGrid {grid-template-columns:repeat(2,minmax(0,1fr))}
}

/* declared after the 820px rule on purpose: both match on a phone and the
   later one has to win, or 390px keeps two columns */
@media (max-width:600px) {
.nsGrid {grid-template-columns:minmax(0,1fr)}
}


/* ══════════════════════════════════════════════════════════════════════
   BLOG — blog.html and blog-post.html on a phone (measured at 390×844 and
   360×780). Almost every desktop value on these pages is inline, so the
   phone rules carry !important only where the value really is inline (the
   search pill's padding, the CTA card's padding, #bpLive's margin). The pull
   quote is the one place the values were moved OUT of the style string in
   blog-post.js and into .bp-quote, so its phone rule needs no !important.
   ══════════════════════════════════════════════════════════════════════ */
.bp-quote {padding:28px 32px;gap:16px}
.bp-quote > span {font-size:44px}

@media (max-width:760px) {
/* Search pill: it is a <label for="aq"> so any tap in the pill focuses the
   field — before, only the bare 19px input inside the 31px pill was live, the
   magnifier and the padding were dead. On phones it takes the whole row (it
   stopped 31px short of the 351px card column) and the input's own padding
   makes the hit box 43px; the wrapper's 6px is dropped so the pill does not
   grow twice. Desktop keeps the 31px pill. */
.aq-wrap {width:100%;padding:0 8px 0 18px !important}
.aq-wrap #aq {padding:12px 0}
}

@media (max-width:600px) {
/* Pull quote: 64px of padding + a 24.6px mark + 16px gap ate 105px of a
   351px box, leaving the text 246px wide at 19–21 characters per line. */
.bp-quote {padding:20px 22px;gap:10px}
.bp-quote > span {font-size:30px}
/* 'Artikel asli →' always wraps under the share tags here (the row is ~419px
   of content in 351px); margin-left:auto then parked it bottom-right, exactly
   where the Dara launcher scrolls in. padding-left:0 lines it up with BAGIKAN. */
body[data-page="blog-post"] #bpLive {margin-left:0 !important;padding-left:0}
/* Breadcrumb: the third crumb dropped to its own line, ellipsised at 351px,
   with a dangling → left on line one. The h1 right below repeats the title,
   so on a phone the crumb is 'Home → Blog'. */
body[data-page="blog-post"] #bcName,
body[data-page="blog-post"] header > div > span:nth-of-type(2) {display:none}
/* Green CTA card: the two stacked buttons were 199px and 144px wide, under
   56px of vertical padding. 6vw (not a fixed 24px) keeps the h2 at two lines
   at 360. */
.blog-cta {padding:36px 6vw !important}
.blog-cta .btn {flex:1 1 100%}
}

@media (max-width:640px) {
/* 404: its one <section> is both the page head and the whole page, so the
   site-wide .page-head rule (padding-bottom:28px !important, at the end of
   this file) would leave the four pill links 28px above the forest footer.
   Same !important, higher specificity, so this wins whatever the order. */
body[data-page="notfound"] .page-head {padding-bottom:64px !important}
}

/* ══════════════════════════════════════════════════════════════════════
   SIGN IN WITH GOOGLE — the button slot, and the signed-in chip in the nav

   The button itself is Google's own rendered widget (da-auth.js asks for
   shape:'pill', theme:'outline'), so nothing here restyles it: their terms
   require their mark and wording, and an override would only fight the
   iframe. These rules give it a home and match everything around it.
   ══════════════════════════════════════════════════════════════════════ */
.g-slot { display: flex; justify-content: center; min-height: 44px; }
.g-slot:empty { display: none; }
.g-or { display: flex; align-items: center; gap: 12px; margin: 2px 0;
        font-size: var(--fs-read); font-weight: 700; letter-spacing: .12em;
        text-transform: uppercase; color: var(--color-neutral-500); }
.g-or::before, .g-or::after { content: ""; flex: 1; height: 1px; background: var(--color-divider); }
/* da-auth.js hides both by `hidden` while there is no client ID (and would
   again if the GSI script never mounts a button). The display:flex above
   beats the UA sheet's [hidden] exactly as .si-slot's did, so the divider
   stood on signin.html with "atau masuk dengan email" and nothing above it. */
.g-or[hidden], .g-slot[hidden] { display: none; }

/* Phones: the remember-me / terms sentence may use the whole column. The
   inline 300px cap (signin.html, register.html) exists so "Forgot password?"
   sits beside the text on wider screens — true in the 480px column at 1440
   and still at 700 — but in a 351px column it only wrapped the sentence to
   three lines with 51px unused, and the link had already dropped a row. */
@media (max-width: 600px) {
  #auRem { max-width: none !important; }
}

/* The two nav states, signed-out (#siWrap) and signed-in (#siUser), swap by
   `hidden`. Their display MUST live here and not in a style attribute: an
   inline display beats the UA sheet's [hidden]{display:none} — with it inline
   the chip showed as an empty circle while signed out AND "Sign in" stayed
   put while signed in, both at once. */
.si-slot { position: relative; display: inline-flex; }
.si-slot[hidden] { display: none; }

/* the nav, once somebody is signed in */
.si-chip { display: inline-flex; align-items: center; gap: 9px; border: none; cursor: pointer;
           background: transparent; padding: 4px 6px 4px 4px; border-radius: 999px;
           font-family: var(--font-body); transition: background-color .25s ease; }
.si-chip:hover { background: color-mix(in srgb, var(--color-accent) 12%, transparent); }
.si-avatar { width: 30px; height: 30px; flex: none; border-radius: 50%;
             background: var(--color-accent) center/cover no-repeat;
             color: var(--color-bg); font-size: 13px; font-weight: 800;
             display: inline-flex; align-items: center; justify-content: center; }
.si-name { font-size: 14px; font-weight: 600; color: var(--color-text); max-width: 12ch;
           overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* the nav sits on the illustration on the home page, where its text is cream */
nav.da-nav .si-name { color: var(--dv-cream); }
body[data-page="home"] nav.da-nav.solid .si-name { color: var(--color-text); }

.si-menu { position: absolute; top: calc(100% + 14px); right: 0; width: 236px;
           background: var(--color-bg); border-radius: calc(var(--radius-lg) * 1.1);
           box-shadow: var(--shadow-lg); padding: 16px; white-space: normal;
           text-align: left; color: var(--color-text); }
.si-who { margin-bottom: 14px; min-width: 0; }
.si-who__n { font-family: var(--font-heading); font-size: 17px; line-height: 1.15; }
.si-who__e { font-size: var(--fs-read); color: var(--color-neutral-600); margin-top: 2px;
             overflow: hidden; text-overflow: ellipsis; }
.si-demo { font-size: var(--fs-read); font-weight: 700; letter-spacing: .04em; color: #96442b;
           background: #f8e3da; border-radius: 999px; padding: 6px 12px; margin-bottom: 12px;
           text-align: center; }
.si-demo[hidden] { display: none; }
.si-out { width: 100%; cursor: pointer; font-size: 14px; box-sizing: border-box; }

/* the account list inside the chip menu. It had no rules at all: fifteen
   children stacked at their default inline layout, and between 860px and the
   mobile world this menu is the ONLY route into the account area. */
.si-links { display: flex; flex-direction: column; gap: 1px; margin-bottom: 12px;
            max-height: min(46vh, 300px); overflow: auto; overscroll-behavior: contain; }
.si-links a { display: flex; align-items: center; min-height: 32px; padding: 0 10px;
              border-radius: calc(var(--radius-md) - 4px); font-size: var(--fs-read);
              font-weight: 600; color: var(--color-text); text-decoration: none; }
.si-links a:hover { background: color-mix(in srgb, var(--color-text) 5%, transparent); }
.si-links a[aria-current="page"] { background: var(--color-accent-100); color: var(--color-accent-800); }
.si-links__g { padding: 10px 10px 3px; font-size: var(--fs-read); font-weight: 700;
               letter-spacing: .12em; text-transform: uppercase; color: var(--color-neutral-700); }

@media (max-width: 1020px) { nav.da-nav .si-name { display: none; } }
/* On a phone the 236px menu hung from the chip's right edge at x=194 (390) /
   179 (360), so it started 42-57px off the left of the screen and every label
   lost its first letters. With the slot static the containing block is the
   pill itself (fixed, centred), so the menu centres in the viewport. Rows 32 -> 44px. */
@media (max-width: 860px) {
  nav.da-nav .si-slot { position: static; }
  nav.da-nav .si-menu { left: 50%; right: auto; transform: translateX(-50%); top: calc(100% + 10px); width: calc(100vw - 24px); max-width: 360px; box-sizing: border-box; }
  nav.da-nav .si-links { max-height: min(calc(100vh - 310px), 420px); }   /* 89 top + ~205 of chrome + 16 clear: 258 at 568, 420 from 730 up */
  nav.da-nav .si-links a { min-height: 44px; }
}

/* the activation page's "this link belongs to" block */
.ac-who { display: flex; align-items: center; gap: 14px; background: var(--color-accent-100);
          border-radius: var(--radius-md); padding: 14px 18px; }
.ac-who__ic { width: 34px; height: 34px; flex: none; border-radius: 50%; background: var(--color-bg);
              color: var(--color-accent); display: inline-flex; align-items: center; justify-content: center; }
.ac-who__n { display: block; font-size: 14.5px; font-weight: 700; color: var(--color-accent-800); }
.ac-who__e { display: block; font-size: var(--fs-read); color: var(--color-accent-800); opacity: .8;
             overflow: hidden; text-overflow: ellipsis; }

/* ══════════════════════════════════════════════════════════════════════
   PENURUNAN — ISI YANG MEMADATKAN
   Enam blok baru di lima lubang: Tentang (±2 m), garis air (−14 m),
   konsol kimia air (−28 m), catatan lapangan + tiga pintu (−32 m), dan
   nama merek yang berhenti bersembunyi.
   Aturannya satu: setiap seksi TRANSPARAN dan duduk DI ATAS ilustrasi.
   Panel hanya di tingkat kartu, semuanya semi-transparan + blur, jadi
   hutan dan laut tetap terbaca di belakangnya.
   ══════════════════════════════════════════════════════════════════════ */

/* — ±2 m · Tentang Dunia Anura (register krem-hutan) — */
.taWrap { display: grid; grid-template-columns: 1.12fr .88fr; gap: clamp(26px,3vw,54px); align-items: center; }
.taSay { display: flex; flex-direction: column; align-items: flex-start; gap: 13px; }
.taKick { color: #C9E5A6; text-shadow: 0 1px 2px rgba(8,26,12,.95), 0 2px 12px rgba(8,26,12,.85); }
.taKick i { background: #C9E5A6; }
.taH { font-size: clamp(28px,3.4vw,50px); color: #F6FBEA; text-shadow: 0 3px 16px rgba(10,32,14,.6); }
.taH .lf { color: #A9D488; }
.taP { margin: 0; max-width: 58ch; font-size: 17px; line-height: 1.72; color: #DCEBC8; text-shadow: 0 2px 10px rgba(10,32,14,.6); }
.taP.dim { font-size: 15.5px; color: rgba(220,235,200,.84); }
.taGo { font-size: 16px; margin-top: 8px; }
.taNums { display: grid; grid-template-columns: repeat(3,1fr); gap: 22px 12px; }
.taNums svg { width: 60px; height: 40px; margin: 0 auto; display: block; color: #FF9A3D; }
.taNums .num { text-shadow: 0 0 22px rgba(255,175,99,.45), 0 2px 10px rgba(10,32,14,.7); }
.taNums .lbl { text-shadow: 0 2px 10px rgba(10,32,14,.8); }
.taKit { margin-top: clamp(26px,2.8vw,46px); display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }
.taKitK { font-size: 15px; font-weight: 800; letter-spacing: .22em; text-transform: uppercase; color: #C9E5A6; text-shadow: 0 2px 10px rgba(10,32,14,.85); }
.taKitRow { display: grid; grid-template-columns: repeat(5,1fr); gap: clamp(10px,1vw,18px); width: 100%; }
.taKitI {
  display: flex; flex-direction: column; align-items: center; text-align: center; gap: 7px;
  padding: 18px 14px 20px; border-radius: calc(var(--radius-lg)*1.25);
  background: rgba(20,48,22,.5); backdrop-filter: blur(7px); -webkit-backdrop-filter: blur(7px);
  border: 1.5px solid rgba(201,229,166,.4); color: #EDF6DE;
  transition: transform .4s cubic-bezier(.22,1,.36,1), background-color .3s ease, border-color .3s ease;
}
.taKitI:hover { transform: translateY(-5px); background: rgba(78,122,56,.72); border-color: #A9D488; color: #FBFEF5; }
.taKitI .ph { display: block; width: 78px; height: 78px; border-radius: 16px; overflow: hidden; background: rgba(246,251,234,.92); }
.taKitI .ph img { width: 100%; height: 100%; object-fit: contain; }
.taKitI .lyr { font-size: 14.5px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: #A9D488; }
.taKitI .nm { font-size: 15.5px; line-height: 1.4; font-weight: 700; }
.taKitI .pr { font-size: 15.5px; font-weight: 800; color: #C9E5A6; }
.taKitGo { font-size: 15px; }
.taFern { position: absolute; right: 2.5vw; bottom: -6px; width: clamp(84px,8vw,140px); height: auto; color: #123A20; opacity: .55; pointer-events: none; z-index: 1; }
/* Di bawah 1500 px ilustrasi hutan tidak punya sisa ruang: rak lima lapis
   menyusut jadi baris keping — tautan yang sama, tinggi sepersepuluhnya. */
@media (max-width: 1500px) {
  .taKitRow { display: flex; flex-wrap: wrap; gap: 9px; width: auto; }
  .taKitI { flex-direction: row; gap: 0; padding: 9px 17px; border-radius: 999px; text-align: left; }
  .taKitI .ph, .taKitI .nm, .taKitI .pr { display: none; }
  /* Di bawah 1500 px anggaran tinggi ilustrasi hutan tinggal ~365 px: setiap piksel
     yang tidak dipakai di sini adalah medalion spesies yang tidak perlu menyusut. */
  .taSay { gap: 9px; }
  .taH { font-size: clamp(26px,3vw,42px); }
  .taP { font-size: 15.5px; line-height: 1.66; }
  .taP.dim { font-size: 14.5px; }
  .taKit { margin-top: 16px; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 9px 12px; }
  .taNums { gap: 12px 10px; }
  .taNums svg { width: 50px; height: 34px; }
  .taNums .num { font-size: 32px; }
}
@media (max-width: 900px) {
  .taWrap { grid-template-columns: 1fr; gap: 24px; }
  .taFern { display: none; }
}
@media (max-width: 560px) { .taNums { gap: 10px 8px; } .taNums .num { font-size: 28px; } .taNums .lbl { font-size: var(--fs-read); } }

/* — −14 m · Garis air: register PERMUKAAN, tinta gelap di air pucat — */
.wlH { font-size: clamp(28px,4.2vw,58px); max-width: 18ch; color: #06333F; }
.wlLede { margin: 0; max-width: 56ch; font-size: clamp(14.5px,1.1vw,17px); line-height: 1.7; color: #0A4152; }
.wlGrid { display: grid; grid-template-columns: repeat(3,1fr); gap: clamp(12px,1.4vw,22px); max-width: 1000px; width: 100%; margin-top: clamp(4px,.8vw,12px); }
.wlCard {
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px; text-align: left;
  padding: clamp(16px,1.6vw,24px); border-radius: calc(var(--radius-lg)*1.25);
  background: rgba(247,253,255,.62); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  border: 1.5px solid rgba(11,74,90,.16); box-shadow: 0 12px 26px -14px rgba(3,42,58,.45);
}
.wlCard svg { width: 26px; height: 26px; color: #0B4A5A; }
.wlCard b { font-family: var(--font-heading); font-weight: 400; font-size: 18px; line-height: 1.25; color: #06333F; }
.wlCard p { margin: 0; font-size: var(--fs-read); line-height: 1.6; color: #0A4152; }
.wlFoot { margin: 0; max-width: 62ch; font-size: var(--fs-read); line-height: 1.6; color: rgba(10,65,82,.8); }
.wlPills { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }
.sea-pill.surf-ghost { background: rgba(255,255,255,.45); color: #06333F; border: 2px solid rgba(11,74,90,.4); box-shadow: none; }
.sea-pill.surf-ghost:hover { background: rgba(255,255,255,.75); color: #06333F; border-color: #0B4A5A; }
@media (max-width: 900px) {
  .wlGrid { grid-template-columns: 1fr 1fr; }
  .wlGrid > :last-child { grid-column: span 2; }
}
@media (max-width: 600px) { .wlGrid { grid-template-columns: 1fr; } .wlGrid > :last-child { grid-column: auto; } }

/* — −28 m · Konsol kimia air (.dv-sonar, selama ini tanpa markup) — */
.eqCon { max-width: 900px; margin: clamp(40px,4vw,64px) auto 0; position: relative; z-index: 4; }
.eqTop { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.eqK { display: inline-flex; align-items: center; gap: 10px; }
.eqK .dv-kicker { color: var(--dv-biolum); letter-spacing: .18em; }
.eqGo { font-size: var(--fs-read); padding: 10px 20px; background: var(--dv-biolum); color: #04282B; }
.eqGo:hover { background: #7FF6DC; color: #04282B; }
.eqH { font-size: clamp(21px,2.4vw,30px); color: var(--dv-navy-ink); margin: 12px 0 6px; }
.eqP { margin: 0 0 18px; font-size: 14px; line-height: 1.6; color: rgba(184,241,255,.78); max-width: 56ch; }
.eqDeck { display: grid; grid-template-columns: repeat(3,1fr); gap: 14px; }
.eqRow {
  display: flex; flex-direction: column; gap: 5px; padding: 14px 16px; border-radius: 18px;
  background: rgba(6,32,52,.5); border: 1px solid rgba(184,241,255,.22); color: var(--dv-navy-ink);
  transition: transform .4s cubic-bezier(.22,1,.36,1), border-color .3s ease, background-color .3s ease;
}
.eqRow:hover { transform: translateY(-4px); border-color: var(--dv-biolum); background: rgba(10,58,92,.6); color: var(--dv-navy-ink); }
.eqRow b { font-family: var(--font-heading); font-weight: 400; font-size: 17px; line-height: 1.2; }
.eqRow span { font-size: var(--fs-read); line-height: 1.55; color: rgba(184,241,255,.72); }
@media (max-width: 900px) { .eqDeck { grid-template-columns: 1fr; } }

/* — −32 m · Catatan lapangan + tiga pintu — */
.fnHead { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 11px; }
.fnH { font-size: clamp(27px,4vw,52px); }
.fnLede { margin: 0; max-width: 52ch; font-size: 15px; line-height: 1.65; color: #CFEEF7; }
.fnGrid { display: grid; grid-template-columns: repeat(3,minmax(0,1fr)); gap: 30px 24px; justify-items: center;
  max-width: 900px; margin: clamp(26px,2.8vw,44px) auto 0; }
@media (max-width: 780px) { .fnGrid { grid-template-columns: repeat(2,minmax(0,1fr)); } }
@media (max-width: 520px) { .fnGrid { grid-template-columns: 1fr; } }
.fnGo { display: flex; justify-content: center; margin-top: clamp(24px,2.4vw,38px); }
.pathGrid { display: grid; grid-template-columns: repeat(3,1fr); gap: clamp(14px,1.6vw,24px); max-width: 1040px; margin: clamp(24px,2.6vw,40px) auto 0; }
.pathCard {
  display: flex; flex-direction: column; gap: 7px; padding: clamp(18px,1.8vw,26px);
  border-radius: calc(var(--radius-lg)*1.25);
  background: rgba(4,24,43,.55); border: 1.5px solid rgba(184,241,255,.3);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); color: var(--dv-navy-ink);
  transition: transform .45s cubic-bezier(.22,1,.36,1), border-color .3s ease, background-color .3s ease;
}
.pathCard:hover { transform: translateY(-6px); border-color: var(--dv-biolum); background: rgba(10,58,92,.6); color: var(--dv-navy-ink); }
.pathCard .n { font-size: var(--fs-min); font-weight: 800; letter-spacing: .2em; color: var(--dv-biolum); }
.pathCard b { font-family: var(--font-heading); font-weight: 400; font-size: clamp(19px,1.7vw,23px); line-height: 1.2; color: #EAF9FF; }
.pathCard p { margin: 0; font-size: var(--fs-read); line-height: 1.6; color: rgba(207,238,247,.82); }
.pathCard .go { margin-top: 6px; font-size: var(--fs-read); font-weight: 800; color: var(--dv-biolum); }
.pathFoot { text-align: center; margin: clamp(22px,2.2vw,34px) 0 0; font-size: 14px; line-height: 1.65; color: rgba(207,238,247,.74); }
.pathFoot a { color: #EAF9FF; text-decoration: underline; text-underline-offset: 3px; }
.pathFoot a:hover { color: var(--dv-biolum); }
@media (max-width: 820px) { .pathGrid { grid-template-columns: 1fr; } }

/* — −32 m · Nama merek: berhenti bersembunyi di balik kursor.
   Dua pita 44 px yang terbaca kosong jadi dua baris keterangan, nol piksel
   tambahan. Dunia Anura sendiri dikecualikan: toko ini bukan salah satu
   merek mitra yang dipercayainya. Di bawah 1000 px grid jadi 4 kolom dan
   labelnya bertabrakan, jadi di sana kembali hover-only. */
@media (min-width: 1001px) {
  .bBub:not([data-self]) b { opacity: .78; transform: translate(-50%,0); }
  .bBub:not([data-self]):hover b { opacity: 1; }
}

/* ══════════════════════════════════════════════════════════════════════
   Phone rules shared by every page (the mobile pass).
   ══════════════════════════════════════════════════════════════════════ */
/* Page headers carry padding-top:170px inline for the pill on a desktop; on a
   phone that is a fifth of the screen above the h1. The pill's bottom is at
   78px, so 120 leaves the same 40-odd px of air. */
@media (max-width: 640px) {
  .page-head { padding-top: 120px !important; padding-bottom: 28px !important; }
}
/* ══════════════════════════════════════════════════════════════════════════
   BERANDA DI PONSEL — "KOLOM AIR"  (<=640 px)

   Ponsel sudah berbentuk kolom vertikal, jadi gulirannya sendiri yang dijadikan
   penyelaman: satu kolom air yang MENDINGIN dari tajuk hutan (0 m) sampai
   palung (−32 m), tanpa satu pun batas keras di antaranya. Latarnya tetap
   terang seperti halaman lain (--color-bg di puncak); satu-satunya yang gelap
   adalah footer palung, dan itu terasa sebagai hadiah karena pembaca sudah
   turun jauh untuk sampai ke sana.

   Semua lukisan, jendela potongan, efek tanah, sambungan, ikan, kunang-kunang,
   burung, daun, dan siluet vektor mati di sini — sekitar 1,1 MB yang tidak
   perlu diunduh di koneksi seluler.

   Tiga alat, masing-masing satu tugas:
     .dvr       rel kedalaman — penanda gulir yang juga daftar isi (navigasi)
     .dvs       rak ketersediaan — 43 dari 308 yang benar-benar bisa dibeli
     .spx-*     ubin spesimen — kesulitan, bendera asal, stok, baru harga

   Desktop tidak tersentuh: seluruh blok ini di dalam media query, dan tiap
   simpul yang ditambahkan ke markup display:none di luarnya (aturan tepat di
   bawah ini). Diverifikasi dengan diff piksel 1440×900, wajib 0.
   ══════════════════════════════════════════════════════════════════════════ */
.dv-artfoot, .dv-artwin, .dv-vec, .dv-phone, .dv-amb,
.dvr, .dvr-scrim, .dvr-sheet, .dvs, .spx-diff, .spx-flag, .spx-stock, .cat-n { display: none; }
.wlHead { display: contents; }   /* kepala garis air: deretan flex biasa di desktop */

@media (max-width: 640px) {

.dv-amb { display: block; }

/* ── 1. kolom air: gradasi, bukan blok warna ───────────────────────────────
   home.js menulis `top` #dvForestFill/#dvSeaFill inline (di bawah tepi lukisan),
   jadi keduanya harus dipukul dengan !important supaya isi seluruh band. */
#dvForestArt > svg, #dvSeaArt > svg, #dvSeamFx, #dvGroundFx,
#dv-terumbu > .dv-artwin, .aqFish,
#dv-puncak > div[aria-hidden], #dv-forest .ff, #dv-forest .ffw,
#dv-forest .mote, #dv-forest .fleaf { display: none !important; }
#dvForestFill { top: 0 !important;
  background: linear-gradient(180deg, #F7F9F4 0%, #F2F7F0 56%, #E9F2ED 100%) !important; }
#dvSeaFill { top: 0 !important;
  background: linear-gradient(180deg, #E4F0F2 0%, #D2E3ED 100%) !important; }
#dv-forest, #dv-sea { min-height: 0 !important; }
#dv-terumbu > :not(.dv-artwin):not(.dv-vec) { position: relative; z-index: 1; }

/* ── Lapisan ambient: daun berguguran di hutan, gelembung naik di laut ──────
   Tiap sprite menempuh ± satu layar dari posisi tetapnya, bukan menyeberangi
   band setinggi 3.600 px — kalau tidak, di layar mana pun nyaris tidak ada
   gerak yang terlihat. Keduanya di dalam pembungkus seni (z-index 0) sehingga
   selalu di belakang isi halaman, dan hanya menganimasikan transform + opacity
   supaya tidak memicu tata letak ulang. */
/* z-index 1 WAJIB: lapisan gelembung tersisip sebagai anak pertama #dvSeaArt,
   sebelum #dvSeaFill — dan karena keduanya absolut tanpa z-index, gradasi
   lautlah yang melukis paling akhir dan menutupi seluruh gelembungnya. Daun
   kebetulan lolos karena tersisip SESUDAH #dvForestFill. Dengan z-index di
   sini, keduanya aman tanpa bergantung pada urutan markup. */
.dv-amb { display: block; position: absolute; inset: 0; overflow: hidden;
  pointer-events: none; z-index: 1; }
/* tanpa will-change: 40 sprite berarti 40 lapisan komposit yang disiapkan
   terus-menerus. transform+opacity yang sedang berjalan sudah dipromosikan
   sendiri oleh peramban, hanya selama animasinya jalan. */
.dv-amb > span { position: absolute; display: block; opacity: 0; }
.dv-amb--leaf > span { width: var(--w, 16px); animation: dvLeafFall var(--d, 20s) linear infinite; }
.dv-amb--leaf svg { display: block; width: 100%; height: auto; fill: currentColor; }
.dv-amb--bub > span { width: var(--w, 8px); height: var(--w, 8px); border-radius: 50%;
  border: 1.5px solid rgba(11, 74, 90, .5);
  background: radial-gradient(circle at 32% 27%, rgba(255, 255, 255, .96), rgba(255, 255, 255, .46) 44%,
    rgba(159, 227, 240, .24) 70%, rgba(159, 227, 240, .06) 100%);
  box-shadow: inset 0 -2px 4px -1px rgba(11, 74, 90, .22);
  animation: dvBubRise var(--d, 20s) linear infinite; }
@keyframes dvLeafFall {
  0%   { transform: translate3d(0, 0, 0) rotate(0deg); opacity: 0; }
  10%  { opacity: var(--o, .4); }
  86%  { opacity: var(--o, .4); }
  100% { transform: translate3d(var(--dx, 32px), 88vh, 0) rotate(var(--rot, 300deg)); opacity: 0; }
}
@keyframes dvBubRise {
  0%   { transform: translate3d(0, 0, 0) scale(.8); opacity: 0; }
  14%  { opacity: calc(var(--o, .36) + .16); }
  78%  { opacity: calc(var(--o, .36) + .16); }
  100% { transform: translate3d(var(--dx, 12px), -76vh, 0) scale(1.1); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .dv-amb { display: none; } }
/* ── Dunia kedua: pil navigasi jadi biru muda ──────────────────────────────
   Tinta di dalamnya harus ikut berbalik. Semua anak pil ini diwarnai untuk
   latar GELAP (krem di atas rgba(255,247,230,.12)), jadi di atas biru muda
   krem itu akan hilang. Yang diwarnai ulang hanya yang benar-benar tampil di
   ponsel: keranjang, tombol menu, dan cip akun. Tombol Adopsi tetap kuning —
   di atas biru muda ia justru makin menonjol. */
body.dv-under nav.da-nav {
  background: color-mix(in srgb, #CFE8F0 93%, transparent) !important;
  box-shadow: 0 12px 30px -16px rgba(6, 44, 58, .5); }
body.dv-under nav.da-nav .cart-btn,
body.dv-under nav.da-nav .nav-menu-btn { background: rgba(11, 74, 90, .1) !important; }
body.dv-under nav.da-nav .cart-btn:hover,
body.dv-under nav.da-nav .nav-menu-btn:hover { background: rgba(11, 74, 90, .18) !important; }
body.dv-under nav.da-nav .cart-btn svg,
body.dv-under nav.da-nav .nav-menu-btn,
body.dv-under nav.da-nav .si-chip { color: #0B4A5A !important; }
body.dv-under nav.da-nav .si-chip { background: rgba(11, 74, 90, .1) !important; }
body.dv-under nav.da-nav .nav-menu-btn[aria-expanded="true"] {
  background: #0B4A5A !important; color: #EAF9FF !important; }

/* isi bergeser 10 px dari tepi supaya tidak menempel pada rel */
#dv-forest .dv-content, #dv-sea .dv-content, #dv-mulai > .dv-content { padding-left: calc(5vw + 16px) !important; }

/* ── 2. rel kedalaman ──────────────────────────────────────────────────────
   Lebar 16 px, jadi ongkosnya hanya 10 px ruang isi. z 60: di atas isi,
   di bawah Dara (180), lembar filter (220) dan keranjang (230). */
.dvr { display: block; position: fixed; left: 0; top: 0; bottom: 0; width: 24px; z-index: 60;
  padding: 0; border: 0; background: none; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.dvr__line { position: absolute; left: 11px; top: 76px; bottom: 74px; width: 2px; border-radius: 2px;
  background: linear-gradient(180deg, #4C8C46, #366D33 24%, #6FAFAE 46%, #0F6E96 66%, #0B4A5A 84%, #062033);
  opacity: .38; }
.dvr__tick { position: absolute; left: 6px; top: 0; width: 12px; height: 12px; border-radius: 50%;
  background: #FFFFFF; border: 2.5px solid var(--dvr-c, #366D33); transform: translateY(120px);
  box-shadow: 0 1px 4px rgba(16, 44, 24, .3); }
.dvr__read { position: absolute; left: -1px; top: 0; width: 26px; white-space: nowrap; transform: translateY(138px);
  font-size: 9px; font-weight: 800; letter-spacing: .01em; text-align: center; color: var(--dvr-c, #366D33);
  font-variant-numeric: tabular-nums; }
.dvr:focus-visible { outline: 2px solid var(--dvr-c, #366D33); outline-offset: -2px; }
@media (prefers-reduced-motion: no-preference) {
  .dvr__tick, .dvr__read { transition: transform .12s linear; }
}

.dvr-scrim { display: block; position: fixed; inset: 0; z-index: 224; background: rgba(8, 26, 20, .42);
  touch-action: none; opacity: 0; visibility: hidden; transition: opacity .3s ease, visibility 0s .3s; }
html.dvr-open .dvr-scrim { opacity: 1; visibility: visible; transition: opacity .3s ease; }
.dvr-sheet { display: flex; flex-direction: column; position: fixed; left: 0; right: 0; bottom: 0; z-index: 225;
  max-height: 84vh; overflow: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  padding: 10px 5vw calc(14px + env(safe-area-inset-bottom, 0px));
  background: var(--color-bg); border-radius: 22px 22px 0 0;
  box-shadow: 0 -12px 40px rgba(0, 0, 0, .2);
  transform: translateY(102%); visibility: hidden;
  transition: transform .32s cubic-bezier(.22, 1, .36, 1), visibility 0s .32s; }
html.dvr-open .dvr-sheet { transform: none; visibility: visible;
  transition: transform .32s cubic-bezier(.22, 1, .36, 1); }
html.dvr-open { overflow: hidden; }
html.dvr-open #daChatBtn { opacity: 0; pointer-events: none; }   /* zona aman Dara */
.dvr-sheet__head { display: grid; grid-template-columns: 1fr auto; align-items: center; position: relative;
  padding: 12px 0 8px; margin-bottom: 4px; border-bottom: 1px solid var(--color-divider); }
.dvr-sheet__handle { position: absolute; top: 0; left: 50%; width: 40px; height: 4px; margin-left: -20px;
  border-radius: 999px; background: var(--color-neutral-300); }
.dvr-sheet__title { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 21px; }
.dvr-sheet__x { width: 44px; height: 44px; margin-right: -8px; border: 0; border-radius: 999px;
  background: var(--color-surface); color: var(--color-text); font-size: 15px; font-weight: 700; cursor: pointer; }
.dvr-row { display: grid; grid-template-columns: 46px minmax(0, 1fr); align-items: baseline; gap: 12px;
  min-height: 52px; padding: 9px 6px; border-bottom: 1px solid var(--color-divider); color: var(--color-text); }
.dvr-row:last-child { border-bottom: 0; }
.dvr-row > b { font-size: 13px; font-weight: 800; color: var(--color-accent-700);
  font-variant-numeric: tabular-nums; letter-spacing: .01em; }
.dvr-row--sea > b { color: #0B4A5A; }
.dvr-row__n { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 17px; }
.dvr-row__m { display: block; grid-column: 2; font-style: normal; font-size: 12.5px;
  color: var(--color-neutral-600); margin-top: 1px; }

/* ── 3. kepala bagian: judul kiri, tautan teks kanan ───────────────────────── */
#dv-forest .dv-content h2, #dv-sea .dv-content h2 { font-size: 28px !important; }
.nsHead > .dv-pill, #dv-sea .dv-content > div[data-reveal] > .sea-pill {
  background: none !important; border: 0; box-shadow: none; padding: 0 !important; min-height: 44px;
  display: inline-flex; align-items: center;
  backdrop-filter: none; -webkit-backdrop-filter: none; font-size: 14px !important; font-weight: 800; white-space: nowrap; }
.nsHead > .dv-pill { color: var(--color-accent-700); }
#dv-sea .dv-content > div[data-reveal] > .sea-pill { color: #0B4A5A; }
/* Kepala bagian laut punya lede: disandingkan dengan tautan, lede-nya terjepit
   jadi kolom 230px. Kepala hutan (.nsHead) tidak punya lede, jadi tetap
   bersanding judul-kiri / tautan-kanan seperti pola beranda resmi. */
.nsHead { display: grid !important; grid-template-columns: minmax(0, 1fr) auto;
  align-items: end; gap: 12px; margin-bottom: 16px !important; }
#dv-sea .dv-content > div[data-reveal]:has(> .sea-pill) {
  display: flex !important; flex-direction: column; align-items: flex-start !important; gap: 9px;
  margin-bottom: 16px !important; }   /* !important: kepala ini membawa align-items:flex-end inline */
#dv-sea .dv-content > div[data-reveal] > .sea-pill .sea-kick i,
#dv-sea .dv-content > div[data-reveal] .sea-kick i { display: none; }   /* garis pemisah membuat kicker pecah dua baris */
#dv-sea .dv-content > div[data-reveal]:has(> .sea-pill.ghost):not(:has(h2)) {
  display: flex !important; justify-content: center; margin-top: 8px !important; }

/* ── 4. tajuk + rak ketersediaan ──────────────────────────────────────────── */
/* Tajuk: judul adalah tokoh utamanya, jadi ia dapat ruang dan dirata-tengahkan
   bersama kalimat dan kedua tombolnya. Bantalan kiri-kanan dibuat SAMA (5vw+16
   keduanya, bukan 5vw di kanan) — kalau tidak, rata tengahnya meleset 8 px
   karena sisi kiri disisihkan untuk rel kedalaman. Rak ketersediaan di bawahnya
   kembali rata kiri: ia baris geser, bukan bagian dari tajuk. */
#dv-puncak { min-height: 0 !important; }
#dv-puncak > .dv-content { padding: 116px calc(5vw + 16px) 30px !important; text-align: center; }
#dv-puncak h1 { font-size: 53px !important; line-height: .97 !important;
  color: var(--color-accent-900) !important; text-shadow: none !important; }
#dv-puncak h1 > span:last-child { color: var(--color-accent-600) !important; text-shadow: none !important; }
#dv-puncak h1 + p { margin: 18px auto 24px !important; max-width: 32ch; font-size: 15.5px !important;
  color: var(--color-neutral-800) !important; text-shadow: none !important; font-weight: 500 !important; }
#dv-puncak .dv-content > div[data-reveal] { justify-content: center; }
#dv-puncak .dv-pill:not(.sun) { background: #FFFFFF; color: var(--color-text);
  border: 1.5px solid var(--color-divider); box-shadow: none; }
.dvs { text-align: left; }

.dvs { display: block; margin-top: 26px; }
.dvs__head { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; gap: 10px; }
.dvs__live { display: inline-flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
  font-size: 12.5px; font-weight: 700; color: var(--color-neutral-700); }
.dvs__live b { position: relative; padding-left: 14px; font-size: 15px; font-weight: 800;
  color: var(--color-accent-700); font-variant-numeric: tabular-nums; }
.dvs__live b::before { content: ""; position: absolute; left: 0; top: 50%; width: 7px; height: 7px;
  margin-top: -3px; border-radius: 50%; background: var(--color-accent-600);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent-600) 20%, transparent); }
.dvs__all { font-size: 13px; font-weight: 800; color: var(--color-accent-700); white-space: nowrap; }
.dvs__row { display: flex; gap: 10px; overflow-x: auto; scroll-snap-type: x proximity;
  margin: 11px 0 0 -2px; padding: 2px 34px 10px 2px;
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 34px), transparent);
  mask-image: linear-gradient(90deg, #000 calc(100% - 34px), transparent); }
.dvs__c { flex: none; width: 124px; scroll-snap-align: start; background: #FFFFFF;
  border: 1px solid var(--color-divider); border-radius: 14px; overflow: hidden;
  display: flex; flex-direction: column; color: var(--color-text); }
.dvs__ph { position: relative; display: block; aspect-ratio: 1; background: var(--color-neutral-100); }
.dvs__ph > img:not(.spx-flag) { width: 100%; height: 100%; object-fit: cover; display: block; }
.dvs__t { display: flex; flex-direction: column; gap: 2px; padding: 8px 9px 10px; flex: 1; }
.dvs__n { font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 13px; line-height: 1.15; }
.dvs__p { margin-top: auto; padding-top: 4px; font-size: 11.5px; font-weight: 800;
  font-variant-numeric: tabular-nums; }

/* ── 5. ubin spesimen: kesulitan, bendera, stok ───────────────────────────── */
.spx-diff { display: block; position: absolute; left: 6px; top: 6px; z-index: 2;
  padding: 2px 7px; border-radius: 999px; background: #FFFFFF;
  font-size: 9px; font-weight: 800; letter-spacing: .06em;
  color: var(--color-accent-700); border: 1px solid var(--color-accent-700); }
.spx-diff--medium { color: #A0521E; border-color: #A0521E; }
.spx-diff--hard { color: #8E2F1B; border-color: #8E2F1B; }
.spx-flag { display: block; position: absolute; right: 6px; top: 6px; z-index: 2;
  width: 20px; height: 14px; border-radius: 2px; object-fit: cover;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .75); }
.spx-stock { display: block; font-style: normal; font-size: 10px; font-weight: 800;
  letter-spacing: .03em; color: var(--color-neutral-600); font-variant-numeric: tabular-nums; }
.spx-stock.is-on { color: var(--color-accent-700); }

/* ── 6. tentang ───────────────────────────────────────────────────────────── */
#dv-tentang > .dv-content { padding-top: 46px; padding-bottom: 14px; }

/* Deret angka: jamur dan bulatan cahayanya dibuang (permintaan pemilik) — di
   atas tanah terang keduanya jadi noda oranye, dan justru menenggelamkan
   angkanya. Yang tersisa satu kartu putih berisi tiga angka, sebangun dengan
   deret angka di halaman Tentang. Animasi berhitungnya sudah ada di main.js
   ([data-count]); angkanya dibesarkan supaya hitungannya benar-benar terbaca. */
.taNums { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 !important;
  margin-top: 6px; background: #FFFFFF; border: 1px solid var(--color-divider);
  border-radius: 20px; overflow: hidden; }
.dv-stat-mush { padding: 16px 8px 15px; border-right: 1px solid var(--color-divider); }
.dv-stat-mush:last-child { border-right: 0; }
.dv-stat-mush svg { display: none; }
.dv-stat-mush .num { font-size: 31px !important; line-height: 1;
  color: var(--color-accent-700); text-shadow: none;
  font-variant-numeric: tabular-nums; letter-spacing: -.015em; }
.dv-stat-mush .lbl { margin-top: 6px; font-size: 12px; line-height: 1.35;
  color: var(--color-neutral-600); text-shadow: none; }

/* Lima lapis: tiga baris chip yang berdesakan jadi SATU baris yang digeser, dan
   tiap lapis dapat nomornya. Penomoran di sini bukan hiasan — lapisannya memang
   urut dari dasar kandang ke atas: drainase, tanah, serasah, tanaman, kru
   pembersih. Nomornya dari counter CSS, jadi markup tidak perlu diubah. */
.taKit { margin-top: 30px; gap: 12px; }
.taKitK { font-size: 11px; letter-spacing: .2em; color: var(--color-accent-700) !important;
  text-shadow: none !important; }
.taKitRow { display: flex !important; flex-wrap: nowrap !important; gap: 10px !important;
  counter-reset: dvlyr; overflow-x: auto; scroll-snap-type: x proximity;
  margin-right: -5vw; padding: 2px calc(5vw + 26px) 12px 2px;
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 42px), transparent);
  mask-image: linear-gradient(90deg, #000 calc(100% - 42px), transparent); }
.taKitI { flex: none; scroll-snap-align: start; flex-direction: column !important;
  align-items: flex-start !important; gap: 3px !important; min-width: 118px;
  padding: 12px 15px 13px !important; border-radius: 16px !important;
  text-align: left; background: #FFFFFF; border-color: var(--color-divider); }
.taKitI::before { counter-increment: dvlyr; content: counter(dvlyr, decimal-leading-zero);
  font-size: 10px; font-weight: 800; letter-spacing: .12em; color: var(--color-accent-600); }
.taKitI .lyr { font-size: 13.5px; font-weight: 700; letter-spacing: .01em;
  text-transform: none; color: var(--color-text) !important; }
.taKitGo { margin-top: 4px; }
.taKick, .nsHead .sea-kick, .frstHead .sea-kick, .taKitK {
  color: var(--color-accent-700) !important; text-shadow: none !important; }
.taKick i, .nsHead .sea-kick i, .frstHead .sea-kick i { background: var(--color-accent-700) !important; }
.taH, .nsHead h2, .frstHead h2 { color: var(--color-text) !important; text-shadow: none !important; }
.taH .lf, .nsHead h2 span, .frstHead h2 span { color: var(--color-accent-600) !important; }
.taP, .frstHead p { color: var(--color-neutral-800) !important; text-shadow: none !important; }
.taP.dim { color: var(--color-neutral-700) !important; }
.dv-stat-mush .num { color: var(--color-accent-800); text-shadow: none; }
.dv-stat-mush .lbl { color: var(--color-neutral-700); }
.taKitI, .catChip { background: #FFFFFF; border-color: var(--color-divider); color: var(--color-text);
  backdrop-filter: none; -webkit-backdrop-filter: none; }
.taKitI .lyr, .catChip svg { color: var(--color-accent-700); }

/* ── 7. spesies terbaru: dua kolom ubin foto ──────────────────────────────── */
#dv-baru { padding: 48px 0 26px !important; min-height: 0 !important; }
.nsGrid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 11px; }
.nsCard { flex-direction: column; align-items: stretch; gap: 0; padding: 0; border-radius: 16px;
  overflow: hidden; background: #FFFFFF; border: 1px solid var(--color-divider);
  box-shadow: none; color: var(--color-text); }
.nsCard .disc { width: 100%; height: auto; aspect-ratio: 1; border-radius: 0; border: 0;
  background: var(--color-neutral-100); }
.nsCard .txt { gap: 2px; padding: 9px 11px 11px; }
.nsCard .mt { color: var(--color-accent-700); }
.nsCard .nm { font-size: 16px; color: var(--color-text); }
.nsCard .pr { font-size: 13px; color: var(--color-accent-900); }
/* Tag NEW dihapus di ponsel: kepala bagiannya sudah berbunyi "Baru tiba di
   Dunia Anura / Spesies terbaru", jadi penanda per kartu hanya mengulang, dan
   di ubin sesempit ini ia menutupi fotonya. */
.nsCard .badge { display: none; }
.nsCard:nth-child(3) { grid-column: 1 / -1; flex-direction: row; align-items: center; gap: 12px; }
.nsCard:nth-child(3) .disc { width: 108px; height: 108px; aspect-ratio: auto; flex: none; }
.nsCard:nth-child(3) .txt { padding: 8px 12px 8px 0; }

/* ── 8. spesies unggulan: ubin foto kotak, bukan medalion gantung ─────────── */
#dv-hutan { padding: 48px 0 54px !important; }
#dv-hutan .frstHead { order: -2; }
.catRow { order: -1; margin: 0 0 4px; gap: 7px; }   /* chip kategori naik ke atas ubin: pintu tercepat ke katalog */
.catChip { padding: 8px 13px; font-size: 12px; }
.catChip svg { width: 13px; height: 13px; }
.cat-n { display: inline; margin-left: 6px; font-style: normal; font-size: 10.5px; font-weight: 800;
  color: var(--color-neutral-600); font-variant-numeric: tabular-nums; }
.spGrid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 11px; width: 100%; max-width: none; }
.spHang { padding-top: 0; animation: none; border-radius: 16px; overflow: hidden; background: #FFFFFF;
  border: 1px solid var(--color-divider); text-align: left; box-shadow: none;
  display: flex; flex-direction: column; }
.spHang .cord { display: none; }
.spDisc { border-radius: 0; box-shadow: none !important; background: var(--color-neutral-100);
  transform: none !important; }
.spDisc > img:not(.spx-flag) { filter: none; }
.spDisc .vig { display: none; }
.spGrid { padding-bottom: 0; }
  /* Di ponsel .spMeta bukan plakat melainkan badan kartu putihnya sendiri:
     lepas latar, bingkai, dan bayangan yang dipakai versi desktop. */
  .spMeta { position: static; opacity: 1; transform: none; display: flex; flex-direction: column; gap: 2px;
  padding: 9px 11px 11px; flex: 1; background: none; border-radius: 0; box-shadow: none;
  backdrop-filter: none; -webkit-backdrop-filter: none;
  width: auto; max-width: none; }   /* lepas width:max-content plakat desktop: di sini .spMeta adalah badan kartu */
.spMeta b { font-size: 15px; color: var(--color-text); text-shadow: none; }
.spMeta i { order: 3; margin-top: auto; padding-top: 4px; color: var(--color-accent-900);
  text-shadow: none; font-size: 12px; }
.spMeta .spx-stock { order: 2; }
/* ── Ubin spesies unggulan: tidak ada keadaan hover di layar sentuh ────────
     Layar sentuh MENAHAN :hover setelah jari diangkat, dan tiga aturan desktop
     ikut menempel di ubin yang disentuh:
       .spHang:hover .spMeta  menggeser plakatnya translate(-50%,0) — di sini
                              .spMeta bukan plakat melainkan badan kartu, jadi
                              teksnya melompat 80px ke kiri dan terpotong;
       .spHang:hover .spDisc img  membesarkan fotonya 1,1x dan ia tinggal begitu;
       .spHang:hover  membekukan sway dengan animation-play-state:paused, jadi
                      ubinnya miring permanen di sudut mana pun sway berhenti.
     Ketiganya dimatikan dengan selektor yang specificity-nya sama dan posisinya
     lebih belakang — bukan dengan !important. Umpan balik sentuh diganti
     perubahan warna pada :active: ia habis sendiri begitu jari diangkat, dan
     tidak memakai transform, yang pada ubin ini sudah ditulis inline oleh GSAP
     (animasi reveal) sehingga transform dari stylesheet tidak akan terpakai. */
  .spHang, .spHang:hover { animation: none; }
  .spHang:hover .spMeta { transform: none; }
  .spHang:hover .spDisc img { transform: none; filter: none; }
  .spHang:active { border-color: var(--color-accent-400); background: var(--color-accent-100); }
  .spHang { transition: border-color .18s ease, background-color .18s ease; }
  .spHang:nth-child(n+7) { display: none; }

/* ── 9. −10 m jalur pemula ────────────────────────────────────────────────── */
#dv-mulai { display: block; padding: 34px 0 48px; overflow: visible; background: #E9F2ED; }
#dv-mulai > .dv-content { max-width: 1240px; margin: 0 auto; width: 100%; box-sizing: border-box;
  padding-right: 5vw; position: relative; z-index: 4; }
.mulai-k { display: block; font-size: 11px; font-weight: 800; letter-spacing: .2em;
  text-transform: uppercase; color: var(--color-accent-700); }
.mulai-h { margin: 7px 0 0; font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 26px !important; line-height: 1.08; color: var(--color-text); }
.mulai-h b { font-weight: inherit; color: var(--color-accent-600); font-variant-numeric: tabular-nums; }
.mulai-p { margin: 8px 0 0; font-size: 14.5px; line-height: 1.55; color: var(--color-neutral-800); }
.mulai-row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 13px; }
.mulai-chip { display: inline-flex; align-items: baseline; gap: 7px; padding: 9px 14px; border-radius: 999px;
  background: #FFFFFF; border: 1px solid var(--color-divider); font-size: 13px; font-weight: 700; }
.mulai-chip.is-on { border-color: var(--color-accent-600); color: var(--color-accent-800); }
.mulai-chip i { font-style: normal; font-size: 11px; font-weight: 800; color: var(--color-neutral-600);
  font-variant-numeric: tabular-nums; }
.mulai-chip.is-on i { color: var(--color-accent-700); }
.mulai-go { display: inline-flex; align-items: center; min-height: 44px; margin-top: 10px;
  font-size: 13.5px; font-weight: 800; color: var(--color-accent-700); }

/* ── 10. −14 m garis air: satu momen menyeberang ──────────────────────────── */
#dv-garisair { min-height: 0 !important; padding: 54px 0 58px !important;
  background: linear-gradient(180deg, #E9F2ED 0%, #D8ECF0 40%, #D8ECF0 66%, #E1EEF1 100%) !important; }
.wlHead .sea-kick i { display: none; }
.wlGrid { gap: 10px; }
.wlCard { padding: 14px 16px; background: #FFFFFF; border-color: var(--color-divider); box-shadow: none;
  backdrop-filter: none; -webkit-backdrop-filter: none; }
.wlFoot { color: #3B5C66; }

/* ── 11. laut: tinta teal gelap, kartu putih ──────────────────────────────── */
#dv-sea .sea-kick { color: #0B4A5A !important; text-shadow: none !important; }
#dv-sea .sea-kick i { background: #0B4A5A !important; opacity: .55; }
#dv-sea .dv-sea-h, .fnH, .wlH { color: #06333F !important; text-shadow: none !important; }
#dv-sea .dv-sea-lede, .fnLede, .eqP, .pathFoot, .pathCard p, .eqRow span, .wlLede {
  color: #3B5C66 !important; text-shadow: none !important; }
.sea-pill.ghost { background: #FFFFFF; color: #0B4A5A; border-color: var(--color-divider);
  backdrop-filter: none; -webkit-backdrop-filter: none; }
.sea-pill:not(.ghost):not(.surf-ghost):not(.eqGo) { background: #0B4A5A; color: #FFFFFF; box-shadow: none; }
.sea-pill.surf-ghost { background: #FFFFFF; border-color: var(--color-divider); }
#dv-terumbu { min-height: 0 !important; margin-top: 0 !important; padding: 54px 0 50px !important; }
.aqGrid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.aqCard { padding: 0; gap: 0; background: #FFFFFF; border: 1px solid var(--color-divider);
  box-shadow: none; color: var(--color-text); backdrop-filter: none; -webkit-backdrop-filter: none;
  border-radius: 16px; overflow: hidden; }
.aqCard .art { aspect-ratio: 1; border-radius: 0; background: var(--color-neutral-100) !important; }
.aqCard > :not(.art):not(.flag) { margin-left: 11px; margin-right: 11px; }
.aqCard .cat { margin-top: 9px; font-size: 10.5px; letter-spacing: .08em; color: #0B4A5A; }
.aqCard .nm { font-size: 16px; }
.aqCard .sci { color: var(--color-neutral-700); }
.aqCard .pr, .aqCard .soon { margin-top: 6px; margin-bottom: 11px; }
.aqCard .pr { color: #06333F; font-size: 13px; }
.aqCard .soon { color: #0B4A5A; font-size: 11px; letter-spacing: .06em; }
.aqCard .spx-stock { margin-top: 4px; }
.aqCard .flag { display: none; }   /* mengulang baris stok yang baru, dan bertabrakan dengan chip kesulitan */
.aqGrid > :nth-child(3) { grid-column: 1 / -1; display: grid;
  grid-template-columns: 88px minmax(0, 1fr); grid-auto-rows: auto; column-gap: 0; row-gap: 2px;
  align-items: center; }
.aqGrid > :nth-child(3) .art { grid-column: 1; grid-row: 1 / span 4; aspect-ratio: 1; width: 88px; }
.aqGrid > :nth-child(3) > :not(.art) { grid-column: 2; margin: 0 11px; }
.aqGrid > :nth-child(3) .cat { margin-top: 11px; }
.aqGrid > :nth-child(3) .soon { margin-bottom: 11px; }
.dv-sonar { background: #FFFFFF; border-color: var(--color-divider);
  backdrop-filter: none; -webkit-backdrop-filter: none; }
.dv-sonar .ping { background: #0B4A5A; }
.eqCon { margin-top: 26px; }
.eqK .dv-kicker { color: #0B4A5A; }
.eqGo { background: #0B4A5A; color: #FFFFFF; }
.eqH { color: #06333F; }
.eqRow { background: #F4F8FA; border-color: var(--color-divider); color: var(--color-text); }

/* ── 12. −32 m palung: produk, merek, catatan lapangan ────────────────────── */
#dv-lautdalam { min-height: 0 !important; margin-top: 0 !important;
  padding: 50px 0 64px !important; gap: 54px !important; }
#dv-lautdalam > .dv-content { min-width: 0; width: 100%; box-sizing: border-box; }
.prodGrid .pTile:nth-child(n+7) { display: none; }
.prodGrid .pTile { box-shadow: none; border: 1px solid var(--color-divider); }
.brandGrid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 9px; max-width: 100%;
  row-gap: 9px !important; }
.bBub { aspect-ratio: 1.45; border-radius: 13px; animation: none; transform: none !important;
  background: #FFFFFF; border: 1px solid var(--color-divider); box-shadow: none; }
.bBub::before, .bBub::after, .bBub .sheen, .bBub .pop, .bBub b { display: none; }
.bBub img { width: 72%; max-height: 62%; opacity: 1; }
.fnGrid { gap: 12px; justify-items: stretch; }   /* aturan dasarnya memusatkan: kartu yang seluruh anaknya absolut jadi selebar 0 */
.pcard { display: block; position: relative; width: 100%; aspect-ratio: 16 / 10; border-radius: 16px;
  overflow: hidden; background: #0B2740; text-align: left; transform: none !important; }
.pcard::after { content: ''; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(180deg, rgba(4, 18, 32, 0) 36%, rgba(4, 18, 32, .86) 100%); }
.pcard .port { position: absolute; inset: 0; width: 100%; max-width: none; aspect-ratio: auto; margin: 0; }
.pcard .port svg { display: none; }
.pcard .port img { left: 0; top: 0; width: 100%; height: 100%; border-radius: 0; object-fit: cover;
  transform: none !important; }
.pcard b { position: absolute; left: 14px; right: 14px; bottom: 33px; z-index: 2; margin: 0; max-width: none;
  font-size: 16.5px; color: #FFFFFF; text-shadow: 0 2px 8px rgba(0, 0, 0, .55); }
.pcard > span:last-child { position: absolute; left: 14px; bottom: 12px; z-index: 2; font-size: 12.5px; }
.pathCard { background: #FFFFFF; border-color: var(--color-divider); color: var(--color-text);
  backdrop-filter: none; -webkit-backdrop-filter: none; }
.pathCard b { color: #06333F; }
.pathCard .n, .pathCard .go { color: #0B4A5A; }
.pathFoot a { color: #06333F; }
}
/* Footer palung (beranda) di ponsel: sama dengan footer hijau — kotak, tanpa
   gambar dan efek, tautan dalam akordeon, sosial di atas hak cipta. */
@media (max-width: 620px) {
  footer.dv-abyss { border-radius: 0 !important; padding: 48px 5vw 26px !important; }
  footer.dv-abyss > div[aria-hidden="true"] { display: none !important; }   /* the art + the mist bands + the glow/bubble/snow layer */
  footer.dv-abyss .dv-wordmark-img { width: 176px; margin-left: auto; margin-right: auto; }   /* sama seperti footer hijau */
  footer.dv-abyss .dv-radio, footer.dv-abyss a.dv-surface-btn { width: 100%; box-sizing: border-box; justify-content: center; min-height: 44px; }
  footer.dv-abyss .ff-cols { display: block !important; width: 100%; border-top: 1px solid rgba(127, 214, 232, .22); }
  footer.dv-abyss .ff-col { display: block !important; border-bottom: 1px solid rgba(127, 214, 232, .22); }
  /* pointer-events:auto WAJIB: aturan desktop di atas mematikannya supaya judul
     kolom jadi teks mati saat akordeon selalu terbuka. Footer hutan sudah
     menghidupkannya lagi di ponsel; footer palung terlewat, jadi Collections,
     Company, dan Support tidak bisa diketuk sama sekali. */
  footer.dv-abyss details.ff-col > summary { list-style: none; pointer-events: auto; cursor: pointer; display: flex; align-items: center; justify-content: space-between; min-height: 52px; margin: 0; font-size: 16px; }
  footer.dv-abyss details.ff-col > summary::-webkit-details-marker { display: none; }
  footer.dv-abyss details.ff-col > summary::after { content: ''; width: 9px; height: 9px; margin: -5px 6px 0 0; border-right: 2px solid rgba(184, 241, 255, .72); border-bottom: 2px solid rgba(184, 241, 255, .72); transform: rotate(45deg); transition: transform .16s ease; }
  footer.dv-abyss details.ff-col[open] > summary::after { transform: rotate(225deg); margin-top: 4px; }
  footer.dv-abyss .ff-col__links { display: flex; flex-direction: column; padding: 0 0 10px; }
  footer.dv-abyss .foot-link { padding: 9px 0; }
  footer.dv-abyss .ff-col--yt { border: 0; padding-top: 18px; }
  footer.dv-abyss .ff-col--yt .dv-col-title { display: none; }
  footer.dv-abyss .ff-col--yt .yt-card { width: 100% !important; }
  /* Baris dasar: lima tautan sosial dan tombol naik jadi SATU keluarga — bentuk,
     ukuran, dan jarak yang sama, dalam satu baris; hak cipta turun ke barisnya
     sendiri. Sebelumnya tombol naik ikut aturan lebar-penuh di atas sehingga
     jadi batang mint selebar layar yang berteriak di footer segelap ini.
     Warnanya sekarang biru kaca palung; biolum tinggal jadi aksen tombol naik. */
  footer.dv-abyss .dv-foot-base { display: flex !important; flex-direction: column; align-items: stretch;
    gap: 16px; padding-top: 18px !important;
    padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px)) !important; }
  footer.dv-abyss .dv-foot-base > div { order: 1; display: flex !important; width: 100%; max-width: none;
    justify-content: flex-start; align-items: center; gap: 8px; }
  footer.dv-abyss .dv-foot-base > span { order: 2; text-align: center; color: rgba(185, 210, 228, .6); }
  footer.dv-abyss .foot-ico { display: block; width: 19px; height: 19px; }
  footer.dv-abyss .foot-lbl { position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap; }   /* disembunyikan secara visual, tetap jadi nama aksesibilitas */
  footer.dv-abyss .soc, footer.dv-abyss .dv-foot-base [data-scroll-top] {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 44px; height: 44px; min-height: 0; padding: 0 !important; border-radius: 50%; }
  footer.dv-abyss .soc { background: rgba(127, 214, 232, .08); border: 1px solid rgba(127, 214, 232, .24);
    color: #9FE3F0; }
  footer.dv-abyss .soc:active { background: rgba(127, 214, 232, .2); color: var(--dv-navy-ink);
    transform: none; }
  footer.dv-abyss .dv-foot-base [data-scroll-top] { margin-left: auto !important;
    background: rgba(89, 242, 206, .12) !important; border: 1px solid rgba(89, 242, 206, .38);
    color: var(--dv-biolum) !important; box-shadow: none !important; }
  footer.dv-abyss .dv-radio .dv-ico { color: var(--dv-biolum); }
}
/* iOS Safari zooms the page when a field under 16px takes focus. The site's
   floor is 14px, so on phones every text field, select and textarea is 16px
   regardless of what the page set inline — the one exception to the floor. */
@media (max-width: 640px) {
  input:not([type="checkbox"]):not([type="radio"]), select, textarea { font-size: 16px !important; }
}
