/* Band + FAQ styles for the MIGRATED service pages (/fitness-equipment-repair/, /pm-programs/,
   /installation/), extracted from region.css.

   WHY THIS FILE EXISTS. Those pages already carry a complete Elementor stylesheet of their own.
   The first attempt simply injected region.css so the appended blocks would pick up the band
   system — but region.css is not a component stylesheet, it is the FULL stylesheet for the
   generated pages: 852 of its selectors are unscoped, including *, body, h1/h2/h3, p, a, img and
   the form controls. Loading it on a page that already has its own reset restyles that page's
   existing content, which is exactly the design damage the owner reported on the service pages.

   This carries ONLY the classes the appended blocks use, so nothing outside those blocks is
   touched. Generated pages that region.css fully owns (city, facility, equipment, and the
   standalone service pages) keep loading region.css itself and are unaffected.

   Regenerate rather than hand-edit if the bands change: the extraction script is in the commit
   for this file. */

.osf-region-pm{margin:28px 0}

.osf-region-pm h3{margin:0 0 10px}

.osf-pm-tiers{list-style:none;margin:14px 0 0;padding:0;display:grid;gap:12px}

.osf-pm-tiers li{padding:12px 16px;border:1px solid #e3e3e3;border-radius:4px;background:#fff}
@media (min-width:820px){.osf-pm-tiers{grid-template-columns:repeat(3,1fr)}}

.osf-region-creds{margin:28px 0}

.osf-region-creds h3{margin:0 0 10px}

.osf-brand-list{font-size:.95rem;color:#555;margin-top:10px}

.osf-region-stats{margin:28px 0}

.osf-region-stats h3{margin:0 0 10px}

.osf-region-stats p{margin:0 0 12px;line-height:1.7}


/* ===== Region section rhythm (2026-08-12) =====
   The blocks previously carried their own 28px margins, producing uniform ~66px voids with
   nothing tying them together — sections read as separately pasted panels. One shared class now
   sets the rhythm: equal padding, a hairline rule between sections instead of empty space, and a
   consistent heading scale so each section reads as part of one page. */
.osf-region-block{margin:0;padding:26px 0;border-top:1px solid #e8e8e8}

.osf-region-block:first-child{border-top:0}

.osf-region-block > .osf-widget-container{max-width:100%}

.osf-region-block h3{margin:0 0 14px;font-size:1.45rem;line-height:1.25;color:#363231}

.osf-region-block p{margin:0 0 14px;line-height:1.7}

.osf-region-block p:last-child{margin-bottom:0}

/* PM tier cards: tighter, aligned, and they carry the section's bottom edge */
.osf-pm-tiers{margin:16px 0 14px;gap:14px}

.osf-pm-tiers li{padding:14px 16px;line-height:1.55}

.osf-brand-list{margin-top:12px}

.osf-region-nearby{padding-bottom:26px}


/* ===== City-page visual language (2026-08-12) =====
   Borrowed from the maintenance/home pages rather than invented: brand orange #F48F20, the
   "Days One" display face for headings, orange blocks on white cards, and a dark charcoal panel
   for contrast. The sections previously differed only by a hairline rule, which read as one long
   undifferentiated column. */

/* Section headings get an orange accent bar, matching the site's heading treatment */
.osf-region-block h3{position:relative;padding-bottom:12px;margin-bottom:18px;font-family:"Days One",sans-serif;font-weight:400;color:#111;font-size:1.5rem}

.osf-region-block h3::after{content:"";position:absolute;left:0;bottom:0;width:56px;height:3px;background:#F48F20;border-radius:2px}


/* BRANDS/CREDENTIALS — dark panel. High contrast breaks the page into halves. */
.osf-region-creds{border-top:0;padding:0;margin:30px 0}

.osf-region-creds > .osf-widget-container{background:#2b2b2b;color:#f2f2f2;padding:30px 32px;border-radius:6px}

.osf-region-creds h3{color:#fff}

.osf-region-creds h3::after{background:#F48F20}

.osf-region-creds p{color:#e2e2e2}

.osf-region-creds .osf-brand-list{color:#c9c9c9;font-size:.95rem;border-top:1px solid #444;padding-top:14px;margin-top:16px}


/* PM TIERS — white cards with an orange header strip, echoing the maintenance-page cards */
.osf-pm-tiers li{padding:0;overflow:hidden;border:1px solid #e6e6e6;border-radius:6px;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.06)}

.osf-pm-tiers li{padding-bottom:16px}

.osf-pm-tiers li{line-height:1.55}

.osf-pm-tiers li:not(.osf-pm-tier-name){}

.osf-pm-tiers li > *:not(.osf-pm-tier-name){padding:0 16px}


/* NEARBY — light panel, quietest section */
.osf-region-nearby{border-top:0;padding:0;margin:30px 0}

.osf-region-nearby > .osf-widget-container{background:#f6f6f6;padding:24px 28px;border-radius:6px}

/* Band link color is #a85f0c, a darkened brand orange, NOT the brand #f48f20. The previous
   #c47612 measured 3.53:1 on white and these links are 16px/600 — under the 18.66px-bold cutoff,
   so WCAG AA wants 4.5:1, not 3.0. #a85f0c measures 4.88:1 and still reads as the brand orange.
   The brand orange itself is kept everywhere it is a large button label or sits on a dark band. */
.osf-region-nearby a{color:#a85f0c;font-weight:600}


/* STATS — plain, but the lead sentence carries weight */
.osf-region-stats{border-top:0;padding-top:6px}

/* 1.12rem at EVERY width, not 1.06rem below 900px. The section-intro paragraph and the answer
   capsule are the same treatment — the page's one lead style — and a media query was shrinking
   only the intro on phones, so mobile rendered a lead at 1.06rem/1.7 AND a capsule at 1.12rem/1.7
   while desktop rendered one lead size. Two lead sizes is the drift this scale exists to prevent;
   it just happened to be invisible unless you measured at 390. */
.osf-region-stats p:first-of-type{font-size:1.12rem;color:#2b2b2b}


/* ===== Refinement pass (2026-08-12) — spacing + asymmetric layout =====
   Two problems: the PM tier body text had no horizontal padding (the CSS targeted child ELEMENTS,
   but the description is a bare text node, so it sat flush to the card edge), and every section was
   a single full-width column, which reads as a wall. fitsupply.com's services pages break their
   sections into asymmetric two-column blocks; the same idea is applied here. */

/* PM cards: pad the LI and let the orange header bleed out via negative margin, so the body text
   is properly inset without needing a wrapper element around a text node. */
.osf-pm-tiers li{padding:0 18px 18px;line-height:1.65}

.osf-pm-tiers{gap:18px;margin:20px 0 16px}
@media (min-width:900px){
  .osf-region-creds > .osf-widget-container{display:grid;grid-template-columns:1fr 1fr;gap:34px;align-items:start}
  .osf-region-creds h3{grid-column:1 / -1;margin-bottom:6px}
  .osf-region-creds .osf-brand-list{border-top:0;border-left:1px solid #4a4a4a;padding:2px 0 2px 30px;margin:0}}
@media (min-width:900px){
  .osf-region-stats p:first-of-type{font-size:1.12rem;line-height:1.75;max-width:92%}
  .osf-region-stats p:last-of-type{border-left:3px solid #f0f0f0;padding-left:22px;margin-left:2px;color:#444}}
@media (min-width:900px){
  .osf-region-nearby > .osf-widget-container{display:grid;grid-template-columns:minmax(0,30%) minmax(360px,1fr);column-gap:26px;row-gap:0;align-items:start}
  /* The label spans every row and the paragraphs all go in column 2. WITHOUT THIS the band is a
     plain 2-column grid and auto-placement puts child 3 back in column 1: these bands carry a
     heading and TWO paragraphs, so the second paragraph landed under the label in the 312px
     column, bordered, reading as a stray sidebar. That is the flaw the owner saw on /mirrors/ and
     /relocation/. Fixing the column widths alone did not fix it — the second paragraph was still
     in the wrong column, just a wider wrong column. */
  .osf-region-nearby > .osf-widget-container > h2,
  .osf-region-nearby > .osf-widget-container > h3{grid-column:1;grid-row:1 / -1;align-self:center;margin:0;padding-bottom:0}
  .osf-region-nearby > .osf-widget-container > h3::after{display:none}
  /* Row-gap is 0 and the spacing lives in the padding, so the 3px rule down column 2 is one
     continuous line instead of one detached segment per paragraph. */
  .osf-region-nearby > .osf-widget-container > p{grid-column:2;margin:0;border-left:3px solid #e3e3e3;padding:0 0 0 26px}
  .osf-region-nearby > .osf-widget-container > p + p{padding-top:14px}}


/* ===== Column alignment (2026-08-12) =====
   The page's own body copy sits in an Elementor widget set to ~63% width, centred (783px inside a
   1240px container). The region blocks were rendering at the FULL 1240px, so their left edge began
   ~229px further out than every original paragraph — the page looked broken rather than designed.
   Matching the same measure aligns both edges and keeps line length readable (~90 characters). */
.osf-region-block{width:63%;margin-left:auto;margin-right:auto}

/* Panels read as deliberate feature elements, so they may run a little wider than body copy —
   still centred on the same axis, which keeps the page's spine intact. */
.osf-region-creds,.osf-region-pm{width:78%}
@media (max-width:900px){.osf-region-block,.osf-region-creds,.osf-region-pm{width:100%}}


/* ===== Color contrast on the upper sections (2026-08-12) =====
   The dark brands panel and the orange-headed PM cards give the lower half of the page its shape.
   The top half had none, so it read flat by comparison. These use the same IDEA — a panel with a
   color shift — without repeating the same treatment, so the page builds rather than echoes:
     Why Choose  -> light grey panel, orange top edge
     Stats       -> warm cream panel, orange left edge
     Brands      -> dark charcoal (existing)
     PM tiers    -> white cards, orange headers (existing) */

.osf-why-panel{
  background:#f4f4f4;border-top:4px solid #F48F20;border-radius:0 0 8px 8px;
  padding:34px 38px 28px;margin:6px 0 0}

.osf-why-panel h3.osf-heading-title{margin-bottom:18px}

.osf-why-panel p{color:#3a3a3a}

.osf-why-panel p:last-child{margin-bottom:0}


/* Stats — warm cream, orange left edge. Related to the Why Choose panel, not identical. */
.osf-region-stats{
  background:#fdf6ec;border-left:4px solid #F48F20;border-radius:0 8px 8px 0;
  padding:26px 30px;margin:30px auto}

.osf-region-stats h3{margin-top:0}

.osf-region-stats p:last-of-type{border-left:0;padding-left:0;margin-left:0;color:#4a4a4a}


/* ===== One panel measure (2026-08-12) =====
   Mixed widths were the problem: the Why Choose panel ran the full 1240px while the copy inside it
   was constrained to 63%, so two-fifths of the panel was empty; the stats panel then sat at a third
   width again. Every panel now shares one 78% measure, centred on the same axis, and the widgets
   inside the Why Choose panel are released to fill it. */
.osf-region-block,.osf-region-creds,.osf-region-pm{width:78%}

.osf-why-panel{width:78%;margin:6px auto 0}

.osf-why-panel > .osf-element{width:100%;max-width:100%}

.osf-region-stats{margin-left:auto;margin-right:auto}
@media (max-width:900px){.osf-why-panel{width:100%}}


/* FAQs */
.osf-faq{width:78%;margin:0 auto;padding:6px 0 46px}

.osf-faq h2.osf-heading-title{
  position:relative;padding-bottom:14px;margin:0 0 24px;
  font-family:"Days One",sans-serif;color:#111;font-size:1.7rem}

.osf-faq h2.osf-heading-title::after{
  content:"";position:absolute;left:0;bottom:0;width:64px;height:3px;background:#F48F20;border-radius:2px}
@media (max-width:900px){.osf-faq,.osf-closing-panel{width:100%}}


/* ===== FAQ cards in the maintenance-page style (2026-08-12) =====
   White card, orange icon block on the left with the site's own angled edge
   (.matter-icon => clip-path: polygon(0 0, 100% 0, 95% 100%, 0% 100%)), bold question, answer
   beneath. Replaces the plain left-rule cards. */
.osf-faq-item{
  display:flex;align-items:stretch;gap:0;
  background:#fff;border:1px solid #e6e6e6;border-left:0;border-radius:2px;
  padding:0;margin:0 0 16px;overflow:hidden;
  box-shadow:0 2px 6px rgba(0,0,0,.07)}

.osf-faq-item:nth-child(even){background:#fff}

.osf-faq-icon{
  flex:0 0 88px;background:#F48F20;display:flex;align-items:center;justify-content:center;
  padding:22px 14px}

.osf-faq-body{flex:1 1 auto;padding:20px 26px 20px 18px;min-width:0}

.osf-faq-q{
  font-family:"Days One",sans-serif;font-weight:400;font-size:1.06rem;color:#1c1c1c;
  margin:0 0 8px;line-height:1.35}

.osf-faq-a{margin:0;line-height:1.75;color:#444}
@media (max-width:620px){
  .osf-faq-icon{flex:0 0 62px;padding:16px 8px}
  .osf-faq-icon svg{width:24px;height:24px}
  .osf-faq-body{padding:16px 18px 16px 14px}}


/* .matter-icon is defined in another page's stylesheet, which region pages never load — the clip
   silently did nothing. Declared here instead, with a deeper cut than the original 5% so the angle
   actually reads at this block width. Selectors are prefixed with .osf-faq to beat the earlier
   card padding that was leaving white gaps above and below the orange block. */
.osf-faq .osf-faq-item{padding:0;align-items:stretch}

.osf-faq .osf-faq-icon{
  flex:0 0 96px;padding:0;align-self:stretch;
  clip-path:polygon(0 0, 100% 0, 84% 100%, 0% 100%)}

.osf-faq .osf-faq-body{padding:20px 28px 20px 14px}
@media (max-width:620px){
  .osf-faq .osf-faq-icon{flex:0 0 66px;clip-path:polygon(0 0,100% 0,88% 100%,0 100%)}
  .osf-faq .osf-faq-body{padding:16px 18px 16px 10px}}


/* custom.css carries an older "Service-region FAQ block" (.osf-faq .osf-faq-item{padding:18px 0;
   border-bottom:...}
) which overrides the card layout and leaves white gaps above and below the
   orange block. Won on specificity from here instead of editing custom.css.
   NOTE (2026-08-13): the original reason for that choice is gone — every stylesheet is now
   cache-busted (Base.astro stamps ?v=ASSET_REV on all of them), so custom.css is safe to edit.
   The escalation is kept anyway, because that custom.css block is NOT dead: it is the FAQ styling
   the 11 blog POSTS rely on (they load neither region.css nor, until now, custom.css — see the
   answer-capsule block in blog.css). Deleting it there to simplify here would strip the blog FAQ.
   The two treatments are deliberately different: cards with the angled orange icon on region
   pages, a stacked list on posts, which have no .osf-faq-icon in the markup. */
.container.osf-faq .osf-faq-item{
  padding:0;border-bottom:0;align-items:stretch;
  border:1px solid #e6e6e6;border-radius:2px;overflow:hidden;
  box-shadow:0 2px 6px rgba(0,0,0,.07);margin:0 0 16px;background:#fff}

.container.osf-faq .osf-faq-icon{
  flex:0 0 96px;padding:0;align-self:stretch;background:#F48F20;
  display:flex;align-items:center;justify-content:center;
  clip-path:polygon(0 0, 100% 0, 84% 100%, 0% 100%)}

.container.osf-faq .osf-faq-body{padding:20px 28px 20px 14px}

.container.osf-faq .osf-faq-q{font-family:"Days One",sans-serif;font-weight:400;font-size:1.06rem;color:#1c1c1c;margin:0 0 8px;line-height:1.35}

.container.osf-faq .osf-faq-a{margin:0;line-height:1.75;color:#444}
@media (max-width:620px){
  .container.osf-faq .osf-faq-icon{flex:0 0 66px;clip-path:polygon(0 0,100% 0,88% 100%,0 100%)}
  .container.osf-faq .osf-faq-body{padding:16px 18px 16px 10px}}


/* ===== Regions hub: cumulative stats (2026-08-12) =====
   The regions page is the cover page for the 47 city pages, so it carries the company-wide totals
   while each city page carries its own local detail. Same panel language as the city pages. */
/* min-width:0 IS LOad-BEARING — it fixes horizontal scroll on phones.
   This block is a flex ITEM (its parent .ose-con-inner is display:flex), and a flex item defaults
   to min-width:auto, meaning it will not shrink below its min-content width. The stat grid's
   min-content width is 377px, so inside a 286px parent at a 390px viewport the block stayed 377px
   wide and pushed the document to 427px — every hub and standalone service page scrolled sideways
   on a phone. Measured on /mirrors/, /services/, /equipment/, /facilities/, /warranty-repair/,
   /relocation/ and /equipment-removal/. */
.osf-hub-stats{max-width:1140px;margin:0 auto;padding:44px 20px 8px;min-width:0}

.osf-hub-stats h2.osf-heading-title{
  position:relative;padding-bottom:14px;margin:0 0 24px;
  font-family:"Days One",sans-serif;color:#111;font-size:1.7rem}

.osf-hub-stats h2.osf-heading-title::after{
  content:"";position:absolute;left:0;bottom:0;width:64px;height:3px;background:#F48F20;border-radius:2px}

.osf-stat-grid{list-style:none;display:grid;grid-template-columns:repeat(2,1fr);gap:16px;padding:0;margin:0 0 26px}

.osf-stat-grid li{
  background:#2b2b2b;border-top:4px solid #F48F20;border-radius:0 0 6px 6px;
  padding:20px 22px;display:flex;flex-direction:column;gap:6px}

.osf-stat-n{font-family:"Days One",sans-serif;font-size:1.9rem;line-height:1;color:#F48F20}

.osf-stat-l{color:#e2e2e2;font-size:.97rem;line-height:1.45}

.osf-hub-stats p{line-height:1.75;margin:0 0 14px}
@media (min-width:900px){.osf-stat-grid{grid-template-columns:repeat(4,1fr)}}


/* The hub's migrated body copy is justified, which opens rivers at this measure */
.osf-hub-stats p,.osf-suburbs p,.trust-services-section p{text-align:left}

/* tighten the vertical rhythm between hub sections */
body.osf-page-77 .osf-hub-stats{padding:26px 20px 6px}


/* ===== Hub dead space (2026-08-12) =====
   The blocks I inserted landed inside an outer .ose-con-inner carrying padding:100px 0 — that,
   not my own spacing, was the ~250px void above the stats banner. :has() lets me collapse only
   the wrappers that contain my sections, leaving the migrated Elementor sections untouched. */
body.osf-page-77 .ose-con-inner:has(> .ose-con-boxed .osf-hub-stats),
body.osf-page-77 .ose-con-inner:has(> .ose-con-boxed .osf-hub-faq),
body.osf-page-77 .ose-con-inner:has(> .ose-con-boxed .osf-suburbs),
body.osf-page-77 .ose-con-inner:has(.osf-hub-stats),
body.osf-page-77 .ose-con-inner:has(.osf-hub-faq),
body.osf-page-77 .ose-con-inner:has(.osf-suburbs){padding-top:22px;padding-bottom:22px}


/* ===== Hub stats band (2026-08-12) =====
   The transition from "Professional Care" into the stats was just whitespace. The whole section
   now sits on a full-width dark band with an orange top rule — a hard color change, which is the
   strongest transition available and matches how the rest of the site separates sections. Tiles
   invert to white on the dark ground so they still read as cards. */

body.osf-page-77 .osf-hub-stats h2.osf-heading-title{color:#fff}

body.osf-page-77 .osf-hub-stats p{color:#dcdcdc}

body.osf-page-77 .osf-hub-stats strong{color:#fff}

body.osf-page-77 .osf-stat-grid li{
  background:#fff;border-top:4px solid #F48F20;box-shadow:0 2px 8px rgba(0,0,0,.28)}

body.osf-page-77 .osf-stat-n{color:#c96f0c}

body.osf-page-77 .osf-stat-l{color:#444}

/* The band was inset 20px by its parent's padding while the dark section beneath it runs edge to
   edge — two dark blocks at different widths, which reads as a mistake. Pull it full-bleed and
   re-apply the inset to its own padding so the content stays aligned with everything else. */


/* ===== Stats band, take two (2026-08-12) =====
   The band was applied to the shared .ose-con-inner wrapper, which also contains the next section
   — so the dark ground bled down behind "What We Can Do for You". And negative margins alone made
   it full-bleed on the left only. Applying it to the stats block itself with the standard
   100vw / calc(50% - 50vw) full-bleed keeps it symmetric and confined to its own section. */
body.osf-page-77 .osf-hub-stats{
  background:#2b2b2b;border-top:4px solid #F48F20;border-bottom:4px solid #F48F20;
  width:100vw;max-width:100vw;margin-left:calc(50% - 50vw);margin-right:calc(50% - 50vw);
  padding:34px max(20px, calc(50vw - 570px));box-sizing:border-box}

body.osf-page-77 .ose-con-inner:has(.osf-hub-stats){padding-top:0;padding-bottom:0;background:transparent}


/* ===== FULL-BLEED SECTION BANDS (2026-08-12) =====
   The panels stopped short of the viewport edges, leaving white gutters, while the site's own
   dark sections and the hub stats band run edge to edge. Modern convention — and the rest of this
   site — is a full-width color band with the copy centred inside it. Every region section now
   uses one full-bleed pattern with content locked to a single 1040px measure, so the left edge of
   the text is identical from the top of the page to the bottom.
   100vw + calc(50% - 50vw) is the standard technique; the padding formula re-centres the content. */
.osf-region-block,
.osf-why-panel,
.osf-closing-panel,
body.osf-page-77 .osf-hub-panel{
  width:100vw;max-width:100vw;
  margin-left:calc(50% - 50vw);margin-right:calc(50% - 50vw);
  padding-left:max(20px, calc(50vw - 520px));
  padding-right:max(20px, calc(50vw - 520px));
  border-radius:0;box-sizing:border-box}


/* alternating grounds down the page — color, not whitespace, marks each section */
.osf-region-stats{background:#fdf6ec;border-left:0;border-top:3px solid #F48F20;padding-top:30px;padding-bottom:30px}

.osf-region-creds{background:#2b2b2b;padding-top:34px;padding-bottom:34px;border-top:3px solid #F48F20}

.osf-region-creds > .osf-widget-container{background:transparent;padding:0;border-radius:0}

.osf-region-pm{background:#f6f6f6;padding-top:32px;padding-bottom:32px;border-top:1px solid #ececec}

.osf-region-nearby{background:#fff;padding-top:26px;padding-bottom:30px;border-top:1px solid #ececec}

.osf-region-nearby > .osf-widget-container{background:transparent;padding:0;border-radius:0}

.osf-why-panel{background:#f4f4f4;padding-top:34px;padding-bottom:28px}

body.osf-page-77 .osf-hub-stats{padding-left:max(20px, calc(50vw - 520px));padding-right:max(20px, calc(50vw - 520px))}

/* Citations block on the vertical pages — same band system, quieter ground */
.osf-region-refs{background:#f6f6f6;padding-top:30px;padding-bottom:30px;border-top:1px solid #ececec}

.osf-region-refs a{color:#a85f0c;font-weight:600}

.osf-region-refs a:hover{text-decoration:underline}


/* ===== h2 parity for the facility pages ===== */
/* region.css was written when every section heading was an <h3>. The facility pages use <h2>
   (correct under their <h1>), so they inherited none of the band styling — no orange rule,
   and dark text on the dark brands panel. Generated from the h3 rules so the two cannot drift. */
.osf-region-pm h2{margin:0 0 10px}

.osf-region-creds h2{margin:0 0 10px}

.osf-region-stats h2{margin:0 0 10px}

.osf-region-block h2{margin:0 0 14px;font-size:1.45rem;line-height:1.25;color:#363231}

.osf-region-block h2{position:relative;padding-bottom:12px;margin-bottom:18px;font-family:"Days One",sans-serif;font-weight:400;color:#111;font-size:1.5rem}

.osf-region-block h2::after{content:"";position:absolute;left:0;bottom:0;width:56px;height:3px;background:#F48F20;border-radius:2px}

.osf-region-creds h2{color:#fff}

.osf-region-creds h2::after{background:#F48F20}

.osf-region-creds h2{grid-column:1 / -1;margin-bottom:6px}

.osf-region-nearby h2{margin:0;padding-bottom:0;white-space:nowrap}

.osf-region-nearby h2::after{display:none}

.osf-why-panel h2.osf-heading-title{margin-bottom:18px}

.osf-region-stats h2{margin-top:0}

/* The facility pages lead with an <h1> inside the same panel the region pages fill with a heading. */
.osf-why-panel h1.osf-heading-title{margin:0 0 18px;font-size:1.9rem;line-height:1.2;color:#363231;position:relative;padding-bottom:14px}

.osf-why-panel h1.osf-heading-title::after{content:"";position:absolute;left:0;bottom:0;width:56px;height:3px;background:#F48F20;border-radius:2px}

.osf-region-refs h2::after{background:#F48F20}

.osf-region-refs p{margin:0 0 14px;line-height:1.75}

.osf-region-refs p:last-child{margin-bottom:0}


/* Facility hub cards + the vertical pages' lead capsule (the H1 now lives in the page banner
   like every other page, so the panel below it carries the answer capsule alone). */
.osf-vertical-capsule{font-size:1.12rem;line-height:1.75;color:#3a3a3a;margin:0}

.osf-facility-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:14px;margin-top:6px}

.osf-facility-card{display:flex;flex-direction:column;gap:5px;background:#fff;border:1px solid #e6e6e6;border-left:4px solid #F48F20;border-radius:6px;padding:16px 18px;text-decoration:none;transition:box-shadow .15s ease,transform .15s ease}

.osf-facility-card:hover{box-shadow:0 6px 18px rgba(0,0,0,.09);transform:translateY(-2px)}

.osf-facility-card-name{font-weight:700;color:#2b2b2b;font-size:1.02rem;line-height:1.3}

.osf-facility-card-meta{color:#6d6d6d;font-size:.87rem}


/* ===== Equipment-type pages (2026-08-13) =====
   Only two new classes; everything else on these pages reuses the region band system above.
   .osf-region-symptoms and .osf-region-refs need no rules of their own — they inherit the
   .osf-region-block banding, and the h2 parity rules further up already cover their headings. */
.osf-symptom-list{max-width:1040px;margin:0 auto;padding:0;list-style:none}

.osf-symptom-list li{
  position:relative;padding:12px 0 12px 26px;border-bottom:1px solid rgba(0,0,0,.08);line-height:1.7}

.osf-symptom-list li:last-child{border-bottom:0}

.osf-symptom-list li::before{
  content:"";position:absolute;left:4px;top:21px;width:8px;height:8px;
  background:#F48F20;border-radius:50%}

.osf-symptom-list strong{color:#1c1c1c}

/* Two columns for the PM checklist — these run to 13 items and read as a wall in one column. */
.osf-pm-checklist{
  max-width:1040px;margin:0 auto 18px;padding:0 0 0 20px;
  columns:2;column-gap:38px;line-height:1.85}

.osf-pm-checklist li{break-inside:avoid}
@media (max-width:700px){
  .osf-pm-checklist{columns:1}}

/* ===== Layout guards for the appended blocks on MIGRATED pages =====
   The blocks deliberately carry no Elementor container classes (ose-con / ose-flex / osf-element).
   On a migrated page those resolve through --display and produced a band with clientWidth 0, so
   its horizontal padding never created a content box and every child sat flush at x=0 across the
   full viewport width. These pin the layout explicitly instead of inheriting it. */
.osf-service-extra{display:block;width:100%}
.osf-region-block{display:block;box-sizing:border-box}
.osf-region-block > .osf-widget-container{display:block;box-sizing:border-box;max-width:100%}

/* The FAQ block on a migrated page inherits that page's own .container width (1120px) rather than
   the 78% measure region.css gives it on generated pages (802px). Pinned to the same 1040px measure
   the bands above it use, so the appended section reads as one column rather than two widths. */
.osf-service-extra .osf-faq{max-width:1040px;margin-left:auto;margin-right:auto;width:100%}

/* ===== Dark band readability (2026-08-14) =====
   .osf-region-creds is a near-black band (#2b2b2b). The symptom/checklist list styling sets
   `strong{color:#1c1c1c}` for the LIGHT bands, which inside this one is 1.20:1 against the
   background — effectively invisible, and reported by the owner as unreadable text on the
   service pages. Anything falling back to the inherited #333 body color is 1.12:1, no better.
   These pin readable colors for every text element the bands can contain.
   Measured: #e2e2e2 = 10.9:1, #ffffff = 14.2:1, the orange link = 5.9:1. All clear AA; the
   body and bold text clear AAA. */
.osf-region-creds{color:#e2e2e2}
.osf-region-creds p,
.osf-region-creds li,
.osf-region-creds .osf-symptom-list li{color:#e2e2e2}
.osf-region-creds strong,
.osf-region-creds .osf-symptom-list strong{color:#fff}
.osf-region-creds a{color:#f9b45c}
.osf-region-creds a:hover,.osf-region-creds a:focus{color:#ffd9a8}

/* ===== One typography scale for the band content (2026-08-14) =====
   Owner reported the fonts reading as inconsistent between sections and between pages, and he
   was right — the family was fine (Roboto throughout) but the SCALE had drifted. Measured on a
   single equipment page, body copy was rendering at EIGHT different size/leading combinations:

     lead capsule      17.92 / 30.46      brand list        15.20 / 25.84
     some paragraphs   17.92 / 31.36      PM checklist      16 / 29.60
     most paragraphs   16    / 27.20      PM tier list      16 / 26.40
     other paragraphs  16    / 28.00      FAQ answers       16 / 27.52

   Each was individually reasonable — 1.7 here, 1.72 there, 1.85 on a list, a rem-based size on
   another — and together they read as sloppy, because a reader notices leading changing between
   two paragraphs even when they cannot say why.

   Collapsed to a deliberate TWO-step scale. Everything below is scoped to the band/FAQ/stat
   blocks, so the migrated pages' own Elementor copy keeps the design it shipped with and is not
   restyled by this.
     lead  1.12rem / 1.7    — the answer capsule only
     body  1rem    / 1.75   — every paragraph and list item in the blocks

   BODY LEADING IS 1.75, NOT 1.72, AND THAT NUMBER IS NOT ARBITRARY: it is what the untouched
   Elementor copy on the migrated pages already computes to (16px -> 28px). Leaving the appended
   bands at 1.72 meant /installation/ rendered its original three paragraphs at 16/28 and every
   appended paragraph at 16/27.52 — two body styles on one page, which is the drift this block
   exists to remove. Matching the host page makes the migrated pages internally uniform and, since
   the generated pages use the same rules, makes the whole site one body scale.
   Specificity is (0,2,0) so it beats the single-class rules that set the old values. */
.osf-region-block .osf-vertical-capsule,
.osf-service-extra .osf-vertical-capsule{font-size:1.12rem;line-height:1.7}

.osf-region-block p,
.osf-region-block li,
.osf-region-block .osf-brand-list,
.osf-region-block .osf-symptom-list li,
.osf-region-block .osf-pm-checklist li,
.osf-region-block .osf-pm-tiers li,
.osf-service-extra p,
.osf-service-extra li,
.osf-faq .osf-faq-a,
.osf-hub-stats p{font-size:1rem;line-height:1.75}

/* Two lead treatments existed at the same SIZE but different leading — the answer capsule at
   1.12rem/1.7 and the section-intro paragraph (.osf-region-stats p:first-of-type) at 1.12rem/1.75.
   The larger intro size is a deliberate, pre-existing choice on the city pages and is kept; only
   the leading is unified, so the scale is now exactly two steps everywhere:
     lead 1.12rem / 1.7      body 1rem / 1.72 */
.osf-region-block .osf-region-stats p:first-of-type,
.osf-region-stats p:first-of-type,
.osf-service-extra .osf-region-stats p:first-of-type{line-height:1.7}

/* Inline links inside the content bands. The Elementor kit sets ALL links to the brand primary
   #f48f20 via `.osf-kit-9 a`, which measures 2.21:1 on white — well under the 4.5:1 WCAG AA wants
   for 16px/400 body text, and visibly hard to read in a paragraph. This scopes the readable
   #a85f0c (4.88:1) to the bands authored here, matching .osf-region-nearby a and .osf-region-refs a
   so every link in a band is one color. The GLOBAL kit link color is deliberately left alone: it
   also styles the migrated pages' original copy, and changing it is a sitewide design decision for
   the owner, not a side effect of a contrast fix. Specificity (0,2,1) beats `.osf-kit-9 a` (0,1,1). */
.osf-region-block p a,
.osf-region-block li a,
.osf-service-extra p a,
.osf-service-extra li a{color:#a85f0c}

/* The dark credentials band keeps its light link color. The rule above (.osf-region-block p a,
   specificity 0,1,2) outranks the original `.osf-region-creds a` (0,1,1), so adding a readable
   link color for light bands silently repainted the DARK band's links #a85f0c on #2b2b2b — 2.9:1,
   worse than the 1.20:1 dark-band problem this project already fixed once. Caught by the probe on
   the very next run, which is the argument for the probe. (0,2,2) beats (0,1,2). */
.osf-region-block.osf-region-creds p a,
.osf-region-block.osf-region-creds li a,
.osf-region-creds p a,
.osf-region-creds li a{color:#f9b45c}

/* THE NEARBY BAND COLLAPSED TWICE. It is a two-column grid: a short label beside a line of links.
   With `grid-template-columns:auto 1fr` and a `white-space:nowrap` heading, a LONG heading takes
   the whole row as one unbreakable token and the paragraph gets whatever is left — measured at
   140px on /mirrors/ and 97px on /warranty-repair/, /relocation/ and /equipment-removal/, i.e. a
   ribbon of two or three words per line. The first fix was to keep the band's content short, which
   held only until the standalone service pages reused the band with real prose in it.
   This makes the collapse impossible instead: the label column is capped at 30% of the band, the
   text column can never go below 360px, and the heading wraps rather than reserving a whole row.
   30% and not max-content: these headings run from "Planning a move" to "Looking for your city or
   a specific machine?", and sizing to max-content handed the longest one 654px beside a 360px
   paragraph — no longer collapsed, still visibly wrong. A cap keeps every page in the set to the
   same label-beside-text proportions no matter how long the label is. */
.osf-region-nearby h2,
.osf-region-nearby h3{white-space:normal}

/* Below 430px the two-up stat grid has ~130px per tile, which is what drove the min-content width
   that broke the page open. One column per tile instead. */
@media (max-width:430px){.osf-stat-grid{grid-template-columns:1fr}}

/* Per-equipment maintenance tabs on /maintenance/ (src/data/pm-equipment.ts + pm-equipment-icons.ts).
   Styled to match the original tab section on /assembly/, which the owner asked for by name: the
   same background photo, the same dark overlay over it, icon-above-label tabs and an orange
   indicator under the active one.

   THE RULE THAT MAKES TWELVE TABS POSSIBLE: the migrated widget sets flex-wrap:nowrap on
   .eael-tabs-nav > ul, and .eael-tab-nav-item pins min/max-width to 220px. Four fit in a 1240px
   container and the rest go off-screen with no scroll affordance. The grid below replaces both,
   and is SCOPED to .osf-pm-tabs so /assembly/ keeps its four-up single row untouched. */
.osf-region-creds > .osf-widget-container:has(.osf-pm-tabs){
  background-color:#1c1c1c;
  background-image:linear-gradient(rgba(20,20,20,.85),rgba(20,20,20,.85)),url("/assets/onsitefitnessservice.com/content/uploads/2025/04/tab-section-bg.webp");
  background-position:center center;background-repeat:no-repeat;background-size:cover;
  padding:48px 32px;
}
.osf-region-creds > .osf-widget-container:has(.osf-pm-tabs) > h2{text-align:center;margin:0 0 8px}
.osf-region-creds > .osf-widget-container:has(.osf-pm-tabs) > p{text-align:center;max-width:760px;margin:0 auto 26px}

.osf-pm-tabs .eael-tabs-nav > ul{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;
  list-style:none;margin:0;padding:0;
}
.osf-pm-tabs .eael-tabs-nav > ul li{
  width:auto;min-width:0;max-width:none;height:auto;
  display:flex;flex-direction:column;align-items:center;gap:8px;
  padding:16px 8px 20px;cursor:pointer;position:relative;
  color:#9a9a9a;font-weight:700;text-align:center;line-height:1.25;
}
.osf-pm-tabs .eael-tabs-nav > ul li:hover{color:#fff}
.osf-pm-tabs .eael-tabs-nav > ul li.active{color:#fff}
/* Orange indicator under the selected tab — the marker in the original section. */
.osf-pm-tabs .eael-tabs-nav > ul li.active::after{
  content:"";position:absolute;bottom:2px;left:50%;transform:translateX(-50%);
  border-left:9px solid transparent;border-right:9px solid transparent;
  border-top:10px solid var(--c-primary,#F5811F);
}
.osf-pm-tabs .eael-tabs-nav > ul li svg{width:44px;height:44px;flex:none}
/* Inactive icons are drawn with stroke="black" and sit on a dark band, so without this they are
   invisible rather than merely dim. The theme only recolours .active and :hover. */
.osf-pm-tabs .eael-tabs-nav > ul li svg path{stroke:#9a9a9a}
.osf-pm-tabs .eael-tabs-nav > ul li:hover svg path,
.osf-pm-tabs .eael-tabs-nav > ul li.active svg path{stroke:#fff}
.osf-pm-tabs .eael-tab-title{display:block;overflow-wrap:anywhere;font-size:15px}

.osf-pm-tabs .eael-tabs-content{margin-top:26px;border-top:1px solid rgba(255,255,255,.15);padding-top:26px}
.osf-pm-tabs .eael-tabs-content > div{display:none}
.osf-pm-tabs .eael-tabs-content > div.active{display:block}
.osf-pm-tabs .eael-tabs-content h3{margin:0 0 12px;color:#fff}
.osf-pm-tabs .eael-tabs-content p{margin:0 0 12px;color:#e8e8e8;max-width:900px}
.osf-pm-tabs .eael-tabs-content strong{color:#fff}
/* Brand orange on the near-black panel measures ~6:1, above the 4.5:1 AA floor for body text.
   Do not swap this for a darker orange without re-checking against #141414. */
.osf-pm-tabs .osf-pm-equipment-more a{font-weight:700;color:var(--c-primary,#F5811F);text-decoration:underline}
.osf-pm-tabs .osf-pm-equipment-more a:hover{color:#fff}
@media (max-width:900px){.osf-pm-tabs .eael-tabs-nav > ul{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:560px){
  .osf-pm-tabs .eael-tabs-nav > ul{grid-template-columns:repeat(2,minmax(0,1fr))}
  .osf-region-creds > .osf-widget-container:has(.osf-pm-tabs){padding:34px 18px}
}

/* Owner, 2026-08-14: no orange accent bar inside the equipment tabs. `.osf-region-block h3::after`
   draws a 56x3 orange rule under every h3 in a band, which is right for the light service bands but
   wrong here — each of the twelve panes has an h3, so it repeated on every pane heading against the
   dark panel. Suppressed for this widget only; the bands keep it. */
.osf-pm-tabs .eael-tabs-content h3{padding-bottom:0}
.osf-pm-tabs .eael-tabs-content h3::after{content:none}

/* Tighten the transition into the relocated "Keep Your Fitness Equipment Running Like New!" section.
   It sits inside .osf-service-extra only because maintenance.astro moves it there (owner asked for
   it directly before the FAQs), and it carries the migrated 64px top/bottom container padding, which
   read as a hole under "Getting a plan quoted". Scoped to the relocated copy so the same markup
   keeps its original spacing anywhere it has not been moved. */
/* The class is trust-serviceS-sectioN, not .trust-service — an earlier attempt used the shortened
   name and silently did nothing, because a JS substring match found the element while the CSS class
   selector (which is exact) did not. And the padding is an Elementor CUSTOM PROPERTY, so overriding
   `padding` loses to `padding: var(--padding-top)`; the variable itself has to be set. */
/* FOUR classes deliberately. post-maintenance.css carries
     .osf-573 .osf-element.osf-element-161bc7be { --padding-top:64px }
   at (0,3,0) AND loads after this file, so (0,2,0) or even a tying (0,3,0) silently loses. Measured
   in the browser — the rule was present and the selector matched while the computed value stayed
   64px, which is exactly the ladder this repo has been bitten by before. */
.osf-service-extra .osf-element.osf-element-161bc7be.trust-services-section{--padding-top:34px;--padding-bottom:34px}
.osf-service-extra .osf-region-nearby{margin-bottom:8px}

/* The tile band on /maintenance/ ("Rapid response time…" etc). Owner, 2026-08-14: the grey panel
   should be the size needed to house the tiles, not carry dead space under them. The section runs
   to 64px bottom padding while the gap ABOVE the tile grid is ~50px, and with the phone-CTA row
   now removed that padding was the only thing left below the last tile. 32px balances it against
   the top gap.

   FOUR classes for the same reason as the trust-services override above: post-maintenance.css sets
   these Elementor --padding vars at (0,3,0) and loads after this file, so anything lower silently
   loses. Verify by computed value, not by the rule being present. */
.osf-element.osf-element-f10f9a9.matter-section.ose-con{--padding-bottom:32px}

/* "Getting a plan quoted" had its heading sitting flush on its first paragraph — zero gap, while
   every other band on the page has 18px. Cause: `.osf-region-nearby h2{margin:0}` above, written
   for the >=900px layout where this heading is a LABEL in a side column next to the paragraphs.
   In that arrangement no bottom margin is right. When the block renders stacked (which it does
   here — computed display was `block`, not `grid`), the same rule leaves the heading welded to the
   text. Restore the standard rhythm only when it is NOT the side-by-side grid, so both layouts
   stay correct. */
.osf-region-nearby > .osf-widget-container:not([style]) h2{margin-bottom:16px}
@media (min-width:900px){
  .osf-region-nearby > .osf-widget-container h2{margin-bottom:16px}
}

/* ===== Owner pass, 2026-08-14 (evening) — width + the last orange bar + a callout ===== */

/* 1. THE ORANGE BAR I MISSED. The earlier fix suppressed `.osf-pm-tabs .eael-tabs-content h3::after`
   — the twelve PANE headings — but the bar the owner kept seeing is on the SECTION heading, an h2
   that sits outside .osf-pm-tabs entirely. My verification only ever checked a pane heading, so it
   reported success on the half I had fixed. Same shape of error as grepping for the CTA text I had
   already removed. */
.osf-region-creds > .osf-widget-container:has(.osf-pm-tabs) > h2{padding-bottom:0}
.osf-region-creds > .osf-widget-container:has(.osf-pm-tabs) > h2::after{content:none}

/* 2. WIDER CONTENT COLUMN. The bands centre on `max(20px, -520px + 50vw)`, which pins the column to
   1040px — at 1440 that is 200px of dead margin each side, and it is what made the copy read narrow.
   -620px yields 1240px, using the width without running body text to an unreadable measure. */
.osf-region-block, .osf-why-panel, .osf-closing-panel{padding-left:max(20px, -620px + 50vw);padding-right:max(20px, -620px + 50vw)}
.osf-pm-tabs .eael-tabs-content p{max-width:1040px}
.osf-region-creds > .osf-widget-container:has(.osf-pm-tabs) > p{max-width:900px}

/* 3. CALLOUT. Owner: the closing sentences of the quote band "look horrible", put them in a box like
   a quote or testimonial. Applies to the LAST paragraph of the nearby band only — the "Call … or
   request a quote" line — which is a call to action rather than body copy and was previously
   indistinguishable from it. */
.osf-region-nearby p:last-of-type{
  background:#fff;border:1px solid #ececec;border-left:4px solid var(--c-primary,#F48F20);
  border-radius:6px;padding:18px 22px;margin-top:18px;box-shadow:0 1px 3px rgba(0,0,0,.05);
  font-size:1.05rem;line-height:1.65;
}
@media (max-width:560px){.osf-region-nearby p:last-of-type{padding:14px 16px}}

/* ===== /maintenance/ TOP SECTION — owner, 2026-08-14 =====
   Two separate asks, both about the MIGRATED intro above the equipment tabs. The earlier widening
   only moved `.osf-region-block`, which is the appended bands — it never touched this Elementor
   content, which is why the top of the page still looked narrow after that change.

   #4b6ddd8 is the intro copy widget: 807px inside a 1400px section, and set text-align:justify.
   Justify at this measure is what produces the stretched word gaps that read as broken — English
   without hyphenation justifies badly. Widened and set left-aligned.

   #f651282 is the closing line ("Preventative Maintenance Programs are the best way…") — 660px,
   centred, bold, run in as plain copy. It is a conclusion, not body text, so it gets the callout
   treatment the owner asked for. Warm tint rather than the white card used on the lower bands,
   because this one sits on a light area and a white card on white reads as nothing.

   FOUR classes: post-maintenance.css pins these widths at (0,3,0) and loads after this file.
   NOTE f651282 is a HEADING widget (osf-widget-heading) that happens to contain a <p>, not a
   text-editor widget like 4b6ddd8 — a selector assuming text-editor matches nothing here. */
.osf-element.osf-element-4b6ddd8.osf-widget.osf-widget-text-editor{width:100%;max-width:1120px;margin-left:auto;margin-right:auto}
.osf-element.osf-element-4b6ddd8.osf-widget.osf-widget-text-editor p{text-align:left}

.osf-element.osf-element-f651282.osf-widget.osf-widget-heading{width:100%;max-width:1120px;margin:26px auto 0}
.osf-element.osf-element-f651282.osf-widget.osf-widget-heading > .osf-widget-container{
  background:#FFF7EC;border:1px solid #F0DCC0;border-left:5px solid var(--c-primary,#F48F20);
  border-radius:8px;padding:22px 28px;box-shadow:0 1px 3px rgba(0,0,0,.05);
}
.osf-element.osf-element-f651282.osf-widget.osf-widget-heading p{
  text-align:left;font-size:1.1rem;line-height:1.7;margin:0;color:#2b2b2b;
}
@media (max-width:560px){
  .osf-element.osf-element-f651282.osf-widget.osf-widget-heading > .osf-widget-container{padding:16px 18px}
}
