/* =============================================================================
   Del Plaza — components
   Buttons, badges, cards, breadcrumbs, tooltips, keyframes, utilities
   =============================================================================*/

/* Button Geometry — Mandate*/
.btn {
  /* Typography standard: Univers Extended / 400 / 1rem.*/
  font-family: 'Univers Extended', var(--font-primary);
  font-weight: 400;
  font-size: 1rem;
  text-transform: uppercase;
  padding: 0.75rem 1.5rem;
  /* Geometry mandate: sharp top, rounded bottom — 9px default for all CTA*/
  border-radius: 0 0 9px 9px;
  transition: all 0.2s var(--ease-in-out);
  position: relative;
  overflow: hidden;
}

/* Size variants*/
.btn-sm {
  padding: 0.5rem 1rem;
  font-size: 0.75rem;
}

.btn-lg {
  padding: 1rem 2rem;
  font-size: 1rem;
}

.btn-xl {
  padding: 1.25rem 2.5rem;
  font-size: 1.125rem;
}

/* Primary button — Variants*/
.btn-primary {
  --bs-btn-bg: var(--color-interactive-primary);
  --bs-btn-border-color: var(--color-interactive-primary);
  --bs-btn-color: #ffffff;
  --bs-btn-hover-bg: var(--color-interactive-hover);
  --bs-btn-hover-border-color: var(--color-interactive-hover);
  --bs-btn-hover-color: #ffffff;
  --bs-btn-active-bg: var(--color-interactive-active);
  --bs-btn-active-border-color: var(--color-interactive-active);
  --bs-btn-active-color: #ffffff;
  --bs-btn-disabled-bg: var(--muted-silver);
  --bs-btn-disabled-border-color: var(--muted-silver);
  --bs-btn-disabled-color: rgba(255, 255, 255, 0.4);
}

/* Outline button*/
.btn-outline-primary {
  --bs-btn-color: var(--color-interactive-primary);
  --bs-btn-border-color: var(--color-interactive-primary);
  --bs-btn-hover-bg: var(--color-interactive-primary);
  --bs-btn-hover-border-color: var(--color-interactive-primary);
  --bs-btn-hover-color: #ffffff;
  --bs-btn-active-bg: var(--color-interactive-active);
  --bs-btn-active-border-color: var(--color-interactive-active);
  --bs-btn-active-color: #ffffff;
}

/* Ghost button — custom variant*/
.btn-ghost {
  --bs-btn-color: var(--color-content-primary);
  --bs-btn-bg: transparent;
  --bs-btn-border-color: transparent;
  --bs-btn-hover-color: var(--color-interactive-primary);
  --bs-btn-hover-bg: rgba(247, 238, 218, 0.08);
  --bs-btn-active-color: var(--color-interactive-active);
  --bs-btn-active-bg: rgba(247, 238, 218, 0.16);
}

/* Press effect — tactile physics*/
.btn:active {
  transform: translateY(1px);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2) !important;
}

/* Hover depth*/
.btn:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

/* =============================================================================
   Origin Badge
   =============================================================================*/
.origin-badge {
  display: inline-flex;
  align-items: center;
  padding: var(--spacing-quark) var(--spacing-nano);
  background-color: var(--color-badge-origin);
  color: #ffffff;
  font-size: clamp(0.6875rem, 1vw, 0.8125rem);
  font-weight: 700; /* Univers Black*/
  text-transform: uppercase;
  border-radius: var(--border-radius-sticker);
  margin-bottom: var(--spacing-nano);
  position: relative;
  overflow: hidden;
}

/* Sticker text — shared with status pill. Top margin optically re-centres
   Univers uppercase glyphs (cap-height sits high in the em box).*/
.track-status-pill__text {
  font-weight: 700; /* Univers Black*/
  margin-top: var(--spacing-tiny);
}

/* Exclusive/premium badge variant*/
.origin-badge.badge-exclusive {
  background-color: var(--color-badge-exclusive);
}

/* Circa Badge — Account hero "Member since" indicator*/
.circa-badge {
  display: inline-flex;
  align-items: center;
  padding: var(--spacing-quark) var(--spacing-nano);
  font-size: clamp(0.6875rem, 1vw, 0.8125rem);
  text-transform: uppercase;
  border-radius: var(--border-radius-sticker);
  margin-bottom: var(--spacing-nano);
  position: relative;
  overflow: hidden;
}

.circa-badge::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
  transform: translateX(-100%);
  transition: transform 0.6s var(--ease-out);
}

.circa-badge:hover::before {
  transform: translateX(100%);
}

.circa-badge__text {
  font-weight: 700;
  margin-top: var(--spacing-tiny);
}

/* =============================================================================
   Navigation & Wayfinding
   =============================================================================*/
/* Active nav indicator*/
.nav-link {
  position: relative;
  text-transform: uppercase;
  font-family: var(--font-primary);
  font-weight: 500;
  color: var(--color-content-primary);
  transition: color 0.2s var(--ease-out);
}

.nav-link::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 0;
  height: 2px;
  background-color: var(--color-interactive-primary);
  transition: width 0.3s var(--ease-out);
}

.nav-link:hover::after,
.nav-link.active::after {
  width: 100%;
}

.nav-link:hover,
.nav-link.active {
  color: var(--color-interactive-primary);
}

/* =============================================================================
   Card Styles
   =============================================================================*/
.card {
  border: 1px solid var(--color-border-primary);
  border-radius: var(--border-radius-md);
  background-color: var(--color-surface-card);
  transition: box-shadow 0.3s var(--ease-out), transform 0.3s var(--ease-out);
}

.card:hover {
  box-shadow: var(--shadow-heavy);
  transform: translateY(-4px);
}

.card-body {
  padding: var(--spacing-xxs);
}

/* =============================================================================
   Breadcrumb
   =============================================================================*/
.breadcrumb {
  font-family: var(--font-primary);
  font-size: 0.75rem;
  text-transform: uppercase;
}

.breadcrumb-item + .breadcrumb-item::before {
  color: var(--color-badge-origin);
  content: '\203A';
}

.breadcrumb-item.active {
  font-weight: 600;
  color: var(--color-content-heading);
}

/* =============================================================================
   Interactive Physics
   All interactive elements respond with tactile feedback
   =============================================================================*/
a, button, .nav-link, .dropdown-item, .footer-link, .action-icon {
  transition: all 0.2s var(--ease-in-out);
}

/* =============================================================================
   Focus Styles — ACCESSIBILITY (WCAG AA)
   =============================================================================*/
*:focus {
  outline: none;
}

*:focus-visible {
  outline: 2px solid var(--color-badge-origin);
  outline-offset: 2px;
}

/* =============================================================================
   Animation Keyframes
   =============================================================================*/
@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes slideDown {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: translateY(0); }
}

.fade-in-up {
  animation: fadeInUp 0.6s var(--ease-out) forwards;
}

/* =============================================================================
   Utility Classes — Extended palette utilities
   =============================================================================*/
.text-cognac          { color: var(--cognac) !important; }
.text-deep-navy       { color: var(--deep-navy) !important; }
.text-parchment-cream { color: var(--parchment-cream) !important; }
.text-imperial-plum   { color: var(--imperial-plum) !important; }
.text-ash-grey        { color: var(--ash-grey) !important; }

.bg-cognac          { background-color: var(--cognac) !important; }
.bg-parchment-cream { background-color: var(--parchment-cream) !important; }
.bg-deep-navy       { background-color: var(--deep-navy) !important; }

.border-cognac    { border-color: var(--cognac) !important; }
.border-muted     { border-color: var(--muted-silver) !important; }

/* Visually Hidden — ACCESSIBILITY (WCAG AA)*/
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* =============================================================================
   Responsive Adjustments — Mobile-first
   =============================================================================*/
@media (max-width: 991.98px) {
  .header {
    /* padding removed - header sits flush*/
  }

  .footer {
    text-align: center;
  }

  .footer-title::after {
    left: 50%;
    transform: translateX(-50%);
  }
}

@media (max-width: 767.98px) {
  .footer {
    padding: var(--spacing-lg) 0 var(--spacing-xxs) 0;
  }
}

/* =============================================================================
   Reduced Motion — Accessibility
   =============================================================================*/
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* =============================================================================
   Print Styles
   =============================================================================*/
@media print {
  .header,
  .footer {
    display: none;
  }

  body {
    background-color: #ffffff;
    color: #000000;
  }
}

/* Tooltip — Flag Selector Click Tooltip*/

/* ---- Tooltip inner container — Tawny Umber ground ----*/
.tooltip .tooltip-inner {
  background-color: var(--tawny-umber);
  color: var(--parchment-cream);
  font-family: var(--font-primary);
  font-size: 0.75rem;
  font-weight: 400;
  line-height: 1.5;
  text-align: center;
  padding: 15px;
  border-radius: 0 0 12px 12px; /* : sharp top, softly rounded bottom*/
  max-width: 280px;
}

/* ---- Market name span inside tooltip — Univers Black Oblique ----*/
.tooltip .tooltip-market-name {
  font-weight: 700;
  font-style: italic;
}

/* ---- Tooltip arrow — Tawny Umber to match background ----*/
.tooltip .tooltip-arrow::before {
  border-bottom-color: var(--tawny-umber) !important;
}

/* ---- Tooltip placement overrides (bottom) ----*/
.tooltip.bs-tooltip-bottom .tooltip-arrow::before {
  border-bottom-color: var(--tawny-umber) !important;
}

/* ---- Tooltip show state — subtle fade for tactile feedback ----*/
.tooltip.show {
  opacity: 1;
}

/* Store Banner — Promotional Message (site-wide component)*/
.store-banner {
  position: relative;
  background-color: var(--imperial-plum);
  padding: var(--spacing-xs) 0;
  /* The band's own surface, named so the strip of clearance above it can be painted
     the same color in either register — the plum, or the charcoal of a closed market. */
  --store-banner-surface: var(--imperial-plum);
  /* The header's round logo overhangs the header bar by 40px (.logo margin-bottom,
     layout.css). The band stands 40px clear of the bar and carries its own surface up
     through that clearance, so the store banner runs unbroken from the header down and
     the mark hangs over its top. The secondary register (Basket, Checkout) is flush. */
  margin-top: var(--spacing-lg);
}

/* The clearance, in the band's own surface — the strip is the store banner, not a gap.
   It is a strip rather than the band's own top padding because the narrow-screen rule
   below resets that padding, while the mark's overhang is the same at every width. */
.store-banner:not(.store-banner--secondary)::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: var(--spacing-lg);
  background-color: var(--store-banner-surface);
}

.store-banner--secondary {
  margin-top: 0;
  border-bottom: none;
}

/* ---- Greek Meander Border - Imperial Plum divider beneath the Store Banner ----*/
.meander-border {
  display: block;
  width: 100%;
  height: clamp(2.5rem, 4.5vw, 3.75rem);
  background-color: transparent;
  background-image: url("../assets/svg/greek-meander.svg");
  background-repeat: repeat-x;
  background-size: auto 100%;
  background-position: left center;
}

.store-banner__inner {
  text-align: center;
  padding: var(--spacing-nano) 0;
}

.store-banner__overline {
  display: block;
  font-family: var(--font-primary);
  font-weight: 500;
  font-size: 0.6875rem;
  text-transform: uppercase;
  color: var(--cognac);
  margin-bottom: var(--spacing-quark);
}

.store-banner__message {
  font-family: var(--font-primary);
  font-weight: 300;
  font-size: clamp(0.875rem, 1.2vw, 1rem);
  color: var(--parchment-cream);
  margin-bottom: 0;
  line-height: 1.6;
}

.store-banner__message strong {
  font-weight: 600;
  color: #ffffff;
}

/* Secondary register (Basket, Checkout). The message stands alone with no*/
.store-banner--secondary .store-banner__message {
  margin-top: 35px;
}

/* Unavailable Register —*/

/* The modifier carries the charcoal. The machine-readable attribute is accepted
   as the same state, so a runtime toggle cannot desynchronise surface from state.*/
.store-banner:is(.store-banner--unavailable, [data-market-closed="true"]) {
  background-color: var(--slate-charcoal);
  /* The clearance above a closed market's band is charcoal too, or a plum strip would
     sit on a charcoal surface. */
  --store-banner-surface: var(--slate-charcoal);
}

/* ---- Heading — the warmth is withdrawn (Golden Milk -> Alabaster) ----*/
.store-banner:is(.store-banner--unavailable, [data-market-closed="true"]) .store-banner__heading {
  color: var(--alabaster);
}

/* ---- Message — re-asserted, so no page-level rule can warm a refused surface ----*/
.store-banner:is(.store-banner--unavailable, [data-market-closed="true"]) .store-banner__message {
  color: var(--parchment-cream);
}

/* ---- Countdown — the register's instrument, rendered here and nowhere else.
   A gauge, a quiet label, a monumental value: the band's station clock. ----*/
.store-banner__countdown {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--spacing-nano);
  margin-top: var(--spacing-md);
}

/* The rule the reading sits under, crowned by the door mark. */
.store-banner__countdown-rule {
  display: block;
  width: 3.5rem;
  border-top: 1px solid var(--color-border-primary);
}

.store-banner__countdown-mark {
  /* The mark stands on the rule, so its own leading is closed right up, and wears
     the same accent as the reading's unit letters (Golden Milk). */
  font-size: 1.5rem;
  line-height: 1;
  color: var(--golden-milk);
}

.store-banner__countdown-label {
  /* The label wears the same type as the Hours Rail's own on the homepage
     (.home-hours__count-label): Univers Extended, 500, at the overline size. */
  font-family: 'Univers Extended', var(--font-primary);
  font-weight: 500;
  font-size: 0.6875rem; /* overline-small*/
  line-height: 1.3;
  text-transform: uppercase;
  color: var(--parchment-cream);
}

/* The value is the homepage's key figure (.home-count) with its units
   (.home-count__unit): figures and their letters share a baseline, the pair
   standing on one line until the band is too narrow to hold the reading. */
.store-banner__countdown-value {
  display: inline-flex;
  align-items: baseline;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--spacing-sm);
  animation: fadeIn 0.3s var(--ease-out) both;
}

.store-banner__countdown-part {
  display: inline-flex;
  align-items: baseline;
}

.store-banner__countdown-figure {
  /* The homepage's key figure (.home-count__num) exactly: same family, weight,
     size and line-height, so the band's clock stands the same height as the
     Hours Rail's. The colour stays the register's inverse — the homepage
     figure's navy belongs to its parchment ground, not to charcoal. */
  font-family: var(--font-primary);
  font-weight: 700; /* Univers Black*/
  font-size: clamp(1.75rem, 3.6vw, 2.75rem); /* the home key figure's own scale*/
  line-height: 1;
  color: var(--color-content-inverse);
  font-variant-numeric: tabular-nums;
}

.store-banner__countdown-unit {
  /* The homepage's unit (.home-count__unit): smaller than the figure, in the
     accent. On the charcoal ground the accent is Golden Milk, not the homepage's
     Cognac — Cognac on Slate Charcoal reads at barely 1.4:1. */
  font-family: 'Univers Extended', var(--font-primary);
  font-weight: 500;
  font-size: clamp(0.8125rem, 1.4vw, 1rem);
  line-height: 1;
  color: var(--golden-milk);
  margin-left: 2px;
}

/* ---- Narrow screens: the figure steps down, the band does not re-space ----*/
@media (max-width: 575.98px) {
  .store-banner__countdown {
    margin-top: var(--spacing-sm);
  }

  /* The parts close up, as the homepage's figure does on the same width. */
  .store-banner__countdown-value {
    gap: var(--spacing-xxs);
  }
}

/* ---- Reduced motion: the countdown settles without drawing itself ---*/
@media (prefers-reduced-motion: reduce) {
  .store-banner__countdown-value {
    animation: none;
  }
}

/* ---- Responsive: consistent banner padding on narrow screens ----*/
@media (max-width: 575.98px) {
  .store-banner {
    padding: var(--spacing-nano) 0;
  }
}

/* Form Messages — shared validation feedback*/
.form-message {
  font-family: var(--font-primary);
  font-weight: 400;
  font-size: 0.75rem;
  margin-top: var(--spacing-quark);
  min-height: 1.25rem;
}

.form-message--error {
  color: #dc3545;
}

.form-message--success {
  color: var(--deep-navy);
}

/* =============================================================================
   Notice Panel — the house's notice, in its sizes

   MOVED HERE FROM THE AUTH PAGES' OWN SHEET on 2026-09-30. It was born on the
   sign-in pages and styled there; the merchant's door shows the same panel now
   (templates/pages/login-seller.html.twig), so it belongs in the shared layer
   that every page loads. Every declaration is the one the auth pages already
   wore: the file changed, and nothing else.

   The class name is the auth pages' own. .auth-success is the notice panel — on
   parchment, on Oxford Light and on the dark sign-in card — and both doors of the
   emporium put one on show. Renaming it would touch every page that renders one,
   for a word.

   =============================================================================*/

/* ---- The panel itself ----*/
.auth-success {
  display: flex;
  align-items: flex-start;
  gap: var(--spacing-xxs);
  padding: var(--spacing-xxs);
  background-color: rgba(60, 71, 122, 0.04);
  border: 1px solid var(--deep-navy);
  border-radius: 0 0 9px 9px;
}

.auth-success__icon {
  font-size: 1.25rem;
  color: var(--deep-navy);
  flex-shrink: 0;
  margin-top: 0.125rem;
}

.auth-success__text {
  font-family: var(--font-primary);
  font-weight: 300;
  font-size: 0.8125rem;
  color: var(--color-content-primary);
  line-height: 1.6;
  margin-bottom: 0;
}

.auth-success__text strong {
  font-weight: 600;
  color: var(--color-content-heading);
}


/* ---- Session Flash Panel (the notice standing alone in a bare .container)

   The same .auth-success — the component the sign-in card uses to confirm a
   sign-in or a registration — but this panel stands alone in a bare .container.
   It is not attached beneath a card, so the shared component's card-foot radius
   (squared against the card above, rounded below) reads unfinished here.

   The --flash modifier finishes it as a self-contained Del Plaza notice: the
   house corner geometry (sharp top, subtly rounded bottom), a Parchment Cream
   body on a Muted Silver hairline, and a weighed 3px lintel across the top —
   the same structural band the timetable cards carry. Weight and permanence,
   not a transient toast.

   One component, one variable. The lintel and the icon take the type colour,
   and the gravity of that colour carries the meaning:
     success  Deep Navy      — an affirmation; the house's light-surface "yes"
     notice   Tawny Umber    — neutral intelligence; the spent-link colour
     error    Imperial Plum  — the gravest tone the palette holds
   The icon glyph and the ARIA role (status / alert) tell them apart a second
   time, for anyone who cannot lean on the colour. */
.auth-success--flash {
  --flash-accent: var(--deep-navy);
  /* The icon rides the message line, not the panel's top edge (see the icon rule below). */
  align-items: center;
  padding: var(--spacing-xxs) var(--spacing-xs);
  background-color: var(--parchment-cream);
  border: 1px solid var(--color-border-primary);
  border-top: 3px solid var(--flash-accent);
  /* Sharp top — the house's geometry, kept — with a more generous foot than the shared
     card-foot component carries: 3px reads as a clipped edge on a panel that stands
     alone, so the flash finishes itself with a fuller curve. */
  border-radius: 0 0 12px 12px;
  box-shadow: var(--shadow-light);
}

.auth-success--flash.auth-success--success { --flash-accent: var(--deep-navy); }
.auth-success--flash.auth-success--notice  { --flash-accent: var(--tawny-umber); }
.auth-success--flash.auth-success--error   { --flash-accent: var(--imperial-plum); }

/* ---- The same panel on Oxford Light (the merchant at the shopper's door)

   The panel both doors put in front of a visitor who is signed in somewhere else: a merchant
   who opens the shopper's sign-in page (templates/pages/login.html.twig, which serves /login
   and /register), and a customer who opens the merchant's (templates/pages/login-seller.html.twig,
   /login-seller). Each is told so at the head of the page, and offered the way back to their own.
   It is the flash panel above with one thing changed: the ground.

   THE INK IS LEFT ALONE, AND THAT IS THE WHOLE POINT. The flash panel's message is
   Slate Charcoal, and Oxford Light is a ground the house already puts that ink on — the
   admin pairs the same two, at 4.75:1, for its author lines (public/css/admin.css). So
   this modifier re-points no text, no icon and no button: parchment cream to Oxford
   Light, and the panel stays readable without a second set of decisions.

   THE BAND IS THE ACCENT, NOT THE FRAME. border-color paints all four sides, the top
   one with them, and the top one is the band — so it is put back to --flash-accent
   after the hairline, the same colour the icon wears, because both take that variable.
   This is the one way this modifier can be got wrong: leave the shorthand last and the
   band comes out navy while the icon stays bronze. The hairline itself is re-tinted
   navy because Muted Silver on a pale blue panel draws a line nobody can see. */
.auth-success--oxford-light {
  background-color: var(--oxford-light);
  border-color: rgba(60, 71, 122, 0.22);
  border-top-color: var(--flash-accent);
}

.auth-success--flash .auth-success__icon {
  font-size: 1.375rem;
  color: var(--flash-accent);
  /* Cancel the shared component's 0.125rem nudge — on the flash panel the flex line
     centres the icon against the message, so a single-line notice no longer sits high. */
  margin-top: 0;
}

/* Heavier than the shared component's 300, scoped to the flash panel alone: the sign-in
   card's own confirmations, the thank-you page and the reset page keep their lighter
   voice. A notice the customer is meant to read is read, not skimmed. */
.auth-success--flash .auth-success__text {
  font-weight: 500;
}


/* =============================================================================
   Concierge Note — shared component
   Used on login.php and track-order.php.
   =============================================================================*/
.auth-concierge {
  display: flex;
  align-items: flex-start;
  gap: var(--spacing-xxs);
  margin-top: var(--spacing-md);
  padding: var(--spacing-xxs) var(--spacing-xs);
  background-color: var(--color-surface-secondary);
  border: 1px solid var(--color-border-primary);
  border-radius: 0 0 9px 9px;
}

.auth-concierge i {
  font-size: 1.25rem;
  color: var(--cognac);
  flex-shrink: 0;
  margin-top: 0.125rem;
}

.auth-concierge p {
  font-family: var(--font-primary);
  font-weight: 300;
  font-size: 0.8125rem;
  color: var(--color-content-primary);
  line-height: 1.6;
  margin-bottom: 0;
}

.auth-concierge a {
  color: var(--deep-navy);
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color 0.2s var(--ease-out);
}

.auth-concierge a:hover {
  color: var(--cognac);
}

@media (max-width: 991.98px) {
  .auth-concierge {
    padding: var(--spacing-xxs);
  }
}

/* Product Carousel — Shared Component*/
.dp-carousel {
  position: relative;
}

.dp-carousel__track {
  display: flex;
  align-items: stretch;
  gap: var(--spacing-sm);
  margin: 0;
  padding: 0 0 var(--spacing-md);
  list-style: none;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.dp-carousel__track::-webkit-scrollbar {
  display: none;
}

.dp-carousel__slide {
  flex: 0 0 auto;
  width: clamp(11rem, 62vw, 16.5rem);
  scroll-snap-align: start;
}

@media (min-width: 660px) {
  .dp-carousel__slide {
    width: clamp(12rem, 30vw, 17.5rem);
  }
}

@media (min-width: 1024px) {
  .dp-carousel__slide {
    width: 18rem;
  }
}

/* ---- Progress rule — reports position, never decks the rail with dots ----*/
.dp-carousel__progress {
  position: relative;
  height: 2px;
  margin-top: var(--spacing-xs);
  background-color: var(--muted-silver);
  overflow: hidden;
}

.dp-carousel__progress-bar {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 30%;
  background-color: var(--cognac);
  transition: width 0.25s var(--ease-out), transform 0.25s var(--ease-out);
}

/* ---- Paged controls — button geometry per ---*/
.dp-carousel__nav {
  display: flex;
  gap: var(--spacing-nano);
  flex-shrink: 0;
}

.dp-carousel__btn {
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.125rem;
  background-color: #ffffff;
  border: 1px solid var(--color-border-primary);
  color: var(--color-content-heading);
  border-radius: 0 0 9px 9px;
  cursor: pointer;
  transition: all 0.2s var(--ease-out);
}

.dp-carousel__btn:hover {
  background-color: var(--deep-navy);
  border-color: var(--deep-navy);
  color: #ffffff;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.dp-carousel__btn:active {
  background-color: var(--imperial-plum);
  border-color: var(--imperial-plum);
  transform: translateY(1px);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
}

.dp-carousel__btn:disabled,
.dp-carousel__btn:disabled:hover,
.dp-carousel__btn[aria-disabled="true"],
.dp-carousel__btn[aria-disabled="true"]:hover {
  background-color: var(--muted-silver);
  border-color: var(--muted-silver);
  color: #ffffff;
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
}

@media (max-width: 575.98px) {
  .dp-carousel__btn {
    width: 2.5rem;
    height: 2.5rem;
    font-size: 1rem;
  }
}

/* Product Card - THE universal card. There is exactly one, and this is it.*/
.product-card {
  position: relative;
  background-color: var(--color-surface-card);
  border: 1px solid var(--color-border-primary);
  border-radius: 0 0 var(--border-radius-md) var(--border-radius-md);
  overflow: hidden;
  transition: box-shadow 0.3s var(--ease-out), transform 0.3s var(--ease-out);
  height: 100%;
  display: flex;
  flex-direction: column;
}

.product-card:hover {
  box-shadow: var(--shadow-heavy);
  transform: translateY(-4px);
}

/* ---- Card Link (entire card clickable) ----*/
.product-card__link {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  text-decoration: none;
  color: inherit;
}

.product-card__link:hover {
  color: inherit;
}

/* ---- Product Image ----*/
.product-card__image-wrap {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background-color: var(--parchment-cream);
}

.product-card__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.5s var(--ease-out);
}

.product-card:hover .product-card__image {
  transform: scale(1.06);
}

/* ---- Sale Badge ----*/
.product-card__badge {
  position: absolute;
  top: var(--spacing-nano);
  left: var(--spacing-nano);
  z-index: 5;
  display: inline-flex;
  align-items: center;
  padding: var(--spacing-quark) var(--spacing-nano);
  font-family: 'Univers Extended', var(--font-primary);
  font-weight: 600;
  font-size: 0.6875rem;
  text-transform: uppercase;
  border-radius: var(--border-radius-sticker);
  pointer-events: none;
}

/* The one merchandising badge, set in ink and never in a colour block: the two*/
.product-card__badge--new {
  background-color: var(--alabaster);
  color: var(--slate-charcoal);
  border: 1px solid var(--muted-silver);
}

/* Exclusivity is DEPLOYED here, never re-declared: supplies the sticker's*/
.product-card__image-wrap .origin-badge {
  position: absolute;
  top: var(--spacing-nano);
  left: var(--spacing-nano);
  z-index: 4;
}

/* ---- Wishlist Button ----*/
.product-card__wishlist {
  position: absolute;
  top: var(--spacing-nano);
  right: var(--spacing-nano);
  z-index: 6;
  width: 2.25rem;
  height: 2.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgba(255, 255, 255, 0.85);
  border: 1px solid var(--muted-silver);
  color: var(--slate-charcoal);
  font-size: 1rem;
  cursor: pointer;
  border-radius: var(--border-radius-sticker);
  transition: all 0.25s var(--ease-out);
  backdrop-filter: blur(4px);
  padding: 0;
}

/* Wishlist heart glyph — slight margin-top for optical centring within the button*/
.product-card__wishlist i {
  margin-top: var(--spacing-tiny);
}

.product-card__wishlist:hover {
  background-color: var(--golden-milk);
  color: var(--imperial-plum);
  border-color: var(--imperial-plum);
}

.product-card__wishlist:active {
  transform: translateY(1px);
  background-color: var(--imperial-plum);
  color: var(--golden-milk);
  border-color: var(--golden-milk);
}

.product-card__wishlist.is-wished {
  background-color: var(--imperial-plum);
  color: var(--golden-milk);
  border-color: var(--golden-milk);
}

.product-card__wishlist.is-wished:hover {
  background-color: var(--imperial-plum);
  color: var(--golden-milk);
  border-color: var(--golden-milk);
}

/* ---- Card Body ----*/
.product-card__body {
  padding: var(--spacing-xxs);
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
}

/* ---- Product Name ----*/
.product-card__name {
  font-family: 'Univers', var(--font-primary);
  font-weight: 600;
  font-size: clamp(0.875rem, 1.2vw, 1rem);
  line-height: 1.25;
  color: var(--color-content-heading);
  margin-bottom: var(--spacing-nano);
  /* Clamp to 2 lines with ellipsis*/
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ---- Price ----*/
.product-card__price {
  display: flex;
  align-items: baseline;
  gap: var(--spacing-quark);
  margin-top: auto;
  flex-wrap: wrap;
}

.product-card__price-currency {
  font-family: 'Univers Extended', var(--font-primary);
  font-size: clamp(0.75rem, 1vw, 0.875rem);
  font-weight: 400;
  color: var(--cognac);
}

.product-card__price-amount {
  font-family: 'Univers Extended', var(--font-primary);
  font-size: clamp(1rem, 1.5vw, 1.25rem);
  font-weight: 400;
  color: var(--cognac);
  line-height: 1;
}

/* ---- Original Price (strikethrough when on sale) ----*/
.product-card__price-amount--original {
  font-size: clamp(0.8125rem, 1.2vw, 1rem);
  color: var(--ash-grey);
  text-decoration: line-through;
}

/* ---- Sale Price ----*/
.product-card__price-sale {
  display: inline-flex;
  align-items: baseline;
  gap: var(--spacing-quark);
  color: var(--cognac);
}

.product-card__price-sale .product-card__price-currency,
.product-card__price-sale .product-card__price-amount {
  color: var(--cognac);
}

.product-card__price-sale .product-card__price-amount {
  font-size: clamp(1rem, 1.5vw, 1.25rem);
  font-weight: 600;
}

/* =============================================================================
   Product Card — Responsive Adjustments
   Base rules stand above; only breakpoints below.
   =============================================================================*/
@media (max-width: 575.98px) {
  .product-card__wishlist {
    width: 2rem;
    height: 2rem;
    font-size: 0.875rem;
  }

  .product-card__body {
    padding: var(--spacing-xxxs);
  }

  .product-card__name {
    font-size: 0.8125rem;
  }

  .product-card__price-amount {
    font-size: 0.9375rem;
  }
}

/* =============================================================================
   Grid Gutters — Responsive
   =============================================================================*/
/* Mobile (< 660px): gap-xxs (16px)*/
.gx-xxs {
  --bs-gutter-x: var(--spacing-xxs);
}

.mb-xxs {
  margin-bottom: var(--spacing-xxs);
}

/* Tablet (≥ 660px): gap-xs (20px)*/
@media (min-width: 660px) {
  .gx-xs--tablet {
    --bs-gutter-x: var(--spacing-xs);
  }

  .mb-xs--tablet {
    margin-bottom: var(--spacing-xs);
  }
}

/* Desktop (≥ 1024px): gap-sm (24px)*/
@media (min-width: 1024px) {
  .gx-sm--desktop {
    --bs-gutter-x: var(--spacing-sm);
  }

  .mb-sm--desktop {
    margin-bottom: var(--spacing-sm);
  }
}

/* Store Banner — Heading*/
.store-banner__heading {
  display: block;
  font-family: 'Univers Extended', var(--font-primary);
  font-weight: 600;
  font-size: 0.8125rem;
  text-transform: uppercase;
  color: var(--golden-milk);
  /* No margin of its own: the band's 40px clearance above already carries the weight
     at the top, and the heading stands where the product page's banner copy stands. */
  margin-bottom: var(--spacing-quark);
}

.product-card__meta {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-tiny);
  margin-top: var(--spacing-nano);
  margin-bottom: var(--spacing-nano);
  padding-top: var(--spacing-nano);
  border-top: 1px solid var(--color-border-primary);
}

.product-card__meta-seller {
  font-family: var(--font-primary);
  font-weight: 500;
  font-size: 0.75rem;
  line-height: 1.3;
  color: var(--color-content-heading);
}

/* =============================================================================
   Bulletin Ticker — the house's moving band across the top of the masthead
   =============================================================================
   The band rides above the logo row on every page and carries the house's bulletin
   past the reader. What that bulletin says is the partial's business, never this
   stylesheet's.

   ONE COMPONENT, INTERCHANGEABLE. The notices are a plain list in
   _partials/ticker.html.twig and nothing else — the partial names no colour, no
   measure and no pace. A backend populating real announcements swaps the list, and
   the band, its rhythm and its speed take the new copy without another edit.

   THE GROUND. Black, seated under an Oxford Light rule and above the white masthead: the
   band reads as the cornice the header is crowned with, not as a transient strip. The notice
   is set in Oxford Light, which stands at 15:1 on black. The lozenge between notices, and the
   band's control, stay gilt (golden milk) — the house's mark for a thing worth reading, and
   the one warm note on an otherwise cool band.

   THE MOVEMENT. The track is drawn twice and travels exactly one group's width, so
   it arrives where it began with no seam. The pace is one knob, --ticker-pace. The
   copy holds still while the visitor points at it, while the keyboard is inside it,
   and for as long as the band's own control is held. A reader who has asked their
   system for reduced motion gets the notices set out once and wrapped — nothing
   moves, and nothing is lost.
   =============================================================================*/
.ticker {
  /* The pace of the band: the time one full group takes to cross. This is the one number to
     turn — a smaller time is a faster band. 60s carries the long notice the band holds now at
     roughly 50px a second: a measured stride, quick enough to read as movement and slow enough
     to read as a sentence. Past about 45s the copy starts to outrun the eye. */
  --ticker-pace: 60s;

  display: flex;
  align-items: stretch;
  position: relative;
  min-height: 2.5rem;
  /* Black is the band's ground — the palette admits it beside white, and nothing draws a
     harder edge against the masthead below. */
  background-color: #000000;
  /* The cornice: the drawn line between the band and the masthead under it. It is the band's
     own text colour, so the rule and the notice are cut from one material. */
  border-bottom: 2px solid var(--oxford-light);
  overflow: hidden;
}

/* ---- The lane the copy travels through ---- */
.ticker__viewport {
  /* How far the copy is feathered at each end. Narrower on small screens, where the
     lane is too short to spend 3.5rem fading at either side. */
  --ticker-fade: 3.5rem;

  position: relative;
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  overflow: hidden;
  /* The copy enters from the edge of the band and leaves it, rather than appearing to
     be cut by it. The mask fades the copy only: the navy behind it is the band's own. */
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 var(--ticker-fade), #000 calc(100% - var(--ticker-fade)), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 var(--ticker-fade), #000 calc(100% - var(--ticker-fade)), transparent 100%);
}

.ticker__track {
  display: flex;
  flex: 0 0 auto;
  width: max-content;
  animation: tickerRun var(--ticker-pace) linear infinite;
  will-change: transform;
}

.ticker__group {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ticker__item {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-xxxs);
  /* The lane between one notice and the next is the item's own, and it is symmetric: half
     of it stands on either side. That is what lets the echo group follow the first at
     exactly the distance between any two notices, so the loop closes with no seam. */
  padding: 0 var(--spacing-sm);
  white-space: nowrap;
}

/* The house's lozenge — the mark between one notice and the next. */
.ticker__mark {
  flex: 0 0 auto;
  width: 0.375rem;
  height: 0.375rem;
  background-color: var(--golden-milk);
  transform: rotate(45deg);
}

.ticker__text {
  /* Univers Bold — the house's own face, upright, at the slot the design names Bold. Not the
     Extended width: the notice is a sentence to be read rather than a signboard to be shouted,
     and the roman width is what running copy wants. */
  font-family: var(--font-primary);
  font-weight: 600;
  /* Set a step above the caps this band used to carry: mixed case has no cap-height to
     stand on, and the copy is read in motion, so it wants the size back. */
  font-size: 0.875rem;
  line-height: 1;
  /* Case is the bulletin's own. The band sets no transform: the notice is written the way it
     is meant to be read — an address, a legal form, the shout that opens it — and a notice
     this long set in capitals is a wall, not a sentence. */
  color: var(--oxford-light);
}

/* ---- The incorporation suffixes ----
   GmbH, S.L. and SARL, set in Univers Bold Oblique — the oblique of the very drawing the
   notice is set in. The family here is 'Univers', not 'Univers Extended', and tokens.css
   declares that family's oblique faces at the same ranks as its uprights, so 600 with italic
   reaches Univers-BoldOblique.woff2 and nothing has to be synthesised: no sheared upright,
   no faux italic. The weight is written out rather than inherited, so the pairing — Bold with
   its own Oblique — is legible to whoever reads this next. */
.ticker__text em {
  font-weight: 600;
  font-style: italic;
}

/* ---- The control: the visitor's one say in the band ---- */
.ticker__control {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  padding: 0;
  border: none;
  /* Button geometry mandate: right angles above, a 3px round below. */
  border-radius: 0 0 3px 3px;
  background-color: var(--golden-milk);
  color: var(--deep-navy);
  font-size: 0.875rem;
  cursor: pointer;
  transition: background-color 0.2s var(--ease-out), color 0.2s var(--ease-out);
}

.ticker__control:hover {
  background-color: var(--parchment-cream);
  color: var(--deep-navy);
}

.ticker__control:active {
  /* The lever pressed: the gilt block takes the house's cognac. It cannot go dark here, as it
     once did — a dark press would sink into the black band and the control would seem to
     vanish under the visitor's own finger. */
  background-color: var(--cognac);
  color: var(--parchment-cream);
}

/* The gilt block is its own ring's ground, so the focus ring is drawn inside it in cream. */
.ticker__control:focus-visible {
  outline: 2px solid var(--parchment-cream);
  outline-offset: -3px;
}

/* ---- Holding still ---- */
.ticker__viewport:hover .ticker__track,
.ticker__viewport:focus-within .ticker__track,
.ticker.is-paused .ticker__track {
  animation-play-state: paused;
}

@keyframes tickerRun {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ---- The lane at width ---- */
@media (min-width: 768px) {
  .ticker__item {
    padding: 0 var(--spacing-md);
  }
}

@media (max-width: 575.98px) {
  .ticker__viewport {
    --ticker-fade: 2rem;
  }
}

/* ---- A reader who has asked for no motion ----
   The copy does not travel: it is set out once and wrapped, so every notice is legible at
   once. The echo group is dropped — it exists only to close a loop that no longer turns —
   the feathering goes with the movement, and the hold control goes too, because there is
   nothing left to hold. */
@media (prefers-reduced-motion: reduce) {
  .ticker__track {
    animation: none;
    width: 100%;
  }

  .ticker__group {
    flex-wrap: wrap;
    row-gap: var(--spacing-quark);
    padding: var(--spacing-quark) 0;
  }

  .ticker__group--echo {
    display: none;
  }

  .ticker__viewport {
    -webkit-mask-image: none;
    mask-image: none;
  }

  .ticker__control {
    display: none;
  }
}
