/* ===========================================================================
   ROZER STORE — shelf, product buy box, basket, checkout
   Requires /site.css first (tokens, reset, buttons, footer).

   Jakob's Law in practice: every component below is the shape people already
   know from other shops — a grid of cards with a price and an add button, a
   basket icon with a count, a line-item table with quantity steppers, an order
   summary that sticks beside the form. Nothing invented.

   The house style still applies: grey rounded cards on white, one red,
   outlined pill actions, no shadow, no glow, no blur, no gradient.
   =========================================================================== */

/* ---------- STORE HEADER ---------- */
.shop-head {
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  border-bottom: 1px solid var(--accent-line);
}
@supports not (background: color-mix(in srgb, red 50%, blue)) {
  .shop-head { background: var(--bg); }
}
.shop-head__inner {
  max-width: var(--wrap);
  margin-inline: auto;
  padding: 0.9rem var(--pad);
  display: flex;
  align-items: center;
  gap: 1.25rem;
}
/* Wordmark: the sans, all red, set in capitals like a maker's mark. */
.shop-head__logo {
  font-family: var(--font-head);
  font-size: 1.25rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
  margin-inline-end: auto;
}
.shop-head__links { display: flex; align-items: center; gap: 1.25rem; }
/* Nav links are red text; hover changes opacity only. */
.shop-head__link {
  font-size: 0.94rem;
  color: var(--accent-text);
  transition: opacity var(--fast);
}
.shop-head__link:hover { opacity: 0.65; }
.shop-head__link[aria-current="page"] { text-decoration: underline; text-underline-offset: 5px; }

/* Basket button — icon + count, the single most recognised control in any shop */
.basket-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.94rem;
  padding: 0.45em 1.1em;
  color: var(--accent-text);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-pill);
  transition: background var(--fast), color var(--fast), border-color var(--fast);
}
.basket-btn:hover { background: var(--accent-hi); border-color: var(--accent-hi); color: var(--accent-ink); }
.basket-btn__count {
  min-width: 1.35em;
  height: 1.35em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  background: var(--accent-hi);
  color: var(--accent-ink);
  border-radius: var(--r-pill);
  padding: 0 0.35em;
}
.basket-btn__count.is-empty { display: none; }

/* ---------- SHELF ---------- */
.shelf-intro {
  max-width: var(--wrap);
  margin-inline: auto;
  padding: 3.5rem var(--pad) 0;
}
.shelf-intro h1 {
  font-size: clamp(2.75rem, 6vw, 4.5rem);
  line-height: 0.99;
  text-wrap: balance;
}
.shelf-intro p {
  color: var(--text-2);
  font-size: 1rem;
  line-height: 1.6;
  max-width: 52ch;
  margin-top: 0.9rem;
  text-wrap: pretty;
}

/* Section label: 10px red mono over a 1px red rule, count on the right. */
.shelf-bar {
  width: calc(100% - 2 * var(--pad));
  max-width: calc(var(--wrap) - 2 * var(--pad));
  margin: 2.5rem auto 1.9rem;
  padding-bottom: 0.7rem;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  border-bottom: 1px solid var(--accent-line);
}
.shelf-bar__label,
.shelf-bar__count {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-text);
}

.shelf {
  max-width: var(--wrap);
  margin-inline: auto;
  padding: 0 var(--pad) 4rem;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 20px;
}

/* Product card: soft grey on the white page, 25px radius, 30px padding, the
   package centred at the top. No border, no shadow. */
.pcard {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-radius: var(--r-card);
  padding: 1.9rem;
  overflow: hidden;
  transition: background var(--fast);
}
.pcard:hover { background: var(--surface-hi); }
.pcard:has(.pcard__name a:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.pcard__media {
  width: 52px; height: 52px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-md);
  background: var(--bg-raised);
  margin-bottom: 1.1rem;
  overflow: hidden;
}
.pcard__media img { width: 32px; height: 32px; object-fit: contain; }
.pcard__name {
  font-family: var(--font-head);
  font-size: 1.25rem;
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: 0.017em;
  color: var(--text);
  margin-bottom: 0.35rem;
}
.pcard__name a:focus-visible { outline: none; }
/* Stretched link: the whole card is clickable, but the Add button sits above it */
.pcard__name a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
.pcard__name a { color: inherit; }
.pcard__tagline {
  color: var(--text-2);
  font-size: 0.94rem;
  line-height: 1.5;
  letter-spacing: 0.013em;
  text-wrap: pretty;
  margin-bottom: 1.4rem;
}
/* ---------- COMPATIBILITY STRIP ---------- */
.pcard__support {
  margin-top: auto;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding-bottom: 1rem;
}
.sup {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 5px;
  font-family: var(--font-head);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  line-height: 1;
  border: 1px solid transparent;
}
/* Adobe's own tile colours — recognisability is the point of these marks. */
.sup--pr { background: #2a0634; color: #d8a0ff; border-color: #4a1060; }
.sup--ae { background: #00005b; color: #a2a2ff; border-color: #1a1a80; }
.sup--ps { background: #001e36; color: #9ad0ff; border-color: #0a3a5c; }
.sup--os { color: var(--text-3); border-color: var(--rule-2); background: var(--bg-raised); }
.sup-sep {
  width: 1px;
  height: 14px;
  background: var(--rule-2);
  margin-inline: 0.25rem;
}

.pcard__foot {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--rule-2);
}
/* The price is the thing a shopper's eye goes to first — it gets display
   weight, with the qualifiers ("From", "/ month") stepped down around it. */
.pcard__price {
  font-family: var(--font-display);
  font-size: 2.25rem;
  font-weight: 300;
  letter-spacing: -0.005em;
  line-height: 1;
  color: var(--text);
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  flex-wrap: wrap;
}
.pcard__price small {
  font-family: var(--font-body);
  font-size: 0.88rem;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--text-3);
}
.pcard__price .pcard__from {
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--text-3);
}
.pcard__cta {
  position: relative;
  z-index: 2;              /* above the stretched link */
  flex-shrink: 0;
  width: 46px;
  height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
  color: var(--accent-text);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-pill);
  transition: background var(--fast), color var(--fast), border-color var(--fast);
}
.pcard__cta:hover { background: var(--accent-hi); border-color: var(--accent-hi); color: var(--accent-ink); }
.pcard__cta:active { transform: translateY(1px); }
.pcard__cta.is-added { background: var(--ok-soft); border-color: var(--ok); color: var(--ok); }

.pcard__tag {
  align-self: flex-end;      /* its own line above the box, never overlapping it */
  margin-bottom: -0.4rem;
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-text);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-pill);
  padding: 0.25em 0.8em;
}

/* ---------- BUY BOX (product page) ---------- */
.buybox {
  border-radius: var(--r-card);
  background: var(--surface);
  padding: 1.9rem;
}
.buybox__price {
  font-family: var(--font-display);
  font-size: 2.75rem;
  font-weight: 300;
  letter-spacing: -0.005em;
  line-height: 1;
}
.buybox__price small {
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 400;
  color: var(--text-2);
  letter-spacing: 0;
}
.buybox__note {
  color: var(--text-2);
  font-size: 0.85rem;
  line-height: 1.55;
  margin-top: 0.55rem;
}
.buybox__recurring {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.8rem;
  font-size: 0.78rem;
  color: var(--accent-text);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-pill);
  padding: 0.35em 0.9em;
}

/* One axis = one row of choices. Segmented control, like a size picker. */
.axis { margin-top: 1.4rem; }
.axis__label {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 0.55rem;
}
.axis__opts { display: flex; flex-wrap: wrap; gap: 0.5rem; }
/* Choices are outlined pills; the chosen one takes the red outline. */
.axis__opt {
  font-family: inherit;
  font-size: 0.94rem;
  color: var(--text-2);
  background: var(--bg);
  border: 1px solid var(--rule-2);
  border-radius: var(--r-pill);
  padding: 0.5em 1.15em;
  cursor: pointer;
  transition: border-color var(--fast), color var(--fast), background var(--fast);
}
.axis__opt:hover { color: var(--text); border-color: var(--rule-3); }
.axis__opt[aria-pressed="true"] {
  color: var(--accent-text);
  background: var(--bg);
  border-color: var(--accent-line);
  box-shadow: inset 0 0 0 1px var(--accent-line);
}
.axis__opt[disabled] { opacity: 0.35; cursor: not-allowed; }

.buybox__add {
  width: 100%;
  margin-top: 1.5rem;
  font-family: inherit;
  font-size: 0.94rem;
  padding: 0.8em 1.2em;
  color: var(--accent-text);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-pill);
  transition: background var(--fast), color var(--fast), border-color var(--fast);
}
.buybox__add:hover { background: var(--accent-hi); border-color: var(--accent-hi); color: var(--accent-ink); }
.buybox__add:active { transform: translateY(1px); }
.buybox__added {
  display: none;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.9rem;
  font-size: 0.85rem;
  color: var(--ok);
}
.buybox__added.is-on { display: flex; }
.buybox__added a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 3px; }
.buybox__fine {
  margin-top: 1rem;
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--text-3);
}

/* ---------- BASKET ---------- */
/* Page title on the basket and checkout: a display line, like every other page. */
.shop-title {
  font-size: clamp(2.75rem, 6vw, 4.5rem);
  line-height: 0.99;
}
.cart-wrap {
  max-width: var(--wrap);
  margin-inline: auto;
  padding: 3rem var(--pad) 4rem;
}
/* ── "Add to your order" ───────────────────────────────────────────────────
   Cross-sell under the basket lines. Deliberately small and rule-separated,
   not a second shelf: the job of this page is to finish the order, and a row
   that competes with Checkout costs more than it earns. */
.suggest { margin-top: 2.5rem; }
.suggest__h {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-text);
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--accent-line);
  margin-bottom: 1rem;
}
.suggest__row {
  display: grid;
  /* Wide enough that a full product name does not ellipsis away. In the
     basket's narrow left column that means two per row, not three. */
  grid-template-columns: repeat(auto-fit, minmax(248px, 1fr));
  gap: 10px;
}
.sug {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.85rem 1rem;
  background: var(--surface);
  border-radius: var(--r-md);
}
.sug__art {
  flex: none;
  width: 44px;
  height: 36px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg-raised);
}
.sug__art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sug__body { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; margin-inline-end: auto; }
.sug__name {
  font-size: 0.86rem;
  font-weight: 500;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sug__name:hover { color: var(--accent-text); }
.sug__price { font-family: var(--font-mono); font-size: 0.68rem; color: var(--text-3); }
.sug__add {
  flex: none;
  font: inherit;
  font-size: 0.82rem;
  text-decoration: none;
  padding: 0.34rem 0.95rem;
  background: transparent;
  cursor: pointer;
  color: var(--accent-text);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-pill);
  transition: background var(--fast), color var(--fast), border-color var(--fast);
}
.sug__add:hover { background: var(--accent-hi); border-color: var(--accent-hi); color: var(--accent-ink); }

/* ── Add-to-basket feedback ────────────────────────────────────────────────
   A clone of what you clicked, flying to the basket. Fixed and unclickable so
   it can never affect layout or intercept a click; only transform and opacity
   animate, so it stays on the compositor. */
.fly-basket {
  position: fixed;
  z-index: 200;
  margin: 0;
  pointer-events: none;
  border-radius: var(--r-sm);
  overflow: hidden;
  transform-origin: center;
  transition: transform 300ms cubic-bezier(.2, .7, .3, 1), opacity 300ms linear;
  will-change: transform, opacity;
}
.fly-basket * { pointer-events: none; }

/* The basket itself acknowledges the arrival — one short, flat pop. */
.basket-btn.is-bumped { animation: basket-bump 480ms cubic-bezier(.2, .8, .3, 1); }
@keyframes basket-bump {
  0%   { transform: scale(1); }
  32%  { transform: scale(1.16); }
  62%  { transform: scale(0.96); }
  100% { transform: scale(1); }
}
.basket-btn.is-bumped .basket-btn__count {
  animation: basket-count-in 480ms cubic-bezier(.2, .8, .3, 1);
}
@keyframes basket-count-in {
  0%   { transform: scale(0.4); opacity: 0.4; }
  55%  { transform: scale(1.25); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .fly-basket { display: none; }
  .basket-btn.is-bumped,
  .basket-btn.is-bumped .basket-btn__count { animation: none; }
}

.cart-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: 2.5rem;
  align-items: start;
  margin-top: 2rem;
}
.cart-lines { border-top: 1px solid var(--accent-line); }
.cart-line {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) auto;
  gap: 1.1rem;
  align-items: start;
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--rule);
}
.cart-line__media {
  width: 56px; height: 56px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-md);
  background: var(--surface);
  overflow: hidden;
}
.cart-line__media img { width: 32px; height: 32px; object-fit: contain; }
/* A cover fills the tile; a logo stays inset. */
.cart-line__media img.is-cover { width: 100%; height: 100%; object-fit: cover; }
.cart-line__name {
  font-family: var(--font-head);
  font-weight: 400;
  font-size: 1.25rem;
  line-height: 1.3;
  letter-spacing: 0.017em;
}
.cart-line__name a { color: inherit; }
.cart-line__name a:hover { color: var(--accent-text); }
.cart-line__variant {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--text-3);
  margin-top: 0.3rem;
}
.cart-line__recurring {
  display: inline-block;
  margin-top: 0.5rem;
  font-size: 0.75rem;
  color: var(--accent-text);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-pill);
  padding: 0.2em 0.8em;
}
.cart-line__right { text-align: end; }
.cart-line__total { font-family: var(--font-mono); font-size: 0.9rem; }

/* Quantity stepper — the universal − N + control */
.qty {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--rule-2);
  border-radius: var(--r-pill);
  overflow: hidden;
  margin-top: 0.7rem;
}
.qty button {
  width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono);
  font-size: 0.95rem;
  color: var(--text-2);
  background: transparent;
  transition: background var(--fast), color var(--fast);
}
.qty button:hover:not([disabled]) { background: var(--surface); color: var(--text); }
.qty button[disabled] { opacity: 0.3; cursor: not-allowed; }
.qty__n {
  min-width: 34px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  border-inline: 1px solid var(--rule);
  line-height: 30px;
}
.cart-line__remove {
  display: block;
  margin-top: 0.7rem;
  font-size: 0.78rem;
  color: var(--text-3);
  background: none;
  font-family: inherit;
  transition: color var(--fast);
}
.cart-line__remove:hover { color: var(--err); }

/* Order summary — sticky, as on every checkout people have used */
.summary {
  position: sticky;
  top: 5.5rem;
  border-radius: var(--r-card);
  background: var(--surface);
  padding: 1.9rem;
}
/* A panel title, not a display line: the sans at 20px, in ink. */
.summary h2 {
  font-family: var(--font-head);
  font-size: 1.25rem;
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: 0.017em;
  color: var(--text);
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--rule-2);
  margin-bottom: 1rem;
}
.summary__row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.87rem;
  color: var(--text-2);
  padding: 0.4rem 0;
}
.summary__row--total {
  margin-top: 0.75rem;
  padding-top: 1rem;
  border-top: 1px solid var(--rule-2);
  color: var(--text);
  font-size: 1.05rem;
  font-weight: 500;
}
.summary__row--total .summary__v { font-family: var(--font-display); font-size: 1.9rem; font-weight: 300; line-height: 1; }
.summary__v { font-family: var(--font-mono); color: var(--text); }
.summary__note {
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--text-3);
  margin-top: 0.9rem;
}
.summary__cta {
  display: block;
  width: 100%;
  text-align: center;
  margin-top: 1.25rem;
  font-family: inherit;
  font-size: 0.94rem;
  padding: 0.8em 1.2em;
  color: var(--accent-text);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-pill);
  transition: background var(--fast), color var(--fast), border-color var(--fast);
}
.summary__cta:hover { background: var(--accent-hi); border-color: var(--accent-hi); color: var(--accent-ink); }
.summary__back {
  display: block;
  text-align: center;
  margin-top: 0.8rem;
  font-size: 0.86rem;
  color: var(--accent-text);
  transition: opacity var(--fast);
}
.summary__back:hover { opacity: 0.65; }

/* Empty basket — a composed state, not a blank page */
.cart-empty {
  text-align: center;
  padding: 5rem 1.9rem;
  background: var(--surface);
  border-radius: var(--r-card);
  margin-top: 2rem;
}
.cart-empty svg { color: var(--accent-text); margin-bottom: 1.25rem; }
.cart-empty h2 { font-size: clamp(2rem, 4vw, 2.75rem); margin-bottom: 0.6rem; }
.cart-empty p { color: var(--text-2); font-size: 0.92rem; margin-bottom: 1.75rem; }

/* ---------- CHECKOUT ---------- */
.co-step {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: 0.6rem;
}
.co-block {
  background: var(--surface);
  border-radius: var(--r-card);
  padding: 1.9rem;
  margin-bottom: 1.25rem;
}
/* A panel title: the sans at 20px, in ink. */
.co-block h2 {
  font-family: var(--font-head);
  font-size: 1.25rem;
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: 0.017em;
  color: var(--text);
  margin-bottom: 0.35rem;
}
.co-block p.co-sub { color: var(--text-2); font-size: 0.86rem; line-height: 1.55; }
.co-mini {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.7rem 0;
  font-size: 0.86rem;
}
.co-mini + .co-mini { border-top: 1px solid var(--rule-2); }
.co-mini__q { font-family: var(--font-mono); font-size: 0.74rem; color: var(--text-3); }
.co-mini__n { flex: 1; min-width: 0; }
.co-mini__p { font-family: var(--font-mono); font-size: 0.82rem; }

/* ---------- RESPONSIVE ---------- */
@media (max-width: 900px) {
  .cart-grid { grid-template-columns: minmax(0, 1fr); gap: 2rem; }
  .summary { position: static; }
}
@media (max-width: 560px) {
  .shop-head__links { gap: 0.85rem; }
  .shop-head__link { display: none; }
  .cart-line { grid-template-columns: 44px minmax(0, 1fr); }
  .cart-line__media { width: 44px; height: 44px; }
  .cart-line__right { grid-column: 2; text-align: start; }
}

/* ---------- BOX SHOT ----------
   A real box: three faces built from one origin, so it has volume rather than
   being a tilted card. Front, left side and top, each positioned from the
   centre and pushed out by half the box's own dimension — the standard cube
   construction, which keeps the corners meeting exactly at any angle.

   Lighting is consistent and flat: one light from the front-left, so the front
   is lightest, the top is mid, and the side is darkest. No blur, no gradient
   glow — just three solid tones and hairline edges, same as the rest of the site.
   Built in CSS rather than generated, so the text is always correct and a new
   catalogue entry gets a box for free. */
.boxshot {
  --bw: 132px;            /* width  */
  --bh: 184px;            /* height */
  --bd: 34px;             /* depth  */
  position: relative;
  perspective: 1000px;
  perspective-origin: 50% 40%;
  display: flex;
  justify-content: center;
  align-items: center;
  height: calc(var(--bh) + 62px);
  margin: -1.9rem -1.9rem 1.4rem;   /* the stage bleeds to the card edges */
  overflow: hidden;
  /* The package stands on the card's own grey: one flat field, centred. */
}
.boxshot__inner {
  position: relative;
  width: var(--bw);
  height: var(--bh);
  transform-style: preserve-3d;
  /* Turned to show the spine, tipped so the top face reads. The angles are
     custom properties so the pointer tracker can drive them per frame. */
  transform: rotateX(var(--rx, 8deg)) rotateY(var(--ry, 28deg));
  transition: transform 520ms cubic-bezier(.22, .61, .36, 1);
  will-change: transform;
}
/* While the cursor is on the card the box is attached to it — near-instant.
   On leave the properties are removed and the long transition eases it home. */
.boxshot__inner.is-tracking { transition: transform 90ms linear; }
/* Fallback for pointers we don't track (and before JS runs). */
.pcard:hover .boxshot__inner:not(.is-tracking) { transform: rotateX(6deg) rotateY(18deg); }

.boxshot__face {
  position: absolute;
  left: 50%;
  top: 50%;
  border: 1px solid var(--rule-2);
  backface-visibility: hidden;
}

/* FRONT — the cover. Lightest face. */
.boxshot__front {
  width: var(--bw);
  height: var(--bh);
  transform: translate(-50%, -50%) translateZ(calc(var(--bd) / 2));
  background: var(--box-front);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  text-align: center;
}
/* Cover art bleeds to the box edges, like the artwork on a real software box;
   the title block sits under it. The files are cut to this slot's exact ratio
   (132 : 184*0.58), so object-fit has nothing to crop away — change the 58%
   and the covers have to be re-cut, or compositions start losing their edges. */
.boxshot__art--shot {
  width: 100%;
  height: 58%;
  border-bottom: 1px solid var(--rule-2);
  overflow: hidden;
}
.boxshot__art--shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}
.boxshot__copy {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  padding: 0.6rem 0.6rem 0.75rem;
}
.boxshot__icon { width: 38px; height: 38px; object-fit: contain; }
.boxshot__name {
  font-family: var(--font-head);
  font-size: 0.74rem;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--text);
  text-wrap: balance;
}
.boxshot__rule { width: 20px; height: 2px; background: var(--accent); }
.boxshot__kind {
  font-family: var(--font-mono);
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-3);
}

/* SIDE — the spine. Darkest face, turned away from the light. */
.boxshot__side {
  width: var(--bd);
  height: var(--bh);
  transform: translate(-50%, -50%) rotateY(-90deg) translateZ(calc(var(--bw) / 2));
  background: var(--box-side);
  display: flex;
  align-items: center;
  justify-content: center;
}
.boxshot__side span {
  font-family: var(--font-head);
  font-size: 0.56rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  /* --text-3 measures 4.33:1 on the light theme's side face; the face stays
     dark because that is what gives the box its volume, so the type steps up
     instead. 5.21:1 light, and still quiet on dark. */
  color: var(--text-2);
  white-space: nowrap;
  transform: rotate(90deg);
}

/* TOP — mid tone. This is the face that actually sells the volume. */
.boxshot__top {
  width: var(--bw);
  height: var(--bd);
  transform: translate(-50%, -50%) rotateX(90deg) translateZ(calc(var(--bh) / 2));
  background: var(--box-top);
}

/* No contact shadow: the system has no drop shadows. The three shaded faces
   carry the volume on their own. */

@media (prefers-reduced-motion: reduce) {
  .boxshot__inner { transition: none; }
  .pcard:hover .boxshot__inner { transform: rotateX(8deg) rotateY(28deg); }
}

/* ---------- HEADER: ACCOUNT + BASKET ----------
   Both controls carry a word, not just a glyph. A shopper should never have to
   hover an icon to find out whether they're signed in or what's in the basket. */
.acct-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.4em 0.7em;
  border-radius: var(--r-pill);
  color: var(--accent-text);
  transition: opacity var(--fast);
}
.acct-btn:hover { opacity: 0.65; }
.acct-btn__text { display: flex; flex-direction: column; line-height: 1.15; text-align: start; }
.acct-btn__top { font-size: 0.94rem; color: var(--accent-text); }
.acct-btn__sub { font-size: 0.68rem; color: var(--text-3); }
.acct-btn.is-in .acct-btn__sub { color: var(--ok); }

/* Was a solid amber block; the system allows outlined actions only, so the
   modifier now just widens the spacing for the icon + label + count. */
.basket-btn--solid {
  gap: 0.6rem;
  padding: 0.45em 1.15em;
}
.basket-btn__ico { position: relative; display: inline-flex; }
.basket-btn--solid .basket-btn__count {
  position: absolute;
  top: -7px;
  inset-inline-end: -9px;
  border: 1px solid var(--bg);
}
.basket-btn__label { font-size: 0.94rem; }

@media (max-width: 640px) {
  .acct-btn__text { display: none; }
  .basket-btn__label { display: none; }
}

/* ---------- PROMO STRIP ----------
   Three flat cards. No countdowns, no invented discounts — each one points at
   something that actually exists.

   The tracks are explicit rather than auto-fit: an odd number of cards in a
   two-column grid leaves a visible hole in the bottom-right, which reads as a
   card that failed to load. The last card takes the whole row instead. */
.promos {
  max-width: var(--wrap);
  margin-inline: auto;
  padding: 2.5rem var(--pad) 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}
@media (min-width: 620px) {
  .promos { grid-template-columns: repeat(2, 1fr); }
  .promos > :last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@media (min-width: 1000px) {
  /* Three across, so three cards fill the row and nothing has to stretch. */
  .promos { grid-template-columns: repeat(3, 1fr); }
  .promos > :last-child:nth-child(odd) { grid-column: auto; }
  /* A fourth card would otherwise sit alone under three — give it the row. */
  .promos > :last-child:nth-child(3n + 1) { grid-column: 1 / -1; }
}
.promo {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 1.9rem;
  background: var(--surface);
  border-radius: var(--r-card);
  transition: background var(--fast);
}
.promo:hover { background: var(--surface-hi); }
.promo__kicker {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: 0.35rem;
}
.promo__title {
  font-family: var(--font-head);
  font-size: 1.25rem;
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: 0.017em;
  color: var(--text);
  text-wrap: balance;
}
.promo__sub { font-size: 0.94rem; color: var(--text-2); line-height: 1.5; text-wrap: pretty; }
/* The one red band on the page. The fill is the deeper red, so white type on
   it clears 4.5:1 (the brick red itself is 4.35:1 under white). */
.promo--accent { background: var(--accent-hi); }
.promo--accent:hover { background: var(--accent-hi); opacity: 0.94; }
.promo--accent .promo__kicker,
.promo--accent .promo__title,
.promo--accent .promo__sub { color: var(--accent-ink); }

/* ---------- PLAY BUTTON + VIDEO LIGHTBOX ----------
   aescripts-style: if a product has a video you can watch it from the shelf
   without losing your place. The button only exists when a video does. */
.pcard__actions { display: inline-flex; align-items: center; gap: 0.5rem; }
.pcard__play {
  position: relative;
  z-index: 2;                 /* above the card's stretched link */
  flex-shrink: 0;
  width: 46px;
  height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-pill);
  border: 1px solid var(--rule-3);
  background: transparent;
  color: var(--text);
  font-family: inherit;
  transition: color var(--fast), border-color var(--fast);
}
.pcard__play:hover { color: var(--accent-text); border-color: var(--accent-line); }
.pcard__play:active { transform: translateY(1px); }

html.vlb-open, html.vlb-open body { overflow: hidden; }
.vlb {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: var(--scrim-deep);
}
.vlb[hidden] { display: none; }
.vlb__box {
  width: min(1000px, 100%);
  background: var(--bg);
  border-radius: var(--r-card);
  overflow: hidden;
}
.vlb__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.9rem 1.1rem;
  border-bottom: 1px solid var(--rule);
}
.vlb__title {
  font-size: 0.92rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--text);
}
.vlb__close {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  line-height: 1;
  color: var(--text-3);
  border: 1px solid var(--rule-2);
  border-radius: 50%;
  background: transparent;
  font-family: inherit;
  transition: color var(--fast), border-color var(--fast);
}
.vlb__close:hover { color: var(--text); border-color: var(--rule-3); }
.vlb__video {
  display: block;
  width: 100%;
  max-height: 72vh;
  background: #000;
}

/* ---------- BOX COVER ART ----------
   Each box front carries a motif of what the product does, so the shelf is
   readable without reading. Two tones only — neutral structure, accent for the
   action — so four different covers still look like one family. */
.boxshot__art {
  width: 100%;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.6rem;
}
.boxshot__art .cov { width: 92%; height: auto; }
.boxshot__icon { width: 38px; height: 38px; object-fit: contain; }

/* Shared motif palette */
.cov-dim,
.cov-dim2   { fill: var(--rule-3); }
.cov-dim-s  { stroke: var(--rule-2); }
.cov-dim2-f { fill: var(--rule-3); }
.cov-panel  { fill: var(--surface); stroke: var(--rule-2); stroke-width: 1.5; }
.cov-acc,
.cov-acc-f  { fill: var(--accent); }
.cov-acc-s  { stroke: var(--accent); }

/* ---------- TYPE CHIP ----------
   Says what the thing IS — a plug-in or an app — before any reading. */
.sup--type {
  width: auto;
  gap: 0.3rem;
  padding: 0 0.6em;
  border-radius: var(--r-pill);
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-2);
  background: var(--bg-raised);
  border-color: var(--rule-2);
}
.sup--type svg { flex-shrink: 0; }

/* ---------- CHECKOUT IDENTITY ---------- */
.co-who { display: flex; align-items: center; gap: 0.85rem; }
.co-who__av {
  flex-shrink: 0;
  width: 38px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--accent-line);
  border-radius: 50%;
  background: var(--bg-raised);
  font-family: var(--font-head);
  font-weight: 500;
  color: var(--accent-text);
}
.co-who__meta { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.co-who__name { font-weight: 500; font-size: 0.92rem; }
.co-who__mail { font-family: var(--font-mono); font-size: 0.74rem; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; }
.co-who__switch { font-size: 0.8rem; color: var(--text-3); flex-shrink: 0; }
.co-who__switch:hover { color: var(--accent-text); }
