/*
 * Base styles — Aspirasi Aktual
 * Fondasi lintas halaman: reset wajar, tipografi dasar, komponen HTML native,
 * dan aksesibilitas. Bukan styling homepage/article — itu menyusul di
 * Stage 4/5. Nilai warna & tipografi mengikuti token di theme.json.
 */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	background-color: var( --wp--preset--color--paper );
	color: var( --wp--preset--color--ink );
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--body );
	line-height: normal;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

img,
svg,
video,
canvas {
	max-width: 100%;
	height: auto;
	display: block;
}

figure {
	margin: 0;
}

figcaption {
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--small );
	color: var( --wp--preset--color--text-muted );
}

a {
	color: var( --wp--preset--color--ink );
	text-decoration: none;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.15em;
	overflow-wrap: anywhere;
}

a:hover {
	color: var( --wp--preset--color--accent );
}

h1,
h2,
h3,
h4,
h5,
h6 {
	font-family: var( --wp--preset--font-family--editorial-display );
	font-weight: 700;
	line-height: 1.2;
	margin: 0 0 var( --wp--preset--spacing--sm );
}

p {
	margin: 0 0 var( --wp--preset--spacing--md );
	/*
	 * Editorial excerpts (get_the_excerpt()) can auto-generate from content
	 * containing a long unbroken string (e.g. a URL with no spaces) — unlike
	 * <a> (overflow-wrap: anywhere above), plain text has no break opportunity
	 * and can force a card/grid track wider than its container at narrow
	 * viewports. Root cause fix for the archive-card/excerpt overflow found
	 * in Stage 16 audit — normal prose is unaffected (only kicks in when a
	 * single word would otherwise overflow).
	 */
	overflow-wrap: anywhere;
}

ul,
ol {
	margin: 0 0 var( --wp--preset--spacing--md );
	padding-left: 1.25em;
}

blockquote {
	margin: var( --wp--preset--spacing--lg ) 0;
	padding-left: var( --wp--preset--spacing--md );
	border-left: 3px solid var( --wp--preset--color--accent );
	font-family: var( --wp--preset--font-family--editorial-display );
	font-size: var( --wp--preset--font-size--lead );
	color: var( --wp--preset--color--accent );
}

hr {
	border: none;
	border-top: 1px solid var( --wp--preset--color--line );
	margin: var( --wp--preset--spacing--lg ) 0;
}

button,
input,
textarea,
select {
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--metadata );
}

button,
input[type="submit"],
input[type="button"] {
	cursor: pointer;
	border: 1px solid var( --wp--preset--color--ink );
	background-color: var( --wp--preset--color--accent );
	color: var( --wp--preset--color--on-dark );
	border-radius: 0;
	padding: var( --wp--preset--spacing--xs ) var( --wp--preset--spacing--md );
}

button:hover,
input[type="submit"]:hover,
input[type="button"]:hover {
	background-color: var( --wp--preset--color--accent-dark );
}

input,
textarea,
select {
	/*
	 * text-muted (bukan line) — border input adalah batas UI component yang
	 * wajib dikenali (WCAG 1.4.11 non-text contrast, target >=3:1). line di
	 * atas surface/paper hanya ~1.3-1.4:1 (diukur, Stage 11); text-muted
	 * ~7.3-7.9:1, jauh melewati ambang tanpa mengubah warna teks/desain lain.
	 */
	border: 1px solid var( --wp--preset--color--text-muted );
	background-color: var( --wp--preset--color--surface );
	color: var( --wp--preset--color--ink );
	padding: var( --wp--preset--spacing--xs ) var( --wp--preset--spacing--sm );
}

table {
	width: 100%;
	border-collapse: collapse;
}

th,
td {
	border-bottom: 1px solid var( --wp--preset--color--line );
	padding: var( --wp--preset--spacing--xs ) var( --wp--preset--spacing--sm );
	text-align: left;
}

/* Accessibility: screen-reader text */
.screen-reader-text {
	border: 0;
	clip: rect( 1px, 1px, 1px, 1px );
	clip-path: inset( 50% );
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}

/*
 * Accessibility: skip link.
 * Menggunakan teknik clip yang sama dengan .screen-reader-text (bukan
 * left: -9999px) — offset negatif besar memperluas scrollWidth dokumen
 * di sebagian besar browser dan menjadi penyebab horizontal overflow.
 */
.skip-link {
	position: absolute;
	top: 0;
	left: 0;
	z-index: 100000;
	clip: rect( 1px, 1px, 1px, 1px );
	clip-path: inset( 50% );
	height: 1px;
	width: 1px;
	overflow: hidden;
	white-space: nowrap;
}

.skip-link:focus {
	top: var( --wp--preset--spacing--sm );
	left: var( --wp--preset--spacing--sm );
	width: auto;
	height: auto;
	clip: auto;
	clip-path: none;
	overflow: visible;
	white-space: normal;
	background-color: var( --wp--preset--color--ink );
	color: var( --wp--preset--color--on-dark );
	padding: var( --wp--preset--spacing--xs ) var( --wp--preset--spacing--md );
}

/* Accessibility: visible focus */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
[tabindex]:focus-visible {
	outline: 2px solid var( --wp--preset--color--accent );
	outline-offset: 2px;
}

/*
 * Icon system — markup generated by inc/icons.php.
 * The global `svg { height: auto }` reset above lets an icon's box drift from
 * its width/height attributes inside flex and grid contexts, so icons are
 * pinned here and kept out of flex shrinking. Colour is always inherited so a
 * control's own hover / active / focus-visible state carries the glyph with
 * it — icons never declare their own palette.
 */
.aa-icon {
	display: block;
	flex: 0 0 auto;
	color: inherit;
	transition: color var( --t-fast, 140ms ) var( --ease-out, ease );
}

/*
 * Hit areas for icon-bearing controls.
 *
 * These live together rather than in each component stylesheet because they
 * are one accessibility guarantee, not five component decisions, and this is
 * the file that already owns the shared a11y primitives (screen-reader text,
 * skip link, focus ring). Measured before the rule existed: the submenu
 * chevron was 18x26, the search-page clear button 18x18, and the nav search
 * toggle only 36x34 at 390px.
 *
 * 24x24 is the WCAG 2.2 AA minimum and applies everywhere; 44x44 applies
 * below the theme's 1100px shell breakpoint, where interaction is touch-first.
 * Only the hit area grows — glyph size is untouched.
 */
.submenu-toggle,
.mobile-menu-toggle,
.primary-nav__search-toggle,
.search-overlay__clear,
.search-overlay__close,
.search-page-form__clear,
.search-page-form__submit,
.breaking-news__prev,
.breaking-news__next,
.breaking-news__open {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 24px;
	min-height: 24px;
}

/*
 * Icon-only controls opt out of the generic `button` padding above. That
 * padding (8px/16px) ate into a fixed-width control's content box and the
 * `svg { max-width: 100% }` reset then scaled the glyph down to fit — the
 * search submit arrow was rendering at 16px on desktop and 12px at 390px
 * instead of the declared 18px, and the ticker chevrons at 14px. The box is
 * sized by the min-width/min-height above and by each component's own rules.
 */
.submenu-toggle,
.mobile-menu-toggle,
.primary-nav__search-toggle,
.search-overlay__clear,
.search-page-form__clear,
.search-page-form__submit,
.breaking-news__prev,
.breaking-news__next,
.breaking-news__open {
	padding: 0;
}

@media ( max-width: 1100px ) {
	.submenu-toggle,
	.mobile-menu-toggle,
	.primary-nav__search-toggle,
	.search-overlay__clear,
	.search-overlay__close,
	.search-page-form__clear,
	.search-page-form__submit,
	.breaking-news__prev,
	.breaking-news__next,
	.breaking-news__open {
		min-width: 44px;
		min-height: 44px;
	}
}

/* Accessibility: reduced motion */
@media ( prefers-reduced-motion: reduce ) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

/* width: 100% — see the shared `main` sizing rule in visual-parity.css for
 * why an explicit width is load-bearing here. Only index.php emits this exact
 * class; the other templates use the .site-main--* modifiers. */
.site-main {
	width: 100%;
	max-width: var( --wp--style--global--wide-size, 1280px );
	margin-inline: auto;
	padding-inline: var( --wp--preset--spacing--lg );
}

/*
 * Desktop scale — wideSize 1280px (theme.json) was sized for laptop-class
 * viewports; at 1440/1920px it left excessive unused margin either side of
 * .site-container/.site-main (Stage 17 screenshot audit). Raising the same
 * custom property at larger breakpoints lets every section that already
 * reads var(--wp--style--global--wide-size) (site-container, site-main,
 * site-footer__columns) grow with the viewport instead of staying pinned to
 * a laptop-width column. Overrides the value WP prints on :root via
 * global-styles-inline-css — same selector specificity, wins by load order
 * (this stylesheet is enqueued after global styles).
 */
@media ( min-width: 1440px ) {
	:root {
		--wp--style--global--wide-size: 1440px;
	}
}

@media ( min-width: 1920px ) {
	:root {
		--wp--style--global--wide-size: 1600px;
	}
}

.site-footer {
	border-top: 1px solid var( --wp--preset--color--line );
	padding: var( --wp--preset--spacing--md ) var( --wp--preset--spacing--lg );
}

/*
 * Shared component: post thumbnail / placeholder, category label, time.
 * Moved here from home.css (Stage 4) — used by homepage AND by Baca Juga
 * (template-parts/single/related-posts.php, Stage 5) AND archive/search/
 * author card listings (Stage 6). Was previously only defined in home.css,
 * which is not loaded on single/archive pages — Baca Juga thumbnails were
 * unstyled there. Centralizing here (loaded on every page) fixes that and
 * avoids duplicating the same rules per page-type stylesheet.
 */
.post-thumb {
	position: relative;
	overflow: hidden;
	background-color: var( --wp--preset--color--placeholder );
	margin-bottom: var( --wp--preset--spacing--xs );
}

.post-thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/*
 * Branded placeholder — demo posts have no featured image (local fixture
 * data, Stage 17 audit). A flat placeholder-color box reads as an unloaded
 * skeleton; a diagonal duotone + centered wordmark signals an intentional
 * fallback instead. Pattern lives on the placeholder element itself (only
 * present in the no-thumbnail branch of aspirasi_aktual_render_thumbnail()),
 * so real photos are never affected.
 */
.post-thumb__placeholder {
	display: block;
	width: 100%;
	height: 100%;
	position: relative;
	background:
		repeating-linear-gradient(
			135deg,
			rgba( 23, 23, 23, 0.04 ) 0px,
			rgba( 23, 23, 23, 0.04 ) 2px,
			transparent 2px,
			transparent 14px
		),
		linear-gradient(
			135deg,
			var( --wp--preset--color--muted ) 0%,
			var( --wp--preset--color--placeholder ) 100%
		);
}

/* :empty scopes this generated watermark to placeholders with no manual
 * markup (template-parts/single/featured-media.php). homepage.php's
 * fallback renders its own AA/hairline/caption child markup inline —
 * without :empty this pseudo-element doubled up behind it. */
.post-thumb__placeholder:empty::after {
	content: "AA";
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	font-family: var( --wp--preset--font-family--editorial-display );
	font-weight: 700;
	letter-spacing: 0.08em;
	font-size: var( --wp--preset--font-size--headline-small );
	color: rgba( 23, 23, 23, 0.18 );
}

.post-thumb--hero {
	aspect-ratio: 16 / 9;
}

.post-thumb--landscape {
	aspect-ratio: 3 / 2;
}

.post-thumb--wide {
	aspect-ratio: 16 / 9;
}

.post-thumb--channel {
	aspect-ratio: 4 / 3;
	background-color: var( --wp--preset--color--muted );
}

.post-thumb--media-large {
	aspect-ratio: 2 / 1;
}

.post-card__category {
	display: inline-block;
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--small );
	font-weight: 700;
	text-transform: uppercase;
	color: var( --wp--preset--color--accent );
	text-decoration: none;
	margin-bottom: var( --wp--preset--spacing--2-xs );
}

.post-card__time {
	display: block;
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--small );
	color: var( --wp--preset--color--text-muted );
	margin-top: var( --wp--preset--spacing--2-xs );
}

/*
 * Shared component: breadcrumb trail. Moved here from single.css (Stage 5)
 * — item/link/separator styling is identical wherever breadcrumbs appear
 * (article, archive, search, author). Container width/alignment stays
 * page-scoped in single.css / archive.css since the two contexts differ
 * (centered narrow column on article, left-aligned wide on archive).
 */
.breadcrumb__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: var( --wp--preset--spacing--2-xs );
	font-family: var( --wp--preset--font-family--interface );
	font-size: var( --wp--preset--font-size--small );
	text-transform: none;
	letter-spacing: 0.04em;
}

.breadcrumb__item {
	color: var( --wp--preset--color--accent );
}

.breadcrumb__item:not( :last-child )::after {
	content: "/";
	margin-left: var( --wp--preset--spacing--2-xs );
	color: var( --wp--preset--color--line );
}

.breadcrumb__item a {
	color: inherit;
	text-decoration: none;
}

.breadcrumb__item a:hover {
	color: var( --wp--preset--color--accent-dark );
}

.breadcrumb__item--current {
	color: var( --wp--preset--color--text-muted );
	overflow-wrap: anywhere;
}

