/*
Theme Name: UMBC Child Theme: Office of Professional Programs
Theme URI: https://professionalprograms.umbc.edu/
Template: twentytwentyfive
Author: Mindgrub
Author URI: https://www.mindgrub.com/
Description: Child theme of Twenty Twenty-Five for the UMBC Office of Professional Programs. All UMBC customizations live here so that the Twenty Twenty-Five parent theme can be updated through WordPress without losing site-specific work.
Requires at least: 6.7
Requires PHP: 7.2
Version: 1.14.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: umbc-opp-child
Tags: block-patterns, full-site-editing, accessibility-ready
*/

/*
 * Design tokens (colours, fonts, spacing) are defined in theme.json, NOT here.
 * Use this file only for rules that theme.json cannot express.
 *
 * Contents:
 *   1. Brand table styling
 *   2. Brand blockquote
 *   3. Accessibility helpers
 *   4. Form fields
 *   5. Archive banner component
 *   6. Course block overrides
 *   7. Site header
 *   8. Site footer
 *   9. Page body layout — OPP container geometry
 *  10. Events Calendar Shortcode (ECS) — thumbnail image cap
 *  11. Heading link color — static page bodies
 *  12. Course accordion toggle — UA <button> reset
 *  13. RFI form containers (.shortRFI / .wideRFI)
 *  14. Floated embeds in the page body — OPP alignleft/alignright width
 *  15. Body typography — what theme.json cannot express
 *  16. Legacy content utility classes — ported from Customizer "Additional CSS"
 *  17. Centered images in advgb columns — icon-grid alignment
 *  18. Non-floated video embeds — OPP intrinsic size + flush-left default
 *  19. Content utility classes from OPP _custom.scss (.at-a-glance)
 *  20. Program hub "At a Glance" cards — .program-card / .cols-delivery / text-style buttons
 *  21. Faculty read-more toggles — .faculty-read-more / .faculty-more / .faculty-show-less
 *  22. Cover block — OPP padding
 *  23. Legacy `has-N-columns` inter-column margin — Twenty Nineteen port
 *  24. Blog listing — OPP archive grid, excerpt cards, meta line, sidebar rail, pagination
 *  25. Blog single (detail) — OPP single-post layout: intro, meta, author bio, post nav, comments
 */

/* ---------------------------------------------------------------------------
 * 1. Brand table styling
 * Migrated from OPP/sass/_custom.scss. The original applied a gold border to
 * every `table, th, td` on the page, which also hit plugin and admin-adjacent
 * markup. Scoped to core table blocks here.
 * ------------------------------------------------------------------------- */
.wp-block-table table {
	border-collapse: collapse;
}

.wp-block-table th,
.wp-block-table td {
	border: 1px solid var(--wp--preset--color--accent-1);
	padding: 0.5em;
	/*
	 * The original used `word-break: break-all`, which breaks words mid-glyph
	 * and hurts readability. `break-word` only breaks when a word cannot fit.
	 */
	word-break: break-word;
}

.wp-block-table thead th,
.wp-block-table th {
	/* OPP _custom.scss:2614 paints the header cell #000 and its later rules
	 * (:2619, :5913) leave the cell BORDER gold like every other cell — the
	 * header row reads as a gold grid on black, not a dark outline. Measured
	 * live 2026-09-09 (program-costs): th bg rgb(0,0,0), border 1px #fdb515. */
	background-color: var(--wp--preset--color--black);
	color: var(--wp--preset--color--accent-1);
	border-color: var(--wp--preset--color--accent-1);
	font-weight: 700;
	text-transform: uppercase;
}

/* "Stripes" table style (every program-costs page — 20 pages). Core's stripes
 * rule `.wp-block-table.is-style-stripes td, … th { border-color: #0000 }`
 * (block-library table/style.css, (0,2,1)) out-ranks the (0,1,1) cell rules
 * above, so striped tables lost their gold grid entirely. OPP's cells kept it:
 * its `.entry .entry-content .wp-block-table td` (0,3,1) beat core. Same
 * specificity as core here, later source order wins. (2026-09-09) */
.wp-block-table.is-style-stripes th,
.wp-block-table.is-style-stripes td {
	border-color: var(--wp--preset--color--accent-1);
}

/* Core draws `thead { border-bottom: 3px solid }` in currentColor; OPP's
 * `th, thead { color: #fdb515 }` made that rule gold. Measured live: 3px gold. */
.wp-block-table thead {
	border-bottom-color: var(--wp--preset--color--accent-1);
}

/* ---------------------------------------------------------------------------
 * 2. Brand blockquote — gold rule, migrated from OPP/sass/_custom.scss
 * ------------------------------------------------------------------------- */
.wp-block-quote {
	border-left: 2px solid var(--wp--preset--color--accent-1);
	margin-left: 0;
	padding: 0 0 0 1rem;
}

/* ---------------------------------------------------------------------------
 * 3. Accessibility helpers
 * The parent theme does not ship a visible focus ring on every interactive
 * element. A gold ring on a dark offset is visible against both the light
 * page background and the dark footer.
 * ------------------------------------------------------------------------- */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
	outline: 2px solid var(--wp--preset--color--accent-1);
	outline-offset: 2px;
}

.skip-link:focus {
	position: static !important;
	width: auto !important;
	height: auto !important;
	clip-path: none !important;
}

/* ---------------------------------------------------------------------------
 * 4. Form fields
 * Migrated from OPP/sass/_custom.scss. OPP tinted the focused field border
 * UMBC Red and then added `outline: thin solid rgba(0,115,170,.15)` — a
 * near-invisible 15%-opacity ring left over from stock Twenty Nineteen. Only
 * the border colour is carried over; the focus ring in section 3 replaces
 * that outline, which did not meet WCAG 2.4.7.
 *
 * These are bare element selectors because form markup here comes from
 * plugins (FormAssembly, search) rather than core blocks, so there is no
 * reliable block class to scope to.
 *
 * Base field treatment (2026-09-08): OPP/sass/forms/_fields.scss gave every text
 * input + textarea a flat look (white fill, 1px #ccc border, no radius,
 * appearance:none, .36/.66rem padding) and OPP/custom.css made FormAssembly
 * sections full-width (`.wForm fieldset.section{width:100%}`). None of that was
 * carried, so bare FormAssembly forms with no `.shortRFI` wrapper (e.g. Student
 * Forms, reusable block 197) fell back to TT5/native narrow fields — a <select>
 * at 200px vs OPP's ~420px. Ported below. <select> is deliberately left to the
 * plugin's own styling/width (OPP did not restyle it — its empty `select {}` rule);
 * the fieldset-width rule fills it out. `#ccc` has no palette token — kept literal
 * (as §16 keeps some source hexes).
 * ------------------------------------------------------------------------- */
input[type="text"],
input[type="email"],
input[type="url"],
input[type="password"],
input[type="search"],
input[type="number"],
input[type="tel"],
input[type="date"],
textarea {
	background: var(--wp--preset--color--base);
	border: 1px solid #ccc;
	border-radius: 0;
	box-sizing: border-box;
	-webkit-appearance: none;
	appearance: none;
	padding: 0.36rem 0.66rem;
}

/* Textarea fills its container and grows vertically only (OPP _fields.scss). */
textarea {
	width: 100%;
	max-width: 100%;
	resize: vertical;
}

/* FormAssembly field containers full-width. Its responsive layout drops
 * `.oneField` to width:50% at `@media (min-width:600px)`, so bare RFI forms
 * rendered half-width fields here; OPP renders them single-column full-width. The
 * !important beats FormAssembly's `.wForm .section div.oneField` (0,3,1). Text
 * inputs + textarea then fill the container (their own `.inputWrapper` width:100%). */
.wForm .oneField {
	width: 100% !important;
}

/* <select> full-width (2026-09-08). FormAssembly pins some selects to a fixed px width
 * via `#tfa_NNN{width:200px!important}` — "I am based in…" / "Campus of Choice" on every
 * program-page RFI, the two Student-Forms selects. OPP beat that not with CSS but with
 * inline jQuery at the bottom of OPP/footer.php (l.69-80) that wrote
 * style="width:100% !important" onto every `.wFormContainer form select`, `.oneField`
 * and `input[type=text]` (the "interaction" earlier audits could not find). A class
 * selector can never out-rank an id + !important `width`, but `min-width` wins over
 * `width` in layout regardless of specificity — same result, no field ids, no script. */
.wFormContainer .wForm select {
	min-width: 100%;
}

/* Same family of fix for a field inside a FormAssembly `.section.group` (a flex row):
 * FormAssembly pins it with `#tfa_NNN-D{width:auto !important}`, so it shrinks to its
 * content and the select above only reached ~331px of the 409px OPP shows. For a flex
 * item `flex-basis` out-ranks `width` in layout, again regardless of specificity. OPP's
 * jQuery forced these `.oneField`s to 100% too, so every field stacks full-width. */
.wFormContainer .wForm .section.group > .oneField {
	flex-basis: 100%;
}

/* FormAssembly autosuggest fields ("Program of Interest" on every RFI, ~150
 * program pages) carry three Font Awesome <i> icons (search / spinner / clear)
 * positioned inside the input; OPP nudged them to the vertical middle
 * (_custom.scss:6887). The glyphs themselves come from Max Mega Menu Pro's
 * fontawesome5/6 stylesheets, which both themes enqueue. (2026-09-09) */
.wForm .fa-search.tt-search,
.wForm .fa-spinner.tt-spinner,
.wForm .fa-times-circle.tt-clear {
	top: 50%;
}

/* FormAssembly's form footer link ("Contact Information") renders underlined on
 * OPP (its global anchor rule) but plain under the child, where the vendor's
 * `.wFormFooter` styling wins over theme.json's :where()-wrapped link rule.
 * Measured live vs local 2026-09-09. */
.wFormContainer .wFormFooter .supportInfo a {
	text-decoration: underline;
}

input[type="text"]:focus,
input[type="email"]:focus,
input[type="url"]:focus,
input[type="password"]:focus,
input[type="search"]:focus,
input[type="number"]:focus,
input[type="tel"]:focus,
input[type="date"]:focus,
textarea:focus,
select:focus {
	border-color: var(--wp--preset--color--accent-7);
}

/* ---------------------------------------------------------------------------
 * 5. Archive banner component
 * Migrated from OPP/sass/components/_archive-banner.scss, plus the `.umbc-`
 * helpers it depended on (_container.scss, _wysiwyg.scss).
 *
 * In OPP this was rendered by partials/archive-banner.php whenever the ACF
 * field `is_archived` was true on a page or post. A block theme has no
 * page.php to hook that into, so the markup is now a block pattern
 * (patterns/archive-banner.php) that an editor inserts deliberately. The
 * styling below is unchanged in intent.
 *
 * Note: zero published pages currently have `is_archived` set, and the
 * banner's ACF option fields are unset, so this component is dormant today.
 * It is carried over so the capability is not silently lost.
 * ------------------------------------------------------------------------- */
.umbc-archive-banner__inner {
	background-color: var(--wp--preset--color--accent-8);
	border: 4px solid var(--wp--preset--color--accent-1);
	border-radius: 4px;
	padding: 44px 80px;
	display: flex;
	flex-direction: column;
	gap: 1rem;
	margin-top: 25px;
}

@media (max-width: 767px) {
	.umbc-archive-banner__inner {
		padding: 40px;
	}
}

.umbc-archive-banner a {
	color: var(--wp--preset--color--accent-2);
	text-decoration-color: var(--wp--preset--color--accent-2);
}

.umbc-archive-banner a:hover,
.umbc-archive-banner a:focus-visible {
	color: var(--wp--preset--color--contrast);
}

.umbc-archive-banner__title {
	margin: 0;
	padding: 0;
	font-weight: 700;
	line-height: 1;
}

.umbc-archive-banner__title span:not([class]) {
	font-size: 1.2rem;
	font-weight: 700;
}

.umbc-archive-banner__description {
	color: var(--wp--preset--color--contrast);
	font-size: 18px;
}

@media (max-width: 767px) {
	.umbc-archive-banner__description {
		font-size: 16px;
	}
}

.umbc-archive-banner__link {
	display: flex;
	align-items: center;
	gap: 8px;
}

/* ---------------------------------------------------------------------------
 * 6. Course block overrides
 * Migrated from OPP/sass/components/_course-list.scss.
 *
 * The `acf/display-course-list` and `acf/display-course-table` blocks are
 * registered by the mg-umbc-course-retriever PLUGIN and ship their own
 * complete stylesheets, so they are unaffected by the theme switch. OPP only
 * added these small resets. Note (2026-09-04): they do NOT guard against
 * theme.json — `elements.button` compiles only to `.wp-element-button,
 * .wp-block-button__link` and never reaches a bare <button>. What they
 * neutralise is the browser's default `buttonface` fill and padding on the
 * plugin's bare <button> toggles. The matching UA *border* reset is §12.
 *
 * Used on 59 published pages, so these must not be dropped.
 * ------------------------------------------------------------------------- */
.course-accordion__toggle {
	padding: 0;
}

.course-accordion__description {
	margin: 0;
}

.course-accordion__toggle,
.course-table__select-toggle {
	background: none;
	color: var(--wp--preset--color--contrast);
}

.course-accordion__toggle:hover,
.course-accordion__toggle:focus,
.course-table__select-toggle:hover,
.course-table__select-toggle:focus {
	background: none;
}

/* The plugin's teal pill links ("Sample Syllabus", GIS / Data-Science pathway
 * pages): OPP _custom.scss:6178-6185 keeps the inline SVG outline-only and
 * stops a visited link turning red (theme link colour). (2026-09-09) */
.course-accordion__link svg {
	fill: transparent;
}

.course-accordion__link:visited {
	color: var(--wp--preset--color--base);
}

/* ---------------------------------------------------------------------------
 * 7. Site header
 * Ported from OPP/sass/_custom.scss (~6285–6835: #masthead, .site-branding-inner,
 * .logo-container, .programbar, #officetitle, #programtitle, #JLDnavbar,
 * #megabox, #mega-menu-wrap-Ribbon) for the three-band header pattern in
 * patterns/header-umbc.php. Band backgrounds (black / charcoal / gold) and the
 * 11px gold rule are set on the blocks themselves; everything here is what
 * block attributes cannot express.
 *
 * OPP sized the bands with `margin: 0 10%; padding: 0 60px`. The pattern first
 * used the theme's constrained layout (wideSize 1100px) instead; §7.x below
 * (2026-09-08) restores OPP's `calc(10% + 60px)` left inset for the header's
 * left column (logo / office title / nav) so it aligns with the page body (§9).
 * ------------------------------------------------------------------------- */
.umbc-header a {
	text-decoration: none;
}

/* The bands sit flush in OPP; without this the parent's default blockGap
 * (1.2rem) shows the black outer group between them. */
.umbc-header > .wp-block-group {
	margin-block-start: 0;
}

/* Band 1 — logo + Ribbon menu. Flex comes from the block layout; OPP aligned
 * the two to the bottom edge. */
.umbc-header__branding-inner {
	align-items: flex-end;
}

/* OPP: .logo-container max-width 355px with 45px side padding → 265px image. */
.umbc-header__logo {
	max-width: 265px;
}

.umbc-header__logo img {
	display: block;
	width: 100%;
	height: auto;
}

/* The Ribbon theme's own custom_css adds `clear: both`; keep it on one line
 * with the logo at desktop width. */
#mega-menu-wrap-Ribbon {
	margin: 0;
	clear: none;
}

/* Match OPP: the branding row is Marge's centered 1100px column, but OPP pins the
 * Programs/Contact/Apply block flush to the masthead's right edge. Anchor it to
 * band 1 (full-width) instead of the column's right edge, so it hugs the right at
 * every width like OPP. Desktop only — below 1030px the header stacks (see the
 * max-width:1030px rule below) and the block flows normally. (As of 2026-09-08
 * the logo + office title + nav also left-align to the body edge — see §7.x.)
 *
 * The selector is scoped under `.umbc-header__branding` to out-specify Max Mega
 * Menu's inline reset (`#mega-menu-wrap-Ribbon { position: relative; top/right:
 * auto }`), which is a single-ID rule that loads after this stylesheet. */
@media (min-width: 1031px) {
	.umbc-header__branding {
		position: relative;
	}

	.umbc-header__branding #mega-menu-wrap-Ribbon {
		position: absolute;
		top: 49px;   /* match OPP ribbon top (=49) → bottom 89 in the 119px band */
		right: 19px; /* match OPP: 19px from the right edge, at every width */
	}

	/* With the block flush-right, the Programs mega-flyout must open leftward
	 * (right-aligned) so it stays on screen instead of overflowing the right
	 * edge. OPP does exactly this (OPP/sass/_custom.scss ~6378); the child never
	 * ported it, so its flyout was left-aligned. MMM's own flyout selectors are
	 * more specific, hence !important (matching OPP). */
	#mega-menu-wrap-Ribbon .mega-sub-menu {
		left: unset !important;
		right: 0 !important;
	}
}

/* Band 2 — program bar with the UMBC flag pattern. The SVG is the one OPP
 * inlined in site-branding.php, with its currentColor fill baked in. */
.umbc-header__programbar {
	position: relative;
	overflow: hidden;
	background-image: url(assets/images/flag-pattern.svg);
	background-size: cover;
	background-repeat: no-repeat;
}

#officetitle {
	position: relative;
	z-index: 20;
	margin: 0;
	padding: 0.5em 0;
	font-size: 20px;
	font-weight: 400;
	line-height: 1.75em;
	color: var(--wp--preset--color--base);
}

#officetitle a {
	color: var(--wp--preset--color--base);
}

#officetitle a:hover,
#officetitle a:focus-visible {
	text-decoration: underline;
}

#officetitle + #programtitle {
	position: relative;
	z-index: 20;
	margin: -0.25em 0 0;
	padding: 0 0 16px;
	font-size: 40px;
	font-weight: 700;
	line-height: 52px;
}

#programtitle a {
	color: var(--wp--preset--color--accent-1);
}

#programtitle a:hover,
#programtitle a:focus-visible {
	text-decoration: underline;
}

/* Band 3 — gold nav bar holding the per-program Max Mega Menu. */
#JLDnavbar {
	position: relative;
	z-index: 20;
	min-height: 40px;
}

#megabox {
	background-color: var(--wp--preset--color--accent-1);
}

@media (max-width: 1030px) {
	.umbc-header__branding-inner {
		flex-direction: column;
		align-items: flex-start;
	}
}

@media (max-width: 990px) {
	#JLDnavbar {
		text-align: center;
	}

	#megabox {
		display: block;
		width: 100%;
	}
}

@media (max-width: 770px) {
	.umbc-header__logo {
		max-width: 255px;
	}

	#officetitle + #programtitle {
		font-size: 32px;
		line-height: 1.2;
	}
}

/* 7.x  Header left column aligned to the body edge (2026-09-08)
 * Revises the "centered 1100px column" notes above: the logo, office-title band
 * and the gold nav now share the body's left inset (calc(10% + 60px), §9) so
 * they align with the page title at every width — matching live OPP. (Before
 * this, the centered wideSize:1100 column drifted from the body's proportional
 * inset as the window widened — on wide monitors the nav sat ~160px right of the
 * title.) Each band's global padding is zeroed so the 10% is measured against
 * the full viewport (exactly as §9 does for the body); each alignwide inner
 * drops its centered wideSize cap and left-insets instead of centering.
 * Desktop only — at ≤1030px the header stacks and keeps the parent's flow
 * (see the max-width:1030px / :990px rules above). The flush-right Ribbon is
 * unaffected: it is positioned right:19px against band 1's full-width padding
 * box, which zeroing the padding does not move. */
@media (min-width: 1031px) {
	.umbc-header__branding,
	.umbc-header__programbar,
	#JLDnavbar {
		padding-left: 0 !important;
		padding-right: 0 !important;
	}

	.umbc-header__branding-inner,
	.umbc-header__programbar-inner {
		max-width: none !important;
		margin-left: calc(10% + 60px) !important;
		margin-right: 0 !important;
	}

	/* +50 (not +60): the home link's own 10px left padding then lands the home
	 * GLYPH on the body text edge (10% + 60px), matching OPP. */
	.umbc-header__navbar-inner {
		max-width: none !important;
		margin-left: calc(10% + 50px) !important;
		margin-right: 0 !important;
	}
}

/* ---------------------------------------------------------------------------
 * 8. Site footer
 * Ported from OPP/sass/_custom.scss (6655–6716 #colophon / .site-info /
 * #copyright / #mega-menu-Social, 6580 #footerlogo, 6859 + 6881 responsive
 * margins) for patterns/footer-umbc.php. Band backgrounds (black / gold) are
 * set on the blocks themselves; everything here is what block attributes
 * cannot express.
 *
 * Deviations from OPP, on purpose:
 *  - `.site-info` was #767676 on black (2.9:1). Uses the base colour instead.
 *  - Site-name hover in the gold strip stays dark; theme.json's gold hover for
 *    core/site-title would vanish against the gold band.
 *  - OPP's `!important`s on the Social mega menu are kept only where the
 *    plugin's inline theme CSS would otherwise win.
 *
 * Horizontal geometry: the band's alignwide inners originally kept the theme's
 * centered wideSize (1100px) column — a documented deviation from OPP's
 * `calc(10% + 60px)` inset. Reversed 2026-09-08 in §8.x below (Jeff's call), so
 * the footer, body (§9) and header (§7.x) now share one left edge.
 * ------------------------------------------------------------------------- */
.umbc-footer a,
.umbc-footer a:visited {
	color: var(--wp--preset--color--base);
	/* OPP's #colophon a is .85em of a ~22px base (~18.7px); at this theme's 19px
	 * base .85em rendered ~16px, too small. 1em (~19px) matches OPP. */
	font-size: 1em;
	text-decoration: none;
}

.umbc-footer a:hover,
.umbc-footer a:focus-visible {
	text-decoration: underline;
}

.umbc-footer h2 {
	margin: 0 0 0.5em;
	color: var(--wp--preset--color--accent-1);
	font-size: 1em;
	/* OPP's footer headings are 700; without this they inherit theme.json's
	 * global heading weight (900). */
	font-weight: 700;
	text-transform: uppercase;
}

.umbc-footer h2 + h2,
.umbc-footer address + h2 {
	margin-top: 1.5em;
}

.umbc-footer address {
	margin: 0;
	font-size: 1em;
	font-style: normal;
	line-height: 1.1em;
}

.umbc-footer ul,
.umbc-footer li {
	margin: 0;
	padding: 0;
	list-style: none;
}

/* OPP stacked the More Information links at line-height only (~25px pitch) with no
 * inter-item gap; keep that tight rhythm. */
.umbc-footer .wp-block-list li {
	margin-bottom: 0;
	line-height: 1.3;
}

/* Logo widget (was block-15). */
#footerlogo {
	display: block;
	max-width: 210px;
	height: auto;
	margin-top: 1em;
}

/* Social mega menu (was the maxmegamenu-4 widget on the Social location). */
#mega-menu-wrap-Social,
#mega-menu-wrap-Social #mega-menu-Social {
	background: var(--wp--preset--color--black) !important;
}

#mega-menu-wrap-Social #mega-menu-Social > li.mega-menu-item > a.mega-menu-link {
	font-size: 30px !important;
	color: var(--wp--preset--color--accent-1) !important;
	background: var(--wp--preset--color--black) !important;
}

/* The Shortcode block wraps its output in <p> (wpautop); drop the margins so the
 * mega menu and the privacy link sit flush like the widgets did. */
.umbc-footer .umbc-footer__widget p {
	margin: 0;
}

/* Privacy link row (was .site-info under the widget area).
 * No top margin: the privacy link is empty on this site (the Privacy Policy
 * page is a draft), so any margin here is pure dead space between the widget
 * columns and the gold copyright strip. OPP's empty .site-info collapsed to
 * nothing the same way, so the black band's bottom gap is just #colophon's
 * padding-bottom (spacing-40 ≈ OPP's 1.5rem). If the privacy page is ever
 * published, restore a top margin (e.g. spacing-40) to separate the link. */
.umbc-footer__site-info {
	margin-top: 0;
}

.umbc-footer__site-info p {
	margin: 0;
}

/* Gold copyright strip (was #copyright, outside <footer> in OPP). */
.umbc-footer__copyright .wp-block-site-title {
	margin: 0;
	/* OPP's copyright site-name is ~13.8px, regular weight; theme.json makes
	 * core/site-title 700, so both size and weight are overridden here. */
	font-size: 0.72em;
	font-weight: 400;
}

.umbc-footer__copyright .wp-block-site-title a,
.umbc-footer__copyright .wp-block-site-title a:hover,
.umbc-footer__copyright .wp-block-site-title a:focus-visible {
	color: var(--wp--preset--color--contrast);
}

.umbc-footer__copyright .wp-block-site-title a:hover,
.umbc-footer__copyright .wp-block-site-title a:focus-visible {
	text-decoration: underline;
}

/* 8.x  Footer aligned to the body edge (2026-09-08)
 * Revises the "centered 1100px column" deviation above: the black band's two
 * alignwide inners (the widget Columns + the privacy row) now use OPP's
 * symmetric `calc(10% + 60px)` inset (_custom.scss:6859, ≥768px) — the same
 * inset as the body (§9) and the header (§7.x) — so the footer's left edge sits
 * on the page title at every width, matching live OPP (204 @1440, 252 @1920,
 * 188 @1280). Before this, the centered wideSize:1100 column drifted the same
 * way the header did: 34px left of the body at 1440, 158px right of it at 1920.
 * The band's global padding is zeroed so the 10% is measured against the full
 * viewport (exactly as §7.x and §9 do). #copyright is untouched: OPP's gold
 * strip is full-width with centered text. Below 768px the band keeps the
 * parent's root padding (OPP used 1rem gutters there — close enough).
 * !important mirrors §7.x: core's constrained rule centres with
 * `margin-left/right: auto !important`, and the per-container
 * `.wp-container-core-*` wideSize cap must not win on source order. */
@media (min-width: 768px) {
	.umbc-footer.has-global-padding {
		padding-left: 0;
		padding-right: 0;
	}

	.umbc-footer > .alignwide {
		max-width: none !important;
		margin-left: calc(10% + 60px) !important;
		margin-right: calc(10% + 60px) !important;
	}
}

/* ---------------------------------------------------------------------------
 * 9. Page body layout — OPP container geometry
 * Migrated from OPP/sass/site/primary/_posts-and-pages.scss:178-188 and
 * OPP/sass/blocks/_blocks.scss (via the postContentMaxWidth() mixin), whose
 * tokens live in OPP/sass/variables-site/_structure.scss:
 *   $size__site-margins:        calc(10% + 60px)          (per-side inset ≥768)
 *   $size__site-tablet-content: calc(8*(100vw/12) - 28px) = calc(66.6667vw - 28px)
 *
 * Why this exists: OPP shipped ~27 custom page-*.php templates that gave each
 * page its body container. The block theme dropped them, so every static page
 * (~318 of them, incl. the front page id 10) falls back to the TT5 parent's
 * generic templates/page.html. There the DB block content (Advanced Gutenberg
 * advgb/columns + advgb/accordions, authored for OPP's container) renders under
 * the block theme's constrained model — every top-level block capped at
 * contentSize (720px) and CENTERED. OPP instead used no fixed container: an
 * .entry-content inset of 80% / margin 10% / padding 60px, with each top-level
 * block capped at the viewport-relative calc(66.6667vw - 28px) and LEFT-aligned
 * (a Twenty Nineteen trait — note the intentional right-side whitespace). The
 * result was a body ~932px wide, left-hugging, at a 1440px viewport vs the
 * block default's 720px centered. This section restores OPP's geometry.
 *
 * Scope: `.page` is on the <body> of every static page including the home page
 * (body.home.page); posts/archives/search use other templates and are excluded.
 *
 * INTENT: the BODY here matches OPP's left-aligned, viewport-relative column
 * (Jeff's call 2026-09-03). As of 2026-09-08 §7.x aligns the HEADER's left column
 * (logo / office title / nav) to this same `calc(10% + 60px)` edge, so the header
 * and body now share one left line at every width (Jeff's call 2026-09-08, revising
 * the earlier "keep the header's centered 1100px column" decision). §8.x does the
 * same for the FOOTER's black band (also 2026-09-08), so header, body and footer
 * all sit on this one `calc(10% + 60px)` edge.
 *
 * !important is used only where the core layout rules it fights also use it:
 * the constrained centering rule
 *   .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull))
 *     { max-width: <content-size>; margin-left: auto !important; margin-right: auto !important }
 * and the root-padding-aware full-bleed rule
 *   .has-global-padding > .alignfull { margin-left/right: calc(root-padding * -1) }.
 * ------------------------------------------------------------------------- */
/* Title → content gap (2026-09-09). OPP: the entry-content box starts 22px below
 * the title (Twenty Nineteen entry-header margin) and every top-level block
 * carries a 32px top margin — so the first block sits 54px below the title on
 * every page, or 22px when that block is a float (floats have margin-top 0 in
 * OPP; the first paragraph beside it still starts at +54). TT5 gave the child
 * 19px (the inner group's 1.2rem block gap, and the constrained layout zeroes
 * the first child's margin). Measured on all 18 representative pages: OPP 54/22
 * at 1440 AND 375 (the float keeps its 0 margin when stacked on phones), child
 * 19 — so this applies at every width. */
.page main > .wp-block-group > .wp-block-post-content.is-layout-constrained {
	margin-block-start: 22px !important;
}

.page .wp-block-post-content.is-layout-constrained > :first-child:not(.alignleft):not(.alignright) {
	margin-block-start: 32px;
}

/* Content → footer gap (2026-09-09). OPP's last top-level block carries a 32px
 * bottom margin and #colophon starts right under the article, so the site footer
 * sits 32px below the last block at every width. page.html instead gives the inner
 * group `padding-bottom: spacing|60` (~70px @1440) and the footer template part
 * picks up the body flow's 1.2rem block gap — 89px measured @1440 (OPP 32). All
 * widths: OPP's `.entry-content > *` margin is 32px on phones too. !important only
 * against the block's inline padding-bottom style. */
.page main > .wp-block-group.has-global-padding {
	padding-bottom: 32px !important;
}

.page main + footer.wp-block-template-part {
	margin-block-start: 0;
}

/* Featured image: TT5's page.html renders `wp:post-featured-image` ABOVE the
 * post title (featured image → title → content). OPP never showed a page's
 * featured image at all — OPP/functions.php:120 filters
 * `twentynineteen_can_show_post_thumbnail` to false — so any page with a
 * thumbnail set (e.g. /community-leadership/, whose H1 sat 536px lower than
 * OPP's behind a 932×466 image) gained a hero OPP does not have. Hidden here to
 * match OPP; the durable fix is a child `templates/page.html` without the block
 * (readme follow-up #3), which would also stop the image request. (2026-09-09) */
.page main > .wp-block-group > .wp-block-post-featured-image {
	display: none;
}

/* A display:none figure is still a preceding SIBLING, so TT5's constrained-layout
 * gap (`> * + * { margin-block-start: 1.2rem }`) still lands on the title that
 * follows it — measured 20px lower than OPP on /community-leadership/ (358 vs 338).
 * Zero it only in that pairing; pages without a thumbnail are unaffected. */
.page main > .wp-block-group > .wp-block-post-featured-image + .wp-block-post-title {
	margin-block-start: 0;
}

@media (min-width: 768px) {
	/* Measure the inset against the full viewport: cancel the inner wrapper's
	 * root padding (page.html: main > div.wp-block-group.alignfull.has-global-padding). */
	.page main > .wp-block-group.has-global-padding {
		padding-left: 0;
		padding-right: 0;
	}

	/* Header → page-title vertical gap. page.html stacks a 70px `main` margin-top
	 * on the inner group's 70px padding-top (= 140px of dead space above the page
	 * title); OPP's nav→title gap is ~66px. Zero the margin and set the inner
	 * padding-top to 66px so the title sits where OPP's does. (2026-09-08) */
	.page main.wp-block-group {
		margin-top: 0 !important;
	}

	.page main > .wp-block-group.has-global-padding {
		padding-top: 66px !important;
	}

	/* OPP .entry-content inset. post-content is alignfull + has-global-padding in
	 * page.html, so override both its full-bleed negative margins and its root
	 * padding with OPP's 80% / 10% / 60px. */
	.page .wp-block-post-content.is-layout-constrained {
		max-width: 80% !important;
		margin-left: 10% !important;
		margin-right: 10% !important;
		padding-left: 60px !important;
		padding-right: 60px !important;
	}

	/* Each top-level body block: OPP's viewport-relative cap, left-aligned
	 * (override the constrained rule's centering). */
	.page .wp-block-post-content.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
		max-width: calc(66.6667vw - 28px);
		margin-left: 0 !important;
		margin-right: 0 !important;
	}

	/* Blocks OPP let span the full container (1032px @1440) instead of the cap: the
	 * gold separator (Additional CSS l.30-36 `max-width:100%`) and the `.at-a-glance`
	 * callout (_custom.scss:6910 `max-width:100% !important`; styled in §19). (0,4,0)
	 * beats the cap's (0,3,0). (2026-09-08) */
	.page .wp-block-post-content.is-layout-constrained > .wp-block-separator,
	.page .wp-block-post-content.is-layout-constrained > .at-a-glance {
		max-width: 100%;
	}

	/* The page title + featured image are rendered by page.html as siblings ABOVE
	 * post-content, so they are not covered above. Align their left edge with the
	 * body (10% margin + 60px padding) and give them the same cap. */
	.page main > .wp-block-group > .wp-block-post-title,
	.page main > .wp-block-group > .wp-block-post-featured-image {
		max-width: calc(66.6667vw - 28px);
		margin-left: calc(10% + 60px) !important;
		margin-right: 0 !important;
	}
}

/* < 768px: OPP used max-width calc(100% - 44px) with 22px side gutters and
 * full-width blocks. (Note: this heavy homepage has a PRE-EXISTING horizontal
 * overflow at ≤~420px that predates this section and is unrelated to it —
 * tracked separately; these rules do not cause or fix it.) */
@media (max-width: 767.98px) {
	.page .wp-block-post-content.is-layout-constrained {
		max-width: calc(100% - 44px) !important;
		margin-left: 22px !important;
		margin-right: 22px !important;
		padding-left: 0 !important;
		padding-right: 0 !important;
	}

	.page .wp-block-post-content.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
		max-width: 100%;
	}

	/* Phone widths were inset 52px, not 22px (2026-09-08 find, program-hub audit): the
	 * inner group's root padding (TT5 `--wp--style--root--padding-*`, 30px at 375) was
	 * only zeroed in the ≥768px block above, so it stacked on the 22px margin and the
	 * body rendered 271px wide at 375 where OPP renders 331px — narrow enough to break
	 * the At-a-Glance Delivery row. Zero it here too, and give the title (a sibling
	 * above post-content, same as at ≥768px) the same 22px inset so it stops falling
	 * to the viewport edge; OPP's title sits at 22px on phones. */
	.page main > .wp-block-group.has-global-padding {
		padding-left: 0;
		padding-right: 0;
	}

	.page main > .wp-block-group > .wp-block-post-title,
	.page main > .wp-block-group > .wp-block-post-featured-image {
		max-width: calc(100% - 44px);
		margin-left: 22px !important;
		margin-right: 22px !important;
	}
}

/* ---------------------------------------------------------------------------
 * 10. Events Calendar Shortcode (ECS) — thumbnail image cap
 * The homepage "Featured Events" area runs an ECS event list. Its featured
 * thumbnail ships a MALFORMED class ("attachment-max-width: 100% size-max-width:
 * 100% wp-post-image" — a style string passed where an image SIZE name belonged),
 * so its intended max-width:100% never applies. OPP capped it via the global
 * Underscores rule OPP/custom.css: img{height:auto;max-width:100%}. TT5 has no
 * blanket cap for raw <img>, so the 1200px image overflowed its ~456px column by
 * ~744px. Scope: .ecs-events (event-list output only). Fix in the child; do not
 * touch OPP, the plugin, or the DB content.
 * ------------------------------------------------------------------------- */
.ecs-events img {
	max-width: 100%;
	height: auto; /* keep the 1200×627 aspect when width is capped */
}

/* Event titles. ECS prints each event as `h2.entry-title.summary`; OPP sized it via
 * Customizer Additional CSS l.307 `h2.entry-title{font-size:1.5em}` (29px) — a rule §16
 * skipped as Twenty-Nineteen-only markup, but the ECS list still emits it. Without it
 * the child's H2 scale (36px) applies and titles run to three lines. Scoped to the ECS
 * output; blog titles are `.wp-block-post-title`. (2026-09-08) */
.ecs-events h2.entry-title {
	font-size: 1.5em;
}

/* ---------------------------------------------------------------------------
 * 11. Heading link color — static page bodies
 * Block themes color every link; theme.json sets the global link color to
 * accent-7 (#DA2128, UMBC Red). Links that sit INSIDE a heading (e.g. the ECS
 * event title <h2 class="entry-title"><a>) then render red against the dark
 * heading. OPP kept heading links dark via .entry .entry-title a{color:inherit}.
 * This restores that as a general block-header rule: a link inside any body
 * heading inherits the heading's (dark) color. Scoped to `.page` — static pages
 * incl. the home page (body.home.page); blog/archive post-title links keep the
 * theme's link color (they use non-.page templates). :where() keeps specificity
 * at (0,1,1) but `.page` still beats theme.json's :where()-wrapped link color.
 * Site header (#officetitle/#programtitle, §7) and footer (§8) set their own
 * link colors at higher specificity, so they are unaffected.
 * ------------------------------------------------------------------------- */
.page :where(h1, h2, h3, h4, h5, h6) a,
.page :where(h1, h2, h3, h4, h5, h6) a:visited {
	color: inherit;
}

.page :where(h1, h2, h3, h4, h5, h6) a:hover,
.page :where(h1, h2, h3, h4, h5, h6) a:focus-visible {
	color: var(--wp--preset--color--accent-4); /* Grey #636466 — OPP used #4a4a4a */
}

/* ---------------------------------------------------------------------------
 * 12. Course accordion toggle — UA <button> reset
 * The course-list block's toggle (plugin course-list.php) is a bare <button>.
 * OPP reset every bare button globally — OPP/sass/forms/_buttons.scss:1-20,
 * incl. `border: none` on line 9 — and that reset was never ported, so under
 * TT5 the toggle renders as the browser's default grey `2px outset` box (the
 * gold top edge is the plugin's own .course-accordion__item border-top). TT5
 * has no bare-button rule: theme.json's `elements.button` compiles only to
 * `.wp-element-button, .wp-block-button__link` (class-wp-theme-json.php:664).
 * §6 already removes the UA fill and padding; this adds the border reset and
 * restores OPP's Roboto 700 ~17px for the +/- glyph (bare buttons do not
 * inherit font). Scoped to the accordion toggle only —
 * .course-table__select-toggle (grouped in §6) keeps its plugin border.
 * OPP's `outline: none` is deliberately NOT ported (TT5's focus ring, §3).
 * ------------------------------------------------------------------------- */
.course-accordion__toggle {
	appearance: none;
	border: 0;
	border-radius: 0;
	font: inherit;
	font-size: var(--wp--preset--font-size--small); /* 17px ≈ OPP .88889em (17.2px) */
	font-weight: 700;
	text-align: left;
}

/* OPP/sass/typography/_headings.scss:47 — accordion titles are 700, never 900. */
.course-accordion__title {
	font-weight: 700;
}

/* Mouse focus: TT5's parent paints a 2px solid currentColor ring on ANY focused
 * element (`:where(.wp-site-blocks *:focus)`, twentytwentyfive/style.css:34), so
 * every clicked course row stayed boxed until focus moved. OPP showed Twenty
 * Nineteen's `thin dotted` inset ring (`_custom.scss:2669-2673`). Reproduce it
 * for pointer focus only; keyboard focus (:focus-visible) keeps §3's gold ring.
 * (2026-09-11) */
.course-accordion__toggle:focus:not(:focus-visible) {
	outline: 1px dotted;
	outline-offset: -4px;
}

/* ---------------------------------------------------------------------------
 * 13. RFI form containers (.shortRFI / .wideRFI)
 * The lead-capture forms are FormAssembly embeds authored in page content as
 * <div class="shortRFI"><p style="…">We're here to help!…</p>[formassembly
 * formid=…]</div> (23 published rows use .shortRFI, 1 uses .wideRFI). OPP drew
 * the gold box in OPP/sass/_custom.scss:6569-6571; the inner gutter, the
 * short-form field suppression and the captcha trimming lived in the
 * Customizer "Additional CSS" (custom_css post 5147, lines 1-20), which
 * wp_get_custom_css() keys to the ACTIVE stylesheet — so none of it reaches a
 * different theme. Ported here so it is version-controlled with the theme.
 * The source's !importants are dropped: nothing else on the page targets these
 * selectors (re-add only if FormAssembly's own theme-39.css is seen winning).
 * ------------------------------------------------------------------------- */
.shortRFI,
.wideRFI {
	border: 1px solid var(--wp--preset--color--accent-1);
}

/* Intro "We're here to help!" gold bar — OPP/sass/_custom.scss:6901 (`.shortRFI p`).
 * Some RFI blocks (reusable block 202, used site-wide) author the intro as a plain
 * <p> and relied on this rule; others (block 197) carry the gold as an inline style
 * and are unaffected. Scoped to the DIRECT child <p> (tighter than OPP's `.shortRFI
 * p`) so it can never hit a FormAssembly <p> nested in `.wFormContainer`. accent-1
 * (#FDB515) stands in for OPP's near-identical #fcb515. */
.shortRFI > p {
	margin-top: 0;
	padding: 10px 22px;
	background: var(--wp--preset--color--accent-1);
}

.shortRFI .wFormContainer {
	padding: 0 10px;
}

/* Fields hidden to make the "short" RFI short (FormAssembly field ids). */
.shortRFI #tfa_611,
.shortRFI #tfa_627,
.shortRFI #tfa_505-D,
.shortRFI #tfa_668-D,
.shortRFI #tfa_673-D {
	display: none;
}

/* Captcha: drop the fieldset chrome and help text, scale the widget to fit. */
fieldset.captcha {
	border: 0;
	margin: 0;
}

fieldset.captcha legend,
div.captchaHelp {
	display: none;
}

.g-recaptcha {
	transform: scale(0.85);
	transform-origin: 0 0;
	height: 50px;
}

/* FormAssembly's "Add another response" repeat control — hidden in OPP
 * (_custom.scss:6897). (2026-09-08) */
.wForm .duplicateSpan {
	display: none;
}

/* ---------------------------------------------------------------------------
 * 14. Floated embeds in the page body — OPP alignleft/alignright width
 * Program pages open with a right-floated YouTube core/embed and wrap the
 * intro paragraphs around it (42 published rows have a floated embed). Core
 * caps `.wp-block-embed.alignleft/.alignright` at 360px (block-library
 * embed/style.css, (0,2,0)). OPP instead capped every floated top-level block
 * at the viewport-relative calc(5*(100vw/12)), and calc(4*(100vw/12)) from
 * 768px, with margin-top 0 and a 1rem/2rem (22/44px) gutter
 * (OPP/sass/blocks/_blocks.scss:64-79 via _custom.scss:5156-5173) — ~480px at
 * 1440 vs the child's 360px. The TEXT column already matches OPP (§9 excludes
 * floats from its cap); only the float shrank, which is why the text looked
 * wider. (0,4,0) here beats core's (0,2,0) and the root layout float rule — no
 * !important. The child's responsive 16:9 embed box (wp-embed-responsive) is
 * kept; only the width changes. Below 768px OPP stacked floated figures and
 * images (Customizer Additional CSS l.115-124: `float: none; max-width: 80%`).
 * ------------------------------------------------------------------------- */
.page .wp-block-post-content.is-layout-constrained > .alignleft,
.page .wp-block-post-content.is-layout-constrained > .alignright {
	max-width: calc(5 * (100vw / 12));
	margin-block-start: 0;
}

.page .wp-block-post-content.is-layout-constrained > .alignright {
	margin-inline-start: 22px; /* OPP 1rem @22px root */
}

.page .wp-block-post-content.is-layout-constrained > .alignleft {
	margin-inline-end: 22px;
}

@media (min-width: 768px) {
	.page .wp-block-post-content.is-layout-constrained > .alignleft,
	.page .wp-block-post-content.is-layout-constrained > .alignright {
		max-width: calc(4 * (100vw / 12));
	}

	.page .wp-block-post-content.is-layout-constrained > .alignright {
		margin-inline-start: 44px; /* OPP 2rem @22px root */
	}

	.page .wp-block-post-content.is-layout-constrained > .alignleft {
		margin-inline-end: 44px;
	}
}

@media (max-width: 767.98px) {
	.page .wp-block-post-content.is-layout-constrained > figure.alignleft,
	.page .wp-block-post-content.is-layout-constrained > figure.alignright,
	.page .wp-block-post-content.is-layout-constrained > img.alignleft,
	.page .wp-block-post-content.is-layout-constrained > img.alignright {
		float: none;
		max-width: 80%;
	}
}

/* ---------------------------------------------------------------------------
 * 15. Body typography — what theme.json cannot express
 * The 32px block rhythm, heading sizes/weights and the nested-heading margins
 * are theme.json (core/post-content blockGap, elements.heading/h2/h3/h4/h6 —
 * see readme.md "Heading scale & rhythm"). Two OPP rules have no theme.json
 * equivalent:
 *  - headings clear floats (OPP/sass/_custom.scss:2511-2518 `h1..h6 { clear:
 *    both }`), so a heading after the floated intro video starts below it
 *    instead of wrapping beside it;
 *  - list indent: OPP ul/ol padding-left 22px ($size__spacing-unit) vs the UA
 *    default 40px. `li` is left alone — the child's 28.5px line + TT5's 0.5rem
 *    item margin already lands within a few px of OPP's 1.8 line-height pitch.
 * :where() keeps these at (0,2,0) so they never outrank the layout gap rule.
 * ⚠️ Heading MARGINS must stay out of this file: anything ≥ (0,1,0) loaded
 * after global styles would defeat the 32px top-level gap. They live in
 * theme.json (elements.heading.spacing.margin), where the layout rule still
 * wins for direct children and only nested headings get the 22px.
 * ------------------------------------------------------------------------- */
.page .wp-block-post-content :where(h1, h2, h3, h4, h5, h6) {
	clear: both;
}

.page .wp-block-post-content :where(ul, ol) {
	padding-left: 22px;
}

/* List items: OPP gives every `li` line-height 1.8 (Twenty Nineteen
 * elements/_lists.scss + _custom.scss:2553) and no item margin; TT5 renders them
 * at the body's 1.5 and adds `margin-top: .5rem` per item (theme.json core/list
 * css). Single-line items came out within 2px of OPP, which is why the 2026-09-04
 * pass left this alone — but every WRAPPED item loses ~6px per extra line, so
 * multi-line lists ran 15–20% shorter (how-to-apply list 244 → 195px, hub "Why"
 * lists 383 → 330 / 488 → 452 @1440, measured live vs local 2026-09-09). Port the
 * 1.8 and drop the item margin so the pitch is OPP's at any line count. (0,2,0)
 * beats theme.json's `:root :where(.wp-block-list) li` (0,1,1); §8's footer list
 * rule (0,3,1) and §20's card lists are more specific and unaffected in intent.
 * Scoped to `.page` like the rest of §15. */
.page .wp-block-post-content :where(li) {
	line-height: 1.8;
	margin-block-start: 0;
}

/* Image captions — OPP/sass/blocks/_blocks.scss:621-630: centered, .71111em (≈13.8px on
 * OPP's 19.36px body), line-height 1.6. TT5 left-aligns captions at the `small` preset
 * (17px), which reads wrong under a centered image. Fixed 14px rather than the em: the
 * child's body type is fluid and drops to ~14.4px at phone widths, where .71111em would
 * give a 10px caption. OPP's system heading font stack is not carried — the child is
 * Roboto throughout. (2026-09-08) */
.page .wp-block-post-content .wp-block-image figcaption {
	text-align: center;
	font-size: 14px;
	line-height: 1.6;
}

/* ---------------------------------------------------------------------------
 * 16. Legacy content utility classes — ported from Customizer "Additional CSS"
 * OPP carried 389 lines of Customizer Additional CSS (custom_css post 5147,
 * post_name "opp"; theme_mods_OPP.custom_css_post_id). WordPress keys that CSS
 * to the active stylesheet (wp_get_custom_css()), so switching themes silently
 * drops all of it — including the styling for class names editors typed into
 * page content over the years. Ported here (2026-09-04) so it is
 * version-controlled with the theme. Only classes with at least one use in
 * published content are carried (counts in the notes folder:
 * Projects/ACES/UMBC/Child-Theme-Program-Page-Styling-Audit.md); brand hexes are
 * swapped for palette tokens where they match exactly. Otherwise verbatim,
 * including the source's !importants (they fight Advanced Gutenberg inline
 * styles and the plugin's own accordion CSS).
 *
 * Deliberately NOT ported (Twenty Nineteen markup, or zero uses in content):
 *   .entry .entry-title a, .entry-meta *, .entry-footer.cat-links,
 *   .navigation.post-navigation, h2.entry-title, .widget *, .archive-wa *,
 *   p{hyphens:none} (TT5 does not hyphenate), a stray `media="…"` line,
 *   .yellow-bg, .black-link, .goldshowtext*, .red-box, .event-box,
 *   .datepicker-switch, ul.prgm-list.
 * Already handled elsewhere: .shortRFI/captcha (§13), mobile floats (§14),
 * outline buttons (theme.json core/button.variations.outline),
 * .wp-block-separator (theme.json core/separator).
 * ------------------------------------------------------------------------- */

/* Homepage hero line (1 use). */
.opp-hero-line-1 {
	text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}

/* Legacy course accordion markup authored in content (40 uses) — predates the
 * plugin's .course-accordion__* block. */
.course-title,
.course-title-open {
	padding-top: 8px !important;
	padding-bottom: 8px !important;
	/* margin-top: 0 !important — deliberately NOT ported (2026-09-11). In Twenty
	 * Nineteen every top-level block carried `margin: 32px 0`, so zeroing the
	 * title's own top margin still left the previous block's 32px as the gap. TT5
	 * puts the whole gap on the following sibling's margin-block-start
	 * (post-content 32px; .is-layout-flow 1.2rem inside columns), so the same
	 * line stacked every course title flush on the paragraph above it (0 vs OPP
	 * 32 / 19 nested, 13 pages). Leaving the layout rule in charge reproduces
	 * OPP at every width. */
	margin-bottom: -1px !important;
	font-weight: normal;
}

/* Consecutive titles (e.g. the four bare course titles on
 * /learning-and-performance-technology/master-of-arts-in-instructional-systems-development/)
 * overlap by the 1px negative bottom margin in OPP; the layout gap would space
 * them 31px apart. (0,2,0) beats the layout rule's (0,1,0). */
.course-title + .course-title,
.course-title + .course-title-open,
.course-title-open + .course-title,
.course-title-open + .course-title-open {
	margin-top: 0;
}

.course-title-open {
	border-bottom: none;
}

.course-description li {
	margin-left: 15px;
}

h3.course-title {
	font-weight: normal;
}

/* Background / link colour utilities. */
.gray-bg {
	background: var(--wp--preset--color--accent-5);
}

.teal-bg {
	background: var(--wp--preset--color--accent-2);
	color: var(--wp--preset--color--base);
}

.teal-link a {
	color: var(--wp--preset--color--accent-2);
}

.course-long-list {
	background: var(--wp--preset--color--accent-5);
	padding-left: 20px;
	padding-right: 20px;
}

/* Data Science pathway blocks (69 uses). */
.pathway {
	background: var(--wp--preset--color--accent-5) !important;
	margin-top: 1px !important;
	margin-bottom: 0 !important;
	padding: 18px 5px 10px 12px;
}

/* Grid cards (8 uses). */
.grid-card {
	padding: 11px 28.6px 18.7px; /* OPP .5rem 1.3rem .85rem @22px root */
	margin-bottom: 28px !important; /* OPP 1.25rem @22px root (27.5, rounded as S20) */
	box-shadow: 4px 4px 7px rgba(0, 0, 0, 0.14);
	border-radius: 5px;
	border: 1px solid var(--wp--preset--color--black);
	background-color: var(--wp--preset--color--base);
}

.program-card-list li,
.grid-card-list li {
	list-style-type: disc;
}

.grid-card a {
	color: var(--wp--preset--color--accent-2);
}

.is-layout-grid.gray-bg {
	padding: 15px;
}

/* Teal rule headings — finance page (12 uses). */
h2.teal-bar,
h3.teal-bar {
	border-top: 1px solid var(--wp--preset--color--accent-2);
	border-bottom: 1px solid var(--wp--preset--color--accent-2);
	line-height: 1.5em;
}

.margin-top-ten {
	margin-top: 10px !important;
}

/* Scrolling program list (5 uses). */
.program-scrolling-list li {
	font-size: 20px;
	border-top: 1px solid var(--wp--preset--color--black);
	list-style-type: none;
	margin: 0 0 0 -20px;
	padding-top: 10px;
}

.program-scrolling-list a {
	color: var(--wp--preset--color--black);
}

.program-scrolling-list a[href*="enrole"]::after,
.program-scrolling-list a[href*="catalog"]::after {
	content: " " url("https://api.iconify.design/dashicons/share-alt2.svg");
}

@media only screen and (max-width: 767px) {
	.program-scrolling-list {
		overflow-y: scroll;
		height: 300px;
	}
}

.program-scrolling-list::-webkit-scrollbar {
	width: 15px;
}

.program-scrolling-list::-webkit-scrollbar-track {
	background: var(--wp--preset--color--base);
}

.program-scrolling-list::-webkit-scrollbar-thumb {
	background: #c7c8ca;
}

.program-scrolling-list::-webkit-scrollbar-thumb:hover {
	background: var(--wp--preset--color--accent-4);
}

/* Yoast how-to block (1 use). */
li.schema-how-to-step {
	margin-left: 35px;
	margin-right: 45px;
}

.schema-how-to-step p {
	margin-top: 0;
}

.schema-how-to {
	border: 2px solid #fcb515; /* source hex (one digit off UMBC Gold), kept as authored */
}

/* One specific Advanced Gutenberg button instance (2 uses). */
.advgbbtn-d558f8c9-3ee4-4b5d-80e9-e3a92c137f4e {
	font-size: 18px;
	color: var(--wp--preset--color--accent-2) !important;
	background-color: var(--wp--preset--color--accent-5) !important;
	padding: 16px 22px;
	border-width: 2px !important;
	border-color: var(--wp--preset--color--accent-2) !important;
	border-style: none;
	border-radius: 0 !important;
}

/* The Events Calendar — teal links/buttons, hidden venue. (Events templating
 * under the block theme is a known separate gap; these rules are harmless
 * until then.) */
#tribe-events-content a:not(.btn) {
	text-decoration: underline;
	color: var(--wp--preset--color--accent-2);
}

.tribe-events .tribe-events-c-search__button {
	background-color: var(--wp--preset--color--accent-2);
}

.tribe-events .tribe-events-calendar-list__event-title-link,
.tribe-events .tribe-events-calendar-list__event-title-link:visited,
.tribe-events-widget .tribe-events-widget-events-list__view-more-link:visited {
	color: var(--wp--preset--color--accent-2);
}

.tribe-common .tribe-common-c-btn-border,
.tribe-common a.tribe-common-c-btn-border {
	color: var(--wp--preset--color--accent-2);
	border: 1px solid var(--wp--preset--color--accent-2);
}

.tribe-events .tribe-events-calendar-list__event-venue {
	display: none;
}

.tribe-common a,
.tribe-common a:active,
.tribe-common a:focus,
.tribe-common a:hover,
.tribe-common a:visited {
	color: var(--wp--preset--color--accent-2);
}

#tribe-events-footer ~ a.tribe-events-ical.tribe-events-button {
	color: var(--wp--preset--color--accent-1);
}

.tribe-events-sub-nav li a {
	background: none;
}

section.tribe-common-l-container.tribe-events-l-container {
	padding-bottom: 0 !important;
	padding-top: 0 !important;
}

/* Student Success icon area (1 use). */
.success-icon-area a {
	color: var(--wp--preset--color--accent-2);
}

/* Professional Pulse tiles (6 uses). ⚠️ .pulse-button a::after relies on Font
 * Awesome 6, which OPP loaded from a header kit that was intentionally not
 * migrated (readme.md "not migrated" #11) — the arrow glyph will not render
 * until FA is re-added (plugin) or the rule is dropped. Kept for parity. */
.pulse1 {
	background-color: rgba(0, 113, 118, 0.3);
	padding: 10px;
	border-bottom: 10px solid var(--wp--preset--color--black);
}

.pulse2 {
	background-color: rgba(253, 181, 21, 0.3);
	padding: 10px;
	border-bottom: 10px solid var(--wp--preset--color--black);
}

.pulse3 {
	background-color: rgba(199, 200, 202, 0.3);
	padding: 10px;
	border-bottom: 10px solid var(--wp--preset--color--black);
}

.pulse-button a::after {
	font-family: "Font Awesome 6 Free";
	font-weight: 900;
	-webkit-font-smoothing: antialiased;
	content: " \f0a9";
	text-decoration: none;
}

.pulse-button a,
.pulse-button p {
	color: var(--wp--preset--color--black);
}

.pulse-button a:hover,
.pulse-button a:active {
	text-decoration: underline;
}

/* ---------------------------------------------------------------------------
 * 17. Centered images in advgb columns — icon-grid alignment
 * Icon grids (e.g. the Student Success "Professional Graduate Program Student
 * Resources" block, .success-icon-area) place a center-aligned wp:image in each
 * Advanced Gutenberg column: <figure class="wp-block-image aligncenter size-full">.
 * OPP wrapped every image in a full-width <div class="wp-block-image"> and centred
 * the inner .aligncenter <figure> (classic-theme core CSS), so each 100px icon sat
 * centred in its ~170px cell. The block theme puts .aligncenter directly on the
 * shrink-wrapped <figure> (display:table, width:100px); inside a non-layout
 * .advgb-column-inner the constrained-layout centering never applies and no core
 * fallback margin does either, so the figure kept margin-left:0 and the icons
 * hugged the LEFT of each cell — visibly off-centre against their centred labels
 * (measured @1440: child icon left 214 = cell edge; OPP 249 = cell centre). Restore
 * OPP's centering with auto side margins (display:table honours them). Scoped to
 * advgb columns in page bodies; standalone aligncenter images keep the theme's own
 * layout centering and are untouched.
 * ------------------------------------------------------------------------- */
.page .wp-block-post-content .advgb-column-inner .wp-block-image.aligncenter {
	margin-left: auto;
	margin-right: auto;
}

/* ---------------------------------------------------------------------------
 * 18. Non-floated video embeds — OPP intrinsic size
 * The Student Success page embeds two YouTube videos as core wp:embed blocks
 * (figure.wp-block-embed.wp-embed-aspect-16-9.wp-has-aspect-ratio, NOT floated),
 * nested in the ~681px left column. OPP never enabled `responsive-embeds`
 * (OPP/functions.php adds only post-thumbnails), so its block iframe kept its
 * intrinsic 500×281 centred in the column (small screens clamp via
 * embed,iframe{max-width:100%}). TT5 enables responsive-embeds → the body gets
 * .wp-embed-responsive → core stretches the aspect iframe to width:100% of its
 * container, so the child rendered 681×383 — far larger than OPP (measured @1440).
 * Cap the embed figure at OPP's 500px and centre it (matching OPP's 500px iframe
 * at column centre), while KEEPING the responsive 16:9 wrapper so phones scale to
 * the column instead of distorting the way OPP's fixed-height iframe does (<500px).
 * Scoped to page-body, non-floated aspect embeds; floated embeds keep §14's width.
 *
 * Alignment (revised 2026-09-08): OPP's embeds sit at intrinsic 500px in normal
 * flow — i.e. FLUSH-LEFT in a plain column (Career Opps videos in core wp:columns:
 * OPP iframe left=252, not centered). The video is only CENTERED where OPP's
 * container centers it: Student Success's advgb `.gray-bg` column applies
 * text-align:center to `.advgb-column-inner`, centering the inline iframe (child &
 * OPP both left=472.8 there). So cap + left-align by default, and restore centering
 * only in the advgb-centered contexts (.gray-bg / .success-icon-area). The first
 * cut's blanket `margin:auto` over-centered every multi-column embed (a ~53px left
 * indent at wide viewports, appearing once a column exceeds 500px). See
 * Projects/ACES/UMBC/Child-Theme-Resources-Pages-Audit.md.
 * ------------------------------------------------------------------------- */
.page .wp-block-post-content .wp-block-embed.wp-has-aspect-ratio:not(.alignleft):not(.alignright):not(.alignfull) {
	max-width: 500px;
	margin-left: 0;
	margin-right: 0;
}

/* Center only where OPP centered it: advgb columns with centered content. The extra
 * class raises specificity above the default rule so it wins. */
.page .wp-block-post-content .gray-bg .wp-block-embed.wp-has-aspect-ratio:not(.alignleft):not(.alignright):not(.alignfull),
.page .wp-block-post-content .success-icon-area .wp-block-embed.wp-has-aspect-ratio:not(.alignleft):not(.alignright):not(.alignfull) {
	margin-left: auto;
	margin-right: auto;
}

/* ---------------------------------------------------------------------------
 * 19. Content utility classes from OPP _custom.scss
 * §16 ported the content classes that lived in the Customizer "Additional CSS"
 * (post 5147). Some content utility classes instead live in OPP's theme SCSS
 * (OPP/sass/_custom.scss), so switching themes dropped them too. Ported here so
 * they are version-controlled with the theme; brand hexes swapped for palette
 * tokens where they match exactly.
 *
 * .at-a-glance — "at a glance" callout box (OPP/sass/_custom.scss:6909), used on
 * 105 published pages (e.g. Partnerships: the Fellowship / FAES / Training-Centers /
 * Cohorts callouts). A light-grey padded box with teal 500-weight links. OPP's
 * #F5F5F5 == accent-5 exactly. OPP's `max-width:100% !important` is what let the box span
 * the full 1032px container past the §9 top-level cap; the plain `max-width` below lost
 * to §9's (0,3,0), so §9 carries an explicit full-width exemption for `.at-a-glance` (and
 * the separator) since 2026-09-08. The
 * >.wp-block-column:last-child padding-top only applies when .at-a-glance is on a
 * columns block (OPP @min-width:782px); inert on the <p> usages.
 * ------------------------------------------------------------------------- */
.at-a-glance {
	max-width: 100%;
	padding: 1em 1.85em 0.5em;
	gap: 0.25em;
	background: var(--wp--preset--color--accent-5);
}

.at-a-glance a {
	color: var(--wp--preset--color--accent-2);
	font-weight: 500;
}

.at-a-glance h2 {
	margin-top: 0.35em;
}

@media (min-width: 782px) {
	.at-a-glance > .wp-block-column:last-child {
		/* OPP: 2.96rem @22px root = 65.12px, which equalled its left column's h2 line box
		 * (43.2px) + Twenty Nineteen's 22px heading margin-bottom, so both columns' first
		 * cards sat level. TT5 puts the heading's gap on the NEXT sibling's
		 * margin-block-start (--wp--style--block-gap, 19.2px) instead, so a fixed 65px left
		 * the right column 2px low at 1440 and 5px at 1024 (measured 2026-09-14). Track the
		 * left column instead: the h2 line box (font-size × 1.2) + the sibling gap. The
		 * clamp() is the fluid size WP derives from theme.json `elements.h2` 36px — copy it
		 * again from `#global-styles-inline-css` (`h2{font-size:…}`) if the h2 size or the
		 * fluid settings ever change. 43.2px @≥1600, 41.6 @1024, 36.4 @782. */
		padding-top: calc(1.2 * clamp(22.041px, 1.378rem + ((1vw - 3.2px) * 1.79), 36px) + var(--wp--style--block-gap, 1.2rem));
	}
}

/* ---------------------------------------------------------------------------
 * 20. Program hub "At a Glance" cards — .program-card / .cols-delivery / text-style buttons
 * Every program hub page (/data-science, /cybersecurity, …) opens with an "At a
 * Glance" columns block (§19) whose cells are `wp:group` blocks classed
 * `program-card`, authored once per program as reusable blocks (34 wp_block rows →
 * 119 published pages, incl. contact-us and schedule pages). OPP styled them in
 * OPP/sass/_custom.scss:6925-6969 (card, bullet-less lists, arrow sub-lists, the
 * "Delivery" icon row) and _custom.scss:5345-5382 (the "Text" button style, which
 * the mg-umbc mu-plugin registers for the editor). None of it reached the child, so
 * the cards rendered as bare text with bullets, the Delivery icons shrank inside a
 * 50/50 column split and the "Download Program Guide" links came out as gold fill
 * buttons. rem → px at OPP's 22px root (sass/variables-site/_fonts.scss:70); the
 * child's root is 16px. Icons copied from OPP/images/ to assets/images/. (2026-09-08)
 * ------------------------------------------------------------------------- */

/* The class is a bare `.program-card` in OPP (_custom.scss:6925), so it boxes
 * WHATEVER carries it. Beyond the 34 reusable Group cards, three EIL "Virtual
 * Class Visit" pages put it on a Columns block AND on the h3 / p / figure inside
 * — and live OPP renders each of those as its own card (measured 2026-09-09:
 * padding 11px 28.6px 18.7px, margin-bottom 27.5px, shadow, 5px radius, white;
 * the Columns keeps its inline #f5f5f5). Generic rule first at (0,2,0) — equal to
 * the Group rule below, which therefore still wins its folded-margin padding —
 * and above WP's `:where(.wp-block-columns.has-background)` padding and the
 * `.has-global-padding :where()` reset. */
.wp-block-post-content .program-card {
	padding: 11px 28.6px 18.7px; /* OPP .5rem 1.3rem .85rem @22px root */
	margin-bottom: 27.5px !important; /* OPP 1.25rem */
	box-shadow: 4px 4px 7px rgba(0, 0, 0, 0.14);
	border-radius: 5px;
	background-color: var(--wp--preset--color--base);
}

/* The card. `.wp-block-group.program-card` (0,2,0) so it out-ranks WP's
 * `.has-global-padding :where(…)` padding reset (0,1,0); the margin-bottom needs
 * !important against `:root :where(.is-layout-flow) > * { margin-block-end: 0 }`,
 * exactly as OPP needed it against Twenty Nineteen's `.entry-content > *` margins.
 * Padding-top is OPP's .5rem (11px) PLUS the 22px heading margin-top that OPP kept
 * inside the card and TT5's constrained layout zeroes on the group's first child
 * (`:root :where(.is-layout-constrained) > * { margin-block-start: 0 }`) — measured
 * live: first heading 33px below the card top. */
.wp-block-group.program-card {
	padding: 33px 29px 19px; /* OPP .5rem (+22px folded heading margin) 1.3rem .85rem */
	margin-bottom: 28px !important; /* OPP 1.25rem */
	box-shadow: 4px 4px 7px rgba(0, 0, 0, 0.14);
	border-radius: 5px;
	background-color: var(--wp--preset--color--base);
}

/* Lists inside a card: no bullets, no indent ((0,2,1) beats §15's :where(ul) at
 * (0,2,0)); nested lists get OPP's arrow glyph instead of a marker. The bottom margin
 * restores the UA `1em` (19.36px on OPP) that the constrained layout zeroes — it is
 * what gives OPP's cards their room below the last list item (card heights matched
 * within ~10px once restored). */
.wp-block-group.program-card ul {
	padding-left: 0;
	list-style: none;
	margin-bottom: 19px;
}

.wp-block-group.program-card ul ul {
	margin-bottom: 18px; /* OPP .8rem */
}

.wp-block-group.program-card ul ul li::before {
	content: "";
	display: inline-block;
	width: 15px;
	height: 15px;
	margin-right: 6px; /* OPP .25rem */
	background: url(assets/images/list-arrow.png) no-repeat 0 0 / contain;
}

.wp-block-group.program-card .wp-block-buttons {
	margin-bottom: 6px; /* OPP .25rem */
}

/* "Delivery" row: a 2-column block holding a nowrap icon+label group. TT5 gives each
 * column flex-basis:0, so the group was squeezed into half the card and the icons
 * shrank; OPP lets the columns size to their content. !important mirrors OPP and is
 * needed against core's `.wp-block-columns:not(.is-not-stacked-on-mobile) >
 * .wp-block-column { flex-basis: 0 }` (0,3,0). */
.wp-block-columns.cols-delivery {
	display: flex;
	flex-wrap: wrap !important;
	gap: 0;
	margin-bottom: 0;
}

.wp-block-columns.cols-delivery > .wp-block-column {
	flex-basis: auto !important;
	margin-bottom: 19px; /* OPP .85rem */
}

.wp-block-columns.cols-delivery .wp-block-image {
	flex-shrink: 0;
}

/* The icon+label group inside the Delivery row is a flex group. TT5's root blockGap
 * (1.2rem) becomes its gap; OPP, with no blockGap, rendered WP's 0.5em fallback. */
.wp-block-columns.cols-delivery .wp-block-group.is-layout-flex {
	gap: 0.5em;
}

/* "Text" button style (`is-style-text`, registered by mu-plugins/mg-umbc): an underlined
 * text link with a 19px arrow icon, no box. (0,3,0)+ beats theme.json's
 * `:root :where(.wp-element-button, .wp-block-button__link)` fill styling and §19's
 * `.at-a-glance a` teal. OPP #000 → contrast; hover #636466 == accent-4. */
.wp-block-button.is-style-text .wp-block-button__link {
	display: flex;
	align-items: center;
	padding: 0;
	border: none;
	background-color: transparent;
	color: var(--wp--preset--color--contrast);
	font-weight: 400;
	text-decoration: underline;
	margin-right: 22px; /* OPP 1rem */
	margin-bottom: 11px; /* OPP .5rem */
}

.wp-block-button.is-style-text .wp-block-button__link::after {
	content: "";
	display: inline-block;
	width: 19px;
	height: 19px;
	margin-left: 8px; /* OPP .35rem */
	background: url(assets/images/button-icon.png) no-repeat 0 0 / contain;
}

.wp-block-button.is-style-text .wp-block-button__link:hover,
.wp-block-button.is-style-text .wp-block-button__link:focus,
.wp-block-button.is-style-text .wp-block-button__link:active {
	padding: 0;
	border: none;
	background-color: transparent;
	color: var(--wp--preset--color--accent-4);
	text-decoration: none;
}

.wp-block-button.is-style-text .wp-block-button__link:hover::after,
.wp-block-button.is-style-text .wp-block-button__link:focus::after,
.wp-block-button.is-style-text .wp-block-button__link:active::after {
	background-image: url(assets/images/button-icon-active.png);
}

/* ---------------------------------------------------------------------------
 * 21. Faculty read-more toggles — .faculty-read-more / .faculty-more / .faculty-show-less
 * Faculty and advisory-board pages (22 published pages) author each bio as
 *   <p class="faculty-read-more">Show more</p><p class="faculty-more">…</p>.
 * OPP hid the bio and styled the toggle here (_custom.scss:6543-6564) and ran the
 * click behaviour as inline jQuery at the bottom of OPP/footer.php (l.42-56) — a
 * script the block theme dropped with the classic footer, so every bio rendered
 * fully expanded under a dead "Show more" line (local page 12,607px tall vs OPP's
 * 6,812). The behaviour is now assets/js/faculty-toggle.js (vanilla, enqueued by
 * functions.php only on pages whose content carries the class); it reveals a bio
 * by adding `.is-open` and appends the "Show Less" span exactly as OPP did.
 * OPP's #007176 == accent-2. The `[hidden]` state is set by the script on the
 * "Show more" paragraph while its bio is open. NOT mirrored into the editor
 * stylesheet: `.faculty-more { display: none }` would hide content in the canvas.
 * ------------------------------------------------------------------------- */
.faculty-read-more,
.faculty-show-less {
	cursor: pointer;
	font-weight: 700;
	color: var(--wp--preset--color--accent-2);
}

.faculty-read-more::after {
	content: " ▾";
	font-weight: 400;
}

.faculty-show-less {
	display: block;
}

.faculty-show-less::after {
	content: " ▴";
	font-weight: 400;
}

.faculty-more {
	display: none;
}

.faculty-more.is-open {
	display: block;
}

.faculty-read-more[hidden] {
	display: none;
}

/* ---------------------------------------------------------------------------
 * 22. Cover block — OPP padding
 * OPP/sass/blocks/_blocks.scss:549-556 gives `.wp-block-cover` a 22px inset and
 * `22px 10%` from 768px (the 10% resolves against the 1032px container: live
 * /community-leadership/ measures `22px 103px`, inner column 726px). Core's cover
 * default is `padding: 1em` (19px here), so the child's inner column ran ~894px
 * wide and the hero heading wrapped differently. min-height 430px already matches
 * core. Scoped to page bodies like §14/§18. (2026-09-09)
 * ------------------------------------------------------------------------- */
.page .wp-block-post-content .wp-block-cover {
	padding: 22px;
}

@media (min-width: 768px) {
	.page .wp-block-post-content .wp-block-cover {
		padding: 22px 10%;
	}
}

/* ---------------------------------------------------------------------------
 * 23. Legacy `has-N-columns` inter-column margin — Twenty Nineteen port
 * Classic-editor-era Columns blocks carry `has-2-columns` / `has-3-columns` /
 * `has-4-columns` (60 / 13 / 1 live pages by REST search, plus the "At a Glance"
 * columns inside the 34 program-hub reusable blocks → 119 pages). Twenty Nineteen —
 * hence OPP — spaced those with a column margin ON TOP of the block's own gap:
 * `.entry .entry-content .wp-block-columns[class*='has-'] > * { margin-right: 1rem }`
 * (+ `:last-child { margin-right: 0 }`) from 768px (OPP/sass/_custom.scss:5986-5990;
 * 1rem = 22px at OPP's root). The gap itself was never the problem — `.at-a-glance`
 * measures 4.84px on OPP vs 4.75 here (§19's 0.25em, parity) and plain columns 38.72
 * vs 38 (theme.json 2em) — but without the margin the two "At a Glance" card columns
 * sat 5px apart instead of OPP's 26 (1024: 4 vs 27) and legacy 2-column text blocks
 * 38 instead of 60: the "padding between the boxes" Jeff flagged on the multidev
 * (2026-09-14). Newer Columns blocks (no `has-` class) and `.cols-delivery` already
 * match OPP and are untouched. 782px (core's stacking breakpoint) rather than OPP's
 * 768: between 768 and 781 OPP's columns are already stacked at 100% and the margin
 * only shaved 22px off each stacked column — a bug, not a design. `[class*="has-"]`
 * also matches `has-background` etc., exactly as OPP's selector did.
 * ------------------------------------------------------------------------- */
@media (min-width: 782px) {
	.wp-block-post-content .wp-block-columns[class*="has-"] > .wp-block-column:not(:last-child) {
		margin-right: 22px; /* OPP 1rem @22px root */
	}
}

/* ---------------------------------------------------------------------------
 * 24. Blog listing — OPP archive grid, excerpt cards, meta line, sidebar rail, pagination
 * templates/home.html, archive.html, search.html + patterns/blog-query-loop.php
 * + parts/blog-sidebar.html replace the parent's stock blog, which rendered a
 * centred 720px column with no rail and the WHOLE post body under a 3:2
 * featured image (Remaining-Gaps audit rows A1–A11, C1–C5; category page
 * 22,323px tall vs OPP 4,444). Geometry is OPP/sass/_grid.scss plus the blog
 * rules in _custom.scss (:4226-4282 meta, :3522-3573 pagination, :6489-6512
 * .entry-description) and the Customizer "Additional CSS" (post 5147
 * l.247-350: widget type, .prgm-list), measured live 2026-09-14 @1440:
 * container 144/1152 (80% + 71px), grid 183/1042, main column 183/695 (content
 * 203/675), rail 878/347 (list 910/315, items 934/291); card thumbnail 145×81 at
 * 203, text at 380/498, excerpt capped to 398 (OPP's inherited `.entry
 * .entry-content { max-width: 80% }`), meta 13.77px #767676 with 16px icons;
 * pagination 17.2px/700, 22px padding, indented calc(10% + 60px). OPP's columns
 * engage at 1000px (not core's 782): below that the thumbnail stacks above the
 * text and the rail sits under the posts. 1rem OPP = 22px. Everything is scoped
 * to `.umbc-blog` (the templates' <main>) so static pages are untouched; OPP's
 * `article.entry` selectors become the templates' `umbc-*` classes.
 * ------------------------------------------------------------------------- */

/* Container — .archive-grid-bind (_grid.scss:1-20). */
.umbc-blog {
	box-sizing: border-box;
	width: 100%;
	max-width: calc(100% - 44px);
	margin: 0 auto;
	padding: 0;
}

@media (min-width: 768px) {
	.umbc-blog {
		max-width: 80%;
		padding: 0 60px;
	}
}

@media (min-width: 1000px) {
	.umbc-blog {
		padding: 0 71px;
	}
}

/* Grid — .um-en-grid + .um-en-grid__col (_grid.scss:32-75): a 32px gutter faked
 * by a negative row margin and column padding; the 8/12 column pads 20px. */
.umbc-blog__grid {
	display: flex;
	flex-wrap: wrap;
	margin-left: -32px;
}

.umbc-blog__grid > * + *,
.umbc-blog__main > * + *,
.umbc-card > * + *,
.umbc-card__body > * + *,
.archive-wa > * + * {
	margin-block-start: 0; /* OPP spacing below, not TT5's 1.2rem flow gap */
}

/* `.umbc-blog__grid > …` and `.umbc-card > …` (0,2,0): core's flow layout zeroes a
 * group's first/last child margins with `:root :where(.is-layout-flow) > :last-child`
 * at (0,2,0), which would eat OPP's 48px column margin-bottom and the rail's first
 * heading margin — the child selectors tie on specificity and win on order. */
.umbc-blog__grid > .umbc-blog__main,
.umbc-blog__grid > .umbc-blog__side {
	box-sizing: border-box;
	flex: 0 1 auto;
	width: 100%;
	position: relative;
	padding-left: 32px;
	margin-bottom: 48px;
}

@media (min-width: 1000px) {
	.umbc-blog__grid > .umbc-blog__main {
		width: 66.6667%;
		padding-left: 20px;
	}

	.umbc-blog__grid > .umbc-blog__main--full {
		width: 100%; /* search.php had no rail */
	}

	.umbc-blog__grid > .umbc-blog__side {
		width: 33.3333%;
	}
}

/* Page heading + intro — h1.entry-title (2.25em @19.36 = 43.56px, margins 1rem)
 * and .entry-description (_custom.scss:6489-6512: italic, 2px grey rule). */
.umbc-blog h1.entry-title {
	font-size: 44px;
	line-height: 1.2;
	font-weight: 700;
	letter-spacing: -0.02em;
	margin: 22px 0;
}

.umbc-blog .entry-description {
	font-style: italic;
	font-size: 19px; /* OPP holds 19.36 at every width; TT5's fluid body would drop to 14.35 @375 */
	line-height: 1.5;
	border-bottom: 2px solid #808080;
	margin: 0;
}

.umbc-blog .entry-description p {
	margin: 19px 0; /* UA 1em @19.36 */
}

/* Cards — article.article-grid.entry (_grid.scss:22-30): 20px after the intro,
 * then 32px apart; each card is its own 25/75 .um-en-grid. */
.umbc-blog__list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.umbc-blog__list > li {
	margin: 32px 0 0;
	padding: 0;
}

.umbc-blog__list > li:first-child {
	margin-top: 20px;
}

.umbc-card {
	display: flex;
	flex-wrap: wrap;
	margin-left: -32px;
}

.umbc-card > .umbc-card__thumb,
.umbc-card > .umbc-card__body {
	box-sizing: border-box;
	flex: 0 1 auto;
	width: 100%;
	padding-left: 32px;
	margin-bottom: 48px;
}

@media (min-width: 1000px) {
	.umbc-card > .umbc-card__thumb {
		width: 25%;
	}

	.umbc-card > .umbc-card__body {
		width: 75%;
	}
}

.umbc-card__thumb .wp-block-post-featured-image {
	margin: 0;
}

.umbc-card__thumb img {
	display: block;
	max-width: 100%;
	height: auto;
}

/* Card title — h2.entry-title a (_grid.scss:91-99): 20px/1.2 on the link, inherit
 * colour, underlined; hover accent-4 as §11 does for page headings (OPP #4a4a4a).
 * Also closes the register's A7/K26 — post titles were UMBC Red here. */
.umbc-card h2.entry-title {
	font-size: 20px;
	line-height: 1.2;
	letter-spacing: -0.02em;
	margin: 0;
}

.umbc-card h2.entry-title a,
.umbc-card h2.entry-title a:visited {
	color: inherit;
	text-decoration: underline;
}

.umbc-card h2.entry-title a:hover,
.umbc-card h2.entry-title a:focus-visible {
	color: var(--wp--preset--color--accent-4);
}

/* Excerpt — .entry-content inside a card kept Twenty Nineteen's cap
 * (_custom.scss:4368-4381): calc(100% - 44px), 80% from 768px; the paragraph
 * carries OPP's 32px block margins. */
.umbc-card .wp-block-post-excerpt {
	max-width: calc(100% - 44px);
	margin: 0;
	font-size: 19px;
	line-height: 1.5;
}

@media (min-width: 768px) {
	.umbc-card .wp-block-post-excerpt {
		max-width: 80%;
	}
}

.umbc-card .wp-block-post-excerpt__excerpt {
	margin: 32px 0;
}

/* Meta line — footer.entry-footer (_custom.scss:4226-4265 + :2363 0.71111em):
 * #767676, weight 500, inline-block spans 1rem apart, 16px icons half an em
 * before each, links currentColor → #0073aa. The icons are Twenty Nineteen's
 * SVGs (classes/class-twentynineteen-svg-icons.php: person, watch, archive/
 * folder, tag, comment) as data URIs so the templates carry no inline SVG. */
.umbc-card__meta {
	margin: 0;
	color: #767676;
	font-weight: 500;
	font-size: 13.5px; /* OPP 0.71111em of a fixed 19.36 = 13.77; fixed here so TT5's fluid phone type (K2) doesn't shrink it to 10px */
	line-height: 1.5;
}

.umbc-card__meta > * {
	display: inline-block;
	margin: 0 22px 0 0;
	vertical-align: top;
}

.umbc-card__meta > *:last-child {
	margin-right: 0;
}

.umbc-card__meta .wp-block-post-author-name {
	display: inline; /* sits after the icon inside the .byline group */
}

.umbc-card__meta .wp-block-post-author-name,
.umbc-card__meta .wp-block-post-date,
.umbc-card__meta .wp-block-post-terms {
	font-size: inherit; /* TT5 gives post-date/post-terms the small preset + 600 */
	font-weight: inherit;
	color: inherit;
}

.umbc-card__meta a,
.umbc-card__meta a:visited {
	color: currentColor;
	text-decoration: none;
	transition: color 110ms ease-in-out;
}

.umbc-card__meta a:hover,
.umbc-card__meta a:focus-visible {
	color: #0073aa;
	text-decoration: none;
}

.umbc-card__meta .wp-block-post-terms__prefix {
	/* OPP's "Posted in" / "Tags:" were screen-reader-only spans. */
	border: 0;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}

.umbc-meta::before {
	content: "";
	display: inline-block;
	width: 16px;
	height: 16px;
	margin-right: 0.5em;
	vertical-align: middle;
	background-repeat: no-repeat;
	background-position: center;
	background-size: 16px 16px;
}

.umbc-meta--author::before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23767676' d='M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z'/%3E%3C/svg%3E");
}

.umbc-meta--date::before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23767676' d='M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm4.2 14.2L11 13V7h1.5v5.2l4.5 2.7-.8 1.3z'/%3E%3C/svg%3E");
}

.umbc-meta--cats::before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23767676' d='M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z'/%3E%3C/svg%3E");
}

.umbc-meta--tags::before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23767676' d='M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z'/%3E%3C/svg%3E");
}

.umbc-meta--comments::before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23767676' d='M21.99 4c0-1.1-.89-2-1.99-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4-.01-18z'/%3E%3C/svg%3E");
}

/* Events in search results: OPP's entry footer printed nothing for
 * non-post types (twentynineteen_entry_footer() is `post`-only). */
.umbc-blog__list > li.type-tribe_events .umbc-card__meta {
	display: none;
}

/* No-results copy — content-none.php inside .page-content. */
.umbc-blog__no-results {
	margin: 66px 0;
}

/* Sidebar rail — ul.archive-wa (_grid.scss:101-164) + Customizer l.326-350:
 * 24px uppercase headings on a 2px gold rule, 22px list type, recent posts
 * 20px apart, categories with a gold arrow (a Dashicon in OPP; inline SVG here
 * so nothing depends on Dashicons loading), the program list as plain discs. */
.umbc-blog__side .archive-wa {
	margin: 0;
	padding: 0;
}

@media (min-width: 1000px) {
	.umbc-blog__side .archive-wa {
		padding-top: 22px;
		padding-left: 24px;
	}
}

.archive-wa h2,
.archive-wa > h2:first-child {
	font-size: 24px;
	line-height: 1.2;
	font-weight: 700;
	letter-spacing: -0.02em;
	text-transform: uppercase;
	border-bottom: 2px solid var(--wp--preset--color--accent-1);
	margin: 22px 0; /* first heading sits 22px under the 22px rail padding: y=316 like OPP */
}

.archive-wa ul {
	list-style: none;
	margin: 0;
	padding: 0;
}

.archive-wa li {
	/* OPP's `.widget_recent_entries ul li` / `.widget_categories ul li` (_custom.scss:4990)
	 * set Twenty Nineteen's system-sans stack, so the rail lists never rendered in
	 * Roboto; ported so titles wrap on the same words. */
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
	font-size: 22px;
	line-height: 1.1;
	font-weight: 700;
	color: #767676;
	margin: 11px 0 20px;
}

.archive-wa li:last-child {
	margin-bottom: 0;
}

.archive-wa a,
.archive-wa a:visited {
	color: var(--wp--preset--color--contrast);
	font-weight: 400;
	text-decoration: none;
}

.archive-wa a:hover,
.archive-wa a:focus-visible {
	color: var(--wp--preset--color--contrast);
	text-decoration: underline;
}

/* Category marker: OPP used the Dashicons `arrow-right-alt2` glyph (`\f345`, a bold
 * gold chevron), not the Twenty Nineteen SVGs the meta line uses. It is kept as the
 * real Dashicon rather than an inline SVG because — unlike the meta icons' dropped
 * Font Awesome — Dashicons is a WordPress core font that is always available; the
 * child enqueues it on blog views (inc/blog.php) exactly as OPP relied on it being
 * present. Font-size inherits the 22px `li` like OPP; a glyph `::before` sizes itself
 * (no box/background). OPP _grid.scss:150-155. */
.archive-wa .wp-block-categories li::before {
	content: "\f345";
	font-family: dashicons;
	color: var(--wp--preset--color--accent-1); /* UMBC Gold #FDB515 = OPP's rgb(253,181,21) */
	margin-right: 10px;
	vertical-align: bottom;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

.archive-wa .prgm-list {
	list-style: disc outside;
	padding-left: 44px;
}

.archive-wa .prgm-list li {
	font-family: inherit; /* a plain wp:list in OPP — body Roboto, not the widget stack */
	line-height: 1.5;
	font-weight: 400;
	color: var(--wp--preset--color--contrast);
	margin: 0;
}

/* Pagination — nav.pagination .nav-links (_custom.scss:3522-3573, :2357):
 * 0.88889em/700 numbers padded 1rem (½rem below 768), the row indented
 * calc(10% + 60px) inside the column from 768px, prev/next in the link colour
 * with a 22px chevron; the "Newer/Older posts" labels hide below 768px. */
.umbc-blog__pagination {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0;
	margin: 0;
	padding: 0 11px;
	font-size: 17px;
	font-weight: 700;
	line-height: 1.25;
	letter-spacing: -0.02em;
}

@media (min-width: 768px) {
	.umbc-blog__pagination {
		margin-left: calc(10% + 60px);
		padding: 0;
	}
}

.umbc-blog__pagination > * {
	margin: 0;
}

.umbc-blog__pagination .wp-block-query-pagination-numbers {
	display: flex;
	flex-wrap: wrap;
}

.umbc-blog__pagination .page-numbers,
.umbc-blog__pagination .wp-block-query-pagination-previous,
.umbc-blog__pagination .wp-block-query-pagination-next {
	display: inline-block;
	padding: 11px;
	text-decoration: none;
}

@media (min-width: 768px) {
	.umbc-blog__pagination .page-numbers,
	.umbc-blog__pagination .wp-block-query-pagination-previous,
	.umbc-blog__pagination .wp-block-query-pagination-next {
		padding: 22px;
	}
}

.umbc-blog__pagination .page-numbers,
.umbc-blog__pagination .page-numbers:visited {
	color: var(--wp--preset--color--contrast);
}

.umbc-blog__pagination .wp-block-query-pagination-previous {
	padding-left: 0;
}

.umbc-blog__pagination .page-numbers.dots {
	padding-left: 0; /* OPP `.nav-links > *.dots` — keeps the numbers run 44px tighter */
	padding-right: 0;
}

.umbc-blog__pagination .wp-block-query-pagination-next {
	padding-right: 0;
}

.umbc-blog__pagination a:hover,
.umbc-blog__pagination a:focus-visible {
	text-decoration: underline;
}

.umbc-blog__pagination .wp-block-query-pagination-previous-arrow,
.umbc-blog__pagination .wp-block-query-pagination-next-arrow {
	font-size: 22px;
	line-height: 1;
	vertical-align: text-bottom;
}

@media (max-width: 767.98px) {
	.umbc-blog__pagination .wp-block-query-pagination-previous,
	.umbc-blog__pagination .wp-block-query-pagination-next {
		font-size: 0; /* chevron only, like OPP's hidden .nav-prev-text/.nav-next-text */
	}
}

/* Search — search.php's grey "search all of UMBC" box (#8e8e8e inline style,
 * sitting in OPP's .entry-content container) and the results heading, which
 * OPP split into a grey "Search results for:" and the term (here one h1). */
.umbc-blog--search #searchUMBC {
	background-color: #8e8e8e;
	margin-top: 1em;
	padding: 1px 22px;
}

@media (min-width: 768px) {
	.umbc-blog--search #searchUMBC {
		padding: 1px 60px;
	}
}

.umbc-blog--search #searchUMBC p {
	margin: 19px 0;
}

.umbc-blog--search .umbc-search-umbc__form {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 11px;
	padding-bottom: 19px;
}

.umbc-blog--search .umbc-search-umbc__input {
	flex: 1 1 200px;
	min-width: 0;
}

.umbc-blog--search h1.entry-title {
	color: #767676;
	margin-bottom: 44px;
}

/* ---------------------------------------------------------------------------
 * 25. Blog single (detail) — OPP single-post layout
 * templates/single.html rebuilds OPP/single.php + content-single.php as a block
 * template. It reuses the section 24 shell: `.umbc-blog` container geometry,
 * the `.umbc-blog__grid` 66.67/33.33 two-column split at ≥1000px (main + the
 * `blog-sidebar` rail), `h1.entry-title` (44px), `.entry-description` (italic +
 * bottom rule) and the global `.umbc-meta--*::before` icons — so this section
 * only adds the single-only pieces OPP rendered in content-single.php /
 * entry-description.php / author-bio.php / the post navigation and comments,
 * ported from OPP `_custom.scss` (:6489 entry-description, :4226 meta, :6611
 * author-bio, :3422 post-navigation, :4471 comments). OPP forces
 * `twentynineteen_can_show_post_thumbnail` false site-wide (functions.php:120),
 * so single posts never show a featured image and the header renders inline —
 * single.html carries no `wp:post-featured-image`. Everything is scoped to
 * `.umbc-blog--single` so the listing and static pages are untouched. Measured
 * live 2026-09-14 (professionalprograms.umbc.edu, dev-umbc-opp).
 * ------------------------------------------------------------------------- */

/* Article header spacing — OPP `.single .um-en-grid .entry-header{margin-top:48px}`
 * (_grid.scss) plus the title's own margin ≈ 66px above the H1 (measured live).
 * `h1.entry-title` to beat §24's same-named rule (0,2,1) on source order. */
.umbc-blog--single h1.entry-title {
	margin-top: 66px;
}

/* Category intro — entry-description.php: a linked first-category heading over
 * that category's description, italic, ruled top AND bottom (base rule in §24
 * is the bottom; --top-border adds the top). Heading is OPP teal (accent-2). */
.umbc-blog--single .entry-description {
	margin: 22px 0 0;
	padding: 28px 0;
}

.umbc-blog--single .entry-description--top-border {
	border-top: 2px solid #808080;
}

.umbc-blog--single .entry-description__heading {
	font-size: 25px; /* OPP 1.3em of 19.36 */
	line-height: 1.2;
	font-weight: 700;
	font-style: normal;
	letter-spacing: -0.02em;
	margin: 0 0 6px;
}

.umbc-blog--single .entry-description__heading a,
.umbc-blog--single .entry-description__heading a:visited {
	color: var(--wp--preset--color--accent-2); /* OPP teal #007176 */
	text-decoration: none;
}

.umbc-blog--single .entry-description__heading a:hover,
.umbc-blog--single .entry-description__heading a:focus-visible {
	text-decoration: underline;
}

.umbc-blog--single .entry-description__desc {
	font-style: italic;
}

.umbc-blog--single .entry-description__desc p {
	margin: 19px 0;
}

.umbc-blog--single .entry-description__desc :first-child {
	margin-top: 0;
}

.umbc-blog--single .entry-description__desc :last-child {
	margin-bottom: 0;
}

/* Meta rows — the header meta (author · date · comments) and the footer meta
 * (categories · tags), both `.umbc-blog__meta`. Same treatment as the card meta
 * (§24 `.umbc-card__meta`): #767676 / weight 500 / 13.5px, inline-block items
 * 22px apart, the §24 `.umbc-meta--*` icons half an em before each, links in
 * currentColor. OPP printed "Posted in" / "Tags:" as screen-reader spans. */
.umbc-blog--single .umbc-blog__meta {
	margin: 22px 0 0;
	color: #767676;
	font-weight: 500;
	font-size: 13.5px;
	line-height: 1.5;
}

.umbc-blog--single .entry-footer.umbc-blog__meta {
	margin-top: 32px;
}

.umbc-blog--single .umbc-blog__meta > * {
	display: inline-block;
	margin: 0 22px 0 0;
	vertical-align: top;
}

.umbc-blog--single .umbc-blog__meta > *:last-child {
	margin-right: 0;
}

.umbc-blog--single .umbc-blog__meta .byline {
	margin-bottom: 0; /* the author group is a flow group; keep it on the meta line */
}

.umbc-blog--single .umbc-blog__meta .wp-block-post-author-name {
	display: inline;
}

.umbc-blog--single .umbc-blog__meta .wp-block-post-author-name,
.umbc-blog--single .umbc-blog__meta .wp-block-post-date,
.umbc-blog--single .umbc-blog__meta .wp-block-post-terms {
	font-size: inherit;
	font-weight: inherit;
	color: inherit;
}

.umbc-blog--single .umbc-blog__meta a,
.umbc-blog--single .umbc-blog__meta a:visited {
	color: currentColor;
	text-decoration: none;
	transition: color 110ms ease-in-out;
}

.umbc-blog--single .umbc-blog__meta a:hover,
.umbc-blog--single .umbc-blog__meta a:focus-visible {
	color: #0073aa;
}

.umbc-blog--single .umbc-blog__meta .wp-block-post-terms__prefix {
	/* OPP's "Posted in" / "Tags:" were screen-reader-only spans. */
	border: 0;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}

/* Post body — left-aligned in the 66.67% column, capped to OPP's inherited
 * `.entry .entry-content{max-width:80%}` (_custom.scss:4368) = ~540px of the
 * 675px column (override TT5's centred, constrained 720px column). The narrower
 * measure is why OPP's body wraps taller than TT5's. Block rhythm is
 * theme.json's 32px post-content blockGap. No featured image on singles (OPP
 * filter); guard defensively. */
.umbc-blog--single .wp-block-post-content {
	max-width: calc(100% - 44px);
	margin: 32px 0 0;
}

@media (min-width: 768px) {
	.umbc-blog--single .wp-block-post-content {
		max-width: 80%;
	}
}

.umbc-blog--single .wp-block-post-featured-image {
	display: none;
}

/* Author bio — author-bio.php (_custom.scss:6611): a light-grey box with the
 * avatar on the left and the bold name link (+ optional description) beside it,
 * vertically centred. */
.umbc-blog--single .author-bio {
	display: flex;
	align-items: center;
	gap: 18px;
	margin: 32px 0;
	padding: 24px;
	background-color: #dddddd;
}

.umbc-blog--single .author-bio .avatar {
	flex: 0 0 auto;
	display: block;
	height: 64px;
	width: 64px;
	margin: 0;
	border-radius: 50%;
}

.umbc-blog--single .author-bio .author-box {
	min-width: 0;
}

.umbc-blog--single .author-bio .author-title {
	display: inline-block;
	color: #111111;
	font-weight: 700;
	font-size: 22px;
	line-height: 1.2;
	margin: 0;
	text-decoration: none;
}

.umbc-blog--single .author-bio .author-title:hover,
.umbc-blog--single .author-bio .author-title:focus-visible {
	text-decoration: underline;
}

.umbc-blog--single .author-bio .author-description {
	color: #111111;
	font-size: 16px; /* OPP 0.727rem */
	line-height: 1.4;
	margin: 6px 0 0;
}

/* Post navigation — the_post_navigation (_custom.scss:3422+): stacked on mobile,
 * a two-up row at ≥768px with Previous on the left and Next right-aligned. */
.umbc-blog--single .post-navigation {
	margin: 44px 0;
}

.umbc-blog--single .nav-links {
	display: flex;
	flex-direction: column;
	gap: 22px;
}

.umbc-blog--single .nav-links .wp-block-post-navigation-link {
	margin: 0;
}

@media (min-width: 768px) {
	.umbc-blog--single .nav-links {
		flex-direction: row;
		justify-content: space-between;
	}

	.umbc-blog--single .nav-links .nav-previous {
		order: 1;
		min-width: calc(50% - 22px);
	}

	.umbc-blog--single .nav-links .nav-next {
		order: 2;
		min-width: calc(50% - 22px);
		text-align: right;
	}
}

.umbc-blog--single .nav-links a,
.umbc-blog--single .nav-links a:visited {
	color: var(--wp--preset--color--contrast); /* not TT5's UMBC-red link colour */
	text-decoration: none;
}

.umbc-blog--single .nav-links a:hover,
.umbc-blog--single .nav-links a:focus-visible {
	color: var(--wp--preset--color--accent-2);
	text-decoration: underline;
}

/* Comments — comments.php (_custom.scss:4471). Kept at the full column width
 * (OPP narrowed it to ~6/12 of the viewport; revisit only if the diff needs it). */
.umbc-blog--single .comments-area {
	margin: 44px 0 0;
}

.umbc-blog--single .comments-title,
.umbc-blog--single .comment-reply-title {
	font-size: 28px;
	font-weight: 700;
	letter-spacing: -0.02em;
	line-height: 1.2;
}

.umbc-blog--single .comment-list {
	list-style: none;
	margin: 22px 0;
	padding: 0;
}
