/*
Theme Name: Making ILM Home
Theme URI: https://github.com/kleintech/wp-milmh
Author: Klein Tech
Author URI: https://www.makingilmhome.com
Description: Editorial real-estate block theme ported from the Making ILM Home (ilm-realtor) Next.js site. Paper-toned canvas, Source Serif display type, mono-caps captions, and flat rectangular surfaces. Every page is built from blocks and editable in the WordPress editor, with ready-made patterns for the homepage, agent bio, contact, and MLS search sections.
Version: 2.15.0
Requires at least: 6.6
Tested up to: 7.1
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: making-ilm-home
Tags: real-estate, editorial, blog, full-site-editing, block-patterns, custom-colors, custom-menu, featured-images, translation-ready, wide-blocks
*/

/* ==========================================================================
   This file is deliberately small.

   Colors, fonts, spacing, and block defaults all live in theme.json so the
   site owner can change them from Appearance → Editor → Styles. What is
   left here is the handful of treatments the design needs that theme.json
   cannot express: the section marker rule, the italic headline flourish,
   the card and plate behaviors inside Query Loops, and the testimonial
   rotator. Everything is a class a pattern opts into.
   ========================================================================== */

/* --- The italic brand flourish -------------------------------------------
   Almost every headline in this design ends with an italic phrase in brand
   blue. Authors get it by italicising a word in the editor — no class
   needed — so it must work off the bare <em>. */

h1 em, h2 em, h3 em, h4 em,
.wp-block-post-title em {
	font-style: italic;
	color: var(--wp--preset--color--brand);
}

/* On ink sections the flourish flips to terracotta, and headings to white. */
.has-ink-background-color h1,
.has-ink-background-color h2,
.has-ink-background-color h3,
.has-ink-background-color h4,
.has-ink-background-color .wp-block-post-title,
.has-ink-background-color .wp-block-post-title a {
	color: var(--wp--preset--color--white);
}

.has-ink-background-color h1 em,
.has-ink-background-color h2 em,
.has-ink-background-color h3 em,
.has-ink-background-color h4 em {
	color: var(--wp--preset--color--accent);
}

.has-ink-background-color .wp-block-post-date,
.has-ink-background-color .mih-mono {
	color: rgba(255, 255, 255, 0.65);
}

.has-ink-background-color .wp-block-post-excerpt__excerpt,
.has-ink-background-color p {
	color: rgba(255, 255, 255, 0.7);
}

/* Buttons default to an ink fill (theme.json → elements.button), which is
   invisible on an ink section — the search hero shipped a button the same
   color as the wall behind it. On ink they flip to terracotta with ink text:
   the palette's warm counterweight, and the only pairing here that clears
   4.5:1 (white on terracotta is 3.3:1, so the label goes dark, not light).

   Two exclusions, both deliberate: a button the editor has given its own
   color (`has-background`) has been chosen on purpose, and the outline style
   is already legible because it draws its own border. */
.has-ink-background-color .wp-block-button__link:not(.has-background):not(.is-style-outline) {
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--ink);
}

.has-ink-background-color .wp-block-button__link:not(.has-background):not(.is-style-outline):hover,
.has-ink-background-color .wp-block-button__link:not(.has-background):not(.is-style-outline):focus-visible {
	/* Lighter on hover, not darker: on a dark section brightening reads as
	   "active" where darkening reads as "disabled". Tied to the preset so it
	   still tracks a palette the owner edits in Styles; the flat value is the
	   fallback for browsers without color-mix(). */
	background-color: #d1926e;
	background-color: color-mix(in srgb, var(--wp--preset--color--accent) 82%, #ffffff);
	color: var(--wp--preset--color--ink);
}

.has-ink-background-color .wp-block-button__link:focus-visible {
	outline: 2px solid var(--wp--preset--color--white);
	outline-offset: 3px;
}

/* --- Mono-caps caption ----------------------------------------------------
   Exposed to authors as the "Mono caps" style on Paragraph and Heading. */

.mih-mono,
.is-style-mih-mono {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 12px;
	letter-spacing: 0.15em;
	text-transform: uppercase;
	line-height: 1.6;
}

.mih-mono--wide,
.is-style-mih-mono-wide {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 12px;
	letter-spacing: 0.25em;
	text-transform: uppercase;
}

/* --- Section marker -------------------------------------------------------
   A thin terracotta rule followed by a mono-caps label. Available to authors
   as the "Section marker" style on Paragraph. */

.is-style-mih-marker {
	display: flex;
	align-items: center;
	gap: 16px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 12px;
	letter-spacing: 0.3em;
	text-transform: uppercase;
	color: var(--wp--preset--color--slate);
}

.is-style-mih-marker::before {
	content: "";
	display: block;
	width: 28px;
	height: 1px;
	background: var(--wp--preset--color--accent);
	flex-shrink: 0;
}

.has-ink-background-color .is-style-mih-marker {
	color: rgba(255, 255, 255, 0.55);
}

/* --- Underlined link ------------------------------------------------------
   The "read more" treatment: text with a terracotta rule under it. Applied
   as the "Editorial link" style on Paragraph. */

.is-style-mih-link a {
	border-bottom: 1px solid var(--wp--preset--color--accent);
	padding-bottom: 2px;
	color: var(--wp--preset--color--ink);
}

.is-style-mih-link a:hover {
	color: var(--wp--preset--color--brand);
}

.has-ink-background-color .is-style-mih-link a {
	color: var(--wp--preset--color--white);
}

/* --- Image plates ---------------------------------------------------------
   The design softens image corners by exactly 2px and frames them with a
   1px line. Applied as the "Plate" style on Image and Post Featured Image. */

.is-style-mih-plate img,
.is-style-mih-plate.wp-block-post-featured-image img,
.is-style-mih-plate.wp-block-image img {
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 2px;
	background: var(--wp--preset--color--paper-soft);
	width: 100%;
	object-fit: cover;
}

/* --- Editorial numbered list ---------------------------------------------
   Services, specializations, quick actions, assurances. Authored as a
   Columns block inside a Group carrying this class: the first column holds
   the "01 /" marker, the rest is title and description. Rules are drawn by
   the container so authors can add or remove rows freely. */

.mih-rows > .wp-block-columns {
	border-bottom: 1px solid var(--wp--preset--color--line);
	padding: 36px 8px;
	margin-bottom: 0;
	align-items: center;
}

.mih-rows > .wp-block-columns:first-of-type {
	border-top: 1px solid var(--wp--preset--color--line);
}

.mih-rows .wp-block-column p {
	margin: 0;
}

/* The counter means authors never renumber by hand — add a row and the
   numbering follows. */
.mih-rows {
	counter-reset: mih-row;
}

.mih-rows > .wp-block-columns::before {
	counter-increment: mih-row;
	content: counter(mih-row, decimal-leading-zero) " /";
	font-family: var(--wp--preset--font-family--mono);
	font-size: 12px;
	letter-spacing: 0.15em;
	color: var(--wp--preset--color--accent);
	flex: 0 0 60px;
	align-self: flex-start;
}

@media (min-width: 782px) {
	.mih-rows > .wp-block-columns::before {
		flex-basis: 80px;
		align-self: center;
	}
}

/* --- Cards inside a Query Loop -------------------------------------------
   Applied to the Post Template so every card is a flush column with its
   meta pinned to the bottom, whatever the excerpt length. */

.mih-cards .wp-block-post {
	display: flex;
	flex-direction: column;
}

.mih-cards .wp-block-post-title {
	margin: 20px 0 12px;
	transition: color 0.2s ease;
}

.mih-cards .wp-block-post-title a:hover {
	color: var(--wp--preset--color--brand);
}

.mih-cards .wp-block-post-excerpt {
	flex: 1;
}

.mih-cards .wp-block-post-date {
	margin-top: auto;
	padding-top: 16px;
	border-top: 1px solid var(--wp--preset--color--line);
}

/* The episode archive's compact listen buttons. Keyed on the class the block
   itself emits, not on the card grid around it: hanging it off `.mih-cards`
   made it mean the opposite of how it reads — a *non*-compact block dropped
   into any card grid got shrunk, and a compact one used anywhere else did
   not.

   Smaller than theme.json's 16px/28px, which is sized for a page CTA and is
   a lot of button to put under every card in a grid. The block sits above the
   date rather than below it, so that the date keeps the `margin-top:auto`
   that pins it to the bottom of the card (see .wp-block-post-date above) and
   the row's date rules stay in line with each other whatever the button above
   them does. */
.mih-episode-links.is-compact {
	margin-top: 16px;
	/* The date's own border-top is the next thing down the card, and the
	   excerpt above absorbs all the slack, so without this the rule is drawn
	   hard against the button's bottom-left corner and reads as attached to
	   it rather than as the date's rule. */
	margin-bottom: 14px;
}

.mih-episode-links.is-compact .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	padding: 10px 16px;
	font-size: 12px;
}

/* `align-items: center` centres the glyph on the flex line box, which
   includes the label's descender space, so it already sits a hair below the
   cap-height centre a designer would eyeball. Sub-pixel, and worth leaving
   alone: nudging it is guesswork at this size, and an earlier `translateY`
   here was pushing it the wrong way under a rationale about horizontal mass. */
.mih-episode-links.is-compact .mih-play {
	flex-shrink: 0;
}

/* Framed card variant — used for neighborhoods, which carry a meta row. */
.mih-cards--framed .wp-block-post {
	border: 1px solid var(--wp--preset--color--line);
	background: var(--wp--preset--color--paper);
	transition: background-color 0.2s ease;
}

.mih-cards--framed .wp-block-post:hover {
	background: var(--wp--preset--color--paper-soft);
}

.mih-cards--framed .wp-block-post > :not(.wp-block-post-featured-image) {
	padding-left: 24px;
	padding-right: 24px;
}

.mih-cards--framed .wp-block-post > :last-child {
	padding-bottom: 24px;
}

/* The gap under the image belongs to the card, not to whichever block happens
   to come first. It used to live on the title as an inline `margin-top`, which
   was the same thing only as long as the title WAS first — the waterfront
   label then landed above it and sat flush on the image's border, while the
   title kept a 24px margin the label's own 12px could not collapse into
   (the card is a flex column, so margins do not collapse). Both titles now
   carry `margin-top:0` and the card pays for the gap once, whoever is first. */
.mih-cards--framed .wp-block-post > .wp-block-post-featured-image + * {
	padding-top: 24px;
}

.mih-cards--framed .wp-block-post-featured-image {
	margin-bottom: 0;
}

/* The framed card is used by both the neighborhoods archive and the
   neighborhoods rail, and they crop differently: the archive is square like
   every other archive grid, the rail stays 3:2. So the ratio a card actually
   wants belongs to the card, not to this shared rule — the archive template
   sets `"aspectRatio":"1/1"`, which core puts on the figure with `height:100%`
   inline on the img, and that wins over this. This is the fallback for the
   rail, and for a framed grid that names no ratio of its own. */
.mih-cards--framed .wp-block-post-featured-image img {
	border: 0;
	border-bottom: 1px solid var(--wp--preset--color--line);
	border-radius: 0;
	aspect-ratio: 3 / 2;
}

/* --- Bordered benefit grid -----------------------------------------------
   1px gaps reveal the line color beneath, so the grid reads as ruled cells
   rather than floating cards. */

.mih-grid-ruled {
	gap: 1px !important;
	background: var(--wp--preset--color--line);
	border: 1px solid var(--wp--preset--color--line);
}

.mih-grid-ruled > .wp-block-column,
.mih-grid-ruled > .wp-block-group {
	background: var(--wp--preset--color--paper-soft);
	padding: 32px;
	margin: 0;
}

/* --- Checklist ------------------------------------------------------------
   A 16px terracotta rule instead of a bullet. Applied as the "Checklist"
   style on List.

   Decorative only, and not to be confused with the "Task checklist" block
   further down this file — that one has tick boxes and a saved done/not-done
   state per line. This is a bullet that happens to look like a dash. The two
   share a word and nothing else; the selectors (.is-style-mih-checklist
   versus .mih-checklist) do not overlap. */

.is-style-mih-checklist {
	list-style: none;
	padding-left: 0;
}

.is-style-mih-checklist li {
	display: flex;
	align-items: center;
	gap: 16px;
	font-size: 15px;
	margin-bottom: 16px;
}

.is-style-mih-checklist li::before {
	content: "";
	display: block;
	width: 16px;
	height: 1px;
	background: var(--wp--preset--color--accent);
	flex-shrink: 0;
}

/* --- MLS button ----------------------------------------------------------
   The "Full width" toggle on the block stretches it across the container,
   which is how the homepage search strip reads. */

.mih-button--full,
.mih-button--full .wp-block-button__link {
	width: 100%;
}

.mih-button--full .wp-block-button__link {
	padding-top: 20px;
	padding-bottom: 20px;
	letter-spacing: 0.15em;
}

/* --- Testimonial rotator (dynamic block) --------------------------------- */

.mih-testimonials {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
}

.mih-testimonials__mark {
	font-family: var(--wp--preset--font-family--serif);
	font-style: italic;
	font-size: 200px;
	line-height: 0.5;
	color: var(--wp--preset--color--accent);
	user-select: none;
}

.mih-testimonials blockquote {
	display: none;
	font-family: var(--wp--preset--font-family--serif);
	font-style: italic;
	font-size: clamp(24px, 4vw, 38px);
	line-height: 1.3;
	color: var(--wp--preset--color--ink);
	max-width: 800px;
	margin: 40px 0 0;
	border: 0;
	padding: 0;
}

.mih-testimonials blockquote.is-active {
	display: block;
}

.mih-testimonials cite {
	display: block;
	font-family: var(--wp--preset--font-family--sans);
	font-style: normal;
	font-size: 13px;
	color: var(--wp--preset--color--ink-soft);
	margin-top: 40px;
}

.mih-testimonials__pager {
	display: flex;
	align-items: center;
	gap: 12px;
	margin-top: 40px;
}

.mih-testimonials__dot {
	width: 20px;
	height: 1px;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: rgba(106, 118, 132, 0.4);
	transition: all 0.2s ease;
}

.mih-testimonials__dot:hover {
	background: var(--wp--preset--color--slate);
}

.mih-testimonials__dot[aria-selected="true"] {
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: var(--wp--preset--color--ink);
}

/* --- Lead form (dynamic block) -------------------------------------------
   Underline-only inputs: transparent background, a single bottom rule. */

.mih-form {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.mih-form__row {
	display: grid;
	grid-template-columns: 1fr;
	gap: 4px;
}

@media (min-width: 600px) {
	.mih-form__row {
		grid-template-columns: repeat(2, 1fr);
		gap: 24px;
	}
}

.mih-form input[type="text"],
.mih-form input[type="email"],
.mih-form input[type="tel"],
.mih-form textarea {
	width: 100%;
	background: transparent;
	border: 0;
	border-bottom: 1px solid var(--wp--preset--color--line);
	border-radius: 0;
	padding: 16px 0;
	font-family: var(--wp--preset--font-family--sans);
	font-size: 15px;
	color: var(--wp--preset--color--ink);
	transition: border-color 0.2s ease;
}

.mih-form textarea {
	resize: vertical;
	min-height: 120px;
}

.mih-form input::placeholder,
.mih-form textarea::placeholder {
	color: var(--wp--preset--color--slate);
}

.mih-form input:focus,
.mih-form textarea:focus {
	outline: none;
	border-bottom-color: var(--wp--preset--color--brand);
}

.mih-form__consent {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	margin-top: 24px;
	font-size: 12px;
	line-height: 1.6;
	color: var(--wp--preset--color--ink-soft);
	cursor: pointer;
}

.mih-form__consent input {
	margin-top: 3px;
	flex-shrink: 0;
	accent-color: var(--wp--preset--color--brand);
}

.mih-form__hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.mih-form button {
	margin-top: 28px;
	align-self: flex-start;
	border: 0;
	border-radius: 0;
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--sans);
	font-size: 13px;
	font-weight: 500;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	padding: 16px 28px;
	transition: background-color 0.2s ease;
}

.mih-form button:hover {
	background: var(--wp--preset--color--ink-soft);
}

.mih-notice {
	padding: 16px 20px;
	border: 1px solid var(--wp--preset--color--line);
	font-size: 14px;
	margin-bottom: 24px;
}

.mih-notice--ok {
	border-color: rgba(74, 138, 149, 0.4);
	background: rgba(74, 138, 149, 0.06);
}

.mih-notice--error {
	border-color: rgba(231, 111, 81, 0.4);
	background: rgba(231, 111, 81, 0.06);
}

/* --- Neighborhood map (dynamic block) -------------------------------------
   Two states in one set of rules. Before the view script runs — and forever,
   if it never does — the frame holds a plain list of links to the
   neighborhoods, styled to look deliberate rather than unstyled. Once the
   map is built the script hides the list and the same frame holds Leaflet,
   whose own stylesheet is loaded only on pages carrying this block.

   Leaflet's stylesheet is vendored untouched, so everything below that
   reaches into a `.leaflet-*` class is scoped under `.mih-neighborhood-map`
   and lives here rather than in the vendored file. */

/* How tall this map actually ends up, resolved once. `--mih-map-height` is
   what the block asked for, printed on the frame by render.php; this is what
   the stylesheet grants, and the frame, the canvas and the detail panel all
   size from it. Deliberately one token: the panel's cap is calculated from
   the map's height, and when the two were computed separately a clamp added
   to one of them left the other reading the unclamped figure — a 600px panel
   inside a 420px frame, overflowing on top of the page above. */
.mih-neighborhood-map__frame {
	--mih-map-h: var(--mih-map-height, 420px);
	position: relative;
	min-height: var(--mih-map-h, 420px);
	border: 1px solid var(--wp--preset--color--line);
	background: var(--wp--preset--color--paper);
}

/* Taller once the layout is wide enough to give it the room: 1024px is where
   the site this was ported from steps its map up, and where a two-column hero
   stops being one column.

   Resolved once here into --mih-map-h and read from there by the canvas and
   the panel, rather than re-declaring --mih-map-height at the breakpoint. A
   custom property whose own value references itself is a cycle, and a cyclic
   property computes to nothing at all — the map would collapse to the 420px
   fallback on exactly the screens this rule exists to make taller. */
.mih-neighborhood-map__frame {
	--mih-map-h: var(--mih-map-height, 420px);
}

@media (min-width: 1024px) {
	.mih-neighborhood-map__frame {
		--mih-map-h: var(--mih-map-height-lg, var(--mih-map-height, 420px));
	}
}

/* A map that is on its way. The view script sets this attribute on every
   block it is going to turn into a map, at DOMContentLoaded, and drops it
   once the map is built — or once the build has failed, or been postponed
   because a keyboard visitor is reading the list inside the frame, in all of
   which cases the list is the block again and gets its full height back.

   `height`, not `min-height`: the frame has to be the same box before and
   after the swap, so a fallback list taller or shorter than the map it
   becomes cannot move the page when the two exchange places. It is usually
   the taller of the two — eighteen neighborhoods on the live homepage is
   1760px against a 420px map — and doing this any later means collapsing
   that difference while the visitor is looking at it. Measured: 0.74 CLS
   deferred, 0.0009 done here.

   `auto` rather than `hidden`, which is the other half of the same problem.
   While this rule holds, the list is still the only thing in the block, and
   a list clipped to three of eighteen items that a visitor can neither
   finish nor scroll is worse than the shift the rule exists to prevent. The
   frame scrolls; every link stays reachable by wheel, touch and tab.

   Deliberately not applied with JavaScript off or the library missing: the
   list is then the block for good, and must run to whatever height it needs. */
.mih-neighborhood-map[data-mih-map-pending] .mih-neighborhood-map__frame {
	height: var(--mih-map-h, 420px);
	overflow: auto;
}

.mih-neighborhood-map__canvas {
	/* Leaflet measures its container, so the height has to be real and not
	   inherited from a parent that is itself sized by its content. */
	height: var(--mih-map-h, 420px);
	width: 100%;
}

/* The service-area section's two columns come apart at the same 1024px the
   map's height steps up at, above — one breakpoint, one decision, and kept
   next to that rule so the two cannot drift apart.

   This branch reached the same 420/520 split from the other direction, with
   a `min()` clamp below the breakpoint, before v2.8.0 landed the mobile-first
   `--mih-map-height-lg` step-up. The clamp is gone rather than kept alongside
   it: two rules moving one token is exactly how this block's panel-overflow
   bug happened the first time.

   Marked `is-not-stacked-on-mobile` in the pattern precisely so core does not
   stack these at 782px instead — which would leave a tablet showing a
   half-width map that is still asking for its wide-screen height. */
@media (max-width: 1023.98px) {
	.wp-block-columns.mih-service-area {
		/* `!important` because core's own `is-not-stacked-on-mobile` rule is
		   `flex-wrap: nowrap !important`, and without matching it this rule
		   loses silently: the section stays two columns down to a 390px phone,
		   132px of text beside 132px of map, which is what it did the first
		   time this was measured. */
		flex-wrap: wrap !important;
	}

	.wp-block-columns.mih-service-area > .wp-block-column {
		flex-basis: 100% !important;
	}
}

/* The fallback list. Padded off the frame edge and set as a column of
   links, because with no map this *is* the block, not a placeholder. */
.mih-neighborhood-map__list {
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	margin: 0;
	padding: var(--wp--preset--spacing--50);
	list-style: none;
}

.mih-neighborhood-map__list[hidden] {
	display: none;
}

/* The same list, kept for screen readers only. A map showing pins can hide
   its list outright — the markers carry the same names and links. A map
   showing nothing but the service-area outline cannot: the outline is an
   unnamed SVG path, so this list is the only text saying which places it
   encloses, and `hidden` would take it out of the accessibility tree along
   with the view. Off-screen rather than absent, therefore.

   clip-path with a real width and height rather than `display: none` or
   `width: 0`, both of which remove an element from the accessibility tree in
   at least one shipping browser, and `overflow: hidden` so a long list of
   towns cannot push the page sideways from behind the map it sits under. */
.mih-neighborhood-map__list--text {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.mih-neighborhood-map__item {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.5rem 1rem;
	padding-bottom: 0.75rem;
	border-bottom: 1px solid var(--wp--preset--color--line);
}

.mih-neighborhood-map__item:last-child {
	border-bottom: 0;
	padding-bottom: 0;
}

.mih-neighborhood-map__item > a {
	font-family: var(--wp--preset--font-family--serif);
	color: var(--wp--preset--color--ink);
}

.mih-neighborhood-map__tagline {
	font-family: var(--wp--preset--font-family--serif);
	font-style: italic;
	color: var(--wp--preset--color--ink-soft);
}

/* Overlays. z-index 500 keeps them above Leaflet's tile and overlay panes
   (400) and below its controls (1000), so nothing here can cover the zoom
   buttons or the attribution — which has to stay legible to stay licensed. */
.mih-neighborhood-map__region,
.mih-neighborhood-map__key,
.mih-neighborhood-map__panel {
	position: absolute;
	z-index: 500;
	margin: 0;
	border: 1px solid var(--wp--preset--color--line);
	background: var(--wp--preset--color--paper);
}

.mih-neighborhood-map__region {
	top: 1rem;
	right: 1rem;
	padding: 0.4rem 0.6rem;
	pointer-events: none;
}

.mih-neighborhood-map__key {
	bottom: 0.75rem;
	left: 0.75rem;
	padding: 0.5rem 0.75rem;
	pointer-events: none;
}

.mih-neighborhood-map__key p {
	margin: 0 0 0.25rem;
	font-size: 0.75rem;
}

.mih-neighborhood-map__key p:last-child {
	margin-bottom: 0;
}

/* The two pin colors, drawn in SVG by the view script and so unable to come
   from a preset. Kept in step with the constants there — including the darker
   outline, which is what clears 3:1 against the paper basemap. */
.mih-neighborhood-map__swatch {
	display: inline-block;
	width: 0.625rem;
	height: 0.625rem;
	margin-right: 0.4rem;
	border: 1px solid #8f4f2c;
	border-radius: 50%;
	background: #c77a4e;
}

.mih-neighborhood-map__swatch--water {
	border-color: #2f5f68;
	background: #4a8a95;
	/* A squircle rather than a circle, echoing the wave the waterfront pin
	   carries: the two hues are 1.18:1 against each other, so the key cannot
	   lean on colour to tell them apart any more than the pins can. */
	border-radius: 30%;
}

.mih-neighborhood-map__panel {
	bottom: 3rem;
	left: 0.75rem;
	width: min(20rem, calc(100% - 1.5rem));
	padding: 1rem;
}

/* The scrim behind the mobile sheet. Hidden outright above the breakpoint
   rather than merely unstyled, so a desktop panel can never dim the page. */
.mih-neighborhood-map__scrim {
	display: none;
}

/* Phones. Two separate problems share this breakpoint.

   The tile credit wraps onto two lines here and grows up the bottom edge of
   the map, straight through the key sitting in the same corner — and because
   the credit is a control (z-index 1000) and the key an overlay (500), the row
   it swallows is "Waterfront available", the one line that says what the second
   pin colour means. The credit is a licence term and cannot be shrunk or moved,
   so the key steps up over it instead.

   And the detail card stops being a card. Inside a 420px frame a floating
   panel is capped at about 320px of scrollable text sitting on top of the map
   that is meant to be giving it context — the site this was ported from turns
   it into a full-width bottom sheet over a dimmed page at exactly this width,
   which is the ordinary phone idiom for "read this, then dismiss it". Same
   breakpoint, 640px, for both.

   Placed after every rule it overrides, not beside them: a media query carries
   no extra specificity, so declared any earlier it would simply lose. */
@media (max-width: 640px) {
	.mih-neighborhood-map__key {
		bottom: 3.5rem;
	}

	.mih-neighborhood-map__scrim {
		display: block;
		position: fixed;
		inset: 0;
		/* Under the sheet, over everything else including Leaflet's controls
		   (1000) — the credit must not stay bright over a dimmed page. */
		z-index: 1099;
		border: 0;
		padding: 0;
		background: rgba(26, 35, 50, 0.4);
		animation: mih-map-fade 240ms ease-out;
	}

	.mih-neighborhood-map__scrim[hidden] {
		display: none;
	}

	.mih-neighborhood-map__panel {
		/* Fixed to the viewport, not the frame: the frame is 420px tall and a
		   sheet that honours it is just the floating card again. Nothing in
		   the block's ancestry is transformed, which is what would otherwise
		   turn `fixed` back into `absolute` and break this silently. */
		position: fixed;
		inset: auto 0 0 0;
		/* Sized by left/right, not by `width: 100%` — which would be 100% of
		   the viewport *plus* the padding wherever this block lands somewhere
		   `box-sizing: border-box` has not been inherited, pushing the stat
		   values off the right edge. Both are set anyway rather than relying
		   on one: the sheet is the only part of this block that escapes the
		   frame, so it is the only part a host page's box model can surprise. */
		box-sizing: border-box;
		width: auto;
		max-width: none;
		max-height: 80vh;
		z-index: 1100;
		padding: 1.25rem 1rem 1.5rem;
		border-width: 1px 0 0;
		animation: mih-map-sheet 240ms cubic-bezier(0.2, 0.8, 0.2, 1);
	}

	/* The close button is the only way out once the sheet covers the map, so
	   it gets a real touch target rather than a 20px glyph in a corner. */
	.mih-neighborhood-map__close {
		top: 0.5rem;
		right: 0.5rem;
		padding: 0.5rem 0.75rem;
	}
}

/* Both animations are skipped for anyone who has asked for less movement; the
   sheet still appears, it just does not travel. */
@media (prefers-reduced-motion: reduce) {
	.mih-neighborhood-map__scrim,
	.mih-neighborhood-map__panel {
		animation: none;
	}
}

@keyframes mih-map-sheet {
	from {
		transform: translateY(100%);
	}

	to {
		transform: translateY(0);
	}
}

@keyframes mih-map-fade {
	from {
		opacity: 0;
	}

	to {
		opacity: 1;
	}
}

.mih-neighborhood-map__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--serif);
	font-size: 1.125rem;
	color: var(--wp--preset--color--ink);
}

.mih-neighborhood-map__panel .mih-neighborhood-map__tagline {
	display: block;
	margin: 0.25rem 0 0;
}

.mih-neighborhood-map__badge {
	margin: 0.5rem 0 0;
	/* The darkened teal, not the pin's own: at 12px this is body text, and
	   the bright one is 3.51:1 against paper — under the 4.5:1 floor. */
	color: #2f5f68;
}

.mih-neighborhood-map__stat {
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	margin: 0.5rem 0 0;
	padding-top: 0.5rem;
	border-top: 1px solid var(--wp--preset--color--line);
	font-size: 0.875rem;
}

.mih-neighborhood-map__description {
	margin: 0.5rem 0 0;
	font-size: 0.875rem;
	color: var(--wp--preset--color--ink-soft);
}

/* The More/Less toggle is a button because it does something, but it has to
   read as the link it looks like. */
.mih-neighborhood-map__more {
	margin-top: 0.25rem;
	padding: 0;
	border: 0;
	background: none;
	color: var(--wp--preset--color--brand);
	cursor: pointer;
}

.mih-neighborhood-map__features {
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem;
	margin: 0.75rem 0 0;
	padding: 0;
	list-style: none;
}

.mih-neighborhood-map__features li {
	padding: 0.15rem 0.4rem;
	border: 1px solid var(--wp--preset--color--line);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 0.6875rem;
	color: var(--wp--preset--color--slate);
}

/* Long descriptions push the panel taller than the frame it sits in; cap it
   and let the panel scroll rather than the map lose its bottom edge. Sized
   from the height the stylesheet granted, not the one the block asked for —
   see --mih-map-h above. */
.mih-neighborhood-map__panel {
	max-height: calc(var(--mih-map-h, 420px) - 6rem);
	overflow-y: auto;
}

.mih-neighborhood-map__link {
	display: inline-block;
	margin-top: 0.75rem;
	color: var(--wp--preset--color--brand);
}

.mih-neighborhood-map__close {
	position: absolute;
	top: 0.25rem;
	right: 0.25rem;
	padding: 0.25rem 0.5rem;
	border: 0;
	background: none;
	/* Ink-soft, not slate: slate on paper is 4.15:1 and 20px is not large
	   text, so it misses AA on the one control that dismisses the panel. */
	color: var(--wp--preset--color--ink-soft);
	font-size: 1.25rem;
	line-height: 1;
	cursor: pointer;
}

/* Leaflet's own chrome, brought into the theme. Square corners and paper
   surfaces, matching every other panel on the site. */
.mih-neighborhood-map .leaflet-container {
	font-family: inherit;
	background: var(--wp--preset--color--paper);
}

/* The paper cast. Applied to the tile pane rather than the container so it
   tints the basemap and its labels and leaves the pins, the outline and the
   controls at full strength. */
.mih-neighborhood-map .leaflet-tile-pane {
	filter: sepia(0.18) hue-rotate(-8deg) saturate(0.55) brightness(1.04);
}

.mih-neighborhood-map .leaflet-control-zoom {
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 0;
	box-shadow: none;
	overflow: hidden;
}

.mih-neighborhood-map .leaflet-control-zoom a {
	width: 28px;
	height: 28px;
	border: 0;
	background: var(--wp--preset--color--paper);
	color: var(--wp--preset--color--ink);
	font-size: 14px;
	line-height: 28px;
}

/* The tile providers' credits. Deliberately not shrunk into invisibility: a
   licence that requires attribution requires legible attribution, and slate on
   paper at 9px measures 4.13:1, under the 4.5:1 AA floor. Ink-soft at 11px is
   8.2:1 and still reads as fine print. */
.mih-neighborhood-map .leaflet-control-attribution {
	border: 1px solid var(--wp--preset--color--line);
	background: var(--wp--preset--color--paper);
	color: var(--wp--preset--color--ink-soft);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11px;
	letter-spacing: 0.02em;
}

.mih-neighborhood-map .leaflet-control-attribution a {
	color: var(--wp--preset--color--ink-soft);
	text-decoration: underline;
}

/* Leaflet gives every divIcon a white box and a border by default, which
   would frame each pin in a square. */
.mih-neighborhood-map .mih-map-pin {
	background: none;
	border: 0;
}

/* --- Header / footer ------------------------------------------------------
   Both are template parts the owner can edit visually; these rules only
   cover behavior blocks cannot express on their own. */

.mih-header {
	position: sticky;
	top: 0;
	z-index: 100;
}

.admin-bar .mih-header {
	top: 32px;
}

@media (max-width: 782px) {
	.admin-bar .mih-header {
		top: 46px;
	}
}

/* Utility bar: the phone number and Sign in sit together on the right,
   separated by the same middot the source design uses. */
/* The brokerage mark. Height comes from the block so the owner can size it;
   width follows, and the paragraph carries no margin inside the bar. */
.mih-brokerage-logo {
	margin: 0;
	display: flex;
	align-items: center;
}

.mih-brokerage-logo img {
	width: auto;
	max-width: 100%;
}

/* A blank phone number is a supported setting, and the paragraph bound to it
   then renders empty — a stray gap next to the Sign in button. */
.mih-utility__right p:empty {
	display: none;
}

/* Sign in is a button, sized to sit inside a 14px-padded utility bar rather
   than at the page's button scale: mono caps to match the rest of the strip,
   and the same flat rectangle the design uses everywhere else. */
.mih-utility__signin .wp-block-button__link {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11px;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	line-height: 1;
	padding: 9px 16px;
	border-radius: 0;
}

/* Below 600px the brokerage mark, the number and the button stop fitting on
   one line: the number crowded the button off the right edge, and at 360px it
   wrapped under the logo. The mark and the button are what have to stay — the
   number is one tap away in the menu, with a handset beside it. */
@media (max-width: 599px) {
	.mih-utility__right > p {
		display: none;
	}
}

.mih-utility__signin .wp-block-button__link:hover,
.mih-utility__signin .wp-block-button__link:focus-visible {
	background-color: var(--wp--preset--color--brand);
}

/* Header row: menu, centred wordmark, menu. The two desktop Navigation
   blocks render halves of the one menu (see inc/header.php); the third is
   the mobile overlay, and exactly one set is visible at a time. */
.mih-header .mih-header__row {
	gap: 32px;
	align-items: center;
}

.mih-header .mih-nav--mobile {
	display: none;
}

@media (min-width: 1024px) {
	.mih-header .mih-header__row {
		display: grid;
		grid-template-columns: 1fr auto 1fr;
	}

	/* Placed explicitly, not left to auto-flow. A half with nothing in it
	   renders no <nav> at all, and auto-placement would then slide the
	   wordmark into the empty column — off-centre, which is the one thing
	   this layout exists to fix. */
	.mih-header .mih-nav--left {
		grid-column: 1;
	}

	.mih-header .mih-wordmark {
		grid-column: 2;
		align-items: center;
		text-align: center;
	}

	.mih-header .mih-nav--right {
		grid-column: 3;
	}
}

@media (max-width: 1023px) {
	.mih-header .mih-nav--left,
	.mih-header .mih-nav--right {
		display: none;
	}

	.mih-header .mih-nav--mobile {
		display: flex;
	}
}

/* Widening past the breakpoint with the overlay open hides the dialog and its
   close button, and core's navigation script has no resize handler — so the
   scroll lock it put on <html> would stay on with nothing left to close.
   Releasing it here means a rotate-to-landscape loses the menu instead of
   freezing the page. */
@media (min-width: 1024px) {
	html.has-modal-open {
		overflow: visible;
	}
}

/* --- Mobile overlay -------------------------------------------------------
   Core renders the open menu as a right-aligned list of links on a white
   sheet, which is the one place on the site that looks like default
   WordPress. Dressed here as the header it covers: paper ground, the wordmark
   and close control on one row, a hairline under it, the menu set flush left
   in body type, and the phone, email and Sign in below in mono-caps.

   The lockup and the contact block are injected by inc/header.php — they
   cannot be authored as inner blocks, because all three Navigation blocks
   resolve to the same menu and anything added here would show up in the
   desktop halves too. */

.mih-header .mih-nav--mobile .wp-block-navigation__responsive-container-open {
	color: var(--wp--preset--color--ink);
}

.mih-header .mih-nav--mobile.wp-block-navigation .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay) {
	/* The block is justified right so the closed burger sits at the right
	   edge of the header, and core reuses that same setting to align the open
	   overlay's list. Re-pointing the variable turns the list flush left
	   without touching the burger. */
	--navigation-layout-justification-setting: flex-start;
	padding: 20px 24px 40px;
	background-color: var(--wp--preset--color--paper);
	color: var(--wp--preset--color--ink);
	overflow-y: auto;
	overscroll-behavior: contain;
	animation: mih-overlay-in 0.35s cubic-bezier( 0.16, 1, 0.3, 1 );
}

/* The lockup, the close button and the menu on one grid: wordmark left,
   close right, everything else across both columns. Core positions that
   button absolutely, which would drop it out of the row. */
.mih-header .mih-nav--mobile .is-menu-open .wp-block-navigation__responsive-dialog {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: center;
	/* Core hands the block's 28px gap down to every container inside the
	   overlay with `gap: inherit`, which is the menu's rhythm, not this
	   furniture's. Both containers set their own. */
	gap: 0;
	column-gap: 16px;
}

/* Placed explicitly. Leaving it to auto-flow put the close control in
   column 1 — the top-LEFT corner — on any render where the lockup did not
   make it into the markup. */
.mih-header .mih-nav--mobile .is-menu-open .wp-block-navigation__responsive-container-close {
	grid-column: 2;
	align-self: start;
	position: static;
	padding: 0;
	color: var(--wp--preset--color--ink);
}

.mih-overlay__lockup {
	display: flex;
	flex-direction: column;
	gap: 6px;
	line-height: 1;
}

.mih-overlay__wordmark {
	font-family: var(--wp--preset--font-family--serif);
	/* The same clamp WordPress generates for the site title from theme.json's
	   fluid 22px. A flat 22px here made the wordmark grow 45% as the menu
	   opened — 15.2px in the header at 390px, 22px in the overlay — which
	   reads as a different lockup rather than the same one lifted up. Keep
	   this in step with `core/site-title` in theme.json. */
	font-size: clamp(14.642px, 0.915rem + ((1vw - 3.2px) * 0.836), 22px);
	font-style: italic;
	/* Not 1: a title long enough to wrap at 320px had its ascenders and
	   descenders touching. */
	line-height: 1.15;
}

/* The upright-ILM rule is scoped to the header lockup, and this copy of the
   wordmark sits outside it. */
.mih-overlay__wordmark .mih-wordmark__upright {
	font-style: normal;
	letter-spacing: 0.03em;
	color: var(--wp--preset--color--brand);
}

.mih-overlay__tagline {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11px;
	line-height: 1.15;
	letter-spacing: 0.25em;
	text-transform: uppercase;
	color: var(--wp--preset--color--slate);
}

/* The container class is named twice on purpose: core's own
   `padding-top: calc(2rem + 24px)` on this element is also four classes, so
   without the extra one this rule wins on load order alone — and per-block
   CSS is not always printed before the theme's. */
.mih-header .mih-nav--mobile .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
	grid-column: 1 / -1;
	gap: 0;
	margin-top: 24px;
	padding-top: 8px;
	border-top: 1px solid var(--wp--preset--color--line);
}

/* Flush left, whatever the block's own justification is: the header's mobile
   Navigation is justified right so the closed burger sits at the right edge,
   and core carries that same alignment into the overlay list. */
.mih-header .mih-nav--mobile .is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__container {
	/* `items-justified-right` sits on the list as well, re-declaring the
	   variable the container set — and core reads it again for each item. */
	--navigation-layout-justification-setting: flex-start;
	width: 100%;
	gap: 0;
	align-items: stretch;
	text-align: left;
}

/* A submenu is just more rows here, indented. Core pads its container by the
   block gap, which put a 28px hole above a submenu's first child and broke
   the list's rhythm at exactly the place it matters most. */
.mih-header .mih-nav--mobile .is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation__submenu-container {
	padding-top: 0;
	padding-bottom: 0;
}

.mih-header .mih-nav--mobile .is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item {
	width: 100%;
}

.mih-header .mih-nav--mobile .is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item__content {
	/* Core makes each item a flex column, so the anchor is sized to its text:
	   "Blog" was a 33px target in a 327px row that reads as tappable end to
	   end. The row is the target. */
	display: block;
	width: 100%;
	padding: 13px 0;
	font-size: 15px;
	letter-spacing: 0.02em;
	color: var(--wp--preset--color--ink-soft);
	transition: color 0.15s ease;
}

.mih-header .mih-nav--mobile .is-menu-open .wp-block-navigation__responsive-container-content .current-menu-item > .wp-block-navigation-item__content,
.mih-header .mih-nav--mobile .is-menu-open .wp-block-navigation__responsive-container-content .current-menu-ancestor > .wp-block-navigation-item__content {
	font-weight: 500;
	color: var(--wp--preset--color--ink);
}

.mih-header .mih-nav--mobile .is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item__content:hover,
.mih-header .mih-nav--mobile .is-menu-open .wp-block-navigation__responsive-container-content .wp-block-navigation-item__content:focus-visible {
	color: var(--wp--preset--color--ink);
}

/* Sign in keeps the ink fill it has in the utility bar. Everything else in
   the overlay is type on paper, so the one control that is not navigation is
   the one thing that reads as a button. */
.mih-overlay__signin {
	margin: 4px 0 12px;
}

.mih-overlay__button {
	display: inline-block;
	padding: 10px 18px;
	background-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11px;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	line-height: 1;
	text-decoration: none;
}

.mih-overlay__button:hover,
.mih-overlay__button:focus-visible {
	background-color: var(--wp--preset--color--brand);
	color: var(--wp--preset--color--white);
}

.mih-overlay__contact {
	display: flex;
	width: 100%;
	flex-direction: column;
	gap: 4px;
	margin-top: 20px;
	padding-top: 20px;
	border-top: 1px solid var(--wp--preset--color--line);
}

.mih-overlay__line {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 6px 0;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 11px;
	letter-spacing: 0.25em;
	text-transform: uppercase;
	/* Ink-soft rather than the slate the utility bar uses for the same three
	   items: slate on paper is 4.15:1, under AA, and 11px mono-caps at 0.25em
	   is the worst case for it. These are the overlay's only links out to a
	   phone call or an inbox. */
	color: var(--wp--preset--color--ink-soft);
	text-decoration: none;
	transition: color 0.15s ease;
}

/* Optically aligned: the handset's drawn mass sits right of the box's left
   edge, so the number lines up with the menu above it rather than the icon. */
.mih-overlay__icon {
	flex: 0 0 auto;
	margin-left: -2px;
}

.mih-overlay__line:hover,
.mih-overlay__line:focus-visible {
	color: var(--wp--preset--color--ink);
}

@keyframes mih-overlay-in {
	from {
		opacity: 0;
		transform: translateY( -8px );
	}
}

@media ( prefers-reduced-motion: reduce ) {
	.mih-header .mih-nav--mobile.wp-block-navigation .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay) {
		animation: none;
	}
}

/* Site title lockup: keep "ILM" upright and brand-blue inside the italic. */
.wp-block-site-title a {
	color: inherit;
}

.mih-wordmark .wp-block-site-title {
	line-height: 1;
}

/* Scoped to the header lockup on purpose. The same span is injected into
   every site title, and the footer's sits on the ink panel — brand blue on
   ink is 1.9:1, so there the three letters keep the colour they inherit. */
.mih-wordmark .mih-wordmark__upright {
	font-style: normal;
	letter-spacing: 0.03em;
	color: var(--wp--preset--color--brand);
}

.mih-footer .wp-block-navigation {
	flex-direction: column;
	gap: 10px;
	align-items: flex-start;
	font-size: 13px;
}

.mih-footer .wp-block-heading {
	font-family: var(--wp--preset--font-family--mono);
	font-size: 12px;
	font-weight: 400;
	letter-spacing: 0.25em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.65);
}

/* Links inherit the brand blue from theme.json, which is unreadable on the
   ink footer — restate them here rather than overriding the global token.

   Navigation is set on the container, not the anchor, on purpose: core
   ships `.wp-block-navigation .wp-block-navigation-item__content
   .wp-block-navigation-item__content { color: inherit }` (the class is
   doubled to raise specificity), so any rule on the anchor loses. Colouring
   the container is what that `inherit` then picks up. */
.mih-footer a,
.mih-footer .wp-block-navigation {
	color: rgba(255, 255, 255, 0.8);
}

.mih-footer a:hover,
.mih-footer .wp-block-navigation .wp-block-navigation-item__content:hover {
	color: var(--wp--preset--color--white);
}

/* --- Waterfront label (dynamic block) -------------------------------------
   Flat mono-caps in muted teal — the color of the map pins, which is the
   point: a card and a pin for the same neighborhood should read as the same
   fact. Never a pill and never a badge; the design carries the claim in
   type, not in a shape. */

.mih-waterfront {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 0 0 12px;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 12px;
	letter-spacing: 0.25em;
	text-transform: uppercase;
	line-height: 1.6;
	color: var(--wp--preset--color--muted-teal);
}

.mih-waterfront__icon {
	flex: 0 0 auto;
}

/* --- Neighborhood facts (dynamic block) -----------------------------------
   A bordered definition list: price, character, and the feature list. Rules
   rather than bullets — a bullet list reads as sales points, and these are
   meant to read as a spec sheet. */

.mih-facts {
	border: 1px solid var(--wp--preset--color--line);
	background: var(--wp--preset--color--paper);
	padding: 28px;
}

.mih-facts__title {
	display: flex;
	align-items: center;
	gap: 12px;
	font-family: var(--wp--preset--font-family--serif);
	font-size: 18px;
	color: var(--wp--preset--color--ink);
	margin: 0;
	padding-bottom: 20px;
	border-bottom: 1px solid var(--wp--preset--color--line);
}

/* The accent tick that opens a panel title everywhere else on the site. */
.mih-facts__title::before {
	content: "";
	flex: 0 0 auto;
	width: 20px;
	height: 1px;
	background: var(--wp--preset--color--accent);
}

.mih-facts__list {
	margin: 24px 0 0;
}

.mih-facts__row + .mih-facts__row {
	margin-top: 24px;
}

.mih-facts dt {
	color: var(--wp--preset--color--slate);
}

.mih-facts dd {
	margin: 8px 0 0;
}

.mih-facts__value {
	font-family: var(--wp--preset--font-family--serif);
	font-size: 22px;
	line-height: 1.1;
	color: var(--wp--preset--color--ink);
}

/* Character is a phrase, not a figure, so it wraps at a readable size. */
.mih-facts__value--soft {
	font-size: 18px;
	line-height: 1.35;
}

.mih-facts__note {
	color: var(--wp--preset--color--slate);
}

.mih-facts__features {
	list-style: none;
	margin: 12px 0 0;
	padding: 0;
	border-top: 1px solid var(--wp--preset--color--line);
}

.mih-facts__features li {
	display: grid;
	grid-template-columns: 16px 1fr;
	gap: 12px;
	align-items: center;
	padding: 12px 0;
	border-bottom: 1px solid var(--wp--preset--color--line);
	font-family: var(--wp--preset--font-family--sans);
	font-size: 14px;
	color: var(--wp--preset--color--ink);
}

.mih-facts__features li::before {
	content: "";
	width: 12px;
	height: 1px;
	background: var(--wp--preset--color--accent);
}

/* --- Task checklist (dynamic block) ---------------------------------------
   A square box per line, ticked in muted teal — the same teal as the map
   pins and the waterfront label, because all three are the theme's way of
   saying "this is a fact about the thing", not a decoration.

   A done line is muted rather than struck through. Strikethrough is not
   announced by any screen reader, so it would be a state only sighted
   readers could read, and it makes the very lines someone is scanning past
   the hardest ones to scan. The tick and the off-screen "Done — " carry the
   state; the colour is only a hint.

   Loaded into the editor canvas too, by add_editor_style( 'style.css' ) in
   functions.php, which is what keeps the editing surface honest — the
   editor draws these items itself rather than through ServerSideRender. */

.mih-checklist {
	list-style: none;
	margin: 0;
	padding: 0;
}

.mih-checklist__item {
	display: flex;
	align-items: flex-start;
	gap: 14px;
	padding: 10px 0;
	border-bottom: 1px solid var(--wp--preset--color--line);
	font-size: 15px;
	line-height: 1.55;
	color: var(--wp--preset--color--ink);
}

.mih-checklist__item:last-child {
	border-bottom: 0;
}

/* Nudged down by the difference between the box and the cap height of the
   line beside it, so the tick sits on the first line of a wrapping item
   rather than floating above it. */
.mih-checklist__box {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	margin-top: 2px;
	border: 1px solid var(--wp--preset--color--line);
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--white);
}

.mih-checklist__item.is-checked .mih-checklist__box {
	border-color: var(--wp--preset--color--muted-teal);
	background: var(--wp--preset--color--muted-teal);
}

.mih-checklist__item.is-checked .mih-checklist__text {
	color: var(--wp--preset--color--slate);
}

/* The box is a real <button> in the editor and an inert <span> on the front
   end. These reset the button back to the span's appearance; on the front
   end they match nothing and cost nothing. */
button.mih-checklist__box {
	padding: 0;
	border-radius: 0;
	cursor: pointer;
	appearance: none;
}

/* --- Utility --------------------------------------------------------------
   Two-line clamps on card excerpts so a long one cannot break a grid row. */

.mih-clamp-3 .wp-block-post-excerpt__excerpt,
.mih-clamp-3 p {
	display: -webkit-box;
	-webkit-line-clamp: 3;
	line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* Off-screen but in the accessibility tree — the standard WordPress class,
   defined here rather than borrowed.

   It is borrowable: core's wp-block-library stylesheet carries a copy, and
   blocks/lead-form has been leaning on that copy for its field labels since
   it shipped. That is a dependency on core's internal packaging, though, not
   on any documented promise — wp-block-library is not loaded at all on a
   page built entirely from dynamic blocks with separate block assets turned
   on, and the labels would then be five stray words down the side of the
   form. The theme should own the class it uses.

   `clip-path` alongside the deprecated `clip` for the same reason core keeps
   both: Safari still needs the old one. */
.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	border: 0;
	word-wrap: normal !important;
}

/* Skip link — WordPress injects this; make it match the theme when focused. */
.skip-link:focus {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--white);
	outline: 2px solid var(--wp--preset--color--white);
}

:focus-visible {
	outline: 2px solid var(--wp--preset--color--brand);
	outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		transition-duration: 0.01ms !important;
	}
}

/* The podcast archive as a numbered list rather than a card grid, which is
   what the live site does and what the episode number is for: a reader
   scanning for "the one about flood insurance" reads titles down a column,
   not across three. The row is a flex group — number, thumbnail, then the
   text — and it comes apart below 782px because a 120px plate beside a
   two-line title beside four platform buttons has nowhere left to go on a
   phone. The number stays on its own line there rather than being hidden:
   it is how episodes are referred to out loud. */

.mih-episode-list .wp-block-post-featured-image {
	flex: 0 0 auto;
	margin: 0;
}

/* Sized here and nowhere else. The block's own width/height attributes look
   like the obvious place, but core serializes them inline onto the figure,
   the link and the img — and an inline style beats the class selector below,
   so the phone breakpoint could set the width to 88px and never touch the
   height. The plate came out 88x120 inside a 120px box, which reads as a
   cropping bug rather than a specificity one. */

.mih-episode-list .wp-block-post-featured-image img {
	width: 120px;
	height: 120px;
	object-fit: cover;
}

@media (max-width: 781px) {
	.mih-episode-list > li > .wp-block-group {
		flex-wrap: wrap;
	}

	.mih-episode-list .wp-block-post-featured-image img {
		width: 88px;
		height: 88px;
	}
}
