/*
 * Shell styles — Aspirasi Aktual
 * Utility bar, masthead, navigasi (desktop + mobile), dropdown Sastra,
 * breaking-news ticker, dan footer. Bukan styling homepage/article — itu
 * menyusul di Stage 4/5. Breakpoint 960px dipilih berdasarkan kebutuhan
 * konten (11 item navigasi berbahasa Indonesia tidak lagi muat nyaman
 * dalam satu baris di bawah lebar ini), bukan perangkat tertentu.
 */

.site-container {
	max-width: var( --wp--style--global--wide-size, 1280px );
	margin-inline: auto;
	padding-inline: var( --wp--preset--spacing--lg );
}

.site-header {
	background-color: var( --wp--preset--color--paper );
}

/* Utility bar */
.utility-bar {
	border-bottom: 1px solid var( --wp--preset--color--line );
	background: var( --wp--preset--color--paper );
}

.utility-bar__inner {
	display: flex;
	justify-content: flex-end;
	min-height: 38px;
}

.utility-bar__actions {
	display: flex;
	align-items: center;
	gap: var( --wp--preset--spacing--md );
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--small );
}

.utility-bar__actions a {
	color: var( --wp--preset--color--ink );
	text-decoration: none;
}

.utility-bar__subscribe {
	display: inline-flex;
	align-items: center;
	min-height: 28px;
	padding-inline: var( --wp--preset--spacing--sm );
	border: 1px solid var( --wp--preset--color--line );
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.utility-bar__subscribe:hover {
	border-color: var( --wp--preset--color--accent );
}

/* Masthead / branding */
.site-branding-group {
	text-align: center;
	padding: 30px 0 22px;
}

/*
 * Three-track grid (gutter | wordmark | account), not centre-justified flex
 * with an absolutely positioned account block. The account block was out of
 * flow, so the centred wordmark had no idea it was there and simply ran
 * underneath "Masuk"/"Berlangganan" once it grew wide enough — a 13px
 * overlap at 1366px and a ~190px one at 768px, where the two buttons sat
 * directly on top of the site name (Stage 18 screenshot audit). The two
 * minmax(0, 1fr) gutters are equal by definition, so the wordmark stays
 * optically centred exactly as before while the account column now reserves
 * its own space instead of stealing the wordmark's.
 */
.site-branding__row {
	display: grid;
	/*
	 * Plain 1fr (implicit auto minimum), not minmax(0, 1fr): the account
	 * track has to floor at its own min-content or "Masuk" and the
	 * "Berlangganan" button get squeezed into stacked single letters as soon
	 * as the wordmark is wide. The two 1fr gutters keep the wordmark centred
	 * whenever there is room for equal ones, and give ground to the account
	 * column rather than deforming it when there is not.
	 */
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	gap: var( --wp--preset--spacing--md );
}

.site-branding__title,
.custom-logo-link {
	grid-column: 2;
}

.site-branding__title {
	font-family: var( --wp--preset--font-family--editorial-display );
	font-size: var( --wp--preset--font-size--display );
	/*
	 * font-weight/line-height are declared here on purpose. header.php renders
	 * this element as <h1> on the front page and as <p> everywhere else (one
	 * H1 per document — a deliberate semantic choice, not a styling one), so
	 * with no declaration of its own the masthead inherited 700/1.2 from the
	 * base.css h1-h6 rule on "/" and 400/1.6 from body on every other page:
	 * the same wordmark rendered at two different weights, and the masthead
	 * block came out 22px taller off the front page. That was the visible
	 * "typography differs between Beranda and the other pages" report.
	 * docs/02-design-analysis.md records that the header is pixel-identical
	 * across the design comps, and the front page is the agreed reference,
	 * so both values are pinned to what "/" already rendered.
	 */
	font-weight: 700;
	line-height: 1.2;
	letter-spacing: 0.06em;
	margin: 0;
}

.site-branding {
	color: var( --wp--preset--color--ink );
	text-decoration: none;
	display: block;
}

.site-branding__tagline {
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--small );
	letter-spacing: 0.15em;
	text-transform: uppercase;
	color: var( --wp--preset--color--text-muted );
	margin: var( --wp--preset--spacing--2-xs ) 0 0;
}

.site-branding__account {
	grid-column: 3;
	justify-self: end;
	display: flex;
	align-items: center;
	gap: var( --wp--preset--spacing--md );
	white-space: nowrap;
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--metadata );
}

.site-branding__account a {
	text-decoration: none;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var( --wp--preset--color--ink );
}

.site-branding__subscribe {
	background-color: var( --wp--preset--color--accent );
	padding: var( --wp--preset--spacing--xs ) var( --wp--preset--spacing--md );
	font-weight: 600;
	display: inline-block;
	line-height: 1.2;
}

/*
 * Root cause of the black "Berlangganan" label: `.site-branding__account a`
 * just above is class + type (0,1,1) and outranked the bare
 * `.site-branding__subscribe` (0,1,0), so `color: ink` won in the resting
 * state; on hover the base.css `a:hover { color: accent }` rule (also 0,1,1)
 * took over. Re-declaring the colour at 0,2,0 beats both without !important.
 * Every state is listed because each of the two rules it has to outrank
 * applies in a different one — a single resting-state declaration would be
 * silently undone again on hover.
 */
.site-branding__account .site-branding__subscribe,
.site-branding__account .site-branding__subscribe:link,
.site-branding__account .site-branding__subscribe:visited,
.site-branding__account .site-branding__subscribe:hover,
.site-branding__account .site-branding__subscribe:focus,
.site-branding__account .site-branding__subscribe:focus-visible,
.site-branding__account .site-branding__subscribe:active {
	color: var( --wp--preset--color--on-dark );
}

.site-branding__subscribe:hover {
	background-color: var( --wp--preset--color--accent-dark );
}

/*
 * Stacked below 960px — the same breakpoint the navigation already switches
 * at, raised here from 600px. Between 600 and 959px the wordmark and the
 * account block could not both fit on one row, and the old absolutely
 * positioned account block simply printed "Masuk"/"Berlangganan" straight on
 * top of the site name (a ~190px overlap at 768px, Stage 18 audit). Giving
 * the account its own centred row is the only arrangement at these widths
 * that neither overlaps the wordmark nor deforms either of them.
 */
@media ( max-width: 1100px ) {
	.site-branding__row {
		grid-template-columns: minmax( 0, 1fr );
		gap: var( --wp--preset--spacing--xs );
		justify-items: center;
	}

	.site-branding__title,
	.custom-logo-link,
	.site-branding__account {
		grid-column: 1;
		justify-self: center;
	}
}

.custom-logo-link {
	display: inline-block;
}

.custom-logo-link img {
	max-height: 64px;
	width: auto;
}

/* Primary navigation */
.primary-nav {
	border-top: 1px solid var( --wp--preset--color--line );
	border-bottom: 1px solid var( --wp--preset--color--line );
}

.primary-nav__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var( --wp--preset--spacing--md );
}

.mobile-menu-toggle {
	display: none;
	align-items: center;
	gap: var( --wp--preset--spacing--2-xs );
	background: none;
	border: 1px solid var( --wp--preset--color--line );
	padding: var( --wp--preset--spacing--xs ) var( --wp--preset--spacing--sm );
	margin-block: var( --wp--preset--spacing--sm );
	cursor: pointer;
	min-height: 44px;
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--metadata );
	color: var( --wp--preset--color--ink );
}

/* Sama seperti .primary-menu .submenu-toggle di bawah — cegah button:hover
   (base.css) mengecat toggle ikon/teks ini dengan latar accent-dark solid. */
.mobile-menu-toggle:hover,
.mobile-menu-toggle:focus {
	background: none;
}

/*
 * The hamburger used to be drawn with a 2px <span> plus ::before/::after
 * bars. It is now the shared `menu` glyph from inc/icons.php so the drawer
 * toggle uses the same outline family, stroke and optical weight as every
 * other control in the shell.
 */
.mobile-menu-toggle__icon {
	display: block;
	flex: 0 0 auto;
}

.primary-menu {
	list-style: none;
	margin: 0;
	padding: var( --wp--preset--spacing--sm ) 0;
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--metadata );
	text-transform: uppercase;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var( --wp--preset--spacing--lg );
}

.primary-menu li {
	position: relative;
}

.primary-menu .menu-item-has-children {
	display: flex;
	align-items: center;
	gap: 0;
}

.primary-menu a {
	color: var( --wp--preset--color--ink );
	text-decoration: none;
	display: inline-flex;
	align-items: center;
	padding: var( --wp--preset--spacing--2-xs ) 0;
}

.primary-menu a:hover {
	color: var( --wp--preset--color--accent );
}

/*
 * The submenu parent (Sastra) IS this button — it carries the label, there is
 * no sibling link and no caret icon (class-primary-nav-walker.php). So it has
 * to be typographically indistinguishable from the <a> items beside it:
 * identical family/size/weight/line-height/letter-spacing/case, identical
 * padding box, no border, no background, no reserved icon width, nothing that
 * would push its baseline off the row.
 *
 * Every inherited value is spelled out as a longhand rather than the `font`
 * shorthand: the UA stylesheet sets font-family/size/weight/line-height on
 * <button> so they do NOT inherit from .primary-menu on their own, and the
 * shorthand would additionally reset properties (font-variant, font-stretch)
 * that nothing here intends to touch.
 */
.primary-menu .submenu-toggle {
	appearance: none;
	display: inline-flex;
	align-items: center;
	background: none;
	border: none;
	border-radius: 0;
	margin: 0;
	padding: var( --wp--preset--spacing--2-xs ) 0;
	font-family: inherit;
	font-size: inherit;
	font-weight: inherit;
	line-height: inherit;
	letter-spacing: inherit;
	text-transform: inherit;
	color: var( --wp--preset--color--ink );
	cursor: pointer;
}

/*
 * base.css styles bare `button` with a solid accent background and an ink
 * border, and `button:hover` with accent-dark. Those are element selectors
 * (0,0,1 / 0,0,2); these class rules (0,2,0 / 0,2,1) outrank them, which is
 * what keeps this control looking like plain menu text rather than a filled
 * button. Found in the Stage 16 audit, still required here.
 */
.primary-menu .submenu-toggle:hover,
.primary-menu .submenu-toggle:focus {
	background: none;
	color: var( --wp--preset--color--accent );
}

.primary-menu .current-menu-item > a,
.primary-menu .current-menu-item > .submenu-toggle,
.primary-menu .current-menu-ancestor > .submenu-toggle {
	color: var( --wp--preset--color--accent );
}

.sub-menu {
	list-style: none;
	margin: 0;
	padding: var( --wp--preset--spacing--xs );
	text-transform: none;
	font-weight: 400;
	letter-spacing: normal;
}

.sub-menu a {
	display: block;
	padding: var( --wp--preset--spacing--sm ) var( --wp--preset--spacing--sm );
}

.sub-menu a:hover,
.sub-menu a:focus-visible {
	background-color: var( --wp--preset--color--subtle );
	color: var( --wp--preset--color--accent );
}

/* Desktop nav (>=960px): horizontal row, Sastra submenu as absolute dropdown */
@media ( min-width: 1101px ) {
	.mobile-menu-toggle {
		display: none !important;
	}

	.primary-menu .sub-menu {
		position: absolute;
		top: calc( 100% + var( --wp--preset--spacing--xs ) );
		left: calc( -1 * var( --wp--preset--spacing--sm ) );
		min-width: 220px;
		max-width: 300px;
		background-color: var( --wp--preset--color--surface );
		border: 1px solid var( --wp--preset--color--line );
		border-top: 2px solid var( --wp--preset--color--accent );
		box-shadow: 0 12px 24px -8px rgba( 23, 23, 23, 0.22 );
		z-index: 50;
	}

	.js-nav .primary-menu .sub-menu {
		display: none;
	}

	.js-nav .primary-menu .sub-menu.is-open {
		display: block;
	}

	.sub-menu li {
		display: block;
	}
}

/*
 * Mobile/tablet nav (<960px): base stacked-list styling for `.primary-menu`
 * (item borders, full-width tap targets, submenu accordion). The *open*
 * state's positioning — fixed drawer, backdrop, body scroll-lock — is
 * layered on top of this in visual-parity.css's "MOBILE MENU: FIXED DRAWER"
 * block (`body.mobile-menu-open`, appended after the mobile masthead
 * restructure), since that file already owns the rest of the mobile shell
 * layout and loads last.
 */
@media ( max-width: 1100px ) {
	.primary-nav__inner {
		flex-direction: column;
		align-items: stretch;
	}

	.js-nav .mobile-menu-toggle {
		display: flex;
	}

	.primary-menu {
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		padding-bottom: var( --wp--preset--spacing--md );
	}

	.js-nav .primary-menu {
		display: none;
	}

	.js-nav .primary-menu.is-open {
		display: flex;
	}

	.primary-menu li {
		width: 100%;
		border-bottom: 1px solid var( --wp--preset--color--line );
	}

	.primary-menu li:last-child {
		border-bottom: none;
	}

	/*
	 * flex-wrap: wrap (not nowrap) — the <li> is the flex container for the
	 * label control AND the .sub-menu list itself, which are siblings (see
	 * class-primary-nav-walker.php). With nowrap the browser tried to fit the
	 * full-width .sub-menu onto the same row as the label, crushing the
	 * label's flex-shrunk width down to single characters. With wrap, the
	 * label takes row one and .sub-menu's own width: 100% (below) pushes it
	 * onto its own row automatically.
	 */
	.primary-menu .menu-item-has-children {
		flex-wrap: wrap;
	}

	.primary-menu a,
	.primary-menu .submenu-toggle {
		width: 100%;
		min-height: 44px;
		padding: var( --wp--preset--spacing--sm ) 0;
	}

	/* Full-row hit area for the accordion control, label flush left with the
	   sibling links rather than centred in the button box. */
	.primary-menu .submenu-toggle {
		justify-content: flex-start;
		text-align: left;
	}

	.sub-menu {
		width: 100%;
		padding: var( --wp--preset--spacing--2-xs ) 0 var( --wp--preset--spacing--sm );
		background-color: var( --wp--preset--color--subtle );
		border-left: 3px solid var( --wp--preset--color--accent );
	}

	.sub-menu a {
		padding-block: var( --wp--preset--spacing--xs );
		padding-left: var( --wp--preset--spacing--md );
	}

	.js-nav .sub-menu {
		display: none;
	}

	.js-nav .sub-menu.is-open {
		display: block;
	}
}

/* Breaking-news ticker */
.breaking-news {
	background-color: var( --wp--preset--color--surface );
	border-bottom: 1px solid var( --wp--preset--color--line );
}

.breaking-news__inner {
	display: flex;
	align-items: center;
	gap: var( --wp--preset--spacing--md );
	padding-block: var( --wp--preset--spacing--sm );
}

.breaking-news__label {
	flex-shrink: 0;
	background-color: var( --wp--preset--color--accent );
	color: var( --wp--preset--color--on-dark );
	text-transform: uppercase;
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--small );
	font-weight: 700;
	letter-spacing: 0.04em;
	padding: var( --wp--preset--spacing--2-xs ) var( --wp--preset--spacing--sm );
}

/*
 * Missing text-decoration: none was the root cause of the "unstyled
 * default browser link" look reported in the Stage 17 screenshot audit —
 * every other card title link in the theme sets this explicitly, this one
 * didn't. Underline restored only on hover/focus as the interactive cue.
 */
.breaking-news__link {
	flex: 1;
	min-width: 0;
	color: var( --wp--preset--color--ink );
	font-family: var( --wp--preset--font-family--interface );
	font-weight: 600;
	text-decoration: none;
	overflow-wrap: anywhere;
	display: -webkit-box;
	-webkit-line-clamp: 1;
	-webkit-box-orient: vertical;
	overflow: hidden;
	text-overflow: ellipsis;
}

.breaking-news__link:hover,
.breaking-news__link:focus-visible {
	text-decoration: underline;
	text-decoration-color: var( --wp--preset--color--line );
}

.breaking-news__meta {
	margin-left: auto;
	flex-shrink: 0;
	white-space: nowrap;
	color: var( --wp--preset--color--text-muted );
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--small );
}

.breaking-news__meta::before {
	content: "\2022";
	margin-right: var( --wp--preset--spacing--sm );
	color: var( --wp--preset--color--line );
}

@media ( max-width: 390px ) {
	.breaking-news__link {
		-webkit-line-clamp: 2;
	}

	.breaking-news__meta::before {
		display: none;
	}
}

@media ( max-width: 390px ) {
	.breaking-news__meta {
		margin-left: 0;
	}
}

/* Footer */
.site-footer {
	background-color: var( --wp--preset--color--dark-surface );
	color: var( --wp--preset--color--on-dark );
}

.site-footer a {
	color: var( --wp--preset--color--on-dark );
	text-decoration: none;
}

.site-footer a:hover {
	color: var( --wp--preset--color--accent );
}

/*
 * The global focus ring (base.css: 2px solid accent) is sized for the paper
 * background, where accent scores 8.22:1. On the dark-surface footer the same
 * ring drops to 2.0:1 — under the 3:1 WCAG 2.4.11/1.4.11 floor for a focus
 * indicator, i.e. keyboard users could not see where they were in the Kanal
 * list. on-dark scores 16.45:1 against the same background. Pre-existing since
 * the footer went dark (Stage 3), surfaced while verifying the Kanal columns
 * keep a visible focus-visible state (Stage 18).
 */
.site-footer a:focus-visible {
	outline-color: var( --wp--preset--color--on-dark );
}

/*
 * auto-fit (not a fixed repeat(4, 1fr)) — footer-company and social menu
 * locations are frequently unconfigured (no policy pages / social accounts
 * yet, see footer.php), which previously left permanently empty grid
 * tracks stretching to the far right on wide viewports (Stage 17 audit).
 * With auto-fit, the track count always matches however many .footer-col
 * elements actually rendered.
 */
.site-footer__columns {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 200px, 1fr ) );
	gap: var( --wp--preset--spacing--xl );
	padding-block: var( --wp--preset--spacing--2-xl );
}

.footer-col__title {
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--metadata );
	text-transform: uppercase;
	letter-spacing: 0.06em;
	margin: 0 0 var( --wp--preset--spacing--md );
}

.footer-brand__name {
	font-family: var( --wp--preset--font-family--editorial-display );
	font-size: var( --wp--preset--font-size--headline-medium );
	margin: 0 0 var( --wp--preset--spacing--xs );
}

.footer-brand__description {
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--metadata );
	line-height: 1.6;
	color: var( --wp--preset--color--muted );
	margin: 0 0 var( --wp--preset--spacing--md );
	max-width: 32ch;
}

.footer-menu,
.footer-social {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var( --wp--preset--spacing--sm );
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--metadata );
	line-height: 1.4;
}

/*
 * Kanal carries all ten editorial channels, so as a single column it ran
 * roughly twice as tall as the brand and Informasi columns next to it and
 * left the footer visibly lopsided (client feedback, Stage 18).
 *
 * CSS multi-column rather than a grid with a hardcoded row count: it stays
 * ONE <ul> from the one "Footer - Kanal" WordPress menu (no duplicated
 * items, no second menu location), DOM order is untouched so reading order
 * and tab order still run Nasional -> Video, and the split rebalances itself
 * if an editor adds or removes a channel instead of silently overflowing a
 * fixed five-row template. Ten equal-height items balance 5 + 5.
 *
 * Gated at 700px, not at the footer grid's own 768px breakpoint: between 481
 * and 768px the footer is already two columns, so at the low end of that
 * range each sub-column would be ~70px and "Gaya Hidup" would wrap. 700px is
 * where the Kanal column is wide enough (~123px per sub-column) to hold the
 * longest label on one line.
 */
@media ( min-width: 1101px ) {
	.footer-col--channels .footer-menu {
		display: block;
		columns: 2;
		column-gap: var( --wp--preset--spacing--xl );
	}

	.footer-col--channels .footer-menu li {
		break-inside: avoid;
		margin-bottom: var( --wp--preset--spacing--sm );
	}

	.footer-col--channels .footer-menu li:last-child {
		margin-bottom: 0;
	}
}

.site-footer__bottom {
	border-top: 1px solid rgba( 247, 245, 240, 0.15 );
	padding-block: var( --wp--preset--spacing--md );
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--metadata );
	color: var( --wp--preset--color--muted );
}

.site-footer__bottom p {
	margin: 0;
}

@media ( max-width: 1100px ) {
	.site-footer__columns {
		grid-template-columns: 1fr 1fr;
	}
}

@media ( max-width: 390px ) {
	.site-footer__columns {
		grid-template-columns: 1fr;
	}
}

/* ==========================================================================
   Sticky compact navigation (Stage 19)
   --------------------------------------------------------------------------
   Nav dipindahkan keluar dari <header id="masthead"> di header.php supaya
   position: sticky benar-benar bekerja: sticky selalu dibatasi kotak
   induknya, dan selama nav masih anak <header> ia akan langsung "lepas"
   begitu header habis — persis di titik kita justru ingin ia mulai
   menempel. Sebagai saudara <body>, batas stickynya menjadi seluruh
   dokumen. Konsekuensi lain yang disengaja: karena elemen nav-nya sama
   (bukan bar kedua), tidak ada satu pun link yang digandakan untuk screen
   reader, dan tidak ada layout shift karena nav tidak pernah keluar dari
   alur dokumen.
   ========================================================================== */

.nav-sentinel {
	height: 0;
	margin: 0;
}

.primary-nav {
	position: sticky;
	top: 0;
	z-index: 100;
	background-color: var( --wp--preset--color--paper );
}

/* Admin bar hanya fixed pada >=783px — lihat catatan di navigation.js. */
.admin-bar .primary-nav {
	top: 32px;
}

@media ( max-width: 1100px ) {
	.admin-bar .primary-nav {
		top: 0;
	}
}

/*
 * Bar yang sedang menempel menutupi ~54px teratas viewport, jadi target
 * anchor (skip-link ke #primary, tautan #newsletter di masthead, heading
 * ber-id di dalam artikel) harus berhenti di bawahnya — bukan persis di
 * bawah tepi atas viewport tempat bar berada.
 */
:target,
#primary {
	scroll-margin-top: 68px;
}

.admin-bar :target,
.admin-bar #primary {
	scroll-margin-top: 100px;
}

/* Wordmark + aksi ringkas: hanya ada saat bar menempel. */
.primary-nav__brand,
.primary-nav__actions {
	display: none;
}

.primary-nav__brand {
	font-family: var( --wp--preset--font-family--editorial-display );
	font-size: var( --wp--preset--font-size--small );
	letter-spacing: 0.02em;
	text-transform: uppercase;
	text-decoration: none;
	color: var( --wp--preset--color--ink );
	white-space: nowrap;
}

.primary-nav__actions {
	align-items: center;
	gap: var( --wp--preset--spacing--sm );
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--metadata );
	text-transform: uppercase;
}

.primary-nav__actions a {
	text-decoration: none;
	color: var( --wp--preset--color--ink );
	white-space: nowrap;
}

.primary-nav__kirim {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 7px;
	padding: 7px 15px;
	border-radius: 7px;
	background: var( --wp--preset--color--accent );
	color: var( --wp--preset--color--on-dark ) !important;
	font-weight: 600;
	letter-spacing: 0.03em;
	text-transform: none;
}

.primary-nav__kirim:hover {
	background: var( --wp--preset--color--accent-dark );
}

.primary-nav__search-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 34px;
	padding: 0;
	border: 1px solid var( --wp--preset--color--line );
	border-radius: 7px;
	background: var( --wp--preset--color--surface );
	color: var( --wp--preset--color--ink );
}

.primary-nav__search-toggle:hover {
	border-color: var( --wp--preset--color--accent );
	background: var( --wp--preset--color--surface );
	color: var( --wp--preset--color--accent );
}

@media ( min-width: 1101px ) {
	.primary-menu {
		flex: 1 1 auto;
		justify-content: center;
	}

	.primary-nav__actions {
		display: flex;
		flex: 0 0 auto;
	}
}

.primary-nav__search {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
}

/* Kaca pembesar murni CSS — tidak ada request aset tambahan. */
.primary-nav__search-icon {
	position: relative;
	display: inline-block;
	width: 12px;
	height: 12px;
	border: 2px solid currentColor;
	border-radius: 50%;
}

.primary-nav__search-icon::after {
	content: "";
	position: absolute;
	top: 10px;
	left: 9px;
	width: 7px;
	height: 2px;
	background-color: currentColor;
	transform: rotate( 45deg );
}

.primary-nav__subscribe {
	background-color: var( --wp--preset--color--accent );
	color: var( --wp--preset--color--on-dark ) !important;
	padding: var( --wp--preset--spacing--2-xs ) var( --wp--preset--spacing--sm );
	min-height: 32px;
	display: inline-flex;
	align-items: center;
}

.primary-nav__subscribe:hover {
	background-color: var( --wp--preset--color--accent-dark );
}

/* --- State menempel --- */
.primary-nav.is-stuck {
	border-bottom: 1px solid var( --wp--preset--color--line );
	box-shadow: 0 1px 3px rgba( 23, 23, 23, 0.08 );
}

/*
 * Baris ringkas (wordmark + menu + aksi dalam SATU baris) hanya dipasang mulai
 * 1440px, bukan 960px.
 *
 * Root cause bug "kanvas desktop-mode" (Stage 19G): susunan itu butuh ~1271px
 * lebar konten container (terukur — wordmark 128 + menu 897 + aksi 270 + 2 gap
 * md), sedangkan `.site-container` hanya menyediakan `wide-size - 64px`:
 * 916px pada 980px, 1216px pada 1280/1366px. Kurang lebar, dan `flex-wrap:
 * nowrap` melarang menu memakai jalan keluar yang dipakai state istirahat
 * (membungkus ke baris kedua). Akibatnya <li> diperas di bawah lebar kata:
 * label <a> ikut `overflow-wrap: anywhere` dari base.css sehingga min-content-
 * nya jadi SATU karakter — "BERANDA" terukur 10.8px x 176px, menumpuk vertikal
 * satu huruf per baris — sementara <button> mega menu (tanpa deklarasi itu)
 * bertahan di lebar kata dan mendorong baris melewati tepi kanvas:
 * documentElement.scrollWidth 1303px pada clientWidth 980px.
 *
 * Overflow itulah yang membuat seluruh halaman tampak rusak di Chrome
 * "Desktop site" pada ponsel: header/nav menjulur sampai 1303px sementara
 * main/section/newsletter/footer berhenti di 980px (`width: 100%` terhadap
 * ICB), lalu Chrome mengecilkan skala agar kanvas 1303px muat di layar —
 * itu strip kosong di kanan, tata letak yang seolah menempel ke kiri, dan
 * kartu/tipografi yang mengecil berlebihan.
 *
 * 1440px bukan angka perangkat: itu breakpoint tempat base.css menaikkan
 * `--wp--style--global--wide-size` ke 1440px, satu-satunya titik di mana
 * lebar konten container (1376px) akhirnya melampaui ~1271px yang dibutuhkan.
 * Di bawahnya bar menempel mempertahankan tampilan istirahatnya (menu terpusat
 * yang boleh membungkus), sehingga lebar DAN tinggi kanvas tidak berubah sama
 * sekali saat sticky aktif.
 */
@media ( min-width: 1440px ) {
	.primary-nav.is-stuck .primary-nav__inner {
		justify-content: space-between;
		gap: var( --wp--preset--spacing--md );
		min-height: 52px;
	}

	.primary-nav.is-stuck .primary-nav__brand,
	.primary-nav.is-stuck .primary-nav__actions {
		display: flex;
		align-items: center;
		animation: aa-nav-fade 140ms ease-out both;
	}

	/*
	 * `flex-wrap` sengaja dibiarkan mewarisi `wrap` dari `.primary-menu`.
	 * Pada lebar ini seluruh item memang muat dalam satu baris, jadi wrap
	 * tidak mengubah tampilan; tetapi kalau kelak ada item menu tambahan atau
	 * nama situs yang lebih panjang, baris cukup membungkus — tidak kembali
	 * meremas label jadi tumpukan satu karakter seperti `nowrap` dulu.
	 */
	.primary-nav.is-stuck .primary-menu {
		padding-block: 0;
		gap: var( --wp--preset--spacing--md );
		justify-content: center;
	}
}

@keyframes aa-nav-fade {
	from {
		opacity: 0;
	}

	to {
		opacity: 1;
	}
}

/* Mobile: baris ringkas berisi tombol menu, wordmark, search, dan Masuk.
   Berlangganan sengaja disembunyikan di sini — ruang 360px tidak cukup
   tanpa memicu horizontal overflow. */
@media ( max-width: 1100px ) {
	.utility-bar__inner {
		min-height: 34px;
	}

	.utility-bar__actions {
		gap: var( --wp--preset--spacing--sm );
	}

	.site-branding {
		padding-block: var( --wp--preset--spacing--lg );
	}

	.primary-nav__inner {
		flex-wrap: wrap;
	}

	.primary-nav__actions {
		display: flex;
		margin-left: auto;
	}

	.primary-nav.is-stuck .primary-nav__kirim {
		display: none;
	}

	.primary-nav.is-stuck .primary-nav__inner {
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
		gap: var( --wp--preset--spacing--xs );
		min-height: 48px;
		flex-wrap: wrap;
	}

	.primary-nav.is-stuck .mobile-menu-toggle {
		margin-block: 0;
		border: none;
		padding-inline: 0;
	}

	/*
	 * Tombol menu dan aksi memakai lebar alaminya; wordmark-lah yang
	 * menyusut. Tanpa `flex: 1 1 0` + `min-width: 0` di sini, nama situs
	 * yang panjang ("Aspirasi Aktual (Local)" saat QA) mendorong aksi ke
	 * baris kedua dan tinggi bar melar dari 48px menjadi 98px.
	 */
	.primary-nav.is-stuck .mobile-menu-toggle,
	.primary-nav.is-stuck .primary-nav__actions {
		flex: 0 0 auto;
	}

	.primary-nav.is-stuck .primary-nav__actions {
		display: flex;
		align-items: center;
		gap: var( --wp--preset--spacing--xs );
	}

	.primary-nav.is-stuck .primary-nav__brand {
		display: block;
		flex: 1 1 0;
		min-width: 0;
		overflow: hidden;
		white-space: nowrap;
		text-overflow: ellipsis;
		text-align: center;
	}

	.primary-nav.is-stuck .primary-nav__subscribe {
		display: none;
	}

	/*
	 * Menu accordion tetap tampil penuh di bawah baris ringkas saat dibuka.
	 *
	 * Root cause (Stage 19E, temuan QA ponsel fisik): `max-height: 70vh` di
	 * sini adalah flex item TANPA `min-height: 0`. Default UA untuk flex item
	 * adalah `min-height: auto` (content-based), yang di sejumlah mobile
	 * WebKit membuat `max-height`/`overflow-y: auto` tidak benar-benar
	 * membentuk area scroll yang berfungsi — sisa item (Opini/Sastra/Video)
	 * terpotong tanpa cara untuk mencapainya, dan baris search/MASUK
	 * (`.primary-nav__actions`, item flex berikutnya) langsung muncul
	 * menempel di bawah potongan itu. `min-height: 0` di bawah adalah
	 * perbaikannya.
	 *
	 * `70vh` (large viewport height) juga tidak ikut menyusut/melebar saat
	 * chrome browser mobile (address bar) berubah tinggi di tengah sesi —
	 * `dvh` (dynamic viewport height) dipakai sebagai override supaya batas
	 * tinggi selalu mengikuti ruang yang benar-benar terlihat saat itu;
	 * deklarasi `vh` sebelumnya dipertahankan sebagai fallback untuk browser
	 * yang belum mendukung `dvh` (properti CSS yang tidak dikenal diabaikan,
	 * bukan meng-invalidate seluruh rule).
	 *
	 * `overscroll-behavior: contain` mencegah gesture scroll yang mencapai
	 * ujung area accordion ini "menembus" ke scroll halaman utama sebelum
	 * pengguna sempat melihat item paling bawah (Video) — pengaman kedua
	 * untuk skenario yang sama seperti bug min-height di atas.
	 */
	.primary-nav.is-stuck .primary-menu.is-open {
		flex-basis: 100%;
		min-height: 0;
		max-height: calc( 100vh - 48px );
		max-height: calc( 100dvh - 48px );
		overflow-y: auto;
		overscroll-behavior: contain;
	}
}

@media ( prefers-reduced-motion: reduce ) {
	.primary-nav.is-stuck .primary-nav__brand,
	.primary-nav.is-stuck .primary-nav__actions {
		animation: none;
	}
}

/* ==========================================================================
   Mega menu Sastra (Stage 19)
   ========================================================================== */

.mega-menu__heading {
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--metadata );
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var( --wp--preset--color--text-muted );
	margin: 0 0 var( --wp--preset--spacing--xs );
}

.mega-menu__list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.mega-menu__kicker {
	display: block;
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--metadata );
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var( --wp--preset--color--accent );
}

.mega-menu__title {
	display: block;
	font-family: var( --wp--preset--font-family--editorial-display );
	font-size: var( --wp--preset--font-size--small );
	line-height: 1.35;
	color: var( --wp--preset--color--ink );
}

.mega-menu__excerpt {
	display: block;
	margin-top: var( --wp--preset--spacing--2-xs );
	font-family: var( --wp--preset--font-family--editorial-body );
	font-size: var( --wp--preset--font-size--metadata );
	line-height: 1.5;
	color: var( --wp--preset--color--text-muted );
	text-transform: none;
}

.mega-menu__empty {
	margin: 0;
	font-family: var( --wp--preset--font-family--editorial-body );
	font-size: var( --wp--preset--font-size--metadata );
	color: var( --wp--preset--color--text-muted );
	text-transform: none;
}

.mega-menu__thumb {
	display: block;
	width: 100%;
	height: auto;
	margin-bottom: var( --wp--preset--spacing--xs );
}

.mega-menu__pick {
	display: block;
	text-decoration: none;
}

@media ( min-width: 1101px ) {
	/*
	 * Panel selebar area konten, BUKAN selebar <li> SASTRA.
	 *
	 * `.primary-menu li` bersifat position: relative (dipakai dropdown biasa),
	 * jadi panel yang absolute akan berpatokan pada <li> yang hanya ~60px dan
	 * — begitu di-center dengan translateX( -50% ) — menjulur jauh melewati
	 * tepi kanan viewport (terukur 2172px pada viewport 1920px saat QA Stage
	 * 19). Karena itu item mega dikembalikan ke position: static supaya
	 * containing block-nya naik ke .primary-nav__inner, lalu panel
	 * direntangkan left/right: 0 terhadap container itu. Hasilnya lebar panel
	 * mengikuti area konten dan tidak pernah bisa menyebabkan overflow
	 * horizontal, berapa pun lebar viewport.
	 */
	.primary-nav__inner {
		position: relative;
	}

	.primary-menu .menu-item--mega {
		position: static;
	}

	.primary-menu .mega-menu {
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		/* Panel ikut mewarisi kelas .sub-menu (agar CSS/JS dropdown existing
		   tetap berlaku), termasuk min-width: 220px / max-width: 300px milik
		   dropdown biasa di atas — keduanya harus dilepas di sini, kalau
		   tidak panel terjepit jadi 300px. */
		min-width: 0;
		max-width: none;
		padding: var( --wp--preset--spacing--md ) 0 var( --wp--preset--spacing--lg );
		background-color: var( --wp--preset--color--surface );
		border: 1px solid var( --wp--preset--color--line );
		border-top: 2px solid var( --wp--preset--color--accent );
		box-shadow: 0 8px 20px -10px rgba( 23, 23, 23, 0.18 );
		z-index: 60;
	}

	/*
	 * Tanpa JavaScript, tidak ada yang pernah menutup panel (kelas .js-nav
	 * tidak pernah dipasang, sehingga aturan display:none milik .js-nav juga
	 * tidak berlaku). Panel absolute akan menggantung permanen menutupi
	 * konten; dikembalikan ke alur dokumen supaya menu tetap terbaca dan
	 * seluruh tautan Sastra tetap bisa dipakai.
	 */
	html:not( .js-nav ) .primary-menu .mega-menu {
		position: static;
		box-shadow: none;
	}

	.mega-menu__inner {
		display: grid;
		grid-template-columns: minmax( 0, 1fr ) minmax( 0, 1.4fr ) minmax( 0, 1fr );
		gap: var( --wp--preset--spacing--lg );
		align-items: start;
		text-transform: none;
	}

	.mega-menu__col--channels .mega-menu__list a {
		display: block;
		padding: var( --wp--preset--spacing--2-xs ) 0;
		font-family: var( --wp--preset--font-family--interface );
		font-size: var( --wp--preset--font-size--small );
		color: var( --wp--preset--color--ink );
		text-decoration: none;
	}

	.mega-menu__col--latest .mega-menu__item + .mega-menu__item {
		margin-top: var( --wp--preset--spacing--sm );
		padding-top: var( --wp--preset--spacing--sm );
		border-top: 1px solid var( --wp--preset--color--line );
	}

	.mega-menu__col--latest a,
	.mega-menu__col--pick a {
		text-decoration: none;
	}

	.mega-menu__col--latest a:hover .mega-menu__title,
	.mega-menu__col--pick:hover .mega-menu__title,
	.mega-menu__col--channels a:hover {
		color: var( --wp--preset--color--accent );
	}
}

/*
 * Mobile/tablet: mega menu turun menjadi accordion biasa. Kolom Pilihan
 * Redaksi selalu disembunyikan (kurasi tambahan, bukan navigasi inti).
 *
 * Kolom Terbaru diperlakukan tergantung apakah kanal punya Subkanal
 * (`.mega-menu--has-children`, lihat class-primary-nav-walker.php):
 * - Ada Subkanal (mis. Sastra: Puisi/Cerpen/Esai) — Terbaru disembunyikan,
 *   sama seperti perilaku Sastra yang sudah PASS: daftar Subkanal tetap jadi
 *   target sentuh utama, panel tidak menjadi dinding teks panjang.
 * - Tidak ada Subkanal (mis. Nasional, Politik) — Terbaru DITAMPILKAN
 *   sebagai gantinya. Tanpa ini accordion kanal semacam itu akan kosong sama
 *   sekali di mobile (tidak ada Subkanal untuk ditampilkan), yang justru
 *   melanggar syarat "child categories dan artikel harus mudah disentuh".
 */
@media ( max-width: 1100px ) {
	.mega-menu__inner {
		display: block;
	}

	.mega-menu__heading,
	.mega-menu__col--pick {
		display: none;
	}

	.mega-menu--has-children .mega-menu__col--latest {
		display: none;
	}

	.mega-menu .mega-menu__list a {
		display: block;
		min-height: 44px;
		padding: var( --wp--preset--spacing--xs ) var( --wp--preset--spacing--md );
		color: var( --wp--preset--color--ink );
		text-decoration: none;
	}

	/*
	 * Kicker/title span Terbaru hanya berguna sebagai dua baris di kolom
	 * desktop; di accordion mobile keduanya cukup jadi satu baris inline teks
	 * tautan biasa, konsisten dengan tampilan link Subkanal di sebelahnya.
	 */
	.mega-menu__col--latest .mega-menu__kicker {
		display: inline;
		font-size: inherit;
		letter-spacing: normal;
		text-transform: none;
		color: inherit;
	}

	.mega-menu__col--latest .mega-menu__kicker::after {
		content: "\2014";
		margin: 0 var( --wp--preset--spacing--2-xs );
	}

	.mega-menu__col--latest .mega-menu__title {
		display: inline;
		font-family: inherit;
		font-size: inherit;
		line-height: inherit;
	}
}
