/* ==========================================================================
   GRID Spatial — site layer
   Loaded AFTER assets/css/theme.css (the base theme stylesheet).
   This file only adds: scroll-reveal states, the two carousels, the
   Instagram grid (filled from the Behold feed by clone.js), the GRID logo
   sizing, and small corrective rules. All base layout, typography and colour
   come from theme.css, unchanged.
   ========================================================================== */

/* --- scroll reveal: mirrors the site's GSAP fromTo(opacity 0→1, y 40→0) --- */
html.js .animate-up { opacity: 0; transform: translateY(40px); }
html.js .animate-up.is-in {
  opacity: 1;
  transform: translateY(0);
  transition: opacity .7s cubic-bezier(.25, .46, .45, .94),
              transform .7s cubic-bezier(.25, .46, .45, .94);
}

/* --- lazy image fade (theme's .js-lazyanim-image + .fadein) --- */
html.js .js-lazyanim-image img { opacity: 0; transition: opacity .6s ease; }
html.js .js-lazyanim-image.fadein img { opacity: 1; }

/* --- the served theme relies on a centring translate that isn't in the
       stylesheet; without it the about images sit half off their crop box --- */
.textimg-block__image img {
  transform: translate(-50%, -50%);
  object-fit: cover;
  height: 100%;
}

/* ==========================================================================
   Carousels — logo strip + project row
   The original used slick (float/width injected at runtime). These replace it
   with a flex track that keeps the same stepping behaviour and timing.
   ========================================================================== */
.carousel { position: relative; width: 100%; overflow: hidden; }
.carousel__track {
  display: flex;
  flex-wrap: nowrap;
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
  will-change: transform;
  transition: transform .6s cubic-bezier(.67, 0, .285, 1);
}
.carousel__track.is-resetting { transition: none; }
.carousel__slide { flex: 0 0 auto; box-sizing: border-box; min-width: 0; }

/* logo strip: theme sets .logos__cell width:16.666% for a 6-up grid — let the
   carousel drive width, and keep the logos vertically centred in their track */
.logo-slider .logos__cell { width: auto; }
.logo-slider .carousel__track { align-items: center; }
.logo-slider .logos__cell img { max-width: 240px; }

/* project row: .col-03 is a flex cell in the theme; give it the slide width */
.portfolio-slider .carousel__track { align-items: stretch; }
.portfolio-slider .col-03 { width: auto; }
.portfolio-slider .carousel__slide { display: flex; }

/* ==========================================================================
   Instagram — @gridspatial posts rendered by clone.js from the Behold feed.
   Grid layout, 4 columns desktop / 2 phone, 8 posts, dark hover veil.
   ========================================================================== */
/* no feed yet (or it failed): show the intro as a full-width "Follow Us" band */
.social:not(.has-feed) .social__column--wrapper { display: none; }
.social:not(.has-feed) .social__column--intro {
  width: 100%;
  margin-right: 0;
  align-items: center;
  text-align: center;
}
.ig-grid {
  display: grid;
  /* minmax(0,1fr) keeps the image intrinsic width from forcing the flex row to wrap */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  width: 100%;
  min-width: 0;
}
/* basis 0 so the grid shares the row with the intro instead of wrapping under it */
.social__column--wrapper { flex: 1 1 0; min-width: 0; }
.ig-grid__item {
  position: relative;
  display: block;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: #f2efe9;
}
.ig-grid__item img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .6s cubic-bezier(.67, 0, .285, 1);
}
.ig-grid__item::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0);
  transition: background .3s ease;
}
.ig-grid__item:hover img { transform: scale(1.05); }
.ig-grid__item:hover::after { background: rgba(0, 0, 0, .45); }
.ig-grid__label {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  color: #fff;
  font-size: .6875rem;
  line-height: 1;
  letter-spacing: 2px;
  text-transform: uppercase;
  opacity: 0;
  transition: opacity .3s ease;
}
.ig-grid__item:hover .ig-grid__label,
.ig-grid__item:focus-visible .ig-grid__label { opacity: 1; }
.ig-grid__label .icon { font-size: 1rem; }

/* --- GRID logo: a round mark, so the theme's slots (built for a 40px icon
       and an 880px-wide wordmark) are resized for it --- */
.header__logo { max-width: 64px; }
.footer__column--logo img { max-width: 96px; }
.hero .hero-overlay .hero-txt img.hero__logo {
  display: block;
  width: 100%;
  max-width: 260px;
  margin: 0 auto;
}

/* --- hero: real video frame underneath the live Vimeo embed --- */
.hero .video-wrapper > .hero-poster {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.hero .video-wrapper iframe { z-index: 1; }

/* ==========================================================================
   Interaction states — focus visibility (the theme ships none)
   ========================================================================== */
a:focus-visible,
button:focus-visible,
.carousel__slide:focus-visible,
.ig-grid__item:focus-visible {
  outline: 2px solid #746b5f;
  outline-offset: 3px;
}
.header .navigation__link:focus-visible { outline-offset: 1px; }

/* ==========================================================================
   Responsive adjustments for the cloned pieces
   ========================================================================== */
@media screen and (max-width: 860px) {
  .ig-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .social__column--intro { width: 100%; margin: 0 0 5px; }
  .social__column--wrapper { flex-basis: 100%; }
}
@media screen and (max-width: 480px) {
  .ig-grid { gap: 6px; }
  .hero .hero-overlay .hero-txt img.hero__logo { max-width: 180px; }
}

@media (prefers-reduced-motion: reduce) {
  html.js .animate-up { opacity: 1; transform: none; }
  html.js .js-lazyanim-image img { opacity: 1; }
  .carousel__track { transition: none; }
  .ig-grid__item img { transition: none; }
}

/* ==========================================================================
   Brand colour — deep chocolate #2A1202
   Applied to the footer's contact bar (email / General Enquiries) and to
   every CTA button site-wide. Header navigation is deliberately untouched:
   those are links, not buttons.

   The base is the supplied #2A1202 = oklch(0.214 0.0488 54.4). Hover tones
   are derived from that same hue and chroma so the brand colour stays the
   single source of truth, and each hover moves *away* from its own
   background so contrast never drops in the hover state:
     solid  oklch(0.314 0.0488 54.4)  lightens off #2A1202
     ghost  oklch(0.154 0.0488 54.4)  darkens (it sits on cream)
   The theme's own hover motion (padding shift, rule width) is left intact —
   only the colour values change.
   ========================================================================== */
.footer__bottom { background-color: #2A1202; }

/* ghost CTA — its label and the two flanking rules */
.button { color: #2A1202; }
.button:before,
.button:after { background-color: #2A1202; }
.button:hover { color: oklch(0.154 0.0488 54.4); }
.button:hover:before,
.button:hover:after { background-color: oklch(0.154 0.0488 54.4); }

/* solid CTA — declared after the ghost rule so its white label wins
   (both selectors carry the same specificity) */
.button--solid { background-color: #2A1202; color: #fff; }
.button--solid:hover { background-color: oklch(0.314 0.0488 54.4); color: #fff; }

/* The solid button's inner rules stay white. Without this the ghost
   :before/:after rule above would recolour them to the same chocolate as the
   button itself, and they would disappear. */
.button--solid:before,
.button--solid:after,
.button--solid:hover:before,
.button--solid:hover:after { background-color: #fff; }
