/* ============================================================
   tmj-lean.css — components for the lean page pass (2026-08-17)

   Three components, each introduced to REPLACE prose, not to reorganise it.
   See docs/superpowers/specs/2026-08-17-lean-page-optimization.md

     1. .ac-signal-grid  — icon cards, replaces prose symptom lists
     2. .ac-steps        — numbered row, replaces Goals + Steps prose sections
     3. .ac-faq-compact  — density modifier on the existing .ac-accordion

   DESIGN LAW (client, 2026-08-18) — HARD CORNERS ONLY.
   The square corner is deliberate: it echoes the diamond in the logo. Nothing in
   this file may carry a border-radius, and icon grounds are ROTATED SQUARES, not
   circles — matching .quiz-icon (tmj-cards.css:115) and .condition-icon
   (tmj-modules.css:608), which are the site's established icon treatments.
   The first version of this file used 14px radii and circular icon badges. Both
   were wrong.

   Band colours this file is designed against (tmj-sections.css:46-50):
     .s--dark #153b37 · .s--dark2 #1a4a45 · .s--light #fff · .s--mist #f1f6f5

   TRAP this file must not repeat: the theme has two inverse light/dark text
   conventions and getting them backwards fails silently. Every component here
   states its text colour explicitly rather than inheriting.
   ============================================================ */

/* ------------------------------------------------------------
   1. SIGNAL GRID — .ac-signal-grid
   Designed for .s--mist. Use .ac-signal-grid--on-dark on .s--dark.
   ------------------------------------------------------------ */

/* DIAMOND GEOMETRY — one side length for the whole system.
   A square of side S rotated 45deg is S*sqrt(2) tall, so it bleeds
   S*(sqrt(2)-1)/2 = 0.2071*S past its own box, top and bottom. Every margin and
   flex `gap` is measured from the BOX, so that bleed silently eats the spacing:
   the peach diamond sat 1.2px above its heading while the CSS said 12px.
   --ac-diamond-bleed is that overhang, precomputed, and every rule that needs
   clearance around a diamond adds it explicitly.
   Client, 2026-08-18: the peach diamonds must match the green ones. They were 52px
   against the steps' 40px. */
.ac-signal-grid,
.ac-steps {
	--ac-diamond: 2.5rem;
	--ac-diamond-bleed: 0.5178rem;
}

.ac-signal-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
	gap: 1.25rem;
	max-width: 1080px;
	margin: 0 auto;
	padding: 0;
	list-style: none;
}

/* 4 items should read as one row on desktop, not 3 + 1 orphan. */
@media (min-width: 1100px) {
	.ac-steps { grid-template-columns: repeat(4, 1fr); }
	.ac-signal-grid[data-count="4"] { grid-template-columns: repeat(4, 1fr); }
	.ac-signal-grid[data-count="3"] { grid-template-columns: repeat(3, 1fr); }
	.ac-signal-grid[data-count="2"] { grid-template-columns: repeat(2, 1fr); max-width: 760px; }

	/* Two counts the home page's clinical-argument sections need, written the same
	   way as the four above rather than as new components.

	   6 goes 3x2, not 4+2. auto-fit against minmax(230px,1fr) inside 1080px
	   resolves to four tracks, so a six-item grid orphans two cards on a second
	   row — the exact defect the [data-count] rules exist to prevent.

	   5 gets a wider cap, and the number is derived rather than picked. The shared
	   1080px holds four tracks of 255px; five tracks of that same 255px plus four
	   1.25rem gaps needs 1355px. So the five-up is not "wider", it is the same card
	   at a fifth column — which is the only reading under which these components
	   stay one system.

	   It was 1080px first, which squeezed the tracks to 200px: correct by the
	   letter of the shared cap and wrong on the page, because .s-container runs to
	   1440px and the row sat inside 216-360px of dead margin while its longest
	   step wrapped to six lines. Client, 2026-08-31, looking at the rendered
	   section: "the wrapper seems like it could be bigger to account for all the
	   items in there."

	   The cost, stated because bin/check-spacing.py reports it and the next person
	   will see it: this row's content edge no longer matches the 1080px grids in
	   the sections above and below it. That check compares every content block on a
	   page against one edge, and the home page cannot satisfy it either way —
	   .conditions-grid already runs the full container. A five-up at 1080 is
	   narrower than both of them; at 1355 it sits between them. Do not "fix" the
	   spread by widening the base 1080px cap: that is the 2-up through 4-up card
	   width for twenty lean pages, and it is not this section's decision to make.

	   .ac-steps carries data-count for the first time here: it had a bare
	   repeat(4, 1fr) and no opt-out, which is why a five-step row was not
	   expressible before. Existing markup passes no data-count, so nothing that
	   already ships changes. */
	.ac-signal-grid[data-count="6"] { grid-template-columns: repeat(3, 1fr); }
	.ac-signal-grid[data-count="5"],
	.ac-steps[data-count="5"] { grid-template-columns: repeat(5, 1fr); max-width: 1355px; }
	.ac-steps[data-count="3"] { grid-template-columns: repeat(3, 1fr); }
}

.ac-signal {
	display: flex;
	flex-direction: column;
	gap: 1rem;
	padding: 1.75rem 1.5rem;
	background: var(--white);
	border: 1px solid var(--gray-light);
	/* No border-radius. Hard corners are the design language. */
	transition: transform 0.35s ease, box-shadow 0.35s ease, border-color 0.35s ease;
}

.ac-signal:hover {
	transform: translateY(-4px);
	border-color: var(--light);
	box-shadow: 0 12px 30px rgba(21, 59, 55, 0.09);
}

/* Diamond icon ground — the same construction as .quiz-icon: a square rotated
   45deg behind an unrotated SVG. Rotating the box and counter-rotating the icon
   would blur the strokes, so only the ::before turns. */
.ac-signal__icon {
	position: relative;
	width: var(--ac-diamond);
	height: var(--ac-diamond);
	flex: 0 0 auto;
	/* Push the box down by the bleed so the diamond's top point starts at the
	   card padding rather than above it, and pad the bottom by the bleed plus a
	   little, so the visual gap to the heading is ~20px and not ~1px. */
	margin-top: var(--ac-diamond-bleed);
	margin-bottom: calc(var(--ac-diamond-bleed) + 0.25rem);
}

.ac-signal__icon::before {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--accent);
	transform: rotate(45deg);
	transition: transform 0.4s ease;
}

.ac-signal:hover .ac-signal__icon::before { transform: rotate(45deg) scale(1.08); }

.ac-signal__icon svg {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	width: 20px;
	height: 20px;
	fill: none;
	stroke: var(--dark);
	stroke-width: 1.5;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* ---- .ac-icon : the practice's own icon set ------------------------------
   Client 2026-09-11: a commissioned set of 30 glyphs (TMJ-Utah-Icons), installed
   at uploads/2026/09/icons/. They replace the generic Feather-style line icons
   that were drawn inline in page content — the ones that had to stand in for
   "tongue tie", "airway collapse" and "bite misalignment" with a rectangle and
   two strokes.

   ONE rule for all of them, because the four wrappers that hold an icon on this
   site (.ac-signal__icon, .quiz-icon, .condition-icon, .contact-card-icon) are
   already the same component in four sizes: an absolutely-centred glyph inside a
   rotated diamond. The wrapper keeps owning the diamond and the size; this owns
   the glyph. Anything that gains an icon later gets it by adding .ac-icon, not by
   another copy of these six lines.

   No colour handling: the PNGs are flat #153b37 with alpha, which is the same ink
   the inline SVGs stroked, so they land on the coral diamond exactly as before.
   A wrapper that needs white glyphs can filter this element — see .icon-badge in
   primitives.css, which already does that for its own images. */
.ac-icon {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	/* 82%, not the ~62% a 24x24 stroke icon needed. These PNGs carry ~11% of empty
	   canvas on each side, so the glyph itself ends up at 82 x 0.79 = 65% of the
	   wrapper -- which is what fits inside a rotated square's inscribed width
	   (1/sqrt(2) = 71%) with a little air. Measured off the alpha bounding boxes,
	   which are consistent across the set. */
	width: 82%;
	height: auto;
	max-width: none;
	object-fit: contain;
	pointer-events: none;
}

/* Pediatric pages may use the client's own illustrations (Website-Icons-16..21).
   They are full-colour artwork, so they get no diamond ground.

   Their footprint MUST equal the diamond's, or a grid that mixes the two breaks:
   an 84px drawing beside a 40px diamond pushed the card titles ~44px out of line,
   which forced one page to go all-illustration including two loose matches. The
   diamond occupies --ac-diamond * sqrt(2) of visual height (the rotation) plus its
   margins, so the illustration is sized to exactly that and drops the bleed
   margins it does not need. Mixed rows now align. */
.ac-signal__icon--illus {
	width: calc(var(--ac-diamond) * 1.4142);
	height: calc(var(--ac-diamond) * 1.4142);
	margin-top: 0;
	margin-bottom: 0.25rem;
}

.ac-signal__icon--illus::before { display: none; }

.ac-signal__icon--illus img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	display: block;
}

.ac-signal__title {
	margin: 0;
	font-size: 1.0625rem;
	line-height: 1.35;
	font-weight: 700;
	color: var(--text-dark);
}

.ac-signal__text {
	margin: 0;
	font-size: 0.9375rem;
	line-height: 1.6;
	color: var(--text-muted-dark);
}

/* On a dark band. Stated explicitly — do NOT rely on .white inheritance. */
.ac-signal-grid--on-dark .ac-signal {
	background: var(--dark-mid);
	border-color: rgba(62, 133, 124, 0.3);
}

.ac-signal-grid--on-dark .ac-signal:hover {
	border-color: var(--light);
	box-shadow: 0 12px 30px rgba(0, 0, 0, 0.25);
}

.ac-signal-grid--on-dark .ac-signal__title { color: var(--white); }
.ac-signal-grid--on-dark .ac-signal__text { color: var(--text-light); }

/* ------------------------------------------------------------
   2. STEPS — .ac-steps
   Replaces the stacked "Goals Of Treatment" + "Steps Of Treatment" prose
   sections with one scannable row. Designed for .s--light.
   ------------------------------------------------------------ */

.ac-steps {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	/* Column gap matches .ac-signal-grid (1.25rem) so both sections resolve to the
	   same 255px tracks and their columns align down the page. */
	gap: 2rem 1.25rem;
	max-width: 1080px;
	margin: 0 auto;
	padding: 0;
	list-style: none;
	counter-reset: ac-step;
	/* Space from the lead paragraph above. The diamonds bleed upward past the
	   li box, so the visual gap is this margin minus --ac-diamond-bleed. */
	margin-top: 2.75rem;
}

.ac-step {
	position: relative;
	counter-increment: ac-step;
	/* Diamond spans -bleed .. (diamond + bleed) from the li top, so clear it. */
	padding-top: calc(var(--ac-diamond) + var(--ac-diamond-bleed) + 1.25rem);
}

/* Diamond badge. ::before is the rotated ground, ::after carries the numeral
   upright — one pseudo-element cannot be both rotated and hold level text.
   This is why there is no connector rule: it previously lived on ::after. */
.ac-step::before {
	content: "";
	position: absolute;
	top: var(--ac-diamond-bleed);
	/* Left must be the BLEED, not an arbitrary offset: the rotated square sticks
	   out --ac-diamond-bleed to the left of its box, so left:4px put the diamond's
	   point 4.28px OUTSIDE the 1080px grid while the text sat on the edge. That
	   4px overhang is what made this section look wider than the card grid. */
	left: var(--ac-diamond-bleed);
	width: var(--ac-diamond);
	height: var(--ac-diamond);
	background: var(--dark);
	transform: rotate(45deg);
	/* Offset accent shadow behind the diamond. Note the offset is applied in the
	   element's OWN coordinate space and then rotated with it, so -2px 2px does not
	   read as left-and-down on screen — at 45deg it resolves to roughly 2.8px
	   straight left. That is the intended look; do not "correct" it to 0 -2.8px. */
	box-shadow: -2px 2px var(--accent);
}

.ac-step::after {
	content: counter(ac-step);
	position: absolute;
	top: var(--ac-diamond-bleed);
	left: var(--ac-diamond-bleed);
	width: var(--ac-diamond);
	height: var(--ac-diamond);
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--white);
	font-family: 'Gilda Display', Georgia, serif;
	font-size: 1.125rem;
	line-height: 1;
}

.ac-step__title {
	margin: 0 0 0.875rem;
	font-size: 1.0625rem;
	line-height: 1.35;
	font-weight: 700;
	color: var(--text-dark);
}

.ac-step__text {
	margin: 0;
	font-size: 0.9375rem;
	line-height: 1.6;
	color: var(--text-muted-dark);
}

/* On a dark band the diamond itself is accent, so the accent shadow would vanish
   into it — flip the shadow to the dark green instead. */
.ac-steps--on-dark .ac-step::before { background: var(--accent); box-shadow: -2px 2px var(--dark); }
.ac-steps--on-dark .ac-step::after  { color: var(--dark); }
.ac-steps--on-dark .ac-step__title  { color: var(--white); }
.ac-steps--on-dark .ac-step__text   { color: var(--text-light); }

/* ------------------------------------------------------------
   3. COMPACT FAQ — .ac-faq-compact
   A density modifier ONLY. It rides on the existing .ac-accordion so
   initAccordions() in tmj-components.js keeps driving it. Never add an inline
   accordion script to post_content (double-bind, HANDOFF §13).
   Base is gap:12px, max-width:820px, trigger 22px/26px, content padding on the
   `p` (0 26px), open padding-bottom 24px — verified against
   tmj-components.css:283-421, not assumed.
   ------------------------------------------------------------ */

.ac-accordion.ac-faq-compact { gap: 8px; }

/* Square off the accordion's own 14px radius on lean pages only, so the FAQ
   matches the hard-cornered cards beside it. */
.ac-accordion.ac-faq-compact .ac-accordion-item { border-radius: 0; }

.ac-accordion.ac-faq-compact .ac-accordion-trigger { padding: 16px 22px; }

.ac-accordion.ac-faq-compact .ac-accordion-title { font-size: clamp(15px, 1.4vw, 16.5px); }

.ac-accordion.ac-faq-compact .ac-accordion-content-inner p {
	padding: 0 22px;
	font-size: 15px;
	line-height: 1.6;
}

.ac-accordion.ac-faq-compact .ac-accordion-item.is-open .ac-accordion-content-inner {
	padding-bottom: 18px;
}

/* ------------------------------------------------------------
   4. UTILITIES
   ------------------------------------------------------------ */

.u-measure      { max-width: 900px;  margin-left: auto; margin-right: auto; }
.u-measure-wide { max-width: 1080px; margin-left: auto; margin-right: auto; }

/* Was style="height:80vh" on .hero-diamonds (the floating-diamond layer), not on
   the section — checked against the live markup rather than assumed. */
.hero-diamonds--tall { height: min(80vh, 660px); }

/* IMAGE SIZING — constrain WIDTH, never height.
   `.s-imgwrap > img` (tmj-sections.css:100) sets width:100%;height:auto. Adding a
   max-height on top of that clamps the height while the width stays 100%, which
   DISTORTS the image — that is exactly how the TMJ infographic shipped stretched.
   Capping the width instead keeps height:auto in charge, so the aspect ratio is
   always the file's own. Client rule: never warp; source or crop an image that
   fits the section rather than forcing one that does not. */
.u-img-fit {
	max-width: 460px;
	margin-left: auto;
	margin-right: auto;
}

/* Cutting words alone barely shortened the page — the rest was padding and list
   spacing. Measured: 39% fewer words bought only 14% less height until these. */

/* .featured-list at full width runs one item per row: five treatments = ~475px.
   Two columns and tighter rhythm bring that under 300px without shrinking type. */
.featured-list--compact li { padding: 0.5rem 0; }
.featured-list--compact .info-text { margin-bottom: 0; font-size: 0.9375rem; }
.featured-list--compact .info-subtitle { margin-bottom: 0.125rem; }

@media (min-width: 900px) {
	.featured-list--compact {
		display: grid;
		grid-template-columns: 1fr 1fr;
		column-gap: 2.5rem;
	}
	.featured-list--compact li:nth-last-child(-n+2):nth-child(odd) ~ li,
	.featured-list--compact li:last-child { border-bottom: none; }
}

/* Section padding for lean pages. The skeleton's s--pt-80/s--pb-54 is 134px per
   section, ~940px across a 7-section page — more than the copy it frames. */
.s--lean { padding-top: 3.75rem; padding-bottom: 2.5rem; }
.s--lean-tight { padding-top: 3rem; padding-bottom: 2rem; }

/* Mobile. The grid's 230px minimum would drop to one card per row at 390px, which
   made this the TALLEST section on the page (1,175px of 6,755px measured). The
   cards carry an icon, a short label and one clause, so they hold up two-up if the
   icon and padding come down with them. */
@media (max-width: 640px) {
	.ac-signal-grid,
	.ac-signal-grid[data-count="3"],
	.ac-signal-grid[data-count="4"] {
		grid-template-columns: 1fr 1fr;
		/* Row gap a touch wider than the column gap: stacked rows need more
		   separation than side-by-side cards, which already have their borders. */
		gap: 1rem 0.75rem;
	}

	.ac-signal-grid { --ac-diamond: 2rem; --ac-diamond-bleed: 0.4142rem; }
	.ac-signal { padding: 1.125rem 0.875rem; gap: 0.875rem; }
	.ac-signal__icon svg { width: 17px; height: 17px; }
	.ac-signal__title { font-size: 0.9375rem; }
	.ac-signal__text  { font-size: 0.875rem; line-height: 1.5; }

	.ac-steps { --ac-diamond: 2rem; --ac-diamond-bleed: 0.4142rem; margin-top: 2rem; }
}

/* A section that carries a grid and then keeps going. Both components were built
   as the LAST thing in their section, so neither has a bottom margin — put a
   paragraph after one and the text sits flush against the card borders. Measured
   at 0.0px by bin/check-spacing.py on the home page's two new grid sections.
   2.75rem is the same gap .ac-steps already uses to clear the lead paragraph
   above it, so a section reads with one rhythm whichever side the prose is on. */
.ac-signal-grid + .info-content,
.ac-steps + .info-content,
.ac-signal-grid + .section-header,
.ac-steps + .section-header { margin-top: 2.75rem; }

/* The trademark mark on "The Ferzli Clinical Systems Model™". Gilda Display has
   no ™ glyph, so the browser falls back to a font that does and paints it at full
   weight, and <sup>'s default `font-size: smaller` only steps 56px down to 46.7px
   — which reads as two capital letters sitting in the headline rather than as a
   mark. Scoped to .section-title so it cannot touch a <sup> in body copy. */
.section-title sup { font-size: 0.32em; vertical-align: super; letter-spacing: 0; }

/* A sub-head introducing a second component inside one section. The other four
   .info-content > .info-subtitle on the home page compute to 18px; this one came
   out at 12px, which check-spacing.py flags. Match them rather than invent a
   third value. No other page has a direct .info-content > .info-subtitle child,
   so the blast radius is that one heading. */
.info-content > .info-subtitle { margin-bottom: 1.125rem; }

/* Very narrow phones cannot carry two columns of text cards legibly. */
@media (max-width: 359px) {
	.ac-signal-grid,
	.ac-signal-grid[data-count="3"],
	.ac-signal-grid[data-count="4"] { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------
   5. SCREENING BLOCK — spacing only
   The restored Cleveland block is reproduced faithfully, including its 60px
   .quiz-icon. But it has the same diamond-bleed defect as everything else: a 60px
   square rotated 45deg bleeds 12.43px past its box, so its 24px margin-bottom
   leaves 11.6px of real clearance under the diamond's point.

   SCOPED to .s--screening on purpose. .quiz-icon is a shared component and the
   identical gap exists wherever else quiz cards appear; correcting it globally
   would silently restyle pages outside this pass. Flagged for the client instead.
   ------------------------------------------------------------ */

/* .quiz-cta-inner has no max-width of its own, so it filled the 1296px
   .s-container while every other content block on the page is 1080px — the
   screening band read as 108px wider per side than the sections above it.
   Matched to the page's single content edge. Scoped, like the spacing fix. */
.s--screening .quiz-cta-inner {
	max-width: 1080px;
	margin-left: auto;
	margin-right: auto;
}

.s--screening .quiz-icon { margin-bottom: calc(1.5rem + 0.7766rem); }
.s--screening .quiz-card h3 { margin-bottom: 1rem; }

/* ------------------------------------------------------------
   6. BLOCKQUOTE — client-supplied values, 2026-08-18
   Applied site-wide. Blockquotes exist on 7 published pages and in ZERO blog
   posts (checked), and all of them sit on white bands, so this is low blast
   radius. There was no blockquote treatment before this — only the colour fix in
   tmj-modules.css:678 that stopped them rendering invisible.
   No border-radius: hard corners.
   ------------------------------------------------------------ */

blockquote {
	background: rgb(241, 246, 245);
	margin: 0;
	margin-bottom: 1.25rem;
	padding: 1.25rem;
	font-style: italic;
}

/* rgb(241,246,245) IS --mist, i.e. the exact background of an .s--mist section, so
   the quote would vanish into the band. White keeps the same "inset panel" read.
   Nothing uses this today; it is here so the rule cannot fail silently later. */
.s--mist blockquote,
.s--tint blockquote {
	background: var(--white);
}

/* On a dark band the mist panel would be near-white behind light text. A
   translucent lift keeps the panel legible and the text light. */
.s--dark blockquote,
.s--dark2 blockquote {
	background: rgba(255, 255, 255, 0.06);
}

/* The citation is a separate voice from the quote — keep it upright so the two do
   not run together, and give it a little air. */
blockquote footer {
	margin-top: 0.625rem;
	font-style: normal;
	font-size: 0.875rem;
}

/* ------------------------------------------------------------
   7. HOME HERO — full-viewport stage + anatomical callouts
   Small labelled markers over the hero illustration, naming the systems the
   practice treats. Borrowed device, not borrowed design: the reference build
   the client liked used floating pills to say "this is more than a jaw", which
   is the one idea worth taking from it.

   7a. THE STAGE. The hero used to be sized only by its own padding — 661px tall
   in a 900px viewport — which letterboxed the illustration and left the
   credibility bar stranded in the middle of the fold. It now fills the viewport
   above that bar, so hero + bar is exactly one screen.

   7b. WHY THE CALLOUTS DRIFTED. They were positioned as percentages of
   .s-hero__bg — a 60%-wide box painting a 3:2 picture with background-size:cover.
   Cover scales that picture to the box's HEIGHT here, so the painted image is
   1.5x the hero's height and much wider than the box holding it: the box's
   0-100% and the picture's 0-100% are simply not the same axis, and every change
   of viewport slid the labels off the anatomy they were naming. Measured at
   1440x900, "Airway & Breathing" sat 340px to the left of the airway, out in
   flat gradient.

   The fix is to stop positioning against the box. .hero-callouts is now sized to
   the PAINTED PICTURE: aspect-ratio 1536/1024 with min-width/min-height 100%
   reproduces background-size:cover exactly, and right + translateY reproduce
   background-position:right center. Percentages inside it are therefore
   picture-relative, so a node pinned to the jaw joint stays on the jaw joint at
   every width. The coordinates below were read off the source file against a
   percentage grid, not eyeballed against a screenshot.

   7c. THE MARKER. Each callout is a plate, a hairline leader, and a diamond node
   sitting on the structure it names — the anatomical-plate convention, which is
   the honest version of what the free-floating pills were gesturing at. Label and
   node share a y, so every leader is horizontal by construction: no trigonometry,
   and nothing to re-tune per breakpoint.

   Shown from 1024px, which is where the side-strip hero layout itself starts.
   The old 1200px floor existed because a leader needs a margin to be drawn into
   and there was none left below that; a pill that sits on its own point needs
   no margin, so the markers now reach every width where the strip exists. Below
   900px the mobile rule flattens .s-hero__bg into a 185px band and the markers
   go away with it — pinning to a letterboxed strip would mean nothing.
   ------------------------------------------------------------ */

/* --- 7a. The stage ------------------------------------------------------- */

body.home {
	/* .anchor-block--1093895, the "Over 70 Centres" bar: 27px + 65px + 27px.
	   Declared here rather than measured in JS so the hero has a height on the
	   first paint; verified against the rendered bar at 1200-1920. */
	--credbar-h: 119px;

	/* The theme's warm cream. There is no cream token: the only place the value
	   existed at all was .s--tint's rgba(241,240,239,0.36) in tmj-sections.css,
	   where the alpha hides what the underlying colour is. Same colour, named.
	   Scoped to the home page rather than :root deliberately — it is one page's
	   need today, and .s--tint still carries its own literal. Promote both to a
	   shared token if a third caller shows up. Warm on purpose: --mist (#f1f6f5)
	   is the cool sibling and goes green against the peach illustration. Stored
	   as components so callers set their own alpha without re-typing the hex. */
	--cream-rgb: 241, 240, 239;
	--cream: rgb(var(--cream-rgb));
}

@media (min-width: 1024px) {
	/* The stage height is capped against the viewport's WIDTH as well as its
	   height, and that second term is the important one.

	   .s-hero__bg is a box 60% of the viewport wide painting a 3:2 picture with
	   background-size:cover, so the box's ASPECT — not its size — decides how much
	   of the photo survives. Cover scales the picture to whichever axis is
	   proportionally longer; once the box is taller than 1.5:1 it scales to height
	   and throws away the sides. Sized purely by `100svh - credbar`, that ratio
	   collapses as the window narrows while staying tall, which is exactly what a
	   split-screen or a half-width window is: 1.20 at 1920x1080, 0.98 at 1280x900,
	   0.85 at 1100x900 — a 1.8x zoom that crops the subject's face out of frame
	   and leaves the callouts naming hair.

	   52vw is that ratio held at ~1.15, the crop the illustration was chosen for.
	   min() means it only ever binds when the window is narrow for its height: at
	   16:9 the svh term is smaller and still wins outright, so the "hero + bar =
	   one screen" intent of 7a is untouched on a normal desktop. It is a
	   min-height, so content taller than the cap still sets the height at the
	   bottom of this range — the stage stops fighting the picture rather than the
	   other way round.

	   Do not drop back to a bare svh here, and do not raise 52vw much past ~55:
	   both re-introduce the tall-narrow box.

	   2026-09-11: `+ var(--hero-chrome-h)`. The panel no longer starts at y=0 --
	   it starts at the chrome's bottom edge (tmj-sections.css) -- so the box whose
	   aspect this term is protecting is `stage - chrome` tall, not `stage`. The
	   chrome height is added back so 52vw still describes the PANEL's ~1.15, which
	   is what the paragraph above is actually about. Without it the panel came out
	   a chrome-height shorter than the crop the illustration was chosen for. */
	body.home .s-hero {
		display: flex;
		align-items: center;
		min-height: min(calc(100vh - var(--credbar-h)), calc(52vw + var(--hero-chrome-h)));
		min-height: min(calc(100svh - var(--credbar-h)), calc(52vw + var(--hero-chrome-h)));
	}
	/* .s-hero > .s-container is held at width:90%;margin:0 auto site-wide
	   (tmj-sections.css) — as a flex item that still centres it horizontally,
	   so only the vertical axis changes here. */

	/* .hero-title's clamp (tmj-modules.css) is already pinned to its ceiling by
	   ~1170px, so the type stops responding exactly where the stage starts running
	   out of room: at 1200x760 an oversized headline overflows the fold and pushes
	   the credibility bar off screen.
	   Tie the column and the type to the viewport so the content keeps fitting
	   the stage it is centred in. Both terms track the component's own size: the
	   ceiling is the clamp's ceiling, and the vw term is the one that reaches it a
	   little later, so this only ever binds on a narrow desktop window. */
	body.home .hero-text  { max-width: min(650px, 46vw); }
	body.home .hero-title { font-size: min(3rem, 3.5vw); }

	/* .s--pb-54 used to be load-bearing — it was half of what gave the hero its
	   height. Now that the stage sets the height and the content is centred in
	   it, that padding only decides when the content stops fitting: at 1200x760
	   it pushed the hero 12px past the fold. 40px keeps the content inside the
	   stage at every desktop size we support and is invisible once centred. */
	body.home .s-hero { padding-bottom: 2.5rem; }
}

/* --- 7b. The callout layer, locked to the painted picture ---------------- */

.hero-callouts {
	position: absolute;
	inset: 0;
	pointer-events: none;
	display: none;
}

@media (min-width: 1024px) {
	.hero-callouts { display: block; }

	body.home .hero-callouts {
		/* `left: P%` + `translateX(-P%)` IS the definition of `background-position: P%`
		   -- it aligns the P% point of the picture with the P% point of the box -- so
		   this tracks --hero-focal-x (declared on .s-hero__bg in tmj-pages.css,
		   inherited here) for free. The old `inset: auto 0 auto auto` was the P=100%
		   special case written out longhand, which is why reframing the photo used to
		   strand the pills. Mechanism ported from the Utah build. */
		inset: auto auto auto var(--hero-focal-x);
		top: 0; /* matches the photo's top-pinned background-position-y */

		/* REQUIRED for the linked markers to be clickable, not cosmetic.
		   `.s-hero > .s-container` (tmj-sections.css) is `position: relative;
		   z-index: 1` and its box lies over the photo, so it won every hit test
		   aimed at a pill. Pairs with the `body.home .s-hero__bg { z-index: auto }`
		   rule below and is USELESS without it -- see the note there. Ported from
		   the Utah build (anchor-tmj), which hit and solved this first. */
		z-index: 2;
		transform: translate(calc(-1 * var(--hero-focal-x)), 0);
		width: auto;
		height: auto;
		aspect-ratio: 1536 / 1084; /* the -headroom crop's intrinsic size */
		min-width: 100%;
		min-height: 100%;          /* the two minimums together == cover */
	}
}

/* The other half of the clickable-marker fix, and the non-obvious half.
   .s-hero__bg carries `z-index: 0` (tmj-sections.css) -- and an explicit z-index on a
   positioned element CREATES A STACKING CONTEXT. That traps everything inside it: the
   `z-index: 2` above resolves against .s-hero__bg's own children, not against
   .s-container, so the layer stays pinned under the container and the pills stay dead.
   Setting z-index to auto removes the stacking context and lets the marker layer
   compete with .s-container directly.

   Paint-order neutral: a positioned element at `z-index: auto` and one at `z-index: 0`
   both paint in the same step of the painting algorithm, so the photo and its fades
   render exactly as before, and .s-container (z-index: 1) still paints above the panel.
   The only thing that changes is that a descendant may now lift itself out --
   .hero-callouts is the only descendant .s-hero__bg has. The pills stay under the fixed
   header (z-index 100000+, tmj-header.css), so the nav still covers the top marker on
   scroll.

   Scoped to the home page: every inner page shares .s-hero__bg, none has a marker layer,
   and there is no reason to restack those heroes to fix this one. Delete this and the
   `z-index: 2` above together if the markers ever stop being links. */
@media (min-width: 1024px) {
	body.home .s-hero__bg { z-index: auto; }
}

/* --- 7c. The marker ------------------------------------------------------ */

/* A pill that sits on the picture, nothing else: no leader, no separate node.
   The leader/node version placed correctly but paid for it — it needed a margin
   of empty gradient to the left of every plate to draw the line into, which is
   what forced the headline to shrink at 1280 and what would have had to be
   rebuilt from scratch for a narrow screen. A pill that simply sits where it
   points needs no margin at all, so it survives the trip down to mobile.

   .hero-callout is a zero-size anchor at the anatomical point; the pill centres
   itself on it. So --nx/--ny still mean "the structure", exactly as they did
   when they positioned the diamond, and the coordinates carry over untouched. */

.hero-callout {
	position: absolute;
	left: var(--nx);
	top: var(--ny);
	width: 0;
	height: 0;
}

/* Linked markers. The layer above is `pointer-events: none` so the pills never
   steal a drag across the photo; the ones that go somewhere opt back in. Hit
   testing follows the rendered pill, not the zero-size anchor point, because
   .hero-callout__label is its child. All four markers are links on this site:
   nerves -> /condition/chronic-pain/, jaw -> /services/facial-pain-treatment/,
   airway -> /condition/sleep-apnea/, neck -> /symptom/neck-pain/. The <span>
   form is still supported for a marker with nowhere to go (Utah's neck pill is
   that case) -- it simply never opts back into pointer-events. */
a.hero-callout {
	pointer-events: auto;
	text-decoration: none;
	color: inherit;
}

a.hero-callout .hero-callout__label {
	transition: transform 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}

a.hero-callout:hover .hero-callout__label,
a.hero-callout:focus-visible .hero-callout__label {
	/* The pill's resting transform is the centring translate -- the lift has to
	   carry it, or hovering drops the marker off its anatomical point. */
	transform: translate(-50%, calc(-50% - 2px));
	background: rgba(var(--cream-rgb), 1);
	box-shadow: 0 6px 18px rgba(21, 59, 55, 0.24);
}

a.hero-callout:focus-visible .hero-callout__label {
	outline: 2px solid var(--accent);
	outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
	a.hero-callout .hero-callout__label { transition: none; }
}


.hero-callout__label {
	position: absolute;
	left: 0;
	top: 0;
	transform: translate(-50%, -50%);
	display: flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.4rem 0.9rem;
	/* A deliberate break from the theme's hard corners — asked for, and it is
	   what separates a marker floating on an illustration from the flat plates
	   and cards that make up the rest of the page. */
	border-radius: 999px;
	background: rgba(var(--cream-rgb), 0.9);
	box-shadow: 0 4px 14px rgba(21, 59, 55, 0.16);
	font-family: 'Libre Franklin', system-ui, sans-serif;
	font-size: 0.7rem;
	font-weight: 600;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--dark);
	white-space: nowrap;
}

/* The brand diamond, demoted to the pill's dot. */
.hero-callout__label::before {
	content: "";
	width: 7px;
	height: 7px;
	flex: 0 0 auto;
	background: var(--accent);
	transform: rotate(45deg);
}

/* The radiate: one ring leaving the pill's own outline. Staggered per marker
   below — four pills breathing in unison reads as a page-load glitch, four
   breathing in turn reads as a live signal. */
.hero-callout__label::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	border: 1px solid var(--accent);
	opacity: 0;
	pointer-events: none;
	animation: heroCalloutRadiate 3.2s ease-out infinite;
	animation-delay: var(--pulse-delay, 0s);
}

@keyframes heroCalloutRadiate {
	0%   { transform: scale(1);    opacity: 0.7; }
	65%  { transform: scale(1.35); opacity: 0; }
	100% { transform: scale(1.35); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
	.hero-callout__label::after { animation: none; }
}

/* Picture-relative coordinates:
     nerves — the trigeminal fan over the temple
     jaw    — the joint itself, just in front of the ear
     airway — the teal column in the throat
     neck   — mid cervical spine
   2026-09-11: remapped onto the -headroom crop, which adds 60px of wall above
   the original 1024 (tmj-pages.css). Same points on the same anatomy --
   ny_new = (ny_old * 1024 + 60) / 1084 -- so nothing moved relative to the man;
   only the frame he is in got taller. --nx is untouched: the width did not change.
   The old note about keeping "nerves" below ~22% so the pill cleared the nav is
   spent: the panel itself now starts below the chrome, so no coordinate in this
   picture can land under it. */
.hero-callout--nerves { --nx: 70%;   --ny: 30.1%; --pulse-delay: 0s;   }
.hero-callout--jaw    { --nx: 60%;   --ny: 40.5%; --pulse-delay: 0.8s; }
.hero-callout--airway { --nx: 57.5%; --ny: 59.4%; --pulse-delay: 1.6s; }
.hero-callout--neck   { --nx: 66%;   --ny: 75.4%; --pulse-delay: 2.4s; }

/* --- 7d. Cream variant: dark type on the theme's beige -------------------- */
/* Opt in by adding `s-hero--cream` to the home hero <section>. Leave `s--dark`
   on it: everything below only overrides, so removing the one class restores
   the dark hero exactly. Nothing here touches the callout layer (7b/7c) or the
   stage (7a); the picture, its crop and the marker coordinates are unchanged.

   The panel colour is a warm beige one step lighter than the photo's own
   top-left (measured #f7eee5). The photo's visible left edge at desktop crops is
   a tan (#9a7855), so the fade reads as cream settling into the photo's own
   vignette rather than as a seam. The stop positions are the dark rule's
   (tmj-pages.css) for the reasons given there — only the colour changes. */
/* Doubled class (0,3,1) so it outranks `body.home .s-hero` (0,2,1) in tmj-pages.css
   whatever order the stylesheets print in -- both rules set --hero-side-fade on the
   same element and a tie would be decided by enqueue order alone. */
body.home .s-hero.s-hero--cream {
	--hero-cream: var(--beige);
	--hero-cream-rgb: var(--beige-rgb);
	background-color: var(--hero-cream);

	/* The one switch. Both fades in the hero's layer stack are written in terms of
	   --hero-ground-rgb (tmj-sections.css), so recolouring the ground recolours the
	   top fade and the side fade together; the stop positions, the angle and the
	   photo are the dark hero's and are not restated here. */
	--hero-ground-rgb: var(--hero-cream-rgb);
}

/* Type. The eyebrow drops from coral to the mid green: coral on beige is ~1.8:1
   and unreadable; the diamond before it stays coral, so the accent survives as
   a mark rather than as text. `.white *` colours descendants, hence the second
   selector for the <span> inside the title. */
body.home .s-hero--cream .hero-label { color: var(--mid); }
body.home .s-hero--cream .hero-title.white,
body.home .s-hero--cream .hero-title.white * { color: var(--dark); }
body.home .s-hero--cream .hero-desc { color: var(--text-muted-dark); }

/* The floating diamonds are a light green at 0.1 alpha, tuned to vanish into
   dark green; on beige they vanish entirely. Same weight, dark ink. The coral
   one (5th) keeps its colour. */
body.home .s-hero--cream .floating-diamond { background: var(--dark); opacity: 0.06; }
body.home .s-hero--cream .floating-diamond:nth-child(5) { background: var(--accent); opacity: 0.45; }

/* Buttons, inverted for a light ground. Primary: coral-on-beige has no edge, so
   it becomes the dark green plate with cream type — the mirror of the header's
   coral-on-green CTA. Its hover sweep was --accent-light (would erase cream
   type), so it sweeps the mid green instead. Secondary: light-green text and
   rule were invisible here; dark ink and a half-tone rule, coral on hover. */
body.home .s-hero--cream .btn-primary { background: var(--dark); color: var(--hero-cream); }
body.home .s-hero--cream .btn-primary::before { background: var(--mid); }
body.home .s-hero--cream .btn-secondary { color: var(--dark); }
body.home .s-hero--cream .btn-secondary::after { background: rgba(21, 59, 55, 0.45); }
body.home .s-hero--cream .btn-secondary:hover { color: var(--mid); }
body.home .s-hero--cream .btn-secondary:hover::after { background: var(--accent); }

/* The fixed nav is transparent at rest and relies on the dark hero behind it for
   its white type. Pin it to the brand green while this hero is in play so the
   header keeps its own ground over the beige; the scrolled state (now beige glass,
   tmj-header.css) is untouched. :has() is the only way a section can reach the
   header above it without a body class; browsers without it fall back to white nav
   on beige.
   The bar no longer costs the photograph anything: what made it a problem was that
   the picture ran underneath it, and the picture now starts at the bar's bottom
   edge (tmj-sections.css). Briefly made transparent on 2026-09-11 and reverted the
   same day -- the client wanted the green back. */
body.home:has(.s-hero--cream) .nav-wrapper:not(.scrolled) { background: var(--dark); }

/* ------------------------------------------------------------
   8. Two crowded gaps the spacing gate found on the home page.
   Home predates the lean pass, so it had never been run through check-spacing.
   Both are real: a section header sitting flush against the grid beneath it, and
   a tab panel's H2 six pixels off its own subtitle.
   ------------------------------------------------------------ */

/* .no-margin means "no margin below the header" — but flush against a card grid
   is 0.0px of separation, which reads as a rendering fault rather than a choice. */
.section-header.no-margin + .conditions-grid { margin-top: 2rem; }

/* tmj-pages.css sets `.s-col-text > .info-content > .ac-ofp__title { margin: 0 0 6px }`
   at (0,3,0). A flat `.ac-ofp__title + .info-subtitle` rule at (0,2,0) loses to it
   and silently does nothing — match the specificity instead of guessing. */
.s-col-text > .info-content > .ac-ofp__title { margin-bottom: 0.875rem; }
