/*
Theme Name: Home Plant
Theme URI: https://github.com/amornnan/wp-home-plant
Author: Home Plant
Description: An old-newspaper block theme for cataloguing the plants growing around the house. Front-end only - the plant post type, fields and API live in the Home Plant Core plugin so the catalogue survives a theme change.
Version: 1.0.0
Requires at least: 6.5
Tested up to: 6.8
Requires PHP: 8.1
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: home-plant
Tags: blog, portfolio, one-column, block-patterns, full-site-editing, custom-colors, editor-style
*/

/*
 * theme.json holds every colour, type size and spacing step, and WordPress
 * turns each into a --wp--preset--* custom property. Nothing here restates a
 * value: every colour below is read back out of one of those properties, so
 * there is exactly one place to change a colour.
 *
 * What lives here is what theme.json cannot express - the paper texture, the
 * masthead rules, the justified columns and the drop cap, the ruled table of
 * particulars, and the index listing.
 */

/* ---------------------------------------------------------------------------
 * The paper
 *
 * Two procedural noise layers, both inline SVG data URIs: no image file, no
 * request, nothing to manage. Grain alone reads as screen noise - the coarse
 * mottle is what makes it read as aged stock. Both opacities stay low enough
 * that body-text contrast is untouched.
 * ------------------------------------------------------------------------ */

body {
	min-height: 100vh;
	background-image:
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23g)' opacity='0.05'/%3E%3C/svg%3E"),
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='600' height='600'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.012' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='600' height='600' filter='url(%23m)' opacity='0.04'/%3E%3C/svg%3E");
}

/* ---------------------------------------------------------------------------
 * Shared devices
 *
 * A 3px rule separates major regions, a 1px dark rule separates sections, a
 * 1px pale rule separates rows. Secondary information is italic, never
 * capitalised.
 * ------------------------------------------------------------------------ */

.aside,
.aside p,
.plant-scientific-name,
.plant-fact__label {
	font-style: italic;
	color: var(--wp--preset--color--muted);
}

.aside a,
.plate__caption a {
	color: var(--wp--preset--color--primary);
}

/* A short sage line closing a page or section head. */
.ornament {
	width: 4.25rem;
	margin: 1.4rem auto 0;
	border-top: 1px solid var(--wp--preset--color--secondary);
}

/* A section head inside a region: dark hairline above, pale hairline below. */
.section-rule {
	margin-block: 0;
	padding-top: 0.55rem;
	border-top: 1px solid var(--wp--preset--color--contrast);
}

.section-head {
	text-align: center;
}

.section-head .aside {
	margin-top: 0.4rem;
}

/* Links inside running text keep an affordance now that they are not
   underlined: a pale rule that darkens on hover. */
.wp-block-post-content a,
.newsprint a,
.plant-fact__value a,
.wp-block-post-terms a,
.wp-block-post-excerpt a {
	border-bottom: 1px solid var(--wp--preset--color--tertiary);
}

.wp-block-post-content a:hover,
.newsprint a:hover,
.plant-fact__value a:hover,
.wp-block-post-terms a:hover,
.wp-block-post-excerpt a:hover {
	border-bottom-color: var(--wp--preset--color--primary);
}

/* Keyboard focus is visible on every link, filter and control. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
	outline: 2px solid var(--wp--preset--color--primary);
	outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
 * Masthead
 *
 * hairline / dateline strip / hairline / wordmark / 3px heavy rule / gap /
 * hairline / section navigation / hairline. Every rule is a border on
 * something that was going to be there anyway, so the markup carries no
 * empty spacer elements.
 * ------------------------------------------------------------------------ */

.masthead__dateline {
	padding-block: 0.4rem;
	border-top: 1px solid var(--wp--preset--color--contrast);
	border-bottom: 1px solid var(--wp--preset--color--contrast);
	font-size: var(--wp--preset--font-size--small);
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
}

.masthead__dateline p {
	margin: 0;
}

.masthead__wordmark {
	padding-block: 1.6rem 1.4rem;
	border-bottom: 3px solid var(--wp--preset--color--contrast);
}

.leaf-mark {
	flex: none;
	display: block;
	color: var(--wp--preset--color--primary);
}

.masthead__wordmark .wp-block-site-title {
	margin: 0;
}

nav.masthead__nav {
	margin-top: 3px;
	padding-block: 0.5rem;
	border-top: 1px solid var(--wp--preset--color--contrast);
	border-bottom: 1px solid var(--wp--preset--color--contrast);
}

nav.masthead__nav .wp-block-navigation__container {
	gap: 2.1rem;
}

/* The one place `primary` marks state: the section the reader is inside. */
body.post-type-archive-plant nav.masthead__nav a[href$="/plants/"],
body.single-plant nav.masthead__nav a[href$="/plants/"],
body.tax-plant_location nav.masthead__nav a[href$="/plants/"] {
	color: var(--wp--preset--color--contrast);
	border-bottom: 1.5px solid var(--wp--preset--color--primary);
	padding-bottom: 1px;
}

@media (max-width: 40rem) {
	/* The paper's own line is the first thing to go: the issue number and the
	   date are what a reader actually uses. */
	.masthead__dateline-line {
		display: none;
	}

	/* Below this the two survivors no longer fit side by side, and left to
	   themselves they wrapped into a ragged two lines that read as an accident.
	   Stacking them centred is the same information, deliberately set. */
	.masthead__dateline {
		flex-direction: column;
		align-items: center;
		gap: 0.1rem;
		letter-spacing: 0.08em;
		line-height: 1.35;
		text-align: center;
	}
}

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

.site-footer p {
	margin: 0;
}

/* The rule sits on the note, not on the group, so it stops at the same
   measure as every other rule on the page. */
.site-footer__note {
	padding-top: 1.4rem;
	border-top: 3px solid var(--wp--preset--color--contrast);
}

/* ---------------------------------------------------------------------------
 * Justified columns and the drop cap
 *
 * Below 48rem this collapses to a single column and gives up justification -
 * two columns on a phone would be four words wide.
 * ------------------------------------------------------------------------ */

.newsprint {
	column-count: 2;
	column-gap: 2.7rem;
	column-rule: 1px solid var(--wp--preset--color--tertiary);
	text-align: justify;
	hyphens: auto;
}

.newsprint > *,
.newsprint .wp-block-post-content > * {
	margin-block: 0;
}

.newsprint > * + *,
.newsprint .wp-block-post-content > * + * {
	margin-block-start: 0.9em;
}

/* The opening paragraph carries a floated initial, and a float inside a
   fragmented context can be left behind when the paragraph breaks across
   columns - the initial ends up alone in one column and its own word in the
   other. Keeping the lead paragraph whole is also what a newspaper does. */
.newsprint__opening,
.article__body .wp-block-post-content > p:first-of-type {
	break-inside: avoid;
}

.newsprint__opening::first-letter,
.article__body .wp-block-post-content > p:first-of-type::first-letter {
	float: left;
	font-size: 3.6em;
	line-height: 0.78;
	font-weight: 600;
	padding: 0.06em 0.1em 0 0;
	color: var(--wp--preset--color--contrast);
}

@media (max-width: 48rem) {
	.newsprint {
		column-count: 1;
		text-align: left;
		hyphens: manual;
	}
}

/* ---------------------------------------------------------------------------
 * Plates
 *
 * The frame is always drawn, so an entry with no photograph still holds its
 * place in the page with a sage leaf on pale stock rather than collapsing.
 * ------------------------------------------------------------------------ */

.plate__frame {
	position: relative;
	display: grid;
	place-items: center;
	aspect-ratio: 5 / 2;
	overflow: hidden;
	background-color: var(--wp--preset--color--tertiary);
	border: 1px solid var(--wp--preset--color--contrast);
	border-radius: 4px;
}

.plate__mark {
	color: var(--wp--preset--color--secondary);
}

.plate__frame .wp-block-post-featured-image {
	position: absolute;
	inset: 0;
	margin: 0;
}

.plate__frame .wp-block-post-featured-image img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	border-radius: 0;
}

.plate__caption {
	margin-top: 0.55rem;
	align-items: baseline;
	font-size: var(--wp--preset--font-size--small);
}

.plate__caption p,
.plate__caption .wp-block-post-title,
.plate__caption .wp-block-post-excerpt p {
	margin: 0;
	font-size: var(--wp--preset--font-size--small);
}

.plate__caption .wp-block-post-excerpt {
	font-style: italic;
	color: var(--wp--preset--color--muted);
}

.plate__caption .wp-block-post-title a {
	color: var(--wp--preset--color--contrast);
}

/* The comma only exists when there is a binomial to separate. */
.plate__caption:has(.plant-scientific-name:not(:empty)) .wp-block-post-title::after {
	content: ",";
}

/* ---------------------------------------------------------------------------
 * Front page
 * ------------------------------------------------------------------------ */

.front__aside {
	border-left: 1px solid var(--wp--preset--color--tertiary);
	padding-left: var(--wp--preset--spacing--40);
}

.lead__statement {
	max-width: 38rem;
	margin-inline: auto;
	letter-spacing: -0.012em;
}

.lead__standfirst {
	max-width: 30rem;
	margin-inline: auto;
	margin-top: 0.6rem;
}

.lead__plate {
	margin-top: 1.6rem;
}

.lead .newsprint {
	margin-top: 1.4rem;
	padding-top: 1.4rem;
	border-top: 1px solid var(--wp--preset--color--tertiary);
}

.lead__action {
	margin-top: 1.8rem;
}

.aside-section__head {
	margin-block: 0;
	padding-top: 0.55rem;
	border-top: 1px solid var(--wp--preset--color--contrast);
	border-bottom: 1px solid var(--wp--preset--color--tertiary);
	padding-bottom: 0.5rem;
}

.brief {
	padding-block: 0.7rem;
	border-bottom: 1px solid var(--wp--preset--color--tertiary);
}

.brief__title {
	margin: 0;
	line-height: 1.2;
}

.brief__meta {
	align-items: baseline;
	column-gap: 0.35em;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--muted);
}

.brief__meta p,
.brief__meta .wp-block-post-date {
	margin: 0;
	font-style: italic;
	color: var(--wp--preset--color--muted);
}

.brief__meta .plant-scientific-name:not(:empty)::after {
	content: ",";
}

/* The location index, the one place a dotted leader belongs. */
.leaders {
	list-style: none;
	margin: 0.5rem 0 0;
	padding: 0;
}

.leaders__row {
	margin: 0;
}

.leaders__link {
	display: flex;
	align-items: baseline;
	gap: 0.45rem;
	padding-block: 0.3rem;
}

.leaders__label {
	color: var(--wp--preset--color--contrast);
}

.leaders__link:hover .leaders__label {
	color: var(--wp--preset--color--primary);
}

.leaders__dots {
	flex: 1 1 auto;
	border-bottom: 1px dotted var(--wp--preset--color--secondary);
	transform: translateY(-0.28em);
}

.leaders__count {
	color: var(--wp--preset--color--muted);
	font-variant-numeric: tabular-nums;
}

.leaders__total {
	margin-top: 0.7rem;
	padding-top: 0.7rem;
	border-top: 1px solid var(--wp--preset--color--tertiary);
}

@media (max-width: 781px) {
	.front__aside {
		border-left: 0;
		border-top: 3px solid var(--wp--preset--color--contrast);
		padding-left: 0;
		padding-top: var(--wp--preset--spacing--30);
	}
}

/* ---------------------------------------------------------------------------
 * The index
 *
 * Heading, search, filters and listing all sit in the same measure. Density
 * beats generosity here: the page exists to be looked something up in.
 * ------------------------------------------------------------------------ */

.index-search {
	position: relative;
	max-width: 38rem;
	margin-inline: auto;
}

.index-search__glyph {
	position: absolute;
	top: 50%;
	left: 0.95rem;
	transform: translateY(-50%);
	z-index: 1;
	pointer-events: none;
	color: var(--wp--preset--color--secondary);
}

.index-search .wp-block-search__inside-wrapper {
	background-color: transparent;
	border: 1px solid var(--wp--preset--color--contrast);
	border-radius: 0;
	padding: 0;
}

.index-search .wp-block-search__input {
	border: 0;
	background: transparent;
	border-radius: 0;
	padding: 0.7rem 0.8rem 0.7rem 2.7rem;
	min-width: 0;
	color: var(--wp--preset--color--contrast);
}

/* Core's own stylesheet removes the outline from a search input inside a
   bordered wrapper, so it has to be put back explicitly. */
.index-search .wp-block-search__input:focus-visible {
	outline: 2px solid var(--wp--preset--color--primary);
	outline-offset: -2px;
}

.index-search .wp-block-search__input::placeholder {
	font-style: italic;
	color: var(--wp--preset--color--muted);
	opacity: 1;
}

.index-search .wp-block-search__button {
	margin: 0;
	border-radius: 0;
	padding-inline: 1.5rem;
}

.filters {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: baseline;
	gap: 0.3rem 1.15rem;
	margin: 0;
	padding: 0;
}

.filters__item {
	margin: 0;
}

.filters__link {
	color: var(--wp--preset--color--muted);
}

.filters__link:hover {
	color: var(--wp--preset--color--contrast);
}

.filters__link.is-current {
	color: var(--wp--preset--color--contrast);
	border-bottom: 1.5px solid var(--wp--preset--color--primary);
	padding-bottom: 1px;
}

.index-listing .wp-block-post-template {
	column-gap: 2.9rem;
	row-gap: 0;
	border-top: 3px solid var(--wp--preset--color--contrast);
}

.entry {
	align-items: flex-start;
	padding-block: 1.05rem;
	border-bottom: 1px solid var(--wp--preset--color--tertiary);
}

.entry__plate {
	flex: none;
	width: 6.75rem;
	aspect-ratio: 4 / 3;
}

.entry__plate .wp-block-post-featured-image img {
	border-radius: 3px;
}

.entry__text > * {
	margin-block: 0;
}

.entry__title {
	line-height: 1.2;
}

.entry__meta {
	align-items: baseline;
	column-gap: 0.35em;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--muted);
}

.entry__meta p,
.entry__meta .wp-block-post-terms {
	margin: 0;
	color: var(--wp--preset--color--muted);
}

.entry__meta:has(.entry__where) .entry__family:not(:empty)::after {
	content: ",";
}

/* The vertical rule between the two columns of the listing. The breakpoint
   sits above the width at which the grid itself drops to one column, so a
   single-column listing can never inherit a stray left border. */
@media (min-width: 60rem) {
	.index-listing .wp-block-post-template > :nth-child(even) .entry {
		border-left: 1px solid var(--wp--preset--color--tertiary);
		padding-left: 2.9rem;
		margin-left: -2.9rem;
	}
}

.pagination {
	padding-top: 1rem;
	border-top: 1px solid var(--wp--preset--color--contrast);
	font-size: var(--wp--preset--font-size--small);
}

/* ---------------------------------------------------------------------------
 * A single specimen
 * ------------------------------------------------------------------------ */

.article__head .wp-block-post-title {
	margin: 0;
	letter-spacing: -0.012em;
}

.article__binomial {
	margin-top: 0.5rem;
}

.article__body {
	padding-top: 1.4rem;
	border-top: 1px solid var(--wp--preset--color--tertiary);
}

/* A real dateline, the way a newspaper opens a report. Together with the
   masthead wordmark and the dateline strip this is the whole capitals budget
   for the page. */
.article__dateline {
	/* Spans both columns rather than sitting inside the first one. Left in the
	   flow it consumed two or three lines of column one and nothing of column
	   two, so the columns ended several lines apart and the rule between them
	   trailed off into whitespace. */
	column-span: all;
	margin: 0 0 0.35em;
	font-size: var(--wp--preset--font-size--small);
	letter-spacing: 0.1em;
	text-transform: uppercase;
	text-align: left;
	color: var(--wp--preset--color--contrast);
}

/* The particulars: a four-column ruled table. An empty field renders an em
   dash rather than disappearing - the shape of the table is what tells you
   which things are still unknown. */
.plant-facts {
	display: grid;
	grid-template-columns: minmax(6rem, 9rem) minmax(0, 1fr) minmax(6rem, 9rem) minmax(0, 1fr);
	margin-top: 0.5rem;
	border-top: 1px solid var(--wp--preset--color--tertiary);
	border-bottom: 1px solid var(--wp--preset--color--tertiary);
}

.plant-facts > p {
	margin: 0;
	padding: 0.65rem 1.4rem 0.65rem 0;
	overflow-wrap: anywhere;
}

.plant-facts > p:nth-child(n+5) {
	border-top: 1px solid var(--wp--preset--color--tertiary);
}

.plant-facts > p:nth-child(4n+3) {
	padding-left: 1.4rem;
	border-left: 1px solid var(--wp--preset--color--tertiary);
}

/* Bark, and only here: toxicity is the one warm thing on the site. */
.plant-fact__value--toxicity {
	color: var(--wp--preset--color--accent);
}

.care .plant-care-notes {
	margin-top: 0.8rem;
	white-space: pre-line;
}

.continued {
	padding-top: 0.9rem;
	border-top: 3px solid var(--wp--preset--color--contrast);
}

.continued__link {
	max-width: 45%;
}

.continued__link a {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	color: var(--wp--preset--color--contrast);
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.2;
}

.continued__link.has-text-align-right a {
	align-items: flex-end;
	text-align: right;
}

.continued__link a:hover {
	color: var(--wp--preset--color--primary);
}

.continued__link .post-navigation-link__label {
	font-style: italic;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--muted);
}

@media (max-width: 48rem) {
	.plant-facts {
		grid-template-columns: minmax(6rem, 9rem) minmax(0, 1fr);
	}

	.plant-facts > p:nth-child(n+3) {
		border-top: 1px solid var(--wp--preset--color--tertiary);
	}

	.plant-facts > p:nth-child(4n+3) {
		padding-left: 0;
		border-left: 0;
	}
}

@media (max-width: 30rem) {
	.plant-facts {
		grid-template-columns: minmax(0, 1fr);
	}

	.plant-facts > p {
		padding-block: 0.35rem;
	}

	.plant-facts > .plant-fact__label {
		padding-top: 0.65rem;
	}

	.plant-facts > .plant-fact__value {
		padding-bottom: 0.65rem;
		border-top: 0;
	}

	.plant-facts > p:nth-child(n+3) {
		border-top: 0;
	}

	.plant-facts > .plant-fact__label:nth-child(n+3) {
		border-top: 1px solid var(--wp--preset--color--tertiary);
	}

	.continued__link {
		max-width: 100%;
	}
}

/* ---------------------------------------------------------------------------
 * Written notes (the post index and search results)
 * ------------------------------------------------------------------------ */

.note {
	padding-block: 1.1rem;
	border-bottom: 1px solid var(--wp--preset--color--tertiary);
}

.note .wp-block-post-title {
	margin-block: 0 0.2rem;
}

.notes .wp-block-post-template {
	border-top: 3px solid var(--wp--preset--color--contrast);
}

/* Nothing on this site animates, so prefers-reduced-motion has nothing to
   turn off. Stated here so the next person does not have to check. */
