/* ==========================================================================
   Inner pages — gallery, contact, FRP products.
   Depends on the sector-page primitives (.shero, .crumbs, .label--light,
   .vlist, .body-p), so it is loaded together with sectors.css.
   ========================================================================== */

/* ---------------- compact page hero ---------------- */
/* Shorter than the sector hero: these pages lead with content, so the
   photograph is a band rather than a full screen. */
.shero--sm { min-height: 62svh; }
.shero--sm h1 { font-size: clamp(2rem, 1.2rem + 3.4vw, 4.2rem); max-width: 18ch; }
.shero--sm .hero-row { border-top: 0; padding-top: 0; margin-top: .4rem; }
.shero--sm .hero-row p { max-width: 64ch; }

@media (max-width: 900px) { .shero--sm { min-height: 58svh; } }

/* ==========================================================================
   GALLERY
   ========================================================================== */
.gfilters {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-bottom: clamp(1.8rem, 3vw, 2.8rem);
}
.gfilter {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  padding: .7rem 1.15rem;
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--fg-muted);
  box-shadow: inset 0 0 0 1px var(--bone-3);
  transition: color .28s, background .28s, box-shadow .28s;
}
.gfilter:hover { color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.gfilter.is-on { background: var(--ink); color: var(--bone); box-shadow: none; }

.gcount {
  font-family: 'Editorial', Georgia, serif;
  font-style: italic;
  font-size: .82rem;
  letter-spacing: 0;
  text-transform: none;
  opacity: .6;
}

/* Pinterest-style masonry.
   CSS columns rather than JS positioning: the layout is right on first paint,
   survives script being disabled, and reflows on its own when the filter hides
   tiles. Each image keeps its natural proportions, which is what makes the
   columns stagger. */
.ggrid {
  column-count: 4;
  column-gap: clamp(.5rem, .9vw, .9rem);
}

/* .gtile also carries .mtile, which supplies the zoom cursor, hover scale and
   the lightbox binding. The square aspect-ratio and absolute fill it inherits
   from the homepage mosaic have to be undone here — masonry needs the tile to
   take its height from the image. */
.gtile {
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  display: block;
  width: 100%;
  aspect-ratio: auto;
  margin-bottom: clamp(.5rem, .9vw, .9rem);
  background: var(--bone-2);
}
.gtile img { width: 100%; height: auto; }
.gtile[hidden] { display: none; }

/* a quiet caption band, revealed on hover, so a tile still reads as a project */
.gtile::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 45%;
  background: linear-gradient(transparent, rgba(7, 11, 9, .55));
  opacity: 0;
  transition: opacity .4s var(--ease);
  pointer-events: none;
}
.gtile:hover::after { opacity: 1; }

@media (max-width: 1200px) { .ggrid { column-count: 3; } }
@media (max-width: 760px)  { .ggrid { column-count: 2; } }
@media (max-width: 420px)  { .ggrid { column-count: 1; } }

.gempty {
  margin-top: 2.5rem;
  color: var(--fg-muted);
  font-size: .98rem;
}

/* ==========================================================================
   CONTACT
   ========================================================================== */
.cwrap {
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: clamp(2.5rem, 5vw, 6rem);
  align-items: start;
}
@media (max-width: 900px) { .cwrap { grid-template-columns: 1fr; } }

.cform { display: grid; gap: 1.2rem; justify-items: start; }
.cform h2 { margin-bottom: .4rem; }
.cform form { display: grid; gap: 1.1rem; width: 100%; }
/* the form is a grid, so the button would otherwise stretch the full width */
.cform form > .btn { justify-self: start; }

.frow { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; }
@media (max-width: 560px) { .frow { grid-template-columns: 1fr; } }

.field { display: grid; gap: .45rem; }
.field > span {
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.field input, .field select, .field textarea {
  width: 100%;
  padding: .95rem 1.05rem;
  font-size: 1rem;
  color: var(--ink);
  background: var(--bone-2);
  border: 1px solid transparent;
  border-radius: 2px;
  transition: border-color .25s, background .25s;
}
.field textarea { resize: vertical; min-height: 8rem; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  background: var(--bone);
  border-color: var(--ink);
}
.field [aria-invalid="true"] { border-color: var(--clay-2); background: #FBEDE7; }
.field em {
  font-style: normal;
  font-size: .84rem;
  color: var(--clay-2);
}

/* the honeypot must be reachable to a bot parsing the HTML but invisible and
   unfocusable for anyone actually using the page — so it is moved off-screen
   rather than display:none */
.trap {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

.note {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .8rem;
  align-items: start;
  width: 100%;
  padding: 1.05rem 1.2rem;
  font-size: .97rem;
  line-height: 1.6;
  border-left: 3px solid;
}
.note .icn { margin-top: .28rem; }
.note--ok   { background: #E6EFE8; border-color: #2F6B45; color: #1F4A2F; }
.note--info { background: var(--bone-2); border-color: var(--clay); color: var(--ink); }
.note--bad  { background: #FBEDE7; border-color: var(--clay-2); color: #7A2E15; }
.note a { text-decoration: underline; }

.cinfo { display: grid; gap: 1.6rem; justify-items: start; }

.cdetails { display: grid; gap: 1.4rem; width: 100%; }
.cdetails li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1rem;
  align-items: start;
  padding-bottom: 1.4rem;
  border-bottom: 1px solid var(--bone-3);
}
.cdetails li:last-child { border-bottom: 0; padding-bottom: 0; }
.cdetails .icn { color: var(--clay); margin-top: .3rem; width: 1.3rem; height: 1.3rem; }
.cdetails b {
  display: block;
  font-family: 'Bricolage', sans-serif;
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: -.01em;
  margin-bottom: .25rem;
}
.cdetails span { color: var(--fg-muted); font-size: .98rem; line-height: 1.6; }
.cdetails a:hover { color: var(--clay-2); }

.cmap-wrap { padding-bottom: 0; }
.cmap {
  position: relative;
  margin-top: clamp(1.5rem, 3vw, 2.5rem);
  min-height: clamp(320px, 44vh, 520px);
}
.cmap iframe {
  display: block;
  position: relative;          /* paints over the fallback when it loads */
  width: 100%;
  height: clamp(320px, 44vh, 520px);
  border: 0;
  filter: grayscale(1) contrast(1.05);
  transition: filter .5s;
}
.cmap:hover iframe { filter: none; }

/* Sits underneath the iframe and is only seen if the embed never paints. */
.cmap-fallback {
  position: absolute;
  inset: 0;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: .8rem;
  padding: 2rem;
  text-align: center;
  background: var(--bone-2);
  border: 1px solid var(--bone-3);
  color: var(--fg-muted);
}
.cmap-fallback .icn { width: 1.8rem; height: 1.8rem; color: var(--clay); }
.cmap-fallback b { display: block; color: var(--ink); font-size: 1.05rem; margin-bottom: .3rem; }

/* ==========================================================================
   FRP PRODUCTS
   ========================================================================== */
.prose-wrap {
  display: grid;
  grid-template-columns: 1fr 1.25fr;
  gap: clamp(2rem, 5vw, 6rem);
  align-items: start;
}
.prose-head { display: grid; gap: 1.2rem; position: sticky; top: 3rem; }
.prose { display: grid; gap: 1.3rem; }
.prose p { color: var(--fg-muted); line-height: 1.75; max-width: 66ch; }
.prose .lede { color: var(--fg); max-width: 66ch; }

@media (max-width: 900px) {
  .prose-wrap { grid-template-columns: 1fr; }
  .prose-head { position: static; }
}

.fgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: clamp(.5rem, .9vw, .9rem);
  margin-top: clamp(1.8rem, 3vw, 2.6rem);
}
/* These are catalogue shots of whole products, so nothing may be cropped — a
   statue or a planter loses its meaning the moment its sides are cut off. The
   first version dropped aspect-ratio entirely and let each tile take its own
   height, but the set mixes 1.85:1 garden scenes with 1.2:1 product renders, so
   grid stretched the short ones and left a beige band under every wide tile.
   A fixed box with object-fit: contain keeps the grid even and still shows each
   product whole; the bone ground is the same colour the cut-outs sit on. */
.ftile {
  aspect-ratio: 4 / 3;
  background: var(--bone-2);
  display: grid;
  place-items: center;
  padding: clamp(.4rem, .8vw, .8rem);
}
.ftile img { width: 100%; height: 100%; object-fit: contain; }

.assist {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  gap: clamp(2rem, 4vw, 4rem);
  align-items: center;
  padding: clamp(2rem, 4vw, 3.5rem);
  background: var(--bone-2);
}
.assist > div { display: grid; gap: 1.1rem; }
.assist-list { display: grid; gap: 1.1rem; }
.assist-list li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .9rem;
  align-items: center;
  font-size: 1.02rem;
}
.assist-list .icn { color: var(--clay); width: 1.25rem; height: 1.25rem; }
.assist-list a:hover { color: var(--clay-2); }

@media (max-width: 900px) { .assist { grid-template-columns: 1fr; } }

/* ==========================================================================
   PRODUCT CATEGORY PAGES
   ========================================================================== */
/* The sub-product tiles are catalogue cut-outs and on-site photos mixed
   together, so the tile fixes the frame and lets object-fit do the cropping —
   a cut-out on white and a wide banner then read as the same component. */
.pgrid {
  display: grid;
  /* Capped at four. auto-fill put five across on a 1440 laptop, which strands
     the last three of an eight-tile range in a half-empty second row; four
     columns tile 8 into two full rows and 4 into one. */
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: clamp(.6rem, 1vw, 1rem);
  margin-top: clamp(1.8rem, 3vw, 2.6rem);
}
@media (min-width: 1000px) {
  .pgrid { grid-template-columns: repeat(4, 1fr); }
}
.ptile {
  position: relative;
  display: grid;
  gap: 0;
  background: var(--bone-2);
  overflow: hidden;
  scroll-margin-top: 6rem;          /* the mega-menu links here by anchor */
}
.ptile img {
  width: 100%;
  aspect-ratio: 4/3;
  object-fit: cover;
  transition: transform .6s var(--ease);
}
.ptile:hover img { transform: scale(1.05); }
.ptile figcaption {
  padding: .95rem 1.1rem;
  font-family: 'Bricolage', sans-serif;
  font-size: .98rem;
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--ink);
}

/* ---------------- long-form legal / blog prose ---------------- */
.legal { max-width: 74ch; display: grid; gap: 1.4rem; }
.legal h2 {
  margin-top: clamp(1.6rem, 3vw, 2.6rem);
  font-size: clamp(1.35rem, 1rem + 1.1vw, 1.9rem);
}
.legal h2:first-child { margin-top: 0; }
.legal p, .legal li { color: var(--fg-muted); line-height: 1.78; }
.legal ul { display: grid; gap: .7rem; padding-left: 1.2rem; list-style: disc; }
.legal a { color: var(--clay-2); text-decoration: underline; }
.legal .updated {
  font-size: .82rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

/* ---------------- blog index ---------------- */
.bgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: clamp(1.4rem, 2.5vw, 2.4rem);
}
.bcard { display: grid; gap: 1rem; align-content: start; }
.bcard-img { overflow: hidden; background: var(--bone-2); }
.bcard-img img {
  width: 100%;
  aspect-ratio: 3/2;
  object-fit: cover;
  transition: transform .6s var(--ease);
}
.bcard:hover .bcard-img img { transform: scale(1.05); }
.bcard time {
  font-size: .74rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.bcard h3 { font-size: 1.22rem; line-height: 1.22; }
.bcard p { color: var(--fg-muted); line-height: 1.66; font-size: .98rem; }

/* ==========================================================================
   SPLIT HERO
   Type on a solid ground beside two image panels, used where the available
   photography cannot fill a full-bleed hero sharply. Sized so each panel lands
   near 650x255 CSS — a 1104x450 source covers that at 2x, which a full-width
   hero would need 2700px to do.
   ========================================================================== */
.shero-split {
  padding-block: clamp(6.5rem, 5rem + 6vw, 10rem) clamp(3.5rem, 2rem + 5vw, 6rem);
}
.shero-split-in {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  gap: clamp(2rem, 4vw, 5rem);
  align-items: center;
}
.shero-split-txt { display: grid; gap: clamp(.9rem, 1.6vw, 1.4rem); align-content: center; }
.shero-split-txt h1 {
  font-size: clamp(2rem, 1.2rem + 3vw, 3.9rem);
  max-width: 18ch;
  color: var(--bone);
}
.shero-split-txt .lede { max-width: 52ch; color: rgba(243, 240, 231, .82); }
.shero-split-txt .cta-actions { margin-top: .5rem; }
.shero-split-txt .btn--line { color: var(--bone); border-color: rgba(243, 240, 231, .34); }

.shero-split-meta {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem 1.6rem;
  margin-top: clamp(.6rem, 1.5vw, 1.4rem);
  padding-top: clamp(1rem, 2vw, 1.6rem);
  border-top: 1px solid rgba(243, 240, 231, .16);
  font-size: .74rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: rgba(243, 240, 231, .58);
}

.shero-split-media { display: grid; gap: clamp(.7rem, 1.4vw, 1.1rem); }
.shero-split-media figure { margin: 0; overflow: hidden; }
.shero-split-media img {
  display: block;
  width: 100%;
  aspect-ratio: 2.55 / 1;
  object-fit: cover;
  transition: transform 1s var(--ease2);
}
.shero-split-media figure:hover img { transform: scale(1.04); }

.shero-split .crumbs a { color: rgba(243, 240, 231, .72); }
.shero-split .crumbs a:hover { color: var(--bone); }

@media (max-width: 900px) {
  .shero-split { padding-block: clamp(5.5rem, 4rem + 6vw, 8rem) 3rem; }
  .shero-split-in { grid-template-columns: 1fr; gap: 2.2rem; }
  /* Two stacked panels under the headline would push the page a long way down
     on a phone, so they sit side by side there instead. */
  .shero-split-media { grid-template-columns: 1fr 1fr; }
  .shero-split-media img { aspect-ratio: 4 / 3; }
}
@media (max-width: 520px) {
  .shero-split-media { grid-template-columns: 1fr; }
  .shero-split-media img { aspect-ratio: 2.55 / 1; }
}

/* CTA with no background photograph — same block, same type, nothing to be
   soft. Used on the two pages whose imagery cannot fill the band. */
.cta--flat { min-height: 0; padding-block: clamp(4rem, 3rem + 5vw, 7.5rem); }
.cta--flat::after { display: none; }

/* A split panel holding a catalogue cut-out rather than a photograph. Cover
   would crop straight through the product — and on a white sweep the crop reads
   as a broken image — so it is contained on the bone ground instead. */
.split-img--fit { background: var(--bone-2); }
.split-img--fit img {
  object-fit: contain;
  padding: clamp(1.5rem, 4vw, 4rem);
}

/* A feature panel split into two stacked images. Used where the tallest clean
   source is shorter than the panel: halving the height each image has to cover
   is worth more than any crop of a single one. */
.split-img--stack {
  display: grid;
  grid-template-rows: 1fr 1fr;
  gap: clamp(.4rem, .8vw, .8rem);
}
.split-img--stack figure { position: relative; margin: 0; overflow: hidden; }
.split-img--stack img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
