/* inner-pages.css — inner-page-specific styles for OSTA 2026 */

/* Chapter Portal — a denser workspace treatment for the chapter dashboard.
   Data and navigation remain in template-chapter-portal.php; these rules only
   provide the banner/KPI hierarchy from the portal reference design. */
.chapter-portal {
  display: grid;
  gap: var(--space-3);
}

.chapter-portal__banner {
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
}

.chapter-portal__banner-copy {
  min-width: 0;
}

.chapter-portal__eyebrows {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  margin-bottom: var(--space-1);
}

.chapter-portal__eyebrow,
.chapter-portal__status {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 4px 10px;
  border-radius: var(--radius-sm);
  font-size: var(--text-micro);
  font-weight: var(--weight-bold);
  letter-spacing: .05em;
  text-transform: uppercase;
}

.chapter-portal__eyebrow {
  color: var(--color-brand);
  background: var(--color-brand-wash);
}

.chapter-portal__status {
  color: var(--color-accent-ink);
  background: var(--color-success-wash);
}

.chapter-portal__title {
  margin: 0;
  color: var(--color-brand);
  font-size: clamp(28px, 4vw, 42px);
  line-height: var(--leading-tight);
}

.chapter-portal__description {
  max-width: 720px;
  margin: var(--space-1) 0 0;
  color: var(--color-muted);
}

.chapter-portal__context {
  display: flex;
  flex: 0 0 220px;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  padding: var(--space-2);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  background: var(--color-surface-workspace);
  color: var(--color-muted);
  font-size: var(--text-small);
}

.chapter-portal__context strong {
  color: var(--color-brand);
  font-size: var(--text-h3);
  line-height: var(--leading-tight);
}

.chapter-portal__context-label,
.chapter-portal__kpi-label {
  color: var(--color-muted);
  font-size: var(--text-micro);
  font-weight: var(--weight-bold);
  letter-spacing: .06em;
  text-transform: uppercase;
}

.chapter-portal__kpis {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-2);
}

.chapter-portal__kpi {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 4px;
  padding: var(--space-2);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
  color: var(--color-muted);
  text-decoration: none;
}

a.chapter-portal__kpi:hover {
  border-color: var(--color-brand);
  box-shadow: var(--shadow-hover);
}

.chapter-portal__kpi strong {
  overflow-wrap: anywhere;
  color: var(--color-brand);
  font-size: clamp(24px, 3vw, 34px);
  line-height: var(--leading-tight);
}

.chapter-portal__kpi > span:last-child {
  font-size: var(--text-small);
}

a.chapter-portal__kpi > span:last-child {
  color: var(--color-link);
  text-decoration: underline;
}

@media (max-width: 900px) {
  .chapter-portal__kpis {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 640px) {
  .chapter-portal__banner {
    flex-direction: column;
    padding: var(--space-3);
  }

  .chapter-portal__context {
    flex-basis: auto;
  }

  .chapter-portal__kpis {
    grid-template-columns: 1fr;
  }
}

/* ==========================================================================
   1. MINIMAL TEMPLATE STUBS (404, search, archive) — Pass 18
   Shared base for the plain templates fixed in Pass 18. Scoped to
   .minimal-page only, on purpose: page.php and template-members-only.php
   render #content with no wrapper at all today, and nothing here should
   reach out and restyle them. Tokens only, no new colors or components.
   ========================================================================== */

.minimal-page {
  max-width: var(--measure-max);
  margin: 0 auto;
  padding: var(--space-6) var(--space-3);
}

.minimal-page h1 {
  margin-bottom: var(--space-3);
}

.minimal-page .btn + .btn {
  margin-left: var(--space-2);
}

.minimal-page .locked__label {
  margin-bottom: var(--space-1);
}

/* Search and archive result lists share the same look. */

.search-results,
.archive-list {
  margin: var(--space-4) 0;
}

.search-result,
.archive-item {
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border-soft);
}

.search-result:first-child,
.archive-item:first-child {
  border-top: 1px solid var(--color-border-soft);
}

.search-result__title,
.archive-item__title {
  margin-bottom: var(--space-1);
}

/* Pass 44 — the Posts Page (index.php) reuses this same .archive-item
   look and adds only what a functional listing needs: a small fixed-
   width thumbnail and a muted byline/date line. No new visual design —
   see index.php's own docblock. */

.archive-item__thumbnail {
  display: block;
  float: left;
  width: 120px;
  margin: 0 var(--space-3) var(--space-1) 0;
}

.archive-item__thumbnail img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
}

.archive-item__meta {
  margin: 0 0 var(--space-1);
  font-size: 0.9em;
  color: var(--color-ink-muted, #5A6072);
}

/* WordPress core's the_posts_pagination() markup: a <nav class="pagination">
   of <a>/<span class="page-numbers"> links. Kept inside .minimal-page so it
   never reaches a template outside this pass. */

.minimal-page .pagination {
  margin-top: var(--space-4);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

.minimal-page .pagination .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  padding: 0 var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-brand);
  text-decoration: none;
}

.minimal-page .pagination .page-numbers.current {
  background: var(--color-brand);
  color: var(--color-surface);
  border-color: var(--color-brand);
}

.minimal-page .pagination .page-numbers.dots {
  border: none;
  min-width: auto;
}

/* ==========================================================================
   2. STYLE GUIDE (template-style-guide.php) — Pass 21
   One-off layout for the /style-guide/ reference page. Scoped to
   .style-guide so it never reaches any other template — the component
   rules it demonstrates live in global.css, not here.
   ========================================================================== */

.style-guide__restricted {
  padding-block: var(--space-6);
}

.style-guide__body {
  padding-block: 0 var(--space-12);
}

.style-guide__section {
  margin-bottom: var(--space-10);
}

.style-guide__section:last-child {
  margin-bottom: 0;
}

.style-guide__demo-header-card {
  padding: 0;
  overflow: hidden;
}

.style-guide__demo-header-card .page-header {
  margin-bottom: 0;
}

.style-guide__flush-top {
  margin-top: 0;
}

/* ==========================================================================
   3. DISTRICT MAP (template-district-portal.php, overview view) — Pass 43
   Scoped to .osta-district-map so nothing here reaches any other portal.
   The canvas and the fallback message occupy the SAME space; exactly one
   of them is ever visible at a time (see assets/js/district-map.js —
   the canvas starts [hidden], the fallback starts visible, so a visitor
   with JavaScript disabled — or before the Maps script has finished
   loading — always sees the fallback text, never an empty grey box).
   The always-rendered text list (Step 5) is deliberately NOT part of
   this component — .data-table already has its own styling and needs
   none of this.
   ========================================================================== */

.osta-district-map {
  position: relative;
  margin-bottom: var(--space-3);
}

.osta-district-map__canvas {
  width: 100%;
  height: 420px;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-soft);
}

.osta-district-map__canvas[hidden] {
  display: none;
}

.osta-district-map__fallback {
  padding: var(--space-4) var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-soft);
  background: var(--color-surface-muted, #F4F5F8);
  text-align: center;
}

.osta-district-map__fallback[hidden] {
  display: none;
}

.osta-district-map__fallback-hint {
  margin-top: var(--space-1);
  font-size: 0.9em;
  color: var(--color-ink-muted, #5A6072);
}

/* (Removed) .osta-district-map__omitted-note — PASS: District map
   (interactive), item 1: the aggregate "N chapters not shown" sentence
   this styled is gone; omitted chapters are now individual rows in the
   Step 5 list below (its own .form-hint covers their "(location not
   mapped)" marker, nothing bespoke needed). */

/* Step 5's always-rendered text list — plain, no card-within-card
   styling, since it already lives inside the map's own .card. */
.osta-district-map__list {
  margin: var(--space-3) 0 0;
  padding: 0;
  list-style: none;
}

.osta-district-map__list li {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-1);
  padding: var(--space-1) 0;
  border-bottom: 1px solid var(--color-border-soft);
}

/* PASS — District map (interactive): the LINK itself, not just the row
   it sits in, is what needs to meet --tap-min (48px) — sizing only the
   parent <li> leaves the actual clickable text no taller than one line.
   inline-flex + min-height + block-axis padding makes the anchor's own
   hit box the full 48px, still inline enough to sit next to the city/
   approximate-location text that follows it in the same row (that
   trailing text is deliberately NOT part of the link — only the chapter
   name should be clickable). */
.osta-district-map__list li > a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  padding-block: var(--space-1);
}

.osta-district-map__list li:last-child {
  border-bottom: none;
}

/* Google's InfoWindow renders in its own shadow-free container appended
   near the map, outside this component's own DOM subtree in some
   browsers — these rules are written to also match unscoped so the
   content inside a pin's info window still reads consistently instead
   of inheriting the page's default paragraph spacing. */
.osta-map-infowindow {
  max-width: 220px;
}

.osta-map-infowindow__name {
  margin: 0 0 4px;
  font-weight: 700;
}

.osta-map-infowindow__meta {
  margin: 0 0 4px;
  font-size: 0.9em;
}

.osta-map-infowindow__approx {
  margin: 0 0 4px;
  font-size: 0.85em;
  color: #8A6200; /* muted amber, matches the approximate marker color */
}

/* ---- (Removed) static 5-district schematic — Bucket A item 6 added
   this here as a stand-in fallback before a live browser Maps key
   existed. The District map (interactive) pass replaced it: the real
   interactive map (below, this same section) now renders once a key is
   configured, and Step 5's own always-rendered park list further down
   is the correct on-topic fallback (this district's own parks, not a
   5-district overview) — see template-district-portal.php's own
   comment at the fallback branch. template-parts/static-district-
   map.php was deleted; nothing references these selectors any more. */

/* ---- Progress bar (item 2) — pure HTML/CSS, template-parts/progress-
   bar.php. The fill's width is a server-computed inline style, so it is
   correct on first paint with JavaScript disabled — nothing here is a
   JS-driven animation. The percentage prints as a separate plain-text
   node NEXT TO the bar, never overlapping the fill — see that file's own
   comment for why (one predictable AA-safe contrast pair, not two that
   depend on exactly where the fill's edge lands). */
.osta-progress-bar-wrap {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.osta-progress-bar {
  position: relative;
  flex: 1 1 auto;
  min-width: 80px;
  height: 12px;
  border-radius: 999px;
  background: var(--color-surface-muted, #F4F5F8);
  /* PASS "Fix the accessibility failures found by the component
     inventory", item 5 — was --color-border-soft, well under the 3:1
     non-text-contrast floor. Same fix as the form-control borders
     elsewhere in this pass. */
  border: 1px solid var(--color-muted);
  overflow: hidden;
}

.osta-progress-bar__fill {
  height: 100%;
  background: var(--color-brand);
  border-radius: 999px;
}

.osta-progress-bar__text {
  flex: 0 0 auto;
  min-width: 3.5ch;
  font-size: 0.9em;
  font-weight: var(--weight-semibold);
  color: var(--color-body);
}

/* ==========================================================================
   ABOUT PAGE — Pass 49. Structure/layout ported from the supplied
   Tailwind mockup ("Osta About Us Page Code.txt"); every rule below is
   written fresh against tokens.css — no Tailwind, no CDN, no icon font.
   Body copy is --text-body (18px) throughout, never the mockup's
   text-sm (14px)/10px badge. Green (--color-accent) is used only as a
   surface (icon-circle backers, the timeline's own line/dots) — never
   as text or a checkmark colour; checkmarks are navy, same correction
   Pass 48 already applied on the homepage. The membership section this
   page uses lives in membership-section.css, not here — see
   inc/enqueue.php's osta_page_has_membership_section().
   ========================================================================== */

/* Every ACF-sourced text element across this page's sections gets this —
   same long-unbroken-word overflow fix used everywhere else in the site
   (see homepage.css's own copy of this comment for the fuller history). */
.about-hero__eyebrow,
.about-hero__heading,
.about-hero__body,
.about-timeline__heading,
.about-timeline__intro-body,
.about-timeline__period,
.about-timeline__milestone-heading,
.about-timeline__milestone-summary,
.about-timeline__milestone-intro,
.about-timeline__disclosure-toggle,
.about-timeline__achievements,
.about-board__heading,
.about-board__intro,
.about-board__name,
.about-board__role {
  overflow-wrap: break-word;
  word-break: break-word;
}

/* ---- ABOUT HERO ----
   Pass 62: rebuilt to match the homepage hero (template-parts/sections/
   hero.php, homepage.css) exactly — eyebrow/heading/subtext over a
   full-bleed photo with a scrim, replacing Pass 49's "glass" panel.
   Every rule below is ported from homepage.css's own HERO section (same
   min-height formula, same padding, same type scale, same two scrim
   opacities) with .about-hero__ in place of .hero__ — see about-
   hero.php's own docblock for why this page keeps its own prefixed
   classnames instead of reusing .hero/.hero__ directly. One rule is NOT
   a straight port: .about-hero__overlay's gradient stops are measured
   for this page's own photo, not copied verbatim — see that rule's own
   comment. */

.about-hero {
  position: relative;
  background-size: cover;
  background-position: center;
  background-color: var(--color-surface-dark);
  display: flex;
  align-items: center;
  /* Identical floor to the homepage hero: never shorter than header
     height + 3 * --space-16, and never shorter than 60vh either. */
  min-height: max(calc(var(--header-height) + (var(--space-16) * 3)), 60vh);
}

.about-hero__overlay {
  position: absolute;
  inset: 0;
  /* Same two opacities as the homepage hero's scrim (0.6 fading to
     0.15) — but NOT the same 0%-to-100%-of-viewport gradient stops.
     Measured against this page's actual photo (about-hero-1.jpg):
     copying the homepage's percentage-based stops verbatim put worst-
     case contrast as low as 1.66:1 at mobile/tablet/typical-desktop
     widths, because at those widths the text column (padding + up to
     --measure-max) reaches nearly the full viewport width, running
     into the deliberately-light right end of the gradient that the
     homepage hero's own wider text column never reaches. Fix: hold
     0.6 flat through the text column's own right edge (space-3 +
     measure-max = 744px) and only fade to 0.15 beyond it, out past
     --container-max, where text never sits at any viewport width
     tested. Re-measured worst case at mobile/tablet/desktop/wide/
     ultrawide: 5.98–6.53:1, all clear of the 4.5:1 AA floor with
     margin — see this pass's own report for the full numbers. */
  background: linear-gradient(
    to right,
    rgba(0, 0, 0, 0.6) 0,
    rgba(0, 0, 0, 0.6) calc(var(--space-3) + var(--measure-max)),
    rgba(0, 0, 0, 0.15) var(--container-max)
  );
}

/*
 * PASS "Block theme conversion, Phase 4 (About)" — the hero's own
 * background photo lived as an inline style="background-image:url(...)"
 * directly on .about-hero (the <section>) in the original PHP render;
 * that <section> is now a real, validated core/group block, and Gutenberg
 * flags "Block contains unexpected or invalid content" the moment its
 * saved HTML carries an inline style its own block attributes never
 * declared. Moving the photo to its own plain <div> (a wp:html block,
 * never validated against attributes) sidesteps that — but the div also
 * needs position/size, and inline `inset: 0` on that div was silently
 * stripped by safecss_filter_attr() on save (not on WP's own inline-style
 * property allowlist, unlike the four longhands or a plain url()
 * background-image) — confirmed live: the photo disappeared entirely
 * once `inset` vanished, since an absolutely positioned div with no
 * declared edges collapses to zero size. Solution: real CSS class for
 * position/sizing (this rule, never touched by KSES), inline style
 * limited to just the one genuinely per-page value, the image URL.
 */
/*
 * PASS "Block theme conversion, Group 1 rework" — the hero photo is now a
 * real core/image block (a <figure><img>), not a div with an inline
 * background-image. The old form rendered correctly but could not be
 * changed: swapping the photo meant editing raw HTML inside a wp:html
 * block, which is not something the client can reasonably do. As a real
 * image block it gets the normal media picker, and the alt text stays
 * empty on purpose — the photo sits behind a scrim with the page's own
 * <h1> over it, so it is decorative and a screen reader should skip it
 * rather than read a description of it twice.
 *
 * object-fit reproduces exactly what background-size: cover did, so the
 * scrim gradient measured for this photo in an earlier pass still lands
 * on the same part of the image.
 */
.about-hero__bg,
.osta-hero-bg {
  position: absolute;
  inset: 0;
  margin: 0;
}

/*
 * Scoped to .about-hero (0,2,1) rather than the bare .about-hero__bg img
 * (0,1,1) on purpose: WordPress's own block-library CSS carries
 * `.wp-block-image img { height: auto }` at the same (0,1,1), and inside
 * the editor canvas it loads after this file and won the tie — the photo
 * then rendered at its natural aspect ratio, covering only the top ~640px
 * of the hero with bare navy beneath it. The extra class settles it in
 * both contexts without needing an editor-only duplicate.
 */
/*
 * The image fills its figure by INSET, not by height: 100%. A percentage
 * height has to resolve against a definite containing-block height, and in
 * the editor canvas it kept resolving to auto — the photo rendered at its
 * natural 16:9 (720x405) inside a 685px-tall hero, leaving bare navy under
 * it, even with this rule at higher specificity than the `.wp-block-image
 * img { height: auto }` it was competing with. Absolute inset sidesteps
 * percentage resolution entirely and behaves identically in both contexts.
 */
.about-hero .about-hero__bg.wp-block-image img,
.osta-hero-bg.wp-block-image img {
  display: block;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/*
 * PASS "Block theme conversion, Phase 4 (About)" — editor-canvas-only
 * fix, harmless (and inert) on the front end since this class never
 * exists there. Gutenberg wraps every block — including a plain wp:html
 * one — in its own `.block-editor-block-list__block` div for selection/
 * toolbar purposes, and that wrapper is itself `position: relative`.
 * .about-hero__bg's `position: absolute; inset: 0;` above sizes itself
 * against the NEAREST positioned ancestor — on the front end that's
 * .about-hero (real height, from its own flex content); in the editor
 * it's this Gutenberg wrapper instead, which has no normal-flow content
 * of its own (its only child is absolutely positioned, contributing
 * nothing to its height) — a classic collapse to 0×0, confirmed live:
 * getBoundingClientRect() on the bg div read {w:0,h:0} in the editor
 * canvas despite every computed style being correct. Forcing this one
 * wrapper back to static removes it from the positioning chain, so the
 * bg div skips straight to .about-hero the same way it does on the
 * front end.
 */
.about-hero .block-editor-block-list__block.wp-block-html {
  position: static;
}

/*
 * PASS "Block theme conversion, Group 1 rework" — the companion to the
 * rule above, for the hero photo now that it is a real core/image block
 * rather than a div with an inline background-image.
 *
 * Gutenberg applies the block's own className to the SAME element it uses
 * as the selection wrapper, so in the editor the <figure> is both
 * .about-hero__bg and .block-editor-block-list__block — and the editor's
 * own `position: relative` on that class beat this file's `position:
 * absolute` (both a single class, editor styles winning on load order).
 * The consequence was not subtle: .about-hero is display:flex, so a
 * statically-positioned figure became a real flex ITEM. Measured in the
 * canvas: the photo took 498px of the row and squeezed .about-hero__inner
 * to 222px, wrapping the <h1> to roughly one word per line and making the
 * section about 1500px tall — the editor showed the client something that
 * looked nothing like her page.
 *
 * Restated at (0,3,0) so it wins inside the canvas. Inert on the front
 * end, where .block-editor-block-list__block does not exist — verified by
 * pixel diff, not assumed.
 */
.about-hero .block-editor-block-list__block.about-hero__bg,
.block-editor-block-list__block.osta-hero-bg {
  position: absolute;
  inset: 0;
  /* display:flex, so the image can be stretched by ALIGNMENT rather than by
     a percentage height. In the canvas the section's height comes from
     min-height plus content, which never became "definite" enough for the
     image's height: 100% to resolve — it fell back to auto, and because an
     <img> is a replaced element (auto height means intrinsic height, and the
     bottom inset is then ignored) the photo rendered at its natural 16:9
     inside a 685px hero. align-self: stretch needs no percentage at all. */
  display: flex;
}

/*
 * …and the image inside it. On the front end `height: 100%` resolves
 * correctly against the figure. In the canvas it kept resolving to auto —
 * the photo rendered at its natural 16:9 (720x405) inside a 685px hero,
 * leaving bare navy beneath it — regardless of specificity, because the
 * percentage had no definite containing-block height to resolve against
 * there. Since the image is already absolutely positioned with inset: 0,
 * height: auto simply lets those insets stretch it, which is exactly the
 * intent. Editor-only, so the front end keeps the form already verified
 * pixel-identical.
 */
.about-hero .block-editor-block-list__block.about-hero__bg img,
.block-editor-block-list__block.osta-hero-bg img {
  position: static;
  align-self: stretch;
  width: 100%;
  height: auto;
  object-fit: cover;
}

.about-hero__inner {
  position: relative;
  z-index: 1;
  padding-top: calc(var(--header-height) + var(--space-6));
  padding-bottom: var(--space-10);
}

.about-hero__eyebrow,
.about-hero__heading,
.about-hero__body {
  /* Left-aligned text block capped at measure-max inside the centred
     .container — same technique as the homepage hero. */
  max-width: var(--measure-max);
  margin-inline-start: 0;
  margin-inline-end: auto;
}

.about-hero__eyebrow {
  font-size: var(--text-eyebrow);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: var(--weight-semibold);
  color: var(--color-surface);
  margin: 0 0 var(--space-2);
}

.about-hero__heading {
  font-size: var(--text-display);
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  color: var(--color-surface);
  margin: 0 0 var(--space-3);
}

.about-hero__body {
  font-size: var(--text-lead);
  line-height: var(--leading-body);
  color: var(--color-surface);
  margin: 0;
}

.about-hero__actions {
  margin-top: var(--space-4);
}

@media (max-width: 767px) {
  .about-hero {
    min-height: auto;
  }
}

/* ---- SECTION RHYTHM ----
   Every section below used the plain sitewide .section class — 80px
   (--space-10) top AND bottom. Measured live: the section BOXES
   themselves sit flush against each other (0px between them, no
   doubling like the News page's own bug), so the "dead space" isn't a
   gap between sections — it's 160px of padding bracketing each
   section's own short content (a heading + one paragraph, or a small
   card row), stacked six sections deep down one page. Cut to a single,
   deliberate --space-6 (48px) per edge here — still real breathing room
   between bands, not the sitewide default, which stays 80px everywhere
   it was already correct (a page with fewer, larger sections). Board's
   own section wrapper is included so it keeps the same rhythm as its
   neighbours — its CARD/photo design is untouched, only the outer
   section padding matches. */
.about-who-we-are,
.about-why-exists,
.about-timeline,
.about-membership-benefits,
.about-board,
.about-final-cta {
  padding-block: var(--space-6);
}

/* ---- WHO WE ARE ---- */

.about-who-we-are__row {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/*
 * PASS "Block theme conversion, Phase 4 (About)" — invisible at the
 * desktop row layout below (heading and body sit side by side, so a
 * trailing bottom margin on the heading never shows), but real at the
 * stacked mobile layout above, where it's the only thing separating the
 * heading from the body other than .about-who-we-are__row's own gap.
 * Never needed its own rule before this pass: without it the heading
 * still got --space-2 from this file's own plain `h1,h2,h3,h4` default
 * (global.css) at (0,0,1) specificity, plenty on the classic PHP
 * render, which never had anything else competing for margin-bottom
 * here. Once this row is itself an osta-frame Group (this pass), the
 * heading picks up an .entry-content-flow ancestor and WordPress's own
 *   :root :where(.is-layout-flow) > * { margin-block: 24px 0px; }
 * — (0,1,0), same rule the other margin-block-START fixes on this page
 * already fight — zeroes margin-bottom too via that shorthand, and
 * beats the theme's (0,0,1) default outright. Every OTHER section
 * heading on this page already had its own (0,1,0)-or-higher margin
 * rule for a different reason (its own type scale/alignment) that
 * happened to double as protection here; this is the one heading that
 * never needed one before and was left exposed. A plain, explicit
 * (0,1,0) rule is the fix, not a marker class — this is a real,
 * permanent design value, not a per-instance opt-out.
 */
.about-who-we-are__heading {
  margin-bottom: var(--space-2);
}

@media (min-width: 768px) {
  .about-who-we-are__row {
    flex-direction: row;
    align-items: flex-start;
    gap: var(--space-8);
  }

  .about-who-we-are__heading {
    flex: 0 0 33%;
  }

  .about-who-we-are__body {
    flex: 1 1 0;
  }
}

.about-who-we-are__body p {
  font-size: var(--text-lead);
  line-height: var(--leading-body);
  color: var(--color-body);
  margin: 0 0 var(--space-2);
}

.about-who-we-are__body p:last-child {
  margin-bottom: 0;
}

/* ---- WHY OSTA EXISTS ---- */

.about-why-exists__heading {
  text-align: center;
  max-width: var(--measure-max);
  margin-inline: auto;
  margin-bottom: var(--space-6);
}

.about-why-exists__intro {
  max-width: var(--measure-max);
  margin: calc(var(--space-3) * -1) auto var(--space-6);
  text-align: center;
  font-size: var(--text-body);
  line-height: var(--leading-body);
}

.about-why-exists__grid {
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

@media (min-width: 900px) {
  .about-why-exists__grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

.about-why-exists__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-8);
  height: var(--space-8);
  border-radius: 50%;
  /* Surface use of the brand navy — a decorative circle behind the
     icon, matching this page's own navy identity rather than reusing
     the homepage validation cards' green (that circle specifically
     signals "a problem" there; these four cards are neutral facts about
     the org, not problems). */
  background: var(--color-brand-wash);
  color: var(--color-brand);
  margin-bottom: var(--space-3);
}

.about-why-exists__icon svg {
  width: 28px;
  height: 28px;
}

/* ---- TIMELINE ---- */

.about-timeline__intro {
  text-align: center;
  max-width: var(--measure-max);
  margin-inline: auto;
  margin-bottom: var(--space-4);
}

.about-timeline__list {
  position: relative;
  margin: 0;
  padding: 0;
}

.about-timeline__list::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 20px;
  width: 4px;
  border-radius: 999px;
  /* Surface use of accent — the timeline's own spine, never text. */
  background: var(--color-accent);
}

.about-timeline__item {
  position: relative;
  display: flex;
  padding-left: 56px;
  /* Single-column (below 900px): one card under the next. Desktop tree
     overlap is set in the media query — a positive margin here plus
     the opposite card's height is what made same-side gaps look like
     empty bands. */
  margin-bottom: var(--space-1);
}

.about-timeline__item:last-child {
  margin-bottom: 0;
}

.about-timeline__dot {
  position: absolute;
  top: var(--space-1);
  left: 20px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--color-surface);
  border: 4px solid var(--color-accent);
  transform: translateX(-50%);
}

.about-timeline__card {
  width: 100%;
  padding: var(--space-2);
}

/* ---- Alternating left/right at desktop, rebuilt from scratch rather
   than restoring the old version verbatim — that one broke down at
   mobile because the alternating rule and the mobile fallback were two
   separate layouts (flex justify-content flip + a manually recomputed
   PHP side class) that could drift out of sync. This version changes
   NOTHING below 900px (the already-verified single-column layout, still
   tested clean at 360px) and turns the alternation on for wider screens
   using pure CSS structural selection (:nth-child) — no PHP side
   computation to keep in sync with anything, the side is just "which
   position in the list," which can never disagree with itself. ---- */
@media (min-width: 900px) {
  .about-timeline__list::before {
    left: 50%;
    transform: translateX(-50%);
  }

  .about-timeline__item {
    padding-left: 0;
    justify-content: flex-start;
    /* Nest opposite-side cards without letting two left (or two right)
       cards collide. -64px overlapped same-side tiles when the card
       in between was short (~115px). -40px leaves ~16–35px between
       same-side cards. Last item stays 0 so the next section is not
       pulled up. */
    margin-bottom: calc(var(--space-5) * -1);
  }

  .about-timeline__item:nth-child(even) {
    justify-content: flex-end;
  }

  .about-timeline__item:last-child {
    margin-bottom: 0;
  }

  .about-timeline__dot {
    left: 50%;
  }

  .about-timeline__card {
    /* Smaller tile: a fixed, narrower width rather than the old
       calc(50% - gap) — the old formula gave a card the full half-
       column width, which is what read as "one giant box after
       another" rather than a tree of smaller tiles either side of the
       spine. */
    width: 42%;
    max-width: 380px;
  }
}

.about-timeline__period {
  display: inline-block;
  background: var(--color-accent);
  /* Navy text on green — this pairing passes contrast (verified in this
     pass's report), so it's kept, per this pass's own instruction. */
  color: var(--color-ink);
  font-weight: var(--weight-bold);
  font-size: var(--text-small);
  padding: var(--space-1) var(--space-2);
  border-radius: 999px;
  margin-bottom: var(--space-1);
}

/* PASS 50 — card redesign: heading, optional per-milestone intro, and
   an achievement bullet list of any length (0–6+, the post's own
   content — see timeline.php/osta_milestones()'s own docblocks). */

/* PASS 52 — always-visible one-line summary, distinct from the intro
   below (which only ever appears inside the opened panel). */
.about-timeline__milestone-summary {
  color: var(--color-body);
  margin: 0;
}

/* Card__heading already carries margin-bottom: var(--space-2); the
   summary directly under it doesn't need its own top margin as well —
   its OWN bottom margin (above) is what separates it from the
   disclosure toggle beneath. */

.about-timeline__milestone-intro {
  color: var(--color-body);
  margin: 0 0 var(--space-3);
}

.about-timeline__milestone-intro:first-child {
  margin-top: 0;
}

/* ---- PASS 52: collapsed achievements (<details>/<summary>) ---- */

.about-timeline__disclosure {
  margin-top: var(--space-2);
}

.about-timeline__disclosure-toggle {
  /* Remove the browser's default marker so a custom one (below) can
     replace it — list-style: none alone doesn't do this in every
     browser for <summary>, ::-webkit-details-marker also has to go. */
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: var(--tap-min);
  color: var(--color-brand);
  font-weight: var(--weight-semibold);
  /* PASS "Fix the accessibility failures found by the component
     inventory", item 2 — was --text-small (16px). */
  font-size: var(--text-body);
  cursor: pointer;
  user-select: none;
}

.about-timeline__disclosure-toggle::-webkit-details-marker {
  display: none;
}

.about-timeline__disclosure-toggle::before {
  content: '';
  flex-shrink: 0;
  width: 10px;
  height: 10px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 150ms;
}

@media (prefers-reduced-motion: reduce) {
  .about-timeline__disclosure-toggle::before {
    transition: none;
  }
}

/* Chevron points down closed, up open — [open] is the native state
   attribute <details> manages itself, no JS needed to toggle this. */
.about-timeline__disclosure[open] > .about-timeline__disclosure-toggle::before {
  transform: rotate(135deg);
}

.about-timeline__disclosure-toggle:hover {
  color: var(--color-brand-hover);
}

.about-timeline__disclosure-toggle:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-sm);
}

.about-timeline__disclosure-content {
  padding-top: var(--space-2);
}

.about-timeline__achievements ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.about-timeline__achievements li {
  position: relative;
  /* Explicit floor, not an assumption: the editor's own list output
     would otherwise inherit whatever font-size surrounds it. --text-body
     is this site's minimum anywhere, per this pass's own instruction. */
  font-size: var(--text-body);
  line-height: var(--leading-body);
  color: var(--color-body);
  padding-left: var(--space-3);
}

.about-timeline__achievements li + li {
  margin-top: var(--space-2);
}

.about-timeline__achievements li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.65em;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  /* Marker drawn as a background (a surface), never as list-style/color
     text. Navy, not the accent green used on the spine/dots above: at
     this small a size the green measures 2.10:1 against a white card —
     under the 3:1 non-text contrast floor (WCAG 1.4.11) — while navy
     clears it many times over. The pass explicitly allows either colour
     here; navy is the one that actually passes at this size. */
  background: var(--color-brand);
}

/* A milestone with zero bullets (content left empty) still renders a
   clean card — period/heading/intro only, no dangling empty list, since
   timeline.php never prints .about-timeline__achievements when
   $milestone->content is empty. Nothing extra needed here for that
   case; noted for whoever reads this next to why there's no
   :empty-state rule. */

.about-timeline__highlight-label {
  display: inline-block;
  color: var(--color-brand);
  font-weight: var(--weight-bold);
  font-size: var(--text-eyebrow);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0 0 var(--space-1);
}

.about-timeline__item--highlighted .about-timeline__card {
  /* Same emphasis tokens .card--primary already uses elsewhere in the
     site (global.css) — not a new visual language for "this one
     matters more", the one this project already has. */
  border-top: 4px solid var(--color-brand);
  box-shadow: var(--shadow-primary);
}

.about-timeline__item--highlighted .about-timeline__dot {
  width: 20px;
  height: 20px;
  border-width: 5px;
}

/* ---- MEMBERSHIP BENEFITS ---- */

.about-membership-benefits__layout {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

@media (min-width: 900px) {
  .about-membership-benefits__layout {
    flex-direction: row;
    align-items: stretch;
  }

  .about-membership-benefits__list-col,
  .about-membership-benefits__panel {
    flex: 1 1 0;
    min-width: 0;
  }
}

.about-membership-benefits__heading {
  margin: 0 0 var(--space-4);
}

.about-membership-benefits__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.about-membership-benefits__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  padding: var(--space-3);
}

.about-membership-benefits__icon {
  flex-shrink: 0;
  color: var(--color-brand);
  margin-top: 2px;
}

.about-membership-benefits__icon svg {
  width: 24px;
  height: 24px;
}

/*
 * PASS "Block theme conversion, Group 1 rework" — the icon's own 2px
 * optical nudge (rule above) is a first-child margin-top, so it loses to
 * WordPress core's `:where(.is-layout-flow) > :first-child {
 * margin-block-start: 0 }` (0,2,0) now that each benefit <li> is a real
 * Group block. This is the exact per-component shape global.css's own
 * .keep-margin comment documents as the remedy — .keep-margin cannot fix
 * it, because core zeroes the property outright and only this component
 * knows the value to put back. (0,2,0) ties core; inner-pages.css loads
 * after the inline layout styles, so it wins on order.
 */
.about-membership-benefits__item .about-membership-benefits__icon {
  margin-top: 2px;
}

.about-membership-benefits__item-title {
  display: block;
  font-weight: var(--weight-bold);
  color: var(--color-ink);
  margin-bottom: 2px;
}

.about-membership-benefits__item-body {
  display: block;
  color: var(--color-body);
}

.about-membership-benefits__panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  /* White text on --color-brand — 11.57:1, computed, same figure this
     token pairing carries everywhere else on the site. Not the
     mockup's own light-tint panel: that one would need light-on-light
     text to match its screenshot, which this pass's own instruction
     rules out. */
  background: var(--color-brand);
  color: var(--color-surface);
  border-radius: var(--radius-lg);
  padding: var(--space-6) var(--space-4);
}

.about-membership-benefits__panel-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--color-surface);
  color: var(--color-brand);
  margin-bottom: var(--space-3);
}

.about-membership-benefits__panel-icon svg {
  width: 32px;
  height: 32px;
}

.about-membership-benefits__panel-heading {
  color: var(--color-surface);
  margin: 0 0 var(--space-3);
}

.about-membership-benefits__panel-quote {
  font-size: var(--text-lead);
  line-height: var(--leading-body);
  color: var(--color-surface);
  opacity: 0.92;
  max-width: 440px;
  margin: 0;
}

/* ---- FINAL CTA ---- */

.about-final-cta__inner {
  max-width: 800px;
  margin-inline: auto;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
}

.about-final-cta__heading {
  /* Was --text-display (60px) — the SAME size as the page's own hero
     heading, while every other section heading on this page (Who We
     Are, Why OSTA Exists, Legislative Milestones, Why Be a Member,
     Meet Our Board) sits at the plain default h2 (34px) — confirmed
     live, not assumed: measured every section heading's computed
     font-size before touching this. One deliberate step above that
     shared 34px baseline for the page's true closing statement, not
     four steps above it. */
  font-size: var(--text-h1);
  margin: 0;
}

/* ---- BOARD OF DIRECTORS ---- Pass 62.
   Cards are non-interactive (no <a>, no hover/focus treatment) — plain
   information, not a navigation control. Flexbox + justify-content:
   center rather than CSS grid: with a fixed card width per breakpoint
   and no flex-grow, an incomplete final row (11 members over 3 columns
   leaves 2 on the last row) centers itself automatically, which a grid
   would not do without extra markup. */

.about-board__heading {
  text-align: center;
  max-width: var(--measure-max);
  margin-inline: auto;
  margin-bottom: var(--space-3);
}

.about-board__intro {
  text-align: center;
  max-width: var(--measure-max);
  margin-inline: auto;
  margin-bottom: var(--space-6);
  color: var(--color-body);
}

.about-board__grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-6) var(--space-4);
  list-style: none;
  margin: 0;
  padding: 0;
}

.about-board__card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  /* One column at mobile (the default, below), 2 at tablet, 3 at
     desktop — see the media queries below. flex-grow/-shrink: 0 keeps
     each card at its computed width instead of stretching to fill a
     short last row, which is what lets justify-content: center on the
     parent actually center that row. */
  flex: 0 0 100%;
  max-width: 100%;
}

@media (min-width: 768px) {
  .about-board__card {
    flex-basis: calc((100% - var(--space-4)) / 2);
    max-width: calc((100% - var(--space-4)) / 2);
  }
}

@media (min-width: 992px) {
  .about-board__card {
    flex-basis: calc((100% - (var(--space-4) * 2)) / 3);
    max-width: calc((100% - (var(--space-4) * 2)) / 3);
  }
}

.about-board__photo {
  display: block;
  width: 100%;
  max-width: 220px;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  /* 16px per this pass's explicit spec — doesn't match an existing
     --radius-* token (6/12/20px), so it's a one-off literal value here
     rather than a mismatched token. */
  border-radius: 16px;
  margin-bottom: var(--space-3);
  background: var(--color-surface-alt);
}

.about-board__photo--fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-brand);
  color: var(--color-surface);
  font-weight: var(--weight-bold);
  font-size: var(--text-h2);
}

.about-board__name {
  display: block;
  font-size: var(--text-h4); /* 21px — this pass's "~20px, min 18px" */
  font-weight: var(--weight-semibold);
  color: var(--color-brand);
}

.about-board__role {
  display: block;
  font-size: var(--text-body);
  color: var(--color-muted);
  margin-top: var(--space-1);
}

/* ---- PAGE'S OWN EDITOR CONTENT ---- */

.about-editor-content {
  max-width: var(--measure-max);
  padding-block: var(--space-8);
}

/* ==========================================================================
   CONTACT PAGE — Pass 54. Structure/layout ported from the supplied
   mockup ("Osta Contact Us Page Code.txt"); every rule below is written
   fresh against tokens.css — no Tailwind, no CDN, no icon font. Body
   copy is --text-body (18px) throughout, never the mockup's 16px
   helper text or 14px labels — form inputs/labels already inherit this
   from global.css's own form component (Pass 21), not repeated here.
   Green is a surface only (the confidentiality badge's background, the
   info panel's tint) — every piece of text on this page, including the
   badge, is navy or a neutral ink, never green, per this pass's own
   corrections-carried-forward instruction.
   ========================================================================== */

.contact-hero__heading,
.contact-hero__body,
.contact-hub__form-heading,
.contact-hub__info-heading,
.contact-hub__info-body,
.contact-hub__reach-text,
.contact-cards__heading {
  overflow-wrap: break-word;
  word-break: break-word;
}

/* ---- HERO ---- */

.contact-hero {
  padding-block: calc(var(--header-height) + var(--space-8)) var(--space-10);
  /* Same brand navy used for every other no-image hero/section in this
     theme (homepage hero fallback, About hero fallback, Solution
     section, Shift panel, Climax band) — --color-surface-dark, not a
     one-off blue. Text below is flipped to light to match, mirroring
     the .on-dark / .section--dark convention in global.css. */
  background: var(--color-surface-dark);
  text-align: center;
}

.contact-hero__inner {
  max-width: var(--measure-max);
  margin-inline: auto;
}

.contact-hero__heading {
  font-size: var(--text-display);
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  /* White on --color-surface-dark (#1A2255) = ~14.95:1. */
  color: var(--color-surface);
  margin: 0 0 var(--space-3);
}

.contact-hero__body {
  font-size: var(--text-lead);
  line-height: var(--leading-body);
  /* Same lead-copy-on-dark treatment as the homepage hero/Solution
     section: --color-surface at 92% opacity = ~12.8:1 on the navy
     background, still comfortably above the 4.5:1 AA floor. */
  color: var(--color-surface);
  opacity: 0.92;
  margin: 0 0 var(--space-4);
}

.contact-hero__badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  /* Surface use of a light green tint — the badge TEXT is navy, never
     green (this pass's own corrections-carried-forward instruction). */
  background: var(--color-success-wash);
  color: var(--color-brand);
  font-weight: var(--weight-bold);
  font-size: var(--text-small);
  padding: var(--space-1) var(--space-3);
  border-radius: 999px;
}

.contact-hero__badge-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

/* ---- CONTACT HUB (the floating card) ---- */

.contact-hub {
  position: relative;
  z-index: 1;
  /* Pulls the card up to overlap the hero's bottom edge, same floating-
     panel idea the mockup uses — kept, since it's a layout choice, not
     styling the mockup's own CSS system supplied. */
  margin-top: calc(-1 * var(--space-8));
  padding-bottom: var(--space-10);
}

.contact-hub__card {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-hover);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.contact-hub__form-side,
.contact-hub__info-side {
  padding: var(--space-5) var(--space-4);
}

.contact-hub__info-side {
  /* Surface use of the same light green tint as the badge above —
     matches the mockup's own #F4F9ED info panel, never used for text. */
  background: var(--color-success-wash);
  border-top: 1px solid var(--color-border-soft);
}

@media (min-width: 900px) {
  .contact-hub__card {
    flex-direction: row;
  }

  .contact-hub__form-side {
    width: 60%;
  }

  .contact-hub__info-side {
    width: 40%;
    border-top: none;
    border-left: 1px solid var(--color-border-soft);
  }
}

.contact-hub__form-heading {
  margin: 0 0 var(--space-4);
}

.contact-hub__another {
  margin-top: var(--space-4);
}

/* ---- THE FORM ITSELF ---- */

.contact-form {
  position: relative;
}

/* Found during this pass's own contrast check: global.css's shared
   input/select/textarea border (--color-border, #CDD1DC) measures
   1.53:1 against white — well under the 3:1 WCAG 1.4.11 floor for a
   UI component boundary. That's a SITE-WIDE default (every form on
   every page uses it, not something this pass introduced), so it's
   fixed HERE, scoped to only this page's own inputs, rather than
   silently changed everywhere else — flagged in this pass's own report
   as worth fixing globally in a future pass instead of guessed at now. */
.contact-form input,
.contact-form textarea {
  border-color: var(--color-muted);
}

/* The honeypot: off-screen (not just visually hidden — see global.css's
   own .visually-hidden, which is deliberately SCREEN-READER-visible for
   skip-links and the like; this is the opposite, on purpose) AND
   aria-hidden AND tabindex="-1" in the markup, so no assistive
   technology user is ever told this field exists and no keyboard user
   can ever tab to it. A real visitor never interacts with this in any
   way; only something that fills in every field it can find does. */
.contact-form__trap {
  position: absolute;
  left: -9999px;
  top: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.contact-form__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
}

@media (min-width: 560px) {
  .contact-form__grid {
    grid-template-columns: 1fr 1fr;
    column-gap: var(--space-3);
  }

  .contact-form__span2 {
    grid-column: span 2;
  }
}

.contact-form__error-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.contact-form__error-list a {
  color: var(--color-alert);
  text-decoration: underline;
}

/* ---- INFO SIDE: "Other Ways to Reach Us" ---- */

.contact-hub__reach-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-top: var(--space-3);
}

.contact-hub__reach-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
}

.contact-hub__reach-icon {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--color-brand);
}

.contact-hub__reach-label {
  font-size: var(--text-small);
  font-weight: var(--weight-semibold);
  color: var(--color-ink);
  margin: 0 0 2px;
}

.contact-hub__reach-link {
  /* Found during this pass's own tap-target check: the plain inline
     link's own clickable box was only as tall as its text (~20px) —
     under the 48px minimum. Padding grows the tappable area without
     growing the text itself or breaking its inline flow next to the
     label above it. */
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  padding-block: var(--space-1);
  color: var(--color-brand);
  text-decoration: underline;
}

.contact-hub__reach-text {
  margin: 0;
  color: var(--color-body);
}

.contact-hub__divider {
  border: none;
  border-top: 1px solid var(--color-border-soft);
  margin: var(--space-5) 0;
}

/* ---- BOTTOM SELF-SERVE CARDS ---- */

.contact-cards__heading {
  text-align: center;
  max-width: var(--measure-max);
  margin-inline: auto;
  margin-bottom: var(--space-6);
}

.contact-cards__card {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
  transition: box-shadow 150ms;
}

@media (prefers-reduced-motion: reduce) {
  .contact-cards__card {
    transition: none;
  }
}

.contact-cards__card:hover,
.contact-cards__card:focus-visible {
  box-shadow: var(--shadow-hover);
}

.contact-cards__card .card__body {
  flex-grow: 1;
}

.contact-cards__link {
  margin-top: var(--space-2);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--color-brand);
  font-weight: var(--weight-semibold);
}

.contact-cards__link svg {
  width: 16px;
  height: 16px;
}

@media (max-width: 767px) {
  .contact-hero {
    padding-block: calc(var(--header-height) + var(--space-6)) var(--space-8);
  }

  .contact-hub {
    margin-top: calc(-1 * var(--space-6));
  }
}

/*
 * PASS "Block theme conversion, Group 1 (Contact)" — three margin
 * restorations needed once this page's markup became real Group blocks
 * sitting inside core/post-content's own is-layout-flow wrapper
 * (.entry-content.wp-block-post-content). Three different rules already
 * in the cascade were each independently beating this component's own
 * margin declarations above on specificity — none of them a plain
 * WP-blockGap "spacing between blocks" case the existing
 * .keep-margin/.keep-margin-bottom convention already covers, so scoped
 * here rather than touched globally (flagged in this pass's own report
 * as a new class of gap worth reviewing centrally):
 *
 *  1. .contact-hero__body is the LAST child of its own osta-frame
 *     Group. WordPress's block-theme global styles set
 *     :where(.is-layout-flow) > :last-child { margin-block-end: 0 }
 *     at (0,2,0) specificity — strictly greater than this component's
 *     own single-class margin rule above (0,1,0), so it always wins
 *     regardless of stylesheet load order (unlike a same-specificity
 *     TIE against WordPress's own general is-layout-flow rule, which
 *     this theme's CSS already wins everywhere else on this page simply
 *     by loading after WordPress's inline global-styles block).
 *  2. .contact-hub__info-heading relies on the GENERIC h1–h4 rule
 *     above for its margin-bottom (no component-specific override was
 *     ever needed before this page put one inside an osta-frame Group)
 *     — a bare type selector (0,0,1) that WordPress's general blockGap
 *     rule (0,1,0) beats outright, not a tie. The second heading
 *     ("Other Ways to Reach Us") already carries .keep-margin so its
 *     own margin-TOP survives the .osta-frame zeroing rule, but
 *     .keep-margin only ever undoes THAT one rule — the value it falls
 *     back to is WordPress's own flat 24px blockGap default (0,1,0),
 *     not this component's actual --space-6 design value, since the
 *     generic h1–h4 rule supplying that value is still only (0,0,1).
 *     Both headings need a real component-specific rule here.
 *  3. .contact-hub__divider is a structural <hr> — the first one this
 *     theme has ever placed inside an osta-frame section. It collides
 *     with global.css's own earlier ".entry-content hr { margin: 0 }"
 *     prose reset (0,1,1), which beats this component's own
 *     single-class margin rule (0,1,0) outright — unrelated to blockGap
 *     at all. That prose reset has no ":not(.osta-frame *)" exemption
 *     the way the heading version does (no prior page ever needed one),
 *     so any FUTURE page's own structural <hr> inside an osta-frame
 *     section will hit this same gap — flagged for a central fix,
 *     worked around locally here. Also carries .keep-margin in the
 *     markup itself so its margin-top isn't separately zeroed by the
 *     unconditional .osta-frame child rule before this override is even
 *     reached.
 */
.contact-hero__inner p.contact-hero__body {
  margin-bottom: var(--space-4);
}

.contact-hub__info-side .contact-hub__info-heading {
  margin-bottom: var(--space-2);
}

.contact-hub__info-side .contact-hub__info-heading.keep-margin {
  margin-top: var(--space-6);
}

.contact-hub__info-side .contact-hub__divider {
  margin: var(--space-5) 0;
}

/*
 * PASS "Block theme conversion, Group 1 (Contact)" — a FIFTH instance of
 * the same ".entry-content now wraps the whole page, not just prose"
 * category of bug the four fixes above (About) already found and fixed
 * with a ":not(.osta-frame *)" exemption, just not yet caught because it
 * only becomes visible with a genuinely long, unbreakable string.
 * global.css's own ".entry-content { overflow-wrap: break-word;
 * word-break: break-word; }" (Pass 61) was written when .entry-content
 * only ever wrapped a template's own manually-classed editor-content
 * <article> — never the WHOLE page. Now that core/post-content auto-
 * wraps this page's ENTIRE post_content (hero through the cards) in a
 * div carrying that same class, every osta-frame section inherits
 * break-word too, including this component's own reach-link email
 * address, which never wrapped before (nothing in this component's own
 * CSS sets overflow-wrap at all — it relied on the ambient default of
 * "normal"). At the 360px breakpoint "questions@oregontenants.com" no
 * longer fits its column on one line, so it now wraps to two, growing
 * this card and the whole page. Restored locally, scoped to this
 * component; flagged for the same central ":not(.osta-frame *)" fix as
 * the four instances above, since any future page's own osta-frame
 * section with a long unbreakable string (an email, a URL, a long
 * unhyphenated word) will hit this identical gap.
 */
.contact-hub__info-side .contact-hub__reach-link {
  overflow-wrap: normal;
  word-break: normal;
}

/*
 * PASS "Block theme conversion, Group 1 (Contact)" — a SIXTH instance of
 * the same ".entry-content now wraps the whole page" category above.
 * global.css's own ".entry-content a { color: var(--color-brand);
 * text-decoration: underline; }" (a class + a tag, (0,1,1)) beats this
 * component's own single-class "text-decoration: none" on
 * .contact-cards__card ((0,1,0)) outright — not a tie, so stylesheet
 * load order can't save it the way it does elsewhere on this page.
 * Text-decoration also propagates visually to descendant text even
 * where a descendant sets its own color, so the whole card (heading,
 * body copy, "View FAQs →" link alike) rendered underlined, not just
 * the outer <a>'s own text. Restored locally; flagged for the same
 * central ":not(.osta-frame *)" fix as the instances above — any future
 * page's own osta-frame section with a whole-card (or otherwise
 * text-bearing) <a> will hit this identical gap.
 */
.contact-cards .contact-cards__card {
  text-decoration: none;
  color: inherit;
}

/* --------------------------------------------------------------------------
 * PASS "Block theme conversion, Group 1 rework (Contact)" — the five
 * rules below all exist for one reason: DEFECT 2 required the four
 * core/html blocks that were locking this page's real copy out of the
 * editor to become real, editable blocks. Making text editable means
 * making it a BLOCK, and a block is an element WordPress wraps in its
 * own layout container — so each of these restores something the raw
 * HTML used to get for free. Every value below was measured against
 * this page's own previous committed render, not guessed.
 *
 * 1. REACH ICON'S OPTICAL NUDGE. .contact-hub__reach-icon's own
 *    `margin-top: 2px` (above) lines the 24px envelope/phone glyph up
 *    with the cap-height of the label beside it. The icon is now the
 *    FIRST child of a real Group block, so WordPress core's inline
 *    layout style
 *      :root :where(.is-layout-flow) > :first-child { margin-block-start: 0 }
 *    (0,2,0) zeroes it — it outranks the icon's own single-class rule
 *    (0,1,0), and .keep-margin (which the svg also carries, for
 *    global.css's own (0,3,0) .osta-frame child rule) does nothing about
 *    core's version. Measured: the icon sat 2px high against the
 *    previous render until this went in. This is the SAME systemic gap
 *    the Evictions section of this file already documents at length for
 *    .evictions-callout__icon / .evictions-safeharbor__check — a third
 *    instance, and more evidence that a "keep-margin-first-child" shape
 *    belongs centrally in global.css (still deliberately not touched
 *    here).
 * -------------------------------------------------------------------------- */
.contact-hub__reach-item .contact-hub__reach-icon {
  margin-top: 2px;
}

/*
 * 2. CARD BODY'S BOTTOM MARGIN. The self-serve cards' body copy is now a
 *    real core/paragraph inside a real Group block, so WordPress core's
 *      :root :where(.is-layout-flow) > * { margin-block-end: 0 }
 *    (0,1,0) now applies to it and beats global.css's own sitewide
 *    `p { margin-bottom: var(--space-3) }` (0,0,1) outright. That
 *    sitewide 24px was load-bearing here: as raw HTML inside a core/html
 *    block the <p> was never inside a layout container at all, so it
 *    kept it. Measured, not assumed — losing it shortened every card by
 *    exactly 24px (a 24px page-height delta at 1440px where the three
 *    cards sit side by side, 72px at 360px where they stack). Restored
 *    at (0,3,0) so it beats core's rule rather than tying it.
 */
.contact-cards .contact-cards__card .card__body {
  margin-bottom: var(--space-3);
}

/*
 * 3. "VIEW FAQs →" LINK UNDERLINE. .contact-cards__link used to be a
 *    <span> INSIDE the card's own <a>, so it was never itself a link and
 *    never matched global.css's `.entry-content a { text-decoration:
 *    underline }`. It is now a Group wrapping a real osta/resource-link
 *    <a> (editable label, live-resolved destination) plus its arrow
 *    icon, so that rule (0,1,1) reaches the anchor for the first time.
 *    The sibling rule immediately above this comment block already
 *    handles the same problem for the card itself; this is its
 *    counterpart for the inner anchor. `color: inherit` is included at
 *    (0,2,1) deliberately so it also outranks `.entry-content a:hover`
 *    (0,1,1) — the previous span never changed colour on hover and this
 *    keeps that true.
 */
.contact-cards .contact-cards__link a {
  text-decoration: none;
  color: inherit;
}

/*
 * 4. WHOLE-CARD CLICK TARGET. Previously the entire card WAS the <a>
 *    (`<a class="card contact-cards__card">` wrapping heading, body and
 *    link) — a ~360x244px tap target, which on a page built for elderly
 *    and low-vision residents is the point, not an accident. A real
 *    block cannot reproduce that: core/heading and core/paragraph cannot
 *    live inside an anchor, and osta/resource-link renders a leaf
 *    <a>text</a> with no inner blocks. The card is therefore now a
 *    Group <div> and the anchor is the inner "View FAQs" link, with the
 *    original tap target restored the standard way — a transparent
 *    stretched pseudo-element pinned to the card.
 *
 *    :not(.block-editor-block-list__block) makes this FRONT-END ONLY, on
 *    purpose and for a concrete reason, not caution: Gutenberg puts that
 *    class on the very element it applies a block's className to, so in
 *    the editor canvas the card div carries it — and an overlay pinned
 *    across the whole card there would swallow the clicks that select
 *    the heading and body blocks, re-creating the exact "client cannot
 *    edit this" defect this rework exists to fix. That class never
 *    exists on the front end, so the selector is simply always true
 *    there; verified by pixel diff (0.0000% at both 1440px and 360px)
 *    before and after adding this rule.
 *
 *    .card is not positioned by default, so `position: relative` here is
 *    the containing block the overlay needs. It is scoped to
 *    .contact-cards so no other .card on the site is affected.
 */
.contact-cards .contact-cards__card {
  position: relative;
}

.contact-cards .contact-cards__card:not(.block-editor-block-list__block) .contact-cards__link a::before {
  content: "";
  position: absolute;
  inset: 0;
}

/*
 * 5. FOCUS AFFORDANCE. .contact-cards__card:focus-visible (above) styled
 *    the card because the card was the focusable element. Now the
 *    anchor inside it is, so that selector can never match again — this
 *    is the same declaration re-hung off the focused descendant, so
 *    keyboard users still get the identical hover/focus shadow on the
 *    card they are about to activate. (The anchor keeps the site's own
 *    global focus ring; this only restores the card-level shadow.)
 */
.contact-cards .contact-cards__card:has(.contact-cards__link a:focus-visible) {
  box-shadow: var(--shadow-hover);
}

/* ==========================================================================
   GET ANSWERS — SAME-PAGE SEARCH RESULTS
   Moved out to its own file, assets/css/answers-search-results.css — see
   that file's own top comment for why: this component now also renders
   on the homepage (homepage.css), a second stylesheet mutually exclusive
   with this one (inc/enqueue.php), so it could no longer live in only
   one of the two.
   ========================================================================== */

/* ==========================================================================
   FIND RESOURCES PAGE — structure/layout ported from the supplied
   mockup ("Find Resources - SeniorAdvocate"); every rule written fresh
   against tokens.css. The mockup's own header/nav/Emergency Call button
   are NOT reproduced anywhere here — "global chrome stays global" per
   this pass's own instruction, so this file only styles the sections
   template-find-resources.php actually renders between get_header() and
   get_footer(): the hero and the sidebar+grid layout below it.
   ========================================================================== */

/* ---- RESOURCES HERO ----
   PASS: replaces the old navy "Join Our Community" CTA band (deleted
   below — this page no longer has a .resources-cta anything) with the
   site's standard hero pattern. Ported rule-for-rule from the About
   page's own hero (.about-hero/.about-hero__*, inner-pages.css's own
   ABOUT HERO section) — itself a port of the homepage hero
   (homepage.css/template-parts/sections/hero.php) — same min-height
   formula, same padding, same type scale, same two scrim opacities.
   Kept as its own resources-hero__* prefix rather than reusing
   .about-hero__* directly — see template-parts/sections/resources-
   hero.php's own docblock for why. */

.resources-hero {
  position: relative;
  background-size: cover;
  background-position: center;
  background-color: var(--color-surface-dark);
  display: flex;
  align-items: center;
  min-height: max(calc(var(--header-height) + (var(--space-16) * 3)), 60vh);
}

.resources-hero__overlay {
  position: absolute;
  inset: 0;
  /* Same gradient stops as .about-hero__overlay, reusing the same photo
     (attachment 1807) at the same measured-safe values — re-verified
     live on this page's own rendered hero, not assumed carried over:
     see this pass's own report for the numbers. */
  background: linear-gradient(
    to right,
    rgba(0, 0, 0, 0.6) 0,
    rgba(0, 0, 0, 0.6) calc(var(--space-3) + var(--measure-max)),
    rgba(0, 0, 0, 0.15) var(--container-max)
  );
}

.resources-hero__inner {
  position: relative;
  z-index: 1;
  padding-top: calc(var(--header-height) + var(--space-6));
  padding-bottom: var(--space-10);
}

.resources-hero__eyebrow,
.resources-hero__heading,
.resources-hero__body {
  max-width: var(--measure-max);
  margin-inline-start: 0;
  margin-inline-end: auto;
  overflow-wrap: break-word;
  word-break: break-word;
}

.resources-hero__eyebrow {
  font-size: var(--text-eyebrow);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: var(--weight-semibold);
  color: var(--color-surface);
  margin: 0 0 var(--space-2);
}

.resources-hero__heading {
  font-size: var(--text-display);
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  color: var(--color-surface);
  margin: 0 0 var(--space-3);
}

.resources-hero__body {
  font-size: var(--text-lead);
  line-height: var(--leading-body);
  color: var(--color-surface);
  margin: 0;
}

.resources-hero__actions {
  margin-top: var(--space-4);
}

@media (max-width: 767px) {
  .resources-hero {
    min-height: auto;
  }
}

/* ---- MAIN LAYOUT: sidebar + content ---- */

.resources-main__layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  align-items: start;
}

@media (min-width: 900px) {
  .resources-main__layout {
    grid-template-columns: 300px 1fr;
  }
}

.resources-sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}

/* ---- Recent Guides ---- */

.resources-guides {
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  /* Tighter than the --space-4 (32px) this started with — a sidebar
     panel, secondary to the resource grid it sits beside, reads as
     secondary partly through restrained padding, not just position. */
  padding: var(--space-3);
}

.resources-guides__heading {
  font-size: var(--text-h4);
  color: var(--color-brand);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border-soft);
  margin: 0 0 var(--space-3);
}

.resources-guides__list li + li {
  margin-top: var(--space-1);
}

.resources-guides__link {
  display: inline-flex;
  align-items: center;
  /* Same tap-target fix as contact-hub__reach-link — a plain inline
     link's own box is only as tall as its text otherwise. */
  min-height: var(--tap-min);
  padding-block: var(--space-1);
  color: var(--color-brand);
  text-decoration: underline;
}

/* Empty state (PASS "Fix the Find Resources sidebars") — plain text,
   never a link to nowhere; not interactive, so no tap-target sizing. */
.resources-guides__empty {
  color: var(--color-muted);
  margin: 0;
}

/* ---- Intro ---- */

.resources-intro {
  /* Moderate section-level gap into the grid — one step down from the
     48px this started with, so "heading+description" and "grid" still
     read as two distinct beats without a gap wide enough to feel
     disconnected. */
  margin-bottom: var(--space-5);
}

.resources-intro__heading {
  font-size: var(--text-h1);
  font-weight: var(--weight-bold);
  letter-spacing: 0.04em;
  line-height: var(--leading-tight);
  text-transform: uppercase;
  color: var(--color-brand);
  /* Small, controlled gap to its own description — the two are one
     component (a page intro), not two independent blocks. */
  margin: 0 0 var(--space-2);
}

.resources-intro__body {
  font-size: var(--text-lead);
  color: var(--color-body);
  max-width: var(--measure-max);
  margin: 0;
}

.resources-situations {
  margin-top: var(--space-8);
  display: grid;
  gap: var(--space-6);
}

.resources-situation {
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border-soft);
}

.resources-situation__heading {
  margin: 0 0 var(--space-3);
  font-size: var(--text-h3);
  color: var(--color-brand);
}

.resources-situation__subheading {
  margin: var(--space-4) 0 var(--space-2);
  font-size: var(--text-h4);
}

.resources-situation__label {
  margin: var(--space-3) 0 var(--space-2);
  font-weight: 600;
}

.resources-situation ul {
  margin: 0 0 var(--space-3);
  padding-left: 1.25em;
}

.resources-faqs {
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px solid var(--color-border-soft);
}

.resources-faqs__heading {
  margin: 0 0 var(--space-2);
}

.resources-faqs__intro {
  margin: 0 0 var(--space-4);
  color: var(--color-body);
  max-width: var(--measure-max);
}

.resources-faqs__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  align-items: start;
}

@media (min-width: 700px) {
  .resources-faqs__grid {
    grid-template-columns: 1fr 1fr;
  }
}

.resources-faqs__card {
  display: grid;
  gap: var(--space-2);
}

.resources-faqs__card .card__heading {
  font-size: var(--text-h4, 1.15rem);
  margin: 0;
}

.resources-faqs__card .card__heading a {
  color: inherit;
  text-decoration: none;
}

.resources-faqs__card .card__heading a:hover,
.resources-faqs__card .card__heading a:focus-visible {
  color: var(--color-brand);
  text-decoration: underline;
}

.resources-faqs__card .btn {
  justify-self: start;
}

.resources-faqs__more {
  margin: var(--space-4) 0 0;
}

/* ---- Card grid ----
   Stitch two-column utility cards. Keep live hub titles/links.
   Gutenberg wraps each card as .wp-block-group — reset block margins
   so the grid, not WordPress default block spacing, owns the rhythm. */

.resources-grid,
.resources-content .resources-grid.wp-block-group {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  align-items: stretch;
  margin: 0;
}

@media (min-width: 700px) {
  .resources-grid,
  .resources-content .resources-grid.wp-block-group {
    grid-template-columns: 1fr 1fr;
  }
}

.resources-grid__card .card__heading {
  font-size: var(--text-h3);
  font-weight: var(--weight-bold);
  color: var(--color-brand);
  margin: 0 0 var(--space-2);
}

.resources-grid__card,
.resources-grid .wp-block-group.resources-grid__card {
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  box-shadow: none;
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
  height: 100%;
  margin: 0;
}

.resources-grid__card-top,
.resources-grid .wp-block-group.resources-grid__card-top {
  display: flex;
  gap: var(--space-2);
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  background: transparent;
  border: 0;
  box-shadow: none;
  padding: 0;
}

/* Editable Gutenberg cards: icon HTML + copy group are direct children. */
.resources-grid__card-top > .wp-block-html {
  flex-shrink: 0;
  line-height: 0;
}

.resources-grid__card-top > .resources-grid__card-copy,
.resources-grid__card-top > .wp-block-group.resources-grid__card-copy {
  min-width: 0;
  flex: 1 1 auto;
  margin: 0;
  background: transparent;
  border: 0;
  box-shadow: none;
  padding: 0;
}

.resources-grid__card-copy {
  min-width: 0;
  flex: 1 1 auto;
}

.resources-grid__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: var(--space-6);
  height: var(--space-6);
  border-radius: 50%;
  background: var(--color-brand-wash, #edeff7);
  color: var(--color-brand);
}

.resources-grid__icon svg {
  width: 22px;
  height: 22px;
}

.resources-grid__list {
  margin: var(--space-1) 0 0;
  padding-left: 1.2em;
  color: var(--color-body);
}

.resources-grid__list li + li {
  margin-top: 2px;
}

/* Card CTAs use global .btn.btn--accent.btn--block — no page-only button rules. */

/* ==========================================================================
   NEWS PAGE (home.php — see that file's own docblock for why this is
   home.php and not a page template) — structure/layout ported from the
   supplied mockup ("News & Updates - Senior Advocates"); every rule
   written fresh against tokens.css. Same "global chrome stays global"
   rule as Resources: the mockup's own nav/footer are not reproduced.

   LESSONS CARRIED FORWARD FROM THE RESOURCES PAGE BUILD (do not repeat):
   1) CSS Grid's default row-stretch + a flex child's justify-content:
      space-between together turn "one card's title/text is longer" into
      uneven dead space on its shorter row-mates. Every multi-column grid
      below gets align-items: start; every card lays out with normal
      flow and a fixed gap, never space-between across a stretched row.
   2) A component's title size has to be checked against its OWN
      available width, not inherited from a wider component's default —
      wrong-for-the-column type size is what caused most of Resources'
      cards to wrap when the reference mockup's didn't. Sizes below were
      picked and then measured against real rendered width, not assumed.
   ========================================================================== */

/* ---- Placeholder image box — stands in for every hotlinked mockup
   photo (hero, media cards, article thumbs, featured video). Flat
   colour + icon + label, never an <img>, so contrast into the hero
   scrim above it is fully controlled rather than measured against a
   photo that doesn't exist yet. ---- */

.news-img-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  width: 100%;
  height: 100%;
  background: var(--color-surface-alt);
  color: var(--color-muted);
  text-align: center;
}

.news-img-placeholder svg {
  width: 36px;
  height: 36px;
}

.news-img-placeholder span {
  font-size: var(--text-small);
  font-weight: var(--weight-semibold);
  padding-inline: var(--space-2);
}

/* ---- Hero ---- */

.news-hero {
  padding-block: calc(var(--header-height) + var(--space-6)) var(--space-4);
}

/* Unique News & Updates page: header is already in the FSE template. */
body:has(.news-page) .news-hero {
  padding-block: var(--space-6) var(--space-4);
}

.news-hero__frame {
  position: relative;
  width: 100%;
  /* Matches the mockup's own h-400/480 exactly — caught live at a
     narrower 320px: the heading wraps to 2 lines at mobile widths and
     collides with the placeholder icon anchored above it. The mockup's
     own taller figure was already the correct amount of room; not a
     value to compact. */
  height: 400px;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-card);
}

@media (min-width: 900px) {
  .news-hero__frame {
    height: 480px;
  }
}

.news-hero__photo,
.news-hero .wp-block-post-featured-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
}

.news-hero__photo img,
.news-hero .wp-block-post-featured-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.news-hero__frame:has(.wp-post-image) .news-img-placeholder {
  display: none;
}

.news-hero__image {
  position: absolute;
  inset: 0;
  /* .news-img-placeholder centres its icon+label by default — dead
     centre of this frame falls inside the scrim's flat-opaque bottom
     55% below, hiding it entirely (caught live: the first render showed
     no visible placeholder content at all). Anchoring it to the top
     instead was the first attempt, but at mobile widths the heading
     wraps to 2 lines and the bottom text block grows tall enough to
     collide with it anyway (also caught live, screenshotted) — text
     height here isn't predictable enough to reserve a safe top zone
     for a full centred icon+label. A small fixed-size tag pinned to the
     top-right corner is: it can never collide with the bottom-LEFT
     text block regardless of how tall either one gets. */
  display: block;
}

.news-hero__image span {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  display: flex;
  align-items: center;
  gap: 6px;
  padding: var(--space-1) var(--space-2);
  background: var(--color-surface);
  color: var(--color-muted);
  border-radius: var(--radius-sm);
  font-size: var(--text-small);
}

.news-hero__image > svg {
  /* The standalone icon (a sibling of the badge <span>, not inside it —
     osta_news_placeholder_image()'s shared markup) would otherwise sit
     alone in normal flow at the top-left, outside the corner badge.
     Hidden here rather than restructured: the badge text alone already
     says "photo pending" clearly, and this is the one placeholder
     instance on the page small enough that an icon isn't needed to
     read as a placeholder rather than a real photo. */
  display: none;
}

.news-hero__scrim {
  position: absolute;
  inset: 0;
  /* Flat --color-brand (not a fade) through the bottom 55% where the
     text sits — same "flat opacity through the text zone" fix the
     homepage/About hero scrims already established, simplified here
     because this is a controlled placeholder colour, not a photo: no
     measurement uncertainty, the text sits on a guaranteed-flat
     11.57:1 white-on-brand background (computed, see this pass's
     report). */
  background: linear-gradient(to top, var(--color-brand) 0%, var(--color-brand) 55%, transparent 100%);
}

.news-hero__text {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  max-width: 720px;
  padding: var(--space-4) var(--space-4) var(--space-5);
  color: var(--color-surface);
}

@media (min-width: 700px) {
  .news-hero__text {
    padding: var(--space-6);
  }
}

.news-hero__heading {
  font-size: var(--text-display);
  text-transform: uppercase;
  color: var(--color-surface);
  margin: 0 0 var(--space-2);
}

.news-hero__body {
  font-size: var(--text-lead);
  color: var(--color-surface);
  opacity: 0.92;
  margin: 0;
}

/* ---- Section rhythm ----
   Deliberately NOT the sitewide .section class here (measured live: the
   page originally used it on every section below the hero, and every
   pair of consecutive sections ended up 112–160px apart — .section pads
   BOTH its top and bottom by --space-10 (80px), so two of them stacked
   back to back double up). The mockup's own source never pads a
   section's top at all — every section after the first is pb-section-
   gap only (64px), so consecutive sections sit a single 64px apart, not
   two paddings' worth. Reproduced exactly that way here: bottom padding
   only, on the sections themselves, nothing above .news-hero (which
   keeps its own top clearance for the fixed header). */
.news-alerts,
.news-events,
.news-media,
.news-articles {
  padding-block: 0 var(--space-8);
}

/* ---- Section heading (shared by Legislative Changes / Calendar /
   Upcoming Events / Latest Articles) ---- */

.news-section-heading {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-h3);
  color: var(--color-brand);
  margin: 0 0 var(--space-3);
}

.news-section-heading svg {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
}

.news-section-heading--lg {
  font-size: var(--text-h1);
  margin-bottom: var(--space-4);
}

.news-section-heading--lg svg {
  width: 32px;
  height: 32px;
}

/* ---- Alert banner ---- */

.news-alert-banner {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  background: var(--color-brand);
  color: var(--color-surface);
  border-left: 8px solid var(--color-accent);
  border-radius: var(--radius-lg);
  /* Matches the mockup's own p-6/mb-8 (24px/32px) — was --space-4/
     --space-6 (32px/48px), measured as part of this page's own
     doubled-up section gaps (see the section-rhythm comment above). */
  padding: var(--space-3);
  margin-bottom: var(--space-4);
}

@media (min-width: 700px) {
  .news-alert-banner {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

.news-alert-banner__icon {
  flex-shrink: 0;
  color: var(--color-accent);
}

.news-alert-banner__icon svg {
  width: 40px;
  height: 40px;
}

.news-alert-banner__text {
  flex: 1 1 0;
}

.news-alert-banner__heading {
  font-size: var(--text-h4);
  color: var(--color-surface);
  margin: 0 0 var(--space-1);
}

.news-alert-banner__text p {
  color: var(--color-surface);
  opacity: 0.9;
  margin: 0;
  max-width: var(--measure-max);
}

.news-alert-banner__cta {
  flex-shrink: 0;
}

/* ---- Legislative grid ---- */

.news-legislative-grid {
  display: grid;
  grid-template-columns: 1fr;
  /* Matches the mockup's own gap-8 (32px) — was --space-6 (48px). */
  gap: var(--space-4);
  align-items: start;
}

@media (min-width: 900px) {
  .news-legislative-grid {
    grid-template-columns: 3fr 2fr;
  }
}

.news-bill-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.news-bill {
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  padding: var(--space-3);
}

.news-bill__row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-1);
}

.news-bill__title {
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  color: var(--color-ink);
  margin: 0;
}

.news-status-pill {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: var(--text-small);
  font-weight: var(--weight-bold);
  white-space: nowrap;
}

.news-status-pill--passed {
  /* Same green-surface/dark-green-text pair as the Contact page's own
     confidentiality badge — 5.02:1, documented in tokens.css. */
  background: var(--color-success-wash);
  color: var(--color-accent-ink);
}

.news-status-pill--committee {
  background: var(--color-surface-alt);
  color: var(--color-muted);
}

.news-bill__summary {
  color: var(--color-body);
  font-size: var(--text-body);
  margin: 0;
}

.news-calendar-panel {
  background: var(--color-surface-soft);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  padding: var(--space-3);
}

.news-calendar-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  /* Matches the mockup's own gap-6 (24px) — was --space-4 (32px). */
  gap: var(--space-3);
}

.news-calendar-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
}

.news-date-badge {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  min-width: 60px;
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-brand);
  font-weight: var(--weight-bold);
  font-size: var(--text-small);
  text-transform: uppercase;
}

.news-calendar-item__title {
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  color: var(--color-ink);
  margin: 0 0 2px;
}

.news-calendar-item__meta {
  font-size: var(--text-small);
  color: var(--color-muted);
  margin: 0;
}

/* ---- Upcoming Events panel ---- */

.news-events-panel {
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}

.news-events-panel__heading {
  font-size: var(--text-h3);
  border-bottom: 1px solid var(--color-border-soft);
  padding-bottom: var(--space-2);
  /* Matches the mockup's own mb-6 (24px) — was --space-4 (32px). */
  margin: 0 0 var(--space-3);
}

.news-events-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  align-items: start;
}

@media (min-width: 768px) {
  .news-events-grid {
    grid-template-columns: repeat(3, 1fr);
  }

  .news-events-col:not(:last-child) {
    border-right: 1px solid var(--color-border-soft);
    padding-right: var(--space-4);
  }
}

.news-events-col__month {
  display: block;
  color: var(--color-brand);
  font-size: var(--text-h4);
  font-weight: var(--weight-bold);
  /* Matches the mockup's own gap-2 (8px) — was --space-2 (16px). */
  margin-bottom: var(--space-1);
}

.news-events-col__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
}

.news-events-col__day {
  flex-shrink: 0;
  width: 32px;
  font-size: var(--text-lead);
  font-weight: var(--weight-bold);
  color: var(--color-muted);
}

.news-events-col__title {
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  color: var(--color-ink);
  margin: 0 0 2px;
}

.news-events-col__location {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: var(--text-small);
  color: var(--color-muted);
  margin: 0;
}

.news-events-col__location svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.news-events-col__empty {
  display: flex;
  align-items: center;
  min-height: 80px;
  font-style: italic;
  color: var(--color-muted);
  margin: 0;
}

/* ---- Media cards (Newsletter / Podcast / Video Library) ---- */

.news-media-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  /* See this file's own top comment, lesson 1 — no forced equal-height
     row here. */
  align-items: start;
}

@media (min-width: 700px) {
  .news-media-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.news-media-card {
  background: var(--color-brand);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-card);
  display: flex;
  flex-direction: column;
}

.news-media-card__image {
  height: 200px;
}

.news-media-card__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--space-4);
}

.news-media-card__icon {
  /* The token built specifically for icons/text on a navy surface —
     5.63:1, computed. */
  color: var(--color-brand-on-dark);
  margin-bottom: var(--space-2);
}

.news-media-card__icon svg {
  width: 36px;
  height: 36px;
}

.news-media-card__title {
  color: var(--color-surface);
  font-size: var(--text-h3);
  margin: 0 0 var(--space-1);
}

.news-media-card__desc {
  color: var(--color-brand-on-dark);
  font-size: var(--text-body);
  margin: 0 0 var(--space-3);
}

.news-media-card__btn {
  width: 100%;
  max-width: 220px;
}

/* ---- Divider ---- */

.news-divider {
  max-width: var(--container-max);
  /* Matches the mockup's own my-8 (32px, symmetric) — was an
     asymmetric 8px/48px. */
  margin: var(--space-4) auto;
  border: none;
  border-top: 2px solid var(--color-border-soft);
}

/* ---- Articles layout (Latest Articles + sidebar) ---- */

.news-articles__layout {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

@media (min-width: 900px) {
  .news-articles__layout {
    flex-direction: row;
    /* See this file's own top comment, lesson 1 — a flex row's default
       align-items is stretch, the same trap as grid's default; without
       this the shorter of {main column, sidebar} would be forced to
       match the taller one's height for no reason. */
    align-items: flex-start;
  }
}

.news-articles__main {
  flex: 1 1 0;
  min-width: 0;
}

.news-articles__sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  min-width: 0;
}

@media (min-width: 900px) {
  .news-articles__sidebar {
    flex: 0 0 340px;
  }
}

.news-article-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

.news-article-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: var(--space-3);
}

@media (min-width: 600px) {
  .news-article-card {
    flex-direction: row;
    align-items: flex-start;
  }
}

.news-article-card__thumb {
  display: block;
  flex-shrink: 0;
  width: 100%;
  height: 192px;
  border-radius: var(--radius-md);
  overflow: hidden;
}

@media (min-width: 600px) {
  .news-article-card__thumb {
    width: 220px;
    height: 160px;
  }
}

.news-article-card__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.news-article-card__body {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-2);
  min-width: 0;
}

.news-article-card__eyebrow {
  display: block;
  color: var(--color-brand);
  font-weight: var(--weight-semibold);
  font-size: var(--text-small);
  margin-bottom: 2px;
}

.news-article-card__title {
  font-size: var(--text-h3);
  margin: 0 0 var(--space-1);
}

.news-article-card__title a {
  color: var(--color-ink);
  text-decoration: none;
}

.news-article-card__title a:hover,
.news-article-card__title a:focus-visible {
  color: var(--color-brand);
  text-decoration: underline;
}

.news-article-card__excerpt {
  color: var(--color-body);
  font-size: var(--text-body);
  margin: 0;
}

.news-article-card__link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: fit-content;
  min-height: var(--tap-min);
  color: var(--color-brand);
  font-weight: var(--weight-semibold);
  text-decoration: underline;
}

.news-article-card__link svg {
  width: 18px;
  height: 18px;
}

.news-articles__more {
  text-align: center;
}

/* ---- Recent Episodes ---- */

.news-episodes-panel {
  background: var(--color-surface-soft);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  /* Matches the mockup's own p-6 (24px) — was --space-4 (32px). */
  padding: var(--space-3);
}

.news-episodes-panel__heading {
  font-size: var(--text-h4);
  border-bottom: 1px solid var(--color-border-soft);
  /* Matches the mockup's own pb-2 (8px) — was --space-2 (16px). */
  padding-bottom: var(--space-1);
  margin: 0 0 var(--space-3);
}

.news-episodes-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.news-episode {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-sm);
  /* Matches the mockup's own p-3 (12px) — was --space-2 (16px). No
     token sits exactly on 12px (the scale runs 8/16/24…); used the
     literal value rather than round to the nearest token and lose the
     match. */
  padding: 12px;
}

.news-episode__play {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: var(--tap-min);
  height: var(--tap-min);
  border-radius: 50%;
  background: var(--color-brand-wash);
  color: var(--color-brand);
}

.news-episode__play svg {
  width: 18px;
  height: 18px;
}

.news-episode__title {
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  color: var(--color-ink);
  margin: 0 0 2px;
}

.news-episode__meta {
  font-size: var(--text-small);
  color: var(--color-muted);
}

.news-episodes-panel__all {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap-min);
  margin-top: var(--space-2);
  color: var(--color-brand);
  font-weight: var(--weight-semibold);
  text-decoration: underline;
}

/* ---- Featured video ---- */

.news-featured-video {
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.news-featured-video__image {
  height: 192px;
}

.news-featured-video__body {
  padding: var(--space-3);
}

.news-featured-tag {
  display: inline-block;
  background: var(--color-alert-wash);
  color: var(--color-alert);
  font-size: var(--text-small);
  font-weight: var(--weight-bold);
  padding: 2px 10px;
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-1);
}

.news-featured-video__title {
  font-size: var(--text-h4);
  margin: 0;
}

@media (max-width: 767px) {
  .news-hero {
    padding-block: calc(var(--header-height) + var(--space-4)) var(--space-3);
  }
}

/* ==========================================================================
   TENANT RIGHTS PAGE — demo/staging page, structure/layout ported from
   the supplied mockup. "Global chrome stays global" per this pass's own
   instruction: the mockup's own top header/footer are NOT reproduced —
   the site's real fixed header sits above everything below, hence the
   header-height top padding on the layout wrapper. The left "Resource
   Center" sidebar IS reproduced (page-specific, not chrome).

   HEADINGS: one consistent scale throughout — text-h1 for both hero-
   style headings (the promo band, the plain-background page hero;
   the mockup itself sizes these identically, headline-xl both times),
   text-h3 for every accordion title and the two sidebar panel
   headings. No section here uses a fourth, different size — checked
   before shipping, the lesson from the About page pass.
   ========================================================================== */

.tenant-rights-layout {
  display: flex;
  flex-direction: column;
  max-width: var(--container-max);
  margin-inline: auto;
  /* FIX (flagged by a later pass's design audit): body.no-hero #main-
     content (global.css) already reserves --header-height of clearance
     for the fixed header on every page in this family. This used to
     re-add the full header height on top of that, doubling it with no
     breathing room actually intended -- corrected to just the intended
     gap below the header. */
  padding-top: var(--space-6);
}

@media (min-width: 1024px) {
  .tenant-rights-layout {
    flex-direction: row;
    align-items: flex-start;
  }
}

/* ---- Resource Center sidebar (page-specific, hidden below 1024px —
   matching the mockup's own responsive choice rather than building a
   second, separate mobile nav for the same links). ---- */

.tenant-rights-sidebar {
  display: none;
}

@media (min-width: 1024px) {
  .tenant-rights-sidebar {
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    width: 300px;
    border-right: 1px solid var(--color-border-soft);
    background: var(--color-surface-soft);
    position: sticky;
    top: var(--header-height);
    height: calc(100vh - var(--header-height));
  }
}

.tenant-rights-sidebar__nav {
  flex: 1 1 0;
  overflow-y: auto;
  padding: var(--space-2);
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.tenant-rights-sidebar__footer {
  padding: var(--space-4);
  border-top: 1px solid var(--color-border-soft);
}

/* ---- Shared "On this page" / "Other resources" sidebar blocks (PASS
   "Fix the Find Resources sidebars: real table of contents, remove
   dead nav and broken filters") — template-parts/sections/resource-
   sidebar-nav.php, reused by every page in the Find Resources family.
   Styled once here to match .tenant-rights-sidebar__link's own look
   (the sidebar this replaces) rather than duplicated per page. No
   padding/gap of their own — the .tenant-rights-sidebar__nav wrapper
   (above) already supplies both, and .resources-sidebar (Find
   Resources' own container, further below) supplies its own. ---- */

.resource-sidebar-toc__heading,
.resource-sidebar-siblings__heading {
  font-size: var(--text-h4);
  color: var(--color-brand);
  padding-inline: var(--space-2);
  margin: 0 0 4px;
}

.resource-sidebar-toc__list,
.resource-sidebar-siblings__list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.resource-sidebar-toc__link,
.resource-sidebar-siblings__link {
  display: flex;
  align-items: center;
  min-height: var(--tap-min);
  padding-inline: var(--space-2);
  border-radius: var(--radius-sm);
  color: var(--color-body);
  font-weight: var(--weight-semibold);
  text-decoration: none;
}

.resource-sidebar-toc__link:hover,
.resource-sidebar-toc__link:focus-visible,
.resource-sidebar-siblings__link:hover,
.resource-sidebar-siblings__link:focus-visible {
  background: var(--color-surface-alt);
  color: var(--color-brand);
}

.resource-sidebar-siblings__link--current {
  color: var(--color-brand);
  background: var(--color-brand-wash);
  border-left: 4px solid var(--color-brand);
  font-weight: var(--weight-bold);
}

/* Separator only when a TOC block actually precedes the siblings block
   — a page with no TOC (e.g. Find Resources, see this pass's own
   report for why) never gets an orphaned top border. */
.resource-sidebar-toc + .resource-sidebar-siblings {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border-soft);
}

/* ---- Main column ---- */

.tenant-rights-main {
  flex: 1 1 0;
  min-width: 0;
  padding: var(--space-4);
}

@media (min-width: 1024px) {
  .tenant-rights-main {
    padding: var(--space-6) var(--space-6) var(--space-8) var(--space-8);
  }
}

/* ---- Promo band (navy + photo) ---- */

.tenant-rights-promo {
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-lg);
  overflow: hidden;
  margin-bottom: var(--space-6);
  min-height: 320px;
}

@media (min-width: 700px) {
  .tenant-rights-promo {
    flex-direction: row;
  }
}

.tenant-rights-promo__copy {
  flex: 1 1 0;
  background: var(--color-brand);
  color: var(--color-surface);
  padding: var(--space-6) var(--space-4);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.tenant-rights-promo__heading {
  font-size: var(--text-h1);
  color: var(--color-surface);
  margin: 0 0 var(--space-2);
}

.tenant-rights-promo__body {
  font-size: var(--text-lead);
  color: var(--color-surface);
  opacity: 0.92;
  margin: 0;
}

.tenant-rights-promo__media {
  flex: 1 1 0;
  min-height: 220px;
}

.tenant-rights-promo__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---- Breadcrumb ---- */

.tenant-rights-breadcrumb {
  margin-bottom: var(--space-4);
}

.tenant-rights-breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  color: var(--color-muted);
}

.tenant-rights-breadcrumb a {
  /* PASS "Fix the accessibility failures found by the component
     inventory", item 3 — was 32px, explicit, under --tap-min. Its two
     sibling breadcrumbs on this same page family (.park-maint-
     breadcrumb a, .evictions-breadcrumb a) already use var(--tap-min);
     copied here. */
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  color: var(--color-muted);
  text-decoration: underline;
}

.tenant-rights-breadcrumb a:hover,
.tenant-rights-breadcrumb a:focus-visible {
  color: var(--color-brand);
}

.tenant-rights-breadcrumb li[aria-current] {
  color: var(--color-brand);
  font-weight: var(--weight-semibold);
}

/* ---- Page hero (plain background) ---- */

.tenant-rights-hero {
  margin-bottom: var(--space-6);
}

.tenant-rights-hero__heading {
  font-size: var(--text-h1);
  color: var(--color-brand);
  margin: 0 0 var(--space-3);
}

.tenant-rights-hero__body {
  font-size: var(--text-lead);
  color: var(--color-body);
  max-width: var(--measure-max);
  margin: 0;
}

/* ---- Content: accordions + info sidebar ---- */

.tenant-rights-content {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

@media (min-width: 1200px) {
  .tenant-rights-content {
    flex-direction: row;
    /* No stretch — the info sidebar must never be forced to match
       whichever accordion happens to be open's height, and vice
       versa. Same lesson as every other multi-column layout in this
       build. */
    align-items: flex-start;
  }

  .tenant-rights-accordions {
    /* Was 2:1 — measured live, that left the info column at 247px,
       too narrow for the helpline button's icon+text to fit "Call 541
       508 0404" on one line (it wrapped to 3 lines and the button
       ballooned to 154px tall). 3:2 is closer to the mockup's own
       actual sidebar proportion anyway. */
    flex: 3 1 0;
    min-width: 0;
  }

  .tenant-rights-info {
    flex: 2 1 0;
    min-width: 0;
  }
}

.tenant-rights-accordions {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.tenant-rights-accordion {
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}

.tenant-rights-accordion__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 64px;
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
  list-style: none;
  color: var(--color-brand);
  font-weight: var(--weight-bold);
}

.tenant-rights-accordion__toggle::-webkit-details-marker {
  display: none;
}

.tenant-rights-accordion__toggle:focus-visible {
  outline: 2px solid var(--color-brand);
  outline-offset: -2px;
}

.tenant-rights-accordion__title {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--text-h3);
}

.tenant-rights-accordion__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--color-brand-wash);
  color: var(--color-brand);
}

.tenant-rights-accordion__icon svg {
  width: 24px;
  height: 24px;
}

.tenant-rights-accordion__chevron {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  color: var(--color-brand);
  transition: transform 150ms;
}

@media (prefers-reduced-motion: reduce) {
  .tenant-rights-accordion__chevron {
    transition: none;
  }
}

.tenant-rights-accordion[open] > .tenant-rights-accordion__toggle .tenant-rights-accordion__chevron {
  transform: rotate(180deg);
}

.tenant-rights-accordion__body {
  padding: 0 var(--space-4) var(--space-4);
  border-top: 1px solid var(--color-border-soft);
  padding-top: var(--space-3);
  /* "On This Page" anchor target (PASS "Fix the Find Resources
     sidebars") — the id a TOC link jumps to lives here, not on the
     <details> itself (see that link's own comment in template-tenant-
     rights.php for why). scroll-margin-top clears BOTH the fixed header
     AND this card's own toggle - 96px, its real live-measured rendered
     height (min-height:64px, but its own padding pushes it taller) — without the toggle's height added in, landing
     this element flush under the header would push the card's own
     heading (which sits above it) up out of view. Same .no-js-zeroed
     pattern global.css already uses for `main` itself. */
  scroll-margin-top: calc(var(--header-height) + 96px);
}

.no-js .tenant-rights-accordion__body {
  /* Only the HEADER portion of the offset zeroes out here — with no JS
     the header isn't fixed any more (same reasoning as global.css's own
     .no-js main rule), but this card's own toggle is still ~96px tall
     and still sits above the body regardless of header state, so that
     part of the offset stays. Confirmed live: without this, a no-JS
     jump scrolled the card's own heading off-screen above the viewport
     instead of clearing it. */
  scroll-margin-top: 96px;
}

.tenant-rights-accordion__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.tenant-rights-accordion__list li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  color: var(--color-body);
}

.tenant-rights-accordion__statutes,
.tenant-rights-accordion__entitle,
.tenant-rights-accordion__violate {
  margin: 0 0 var(--space-3);
  color: var(--color-body);
}

.tenant-rights-accordion__statutes {
  font-weight: 600;
}

.tenant-rights-rights-intro,
.tenant-rights-explore {
  margin: 0 0 var(--space-4);
}

.tenant-rights-explore {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 0.5rem;
}

.tenant-rights-accordion__hubs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.15rem;
}

.tenant-rights-accordion__hub-sep {
  color: var(--color-muted, #5c6570);
}

.tenant-rights-accordion__more {
  margin: 0;
}

.tenant-rights-accordion__more-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 48px;
  font-weight: 600;
  color: var(--color-brand, #263279);
  text-decoration: none;
}

.tenant-rights-accordion__more-link:hover,
.tenant-rights-accordion__more-link:focus-visible {
  text-decoration: underline;
}

.tenant-rights-category-page {
  padding-block: var(--space-6, 48px);
}

.tenant-rights-category-page__back {
  margin: 0 0 var(--space-4, 32px);
}

.tenant-rights-category-page__back a {
  font-weight: 600;
  text-decoration: none;
}

.tenant-rights-category-page__back a:hover,
.tenant-rights-category-page__back a:focus-visible {
  text-decoration: underline;
}

.tenant-rights-category-page__article {
  max-width: 720px;
}

.tenant-rights-category-page__bullets {
  margin-bottom: var(--space-5, 40px);
}

.tenant-rights-accordion__check {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  margin-top: 2px;
  color: var(--color-brand);
}

/* ---- Info sidebar (Essential Documents + Need Immediate Help) ---- */

.tenant-rights-info {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.tenant-rights-documents {
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}

/*
 * PASS "Block theme conversion, Group 2 (Tenant Rights)" — line-height was
 * added, and .tenant-rights-documents__heading-text below is new.
 *
 * This used to be an <h3> with the icon <svg> inside it. That shape cannot
 * survive conversion with its text still editable: a heading block's text is
 * a rich-text attribute, whose parser discards any node contributing no text
 * characters, so the icon is silently deleted the first time the heading is
 * saved (the exact defect that cost Evictions four icons in Group 1). The
 * heading is therefore split — this element keeps the class and becomes the
 * flex container, with the icon and an editable <h3> as its two children.
 *
 * The <h3> was carrying its own line-height (--leading-tight) as a heading;
 * a plain container inherits --leading-body (1.70) instead, which measured
 * 44.2px against the original 29.9px and pushed the label off its baseline.
 * Restated here so the container reproduces exactly what the <h3> used to do,
 * and the inner heading inherits it back rather than either element guessing.
 */
.tenant-rights-documents__heading {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-h3);
  line-height: var(--leading-tight);
  color: var(--color-brand);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border-soft);
  margin: 0 0 var(--space-3);
}

.tenant-rights-documents__heading svg {
  width: 24px;
  height: 24px;
}

/* The editable heading inside that container — see the block comment above.
   It takes every typographic decision from the container so the split is
   invisible; only font-family and font-weight stay its own, which is what
   makes it still read as a heading. */
.tenant-rights-documents__heading-text {
  margin: 0;
  font-size: inherit;
  line-height: inherit;
  color: inherit;
}

/*
 * The promo photo. Classic emitted a bare <img>; core/image wraps it in a
 * <figure>, and the img's own `height: 100%` (immediately below) then
 * resolves against that figure instead of against .tenant-rights-promo__media
 * — which is the flex item that actually has a definite stretched height. The
 * figure has none, so the image fell back to its intrinsic ratio and rendered
 * 204px tall inside a 320px box, leaving a bare strip beside the copy.
 *
 * Same replaced-element trap as the hero images (.osta-hero-bg): a percentage
 * height needs a definite containing block, and an extra wrapper is enough to
 * remove one. Giving the figure the full height passes it straight through.
 */
.tenant-rights-promo__media .wp-block-image {
  display: block;
  height: 100%;
  margin: 0;
}

.tenant-rights-documents__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.tenant-rights-documents__item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2);
  min-height: var(--tap-min);
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  padding: var(--space-3);
}

.tenant-rights-documents__item:hover,
.tenant-rights-documents__item:focus-visible {
  border-color: var(--color-brand);
  box-shadow: var(--shadow-hover);
}

.tenant-rights-documents__item h4 {
  color: var(--color-brand);
  margin: 0 0 2px;
}

.tenant-rights-documents__item p {
  color: var(--color-muted);
  margin: 0;
}

.tenant-rights-documents__item svg {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  color: var(--color-brand);
  margin-top: 2px;
}

.tenant-rights-helpline {
  position: relative;
  background: var(--color-brand);
  color: var(--color-surface);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-4);
  overflow: hidden;
}

.tenant-rights-helpline__icon {
  position: absolute;
  top: calc(-1 * var(--space-4));
  right: calc(-1 * var(--space-4));
  opacity: 0.12;
  pointer-events: none;
}

.tenant-rights-helpline__icon svg {
  width: 150px;
  height: 150px;
}

.tenant-rights-helpline__content {
  position: relative;
  z-index: 1;
}

.tenant-rights-helpline__content h3 {
  color: var(--color-surface);
  font-size: var(--text-h3);
  margin: 0 0 var(--space-2);
}

.tenant-rights-helpline__content > p {
  color: var(--color-surface);
  opacity: 0.9;
  margin: 0 0 var(--space-4);
  /* The trailing margin this rule wants back when the last paragraph in
     this panel opts into .keep-margin-bottom — see that marker's own
     comment in global.css. Declared here, beside the margin it mirrors,
     so the two can never drift. */
  --osta-keep-margin-bottom: var(--space-4);
}

.tenant-rights-helpline__cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
}

.tenant-rights-helpline__cta svg {
  /* Caught live: this icon had no explicit size anywhere, so it fell
     back to the browser's own unstyled-SVG default (~300x150) instead
     of the global img/svg reset's max-width:100% shrinking it sensibly
     — it rendered oversized inside the button, squeezing "541 508
     0404" into a narrow column that wrapped three ways. */
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}

.tenant-rights-helpline__hours {
  /* PASS "Fix the accessibility failures found by the component
     inventory", items 2 + 5 — was --text-small (16px) at opacity: 0.75,
     which measured ~4.3:1 on the navy panel behind it, under the 4.5:1
     AA floor for normal text. Dropping the opacity instead of just
     lightening the colour reuses the exact white-on-navy pairing
     already proven elsewhere in this file (11.57:1, --color-brand) —
     no new colour introduced. */
  text-align: center;
  color: var(--color-surface);
  font-size: var(--text-body);
  margin: var(--space-3) 0 0;
}

/* ==========================================================================
   DISABILITY RIGHTS PAGE — second in the Resources sub-page family after
   Tenant Rights. Own scoped sidebar (this mockup's "Resource
   Categories" is a different, simpler component than Tenant Rights'
   "Resource Center" — different items, different design, not a shared
   component pretending otherwise).

   DEFENSIVE ICON SIZING: every inline SVG on this page gets a sane
   default (1em, i.e. it always matches its own text's font-size)
   BEFORE any more specific rule below overrides it. This is the direct
   fix for a real bug caught on the Tenant Rights page — a button icon
   there had no explicit size anywhere and fell back to the browser's
   oversized SVG default, breaking the button's layout. Setting a
   baseline here means a future icon added without its own explicit
   size still renders sensibly instead of repeating that bug.
   ========================================================================== */

.disability-rights-page svg {
  width: 1em;
  height: 1em;
  flex-shrink: 0;
}

.disability-rights-layout {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  max-width: var(--container-max);
  margin-inline: auto;
  /* FIX (flagged by a later pass's design audit): body.no-hero #main-
     content (global.css) already reserves --header-height of clearance
     for the fixed header. This used to re-add it a second time here,
     doubling the dead space above the sidebar/content -- corrected to
     just the intended gap below the header. */
  padding: var(--space-6) var(--space-4) var(--space-8);
}

@media (min-width: 768px) {
  .disability-rights-layout {
    flex-direction: row;
    align-items: flex-start;
  }
}

/* ---- Sidebar ---- */

.disability-rights-sidebar {
  flex-shrink: 0;
  width: 100%;
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: var(--space-4);
}

@media (min-width: 768px) {
  .disability-rights-sidebar {
    width: 280px;
    position: sticky;
    top: calc(var(--header-height) + var(--space-4));
  }
}

.disability-rights-sidebar__heading {
  font-size: var(--text-h4);
  color: var(--color-brand);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border-soft);
  margin: 0 0 var(--space-3);
}

.disability-rights-sidebar__nav {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.disability-rights-sidebar__link {
  display: flex;
  align-items: center;
  min-height: var(--tap-min);
  padding-inline: var(--space-2);
  border-radius: var(--radius-sm);
  color: var(--color-body);
  font-weight: var(--weight-semibold);
}

.disability-rights-sidebar__link:hover,
.disability-rights-sidebar__link:focus-visible {
  background: var(--color-surface-alt);
  color: var(--color-brand);
}

.disability-rights-sidebar__link--active {
  color: var(--color-brand);
  background: var(--color-brand-wash);
  border-left: 4px solid var(--color-brand);
  font-weight: var(--weight-bold);
}

/* ---- Main column ---- */

.disability-rights-main {
  flex: 1 1 0;
  min-width: 0;
  max-width: 760px;
}

.disability-rights-intro__heading {
  font-size: var(--text-h1);
  color: var(--color-brand);
  margin: 0 0 var(--space-3);
}

.disability-rights-intro__body {
  font-size: var(--text-lead);
  color: var(--color-body);
  margin: 0 0 var(--space-4);
}

.disability-rights-note {
  background: var(--color-surface-soft);
  border-left: 4px solid var(--color-brand);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
}

.disability-rights-note p {
  margin: 0;
  color: var(--color-body);
}

/* ---- Table of contents ---- */

.disability-rights-toc {
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  margin-top: var(--space-6);
}

.disability-rights-toc__heading {
  font-size: var(--text-small);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-muted);
  margin: 0 0 var(--space-3);
}

.disability-rights-toc__list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2);
}

@media (min-width: 560px) {
  .disability-rights-toc__list {
    grid-template-columns: 1fr 1fr;
  }
}

.disability-rights-toc__list a {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--tap-min);
  color: var(--color-brand);
  font-weight: var(--weight-semibold);
  text-decoration: underline;
}

.disability-rights-toc__list svg {
  width: 18px;
  height: 18px;
}

/* ---- Content sections ---- */

.disability-rights-sections {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  margin-top: var(--space-6);
}

.disability-rights-card {
  position: relative;
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: var(--space-5);
  /* Surface use of accent — a decorative flag on the card's own left
     edge, never text. */
  border-left: 6px solid var(--color-accent);
}

.disability-rights-card--compact {
  border-left: none;
  padding: var(--space-4);
}

.disability-rights-card p {
  color: var(--color-body);
  margin: 0 0 var(--space-3);
}

.disability-rights-card p:last-child {
  margin-bottom: 0;
}

.disability-rights-card__secondary {
  color: var(--color-muted) !important;
}

.disability-rights-card__heading {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--text-h2);
  color: var(--color-brand);
  margin: 0 0 var(--space-3);
}

.disability-rights-card__heading--sm {
  font-size: var(--text-h3);
}

.disability-rights-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--color-brand-wash);
  color: var(--color-brand);
}

.disability-rights-card__icon svg {
  width: 22px;
  height: 22px;
}

.disability-rights-card__icon--plain {
  background: none;
  width: 32px;
  height: 32px;
}

.disability-rights-card__icon--plain svg {
  width: 28px;
  height: 28px;
}

.disability-rights-examples {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

@media (min-width: 560px) {
  .disability-rights-examples {
    grid-template-columns: 1fr 1fr;
  }
}

.disability-rights-examples__item {
  background: var(--color-surface-soft);
  border-radius: var(--radius-md);
  padding: var(--space-3);
}

.disability-rights-examples__item h4 {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-ink);
  margin: 0 0 var(--space-1);
}

.disability-rights-examples__item h4 svg {
  width: 20px;
  height: 20px;
  color: var(--color-brand);
}

.disability-rights-examples__item p {
  color: var(--color-body);
  margin: 0;
}

.disability-rights-whopays {
  background: var(--color-brand-wash);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin-top: var(--space-4);
}

.disability-rights-whopays h3 {
  font-size: var(--text-h4);
  color: var(--color-brand);
  margin: 0 0 var(--space-2);
}

.disability-rights-whopays ul {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-left: 1.2em;
  list-style: disc;
}

.disability-rights-whopays li {
  color: var(--color-body);
}

.disability-rights-twocol {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

@media (min-width: 700px) {
  .disability-rights-twocol {
    grid-template-columns: 1fr 1fr;
    align-items: start;
  }
}

.disability-rights-marklist {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.disability-rights-marklist li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  color: var(--color-body);
}

.disability-rights-marklist__icon {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  margin-top: 2px;
}

.disability-rights-marklist__icon--neg {
  /* Deliberately navy, not red — red is reserved for the Filing a
     Complaint section only, per this pass's own explicit instruction. */
  color: var(--color-brand);
}

.disability-rights-marklist__icon--pos {
  /* Dark accent-ink green, the only green permitted as an icon/text
     colour — 5.52:1, same reasoning as every other checkmark on this
     site (not the lighter --color-accent, which fails the 3:1 floor a
     meaningful icon needs). */
  color: var(--color-accent-ink);
}

/* ---- How to Make a Request (dark panel) ---- */

.disability-rights-howto {
  background: var(--color-surface-dark);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.disability-rights-howto h2 {
  color: var(--color-surface);
  margin: 0 0 var(--space-5);
}

.disability-rights-howto ol {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.disability-rights-howto li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}

.disability-rights-howto h3 {
  color: var(--color-surface);
  font-size: var(--text-h4);
  margin: 0 0 4px;
}

.disability-rights-howto p {
  /* White at 0.85 opacity on --color-surface-dark — 11.16:1, computed. */
  color: var(--color-surface);
  opacity: 0.85;
  margin: 0;
}

.disability-rights-howto__number {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--color-surface);
  color: var(--color-brand);
  font-weight: var(--weight-bold);
}

/* ---- Filing a Complaint ---- */

.disability-rights-complaint {
  background: var(--color-alert-wash);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.disability-rights-complaint h2 {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-alert);
  margin: 0 0 var(--space-3);
}

.disability-rights-complaint h2 svg {
  width: 28px;
  height: 28px;
}

.disability-rights-complaint > p {
  color: var(--color-body);
  margin: 0 0 var(--space-4);
}

.disability-rights-complaint__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
}

@media (min-width: 560px) {
  .disability-rights-complaint__grid {
    grid-template-columns: 1fr 1fr;
    align-items: start;
  }
}

.disability-rights-complaint__card {
  background: var(--color-surface);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  padding: var(--space-4);
}

.disability-rights-complaint__card h3 {
  font-size: var(--text-h4);
  color: var(--color-brand);
  margin: 0 0 var(--space-2);
}

.disability-rights-complaint__card p {
  color: var(--color-body);
  margin: 0 0 var(--space-3);
}

.disability-rights-complaint__card a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--tap-min);
  color: var(--color-brand);
  font-weight: var(--weight-bold);
  text-decoration: underline;
}

.disability-rights-complaint__card a svg {
  width: 16px;
  height: 16px;
}

/*
 * PASS "Block theme conversion, Group 1 rework" — the "opens in a new tab"
 * arrow is now drawn by CSS instead of an inline <svg> inside the <a>.
 *
 * Why: these two links point at real external sites (BOLI, Fair Housing
 * Council), so their wording AND their URLs are things the client may
 * genuinely need to change — but an inline SVG cannot survive inside a
 * rich-text block, so keeping the icon in the markup meant keeping the whole
 * link locked in a raw-HTML block she cannot edit. Drawing the arrow with a
 * masked pseudo-element frees the link to be ordinary editable rich text
 * with no visual change at all.
 *
 * Not a new technique here: .disability-rights-toc__list a::before on this
 * same page already draws its arrow exactly this way. (That one, it turned
 * out, ALSO had a redundant inline copy — the classic page rendered two
 * arrows per TOC row; dropping the inline SVGs fixed that.)
 *
 * :not(:has(svg)) so any link that still carries a real inline icon is left
 * alone rather than given a second one.
 */
.disability-rights-complaint__card a:not(:has(svg))::after {
  content: "";
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/%3E%3Cpolyline points='15 3 21 3 21 9'/%3E%3Cline x1='10' y1='14' x2='21' y2='3'/%3E%3C/svg%3E") no-repeat center / 16px 16px;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/%3E%3Cpolyline points='15 3 21 3 21 9'/%3E%3Cline x1='10' y1='14' x2='21' y2='3'/%3E%3C/svg%3E") no-repeat center / 16px 16px;
}

/* ---- Closing CTA ---- */

.disability-rights-cta {
  text-align: center;
  background: var(--color-surface-alt);
  border-radius: var(--radius-lg);
  padding: var(--space-6) var(--space-4);
}

.disability-rights-cta h2 {
  color: var(--color-brand);
  margin: 0 0 var(--space-3);
}

.disability-rights-cta p {
  color: var(--color-body);
  max-width: 640px;
  margin: 0 auto var(--space-5);
}

/* ---- Block-theme conversion fixes (PASS "Block theme conversion, Group 2
   (Disability Rights)") — this page's markup now lives in post_content, so
   every element above additionally sits inside core/post-content's own
   <div class="entry-content">. Three rules there reach markup that was
   written when it never did. Every fix is scoped to this page's own
   classes; nothing shared is touched. ---- */

/* `.entry-content .list-reset { padding-left: 0 }` (global.css, 0-2-0) was
   written for STRUCTURAL grids built from <li> — it outranks
   `.disability-rights-whopays ul { padding-left: 1.2em }` (0-1-1) here, and
   this is the one list on the page that carries .list-reset AND deliberately
   opts back into real disc bullets (list-style: disc + 1.2em of room for
   them). Without the indent the markers render outside the padding box and
   the text reflows: measured live at -30.6px of section height at 1440px
   and -153px at 360px before this rule was added. Same 1.2em value as the
   original rule above, restated at (0,2,1) so it wins inside .entry-content
   too. */
.entry-content .disability-rights-whopays ul {
  padding-left: 1.2em;
}

/* SIDEBAR CONSOLIDATION (same pass): the hand-rolled
   .disability-rights-sidebar__heading + __nav + __link markup this page used
   to carry was replaced by the shared osta/resource-family-sidebar block
   (inc/resource-blocks.php -> template-parts/sections/resource-sidebar-nav.php),
   which duplicated the same nav contract. The shared block's links are
   byte-for-byte the same treatment as the old ones (measured: identical
   min-height, padding, radius, colour, weight), but its HEADING is styled
   for a sidebar that supplies its own padding — indented by --space-2, only
   4px of space beneath it, no rule below it. This page's own sidebar shell
   (kept, since it owns the padding/border/shadow/sticky behaviour the shared
   block has none of) always drew that heading flush-left with a divider
   under it. Restores the three declarations .disability-rights-sidebar__
   heading carried (padding-bottom, border-bottom, margin-bottom) and drops
   the shared block's own padding-inline back to 0, so the divider spans the
   sidebar's full inner width the way it always did. Measured after: the
   heading box is 49.1px tall at 1440px in both the old and new markup, to
   the pixel. Scoped so no other page using the shared block is affected. */
.disability-rights-sidebar .resource-sidebar-siblings__heading {
  padding-inline: 0;
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border-soft);
  margin-bottom: var(--space-3);
}

/* ==========================================================================
   PARK MAINTENANCE PAGE — third in the Resources sub-page family, after
   Tenant Rights and Disability Rights. Single-column article layout (this
   mockup's own section list never includes a categories sidebar, unlike
   the other two). Own scoped class prefix throughout, per this codebase's
   own convention.

   COLOUR MAPPING (mockup -> tokens, computed/verified in this pass's own
   report): primary #02175d -> --color-brand; primary-container/-fixed ->
   navy surfaces (--color-brand-wash, --color-surface-dark); secondary
   green -> --color-accent, surface-only, NEVER text. The mockup's own
   "Tenant Responsibilities" heading was drawn in green text — that
   violates this site's green-not-text rule and is corrected to navy here
   (.park-maint-summary__heading--brand), matching Landlord Must Maintain
   exactly rather than the mockup's own (non-compliant) choice.

   DEFENSIVE ICON SIZING — same fix as Tenant Rights/Disability Rights,
   applied proactively here from the start rather than after a bug. */

.park-maint-page svg {
  width: 1em;
  height: 1em;
  flex-shrink: 0;
}

/* PASS "Block theme conversion, Group 2" — the page-scoped
   `.park-maint-page { word-break: normal; overflow-wrap: break-word }`
   workaround that stood here is GONE, because the systemic rule it was
   working around is gone: global.css no longer sets `word-break:
   break-word` on .entry-content at all. See that rule's own comment for
   why, and for the Tenant Rights measurement that made the case.

   Group 1 scoped it to this page on purpose, on the reasoning that one
   page is not enough evidence to change a sitewide rule. Tenant Rights
   then hit the identical bug from the identical cause, which is the
   evidence that was missing.

   STILL TRUE, STILL NOT FIXED: at 360px the agency card titles genuinely
   do overflow .park-maint-agency (which is overflow:hidden), clipping the
   DEQ card's chevron — a real, PRE-EXISTING bug in the classic render,
   unchanged by any of this. It wants a proper mobile treatment of
   .park-maint-agency__toggle, not a side effect of a template
   conversion. */

.park-maint-shell {
  max-width: var(--container-max);
  margin-inline: auto;
  /* FIX (flagged by a later pass's design audit): body.no-hero #main-
     content (global.css) already reserves --header-height of clearance
     for the fixed header. This used to re-add it a second time here,
     doubling the dead space at the top of the page -- corrected to
     just the intended gap below the header. */
  padding: var(--space-6) var(--space-4) var(--space-10);
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.park-maint-breadcrumb {
  margin: 0;
}

.park-maint-breadcrumb ol {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex-wrap: wrap;
  font-size: var(--text-small);
  color: var(--color-muted);
}

/* min-height alone won't satisfy a 48px tap target on an inline text
   link that only takes up its own line-height -- it needs to actually
   be a flex box so the extra height is real, clickable area, not just
   a taller box the text sits inside doing nothing. */
.park-maint-breadcrumb a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  color: var(--color-muted);
}

.park-maint-breadcrumb a:hover,
.park-maint-breadcrumb a:focus-visible {
  color: var(--color-brand);
}

.park-maint-breadcrumb li[aria-current] {
  color: var(--color-body);
  font-weight: var(--weight-semibold);
}

/* ---- 1. Hero ---- */

.park-maint-hero {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  align-items: flex-start;
}

@media (min-width: 900px) {
  .park-maint-hero {
    flex-direction: row;
    align-items: center;
    gap: var(--space-8);
  }

  .park-maint-hero__copy {
    flex: 1 1 0;
    min-width: 0;
  }

  .park-maint-hero__media {
    flex: 1 1 0;
    min-width: 0;
  }
}

.park-maint-hero__heading {
  color: var(--color-brand);
  font-size: var(--text-h1);
  line-height: var(--leading-tight);
  margin: 0 0 var(--space-3);
}

.park-maint-hero__body {
  font-size: var(--text-lead);
  line-height: var(--leading-body);
  color: var(--color-body);
  margin: 0 0 var(--space-3);
}

.park-maint-hero__disclaimer {
  /* PASS "Fix the accessibility failures found by the component
     inventory", item 2 — was --text-small (16px). */
  font-size: var(--text-body);
  font-style: italic;
  color: var(--color-muted);
  margin: 0;
}

.park-maint-hero__media {
  width: 100%;
}

.park-maint-img-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  width: 100%;
  background: var(--color-surface-alt);
  color: var(--color-muted);
  border-radius: var(--radius-lg);
  text-align: center;
  padding: var(--space-4);
}

.park-maint-img-placeholder svg {
  width: 40px;
  height: 40px;
}

.park-maint-hero__image {
  aspect-ratio: 4 / 3;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

@media (min-width: 900px) {
  .park-maint-hero__image {
    aspect-ratio: 1 / 1;
  }
}

/* ---- 2. Two-column summary ---- */

.park-maint-summary {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  align-items: start;
}

@media (min-width: 768px) {
  .park-maint-summary {
    grid-template-columns: 1fr 1fr;
  }
}

.park-maint-summary__col {
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: var(--space-5);
}

.park-maint-summary__heading {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-h3);
  margin: 0 0 var(--space-4);
}

/* Both headings render navy — see the docblock above for why the
   mockup's own green "Tenant Responsibilities" heading is corrected
   here rather than reproduced as drawn. */
.park-maint-summary__heading--brand {
  color: var(--color-brand);
}

.park-maint-summary__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--color-brand-wash);
  color: var(--color-brand);
}

.park-maint-summary__icon svg {
  width: 20px;
  height: 20px;
}

.park-maint-summary__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.park-maint-summary__list li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
}

/* Accent green as a small foreground glyph, not a text color — uses
   --color-accent-ink (5.52:1), the only green permitted as text/icon
   foreground on a light surface (tokens.css). */
.park-maint-summary__check {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  color: var(--color-accent-ink);
  margin-top: 2px;
}

.park-maint-summary__check svg {
  width: 100%;
  height: 100%;
}

.park-maint-summary__list span > span {
  display: block;
  color: var(--color-body);
  line-height: var(--leading-snug);
}

.park-maint-summary__ref {
  /* PASS "Fix the accessibility failures found by the component
     inventory", item 2 — was --text-micro (13px), a statute citation
     — real reading content, not secondary chrome. The worst instance
     of this pattern in the codebase per the component inventory. */
  display: block;
  margin-top: 4px;
  font-size: var(--text-body);
  color: var(--color-muted);
  font-style: italic;
}

/* ---- 3. Taking Action ---- */

.park-maint-action {
  background: var(--color-brand-wash);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-6);
}

.park-maint-action__heading {
  color: var(--color-brand);
  font-size: var(--text-h3);
  margin: 0 0 var(--space-3);
}

.park-maint-action p {
  color: var(--color-ink);
  line-height: var(--leading-body);
  margin: 0 0 var(--space-3);
}

.park-maint-action p:last-child {
  margin-bottom: 0;
}

.park-maint-action__ref {
  /* PASS "Fix the accessibility failures found by the component
     inventory", item 2 — was --text-micro (13px), a statute citation. */
  display: inline-block;
  font-size: var(--text-body);
  color: var(--color-muted);
  font-style: italic;
  white-space: nowrap;
}

/* ---- 4. Where to File a Complaint ---- */

.park-maint-complaints__heading {
  color: var(--color-brand);
  font-size: var(--text-h2);
  margin: 0 0 var(--space-2);
}

.park-maint-complaints__intro {
  color: var(--color-body);
  font-size: var(--text-lead);
  max-width: var(--measure-max);
  margin: 0 0 var(--space-5);
}

.park-maint-complaints__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  align-items: start;
}

@media (min-width: 768px) {
  .park-maint-complaints__grid {
    grid-template-columns: 1fr 1fr;
  }

  .park-maint-agency--wide {
    grid-column: 1 / -1;
  }
}

.park-maint-agency {
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}

.park-maint-agency--wide {
  border-color: var(--color-brand);
}

.park-maint-agency__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 64px;
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
  list-style: none;
  color: var(--color-brand);
  font-weight: var(--weight-bold);
}

.park-maint-agency__toggle::-webkit-details-marker {
  display: none;
}

.park-maint-agency__toggle:focus-visible {
  outline: 2px solid var(--color-brand);
  outline-offset: -2px;
}

.park-maint-agency__title {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--text-h4);
}

.park-maint-agency__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--color-brand-wash);
  color: var(--color-brand);
}

.park-maint-agency__icon svg {
  width: 22px;
  height: 22px;
}

/* DEQ's icon backer only — accent green used strictly as a SURFACE
   (a colored circle) with the required dark foreground on top
   (--color-accent-on, 8.89:1), never as text. */
.park-maint-agency__icon--accent {
  background: var(--color-accent);
  color: var(--color-accent-on);
}

.park-maint-agency__chevron {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  color: var(--color-brand);
  transition: transform 150ms;
}

@media (prefers-reduced-motion: reduce) {
  .park-maint-agency__chevron {
    transition: none;
  }
}

.park-maint-agency[open] > .park-maint-agency__toggle .park-maint-agency__chevron {
  transform: rotate(180deg);
}

.park-maint-agency__body {
  padding: 0 var(--space-4) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  align-items: flex-start;
}

.park-maint-agency__body p {
  color: var(--color-body);
  line-height: var(--leading-body);
  margin: 0;
}

.park-maint-agency__phone {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: var(--text-h4);
  font-weight: var(--weight-bold);
  color: var(--color-brand);
  margin: 0;
}

.park-maint-agency__phone a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  color: inherit;
}

.park-maint-agency__phone-note {
  font-size: var(--text-small);
  font-weight: var(--weight-regular);
  color: var(--color-muted);
}

/* ---- 5. FAQ ---- */

.park-maint-faq__heading {
  color: var(--color-brand);
  font-size: var(--text-h2);
  margin: 0 0 var(--space-5);
}

.park-maint-faq__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.park-maint-faq__item {
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.park-maint-faq__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 64px;
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
  list-style: none;
  color: var(--color-ink);
  font-weight: var(--weight-semibold);
  font-size: var(--text-h4);
}

.park-maint-faq__toggle::-webkit-details-marker {
  display: none;
}

.park-maint-faq__toggle:focus-visible {
  outline: 2px solid var(--color-brand);
  outline-offset: -2px;
}

.park-maint-faq__chevron {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  color: var(--color-brand);
  transition: transform 150ms;
}

@media (prefers-reduced-motion: reduce) {
  .park-maint-faq__chevron {
    transition: none;
  }
}

.park-maint-faq__item[open] > .park-maint-faq__toggle .park-maint-faq__chevron {
  transform: rotate(180deg);
}

.park-maint-faq__body {
  padding: 0 var(--space-4) var(--space-4);
}

.park-maint-faq__body p {
  color: var(--color-body);
  line-height: var(--leading-body);
  margin: 0;
}

.park-maint-faq__ref {
  /* PASS "Fix the accessibility failures found by the component
     inventory", item 2 — was --text-micro (13px), a statute citation. */
  display: inline-block;
  font-size: var(--text-body);
  color: var(--color-muted);
  font-style: italic;
  white-space: nowrap;
}

/* ---- 6. Closing CTA ----
   Navy panel: white text on --color-brand (#263279) is 11.57:1 — the
   same pairing tokens.css already documents as safe (contrast is
   symmetric with brand-on-white), verified again in this pass's own
   report. */

.park-maint-cta {
  text-align: center;
  background: var(--color-brand);
  border-radius: var(--radius-lg);
  padding: var(--space-6) var(--space-4);
}

.park-maint-cta__heading {
  color: var(--color-surface);
  margin: 0 0 var(--space-3);
}

.park-maint-cta__body {
  color: var(--color-brand-on-dark);
  max-width: 640px;
  margin: 0 auto var(--space-5);
}

/* PASS "Block theme conversion, Group 1" (Park Maintenance) — BLOCK
   EDITOR ONLY, and a no-op on the front end.

   theme.json's own styles.blocks."core/paragraph".color.text is emitted
   by WordPress as `:root :where(p){color: var(--wp--preset--color--body,
   #363B4A)}` — an unscoped ELEMENT selector at (0,1,0), the same
   specificity as every single-class colour rule in this file. On the
   front end inner-pages.css loads after that inline global-styles block,
   so the rule above wins the tie and this paragraph stays light on the
   navy panel (verified live: computed colour identical before and after
   this page's conversion). Inside the editor canvas the two are loaded
   in the OTHER order, so WordPress's rule won instead and the CTA copy
   rendered near-black on navy — 1.34:1, unreadable — in the client's own
   editing preview. One extra class lifts this to (0,2,0) so it wins in
   both places, with the same value it already had.

   SAME ROOT CAUSE, NOT FIXED HERE (flagged in this pass's report
   instead, because the fix belongs in theme.json or the footer's own
   rules, not in a page-scoped file): that WordPress rule also lands on
   the SITE FOOTER's own unclassed paragraphs on every page that contains
   a core/paragraph block — already live on /about/ and /contact/ from
   this same conversion group, and now here — turning them from white to
   #363B4A on the navy footer. */
.park-maint-cta .park-maint-cta__body {
  color: var(--color-brand-on-dark);
}

/* ==========================================================================
   EVICTIONS PAGE — fourth in the Resources sub-page family. Single-column
   article layout, own scoped class prefix, defensive SVG sizing baseline
   proactively included as established by this page family's own convention.

   COLOUR MAPPING (mockup -> tokens, verified in this pass's own report):
   primary #02175d -> --color-brand; primary-fixed (the Safe Harbor box) ->
   --color-brand-wash; secondary green (lock icon, bullet icons, "Join Now
   to Unlock") -> --color-accent, surface-only. The mockup's own "Join Now
   to Unlock" button used WHITE text on the green surface, which fails
   contrast (2.10:1) -- corrected here to the site's existing --color-
   accent-on navy text on the same green surface (.btn--accent, already
   8.89:1 sitewide), same prominent spot, same green surface. */

.evictions-page svg {
  width: 1em;
  height: 1em;
  flex-shrink: 0;
}

.evictions-shell {
  max-width: var(--container-max);
  margin-inline: auto;
  /* FIX (design audit): body.no-hero #main-content (global.css) already
     reserves --header-height of clearance for the fixed header on every
     page in this family. This used to re-add the full header height a
     second time here -- ~64px of pure dead space logged out, ~96px
     logged in as admin (the admin bar adds its own clearance to that
     same global rule) -- corrected to just the intended gap below the
     header. Section-to-section gap also tightened from --space-8 (64px)
     to --space-6 (48px): six stacked sections at 64px apart read as
     sparse/unfinished rather than deliberately spacious. */
  padding: var(--space-6) var(--space-4) var(--space-10);
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.evictions-breadcrumb {
  margin: 0;
}

.evictions-breadcrumb ol {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex-wrap: wrap;
  font-size: var(--text-small);
  color: var(--color-muted);
}

.evictions-breadcrumb a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  color: var(--color-muted);
}

.evictions-breadcrumb a:hover,
.evictions-breadcrumb a:focus-visible {
  color: var(--color-brand);
}

.evictions-breadcrumb li[aria-current] {
  color: var(--color-body);
  font-weight: var(--weight-semibold);
}

/* ---- 1. Hero ---- */

.evictions-hero {
  text-align: center;
}

.evictions-hero__heading {
  color: var(--color-brand);
  font-size: var(--text-h1);
  line-height: var(--leading-tight);
  margin: 0 0 var(--space-3);
}

.evictions-hero__body {
  font-size: var(--text-lead);
  line-height: var(--leading-body);
  color: var(--color-body);
  max-width: var(--measure-max);
  margin: 0 auto;
}

/* ---- 2. Info callout ----
   FIX (design audit): was plain white + a thin border, which read as
   just another card rather than a highlighted notice. This is the
   site's own sanctioned "info" pairing (tokens.css: "Info ... reuse
   existing tokens -- --color-brand/-wash for info"), the same tinted-
   panel treatment already used for Safe Harbor just below it and for
   Park Maintenance's "Taking Action" panel -- a real highlighted card,
   not a look-alike. */

.evictions-callout {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  background: var(--color-brand-wash);
  border: 1px solid var(--color-brand);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.evictions-callout__icon {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  color: var(--color-brand);
  margin-top: 2px;
}

.evictions-callout__icon svg {
  width: 100%;
  height: 100%;
}

.evictions-callout p {
  font-size: var(--text-lead);
  line-height: var(--leading-body);
  color: var(--color-ink);
  margin: 0;
}

/* ---- 3. Step-by-step timeline ---- */

.evictions-timeline__heading {
  color: var(--color-brand);
  font-size: var(--text-h2);
  margin: 0 0 var(--space-5);
}

/* FIX (design audit): the mockup's own 2-col grid with steps 5 and 6
   forced to span both columns produced four squarish cards followed by
   two long skinny bars -- an inconsistent shape mid-page that read as
   unfinished rather than deliberate. Rebuilt as a true 3-column x
   2-row grid at desktop: all six cards the same size, nothing spans,
   nothing floats half off a corner. */
.evictions-timeline__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  align-items: stretch;
}

@media (min-width: 640px) {
  .evictions-timeline__grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (min-width: 1000px) {
  .evictions-timeline__grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.evictions-timeline__card {
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: var(--space-4);
}

.evictions-timeline__card--tinted {
  background: var(--color-surface-soft);
}

/* FIX (design audit): the numbered badge used to be an absolutely-
   positioned circle overlapping the card's top-left corner -- clipped
   awkwardly against the card's own rounded corner at real render sizes
   and read as misaligned rather than deliberate. Moved inline, in the
   same row as the icon and heading, so there's nothing to mis-align:
   number, icon, and title all sit on one baseline. */
.evictions-timeline__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--color-brand);
  color: var(--color-surface);
  font-weight: var(--weight-bold);
  font-size: var(--text-small);
}

.evictions-timeline__card-heading {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-brand);
  font-size: var(--text-h4);
  margin: 0 0 var(--space-2);
}

.evictions-timeline__card-heading svg {
  width: 22px;
  height: 22px;
}

.evictions-timeline__card p {
  color: var(--color-body);
  line-height: var(--leading-body);
  margin: 0;
}

/* ---- 4. Safe Harbor Provision ---- */

.evictions-safeharbor {
  background: var(--color-brand-wash);
  border: 1px solid var(--color-brand);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}

.evictions-safeharbor__heading {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--color-brand);
  font-size: var(--text-h2);
  margin: 0 0 var(--space-3);
}

.evictions-safeharbor__heading svg {
  width: 32px;
  height: 32px;
}

.evictions-safeharbor__intro {
  color: var(--color-ink);
  font-size: var(--text-body);
  margin: 0 0 var(--space-4);
}

.evictions-safeharbor__steps {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.evictions-safeharbor__step {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}

.evictions-safeharbor__check {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  color: var(--color-brand);
  margin-top: 2px;
}

.evictions-safeharbor__check svg {
  width: 100%;
  height: 100%;
}

.evictions-safeharbor__step strong {
  display: block;
  font-size: var(--text-lead);
  color: var(--color-ink);
  margin-bottom: 2px;
}

.evictions-safeharbor__step p {
  color: var(--color-body);
  margin: 0;
}

/* ---- 5. Legal definitions ---- */

.evictions-definitions__heading {
  color: var(--color-brand);
  font-size: var(--text-h2);
  margin: 0 0 var(--space-5);
}

.evictions-definitions__list {
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-surface);
}

.evictions-definitions__item {
  border-bottom: 1px solid var(--color-border-soft);
}

.evictions-definitions__item:last-child {
  border-bottom: none;
}

.evictions-definitions__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 64px;
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
  list-style: none;
  color: var(--color-brand);
  font-weight: var(--weight-semibold);
  font-size: var(--text-h4);
}

.evictions-definitions__toggle::-webkit-details-marker {
  display: none;
}

.evictions-definitions__toggle:focus-visible {
  outline: 2px solid var(--color-brand);
  outline-offset: -2px;
}

.evictions-definitions__chevron {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  color: var(--color-muted);
  transition: transform 150ms;
}

@media (prefers-reduced-motion: reduce) {
  .evictions-definitions__chevron {
    transition: none;
  }
}

.evictions-definitions__item[open] > .evictions-definitions__toggle .evictions-definitions__chevron {
  transform: rotate(180deg);
}

.evictions-definitions__body {
  padding: 0 var(--space-4) var(--space-4);
}

.evictions-definitions__body p {
  color: var(--color-body);
  line-height: var(--leading-body);
  margin: 0;
}

/* ---- 6. Need Legal Help CTA ---- */

.evictions-legalhelp {
  text-align: center;
  background: var(--color-surface-alt);
  border-radius: var(--radius-lg);
  padding: var(--space-6) var(--space-4);
}

.evictions-legalhelp__heading {
  color: var(--color-brand);
  margin: 0 0 var(--space-3);
}

.evictions-legalhelp__body {
  color: var(--color-body);
  max-width: 640px;
  margin: 0 auto var(--space-5);
}

.evictions-legalhelp__links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-6);
}

.evictions-legalhelp__links a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  padding-inline: var(--space-1);
  color: var(--color-brand);
  font-weight: var(--weight-semibold);
}

.evictions-legalhelp__links a:hover,
.evictions-legalhelp__links a:focus-visible {
  text-decoration: underline;
}

.evictions-legalhelp__sep {
  color: var(--color-border);
}

/* ---- 7. Members-only teaser ---- */

.evictions-members {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  background: var(--color-success-wash);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg);
  padding: var(--space-8) var(--space-4);
}

.evictions-members__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  color: var(--color-accent-ink);
  margin-bottom: var(--space-3);
}

.evictions-members__icon svg {
  width: 100%;
  height: 100%;
}

.evictions-members__heading {
  color: var(--color-brand);
  margin: 0 0 var(--space-5);
}

.evictions-members__list {
  display: inline-flex;
  flex-direction: column;
  gap: var(--space-3);
  text-align: left;
  margin: 0 0 var(--space-6);
}

.evictions-members__list li {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--text-lead);
  color: var(--color-body);
}

.evictions-members__list li span {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  color: var(--color-accent-ink);
}

/*
 * PASS "Block theme conversion, Group 1 rework" — each item's words are now
 * a real editable paragraph instead of a bare text node, so that the client
 * can edit them without the icon beside them being destroyed (an inline SVG
 * cannot survive inside a rich-text block attribute, which is exactly how
 * these three icons were silently lost once and had to be restored).
 *
 * A <p> brings two things the bare text node never had: the sitewide
 * paragraph bottom margin, and theme.json's explicit 18px core/paragraph
 * font-size, which overrode the --text-lead size this list sets on its own
 * <li>. Both are cancelled here so the rendered result is identical to the
 * original text node — measured, not assumed.
 */
.evictions-members__list li > p {
  margin: 0;
  font-size: inherit;
  line-height: inherit;
}

.evictions-members__list li svg {
  width: 100%;
  height: 100%;
}

.evictions-members__button {
  gap: var(--space-2);
}

.evictions-members__button svg {
  width: 20px;
  height: 20px;
}

/*
 * PASS "Block theme conversion, Group 2 (Evictions)" — an EDITOR-CANVAS
 * fix with no front-end effect at all, verified by pixel diff before and
 * after adding it. Both of these icon spans size themselves with a plain
 * width/height (24px/28px above) and rely on being a FLEX ITEM of their
 * section (.evictions-callout / .evictions-safeharbor__step, both
 * display:flex) for that to take effect — a flex item is blockified, so
 * width/height apply. On the front end that is exactly what happens, and
 * it is unchanged by this rule (a flex item's `display` is blockified,
 * so `inline-flex` here computes to `flex`, and the icon's own
 * `svg { width:100%; height:100% }` resolves against the same 24/28px
 * box either way — measured, not assumed).
 *
 * In the BLOCK EDITOR the relationship is broken: Gutenberg wraps every
 * block in its own `<div class="wp-block …">`, so each span sits inside
 * that wrapper instead of being a direct child of the section, is no
 * longer a flex item, stays `display: inline`, and drops its width and
 * height entirely — the SVG then fills the whole column. Confirmed live
 * in the editor canvas: the callout "i" and both Safe Harbor check marks
 * rendered several times their real size, while .evictions-members__icon
 * — which already declares display:inline-flex two rules above, for its
 * own centring — rendered correctly at 56px in the same canvas. This
 * just gives the other two icons the same self-sufficient sizing.
 */
.evictions-callout__icon,
.evictions-safeharbor__check {
  display: inline-flex;
}

/*
 * PASS "Block theme conversion, Group 2 (Evictions)" — the FIRST-CHILD
 * counterpart to global.css's own .keep-margin/.keep-margin-bottom pair,
 * and a case neither of them covers. Two icon spans on this page carry
 * their own deliberate `margin-top: 2px` (the optical nudge that lines
 * a 28px/24px icon up with the cap-height of the text beside it):
 * .evictions-callout__icon and .evictions-safeharbor__check, both
 * above. Each is the FIRST child of its section's Group block, so two
 * separate rules zero it once this page renders as blocks:
 *   1. .osta-frame.wp-block-group.is-layout-flow > *:not(.keep-margin)
 *      (global.css, 0,3,0) — answered the established way, by adding
 *      .keep-margin to both spans in post_content.
 *   2. WordPress core's own
 *        :root :where(.is-layout-flow) > :first-child {
 *          margin-block-start: 0;
 *        }
 *      (0,2,0 — :root and :first-child each count, :where() is free),
 *      printed inline by the block-layout support. .keep-margin does
 *      nothing about this one, and it still outranks each span's own
 *      single-class rule (0,1,0).
 * Measured, not assumed: both icons rendered 2px high against the
 * classic PHP output until this rule went in (a 302px + 2x116px pixel
 * delta on an otherwise height-identical page).
 *
 * (0,2,0) ties core's rule exactly; inner-pages.css is a real <link>
 * enqueued with osta-global as a dependency and always lands after the
 * inline layout styles in <head>, so the tie resolves here on order —
 * verified live rather than assumed. Scoped to .evictions-page so it
 * reaches nothing else.
 *
 * FLAGGED FOR CENTRAL REVIEW (not fixed here): systemic, same family as
 * the five fixes already in global.css. Any converted page whose section
 * begins with an element that sets its own margin-top needs this, and
 * .keep-margin alone is not enough — a "keep-margin-first-child" shape
 * (or extending .keep-margin's rule to also re-assert the value) belongs
 * in global.css, which this pass deliberately does not touch.
 */
.evictions-page .evictions-callout__icon,
.evictions-page .evictions-safeharbor__check {
  margin-top: 2px;
}

/* --------------------------------------------------------------------------
 * PASS "Block theme conversion, Group 2 rework (Evictions)" — DEFECT 2.
 *
 * Twelve core/html blocks on this page were holding real, client-owned
 * copy (six timeline card headings, the Safe Harbor heading, the
 * breadcrumb, the legal-help links and CTA, the members list and its
 * Join button) where the editor could not reach it. Every one of them is
 * now a real block. Two structural consequences needed CSS, both because
 * of the SAME hard constraint:
 *
 *   core/heading, core/paragraph and core/list-item store their text as
 *   `source: rich-text`, and rich-text's parser keeps only nodes that
 *   contribute text CHARACTERS. An inline <svg> contributes none, so it
 *   is silently destroyed on the first save — the heading would come
 *   back without its icon and nobody would be told. The icon therefore
 *   cannot stay inside the element whose text we are making editable.
 *
 * 1. THE TWO ICON+TEXT HEADINGS (timeline cards, Safe Harbor). These
 *    were `<h3>`/`<h2>` that were THEMSELVES the flex row holding the
 *    step badge, the icon and the words. Splitting the icon out into its
 *    own sibling wp:html block (this codebase's established pattern for
 *    a decorative icon) means the flex row can no longer BE the heading
 *    — it has to be a parent of it. So each heading gained a Group
 *    wrapper that now carries the row, and the heading keeps its own
 *    class, element type and level exactly as before.
 *
 *    The wrapper takes over the three declarations that were positional
 *    rather than typographic (display/align-items/gap) plus the
 *    margin-bottom that used to separate the heading from the body copy
 *    below it; the heading keeps everything typographic (colour,
 *    font-size) from its own existing rules above, and has its margin
 *    zeroed so that margin is not applied twice, once inside the row and
 *    once below it. Values are copied verbatim from the heading rules
 *    above — nothing was redesigned.
 *
 *    The `svg` sizing rules have to be restated here for a concrete
 *    reason, not for symmetry: the existing ones are
 *    `.evictions-timeline__card-heading svg` and
 *    `.evictions-safeharbor__heading svg`, DESCENDANT selectors that
 *    stopped matching the moment the icon moved out of the heading. With
 *    nothing else matching, both icons fell back to this file's own
 *    `.evictions-page svg { width: 1em; height: 1em }` and rendered at
 *    18px instead of 22px/32px — measured live, not predicted. Same
 *    (0,1,1) specificity as that fallback, and later in this file, so
 *    they win on order (this file's existing Evictions rules already
 *    rely on that same ordering).
 * -------------------------------------------------------------------------- */
/*
 *    `color` is on the wrapper for a reason that only shows up in a
 *    pixel diff: both icons draw with stroke="currentColor", and inside
 *    the heading they inherited the heading's own navy
 *    (--color-brand). Out in a plain wrapper they inherited the
 *    section's body grey instead and rendered rgb(54,59,74) where they
 *    used to be rgb(38,50,121) — the ONLY residual delta left on this
 *    page after the layout rules above, caught by diffing the icon
 *    pixels rather than the page height (the height was already
 *    identical). Declared on the wrapper, not the svg, so the row as a
 *    whole carries the heading colour it always effectively had; both
 *    the heading and the step badge set their own colour and are
 *    unaffected.
 */
/*
 *    `line-height` is here for the same "inherited from the heading"
 *    reason as `color`, and was the very last delta left on this page.
 *    The step badge sets its own font-size (16px) but NOT its own
 *    line-height, so inside the <h3> it inherited --leading-tight (18.4px
 *    at 16px) and in a plain wrapper it inherited body leading (27.2px).
 *    The badge is a 28px circle centring its digit with
 *    `align-items: center`, so a taller inner line box moves the glyph:
 *    measured at exactly 0.390625px higher, which is invisible to the eye
 *    but showed up as 244 differing pixels across the three second-row
 *    badges in the page's pixel diff. --leading-tight is what
 *    global.css's own `h1,h2,h3,h4` rule was supplying, restated here.
 */
.evictions-timeline__card-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-2);
  color: var(--color-brand);
  line-height: var(--leading-tight);
}

.evictions-timeline__card-head .evictions-timeline__card-heading {
  margin: 0;
}

.evictions-timeline__card-head svg {
  width: 22px;
  height: 22px;
}

/*
 * PASS "Block theme conversion, Group 1 rework" — EDITOR-CANVAS ONLY, and
 * inert on the front end where .block-editor-block-list__block does not
 * exist (verified by pixel diff, not assumed).
 *
 * These heads are a flex row: number badge, icon, then the heading. The
 * badge and icon are decorative, so they live in a wp:html block while the
 * heading stays a real editable core/heading. On the front end the two
 * spans are direct flex children of the head and lay out in the row as
 * intended. In the canvas Gutenberg wraps that wp:html in its own block
 * div, which becomes a single 28px-wide flex item — so the badge and icon
 * stacked vertically inside it and the head grew to 50px instead of 24px,
 * visibly unlike the published page.
 *
 * display: contents removes that wrapper from layout without removing the
 * block, so its children participate in the head's flex row exactly as they
 * do on the front end. Same treatment for the Safe Harbor head, which has
 * the identical shape.
 */
.evictions-timeline__card-head .block-editor-block-list__block.wp-block-html,
.evictions-safeharbor__head .block-editor-block-list__block.wp-block-html {
  display: contents;
}

.evictions-safeharbor__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: 0 0 var(--space-3);
  color: var(--color-brand);
}

.evictions-safeharbor__head .evictions-safeharbor__heading {
  margin: 0;
}

.evictions-safeharbor__head svg {
  width: 32px;
  height: 32px;
}

/*
 * 2. THE TWO ICONS THAT HAVE NOWHERE TO BE A SIBLING. The members-only
 *    teaser's three benefit rows and its "Join Now to Unlock" button are
 *    the two places on this page where the icon-splitting pattern above
 *    is simply not available:
 *
 *      - A benefit row is an <li>. core/list-item takes no inner blocks
 *        except a nested list, so there is no sibling slot inside the
 *        item to put a wp:html icon in. Keeping the icon in the <li>'s
 *        rich text destroys it (see the top of this comment); dropping
 *        the <ul> for a stack of paragraphs would throw away the real
 *        list semantics three benefits deserve.
 *      - The button is osta/resource-link, which renders a leaf
 *        <a>text</a> and has no icon slot at all. It is used here rather
 *        than a hand-written <a> precisely so that /membership-levels/
 *        moving can never rot this link, and so the client owns the
 *        wording.
 *
 *    Both icons are therefore rendered as pseudo-elements, which this is
 *    a legitimate use of: they are decorative, fixed, positional and
 *    were already aria-hidden — nothing a client would ever edit, which
 *    is the same reasoning that leaves every OTHER icon on this page in
 *    a wp:html block. `mask` + `background-color: currentColor` is used
 *    rather than a background-image so the glyphs keep INHERITING their
 *    colour exactly as `stroke="currentColor"` did (--color-accent-ink
 *    on the list, .btn--accent's own text colour on the button); a
 *    background-image would have had to hard-code both.
 *
 *    Geometry is carried over unchanged: 24x24 (matching the old
 *    `li span` box, with `flex-shrink: 0` so it survives a narrow
 *    column) and 20x20 (matching `.evictions-members__button svg`); the
 *    source viewBox is 0 0 24 24 in both cases and `mask-size: contain`
 *    reproduces the same scale, so stroke weights render identically.
 *    A pseudo-element on a flex container becomes a flex item, so each
 *    one lands in exactly the slot its <span> used to occupy, under the
 *    same `gap`.
 *
 *    The paths are byte-for-byte the ones previously inline in
 *    post_content; `stroke='black'` replaces `stroke="currentColor"`
 *    only because a mask cares about alpha, not colour.
 */
.evictions-members__list li::before {
  content: "";
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  background-color: currentColor;
  color: var(--color-accent-ink);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
}

.evictions-members__list li:nth-child(1)::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z'/%3E%3Cpolyline points='14 2 14 8 20 8'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z'/%3E%3Cpolyline points='14 2 14 8 20 8'/%3E%3C/svg%3E");
}

.evictions-members__list li:nth-child(2)::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 2a5 5 0 0 0-5 5v2a5 5 0 0 0 10 0V7a5 5 0 0 0-5-5z'/%3E%3Cpath d='M6 13a6 6 0 0 0-4 5.66V21h8'/%3E%3Cpath d='M14 13a6 6 0 0 1 4 5.66V21'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 2a5 5 0 0 0-5 5v2a5 5 0 0 0 10 0V7a5 5 0 0 0-5-5z'/%3E%3Cpath d='M6 13a6 6 0 0 0-4 5.66V21h8'/%3E%3Cpath d='M14 13a6 6 0 0 1 4 5.66V21'/%3E%3C/svg%3E");
}

.evictions-members__list li:nth-child(3)::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='3' width='18' height='18' rx='2'/%3E%3Cline x1='8' y1='17' x2='8' y2='11'/%3E%3Cline x1='12' y1='17' x2='12' y2='7'/%3E%3Cline x1='16' y1='17' x2='16' y2='13'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='3' width='18' height='18' rx='2'/%3E%3Cline x1='8' y1='17' x2='8' y2='11'/%3E%3Cline x1='12' y1='17' x2='12' y2='7'/%3E%3Cline x1='16' y1='17' x2='16' y2='13'/%3E%3C/svg%3E");
}

.evictions-members__button::before {
  content: "";
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='11' width='16' height='10' rx='2'/%3E%3Cpath d='M8 11V7a4 4 0 0 1 7-2.65'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='11' width='16' height='10' rx='2'/%3E%3Cpath d='M8 11V7a4 4 0 0 1 7-2.65'/%3E%3C/svg%3E");
}

/* ---- Notifications: type filter + pagination (item 4) —
   template-notifications.php. Both plain GET-form/link controls, no JS;
   these two classes are spacing-only wrappers around already-styled
   elements (.form-field, .card__footer, .btn), same discipline as the
   board Audit Log's own filter form (no bespoke input styling here
   either). */
.osta-notifications-filter {
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border-soft);
}

.osta-notifications-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

/* ==========================================================================
   RESOURCE DIRECTORY PAGE — PASS "Resource Directory page" (approved-
   design revision; replaces the old "Support Hotlines" Find Resources
   card, which pointed at the Contact page — there was never a separate
   hotlines page). Reuses .card, .btn/.btn--accent/.btn--on-dark/.btn--
   block, .container/.container--narrow, .alert, and the general contact
   form's own .contact-form__ / .form-field / .form-error / .form-hint /
   .form-required styling (the mail form reuses those field styles as-is).

   SPACING DISCIPLINE (fixed after a design review of the first build
   found "extra space between sections" and no consistent rhythm): every
   section below manages its OWN padding-block fully, never combined
   with the shared .section class — same discipline .contact-hero/
   .contact-hub/.resources-hero already use elsewhere in this file. The
   earlier draft put the .section class AND a competing padding-top
   override on the same element in two places, which silently stacked
   .section's own 80px top+bottom with this file's own values and
   produced exactly the oversized gaps that review caught. No element
   below carries the plain .section class for that reason.

   NO CATEGORY FILTER CHIPS: see the template's own top docblock — built,
   verified working, removed after design review as more friction than
   help (every card already shows all three categories at once).
   ========================================================================== */

/* ---- Heading + intro — left-aligned, plain text on the page's own
   default background, NOT a dark hero band. Uses the same .container
   (not .container--narrow) as the helpline/grid below it, so the
   heading's own left edge lines up with everything under it — a
   centered narrow column here (the first build's own choice) orphaned
   itself against the full-width content below and read as misaligned;
   design review feedback on the live page. ---- */
.resource-directory-intro {
  padding-block: calc(var(--header-height) + var(--space-8)) var(--space-6);
}

.resource-directory-intro__heading {
  margin: 0 0 var(--space-3);
}

.resource-directory-intro__body {
  max-width: var(--measure-max);
  color: var(--color-body);
  font-size: var(--text-lead);
}

@media (max-width: 767px) {
  .resource-directory-intro {
    padding-top: calc(var(--header-height) + var(--space-6));
  }
}

.resource-directory-main {
  padding-bottom: var(--space-8);
}

/* ---- OSTA's own helpline — same exact pattern as .tenant-rights-
   helpline (that component's own docblock explains the visual choices);
   full-width band here rather than a sidebar widget, since this page
   has no sidebar and this block must read as the FIRST thing under the
   intro, above every county card — never buried among third-party
   agencies (this pass's own explicit instruction). ---- */
.resource-directory-helpline {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  position: relative;
  background: var(--color-brand);
  color: var(--color-surface);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-4);
  overflow: hidden;
  margin-bottom: var(--space-6);
}

.resource-directory-helpline__icon {
  flex-shrink: 0;
  opacity: 0.85;
}

.resource-directory-helpline__icon svg {
  width: 48px;
  height: 48px;
}

.resource-directory-helpline__content h2 {
  color: var(--color-surface);
  font-size: var(--text-h3);
  margin: 0 0 var(--space-2);
}

.resource-directory-helpline__content > p {
  color: var(--color-surface);
  opacity: 0.9;
  margin: 0 0 var(--space-3);
}

.resource-directory-helpline__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  width: auto;
  font-size: var(--text-lead);
  font-weight: var(--weight-bold);
}

.resource-directory-helpline__cta svg {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}

@media (max-width: 599px) {
  .resource-directory-helpline {
    flex-direction: column;
    align-items: flex-start;
  }

  .resource-directory-helpline__cta {
    width: 100%;
  }
}

.resource-directory-statewide {
  background: var(--color-brand);
  color: var(--color-surface);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-4);
  margin-bottom: var(--space-6);
}

.resource-directory-statewide__intro {
  margin-bottom: var(--space-4);
}

.resource-directory-statewide__intro h2 {
  color: var(--color-surface);
  font-size: var(--text-h3);
  margin: 0 0 var(--space-2);
}

.resource-directory-statewide__kicker {
  color: var(--color-surface);
  opacity: 0.9;
  margin: 0 0 var(--space-2);
}

.resource-directory-statewide__label {
  color: var(--color-surface);
  font-weight: var(--weight-bold);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  font-size: var(--text-body);
  margin: 0;
}

.resource-directory-statewide__groups {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

@media (min-width: 800px) {
  .resource-directory-statewide__groups {
    grid-template-columns: repeat(2, 1fr);
  }
}

.resource-directory-statewide__group {
  background: var(--color-surface);
  color: var(--color-body);
  border-radius: var(--radius-md);
  padding: var(--space-4);
}

.resource-directory-statewide__group h3 {
  color: var(--color-brand);
  font-size: var(--text-h4);
  margin: 0 0 var(--space-3);
}

.resource-directory-statewide__group .resource-directory-entry:first-of-type {
  border-top: 0;
  padding-top: 0;
}

.resource-directory-statewide__group .resource-directory-entry:last-child {
  padding-bottom: 0;
}

.resource-directory-statewide__link {
  margin: 0 0 var(--space-2);
}

.resource-directory-statewide__link a {
  color: var(--color-brand);
  font-weight: var(--weight-semibold);
}

.resource-directory-statewide__group .resource-directory-entry__phone {
  display: flex;
  margin-bottom: var(--space-1);
}

/* ---- County cards — 2-column grid, 1 column below 600px. ---- */
.resource-directory-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

@media (min-width: 600px) {
  .resource-directory-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

.resource-directory-county-card__heading {
  margin: 0 0 var(--space-1);
}

.resource-directory-county-card__subtitle {
  color: var(--color-muted);
  font-size: var(--text-body);
  margin: 0 0 var(--space-3);
}

/* "OSTA provides referrals to the following legal resources." — this
   pass's own required disclaimer line, once per card. Sized at
   --text-body, not --text-small: this is reading content, not a form
   label/hint (the one place this file still uses --text-small — see
   below), and this pass's own 18px-body-text floor applies to it. */
.resource-directory-county-card__disclaimer {
  color: var(--color-muted);
  font-size: var(--text-body);
  font-style: italic;
  margin: 0 0 var(--space-4);
}

.resource-directory-category-block {
  margin-bottom: var(--space-4);
}

.resource-directory-category-block:last-child {
  margin-bottom: 0;
}

.resource-directory-category-block__heading {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-h4);
  color: var(--color-brand);
  margin: 0 0 var(--space-3);
}

.resource-directory-category-block__heading svg {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  color: var(--color-brand);
}

.resource-directory-entry {
  padding-block: var(--space-3);
  border-top: 1px solid var(--color-border-soft);
}

.resource-directory-category-block__heading + .resource-directory-entry {
  border-top: 0;
  padding-top: 0;
}

.resource-directory-entry__name {
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  margin: 0 0 var(--space-1);
}

.resource-directory-entry__address {
  color: var(--color-body);
  margin: 0 0 var(--space-2);
}

/* Phone numbers must be "large and easy to tap" (this pass's own
   explicit instruction) — bold, brand-navy, well past the 48px floor,
   same visual weight as a primary link without being mistaken for a
   filled button (this is a plain <a>, .btn's own filled/bordered
   treatment is reserved for OSTA's own number above so the hierarchy
   between the two stays clear). */
.resource-directory-entry__phone {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--tap-min);
  color: var(--color-brand);
  font-size: var(--text-lead);
  font-weight: var(--weight-bold);
  text-decoration: none;
}

.resource-directory-entry__phone:hover,
.resource-directory-entry__phone:focus-visible {
  color: var(--color-brand-hover);
  text-decoration: underline;
}

.resource-directory-entry__phone svg {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

/* ---- "Request County Resources by Mail" form — reuses .card and the
   general contact form's own .contact-form__ / .form-field / .form-error /
   .form-hint / .form-required styling untouched. Heading+subtext sit
   OUTSIDE the card, at section level — same plain-centered-intro pattern
   as .resource-directory-intro at the top of the page, rather than a
   heading crowded inside the card alongside the form (design review
   feedback on the first build). ---- */
.resource-directory-mail {
  padding-block: var(--space-8);
  background: var(--color-surface-soft);
}

.resource-directory-mail__intro {
  text-align: center;
  margin-bottom: var(--space-5);
}

.resource-directory-mail__intro h2 {
  margin: 0 0 var(--space-2);
}

.resource-directory-mail__intro p {
  max-width: var(--measure-max);
  margin-inline: auto;
  color: var(--color-body);
  font-size: var(--text-lead);
}

.resource-directory-mail__card {
  padding: var(--space-5) var(--space-4);
}

.resource-directory-mail__another {
  margin-top: var(--space-4);
}

.resource-directory-mail__topics-label {
  /* PASS "Fix the accessibility failures found by the component
     inventory", item 2 — a form label, was --text-small (16px). */
  display: block;
  font-weight: var(--weight-semibold);
  font-size: var(--text-body);
  margin-bottom: var(--space-1);
  color: var(--color-ink);
}

.resource-directory-mail__topics-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2);
}

@media (min-width: 460px) {
  .resource-directory-mail__topics-grid {
    grid-template-columns: 1fr 1fr;
  }
}

.resource-directory-mail__topic {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--tap-min);
  margin: 0;
  font-weight: var(--weight-regular);
}

/* ---- "Join OSTA" CTA band — deliberately NOT .on-dark: that class
   shares --color-surface-dark with .site-footer itself (global.css),
   and this band sits directly above the footer, so the two read as one
   merged block with no seam (design review feedback on the first
   build). --color-brand here is a distinct, lighter navy (the same one
   .resource-directory-helpline already uses above) so the band reads as
   its own section; the accent-green border-bottom matches the exact
   convention .footer-stats already uses to separate ITS OWN internal
   bands, so this reads as "one more band in the sequence", not part of
   the footer. ---- */
.resource-directory-cta {
  background: var(--color-brand);
  border-bottom: 1px solid var(--color-accent);
  padding-block: var(--space-8);
  text-align: center;
}

.resource-directory-cta h2 {
  color: var(--color-surface);
  margin: 0 0 var(--space-3);
}

.resource-directory-cta p {
  max-width: var(--measure-max);
  margin: 0 auto var(--space-5);
  color: var(--color-surface);
  opacity: 0.9;
  font-size: var(--text-lead);
}

/* ==========================================================================
   MY RESOURCES — PASS "Member Resources: gated document library".
   Reuses .card-grid (already the site's own auto-fit card-grid, see
   global.css) and .card/.card__heading/.card__body/.card__footer/.btn
   throughout — only the document-specific pieces (the file-type badge,
   the size line, the category group heading) are new here.
   ========================================================================== */

.my-resources-group__heading {
  margin: 0 0 var(--space-3);
}

.my-resources-group__heading:not(:first-child) {
  margin-top: var(--space-6);
}

.my-resources-grid {
  margin-bottom: var(--space-2);
  /* CSS Grid's own default (align-items: stretch) makes every card in a
     row match the TALLEST card in that row — so a short card (a plain
     title, no description) was stretching to match a neighbor with a
     long, wrapping title, leaving a large empty gap above its buttons.
     align-items: start lets each card size to its own content instead —
     the fix for the oversized, half-empty cards flagged in review. */
  align-items: start;
}

.my-resources-card {
  display: flex;
  flex-direction: column;
}

/* Same pill-badge shape as .contact-hero__badge (that component's own
   comment explains the choice) — light tint surface, navy text, never
   green text. */
.my-resources-card__badge {
  display: inline-flex;
  align-self: flex-start;
  background: var(--color-success-wash);
  color: var(--color-brand);
  font-weight: var(--weight-bold);
  font-size: var(--text-small);
  padding: var(--space-1) var(--space-3);
  border-radius: 999px;
  margin-bottom: var(--space-2);
}

/* Was inheriting <h3>'s sitewide --text-h3 (26px) via .card__heading —
   far too large for what's really a file-name label in a small card,
   and the main driver of both "too tall" and "wildly different card
   heights" (a long title wraps to 3-4 lines at 26px; a short one wraps
   to 1) flagged in review. Sized down to --text-body (18px, this
   project's own accessibility floor — never smaller) and capped at 2
   lines with an ellipsis, so card height stays close and consistent
   regardless of title length; the full title is still in the DOM (a
   screen reader reads all of it) and available on hover via the
   template's own title="" attribute on this element. */
.my-resources-card__title {
  font-size: var(--text-body);
  line-height: var(--leading-snug);
  margin: 0 0 var(--space-2);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.my-resources-card__description {
  margin-bottom: var(--space-2);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.my-resources-card__meta {
  color: var(--color-muted);
  font-size: var(--text-small);
  margin: 0;
}

.my-resources-card__actions {
  margin-top: var(--space-3); /* Fixed gap, not auto — with align-items: start above, each card is only as tall as its own content, so there's no leftover space to "auto" push against; a fixed gap keeps the buttons close to the size line instead of floating. */
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* ==========================================================================
   PASS "Block theme conversion, Group 1 rework" — DISABILITY RIGHTS and
   PARK MAINTENANCE: the CSS half of "every heading, paragraph, list item,
   button and link on these two pages must be editable in the block editor".

   WHY THESE RULES EXIST AT ALL. core/heading, core/paragraph and
   core/list-item all read their text through `source: rich-text`, whose
   parser keeps only nodes that contribute TEXT characters — an inline
   <svg> contributes none, so it is silently destroyed on save. Every
   heading on these two pages that carried its own icon therefore had to be
   split: the icon into its own small wp:html sibling, the words into a real
   editable block, with a Group block taking over the flex row the heading
   element used to be. Splitting moves the icon OUT of the heading, so three
   things the old descendant selectors provided have to be restated here:
   the flex row itself, the icon's size/colour (it no longer inherits from
   the heading), and the heading's own margins (a heading that is no longer
   the row is a block inside it, and picks the sitewide h1-h4 margins back
   up). Every rule below is scoped to one of these two pages' own class
   prefixes; nothing shared is touched, and the ORIGINAL rules above are
   left exactly as they are — these only cover the elements the split
   created. Values are not guessed: each one was measured on the committed
   pre-rework render at 1440px and 360px and re-measured after.
   ========================================================================== */

/* ---- Disability Rights ------------------------------------------------ */

/*
 * .disability-rights-card__heading is now the Group <div> that holds the
 * icon and the <h2>, instead of being the <h2> itself. It already carries
 * the font-size (--text-h2, or --text-h3 in its --sm variant) and colour,
 * so the heading inside it only has to stop overriding them: global.css's
 * `h1, h2, h3, h4 { font-size: … ; color: var(--color-ink) }` (0,0,1) and
 * `{ margin-top: var(--space-6); margin-bottom: var(--space-2) }` would
 * otherwise re-impose 34px ink-coloured text with 48px of space above it.
 * `inherit` — not a restated value — so the --sm variant keeps working
 * from the single place that already declares it. line-height, weight and
 * family are deliberately NOT inherited: the h2 element's own
 * --leading-tight/bold/--font-display are exactly what the old anonymous
 * text run inside the <h2> already computed to (measured: 39.1px line box
 * at --text-h2, 29.9px at --text-h3, identical before and after).
 */
.disability-rights-card__heading > h2 {
  font-size: inherit;
  color: inherit;
  margin: 0;
}

/*
 * The "Example" <h4>s, same split — but this heading was styled through a
 * DESCENDANT selector (`.disability-rights-examples__item h4`) rather than
 * its own class, so the wrapper cannot inherit that styling by carrying a
 * class: the flex row, the icon size and the icon colour all have to be
 * restated on the new wrapper. The <h4> inside still matches the original
 * rule (it is still an h4 inside the item), so only its margin — now the
 * wrapper's job — is overridden here, at (0,2,1) so it beats that rule's
 * own (0,1,1) regardless of load order.
 */
.disability-rights-examples__item .disability-rights-examples__heading {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-1);
}

.disability-rights-examples__item .disability-rights-examples__heading svg {
  /* DESCENDANT, not a child combinator, on purpose: on the front end the
     icon is a direct child of the wrapper, but inside the block-editor
     canvas core/html renders its content inside its own
     `div.wp-block-html` wrapper, so `> svg` would silently stop matching
     there and the icon would render at the 1em fallback in the client's
     editing view only. Every selector in this section that reaches into a
     wp:html block is written the same way for the same reason. */
  /* Was `.disability-rights-examples__item h4 svg` — the icon is no longer
     inside the h4. Without this it falls back to `.disability-rights-page
     svg { width: 1em; height: 1em }` and rendered 13.5px instead of 20px
     (measured). (0,2,1) beats that rule's (0,1,1). */
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  color: var(--color-brand);
}

.disability-rights-examples__item .disability-rights-examples__heading > h4 {
  margin: 0;
}

/*
 * "Filing a Complaint" — same split again, and the same descendant-selector
 * problem (`.disability-rights-complaint h2`). The colour is restated on
 * the WRAPPER, not just re-inherited, because the icon used to take its
 * `currentColor` from the <h2>; outside it the svg would inherit the
 * section's body colour instead and the warning triangle would render grey
 * rather than alert red (measured: rgb(163,33,26) -> rgb(54,59,74)).
 */
.disability-rights-complaint .disability-rights-complaint__heading {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-alert);
  margin: 0 0 var(--space-3);
}

.disability-rights-complaint .disability-rights-complaint__heading svg {
  width: 28px;
  height: 28px;
}

.disability-rights-complaint .disability-rights-complaint__heading > h2 {
  margin: 0;
}

/*
 * FIRST-CHILD MARGIN TRAP — the exact case global.css's own .keep-margin
 * docblock documents. Each marklist <li> is now a Group block, so its icon
 * span is the first child of a flow container and loses its own 2px optical
 * nudge twice over: to `.osta-frame…is-layout-flow > *:not(.keep-margin)`
 * (0,3,0 — answered by putting .keep-margin on the span in post_content)
 * AND to WordPress core's `:where(.is-layout-flow) > :first-child {
 * margin-block-start: 0 }` (0,2,0), which .keep-margin cannot reach.
 * Measured: both icons sat 2px high until this went in. (0,2,0) ties core's
 * rule; inner-pages.css is enqueued after the inline layout styles, so the
 * tie resolves here on order.
 */
.disability-rights-marklist .disability-rights-marklist__icon {
  margin-top: 2px;
}

/*
 * THE "In this Guide" TOC ARROWS. This is the one place on either page
 * where the icon could NOT simply move to a wp:html sibling: it lives
 * inside the <a> inside the <li>, and the only way to keep the six link
 * LABELS editable is core/list + core/list-item, whose content is rich text
 * for the whole <li> — no inline <svg> can survive anywhere inside it, and
 * no block can be nested inside an <li> that is itself rich text. The
 * alternatives were worse: replacing <ul>/<li> with Group <div>s destroys
 * the list semantics a screen-reader user relies on, and leaving the block
 * as raw HTML is what the client rejected.
 *
 * So the arrow is delivered as a masked ::before instead. It is the SAME
 * path data, at the same 18px box, and `background-color: currentColor`
 * through a mask reproduces the original `stroke="currentColor"` exactly —
 * including any future hover colour — which a plain background-image with a
 * baked-in hex would not. Being a pseudo-element it is also still INSIDE
 * the <a>, so the link's clickable area is unchanged; moving the svg out to
 * a sibling would have shrunk the tap target by the icon plus its gap.
 * Decorative and aria-hidden in the original, so nothing is lost to
 * assistive tech by expressing it in CSS.
 */
.disability-rights-toc__list a::before {
  content: "";
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'/%3E%3Cpolyline points='12 5 19 12 12 19'/%3E%3C/svg%3E") no-repeat center / 18px 18px;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'/%3E%3Cpolyline points='12 5 19 12 12 19'/%3E%3C/svg%3E") no-repeat center / 18px 18px;
}

/* ---- Park Maintenance ------------------------------------------------- */

/*
 * Both summary headings, same split as .disability-rights-card__heading
 * above and for the same reason — .park-maint-summary__heading already
 * declares the --text-h3 size and the --brand variant the colour, so the
 * <h2> inside only has to stop re-imposing global.css's h1-h4 defaults
 * (measured without this: 26px navy -> 34px ink, plus 48px of space above).
 */
.park-maint-summary__heading > h2 {
  font-size: inherit;
  color: inherit;
  margin: 0;
}

/*
 * Same first-child margin trap as .disability-rights-marklist__icon above:
 * each summary bullet is now a Group <li>, so the green check loses its own
 * 2px nudge to core's (0,2,0) :first-child reset. .keep-margin is on the
 * span in post_content for the (0,3,0) rule; this restores the value for
 * core's.
 */
.park-maint-summary__list .park-maint-summary__check {
  margin-top: 2px;
}

/*
 * The ORS citation. It used to be a <span> inside the bullet's own text
 * <span>, and `.park-maint-summary__list span > span` (above) is what gave
 * it the body colour and the snug line-height — that selector no longer
 * matches now the text is an editable core/paragraph and the citation's
 * parent is a <p>. Same two declarations, re-pointed at the new parent;
 * `display: block` and the 4px top margin still come from
 * .park-maint-summary__ref itself and are deliberately not repeated.
 * (Measured without this: line-height 24.3px -> 30.6px and colour
 * rgb(54,59,74) -> rgb(94,100,117) on all four citations.)
 */
.park-maint-summary__list p > .park-maint-summary__ref {
  color: var(--color-body);
  line-height: var(--leading-snug);
}

/* ---- Disability Rights + Park Maintenance: EDITOR-CANVAS PARITY --------
   PASS "Block theme conversion, Group 1 rework", defect 3 ("the editor
   must look like the page"). Both differences below were found by
   screenshotting the editor canvas and the front end at the SAME width and
   comparing, not by inspection.
   ----------------------------------------------------------------------- */

/*
 * 1. THE MAIN COLUMN WAS ~330px WIDE IN THE EDITOR (760px on the front
 *    end), so every heading and paragraph on Disability Rights wrapped two
 *    to four times more than it really does, and Park Maintenance's hero
 *    and two-column summary never got the width their own breakpoints need.
 *
 *    CAUSE, measured in the canvas rather than guessed: theme.json declares
 *    settings.layout.contentSize = 720px, and the editor applies it to
 *    every TOP-LEVEL block through its own inline rule
 *      .block-editor-block-list__layout.is-root-container
 *        > :where(:not(.alignleft):not(.alignright):not(.alignfull))
 *        { max-width: 720px }
 *    (0,2,0). On the front end the same content is inside core/post-content's
 *    <div class="entry-content … is-layout-flow">, which constrains nothing
 *    — so the constraint exists ONLY in the editor. 720px minus this page's
 *    own padding, its 280px sidebar and the 48px column gap leaves ~330px,
 *    which is exactly what was measured.
 *
 *    Both pages already manage their own maximum width (.disability-rights-
 *    layout and .park-maint-shell both set max-width: var(--container-max)
 *    and centre themselves), so lifting the editor's constraint on the
 *    outermost wrapper reproduces the front end rather than overriding a
 *    deliberate choice. (0,3,0) beats the editor's rule outright, so this
 *    does not depend on stylesheet order inside the iframe.
 *
 *    .block-editor-block-list__layout exists ONLY in the editor canvas, so
 *    this rule is inert on the front end — verified, not assumed: the
 *    front-end pixel diff is byte-identical before and after it was added.
 */
/*
 * PASS "Block theme conversion, Group 2" — generalised from the two
 * page-specific selectors that stood here (.disability-rights-page,
 * .park-maint-page) to the marker every converted section already carries.
 *
 * Find Resources is what forced it, and it is the case the page-by-page form
 * could not have covered anyway: its two top-level blocks are the hero and
 * the listing section, not one page wrapper, and the hero is full-bleed. In
 * the canvas it rendered 720px wide inside a 1585px frame — measured, not
 * eyeballed — so the editor showed a boxed photo where the page shows an
 * edge-to-edge one.
 *
 * .osta-frame is exactly the right marker: it means "theme-authored section
 * structure", and every such section already decides its own width (a
 * .container inside it, or full-bleed on purpose). Client prose is the thing
 * that genuinely wants the 720px measure, and it never carries this marker —
 * About's own .about-editor-content is the live example, and it stays
 * constrained.
 *
 * The second selector is for Contact and Resource Directory, whose whole page
 * sits inside osta/core-gate. That block's edit() renders a bare <InnerBlocks>
 * with no useBlockProps, so in the canvas the root container's direct child is
 * .block-editor-inner-blocks and carries no block class at all — measured, at
 * 720px, after a first attempt at `.wp-block-osta-core-gate` matched nothing.
 * Lifting it is enough on its own: the editor constrains only DIRECT children
 * of .is-root-container, so the .osta-frame sections nested inside were never
 * constrained in the first place.
 *
 * Editor-only, as before: .block-editor-block-list__layout never exists on
 * the front end. Re-verified by pixel diff after this change, not assumed.
 */
.block-editor-block-list__layout.is-root-container > .osta-frame,
.block-editor-block-list__layout.is-root-container > .block-editor-inner-blocks {
  max-width: none;
}

/*
 * 2. THE ICON SPANS COLLAPSED IN THE EDITOR. Same root cause as the fix
 *    already in this file for .evictions-callout__icon /
 *    .evictions-safeharbor__check (see its own comment above): these spans
 *    have a width and a height but no display of their own, and they only
 *    ever worked because they are direct children of a flex container on the
 *    front end, where flex blockifies them. In the canvas core/html renders
 *    inside its own div.wp-block-html wrapper, so the span is no longer a
 *    flex item, stays `display: inline`, and an inline box ignores width and
 *    height entirely — measured live in the canvas: the whole icon wrapper
 *    came out 6-7px wide instead of 22px, and .park-maint-summary__check's
 *    own `svg { width: 100%; height: 100% }` then resolved against the wrong
 *    box. Declaring the display the component actually needs makes each span
 *    self-sufficient in both places; on the front end it is a no-op, because
 *    flex blockifies inline-flex to flex and the box was already 22x22
 *    (re-verified by pixel diff after adding it).
 */
.disability-rights-marklist__icon,
.park-maint-summary__check {
  display: inline-flex;
}

/*
 * 3. TENANT RIGHTS' INFO COLUMN WAS 53px WIDE IN THE EDITOR (measured in the
 *    canvas), so "Need Immediate Help?" rendered one letter per line and the
 *    column ran 5,563px tall against a 3,730px page. The canvas was 6,744px
 *    where the front end is 3,730px — nearly double, all of it this column.
 *
 *    CAUSE: .tenant-rights-content is a flex row whose two children are
 *    supposed to be .tenant-rights-accordions (flex: 3) and
 *    .tenant-rights-info (flex: 2). In the editor the accordions arrive
 *    wrapped in the block's own preview <div>, so the element carrying
 *    `flex: 3 1 0` is a grandchild and the actual flex item falls back to
 *    `flex: 0 1 auto` — it takes its full max-content width, and .tenant-
 *    rights-info, which DOES still get `flex: 2 1 0` (flex-basis 0), is left
 *    with whatever is over.
 *
 *    Same family as the wrapper problems already fixed above, and the same
 *    remedy the Evictions card heads use: display:contents removes the
 *    wrapper from layout entirely, so the real element becomes the flex item
 *    again. Scoped to this one preview class rather than all of them — the
 *    other blocks' previews sit in ordinary flow containers where the extra
 *    wrapper costs nothing.
 *
 *    There are TWO wrappers, not one — the block's own preview div and the
 *    classless <div> ServerSideRender puts inside it. Making only the outer
 *    one `contents` just promoted the inner one to flex item and changed
 *    nothing measurable, which is how the second was found. `:not([class])`
 *    is what keeps this off .tenant-rights-accordions itself, the element
 *    that actually has to stay a flex item.
 *
 *    The class is generated by the block's own edit() and exists only in the
 *    editor, so this cannot reach the front end; re-verified by pixel diff
 *    all the same.
 */
.osta-tenant-right-accordions-editor-preview,
.osta-tenant-right-accordions-editor-preview > div:not([class]) {
  display: contents;
}

/*
 * FOUND IN PASSING, DELIBERATELY NOT FIXED — "Filing a Complaint"'s own
 * warning-triangle icon. Its <span> has no display and no flex-shrink of
 * its own, so below ~560px the flex row shrinks it and the svg inside
 * (max-width: 100% from global.css's replaced-element reset, but an
 * explicit 28px height) renders 20.3 x 28 — a horizontally squashed
 * triangle. Measured at 360px on the CURRENT COMMITTED page, before any of
 * this pass's changes: this is pre-existing, not something the rework
 * introduced, and it is identical at 1440px (28 x 28) either way.
 *
 * Adding this span to the `display: inline-flex` list above fixes it —
 * verified, it renders a correct 28 x 28 — but that is a real, visible
 * change to a committed design at mobile widths, which this pass has no
 * mandate to make: it would show up as an unexplained 3,325-pixel delta in
 * the very front-end parity check this rework is being judged on. It is
 * reported instead, with the one-line fix already known. Scoped to the
 * editor canvas here (.block-editor-block-list__layout never exists on the
 * front end) purely so the client's editing preview is not ALSO wrong for
 * the separate reason the rule above exists — core/html's own wrapper div
 * taking the span out of the flex row.
 */
.block-editor-block-list__layout .disability-rights-complaint__heading span {
  display: inline-flex;
}

/* Topic hub listings (osta/topic-related) and PHP guides nested in Page with Sidebar. */
.topic-related {
  display: grid;
  gap: var(--space-3);
  margin-top: var(--space-5);
}

.topic-related__heading {
  margin: 0;
  color: var(--color-brand);
}

.topic-related__subheading {
  margin: var(--space-3) 0 var(--space-2);
}

.topic-related__list {
  display: grid;
  gap: var(--space-2);
}

.topic-related__card .card__heading {
  font-size: var(--text-h4, 1.15rem);
}

/* Beat WP global-styles `body .is-layout-flex { display: flex }` and the
   group’s flexWrap/align-items:center so hubs keep a real sidebar grid. */
body .page-with-sidebar__row.wp-block-group.is-layout-flex,
.page-with-sidebar__row.wp-block-group {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  align-items: start;
  flex-wrap: unset;
}

@media (min-width: 900px) {
  body .page-with-sidebar__row.wp-block-group.is-layout-flex,
  .page-with-sidebar__row.wp-block-group {
    grid-template-columns: 300px minmax(0, 1fr);
  }

  .page-with-sidebar__aside {
    grid-column: 1;
    grid-row: 1;
  }

  .page-with-sidebar__main {
    grid-column: 2;
    grid-row: 1;
    min-width: 0;
  }
}

.page-with-sidebar__aside .resource-sidebar-nav,
.page-with-sidebar__aside .osta-on-this-page,
.page-with-sidebar__aside .resource-sidebar-toc,
.page-with-sidebar__aside .resource-sidebar-siblings,
.page-with-sidebar__aside .hub-essential-docs {
  margin-bottom: var(--space-4);
}

.page-with-sidebar__aside .hub-essential-docs.tenant-rights-documents {
  padding-top: var(--space-4);
}

.hub-essential-docs__tag {
  font-size: var(--text-small);
  font-weight: var(--weight-bold);
  color: var(--color-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 var(--space-2);
}

.hub-essential-docs__empty,
.hub-essential-docs__footnote {
  color: var(--color-muted);
  margin: 0;
}

.hub-essential-docs__footnote {
  margin-top: var(--space-3);
}

.hub-essential-docs__footnote a {
  color: var(--color-brand);
  font-weight: var(--weight-semibold);
}

.hub-essential-docs__item--locked {
  cursor: default;
}

.hub-essential-docs__item--locked:hover,
.hub-essential-docs__item--locked:focus-visible {
  border-color: var(--color-border-soft);
  box-shadow: none;
}

.hub-essential-docs__lock-label {
  margin-top: var(--space-1);
  font-weight: var(--weight-semibold);
  color: var(--color-locked);
}

.hub-essential-docs__item--locked svg {
  color: var(--color-locked);
}
.page-with-sidebar__main .disability-rights-shell,
.page-with-sidebar__main .park-maint-shell,
.page-with-sidebar__main .container.evictions-shell,
.page-with-sidebar__main .resident-assoc-page,
.page-with-sidebar__main .drinking-water-page,
.page-with-sidebar__main .legal-assist-page,
.page-with-sidebar__main .park-maint-hub,
.page-with-sidebar__main .rent-caps-page {
  width: 100%;
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

/* Hub deep-link target: cards land at #resources (top of main column). */
.osta-hub-resources-anchor.wp-block-group {
  margin: 0;
  padding: 0;
  min-height: 0;
  height: 0;
  overflow: hidden;
  scroll-margin-top: calc(var(--header-height, 64px) + var(--space-2, 16px));
}

.page-with-sidebar__main .evictions-breadcrumb,
.page-with-sidebar__main .disability-rights-breadcrumb,
.page-with-sidebar__main .park-maint-breadcrumb {
  display: none;
}

body:has(.page-with-sidebar__main .evictions-hero) .page-header,
body:has(.page-with-sidebar__main .disability-rights-intro) .page-header,
body:has(.page-with-sidebar__main .park-maint-hero) .page-header,
body:has(.page-with-sidebar__main .resident-assoc-page) .page-header,
body:has(.page-with-sidebar__main .drinking-water-page) .page-header,
body:has(.page-with-sidebar__main .purchase-park-page) .page-header,
body:has(.page-with-sidebar__main .selling-home-page) .page-header,
body:has(.page-with-sidebar__main .amenities-page) .page-header,
body:has(.page-with-sidebar__main .legal-assist-page) .page-header,
body:has(.page-with-sidebar__main .park-maint-hub) .page-header,
body:has(.page-with-sidebar__main .rent-caps-page) .page-header,
body:has(.news-page) .page-header {
  display: none;
}

.legal-assist-page,
.drinking-water-page,
.purchase-park-page,
.selling-home-page,
.amenities-page,
.park-maint-hub,
.rent-caps-page {
  display: grid;
  gap: var(--space-5);
}

.drinking-water-page > .wp-block-cover,
.drinking-water-hero {
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.purchase-park-page > .wp-block-cover,
.purchase-park-hero,
.selling-home-page > .wp-block-cover,
.selling-home-hero,
.amenities-page > .wp-block-cover,
.amenities-hero {
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.purchase-park-page .is-style-osta-eyebrow,
.selling-home-page .is-style-osta-eyebrow,
.amenities-page .is-style-osta-eyebrow,
.drinking-water-page .is-style-osta-eyebrow {
  text-align: left;
}

.purchase-park-critical,
.selling-home-critical {
  scroll-margin-top: calc(var(--header-height, 64px) + var(--space-2, 16px));
}

@media (min-width: 768px) {
  .purchase-park-steps.wp-block-columns,
  .purchase-park-incentive-grid.wp-block-columns,
  .purchase-park-partners.wp-block-columns,
  .selling-home-pillars.wp-block-columns,
  .selling-home-hb-grid.wp-block-columns,
  .selling-home-resources.wp-block-columns,
  .amenities-pillars.wp-block-columns,
  .amenities-deposit-grid.wp-block-columns,
  .amenities-fee-grid.wp-block-columns,
  .amenities-docs-grid.wp-block-columns {
    display: grid !important;
    gap: var(--space-4);
  }

  .purchase-park-steps.wp-block-columns {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .purchase-park-incentive-grid.wp-block-columns,
  .purchase-park-partners.wp-block-columns,
  .selling-home-pillars.wp-block-columns,
  .selling-home-hb-grid.wp-block-columns,
  .selling-home-resources.wp-block-columns,
  .amenities-pillars.wp-block-columns,
  .amenities-deposit-grid.wp-block-columns,
  .amenities-fee-grid.wp-block-columns,
  .amenities-docs-grid.wp-block-columns {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .selling-home-age-grid.wp-block-columns,
  .amenities-def-grid.wp-block-columns {
    display: grid !important;
    gap: var(--space-4);
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.page-with-sidebar__main .purchase-park-page,
.page-with-sidebar__main .selling-home-page,
.page-with-sidebar__main .amenities-page {
  width: 100%;
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

.drinking-water-pillar-caution {
  border: 2px solid var(--color-alert-wash);
}

@media (min-width: 768px) {
  .drinking-water-pillars.wp-block-columns,
  .drinking-water-steps.wp-block-columns,
  .drinking-water-samples.wp-block-columns {
    display: grid !important;
    gap: var(--space-4);
  }

  .drinking-water-pillars.wp-block-columns,
  .drinking-water-samples.wp-block-columns {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .drinking-water-steps.wp-block-columns {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.drinking-water-lookup {
  scroll-margin-top: calc(var(--header-height, 64px) + var(--space-2, 16px));
}

.osta-water-caution {
  scroll-margin-top: calc(var(--header-height, 64px) + var(--space-2, 16px));
}

.resident-assoc-page {
  display: grid;
  gap: var(--space-5);
}

.resident-assoc-page .osta-ra-band-members {
  background: var(--color-surface-alt);
}

.resident-assoc-page .is-style-osta-notice-success .is-style-osta-checklist li::before {
  background-color: var(--color-accent);
}

.resident-assoc-page .wp-block-columns .is-style-osta-cta-navy {
  text-align: left;
}

.resident-assoc-page .wp-block-columns .is-style-osta-cta-navy > * {
  max-width: none;
  margin-left: 0;
  margin-right: 0;
}

.resident-assoc-page > .wp-block-cover,
.resident-assoc-hero,
.rent-caps-page > .wp-block-cover,
.rent-caps-hero {
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.rent-caps-page .is-style-osta-cta-navy .resident-assoc-actions {
  justify-content: center;
}

.rent-caps-calc .wp-block-list {
  font-variant-numeric: tabular-nums;
}

.resident-assoc-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}

.resident-assoc-actions .btn {
  margin: 0;
}

.osta-members-gate-editor {
  outline: 1px dashed var(--color-border);
  padding: var(--space-3);
  border-radius: var(--radius-md);
}

.osta-members-gate-editor::before {
  content: "Members only (visible on the site to members)";
  display: block;
  font-size: var(--text-eyebrow);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-muted);
  margin-bottom: var(--space-2);
}

a.skip-link ~ a.skip-link {
  display: none;
}

.page-with-sidebar__main .disability-rights-layout {
  display: block;
  width: 100%;
  max-width: none;
  padding: 0;
  margin: 0;
}
.page-with-sidebar__main .disability-rights-sidebar,
.page-with-sidebar__main .disability-rights-toc {
  display: none;
}
.page-with-sidebar__main .disability-rights-breadcrumb,
.page-with-sidebar__main .park-maint-breadcrumb,
.page-with-sidebar__main .evictions-breadcrumb {
  display: none;
}

/* OSTA University / Courses — scoped to this page only. Do not add
   these classes to other hubs; do not fold them into the shared
   page-header :has() list above. */
body:has(.page-with-sidebar__main .osta-courses-page) .page-header {
  display: none;
}

.page-with-sidebar__main .osta-courses-page {
  width: 100%;
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

.osta-courses-page .osta-courses-breadcrumb {
  margin: 0 0 var(--space-3, 16px);
}

.osta-courses-page .osta-courses-hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3, 16px);
  margin-top: var(--space-4, 24px);
}

.osta-courses-page .osta-courses-hero a:not(.btn) {
  color: var(--color-link-on-dark, #b8d4ff);
  text-decoration: underline;
}

.osta-courses-page .osta-courses-progress {
  margin: 0 0 var(--space-5, 32px);
}

.osta-courses-page .tutor-wrap.tutor-courses-wrap,
.osta-courses-page .tutor-container {
  max-width: 100%;
  width: 100%;
  padding-left: 0;
  padding-right: 0;
  margin-left: 0;
  margin-right: 0;
}

.osta-courses-page .tutor-course-filter-container {
  margin-bottom: var(--space-4, 24px);
}

.osta-courses-page .tutor-card.tutor-course-card {
  background: var(--color-surface, #fff);
  border: 1px solid var(--color-border, #d7dbe3);
  border-radius: var(--radius-md, 8px);
  box-shadow: none;
  overflow: hidden;
}

.osta-courses-page .tutor-card.tutor-course-card .tutor-course-name a,
.osta-courses-page .tutor-card.tutor-course-card h3 a {
  color: var(--color-brand, #263279);
  text-decoration: none;
}

.osta-courses-page .tutor-card.tutor-course-card .tutor-course-name a:hover,
.osta-courses-page .tutor-card.tutor-course-card h3 a:hover {
  text-decoration: underline;
}

.osta-courses-page .tutor-btn,
.osta-courses-page .tutor-btn-primary {
  background: var(--color-brand, #263279);
  border-color: var(--color-brand, #263279);
  color: var(--color-surface, #fff);
}

.osta-courses-page .tutor-form-control {
  min-height: 48px;
  font-size: 1rem;
}

.osta-courses-page .osta-courses-cta {
  margin-top: var(--space-6, 48px);
}

.osta-courses-page .osta-courses-cta .resident-assoc-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3, 16px);
}

/* Working with OSTA — Stitch inner column on Page with Sidebar.
   Do not add these classes to header, footer, or the template aside. */
body:has(.page-with-sidebar__main .working-with-osta-page) .page-header {
  display: none;
}

.page-with-sidebar__main .working-with-osta-page {
  width: 100%;
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

.working-with-osta-page {
  display: grid;
  gap: var(--space-5, 40px);
}

.working-with-osta-page .is-style-osta-eyebrow,
.working-with-osta-page p.is-style-osta-eyebrow,
.working-with-osta-page p.is-style-osta-intro,
.working-with-osta-page p.wwo-lead {
  text-align: left;
  margin-left: 0;
  margin-right: 0;
}

.working-with-osta-page p.wwo-lead,
.working-with-osta-page p.is-style-osta-intro.wwo-lead {
  max-width: 40rem;
  color: var(--color-muted);
}

.working-with-osta-page .wwo-kicker {
  display: inline-block;
  padding: 0.35em 0.9em;
  border-radius: 999px;
  background: var(--color-surface-alt, #edeff4);
  color: var(--color-accent-ink, #4e7328);
  font-weight: 700;
}

.working-with-osta-page .wwo-hero h1 {
  max-width: 22ch;
  color: var(--color-brand, #263279);
}

.working-with-osta-page .wwo-stats .wp-block-column {
  min-width: 0;
}

.working-with-osta-page .wwo-stats .is-style-osta-card,
.working-with-osta-page .wwo-stats .is-style-osta-cta-navy {
  min-height: 140px;
  height: 100%;
}

.working-with-osta-page .wwo-stats .is-style-osta-stat-number {
  font-size: clamp(1.35rem, 2.1vw, 2.25rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  overflow-wrap: normal;
  word-break: keep-all;
  hyphens: none;
}

.working-with-osta-page .wwo-stat-join .btn {
  margin-top: var(--space-3, 16px);
}

.working-with-osta-page .wwo-photo {
  border-radius: var(--radius-md, 12px);
  overflow: hidden;
}

.working-with-osta-page .wwo-nonprofit {
  margin-top: var(--space-3, 16px);
}

.working-with-osta-page .wwo-tier-pill {
  display: inline-block;
  margin: 0 0 var(--space-2, 8px);
  padding: 0.25em 0.75em;
  border-radius: 999px;
  font-size: var(--text-small, 0.875rem);
  font-weight: 700;
  background: var(--color-surface-alt, #edeff4);
  color: var(--color-brand, #263279);
}

.working-with-osta-page .wwo-tier-pill--park {
  background: #acf775;
  color: var(--color-accent-ink, #4e7328);
}

.working-with-osta-page .wwo-tier-pill--region {
  background: var(--color-brand-wash, #edeff7);
  color: var(--color-brand, #263279);
}

.working-with-osta-page .wwo-when {
  background: var(--color-surface-alt, #edeff4);
  border-radius: var(--radius-md, 12px);
  padding: var(--space-3, 16px);
  margin: var(--space-3, 16px) 0;
}

.working-with-osta-page .wwo-tier .btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 48px;
  margin: 0;
}

.working-with-osta-page .wwo-step {
  background: var(--color-surface-alt, #edeff4);
  border-radius: var(--radius-md, 12px);
  padding: var(--space-4, 24px);
  height: 100%;
}

.working-with-osta-page .wwo-step-num {
  width: 2.5rem;
  height: 2.5rem;
  margin: 0 0 var(--space-3, 16px);
  border-radius: 999px;
  background: var(--color-brand, #263279);
  color: var(--color-surface, #fff);
  font-weight: 700;
  font-size: 1.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
}

.working-with-osta-page .wwo-step--final .wwo-step-num {
  background: var(--color-surface, #fff);
  color: var(--color-brand, #263279);
}

.working-with-osta-page .wwo-compare {
  overflow-x: auto;
}

.working-with-osta-page .wwo-compare table {
  min-width: 760px;
  width: 100%;
  border-collapse: collapse;
}

.working-with-osta-page .wwo-compare th,
.working-with-osta-page .wwo-compare td {
  padding: var(--space-3, 16px) var(--space-4, 24px);
  text-align: left;
  vertical-align: top;
}

.working-with-osta-page .wwo-compare thead {
  background: var(--color-surface-alt, #edeff4);
}

.working-with-osta-page .wwo-compare thead th {
  color: var(--color-brand, #263279);
  font-weight: 700;
}

.working-with-osta-page .wwo-compare tbody tr:nth-child(even) {
  background: var(--color-surface-alt, #edeff4);
}

.working-with-osta-page .wwo-cta {
  text-align: center;
}

.working-with-osta-page .wwo-cta .is-style-osta-eyebrow,
.working-with-osta-page .wwo-cta p.is-style-osta-eyebrow,
.working-with-osta-page .wwo-cta p.is-style-osta-intro,
.working-with-osta-page .wwo-cta .wwo-lead {
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}

.working-with-osta-page .wwo-cta .resident-assoc-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3, 16px);
  justify-content: center;
}

.working-with-osta-page .wwo-cta .btn {
  min-height: 48px;
}

@media (min-width: 768px) {
  .working-with-osta-page .wwo-stats.wp-block-columns {
    display: grid !important;
    gap: var(--space-4, 24px);
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .working-with-osta-page .wwo-steps.wp-block-columns {
    display: grid !important;
    gap: var(--space-4, 24px);
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {

  .working-with-osta-page .wwo-tiers.wp-block-columns {
    display: grid !important;
    gap: var(--space-4, 24px);
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: stretch;
  }

  .working-with-osta-page .wwo-steps.wp-block-columns {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Sidebar main is ~2/3 of the viewport; four stat cards need more room
   than a full-width Stitch canvas before they sit in one row. */
@media (min-width: 1280px) {
  .working-with-osta-page .wwo-stats.wp-block-columns {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Leases and rental agreements — Stitch inner column on Page with Sidebar.
   Do not add these classes to header, footer, or the template aside. */
body:has(.page-with-sidebar__main .leases-page) .page-header {
  display: none;
}

.page-with-sidebar__main .leases-page {
  width: 100%;
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

.leases-page {
  display: grid;
  gap: var(--space-5, 40px);
}

.leases-page .is-style-osta-eyebrow,
.leases-page p.is-style-osta-eyebrow,
.leases-page p.is-style-osta-intro,
.leases-page p.leases-lead {
  text-align: left;
  margin-left: 0;
  margin-right: 0;
}

.leases-page p.leases-lead,
.leases-page p.is-style-osta-intro.leases-lead {
  max-width: 42rem;
  color: var(--color-muted);
}

.leases-page .leases-kicker,
.leases-page .leases-statute-badge {
  display: inline-block;
  padding: 0.35em 0.9em;
  border-radius: 999px;
  font-weight: 700;
}

.leases-page .leases-kicker {
  background: var(--color-surface-alt, #edeff4);
  color: var(--color-accent-ink, #4e7328);
}

.leases-page .leases-statute-badge {
  background: var(--color-success-wash, #eff7e7);
  color: var(--color-accent-ink, #4e7328);
  font-size: 0.875rem;
}

.leases-page .leases-hero h1 {
  max-width: 22ch;
  color: var(--color-brand, #263279);
}

.leases-page .leases-hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3, 16px);
}

.leases-page .leases-hero-actions .btn {
  min-height: 48px;
}

.leases-page .leases-photo {
  border-radius: var(--radius-md, 12px);
  overflow: hidden;
  margin-top: var(--space-4, 24px);
}

.leases-page .leases-compare {
  overflow-x: auto;
}

.leases-page .leases-compare table {
  min-width: 760px;
  width: 100%;
  border-collapse: collapse;
}

.leases-page .leases-compare th,
.leases-page .leases-compare td {
  padding: var(--space-3, 16px) var(--space-4, 24px);
  text-align: left;
  vertical-align: top;
}

.leases-page .leases-compare thead {
  background: var(--color-surface-alt, #edeff4);
}

.leases-page .leases-compare thead th {
  color: var(--color-brand, #263279);
  font-weight: 700;
}

.leases-page .leases-compare thead th:nth-child(2) {
  color: var(--color-accent-ink, #4e7328);
}

.leases-page .leases-compare thead th:nth-child(3) {
  color: var(--color-warning, #7a4e00);
}

.leases-page .leases-compare tbody tr:nth-child(even) {
  background: var(--color-surface-alt, #edeff4);
}

.leases-page .leases-num-card,
.leases-page .leases-timeline-card,
.leases-page .leases-warn-card,
.leases-page .leases-pillars .is-style-osta-card {
  height: 100%;
}

.leases-page .leases-num {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  margin: 0 0 var(--space-3, 16px);
  border-radius: 999px;
  background: var(--color-brand, #263279);
  color: #fff;
  font-weight: 700;
  line-height: 1;
}

.leases-page .leases-pill {
  display: inline-block;
  padding: 0.25em 0.75em;
  margin-bottom: var(--space-2, 8px);
  border-radius: 999px;
  background: var(--color-surface-alt, #edeff4);
  color: var(--color-brand, #263279);
  font-size: 0.8125rem;
  font-weight: 700;
}

.leases-page .leases-pill--accent {
  background: var(--color-success-wash, #eff7e7);
  color: var(--color-accent-ink, #4e7328);
}

.leases-page .leases-timeline-card {
  border-left: 4px solid var(--color-brand, #263279);
}

.leases-page .leases-timeline-card--sale {
  border-left-color: var(--color-accent, #8ac34e);
}

.leases-page .leases-timeline-card--waiver {
  border-left-color: var(--color-warning, #7a4e00);
}

.leases-page .leases-timelines {
  padding: var(--space-5, 40px) var(--space-4, 24px);
  border-radius: var(--radius-md, 12px);
  background: var(--color-surface-alt, #edeff4);
}

.leases-page .leases-warning-kicker {
  color: var(--color-warning, #7a4e00);
}

.leases-page .leases-warn-card {
  border-top: 4px solid var(--color-warning, #7a4e00);
}

.leases-page .leases-forever {
  display: grid;
  gap: var(--space-4, 24px);
}

.leases-page .leases-forever-banner h2 {
  color: var(--color-brand, #263279);
}

.leases-page .leases-cta,
.leases-page .leases-takeaway {
  text-align: center;
}

.leases-page .leases-cta .is-style-osta-eyebrow,
.leases-page .leases-cta p.is-style-osta-eyebrow,
.leases-page .leases-takeaway .is-style-osta-eyebrow,
.leases-page .leases-takeaway p.is-style-osta-eyebrow {
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}

.leases-page .leases-cta .resident-assoc-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3, 16px);
  justify-content: center;
}

.leases-page .leases-cta .btn {
  min-height: 48px;
}

.leases-page .wp-block-column {
  min-width: 0;
}

@media (min-width: 768px) {
  .leases-page .leases-timeline-grid.wp-block-columns,
  .leases-page .leases-pillars.wp-block-columns {
    display: grid !important;
    gap: var(--space-4, 24px);
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .leases-page .leases-disclosures.wp-block-columns,
  .leases-page .leases-timeline-grid.wp-block-columns,
  .leases-page .leases-warnings.wp-block-columns,
  .leases-page .leases-pillars.wp-block-columns {
    display: grid !important;
    gap: var(--space-4, 24px);
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* Mandatory mediation — Stitch inner column on Page with Sidebar.
   Do not add these classes to header, footer, or the template aside. */
body:has(.page-with-sidebar__main .mediation-page) .page-header {
  display: none;
}

.page-with-sidebar__main .mediation-page {
  width: 100%;
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

.mediation-page {
  display: grid;
  gap: var(--space-5, 40px);
}

.mediation-page .is-style-osta-eyebrow,
.mediation-page p.is-style-osta-eyebrow,
.mediation-page p.is-style-osta-intro,
.mediation-page p.mediation-lead {
  text-align: left;
  margin-left: 0;
  margin-right: 0;
}

.mediation-page p.mediation-lead,
.mediation-page p.is-style-osta-intro.mediation-lead {
  max-width: 42rem;
  color: var(--color-muted);
}

.mediation-page .mediation-kicker,
.mediation-page .mediation-statute-badge {
  display: inline-block;
  padding: 0.35em 0.9em;
  border-radius: 999px;
  font-weight: 700;
}

.mediation-page .mediation-kicker {
  background: var(--color-surface-alt, #edeff4);
  color: var(--color-accent-ink, #4e7328);
}

.mediation-page .mediation-statute-badge {
  background: var(--color-success-wash, #eff7e7);
  color: var(--color-accent-ink, #4e7328);
  font-size: 0.875rem;
}

.mediation-page .mediation-hero h1 {
  max-width: 22ch;
  color: var(--color-brand, #263279);
}

.mediation-page .mediation-hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3, 16px);
}

.mediation-page .mediation-hero-actions .btn,
.mediation-page .mediation-cta .btn,
.mediation-page .mediation-contacts .btn {
  min-height: 48px;
}

.mediation-page .mediation-photo {
  border-radius: var(--radius-md, 12px);
  overflow: hidden;
  margin-top: var(--space-4, 24px);
}

.mediation-page .mediation-benefit,
.mediation-page .mediation-eligible,
.mediation-page .mediation-exempt,
.mediation-page .mediation-step,
.mediation-page .mediation-tips .is-style-osta-card {
  height: 100%;
}

.mediation-page .mediation-eligible {
  border-top: 4px solid var(--color-accent, #8ac34e);
}

.mediation-page .mediation-exempt {
  border-top: 4px solid var(--color-warning, #7a4e00);
}

.mediation-page .mediation-num {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  margin: 0 0 var(--space-3, 16px);
  border-radius: 999px;
  background: var(--color-brand, #263279);
  color: #fff;
  font-weight: 700;
  line-height: 1;
}

.mediation-page .mediation-process {
  padding: var(--space-5, 40px) var(--space-4, 24px);
  border-radius: var(--radius-md, 12px);
  background: var(--color-surface-alt, #edeff4);
}

.mediation-page .mediation-path-a {
  border-left: 4px solid var(--color-accent, #8ac34e);
}

.mediation-page .mediation-path-b {
  border-left: 4px solid var(--color-warning, #7a4e00);
}

.mediation-page .mediation-cta,
.mediation-page .mediation-enforce {
  text-align: center;
}

.mediation-page .mediation-cta .is-style-osta-eyebrow,
.mediation-page .mediation-cta p.is-style-osta-eyebrow,
.mediation-page .mediation-enforce .is-style-osta-eyebrow,
.mediation-page .mediation-enforce p.is-style-osta-eyebrow {
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}

.mediation-page .mediation-cta .resident-assoc-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3, 16px);
  justify-content: center;
}

.mediation-page .wp-block-column {
  min-width: 0;
}

@media (min-width: 768px) {
  .mediation-page .mediation-benefits--two.wp-block-columns,
  .mediation-page .mediation-scope.wp-block-columns,
  .mediation-page .mediation-paths.wp-block-columns,
  .mediation-page .mediation-tips.wp-block-columns,
  .mediation-page .mediation-flow.wp-block-columns {
    display: grid !important;
    gap: var(--space-4, 24px);
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .mediation-page .mediation-benefits.wp-block-columns:not(.mediation-benefits--two),
  .mediation-page .mediation-contact-grid.wp-block-columns {
    display: grid !important;
    gap: var(--space-4, 24px);
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .mediation-page .mediation-flow.wp-block-columns {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Advocacy & Legislation — Stitch inner column on Page with Sidebar.
   Do not add these classes to header, footer, or the template aside. */
body:has(.page-with-sidebar__main .advocacy-page) .page-header {
  display: none;
}

.page-with-sidebar__main .advocacy-page {
  width: 100%;
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

.advocacy-page {
  display: grid;
  gap: var(--space-5, 40px);
}

.advocacy-page .is-style-osta-eyebrow,
.advocacy-page p.is-style-osta-eyebrow,
.advocacy-page p.is-style-osta-intro,
.advocacy-page p.advocacy-lead {
  text-align: left;
  margin-left: 0;
  margin-right: 0;
}

.advocacy-page p.advocacy-lead,
.advocacy-page p.is-style-osta-intro.advocacy-lead {
  max-width: 42rem;
  color: var(--color-muted);
}

.advocacy-page .advocacy-kicker,
.advocacy-page .advocacy-statute-badge {
  display: inline-block;
  padding: 0.35em 0.9em;
  border-radius: 999px;
  font-weight: 700;
}

.advocacy-page .advocacy-kicker {
  background: var(--color-surface-alt, #edeff4);
  color: var(--color-accent-ink, #4e7328);
}

.advocacy-page .advocacy-statute-badge {
  background: var(--color-success-wash, #eff7e7);
  color: var(--color-accent-ink, #4e7328);
  font-size: 0.875rem;
}

.advocacy-page .advocacy-hero h1 {
  max-width: 22ch;
  color: var(--color-brand, #263279);
}

.advocacy-page .advocacy-hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3, 16px);
}

.advocacy-page .advocacy-hero-actions .btn,
.advocacy-page .advocacy-cta .btn,
.advocacy-page .advocacy-contacts .btn {
  min-height: 48px;
}

.advocacy-page .advocacy-photo {
  border-radius: var(--radius-md, 12px);
  overflow: hidden;
  margin-top: var(--space-4, 24px);
}

.advocacy-page .advocacy-step,
.advocacy-page .advocacy-written,
.advocacy-page .advocacy-spoken,
.advocacy-page .advocacy-when-card {
  height: 100%;
}

.advocacy-page .advocacy-written {
  border-top: 4px solid var(--color-brand, #263279);
}

.advocacy-page .advocacy-spoken {
  border-top: 4px solid var(--color-accent, #8ac34e);
}

.advocacy-page .advocacy-num {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  margin: 0 0 var(--space-3, 16px);
  border-radius: 999px;
  background: var(--color-brand, #263279);
  color: #fff;
  font-weight: 700;
  line-height: 1;
}

.advocacy-page .advocacy-process,
.advocacy-page .advocacy-testimony-section,
.advocacy-page .advocacy-writing,
.advocacy-page .advocacy-contacts {
  display: grid;
  gap: var(--space-4, 24px);
}

.advocacy-page .advocacy-process,
.advocacy-page .advocacy-writing,
.advocacy-page .advocacy-contacts {
  padding: var(--space-5, 40px) var(--space-4, 24px);
  border-radius: var(--radius-md, 12px);
}

.advocacy-page .advocacy-process,
.advocacy-page .advocacy-contacts {
  background: var(--color-surface-alt, #edeff4);
}

.advocacy-page .advocacy-writing {
  background: var(--color-surface, #fff);
  border: 1px solid var(--color-border, #d7dadf);
  box-shadow: var(--shadow-card, 0 1px 8px rgba(0, 0, 0, 0.06));
}

.advocacy-page .advocacy-section-intro {
  display: grid;
  gap: 0.35rem;
}

.advocacy-page .advocacy-section-intro > * {
  margin-top: 0;
  margin-bottom: 0;
}

.advocacy-page .advocacy-section-intro .wp-block-heading {
  margin-top: 0.15rem;
  margin-bottom: 0.35rem;
}

.advocacy-page .advocacy-written,
.advocacy-page .advocacy-spoken {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.advocacy-page .advocacy-panel-kicker {
  margin: 0 0 var(--space-3, 16px);
  color: var(--color-accent-ink, #4e7328);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.advocacy-page .advocacy-item {
  padding: 0.85rem 0 0;
  margin: 0;
  border-top: 1px solid var(--color-border, #d7dadf);
  background: transparent;
  box-shadow: none;
}

.advocacy-page .advocacy-item:first-of-type {
  padding-top: 0;
  border-top: 0;
}

.advocacy-page .advocacy-item .wp-block-heading {
  font-size: 1rem;
  margin-bottom: 0.25rem;
}

.advocacy-page .advocacy-item p {
  margin-bottom: 0;
}

.advocacy-page .advocacy-note {
  margin: auto 0 0;
  padding: 0.85rem 1rem;
  border-radius: var(--radius-md, 12px);
  background: var(--color-surface-alt, #edeff4);
  border: 1px solid var(--color-border, #d7dadf);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--color-muted, #454650);
}

.advocacy-page .advocacy-step-critical {
  border-left: 4px solid var(--color-accent, #8ac34e);
}

.advocacy-page .advocacy-when-card {
  border-left: 4px solid var(--color-brand, #263279);
}

.advocacy-page .advocacy-blueprint {
  overflow-x: auto;
}

.advocacy-page .advocacy-cta {
  text-align: center;
}

.advocacy-page .advocacy-cta .is-style-osta-eyebrow,
.advocacy-page .advocacy-cta p.is-style-osta-eyebrow {
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}

.advocacy-page .advocacy-cta .resident-assoc-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3, 16px);
  justify-content: center;
}

.advocacy-page .wp-block-column {
  min-width: 0;
}

@media (min-width: 768px) {
  .advocacy-page .advocacy-paths.wp-block-columns,
  .advocacy-page .advocacy-testimony.wp-block-columns,
  .advocacy-page .advocacy-flow.wp-block-columns {
    display: grid !important;
    gap: var(--space-4, 24px);
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .advocacy-page .advocacy-when.wp-block-columns {
    display: grid !important;
    gap: var(--space-4, 24px);
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .advocacy-page .advocacy-flow.wp-block-columns,
  .advocacy-page .advocacy-contact-grid.wp-block-columns {
    display: grid !important;
    gap: var(--space-4, 24px);
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .advocacy-page .advocacy-flow.wp-block-columns {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Retaliation — Stitch inner column on Page with Sidebar.
   Do not add these classes to header, footer, or the template aside. */
body:has(.page-with-sidebar__main .retaliation-page) .page-header {
  display: none;
}

.page-with-sidebar__main .retaliation-page {
  width: 100%;
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

.retaliation-page {
  display: grid;
  gap: var(--space-5, 40px);
}

.retaliation-page .is-style-osta-eyebrow,
.retaliation-page p.is-style-osta-eyebrow,
.retaliation-page p.is-style-osta-intro,
.retaliation-page p.retaliation-lead {
  text-align: left;
  margin-left: 0;
  margin-right: 0;
}

.retaliation-page p.retaliation-lead,
.retaliation-page p.is-style-osta-intro.retaliation-lead {
  max-width: 42rem;
  color: var(--color-muted);
}

.retaliation-page .retaliation-kicker,
.retaliation-page .retaliation-statute-badge {
  display: inline-block;
  padding: 0.35em 0.9em;
  border-radius: 999px;
  font-weight: 700;
}

.retaliation-page .retaliation-kicker {
  background: var(--color-surface-alt, #edeff4);
  color: var(--color-accent-ink, #4e7328);
}

.retaliation-page .retaliation-statute-badge {
  background: var(--color-success-wash, #eff7e7);
  color: var(--color-accent-ink, #4e7328);
  font-size: 0.875rem;
}

.retaliation-page .retaliation-hero h1 {
  max-width: 22ch;
  color: var(--color-brand, #263279);
}

.retaliation-page .retaliation-hero-actions,
.retaliation-page .retaliation-assoc .resident-assoc-actions,
.retaliation-page .retaliation-cta .resident-assoc-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3, 16px);
}

.retaliation-page .retaliation-hero-actions .btn,
.retaliation-page .retaliation-cta .btn,
.retaliation-page .retaliation-assoc .btn {
  min-height: 48px;
}

.retaliation-page .retaliation-photo {
  border-radius: var(--radius-md, 12px);
  overflow: hidden;
  margin-top: var(--space-4, 24px);
}

.retaliation-page .retaliation-act,
.retaliation-page .retaliation-illegal-card,
.retaliation-page .retaliation-step {
  height: 100%;
}

.retaliation-page .retaliation-act {
  border-left: 4px solid var(--color-brand, #263279);
}

.retaliation-page .retaliation-illegal {
  border-top: 4px solid var(--color-error, #ba1a1a);
}

.retaliation-page .retaliation-illegal-card {
  border-left: 4px solid var(--color-error, #ba1a1a);
}

.retaliation-page .retaliation-warning-kicker {
  color: var(--color-error, #ba1a1a);
}

.retaliation-page .retaliation-num {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  margin: 0 0 var(--space-3, 16px);
  border-radius: 999px;
  background: var(--color-brand, #263279);
  color: #fff;
  font-weight: 700;
  line-height: 1;
}

.retaliation-page .retaliation-protected,
.retaliation-page .retaliation-illegal,
.retaliation-page .retaliation-plan,
.retaliation-page .retaliation-assoc {
  display: grid;
  gap: var(--space-4, 24px);
  padding: var(--space-5, 40px) var(--space-4, 24px);
  border-radius: var(--radius-md, 12px);
}

.retaliation-page .retaliation-protected,
.retaliation-page .retaliation-plan {
  background: var(--color-surface-alt, #edeff4);
}

.retaliation-page .retaliation-illegal,
.retaliation-page .retaliation-assoc {
  background: var(--color-surface, #fff);
  border: 1px solid var(--color-border, #d7dadf);
  box-shadow: var(--shadow-card, 0 1px 8px rgba(0, 0, 0, 0.06));
}

.retaliation-page .retaliation-illegal {
  border-top: 4px solid var(--color-error, #ba1a1a);
}

.retaliation-page .retaliation-section-intro {
  display: grid;
  gap: 0.35rem;
}

.retaliation-page .retaliation-section-intro > * {
  margin-top: 0;
  margin-bottom: 0;
}

.retaliation-page .retaliation-section-intro .wp-block-heading {
  margin-top: 0.15rem;
  margin-bottom: 0.35rem;
}

.retaliation-page .retaliation-step-urgent {
  border-left: 4px solid var(--color-accent, #8ac34e);
}

.retaliation-page .retaliation-cta {
  text-align: center;
}

.retaliation-page .retaliation-cta .is-style-osta-eyebrow,
.retaliation-page .retaliation-cta p.is-style-osta-eyebrow {
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}

.retaliation-page .retaliation-cta .resident-assoc-actions {
  justify-content: center;
}

.retaliation-page .wp-block-column {
  min-width: 0;
}

.retaliation-page h2[id] {
  scroll-margin-top: calc(var(--header-height, 64px) + var(--space-2, 16px));
}

@media (min-width: 768px) {
  .retaliation-page .retaliation-acts.wp-block-columns,
  .retaliation-page .retaliation-illegal-grid.wp-block-columns {
    display: grid !important;
    gap: var(--space-4, 24px);
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .retaliation-page .retaliation-steps.wp-block-columns {
    display: grid !important;
    gap: var(--space-4, 24px);
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .retaliation-page .retaliation-steps.wp-block-columns {
    display: grid !important;
    gap: var(--space-4, 24px);
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Find your chapter — /chapters/ on Page with Sidebar.
   Do not add these classes to header, footer, or the template aside. */
body:has(.page-with-sidebar__main .find-chapter-page) .page-header {
  display: none;
}

.page-with-sidebar__main .find-chapter-page {
  width: 100%;
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

.find-chapter-page {
  display: grid;
  gap: var(--space-5, 40px);
}

.find-chapter-page .is-style-osta-eyebrow,
.find-chapter-page p.is-style-osta-eyebrow,
.find-chapter-page p.is-style-osta-intro,
.find-chapter-page p.find-chapter-lead {
  text-align: left;
  margin-left: 0;
  margin-right: 0;
}

.find-chapter-page p.find-chapter-lead,
.find-chapter-page p.is-style-osta-intro.find-chapter-lead {
  max-width: 42rem;
  color: var(--color-muted);
}

.find-chapter-page .find-chapter-kicker {
  display: inline-block;
  padding: 0.35em 0.9em;
  border-radius: 999px;
  font-weight: 700;
  background: var(--color-surface-alt, #edeff4);
  color: var(--color-accent-ink, #4e7328);
}

.find-chapter-page .find-chapter-hero h1 {
  max-width: 22ch;
  color: var(--color-brand, #263279);
}

/* Same 1→2 column card CTA grid as Find Resources (.resources-grid).
   Beat WP `is-layout-flex` and `.osta-frame.is-layout-flex { gap: 0 }`. */
.find-chapter-page .find-chapter-hero-actions,
.find-chapter-page .find-chapter-organize .resident-assoc-actions,
.find-chapter-page .find-chapter-cta .resident-assoc-actions,
.find-chapter-page .locked .resident-assoc-actions,
body .page-with-sidebar__main .find-chapter-page .find-chapter-hero-actions.wp-block-group,
body .page-with-sidebar__main .find-chapter-page .find-chapter-organize .resident-assoc-actions.wp-block-group,
body .page-with-sidebar__main .find-chapter-page .find-chapter-cta .resident-assoc-actions.wp-block-group,
body .page-with-sidebar__main .find-chapter-page .find-chapter-hero-actions.wp-block-group.is-layout-flex,
body .page-with-sidebar__main .find-chapter-page .find-chapter-organize .resident-assoc-actions.wp-block-group.is-layout-flex,
body .page-with-sidebar__main .find-chapter-page .find-chapter-cta .resident-assoc-actions.wp-block-group.is-layout-flex {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  align-items: stretch;
  justify-content: stretch;
  margin: 0;
}

@media (min-width: 700px) {
  .find-chapter-page .find-chapter-hero-actions,
  .find-chapter-page .find-chapter-organize .resident-assoc-actions,
  .find-chapter-page .find-chapter-cta .resident-assoc-actions,
  .find-chapter-page .locked .resident-assoc-actions,
  body .page-with-sidebar__main .find-chapter-page .find-chapter-hero-actions.wp-block-group,
  body .page-with-sidebar__main .find-chapter-page .find-chapter-organize .resident-assoc-actions.wp-block-group,
  body .page-with-sidebar__main .find-chapter-page .find-chapter-cta .resident-assoc-actions.wp-block-group {
    grid-template-columns: 1fr 1fr;
  }
}

.find-chapter-page .find-chapter-hero-actions .btn,
.find-chapter-page .find-chapter-organize .btn,
.find-chapter-page .find-chapter-cta .btn,
.find-chapter-page .locked .btn,
body .page-with-sidebar__main .find-chapter-page .find-chapter-hero-actions .btn,
body .page-with-sidebar__main .find-chapter-page .find-chapter-organize .btn,
body .page-with-sidebar__main .find-chapter-page .find-chapter-cta .btn,
body .page-with-sidebar__main .find-chapter-page .locked .btn {
  width: 100%;
  margin: 0;
  box-sizing: border-box;
}

.find-chapter-page .find-chapter-search .btn {
  margin: 0;
}

.find-chapter-page .find-chapter-photo {
  border-radius: var(--radius-md, 12px);
  overflow: hidden;
  margin-top: var(--space-4, 24px);
}

.find-chapter-page .find-chapter-photo .wp-block-cover__inner-container {
  display: none;
}

.find-chapter-page .find-chapter-benefits.wp-block-columns {
  align-items: stretch;
}

.find-chapter-page .find-chapter-search {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3, 16px);
  margin: 0 0 var(--space-5, 40px);
}

.find-chapter-page .find-chapter-search input[type="search"],
.find-chapter-page .find-chapter-search select {
  flex: 1 1 16rem;
  min-height: 48px;
  padding: 0.75rem 1rem;
  border: 2px solid var(--color-border-soft);
  border-radius: var(--radius-md, 12px);
}

.find-chapter-page .find-chapter-search .btn {
  flex: 0 0 auto;
}

.find-chapter-page .find-chapter-directory .table-scroll-cap {
  max-height: 36.5rem;
}

.find-chapter-page .locked.resident-assoc-locked {
  display: grid;
  gap: var(--space-3, 16px);
}

.find-chapter-page .locked.resident-assoc-locked > p {
  margin: 0;
}

.find-chapter-page .find-chapter-directory__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  align-items: stretch;
}

@media (min-width: 700px) {
  .find-chapter-page .find-chapter-directory__grid {
    grid-template-columns: 1fr 1fr;
  }
}

.find-chapter-page .find-chapter-county {
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md);
  box-shadow: none;
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
  height: 100%;
  margin: 0;
}

.find-chapter-page .find-chapter-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
  margin: 0;
  padding: 0;
}

.find-chapter-page .find-chapter-card__actions {
  margin-top: auto;
}

.find-chapter-page .find-chapter-card__link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 48px;
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  box-shadow: none;
  width: auto;
  font-weight: 600;
  color: var(--color-brand, #263279);
  text-decoration: none;
}

.find-chapter-page .find-chapter-card__link:hover,
.find-chapter-page .find-chapter-card__link:focus-visible {
  text-decoration: underline;
}

.find-chapter-page .find-chapter-county__heading {
  margin: 0 0 var(--space-3, 16px);
  color: var(--color-brand);
}

.find-chapter-page .find-chapter-county__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-4, 24px);
}

.find-chapter-page .find-chapter-card__yours,
.find-chapter-page .find-chapter-card__number {
  margin: 0 0 0.25rem;
  font-size: 0.875rem;
  font-weight: 700;
}

.find-chapter-page .find-chapter-card__yours {
  color: var(--color-accent-ink, #4e7328);
}

.find-chapter-page .find-chapter-card__title {
  margin: 0 0 0.35rem;
}

.find-chapter-page .find-chapter-card__address {
  margin: 0 0 var(--space-3, 16px);
  color: var(--color-muted);
}

.find-chapter-page .find-chapter-reach {
  text-align: center;
  padding: var(--space-5, 40px) var(--space-4, 24px);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-lg, 16px);
}

@media (min-width: 768px) {
  .find-chapter-page .find-chapter-benefits.wp-block-columns {
    display: grid !important;
    gap: var(--space-4, 24px);
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* Educational Video Library — /video-library/ on Page with Sidebar.
   Scoped to .video-library-page. Do not restyle sitewide buttons. */
body:has(.page-with-sidebar__main .video-library-page) .page-header {
  display: none;
}

.page-with-sidebar__main .video-library-page {
  width: 100%;
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

.video-library-page {
  display: grid;
  gap: var(--space-5, 40px);
}

.video-library-page .is-style-osta-eyebrow,
.video-library-page p.is-style-osta-eyebrow,
.video-library-page p.is-style-osta-intro,
.video-library-page p.video-library-lead {
  text-align: left;
  margin-left: 0;
  margin-right: 0;
}

.video-library-page p.video-library-lead {
  max-width: 42rem;
  color: var(--color-muted);
}

.video-library-page .video-library-kicker {
  display: inline-block;
  padding: 0.35em 0.9em;
  border-radius: 999px;
  font-weight: 700;
  background: var(--color-surface-alt, #edeff4);
  color: var(--color-accent-ink, #4e7328);
}

.video-library-page .video-library-hero h1 {
  max-width: 24ch;
  color: var(--color-brand, #263279);
}

.video-library-page .video-library-hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3, 16px);
}

.video-library-page .video-library-hero-actions .btn,
.video-library-page .video-library-spotlight .btn,
.video-library-page .video-library-card .btn,
.video-library-page .video-library-search .btn,
.video-library-page .video-library-watch-party .btn,
.video-library-page .video-library-request .btn {
  margin: 0;
  min-height: 48px;
}

.video-library-page .video-library-spotlight {
  padding: var(--space-5, 40px) var(--space-4, 24px);
  border-radius: var(--radius-lg, 16px);
}

.video-library-page .video-library-spotlight__badge {
  display: inline-block;
  margin: 0 0 var(--space-3, 16px);
  padding: 0.3em 0.85em;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: var(--color-accent, #8fbf4d);
  color: var(--color-brand-ink, #12203a);
}

.video-library-page .video-library-spotlight__grid {
  display: grid;
  gap: var(--space-4, 24px);
}

@media (min-width: 900px) {
  .video-library-page .video-library-spotlight__grid {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    align-items: center;
  }
}

.video-library-page .video-library-player {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #0b1220;
  border-radius: var(--radius-md, 12px);
  overflow: hidden;
}

.video-library-page .video-library-poster {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  cursor: pointer;
  background: transparent;
}

.video-library-page .video-library-poster img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video-library-page .video-library-poster__play {
  position: absolute;
  inset: 50% auto auto 50%;
  width: 4.25rem;
  height: 4.25rem;
  margin: -2.125rem 0 0 -2.125rem;
  border-radius: 50%;
  background: var(--color-accent, #8fbf4d);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28);
}

.video-library-page .video-library-poster__play::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 54%;
  width: 0;
  height: 0;
  transform: translate(-50%, -50%);
  border-style: solid;
  border-width: 0.7rem 0 0.7rem 1.15rem;
  border-color: transparent transparent transparent #12203a;
}

.video-library-page .video-library-iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.video-library-page .video-library-spotlight__copy h2 {
  margin: 0 0 0.75rem;
  color: inherit;
}

.video-library-page .video-library-spotlight__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3, 16px);
}

.video-library-page .video-library-search {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3, 16px);
  margin: 0 0 var(--space-4, 24px);
}

.video-library-page .video-library-search input[type="search"] {
  flex: 1 1 16rem;
  min-height: 48px;
  padding: 0.75rem 1rem;
  border: 2px solid var(--color-border-soft);
  border-radius: var(--radius-md, 12px);
}

.video-library-page .video-library-pills {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0;
  padding: 0;
}

.video-library-page .video-library-pill {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0.35em 0.9em;
  border-radius: 999px;
  border: 1px solid var(--color-border-soft);
  background: var(--color-surface-alt, #edeff4);
  color: var(--color-brand, #263279);
  text-decoration: none;
  font-weight: 600;
}

.video-library-page .video-library-pill.is-active {
  background: var(--color-brand, #263279);
  border-color: var(--color-brand, #263279);
  color: #fff;
}

.video-library-page .video-library-grid {
  list-style: none;
  display: grid;
  gap: var(--space-4, 24px);
  margin: 0;
  padding: 0;
}

@media (min-width: 768px) {
  .video-library-page .video-library-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1100px) {
  .video-library-page .video-library-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.video-library-page .video-library-card {
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border: 1px solid var(--color-border-soft);
  border-radius: var(--radius-md, 12px);
  overflow: hidden;
}

.video-library-page .video-library-card__tag,
.video-library-page .video-library-card__duration {
  position: absolute;
  z-index: 1;
  top: 0.65rem;
  padding: 0.2em 0.55em;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 700;
  background: rgba(18, 32, 58, 0.86);
  color: #fff;
}

.video-library-page .video-library-card__tag {
  left: 0.65rem;
}

.video-library-page .video-library-card__duration {
  right: 0.65rem;
}

.video-library-page .video-library-card__body {
  display: grid;
  gap: 0.5rem;
  padding: var(--space-4, 24px);
}

.video-library-page .video-library-card__source,
.video-library-page .video-library-card__summary {
  margin: 0;
  color: var(--color-muted);
}

.video-library-page .video-library-card__title {
  margin: 0;
  color: var(--color-brand, #263279);
}

.video-library-page .video-library-watch-party {
  padding: var(--space-5, 40px) var(--space-4, 24px);
  background: var(--color-surface-alt, #edeff4);
  border-radius: var(--radius-lg, 16px);
}

.video-library-page .video-library-request.wp-block-columns {
  align-items: stretch;
}

/* Single chapter — /chapter/{slug}/. Do not add these to header or footer. */
body.single-osta_chapter .page-header {
  display: none;
}

.single-chapter-page {
  display: grid;
  gap: var(--space-5, 40px);
}

.single-chapter-page .single-chapter-kicker,
.single-chapter-page p.is-style-osta-eyebrow {
  text-align: left;
  margin-left: 0;
}

.single-chapter-chip {
  display: inline-block;
  margin: 0;
  padding: 0.25em 0.75em;
  border-radius: 999px;
  font-size: 0.9rem;
  font-weight: 600;
  background: var(--color-surface-alt, #edeff4);
}

.single-chapter-title {
  margin: 0.25rem 0 0;
  max-width: 22ch;
  color: var(--color-brand, #263279);
}

.single-chapter-meta,
.single-chapter-lead,
.single-chapter-empty,
.single-chapter-card__meta,
.single-chapter-aside__note {
  color: var(--color-muted);
}

.single-chapter-hero {
  display: grid;
  gap: var(--space-4, 24px);
}

@media (min-width: 900px) {
  .single-chapter-hero {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    align-items: stretch;
  }
}

.single-chapter-page .single-chapter-hero__frame.is-style-osta-hero-framed {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: 320px;
}

.single-chapter-page .wp-block-cover.is-style-osta-hero-framed .wp-block-cover__background {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(38, 50, 121, 0.72) !important;
  opacity: 1 !important;
}

.single-chapter-page .single-chapter-hero__frame .wp-block-cover__inner-container {
  position: relative;
  z-index: 2;
}

.single-chapter-page .single-chapter-hero__frame .wp-block-cover__image-background {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
}

.single-chapter-page .single-chapter-hero__frame.on-dark .single-chapter-title,
.single-chapter-page .single-chapter-hero__frame.on-dark :where(h1, h2, h3, p) {
  color: var(--color-surface, #fff);
}

.single-chapter-page .single-chapter-hero__frame.on-dark .single-chapter-meta,
.single-chapter-page .single-chapter-hero__frame.on-dark .single-chapter-lead {
  color: var(--color-surface, #fff);
}

.single-chapter-page .single-chapter-hero__frame.on-dark .single-chapter-chip {
  background: rgba(255, 255, 255, 0.16);
  color: var(--color-surface, #fff);
}

.single-chapter-page .single-chapter-help.is-style-osta-notice-success {
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 100%;
  box-sizing: border-box;
  padding: var(--space-5, 40px);
  border-radius: var(--radius-lg, 16px);
}

.single-chapter-hero__copy {
  display: grid;
  gap: var(--space-3, 16px);
}

.single-chapter-page .single-chapter-profile__contact {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border-soft);
}

.single-chapter-hero-actions,
.single-chapter-page .resident-assoc-actions,
.single-chapter-page .locked .resident-assoc-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3, 16px);
}

.single-chapter-page .btn {
  margin: 0;
}

.single-chapter-photo {
  margin: 0;
  overflow: hidden;
  border-radius: var(--radius-lg, 16px);
}

.single-chapter-photo__img {
  display: block;
  width: 100%;
  height: auto;
}

.single-chapter-help__title {
  margin: 0 0 0.35rem;
  font-weight: 700;
}

.single-chapter-next {
  padding: var(--space-4, 24px);
}

.single-chapter-next__label {
  margin: 0;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.85rem;
  font-weight: 700;
}

.single-chapter-next__title {
  margin: 0.25rem 0;
}

.single-chapter-next__when {
  margin: 0 0 var(--space-3, 16px);
}

.single-chapter-body {
  display: grid;
  gap: var(--space-5, 40px);
}

@media (min-width: 900px) {
  .single-chapter-body {
    grid-template-columns: minmax(0, 8fr) minmax(16rem, 4fr);
    align-items: start;
  }
}

.single-chapter-main,
.single-chapter-updates,
.single-chapter-events,
.single-chapter-aside {
  display: grid;
  gap: var(--space-3, 16px);
}

.single-chapter-card {
  padding: var(--space-4, 24px);
}

.single-chapter-card h3,
.single-chapter-join h2,
.single-chapter-profile h2,
.single-chapter-support h2 {
  margin: 0 0 0.35rem;
  color: var(--color-brand, #263279);
}

.single-chapter-card__pin {
  display: inline-block;
  margin-right: 0.4rem;
  padding: 0.15em 0.55em;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 700;
  background: var(--color-accent, #6fa83a);
  color: #fff;
}

.single-chapter-event {
  display: grid;
  gap: var(--space-3, 16px);
}

@media (min-width: 600px) {
  .single-chapter-event {
    grid-template-columns: 4.5rem minmax(0, 1fr);
  }
}

.single-chapter-event__date {
  margin: 0;
  padding: 0.65rem;
  text-align: center;
  border-radius: var(--radius-md, 8px);
  background: var(--color-brand, #263279);
  color: #fff;
}

.single-chapter-event__month {
  display: block;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
}

.single-chapter-event__day {
  display: block;
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1;
}

.single-chapter-aside {
  position: sticky;
  top: 1.5rem;
}

.single-chapter-page .single-chapter-help-grid,
.single-chapter-page .single-chapter-aside-cards {
  grid-template-columns: 1fr;
}

.single-chapter-page .news-legislative-col .news-bill-list {
  width: 100%;
}

.single-chapter-page .single-chapter-profile .news-calendar-item__title {
  font-size: var(--text-h4, 1.15rem);
  margin-top: 0;
}

.single-chapter-page .single-chapter-support .news-events-panel__heading {
  margin-bottom: var(--space-2);
}

/* Park closure — Page with Sidebar inner column. */
body:has(.page-with-sidebar__main .closure-page) .page-header {
  display: none;
}

.page-with-sidebar__main .closure-page {
  width: 100%;
  max-width: none;
  padding-left: 0;
  padding-right: 0;
}

.closure-page {
  display: grid;
  gap: var(--space-5);
}

.closure-page .closure-kicker,
.closure-page .closure-statute-badge {
  display: inline-block;
  padding: 0.35em 0.9em;
  border-radius: 999px;
  font-weight: 700;
}

.closure-page .closure-kicker {
  background: var(--color-surface-alt);
  color: var(--color-accent-ink);
}

.closure-page .closure-statute-badge {
  background: var(--color-success-wash);
  color: var(--color-accent-ink);
  font-size: 0.875rem;
}

.closure-page .closure-hero h1 {
  max-width: 24ch;
  color: var(--color-brand);
}

.closure-page .closure-lead,
.closure-page p.is-style-osta-intro.closure-lead {
  max-width: 42rem;
  color: var(--color-muted);
}

.closure-page .closure-hero-actions,
.closure-page .closure-cta-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.closure-page .closure-hero-actions .btn,
.closure-page .closure-cta-actions .btn,
.closure-page .closure-retaliation .btn {
  min-height: 48px;
}

.closure-page .closure-notice-card--365 {
  border-top: 4px solid var(--color-accent);
}

.closure-page .closure-notice-card--15 {
  border-top: 4px solid var(--color-brand);
}

.closure-page .closure-pay-card h3 {
  color: var(--color-brand);
}

.closure-page .closure-retaliation {
  padding: var(--space-5);
  color: var(--color-surface);
  background: var(--color-brand);
  border-radius: var(--radius-md);
}

.closure-page .closure-retaliation h2,
.closure-page .closure-retaliation p {
  color: var(--color-surface);
}

.closure-page .closure-statutes ul {
  margin: 0;
  padding-left: 1.2em;
}

.osta-ldoc-outline {
  white-space: pre-wrap;
  font-family: inherit;
  font-size: 0.95em;
  padding: var(--space-4);
  background: var(--color-surface-2, #f6f4ef);
  border-radius: var(--radius-md);
  overflow: auto;
  max-height: 28rem;
}

.osta-meeting-report-form .osta-action-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

@media (min-width: 768px) {
  .osta-meeting-report-form .osta-action-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: start;
  }

  .osta-meeting-report-form .osta-action-row .form-field {
    margin-bottom: 0;
    min-width: 0;
  }
}

.osta-ldoc-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.osta-ldoc-list__item {
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--color-border, #ddd);
}

.osta-ldoc-list__title {
  margin: 0 0 0.25rem;
  font-weight: 600;
}

.osta-ldoc-list__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}

.osta-ldoc-delete {
  display: inline;
  margin: 0;
}

.osta-park-visits {
  max-height: 18rem;
  overflow-y: auto;
}

.osta-park-visits__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.osta-park-visits__list li {
  display: grid;
  gap: 0.25rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--color-border, #ddd);
}

.osta-park-visits__date {
  font-weight: 600;
}

/* The OSTA Podcast — /podcast/. Scoped to .podcast-page. */
.podcast-page {
  max-width: 75rem;
  margin-inline: auto;
}

.podcast-page .podcast-topbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.85rem 0 1rem;
  margin-bottom: 0.5rem;
  border-bottom: 1px solid var(--color-border-soft, #e0e3e8);
}

.podcast-page .podcast-access-pill {
  margin: 0;
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0.35em 1em;
  border-radius: 999px;
  background: var(--color-accent, #336b00);
  color: #fff;
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.02em;
}

.podcast-page .podcast-hero {
  align-items: center;
  margin-block: var(--space-5, 1.5rem);
}

.podcast-page .podcast-hero h1 {
  max-width: 18ch;
}

.podcast-page .podcast-hero-photo {
  border-radius: 1rem;
  overflow: hidden;
}

.podcast-page .podcast-hero-photo-caption {
  margin: 0;
  font-weight: 700;
}

.podcast-page .podcast-hero-actions,
.podcast-page .podcast-spotlight__actions,
.podcast-page .podcast-player-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
}

.podcast-page .podcast-hero-actions .btn,
.podcast-page .podcast-spotlight__actions .btn,
.podcast-page .podcast-player-tools .btn,
.podcast-page .podcast-episode__play .btn,
.podcast-page .podcast-clubhouse .btn,
.podcast-page .podcast-ask .btn,
.podcast-page .podcast-search .btn,
.podcast-page .podcast-admin-rss .btn {
  min-height: 48px;
}

.podcast-page .podcast-checks {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.25rem;
  margin: 1.25rem 0 0;
  padding: 0;
  list-style: none;
}

.podcast-page .podcast-checks li {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 600;
}

.podcast-page .podcast-checks li::before {
  content: "";
  width: 1.1rem;
  height: 1.1rem;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--color-accent, #336b00);
  box-shadow: inset 0 0 0 2px #fff;
}

.podcast-page .podcast-platforms,
.podcast-page .podcast-directory,
.podcast-page .podcast-howto-wrap,
.podcast-page .podcast-ask {
  margin-block: var(--space-6, 2rem);
  padding: 1.5rem 1.25rem;
  border-radius: 1.25rem;
  background: var(--color-surface-alt, #ebeef3);
}

.podcast-page .podcast-platforms__head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  align-items: flex-start;
  margin-bottom: 1rem;
}

.podcast-page .podcast-phone-chip {
  margin: 0;
  padding: 0.5em 0.9em;
  border-radius: 0.75rem;
  background: #fff;
  font-weight: 700;
  color: var(--color-brand, #263279);
}

.podcast-page #featured-player,
.podcast-page #directory,
.podcast-page #episode-library {
  scroll-margin-top: 6rem;
}

.podcast-page .podcast-platform-list,
.podcast-page .podcast-episode-list,
.podcast-page .podcast-pills {
  list-style: none;
  margin: 0;
  padding: 0;
}

.podcast-page .podcast-platform-list,
.podcast-page .podcast-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
}

.podcast-page .podcast-chip,
.podcast-page .podcast-pill {
  display: inline-flex;
  align-items: center;
  min-height: 48px;
  padding: 0.4em 1.1em;
  border-radius: 0.85rem;
  background: #fff;
  color: var(--color-text, #181c20);
  text-decoration: none;
  font-weight: 600;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
}

.podcast-page .podcast-chip--soon {
  opacity: 0.7;
}

.podcast-page .podcast-pill.is-active {
  background: var(--color-brand, #263279);
  color: #fff;
}

.podcast-page .podcast-admin-rss {
  margin: 1rem 0 0;
}

.podcast-page .podcast-spotlight {
  margin-block: var(--space-6, 2rem);
  padding: 1.75rem 1.5rem;
  border-radius: 1.5rem;
  background: #fff;
  box-shadow: 0 8px 28px rgba(24, 28, 32, 0.08);
}

.podcast-page .podcast-spotlight__top {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}

.podcast-page .podcast-spotlight__badge {
  display: inline-flex;
  margin: 0;
  padding: 0.3em 0.8em;
  border-radius: 999px;
  background: var(--color-accent-wash, #acf775);
  color: var(--color-brand, #263279);
  font-weight: 800;
}

.podcast-page .podcast-spotlight__title {
  margin: 0 0 0.5rem;
  color: var(--color-brand, #263279);
}

.podcast-page .podcast-player-panel {
  margin-top: 1rem;
  padding: 1.1rem;
  border-radius: 1rem;
  background: var(--color-surface-alt, #f1f4f9);
}

.podcast-page .podcast-player-placeholder {
  height: 8px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--color-brand, #263279) 38%, #d7dadf 38%);
}

.podcast-page .podcast-audio {
  width: 100%;
  min-height: 48px;
  margin: 0 0 1rem;
}

.podcast-page .podcast-speed {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.podcast-page .js-osta-pod-speed.is-active {
  background: var(--color-brand, #263279);
  color: #fff;
  border-color: var(--color-brand, #263279);
}

.podcast-page .podcast-search {
  margin: 1rem 0;
}

.podcast-page .podcast-search-label {
  display: block;
  font-weight: 700;
  color: var(--color-brand, #263279);
  margin-bottom: 0.4rem;
}

.podcast-page .podcast-search-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.podcast-page .podcast-search input[type="search"] {
  flex: 1 1 16rem;
  min-height: 56px;
  padding: 0.75rem 1rem;
  border: 0;
  border-radius: 0.85rem;
  background: #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
}

.podcast-page .podcast-pills {
  margin: 0.75rem 0 1.25rem;
}

.podcast-page .podcast-episode-list {
  display: grid;
  gap: 1.1rem;
}

.podcast-page .podcast-episode {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.4rem 1.5rem;
  border-radius: 1rem;
  background: #fff;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05);
  scroll-margin-top: 6rem;
}

.podcast-page .podcast-episode[hidden] {
  display: none;
}

.podcast-page .podcast-episode__meta {
  margin: 0 0 0.35rem;
  color: var(--color-muted, #454650);
}

.podcast-page .podcast-episode__title {
  margin: 0 0 0.5rem;
  color: var(--color-brand, #263279);
}

.podcast-page .podcast-episode__links {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin: 0.75rem 0 0;
}

.podcast-page .podcast-episode__play {
  flex-shrink: 0;
}

.podcast-page .podcast-howto {
  margin-block: 1.25rem;
}

.podcast-page .podcast-step-num {
  width: 2.75rem;
  height: 2.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 0 0.75rem;
  border-radius: 50%;
  background: var(--color-accent-wash, #acf775);
  color: var(--color-brand, #263279);
  font-weight: 800;
  font-size: 1.25rem;
}

.podcast-page .podcast-clubhouse {
  margin-top: 1.25rem;
}

.podcast-page .podcast-show-more {
  margin: 1.25rem 0 0;
}

.podcast-page .podcast-show-more__link {
  font-weight: 700;
  text-decoration: underline;
}

.podcast-page .podcast-ask {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: var(--color-surface-alt, #e5e8ee);
  --podcast-ask-photo: none;
}

.podcast-page .podcast-ask::after {
  content: "";
  position: absolute;
  inset: 0 0 0 auto;
  width: 30%;
  z-index: 0;
  pointer-events: none;
  background-image: var(--podcast-ask-photo);
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center right;
  -webkit-mask-image: linear-gradient(to left, #000 25%, transparent);
  mask-image: linear-gradient(to left, #000 25%, transparent);
}

.podcast-page .podcast-ask > * {
  position: relative;
  z-index: 1;
}

@media (max-width: 640px) {
  .podcast-page .podcast-ask::after {
    width: 42%;
    opacity: 0.4;
  }
}

/* Find Resources — marina card CTA only. Other cards stay .btn--accent. */
.resources-grid .osta-marina-find-card a.btn--marina-guide,
.resources-grid .osta-marina-find-card .btn.btn--marina-guide {
  display: block;
  width: 100%;
  text-align: center;
  background: var(--color-brand);
  color: var(--color-surface);
  border: 3px solid var(--color-brand);
}

.resources-grid .osta-marina-find-card a.btn--marina-guide:hover,
.resources-grid .osta-marina-find-card a.btn--marina-guide:focus-visible,
.resources-grid .osta-marina-find-card a.btn--marina-guide:active {
  background: var(--color-brand-hover);
  border-color: var(--color-brand-hover);
  color: var(--color-surface);
}

/* Marina hub — court-papers card + centered Get help from OSTA box only. */
.osta-marina-hub-v1 .osta-marina-court-card {
  margin-bottom: var(--space-4);
}

.osta-marina-hub-v1 .osta-marina-help-cta,
.osta-marina-hub-v1 .osta-marina-help-cta :where(h1, h2, h3, p, .is-style-osta-eyebrow) {
  text-align: center;
}

.osta-marina-hub-v1 .osta-marina-help-cta .resident-assoc-actions,
.osta-marina-hub-v1 .osta-marina-help-cta .resident-assoc-actions.wp-block-group,
body .page-with-sidebar__main .osta-marina-hub-v1 .osta-marina-help-cta .resident-assoc-actions.wp-block-group {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  width: 100%;
}

.osta-marina-hub-v1 .osta-marina-help-cta .resident-assoc-actions > a.btn {
  margin-left: 0;
  margin-right: 0;
}

.osta-leader-cards {
  margin-bottom: var(--space-6, 1.5rem);
}

.osta-leader-card {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  margin: 0 0 1rem;
  padding: 1rem 0;
}

.osta-leader-card__photo img {
  width: 72px;
  height: 72px;
  object-fit: cover;
  border-radius: 50%;
}

.osta-leader-card__role {
  margin: 0;
  font-size: 0.8125rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.osta-leader-card__name {
  margin: 0.25rem 0;
  font-size: 1.125rem;
}

.osta-leader-card__bio,
.osta-leader-card__contact {
  margin: 0.35rem 0 0;
}

.osta-leader-manage {
  margin-bottom: 1.5rem;
}

.osta-leader-manage form + form {
  margin-top: 0.75rem;
}



