/* =============================================================================
   58-pdp-frame.css — THE PRODUCT PAGE: FRAME, OPENING AND RHYTHM
   =============================================================================

   Three verified faults on this template, all of them compositional:

   1  IT WAS THE ONLY BODY TEMPLATE THAT OPENED COLD. Shop, blog, cart,
      checkout, account, search and the brand archives all open on the
      composed chapter plate in 20-page-header.css; the PDP went nav ->
      10px breadcrumb strip -> bare grid. It now opens on `.sp-plate`: the
      same grammar — scrimmed photograph, HUD trail, 34x1px accent rule and
      micro-kicker, Fraunces 300 display line with one italic accent word, a
      sentence, a right-hand counterweight with real mass, and a foot index
      on a hairline — in the product's own dialect. It is deliberately NOT
      `.page-banner`: this band's display line speaks for the CHAPTER (the
      family of objects and how it is made), because the piece's own name is
      set forty pixels below it in the summary column and repeating it at
      display size would only stutter.

   2  A ~400px DEAD POCKET AT THE BOTTOM LEFT. The gallery column ran out
      around y=1037 while the summary ran to y=1436. `.sp-maker` closes it
      with content, not with a sticky trick: the note that belongs under a
      photograph of an object — what the material does, and the three things
      you actually do with it — plus the hard facts read out of the
      supplier's own spec block. The layout grid is given explicit rows so
      the summary column spans both and the two columns finish on the same
      line.

   3  "RELATED PRODUCTS" IN THE MOST EXPRESSIVE SLOT ON THE PAGE. The lockup
      around it is already correct (93-coherence.css draws the kicker and the
      right-hand counter); only the words were generic. The template now sets
      the line itself, and the accent word and the full stop are styled here.

   OWNERSHIP. This file owns composition, placement and page rhythm on the
   PDP. It deliberately sets no colour, type or surface on `.product-gallery`
   or on anything inside `.product-info` — those belong to other workstreams.
   The two placement declarations it does make on `.product-info` are grid
   coordinates, which is the only way row two can exist at all.

   Part files load after every media query in main.css, so every breakpoint
   this file needs is restated at the foot of it.
   ========================================================================== */


/* =============================================================================
   1 · THE CHAPTER PLATE
   ========================================================================== */

.sp-plate {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: clamp(44px, 4.4vw, 68px) 0 clamp(46px, 4.2vw, 64px);
  background-color: var(--night-2);

  /* Set per archetype from the template, so 581 products resolve to four
     grounds without this file knowing anything about the catalogue. */
  --sp-ground: url("../../media/journey/04-fire-and-form.webp");
  --sp-ground-pos: 46% 46%;
  --sp-ground-filter: saturate(0.92) contrast(1.06) brightness(1.24);
  --sp-ground-flip: 1;
  --sp-window: 0.26;

  /* The container gutter, so the foot rule starts exactly under the kicker
     rule whatever the viewport is doing. */
  --sp-gutter: max(
    var(--container-padding),
    calc((100% - var(--container-width)) / 2 + var(--container-padding))
  );
}

/* Layer 1 — the photograph. Darkened, never desaturated to mush. */
.sp-plate::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: var(--sp-ground);
  background-repeat: no-repeat;
  background-position: var(--sp-ground-pos);
  background-size: cover;
  filter: var(--sp-ground-filter);
  transform: scaleX(var(--sp-ground-flip));
}

/* Layer 2 — the scrim stack, the grain and the closing hairline. Painted
   top-first, as CSS paints background layers. */
.sp-plate::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;

  background-image:
    /* the closing hairline — brightest under the display type */
    linear-gradient(90deg,
      color-mix(in srgb, var(--color-accent) 34%, transparent) 0%,
      var(--color-border-strong) 24%,
      var(--color-border) 62%,
      transparent 100%),
    /* film grain, so photograph and gradient share one surface */
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)' opacity='0.42'/%3E%3C/svg%3E"),
    /* a low green wash pooling under the display line */
    radial-gradient(58% 130% at 2% 116%,
      color-mix(in srgb, var(--color-primary) 24%, transparent) 0%,
      color-mix(in srgb, var(--color-primary) 6%, transparent) 44%,
      transparent 72%),
    /* the vertical recess: dark under the sticky header, opening through the
       middle, closing again into the page below */
    linear-gradient(180deg,
      color-mix(in srgb, var(--night-2) 82%, transparent) 0%,
      color-mix(in srgb, var(--night-2) 8%, transparent) 42%,
      color-mix(in srgb, var(--night-2) 52%, transparent) 100%),
    /* THE SCRIM. Near-black under the type, a real window across the middle
       third where nothing is set, closing again so the contents plate on the
       right has an edge to stand against. */
    linear-gradient(90deg,
      rgba(9, 15, 11, 0.965) 0%,
      rgba(9, 15, 11, 0.9) 24%,
      rgba(9, 15, 11, calc(var(--sp-window) + 0.28)) 40%,
      rgba(9, 15, 11, var(--sp-window)) 56%,
      rgba(9, 15, 11, calc(var(--sp-window) + 0.2)) 72%,
      rgba(9, 15, 11, 0.76) 88%,
      rgba(9, 15, 11, 0.86) 100%);
  background-repeat: no-repeat, repeat, no-repeat, no-repeat, no-repeat;
  background-position: left bottom, 0 0, 0 0, 0 0, 0 0;
  background-size: 100% 1px, 180px 180px, auto, auto, auto;
  background-blend-mode: normal, soft-light, normal, normal, normal;
}

/* --- The composition -----------------------------------------------------
   col 1                                   col 2
   row 1  trail, kicker, display, sentence the contents rail
   row 2  the foot index, gutter to gutter                                  */

.sp-plate-inner {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(238px, 23vw, 330px);
  column-gap: clamp(30px, 4vw, 72px);
  row-gap: 0;
  align-items: start;
  min-height: clamp(250px, 21vw, 318px);
}

.sp-plate-lede {
  grid-column: 1;
  grid-row: 1;
  min-width: 0;
}

/* --- The trail: HUD text on the top edge --------------------------------- */

.sp-plate .breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 9px;
  max-width: 74ch;
  margin: 0 0 clamp(20px, 2vw, 30px);
  font-family: var(--font-primary);
  font-size: 0.7rem;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  overflow-wrap: anywhere;
  /* The terminal crumb is a bare text node in the WooCommerce output, so the
     emphasis lives on the nav and the ancestors step down from it. */
  color: color-mix(in srgb, var(--ink) 74%, transparent);
}

.sp-plate .breadcrumb a {
  color: color-mix(in srgb, var(--ink) 50%, transparent);
  font-weight: 500;
  text-decoration: none;
  padding-bottom: 3px;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: left bottom;
  background-size: 0% 1px;
  transition:
    color 0.32s cubic-bezier(0.2, 0.75, 0.2, 1),
    background-size 0.42s cubic-bezier(0.2, 0.75, 0.2, 1);
}

.sp-plate .breadcrumb a:hover,
.sp-plate .breadcrumb a:focus-visible {
  color: var(--color-accent);
  background-size: 100% 1px;
  outline: none;
}

.sp-plate .breadcrumb .sep {
  color: color-mix(in srgb, var(--ink) 26%, transparent);
  font-size: 0.86rem;
  line-height: 1;
}

/* --- The micro-kicker: the hero's signature ------------------------------ */

.sp-plate-kicker {
  margin: 0 0 clamp(16px, 1.7vw, 24px);
  padding-left: 47px;               /* 34px rule + 13px gap, as the hero */
  background-image: linear-gradient(90deg,
    var(--color-accent) 0%,
    color-mix(in srgb, var(--color-accent) 26%, transparent) 100%);
  background-repeat: no-repeat;
  background-position: left 0.52em;
  background-size: 34px 1px;
  font-family: var(--font-primary);
  font-size: 0.7rem;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--color-text-light);
}

.sp-plate-kicker-sep {
  margin: 0 0.28em;
  color: color-mix(in srgb, var(--ink) 30%, transparent);
}

/* --- The display line ---------------------------------------------------- */

.sp-plate-line {
  max-width: 17ch;
  margin: 0;
  font-family: var(--font-heading);
  font-optical-sizing: auto;
  font-size: clamp(2.3rem, 3.9vw, 4.1rem);
  font-weight: 300;
  line-height: 0.98;
  letter-spacing: -0.045em;
  color: var(--ink);
  text-wrap: balance;
  overflow-wrap: break-word;
  text-shadow: 0 6px 44px rgba(3, 7, 4, 0.62);
}

/* The one accent moment, borrowed from the hero's "becomes *tea*."
   Fraunces is loaded without an italic face, so this is a synthetic slant and
   the final glyph leans into the word-space after it — "finished by" closes
   up to "finishedby". The trailing padding hands that space back without
   touching the tracking. Every accent word on this page gets it. */
.sp-plate-line em {
  font-style: italic;
  padding-right: 0.09em;
  color: var(--color-accent);
}

.sp-plate-stop { color: var(--ink); }

.sp-plate-copy {
  max-width: 42ch;
  margin: clamp(20px, 2vw, 30px) 0 0;
  font-family: var(--font-primary);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.62;
  letter-spacing: 0.004em;
  color: color-mix(in srgb, var(--ink) 60%, transparent);
  text-wrap: pretty;
}

/* --- The counterweight: the contents rail --------------------------------
   The right half of a header band is never left as empty field — that has
   been a repeated critic rejection. Here it carries the one thing a product
   page can honestly promise up front: what is further down it. */

.sp-plate-contents {
  grid-column: 2;
  grid-row: 1;
  align-self: start;
  padding: clamp(15px, 1.4vw, 20px) clamp(16px, 1.5vw, 22px) clamp(6px, 0.7vw, 10px);
  border: 1px solid color-mix(in srgb, var(--ink) 13%, transparent);
  border-radius: var(--radius-md);
  background-color: color-mix(in srgb, var(--night-2) 66%, transparent);
  -webkit-backdrop-filter: blur(7px) saturate(1.08);
  backdrop-filter: blur(7px) saturate(1.08);
  box-shadow:
    0 30px 64px -34px rgba(0, 0, 0, 0.9),
    inset 0 1px 0 color-mix(in srgb, var(--ink) 8%, transparent);
}

.sp-contents-label {
  margin: 0 0 clamp(10px, 1vw, 14px);
  padding-bottom: clamp(10px, 1vw, 14px);
  border-bottom: 1px solid color-mix(in srgb, var(--ink) 12%, transparent);
  font-family: var(--font-primary);
  font-size: 0.7rem;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--ink) 46%, transparent);
}

.sp-contents-list {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: none;
}

.sp-contents-list li + li {
  border-top: 1px solid color-mix(in srgb, var(--ink) 8%, transparent);
}

.sp-contents-list a {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 13px;
  padding: 11px 0;
  text-decoration: none;
  color: inherit;
}

.sp-contents-n {
  font-family: var(--font-primary);
  font-size: 0.7rem;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0.1em;
  font-variant-numeric: tabular-nums;
  color: color-mix(in srgb, var(--ink) 34%, transparent);
  transition: color 0.36s cubic-bezier(0.2, 0.75, 0.2, 1);
}

.sp-contents-t {
  font-family: var(--font-primary);
  font-size: 0.82rem;
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: 0.008em;
  color: color-mix(in srgb, var(--ink) 76%, transparent);
  transition: color 0.36s cubic-bezier(0.2, 0.75, 0.2, 1);
}

.sp-contents-list a::after {
  content: "\2193";                 /* down, because every target is below */
  font-family: var(--font-primary);
  font-size: 0.76rem;
  line-height: 1.3;
  color: color-mix(in srgb, var(--ink) 22%, transparent);
  transform: translateY(0);
  transition:
    color 0.36s cubic-bezier(0.2, 0.75, 0.2, 1),
    transform 0.44s cubic-bezier(0.2, 0.75, 0.2, 1);
}

.sp-contents-list a:hover .sp-contents-t,
.sp-contents-list a:focus-visible .sp-contents-t { color: var(--color-accent); }
.sp-contents-list a:hover .sp-contents-n,
.sp-contents-list a:focus-visible .sp-contents-n { color: color-mix(in srgb, var(--ink) 62%, transparent); }
.sp-contents-list a:hover::after,
.sp-contents-list a:focus-visible::after {
  color: var(--color-accent);
  transform: translateY(3px);
}
.sp-contents-list a:focus-visible { outline: none; }

/* --- The foot index ------------------------------------------------------
   The hard facts, set behind the hero's own 34x1px accent rule so the band
   closes on the same signature it opened with. */

.sp-plate-foot {
  grid-column: 1 / -1;
  grid-row: 2;
  margin: clamp(30px, 3.2vw, 48px) 0 0;
  padding-top: 15px;
  text-indent: 47px;
  background-image:
    linear-gradient(90deg,
      var(--color-accent) 0%,
      color-mix(in srgb, var(--color-accent) 22%, transparent) 100%),
    linear-gradient(90deg,
      var(--color-border-strong) 0%,
      color-mix(in srgb, var(--color-border) 70%, transparent) 58%,
      transparent 100%);
  background-repeat: no-repeat, no-repeat;
  background-position: left top, left top;
  background-size: 34px 1px, 100% 1px;
  font-family: var(--font-primary);
  font-size: 0.7rem;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}


/* =============================================================================
   2 · THE LAYOUT GRID — two columns that finish on the same line
   -----------------------------------------------------------------------------
   Row one is the gallery, sized to its own content and never taller. Row two
   is the maker's note, which absorbs whatever slack the summary column's
   span creates. The summary spans both. That is what closes the pocket: the
   left column is now as tall as the right one BY CONSTRUCTION rather than by
   sticking something to the viewport.
   ========================================================================== */

.single-product-page {
  padding-top: clamp(46px, 4.4vw, 72px);
  padding-bottom: clamp(64px, 6vw, 96px);
}

.single-product-page .single-product-layout {
  grid-template-rows: max-content auto;
  row-gap: clamp(28px, 3vw, 46px);
  align-items: start;
}

/* NOT `grid-row: 1 / 3` and NOT `grid-column: 2`. Naming column two would
   couple this file to whatever width 60-gallery.css happens to stack the
   layout at, and the two would fall out of step the moment either moved. A
   SPAN carries no column, so auto-placement resolves it correctly in both
   states: two columns -> gallery r1c1, summary r1c2 over both rows, note
   r2c1; one column -> gallery, summary, note, in DOM order, no overlap. */
.single-product-page .single-product-layout > .product-info {
  grid-row: span 2;
}

.single-product-page .single-product-layout > .sp-maker {
  grid-column: 1;
  align-self: stretch;
}

/* The gallery's sticky offset is now inert — row one is `max-content`, so its
   grid area is exactly its own height and there is nothing for it to travel
   through. Left in place rather than unset: the declaration belongs to the
   gallery's own stylesheet, and a column this full has no business sticking. */


/* =============================================================================
   3 · THE MAKER'S NOTE — the resolution of the gallery column
   ========================================================================== */

.sp-maker {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: clamp(24px, 2.4vw, 36px);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background-color: var(--color-surface);
  background-image:
    /* the same grain the plate above carries, so the two read as one page */
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)' opacity='0.3'/%3E%3C/svg%3E"),
    radial-gradient(78% 120% at 0% 0%,
      color-mix(in srgb, var(--color-primary) 15%, transparent) 0%,
      color-mix(in srgb, var(--color-primary) 4%, transparent) 42%,
      transparent 74%);
  background-repeat: repeat, no-repeat;
  background-size: 180px 180px, auto;
  background-blend-mode: soft-light, normal;
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--ink) 5%, transparent);
}

.sp-maker-kicker {
  margin: 0 0 clamp(14px, 1.4vw, 20px);
  padding-left: 47px;
  background-image: linear-gradient(90deg,
    var(--color-accent) 0%,
    color-mix(in srgb, var(--color-accent) 26%, transparent) 100%);
  background-repeat: no-repeat;
  background-position: left 0.52em;
  background-size: 34px 1px;
  font-family: var(--font-primary);
  font-size: 0.7rem;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.sp-maker-line {
  max-width: 22ch;
  margin: 0;
  font-family: var(--font-heading);
  font-optical-sizing: auto;
  font-size: clamp(1.5rem, 1.95vw, 2.05rem);
  font-weight: 300;
  line-height: 1.08;
  letter-spacing: -0.034em;
  color: var(--ink);
  text-wrap: balance;
}

.sp-maker-line em {
  font-style: italic;
  padding-right: 0.09em;
  color: var(--color-accent);
}

.sp-maker-stop { color: var(--ink); }

.sp-maker-copy {
  max-width: 58ch;
  margin: clamp(15px, 1.5vw, 21px) 0 0;
  font-family: var(--font-primary);
  font-size: 0.92rem;
  font-weight: 400;
  line-height: 1.72;
  color: var(--color-text);
  text-wrap: pretty;
}

/* --- The photograph that carries the slack --------------------------------
   `flex: 1 1 auto` is the whole mechanism. The summary column's height is not
   knowable from here — a nine-row spec block and a two-row one differ by a
   thousand pixels — so the panel needs one child that grows. A frame that
   grows is a picture; a paragraph that grows is a hole. Captioned in the
   display voice over its own foot scrim, exactly as the chapter plates on
   every other template caption theirs. */

.sp-maker-figure {
  position: relative;
  display: flex;
  align-items: flex-end;
  flex: 1 1 auto;
  /* The floor is deliberately low. When the summary column is short — a tea
     cake whose supplier wrote four lines of prose instead of a nine-row spec
     block — the panel must not overshoot it and open the same pocket on the
     other side; at the floor this is a letterbox band with a caption, and it
     grows to a 640px portrait the moment there is height to take. */
  min-height: clamp(96px, 8vw, 118px);
  margin: clamp(22px, 2.3vw, 30px) 0 0;
  padding: 0 clamp(15px, 1.4vw, 20px) clamp(14px, 1.3vw, 18px);
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent);
  border-radius: var(--radius-md);
  background-color: var(--night-2);
  background-image:
    linear-gradient(180deg,
      rgba(6, 11, 8, 0) 46%,
      rgba(6, 11, 8, 0.36) 66%,
      rgba(6, 11, 8, 0.82) 86%,
      rgba(6, 11, 8, 0.95) 100%),
    url("../../media/journey/06-tea-ceremony.webp");
  background-repeat: no-repeat, no-repeat;
  background-position: center, var(--sp-plate-pos, 50% 54%);
  background-size: cover, cover;
  /* 06-tea-ceremony is the darkest asset in the set by a distance; the page
     headers open it up the same way when they use it as a framed plate. */
  filter: saturate(0.9) contrast(1.04) brightness(1.38);
}

.sp-maker-figure figcaption {
  font-family: var(--font-heading);
  font-optical-sizing: auto;
  font-size: clamp(0.92rem, 0.98vw, 1.04rem);
  font-weight: 300;
  line-height: 1.36;
  letter-spacing: -0.004em;
  color: color-mix(in srgb, var(--ink) 88%, transparent);
  text-shadow: 0 2px 16px rgba(0, 0, 0, 0.8);
  text-wrap: pretty;
}


/* --- Three steps of real practice, indexed --------------------------------
   The site's numbered-set convention: a quiet 01/02/03 in the corner of each
   item, a display-voice title, and one line that earns its place. */

/* Fixed: the figure above takes the slack. An earlier pass had this list
   spread itself instead, which was fine at 150px of overflow and absurd at
   600 — three rules 400px apart read as a broken page, not a generous one. */
.sp-maker-steps {
  flex: 0 0 auto;
  list-style: none;
  margin: clamp(22px, 2.4vw, 32px) 0 0;
  padding: 0;
}

/* Three abreast was the first draft. The gallery column is ~600px wide, which
   left each step a 155px measure — four words a line, five lines a step. A
   ruled list with the index in its own gutter reads at that width, and it
   gives the column the height it is here to supply. */
.sp-maker-step {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  column-gap: 16px;
  padding: 14px 0;
  border-top: 1px solid var(--color-border);
}

.sp-maker-step:last-child { padding-bottom: 0; }

/* Not every product carries a spec block this file can read — a tea cake
   lists "Ingredient" and "Harvest Time", neither of which is origin, material
   or craft — so on those pages the facts line is absent and the list is the
   last thing in the plate. It closes on a rule of its own rather than
   trailing off into the padding. */
.sp-maker-steps:last-child .sp-maker-step:last-child {
  padding-bottom: 14px;
  border-bottom: 1px solid var(--color-border);
}

.sp-step-n {
  grid-column: 1;
  grid-row: 1 / 3;
  display: block;
  padding-top: 0.26em;
  font-family: var(--font-primary);
  font-size: 0.7rem;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.1em;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
}

.sp-step-t {
  grid-column: 2;
  display: block;
  margin-bottom: 5px;
  font-family: var(--font-heading);
  font-optical-sizing: auto;
  font-size: 1.02rem;
  font-weight: 400;
  line-height: 1.24;
  letter-spacing: -0.018em;
  color: var(--color-dark);
}

.sp-step-d {
  grid-column: 2;
  display: block;
  font-family: var(--font-primary);
  font-size: 0.8rem;
  font-weight: 400;
  line-height: 1.6;
  color: var(--color-text-light);
  text-wrap: pretty;
}

/* --- The hard facts, on the foot of the plate ----------------------------
   No `margin-top: auto` here: the step list above already claims the slack,
   and pinning this line to the floor as well only glued it to the last step
   with the whole gap opened above it. */

.sp-maker-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 12px clamp(20px, 2.4vw, 40px);
  margin: clamp(22px, 2.4vw, 34px) 0 0;
  padding-top: clamp(16px, 1.7vw, 24px);
  border-top: 1px solid var(--color-border);
}

.sp-maker-facts .sp-fact { min-width: 0; }

.sp-maker-facts dt {
  margin-bottom: 5px;
  font-family: var(--font-primary);
  font-size: 0.7rem;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.sp-maker-facts dd {
  margin: 0;
  font-family: var(--font-primary);
  font-size: 0.86rem;
  font-weight: 400;
  line-height: 1.45;
  color: var(--color-text);
}


/* =============================================================================
   4 · THE SHELF — the accent word in the display line
   -----------------------------------------------------------------------------
   93-coherence.css already sets this header's grid, its kicker and its
   right-hand counter. All that was missing was the line, and the line needs
   its one italic accent word.
   ========================================================================== */

.single-product-page .sp-related .section-title em {
  font-style: italic;
  padding-right: 0.04em;
  color: var(--color-accent);
}

.single-product-page .sp-related .section-title .sp-related-stop { color: var(--ink); }


/* =============================================================================
   BREAKPOINTS — this file loads last, so it carries its own.
   ========================================================================== */

@media (max-width: 1240px) {
  .sp-plate-inner { grid-template-columns: minmax(0, 1fr) clamp(224px, 25vw, 300px); }
  .sp-plate-line { max-width: 15ch; }
  .sp-plate-copy { max-width: 38ch; }
}

@media (max-width: 1024px) {
  .sp-plate { padding: clamp(42px, 4.6vw, 62px) 0 clamp(46px, 5vw, 62px); }
  .sp-plate-inner {
    grid-template-columns: minmax(0, 1fr) minmax(196px, 30vw);
    column-gap: 28px;
    min-height: 224px;
  }
  .sp-plate-line { font-size: clamp(2.1rem, 4.2vw, 3.1rem); max-width: 14ch; }
  .sp-plate-copy { font-size: 0.95rem; max-width: 34ch; }
  .sp-plate .breadcrumb { max-width: 52ch; }
  .sp-maker { padding: clamp(22px, 2.6vw, 30px); }
}

/* Under ~860px the two-column band stops being honest: there is not enough
   width for a display line AND a plate beside it. The rail becomes the floor
   of the band instead of its right-hand wall — the same move the page header
   makes with its framed photograph. */
@media (max-width: 860px) {
  .sp-plate-inner {
    grid-template-columns: minmax(0, 1fr);
    row-gap: clamp(26px, 3.4vw, 36px);
    min-height: 0;
  }
  .sp-plate-lede { grid-row: 1; }
  .sp-plate-contents { grid-column: 1; grid-row: 2; }
  .sp-plate-foot { grid-column: 1; grid-row: 3; }
  .sp-plate-line { max-width: 16ch; }
  .sp-plate-copy { max-width: 46ch; }
  .sp-contents-list a { padding: 12px 0; }
}

@media (max-width: 768px) {
  .single-product-page .single-product-layout { row-gap: clamp(30px, 5vw, 44px); }
  .sp-plate { padding: 34px 0 40px; }
  .sp-plate-line { font-size: clamp(2rem, 7.4vw, 2.7rem); max-width: 15ch; }
  .sp-plate-copy { font-size: 0.94rem; max-width: 100%; }
  .sp-plate .breadcrumb {
    max-width: 100%;
    margin-bottom: 18px;
    line-height: 1.7;
  }
  .sp-plate-foot { letter-spacing: 0.13em; }
  .single-product-page { padding-top: 30px; }
}

@media (max-width: 600px) {
  .sp-plate-line { font-size: clamp(1.9rem, 8.4vw, 2.4rem); letter-spacing: -0.04em; }
  .sp-plate-kicker,
  .sp-maker-kicker { padding-left: 40px; background-size: 27px 1px; }
  .sp-plate-foot { text-indent: 40px; background-size: 27px 1px, 100% 1px; }
  .sp-maker { padding: 22px 18px; border-radius: var(--radius-md); }
  .sp-maker-line { font-size: 1.42rem; max-width: 100%; }
  .sp-maker-copy { font-size: 0.88rem; }
  .sp-maker-facts { gap: 12px 24px; }
}

@media (max-width: 430px) {
  /* The trail's terminal crumb is a full product name; at this width it is
     three lines of tracked capitals before anything else is read. The band
     keeps the route and drops the destination, which is the h1 below it. */
  .sp-plate .breadcrumb { font-size: 0.7rem; letter-spacing: 0.11em; gap: 7px; }
  .sp-plate-line { font-size: 1.86rem; }
  .sp-plate-copy { font-size: 0.9rem; line-height: 1.6; }
  .sp-plate-foot { font-size: 0.7rem; letter-spacing: 0.1em; line-height: 1.7; }
  .sp-contents-t { font-size: 0.8rem; }
}

/* Reduced motion: the rail's arrow is the only thing here that moves. */
@media (prefers-reduced-motion: reduce) {
  .sp-contents-list a::after,
  .sp-contents-n,
  .sp-contents-t,
  .sp-plate .breadcrumb a { transition: none; }
  .sp-contents-list a:hover::after { transform: none; }
}
