/* Intro Statement (§3, Figma node 10355:3590) — statement + CTA link, pixel-loop
   decorative glyph grid, and the "Brand Idea -> Brand Growth" meter. See
   intro-statement-SPEC.md for measured geometry (Figma + primary.studio
   #introduction parity check). */

.tb-intro {
	/* No outer padding/min-height — BB row owns section bg + spacing
	   (bb-owns-section-spacing convention). Guard vs BB shrink-to-fit column
	   blowup, same as tbl-slideshow (03-02 QA finding). */
	position: relative;
	display: block;
	max-width: 100vw;

	& .tb-intro__inner {
		display: flex;
		flex-flow: row nowrap;
		align-items: flex-start;
		gap: 30px;
	}

	/* Pixel Loop — decorative 2x3 grid, 20x20 cells, 20px gaps (block =
	   100x60), left col fixed 280px, top-aligned with a small optical nudge
	   to align with the statement's cap-height. The inlined SVG paths use
	   fill="currentColor" so the cell's color owns the hue — normal cells
	   inherit --Neutral-30 from the grid; the JS-driven accent hop (Ben
	   checkpoint round, fix 3) moves .is-accent to a random cell every 2s. */
	& .tb-intro__grid {
		color: #CECECE;

		flex: 0 0 280px;
		width: 280px;
		padding-top: 6px;
		display: grid;
		grid-template-columns: repeat(3, 20px);
		grid-auto-rows: 20px;
		gap: 20px;
		justify-content: flex-start;
	}

	& .tb-intro__cell {
		display: block;
		width: 20px;
		height: 20px;

		/* Accent hop (Ben checkpoint round, fix 3): one random cell carries
		   the light-purple accent, moved by JS every 2s (10th shuffle tick).
		   The paths' fill="currentColor" picks this up. */
		&.is-accent {
			color: var(--Primary-Alt-50-Base);
		}

		& svg {
			display: block;
			width: 100%;
			height: 100%;
		}
	}

	/* Single Glyph (graphic_style = glyph, §2 team/about) — one static 34×34
	   glyph replacing the animated 2×3 loop (function round 2026-07-13). The
	   left column keeps its 280px width in both modes so the right content
	   column aligns identically. currentColor = --Neutral-30 (matches the loop
	   cells' default hue). No JS: the shuffle bails without a .tb-intro__grid. */
	& .tb-intro__glyph {
		flex: 0 0 280px;
		width: 280px;
		padding-top: 10px;
		color: #CECECE;

		& svg {
			display: block;
			width: 34px;
			height: 34px;
		}
	}

	& .tb-intro__content {
		flex: 1 1 auto;
		min-width: 0;
		display: flex;
		flex-flow: column nowrap;
		align-items: flex-start;
		gap: 160px;
	}

	/* Body present (§2): the text-block→meter gap collapses 160px → 60px
	   (Figma §2). The compound .tb-intro.tb-intro--has-body selector outranks
	   the ≤767 mobile gap rule, so 60px holds at every breakpoint. Content-
	   driven (no separate knob) per function round 2026-07-13. */
	&.tb-intro--has-body .tb-intro__content {
		gap: 60px;
	}

	/* Statement — house .h2 scale (--h2-max-font-size is exactly Figma's 50px,
	   --h2-min-font-size is primary's measured 30px mobile size, so the fluid
	   clamp needs no override). Max-width is a design knob (Ben checkpoint
	   round, fix 2): the statement_max_width module setting emits
	   --tb-intro-statement-max inline on the section; 950px = SPEC default.
	   .h2's default heading margin is zeroed — column gap above owns spacing. */
	/* Text block wrapper (statement + optional body) — column, 49px gap (Figma
	   §2 heading→body 49.39; only manifests when a body exists). Full width so
	   the statement/body max-widths constrain within it. */
	& .tb-intro__text {
		width: 100%;
		min-width: 0;
		display: flex;
		flex-flow: column nowrap;
		align-items: flex-start;
		gap: 49px;
	}

	& .tb-intro__statement {
		margin: 0;
		max-width: var(--tb-intro-statement-max, 950px);
	}

	/* Body paragraph (§2 team/about, body_text field) — house Paragraph-Large:
	   20/30, --Neutral-70, normal tracking. No house .p-lg class exists, so the
	   type is set explicitly. Max-width 763px (Figma Text frame); caps only
	   while there's room (full width when stacked). */
	& .tb-intro__body {
		margin: 0;
		max-width: 763px;
		font-family: var(--body-font);
		font-size: 20px;
		line-height: 30px;
		letter-spacing: var(--Font-Paragraph-Lg-Letter-Spacing);
		color: var(--Neutral-70);
	}

	/* CTA — underlined text link at statement scale (inherits the .h2
	   font-size/line-height/letter-spacing from the parent paragraph; NOT a
	   .btn, per function-round decision 2026-07-10 — supersedes the plan's
	   .btn assumption). Figma TextLink component "Large / On White"
	   (10411:4439 default / 10411:4453 hover, Ben checkpoint round, fix 1):
	   display:block forces its own line regardless of copy length; underline
	   thickness/position from the font with ink-skip disabled; hover shifts
	   the color to the light-purple token (underline stays), on the house
	   150ms linear link transition. */
	& .tb-intro__cta {
		display: block;
        width: max-content;
        color: inherit;
        text-decoration-line: underline;
        text-decoration-style: solid;
        text-decoration-skip-ink: auto;
        text-decoration-thickness: auto;
        text-underline-offset: auto;
        text-underline-position: from-font;
        transition: var(--button-easing);

		&:hover,
		&:focus-visible {
			color: var(--Primary-Alt-50-Base);
			text-decoration: underline;
		}
	}

	/* Meter — static geometry (no fill/progress/arrow, per SPEC "Meter": the
	   plan's meter_progress knob is dropped, superseded by function round). */
	& .tb-intro__meter {
		width: 100%;
	}

	& .tb-intro__meter-wrap {
		display: flex;
		flex-flow: column nowrap;
		gap: 10px;
		width: var(--tb-intro-meter-max, 658px);
		max-width: 100%;
	}

	& .tb-intro__meter-labels {
		display: flex;
		justify-content: space-between;
		font-family: var(--body-font);
		font-size: 10px;
		line-height: 10px;
		letter-spacing: 0.1px;
		color: var(--Neutral-70);
		/* Guard against the reveal JS collapsing the wrap narrower than the
		   labels' natural width (min-width:max-content label-clip pattern,
		   03-02) — the JS zeroes this inline during the collapsed instant. */
		min-width: max-content;
	}

	& .tb-intro__meter-track {
		display: flex;
		align-items: center;
		justify-content: space-between;
	}

	& .tb-intro__meter-node {
		flex: 0 0 auto;
		display: block;
		width: 6px;
		height: 6px;
		background: var(--Neutral-70);
	}

	& .tb-intro__meter-line {
		flex: 1 1 auto;
		display: block;
		height: 1px;
		background: var(--Neutral-70);
	}
}

/* Column stack <=1024 (primary.studio 810 measurement mapped to house
   breakpoint, D-12): pixel loop above the content, gap 80 replaces the
   30px row gap; grid no longer pinned to a fixed 280px column. */
@media (max-width: 1024px) {
	.tb-intro .tb-intro__inner {
		flex-flow: column nowrap;
		gap: 80px;
	}

	.tb-intro .tb-intro__grid,
	.tb-intro .tb-intro__glyph {
		flex: 0 0 auto;
		width: auto;
		padding-top: 0;
	}

	.tb-intro .tb-intro__meter-wrap {
		width: 100%;
	}
}

/* Mobile <=767: right-col (statement -> meter) gap tightens to 60. */
@media (max-width: 767px) {
	.tb-intro .tb-intro__content {
		gap: 80px;
	}

	/* Pastel #68 — glyph-to-text gap. The 1024 column-stack rule reuses 80px
	   for BOTH the row gap it replaces and this vertical one; at 379 that
	   left the glyph stranded most of a screen above the statement. */
	.tb-intro .tb-intro__inner {
		gap: 24px;
	}
}

/* Grow-in reveal (meter wrap width, JS-driven — tbl-intro-statement.js) and
   pixel-loop shuffle are motion; both are gated behind reduced-motion and
   skipped in the BB editor by the JS itself. No CSS-only fallback is needed
   here since both render their final/static state without JS. */
@media (prefers-reduced-motion: reduce) {
	.tb-intro .tb-intro__meter-wrap {
		transition: none !important;
	}
}
