/* ── Site Builder default theme ──
   The --theme-* vars are optionally injected by the build (from the site's
   Theme settings). Everything here uses them with a safe fallback so a site
   with no theme set still looks the same as before. */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* Prevent horizontal scroll from full-bleed children (e.g. gallery slider uses
   width: 100vw, which on pages with a vertical scrollbar is slightly wider
   than the visible viewport and would otherwise trigger horizontal scroll).
   Use `clip` rather than `hidden` so it doesn't establish a scroll container
   - `position: sticky` on the navbar needs the viewport as its nearest
   scrolling ancestor, and `overflow: hidden` would break that. */
html, body { overflow-x: clip; }

:root {
  /* Fallback palette - overridden by {{THEME_STYLES}} if the site has a theme. */
  --bg: var(--theme-bg, #fff);
  --fg: var(--theme-text, #1a1a1a);
  --muted: #666;
  --accent: var(--theme-link, #c0392b);
  --accent-hover: #e74c3c;
  --border: #e5e5e5;
  --card-bg: #fafafa;
  --max-width: 1200px;
  --header-bg: var(--theme-header-bg, #111);
  --header-text: var(--theme-header-text, #fff);
  /* Nav + logo: fall through to header colours unless overridden */
  --nav-bg: var(--theme-nav-bg, var(--theme-header-bg, #111));
  --scrolled-nav-bg: var(--theme-scrolled-nav-bg, #000000);
  --scrolled-nav-opacity-pct: var(--theme-scrolled-nav-opacity-pct, 70%);
  --nav-link: var(--theme-nav-link, var(--theme-header-text, #fff));
  --nav-link-bg: var(--theme-nav-link-bg, transparent);
  --nav-link-hover-bg: var(--theme-nav-link-hover-bg, transparent);
  --nav-link-hover: var(--theme-nav-link-hover, var(--nav-link));
  --logo-title: var(--theme-logo-title, var(--theme-header-text, #fff));
  --scrolled-logo-title: var(--theme-scrolled-logo-title, #ffffff);
  /* Mobile hamburger menu - falls back to the desktop nav colours unless the
     user sets explicit mobile-specific theme roles. */
  --mobile-menu-bg: var(--theme-mobile-menu-bg, var(--theme-nav-bg, var(--theme-header-bg, #111)));
  /* Default 100% (opaque). The build emits an override (e.g. 70%) when the
     user picks a non-default value in the Theme editor. */
  --mobile-menu-opacity-pct: var(--theme-mobile-menu-opacity-pct, 100%);
  --mobile-link: var(--theme-mobile-link, var(--theme-nav-link, var(--theme-header-text, #fff)));
  --mobile-link-bg: var(--theme-mobile-link-bg, transparent);
  --mobile-link-hover: var(--theme-mobile-link-hover, var(--mobile-link));
  /* Fallback chain picks a colour that's already known to be visible on the
     nav background: the logo title → nav link → header text → white.
     `--theme-nav-link` can legitimately be the same colour as the nav bg
     (sites using pill-style link backgrounds), so using it first would hide
     the hamburger bars. Logo title is guaranteed visible. */
  --hamburger: var(--theme-hamburger, var(--theme-logo-title, var(--theme-nav-link, var(--theme-header-text, #fff))));
  --footer-bg: var(--theme-footer-bg, #111);
  --footer-text: var(--theme-footer-text, #999);
  /* Footer-link colour falls through to footer-text when "auto" so a
     site that doesn't set a separate link colour still gets matching
     copy + links. Hover does the same fallback chain. */
  --footer-link: var(--theme-footer-link, var(--footer-text));
  --footer-link-hover: var(--theme-footer-link-hover, var(--footer-link));
  /* text-decoration tokens emitted by build.mjs based on the user's
     "Footer link decoration" choice (underline / none / hover only). */
  --footer-link-decoration: var(--theme-footer-link-decoration, underline);
  --footer-link-decoration-hover: var(--theme-footer-link-decoration-hover, underline);
  --btn-bg: var(--theme-btn-bg, #c0392b);
  --btn-text: var(--theme-btn-text, #fff);
  --btn-hover-bg: var(--theme-btn-hover-bg, #e74c3c);
}

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  background: var(--bg);
  color: var(--fg);
  line-height: 1.5;
}

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); text-decoration: underline; }
img { max-width: 100%; display: block; }

.wrap { max-width: var(--max-width); margin: 0 auto; padding: 32px 20px; }

/* ── Navbar ── */
.navbar {
  background: var(--nav-bg);
  color: var(--nav-link);
  /* Smooth all the properties the scrolled state animates so entering/leaving
     the stuck state feels continuous, not snappy. Only used when the site has
     the sticky-menu option enabled (body.has-sticky-nav). */
  transition: box-shadow .25s ease, backdrop-filter .25s ease,
              -webkit-backdrop-filter .25s ease, padding .25s ease,
              background-color .25s ease;
}
/* Sticky-mode fancy effect - JS in js/site.js toggles .scrolled on .navbar
   once the page has scrolled past the nav. Gated on body.has-sticky-nav so
   the effect never appears on sites that opted out of sticky.
   Background blends the themed scrolled colour with transparency at the
   user-set opacity (Theme tab → "Sticky nav opacity"). Backdrop blur makes
   the see-through effect feel glass-y, and the logo title switches to the
   scrolled logo colour (default white). */
.has-sticky-nav .navbar.scrolled {
  background: color-mix(in srgb, var(--scrolled-nav-bg) var(--scrolled-nav-opacity-pct), transparent);
  backdrop-filter: saturate(160%) blur(10px);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
  box-shadow: 0 4px 18px rgba(0, 0, 0, .28);
}
.has-sticky-nav .navbar.scrolled .nav-brand,
.has-sticky-nav .navbar.scrolled .nav-brand .nav-title {
  color: var(--scrolled-logo-title);
}
/* Desktop nav layout: default = original flex row (brand left, links right).
   When body.has-socials is set (i.e. at least one social URL is configured),
   we switch to a 3-column grid so the main nav links sit dead-centre between
   the brand (left) and the socials cluster (right). The middle "auto" track
   sizes to its content; the two "1fr" side tracks balance the empty space,
   which keeps the link list visually centred even when the brand and
   socials groups have different widths. The .nav-toggle (hamburger) is
   display:none on desktop so it doesn't claim a track. */
.nav-inner { max-width: var(--max-width); margin: 0 auto; padding: 16px 20px; display: flex; align-items: center; gap: 24px; transition: padding .25s ease; }
body.has-socials .nav-inner { display: grid; grid-template-columns: 1fr auto 1fr; }
.nav-brand { color: var(--logo-title); font-weight: 700; font-size: 18px; display: flex; align-items: center; gap: 10px; line-height: 1; }
body.has-socials .nav-brand { justify-self: start; }
.nav-brand:hover { color: var(--logo-title); text-decoration: none; }
.nav-brand img { display: block; flex-shrink: 0; }
/* IMPORTANT: keep .nav-title as plain inline. We had display: inline-flex
   here originally (so the title would baseline-align with the logo image)
   but inline-flex turns each whitespace text-node between W-swap word
   spans and the next word ("</span> Hair") into a flex-item whose leading
   whitespace gets collapsed - causing "Twins Hair" to render as
   "TwinsHair" with no visible space. The parent .nav-brand is already a
   flex row with align-items:center, which handles baseline-aligning the
   logo + title on its own. */
.nav-brand .nav-title { color: var(--logo-title); line-height: 1; display: inline; }
.nav-links { list-style: none; display: flex; gap: 8px; margin-left: auto; align-items: center; }
body.has-socials .nav-links { margin-left: 0; justify-self: center; }
.nav-links a { color: var(--nav-link); background: var(--nav-link-bg); opacity: .85; font-size: 14px; padding: 6px 12px; border-radius: 4px; transition: opacity .15s, background .15s; display: block; }
.nav-links a:hover { opacity: 1; background: var(--nav-link-hover-bg); color: var(--nav-link-hover); }

/* Socials cluster on the right of the navbar (column 3 of the grid).
   Each child is a small inline-icon link that inherits --nav-link colour
   so the icon glyphs blend with the rest of the nav text. The icons are
   24x24 SVGs scaled down to 18px (keeps the touch target ~36px after
   padding), with a subtle opacity that lifts on hover - same pattern as
   the existing nav-link hover state. */
.nav-socials {
  display: flex;
  align-items: center;
  gap: 4px;
  justify-self: end;
}
.nav-social {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  color: var(--nav-link);
  opacity: .65;
  transition: opacity .15s ease, background .15s ease, color .15s ease;
}
.nav-social:hover {
  opacity: 1;
  background: var(--nav-link-hover-bg);
  color: var(--nav-link-hover);
  text-decoration: none;
}
.nav-social svg { width: 18px; height: 18px; display: block; }

/* Dropdown menus on the desktop navigation. A nav item with children gets
   class="nav-has-dropdown"; hovering or clicking it reveals .nav-dropdown.
   Mobile reuses .nav-links flat-listing logic in the @media block below
   so children appear inline with their parent (no nested popups on
   touch). */
.nav-has-dropdown { position: relative; }
.nav-has-dropdown > .nav-parent { display: flex; align-items: center; gap: 4px; }
.nav-caret { font-size: 10px; opacity: .7; transition: transform .2s ease; }
.nav-has-dropdown:hover > .nav-parent .nav-caret,
.nav-has-dropdown.open > .nav-parent .nav-caret { transform: translateY(1px); opacity: 1; }
/* Mobile-only +/- toggle button next to dropdown parents. Hidden on
   desktop where hover handles things. The icon is drawn as two
   absolutely-positioned bars (one of which rotates away when open),
   producing a + → − transition that reads more cleanly than an
   emoji at small sizes. Tap target is a comfortable 44px so it sits
   on the recommended minimum for mobile. */
.nav-dropdown-toggle { display: none; }
.nav-dropdown {
  list-style: none;
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 180px;
  background: var(--nav-bg);
  border: 1px solid color-mix(in srgb, var(--nav-link) 14%, transparent);
  border-radius: 6px;
  padding: 6px;
  margin-top: 6px;
  display: none;
  z-index: 50;
}
/* Invisible hover bridge so the mouse can cross the gap between trigger
   and menu without losing :hover. */
.nav-has-dropdown::after {
  content: "";
  position: absolute;
  top: 100%; left: 0; right: 0;
  height: 8px;
  pointer-events: auto;
}
/* ── Desktop dropdown effect library ──
   Each effect is a body-class block. The build emits body.nav-fx-{name};
   to add a new effect, drop in another block targeting body.nav-fx-myname.
   Default ("Standard") = instant show via display: block.
   "Fade" = opacity + small upward translate transitions cleanly.
   Mobile uses its own mobile-fx-* selectors lower in this file so the two
   stay independent. */

/* Standard (default): instant show on hover. */
body.nav-fx-standard .nav-has-dropdown:hover > .nav-dropdown,
body.nav-fx-standard .nav-has-dropdown.open  > .nav-dropdown,
.nav-has-dropdown:hover > .nav-dropdown,
.nav-has-dropdown.open  > .nav-dropdown { display: block; }

/* Fade: dropdown is always rendered (display: block) but invisible until
   hovered; opacity/transform transition into place. visibility transition
   is delayed on the way out so the fade is fully visible before it
   becomes pointer-inert. */
body.nav-fx-fade .nav-has-dropdown > .nav-dropdown {
  display: block;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity .18s ease, transform .18s ease, visibility 0s linear .18s;
  pointer-events: none;
}
body.nav-fx-fade .nav-has-dropdown:hover > .nav-dropdown,
body.nav-fx-fade .nav-has-dropdown.open  > .nav-dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition: opacity .18s ease, transform .18s ease, visibility 0s linear 0s;
  pointer-events: auto;
}
.nav-dropdown li { width: auto; }
.nav-dropdown a {
  display: block;
  padding: 8px 12px;
  font-size: 13px;
  color: var(--nav-link);
  background: transparent;
  border-radius: 4px;
  white-space: nowrap;
}
.nav-dropdown a:hover { background: var(--nav-link-hover-bg); color: var(--nav-link-hover); }

/* Hamburger button - hidden on desktop, shown on mobile (≤600px).
   Three bars that morph into an X when the menu is open. */
.nav-toggle {
  display: none;
  margin-left: auto;
  background: transparent;
  border: 0;
  cursor: pointer;
  padding: 8px;
  flex-direction: column;
  gap: 5px;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 4px;
  -webkit-tap-highlight-color: transparent;
}
.nav-toggle:hover { background: color-mix(in srgb, var(--hamburger) 15%, transparent); }
.nav-toggle span {
  display: block;
  width: 24px;
  height: 2px;
  background: var(--hamburger);
  border-radius: 1px;
  transition: transform .25s ease, opacity .2s ease;
  transform-origin: center;
}

/* ── Hero ──
   Default (no background image): clean, light banner that blends with the
   page. Large centered heading, muted subheading, themed CTA button. The
   heavy dark-background "banner" look is reserved for hero-with-image,
   where it's needed to keep light text readable over a photo. */
.hero {
  background: var(--bg);
  color: var(--fg);
  padding: 72px 20px 32px;
  text-align: center;
}
/* When the hero (or any home text section) is immediately followed by a
   full-bleed gallery slider, drop the gap to nearly zero - the slider
   becomes the visual divider on its own. */
.hero + .gallery-slider,
.home-body + .gallery-slider {
  margin-top: 0;
}
.home-body:has(+ .gallery-slider) { margin-bottom: 16px; }
/* The slider is full-bleed via margin-left:calc(50% - 50vw), but its
   parent <main class="wrap"> still has 32px top padding which pushes
   the slider away from the hero. When the slider is the first child of
   the wrap, cancel that padding so it sits flush against the hero. */
.wrap > .gallery-slider:first-child { margin-top: -32px; }
.hero h1 {
  font-size: 44px;
  font-weight: 700;
  letter-spacing: -0.5px;
  margin-bottom: 14px;
  color: var(--fg);
}
.hero p {
  font-size: 18px;
  color: var(--muted);
  margin: 0 auto 26px;
  max-width: 640px;
  line-height: 1.5;
}

/* With a background image: switch to the dramatic darkened-photo style. */
.hero.has-image {
  background-size: cover;
  background-position: center;
  position: relative;
  color: #fff;
  padding: 96px 20px;
  border-bottom: none;
}
.hero.has-image h1 { color: #fff; }
.hero.has-image p { color: rgba(255, 255, 255, .88); }
.hero.has-image::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .45);
}
.hero > * { position: relative; }

.hero .btn-cta { display: inline-block; background: var(--btn-bg); color: var(--btn-text); padding: 12px 28px; border-radius: 4px; font-weight: 600; }
.hero .btn-cta:hover { background: var(--btn-hover-bg); color: var(--btn-text); text-decoration: none; }

/* ── Page header ── */
.page-header { margin-bottom: 32px; }
.page-header h1 { font-size: 32px; margin-bottom: 8px; }

/* Gallery-as-page H1 is intentionally smaller than other page headers
   so the photos below stay the visual hero. */
body.template-gallery-page .page-header h1 { font-size: 24px; }
@media (max-width: 700px) {
  body.template-gallery-page .page-header h1 { font-size: 20px; }
}

/* ── Album back-link breadcrumb ──
   When a gallery is part of an album group, the build renders a small
   "← Back to {album}" anchor immediately before the H1. The two sit on
   the same horizontal line with a small gap; the back-link reads as a
   secondary breadcrumb so the H1 still owns the visual hierarchy. */
.page-header .album-back-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  color: var(--muted);
  text-decoration: none;
  margin-right: 12px;
  padding: 4px 0;
  vertical-align: middle;
  transition: color 150ms ease;
}
.page-header .album-back-link::before { content: "←"; font-size: 14px; line-height: 1; }
.page-header .album-back-link:hover { color: var(--accent); }
.page-header .album-back-wrap {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 12px;
}

/* ── Sibling gallery prev/next pagination ──
   Footer-style bar at the bottom of a page-mode gallery page when the
   gallery is part of an album group (albumOf set). Two anchors flank
   the bar; each shows a small "PREVIOUS GALLERY" / "NEXT GALLERY"
   eyebrow above the destination gallery's name, plus a chevron icon
   on the outer edge. Wraps cleanly on narrow screens by collapsing to
   a vertical stack. */
.gallery-pagination {
  display: flex;
  justify-content: space-between;
  align-items: stretch;
  gap: 24px;
  margin: 56px 0 24px;
  padding: 20px 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.gallery-pagination a {
  display: flex;
  align-items: center;
  gap: 14px;
  text-decoration: none;
  color: var(--text);
  padding: 8px 4px;
  flex: 1 1 0;
  min-width: 0;
  transition: opacity 200ms ease;
}
.gallery-pagination a:hover { opacity: .7; }
.gallery-pagination .gp-prev { justify-content: flex-start; text-align: left; }
.gallery-pagination .gp-next { justify-content: flex-end; text-align: right; }
/* Empty placeholder when the current gallery has no prev (first) or no
   next (last) - keeps the remaining anchor on its expected side via
   justify-content:space-between. */
.gallery-pagination .gp-spacer { flex: 1 1 0; display: block; }
.gallery-pagination .gp-label {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.gallery-pagination .gp-eyebrow {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: var(--muted, #888);
  line-height: 1;
  margin-bottom: 4px;
}
.gallery-pagination .gp-name {
  font-size: 16px;
  font-weight: 600;
  color: var(--text-heading, var(--text));
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Bar + chevron icon, pure CSS so we don't pull in FontAwesome. The
   horizontal bar is the ::after pseudo and the chevron arrow is the
   element itself rotated. */
.gallery-pagination .gp-icon {
  position: relative;
  width: 36px;
  height: 12px;
  flex: 0 0 36px;
}
.gallery-pagination .gp-icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 2px;
  background: currentColor;
  transform: translateY(-50%);
}
.gallery-pagination .gp-icon::before {
  content: "";
  position: absolute;
  top: 50%;
  width: 10px;
  height: 10px;
  border-top: 2px solid currentColor;
  border-right: 2px solid currentColor;
}
.gallery-pagination .gp-prev .gp-icon::before {
  left: 0;
  transform: translateY(-50%) rotate(-135deg);
}
.gallery-pagination .gp-next .gp-icon::before {
  right: 0;
  transform: translateY(-50%) rotate(45deg);
}
@media (max-width: 540px) {
  /* Stack the two anchors vertically. Keep each anchor's desktop layout
     so the chevron tip stays at the OUTER end of the bar — prev's arrow
     points left at the start of its bar, next's arrow points right at
     the end of its bar. Previously we used row-reverse + left:0 on next,
     which dragged the chevron INTO the middle of the bar (looked like
     ">----" instead of "---->"). */
  .gallery-pagination { flex-direction: column; gap: 8px; }
}
.page-desc { color: var(--muted); }

.page-body { margin-bottom: 40px; }
.page-body h2 { margin: 24px 0 12px; }
.page-body p, .page-body ul, .page-body ol { margin-bottom: 16px; }
.page-body ul, .page-body ol { padding-left: 24px; }

/* ── Homepage sections ── */
.home-section { margin: 48px 0; }
.home-section h2 { font-size: 24px; margin-bottom: 20px; }

/* ── Homepage body (free-form WYSIWYG output) ──
   Gives the user-authored body HTML readable spacing, a comfortable reading
   width, and consistent rhythm for headings, paragraphs, lists, quotes,
   and images. Matches .page-body so the same authoring output looks right
   on both the home page and standalone pages. */
.home-body {
  max-width: 820px;
  margin: 48px auto;
  line-height: 1.7;
  font-size: 16px;
  color: var(--fg);
}
.home-body h1,
.home-body h2,
.home-body h3,
.home-body h4 { margin: 28px 0 12px; line-height: 1.3; color: var(--fg); }
.home-body h1 { font-size: 32px; }
.home-body h2 { font-size: 26px; }
.home-body h3 { font-size: 20px; }
.home-body h4 { font-size: 17px; }
.home-body p,
.home-body ul,
.home-body ol,
.home-body blockquote { margin: 0 0 16px; }
.home-body ul,
.home-body ol { padding-left: 28px; }
.home-body li { margin-bottom: 6px; }
.home-body a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.home-body a:hover { color: var(--accent-hover); }
.home-body strong { color: var(--fg); }
.home-body blockquote {
  border-left: 3px solid var(--accent);
  padding: 4px 14px;
  color: var(--muted);
  font-style: italic;
  background: color-mix(in srgb, var(--accent) 5%, transparent);
}
.home-body img {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 20px auto;
  border-radius: 6px;
}
.home-body hr { border: 0; border-top: 1px solid var(--border); margin: 32px 0; }
/* Direct children that were imported as plain text and left as raw block
   elements (div/section) still get a little breathing room. */
.home-body > * + * { margin-top: 12px; }

@media (max-width: 600px) {
  .home-body { font-size: 15px; margin: 32px auto; }
  .home-body h1 { font-size: 26px; }
  .home-body h2 { font-size: 22px; }
}

/* ── Mobile / narrow-tablet heading scale ──
   Below 700px the page headers + the inline body headings drop down one
   step so the largest type doesn't overflow the column. Sits above the
   existing 600px rules in source so the 600px overrides win for the
   smallest screens. */
@media (max-width: 700px) {
  .page-header h1 { font-size: 26px; }
  .home-body h1 { font-size: 28px; }
  .home-body h2 { font-size: 22px; }
  .home-section h2 { font-size: 20px; }
  .product-info h1 { font-size: 24px; }
  .hero h1 { font-size: 32px; }
  .page-body h2 { font-size: 20px; }
}

/* ── Product grid ── */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 20px; }
.card { background: var(--card-bg); border: 1px solid var(--border); border-radius: 6px; overflow: hidden; transition: box-shadow .15s, transform .15s; }
.card:hover { box-shadow: 0 4px 12px rgba(0,0,0,.08); transform: translateY(-2px); }
.card a { color: inherit; text-decoration: none; display: block; }
.card-img-wrap { aspect-ratio: 1; background: #fff; overflow: hidden; }
.card-img-wrap img { width: 100%; height: 100%; object-fit: contain; }
.card-body { padding: 12px 14px; }
.card h3 { font-size: 15px; font-weight: 600; margin-bottom: 4px; line-height: 1.3; }
.card .price { color: var(--accent); font-weight: 600; font-size: 15px; }
.card .short { color: var(--muted); font-size: 13px; margin-top: 4px; }

/* ── Category cards ── */
.cat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; }
.cat-card { background: var(--card-bg); border: 1px solid var(--border); border-radius: 6px; padding: 24px; text-align: center; transition: border-color .15s; }
.cat-card:hover { border-color: var(--accent); text-decoration: none; }
.cat-card h3 { font-size: 18px; }

/* ── Product page ── */
.product-page { max-width: 1100px; }
.product-layout { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; }
@media (max-width: 768px) { .product-layout { grid-template-columns: 1fr; } }
.main-image { background: #fff; border: 1px solid var(--border); border-radius: 6px; aspect-ratio: 1; overflow: hidden; }
.main-image img { width: 100%; height: 100%; object-fit: contain; }
.thumb-row { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.thumb { width: 68px; height: 68px; border: 1px solid var(--border); border-radius: 4px; overflow: hidden; cursor: pointer; background: #fff; }
.thumb.active { border-color: var(--accent); }
.thumb img { width: 100%; height: 100%; object-fit: contain; }

.product-info h1 { font-size: 28px; margin-bottom: 12px; }
.price-block { font-size: 24px; font-weight: 700; color: var(--accent); margin-bottom: 20px; }
.product-desc { margin-bottom: 24px; line-height: 1.7; }
.product-desc p, .product-desc ul { margin-bottom: 12px; }
.product-desc ul { padding-left: 22px; }

.btn-buy { display: inline-block; background: var(--btn-bg); color: var(--btn-text); padding: 12px 28px; border-radius: 4px; font-weight: 600; border: none; cursor: pointer; font-size: 15px; }
.btn-buy:hover { background: var(--btn-hover-bg); text-decoration: none; color: var(--btn-text); }

.meta-block { margin-top: 24px; padding: 16px; background: var(--card-bg); border-radius: 4px; font-size: 14px; }
.meta-block dt { font-weight: 600; color: var(--muted); display: inline-block; min-width: 80px; }
.meta-block dd { display: inline; }
.meta-block div { margin-bottom: 6px; }

.tag-links { margin-top: 20px; font-size: 13px; color: var(--muted); }
.tag-links a { display: inline-block; margin-right: 10px; padding: 3px 10px; border: 1px solid var(--border); border-radius: 20px; font-size: 12px; }

/* ── Footer ── */
.site-footer { background: var(--footer-bg); color: var(--footer-text); margin-top: 60px; }
/* Footer is now a single line of "cells" (brand, optional slogan, then each
   link) separated by a pipe via a CSS pseudo-element on each cell after the
   first. Wraps cleanly on narrow screens. */
.footer-inner {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 32px 20px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0;
  justify-content: center;
  text-align: center;
  line-height: 1.6;
}
.footer-cell {
  font-size: 13px;
  color: var(--footer-text);
  text-decoration: none;
  padding: 2px 0;
}
a.footer-cell { color: var(--footer-link); text-decoration: var(--footer-link-decoration); }
a.footer-cell:hover { color: var(--footer-link-hover); text-decoration: var(--footer-link-decoration-hover); }
.footer-cell.footer-brand { font-size: 14px; }
.footer-cell.footer-slogan { font-style: italic; opacity: .85; }
.footer-cell + .footer-cell::before {
  content: "|";
  margin: 0 14px;
  opacity: .4;
  font-weight: 300;
}

@media (max-width: 600px) {
  .hero h1 { font-size: 28px; }
  /* Tighten the gap on phones - the hero's bottom padding plus the
     slider's full-bleed height was leaving a chunky band of empty
     space between the subheading and the image. Drop the hero's
     bottom padding and any margin between it and an adjacent slider. */
  .hero { padding-bottom: 16px; }
  .hero + .gallery-slider,
  .home-body + .gallery-slider { margin-top: 0; }
  .home-body:has(+ .gallery-slider) { margin-bottom: 8px; }
}

/* The entire mobile-nav stylesheet (hamburger + drawer + dropdowns) used
   to live in this 600px @media block. It now lives in
   themes/Standard/templates/_nav-mobile.css.tpl and is generated per-site
   by build.mjs with the user's chosen breakpoint substituted for
   __MOBILE_BP__. The generated CSS is inlined into the page head as a
   <style> block after this file, so it wins on identical specificity. */

/* ══════════ PAGE TEMPLATES ══════════ */

/* ── FAQ template ──
   Apply by setting a page's `template` field to "faq".  Every <h2> / <h3>
   in the body becomes a collapsible question card; the paragraph(s) that
   follow it become the answer. Authors don't need to add any special markup.
*/
body.template-faq .page-header {
  text-align: center;
  padding: 20px 0 30px;
  border-bottom: 2px solid var(--theme-primary, var(--accent));
  margin-bottom: 30px;
}
body.template-faq .page-header h1 {
  font-size: 42px;
  font-weight: 800;
  margin-bottom: 8px;
  letter-spacing: -.5px;
}
body.template-faq .page-desc {
  color: var(--muted);
  font-size: 16px;
  max-width: 640px;
  margin: 0 auto;
}

body.template-faq .page-body {
  max-width: 820px;
  margin: 0 auto;
}

/* Each <h2> / <h3> - or a <p> whose ONLY content is bold text (imported FAQ
   content often comes this way) - is treated as a question card. */
body.template-faq .page-body > h2,
body.template-faq .page-body > h3,
body.template-faq .page-body > p:has(> b:only-child),
body.template-faq .page-body > p:has(> strong:only-child) {
  position: relative;
  margin-top: 18px;
  padding: 18px 52px 18px 22px;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-left: 4px solid var(--theme-primary, var(--accent));
  border-radius: 6px;
  font-size: 18px;
  font-weight: 700;
  color: var(--fg);
  cursor: default;
  transition: box-shadow .15s, border-color .15s;
}
body.template-faq .page-body > h2:hover,
body.template-faq .page-body > h3:hover,
body.template-faq .page-body > p:has(> b:only-child):hover,
body.template-faq .page-body > p:has(> strong:only-child):hover {
  box-shadow: 0 2px 10px rgba(0,0,0,.06);
}
/* Strip the bold styling on our synthetic question paragraphs so the card's
   own font-weight/size take over cleanly. */
body.template-faq .page-body > p:has(> b:only-child) > b,
body.template-faq .page-body > p:has(> strong:only-child) > strong {
  font-weight: inherit;
}
/* Little "Q" mark on the right of each question */
body.template-faq .page-body > h2::after,
body.template-faq .page-body > h3::after,
body.template-faq .page-body > p:has(> b:only-child)::after,
body.template-faq .page-body > p:has(> strong:only-child)::after {
  content: "Q";
  position: absolute;
  top: 50%;
  right: 18px;
  transform: translateY(-50%);
  font-weight: 800;
  font-size: 13px;
  color: #fff;
  background: var(--theme-primary, var(--accent));
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  letter-spacing: 0;
}
/* Answer body - a paragraph / list / blockquote immediately under the heading. */
body.template-faq .page-body > h2 + p,
body.template-faq .page-body > h3 + p,
body.template-faq .page-body > h2 + ul,
body.template-faq .page-body > h3 + ul,
body.template-faq .page-body > h2 + ol,
body.template-faq .page-body > h3 + ol,
body.template-faq .page-body > h2 + blockquote,
body.template-faq .page-body > h3 + blockquote,
body.template-faq .page-body > p + p,
body.template-faq .page-body > p + ul,
body.template-faq .page-body > p + ol {
  margin: 0 22px 0 22px;
  padding: 14px 22px;
  background: #fff;
  border: 1px solid var(--border);
  border-top: none;
  border-bottom: none;
  line-height: 1.7;
}
/* Close the answer block with a rounded bottom on the last paragraph before
   the next question. Using + * lookahead is impossible in pure CSS, so we
   round the base answer instead and let consecutive paragraphs visually join. */
body.template-faq .page-body p,
body.template-faq .page-body ul,
body.template-faq .page-body ol,
body.template-faq .page-body blockquote {
  font-size: 15px;
}
body.template-faq .page-body a {
  color: var(--theme-secondary, var(--accent));
  text-decoration: underline;
  text-underline-offset: 2px;
}
body.template-faq .page-body strong {
  color: var(--fg);
}
body.template-faq .page-body ul,
body.template-faq .page-body ol {
  padding-left: 42px;
}
body.template-faq .page-body img {
  border-radius: 6px;
  margin: 12px auto;
}

/* Softer card-bottom: wrap the answer group by rounding the first paragraph
   in each cluster and the last one by selecting the sibling-before-heading. */
body.template-faq .page-body > h2 + p:last-child,
body.template-faq .page-body > h3 + p:last-child,
body.template-faq .page-body > h2 + ul:last-child,
body.template-faq .page-body > h3 + ul:last-child {
  border-bottom: 1px solid var(--border);
  border-bottom-left-radius: 6px;
  border-bottom-right-radius: 6px;
}

/* Small screens: tighten padding */
@media (max-width: 600px) {
  body.template-faq .page-header h1 { font-size: 30px; }
  body.template-faq .page-body > h2,
  body.template-faq .page-body > h3 { padding: 14px 44px 14px 16px; font-size: 16px; }
  body.template-faq .page-body > h2 + p,
  body.template-faq .page-body > h3 + p,
  body.template-faq .page-body p + p {
    margin: 0 8px 0 8px;
    padding: 12px 14px;
  }
}

/* ══════════ CONTACT FORM ══════════
   Rendered by pages with template="contact". Field rows stack vertically
   with consistent spacing. reCAPTCHA widget (if present) sits above the
   submit button. */
body.template-contact .page-body { max-width: 640px; margin: 0 auto; }
.contact-form { display: flex; flex-direction: column; gap: 16px; margin-top: 12px; }
.contact-form .cf-row { display: flex; flex-direction: column; gap: 6px; }
.contact-form .cf-label { font-size: 13px; font-weight: 600; color: var(--fg); }
.contact-form .cf-label .req { color: var(--accent); margin-left: 2px; }
.contact-form input[type="text"],
.contact-form input[type="email"],
.contact-form input[type="tel"],
.contact-form input[type="number"],
.contact-form textarea,
.contact-form select {
  width: 100%;
  padding: 10px 12px;
  font: inherit;
  color: var(--fg);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 4px;
  transition: border-color .15s, box-shadow .15s;
}
.contact-form input:focus,
.contact-form textarea:focus,
.contact-form select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}
.contact-form textarea { resize: vertical; min-height: 120px; }
.contact-form .g-recaptcha { margin: 4px 0; }
.contact-form .btn-submit {
  align-self: flex-start;
  background: var(--btn-bg);
  color: var(--btn-text);
  padding: 12px 28px;
  border: none;
  border-radius: 4px;
  font-weight: 600;
  font-size: 15px;
  cursor: pointer;
  transition: background .15s;
}
.contact-form .btn-submit:hover { background: var(--btn-hover-bg); }
.contact-form .cf-success {
  padding: 12px 16px;
  background: color-mix(in srgb, #2ecc71 15%, transparent);
  border: 1px solid color-mix(in srgb, #2ecc71 50%, transparent);
  border-radius: 4px;
  color: #1e7e4a;
  font-size: 14px;
}

/* ══════════ SITE FORM (reusable forms.json) ══════════
   The newer reusable form builder, rendered by pages via
   formAbove / formBelow. Same general look as .contact-form but adds
   custom-styled radios + checkboxes (the native inputs are visually
   hidden and we draw a circle / square via .sf-option-mark) so the
   form feels first-class regardless of OS. The native input is still
   focusable + keyboard-accessible - we paint hover/focus/checked
   states off its :checked / :focus-visible siblings. */
.site-form { max-width: 640px; margin: 36px auto; padding: 0 20px; }
.site-form .sf-heading { font-size: 24px; margin: 0 0 18px; color: var(--fg); letter-spacing: -.3px; }
.sf-form { display: flex; flex-direction: column; gap: 16px; }
.sf-row { display: flex; flex-direction: column; gap: 6px; }
.sf-row-inline { flex-direction: row; align-items: flex-start; }
.sf-label { font-size: 13px; font-weight: 600; color: var(--fg); }
.sf-label .sf-req, .sf-option-label .sf-req { color: var(--btn-bg); margin-left: 2px; }
.sf-help { font-size: 12px; color: var(--muted); margin-top: -2px; }
.sf-form input[type="text"],
.sf-form input[type="email"],
.sf-form input[type="tel"],
.sf-form input[type="number"],
.sf-form input[type="url"],
.sf-form textarea,
.sf-form select {
  width: 100%;
  padding: 10px 12px;
  font: inherit;
  color: var(--fg);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 4px;
  transition: border-color .15s, box-shadow .15s;
}
.sf-form input:focus,
.sf-form textarea:focus,
.sf-form select:focus {
  outline: none;
  border-color: var(--accent, var(--btn-bg));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent, var(--btn-bg)) 25%, transparent);
}
.sf-form textarea { resize: vertical; min-height: 120px; }
.sf-form select { appearance: none; -webkit-appearance: none; background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%); background-position: calc(100% - 18px) 14px, calc(100% - 12px) 14px; background-size: 6px 6px, 6px 6px; background-repeat: no-repeat; padding-right: 38px; }
/* Radio + checkbox option lists. Each .sf-option is a clickable row
   with a custom-drawn marker; the underlying native input is visually
   hidden but still keyboard / screen-reader accessible. */
.sf-options { display: flex; flex-direction: column; gap: 6px; padding: 4px 0; }
.sf-options-radio,
.sf-options-checkboxes { gap: 8px; }
.sf-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  transition: border-color .15s, background .15s;
  background: #fff;
  user-select: none;
  font-size: 14px;
  line-height: 1.35;
  color: var(--fg);
}
.sf-option:hover { border-color: var(--btn-bg); background: color-mix(in srgb, var(--btn-bg) 4%, #fff); }
.sf-option input { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); border: 0; }
.sf-option-mark {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border: 2px solid var(--border);
  border-radius: 50%;
  position: relative;
  background: #fff;
  transition: border-color .15s, background .15s;
}
.sf-option-mark::after {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  background: var(--btn-bg);
  transform: scale(0);
  transition: transform .15s ease;
}
.sf-option-mark-square { border-radius: 4px; }
.sf-option-mark-square::after { border-radius: 2px; inset: 2px; background: transparent; border: solid var(--btn-bg); border-width: 0 2px 2px 0; transform: rotate(45deg) scale(0); width: 8px; height: 12px; left: 50%; top: 45%; margin: -7px 0 0 -4px; inset: auto; }
.sf-option input:checked + .sf-option-mark { border-color: var(--btn-bg); }
.sf-option input:checked + .sf-option-mark::after { transform: scale(1); }
.sf-option input:checked + .sf-option-mark-square::after { transform: rotate(45deg) scale(1); }
.sf-option input:focus-visible + .sf-option-mark { box-shadow: 0 0 0 3px color-mix(in srgb, var(--btn-bg) 25%, transparent); }
.sf-option:has(input:checked) { border-color: var(--btn-bg); background: color-mix(in srgb, var(--btn-bg) 6%, #fff); }
.sf-option-single { border: 0; padding: 0; background: transparent; }
.sf-option-single:hover { background: transparent; border: 0; }
.sf-recaptcha { margin: 4px 0; }
.sf-submit-row { margin-top: 4px; }
.sf-submit {
  align-self: flex-start;
  background: var(--btn-bg);
  color: var(--btn-text);
  padding: 12px 28px;
  border: none;
  border-radius: 4px;
  font-weight: 600;
  font-size: 15px;
  cursor: pointer;
  transition: background .15s, transform .05s;
}
.sf-submit:hover { background: var(--btn-hover-bg); }
.sf-submit:active { transform: translateY(1px); }
.sf-success {
  padding: 12px 16px;
  background: color-mix(in srgb, #2ecc71 15%, transparent);
  border: 1px solid color-mix(in srgb, #2ecc71 50%, transparent);
  border-radius: 4px;
  color: #1e7e4a;
  font-size: 14px;
}
/* Inline status / error message slot the submit handler creates when
   it has something to report (form not configured, network failure,
   non-2xx response). Default to a neutral muted look; .sf-status-error
   adds the red accent so a problem stands out without being shouty. */
.sf-status {
  margin: 8px 0 0;
  padding: 10px 14px;
  background: color-mix(in srgb, var(--muted, #666) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--muted, #666) 25%, transparent);
  border-radius: 4px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text, #1b1b1b);
}
.sf-status-error {
  background: color-mix(in srgb, #d9534f 10%, transparent);
  border-color: color-mix(in srgb, #d9534f 45%, transparent);
  color: #a02622;
}

/* ══════════ GALLERY SLIDER ══════════
   Full-bleed slider: breaks out of any centred .wrap container so it spans
   the whole viewport width. Slides are stacked and fade between each other;
   client JS (js/site.js) handles auto-advance + dot navigation. */
/* ── Site gallery (Whizz-style: justifiedGallery + lightGallery) ──
   Markup mirrors gray-shades.html so the bundled lightGallery + justified
   Gallery libs work directly. Layout is a justified-row masonry; clicking
   any tile opens lightGallery with the thumbnail strip + zoom buttons. */
.site-gallery { margin: 36px auto; max-width: var(--max-width); padding: 0 20px; }
.site-gallery .sg-heading { font-size: 26px; margin-bottom: 6px; color: var(--fg); letter-spacing: -.4px; }
.site-gallery .sg-desc { color: var(--muted); font-size: 15px; margin-bottom: 18px; max-width: 720px; }

/* CSS-Grid layout for the gallery (we don't use justifiedGallery -
   it fought our width/height rules with negative-margin centring tricks
   meant for natural-sized images). The grid handles spacing, aspect,
   and responsiveness; lightGallery still drives the popup slider. */
.gallery-single { position: relative; }
.gallery-single .izotope-container {
  display: grid;
  /* Default: 2 columns (matches Whizz gray-shades). Per-gallery override
     via .sg-cols-{n} on the section. .sg-cols-auto falls back to a
     responsive auto-fill grid. */
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}
.site-gallery.sg-cols-1 .izotope-container { grid-template-columns: 1fr; }
.site-gallery.sg-cols-2 .izotope-container { grid-template-columns: repeat(2, 1fr); }
.site-gallery.sg-cols-3 .izotope-container { grid-template-columns: repeat(3, 1fr); }
.site-gallery.sg-cols-4 .izotope-container { grid-template-columns: repeat(4, 1fr); }
.site-gallery.sg-cols-auto .izotope-container { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
@media (max-width: 600px) {
  /* On phones, multi-column grids drop to 1 column for legibility unless
     explicitly set to 1 already. (Auto stays responsive.) */
  .site-gallery.sg-cols-2 .izotope-container,
  .site-gallery.sg-cols-3 .izotope-container,
  .site-gallery.sg-cols-4 .izotope-container { grid-template-columns: 1fr; }
}
.gallery-single .grid-sizer { display: none; }
.gallery-single .item-single { overflow: hidden; }
.gallery-single .gallery-item {
  display: block;
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 100%;
  text-decoration: none;
  background: var(--card-bg, #f5f5f5);
}
.gallery-single .gallery-item img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* Default crop is centred. The square-tile variant overrides this
     to top-align (see .site-gallery.sg-aspect-square below) so a
     portrait photo keeps its top - usually the face / subject -
     visible in the thumbnail instead of slicing across the middle. */
  object-position: center;
  display: block;
  transition: transform .6s ease, opacity .35s ease;
}
.site-gallery.sg-aspect-square .gallery-single .gallery-item img {
  object-position: center top;
}
.gallery-single .gallery-item:hover img { transform: scale(1.05); }

/* Hover overlay (the Whizz "info-content"). Hidden by default - the
   gallery's hover-effect setting decides which variant to show:
     sg-hover-none      → never visible.
     sg-hover-dim       → dark fade on hover, no caption text.
     sg-hover-dim-label → dark fade on hover + caption text inside. */
.gallery-single .info-content {
  position: absolute;
  inset: 0;
  display: none;                  /* default: no overlay (sg-hover-none) */
  align-items: center;
  justify-content: center;
  /* --sg-overlay is set per-section by the build when the gallery has
     a custom Overlay darkness (admin → grid-opts → Overlay darkness).
     Falling back to .45 keeps the legacy look for galleries that
     haven't set the field. */
  background: rgba(0, 0, 0, var(--sg-overlay, .45));
  opacity: 0;
  transition: opacity .25s ease;
  pointer-events: none;
  padding: 20px;
}
.site-gallery.sg-hover-dim       .gallery-single .info-content,
.site-gallery.sg-hover-dim-label .gallery-single .info-content { display: flex; }
.site-gallery.sg-hover-dim       .gallery-single .gallery-item:hover .info-content,
.site-gallery.sg-hover-dim-label .gallery-single .gallery-item:hover .info-content { opacity: 1; }
/* Hide the caption text under "dim" mode even though the markup contains it. */
.site-gallery.sg-hover-dim       .gallery-single .info-content .vertical-align { display: none; }
.gallery-single .info-content .vertical-align { color: #fff; text-align: center; }
.gallery-single .info-content h5 {
  font-size: 16px;
  letter-spacing: 2px;
  margin: 0;
  text-transform: uppercase;
  color: #fff;
  font-weight: 700;
}

/* ── Per-tile "inverted overlay" ──
   When the user ticks "Inverted overlay" on a tile, the build adds
   .sg-tile-inverted to its .item-single wrapper. The overlay then
   shows BY DEFAULT (dim + caption visible), and on hover / tap the
   dim fades out so the photo reads cleanly underneath. Inversion is
   per-tile so the rest of the gallery can keep its normal flow. The
   selectors below force display:flex regardless of which gallery-wide
   sg-hover-* class is set, because an inverted tile needs an overlay
   container to fade out of - the gallery's hover effect is irrelevant
   for these tiles. */
.gallery-single .item-single.sg-tile-inverted .info-content {
  display: flex;
  opacity: 1;
}
.gallery-single .item-single.sg-tile-inverted .gallery-item:hover .info-content,
.gallery-single .item-single.sg-tile-inverted .gallery-item:active .info-content,
.gallery-single .item-single.sg-tile-inverted .gallery-item:focus-visible .info-content {
  opacity: 0;
}
/* Caption text inside an inverted tile is always rendered visibly,
   even if the gallery is in plain "sg-hover-dim" mode (which hides
   the caption text for the rest of the gallery). */
.gallery-single .item-single.sg-tile-inverted .info-content .vertical-align {
  display: block;
}

/* Aspect-ratio variants drive the row height of justifiedGallery via JS,
   but also set a minimum aspect on tiles so they look right while images
   are still loading. */
.site-gallery.sg-aspect-square .gallery-item { aspect-ratio: 1 / 1; }
.site-gallery.sg-aspect-wide   .gallery-item { aspect-ratio: 16 / 9; }
.site-gallery.sg-aspect-tall   .gallery-item { aspect-ratio: 9 / 16; }

@media (max-width: 600px) {
  .site-gallery .sg-heading { font-size: 22px; }
  /* Three mobile view modes for site-gallery tiles - applied per-gallery
     via the section's sg-mobile-* class. Defaults to "preserve" which
     keeps the desktop aspect on mobile too. */
  .site-gallery.sg-mobile-portrait .gallery-item { aspect-ratio: 9 / 16; }
  .site-gallery.sg-mobile-square   .gallery-item { aspect-ratio: 1 / 1;  }
  /* Mobile mode "preserve" (default): declared aspect unchanged. */
}

.gallery-slider {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  overflow: hidden;
  background: #000;
}
.gallery-slider.gs-h-full   { height: 100vh; }
.gallery-slider.gs-h-tall   { height: 70vh; }
.gallery-slider.gs-h-medium { height: 50vh; }

.gallery-slider .gs-heading {
  position: absolute;
  top: 24px;
  left: 50%;
  transform: translateX(-50%);
  color: #fff;
  font-size: 28px;
  text-shadow: 0 2px 8px rgba(0,0,0,.5);
  z-index: 3;
  margin: 0;
  padding: 0 16px;
  text-align: center;
}

.gallery-slider .gs-track {
  position: absolute;
  inset: 0;
}
.gallery-slider .gs-slide {
  position: absolute;
  inset: 0;
  /* `contain` keeps each image at its natural aspect ratio - the image fits
     inside the slide fully, never stretched and never cropped. Any leftover
     space shows the slider's black background (letterbox/pillarbox). */
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
  opacity: 0;
  /* --gs-fade is set per-section by the build (style="--gs-fade:700ms").
     Falling back to 700ms keeps the default behaviour when the variable
     isn't supplied (older builds, hand-written sections, etc.). */
  transition: opacity var(--gs-fade, 700ms) ease;
  will-change: opacity;
  /* Inactive slides stay stacked above/below the active one. opacity:0
     doesn't disable pointer events, so without this they'd eat every
     click - including taps on the slide-link. Restored on .active so
     the visible slide is fully interactive. */
  pointer-events: none;
}
.gallery-slider .gs-slide.active {
  opacity: 1;
  pointer-events: auto;
}

/* Dots at the bottom-center of the slider */
.gallery-slider .gs-dots {
  position: absolute;
  bottom: 22px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 10px;
  z-index: 3;
}
.gallery-slider .gs-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid #fff;
  background: transparent;
  padding: 0;
  cursor: pointer;
  opacity: .7;
  transition: background .2s, opacity .2s, transform .2s;
}
.gallery-slider .gs-dot:hover { opacity: 1; }
.gallery-slider .gs-dot.active {
  background: #fff;
  opacity: 1;
  transform: scale(1.15);
}

/* ── Per-slide text overlay ──
   Sits 20% up from the bottom of the slide so the caption hovers in
   the lower third of the image - matches the convention most hero
   sliders use, leaves the top half of the photo unobscured. Subtle
   dark panel keeps the white text legible against any photo. */
.gallery-slider .gs-slide-text {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 20%;
  display: flex;
  justify-content: center;
  padding: 0 5vw;
  z-index: 2;
}
.gallery-slider .gs-slide-text-inner {
  max-width: 720px;
  text-align: center;
  color: #fff;
  padding: 22px 28px;
  background: rgba(0, 0, 0, .42);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 4px;
}
.gallery-slider .gs-slide-subtitle {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 18px;
  line-height: 1.45;
  margin: 0 0 10px;
  color: rgba(255, 255, 255, .92);
  letter-spacing: .5px;
}
.gallery-slider .gs-slide-title {
  font-size: 32px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 1.5px;
  margin: 0 0 10px;
  color: #fff;
  text-shadow: 0 2px 12px rgba(0, 0, 0, .35);
}
.gallery-slider .gs-slide-desc {
  font-size: 17px;
  line-height: 1.55;
  margin: 0 0 18px;
  color: rgba(255, 255, 255, .92);
}
.gallery-slider .gs-slide-link {
  display: inline-block;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: #fff;
  text-decoration: none;
  padding: 10px 0;
  border-bottom: 1px solid #fff;
  transition: opacity 200ms ease;
}
.gallery-slider .gs-slide-link:hover { opacity: .75; }
/* The text overlay should fade in WITH its slide. The .gs-slide opacity
   transition already covers this because the text is a descendant. */

/* ── Pause / play toggle ──
   Sits in the top-right corner. Hovering it (or the dots) pauses
   autoplay; clicking flips persistent state. The icon is two CSS bars
   (||) when running, a triangle (▶) when paused, both done with
   pseudo-elements so we don't ship an icon font. */
.gallery-slider .gs-play-pause {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(0, 0, 0, .45);
  border: 1px solid rgba(255, 255, 255, .35);
  color: #fff;
  cursor: pointer;
  z-index: 4;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background .2s ease, transform .2s ease;
}
.gallery-slider .gs-play-pause:hover { background: rgba(0, 0, 0, .7); }
.gallery-slider .gs-pp-icon {
  position: relative;
  display: block;
  width: 12px;
  height: 14px;
}
/* Paused state (aria-pressed=true) shows ▶ ; running state shows || */
.gallery-slider .gs-play-pause[aria-pressed="false"] .gs-pp-icon::before,
.gallery-slider .gs-play-pause[aria-pressed="false"] .gs-pp-icon::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 3px;
  background: #fff;
}
.gallery-slider .gs-play-pause[aria-pressed="false"] .gs-pp-icon::before { left: 1px; }
.gallery-slider .gs-play-pause[aria-pressed="false"] .gs-pp-icon::after  { right: 1px; }
.gallery-slider .gs-play-pause[aria-pressed="true"] .gs-pp-icon::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 1px;
  transform: translateY(-50%);
  border-style: solid;
  border-width: 6px 0 6px 10px;
  border-color: transparent transparent transparent #fff;
}

@media (max-width: 600px) {
  .gallery-slider.gs-h-full   { height: 80vh; }
  .gallery-slider .gs-heading { font-size: 20px; top: 16px; }
  .gallery-slider .gs-dots    { bottom: 14px; gap: 8px; }
  .gallery-slider .gs-dot     { width: 8px; height: 8px; }
  .gallery-slider .gs-slide-text-inner { padding: 16px 18px; }
  .gallery-slider .gs-slide-subtitle { font-size: 15px; margin-bottom: 8px; }
  .gallery-slider .gs-slide-title { font-size: 22px; letter-spacing: 1px; }
  .gallery-slider .gs-slide-desc  { font-size: 15px; }
  .gallery-slider .gs-slide-link  { font-size: 13px; }
  .gallery-slider .gs-play-pause  { top: 10px; right: 10px; width: 32px; height: 32px; }
  /* Three per-slider mobile view modes (set by build via the
     .gs-mobile-* class on the section).

     Preserve: KEEP the image's landscape orientation, but shrink the
     slider's CONTAINER height to match a 16:9 aspect (56.25vw) so the
     image fills it edge-to-edge with no black bars. The height utility
     classes (gs-h-full / gs-h-tall / gs-h-medium) make the slider 100vh
     / 70vh / 50vh on desktop, which is taller than 16:9 on a phone -
     hence the empty space the user saw. !important overrides those. */
  .gallery-slider.gs-mobile-preserve           { height: 56.25vw !important; }
  /* Portrait: full-screen portrait viewport, image cover-cropped. */
  .gallery-slider.gs-mobile-portrait .gs-slide { background-size: cover; }
  /* Square: 1:1 viewport so landscape images centre-crop into a square. */
  .gallery-slider.gs-mobile-square             { height: 100vw !important; }
  .gallery-slider.gs-mobile-square .gs-slide   { background-size: cover; }
}

/* ── Vertical Slider Gallery ──
   Vertical-sliding gallery derived from the Whizz "home-vertical-slider"
   template. Each slide is the image as a cover background with optional
   white text (subtitle / title / description / "See more" link) on top of
   a subtle dim overlay so the white copy stays legible against any photo.
   Viewport height is calc(100vh - 80px) so the site logo + nav above stay
   visible on initial load. Arrows stay visible and slides keep sliding on
   mobile (we intentionally don't stack like the source template did). */
/* Break out of the page's <main class="wrap"> so the slider spans the full
   viewport width. Without this, the slider is constrained to the wrap's
   max-width (usually ~1100px) and ends up much narrower than the template,
   which sits inside a full-width container with side padding only. */
.vertical-slider-gallery {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  background: #fff;
}
.vertical-slider-gallery .vsg-heading {
  text-align: center;
  margin: 24px 16px 6px;
}
.vertical-slider-gallery .vsg-section-desc {
  text-align: center;
  margin: 0 16px 14px;
  color: var(--muted, #666);
}
/* Outer wrapper sets the side padding (mirrors .outer-swiper-wrapper in the
   Whizz template: padding: 0 90px desktop, 0 30px mobile) so the slider is
   inset from the viewport edges by ~90px without running full-bleed. */
.vertical-slider-gallery .vsg-outer {
  position: relative;
  width: 100%;
  padding: 0 90px;
  box-sizing: border-box;
}
.vertical-slider-gallery .vsg-viewport {
  position: relative;
  width: 100%;
  height: calc(100vh - 80px);
  min-height: 480px;
  overflow: hidden;
  box-shadow: 0 0 30px rgba(0, 0, 0, .15);
}
/* Track holds the slides stacked vertically and translates Y to switch
   between them. flex-direction: column + flex: 0 0 100% on each slide
   makes every slide the full viewport height, with subsequent slides
   sitting below the viewport until translateY reveals them. */
.vertical-slider-gallery .vsg-track {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  transition: transform .8s cubic-bezier(.4, 0, .2, 1);
  will-change: transform;
}
.vertical-slider-gallery .vsg-slide {
  position: relative;
  flex: 0 0 100%;
  width: 100%;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  display: flex;
  align-items: center;
}
.vertical-slider-gallery .vsg-slide::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .25);
  pointer-events: none;
}
.vertical-slider-gallery .vsg-wrap {
  position: relative;
  z-index: 2;
  padding: 0 60px;
  width: 100%;
}
.vertical-slider-gallery .vsg-text {
  color: #fff;
  max-width: 85%;
  display: inline-block;
}
.vertical-slider-gallery .vsg-subtitle {
  font-family: Georgia, serif;
  font-size: 20px;
  font-style: italic;
  margin-bottom: 35px;
  color: #fff;
}
.vertical-slider-gallery .vsg-title {
  font-family: inherit;
  font-size: 70px;
  font-weight: 800;
  line-height: 65px;
  letter-spacing: 11px;
  margin-bottom: 25px;
  text-transform: uppercase;
}
/* Per-gallery opt-out of the heavy 800-weight title (toggle in the admin). */
.vertical-slider-gallery.vsg-titles-regular .vsg-title { font-weight: 400; }
.vertical-slider-gallery .vsg-desc {
  font-family: Georgia, serif;
  font-size: 15px;
  line-height: 22px;
  margin: 6px 6px 25px;
  max-width: 370px;
  opacity: .9;
}
.vertical-slider-gallery .vsg-desc span { color: #fff; }
.vertical-slider-gallery .vsg-more {
  display: inline-block;
  position: relative;
  color: #fff;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 5px;
  text-transform: uppercase;
  padding-bottom: 7px;
  text-decoration: none;
  border-bottom: 1px solid #fff;
  transition: all 250ms ease;
}
.vertical-slider-gallery .vsg-more::after {
  content: "";
  position: absolute;
  right: -3px;
  top: 7px;
  border-left: 4px solid #fff;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transform: rotate(-45deg);
  transition: all 100ms ease;
}
.vertical-slider-gallery .vsg-more:hover {
  border-bottom-color: transparent;
  opacity: 1;
}
.vertical-slider-gallery .vsg-more:hover::after {
  transform: rotate(0deg);
  top: 3px;
}

/* Black up/down chevron arrows, both on the right edge of the viewport
   (prev at the top, next at the bottom). Built from two CSS borders on
   a rotated pseudo-element so the arrow head matches the thin chevron
   look of the template's FontAwesome \f106 / \f107 glyphs without
   pulling in a font dependency. */
.vertical-slider-gallery .vsg-button {
  position: absolute;
  right: 25px;
  width: 44px;
  height: 44px;
  z-index: 5;
  cursor: pointer;
  background: transparent;
  border: 0;
  padding: 0;
  transition: opacity .3s ease;
}
.vertical-slider-gallery .vsg-button::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 14px;
  height: 14px;
  border-top: 3px solid #000;
  border-right: 3px solid #000;
}
.vertical-slider-gallery .vsg-prev          { top: 25px; }
.vertical-slider-gallery .vsg-prev::before  { transform: translate(-50%, -25%) rotate(-45deg); }
.vertical-slider-gallery .vsg-next          { bottom: 25px; }
.vertical-slider-gallery .vsg-next::before  { transform: translate(-50%, -75%) rotate(135deg); }
.vertical-slider-gallery .vsg-button:hover  { opacity: .6; }

@media (max-width: 768px) {
  .vertical-slider-gallery .vsg-outer { padding: 0 30px; }
  .vertical-slider-gallery .vsg-viewport {
    height: calc(100vh - 70px);
    min-height: 360px;
  }
  .vertical-slider-gallery .vsg-wrap { padding: 0 30px; }
  .vertical-slider-gallery .vsg-title { font-size: 40px; line-height: 40px; letter-spacing: 6px; margin-bottom: 18px; }
  .vertical-slider-gallery .vsg-subtitle { font-size: 16px; margin-bottom: 22px; }
  .vertical-slider-gallery .vsg-desc { font-size: 14px; max-width: 320px; }
  .vertical-slider-gallery .vsg-prev    { top: 10px; right: 10px; }
  .vertical-slider-gallery .vsg-next    { bottom: 10px; right: 10px; }
  .vertical-slider-gallery .vsg-button  { width: 36px; height: 36px; }
}

/* ── Horizontal Text and Scroll Gallery ──
   Derived from the Whizz "albums-style-six" demo. Each slide is split
   into a text panel on the left (~33%) and the image on the right (~66%);
   slides advance horizontally via prev/next arrows + autoplay. Shares the
   same per-image fields as the Vertical Slider (subtitle / title /
   description / link URL / link anchor text). */
.horizontal-text-gallery {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  background: #fff;
  padding: 30px 0;
}
.horizontal-text-gallery .htsg-heading {
  text-align: center;
  margin: 0 16px 6px;
}
.horizontal-text-gallery .htsg-section-desc {
  text-align: center;
  margin: 0 16px 14px;
  color: var(--muted, #666);
}
.horizontal-text-gallery .htsg-outer {
  position: relative;
  width: 100%;
  padding: 0 90px;
  box-sizing: border-box;
}
.horizontal-text-gallery .htsg-viewport {
  position: relative;
  width: 100%;
  height: 70vh;
  min-height: 480px;
  overflow: hidden;
}
.horizontal-text-gallery .htsg-track {
  position: absolute;
  inset: 0;
  display: flex;
  transition: transform .8s cubic-bezier(.4, 0, .2, 1);
  will-change: transform;
}
.horizontal-text-gallery .htsg-slide {
  position: relative;
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: stretch;
}
.horizontal-text-gallery .htsg-text {
  width: 33.33%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 30px;
  box-sizing: border-box;
}
.horizontal-text-gallery .htsg-text-inner {
  text-align: center;
  max-width: 360px;
}
.horizontal-text-gallery .htsg-image {
  width: 66.66%;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.horizontal-text-gallery .htsg-subtitle {
  font-family: Georgia, serif;
  font-size: 16px;
  font-style: italic;
  margin-bottom: 12px;
  color: #888;
}
.horizontal-text-gallery .htsg-title {
  font-family: inherit;
  font-size: 40px;
  font-weight: 800;
  line-height: 48px;
  letter-spacing: 7px;
  margin: 0 0 25px;
  text-transform: uppercase;
  color: #1B1B1B;
}
/* Same titleBold opt-out as the vertical slider. */
.horizontal-text-gallery.htsg-titles-regular .htsg-title { font-weight: 400; }
.horizontal-text-gallery .htsg-desc {
  font-family: Georgia, serif;
  font-size: 15px;
  line-height: 22px;
  margin: 0 0 30px;
  color: #555;
  letter-spacing: .6px;
}
.horizontal-text-gallery .htsg-more {
  display: inline-block;
  position: relative;
  color: #000;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 5px;
  text-transform: uppercase;
  padding-bottom: 7px;
  text-decoration: none;
  border-bottom: 1px solid #000;
  transition: all 250ms ease;
}
.horizontal-text-gallery .htsg-more::after {
  content: "";
  position: absolute;
  right: -3px;
  top: 7px;
  border-left: 4px solid #000;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transform: rotate(-45deg);
  transition: all 100ms ease;
}
.horizontal-text-gallery .htsg-more:hover {
  border-bottom-color: transparent;
  opacity: 1;
}
.horizontal-text-gallery .htsg-more:hover::after {
  transform: rotate(0deg);
  top: 3px;
}

/* Black left/right chevron arrows mirroring the template's
   .portfolio-pagination glyphs (FontAwesome \f104 / \f105). Built from
   CSS borders on rotated pseudo-elements so no font dependency. */
.horizontal-text-gallery .htsg-button {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  z-index: 5;
  cursor: pointer;
  background: transparent;
  border: 0;
  padding: 0;
  transition: opacity .3s ease;
}
.horizontal-text-gallery .htsg-button::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 14px;
  height: 14px;
  border-top: 3px solid #000;
  border-right: 3px solid #000;
}
.horizontal-text-gallery .htsg-prev          { left: 25px; }
.horizontal-text-gallery .htsg-prev::before  { transform: translate(-30%, -50%) rotate(-135deg); }
.horizontal-text-gallery .htsg-next          { right: 25px; }
.horizontal-text-gallery .htsg-next::before  { transform: translate(-70%, -50%) rotate(45deg); }
.horizontal-text-gallery .htsg-button:hover  { opacity: .6; }

@media (max-width: 991px) {
  .horizontal-text-gallery .htsg-outer { padding: 0 50px; }
  .horizontal-text-gallery .htsg-slide { flex-direction: column; }
  .horizontal-text-gallery .htsg-text {
    width: 100%;
    height: auto;
    padding: 24px 30px;
  }
  .horizontal-text-gallery .htsg-image {
    width: 100%;
    flex: 1 1 auto;
    min-height: 240px;
  }
  .horizontal-text-gallery .htsg-title { font-size: 28px; line-height: 32px; letter-spacing: 4px; margin-bottom: 18px; }
  .horizontal-text-gallery .htsg-prev  { left: 10px; }
  .horizontal-text-gallery .htsg-next  { right: 10px; }
  .horizontal-text-gallery .htsg-button { width: 36px; height: 36px; }
}

/* ── Full Screen Horizontal Gallery ──
   Derived from the Whizz "slider-transition" demo. Each slide is a
   full-viewport cover image with optional white text overlay (subtitle /
   title / description / "See more" link). White chevron arrows at the
   bottom-left of the viewport. Slides advance horizontally. */
.full-screen-horizontal-gallery {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  background: #000;
}
.full-screen-horizontal-gallery .fsh-viewport {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
}
.full-screen-horizontal-gallery .fsh-track {
  position: absolute;
  inset: 0;
  display: flex;
  transition: transform 1s cubic-bezier(.4, 0, .2, 1);
  will-change: transform;
}
.full-screen-horizontal-gallery .fsh-slide {
  position: relative;
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
/* Subtle dim overlay so white text stays readable on bright photos. */
.full-screen-horizontal-gallery .fsh-slide::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .15);
  pointer-events: none;
}
.full-screen-horizontal-gallery .fsh-text {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0 60px;
  text-align: center;
  color: #fff;
  z-index: 2;
}
.full-screen-horizontal-gallery .fsh-subtitle {
  font-family: Georgia, serif;
  font-size: 18px;
  font-style: italic;
  margin-bottom: 18px;
  letter-spacing: 2px;
}
.full-screen-horizontal-gallery .fsh-title {
  font-family: inherit;
  font-size: 70px;
  font-weight: 800;
  line-height: 76px;
  letter-spacing: 8px;
  margin: 0 0 25px;
  text-transform: uppercase;
  color: #fff;
}
.full-screen-horizontal-gallery.fsh-titles-regular .fsh-title { font-weight: 400; }
.full-screen-horizontal-gallery .fsh-desc {
  font-family: Georgia, serif;
  font-size: 16px;
  line-height: 24px;
  margin: 0 0 30px;
  max-width: 600px;
  letter-spacing: .6px;
}
.full-screen-horizontal-gallery .fsh-more {
  display: inline-block;
  position: relative;
  color: #fff;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 5px;
  text-transform: uppercase;
  padding-bottom: 7px;
  text-decoration: none;
  border-bottom: 1px solid #fff;
  transition: all 250ms ease;
}
.full-screen-horizontal-gallery .fsh-more::after {
  content: "";
  position: absolute;
  right: -3px;
  top: 7px;
  border-left: 4px solid #fff;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transform: rotate(-45deg);
  transition: all 100ms ease;
}
.full-screen-horizontal-gallery .fsh-more:hover { border-bottom-color: transparent; }
.full-screen-horizontal-gallery .fsh-more:hover::after { transform: rotate(0deg); top: 3px; }

/* White chevron arrows at the bottom-left of the viewport, matching the
   source template's positioning (.banner-slider .arrows). */
.full-screen-horizontal-gallery .fsh-arrows {
  position: absolute;
  bottom: 50px;
  left: 100px;
  z-index: 5;
  display: flex;
  gap: 14px;
}
.full-screen-horizontal-gallery .fsh-button {
  position: relative;
  width: 28px;
  height: 28px;
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: transform .4s cubic-bezier(.25, .46, .45, .94);
}
.full-screen-horizontal-gallery .fsh-button::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 12px;
  height: 12px;
  border-top: 2px solid #fff;
  border-left: 2px solid #fff;
}
.full-screen-horizontal-gallery .fsh-prev::before { transform: translate(-30%, -50%) rotate(-45deg); }
.full-screen-horizontal-gallery .fsh-next::before { transform: translate(-70%, -50%) rotate(135deg); }
.full-screen-horizontal-gallery .fsh-prev:hover    { transform: translate3d(-5px, 0, 0); }
.full-screen-horizontal-gallery .fsh-next:hover    { transform: translate3d(5px, 0, 0); }

@media (max-width: 640px) {
  .full-screen-horizontal-gallery .fsh-text { padding: 0 30px; }
  .full-screen-horizontal-gallery .fsh-title { font-size: 36px; line-height: 40px; letter-spacing: 5px; margin-bottom: 18px; }
  .full-screen-horizontal-gallery .fsh-subtitle { font-size: 14px; margin-bottom: 14px; }
  .full-screen-horizontal-gallery .fsh-desc { font-size: 14px; }
  .full-screen-horizontal-gallery .fsh-arrows { bottom: 30px; left: 50%; transform: translateX(-50%); }
  .full-screen-horizontal-gallery .fsh-prev:hover { transform: none; }
  .full-screen-horizontal-gallery .fsh-next:hover { transform: none; }
}

/* ── Arrow Horizontal Slider Gallery (Full Width Arrow Horizontal Slider) ──
   Derived from the Whizz "albums-slider-info" demo: a full-bleed
   single-image fader with large outward-pointing arrows on the left/
   right edges and an optional centred title near the bottom. Slides
   cross-fade with opacity; the arrows are pure CSS (bar + chevron via
   pseudo-elements) so we don't pull in FontAwesome. Per-slide info
   popups float above the slider when the user taps the "i" icon. */
.arrow-horizontal-gallery {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  background: #000;
  overflow: hidden;
}
.arrow-horizontal-gallery .ahs-heading {
  position: absolute;
  top: 24px;
  left: 50%;
  transform: translateX(-50%);
  color: #fff;
  font-size: 24px;
  margin: 0;
  padding: 0 16px;
  text-align: center;
  z-index: 3;
  text-shadow: 0 2px 8px rgba(0,0,0,.5);
}
.arrow-horizontal-gallery .ahs-section-desc {
  position: absolute;
  top: 60px;
  left: 50%;
  transform: translateX(-50%);
  color: #fff;
  margin: 0;
  padding: 0 16px;
  text-align: center;
  z-index: 3;
  font-size: 14px;
  opacity: .85;
  text-shadow: 0 2px 6px rgba(0,0,0,.5);
}
.arrow-horizontal-gallery .ahs-outer {
  position: relative;
  width: 100%;
  height: 100vh;
  min-height: 480px;
}
.arrow-horizontal-gallery .ahs-viewport {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
/* Slides stack on top of each other and cross-fade; only the .active
   slide is visible. background-size:cover so the image fills the
   viewport without letterboxing. Each slide has a subtle dark overlay
   matching the Whizz template's slider_simple variant so the title
   text stays legible against varied photos. */
.arrow-horizontal-gallery .ahs-track {
  position: absolute;
  inset: 0;
}
.arrow-horizontal-gallery .ahs-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity .7s ease;
  will-change: opacity;
  pointer-events: none;
}
.arrow-horizontal-gallery .ahs-slide.active {
  opacity: 1;
  pointer-events: auto;
}
.arrow-horizontal-gallery .ahs-slide-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  display: block;
  text-decoration: none;
}
.arrow-horizontal-gallery .ahs-slide-bg::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .1);
  pointer-events: none;
}
/* Content stacks at the bottom-centre of the slide: title (h5) + optional
   info-icon and "see more" link. White text over the slight dark overlay
   reads cleanly against most photos. */
.arrow-horizontal-gallery .ahs-content {
  position: absolute;
  left: 50%;
  bottom: 9%;
  transform: translateX(-50%);
  text-align: center;
  z-index: 2;
  pointer-events: none;
  padding: 0 16px;
  max-width: min(90%, 800px);
}
.arrow-horizontal-gallery .ahs-content > * { pointer-events: auto; }
.arrow-horizontal-gallery .ahs-title {
  font-size: 56px;
  font-weight: 800;
  font-family: inherit;
  color: #fff;
  text-align: center;
  line-height: 1.2;
  letter-spacing: 4px;
  text-transform: uppercase;
  margin: 0;
  display: inline-block;
  text-shadow: 0 2px 12px rgba(0,0,0,.45);
}
.arrow-horizontal-gallery.ahs-titles-regular .ahs-title { font-weight: 400; letter-spacing: 2px; }
.arrow-horizontal-gallery .ahs-info-wrap {
  display: inline-block;
  margin-left: 14px;
  vertical-align: middle;
}
.arrow-horizontal-gallery .ahs-info {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 45px;
  height: 45px;
  color: #fff;
  font-size: 14px;
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-weight: 700;
  border: 2px solid #fff;
  background: rgba(255, 255, 255, .15);
  cursor: pointer;
  transition: background 250ms ease, color 250ms ease;
  padding: 0;
  line-height: 1;
}
.arrow-horizontal-gallery .ahs-info:hover {
  background: rgba(255, 255, 255, .4);
}
.arrow-horizontal-gallery .ahs-more {
  display: inline-block;
  margin-top: 16px;
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 5px;
  text-transform: uppercase;
  text-decoration: none;
  padding-bottom: 6px;
  border-bottom: 1px solid #fff;
  transition: opacity 200ms ease;
}
.arrow-horizontal-gallery .ahs-more:hover { opacity: .8; }
/* Outer arrows: bar + chevron, pure CSS. Hover nudges them outward
   (matches the Whizz template's left:35px <- left:45px hover shift). */
.arrow-horizontal-gallery .ahs-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  background: transparent;
  border: 0;
  cursor: pointer;
  z-index: 4;
  padding: 0;
  transition: left 0.3s ease, right 0.3s ease, opacity 0.3s ease;
}
.arrow-horizontal-gallery .ahs-arrow::after {
  content: "";
  position: absolute;
  height: 4px;
  width: 30px;
  background: #fff;
  top: 50%;
  transform: translateY(-50%);
  box-shadow: 0 1px 6px rgba(0, 0, 0, .35);
}
.arrow-horizontal-gallery .ahs-arrow::before {
  content: "";
  position: absolute;
  top: 50%;
  width: 16px;
  height: 16px;
  border-top: 4px solid #fff;
  border-right: 4px solid #fff;
  filter: drop-shadow(0 1px 4px rgba(0, 0, 0, .35));
}
.arrow-horizontal-gallery .ahs-prev { left: 45px; }
.arrow-horizontal-gallery .ahs-prev:hover { left: 35px; }
.arrow-horizontal-gallery .ahs-prev::after { left: 0; }
.arrow-horizontal-gallery .ahs-prev::before {
  left: 5px;
  transform: translateY(-50%) rotate(-135deg);
}
.arrow-horizontal-gallery .ahs-next { right: 45px; }
.arrow-horizontal-gallery .ahs-next:hover { right: 35px; }
.arrow-horizontal-gallery .ahs-next::after { right: 0; }
.arrow-horizontal-gallery .ahs-next::before {
  right: 5px;
  transform: translateY(-50%) rotate(45deg);
}
/* Per-slide info popup: site.js opens this when the "i" button is
   tapped. Centred over the slider with a dim backdrop. */
.arrow-horizontal-gallery .ahs-popup {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .75);
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.arrow-horizontal-gallery .ahs-popup[hidden] { display: none; }
.arrow-horizontal-gallery .ahs-popup-inner {
  position: relative;
  background: #fff;
  color: #1b1b1b;
  max-width: 520px;
  width: 100%;
  padding: 36px 32px 30px;
  border-radius: 4px;
  text-align: left;
  line-height: 1.55;
}
.arrow-horizontal-gallery .ahs-popup-close {
  position: absolute;
  top: 8px;
  right: 10px;
  background: transparent;
  border: 0;
  font-size: 28px;
  line-height: 1;
  color: #1b1b1b;
  cursor: pointer;
  padding: 4px 8px;
}
.arrow-horizontal-gallery .ahs-popup-subtitle {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 16px;
  color: #444;
  margin-bottom: 10px;
}
.arrow-horizontal-gallery .ahs-popup-desc {
  font-size: 15px;
  color: #222;
}

@media (max-width: 600px) {
  .arrow-horizontal-gallery .ahs-outer { height: 80vh; }
  .arrow-horizontal-gallery .ahs-heading { font-size: 18px; top: 14px; }
  .arrow-horizontal-gallery .ahs-section-desc { top: 42px; font-size: 12px; }
  .arrow-horizontal-gallery .ahs-title { font-size: 28px; letter-spacing: 2px; }
  .arrow-horizontal-gallery .ahs-info { width: 36px; height: 36px; }
  .arrow-horizontal-gallery .ahs-arrow { width: 32px; height: 32px; }
  .arrow-horizontal-gallery .ahs-prev { left: 14px; }
  .arrow-horizontal-gallery .ahs-prev:hover { left: 10px; }
  .arrow-horizontal-gallery .ahs-next { right: 14px; }
  .arrow-horizontal-gallery .ahs-next:hover { right: 10px; }
  .arrow-horizontal-gallery .ahs-arrow::after { width: 22px; height: 3px; }
  .arrow-horizontal-gallery .ahs-arrow::before { width: 12px; height: 12px; border-top-width: 3px; border-right-width: 3px; }
}

/* lightGallery's bundled stylesheet hardcodes the fullscreen-popup
   caption (data-sub-html) to font-weight:700. The bold reads heavy
   against the photo + dark backdrop - drop it back to a normal weight
   so the caption looks like a label, not a headline. The lightgallery
   bundle is loaded AFTER site.css in HEAD_STYLES so we need !important
   to win the cascade. */
.lg-sub-html h4 { font-weight: 400 !important; }

/* ── Album Style Two ──
   Derived from the Whizz "albums-style-two" demo: a responsive grid
   of prominent image tiles, each with a centred title overlay. Used
   for album-hub galleries that link out to individual gallery pages.
   Stays inside the page wrap (no full-bleed) so it can drop into any
   page width without overflowing. Hover zoom + overlay dim mirror the
   template's interaction. */
.album-style-two-gallery {
  width: 100%;
  margin: 24px 0;
}
.album-style-two-gallery .ast2-heading {
  text-align: center;
  margin: 0 0 8px;
}
.album-style-two-gallery .ast2-desc {
  text-align: center;
  color: var(--muted, #666);
  margin: 0 0 20px;
}
.album-style-two-gallery .ast2-grid {
  display: grid;
  gap: 16px;
}
.album-style-two-gallery.ast2-cols-1 .ast2-grid { grid-template-columns: 1fr; }
.album-style-two-gallery.ast2-cols-2 .ast2-grid { grid-template-columns: repeat(2, 1fr); }
.album-style-two-gallery.ast2-cols-3 .ast2-grid { grid-template-columns: repeat(3, 1fr); }
.album-style-two-gallery.ast2-cols-4 .ast2-grid { grid-template-columns: repeat(4, 1fr); }
.album-style-two-gallery.ast2-cols-auto .ast2-grid {
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.album-style-two-gallery .ast2-item {
  position: relative;
  display: block;
  overflow: hidden;
  background: #111;
  aspect-ratio: 4 / 3;
  text-decoration: none;
}
.album-style-two-gallery .ast2-img {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
.album-style-two-gallery .ast2-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 700ms ease, opacity 350ms ease;
}
.album-style-two-gallery .ast2-item:hover .ast2-img img {
  transform: scale(1.06);
}
.album-style-two-gallery .ast2-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .25);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  transition: background 250ms ease;
}
.album-style-two-gallery .ast2-item:hover .ast2-overlay {
  background: rgba(0, 0, 0, .45);
}
.album-style-two-gallery .ast2-title {
  color: #fff;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: 3px;
  line-height: 1.2;
  text-align: center;
  text-transform: uppercase;
  margin: 0;
  text-shadow: 0 2px 12px rgba(0, 0, 0, .45);
}

@media (max-width: 900px) {
  .album-style-two-gallery.ast2-cols-3 .ast2-grid,
  .album-style-two-gallery.ast2-cols-4 .ast2-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 540px) {
  .album-style-two-gallery .ast2-grid { grid-template-columns: 1fr !important; gap: 12px; }
  .album-style-two-gallery .ast2-title { font-size: 20px; letter-spacing: 2px; }
}
