/* ================================================================= hero */
.hero{
  position:relative;display:grid;justify-items:center;align-content:center;
  min-height:100svh;overflow-anchor:none;
  /* the bottom reserve is the scroll cue's own room. It used to be 28px and
     the cue sat on top of the carnet hint. */
  padding:calc(var(--hdr) + clamp(16px,2.4svh,34px)) 0 clamp(58px,7svh,84px);
}
.hero-kicker{
  font-size:11.5px;letter-spacing:var(--tr-wide);text-transform:uppercase;
  color:var(--ink-3);text-align:center;margin-bottom:clamp(14px,2.4vh,28px);
  padding-inline:20px;
}
@media (max-width:620px){
  /* Nine tracked words will not sit on one phone line, and a kicker that
     wraps into a paragraph stops being a kicker. The sentence it was
     abbreviating is two sections further down anyway. */
  .hero-kicker{font-size:10.5px;letter-spacing:.2em;padding-inline:24px}
  .kick-long{display:none}
}
.hero-down{
  position:absolute;bottom:10px;left:50%;transform:translateX(-50%);
  padding:12px 20px;color:var(--ink);z-index:3;
  animation:cue 2.6s ease-in-out infinite;
}
.hero-down:active{transform:translateX(-50%) translateY(3px)}
/* it was asking you to scroll long after you had */
body.has-scrolled .hero-down{opacity:0;pointer-events:none;animation:none;
  transition:opacity .5s var(--e-out)}
/* same trap as the carnet arrows: a viewBox with no width resolves to nothing
   inside a shrink to fit button, so the chevron was never drawn */
.hero-down svg{width:36px;height:18px}
@media (hover:hover){ .hero-down:hover{animation:none;opacity:1} }
@keyframes cue{0%,100%{opacity:.16}50%{opacity:.66}}
@media (prefers-reduced-motion:reduce){.hero-down{animation:none;opacity:.5}}
/* On a phone a landscape spread can only be so tall, so the hero is sized by
   its content instead of the screen. The next section peeking under it is the
   point: it says there is a shop below the book. */
@media (max-width:760px){
  /* The plate fills the phone now, so the hero is a screen again rather than
     a strip. Not the whole screen though: the eight per cent left over is
     the top of the next section, which is how anybody knows there is a shop
     under the book. On a short phone the content wins and it simply grows. */
  .hero{min-height:92svh;padding-block:calc(var(--hdr) + 18px) 52px}
  .hero-down{bottom:4px}
}
@media (max-width:360px),(max-height:600px){
  .hero{padding-block:calc(var(--hdr) + 10px) 44px}
  .hero-kicker{margin-bottom:10px}
}

/* =============================================================== blocks */
.sec-hd{display:grid;gap:14px;margin-bottom:clamp(30px,5vh,56px)}
/* the label draws itself a rule as it arrives */
.sec-hd .label{display:flex;align-items:center}
.sec-hd .label:before{
  content:"";flex:none;height:1px;width:0;background:var(--gold);
  margin-right:0;transition:width .8s var(--e-out) .12s,margin-right .8s var(--e-out) .12s;
}
html.js .sec-hd .label.in:before{width:26px;margin-right:13px}
.sec-hd.center .label:before{display:none}
@media (prefers-reduced-motion:reduce){
  .sec-hd .label:before{transition:none;width:26px;margin-right:13px}
}
.sec-hd.center{justify-items:center;text-align:center}
.sec-hd .lede{max-width:56ch}

.split{
  display:grid;gap:clamp(28px,5vw,72px);align-items:center;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
}
.split>*{min-width:0}
.split.rev .split-fig{order:2}
@media (max-width:860px){
  .split{grid-template-columns:minmax(0,1fr)}
  .split.rev .split-fig{order:0}
}
.split-fig{position:relative;overflow:hidden;border-radius:2px;background-color:var(--paper-deep)}
.split-fig img{width:100%;height:auto;aspect-ratio:3/2;object-fit:cover}
.split-fig figcaption{
  position:absolute;left:0;right:0;bottom:0;padding:16px 18px;
  background:linear-gradient(0deg,rgba(30,24,17,.56),rgba(30,24,17,0));
  color:rgba(255,252,244,.9);font-size:11px;letter-spacing:var(--tr-caps);
  text-transform:uppercase;
}
/* Every other figure in this file pairs its width with a height; this one
   did not, so the 760 in the markup's height attribute stayed the used height
   and a 491x477 magnolia was drawn 230x760 with object-fit falling back to
   `fill`. The reset in base.css now supplies the floor; this says it again
   where the width is set, because that is where anyone will look. */
.bloom-fig{width:clamp(140px,16vw,230px);height:auto;opacity:.92}

.quote{
  display:grid;justify-items:center;gap:18px;text-align:center;
  max-width:800px;margin-inline:auto;
}
.quote p{font-family:var(--display);font-weight:300;font-style:italic;
  font-size:clamp(22px,2.7vw,36px);line-height:1.34}

/* =========================================================== card grid */
.cards{
  display:grid;gap:clamp(20px,2.6vw,38px) clamp(14px,1.8vw,26px);
  grid-template-columns:repeat(auto-fill,minmax(min(100%,248px),1fr));
}
.cards>*{min-width:0}
.cards.cols-3{grid-template-columns:repeat(auto-fill,minmax(min(100%,300px),1fr))}

.card{position:relative;display:flex;flex-direction:column;min-width:0}
/* isolation:isolate keeps .card-plate's multiply blending against this card's
   own paper rather than the page, but it also traps everything inside here in
   a stacking context of its own. The invisible full-tile link (.card-name
   a:after, z-index 2, containing block .card) therefore painted OVER the
   Add to bag button, and a real mouse click on the button navigated to the
   piece instead of adding it — a scripted .click() skips hit testing and
   never saw it. Lifting the figure above the overlay fixes the order; making
   the figure itself transparent to the pointer keeps the photograph a link,
   and the two real controls inside it turn hit testing back on. */
.card-fig{
  position:relative;overflow:hidden;border-radius:2px;
  background-color:var(--paper-lift);
  aspect-ratio:1;display:grid;place-items:center;padding:11%;
  isolation:isolate;z-index:3;pointer-events:none;
}
.card-add,.card-flip{pointer-events:auto}
.card-fig:before{
  content:"";position:absolute;inset:0;
  background:url(../img/atmos/paper.webp) center / cover no-repeat;
  opacity:.42;
}
.card-fig img{
  grid-area:1/1;width:100%;height:100%;object-fit:contain;max-height:100%;
  position:relative;z-index:1;
  transition:opacity .55s var(--e-out),transform .8s var(--e-out);
}
.card-shot{opacity:1}
.card-plate{opacity:0;transform:scale(1.04);mix-blend-mode:multiply}
.card.show-plate .card-shot{opacity:0}
.card.show-plate .card-plate{opacity:1;transform:none}
@media (hover:hover){
  .card:hover .card-shot{opacity:0}
  .card:hover .card-plate{opacity:1;transform:none}
}
/* The 40px brown-black drop shadow that used to come up under a hovered card
   is gone. The tile already answers the cursor three ways — the photograph
   dissolves into the gouache, the card lifts four pixels and the paper behind
   it drifts — and a dark blur under a picture on warm paper reads as a UI kit,
   not as a page of this carnet. */
.card-fig{transition:transform .5s var(--e-out)}

.card-tag{
  position:absolute;top:11px;left:11px;z-index:3;
  font-size:9px;letter-spacing:var(--tr-caps);text-transform:uppercase;
  padding:5px 9px;border-radius:2px;
  background-color:rgba(246,242,233,.9);color:var(--gold-deep);
  border:1px solid rgba(166,124,69,.28);
}
.card-flip{
  position:absolute;top:9px;right:9px;z-index:3;
  width:32px;height:32px;display:grid;place-items:center;border-radius:50%;
  background-color:rgba(246,242,233,.86);color:var(--ink-2);
  border:1px solid var(--hair);
  transition:color var(--t-fast),background-color var(--t-fast);
}
.card-flip svg{width:14px;height:14px}
.card.show-plate .card-flip{color:var(--gold);background-color:#fff}
@media (hover:hover){ .card-flip{display:none} }

/* This used to be a bar of near-black slammed across the bottom of the
   photograph the moment the cursor arrived. It is the same chip as the stock
   tag and the gallery cue now: the paper the card is printed on, a hairline
   round it, ink for the words. The press still fills it. */
.card-add{
  position:absolute;left:11px;right:11px;bottom:11px;z-index:3;
  min-height:40px;border-radius:2px;
  background-color:rgba(246,242,233,.94);color:var(--ink);
  border:1px solid var(--hair);
  font-size:10px;letter-spacing:var(--tr-caps);text-transform:uppercase;
  opacity:0;transform:translateY(8px);
  transition:opacity .34s var(--e-out),transform .34s var(--e-out),
    background-color .3s var(--e-out),color .3s var(--e-out),
    border-color .3s var(--e-out);
}
@media (hover:hover){
  .card-add:hover{background-color:var(--ink);color:var(--paper);border-color:var(--ink)}
  .card:hover .card-add{opacity:1;transform:none}
}
@media (hover:none){ .card-add{display:none} }

.card-txt{display:grid;gap:3px;padding-top:15px}
.card-name{font-family:var(--display);font-size:22px;font-weight:400;line-height:1.24}
.card-name a{position:static}
.card-name a:after{content:"";position:absolute;inset:0;z-index:2}
.card-sub{font-size:12px;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-3)}
.card-price{font-size:14.5px;letter-spacing:.04em;color:var(--ink);margin-top:5px}

/* ======================================================= category strip */
.cats{display:grid;gap:1px;grid-template-columns:repeat(4,minmax(0,1fr));
  background:var(--hair);border-block:1px solid var(--hair)}
.cats>*{min-width:0}
@media (max-width:720px){ .cats{grid-template-columns:repeat(2,minmax(0,1fr))} }
.cat{
  position:relative;display:grid;gap:6px;justify-items:center;text-align:center;
  padding:clamp(26px,4vw,46px) 16px;background-color:var(--paper);
  transition:background-color var(--t-mid) var(--e-out);
}
@media (hover:hover){ .cat:hover{background-color:var(--paper-lift)} }
.cat-n{font-family:var(--display);font-size:clamp(20px,2.2vw,28px);font-weight:400}
.cat-c{font-size:10.5px;letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--ink-3)}
.cat-go{
  font-size:10px;letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--gold-deep);
  opacity:0;transform:translateY(-4px);
  transition:opacity var(--t-mid) var(--e-out),transform var(--t-mid) var(--e-out);
}
@media (hover:hover){ .cat:hover .cat-go{opacity:1;transform:none} }

/* ============================================================== filters */
.page-hd{padding-top:calc(var(--hdr) + clamp(34px,6vh,72px));padding-bottom:clamp(22px,4vh,44px)}
.crumb{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:18px;
  font-size:11.5px;letter-spacing:var(--tr-nav);color:var(--ink-3)}
@media (hover:hover){ .crumb a:hover{color:var(--ink)} }
.crumb i{font-style:normal;opacity:.5}

.bar{
  display:flex;flex-wrap:wrap;gap:14px 20px;align-items:center;justify-content:space-between;
  padding-block:16px;border-block:1px solid var(--hair);margin-bottom:clamp(26px,4vh,44px);
}
.pills{display:flex;flex-wrap:wrap;gap:8px}
.pill{
  min-height:38px;padding:0 16px;border-radius:999px;
  border:1px solid var(--hair);background-color:transparent;
  font-size:11px;letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--ink-2);
  transition:border-color var(--t-fast),color var(--t-fast),background-color var(--t-fast);
  display:inline-flex;align-items:center;
}
@media (hover:hover){ .pill:hover{border-color:var(--ink-4);color:var(--ink)} }
.pill[aria-pressed="true"],.pill[aria-current="page"]{
  background-color:var(--ink);border-color:var(--ink);color:var(--paper)}
.bar-r{display:flex;align-items:center;gap:14px;flex:none}
.count{font-size:11.5px;letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--ink-3);
  white-space:nowrap}
@media (max-width:560px){
  .bar{gap:12px 14px}
  .bar-r{width:100%;justify-content:space-between}
}

.noresult{display:grid;justify-items:center;gap:18px;text-align:center;padding:70px 0}

/* ================================================================== PDP */
.pdp{
  display:grid;gap:clamp(28px,4vw,64px);
  grid-template-columns:minmax(0,1.18fr) minmax(0,.82fr);
  align-items:start;
}
.pdp>*{min-width:0}
@media (max-width:940px){ .pdp{grid-template-columns:minmax(0,1fr)} }

.gal{display:grid;gap:14px}
.gal-main{
  position:relative;overflow:hidden;border-radius:2px;
  background-color:var(--paper-lift);aspect-ratio:1;
  display:grid;place-items:center;padding:8%;isolation:isolate;
}
.gal-main:before{
  content:"";position:absolute;inset:0;
  background:url(../img/atmos/paper.webp) center / cover no-repeat;opacity:.4;
}
.gal-main img{position:relative;z-index:1;width:100%;height:100%;
  object-fit:contain;max-height:100%}
.gal-main img.is-paint{mix-blend-mode:multiply}
.thumb img.is-paint{mix-blend-mode:multiply}
.gal-main.is-plate{padding:3%}
@media (hover:hover){ .gal-main.can-loupe{cursor:none} }
.gal-cue{
  position:absolute;z-index:4;right:14px;bottom:14px;
  display:inline-flex;align-items:center;gap:7px;
  font-size:10px;letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--ink-2);
  background-color:rgba(246,242,233,.84);padding:6px 10px;border-radius:2px;
  border:1px solid var(--hair);
  transition:opacity var(--t-mid) var(--e-out);
}
.gal-main.loupe-live .gal-cue{opacity:0}
@media (hover:none){ .gal-cue{display:none} }

.thumbs{display:flex;gap:10px;flex-wrap:wrap}
.thumb{
  width:74px;height:74px;border-radius:2px;overflow:hidden;
  background-color:var(--paper-lift);border:1px solid transparent;
  display:grid;place-items:center;padding:7px;
  transition:border-color var(--t-fast) var(--e-out);flex:none;
}
.thumb img{width:100%;height:100%;object-fit:contain;max-height:100%}
/* The selected thumb is marked in gold. :hover has the same specificity and
   used to sit after it, so on a phone the thumb you had just chosen took the
   stuck hover's grey border instead — the wrong colour at exactly the moment
   you chose it — and only flipped to gold when you touched something else. */
.thumb[aria-pressed="true"]{border-color:var(--gold)}
@media (hover:hover){
  .thumb:not([aria-pressed="true"]):hover{border-color:var(--ink-4)}
}

.pdp-info{position:sticky;top:calc(var(--hdr) + 22px);display:grid;gap:20px}
@media (max-width:940px){ .pdp-info{position:static} }
.pdp-ref{display:flex;align-items:center;gap:12px;font-size:11px;
  letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--ink-3)}
/* 11px caps: --gold is 3.1:1 on paper, --gold-deep is 5.1:1 */
.pdp-ref b{font-weight:400;color:var(--gold-deep)}
.pdp-name{font-family:var(--display);font-weight:300;line-height:1.04;
  font-size:clamp(38px,4.4vw,60px)}
.pdp-price{font-size:20px;letter-spacing:.03em;color:var(--ink)}
.pdp-tag{font-family:var(--display);font-style:italic;font-weight:300;
  font-size:20px;color:var(--ink-2);line-height:1.4}
.pdp-buy{display:grid;gap:12px}
.pdp-rowbtns{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:stretch}
.pdp-rowbtns>*{min-width:0}
.pdp-rowbtns .qty{height:52px}
.pdp-rowbtns .qty button{width:40px;height:100%}
.pdp-notes{display:grid;gap:10px;padding-top:6px}
.pdp-note{display:flex;gap:10px;align-items:flex-start;font-size:13px;color:var(--ink-2)}
.pdp-note svg{width:15px;height:15px;flex:none;margin-top:3px;color:var(--gold)}

.sizes{display:flex;flex-wrap:wrap;gap:8px}
.size{
  min-width:52px;min-height:44px;padding:0 12px;
  border:1px solid var(--hair);border-radius:2px;background-color:transparent;
  font-size:13px;color:var(--ink-2);
  transition:border-color var(--t-fast),color var(--t-fast),background-color var(--t-fast);
}
@media (hover:hover){ .size:hover{border-color:var(--ink-4);color:var(--ink)} }
.size[aria-pressed="true"]{border-color:var(--ink);background-color:var(--ink);color:var(--paper)}
.size-hd{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:9px}

.acc{border-top:1px solid var(--hair)}
.acc-item{border-bottom:1px solid var(--hair)}
.acc-btn{
  width:100%;display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:18px 2px;text-align:left;
  font-size:12.5px;letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--ink);
}
.acc-btn i{position:relative;width:11px;height:11px;flex:none;font-style:normal}
.acc-btn i:before,.acc-btn i:after{
  content:"";position:absolute;background:var(--ink-2);
  transition:transform var(--t-mid) var(--e-out),opacity var(--t-mid) var(--e-out)}
.acc-btn i:before{left:0;right:0;top:5px;height:1px}
.acc-btn i:after{top:0;bottom:0;left:5px;width:1px}
.acc-btn[aria-expanded="true"] i:after{transform:scaleY(0);opacity:0}
.acc-panel{overflow:hidden;height:0;transition:height .42s var(--e-soft)}
.acc-panel-in{padding-bottom:22px}
.spec{display:grid;grid-template-columns:minmax(0,150px) minmax(0,1fr);gap:8px 20px;
  font-size:14.5px}
.spec>*{min-width:0}
.spec dt{color:var(--ink-3);font-size:12.5px;letter-spacing:.07em;text-transform:uppercase;
  padding-top:3px}
.spec dd{margin:0;color:var(--ink-2)}

/* the plate this piece came from */
.plate-cta{
  display:grid;grid-template-columns:minmax(0,auto) minmax(0,1fr);gap:clamp(18px,3vw,34px);
  align-items:center;padding:clamp(20px,3vw,32px);
  background-color:var(--paper-lift);border:1px solid var(--hair);border-radius:2px;
}
.plate-cta>*{min-width:0}
@media (max-width:640px){ .plate-cta{grid-template-columns:minmax(0,1fr)} }
.plate-cta-fig{width:min(230px,42vw);border-radius:2px;overflow:hidden;
  background-color:var(--page)}
.plate-cta-fig img{width:100%;height:auto;aspect-ratio:1;object-fit:cover}

/* ================================================================= cart */
.cart-grid{display:grid;gap:clamp(28px,4vw,60px);
  grid-template-columns:minmax(0,1.5fr) minmax(0,.85fr);align-items:start}
.cart-grid>*{min-width:0}
@media (max-width:900px){ .cart-grid{grid-template-columns:minmax(0,1fr)} }
.summary{
  position:sticky;top:calc(var(--hdr) + 22px);
  background-color:var(--paper-lift);border:1px solid var(--hair);border-radius:2px;
  padding:clamp(20px,3vw,30px);display:grid;gap:14px;
}
@media (max-width:900px){ .summary{position:static} }
.sum-row{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  font-size:14.5px;color:var(--ink-2)}
.sum-row.total{padding-top:14px;border-top:1px solid var(--hair);
  font-size:19px;color:var(--ink);font-family:var(--display)}
.sum-row.total b{font-weight:400}

/* ============================================================= checkout */
.steps{display:flex;flex-wrap:wrap;gap:10px 22px;margin-bottom:clamp(24px,4vh,42px)}
/* --ink-4 is the hairline tier (.46 alpha, 2.7:1 on paper). The upcoming
   steps are words, so they belong on --ink-3, which the token ladder in
   base.css already documents as the tracked-label tier at 4.9:1. The bubble
   takes its border from currentColor, so it comes up with them. */
.step{display:flex;align-items:center;gap:9px;font-size:11.5px;
  letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--ink-3)}
.step b{width:22px;height:22px;border-radius:50%;display:grid;place-items:center;
  border:1px solid currentColor;font-size:10px;font-weight:400}
.step.is-now{color:var(--ink)}
.step.is-done{color:var(--gold-deep)}
.step.is-done b{background-color:var(--gold-deep);border-color:var(--gold-deep);color:#fff}

.form-grid{display:grid;gap:16px;grid-template-columns:repeat(2,minmax(0,1fr))}
.form-grid>*{min-width:0}
.form-grid .span2{grid-column:1 / -1}
@media (max-width:620px){
  .form-grid{grid-template-columns:minmax(0,1fr)}
  .form-grid .span2{grid-column:auto}
}
.notice{
  display:flex;gap:11px;align-items:flex-start;
  padding:14px 16px;border-radius:2px;
  background-color:rgba(166,124,69,.09);border:1px solid rgba(166,124,69,.28);
  font-size:12.5px;line-height:1.6;color:var(--ink-2);
}
.notice svg{width:16px;height:16px;flex:none;margin-top:2px;color:var(--gold)}

.order-done{display:grid;justify-items:center;gap:22px;text-align:center;
  max-width:640px;margin-inline:auto}
.seal{
  width:104px;height:104px;border-radius:50%;display:grid;place-items:center;
  background:radial-gradient(circle at 34% 28%,#c2a16b,#8a6534 62%,#6d4d26);
  color:rgba(255,250,240,.92);
  font-size:9px;letter-spacing:.24em;text-indent:.24em;text-transform:uppercase;
  box-shadow:0 10px 26px rgba(88,64,32,.28),inset 0 2px 5px rgba(255,255,255,.3);
  animation:seal-in .7s var(--e-back) both;
}
@keyframes seal-in{from{transform:scale(.5) rotate(-14deg);opacity:0}}
@media (prefers-reduced-motion:reduce){ .seal{animation:none} }
.order-tbl{width:100%;text-align:left;border-top:1px solid var(--hair)}
.order-tbl tr{border-bottom:1px solid var(--hair-soft)}
.order-tbl th,.order-tbl td{padding:13px 0;font-weight:400;font-size:14px;vertical-align:top}
.order-tbl th{color:var(--ink-3);font-size:12px;letter-spacing:.07em;text-transform:uppercase}
.order-tbl td{text-align:right;color:var(--ink-2)}

/* ============================================================== atelier */
.atl-grid{display:grid;gap:clamp(26px,4vw,56px);
  grid-template-columns:repeat(3,minmax(0,1fr))}
.atl-grid>*{min-width:0}
@media (max-width:860px){ .atl-grid{grid-template-columns:minmax(0,1fr)} }
.atl-step{display:grid;gap:12px;align-content:start}
.atl-n{font-family:var(--display);font-size:44px;font-weight:300;color:var(--gold);
  line-height:1}

/* ------------------------------------------- the glass over the piece --
   The same jeweller's glass as the carnet, but here it IS the cursor, so
   it has no handle to pick up. */
.pdp-loupe{
  position:absolute;left:0;top:0;z-index:5;
  width:clamp(128px,13vw,168px);aspect-ratio:1;
  border-radius:50%;pointer-events:none;
  padding:calc(clamp(128px,13vw,168px) * .058);
  opacity:0;transition:opacity .22s var(--e-out);
  will-change:transform;
  box-shadow:
    0 1px 2px rgba(58,44,26,.3),
    0 10px 18px rgba(58,44,26,.24),
    0 26px 40px rgba(58,44,26,.2);
}
.gal-main.loupe-live .pdp-loupe{opacity:1}
.pdp-loupe:before{
  content:"";position:absolute;inset:0;border-radius:50%;pointer-events:none;z-index:3;
  background:linear-gradient(146deg,
    #fdf7e9 0%,#e6d7b4 14%,#b69d70 32%,#7d6740 50%,
    #cdbb92 66%,#f4ead3 80%,#9b8459 100%);
  box-shadow:inset 0 1px 1px rgba(255,255,255,.8),inset 0 -2px 3px rgba(70,52,26,.5);
  -webkit-mask-image:radial-gradient(circle closest-side at 50% 50%,transparent 0 88.2%,#000 89.8% 100%);
  mask-image:radial-gradient(circle closest-side at 50% 50%,transparent 0 89.8%,#000 89.8% 100%);
}
.pdp-loupe:after{
  content:"";position:absolute;inset:8%;border-radius:50%;pointer-events:none;z-index:2;
  background:
    radial-gradient(36% 26% at 29% 19%,rgba(255,255,255,.28),rgba(255,255,255,0) 76%),
    radial-gradient(24% 16% at 74% 86%,rgba(255,255,255,.1),rgba(255,255,255,0) 80%),
    radial-gradient(circle at 50% 50%,rgba(0,0,0,0) 56%,rgba(58,44,26,.1) 78%,rgba(46,34,16,.3) 100%);
}
.pdp-lens{
  display:block;width:100%;height:100%;border-radius:50%;
  background-color:var(--page);background-repeat:no-repeat;
  box-shadow:
    inset 0 0 0 1px rgba(52,40,22,.5),
    inset 0 4px 12px rgba(40,30,14,.22);
}

/* ------------------------------------------------------- the plate index */
.plate-list{border-top:1px solid var(--hair)}
.plate{
  display:grid;grid-template-columns:3.4em minmax(0,1fr) auto auto;gap:18px;align-items:baseline;
  width:100%;padding:15px 4px;border-bottom:1px solid var(--hair);text-align:left;color:inherit;
  transition:background-color .22s var(--e-out);
}
.plate>*{min-width:0}
/* The row used to indent by animating padding-left, which relaid the 1192px
   grid and re-resolved its four tracks on every frame of the .22s transition —
   about 53 extra layouts per hover. The two left cells carry the same read on
   the compositor instead (see "the plate index" further down). */
.plate[aria-current="true"]{background-color:rgba(255,252,244,.55)}
@media (hover:hover){ .plate:hover{background-color:rgba(255,252,244,.55)} }
.plate .n{font-size:12.5px;color:var(--ink-3);letter-spacing:.06em}
.plate .t{font-family:var(--display);font-size:clamp(19px,2.1vw,26px);font-weight:400}
.plate .m{font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3);text-align:right}
.plate .p{font-size:13.5px;color:var(--ink-2);text-align:right;min-width:5.6em}
.plate[aria-current="true"] .m{color:var(--gold-deep)}
@media (max-width:640px){
  .plate{grid-template-columns:2.6em minmax(0,1fr) auto;gap:10px;padding-inline:0}
  .plate .m{display:none}
}


/* ====================================================== touch targets ====
   Last stylesheet in, so nothing later can quietly undo these. The pill rule
   in this file was overriding the coarse bump in base.css purely by being
   loaded afterwards, which is exactly the class of bug that only a real
   measurement finds. Forty pixels is the floor for anything a thumb has to
   land on; the exceptions are links inside prose, which are read, not aimed
   at. */
@media (pointer:coarse){
  .pill{min-height:44px;padding-inline:18px}
  .card-flip svg{width:16px;height:16px}
  .tool{width:40px;height:40px}
  .tool svg{width:17px;height:17px}
  .zoom-read{min-width:48px}
  .hero-down{padding:16px 26px}
  .card-flip{width:44px;height:44px}
  .thumb{width:78px;height:78px}
  .acc-btn{padding-block:20px}
  /* the wordmark is a link home, and on a phone it is two lines of small caps
     with nothing around them */
  .mark{min-height:44px;align-content:center}
  .qty button{width:42px;height:42px}
  .cs-opt{min-height:46px}
}

/* ===================================================== where to go next ==
   Every page used to run out into the footer. Three doors, dealt out as you
   arrive at them: the number first, then the name, then the line under it,
   and the ground fills up behind the whole card when you go for one. */
.onward{
  position:relative;z-index:1;
  padding-block:clamp(56px,8vh,104px) clamp(20px,3vh,36px);
  margin-top:var(--sec);
  border-top:1px solid var(--hair-soft);
}
.onward-hd{display:grid;gap:12px;margin-bottom:clamp(26px,4vh,44px)}
.onward-grid{
  display:grid;gap:1px;
  grid-template-columns:repeat(3,minmax(0,1fr));
  background:var(--hair-soft);
  border-block:1px solid var(--hair-soft);
}
.onward-grid>*{min-width:0}
@media (max-width:820px){ .onward-grid{grid-template-columns:minmax(0,1fr)} }

.onward-card{
  position:relative;display:grid;gap:9px;align-content:start;
  padding:clamp(24px,3vw,38px) clamp(20px,2.4vw,32px) clamp(26px,3.4vw,42px);
  background-color:var(--paper);
  isolation:isolate;overflow:hidden;
  min-height:100%;
}
.onward-card>*{position:relative;z-index:2}
/* the ground comes up behind it rather than the card moving */
.onward-fill{
  position:absolute;inset:0;z-index:1;
  background-color:var(--paper-lift);
  transform:scaleY(0);transform-origin:bottom center;
  transition:transform .58s var(--e-soft);
}
.onward-card:focus-visible .onward-fill{transform:scaleY(1)}
@media (hover:hover){ .onward-card:hover .onward-fill{transform:scaleY(1)} }
.onward-card:before{
  content:"";position:absolute;left:0;right:0;top:0;height:1px;z-index:3;
  background:var(--gold);transform:scaleX(0);transform-origin:left center;
  transition:transform .6s var(--e-out);
}
.onward-card:focus-visible:before{transform:scaleX(1)}
@media (hover:hover){ .onward-card:hover:before{transform:scaleX(1)} }
/* The numeral and the "Go through" line were both on --ink-4 at 2.7:1. They
   are words on a card, not hairlines. */
.onward-n{
  font-size:11px;letter-spacing:var(--tr-wide);color:var(--ink-3);
  transition:color .4s var(--e-out);
}
@media (hover:hover){ .onward-card:hover .onward-n{color:var(--gold-deep)} }
.onward-t{
  font-family:var(--display);font-weight:400;line-height:1.14;
  font-size:clamp(23px,2.3vw,31px);
  transition:transform .5s var(--e-out);
}
@media (hover:hover){ .onward-card:hover .onward-t{transform:translateX(5px)} }
.onward-d{font-size:13.5px;line-height:1.62;color:var(--ink-3);max-width:34ch}
.onward-go{
  display:inline-flex;align-items:center;gap:9px;margin-top:6px;
  font-size:10.5px;letter-spacing:var(--tr-caps);text-transform:uppercase;
  color:var(--ink-3);
  transition:color .4s var(--e-out);
}
/* the svg keeps its own explicit size: an inline viewBox with no width in a
   shrink-to-fit flex child resolves to nothing */
.onward-go svg{width:15px;height:11px;
  transition:transform .5s var(--e-back)}
/* the arrow used to travel by opening the flex gap, which is a layout
   property; it travels on the compositor now and goes a little further */
@media (hover:hover){
  .onward-card:hover .onward-go{color:var(--gold-deep)}
  .onward-card:hover .onward-go svg{transform:translateX(6px)}
}
@media (prefers-reduced-motion:reduce){
  .onward-fill,.onward-card:before,.onward-t,.onward-go,.onward-go svg{transition:none}
}

/* ==========================================================================
   The small motions.

   Nothing here is decoration for its own sake: each one answers a press, a
   hover or an arrival that the page was previously silent about. They all
   go quiet under prefers-reduced-motion, at the bottom.
   ========================================================================== */

/* ---- the gallery cue. The glass in it was rendering at ninety pixels: an
   inline svg with a viewBox and no size takes it from its containing block. */
.gal-cue svg{width:14px;height:14px}
.gal-cue{transform:translateY(0);
  transition:opacity var(--t-mid) var(--e-out),transform var(--t-mid) var(--e-out)}
@media (hover:hover){ .gal-main:hover .gal-cue{transform:translateY(2px)} }

/* ---- cards lift, and the price comes up to meet you */
.card-fig{transition:transform .5s var(--e-out)}
@media (hover:hover){
  .card:hover .card-fig{transform:translateY(-4px)}
  .card:hover .card-name a{color:var(--gold-deep)}
  .card:hover .card-price{transform:translateY(-1px);color:var(--gold-deep)}
  .card:hover .card-tag{transform:scale(1.04)}
}
.card-name a{transition:color .34s var(--e-out)}
.card-price{transition:transform .4s var(--e-out),color .34s var(--e-out)}
.card-tag{transform-origin:left center;
  transition:transform .4s var(--e-back),background-color .3s var(--e-out)}
.card-add{will-change:transform,opacity}
.card-add:active{transform:scale(.98)}

/* ---- the category strip: the word steps forward, a gold rule draws under it */
.cat:after{
  content:"";position:absolute;left:14%;right:14%;bottom:0;height:1px;
  background:var(--gold);transform:scaleX(0);transform-origin:center;
  transition:transform .5s var(--e-out);
}
.cat:focus-visible:after{transform:scaleX(1)}
@media (hover:hover){ .cat:hover:after{transform:scaleX(1)} }
.cat-n{transition:transform .45s var(--e-out)}
@media (hover:hover){ .cat:hover .cat-n{transform:translateY(-3px)} }

/* ---- pills and sizes fill from the left, the way the buttons do */
.pill,.size{position:relative;overflow:hidden;isolation:isolate;
  transition:border-color var(--t-fast),color var(--t-fast),transform .2s var(--e-out)}
.pill:before,.size:before{
  content:"";position:absolute;inset:0;z-index:-1;
  background:var(--paper-deep);
  transform:scaleX(0);transform-origin:left center;
  transition:transform .4s var(--e-out);
}
@media (hover:hover){ .pill:hover:before,.size:hover:before{transform:scaleX(1)} }
.pill[aria-pressed="true"]:before,.pill[aria-current="page"]:before,
.size[aria-pressed="true"]:before{transform:scaleX(1);background:var(--ink)}
.pill:active,.size:active{transform:scale(.97)}

/* ---- thumbs answer a press */
.thumb{transition:border-color var(--t-fast) var(--e-out),transform .34s var(--e-back)}
.thumb:active{transform:scale(.95)}
.thumb img{transition:transform .5s var(--e-out)}
@media (hover:hover){
  .thumb:hover{transform:translateY(-2px)}
  .thumb:hover img{transform:scale(1.06)}
}
/* the main image lands rather than simply appearing */
.gal-main img[data-galimg]{animation:gal-in .5s var(--e-out)}
@keyframes gal-in{from{opacity:0;transform:scale(1.03)}}

/* ---- quantity */
.qty button{transition:background-color var(--t-fast),color var(--t-fast),
  transform .2s var(--e-out)}
.qty button:active:not([disabled]){transform:scale(.86)}
.qty.is-bumped output{animation:qty-bump .34s var(--e-out)}
@keyframes qty-bump{40%{transform:translateY(-3px) scale(1.12)}}

/* ---- the accordion label steps aside for the panel */
/* The label used to step aside by transitioning padding-left, which relaid
   the panel on every frame — 101 layouts a second while the cursor sat on it —
   and left the indent behind after a tap on a phone. The colour is the answer
   now; the row itself stays where it is, which also keeps the +/- glyph
   aligned with the ones above and below it. */
.acc-btn{transition:color var(--t-fast) var(--e-out)}
@media (hover:hover){ .acc-btn:hover{color:var(--gold-deep)} }
.acc-btn[aria-expanded="true"]{color:var(--ink)}
.acc-panel-in{transition:opacity .4s var(--e-out) .06s}
.acc-btn[aria-expanded="false"]+.acc-panel .acc-panel-in{opacity:0}

/* ---- the plate index: the row indents, and its rule draws in gold */
.plate{position:relative}
.plate:after{
  content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;
  background:var(--gold);transform:scaleX(0);transform-origin:left center;
  transition:transform .5s var(--e-out);
}
.plate[aria-current="true"]:after{transform:scaleX(1)}
.plate .n,.plate .t{transition:color .3s var(--e-out),transform .4s var(--e-out)}
.plate[aria-current="true"] .n{color:var(--gold-deep)}
.plate[aria-current="true"] .n,.plate[aria-current="true"] .t{transform:translateX(6px)}
/* the row still indents; the two left cells carry it on the compositor
   instead of the row's own padding carrying it through layout */
@media (hover:hover){
  .plate:hover:after{transform:scaleX(1)}
  .plate:hover .n{color:var(--gold-deep)}
  .plate:hover .n,.plate:hover .t{transform:translateX(6px)}
}

/* ---- the footer, the crumbs and the demo note */
.ftr li a,.crumb a{position:relative}
.ftr li a:after,.crumb a:after{
  content:"";position:absolute;left:0;right:0;bottom:-2px;height:1px;
  background:currentColor;transform:scaleX(0);transform-origin:right center;
  transition:transform .4s var(--e-out);
}
@media (hover:hover){
  .ftr li a:hover:after,.crumb a:hover:after{transform:scaleX(1);transform-origin:left center}
}
/* A finger is not a cursor. The crumbs are set at eleven and a half point
   on purpose and the footer list has to stay a list, so the TYPE does not
   move: the TARGET does. An invisible pad, centred on the link and out of
   the flow, takes a nineteen pixel crumb to forty four without shifting a
   single glyph. The footer's rows are thirty six apart, so their pads meet
   rather than leaving the gaps between them dead. */
@media (pointer:coarse){
  .ftr li a::before,.crumb a::before{
    content:"";position:absolute;left:50%;top:50%;
    transform:translate(-50%,-50%);
    width:max(100%,44px);height:44px;
  }
}
/* and a cursor still wants something bigger than nineteen pixels to find */
@media (pointer:fine){
  .crumb a::before{
    content:"";position:absolute;left:50%;top:50%;
    transform:translate(-50%,-50%);
    width:100%;height:26px;
  }
}
.demo-note i{animation:note-pulse 3.4s ease-in-out infinite}
@keyframes note-pulse{0%,100%{opacity:.55}50%{opacity:1}}

/* ---- editorial figures breathe when you look at them */
.split-fig img{transition:transform 1.1s var(--e-out)}
.split-fig figcaption{transform:translateY(3px);opacity:.86;
  transition:transform .5s var(--e-out),opacity .5s var(--e-out)}
@media (hover:hover){
  .split-fig:hover img{transform:scale(1.035)}
  .split-fig:hover figcaption{transform:none;opacity:1}
}

/* ---- the plate this piece came from */
.plate-cta{transition:border-color .4s var(--e-out),background-color .4s var(--e-out)}
.plate-cta-fig img{transition:transform .9s var(--e-out)}
@media (hover:hover){
  .plate-cta:hover{border-color:rgba(166,124,69,.4)}
  .plate-cta:hover .plate-cta-fig img{transform:scale(1.04)}
}

/* ---- the free shipping meter says so when it lands */
.meter-track{position:relative}
.meter-track.is-full i{background:var(--gold-lift)}
.meter-track.is-full:after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(255,255,255,0),rgba(255,252,240,.9),rgba(255,255,255,0));
  animation:meter-sheen .9s var(--e-out);
}
@keyframes meter-sheen{from{transform:translateX(-100%)}to{transform:translateX(100%)}}

/* ---- checkout steps */
.step{transition:color .4s var(--e-out)}
.step b{transition:background-color .4s var(--e-out),border-color .4s var(--e-out),
  transform .5s var(--e-back)}
.step.is-now b{transform:scale(1.12);border-color:var(--gold)}
.step.is-done b{transform:none}

/* ---- the wordmark. It used to open its tracking out from .30em to .36em,
   which is a layout property inside the fixed header: it re-resolved the
   header's three tracks on every frame of a .6s transition, on every route.
   The imprint opens the same amount on the compositor now, and the colour
   goes to the gold the rest of the page uses for a link. */
.mark-word{transition:transform .6s var(--e-out),color .4s var(--e-out)}
.mark-sub{transition:opacity .4s var(--e-out)}
@media (hover:hover){
  .mark:hover .mark-word{transform:scale(1.035);color:var(--gold-deep)}
  .mark:hover .mark-sub{opacity:.7}
}

/* ---- the mobile menu links answer the press. This panel is the phone's
   navigation, so its :hover was very nearly always a stuck one, and the
   8px indent it left behind came from padding-left, which relaid the whole
   sheet of links every frame. The colour and the arrow do the work. */
.menu-link{transition:color .3s var(--e-out)}
.menu-link:active{color:var(--gold-deep)}
.menu-link i{transition:color .3s var(--e-out),transform .4s var(--e-out)}
.menu-link:active i{transform:translateX(-4px)}
@media (hover:hover){
  .menu-link:hover{color:var(--gold-deep)}
  .menu-link:hover i{transform:translateX(-4px)}
}

/* ---- the leaf you are about to lift.
   There used to be a gradient band here, painted along the outer edge of a
   page whenever the cursor was anywhere on that half of the book. It did not
   read as a shadow. The hit zone is half the whole book, so it fired from
   anywhere near the page rather than from the edge you were reaching for; its
   16% was measured from the book element, not from the photographed paper, so
   its dark end landed on bare desk; and it ran the full height of the zone
   while the paper inside the spread only occupies 21.8% to 78.2% of it, which
   left a hard rectangular top and bottom cutting across the desk. Removed.
   What says the page turns is the pair of chevrons either side of the book
   and the hint line under it, both of which are always drawn, plus the fact
   that the zones are <button>s and therefore carry the pointer cursor. */

/* ---- the painted rule draws itself across */
html.js .rule-paint{clip-path:inset(0 100% 0 0);transition:clip-path 1.3s var(--e-soft)}
html.js .rule-paint.in{clip-path:inset(0 0 0 0)}

/* ---- a hairline that reports how far down the page you are */
.progress{position:fixed;top:0;left:0;right:0;height:2px;z-index:640;pointer-events:none}
.progress i{
  display:block;height:100%;background:var(--gold);opacity:.7;
  transform:scaleX(var(--p,0));transform-origin:left center;
}

@media (prefers-reduced-motion:reduce){
  .card-fig,.cat-n,.thumb,.thumb img,.split-fig img,.plate-cta-fig img,
  .mark-word,.menu-link,.plate .t,.plate .n,.card-price,.qty output,.step b,
  .gal-cue,.acc-btn,.card-tag,.card-add,.onward-go svg{transition:none!important}
  .gal-main img[data-galimg],.demo-note i,.meter-track.is-full:after{animation:none!important}
  html.js .rule-paint{transition:none;clip-path:none}
}

/* ---- the kicker settles rather than switching on */
html.js .hero-kicker{letter-spacing:.46em;opacity:0;
  transition:letter-spacing 1.4s var(--e-out),opacity 1s var(--e-out)}
html.js .hero-kicker.in{letter-spacing:var(--tr-wide);opacity:1}
@media (max-width:620px){ html.js .hero-kicker.in{letter-spacing:.2em} }

/* ---- the piece count changes with the filters, so it should say so */
.count{transition:opacity .24s var(--e-out),transform .24s var(--e-out)}
.count.is-swap{opacity:0;transform:translateY(-3px)}

/* ---- nothing found, arriving */
.noresult{animation:noresult-in .5s var(--e-out) both}
@keyframes noresult-in{from{opacity:0;transform:translateY(10px)}}

/* ---- the paper under a card drifts a little as you look at it */
.card-fig:before{transition:transform 1.4s var(--e-out),opacity .5s var(--e-out)}
@media (hover:hover){
  .card:hover .card-fig:before{transform:scale(1.06) translate(-1%,-1%);opacity:.5}
}

/* ---- the summary used to lift off the page under the cursor. It is an
   <aside>: hovering it does nothing, so the shadow answered a gesture that
   was not a gesture, and on a phone the tap that scrolled past it left the
   panel shadowed for the rest of the visit. Gone. */

/* ---- the size guide and other inline text buttons */
.ln.small:active{transform:translateY(1px)}

@media (prefers-reduced-motion:reduce){
  html.js .hero-kicker{transition:none;letter-spacing:var(--tr-wide);opacity:1}
  .noresult{animation:none}
  .card-fig:before,.count{transition:none}
}
