/* Blokmark · theme styles (ts-) */

/* ==========================================================================
 * Blokmark · theme styles (prefix ts-). Everything reads --tnt-* tokens.
 * ========================================================================== */

/* ---- Full-bleed flow: no gaps between header, main and footer (§9) ---- */
.wp-site-blocks > main, .wp-site-blocks > footer, .wp-site-blocks > .wp-block-template-part { margin-block-start: 0; }
.wp-site-blocks > .wp-block-template-part { display: contents; }
body { -webkit-font-smoothing: antialiased; }
/* Every link eases its color / underline (the block-scoped rules below only add properties). */
a { transition: color var(--tnt-dur-fast) var(--tnt-ease-expo), text-decoration-color var(--tnt-dur-fast) var(--tnt-ease-expo); }

/* ---- Focus (keyboard) ---- */
:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
	outline: 2px solid var(--tnt-color-accent);
	outline-offset: 3px;
}

/* ---- Signature: the highlighter mark ---- */
mark, .ts-mark {
	background: var(--tnt-color-accent-2);
	color: inherit;
	padding: 0.04em 0.18em;
	margin-inline: -0.06em;
	border-radius: 0.3em 0.5em 0.35em 0.45em;
	-webkit-box-decoration-break: clone;
	box-decoration-break: clone;
}
.is-style-ts-marker-underline {
	text-decoration: underline;
	text-decoration-color: var(--tnt-color-accent);
	text-decoration-thickness: 0.18em;
	text-underline-offset: 0.12em;
	text-decoration-skip-ink: none;
}

/* ---- Text helpers ---- */
.ts-kicker {
	font-family: var(--tnt-font-mono);
	font-size: var(--tnt-text-xs);
	letter-spacing: var(--tnt-tracking-wide);
	text-transform: uppercase;
	color: var(--tnt-color-text-muted);
	margin: 0 0 var(--tnt-space-3);
}
.ts-kicker::before {
	content: "";
	display: inline-block;
	inline-size: 0.5em; block-size: 0.5em;
	border-radius: 50%;
	background: var(--tnt-color-accent);
	margin-inline-end: 0.6em;
	vertical-align: middle;
}
.ts-lede { font-size: var(--tnt-text-md); color: var(--tnt-color-text-muted); max-inline-size: 36ch; }
.ts-section-title { max-inline-size: 22ch; }

/* ---- Buttons ----
 * Hover offsets use the individual `translate` / `scale` properties (not
 * `transform`): they compose with, instead of being overridden by, the single
 * composed `transform` that Blokino writes on blocks carrying effects. */
.wp-block-button__link {
	transition: background-color var(--tnt-dur-fast) var(--tnt-ease-expo),
		color var(--tnt-dur-fast) var(--tnt-ease-expo),
		border-color var(--tnt-dur-fast) var(--tnt-ease-expo),
		box-shadow var(--tnt-dur-fast) var(--tnt-ease-expo),
		translate 140ms var(--tnt-ease-expo),
		scale 140ms var(--tnt-ease-expo);
}
.wp-block-button__link:hover { translate: 0 -2px; box-shadow: var(--tnt-shadow-2); }
.wp-block-button__link:active { scale: 0.97; }
.wp-block-button.is-style-outline .wp-block-button__link {
	border: 1.5px solid var(--tnt-color-border);
	background: transparent;
	color: var(--tnt-color-text);
}
/* Hover fills with --tnt-color-text, so the label takes --ts-color-on-primary
   (linked to the look: dark on Midnight's chalk fill) — not the fixed on-ink,
   which is chalk in every look and vanished on Midnight. */
.wp-block-button.is-style-outline .wp-block-button__link:hover {
	border-color: var(--tnt-color-text);
	background: var(--tnt-color-text);
	color: var(--ts-color-on-primary);
}
.wp-block-button.is-style-ts-chalk .wp-block-button__link {
	background: var(--tnt-color-on-ink);
	color: var(--tnt-color-ink);
}
.wp-block-button.is-style-ts-chalk .wp-block-button__link:hover {
	background: var(--tnt-color-accent);
	color: var(--tnt-color-ink);
}

/* ---- Group block styles: Card / Ink panel ---- */
.is-style-ts-card {
	background: var(--tnt-color-surface);
	border: 1px solid var(--tnt-color-border);
	border-radius: var(--ts-radius-card);
	box-shadow: var(--tnt-shadow-1);
	transition: translate var(--tnt-dur-base) var(--tnt-ease-expo), box-shadow var(--tnt-dur-base) var(--tnt-ease-expo);
}
@media (hover: hover) and (pointer: fine) {
	.is-style-ts-card:hover { translate: 0 -3px; box-shadow: var(--tnt-shadow-2); }
}
/* Ink panel: always dark, in every variation (§13.1). Text tokens are locked. */
.is-style-ts-ink {
	--tnt-color-text: var(--tnt-color-on-ink);
	--tnt-color-text-muted: color-mix(in srgb, var(--tnt-color-on-ink) 70%, transparent);
	--tnt-color-surface: var(--tnt-color-ink);
	--tnt-color-border: color-mix(in srgb, var(--tnt-color-on-ink) 16%, transparent);
	background: var(--tnt-color-ink);
	color: var(--tnt-color-on-ink);
	border-radius: var(--ts-radius-card);
}
.is-style-ts-ink :where(h1, h2, h3, h4, p, li) { color: var(--tnt-color-on-ink); }
/* Kickers stay muted inside Ink (the :where(p) lock above would paint them 100% chalk). */
.is-style-ts-ink .ts-kicker { color: var(--tnt-color-text-muted); }
.is-style-ts-ink mark { background: var(--tnt-color-accent); color: var(--tnt-color-ink); }
.is-style-ts-ink .wp-block-button__link:not(.is-style-outline *) { background: var(--tnt-color-on-ink); color: var(--tnt-color-ink); }
.is-style-ts-ink.alignfull { border-radius: 0; }

/* ---- Header ---- */
.ts-header {
	background: color-mix(in srgb, var(--tnt-color-bg) 88%, transparent);
	border-block-end: 1px solid var(--tnt-color-border);
	position: sticky; inset-block-start: 0; z-index: 50;
}
.ts-header::before { content: ""; position: absolute; inset: 0; z-index: -1; backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); }
.admin-bar .ts-header { inset-block-start: var(--wp-admin--admin-bar--height, 32px); }
/* Anchor targets (/#services…) land under the sticky header (+ admin bar when shown). */
html { scroll-padding-block-start: calc(6rem + var(--wp-admin--admin-bar--height, 0px)); }
.ts-brand { gap: var(--tnt-space-3); }
.ts-brand .wp-block-site-logo { line-height: 0; }
.ts-brand:has(.wp-block-site-logo img) .ts-site-title { display: none; }
.ts-header .wp-block-navigation a { position: relative; padding-block: 0.25rem; }
.ts-header .wp-block-navigation a::after {
	content: ""; position: absolute; inset-inline: 0; inset-block-end: 0;
	block-size: 2px; background: var(--tnt-color-accent);
	transform: scaleX(0); transform-origin: left;
	transition: transform var(--tnt-dur-base) var(--tnt-ease-expo);
}
.ts-header .wp-block-navigation a:hover::after,
.ts-header .wp-block-navigation .current-menu-item > a::after { transform: scaleX(1); }
.ts-header__cta .wp-block-button__link { padding: 0.65rem 1.1rem; font-size: var(--tnt-text-sm); white-space: nowrap; }
@media (max-width: 600px) { :root .ts-header__cta { display: none; } }

/* Desktop dropdown */
.ts-header .wp-block-navigation .wp-block-navigation__submenu-container {
	background: var(--tnt-color-surface);
	border: 1px solid var(--tnt-color-border);
	border-radius: var(--ts-radius-btn);
	box-shadow: var(--tnt-shadow-2);
	padding: var(--tnt-space-1);
	min-inline-size: 13rem;
	margin-block-start: var(--tnt-space-2);
}
.ts-header .wp-block-navigation__submenu-container::before {
	content: ""; position: absolute; inset-block-start: calc(-1 * var(--tnt-space-2)); inset-inline: 0; block-size: var(--tnt-space-2);
}
.ts-header .wp-block-navigation__submenu-container .wp-block-navigation-item__content { padding: 0.5rem 0.75rem; border-radius: 6px; }
.ts-header .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover { background: var(--tnt-color-accent-2); }

/* Mobile overlay (colors come from the block: overlayBackgroundColor/TextColor) */
.ts-header .wp-block-navigation__responsive-container.is-menu-open { padding: var(--tnt-space-6) var(--tnt-space-5); }
.ts-header .is-menu-open .wp-block-navigation__responsive-container-content { inline-size: 100%; margin-block-start: var(--tnt-space-8); }
.ts-header .is-menu-open .wp-block-navigation__responsive-container-content,
.ts-header .is-menu-open .wp-block-navigation__container { align-items: flex-start !important; text-align: start; }
.ts-header .is-menu-open .wp-block-navigation__container { flex-direction: column; justify-content: flex-start; inline-size: 100%; gap: var(--tnt-space-4); }
.ts-header .is-menu-open .wp-block-navigation-item__content {
	font-family: var(--tnt-font-display); font-weight: 600; font-size: var(--tnt-text-xl); letter-spacing: -0.02em;
	min-block-size: 44px; display: inline-flex; align-items: center;
}
.ts-header .is-menu-open .wp-block-navigation-item__content::after { display: none; }
.ts-header .is-menu-open .wp-block-navigation__submenu-container { position: static; box-shadow: none; border: 0; padding-inline-start: var(--tnt-space-4); background: transparent; }
.wp-block-navigation__responsive-container-open,
.wp-block-navigation__responsive-container-close { inline-size: 44px; block-size: 44px; display: inline-flex; align-items: center; justify-content: center; }
.wp-block-navigation__responsive-container-open svg,
.wp-block-navigation__responsive-container-close svg { inline-size: 28px; block-size: 28px; }

/* ---- Footer ---- */
.ts-footer { background: var(--tnt-color-surface); border-block-start: 1px solid var(--tnt-color-border); }
.ts-footer__about { color: var(--tnt-color-text-muted); margin-block-start: var(--tnt-space-3); max-inline-size: 34ch; }
.ts-footer__title { text-transform: uppercase; letter-spacing: var(--tnt-tracking-wide); font-family: var(--tnt-font-mono); font-weight: 500; color: var(--tnt-color-text-muted); margin-block-end: var(--tnt-space-4); }
.ts-footer__cols { --wp--style--block-gap: 0; }
.ts-footer__nav { --wp--style--block-gap: var(--tnt-space-2); }
.ts-footer__nav a { color: var(--tnt-color-text); text-decoration: none; transition: color var(--tnt-dur-fast) var(--tnt-ease-expo); }
.ts-footer__nav a:hover { color: var(--ts-color-link); }
.ts-footer__social .wp-social-link { color: var(--tnt-color-text) !important; transition: translate var(--tnt-dur-fast) var(--tnt-ease-expo), color var(--tnt-dur-fast) var(--tnt-ease-expo); }
@media (hover: hover) and (pointer: fine) { .ts-footer__social .wp-social-link:hover { translate: 0 -2px; color: var(--tnt-color-accent) !important; } }
.ts-footer__legal p { margin: 0; color: var(--tnt-color-text-muted); }
.ts-footer__legal a { color: var(--tnt-color-text); font-weight: 600; text-decoration-color: color-mix(in srgb, var(--tnt-color-accent) 50%, transparent); text-underline-offset: 0.2em; }
.ts-footer__legal a:hover { color: var(--ts-color-link); }

/* ---- Sections ---- */
.ts-section { position: relative; }
.ts-section + .ts-section { margin-block-start: 0; }

/* ---- Hero: split stage (7/5) ---- */
:root .ts-hero__grid { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--tnt-space-8); align-items: center; }
.ts-hero__copy h1 { margin-block: 0 var(--tnt-space-5); max-inline-size: 12ch; }
.ts-hero__copy .ts-lede { margin-block-end: var(--tnt-space-6); }
/* :root prefix: the gaps beat WP's `:root :where(.is-layout-flex)` by specificity, not source order. */
:root .ts-hero__actions { gap: var(--tnt-space-3); }
.ts-hero__stage { position: relative; }
.ts-hero__photo { margin: 0; }
.ts-hero__photo img { border-radius: var(--ts-radius-photo); inline-size: 100%; block-size: auto; aspect-ratio: 7 / 5; object-fit: cover; box-shadow: var(--tnt-shadow-3); }
:root .ts-hero__card { position: absolute; inset-inline-start: calc(-1 * var(--tnt-space-7)); inset-block-end: var(--tnt-space-6); max-inline-size: 20rem; gap: var(--tnt-space-3); box-shadow: var(--tnt-shadow-3); }
/* The card is not interactive: no lift / lighter shadow from .is-style-ts-card:hover. */
.ts-hero__card:hover { translate: none; box-shadow: var(--tnt-shadow-3); }
.ts-hero__card .ts-avatar { margin: 0; flex: 0 0 48px; }
.ts-hero__card .ts-avatar img { border-radius: 50%; }
.ts-hero__quote { margin: 0; font-family: var(--tnt-font-display); font-weight: 600; line-height: 1.3; }
.ts-hero__who { margin: var(--tnt-space-1) 0 0; color: var(--tnt-color-text-muted); }
/* Mid range (tablet landscape → small laptop): even split so the photo keeps
   room under the floating card; at 7/5 the card covered ~85% of it. */
@media (max-width: 1180px) {
	:root .ts-hero__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
@media (max-width: 1023px) {
	:root .ts-hero__grid { grid-template-columns: 1fr; gap: var(--tnt-space-6); }
	/* Stacked: cap the photo so it does not turn into a billboard at 768–1023. */
	.ts-hero__stage { max-inline-size: 40rem; }
	:root .ts-hero__card { position: relative; inset: auto; margin-block-start: calc(-1 * var(--tnt-space-6)); margin-inline-start: var(--tnt-space-4); }
}

/* ---- Proof ---- */
.ts-proof { border-block: 1px solid var(--tnt-color-border); background: var(--tnt-color-surface); }
/* align-items: stretch overrides WP's .is-layout-flex { align-items: center },
   which would otherwise vertically centre the shorter items (kickers misalign). */
:root .ts-proof__row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--tnt-space-6); align-items: stretch; }
.ts-proof__item p:last-child { margin: 0; font-family: var(--tnt-font-display); font-weight: 600; line-height: 1.3; }
.ts-proof__item + .ts-proof__item { border-inline-start: 1px solid var(--tnt-color-border); padding-inline-start: var(--tnt-space-6); }
@media (max-width: 900px) {
	:root .ts-proof__row { grid-template-columns: 1fr; gap: var(--tnt-space-4); }
	.ts-proof__item + .ts-proof__item { border-inline-start: 0; padding-inline-start: 0; border-block-start: 1px solid var(--tnt-color-border); padding-block-start: var(--tnt-space-4); }
}

/* WP's flow layout gives every non-first child `margin-block-start: blockGap`
   (`:root :where(.is-layout-flow) > *`). Inside our CSS grids / row lists that
   margin shifts items within their cells (cards 19px below the Ink lead, the
   about copy offset by gap + padding, a dead gap above each process hairline).
   The grid gap / row padding already own that spacing, so zero it. */
:root .ts-bento > *, :root .ts-about__grid > *, :root .ts-rows > *,
:root .ts-quotes > *, :root .ts-pricing > *, :root .ts-faq > *,
:root .ts-post-grid > *, :root .ts-cta__grid > *, :root .ts-contact__grid > *,
:root .ts-shell > *, :root .ts-sidebar > * { margin-block-start: 0; }

/* ---- Services: bento (Ink lead spanning two rows + 2×2 Paper cards) ---- */
:root .ts-bento { display: grid; grid-template-columns: minmax(0, 1.15fr) repeat(2, minmax(0, 1fr)); grid-auto-rows: minmax(12rem, auto); gap: var(--tnt-space-4); margin-block-start: var(--tnt-space-7); }
.ts-bento__lead { grid-row: span 2; display: flex; flex-direction: column; justify-content: space-between; }
/* Three flex children: without this, space-between floats the paragraph
   mid-card. The auto margin keeps title + text at the top and pins the link. */
.ts-bento__lead > :last-child { margin-block-start: auto; padding-block-start: var(--tnt-space-4); }
.ts-bento__lead h3 { max-inline-size: 10ch; margin: 0 0 var(--tnt-space-4); }
.ts-bento__lead > p { margin-block-start: 0; } /* the h3 margin already owns the gap (it doubled with the flow margin) */
/* Same language as the CTA link: underline at half accent, full accent on hover. */
.ts-bento__lead a { color: var(--tnt-color-on-ink); text-decoration-color: color-mix(in srgb, var(--tnt-color-accent) 50%, transparent); font-weight: 600; }
.ts-bento__lead a:hover { color: var(--tnt-color-on-ink); text-decoration-color: var(--tnt-color-accent); }
.ts-bento__card h3 { margin: var(--tnt-space-3) 0 var(--tnt-space-2); }
.ts-bento__card p { margin: 0; color: var(--tnt-color-text-muted); }
/* Accent tile (not accent-2): the SVGs are <img>, so their stroke is a fixed
   Ink and cannot follow the look — on Midnight's dark accent-2 tint the icons
   vanished. Ink on accent measures >= 4.5:1 in Chalk / Midnight / Slate. */
.ts-icon { margin: 0; inline-size: 2.5rem; block-size: 2.5rem; display: grid; place-items: center; border-radius: 10px; background: var(--tnt-color-accent); }
.ts-icon img { inline-size: 1.5rem; block-size: 1.5rem; }
@media (max-width: 900px) {
	:root .ts-bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.ts-bento__lead { grid-column: span 2; grid-row: auto; }
}
@media (max-width: 560px) {
	:root .ts-bento { grid-template-columns: 1fr; }
	.ts-bento__lead { grid-column: auto; }
}

/* ---- About: editorial split (photo left, copy pushed down on purpose) ---- */
:root .ts-about__grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--tnt-space-8); align-items: start; }
.ts-about__photo img { border-radius: var(--ts-radius-photo); aspect-ratio: 4 / 3; object-fit: cover; inline-size: 100%; }
.ts-about__copy { padding-block-start: var(--tnt-space-8); }
/* Quote attribution: WP renders <cite> at .8125em of the quote (display face,
   19.5px) — as heavy as the quote itself. Body face, small, muted. */
.wp-block-quote cite { font-family: var(--tnt-font-body); font-size: var(--tnt-text-sm); font-weight: 400; color: var(--tnt-color-text-muted); }
@media (max-width: 900px) {
	:root .ts-about__grid { grid-template-columns: 1fr; }
	.ts-about__copy { padding-block-start: 0; }
}

/* ---- Process: rows (mono number + title/text, hairlines) ---- */
.ts-rows { margin-block-start: var(--tnt-space-7); }
.ts-row { gap: var(--tnt-space-6); padding-block: var(--tnt-space-5); border-block-start: 1px solid var(--tnt-color-border); }
.ts-row:last-child { border-block-end: 1px solid var(--tnt-color-border); }
/* task-11 QA: raw --tnt-color-accent as small text on --tnt-color-bg measured
   2.63:1 (Chalk) / 3.54:1 (Slate) — fails AA for normal text. --ts-color-link
   is the pre-existing AA-safe deep variant of the same marker hue (measured
   >=5:1 on bg in all three looks), reused here instead of a hardcoded color. */
.ts-row__num { margin: 0; flex: 0 0 4rem; font-family: var(--tnt-font-mono); color: var(--ts-color-link); font-size: var(--tnt-text-sm); padding-block-start: 0.35em; /* sits on the title's baseline (top-aligned row) */ }
.ts-row h3 { margin: 0 0 var(--tnt-space-2); }
.ts-row p { margin: 0; max-inline-size: 60ch; }
.ts-row h3 + p { color: var(--tnt-color-text-muted); }
/* Phone: the 4rem number column + space-6 gap left the text ~260px wide
   (four-line wraps). Tighter column and gap on narrow screens. */
@media (max-width: 560px) {
	.ts-row { gap: var(--tnt-space-4); }
	.ts-row__num { flex-basis: 2.5rem; }
}

/* ---- Testimonials: 2:1 (lead quote spanning two rows + two stacked) ---- */
:root .ts-quotes { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); grid-auto-rows: auto; gap: var(--tnt-space-4); margin-block-start: var(--tnt-space-7); }
.ts-quote--lead { grid-row: span 2; display: flex; flex-direction: column; justify-content: space-between; }
/* The section sits on Paper: Chalk cards, so the card edge reads as a real contrast step. */
.ts-testimonials .is-style-ts-card { background: var(--tnt-color-bg); }
.ts-quote p:first-child { font-family: var(--tnt-font-display); font-weight: 500; line-height: 1.35; margin: 0 0 var(--tnt-space-5); }
.ts-quote p:last-child { margin: 0; color: var(--tnt-color-text-muted); }
.ts-quote strong { color: var(--tnt-color-text); }
/* The avatar row is a nowrap flex: without a fixed basis the figure shrank to
   36×48 (an ellipse) at phone widths, because WP's img { max-width:100% }
   lets it give way to the long name/role paragraph. Same fix as the hero card. */
.ts-quote .ts-avatar { flex: 0 0 48px; }
@media (max-width: 900px) {
	:root .ts-quotes { grid-template-columns: 1fr; }
	.ts-quote--lead { grid-row: auto; }
}

/* ---- Pricing: three plans, Growth elevated in Ink ---- */
:root .ts-pricing { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--tnt-space-4); align-items: stretch; margin-block-start: var(--tnt-space-7); }
/* 901–1100px: three ~200px columns broke the unit mid-word ("ONE-" / "TIME")
   onto a second line as tall as the price (the number inherited the body
   leading, 1.6 × 47px). Display leading on the number; the unit wraps whole. */
.ts-plan__price { font-family: var(--tnt-font-display); font-size: var(--tnt-text-xl); font-weight: 700; letter-spacing: var(--tnt-tracking-tight); line-height: 1.1; margin: var(--tnt-space-2) 0 var(--tnt-space-4); }
.ts-plan__price span { font-family: var(--tnt-font-mono); font-size: var(--tnt-text-xs); text-transform: uppercase; letter-spacing: var(--tnt-tracking-wide); color: var(--tnt-color-text-muted); margin-inline-start: .5em; white-space: nowrap; }
.ts-plan ul { list-style: none; padding: 0; margin: 0 0 var(--tnt-space-5); }
/* Hanging indent: the ✓ is the first flex item, so a wrapped feature aligns under its own text. */
.ts-plan li { display: flex; gap: .6em; align-items: flex-start; padding-block: .45rem; border-block-start: 1px solid var(--tnt-color-border); }
.ts-plan li::before { content: "✓"; color: var(--tnt-color-accent); font-weight: 700; }
.ts-plan--featured { translate: 0 -12px; }
/* align-items: stretch makes the three cards Growth's height (badge + a 5th
   item), which left the Starter/Scale buttons floating ~140px above the card
   bottom at 1440. Column flex + auto margin pins every CTA to the bottom edge;
   the badge keeps its shrink-to-fit width (a column flex would stretch it). */
.ts-plan { display: flex; flex-direction: column; }
.ts-plan .wp-block-buttons { margin-block-start: auto; }
.ts-plan__badge { align-self: flex-start; display: inline-block; background: var(--tnt-color-accent); color: var(--tnt-color-ink); border-radius: 999px; padding: .2em .7em; font-family: var(--tnt-font-mono); font-size: var(--tnt-text-xs); text-transform: uppercase; letter-spacing: var(--tnt-tracking-wide); margin: 0 0 var(--tnt-space-3); }
@media (max-width: 900px) {
	:root .ts-pricing { grid-template-columns: 1fr; }
	.ts-plan--featured { translate: none; }
}

/* ---- FAQ: 5/7 split, native <details> with a "+" that turns into "×" ---- */
:root .ts-faq { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--tnt-space-8); }
.ts-faq h2 { text-wrap: balance; } /* no orphan word on the last line of the 5/12 column */
.ts-faq__list .wp-block-details { border-block-start: 1px solid var(--tnt-color-border); padding-block: var(--tnt-space-4); margin: 0; }
.ts-faq__list .wp-block-details:last-child { border-block-end: 1px solid var(--tnt-color-border); }
.ts-faq__list summary { font-family: var(--tnt-font-display); font-weight: 600; font-size: var(--tnt-text-md); cursor: pointer; list-style: none; display: flex; justify-content: space-between; gap: var(--tnt-space-4); transition: color var(--tnt-dur-fast) var(--tnt-ease-expo); }
.ts-faq__list summary:hover { color: var(--ts-color-link); }
.ts-faq__list summary::-webkit-details-marker { display: none; }
.ts-faq__list summary::after { content: "+"; color: var(--tnt-color-accent); font-family: var(--tnt-font-mono); transition: transform var(--tnt-dur-base) var(--tnt-ease-expo); }
.ts-faq__list details[open] summary::after { transform: rotate(45deg); }
.ts-faq__list details p { color: var(--tnt-color-text-muted); margin: var(--tnt-space-3) 0 0; max-inline-size: 60ch; }
@media (max-width: 900px) {
	:root .ts-faq { grid-template-columns: 1fr; }
}

/* ---- Posts: three editorial cards (no chrome; image zoom, mono date) ---- */
:root .ts-post-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--tnt-space-6); margin-block-start: var(--tnt-space-7); }
.ts-post-grid > li, .ts-post-grid .wp-block-post { display: flex; flex-direction: column; gap: var(--tnt-space-2); }
/* The <li> is not a layout container, so WP's flow reset never reaches its
   children: the figure kept 18px, the h3 24px and the excerpt 18.8px of UA /
   block margins on top of the flex gap (27 / 33 / 52px steps at 1440). Zero
   them so the gap alone sets the rhythm; the image keeps one extra step. */
.ts-post-grid .wp-block-post > * { margin: 0; }
.ts-post-grid .ts-post-card__media { margin-block-end: var(--tnt-space-2); }
.ts-post-card__media img { border-radius: var(--ts-radius-card); inline-size: 100%; object-fit: cover; transition: scale var(--tnt-dur-slow) var(--tnt-ease-expo); }
.ts-post-card__media a { display: block; overflow: hidden; border-radius: var(--ts-radius-card); }
@media (hover: hover) and (pointer: fine) { .ts-post-card__media:hover img { scale: 1.04; } }
.ts-post-grid .wp-block-post-title a { text-decoration: none; color: var(--tnt-color-text); transition: color var(--tnt-dur-fast) var(--tnt-ease-expo); }
.ts-post-grid .wp-block-post-title a:hover { color: var(--ts-color-link); }
.ts-post-grid .wp-block-post-excerpt { color: var(--tnt-color-text-muted); }
.wp-block-post-excerpt__more-link { font-weight: 600; }
@media (max-width: 900px) {
	:root .ts-post-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	/* Two columns + three posts: the odd last card spans the row instead of sitting orphaned. */
	.ts-post-grid > li:last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@media (max-width: 560px) {
	:root .ts-post-grid { grid-template-columns: 1fr; }
}

/* ---- CTA: full-bleed Ink band, 7/5 with the action pinned to the baseline ---- */
:root .ts-cta__grid { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--tnt-space-8); align-items: end; }
.ts-cta h2 { max-inline-size: 10ch; margin: 0 0 var(--tnt-space-4); }
.ts-cta .ts-lede { color: color-mix(in srgb, var(--tnt-color-on-ink) 72%, transparent); }
.ts-cta a:not(.wp-block-button__link) { color: var(--tnt-color-on-ink); text-decoration-color: color-mix(in srgb, var(--tnt-color-on-ink) 50%, transparent); transition: text-decoration-color var(--tnt-dur-fast) var(--tnt-ease-expo); }
.ts-cta a:not(.wp-block-button__link):hover { text-decoration-color: var(--tnt-color-accent); }
@media (max-width: 900px) {
	:root .ts-cta__grid { grid-template-columns: 1fr; }
}

/* ---- Contact: 5/7 split, details card with a two-column definition list ---- */
:root .ts-contact__grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--tnt-space-8); align-items: start; }
.ts-contact__list ul { list-style: none; padding: 0; margin: 0 0 var(--tnt-space-5); display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--tnt-space-4); }
.ts-contact__list li strong { display: block; font-family: var(--tnt-font-mono); font-size: var(--tnt-text-xs); text-transform: uppercase; letter-spacing: var(--tnt-tracking-wide); color: var(--tnt-color-text-muted); margin-block-end: .25rem; }
/* The details card is static content, not a link target: no lift from .is-style-ts-card:hover. */
.ts-contact__list:hover { translate: none; box-shadow: var(--tnt-shadow-1); }
@media (max-width: 900px) {
	:root .ts-contact__grid { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
	.ts-contact__list ul { grid-template-columns: 1fr; }
}

/* ---- Page header (archive / search) ---- */
.ts-page-header h1 { max-inline-size: 16ch; }

/* ---- Content shell + sidebar (§13.9) ----
   Grid: main column + 18rem aside. The aside is sticky under the sticky header
   (~4.5rem tall) on desktop and stacks under the content on narrow screens. */
:root .ts-shell { display: grid; grid-template-columns: minmax(0, 1fr) 18rem; gap: var(--tnt-space-8); align-items: start; padding-block: var(--tnt-space-8) var(--tnt-space-9); }
.ts-shell__main { min-inline-size: 0; }
.ts-shell__aside { position: sticky; inset-block-start: calc(var(--tnt-space-6) + 4.5rem); }
.admin-bar .ts-shell__aside { inset-block-start: calc(var(--tnt-space-6) + 4.5rem + 32px); }
@media (max-width: 900px) { :root .ts-shell { grid-template-columns: 1fr; gap: var(--tnt-space-7); } .ts-shell__aside { position: static; } }
/* Engine-controlled: without Blokino (no body class) or with "Full width", the auto shell is single column. */
:root body:not(.blokino-has-sidebar) .ts-shell--auto { display: block; }
body:not(.blokino-has-sidebar) .ts-shell--auto .ts-shell__aside { display: none; }
:root body:not(.blokino-has-sidebar) .ts-shell--auto:not(.ts-shell--list) { max-inline-size: var(--wp--style--global--content-size); margin-inline: auto; }

/* ---- Article ---- */
.ts-article__meta { gap: var(--tnt-space-3); margin-block-end: var(--tnt-space-3); }
.ts-article__meta a { text-decoration: none; }
.ts-article__title { margin-block: 0 var(--tnt-space-5); max-inline-size: 18ch; }
.ts-article__media img { border-radius: var(--ts-radius-photo); }
.ts-article__media { margin-block-end: var(--tnt-space-6); }
.ts-article__foot, .ts-article__nav { border-block-start: 1px solid var(--tnt-color-border); padding-block-start: var(--tnt-space-4); margin-block-start: var(--tnt-space-7); }
.ts-article__nav a { text-decoration: none; font-weight: 600; }
.ts-article__foot a { text-decoration: none; } /* tags: underlined uppercase mono read as noise (r3 foot shot); same rule as the meta row */
/* Author row: WP renders the byline at .5em (9px, unreadable at 1440) and the
   avatar square. Mono kicker + display name + round avatar, same as the cards. */
.ts-article__foot .wp-block-post-author { align-items: center; }
.ts-article__foot .wp-block-post-author__avatar { line-height: 0; }
.ts-article__foot .wp-block-post-author__avatar img { border-radius: 50%; }
.ts-article__foot .wp-block-post-author__byline { font-family: var(--tnt-font-mono); font-size: var(--tnt-text-xs); text-transform: uppercase; letter-spacing: var(--tnt-tracking-wide); color: var(--tnt-color-text-muted); }
.ts-article__foot .wp-block-post-author__name { font-family: var(--tnt-font-display); font-weight: 600; }
.ts-comments { margin-block-start: var(--tnt-space-8); }
/* Same weight as the "Leave a Reply" h3 (lg): at xl the responses title outweighed the article h2s in a 680 column. */
.ts-comments .wp-block-comments-title { font-size: var(--tnt-text-lg); }
.ts-comment { gap: var(--tnt-space-3); padding-block: var(--tnt-space-4); border-block-start: 1px solid var(--tnt-color-border); }
.ts-comment .wp-block-comment-date { font-family: var(--tnt-font-mono); font-size: var(--tnt-text-xs); color: var(--tnt-color-text-muted); }
/* Comment chrome: WP renders name/date/reply as plain underlined links and the
   avatar square (r3 shots). Name in display Ink, date/reply muted, round avatar. */
.ts-comment .wp-block-avatar { flex: 0 0 auto; }
.ts-comment .wp-block-avatar img { border-radius: 50%; }
.ts-comment .wp-block-comment-author-name { font-family: var(--tnt-font-display); font-weight: 600; }
.ts-comment .wp-block-comment-author-name a, .ts-comment .wp-block-comment-date a { color: inherit; text-decoration: none; }
.ts-comment .wp-block-comment-author-name a:hover, .ts-comment .wp-block-comment-date a:hover { color: var(--ts-color-link); }
.ts-comment .wp-block-comment-reply-link a, .ts-comment .wp-block-comment-edit-link a { font-family: var(--tnt-font-display); font-size: var(--tnt-text-sm); font-weight: 600; text-decoration: none; }
.ts-comment .wp-block-comment-content > :last-child { margin-block-end: 0; }
.ts-comment .wp-block-comment-content :where(h1, h2) { font-size: var(--tnt-text-lg); }
.ts-comment .wp-block-comment-content :where(h3, h4) { font-size: var(--tnt-text-md); }
/* The comment body is a nowrap flex item: with min-width:auto a long inline
   <code>/URL pushed it to 1376px (WPTT "Template: Comments", 1814 > 1440). */
.ts-comment > .wp-block-group { min-inline-size: 0; flex: 1 1 auto; }
.ts-comment .wp-block-comment-content { overflow-wrap: anywhere; }
/* Raw <pre> (classic content, comments) keeps white-space: pre — scroll it
   instead of widening the page (a 1376px verse in the same WPTT comment). */
.ts-prose :where(pre), .ts-comment :where(pre) { overflow-x: auto; max-inline-size: 100%; }

/* ---- Prose ---- */
.ts-prose > :where(h2) { margin-block-start: var(--tnt-space-7); }
.ts-prose > :where(h3) { margin-block-start: var(--tnt-space-6); }
.ts-prose :where(ul, ol) { padding-inline-start: 1.2em; }
.ts-prose li + li { margin-block-start: var(--tnt-space-2); }
.ts-prose :where(img, .wp-block-image img) { border-radius: var(--ts-radius-card); }
/* Classic captions carry an inline width (WPTT "Markup: Image Alignment": 690px → 696 > 390 at phone width). */
.ts-prose :where(.wp-caption) { max-inline-size: 100%; }
.ts-narrow .ts-prose { max-inline-size: 60ch; margin-inline: auto; }
/* The shell already pads the top (space-8); a top margin here doubled it to
   ~160px above the listing / page title at 1440 (the single's meta line sits at
   ~80px). The page-header patterns dropped their top padding for the same reason. */
.ts-page-title { margin-block: 0 var(--tnt-space-6); }
/* Listing H1: padding (does not collapse with the query's margins) so "Journal"
   sits at the same distance from the grid as the archive page-header (~88px). */
.ts-shell--list .ts-page-title { margin-block-end: 0; padding-block-end: var(--tnt-space-6); }

/* ---- Listing grid (2 columns inside the shell) ---- */
:root .ts-post-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-block-start: var(--tnt-space-6); }
@media (max-width: 640px) { :root .ts-post-grid--2 { grid-template-columns: 1fr; } }
.wp-block-query-pagination { margin-block-start: var(--tnt-space-7); font-family: var(--tnt-font-mono); font-size: var(--tnt-text-sm); }
.wp-block-query-pagination a, .wp-block-query-pagination .page-numbers { text-decoration: none; padding: .4rem .7rem; border-radius: 8px; }
.wp-block-query-pagination .page-numbers.current { background: var(--tnt-color-accent-2); color: var(--tnt-color-text); }

/* ---- Sidebar widgets ---- */
.ts-sidebar { display: grid; gap: var(--tnt-space-5); }
.ts-sidebar__widget { background: var(--tnt-color-surface); border: 1px solid var(--tnt-color-border); border-radius: var(--ts-radius-card); padding: var(--tnt-space-5); }
.ts-sidebar__widget.is-style-ts-ink { border: 0; }
.ts-sidebar__title { font-family: var(--tnt-font-mono); text-transform: uppercase; letter-spacing: var(--tnt-tracking-wide); color: var(--tnt-color-text-muted); margin: 0 0 var(--tnt-space-3); font-weight: 500; }
/* The search box is its own framed control: a card around it read as a double
   frame (r2 shots), so that widget goes chrome-less like the Aurora port. */
.ts-sidebar__widget--search { background: transparent; border: 0; padding: 0; }
.ts-sidebar .wp-block-post-title a { text-decoration: none; font-weight: 600; }
/* Widget links read as Ink (the cards' language), hover to Link; the flow gap +
   UA margins gave the post list a loose 20/25px rhythm — hairline rows instead. */
.ts-sidebar .wp-block-post-title a, .ts-sidebar .wp-block-categories a { color: var(--tnt-color-text); transition: color var(--tnt-dur-fast) var(--tnt-ease-expo); }
.ts-sidebar .wp-block-post-title a:hover, .ts-sidebar .wp-block-categories a:hover { color: var(--ts-color-link); }
:root .ts-sidebar__list > * { margin: 0; padding-block: .6rem; }
:root .ts-sidebar__list > :first-child { padding-block-start: 0; }
:root .ts-sidebar__list > :last-child { padding-block-end: 0; }
.ts-sidebar__list > * + * { border-block-start: 1px solid var(--tnt-color-border); }
.ts-sidebar__list .wp-block-post-title { margin: 0; line-height: 1.3; }
.ts-sidebar__list .wp-block-post-date { margin: .25rem 0 0; }
.ts-sidebar .wp-block-categories { list-style: none; padding: 0; margin: 0; font-size: var(--tnt-text-sm); } /* sm: matches the post list; base read a size up from the rest of the widget */
.ts-sidebar .wp-block-categories a { text-decoration: none; font-weight: 500; }
.ts-sidebar .wp-block-categories li { padding-block: .35rem; border-block-start: 1px solid var(--tnt-color-border); }

/* ---- Forms (search, comments): tokens, border-box (§9) ----
   One place for every form control. The generic rule dresses the comment form
   (WP 7.1 ships its colours/padding in :where(), so source order wins); the
   search block keeps its own selectors because WP styles the button-inside
   layout at (0,1,0): Line border, card radius (button radius + the 4px inset),
   Paper, focus ring on the wrapper. Merged here from Task 7. */
:where(input:not([type=submit]):not([type=button]):not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=file]):not([type=range]):not([type=color]):not([type=image]):not([type=reset]), textarea, select) {
	box-sizing: border-box; inline-size: 100%;
	font: inherit; color: var(--tnt-color-text);
	background: var(--tnt-color-surface);
	border: 1.5px solid var(--tnt-color-border); border-radius: var(--ts-radius-btn);
	padding: .8rem 1rem;
	transition: border-color var(--tnt-dur-fast) var(--tnt-ease-expo), box-shadow var(--tnt-dur-fast) var(--tnt-ease-expo);
}
:where(input, textarea, select)::placeholder { color: var(--tnt-color-text-muted); }
:where(input[type=checkbox], input[type=radio]) { accent-color: var(--tnt-color-accent); }
.comment-form label { font-size: var(--tnt-text-sm); font-weight: 500; }
/* Focus: accent border + accent-2 halo (checkboxes / radios keep the global outline). */
:where(input:not([type=submit]):not([type=button]):not([type=checkbox]):not([type=radio]), textarea, select):focus { border-color: var(--tnt-color-accent); box-shadow: 0 0 0 3px var(--tnt-color-accent-2); outline: none; }
/* Comment form on WP 6.6–6.8 (declared floor): core styles its inputs at
   `:where(.wp-block-post-comments-form) input:not([type=submit])` (0,1,1) with
   WP's default grey border shorthand, which beats the generic rule and the :focus
   border-color. Same tokens, scoped so the search inset rules stay untouched. */
.wp-block-post-comments-form :is(input:not([type=submit]):not([type=checkbox]):not([type=radio]):not([type=hidden]), textarea) { border: 1.5px solid var(--tnt-color-border); border-radius: var(--ts-radius-btn); padding: .8rem 1rem; background: var(--tnt-color-surface); color: var(--tnt-color-text); }
.wp-block-post-comments-form :is(input:not([type=submit]):not([type=checkbox]):not([type=radio]), textarea):focus { border-color: var(--tnt-color-accent); box-shadow: 0 0 0 3px var(--tnt-color-accent-2); outline: none; }
/* Search / submit buttons (wp-element-button, styled by theme.json) get the same hover easing as core buttons. */
.wp-element-button:not(.wp-block-button__link) { cursor: pointer; transition: background-color var(--tnt-dur-fast) var(--tnt-ease-expo), color var(--tnt-dur-fast) var(--tnt-ease-expo); }
.wp-block-search__input {
	box-sizing: border-box; min-inline-size: 0;
	font-family: var(--tnt-font-body); font-size: var(--tnt-text-base); color: var(--tnt-color-text);
	background: var(--tnt-color-surface); border: 1.5px solid var(--tnt-color-border); border-radius: var(--ts-radius-btn);
	padding: 0.7rem var(--tnt-space-3);
}
:root .wp-block-search__button-inside .wp-block-search__inside-wrapper {
	border: 1.5px solid var(--tnt-color-border);
	border-radius: var(--ts-radius-card);
	background: var(--tnt-color-surface);
	padding: 4px;
	transition: border-color var(--tnt-dur-fast) var(--tnt-ease-expo), box-shadow var(--tnt-dur-fast) var(--tnt-ease-expo);
}
:root .wp-block-search__button-inside .wp-block-search__inside-wrapper:focus-within { border-color: var(--tnt-color-accent); box-shadow: var(--tnt-shadow-2); }
/* Inner input: the border / radius / padding resets are NOT redundant — on WP 7.1
   core zeroes them at `:where(.wp-block-search__button-inside …) .wp-block-search__input`
   (0,1,0), which loses to our later `.wp-block-search__input` (0,1,0) above (verified
   task 12a: without them the input grew a 1px border, 10px radius and 11px padding).
   box-shadow: none keeps the generic :focus halo off the inner input (the wrapper rings). */
.wp-block-search__button-inside .wp-block-search__input { border: 0; border-radius: 0; background: transparent; padding-block: 0; box-shadow: none; }
.wp-block-search__button.wp-element-button { padding: 0.7rem 1.2rem; }

/* ---- Selection ---- */
::selection { background: var(--tnt-color-accent-2); }
