/* ==========================================================================
   The cabinet catalogue — [sage_products] and [sage_finishes]
   ==========================================================================

   Loaded only on pages carrying one of those shortcodes (functions.php,
   sage_designer_assets). Depends on sage-header for the token set and the
   shared .sage-wrap / .sage-eyebrow vocabulary.

   THREE THINGS THIS FILE HAS TO DEFEND AGAINST

   1. Flatsome styles every <button>, <li>, <details> and <summary>, and wins
      on specificity through `.entry-content`. Every interactive element below
      therefore zeroes the inherited chrome on its own class. The tell that you
      are fighting the parent theme: a computed value that appears nowhere in
      this file.

   2. `.sage-btn` lives in homepage.css, which is FRONT-PAGE ONLY. These are
      interior pages, so the catalogue defines .sage-pd-btn rather than reusing
      a class that will not be there.

   3. Never nest @media inside :root:not(...) — it parses but never applies,
      which silently cost a dark-on-dark warranty badge during prototyping.
      Always `@media (...) { :root:not(...) { } }`.

   MOTION

   One entrance curve (--pd-ease, ease-out-expo) and exits ~20% faster. Only
   transform and opacity animate. Every hover is gated on
   `(hover: hover) and (pointer: fine)` so a tap does not leave a tile stuck in
   its hover state.
   ========================================================================== */

.sage-pd,
.sage-fin {
  /* ease-out-expo: covers ~80% of its distance in the first ~20% of the time,
     then glides. That long settle is what reads as mass. */
  --pd-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --pd-surface: #fff;
  --pd-sunk: var(--sage-50, #f2f3ec);
  --pd-badge-fg: var(--olive-800);
  --pd-badge-bg: var(--sage-100, #e8eadf);
  --pd-badge-bd: var(--sage-200, #d9dccb);
  --pd-sh-sm: 0 1px 2px rgba(28, 28, 24, 0.06);
  --pd-sh-md: 0 6px 22px rgba(28, 28, 24, 0.10);
  --pd-sh-lg: 0 18px 50px rgba(28, 28, 24, 0.18);
}

/* --- buttons: ours, because .sage-btn is front-page only ----------------- */
.sage-pd-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.2;
  padding: 0.8rem 1.6rem;
  border: 1px solid transparent;
  border-radius: var(--radius-sm, 2px);
  text-decoration: none;
  cursor: pointer;
  transition: background 0.28s var(--pd-ease), color 0.28s var(--pd-ease),
              border-color 0.28s var(--pd-ease);
}
.sage-pd-btn--pri { background: var(--olive-800); color: #fff; }
.sage-pd-btn--pri:hover,
.sage-pd-btn--pri:focus-visible { background: var(--olive-900); color: #fff; }
.sage-pd-btn--ghost {
  background: transparent;
  color: var(--olive-700);
  border-color: var(--color-border);
}
.sage-pd-btn--ghost:hover,
.sage-pd-btn--ghost:focus-visible { border-color: var(--olive-700); }
.sage-pd-btn:focus-visible,
.sage-pd button:focus-visible,
.sage-fin button:focus-visible {
  outline: 2px solid var(--olive-500);
  outline-offset: 2px;
}

/* ==========================================================================
   VERSION A — product cards
   ========================================================================== */

.sage-pd {
  display: grid;
  grid-template-columns: 230px 1fr;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start;
}
@media (max-width: 900px) {
  .sage-pd { grid-template-columns: 1fr; gap: 1.5rem; }
}

/* --- filter sidebar ------------------------------------------------------ */
/* Sticky, and it must scroll INDEPENDENTLY.
   position:sticky pins the top of the element; it does nothing about an element
   taller than the viewport, so the bottom of a long filter list was simply
   unreachable -- you scrolled the page, the sidebar came with you, and the last
   options stayed off screen. (Owner feedback 2026-09-18: "you need to scroll
   the page to see all the filters".)

   max-height + overflow-y gives the panel its own scrollbar. 150px is the fixed
   editorial header's clearance, so the height budget is the viewport minus that
   minus a bottom breathing gap. svh, not vh: vh is the viewport with browser
   chrome HIDDEN, which is the one state that does not overflow.

   overscroll-behavior stops a flick inside the filter list from chaining to the
   page once it hits the end -- the same fix the visualizer's gate needed. */
.sage-pd-side {
  position: sticky;
  top: 150px;
  max-height: calc(100svh - 150px - 2rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Room for the scrollbar so it never sits on top of the checkboxes. */
  padding-right: 0.5rem;
  scrollbar-width: thin;
}
.sage-pd-side::-webkit-scrollbar { width: 6px; }
.sage-pd-side::-webkit-scrollbar-thumb {
  background: var(--color-border);
  border-radius: 3px;
}
/* The header stays put while the options scroll under it. */
.sage-pd-side-hd {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--bone);
}
@media (max-width: 900px) {
  .sage-pd-side {
    position: static;
    top: auto;
    max-height: none;
    overflow-y: visible;
    padding-right: 0;
  }
  .sage-pd-side-hd { position: static; }
}

.sage-pd-side-hd {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--color-border);
  margin-bottom: 1rem;
}
/* Was an h3. Demoted to a span 2026-09-17: it sat before any h2 on the page,
   so the document outline ran H1 -> H3 -> H2. Styling is unchanged; the
   selector keeps the h3 as well so the rule survives a revert. */
.sage-pd-side-hd h3,
.sage-pd-side-ttl {
  display: block;
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--color-heading);
  margin: 0;
  letter-spacing: 0;
  text-transform: none;
}
.sage-pd-clear {
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  min-height: 0;
  font: inherit;
  font-size: 0.8125rem;
  color: var(--olive-700);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
  box-shadow: none;
  border-radius: 0;
}

/* Flatsome styles <details>/<summary>; zero it here. */
.sage-pd-fgroup {
  border: 0;
  border-bottom: 1px solid var(--color-border);
  margin: 0;
  padding: 0;
  background: none;
  box-shadow: none;
}
.sage-pd-fgroup > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 0;
  margin: 0;
  background: none;
  border: 0;
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 400;
  color: var(--color-heading);
}
.sage-pd-fgroup > summary::-webkit-details-marker { display: none; }
.sage-pd-fgroup > summary::marker { content: none; }
/* The +/− is drawn rather than typed so it cannot inherit a font. */
.sage-pd-fgroup > summary i {
  position: relative;
  width: 0.75rem;
  height: 0.75rem;
  flex: 0 0 auto;
}
.sage-pd-fgroup > summary i::before,
.sage-pd-fgroup > summary i::after {
  content: "";
  position: absolute;
  background: var(--color-text-muted);
  transition: transform 0.28s var(--pd-ease), opacity 0.2s var(--pd-ease);
}
.sage-pd-fgroup > summary i::before {
  inset: 50% 0 auto 0; height: 1px; transform: translateY(-50%);
}
.sage-pd-fgroup > summary i::after {
  inset: 0 50% 0 auto; width: 1px; transform: translateX(50%);
}
.sage-pd-fgroup[open] > summary i::after { opacity: 0; transform: translateX(50%) rotate(90deg); }

.sage-pd-fopts {
  padding: 0 0 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.sage-pd-fopt {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.875rem;
  color: var(--color-text);
  cursor: pointer;
  padding: 0.25rem 0;
  margin: 0;
}
.sage-pd-fopt input {
  accent-color: var(--olive-700);
  width: 1rem;
  height: 1rem;
  margin: 0;
  cursor: pointer;
  flex: 0 0 auto;
}
.sage-pd-n {
  margin-left: auto;
  font-size: 0.75rem;
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}
@media (max-width: 900px) {
  .sage-pd-fopts { flex-direction: row; flex-wrap: wrap; gap: 0.5rem 1.15rem; }
  .sage-pd-n { margin-left: 0.15rem; }
}

/* --- collection sections ------------------------------------------------- */
.sage-pd-coll { margin-bottom: clamp(2.5rem, 6vw, 4rem); }
.sage-pd-coll:last-of-type { margin-bottom: 0; }
.sage-pd-coll[hidden] { display: none; }

.sage-pd-coll-hd {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.5rem 2.5rem;
  align-items: start;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--color-border);
  margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
}
@media (max-width: 760px) { .sage-pd-coll-hd { grid-template-columns: 1fr; } }
.sage-pd-coll-hd > :first-child {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 3.4vw, 2.4rem);
  line-height: var(--leading-heading);
  color: var(--color-heading);
  margin: 0;
}
.sage-pd-coll-hd p {
  margin: 0;
  color: var(--color-text-muted);
  font-size: 0.9375rem;
  max-width: 62ch;
}
/* .sage-pd-warr — the warranty badge that sat under each collection blurb —
   was removed on 2026-09-17 along with every warranty claim on the site. See
   the COLLECTIONS comment in scripts/fetch_cnc_specs.py for why, and do not
   restore this rule without restoring the data it rendered. */

/* --- the cards ----------------------------------------------------------- */
/* Fixed column counts per breakpoint, never auto-fill with a small minmax: a
   9.5rem floor once gave seven 158px columns at 1440px. Row gap exceeds column
   gap because the standing door hangs below each card. */
.sage-pd-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(2.5rem, 4vw, 3.25rem) clamp(1.25rem, 2vw, 1.75rem);
  margin: 0;
  padding: 0;
  list-style: none;
}
@media (max-width: 1180px) { .sage-pd-cards { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 700px)  { .sage-pd-cards { grid-template-columns: 1fr; } }

.sage-pd-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--pd-surface);
  border: 1px solid var(--color-border);
  border-radius: 3px;
  box-shadow: var(--pd-sh-sm);
  /* The door must be free to hang past the lower edge — that overlap is the
     whole visual idea, and the grid's row gap carries it. */
  overflow: visible;
  transition: box-shadow 0.3s var(--pd-ease), transform 0.3s var(--pd-ease);
}
.sage-pd-card[hidden] { display: none; }
@media (hover: hover) and (pointer: fine) {
  .sage-pd-card:hover { box-shadow: var(--pd-sh-lg); transform: translateY(-3px); }
}
.sage-pd-card:not(:hover) { transition-duration: 0.24s; }

/* The photo and the door share a wrapper: the photo clips its own image, the
   wrapper does not, so the door hangs below the photo's edge while staying
   anchored to the PHOTO rather than the card. A card whose title wraps to two
   lines then cannot push the door into the foot. */
.sage-pd-card-top { position: relative; }
.sage-pd-shot {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border-radius: 3px 3px 0 0;
  background: var(--pd-sunk);
}
.sage-pd-shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.7s var(--pd-ease);
}
@media (hover: hover) and (pointer: fine) {
  .sage-pd-card:hover .sage-pd-shot img { transform: scale(1.03); }
}
.sage-pd-shot--none { display: grid; place-items: center; }
/* The standing door occupies the left 26% + gutter; the placeholder has to
   start after it or the two overlap -- which is exactly what happened on the
   three lines with no room render. */
.sage-pd-shot--none { padding-left: calc(26% + 2rem); padding-right: 1.15rem; }
.sage-pd-shot--none span {
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: center;
  color: var(--color-text-muted);
  padding: 1rem;
  text-wrap: balance;
}

/* Sized as a fraction of the CARD, not the viewport: a vw-based clamp made the
   door 96px against a 270px card in the 3-up grid, covering the very room it
   is meant to sample. 26% keeps it a sample held in front of the photograph. */
.sage-pd-door {
  position: absolute;
  left: 1.1rem;
  bottom: -2.1rem;
  width: 26%;
  /* Capped in px as well as %: a collection with two lines renders 2-up, so the
     card is much wider than in a 3-up row and a pure percentage made the door
     read as a poster rather than a sample held against the photograph. */
  max-width: 76px;
  min-width: 56px;
  z-index: 3;
  border: 1px solid var(--color-border);
  background: var(--pd-surface);
  border-radius: var(--radius-sm, 2px);
  box-shadow: var(--pd-sh-md);
  overflow: hidden;
}
.sage-pd-door-im {
  display: block;
  background-color: var(--c);
  aspect-ratio: 1 / 2;
}
.sage-pd-door-im img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Left padding clears the door, tied to its own 26% width rather than guessed. */
.sage-pd-card-body {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-height: 5.4rem;
  padding: 1.1rem 1.15rem 1.15rem;
  padding-left: calc(26% + 2rem);
}
/* Was `h4`, which matched nothing -- the markup emits h3, so these cards were
   silently falling back to Poppins instead of the display face. */
.sage-pd-card-h {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  margin: 0;
  font-weight: inherit;
}
/* The line name leads the heading for SEO, but stays visually secondary: the
   door style is what a browsing customer scans for. */
.sage-pd-card-h .sage-pd-styl {
  display: block;
  font-family: var(--font-display);
  font-size: 1.5rem;
  line-height: 1.1;
  color: var(--color-heading);
  letter-spacing: var(--tracking-display, -0.02em);
}
.sage-pd-cnc { display: block; font-size: 0.8125rem; color: var(--color-text-muted); }
/* A line with no separate style (Newport) renders the line name alone, so it
   has to carry the display treatment itself or the card loses its heading. */
.sage-pd-card-h .sage-pd-cnc:only-child {
  font-family: var(--font-display);
  font-size: 1.5rem;
  line-height: 1.1;
  color: var(--color-heading);
  letter-spacing: var(--tracking-display, -0.02em);
}
.sage-pd-nfin { display: block; margin-top: 0.35rem; font-size: 0.8125rem; }

.sage-pd-card-foot {
  margin-top: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 1.15rem;
  padding-left: calc(26% + 2rem);
  border-top: 1px solid var(--color-border);
  border-radius: 0 0 3px 3px;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--color-heading);
  background: transparent;
  transition: background 0.28s var(--pd-ease), color 0.28s var(--pd-ease);
}
@media (hover: hover) and (pointer: fine) {
  .sage-pd-card:hover .sage-pd-card-foot { background: var(--olive-800); color: #fff; }
}
.sage-pd-chev {
  position: relative;
  width: 1.65rem;
  height: 1.65rem;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--pd-badge-bg);
  transition: background 0.28s var(--pd-ease), transform 0.28s var(--pd-ease);
}
.sage-pd-chev::before,
.sage-pd-chev::after {
  content: "";
  position: absolute;
  background: var(--pd-badge-fg);
  transition: background 0.28s var(--pd-ease);
}
.sage-pd-chev::before {
  top: 50%; left: 32%; width: 36%; height: 1.2px; transform: translateY(-50%);
}
.sage-pd-chev::after {
  top: 50%; right: 34%; width: 7px; height: 7px;
  border-right: 1.2px solid var(--pd-badge-fg);
  border-top: 1.2px solid var(--pd-badge-fg);
  background: none;
  transform: translateY(-50%) rotate(45deg);
}
@media (hover: hover) and (pointer: fine) {
  .sage-pd-card:hover .sage-pd-chev {
    background: var(--gold-300);
    transform: translateX(3px);
  }
  .sage-pd-card:hover .sage-pd-chev::before { background: var(--olive-900); }
  .sage-pd-card:hover .sage-pd-chev::after {
    border-right-color: var(--olive-900);
    border-top-color: var(--olive-900);
  }
}

/* The whole card is the hit target; the label stays for screen readers. */
.sage-pd-open {
  position: absolute;
  inset: 0;
  z-index: 4;
  width: 100%;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 3px;
  background: none;
  box-shadow: none;
  color: transparent;
  font: inherit;
  cursor: pointer;
  text-indent: -9999px;
  overflow: hidden;
}
.sage-pd-open:focus-visible { outline: 2px solid var(--olive-700); outline-offset: 3px; }

.sage-pd-empty,
.sage-fin-empty {
  padding: 3rem 1rem;
  text-align: center;
  color: var(--color-text-muted);
}

/* ==========================================================================
   The detail dialog
   ========================================================================== */
.sage-pd-dlg {
  border: 0;
  padding: 0;
  margin: 0;
  max-width: none;
  max-height: none;
  width: 100%;
  height: 100%;
  background: transparent;
  overflow: visible;
}
.sage-pd-dlg::backdrop { background: rgba(20, 21, 14, 0.74); }
.sage-pd-pane {
  position: absolute;
  inset: 0;
  height: max-content;
  max-height: calc(100dvh - 1.5rem);
  width: calc(100% - 1.5rem);
  max-width: 1180px;
  margin: auto;
  background: var(--color-bg);
  border-radius: 4px;
  box-shadow: var(--pd-sh-lg);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.sage-pd-bar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.7rem clamp(1rem, 2.5vw, 1.75rem);
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-border);
}
.sage-pd-back {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0;
  padding: 0;
  min-height: 0;
  background: none;
  border: 0;
  box-shadow: none;
  border-radius: 0;
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  cursor: pointer;
  transition: color 0.2s var(--pd-ease);
}
.sage-pd-back:hover { color: var(--olive-700); }
.sage-pd-back i {
  position: relative;
  width: 1.5rem;
  height: 1.5rem;
  border: 1px solid var(--color-border);
  border-radius: 50%;
  flex: 0 0 auto;
}
.sage-pd-back i::before {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 6px; height: 6px;
  border-left: 1.2px solid currentColor;
  border-bottom: 1.2px solid currentColor;
  transform: translate(-30%, -50%) rotate(45deg);
}
.sage-pd-x {
  margin: 0 0 0 auto;
  padding: 0;
  width: 2.2rem;
  height: 2.2rem;
  min-height: 0;
  display: grid;
  place-items: center;
  border: 1px solid var(--color-border);
  border-radius: 50%;
  background: var(--pd-surface);
  box-shadow: none;
  color: var(--color-text);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.24s var(--pd-ease);
}
.sage-pd-x:hover { border-color: var(--olive-700); }

.sage-pd-detail {
  display: grid;
  grid-template-columns: 0.85fr 1fr;
  gap: clamp(1.5rem, 3.5vw, 3rem);
  padding: clamp(1.25rem, 3vw, 2.25rem);
  align-items: start;
}
.sage-pd-detail[hidden] { display: none; }
@media (max-width: 940px) { .sage-pd-detail { grid-template-columns: 1fr; } }
/* The spec column runs much taller than the gallery, so the gallery sticks
   rather than leaving a screen of empty space beside the accordions. */
@media (min-width: 941px) { .sage-pd-gal { position: sticky; top: 4.5rem; } }

.sage-pd-gal-main {
  border: 1px solid var(--color-border);
  border-radius: 3px;
  overflow: hidden;
  background: var(--pd-sunk);
  aspect-ratio: 1 / 1.5;
}
.sage-pd-gal-main img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sage-pd-gal-main--door { display: grid; place-items: center; aspect-ratio: 1 / 1.2; }
.sage-pd-gal-door {
  display: block;
  width: 42%;
  max-width: 150px;
  aspect-ratio: 1 / 2;
  background-color: var(--c);
  border: 1px solid var(--color-border);
  box-shadow: var(--pd-sh-md);
}
.sage-pd-gal-door img { display: block; width: 100%; height: 100%; object-fit: cover; }

.sage-pd-thumbs {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 0.55rem;
  margin-top: 0.55rem;
}
.sage-pd-thumb {
  padding: 0;
  margin: 0;
  min-height: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm, 2px);
  background: var(--pd-sunk);
  box-shadow: none;
  overflow: hidden;
  aspect-ratio: 1 / 1.5;
  cursor: pointer;
  transition: border-color 0.24s var(--pd-ease), box-shadow 0.24s var(--pd-ease);
}
.sage-pd-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sage-pd-thumb[aria-current="true"] {
  border-color: var(--olive-700);
  box-shadow: 0 0 0 1px var(--olive-700);
}
.sage-pd-render-note,
.sage-fin-render-note {
  margin: 0.85rem 0 0;
  font-size: 0.75rem;
  color: var(--color-text-muted);
}
.sage-pd-gal-act { margin-top: 1rem; display: flex; flex-wrap: wrap; gap: 0.7rem; }

.sage-pd-eyebrow {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--olive-600);
  margin: 0 0 0.5rem;
}
.sage-pd-spec > h3 {
  font-family: var(--font-display);
  font-size: clamp(1.8rem, 4vw, 2.75rem);
  line-height: var(--leading-heading);
  color: var(--color-heading);
  margin: 0;
}
.sage-pd-sub { margin: 0.3rem 0 0; font-size: 0.9375rem; color: var(--color-text-muted); }
.sage-pd-desc { margin: 1rem 0 0; font-size: 0.9375rem; max-width: 56ch; }

.sage-pd-sect {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  font-family: var(--font-display);
  font-size: 1.25rem;
  color: var(--color-heading);
  margin: 1.75rem 0 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--color-border);
}
.sage-pd-sect i {
  font-style: normal;
  font-family: var(--font-body);
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-left: auto;
}

/* CNC shows the SKU above the door and the name below; the SKU is what a quote
   references, so it is not decorative. */
.sage-pd-fins {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.15rem 0.8rem;
  align-items: start;
}
@media (max-width: 700px) { .sage-pd-fins { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 460px) { .sage-pd-fins { grid-template-columns: repeat(2, 1fr); } }
.sage-pd-fin { display: flex; flex-direction: column; margin: 0; }
.sage-pd-sku {
  display: block;
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  color: var(--color-text-muted);
  margin: 0 0 0.35rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
/* The sampled mean colour of the door sits behind the photograph, so the cell
   is never blank while loading and degrades to a correct flat chip if the image
   fails — see this file's header. */
.sage-pd-sw {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 2;
  background-color: var(--c);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm, 2px);
  overflow: hidden;
}
.sage-pd-sw img { display: block; width: 100%; height: 100%; object-fit: cover; }
.sage-pd-sw[data-noart] { border-style: dashed; }
/* Door-only art (no drawer front above the door): no placeholder colour and
   no box, or the empty top reads as a flat painted drawer. The door keeps an
   edge from a drop-shadow, which follows the image's own outline. */
.sage-pd-sw.is-dooronly {
  background: none;
  border-color: transparent;
}
.sage-pd-sw.is-dooronly img { filter: drop-shadow(0 0 0.6px rgba(28, 28, 24, 0.45)); }
.sage-pd-fin figcaption {
  font-size: 0.8125rem;
  color: var(--color-heading);
  margin-top: 0.4rem;
  line-height: 1.3;
  /* Reserved so a Plus tag on one tile cannot shift its neighbour's baseline. */
  min-height: 2.6em;
}
/* NOT gold. --gold-700 is the deepest bronze in the ramp and still measures
   only 4.14:1 on --bone, under the 4.5:1 AA minimum -- measured on staging,
   not assumed. Gold survives on a light ground as hairlines and non-text
   decoration; gold TEXT needs an olive-800/900 ground. --olive-600 is 6.78:1
   here and still reads as subordinate to the finish name above it. */
.sage-pd-tier,
.sage-pd-sheen {
  display: block;
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--olive-600);
  margin-top: 0.1rem;
}
.sage-pd-note {
  margin: 0.9rem 0 0;
  padding: 0.7rem 0.95rem;
  font-size: 0.8125rem;
  color: var(--color-text-muted);
  background: var(--pd-sunk);
  border-left: 2px solid var(--gold-500);
}
.sage-pd-note--alt { border-left-color: var(--olive-500); }
.sage-pd-unpub { font-size: 0.8125rem; color: var(--color-text-muted); margin: 0.25rem 0 0; }

.sage-pd-pairs { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; }
.sage-pd-pairs span {
  display: block;
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: 0.3rem;
}
.sage-pd-pairs b {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.125rem;
  color: var(--color-heading);
}

.sage-pd-accs { margin-top: 1.35rem; }
.sage-pd-acc {
  border: 0;
  border-top: 1px solid var(--color-border);
  margin: 0;
  padding: 0;
  background: none;
  box-shadow: none;
}
.sage-pd-acc:last-of-type { border-bottom: 1px solid var(--color-border); }
.sage-pd-acc > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.95rem 0;
  margin: 0;
  background: none;
  border: 0;
  font-family: var(--font-display);
  font-size: 1.125rem;
  color: var(--color-heading);
}
.sage-pd-acc > summary::-webkit-details-marker { display: none; }
.sage-pd-acc > summary::marker { content: none; }
.sage-pd-acc > summary i {
  position: relative;
  width: 1.5rem;
  height: 1.5rem;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--pd-badge-bg);
  transition: background 0.24s var(--pd-ease);
}
.sage-pd-acc > summary i::before,
.sage-pd-acc > summary i::after {
  content: "";
  position: absolute;
  background: var(--pd-badge-fg);
  transition: transform 0.24s var(--pd-ease), opacity 0.2s var(--pd-ease),
              background 0.24s var(--pd-ease);
}
.sage-pd-acc > summary i::before {
  top: 50%; left: 30%; width: 40%; height: 1.2px; transform: translateY(-50%);
}
.sage-pd-acc > summary i::after {
  left: 50%; top: 30%; height: 40%; width: 1.2px; transform: translateX(-50%);
}
.sage-pd-acc[open] > summary i { background: var(--olive-800); }
.sage-pd-acc[open] > summary i::before,
.sage-pd-acc[open] > summary i::after { background: #fff; }
.sage-pd-acc[open] > summary i::after { opacity: 0; }
.sage-pd-acc-in { padding: 0 0 1rem; }
.sage-pd-acc-in p { margin: 0; font-size: 0.875rem; }
.sage-pd-acc-in dl {
  margin: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.55rem 1.1rem;
  font-size: 0.875rem;
}
.sage-pd-acc-in dt { font-weight: 500; color: var(--color-heading); white-space: nowrap; }
.sage-pd-acc-in dd { margin: 0; color: var(--color-text-muted); }
@media (max-width: 560px) {
  .sage-pd-acc-in dl { grid-template-columns: 1fr; gap: 0.15rem 0.5rem; }
  .sage-pd-acc-in dd { margin-bottom: 0.5rem; }
}
.sage-pd-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  margin-top: 1.75rem;
  padding-top: 1.35rem;
  border-top: 1px solid var(--color-border);
}

/* ==========================================================================
   VERSION B — the finish library
   ==========================================================================
   No counts, no result total, no sort, no checkboxes. Counts are what make a
   panel read as inventory rather than a showroom; the premium reference set
   (Mutina, Kvadrat, Farrow & Ball) omits them. */

.sage-fin-tools {
  padding-bottom: 1rem;
  margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
  border-bottom: 1px solid var(--color-border);
}
.sage-fin-trow {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem 1.5rem;
  align-items: baseline;
}
.sage-fin-trow + .sage-fin-trow { margin-top: 0.55rem; }
.sage-fin-tlbl {
  min-width: 5.5rem;
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.sage-fin-opts { display: flex; flex-wrap: wrap; gap: 0.35rem 1.15rem; }
.sage-fin-opt {
  position: relative;
  margin: 0;
  padding: 0.15rem 0;
  min-height: 0;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  font: inherit;
  font-size: 0.875rem;
  color: var(--color-text-muted);
  cursor: pointer;
  transition: color 0.2s var(--pd-ease);
}
/* The underline draws in from the left on hover and retracts to the right on
   leave — asymmetry is what separates a designed hover from a default one. */
.sage-fin-opt::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s var(--pd-ease);
}
.sage-fin-opt:hover { color: var(--color-heading); }
.sage-fin-opt:hover::after { transform: scaleX(1); }
.sage-fin-opt:not(:hover)::after { transform-origin: right; transition-duration: 0.22s; }
.sage-fin-opt[aria-pressed="true"] { color: var(--color-heading); font-weight: 500; }
.sage-fin-opt[aria-pressed="true"]::after {
  transform: scaleX(1);
  background: var(--olive-500);
}

.sage-fin-line { margin-bottom: clamp(2.5rem, 6vw, 4.5rem); }
.sage-fin-line:last-of-type { margin-bottom: 0; }
.sage-fin-line[hidden] { display: none; }

.sage-fin-hd {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.4rem 2.5rem;
  align-items: baseline;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--color-border);
  margin-bottom: 1.5rem;
}
@media (max-width: 760px) { .sage-fin-hd { grid-template-columns: 1fr; } }
.sage-fin-hd > :first-child {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3.2vw, 2.2rem);
  line-height: var(--leading-heading);
  color: var(--color-heading);
  margin: 0;
}
.sage-fin-cnc { font-size: 0.8125rem; color: var(--color-text-muted); }
.sage-fin-desc {
  grid-column: 1 / -1;
  margin: 0.3rem 0 0;
  font-size: 0.875rem;
  color: var(--color-text-muted);
  max-width: 66ch;
}
.sage-fin-meta {
  grid-column: 1 / -1;
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--olive-600);
  margin-top: 0.35rem;
}

/* FENIX's rule: the door is a portrait object, so the tile is portrait — but at
   desktop it takes a FIXED height so tiles stay physically comparable as the
   column count drops. Never auto-fill. */
.sage-fin-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  column-gap: clamp(0.45rem, 1vw, 0.8rem);
  row-gap: clamp(1.4rem, 2.4vw, 2rem);
}
@media (max-width: 1180px) { .sage-fin-grid { grid-template-columns: repeat(7, 1fr); } }
@media (max-width: 1000px) { .sage-fin-grid { grid-template-columns: repeat(6, 1fr); } }
@media (max-width: 820px)  { .sage-fin-grid { grid-template-columns: repeat(5, 1fr); } }
@media (max-width: 640px)  { .sage-fin-grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 440px)  { .sage-fin-grid { grid-template-columns: repeat(3, 1fr); } }

.sage-fin-sw { display: flex; flex-direction: column; }
.sage-fin-fr {
  position: relative;
  display: block;
  aspect-ratio: 1 / 1.7;
  overflow: hidden;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm, 2px);
  background-color: var(--c);
  transition: box-shadow 0.3s var(--pd-ease);
}
@media (min-width: 821px) { .sage-fin-fr { aspect-ratio: auto; height: 190px; } }

/* Pluck's move: a flat colour chip becomes a photograph of that colour on a
   whole kitchen. The image is in the DOM at rest so it is crawlable and can be
   found with Ctrl-F; only its opacity changes. */
.sage-fin-room {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.04);
  transition: opacity 0.5s var(--pd-ease), transform 0.7s var(--pd-ease);
}
@media (hover: hover) and (pointer: fine) {
  .sage-fin-sw:hover .sage-fin-fr,
  .sage-fin-sw:focus-within .sage-fin-fr { box-shadow: var(--pd-sh-lg); }
  .sage-fin-sw:hover .sage-fin-room,
  .sage-fin-sw:focus-within .sage-fin-room { opacity: 1; transform: none; }
  .sage-fin-sw:hover { z-index: 2; }
}
/* Farrow & Ball's own fallback: a finish with no honest room photograph says so
   rather than showing another colour's kitchen. */
.sage-fin-sw--noroom .sage-fin-fr::after {
  content: "Showroom";
  position: absolute;
  inset: auto 0 0 0;
  padding: 0.3rem;
  font-size: 0.5625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: center;
  color: #fff;
  background: rgba(20, 21, 14, 0.55);
  opacity: 0;
  transition: opacity 0.3s var(--pd-ease);
}
@media (hover: hover) and (pointer: fine) {
  .sage-fin-sw--noroom:hover .sage-fin-fr::after { opacity: 1; }
}

.sage-fin-cap {
  display: flex;
  flex-direction: column;
  margin-top: 0.5rem;
  /* Reserved so a Plus or sheen tag cannot shift a neighbour's baseline. */
  min-height: 3.1rem;
}
.sage-fin-sku {
  display: block;
  font-size: 0.5625rem;
  letter-spacing: 0.06em;
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}
.sage-fin-nm {
  display: block;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--color-heading);
  line-height: 1.3;
  margin-top: 0.1rem;
}
/* --olive-600, not --gold-700: see the note on .sage-pd-tier. Gold on bone is
   4.14:1 and fails AA for text at any size this small. */
.sage-fin-tier {
  display: block;
  min-height: 1em;
  font-size: 0.5625rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--olive-600);
  margin-top: 0.05rem;
}
.sage-fin-note {
  margin: 1.5rem 0 0;
  padding: 0.75rem 0.95rem;
  font-size: 0.8125rem;
  color: var(--color-text-muted);
  background: var(--pd-sunk);
  border-left: 2px solid var(--gold-500);
  max-width: 70ch;
}
.sage-fin-hint {
  margin: 0.75rem 0 0;
  font-size: 0.75rem;
  color: var(--color-text-muted);
  max-width: 70ch;
}
.sage-fin-render-note { margin-top: clamp(2rem, 4vw, 3rem); }

/* ==========================================================================
   The review-only version switcher

   One grep from deletion: remove every .sage-vswitch rule together with
   sage_version_switch_shortcode() once a version is chosen.
   ========================================================================== */
.sage-vswitch {
  position: fixed;
  /* Bottom-RIGHT, not centred: centred it sat over the middle column of both
     grids and covered a card's own text. The right gutter is empty on every
     breakpoint here. */
  bottom: 1rem;
  right: clamp(1rem, 3vw, 2rem);
  z-index: 500;
  display: flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.3rem;
  background: var(--pd-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full, 999px);
  box-shadow: var(--pd-sh-lg);
  font-size: 0.75rem;
}
.sage-vswitch b {
  padding: 0 0.6rem 0 0.75rem;
  font-family: var(--font-body);
  font-size: 0.5625rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.sage-vswitch a {
  padding: 0.42rem 0.95rem;
  border-radius: var(--radius-full, 999px);
  color: var(--color-text);
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.2s var(--pd-ease), color 0.2s var(--pd-ease);
}
.sage-vswitch a[aria-current] {
  background: var(--olive-800);
  color: #fff;
  font-weight: 500;
}
.sage-vswitch a:not([aria-current]):hover { background: var(--pd-badge-bg); }
@media (max-width: 560px) {
  .sage-vswitch b { display: none; }
  .sage-vswitch {
    font-size: 0.6875rem;
    /* Full-width strip on a phone: a floating pill in the corner covers a
       swatch, and there is no empty gutter to put it in. */
    right: 0.75rem;
    left: 0.75rem;
    justify-content: center;
  }
}

/* ==========================================================================
   Reduced motion

   Not a blanket kill: the preference targets vestibular triggers — travel,
   parallax, zoom — and opacity still carries meaning. Movement goes, fades
   stay, and the hover reveal is disabled entirely because it cannot be read
   without the transition.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .sage-pd *,
  .sage-fin *,
  .sage-vswitch * {
    animation: none !important;
    transition-duration: 0.01ms !important;
  }
  .sage-pd-card:hover { transform: none; }
  .sage-pd-card:hover .sage-pd-shot img { transform: none; }
  .sage-pd-chev { transform: none !important; }
  .sage-fin-room { transform: none; }
}

/* ===================================================================
   Line pages -- /cabinet-products/<line>/
   One indexable page per door line. See product-line.php for why these
   exist and why they are line-level rather than finish-level.
   =================================================================== */

/* Page 825's own intro and FAQ are written for the catalogue index; on a line
   page they would be the same boilerplate on 15 URLs, which is the pattern
   these pages exist to avoid. The catalogue section keeps its padding because
   it is the one holding the line content. */
body.sage-line-page .sage-pd-lede,
body.sage-line-page [class*="sage-eyebrow"]:first-of-type {
  display: none;
}
/* NOT `#content > .section:first-of-type` -- the line markup is rendered
   INSIDE page 825's first section, so that selector hid every line page
   whole: H1, rooms, finishes, all at 0px, footer only. Found 2026-10-13 from
   the owner's phone; the earlier verification counted DOM nodes, not
   rendered height. The duplicate-H1 strip happens on the_content
   (sage_line_strip_sections), which is the only place it should. */
body.sage-line-page .section:has(.sage-pd-faq) {
  display: none;
}

.sage-pl {
  max-width: 1100px;
  margin: 0 auto;
}

.sage-pl-crumb {
  font-size: 0.8125rem;
  color: var(--stone);
  margin-bottom: 1.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
}
.sage-pl-crumb a { color: var(--olive-600); text-decoration: none; }
.sage-pl-crumb a:hover { text-decoration: underline; }
.sage-pl-crumb span[aria-hidden] { color: var(--color-border); }

.sage-pl-hd { margin-bottom: clamp(2rem, 5vw, 3rem); }
.sage-pl-hd h1 {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 4.5vw, 3rem);
  line-height: 1.12;
  margin: 0.35rem 0 0.75rem;
}
.sage-pl-sub {
  font-size: 0.9375rem;
  color: var(--stone);
  margin: 0 0 1rem;
}
.sage-pl-desc { max-width: 62ch; margin: 0; }

.sage-pl-sec { margin-bottom: clamp(2.5rem, 6vw, 4rem); }
.sage-pl-sec > h2,
.sage-pl-cta h2,
.sage-pl-sib h2 {
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 2.8vw, 1.9rem);
  margin: 0 0 0.5rem;
}
.sage-pl-note {
  font-size: 0.8125rem;
  color: var(--stone);
  margin: 0 0 1.25rem;
}

/* Room renders. Fixed column counts rather than auto-fill + a small minmax
   floor: that combination once produced seven 158px columns at 1440px, and the
   plates are 1:2 portrait so a narrow column is unreadable. */
.sage-pl-rooms {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(0.75rem, 1.5vw, 1.25rem);
}
@media (max-width: 1100px) { .sage-pl-rooms { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 760px)  { .sage-pl-rooms { grid-template-columns: repeat(2, 1fr); } }
.sage-pl-rooms figure { margin: 0; }
.sage-pl-rooms img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 3px;
  background: var(--bone);
}
.sage-pl-rooms figcaption {
  font-size: 0.8125rem;
  color: var(--stone);
  margin-top: 0.4rem;
}

.sage-pl-fins {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: clamp(0.75rem, 1.5vw, 1.25rem);
}
@media (max-width: 1100px) { .sage-pl-fins { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 700px)  { .sage-pl-fins { grid-template-columns: repeat(3, 1fr); } }
.sage-pl-fin { margin: 0; }
.sage-pl-sw {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 3px;
  overflow: hidden;
  background-color: var(--sw, var(--bone));
}
.sage-pl-sw img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sage-pl-fin figcaption { margin-top: 0.4rem; line-height: 1.3; }
.sage-pl-fin b {
  display: block;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--color-heading);
}
.sage-pl-fin span {
  display: block;
  font-size: 0.75rem;
  color: var(--stone);
}

.sage-pl-pairs {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.75rem 2rem;
  margin: 0 0 1.5rem;
}
@media (max-width: 700px) { .sage-pl-pairs { grid-template-columns: 1fr; } }
.sage-pl-pairs dt {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--olive-600);
  margin: 0;
}
.sage-pl-pairs dd { margin: 0.15rem 0 0; }

.sage-pl-cta {
  background: var(--bone);
  border-radius: 4px;
  padding: clamp(1.5rem, 4vw, 2.5rem);
  margin-bottom: clamp(2rem, 5vw, 3rem);
}
.sage-pl-cta p { max-width: 62ch; }

.sage-pl-sib ul {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.75rem;
}
@media (max-width: 900px) { .sage-pl-sib ul { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .sage-pl-sib ul { grid-template-columns: 1fr; } }
/* Flatsome styles every <li> through .entry-content ul -- an indent plus a
   decorative left border that renders as a gold rule between cells. Zeroed on
   this component's own class, same as the door grid. */
.sage-pl-sib li {
  margin: 0;
  padding: 0;
  border: 0;
  list-style: none;
}
.sage-pl-sib a {
  display: block;
  padding: 0.85rem 1rem;
  border: 1px solid var(--color-border);
  border-radius: 3px;
  text-decoration: none;
  background: var(--bone);
}
.sage-pl-sib a:hover { border-color: var(--olive-600); }
.sage-pl-sib b {
  display: block;
  color: var(--color-heading);
  font-size: 0.9375rem;
}
.sage-pl-sib span {
  display: block;
  font-size: 0.8125rem;
  color: var(--stone);
}

/* The card foot is now a link to the line page rather than a label. Styled to
   read as the same affordance it was -- the click still opens the dialog. */
.sage-pd-more {
  color: inherit;
  text-decoration: none;
  font: inherit;
}
.sage-pd-more:hover { text-decoration: underline; }

/* CNC brand page collection ladder */
.sage-cnc-ladder {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.5rem, 3vw, 2.5rem);
}
@media (max-width: 760px) { .sage-cnc-ladder { grid-template-columns: 1fr; } }
.sage-cnc-coll {
  background: var(--bone);
  border-radius: 4px;
  padding: clamp(1.25rem, 3vw, 1.75rem);
}
.sage-cnc-coll h3 {
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 2.4vw, 1.6rem);
  margin: 0 0 0.5rem;
}
.sage-cnc-coll > p { margin: 0 0 1rem; }
.sage-cnc-lines {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem;
}
@media (max-width: 480px) { .sage-cnc-lines { grid-template-columns: 1fr; } }
/* Flatsome styles every <li> through .entry-content ul -- indent plus a
   decorative left border. Zeroed on this component's own class. */
.sage-cnc-lines li { margin: 0; padding: 0; border: 0; list-style: none; }
.sage-cnc-lines a {
  display: block;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: 3px;
  text-decoration: none;
  background: #fff;
}
.sage-cnc-lines a:hover { border-color: var(--olive-600); }
.sage-cnc-lines b { display: block; font-size: 0.9375rem; color: var(--color-heading); }
.sage-cnc-lines span { display: block; font-size: 0.8125rem; color: var(--stone); }

/* Grouped door-style filter -- see sage_products_style_groups() for why the
   names inside are unchanged. */
.sage-pd-fopts--grouped { display: block; }
.sage-pd-fam { border-left: 2px solid var(--color-border); margin: 0 0 0.35rem; padding-left: 0.6rem; }
.sage-pd-fam[open] { border-left-color: var(--olive-600); }
.sage-pd-fam > summary {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
  list-style: none;
  padding: 0.3rem 0;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--color-heading);
}
.sage-pd-fam > summary::-webkit-details-marker { display: none; }
.sage-pd-fam-name { flex: 1; }
.sage-pd-fam > summary i {
  width: 7px; height: 7px;
  border-right: 1.5px solid var(--stone);
  border-bottom: 1.5px solid var(--stone);
  transform: rotate(45deg);
  transition: transform 0.15s ease;
  flex: none;
}
.sage-pd-fam[open] > summary i { transform: rotate(-135deg); }
.sage-pd-fam-blurb {
  font-size: 0.75rem;
  line-height: 1.4;
  color: var(--stone);
  margin: 0.1rem 0 0.5rem;
}
.sage-pd-fam .sage-pd-fopt { padding-left: 0.1rem; }
@media (max-width: 900px) {
  /* Declared after the breakpoint block above, so these win on specificity
     order rather than on the query -- the pattern this file already documents. */
  .sage-pd-fopts--grouped { display: block; }
}
/* A family with an active filter inside it, marked so the state reads at a
   glance rather than only when expanded. */
.sage-pd-fam.is-active > summary .sage-pd-fam-name::after {
  content: "";
  display: inline-block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--olive-600);
  margin-left: 0.4rem;
  vertical-align: middle;
}

/* ==========================================================================
   THE TIER LADDER — "What changes between the tiers" (2026-10-12)
   ==========================================================================
   Sits at the top of .sage-pd-main, before the first collection. One
   photographed cabinet with numbered markers, the numbered callouts beside
   it, then the four collections as a ladder. Editorial: no card chrome, no
   radii, the bone ground shows through the WebP's alpha.

   Marker positions come from the markup as --x / --y percentages of the
   image box; see the note on sage_products_tiers() before re-cropping. */
.sage-pd-tiers {
  margin: 0 0 clamp(3.5rem, 7vw, 5.5rem);
  padding: 0 0 clamp(3rem, 6vw, 4.5rem);
  border-bottom: 1px solid var(--greige);
}
.sage-pd-tiers-hd { max-width: 44rem; }
.sage-pd-tiers-hd h2,
.sage-pd-tiers-hd h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.7rem, 3vw, 2.4rem);
  line-height: 1.15;
  color: var(--olive-900);
  margin: 0.7rem 0 0;
}
.sage-pd-tiers-intro {
  margin: 1.2rem 0 0;
  color: var(--stone);
  line-height: 1.75;
  max-width: 40rem;
}

/* --- the cutaway --------------------------------------------------------- */
.sage-pd-cut {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: center;
  margin: clamp(2rem, 4vw, 3rem) 0 0;
}
.sage-pd-cut-img { position: relative; }
.sage-pd-cut-img img { display: block; width: 100%; height: auto; }
/* Markers: a number in an olive disc. White on --olive-800 is 9.73:1. The
   translate centres the disc on the point so --x/--y name the thing, not
   the disc's corner. */
.sage-pd-cut-mk {
  position: absolute;
  left: var(--x);
  top: var(--y);
  transform: translate(-50%, -50%);
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--olive-800);
  color: #fff;
  font: 600 0.75rem/28px var(--font-body);
  text-align: center;
  box-shadow: 0 0 0 3px var(--bone);
}
.sage-pd-cut-cap { margin: 0; }
.sage-pd-cut-list {
  list-style: none;
  counter-reset: cut;
  margin: 0;
  padding: 0;
}
.sage-pd-cut-list li {
  counter-increment: cut;
  position: relative;
  margin: 0 0 1.1rem;
  padding: 0 0 0 2.4rem;
  border: 0;
  line-height: 1.65;
  color: var(--ink);
}
.sage-pd-cut-list li::before {
  content: counter(cut);
  position: absolute; left: 0; top: 0.1rem;
  width: 24px; height: 24px;
  border-radius: 50%;
  background: var(--olive-800);
  color: #fff;
  font: 600 0.6875rem/24px var(--font-body);
  text-align: center;
}
.sage-pd-cut-list b { font-weight: 600; color: var(--olive-900); }
.sage-pd-cut-src {
  margin: 1.4rem 0 0;
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  color: var(--stone);
}

/* --- the ladder ---------------------------------------------------------- */
.sage-pd-ladder {
  list-style: none;
  margin: clamp(2.5rem, 5vw, 3.5rem) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.25rem, 3vw, 2.5rem);
}
.sage-pd-ladder li { margin: 0; padding: 0; border: 0; }
.sage-pd-ladder-a {
  display: block;
  text-decoration: none;
  color: inherit;
  padding-top: 1rem;
  border-top: 1px solid var(--greige);
  transition: border-color 0.25s ease;
}
.sage-pd-ladder-a:hover,
.sage-pd-ladder-a:focus-visible { border-top-color: var(--gold-700); }
.sage-pd-ladder-n {
  display: block;
  font-size: 0.6875rem;
  letter-spacing: 0.22em;
  color: var(--stone);
  margin-bottom: 0.6rem;
}
.sage-pd-ladder-plain {
  display: block;
  font-family: var(--font-display);
  font-size: 1.25rem;
  line-height: 1.2;
  color: var(--olive-900);
}
.sage-pd-ladder-name {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.6875rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--olive-600);           /* 6.78:1 on bone; not gold, 4.14:1 */
}
.sage-pd-ladder-fact {
  display: block;
  margin-top: 0.7rem;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--stone);
}

/* The plain-English kicker above each collection heading, so the CNC name
   never stands alone there either. */
.sage-pd-coll-plain {
  margin: 0 0 0.35rem;
  font-size: 0.6875rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--olive-600);
}

@media (max-width: 900px) {
  .sage-pd-ladder { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .sage-pd-cut { grid-template-columns: 1fr; }
}
@media (max-width: 480px) {
  .sage-pd-ladder { grid-template-columns: 1fr; }
}

/* --- door sample below the photograph, not over it (2026-10-13) -----------
   The sample hung over the lower-left of the room photo (bottom: -2.1rem on
   the card-top). The owner wants the kitchen uncovered, so the door's TOP
   now sits at the photo's bottom edge and it stands in the card body beside
   the text; the body's min-height makes room for a 1:2 door at its 76px cap
   (152px + offset) so it never reaches the link row beneath. */
.sage-pd-door {
  top: calc(100% + 0.9rem);
  bottom: auto;
}
.sage-pd-card-body { min-height: 12rem; }
