/*
Theme Name: Bow & Bridge
Theme URI: https://bowandbridge.com/
Author: Bow & Bridge
Author URI: https://bowandbridge.com/
Description: A reading theme for American luthiers and bow makers. Built as a child of Twenty Twenty-Five for long, heavily-cited prose: a real type scale, generous leading, a measured column, and quiet handling of maker records, tables, and print. The citation apparatus itself (notes, bibliography, honesty markers) belongs to the bb-library plugin and is left alone; this stylesheet is the page around it.
Template: twentytwentyfive
Requires at least: 6.7
Requires PHP: 7.2
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: bowandbridge
*/

/* ==========================================================================
   Colour tokens — the workshop in the white

   The reflex for a violin site is varnish: an amber ground and a red-brown
   accent. An earlier version of this file took that reflex, and it was wrong
   twice over. Amber-on-cream is the house style of instrument *marketing* —
   the glowing hero shot, the auction catalogue cover — and this site refuses
   to appraise, authenticate or sell anything. It is also, as it happens, the
   single most over-used palette in machine-made design.

   So the palette goes to the other end of the bench: the instrument before
   varnish. Spruce in the white is almost colourless. A maple bridge blank is
   pale. Bow hair is blond, silver winding tarnishes cool, chalk is chalk, and
   a drawing sheet under a north window is faintly blue. That is a light, airy,
   distinctly cool room, and it is the honest one — this is a site about
   evidence, not about finish.

   Verdigris carries the accent: oxidised silver and brass off bow mountings.
   It is cool, quiet, and cannot be mistaken for terracotta.

   But cool on its own goes clinical, and clinical is only cold in the other
   direction. So honey is a real second voice here, not a warning light — it
   carries pull-quotes and the places where the writing warms up, the sense of
   a person at a bench rather than a database. The room is north-lit, not
   sterile. What keeps the page from drifting back to cream is that the warmth
   sits in the *marks*, never in the ground.

   The four confidence values get their own scale, deliberately separate from
   the accent. Confidence is the site's core information, so it must not be
   readable as decoration or be confusable with a link.

   Three states, as required: the complete light palette lives on bare
   :root; @media(prefers-color-scheme:dark) redefines the same custom
   properties, guarded so an explicit :root[data-theme="light"] can opt
   back out; and :root[data-theme="dark"] redefines them again so a manual
   toggle wins over the OS setting in both directions. No colour below has
   its only definition inside a media query.

   The eight --wp--preset--color--* custom properties are the same ones
   theme.json generates (base/contrast/accent-1..6); redefining them here
   for dark mode means every block that consumes them through theme.json
   (body background, links, quote borders, table rules, code backgrounds)
   goes dark automatically, without a parallel set of theme-only tokens
   drifting out of sync. A handful of extra tokens this stylesheet needs
   and theme.json has no slot for (a soft divider, a raised surface, a
   softened ink for secondary text) are defined the same way, under the
   --bab- prefix (Bow And Bridge).
   ========================================================================== */

:root {
	/* Tell the browser this page is light, so the UA paints scrollbars,
	   text fields, checkboxes and the canvas behind the page in light too.
	   Without it a dark-mode reader gets a white page framed by dark
	   browser furniture, with form controls that are dark-on-dark. */
	color-scheme: light;

	/* Core palette — also declared in theme.json; restated here so this
	   stylesheet is self-contained and the light values are provably on
	   bare :root, not only inferred from another file. */
	--wp--preset--color--base: #ffffff;       /* White — page ground, owner's call */
	--wp--preset--color--contrast: #000000;   /* Black — ink */
	--wp--preset--color--accent-1: #0f7a80;   /* Verdigris — links, primary accent */
	--wp--preset--color--accent-2: #0b5f64;   /* Deep verdigris — hover, pressed */
	--wp--preset--color--accent-3: #8f5d0f;   /* Honey — the warm second voice */
	--wp--preset--color--accent-4: #595959;   /* Grey — muted / secondary text */
	--wp--preset--color--accent-5: #f2f2f2;   /* Raised surface */
	--wp--preset--color--accent-6: #cccccc;   /* Stronger borders */

	/* Extra tokens this stylesheet needs beyond the eight editor slots.
	   Kept as true neutrals: a cool-biased grey next to pure black reads
	   as a mistake rather than a choice. */
	--bab-ink-soft: #404040;     /* secondary reading text, a step off full ink */
	--bab-surface-alt: #ebebeb;  /* table header / zebra rows */
	--bab-rule: #e0e0e0;         /* hairline divider — crisp, not soft */

	/* Confidence. Deliberately its own scale: this is the site's core
	   information and must never read as decoration, nor be mistaken for a
	   link. Four values, four hues, no overlap with the accent. */
	--bab-documented: #2f6b4f;   /* read from a primary source */
	--bab-reported:   #8f5d0f;   /* single or secondary source */
	--bab-disputed:   #a83f2b;   /* sources disagree */
	--bab-corrected:  #2f5aa8;   /* the record contradicts the received account */
}

/* Single appearance, deliberately — white ground, black ink, on every
   device regardless of OS setting. The dark palette is not deleted, only
   held at the light values, so restoring it later is one edit per block
   rather than a rewrite. Both states are still declared, because a page
   that leaves these undefined does not stay light: it borrows whatever
   ground the host paints behind it, which is how a "light" theme ends up
   showing black text on black. */

@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) {
		--wp--preset--color--base: #ffffff;
		--wp--preset--color--contrast: #000000;
		--wp--preset--color--accent-1: #0f7a80;
		--wp--preset--color--accent-2: #0b5f64;
		--wp--preset--color--accent-3: #8f5d0f;
		--wp--preset--color--accent-4: #595959;
		--wp--preset--color--accent-5: #f2f2f2;
		--wp--preset--color--accent-6: #cccccc;

		--bab-ink-soft: #404040;
		--bab-surface-alt: #ebebeb;
		--bab-rule: #e0e0e0;

		--bab-documented: #2f6b4f;
		--bab-reported:   #8f5d0f;
		--bab-disputed:   #a83f2b;
		--bab-corrected:  #2f5aa8;
	}
}

:root[data-theme="dark"] {
	--wp--preset--color--base: #ffffff;
	--wp--preset--color--contrast: #000000;
	--wp--preset--color--accent-1: #0f7a80;
	--wp--preset--color--accent-2: #0b5f64;
	--wp--preset--color--accent-3: #8f5d0f;
	--wp--preset--color--accent-4: #595959;
	--wp--preset--color--accent-5: #f2f2f2;
	--wp--preset--color--accent-6: #cccccc;

	--bab-ink-soft: #404040;
	--bab-surface-alt: #ebebeb;
	--bab-rule: #e0e0e0;

	--bab-documented: #2f6b4f;
	--bab-reported:   #8f5d0f;
	--bab-disputed:   #a83f2b;
	--bab-corrected:  #2f5aa8;
}

/* ==========================================================================
   Base
   ========================================================================== */

body {
	/* theme.json already sets this via styles.color.background; restated
	   explicitly here so the page has one from a token even if that
	   generated stylesheet is ever missing. */
	background: var(--wp--preset--color--base);
}

/* Anchor jumps (a noteref to its endnote) should glide, not jump — but
   only for readers who haven't asked for less motion. */
@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

/* ==========================================================================
   Keyboard focus

   Twenty Twenty-Five gives every focusable element a plain 2px outline
   with no explicit colour, which leaves it to the browser default. Make
   it visible and on-brand instead, at a specificity that beats the
   parent's :where()-wrapped (zero-specificity) rule without a fight.
   ========================================================================== */

:focus-visible {
	outline: 3px solid var(--wp--preset--color--accent-1);
	outline-offset: 2px;
	border-radius: 1px;
}

/* ==========================================================================
   Maker records — dl.bb-record

   Rendered by the bb-library plugin's [maker_record] shortcode as a plain
   <dl>; the plugin ships no CSS for it at all. The brief here is to make
   the label read as a field name and the value read as prose, so this
   leans on two different type families: Field Sans, small, uppercase and
   tracked for dt; Reading Serif at body size for dd. A CSS grid keeps the
   two aligned without a table.
   ========================================================================== */

.bb-record {
	display: grid;
	grid-template-columns: minmax(8rem, 22%) 1fr;
	column-gap: 1.5rem;
	row-gap: 0;
	margin: 2rem 0;
}

.bb-record dt {
	grid-column: 1;
	margin: 0;
	padding: 0.85em 0;
	border-bottom: 1px solid var(--bab-rule);
	font-family: var(--wp--preset--font-family--label);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent-4);
}

.bb-record dd {
	grid-column: 2;
	margin: 0;
	padding: 0.85em 0;
	border-bottom: 1px solid var(--bab-rule);
	font-size: var(--wp--preset--font-size--medium);
	line-height: 1.6;
	color: var(--wp--preset--color--contrast);
}

@media (max-width: 36em) {
	.bb-record {
		grid-template-columns: 1fr;
	}

	.bb-record dt {
		padding-bottom: 0.2em;
		border-bottom: 0;
	}

	.bb-record dd {
		padding-top: 0;
	}
}

/* Confidence marks — .bb-conf / .bb-conf--{documented,reported,disputed,
   corrected}. The plugin defines the four values (see class-bb-makers.php,
   BB_Makers::confidences()) but ships no styling for them at all, so a
   reader currently sees plain text like "documented". Treated here as a
   small, letter-spaced provenance stamp rather than a boxed badge — the
   convention an appraisal report already uses for exactly this judgement,
   and the one deliberate flourish this theme allows itself. */

.bb-conf {
	margin-left: 0.6em;
	font-family: var(--wp--preset--font-family--label);
	font-size: 0.72em;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	white-space: nowrap;
}

.bb-conf--documented {
	color: var(--bab-documented);
}

.bb-conf--reported {
	color: var(--bab-reported);
}

.bb-conf--disputed {
	color: var(--bab-disputed);
}

.bb-conf--corrected {
	color: var(--bab-corrected);
}

/* A claim row with no source, and a record with no claims at all — both
   left unstyled by the plugin. Quiet, not alarmed: this is an honest gap,
   not the broken-reference case .bb-missing already flags in red. */

.bb-nosource {
	font-style: italic;
	font-size: 0.92em;
	color: var(--wp--preset--color--accent-4);
}

.bb-empty {
	font-style: italic;
	color: var(--wp--preset--color--accent-4);
}

/* ==========================================================================
   Tables — numbering series, price history

   The Table block's figure.wp-block-table is already its own container;
   giving it horizontal scroll keeps a wide numbering or price table from
   ever pushing the page itself sideways. Numerals get tabular figures so
   a column of serial numbers or prices lines up on the decimal/digit
   rather than drifting with proportional widths.
   ========================================================================== */

.wp-block-table {
	overflow-x: auto;
	max-width: 100%;
}

.wp-block-table table,
.entry-content table {
	width: 100%;
	border-collapse: collapse;
	font-variant-numeric: tabular-nums;
}

.wp-block-table th,
.wp-block-table td,
.entry-content table th,
.entry-content table td {
	padding: 0.65em 1em;
	text-align: left;
	vertical-align: baseline;
	border-bottom: 1px solid var(--bab-rule);
}

.wp-block-table thead th,
.entry-content table thead th {
	border-bottom: 2px solid var(--wp--preset--color--accent-6);
	font-family: var(--wp--preset--font-family--label);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent-4);
}

.wp-block-table.is-style-stripes tbody tr:nth-child(odd) td {
	background-color: var(--bab-surface-alt);
}

/* ==========================================================================
   Print

   Appraisers, librarians and peer reviewers print these pages. The plugin
   already keeps individual notes and bibliography entries from splitting
   across a page break; this extends the same discipline to the record
   grid and to plain tables, and resets the reading palette to plain ink
   on paper so the print doesn't spend toner on a golden page background.
   ========================================================================== */

@media print {
	body {
		background: #fff;
		color: #000;
	}

	a,
	a:visited {
		color: inherit;
		text-decoration: underline;
	}

	h1,
	h2,
	h3,
	h4,
	h5,
	h6 {
		break-after: avoid;
	}

	.bb-record dt,
	.bb-record dd {
		break-inside: avoid;
	}

	.wp-block-table table,
	.entry-content table {
		break-inside: auto;
	}

	.wp-block-table tr,
	.entry-content table tr {
		break-inside: avoid;
	}
}

/* ==========================================================================
   Plugin bridge

   bb-library's stylesheets consume their own --bb-* variables and fall back
   to literal colours when nothing defines them. Those fallbacks were written
   against the old varnish palette, so on the unvarnished ground they render
   as stray warm patches — a rust heading, a cream flag box — that no token
   controls and no dark-mode rule reaches.

   Mapping them here is the fix: the plugin keeps working standalone on any
   theme, and on this one it inherits the palette for free. The flag and miss
   backgrounds are mixed from their own foreground so they stay legible on
   either ground instead of being a fixed pale tint that disappears.

   ⚠ The selector is tripled deliberately, and removing a :root will break
   the page. bb-library.css does not only declare fallbacks on bare :root —
   it also redefines every --bb-* token inside its own
   @media(prefers-color-scheme:dark){ :root:not([data-theme="light"]) } and
   :root[data-theme="dark"] blocks. Those selectors score 0,2,0, so a bridge
   written at bare :root (0,1,0) LOSES to them on any device whose OS is set
   to dark — no matter which stylesheet loads last. The visible result is the
   plugin's near-white ink (#ede8e0) landing on this theme's white ground:
   record text disappears while the rest of the page looks correct, and only
   for readers in dark mode, which is why it survives a casual check.

   :root:root:root scores 0,3,0 and so wins in every state. The rule is that
   an active theme owns the palette; a plugin's own values are fallbacks for
   when no theme has an opinion, not a competing source of truth.
   ========================================================================== */

:root:root:root {
	--bb-ink:     var(--wp--preset--color--contrast);
	--bb-soft:    var(--bab-ink-soft);
	--bb-muted:   var(--wp--preset--color--accent-4);
	--bb-quiet:   var(--wp--preset--color--accent-4);
	--bb-rule:    var(--bab-rule);
	--bb-accent:  var(--wp--preset--color--accent-1);

	/* A flag is "reported"; a miss is "disputed". Same vocabulary as the
	   confidence scale, so the two never disagree on screen. */
	--bb-flag:    var(--bab-reported);
	--bb-miss:    var(--bab-disputed);
	--bb-flag-bg: color-mix(in srgb, var(--bab-reported) 9%, var(--wp--preset--color--base));
	--bb-miss-bg: color-mix(in srgb, var(--bab-disputed) 9%, var(--wp--preset--color--base));
}

/* ==========================================================================
   The measured column must be an absolute unit

   contentSize was 68ch, which looks like the right way to ask for a 68-
   character measure and is a trap. WordPress applies contentSize as a
   max-width on every direct child of an is-layout-constrained wrapper, and
   `ch` resolves against *that element's own font-size*. A paragraph at
   1.125rem and an h2 at 2.25rem therefore compute two different widths from
   the same declaration — the heading's box comes out roughly twice as wide.
   Both are centred, so the heading hangs off the paragraph column on both
   sides, and because every heading level is a different size, every level
   hangs out by a different amount. The page reads as an indented, nested
   list rather than as prose with headings over it.

   37rem is about 68 characters at the body size and, being absolute, is the
   same 37rem for every element in the flow. Headings and paragraphs now
   share one left edge, which is the entire point of a measured column.

   2026-08-13: the owner asked prose to match the width of the grids and
   tables it sits above/below (/makers-index/ etc.), not just share a left
   edge with itself. Those already render at wide-size (see "Records are not
   prose" below), so content-size is now set equal to wide-size — in
   theme.json and here — rather than picking a new narrower number. Prose,
   headings, grids and tables now all resolve to one right edge as well as
   one left edge.
   ========================================================================== */

.entry-content > *,
.wp-block-post-content > * {
	/* Belt and braces: even if a block ships its own ch-based constraint,
	   the flow keeps one edge. */
	--wp--style--global--content-size: 1100px;
}

/* ==========================================================================
   Records are not prose, and should not be measured like prose

   46rem is a reading measure — right for the essays, and too narrow for the
   things this site actually exists to show. A claims table squeezed into a
   prose column wraps every cell to two or three words, which is the failure
   the census stylesheet already documents having hit once.

   So the tabular and list-shaped components opt out and take the wide
   measure instead. They are still bounded — wideSize, not the viewport,
   because a 413-row table run edge to edge on a large display is unreadable
   in the other direction, the eye losing the row on the way back.
   ========================================================================== */

/* Matched on the layout class rather than on .entry-content, because these
   components appear in two places: inside post content on a maker page, and
   as the whole body of an archive template, where there is no .entry-content
   to hang off. WordPress puts the measure on `.is-layout-constrained > *`,
   so that is the rule to answer. */
.is-layout-constrained > .bb-census,
.is-layout-constrained > .bb-instrument-register,
.is-layout-constrained > .bb-numbering-series,
.is-layout-constrained > .bb-makerindex,
.is-layout-constrained > .bb-sourceindex,
.is-layout-constrained > .bb-codekey,
.is-layout-constrained > figure.wp-block-table,
.entry-content > .bb-census,
.wp-block-post-content > .bb-census,
.entry-content > .bb-instrument-register,
.wp-block-post-content > .bb-instrument-register,
.entry-content > .bb-numbering-series,
.wp-block-post-content > .bb-numbering-series,
.entry-content > .bb-makerindex,
.wp-block-post-content > .bb-makerindex,
.entry-content > .bb-sourceindex,
.wp-block-post-content > .bb-sourceindex,
.entry-content > .bb-codekey,
.wp-block-post-content > .bb-codekey,
.entry-content > figure.wp-block-table,
.wp-block-post-content > figure.wp-block-table {
	max-width: var(--wp--style--global--wide-size);
	/* The wide box is centred on the prose column rather than the page, so
	   the left edge of a table lines up with the left edge of the sentence
	   that introduces it. */
	margin-inline: auto;
}

/* ==========================================================================
   Prose and wide content share one left edge

   WordPress centres a constrained container's default children on the full
   available width (max-width: content-size; margin-inline: auto) and an
   alignwide child on that same width but at wide-size instead. Independent
   centring is fine when only one measure is on the page, but the moment
   both appear together — an intro paragraph above a maker or source index,
   a table under a paragraph that introduces it — the two boxes are each
   centred on their own axis and their left edges land 182px apart at
   1440px (measured on /makers-index/: prose from 352px, the wide index
   from 170px). The reading column ends up looking like an inset stripe
   floating beside a wider block, which is the complaint the owner keeps
   raising as "the body text is too narrow" — the width itself is fine, the
   misalignment is what reads as wrong.

   Two ways to fix this were on the table. Two columns (prose beside the
   index) was the owner's own suggestion, and it is a reasonable answer for
   a long intro sitting next to a comparably long table of contents. But
   /makers-index/ and /sources-index/ each carry two short paragraphs above
   a card grid or a source list — a second column would just be mostly
   empty next to a full-bleed grid, and it would fight the site's whole
   idiom of one flowing reading column per page (see the measure notes
   elsewhere in this file). A single column, left-anchored to the wide
   block, is the better answer for those two pages and for /instruments/.
   The one page where two columns might genuinely earn their keep is
   /census-1916/, whose intro runs to several paragraphs before the table —
   but changing that page's structure alone, differently from every other
   index page, would trade one inconsistency for another, and a long intro
   still reads fine as a single left-anchored column above the data. Kept
   this fix uniform across all of them rather than special-casing one page.

   So: re-anchor the constrained (default-layout) children's LEFT edge to
   match the wide block's left edge, and let the right edge float free
   (margin-right stays auto). Scoped to a constrained container that
   actually :has() an alignwide child, so a page with no wide content (a
   maker record, a source record, the front page) is untouched. max(0px, …)
   is what makes this degrade correctly on a narrow viewport: once the wide
   measure no longer exceeds the available width the calculation goes
   negative and clamps to zero, which is exactly the "both edges already
   match" state a narrow screen is in anyway — nothing here can push a box
   wider than its container, so it introduces no horizontal overflow.

   WordPress's own rule for this selector ships as
   `.is-layout-constrained > :where(...) { margin-left: auto !important;
   margin-right: auto !important; }` — `!important`, and :where() carries no
   specificity, so an override needs `!important` too, plus enough real
   specificity (:has() counts as an ordinary pseudo-class) to win outright
   rather than depend on source order.
   ========================================================================== */

.is-layout-constrained:has(> .alignwide) > :where(:not(.alignleft):not(.alignright):not(.alignfull):not(.alignwide)) {
	margin-left: max(0px, calc((100% - var(--wp--style--global--wide-size)) / 2)) !important;
	margin-right: auto !important;
}

/* On a Page (templates/page.html), the wide index/table is not a direct
   sibling of the title the way it is on the archive templates above — it is
   one level further in, inside wp:post-content, because that is where a
   Page's own body content (the intro paragraphs AND the shortcode that
   prints the index) actually lives. post-content is itself set `align:full`
   there specifically so a wide child inside it can reach wide-size rather
   than being capped at content-size by post-content's own box — the rule
   above already re-anchors post-content's OWN constrained children (the
   intro paragraphs) correctly, since the wide element genuinely is a direct
   child of post-content. The title needs a second, narrowly-scoped rule
   because it sits one level further OUT, as post-content's sibling rather
   than its child.

   Deliberately scoped to `.wp-block-post-content.alignfull .alignwide`
   specifically, not just "any .alignwide anywhere below main" — a maker or
   source record (templates/single-bb_maker.html, single-bb_source.html)
   can also carry wide content inside its post-content (an instrument
   register and a numbering series, e.g. on the Knute Reindahl record).
   Those two templates now set post-content to `align:full` as well, for
   the same reason a Page does, so this same selector reaches their titles
   too — no third rule needed. */
.is-layout-constrained:has(> .wp-block-post-content.alignfull .alignwide) > .wp-block-post-title {
	margin-left: max(0px, calc((100% - var(--wp--style--global--wide-size)) / 2)) !important;
	margin-right: auto !important;
}

/* ==========================================================================
   The gap between the header and the first heading

   The record templates inherited Twenty Twenty-Five's single-post layout,
   which sets a top margin on <main> and then a top padding on the group
   inside it. Both resolved to spacing-60, so every record opened with two
   stacked gaps before the title and the h1 floated far below the header.
   The templates now set one modest padding and no margin; this is the
   backstop for any template that still stacks them.
   ========================================================================== */

main.wp-block-group > .wp-block-group:first-child {
	margin-block-start: 0;
}

/* ==========================================================================
   Footer

   Replaces Twenty Twenty-Five's footer pattern, which shipped eight
   href="#" links across two columns headed Blog / About / FAQs / Authors
   and Events / Shop / Patterns / Themes, plus the theme's own name and a
   "Designed with WordPress" credit. On a reference site that asks to be
   trusted and cited, a footer full of links that go nowhere is not merely
   untidy — it is the first thing a careful reader clicks, and it tells
   them the site was not finished.

   Every link in the replacement was checked to return 200 before it was
   written. The machine-readable column is the deliberate part: llms.txt,
   the register exports and the sitemap are the formats this site exists to
   publish, and hiding them from human readers while serving them to
   crawlers would be a strange way to run a project about provenance.

   The list markup asks for is-style-no-bullet, which Twenty Twenty-Five
   does not register — the class is inert on its own, so the bullets are
   removed here rather than left to a block style that does not exist.
   ========================================================================== */

.wp-block-list.is-style-no-bullet {
	list-style: none;
	padding-inline-start: 0;
	margin-block: 0;
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
}

/* The column headings are labels, not headings in the reading sense. Same
   small-caps idiom the census and register already use for column heads,
   so the footer reads as part of the same object.

   Matched on .bab-site-footer rather than footer.wp-block-group: this group
   no longer sets tagName:"footer" on itself (see parts/footer.html) because
   WordPress's template-part renderer already wraps any part assigned to the
   "footer" area in its own <footer>, and the group also claiming the tag
   produced two nested <footer> landmarks on every page — an outer one from
   core holding nothing but this inner one. A stable class keeps these rules
   working without depending on the element being a footer twice over. */
.bab-site-footer h2.wp-block-heading {
	font-size: 0.72rem;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	font-weight: 600;
	color: var(--wp--preset--color--accent-4);
	margin-block: 0 0.7rem;
}

.bab-site-footer a:not(.wp-block-site-title a) {
	color: var(--wp--preset--color--contrast);
	text-decoration-color: var(--wp--preset--color--accent-6);
	text-underline-offset: 0.15em;
}

.bab-site-footer a:hover,
.bab-site-footer a:focus-visible {
	color: var(--wp--preset--color--accent-2);
	text-decoration-color: currentColor;
}

/* The closing bar carries the two promises a citable site has to make —
   that records are dated and that permalinks hold. Set quiet, but present
   on every page, because a promise made only on the About page is not one
   a reader stumbles into at the moment they decide whether to cite. */
.bab-site-footer > .wp-block-group.alignwide {
	padding-block-start: 1.1rem;
	gap: 1.5rem;
}

.bab-site-footer > .wp-block-group.alignwide p {
	margin: 0;
	max-width: 46ch;
}

/* ==========================================================================
   Caveats are the argument, not an alarm

   The plugin renders every caveat and every instrument note in the "flag"
   colour, which resolves to honey — the same hue as the `reported`
   confidence value. On a page where most rows carry a caveat, and this site
   is built so that most rows do, the result is a wall of amber body text.
   Two things go wrong at once: the page reads as though everything on it is
   a warning, and the colour stops carrying information, because a signal
   present on almost every row is not a signal.

   So the prose goes to soft ink and reads as prose. The colour moves to the
   marker in front of it — a short em dash rule — which is enough to say
   "this qualifies the row above" without shouting it. The confidence labels
   keep their own scale untouched: those are the four values a reader is
   meant to distinguish, and they should be the only coloured words in a
   record.
   ========================================================================== */

.bb-caveat,
.bb-instrument-note > td,
.bb-census__warn {
	color: var(--bab-ink-soft);
}

.bb-instrument-note > td {
	/* The dash the plugin prints before a note becomes the coloured part,
	   drawn here as a border so the text itself stays a clean measure. */
	border-inline-start: 2px solid var(--bab-reported);
	padding-inline-start: 0.75rem;
}

/* A missing source is a genuine defect and keeps its colour — it is rare,
   which is exactly what makes it worth colouring. */
.bb-nosource,
.bb-recordsources__missing .bb-recordsources__warn {
	color: var(--bab-disputed);
}


/* ==========================================================================
   Component colour and overflow

   The caveat prose is set in the plugin's "flag" colour, which is the same
   honey as the `reported` confidence value. On a site built so that most
   rows carry a caveat, that paints the page amber and the colour stops
   meaning anything — a signal present almost everywhere is not a signal.
   The prose goes to soft ink; the coloured rule down the left of the note
   keeps the association without shouting it.

   The plugin's own selector is `.bb-instrument-register .bb-caveat` — two
   classes, in a stylesheet enqueued after this one — so an override needs
   three to win. A doubled class ties and therefore loses, which is exactly
   what the first attempt did while looking correct in the file.

   The overflow guard is the lesson from getting this wrong: a table pushed
   wider than the viewport gives the whole page a horizontal scrollbar, which
   is the one layout fault a reader cannot work around. The wide box now
   comes from an alignwide group in the template — WordPress's own mechanism
   — and this only ensures a table can never exceed it.
   ========================================================================== */

.bb-instrument-register .bb-caveat.bb-caveat,
.bb-instrument-register tr.bb-instrument-note > td,
.bb-record .bb-caveat.bb-caveat {
	color: var(--bab-ink-soft);
}

.bb-instrument-register,
.bb-numbering-series,
.bb-makerindex,
.bb-sourceindex {
	max-width: 100%;
	width: 100%;
}

/* Scoped to data rows only, and the exclusion is load-bearing. A caveat is
   rendered as its own full-width row whose single cell is also a
   :first-child, so an unscoped rule sets white-space:nowrap on a paragraph
   and the table stretches to the longest sentence in it — 6104px across a
   1440px viewport, with the whole page scrolling sideways. */
.bb-instrument-register tr:not(.bb-instrument-note) > td:first-child,
.bb-instrument-register thead th:first-child {
	white-space: nowrap;
}

/* ==========================================================================
   The reading grade

   "How this was read" and the sentence after it both begin with "read", and
   run together inline they read as one broken sentence. The label is an
   eyebrow, not part of the prose, so it goes on its own line and takes the
   small-caps treatment the rest of the site uses for column heads. The
   sentence then stands on its own and says what the grade means, which is
   the part a reader actually needs.
   ========================================================================== */

.bb-readas {
	margin-block: 1.25rem;
	padding-inline-start: 0.9rem;
	border-inline-start: 2px solid var(--wp--preset--color--accent-6);
}

.bb-readas__label {
	display: block;
	font-size: 0.72rem;
	letter-spacing: 0.07em;
	text-transform: uppercase;
	font-weight: 600;
	color: var(--wp--preset--color--accent-4);
	margin-block-end: 0.2rem;
}

/* A source nobody has actually read is the one grade that should catch the
   eye, because every claim resting on it is unverified by definition. */
.bb-readas--unread,
.bb-readas--none {
	border-inline-start-color: var(--bab-disputed);
}

/* A sortable column header is a control once JavaScript has enhanced it, so
   it needs a focus state a keyboard user can see. The cursor hint is scoped
   to the enhanced state for the same reason the tabindex is: before the
   script runs, the header is not clickable and should not claim to be. */
.bb-sortable thead th[data-sortable] {
	cursor: pointer;
}

.bb-sortable thead th[data-sortable]:focus-visible {
	outline: 3px solid var(--wp--preset--color--accent-1);
	outline-offset: 2px;
}

.bb-sortable thead th[aria-sort="ascending"]::after { content: " \2191"; }
.bb-sortable thead th[aria-sort="descending"]::after { content: " \2193"; }

/* ==========================================================================
   Seven top-level items wrap at laptop width

   The header pattern (twentytwentyfive/header, inherited unmodified) sets
   the navigation to flex-wrap and leaves it at the body's own medium type
   size — a reasonable default for four or five short labels, but this site
   carries seven, two of them long ("Sources and method", "How to read a
   maker record"). Measured against the live header: at the default medium
   size (18px) with the theme's 1.5rem blockGap between items, the row needs
   about 890px clear beside the site title, and that stops fitting somewhere
   between 1100px and 1150px — a range that covers ordinary laptop windows,
   not just a narrow phone. Below 1100px "Contribute" drops to a second line
   with no visual signal that anything changed, which reads as broken rather
   than responsive.

   WordPress's own fallback exists and works — the Navigation block already
   collapses to a toggle-triggered overlay below 600px, a breakpoint fixed
   in core's own inline styles and not something a theme stylesheet can move
   without fighting `!important` inline rules on every affected page. Pushing
   that same overlay up to ~1150px was the other option on the table, and it
   was set aside: it would hide "How to read a maker record" — the one link
   a first-time reader most needs — behind a menu icon for most desktop
   widths, on a reference site whose whole idiom is a visible, browsable
   apparatus rather than a marketing nav a visitor is expected to hunt for.

   So: tighten instead of hide. Below 1220px (comfortably above where the
   row already fits at full size, so this never fires where it is not
   needed), the row drops one type step — medium to small, the same step
   used elsewhere on the site — and the gap between items tightens to match.
   That alone moves the wrap point well clear of 1000px without removing a
   single link from view. All seven items stay visible and reachable down to
   600px, where core's own overlay takes over. */
@media (max-width: 1220px) {
	.wp-block-navigation {
		--wp--style--spacing--block-gap: 0.75rem;
		font-size: var(--wp--preset--font-size--small) !important;
		gap: 0.75rem !important;
	}

	.wp-block-navigation .wp-block-navigation__container {
		gap: 0.75rem !important;
	}
}
