/*
Theme Name: SDA Website
Description: Custom hand-coded WordPress theme for Stanford Downey Architects (stanforddowney.ca) — classic PHP template hierarchy, no page builder, no block/FSE architecture.
Author: Ivan Formaran
Version: 0.1.0
Text Domain: sda-website
*/

/* ==========================================================================
   CSS custom properties (design tokens)

   Full site-wide token system per DESIGN.md `colors`, `typography`,
   `layout`, and Revision Notes (8px-based spacing scale). Built
   incrementally: header.php and footer.php contributed the header- and
   footer-specific subset first (do not duplicate those below); this
   base-stylesheet task completes the block with the remaining color,
   typography, and spacing tokens for sitewide base styles and future
   page templates.
   ========================================================================== */
:root {
	--sda-color-page-bg: #FFFFFF;
	--sda-color-ink: #4A4A4A;
	--sda-color-ink-strong: #000000;
	--sda-color-accent: #0B5579;
	/* DESIGN.md confirmed 2026-07-30, direct from the live site's
	   Squarespace design panel: this is "Nav Link (Active)" — the
	   nav-link hover/active color. Applied below wherever a nav-link-
	   styled control previously used a generic opacity shift as an
	   unconfirmed-color placeholder (.main-navigation .primary-menu a,
	   .hero-slideshow-nav, .project-category-tile-link,
	   .term-projects-tile-link, .single-project-nav-prev/-next,
	   .news-list-pagination .page-numbers, .post-navigation a). */
	--sda-color-accent-light: #2F93B1;
	/* DESIGN.md confirmed 2026-07-30, same Squarespace panel: "Page Meta
	   Color" — secondary/supporting text (dates, bylines, tags, meta-row
	   labels), distinct from --sda-color-ink's primary-body-copy role. */
	--sda-color-meta: #9E9E9E;
	/* Proposed, not present on the live site — needed for future form
	   states. No forms exist in this build yet; variables only. */
	--sda-color-success: #3F8F5C;
	--sda-color-error: #C4342B;
	--sda-font-family-base: 'Nunito Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
	--sda-content-max-width: 1020px;
	--sda-header-height-desktop: 122px;
	--sda-header-height-mobile: 90px;
	--sda-nav-link-font-size: 13px;
	--sda-nav-link-font-weight: 600;
	--sda-nav-link-letter-spacing: 2px;

	/* DESIGN.md typography.page-title — section headings ("ABOUT",
	   "PROJECTS", ...). Live site's actual computed value is 300 (Proxima
	   Nova-specific rendering), but 700 is used here as a font-substitution
	   visual match for the Nunito Sans replacement — confirmed via direct
	   measurement 2026-07-30. 700 renders closer to the live site's
	   intended weight than the literal 300 would in the substitute font. */
	--sda-page-title-font-size: 26px;
	--sda-page-title-font-weight: 700;
	--sda-page-title-line-height: 39px;

	/* DESIGN.md typography.body — all running copy (About text, News,
	   project meta labels). Distinct from --sda-footer-text-* below,
	   which uses reduced-opacity white on the dark footer panel. */
	--sda-body-font-size: 17px;
	--sda-body-font-weight: 400;
	--sda-body-line-height: 27.2px;

	/* DESIGN.md Revision Notes: no spacing scale exists on the live
	   site (hand-tuned Squarespace margins) — deliberate deviation,
	   adopt a clean 8px-based scale for the WP rebuild instead. */
	--sda-space-1: 8px;
	--sda-space-2: 16px;
	--sda-space-3: 24px;
	--sda-space-4: 32px;
	--sda-space-5: 48px;
	--sda-space-6: 64px;
	--sda-space-7: 96px;

	--sda-footer-bg: #4A4A4A;
	--sda-footer-text: rgba(255, 255, 255, 0.4);
	--sda-footer-text-strong: rgba(255, 255, 255, 0.8);
	/* Reduced ~30% 2026-08-06 per Ivan's review (17px -> 12px; line-height
	   scaled down proportionally, same ~1.6 ratio, 27.2px -> 19px) — the
	   footer now holds one short info line, not the fuller original block,
	   so DESIGN.md's originally-measured 17px/400 footer-text size read too
	   large for it. Only used by .site-footer, so this doesn't affect
	   anything outside the dark panel. */
	--sda-footer-text-font-size: 12px;
	--sda-footer-text-font-weight: 400;
	--sda-footer-text-line-height: 19px;
}

/* ==========================================================================
   Global base styles (base stylesheet task)

   Sitewide resets and defaults not owned by any single component, plus
   the .content-width and .page-title utilities future page templates
   (page-about.php, page-projects.php, etc.) will use directly. Source:
   DESIGN.md `typography.body`, `typography.page-title`, `colors`.
   ========================================================================== */
*,
*::before,
*::after {
	box-sizing: border-box;
}

body {
	margin: 0;
	font-family: var(--sda-font-family-base);
	font-size: var(--sda-body-font-size);
	font-weight: var(--sda-body-font-weight);
	line-height: var(--sda-body-line-height);
	color: var(--sda-color-ink);
	background-color: var(--sda-color-page-bg);
}

h1,
h2,
h3,
h4,
h5,
h6,
p {
	margin: 0 0 var(--sda-space-2);
}

/* Accent is used exclusively for navigation links and in-body
   hyperlinks per DESIGN.md `colors.accent`. Nav links override this
   with their own color/text-decoration rules above and below. */
a {
	color: var(--sda-color-accent);
}

/* Reusable centered-column pattern. .site-header-inner and
   .site-footer-inner already apply this max-width/margin/padding
   combination inline and are done/working — left as-is. This class is
   for the page templates that come next so they don't re-write the
   same three lines each time. */
.content-width {
	max-width: var(--sda-content-max-width);
	margin: 0 auto;
	padding: 0 var(--sda-space-3);
}

/* DESIGN.md typography.page-title — section headings ("ABOUT",
   "PROJECTS", "RESTAURANTS", "SELECTED CLIENTS"). Heading text is typed
   as real uppercase content in the CMS, not CSS text-transform — no
   text-transform rule here; future template tasks must type the
   heading text in caps themselves. */
.page-title {
	margin: 0 0 var(--sda-space-3);
	font-family: var(--sda-font-family-base);
	font-size: var(--sda-page-title-font-size);
	font-weight: var(--sda-page-title-font-weight);
	line-height: var(--sda-page-title-line-height);
	color: var(--sda-color-ink);
}

/* ==========================================================================
   Accessibility utility (standard WP theme convention)
   ========================================================================== */
.screen-reader-text {
	border: 0;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute !important;
	width: 1px;
	word-wrap: normal !important;
}

/* ==========================================================================
   Reduced motion (checklist criterion 6, Spec 08 10 00 §3.3)

   Added by the Phase 5 fe-review sweep — the theme had no
   prefers-reduced-motion handling at all, which is a binary checklist
   failure. Verified before the fix by loading the home page in a
   reduced-motion browser context: the hero slideshow still auto-advanced and
   still reported a 0.4s crossfade.

   Collapsing durations to 0.01ms rather than 0 is the standard form: the
   transition/animation still fires, so `transitionend`/`animationend`
   listeners that gate other behaviour don't silently stop running. The hero
   slideshow's *auto-advance timer* is JS, not CSS, so it can't be reached
   from here — front-page.php suppresses it separately (see the
   heroPrefersReducedMotion guard there). Its Prev/Next buttons keep working
   under both settings, so no content becomes unreachable.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

/* ==========================================================================
   Site header (header.php)

   Fixed white bar per DESIGN.md `components.header` + `layout` block:
   122px desktop / 90px mobile, logo left, nav right. Two separate,
   live-site-measured breakpoints as of the Phase 5 correction
   (2026-08-27) — see DESIGN.md Revision Notes ("Mobile header/nav
   toggle"): nav links collapse to the hamburger toggle at
   `max-width: 999px` (binary-searched live-site boundary: visible at
   1000px, hidden at 998px); header height steps 122px -> 90px
   separately at `max-width: 640px` (live-site boundary: 122px at
   641px, 90px at 640px). These replace the single reasoned-default
   768px breakpoint both concerns previously shared since Phase 1.
   ========================================================================== */
.site-header,
.site-header *,
.site-header *::before,
.site-header *::after {
	box-sizing: border-box;
}

.site-header {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 999;
	height: var(--sda-header-height-desktop);
	background-color: var(--sda-color-page-bg);
}

/* Push page content below the fixed header. Belongs here (not the base
   stylesheet task) because it's a direct consequence of the header's
   fixed position — without it, every template's content renders hidden
   underneath the bar. */
body {
	padding-top: var(--sda-header-height-desktop);
}

/* Keep the fixed header below the WP admin bar instead of overlapping it. */
body.admin-bar .site-header {
	top: 32px;
}
@media screen and (max-width: 782px) {
	body.admin-bar .site-header {
		top: 46px;
	}
}

.site-header-inner {
	max-width: var(--sda-content-max-width);
	height: 100%;
	margin: 0 auto;
	padding: 0 24px;
	display: flex;
	/* Reverted to `center` 2026-08-06 — a same-day `flex-end` change (to fix
	   the logo/nav scale mismatch below) turned out to be wrong: a live
	   DOM measurement taken this session (header 122px tall, logo top=20px/
	   bottom=102px) shows the live site's logo is actually *centered*, with
	   equal ~20px margins top and bottom — not bottom-aligned. flex-end put
	   all of that leftover space above the now-smaller logo instead of
	   splitting it evenly, which read as a big empty gap at the top of the
	   header. Reverting to center, which is both simpler and what the live
	   site's own measurements confirm it actually does; the logo-size
	   reduction below is what should be doing the real work of closing the
	   visual gap between the logo's wordmark text and the nav links. */
	align-items: center;
	justify-content: space-between;
	/* Added 2026-08-28, Phase 8 post-launch fix — see .site-branding below
	   for the actual overflow fix; this just guarantees a minimum breathing
	   room between the (now-shrinkable) logo and the toggle instead of
	   letting them land flush edge-to-edge on the narrowest phones. */
	gap: var(--sda-space-2);
}

/* Phase 8 post-launch fix (2026-08-28) — real Playwright renders at 375/390/
   414/430px confirmed Ivan's phone report and the investigation notes'
   hypothesis: .menu-toggle was rendering at x=346-390 while the viewport was
   only 375/390px wide, i.e. genuinely off-screen (not reachable by scroll
   either, since .site-header is `position: fixed` and fixed-position overflow
   doesn't extend document.documentElement.scrollWidth — confirmed scrollWidth
   stayed exactly equal to clientWidth even while the toggle rendered past the
   edge). Root cause: .site-branding's img renders ~322px wide at max-height:
   64px (its ~5:1 native ratio), and flex items default to `min-width: auto`,
   which floors a flex item's shrink at its own content size — so
   .site-branding could never shrink below the logo's full ~322px even though
   .menu-toggle (flex-shrink: 0, 44px) needed room too. 322 + 44 + 48px header
   padding = 414px, comfortably over 375/390 and just barely under 414/430 —
   matching exactly which widths broke and which didn't. Fixed with
   `min-width: 0` here (removes the shrink floor) and `max-width: 100%` on the
   logo img below (lets the browser's standard replaced-element sizing take
   the tighter of max-height/max-width while preserving aspect ratio) — the
   logo now shrinks only as far as narrow viewports actually require, full
   64px height everywhere it already fit. */
.site-branding {
	display: flex;
	align-items: center;
	min-width: 0;
}

.site-branding .custom-logo,
.site-branding img {
	display: block;
	height: auto;
	/* Reduced from 82px 2026-08-06 — matches DESIGN.md's note that the live
	   site's logo is "reduced a little" from its natural size specifically
	   so its wordmark text sits close to the nav links' size, not a large,
	   dominant mark. Centered (see .site-header-inner above) like the live
	   site, not bottom-aligned. */
	max-height: 64px;
	/* Added 2026-08-28 alongside .site-branding's min-width:0 above — the
	   pair that lets the logo actually shrink on narrow phones instead of
	   pushing .menu-toggle off-screen. See the comment above .site-branding
	   for the full measured root cause. */
	max-width: 100%;
	width: auto;
}

.site-title {
	margin: 0;
	font-family: var(--sda-font-family-base);
	font-size: 20px;
	font-weight: 600;
}

.site-title a {
	color: var(--sda-color-accent);
	text-decoration: none;
}

/* Hamburger toggle — hidden on desktop, shown under the mobile breakpoint.

   `flex-shrink: 0` added by the Phase 5 fe-review sweep and is the real bug
   fix here: this button is a flex item of .site-header-inner, and with the
   default `flex-shrink: 1` it was being crushed to 5px wide at 375px (the
   logo takes the rest of the row), rendering as a thin vertical sliver
   instead of a hamburger. Measured 5x32 at 375px / 32x32 at 768px before the
   fix, 44x44 at both after.

   Box grown 32x32 -> 44x44 for DET-14 / checklist 9 (44x44 minimum). The bars
   are pinned to an explicit 24px rather than the previous `width: 100%` so
   growing the hit area doesn't also grow the drawn icon — 24px keeps it at
   the live site's own icon scale (its .mobile-nav-toggle measures 22x22,
   DOM-measured 2026-08-27), which the old 100%-of-32px bars already
   over-shot. Note the live site's own 22x22 toggle would itself fail DET-14;
   parity does not license a checklist violation (Spec 08 10 00 §3.5). */
.menu-toggle {
	display: none;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	flex-shrink: 0;
	gap: 4px;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 0;
	background: transparent;
	cursor: pointer;
}

.menu-toggle-bar {
	display: block;
	width: 24px;
	height: 2px;
	background-color: var(--sda-color-accent);
}

.main-navigation {
	display: flex;
}

.main-navigation .primary-menu {
	display: flex;
	align-items: center;
	gap: 32px;
	list-style: none;
	margin: 0;
	padding: 0;
}

/* The flex/min-height trio is a DET-14 / checklist 9 fix from the Phase 5
   fe-review sweep: these links measured 47x18 / 56x18 / 79x18 / 75x18 at
   1024px+ — the full-height hit area was only the 18px inline text box.
   .site-header-inner is a fixed 122px row with `align-items: center` and
   .primary-menu is `align-items: center` too, so growing each link's box to
   44px re-centers it on very nearly the same baseline rather than pushing
   anything around. Measured A/B at 1440px (stash the change, render, restore,
   render): the link box goes 56x18 -> 56x44 while the text's own rect moves
   y=53 -> y=52 — a 1px shift from flex-centering rounding, not zero. Header
   height, .page-title position, document scrollWidth and total body height
   are all byte-identical before and after. */
.main-navigation .primary-menu a {
	display: flex;
	align-items: center;
	min-height: 44px;
	font-family: var(--sda-font-family-base);
	font-size: var(--sda-nav-link-font-size);
	font-weight: var(--sda-nav-link-font-weight);
	letter-spacing: var(--sda-nav-link-letter-spacing);
	line-height: 13px;
	text-transform: uppercase;
	color: var(--sda-color-accent);
	text-decoration: none;
}

.main-navigation .primary-menu a:hover,
.main-navigation .primary-menu a:focus {
	/* DESIGN.md confirmed 2026-07-30: {colors.accent-light} is
	   Squarespace's own "Nav Link (Active)" color — applied directly
	   instead of the earlier opacity-shift placeholder. */
	color: var(--sda-color-accent-light);
}

.primary-menu-fallback {
	margin: 0;
	font-family: var(--sda-font-family-base);
	font-size: 13px;
	color: var(--sda-color-ink);
}

/* Nav-link-to-hamburger collapse — max-width: 999px, live-site-measured
   (see file-header comment above). `.main-navigation`'s fixed dropdown
   defaults its `top` to the desktop header height (122px), because between
   this breakpoint and the separate 640px header-height step below, the
   header is still 122px tall — only the header-height media query
   overrides `top` down to the 90px mobile value once the header itself
   actually shrinks. Without this split, the dropdown would hang 32px too
   low (or high) somewhere in the 641-999px range. */
@media (max-width: 999px) {
	.menu-toggle {
		display: flex;
	}

	.main-navigation {
		position: fixed;
		top: var(--sda-header-height-desktop);
		left: 0;
		right: 0;
		flex-direction: column;
		max-height: 0;
		overflow: hidden;
		background-color: var(--sda-color-page-bg);
		transition: max-height 0.25s ease;
	}

	.main-navigation.is-open {
		max-height: 400px;
	}

	.main-navigation .primary-menu {
		flex-direction: column;
		align-items: flex-start;
		gap: 0;
		padding: 16px 24px;
	}

	.main-navigation .primary-menu li {
		width: 100%;
		border-bottom: 1px solid rgba(0, 0, 0, 0.08);
	}

	/* 12px -> 16px vertical padding: DET-14 / checklist 9. At 12px these
	   drawer links measured 37px tall (13px line-height + 24px padding), 7px
	   under the 44px floor — and this is the one nav that is genuinely
	   touch-operated. 16px puts them at 45px. */
	.main-navigation .primary-menu a {
		display: block;
		padding: 16px 0;
	}

	.primary-menu-fallback {
		padding: 16px 24px;
	}
}

/* Header-height step — max-width: 640px, live-site-measured (see
   file-header comment above). A separate, narrower breakpoint from the
   999px nav-collapse query above; `.main-navigation`'s dropdown `top`
   is re-pointed at the now-shorter mobile header height here so the
   drawer still hangs flush under the header once it actually steps down. */
@media (max-width: 640px) {
	.site-header {
		height: var(--sda-header-height-mobile);
	}

	body {
		padding-top: var(--sda-header-height-mobile);
	}

	.main-navigation {
		top: var(--sda-header-height-mobile);
	}
}

/* ==========================================================================
   Pre-footer (footer.php) — plain white section directly above the dark
   footer panel: Privacy Policy link (left) and copyright line (right).

   Rebuilt 2026-08-06 against the live site's real DOM — Privacy Policy and
   copyright live here, on the page background, NOT inside the dark panel
   below (see footer.php's file header comment for the full audit).
   ========================================================================== */
.pre-footer {
	background-color: var(--sda-color-page-bg);
}

.pre-footer-inner {
	padding-top: var(--sda-space-3);
	padding-bottom: var(--sda-space-3);
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--sda-space-2);
}

/* The inline-block/padding/negative-margin trio is a DET-14 / checklist 9 fix
   from the Phase 5 fe-review sweep: this is a standalone navigational link
   (its own <nav>), not a link inside running text, and it measured 251x23.
   The equal negative margin cancels the padding's effect on layout, so the
   margin box stays 23px and the pre-footer row's height and this link's
   rendered position are both unchanged — only the clickable area grows to
   45px. Verified by re-measuring the row height before/after. */
.pre-footer-link {
	display: inline-block;
	padding: 11px 0;
	margin: -11px 0;
	color: var(--sda-color-accent);
	font-size: var(--sda-body-font-size);
	text-decoration: underline;
}

.pre-footer-link:hover,
.pre-footer-link:focus {
	color: var(--sda-color-accent-light);
}

.pre-footer-copyright {
	margin: 0;
	color: var(--sda-color-ink);
	font-size: var(--sda-body-font-size);
}

/* ==========================================================================
   Site footer (footer.php) — the dark panel itself.

   Rebuilt 2026-08-06: now holds just one centered line combining the firm
   name/address/phone — the live site's dark panel is this simple; Privacy
   Policy/copyright above are a separate light section (.pre-footer). Back
   to Top was here too originally but Ivan asked to drop it (2026-08-06,
   same day) — removed, not hidden. footer-bg solid color, footer-text
   (40% white) for body copy, footer-text-strong (80% white) for links/
   labels. Typography per DESIGN.md `typography.footer-text`, reduced
   ~30% 2026-08-06 (17px/400/27.2px line-height -> 12px/400/19px — see the
   --sda-footer-text-* token comments).
   ========================================================================== */
.site-footer,
.site-footer *,
.site-footer *::before,
.site-footer *::after {
	box-sizing: border-box;
}

.site-footer {
	background-color: var(--sda-footer-bg);
	color: var(--sda-footer-text);
	font-family: var(--sda-font-family-base);
	font-size: var(--sda-footer-text-font-size);
	font-weight: var(--sda-footer-text-font-weight);
	line-height: var(--sda-footer-text-line-height);
	text-align: center;
}

.site-footer-inner {
	max-width: var(--sda-content-max-width);
	margin: 0 auto;
	/* Asymmetric 2026-08-06 per Ivan's review ("keep the text closer to the
	   top") — was an even --sda-space-5 (48px) all around; top reduced to
	   --sda-space-2 (16px) so the text sits close to the panel's top edge,
	   bottom left larger so the panel doesn't end up looking cramped/
	   clipped right under the text. */
	padding: var(--sda-space-2) 24px var(--sda-space-5);
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sda-space-2);
}

.footer-link {
	color: var(--sda-footer-text);
	text-decoration: underline;
}

.footer-link-strong {
	color: var(--sda-footer-text-strong);
}

.footer-info-line {
	margin: 0;
	/* Deliberate, narrowly-scoped exception to this theme's usual
	   real-uppercase-content-over-CSS-transform preference — see
	   footer.php's file header comment for why this specific line is
	   different from a `.page-title`-style heading. */
	text-transform: uppercase;
}

.footer-phone {
	margin-left: var(--sda-space-2);
}

/* ==========================================================================
   Home page (front-page.php)

   Hero slideshow: full-width image carousel of `featured_hero` projects,
   Previous/Next buttons, no on-slide captions. Source: DESIGN.md
   `components.hero-slideshow`. Reuses the .content-width/.page-title
   utilities and the color/typography/spacing tokens already defined above
   — no new tokens added here.

   The News Carousel component that used to live below the hero (recent
   WordPress Posts — thumbnail/title/date) was removed 2026-08-12 per
   Ivan's request, to free vertical space for a taller hero (see
   aspect-ratio note below). DESIGN.md's Home-page News Carousel component
   entry now describes a removed feature and is stale — flagged for a
   separate DESIGN.md update, not edited here (build-stage work never
   edits DESIGN.md directly).

   Aspect ratio corrected 2026-08-12 from a 16/7 placeholder guess (Phase 3)
   to a measured 16:9 — direct DOM measurement of the live site
   (stanforddowney.ca) found its hero images render at 956x538 within its
   956px content column, and source images' natural dimensions confirm the
   same ratio (e.g. 1000x562, 1000/562 = 1.779 ~= 16/9). At this theme's
   1020px content column this also makes the hero taller (446px -> 574px),
   satisfying Ivan's "taller" request via the same correct fix rather than
   a second arbitrary tweak.

   Phase 8 post-launch fix (2026-08-28): the "reuses .content-width" claim
   above was aspirational, not actual — .hero-slideshow carried its own
   max-width/margin (duplicating two of .content-width's three
   declarations) but no padding, and was never wrapped in a `.content-width`
   div the way every other template's content is, so it ran edge-to-edge on
   mobile alone. Fixed by wrapping the whole <section class="hero-slideshow">
   in a new `<div class="content-width hero-slideshow-wrap">` in
   front-page.php and dropping the now-redundant max-width/margin from this
   rule below — the wrapper now owns centering/max-width/padding, and
   .hero-slideshow (a block-level <section>) simply fills 100% of the
   wrapper's already-inset content box. Deliberately NOT done by adding
   padding directly to .hero-slideshow itself: .hero-slideshow-nav's
   `left`/`right: var(--sda-space-3)` resolve against .hero-slideshow's own
   padding-box edge (the standard CSS containing-block rule for absolutely
   positioned descendants), which is unmoved by padding added to that same
   element — padding there would have inset the image but left the Prev/Next
   buttons anchored to the old (now-wrong) edge, landing them flush against
   the image instead of --sda-space-3 inside it. Wrapping one level up avoids
   that entirely: .hero-slideshow itself still carries zero padding of its
   own, so the buttons keep the exact same position relative to the image
   they always had — only the image (and buttons together) moved inward. */
.hero-slideshow {
	position: relative;
	width: 100%;
	aspect-ratio: 16 / 9;
	overflow: hidden;
	background-color: var(--sda-color-ink);
}

.hero-slideshow-track {
	position: relative;
	width: 100%;
	height: 100%;
}

.hero-slide {
	position: absolute;
	inset: 0;
	opacity: 0;
	visibility: hidden;
	/* 0.4s -> 0.3s: DET-16 requires state transitions inside the 150-300ms
	   band, and 400ms was the only value in the stylesheet outside it (Phase 5
	   fe-review sweep). 300ms is the top of the band, so this stays the
	   slowest, most gradual crossfade the standard allows. */
	transition: opacity 0.3s ease;
}

.hero-slide.is-active {
	opacity: 1;
	visibility: visible;
}

.hero-slide a {
	display: block;
	width: 100%;
	height: 100%;
}

.hero-slide img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.hero-slideshow-nav {
	position: absolute;
	top: 50%;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	transform: translateY(-50%);
	border: 0;
	border-radius: 50%;
	background-color: rgba(74, 74, 74, 0.35);
	color: #FFFFFF;
	font-size: 24px;
	line-height: 1;
	cursor: pointer;
}

.hero-slideshow-prev {
	left: var(--sda-space-3);
}

.hero-slideshow-next {
	right: var(--sda-space-3);
}

.hero-slideshow-nav:hover,
.hero-slideshow-nav:focus {
	/* Same accent-light hover convention as .main-navigation a — see
	   --sda-color-accent-light token comment. */
	color: var(--sda-color-accent-light);
}

/* Sparse-data state: no featured_hero project has a Primary Project Image
   set yet (expected before Phase 4 content migration) — an honest message
   instead of an empty/broken-looking carousel. */
.hero-slideshow-empty {
	margin: 0;
	padding: var(--sda-space-6) var(--sda-space-3);
	text-align: center;
	color: var(--sda-color-ink);
}

@media (max-width: 768px) {
	.hero-slideshow {
		aspect-ratio: 4 / 5;
	}
}

/* ==========================================================================
   About page (page-about.php)

   Mission text block, pull-quote testimonial, and two-column "Selected
   Clients" list per DESIGN.md `components.about-page`. Body copy inside
   .about-mission inherits the sitewide body typography already set on the
   `body`/`p` selectors above — no duplicate font rules needed here. Reuses
   .content-width/.page-title and the existing color/typography/spacing
   tokens; no new tokens added.
   ========================================================================== */
.about-page {
	padding-top: var(--sda-space-4);
	padding-bottom: var(--sda-space-6);
}

.about-header {
	margin-bottom: var(--sda-space-4);
}

.about-hero {
	margin-bottom: var(--sda-space-5);
}

/* Aspect ratio measured directly from the live site's hero photo
   (2026-08-06, ~956x380 rendered at 1280px viewport ≈ 5:2). Ivan supplies
   the real photo later via the Page's featured image; this ratio just
   reserves the right shape so the layout doesn't jump when it's added. */
.about-hero-image {
	display: block;
	width: 100%;
	aspect-ratio: 5 / 2;
	object-fit: cover;
}

.about-hero-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	aspect-ratio: 5 / 2;
	padding: var(--sda-space-3);
	border: 1px dashed rgba(74, 74, 74, 0.3);
	background-color: rgba(74, 74, 74, 0.05);
	text-align: center;
	font-family: var(--sda-font-family-base);
	font-size: var(--sda-body-font-size);
	color: var(--sda-color-ink);
	opacity: 0.6;
}

.about-mission {
	margin-bottom: var(--sda-space-6);
}

/* Two-column mission layout, measured from the live site 2026-08-06: a
   ~1:2 column-width split (left/right), both columns bottom-aligned
   (align-items: flex-end) rather than top-aligned — the right column's
   font-size below is deliberately smaller than the sitewide body default
   so its extra paragraph count still ends at roughly the same baseline as
   the shorter, larger-type left column, matching the live layout. Stacks
   to one column under 600px, same breakpoint as .about-clients-list. */
.about-mission-columns {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: var(--sda-space-5);
}

.about-mission-intro {
	flex: 1 1 280px;
}

.about-mission-intro p {
	margin: 0;
	font-family: var(--sda-font-family-base);
	font-size: 26px;
	font-weight: 300;
	line-height: 1.5;
	color: var(--sda-color-ink);
}

.about-mission-body {
	flex: 2 1 480px;
}

.about-mission-body p {
	margin: 0 0 var(--sda-space-3);
	font-family: var(--sda-font-family-base);
	font-size: 16px;
	font-weight: var(--sda-body-font-weight);
	line-height: 1.6;
	color: var(--sda-color-ink);
}

.about-mission-body > :last-child,
.about-mission-body p:last-child {
	margin-bottom: 0;
}

@media (max-width: 600px) {
	.about-mission-columns {
		align-items: flex-start;
	}
}

.about-mission-placeholder {
	font-style: italic;
	color: var(--sda-color-ink);
	opacity: 0.6;
}

.about-testimonial-wrap {
	margin-bottom: var(--sda-space-6);
}

/* Rebuilt 2026-08-06 to match the live site's actual quote-block layout
   (DOM-measured, not the earlier left-rule/italic guess): centered text in
   a narrower column, a large decorative opening quotation mark on its own
   line above it, and a muted (not accent-colored, not uppercase)
   attribution line below. The 760px max-width and 64px/14px sizes are the
   live site's measured values (blockquote/figcaption width at 1280px
   viewport; the big mark's font-size). The live site's own big quote mark
   renders at the same ink color as the body text — same value used here
   (--sda-color-meta) reads visually closer to the screenshot's clearly
   lighter mark than that literal color would, since a solid color swap is
   simpler and more reliable than relying on "thin glyph at 64px looks
   lighter" to reproduce itself in a different font (Nunito Sans vs Proxima
   Nova). */
.about-testimonial {
	max-width: 760px;
	margin: 0 auto;
	padding: 0;
	text-align: center;
}

.about-testimonial-mark {
	display: block;
	margin: 0 0 var(--sda-space-1);
	font-family: var(--sda-font-family-base);
	font-size: 64px;
	line-height: 1;
	color: var(--sda-color-meta);
}

.about-testimonial-text {
	margin: 0 0 var(--sda-space-2);
	font-family: var(--sda-font-family-base);
	font-size: var(--sda-body-font-size);
	font-weight: var(--sda-body-font-weight);
	font-style: normal;
	line-height: var(--sda-body-line-height);
	color: var(--sda-color-ink);
}

.about-testimonial-cite {
	display: block;
	font-family: var(--sda-font-family-base);
	font-size: 14px;
	font-weight: 400;
	font-style: normal;
	color: var(--sda-color-meta);
}

.about-clients {
	margin-bottom: var(--sda-space-4);
}

/* Three columns per Ivan's direct request 2026-08-06 (was two) — the
   ~26-name list reads better split three ways at desktop widths. */
.about-clients-list {
	margin: 0;
	padding: 0;
	list-style: none;
	column-count: 3;
	column-gap: var(--sda-space-5);
}

.about-clients-list li {
	margin: 0 0 var(--sda-space-2);
	break-inside: avoid;
}

@media (max-width: 768px) {
	.about-clients-list {
		column-count: 2;
	}
}

@media (max-width: 600px) {
	.about-clients-list {
		column-count: 1;
	}
}

/* ==========================================================================
   Privacy Policy page (page-privacy-policy.php)

   Added 2026-08-06. Legal document layout DOM-measured from the live site:
   the top page heading uses this theme's usual all-caps .page-title, but
   the two content-level section headings ("Privacy Policy"/"Terms of
   Service") are deliberately quieter — 26px/300, real Title Case, no
   text-transform — a distinct tier the live site itself only uses here.
   The 8 numbered subsection headings (26px/300 -> 16px/600, one size down)
   are typed as real uppercase content in the CMS rather than CSS
   text-transform, matching every other heading tier on this site.
   ========================================================================== */
.privacy-policy-page {
	padding-top: var(--sda-space-4);
	padding-bottom: var(--sda-space-6);
}

.privacy-header {
	margin-bottom: var(--sda-space-4);
}

.legal-content h2 {
	margin: 0 0 var(--sda-space-3);
	font-family: var(--sda-font-family-base);
	font-size: 26px;
	font-weight: 300;
	line-height: 1.5;
	color: var(--sda-color-ink);
}

.legal-content h2:not(:first-child) {
	margin-top: var(--sda-space-6);
}

.legal-content h3 {
	margin: 0 0 var(--sda-space-2);
	font-family: var(--sda-font-family-base);
	font-size: 16px;
	font-weight: 700;
	color: var(--sda-color-ink);
}

.legal-content p,
.legal-content li {
	margin: 0 0 var(--sda-space-3);
	font-family: var(--sda-font-family-base);
	font-size: var(--sda-body-font-size);
	font-weight: var(--sda-body-font-weight);
	line-height: var(--sda-body-line-height);
	color: var(--sda-color-ink);
}

.legal-content ul {
	margin: 0 0 var(--sda-space-3);
	padding-left: var(--sda-space-3);
}

.legal-content ul li {
	margin-bottom: var(--sda-space-1);
}

/* The Terms of Service subsections (1-8) render inside a native Gutenberg
   Group block carrying this class — Ivan's ask, two columns rather than
   the live site's single column. break-after on the heading plus
   break-inside on paragraphs/lists keeps each numbered subsection intact
   across the column break (no reliable CSS way to hard-bind a heading to
   its following sibling in a multi-column layout otherwise, short of
   wrapping every subsection in its own nested block). */
.legal-terms-columns {
	column-count: 2;
	column-gap: var(--sda-space-5);
}

.legal-terms-columns h3 {
	break-after: avoid-column;
}

.legal-terms-columns p,
.legal-terms-columns ul {
	break-inside: avoid-column;
}

@media (max-width: 768px) {
	.legal-terms-columns {
		column-count: 1;
	}
}

/* ==========================================================================
   Projects hub (page-projects.php)

   8-tile category grid per DESIGN.md `components.project-category-hub`:
   image + label per tile, linking to that category's term archive. Reuses
   .content-width/.page-title and the existing color/typography/spacing
   tokens; no new tokens added. Tile label is an overlay caption on the tile
   image — identical treatment to .term-projects-tile-caption on
   taxonomy-project_category.php (dark scrim band, 14px/700 bold, white
   text, 7px/14px padding) — corrected 2026-07-30 from a separate
   nav-link-styled line sitting below the image, per Ivan's review of the
   built page against that other template's already-matching pattern. The
   label text itself is already uppercase real content (term name), so no
   CSS text-transform is applied here; see page-projects.php's file header
   comment on term name output. Hover/focus still shifts the tile link to
   --sda-color-accent-light, the same convention used on .main-navigation a,
   .hero-slideshow-nav, and
   .term-projects-tile-link:hover/:focus above/below — accent-light teal
   reads fine against the dark scrim, so this pass kept it rather than
   introducing a different hover treatment than the sibling template uses.
   ========================================================================== */
.page-projects {
	padding-top: var(--sda-space-4);
	padding-bottom: var(--sda-space-6);
}

.page-projects-header {
	margin-bottom: var(--sda-space-4);
}

.project-category-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: var(--sda-space-3);
	margin: 0;
	padding: 0;
	list-style: none;
}

.project-category-tile-link {
	display: block;
	text-decoration: none;
}

.project-category-tile-link:hover,
.project-category-tile-link:focus {
	color: var(--sda-color-accent-light);
}

.project-category-tile-link:hover .project-category-tile-label,
.project-category-tile-link:focus .project-category-tile-label {
	color: var(--sda-color-accent-light);
}

.project-category-tile-image {
	display: block;
	position: relative;
	aspect-ratio: 1 / 1;
	background-color: rgba(74, 74, 74, 0.05);
	overflow: hidden;
}

.project-category-tile-img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Sparse-data state: no category has a tile image set yet (expected before
   Phase 4 content migration) — a clearly-labeled placeholder instead of a
   broken <img> or a plain text-only link. */
.project-category-tile-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	padding: var(--sda-space-2);
	border: 1px dashed rgba(74, 74, 74, 0.3);
	text-align: center;
	font-family: var(--sda-font-family-base);
	font-size: 13px;
	font-weight: 400;
	color: var(--sda-color-ink);
	opacity: 0.6;
}

.project-category-tile-label {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	padding: 7px 14px;
	background: rgba(0, 0, 0, 0.6);
	font-family: var(--sda-font-family-base);
	font-size: 14px;
	font-weight: 700;
	color: #FFFFFF;
}

@media (max-width: 768px) {
	.project-category-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

/* ==========================================================================
   Project Category archive (taxonomy-project_category.php)

   Sibling sub-nav + linked image grid per DESIGN.md
   `components.project-category-linked` — one template for all 8
   categories, not a lightbox-only variant. Reuses .content-width/.page-title
   and the existing color/typography/spacing tokens; no new tokens added.

   Classes are prefixed `term-projects-*`, deliberately NOT
   `project-category-*` — that prefix belongs to the Projects hub's
   *category* tiles directly above (page-projects.php). Reusing it here for
   *project* tiles within a category would collide in this shared
   stylesheet and corrupt both templates' styling. See
   taxonomy-project_category.php's file header comment.
   ========================================================================== */
.taxonomy-project-category {
	padding-top: var(--sda-space-4);
	padding-bottom: var(--sda-space-6);
}

.term-projects-header {
	margin-bottom: var(--sda-space-4);
}

.term-projects-layout {
	display: flex;
	align-items: flex-start;
	gap: var(--sda-space-5);
}

.term-projects-siblings {
	flex: 0 0 220px;
}

.term-projects-sibling-list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.term-projects-sibling-list li {
	margin-bottom: var(--sda-space-2);
	font-size: var(--sda-body-font-size);
	line-height: var(--sda-body-line-height);
}

.term-projects-sibling-list a {
	color: var(--sda-color-accent);
	text-decoration: none;
}

.term-projects-sibling-list a:hover,
.term-projects-sibling-list a:focus {
	text-decoration: underline;
	opacity: 0.75;
}

.term-projects-main {
	flex: 1 1 auto;
	min-width: 0;
}

.term-projects-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--sda-space-3);
	margin: 0;
	padding: 0;
	list-style: none;
}

.term-projects-tile-link {
	display: block;
	/* Button-element reset. A no-op on this template's own <a> tiles
	   (anchors carry none of these by default) — added so the lightbox
	   variant's <button> tiles (taxonomy-project_category-retail.php /
	   -patios.php, which have no page to link to) render identically
	   instead of picking up the browser's default button chrome. Shared
	   here rather than forked into a second rule, since both tag types end
	   up wanting the exact same box. */
	width: 100%;
	border: 0;
	padding: 0;
	background: none;
	font: inherit;
	text-align: left;
	cursor: pointer;
}

.term-projects-tile-link:hover,
.term-projects-tile-link:focus {
	/* Same accent-light hover convention as .main-navigation a (see
	   --sda-color-accent-light token comment). */
	color: var(--sda-color-accent-light);
}

.term-projects-tile-link:hover .term-projects-tile-caption,
.term-projects-tile-link:focus .term-projects-tile-caption {
	color: var(--sda-color-accent-light);
}

/* 1:1 square — confirmed against live site (stanforddowney.ca/residential-projects)
   via direct tile measurement at 1280px viewport: 309×309px per tile.
   2026-07-30 confirmed; do not revert. */
.term-projects-tile-image {
	display: block;
	position: relative;
	aspect-ratio: 1 / 1;
	background-color: rgba(74, 74, 74, 0.05);
	overflow: hidden;
}

.term-projects-tile-img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Overlay caption — exact measured values from live site (solid
   rgba(0,0,0,0.6) band, 14px/700 bold, 7px/14px padding — confirmed via
   computed-style measurement 2026-07-30). Replaces the visible
   .term-projects-siblings list (now hidden via .screen-reader-text, see
   taxonomy-project_category.php) with the project title overlaid at the
   bottom of each tile's image, matching the live site's actual
   .image-slide-title behavior (position: absolute; bottom: 0 inside the
   image wrapper) — confirmed against the live site's rendered DOM, not
   just DESIGN.md's original "sub-nav" note, which described DOM presence
   rather than visual layout. .term-projects-tile-image (not the <a>) is
   the positioning context, so the caption clips to the same box as the
   photo/placeholder above it. Dark scrim + white text keeps the caption
   legible over arbitrary photography without introducing new color —
   restrained per DESIGN.md's near-monochrome direction, no accent color
   used. */
.term-projects-tile-caption {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	padding: 7px 14px;
	background: rgba(0, 0, 0, 0.6);
	font-family: var(--sda-font-family-base);
	font-size: 14px;
	font-weight: 700;
	line-height: 1.4;
	color: #FFFFFF;
}

/* Sparse-data state: no project has a Primary Project Image set yet outside
   the schema test project (expected before Phase 4 content migration) — a
   clearly-labeled placeholder instead of a broken <img>. */
.term-projects-tile-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	padding: var(--sda-space-2);
	border: 1px dashed rgba(74, 74, 74, 0.3);
	text-align: center;
	font-family: var(--sda-font-family-base);
	font-size: 13px;
	font-weight: 400;
	color: var(--sda-color-ink);
	opacity: 0.6;
}

/* Empty-category state (7 of 8 categories until Phase 4 content migration)
   — same convention as .hero-slideshow-empty. */
.term-projects-empty {
	margin: 0;
	color: var(--sda-color-ink);
}

@media (max-width: 768px) {
	.term-projects-layout {
		flex-direction: column;
	}

	/* `.term-projects-siblings { flex: none; width: 100%; }` used to live here
	   and was deleted by the Phase 5 fe-review sweep (DET-18 / checklist 8).
	   It was a leftover from before the 2026-07-30 correction that made the
	   sibling nav `.screen-reader-text`: because it sits later in the file
	   than the `.screen-reader-text` rule and carries equal specificity, its
	   `width: 100%` beat that rule's `width: 1px`, inflating the (still
	   absolutely-positioned) hidden nav to full viewport width at its ~23px
	   static offset. That pushed scrollWidth 23px past the viewport and put a
	   horizontal scrollbar on all four category archives at 375px and 768px
	   (measured 398 > 375 and 791 > 768). The nav is visually hidden, so it
	   has no mobile layout to describe — the rule had nothing left to do. */
	.term-projects-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

/* ==========================================================================
   Project Category lightbox archive
   (taxonomy-project_category-retail.php / taxonomy-project_category-patios.php)

   Per DESIGN.md `components.project-category-lightbox` — reuses every
   `.term-projects-*` class/token above unchanged (identical header/layout/
   grid/tile/caption markup, just <button> tiles instead of <a> tiles; see
   `.term-projects-tile-link`'s comment above for the shared button reset).
   This block adds only what's genuinely new: the lightbox/modal itself.
   ========================================================================== */
.term-projects-lightbox {
	position: fixed;
	inset: 0;
	z-index: 1000; /* above .site-header's z-index: 999 */
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--sda-space-3);
}

.term-projects-lightbox[hidden] {
	display: none;
}

.term-projects-lightbox-backdrop {
	position: absolute;
	inset: 0;
	background: rgba(0, 0, 0, 0.85);
}

.term-projects-lightbox-close {
	position: absolute;
	top: var(--sda-space-3);
	right: var(--sda-space-3);
	z-index: 2;
	border: 0;
	background: none;
	padding: var(--sda-space-1) var(--sda-space-2);
	font-size: 28px;
	line-height: 1;
	color: #FFFFFF;
	cursor: pointer;
}

.term-projects-lightbox-dialog {
	position: relative;
	z-index: 1;
	max-width: min(90vw, 1020px);
	max-height: 90vh;
	display: flex;
	flex-direction: column;
	align-items: center;
}

.term-projects-lightbox-image {
	display: block;
	max-width: 100%;
	max-height: 80vh;
	object-fit: contain;
}

.term-projects-lightbox-caption {
	margin: var(--sda-space-2) 0 0;
	font-family: var(--sda-font-family-base);
	font-size: var(--sda-body-font-size);
	font-weight: 700;
	color: #FFFFFF;
	text-align: center;
}

/* Prevents background scroll behind the modal while it's open — the tile
   grid extends well past the viewport, so without this an open lightbox
   would still let the page scroll underneath it. */
body.term-projects-lightbox-open {
	overflow: hidden;
}

/* ==========================================================================
   Project Detail (single-project.php)

   Sibling sidebar + Prev/Next nav (top & bottom) + meta row (inline SVG
   icons) + image gallery per DESIGN.md `components.project-detail`. Reuses
   .content-width/.page-title and the existing color/typography/spacing
   tokens; no new tokens added.

   Classes are prefixed `single-project-*`, deliberately distinct from both
   `project-category-*` (page-projects.php's hub tiles) and `term-projects-*`
   (taxonomy-project_category.php's archive sibling list/grid) — three
   templates share this stylesheet and each needs its own namespace to avoid
   collisions. .single-project-siblings/.single-project-sibling-list mirror
   .term-projects-siblings/.term-projects-sibling-list's layout on purpose
   (same sibling-list concept, reused per single-project.php's file header
   comment) but stay in their own prefix rather than sharing selectors.
   ========================================================================== */
/* Correction: top padding bumped from --sda-space-4 (32px, the shared
   convention every other single-*-page.php-style template uses for its
   first element) to --sda-space-6 (64px) — matching the padding-bottom
   already on this same rule. Root cause of the "cramped against the
   header" report: 32px reads fine on every other template because their
   first element below the header is a text heading (line-height gives it
   perceived breathing room); here the first element is
   .single-project-header's solid rgb(39,39,39) button row — a heavy
   graphic bar directly under the fixed header's own bar, which read as
   touching/crowded at the site-wide 32px offset. That exact same button
   row repeats at the bottom of the page and already gets 64px of
   clearance via padding-bottom below; matching the top offset to it
   gives the nav row symmetric, comfortable spacing in both places rather
   than guessing a value. Header height/body push (var(--sda-header-height-desktop),
   applied as body's padding-top) already fully clears the fixed header —
   this token governs the gap *below* that, not header overlap. */
.single-project {
	padding-top: var(--sda-space-6);
	padding-bottom: var(--sda-space-6);
}

.single-project-header {
	margin-bottom: var(--sda-space-4);
}

/* Live-site title tier (DOM-measured 2026-08-06 on two projects): 26px/300,
   natural case — distinct from this theme's bold all-caps .page-title,
   which the live site doesn't use for individual project/post titles
   (matches the 2026-07-30 finding on category-archive/hub headings).

   Correction 2026-08-10: font-weight deliberately overridden from the
   DOM-measured 300 above to 700 (bold), per Ivan's own design call from
   screenshot review of the Niagara Falls Convention Centre page — this is
   NOT a live-site-parity fix and NOT a mistaken revert of the 6cd9456
   measurement. Do not "correct" this back toward 300 in a future pass;
   the live site's real weight is intentionally being overridden here.
   700 matches this theme's existing bold convention (e.g. .page-title's
   --sda-page-title-font-weight, and the literal 700 used by
   .legal-content h3 and other one-off bold headings) rather than
   inventing a new weight value. */
.single-project-title {
	margin: 0 0 var(--sda-space-2);
	font-family: var(--sda-font-family-base);
	font-size: 26px;
	font-weight: 700;
	line-height: 1.5;
	color: var(--sda-color-ink);
}

/* Prev/Next (+ the bottom instance's middle "gallery" button) — rendered
   from the same sda_render_project_prev_next() call in single-project.php
   (top: 2 buttons, bottom: 3), so the two copies always agree on Prev/Next.
   space-between with 2 children naturally pins them to the row's outer
   edges; with 3 it centers the middle one — no extra layout rule needed
   either way. */
.single-project-nav {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--sda-space-2);
	margin-top: var(--sda-space-2);
}

/* Button look DOM-measured 2026-08-06 from the live Aera page's own three
   buttons (Previous/Restaurant Gallery/Next) — exact values: background
   rgb(39,39,39), white text, 12px/600, 1px letter-spacing, 13px/26px
   padding, sharp corners (border-radius measured as 0, not rounded).
   Label text is typed as real uppercase content in the template rather
   than relying on text-transform, per this theme's standing accessibility
   preference — no text-transform rule here. */
.single-project-nav-link {
	display: inline-block;
	padding: 13px 26px;
	background-color: rgb(39, 39, 39);
	font-family: var(--sda-font-family-base);
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 1px;
	color: #FFFFFF;
	text-align: center;
	text-decoration: none;
}

.single-project-nav-prev:hover,
.single-project-nav-prev:focus,
.single-project-nav-gallery:hover,
.single-project-nav-gallery:focus,
.single-project-nav-next:hover,
.single-project-nav-next:focus {
	/* Same accent-light hover convention as .main-navigation a, repurposed
	   as a background tint since this is a solid button, not a text link —
	   white text keeps sufficient contrast against this color too. */
	background-color: var(--sda-color-accent-light);
}

/* First/last project in a category has no Previous/Next — a disabled
   button, not a broken/dead link. Same shape/size as the real buttons,
   just visually muted. */
.single-project-nav-disabled {
	background-color: rgba(39, 39, 39, 0.35);
}

/* Sibling list: kept as real DOM/markup (internal linking, a11y, crawlers)
   but visually hidden — the live site's own sibling nav is DOM-present and
   offsetParent-null, confirmed 2026-08-06, same pattern already applied to
   taxonomy-project_category.php's .term-projects-siblings on 2026-07-30. */
.single-project-sibling-list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.single-project-sibling-list a {
	color: var(--sda-color-accent);
	text-decoration: none;
}

.single-project-sibling-list a:hover,
.single-project-sibling-list a:focus {
	text-decoration: underline;
	opacity: 0.75;
}

/* Current project bolded/highlighted per DESIGN.md `components.project-detail`
   ("current project bolded/implied by URL"); rendered as non-link text with
   aria-current="page" rather than a self-link. Kept even though the nav
   itself is hidden — still meaningful to a screen reader/crawler reading
   the hidden list. */
.single-project-sibling-current {
	font-weight: 600;
	color: var(--sda-color-ink);
}

/* Title + meta (left) / hero image (right) row — DOM-measured 2026-08-06
   from the live Aera project page: a ~1:2 column-width row (330:660 at
   1280px viewport), same ratio and flex technique as the About page's
   .about-mission-columns.
   align-items: stretch (flex's own default, so left un-set rather than
   declared) makes both columns take the row's tallest hypothetical
   cross-size — see .single-project-hero-img below for how that height
   is now kept from being driven by the image itself. */
.single-project-layout {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sda-space-5);
	margin-bottom: var(--sda-space-5);
}

.single-project-info {
	flex: 1 1 280px;
}

/* position: relative establishes the containing block for the
   absolutely-positioned .single-project-hero-img below. */
.single-project-hero {
	position: relative;
	flex: 2 1 480px;
}

/* Correction 2026-08-10 — replaces the align-items: stretch +
   height: 100% technique from the c31e07e correction above, which its
   own follow-up note diagnosed as broken: a flex item's percentage-
   height descendant can't resolve during the browser's "hypothetical
   cross size" pass, because the row's own height is still auto at that
   point — so the browser fell back to the image's intrinsic
   aspect-ratio height for that pass instead. For a portrait image that
   becomes the row's cross size outright, and stretch then just handed
   that same image-driven height back to both columns (confirmed via
   real DOM measurement: Aera, landscape, computed all three boxes to
   an identical 393.375px by coincidence; Bridgette Bar, portrait,
   computed all three to 882.9px, with the image showing essentially
   uncropped and a dead gap under .single-project-info's shorter
   content).
   Fix: take the image out of flow with position: absolute, so it
   contributes nothing to .single-project-hero's flex hypothetical
   cross-size calculation — that pass now sees an empty box
   (hypothetical size 0), so the row's cross size ends up driven purely
   by .single-project-info's own content height, never by the image's
   aspect ratio. inset: 0 + width/height: 100% then re-expands the
   (now out-of-flow) image to fill whatever height that resolves to,
   and object-fit: cover crops to match without distorting — same
   guarantee cover always gave, just no longer circular. */
.single-project-hero-img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* NOT given the position: absolute treatment above — confirmed, not
   assumed. Unlike .single-project-hero-img, this is a plain <div> with
   no intrinsic aspect ratio of its own: when its height: 100% can't
   resolve during that same pre-stretch hypothetical-size pass, a
   non-replaced element's percentage height falls back to auto
   (shrink-to-fit its own text + padding), never to an image-shaped
   size, so it was never able to inflate the row the way the <img> did.
   It stays in-flow and gets the same ordinary stretch-to-fill once the
   row's real height (driven by .single-project-info) resolves. */
.single-project-hero-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	padding: var(--sda-space-3);
	border: 1px dashed rgba(74, 74, 74, 0.3);
	background-color: rgba(74, 74, 74, 0.05);
	text-align: center;
	font-family: var(--sda-font-family-base);
	font-size: var(--sda-body-font-size);
	color: var(--sda-color-ink);
	opacity: 0.6;
}

.single-project-meta {
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Correction 2026-08-10: align-items changed from center to flex-start —
   center was vertically centering the icon against the WHOLE row
   (including wrapped 2-line values like a long Location address), which
   reads as the icon floating low relative to where the first line of text
   actually starts. flex-start pins the icon and the text's line box to
   the same cross-start edge instead. See .single-project-meta-icon below
   for the small optical correction this alone doesn't cover. */
.single-project-meta-row {
	display: flex;
	align-items: flex-start;
	gap: var(--sda-space-2);
	margin-bottom: var(--sda-space-2);
}

/* margin-top: 3px is an optical correction layered on top of the
   align-items: flex-start above, not a replacement for it. Box-model
   math (.single-project-meta-text uses --sda-body-font-size: 17px and
   --sda-body-line-height: 27.2px):
     - leading = line-height - font-size = 27.2 - 17 = 10.2px
     - half-leading (space above the glyphs within the line box, before
       the first line's visible cap-height actually starts) = 10.2 / 2
       = 5.1px
     - this icon box is 24x24 with align-items/justify-content: center
       centering the 20x20 svg inside it, so the svg's own visible top
       already sits (24 - 20) / 2 = 2px below the icon box's top edge
   With flex-start, the icon box's top edge and the text's line-box top
   edge land on the same line — but the text's visible cap-height starts
   ~5.1px below that shared edge, while the icon's visible svg glyph
   starts only ~2px below it. That's a ~3.1px (5.1 - 2) gap, i.e. the
   icon reads slightly high relative to the first line's actual glyphs.
   Rounded to 3px and applied as margin-top here so the icon's visible
   svg lines up with the first line's cap-height instead of the top of
   its full (possibly 2-line) line box. */
.single-project-meta-icon {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 24px;
	height: 24px;
	margin-top: 3px;
	color: var(--sda-color-accent);
}

.single-project-meta-icon svg {
	width: 20px;
	height: 20px;
}

.single-project-meta-text {
	font-size: var(--sda-body-font-size);
	line-height: var(--sda-body-line-height);
	/* Correction 2026-08-10: switched back to --sda-color-ink (#4A4A4A,
	   the sitewide primary body-copy token), reversing the 2026-07-30
	   change to --sda-color-meta (#9E9E9E) noted below. Per Ivan's
	   screenshot review, this template's meta list isn't secondary
	   supporting text the way dates/bylines/tags are elsewhere — it's
	   the page's actual content (Location, Size, Architect, Photographer)
	   and reads too light at the meta-gray value. --sda-color-ink is the
	   existing primary body-copy token, not a new one invented for this.
	   Covers both .single-project-meta-label and -value, which don't set
	   their own color and inherit from here.

	   Prior comment, for history: DESIGN.md {colors.meta} — confirmed
	   2026-07-30 "Page Meta Color"; this is the meta row DESIGN.md names
	   directly. Was --sda-color-ink (uniform with body copy) before that
	   correction. */
	color: var(--sda-color-ink);
}

.single-project-meta-label {
	margin-right: 4px;
	font-weight: 700;
}

/* 2 images per row, full content-width (not confined to .single-project-hero's
   column) — DOM-confirmed 2026-08-06 via the live site's own
   sqs-gallery-thumbnails-per-row-2 class on the Aera project page; the old
   3-per-row grid was a guess DESIGN.md never actually specified a count for. */
.single-project-gallery {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--sda-space-3);
	margin: 0 0 var(--sda-space-5);
	padding: 0;
	list-style: none;
}

.single-project-gallery-link {
	display: block;
}

.single-project-gallery-link:hover,
.single-project-gallery-link:focus {
	opacity: 0.75;
}

/* Fixed-ratio crop box — Correction 2026-08-27. The old natural
   height: auto rule (no fixed box) let portrait and landscape photos in
   the same 2-per-row grid render as visibly mismatched tile sizes
   (0.67-2.07 aspect-ratio spread measured within some projects, per the
   project-gallery data-sweep correction task above).

   Checked the live Squarespace site's own sqs-gallery-thumbnails-per-row-2
   galleries directly (Playwright, 8 projects sampled across 5 categories:
   Aera, The Dorset, Pharma Medica Research Centre, Local Leaside, Lulu
   Bar, GlaxoSmithKline, Niagara Falls Convention Centre, Alloa Reservoir
   Pumping Station, JOEY Markville, Bridgette Bar, Lane House, One York
   Quay, RBC Computer and Research Centre, Toronto Community Housing)
   rather than assuming one page generalizes. Result: the live site does
   NOT enforce one sitewide gallery ratio either — it's a per-project
   Squarespace gallery-block setting, confirmed at three distinct fixed
   values across the sample: ~1.48:1 landscape (majority), a 1:1 square
   (JOEY Markville and Bridgette Bar — notably, one of this task's own two
   named test cases), and a ~0.673:1 portrait variant (3 Residential/
   Commercial projects). This theme applies one shared CSS rule across
   every project (no per-project ratio field exists, and adding one is
   out of scope for a sizing-only fix), so there is no single live-
   measured ratio to port here. Falling back instead to this theme's own
   established "mixed native shapes, one uniform grid" convention:
   aspect-ratio: 1/1 + object-fit: cover, the same technique already
   proven on .term-projects-tile-image (taxonomy-project_category.php),
   confirmed against the live site 2026-07-30 for that identical problem.

   .single-project-gallery-image is the new positioning/crop box (mirrors
   .term-projects-tile-image's <span> wrapper in the PHP template); the
   <img> itself just fills it — same img/wrapper split, same class-naming
   pattern (-image for the box, -img for the element) used there. */
.single-project-gallery-image {
	display: block;
	position: relative;
	aspect-ratio: 1 / 1;
	background-color: rgba(74, 74, 74, 0.05);
	overflow: hidden;
}

.single-project-gallery-img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Empty-gallery state: no images attached to any project yet (Phase 4
   content migration) — same "coming soon" convention as
   .hero-slideshow-empty/.term-projects-tile-placeholder/etc. */
.single-project-gallery-empty {
	margin: 0;
	color: var(--sda-color-ink);
}

@media (max-width: 768px) {
	.single-project-layout {
		flex-direction: column;
	}

	/* Equal-height crop above is a two-column-row concept — once
	   .single-project-layout stacks to a single column there's no second
	   column to match, so the image goes back to its own natural
	   height: auto instead of the cropped fill from a row that no longer
	   exists. (Prior comment here analogized this to
	   .single-project-gallery-img's own sizing — no longer accurate as of
	   the 2026-08-27 correction above, which gave the gallery a fixed
	   aspect-ratio/object-fit: cover box instead; this hero image is a
	   separate element with its own, still-unfixed-ratio behavior,
	   unaffected by that change.) position: static is required here too, not just
	   height: auto: the desktop rule makes this element position:
	   absolute with inset: 0, and an absolutely-positioned box with top
	   and bottom both pinned to 0 stretches to fill its containing
	   block's height even when its own height is auto — height: auto
	   alone would not have reverted anything. Restoring position: static
	   puts the image back in normal flow, where height: auto sizes it
	   from its own intrinsic aspect ratio again, same as before this
	   template ever used absolute positioning. */
	.single-project-hero-img {
		position: static;
		height: auto;
	}

	/* Placeholder has no intrinsic size of its own the way a real image
	   does, so it can't just fall back to "auto" — restore the original
	   fixed 3:2 photo-shaped box (in place of the desktop row's
	   height: 100% stretch, which would collapse to fit only the
	   placeholder text once its parent is no longer stretched). Never
	   made position: absolute at desktop (see that rule's own comment
	   above), so there's no position to reset here. */
	.single-project-hero-placeholder {
		height: auto;
		aspect-ratio: 3 / 2;
	}

	.single-project-nav {
		flex-wrap: wrap;
	}

	.single-project-gallery {
		grid-template-columns: 1fr;
	}
}

/* ==========================================================================
   News List (home.php)

   Full inline post list (title, date, byline, complete body — not truncated
   excerpts) per DESIGN.md `components.news-list`. Reuses .content-width/
   .page-title and the existing color/typography/spacing tokens; no new
   tokens added.

   Classes are prefixed `news-list-*`, distinct from `project-category-*`
   (page-projects.php), `term-projects-*` (taxonomy-project_category.php),
   and `single-project-*` (single-project.php) — same one-namespace-per-
   template convention this shared stylesheet already follows.

   .news-list-item-body has no font rules of its own: the_content()'s <p>
   tags inherit the sitewide body typography already set on the `body`/`p`
   selectors above, same as .about-mission's convention.
   ========================================================================== */
.news-list {
	padding-top: var(--sda-space-4);
	padding-bottom: var(--sda-space-6);
}

.news-list-header {
	margin-bottom: var(--sda-space-4);
}

.news-list-item {
	padding-bottom: var(--sda-space-5);
	margin-bottom: var(--sda-space-5);
	border-bottom: 1px solid rgba(74, 74, 74, 0.12);
}

.news-list-item:last-child {
	padding-bottom: 0;
	margin-bottom: 0;
	border-bottom: 0;
}

.news-list-item-header {
	margin-bottom: var(--sda-space-2);
}

.news-list-item-title {
	margin: 0 0 var(--sda-space-1);
	font-family: var(--sda-font-family-base);
	font-size: 22px;
	font-weight: 600;
	line-height: 1.3;
}

.news-list-item-title a {
	color: var(--sda-color-ink);
	text-decoration: none;
}

.news-list-item-title a:hover,
.news-list-item-title a:focus {
	color: var(--sda-color-accent);
}

.news-list-item-date,
.news-list-item-byline {
	margin: 0 0 4px;
	font-size: 14px;
	/* DESIGN.md {colors.meta} — confirmed 2026-07-30 "Page Meta Color".
	   Replaces the earlier ink+opacity approximation now that a real
	   confirmed meta color token exists. */
	color: var(--sda-color-meta);
}

.news-list-item-byline:last-child {
	margin-bottom: 0;
}

.news-list-item-author {
	color: var(--sda-color-accent);
	text-decoration: none;
}

.news-list-item-author:hover,
.news-list-item-author:focus {
	text-decoration: underline;
	opacity: 0.75;
}

.news-list-item-body {
	margin-top: var(--sda-space-3);
}

.news-list-item-body > :last-child {
	margin-bottom: 0;
}

.news-list-empty {
	color: var(--sda-color-ink);
}

/* the_posts_pagination() default markup: <nav class="navigation pagination">
   > <h2 class="screen-reader-text"> (already hidden by the sitewide
   .screen-reader-text utility above) + <div class="nav-links"> of
   .page-numbers links/spans. Styled to match the nav-link type token used
   throughout (.main-navigation a, .single-project-nav-link, etc.) rather
   than introducing a new button/link style. */
.news-list-pagination {
	margin-top: var(--sda-space-5);
}

.news-list-pagination .nav-links {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--sda-space-2);
}

.news-list-pagination .page-numbers {
	font-family: var(--sda-font-family-base);
	font-size: var(--sda-nav-link-font-size);
	font-weight: var(--sda-nav-link-font-weight);
	letter-spacing: var(--sda-nav-link-letter-spacing);
	text-transform: uppercase;
	color: var(--sda-color-accent);
	text-decoration: none;
}

.news-list-pagination a.page-numbers:hover,
.news-list-pagination a.page-numbers:focus {
	/* Same accent-light hover convention as .main-navigation a — see
	   --sda-color-accent-light token comment. */
	color: var(--sda-color-accent-light);
}

.news-list-pagination .page-numbers.current {
	color: var(--sda-color-ink);
	opacity: 0.5;
}

.news-list-pagination .page-numbers.dots {
	color: var(--sda-color-ink);
	opacity: 0.5;
}

/* ==========================================================================
   News Post (single.php)

   Article view per DESIGN.md `components.news-post`: byline, date, title,
   full body, tag list, Older/Newer post navigation. Reuses .content-width/
   .page-title and the existing color/typography/spacing tokens; no new
   tokens added.

   Classes are prefixed `single-news-*`, distinct from `news-list-*`
   (home.php) even though both templates share the byline/date visual
   pattern — same one-namespace-per-template convention this shared
   stylesheet already follows.

   .single-news-body has no font rules of its own, same reasoning as
   .news-list-item-body: the_content()'s <p> tags inherit the sitewide
   body typography already set on the `body`/`p` selectors above.

   .post-navigation/.nav-links/.nav-previous/.nav-next/.screen-reader-text
   below are WordPress core's own the_post_navigation() markup (unprefixed,
   un-namespaced) — styled directly rather than reproduced under a
   single-news-* class, same approach news-list-pagination above takes with
   the_posts_pagination()'s core `.page-numbers` markup. This is the only
   template on the site that calls the_post_navigation(), so there's no
   collision risk.
   ========================================================================== */
.single-news {
	padding-top: var(--sda-space-4);
	padding-bottom: var(--sda-space-6);
}

.single-news-header {
	margin-bottom: var(--sda-space-4);
}

.single-news-date,
.single-news-byline {
	margin: 0 0 4px;
	font-size: 14px;
	/* DESIGN.md {colors.meta} — confirmed 2026-07-30 "Page Meta Color".
	   Replaces the earlier ink+opacity approximation now that a real
	   confirmed meta color token exists. */
	color: var(--sda-color-meta);
}

.single-news-byline:last-child {
	margin-bottom: 0;
}

.single-news-author {
	color: var(--sda-color-accent);
	text-decoration: none;
}

.single-news-author:hover,
.single-news-author:focus {
	text-decoration: underline;
	opacity: 0.75;
}

.single-news-body > :last-child {
	margin-bottom: 0;
}

.single-news-tags-wrap {
	margin-top: var(--sda-space-4);
}

.single-news-tags {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sda-space-1);
	list-style: none;
	margin: 0;
	padding: 0;
}

.single-news-tag a {
	display: inline-block;
	padding: 4px 12px;
	border: 1px solid rgba(74, 74, 74, 0.25);
	border-radius: 999px;
	font-size: 13px;
	/* DESIGN.md {colors.meta} — confirmed 2026-07-30 "Page Meta Color",
	   named explicitly alongside dates/bylines/tags. Was accent before
	   this correction; the hover fill below still uses accent
	   intentionally (an interactive state, not resting supporting text). */
	color: var(--sda-color-meta);
	text-decoration: none;
}

.single-news-tag a:hover,
.single-news-tag a:focus {
	background-color: var(--sda-color-accent);
	border-color: var(--sda-color-accent);
	color: var(--sda-color-page-bg);
}

.single-news-nav-wrap {
	margin-top: var(--sda-space-5);
}

.post-navigation .nav-links {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--sda-space-2);
}

.post-navigation .nav-previous a,
.post-navigation .nav-next a {
	font-family: var(--sda-font-family-base);
	font-size: var(--sda-nav-link-font-size);
	font-weight: var(--sda-nav-link-font-weight);
	letter-spacing: var(--sda-nav-link-letter-spacing);
	text-transform: uppercase;
	color: var(--sda-color-accent);
	text-decoration: none;
}

.post-navigation .nav-previous a:hover,
.post-navigation .nav-previous a:focus,
.post-navigation .nav-next a:hover,
.post-navigation .nav-next a:focus {
	/* Same accent-light hover convention as .main-navigation a — see
	   --sda-color-accent-light token comment. */
	color: var(--sda-color-accent-light);
}

/* ==========================================================================
   Contact page (page-contact.php)

   Rebuilt 2026-08-06 against the live site's actual rendered DOM (see
   page-contact.php's file header comment for the full audit). Real layout:
   a two-column row — square map image (~5/12) beside firm-name/address/
   phone/email text (~7/12) — stacking to one column at its own 768px
   breakpoint. Not tied to header.php's nav-toggle breakpoint, which the
   2026-08-27 Phase 5 correction split into 999px (nav collapse) / 640px
   (header height) — this rule's 768px is independent and unaffected.
   Reuses .content-width/.page-title and the existing color/typography/
   spacing tokens; no new tokens added.
   ========================================================================== */
.contact-page {
	padding-top: var(--sda-space-4);
	padding-bottom: var(--sda-space-6);
}

.contact-header {
	/* Reduced from --sda-space-5 (48px) 2026-08-06 per Ivan's review — the
	   original value left too much visual gap between "CONTACT" and the
	   map/text row below it. */
	margin-bottom: var(--sda-space-3);
}

.contact-layout {
	display: flex;
	align-items: flex-start;
	/* Reduced from --sda-space-5 2026-08-06, same "too much space" review —
	   also widens .contact-info-col in practice, which is what let
	   .contact-firm-name fit on one line below without wrapping. */
	gap: var(--sda-space-4);
}

.contact-map-col {
	flex: 0 0 auto;
	/* 2026-08-06, second pass: 30% (from the live site's original 41.6%)
	   fixed the .contact-firm-name wrap, but over-corrected — it widened
	   .contact-info-col enough that its short lines (address, "Tel: ...",
	   "General Inquiries") left visible dead space at the column's right
	   edge (.contact-info-col has left padding but no matching right
	   padding/max-width), reading as "everything shifted left." 36% is a
	   middle ground: bigger map per Ivan's review, and a narrower
	   .contact-info-col (flex: 1 1 0 — it just takes whatever width is
	   left) that keeps the text closer to the map instead of sprawling.
	   Still comfortably wide enough at --sda-content-max-width for
	   .contact-firm-name to stay on one line — verified by the same
	   character-width math as the first pass, with more margin this time. */
	width: 36%;
}

.contact-map-link {
	display: block;
	aspect-ratio: 1 / 1; /* confirmed square on the live site at both desktop and mobile widths */
	overflow: hidden;
	border: 2.7px solid var(--sda-color-ink-strong);
}

.contact-map-img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.contact-map-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	padding: var(--sda-space-2);
	text-align: center;
	font-family: var(--sda-font-family-base);
	font-size: var(--sda-body-font-size);
	line-height: var(--sda-body-line-height);
	color: var(--sda-color-meta);
}

.contact-info-col {
	flex: 1 1 0;
	padding-left: var(--sda-space-4); /* echoes the live page's ~40px text indent, measured 2026-08-06 */
}

.contact-firm-name,
.contact-email-heading {
	/* One-off size reduction from .page-title's inherited 26px, 2026-08-06 —
	   .contact-firm-name needed it to fit "STANFORD DOWNEY ARCHITECTS INC."
	   on one line (the only heading on the site long enough to need it, so
	   not promoted to a new token); .contact-email-heading ("EMAIL") didn't
	   need it but is set to match per Ivan's review, so the two headings on
	   this page read as the same visual size instead of EMAIL looking
	   larger next to the firm name. */
	font-size: 22px;
}

.contact-firm-name {
	margin-top: 0;
}

.contact-address,
.contact-phone-line {
	margin: 0 0 var(--sda-space-2);
	font-family: var(--sda-font-family-base);
	font-style: normal;
	font-size: var(--sda-body-font-size);
	line-height: var(--sda-body-line-height);
	color: var(--sda-color-ink);
}

/* 26px measured on the live site; snapped to the nearest existing spacing
   token rather than adding a one-off exact-pixel value. */
.contact-email-heading {
	margin-top: var(--sda-space-3);
}

.contact-email-label {
	margin: 0;
	font-family: var(--sda-font-family-base);
	font-size: var(--sda-body-font-size);
	line-height: var(--sda-body-line-height);
	color: var(--sda-color-ink);
}

.contact-link {
	color: var(--sda-color-accent);
	font-family: var(--sda-font-family-base);
	font-size: var(--sda-body-font-size);
	line-height: var(--sda-body-line-height);
	text-decoration: none;
}

.contact-link:hover,
.contact-link:focus {
	/* --sda-color-accent-light token comment (style.css top of file) —
	   confirmed 2026-07-30, applied everywhere else already; this page's
	   link hover was missed in that sweep until now. */
	text-decoration: underline;
	color: var(--sda-color-accent-light);
}

@media (max-width: 768px) {
	.contact-layout {
		flex-direction: column;
	}

	.contact-map-col {
		width: 100%;
	}

	.contact-info-col {
		padding-left: 0;
	}
}
