/* Blue Chisel Studio — the virtual gallery.
   All walls are white. Art hangs with space around it. A small museum
   label sits beside each piece. No cards, no shadows fighting for
   attention — just the work. */

:root {
  /* Kate's palette (site-wide):
       text/ink  #34487F   link  #27327C   link hover  #7F8BAA
     All derived tokens sit inside the same blue family. */
  --ink: #34487F;
  --ink-soft: #34487F;
  --muted: #8892a8;
  --rule: #e8e6e2;
  --wall: #ffffff;
  --wall-shadow: 0 0 0 rgba(0,0,0,0);
  --accent: #27327C;
  --link: #27327C;
  --link-hover: #7F8BAA;
  --serif: "Questrial", "Helvetica Neue", Arial, sans-serif;
  --sans: "Ubuntu", "Helvetica Neue", Arial, sans-serif;
  --measure: 34rem;
  --page-max: 88rem;
  --label-width: 16rem;
  /* Kate asked for every image on the site to come down 25% in displayed
     size. Adjust here to scale them all together. */
  --art-scale: 0.75;
  /* Detail-page product image height — kept in lock-step with the gallery's
     --gallery-art-height so a print's footprint matches what's shown on the
     gallery page. Mobile override mirrors the gallery's below 900px. */
  --product-art-height: clamp(22rem, 32vw, 30rem);
  /* Height of the sticky site-header — section headings dock just under it. */
  --nav-height: 4.5rem;
}

*, *::before, *::after { box-sizing: border-box; }

html {
  font-size: 17px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  scroll-padding-top: calc(var(--nav-height, 4.5rem) + 4rem);
}

body {
  margin: 0;
  background: var(--wall);
  color: var(--ink);
  font-family: var(--sans);
  font-weight: 400;
  line-height: 1.55;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

a {
  color: var(--link);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 160ms ease, color 160ms ease;
}
a:hover {
  color: var(--link-hover);
  border-bottom-color: currentColor;
}
/* Structural links (nav, brand, buttons, logo) opt out of the default
   link colour so chrome elements keep their own palette. */
.nav a,
.brand-logo,
.btn-pill,
.filter-btn,
.tag-view {
  color: inherit;
}
.nav a:hover {
  color: var(--ink);
}

/* ---------- Layout shell ---------- */

.site {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 clamp(1.5rem, 4vw, 4rem);
}

.site-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  padding: 2rem 0 1.25rem;
  gap: 2rem;
  flex-wrap: wrap;
  background: var(--wall);
}

.site-header[data-sticky] {
  position: sticky;
  top: 0;
  z-index: 20;
  padding: 1rem 0;
  transition: border-color 200ms ease, box-shadow 200ms ease;
  border-bottom: 1px solid transparent;
}
.site-header[data-sticky].scrolled {
  border-bottom-color: var(--rule);
}
/* While the fullscreen hero dominates the viewport, fade the sticky header
   out — but leave it *in* layout (no position switch) so it doesn't jump
   when the opacity transitions at the boundary. The hero instead uses a
   negative margin-top below to overlap the header's natural space. */
.site-header[data-hero-hide].hero-active {
  opacity: 0;
  pointer-events: none;
}
.site-header[data-hero-hide] {
  transition: opacity 380ms ease, border-color 200ms ease, box-shadow 200ms ease;
}
.site { position: relative; }
.site-header:not([data-sticky]) {
  border-bottom: 1px solid var(--rule);
}

.anchor-section { scroll-margin-top: 5.5rem; }

/* ---------- Brand + nav ---------- */

.brand-logo { display: inline-block; line-height: 0; border: 0; }
.brand-logo:hover { border-bottom-color: transparent; }
.brand-logo img { height: 2.5rem; width: auto; display: block; }
@media (max-width: 900px) { .brand-logo img { height: 2.1rem; } }
@media (max-width: 520px) { .brand-logo img { height: 1.85rem; } }

.nav {
  display: flex;
  align-items: center;
  gap: 1.75rem;
  font-family: var(--sans);
  font-size: 0.72rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.nav a.active { border-bottom-color: var(--ink); }

.nav .nav-gallery {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.95rem;
  background: transparent;
  color: var(--ink);
  border-radius: 0;
  border: 1px solid var(--ink);
  font-size: 0.7rem;
  letter-spacing: 0.28em;
  line-height: 1;
  white-space: nowrap;
  transition: background 180ms ease, color 180ms ease;
}
.nav .nav-gallery:hover { background: var(--ink); color: var(--wall); border-bottom-color: var(--ink); }
.nav .nav-gallery.active { background: transparent; color: var(--ink); }
.nav .nav-gallery svg { flex: 0 0 auto; }

/* ---------- Pill button (all actions look like a small museum tag) ---------- */

.btn-pill {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.7rem 1.15rem;
  background: transparent;
  color: var(--ink);
  border-radius: 0;
  border: 1px solid var(--ink);
  font-family: var(--sans);
  font-size: 0.7rem;
  letter-spacing: 0.28em;
  line-height: 1;
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
  transition: background 180ms ease, color 180ms ease;
}
.btn-pill:hover { background: var(--ink); color: var(--wall); }
.btn-pill svg { flex: 0 0 auto; }
.btn-pill.sold,
.btn-pill[disabled] {
  color: var(--muted);
  border-color: var(--rule);
  cursor: not-allowed;
  font-style: italic;
}
.btn-pill.sold:hover,
.btn-pill[disabled]:hover { background: transparent; color: var(--muted); }

/* ---------- Typography ---------- */

h1, h2, h3, h4 {
  font-family: var(--serif);
  font-weight: 400;
  letter-spacing: 0;
  color: var(--ink);
  margin: 0 0 1rem;
}
h1 { font-size: clamp(2.4rem, 5.5vw, 4.2rem); line-height: 1.05; font-weight: 300; letter-spacing: -0.01em; }
h2 { font-size: clamp(1.7rem, 3.2vw, 2.4rem); line-height: 1.2; font-weight: 300; }
h3 { font-size: 1.25rem; line-height: 1.25; }

.eyebrow {
  display: inline-block;
  font-family: var(--sans);
  font-size: 0.68rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 1.1rem;
}
/* Larger, ink-dark eyebrow for the main section titles on the homepage
   (Kate wanted these big; "Blue Chisel Studio", "On the wall currently",
   "How the prints are made", "Contact"). */
.eyebrow-lg {
  font-size: clamp(1rem, 1.6vw, 1.35rem);
  letter-spacing: 0.24em;
  color: var(--ink);
  font-weight: 500;
}

.lede {
  font-size: 1.15rem;
  line-height: 1.7;
  color: var(--ink-soft);
  max-width: var(--measure);
  font-weight: 300;
}

.prose {
  max-width: var(--measure);
  font-size: 1rem;
  line-height: 1.8;
  color: var(--ink-soft);
}
.prose p + p { margin-top: 1.1rem; }

.rule {
  width: 3rem;
  height: 1px;
  background: var(--ink);
  border: 0;
  margin: 1.75rem 0;
}

/* ---------- Hero: a fullscreen opening wall ---------- */

.hero-full {
  /* Breaks out of .site's max-width so it truly fills the viewport width.
     Negative margin-top pulls the hero up behind the sticky header (which
     is fading in/out via opacity), so the wordmark sits at the very top
     without a layout jump when the header re-appears. */
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
  margin-top: calc(-1 * var(--nav-height));
  width: 100vw;
  min-height: 100vh;
  padding: clamp(1rem, 2vh, 1.75rem) clamp(1.5rem, 4vw, 4rem) 2rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: clamp(0.5rem, 1.25vh, 1rem);
  background: var(--wall);
}
.hero-wordmark {
  font-family: var(--serif);
  font-weight: 300;
  text-align: center;
  margin: 0;
  line-height: 1.1;
  letter-spacing: -0.005em;
  color: var(--ink);
}
.hero-wordmark span {
  display: block;
  font-size: clamp(2rem, 5.4vw, 4.2rem);
  letter-spacing: 0.02em;
}
.hero-wordmark em {
  display: block;
  font-style: italic;
  color: var(--accent);
  font-size: clamp(1.2rem, 3vw, 2.1rem);
  margin-top: 0.25rem;
  letter-spacing: 0.04em;
}
.hero-full-image {
  /* Container sized so the image always fits the viewport under the
     wordmark on desktop. Height leaves room for the wordmark AND a
     breathing-space margin beneath the image. object-fit: contain does
     the rest. */
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: min(calc(100% * var(--art-scale)), calc(1400px * var(--art-scale)));
  height: calc(100vh - 13rem);
  min-height: 0;
  border: 0;
  line-height: 0;
}
.hero-full-image:hover { border-bottom-color: transparent; }
.hero-full-image img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
}

/* ---------- Pinned tagline: scroll-hang animation ---------- */

.tagline-pin {
  /* Section height controls how long "Never reprinted." stays pinned at
     viewport center before the containing block runs out and the line
     un-pins to scroll up with the page. */
  position: relative;
  padding: 0;
  height: 85vh;
}
.tagline-title {
  height: 100%;
  margin: 0;
  padding: 35vh clamp(1.5rem, 4vw, 4rem) 0;
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(1.5rem, 4vw, 3.4rem);
  line-height: 1.15;
  letter-spacing: -0.015em;
  color: var(--ink);
  text-align: center;
}
.tagline-fade {
  display: block;
  white-space: nowrap;
  transition: opacity 140ms linear;
  opacity: 1;
}
@media (max-width: 600px) {
  /* On mobile the prefix can be quite long for the available width — let
     it wrap naturally instead of forcing a single line. */
  .tagline-fade { white-space: normal; }
  /* No scroll-driven fade on mobile — the lines just sit there as the
     page scrolls. Overrides the inline opacity the JS keeps writing. */
  .tagline-fade,
  .tagline-hold { opacity: 1 !important; }
}
.tagline-hold {
  display: block;
  /* Match the prefix: same family, weight, size and ink colour. Element
     is still an <em>, so reset font-style explicitly. */
  font-style: normal;
  color: var(--ink);
  margin-top: 2.6rem;
  transition: opacity 140ms linear;
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  .tagline-pin { height: auto; padding: 4rem 0; }
  .tagline-title { height: auto; padding: 0 clamp(1.5rem, 4vw, 4rem); }
  .tagline-hold { position: static; transform: none; }
}

/* Soft scroll cue beneath the hero */
.scroll-cue {
  display: block;
  text-align: center;
  font-family: var(--sans);
  font-size: 0.95rem;
  letter-spacing: 0.3em;
  color: var(--muted);
  padding: 0.5rem 0 3rem;
  border: 0;
  opacity: 0.6;
  animation: scrollCue 2.4s ease-in-out infinite;
}
.scroll-cue:hover { opacity: 1; border-bottom-color: transparent; }
@keyframes scrollCue {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(6px); }
}

/* ---------- Section spacing ---------- */

section { padding: 2.25rem 0; }

.section-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 0.75rem;
  margin-bottom: 1.5rem;
  flex-wrap: wrap;
  gap: 1rem;
}

/* Featured + Process section headings dock under the top nav as their
   content scrolls past, then release when the section ends. The negative
   top + extra padding-top tucks the bar 2px under the nav so no slice of
   the page underneath peeks through the seam. */
#featured > .section-head,
#process > .section-head,
#about > .section-head,
#contact > .section-head {
  position: sticky;
  top: calc(var(--nav-height) - 2px);
  background: var(--wall);
  z-index: 8;
  padding-top: calc(0.75rem + 2px);
  margin-bottom: 1.25rem;
}
@media (max-width: 900px) {
  :root { --nav-height: 3.7rem; }
}
.section-head.inline { align-items: baseline; }
.section-head.inline .eyebrow { margin-bottom: 0; }
.section-head .link-more {
  font-family: var(--sans);
  font-size: 0.7rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.page-head {
  padding: 2.5rem 0 1.5rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 1.75rem;
  max-width: var(--measure);
}

/* Gallery page entry: larger title, smaller description (Kate's request). */
.gallery-page-head {
  max-width: 70rem;
  text-align: left;
}
.gallery-title {
  font-size: clamp(2.6rem, 5.5vw, 4.6rem);
  line-height: 1.05;
  font-weight: 300;
  font-style: italic;
  margin: 0 0 0.8rem;
  letter-spacing: -0.01em;
}
.gallery-lede {
  font-family: var(--sans);
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--muted);
  max-width: 42rem;
  margin: 0;
  font-weight: 400;
}

/* ---------- Category filter (bottom of the gallery entry) ---------- */

.category-filter {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  justify-content: center;
  border-bottom: 1px solid var(--rule);
  padding: 0 0 1rem;
  margin-bottom: 1.5rem;
}
.filter-btn {
  font-family: var(--sans);
  font-size: 0.68rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  background: transparent;
  border: 1px solid var(--ink);
  border-radius: 0;
  padding: 0.6rem 1.1rem;
  cursor: pointer;
  color: var(--ink);
  line-height: 1;
  transition: color 180ms ease, background 180ms ease;
}
.filter-btn:hover,
.filter-btn.active { color: var(--wall); background: var(--ink); }
.filter-btn .count {
  font-family: var(--serif);
  font-style: italic;
  font-size: 0.78rem;
  letter-spacing: 0;
  color: var(--muted);
  margin-left: 0.4rem;
  text-transform: none;
}
.filter-btn.active .count { color: rgba(255,255,255,0.7); }

/* ---------- The wall: art + museum tag ---------- */

/* The "gallery" is a column of walls. Each wall holds one piece and its tag.
   Tags alternate left/right so the promenade feels like walking down a
   corridor rather than a grid of product cards. */

.walls {
  display: flex;
  flex-direction: column;
  gap: clamp(2rem, 4vw, 3.5rem);
  padding: 0.5rem 0 1rem;
}

.wall {
  display: grid;
  grid-template-columns: 1fr var(--label-width);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
.wall.reverse { grid-template-columns: var(--label-width) 1fr; }
.wall.reverse .wall-art  { order: 2; }
.wall.reverse .wall-tag  { order: 1; text-align: right; }
.wall.reverse .wall-tag .tag-rule { margin-left: auto; }

.wall-art {
  display: block;
  border: 0;
  line-height: 0;
  background: var(--wall);
  overflow: hidden;
  /* Shrink the artwork 25% within its column, centered, so the label
     column stays where it is. */
  max-width: calc(100% * var(--art-scale));
  margin-inline: auto;
}
.wall-art img {
  width: 100%;
  height: auto;
  object-fit: contain;
  background: var(--wall);
}
.wall-art:hover { border-bottom-color: transparent; }

/* Museum label — small, quiet, all the information the visitor wants. */
.wall-tag {
  font-family: var(--sans);
  color: var(--ink);
  padding: 0.5rem 0;
}
.wall-tag .tag-title {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.15rem;
  line-height: 1.25;
  margin: 0 0 0.25rem;
  font-weight: 400;
  color: var(--ink);
}
.wall-tag .tag-title a {
  color: inherit;
  border-bottom: 0;
  text-decoration: underline;
  text-decoration-color: var(--rule);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
}
.wall-tag .tag-title a:hover,
.wall .wall-art:hover ~ .wall-tag .tag-title a {
  color: inherit;
  border-bottom: 0;
  text-decoration-color: currentColor;
}
.wall-tag .tag-rule {
  display: block;
  width: 5rem;
  height: 1px;
  background: var(--ink);
  margin: 0 0 0.6rem;
}
.wall-tag .tag-meta {
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  line-height: 1.75;
  color: var(--ink-soft);
  margin: 0;
}
.wall-tag .tag-meta span { display: block; }
.wall-tag .tag-price {
  font-family: var(--serif);
  font-size: 1rem;
  letter-spacing: 0.02em;
  color: var(--ink);
  margin-top: 0.9rem;
  display: inline-block;
}
.wall-tag .tag-price.sold {
  font-style: italic;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.3em;
  font-size: 0.72rem;
  font-family: var(--sans);
}
.wall-tag .tag-view {
  display: inline-block;
  margin-top: 0.9rem;
  font-family: var(--sans);
  font-size: 0.66rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--ink-soft);
  border-bottom: 1px solid var(--rule);
  padding-bottom: 0.15rem;
}
.wall-tag .tag-view:hover { color: var(--ink); border-bottom-color: var(--ink); }

/* Gallery page + featured walls: photo-first walls showing only the
   title and "View the piece" link. */
.wall-minimal {
  grid-template-columns: 1fr 13rem;
  gap: clamp(0.35rem, 0.7vw, 0.6rem);
}
.wall-minimal.reverse {
  grid-template-columns: 13rem 1fr;
}
.wall-minimal .wall-tag {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  justify-content: center;
  padding: 0;
}
.wall-minimal .wall-tag .tag-title {
  font-size: 1.35rem;
  margin: 0;
  white-space: nowrap;
}
.wall-minimal .wall-tag .tag-view { margin-top: 0; }

/* Gallery page specifically: every image renders at the same height,
   centred in its column, regardless of aspect ratio. Titles continue
   to alternate left/right via the `.reverse` class. */
#gallery-rooms {
  --gallery-art-height: clamp(22rem, 32vw, 30rem);
}
/* Gallery page: same centre-gutter alignment as the homepage featured
   walls — each wall is a strict 50/50 split around a 100 px midline
   gutter, so the image's inside edge lands 50 px from the page centre
   (right-edge on standard walls, left-edge on reversed). Image heights
   stay unified via --gallery-art-height (larger than the featured one). */
#gallery-rooms .wall-minimal,
#gallery-rooms .wall-minimal.reverse {
  max-width: none;
  margin-inline: 0;
  grid-template-columns: 1fr 1fr;
  gap: 100px;
}
#gallery-rooms .wall-minimal .wall-art {
  margin: 0;
  max-width: none;
  height: var(--gallery-art-height);
  display: flex;
  align-items: center;
  justify-content: center;
}
#gallery-rooms .wall-minimal .wall-art img {
  width: auto;
  height: 100%;
  max-width: 100%;
  object-fit: contain;
}
#gallery-rooms .wall-minimal:not(.reverse) .wall-art { justify-self: end; }
#gallery-rooms .wall-minimal:not(.reverse) .wall-tag { justify-self: start; text-align: left; }
#gallery-rooms .wall-minimal.reverse       .wall-art { justify-self: start; }
#gallery-rooms .wall-minimal.reverse       .wall-tag { justify-self: end; text-align: right; }
#gallery-rooms .wall-minimal .wall-tag {
  max-width: none;
  padding: 0;
}

@media (max-width: 900px) {
  #gallery-rooms { --gallery-art-height: clamp(18rem, 60vw, 24rem); }
  /* Keep the detail-page product image in lock-step with the gallery. */
  :root { --product-art-height: clamp(18rem, 60vw, 24rem); }
  /* Long titles can wrap when stacked under a narrow image. */
  .wall-minimal .wall-tag .tag-title { white-space: normal; }
  /* Stack on mobile, image centred with title centred tight beneath it. */
  #gallery-rooms .wall-minimal,
  #gallery-rooms .wall-minimal.reverse {
    grid-template-columns: 1fr;
    gap: 0.55rem;
  }
  #gallery-rooms .wall-minimal .wall-art,
  #gallery-rooms .wall-minimal.reverse .wall-art {
    justify-self: center;
    justify-content: center;
    max-width: none;
  }
  #gallery-rooms .wall-minimal:not(.reverse) .wall-tag,
  #gallery-rooms .wall-minimal.reverse       .wall-tag {
    justify-self: center;
    text-align: center;
    max-width: none;
  }
  /* More space between cards so each image+title reads as a unit. */
  #gallery-rooms .walls { gap: clamp(2.75rem, 7vw, 4rem); }
}

.room-divider {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: clamp(1.5rem, 3vw, 2.5rem) 0 clamp(1rem, 2vw, 1.75rem);
}
.room-label {
  font-family: var(--sans);
  font-size: 0.68rem;
  letter-spacing: 0.38em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: center;
  display: block;
  margin: 0 auto 0.5rem;
  padding-top: 0.25rem;
}
.room-subheading {
  font-family: var(--serif, var(--sans));
  font-style: italic;
  font-size: 0.95rem;
  color: var(--muted);
  text-align: center;
  margin: 0 auto clamp(1.25rem, 3vw, 2rem);
  max-width: 42rem;
  padding: 0 1rem;
}
.room-label + .room-subheading { margin-top: 0; }
/* When no subheading follows, restore the label's original bottom spacing. */
.room-label:not(:has(+ .room-subheading)) {
  margin-bottom: clamp(1.25rem, 3vw, 2rem);
}

/* ---------- Featured wall on the home page ---------- */
/* Mirrors the gallery page's staggered wall-minimal layout (alternating
   left/right around a centre gutter, museum-tag title aside the image).
   Image height is held to the same cap the home page used pre-rework so
   the section keeps its existing visual weight. */

.featured-walls {
  --featured-art-height: clamp(20rem, 32vw, 28rem);
  display: flex;
  flex-direction: column;
  gap: clamp(2rem, 4vw, 3.25rem);
  padding-top: 0.5rem;
}
.featured-walls .wall-minimal,
.featured-walls .wall-minimal.reverse {
  max-width: none;
  margin-inline: 0;
  grid-template-columns: 1fr 1fr;
  gap: 100px;
}
.featured-walls .wall-minimal .wall-art {
  margin: 0;
  max-width: none;
  height: var(--featured-art-height);
  display: flex;
  align-items: center;
  justify-content: center;
}
.featured-walls .wall-minimal .wall-art img {
  width: auto;
  height: 100%;
  max-width: 100%;
  object-fit: contain;
}
.featured-walls .wall-minimal:not(.reverse) .wall-art { justify-self: end; }
.featured-walls .wall-minimal:not(.reverse) .wall-tag { justify-self: start; text-align: left; }
.featured-walls .wall-minimal.reverse       .wall-art { justify-self: start; }
.featured-walls .wall-minimal.reverse       .wall-tag { justify-self: end; text-align: right; }
.featured-walls .wall-minimal .wall-tag {
  max-width: none;
  padding: 0;
}

@media (max-width: 900px) {
  .featured-walls {
    --featured-art-height: clamp(18rem, 60vw, 24rem);
    gap: clamp(2.75rem, 7vw, 4rem);
  }
  .featured-walls .wall-minimal,
  .featured-walls .wall-minimal.reverse {
    grid-template-columns: 1fr;
    gap: 0.55rem;
  }
  .featured-walls .wall-minimal:not(.reverse) .wall-art,
  .featured-walls .wall-minimal.reverse       .wall-art {
    justify-self: center;
    justify-content: center;
  }
  .featured-walls .wall-minimal:not(.reverse) .wall-tag,
  .featured-walls .wall-minimal.reverse       .wall-tag {
    justify-self: center;
    text-align: center;
    max-width: none;
  }
}

/* ---------- Print detail: a single wall, expanded label ---------- */

.detail {
  display: grid;
  grid-template-columns: 1fr minmax(18rem, 22rem);
  gap: clamp(2.5rem, 6vw, 5rem);
  padding: 2rem 0 6rem;
  align-items: start;
}
.detail-figure {
  background: var(--wall);
  padding: 0;
  box-shadow: none;
  max-width: calc(100% * var(--art-scale));
  margin-inline: auto;
}
/* Same model as the gallery page (.wall-art): a fixed-HEIGHT stage with the
   image contained, width auto. Every print renders at the same height it
   does in the gallery, so the footprint matches. The constant height also
   means the thumbnail row below never shifts on swap, and portraits aren't
   blown up to landscape width — all in pure CSS, no JS sizing. */
.detail-figure .detail-main {
  background: var(--wall);
  height: var(--product-art-height);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.detail-figure .detail-main img {
  width: auto;
  height: 100%;
  max-width: 100%;
  object-fit: contain;
  background: var(--wall);
}
.detail-thumbs {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.75rem;
  flex-wrap: wrap;
}
.detail-thumb {
  border: 1px solid var(--rule);
  background: var(--wall);
  padding: 0;
  width: 4.5rem;
  height: 4.5rem;
  cursor: pointer;
  overflow: hidden;
  transition: border-color 120ms ease, transform 120ms ease;
}
.detail-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.detail-thumb:hover { border-color: var(--ink-soft); }
.detail-thumb.active {
  border-color: var(--ink);
  transform: translateY(-1px);
}
.detail-info {
  padding-top: 1rem;
  border-left: 1px solid var(--rule);
  padding-left: clamp(1.5rem, 3vw, 2.5rem);
}
.detail-info .eyebrow { margin-bottom: 0.5rem; }
.detail-info h1 {
  font-size: clamp(1.9rem, 3.4vw, 2.6rem);
  font-style: italic;
  font-weight: 300;
  margin-bottom: 1rem;
  line-height: 1.1;
}
.price {
  font-family: var(--serif);
  font-size: 1.4rem;
  color: var(--ink);
  margin: 0 0 1.5rem;
}

.specs {
  font-family: var(--sans);
  font-size: 0.76rem;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  line-height: 1.6;
  margin: 1.75rem 0;
  padding: 1.25rem 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  /* Grid layout so a wrapped value stays inside the value column and
     never wraps underneath the label (the "detail title"). */
  display: grid;
  grid-template-columns: 7rem 1fr;
  column-gap: 1rem;
  row-gap: 0.45rem;
}
.specs dt {
  font-weight: 500;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.24em;
  font-size: 0.62rem;
  align-self: start;
  line-height: 1.5;
  padding-top: 0.25rem; /* optical align with the dd's first line */
}
.specs dd {
  margin: 0;
  min-width: 0; /* let long values wrap inside the column */
  overflow-wrap: anywhere;
}

.buy-row { display: flex; gap: 0.9rem; flex-wrap: wrap; margin-top: 1rem; }

.detail-note {
  font-family: var(--sans);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 1.5rem 0 0;
}

/* ---------- Process section: static 3 × 2 grid ---------- */

.process-grid {
  list-style: none;
  margin: 0.5rem 0 1rem;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.25rem, 3vw, 2.25rem);
}
.process-panel { margin: 0; }
.process-panel figure {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.process-panel-image {
  background: var(--wall);
  line-height: 0;
  overflow: hidden;
}
.process-panel-image img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
}
.process-panel-caption {
  font-family: var(--serif);
  font-size: 0.95rem;
  font-style: italic;
  color: var(--ink-soft);
  line-height: 1.5;
  margin: 0;
  max-width: 32rem;
}

@media (max-width: 900px) {
  .process-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .process-grid { grid-template-columns: 1fr; }
}

/* ---------- Legacy process-wall styles (markup removed but rules kept
   inert below; .caption-view is still used by the new last-panel link) ---------- */

.process-wall {
  display: grid;
  grid-template-columns: 1fr minmax(22rem, 28rem);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
  padding: 0.5rem 0 1rem;
  min-height: 480vh;
  position: relative;
}
/* 16 invisible snap points, one per stage, evenly spaced down the wall.
   Combined with `scroll-snap-type: y proximity` on <html>, the browser
   gently pulls scroll to the nearest stage when the user pauses. */
.process-snap-grid {
  position: absolute;
  inset: 0;
  width: 1px;
  pointer-events: none;
}
.process-snap-grid .snap-point {
  position: absolute;
  left: 0;
  width: 1px;
  height: 1px;
  scroll-snap-align: start;
  top: calc(var(--i) * (100% / 16));
}

/* Left column: image + caption. Sticks just below the section heading
   so the user sees the stage change as they scroll through the section. */
.process-image-column {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin: 0;
  align-self: start;
  position: sticky;
  top: calc(var(--nav-height) + 4rem);
}
.process-image-wrap { background: var(--wall); }
.process-image-wrap img {
  width: 100%;
  max-height: calc(100vh - var(--nav-height) - 12rem);
  object-fit: contain;
  transition: opacity 220ms ease;
}
.process-caption {
  font-family: var(--serif);
  font-size: 1rem;
  font-style: italic;
  color: var(--ink-soft);
  line-height: 1.5;
  margin: 0;
  padding: 0.2rem 0 0;
  max-width: 42rem;
  min-height: 4.5rem;
  transition: opacity 180ms ease;
}

/* Small inline "View the piece" tag that follows the final caption on
   step 16 (Colours of New England). JS appends it to the caption, so
   it fades in/out together with the caption text. */
.caption-view {
  display: inline-block;
  margin-left: 0.35rem;
  font-family: var(--serif);
  font-style: italic;
  font-size: 0.82rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--link);
  border-bottom: 1px solid var(--rule);
  padding-bottom: 0.05rem;
  white-space: nowrap;
  transition: border-color 160ms ease, color 160ms ease;
}
.caption-view:hover {
  color: var(--link-hover);
  border-bottom-color: currentColor;
}

/* Segmented progress bar sitting under the image. Each of the 16 stages
   gets one segment; segments fill left-to-right as the user scrolls. */
.process-progress {
  display: flex;
  gap: 3px;
  width: 100%;
  margin: 0.2rem 0 0.35rem;
  padding: 0;
  list-style: none;
}
.process-progress .progress-seg {
  flex: 1 1 0;
  height: 3px;
  background: var(--rule);
  border-radius: 2px;
  transition: background-color 280ms ease;
}
.process-progress .progress-seg.filled {
  background: var(--accent);
}
.process-progress .progress-seg.current {
  background: var(--ink);
}

/* Right column on desktop: the numbered list, sticky and vertically
   centered against the image. Height matches the image's max-height so
   flex-center places the list's middle at the image's middle. Hover
   previews any step. */
.process-stages-column {
  position: sticky;
  top: calc(var(--nav-height) + 4rem);
  align-self: start;
  height: calc(100vh - var(--nav-height) - 12rem);
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 0 0.25rem;
}

@media (max-width: 900px) {
  .process-wall {
    grid-template-columns: 1fr;
    /* Keep the same scroll budget on mobile so each photo + caption
       gets its share of scroll, snap-aligned to each stage. */
    min-height: 480vh;
  }
  /* Drop the number list entirely on mobile — scroll alone drives the
     photo + caption cycle. */
  .process-stages-column { display: none; }
  .process-image-column {
    top: calc(var(--nav-height) + 3rem);
  }
  .process-image-wrap img {
    max-height: calc(100vh - var(--nav-height) - 10rem);
  }
  .process-caption {
    min-height: 5.5rem; /* narrower column → longer captions wrap further */
  }
}
.process-wall .wall-art img {
  width: 100%;
  max-height: calc(78vh * var(--art-scale));
  object-fit: contain;
}
.process-wall .process-tag {
  font-family: var(--sans);
  color: var(--ink);
}
.process-wall .process-tag .eyebrow { margin-bottom: 1rem; }
.process-wall .process-tag h2 {
  font-style: italic;
  font-weight: 300;
  margin-bottom: 1.1rem;
}
.process-wall .process-tag .tag-rule {
  display: block;
  width: 2.25rem;
  height: 1px;
  background: var(--ink);
  margin: 0.1rem 0 1.25rem;
}
.process-wall .process-tag .prose {
  font-size: 0.98rem;
  max-width: 32rem;
}
/* Stages list: browser-rendered "1." counter, one line per title. */
.process-stages {
  margin: 0;
  padding: 0 0 0 2.25rem; /* room for the decimal counter on the left */
  font-family: var(--serif);
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--ink-soft);
  list-style: decimal;
}
.process-stages li {
  padding: 0.4rem 0.4rem 0.4rem 0.25rem;
  border-radius: 3px;
  cursor: pointer;
  transition: background 160ms ease, color 160ms ease;
}
.process-stages li::marker {
  color: var(--muted);
  font-family: var(--serif);
  font-style: italic;
}
.process-stages li:hover,
.process-stages li.active {
  background: var(--rule);
  color: var(--ink);
}
.process-stages li.active::marker { color: var(--accent); }

/* Text-only glint: when the section enters view, a subtle wave of colour
   runs down the list once (each item pulses muted → accent → muted). No
   background, no gradient strip — just the text. Stops permanently on
   first interaction via the `engaged` class. */
.process-stages-column.hint-active .process-stages li {
  animation-name: stepLabelGlint;
  animation-duration: 1.6s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: 1;
  animation-fill-mode: both;
  animation-delay: var(--glint-delay, 0s);
}
.process-stages-column.hint-active .process-stages li span:first-child {
  animation-name: stepNumGlint;
  animation-duration: 1.6s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: 1;
  animation-fill-mode: both;
  animation-delay: var(--glint-delay, 0s);
}
@keyframes stepLabelGlint {
  0%, 100% { color: var(--ink-soft); }
  50%      { color: var(--ink); }
}
@keyframes stepNumGlint {
  0%, 100% { color: var(--muted); }
  50%      { color: var(--accent); }
}
.process-stages-column.engaged .process-stages li,
.process-stages-column.engaged .process-stages li span:first-child {
  animation: none;
}

/* Smooth swap — the image is fully replaced on hover; this crossfades
   the src change by easing the opacity as it loads. */
.process-image-wrap img {
  transition: opacity 220ms ease;
}
.process-image-wrap img:not([src]) { opacity: 0; }
/* Caption fades softly when the text changes so it feels cohesive. */
.process-caption {
  transition: opacity 180ms ease;
}

/* ---------- About wall ---------- */

.about-wall {
  display: grid;
  grid-template-columns: minmax(18rem, 24rem) minmax(auto, 36rem);
  grid-template-areas:
    "image   name"
    "image   prose";
  grid-template-rows: auto 1fr;
  column-gap: clamp(1.5rem, 4vw, 3rem);
  row-gap: 0;
  align-items: start;
  padding: 1.5rem 0;
  max-width: 64rem;
  margin-inline: auto;
  justify-content: center;
}
.about-wall .about-name-block { grid-area: name; }
.about-wall .about-portrait   { grid-area: image; }
.about-wall .about-tag        { grid-area: prose; }

.about-wall img {
  width: calc(100% * var(--art-scale));
  height: auto;
  object-fit: contain;
  background: var(--wall);
  margin-inline: auto;
}
.about-wall .about-tag .eyebrow { margin-bottom: 0.8rem; }
.about-wall .about-tag .prose > p:first-child { margin-top: 0; }
.about-wall .about-portrait > picture { display: block; }
.about-wall .about-portrait > picture img { vertical-align: top; }
.about-wall .about-name {
  font-style: italic;
  font-weight: 300;
  margin-bottom: 0.4rem;
}
.about-wall .tag-rule {
  display: block;
  width: 2.25rem;
  height: 1px;
  background: var(--ink);
  margin: 0.5rem 0 1.25rem;
}

/* ---------- Gallery exhibits block (About section) ----------
   Quiet footer to the About section — small eyebrow, hairline rule,
   no sticky banner so it doesn't compete with "About the artist". */

.exhibits-block {
  margin: clamp(2rem, 4vw, 3rem) auto 0;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
  max-width: 38rem;
}
.exhibits-block .eyebrow {
  display: block;
  margin-bottom: 1rem;
}
.exhibits-block .exhibit-list {
  /* No top rule on the list itself — the block already has one. */
  border-top: 0;
  padding-top: 0;
}

.exhibit-list {
  list-style: none;
  padding: 1.25rem 0 0;
  margin: 0;
  border-top: 1px solid var(--rule);
  display: grid;
  grid-template-columns: 1fr auto auto;
  column-gap: clamp(1rem, 2.5vw, 2rem);
  row-gap: 0.7rem;
  align-items: baseline;
}
.exhibit-list li { display: contents; }
.ex-name {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1rem;
  color: var(--ink);
}
.ex-where {
  font-family: var(--sans);
  font-size: 0.82rem;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}
.ex-when {
  font-family: var(--sans);
  font-size: 0.7rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
  text-align: right;
}
@media (max-width: 600px) {
  .exhibit-list {
    grid-template-columns: 1fr;
    row-gap: 0.2rem;
  }
  .exhibit-list li {
    display: block;
    padding: 0.4rem 0 0.5rem;
    border-bottom: 1px solid var(--rule);
  }
  .exhibit-list li:last-child { border-bottom: 0; }
  .ex-name { display: block; margin-bottom: 0.15rem; }
  .ex-where { display: inline; }
  .ex-when { display: inline; text-align: left; }
  .ex-where::after { content: " · "; color: var(--muted); }
}

.pull-quote {
  font-family: var(--serif);
  font-size: clamp(1.3rem, 2.2vw, 1.8rem);
  font-style: italic;
  font-weight: 300;
  line-height: 1.4;
  color: var(--ink);
  max-width: var(--measure);
  margin: 3rem auto;
  text-align: center;
  padding: 1.75rem 1rem;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.pull-quote-tight { margin: 1.5rem auto 0; padding: 1.25rem 1rem; }

/* Small variant that lives directly under Kate's portrait, in the
   same grid column. Sized to fit the photo's width and quiet enough
   not to compete with the bio prose alongside it. */
.pull-quote-portrait {
  font-size: clamp(0.95rem, 1.25vw, 1.05rem);
  line-height: 1.5;
  margin: 1rem auto 0;
  padding: 0.9rem 0.5rem 0;
  text-align: center;
  border-top: 1px solid var(--rule);
  border-bottom: 0;
  max-width: 22rem;
}

/* ---------- Contact ---------- */

/* Kate wanted "Write to the studio." smaller than the default h1. */
.contact-head {
  padding: 0;
  border: 0;
  margin: 0 auto 0.5rem;
  max-width: var(--measure);
}
.contact-head .lede { margin: 0; }
.contact-title {
  font-size: clamp(1.3rem, 2.4vw, 1.9rem);
  font-weight: 300;
  font-style: italic;
  line-height: 1.15;
}

.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2.5rem;
  padding: 0 0 0.75rem;
  max-width: 64rem;
  margin-inline: auto;
}
.contact-details h3 { margin-bottom: 0.4rem; }
.contact-details a { font-family: var(--sans); font-size: 0.92rem; }

form.newsletter, form.contact-form {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.newsletter-intro {
  margin: 0 0 0.25rem;
}
.newsletter-prefs {
  border: 0;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
.newsletter-prefs .check-row {
  /* Override the global uppercase tracked label rule. */
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  font-family: var(--sans);
  font-size: 0.92rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  line-height: 1.45;
  cursor: pointer;
}
.newsletter-prefs .check-row input[type="checkbox"] {
  /* Override the global input padding/border treatment. */
  appearance: auto;
  width: 1rem;
  height: 1rem;
  margin: 0.18rem 0 0;
  padding: 0;
  border: 1px solid var(--rule);
  background: var(--wall);
  accent-color: var(--ink);
  flex: 0 0 auto;
}
label {
  font-family: var(--sans);
  font-size: 0.66rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--muted);
}
input, textarea {
  font-family: var(--serif);
  font-size: 1rem;
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--rule);
  background: #fafaf7;
  color: var(--ink);
  border-radius: 2px;
  transition: border-color 160ms ease, background-color 160ms ease, box-shadow 160ms ease;
}
input:hover, textarea:hover {
  border-color: #cfcdc7;
}
input:focus, textarea:focus {
  outline: none;
  border-color: var(--ink);
  background: var(--wall);
  box-shadow: 0 0 0 3px rgba(52, 72, 127, 0.08);
}
input::placeholder, textarea::placeholder {
  color: var(--muted);
  opacity: 1;
}

/* ---------- Site footer ---------- */

.site-footer {
  border-top: 1px solid var(--rule);
  margin-top: 1.25rem;
  padding: 1.75rem 0 2.25rem;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 2.5rem;
  font-family: var(--sans);
  font-size: 0.8rem;
  color: var(--muted);
  line-height: 1.7;
}
.site-footer h4 {
  font-family: var(--sans);
  font-size: 0.66rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 0.9rem;
  font-weight: 500;
}
.site-footer .fine-print {
  grid-column: 1 / -1;
  border-top: 1px solid var(--rule);
  padding-top: 1.5rem;
  display: flex;
  justify-content: space-between;
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  flex-wrap: wrap;
  gap: 1rem;
}
.al-credit { display: inline-flex; align-items: baseline; gap: 0.4em; }
.al-mark {
  font-family: 'Allura', 'Snell Roundhand', 'Apple Chancery', cursive;
  font-style: normal;
  text-transform: none;
  letter-spacing: 0;
  font-size: 1.55em;
  line-height: 1;
  color: var(--ink);
  border-bottom: none;
  vertical-align: -0.12em;
}
.al-mark:hover { color: var(--accent, var(--ink)); }

/* ---------- Cart FAB (unchanged behaviour, simpler skin) ---------- */

.fab-dock {
  position: fixed;
  right: clamp(1rem, 2.5vw, 2rem);
  bottom: clamp(1rem, 2.5vw, 2rem);
  z-index: 30;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  align-items: flex-end;
  pointer-events: none;
}
.fab-dock .fab { pointer-events: auto; }
.fab {
  position: relative;
  width: 3rem;
  height: 3rem;
  border-radius: 999px;
  background: var(--ink);
  color: var(--wall);
  border: 1px solid var(--ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  transition: background 180ms ease;
}
.fab:hover { background: #000; border-bottom-color: var(--ink); }
.fab svg { flex: 0 0 auto; }
.fab-cart { display: none; }
.fab-cart.visible { display: inline-flex; }
.fab-badge {
  position: absolute;
  top: 4px;
  right: 5px;
  min-width: 0.9rem;
  height: 0.9rem;
  padding: 0 0.22rem;
  border-radius: 999px;
  background: var(--wall);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 0.56rem;
  font-weight: 500;
  letter-spacing: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

/* ---------- Scroll reveal ---------- */

.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 900ms cubic-bezier(.2,.7,.2,1),
              transform 900ms cubic-bezier(.2,.7,.2,1);
  will-change: opacity, transform;
}
.reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* ---------- Responsive ---------- */

@media (max-width: 900px) {
  .hero {
    grid-template-columns: 1fr;
    gap: 2rem;
    padding: 2.5rem 0 1.5rem;
  }
  /* Mobile hero: drop the forced 100vh and pull the wordmark tight to the
     image — Kate's feedback was that the title was sitting too high. */
  .hero-full {
    min-height: auto;
    padding: 0.75rem 1rem 0.5rem;
    gap: 0.4rem;
  }
  .hero-full-image {
    width: 100%;
    height: auto;
    max-height: 72vh;
  }
  .detail,
  .process-wall,
  .about-wall,
  .contact-grid {
    grid-template-columns: 1fr;
    gap: 2rem;
  }
  /* About on mobile — single column, name block first, then image, then prose. */
  .about-wall {
    grid-template-areas: "name" "image" "prose";
    row-gap: 1rem;
  }
  .detail-info { border-left: 0; padding-left: 0; border-top: 1px solid var(--rule); padding-top: 2rem; }
  .wall,
  .wall.reverse,
  .wall-minimal,
  .wall-minimal.reverse {
    grid-template-columns: 1fr;
    gap: 1rem;
  }
  .wall.reverse .wall-art { order: 0; }
  .wall.reverse .wall-tag { order: 1; text-align: left; }
  .wall.reverse .wall-tag .tag-rule { margin-left: 0; }
  .wall-tag { padding: 0; max-width: 32rem; }
  .site-header, .site-header[data-sticky] { padding: 0.8rem 0; }
  .nav { gap: 1rem; font-size: 0.66rem; letter-spacing: 0.22em; }
  .fab { width: 2.6rem; height: 2.6rem; }
  .fab-dock { right: 0.75rem; bottom: 0.75rem; }
  .filter-btn { min-height: 44px; }
  input, textarea { font-size: 16px; }
}

@media (max-width: 520px) {
  .site { padding: 0 1.1rem; }
  .nav { gap: 0.75rem; font-size: 0.62rem; letter-spacing: 0.18em; }
  .hero-title { font-size: clamp(2.2rem, 9vw, 2.8rem); }
  .page-head { padding: 3rem 0 2rem; margin-bottom: 2rem; }
  .site-footer { margin-top: 4rem; padding: 2.5rem 0 3rem; }
  .site-footer .fine-print { flex-direction: column; }
}

/* ---------- Cart drawer ---------- */

.cart-drawer { position: fixed; inset: 0; z-index: 50; pointer-events: none; }
.cart-backdrop {
  position: absolute; inset: 0;
  background: rgba(17, 17, 17, 0.35);
  opacity: 0;
  transition: opacity 260ms ease;
  pointer-events: none;
}
.cart-panel {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(26rem, 100vw);
  background: var(--wall);
  border-left: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 320ms cubic-bezier(.2,.7,.2,1);
  pointer-events: none;
}
.cart-drawer.open { pointer-events: auto; }
.cart-drawer.open .cart-backdrop { opacity: 1; pointer-events: auto; }
.cart-drawer.open .cart-panel { transform: none; pointer-events: auto; }

body.cart-open { overflow: hidden; }

.cart-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.4rem 1.5rem 1rem;
  border-bottom: 1px solid var(--rule);
}
.cart-head .eyebrow { margin: 0; }
.cart-x {
  font-family: var(--serif);
  font-size: 1.6rem;
  line-height: 1;
  background: none;
  border: 0;
  color: var(--ink);
  cursor: pointer;
  padding: 0.25rem 0.5rem;
}
.cart-x:hover { color: var(--accent); }

.cart-body { flex: 1 1 auto; overflow-y: auto; padding: 1rem 1.5rem; }
.cart-empty { color: var(--muted); font-style: italic; text-align: center; padding: 3rem 1rem; }
.cart-line {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: 1rem;
  padding: 1rem 0;
  border-bottom: 1px solid var(--rule);
  align-items: start;
}
.cart-line:last-child { border-bottom: 0; }
.cart-thumb { width: 4.5rem; height: 4.5rem; object-fit: cover; background: var(--wall); border: 1px solid var(--rule); }
.cart-line-title {
  font-family: var(--serif);
  font-size: 1.05rem;
  font-style: italic;
  font-weight: 400;
  margin: 0 0 0.25rem;
  line-height: 1.2;
}
.cart-line-meta {
  font-family: var(--sans);
  font-size: 0.76rem;
  color: var(--muted);
  margin: 0 0 0.4rem;
  letter-spacing: 0.04em;
}
.cart-remove {
  font-family: var(--sans);
  font-size: 0.66rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  background: none;
  border: 0;
  color: var(--muted);
  padding: 0;
  cursor: pointer;
}
.cart-remove:hover { color: var(--ink); }

.cart-foot {
  border-top: 1px solid var(--rule);
  padding: 1.2rem 1.5rem 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}
.cart-totals {
  display: flex;
  justify-content: space-between;
  font-family: var(--sans);
  font-size: 0.72rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--ink);
}
.cart-checkout-btn { width: 100%; justify-content: center; }
.cart-checkout-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.cart-fine {
  font-family: var(--sans);
  font-size: 0.66rem;
  color: var(--muted);
  line-height: 1.5;
  margin: 0;
  text-align: center;
}
@media (max-width: 520px) {
  .cart-panel { width: 100vw; }
  .cart-head, .cart-foot, .cart-body { padding-left: 1.1rem; padding-right: 1.1rem; }
}

/* ---------- Legal drawer (Privacy + Terms) ---------- */
/* Slides up from the bottom of the viewport — same backdrop+panel pattern
   as .cart-drawer, just rotated 90°. Tiny .legal-link triggers in the
   footer open it; ESC or backdrop click closes. */

.legal-drawer { position: fixed; inset: 0; z-index: 50; pointer-events: none; }
.legal-backdrop {
  position: absolute; inset: 0;
  background: rgba(17, 17, 17, 0.35);
  opacity: 0;
  transition: opacity 260ms ease;
  pointer-events: none;
}
.legal-panel {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: min(80vh, 44rem);
  background: var(--wall);
  border-top: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  transform: translateY(100%);
  transition: transform 320ms cubic-bezier(.2,.7,.2,1);
  pointer-events: none;
}
.legal-drawer.open { pointer-events: auto; }
.legal-drawer.open .legal-backdrop { opacity: 1; pointer-events: auto; }
.legal-drawer.open .legal-panel { transform: none; pointer-events: auto; }

body.legal-open { overflow: hidden; }

.legal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.4rem 1.5rem 1rem;
  border-bottom: 1px solid var(--rule);
}
.legal-head .legal-eyebrow { margin: 0; }
.legal-x {
  font-family: var(--serif);
  font-size: 1.6rem;
  line-height: 1;
  background: none;
  border: 0;
  color: var(--ink);
  cursor: pointer;
  padding: 0.25rem 0.5rem;
}
.legal-x:hover { color: var(--accent); }

.legal-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 1.5rem clamp(1.25rem, 5vw, 3rem) 2rem;
  max-width: 56rem;
  margin: 0 auto;
  width: 100%;
  font-family: var(--sans);
  color: var(--ink);
  line-height: 1.55;
  font-size: 0.95rem;
}
.legal-body h2.legal-title {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  margin: 0 0 0.5rem;
  color: var(--ink);
}
.legal-body p.legal-updated {
  font-family: var(--sans);
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 1.5rem;
}
.legal-body h3 {
  font-family: var(--sans);
  font-size: 0.78rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--accent);
  margin: 1.6rem 0 0.5rem;
}
.legal-body p { margin: 0 0 0.85rem; }
.legal-body ul {
  margin: 0 0 0.85rem;
  padding-left: 1.2rem;
}
.legal-body li { margin: 0 0 0.3rem; }
.legal-body strong { color: var(--ink); font-weight: 500; }

.legal-link {
  font-family: var(--sans);
  font-size: 0.66rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  cursor: pointer;
  background: none;
  border: 0;
  padding: 0;
}
.legal-link:hover { color: var(--ink); }

@media (max-width: 520px) {
  .legal-panel { height: 90vh; }
  .legal-head { padding-left: 1.1rem; padding-right: 1.1rem; }
}

/* ---------- Gallery page (All Work): flat 2-column grid ---------- */
/* Active only when #gallery-rooms has .is-grid (toggled by main.js when
   the "Entire gallery" filter is selected). Specific-gallery filters
   render a single staggered room instead, so this dense layout is the
   overview view only. */

#gallery-rooms.is-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(0.75rem, 1.6vw, 1.5rem);
  padding: 0.5rem 0 1rem;
}

#gallery-rooms.is-grid .grid-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  border: 0;
  background: var(--wall);
  text-decoration: none;
  color: inherit;
}
#gallery-rooms.is-grid .grid-card-figure {
  margin: 0;
  width: 100%;
  background: var(--wall);
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 0;
}
#gallery-rooms.is-grid .grid-card-figure img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  display: block;
}

/* Caption sits visibly under the image — title-under-photo on every
   viewport, no hover required. */
#gallery-rooms.is-grid .grid-card-caption {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  padding: 0.55rem 0 0;
  text-align: center;
  color: var(--ink);
  line-height: 1.3;
}
#gallery-rooms.is-grid .grid-card-title {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.1rem, 1.6vw, 1.4rem);
  font-weight: 400;
}
#gallery-rooms.is-grid .grid-card-price {
  font-family: var(--sans);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  color: var(--ink-soft);
}
#gallery-rooms.is-grid .grid-card-price.sold {
  font-style: italic;
  text-transform: uppercase;
  letter-spacing: 0.3em;
}

/* 2 columns on tablet, 1 on phone. */
@media (max-width: 900px) {
  #gallery-rooms.is-grid {
    grid-template-columns: 1fr 1fr;
    gap: clamp(1rem, 2.5vw, 1.5rem);
  }
}
@media (max-width: 520px) {
  #gallery-rooms.is-grid {
    grid-template-columns: 1fr;
    gap: 1.25rem;
  }
}
