/* =========================================================
   JATIMSATUNEWS — MILESTONE 1
   Design tokens + Header/Nav/Hero/Pulse/Latest/Trending only.
   Breakpoints (fixed, reused from approved spec):
     Desktop >= 1025px | Tablet 768-1024px | Mobile <= 767px
========================================================= */

:root{
	/* color */
	--color-ink:        #14161C;
	--color-ink-soft:    #3A3D46;
	--color-muted:       #6B6E76;
	--color-faint:       #9C9C94;
	--color-red:         #C8102E;
	--color-red-deep:    #A50D25;
	--color-red-wash:    rgba(200,16,46,.05);
	--color-paper:       #FFFFFF;
	--color-canvas:      #FAFAF8;
	--color-rule:        #E4E2DC;
	--color-rule-strong: #14161C;

	/* T.3 -- dark masthead/footer surface + on-dark text scale. Near-black
	   rather than pure #000 so it reads as an ink, not a UI-chrome black;
	   --color-ink stays reserved for on-paper text elsewhere in the site. */
	--color-near-black:  #0D0D0D;
	--color-charcoal:    #1A1A1A;
	--color-on-dark:          #FFFFFF;
	--color-on-dark-muted:    rgba(255,255,255,.64);
	--color-on-dark-faint:    rgba(255,255,255,.40);
	--color-on-dark-rule:     rgba(255,255,255,.14);

	/* spacing */
	--space-1:4px; --space-2:8px; --space-3:12px; --space-4:16px;
	--space-5:24px; --space-6:32px; --space-7:48px; --space-8:64px; --space-9:96px;

	/* radius -- Phase B: reconciled toward the "Precision News & Data
	   System" reference (sharp, 0px, hard-news geometry) rather than a
	   full token swap. 2px was already close to imperceptible; this
	   just commits to the sharp-corner language the brief calls for
	   without touching color/type identity. */
	--radius-sm:0px;

	/* container */
	--container-max: 1280px;
	--container-pad: 32px;

	/* type */
	--font-headline: 'Source Serif 4', Georgia, serif;
	--font-sans-headline: -apple-system, BlinkMacSystemFont, 'Segoe UI', Inter, Arial, sans-serif;
	--font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
	--font-mono: 'IBM Plex Mono', ui-monospace, monospace;

	/* interaction -- one shared timing so hover/focus feels consistent
	   site-wide (nav, cards, buttons, chips) instead of each component
	   picking its own duration or relying on the browser default (instant). */
	--transition-fast: 180ms ease;
}

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

/* Keyboard focus parity for everything that gained a hover treatment
   this pass -- cards, tags, rail links, share buttons. Nav/search/menu
   focus states were already covered in T.0. */
.jsn-card-title a:focus-visible,
.jsn-tag:focus-visible,
.jsn-rail-list a:focus-visible,
.jsn-share-btn:focus-visible,
.jsn-chip:focus-visible{
	outline:2px solid var(--color-red);
	outline-offset:2px;
}

@media(max-width:1024px){
	:root{ --container-pad: 24px; }
}
@media(max-width:767px){
	:root{ --container-pad: 16px; }
}

/* =========================================================
   RESET / BASE
========================================================= */

*, *::before, *::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; }
body{
	margin:0;
	background:var(--color-canvas);
	color:var(--color-ink);
	font-family:var(--font-body);
	line-height:1.5;
	overflow-x:hidden;
}
img{ max-width:100%; display:block; }
a{ color:inherit; text-decoration:none; }
ul, ol{ list-style:none; margin:0; padding:0; }
h1,h2,h3,p{ margin:0; }

.jsn-container{
	max-width:var(--container-max);
	margin:0 auto;
	padding-left:var(--container-pad);
	padding-right:var(--container-pad);
}

/* Visually-hidden-but-accessible text (search form <label>s already used
   this class site-wide with no matching CSS -- they were rendering
   visibly on screen until this rule existed). Standard WP pattern. */
.screen-reader-text{
	position:absolute !important;
	width:1px; height:1px;
	padding:0; margin:-1px;
	overflow:hidden;
	clip:rect(0,0,0,0);
	white-space:nowrap;
	border:0;
}
.jsn-skip-link.screen-reader-text:focus{
	position:fixed !important;
	top:var(--space-3);
	left:var(--space-3);
	width:auto; height:auto;
	padding:var(--space-3) var(--space-5);
	margin:0;
	clip:auto;
	overflow:visible;
	background:var(--color-ink);
	color:var(--color-paper);
	font-family:var(--font-body);
	font-weight:700;
	font-size:14px;
	border-radius:var(--radius-sm);
	z-index:100;
}

.jsn-eyebrow{
	display:inline-block;
	font-family:var(--font-body);
	font-size:11px;
	font-weight:600;
	text-transform:uppercase;
	letter-spacing:.08em;
	color:var(--color-muted);
}
.jsn-eyebrow--red{ color:var(--color-red); }

.jsn-section-title{
	font-family:var(--font-body);
	font-size:13px;
	font-weight:700;
	text-transform:uppercase;
	letter-spacing:.06em;
	color:var(--color-ink);
	border-top:2px solid var(--color-rule-strong);
	padding-top:var(--space-3);
	margin-bottom:var(--space-5);
}

/* Utility visibility classes -- used by News Pulse mobile-reintroduction */
.jsn-mobile-only{ display:none; }
@media(max-width:1024px){
	.jsn-mobile-only{ display:list-item; }
}

/* =========================================================
   HEADER — utility row + brand row
========================================================= */

.jsn-masthead{
	background:var(--color-near-black);
	border-bottom:1px solid var(--color-on-dark-rule);
	/* Phase B: restrained red editorial mark -- reconciles the Stitch
	   "Accent Red reserved for high-priority/institutional signals"
	   language with the existing dark identity, without changing the
	   masthead's color/type system wholesale. */
	border-top:3px solid var(--color-red);
}

/* Phase B: utility row reframed as a lightweight "data strip" --
   truthful date only today (no fake weather/market figures -- see
   Phase A audit, no provider is configured). Built so a future
   real data widget can be appended as a sibling of .jsn-utility-date
   inside the same flex row without any layout restructuring. */
.jsn-utility{
	max-width:var(--container-max);
	margin:0 auto;
	padding:var(--space-2) var(--container-pad);
	display:flex;
	align-items:center;
	justify-content:flex-start;
	gap:var(--space-4);
	font-size:12px;
	border-bottom:1px solid var(--color-on-dark-rule);
}
.jsn-utility-date{
	font-family:var(--font-mono);
	font-size:12px;
	font-weight:500;
	color:var(--color-on-dark-muted);
	letter-spacing:.04em;
	text-transform:uppercase;
}

.jsn-checkbox-hack{
	position:absolute;
	opacity:0;
	width:1px;
	height:1px;
	pointer-events:none;
}

.jsn-search-toggle{ position:relative; display:flex; align-items:center; }
.jsn-search-icon{
	/* Phase B: 44x44 minimum touch target (was 28x28) -- icon glyph
	   itself stays visually 18x18 via the inline SVG's own width/height,
	   this just enlarges the tappable/clickable label around it. */
	display:flex;
	align-items:center;
	justify-content:center;
	width:44px;
	height:44px;
	cursor:pointer;
	color:var(--color-on-dark);
	transition:color var(--transition-fast);
}
.jsn-search-icon:hover{ color:var(--color-red); }
.jsn-search-form{
	position:absolute;
	right:0;
	top:100%;
	margin-top:var(--space-2);
	width:0;
	overflow:hidden;
	opacity:0;
	transition:width .2s ease, opacity .2s ease;
	background:var(--color-charcoal);
	border:1px solid var(--color-on-dark-rule);
	border-radius:var(--radius-sm);
	z-index:40;
}
.jsn-search-toggle .jsn-checkbox-hack:checked ~ .jsn-search-form{
	width:240px;
	opacity:1;
}
.jsn-search-form input[type=search]{
	width:100%;
	border:0;
	padding:var(--space-2) var(--space-3);
	font-family:var(--font-body);
	font-size:14px;
	background:transparent;
	color:var(--color-on-dark);
}
.jsn-search-form input[type=search]::placeholder{ color:var(--color-on-dark-faint); }
.jsn-search-form input[type=search]:focus-visible{ outline:2px solid var(--color-red); outline-offset:-2px; }

.jsn-brand{
	max-width:var(--container-max);
	margin:0 auto;
	padding:8px var(--container-pad);
	display:flex;
	align-items:center;
	justify-content:flex-start;
	gap:var(--space-4);
}
.jsn-logo{ flex:1; text-align:left; }
.jsn-logo img{ max-height:64px; width:auto; max-width:100%; margin:0; }
.jsn-wordmark{
	font-family:var(--font-headline);
	font-weight:700;
	font-size:26px;
	letter-spacing:-.01em;
	color:var(--color-on-dark);
}
@media(min-width:1025px){
	/* Phase B: a touch more vertical room at desktop only -- more
	   "masthead" authority without changing the compact mobile brand
	   row (already tuned separately below, left untouched). */
	.jsn-brand{ padding:16px var(--container-pad); }
}

.jsn-hamburger-toggle{ position:relative; flex:0 0 44px; }
.jsn-brand-spacer{ display:none; }
@media(min-width:768px){
	/* Hamburger/drawer is a mobile+tablet affordance; desktop uses the
	   persistent .jsn-nav bar below instead. */
	.jsn-hamburger-toggle{ display:none; }
}

@media(max-width:767px){
	/* Mobile P0 FIX: sticky must be applied to .jsn-masthead (the
	   parent, whose containing block is <body> -- ample room to stick)
	   NOT to .jsn-brand alone. .jsn-brand is the last child of
	   .jsn-masthead with nothing below it in that same parent, so a
	   sticky position on the child itself has zero "room" to remain
	   pinned before the parent's own bottom edge (which arrives at the
	   exact same scroll point) releases it -- that was the root cause
	   of the child not sticking. Fix: the whole header (utility+brand)
	   sticks as one unit; once scrolled, .jsn-masthead-scrolled
	   (toggled by nav.js, same scroll listener already driving the nav
	   shadow) collapses .jsn-utility to zero height, visually leaving
	   only the compact brand row pinned -- matching the target stack. */
	.jsn-masthead{
		position:sticky;
		top:0;
		z-index:35;
		transition:box-shadow .2s ease;
	}
	.jsn-masthead-scrolled .jsn-utility{
		display:none;
	}
	.jsn-masthead-scrolled{
		box-shadow:0 1px 0 var(--color-on-dark-rule), 0 4px 12px rgba(0,0,0,.35);
	}
	.jsn-brand{
		padding:8px var(--container-pad);
	}
	.jsn-logo img{ max-height:36px; }
	.jsn-wordmark{ font-size:20px; }
}

.jsn-hamburger-icon{
	/* Phase B: 44x44 minimum touch target (was 28x28); the three bars
	   stay the same visual width/weight, just centered in a larger
	   tappable label. */
	display:flex;
	flex-direction:column;
	justify-content:center;
	align-items:center;
	gap:5px;
	width:44px;
	height:44px;
	cursor:pointer;
}
.jsn-hamburger-icon span{
	display:block;
	width:22px;
	height:2px;
	background:var(--color-on-dark);
}

.jsn-drawer{
	position:fixed;
	top:0;
	left:0;
	bottom:0;
	height:100vh;
	height:100dvh; /* mobile-browser dynamic toolbar -- falls back to 100vh above on engines without dvh */
	width:280px;
	max-width:80vw;
	background:var(--color-paper);
	box-shadow:1px 0 0 var(--color-rule);
	transform:translateX(-100%);
	transition:transform .25s ease;
	z-index:50;
	overflow-y:auto;
	-webkit-overflow-scrolling:touch;
	/* Only THIS panel scrolls while open (see JS scroll-lock below);
	   overscroll-behavior:contain stops a drag that hits the top/bottom
	   of the drawer's own scroll range from chaining into the page
	   behind it once the lock releases mid-gesture on some browsers. */
	overscroll-behavior:contain;
	padding:var(--space-7) var(--space-5);
}
.jsn-hamburger-toggle .jsn-checkbox-hack:checked ~ .jsn-drawer{
	transform:translateX(0);
}

/* Backdrop: a <label for="jsn-drawer-check"> sibling of the drawer, so
   tapping it closes the drawer via the native checkbox toggle -- zero JS. */
.jsn-drawer-backdrop{
	position:fixed;
	inset:0;
	background:rgba(20,22,28,.4);
	opacity:0;
	pointer-events:none;
	transition:opacity .25s ease;
	z-index:49;
}
.jsn-hamburger-toggle .jsn-checkbox-hack:checked ~ .jsn-drawer-backdrop{
	opacity:1;
	pointer-events:auto;
}
/* Scroll-lock: PRIMARY mechanism is now JS (nav-v4.js, listens for the
   drawer checkbox's 'change' event) using the position:fixed-on-<body>
   technique with scrollY capture/restore -- the only method that is
   both (a) fully reliable on iOS Safari (overflow:hidden alone is not
   -- long-standing WebKit quirk, background still rubber-bands under a
   fixed overlay) and (b) doesn't visually snap the page to the top
   when the drawer opens (a plain `body{position:fixed}` with no `top`
   offset does that -- needs the actual scrollY, which only JS knows).
   This :has() rule stays as a CSS-only FALLBACK for the no-JS case
   (harmless degradation: basic scroll prevention, no jump-fix) --
   redundant with, and overridden by, the JS lock's inline styles
   whenever JS runs. */
html:has(#jsn-drawer-check:checked),
body:has(#jsn-drawer-check:checked){
	overflow:hidden;
	height:100%;
}
.jsn-drawer .jsn-nav-list{
	display:flex;
	flex-direction:column;
}
.jsn-drawer .jsn-nav-list > li{
	border-bottom:1px solid var(--color-rule);
}
.jsn-drawer .jsn-nav-list > li:last-child{
	border-bottom:none;
}
.jsn-drawer .jsn-nav-list a,
.jsn-drawer .jsn-nav-dropdown > details > summary{
	font-family:var(--font-body);
	font-weight:600;
	font-size:15px;
	text-transform:uppercase;
	letter-spacing:.02em;
	padding:var(--space-4) var(--space-1);
}
.jsn-drawer .jsn-nav-list > li > a{
	display:block;
}
/* Tap feedback -- no :hover on mobile (sticks after tap on touch
   devices); :active is the touch-safe equivalent. */
.jsn-drawer .jsn-nav-list a:active,
.jsn-drawer .jsn-nav-dropdown > details > summary:active{
	background:var(--color-canvas);
}
.jsn-drawer .jsn-nav-current > a,
.jsn-drawer .jsn-nav-current > details > summary{
	color:var(--color-red);
}

/* =========================================================
   NAVIGATION — sticky desktop/tablet bar
========================================================= */

.jsn-nav{
	background:var(--color-ink);
	border-bottom:1px solid var(--color-on-dark-rule);
	position:sticky;
	top:0;
	z-index:30;
	transition:box-shadow .2s ease, padding .15s ease;
}
.jsn-nav.jsn-nav-scrolled{
	box-shadow:0 1px 0 var(--color-on-dark-rule), 0 4px 10px rgba(0,0,0,.35);
}
@media(max-width:767px){
	/* Mobile P0: category nav becomes an immediately-visible horizontal
	   strip (reuses the same overflow-x:auto rule already proven on
	   tablet -- .jsn-nav-list below) instead of being hidden behind the
	   hamburger. It sticks directly under the sticky brand row (see
	   .jsn-brand mobile rule further down) so both stay visible as one
	   compact unit while the utility/date row scrolls away normally
	   above them. The hamburger drawer (brand.php) is left untouched
	   as a secondary/full-menu access point -- nothing existing removed. */
	.jsn-nav{
		display:block;
		position:sticky;
		top:52px;
		z-index:34;
	}
}

.jsn-nav .jsn-nav-list{
	/* Phase B fix: overflow-x:auto was previously unconditional here,
	   which per the CSS spec forces the browser to also compute
	   overflow-y as auto (you cannot mix visible/non-visible per-axis)
	   -- that silently clipped every absolutely-positioned dropdown
	   panel (Daerah mega-menu, Lainnya) to this bar's own height on
	   ALL viewport widths, including desktop, where no scrolling was
	   ever needed (11 items already fit). Scoped below to only the
	   breakpoint that actually needs horizontal scroll (tablet/mobile,
	   where the nav becomes a compact strip) -- desktop now keeps
	   overflow:visible (the default) so dropdowns render normally. */
	max-width:var(--container-max);
	margin:0 auto;
	padding:0 var(--container-pad);
	display:flex;
	align-items:center;
	gap:var(--space-5);
	min-width:0;
}
.jsn-nav .jsn-nav-list::-webkit-scrollbar{ display:none; }
.jsn-nav .jsn-nav-list li{ flex:0 0 auto; }
@media(max-width:1024px){
	/* Horizontal scroll only where it's actually needed -- see the fix
	   note on the base .jsn-nav-list rule above. */
	.jsn-nav .jsn-nav-list{
		overflow-x:auto;
		scrollbar-width:none;
	}
}

.jsn-nav .jsn-nav-list a,
.jsn-nav .jsn-nav-dropdown summary{
	display:block;
	padding:var(--space-3) 0;
	font-family:var(--font-body);
	font-size:13px;
	font-weight:600;
	text-transform:uppercase;
	letter-spacing:.03em;
	color:var(--color-on-dark);
	white-space:nowrap;
	border-bottom:2px solid transparent;
	transition:color .18s ease, border-color .18s ease;
	cursor:pointer;
	list-style:none;
}
.jsn-nav .jsn-nav-list a:hover,
.jsn-nav .jsn-nav-dropdown summary:hover{
	color:var(--color-red);
	border-bottom-color:var(--color-red);
}
.jsn-nav .jsn-nav-list a:focus-visible,
.jsn-nav .jsn-nav-dropdown summary:focus-visible{
	outline:2px solid var(--color-red);
	outline-offset:2px;
}
.jsn-nav .jsn-nav-dropdown summary::-webkit-details-marker{ display:none; }
.jsn-nav .jsn-nav-dropdown{ position:relative; }
.jsn-nav .jsn-nav-dropdown-list{
	position:absolute;
	top:100%;
	left:0;
	background:var(--color-charcoal);
	border:1px solid var(--color-on-dark-rule);
	min-width:160px;
	padding:var(--space-2) 0;
	z-index:31;
}
.jsn-nav .jsn-nav-dropdown-list a{ padding:var(--space-2) var(--space-4); }

/* current section indicator (native menu only; fallback has none) */
.jsn-nav .jsn-nav-current > a,
.jsn-nav .jsn-nav-current > details > summary{
	color:var(--color-red);
	border-bottom-color:var(--color-red);
}

/* ---- Daerah mega-menu: many real regional categories, needs a wide
   multi-column panel instead of the narrow single-column dropdown used
   by small menus like "Lainnya". Nested Malang Raya/Pasuruan Raya
   <details> render as static indented blocks inside their column
   (not a second flyout) to keep this CSS-only, no extra JS. ---- */
.jsn-nav .jsn-nav-mega > details > .jsn-nav-dropdown-list{
	min-width: 640px;
	max-width: 780px;
	columns: 3;
	column-gap: var(--space-6);
	padding:var(--space-4);
}
@media(max-width:1024px){
	.jsn-nav .jsn-nav-mega > details > .jsn-nav-dropdown-list{ min-width:520px; columns:2; }
}
.jsn-nav .jsn-nav-mega > details > .jsn-nav-dropdown-list > li{
	break-inside: avoid;
}
.jsn-nav .jsn-nav-mega .jsn-nav-dropdown-list a{
	padding: 6px var(--space-2);
	font-weight: 500;
	text-transform: none;
	letter-spacing: normal;
	font-size: 13.5px;
	color: var(--color-on-dark-muted);
}
.jsn-nav .jsn-nav-mega .jsn-nav-dropdown-list a:hover{ color:var(--color-red); }
/* nested Malang Raya / Pasuruan Raya group inside the mega panel */
.jsn-nav-dropdown--sub{ margin-top:2px; }
.jsn-nav-dropdown--sub > summary{
	padding: 6px var(--space-2);
	font-weight: 700;
	font-size: 13.5px;
	color: var(--color-on-dark);
	cursor: pointer;
}
.jsn-nav-dropdown--sub > summary::-webkit-details-marker{ display:none; }
.jsn-nav-dropdown--sub > summary::after{
	content: '›';
	float: right;
	color: var(--color-on-dark-faint);
}
.jsn-nav-dropdown--sub[open] > summary::after{ content: '⌄'; }
.jsn-nav-dropdown-list--nested{
	position: static;
	border: none;
	padding: 0 0 0 var(--space-4);
	min-width: 0;
}
.jsn-nav-dropdown-list--nested a{
	font-weight: 400;
	color: var(--color-on-dark-muted);
}

/* ---- #jsn-nav category bar (under the logo, shown on desktop AND as a
   horizontal-scroll strip on mobile) -- floating dropdown fix.
   Root cause: .jsn-nav-list gets overflow-x:auto at <=1024px (rule
   above, for the horizontal scroll strip); per the CSS spec, an
   element can't mix overflow-x:auto with overflow-y:visible -- the
   y-axis gets silently forced to auto too. The dropdown's containing
   block was the <li> (position:relative, further up in this file),
   which sits inside that now-clipped scroll container, so the ~580px
   Daerah panel was being cut down to the bar's own ~45px height.
   Fix: at <=767px, drop position:relative from the <li> so the
   dropdown's position:absolute resolves against #jsn-nav itself
   instead (already a valid containing block via position:sticky) --
   .jsn-nav has no overflow set, so nothing clips it there. This only
   targets .jsn-nav; .jsn-drawer (hamburger) is completely untouched. */
@media(max-width:767px){
	.jsn-nav .jsn-nav-dropdown{
		position:static;
	}
	.jsn-nav .jsn-nav-dropdown-list,
	.jsn-nav .jsn-nav-mega > details > .jsn-nav-dropdown-list{
		position:absolute;
		top:100%;
		left:0;
		width:100%;
		min-width:0;
		max-width:none;
		columns:1;
		z-index:9999;
	}
}

/* ---- Mobile drawer: nested details get a left rule + indent so the
   Daerah -> Malang Raya -> Kota Malang hierarchy stays legible in the
   narrow off-canvas panel.

   Accordion fix: the native <details>/<summary> click-to-toggle is
   broken in WebKit/Safari when `display:flex` is set directly on the
   <summary> (a known engine bug -- the browser's built-in disclosure
   click handler stops firing once `display` is overridden away from
   its default `list-item`). That's exactly what this row layout needs
   (icon pinned right via justify-content:space-between), so instead of
   giving up the layout, assets/js/nav.js now drives the open/close
   itself (click/touchend, preventDefault on the native toggle, sets
   details.open programmatically) -- see the requirement that mobile
   must not depend on :hover/native-only behavior anyway. The [open]
   attribute is still what the +/- icon and max-height animation below
   key off of; JS just becomes the only thing that flips it. ---- */
.jsn-drawer .jsn-nav-dropdown > details > summary{
	display:flex;
	align-items:center;
	justify-content:space-between;
	cursor:pointer;
}
.jsn-drawer .jsn-nav-dropdown > details > summary::-webkit-details-marker{ display:none; }
.jsn-drawer .jsn-nav-dropdown > details > summary::after{
	content:'+';
	color:var(--color-faint);
	font-weight:400;
	font-size:18px;
	line-height:1;
}
.jsn-drawer .jsn-nav-dropdown > details[open] > summary::after{ content:'\2212'; }
.jsn-drawer .jsn-nav-dropdown-list{
	margin-top:0;
	padding-left:var(--space-4);
	border-left:2px solid var(--color-rule);
	display:flex;
	flex-direction:column;
	gap:var(--space-3);
	overflow:hidden;
	max-height:0;
	transition:max-height .25s ease;
}
.jsn-drawer .jsn-nav-dropdown > details[open] > .jsn-nav-dropdown-list{
	margin-top:var(--space-2);
}
.jsn-drawer .jsn-nav-dropdown-list a{
	font-size:13px;
	font-weight:500;
	text-transform:none;
}

/* Daerah's own top-level list: NO max-height/overflow animation at
   all -- this is the fix for nested-accordion clipping. Root cause
   (2nd round): even switching this list's max-height to `none` once
   ITS open transition finished (previous attempt) still depended on
   a JS transitionend callback firing at the right moment; any timing
   miss (slow device, reduced-motion, backgrounded tab, etc.) left a
   stale pixel ceiling in place that clipped Malang Raya / Pasuruan
   Raya's nested panel when IT opened afterward. Removing the
   max-height mechanism from this level ENTIRELY removes the ceiling
   by construction -- there is no frozen value that can ever go stale,
   because none is ever set. Show/hide instead uses the native
   details[open] mechanism only (display:none <-> the grid below);
   nav-v4.js still drives `details.open` itself (Safari's native
   click-to-toggle is broken here, see the summary comment above), it
   just no longer touches this element's height/max-height/overflow.
   The nested Malang Raya / Pasuruan Raya lists are UNCHANGED (still
   use the max-height slide animation above) -- they're leaf-level
   (nothing nested further inside them), so that mechanism was never
   the source of clipping and stays for its animation.

   `.jsn-nav-mega` is unique to the Daerah menu item (verified -- no
   other top-level item carries it), and the `>` child combinator
   excludes the nested lists (several levels deeper, not a direct
   child of Daerah's own <details>) -- so all of this only affects
   Daerah's own flat kabupaten list. Mobile only -- desktop's
   mega-menu panel (.jsn-nav .jsn-nav-mega, its own 3-column layout
   further up this file) is a completely different selector/subtree,
   untouched. */
.jsn-drawer .jsn-nav-mega > details > .jsn-nav-dropdown-list{
	display:none;
	max-height:none;
	overflow:visible;
	transition:none;
}
@media(max-width:767px){
	.jsn-drawer .jsn-nav-mega > details[open] > .jsn-nav-dropdown-list{
		display:grid;
		grid-template-columns:repeat(2, 1fr);
		column-gap:var(--space-4);
		row-gap:var(--space-3);
	}
}

.jsn-drawer .jsn-nav-dropdown--sub > summary{
	font-size:13px;
	font-weight:700;
	text-transform:none;
	padding:2px 0;
}

/* =========================================================
   BREAKING STRIP -- Phase B. Renders ONLY when a real published
   post exists in the "Headline" category (existing category,
   term_id 13 -- not a new taxonomy). See inc/template-helpers.php
   jsn_get_breaking_post(). Zero markup output when empty, so there
   is never an empty red bar and never a placeholder headline.
========================================================= */
.jsn-breaking{
	background:var(--color-red);
	border-bottom:1px solid var(--color-red-deep);
}
.jsn-breaking-inner{
	max-width:var(--container-max);
	margin:0 auto;
	padding:var(--space-2) var(--container-pad);
	display:flex;
	align-items:center;
	gap:var(--space-3);
}
.jsn-breaking-label{
	flex:0 0 auto;
	font-family:var(--font-body);
	font-weight:700;
	font-size:11px;
	letter-spacing:.08em;
	text-transform:uppercase;
	color:var(--color-red);
	background:var(--color-on-dark);
	padding:3px var(--space-2);
}
.jsn-breaking-link{
	flex:1;
	min-width:0;
	font-family:var(--font-body);
	font-weight:700;
	font-size:14px;
	color:var(--color-on-dark);
	white-space:nowrap;
	overflow:hidden;
	text-overflow:ellipsis;
}
.jsn-breaking-link:hover,
.jsn-breaking-link:focus-visible{ text-decoration:underline; }
.jsn-breaking-link:focus-visible{ outline:2px solid var(--color-on-dark); outline-offset:2px; }
@media(max-width:767px){
	.jsn-breaking-label{ font-size:10px; }
	.jsn-breaking-link{ font-size:13px; }
}

/* =========================================================
   FOOTER NAV (list used inside .jsn-footer-col -- see FOOTER block)
========================================================= */
.jsn-footer-nav-list{
	display:flex;
	flex-direction:column;
	gap:10px;
}
.jsn-footer-nav-list a{
	position:relative;
	display:inline-flex;
	align-items:center;
	font-family:var(--font-body);
	font-size:13.5px;
	font-weight:500;
	color:var(--color-on-dark-muted);
	transition:color var(--transition-fast), transform var(--transition-fast);
}
.jsn-footer-nav-list a::before{
	content:'';
	position:absolute;
	left:-10px;
	width:3px;
	height:12px;
	background:var(--color-red);
	opacity:0;
	transition:opacity var(--transition-fast);
}
.jsn-footer-nav-list a:hover{
	color:var(--color-on-dark);
	transform:translateX(2px);
}
.jsn-footer-nav-list a:hover::before{ opacity:1; }
.jsn-footer-nav-list a:focus-visible{ outline:2px solid var(--color-red); outline-offset:2px; }
@media(prefers-reduced-motion: reduce){
	.jsn-footer-nav-list a:hover{ transform:none; }
}

/* =========================================================
   HOME HERO — 3-column editorial grid (Desktop Hero Rebuild step)
   Namespaced under .jsn-home-hero-* so this component's CSS cannot
   collide with any other selector in the theme. minmax architecture
   dipertahankan (fix overflow min-width:auto dari kasus Blogger dulu)
   -- hanya rasio kolom tengah diperbesar supaya featured image jadi
   pusat perhatian.

   Hero Redesign Phase 1: CENTER > LEFT > RIGHT hierarchy encoded two
   ways -- (1) column share LEFT .95fr vs RIGHT .75fr, CENTER stays the
   largest single share at 1.7fr; (2) RIGHT card image/title are sized
   down from LEFT's via dedicated rules further below, since LEFT now
   holds 2 large cards and RIGHT holds 2 medium cards + 2 small briefs.
   max-width is now dedicated to this component (was var(--container-max),
   the SAME token used by header/pulse/latest-grid) so widening the hero
   container can never shift anything outside it -- see the 1440px
   breakpoint below for the desktop-only bump requested in review.
========================================================= */

.jsn-home-hero{
	display:grid;
	grid-template-columns: minmax(230px,.95fr) minmax(0,1.7fr) minmax(210px,.75fr);
	gap:0;
	align-items:start;
	max-width:1200px;
	margin:var(--space-6) auto 0 auto;
	padding:0 var(--container-pad);
}
@media(min-width:1440px){
	.jsn-home-hero{ max-width:1440px; }
}
.jsn-home-hero > div{ min-width:0; } /* overflow fix -- jangan dihapus */

.jsn-home-hero-main{
	border-left:1px solid var(--color-rule);
	border-right:1px solid var(--color-rule);
	padding:0 var(--space-5);
}
.jsn-home-hero-left{ padding-right:var(--space-5); }
.jsn-home-hero-right{ padding-left:var(--space-5); }

/* LEFT now holds 2 repeated .jsn-home-hero-left-feature cards, RIGHT
   holds 2 repeated .jsn-home-hero-right-feature cards -- space the
   2nd card from the 1st the same way the old related/briefs lists did. */
.jsn-home-hero-left .jsn-home-hero-left-feature + .jsn-home-hero-left-feature,
.jsn-home-hero-right .jsn-home-hero-right-feature + .jsn-home-hero-right-feature{
	margin-top:var(--space-5);
	padding-top:var(--space-5);
	border-top:1px solid var(--color-rule);
}

.jsn-home-hero-main-image-link{ display:block; }
.jsn-home-hero-main-image{
	width:100%;
	height:auto; /* Desktop Hero Rebuild fix: without this, the img's
	                own HTML height attribute (from get_the_post_thumbnail,
	                which for most already-migrated attachments falls
	                back to the original upload's arbitrary native size)
	                wins over aspect-ratio, since aspect-ratio only fills
	                in a dimension left as auto. Confirmed live before
	                this fix: rendered as a squashed ~578x213 (ratio 2.71)
	                instead of true 16:9. */
	aspect-ratio:16/9;
	object-fit:cover;
	border-radius:var(--radius-sm);
	border:1px solid var(--color-rule);
}
.jsn-home-hero-main-image--empty{
	background:var(--color-canvas);
	display:block;
}
.jsn-home-hero-main-body{
	padding-top:var(--space-3);
	margin-top:var(--space-3);
	border-top:3px solid var(--color-red);
	min-width:0;
}

.jsn-home-hero-main-eyebrow{
	font-size:12px;
	font-weight:700;
}

.jsn-home-hero-headline{
	margin:var(--space-2) 0 var(--space-3) 0;
	font-weight:700;
	line-height:1.15;
	color:var(--color-ink);
	overflow-wrap:break-word;
}
.jsn-home-hero-headline--serif{
	font-family:var(--font-headline);
	font-size:clamp(26px, 18px + 2vw, 38px);
}
.jsn-home-hero-headline--sans{
	font-family:var(--font-sans-headline);
	font-size:clamp(24px, 16px + 2vw, 34px);
	letter-spacing:-.01em;
}
.jsn-home-hero-headline a:hover{ color:var(--color-red); }

.jsn-home-hero-dek{
	font-size:15.5px;
	line-height:1.6;
	color:var(--color-ink-soft);
	margin-bottom:var(--space-3);
}
.jsn-home-hero-byline{
	display:flex;
	gap:var(--space-3);
	font-family:var(--font-mono);
	font-size:12px;
	color:var(--color-faint);
}

.jsn-home-hero-left-feature-image,
.jsn-home-hero-right-feature-image{
	width:100%;
	height:auto; /* same attribute-vs-aspect-ratio fix as the main image above */
	object-fit:cover;
	border-radius:var(--radius-sm);
	margin-bottom:var(--space-2);
}
.jsn-home-hero-left-feature-image{ aspect-ratio:4/3; }
/* RIGHT deliberately smaller than LEFT -- CENTER > LEFT > RIGHT */
.jsn-home-hero-right-feature-image{ aspect-ratio:16/11; }

.jsn-home-hero-left-feature-title,
.jsn-home-hero-right-feature-title{
	font-family:var(--font-body);
	font-weight:700;
	line-height:1.3;
	color:var(--color-ink);
	margin-top:var(--space-2);
	display:-webkit-box;
	-webkit-box-orient:vertical;
	-webkit-line-clamp:3;
	overflow:hidden;
}
.jsn-home-hero-left-feature-title{ font-size:19px; }
.jsn-home-hero-right-feature-title{ font-size:15.5px; -webkit-line-clamp:2; }
.jsn-home-hero-left-feature:hover .jsn-home-hero-left-feature-title,
.jsn-home-hero-right-feature:hover .jsn-home-hero-right-feature-title{ color:var(--color-red); }

.jsn-home-hero-left-related{
	margin-top:var(--space-4);
	border-top:1px solid var(--color-rule);
}
.jsn-home-hero-left-related li{ border-bottom:1px solid var(--color-rule); }
.jsn-home-hero-left-related li:last-child{ border-bottom:none; }
.jsn-home-hero-related-link{
	display:flex;
	align-items:center;
	gap:var(--space-3);
	padding:var(--space-3) 0;
	min-width:0;
}
.jsn-home-hero-related-thumb{
	width:56px;
	height:56px;
	flex:0 0 56px;
	object-fit:cover;
	border-radius:var(--radius-sm);
}
.jsn-home-hero-related-title{
	font-size:14px;
	font-weight:600;
	line-height:1.4;
	color:var(--color-ink);
	min-width:0;
	display:-webkit-box;
	-webkit-box-orient:vertical;
	-webkit-line-clamp:2;
	overflow:hidden;
}
.jsn-home-hero-related-link:hover .jsn-home-hero-related-title{ color:var(--color-red); }

.jsn-home-hero-right-briefs{
	margin-top:var(--space-4);
	border-top:1px solid var(--color-rule);
}
.jsn-home-hero-right-briefs li{ border-bottom:1px solid var(--color-rule); }
.jsn-home-hero-right-briefs li:last-child{ border-bottom:none; }
.jsn-home-hero-brief-link{
	display:flex;
	align-items:center;
	gap:var(--space-3);
	padding:var(--space-3) 0;
	min-width:0;
}
.jsn-home-hero-brief-thumb{
	width:72px;
	height:52px;
	flex:0 0 72px;
	object-fit:cover;
	border-radius:var(--radius-sm);
}
.jsn-home-hero-brief-body{ min-width:0; }
.jsn-home-hero-brief-body time{
	display:block;
	font-family:var(--font-mono);
	font-size:11px;
	color:var(--color-faint);
	margin-bottom:2px;
}
.jsn-home-hero-brief-title{
	font-size:13.5px;
	font-weight:600;
	line-height:1.4;
	color:var(--color-ink);
	display:-webkit-box;
	-webkit-box-orient:vertical;
	-webkit-line-clamp:2;
	overflow:hidden;
}
.jsn-home-hero-brief-link:hover .jsn-home-hero-brief-title{ color:var(--color-red); }

/* Tablet: regrid to 2 columns, main spans full width on top.
   Unchanged behavior from Phase B -- selectors renamed only so they
   keep matching the renamed markup in template-parts/hero.php. */
@media(max-width:1024px) and (min-width:768px){
	.jsn-home-hero{
		grid-template-columns: minmax(0,1fr) minmax(0,1fr);
		grid-template-areas: "main main" "left right";
		gap:var(--space-6);
	}
	.jsn-home-hero-main{ grid-area:main; border-left:none; border-right:none; padding:0; }
	.jsn-home-hero-left{ grid-area:left; padding-right:0; }
	.jsn-home-hero-right{ grid-area:right; padding-left:0; }
}

/* Mobile hero -- Mobile Hero Rebuild step. Main headline stays the
   single dominant story; Left/Right (desktop columns) stay hidden;
   .jsn-home-hero-support renders instead as a proper 2-column grid of
   4 cards (see the $mobile_support selection in hero.php -- reuses
   already-fetched hero data, no new query). Desktop/tablet never see
   this block (display:none by default, only switched on below). */
.jsn-home-hero-support{ display:none; }

@media(max-width:767px){
	.jsn-home-hero{ display:block; padding:0 var(--container-pad); margin-top:var(--space-4); overflow-x:hidden; }
	.jsn-home-hero-left, .jsn-home-hero-right{ display:none; }
	.jsn-home-hero-main{ border:none; padding:0; }
	.jsn-home-hero-main-body{ border-top-width:2px; }

	.jsn-home-hero-support{ display:block; margin-top:var(--space-5); }
	.jsn-home-hero-support-grid{
		display:grid;
		grid-template-columns:repeat(2,minmax(0,1fr));
		gap:12px;
	}
	.jsn-home-hero-support-card{ display:block; min-width:0; }
	.jsn-home-hero-support-card-image{
		width:100%;
		height:auto; /* same attribute-vs-aspect-ratio fix proven in the Desktop Hero step */
		aspect-ratio:16/9;
		object-fit:cover;
		display:block;
		border-radius:var(--radius-sm);
		border:1px solid var(--color-rule);
		margin-bottom:var(--space-2);
	}
	.jsn-home-hero-support-card-image--empty{ background:var(--color-canvas); }
	.jsn-home-hero-support-card .jsn-eyebrow{ font-size:10px; }
	.jsn-home-hero-support-card-title{
		display:-webkit-box;
		-webkit-box-orient:vertical;
		-webkit-line-clamp:3;
		overflow:hidden;
		margin-top:4px;
		font-family:var(--font-body);
		font-size:14px;
		font-weight:700;
		line-height:1.35;
		color:var(--color-ink);
	}
	.jsn-home-hero-support-card:hover .jsn-home-hero-support-card-title{ color:var(--color-red); }
}

/* =========================================================
   NEWS PULSE — thin horizontal strip, target ~40-44px desktop
========================================================= */

.jsn-pulse{
	max-width:var(--container-max);
	margin:var(--space-6) auto 0 auto;
	padding:var(--space-2) var(--container-pad);
	background:var(--color-red-wash);
	border-top:1px solid var(--color-rule);
	border-bottom:1px solid var(--color-rule);
	display:flex;
	align-items:center;
	gap:var(--space-4);
	overflow-x:auto;
	scrollbar-width:none;
}
.jsn-pulse::-webkit-scrollbar{ display:none; }

.jsn-pulse-label{
	flex:0 0 auto;
	font-family:var(--font-mono);
	font-size:11px;
	font-weight:700;
	text-transform:uppercase;
	letter-spacing:.08em;
	color:var(--color-red);
}
.jsn-pulse-list{
	display:flex;
	align-items:center;
	gap:var(--space-5);
	flex:1;
	min-width:0;
}
.jsn-pulse-item{ flex:0 0 auto; }
.jsn-pulse-item a{
	display:flex;
	align-items:baseline;
	gap:var(--space-2);
	white-space:nowrap;
}
.jsn-pulse-item time{
	font-family:var(--font-mono);
	font-size:12px;
	color:var(--color-faint);
}
.jsn-pulse-title{
	font-size:13.5px;
	font-weight:600;
	color:var(--color-ink);
}
.jsn-pulse-item a:hover .jsn-pulse-title{ color:var(--color-red); }

@media(max-width:767px){
	.jsn-pulse-item a{ white-space:normal; }
	.jsn-pulse-title{
		display:-webkit-box;
		-webkit-box-orient:vertical;
		-webkit-line-clamp:1;
		overflow:hidden;
		max-width:60vw;
	}
}

/* =========================================================
   HOME ECONOMY — Step 3. Fully namespaced under .jsn-home-economy-*.
   Reuses the existing .jsn-container width/padding tokens (no new
   container invented) and the site's existing red-accent/section-
   spacing conventions.
========================================================= */

.jsn-home-economy{
	max-width:var(--container-max);
	margin:var(--space-8) auto 0 auto;
	padding:0 var(--container-pad);
}

.jsn-home-economy-header{
	display:flex;
	align-items:baseline;
	justify-content:space-between;
	gap:var(--space-4);
	border-top:3px solid var(--color-red);
	padding-top:var(--space-3);
	margin-bottom:var(--space-5);
}
.jsn-home-economy-title{
	font-family:var(--font-body);
	font-size:20px;
	font-weight:800;
	text-transform:uppercase;
	letter-spacing:.02em;
	color:var(--color-ink);
}
.jsn-home-economy-link{
	flex:0 0 auto;
	font-family:var(--font-body);
	font-size:12.5px;
	font-weight:600;
	color:var(--color-muted);
	white-space:nowrap;
}
.jsn-home-economy-link:hover{ color:var(--color-red); }

.jsn-home-economy-grid{
	display:grid;
	grid-template-columns: 1.3fr 1fr;
	gap:var(--space-6);
	align-items:stretch;
}

.jsn-home-economy-card{ display:flex; flex-direction:column; min-width:0; height:100%; }
.jsn-home-economy-card-image{
	width:100%;
	height:auto; /* proven Step 1/2 fix -- without this the img's own HTML
	                height attribute wins over aspect-ratio */
	aspect-ratio:16/9;
	object-fit:cover;
	display:block;
	border-radius:var(--radius-sm);
	border:1px solid var(--color-rule);
	transition:transform var(--transition-fast);
}
.jsn-home-economy-card:hover .jsn-home-economy-card-image{ transform:scale(1.02); }
.jsn-home-economy-card-image--empty{ background:var(--color-canvas); }

.jsn-home-economy-card-content{ padding-top:var(--space-3); flex:1; min-width:0; }
.jsn-home-economy-category{
	display:inline-block;
	font-family:var(--font-body);
	font-size:11px;
	font-weight:700;
	text-transform:uppercase;
	letter-spacing:.06em;
	color:var(--color-red);
}
.jsn-home-economy-headline{
	margin-top:4px;
	font-family:var(--font-body);
	font-weight:700;
	line-height:1.35;
	color:var(--color-ink);
	display:-webkit-box;
	-webkit-box-orient:vertical;
	overflow:hidden;
}
.jsn-home-economy-card:hover .jsn-home-economy-headline{ color:var(--color-red); }
.jsn-home-economy-meta{
	display:block;
	margin-top:var(--space-2);
	font-family:var(--font-mono);
	font-size:11px;
	color:var(--color-faint);
}

/* Main (dominant) card */
.jsn-home-economy-card--main .jsn-home-economy-headline{ font-size:22px; -webkit-line-clamp:3; }

/* Side (4 supporting cards) */
.jsn-home-economy-side{
	display:grid;
	grid-template-columns:repeat(2,minmax(0,1fr));
	grid-template-rows:repeat(2,1fr);
	gap:var(--space-4);
}
.jsn-home-economy-side .jsn-home-economy-headline{ font-size:14px; -webkit-line-clamp:3; }
.jsn-home-economy-side .jsn-home-economy-card-content{ padding-top:var(--space-2); }

@media(max-width:1024px){
	.jsn-home-economy-grid{ grid-template-columns:1fr; }
	.jsn-home-economy-card--main .jsn-home-economy-headline{ font-size:20px; }
	.jsn-home-economy-side{ grid-template-rows:auto; }
}

@media(max-width:767px){
	.jsn-home-economy{ padding:0 var(--container-pad); margin-top:var(--space-6); }
	.jsn-home-economy-title{ font-size:17px; }
	.jsn-home-economy-card--main .jsn-home-economy-headline{ font-size:18px; -webkit-line-clamp:3; }
	.jsn-home-economy-side{
		grid-template-columns:repeat(2,minmax(0,1fr));
		grid-template-rows:auto;
		gap:12px;
	}
	.jsn-home-economy-side .jsn-home-economy-headline{ font-size:13px; -webkit-line-clamp:3; }
}

/* =========================================================
   HOME GRID — Latest News (66%) + Trending/Most Read (34%)
========================================================= */

.jsn-home-grid{
	max-width:var(--container-max);
	margin:var(--space-8) auto 0 auto;
	padding:0 var(--container-pad) var(--space-8) var(--container-pad);
}

@media(min-width:1025px){
	.jsn-home-grid{
		display:grid;
		grid-template-columns: minmax(0,1.94fr) minmax(0,1fr);
		column-gap:var(--space-7);
		align-items:start;
	}
}

/* Latest News */
.jsn-latest-list{ display:flex; flex-direction:column; }
.jsn-latest-item{
	display:flex;
	gap:var(--space-4);
	padding:var(--space-5) 0;
	min-width:0;
}
.jsn-latest-item + .jsn-latest-item{ border-top:1px solid var(--color-rule); }

.jsn-latest-thumb{
	width:120px;
	height:80px;
	object-fit:cover;
	border-radius:var(--radius-sm);
	flex:0 0 120px;
}
.jsn-latest-body{ flex:1; min-width:0; }
.jsn-latest-meta{
	display:flex;
	align-items:center;
	gap:var(--space-2);
	margin-bottom:var(--space-1);
}
.jsn-latest-meta time{
	font-family:var(--font-mono);
	font-size:11px;
	color:var(--color-faint);
}
.jsn-latest-title{
	font-size:17px;
	font-weight:600;
	line-height:1.4;
	color:var(--color-ink);
	display:-webkit-box;
	-webkit-box-orient:vertical;
	-webkit-line-clamp:2;
	overflow:hidden;
}
.jsn-latest-title a:hover{ color:var(--color-red); }
.jsn-latest-excerpt{
	margin-top:var(--space-1);
	font-size:14px;
	line-height:1.55;
	color:var(--color-muted);
	display:-webkit-box;
	-webkit-box-orient:vertical;
	-webkit-line-clamp:2;
	overflow:hidden;
}

@media(max-width:767px){
	.jsn-latest-excerpt{ display:none; }
	.jsn-latest-thumb{ width:96px; height:72px; flex-basis:96px; }
	.jsn-latest-item{ padding:var(--space-4) 0; }
}

/* Trending / Most Read -- rank number IS the visual anchor, no thumb */
.jsn-trending{ margin-top:var(--space-8); }
@media(min-width:1025px){ .jsn-trending{ margin-top:0; } }

.jsn-trending-list{ counter-reset:jsn-rank; }
.jsn-trending-item{ counter-increment:jsn-rank; }
.jsn-trending-item + .jsn-trending-item{ border-top:1px solid var(--color-rule); }
.jsn-trending-item a{
	display:flex;
	align-items:baseline;
	gap:var(--space-3);
	padding:var(--space-4) 0;
	min-width:0;
}
.jsn-trending-rank::before{
	content:counter(jsn-rank, decimal-leading-zero);
	font-family:var(--font-mono);
	font-size:26px;
	font-weight:700;
	color:var(--color-red);
	flex:0 0 auto;
}
.jsn-trending-title{
	font-size:15px;
	font-weight:600;
	line-height:1.35;
	color:var(--color-ink);
	min-width:0;
	display:-webkit-box;
	-webkit-box-orient:vertical;
	-webkit-line-clamp:2;
	overflow:hidden;
	transition:color var(--transition-fast);
}
.jsn-trending-item a:focus-visible{ outline:2px solid var(--color-red); outline-offset:2px; }
.jsn-trending-item a:hover .jsn-trending-title{ color:var(--color-red); }

/* =========================================================
   TOPIK PILIHAN — Homepage Phase 2. Replaces the sitewide Most Read
   sidebar (.jsn-trending* above is now dead/unreferenced -- left in
   place rather than deleted, minimal-diff precedent from Hero Phase 1).
   Category-scoped chips + a Most Read panel that swaps via AJAX.
========================================================= */
.jsn-topics{
	max-width:var(--container-max);
	margin:var(--space-8) auto 0 auto;
	padding:0 var(--container-pad) var(--space-8) var(--container-pad);
	display:block;
}

.jsn-topics-chips{
	display:flex;
	gap:var(--space-2);
	overflow-x:auto;
	-webkit-overflow-scrolling:touch;
	scrollbar-width:none;
	padding-bottom:var(--space-2);
	margin-bottom:var(--space-5);
	cursor:grab;
}
.jsn-topics-chips::-webkit-scrollbar{ display:none; }
.jsn-topics-chips.is-dragging{ cursor:grabbing; user-select:none; }

.jsn-topic-chip{
	display:inline-flex;
	align-items:baseline;
	gap:6px;
	flex:0 0 auto;
	padding:var(--space-2) var(--space-3);
	border:1px solid var(--color-rule);
	border-radius:999px;
	white-space:nowrap;
	text-decoration:none;
	transition:border-color var(--transition-fast), background-color var(--transition-fast);
}
.jsn-topic-chip-name{
	font-family:var(--font-body);
	font-size:13px;
	font-weight:600;
	color:var(--color-ink);
}
.jsn-topic-chip-count{
	font-family:var(--font-mono);
	font-size:11px;
	color:var(--color-faint);
}
.jsn-topic-chip:hover{ border-color:var(--color-ink); }
.jsn-topic-chip.is-active{ background:var(--color-ink); border-color:var(--color-ink); }
.jsn-topic-chip.is-active .jsn-topic-chip-name{ color:var(--color-on-dark); }
.jsn-topic-chip.is-active .jsn-topic-chip-count{ color:var(--color-on-dark-faint); }
.jsn-topic-chip:focus-visible{ outline:2px solid var(--color-red); outline-offset:2px; }

.jsn-topics-panel{ transition:opacity var(--transition-fast); }
.jsn-topics-panel.is-loading{ opacity:.5; pointer-events:none; }

.jsn-topics-panel-head{
	display:flex;
	align-items:baseline;
	justify-content:space-between;
	gap:var(--space-3);
	margin-bottom:var(--space-3);
}
.jsn-topics-panel-heading{
	font-family:var(--font-body);
	font-size:13px;
	font-weight:700;
	text-transform:uppercase;
	letter-spacing:.06em;
	color:var(--color-ink);
}
.jsn-topics-panel-more{
	font-family:var(--font-body);
	font-size:12px;
	font-weight:600;
	color:var(--color-red);
	text-decoration:none;
	white-space:nowrap;
}
.jsn-topics-panel-more:hover{ text-decoration:underline; }

.jsn-topics-list{ counter-reset:jsn-topics-rank; }
.jsn-topics-item{ counter-increment:jsn-topics-rank; }
.jsn-topics-item + .jsn-topics-item{ border-top:1px solid var(--color-rule); }
.jsn-topics-item a{
	display:flex;
	align-items:baseline;
	gap:var(--space-3);
	padding:var(--space-4) 0;
	min-width:0;
	text-decoration:none;
}
.jsn-topics-rank::before{
	content:counter(jsn-topics-rank, decimal-leading-zero);
	font-family:var(--font-mono);
	font-size:26px;
	font-weight:700;
	color:var(--color-red);
	flex:0 0 auto;
}
.jsn-topics-title{
	font-size:15px;
	font-weight:600;
	line-height:1.35;
	color:var(--color-ink);
	min-width:0;
	display:-webkit-box;
	-webkit-box-orient:vertical;
	-webkit-line-clamp:2;
	overflow:hidden;
	transition:color var(--transition-fast);
}
.jsn-topics-item a:focus-visible{ outline:2px solid var(--color-red); outline-offset:2px; }
.jsn-topics-item a:hover .jsn-topics-title{ color:var(--color-red); }

/* =========================================================
   BREADCRUMB — shared by single/category/archive/search/404
========================================================= */
.jsn-breadcrumb{ margin:var(--space-5) 0 var(--space-3) 0; }
.jsn-breadcrumb ol{ display:flex; flex-wrap:wrap; align-items:center; gap:6px; }
.jsn-breadcrumb li{
	font-family:var(--font-body);
	font-size:12.5px;
	color:var(--color-muted);
	display:flex;
	align-items:center;
	gap:6px;
}
.jsn-breadcrumb li:not(:last-child)::after{
	content:'/';
	color:var(--color-faint);
}
.jsn-breadcrumb a{ color:var(--color-muted); }
.jsn-breadcrumb a:hover{ color:var(--color-red); }
.jsn-breadcrumb li[aria-current="page"] span{
	color:var(--color-ink);
	font-weight:600;
	max-width:40ch;
	overflow:hidden;
	text-overflow:ellipsis;
	white-space:nowrap;
}

/* =========================================================
   CHIPS — sub-category nav, quick links, 404 links
========================================================= */
.jsn-chip{
	display:inline-block;
	padding:6px var(--space-3);
	border:1px solid var(--color-rule);
	border-radius:999px;
	font-family:var(--font-body);
	font-size:12.5px;
	font-weight:600;
	color:var(--color-ink-soft);
	white-space:nowrap;
}
.jsn-chip:hover{ border-color:var(--color-red); color:var(--color-red); }
.jsn-archive-subnav,
.jsn-quick-links{
	display:flex;
	flex-wrap:wrap;
	gap:var(--space-2);
	margin-top:var(--space-4);
}

/* Homepage-only: Quick Links as a compact nav divider right after
   Latest+Trending, before the category rows. Scoped via adjacent-
   sibling selector so .jsn-quick-links used in 404.php/search.php
   (different preceding siblings, no .jsn-home-grid there) is untouched. */
.jsn-home-grid + .jsn-quick-links{
	max-width:var(--container-max);
	margin:0 auto;
	padding:var(--space-4) var(--container-pad);
	border-top:1px solid var(--color-rule);
}

/* =========================================================
   CARD GRID — archive/search/related/404 result cards
========================================================= */
.jsn-card-grid{
	display:grid;
	grid-template-columns:repeat(3, minmax(0,1fr));
	gap:var(--space-6) var(--space-5);
}
.jsn-card-grid--archive{ grid-template-columns:repeat(3, minmax(0,1fr)); }
@media(max-width:1024px){
	.jsn-card-grid{ grid-template-columns:repeat(2, minmax(0,1fr)); }
}
@media(max-width:600px){
	.jsn-card-grid{ grid-template-columns:1fr; gap:0; }
}

.jsn-card{ min-width:0; }
@media(max-width:600px){
	.jsn-card{ display:flex; gap:var(--space-3); padding:var(--space-4) 0; }
	.jsn-card + .jsn-card{ border-top:1px solid var(--color-rule); }
}
.jsn-card-thumb-link{ display:block; overflow:hidden; border-radius:var(--radius-sm); }
.jsn-card-thumb{
	width:100%;
	aspect-ratio:3/2;
	object-fit:cover;
	border-radius:var(--radius-sm);
	border:1px solid var(--color-rule);
	transition:transform var(--transition-fast);
}
.jsn-card:hover .jsn-card-thumb{ transform:scale(1.035); }
.jsn-card-thumb--empty{ display:block; background:var(--color-canvas); }
@media(max-width:600px){
	.jsn-card-thumb-link{ flex:0 0 112px; }
	.jsn-card-thumb{ width:112px; height:80px; aspect-ratio:auto; }
}
.jsn-card-body{ padding-top:var(--space-3); min-width:0; }
@media(max-width:600px){ .jsn-card-body{ padding-top:0; flex:1; min-width:0; } }
.jsn-card-meta{ display:flex; align-items:center; gap:var(--space-2); margin-bottom:6px; }
.jsn-card-meta time{ font-family:var(--font-mono); font-size:11px; color:var(--color-faint); }
.jsn-card-title{
	font-size:16px;
	font-weight:700;
	line-height:1.35;
	color:var(--color-ink);
	display:-webkit-box;
	-webkit-box-orient:vertical;
	-webkit-line-clamp:3;
	overflow:hidden;
}
.jsn-card-title a{ transition:color var(--transition-fast); }
.jsn-card-title a:hover{ color:var(--color-red); }
.jsn-card-excerpt{
	margin-top:6px;
	font-size:13.5px;
	line-height:1.55;
	color:var(--color-muted);
	display:-webkit-box;
	-webkit-box-orient:vertical;
	-webkit-line-clamp:2;
	overflow:hidden;
}
@media(max-width:600px){ .jsn-card-excerpt{ display:none; } }

/* =========================================================
   ARCHIVE / CATEGORY / SEARCH
========================================================= */
.jsn-archive-head{ padding-top:var(--space-2); padding-bottom:var(--space-6); border-bottom:1px solid var(--color-rule); margin-bottom:var(--space-7); }
.jsn-archive-title{
	font-family:var(--font-headline);
	font-size:clamp(26px, 20px + 1.6vw, 36px);
	font-weight:700;
	color:var(--color-ink);
	line-height:1.15;
}
.jsn-archive-title-query{ color:var(--color-red); }
.jsn-archive-description{ margin-top:var(--space-2); color:var(--color-muted); font-size:14.5px; max-width:70ch; }

.jsn-archive-list{ display:flex; flex-direction:column; }
.jsn-archive-lead{
	display:grid;
	grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);
	gap:var(--space-6);
	align-items:start;
	padding-bottom:var(--space-7);
	margin-bottom:var(--space-7);
	border-bottom:1px solid var(--color-rule);
}
.jsn-archive-lead-thumb{
	width:100%;
	aspect-ratio:16/9;
	object-fit:cover;
	border-radius:var(--radius-sm);
	border:1px solid var(--color-rule);
}
.jsn-archive-lead-thumb--empty{ display:block; background:var(--color-canvas); }
.jsn-archive-lead-title{
	font-family:var(--font-headline);
	font-size:clamp(22px, 17px + 1.2vw, 28px);
	font-weight:700;
	line-height:1.2;
	margin:var(--space-2) 0 var(--space-2) 0;
	color:var(--color-ink);
}
.jsn-archive-lead-title a:hover{ color:var(--color-red); }
.jsn-archive-lead-excerpt{ font-size:15px; line-height:1.6; color:var(--color-ink-soft); margin-bottom:var(--space-3); }
.jsn-archive-lead-meta{ display:flex; gap:var(--space-3); font-family:var(--font-mono); font-size:12px; color:var(--color-faint); }
@media(max-width:767px){
	.jsn-archive-lead{ grid-template-columns:1fr; gap:var(--space-3); }
}

.jsn-archive-list .jsn-card:not(.jsn-archive-lead){
	display:grid;
	grid-template-columns:160px minmax(0,1fr);
	gap:var(--space-4);
	padding:var(--space-5) 0;
	border-top:1px solid var(--color-rule);
}
.jsn-archive-list .jsn-card:not(.jsn-archive-lead) .jsn-card-body{ padding-top:0; }
@media(max-width:600px){
	.jsn-archive-list .jsn-card:not(.jsn-archive-lead){ grid-template-columns:112px minmax(0,1fr); }
}

.jsn-archive-empty{ color:var(--color-muted); padding:var(--space-7) 0; text-align:center; }
.jsn-search-empty{ text-align:left; }

.jsn-archive-search-form{
	display:flex;
	max-width:420px;
	margin-top:var(--space-4);
	border:1px solid var(--color-rule);
	border-radius:var(--radius-sm);
	overflow:hidden;
}
.jsn-archive-search-form input[type=search]{
	flex:1;
	border:0;
	padding:var(--space-3);
	font-family:var(--font-body);
	font-size:14px;
	background:var(--color-paper);
}
.jsn-archive-search-form input[type=search]:focus-visible{ outline:2px solid var(--color-red); outline-offset:-2px; }
.jsn-archive-search-form button{
	border:0;
	background:var(--color-ink);
	color:var(--color-paper);
	padding:0 var(--space-5);
	font-family:var(--font-body);
	font-weight:600;
	font-size:13px;
	cursor:pointer;
}
.jsn-archive-search-form button:hover{ background:var(--color-red); }

/* WP core pagination -- unstyled by default, bring in line with tokens */
.pagination, .navigation.pagination{
	display:flex;
	flex-wrap:wrap;
	gap:var(--space-2);
	margin:var(--space-7) 0;
	justify-content:center;
}
.pagination .page-numbers{
	display:inline-flex;
	align-items:center;
	justify-content:center;
	min-width:36px;
	height:36px;
	padding:0 var(--space-2);
	border:1px solid var(--color-rule);
	border-radius:var(--radius-sm);
	font-family:var(--font-mono);
	font-size:13px;
	color:var(--color-ink);
}
.pagination .page-numbers.current{ background:var(--color-ink); color:var(--color-paper); border-color:var(--color-ink); }
.pagination .page-numbers:hover:not(.current){ border-color:var(--color-red); color:var(--color-red); }
.pagination .page-numbers.dots{ border:none; }

/* =========================================================
   SINGLE ARTICLE
========================================================= */
.jsn-article-head{ padding-top:var(--space-5); max-width:840px; margin-left:auto; margin-right:auto; }
.jsn-article-eyebrow{ font-size:12.5px; }
.jsn-article-headline{
	font-family:var(--font-headline);
	font-size:clamp(28px, 22px + 1.6vw, 42px);
	font-weight:700;
	line-height:1.18;
	color:var(--color-ink);
	margin:var(--space-3) 0;
}
.jsn-article-standfirst{
	font-size:17px;
	line-height:1.55;
	color:var(--color-ink-soft);
	margin-bottom:var(--space-4);
}
/* Author identity block -- avatar + name/role/date + integrated share
   row, replacing the old thin one-line byline + a separate 56px share
   rail that read as visually detached from everything around it. */
.jsn-article-meta{
	display:flex;
	align-items:center;
	flex-wrap:wrap;
	gap:var(--space-3) var(--space-4);
	padding:var(--space-4) 0;
	margin-top:var(--space-2);
	border-top:1px solid var(--color-rule);
	border-bottom:1px solid var(--color-rule);
}
.jsn-article-avatar{
	border-radius:50%;
	flex:0 0 auto;
}
.jsn-article-meta-info{
	display:flex;
	flex-direction:column;
	gap:2px;
	flex:1 1 auto;
	min-width:180px;
}
.jsn-article-meta-name{
	font-family:var(--font-body);
	font-weight:700;
	font-size:14.5px;
	color:var(--color-ink);
}
a.jsn-article-meta-name{
	transition:color var(--transition-fast);
}
a.jsn-article-meta-name:hover{ color:var(--color-red); }
a.jsn-article-meta-name:focus-visible{ outline:2px solid var(--color-red); outline-offset:2px; }
.jsn-article-meta-role{
	font-family:var(--font-body);
	font-size:12px;
	font-weight:600;
	color:var(--color-red);
	text-transform:uppercase;
	letter-spacing:.03em;
}
.jsn-article-meta-date{
	font-family:var(--font-mono);
	font-size:12px;
	color:var(--color-faint);
	display:flex;
	flex-wrap:wrap;
	gap:var(--space-2);
}
.jsn-article-meta-updated::before{ content:'· '; }
.jsn-article-meta .jsn-share{ flex:0 0 auto; margin-left:auto; }
@media(max-width:600px){
	.jsn-article-meta{ align-items:flex-start; }
	.jsn-article-meta .jsn-share{ flex:1 1 100%; margin-left:0; justify-content:flex-start; }
}

.jsn-article-featured{ max-width:1120px; margin:var(--space-6) auto 0 auto; }
/* T.1A: was aspect-ratio:16/9 + object-fit:cover, which force-crops every
   photo into a 16:9 box regardless of its real shape -- destructive for
   the corpus's many portrait (e.g. 960x1280) and square/near-square
   images (verified against real attachment dimensions, not assumed).
   height:auto preserves the natural ratio outright (no cropping is even
   possible when height is derived from width); max-height only exists
   to stop an extreme portrait from taking over the page, and
   object-fit:contain (not cover) means that cap letterboxes rather than
   crops when it actually triggers. For ordinary landscape news photos
   this cap is rarely if ever reached, so almost nothing changes for the
   common case -- the fix is specifically for the images this was
   cropping badly before. */
.jsn-article-featured-image{
	width:100%;
	height:auto;
	max-height:640px;
	object-fit:contain;
	background:var(--color-canvas);
	border-radius:var(--radius-sm);
	display:block;
	margin:0 auto;
}
.jsn-article-caption{
	margin-top:var(--space-2);
	font-size:12.5px;
	color:var(--color-faint);
	font-style:italic;
}

/* Main + rail on wide desktop (>=1280px) fills the space that used to
   sit empty beside a lone 840px column; single column below that,
   which is also the mobile-first default. Rail content is fetched
   either way (small, bounded queries -- see article-rail.php) and
   simply hidden by CSS at <1280px rather than gated server-side, since
   there's no reliable server-side viewport check. */
.jsn-article-layout{
	max-width:var(--container-max);
	margin:var(--space-7) auto 0 auto;
	padding-left:var(--container-pad);
	padding-right:var(--container-pad);
	display:grid;
	grid-template-columns:minmax(0,1fr);
	gap:var(--space-7);
	align-items:start;
}
@media(min-width:1280px){
	.jsn-article-layout{
		grid-template-columns:minmax(0,760px) minmax(280px,320px);
		justify-content:center;
	}
}

/* Article body -- must safely contain legacy Blogger HTML (inline
   widths, wrapper tables around images, old anchors, embeds). Kept to
   the minimum !important needed to override inline style="" attributes
   that would otherwise break the reading column; everything else here
   is plain cascade. */
.jsn-article-body{
	max-width:760px;
	margin:0 auto;
	font-family:var(--font-body);
	font-size:17px;
	line-height:1.75;
	color:var(--color-ink);
	overflow-wrap:break-word;
	word-wrap:break-word;
}
@media(min-width:1280px){
	.jsn-article-body{ margin:0; }
}
.jsn-article-body > *{ max-width:100%; }
.jsn-article-body p{ margin:0 0 var(--space-4) 0; }
.jsn-article-body h2{ font-family:var(--font-headline); font-size:24px; font-weight:700; margin:var(--space-6) 0 var(--space-3) 0; }
.jsn-article-body h3{ font-family:var(--font-headline); font-size:20px; font-weight:700; margin:var(--space-5) 0 var(--space-3) 0; }
.jsn-article-body a{ color:var(--color-red-deep); text-decoration:underline; text-underline-offset:2px; }
.jsn-article-body ul, .jsn-article-body ol{ list-style:revert; margin:0 0 var(--space-4) 0; padding-left:1.4em; }
.jsn-article-body li{ margin-bottom:var(--space-1); }
.jsn-article-body img{
	max-width:100% !important;
	height:auto !important;
	width:auto;
	border-radius:var(--radius-sm);
	margin:var(--space-2) auto;
	display:block;
}
.jsn-article-body table{
	max-width:100% !important;
	display:block;
	overflow-x:auto;
	border-collapse:collapse;
	margin:0 0 var(--space-4) 0;
}
.jsn-article-body table td, .jsn-article-body table th{ border:1px solid var(--color-rule); padding:var(--space-2); }
.jsn-article-body iframe, .jsn-article-body video, .jsn-article-body embed{
	max-width:100%;
	width:100%;
	aspect-ratio:16/9;
	height:auto;
	border:0;
	margin:var(--space-4) 0;
}
.jsn-article-body blockquote{
	margin:var(--space-5) 0;
	padding:var(--space-3) var(--space-5);
	border-left:3px solid var(--color-red);
	background:var(--color-red-wash);
	font-style:italic;
	color:var(--color-ink-soft);
}
.jsn-article-body figure{ margin:var(--space-4) 0; }
.jsn-article-body figcaption{ font-size:12.5px; color:var(--color-faint); text-align:center; margin-top:6px; }
/* Blogger's own image-caption wrapper tables often set inline text-align
   and width on the <td>/<table> -- neutralize so they don't fight the
   reading column. */
.jsn-article-body .tr-caption-container{ max-width:100% !important; width:auto !important; }

/* Share row -- now integrated into .jsn-article-meta (byline block)
   instead of a detached sticky sidebar. Horizontal on every breakpoint,
   >=44px touch targets on the buttons themselves per Task 3/10. */
.jsn-share{ display:flex; flex-direction:row; gap:var(--space-2); align-items:center; flex-wrap:wrap; }
.jsn-share-label{ font-family:var(--font-mono); font-size:11px; text-transform:uppercase; letter-spacing:.06em; color:var(--color-faint); }
.jsn-share-btn{
	display:flex;
	align-items:center;
	justify-content:center;
	width:44px;
	height:44px;
	border-radius:50%;
	border:1px solid var(--color-rule);
	color:var(--color-ink-soft);
	background:var(--color-paper);
	cursor:pointer;
	transition:border-color var(--transition-fast), color var(--transition-fast), background var(--transition-fast);
}
.jsn-share-btn:hover{ border-color:var(--color-red); color:var(--color-red); }
.jsn-share-btn.jsn-share-copied{ border-color:var(--color-red); color:var(--color-red); background:var(--color-red-wash); }

/* Tags -- now sits inside .jsn-article-body, right after the_content(),
   with its own top divider so the end of the article reads as a
   deliberate close rather than trailing off into empty margin. */
.jsn-article-tags{
	margin-top:var(--space-6);
	padding-top:var(--space-5);
	border-top:1px solid var(--color-rule);
	display:flex;
	flex-wrap:wrap;
	gap:var(--space-2);
}
.jsn-tag{
	display:inline-block;
	padding:6px var(--space-3);
	background:var(--color-canvas);
	border:1px solid var(--color-rule);
	border-radius:var(--radius-sm);
	font-size:12.5px;
	color:var(--color-ink-soft);
	transition:color var(--transition-fast), border-color var(--transition-fast);
}
.jsn-tag:hover{ color:var(--color-red); border-color:var(--color-red); }

/* =========================================================
   ARTICLE RAIL — Most Read/Pilihan Redaksi + Berita Terbaru,
   desktop-only (>=1280px), real data, no ad placeholder.
========================================================= */
.jsn-article-rail{ display:none; }
@media(min-width:1280px){
	.jsn-article-rail{
		display:flex;
		flex-direction:column;
		gap:var(--space-7);
		position:sticky;
		top:var(--space-6);
	}
}
.jsn-rail-block .jsn-section-title{ margin-bottom:var(--space-4); }
.jsn-rail-list{ display:flex; flex-direction:column; }
.jsn-rail-list li + li{ border-top:1px solid var(--color-rule); }
.jsn-rail-list a{
	display:flex;
	align-items:baseline;
	gap:var(--space-3);
	padding:var(--space-3) 0;
	min-width:0;
}
.jsn-rail-list .jsn-rail-title{
	font-size:13.5px;
	font-weight:600;
	line-height:1.4;
	color:var(--color-ink);
	display:-webkit-box;
	-webkit-box-orient:vertical;
	-webkit-line-clamp:2;
	overflow:hidden;
	transition:color var(--transition-fast);
}
.jsn-rail-list a:hover .jsn-rail-title{ color:var(--color-red); }
.jsn-rail-list time{ font-family:var(--font-mono); font-size:11px; color:var(--color-faint); flex:0 0 auto; }
.jsn-rail-list--ranked .jsn-rail-rank{
	font-family:var(--font-mono);
	font-size:18px;
	font-weight:700;
	color:var(--color-red);
	flex:0 0 auto;
	min-width:1.2em;
}

/* =========================================================
   AUTHOR BIO -- T.2, only rendered when a real WP user
   description exists (empty for all 22 current authors, so this
   is dormant today but ready).
========================================================= */
.jsn-author-bio{
	display:flex;
	gap:var(--space-4);
	max-width:840px;
	margin:var(--space-7) auto 0 auto;
	padding:var(--space-5);
	background:var(--color-canvas);
	border:1px solid var(--color-rule);
	border-radius:var(--radius-sm);
}
.jsn-author-bio .jsn-author-avatar{ flex:0 0 auto; border-radius:50%; }
.jsn-author-bio-body{ min-width:0; }
.jsn-author-bio-name{
	display:block;
	font-family:var(--font-body);
	font-weight:700;
	font-size:15px;
	color:var(--color-ink);
	margin-bottom:4px;
}
.jsn-author-bio-text{
	font-size:14px;
	line-height:1.6;
	color:var(--color-ink-soft);
	margin-bottom:var(--space-2);
}
.jsn-author-bio-link{
	font-size:13px;
	font-weight:600;
	color:var(--color-red);
	transition:color var(--transition-fast);
}
.jsn-author-bio-link:hover{ color:var(--color-red-deep); text-decoration:underline; }
.jsn-author-bio-link:focus-visible{ outline:2px solid var(--color-red); outline-offset:2px; }

/* =========================================================
   RELATED ARTICLES / 404 LATEST
========================================================= */
.jsn-related{ margin-top:var(--space-8); padding-top:var(--space-6); border-top:1px solid var(--color-rule); }
.jsn-related--latest{ margin-top:var(--space-7); padding-top:var(--space-6); border-top:1px solid var(--color-rule); }

/* Gives "Artikel Terkait" a touch more recommendation-module warmth
   than a plain archive listing, without a second card component --
   subtle background + border tint on hover, same restrained language
   as the rest of the theme (no shadow, no scale beyond the shared
   image zoom already applied to .jsn-card globally). */
.jsn-related .jsn-card{
	padding:var(--space-3);
	margin:calc(var(--space-3) * -1);
	border-radius:var(--radius-sm);
	transition:background var(--transition-fast);
}
.jsn-related .jsn-card:hover{ background:var(--color-canvas); }
@media(max-width:600px){
	.jsn-related .jsn-card{ padding:var(--space-3) 0; margin:0; }
	.jsn-related .jsn-card:hover{ background:transparent; }
}

/* =========================================================
   404
========================================================= */
.jsn-404{ max-width:640px; margin:var(--space-9) auto; text-align:center; }
.jsn-404-code{
	font-family:var(--font-mono);
	font-size:64px;
	font-weight:700;
	color:var(--color-rule);
	line-height:1;
	margin-bottom:var(--space-3);
}
.jsn-404-title{ font-family:var(--font-headline); font-size:28px; font-weight:700; color:var(--color-ink); margin-bottom:var(--space-3); }
.jsn-404-copy{ color:var(--color-muted); margin-bottom:var(--space-5); }
.jsn-404-search{ margin:0 auto var(--space-6) auto; }
.jsn-404 .jsn-quick-links{ justify-content:center; margin-bottom:var(--space-8); }
.jsn-404-latest{ text-align:left; }

/* =========================================================
   FOOTER — revisi ke-3: 4 kolom premium tanpa accordion (Brand /
   Tentang JatimSatuNews / Kontak Redaksi / Pimpinan), strip
   "Legalitas Media" di bawah kolom, copyright dua baris di paling
   bawah. Struktur redaksi lengkap + reporter tetap di halaman
   /redaksi/. Tidak ada fabricated link -- semua data verbatim dari
   approval brief, cocok dengan NewsMediaOrganization schema (Rank
   Math) yang sudah live.
========================================================= */
.jsn-footer{
	background:var(--color-near-black);
	color:var(--color-on-dark-muted);
}
.jsn-footer-inner{
	max-width:1400px;
	margin:0 auto;
	padding:var(--space-7) var(--container-pad) var(--space-6);
	display:grid;
	grid-template-columns:1.3fr 1fr 1fr 1fr;
	gap:var(--space-6);
	align-items:start;
}
.jsn-footer-brand-logo{ display:inline-block; margin-bottom:var(--space-3); }
.jsn-footer-brand-logo img{ max-height:44px; width:auto; max-width:100%; }
.jsn-footer-tagline{
	font-size:13.5px;
	line-height:1.65;
	color:var(--color-on-dark-muted);
	max-width:32ch;
	margin:0;
}
.jsn-footer-about-desc{
	font-size:13px;
	line-height:1.65;
	color:var(--color-on-dark-muted);
	margin:0;
	max-width:30ch;
}
.jsn-footer-col-title{
	font-family:var(--font-body);
	font-size:12.5px;
	font-weight:700;
	text-transform:uppercase;
	letter-spacing:.06em;
	color:var(--color-on-dark);
	margin:0 0 var(--space-4);
}

/* -- Kontak Redaksi -- */
.jsn-footer-contact-line{ font-size:13.5px; margin:0 0 var(--space-2); }
.jsn-footer-contact-line a{ color:var(--color-on-dark); text-decoration:none; }
.jsn-footer-contact-line a:hover{ color:var(--color-red); }
.jsn-footer-address{
	font-style:normal;
	font-size:12.5px;
	line-height:1.6;
	color:var(--color-on-dark-muted);
	margin:0 0 var(--space-2);
}
.jsn-footer-cta{
	display:inline-block;
	margin-top:var(--space-3);
	padding:9px 20px;
	border:1px solid var(--color-on-dark);
	color:var(--color-on-dark);
	font-family:var(--font-body);
	font-size:11.5px;
	font-weight:700;
	text-transform:uppercase;
	letter-spacing:.05em;
	text-decoration:none;
	transition:background-color var(--transition-fast), color var(--transition-fast);
}
.jsn-footer-cta:hover{ background:var(--color-red); border-color:var(--color-red); color:var(--color-on-dark); }
.jsn-footer-cta:focus-visible{ outline:2px solid var(--color-red); outline-offset:2px; }

/* -- Pimpinan -- */
.jsn-footer-structure-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:var(--space-3); }
.jsn-footer-structure-role{
	display:block;
	font-size:11px;
	text-transform:uppercase;
	letter-spacing:.04em;
	color:var(--color-on-dark-faint);
	margin-bottom:2px;
}
.jsn-footer-structure-name{
	display:block;
	font-size:13.5px;
	font-weight:600;
	color:var(--color-on-dark);
}

/* -- Legalitas Media strip -- */
.jsn-footer-legal-strip{
	border-top:1px solid var(--color-on-dark-rule);
	background:rgba(255,255,255,.02);
}
.jsn-footer-legal-strip-inner{
	max-width:1400px;
	margin:0 auto;
	padding:var(--space-4) var(--container-pad);
}
.jsn-footer-legal-strip-title{
	display:block;
	font-size:10.5px;
	font-weight:700;
	text-transform:uppercase;
	letter-spacing:.06em;
	color:var(--color-on-dark-faint);
	margin-bottom:6px;
}
.jsn-footer-legal-strip-inner p{
	margin:0;
	font-size:12px;
	line-height:1.6;
	color:var(--color-on-dark-faint);
}
.jsn-footer-legal-strip-inner p.jsn-footer-legal-ukw{
	margin-top:6px;
	font-weight:600;
	color:var(--color-on-dark-muted);
}

.jsn-footer-bottom{
	border-top:1px solid var(--color-on-dark-rule);
}
.jsn-footer-bottom-inner{
	max-width:1400px;
	margin:0 auto;
	padding:var(--space-4) var(--container-pad);
	text-align:center;
}
.jsn-footer-copyright{
	font-size:12px;
	line-height:1.6;
	color:var(--color-on-dark-muted);
	margin:0;
}

@media(max-width:1024px){
	.jsn-footer-inner{
		grid-template-columns:1fr 1fr;
	}
	.jsn-footer-col--brand{ grid-column:1 / -1; }
}
@media(max-width:600px){
	.jsn-footer-inner{
		grid-template-columns:1fr;
		gap:var(--space-5);
	}
	.jsn-footer-col--brand{ grid-column:auto; }
}

/* =========================================================
   PSI audit 2026-08-16, REVISED same day after user review.
   First pass added `.google-auto-placed{min-height:250px}` to
   reserve space for AdSense Auto Ads (root cause of the CLS spike
   seen in one Lighthouse lab run -- see CHANGELOG/report). Reverted:
   a fixed min-height fights Google's own no-fill collapse behavior
   (adsbygoogle.js already shrinks `.google-auto-placed` back down
   when a slot gets no ad -- that is the CORRECT default), so forcing
   250px here would have created a permanent blank gap on every
   no-fill impression instead of preventing a shift. Auto Ads
   placement/size is decided dynamically by Google per-impression;
   there is no theme-CSS value that is safe to guess for every case.
   The real fix for the lab-run CLS spike lives in the AdSense
   dashboard (Auto ads -> Ad formats: disable Anchor ads / Vignette
   ads, the two overlay formats most associated with large layout
   shifts; or lower Ad load), which needs account access this session
   does not have. Real-user CLS (CrUX, 28-day) was already 0.05/PASS
   before this whole investigation -- this reversion returns
   `.google-auto-placed` to that already-passing, unmodified-by-theme
   baseline rather than risking a worse, code-introduced regression.
   ========================================================= */
