@charset "UTF-8";
/* ==========================================================================
   KAMJOO — Home components: hero, product card, countdown, tiles, footer
   ========================================================================== */

/* ==========================================================================
   HERO
   ========================================================================== */
.kj-hero {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--kj-gutter);
  padding-block: var(--kj-s5);
}
@media (min-width: 992px) {
  .kj-hero { grid-template-columns: 1fr 300px; align-items: stretch; }
}

.kj-hero__main {
  position: relative;
  border-radius: var(--kj-r-xl);
  overflow: hidden;
  background: var(--kj-surface-3);
  /* Heights are sized for the WORST case: a two-line product title plus
     eyebrow, description, price and a 44px CTA. Slides are absolutely
     positioned (needed for the crossfade) so they cannot push this box
     taller — if the content did not fit, overflow:hidden would slice the
     CTA in half. The title/text clamps below keep that promise for any
     product name length. */
  min-height: 300px;
}
@media (min-width: 768px) { .kj-hero__main { min-height: 360px; } }
@media (min-width: 1200px) { .kj-hero__main { min-height: 420px; } }

.kj-hero__slides { position: relative; width: 100%; height: 100%; }
.kj-hero__slide {
  position: absolute; inset: 0;
  display: grid;
  grid-template-columns: 1fr;
  align-items: center;
  align-content: center;
  /* Extra bottom padding reserves the dots row so the CTA can never sit
     underneath it. */
  padding: var(--kj-s6) var(--kj-s6) var(--kj-s10);
  opacity: 0; visibility: hidden;
  transition: opacity var(--kj-t-slow) var(--kj-ease);
}
.kj-hero__slide > * { min-width: 0; min-height: 0; }
.kj-hero__slide.is-active { opacity: 1; visibility: visible; }
@media (min-width: 768px) {
  .kj-hero__slide {
    grid-template-columns: 1.05fr .95fr; gap: var(--kj-s5);
    padding: var(--kj-s8) var(--kj-s10) var(--kj-s12);
  }
}

/* Decorative multi-stop gradients stay on fixed literals by design. They are
   illustration, not brand chrome: each is dark enough for the white text that
   sits on it, and binding them to --kj-primary would let one hub colour pick
   (e.g. a pale yellow) destroy the contrast of every hero slide at once. The
   brand shows through the controls, links and accents instead. */
.kj-hero__slide--v1 { background: linear-gradient(120deg, #7A2BE2 0%, #C026D3 100%); }
.kj-hero__slide--v2 { background: linear-gradient(120deg, #F97008 0%, #FF3B6B 100%); }
.kj-hero__slide--v3 { background: linear-gradient(120deg, #0EA5E9 0%, #7A2BE2 100%); }

.kj-hero__content { position: relative; z-index: 2; color: #fff; }
.kj-hero__eyebrow {
  display: inline-flex; align-items: center; gap: var(--kj-s2);
  height: 28px; padding-inline: var(--kj-s3);
  margin-bottom: var(--kj-s3);
  font-size: var(--kj-fs-xs); font-weight: 700;
  background: rgba(255,255,255,.2);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  border-radius: var(--kj-r-pill);
}
.kj-hero__eyebrow svg { width: 14px; height: 14px; }
.kj-hero__title {
  font-size: var(--kj-fs-4xl);
  font-weight: 800; color: #fff;
  line-height: 1.2; letter-spacing: -.03em;
  margin-bottom: var(--kj-s2);
  text-wrap: balance;
  /* Hard cap at two lines. A real WooCommerce product title can be any
     length; without this the slide content overflows and gets clipped. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.kj-hero__text {
  font-size: var(--kj-fs-md);
  color: rgba(255,255,255,.88);
  margin-bottom: var(--kj-s5);
  max-width: 42ch;
  line-height: var(--kj-lh-snug);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
@media (max-width: 767.98px) { .kj-hero__text { display: none; } }

.kj-hero__price {
  display: flex; align-items: baseline; gap: var(--kj-s2);
  margin-bottom: var(--kj-s5);
}
.kj-hero__price-from { font-size: var(--kj-fs-sm); color: rgba(255,255,255,.8); }
.kj-hero__price-val { font-size: var(--kj-fs-2xl); font-weight: 800; color: #fff; }
.kj-hero__price-cur { font-size: var(--kj-fs-sm); color: rgba(255,255,255,.85); font-weight: 600; }

.kj-hero__cta {
  display: inline-flex; align-items: center; gap: var(--kj-s2);
  min-height: var(--kj-tap); padding-inline: var(--kj-s6);
  font-size: var(--kj-fs-md); font-weight: 800;
  color: var(--kj-violet-700); background: #fff;
  border-radius: var(--kj-r-md);
  box-shadow: 0 8px 24px rgba(0,0,0,.18);
  transition: transform var(--kj-t-fast) var(--kj-ease),
              box-shadow var(--kj-t-base) var(--kj-ease),
              color var(--kj-t-fast) var(--kj-ease);
}
.kj-hero__cta:hover { transform: translateY(-2px); box-shadow: 0 14px 34px rgba(0,0,0,.24); color: var(--kj-violet-800); }
.kj-hero__cta svg { width: 17px; height: 17px; transition: transform var(--kj-t-fast) var(--kj-ease); }
.kj-hero__cta:hover svg { transform: translateX(-3px); }

.kj-hero__media { position: relative; display: none; }
@media (min-width: 768px) { .kj-hero__media { display: grid; place-items: center; } }
/* Product photography is shot on white. Rather than fight it on a coloured
   panel, we present it on a deliberate rounded "photo plate" — it reads as a
   designed frame instead of a stray white rectangle, and it works with any
   supplier image without per-image masking. */
.kj-hero__media img {
  max-height: 300px; width: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  background: #fff;
  border-radius: var(--kj-r-lg);
  box-shadow: 0 24px 44px rgba(0,0,0,.26), 0 0 0 1px rgba(255,255,255,.35);
  animation: kj-float 5s var(--kj-ease) infinite;
}
@keyframes kj-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-14px); }
}
/* Decorative blobs */
.kj-hero__slide::before {
  content: ""; position: absolute;
  width: 320px; height: 320px;
  inset-inline-end: -80px; top: -110px;
  background: radial-gradient(circle, rgba(255,255,255,.18) 0%, transparent 68%);
  border-radius: 50%;
  pointer-events: none;
}

/* Hero controls */
/* The CTA is pinned to the content side (right in RTL). The dots therefore
   live on the OPPOSITE side, otherwise the two overlap and the dots become
   unclickable furniture on top of the primary action. */
.kj-hero__dots {
  position: absolute; bottom: var(--kj-s4);
  inset-inline-end: var(--kj-s6);
  display: flex; align-items: center; gap: var(--kj-s3);
  z-index: 3;
}
.kj-hero__dot {
  width: 9px; height: 9px; padding: 0;
  border-radius: var(--kj-r-pill);
  background: rgba(255,255,255,.45);
  transition: width var(--kj-t-base) var(--kj-ease), background var(--kj-t-base) var(--kj-ease);
}
.kj-hero__dot.is-active { width: 28px; background: #fff; }
/* Enlarge the hit area without enlarging the visual dot.
   The dot is 9px tall, so -18px on each side yields 45px of touchable
   height — clears the 44px minimum target with a pixel to spare. */
.kj-hero__dot { position: relative; }
.kj-hero__dot::after { content: ""; position: absolute; inset: -19px -9px; }

.kj-hero__arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 40px; height: 40px;
  display: none; place-items: center;
  color: #fff;
  background: rgba(255,255,255,.18);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  border-radius: var(--kj-r-pill);
  z-index: 3;
  transition: background var(--kj-t-fast) var(--kj-ease);
}
.kj-hero__main:hover .kj-hero__arrow { display: grid; }
.kj-hero__arrow:hover { background: rgba(255,255,255,.32); }
.kj-hero__arrow svg { width: 19px; height: 19px; }
.kj-hero__arrow--prev { inset-inline-start: var(--kj-s4); }
.kj-hero__arrow--next { inset-inline-end: var(--kj-s4); }
@media (max-width: 767.98px) { .kj-hero__arrow { display: none !important; } }

/* Hero side cards */
.kj-hero__side { display: grid; grid-template-rows: repeat(2, 1fr); gap: var(--kj-gutter); }
@media (max-width: 991.98px) {
  .kj-hero__side { grid-template-rows: none; grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 479.98px) { .kj-hero__side { grid-template-columns: 1fr; } }

.kj-hero__card {
  position: relative;
  display: flex; flex-direction: column; justify-content: space-between;
  padding: var(--kj-s5);
  border-radius: var(--kj-r-lg);
  overflow: hidden;
  min-height: 140px;
  transition: transform var(--kj-t-base) var(--kj-ease-out),
              box-shadow var(--kj-t-base) var(--kj-ease);
}
.kj-hero__card:hover { transform: translateY(-4px); box-shadow: var(--kj-sh-lg); }
.kj-hero__card--mint { background: linear-gradient(135deg, #05C08B 0%, #0EA5E9 100%); }
.kj-hero__card--amber { background: linear-gradient(135deg, #FFC53D 0%, #F97008 100%); }
.kj-hero__card-title { font-size: var(--kj-fs-lg); font-weight: 800; color: #fff; margin-bottom: var(--kj-s1); }
.kj-hero__card-text { font-size: var(--kj-fs-xs); color: rgba(255,255,255,.9); }
.kj-hero__card-link {
  display: inline-flex; align-items: center; gap: var(--kj-s1);
  font-size: var(--kj-fs-sm); font-weight: 700; color: #fff;
  margin-top: var(--kj-s3);
}
.kj-hero__card-link svg { width: 15px; height: 15px; transition: transform var(--kj-t-fast) var(--kj-ease); }
.kj-hero__card:hover .kj-hero__card-link svg { transform: translateX(-4px); }
.kj-hero__card img {
  position: absolute; inset-inline-end: var(--kj-s4); bottom: var(--kj-s4);
  width: 84px; height: 84px; object-fit: cover;
  background: #fff;
  border-radius: var(--kj-r-md);
  box-shadow: 0 10px 20px rgba(0,0,0,.22), 0 0 0 1px rgba(255,255,255,.4);
}

/* ==========================================================================
   SERVICE STRIP
   ========================================================================== */
.kj-services {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--kj-s3);
  padding: var(--kj-s5);
  background: var(--kj-surface);
  border-radius: var(--kj-r-lg);
  box-shadow: var(--kj-sh-sm);
}
.kj-service { display: flex; align-items: center; gap: var(--kj-s3); min-width: 0; }
/* The text column: title over subtitle. Both are <span>, so they must be
   told to stack — inline spans would otherwise run on a single line. */
.kj-service > span:not(.kj-service__icon) {
  display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.kj-service__icon {
  flex: none; width: 44px; height: 44px;
  display: grid; place-items: center;
  border-radius: var(--kj-r-md);
  background: var(--kj-primary-soft); color: var(--kj-primary-ink, var(--kj-primary));
}
.kj-service__icon svg { width: 22px; height: 22px; }
.kj-service__title {
  display: block; font-size: var(--kj-fs-sm); font-weight: 700; color: var(--kj-ink);
  line-height: var(--kj-lh-snug);
}
.kj-service__text {
  display: block; font-size: var(--kj-fs-xs); color: var(--kj-muted);
  line-height: var(--kj-lh-snug);
}

/* Section wrapper: the strip sits between hero and categories. */
.kj-services-wrap { margin-block: var(--kj-s8); }

/* ==========================================================================
   PRODUCT CARD
   ========================================================================== */
.kj-card {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
  overflow: hidden;
  transition: border-color var(--kj-t-base) var(--kj-ease),
              box-shadow var(--kj-t-base) var(--kj-ease),
              transform var(--kj-t-base) var(--kj-ease-out);
  height: 100%;
}
.kj-card:hover {
  border-color: transparent;
  box-shadow: var(--kj-sh-lg);
  transform: translateY(-4px);
}

.kj-card__media {
  position: relative;
  aspect-ratio: 1 / 1;
  background: var(--kj-surface);
  overflow: hidden;
}
.kj-card__img {
  width: 100%; height: 100%;
  object-fit: contain;
  padding: var(--kj-s4);
  transition: transform var(--kj-t-slow) var(--kj-ease-out);
}
.kj-card:hover .kj-card__img { transform: scale(1.06); }

.kj-card__badges {
  position: absolute; top: var(--kj-s3); inset-inline-start: var(--kj-s3);
  display: flex; flex-direction: column; gap: var(--kj-s1);
  z-index: 2;
}

/* Quick actions — always present in DOM, revealed on hover / focus */
.kj-card__quick {
  position: absolute; top: var(--kj-s3); inset-inline-end: var(--kj-s3);
  display: flex; flex-direction: column; gap: var(--kj-s2);
  z-index: 2;
  opacity: 0; transform: translateX(8px);
  transition: opacity var(--kj-t-base) var(--kj-ease), transform var(--kj-t-base) var(--kj-ease);
}
[dir="rtl"] .kj-card__quick { transform: translateX(-8px); }
.kj-card:hover .kj-card__quick,
.kj-card:focus-within .kj-card__quick { opacity: 1; transform: none; }
/* Touch devices: no hover, so always show */
@media (hover: none) {
  .kj-card__quick { opacity: 1; transform: none; }
}
.kj-card__qbtn {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  color: var(--kj-muted);
  background: var(--kj-surface);
  border-radius: var(--kj-r-pill);
  box-shadow: var(--kj-sh-sm);
  transition: background var(--kj-t-fast) var(--kj-ease),
              color var(--kj-t-fast) var(--kj-ease),
              transform var(--kj-t-fast) var(--kj-ease);
}
.kj-card__qbtn:hover { background: var(--kj-primary-solid, var(--kj-primary)); color: var(--kj-on-primary, #fff); transform: scale(1.1); }
.kj-card__qbtn svg { width: 16px; height: 16px; }
.kj-card__qbtn.is-active { background: var(--kj-sale); color: #fff; }

.kj-card__body {
  display: flex; flex-direction: column;
  gap: var(--kj-s2);
  padding: var(--kj-s4);
  flex: 1 1 auto;
}
.kj-card__brand {
  font-size: var(--kj-fs-2xs); font-weight: 600;
  color: var(--kj-faint);
  text-transform: uppercase; letter-spacing: .04em;
}
.kj-card__title {
  font-size: var(--kj-fs-sm);
  font-weight: 600;
  line-height: var(--kj-lh-snug);
  color: var(--kj-body);
  /* exactly 2 lines — prevents the ragged grid iShop suffers from */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  line-clamp: 2; overflow: hidden;
  min-height: calc(var(--kj-fs-sm) * var(--kj-lh-snug) * 2);
  transition: color var(--kj-t-fast) var(--kj-ease);
}
.kj-card__title:hover { color: var(--kj-primary-ink, var(--kj-primary)); }
/* Make the whole card clickable but keep buttons on top */
.kj-card__title::after { content: ""; position: absolute; inset: 0; z-index: 1; }
/* NOTE: .kj-card__quick is absolutely positioned above; it must NOT be reset
   to relative here or the overlay buttons fall into the flow. It already
   carries z-index:2 in its own rule. */
.kj-card__cart, .kj-card__colors { position: relative; z-index: 2; }

.kj-card__rating { display: flex; align-items: center; gap: var(--kj-s1); font-size: var(--kj-fs-xs); }
.kj-card__stars { display: inline-flex; gap: 1px; color: var(--kj-star); }
.kj-card__stars svg { width: 13px; height: 13px; }
.kj-card__rating-val { font-weight: 700; color: var(--kj-ink); }
.kj-card__rating-count { color: var(--kj-faint); }

.kj-card__colors { display: flex; gap: 4px; }
.kj-card__color {
  width: 13px; height: 13px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.9), 0 0 0 1px var(--kj-line);
}

.kj-card__foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--kj-s2);
  margin-top: auto;
  padding-top: var(--kj-s2);
  /* Establish the query container the price sizes against. inline-size only:
     a size container would need a fixed block size too. */
  container-type: inline-size;
}
.kj-card__prices { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1 1 auto; }
.kj-card__old {
  font-size: var(--kj-fs-xs);
  color: var(--kj-faint);
  text-decoration: line-through;
  text-decoration-color: var(--kj-sale);
  /* Never let the struck-through price widen the column. */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* Always occupies one line — empty on non-discounted items — so the price
     and cart button share a baseline across every card in a row. */
  min-height: 1em;
  line-height: 1;
}
.kj-card__old:empty { visibility: hidden; }
.kj-card__price {
  display: flex; align-items: baseline; gap: 3px;
  /* A 9-digit toman price ("۱۳۲,۰۰۰,۰۰۰ تومان") does not fit beside the
     38px cart button in a 186px card. The number keeps the full type size
     and the currency word wraps beneath it only when there is no room —
     `flex-wrap` plus a shrinkable number means narrow cards stay tidy and
     wide cards still render the price on a single line. */
  flex-wrap: wrap;
  min-width: 0;
  /* The type scale is clamped to the column rather than fixed: on a 320px
     phone the card body is ~59px wide and a fixed 15px price overflows its
     own box. cqi units size against the card, so the number always fits.
     The clamp floor keeps it legible and the ceiling stops it growing past
     the intended step on wide cards. */
  font-size: clamp(10px, 5.2cqi, var(--kj-fs-md));
  font-weight: 800; color: var(--kj-ink);
  line-height: 1.2;
}
@media (min-width: 1200px) { .kj-card__price { font-size: clamp(12px, 5.6cqi, var(--kj-fs-lg)); } }
.kj-card__price .kj-num { font-variant-numeric: tabular-nums; }
.kj-card__cur { font-size: var(--kj-fs-2xs); font-weight: 600; color: var(--kj-muted); }
.kj-card__free { font-size: var(--kj-fs-sm); font-weight: 700; color: var(--kj-success-ink); }

.kj-card__cart {
  flex: none;
  /* Shrinks with the card so the price keeps its room on a 320px phone,
     but never below the 32px that stays comfortably tappable inside a
     44px row. */
  width: clamp(32px, 17cqi, 38px);
  height: clamp(32px, 17cqi, 38px);
  display: grid; place-items: center;
  color: var(--kj-on-primary, #fff); background: var(--kj-primary-solid, var(--kj-primary));
  border-radius: var(--kj-r-sm);
  transition: background var(--kj-t-fast) var(--kj-ease),
              transform var(--kj-t-fast) var(--kj-ease-spring),
              box-shadow var(--kj-t-base) var(--kj-ease);
}
.kj-card__cart:hover { background: var(--kj-primary-hover); transform: scale(1.08); box-shadow: var(--kj-sh-brand); }
.kj-card__cart svg { width: clamp(15px, 8cqi, 18px); height: clamp(15px, 8cqi, 18px); }
.kj-card__cart[disabled] { background: var(--kj-surface-3); color: var(--kj-faint); }

/* Stock bar */
.kj-card__stock { display: flex; flex-direction: column; gap: 4px; }
.kj-card__stock-bar {
  height: 4px;
  background: var(--kj-surface-3);
  border-radius: var(--kj-r-pill);
  overflow: hidden;
}
.kj-card__stock-fill {
  height: 100%;
  background: var(--kj-grad-warm);
  border-radius: var(--kj-r-pill);
  transition: width var(--kj-t-slow) var(--kj-ease);
}
.kj-card__stock-text { font-size: var(--kj-fs-2xs); color: var(--kj-muted); font-weight: 500; }
.kj-card__stock-text b { color: var(--kj-sale-ink); font-weight: 800; }

/* Out of stock */
.kj-card--oos .kj-card__img { filter: grayscale(1); opacity: .55; }

/* ==========================================================================
   AMAZING / FLASH SALE
   ========================================================================== */
.kj-flash {
  border-radius: var(--kj-r-xl);
  background: linear-gradient(120deg, #EE2255 0%, #C026D3 55%, #7A2BE2 100%);
  padding: var(--kj-s5);
  overflow: hidden;
}
.kj-flash__inner { display: grid; grid-template-columns: 1fr; gap: var(--kj-gutter); align-items: center; }
@media (min-width: 992px) { .kj-flash__inner { grid-template-columns: 208px 1fr; } }

.kj-flash__aside {
  display: flex; flex-direction: column; align-items: center;
  gap: var(--kj-s3); text-align: center;
  min-width: 0;   /* grid children default to min-width:auto and refuse to shrink */
}
@media (max-width: 991.98px) {
  .kj-flash__aside {
    flex-direction: row;
    flex-wrap: wrap;              /* countdown drops below the title instead of bleeding out */
    justify-content: space-between;
    align-items: center;
    text-align: start;
    row-gap: var(--kj-s2);
  }
  .kj-flash__title { flex: 1 1 auto; min-width: 0; }
  .kj-flash__all   { flex: none; }
}
@media (max-width: 420px) {
  /* Very narrow phones: countdown takes its own full-width row, centred. */
  .kj-flash__aside .kj-count { flex: 1 0 100%; justify-content: center; }
}
.kj-flash__title { font-size: var(--kj-fs-2xl); font-weight: 800; color: #fff; line-height: 1.15; }
.kj-flash__title span { display: block; font-size: var(--kj-fs-sm); font-weight: 600; color: rgba(255,255,255,.85); margin-top: 4px; }

/* Countdown */
.kj-count { display: flex; align-items: center; gap: var(--kj-s1); }
.kj-count__unit {
  display: flex; flex-direction: column; align-items: center;
  min-width: 46px; padding: var(--kj-s2) var(--kj-s1);
  background: rgba(255,255,255,.16);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  border-radius: var(--kj-r-sm);
}
.kj-count__num {
  font-size: var(--kj-fs-xl); font-weight: 800; color: #fff; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.kj-count__lbl { font-size: 9px; color: rgba(255,255,255,.8); font-weight: 600; margin-top: 3px; }
.kj-count__sep { color: rgba(255,255,255,.6); font-weight: 800; }

.kj-flash__all {
  display: inline-flex; align-items: center; gap: var(--kj-s1);
  min-height: 38px; padding-inline: var(--kj-s4);
  font-size: var(--kj-fs-sm); font-weight: 700;
  /* rose-600 is a fill colour, not a text colour: it lands at 4.2:1 on white.
     --kj-sale-ink is the AA-safe ink of the same hue family. */
  color: var(--kj-sale-ink); background: #fff;
  border-radius: var(--kj-r-pill);
  transition: transform var(--kj-t-fast) var(--kj-ease);
}
.kj-flash__all:hover { transform: translateY(-2px); color: var(--kj-sale-ink); }
.kj-flash__all svg { width: 14px; height: 14px; }

.kj-flash__rail { min-width: 0; }
.kj-flash__rail .kj-card { border-color: transparent; }
.kj-flash__rail .kj-hscroll > * { width: 186px; }
@media (min-width: 576px) { .kj-flash__rail .kj-hscroll > * { width: 200px; } }

/* `.kj-card` carries `height:100%` so it fills a GRID cell. Inside a flex
   scroll rail that percentage resolves against an auto-height parent, which
   cancels flex stretching and leaves every card as tall as its own content —
   cards with a stock bar ended up 28px taller than those without. Reverting
   to `height:auto` lets `align-items:stretch` do its job, so a rail row is
   flush regardless of which optional parts each card renders. */
.kj-hscroll { align-items: stretch; }
.kj-hscroll > .kj-card { height: auto; }

/* ==========================================================================
   CATEGORY TILES
   ========================================================================== */
.kj-cats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 104px), 1fr));
  gap: var(--kj-s3);
}
.kj-cat {
  display: flex; flex-direction: column; align-items: center; gap: var(--kj-s2);
  padding: var(--kj-s4) var(--kj-s2);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
  text-align: center;
  transition: border-color var(--kj-t-base) var(--kj-ease),
              box-shadow var(--kj-t-base) var(--kj-ease),
              transform var(--kj-t-base) var(--kj-ease-out);
}
.kj-cat:hover { border-color: var(--kj-violet-200); box-shadow: var(--kj-sh-md); transform: translateY(-4px); }
.kj-cat__media {
  width: 66px; height: 66px;
  display: grid; place-items: center;
  border-radius: var(--kj-r-pill);
  background: var(--kj-surface-2);
  overflow: hidden;
  transition: background var(--kj-t-base) var(--kj-ease);
}
.kj-cat:hover .kj-cat__media { background: var(--kj-primary-soft); }
.kj-cat__media img { width: 78%; height: 78%; object-fit: contain; }
.kj-cat__name {
  font-size: var(--kj-fs-sm); font-weight: 600; color: var(--kj-body);
  transition: color var(--kj-t-fast) var(--kj-ease);
}
.kj-cat:hover .kj-cat__name { color: var(--kj-primary-ink, var(--kj-primary)); }
.kj-cat__count { font-size: var(--kj-fs-2xs); color: var(--kj-faint); }

/* ==========================================================================
   BANNERS
   ========================================================================== */
.kj-banners { display: grid; gap: var(--kj-gutter); grid-template-columns: 1fr; }
@media (min-width: 640px) { .kj-banners { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .kj-banners--3 { grid-template-columns: repeat(3, 1fr); } }

/*
 * Two real columns instead of an absolutely-positioned photo.
 *
 * The photo used to be pinned with `inset-inline-start:0`, which in RTL
 * resolves to the RIGHT edge — the same side the text starts from — so the
 * image sat on top of the title at every width. A grid track cannot overlap
 * its sibling by construction, so the collision is impossible now rather
 * than merely tuned away with percentages.
 *
 * The markup is flat (label, title, text, cta, media), so the text spans are
 * placed in column 1 and the media spans every row of column 2.
 */
.kj-banner {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  align-content: center;
  column-gap: var(--kj-s4);
  min-height: 168px;
  padding: var(--kj-s6);
  border-radius: var(--kj-r-lg);
  overflow: hidden;
  transition: transform var(--kj-t-base) var(--kj-ease-out), box-shadow var(--kj-t-base) var(--kj-ease);
}
.kj-banner > :not(.kj-banner__media) { grid-column: 1; min-width: 0; }
.kj-banner__media { grid-column: 2; grid-row: 1 / -1; }
.kj-banner:hover { transform: translateY(-4px); box-shadow: var(--kj-sh-lg); }
.kj-banner--v { background: linear-gradient(135deg, #7A2BE2, #A472FA); }
.kj-banner--o { background: linear-gradient(135deg, #F97008, #FFC53D); }
.kj-banner--m { background: linear-gradient(135deg, #05C08B, #2BD9A8); }
.kj-banner__label { font-size: var(--kj-fs-xs); font-weight: 700; color: rgba(255,255,255,.85); margin-bottom: 4px; }
.kj-banner__title {
  font-size: var(--kj-fs-xl); font-weight: 800; color: #fff;
  line-height: 1.25; text-wrap: balance;
  /* The grid column already bounds the width; clamp the height so an
     unusually long headline cannot push the CTA out of the banner. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.kj-banner__cta {
  display: inline-flex; align-items: center; gap: var(--kj-s1);
  margin-top: var(--kj-s4);
  font-size: var(--kj-fs-sm); font-weight: 700; color: #fff;
  width: max-content;
}
.kj-banner__cta svg { width: 15px; height: 15px; transition: transform var(--kj-t-fast) var(--kj-ease); }
.kj-banner:hover .kj-banner__cta svg { transform: translateX(-4px); }
/* .kj-banner img positioning lives with .kj-banner__media (see BANNER block below) */

/* ==========================================================================
   BRANDS
   ========================================================================== */
.kj-brands {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 128px), 1fr));
  gap: var(--kj-s3);
}
.kj-brand {
  display: grid; place-items: center;
  height: 78px; padding: var(--kj-s3);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-md);
  transition: border-color var(--kj-t-base) var(--kj-ease),
              box-shadow var(--kj-t-base) var(--kj-ease);
}
.kj-brand:hover { border-color: var(--kj-violet-200); box-shadow: var(--kj-sh-sm); }

/* Logo and text wordmark share one greyed resting state so a row that mixes
   both reads as a single set rather than two kinds of tile. */
.kj-brand__logo,
.kj-brand span {
  color: var(--kj-faint);
  transition: color var(--kj-t-base) var(--kj-ease),
              opacity var(--kj-t-base) var(--kj-ease);
}
/* Width and height are set per-logo in PHP so each glyph lands on the same
   optical size; the max-width only guards very narrow tiles. */
.kj-brand__logo {
  max-width: 100%; height: auto;
  opacity: .62;
}
.kj-brand span {
  font-size: var(--kj-fs-md); font-weight: 800;
  letter-spacing: .02em;
}
.kj-brand:hover .kj-brand__logo { color: var(--kj-primary-ink, var(--kj-primary)); opacity: 1; }
.kj-brand:hover span { color: var(--kj-primary-ink, var(--kj-primary)); }

/* Text fallbacks share the logo box height so mixed rows stay aligned. */
.kj-brand--text span { display: block; line-height: 30px; }

/* ==========================================================================
   BLOG CARD
   ========================================================================== */
.kj-posts { display: grid; gap: var(--kj-gutter); grid-template-columns: 1fr; }
@media (min-width: 640px) { .kj-posts { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .kj-posts { grid-template-columns: repeat(3, 1fr); } }

.kj-post {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
  overflow: hidden;
  transition: border-color var(--kj-t-base) var(--kj-ease),
              box-shadow var(--kj-t-base) var(--kj-ease),
              transform var(--kj-t-base) var(--kj-ease-out);
}
.kj-post:hover { border-color: transparent; box-shadow: var(--kj-sh-lg); transform: translateY(-4px); }
/* The category chip is an overlay on the thumbnail, so the media box is the
   positioning context. `display:block` prevents the inline-image baseline
   gap under the picture. */
.kj-post__media {
  position: relative; display: block;
  aspect-ratio: 16 / 9; overflow: hidden; background: var(--kj-surface-3);
}
.kj-post__media img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--kj-t-slow) var(--kj-ease-out); }
.kj-post:hover .kj-post__media img { transform: scale(1.06); }
.kj-post__body { display: flex; flex-direction: column; gap: var(--kj-s2); padding: var(--kj-s4); flex: 1 1 auto; }
.kj-post__cat {
  position: absolute;
  inset-block-start: var(--kj-s3);
  inset-inline-start: var(--kj-s3);
  z-index: 2;
  font-size: var(--kj-fs-2xs); font-weight: 700;
  color: var(--kj-primary-ink, var(--kj-primary)); background: rgba(255, 255, 255, .94);
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  padding: 4px var(--kj-s3); border-radius: var(--kj-r-pill);
  box-shadow: var(--kj-sh-xs);
}
.kj-post__title {
  font-size: var(--kj-fs-md); font-weight: 700; color: var(--kj-ink);
  line-height: var(--kj-lh-snug);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  line-clamp: 2; overflow: hidden;
  transition: color var(--kj-t-fast) var(--kj-ease);
}
.kj-post__title::after { content: ""; position: absolute; inset: 0; }
.kj-post:hover .kj-post__title { color: var(--kj-primary-ink, var(--kj-primary)); }
.kj-post__excerpt {
  font-size: var(--kj-fs-sm); color: var(--kj-muted);
  line-height: var(--kj-lh-snug);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  line-clamp: 2; overflow: hidden;
}
.kj-post__meta {
  display: flex; align-items: center; gap: var(--kj-s3);
  margin-top: auto; padding-top: var(--kj-s3);
  border-top: 1px solid var(--kj-line-2);
  font-size: var(--kj-fs-xs); color: var(--kj-faint);
}
.kj-post__meta span { display: inline-flex; align-items: center; gap: 4px; }
.kj-post__meta svg { width: 13px; height: 13px; }

/* ==========================================================================
   TRUST / FOOTER
   ========================================================================== */
.kj-trust {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 158px), 1fr));
  gap: var(--kj-gutter);
  text-align: center;
}
.kj-trust__item { display: flex; flex-direction: column; align-items: center; gap: var(--kj-s2); }
.kj-trust__icon {
  width: 56px; height: 56px; display: grid; place-items: center;
  border-radius: var(--kj-r-pill);
  background: var(--kj-primary-soft); color: var(--kj-primary-ink, var(--kj-primary));
}
.kj-trust__icon svg { width: 27px; height: 27px; }
.kj-trust__title { font-size: var(--kj-fs-sm); font-weight: 700; color: var(--kj-ink); }
.kj-trust__text { font-size: var(--kj-fs-xs); color: var(--kj-muted); }

.kj-footer { background: var(--kj-surface); border-top: 1px solid var(--kj-line); margin-top: var(--kj-s10); }
.kj-footer__top {
  display: grid; gap: var(--kj-s8);
  grid-template-columns: 1fr;
  padding-block: var(--kj-s10);
}
@media (min-width: 640px) { .kj-footer__top { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .kj-footer__top { grid-template-columns: 1.6fr repeat(3, 1fr); } }

.kj-footer__about p {
  font-size: var(--kj-fs-sm); color: var(--kj-muted);
  line-height: var(--kj-lh-base); margin-block: var(--kj-s3) var(--kj-s4);
  max-width: 46ch;
}
.kj-footer__title { font-size: var(--kj-fs-md); font-weight: 800; color: var(--kj-ink); margin-bottom: var(--kj-s4); }
.kj-footer__links { display: flex; flex-direction: column; gap: var(--kj-s1); }
.kj-footer__links a {
  display: inline-block;
  font-size: var(--kj-fs-sm); color: var(--kj-muted);
  padding-block: 5px;
  transition: color var(--kj-t-fast) var(--kj-ease), padding-inline-start var(--kj-t-fast) var(--kj-ease);
}
.kj-footer__links a:hover { color: var(--kj-primary-ink, var(--kj-primary)); padding-inline-start: var(--kj-s2); }

.kj-social { display: flex; gap: var(--kj-s2); }
.kj-social a {
  width: 38px; height: 38px; display: grid; place-items: center;
  color: var(--kj-muted); background: var(--kj-surface-2);
  border-radius: var(--kj-r-sm);
  transition: background var(--kj-t-fast) var(--kj-ease), color var(--kj-t-fast) var(--kj-ease);
}
.kj-social a:hover { background: var(--kj-primary-solid, var(--kj-primary)); color: var(--kj-on-primary, #fff); }
.kj-social svg { width: 18px; height: 18px; }

.kj-footer__bottom {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--kj-s3);
  padding-block: var(--kj-s5);
  border-top: 1px solid var(--kj-line-2);
  font-size: var(--kj-fs-xs); color: var(--kj-muted);
}

/* Back to top */
.kj-totop {
  position: fixed;
  bottom: calc(var(--kj-s5) + env(safe-area-inset-bottom, 0px));
  /* inset-inline-END keeps this on the side AWAY from where RTL text starts:
     bottom-right in LTR, bottom-left in RTL. With inset-inline-start it sat on
     the right in Persian and covered the section headings. */
  inset-inline-end: var(--kj-s5);
  width: 44px; height: 44px;
  display: grid; place-items: center;
  color: var(--kj-on-primary, #fff); background: var(--kj-primary-solid, var(--kj-primary));
  border-radius: var(--kj-r-pill);
  box-shadow: var(--kj-sh-brand);
  opacity: 0; visibility: hidden; transform: translateY(12px);
  transition: opacity var(--kj-t-base) var(--kj-ease),
              transform var(--kj-t-base) var(--kj-ease),
              visibility var(--kj-t-base), background var(--kj-t-fast) var(--kj-ease);
  z-index: var(--kj-z-sticky);
}
.kj-totop.is-visible { opacity: 1; visibility: visible; transform: none; }
.kj-totop:hover { background: var(--kj-primary-hover); }
.kj-totop svg { width: 20px; height: 20px; }
@media (max-width: 991.98px) {
  /* Clear the fixed mobile bar, shrink slightly and soften so it never
     obscures a product card underneath. */
  .kj-totop {
    bottom: calc(var(--kj-mobilebar-h) + var(--kj-s3) + env(safe-area-inset-bottom, 0px));
    width: 40px; height: 40px;
    opacity: 0;
  }
  .kj-totop.is-visible { opacity: .92; }
  .kj-totop:hover, .kj-totop:focus-visible { opacity: 1; }
  .kj-totop svg { width: 18px; height: 18px; }
}

/* ---------- Toast --------------------------------------------------------- */
.kj-toasts {
  position: fixed; top: var(--kj-s5); inset-inline-end: var(--kj-s5);
  display: flex; flex-direction: column; gap: var(--kj-s2);
  z-index: var(--kj-z-toast);
  pointer-events: none;
}
.kj-toast {
  display: flex; align-items: center; gap: var(--kj-s3);
  min-width: 260px; max-width: min(360px, calc(100vw - var(--kj-s10)));
  padding: var(--kj-s3) var(--kj-s4);
  background: var(--kj-ink); color: #fff;
  border-radius: var(--kj-r-md);
  box-shadow: var(--kj-sh-xl);
  font-size: var(--kj-fs-sm); font-weight: 600;
  animation: kj-toast-in .3s var(--kj-ease-spring);
  pointer-events: auto;
}
.kj-toast svg { width: 19px; height: 19px; flex: none; }
.kj-toast--success svg { color: var(--kj-mint-400); }
.kj-toast--error svg { color: #FF8FA8; }
.kj-toast.is-out { animation: kj-toast-out .25s var(--kj-ease) forwards; }
@keyframes kj-toast-in  { from { opacity: 0; transform: translateY(-14px) scale(.96); } }
@keyframes kj-toast-out { to   { opacity: 0; transform: translateY(-10px) scale(.97); } }
@media (max-width: 575.98px) {
  /* Toasts sit above the mobile nav bar — and above the compare bar too when
     it is open, otherwise the confirmation lands on top of the thing it is
     confirming. --kj-cmpbar-h is published by the script and is 0 when the
     bar is closed. */
  .kj-toasts {
    top: auto;
    bottom: calc(var(--kj-mobilebar-h) + var(--kj-cmpbar-h, 0px) + var(--kj-s3));
    inset-inline: var(--kj-s4);
  }
  .kj-toast { max-width: none; }
}

/* ==========================================================================
   BANNER — text + product cut-out
   ========================================================================== */
.kj-banner__text {
  font-size: var(--kj-fs-sm);
  color: rgba(255,255,255,.9);
  margin-top: 6px;
  line-height: var(--kj-lh-snug);
  /* Width comes from the grid column now; the percentage cap is obsolete. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.kj-banner__media {
  display: grid;
  place-items: center;
  pointer-events: none;
}
.kj-banner__media img {
  width: 118px; height: 118px;
  object-fit: cover;
  background: #fff;
  border-radius: var(--kj-r-md);
  box-shadow: 0 12px 24px rgba(0,0,0,.24), 0 0 0 1px rgba(255,255,255,.4);
  transform: rotate(-5deg);
  transition: transform var(--kj-t-slow) var(--kj-ease-out);
}
.kj-banner:hover .kj-banner__media img { transform: rotate(-5deg) scale(1.05); }
/* Narrow cards: shrink the plate rather than squeezing the copy. */
@media (max-width: 400px) {
  .kj-banner { column-gap: var(--kj-s3); padding: var(--kj-s5); }
  .kj-banner__media img { width: 92px; height: 92px; }
}

/* ==========================================================================
   TABS
   ========================================================================== */
.kj-tabs {
  display: flex;
  flex: none;
  gap: 4px;
  padding: 4px;
  background: var(--kj-surface-2);
  border-radius: var(--kj-r-pill);
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.kj-tabs::-webkit-scrollbar { display: none; }
.kj-tab {
  flex: none;
  min-height: 34px;
  padding-inline: var(--kj-s4);
  font-size: var(--kj-fs-sm);
  font-weight: 600;
  color: var(--kj-muted);
  background: transparent;
  border-radius: var(--kj-r-pill);
  white-space: nowrap;
  transition: background var(--kj-t-fast) var(--kj-ease),
              color var(--kj-t-fast) var(--kj-ease),
              box-shadow var(--kj-t-fast) var(--kj-ease);
}
.kj-tab:hover { color: var(--kj-ink); }
.kj-tab.is-active {
  color: var(--kj-primary-ink, var(--kj-primary));
  background: var(--kj-surface);
  box-shadow: var(--kj-sh-xs);
}
.kj-tabpanel { display: none; }
.kj-tabpanel.is-active { display: block; animation: kj-fade-in var(--kj-t-base) var(--kj-ease-out) both; }
@keyframes kj-fade-in { from { opacity: 0; transform: translateY(6px); } }

/* ==========================================================================
   NEWSLETTER
   ========================================================================== */
.kj-news {
  display: grid;
  /* An implicit grid track is min-content sized, and the form's min-content
     (input + gap + button) is wider than a 320px screen minus padding, so the
     track overflowed its own box. Pin the single column to the content box. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--kj-s5);
  align-items: center;
  padding: var(--kj-s7) var(--kj-s6);
  border-radius: var(--kj-r-xl);
  background:
    radial-gradient(120% 140% at 100% 0%, rgba(255,255,255,.22), transparent 60%),
    linear-gradient(135deg, var(--kj-violet-600), #C026D3);
  box-shadow: var(--kj-sh-brand);
}
@media (min-width: 860px) { .kj-news { grid-template-columns: 1fr minmax(320px, 460px); } }
.kj-news__title { font-size: var(--kj-fs-lg); font-weight: 800; color: #fff; }
.kj-news__sub {
  font-size: var(--kj-fs-sm);
  color: rgba(255,255,255,.86);
  margin-top: 6px;
  line-height: var(--kj-lh-base);
  max-width: 52ch;
}
.kj-news__form { display: flex; gap: var(--kj-s2); flex-wrap: wrap; }
/* Below ~360px the input would be squeezed to a couple of characters, so let
   the button drop onto its own full-width line instead. */
@media (max-width: 359.98px) {
  .kj-news__input { flex: 1 1 100%; }
  .kj-news__btn { flex: 1 1 100%; }
}
.kj-news__input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: var(--kj-tap);
  padding-inline: var(--kj-s4);
  font: inherit;
  font-size: var(--kj-fs-sm);
  color: var(--kj-ink);
  background: #fff;
  border: 2px solid transparent;
  border-radius: var(--kj-r-md);
  transition: border-color var(--kj-t-fast) var(--kj-ease);
}
.kj-news__input::placeholder { color: var(--kj-faint); }
.kj-news__input:focus-visible { outline: none; border-color: var(--kj-amber-400); }
.kj-news__input[aria-invalid="true"] { border-color: var(--kj-sale-ink); }
.kj-news__btn {
  flex: none;
  min-height: var(--kj-tap);
  padding-inline: var(--kj-s6);
  font-size: var(--kj-fs-sm);
  font-weight: 700;
  color: var(--kj-primary-ink, var(--kj-primary));
  background: #fff;
  border-radius: var(--kj-r-md);
  transition: transform var(--kj-t-fast) var(--kj-ease-out),
              box-shadow var(--kj-t-fast) var(--kj-ease);
}
.kj-news__btn:hover { transform: translateY(-1px); box-shadow: 0 8px 18px rgba(0,0,0,.18); }
.kj-news__btn:active { transform: none; }

/* ==========================================================================
   STATS
   ========================================================================== */
.kj-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr));
  gap: var(--kj-gutter);
  margin-top: var(--kj-s6);
  text-align: center;
}
.kj-stat {
  padding: var(--kj-s5) var(--kj-s3);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
  transition: border-color var(--kj-t-base) var(--kj-ease),
              box-shadow var(--kj-t-base) var(--kj-ease);
}
.kj-stat:hover { border-color: var(--kj-violet-200); box-shadow: var(--kj-sh-sm); }
.kj-stat__num {
  display: block;
  font-size: var(--kj-fs-xl);
  font-weight: 800;
  color: var(--kj-primary-ink, var(--kj-primary));
  letter-spacing: -.02em;
}
.kj-stat__lbl { display: block; font-size: var(--kj-fs-xs); color: var(--kj-muted); margin-top: 4px; }

/* ==========================================================================
   FOOTER — brand block, contact, social, badges
   ========================================================================== */
.kj-footer__about {
  font-size: var(--kj-fs-sm);
  color: var(--kj-muted);
  line-height: var(--kj-lh-base);
  margin-block: var(--kj-s3) var(--kj-s4);
  max-width: 46ch;
}
.kj-footer__contact { display: flex; flex-direction: column; gap: var(--kj-s2); }
.kj-footer__contact-item {
  display: inline-flex;
  align-items: center;
  gap: var(--kj-s3);
  min-height: var(--kj-tap);
  color: var(--kj-muted);
  transition: color var(--kj-t-fast) var(--kj-ease);
}
.kj-footer__contact-item:hover { color: var(--kj-primary-ink, var(--kj-primary)); }
.kj-footer__contact-item svg { width: 18px; height: 18px; flex: none; color: var(--kj-primary-ink, var(--kj-primary)); }
.kj-footer__contact-lbl { display: block; font-size: var(--kj-fs-2xs); color: var(--kj-faint); }
.kj-footer__contact-val { display: block; font-size: var(--kj-fs-sm); font-weight: 700; color: var(--kj-ink); }

.kj-footer__mid {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--kj-s4);
  padding-block: var(--kj-s5);
  border-top: 1px solid var(--kj-line-2);
}
.kj-social-wrap { display: flex; align-items: center; gap: var(--kj-s2); flex-wrap: wrap; }
.kj-footer__social-lbl { font-size: var(--kj-fs-sm); color: var(--kj-muted); margin-inline-end: var(--kj-s1); }
.kj-social__a {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  color: var(--kj-muted);
  background: var(--kj-surface-2);
  border-radius: var(--kj-r-sm);
  transition: background var(--kj-t-fast) var(--kj-ease),
              color var(--kj-t-fast) var(--kj-ease),
              transform var(--kj-t-fast) var(--kj-ease-out);
}
.kj-social__a:hover { background: var(--kj-primary-solid, var(--kj-primary)); color: var(--kj-on-primary, #fff); transform: translateY(-2px); }
.kj-social__a svg { width: 18px; height: 18px; }

.kj-footer__badges { display: flex; gap: var(--kj-s2); flex-wrap: wrap; }
.kj-footer__badge {
  display: inline-flex; align-items: center; gap: var(--kj-s2);
  min-height: 38px; padding-inline: var(--kj-s4);
  font-size: var(--kj-fs-xs); font-weight: 600;
  color: var(--kj-muted);
  background: var(--kj-surface-2);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-sm);
}
.kj-footer__badge svg { width: 17px; height: 17px; color: var(--kj-success-ink); }

.kj-footer__legal { display: flex; align-items: center; gap: var(--kj-s2); }
.kj-footer__legal a {
  color: var(--kj-muted);
  transition: color var(--kj-t-fast) var(--kj-ease);
  /* Footer legal links are standalone targets in a flex row, not words inside
     a sentence, so WCAG 2.5.8's inline-text exemption does not cover them.
     Padding lifts the row to 24px without moving the text baseline. */
  display: inline-flex;
  align-items: center;
  min-block-size: 24px;
}
.kj-footer__legal a:hover { color: var(--kj-primary-ink, var(--kj-primary)); }

/* Footer layout helpers */
.kj-footer__brand { min-width: 0; }
.kj-footer__col { min-width: 0; }
.kj-news__text { min-width: 0; }

/* ==========================================================================
   Archive, pagination and empty states
   Used by index.php / search.php / post-card.php. Kept at the end of the
   file so it can never be overridden by an earlier component block.
   ========================================================================== */

.kj-archive__desc {
  max-width: 72ch;
  margin-block: calc(var(--kj-s4) * -1) var(--kj-s6);
  color: var(--kj-muted);
  font-size: var(--kj-fs-sm);
  line-height: var(--kj-lh-loose);
}
.kj-archive__desc :last-child { margin-bottom: 0; }

/* Featured-image placeholder so cards never collapse without a thumbnail. */
.kj-post__ph {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  background:
    radial-gradient(120% 120% at 85% 15%, rgba(122, 43, 226, .14), transparent 60%),
    var(--kj-surface-2);
}

/* --- Pagination ----------------------------------------------------------- */

.kj-pagination {
  margin-top: var(--kj-s10);
}
.kj-pagination .nav-links,
.kj-pagination .kj-pagination__links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--kj-s2);
}
.kj-pagination .screen-reader-text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }

.kj-pagination .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--kj-tap);
  min-height: var(--kj-tap);
  padding-inline: var(--kj-s3);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-md);
  background: var(--kj-surface);
  color: var(--kj-body);
  font-size: var(--kj-fs-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  transition: background var(--kj-t-fast) var(--kj-ease),
              border-color var(--kj-t-fast) var(--kj-ease),
              color var(--kj-t-fast) var(--kj-ease),
              transform var(--kj-t-fast) var(--kj-ease-out);
}
.kj-pagination a.page-numbers:hover {
  background: var(--kj-violet-50);
  border-color: var(--kj-violet-200);
  color: var(--kj-primary-ink, var(--kj-primary));
  transform: translateY(-1px);
}
.kj-pagination .page-numbers.current {
  background: var(--kj-primary-solid, var(--kj-primary));
  border-color: var(--kj-primary);
  color: var(--kj-on-primary, #fff);
  box-shadow: var(--kj-sh-brand);
}
.kj-pagination .page-numbers.dots {
  border-color: transparent;
  background: transparent;
  color: var(--kj-faint);
  min-width: var(--kj-s6);
  padding-inline: 0;
}
.kj-pagination .page-numbers svg { width: 16px; height: 16px; }

/* Arrows are mirrored for RTL by the icon choice itself, not a transform. */
.kj-pagination .prev,
.kj-pagination .next { gap: var(--kj-s2); padding-inline: var(--kj-s4); }

@media (max-width: 575.98px) {
  /* Keep only prev / next / current on very small screens. */
  .kj-pagination .page-numbers:not(.current):not(.prev):not(.next):not(.dots) { display: none; }
}

/* --- Empty state ---------------------------------------------------------- */

.kj-empty {
  display: grid;
  place-items: center;
  gap: var(--kj-s3);
  text-align: center;
  padding: var(--kj-s14) var(--kj-s5);
  border: 1px dashed var(--kj-line-2);
  border-radius: var(--kj-r-xl);
  background:
    radial-gradient(90% 120% at 50% 0%, rgba(122, 43, 226, .06), transparent 65%),
    var(--kj-surface);
}
.kj-empty__icon {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--kj-violet-50);
  color: var(--kj-primary-ink, var(--kj-primary));
}
.kj-empty__icon svg { width: 28px; height: 28px; }
.kj-empty__title {
  margin: 0;
  font-size: var(--kj-fs-lg);
  font-weight: 800;
  color: var(--kj-ink);
}
.kj-empty__text {
  margin: 0;
  max-width: 46ch;
  color: var(--kj-muted);
  font-size: var(--kj-fs-sm);
  line-height: var(--kj-lh-loose);
}
.kj-empty .kj-btn { margin-top: var(--kj-s2); }

/* --- Posts list on archives ---------------------------------------------- */

.kj-posts--archive {
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
@media (max-width: 419.98px) {
  .kj-posts--archive { grid-template-columns: 1fr; }
}

/* ==========================================================================
   SHOP — archive layout, filters, breadcrumb
   ========================================================================== */

.kj-crumbs {
  margin-bottom: var(--kj-s5);
  font-size: var(--kj-fs-sm);
  color: var(--kj-muted);
}
.kj-crumbs ol {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--kj-s2);
  margin: 0; padding: 0; list-style: none;
}
.kj-crumbs li { display: inline-flex; align-items: center; gap: var(--kj-s2); min-width: 0; }
/* The separator is generated rather than authored so Woo's delimiter can stay
   empty — a literal "/" in the markup would be read out by screen readers. */
.kj-crumbs li + li::before {
  content: "";
  width: 5px; height: 5px;
  border-right: 1.5px solid var(--kj-line-2);
  border-bottom: 1.5px solid var(--kj-line-2);
  /* RTL: the chevron points left, so rotate the other way. */
  transform: rotate(45deg);
  flex: none;
}
.kj-crumbs a { color: var(--kj-muted); transition: color var(--kj-t-fast) var(--kj-ease); }
.kj-crumbs a:hover { color: var(--kj-primary-ink, var(--kj-primary)); }
.kj-crumbs .kj-crumbs__current,
.kj-crumbs li:last-child { color: var(--kj-ink); font-weight: 600; }

/* Two-column shop: filters rail + product grid. */
.kj-shop {
  display: grid;
  grid-template-columns: 264px minmax(0, 1fr);
  gap: var(--kj-s6);
  align-items: start;
}
.kj-shop__main { min-width: 0; }

.kj-shop__bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--kj-s3);
  margin-bottom: var(--kj-s5);
  padding: var(--kj-s3) var(--kj-s4);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-md);
}
/* The filter button only exists for the off-canvas breakpoint. */
.kj-shop__filter-btn { display: none; }

.kj-shop__count {
  margin: 0;
  font-size: var(--kj-fs-sm); color: var(--kj-muted);
}
.kj-shop__count .kj-num { color: var(--kj-ink); font-weight: 700; }
/* The count takes the slack so the sort control stays pinned to the edge
   instead of floating in the middle of a wide bar. */
.kj-shop__bar .kj-shop__count { margin-inline-end: auto; }
.kj-shop__bar .woocommerce-ordering { margin: 0; }
.kj-shop__bar select {
  height: var(--kj-tap);
  /* Logical padding: the text side gets the small inset, the arrow side the
     large one. Physical left/right would be swapped under RTL. */
  padding-block: 0;
  padding-inline-start: var(--kj-s3);
  padding-inline-end: var(--kj-s8);
  font: inherit; font-size: var(--kj-fs-sm); color: var(--kj-ink);
  background: var(--kj-surface-2);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-sm);
  cursor: pointer;
  /* The native arrow renders on the inline-end edge, which flips with the
     document direction; drawing our own keeps it predictable. Two gradients
     make the chevron: each paints one half of the "v". */
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--kj-muted) 50%),
                    linear-gradient(135deg, var(--kj-muted) 50%, transparent 50%);
  background-position: left var(--kj-s4) center,
                       left calc(var(--kj-s4) + 5px) center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.kj-shop__bar select:focus-visible {
  outline: 2px solid var(--kj-primary);
  outline-offset: 2px;
}

/* --- Filters rail ------------------------------------------------------- */

.kj-filters {
  position: sticky; top: calc(var(--kj-header-h) + var(--kj-s4));
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-md);
  overflow: hidden;
}
.kj-filters__head {
  display: none; /* Only the off-canvas version needs a title bar. */
  align-items: center; justify-content: space-between;
  padding: var(--kj-s4);
  border-bottom: 1px solid var(--kj-line);
}
.kj-filters__title { font-weight: 800; font-size: var(--kj-fs-md); color: var(--kj-ink); }
.kj-filters__body { padding: var(--kj-s2); }

.kj-filter { padding: var(--kj-s3); }
.kj-filter + .kj-filter { border-top: 1px solid var(--kj-line); }
.kj-filter__title {
  margin: 0 0 var(--kj-s3);
  font-size: var(--kj-fs-sm); font-weight: 800; color: var(--kj-ink);
}
.kj-filter__list { margin: 0; padding: 0; list-style: none; display: grid; gap: 2px; }
.kj-filter__link {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--kj-s2);
  min-height: 36px;
  padding: var(--kj-s2) var(--kj-s3);
  font-size: var(--kj-fs-sm); color: var(--kj-body);
  border-radius: var(--kj-r-sm);
  transition: background var(--kj-t-fast) var(--kj-ease),
              color var(--kj-t-fast) var(--kj-ease);
}
.kj-filter__link > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kj-filter__link:hover { background: var(--kj-surface-2); color: var(--kj-ink); }
.kj-filter__link.is-active { background: var(--kj-primary-soft); color: var(--kj-primary-ink, var(--kj-primary)); font-weight: 700; }
.kj-filter__count {
  flex: none;
  padding: 1px 7px;
  font-size: var(--kj-fs-2xs); color: var(--kj-faint);
  background: var(--kj-surface-2);
  border-radius: var(--kj-r-pill);
}
.kj-filter__link.is-active .kj-filter__count { background: #fff; color: var(--kj-primary-ink, var(--kj-primary)); }

.kj-filter__form { display: grid; gap: var(--kj-s3); }

/* Custom checkbox: the native input stays in the DOM for keyboard and form
   semantics, visually replaced by .kj-check__box. */
.kj-check {
  display: flex; align-items: center; gap: var(--kj-s3);
  min-height: var(--kj-tap);
  cursor: pointer;
  user-select: none;
}
.kj-check input {
  position: absolute; width: 1px; height: 1px;
  opacity: 0; pointer-events: none;
}
.kj-check__box {
  flex: none;
  display: grid; place-items: center;
  width: 20px; height: 20px;
  background: var(--kj-surface);
  border: 1.5px solid var(--kj-line-2);
  border-radius: var(--kj-r-xs);
  color: #fff;
  transition: background var(--kj-t-fast) var(--kj-ease),
              border-color var(--kj-t-fast) var(--kj-ease);
}
.kj-check__box svg { opacity: 0; transition: opacity var(--kj-t-fast) var(--kj-ease); }
.kj-check input:checked + .kj-check__box {
  background: var(--kj-primary-solid, var(--kj-primary));
  border-color: var(--kj-primary);
}
.kj-check input:checked + .kj-check__box svg { opacity: 1; }
.kj-check input:focus-visible + .kj-check__box {
  outline: 2px solid var(--kj-primary);
  outline-offset: 2px;
}
.kj-check__text { font-size: var(--kj-fs-sm); color: var(--kj-body); }

.kj-filter__apply { width: 100%; justify-content: center; }
.kj-filter__reset {
  text-align: center;
  font-size: var(--kj-fs-sm); color: var(--kj-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.kj-filter__reset:hover { color: var(--kj-sale); }

/* --- Off-canvas filters below 992px ------------------------------------- */

@media (max-width: 991px) {
  .kj-shop { grid-template-columns: minmax(0, 1fr); }
  .kj-shop__filter-btn { display: inline-flex; }

  .kj-filters {
    position: fixed; inset-block: 0; inset-inline-start: 0;
    z-index: var(--kj-z-drawer);
    width: min(320px, 86vw);
    border: 0; border-radius: 0;
    display: flex; flex-direction: column;
    /* RTL: inset-inline-start is the right edge, so the panel slides out to
       the right. translateX(100%) moves it off that edge. */
    transform: translateX(100%);
    /* visibility keeps the controls out of the tab order while closed — a
       transform alone leaves them focusable. */
    visibility: hidden;
    transition: transform var(--kj-t-base) var(--kj-ease),
                visibility 0s linear var(--kj-t-base);
  }
  .kj-filters.is-open {
    transform: translateX(0);
    visibility: visible;
    transition: transform var(--kj-t-base) var(--kj-ease), visibility 0s;
  }
  .kj-filters__head { display: flex; }
  .kj-filters__body { overflow-y: auto; flex: 1; -webkit-overflow-scrolling: touch; }
}

@media (min-width: 992px) {
  /* Desktop has no close button — the rail is always visible. */
  .kj-filters__close { display: none; }
}

@media (max-width: 767px) {
  /* The count is the first thing to go: the sort control and the filter
     button are actions, the count is only information. */
  .kj-shop__count { display: none; }
}

@media (max-width: 575px) {
  .kj-shop__bar { flex-wrap: wrap; }
  .kj-shop__bar .kj-shop__filter-btn { flex: 1 1 auto; justify-content: center; }
  .kj-shop__bar .woocommerce-ordering { flex: 1 1 100%; }
  .kj-shop__bar select { width: 100%; }
}

/* ==========================================================================
   SINGLE PRODUCT
   ========================================================================== */

.kj-product__top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--kj-s8);
  align-items: start;
  margin-bottom: var(--kj-s10);
}

/* --- Gallery ------------------------------------------------------------ */

.kj-gallery { display: grid; gap: var(--kj-s3); }

.kj-gallery__stage {
  position: relative;
  /* A fixed square keeps the page from reflowing between images of different
     heights, and gives the buy box a stable anchor to sit beside. */
  aspect-ratio: 1;
  /* Once the columns stack, a square stage is as tall as the screen is wide:
     at 768px that is a 729px image that buries the price and the add-to-cart
     button below the fold. Cap the height so the buy box stays reachable, and
     centre the narrowed stage. max-block-size wins over aspect-ratio, so the
     box simply stops growing. */
  max-block-size: min(72vh, 520px);
  /* Cap the width to match, so the stage stays square instead of becoming a
     wide letterbox with the product floating in the middle of it. */
  max-inline-size: min(72vh, 520px);
  margin-inline: auto;
  inline-size: 100%;
  background: #fff;
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
  overflow: hidden;
}
/* Above the split point the column already constrains the width, so the stage
   can use the full square again. */
@media (min-width: 992px) {
  .kj-gallery__stage { max-block-size: none; max-inline-size: none; }
}
.kj-gallery__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  padding: var(--kj-s6);
  opacity: 0;
  /* visibility stops a hidden slide from swallowing pointer events over the
     active one; opacity alone leaves it on top and clickable. */
  visibility: hidden;
  transition: opacity var(--kj-t-base) var(--kj-ease),
              visibility 0s linear var(--kj-t-base);
}
.kj-gallery__img.is-active {
  opacity: 1; visibility: visible;
  transition: opacity var(--kj-t-base) var(--kj-ease), visibility 0s;
}

.kj-gallery__badges {
  position: absolute; inset-block-start: var(--kj-s4); inset-inline-start: var(--kj-s4);
  z-index: 3;
  display: flex; flex-direction: column; gap: 6px; align-items: flex-start;
}

.kj-gallery__nav {
  position: absolute; inset-block-start: 50%;
  z-index: 3;
  display: grid; place-items: center;
  width: 40px; height: 40px;
  margin-block-start: -20px;
  color: var(--kj-ink);
  background: rgba(255,255,255,.92);
  border: 1px solid var(--kj-line);
  border-radius: 50%;
  box-shadow: var(--kj-sh-sm);
  opacity: 0;
  transition: opacity var(--kj-t-fast) var(--kj-ease),
              background var(--kj-t-fast) var(--kj-ease);
}
/* The circle stays 40px for looks; the touch target is pushed out to 44px
   with the same ::after trick used by the hero dots and the share links. */
.kj-gallery__nav::after { content: ""; position: absolute; inset: -2px; border-radius: 50%; }
/* Physical properties on purpose: "prev" is the right-hand arrow in RTL and
   the left-hand one in LTR, which is exactly what inset-inline would flip. */
.kj-gallery__nav--prev { right: var(--kj-s4); }
.kj-gallery__nav--next { left: var(--kj-s4); }
html[dir="ltr"] .kj-gallery__nav--prev { right: auto; left: var(--kj-s4); }
html[dir="ltr"] .kj-gallery__nav--next { left: auto; right: var(--kj-s4); }

.kj-gallery__stage:hover .kj-gallery__nav,
.kj-gallery__nav:focus-visible { opacity: 1; }
.kj-gallery__nav:hover { background: #fff; }
/* Touch has no hover, so the arrows must be permanently visible there. */
@media (hover: none) {
  .kj-gallery__nav { opacity: 1; }
}

.kj-gallery__counter {
  position: absolute; inset-block-end: var(--kj-s4); inset-inline-end: var(--kj-s4);
  z-index: 3;
  display: inline-flex; align-items: baseline; gap: 3px;
  padding: 3px 10px;
  font-size: var(--kj-fs-xs); color: var(--kj-muted);
  background: rgba(255,255,255,.92);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-pill);
}

.kj-gallery__thumbs {
  display: flex; gap: var(--kj-s2);
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  padding-block-end: 2px;
  /* Track the capped stage so the strip stays flush with the image edge
     instead of running the full column width beneath a narrower stage. */
  inline-size: 100%;
  max-inline-size: min(72vh, 520px);
  margin-inline: auto;
}
@media (min-width: 992px) {
  .kj-gallery__thumbs { max-inline-size: none; }
}
.kj-gallery__thumbs::-webkit-scrollbar { display: none; }
.kj-gallery__thumb {
  flex: none;
  width: 72px; height: 72px;
  padding: 6px;
  background: #fff;
  border: 1.5px solid var(--kj-line);
  border-radius: var(--kj-r-sm);
  transition: border-color var(--kj-t-fast) var(--kj-ease);
}
.kj-gallery__thumb img { width: 100%; height: 100%; object-fit: contain; }
.kj-gallery__thumb:hover { border-color: var(--kj-violet-200); }
.kj-gallery__thumb.is-active { border-color: var(--kj-primary); }

/* --- Summary ------------------------------------------------------------ */

.kj-product__summary {
  /* Follows a tall gallery down the page on desktop; released below 992px
     where the two columns stack and stickiness would be meaningless. */
  position: sticky;
  top: calc(var(--kj-header-h) + var(--kj-s4));
  display: grid; gap: var(--kj-s4);
  align-content: start;
}
.kj-product__brand {
  font-size: var(--kj-fs-xs); font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--kj-primary-ink, var(--kj-primary));
}
.kj-product__title {
  margin: 0;
  font-size: var(--kj-fs-2xl); font-weight: 800;
  line-height: var(--kj-lh-snug); color: var(--kj-ink);
}
.kj-product__meta {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--kj-s3) var(--kj-s5);
  padding-block-end: var(--kj-s4);
  border-block-end: 1px solid var(--kj-line);
}
.kj-product__rating { display: inline-flex; }
.kj-product__norating,
.kj-product__sku { font-size: var(--kj-fs-sm); color: var(--kj-faint); }
.kj-product__sku .kj-num { color: var(--kj-muted); }

.kj-product__buybox {
  display: grid; gap: var(--kj-s4);
  padding: var(--kj-s5);
  background: var(--kj-surface-2);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
}
.kj-product__pricing { display: grid; gap: 2px; }
.kj-product__was {
  display: flex; align-items: center; gap: var(--kj-s2);
  font-size: var(--kj-fs-sm);
}
.kj-product__was .kj-num {
  color: var(--kj-faint);
  text-decoration: line-through;
  text-decoration-color: var(--kj-sale);
}
.kj-product__price {
  font-size: var(--kj-fs-2xl); font-weight: 800; color: var(--kj-ink);
  line-height: 1.2;
}
/* Woo wraps the amount in <span class="woocommerce-Price-amount">; the
   currency suffix is a child <span class="woocommerce-Price-currencySymbol">. */
.kj-product__price .woocommerce-Price-currencySymbol {
  font-size: var(--kj-fs-sm); font-weight: 600; color: var(--kj-muted);
  margin-inline-start: 4px;
}
.kj-product__price del { font-size: var(--kj-fs-md); color: var(--kj-faint); font-weight: 600; }
.kj-product__price ins { text-decoration: none; }

/* --- Stock -------------------------------------------------------------- */

.kj-stock { display: grid; gap: var(--kj-s2); margin: 0; }
.kj-stock__line,
.kj-stock--in, .kj-stock--out {
  display: flex; align-items: center; gap: var(--kj-s2);
  margin: 0;
  font-size: var(--kj-fs-sm); font-weight: 600;
}
.kj-stock--in  { color: var(--kj-success-ink); }
.kj-stock--out { color: var(--kj-sale-ink); }
.kj-stock--low .kj-stock__line { color: var(--kj-accent-ink); }
.kj-stock__bar {
  height: 5px;
  background: var(--kj-surface-3);
  border-radius: var(--kj-r-pill);
  overflow: hidden;
}
.kj-stock__fill {
  height: 100%;
  background: linear-gradient(90deg, var(--kj-accent), var(--kj-sale));
  border-radius: inherit;
}

/* --- WooCommerce add-to-cart form -------------------------------------- */

.kj-product__buybox form.cart {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--kj-s3);
  margin: 0;
  /* The quantity box carries a 1px border, so a 44px outer height leaves the
     input itself at 42px — under the minimum target. Size both controls from
     one variable that adds the border back, keeping them the same height. */
  --kj-ctl: calc(var(--kj-tap) + 2px);
}
.kj-product__buybox .quantity {
  display: inline-flex; align-items: center;
  height: var(--kj-ctl);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-sm);
  overflow: hidden;
}
.kj-product__buybox .quantity input[type="number"] {
  width: 62px; height: 100%;
  padding: 0 var(--kj-s2);
  font: inherit; font-weight: 700; text-align: center;
  color: var(--kj-ink);
  background: transparent;
  border: 0;
  /* The native spinners are tiny, unstyleable and land on the wrong side
     in RTL. */
  appearance: textfield;
}
.kj-product__buybox .quantity input::-webkit-outer-spin-button,
.kj-product__buybox .quantity input::-webkit-inner-spin-button {
  appearance: none; margin: 0;
}
.kj-product__buybox .quantity input:focus-visible {
  outline: 2px solid var(--kj-primary); outline-offset: -2px;
}
.kj-product__buybox button.single_add_to_cart_button {
  flex: 1 1 200px;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--kj-s2);
  min-height: var(--kj-ctl, var(--kj-tap));
  padding-inline: var(--kj-s6);
  font: inherit; font-size: var(--kj-fs-md); font-weight: 800;
  color: var(--kj-on-primary, #fff);
  background: var(--kj-primary-solid, var(--kj-primary));
  border: 0; border-radius: var(--kj-r-sm);
  cursor: pointer;
  transition: background var(--kj-t-fast) var(--kj-ease),
              box-shadow var(--kj-t-base) var(--kj-ease),
              transform var(--kj-t-fast) var(--kj-ease-spring);
}
.kj-product__buybox button.single_add_to_cart_button:hover {
  background: var(--kj-primary-hover);
  box-shadow: var(--kj-sh-brand);
  transform: translateY(-1px);
}
.kj-product__buybox button.single_add_to_cart_button:disabled {
  background: var(--kj-surface-3); color: var(--kj-faint);
  cursor: not-allowed; transform: none; box-shadow: none;
}
/* Variation selects */
.kj-product__buybox .variations { width: 100%; margin: 0; border-collapse: collapse; }
.kj-product__buybox .variations th,
.kj-product__buybox .variations td { padding: 0 0 var(--kj-s3); text-align: start; }
.kj-product__buybox .variations label { font-size: var(--kj-fs-sm); font-weight: 700; color: var(--kj-ink); }
.kj-product__buybox .variations select {
  width: 100%; min-height: var(--kj-tap);
  padding-inline: var(--kj-s3);
  font: inherit; font-size: var(--kj-fs-sm); color: var(--kj-ink);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-sm);
}

/* --- Assurances --------------------------------------------------------- */

.kj-assure {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--kj-s2) var(--kj-s3);
  margin: 0; padding: var(--kj-s4) 0 0;
  list-style: none;
  border-block-start: 1px solid var(--kj-line);
}
.kj-assure__item { display: flex; align-items: center; gap: var(--kj-s2); min-width: 0; }
.kj-assure__icon {
  flex: none;
  display: grid; place-items: center;
  width: 30px; height: 30px;
  color: var(--kj-primary-ink, var(--kj-primary));
  background: var(--kj-primary-soft);
  border-radius: var(--kj-r-xs);
}
.kj-assure__text {
  font-size: var(--kj-fs-xs); font-weight: 600; color: var(--kj-body);
  min-width: 0;
}

/* --- Share -------------------------------------------------------------- */

.kj-share { display: flex; align-items: center; gap: var(--kj-s3); flex-wrap: wrap; }
.kj-share__label { font-size: var(--kj-fs-sm); color: var(--kj-muted); }
.kj-share__list { display: flex; gap: var(--kj-s2); margin: 0; padding: 0; list-style: none; }
.kj-share__link {
  display: grid; place-items: center;
  width: 36px; height: 36px;
  color: var(--kj-muted);
  background: var(--kj-surface-2);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-sm);
  cursor: pointer;
  transition: color var(--kj-t-fast) var(--kj-ease),
              background var(--kj-t-fast) var(--kj-ease),
              border-color var(--kj-t-fast) var(--kj-ease);
}
.kj-share__link:hover {
  color: var(--kj-primary-ink, var(--kj-primary));
  background: var(--kj-primary-soft);
  border-color: var(--kj-violet-200);
}
/* The visual box is 36px; extend the hit area to the 44px minimum without
   changing the layout. */
.kj-share__link::after {
  content: "";
  position: absolute; inset: -4px;
}
.kj-share__list li { position: relative; display: flex; }

/* --- Tabs --------------------------------------------------------------- */

.kj-product__tabs { margin-block-end: var(--kj-s10); }
.kj-tabs--product { margin-block-end: var(--kj-s5); }
/* These are primary navigation for the page, unlike the compact filter tabs
   on the homepage, so they get the full 44px target rather than a hit-area
   overlay — overlapping ::after boxes on adjacent pills would steal clicks
   from each other. */
.kj-tabs--product .kj-tab { min-height: var(--kj-tap); font-size: var(--kj-fs-md); }
.kj-tabpanel:focus-visible { outline: 2px solid var(--kj-primary); outline-offset: 4px; }

/* Long-form content inside a tab. */
.kj-prose { color: var(--kj-body); line-height: var(--kj-lh-loose); }
.kj-prose > :first-child { margin-block-start: 0; }
.kj-prose > :last-child { margin-block-end: 0; }
.kj-prose p { margin-block: 0 var(--kj-s4); }
/* A full-width tab panel gives ~125 characters per line, which is roughly
   twice a comfortable measure. Cap the running text only — tables, media and
   review threads still want the whole width. */
.kj-prose > p,
.kj-prose > ul,
.kj-prose > ol,
.kj-prose > h2,
.kj-prose > h3,
.kj-prose > h4,
.kj-prose > blockquote { max-width: 72ch; }
.kj-prose h2, .kj-prose h3, .kj-prose h4 {
  margin-block: var(--kj-s6) var(--kj-s3);
  color: var(--kj-ink); font-weight: 800; line-height: var(--kj-lh-snug);
}
.kj-prose h2 { font-size: var(--kj-fs-xl); }
.kj-prose h3 { font-size: var(--kj-fs-lg); }
.kj-prose h4 { font-size: var(--kj-fs-md); }
/* The base reset kills list markers globally; editor-authored content is the
   one place they have to come back, so restore them explicitly here. */
.kj-prose ul, .kj-prose ol { margin-block: 0 var(--kj-s4); padding-inline-start: var(--kj-s5); }
.kj-prose ul { list-style: disc outside; }
.kj-prose ol { list-style: decimal outside; }
.kj-prose ul ul { list-style-type: circle; }
.kj-prose ul ul ul { list-style-type: square; }
.kj-prose li { margin-block-end: var(--kj-s2); }
.kj-prose li::marker { color: var(--kj-primary-ink, var(--kj-primary)); }
.kj-prose ul ul, .kj-prose ol ol, .kj-prose ul ol, .kj-prose ol ul {
	margin-block: var(--kj-s2) 0;
}
.kj-prose a { color: var(--kj-primary-ink, var(--kj-primary)); text-decoration: underline; text-underline-offset: 3px; }
.kj-prose img { max-width: 100%; height: auto; border-radius: var(--kj-r-md); }
.kj-prose strong, .kj-prose b { color: var(--kj-ink); font-weight: 700; }

/* Woo's attributes table. */
.kj-prose table.shop_attributes,
.kj-prose table.woocommerce-product-attributes {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--kj-fs-sm);
}
.kj-prose table.shop_attributes th,
.kj-prose table.shop_attributes td,
.kj-prose table.woocommerce-product-attributes th,
.kj-prose table.woocommerce-product-attributes td {
  padding: var(--kj-s3) var(--kj-s4);
  text-align: start;
  border-block-end: 1px solid var(--kj-line);
}
.kj-prose table.shop_attributes tr:nth-child(odd),
.kj-prose table.woocommerce-product-attributes tr:nth-child(odd) {
  background: var(--kj-surface-2);
}
.kj-prose table.shop_attributes th,
.kj-prose table.woocommerce-product-attributes th {
  width: 40%;
  font-weight: 700; color: var(--kj-ink);
}
.kj-prose table.shop_attributes td p,
.kj-prose table.woocommerce-product-attributes td p { margin: 0; }

/* --- Reviews ------------------------------------------------------------ */

.kj-prose .comment-reply-title { font-size: var(--kj-fs-lg); font-weight: 800; color: var(--kj-ink); }
.kj-prose ol.commentlist { margin: 0 0 var(--kj-s6); padding: 0; list-style: none; }
.kj-prose ol.commentlist li { margin-block-end: var(--kj-s4); }
.kj-prose .comment_container {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr);
  gap: var(--kj-s4);
  padding: var(--kj-s4);
  background: var(--kj-surface-2);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-md);
}
.kj-prose .comment_container img.avatar {
  width: 48px; height: 48px;
  border-radius: 50%;
  margin: 0;
}
.kj-prose .comment-text { min-width: 0; }
.kj-prose .woocommerce-review__author { font-weight: 800; color: var(--kj-ink); }
.kj-prose .woocommerce-review__published-date { font-size: var(--kj-fs-xs); color: var(--kj-faint); }
.kj-prose .star-rating { color: var(--kj-star); }

.kj-prose .comment-form { display: grid; gap: var(--kj-s4); }
.kj-prose .comment-form label { display: block; margin-block-end: 6px; font-size: var(--kj-fs-sm); font-weight: 700; color: var(--kj-ink); }
.kj-prose .comment-form input[type="text"],
.kj-prose .comment-form input[type="email"],
.kj-prose .comment-form textarea {
  width: 100%;
  min-height: var(--kj-tap);
  padding: var(--kj-s3);
  font: inherit; font-size: var(--kj-fs-sm); color: var(--kj-ink);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-sm);
}
.kj-prose .comment-form textarea { min-height: 120px; resize: vertical; }
.kj-prose .comment-form input:focus-visible,
.kj-prose .comment-form textarea:focus-visible {
  outline: 2px solid var(--kj-primary); outline-offset: -1px;
}
.kj-prose .comment-form .submit {
  justify-self: start;
  min-height: var(--kj-tap);
  padding-inline: var(--kj-s6);
  font: inherit; font-weight: 800; color: var(--kj-on-primary, #fff);
  background: var(--kj-primary-solid, var(--kj-primary));
  border: 0; border-radius: var(--kj-r-sm);
  cursor: pointer;
}
.kj-prose .comment-form .submit:hover { background: var(--kj-primary-hover); }

/* --- Related products --------------------------------------------------- */

.related.products > h2,
.up-sells > h2,
.cross-sells > h2 {
  margin: 0 0 var(--kj-s5);
  font-size: var(--kj-fs-xl); font-weight: 800; color: var(--kj-ink);
}

/* --- Responsive --------------------------------------------------------- */

@media (max-width: 991px) {
  .kj-product__top { grid-template-columns: minmax(0, 1fr); gap: var(--kj-s6); }
  /* Stacked: sticky would pin the buy box over the gallery as it scrolls. */
  .kj-product__summary { position: static; }
}

@media (max-width: 575px) {
  .kj-product__title { font-size: var(--kj-fs-xl); }
  .kj-gallery__img { padding: var(--kj-s4); }
  .kj-gallery__thumb { width: 60px; height: 60px; }
  .kj-assure { grid-template-columns: minmax(0, 1fr); }
  .kj-product__buybox { padding: var(--kj-s4); }
  .kj-product__buybox button.single_add_to_cart_button { flex-basis: 100%; }
}

/* =========================================================================
   CART & CHECKOUT
   ========================================================================= */

/* ---------- Page shell for WooCommerce pages ----------------------------- */
.kj-wcpage__title {
  font-size: var(--kj-fs-2xl);
  font-weight: 800;
  color: var(--kj-ink);
  letter-spacing: -.02em;
  margin-block: var(--kj-s3) var(--kj-s5);
}

/* ---------- Step indicator ----------------------------------------------- */
.kj-steps {
  display: flex;
  align-items: flex-start;
  gap: var(--kj-s2);
  margin: 0 0 var(--kj-s6);
  padding: 0;
  list-style: none;
}
.kj-step {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--kj-s2);
  position: relative;
  text-align: center;
}
/* The connector is drawn from each step back to the previous one, so it never
   dangles past the first or last dot. Physical inset because the row is a
   fixed visual sequence, not text. */
.kj-step + .kj-step::before {
  content: "";
  position: absolute;
  inset-block-start: 17px;
  inset-inline-end: 50%;
  inline-size: 100%;
  block-size: 2px;
  background: var(--kj-line);
  z-index: 0;
}
.kj-step.is-done + .kj-step::before,
.kj-step.is-current + .kj-step::before { background: var(--kj-violet-200); }
.kj-step__dot {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  inline-size: 36px;
  block-size: 36px;
  border-radius: 50%;
  background: var(--kj-surface);
  border: 2px solid var(--kj-line);
  color: var(--kj-faint);
  transition: background var(--kj-t-base) var(--kj-ease),
              border-color var(--kj-t-base) var(--kj-ease),
              color var(--kj-t-base) var(--kj-ease);
}
.kj-step__label {
  font-size: var(--kj-fs-xs);
  font-weight: 600;
  color: var(--kj-faint);
  line-height: var(--kj-lh-tight);
}
.kj-step.is-current .kj-step__dot {
  background: var(--kj-primary-solid, var(--kj-primary));
  border-color: var(--kj-primary);
  color: var(--kj-on-primary, #fff);
  box-shadow: 0 0 0 4px var(--kj-primary-soft);
}
.kj-step.is-current .kj-step__label { color: var(--kj-ink); font-weight: 700; }
.kj-step.is-done .kj-step__dot {
  background: var(--kj-violet-100);
  border-color: var(--kj-violet-200);
  color: var(--kj-primary-ink, var(--kj-primary));
}
.kj-step.is-done .kj-step__label { color: var(--kj-body); }
@media (max-width: 419.98px) {
  .kj-step__label { font-size: 10px; }
}

/* ---------- Cart layout --------------------------------------------------- */
/* The cart form and the collaterals are siblings emitted by Woo, so the grid
   has to live on their shared parent. */
.kj-wcpage__body .woocommerce { display: contents; }
.kj-cart__form { margin: 0; }

@media (min-width: 992px) {
  /* Two columns: items take the space, the summary is a fixed rail.
     The step indicator and Woo's notices wrapper are siblings of the form,
     so they have to be told to span both columns — otherwise they occupy
     the first grid cell and shove the summary into a row of its own,
     leaving a tall empty gap beside it. */
  .kj-wcpage__body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 360px;
    align-items: start;
    gap: var(--kj-s6);
  }
  .kj-wcpage__body > .kj-steps,
  .kj-wcpage__body > .woocommerce-notices-wrapper,
  .kj-wcpage__body > .woocommerce-message,
  .kj-wcpage__body > .woocommerce-info,
  .kj-wcpage__body > .woocommerce-error { grid-column: 1 / -1; }
  .kj-cart__form  { grid-column: 1; }
  .kj-cart__aside { grid-column: 2; }
  /* Cross-sells are emitted inside the form, below the table, so they
     already sit in column 1 and need no placement of their own. */
}

/* ---------- Cart rows ----------------------------------------------------- */
.kj-cart__list {
  display: grid;
  gap: var(--kj-s3);
}
.kj-cartrow {
  display: grid;
  /* thumb | main | remove  on the first line; unit/qty/total wrap under. */
  grid-template-columns: 84px minmax(0, 1fr) auto;
  grid-template-areas:
    "media main   remove"
    "media unit   unit"
    "media qty    total";
  align-items: center;
  gap: var(--kj-s2) var(--kj-s4);
  padding: var(--kj-s4);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
}
.kj-cartrow__media { grid-area: media; align-self: start; }
.kj-cartrow__media img,
.kj-cartrow__media a {
  display: block;
  inline-size: 84px;
  block-size: 84px;
  object-fit: contain;
  border-radius: var(--kj-r-md);
  background: #fff;
}
.kj-cartrow__main   { grid-area: main; min-width: 0; }
.kj-cartrow__unit   { grid-area: unit; min-width: 0; }
.kj-cartrow__qty    { grid-area: qty; }
.kj-cartrow__total  { grid-area: total; min-width: 0; text-align: end; }
.kj-cartrow__remove { grid-area: remove; align-self: start; }

.kj-cartrow__title {
  display: block;
  font-size: var(--kj-fs-sm);
  font-weight: 700;
  color: var(--kj-ink);
  line-height: var(--kj-lh-tight);
  /* Two lines then ellipsis: a long Persian product name must not push the
     price row off the card. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.kj-cartrow__title:hover { color: var(--kj-primary-ink, var(--kj-primary)); }
.kj-cartrow__sku,
.kj-cartrow__note {
  margin-block: var(--kj-s1) 0;
  font-size: var(--kj-fs-xs);
  color: var(--kj-faint);
}
.kj-cartrow .variation {
  margin-block: var(--kj-s1) 0;
  font-size: var(--kj-fs-xs);
  color: var(--kj-muted);
}
.kj-cartrow .variation dt,
.kj-cartrow .variation dd { display: inline; margin: 0; }
/* Space after the label, not after the value: "رنگ: مشکی" not "رنگ:مشکی". */
.kj-cartrow .variation dt::after { content: " "; white-space: pre; }
.kj-cartrow .variation dd + dt { margin-inline-start: var(--kj-s3); }
.kj-cartrow .variation p { margin: 0; display: inline; }

.kj-cartrow__unit-label,
.kj-cartrow__total-label {
  display: block;
  font-size: var(--kj-fs-xs);
  color: var(--kj-faint);
  margin-block-end: 2px;
}
.kj-cartrow__unit  { font-size: var(--kj-fs-sm); color: var(--kj-body); }
.kj-cartrow__total { font-size: var(--kj-fs-md); font-weight: 800; color: var(--kj-ink); }
/* Woo prints its own <span class="amount"> inside these cells. */
.kj-cartrow__total .amount { font-weight: 800; }

/* Quantity stepper: Woo renders div.quantity > input.qty */
.kj-cartrow .quantity {
  display: inline-flex;
  align-items: center;
  block-size: calc(var(--kj-tap) + 2px);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-sm);
  overflow: hidden;
}
.kj-cartrow .quantity input[type="number"] {
  inline-size: 64px;
  block-size: 100%;
  padding: 0 var(--kj-s2);
  font: inherit;
  font-weight: 700;
  text-align: center;
  color: var(--kj-ink);
  background: transparent;
  border: 0;
  appearance: textfield;
}
.kj-cartrow .quantity input::-webkit-outer-spin-button,
.kj-cartrow .quantity input::-webkit-inner-spin-button { appearance: none; margin: 0; }
.kj-cartrow .quantity input:focus-visible {
  outline: 2px solid var(--kj-primary);
  outline-offset: -2px;
}
.kj-cartrow .quantity .screen-reader-text,
.kj-cartrow .quantity label.screen-reader-text { position: absolute !important; clip-path: inset(50%); inline-size: 1px; block-size: 1px; overflow: hidden; }

/* Remove button — Woo requires .product-remove > a, so style the anchor. */
.kj-cartrow__remove-btn {
  display: grid;
  place-items: center;
  inline-size: 36px;
  block-size: 36px;
  color: var(--kj-faint);
  background: transparent;
  border-radius: var(--kj-r-sm);
  transition: color var(--kj-t-fast) var(--kj-ease),
              background var(--kj-t-fast) var(--kj-ease);
  position: relative;
}
/* 36px visual box, 44px touch target. */
.kj-cartrow__remove-btn::after { content: ""; position: absolute; inset: -4px; }
.kj-cartrow__remove-btn:hover,
.kj-cartrow__remove-btn:focus-visible {
  color: var(--kj-sale-ink);
  background: var(--kj-sale-soft);
}

@media (min-width: 576px) {
  .kj-cartrow {
    grid-template-columns: 96px minmax(0, 1fr) auto auto auto;
    grid-template-areas: "media main unit qty total remove";
    gap: var(--kj-s4);
  }
  .kj-cartrow__media img,
  .kj-cartrow__media a { inline-size: 96px; block-size: 96px; }
  .kj-cartrow__unit,
  .kj-cartrow__total { text-align: center; }
  .kj-cartrow__total { min-inline-size: 116px; }
  .kj-cartrow__remove { align-self: center; }
}

/* ---------- Cart actions (coupon + update) -------------------------------- */
.kj-cart__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--kj-s3);
  padding: var(--kj-s4);
  background: var(--kj-surface-2);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
}
/* 260px is a *width* hint for the row layout. Once .kj-cart__actions turns
   into a column (<480px) flex-basis resolves against the block axis, so this
   would set a 260px HEIGHT and open a dead gap under the coupon field. Scope
   the basis to the row direction and reset it in the column media query. */
.kj-coupon { flex: 1 1 260px; min-width: 0; }
.kj-coupon__label {
  display: inline-flex;
  align-items: center;
  gap: var(--kj-s1);
  margin-block-end: var(--kj-s2);
  font-size: var(--kj-fs-sm);
  font-weight: 700;
  color: var(--kj-ink);
}
.kj-coupon__label svg { color: var(--kj-primary-ink, var(--kj-primary)); }
.kj-coupon__row { display: flex; gap: var(--kj-s2); }
.kj-coupon__input {
  flex: 1 1 auto;
  min-width: 0;
  min-block-size: var(--kj-tap);
  padding-inline: var(--kj-s4);
  font: inherit;
  font-size: var(--kj-fs-sm);
  color: var(--kj-ink);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-sm);
}
.kj-coupon__input:focus-visible {
  outline: 2px solid var(--kj-primary);
  outline-offset: -1px;
  border-color: var(--kj-primary);
}
.kj-cart__update { flex: 0 0 auto; }
.kj-cart__update[disabled] { opacity: .5; cursor: not-allowed; }

@media (max-width: 479.98px) {
  .kj-cart__actions {
    flex-direction: column;
    align-items: stretch;
    /* Nothing to distribute in a column; space-between would push the
       children to the two ends of any leftover height. */
    justify-content: flex-start;
  }
  /* Height must follow content now that the main axis is vertical. */
  .kj-coupon { flex: 0 0 auto; }
  .kj-cart__update { inline-size: 100%; justify-content: center; }
}

/* ---------- Totals panel --------------------------------------------------- */
.kj-totals {
  padding: var(--kj-s5);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
  box-shadow: var(--kj-sh-sm);
}
@media (min-width: 992px) {
  /* Follows the customer down a long cart. */
  .kj-totals { position: sticky; inset-block-start: calc(var(--kj-header-h) + var(--kj-s4)); }
}
.kj-totals__title {
  margin: 0 0 var(--kj-s4);
  font-size: var(--kj-fs-lg);
  font-weight: 800;
  color: var(--kj-ink);
}
.kj-totals__list { margin: 0; }
.kj-totals__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--kj-s3);
  padding-block: var(--kj-s3);
  border-block-end: 1px dashed var(--kj-line-2);
  font-size: var(--kj-fs-sm);
}
.kj-totals__row dt { color: var(--kj-muted); margin: 0; }
.kj-totals__row dd { margin: 0; color: var(--kj-ink); font-weight: 700; text-align: end; }
.kj-totals__row--save dd { color: var(--kj-success-ink); }
.kj-totals__row--grand {
  border-block-end: 0;
  padding-block-start: var(--kj-s4);
  margin-block-start: var(--kj-s1);
  border-block-start: 1px solid var(--kj-line);
}
.kj-totals__row--grand dt { color: var(--kj-ink); font-weight: 700; font-size: var(--kj-fs-md); }
.kj-totals__row--grand dd { font-size: var(--kj-fs-xl); font-weight: 800; color: var(--kj-primary-ink, var(--kj-primary)); }

/* Woo's shipping rows arrive as <tr>/<th>/<td> from wc_cart_totals_shipping_html.
   Re-flow them to match the dl rows around them. */
.kj-totals__list tr,
.kj-review__totals tr {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--kj-s3);
  padding-block: var(--kj-s3);
  border-block-end: 1px dashed var(--kj-line-2);
  font-size: var(--kj-fs-sm);
}
.kj-totals__list th,
.kj-review__totals th {
  font-weight: 500;
  color: var(--kj-muted);
  text-align: start;
  padding: 0;
}
.kj-totals__list td,
.kj-review__totals td {
  font-weight: 700;
  color: var(--kj-ink);
  text-align: end;
  padding: 0;
}
.kj-totals__list ul,
.kj-review__totals ul { margin: 0; padding: 0; list-style: none; text-align: start; }
.kj-totals__list li,
.kj-review__totals li { margin-block-end: var(--kj-s2); }
.kj-totals__list li:last-child,
.kj-review__totals li:last-child { margin-block-end: 0; }
/* Woo emits a bare <label> next to each shipping radio — no class, no
   wrapper — so target the label inside the rate list directly. An earlier
   .shipping__inner descendant selector matched nothing and the radio ended
   up flush against its text. */
.kj-totals__list li label,
.kj-review__totals li label,
#shipping_method label {
  display: inline-flex;
  align-items: center;
  gap: var(--kj-s2);
  font-size: var(--kj-fs-sm);
  color: var(--kj-body);
  cursor: pointer;
}
/* The radio and its label are siblings, so the gap above cannot reach
   across them; space them explicitly. */
.kj-totals__list li,
.kj-review__totals li,
#shipping_method li {
  display: flex;
  align-items: center;
  gap: var(--kj-s2);
}
.kj-totals__list input[type="radio"],
.kj-review__totals input[type="radio"] {
  inline-size: 18px;
  block-size: 18px;
  accent-color: var(--kj-primary);
  flex: none;
}
/* A shipping or payment choice is a real decision made with a thumb. The
   control glyph stays 18px (enlarging it looks clumsy), but the row it lives
   in gets a 24px minimum so the whole line is the hit area -- WCAG 2.5.8.
   The label is already display:flex and fills the row, so clicking anywhere
   along it activates the radio through the for= association. */
.kj-totals__list li,
.kj-review__totals li,
#shipping_method li,
#payment ul.payment_methods li {
  min-block-size: 28px;
}
.kj-totals__list li label,
.kj-review__totals li label,
#shipping_method label,
#payment ul.payment_methods li > label {
  min-block-size: 28px;
  padding-block: 2px;
}

.kj-totals__go { margin-block-start: var(--kj-s5); }
.kj-totals__go .kj-btn { inline-size: 100%; }

.kj-totals__trust {
  margin: var(--kj-s4) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--kj-s2);
}
.kj-totals__trust li {
  display: flex;
  align-items: center;
  gap: var(--kj-s2);
  font-size: var(--kj-fs-xs);
  color: var(--kj-muted);
}
.kj-totals__trust svg { color: var(--kj-success-ink); flex: none; }

/* ---------- Cross-sells ---------------------------------------------------- */
.cross-sells { margin-block-start: var(--kj-s8); }
.cross-sells > h2 {
  margin: 0 0 var(--kj-s4);
  font-size: var(--kj-fs-lg);
  font-weight: 800;
  color: var(--kj-ink);
}

/* ---------- Checkout ------------------------------------------------------- */
.kj-checkout__grid {
  display: grid;
  gap: var(--kj-s6);
}
@media (min-width: 992px) {
  .kj-checkout__grid {
    grid-template-columns: minmax(0, 1fr) 380px;
    align-items: start;
  }
}
.kj-checkout__fields { display: grid; gap: var(--kj-s5); }
.kj-checkout__panel {
  padding: var(--kj-s5);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
}
/* An empty shipping column would otherwise render as a stray empty card. */
.kj-checkout__panel:empty { display: none; }
.kj-checkout__panel h3 {
  margin: 0 0 var(--kj-s4);
  font-size: var(--kj-fs-md);
  font-weight: 800;
  color: var(--kj-ink);
}
.kj-checkout__aside-title {
  margin: 0 0 var(--kj-s4);
  font-size: var(--kj-fs-lg);
  font-weight: 800;
  color: var(--kj-ink);
}
.kj-checkout__review {
  padding: var(--kj-s5);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
  box-shadow: var(--kj-sh-sm);
}
@media (min-width: 992px) {
  .kj-checkout__aside {
    position: sticky;
    inset-block-start: calc(var(--kj-header-h) + var(--kj-s4));
  }
}

/* Woo's form rows. These class names come from the plugin. */
.kj-checkout .form-row {
  display: flex;
  flex-direction: column;
  gap: var(--kj-s2);
  margin: 0 0 var(--kj-s4);
  padding: 0;
}
.kj-checkout .form-row:last-child { margin-block-end: 0; }
.kj-checkout .form-row label {
  font-size: var(--kj-fs-sm);
  font-weight: 600;
  color: var(--kj-body);
}
.kj-checkout .form-row .required {
  color: var(--kj-sale-ink);
  text-decoration: none;
  margin-inline-start: 2px;
}
.kj-checkout .form-row .optional { color: var(--kj-faint); font-weight: 400; }
.kj-checkout input[type="text"],
.kj-checkout input[type="email"],
.kj-checkout input[type="tel"],
.kj-checkout input[type="password"],
.kj-checkout input[type="number"],
.kj-checkout textarea,
.kj-checkout select,
.kj-checkout .select2-selection {
  inline-size: 100%;
  min-block-size: var(--kj-tap);
  padding: var(--kj-s3) var(--kj-s4);
  font: inherit;
  font-size: var(--kj-fs-sm);
  color: var(--kj-ink);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-sm);
  transition: border-color var(--kj-t-fast) var(--kj-ease),
              box-shadow var(--kj-t-fast) var(--kj-ease);
}
.kj-checkout textarea { min-block-size: 96px; resize: vertical; line-height: var(--kj-lh-base); }
.kj-checkout input:focus-visible,
.kj-checkout textarea:focus-visible,
.kj-checkout select:focus-visible {
  outline: 0;
  border-color: var(--kj-primary);
  box-shadow: 0 0 0 3px var(--kj-primary-soft);
}
/* Woo marks invalid rows on blur. */
.kj-checkout .woocommerce-invalid input,
.kj-checkout .woocommerce-invalid select,
.kj-checkout .woocommerce-invalid textarea { border-color: var(--kj-sale-ink); }
.kj-checkout .woocommerce-validated input { border-color: var(--kj-success-ink); }

/* Two-up rows on wider screens: Woo emits form-row-first / form-row-last. */
@media (min-width: 576px) {
  .kj-checkout__panel .woocommerce-billing-fields__field-wrapper,
  .kj-checkout__panel .woocommerce-shipping-fields__field-wrapper,
  .kj-checkout__panel .woocommerce-additional-fields__field-wrapper {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 var(--kj-s4);
  }
  .kj-checkout .form-row-wide,
  .kj-checkout .notes { grid-column: 1 / -1; }
}

/* Order review list */
.kj-review__items { margin: 0 0 var(--kj-s4); padding: 0; list-style: none; }
.kj-review__item {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--kj-s3);
  padding-block: var(--kj-s3);
  border-block-end: 1px dashed var(--kj-line-2);
}
.kj-review__item:last-child { border-block-end: 0; }
.kj-review__thumb img {
  inline-size: 48px;
  block-size: 48px;
  object-fit: contain;
  border-radius: var(--kj-r-sm);
  background: #fff;
  border: 1px solid var(--kj-line-2);
}
.kj-review__name {
  min-width: 0;
  font-size: var(--kj-fs-sm);
  color: var(--kj-body);
  line-height: var(--kj-lh-tight);
}
.kj-review__qty { color: var(--kj-faint); font-weight: 700; }
.kj-review__price { font-size: var(--kj-fs-sm); font-weight: 800; color: var(--kj-ink); text-align: end; }
.kj-review__totals { margin: 0; }
.kj-review__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--kj-s3);
  padding-block: var(--kj-s3);
  border-block-end: 1px dashed var(--kj-line-2);
  font-size: var(--kj-fs-sm);
}
.kj-review__row dt { margin: 0; color: var(--kj-muted); }
.kj-review__row dd { margin: 0; font-weight: 700; color: var(--kj-ink); text-align: end; }
.kj-review__row--save dd { color: var(--kj-success-ink); }
.kj-review__row--grand {
  border-block-end: 0;
  border-block-start: 1px solid var(--kj-line);
  padding-block-start: var(--kj-s4);
  margin-block-start: var(--kj-s1);
}
.kj-review__row--grand dt { font-weight: 700; color: var(--kj-ink); font-size: var(--kj-fs-md); }
.kj-review__row--grand dd { font-size: var(--kj-fs-xl); font-weight: 800; color: var(--kj-primary-ink, var(--kj-primary)); }

/* Payment box */
.kj-checkout #payment,
.woocommerce-checkout #payment {
  margin-block-start: var(--kj-s5);
  background: transparent;
}
#payment ul.payment_methods {
  margin: 0 0 var(--kj-s4);
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--kj-s2);
}
#payment ul.payment_methods li {
  padding: var(--kj-s3) var(--kj-s4);
  background: var(--kj-surface-2);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-sm);
}
#payment ul.payment_methods li > label {
  display: inline-flex;
  align-items: center;
  gap: var(--kj-s2);
  font-size: var(--kj-fs-sm);
  font-weight: 600;
  color: var(--kj-ink);
  cursor: pointer;
}
#payment ul.payment_methods input[type="radio"] {
  inline-size: 18px;
  block-size: 18px;
  accent-color: var(--kj-primary);
  flex: none;
}
#payment .payment_box {
  margin-block-start: var(--kj-s3);
  padding: var(--kj-s3) var(--kj-s4);
  font-size: var(--kj-fs-xs);
  color: var(--kj-muted);
  background: var(--kj-surface);
  border-radius: var(--kj-r-sm);
  line-height: var(--kj-lh-base);
}
#payment .payment_box p:last-child { margin-block-end: 0; }
#payment .place-order { margin: 0; }
#payment button#place_order {
  inline-size: 100%;
  min-block-size: calc(var(--kj-tap) + 4px);
  padding-inline: var(--kj-s6);
  font: inherit;
  font-size: var(--kj-fs-md);
  font-weight: 800;
  color: var(--kj-on-primary, #fff);
  background: var(--kj-primary-solid, var(--kj-primary));
  border: 0;
  border-radius: var(--kj-r-sm);
  cursor: pointer;
  transition: background var(--kj-t-fast) var(--kj-ease),
              transform var(--kj-t-fast) var(--kj-ease-spring);
}
#payment button#place_order:hover { background: var(--kj-primary-hover); }
#payment button#place_order:active { transform: translateY(1px); }
#payment .woocommerce-terms-and-conditions-wrapper {
  margin-block-end: var(--kj-s4);
  font-size: var(--kj-fs-xs);
  color: var(--kj-muted);
}

/* Woo notices */
.woocommerce-message,
.woocommerce-info,
.woocommerce-error {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--kj-s3);
  margin: 0 0 var(--kj-s5);
  padding: var(--kj-s4);
  font-size: var(--kj-fs-sm);
  border-radius: var(--kj-r-md);
  border: 1px solid transparent;
  list-style: none;
}
.woocommerce-message {
  color: var(--kj-success-ink);
  background: var(--kj-success-soft);
  border-color: var(--kj-mint-400);
}
.woocommerce-info {
  color: var(--kj-primary-ink, var(--kj-primary));
  background: var(--kj-primary-soft);
  border-color: var(--kj-violet-200);
}
.woocommerce-error {
  color: var(--kj-sale-ink);
  background: var(--kj-sale-soft);
  border-color: var(--kj-rose-500);
}
.woocommerce-message .button,
.woocommerce-info .button { margin-inline-start: auto; }

/* =========================================================================
   MY ACCOUNT
   Sidebar + content shell, dashboard cards, order list, auth forms.
   Woo class names (.woocommerce-MyAccount-*, .woocommerce-Address, form-row)
   are kept in the markup for compatibility; layout hangs off .kj-* classes.
   ========================================================================= */

.kj-account {
  display: grid;
  gap: var(--kj-s5);
}

/* ---------- Sidebar ------------------------------------------------------- */
.kj-account__nav {
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
  padding: var(--kj-s4);
  box-shadow: var(--kj-sh-sm);
}
.kj-account__who {
  display: flex;
  align-items: center;
  gap: var(--kj-s3);
  padding-block-end: var(--kj-s4);
  margin-block-end: var(--kj-s3);
  border-block-end: 1px solid var(--kj-line);
}
.kj-account__avatar {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--kj-violet-50);
  color: var(--kj-primary-ink, var(--kj-primary));
}
.kj-account__who-text { display: grid; gap: 2px; min-width: 0; }
.kj-account__hello { font-size: var(--kj-fs-xs); color: var(--kj-faint); }
.kj-account__name {
  font-size: var(--kj-fs-sm);
  color: var(--kj-ink);
  /* A long display name must not widen the rail. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.kj-account__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.kj-account__link {
  display: flex;
  align-items: center;
  gap: var(--kj-s3);
  /* 44px tap target measured on the OUTER box: this control has no border,
     so min-height alone is the full height. */
  min-height: var(--kj-tap);
  padding: var(--kj-s2) var(--kj-s3);
  border-radius: var(--kj-r-md);
  color: var(--kj-body);
  font-size: var(--kj-fs-sm);
  text-decoration: none;
  transition: background var(--kj-t-fast) var(--kj-ease),
              color var(--kj-t-fast) var(--kj-ease);
}
.kj-account__link:hover { background: var(--kj-surface-2); color: var(--kj-ink); }
.kj-account__icon { flex: none; display: grid; place-items: center; color: var(--kj-faint); }
.kj-account__label { flex: 1 1 auto; min-width: 0; }
.kj-account__chev {
  flex: none;
  display: grid;
  place-items: center;
  color: var(--kj-line-2);
  opacity: 0;
  transition: opacity var(--kj-t-fast) var(--kj-ease);
}
.kj-account__link:hover .kj-account__chev { opacity: 1; }

/* Woo puts is-active on the <li>; the anchor carries aria-current="page". */
.kj-account__item.is-active > .kj-account__link,
.kj-account__link[aria-current="page"] {
  background: var(--kj-primary-solid, var(--kj-primary));
  color: var(--kj-on-primary, #fff);
  font-weight: 700;
}
.kj-account__item.is-active > .kj-account__link .kj-account__icon,
.kj-account__link[aria-current="page"] .kj-account__icon,
.kj-account__item.is-active > .kj-account__link .kj-account__chev,
.kj-account__link[aria-current="page"] .kj-account__chev {
  color: #fff;
  opacity: 1;
}
/* Logout reads as a quiet exit, never as a destination. */
.kj-account__item.woocommerce-MyAccount-navigation-link--customer-logout > .kj-account__link {
  color: var(--kj-sale-ink);
}

/* ---------- Content panel ------------------------------------------------- */
.kj-account__content {
  min-width: 0;
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
  padding: var(--kj-s5);
  box-shadow: var(--kj-sh-sm);
}
.kj-account__content > :first-child { margin-block-start: 0; }
.kj-account__content > :last-child { margin-block-end: 0; }

@media (min-width: 992px) {
  .kj-account {
    grid-template-columns: 264px minmax(0, 1fr);
    /* stretch, not start: a short panel next to a tall sidebar otherwise
       leaves a ragged void under the content card. The sidebar opts back
       out below so sticky still works. */
    align-items: stretch;
  }
  .kj-account__nav {
    position: sticky;
    top: calc(var(--kj-header-h) + var(--kj-s4));
    align-self: start;
  }
}

/* ---------- Dashboard ----------------------------------------------------- */
.kj-dash__hello {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--kj-s3);
  margin: 0 0 var(--kj-s5);
}
/* Must stay a single flex item: loose text nodes would each be spaced out
   by justify-content and the sentence would come apart. */
.kj-dash__greeting {
  margin: 0;
  font-size: var(--kj-fs-md);
  color: var(--kj-body);
}
.kj-dash__greeting strong { color: var(--kj-ink); }
.kj-dash__logout {
  display: inline-flex;
  align-items: center;
  gap: var(--kj-s1);
  min-height: var(--kj-tap);
  padding-inline: var(--kj-s2);
  font-size: var(--kj-fs-sm);
  color: var(--kj-sale-ink);
  text-decoration: none;
}
.kj-dash__logout:hover { text-decoration: underline; }

.kj-dash__grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--kj-s3);
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 640px) {
  .kj-dash__grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr)); }
}
.kj-dash__card {
  display: flex;
  align-items: center;
  gap: var(--kj-s3);
  height: 100%;
  padding: var(--kj-s4);
  background: var(--kj-surface-2);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--kj-t-fast) var(--kj-ease),
              transform var(--kj-t-fast) var(--kj-ease),
              box-shadow var(--kj-t-fast) var(--kj-ease);
}
.kj-dash__card:hover {
  border-color: var(--kj-primary);
  box-shadow: var(--kj-sh-sm);
  transform: translateY(-2px);
}
@media (prefers-reduced-motion: reduce) {
  .kj-dash__card { transition: none; }
  .kj-dash__card:hover { transform: none; }
}
.kj-dash__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: var(--kj-r-md);
  background: var(--kj-violet-50);
  color: var(--kj-primary-ink, var(--kj-primary));
}
.kj-dash__text { display: grid; gap: 2px; min-width: 0; }
.kj-dash__title { font-size: var(--kj-fs-sm); color: var(--kj-ink); }
.kj-dash__desc { font-size: var(--kj-fs-xs); color: var(--kj-muted); }
.kj-dash__go { flex: none; color: var(--kj-line-2); }
.kj-dash__card:hover .kj-dash__go { color: var(--kj-primary-ink, var(--kj-primary)); }

/* ---------- Orders list --------------------------------------------------- */
.kj-orders { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--kj-s3); }
.kj-order {
  padding: var(--kj-s4);
  background: var(--kj-surface-2);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
}
.kj-order__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--kj-s2);
  padding-block-end: var(--kj-s3);
  border-block-end: 1px solid var(--kj-line);
}
.kj-order__num { display: inline-flex; align-items: baseline; gap: var(--kj-s2); }
.kj-order__num-label { font-size: var(--kj-fs-xs); color: var(--kj-faint); }
.kj-order__num-link { color: var(--kj-ink); font-weight: 700; text-decoration: none; }
.kj-order__num-link:hover { color: var(--kj-primary-ink, var(--kj-primary)); text-decoration: underline; }

.kj-order__status {
  display: inline-flex;
  align-items: center;
  padding: 4px var(--kj-s3);
  border-radius: 999px;
  font-size: var(--kj-fs-xs);
  font-weight: 700;
  /* Neutral default: an unknown/custom status still reads as a badge. */
  background: var(--kj-surface);
  color: var(--kj-muted);
  border: 1px solid var(--kj-line);
}
.kj-order__status--completed { background: var(--kj-success-soft); color: var(--kj-success-ink); border-color: transparent; }
.kj-order__status--processing,
.kj-order__status--on-hold { background: var(--kj-accent-soft); color: var(--kj-accent-ink); border-color: transparent; }
.kj-order__status--cancelled,
.kj-order__status--failed,
.kj-order__status--refunded { background: var(--kj-sale-soft); color: var(--kj-sale-ink); border-color: transparent; }
.kj-order__status--pending { background: var(--kj-primary-soft); color: var(--kj-primary-ink, var(--kj-primary)); border-color: transparent; }

.kj-order__meta {
  display: grid;
  gap: var(--kj-s2);
  margin: var(--kj-s3) 0 0;
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 480px) {
  .kj-order__meta { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.kj-order__pair { display: grid; gap: 2px; min-width: 0; }
.kj-order__pair dt { font-size: var(--kj-fs-xs); color: var(--kj-faint); }
.kj-order__pair dd { margin: 0; font-size: var(--kj-fs-sm); color: var(--kj-body); }
.kj-order__pair--total dd { font-weight: 700; color: var(--kj-ink); }

.kj-order__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--kj-s2);
  margin-block-start: var(--kj-s3);
  padding-block-start: var(--kj-s3);
  border-block-start: 1px solid var(--kj-line);
}

.kj-orders__pager {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--kj-s3);
  margin-block-start: var(--kj-s5);
}
.kj-orders__pager-count { font-size: var(--kj-fs-sm); color: var(--kj-muted); }

/* ---------- Addresses ----------------------------------------------------- */
.kj-addr__lead { margin: 0 0 var(--kj-s4); color: var(--kj-muted); font-size: var(--kj-fs-sm); }
.kj-addr__grid {
  display: grid;
  gap: var(--kj-s4);
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 720px) {
  .kj-addr__grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }
}
.kj-addr {
  padding: var(--kj-s4);
  background: var(--kj-surface-2);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
}
.kj-addr__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--kj-s2);
  margin-block-end: var(--kj-s3);
}
.kj-addr__title {
  display: inline-flex;
  align-items: center;
  gap: var(--kj-s2);
  margin: 0;
  font-size: var(--kj-fs-md);
  color: var(--kj-ink);
}
.kj-addr__icon { color: var(--kj-primary-ink, var(--kj-primary)); display: grid; place-items: center; }
.kj-addr__body {
  margin: 0;
  font-style: normal;
  line-height: 1.9;
  color: var(--kj-body);
  font-size: var(--kj-fs-sm);
}
.kj-addr__body--empty { color: var(--kj-faint); }

/* ---------- Forms (login, register, edit account) ------------------------- */
.kj-form__section { margin-block-end: var(--kj-s5); border: 0; padding: 0; }
.kj-form__section:last-of-type { margin-block-end: 0; }
.kj-form__legend {
  margin: 0 0 var(--kj-s3);
  padding: 0;
  font-size: var(--kj-fs-md);
  color: var(--kj-ink);
}
.kj-form__grid { display: grid; gap: 0 var(--kj-s4); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 560px) {
  .kj-form__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.kj-form__row { display: grid; gap: var(--kj-s2); margin: 0 0 var(--kj-s4); }
.kj-form__row label { font-size: var(--kj-fs-sm); font-weight: 700; color: var(--kj-ink); }
.kj-form__row .required { color: var(--kj-sale-ink); margin-inline-start: 2px; }

.kj-form__input,
.kj-form input[type="text"],
.kj-form input[type="email"],
.kj-form input[type="tel"],
.kj-form input[type="password"] {
  inline-size: 100%;
  /* A 1px border inside a 44px box leaves a 42px control, so size from the
     token plus the two borders. */
  min-block-size: calc(var(--kj-tap) + 2px);
  padding: var(--kj-s2) var(--kj-s3);
  font: inherit;
  font-size: var(--kj-fs-sm);
  color: var(--kj-ink);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line-2);
  border-radius: var(--kj-r-md);
  transition: border-color var(--kj-t-fast) var(--kj-ease),
              box-shadow var(--kj-t-fast) var(--kj-ease);
}
.kj-form__input:focus,
.kj-form input:focus {
  outline: none;
  border-color: var(--kj-primary);
  box-shadow: 0 0 0 3px var(--kj-primary-soft);
}
.kj-form__hint { font-size: var(--kj-fs-xs); color: var(--kj-muted); }
.kj-form__hint--block { margin: 0 0 var(--kj-s3); }
.kj-form__row--submit { gap: var(--kj-s3); margin-block-end: var(--kj-s3); }
.kj-form__actions { margin: 0; }

/* Woo's JS wraps password inputs in .password-input and appends an eye
   button; it is absolutely positioned, so the wrapper must be relative and
   the field needs room for it. */
.kj-form .password-input { position: relative; display: block; }
.kj-form .password-input input { padding-inline-end: calc(var(--kj-tap) + var(--kj-s2)); }
.kj-form .show-password-input {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: var(--kj-s2);
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  inline-size: var(--kj-tap);
  block-size: var(--kj-tap);
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--kj-faint);
}
.kj-form .show-password-input::after {
  content: "";
  inline-size: 18px;
  block-size: 18px;
  background: currentColor;
  /* Eye glyph, so no extra request and it follows currentColor. */
  mask: center / contain no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7-10-7-10-7Z'/%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3C/svg%3E");
  -webkit-mask: center / contain no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7-10-7-10-7Z'/%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3C/svg%3E");
}
.kj-form .show-password-input.display-password { color: var(--kj-primary-ink, var(--kj-primary)); }

/* Woo's strength meter appends .woocommerce-password-strength after the field. */
.kj-form .woocommerce-password-strength {
  margin-block-start: var(--kj-s2);
  padding: var(--kj-s2) var(--kj-s3);
  border-radius: var(--kj-r-xs);
  font-size: var(--kj-fs-xs);
  font-weight: 700;
  text-align: center;
}
.kj-form .woocommerce-password-strength.strong { background: var(--kj-success-soft); color: var(--kj-success-ink); }
.kj-form .woocommerce-password-strength.good { background: var(--kj-primary-soft); color: var(--kj-primary-ink, var(--kj-primary)); }
.kj-form .woocommerce-password-strength.short,
.kj-form .woocommerce-password-strength.bad { background: var(--kj-accent-soft); color: var(--kj-accent-ink); }
.kj-form .woocommerce-password-hint {
  display: block;
  margin-block-start: var(--kj-s2);
  font-size: var(--kj-fs-xs);
  color: var(--kj-muted);
}

/* ---------- Login / register ---------------------------------------------- */
.kj-auth__cols {
  display: grid;
  gap: var(--kj-s5);
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 880px) {
  .kj-auth__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.kj-auth__card {
  height: 100%;
  padding: var(--kj-s5);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
  box-shadow: var(--kj-sh-sm);
}
.kj-auth--single .kj-auth__card {
  max-inline-size: 480px;
  margin-inline: auto;
}
.kj-auth__title { margin: 0 0 var(--kj-s2); font-size: var(--kj-fs-lg); color: var(--kj-ink); }
.kj-auth__lead { margin: 0 0 var(--kj-s4); font-size: var(--kj-fs-sm); color: var(--kj-muted); }
.kj-auth__note { margin: 0 0 var(--kj-s4); font-size: var(--kj-fs-sm); color: var(--kj-muted); }
.kj-auth__lost { margin: 0; text-align: center; }
.kj-auth__lost a { font-size: var(--kj-fs-sm); color: var(--kj-primary-ink, var(--kj-primary)); }

/* ---------- WC page shell: account variant -------------------------------- */
/* The cart/checkout rule pins a 360px summary rail on .kj-wcpage__body; the
   account page brings its own two-column grid, so that inherited template
   must be neutralised. A modifier class set by page.php is used rather than
   :has() — the selector is only supported in newer browsers, and if it fails
   the account page silently renders in a 360px column. */
.kj-wcpage__body--account { display: block; }

/* =========================================================================
   COLOUR AND PRICE FACETS
   ========================================================================= */

/* ---------- Colour swatches ----------------------------------------------- */
.kj-swatches {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--kj-s1);
}
.kj-swatches__item { min-width: 0; }

/* The real checkbox is visually hidden but stays in the tab order, so the
   label is the visible control and :checked/:focus-visible drive its state. */
.kj-swatch {
  display: flex;
  align-items: center;
  gap: var(--kj-s2);
  min-height: var(--kj-tap);
  padding: var(--kj-s1) var(--kj-s2);
  border: 1px solid transparent;
  border-radius: var(--kj-r-md);
  cursor: pointer;
  font-size: var(--kj-fs-sm);
  color: var(--kj-body);
  transition: background var(--kj-t-fast) var(--kj-ease),
              border-color var(--kj-t-fast) var(--kj-ease);
}
.kj-swatch:hover { background: var(--kj-surface-2); }

.kj-swatch__dot {
  flex: none;
  inline-size: 20px;
  block-size: 20px;
  border-radius: 50%;
  background: var(--kj-swatch, var(--kj-line-2));
  /* An inset ring rather than an outer border, so a white swatch is still
     visible against a white panel without changing the dot's footprint. */
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 18%);
}
.kj-swatch__name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kj-swatch__count { flex: none; font-size: var(--kj-fs-xs); color: var(--kj-faint); }

.kj-swatch__input:checked + .kj-swatch {
  background: var(--kj-primary-soft);
  border-color: var(--kj-primary);
  font-weight: 700;
  color: var(--kj-ink);
}
.kj-swatch__input:checked + .kj-swatch .kj-swatch__count { color: var(--kj-primary-ink, var(--kj-primary)); }
/* The input is visually hidden, so its focus ring must be re-hosted on the
   label or keyboard users get no visible focus at all. */
.kj-swatch__input:focus-visible + .kj-swatch {
  outline: 2px solid var(--kj-primary);
  outline-offset: 2px;
}

/* ---------- Price range --------------------------------------------------- */
.kj-price { display: grid; gap: var(--kj-s2); }
.kj-price__row {
  display: grid;
  /* minmax(0,1fr) not 1fr: an auto track is min-content sized and a number
     input's default width would overflow the 264px rail. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--kj-s2);
}
.kj-price__field { display: grid; gap: 4px; min-width: 0; }
.kj-price__label { font-size: var(--kj-fs-xs); color: var(--kj-faint); }
.kj-price__input {
  inline-size: 100%;
  min-width: 0;
  /* 44px outer box: the 1px border on each side would otherwise leave a
     42px control. */
  min-block-size: calc(var(--kj-tap) + 2px);
  padding: var(--kj-s1) var(--kj-s2);
  font: inherit;
  font-size: var(--kj-fs-sm);
  color: var(--kj-ink);
  background: var(--kj-surface);
  border: 1px solid var(--kj-line-2);
  border-radius: var(--kj-r-md);
  transition: border-color var(--kj-t-fast) var(--kj-ease),
              box-shadow var(--kj-t-fast) var(--kj-ease);
}
.kj-price__input:focus {
  outline: none;
  border-color: var(--kj-primary);
  box-shadow: 0 0 0 3px var(--kj-primary-soft);
}
/* Spinners steal width in a narrow rail and are useless on a price. */
.kj-price__input::-webkit-outer-spin-button,
.kj-price__input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.kj-price__input { -moz-appearance: textfield; appearance: textfield; }

.kj-price__hint { margin: 0; font-size: var(--kj-fs-xs); color: var(--kj-muted); line-height: 1.7; }

/* ---------- Shared filter actions ----------------------------------------- */
.kj-filter__actions {
  display: grid;
  gap: var(--kj-s2);
  padding-block-start: var(--kj-s3);
  border-block-start: 1px solid var(--kj-line);
}
.kj-filter__actions .kj-filter__apply { inline-size: 100%; justify-content: center; }
.kj-filter__actions .kj-filter__reset {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--kj-tap);
  font-size: var(--kj-fs-sm);
  color: var(--kj-muted);
  text-decoration: none;
}
.kj-filter__actions .kj-filter__reset:hover { color: var(--kj-sale-ink); text-decoration: underline; }

/* =========================================================================
   COMPARE — floating bar and comparison table
   ========================================================================= */

/*
 * The bar is fixed to the bottom of the viewport and only exists once a
 * product is picked. It sits below the toast layer so a confirmation is never
 * hidden behind it, and above everything else the page scrolls.
 */
.kj-cmpbar {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: calc(var(--kj-z-toast) - 1);
  background: var(--kj-surface);
  border-top: 1px solid var(--kj-line);
  box-shadow: var(--kj-sh-lg);
  padding: var(--kj-s3) 0;
  animation: kj-cmpbar-in .22s ease-out both;
}
.kj-cmpbar[hidden] { display: none; }

@keyframes kj-cmpbar-in {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .kj-cmpbar { animation: none; }
}

.kj-cmpbar__inner {
  width: min(var(--kj-container), 100% - 2 * var(--kj-gutter));
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: var(--kj-s4);
  flex-wrap: wrap;
}

/*
 * The chip strip scrolls on its own rather than pushing the action buttons
 * off the row: at four products on a phone the buttons must stay reachable.
 */
.kj-cmpbar__items {
  display: flex;
  gap: var(--kj-s2);
  flex: 1 1 220px;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: thin;
  padding-block: 2px;
}

.kj-cmpbar__actions {
  display: flex;
  gap: var(--kj-s2);
  flex: none;
  margin-inline-start: auto;
}

/* Fewer than two products is nothing to compare; say so instead of leading
   the shopper to an empty table. */
.kj-cmpbar__go.is-disabled {
  opacity: .5;
  pointer-events: none;
}

.kj-cmpchip {
  display: flex;
  align-items: center;
  gap: var(--kj-s2);
  flex: none;
  background: var(--kj-surface-2);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-md);
  padding: 6px var(--kj-s2) 6px 6px;
  max-width: 260px;
}
.kj-cmpchip__img {
  width: 44px; height: 44px;
  border-radius: var(--kj-r-sm);
  object-fit: contain;
  background: #fff;
  flex: none;
}
.kj-cmpchip__img--empty { background: var(--kj-surface-3); }
.kj-cmpchip__body { display: grid; min-width: 0; }
.kj-cmpchip__name {
  font-size: var(--kj-fs-sm);
  color: var(--kj-ink);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 150px;
}
.kj-cmpchip__price { font-size: var(--kj-fs-xs); color: var(--kj-muted); }

.kj-cmpchip__x {
  flex: none;
  width: 28px; height: 28px;
  display: grid; place-items: center;
  border: 0;
  background: transparent;
  color: var(--kj-faint);
  font-size: 20px;
  line-height: 1;
  border-radius: var(--kj-r-sm);
  cursor: pointer;
}
.kj-cmpchip__x:hover { background: var(--kj-surface-3); color: var(--kj-ink); }

/* The bar overlays the page bottom, so give the document room to scroll past
   it — otherwise the footer's last row is unreachable. The bar's height
   changes with wrapping, so the script publishes the measured value; the
   fallback covers the moment before the first measurement. */
.kj-has-cmpbar { padding-bottom: var(--kj-cmpbar-h, 104px); }

/* ---------- comparison table --------------------------------------------- */

/* The table reads as one panel rather than rows floating on the page. */
.kj-cmp-wrap {
  overflow-x: auto;
  background: var(--kj-surface);
  border: 1px solid var(--kj-line);
  border-radius: var(--kj-r-lg);
}

.kj-cmp {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  min-width: 560px;
}
.kj-cmp th,
.kj-cmp td {
  padding: var(--kj-s3);
  border-bottom: 1px solid var(--kj-line);
  text-align: start;
  vertical-align: middle;
}
/*
 * The row-label column is sticky so a shopper scrolling a four-product table
 * sideways on a phone never loses track of which attribute they are reading.
 */
.kj-cmp th[scope="row"] {
  position: sticky;
  inset-inline-start: 0;
  background: var(--kj-surface-2);
  color: var(--kj-muted);
  font-weight: 600;
  font-size: var(--kj-fs-sm);
  width: 116px;
  z-index: 1;
}
/* The image row's header carries only a screen-reader label, so it must not
   draw as an empty tile next to the product shots. */
.kj-cmp th[scope="row"].is-quiet { background: var(--kj-surface); }

/* The last row closes on the wrapper's own rounded edge. */
.kj-cmp tr:last-child th,
.kj-cmp tr:last-child td { border-bottom: 0; }
.kj-cmp td { color: var(--kj-ink); }
.kj-cmp__img {
  width: 100%;
  max-width: 140px;
  height: auto;
  aspect-ratio: 1;
  object-fit: contain;
  background: #fff;
  border-radius: var(--kj-r-md);
}
/*
 * A one-word product name gives a 23px-tall link, below the minimum target.
 * Padding on the link itself keeps it comfortable without changing the row
 * rhythm, since the cell already has its own padding.
 */
.kj-cmp__name {
  display: inline-block;
  font-weight: 700;
  color: var(--kj-ink);
  text-decoration: none;
  padding-block: 5px;
}
.kj-cmp__name:hover { color: var(--kj-primary-ink, var(--kj-primary)); }
.kj-cmp__na { color: var(--kj-faint); }

/* Rows where every product agrees are dimmed, so differences lead the eye. */
.kj-cmp__row.is-same td { color: var(--kj-muted); }

.kj-cmp-tools {
  display: flex;
  align-items: center;
  gap: var(--kj-s2);
  margin-bottom: var(--kj-s3);
}

/* ---------- Setup prompt (admin-only, empty shop) ------------------------- */
.kj-setup { padding-block: var(--kj-s8); }
.kj-setup__card {
  padding: var(--kj-s7);
  background: var(--kj-surface);
  border: 1px dashed var(--kj-line);
  border-radius: var(--kj-r-lg);
}
.kj-setup__eyebrow {
  margin: 0 0 var(--kj-s2);
  font-size: var(--kj-fs-sm);
  font-weight: 700;
  color: var(--kj-primary-ink, var(--kj-primary));
}
.kj-setup__title { margin: 0 0 var(--kj-s3); font-size: var(--kj-fs-2xl); font-weight: 800; }
.kj-setup__text { margin: 0 0 var(--kj-s6); max-width: 70ch; color: var(--kj-muted); line-height: var(--kj-lh-loose); }
.kj-setup__steps { display: grid; gap: var(--kj-s5); }
@media (min-width: 768px) { .kj-setup__steps { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.kj-setup__step { display: flex; gap: var(--kj-s4); align-items: flex-start; }
.kj-setup__step > div { min-width: 0; }
.kj-setup__step h3 { margin: 0 0 var(--kj-s2); font-size: var(--kj-fs-md); font-weight: 700; }
.kj-setup__step p { margin: 0 0 var(--kj-s4); font-size: var(--kj-fs-sm); color: var(--kj-muted); }
.kj-setup__num {
  flex: none;
  inline-size: 34px; block-size: 34px;
  display: grid; place-items: center;
  font-weight: 800;
  color: var(--kj-on-primary, #fff);
  background: var(--kj-primary-solid, var(--kj-primary));
  border-radius: var(--kj-r-pill);
}
