/* ==========================================================================
   Components
   --------------------------------------------------------------------------
   Header, hero, cards, drawer, footer.

   Every surface is one step up the ladder in output.css plus a hairline
   edge. There are no box-shadows, no coloured halos and no text shadows in
   this file: a card lifts by getting lighter, not by casting.
   ========================================================================== */

/* --- surfaces ----------------------------------------------------------- */

.dm-glass,
.dm-panel {
  background: var(--dm-surface-1);
  border: 1px solid var(--dm-edge);
  border-radius: var(--dm-radius);
}

.dm-glass--light {
  background: var(--dm-surface-2);
}

.dm-glass--soft {
  background: var(--dm-glass-soft);
}

.dm-panel--pad {
  padding: 20px;
}

@media (min-width: 768px) {
  .dm-panel--pad {
    padding: 26px;
  }
}

/* --- buttons ------------------------------------------------------------ */
/* Three weights and no more: filled accent for the one action that matters,
   a raised neutral for everything secondary, an outline for the pairing
   next to a filled button. None of them carry a shadow. */

.dm-btn {
  --btn-bg: var(--dm-surface-2);
  --btn-fg: var(--dm-ink);
  --btn-edge: var(--dm-edge);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 11px 18px;
  border: 1px solid var(--btn-edge);
  border-radius: var(--dm-radius-sm);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: 0.9063rem;
  font-weight: 600;
  letter-spacing: -0.012em;
  white-space: nowrap;
  transition: background 0.18s var(--dm-ease), border-color 0.18s var(--dm-ease),
    color 0.18s var(--dm-ease), transform 0.18s var(--dm-ease);
}

.dm-btn:hover {
  --btn-bg: var(--dm-surface-3);
  --btn-edge: var(--dm-edge-2);
}

.dm-btn:active {
  transform: translateY(1px);
}

/* Every icon is sized by the control that holds it. The set shipped with
   Tailwind sizing classes that this template has no framework for, so any
   icon missing an intrinsic size rendered at its natural dimensions - which
   is how the sign-out glyph ended up filling the dropdown. */
.dm-btn svg,
.dm-iconbtn svg,
.dm-menu__item svg,
.dm-include svg,
.dm-social svg {
  width: 1.05em;
  height: 1.05em;
  flex: none;
}

.dm-iconbtn svg {
  width: 17px;
  height: 17px;
}

.dm-menu__item svg {
  width: 15px;
  height: 15px;
}

.dm-btn i {
  font-size: 0.875em;
}

.dm-btn--primary {
  --btn-bg: var(--dm-accent);
  --btn-fg: var(--dm-on-accent);
  --btn-edge: transparent;
  font-weight: 700;
}

.dm-btn--primary:hover {
  --btn-bg: color-mix(in srgb, var(--dm-accent) 88%, #fff);
  --btn-edge: transparent;
}

/* Sits beside a filled button: same weight of shape, none of the fill, so
   the pair reads as one primary and one alternative. */
.dm-btn--outline {
  --btn-bg: transparent;
  --btn-edge: var(--dm-edge-2);
}

.dm-btn--outline:hover {
  --btn-bg: var(--dm-glass-light);
  --btn-edge: var(--dm-edge-3);
}

.dm-btn--ghost {
  --btn-bg: transparent;
  --btn-edge: transparent;
}

.dm-btn--danger {
  --btn-bg: color-mix(in srgb, var(--dm-sale) 14%, transparent);
  --btn-fg: color-mix(in srgb, var(--dm-sale) 70%, #fff);
  --btn-edge: color-mix(in srgb, var(--dm-sale) 30%, transparent);
}

.dm-btn--danger:hover {
  --btn-bg: color-mix(in srgb, var(--dm-sale) 24%, transparent);
  --btn-edge: color-mix(in srgb, var(--dm-sale) 44%, transparent);
}

.dm-btn--lg {
  padding: 14px 24px;
  font-size: 0.9688rem;
}

.dm-btn--sm {
  padding: 8px 13px;
  font-size: 0.8438rem;
}

.dm-btn--block {
  width: 100%;
}

.dm-btn--pill {
  border-radius: 999px;
}

.dm-iconbtn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--dm-edge);
  border-radius: var(--dm-radius-xs);
  background: var(--dm-surface-1);
  color: var(--dm-dim);
  transition: color 0.18s var(--dm-ease), background 0.18s var(--dm-ease),
    border-color 0.18s var(--dm-ease);
}

.dm-iconbtn:hover {
  color: var(--dm-ink);
  background: var(--dm-surface-3);
  border-color: var(--dm-edge-2);
}

/* --- chips, badges, price ----------------------------------------------- */

.dm-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 9px;
  border: 1px solid var(--dm-edge);
  border-radius: 6px;
  background: var(--dm-glass-light);
  color: var(--dm-dim);
  font-family: var(--dm-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.dm-chip i {
  font-size: 0.5rem;
  color: var(--dm-accent);
}

.dm-tag {
  display: inline-flex;
  align-items: center;
  padding: 4px 9px;
  border-radius: 6px;
  background: rgb(250 250 250 / 94%);
  color: #101012;
  font-family: var(--dm-mono);
  font-size: 0.5938rem;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  white-space: nowrap;
}

.dm-tag--accent {
  background: var(--dm-accent);
  color: var(--dm-on-accent);
}

.dm-tag--sale {
  background: var(--dm-sale);
  color: #fff;
}

.dm-price {
  font-family: var(--dm-display);
  font-weight: 800;
  font-size: 1.375rem;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  color: var(--dm-ink);
}

.dm-price--lg {
  font-size: clamp(2rem, 3.2vw, 2.6rem);
}

.dm-price--free {
  color: var(--dm-accent);
}

.dm-price-was {
  font-family: var(--dm-body);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--dm-faint);
  text-decoration: line-through;
}

/* --- header ------------------------------------------------------------- */
/* Transparent at rest: no bar, no border, no boxes. Only the wordmark, the
   navigation as plain text, and one solid action. The page reads as one
   surface until you scroll, at which point a blurred ground and a single
   hairline separate the header from the content moving under it. */

.dm-topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s var(--dm-ease), background 0.3s var(--dm-ease),
    backdrop-filter 0.3s var(--dm-ease);
}

.dm-topbar.is-stuck {
  background: color-mix(in srgb, var(--dm-bg) 76%, transparent);
  backdrop-filter: blur(var(--dm-blur-lg)) saturate(150%);
  -webkit-backdrop-filter: blur(var(--dm-blur-lg)) saturate(150%);
  border-bottom-color: var(--dm-edge);
}

.dm-topbar__inner {
  display: flex;
  align-items: center;
  gap: 14px;
  height: var(--dm-header);
}

/* Every control in the header is bare. The accent button below is the only
   filled element, so it is unmistakably the primary action. */
.dm-topbar .dm-iconbtn,
.dm-topbar .dm-btn:not(.dm-btn--primary) {
  background: transparent;
  border-color: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.dm-topbar .dm-iconbtn {
  width: 34px;
  height: 34px;
  color: var(--dm-faint);
}

.dm-topbar .dm-iconbtn:hover,
.dm-topbar .dm-btn:not(.dm-btn--primary):hover {
  background: var(--dm-glass-light);
  border-color: transparent;
  color: var(--dm-ink);
}

.dm-topbar .dm-btn:not(.dm-btn--primary) {
  color: var(--dm-dim);
  font-weight: 500;
}

.dm-brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex: none;
}

.dm-brand__mark {
  width: 30px;
  height: 30px;
  object-fit: contain;
}

.dm-brand__name {
  font-family: var(--dm-display);
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
}

.dm-brand__slug {
  font-family: var(--dm-mono);
  font-size: 0.5625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dm-faint);
}

/* The rule between wordmark and navigation belongs to a bar with a
   background. A transparent header has nothing to divide. */
.dm-divider {
  display: none;
}

.dm-nav {
  display: none;
  align-items: center;
  gap: 2px;
  margin-left: 14px;
}

.dm-nav__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 13px;
  border-radius: var(--dm-radius-xs);
  color: var(--dm-faint);
  font-size: 0.9063rem;
  font-weight: 500;
  letter-spacing: -0.012em;
  transition: color 0.2s var(--dm-ease);
}

.dm-nav__link:hover,
.dm-nav__link.is-open {
  color: var(--dm-ink);
  background: transparent;
}

/* The current page is marked by an accent dot under the label, not by a
   filled pill. Nothing in the header gets a box. */
.dm-nav__link.is-active {
  color: var(--dm-ink);
  background: transparent;
}

.dm-nav__link.is-active::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 1px;
  width: 4px;
  height: 4px;
  margin-left: -2px;
  border-radius: 50%;
  background: var(--dm-accent);
}

.dm-nav__link i {
  font-size: 0.5625rem;
  opacity: 0.6;
  transition: transform 0.24s var(--dm-ease);
}

.dm-nav__link.is-open i {
  transform: rotate(180deg);
}

.dm-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  flex: none;
}

.dm-actions--desktop {
  display: none;
}

/* A hairline before the sign-in cluster, so the actions read as their own
   group without needing a container around them. */
.dm-actions--desktop::before {
  content: "";
  width: 1px;
  height: 18px;
  margin-inline: 6px 2px;
  background: var(--dm-edge-2);
}

@media (min-width: 1080px) {
  .dm-nav,
  .dm-actions--desktop {
    display: flex;
  }

  .dm-actions--mobile {
    display: none;
  }
}

/* --- dropdown menus ----------------------------------------------------- */

.dm-drop {
  position: relative;
}

.dm-menu {
  position: absolute;
  left: 0;
  top: calc(100% + 12px);
  z-index: 50;
  min-width: 230px;
  padding: 8px;
  border: 1px solid var(--dm-edge);
  border-radius: var(--dm-radius);
  background: var(--dm-glass-strong);
  backdrop-filter: blur(var(--dm-blur-lg)) saturate(150%);
  -webkit-backdrop-filter: blur(var(--dm-blur-lg)) saturate(150%);
  box-shadow: 0 26px 60px -34px rgb(0 0 0 / 80%);
  opacity: 0;
  visibility: hidden;
  translate: 0 -6px;
  transition: opacity 0.18s var(--dm-ease), translate 0.18s var(--dm-ease), visibility 0.18s;
}

.dm-menu--right {
  left: auto;
  right: 0;
}

.dm-menu.is-open {
  opacity: 1;
  visibility: visible;
  translate: 0 0;
}

.dm-menu__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 13px;
  border-radius: 9px;
  color: var(--dm-dim);
  font-size: 0.9375rem;
  font-weight: 500;
  transition: background 0.15s var(--dm-ease), color 0.15s var(--dm-ease);
}

.dm-menu__item:hover {
  background: var(--dm-glass-lighter);
  color: var(--dm-ink);
}

.dm-menu__item.is-active {
  color: var(--dm-accent);
}

.dm-menu__item i {
  font-size: 0.6875rem;
  color: var(--dm-faint);
  transition: transform 0.18s var(--dm-ease), color 0.18s var(--dm-ease);
}

.dm-menu__item:hover i {
  color: var(--dm-accent);
  transform: translateX(2px);
}

.dm-menu__count {
  font-family: var(--dm-mono);
  font-size: 0.6875rem;
  color: var(--dm-faint);
}

.dm-menu--grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 3px;
  min-width: 216px;
}

.dm-menu--grid .dm-menu__item {
  justify-content: center;
  padding: 9px 6px;
  font-family: var(--dm-mono);
  font-size: 0.75rem;
}

.dm-cart-dot {
  position: absolute;
  top: -5px;
  right: -5px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9px;
  background: var(--dm-accent);
  color: var(--dm-on-accent);
  font-family: var(--dm-mono);
  font-size: 0.5625rem;
  font-weight: 700;
}

/* mobile panel */
.dm-mobile {
  display: none;
  border-top: 1px solid var(--dm-edge);
  background: color-mix(in srgb, var(--dm-bg) 92%, transparent);
  backdrop-filter: blur(var(--dm-blur-lg)) saturate(150%);
  -webkit-backdrop-filter: blur(var(--dm-blur-lg)) saturate(150%);
}

.dm-mobile.is-open {
  display: block;
}

.dm-mobile__inner {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding-block: 16px;
}

.dm-mobile__nav {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.dm-mobile__nav .dm-nav__link {
  padding: 12px 14px;
  justify-content: space-between;
}

.dm-currency-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
}

/* --- promo strip -------------------------------------------------------- */
/* A neutral bar, darker than the page, sitting above the header like a
   system status line. No tint: the band stays black so the only colour on
   it is the information that matters - the bolt, the code and the clock.
   A very faint white sheen crosses it so it still reads as live. */

.dm-promo {
  position: relative;
  z-index: 45;
  overflow: hidden;
  background: color-mix(in srgb, #000 55%, var(--dm-bg));
  border-bottom: 1px solid var(--dm-edge);
  font-size: 0.8125rem;
}

.dm-promo::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    100deg,
    transparent 40%,
    rgb(255 255 255 / 4%) 50%,
    transparent 60%
  );
  transform: translateX(-100%);
  animation: dm-sheen 9s var(--dm-ease) infinite;
}

@keyframes dm-sheen {
  0%, 58% { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

.dm-promo__inner {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px 18px;
  min-height: 44px;
  padding-block: 8px;
}

.dm-promo__msg {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: -0.012em;
  color: var(--dm-ink);
}

/* The bolt gets a badge of its own, so the eye lands on the strip before it
   reads the sentence. It is the only filled accent on the bar. */
.dm-promo__msg i {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  flex: none;
  border-radius: 6px;
  background: var(--dm-accent);
  color: var(--dm-on-accent);
  font-size: 0.625rem;
}

.dm-code {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 11px;
  border: 1px dashed color-mix(in srgb, var(--dm-accent) 50%, transparent);
  border-radius: 7px;
  background: color-mix(in srgb, var(--dm-accent) 10%, transparent);
  color: var(--dm-accent);
  font-family: var(--dm-mono);
  font-size: 0.7188rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transition: background 0.18s var(--dm-ease), color 0.18s var(--dm-ease),
    border-color 0.18s var(--dm-ease);
}

.dm-code:hover {
  background: var(--dm-accent);
  border-color: var(--dm-accent);
  color: var(--dm-on-accent);
}

.dm-code i {
  font-size: 0.6875rem;
  opacity: 0.75;
}

.dm-count {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--dm-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: var(--dm-faint);
}

.dm-count b {
  min-width: 25px;
  padding: 4px 6px;
  border-radius: 6px;
  background: rgb(255 255 255 / 5%);
  border: 1px solid var(--dm-edge);
  color: var(--dm-ink);
  font-weight: 700;
  text-align: center;
}

@media (max-width: 640px) {
  .dm-promo__inner {
    gap: 8px 12px;
  }

  .dm-promo__msg {
    font-size: 0.75rem;
  }
}

/* --- hero --------------------------------------------------------------- */
/* The claim leads: announcement, headline, sentence, actions, then the
   artwork as a full-bleed showcase that fades out into the section below. */

.dm-hero {
  position: relative;
  display: flex;
  align-items: center;
  overflow: hidden;
  padding-block: 52px;
  /* Fill what is left of the viewport once the promo strip, the header and
     the purchase bar have taken their share, so the claim sits on the
     optical centre of the first screen. */
  min-height: calc(100svh - var(--dm-header) - var(--dm-bar) - 52px);
}

@media (min-width: 1024px) {
  .dm-hero {
    padding-block: 72px;
  }
}

.dm-hero__center {
  width: 100%;
}

/* --- scene backdrop ------------------------------------------------------ */

.dm-hero__scene {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: -1;
  display: flex;
  justify-content: center;
  pointer-events: none;
  overflow: hidden;
}

.dm-hero__scene img {
  width: 100%;
  min-width: 1180px;
  height: auto;
  opacity: 0.16;
  /* Masked at both ends: the artwork has a hard horizon and a straight top
     edge, and neither should ever be visible as a line across the page. */
  mask-image: linear-gradient(180deg, transparent, #000 30%, #000 86%, transparent);
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 30%, #000 86%, transparent);
}

@media (max-width: 700px) {
  .dm-hero__scene img {
    opacity: 0.1;
  }
}

/* The bloom reaches up behind the transparent header, so the colour behind
   the wordmark belongs to the hero rather than to a bar of its own. */
.dm-hero .dm-bloom {
  inset: calc(var(--dm-header) * -1) 0 0;
}

.dm-hero__center {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 24px;
}

/* --- announcement ------------------------------------------------------- */

.dm-hero__pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 6px 6px 6px 14px;
  border: 1px solid var(--dm-edge);
  border-radius: 999px;
  background: var(--dm-surface-1);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: -0.006em;
  color: var(--dm-dim);
  transition: border-color 0.2s var(--dm-ease), color 0.2s var(--dm-ease);
}

.dm-hero__pill:hover {
  border-color: var(--dm-edge-2);
  color: var(--dm-ink);
}

/* A slow pulse instead of an icon: it reads as a live feed, and it is the
   only motion above the fold. */
.dm-hero__pip {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--dm-accent);
  flex: none;
  animation: dm-pip 2.4s var(--dm-ease) infinite;
}

@keyframes dm-pip {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

.dm-hero__pill b {
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--dm-accent);
  color: var(--dm-on-accent);
  font-family: var(--dm-mono);
  font-size: 0.6563rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* --- headline ----------------------------------------------------------- */

.dm-hero__title {
  max-width: 16ch;
  margin-top: 2px;
}

.dm-hero__title .dm-line {
  display: block;
}

.dm-hero__lead {
  max-width: 56ch;
  color: var(--dm-dim);
}

.dm-hero__cta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-top: 4px;
}

.dm-hero__frameworks {
  color: var(--dm-faint);
  font-size: 0.6563rem;
  letter-spacing: 0.2em;
  margin-top: 2px;
}

/* --- inner page header -------------------------------------------------- */
/* Inner pages carry the same bloom as the home hero, at a fraction of the
   strength, so the transparent header always has something behind it. */

.dm-pagehead {
  position: relative;
  overflow: hidden;
}

.dm-bloom--head {
  inset: calc(var(--dm-header) * -1) 0 0;
}

.dm-bloom--head::before {
  top: -560px;
  width: min(1280px, 150%);
  background: radial-gradient(
    closest-side,
    color-mix(in srgb, var(--dm-accent) 10%, transparent),
    transparent 68%
  );
}

/* --- featured reel ------------------------------------------------------- */
/* A carousel of the packages the store marked as featured. Cards keep their
   own design; the reel only handles the track, the peek at the right edge and
   the two controls sitting in the section header. */

/* The track runs the full width of the page rather than sitting inside the
   shell, so the reel reads as a moving band rather than a boxed row. The
   gutter stays small on purpose: matching it to the shell would just put the
   row back in the box it was in. */
.dm-reel-bleed {
  width: 100%;
  /* Slightly wider than the shell so the reel reads as its own band, but
     still centred - running it to the viewport edge sized the cards against
     the whole page and blew them up on a wide monitor. */
  max-width: 1440px;
  margin-inline: auto;
  padding-inline: 20px;
}

.dm-reel {
  /* Must clip: with loop enabled Swiper parks a duplicate slide to the left of
     the start position, and overflow:visible let it spill across the page. */
  overflow: hidden;
  /* Fade both ends. Only the right was masked before, so cards entering on the
     left appeared with a hard cut while the right side dissolved - the two
     edges of the same moving band behaving differently. */
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent,
    #000 4%,
    #000 96%,
    transparent
  );
  mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
}

.dm-reel .swiper-wrapper {
  align-items: stretch;
}

/* Linear easing is what turns Swiper's slide-to-slide animation into one
   unbroken drift. Without it every advance eases in and out, which reads as
   the stop-start stepping rather than continuous motion. */
.dm-reel--drift .swiper-wrapper {
  transition-timing-function: linear !important;
}

@media (prefers-reduced-motion: reduce) {
  .dm-reel--drift .swiper-wrapper {
    transition-timing-function: ease !important;
  }
}

/* The card keeps the width it was designed at whatever the viewport does;
   a wider screen shows more cards rather than bigger ones. */
.dm-reel .swiper-slide {
  width: clamp(260px, 76vw, 380px);
  height: auto;
  display: flex;
}

@media (min-width: 760px) {
  .dm-reel .swiper-slide {
    width: 380px;
  }
}

.dm-reel .swiper-slide > * {
  width: 100%;
}

/* --- controls ------------------------------------------------------------- */

.dm-reel__nav {
  display: flex;
  gap: 7px;
  flex: none;
}

.dm-reel__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: 1px solid var(--dm-edge);
  border-radius: 9px;
  background: var(--dm-surface-1);
  color: var(--dm-faint);
  font-size: 0.6875rem;
  cursor: pointer;
  transition: color 0.18s var(--dm-ease), border-color 0.18s var(--dm-ease),
    background 0.18s var(--dm-ease);
}

.dm-reel__btn:hover {
  color: var(--dm-ink);
  border-color: var(--dm-edge-2);
  background: var(--dm-surface-2);
}

.dm-reel__btn.swiper-button-disabled {
  opacity: 0.35;
  cursor: default;
}

.dm-reel__foot {
  display: flex;
  justify-content: center;
  margin-top: 26px;
}

.dm-reel__foot .dm-btn i {
  font-size: 0.6875rem;
  color: var(--dm-faint);
}

@media (max-width: 640px) {
  .dm-reel {
    -webkit-mask-image: none;
    mask-image: none;
  }

  .dm-reel-bleed {
    padding-inline: 16px;
  }

  .dm-reel__nav {
    display: none;
  }
}

/* --- product card ------------------------------------------------------- */
/* Artwork, name, one line of summary, framework chips, then price and action
   together on a foot row. Hover lifts the surface a step and brightens the
   edge; it does not glow. */

.dm-pkg {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--dm-edge);
  border-radius: var(--dm-radius);
  background: var(--dm-surface-1);
  overflow: hidden;
  transition: border-color 0.24s var(--dm-ease), transform 0.24s var(--dm-ease),
    background 0.24s var(--dm-ease);
}

.dm-pkg:hover {
  border-color: var(--dm-edge-2);
  background: var(--dm-surface-2);
  transform: translateY(-4px);
}

.dm-pkg__art {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--dm-surface-2);
  border-bottom: 1px solid var(--dm-edge);
  flex: none;
}

.dm-pkg__art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.7s var(--dm-ease);
}

.dm-pkg:hover .dm-pkg__art img {
  transform: scale(1.045);
}

/* The artwork runs bright at the bottom edge where the name sits under it,
   so a short scrim keeps the badge row and the card body distinct. */
.dm-pkg__art::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 45%;
  background: linear-gradient(180deg, transparent, rgb(0 0 0 / 45%));
  pointer-events: none;
}

.dm-pkg__tops {
  position: absolute;
  left: 12px;
  top: 12px;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  max-width: 70%;
}

.dm-pkg__body {
  display: flex;
  flex-direction: column;
  gap: 11px;
  padding: 18px 18px 20px;
  flex: 1;
  min-width: 0;
}

.dm-pkg__name {
  font-family: var(--dm-display);
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.3;
  /* Two lines, always. Titles in this catalogue run long, and letting the
     block reserve both lines keeps every card's price line on the same
     baseline across a row. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.6em;
}

.dm-pkg__name a {
  transition: color 0.18s var(--dm-ease);
}

.dm-pkg__name a:hover {
  color: var(--dm-accent);
}

.dm-pkg__blurb {
  color: var(--dm-faint);
  font-size: 0.8438rem;
  line-height: 1.6;
  letter-spacing: -0.008em;
}

.dm-pkg__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  min-height: 24px;
}

/* Framework chips carry a colour mark so a compatibility row reads as a list
   of distinct things rather than identical grey pills. The label keeps its
   real casing - QBCore, not QBCORE. */
.dm-pkg__chips .dm-chip {
  padding: 5px 10px 5px 7px;
  border-color: transparent;
  background: var(--dm-glass-light);
  color: var(--dm-dim);
  font-size: 0.6875rem;
  letter-spacing: 0;
  text-transform: none;
}

.dm-chip--fw {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* --fw is set inline per framework by frameworkChipHTML */
.dm-chip__dot {
  width: 11px;
  height: 11px;
  flex: none;
  border-radius: 3px;
  background: var(--fw, var(--dm-accent));
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 12%);
}

.dm-chip__logo {
  width: 17px;
  height: 17px;
  flex: none;
  object-fit: contain;
}

/* Wordmarks get a box matching their own proportions. Squeezing a 3:1 mark
   into a square leaves it a few pixels tall and unreadable. */
.dm-chip__logo--wide {
  width: 40px;
  height: 15px;
}

.dm-chip--lg {
  padding: 6px 11px 6px 8px;
  font-size: 0.8125rem;
}

.dm-chip--lg .dm-chip__dot,
.dm-chip--lg .dm-chip__logo {
  width: 20px;
  height: 20px;
}

.dm-chip--lg .dm-chip__logo--wide {
  width: 48px;
  height: 18px;
}

.dm-pkg:hover .dm-pkg__chips .dm-chip {
  color: var(--dm-ink);
}

/* --- card foot ----------------------------------------------------------- */

.dm-pkg__foot {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: auto;
  padding-top: 15px;
  border-top: 1px solid var(--dm-edge);
}

.dm-pkg__price {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 9px;
  min-width: 0;
}

.dm-pkg__price .dm-price {
  font-size: 1.375rem;
  letter-spacing: -0.04em;
}

.dm-pkg__price .dm-tag--sale {
  margin-left: 1px;
}

.dm-pkg__actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* --- browse: filter pills + search -------------------------------------- */
/* Filters and search sit on one row above a hairline, so the grid starts as
   high on the page as it can and the toolbar reads as a single control. */

.dm-browse {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding-bottom: 18px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--dm-edge);
}

.dm-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  flex: 1;
  min-width: 0;
}

.dm-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 15px;
  border: 1px solid var(--dm-edge);
  border-radius: 999px;
  background: var(--dm-surface-1);
  color: var(--dm-dim);
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: -0.012em;
  transition: background 0.16s var(--dm-ease), color 0.16s var(--dm-ease),
    border-color 0.16s var(--dm-ease);
}

.dm-pill:hover {
  color: var(--dm-ink);
  background: var(--dm-surface-2);
  border-color: var(--dm-edge-2);
}

.dm-pill.is-active {
  background: var(--dm-accent);
  border-color: transparent;
  color: var(--dm-on-accent);
}

/* Filter pills carry the same framework marks as the product chips. The mark
   sits on a dark plate when the pill is active, because the logos are drawn
   for a dark surface and the active pill is lime. */
.dm-pill--fw {
  padding-left: 11px;
}

.dm-pill .dm-chip__logo {
  width: 19px;
  height: 19px;
}

.dm-pill .dm-chip__logo--wide {
  width: 44px;
  height: 17px;
}

.dm-pill .dm-chip__dot {
  width: 12px;
  height: 12px;
}

.dm-pill.is-active .dm-chip__logo {
  background: rgb(0 0 0 / 82%);
  padding: 2px 4px;
  border-radius: 5px;
  box-sizing: content-box;
}

.dm-pill__count {
  font-family: var(--dm-mono);
  font-size: 0.6563rem;
  opacity: 0.65;
}

.dm-search {
  position: relative;
  width: 100%;
  max-width: 280px;
  flex: none;
}

@media (max-width: 700px) {
  .dm-search {
    max-width: none;
  }
}

.dm-search__icon {
  position: absolute;
  left: 14px;
  top: 50%;
  translate: 0 -50%;
  color: var(--dm-faint);
  pointer-events: none;
  display: inline-flex;
}

.dm-search__icon svg {
  width: 15px;
  height: 15px;
}

.dm-field {
  width: 100%;
  padding: 10px 14px;
  border: 1px solid var(--dm-edge);
  border-radius: 999px;
  background: var(--dm-surface-1);
  color: var(--dm-ink);
  font-size: 0.875rem;
  transition: border-color 0.18s var(--dm-ease), background 0.18s var(--dm-ease);
}

.dm-field--icon {
  padding-left: 40px;
}

.dm-field::placeholder {
  color: var(--dm-faint);
}

.dm-field:focus {
  border-color: var(--dm-edge-3);
  background: var(--dm-surface-2);
}

.dm-results__meta {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

/* --- product page ------------------------------------------------------- */

.dm-product {
  display: grid;
  gap: 20px;
  align-items: start;
}

.dm-product > * {
  min-width: 0;
}

@media (min-width: 1024px) {
  .dm-product {
    grid-template-columns: minmax(0, 1.5fr) minmax(330px, 1fr);
  }

  .dm-buy-panel {
    position: sticky;
    top: 94px;
  }
}

.dm-buy {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.dm-buy__price {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 11px;
}

.dm-buy__group {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-top: 18px;
  border-top: 1px solid var(--dm-edge);
}

/* Sections run the full width of the shell. The old layout put the label in a
   fixed 200px column beside the content, which cost ~230px of horizontal room
   on every section, squeezed the feature grid, and left a ragged empty gutter
   down the whole page. The label now sits above its content. */
.dm-detail {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding-top: 30px;
  margin-top: 30px;
  border-top: 1px solid var(--dm-edge);
}

/* --- section header ------------------------------------------------------ */

.dm-secthead {
  display: flex;
  align-items: center;
  gap: 11px;
  min-width: 0;
}

.dm-secthead i {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex: none;
  border: 1px solid var(--dm-accent-edge);
  border-radius: 8px;
  background: var(--dm-accent-soft);
  color: var(--dm-accent);
  font-size: 0.75rem;
}

.dm-secthead h2 {
  font-family: var(--dm-display);
  font-size: clamp(1.125rem, 1.7vw, 1.375rem);
  font-weight: 800;
  letter-spacing: -0.032em;
  line-height: 1.2;
}

/* --- product left column -------------------------------------------------- */

.dm-product__main {
  display: flex;
  flex-direction: column;
  gap: 24px;
  min-width: 0;
}

.dm-about {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.dm-includes {
  display: grid;
  gap: 9px;
}

@media (min-width: 640px) {
  .dm-includes {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.dm-include {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 15px;
  border: 1px solid var(--dm-edge);
  border-radius: 10px;
  background: var(--dm-glass-light);
  font-size: 0.875rem;
}

.dm-include i {
  color: var(--dm-accent);
  font-size: 0.8125rem;
}

/* --- optional feature sections ------------------------------------------ */
/* Built by main.js from the package description. Product features are a grid
   of small spec cards; visual features are wide rows pairing a screenshot
   with what it shows. Both inherit the page surface ladder, so neither
   carries a shadow. */

.dm-feats {
  display: grid;
  gap: 14px;
  grid-template-columns: 1fr;
}

@media (min-width: 640px) {
  .dm-feats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1100px) {
  .dm-feats {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.dm-feat {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 18px;
  border: 1px solid var(--dm-edge);
  border-radius: var(--dm-radius);
  background: var(--dm-surface-1);
  transition: border-color 0.2s var(--dm-ease), background 0.2s var(--dm-ease);
}

.dm-feat:hover {
  border-color: var(--dm-edge-2);
  background: var(--dm-surface-2);
}

.dm-feat__title {
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: var(--dm-display);
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: -0.022em;
  line-height: 1.3;
}

.dm-feat__title i {
  font-size: 0.8125rem;
  color: var(--dm-accent);
  flex: none;
}

.dm-feat__list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Bullets are drawn rather than inherited, so the marker colour and its
   alignment with the first line are both under our control. */
.dm-feat__list li,
.dm-vis__list li {
  position: relative;
  padding-left: 15px;
  color: var(--dm-faint);
  font-size: 0.8125rem;
  line-height: 1.6;
  letter-spacing: -0.008em;
}

.dm-feat__list li::before,
.dm-vis__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--dm-accent);
}

.dm-feat__text {
  color: var(--dm-faint);
  font-size: 0.8125rem;
  line-height: 1.6;
}

/* --- visual features ----------------------------------------------------- */

.dm-viss {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.dm-vis {
  display: grid;
  gap: 20px;
  /* Stretch, not centre: with a fixed 16:9 shot the image dictated the row
     height, so a row with two short bullets left the text floating in a
     column of dead space. Now the text sets the height and the shot fills
     whatever that turns out to be. */
  align-items: stretch;
  padding: 20px;
  border: 1px solid var(--dm-edge);
  border-radius: var(--dm-radius);
  background: var(--dm-surface-1);
  grid-template-columns: 1fr;
}

@media (min-width: 900px) {
  .dm-vis {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
    padding: 24px;
    gap: 28px;
  }

  /* Alternate the shot side down the stack so a long list of rows does not
     read as the same slab repeated. */
  .dm-vis:nth-child(even) .dm-vis__body {
    order: 2;
  }
}

.dm-vis--noshot {
  grid-template-columns: 1fr;
}

.dm-vis__body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 10px;
  min-width: 0;
  padding-block: 4px;
}

/* Icon plate on a visual row. Larger than the one on a feature card because
   it sits against a display-size heading rather than a 15px one. */
.dm-vis__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex: none;
  border: 1px solid var(--dm-accent-edge);
  border-radius: 11px;
  background: var(--dm-accent-soft);
  color: var(--dm-accent);
  font-size: 0.9375rem;
}

.dm-vis__title {
  font-family: var(--dm-display);
  font-size: clamp(1.25rem, 2vw, 1.6rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.1;
}

.dm-vis__text {
  color: var(--dm-dim);
  font-size: 0.9063rem;
  line-height: 1.65;
  letter-spacing: -0.01em;
}

.dm-vis__list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.dm-vis__list li {
  font-size: 0.8438rem;
}

.dm-vis__shot {
  border: 1px solid var(--dm-edge);
  border-radius: var(--dm-radius-sm);
  overflow: hidden;
  background: var(--dm-surface-2);
  min-width: 0;
  /* Absolute-positioned image, so its intrinsic height contributes nothing to
     layout. Left in flow, a 16:9 source stretched the row to its own height
     and reopened the dead space beside short text. The row is now as tall as
     the text, or this floor, whichever is greater. */
  position: relative;
  min-height: 215px;
}

.dm-vis__shot img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Stacked on narrow screens, where there is no second column to match. */
@media (max-width: 899px) {
  .dm-vis__shot {
    position: static;
    min-height: 0;
  }

  .dm-vis__shot img {
    position: static;
    height: auto;
    aspect-ratio: 16 / 9;
  }
}

/* --- gallery ------------------------------------------------------------ */

.dm-gallery {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.dm-gallery__main {
  max-width: 100%;
  border: 1px solid var(--dm-edge);
  border-radius: var(--dm-radius);
  overflow: hidden;
  aspect-ratio: 16 / 9;
  background: var(--dm-glass-light);
}

.packageMainSwiper,
.packageThumbsSwiper {
  width: 100%;
  max-width: 100%;
  overflow: hidden;
}

.dm-gallery .swiper-slide {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--dm-glass-light);
}

.packageMainSwiper .swiper-slide img,
.packageMainSwiper .swiper-slide iframe {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: 0;
}

.packageThumbsSwiper .swiper-slide {
  opacity: 0.45;
  cursor: pointer;
  border: 1px solid var(--dm-edge);
  border-radius: 10px;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  transition: opacity 0.2s var(--dm-ease), border-color 0.2s var(--dm-ease);
}

.packageThumbsSwiper .swiper-slide:hover {
  opacity: 0.8;
}

.packageThumbsSwiper .swiper-slide-thumb-active {
  opacity: 1 !important;
  border-color: var(--dm-accent) !important;
}

.swiper-button-next,
.swiper-button-prev {
  width: 40px !important;
  height: 40px !important;
  border-radius: 10px !important;
  border: 1px solid var(--dm-edge);
  background: var(--dm-glass-strong) !important;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  color: var(--dm-ink) !important;
}

.swiper-button-next:hover,
.swiper-button-prev:hover {
  background: var(--dm-accent) !important;
  color: var(--dm-on-accent) !important;
}

.swiper-button-next::after,
.swiper-button-prev::after {
  font-size: 13px !important;
  font-weight: 700;
}

/* --- category tiles ----------------------------------------------------- */
/* Large, quiet tiles. The count sits above the name so the eye reads scale
   first, and the accent appears only on the outbound link. */

.dm-cats {
  display: grid;
  gap: var(--dm-gap);
}

@media (min-width: 860px) {
  .dm-cats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.dm-cat {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 30px;
  border: 1px solid var(--dm-edge);
  border-radius: var(--dm-radius);
  background: var(--dm-surface-1);
  overflow: hidden;
  transition: border-color 0.22s var(--dm-ease), background 0.22s var(--dm-ease),
    transform 0.22s var(--dm-ease);
}

.dm-cat:hover {
  border-color: var(--dm-edge-2);
  background: var(--dm-surface-2);
  transform: translateY(-3px);
}

/* A single accent hairline that draws itself across the top on hover. It
   replaces the glow these tiles would otherwise ask for. */
.dm-cat::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 1px;
  background: linear-gradient(90deg, var(--dm-accent), transparent 70%);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.4s var(--dm-ease);
}

.dm-cat:hover::before {
  transform: scaleX(1);
}

.dm-cat__name {
  font-family: var(--dm-display);
  font-size: clamp(1.5rem, 2.3vw, 2rem);
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1.05;
}

/* Category descriptions come from the store as HTML, normally a single
   <p>. Tebex Twig has no striptags filter, so the markup renders as-is and
   is flattened here to sit inline in the card. */
.dm-cat__desc {
  display: block;
  max-width: 46ch;
  font-size: 0.9375rem;
  line-height: 1.65;
}

.dm-cat__desc p {
  margin: 0 0 0.5em;
}

.dm-cat__desc > :last-child {
  margin-bottom: 0;
}

.dm-cat__go {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-top: auto;
  padding-top: 18px;
  color: var(--dm-accent);
  font-size: 0.8438rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.dm-cat__go i {
  font-size: 0.6875rem;
  transition: transform 0.22s var(--dm-ease);
}

.dm-cat:hover .dm-cat__go i {
  transform: translateX(4px);
}

/* --- why-buy-here grid & reviews ----------------------------------------- */
/* Four panels, two up. The icon sits inline with the title so the claim reads
   as one line, and two of the four carry an accent wash so the block has a
   diagonal rather than four identical boxes. */

.dm-features {
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr;
}

@media (min-width: 800px) {
  .dm-features {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
  }
}

.dm-feature {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 24px;
  border: 1px solid var(--dm-edge);
  border-radius: var(--dm-radius);
  background: var(--dm-surface-1);
  overflow: hidden;
  transition: border-color 0.22s var(--dm-ease), background 0.22s var(--dm-ease);
}

.dm-feature:hover {
  border-color: var(--dm-edge-2);
  background: var(--dm-surface-2);
}

/* The wash is a corner bloom rather than a flat tint, so the accent reads as
   light falling on the panel instead of a coloured rectangle. */
.dm-feature--accent::before {
  content: "";
  position: absolute;
  inset: -40% 40% 40% -20%;
  background: radial-gradient(
    closest-side,
    color-mix(in srgb, var(--dm-accent) 13%, transparent),
    transparent 70%
  );
  pointer-events: none;
}

.dm-feature--accent {
  border-color: var(--dm-accent-edge);
}

.dm-feature--accent .dm-feature__title {
  color: var(--dm-accent);
}

.dm-feature__head {
  display: flex;
  align-items: center;
  gap: 13px;
  position: relative;
}

.dm-feature__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex: none;
  border: 1px solid var(--dm-accent-edge);
  border-radius: 11px;
  background: var(--dm-accent-soft);
  color: var(--dm-accent);
  font-size: 0.9375rem;
}

.dm-feature__title {
  font-family: var(--dm-display);
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.3;
}

.dm-feature__text {
  position: relative;
  color: var(--dm-faint);
  font-size: 0.875rem;
  line-height: 1.65;
  letter-spacing: -0.008em;
}

.dm-feature__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: auto;
  padding-top: 4px;
  color: var(--dm-ink);
  font-size: 0.8438rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  transition: color 0.16s var(--dm-ease);
}

.dm-feature__link i {
  font-size: 0.6875rem;
  color: var(--dm-accent);
  transition: transform 0.18s var(--dm-ease);
}

.dm-feature__link:hover {
  color: var(--dm-accent);
}

.dm-feature__link:hover i {
  transform: translate(2px, -2px);
}

.dm-review {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 26px;
  border: 1px solid var(--dm-edge);
  border-radius: var(--dm-radius);
  background: var(--dm-surface-1);
  transition: border-color 0.22s var(--dm-ease), background 0.22s var(--dm-ease);
}

.dm-review:hover {
  border-color: var(--dm-edge-2);
  background: var(--dm-surface-2);
}

.dm-review__quote {
  font-size: 0.9375rem;
  line-height: 1.7;
  letter-spacing: -0.01em;
  color: var(--dm-dim);
}

.dm-review__foot {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid var(--dm-edge);
}

.dm-review__avatar {
  width: 36px;
  height: 36px;
  border-radius: 999px;
  object-fit: cover;
  flex: none;
}

.dm-stars {
  display: inline-flex;
  gap: 3px;
  color: var(--dm-accent);
}

.dm-stars svg {
  width: 14px;
  height: 14px;
}

/* --- fixed purchase bar ------------------------------------------------- */
/* Full bleed, edge to edge. This bar is chrome rather than content, so it is
   deliberately not held to the content shell: holding it to 1240px left two
   dead margins and made it look like a component that had come loose. The
   label is a fixed segment on the left with its own hairline, and the feed
   runs the entire remaining width. */

.recent-payments {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  height: var(--dm-bar);
  display: flex;
  align-items: center;
  border-top: 1px solid var(--dm-edge);
  background: color-mix(in srgb, var(--dm-bg) 86%, transparent);
  backdrop-filter: blur(var(--dm-blur-lg)) saturate(150%);
  -webkit-backdrop-filter: blur(var(--dm-blur-lg)) saturate(150%);
}

.dm-ticker-bar {
  display: flex;
  align-items: center;
  width: 100%;
  height: var(--dm-bar);
}

/* The label anchors the left edge: its own segment, its own hairline, so the
   feed appears to run out from behind it. */
.dm-live {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  flex: none;
  height: 100%;
  padding-inline: 20px;
  border-right: 1px solid var(--dm-edge);
  background: rgb(255 255 255 / 2.5%);
}

.dm-live .dm-eyebrow {
  color: var(--dm-dim);
  font-size: 0.625rem;
  letter-spacing: 0.18em;
}

.dm-live__dot {
  position: relative;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--dm-accent);
  flex: none;
}

/* A single expanding ring, the way a live indicator should read. */
.dm-live__dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--dm-accent);
  animation: dm-ping 2.6s var(--dm-ease) infinite;
}

@keyframes dm-ping {
  0% { transform: scale(1); opacity: 0.6; }
  70%, 100% { transform: scale(2.8); opacity: 0; }
}

.dm-ticker {
  position: relative;
  flex: 1;
  min-width: 0;
  height: 100%;
  display: flex;
  align-items: center;
  overflow: hidden;
  mask-image: linear-gradient(90deg, #000 0%, #000 94%, transparent);
  -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 94%, transparent);
}

.dm-ticker__track {
  display: flex;
  align-items: center;
  gap: 0;
  width: max-content;
  animation: dm-marquee 64s linear infinite;
}

.dm-ticker:hover .dm-ticker__track {
  animation-play-state: paused;
}

@keyframes dm-marquee {
  to { transform: translateX(-50%); }
}

/* Each sale is its own cell divided by a hairline, so a long feed reads as
   a list of transactions instead of one run-on sentence. */
.dm-ticker__item {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  flex: none;
  white-space: nowrap;
  padding-inline: 22px;
  font-size: 0.8125rem;
  color: var(--dm-faint);
  border-right: 1px solid var(--dm-edge);
}

.dm-ticker__avatar {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  object-fit: cover;
  flex: none;
  border: 1px solid var(--dm-edge);
}

.dm-ticker__who {
  font-weight: 600;
  color: var(--dm-ink);
  letter-spacing: -0.012em;
}

.dm-ticker__price {
  font-family: var(--dm-mono);
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--dm-accent);
}

@media (max-width: 640px) {
  .dm-live {
    padding-inline: 14px;
  }

  .dm-live .dm-eyebrow {
    display: none;
  }

  .dm-ticker__item {
    padding-inline: 16px;
  }
}

/* --- basket drawer ------------------------------------------------------ */

.dm-drawer {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: none;
  background: rgb(0 0 0 / 55%);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.dm-drawer__panel {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: min(520px, 100%);
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 22px;
  background: color-mix(in srgb, var(--dm-base) 82%, transparent);
  backdrop-filter: blur(var(--dm-blur-lg)) saturate(140%);
  -webkit-backdrop-filter: blur(var(--dm-blur-lg)) saturate(140%);
  border-left: 1px solid var(--dm-edge);
}

.dm-drawer__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex: none;
}

.dm-drawer__body {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.dm-basket-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
  overflow-y: auto;
  padding-right: 4px;
}

.dm-line-item {
  position: relative;
  display: flex;
  gap: 13px;
  padding: 10px;
  border: 1px solid var(--dm-edge);
  border-radius: 12px;
  background: var(--dm-glass-light);
  transition: border-color 0.18s var(--dm-ease), background 0.18s var(--dm-ease);
}

.dm-line-item:hover {
  border-color: var(--dm-edge-2);
  background: var(--dm-glass-lighter);
}

.dm-line-item__art {
  width: 104px;
  height: 68px;
  flex: none;
  object-fit: cover;
  border-radius: 8px;
  background: var(--dm-glass-light);
}

.dm-line-item__body {
  display: flex;
  flex-direction: column;
  gap: 7px;
  flex: 1;
  min-width: 0;
  padding-right: 42px;
}

.dm-line-item__name {
  font-family: var(--dm-display);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.dm-line-item__del {
  position: absolute;
  right: 10px;
  bottom: 10px;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: color-mix(in srgb, var(--dm-sale) 16%, transparent);
  color: var(--dm-sale);
  transition: background 0.18s var(--dm-ease);
}

.dm-line-item__del:hover {
  background: color-mix(in srgb, var(--dm-sale) 28%, transparent);
}

.dm-summary {
  display: flex;
  flex-direction: column;
  gap: 14px;
  flex: none;
  padding-top: 16px;
  border-top: 1px solid var(--dm-edge);
}

.dm-summary__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.dm-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  height: 100%;
  text-align: center;
  padding: 24px;
}

/* --- modal -------------------------------------------------------------- */

.dm-modal {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: none;
  background: rgb(0 0 0 / 55%);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

/* positioned rather than flex-centred: jQuery fadeIn sets display:block */
.dm-modal__card {
  position: absolute;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
  width: min(410px, calc(100% - 40px));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 17px;
  padding: 30px;
  text-align: center;
  border: 1px solid var(--dm-edge);
  border-radius: 18px;
  background: color-mix(in srgb, var(--dm-base) 86%, transparent);
  backdrop-filter: blur(var(--dm-blur-lg)) saturate(140%);
  -webkit-backdrop-filter: blur(var(--dm-blur-lg)) saturate(140%);
}

/* --- footer ------------------------------------------------------------- */
/* Two rows and nothing else: identity above, legal below. The link columns
   were removed because they only repeated the header, which made the footer
   the tallest band on the page for no gain. */

.dm-footer {
  border-top: 1px solid var(--dm-edge);
  background: color-mix(in srgb, #000 30%, var(--dm-bg));
}

.dm-footer__top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 28px;
  flex-wrap: wrap;
  padding-block: 34px;
}

.dm-footer__id {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}

.dm-footer__note {
  color: var(--dm-faint);
  font-size: 0.875rem;
  line-height: 1.6;
  letter-spacing: -0.008em;
  max-width: 46ch;
}

.dm-footer__mail {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  align-self: flex-start;
  color: var(--dm-dim);
  font-size: 0.8438rem;
  font-weight: 500;
  transition: color 0.16s var(--dm-ease);
}

.dm-footer__mail i {
  font-size: 0.8125rem;
  color: var(--dm-accent);
}

.dm-footer__mail:hover {
  color: var(--dm-ink);
}

.dm-socials {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  flex: none;
}

.dm-social {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--dm-edge);
  border-radius: var(--dm-radius-xs);
  background: var(--dm-surface-1);
  color: var(--dm-faint);
  font-size: 0.875rem;
  transition: color 0.18s var(--dm-ease), border-color 0.18s var(--dm-ease),
    background 0.18s var(--dm-ease);
}

.dm-social:hover {
  color: var(--dm-accent);
  border-color: var(--dm-accent-edge);
  background: var(--dm-accent-soft);
}

.dm-footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  padding-block: 16px;
  border-top: 1px solid var(--dm-edge);
}

.dm-footer__legal {
  font-size: 0.6563rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dm-faint);
}

.dm-pays {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
  margin-left: auto;
}

.dm-pay {
  height: 24px;
  border-radius: 5px;
  border: 1px solid var(--dm-edge);
  object-fit: cover;
  opacity: 0.85;
  transition: opacity 0.18s var(--dm-ease);
}

.dm-pays:hover .dm-pay {
  opacity: 1;
}

.dm-pay--plain {
  border: 0;
}

@media (max-width: 640px) {
  .dm-footer__top {
    padding-block: 28px;
    gap: 20px;
  }

  .dm-pays {
    margin-left: 0;
  }
}

/* --- CMS pages ----------------------------------------------------------- */
/* One 78ch panel left the right half of these pages empty and turned long
   copy into a wall. Documents now run beside a sticky contents rail, and
   FAQ pages become an accordion across the full width. */

.dm-cms__head {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-bottom: 34px;
}

.dm-cms {
  display: grid;
  gap: 28px;
  align-items: start;
}

@media (min-width: 940px) {
  .dm-cms--doc {
    grid-template-columns: 220px minmax(0, 1fr);
    gap: 48px;
  }
}

.dm-cms--plain {
  grid-template-columns: minmax(0, 1fr) !important;
}

.dm-cms__body {
  min-width: 0;
  max-width: 80ch;
}

.dm-cms--faq .dm-cms__body {
  max-width: none;
}

/* --- contents rail -------------------------------------------------------- */

.dm-toc {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

@media (min-width: 940px) {
  .dm-toc {
    position: sticky;
    top: 96px;
  }
}

.dm-toc__list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  border-left: 1px solid var(--dm-edge);
}

.dm-toc__link {
  position: relative;
  padding: 7px 0 7px 14px;
  color: var(--dm-faint);
  font-size: 0.8438rem;
  line-height: 1.45;
  letter-spacing: -0.01em;
  transition: color 0.18s var(--dm-ease);
}

.dm-toc__link::before {
  content: "";
  position: absolute;
  left: -1px;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--dm-accent);
  opacity: 0;
  transition: opacity 0.2s var(--dm-ease);
}

.dm-toc__link:hover {
  color: var(--dm-dim);
}

.dm-toc__link.is-active {
  color: var(--dm-ink);
  font-weight: 600;
}

.dm-toc__link.is-active::before {
  opacity: 1;
}

/* --- FAQ accordion -------------------------------------------------------- */

.dm-qas {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.dm-qa {
  border: 1px solid var(--dm-edge);
  border-radius: var(--dm-radius);
  background: var(--dm-surface-1);
  overflow: hidden;
  transition: border-color 0.2s var(--dm-ease), background 0.2s var(--dm-ease);
}

.dm-qa:hover {
  border-color: var(--dm-edge-2);
}

.dm-qa[open] {
  background: var(--dm-surface-2);
  border-color: var(--dm-edge-2);
}

.dm-qa__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 18px 20px;
  cursor: pointer;
  list-style: none;
  font-family: var(--dm-display);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.024em;
  line-height: 1.35;
  color: var(--dm-ink);
}

/* the default disclosure triangle, in every engine */
.dm-qa__q::-webkit-details-marker { display: none; }
.dm-qa__q::marker { content: ""; }

.dm-qa__q i {
  flex: none;
  font-size: 0.75rem;
  color: var(--dm-faint);
  transition: transform 0.25s var(--dm-ease), color 0.2s var(--dm-ease);
}

.dm-qa[open] .dm-qa__q i {
  transform: rotate(180deg);
  color: var(--dm-accent);
}

.dm-qa__a {
  padding: 0 20px 20px;
  max-width: 80ch;
}

.dm-qa__a > *:first-child {
  margin-top: 0;
}

@media (min-width: 940px) {
  .dm-qa__q {
    padding: 20px 24px;
    font-size: 1.0625rem;
  }

  .dm-qa__a {
    padding: 0 24px 22px;
  }
}

/* --- long-form content -------------------------------------------------- */

.package-description,
.dm-prose {
  color: var(--dm-dim);
  font-size: 0.9375rem;
  line-height: 1.75;
}

.package-description > * + *,
.dm-prose > * + * {
  margin-top: 0.9rem;
}

.package-description h1,
.package-description h2,
.package-description h3,
.package-description h4,
.dm-prose h1,
.dm-prose h2,
.dm-prose h3,
.dm-prose h4 {
  font-family: var(--dm-display);
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--dm-ink);
  margin-top: 1.6rem;
  margin-bottom: 0.6rem;
}

.package-description h1, .dm-prose h1 { font-size: 1.5rem; }
.package-description h2, .dm-prose h2 { font-size: 1.25rem; }
.package-description h3, .dm-prose h3 { font-size: 1.0625rem; }

.package-description a,
.dm-prose a {
  color: var(--dm-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.package-description strong,
.package-description b,
.dm-prose strong,
.dm-prose b {
  color: var(--dm-ink);
  font-weight: 650;
}

.package-description ul li,
.package-description ol li,
.dm-prose ul li,
.dm-prose ol li {
  position: relative;
  padding-left: 1.9ch;
  margin-bottom: 0.35rem;
}

.package-description ul li::before,
.dm-prose ul li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.68rem;
  width: 6px;
  height: 6px;
  border-radius: 2px;
  background: var(--dm-accent);
}

.package-description ol,
.dm-prose ol {
  counter-reset: dm-ol;
}

.package-description ol li,
.dm-prose ol li {
  counter-increment: dm-ol;
}

.package-description ol li::before,
.dm-prose ol li::before {
  content: counter(dm-ol) ".";
  position: absolute;
  left: 0;
  font-family: var(--dm-mono);
  font-size: 0.8125rem;
  color: var(--dm-accent);
}

.package-description img,
.dm-prose img {
  border-radius: 10px;
  margin-block: 1rem;
}

.package-description iframe,
.dm-prose iframe {
  aspect-ratio: 16 / 9;
  width: 100%;
  height: auto;
  border: 0;
  border-radius: 10px;
}

.package-description hr,
.dm-prose hr {
  border: 0;
  border-top: 1px solid var(--dm-edge);
  margin-block: 1.4rem;
}

/* --- hooks required by assets/scripts/main.js --------------------------- */

.flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

.absolute-center {
  position: absolute;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
}

.scrollbar-hide {
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.scrollbar-hide::-webkit-scrollbar {
  display: none;
}

/* spinner while the basket loads */
.loading-data {
  width: 40px;
  padding: 6px;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--dm-accent);
  --_m: conic-gradient(#0000 10%, #000), linear-gradient(#000 0 0) content-box;
  -webkit-mask: var(--_m);
  mask: var(--_m);
  -webkit-mask-composite: source-out;
  mask-composite: subtract;
  animation: dm-spin 1s linear infinite;
}

/* spinner swapped into a button mid-request */
.btn-loading {
  width: 19px;
  height: 19px;
  border-radius: 50%;
  border: 2px solid rgb(0 0 0 / 25%);
  border-top-color: var(--dm-on-accent);
  animation: dm-spin 0.7s linear infinite;
}

.dm-btn--danger .btn-loading,
.dm-line-item__del .btn-loading {
  border-color: color-mix(in srgb, var(--dm-sale) 30%, transparent);
  border-top-color: var(--dm-sale);
}

@keyframes dm-spin {
  to { rotate: 1turn; }
}

/* toggled by main.js during add and remove */
.bg-primary {
  background: var(--dm-accent) !important;
}

.bg-delete {
  background: color-mix(in srgb, var(--dm-sale) 22%, transparent) !important;
}

.colored-toast {
  border: 1px solid var(--dm-edge) !important;
  border-radius: 12px !important;
  background: color-mix(in srgb, var(--dm-base) 88%, transparent) !important;
  backdrop-filter: blur(var(--dm-blur)) !important;
}

.colored-toast .swal2-title {
  color: var(--dm-ink) !important;
  font-family: var(--dm-display) !important;
  font-size: 0.9375rem !important;
}

.colored-toast .swal2-html-container {
  color: var(--dm-dim) !important;
  font-size: 0.8125rem !important;
}

.colored-toast .swal2-close {
  color: var(--dm-faint) !important;
}

.colored-toast .swal2-timer-progress-bar {
  background: var(--dm-accent) !important;
}

/* --- youtube reel -------------------------------------------------------- */
/* Video cards are product cards: same .dm-pkg shell, same .dm-reel track, same
   380px slide. Only three things are specific to a video - the play badge, the
   channel line under the title, and the fact that the whole card is a link. */

.dm-tube__card {
  display: flex;
  flex-direction: column;
  height: 100%;
}

/* The thumbnail box inherits .dm-pkg__art, which already supplies the 16:9
   ratio, the hairline under it and the zoom on hover. */
.dm-tube__shot {
  display: block;
}

/* Accent, not YouTube red: this band sits inside the store, and a second
   brand colour here would fight the page. */
.dm-tube__play {
  position: absolute;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--dm-base) 72%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--dm-edge-2);
  color: var(--dm-ink);
  font-size: 0.9375rem;
  padding-left: 3px;
  transition: background 0.22s var(--dm-ease), color 0.22s var(--dm-ease),
    border-color 0.22s var(--dm-ease), scale 0.22s var(--dm-ease);
}

.dm-tube__card:hover .dm-tube__play {
  background: var(--dm-accent);
  border-color: transparent;
  color: var(--dm-on-accent);
  scale: 1.06;
}

/* A video title runs far longer than a package name, so it takes the size of
   the card blurb while keeping the display face and the two-line clamp. */
.dm-tube__title {
  font-size: 1rem;
  transition: color 0.18s var(--dm-ease);
}

.dm-tube__card:hover .dm-tube__title {
  color: var(--dm-accent);
}

/* Stands in for the price row, so the card foot is not left empty. */
.dm-tube__meta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: auto;
  padding-top: 13px;
  border-top: 1px solid var(--dm-edge);
  color: var(--dm-faint);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.dm-tube__meta i {
  font-size: 0.9375rem;
  color: var(--dm-accent);
}

.dm-tube .dm-reel__foot .dm-btn i {
  color: var(--dm-accent);
}
