/* ═══════════════════════════════════════════════════════════════════════════
   Haifawi — the furniture every page shares.

   The site is built as a stack of coloured bands: a full-height field the
   colour of whatever product you are looking at, a stitched gold edge, a plum
   strip, then paper. Everything below is the parts that repeat across those
   bands. The two heroes that make the field worth looking at are in front.css
   and product.css.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Registered so calc() on them is typed, and so they interpolate rather than
   jumping when a script animates one. */
@property --mx { syntax:'<length>'; inherits:true; initial-value:0px }
@property --my { syntax:'<length>'; inherits:true; initial-value:0px }
@property --sy { syntax:'<length>'; inherits:true; initial-value:0px }
@property --px { syntax:'<length>'; inherits:true; initial-value:0px }
@property --py { syntax:'<length>'; inherits:true; initial-value:0px }

:root{
  --display:"Baloo Bhaijaan 2","Avenir Arabic",system-ui,sans-serif;
  --body:"Avenir Arabic",system-ui,sans-serif;
  /* JetBrains Mono carries no Arabic, and its unicode-range says so, so Arabic in the micro-type
     skipped straight past it to whatever monospaced face the system had — which sets Arabic wide
     and disjointed. Avenir Arabic sits between the two: Latin still gets the mono, Arabic gets the
     body face at the same small size. */
  --mono:"JetBrains Mono","Avenir Arabic",ui-monospace,monospace;

  --cream:#FBF7F1;
  --plum:#3C1A57;
  --gold:#F5C042;
  --ink:#191512;
  --muted:#584C55;
  --faint:#8A7B70;

  /* The field is the product's own label colour, printed into the page by
     haifawi_token_css(). These are only what a page with no product uses. */
  --field:#C4212B;
  --deep:#7E1219;

  /* The bar is fixed, so a page that does not open on a hero has to make room
     for it. One number, derived from the bar's own padding and button size. */
  --barh:calc(2.6rem + 2 * clamp(.8rem,2vw,1.35rem));

  --gut:clamp(1.1rem,4vw,3.5rem);
  --ease:cubic-bezier(.22,1,.36,1);
  --radius:1.2rem;
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
/* The page behind everything is the footer's ink, so a short page does not end
   in a band of the hero's colour below the footer. */
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;background:var(--ink)}
body{font-family:var(--body);font-size:clamp(15px,.55vw + 13.5px,17px);line-height:1.55;
  /* `clip`, not `hidden`: both hide what runs off the side, but `hidden` makes the body a scroll
     container, and a scroll container is what a position:sticky descendant sticks inside — which
     is why the checkout's slip would not stay put. `clip` hides without scrolling. */
  color:var(--cream);background:var(--field);overflow-x:clip;
  min-block-size:100svh;display:flex;flex-direction:column}
main{flex:1 0 auto}
/* The bar is fixed and these pages start straight on the paper, so they make
   the room for it themselves. */
.hf-flat main{padding-block-start:var(--barh)}
/* The ribbon is the first thing on a flat page, so the paper behind the bar has
   to be paper too — otherwise the translucent bar sits over the field colour. */
.hf-flat{background:var(--cream)}
img{display:block;max-inline-size:100%;height:auto}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
:focus-visible{outline:3px solid var(--gold);outline-offset:3px;border-radius:3px}

.sr,.screen-reader-text{position:absolute;inline-size:1px;block-size:1px;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap}
.sr:focus{position:fixed;inset-block-start:.6rem;inset-inline-start:.6rem;inline-size:auto;
  block-size:auto;clip-path:none;z-index:99;padding:.7rem 1.1rem;border-radius:999px;
  background:var(--cream);color:var(--plum);font-weight:800}
.mono{font-family:var(--mono);font-weight:500;font-size:.68rem;letter-spacing:.16em;
  text-transform:uppercase}

/* ── the bar ─────────────────────────────────────────────────────────────────
   Fixed, transparent over the field, and turning to paper the moment the hero
   has gone past. */
.bar{position:fixed;inset-block-start:0;inset-inline:0;z-index:60;display:flex;align-items:center;
  gap:1rem;padding:clamp(.8rem,2vw,1.35rem) var(--gut);
  transition:background-color .45s,color .45s}
.mark{font-family:var(--display);font-weight:800;font-size:1.4rem;letter-spacing:-.02em;
  line-height:1;display:block}
.mark small{display:block;font-family:var(--mono);font-size:.56rem;letter-spacing:.3em;
  opacity:.7;margin-block-start:.2rem}
.mark--img img{block-size:2.4rem;inline-size:auto}

/* Centred on the page, not on the space left between the wordmark and the cart:
   an auto margin only balances what is beside it, and the wordmark is much the
   wider of the two. */
.nav{position:absolute;left:50%;translate:-50% 0;
  display:flex;gap:.15rem;padding:.3rem;border-radius:999px;
  background:rgb(255 255 255 / .14);backdrop-filter:blur(14px)}
.nav a{padding:.5rem 1.05rem;border-radius:999px;font-size:.83rem;font-weight:500;
  white-space:nowrap;transition:background-color .25s,color .25s}
.nav a[aria-current]{background:var(--cream);color:var(--plum);font-weight:800}
.nav a:hover:not([aria-current]){background:rgb(255 255 255 / .16)}

.tools{display:flex;gap:.5rem;align-items:center;margin-inline-start:auto}

/* Not `.cart`: WooCommerce's add-to-cart form carries that class, and a rule
   sizing it to a 2.6rem circle collapses the whole buy rail. */
.cartbtn{position:relative;inline-size:2.6rem;block-size:2.6rem;border-radius:50%;
  display:grid;place-items:center;border:1.5px solid rgb(255 255 255 / .42);
  transition:background-color .25s,color .25s,border-color .25s}
.cartbtn .icon{inline-size:1.15rem;block-size:1.15rem}
.cartbtn:hover{background:var(--cream);color:var(--plum);border-color:var(--cream)}
.cart__count{position:absolute;inset-block-start:-.28rem;inset-inline-end:-.28rem;
  min-inline-size:1.15rem;block-size:1.15rem;padding-inline:.26rem;border-radius:999px;
  background:var(--gold);color:var(--ink);font-family:var(--mono);font-size:.6rem;font-weight:500;
  font-style:normal;display:grid;place-items:center}
/* display:grid above outranks the user agent's [hidden] rule, so an empty cart
   would otherwise show a gold "0". */
.cart__count[hidden]{display:none}

.bar.light{background:rgb(251 247 241 / .9);backdrop-filter:blur(16px);color:var(--plum)}
.bar.light .nav{background:rgb(60 26 87 / .08)}
.bar.light .nav a[aria-current]{background:var(--plum);color:var(--cream)}
.bar.light .cartbtn{border-color:rgb(60 26 87 / .3)}
.bar.light .cartbtn:hover{background:var(--plum);color:var(--cream);border-color:var(--plum)}

@media(max-width:58rem){.nav{display:none}}

/* ── the stitched edge and the strip ─────────────────────────────────────────
   One tooth of tatreez cross-stitch, repeated. It is a mask rather than an
   image so it takes the gold from the palette and can be flipped in CSS. */
.stitchband{background:var(--behind,var(--field));position:relative;z-index:9;
  display:block;line-height:0}
.stitch{display:block;block-size:.8rem;background:var(--gold);
  -webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12'%3E%3Cg fill='%23000'%3E%3Crect x='0' y='9' width='3' height='3'/%3E%3Crect x='3' y='6' width='3' height='3'/%3E%3Crect x='6' y='3' width='3' height='3'/%3E%3Crect x='9' y='0' width='3' height='3'/%3E%3Crect x='12' y='0' width='3' height='3'/%3E%3Crect x='15' y='3' width='3' height='3'/%3E%3Crect x='18' y='6' width='3' height='3'/%3E%3Crect x='21' y='9' width='3' height='3'/%3E%3C/g%3E%3C/svg%3E");
          mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12'%3E%3Cg fill='%23000'%3E%3Crect x='0' y='9' width='3' height='3'/%3E%3Crect x='3' y='6' width='3' height='3'/%3E%3Crect x='6' y='3' width='3' height='3'/%3E%3Crect x='9' y='0' width='3' height='3'/%3E%3Crect x='12' y='0' width='3' height='3'/%3E%3Crect x='15' y='3' width='3' height='3'/%3E%3Crect x='18' y='6' width='3' height='3'/%3E%3Crect x='21' y='9' width='3' height='3'/%3E%3C/g%3E%3C/svg%3E");
  -webkit-mask-size:1.6rem .8rem;mask-size:1.6rem .8rem;
  -webkit-mask-repeat:repeat-x;mask-repeat:repeat-x}
.stitch--flip{transform:scaleY(-1)}

.strip{background:var(--plum);color:var(--cream);padding-block:.85rem;overflow:hidden;
  position:relative;z-index:9}
.strip__list{display:flex;gap:2.5rem;list-style:none;inline-size:max-content;
  font-family:var(--display);font-weight:800;font-size:1.05rem;will-change:transform}
.strip__list li::after{content:"\00b7";margin-inline-start:2.5rem;opacity:.45}

/* ── the paper sections ──────────────────────────────────────────────────── */
.paper{background:var(--cream);color:var(--ink);position:relative;z-index:9;
  padding:clamp(3rem,7vw,6rem) var(--gut)}
.band{background:var(--plum);color:var(--cream);position:relative;z-index:9;
  padding:clamp(3rem,7vw,5.5rem) var(--gut)}
.sec-head{display:flex;flex-direction:column;align-items:flex-start;text-align:start;gap:.7rem;
  margin-block-end:clamp(1.6rem,3vw,2.6rem)}
.sec-head p{max-inline-size:48ch;font-size:.94rem;color:var(--muted)}
.band .sec-head p{color:inherit;opacity:.84}
h2.sec{font-family:var(--display);font-weight:800;letter-spacing:-.03em;line-height:1.05;
  font-size:clamp(1.5rem,4.2vw,2.4rem);color:var(--plum)}
.band h2.sec{color:inherit}

/* ── the grid of jars ────────────────────────────────────────────────────── */
.grid{display:grid;gap:clamp(.5rem,1.1vw,1rem);
  grid-template-columns:repeat(auto-fill,minmax(clamp(8rem,14vw,11.5rem),1fr))}
@media(min-width:74rem){.grid{grid-template-columns:repeat(5,1fr)}}

.tile{position:relative;border-radius:var(--radius);padding:.9rem .9rem 0;text-align:center;
  display:grid;grid-template-rows:1fr auto;transition:background-color .35s var(--ease)}
.hf-motion .tile{opacity:0}
.tile img,.tile__blank{inline-size:100%;block-size:auto;aspect-ratio:3/4;object-fit:contain;
  /* a 250g shaker really is taller than a 170g jar, so the jars stand down on
     the same line rather than every product being stretched to one box */
  object-position:50% 100%;scale:var(--s,1);transform-origin:50% 100%;
  transition:transform .45s var(--ease)}
.tile__blank{display:block;border-radius:.8rem;background:rgb(60 26 87 / .06)}
.tile__nm{padding:.5rem .1rem 0;font-family:var(--display);font-weight:800;font-size:.95rem;
  letter-spacing:-.015em;color:var(--plum)}
.tile__sub{padding:.05rem .1rem .85rem;font-family:var(--mono);font-size:.6rem;color:var(--faint);
  letter-spacing:.1em;text-transform:uppercase}
.tile::after{content:"";position:absolute;inset-block-start:.9rem;inset-inline-end:.9rem;
  inline-size:.5rem;block-size:.5rem;border-radius:50%;background:var(--c,var(--field));
  transform:scale(0);transition:transform .3s var(--ease)}
/* The whole tile is a link, so the buy button has to sit above it and stop the
   click. It is drawn quietly until the tile is under the pointer, at which
   point it fills in — on a touch screen, where there is no hover, that leaves
   the outlined state, which is still a button. */
.tile__add{position:relative;z-index:2;margin:.15rem .15rem 1rem;
  min-block-size:2.75rem;padding:.55rem .8rem;border-radius:999px;
  display:inline-flex;align-items:center;justify-content:center;gap:.4rem;
  border:1.5px solid rgb(60 26 87 / .22);color:var(--plum);
  font-family:var(--display);font-weight:800;font-size:.82rem;line-height:1;
  transition:background-color .28s var(--ease),color .28s var(--ease),
             border-color .28s var(--ease),opacity .2s}
.tile__add .icon{inline-size:.95rem;block-size:.95rem;flex:none}
.tile:hover .tile__add,.tile:focus-within .tile__add,
.tile__add:hover{background:var(--plum);color:var(--cream);border-color:var(--plum)}
.tile__add.is-busy{opacity:.55;pointer-events:none}
/* Added: the tick holds long enough to be read, then the button goes back. */
.tile__add.is-in{background:var(--plum);color:var(--cream);border-color:var(--plum)}

.tile:hover,.tile:focus-within{background:#F1E8DA}
.tile:hover img,.tile:focus-within img{transform:scale(1.06)}
.tile:hover::after,.tile:focus-within::after{transform:scale(1)}
/* The overlay link, and only it: the buy button is an anchor too when the jar
   has a choice to make. */
.tile > a{position:absolute;inset:0;border-radius:var(--radius)}
.tile > a.tile__add{position:relative;inset:auto}

/* ── buttons ─────────────────────────────────────────────────────────────── */
.cta{display:inline-block;padding:.9rem 1.7rem;border-radius:999px;background:var(--cream);
  color:var(--plum);font-family:var(--display);font-weight:800;font-size:.93rem;
  white-space:nowrap;will-change:transform;transition:box-shadow .3s var(--ease)}
.cta:hover{box-shadow:0 .8rem 1.4rem rgb(0 0 0 / .3)}
.ghostbtn{display:inline-block;padding:.86rem 1.6rem;border-radius:999px;
  border:1.5px solid rgb(255 255 255 / .5);font-family:var(--display);font-weight:800;
  font-size:.92rem;transition:background-color .3s,color .3s,border-color .3s}
.ghostbtn:hover{background:var(--cream);color:var(--plum);border-color:var(--cream)}
.more{display:flex;justify-content:center;margin-block-start:clamp(1.8rem,4vw,3rem)}
.more a{padding:.9rem 1.9rem;border-radius:999px;border:1.5px solid rgb(60 26 87 / .28);
  font-family:var(--display);font-weight:800;font-size:.93rem;color:var(--plum);
  transition:background-color .3s var(--ease),color .3s var(--ease),border-color .3s var(--ease)}
.more a:hover{background:var(--plum);color:var(--cream);border-color:var(--plum)}
.band .more a{border-color:rgb(255 255 255 / .5);color:inherit}
.band .more a:hover{background:var(--cream);color:var(--plum);border-color:var(--cream)}

/* a punched shelf tag, because that is what a price is on a shelf */
.tag{position:relative;padding:.6rem 1rem .6rem 1.5rem;border-radius:.3rem .55rem .55rem .3rem;
  background:var(--gold);color:var(--ink);rotate:-2.5deg;
  font-family:var(--display);font-weight:800;font-size:1.35rem;line-height:1}
.tag::before{content:"";position:absolute;inset-block-start:50%;inset-inline-start:.5rem;
  inline-size:.4rem;block-size:.4rem;border-radius:50%;translate:0 -50%;background:var(--field);
  transition:background-color .8s var(--ease)}
/* The weight, not every span: WooCommerce's price is itself built out of spans,
   and a rule on `.tag span` would set the price in the small mono face too. */
.tag__w{display:block;font-family:var(--mono);font-size:.55rem;font-weight:500;
  letter-spacing:.2em;opacity:.68;margin-block-start:.25rem}
.tag del{opacity:.5;font-size:.72em;font-weight:500}
.tag ins{text-decoration:none}
.tag__p{display:block;white-space:nowrap}
/* a variable product prints a range, which is half as wide again as one price */
.tag__p:has(.woocommerce-Price-amount + .woocommerce-Price-amount){font-size:.72em}

/* ── the footer ──────────────────────────────────────────────────────────────
   The last band, and the one a visitor lands in when they did not find what
   they came for — so it is a set of labelled columns rather than a centred
   heap: the shop and how to reach it first, then everything the shop has
   chosen to link, then the small print on a line of its own.

   The inline padding sits on the two inner blocks rather than on the footer,
   so the stitched edge can run the full width of the page above them. */
.foot{--fg:#C2B7AC;--line:rgb(251 247 241 / .13);
  background:var(--ink);color:var(--fg);position:relative;z-index:9;font-size:.88rem}
.foot__in,.foot__end{max-inline-size:calc(76rem + 2 * var(--gut));margin-inline:auto}
/* Named tracks rather than auto-fit: the columns hold lists of very different
   lengths, and a track that wraps leaves a hole the height of the longest list
   above it. Four fixed columns wrap in halves instead, which never does. */
.foot__in{display:grid;align-items:start;gap:clamp(1.9rem,3.4vw,2.8rem) clamp(1.4rem,3vw,3rem);
  grid-template-columns:1fr;
  padding:clamp(2.6rem,6vw,4.2rem) var(--gut) clamp(2rem,4vw,3rem)}
@media(min-width:40rem){.foot__in{grid-template-columns:repeat(2,1fr)}}
@media(min-width:64rem){.foot__in{grid-template-columns:1.5fr 1fr 1fr 1.2fr}}

.foot__brand{max-inline-size:34ch}
.foot .mark--img img{block-size:3rem}
.foot .mark{font-size:1.75rem;color:var(--cream)}
.foot__blurb{margin-block:.85rem 1.3rem;font-size:.92rem;line-height:1.5;opacity:.8}

.foot__contact{list-style:none;display:grid;gap:.2rem;justify-items:start}
.foot__contact a{display:inline-flex;align-items:center;gap:.65rem;
  min-block-size:2.75rem;padding-inline-end:.4rem;font-size:.92rem;
  transition:color .25s}
.foot__contact .icon{flex:none;inline-size:2.1rem;block-size:2.1rem;padding:.5rem;
  border:1px solid var(--line);border-radius:50%;
  transition:border-color .25s,background-color .25s,color .25s}
.foot__contact a:hover .icon{border-color:var(--gold);color:var(--gold)}

/* Not one of the contact rows: the hours are a fact, not a way to get in touch,
   and giving them the same ringed icon would imply they were tappable. */
.foot__hours{display:flex;align-items:center;gap:.65rem;margin-block-start:.9rem;
  font-size:.86rem;opacity:.7}
.foot__hours .icon{flex:none;inline-size:1.05rem;block-size:1.05rem}

/* ── the social row ────────────────────────────────────────────────────────
   Icons only. The network's name is the accessible name rather than a label
   beside it — eight labelled links in a footer is a second navigation, and the
   marks are the most recognisable thing on the page. The touch target is the
   whole circle, which is 2.6rem before the icon inside it is drawn at 1.05. */
.social{list-style:none;display:flex;flex-wrap:wrap;gap:.5rem;margin-block-start:1.4rem}
.social a{display:grid;place-items:center;inline-size:2.6rem;block-size:2.6rem;
  border:1px solid var(--line);border-radius:50%;color:inherit;
  transition:border-color .25s,color .25s,background-color .25s,translate .25s var(--ease)}
.social .icon{inline-size:1.05rem;block-size:1.05rem}
.social a:hover{border-color:var(--gold);color:var(--gold);translate:0 -2px}
.social a:focus-visible{outline:3px solid var(--gold);outline-offset:2px}
@media(prefers-reduced-motion:reduce){.social a{transition:none}.social a:hover{translate:none}}

/* The titles are set as labels rather than as headings: at this size the
   display face reads as another link, and what a column needs is to be
   scannable, not loud. */
.foot__title,
/* A block widget writes its own heading, so the label style is matched onto it
   rather than being something only the classic widget titles get. */
.foot__widget :is(h2,h3,h4){font-family:var(--mono);font-weight:500;font-size:.63rem;
  letter-spacing:.18em;text-transform:uppercase;color:rgb(251 247 241 / .5);
  margin-block-end:.9rem}

/* The marks are a column, not a tail on the brand. The row's own top margin is
   for sitting under a paragraph; here it sits under a column label like every
   other column does, so the label's own margin is the only gap. Four to a line
   keeps eight marks as two tidy rows in a track this narrow rather than as a
   ragged three-and-a-bit. */
.foot__social .social{margin-block-start:0;max-inline-size:calc(4 * 2.6rem + 3 * .5rem)}

/* Whatever the shop has put in the widget areas is one column, stacked, rather
   than one column each: the theme's own columns are the backbone. */
.foot__cols{display:grid;gap:1.7rem;align-content:start}
.foot__cols:empty{display:none}
.foot__col ul,.foot__widget ul{list-style:none;display:grid;gap:.05rem;justify-items:start}
.foot__col a,.foot__widget a{display:inline-block;padding-block:.36rem;
  text-decoration:underline;text-decoration-color:transparent;text-underline-offset:.32em;
  text-decoration-thickness:1.5px;
  transition:color .25s,text-decoration-color .25s}
.foot__col a:hover,.foot__widget a:hover{text-decoration-color:var(--gold)}
.foot__widget{font-size:.88rem}

/* A note to the shop owner who has scrolled this far, boxed so it is not read
   as one more link in the column above it. No button: the block says one
   thing, and the sentence is the thing. */
.foot__trade{margin-block-start:1.7rem;border:1px solid var(--line);
  border-radius:var(--radius);padding:clamp(1.1rem,2vw,1.4rem)}
.foot__trade p:not(.foot__title){font-size:.86rem;line-height:1.5;opacity:.78;
  max-inline-size:34ch}

.foot__end{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:.9rem 1.5rem;padding:1rem var(--gut) 1.3rem;
  border-block-start:1px solid var(--line);font-size:.78rem;color:rgb(251 247 241 / .5)}
.foot__top{display:inline-flex;align-items:center;gap:.55rem;padding:.55rem 1rem;
  border:1px solid var(--line);border-radius:999px;
  font-family:var(--mono);font-size:.63rem;letter-spacing:.16em;text-transform:uppercase;
  transition:border-color .25s,color .25s}
.foot__top .icon{inline-size:.9rem;block-size:.9rem;transition:translate .25s var(--ease)}
.foot__top:hover{border-color:rgb(251 247 241 / .4)}
.foot__top:hover .icon{translate:0 -2px}

.foot a:hover{color:var(--cream)}

/* A product page's buy rail is fixed over the foot of the page, so the small
   print gets out from under it. */
body:has(.dock) .foot__end{padding-block-end:5.2rem}

/* The WhatsApp button is fixed to the same corner the small print ends in, so
   the row leaves it room rather than letting the two overlap. */
@media(min-width:40rem){
  body:has(.wa) .foot__end{padding-inline-end:calc(var(--gut) + 4.4rem)}
}
@media(max-width:40rem){
  .foot__end{flex-direction:column;align-items:flex-start;padding-block-end:5.2rem}
}

/* ── the WhatsApp button ─────────────────────────────────────────────────────
   A circle fixed at the foot of the page, on the side the bar's own buttons are
   on. It steps up out of the way of the product page's buy rail when that is
   showing. */
.wa{position:fixed;z-index:50;inset-block-end:clamp(1rem,3vw,1.6rem);
  inset-inline-end:clamp(1rem,3vw,1.6rem);
  inline-size:3.4rem;block-size:3.4rem;border-radius:50%;
  display:grid;place-items:center;
  /* The glyph is drawn light, not dark. The button sits on the deep red of the
     shop's own field and a dark mark inside a mid-green circle closes up at
     this size — 3.4rem on a desktop, 2.7rem on a phone — into a smudge you
     cannot read as a telephone. White holds the shape at both. */
  background:#25D366;color:#fff;
  box-shadow:0 .5rem 1.4rem rgb(0 0 0 / .28);
  transition:translate .3s var(--ease),box-shadow .3s var(--ease)}
.wa .icon{inline-size:1.6rem;block-size:1.6rem}
.wa:hover,.wa:focus-visible{translate:0 -2px;box-shadow:0 .7rem 1.8rem rgb(0 0 0 / .38)}

/* On a phone the button is sharing the bottom of the screen rather than sitting
   in an empty corner: the front page puts the shelf's own arrows down there,
   and at 3.4rem the circle lands on top of the "next" arrow. Smaller and
   tucked further in — a thumb still has a 43px target, which is over the 24px
   the guidelines ask for and about what a phone's own floating buttons are. */
@media(max-width:34rem){
  .wa{inline-size:2.7rem;block-size:2.7rem;
    inset-block-end:calc(.75rem + env(safe-area-inset-bottom,0px));
    inset-inline-end:.75rem}
  .wa .icon{inline-size:1.3rem;block-size:1.3rem}
}

/* The buy rail is fixed to the same edge, so the button stands on top of it. */
body:has(.dock.on) .wa{translate:0 -4.6rem}
body:has(.dock.on) .wa:hover,body:has(.dock.on) .wa:focus-visible{translate:0 -4.9rem}

/* An open sheet owns the screen. The script already marks everything behind it
   inert, so this is only the look of that. */
.hf-locked .wa{opacity:0;pointer-events:none;transition:opacity .25s}


/* ── the rail that follows you down a product page ───────────────────────── */
.dock{position:fixed;inset-block-end:0;inset-inline:0;z-index:55;translate:0 110%;
  display:flex;align-items:center;gap:1rem;padding:.7rem var(--gut);
  background:rgb(251 247 241 / .95);backdrop-filter:blur(16px);color:var(--plum);
  border-block-start:1px solid rgb(60 26 87 / .12);transition:translate .45s var(--ease)}
.dock.on{translate:0 0}
.dock img{block-size:2.6rem;inline-size:auto}
.dock b{font-family:var(--display);font-weight:800;font-size:1rem;letter-spacing:-.02em}
.dock small{font-family:var(--mono);font-size:.6rem;letter-spacing:.16em;text-transform:uppercase;
  opacity:.7}
.dock .pr{margin-inline-start:auto;font-family:var(--display);font-weight:800;font-size:1.1rem;
  white-space:nowrap}
.dock .pr:has(.woocommerce-Price-amount + .woocommerce-Price-amount){font-size:.9rem}
.dock .cta{background:var(--plum);color:var(--cream);padding:.72rem 1.3rem;font-size:.86rem}
.dock .cta:hover{box-shadow:none;background:var(--ink)}
/* The stepper the script hangs beside the button. The one on the buy form is
   drawn for the field colour behind it; this one stands on paper. */
.dock__qty{display:flex;align-items:center;gap:.1rem;padding:.1rem;border-radius:999px;
  border:1.5px solid rgb(60 26 87 / .26)}
.dock__qty .step{inline-size:2.1rem;block-size:2.1rem}
.dock__qty .step:hover{background:var(--plum);color:var(--cream)}
.dock__n{min-inline-size:1.9rem;text-align:center;font-family:var(--mono);font-size:.85rem}
@media(max-width:34rem){.dock small,.dock .pr{display:none}}

/* ── an empty result ─────────────────────────────────────────────────────── */
.empty{padding-block:clamp(2rem,6vw,4rem);text-align:center}
.empty__title{font-family:var(--display);font-weight:800;font-size:clamp(1.3rem,3vw,1.9rem);
  color:var(--plum);margin-block-end:.5rem}
.empty__body{color:var(--muted);max-inline-size:44ch;margin-inline:auto}
.band .empty__title,.band .empty__body{color:inherit}

/* ── the customers, in their own pictures ────────────────────────────────────
   A pile, not a row. The one being read stands in front and the rest are
   stacked behind it, which is how a handful of phone screenshots actually sits
   on a table. Hovering a card brings it up; clicking one behind deals it to the
   front. Every card sits on the same spot and is pushed sideways by its
   distance from the active one, so the whole section is one number — no track
   to scroll, and therefore no scrollbar to hide.

   The pile follows the grid of jars, and both are cream. Left at full padding
   the two blocks add up to a hand's width of empty paper between the last jar
   and this heading, which reads as the page having ended and started again.
   Halved, the grid and the pile are two parts of one cream page. */
.voices{padding-block-start:clamp(1.4rem,3.5vw,3rem)}

/* Registered so they interpolate as numbers, lengths and angles rather than as
   strings — that is what makes a card glide between positions instead of
   snapping to the next one. */
@property --cx  { syntax:'<length>'; inherits:false; initial-value:0px }
@property --cy  { syntax:'<length>'; inherits:false; initial-value:0px }
@property --cr  { syntax:'<angle>'; inherits:false; initial-value:0deg }
@property --cs  { syntax:'<number>'; inherits:false; initial-value:1 }
@property --chs { syntax:'<number>'; inherits:false; initial-value:1 }
@property --co  { syntax:'<number>'; inherits:false; initial-value:1 }
@property --cb  { syntax:'<number>'; inherits:false; initial-value:1 }
@property --czh { syntax:'<integer>'; inherits:false; initial-value:0 }
/* This one inherits: it is set once on the stage while you drag and every card
   reads it, so a drag is one write and not one per card. */
@property --cdx { syntax:'<length>'; inherits:true; initial-value:0px }
/* And this one so the countdown and the timer are one number in two places
   rather than two numbers that drift apart. */
@property --cdur{ syntax:'<time>'; inherits:true; initial-value:5000ms }

.pile{
  /* As large as the column allows, but never taller than two thirds of the
     window — a card you have to scroll to see is not a card. */
  --cw:min(clamp(13rem,74vw,19rem),calc(62svh * 9 / 16));
  --ch:calc(var(--cw) * 16 / 9);
  margin-block-start:clamp(.5rem,2vw,1.5rem)}
.pile__stage{position:relative;block-size:calc(var(--ch) * 1.14);
  /* the page still scrolls up and down; sideways is ours */
  touch-action:pan-y;cursor:grab;-webkit-user-select:none;user-select:none}
.pile--drag .pile__stage{cursor:grabbing}
.pile__stage:focus-visible{outline:2px solid var(--plum);outline-offset:10px;
  border-radius:var(--radius)}

.pile__card{
  position:absolute;
  /* Centred by margin, so the box the browser sees is the box you see — a
     transform-centred card gets scrolled into view when it takes focus,
     because scrolling ignores transforms. */
  inset:0;margin:auto;
  inline-size:var(--cw);block-size:var(--ch);
  border:1px solid rgb(25 21 18 / .1);border-radius:var(--radius);overflow:hidden;
  /* The plum shows for the moment before the photo paints and behind any
     picture whose own proportions leave a sliver — never the cream, which would
     read as a hole in the pile. */
  background:var(--plum);
  box-shadow:0 .6rem 1.6rem rgb(25 21 18 / .12);
  /* Out along the fan, down the arc, then tilted about its own centre. The
     script owns the pile variables and the hover multiplier stays here, so the
     two can never fight over one transform. */
  transform:translate(calc(var(--cx) + var(--cdx)),var(--cy)) rotate(var(--cr))
    scale(calc(var(--cs) * var(--chs)));
  opacity:var(--co);z-index:calc(var(--cz,1) + var(--czh));
  filter:brightness(var(--cb));cursor:pointer;
  transition:transform .55s var(--ease),opacity .45s var(--ease),
    filter .45s var(--ease),border-color .45s var(--ease),box-shadow .45s var(--ease)}
/* The frame is 9:16 whatever was uploaded. `cover` is deliberate: a photo that
   came in the wrong shape is cropped to join the pile rather than allowed to
   break it. */
.pile__card img{display:block;inline-size:100%;block-size:100%;object-fit:cover;
  /* the browser's own image drag would fight ours */
  -webkit-user-drag:none;pointer-events:none}

/* While a card is being dragged it follows the cursor exactly. */
.pile--drag .pile__card{transition:none}
.pile--drag .pile__card:hover{--chs:1}
/* On a touchscreen :hover latches after a tap and the card last picked stays
   inflated. Focus still gets the same treatment. */
@media(hover:none){
  .pile__card:hover{--chs:1;--cb:inherit;--czh:0}
}
.pile__card:hover,
.pile__card:focus-visible{--chs:1.07;--cb:1;
  /* a card you point at comes to the front, and straightens up as it comes */
  --czh:20;--cr:0deg;
  border-color:rgb(25 21 18 / .2);box-shadow:0 1rem 2.4rem rgb(25 21 18 / .2)}
/* The ones behind have further to come, so they come further. */
.pile__card:not([aria-current=true]):hover,
.pile__card:not([aria-current=true]):focus-visible{--chs:1.16}
.pile__card[aria-current=true]{cursor:default}
.pile__card:focus-visible{outline:2px solid var(--plum);outline-offset:4px}

.pile__foot{margin-block-start:clamp(1.2rem,3vw,2rem);
  display:grid;justify-items:center;gap:clamp(.7rem,1.6vw,1.1rem)}
.pile__nav{display:flex;align-items:center;gap:clamp(.8rem,2vw,1.2rem)}
.pile__bar{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:.4rem;
  inline-size:88%}

.pile__count{font-family:var(--mono);font-size:.7rem;font-weight:500;line-height:1;
  color:var(--faint);font-variant-numeric:tabular-nums;
  /* A count is read left to right whatever the page around it does; without
     this the two halves swap and 01 / 06 comes out as 06 / 01. */
  direction:ltr;display:flex;gap:.35em}
.pile__count b{color:var(--plum);font-weight:500}

.arrow{inline-size:2.75rem;block-size:2.75rem;border:1px solid rgb(25 21 18 / .2);
  border-radius:50%;color:var(--plum);display:grid;place-items:center;
  transition:background-color .3s var(--ease),border-color .3s var(--ease),color .3s var(--ease)}
.arrow .icon{inline-size:1.05rem;block-size:1.05rem;transition:translate .3s var(--ease)}
@media(hover:hover){
  .arrow:hover{background:var(--plum);border-color:var(--plum);color:var(--cream)}
  /* The nudge follows the arrow, and the arrow follows the reading order: in
     Arabic "previous" is the one pointing right, so it leans right. */
  #hf-pile-prev:hover .icon{translate:-2px 0}
  #hf-pile-next:hover .icon{translate:2px 0}
  [dir=rtl] #hf-pile-prev:hover .icon{translate:2px 0}
  [dir=rtl] #hf-pile-next:hover .icon{translate:-2px 0}
}

/* One segment per message. */
.pile__seg{position:relative;block-size:1.5rem;display:grid;align-items:center}
.pile__seg::after{content:'';display:block;block-size:2px;
  background:rgb(25 21 18 / .16);
  transition:background-color .35s var(--ease),block-size .35s var(--ease)}
.pile__seg.on::after{background:rgb(25 21 18 / .3);block-size:3px}
@media(hover:hover){
  .pile__seg:hover::after{background:rgb(25 21 18 / .4)}
}
/* The wait, drawn — so the pile moving on its own is announced rather than
   sprung on you.

   Drawn by scaling, not by growing. `inline-size` is a layout property: animating
   it makes the browser lay the page out again on every frame of a five-second bar
   that restarts for ever, and it was the single largest thing on this page's main
   thread. A transform is composited — same picture, no layout at all. */
.pile__seg::before{content:'';position:absolute;inset-inline-start:0;
  inset-block-start:50%;inline-size:100%;block-size:3px;
  background:var(--plum);opacity:0;
  transform:translateY(-50%) scaleX(0);transform-origin:0 50%}
.pile--auto .pile__seg.on::before{opacity:1;
  animation:hf-segfill var(--cdur) linear forwards}
/* Pointing at the pile holds it, and the fill holds with it. */
.pile:hover .pile__seg.on::before,
.pile:focus-within .pile__seg.on::before{animation-play-state:paused}
@keyframes hf-segfill{from{transform:translateY(-50%) scaleX(0)}
  to{transform:translateY(-50%) scaleX(1)}}
/* `inset-inline-start` mirrors on its own; `transform-origin` does not, so the bar
   is told which end to grow from. */
[dir=rtl] .pile__seg::before{transform-origin:100% 50%}

@media(min-width:44rem){
  .pile{--cw:min(clamp(15rem,27vw,23rem),calc(66svh * 9 / 16))}
  .arrow{inline-size:2.9rem;block-size:2.9rem}
  .pile__bar{inline-size:min(20rem,72%)}
}
@media(max-height:40rem){
  .pile{--cw:min(clamp(9rem,40vw,15rem),calc(58svh * 9 / 16))}
}
/* A 24px target is fine for a cursor and useless for a thumb. */
@media(pointer:coarse){
  .pile__seg{block-size:2.75rem}
}

/* ── motion, and the promise not to ──────────────────────────────────────── */
[data-fade]{opacity:0;translate:0 1.4rem}
.hf-motion-off [data-fade],.hf-motion-off .tile{opacity:1;translate:none}

@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important}
  [data-fade],.tile{opacity:1;translate:none}
}

/* ── the burger ──────────────────────────────────────────────────────────────
   The same circle as the cart, so the two read as a pair, with the three rules
   folding into a cross when the sheet is open. */
.burger{display:none;position:relative;inline-size:2.6rem;block-size:2.6rem;border-radius:50%;
  border:1.5px solid rgb(255 255 255 / .42);
  transition:background-color .25s,color .25s,border-color .25s}
.burger i{position:absolute;left:50%;inline-size:1.05rem;block-size:1.5px;
  border-radius:2px;background:currentColor;translate:-50% 0;
  transition:translate .3s var(--ease),rotate .3s var(--ease),opacity .2s}
.burger i:nth-child(1){inset-block-start:calc(50% - .34rem)}
.burger i:nth-child(2){inset-block-start:calc(50% - .75px)}
.burger i:nth-child(3){inset-block-start:calc(50% + .34rem)}
.burger:hover{background:var(--cream);color:var(--plum);border-color:var(--cream)}
.bar.light .burger{border-color:rgb(60 26 87 / .3)}
.bar.light .burger:hover{background:var(--plum);color:var(--cream);border-color:var(--plum)}
.burger[aria-expanded=true] i:nth-child(1){translate:-50% .34rem;rotate:45deg}
.burger[aria-expanded=true] i:nth-child(2){opacity:0}
.burger[aria-expanded=true] i:nth-child(3){translate:-50% -.34rem;rotate:-45deg}
@media(max-width:58rem){.burger{display:block}}

/* ── the overlays ────────────────────────────────────────────────────────────
   One shell for both the menu sheet and the cart drawer: a scrim that takes the
   click, and a panel that comes in from wherever it belongs. `hidden` is taken
   off a frame before `.on` goes on, so the panel has a state to move from. */
/* `overflow:hidden` on its own is not a lock on iOS Safari, which happily keeps
   scrolling the page behind a fixed overlay. Pinning the body and holding the
   place it was at is the only thing that stops it everywhere; site.js writes the
   offset and puts the page back where it was on the way out. */
.hf-locked{position:fixed;inline-size:100%;overflow:hidden}
.sheet{position:fixed;inset:0;z-index:80;display:grid}
.sheet[hidden]{display:none}
.sheet__scrim{position:absolute;inset:0;background:rgb(25 21 18 / .55);opacity:0;
  backdrop-filter:blur(3px);transition:opacity .35s var(--ease)}
.sheet.on .sheet__scrim{opacity:1}

/* the menu: a whole sheet of plum, because the navigation is five words */
.sheet__panel{position:relative;justify-self:stretch;align-self:stretch;display:flex;
  flex-direction:column;background:var(--plum);color:var(--cream);overflow:hidden auto;
  padding:clamp(.8rem,2vw,1.35rem) var(--gut) 3.2rem;
  opacity:0;translate:0 -1.5rem;transition:opacity .4s var(--ease),translate .45s var(--ease)}
.sheet.on .sheet__panel{opacity:1;translate:0 0}
.sheet__top{display:flex;align-items:center;justify-content:space-between;gap:1rem;
  min-block-size:2.6rem}
.shut{inline-size:2.6rem;block-size:2.6rem;border-radius:50%;display:grid;place-items:center;
  border:1.5px solid rgb(255 255 255 / .42);transition:background-color .25s,color .25s}
.shut .icon{inline-size:1rem;block-size:1rem}
.shut:hover{background:var(--cream);color:var(--plum)}

.sheet__nav{flex:1;display:flex;flex-direction:column;justify-content:center;
  padding-block:clamp(1.5rem,6vh,3rem)}
.sheet__nav a{position:relative;display:block;font-family:var(--display);font-weight:800;
  letter-spacing:-.03em;line-height:1.06;font-size:clamp(2rem,11vw,3.4rem);
  padding-block:clamp(.5rem,1.6vh,.9rem);border-block-end:1px solid rgb(255 255 255 / .16);
  transition:color .25s,padding-inline-start .3s var(--ease)}
.sheet__nav a:first-child{border-block-start:1px solid rgb(255 255 255 / .16)}
.sheet__nav a:hover{padding-inline-start:.6rem;color:var(--gold)}
.sheet__nav a[aria-current]{color:var(--gold)}
.sheet__nav a[aria-current]::after{content:"";position:absolute;inset-block-start:50%;
  inset-inline-end:.2rem;inline-size:.5rem;block-size:.5rem;border-radius:50%;
  background:var(--gold);translate:0 -50%}

.sheet__foot{display:flex;flex-wrap:wrap;align-items:center;gap:.8rem 1.6rem;
  font-size:.86rem;opacity:.8}
.sheet__contact{display:flex;gap:1.2rem;margin-inline-start:auto}
.sheet__contact a:hover,.sheet__foot a:hover{color:var(--gold)}
.sheet__origin{opacity:.6;order:-1}
/* In the sheet the row sits on its own line under everything else, and the
   margin the footer gives it would push it off the bottom of a short phone. */
.social--sheet{flex-basis:100%;margin-block-start:0;opacity:1}
.sheet__stitch{position:absolute;inset-block-end:0;inset-inline:0;block-size:.8rem;
  background:var(--gold);
  -webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12'%3E%3Cg fill='%23000'%3E%3Crect x='0' y='9' width='3' height='3'/%3E%3Crect x='3' y='6' width='3' height='3'/%3E%3Crect x='6' y='3' width='3' height='3'/%3E%3Crect x='9' y='0' width='3' height='3'/%3E%3Crect x='12' y='0' width='3' height='3'/%3E%3Crect x='15' y='3' width='3' height='3'/%3E%3Crect x='18' y='6' width='3' height='3'/%3E%3Crect x='21' y='9' width='3' height='3'/%3E%3C/g%3E%3C/svg%3E");
          mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12'%3E%3Cg fill='%23000'%3E%3Crect x='0' y='9' width='3' height='3'/%3E%3Crect x='3' y='6' width='3' height='3'/%3E%3Crect x='6' y='3' width='3' height='3'/%3E%3Crect x='9' y='0' width='3' height='3'/%3E%3Crect x='12' y='0' width='3' height='3'/%3E%3Crect x='15' y='3' width='3' height='3'/%3E%3Crect x='18' y='6' width='3' height='3'/%3E%3Crect x='21' y='9' width='3' height='3'/%3E%3C/g%3E%3C/svg%3E");
  -webkit-mask-size:1.6rem .8rem;mask-size:1.6rem .8rem;
  -webkit-mask-repeat:repeat-x;mask-repeat:repeat-x;transform:scaleY(-1)}

/* ── the cart drawer ─────────────────────────────────────────────────────── */
.sheet--side{justify-items:end}
.drawer{position:relative;display:flex;flex-direction:column;inline-size:min(27rem,100vw);
  max-inline-size:100%;block-size:100%;background:var(--cream);color:var(--ink);
  translate:100% 0;transition:translate .45s var(--ease)}
.sheet--side.on .drawer{translate:0 0}
html[dir=rtl] .drawer{translate:-100% 0}
html[dir=rtl] .sheet--side.on .drawer{translate:0 0}
.drawer__top{display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:1.1rem var(--gut) 1rem;padding-inline:1.3rem}
.drawer__h{font-family:var(--display);font-weight:800;font-size:1.35rem;letter-spacing:-.02em;
  color:var(--plum)}
.drawer .shut{border-color:rgb(60 26 87 / .28);color:var(--plum)}
.drawer .shut:hover{background:var(--plum);color:var(--cream)}
.drawer__stitch{display:block;block-size:.55rem;flex:none;background:var(--gold);
  -webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12'%3E%3Cg fill='%23000'%3E%3Crect x='0' y='9' width='3' height='3'/%3E%3Crect x='3' y='6' width='3' height='3'/%3E%3Crect x='6' y='3' width='3' height='3'/%3E%3Crect x='9' y='0' width='3' height='3'/%3E%3Crect x='12' y='0' width='3' height='3'/%3E%3Crect x='15' y='3' width='3' height='3'/%3E%3Crect x='18' y='6' width='3' height='3'/%3E%3Crect x='21' y='9' width='3' height='3'/%3E%3C/g%3E%3C/svg%3E");
          mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12'%3E%3Cg fill='%23000'%3E%3Crect x='0' y='9' width='3' height='3'/%3E%3Crect x='3' y='6' width='3' height='3'/%3E%3Crect x='6' y='3' width='3' height='3'/%3E%3Crect x='9' y='0' width='3' height='3'/%3E%3Crect x='12' y='0' width='3' height='3'/%3E%3Crect x='15' y='3' width='3' height='3'/%3E%3Crect x='18' y='6' width='3' height='3'/%3E%3Crect x='21' y='9' width='3' height='3'/%3E%3C/g%3E%3C/svg%3E");
  -webkit-mask-size:1.1rem .55rem;mask-size:1.1rem .55rem;
  -webkit-mask-repeat:repeat-x;mask-repeat:repeat-x}
.drawer > .widget_shopping_cart_content{flex:1;display:flex;flex-direction:column;
  min-block-size:0;overflow:hidden auto}
.drawer__foot{margin-block-start:auto;padding:1.1rem 1.3rem calc(1.3rem + env(safe-area-inset-bottom));
  border-block-start:1px solid rgb(60 26 87 / .14);background:#F5EEE2;position:sticky;
  inset-block-end:0}
.drawer__sum{display:flex;align-items:baseline;justify-content:space-between;
  margin-block-end:.85rem}
.drawer__sum .mono{color:var(--faint)}
.drawer__sum b{font-family:var(--display);font-weight:800;font-size:1.35rem;color:var(--plum)}
.drawer__go{display:block;inline-size:100%;text-align:center;background:var(--plum);
  color:var(--cream)}
.drawer__go:hover{box-shadow:none;background:var(--ink)}
.drawer__back{display:block;inline-size:100%;padding-block:.7rem;margin-block-start:.3rem;
  font-size:.85rem;color:var(--muted);text-decoration:underline;text-underline-offset:.2em}
.drawer__back:hover{color:var(--plum)}
.drawer__empty{padding:2.6rem 1.3rem;text-align:center;margin-block:auto}
.drawer__empty-t{font-family:var(--display);font-weight:800;font-size:1.3rem;color:var(--plum)}
.drawer__empty-b{color:var(--muted);font-size:.9rem;margin-block:.5rem 1.4rem}

/* ── one line of the basket, in the drawer and on the checkout ───────────── */
.lines{list-style:none;display:flex;flex-direction:column}
.line{display:grid;align-items:center;gap:.2rem .9rem;padding-block:.95rem;
  grid-template-columns:auto minmax(0,1fr) auto auto auto;
  border-block-end:1px solid rgb(60 26 87 / .12)}
.line:first-child{border-block-start:1px solid rgb(60 26 87 / .12)}
.line__shot{position:relative;inline-size:3.4rem;block-size:3.4rem;border-radius:.7rem;
  display:grid;place-items:center;background:color-mix(in srgb,var(--c,var(--plum)) 12%,#fff)}
/* Square, said as a ratio rather than as `block-size:100%`. The photographs are
   tall — 504 by 800 — and WordPress prints those as width and height
   attributes, from which the browser gives the image an aspect ratio of its
   own. Against that, the percentage height resolved to auto and the jar grew
   out of the bottom of its box: in the basket at narrow widths, and in the
   drawer at every width. A ratio of 1 is what the box actually is, and
   object-fit letterboxes the picture inside it. */
.line__img{inline-size:100%;block-size:auto;aspect-ratio:1;object-fit:contain;padding:.3rem}
.line__img--blank{inline-size:100%;block-size:auto;aspect-ratio:1;border-radius:.7rem}
.line__nm{font-family:var(--display);font-weight:800;font-size:.98rem;line-height:1.15;
  letter-spacing:-.015em;color:var(--plum);display:block}
a.line__nm:hover{color:var(--field)}
.line__meta,.line__unit{font-family:var(--mono);font-size:.6rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--faint);margin-block-start:.22rem}
.line__qty{display:flex;align-items:center;gap:.1rem;border-radius:999px;
  border:1.5px solid rgb(60 26 87 / .18)}
.qbtn{inline-size:1.85rem;block-size:1.85rem;border-radius:50%;display:grid;place-items:center;
  font-size:.95rem;line-height:1;color:var(--plum);transition:background-color .2s,color .2s}
.qbtn:hover{background:var(--plum);color:var(--cream)}
/* Specific enough to beat the global number-field rule in pages.css, which
   would otherwise give this one a full-width box, a border and a 12px inset. */
.line input.line__n{inline-size:2.4rem;padding:0;border:0;background:none;text-align:center;
  font-family:var(--mono);font-size:.8rem;font-weight:500;color:var(--ink);border-radius:0;
  -moz-appearance:textfield;appearance:textfield}
.line input.line__n:focus{border:0;outline-offset:1px}
.line input.line__n::-webkit-outer-spin-button,.line input.line__n::-webkit-inner-spin-button{
  -webkit-appearance:none;margin:0}
.line__one{padding:.3rem .8rem;font-family:var(--mono);font-size:.8rem}
.line__sum{font-family:var(--display);font-weight:800;font-size:.98rem;color:var(--plum);
  white-space:nowrap;justify-self:end}
.line__x{inline-size:1.7rem;block-size:1.7rem;border-radius:50%;display:grid;place-items:center;
  color:var(--faint);transition:background-color .2s,color .2s}
.line__x .icon{inline-size:.7rem;block-size:.7rem}
.line__x:hover{background:rgb(196 33 43 / .12);color:var(--field)}
.line.is-busy{opacity:.45;pointer-events:none}
.line.is-going{opacity:0;transition:opacity .25s}

/* the drawer is narrower than a checkout column, so the line folds there */
.lines--mini{padding-inline:1.3rem}
.lines--mini .line{grid-template-columns:auto minmax(0,1fr) auto;gap:.35rem .8rem}
.lines--mini .line__qty{grid-column:2;justify-self:start}
.lines--mini .line__sum{grid-column:3;grid-row:2}
.lines--mini .line__x{grid-column:3;grid-row:1;align-self:start}

@media(prefers-reduced-motion:reduce){
  .sheet__scrim,.sheet__panel,.drawer{transition:none}
}

/* ------------------------------------------------------------------
   Arabic tracking

   The micro-type in this design is tracked wide — .16em, .2em, .34em — because it was drawn as a
   Latin monospaced line. Arabic is cursive: tracking pulls the letters apart at the joins, so
   "التتبيلات" comes out as a row of disconnected shapes. The site is Arabic throughout, so the
   tracking is dropped everywhere rather than rule by rule.

   `!important` because the component sheets — front.css, product.css, wtb.css, checkout.css — all
   load after this file and set their own tracking at the same specificity. This is a property of
   the script, not a style preference, so it wins on purpose.

   A Latin run inside Arabic — a price, a phone number, an ID — is isolated in its own element and
   can opt back in with .track.
   ------------------------------------------------------------------ */
body,
body *:not(.track) { letter-spacing: normal !important; }

.track { letter-spacing: .16em !important; }
