/*
Theme Name: Subtrackers
Theme URI: https://subtrackers.org
Description: Child theme of Twenty Twenty-Five. Turns the stock reverse-chronological
             blog into a browsable reference site: a landing page instead of a feed,
             scannable card grids instead of walls of text, and article styling built
             for the tables and break-even maths these posts are made of.
Author: Subtrackers
Template: twentytwentyfive
Version: 1.0.0
Requires at least: 6.6
Tested up to: 6.8
Requires PHP: 8.0
Text Domain: subtrackers
*/

/* ---------------------------------------------------------------------------
   Tokens

   theme.json owns anything the block editor needs to know about (palette,
   fonts, layout widths). These are the values only this stylesheet uses —
   radii, shadows, the header height the sticky offsets are measured from.
--------------------------------------------------------------------------- */

:root {
	--st-page: #f4f6f8;
	--st-card: #ffffff;
	--st-ink: #111827;
	--st-muted: #5a6572;
	--st-line: #e3e7ec;
	--st-brand: #0e6b57;
	--st-brand-dark: #0a5344;
	--st-tint: #e9f3ef;
	--st-radius: 12px;
	--st-shadow: 0 1px 2px rgba(16, 24, 40, 0.05);
	--st-shadow-lift: 0 8px 24px -12px rgba(16, 24, 40, 0.28);
	--st-header-h: 60px;
}

body {
	-webkit-font-smoothing: antialiased;
}

/* Anchor targets clear the sticky header. */
:target,
.entry-content h2[id],
.entry-content h3[id] {
	scroll-margin-top: calc(var(--st-header-h) + 1rem);
}

/* ---------------------------------------------------------------------------
   Header
--------------------------------------------------------------------------- */

.st-header {
	position: sticky;
	top: 0;
	z-index: 100;
	background: var(--st-card);
	border-bottom: 1px solid var(--st-line);
	padding-top: 0;
	padding-bottom: 0;
}

.st-header__inner {
	min-height: var(--st-header-h);
	gap: 1.5rem;
}

.st-header .wp-block-site-title {
	font-size: 1.15rem;
	font-weight: 800;
	letter-spacing: -0.03em;
	line-height: 1;
}

.st-header .wp-block-site-title a {
	color: var(--st-ink);
	text-decoration: none;
}

/* The mark: a green tile with a struck-through line, for a site whose advice
   is regularly "cancel it". Drawn in CSS so there is no image to load or lose,
   and with empty content so screen readers announce the site name alone —
   generated text counts towards an element's accessible name. */
.st-header .wp-block-site-title a::before {
	content: "";
	display: inline-block;
	width: 1.35em;
	height: 1.35em;
	margin-right: 0.5em;
	border-radius: 7px;
	background:
		linear-gradient(#fff, #fff) center / 55% 2px no-repeat,
		var(--st-brand);
	vertical-align: -0.28em;
}

.st-nav {
	font-size: 0.95rem;
	font-weight: 500;
}

.st-nav .wp-block-navigation-item__content {
	color: var(--st-muted);
	text-decoration: none;
	padding: 0.35rem 0;
	border-bottom: 2px solid transparent;
}

.st-nav .wp-block-navigation-item__content:hover {
	color: var(--st-ink);
	text-decoration: none;
}

.st-nav .current-menu-item > .wp-block-navigation-item__content {
	color: var(--st-ink);
	border-bottom-color: var(--st-brand);
}

/* Compact search that lives in the header on wide screens only. Below that the
   hero, the search page and the 404 all carry a full-width field, so nothing
   is lost by hiding it. */
.st-header__search {
	flex: 0 1 15rem;
}

.st-header__search .wp-block-search__input {
	font-size: 0.9rem;
	padding: 0.45rem 0.7rem;
}

.st-header__search .wp-block-search__button {
	padding: 0.4rem 0.7rem;
}

@media (max-width: 1100px) {
	.st-header__search {
		display: none;
	}
}

/* ---------------------------------------------------------------------------
   Search field
--------------------------------------------------------------------------- */

.wp-block-search__inside-wrapper {
	background: var(--st-card);
	border: 1px solid var(--st-line);
	border-radius: 10px;
	padding: 4px;
	box-shadow: var(--st-shadow);
}

.wp-block-search__inside-wrapper:focus-within {
	border-color: var(--st-brand);
	box-shadow: 0 0 0 3px var(--st-tint);
}

.wp-block-search__input {
	border: 0;
	background: transparent;
	padding: 0.65rem 0.85rem;
	font-size: 1rem;
	color: var(--st-ink);
}

.wp-block-search__input:focus {
	outline: none;
}

.wp-block-search__button {
	border: 0;
	border-radius: 8px;
	background: var(--st-brand);
	color: #fff;
	font-weight: 600;
	padding: 0.6rem 1.1rem;
	cursor: pointer;
}

.wp-block-search__button:hover {
	background: var(--st-brand-dark);
}

.st-hero .wp-block-search {
	max-width: 32rem;
	margin-inline: auto;
}

/* On the results page the field is a way to correct the search, not the main
   event — full width reads as a form to fill in again. */
.st-archive-head .wp-block-search {
	max-width: 30rem;
	margin-top: 1rem;
}

/* ---------------------------------------------------------------------------
   Hero
--------------------------------------------------------------------------- */

.st-hero {
	text-align: center;
	padding-block: clamp(2.5rem, 6vw, 4.5rem) clamp(2rem, 4vw, 3rem);
}

.st-hero h1 {
	max-width: 18ch;
	margin-inline: auto;
	text-wrap: balance;
}

.st-hero__sub {
	max-width: 46ch;
	margin-inline: auto;
	color: var(--st-muted);
	font-size: 1.1rem;
}

.st-hero__hint {
	color: var(--st-muted);
	font-size: 0.9rem;
}

.st-hero__hint a {
	color: var(--st-muted);
}

/* ---------------------------------------------------------------------------
   Section headings on listing pages
--------------------------------------------------------------------------- */

.st-section-title {
	font-size: 0.8rem;
	font-weight: 700;
	letter-spacing: 0.09em;
	text-transform: uppercase;
	color: var(--st-muted);
	margin-bottom: 1.1rem;
	padding-bottom: 0.6rem;
	border-bottom: 1px solid var(--st-line);
}

/* ---------------------------------------------------------------------------
   Cards

   One card style, used by the post grids, the category tiles and the related
   list. The ::after on the title stretches the link over the whole card, so
   the target is the card rather than a line of text — the single biggest
   difference between this and a list of blog headlines.
--------------------------------------------------------------------------- */

.st-card {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	height: 100%;
	background: var(--st-card);
	border: 1px solid var(--st-line);
	border-radius: var(--st-radius);
	padding: 1.15rem 1.25rem 1.3rem;
	box-shadow: var(--st-shadow);
	transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.st-card:hover {
	border-color: #c8d3cf;
	box-shadow: var(--st-shadow-lift);
	transform: translateY(-2px);
}

/* Block spacing is handled by the card's own flex gap. */
.st-card > *,
.st-trust__grid > *,
.st-footer__cols > * {
	margin-block: 0;
}

.st-card .wp-block-post-title {
	font-size: 1.08rem;
	font-weight: 700;
	line-height: 1.3;
	letter-spacing: -0.015em;
}

.st-card .wp-block-post-title a {
	color: var(--st-ink);
	text-decoration: none;
}

.st-card .wp-block-post-title a::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: var(--st-radius);
}

.st-card:hover .wp-block-post-title a {
	color: var(--st-brand);
}

.st-card .wp-block-post-excerpt {
	color: var(--st-muted);
	font-size: 0.94rem;
	line-height: 1.55;
}

.st-card .wp-block-post-excerpt__more-text {
	display: none;
}

/* Category kicker */
.st-kicker,
.st-kicker a {
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--st-brand);
	text-decoration: none;
}

/* The card's own link sits above the stretched ::after so it stays clickable. */
.st-card .st-kicker a {
	position: relative;
	z-index: 1;
}

/* ---------------------------------------------------------------------------
   Category tiles (subtrackers/category-cards block)
--------------------------------------------------------------------------- */

.st-cats {
	display: grid;
	/* Narrow enough that all five categories sit on one row at desktop widths.
	   auto-fit rather than a fixed five, so adding a sixth category reflows
	   instead of overflowing. */
	grid-template-columns: repeat(auto-fit, minmax(11.5rem, 1fr));
	gap: 1rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.st-cat {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
	background: var(--st-card);
	border: 1px solid var(--st-line);
	border-radius: var(--st-radius);
	padding: 1.1rem 1.2rem;
	box-shadow: var(--st-shadow);
	transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.st-cat:hover {
	border-color: #c8d3cf;
	box-shadow: var(--st-shadow-lift);
	transform: translateY(-2px);
}

.st-cat > * {
	margin-block: 0;
}

.st-cat__name {
	font-size: 1.05rem;
	font-weight: 700;
	letter-spacing: -0.015em;
}

.st-cat__name a {
	color: var(--st-ink);
	text-decoration: none;
}

.st-cat__name a::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: var(--st-radius);
}

.st-cat:hover .st-cat__name a {
	color: var(--st-brand);
}

.st-cat__count {
	font-size: 0.85rem;
	color: var(--st-muted);
}

.st-cat__desc {
	font-size: 0.9rem;
	color: var(--st-muted);
	line-height: 1.5;
}

/* ---------------------------------------------------------------------------
   Trust strip — what makes the numbers on this site different, said once,
   where a first-time reader sees it before deciding whether to believe any of
   them.
--------------------------------------------------------------------------- */

.st-trust {
	background: var(--st-tint);
	border: 1px solid #d3e6df;
	border-radius: var(--st-radius);
	padding: clamp(1.25rem, 3vw, 2rem);
}

.st-trust__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
	gap: 1.25rem 2rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.st-trust__item h3 {
	font-size: 0.98rem;
	margin: 0 0 0.25rem;
}

.st-trust__item h3::before {
	content: "✓";
	color: var(--st-brand);
	font-weight: 700;
	margin-right: 0.45rem;
}

.st-trust__item p {
	margin: 0;
	font-size: 0.92rem;
	line-height: 1.55;
	color: #33414f;
}

/* ---------------------------------------------------------------------------
   Archive header
--------------------------------------------------------------------------- */

.st-archive-head {
	padding-block: clamp(1.75rem, 4vw, 2.75rem) 0;
}

.st-archive-head .wp-block-query-title {
	font-size: clamp(1.8rem, 1.3rem + 2vw, 2.4rem);
	margin: 0;
}

.st-archive-head .wp-block-term-description {
	color: var(--st-muted);
	max-width: 62ch;
	/* Narrower than the layout's content width, so the auto margins constrained
	   layout adds would otherwise centre it under a left-aligned heading. */
	margin: 0.5rem auto 0 0;
	font-size: 1rem;
}

/* ---------------------------------------------------------------------------
   Breadcrumbs (subtrackers/breadcrumbs block)
--------------------------------------------------------------------------- */

.st-crumbs {
	font-size: 0.85rem;
	color: var(--st-muted);
	margin-bottom: 0.9rem;
}

.st-crumbs a {
	color: var(--st-muted);
	text-decoration: none;
}

.st-crumbs a:hover {
	color: var(--st-brand);
	text-decoration: underline;
}

.st-crumbs__sep {
	margin: 0 0.45rem;
	opacity: 0.55;
}

/* ---------------------------------------------------------------------------
   The article sheet

   Posts and pages sit on a white card over the grey page, which separates the
   thing you are reading from the site around it.
--------------------------------------------------------------------------- */

.st-sheet {
	background: var(--st-card);
	border: 1px solid var(--st-line);
	border-radius: var(--st-radius);
	box-shadow: var(--st-shadow);
	padding: clamp(1.5rem, 4vw, 3.25rem) clamp(1.15rem, 4vw, 3.25rem);
	margin-block: clamp(1.5rem, 4vw, 2.5rem);
}

/* On a phone the page gutter and the sheet's own padding were stacking, which
   left the article about 275px wide on a 375px screen. Edge to edge instead,
   with the sheet's own padding setting the margin.

   Not the usual negative-margin full bleed: constrained layout sets
   `margin-left/right: auto !important` on every child and would win. A 100vw
   width with those auto margins centres the sheet on the viewport, which
   arrives at the same place without fighting the !important. The doubled class
   is there to outrank the layout rule's max-width, which is not !important but
   is otherwise equally specific. */
@media (max-width: 40rem) {
	.st-sheet.st-sheet {
		width: 100vw;
		max-width: none;
		border-inline: 0;
		border-radius: 0;
		padding-inline: 1.25rem;
	}
}

.st-article__title {
	margin-top: 0;
	text-wrap: balance;
}

.st-meta {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1rem;
	align-items: center;
	font-size: 0.88rem;
	color: var(--st-muted);
	margin-top: 0.85rem;
	padding-bottom: 1.5rem;
	border-bottom: 1px solid var(--st-line);
}

.st-meta a {
	color: var(--st-muted);
}

.entry-content {
	font-size: 1.0625rem;
	line-height: 1.7;
}

.entry-content > * + * {
	margin-top: 1.15em;
}

.entry-content h2 {
	margin-top: 2.4rem;
	padding-top: 1.6rem;
	border-top: 1px solid var(--st-line);
}

.entry-content h3 {
	margin-top: 1.9rem;
}

.entry-content ul,
.entry-content ol {
	padding-left: 1.25rem;
}

.entry-content li + li {
	margin-top: 0.45rem;
}

.entry-content a {
	color: var(--st-brand);
	text-decoration-thickness: 1px;
	text-underline-offset: 2px;
}

/* Outbound affiliate and vendor links get a marker, so a reader can tell where
   a link goes before clicking it. */
.entry-content a[target="_blank"]::after {
	content: "↗";
	font-size: 0.8em;
	margin-left: 0.15em;
	vertical-align: 0.15em;
	text-decoration: none;
	display: inline-block;
}

/* The opening disclosure and the closing sourcing note are both a lone italic
   paragraph — house style, see content/STYLE-GUIDE.md. Pulling them out of the
   body text is what stops them reading as prose the reader has to wade through.  */
.entry-content > p:first-child:has(> em:only-child),
.entry-content > p:last-child:has(> em:only-child) {
	background: #f7f9fa;
	border: 1px solid var(--st-line);
	border-left: 3px solid var(--st-brand);
	border-radius: 8px;
	padding: 0.85rem 1.1rem;
	font-size: 0.9rem;
	line-height: 1.55;
	color: #3d4854;
}

.entry-content > p:first-child:has(> em:only-child) em,
.entry-content > p:last-child:has(> em:only-child) em {
	font-style: normal;
}

/* ---------------------------------------------------------------------------
   Tables

   Article bodies are stored as raw HTML rather than block markup, so these are
   bare <table> elements with no .wp-block-table wrapper and therefore none of
   the theme's table styling. On a site whose whole argument is a price
   comparison, that is the most-read element on the page.

   assets/enhance.js wraps each one in .st-tablewrap so it scrolls sideways on
   a phone instead of forcing the page to.
--------------------------------------------------------------------------- */

.st-tablewrap {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	margin-block: 1.6rem;
	border: 1px solid var(--st-line);
	border-radius: var(--st-radius);
	background: var(--st-card);
}

.entry-content table {
	width: 100%;
	border-collapse: collapse;
	font-size: 0.94rem;
	line-height: 1.45;
}

.entry-content thead th {
	position: sticky;
	top: 0;
	background: #f2f5f7;
	text-align: left;
	font-weight: 700;
	font-size: 0.82rem;
	letter-spacing: 0.03em;
	text-transform: uppercase;
	color: #45505d;
	white-space: nowrap;
}

.entry-content th,
.entry-content td {
	padding: 0.7rem 0.9rem;
	border-bottom: 1px solid var(--st-line);
	vertical-align: top;
}

/* First column is the row label — keep it readable while the prices scroll. */
.entry-content tbody th:first-child,
.entry-content tbody td:first-child {
	font-weight: 600;
	color: var(--st-ink);
	min-width: 9rem;
}

.entry-content tbody tr:last-child td,
.entry-content tbody tr:last-child th {
	border-bottom: 0;
}

.entry-content tbody tr:hover {
	background: #fafbfc;
}

/* ---------------------------------------------------------------------------
   Table of contents, built by assets/enhance.js from the article's own h2s
--------------------------------------------------------------------------- */

.st-toc {
	background: #f7f9fa;
	border: 1px solid var(--st-line);
	border-radius: var(--st-radius);
	padding: 1rem 1.25rem;
	margin-block: 1.75rem;
}

.st-toc__title {
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.09em;
	text-transform: uppercase;
	color: var(--st-muted);
	margin: 0 0 0.6rem;
}

.st-toc ol {
	margin: 0;
	padding: 0;
	list-style: none;
	counter-reset: st-toc;
	columns: 2;
	column-gap: 2rem;
}

@media (max-width: 640px) {
	.st-toc ol {
		columns: 1;
	}
}

.st-toc li {
	break-inside: avoid;
	margin: 0 0 0.4rem;
	font-size: 0.92rem;
	line-height: 1.4;
}

.st-toc a {
	color: #33414f;
	text-decoration: none;
}

.st-toc a:hover {
	color: var(--st-brand);
	text-decoration: underline;
}

/* ---------------------------------------------------------------------------
   Related posts (subtrackers/related-posts block)
--------------------------------------------------------------------------- */

.st-related {
	margin-top: clamp(1.5rem, 4vw, 2.5rem);
}

.st-related__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
	gap: 1rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.st-related .st-card__title {
	font-size: 1.02rem;
	font-weight: 700;
	line-height: 1.3;
	letter-spacing: -0.015em;
	margin: 0;
}

.st-related .st-card__title a {
	color: var(--st-ink);
	text-decoration: none;
}

.st-related .st-card__title a::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: var(--st-radius);
}

.st-related .st-card:hover .st-card__title a {
	color: var(--st-brand);
}

.st-related .st-card__excerpt {
	margin: 0;
	font-size: 0.9rem;
	line-height: 1.5;
	color: var(--st-muted);
}

/* ---------------------------------------------------------------------------
   Pagination
--------------------------------------------------------------------------- */

.wp-block-query-pagination {
	margin-top: 2rem;
	gap: 0.4rem;
	align-items: center;
}

.wp-block-query-pagination a,
.wp-block-query-pagination .current {
	display: inline-block;
	min-width: 2.4rem;
	text-align: center;
	padding: 0.45rem 0.7rem;
	border: 1px solid var(--st-line);
	border-radius: 8px;
	background: var(--st-card);
	color: var(--st-ink);
	text-decoration: none;
	font-size: 0.92rem;
	font-weight: 600;
}

.wp-block-query-pagination a:hover {
	border-color: var(--st-brand);
	color: var(--st-brand);
}

.wp-block-query-pagination .current {
	background: var(--st-brand);
	border-color: var(--st-brand);
	color: #fff;
}

/* ---------------------------------------------------------------------------
   Footer
--------------------------------------------------------------------------- */

.st-footer {
	background: #101a24;
	color: #b9c4cf;
	margin-top: clamp(2.5rem, 6vw, 4rem);
	padding-block: clamp(2.25rem, 5vw, 3.25rem);
	font-size: 0.92rem;
}

.st-footer h2,
.st-footer h3 {
	color: #fff;
}

.st-footer__cols {
	display: grid;
	grid-template-columns: 1.4fr 1fr 1fr;
	gap: 2rem;
}

@media (max-width: 720px) {
	.st-footer__cols {
		grid-template-columns: 1fr;
		gap: 1.5rem;
	}
}

.st-footer__title {
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.09em;
	text-transform: uppercase;
	color: #7f8d9b;
	margin: 0 0 0.7rem;
}

.st-footer ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.st-footer li {
	margin-bottom: 0.4rem;
}

.st-footer a {
	color: #d5dde5;
	text-decoration: none;
}

.st-footer a:hover {
	color: #fff;
	text-decoration: underline;
}

.st-footer__brand {
	font-size: 1.1rem;
	font-weight: 800;
	letter-spacing: -0.03em;
	color: #fff;
	margin: 0 0 0.4rem;
}

.st-footer__blurb {
	margin: 0 0 1.1rem;
	max-width: 34ch;
	color: #94a2b0;
	line-height: 1.55;
}

/* The header search is hidden below 1100px, so on a phone this is the only
   search box on an article page. */
.st-footer .wp-block-search {
	max-width: 20rem;
}

.st-footer .wp-block-search__inside-wrapper {
	background: #1a2733;
	border-color: #2c3b49;
	box-shadow: none;
}

.st-footer .wp-block-search__input {
	color: #e6ecf1;
}

.st-footer .wp-block-search__input::placeholder {
	color: #7f8d9b;
}

.st-footer__legal {
	margin-top: 2rem;
	padding-top: 1.35rem;
	border-top: 1px solid #22303d;
	font-size: 0.82rem;
	line-height: 1.6;
	color: #8998a6;
}

.st-footer__legal p {
	margin: 0 0 0.4rem;
	max-width: 75ch;
}

.st-footer__legal a {
	color: #b9c4cf;
	text-decoration: underline;
}

/* ---------------------------------------------------------------------------
   404
--------------------------------------------------------------------------- */

.st-404 {
	text-align: center;
	padding-block: clamp(2.5rem, 6vw, 4rem) 1rem;
}

.st-404 p {
	color: var(--st-muted);
	max-width: 48ch;
	margin-inline: auto;
}

/* ---------------------------------------------------------------------------
   Skip link — TT5 provides one; make it visible against this header.
--------------------------------------------------------------------------- */

.skip-link:focus {
	background: var(--st-brand);
	color: #fff;
}

@media (prefers-reduced-motion: reduce) {
	.st-card,
	.st-cat {
		transition: none;
	}

	.st-card:hover,
	.st-cat:hover {
		transform: none;
	}
}
