/* =============================================================================
 * custom/site.css — PER-SITE CSS  (edit freely)
 * -----------------------------------------------------------------------------
 * The one place site-specific CSS belongs. Ships blank; the framework never
 * edits it, so pulling framework releases (git merge <tag>) never conflicts here.
 *
 *   • styles.css is FRAMEWORK-OWNED — do NOT edit it (it updates from upstream).
 *   • Re-theming (colours / fonts / spacing / logo) is DATA, not code: use
 *     Admin → Settings → Theme Settings (the ~180 CSS variables). Prefer that.
 *   • Reach for this file only when a bespoke layout/component can't be expressed
 *     through theme variables + a widget's css_class.
 *
 * Loaded LAST (after styles.css and the active button sheet), so rules here win
 * without !important. Reference the theme variables — var(--color-main), etc.
 * ============================================================================= */

/* =============================================================================
 * Product Features strip (.product-features — product detail pages, e.g.
 * /solutions/automated-vending/robocrib-vx500)
 *
 * Layout: the feature image sticks in the left column; the card list sits in
 * the right column. Each card's opacity/scale is driven continuously by
 * custom/site.js as a function of its distance from the viewport's vertical
 * centre — 0 opacity / scaled down at the edges, full opacity / full scale
 * exactly at centre — so a card fades+scales up on its way in from the
 * bottom and fades+scales back down as it exits past the top.
 *
 * .content_container.dark clips its decorative grid/glow background with
 * `overflow: hidden` (styles.css) — but an ancestor's overflow:hidden also
 * disables `position: sticky` on descendants in every major browser. Swap
 * that section's clipping to clip-path (paint-time only, doesn't create a
 * scroll-container) so the sticky image keeps working, with identical
 * visual clipping of the background decoration.
 * ============================================================================= */
.content_container.dark.product-features {
  overflow: visible;
  clip-path: inset(0);
}
.product-features .content {
  display: grid;
  grid-template-columns: minmax(24rem, 38%) 1fr;
  column-gap: 6.4rem;
  align-items: start;
}
.product-features .content > .cf-strip_title {
  grid-column: 1 / -1;
  margin: 0 0 4.8rem;
}
.product-features .content > .cf-strip_image.img-wrapper {
  grid-column: 1;
  grid-row: 2;
  align-self: start;
  position: sticky;
  top: var(--product-features-sticky-top, 12rem);
}
.product-features .content > .cf-strip_image.img-wrapper img {
  width: 100%;
  height: auto;
  border-radius: .8rem;
  display: block;
}
.product-features .content > .flex {
  grid-column: 2;
  grid-row: 2;
  gap: 2.4rem;
}
.product-features .card {
  background: hsla(0 0% 100% / .04);
  border: 1px solid hsla(0 0% 100% / .08);
  border-radius: .8rem;
  box-shadow: none;
  backdrop-filter: blur(2px);
  opacity: 0;
  transform: scale(.92);
  transition: opacity .1s linear, transform .1s linear;
  will-change: opacity, transform;
}
.product-features .card.no-motion {
  opacity: 1;
  transform: none;
  transition: none;
}
.product-features .card .content-wrapper {
  padding: 2.4rem;
}
.product-features .card h3 {
  font-size: 2rem;
}
@media screen and (max-width: 1024px) {
  .product-features .content {
    display: block;
  }
  .product-features .content > .cf-strip_title {
    margin: 0 0 2.4rem;
  }
  .product-features .content > .cf-strip_image.img-wrapper {
    position: static;
    margin: 0 0 3.2rem;
  }
  .product-features .content > .flex {
    gap: 1.6rem;
  }
}
@media (prefers-reduced-motion: reduce) {
  .product-features .card {
    transition: none !important;
  }
}

/* =============================================================================
 * Our Process rail (.process-strip .widget-slider.pf-rail)
 *
 * custom/site.js replaces the widget's default single-slide Swiper with a
 * 3D coverflow "focus rail": image-only cards recede/blur away from the
 * centred active card, an ambient blurred copy of the active image sits
 * behind everything, and the step's title/description render in a synced
 * info row below (extracted from the card's original .content-wrapper).
 * Runs at every viewport width (custom/site.js) — the media queries near the
 * bottom of this block scale the slide width, container padding and ambient
 * blur down for phones so the same rail fits an iPhone viewport instead of
 * overflowing it. Only reduced-motion visitors keep the framework's
 * untouched default slider.
 * ============================================================================= */
.process-strip .widget-slider.pf-rail {
  position: relative;
  overflow: hidden;
  background: var(--color-bg-dark);
  border-radius: 1.6rem;
  padding: 6.4rem 2rem 3.2rem;
}
.process-strip .widget-slider.pf-rail .swiper-wrapper {
  perspective: 1200px;
}
.pf-ambience {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.pf-ambience img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: blur(6rem) saturate(1.8);
  opacity: .4;
  transition: opacity .8s ease;
}
.pf-ambience::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, var(--color-bg-dark), hsla(0 0% 7% / .5) 60%, transparent);
}
.process-strip .widget-slider.pf-rail .swiper-slide {
  width: 26rem;
  height: auto;
}
.process-strip .widget-slider.pf-rail .card {
  position: relative;
  z-index: 1;
  aspect-ratio: 3 / 4;
  height: auto;
  display: block;
  border-radius: 1.6rem;
  overflow: hidden;
  box-shadow: var(--shadow);
  border-top: 1px solid hsla(0 0% 100% / .2);
}
.process-strip .widget-slider.pf-rail .card .anchor {
  display: none;
}
.process-strip .widget-slider.pf-rail .card .img-wrapper,
.process-strip .widget-slider.pf-rail .card .img-wrapper img {
  width: 100%;
  height: 100%;
}
.process-strip .widget-slider.pf-rail .card .img-wrapper img {
  object-fit: cover;
  display: block;
  pointer-events: none;
}
.process-strip .widget-slider.pf-rail .card::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, hsla(0 0% 100% / .12), transparent 40%);
  pointer-events: none;
}
.pf-info-row {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 2.4rem;
  margin-top: 4rem;
}
.pf-info-text {
  max-width: 48rem;
  transition: opacity .25s ease;
}
.pf-meta {
  display: block;
  color: var(--color-main);
  font-family: var(--font-accent);
  font-size: 1.2rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  margin: 0 0 .8rem;
}
.pf-info-body h3 {
  color: var(--color-bg);
  font-size: 2.4rem;
  margin: 0 0 .8rem;
}
.pf-info-body p {
  color: hsla(0 0% 100% / .64);
  margin: 0;
}
.pf-controls {
  display: flex;
  align-items: center;
  gap: .4rem;
  background: hsla(0 0% 100% / .08);
  border: 1px solid hsla(0 0% 100% / .12);
  border-radius: 999px;
  padding: .4rem;
  flex-shrink: 0;
}
.pf-controls .swiper-button-prev,
.pf-controls .swiper-button-next {
  position: static;
  margin: 0;
}
.pf-counter {
  min-width: 5.6rem;
  text-align: center;
  color: hsla(0 0% 100% / .5);
  font-family: var(--font-accent);
  font-size: 1.2rem;
}

/* Scale the rail geometry down for phones — same dark panel, ambient blur and
 * pill controls as desktop, just sized so a slide's neighbours peek in from
 * the edges instead of overflowing a ~375–430px iPhone viewport. */
@media screen and (max-width: 1024px) {
  .process-strip .widget-slider.pf-rail {
    padding: 4.8rem 1.6rem 2.4rem;
  }
  .process-strip .widget-slider.pf-rail .swiper-slide {
    width: 20rem;
  }
  .pf-ambience img {
    filter: blur(4rem) saturate(1.8);
  }
  .pf-info-row {
    margin-top: 2.4rem;
    gap: 1.6rem;
  }
  .pf-info-body h3 {
    font-size: 2rem;
  }
}
@media screen and (max-width: 480px) {
  .process-strip .widget-slider.pf-rail .swiper-slide {
    width: 16rem;
  }
}

/* =============================================================================
 * Dynamic-form custom-select dropdowns (.form_holder .custom-select)
 *
 * custom-selects.js (loaded site-wide via support-files.php) turns a <select>
 * wrapped in .custom-select into a styled dropdown: it hides the native
 * <select> and builds a .select-selected display box + a .select-items list
 * (toggled by .select-hide, arrow state via .select-arrow-active, current row
 * via .same-as-selected). BUT the front-end styles.css only carries the
 * COSMETIC .select-selected rules, and only under legacy .baseline-form /
 * .outline-form / .basic-form wrappers that no current markup applies — the
 * STRUCTURAL rules live only in old-styles.css (never loaded on the front end)
 * and admin.css (admin only). So without this block the widget renders broken:
 * the native <select> stays visible and the options dump out as plain text.
 *
 * This supplies the full, self-contained styling, scoped to the form and
 * matched to the site's inputs via theme variables (var(--color-border),
 * var(--color-bg-light)). Broaden the scope if custom-select is ever used
 * outside the form.
 * ============================================================================= */
.form_holder .custom-select {
  position: relative;
}
/* Hide the native <select>; the .select-selected box stands in for it. */
.form_holder .custom-select select {
  display: none;
}
/* Visible box — mirrors the form's text inputs. */
.form_holder .select-selected {
  box-sizing: border-box;
  width: 100%;
  padding: 1.3rem 4rem 1.3rem 1.6rem;
  border: 1px solid var(--color-border);
  border-radius: .4rem;
  background: var(--color-bg-light);
  color: inherit;
  font: inherit;
  line-height: 1.3;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
}
/* Chevron (down; flips up when open). */
.form_holder .select-selected::after {
  content: "";
  position: absolute;
  top: 45%;
  right: 1.8rem;
  width: .7rem;
  height: .7rem;
  border: solid currentColor;
  border-width: 0 2px 2px 0;
  transform: translateY(-50%) rotate(45deg);
  opacity: .5;
  pointer-events: none;
}
.form_holder .select-selected.select-arrow-active::after {
  transform: translateY(-20%) rotate(-135deg);
}
/* Options panel. */
.form_holder .select-items {
  box-sizing: border-box;
  position: absolute;
  top: calc(100% + .4rem);
  left: 0;
  right: 0;
  z-index: 20;
  background: var(--color-bg-light);
  border: 1px solid var(--color-border);
  border-radius: .4rem;
  box-shadow: 0 .6rem 1.6rem hsla(0 0% 0% / .12);
  overflow: hidden;
}
.form_holder .select-items div {
  padding: 1.1rem 1.6rem;
  cursor: pointer;
}
.form_holder .select-items div:hover,
.form_holder .select-items .same-as-selected {
  background: var(--color-border);
}
/* Closed state (custom-selects.js toggles this class). */
.form_holder .select-hide {
  display: none;
}

#menu .mm-panel {
  background: var(--color-bg-dark);
}

#menu .mm-panel.mm-current,
#menu .mm-panel.mm-highest {
  z-index: 4;
}

/* Video grid: show the title under each thumbnail. `.video-item` wraps the
 * play-overlay link + the title (see videos-block.php) and is the flex-grid
 * cell, so the play icon stays centred on the thumbnail. */
.swipebox_video_full .video-item {
  display: flex;
  flex-direction: column;
}
.swipebox_video_full .video-title {
  margin-top: .8rem;
  font-size: 1.4rem;
  line-height: 1.35;
  font-weight: 600;
}

/* =============================================================================
 * Swiper Grid module CSS (widget sliders with "Grid Rows" > 1)
 *
 * The bundled Swiper JS is v12 (Grid module included), but the bundled
 * swiper.min.css is v6.0.3 — it predates the Grid module and ships none of the
 * .swiper-grid rules. So enabling grid.rows toggled the .swiper-grid class on
 * the container but nothing wrapped the slides into rows. These are Swiper 12's
 * own grid.css rules, scoped to our widget sliders. Swiper only adds the
 * .swiper-grid class when the active breakpoint's grid.rows > 1, so single-row
 * sliders are unaffected.
 * ============================================================================= */
.widget-slider.swiper-grid > .swiper-wrapper {
  flex-wrap: wrap;
}
.widget-slider.swiper-grid-column > .swiper-wrapper {
  flex-wrap: wrap;
  flex-direction: column;
}

/* =============================================================================
 * Anchor targets — the header is fixed, so an anchored jump would otherwise
 * drop the target underneath it. Applies to every widget anchor div (the
 * framework emits <div id="{slugified widget label}"> for any labelled widget)
 * and to the per-card anchors inside a Pages widget.
 * ============================================================================= */
section.content_container > div[id]:not([class]),
section.content_container div.anchor {
  scroll-margin-top: 140px;
}

@media screen and (max-width: 1024px) {
  section.content_container > div[id]:not([class]),
  section.content_container div.anchor {
    scroll-margin-top: 100px;
  }
}

/* =============================================================================
 * 80th anniversary highlight (.anniversary-strip) — a compact brand-coloured
 * band sitting directly beneath the homepage hero. Built as a standard RTE
 * Strip widget so the copy stays editable in the admin; keep the styling here
 * rather than in the RTE so an editor can't accidentally break it.
 *
 * Deliberately narrow in scope: only spacing, colour and type. If the
 * anniversary crest is added later (turn on the widget's Photos setting), the
 * img-wrapper rules below lay it out beside the message automatically.
 * ============================================================================= */
section.content_container.anniversary-strip {
  background: var(--color-main);
  padding: var(--section-block-sm) var(--section-inline);
  text-align: center;
}

section.content_container.anniversary-strip > .content {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 24px;
  flex-wrap: wrap;
}

/* Every text node the RTE can emit inherits the band's colour. */
section.content_container.anniversary-strip,
section.content_container.anniversary-strip p,
section.content_container.anniversary-strip strong,
section.content_container.anniversary-strip .h0,
section.content_container.anniversary-strip .h1,
section.content_container.anniversary-strip .h2,
section.content_container.anniversary-strip .h3,
section.content_container.anniversary-strip .h4,
section.content_container.anniversary-strip .h5,
section.content_container.anniversary-strip .h6,
section.content_container.anniversary-strip h1,
section.content_container.anniversary-strip h2,
section.content_container.anniversary-strip h3,
section.content_container.anniversary-strip h4 {
  color: var(--color-bg);
  margin: 0;
}

section.content_container.anniversary-strip p {
  font-size: clamp(1.125rem, 2.2vw, 1.5rem);
  line-height: 1.35;
  letter-spacing: 0.01em;
}

/* Crest slot — unused until the widget's Photos setting is switched on. */
section.content_container.anniversary-strip .img-wrapper {
  flex: 0 0 auto;
  max-width: 120px;
}

section.content_container.anniversary-strip .img-wrapper img,
section.content_container.anniversary-strip .img-wrapper svg {
  display: block;
  width: 100%;
  height: auto;
}

@media screen and (max-width: 640px) {
  section.content_container.anniversary-strip > .content {
    gap: 16px;
  }
  section.content_container.anniversary-strip .img-wrapper {
    max-width: 88px;
  }
}
