/* ============================================================
   Plants Whisperer — Plant Detail · "One Screen"
   Claude Design: design_handoff_plant_detail_one_screen.

   The whole purchase decision fits one screen: six elements above the fold,
   two disclosures below them, nothing else. Loaded after identity-v2.css and
   catalog.css (the related-plates grid still uses .cat-card). plants/ only.

   Three rules the old sheet broke and this one keeps:
     · object-fit: cover, always. No contain, no filter, no frame, no inner
       rule, no offset shadow.
     · radius 0 everywhere. 50% is reserved for the rarity stamp alone.
     · a field with no value renders no row, and reserves no space.
   ============================================================ */

.pd,
.pdnav,
.pd-buybar {
  /* The handoff's own alpha ladder. --archive-line is 0.22 and --archive-clay
     is #a85f3e, so neither matches what this page draws; only
     --archive-line-soft (0.11) happens to agree, and it is used by name below.
     These three are scoped to the page rather than added to the token sheet:
     they are this design's hairline weights, not new brand colours. */
  --pd-line: rgba(20, 33, 27, 0.16);      /* section hairlines            */
  --pd-btn-line: rgba(20, 33, 27, 0.20);  /* the outlined button          */
  --pd-mark-off: rgba(20, 33, 27, 0.35);  /* empty rarity square, stamp ring */
  --pd-nav-h: 52px;
  --pd-gutter: 16px;
}

/* ============================================================
   1 · the page's own header
   ============================================================ */
/* Replaces the global D1 masthead on this page. 52px on phone with back at the
   start and the wordmark at the end; 66px and a hairline on desktop, with the
   two ends swapped — which is why `order` does the arranging. */
.pdnav {
  position: sticky;
  top: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 10px;
  height: var(--pd-nav-h);
  padding: 0 var(--pd-gutter);
  background: var(--archive-paper);
  border-bottom: 1px solid transparent;
}
/* Once the buy block scrolls away the bar earns its hairline and starts
   carrying the plant's name in place of the wordmark. */
.pdnav.is-condensed { border-bottom-color: rgba(20, 33, 27, 0.14); }
.pdnav.is-condensed .pdnav-mark { display: none; }

.pdnav-back {
  display: inline-flex;
  align-items: center;
  /* 41.3px wide measured at 390 in Arabic — 2.7px under the touch floor, and
     unlike its neighbours it carried no hit area at all. */
  min-width: 44px;
  gap: 5px;
  /* the hairline row is 52px tall, so the link already clears 44px */
  align-self: stretch;
  margin-inline-end: auto;
  color: var(--archive-clay-deep);
  font-family: var(--archive-mono);
  font-size: 10px;
  text-decoration: none;
}
.pdnav-back-lg { display: none; }

.pdnav-mark {
  /* The wordmark is drawn as 15px text but it is also the route home, so it
     has to be reachable. Stretching it to the bar's full 52/66px height gives
     the target without moving a pixel of the type: the text stays centred
     exactly where the design places it. Same reasoning as .pdnav-back. */
  display: flex;
  align-items: center;
  align-self: stretch;
  /* The wordmark is a Latin name and reads left-to-right in both languages.
     Making it a flex container turned its two words into flex items, which an
     RTL page then ordered right-to-left — "Whisperer Plants". The box still
     sits at the page's own end; only its contents are pinned. */
  direction: ltr;
  /* one line on phone, two on desktop — the gap is the word space */
  gap: 0.3em;
  color: var(--archive-clay-deep);
  font-family: var(--archive-display-en);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.05;
  text-decoration: none;
  white-space: nowrap;
}
.pdnav-mark em { font-style: normal; }

.pdnav-name {
  min-width: 0;
  overflow: hidden;
  color: var(--archive-ink);
  font-family: var(--archive-display-ar);
  font-size: 15px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pdnav-name[hidden] { display: none; }

/* The locale control, in D1's approved treatment: plain text under a hairline,
   no box, no fill, no radius. The font stack is D1's own — Mono carries no
   Arabic glyphs, and this is the one control whose label is Arabic ("العربية",
   shown while the UI is English), so the Arabic face is appended and the
   browser falls back per glyph. Latin "EN" still renders Mono exactly. */
.pdnav-lang {
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  padding: 0 0 2px;
  color: var(--archive-ink-soft);
  background: none;
  border: 0;
  border-bottom: 1px solid var(--archive-line);
  border-radius: 0;
  font-family: var(--archive-mono), 'IBM Plex Sans Arabic', monospace;
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
}
/* Text this small is a 13x19 target once the box is gone, so it takes the same
   transparent 44px inset the header icons use. */
/* The hit area has to be RESERVED, not just drawn. As an overflowing pseudo on
   a 13px box it spilled into .pdnav-cart, which sits next to it and paints
   later — so 5.4px of the language control was the cart's, and a tap on the
   near edge of "EN" opened the cart instead of switching language. Measured at
   390 in Arabic, where the label is narrowest. Occupying the 44px in layout
   means neither control can take the other's. */
.pdnav-lang {
  min-width: 44px;
  justify-content: center;
}

.pdnav-lang::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  height: 44px;
}
@media (hover: hover) {
  .pdnav-lang:hover { color: var(--archive-ink); border-bottom-color: var(--archive-ink); }
}

/* The one functional addition to the design header: above 1024 the tab bar is
   gone, so without this the cart has no entry point on this page at all. */
.pdnav-cart {
  position: relative;
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-inline-end: -10px;
  padding: 0;
  color: var(--archive-ink);
  background: none;
  border: 0;
  cursor: pointer;
}
.pdnav-cart svg { width: 21px; height: 21px; }

/* ============================================================
   2 · loading / error
   ============================================================ */
.pd-loading, .pd-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-height: 60vh;
  padding: 40px 20px;
  text-align: center;
  color: var(--archive-ink-soft);
}
/* [hidden] and .pd-loading/.pd-error tie in specificity (0,1,0 each) — without
   this, the later class rule's display:flex would win over the attribute. */
.pd-loading[hidden], .pd-error[hidden] { display: none; }
.pd-loading-mono {
  color: var(--archive-clay-deep);
  font-family: var(--archive-mono);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
}
.pd-error-link {
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  padding: 0 24px;
  color: var(--archive-ink);
  border: 1px solid var(--pd-line);
  text-decoration: none;
}
@media (hover: hover) {
  .pd-error-link:hover { color: var(--archive-paper); background: var(--archive-ink); }
}

/* ============================================================
   3 · the screen
   ============================================================ */
.pd { background: var(--archive-paper); }

/* Phone and tablet: a flex column whose bands sum to the viewport exactly.
   52 nav + gallery + content + tab bar = 100dvh. The subtraction uses the tab
   bar's real reserved space (--pw-tabbar-h + its 6px breathing room + the home
   indicator inset), not the nominal 66, or the page would open 6px scrolled.
   The content column is flex:1, so it cannot shrink below its own content: if
   a band grows, another must give. */
.pd-screen {
  display: flex;
  flex-direction: column;
  min-height: calc(100dvh - var(--pd-nav-h) - var(--pw-tabbar-h, 66px) - 6px - env(safe-area-inset-bottom, 0px));
}

.pd-decide {
  flex: 1;
  padding: 20px var(--pd-gutter) 0;
}

/* ============================================================
   4 · the gallery
   ============================================================ */
.pd-gal {
  position: relative;
  flex: none;
  height: 290px;
  /* A specimen with no photograph shows this ground and nothing else — no
     glyph, no letter in a box, ever. */
  background: var(--archive-paper-deep);
}
.pd-gal-stage { position: absolute; inset: 0; }

.pd-gal-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* cover, always. The old sheet used contain + saturate(.9) and letterboxed a
     third of the frame; the handoff deletes both outright. */
  object-fit: cover;
  opacity: 0;
  transition: opacity 220ms ease;
}
.pd-gal-img.is-on { opacity: 1; }

/* progress bars — indicators by appearance, buttons by behaviour */
.pd-gal-bars {
  position: absolute;
  bottom: 12px;
  inset-inline-end: 12px;
  z-index: 2;
  display: flex;
  gap: 5px;
}
.pd-gal-bar {
  position: relative;
  width: 16px;
  height: 2px;
  padding: 0;
  background: rgba(240, 236, 226, 0.45);
  border: 0;
  border-radius: 0;
  cursor: pointer;
}
.pd-gal-bar.is-on { background: var(--archive-paper); }
/* The invisible 44px target. The drawn bar stays 16x2. */
.pd-gal-bar::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 44px;
  height: 44px;
}

/* the rarity stamp — the only 50% radius on this page */
.pd-stamp {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  color: var(--archive-clay-deep);
  font-family: var(--archive-display-en);
  font-weight: 600;
  transform: rotate(-1.5deg);
}
.pd-stamp--sm {
  position: absolute;
  top: 12px;
  inset-inline-start: 12px;
  z-index: 2;
  width: 44px;
  height: 44px;
  background: rgba(240, 236, 226, 0.94);
  box-shadow: 0 0 0 1.5px rgba(127, 67, 45, 0.5);
  font-size: 18px;
}
.pd-stamp--sm[hidden] { display: none; }

/* desktop thumbnail column */
.pd-gal-thumbs { display: none; }

/* ============================================================
   5 · the decision column
   ============================================================ */
.pd-stamp-row { display: none; }

.pd-name {
  margin: 0;
  color: var(--archive-ink);
  font-family: var(--archive-display-ar);
  font-size: 36px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
}

.pd-latin {
  margin: 4px 0 0;
  color: var(--archive-ink-soft);
  font-family: var(--archive-display-en);
  font-style: italic;
  font-size: 17px;
}
.pd-latin[hidden] { display: none; }

.pd-desc {
  margin: 12px 0 0;
  color: var(--archive-ink-soft);
  font-size: 14.5px;
  line-height: 1.7;
}
.pd-desc[hidden] { display: none; }

/* ---------- three facts, one row ---------- */
.pd-facts {
  display: flex;
  margin-top: 16px;
  border-top: 1px solid var(--pd-line);
  border-bottom: 1px solid var(--pd-line);
}
.pd-facts[hidden] { display: none; }
.pd-fact { flex: 1; min-width: 0; padding: 11px 0; }
.pd-fact + .pd-fact {
  padding-inline-start: 14px;
  border-inline-start: 1px solid var(--archive-line-soft);
}
.pd-fact-l {
  display: block;
  color: var(--archive-muted);
  font-family: var(--archive-mono);
  font-size: 9px;
  letter-spacing: 0.14em;
}
.pd-fact-v {
  display: block;
  margin-top: 3px;
  color: var(--archive-ink);
  font-size: 14.5px;
  font-weight: 600;
}
.pd-fact-v.is-clay { color: var(--archive-clay-deep); }
.pd-fact-v.is-mono { font-family: var(--archive-mono); }

/* ---------- price, availability ---------- */
.pd-money { margin-top: 16px; }
.pd-priceline { display: flex; align-items: baseline; gap: 10px; }
.pd-price {
  color: var(--archive-clay-deep);
  font-family: var(--archive-mono);
  font-size: 23px;
  font-weight: 600;
}
/* Claude Design writes this in its "muted light" #718078. That is the value
   --archive-muted used to carry before the project darkened it to #6a6760, and
   at 12px it measures ~3.5:1 on paper — under the 4.5:1 floor for normal text.
   Colour is the ONLY property that deviates: Mono, 12px, the strikethrough,
   the position beside the price and the 10px gap are all the sheet's own. */
.pd-price-was {
  color: var(--archive-muted);
  font-family: var(--archive-mono);
  font-size: 12px;
  text-decoration: line-through;
}
/* One line, not two: availability and fulfilment share a dotted separator the
   renderer writes, so the block below the price stays a single Mono line. */
.pd-avail {
  margin: 5px 0 0;
  color: var(--archive-ink-soft);
  font-family: var(--archive-mono);
  font-size: 10.5px;
  line-height: 1.6;
}
.pd-avail.is-sold, .pd-avail.is-exception { color: var(--archive-clay-deep); }

/* a real discount, honestly stated — never urgency */
.pd-savings {
  margin: 5px 0 0;
  color: #25382f;
  font-family: var(--archive-mono);
  font-size: 10.5px;
  font-weight: 500;
}
.pd-savings[hidden] { display: none; }

/* ---------- the two buttons ---------- */
.pd-buy { display: flex; gap: 10px; margin-top: 14px; }
.pd-btn {
  display: flex;
  flex: 1;
  min-width: 0;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 0 12px;
  border-radius: 0;
  font-family: inherit;
  font-size: 14.4px;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}
/* Equal geometry, unequal commerce. A WhatsApp order never reaches
   create_order_v2, so it decrements no stock and appears in no admin list —
   the ink fill against the hairline outline is what keeps the tracked path
   primary, and it is the design's own treatment, not an addition to it. */
.pd-btn-add {
  color: var(--archive-paper);
  background: var(--archive-ink);
  border: 1px solid var(--archive-ink);
}
@media (hover: hover) {
  .pd-btn-add:hover { background: #25382f; border-color: #25382f; }
}
.pd-btn-wa {
  color: var(--archive-ink);
  background: transparent;
  border: 1px solid var(--pd-btn-line);
}
@media (hover: hover) {
  .pd-btn-wa:hover { border-color: var(--archive-ink); }
}
/* Sold out is a statement, not a control — WhatsApp stays live beside it. */
.pd-btn-sold {
  color: var(--archive-ink-soft);
  background: var(--archive-paper-deep);
  border: 1px solid var(--pd-line);
  cursor: default;
}

.pd-only-lg { display: none; }

/* ============================================================
   6 · the two disclosures
   ============================================================ */
.pd-folds { margin-top: 14px; }
.pd-fold-h { margin: 0; font-size: inherit; font-weight: inherit; }

.pd-fold {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 48px;
  padding: 0;
  color: var(--archive-ink);
  background: none;
  border: 0;
  border-top: 1px solid var(--pd-line);
  border-radius: 0;
  font-family: inherit;
  font-size: 14.5px;
  font-weight: 500;
  text-align: start;
  cursor: pointer;
}
.pd-fold[aria-expanded='true'] { font-weight: 600; border-bottom: 1px solid var(--pd-line); }

/* The affordance is a mono + / − and nothing else. No chevrons. */
.pd-fold-sign {
  flex: none;
  color: var(--archive-clay-deep);
  font-family: var(--archive-mono);
  font-size: 15px;
  line-height: 1;
}
.pd-fold-sign::after { content: '+'; }
.pd-fold[aria-expanded='true'] .pd-fold-sign::after { content: '−'; }

/* Height animates through grid-template-rows, so nothing is measured in JS.
   `hidden` is applied only once the closing transition ends, which keeps a
   closed panel out of the accessibility tree instead of merely collapsed. */
.pd-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 200ms ease-out;
}
.pd-panel > * { min-height: 0; overflow: hidden; }
.pd-panel.is-open { grid-template-rows: 1fr; }
.pd-panel[hidden] { display: none; }

.pd-rows { margin: 0; padding: 6px 0 14px; }
.pd-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--archive-line-soft);
}
.pd-row:last-child { border-bottom: 0; }
.pd-row dt {
  flex: none;
  color: var(--archive-ink-soft);
  font-family: var(--archive-mono);
  font-size: 10px;
}
.pd-row dd {
  margin: 0;
  color: var(--archive-ink);
  font-size: 14.5px;
  font-weight: 500;
  text-align: end;
}

/* مؤشر الندرة — five real squares, not glyphs standing in for them */
.pd-marks { display: flex; gap: 4px; }
.pd-mark {
  width: 8px;
  height: 8px;
  box-shadow: inset 0 0 0 1px var(--pd-mark-off);
}
.pd-mark.is-on { background: var(--archive-ink); box-shadow: none; }

.pd-panel-note {
  margin: 10px 0 14px;
  color: var(--archive-ink-soft);
  font-size: 12px;
  line-height: 1.6;
}
.pd-panel-note[hidden] { display: none; }

/* ---------- احفظها في دفترك ---------- */
/* A secondary action, past the fold on purpose: it is not part of the
   decision, so it never competes with the two buttons above it. */
.pd-save {
  display: flex;
  width: 100%;
  align-items: center;
  min-height: 44px;
  padding: 0;
  color: var(--archive-clay-deep);
  background: none;
  border: 0;
  border-top: 1px solid var(--pd-line);
  border-bottom: 1px solid var(--pd-line);
  border-radius: 0;
  font-family: inherit;
  font-size: 13px;
  text-align: start;
  cursor: pointer;
}
.pd-save[hidden] { display: none; }
.pd-save.is-saved { color: var(--archive-ink-soft); }

/* ============================================================
   7 · the purchase bar
   ============================================================ */
.pd-buybar {
  position: fixed;
  inset-inline: 0;
  bottom: calc(var(--pw-tabbar-h, 66px) + env(safe-area-inset-bottom, 0px));
  z-index: 80;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 60px;
  padding: 0 16px;
  background: rgba(240, 236, 226, 0.96);
  border-top: 1px solid var(--pd-line);
  box-shadow: 0 -8px 20px rgba(20, 33, 27, 0.06);
  animation: pd-bar-in 180ms ease-out;
}
.pd-buybar[hidden] { display: none; }
@keyframes pd-bar-in { from { transform: translateY(100%); } to { transform: none; } }

.pd-buybar-price {
  flex: 1;
  min-width: 0;
  color: var(--archive-clay-deep);
  font-family: var(--archive-mono);
  font-size: 15px;
  font-weight: 600;
}
.pd-buybar-actions { display: flex; flex: none; gap: 10px; }
.pd-bar-btn {
  display: flex;
  align-items: center;
  min-height: 44px;
  border-radius: 0;
  font-family: inherit;
  font-size: 13px;
  text-decoration: none;
  cursor: pointer;
}
.pd-bar-add {
  padding: 0 20px;
  color: var(--archive-paper);
  background: var(--archive-ink);
  border: 1px solid var(--archive-ink);
}
.pd-bar-wa {
  padding: 0 18px;
  color: var(--archive-ink);
  background: transparent;
  border: 1px solid var(--pd-btn-line);
}
.pd-bar-sold {
  padding: 0 20px;
  color: var(--archive-ink-soft);
  background: var(--archive-paper-deep);
  border: 1px solid var(--pd-line);
  cursor: default;
}

/* ============================================================
   8 · related plates
   ============================================================ */
.pd-related {
  max-width: 1440px;
  margin: 0 auto;
  padding: 36px 16px 40px;
  border-top: 1px solid var(--pd-line);
}
.pd-related[hidden] { display: none; }
.pd-related-group + .pd-related-group { margin-top: 48px; }
.pd-related-title {
  margin: 0 0 24px;
  color: var(--archive-ink);
  font-family: var(--archive-display-ar);
  font-size: 22px;
  font-weight: 600;
}
.pd-related-note {
  max-width: 50ch;
  margin: -14px 0 24px;
  color: var(--archive-ink-soft);
  font-size: 14px;
}
.pd-related .cat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 12px; }

/* ============================================================
   9 · responsive
   The phone gallery heights are derived, not chosen: on a 667pt SE the content
   column alone takes most of the screen, which is why it drops to 232 there.
   ============================================================ */
@media (max-width: 389px) {
  .pd-gal { height: 232px; }
  .pd-name { font-size: 32px; }
}

@media (min-width: 414px) {
  .pd, .pdnav, .pd-buybar { --pd-gutter: 18px; }
  .pd-gal { height: 320px; }
  .pd-name { font-size: 38px; }
  .pd-buybar { padding: 0 18px; }
}

/* tablet — not drawn; derived from the desktop rule in the handoff */
@media (min-width: 768px) {
  .pd, .pdnav, .pd-buybar { --pd-gutter: 34px; }
  .pd-gal { height: 480px; }
  .pd-name { font-size: 46px; }
  .pd-related { padding: 48px 34px 60px; }
  .pd-related .cat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .pd-buybar { padding: 0 34px; }
}

/* desktop — two columns, no band arithmetic, no purchase bar */
@media (min-width: 1041px) {
  .pd, .pdnav, .pd-buybar { --pd-nav-h: 66px; }

  .pdnav { border-bottom-color: rgba(20, 33, 27, 0.14); }
  .pdnav-mark {
    order: -1;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 0;
    font-size: 21px;
  }
  .pdnav-mark em { font-style: italic; }
  /* The spacer lives on the back link, not on the wordmark. The wordmark sets
     `direction: ltr` for its own two words, and an auto inline margin resolves
     against the ELEMENT's direction — so on an RTL page the wordmark's own
     `margin-inline-end:auto` landed on its right, pushing it away from the
     start and collapsing all three controls into one end of the bar. The back
     link inherits the page direction, so its auto margin resolves correctly in
     both languages. */
  .pdnav-back { margin-inline-end: 0; margin-inline-start: auto; font-size: 10.5px; }
  .pdnav-back-sm { display: none; }
  .pdnav-back-lg { display: inline; }
  /* The name never replaces the wordmark here: the buy block does not leave
     the viewport on a desktop-height screen, so there is nothing to restate. */
  .pdnav-name { display: none; }

  .pd-screen {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 460px;
    min-height: 0;
  }
  /* The gallery and its thumbnail column are one cell: main plate 660 tall,
     four 150px thumbs beside it. No frame, no inner rule, no offset shadow,
     no filter — all four are deleted from the old plate. */
  .pd-gal {
    grid-column: 1;
    height: 660px;
    margin: 34px 0 34px 34px;
    margin-inline: 34px 0;
  }
  .pd-gal-bars { display: none; }
  .pd-stamp--sm { display: none; }

  .pd-gal-thumbs {
    grid-column: 1;
    display: flex;
    flex-direction: column;
    gap: 14px;
    width: 120px;
    max-height: 660px;
    margin: 34px 34px 34px 0;
    margin-inline: 0 34px;
    overflow-y: auto;
    justify-self: end;
    align-self: start;
  }
  .pd-gal-thumbs[hidden] { display: none; }
  /* the thumbs sit beside the plate, so the plate gives up their track */
  .pd-screen:has(.pd-gal-thumbs:not([hidden])) .pd-gal { margin-inline-end: 134px; }

  .pd-gal-thumb {
    position: relative;
    flex: none;
    height: 150px;
    padding: 0;
    background: var(--archive-paper-deep);
    border: 0;
    border-radius: 0;
    cursor: pointer;
    opacity: 0.72;
  }
  .pd-gal-thumb img { width: 100%; height: 100%; object-fit: cover; }
  .pd-gal-thumb.is-on { box-shadow: inset 0 0 0 2px var(--archive-ink); opacity: 1; }
  @media (hover: hover) {
    .pd-gal-thumb:hover { opacity: 1; }
  }

  .pd-decide {
    grid-column: 2;
    grid-row: 1;
    padding: 46px 34px 34px 40px;
    border-inline-start: 1px solid var(--pd-line);
  }

  .pd-stamp-row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 16px;
  }
  .pd-stamp-row[hidden] { display: none; }
  .pd-stamp--lg {
    flex: none;
    width: 52px;
    height: 52px;
    border: 2px solid var(--archive-clay-deep);
    box-shadow: 0 0 0 3px var(--archive-paper), 0 0 0 4px rgba(127, 67, 45, 0.35);
    font-size: 21px;
  }
  .pd-stamp-label {
    color: var(--archive-clay-deep);
    font-family: var(--archive-display-ar);
    font-size: 17px;
    font-weight: 600;
  }

  .pd-name { font-size: 56px; }
  .pd-latin { margin-top: 7px; font-size: 22px; }
  .pd-desc { margin-top: 16px; max-width: 40ch; font-size: 16px; line-height: 1.75; }

  .pd-facts { margin-top: 24px; }
  .pd-fact { padding: 14px 0; }
  .pd-fact + .pd-fact { padding-inline-start: 18px; }
  .pd-fact-l { font-size: 9.5px; }
  .pd-fact-v { margin-top: 4px; font-size: 16px; }
  .pd-fact-v.is-mono { margin-top: 5px; font-size: 15px; }

  .pd-money { margin-top: 24px; }
  .pd-price { font-size: 28px; }
  .pd-price-was { font-size: 13px; }
  .pd-avail, .pd-savings { margin-top: 6px; font-size: 11px; }

  .pd-buy { margin-top: 20px; }
  .pd-only-sm { display: none; }
  .pd-only-lg { display: inline; }

  .pd-folds { margin-top: 24px; }
  .pd-fold { min-height: 52px; font-size: 15px; }
  .pd-fold-sign { font-size: 16px; }
  .pd-save { font-size: 13.5px; }

  /* the price never leaves the viewport here */
  .pd-buybar { display: none; }

  .pd-related { padding: 60px 34px 90px; }
  .pd-related .cat-grid {
    grid-template-columns: repeat(auto-fit, minmax(240px, 330px));
    justify-content: start;
  }
}

/* ============================================================
   10 · focus, press, motion
   ============================================================ */
:is(.pdnav-back, .pdnav-mark, .pdnav-cart, .pd-gal-bar, .pd-gal-thumb,
    .pd-btn, .pd-fold, .pd-save, .pd-bar-btn, .pd-error-link):focus-visible {
  outline: 2px solid var(--archive-clay-deep);
  outline-offset: 2px;
}

:is(.pd-btn, .pd-fold, .pd-save, .pd-bar-btn, .pdnav-back, .pdnav-cart,
    .pd-gal-thumb, .pd-error-link) {
  transition: scale 130ms var(--archive-ease), opacity 130ms ease, background 130ms ease;
  -webkit-tap-highlight-color: transparent;
}
:is(.pd-btn-add, .pd-btn-wa, .pd-bar-add, .pd-bar-wa, .pd-save):active { scale: 0.97; }
:is(.pdnav-back, .pdnav-cart, .pd-fold, .pd-error-link):active { opacity: 0.6; }
/* Sold out does not press. */
:is(.pd-btn-sold, .pd-bar-sold):active { scale: 1; opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .pd-gal-img { transition: none; }
  .pd-panel { transition: none; }
  .pd-buybar { animation: none; }
  :is(.pd-btn, .pd-fold, .pd-save, .pd-bar-btn):active { scale: 1; opacity: 0.72; }
}
