/* ============================================================
   FLIBBR PAGE CHASSIS
   Drives page.php — the shared template behind Privacy, Cookies,
   Terms, Thank-you landing, and any future content page added
   through wp-admin.

   Lifted verbatim from flibbr-design-mockup-final-page.html
   (canonical locked 30 Apr 2026), with one explicit deviation
   noted at .page-body-grid below.
   ============================================================ */

/* page header */
.page-header {
	padding-block: var(--s-9) var(--s-7);
	border-bottom: 1px solid var(--rule);
}
.page-header-kicker {
	font-family: var(--sans); font-weight: 600;
	font-size: 12px; line-height: 1;
	letter-spacing: 0.16em; text-transform: uppercase;
	color: var(--accent);
	margin-bottom: var(--s-5);
}
.page-header-headline {
	margin: 0 0 var(--s-5) 0;
	max-width: 22ch;
}
.page-header-supporting {
	max-width: 56ch;
}
.page-header-meta {
	margin-top: var(--s-5);
	padding-top: var(--s-3);
	border-top: 1px solid var(--rule);
	font-family: var(--sans); font-weight: 400;
	font-size: 12px; line-height: 1.4;
	letter-spacing: 0.06em; text-transform: uppercase;
	color: var(--ink-quiet);
	display: flex; gap: var(--s-5); flex-wrap: wrap;
}
.page-header-meta strong {
	font-weight: 600;
	color: var(--ink);
	margin-right: var(--s-2);
}

/* page body — two-column grid by default (label · prose).
   Canonical defines a 3-column grid (label · prose · TOC); v0.4.4
   ships without TOC generation, so the TOC slot is opt-in via
   .page-body-grid--has-toc modifier. When the TOC partial is
   added in a later session, the modifier flips the grid back to
   3-column. */
.page-body {
	padding-block: var(--s-9);
}
.page-body-grid {
	display: grid;
	grid-template-columns: 200px 1fr;
	gap: var(--s-7);
	align-items: start;
}
.page-body-grid--has-toc {
	grid-template-columns: 200px 1fr 220px;
}
@media (max-width: 1080px) {
	.page-body-grid--has-toc {
		grid-template-columns: 200px 1fr;
	}
	.page-toc { display: none; }
}
@media (max-width: 880px) {
	.page-body-grid,
	.page-body-grid--has-toc {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--s-5);
	}
}
.page-label {
	font-family: var(--sans); font-weight: 600;
	font-size: 11px; line-height: 1.2;
	letter-spacing: 0.16em; text-transform: uppercase;
	color: var(--ink-quiet);
	padding-top: var(--s-3);
	border-top: 1px solid var(--ink);
}

/* ----------------------------------------------------------
 * STICKY-CTA PATTERN — promoted from surface CSS at v0.5.34
 * (open #56). Ships the .page-label sticky-positioning
 * behaviour, the .is-released release-state, the
 * .page-label-text block-level child, the 880px-down reset,
 * and the .page-label-cta ink-violet pill family.
 *
 * Pattern was surface-self-contained at v0.5.32 (validation-
 * room.css) and v0.5.33 (brand-ai.css). At v0.5.34, page-
 * bootcamps.php becomes the 3rd live Tier-1 surface to ship
 * the pattern, triggering chassis-promotion per the codified
 * threshold rule.
 *
 * Surface-specific concerns that remain in surface code:
 *   - the IntersectionObserver footer script (lives in
 *     functions.php, one per surface, since each surface
 *     names its own anchor target ID — #enquire / #try /
 *     #cohorts).
 *   - none of the CSS rules differ across surfaces.
 *
 * Graceful degradation: with JS off, the column remains
 * sticky for the whole page on every surface.
 * ---------------------------------------------------------- */
.page-label {
	/* sticky on tablet+ so the page-label CTA stays visible
	   alongside the prose. Disabled when the column stacks
	   above the prose at ≤880px. Top offset uses
	   --scroll-padding-y (v0.5.133 fix) so the rail clears the
	   119px sticky site-header instead of sitting behind it —
	   the prior --s-7 (48px) was measured from the viewport
	   top and left ~71px hidden under the header. The same
	   token drives anchor-jump clearance, so both rails and
	   anchor jumps share one header-clearance source of truth. */
	position: sticky;
	top: var(--scroll-padding-y);
	align-self: start;
}
.page-label.is-released {
	/* Released by IntersectionObserver when the surface's
	   target anchor is in view. Drops out of sticky, scrolls
	   with the prose. The transition is intentionally instant
	   — a transitioned position-change would feel laggy on a
	   column that's already at its final eye-line. */
	position: static;
	top: auto;
}
.page-label-text {
	/* Block so the CTA below stacks cleanly. */
	display: block;
}
@media (max-width: 880px) {
	.page-label {
		position: static;
		top: auto;
	}
}

/* PAGE-LABEL CTA — ink-violet pill in the page-label column.
 * Solid --accent fill, paper text, sans uppercase at 12px /
 * 0.08em tracking. Stays inside the locked palette — no new
 * accent introduced. Reads as the loudest element on the
 * page during scroll, which is correct for a sticky CTA
 * whose job is to surface the in-page primary doorway. */
.page-label-cta {
	display: inline-flex;
	align-items: center;
	gap: var(--s-2);
	margin-top: var(--s-4);
	padding: var(--s-3) var(--s-4);
	font-family: var(--sans); font-weight: 600;
	font-size: 12px; line-height: 1;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--paper);
	background: var(--accent);
	text-decoration: none;
	transition:
		background var(--motion-duration-ui) var(--motion-ease-ui),
		transform   var(--motion-duration-ui) var(--motion-ease-ui);
}
.page-label-cta:hover {
	background: var(--ink);
	color: var(--paper);
}
.page-label-cta-arrow {
	display: inline-block;
	font-size: 14px; line-height: 1;
	transition: transform var(--motion-duration-ui) var(--motion-ease-ui);
}
.page-label-cta:hover .page-label-cta-arrow {
	transform: translateY(2px);
}

/* TOC sidebar — sticky on tablet+. CSS is shipped now so a
   future session can add the TOC partial without re-touching
   this stylesheet. */
.page-toc {
	/* top offset uses --scroll-padding-y (v0.5.133 fix), in
	   lockstep with .page-label above — clears the 119px
	   sticky site-header rather than sitting behind it. */
	position: sticky; top: var(--scroll-padding-y);
	padding-top: var(--s-3);
	border-top: 1px solid var(--ink);
	counter-reset: toc-counter;
}
.page-toc-label {
	font-family: var(--sans); font-weight: 600;
	font-size: 11px; line-height: 1;
	letter-spacing: 0.16em; text-transform: uppercase;
	color: var(--ink-quiet);
	margin-bottom: var(--s-4);
}
.page-toc ol {
	list-style: none; padding: 0; margin: 0;
	display: flex; flex-direction: column;
	gap: var(--s-3);
}
.page-toc li {
	counter-increment: toc-counter;
}
.page-toc a {
	font-family: var(--sans); font-weight: 400;
	font-size: 13px; line-height: 1.4;
	color: var(--ink-soft);
	text-decoration: none;
	display: flex; gap: var(--s-3);
	transition: color var(--motion-duration-ui) var(--motion-ease-ui);
}
.page-toc a::before {
	content: counter(toc-counter, decimal-leading-zero);
	color: var(--ink-quiet);
	font-weight: 600;
	flex-shrink: 0;
}
.page-toc a:hover { color: var(--ink); }

/* ----------------------------------------------------------
 * TOC FLOATING MODIFIER — v0.5.147
 *
 * For pages whose body is NOT a single-prose-column layout
 * and therefore cannot host the in-grid .page-toc (which
 * depends on .page-body-grid--has-toc grid context).
 *
 * Applied at v0.5.147 to /about/ and /consulting/, both of
 * which use multi-section layouts (firm-story / bench /
 * how-we-work / locations on About; consulting-framing /
 * sections / how-we-work / clientele on Consulting).
 *
 * Pattern: fixed-position TOC anchored to right edge of
 * viewport, vertically centred via top:50%/translateY,
 * z-index just below sticky site-header. Hidden ≤1080px
 * matching the existing .page-toc mobile-collapse rule.
 *
 * Does NOT override .page-toc's default sticky behaviour
 * because all base rules sit ABOVE this modifier in cascade.
 * ---------------------------------------------------------- */
.page-toc--floating {
	/* Sticky positioning inside .page-toc-host wrapper.
	   The host wraps all body sections (after page-header) and
	   provides:
	   - Initial Y: TOC sits at top of host = visually aligned
	     with first body section's label hairline because the
	     section's padding-top creates the natural offset.
	   - Sticky behaviour: TOC stays in flow until viewport top
	     reaches --scroll-padding-y, then pins.
	   Float right takes the TOC out of vertical flow so body
	   sections below render normally. Container right-padding
	   on body sections (rule below) reserves horizontal space.

	   Horizontal position is controlled by float + margin-right
	   to flush against the centred container's right edge. */
	position: sticky;
	top: var(--scroll-padding-y);
	float: right;
	clear: right;
	width: 220px;
	/* margin-top equals the first body section's padding-top so
	   the TOC's border-top hairline aligns with the section's
	   label border-top hairline. About uses --s-9 (96px) — the
	   default below. Consulting's first body section uses --s-8;
	   per-page override sits at the end of this block. */
	margin-top: var(--s-9);
	margin-right: max(var(--gutter), calc((100vw - var(--max-w)) / 2 + var(--gutter)));
	max-height: calc(100vh - var(--scroll-padding-y) - var(--s-7));
	overflow-y: auto;
	z-index: 90;
	background: var(--paper);
	padding-top: var(--s-3);
	border-top: 1px solid var(--ink);
}
@media (max-width: 1080px) {
	.page-toc--floating { display: none; }
}

/* .page-toc-host bottom calibration for sticky-TOC release.
   Sticky positioning releases the TOC when its bottom hits the
   host's content-area bottom. The host's last child is a body
   section that has bottom padding (--s-9 on About's .links-rail,
   --s-8 on Consulting's .consulting-clientele-section); without
   this rule, the TOC remained sticky through that padding
   region — appearing to overshoot the visible content end.
   Zeroing the last child's bottom padding pulls the host bottom
   up to where visible content ends, and the .site-footer's
   margin-top: var(--s-9) absorbs the visual whitespace below. */
.page-toc-host > section:last-child {
	padding-bottom: 0;
}
/* Per-page TOC margin-top override.
   Consulting's first body section (.consulting-framing) uses
   padding-block: var(--s-8) (64px). The TOC's default
   margin-top: var(--s-9) (96px) overshoots the hairline by 32px;
   this rule pulls it back to align. */
body.page-template-page-consulting .page-toc--floating {
	margin-top: var(--s-8);
}

/* Floating-TOC overlap prevention — v0.5.153.
   Body sections inside .page-toc-host need right-padding to
   reserve space for the sticky-floating TOC. Without this,
   block-level section content flows full-width and visually
   overlaps the floated TOC. Scope: body class + .page-toc-host
   descendant > section > .container. */
@media (min-width: 1081px) {
	body.page-template-page-about .page-toc-host > section > .container,
	body.page-template-page-consulting .page-toc-host > section > .container {
		padding-right: calc(var(--gutter) + 220px + var(--s-7));
	}
}

/* the prose column */
.page-prose {
	max-width: 60ch;
}
.page-prose > * + * { margin-top: var(--s-5); }
.page-prose p + p { margin-top: var(--s-7); }

/* paragraphs */
.page-prose p {
	font-family: var(--serif); font-weight: 400;
	font-size: 18px; line-height: 1.7;
	color: var(--ink-soft);
	margin: 0;
}
.page-prose p em { font-style: italic; }
.page-prose p strong { font-weight: 600; color: var(--ink); }
.page-prose a {
	color: var(--ink);
	text-decoration: none;
	border-bottom: 1px solid var(--rule);
	transition: border-color var(--motion-duration-ui) var(--motion-ease-ui);
}
.page-prose a:hover { border-bottom-color: var(--accent); }

/* lede — first paragraph reads slightly larger */
.page-prose p.lede {
	font-size: 21px; line-height: 1.6;
	color: var(--ink);
}

/* headings */
.page-prose h2 {
	font-family: var(--serif); font-weight: 400;
	font-size: clamp(24px, 2.4vw, 30px);
	line-height: 1.2; letter-spacing: -0.012em;
	color: var(--ink);
	margin: var(--s-8) 0 0 0;
	padding-top: var(--s-5);
	border-top: 1px solid var(--rule);
	scroll-margin-top: var(--s-9);
}
.page-prose h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.page-prose h2 em { font-style: italic; }

.page-prose h3 {
	font-family: var(--serif); font-weight: 600;
	font-size: 20px; line-height: 1.3;
	color: var(--ink);
	margin-top: var(--s-7);
}

/* heading + first paragraph proximity — pull the para closer */
.page-prose h2 + p,
.page-prose h3 + p {
	margin-top: var(--s-5);
}

/* lists */
.page-prose ul,
.page-prose ol {
	font-family: var(--serif); font-weight: 400;
	font-size: 18px; line-height: 1.7;
	color: var(--ink-soft);
	margin: 0; padding-left: var(--s-6);
}
.page-prose ul li + li,
.page-prose ol li + li { margin-top: var(--s-3); }
.page-prose ul { list-style: square; }
.page-prose ul li::marker { color: var(--ink-quiet); }

/* table — for things like cookie-list disclosures */
.page-prose table {
	width: 100%;
	border-collapse: collapse;
	font-family: var(--sans); font-weight: 400;
	font-size: 14px; line-height: 1.5;
	color: var(--ink-soft);
}
.page-prose th,
.page-prose td {
	text-align: left;
	padding: var(--s-3) var(--s-4) var(--s-3) 0;
	border-bottom: 1px solid var(--rule);
	vertical-align: top;
}
.page-prose th {
	font-family: var(--sans); font-weight: 600;
	font-size: 11px; line-height: 1;
	letter-spacing: 0.14em; text-transform: uppercase;
	color: var(--ink-quiet);
	border-bottom-color: var(--ink);
	padding-bottom: var(--s-3);
}
.page-prose th:not(:last-child),
.page-prose td:not(:last-child) {
	padding-right: var(--s-5);
}

/* callout — quiet emphasis pattern. Used sparingly; for legal
   pages that need to surface one or two facts above the prose
   ("we don't sell your data", etc.). NOT a generic info box. */
.page-callout {
	font-family: var(--serif); font-style: italic; font-weight: 400;
	font-size: clamp(18px, 1.7vw, 22px);
	line-height: 1.5; color: var(--ink);
	border-left: 2px solid var(--accent);
	padding-left: var(--s-5);
	padding-block: var(--s-3);
	max-width: 56ch;
}
.page-callout em { font-style: normal; }

/* #79 retrofit (v41) — symmetric vertical breathing space
   around .page-callout. Higher specificity (0,2,0) beats both
   chassis rules. Per op-learning #16. */
.page-prose .page-callout {
	margin-top: var(--s-7);
	margin-bottom: var(--s-7);
}

/* hr — used for sub-section breaks within a major section */
.page-prose hr {
	border: 0;
	border-top: 1px solid var(--rule);
	margin-block: var(--s-7);
	width: 6ch;
	margin-inline: 0;
}


/* ============================================================
   .section-header chassis — Tier-1 page variant
   v0.5.69 retrofit · 9 May 2026 · defect #340 fix.

   Lifted verbatim from canonical
   flibbr-design-mockup-final-consulting.html (lines 1862–1890,
   marked there as "verbatim chassis from homepage").

   Used by Consulting (§3, §4, §6, §7, §8) and any other Tier-1
   page that opts into the .section / .section-header pattern.

   Homepage carries its own smaller .section-header variant in
   home.css scoped under body.home — this rule is the default
   for everywhere else.
   ============================================================ */

.section-header {
	display: grid;
	grid-template-columns: 200px 1fr;
	gap: var(--s-7);
	align-items: baseline;
	margin-bottom: var(--s-7);
	padding-top: var(--s-3);
	border-top: 1px solid var(--ink);
}
@media (max-width: 880px) {
	.section-header {
		grid-template-columns: 1fr;
		gap: var(--s-3);
	}
}
.section-header .label {
	font-family: var(--sans); font-weight: 600;
	font-size: 11px; line-height: 1.2;
	letter-spacing: 0.16em; text-transform: uppercase;
	color: var(--ink-quiet);
}
.section-header .name {
	font-family: var(--serif); font-weight: 400;
	font-size: clamp(28px, 3.5vw, 44px);
	line-height: 1.10; letter-spacing: -0.012em;
	color: var(--ink); margin: 0;
	text-wrap: balance;
}
.section-header .name em { font-style: italic; }

/* G.3b — page-label-cta tap-target */
@media (max-width: 880px) {
	.page-label-cta {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
		gap: var(--s-3);
	}
}

/* ============================================================
   H. SEARCH PAGE + 404 — contact-path tail-rail + result-list
   @added v0.5.172 / Ship 11-C
   ------------------------------------------------------------
   Three new component families consumed by search.php (and 404.php,
   which shares the same .contact-path-* tail markup):

     H.1 .contact-paths / .contact-path  — three-door card grid for
         empty-state tail (used by /search/ empty + zero-results,
         and by /404/ "where to go from here").
     H.2 .search-results-section / .search-result — flat row list
         of mixed-CPT results.
     H.3 .search-results-pagination — themed WP pagination.

   Class names mirror the markup in flibbr/search.php and flibbr/404.php.
   Before Ship 11-C these classes had no rules anywhere in the theme;
   search and 404 rendered as unstyled HTML. CSS authored in the locked
   canonical flibbr-design-mockup-final-search.html.
============================================================ */

/* H.1 — contact-paths (three-door card grid) */
.contact-paths-section {
	padding-block: var(--s-8) var(--s-9);
}
.contact-paths {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--s-5);
}
@media (max-width: 880px) {
	.contact-paths {
		grid-template-columns: 1fr;
		gap: var(--s-4);
	}
}

.contact-path {
	display: flex; flex-direction: column;
	gap: var(--s-3);
	padding: var(--s-5);
	border: 1px solid var(--rule);
	background: var(--paper);
	text-decoration: none; color: inherit;
	/* base hover transition declared by chassis (.contact-path translateY) */
}
.contact-path:hover {
	background: var(--paper-warm);
	border-color: var(--ink-quiet);
}

.contact-path-kicker {
	font-family: var(--sans); font-weight: 600;
	font-size: 11px; line-height: 1;
	letter-spacing: 0.16em; text-transform: uppercase;
	color: var(--accent);
}

.contact-path-headline {
	font-family: var(--serif); font-weight: 400;
	font-size: clamp(20px, 2.2vw, 24px);
	line-height: 1.18; letter-spacing: -0.008em;
	color: var(--ink);
	margin: 0;
	text-wrap: balance;
}
.contact-path-headline em { font-style: italic; }

.contact-path-supporting {
	font-family: var(--serif); font-weight: 400;
	font-size: 15px; line-height: 1.5;
	color: var(--ink-soft);
	margin: 0;
	max-width: 38ch;
}

.contact-path-cta {
	margin-top: auto;
	padding-top: var(--s-3);
	font-family: var(--sans); font-weight: 500;
	font-size: 13px; line-height: 1.2;
	letter-spacing: 0.04em;
	color: var(--ink);
	display: inline-flex; align-items: center; gap: var(--s-2);
}
.contact-path-cta .flibbr-arrow {
	transition: transform var(--motion-duration-ui) var(--motion-ease-ui);
}
.contact-path:hover .contact-path-cta .flibbr-arrow {
	transform: translateX(calc(4px * var(--motion-ok)));
}

/* H.2 — search results list */
.search-results-section {
	padding-block: var(--s-8) var(--s-9);
}
.search-results-list {
	display: flex; flex-direction: column;
	border-top: 1px solid var(--rule);
}
.search-result {
	display: flex; flex-direction: column;
	gap: var(--s-2);
	padding-block: var(--s-5);
	border-bottom: 1px solid var(--rule);
	text-decoration: none; color: inherit;
	transition: padding var(--motion-duration-ui) var(--motion-ease-ui);
}
.search-result:hover {
	padding-left: var(--s-3);
	background: var(--paper-warm);
}
.search-result-kicker {
	font-family: var(--sans); font-weight: 600;
	font-size: 11px; line-height: 1;
	letter-spacing: 0.16em; text-transform: uppercase;
	color: var(--accent);
}
.search-result-headline {
	font-family: var(--serif); font-weight: 500;
	font-size: clamp(20px, 2.0vw, 22px);
	line-height: 1.25; letter-spacing: -0.005em;
	color: var(--ink);
	margin: 0;
}
.search-result-headline em { font-style: italic; font-weight: 400; }
.search-result-summary {
	font-family: var(--serif); font-weight: 400;
	font-size: 15px; line-height: 1.55;
	color: var(--ink-soft);
	margin: 0;
	max-width: 65ch;
}
.search-result-meta {
	font-family: var(--sans); font-weight: 400;
	font-size: 11px; line-height: 1.2;
	letter-spacing: 0.06em; text-transform: uppercase;
	color: var(--ink-quiet);
}

/* H.3 — pagination */
.search-results-pagination {
	margin-top: var(--s-7);
	padding-top: var(--s-5);
	border-top: 1px solid var(--rule);
	font-family: var(--sans); font-size: 13px;
	color: var(--ink-quiet);
}
.search-results-pagination .page-numbers {
	display: inline-block;
	padding: var(--s-2) var(--s-3);
	margin-right: var(--s-2);
	text-decoration: none; color: var(--ink-quiet);
	border: 1px solid transparent;
	transition: color var(--motion-duration-ui) var(--motion-ease-ui),
	            border-color var(--motion-duration-ui) var(--motion-ease-ui);
}
.search-results-pagination .page-numbers:hover,
.search-results-pagination .page-numbers.current {
	color: var(--ink);
	border-color: var(--rule);
}

/* ============================================================
   v0.5.274 (Ship C): mobile prose typography tightening.

   At <=880px the .page-prose paragraph block tightens its
   line-height from 1.7 to 1.55 and reduces inter-paragraph
   margin from --s-7 (48px) to --s-6 (32px). Net effect:
   ~3px per visible line + 16px per paragraph gap. On a
   ~80-paragraph page like About, this saves ~1500-1800px
   of vertical scroll.

   Body font-size kept at 18px (the desktop value) — shrinking
   font-size at mobile would mean smaller body text on the
   narrowest viewport, opposite of the mobile-legibility
   principle the project applies elsewhere.

   Placed at end-of-file to ensure source-order wins over the
   base .page-prose rules at L317-321 (op-learning
   #G-source-order from Ship A v0.5.273).
   ============================================================ */
@media (max-width: 880px) {
  .page-prose p {
    line-height: 1.55;
  }
  .page-prose p + p {
    margin-top: var(--s-6);
  }
}
