:root {
  /* chassis contract */
  --cx-fg: #f2ede4; --cx-bg: #171512; --cx-accent: #c8551b; --cx-line: #36332f;
  --cx-font-body: 'Public Sans', sans-serif; --cx-font-display: 'Archivo Narrow', sans-serif;
  --cx-body: clamp(16px, 1.05vw, 18px);
  --cx-h1: clamp(38px, 6.4vw, 84px); --cx-h2: clamp(28px, 3.6vw, 48px); --cx-h3: clamp(19px, 1.6vw, 24px);
  --cx-gap: 18px; --cx-band: clamp(48px, 6vw, 72px); --cx-wrap: 1180px; --cx-measure: 62ch;
  --cx-radius: 2px; --cx-radius-media: 6px;
  --cx-head-h: 74px; --cx-bar-h: 64px;
  /* renderer */
  --r-accent: #c8551b; --r-on-accent: #ffffff;
  --r-ground: #171512; --r-ink: #f2ede4;
  --r-inverse-bg: #f2ede4; --r-inverse-fg: #0b0f17; --r-inverse-muted: #636365; --r-inverse-line: #d2cec7; --r-inverse-accent: #c8551b;
  --r-inverse-accent-text: #a2471a;
  --r-display: 'Archivo Narrow', sans-serif; --r-body: 'Public Sans', sans-serif;
  --r-display-weight: 700; --r-display-tracking: 0.005em;
  --r-eyebrow: 13px; --r-micro: 12px;
  --r-bg: #171512; --r-surface: #201e1a; --r-fg: #f2ede4; --r-muted: #9f9b94; --r-line: #36332f; --r-accent: #c8551b; --r-on-accent: #ffffff; --r-accent-text: #ce6c39;
}
[data-theme="light"] {
  --r-bg: #f2ede4; --r-surface: #e9e4dc; --r-fg: #0b0f17; --r-muted: #636365; --r-line: #d2cec7; --r-accent: #c8551b; --r-on-accent: #ffffff; --r-accent-text: #a2471a;
}
[data-theme="dark"] {
  --r-bg: #171512; --r-surface: #201e1a; --r-fg: #f2ede4; --r-muted: #9f9b94; --r-line: #36332f; --r-accent: #c8551b; --r-on-accent: #ffffff; --r-accent-text: #ce6c39;
}
[data-theme="brand"] {
  --r-bg: #f2ede4; --r-surface: #e9e4dc; --r-fg: #0b0f17; --r-muted: #636365; --r-line: #d2cec7; --r-accent: #c8551b; --r-on-accent: #ffffff; --r-accent-text: #a2471a;
}
[data-theme="accent"] {
  --r-bg: #c8551b; --r-surface: #c8551b; --r-fg: #ffffff; --r-muted: #ffffff; --r-line: #ffffff; --r-accent-text: #ffffff;
}

@font-face { font-family: 'Archivo Narrow'; font-style: normal; font-weight: 400 700; font-display: swap; src: url('/assets/fonts/archivo-narrow/archivo-narrow-400-700.woff2') format('woff2'); }
@font-face { font-family: 'Public Sans'; font-style: normal; font-weight: 300 800; font-display: swap; src: url('/assets/fonts/public-sans/public-sans-300-800.woff2') format('woff2'); }
@font-face { font-family: 'IBM Plex Sans'; font-style: normal; font-weight: 400 700; font-display: swap; src: url('/assets/fonts/ibm-plex-sans/ibm-plex-sans-400-700.woff2') format('woff2'); }


.r-cols-1, .r-cols-2, .r-cols-3, .r-cols-4 { display: grid; }
@media (max-width: 719px) { .r-cols-1, .r-cols-2, .r-cols-3, .r-cols-4 { grid-template-columns: minmax(0, 1fr); } }
@media (min-width: 720px) {
  .r-cols-1 { grid-template-columns: minmax(0, 1fr); }
  .r-cols-2, .r-cols-3, .r-cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1000px) {
  .r-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Four across, on ONE row. Four is a divisor like any other, and leaving it out of the list sent four
     steps into a two-by-two block that looked right and was not: a skin removes the right border from
     the LAST card because in a single row that edge is the section's own edge, and in two rows the last
     card sits at the right-hand end of the second row with its box left open. The idiom is the skin's
     to write; the row count is the renderer's to choose, and choosing two rows for four cards broke it. */
  .r-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
/* No divisor: a flex row whose last line grows into whatever is left, so there is never bare ground
   under the cards. Wider cards on the last line read as deliberate; a hole never does. */
.r-cols-fill { display: flex; flex-wrap: wrap; }
.r-cols-fill > * { flex: 1 1 320px; min-width: 0; }

/* ---- shared components (renderer) ---- */
.r-section { padding-block: var(--cx-band); background: var(--r-bg); color: var(--r-fg); }
/* A flush section means its own content reaches the band's edges, not that the band has no
   rhythm: with padding-block 0 the services ledger sat at half the vertical space of every other
   section on the site and the page read as a different document. The band keeps the site's rhythm;
   what is flush is the content inside it. */
.r-section--flush { padding-block: var(--cx-section-pad, clamp(52px, 7vw, 100px)); }
.r-eyebrow { display: inline-flex; align-items: center; gap: 12px; margin: 0 0 20px; font-size: var(--r-eyebrow); font-weight: 700; letter-spacing: .22em; text-transform: uppercase; color: var(--r-accent-text); max-width: none; }
/* overflow hidden and flex none: skins draw the rule as an ::after, sometimes wider than the span, and
   it spilled over the first letters of the eyebrow on three builds. A pseudo now clips to the box. */
.r-eyebrow-rule { width: 28px; height: 2px; flex: none; overflow: hidden; background: var(--r-accent); }
.r-head { margin-bottom: clamp(32px, 4vw, 48px); }
.r-head h2 { font-family: var(--r-display); font-weight: var(--r-display-weight); letter-spacing: var(--r-display-tracking); line-height: 1.02; color: var(--r-fg); }
.r-head--center { text-align: center; }
.r-head--center .r-eyebrow { justify-content: center; }
.r-head--center .r-eyebrow-rule { display: none; }
.r-head--center p { margin-inline: auto; }
.r-lead { font-size: 1.06em; color: var(--r-muted); }
/* line-height is declared because the same class lands on an <a> and on the form's <button>, and the
   two inherit differently: an anchor takes the body's, a button takes the UA's "normal". That is a 5px
   difference in height between the site's buttons and its submit, on every page that carries a form. */
.r-btn { line-height: 1.62; display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 48px; padding: 0 22px; border-radius: var(--cx-radius); font-size: 14px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; text-decoration: none; border: 2px solid transparent; transition: transform .2s ease, background .2s ease, color .2s ease; }
.r-btn--solid { background: var(--r-fg); color: var(--r-bg); }
.r-btn--solid:hover { transform: translateY(-1px); }
.r-btn--accent { background: var(--r-accent); color: var(--r-on-accent); }
.r-btn--ghost { background: transparent; color: var(--r-fg); border-color: var(--r-line); }
.r-btn--ghost:hover { border-color: var(--r-fg); }
.r-btn--outline { background: transparent; color: var(--r-fg); border-color: var(--r-fg); }
.r-btn--outline:hover { background: var(--r-fg); color: var(--r-bg); }
.r-btns { display: flex; flex-wrap: wrap; gap: 14px; }
.r-placeholder { display: grid; place-items: center; min-height: 240px; height: 100%; background: repeating-linear-gradient(135deg, var(--r-surface) 0 12px, var(--r-bg) 12px 24px); border: 1px dashed var(--r-line); border-radius: var(--cx-radius-media); color: var(--r-muted); font-size: 14px; text-align: center; padding: 24px; }
.r-placeholder span { max-width: 26ch; }
.r-muted { color: var(--r-muted); }
.r-display { font-family: var(--r-display); font-weight: var(--r-display-weight); letter-spacing: var(--r-display-tracking); }
.r-grid { display: grid; gap: var(--cx-gap); }
.r-grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.r-grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }
.r-grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); }
.r-hairline { border-top: 1px solid var(--r-line); }
/* Utility pages (404, privacy) have no variant CSS: give their links and footer the site's own colors,
   or a browser-default blue link sits on a dark ground and fails AA. */
.cx-util-head, .cx-util, .cx-foot { color: var(--r-fg); }
.cx-util-head a, .cx-util a, .cx-foot a { color: var(--r-fg); }
.cx-util-head .cx-brand { font-family: var(--r-display); font-weight: var(--r-display-weight); text-decoration: none; }
.cx-foot { color: var(--r-muted); border-top: 1px solid var(--r-line); }
.cx-foot address { font-style: normal; }
/* Below-the-fold sections skip layout and paint until they are near the viewport. Measured on the
   first answer key: the hero's largest paint went from 3.6s to 2.7s on a throttled phone (Lighthouse
   mobile 90 → 96) with no other change; the cost of a long page's first render was the delay. */
main > section:not(:first-child), main > div, footer { content-visibility: auto; contain-intrinsic-size: auto 700px; }
/* Focus: the chassis covers :focus-visible; programmatic focus (what the a11y gate does) must show too. */
a:focus, button:focus, input:focus, select:focus, textarea:focus, summary:focus { outline: 2px solid var(--r-accent); outline-offset: 2px; }
/* The tier motion pass (motion.md M2): a reveal on scroll. The hidden state exists only with JS on
   and only when motion is not reduced, so a crawler, a JS-off render and a reduced-motion visitor all
   get the finished page. Only opacity and transform animate. */
@media (prefers-reduced-motion: no-preference) {
  html.js .r-reveal { opacity: 0; transform: translateY(18px); transition: opacity .6s ease, transform .6s ease; }
  html.js .r-reveal.is-in { opacity: 1; transform: none; }
}
/* The phone bar's clearance under the first screen is NOT here any more: it is a floor (skin-normalize.mjs,
   floorsCss), loaded after the skin so a skin's own hero padding cannot remove it, and scoped to the one
   first screen that is sized to the viewport with the bar visible (the anchored hero between 641 and
   900px). A first version reserved it here on the first section AND on its wrap as a fallback; padding on
   two elements adds, so every phone page carried it twice (164px of dark hero under the stats on the
   third acceptance build, which the look read as content that failed to render). */
/* the mobile action bar: two cells, call and quote, opaque, above everything */
.cx-bar { position: fixed; inset: auto 0 0 0; z-index: 60; display: none; grid-template-columns: 1fr 1fr; height: var(--cx-bar-h); background: var(--r-inverse-bg); color: var(--r-inverse-fg); border-top: 1px solid var(--r-inverse-line); }
.cx-bar a { text-decoration: none; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; font-size: 14px; color: inherit; }
.cx-bar a + a { background: var(--r-accent); color: var(--r-on-accent); }
@media (max-width: 900px) { .cx-bar { display: grid; } }

/* ---- hero (shared) ---- */

.r-hero-stats { display: flex; flex-wrap: wrap; gap: 28px; margin-top: 44px; padding-top: 28px; border-top: 1px solid var(--r-line); }
/* flex: 1 1 180px so two stats SHARE the row instead of wrapping out of it. At their natural widths a
   pair ran 643px inside a 592px hero column, so the second dropped to a line of its own carrying the
   border-left a skin uses as the divider BETWEEN them: a stray vertical rule with nothing on its left,
   and a stat that reads as indented for no reason. A basis wide enough to be worth reading still wraps
   on a phone, where one stat to a line is right. */
.r-hero-stat { display: flex; flex-direction: column; gap: 6px; flex: 1 1 180px; min-width: 0; }
.r-hero-stat-n { font-family: var(--r-display); font-size: 30px; line-height: 1; color: var(--r-fg); }
.r-hero-stat-l { font-size: var(--r-micro); font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--r-muted); }
.r-hero-stat-div { width: 1px; background: var(--r-line); }
@media (max-width: 640px) { .r-hero-stat-div { display: none; } .r-hero-stats { gap: 18px 28px; } }

/* ---- hero (shared) ---- */

.r-claim { position: relative; overflow: hidden; background: var(--r-bg); color: var(--r-fg); }
.r-claim-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center 70%; }
.r-placeholder.r-claim-img { position: absolute; inset: 0; border-radius: 0; min-height: 0; height: 100%; place-items: start start; padding: 16px; }
.r-placeholder.r-claim-img span { background: color-mix(in srgb, var(--r-bg) 85%, transparent); padding: 8px 12px; border-radius: var(--cx-radius); text-align: left; }
/* A commanded placeholder carries its label in the top-left corner; on a narrow screen the copy starts under it. */
@media (max-width: 980px) { .r-claim:has(.r-placeholder.r-claim-img) .r-claim-in { padding-top: 104px; } }
.r-claim-copy { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; justify-content: center; align-items: flex-start; }
.r-claim-eyebrow { margin-bottom: 18px; }
.r-claim-h1 { font-family: var(--r-display); font-weight: var(--r-display-weight); letter-spacing: var(--r-display-tracking); font-size: clamp(42px, 5.5vw, 68px); line-height: 1.02; text-transform: uppercase; color: var(--r-fg); margin: 0; max-width: 15ch; }
.r-claim-sub { font-size: clamp(17px, 1.4vw, 19px); line-height: 1.6; color: var(--r-muted); max-width: 54ch; margin: 22px 0 0; }
.r-claim-btns { margin-top: 30px; }
/* The stops hold near-full strength across the copy column and only then open onto the picture. The
   first cut thinned from 42% of the width, and the subhead's measure runs to about half of it, so
   the end of every line lay on the bright side of the ramp: 3.4:1 where body text needs 4.5. */
.r-claim-scrim { position: absolute; inset: 0; pointer-events: none; background: linear-gradient(100deg, color-mix(in srgb, var(--r-bg) 93%, transparent) 0%, color-mix(in srgb, var(--r-bg) 88%, transparent) 55%, color-mix(in srgb, var(--r-bg) 28%, transparent) 100%); }
/* The ramp runs left to right because the desktop layout puts the words on the left and lets the
   photograph's subject breathe on the right, where the scrim thins to a quarter. Below the stack
   point the copy is FULL WIDTH, so the end of every line lands on that quarter and sits on bare
   photograph: a grey paragraph over a skid steer and foliage, unreadable from about the middle of
   each line, on nine pages of the first acceptance build. Stacked, the ramp turns vertical instead:
   strong through the whole band of text, opening only below it where nothing is being read. */
@media (max-width: 980px) {
  .r-claim-scrim { background: linear-gradient(180deg, color-mix(in srgb, var(--r-bg) 93%, transparent) 0%, color-mix(in srgb, var(--r-bg) 90%, transparent) 62%, color-mix(in srgb, var(--r-bg) 62%, transparent) 100%); }
}
.r-claim-in { position: relative; z-index: 2; }

/* ---- header/utility-sticky ---- */

.r-util { display: none; background: var(--r-bg); color: var(--r-muted); border-bottom: 1px solid var(--r-line); font-size: var(--r-micro); font-weight: 700; letter-spacing: .18em; text-transform: uppercase; }
.r-util-in { display: flex; justify-content: space-between; align-items: center; min-height: 42px; gap: 24px; }
.r-util p { margin: 0; max-width: none; display: inline-flex; align-items: center; gap: 10px; }
.r-util-sq { width: 7px; height: 7px; background: var(--r-accent); }
.r-util-right { display: flex; gap: 22px; align-items: center; }
.r-util-badge { display: inline-flex; align-items: center; gap: 8px; color: var(--r-fg); }
.r-util-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--r-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--r-accent) 30%, transparent); animation: r-pulse 2s ease-in-out infinite; }
@keyframes r-pulse { 50% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--r-accent) 12%, transparent); } }
.r-util-mail { color: inherit; text-decoration: none; letter-spacing: .06em; text-transform: none; font-size: 14px; font-weight: 600; }
@media (min-width: 901px) { .r-util { display: block; } }
.r-hdr--sticky { position: sticky; }
.r-hdr { background: color-mix(in srgb, var(--r-bg) 92%, transparent); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border-bottom: 1px solid var(--r-line); color: var(--r-fg); }
/* column-gap and row-gap are set apart on purpose. This row wraps below the chassis breakpoint, and
   one gap value sets BOTH,
   so the 40px that separates the brand from the nav also became 40px of air between the two rows
   the moment the header wrapped: 171px of sticky header at 1440 on a skin whose nav and phone
   block together ran 39px over the wrap. A wrapped header should read as one compact block. */
.r-hdr-in { display: flex; align-items: center; column-gap: clamp(16px, 2.2vw, 32px); row-gap: 8px; min-height: var(--cx-head-h); padding-block: 10px; flex-wrap: wrap; }
.r-hdr-brand { display: flex; flex-direction: column; line-height: .86; gap: 4px; }
.r-brand { text-decoration: none; color: inherit; font-family: var(--r-display); font-weight: var(--r-display-weight); font-size: 22px; letter-spacing: .02em; text-transform: uppercase; }
.r-brand-logo { height: 40px; width: auto; max-width: 180px; object-fit: contain; }
.r-hdr .cx-nav { margin-inline: auto; }
.r-hdr .cx-nav a { font-size: 14px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--r-fg); padding: 6px 0; display: inline-flex; align-items: center; }
.r-hdr .cx-nav a[aria-current="page"] { box-shadow: inset 0 -2px 0 var(--r-accent); }
.r-hdr .cx-nav-tel { display: none; }
/* margin-inline-start: auto keeps this block at the right edge on the row it lands on. Without it, a
   header that wraps drops the phone and the button to the LEFT of the second row, directly under the
   wordmark, where they read as part of the brand rather than as the actions. */
.r-hdr-right { display: flex; align-items: center; gap: 22px; margin-inline-start: auto; }
.r-hdr-tel { display: flex; flex-direction: column; line-height: 1.05; }
.r-hdr-kicker { font-size: 12px; letter-spacing: .2em; text-transform: uppercase; color: var(--r-muted); font-weight: 700; }
.r-hdr-num { font-family: var(--r-display); font-size: 19px; color: var(--r-fg); text-decoration: none; display: inline-flex; align-items: center; }
.r-hdr-cta { padding-inline: 18px; min-height: 44px; }
/* Above the chassis breakpoint this row does NOT wrap, because the owner's standing rule is that the
   call to action sits at the far right of the header on desktop, and a wrapped row puts it on a line
   of its own under the wordmark. Nothing is allowed to overlap to achieve that: the wordmark and the
   actions keep their size, and the NAV is the one thing that gives, first by shrinking and then by
   wrapping its own list onto a second line. Measured on the sixth build's header (wordmark 124px, nav
   451px, number and button 401px in an 1180px wrap): one row at 79px down to 1200, and at 1024 the nav
   takes a second line and the header is 110px with the button still hard right. */
@media (min-width: 901px) {
  .r-hdr-in { flex-wrap: nowrap; }
  .r-hdr-brand, .r-hdr-right { flex: 0 0 auto; }
  .r-hdr .cx-nav { min-width: 0; }
  .r-hdr .cx-nav ul { flex-wrap: wrap; row-gap: 0; justify-content: flex-end; }
}
@media (max-width: 900px) {
  .r-hdr { background: var(--r-bg); backdrop-filter: none; }
  .r-hdr-in { min-height: 64px; }
  .r-hdr-right { display: none; }
  .r-hdr .cx-nav { margin: 0; border-top: 1px solid var(--r-line); padding-block: 8px; }
  .r-hdr .cx-nav-tel { display: block; }
  .r-hdr .cx-nav a { font-size: 15px; letter-spacing: .1em; }
}

/* ---- footer/columns ---- */

.r-foot { background: var(--r-bg); color: var(--r-muted); padding-block: var(--cx-band) 0; border-top: 1px solid var(--r-line); }
.r-foot-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); gap: clamp(28px, 4vw, 56px); padding-bottom: var(--cx-band); }
.r-foot-brand { grid-column: span 1; }
.r-foot-logo { height: 44px; width: auto; max-width: 200px; object-fit: contain; margin-bottom: 14px; }
.r-foot-word { font-family: var(--r-display); font-weight: var(--r-display-weight); font-size: 24px; color: var(--r-fg); text-transform: uppercase; display: block; margin-bottom: 12px; }
.r-foot-tag { color: var(--r-fg); font-weight: 600; margin-bottom: 10px; }
/* The blurb sits INSIDE the brand block, so whatever a skin does to the brand name it did to the
   paragraph too: two different generated skins styled .r-foot-brand as the wordmark (display face,
   capitals) and a 143-character paragraph inherited both and ran four lines of Archivo Black caps.
   A declaration on the element beats anything it would inherit, so the paragraph states its own
   case and face; a skin that wants to style the blurb names it, and the page gate judges that. */
.r-foot-blurb { font-size: 15px; text-transform: none; letter-spacing: normal; font-family: var(--cx-font-body, inherit); font-weight: 400; line-height: 1.55; }
.cx-fh { font-size: var(--r-eyebrow); font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: var(--r-fg); margin: 0 0 14px; }
.cx-fcol ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.cx-fcol a { color: var(--r-muted); text-decoration: none; }
.cx-fcol a:hover { color: var(--r-fg); }
.cx-fcol address { font-style: normal; line-height: 1.7; }
.cx-fcol p { margin: 10px 0 0; }
.r-foot-sub { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px 24px; padding-block: 18px; border-top: 1px solid var(--r-line); font-size: 14px; }
.r-foot-sub p { margin: 0; }
.r-foot-sub a { color: inherit; }

/* ---- hero/photo-anchored ---- */

.r-hero { position: relative; }
.r-hero--anchored { position: relative; min-height: clamp(580px, 86vh, 840px); display: flex; align-items: flex-end; overflow: hidden; background: var(--r-bg); color: var(--r-fg); }
.r-hero--anchored .r-hero-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center 55%; }
.r-hero--anchored .r-placeholder.r-hero-img { position: absolute; inset: 0; border-radius: 0; min-height: 0; }
.r-hero-scrim { position: absolute; inset: 0; pointer-events: none; }
.r-hero-scrim--v { background: linear-gradient(180deg, color-mix(in srgb, var(--r-bg) 35%, transparent) 0%, color-mix(in srgb, var(--r-bg) 25%, transparent) 38%, color-mix(in srgb, var(--r-bg) 82%, transparent) 100%); }
.r-hero-scrim--h { background: linear-gradient(90deg, color-mix(in srgb, var(--r-bg) 80%, transparent) 0%, color-mix(in srgb, var(--r-bg) 20%, transparent) 55%, transparent 100%); }
.r-hero-in { position: relative; z-index: 2; padding-block: clamp(48px, 8vw, 72px); }
.r-hero-col { max-width: 840px; }
.r-hero-eyebrow { margin-bottom: 24px; }
.r-poster-h1 { font-family: var(--r-display); font-weight: var(--r-display-weight); letter-spacing: var(--r-display-tracking); font-size: clamp(42px, 7vw, 92px); line-height: .92; text-transform: uppercase; color: var(--r-fg); margin: 0; }
.r-hero-grad { display: block; background: linear-gradient(180deg, var(--r-fg) 0%, var(--r-muted) 100%); -webkit-background-clip: text; background-clip: text; color: transparent; }
.r-hero-sub { font-size: clamp(16px, 1.5vw, 19px); line-height: 1.6; color: var(--r-muted); max-width: 600px; margin: 26px 0 0; font-weight: 500; }
.r-hero-btns { margin-top: 36px; }
@media (max-width: 640px) { .r-hero--anchored { min-height: 0; } .r-hero-in { padding-block: 72px 48px; } }

/* ---- services/photo-cards ---- */

.r-svc { position: relative; }
.r-svc-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 24px; flex-wrap: wrap; margin-bottom: 46px; }
.r-svc-head h2 { font-family: var(--r-display); font-weight: var(--r-display-weight); letter-spacing: var(--r-display-tracking); line-height: 1; margin: 0; text-transform: uppercase; }
.r-svc-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); gap: 16px; }
.r-svc-card { position: relative; display: block; min-height: 380px; overflow: hidden; border-radius: var(--cx-radius-media); border: 1px solid var(--r-line); text-decoration: none; color: var(--r-fg); background: var(--r-surface); }
.r-svc-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: brightness(.82); transition: transform .5s ease; }
/* The card's words sit at the BOTTOM of the card, so a missing photograph's instruction cannot sit
   in its middle: on a phone the centred instruction ran into the card's numeral and heading, the
   visual reviewer blocked the fifth Cloud Run build on it, and no stylesheet repair could move it.
   The instruction goes to the top of the card, clear of the words, and reads left like them. */
.r-placeholder.r-svc-img { border-radius: 0; border: 0; min-height: 0; place-items: start start; padding: 20px 22px; text-align: left; }
.r-placeholder.r-svc-img span { max-width: 100%; }
.r-svc-card:hover .r-svc-img { transform: scale(1.06); }
.r-svc-card:hover { border-color: var(--r-muted); }
.r-svc-scrim { position: absolute; inset: 0; background: linear-gradient(180deg, transparent 30%, color-mix(in srgb, var(--r-bg) 92%, transparent) 100%); }
.r-svc-body { position: absolute; inset: auto 0 0 0; padding: 22px; display: grid; gap: 8px; }
.r-svc-index { font-family: var(--r-display); font-size: 14px; color: var(--r-accent-text); letter-spacing: .1em; }
.r-svc-title { font-family: var(--r-display); font-weight: var(--r-display-weight); font-size: 24px; line-height: 1.05; text-transform: uppercase; }
/* Clamped only where the cards sit side by side and an uneven card would break the row. On a phone
   each card is full width and clamping just cuts the sentence, which the mobile audit reads as
   clipped text (correctly: the reader loses words). */
.r-svc-desc { font-size: 15px; line-height: 1.55; color: var(--r-muted); }
/* No line clamp. It kept the cards even and it cut the customer's own sentence in half at every
   width above 640: three lines shown, three lines silently gone, on both AI-planned sites that
   shipped. Grid rows already stretch every card in a row to the tallest, so evenness costs nothing;
   a truncated description costs the sentence. The blurb's length is the planner's job. */
.r-svc-rail { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 32px; padding-top: 24px; border-top: 1px solid var(--r-line); }
.r-svc-rail-label { font-size: var(--r-micro); font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: var(--r-muted); margin-right: 6px; }
.r-chip { display: inline-flex; align-items: center; min-height: 36px; padding: 0 14px; border: 1px solid var(--r-line); border-radius: var(--cx-radius); color: var(--r-fg); text-decoration: none; font-size: 14px; font-weight: 600; }
.r-chip:hover { border-color: var(--r-fg); }

/* ---- split/text-photo-card ---- */

.r-split, .r-split--card { position: relative; }
.r-split-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: clamp(32px, 5vw, 72px); align-items: center; }
.r-split--flip .r-split-media { order: -1; }
.r-split-text .r-head { margin-bottom: 20px; }
.r-split-text p { font-size: 17px; line-height: 1.7; color: var(--r-muted); }
.r-textlink { display: inline-flex; align-items: center; gap: 10px; color: var(--r-fg); text-decoration: none; font-size: 14px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; border-bottom: 2px solid var(--r-accent); padding-bottom: 4px; min-height: 44px; }
.r-textlink::after { content: '\2192'; transition: transform .2s ease; }
.r-textlink:hover::after { transform: translateX(4px); }
.r-split-media { position: relative; }
.r-split-img { width: 100%; aspect-ratio: 4 / 3.4; object-fit: cover; }
.r-split-card { position: absolute; bottom: -22px; left: -22px; background: var(--r-inverse-bg); color: var(--r-inverse-fg); padding: 22px 26px; max-width: 230px; display: grid; gap: 8px; border-radius: var(--cx-radius); }
.r-split-card strong { font-family: var(--r-display); font-weight: var(--r-display-weight); font-size: 18px; text-transform: uppercase; line-height: 1.05; }
.r-split-card span { font-size: 14px; font-weight: 600; color: var(--r-inverse-muted); line-height: 1.5; }
@media (max-width: 640px) { .r-split-card { left: 12px; bottom: -16px; max-width: 70%; } .r-split-media { margin-bottom: 28px; } }

/* ---- process/ghost-numerals ---- */

/* Columns from the step COUNT (cardCols), not from the width: four steps in a width-sized grid came
   out three and one, with two thirds of the second row bare under the last step. */
.r-process-grid { list-style: none; margin: 0; padding: 0; gap: 16px; }
.r-step { border: 1px solid var(--r-line); border-radius: var(--cx-radius-media); padding: 28px 26px 26px; background: var(--r-surface); }
.r-step-n { display: block; font-family: var(--r-display); font-size: 54px; line-height: 1; margin-bottom: 18px; color: color-mix(in srgb, var(--r-fg) 10%, transparent); -webkit-text-stroke: 1px color-mix(in srgb, var(--r-accent) 45%, transparent); }
.r-step h3 { font-size: 20px; font-weight: 700; }
.r-step p { font-size: 15px; color: var(--r-muted); margin: 0; }
.r-process .r-head--center .r-eyebrow { display: inline-flex; gap: 12px; }
.r-process .r-head--center .r-eyebrow::before, .r-process .r-head--center .r-eyebrow::after { content: ''; width: 28px; height: 2px; background: var(--r-accent); }

/* ---- split/sticky-reasons ---- */

.r-why { position: relative; }
.r-why-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: clamp(32px, 5vw, 72px); align-items: start; }
.r-why-rail { position: sticky; top: calc(var(--cx-head-h) + 30px); }
.r-why-rail .r-head { margin-bottom: 24px; }
.r-why-list { list-style: none; margin: 0; padding: 0; }
.r-why-row { display: grid; grid-template-columns: 34px 1fr; gap: 18px; padding: 22px 0; border-top: 1px solid var(--r-line); }
.r-why-row:last-child { border-bottom: 1px solid var(--r-line); }
.r-why-n { font-family: var(--r-display); font-size: 22px; color: var(--r-accent-text); line-height: 1.2; }
.r-why-row h3 { font-size: 18px; font-weight: 700; margin-bottom: 6px; }
.r-why-row p { font-size: 15px; color: var(--r-muted); margin: 0; }
@media (max-width: 900px) { .r-why-rail { position: static; } }

/* ---- gallery/grid ---- */

.r-gallery { position: relative; }
/* Columns from the photo COUNT (cardCols), not from the width: four photographs in a width-sized grid
   came out three and one, with 853px of the second row bare beside the last picture. A skin that lays
   the gallery out as a mosaic overrides this, which is the point of a default. */
.r-gallery-grid { list-style: none; margin: 0; padding: 0; gap: 12px; }
/* min-width: 0 and height: 100% are both load-bearing, and both are about a grid the SKIN writes.
   A skin that lays the gallery out as a mosaic writes repeat(6, 1fr), and 1fr means minmax(auto, 1fr):
   the auto minimum is the item's min-content width, which for a 1600px photograph inflates the track,
   so the tiles in one row came out 247px and 295px wide instead of equal. min-width: 0 on the item is
   what lets a track be the fraction it says it is. Then the cell: grid items stretch, so a tile beside
   a taller one is as tall as that one, and an image with only an aspect-ratio sits at the top of it
   with the rest of the cell empty. That was a 115px band of dead ground under the top-right photograph
   of the sixth build's gallery. The photograph fills the cell it is given and crops, which is what
   object-fit: cover is for; the aspect-ratio still sets the cell's shape when nothing stretches it. */
.r-tile { position: relative; overflow: hidden; border-radius: var(--cx-radius-media); min-width: 0; }
.r-tile-img { width: 100%; height: 100%; aspect-ratio: 4 / 3; object-fit: cover; transition: transform .5s ease; }
.r-tile:hover .r-tile-img { transform: scale(1.04); }
/* The scrim is opaque UNDER the text, not merely at the bottom edge: a two-line caption's first line
   sat where a transparent-to-.65 gradient was still see-through, unreadable over bright grass, and
   the eye flagged it on every skinned build. The gradient's transparent part is padding above the
   text; every line of the caption sits on at least 78% black, plus a shadow for the edges. */
/* On a 390px screen the tiles are two to a row, so each photograph is about 167px tall. A caption of
   two lines then covered 74% of it and a three-line caption 89%: the gallery stopped showing the
   work. The caption is capped at a share of the tile and clips with an ellipsis rather than growing
   over the picture, and the tile itself opens the full image so the detail is still reachable. */
.r-tile-open { position: absolute; inset: 0; z-index: 1; }
.r-tile-cap { position: absolute; inset: auto 0 0 0; padding: 34px 14px 12px; font-size: 14px; font-weight: 600; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.6); background: linear-gradient(180deg, transparent 0, rgba(0,0,0,.78) 24px, rgba(0,0,0,.86) 100%); }
.r-gallery-more { margin: 28px 0 0; max-width: none; }
/* One tile per row on a phone. Two columns made each photograph about 125px tall, so a two-line
   caption sitting on it covered two thirds of the picture and the gallery stopped showing the work.
   One column gives the photograph the width of the screen and the caption about a quarter of it. */
@media (max-width: 640px) { .r-gallery-grid { grid-template-columns: 1fr; } }

/* ---- content/metro-cards ---- */

.r-metro { position: relative; }
.r-metro .r-head { margin-bottom: clamp(28px, 4vw, 40px); }
.r-metro .r-head h2 { text-transform: uppercase; }
/* The column count comes from cardCols() on the card COUNT, not from the width: four cards in a
   width-sized grid rendered as three and one, with two thirds of the second row bare beneath them. */
.r-metro-grid { gap: 20px; align-items: stretch; }
.r-metro-card { background: color-mix(in srgb, var(--r-fg) 7%, transparent); border: 1px solid color-mix(in srgb, var(--r-fg) 16%, transparent); border-radius: var(--cx-radius-media); padding: 26px 26px 22px; }
.r-metro-card h3 { font-family: var(--r-display); font-weight: var(--r-display-weight); letter-spacing: var(--r-display-tracking); font-size: 22px; line-height: 1.1; text-transform: uppercase; margin: 0 0 10px; color: var(--r-fg); }
.r-metro-card p { margin: 0; color: var(--r-muted); font-size: 16px; line-height: 1.65; max-width: none; }
.r-metro-more { text-align: center; margin: 30px 0 0; max-width: none; }
.r-metro-link { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; color: var(--r-accent-text); font-weight: 700; text-decoration: none; border-bottom: 2px solid currentColor; padding-bottom: 2px; }
.r-metro-link::after { content: '\2192'; }

/* ---- reviews/rail-mount ---- */

.r-rail { position: relative; background: var(--r-surface); }
.r-rail-grid { display: grid; grid-template-columns: 300px 1fr; gap: clamp(28px, 4vw, 56px); align-items: stretch; }
/* The rail is a fixed 300px track, which is this section's whole idea, so the heading in it is sized
   to the track rather than to the page. A skin's h2 is a page-width heading: at 50px in 300px,
   "What customers say" came down three lines, one word each, beside 822px of cards. A max() can only
   make the heading smaller, never overflow, and a skin that sizes this heading itself still outranks
   it (same specificity, loaded later), so what is ruled here is only the default. */
.r-rail-side { display: flex; flex-direction: column; justify-content: center; align-items: flex-start; container-type: inline-size; }
.r-rail-side h2 { font-size: min(var(--cx-h2, clamp(28px, 3.6vw, 48px)), 11cqw); }
.r-rail-side h2 { font-family: var(--r-display); font-weight: var(--r-display-weight); letter-spacing: var(--r-display-tracking); line-height: 1.02; text-transform: uppercase; margin: 0 0 14px; }
.r-rail-side .r-lead { margin: 0 0 18px; }
.r-rail-link { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; color: var(--r-fg); text-decoration: none; font-size: 14px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; border-bottom: 2px solid var(--r-accent); }
.r-rail-link::after { content: '\2192'; }
.r-rail-main { display: flex; flex-direction: column; justify-content: center; }
.r-rail-mount { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); gap: var(--cx-gap); }
.r-rail-mount:empty { display: none; }
.r-rail-note { color: var(--r-muted); font-size: 15px; margin: 20px 0 0; }
.r-rail-mount:empty + .r-rail-note { margin-top: 0; }
.r-rail-links { display: flex; gap: 14px; flex-wrap: wrap; margin: 18px 0 0; max-width: none; }
@media (max-width: 900px) { .r-rail-grid { grid-template-columns: 1fr; } }

/* ---- band/cta ---- */

.r-ctaband, .r-ctaband--photo { position: relative; overflow: hidden; text-align: center; }
.r-ctaband-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: .18; filter: grayscale(100%); }
.r-ctaband-in { position: relative; z-index: 1; display: grid; justify-items: center; gap: 18px; }
.r-ctaband h2 { font-family: var(--r-display); font-weight: var(--r-display-weight); letter-spacing: var(--r-display-tracking); text-transform: uppercase; line-height: 1; max-width: 22ch; margin: 0; }
.r-ctaband .r-lead { margin: 0; }
.r-ctaband .r-btns { justify-content: center; margin-top: 8px; }

/* ---- hero/photo-band ---- */

.r-claim--band .r-claim-in { padding-top: 68px; padding-bottom: 72px; }
.r-claim-copy--band { max-width: 780px; }
.r-claim-h1--band { font-size: clamp(38px, 5vw, 56px); max-width: 22ch; }
.r-claim--band .r-claim-sub { max-width: 62ch; }
@media (max-width: 640px) { .r-claim--band .r-claim-in { padding-top: 48px; padding-bottom: 56px; } }

/* ---- split/heritage-numeral ---- */

.r-heritage { position: relative; background: var(--r-surface); }
.r-heritage-grid { display: grid; grid-template-columns: auto 1fr; gap: 52px; align-items: stretch; }
.r-heritage-figure { display: flex; flex-direction: column; justify-content: center; align-items: flex-start; }
.r-heritage-value { display: inline-flex; align-items: flex-start; font-family: var(--r-display); font-weight: var(--r-display-weight); font-size: clamp(96px, 12vw, 170px); line-height: .9; letter-spacing: -.01em; color: var(--r-fg); }
.r-heritage-suffix { color: var(--r-accent-text); font-size: .55em; line-height: 1; margin: .12em 0 0 4px; }
.r-heritage-cap { margin-top: 12px; font-size: var(--r-micro); font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--r-muted); }
.r-heritage-text { display: flex; flex-direction: column; justify-content: center; align-items: flex-start; }
.r-heritage-text h2 { font-family: var(--r-display); font-weight: var(--r-display-weight); letter-spacing: var(--r-display-tracking); line-height: 1.02; text-transform: uppercase; margin: 0 0 14px; }
.r-heritage-text .r-lead { max-width: 60ch; margin: 0 0 22px; }
.r-heritage-chips { list-style: none; margin: 0 0 24px; padding: 0; display: flex; flex-wrap: wrap; gap: 10px; }
.r-heritage-chips li { display: inline-flex; align-items: center; gap: 8px; min-height: 38px; padding: 0 14px; border-radius: 999px; background: var(--r-bg); border: 1px solid var(--r-line); font-size: 14px; font-weight: 600; line-height: 1.3; }
.r-heritage-check { color: var(--r-accent-text); font-weight: 700; }
.r-heritage-link { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; color: var(--r-fg); text-decoration: none; font-size: 14px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; border-bottom: 2px solid var(--r-accent); }
.r-heritage-link::after { content: '\2192'; transition: transform .2s ease; }
.r-heritage-link:hover::after { transform: translateX(4px); }
/* The numeral scales with the screen instead of sitting at a flat 96px, which is a third of the width
   of a small phone and, on a page whose hero runs four lines, pushed its own tracked label down into
   the fixed call bar: the bar's top edge crossed the label a pixel above its baseline and read as a
   line struck through the words. A viewport-relative cap keeps the numeral the largest thing on the
   page and gives the pair back the room it needs to clear the bar. */
@media (max-width: 760px) { .r-heritage-grid { grid-template-columns: 1fr; gap: 28px; } .r-heritage-value { font-size: min(96px, 20vw); } }

/* ---- content/prose ---- */
.r-prose-in { max-width: var(--cx-measure); }
.r-prose-in .r-head { margin-bottom: 20px; }
.r-prose p { color: var(--r-muted); font-size: 17px; line-height: 1.7; }
.r-prose-cta { margin-top: 24px; }

/* ---- split/text-photo ---- */
.r-split-img--43 { aspect-ratio: 4 / 3; }

/* ---- services/zigzag ---- */

.r-zig { position: relative; }
.r-zig-row { display: grid; grid-template-columns: 1fr 1fr; align-items: stretch; background: var(--r-bg); }
.r-zig-row--alt { background: var(--r-surface); }
.r-zig-media { position: relative; min-height: 420px; }
.r-zig-row--flip .r-zig-media { order: 2; }
.r-zig-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.r-placeholder.r-zig-img { position: absolute; inset: 0; border-radius: 0; border: 0; min-height: 0; height: 100%; }
.r-zig-text { display: flex; align-items: center; padding: 60px 52px; }
.r-zig-text-in { max-width: 560px; margin-right: auto; }
.r-zig-row--flip .r-zig-text-in { margin-right: 0; margin-left: auto; }
.r-zig-text h2 { font-family: var(--r-display); font-weight: var(--r-display-weight); letter-spacing: var(--r-display-tracking); font-size: clamp(28px, 3vw, 40px); line-height: 1.02; text-transform: uppercase; margin: 0 0 14px; }
.r-zig-text p { color: var(--r-muted); margin: 0; }
.r-zig-list { list-style: none; margin: 18px 0 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 10px 20px; }
.r-zig-list li { position: relative; padding-left: 24px; font-size: 15px; line-height: 1.5; }
.r-zig-list li::before { content: '\2713'; position: absolute; left: 0; top: 0; color: var(--r-accent-text); font-weight: 700; }
.r-zig-link { display: inline-flex; align-items: center; gap: 8px; margin-top: 22px; min-height: 44px; color: var(--r-fg); text-decoration: none; font-size: 14px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; border-bottom: 2px solid var(--r-accent); }
.r-zig-link::after { content: '\2192'; }
.r-zig-cloud { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 10px; padding-block: var(--cx-band); }
.r-zig-cloud-label { width: 100%; text-align: center; font-size: var(--r-micro); font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: var(--r-muted); margin-bottom: 6px; }
.r-zig-chip { display: inline-flex; align-items: center; min-height: 40px; padding: 0 16px; border: 1px solid var(--r-line); border-radius: 999px; color: var(--r-fg); text-decoration: none; font-size: 14px; font-weight: 600; }
a.r-zig-chip:hover { border-color: var(--r-fg); }
.r-zig-chip--accent { background: color-mix(in srgb, var(--r-accent) 12%, var(--r-bg)); border-color: transparent; }
@media (max-width: 900px) {
  .r-zig-row { grid-template-columns: 1fr; }
  .r-zig-media, .r-zig-row--flip .r-zig-media { order: -1; min-height: 260px; }
  .r-zig-text { padding: 36px 24px 44px; }
  .r-zig-text-in, .r-zig-row--flip .r-zig-text-in { margin: 0; }
}
@media (max-width: 560px) { .r-zig-list { grid-template-columns: 1fr; } }

/* ---- content/faq ---- */

.r-faq { position: relative; }
.r-faq-in { max-width: 820px; }
.r-faq-list { border-top: 1px solid var(--r-line); }
.r-faq-item { border-bottom: 1px solid var(--r-line); }
.r-faq-item summary { list-style: none; cursor: pointer; padding: 18px 44px 18px 0; position: relative; min-height: 44px; display: flex; align-items: center; }
.r-faq-item summary::-webkit-details-marker { display: none; }
.r-faq-item summary::after { content: '+'; position: absolute; right: 8px; font-family: var(--r-display); font-size: 26px; color: var(--r-accent-text); line-height: 1; }
.r-faq-item[open] summary::after { content: '\2212'; }
.r-faq-item h3 { font-size: 18px; font-weight: 700; margin: 0; }
.r-faq-item p { color: var(--r-muted); padding-bottom: 18px; margin: 0; }

/* ---- reviews/mount-cards ---- */

.r-reviews { position: relative; }
.r-reviews-mount { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); gap: var(--cx-gap); min-height: 120px; }
.r-reviews-mount:empty { min-height: 0; }
.r-reviews-note { text-align: center; color: var(--r-muted); margin: 24px auto 0; font-size: 15px; }
.r-reviews-links { display: flex; justify-content: center; gap: 14px; flex-wrap: wrap; margin: 24px 0 0; max-width: none; }

/* ---- contact/split-form ---- */

.r-contact, .r-contact--split { position: relative; }
.r-contact-pitch { min-width: 0; }
.r-contact-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: clamp(32px, 5vw, 72px); align-items: start; }
.r-contact-tel { margin: 0 0 12px; max-width: none; }
.r-contact-num { font-family: var(--r-display); font-size: clamp(26px, 3vw, 40px); color: var(--r-fg); text-decoration: none; display: inline-flex; align-items: center; letter-spacing: .01em; }
.r-contact-addr { font-style: normal; color: var(--r-muted); line-height: 1.6; margin-bottom: 8px; }
.r-contact-hours { color: var(--r-muted); }
.r-contact-expect { list-style: none; margin: 22px 0 0; padding: 0; display: grid; gap: 10px; }
.r-contact-expect li { padding-left: 22px; position: relative; color: var(--r-muted); }
.r-contact-expect li::before { content: ''; position: absolute; left: 0; top: .7em; width: 10px; height: 2px; background: var(--r-accent); }
.r-contact-booking { margin-top: 28px; }
.r-contact-form { background: var(--r-surface); border: 1px solid var(--r-line); border-radius: var(--cx-radius-media); padding: clamp(20px, 3vw, 32px); }
.r-contact-form .cx-form { display: grid; gap: 14px; }
.r-contact-form .cx-form input, .r-contact-form .cx-form select, .r-contact-form .cx-form textarea { background: var(--r-bg); color: var(--r-fg); border-color: var(--r-line); }
.r-contact-form .cx-actions { margin: 6px 0 0; }
.booking-fallback { font-size: 14px; color: var(--r-muted); }

/* ---- content/territories ---- */

.r-terr { position: relative; }
.r-terr-group + .r-terr-group { margin-top: clamp(40px, 6vw, 64px); }
.r-terr-group h2 { font-family: var(--r-display); font-weight: var(--r-display-weight); letter-spacing: var(--r-display-tracking); line-height: 1.02; text-transform: uppercase; margin: 0 0 24px; }
.r-terr-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); gap: 16px; align-items: stretch; }
.r-terr-card { background: var(--r-surface); border-left: 4px solid var(--r-inverse-bg); border-radius: 0 var(--cx-radius) var(--cx-radius) 0; padding: 22px 24px 20px; }
.r-terr-group--accent .r-terr-card { background: color-mix(in srgb, var(--r-accent) 10%, var(--r-bg)); border-left-color: var(--r-accent-text); }
.r-terr-card h3 { font-family: var(--r-display); font-weight: var(--r-display-weight); letter-spacing: var(--r-display-tracking); font-size: 22px; line-height: 1.1; text-transform: uppercase; margin: 0 0 8px; }
.r-terr-card p { margin: 0; color: var(--r-muted); font-size: 15px; line-height: 1.6; max-width: none; }
.r-terr-fallback { text-align: center; margin: clamp(36px, 5vw, 56px) auto 0; max-width: 60ch; }
.r-terr-fallback a { color: var(--r-fg); font-weight: 700; }
.r-terr-tel { white-space: nowrap; }

/* ---- process/circle-triad ---- */

.r-triad { position: relative; }
.r-triad .r-head { max-width: 62ch; margin-inline: auto; }
.r-triad .r-head .r-lead { margin-inline: auto; }
.r-triad-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); gap: clamp(28px, 4vw, 48px) 32px; }
.r-triad-step { display: flex; flex-direction: column; align-items: center; text-align: center; }
.r-triad-mark { display: grid; place-items: center; width: 72px; height: 72px; border-radius: 50%; background: var(--r-accent); color: var(--r-on-accent); margin-bottom: 22px; }
.r-triad-title { font-family: var(--r-display); font-weight: var(--r-display-weight); font-size: 24px; line-height: 1.2; margin: 0 0 10px; color: var(--r-fg); }
.r-triad-text { font-size: 16px; line-height: 1.65; color: var(--r-muted); max-width: 34ch; margin: 0; }



/* Responsive image wrappers must not participate in layout: <picture> is inline by
   default and wrapping a block <img> in one silently reflows the section around it. */
picture{display:contents}
