/* ============================================================================
 * BRIEFLY — SHARED SECTION HEADER COMPONENT.  Batch 0, item 3.
 *
 * ── WHY THIS EXISTS ─────────────────────────────────────────────────────────
 * Measured across the shipped suite: 436 of 474 sections open with a bare
 * centred <h2>. No eyebrow, no rule, no sub-line, no asymmetry. `text-align:
 * center` appears 313 times in the normalised layout declarations. That single
 * repeated shape is the most recognisable "this came out of a template" signal
 * in the product, and a visitor meets it fifteen times on one page.
 *
 * Atlas already solved this for itself — .at-head / .at-tab / .at-reg, with
 * at_head() assembling them. This file generalises Atlas's STRUCTURE and hands
 * every theme its own SKIN for the two ornamental parts (the eyebrow and the
 * rule) plus its own default SHAPE. Same component, thirty-six different
 * section headers.
 *
 * ── WHY IT IS NOT SCOPED TO A THEME CLASS ───────────────────────────────────
 * Briefly_Page_Themes::inject_body_classes() deliberately skips the free theme,
 * so Firstborn carries .briefly-firstborn on each SECTION ROOT instead of on
 * <body>. Anything scoped to a body class is therefore dead on the one theme
 * every free user sees — the same trap that silently no-opped the whole
 * performance layer once already, and the same reason the :has() balanced-grid
 * rule in render-guards.css cannot reach a self-scoped theme.
 *
 * This file is scoped to the COMPONENT CLASS and reads generic --bfy-* tokens.
 * Themes publish those tokens wherever their own scope lands — body class or
 * section root, it does not matter, because custom properties inherit. If no
 * theme scope lands at all, the literal fallbacks below hold and the header is
 * still correct. That is the same inversion that fixed Firstborn's palette
 * binding: read var(--x, #literal), never assign on a descendant.
 *
 * ── EVERY var() CARRIES A LITERAL FALLBACK ──────────────────────────────────
 * Two reasons, both load-bearing:
 *   1. the header stays correct when the theme scope is missing;
 *   2. a BARE var() IS INVISIBLE TO THE CONTRAST AUDITOR. A colour expressed
 *      only as var(--x) cannot be scored, so an unreadable eyebrow would pass
 *      silently. The fallback is what keeps the auditor honest.
 *
 * ── NO INLINE STYLES, AND TRACK LISTS TRAVEL AS CUSTOM PROPERTIES ───────────
 * There is not one !important in the suite, so an inline declaration can never
 * be overridden by a media query. render-guards.css §4 records what that cost:
 * Meridian's hero put a ~185px paragraph beside a ~170px photo on every page of
 * a phone build. The --split shape below therefore declares its grid HERE,
 * where a media query can reach it.
 * ========================================================================== */

/* ── 1. TOKEN CONTRACT ───────────────────────────────────────────────────────
 * A theme supplies as many of these as it wants; every one has a floor.
 * The bridge stylesheet maps each theme's own --{prefix}-* tokens onto these.
 * -------------------------------------------------------------------------- */

.bfy-head {
	/* Layout */
	max-width: var(--bfy-head-measure, 62ch);
	margin: 0 0 var(--bfy-head-mb, clamp(1.75rem, 3.5vw, 2.75rem));
	/* text-wrap:balance on the title is set below, not here, so a long lede
	   is not also balanced — balancing body copy produces ragged short lines. */
}

/* The four parts, in document order. */
.bfy-head__eyebrow { display: inline-block; margin: 0 0 var(--bfy-head-gap-1, 0.75rem); }
.bfy-head__title   { margin: 0; }
.bfy-head__lede    { margin: var(--bfy-head-gap-2, 0.85rem) 0 0; }
.bfy-head__rule    { display: block; margin-top: var(--bfy-head-gap-3, 1.25rem); }

/* Title. The size token is the theme's own h2 step; the literal fallback is
   Atlas's, which is the house standard rather than a fresh opinion. */
.bfy-head__title {
	font-family:     var(--bfy-title-font, inherit);
	font-size:       var(--bfy-title-size, clamp(1.75rem, 3.4vw, 2.7rem));
	font-weight:     var(--bfy-title-weight, 700);
	line-height:     var(--bfy-title-lh, 1.14);
	letter-spacing:  var(--bfy-title-track, -0.015em);
	color:           var(--bfy-title-ink, var(--wp--preset--color--foreground, #16181D));
	text-wrap: balance;
}

/* Lede. Its own measure, narrower than the header block, because a standfirst
   set to the same width as a heading reads as body copy that lost its column. */
.bfy-head__lede {
	font-family:    var(--bfy-lede-font, inherit);
	font-size:      var(--bfy-lede-size, clamp(1rem, 1.3vw, 1.08rem));
	line-height:    var(--bfy-lede-lh, 1.6);
	color:          var(--bfy-lede-ink, var(--wp--preset--color--foreground, #55606B));
	max-width:      var(--bfy-lede-measure, 56ch);
	text-wrap: pretty;
}

/* ── 2. EYEBROW SKINS ────────────────────────────────────────────────────────
 * Six treatments, not six colours. A theme picks one. This is where a section
 * header stops being interchangeable: the eyebrow is the first mark in the
 * section and it is read before the heading.
 *
 * All six share one type contract so swapping skins never changes the rhythm.
 * -------------------------------------------------------------------------- */

[class*="bfy-eyebrow--"] {
	font-family:    var(--bfy-eyebrow-font, inherit);
	font-size:      var(--bfy-eyebrow-size, 0.72rem);
	font-weight:    var(--bfy-eyebrow-weight, 600);
	letter-spacing: var(--bfy-eyebrow-track, 0.14em);
	text-transform: var(--bfy-eyebrow-case, uppercase);
	line-height: 1;
	color:          var(--bfy-eyebrow-ink, var(--wp--preset--color--primary, #0F4C5C));
}

/* (a) TAB — a notched index tab. Atlas's signature, generalised.
       Suits systems, catalogues, technical products. */
.bfy-eyebrow--tab {
	background: var(--bfy-eyebrow-bg, var(--wp--preset--color--background-alt, #FFFFFF));
	border: 1px solid var(--bfy-eyebrow-border, rgba(18, 24, 28, 0.14));
	border-left: 3px solid var(--bfy-eyebrow-ink, var(--wp--preset--color--primary, #0F4C5C));
	padding: 0.34rem 0.9rem 0.34rem 0.7rem;
	clip-path: polygon(0 0, calc(100% - 9px) 0, 100% 9px, 100% 100%, 0 100%);
}

/* (b) RULE-LEAD — a short brand rule running into the label. Firstborn's
       signature. Quiet, works on any canvas, never boxes the text. */
.bfy-eyebrow--rule-lead { display: inline-flex; align-items: center; gap: 0.6rem; }
.bfy-eyebrow--rule-lead::before {
	content: "";
	width: var(--bfy-eyebrow-lead, 28px);
	height: 2px;
	background: var(--bfy-eyebrow-ink, var(--wp--preset--color--primary, #0F4C5C));
	flex: 0 0 auto;
}

/* (c) STAMP — a hard-edged box. Industrial, sporting, civic. */
.bfy-eyebrow--stamp {
	background: transparent;
	border: 1.5px solid var(--bfy-eyebrow-ink, var(--wp--preset--color--primary, #0F4C5C));
	padding: 0.3rem 0.7rem;
	border-radius: var(--bfy-eyebrow-radius, 0);
}

/* (d) NUMERAL — an index figure set larger than the label beside it. Only
       meaningful where sections are genuinely a sequence; the component does
       not fabricate one, the caller passes it. */
.bfy-eyebrow--numeral { display: inline-flex; align-items: baseline; gap: 0.55rem; }
.bfy-eyebrow--numeral .bfy-head__idx {
	font-size: var(--bfy-eyebrow-idx-size, 1.5em);
	font-weight: 700;
	letter-spacing: 0;
	color: var(--bfy-eyebrow-idx-ink, var(--bfy-eyebrow-ink, var(--wp--preset--color--primary, #0F4C5C)));
}

/* (e) DOT — a small filled marker. The softest option; suits care, wellness,
       hospitality, anything that should not look engineered. */
.bfy-eyebrow--dot { display: inline-flex; align-items: center; gap: 0.55rem; }
.bfy-eyebrow--dot::before {
	content: "";
	width: 7px; height: 7px; border-radius: 50%;
	background: var(--bfy-eyebrow-ink, var(--wp--preset--color--primary, #0F4C5C));
	flex: 0 0 auto;
}

/* (f) BARE — tracked caps, no ornament. For editorial and luxury, where any
       added mark cheapens it. Deliberately the emptiest option. */
.bfy-eyebrow--bare { letter-spacing: var(--bfy-eyebrow-track, 0.2em); }

/* ── 3. RULE SKINS ───────────────────────────────────────────────────────────
 * The closing mark of the header. aria-hidden in the markup — decorative.
 * -------------------------------------------------------------------------- */

.bfy-head__rule { height: var(--bfy-rule-h, 1px); border: 0; }

/* (a) REGISTER — Atlas's measured dashes. Reads as an index or a scale. */
.bfy-rule--register {
	height: 7px;
	border-top: 1px solid var(--bfy-rule-ink, rgba(18, 24, 28, 0.14));
	background-image: repeating-linear-gradient(to right,
		var(--bfy-rule-ink, rgba(18, 24, 28, 0.14)) 0 1px, transparent 1px 22px);
	background-repeat: no-repeat;
	background-size: 100% 5px;
}

/* (b) HAIRLINE — one line across the measure. */
.bfy-rule--hairline { background: var(--bfy-rule-ink, rgba(18, 24, 28, 0.14)); }

/* (c) SHORT — a brand-coloured segment, not a full rule. */
.bfy-rule--short {
	width: var(--bfy-rule-len, 56px);
	height: var(--bfy-rule-h, 3px);
	background: var(--bfy-rule-accent, var(--wp--preset--color--primary, #0F4C5C));
	border-radius: var(--bfy-rule-radius, 2px);
}

/* (d) STITCH — a dashed run. Craft's language; also right for anything
       handmade, domestic or informal. */
.bfy-rule--stitch {
	height: 2px;
	background-image: repeating-linear-gradient(to right,
		var(--bfy-rule-ink, rgba(58, 46, 34, 0.35)) 0 7px, transparent 7px 14px);
}

/* (e) FADE — a hairline dissolving to nothing. Suits dark canvases, where a
       full-width hairline reads as a box edge. */
.bfy-rule--fade {
	background: linear-gradient(to right,
		var(--bfy-rule-ink, rgba(255, 255, 255, 0.28)),
		transparent);
}

/* (f) NONE — the header closes on the lede. */
.bfy-rule--none { display: none; }

/* ── 4. SHAPE MODIFIERS ──────────────────────────────────────────────────────
 * Where the header sits and how its parts relate. This is the layer that stops
 * every section starting in the same place on screen.
 * -------------------------------------------------------------------------- */

/* Default is LEFT at a 62ch measure — deliberately not centred. Centring is
   now an opt-in, which is the whole point: it was the unexamined default in
   313 declarations. */

/* (a) CENTER — kept, because some sections genuinely want it. */
.bfy-head--center { margin-left: auto; margin-right: auto; text-align: center; }
.bfy-head--center .bfy-head__lede { margin-left: auto; margin-right: auto; }
.bfy-head--center .bfy-rule--short { margin-left: auto; margin-right: auto; }

/* (b) SPLIT — heading left, lede right, on one baseline. The strongest
       available answer to "every section starts with a centred h2", and it
       costs no new markup: the same four parts, re-tracked.

       The track list is declared here rather than inline precisely so the
       media query below can collapse it. */
.bfy-head--split {
	display: grid;
	grid-template-columns: var(--bfy-head-cols, minmax(0, 1.15fr) minmax(0, 1fr));
	gap: var(--bfy-head-split-gap, clamp(1.5rem, 4vw, 3rem));
	align-items: end;
	max-width: var(--bfy-head-measure-wide, 1160px);
}
.bfy-head--split .bfy-head__eyebrow { grid-column: 1; grid-row: 1; }
.bfy-head--split .bfy-head__title   { grid-column: 1; grid-row: 2; }
.bfy-head--split .bfy-head__lede    { grid-column: 2; grid-row: 2; margin-top: 0; max-width: 46ch; }
.bfy-head--split .bfy-head__rule    { grid-column: 1 / -1; grid-row: 3; }

/* (c) HANG — the eyebrow hangs in the left margin beside the heading.
       Editorial. Falls back to stacked below the hang breakpoint. */
.bfy-head--hang {
	display: grid;
	grid-template-columns: var(--bfy-head-hang-cols, var(--bfy-head-hang-w, 7.5rem) minmax(0, 1fr));
	column-gap: var(--bfy-head-hang-gap, 1.5rem);
	max-width: var(--bfy-head-measure-hang, 72ch);
}
.bfy-head--hang .bfy-head__eyebrow { grid-column: 1; grid-row: 1; margin-bottom: 0; text-align: right; justify-self: end; }
.bfy-head--hang .bfy-head__title   { grid-column: 2; grid-row: 1; }
.bfy-head--hang .bfy-head__lede    { grid-column: 2; grid-row: 2; }
.bfy-head--hang .bfy-head__rule    { grid-column: 2; grid-row: 3; }

/* ── 5. RESPONSIVE ───────────────────────────────────────────────────────────
 * Both multi-track shapes collapse to one column. 760px matches the breakpoint
 * render-guards.css §4 already uses for .ewpk-grid, so a page does not reflow
 * at two different widths.
 * -------------------------------------------------------------------------- */

@media (max-width: 760px) {
	.bfy-head--split,
	.bfy-head--hang {
		display: block;
		max-width: 62ch;
	}
	.bfy-head--split .bfy-head__lede { margin-top: var(--bfy-head-gap-2, 0.85rem); max-width: none; }
	.bfy-head--hang  .bfy-head__eyebrow { text-align: left; margin-bottom: var(--bfy-head-gap-1, 0.75rem); }
}

/* ── 6. QUALITY FLOOR ────────────────────────────────────────────────────────
 * Not announced anywhere in the UI; simply always true.
 * -------------------------------------------------------------------------- */

/* A header that carries an id is an anchor destination. Keep it clear of a
   sticky header when jumped to — otherwise the heading lands under the chrome
   and the CTA looks like it did nothing. */
.bfy-head[id] { scroll-margin-top: var(--bfy-anchor-offset, 6rem); }

/* The component never animates itself. It inherits whatever reveal class the
   theme puts on its wrapper, so there is no third implementation of the reveal
   rule — the failure this project has met more than any other. This block only
   guarantees that if a theme's reveal never fires, the header is still legible. */
@media (prefers-reduced-motion: reduce) {
	.bfy-head, .bfy-head * { animation: none !important; transition: none !important; }
}

/* Forced-colours: the decorative rule and eyebrow ornaments must not vanish
   into the background, and must not be the only thing carrying meaning. */
@media (forced-colors: active) {
	.bfy-eyebrow--tab,
	.bfy-eyebrow--stamp { border-color: CanvasText; }
	.bfy-head__rule     { background: CanvasText; }
	.bfy-rule--register { border-top-color: CanvasText; }
}
