/* ============================================================================
   PREMIUM CAR CARDS
   wp-content/plugins/dubai-car-booking/assets/css/premium-cards.css

   SURFACE   [dcb_car_cards] / [dcb_hourly_car_cards] / [dcb_special_offers]
   REACH     40 pages, 45 placements — 32 display="grid", 13 slider, 0 list.
             Enqueued as dcb-premium-cards-style (FrontController::maybeEnqueue).
   VIEW      app/Views/premium-car-cards.php   (all markup is server-rendered)
   SCRIPT    assets/js/premium-cards.js        (no markup generated; see BEHAVIOUR)
   DIRECTION "Quiet instrument" — the car is the only picture and it is never
             dimmed; the price is the signature; lift is expressed as
             border-colour, never as movement.

   FROZEN NAMES (renaming any of these is a PHP or JS edit, not a CSS edit)
     roots/containers  .dcb-premium-cards  .dcb-premium-cards--grid|--slider|--list
                       .premium-car-slider-shell  .premium-car-carousel
                       .premium-car-card-grid  .premium-car-card-wrap
     card              .premium-car-card  __media __img __overlay __topbar
                       __price __price-main __price-old __price-suffix __price-desc
                       __body __deal __deal--body __deal-label __deal-badge
                       __deal-copy __header __title __brand __brand-logo
                       __brand-name __subtitle __specs __footer __cta __arrow
     badges/specs      .premium-badge  --availability  --year
                       .premium-spec  .premium-spec__icon  .premium-spec__text
     controls          .premium-car-slider-nav  --prev  --next
                       .dcb-premium-cards__load-more(-wrap)
                       .dcb-premium-cards__count  .dcb-premium-cards__empty
     state             .is-load-more-hidden  +  the bare [hidden] attribute
     custom property   --dcb-premium-columns  --dcb-premium-columns-current
                       --dcb-premium-gap

   TWO THINGS THAT WILL BITE THE NEXT EDITOR
   1. `font: 700 22px/1.2 inherit` IS INVALID CSS AND IS DROPPED WHOLE.
      A CSS-wide keyword may only be the entire value of a declaration, so
      `inherit` in the font-family slot of the `font` shorthand invalidates the
      whole thing — no size, no weight, no line-height. Verified in Chrome 152:
      an element with `font:700 22px/1.2 inherit` computes to 14px/400/normal
      and the CSSOM returns an empty string for it. Every type rule in this file
      is therefore written as longhands (font-weight / font-size / line-height)
      and deliberately sets NO font-family, so the Elementor kit font (Roboto,
      already loaded site-wide in 100-900) is inherited exactly as before.
   2. premium-cards.js:39 writes an inline `transform` on .premium-car-card on
      every mousemove. There is not one `transform` declaration in this file and
      there must never be one — not even `transform:none`. See BEHAVIOUR 5.
   ============================================================================ */


/* ============================================================================
   1. BEHAVIOUR
   Rules the JavaScript depends on. Changing anything in this block changes
   what the widget DOES, not how it looks. Every display declaration here is
   followed immediately by the guard for whatever else hides that element.
   ============================================================================ */

/* 1.1 — THE SLIDER COLUMN CONTRACT.  FROZEN.
   premium-cards.js:14
     parseInt(getComputedStyle(root).getPropertyValue('--dcb-premium-columns-current'), 10)
   read off the ROOT element, falling through to --dcb-premium-columns (which
   premium-car-cards.php:37 writes inline as `--dcb-premium-columns: 4`) and
   then to a literal 4. It feeds getMaxIndex() (js:74) and the autoslide gate
   (js:116), both inside setupSlider(), which returns at js:50 unless
   data-layout === "slider".
   It must stay: (a) on this element, (b) a plain integer, (c) stepped by
   viewport. auto-fit cannot replace it — `grid-auto-flow: column` has no
   auto-fit, and a non-integer makes parseInt return NaN, which falls through
   to 4 and disables the next arrow four slides early on a 375px phone.
   This is the ONLY viewport media query in this file and the only place the
   container-aware rule cannot apply. */
.dcb-premium-cards {
  --dcb-premium-columns: 4;
  --dcb-premium-columns-current: var(--dcb-premium-columns);
  --dcb-premium-gap: 12px;
}

@media (max-width: 1200px) {
  .dcb-premium-cards { --dcb-premium-columns-current: 3; }
}
@media (max-width: 900px) {
  .dcb-premium-cards { --dcb-premium-columns-current: 2; }
}
@media (max-width: 640px) {
  .dcb-premium-cards { --dcb-premium-columns-current: 1; }
}
/* Nothing else belongs in those three blocks. The old file also stepped the
   nav buttons 38 -> 34 -> 30px and the media box to 204px there; both are
   deleted — the arrows are now 44px at every width and the media box has no
   fixed height at all. */

/* 1.2 — THE LOAD-MORE BATCHING, WHICH IS CURRENTLY DEAD ON 32 GRID PAGES.
   premium-car-cards.php:117 stamps
     <div class="premium-car-card-wrap is-load-more-hidden" hidden>
   on every card past `initial_visible`, and premium-cards.js:210-211 reveals a
   batch by clearing BOTH — `card.hidden = false` AND
   `card.classList.remove('is-load-more-hidden')` — so BOTH have to be guarded.
   The old rule `.dcb-premium-cards .premium-car-card-wrap{display:flex}` is an
   author declaration at (0,2,0); `[hidden]{display:none}` lives in the
   USER-AGENT origin and loses to any author display value at any specificity.
   Measured on /car-rental-dubai/without-credit-card/ : 62 wraps in the DOM,
   50 carrying `hidden`, all 50 laid out. The guard below is the same (0,2,0)
   in later source order, which is enough — no !important, ever. */
.dcb-premium-cards .premium-car-card-wrap {
  display: flex;
  align-items: stretch;
  justify-content: stretch;
  min-width: 0;
  padding: 0;
}
.dcb-premium-cards .premium-car-card-wrap[hidden],
.dcb-premium-cards .premium-car-card-wrap.is-load-more-hidden {
  display: none;
}

/* 1.3 — THE LOAD-MORE BUTTON.
   premium-cards.js:215 sets `button.hidden = true` once getHiddenCards() is
   empty. The old file gave the button no display value, so the attribute
   happened to work; this one makes it inline-flex, so it needs the guard.
   Appearance is in section 3.12 — do not add a display there. */
.dcb-premium-cards .dcb-premium-cards__load-more {
  display: inline-flex;
}
.dcb-premium-cards .dcb-premium-cards__load-more[hidden] {
  display: none;
}
/* The WRAP is never hidden by anything — PHP omits it entirely when there is
   nothing to page through (premium-car-cards.php:225). Once the button inside
   it hides itself, the wrap is left as an empty flex box contributing 16px of
   dead margin, so it is folded away too. Progressive enhancement only: where
   :has() is unsupported the whole rule is dropped and the old 16px gap
   returns, which is exactly today's behaviour and harms nothing. */
.dcb-premium-cards .dcb-premium-cards__load-more-wrap:has(> .dcb-premium-cards__load-more[hidden]) {
  display: none;
}

/* 1.4 — THE SLIDER TRACK IS THE SCROLL PORT AND ITS GEOMETRY IS LOAD-BEARING.
   premium-cards.js:97 and :137 both compute `target.offsetLeft - track.offsetLeft`.
   That subtraction is correct only while the slide and the track resolve
   against the SAME offsetParent, i.e. while nothing BETWEEN them is positioned
   — and the track is the only thing between them.
     .premium-car-card-grid  MUST stay position:static, with no padding-left
                             and no border-left (offsetLeft includes both), and
                             MUST keep overflow-x:auto — js reads and writes
                             track.scrollLeft / track.scrollTo directly.
     .dcb-premium-cards, .premium-car-slider-shell and .premium-car-carousel
                             ARE free to position: they sit ABOVE both the
                             slide and the track, so they move both equally and
                             the difference is unchanged. (This build positions
                             none of them; the rule is recorded so the next
                             person does not over-constrain themselves.)
   padding-bottom on the track is safe. If side breathing room is ever needed,
   put padding-inline on .premium-car-carousel. */
.dcb-premium-cards .premium-car-card-grid {
  display: grid;
  gap: var(--dcb-premium-gap);
}
.dcb-premium-cards--slider .premium-car-card-grid {
  position: static;
  grid-auto-flow: column;
  grid-auto-columns: calc(
    (100% - (var(--dcb-premium-columns-current) - 1) * var(--dcb-premium-gap))
    / var(--dcb-premium-columns-current)
  );
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding-bottom: 2px;
}
.dcb-premium-cards--slider .premium-car-card-grid::-webkit-scrollbar {
  display: none;
}
.dcb-premium-cards--slider .premium-car-card-wrap {
  scroll-snap-align: start;
}

/* 1.5 — .premium-car-card CARRIES NO transform. EVER.
   premium-cards.js:23-46 (setupHoverTilt) writes card.style.transform on every
   mousemove. An inline style beats any author rule, and beating it back with
   !important is precisely the escalation that produced the .iti__hide failure.
   The old file's `transition: transform .35s` meant every mousemove frame
   started a fresh 350ms interpolation, so the tilt trailed the cursor by a
   third of a second. With no CSS transform and no transform in any transition
   list, the JS now tracks the pointer 1:1.
   The tilt is still invisible — no `perspective` exists anywhere in the plugin
   and overflow:hidden on the card forces transform-style:flat — so the right
   fix is to DELETE setupHoverTilt (js:23-46 and its call at :223). That is a
   JS change and is reported, not assumed. This file is correct either way. */

/* 1.6 — Self-sufficient box model. The 240px / 132px column maths below is
   border-box maths. Elementor supplies this site-wide today; declaring it on
   the widget root means the widget is still right if it ever stops. */
.dcb-premium-cards,
.dcb-premium-cards *,
.dcb-premium-cards *::before,
.dcb-premium-cards *::after {
  box-sizing: border-box;
}


/* ============================================================================
   2. TOKENS — declared on this widget's own root, never :root.
   This stylesheet loads on 40 pages it does not own; a :root block would leak
   these names into every one of them. The names are the ones this file already
   used, re-pointed at saadat-gulf-blue so no call site had to move.
   Contrast is stated where it is relied on, measured against the real ground.
   ============================================================================ */
.dcb-premium-cards {
  --text-main: #001E6B;   /* on --surface #FFFFFF = 15.0:1  */
  --text-soft: #42567A;   /* on --surface #FFFFFF =  7.4:1  */
  --accent:    #3CADD5;   /* the action / hover edge. Carries NAVY (5.8:1), never white. */
  --highlight: #FBBF2B;   /* money saved. Navy on it = 9.0:1. ONE rule in this file. */
  --surface:   #FFFFFF;
  --tint:      #EEF3FA;   /* navy on it = 13.5:1 */
  --bg:        #F4F7FB;   /* quiet pressed/hover ground for controls */
  --border:    #DCE6F2;   /* the one hairline */
  --line:      #EDF2F9;   /* inner separators */
  --on-dark:   #C9D9EC;   /* on --text-main #001E6B = 10.5:1 */

  width: 100%;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;  /* prices, deposits, years, % off */
}
/* #1B8FB8 is deliberately absent. It is for SVG strokes and hairlines only and
   this surface draws no SVG — the nav chevrons and the card arrow are text
   characters, and #1B8FB8 on white is 3.71:1, which is not a text value.
   #B3261E is absent too: this surface has no error state. */


/* ============================================================================
   3. COMPONENTS, in DOM order.
   ============================================================================ */

/* 3.1 — Count line. Needs show_count; 0 of the 45 live placements pass it, so
   this never renders today. Styled so it is not broken if someone switches it
   on, and no further effort spent on it. */
.dcb-premium-cards .dcb-premium-cards__count {
  margin: 0 0 12px;
  font-weight: 500;
  font-size: 13px;
  line-height: 1.4;
  color: var(--text-soft);
}

/* 3.2 — Slider shell: arrow / track / arrow.
   44px at EVERY width. The old file shrank the arrows 38 -> 34 -> 30px, i.e.
   made them smallest exactly where they are thumb-only. The gutter is fixed
   and the TRACK absorbs the difference instead. */
.dcb-premium-cards--slider .premium-car-slider-shell {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) 44px;
  align-items: center;
  gap: 8px;
}

.dcb-premium-cards--slider .premium-car-slider-nav {
  width: 44px;
  height: 44px;
  min-height: 44px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-main);            /* #001E6B on #FFFFFF = 15.0:1 */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  transition: background-color 120ms linear, border-color 120ms linear, color 120ms linear;
}
/* The ‹ › glyphs are aria-hidden text characters (premium-car-cards.php:60, :220).
   18px, not the old file's 20px: 18 is on the type scale and 20 is not, and at
   44px the optical weight is right. */
.dcb-premium-cards--slider .premium-car-slider-nav span {
  font-weight: 700;
  font-size: 18px;
  line-height: 1;
}

.dcb-premium-cards--slider .premium-car-carousel {
  width: 100%;
  overflow: hidden;
}

/* 3.3 — Grid layout track. FREE of the column variable: setupSlider() returns
   at premium-cards.js:50 for data-layout="grid", so nothing reads a column
   count here. auto-fit measures the real container — which is the point, since
   these widgets sit inside Elementor columns as narrow as ~630px. */
.dcb-premium-cards--grid .premium-car-card-grid {
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

/* 3.4 — The card. An <a> wrapping everything.
   No shadow, no blur, no shimmer, no lift. The whole affordance is one
   hairline changing colour. DELETED from the old :135-193: backdrop-filter
   blur(14px), transform-style:preserve-3d, transform in the transition list,
   the :hover translateY(-5px) + heavier shadow, and the entire ::before
   shimmer — a 70% x 250% rotated white gradient transitioning `left` over
   800ms, which is both the most templated gesture on the surface and a
   property that cannot be composited. */
.dcb-premium-cards .premium-car-card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  min-width: 0;
  text-decoration: none;
  color: var(--text-main);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: none;
  transition: border-color 120ms linear;
}

/* 3.5 — THE ONE STRUCTURAL MOVE.
   .premium-car-card__price is a child of __media (premium-car-cards.php:147)
   and cannot move in the DOM. But __media does not have to be a picture frame.
   Made a flex column, its flow children are exactly the image and the price —
   __overlay is display:none and __topbar is position:absolute, so both leave
   the flow — and the price lands as a solid band directly beneath the photo.
   Zero PHP required. __media keeps position:relative because the topbar still
   anchors to it; that is safe, it is inside the card, not an ancestor of the
   slide (see BEHAVIOUR 1.4).
   DELETED: height:196px (:198) and the 204px media-query override (:554). */
.dcb-premium-cards .premium-car-card__media {
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 0 0 auto;
  height: auto;
  overflow: hidden;
  background: transparent;
}

/* One media frame, shared with the filter card and the wizard. Every image in
   the DB is 1024x648 (1.5802:1) against a 1.6:1 box, so `contain` letterboxes
   by under 1% and never crops a car. The aspect-ratio sits on the IMAGE, not
   on __media, because __media is no longer only the picture.
   DELETED: transform:scale(1) (:209), transition:transform .6s (:210) and the
   whole :hover rule (:213-215), which set scale(1) — the value it already had.
   Dead code that had been disabled by neutering instead of deletion. */
.dcb-premium-cards .premium-car-card__img {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 10;
  object-fit: contain;
  object-position: center;
  display: block;
  background: var(--tint);
}

/* The black gradient scrim. In this direction the car is the only picture and
   it is never dimmed. Nothing in the JS touches this element, so no guard. */
.dcb-premium-cards .premium-car-card__overlay {
  display: none;
}

/* 3.6 — Badges.
   justify-content:flex-start, not space-between: the topbar has EXACTLY TWO
   children on 144 of 145 cars — availability, and service_label ("Self-drive"
   on all 145). space-between threw them to opposite corners of the card;
   grouped top-left they read as one status cluster. Same failure as
   .dcb-price-main. */
.dcb-premium-cards .premium-car-card__topbar {
  position: absolute;
  top: 8px;
  left: 8px;
  right: 8px;
  z-index: 2;
  display: flex;
  align-items: flex-start;
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: 6px;
}

.dcb-premium-cards .premium-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 9px;
  border-radius: 999px;
  font-weight: 500;
  font-size: 13px;
  line-height: 1.3;
  letter-spacing: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text-main);            /* #001E6B on #FFFFFF = 15.0:1 */
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  font-variant-numeric: tabular-nums;
}
/* Both variants collapse to the base ON PURPOSE.
   premium-car-cards.php:135 reuses premium-badge--year for the service label,
   so anything year-specific also hits "Self-drive" on all 145 cars. And the
   availability string has four values, five cars reading "Not available" — so
   the old #fff on rgba(36,161,72,.78) green was 2.53:1 composited over the
   light letterbox AND semantically wrong. Two identical quiet white chips at
   15.0:1 tell no lie. */
.dcb-premium-cards .premium-badge--availability,
.dcb-premium-cards .premium-badge--year {
  background: var(--surface);
  border-color: var(--border);
  color: var(--text-main);
}

/* 3.7 — THE PRICE RAIL. The signature, byte-identical on all four surfaces.
   Out of the photograph, onto a solid plate, at its full size.
   BEFORE: 13px #b38724 on a 90%-white blur plate over an arbitrary photo =
   3.28:1, with a 9px #7c7c7c struck price (4.17:1) and a 9px #555 suffix.
   AFTER:  22px/700 #001E6B on solid #FFFFFF = 15.0:1; suffix and struck price
   13px #42567A = 7.4:1. The 9px type — the smallest on the site, carrying the
   price comparison — is gone. */
.dcb-premium-cards .premium-car-card__price {
  position: static;
  z-index: auto;
  display: block;
  padding: 10px 12px;
  margin: 0;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  background: var(--surface);
  color: var(--text-main);
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.dcb-premium-cards .premium-car-card__price-main {
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: nowrap;
  width: 100%;
  min-width: 0;
  font-variant-numeric: tabular-nums;
}
.dcb-premium-cards .premium-car-card__price-main > * {
  flex: 0 0 auto;
}

/* The figure. 22px against a 16px card title: a 4px step reads as a caption,
   a 6px step reads as a decision. This is the one place the sixth type size
   is earned. */
.dcb-premium-cards .premium-car-card__price strong {
  font-weight: 700;
  font-size: 22px;
  line-height: 1.2;
  color: var(--text-main);            /* #001E6B on #FFFFFF = 15.0:1 */
  letter-spacing: 0;
  white-space: nowrap;
}

/* The suffix is addressed BY ITS OWN CLASS (premium-car-cards.php:153 always
   emits it). The old file used a `.premium-car-card__price-main > span`
   catch-all at (0,2,1), which also matched __price-desc and rendered a 67-char
   SEO sentence at 9px forced lowercase. No catch-all is reintroduced here:
   with both spans addressed by class there is nothing left for one to do, and
   the hide rule below never has to out-specify anything. */
.dcb-premium-cards .premium-car-card__price-suffix {
  font-weight: 500;
  font-size: 13px;
  line-height: 1.2;
  color: var(--text-soft);            /* #42567A on #FFFFFF = 7.4:1 */
  text-transform: none;               /* was lowercase */
  white-space: nowrap;
}

/* The struck price is FIRST in the DOM (php:150) and belongs last. order:1
   moves it; margin-left:auto pushes it — on ONE child. Never
   justify-content:space-between on a 2-to-4-child row. */
.dcb-premium-cards .premium-car-card__price-old {
  order: 1;
  margin-left: auto;
  margin-right: 0;
  font-weight: 500;
  font-size: 13px;
  line-height: 1.2;
  font-style: normal;                 /* it is an <em> */
  color: var(--text-soft);            /* #42567A on #FFFFFF = 7.4:1 — a line-through
                                         does not exempt text from 1.4.3 */
  text-decoration: line-through;
  white-space: nowrap;
}

/* price_description goes. 142 of 145 cars carry an SEO sentence up to 67
   characters ("Mercedes GLA 200 Price Abu Dhabi: Affordable Daily & Weekly
   Options"), plus two junk values ("475", "per day without driver"). It is not
   something a renter comparing cars uses, and it is the only reason the price
   plate ever needed 9px type. (0,3,0). */
.dcb-premium-cards .premium-car-card__price-main > .premium-car-card__price-desc {
  display: none;
}

/* 3.8 — Card body. */
.dcb-premium-cards .premium-car-card__body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  padding: 12px;
  gap: 8px;
}

/* 3.9 — The offer band. 29 of 145 cars carry it.
   #FBBF2B APPEARS IN EXACTLY ONE RULE IN THIS FILE — this one. Amber means
   money saved and nothing else is ever amber; anything else that wants to
   raise its voice uses --tint with navy. That exclusivity is what makes the
   29 offer cards unmissable in a 62-card grid.
   No nested pill inside the band: a chip on a chip is decoration. */
.dcb-premium-cards .premium-car-card__deal.premium-car-card__deal--body {
  width: 100%;
  margin: 0;
  padding: 8px 10px;
  border: 0;
  border-radius: 12px;
  background: var(--highlight);       /* #001E6B on #FBBF2B = 9.0:1 */
  box-shadow: none;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px;
}
.dcb-premium-cards .premium-car-card__deal-label {
  font-weight: 700;
  font-size: 13px;
  line-height: 1.3;
  color: var(--text-main);
  text-transform: uppercase;
  letter-spacing: .06em;              /* the ONE uppercase label in the plugin */
}
.dcb-premium-cards .premium-car-card__deal-badge {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--text-main);
  font-weight: 700;
  font-size: 13px;
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
}
.dcb-premium-cards .premium-car-card__deal-copy {
  font-weight: 500;
  font-size: 13px;
  line-height: 1.3;
  color: var(--text-main);
  font-variant-numeric: tabular-nums;
}

/* 3.10 — Title, brand, subtitle. */
.dcb-premium-cards .premium-car-card__header {
  margin: 0;
}

/* The two-line clamp is not optional. .premium-car-card-wrap is
   align-items:stretch and .premium-car-card is height:100%, so ONE unclamped
   three-line name ("Lamborghini Aventador Roadster", 30 chars, the longest of
   the 145) retunes an entire grid row and leaves dead space above three other
   footers. Two lines fits every one of the 145 titles at 240px.
   letter-spacing and margin are restated because an Elementor kit targets h3
   directly and would otherwise win over the root. */
.dcb-premium-cards .premium-car-card__title {
  margin: 0;
  font-weight: 700;
  font-size: 16px;
  line-height: 1.3;
  color: var(--text-main);
  letter-spacing: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.dcb-premium-cards .premium-car-card__brand {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
}
/* The logo loses its 20px plate and sits bare at 14px, baseline-aligned —
   identical to the wizard's .dcb-brand-badge-logo. One treatment, two
   surfaces. 140 of 145 cars have one. */
.dcb-premium-cards .premium-car-card__brand-logo {
  height: 14px;
  width: auto;
  max-width: 40px;
  object-fit: contain;
  display: block;
  border: 0;
  background: transparent;
  padding: 0;
  border-radius: 0;
}
.dcb-premium-cards .premium-car-card__brand-name {
  font-weight: 500;
  font-size: 13px;
  line-height: 1.3;
  color: var(--text-soft);            /* #42567A on #FFFFFF = 7.4:1 */
}

/* KEPT deliberately. This <p> ("Economy • Abu Dhabi", "Luxury • Dubai") is the
   ONLY place the emirate appears on a premium card — the four .premium-spec
   children carry car_type, engine, deposit and highlight, and NOT location —
   on a site that rents across four emirates. Hiding it is information loss,
   not restraint. */
.dcb-premium-cards .premium-car-card__subtitle {
  margin: 4px 0 0;
  font-weight: 500;
  font-size: 13px;
  line-height: 1.4;
  color: var(--text-soft);            /* #42567A on #FFFFFF = 7.4:1 */
}

/* 3.11 — Specs. Exactly four children, always (php:187-205).
   minmax(132px,1fr) measures the real card, not the window: a 240px card minus
   24px of body padding leaves 216px, which is one column of ~25ch and fits
   "Deposit: 5,000 AED" and "2.5L 4-cylinder or Hybrid"; a 340px card gives two
   columns of ~152px. DELETED: the @640 `grid-template-columns:1fr` override
   (:585-587) — auto-fit already did that, and measured the container instead
   of the viewport while doing it.
   DELETED: all nine !important at :445-455 and the hover rule at :457-461,
   which restated the resting values. Grepped: nothing in the plugin or in
   Hello Elementor sets any of those six properties on .premium-spec. They were
   defensive against something that does not exist. */
.dcb-premium-cards .premium-car-card__specs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 6px 12px;
  margin: 0;
}
.dcb-premium-cards .premium-car-card__specs .premium-spec {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}
/* The four emoji (car / gear / money bag / sparkles) are hardcoded at
   premium-car-cards.php:188-203 and cannot be changed without a PHP edit.
   They are NOT suppressed with font-size:0 and replaced by SVG data-URIs:
   that leaves them in the accessibility tree announced as "automobile, gear,
   money bag, sparkles" either way, AND adds four pictures to a direction whose
   whole claim is that the car is the only picture. The tinted disc goes; at
   13px they read as marks rather than decoration. */
.dcb-premium-cards .premium-spec__icon {
  display: inline-flex;
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  border-radius: 0;
  background: transparent;
  font-size: 13px;
  line-height: 1;
}
.dcb-premium-cards .premium-spec__text {
  font-weight: 500;
  font-size: 13px;
  line-height: 1.3;
  color: var(--text-soft);            /* #42567A on #FFFFFF = 7.4:1 */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* 3.12 — Footer. Exactly two children (php:209-210): the label and the arrow.
   margin-left:auto on the arrow — ONE child — never space-between on a
   two-child row. No accent pill here: on a 62-card grid page that would be 62
   accent fills, and the accent's whole claim is "the one action on this view".
   The accent on this surface belongs to .dcb-premium-cards__load-more alone. */
.dcb-premium-cards .premium-car-card__footer {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: auto;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
.dcb-premium-cards .premium-car-card__cta {
  font-weight: 700;
  font-size: 14px;
  line-height: 1;
  color: var(--text-main);            /* #001E6B on #FFFFFF = 15.0:1 */
}
/* The 30px near-black disc and its translateX(4px) hover (:497-513) are gone.
   The arrow is a text character, so it is coloured as text: #42567A at rest,
   NOT #1B8FB8 (3.71:1 — that value is for SVG strokes and hairlines, and a
   `->` glyph is not a stroke). No 44px floor applies: this is decoration
   inside the card's own <a>, which is the target. */
.dcb-premium-cards .premium-car-card__arrow {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 0;
  background: transparent;
  color: var(--text-soft);            /* #42567A on #FFFFFF = 7.4:1 */
  font-size: 16px;
  line-height: 1;
  transition: color 120ms linear;
}

/* 3.13 — List layout. 0 of the 45 live placements use display="list", but the
   shortcode still accepts it, so it is carried forward at zero design cost.
   The old fixed min-height:196px on both the card and the media box is gone
   (the media box has no fixed height anywhere any more), and the hard
   `260px minmax(0,1fr)` split plus its @900 override are replaced by one
   container-aware line: two columns while there is room for them, one when
   there is not, measured against the card and not the window. */
.dcb-premium-cards--list .premium-car-card-grid {
  grid-template-columns: 1fr;
}
.dcb-premium-cards--list .premium-car-card {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  align-items: stretch;
  min-height: auto;
}
.dcb-premium-cards--list .premium-car-card__media {
  height: auto;
  min-height: auto;
}

/* 3.14 — Load more. The shared primary control, verbatim across the plugin.
   Was #111 ground with a #b38724 gold hover at 42px and weight 800 — three
   values that exist nowhere in the design system. Display is in BEHAVIOUR 1.3. */
.dcb-premium-cards .dcb-premium-cards__load-more-wrap {
  display: flex;
  justify-content: center;
  margin-top: 16px;
}
.dcb-premium-cards .dcb-premium-cards__load-more {
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  border-radius: 999px;
  min-height: 44px;
  padding: 0 20px;
  align-items: center;
  justify-content: center;
  background: var(--accent);
  color: var(--text-main);            /* #001E6B on #3CADD5 = 5.8:1 */
  font-weight: 700;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  box-shadow: none;
  transition: background-color 120ms linear, color 120ms linear;
}

/* 3.15 — Empty state. Replaces the whole shell when no cars match. */
.dcb-premium-cards .dcb-premium-cards__empty {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px;
  background: var(--surface);
  color: var(--text-soft);            /* #42567A on #FFFFFF = 7.4:1 */
  font-weight: 500;
  font-size: 14px;
  line-height: 1.5;
  box-shadow: inset 2px 0 0 var(--border);
}


/* ============================================================================
   4. STATES — hover, focus-visible, active, disabled.
   Focus is ONE ring and is never folded into a hover rule. Lift is expressed
   as border-colour only: there is no transform anywhere in this file.
   ============================================================================ */

/* Card. The hover edge is decorative and is not the only signal of anything,
   so #3CADD5 on #FFFFFF (2.3:1) is fine here — unlike a focus indicator,
   which is why focus below is navy and not the accent. */
.dcb-premium-cards .premium-car-card:hover {
  border-color: var(--accent);
}
.dcb-premium-cards .premium-car-card:hover .premium-car-card__arrow {
  color: var(--text-main);            /* #001E6B on #FFFFFF = 15.0:1 */
}

/* Card focus ring. #001E6B against #FFFFFF = 15.0:1, far above the 3:1 that
   WCAG 1.4.11 asks of a focus indicator.
   In the GRID and LIST layouts the ring sits outside the card (offset 2px).
   In the SLIDER the track is a scrollport — overflow-x:auto also clips
   vertically — and .premium-car-carousel is overflow:hidden, so an outward
   ring would be sliced off the first and last visible card. There it is drawn
   inward instead. Same ring, same weight, never clipped. */
.dcb-premium-cards .premium-car-card:focus-visible {
  outline: 3px solid var(--text-main);
  outline-offset: 2px;
}
.dcb-premium-cards--slider .premium-car-card:focus-visible {
  outline-offset: -3px;
}

/* Slider arrows. */
.dcb-premium-cards--slider .premium-car-slider-nav:hover:not(:disabled) {
  background: var(--bg);
  border-color: var(--accent);
  color: var(--text-main);
}
.dcb-premium-cards--slider .premium-car-slider-nav:focus-visible {
  outline: 3px solid var(--text-main);
  outline-offset: 2px;
}
/* Disabled is a colour change, never an opacity fade: opacity:.35 dims the
   border, the glyph and the ground together and leaves a smudge. The control
   keeps its shape and loses its glyph. Disabled controls are exempt from
   1.4.3, which is the only reason #DCE6F2 on #FFFFFF (1.3:1) is allowed to be
   this quiet — and being this quiet is the whole message. */
.dcb-premium-cards--slider .premium-car-slider-nav:disabled {
  background: var(--surface);
  border-color: var(--line);
  color: var(--border);
  cursor: default;
  opacity: 1;
}

/* Load more. The accent inverts to navy rather than darkening — the same
   inversion the wizard's primary button uses, so the two finally agree. */
.dcb-premium-cards .dcb-premium-cards__load-more:hover {
  background: var(--text-main);
  color: var(--surface);              /* #FFFFFF on #001E6B = 15.0:1 */
}
.dcb-premium-cards .dcb-premium-cards__load-more:active {
  background: var(--text-main);
  color: var(--on-dark);              /* #C9D9EC on #001E6B = 10.5:1 */
}
.dcb-premium-cards .dcb-premium-cards__load-more:focus-visible {
  outline: 3px solid var(--text-main);
  outline-offset: 2px;
}


/* ============================================================================
   5. REDUCED MOTION
   Scoped to this widget's own root — never a bare `*`. !important appears in
   this file in this block and nowhere else.
   This CANNOT reach the autoslide: premium-cards.js:113-129 drives it with
   setInterval + track.scrollTo, and scroll-behavior:auto only makes each hop
   instant rather than smooth. Six independent 5000ms loops run on the homepage
   and that is a WCAG 2.2.2 failure no stylesheet can fix — startAutoslide()
   needs gating on matchMedia('(prefers-reduced-motion: reduce)'). Reported.
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {
  .dcb-premium-cards,
  .dcb-premium-cards *,
  .dcb-premium-cards *::before,
  .dcb-premium-cards *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .dcb-premium-cards--slider .premium-car-card-grid {
    scroll-behavior: auto !important;
  }
}
