/* ================================================================
   UPGRADE.CSS  —  client feedback pass
   ----------------------------------------------------------------
   Loaded LAST on index.html so it wins the cascade without editing
   the 112KB home.css. Everything here is additive: existing colours,
   fonts, radii and shadow language are reused, not replaced.

   Contents
     1. Hero — ambient floating accents
     2. Carousel — continuous on every device
     3. What We Do — equal cards, aligned CTAs
     4. Our Work — four category groups
     5. About Us — layout fix + richer visual
     6. Sidebar — featured solutions (mobile item 8)
     7. Responsive + overflow guards
================================================================ */


/* ================================================================
   1. HERO — AMBIENT FLOATING ACCENTS
   Soft brand-red blooms that drift behind the copy. CSS only, no
   image weight, no layout impact (absolutely positioned, inert).
================================================================ */
.hero-floaters {
  position: absolute;
  inset: 0;
  z-index: 2;                /* above the slideshow/overlay, below .hero-content (5) */
  pointer-events: none;
  overflow: hidden;
}

.hero-floater {
  position: absolute;
  display: block;
  border-radius: 50%;
  will-change: transform;
}

.hero-floater--1 {
  width: 26rem;
  height: 26rem;
  left: -6rem;
  top: 12%;
  background: radial-gradient(circle, rgba(215, 25, 32, 0.30), transparent 66%);
  filter: blur(12px);
  animation: heroDrift1 17s ease-in-out infinite;
}

.hero-floater--2 {
  width: 19rem;
  height: 19rem;
  right: 8%;
  top: 8%;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.13), transparent 68%);
  filter: blur(10px);
  animation: heroDrift2 21s ease-in-out infinite;
}

.hero-floater--3 {
  width: 15rem;
  height: 15rem;
  right: 22%;
  bottom: 10%;
  background: radial-gradient(circle, rgba(215, 25, 32, 0.22), transparent 70%);
  filter: blur(14px);
  animation: heroDrift3 25s ease-in-out infinite;
}

/* Thin outlined rings — echo the circular patch shapes in the hero art */
.hero-floater--ring {
  width: 11rem;
  height: 11rem;
  left: 42%;
  bottom: 16%;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: none;
  animation: heroDriftRing 19s ease-in-out infinite;
}

.hero-floater--ring2 {
  width: 6.5rem;
  height: 6.5rem;
  left: 30%;
  top: 14%;
  border: 1px solid rgba(215, 25, 32, 0.34);
  background: none;
  animation: heroDriftRing 15s ease-in-out infinite reverse;
}

/* Small solid sparks. Tiny, slow, and low-contrast on purpose — they read as
   depth rather than decoration. */
.hero-floater--dot1,
.hero-floater--dot2,
.hero-floater--dot3 {
  border-radius: 50%;
}

.hero-floater--dot1 {
  width: 9px;
  height: 9px;
  left: 24%;
  bottom: 30%;
  background: var(--red, #D71920);
  box-shadow: 0 0 14px 3px rgba(215, 25, 32, 0.65);
  animation: heroSpark 11s ease-in-out infinite;
}

.hero-floater--dot2 {
  width: 6px;
  height: 6px;
  left: 57%;
  top: 30%;
  background: rgba(255, 255, 255, 0.75);
  box-shadow: 0 0 12px 2px rgba(255, 255, 255, 0.45);
  animation: heroSpark 14s ease-in-out infinite 1.6s;
}

.hero-floater--dot3 {
  width: 7px;
  height: 7px;
  left: 68%;
  bottom: 26%;
  background: var(--red, #D71920);
  box-shadow: 0 0 12px 3px rgba(215, 25, 32, 0.55);
  animation: heroSpark 9.5s ease-in-out infinite 0.8s;
}

@keyframes heroSpark {
  0%, 100% { transform: translate3d(0, 0, 0); opacity: 0.35; }
  35%      { opacity: 1; }
  50%      { transform: translate3d(0.9rem, -2.6rem, 0); opacity: 0.85; }
  75%      { opacity: 0.5; }
}

/* Mouse parallax.
   The drift keyframes above already own `transform` on each floater, and a
   running animation beats any static declaration — so the parallax offset goes
   on the CONTAINER instead. Container translate and child keyframes are on
   separate elements, so they compose instead of fighting.
   JS writes --px/--py (roughly -1..1); no JS or reduced motion = 0,0. */
.hero-floaters {
  --px: 0;
  --py: 0;
  transform: translate3d(calc(var(--px) * 16px), calc(var(--py) * 11px), 0);
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

/* A second, shallower layer for the small sparks so they don't track the
   cursor at exactly the same rate as the big blooms. */
.hero-floater--dot1,
.hero-floater--dot2,
.hero-floater--dot3,
.hero-floater--ring2 {
  margin-left: calc(var(--px) * 13px);
  margin-top: calc(var(--py) * 9px);
  transition: margin 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

@keyframes heroDrift1 {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  50%      { transform: translate3d(2.5rem, -2rem, 0) scale(1.06); }
}
@keyframes heroDrift2 {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  50%      { transform: translate3d(-2rem, 2.25rem, 0) scale(1.09); }
}
@keyframes heroDrift3 {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(1.75rem, -2.5rem, 0); }
}
@keyframes heroDriftRing {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); opacity: 0.7; }
  50%      { transform: translate3d(-1.5rem, -1.75rem, 0) rotate(8deg); opacity: 1; }
}

/* Gentle continuous lift on the badge and the trust bar — the "floating"
   the client asked for, kept to a few pixels so it reads as premium. */
.hero-badge {
  animation: heroBob 6.5s ease-in-out infinite;
  animation-delay: 1.2s;
}

.hero-trust {
  animation: heroBob 8s ease-in-out infinite;
  animation-delay: 1.8s;
}

@keyframes heroBob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-5px); }
}

/* Slow drift on the active slide so the background is never fully static. */
.hero-slide.is-active {
  animation: heroKenBurns 24s ease-in-out infinite alternate;
}

@keyframes heroKenBurns {
  from { transform: scale(1)     translate3d(0, 0, 0); }
  to   { transform: scale(1.09) translate3d(-1.4%, -1%, 0); }
}

/* The right-hand image slot is empty (its <img> is commented out in the
   markup). Stop it reserving 35% of the hero and squeezing the copy. */
.hero-right-img:empty,
.hero-right-img .hero-img-frame:empty {
  display: none;
}

/* The hero art is composed with its product shot on the right, so the copy
   column stays on its original 48% / 620px footprint — widening it pushes the
   headline over the products. Only the dead right-hand slot is reclaimed. */
.hero-right-img {
  width: auto;
  max-width: none;
  flex: 0 0 auto;
}

@media (prefers-reduced-motion: reduce) {
  .hero-floater,
  .hero-badge,
  .hero-trust,
  .hero-slide.is-active {
    animation: none !important;
  }
  .hero-floaters { opacity: 0.6; }
}


/* ================================================================
   2. CAROUSEL — CONTINUOUS EVERYWHERE
   home.js now duplicates the track on touch too. Make sure the
   animation is honoured and the strip can still be dragged.
================================================================ */
.marquee-track-wrap {
  touch-action: pan-y pinch-zoom;   /* let vertical page scroll win */
}

.marquee-track {
  animation-play-state: running;
}

/* ── Edge blending ────────────────────────────────────────────────
   Cards should dissolve into the section rather than being sliced off at
   the container edge. home.css fades with two 8%-wide linear scrims; a
   straight linear alpha ramp still reads as a visible band, so these are
   widened and eased (a multi-stop scrim approximates an ease-out curve).

   A mask-image would blend perfectly against any background, but there's a
   note in home.css that it broke child animations on iOS Safari — so this
   stays on pseudo-element scrims, matched to the section gradient's colour
   at each end (#0d0d0d on the left, #D71920 on the right). */
.marquee-track-wrap::before,
.marquee-track-wrap::after {
  width: 15%;
  max-width: 13rem;
}

.marquee-track-wrap::before {
  background: linear-gradient(to right,
    rgb(13, 13, 13) 0%,
    rgba(13, 13, 13, 0.985) 11%,
    rgba(13, 13, 13, 0.94) 22%,
    rgba(13, 13, 13, 0.86) 33%,
    rgba(13, 13, 13, 0.72) 45%,
    rgba(13, 13, 13, 0.54) 57%,
    rgba(13, 13, 13, 0.36) 69%,
    rgba(13, 13, 13, 0.19) 81%,
    rgba(13, 13, 13, 0.07) 91%,
    rgba(13, 13, 13, 0) 100%);
}

.marquee-track-wrap::after {
  background: linear-gradient(to left,
    rgb(215, 25, 32) 0%,
    rgba(215, 25, 32, 0.985) 11%,
    rgba(215, 25, 32, 0.94) 22%,
    rgba(215, 25, 32, 0.86) 33%,
    rgba(215, 25, 32, 0.72) 45%,
    rgba(215, 25, 32, 0.54) 57%,
    rgba(215, 25, 32, 0.36) 69%,
    rgba(215, 25, 32, 0.19) 81%,
    rgba(215, 25, 32, 0.07) 91%,
    rgba(215, 25, 32, 0) 100%);
}

/* ── Entrance ─────────────────────────────────────────────────────
   The section already fades 0 -> 1 via .is-visible. Give it a little rise
   and a settling blur so it resolves into the page instead of popping. */
.marquee-section {
  transform: translateY(1.5rem);
  filter: blur(6px);
  transition: opacity 0.75s ease, transform 0.85s cubic-bezier(0.22, 1, 0.36, 1),
              filter 0.75s ease;
}

.marquee-section.is-visible {
  transform: translateY(0);
  filter: blur(0);
}

@media (prefers-reduced-motion: reduce) {
  .marquee-section {
    transform: none;
    filter: none;
    transition: opacity 0.3s ease;
  }
}


/* ================================================================
   2b. ICONS FLOAT ON HOVER
   Every icon lifts, warms to brand red and picks up a soft glow when
   the cursor is on it (or on the card that owns it). One shared rule
   set so the behaviour is identical everywhere.
================================================================ */
.mc-icon,
.sc-icon-wrap,
.why-card-icon,
.apply-card-icon,
.cf-icon,
.faq-icon,
.mega__feature-icon,
.contact-icon {
  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
              filter 0.4s ease,
              color 0.3s ease;
  will-change: transform;
}

/* Direct hover on the icon itself */
.mc-icon:hover,
.sc-icon-wrap:hover,
.why-card-icon:hover,
.apply-card-icon:hover,
.cf-icon:hover,
.faq-icon:hover,
.contact-icon:hover,
/* …and hover anywhere on the card that owns it */
.marquee-card:hover .mc-icon,
.service-card:hover .sc-icon-wrap,
.why-card:hover .why-card-icon,
.apply-card:hover .apply-card-icon,
.mega__feature:hover .mega__feature-icon {
  transform: translateY(-6px) scale(1.08);
  filter: drop-shadow(0 8px 16px rgba(215, 25, 32, 0.45));
}

/* Once lifted, keep a slow idle bob going so it reads as floating rather
   than simply nudged. */
.marquee-card:hover .mc-icon,
.service-card:hover .sc-icon-wrap,
.why-card:hover .why-card-icon,
.apply-card:hover .apply-card-icon,
.mega__feature:hover .mega__feature-icon {
  animation: iconFloat 2.4s ease-in-out infinite 0.4s;
}

@keyframes iconFloat {
  0%, 100% { transform: translateY(-6px) scale(1.08); }
  50%      { transform: translateY(-11px) scale(1.08); }
}

/* Touch devices have no hover — don't leave icons stuck mid-lift. */
@media (hover: none) {
  .mc-icon, .sc-icon-wrap, .why-card-icon, .apply-card-icon,
  .cf-icon, .faq-icon, .mega__feature-icon, .contact-icon {
    transform: none !important;
    animation: none !important;
    filter: none !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  .mc-icon, .sc-icon-wrap, .why-card-icon, .apply-card-icon,
  .cf-icon, .faq-icon, .mega__feature-icon, .contact-icon {
    transition: filter 0.2s ease;
    animation: none !important;
  }
  .marquee-card:hover .mc-icon,
  .service-card:hover .sc-icon-wrap,
  .why-card:hover .why-card-icon,
  .apply-card:hover .apply-card-icon,
  .mega__feature:hover .mega__feature-icon {
    transform: none;
  }
}

/* Clones are inert — keep them out of the hover/focus story. */
.marquee-card[aria-hidden="true"] {
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .marquee-track,
  .trust-logos-track {
    animation: none !important;
    transform: none !important;
  }
  /* Without the loop, let the user scroll the strip by hand. */
  .marquee-track-wrap,
  .trust-logos-marquee-wrap {
    overflow-x: auto;
    scrollbar-width: none;
  }
  .marquee-track-wrap::-webkit-scrollbar,
  .trust-logos-marquee-wrap::-webkit-scrollbar { display: none; }
}


/* ================================================================
   3. WHAT WE DO — EQUAL CARDS, ALIGNED CTAs
   The four cards carry different amounts of copy, so their "Get
   Quote" links used to land at four different heights.
================================================================ */
/* The section sits on a half-grey / half-red torn-paper photo. The heading
   must stay inside the light left half or it becomes red-on-red — hence the
   hard break in the markup plus this width cap as a belt-and-braces guard. */
.services-section-h2 {
  max-width: 34rem;
  text-wrap: balance;
}

.services-section-h2 span {
  color: var(--red, #D71920);
}

.services-grid {
  align-items: stretch;
}

.service-card {
  display: flex;
  flex-direction: column;
  height: 100%;
}

/* Push the link to the bottom of every card regardless of copy length. */
.service-card .sc-link {
  margin-top: auto;
  padding-top: 1.15rem;
}

.service-card .sc-tags {
  margin-bottom: 0.35rem;
}

/* Tag chips wrap rather than overflow on narrow cards. */
.sc-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  padding-left: 0;
  list-style: none;
}

.sc-tags li {
  margin: 0;
}


/* ================================================================
   4. OUR WORK — FOUR CATEGORY GROUPS
================================================================ */
.portfolio-groups {
  display: flex;
  flex-direction: column;
  gap: clamp(2.5rem, 4vw, 3.75rem);
  margin-top: 2.5rem;
}
@media (min-width: 1600px) {/* DESKTOP-SCALE generated by tools/desktop-scale.mjs */
.portfolio-groups {
  gap: clamp(2.5rem, 5.3333vw, 3.75rem);
}
}

.pf-group {
  opacity: 1;
  transition: opacity 0.3s ease;
}

.pf-group--hidden {
  display: none;
}

.pf-group-head {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  margin-bottom: 1.35rem;
  padding-bottom: 0.7rem;
  /* The Our Work section sits on a near-black ground, so the divider and
     type here have to be light — not the dark defaults used elsewhere. */
  border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}

.pf-group-title {
  font-family: 'Bricolage Grotesque', sans-serif;
  font-size: clamp(1.15rem, 1.9vw, 1.5rem);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: #fff;
  margin: 0;
  position: relative;
  padding-left: 0.85rem;
}

@media (min-width: 1600px) {/* DESKTOP-SCALE generated by tools/desktop-scale.mjs */

.pf-group-title {
  font-size: clamp(1.15rem, 2.5333vw, 1.5rem);
}
}

/* Red rail — same device the service cards use for their top rule. */
.pf-group-title::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.18em;
  bottom: 0.18em;
  width: 3px;
  border-radius: 3px;
  background: var(--red, #D71920);
}

.pf-group-meta {
  font-family: 'Montserrat', sans-serif;
  font-size: 0.76rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.58);
  margin-left: auto;
  text-align: right;
}

/* Three columns inside a group rather than four. Two of the four categories
   hold only one or two pieces, and at four-up they left a conspicuous empty
   half-row; at three-up the tiles are larger and the rows read as deliberate. */
.pf-group .portfolio-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 992px) {
  .pf-group .portfolio-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* The overlay no longer repeats the title/category shown directly
   beneath the tile — it now carries just the action. */
.pf-overlay-legacy { display: none; }

.pi-overlay {
  display: flex;
  align-items: center;
  justify-content: center;
}


/* ================================================================
   5. ABOUT US — LAYOUT FIX + RICHER VISUAL
   The markup used to leave .about-visual and .about-container
   unclosed, which trapped the "Discover Our Story" button inside
   the image column. That's fixed in index.html; this styles the
   now-correct structure.
================================================================ */
.about-visual {
  position: relative;
  z-index: 0;          /* own stacking context so the ::before frame at -1
                          sits above the section background, not behind it */
}

.about-image-wrap {
  position: relative;
  border-radius: 20px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.18);
  /* NOT overflow:hidden — the "10+ Years of Excellence" badge deliberately
     hangs off the left edge of the photo and would be clipped. The radius
     is applied to the <img> itself instead. */
}

.about-image-wrap img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 20px;
  transition: transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}

.about-visual:hover .about-image-wrap img {
  transform: scale(1.04);
}

/* Offset red frame behind the photo — depth without new assets. */
.about-visual::before {
  content: '';
  position: absolute;
  inset: 1.5rem -1.25rem -1.5rem 1.25rem;
  border: 2px solid rgba(215, 25, 32, 0.30);
  border-radius: 20px;
  z-index: -1;
  pointer-events: none;
}

.about-badge {
  z-index: 2;
}

.about-cta-wrap {
  justify-content: center;
}

/* Floating accent behind the photo — same motion language as the hero, so the
   two sections feel like one system rather than two unrelated treatments. */
.about-visual::after {
  content: '';
  position: absolute;
  width: 13rem;
  height: 13rem;
  right: -3.5rem;
  top: -3rem;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(215, 25, 32, 0.30), transparent 68%);
  filter: blur(10px);
  z-index: -1;
  pointer-events: none;
  animation: aboutBloom 14s ease-in-out infinite;
}

@keyframes aboutBloom {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  50%      { transform: translate3d(-1.5rem, 1.75rem, 0) scale(1.14); }
}

/* Stat pills: lift and warm on hover, and let the number carry the weight. */
.stat-pill {
  transition: transform 0.32s cubic-bezier(0.22, 1, 0.36, 1),
              box-shadow 0.32s ease, border-color 0.32s ease;
}

.stat-pill:hover {
  transform: translateY(-4px);
  border-color: rgba(215, 25, 32, 0.42);
  box-shadow: 0 10px 26px rgba(215, 25, 32, 0.16);
}

.stat-pill-num,
.stat-pill-suffix {
  font-variant-numeric: tabular-nums;
}

/* The years badge gets the same gentle float as the hero badge. */
.about-badge {
  animation: heroBob 7.5s ease-in-out infinite;
  animation-delay: 0.6s;
}

@media (prefers-reduced-motion: reduce) {
  .about-image-wrap img { transition: none; }
  .about-visual:hover .about-image-wrap img { transform: none; }
  .about-visual::after,
  .about-badge { animation: none !important; }
  .stat-pill { transition: none; }
  .stat-pill:hover { transform: none; }
}


/* ── Repetition: category label vs group heading ──────────────────
   Each tile printed its category ("CUSTOM PATCHES") directly under a group
   heading that already says exactly that — three identical labels stacked
   under one heading. The heading owns the category now.
   display:none takes it out of the accessibility tree as well as the layout,
   which is correct here: the group's <h3> already announces the category, so
   nothing is lost. Left in the markup so reverting is a one-line CSS change. */
.pf-group .pi-info .pi-cat {
  display: none;
}

.pf-group .pi-info {
  padding-top: 0.9rem;
}


/* ================================================================
   6. SIDEBAR — FEATURED SOLUTIONS (mobile half of item 8)
   Digitizing and Vector Art are the two lead services, so they get
   the same emphasis in the mobile drawer that they get in the
   desktop mega menu.
================================================================ */
.sidebar__nested-item--featured > .sidebar__nested-btn {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: #fff;
  font-weight: 700;
  background: rgba(215, 25, 32, 0.14);
  border-left: 3px solid var(--nav-red, #D71920);
  border-radius: 0 8px 8px 0;
}

.sidebar__nested-item--featured > .sidebar__nested-btn:hover,
.sidebar__nested-item--featured > .sidebar__nested-btn:focus-visible {
  background: rgba(215, 25, 32, 0.22);
}

.sidebar__featured-badge {
  font-family: 'Montserrat', sans-serif;
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: #fff;
  background: var(--nav-red, #D71920);
  padding: 0.16rem 0.5rem;
  border-radius: 999px;
  margin-left: 0.2rem;
  flex: none;
}

/* The chevron is the last child of the button — keep it pinned right. */
.sidebar__nested-item--featured > .sidebar__nested-btn .sidebar__chevron {
  margin-left: auto;
}


/* ================================================================
   7. RESPONSIVE + OVERFLOW GUARDS
================================================================ */

/* Nothing may push the page sideways. */
html,
body {
  max-width: 100%;
  overflow-x: hidden;
}

img,
video,
svg {
  max-width: 100%;
}

/* ── Laptop / small desktop ─────────────────────────────────── */
@media (max-width: 1200px) {
  .mega__inner { padding-left: 1.5rem; padding-right: 1.5rem; }
}

/* ── Tablet ─────────────────────────────────────────────────── */
@media (max-width: 992px) {
  .hero-floater--1 { width: 18rem; height: 18rem; }
  .hero-floater--2 { width: 13rem; height: 13rem; }
  .hero-floater--3 { width: 11rem; height: 11rem; }
  .hero-floater--ring { width: 8rem; height: 8rem; }

  .pf-group-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.3rem;
  }
  .pf-group-meta {
    margin-left: 0;
    text-align: left;
  }

  /* Offset frame reads as clutter once the columns stack. */
  .about-visual::before { display: none; }
}

/* ── Mobile ─────────────────────────────────────────────────── */
@media (max-width: 768px) {
  .hero-content {
    width: 100%;
    padding-right: 0;
  }

  .hero-floater--2,
  .hero-floater--ring {
    display: none;   /* keep one bloom on small screens, not four */
  }

  /* .pf-group .portfolio-grid above is (0,2,0); match it here or the
     two-column tablet rule would keep winning on phones. */
  .services-grid,
  .portfolio-grid,
  .pf-group .portfolio-grid {
    grid-template-columns: 1fr;
  }

  .portfolio-groups {
    gap: 2.25rem;
  }

  /* Filter row scrolls horizontally instead of wrapping into a block.
     justify-content MUST be flex-start here: home.css centres this row, and
     a centred flex row that overflows puts its first items at a negative
     scroll offset the user can never reach. */
  .portfolio-filters {
    display: flex;
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    gap: 0.5rem;
    padding-bottom: 0.5rem;
    scroll-padding-left: 1rem;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .portfolio-filters::-webkit-scrollbar { display: none; }
  .pf-btn {
    flex: 0 0 auto;
    white-space: nowrap;
  }
}

/* ── Small phones ───────────────────────────────────────────── */
@media (max-width: 480px) {
  .hero-floater--1 {
    width: 14rem;
    height: 14rem;
    left: -4rem;
  }

  .pf-group-title { font-size: 1.05rem; }
  .pf-group-meta  { font-size: 0.7rem; }

  .service-card .sc-link { padding-top: 0.9rem; }
}
