/*
 * dbi services · Neve Child Theme
 * assets/css/post.css — single-post layer.
 *
 * Loaded on single posts only (see inc/enqueue.php); consumes the
 * .dbi-scope tokens from tokens.css (the class is put on <body> by
 * inc/post-header.php). Contains:
 *   1. The branch-category eyebrow above the title, rendered by
 *      inc/post-header.php — the same chip language as the homepage
 *      cards (front-page.css) so readers recognise it as navigation.
 *   2. The tag list Neve renders after the content — restyled from
 *      Neve's filled teal blocks into quiet hairline pills: tags are
 *      lateral discovery, subordinate to the title and the filter bar.
 *   3. Core Code blocks (wp:code) as a dark monospace box — the base
 *      look that assets/js/code-highlight.js + vendored highlight.js
 *      colourise (ADR 0014). SyntaxHighlighter blocks are untouched.
 *   4. The reads count in the byline (inc/post-views.php).
 *   5. The Neve Pro author box after the content (ADR 0019) — quiet
 *      signature section: portrait, name, bio, link to the author page.
 *
 * @package dbi-neve-child
 */

/* ════════════════════════════════════════════════
   1 · BRANCH-CATEGORY EYEBROW (above the h1)
   One <li> per branch path: the branch chip (card
   chip language), then "›" and the child pills in
   the filter bar's second-row language (dbi-blog.css
   .dbi-filter-sub a) — "DATABASE › PostgreSQL".
   ════════════════════════════════════════════════ */

body.dbi-scope .dbi-post-branches {
	margin: 0 0 14px;
	font-family: var( --f-body );
	line-height: 1.4;
}
body.dbi-scope .dbi-post-branches ul {
	display: flex;
	flex-wrap: wrap;
	gap: 6px 16px;
	margin: 0;
	padding: 0;
	list-style: none;
}
body.dbi-scope .dbi-post-branches li {
	display: inline-flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 4px;
	margin: 0;
	padding: 0;
}
body.dbi-scope .dbi-post-branches a {
	display: inline-flex;
	align-items: center;
	padding: 4px 12px;
	border-radius: 999px;
	background: var( --teal-light );
	color: var( --teal-dark );
	font-size: .7rem;
	font-weight: 700;
	letter-spacing: .07em;
	text-transform: uppercase;
	text-decoration: none;
	transition: background var( --t ) var( --ease ), color var( --t );
}
body.dbi-scope .dbi-post-branches a:hover {
	background: var( --teal-dark );
	color: #fff;
}

/* Separator: quiet glyph, same colour family as the child pills. */
body.dbi-scope .dbi-post-branch__sep {
	color: var( --faint );
	font-size: .8rem;
	line-height: 1;
	padding: 0 2px;
	user-select: none;
}

/* Child pills: lifted from the filter bar's second row so the same
   pill is lit on the archive the chip leads to. Hairline border at rest
   (the tag list's language): owner feedback 2026-09-04 — a bare muted
   word did not read as a link until hovered (plan §6). The filter bar's
   row 2 carries the same border (dbi-blog.css). */
body.dbi-scope .dbi-post-branches a.dbi-post-branch__child {
	background: transparent;
	border: 1px solid var( --border );
	color: var( --muted );
	font-size: .72rem;
	font-weight: 500;
	letter-spacing: 0;
	text-transform: none;
	padding: 3px 10px;
	transition: background var( --t ) var( --ease ), color var( --t ), border-color var( --t );
}
body.dbi-scope .dbi-post-branches a.dbi-post-branch__child:hover {
	background: var( --teal-light );
	border-color: transparent;
	color: var( --teal-dark );
}

/* ════════════════════════════════════════════════
   2 · TAG LIST (after the content, Neve markup)
   ════════════════════════════════════════════════ */

body.dbi-scope .nv-tags-list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px;
	margin: 32px 0 40px;
	padding-top: 20px;
	border-top: 1px solid var( --divider );
	font-family: var( --f-body );
}
body.dbi-scope .nv-tags-list > span {
	margin: 0 4px 0 0;
	color: var( --faint );
	font-size: .72rem;
	font-weight: 600;
	letter-spacing: .06em;
	text-transform: uppercase;
}
body.dbi-scope .nv-tags-list a {
	display: inline-flex;
	align-items: center;
	margin: 0;
	padding: 5px 14px;
	border: 1px solid var( --border );
	border-radius: 999px;
	background: transparent;
	color: var( --muted ) !important;
	font-size: .78rem !important;
	font-weight: 500;
	line-height: 1.4;
	text-transform: none;
	text-decoration: none;
	transition: background var( --t ) var( --ease ), color var( --t ), border-color var( --t );
}
body.dbi-scope .nv-tags-list a:hover {
	background: var( --teal-light );
	border-color: transparent;
	color: var( --teal-dark ) !important;
}

/* Keyboard focus mirrors hover (a11y baseline, design-principles §6) */
body.dbi-scope .dbi-post-branches a:focus-visible,
body.dbi-scope .nv-tags-list a:focus-visible {
	outline: 2px solid var( --teal );
	outline-offset: 2px;
}

/* ════════════════════════════════════════════════
   3 · CORE CODE BLOCKS (pre.wp-block-code)
   ════════════════════════════════════════════════
   Neve styles every <pre> as a light 30px-padded box in Courier; the
   old production theme showed core Code blocks as a dark box coloured
   by highlight.js (atom-one-dark). The box is drawn here in CSS so it
   is right before/without JS; token colours arrive with the .hljs
   class the script adds. Background/foreground mirror atom-one-dark
   (assets/vendor/highlight.js/atom-one-dark.min.css) on purpose — the
   two must stay in sync if the theme file is ever swapped.
   SyntaxHighlighter Evolved output (pre.brush…, no <code>) is not
   matched by these selectors. */

body.dbi-scope pre.wp-block-code {
	margin: 24px 0;
	padding: 0;
	border-radius: 6px;
	background: transparent;
	overflow: hidden;
}
body.dbi-scope pre.wp-block-code > code {
	display: block;
	padding: 1.1em 1.25em;
	border: 0;
	background: #282c34;
	color: #abb2bf;
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, 'Courier New', monospace;
	font-size: .85rem;
	line-height: 1.55;
	tab-size: 4;
	overflow-x: auto;
	white-space: break-spaces; /* wrap long CLI output, as production did */
	overflow-wrap: anywhere;
}

/* ════════════════════════════════════════════════
   3b · INLINE CODE (<code> inside a paragraph, list, table)
   ════════════════════════════════════════════════
   Neve paints inline code selection-blue (#d0effb, bordered, 5px
   radius) — authors read it as highlighted text (feedback 2026-09-14,
   enhancements #36). No Customizer option covers it. Same quiet
   language as the tag pills: neutral surface, hairline border, body
   ink, monospace a step smaller than the text. Block code (pre > code)
   is excluded and keeps §3. Mirrored in editor-style.css. */

body.dbi-scope :not(pre) > code {
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, 'Courier New', monospace;
	font-size: .875em;
	padding: .1em .4em;
	border: 1px solid var( --border );
	border-radius: 4px;
	background: var( --surface );
	color: var( --text );
	overflow-wrap: anywhere;
	-webkit-box-decoration-break: clone; /* long values that wrap keep the box on every line */
	box-decoration-break: clone;
}

/* ════════════════════════════════════════════════
   3c · YOAST TABLE OF CONTENTS BLOCK
   ════════════════════════════════════════════════
   yoast-seo/table-of-contents renders <h2> + nested <ul>. Neve gives
   every list in the content 30px vertical margins and every item 10px
   on top, so a two-level TOC falls apart into islands (feedback
   2026-09-14, enhancements #37). Compact rows, nested lists tucked
   under their parent, indentation kept, no decoration — the underline
   already says "link". Yoast has no styling option for the block. */

body.dbi-scope .wp-block-yoast-seo-table-of-contents {
	margin: 32px 0;
}
body.dbi-scope .wp-block-yoast-seo-table-of-contents h2 {
	margin: 0 0 10px;
	font-size: 1.25rem;
}
body.dbi-scope .wp-block-yoast-seo-table-of-contents ul {
	margin: 0;
	padding-left: 1.2em;
	font-size: .95rem;
	line-height: 1.5;
}
body.dbi-scope .wp-block-yoast-seo-table-of-contents ul ul {
	margin: 4px 0 2px;
}
body.dbi-scope .wp-block-yoast-seo-table-of-contents li {
	margin: 0 0 6px;
}
body.dbi-scope .wp-block-yoast-seo-table-of-contents a {
	font-weight: 500;
}

/* ════════════════════════════════════════════════
   4 · READS COUNT IN THE BYLINE (inc/post-views.php)
   ════════════════════════════════════════════════
   Rendered as a native Neve meta item after author/date, so typography
   and the "/" separator come from Neve; only the number gets tabular
   digits so it doesn't jitter against the date. */

body.dbi-scope .nv-meta-list .dbi-reads {
	font-variant-numeric: tabular-nums;
}

/* ════════════════════════════════════════════════
   5 · AUTHOR BOX (Neve Pro, after the content — ADR 0019)
   ════════════════════════════════════════════════
   Markup (neve-pro-addon blog_pro/module.php):
   .nv-author-biography > .nv-author-elements-wrapper.left >
     img.nv-author-bio-image + .nv-author-bio-text-wrapper >
       h4.nv-author-bio-name + p.nv-author-bio-desc > a.nv-author-bio-link
   Size, position, radius and alignment are Customizer values
   (seed-neve-customizer.php §9) arriving as --avatarsize etc.; this
   only sets the voice: a quiet signature section above the tag list,
   same hairline language. Portraits are not all square → cover-crop. */

body.dbi-scope .nv-author-biography {
	margin: 40px 0 0;
	padding-top: 24px;
	border-top: 1px solid var( --divider );
	font-family: var( --f-body );
}
body.dbi-scope .nv-author-elements-wrapper {
	grid-gap: 20px;
	align-items: start;
}
body.dbi-scope .nv-author-elements-wrapper img.nv-author-bio-image {
	height: var( --avatarsize );
	object-fit: cover;
	border: 1px solid var( --border );
	background: var( --surface );
}
body.dbi-scope .nv-author-bio-name {
	margin: 0 0 6px;
	font-family: var( --f-body );
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.4;
	color: var( --text );
}
body.dbi-scope .nv-author-bio-desc {
	font-size: .95rem;
	line-height: 1.7;
	color: var( --muted );
	max-width: 60ch;
	white-space: pre-line; /* Neve prints the bio's line breaks raw in one <p> */
}
body.dbi-scope .nv-author-elements-wrapper a.nv-author-bio-link {
	margin-top: 10px;
	font-size: .85rem;
	font-weight: 500;
	color: var( --teal-dark );
	text-decoration: none;
	transition: color var( --t );
}
body.dbi-scope .nv-author-elements-wrapper a.nv-author-bio-link:hover {
	color: var( --teal-dark );
	text-decoration: underline;
}
body.dbi-scope .nv-author-elements-wrapper a.nv-author-bio-link:focus-visible {
	outline: 2px solid var( --teal );
	outline-offset: 2px;
}
@media ( min-width: 960px ) {
	/* Neve Pro sets auto/auto: let the text take the remaining width. */
	body.dbi-scope .nv-author-elements-wrapper.left {
		grid-template-columns: auto 1fr;
	}
}

/* ════════════════════════════════════════════════
   5b · PUBLISHING STATS IN THE AUTHOR BOX (ADR 0029)
   ════════════════════════════════════════════════
   inc/author-stats.php sandwiches the Pro box render in
   .dbi-author-box-row: box first, then the same .dbi-author-stats
   block as the author page (base styles in dbi-blog.css). Stacked
   below the box by default; from 960px the row splits 60/40 with a
   hairline between, and the section's top hairline moves from the box
   to the row so it spans both columns. */

body.dbi-scope .dbi-author-box-row > .dbi-author-stats {
	border-top: 1px solid var( --divider );
	margin-top: 24px;
	padding-top: 20px;
	font-family: var( --f-body );
}
/* Profile icons (core Social Icons block, tinted in dbi-blog.css):
   under the box's bio, before the stats. */
body.dbi-scope .dbi-author-box-row > .dbi-author-profiles {
	margin-top: 16px;
}

@media ( min-width: 960px ) {
	body.dbi-scope .dbi-author-box-row {
		display: grid;
		/* bio 60 · stats 40, the author-page card's repartition */
		grid-template-columns: minmax( 0, 3fr ) minmax( 0, 2fr );
		column-gap: 24px;
		align-items: start;
		margin-top: 40px;
		padding-top: 24px;
		border-top: 1px solid var( --divider );
	}
	body.dbi-scope .dbi-author-box-row > .nv-author-biography {
		grid-column: 1;
		grid-row: 1;
		margin-top: 0;
		padding-top: 0;
		border-top: 0;
	}
	body.dbi-scope .dbi-author-box-row > .dbi-author-profiles {
		grid-column: 1;
		grid-row: 2;
		/* the spanning stats column stretches row 2 — stay at its top,
		   hugging the box above; indented to the box's text column
		   (avatar width from PHP, see inc/author-stats.php) */
		align-self: start;
		margin-left: var( --dbi-profiles-indent, 0px );
	}
	body.dbi-scope .dbi-author-box-row > .dbi-author-stats {
		grid-column: 2;
		grid-row: 1 / span 2;
		border-top: 0;
		margin-top: 0;
		padding-top: 0;
		border-left: 1px solid var( --divider );
		padding-left: 28px;
	}
}

/* ── WCAG AA: two colors of the vendored atom-one-dark theme ──
   Comments (#5c6370 = 2.3:1) and tag/name tokens (#e06c75 = 4.4:1) fail on
   the #282c34 code background. The vendor file stays untouched; only these
   two are lifted (enhancements #26). */
.hljs .hljs-comment,
.hljs .hljs-quote {
	color: #9aa1ad;
}
.hljs .hljs-deletion,
.hljs .hljs-name,
.hljs .hljs-section,
.hljs .hljs-selector-tag,
.hljs .hljs-subst {
	color: #e5848b;
}

/* ════════════════════════════════════════════════
   6 · VERTICAL RHYTHM OF THE CONTENT
   ════════════════════════════════════════════════
   Neve spaces every top-level element the same way (p and headings
   margin-bottom 30px, lists 30px, images 24px, core code 24px here,
   SyntaxHighlighter 16px from its own CSS), so a list, image, code
   block or table sits as far from the sentence that introduces it as
   from the next section, and a heading is no closer to its section
   than two paragraphs are (reviewer feedback 2026-11-03, enhancements
   #73). Three tokens: the base step, the tight step for an element and
   its introduction (or two attached elements in a row), the section
   step above h2/h3. Sibling margins collapse to the larger one, so
   both sides of a tight gap are set. Mirrored in editor-style.css. */

body.dbi-scope .nv-content-wrap {
	--dbi-rhythm: 30px;
	--dbi-rhythm-tight: 15px;
	--dbi-rhythm-section: 48px;
}

/* Elements that follow an introduction: lists, figures (images,
   galleries, tables, embeds), code, quotes. */
body.dbi-scope .nv-content-wrap > :is( ul, ol, figure, pre, .wp-block-image, .wp-block-gallery, .wp-block-syntaxhighlighter-code, .syntaxhighlighter, .wp-block-preformatted, .wp-block-quote, .wp-block-pullquote ) {
	margin-top: var( --dbi-rhythm );
	margin-bottom: var( --dbi-rhythm );
}
body.dbi-scope .nv-content-wrap > p:has( + :is( ul, ol, figure, pre, .wp-block-image, .wp-block-gallery, .wp-block-syntaxhighlighter-code, .syntaxhighlighter, .wp-block-preformatted, .wp-block-quote, .wp-block-pullquote ) ) {
	margin-bottom: 0;
}
body.dbi-scope .nv-content-wrap > p + :is( ul, ol, figure, pre, .wp-block-image, .wp-block-gallery, .wp-block-syntaxhighlighter-code, .syntaxhighlighter, .wp-block-preformatted, .wp-block-quote, .wp-block-pullquote ) {
	margin-top: var( --dbi-rhythm-tight );
}
/* Two attached elements in a row (image after image, code after code)
   keep the tight gap between them. */
body.dbi-scope .nv-content-wrap > :is( ul, ol, figure, pre, .wp-block-image, .wp-block-gallery, .wp-block-syntaxhighlighter-code, .syntaxhighlighter, .wp-block-preformatted ):has( + :is( ul, ol, figure, pre, .wp-block-image, .wp-block-gallery, .wp-block-syntaxhighlighter-code, .syntaxhighlighter, .wp-block-preformatted ) ) {
	margin-bottom: var( --dbi-rhythm-tight );
}
/* Inner margins that would add to the outer ones: the first list item's
   10px (Neve) no longer collapses into the list margin once Neve Pro's
   lazy rendering puts content-visibility on the list, the table inside
   its figure (Neve's figure scrolls, so the two do not collapse) and
   SyntaxHighlighter's own 1em, declared !important by the plugin. */
body.dbi-scope .nv-content-wrap > :is( ul, ol ) > li:first-child {
	margin-top: 0;
}
body.dbi-scope .nv-content-wrap > .wp-block-table table {
	margin-bottom: 0;
}
body.dbi-scope .nv-content-wrap .syntaxhighlighter {
	margin: 0 !important;
}
/* A nested list sits at the item spacing from its parent item and from
   the next item, not at the list margin. */
body.dbi-scope .nv-content-wrap li > :is( ul, ol ) {
	margin-top: 0;
	margin-bottom: 0;
}
/* Six old posts compensate the former 30px sub-list margin with an inline
   -27px on the parent items; with the margin gone they would overlap. */
body.dbi-scope .nv-content-wrap li[style*="margin-top: -27px"] {
	margin-top: 10px !important;
}
/* Sections: more air above a heading than between two paragraphs. */
body.dbi-scope .nv-content-wrap > :is( h2, h3 ):not( :first-child ) {
	margin-top: var( --dbi-rhythm-section );
}
body.dbi-scope .nv-content-wrap > :is( h4, h5, h6 ):not( :first-child ) {
	margin-top: calc( var( --dbi-rhythm ) + 6px );
}
