/**
 * Articles Plus — design system
 *
 * Built on tokens rather than literal values, for one practical reason: a
 * component drops into somebody else's template, and a stylesheet full of
 * hard-coded colours fights that template on every page. With tokens a site
 * owner overrides a few custom properties and the whole component follows.
 *
 * Defaults inherit wherever they can — `currentColor`, the template's own font
 * stack — so an unstyled install looks like it belongs rather than like a
 * bolted-on extension.
 *
 * Every selector below corresponds to a class the templates actually emit.
 * That sounds obvious; the first draft of this file styled a vocabulary the
 * templates did not use, and would have changed nothing at all.
 */

.com-articlesplus,
.mod-articlesplus {
	--ap-muted: .68;
	--ap-accent: #2b6ef5;
	--ap-accent-contrast: #fff;
	--ap-rule: rgba(128, 128, 128, .26);
	--ap-surface: rgba(128, 128, 128, .05);
	--ap-surface-hover: rgba(128, 128, 128, .11);

	--ap-text-xs: .74rem;
	--ap-text-sm: .86rem;
	--ap-text-lg: 1.2rem;
	--ap-text-xl: 1.45rem;

	--ap-space-1: .25rem;
	--ap-space-2: .5rem;
	--ap-space-3: .75rem;
	--ap-space-4: 1rem;
	--ap-space-5: 1.5rem;
	--ap-space-6: 2rem;

	--ap-radius: .4rem;
	--ap-radius-sm: .25rem;
	--ap-focus: 0 0 0 3px rgba(43, 110, 245, .35);
}

@media (prefers-color-scheme: dark) {
	.com-articlesplus,
	.mod-articlesplus {
		--ap-rule: rgba(255, 255, 255, .16);
		--ap-surface: rgba(255, 255, 255, .04);
		--ap-surface-hover: rgba(255, 255, 255, .09);
	}
}

/* ---------------------------------------------------------------- article */

.ap-article {
	padding-bottom: var(--ap-space-5);
	margin-bottom: var(--ap-space-5);
	border-bottom: 1px solid var(--ap-rule);
}
.ap-articles > .ap-article:last-child { border-bottom: 0; margin-bottom: 0; padding-bottom: 0; }

.ap-article__header { margin-bottom: var(--ap-space-3); }

.ap-article__title {
	font-size: var(--ap-text-xl);
	line-height: 1.25;
	letter-spacing: -.012em;
	margin: 0 0 var(--ap-space-1);
}
.ap-article__title a { text-decoration: none; color: inherit; }
.ap-article__title a:hover { text-decoration: underline; text-underline-offset: .15em; }

.ap-article__subtitle {
	font-size: var(--ap-text-lg);
	font-weight: 400;
	opacity: var(--ap-muted);
	margin: 0 0 var(--ap-space-2);
	line-height: 1.35;
}

/* Meta row: quiet, never louder than the title. Separators are drawn with
   pseudo-elements so no stray punctuation is read aloud by a screen reader. */
.ap-article__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--ap-space-1) var(--ap-space-3);
	font-size: var(--ap-text-sm);
	opacity: var(--ap-muted);
	margin-bottom: var(--ap-space-2);
}
.ap-article__meta > * + *::before {
	content: "";
	display: inline-block;
	width: 3px;
	height: 3px;
	border-radius: 50%;
	background: currentColor;
	opacity: .6;
	margin-right: .45em;
	vertical-align: middle;
}
.ap-sep { display: none; }

.ap-article__image { margin-bottom: var(--ap-space-3); }
.ap-article__image img { display: block; width: 100%; height: auto; border-radius: var(--ap-radius); }

.ap-article__intro > :first-child,
.ap-article__content > :first-child,
.ap-article__body > :first-child { margin-top: 0; }
.ap-article__intro > :last-child,
.ap-article__content > :last-child,
.ap-article__body > :last-child { margin-bottom: 0; }

.ap-article__video,
.ap-article__audio { margin: var(--ap-space-4) 0; }
.ap-article__video iframe,
.ap-article__video video { width: 100%; aspect-ratio: 16 / 9; border: 0; border-radius: var(--ap-radius); }
.ap-article__audio audio { width: 100%; }

.ap-article__more { margin-top: var(--ap-space-3); }

.ap-article__type {
	font-size: var(--ap-text-xs);
	text-transform: uppercase;
	letter-spacing: .08em;
	opacity: var(--ap-muted);
}

.ap-article__related {
	margin-top: var(--ap-space-5);
	padding-top: var(--ap-space-3);
	border-top: 1px solid var(--ap-rule);
}

/* ------------------------------------------------------ categories, tags */

.ap-article__cats,
.ap-article__tags {
	display: flex;
	flex-wrap: wrap;
	gap: var(--ap-space-1);
	margin-bottom: var(--ap-space-2);
	list-style: none;
	padding: 0;
}
.ap-article__cat,
.ap-article__tags a {
	display: inline-block;
	padding: .1rem .55rem;
	font-size: var(--ap-text-xs);
	line-height: 1.7;
	text-decoration: none;
	color: inherit;
	border: 1px solid var(--ap-rule);
	border-radius: 1rem;
	background: var(--ap-surface);
}
.ap-article__cat:hover,
.ap-article__tags a:hover { background: var(--ap-surface-hover); }

/* The primary category carries the accent, so the main filing stays legible
   among several — which is the point of the whole component. */
.ap-article__cat.is-primary {
	border-color: var(--ap-accent);
	color: var(--ap-accent);
	font-weight: 600;
}

/* -------------------------------------------------------------- readmore */

.ap-readmore {
	display: inline-flex;
	align-items: center;
	gap: .4em;
	padding: .4rem .9rem;
	font-size: var(--ap-text-sm);
	font-weight: 600;
	text-decoration: none;
	color: var(--ap-accent);
	border: 1px solid currentColor;
	border-radius: var(--ap-radius-sm);
}
.ap-readmore:hover { background: var(--ap-accent); color: var(--ap-accent-contrast); }
.ap-readmore::after { content: "\2192"; transition: transform .15s ease; }
.ap-readmore:hover::after { transform: translateX(2px); }

/* -------------------------------------------------------------- listings */

.ap-articles__links { list-style: none; padding: 0; margin: var(--ap-space-4) 0 0; }
.ap-articles__links li { padding: var(--ap-space-2) 0; border-bottom: 1px solid var(--ap-rule); }
.ap-articles__links li:last-child { border-bottom: 0; }
.ap-articles__links a { text-decoration: none; }
.ap-articles__links a:hover { text-decoration: underline; }

.ap-articles__inline-modules { margin: var(--ap-space-5) 0; }

/* Multi-column blog bands. minmax stops a narrow column squeezing text to an
   unreadable width on small screens. */
.ap-cols-2,
.ap-cols-3,
.ap-cols-4,
.ap-cols-5,
.ap-cols-6 { display: grid; gap: var(--ap-space-5); }
.ap-cols-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); }
.ap-cols-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); }
.ap-cols-4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); }

.ap-empty {
	padding: var(--ap-space-5);
	text-align: center;
	opacity: var(--ap-muted);
	border: 1px dashed var(--ap-rule);
	border-radius: var(--ap-radius);
}

/* ------------------------------------------------------------ categories */

.ap-categories { list-style: none; padding: 0; margin: 0; }
.ap-categories__item { padding: var(--ap-space-2) 0; border-bottom: 1px solid var(--ap-rule); }
.ap-categories__link { text-decoration: none; font-weight: 600; }
.ap-categories__link:hover { text-decoration: underline; }
.ap-categories__count { font-size: var(--ap-text-sm); opacity: var(--ap-muted); margin-left: var(--ap-space-1); }
.ap-categories__description { font-size: var(--ap-text-sm); opacity: var(--ap-muted); margin: var(--ap-space-1) 0 0; }
.ap-categories__level-2 { padding-left: var(--ap-space-4); }
.ap-categories__level-3 { padding-left: var(--ap-space-6); }

/* ---------------------------------------------------------------- search */

.ap-search__form { display: flex; flex-wrap: wrap; gap: var(--ap-space-2); margin-bottom: var(--ap-space-4); }
.ap-search__form input[type="search"],
.ap-search__form input[type="text"] { flex: 1 1 14rem; }
.ap-search__filters { display: flex; flex-wrap: wrap; gap: var(--ap-space-2); margin-bottom: var(--ap-space-4); }
.ap-search__count { font-size: var(--ap-text-sm); opacity: var(--ap-muted); margin-bottom: var(--ap-space-3); }
.ap-search__results { list-style: none; padding: 0; margin: 0; }
.ap-search__result { padding: var(--ap-space-3) 0; border-bottom: 1px solid var(--ap-rule); }
.ap-search__result-title { font-size: var(--ap-text-lg); margin: 0 0 var(--ap-space-1); }
.ap-search__result-title a { text-decoration: none; }
.ap-search__snippet { margin: 0; opacity: .9; }
.ap-search__snippet mark { background: rgba(255, 214, 0, .35); padding: 0 .1em; border-radius: 2px; }
.ap-search__row { display: flex; flex-wrap: wrap; gap: var(--ap-space-2); align-items: center; }
.ap-search__hint,
.ap-search__empty { opacity: var(--ap-muted); font-size: var(--ap-text-sm); }

/* -------------------------------------------------- subscribe and manage */

.ap-subscribe,
.ap-manage__form { max-width: 34rem; }
.ap-subscribe__intro,
.ap-manage__identity { margin-bottom: var(--ap-space-4); }
.ap-subscribe__field { margin-bottom: var(--ap-space-3); }
.ap-subscribe__field label { display: block; font-size: var(--ap-text-sm); margin-bottom: var(--ap-space-1); }
.ap-subscribe__field input,
.ap-subscribe__field select { width: 100%; }
.ap-subscribe__topics,
.ap-manage__topics {
	display: grid;
	gap: var(--ap-space-1);
	padding: var(--ap-space-3);
	border: 1px solid var(--ap-rule);
	border-radius: var(--ap-radius);
	background: var(--ap-surface);
	margin-bottom: var(--ap-space-3);
}
.ap-subscribe__check { display: flex; align-items: flex-start; gap: var(--ap-space-2); }
.ap-subscribe__privacy { font-size: var(--ap-text-xs); opacity: var(--ap-muted); }

.ap-manage__pending,
.ap-manage__done,
.ap-manage__invalid {
	padding: var(--ap-space-3) var(--ap-space-4);
	border-radius: var(--ap-radius);
	border-left: 4px solid var(--ap-accent);
	background: var(--ap-surface);
	margin-bottom: var(--ap-space-4);
}
.ap-manage__invalid { border-left-color: #b3382c; }
.ap-manage__optout { margin-top: var(--ap-space-5); padding-top: var(--ap-space-3); border-top: 1px solid var(--ap-rule); }
.ap-manage__optout-text { font-size: var(--ap-text-sm); opacity: var(--ap-muted); }

/* The honeypot stays in the DOM and out of sight WITHOUT display:none — some
   bots skip hidden fields, which would defeat the trap entirely. */
.ap-hp {
	position: absolute !important;
	left: -9999px !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* ----------------------------------------------------------------- index */

.ap-index__table { width: 100%; border-collapse: collapse; }
.ap-index__table th,
.ap-index__table td { padding: var(--ap-space-2); border-bottom: 1px solid var(--ap-rule); text-align: left; }
.ap-index__table th { font-size: var(--ap-text-sm); opacity: var(--ap-muted); font-weight: 600; }

/* ------------------------------------------------------------ pagination */

.ap-pagination { margin-top: var(--ap-space-6); }
.ap-pagination__counter {
	font-size: var(--ap-text-sm);
	opacity: var(--ap-muted);
	margin: 0 0 var(--ap-space-2);
	text-align: center;
}
.ap-pagination__list {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--ap-space-1);
	list-style: none;
	margin: 0;
	padding: 0;
}
.ap-pagination__link {
	display: grid;
	place-content: center;
	min-width: 2.4rem;
	min-height: 2.4rem;
	padding: 0 .5rem;
	font-variant-numeric: tabular-nums;
	text-decoration: none;
	color: inherit;
	border: 1px solid var(--ap-rule);
	border-radius: var(--ap-radius-sm);
}
.ap-pagination__link:hover { background: var(--ap-surface-hover); }

/* The current page is filled AND prints its own number - the case that came
   out as an empty box on a live install. */
.ap-pagination__link--current {
	background: var(--ap-accent);
	border-color: var(--ap-accent);
	color: var(--ap-accent-contrast);
	font-weight: 700;
}
.ap-pagination__item--gap { display: grid; place-content: center; min-width: 1.5rem; opacity: .5; }

/* ------------------------------------------------------------------ a11y */

.com-articlesplus a:focus-visible,
.com-articlesplus button:focus-visible,
.com-articlesplus input:focus-visible,
.com-articlesplus select:focus-visible {
	outline: 0;
	box-shadow: var(--ap-focus);
	border-radius: var(--ap-radius-sm);
}

@media (prefers-reduced-motion: reduce) {
	.ap-readmore::after { transition: none; }
}

@media print {
	.ap-pagination,
	.ap-readmore,
	.ap-search__form,
	.ap-subscribe { display: none; }
	.ap-article { border-bottom: 1px solid #999; page-break-inside: avoid; }
}

/* ------------------------------------------------------------------
   Blog layout: columns and flow direction
   ------------------------------------------------------------------
   The band configurations an editor writes as 1x2x2x2 or 2x3x3x3 are
   leading x intro x columns x links. Columns 5 and 6 had no rule at all,
   so choosing them silently produced a single column - the control
   appeared to do nothing rather than reporting a limit.

   FLOW DIRECTION is the other half. A grid fills ACROSS; CSS columns fill
   DOWN. Both are legitimate and the choice moves every article after the
   first, so it cannot be assumed:

       across   1 2 3        down   1 3 5
                4 5 6               2 4 6

   Implemented with two different mechanisms because no single one does
   both: grid for across, CSS multi-column for down.
   ------------------------------------------------------------------ */
.ap-cols-5 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr)); }
.ap-cols-6 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr)); }

/* Down: CSS columns fill top-to-bottom, which is exactly the wanted order.
   The grid display has to be dropped, since the two cannot coexist. */
.ap-flow-down {
	display: block;
	column-gap: var(--ap-space-5);
}

.ap-flow-down > * {
	/* An item split across a column boundary is the failure mode of CSS
	   columns: half a card at the foot of one column and half at the head
	   of the next. */
	break-inside: avoid;
	margin-bottom: var(--ap-space-5);
}

.ap-cols-2.ap-flow-down { column-count: 2; }
.ap-cols-3.ap-flow-down { column-count: 3; }
.ap-cols-4.ap-flow-down { column-count: 4; }
.ap-cols-5.ap-flow-down { column-count: 5; }
.ap-cols-6.ap-flow-down { column-count: 6; }

/* On a narrow screen every configuration collapses to one column: five
   columns on a phone is five columns of single words. */
@media (max-width: 40rem) {
	.ap-flow-down { column-count: 1 !important; }
}

@media print {
	/* Paper is not a viewport - a six-column grid sized for a screen prints
	   as unreadable slivers. Two columns is the most a page takes. */
	.ap-cols-3, .ap-cols-4, .ap-cols-5, .ap-cols-6 {
		grid-template-columns: repeat(2, 1fr);
	}

	.ap-flow-down { column-count: 2 !important; }
}
.ap-article__created,
.ap-article__modified,
.ap-article__hits { font-size: .88em; opacity: .7; }

/* Previous/next navigation. Two columns so prev sits left and next right
   even when only one exists - a lone "Next" that jumps to the left edge
   reads as "Previous" at a glance. */
.ap-article__nav {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--ap-space-4);
	margin-top: var(--ap-space-6);
	padding-top: var(--ap-space-4);
	border-top: 1px solid var(--ap-rule, rgba(128,128,128,.25));
}
.ap-article__nav-prev { grid-column: 1; }
.ap-article__nav-next { grid-column: 2; text-align: right; }
.ap-article__nav a, .ap-article__nav-prev, .ap-article__nav-next { text-decoration: none; }
.ap-article__nav-label { display: block; font-size: .78rem; text-transform: uppercase; letter-spacing: .06em; opacity: .6; }
.ap-article__nav-title { display: block; font-weight: 600; }
@media (max-width: 34rem) {
	.ap-article__nav { grid-template-columns: 1fr; }
	.ap-article__nav-next { grid-column: 1; text-align: left; }
}
@media print { .ap-article__nav { display: none; } }
.ap-article__source { display: block; font-size: .85em; opacity: .75; }
.ap-active-tags { font-size: .92em; margin: 0 0 1rem; }
.ap-active-tags__tag { font-weight: 600; margin-right: .35rem; }
.ap-active-tags__clear { margin-left: .5rem; opacity: .8; }
.ap-active-tags__label { opacity: .6; font-size: .88em; margin-right: .2rem; }
