/* General Reset and Base Styles */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  scroll-behavior: smooth;
}

/* The scrollbar gutter is reserved whether or not a scrollbar is showing.
   Every dialog on the site sets body.style.overflow = "hidden" while it is open
   (~38 call sites in main.js); without a reserved gutter that removes the ~15px
   desktop scrollbar and the whole page reflows 15px wider behind the dialog. */
html {
  scrollbar-gutter: stable;
}

body {
  font-family: "Montserrat", sans-serif;
  /* Overridden by the customer refresh block at :12890, which paints the two
     hero washes over `--customer-paper-sink`. Kept warm here so the base layer
     never states a colour the palette does not contain. */
  background-color: var(--customer-paper-sink, #f7f2ec);
  /* clip is the same clipping as hidden, minus the scrollable-overflow region, so
     nothing can be scrolled sideways programmatically either. hidden is kept first
     as the fallback for browsers without clip.
     Both are marked !important because the only thing that can defeat them is an
     inline style, and no author layer outranks one: main.js writes
     body.style.overflow at ~39 sites, and a single one of them restoring "auto"
     re-enabled horizontal panning site-wide until the next navigation. The Y axis
     is unaffected — every dialog's body.style.overflow = "hidden" still resolves
     to X: clip, Y: hidden and still propagates to the viewport, so every modal
     scroll-lock behaves exactly as before. */
  overflow-x: hidden !important;
  overflow-x: clip !important;
  display: flex;
  flex-direction: column;
}

/* --- Header Styles --- */
.site-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px 5%;
  background-color: var(--customer-paper, #fdfaf6);
  box-shadow: 0 2px 10px rgba(45, 12, 12, 0.08);
  position: sticky;
  top: 0;
  z-index: 100;
}

.logo-container {
  display: flex;
  align-items: center;
  text-decoration: none;
}

.header-emblem {
  height: 50px;
  width: auto;
  margin-right: 15px;
}

.logo-text {
  font-family: "Montserrat", sans-serif;
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  max-width: 420px;
}

.logo-title {
  font-size: 16px;
  font-weight: 800;
  color: var(--customer-wine);
  letter-spacing: 0.35px;
  line-height: 1.05;
  text-transform: uppercase;
}

.logo-subtitle {
  font-size: 10px;
  font-weight: 700;
  color: var(--customer-wine);
  letter-spacing: 0.8px;
  line-height: 1.15;
  text-transform: uppercase;
}

.main-nav ul {
  list-style: none;
  display: flex;
  gap: 35px;
}

.nav-link {
  font-family: "Montserrat", sans-serif;
  text-decoration: none;
  color: #222;
  font-weight: 500;
  font-size: 17px;
  transition: color 0.3s ease;
}

.nav-link:hover,
.nav-link.active {
  color: var(--customer-wine-hover);
}

.user-profile {
  cursor: pointer;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  transition: box-shadow 0.2s ease;
}

.user-profile:hover {
  box-shadow: 0 0 0 2px var(--customer-primary-strong, #5f0d0d);
}

/* Customer announcements: shared with the products page and intentionally beside
   the profile control.

   Every declaration below is shadowed at equal specificity by the runtime sheet
   `customer-announcements.js` appends to <head> (:460 there), so none of it
   paints on any page that loads that script — which is all four customer pages.
   It is aligned with the runtime sheet anyway, because what it used to hold was
   a trap rather than dead weight: a `#fff4f2` pink disc that went `#fee2df` and
   `translateY(-1px)` on hover. That is the one hover motion the brief bans
   outright, sitting in the sheet every page loads first, one failed script
   request away from painting. Values mirror the runtime sheet exactly so the two
   can never disagree again; `#870b14` is its ink, `--apt-panel` its hover. */
.announcement-bell {
  position: relative;
  display: grid;
  width: 42px;
  height: 42px;
  place-items: center;
  margin-right: 7px;
  border: 0;
  border-radius: 50%;
  background: var(--customer-paper);
  color: var(--customer-wine);
  cursor: pointer;
  /* `transform` is no longer in the transition list: nothing here moves now, and
     a control that only changes colour has no reason to keep a transform on the
     compositor. */
  transition:
    background-color 0.2s ease,
    border-color 0.2s ease;
}
.announcement-bell:hover {
  background: var(--apt-panel);
}
.announcement-modal {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 22px;
  background: var(--ux-dlg-scrim);
  backdrop-filter: blur(5px);
}
.announcement-modal.is-open {
  display: flex;
}
.announcement-modal__card {
  position: relative;
  width: min(100%, 520px);
  overflow: hidden;
  border-radius: 22px;
  background: var(--customer-paper);
  box-shadow: 0 28px 70px rgba(20, 8, 8, 0.34);
}
.announcement-modal__hero {
  padding: 30px 62px 26px 30px;
  color: var(--customer-paper-sink);
  background: linear-gradient(135deg, var(--customer-wine), var(--customer-wine-light) 62%, #e56c37);
}
.announcement-modal__label {
  margin: 0 0 9px;
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  opacity: 0.86;
}
.announcement-modal__title {
  margin: 0;
  font-size: clamp(1.35rem, 3vw, 1.85rem);
  line-height: 1.2;
}
.announcement-modal__body {
  padding: 25px 30px 30px;
}
.announcement-modal__message {
  margin: 0;
  color: #4b5563;
  font-size: 0.95rem;
  line-height: 1.65;
  white-space: pre-line;
}
.announcement-modal__date {
  display: inline-flex;
  margin-top: 17px;
  padding: 7px 10px;
  border-radius: 8px;
  background: #fff3ed;
  color: var(--customer-wine);
  font-size: 0.77rem;
  font-weight: 700;
}
.announcement-modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 25px;
}
.announcement-modal__button,
.announcement-modal__close {
  border: 0;
  cursor: pointer;
  font: inherit;
}
.announcement-modal__button {
  padding: 11px 17px;
  border-radius: var(--ux-dlg-radius, 8px);
  background: var(--customer-wine);
  color: #f7f2ec;
  font-weight: 800;
  text-decoration: none;
}
.announcement-modal__close {
  position: absolute;
  top: 15px;
  right: 15px;
  display: grid;
  width: 34px;
  height: 34px;
  place-items: center;
  border-radius: 50%;
  background: rgba(247, 242, 236, 0.18);
  color: var(--customer-paper-sink);
  font-size: 21px;
}

/* --- Hero Section Styles --- */
.hero-section {
  position: relative;
  display: flex;
  align-items: center;
  padding: 0 5%;
  min-height: calc(100vh - 80px);

  /* PURE CSS GEOMETRIC BACKGROUND */
  background:
    radial-gradient(
      circle at 85% 20%,
    rgba(247, 242, 236, 0.15) 0%,
      transparent 40%
    ),
    linear-gradient(
      115deg,
      transparent 25%,
    rgba(247, 242, 236, 0.08) 26%,
    rgba(247, 242, 236, 0.03) 45%,
      transparent 46%
    ),
    linear-gradient(
      45deg,
      transparent 65%,
    rgba(247, 242, 236, 0.1) 66%,
    rgba(247, 242, 236, 0.04) 75%,
      transparent 76%
    ),
    linear-gradient(
      -35deg,
      transparent 35%,
    rgba(247, 242, 236, 0.05) 36%,
    rgba(247, 242, 236, 0.02) 45%,
      transparent 46%
    ),
    linear-gradient(145deg, var(--customer-wine, #6b202b) 0%, var(--customer-wine-light, #b01c1c) 40%, var(--customer-wine, #6b202b) 100%);
}

.hero-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  max-width: 95%;
  margin: 0 auto;
}

.hero-content-left {
  flex: 1;
  color: var(--customer-paper-sink, #f7f2ec);
  padding-right: 20px;
}

.hero-title {
  font-family: "Montserrat", sans-serif;
  font-size: 61px;
  font-weight: 800;
  line-height: 1.25;
  margin-bottom: 45px;
  text-transform: uppercase;
  text-shadow: 0 2px 10px rgba(45, 12, 12, 0.32);
}

/* The wording arrives from /api/site-settings (see hero-title.js), so on a
   first visit the heading is briefly empty. Hold three lines of space for it
   so the buttons and SDG strip below don't jump when the title lands. */
.hero-title:empty {
  min-height: 3.75em; /* 3 lines at the 1.25 line-height above */
  min-height: 3lh; /* exact, where the unit is supported */
}

.btn-browse {
  font-family: "Montserrat", sans-serif;
  background-color: #eef224; /* solid yellow */
  color: #3d0808; /* dark maroon ink */
  border: 2px solid #eef224;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 16px 40px;
  font-size: 18px;
  font-weight: 800;
  border-radius: var(--apt-radius, 8px);
  cursor: pointer;
  box-shadow: 0 8px 18px rgba(30, 10, 10, 0.18);
  transition:
    background-color 0.3s ease,
    border-color 0.3s ease,
    color 0.3s ease,
    transform 0.1s ease,
    box-shadow 0.1s ease;
}

.btn-browse:hover {
  background-color: #c8cc00; /* darker yellow on hover */
  border-color: #c8cc00;
  color: #3d0808;
}

.btn-browse:active {
  transform: scale(0.97);
  box-shadow: 0 8px 18px rgba(30, 10, 10, 0.18);
}

/* --- Hero Buttons Container --- */
.hero-buttons {
  display: flex;
  gap: 20px;
  flex-wrap: wrap; /* Ensures buttons stack safely if the screen gets too narrow */
}

/* --- New Appointment Button Styles --- */
.btn-appointment {
  font-family: "Montserrat", sans-serif;
  background-color: rgba(247, 242, 236, 0.14);
  color: #f7f2ec;
  border: 2px solid rgba(247, 242, 236, 0.82);
  padding: 16px 40px;
  font-size: 18px;
  font-weight: 800;
  border-radius: var(--apt-radius, 8px);
  cursor: pointer;
  box-shadow: 0 8px 18px rgba(30, 10, 10, 0.18);
  transition:
    background-color 0.3s ease,
    border-color 0.3s ease,
    color 0.3s ease,
    transform 0.1s ease,
    box-shadow 0.1s ease;
}

.btn-appointment:hover {
  background-color: #f7f2ec; /* fills to cream — not pure white */
  border-color: #f7f2ec;
  color: #3d0808; /* dark maroon text */
}

.btn-appointment:active {
  transform: scale(0.97);
  box-shadow: 0 8px 18px rgba(30, 10, 10, 0.18);
}

.hero-content-right {
  flex: 1;
  display: flex;
  justify-content: flex-end;
  align-items: center;
}

.hero-graphic {
  width: 70%;
  max-width: 650px;
  height: auto;
  background-color: #fdfaf6;
  border-radius: 50%;
  box-shadow: 0 14px 34px rgba(35, 8, 8, 0.26);
}

/* Scroll Indicator Styles and Animation */
.scroll-indicator {
  position: absolute;
  bottom: 30px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  color: rgba(247, 242, 236, 0.7);
  text-decoration: none;
  font-family: "Montserrat", sans-serif;
  font-size: 14px;
  font-weight: 600;
  transition: color 0.3s ease;
  animation: bounce 2s infinite;
}

.scroll-indicator:hover {
  color: var(--customer-paper);
}

.scroll-icon {
  margin-top: 8px;
}

@keyframes bounce {
  0%,
  20%,
  50%,
  80%,
  100% {
    transform: translateY(0) translateX(-50%);
  }
  40% {
    transform: translateY(-12px) translateX(-50%);
  }
  60% {
    transform: translateY(-6px) translateX(-50%);
  }
}

/* --- About Us Wrapper --- */
.about-wrapper {
  display: flex;
  flex-direction: column;
  width: 100%;
}

/* --- About Us Section Styles --- */
.about-section {
  background-color: #fef8f8;
  padding: 80px 5%;
  display: flex;
  align-items: center;
}

.about-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;
  gap: 80px;
}

.about-content-left {
  flex: 1.1;
  padding-right: 20px;
}

.section-title {
  font-family: "Montserrat", sans-serif;
  font-size: 55px;
  font-weight: 900;
  color: var(--customer-wine);
  margin-bottom: 30px;
  text-transform: uppercase;
  letter-spacing: 1px;
}

.section-text {
  font-size: 18px;
  line-height: 1.7;
  color: #333;
  margin-bottom: 25px;
  text-align: justify;
}

.section-text strong {
  font-weight: 700;
  color: #111;
}

.about-content-right {
  flex: 0.9;
  display: flex;
  justify-content: flex-end;
}

.features-card {
  background-color: var(--customer-paper);
  padding: 75px 70px;
  border-radius: var(--ux-card-radius);
  box-shadow: 0 15px 50px rgba(176, 28, 28, 0.08);
  display: grid;
  grid-template-columns: 1fr 1fr;
  row-gap: 50px;
  column-gap: 70px;
  position: relative; /* ADDED: Allows us to tuck the link into the corner */
}

/* --- See More Link Styles --- */
.see-more-link {
  position: absolute;
  bottom: 23px;
  right: 175px;
  font-family: "Montserrat", sans-serif;
  font-size: 14px;
  font-weight: 700;
  color: var(--customer-wine);
  text-decoration: none;
  transition: color 0.3s ease;
}

.see-more-link:hover {
  text-decoration: underline;
  color: var(--customer-wine-hover); /* Darkens the text color on hover */
}

.feature-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.feature-item img {
  width: 55px;
  height: 55px;
  object-fit: contain;
  margin-bottom: 15px;
}

.feature-item span {
  font-family: "Montserrat", sans-serif;
  color: var(--customer-wine);
  font-weight: 700;
  font-size: 16px;
}

/* --- Vision & Mission Section Styles --- */
.vision-section {
  background-color: var(--customer-paper);
  padding: 90px 5%;
  display: flex;
  align-items: center;
}

.mission-section {
  background-color: #fef8f8;
  padding: 90px 5%;
  display: flex;
  align-items: center;
}

.vision-container,
.mission-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 90%;
  max-width: 1200px;
  margin: 0 auto;
  gap: 60px;
}

.vision-content-left,
.vision-content-right,
.mission-content-left,
.mission-content-right {
  flex: 1;
}

.vision-img {
  width: 100%;
  max-width: 550px;
  border-radius: 12px;
  box-shadow: 0 10px 30px rgba(45, 12, 12, 0.1);
  display: block;
}

.vm-title {
  font-family: "Montserrat", sans-serif;
  font-size: 48px;
  font-weight: 900;
  color: var(--customer-wine);
  text-transform: uppercase;
  text-align: center;
  margin-bottom: 25px;
  letter-spacing: 2px;
}

.vm-text {
  font-size: 22px;
  line-height: 1.6;
  color: #222;
  text-align: center;
  font-weight: 500;
}

/* --- Organic Image Shape for Mission Section ---
   The wrapper used to carry two decorative pseudo-element blobs behind the
   photo — a dark red `::before` and a pale grey `::after`, each hanging below
   the wrapper. They were removed by request: with a deck of admin-uploaded
   photos on top of them they read as stray hard-coded shapes rather than as
   part of the design, and their overhang was the only reason the wrapper needed
   a bottom margin reserve (see the note further down this file). The organic
   silhouette itself is unchanged — it lives on the photo, and now on the deck
   card too. */
.blob-wrapper {
  position: relative;
  width: 100%;
  max-width: 480px;
  aspect-ratio: 1;
  margin: 0 auto;
}

.mission-img {
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50% 50% 40% 60% / 60% 40% 60% 40%;
  box-shadow: inset 0 0 20px rgba(45, 12, 12, 0.1);
}

/* =========================================
   HOMEPAGE SERVICES PREVIEW SECTION
   ========================================= */
.services-preview-section {
  padding: 80px 5%;
  background-color: var(--customer-paper); /* Matches the mission section background */
}

/* Override standard carousel heights for the landscape look */
.landscape-carousel {
  height: 400px;
  max-width: 1200px;
}

/* Shape the items into wide rectangles */
.landscape-carousel .carousel-item {
  width: 450px;
  height: 320px;
}

.landscape-card {
  height: 100%;
  border-radius: var(--ux-card-radius);
  transition:
    transform 0.3s ease,
    box-shadow 0.3s ease,
    background-color 0.3s ease;
  cursor: default; /* Remove pointer since there's no modal on homepage */
}

/* Shorten the image so the text fits nicely in the rectangle */
.landscape-card .card-img-holder {
  height: 170px;
}

/* Faint red hover effect */
.landscape-card:hover {
  box-shadow: 0 15px 35px rgba(176, 28, 28, 0.15);
  border: 1px solid #fcdbdb; /* Soft red outline on hover */
}

/* Centered Button Below Carousel */
.view-all-container {
  display: flex;
  justify-content: center;
  margin-top: 30px;
}

.view-all-btn {
  background-color: var(--customer-wine);
  color: #f7f2ec;
  border: 2px solid var(--customer-wine);
  padding: 16px 45px;
  font-family: "Montserrat", sans-serif;
  font-size: 16px;
  font-weight: 700;
  border-radius: var(--apt-radius, 8px); /* The card corner, not a pill */
  text-decoration: none;
  box-shadow: 0 6px 16px rgba(128, 24, 18, 0.18);
  transition:
    background-color 0.3s ease,
    transform 0.1s ease,
    box-shadow 0.1s ease;
}

.view-all-btn:hover {
  background-color: #3d0808;
  border-color: #3d0808;
  color: #f7f2ec;
  box-shadow: 0 6px 16px rgba(128, 24, 18, 0.18);
}

.view-all-btn:active {
  transform: scale(0.97) translateY(0);
}

/* --- NEW ORIGINAL FOOTER STYLES --- */
.site-footer {
  background-color: var(--customer-wine, var(--customer-wine));
  color: var(--customer-paper-sink, #f7f2ec);
  padding: 60px 5% 20px;
  font-family: "Montserrat", sans-serif;
  margin-top: auto;
}

.footer-container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  gap: 40px;
  max-width: 1400px;
  margin: 0 auto 40px;
}

.footer-col {
  flex: 1;
  min-width: 200px;
}

.brand-col {
  flex: 1.5; /* Gives the brand section a bit more space */
}

.contact-col {
  flex: 1.3; /* Gives contact section room for long addresses */
}

.footer-logo-row {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
}

.footer-logo {
  height: 50px;
  margin-right: 12px;
  background-color: var(--customer-paper, #fdfaf6);
  border-radius: 50%;
  padding: 3px;
}

.footer-brand {
  font-family: "Montserrat", sans-serif;
  font-size: 26px;
  font-weight: 800;
  color: var(--customer-paper-sink, #f7f2ec);
}

.footer-desc {
  font-size: 16px;
  line-height: 1.6;
  color: rgba(247, 242, 236, 0.9);
}

.footer-heading {
  font-family: "Montserrat", sans-serif;
  font-size: 22px;
  font-weight: 700;
  margin-bottom: 25px;
  color: var(--customer-paper-sink, #f7f2ec);
}

.footer-menu,
.contact-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.footer-menu li,
.contact-list li {
  margin-bottom: 15px;
}

.footer-menu a,
.footer-link {
  color: rgba(247, 242, 236, 0.9);
  text-decoration: none;
  font-size: 16px;
  transition: color 0.3s ease;
}

.footer-menu a:hover,
.footer-link:hover {
  color: #eef224; /* Yellow matching the browse button */
}

.footer-text {
  font-size: 16px;
  color: rgba(247, 242, 236, 0.9);
  margin-bottom: 10px;
}

.contact-list li {
  display: flex;
  align-items: flex-start;
  font-size: 16px;
  color: rgba(247, 242, 236, 0.9);
  line-height: 1.5;
}

.contact-icon {
  flex-shrink: 0;
  margin-right: 12px;
  margin-top: 2px;
  color: var(--customer-paper-sink, #f7f2ec);
}

.footer-bottom {
  text-align: center;
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;
}

.footer-line {
  height: 1px;
  background-color: rgba(247, 242, 236, 0.24);
  margin-bottom: 20px;
}

.footer-bottom p {
  font-size: 14px;
  color: rgba(247, 242, 236, 0.8);
}

/* =========================================
   SERVICES PAGE STYLES
   ========================================= */
.services-page-body {
  background:
    radial-gradient(
      circle at 8% 10%,
      rgba(241, 237, 18, 0.18),
      transparent 22rem
    ),
    radial-gradient(
      circle at 90% 18%,
      rgba(107, 32, 43, 0.12),
      transparent 24rem
    ),
    linear-gradient(135deg, #fffaf0 0%, #f5f7f2 46%, #fffdf8 100%);
}

.services-top-bar {
  background: rgba(247, 242, 236, 0.85);
  padding: 40px 5%;
  border-bottom: 1px solid rgba(107, 32, 43, 0.12);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

.services-container {
  max-width: 1400px;
  margin: 0 auto;
}

.services-list-section {
  padding: 40px 5% 95px;
  background:
    radial-gradient(
      1200px 400px at 50% 0%,
      rgba(107, 32, 43, 0.08),
      transparent 70%
    ),
    linear-gradient(
      180deg,
      rgba(247, 242, 236, 0.3) 0%,
      rgba(245, 247, 242, 0.5) 100%
    );
  position: relative;
}

.services-list-header {
  max-width: 760px;
  margin: 0 auto 36px;
  text-align: center;
}

.services-list-header .services-kicker {
  margin: 0 0 8px;
  font-size: 0.8rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  color: var(--customer-wine);
  text-transform: uppercase;
  display: inline-block;
  padding: 6px 14px;
  border-radius: 999px;
  background: rgba(107, 32, 43, 0.08);
  border: 1px solid rgba(107, 32, 43, 0.14);
}

.services-list-header h2 {
  margin: 12px 0 10px;
  font-size: clamp(2rem, 3.8vw, 2.8rem);
  font-weight: 900;
  color: #241f21;
  letter-spacing: -0.04em;
  line-height: 1.1;
}

.services-list-header p {
  margin: 0;
  color: #5c626e;
  font-size: 1.05rem;
  line-height: 1.65;
}

.services-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: 24px;
  align-items: stretch;
}

.services-grid .service-card {
  --service-accent: var(--customer-wine);
  width: 100%;
  min-width: 0;
  min-height: 100%;
  border: 1px solid rgba(107, 32, 43, 0.14);
  border-radius: var(--ux-card-radius);
  overflow: hidden;
  background:
    linear-gradient(
      145deg,
      rgba(247, 242, 236, 0.97),
      rgba(255, 248, 238, 0.9)
    ),
    var(--customer-paper);
  box-shadow:
    0 18px 42px rgba(61, 35, 28, 0.09),
    inset 0 1px 0 rgba(247, 242, 236, 0.95);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  transition:
    box-shadow 0.3s ease,
    border-color 0.3s ease;
}

.services-grid .service-card:hover {
  transform: none;
  border-color: rgba(107, 32, 43, 0.28);
  box-shadow:
    0 24px 52px rgba(128, 24, 18, 0.14),
    inset 0 1px 0 rgba(247, 242, 236, 1);
}

.service-image-trigger,
.services-grid .service-image-placeholder,
.services-grid .card-img-holder {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: #f6f0e8;
  border-bottom: 1px solid rgba(107, 32, 43, 0.08);
}

.service-image-trigger {
  display: block;
  padding: 0;
  border: 0;
  cursor: zoom-in;
  text-align: left;
}

.service-image-trigger img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: center;
  transition: transform 0.45s ease;
}

.service-image-trigger::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 45%, rgba(41, 14, 11, 0.62));
  pointer-events: none;
}

.service-image-trigger:hover img,
.service-image-trigger:focus-visible img {
  transform: scale(1.05);
}

.service-image-preview-label {
  position: absolute;
  right: 14px;
  bottom: 14px;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 10px;
  border: 1px solid rgba(247, 242, 236, 0.48);
  border-radius: 999px;
  background: rgba(41, 14, 11, 0.64);
  color: var(--customer-paper-sink);
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.service-image-preview-label i {
  font-size: 0.76rem;
}

.services-grid .service-image-placeholder {
  display: grid;
  place-items: center;
  background:
    radial-gradient(
      circle at 76% 20%,
      rgba(241, 237, 18, 0.35),
      transparent 24%
    ),
    linear-gradient(135deg, #f7eee3, #eee4d8);
  color: #8b7062;
}

.service-image-placeholder__content {
  display: grid;
  justify-items: center;
  gap: 8px;
  font-size: 0.78rem;
  font-weight: 700;
}

.service-image-placeholder__content i {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(107, 32, 43, 0.16);
  border-radius: 14px;
  background: rgba(247, 242, 236, 0.58);
  color: var(--customer-wine);
  font-size: 1rem;
}

.services-grid .card-content {
  padding: 20px 22px 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  flex: 1;
}

.service-card-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.service-chip {
  width: fit-content;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 800;
  color: var(--customer-wine);
  background: linear-gradient(
    135deg,
    rgba(107, 32, 43, 0.1),
    rgba(241, 237, 18, 0.16)
  );
  border: 1px solid rgba(107, 32, 43, 0.14);
}

.service-index {
  color: rgba(107, 32, 43, 0.66);
  font-size: 0.72rem;
  font-weight: 900;
  letter-spacing: 0.1em;
}

.services-grid .card-title {
  text-align: left;
  margin-bottom: 0;
  font-size: 1.16rem;
  font-weight: 900;
  color: #2a2020;
  letter-spacing: -0.02em;
  line-height: 1.3;
}

.services-grid .card-desc {
  margin-bottom: 0;
  text-align: left;
  color: #5c626e;
  flex-grow: 1;
  font-size: 0.91rem;
  line-height: 1.6;
}

.service-card-footer {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 14px;
  margin-top: 8px;
  padding-top: 14px;
  border-top: 1px solid rgba(107, 32, 43, 0.1);
}

.services-grid .details-btn {
  position: relative;
  flex: 0 0 auto;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  width: auto;
  color: var(--customer-wine);
  font-family: "Montserrat", sans-serif;
  font-size: 0.82rem;
  font-weight: 900;
  margin: 0;
  padding: 2px 0 5px;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  /* No transition at all: the hover state must switch instantly, so neither the
     underline nor the colour is allowed to ease. This overrides the generic
     `.details-btn { transition: color 0.2s ease }` for the services grid only. */
  transition: none;
}

/* The underline exists only while the cursor (or keyboard focus) is on the link,
   and it appears and disappears instantly. It is drawn as a 2px ::after bar that
   is toggled with `display` — an un-animatable property — rather than with
   opacity or a scaled transform, so there is nothing for a transition to
   interpolate even if one were inherited from elsewhere. */
.services-grid .details-btn::after {
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  display: none;
}

.services-grid .details-btn:hover::after,
.services-grid .details-btn:focus-visible::after {
  display: block;
}

.services-grid .details-btn:hover,
.services-grid .details-btn:focus-visible {
  color: var(--customer-wine-hover);
  outline: none;
  /* The ::after bar is already the underline; suppress the generic
     `.details-btn:hover` text-decoration so the two cannot double up. */
  text-decoration: none;
}

.service-image-trigger:focus-visible,
.services-grid .details-btn:focus-visible {
  outline: 2px solid rgba(107, 32, 43, 0.45);
  outline-offset: -2px;
}

.service-modal-image-trigger {
  padding: 0;
  border: 0;
  cursor: zoom-in;
  appearance: none;
  -webkit-appearance: none;
}

.service-modal-image-trigger:focus-visible {
  outline: 2px solid rgba(107, 32, 43, 0.45);
  outline-offset: 3px;
}

/* --- Skeleton loading cards, shared by the services and products grids ------
   Rendered by `services-page/services.js` and `products-page/products.js`.
   Keep the original card skeletons. The shimmer moves with a transform rather
   than animating the background, and stops for reduced-motion preferences. */

@keyframes fmrcSkeletonSweep {
  from { transform: translate3d(-100%, 0, 0); }
  to { transform: translate3d(100%, 0, 0); }
}

.services-grid .service-skeleton-card,
.shop-grid .product-skeleton-card {
  pointer-events: none;
}

/* Keep the existing warm placeholder fill and rounded clipping. */
.service-skeleton-img,
.service-skeleton-line,
.product-skeleton-img,
.product-skeleton-line {
  position: relative;
  overflow: hidden;
  background: rgba(246, 240, 232, 0.92);
}

.service-skeleton-img::after,
.service-skeleton-line::after,
.product-skeleton-img::after,
.product-skeleton-line::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    rgba(225, 213, 201, 0) 0%,
    rgba(225, 213, 201, 0.95) 50%,
    rgba(225, 213, 201, 0) 100%
  );
  animation: fmrcSkeletonSweep 1.4s linear infinite;
}

/* `aspect-ratio` stays on the per-page rules and never on the grouped selector
   above, because `responsive.css` re-declares `.services-page-body
   .service-skeleton-img { aspect-ratio: 4 / 3 }` and loads after this file. */
.service-skeleton-img {
  width: 100%;
  aspect-ratio: 16 / 10;
  border-bottom: 1px solid rgba(107, 32, 43, 0.08);
}

/* Its own box, deliberately not a second class on `.product-img-wrapper`: that
   wrapper sets `background-color: #ffffff` at the same specificity but later in
   this file, so it would win and paint the skeleton white. */
.product-skeleton-img {
  width: 100%;
  aspect-ratio: 1 / 1;
  border-bottom: 1px solid rgba(107, 32, 43, 0.08);
}

.service-skeleton-line,
.product-skeleton-line {
  display: block;
  height: 14px;
  border-radius: 7px;
}

@media (prefers-reduced-motion: reduce) {
  .service-skeleton-img::after,
  .service-skeleton-line::after,
  .product-skeleton-img::after,
  .product-skeleton-line::after {
    display: none;
  }
}

@media (max-width: 600px) {
  .services-grid .card-content {
    padding: 18px;
  }

  .service-card-footer {
    align-items: flex-start;
    flex-direction: column;
  }
}

.services-main-title {
  font-family: "Montserrat", sans-serif;
  font-size: 42px;
  font-weight: 900;
  color: var(--customer-wine);
  text-transform: uppercase;
  margin-bottom: 30px;
  text-align: center;
  letter-spacing: -0.04em;
}

/* Controls: Search & Filter */
.controls-wrapper {
  display: flex;
  justify-content: center;
  gap: 20px;
  flex-wrap: wrap;
}

.search-box,
.category-box {
  display: flex;
  align-items: center;
  background: var(--customer-paper);
  border: 1px solid #ccc;
  border-radius: 8px;
  padding: 10px 20px;
  width: 100%;
  max-width: 400px;
  transition:
    border-color 0.3s ease,
    box-shadow 0.3s ease;
}

.search-box:focus-within,
.category-box:focus-within {
  border-color: var(--customer-wine);
  box-shadow: 0 0 0 3px rgba(176, 28, 28, 0.1);
}

.search-input {
  border: none;
  outline: none;
  width: 100%;
  margin-left: 10px;
  font-size: 16px;
  font-family: "Montserrat", sans-serif;
  color: #333;
}

.category-dropdown {
  border: none;
  outline: none;
  width: 100%;
  font-size: 16px;
  font-family: "Montserrat", sans-serif;
  color: #555;
  background: transparent;
  cursor: pointer;
}

/* =========================================
   3D CAROUSEL STYLES
   ========================================= */
.services-carousel-section {
  padding: 60px 5% 100px;
  overflow: hidden;
  background-color: #f8f9fc;
}

.carousel-wrapper {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 550px; /* Adjust based on your card content height */
  max-width: 1200px;
  margin: 0 auto;
  /* The off-stage cards are absolutely positioned at translateX(±110%) and ±200%,
     so without clipping they made the document 888px wide inside a 375px phone
     viewport — 2.4x the screen. Desktop hid it because body's overflow-x clips at
     the viewport; on iOS the page just zoomed out to fit the 888px.
     overflow-x: clip (not hidden) keeps the y axis visible, so the active card's
     drop shadow is not sliced off at the top and bottom, and it does not create a
     scroll container. Browsers without clip fall back to today's behaviour. */
  overflow-x: clip;
  overflow-y: visible;
  overflow-clip-margin: 10px;
}

.carousel-track {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  perspective: 1000px; /* Adds 3D depth */
}

.carousel-item {
  position: absolute;
  width: 320px; /* Fixed width for uniformity */
  height: 450px;
  /* `z-index` is deliberately not in this list. Stacking order is an integer
     with no visible intermediate state, so interpolating it bought nothing and
     made every 6s advance re-sort paint order for the whole track. The state
     classes still swap `z-index` — instantly, which is what was wanted. */
  transition:
    transform 0.6s cubic-bezier(0.25, 0.8, 0.25, 1),
    opacity 0.6s ease;
  opacity: 0;
  z-index: 1;
  pointer-events: none; /* Prevents clicking hidden cards */
}

/* Make sure the card fills the carousel item perfectly */
.carousel-item .service-card {
  width: 100%;
  height: 100%;
  margin: 0;
}

/* --- Carousel States --- */
.carousel-item.active {
  transform: translateX(0) scale(1.05);
  z-index: 3;
  opacity: 1;
  pointer-events: auto;
  box-shadow: 0 25px 50px rgba(176, 28, 28, 0.15); /* Stronger shadow for the front card */
}

.carousel-item.prev {
  transform: translateX(-110%) scale(0.85);
  z-index: 2;
  opacity: 0.6;
  pointer-events: auto;
  cursor: pointer; /* Allows clicking the side card to bring it forward */
}

.carousel-item.next {
  transform: translateX(110%) scale(0.85);
  z-index: 2;
  opacity: 0.6;
  pointer-events: auto;
  cursor: pointer;
}

/* For screens wider to show 5 cards (optional extra depth) */
.carousel-item.prev-hidden {
  transform: translateX(-200%) scale(0.7);
  opacity: 0.2;
}
.carousel-item.next-hidden {
  transform: translateX(200%) scale(0.7);
  opacity: 0.2;
}

/* --- Carousel Navigation Buttons --- */
.carousel-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background-color: var(--customer-wine);
  color: var(--customer-paper-sink, #f7f2ec);
  border: none;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  z-index: 10;
  box-shadow: 0 2px 8px rgba(58, 18, 18, 0.16);
  transition:
    background-color 0.2s ease,
    transform 0.1s ease;
}

/* `translateY(-50%)` is what centres this button, so every override of
   `transform` has to repeat it or the arrow jumps out of vertical centre. Hover
   is the fill only; the 1.1 growth it used to do was the one motion the owner
   ruled out. */
.carousel-btn:hover {
  background-color: var(--customer-wine-hover);
  transform: translateY(-50%);
  box-shadow: 0 2px 8px rgba(58, 18, 18, 0.16);
}

.carousel-btn:active {
  transform: translateY(-50%) scale(0.97);
}

.carousel-btn:focus-visible {
  outline: 3px solid rgba(241, 237, 18, 0.55);
  outline-offset: 2px;
}

.prev-btn {
  left: 10px;
}
.next-btn {
  right: 10px;
}

/* --- New Modal Image Styles --- */
.modal-img-holder {
  width: 100%;
  height: 250px;
  border-radius: 12px;
  overflow: hidden;
  margin-bottom: 25px;
  background-color: #f3f4f6;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 15px rgba(43, 43, 49, 0.05);
}

.modal-img-holder img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

/* Make the image inside the modal clickable */
.modal-img-holder {
  cursor: pointer;
}
.modal-img-holder img {
  transition: transform 0.3s ease;
}
.modal-img-holder:hover img {
  transform: scale(1.03); /* Slight zoom to indicate it's clickable */
}

/* Product View Info modal image opens the fullscreen preview. */
#productInfoModal .modal-img-holder,
#productInfoModal .modal-img-holder img {
  cursor: zoom-in;
}

/* Same affordance for the "Ordering for:" thumbnail in Edit Details, so every
   product image on this page behaves the same way. */
#editInfoModal .edit-info-guide img {
  cursor: zoom-in;
  transition: transform 0.3s ease;
}
#editInfoModal .edit-info-guide img:hover {
  transform: scale(1.03);
}

/* =========================================
   FULLSCREEN IMAGE LIGHTBOX STYLES
   ========================================= */
.image-lightbox-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  /* Same-property fallback, not two properties: on iOS 100vh is the large
     viewport, so a lightbox sized in vh centres its image in a box taller than
     the screen and pushes the edges under the toolbar. */
  height: 100vh;
  height: 100dvh;
  background-color: var(--ux-dlg-scrim-media);
  z-index: 10000; /* Must be higher than the regular modal (9999) */
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;

  /* Hidden by default */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.3s ease,
    visibility 0.3s ease;
}

.image-lightbox-overlay.show-lightbox {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.lightbox-img {
  max-width: 90%;
  max-height: 90vh;
  border-radius: 8px;
  box-shadow: 0 10px 40px rgba(43, 43, 49, 0.5);
  object-fit: contain;
  transform: scale(0.9);
  transition: transform 0.3s ease;
}

.image-lightbox-overlay.show-lightbox .lightbox-img {
  transform: scale(1);
}

.close-lightbox-btn {
  position: absolute;
  top: 25px;
  right: 35px;
  background: none;
  border: none;
  color: #ffffff;
  font-size: 45px;
  cursor: pointer;
  transition:
    color 0.2s ease,
    transform 0.2s ease;
}

.close-lightbox-btn:hover {
  color: var(--customer-wine-hover);
  transform: scale(1.1);
}

/* Adjust mobile height for the image */
@media (max-width: 768px) {
  .modal-img-holder {
    height: 180px;
  }

  .hero-container,
  .about-container {
    flex-direction: column;
    text-align: center;
    padding: 50px 0;
  }

  /* Add this to perfectly center both buttons on phones */
  .hero-buttons {
    justify-content: center;
  }
}

/* Responsive adjustments for mobile */
@media (max-width: 768px) {
  .carousel-item.prev {
    transform: translateX(-70%) scale(0.8);
    opacity: 0.3;
  }
  .carousel-item.next {
    transform: translateX(70%) scale(0.8);
    opacity: 0.3;
  }
  .carousel-wrapper {
    height: 480px;
  }
  .carousel-item {
    width: 280px;
    height: 400px;
  }
  .prev-btn {
    left: 0px;
  }
  .next-btn {
    right: 0px;
  }
}

.service-card {
  background: var(--customer-paper, #fdfaf6);
  border-radius: var(--ux-card-radius);
  overflow: hidden;
  box-shadow: 0 8px 20px rgba(65, 16, 16, 0.06);
  transition:
    transform 0.3s ease,
    box-shadow 0.3s ease;
  display: flex;
  flex-direction: column;
  width: calc(25% - 30px); /* 4 cards per row on large screens */
  min-width: 300px; /* Prevents cards from getting too skinny */
}

.service-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 20px 40px rgba(176, 28, 28, 0.12); /* Faint red glow on hover */
}

.card-img-holder {
  width: 100%;
  aspect-ratio: 1 / 1;
  background-color: var(--customer-paper-sink, #f7f2ec);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.card-img-holder img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  transition: transform 0.5s ease;
}

.service-card:hover .card-img-holder img {
  transform: scale(1.05);
}

.card-content {
  padding: 25px;
  display: flex;
  flex-direction: column;
  flex-grow: 1;
}

.card-title {
  font-family: "Montserrat", sans-serif;
  font-size: 20px;
  font-weight: 800;
  color: #222;
  margin-bottom: 12px;
  text-align: center;
}

.card-desc {
  font-size: 15px;
  line-height: 1.6;
  color: #666;
  margin-bottom: 20px;
  flex-grow: 1;
  text-align: justify;
}

.details-btn {
  background: none;
  border: none;
  color: var(--customer-wine);
  font-family: "Montserrat", sans-serif;
  font-size: 14px;
  font-weight: 700;
  text-align: center; /* Centers the button text */
  cursor: pointer;
  padding: 0;
  width: 100%; /* Ensures the button takes full width so text-align center works */
  transition: color 0.2s ease;
}

.details-btn:hover {
  color: var(--customer-wine-hover);
  text-decoration: none;
}

.details-btn:hover .details-btn-label {
  text-decoration: underline;
  text-underline-offset: 4px;
}

.details-btn i {
  display: inline-block;
  text-decoration: none;
}

/* =========================================
   MODAL (POPUP) STYLES
   ========================================= */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: var(--ux-dlg-scrim-media);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  z-index: 9999;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.3s ease,
    visibility 0.3s ease;
}

.modal-overlay.show-modal {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.modal-box {
  background: linear-gradient(
    135deg,
    rgba(247, 242, 236, 0.96),
    rgba(255, 248, 238, 0.92)
  );
  border: 1px solid rgba(107, 32, 43, 0.16);
  width: 100%;
  max-width: 750px;
  border-radius: 32px;
  display: flex;
  flex-direction: column;
  position: relative;
  box-shadow:
    0 35px 90px rgba(45, 12, 12, 0.26),
    inset 0 1px 0 rgba(247, 242, 236, 0.95);
  transform: translateY(20px);
  transition: transform 0.3s ease;
  max-height: 90vh;
  overflow: hidden;
}

.modal-overlay.show-modal .modal-box {
  transform: translateY(0);
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 28px 36px 18px;
  flex-shrink: 0;
  background: rgba(255, 255, 255, 0.6);
  border-bottom: 1px solid rgba(150, 52, 73, 0.08);
}

.close-modal-btn {
  background: rgba(150, 52, 73, 0.06);
  border: 1px solid rgba(150, 52, 73, 0.12);
  border-radius: 50%;
  width: 40px;
  height: 40px;
  font-size: 24px;
  line-height: 1;
  font-weight: bold;
  color: var(--customer-wine);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.close-modal-btn:hover {
  background: var(--customer-wine-hover);
  color: #ffffff;
  transform: scale(1.05);
}

.modal-divider {
  height: 1px;
  width: 100%;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(107, 32, 43, 0.12),
    transparent
  );
  flex-shrink: 0;
}

.modal-scroll-area {
  padding: 28px 36px;
  overflow-y: auto;
  flex-grow: 1;
}

.modal-scroll-area::-webkit-scrollbar {
  width: 8px;
}
.modal-scroll-area::-webkit-scrollbar-track {
  background: rgba(247, 242, 236, 0.5);
}
.modal-scroll-area::-webkit-scrollbar-thumb {
  background: rgba(107, 32, 43, 0.25);
  border-radius: 10px;
}
.modal-scroll-area::-webkit-scrollbar-thumb:hover {
  background: var(--customer-wine-hover);
}

.modal-title {
  font-family: "Montserrat", sans-serif;
  font-size: 30px;
  font-weight: 900;
  color: var(--customer-wine-hover);
  margin: 0;
  letter-spacing: -0.03em;
}

.modal-desc {
  font-size: 16px;
  line-height: 1.65;
  color: #4b5563;
  margin-bottom: 25px;
}

.modal-subtitle {
  font-family: "Montserrat", sans-serif;
  font-size: 20px;
  font-weight: 800;
  color: var(--customer-wine);
  margin-bottom: 14px;
}

.feature-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 30px;
}

.chip {
  background: linear-gradient(
    135deg,
    rgba(107, 32, 43, 0.08),
    rgba(241, 237, 18, 0.14)
  );
  border: 1px solid rgba(107, 32, 43, 0.14);
  color: var(--customer-wine);
  padding: 8px 18px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 700;
  box-shadow: 0 4px 12px rgba(158, 20, 20, 0.05);
}

.modal-columns {
  display: flex;
  gap: 40px;
  margin-bottom: 30px;
}

.modal-col {
  flex: 1;
}

.modal-list {
  list-style-position: inside;
  padding: 0;
  color: #4b5563;
  font-size: 15px;
  line-height: 1.85;
}

.modal-actions {
  display: flex;
  justify-content: center;
  gap: 18px;
  flex-wrap: wrap;
  padding: 22px 36px;
  flex-shrink: 0;
  background: rgba(247, 242, 236, 0.7);
  border-top: 1px solid rgba(107, 32, 43, 0.08);
}

.modal-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: "Montserrat", sans-serif;
  font-size: 15px;
  font-weight: 800;
  padding: 14px 32px;
  border: 2px solid transparent;
  border-radius: var(--apt-radius, 8px);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color 0.2s ease,
    border-color 0.2s ease,
    color 0.2s ease,
    box-shadow 0.1s ease,
    transform 0.1s ease;
}

.outline-btn {
  background: var(--customer-paper);
  border-color: var(--customer-wine);
  color: var(--customer-wine);
  box-shadow: 0 6px 15px rgba(176, 28, 28, 0.2);
}

.outline-btn:hover:not(:disabled),
.outline-btn:focus-visible:not(:disabled) {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  box-shadow: 0 8px 20px rgba(128, 24, 18, 0.24);
  transform: none;
}

.solid-btn {
  background: var(--customer-wine);
  border-color: var(--customer-wine);
  color: var(--customer-paper-sink);
  box-shadow: 0 6px 15px rgba(176, 28, 28, 0.2);
}

.solid-btn:hover:not(:disabled),
.solid-btn:focus-visible:not(:disabled) {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  box-shadow: 0 8px 20px rgba(128, 24, 18, 0.28);
  transform: none;
}

.modal-btn:focus-visible {
  outline: 2px solid rgba(107, 32, 43, 0.42);
  outline-offset: 2px;
}

.modal-btn:active:not(:disabled) {
  transform: scale(0.97);
  box-shadow: 0 2px 5px rgba(176, 28, 28, 0.2);
}

.modal-btn:disabled,
.modal-btn.disabled {
  background: #eeeeee;
  border-color: #cccccc;
  color: #999999;
  box-shadow: none;
  cursor: not-allowed;
}

/* =========================================
   PRODUCTS / SHOPPING PAGE STYLES
   ========================================= */
.products-page-body {
  background:
    radial-gradient(
      circle at 8% 10%,
      rgba(241, 237, 18, 0.18),
      transparent 22rem
    ),
    radial-gradient(
      circle at 90% 18%,
      rgba(107, 32, 43, 0.12),
      transparent 24rem
    ),
    linear-gradient(135deg, #fffaf0 0%, #f5f7f2 46%, #fffdf8 100%);
}

/* --- Toolbar (Search & Filter) --- */
.products-toolbar {
  background: rgba(247, 242, 236, 0.85);
  padding: 24px 5%;
  border-bottom: 1px solid rgba(107, 32, 43, 0.12);
  box-shadow: 0 14px 36px rgba(50, 32, 27, 0.05);
  margin-bottom: 34px;
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

.toolbar-container {
  max-width: 1400px;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
}

.toolbar-search {
  display: flex;
  align-items: center;
  background: rgba(255, 254, 250, 0.9);
  border: 1px solid rgba(107, 32, 43, 0.14);
  border-radius: 999px;
  padding: 12px 22px;
  width: 100%;
  max-width: 460px;
  box-shadow:
    inset 0 1px 0 rgba(247, 242, 236, 0.9),
    0 8px 18px rgba(72, 27, 22, 0.04);
  transition: all 0.2s ease;
}

.toolbar-search:focus-within {
  border-color: rgba(107, 32, 43, 0.64);
  background: var(--customer-paper);
  box-shadow:
    0 0 0 4px rgba(158, 20, 20, 0.08),
    0 14px 28px rgba(72, 27, 22, 0.09);
}

.toolbar-search .search-input {
  border: none;
  outline: none;
  width: 100%;
  margin-left: 10px;
  font-size: 15px;
  font-family: "Montserrat", sans-serif;
  color: #222833;
  background: transparent;
}

.toolbar-actions {
  display: flex;
  gap: 15px;
  align-items: center;
  flex-wrap: wrap;
}

.category-dropdown-box {
  border: 1px solid rgba(107, 32, 43, 0.14);
  border-radius: 16px;
  padding: 10px 18px;
  background: rgba(255, 254, 250, 0.9);
  box-shadow: 0 6px 16px rgba(72, 27, 22, 0.04);
  transition: all 0.2s ease;
}

.category-dropdown-box:focus-within {
  border-color: rgba(107, 32, 43, 0.64);
  box-shadow: 0 0 0 4px rgba(158, 20, 20, 0.08);
}

.category-select {
  border: none;
  outline: none;
  font-family: "Montserrat", sans-serif;
  font-size: 14px;
  font-weight: 700;
  color: #343b49;
  background: transparent;
  cursor: pointer;
}

/* --- E-commerce Product Grid --- */
.shop-section {
  padding: 0 5% 80px;
}

.shop-grid {
  max-width: 1400px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 28px;
}

/* --- Product Card --- */
.shop-card {
  background: linear-gradient(
    135deg,
    rgba(247, 242, 236, 0.92),
    rgba(255, 248, 238, 0.82)
  );
  border-radius: var(--ux-card-radius);
  border: 1px solid rgba(107, 32, 43, 0.12);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow:
    0 20px 48px rgba(61, 35, 28, 0.09),
    inset 0 1px 0 rgba(247, 242, 236, 0.95);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  transition:
    box-shadow 0.3s ease,
    border-color 0.3s ease;
}

/* No vertical lift on hover — depth is expressed with light and border only. */
.shop-card:hover {
  box-shadow:
    0 25px 55px rgba(128, 24, 18, 0.14),
    inset 0 1px 0 rgba(247, 242, 236, 1);
  border-color: rgba(107, 32, 43, 0.28);
}

.product-img-wrapper {
  width: 100%;
  aspect-ratio: 1 / 1;
  background-color: var(--customer-paper);
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 1px solid rgba(107, 32, 43, 0.08);
  overflow: hidden;
}

.product-img-wrapper img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  cursor: zoom-in;
  transition: transform 0.4s ease;
}

.shop-card:hover .product-img-wrapper img {
  transform: scale(1.04);
}

/* --- Product / Service Image Lightbox Modal ---
   One panel, one hairline, one shadow. The white→cream gradient, the
   `blur(20px)` behind an already-opaque card and the 90px drop shadow were all
   doing the same job the scrim behind the panel does on its own. */
.lightbox-box {
  position: relative;
  max-width: 90vw;
  max-height: 85vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: var(--customer-paper, #fdfaf6);
  border: 1px solid var(--apt-line);
  border-radius: var(--ux-dlg-radius);
  padding: 24px;
  box-shadow: 0 18px 44px rgba(45, 12, 12, 0.26);
  /* The entrance, not a hover: the panel settles from 0.95 as the scrim fades
     in, which is the same open gesture every `ux-dlg` card uses. */
  transform: scale(0.95);
  opacity: 0;
  transition:
    transform 0.25s ease,
    opacity 0.25s ease;
}

.modal-overlay.show-modal .lightbox-box {
  transform: scale(1);
  opacity: 1;
}

.lightbox-box img {
  max-width: 80vw;
  max-height: 68vh;
  object-fit: contain;
  border-radius: var(--ux-dlg-radius-sm);
  box-shadow: 0 6px 16px rgba(45, 12, 12, 0.12);
}

.lightbox-box video {
  max-width: 80vw;
  max-height: 68vh;
  width: min(80vw, 860px);
  background: #0f172a;
  border-radius: var(--ux-dlg-radius-sm);
  box-shadow: 0 6px 16px rgba(45, 12, 12, 0.12);
}

.lightbox-box img[hidden],
.lightbox-box video[hidden] {
  display: none;
}

/* Load-failure state: replaces the broken-image icon with a readable message
   and an escape hatch, mirroring the admin media viewer. */
.lightbox-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: min(80vw, 420px);
  padding: 26px 22px;
  border: 1px dashed rgba(107, 32, 43, 0.35);
  border-radius: var(--ux-dlg-radius-sm);
  background: rgba(255, 245, 245, 0.9);
  text-align: center;
}

.lightbox-error[hidden] {
  display: none;
}

.lightbox-error-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--customer-wine);
  color: var(--customer-paper-sink);
  font-family: "Montserrat", sans-serif;
  font-size: 20px;
  font-weight: 800;
  line-height: 1;
}

.lightbox-error-text {
  margin: 0;
  font-family: "Montserrat", sans-serif;
  font-size: 14px;
  font-weight: 700;
  color: var(--customer-wine);
  line-height: 1.5;
}

.lightbox-error-link {
  font-family: "Montserrat", sans-serif;
  font-size: 13px;
  font-weight: 800;
  color: var(--customer-wine);
  text-decoration: underline;
}

.lightbox-error-link:hover {
  color: var(--customer-wine-hover);
}

.lightbox-caption {
  font-family: "Montserrat", sans-serif;
  font-size: 16px;
  font-weight: 800;
  color: var(--customer-wine);
  margin-top: 14px;
  margin-bottom: 0;
  text-align: center;
}

.lightbox-close-btn {
  position: absolute;
  top: -14px;
  right: -14px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--customer-wine);
  color: var(--customer-paper-sink, #f7f2ec);
  border: 2px solid var(--customer-paper, #fdfaf6);
  font-size: 24px;
  font-weight: bold;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8px 20px rgba(45, 12, 12, 0.28);
  transition: background-color 0.2s ease;
}

.lightbox-close-btn:hover {
  background: var(--customer-wine-hover);
}

.lightbox-close-btn:active {
  transform: scale(0.96);
}

.product-info {
  padding: 20px 22px;
  display: flex;
  flex-direction: column;
  flex-grow: 1;
}

.product-name {
  font-family: "Montserrat", sans-serif;
  font-size: 16px;
  font-weight: 800;
  color: #222833;
  margin-bottom: 8px;
  line-height: 1.4;
  letter-spacing: -0.02em;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.product-code-row {
  font-size: 12px;
  margin-bottom: 10px;
  font-family: "Montserrat", sans-serif;
}

.code-label {
  color: var(--customer-wine);
  font-weight: 800;
}

.code-value {
  color: #5c626e;
  font-weight: 600;
}

.product-price {
  font-family: "Montserrat", sans-serif;
  font-size: 22px;
  color: var(--customer-wine);
  font-weight: 900;
  margin-bottom: 12px;
  letter-spacing: -0.03em;
}

.product-stock-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: auto;
}

.product-rating-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

.rating-score {
  font-size: 12px;
  font-weight: 800;
  color: var(--customer-wine);
  font-family: "Montserrat", sans-serif;
}

.rating-stars {
  display: flex;
  align-items: center;
  gap: 3px;
}

.rating-star-btn {
  border: none;
  background: transparent;
  color: #dcdcdc;
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  padding: 0;
}

.rating-star-btn.filled {
  color: #f1ed12;
}

.rating-count {
  font-size: 11px;
  color: #6d7480;
  margin-left: 4px;
}

.stock-text {
  font-size: 12px;
  color: #6d7480;
}

.stock-badge {
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.in-stock {
  background-color: rgba(46, 125, 50, 0.12);
  color: #2e7d32;
  border: 1px solid rgba(46, 125, 50, 0.2);
}

.out-of-stock {
  background-color: rgba(107, 32, 43, 0.12);
  color: var(--customer-wine);
  border: 1px solid rgba(107, 32, 43, 0.2);
}

/* --- Card Footer Buttons ---
   Keep product actions in the same simple, level interaction system as the
   customer site's other buttons. */
.product-actions {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  padding: 12px 14px;
  gap: 8px;
  border-top: 1px solid rgba(107, 32, 43, 0.08);
  background: rgba(247, 242, 236, 0.6);
  align-items: stretch;
  border-radius: 0 0 26px 26px;
}

.action-btn {
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 40px;
  padding: 10px 8px;
  border: 2px solid transparent;
  /* 8px like every other filled action on the site. These two live on the
     products grid rather than the home page, but the shared `.ux-dlg__btn`
     family already carries 8px into the product modal that opens above them, so
     leaving the card buttons at 999px would put both shapes on one screen. */
  border-radius: var(--apt-radius, 8px);
  font-family: "Montserrat", sans-serif;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.01em;
  cursor: pointer;
  white-space: nowrap;
  line-height: 1;
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color 0.2s ease,
    color 0.24s ease,
    border-color 0.24s ease,
    box-shadow 0.1s ease,
    transform 0.1s ease;
}

.action-btn:focus-visible {
  outline: 2px solid rgba(107, 32, 43, 0.42);
  outline-offset: 2px;
}

.action-btn svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

/* Outline pair — View Info / Add to Cart */
.btn-view-info,
.btn-add-cart {
  background: var(--customer-paper);
  border-color: var(--customer-wine);
  color: var(--customer-wine);
  box-shadow: 0 6px 15px rgba(176, 28, 28, 0.16);
}

.btn-view-info:hover:not(.disabled):not(:disabled),
.btn-add-cart:hover:not(.disabled):not(:disabled),
.btn-view-info:focus-visible:not(.disabled):not(:disabled),
.btn-add-cart:focus-visible:not(.disabled):not(:disabled) {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  box-shadow: 0 8px 20px rgba(128, 24, 18, 0.22);
  transform: none;
}

.action-divider {
  width: 1px;
  align-self: stretch;
  background: rgba(107, 32, 43, 0.12);
}

/* Primary — Buy Now */
.btn-buy-now {
  background: var(--customer-wine);
  border-color: var(--customer-wine);
  color: var(--customer-paper-sink);
  box-shadow: 0 6px 15px rgba(176, 28, 28, 0.2);
}

.btn-buy-now:hover:not(.disabled):not(:disabled),
.btn-buy-now:focus-visible:not(.disabled):not(:disabled) {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  box-shadow: 0 8px 20px rgba(128, 24, 18, 0.28);
  transform: none;
}

/* Press feedback: an in-place squeeze, never a lift. */
.action-btn:active:not(.disabled):not(:disabled) {
  transform: scale(0.97);
  box-shadow: 0 2px 5px rgba(176, 28, 28, 0.2);
}

.action-btn.disabled,
.action-btn:disabled {
  background: #eeeeee;
  border-color: #cccccc;
  color: #999999;
  box-shadow: none;
  cursor: not-allowed;
}

@media (prefers-reduced-motion: reduce) {
  .action-btn,
  .modal-btn,
  .btn-place-order {
    transition: none;
  }
  .action-btn:active:not(.disabled):not(:disabled),
  .modal-btn:active:not(:disabled),
  .btn-place-order:active:not(.delete-btn):not(:disabled) {
    transform: none;
  }
}

@media (max-width: 1180px) {
  .shop-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .services-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 1024px) {
  .shop-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .services-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 768px) {
  .shop-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .services-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .product-actions {
    padding: 9px;
    gap: 5px;
  }

  .action-btn {
    font-size: 11px;
    padding: 9px 6px;
  }
}

/* =========================================
   HEADER RIGHT ACTIONS & CART ICON
   ========================================= */
.header-right-actions {
  display: flex;
  align-items: center;
  gap: 25px;
}

.cart-icon-container {
  position: relative;
  color: #333;
  cursor: pointer;
  display: flex;
  align-items: center;
  text-decoration: none;
  transition: color 0.2s ease;
}

.cart-icon-container:hover {
  color: var(--customer-wine-hover);
}

/* =========================================================
   CUSTOMER NAVBAR BADGES (ANNOUNCEMENT BELL & CART ICON)

   One rule, two counters, and until now two different looks: the announcements
   runtime sheet (customer-announcements.js) re-declares the bell half on the
   paper ladder, so the bell shipped as a flat `#b01c1c` disc with a warm ring
   while `.cart-badge` — its comma-grouped partner — kept the values below and
   shipped as a white-ringed red *gradient* with a neutral black shadow. Two
   22px counters, same size, same `top/right` offsets (the comment further down
   literally claims they "match the announcement bell badge exactly"), sitting
   4px apart in the same navbar. The four off-palette declarations now carry the
   bell's own values, so the claim is true and neither counter has white, black
   or a gradient in it.

   `!important` is kept on each one because it was already there and because
   `products-page/product.html` inlines a copy of this whole rule after
   main.css — that copy is warmed to match, and dropping the flag here would
   just hand the win back to whichever sheet loads last.
   ========================================================= */
.announcement-bell__badge,
.cart-badge {
  position: absolute;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px !important;
  min-width: 22px !important;
  max-width: 22px !important;
  height: 22px !important;
  min-height: 22px !important;
  max-height: 22px !important;
  padding: 0 !important;
  border: 2px solid var(--customer-paper) !important;
  border-radius: 50% !important;
  background: var(--apt-danger) !important;
  color: var(--customer-paper-sink) !important;
  font-family:
    "Montserrat",
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    Roboto,
    sans-serif !important;
  font-weight: 800 !important;
  line-height: 1 !important;
  text-align: center !important;
  white-space: nowrap !important;
  box-shadow: 0 2px 6px rgba(58, 18, 18, 0.28);
  pointer-events: none;
  user-select: none;
  font-size: 8px; /* Fallback for 2-3 digits */
  letter-spacing: -0.04em;
  z-index: 10;
  transition:
    transform 0.2s ease,
    opacity 0.2s ease;
}

.announcement-bell .announcement-bell__badge {
  top: -2px !important;
  right: -2px !important;
}

.cart-icon-container .cart-badge {
  /* Matches the announcement bell badge exactly. Both controls resolve to the
     same 38-46px box in the responsive layer, so identical offsets keep the
     two navbar counters visually aligned on every page. */
  top: -2px !important;
  right: -2px !important;
}

/* Character length dynamic scaling for perfect circle fitting */
.announcement-bell__badge[data-length="1"],
.cart-badge[data-length="1"] {
  font-size: 10.5px !important;
  letter-spacing: 0 !important;
}

.announcement-bell__badge[data-length="2"],
.cart-badge[data-length="2"] {
  font-size: 8.5px !important;
  letter-spacing: -0.04em !important;
}

.announcement-bell__badge[data-length="3"],
.cart-badge[data-length="3"] {
  font-size: 7.5px !important;
  letter-spacing: -0.06em !important;
}

.announcement-bell__badge[hidden],
.cart-badge[hidden],
.cart-badge:empty,
.announcement-bell__badge:empty {
  display: none !important;
}

/* =========================================
   E-COMMERCE CHECKOUT MODALS (3-STEP FLOW)
   ========================================= */

/* Z-Index Hierarchy ensures modals stack properly over each other */
#checkoutModal {
  z-index: 10000;
}
#addressSelectionModal {
  z-index: 10005;
}
#editInfoModal {
  z-index: 10010;
}
#addInfoModal {
  z-index: 10010;
}

.shop-modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: var(--ux-dlg-scrim);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  display: flex;
  justify-content: center;
  align-items: center;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.3s ease,
    visibility 0.3s ease;
}

.shop-modal-overlay.show-modal {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.shop-modal-box {
  background: linear-gradient(
    135deg,
    rgba(247, 242, 236, 0.96),
    rgba(255, 248, 238, 0.92)
  );
  border: 1px solid rgba(107, 32, 43, 0.16);
  width: 100%;
  max-width: 520px;
  height: 85vh;
  border-radius: 32px;
  display: flex;
  flex-direction: column;
  position: relative;
  box-shadow:
    0 35px 90px rgba(45, 12, 12, 0.26),
    inset 0 1px 0 rgba(247, 242, 236, 0.95);
  transform: translateY(30px);
  transition: transform 0.35s cubic-bezier(0.25, 0.8, 0.25, 1);
  overflow: hidden;
}

.shop-modal-box,
.shop-modal-box button,
.shop-modal-box input,
.shop-modal-box select,
.shop-modal-box textarea {
  font-family: "Montserrat", sans-serif;
}

.shop-modal-overlay.show-modal .shop-modal-box {
  transform: translateY(0);
}

/* --- Modal Header --- */
.shop-modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18px 24px;
  background: rgba(255, 255, 255, 0.7);
  border-bottom: 1px solid rgba(150, 52, 73, 0.08);
  flex-shrink: 0;
}
.shop-modal-title {
  font-family: "Montserrat", sans-serif;
  font-size: 19px;
  font-weight: 800;
  color: var(--customer-wine-hover);
  margin: 0;
  letter-spacing: -0.02em;
}
.back-shop-modal,
.trash-btn {
  background: rgba(150, 52, 73, 0.06);
  border: 1px solid rgba(150, 52, 73, 0.12);
  color: var(--customer-wine);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  transition: all 0.2s ease;
}
.back-shop-modal:hover,
.trash-btn:hover {
  color: #ffffff;
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
}

.back-shop-modal:active,
.trash-btn:active {
  transform: scale(0.94);
}

/* --- Modal Body & Scroller --- */
.shop-modal-body {
  overflow-y: auto;
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
}
.shop-modal-body::-webkit-scrollbar {
  width: 6px;
}
.shop-modal-body::-webkit-scrollbar-thumb {
  background: rgba(107, 32, 43, 0.2);
  border-radius: 10px;
}

/* --- 1. CHECKOUT MODAL STYLES --- */
.checkout-client-info {
  background: rgba(247, 242, 236, 0.9);
  border: 1px solid rgba(107, 32, 43, 0.12);
  border-radius: 20px;
  padding: 20px 22px 25px;
  display: flex;
  align-items: flex-start;
  gap: 14px;
  position: relative;
  cursor: pointer;
  box-shadow: 0 8px 20px rgba(61, 35, 28, 0.04);
  transition: all 0.2s ease;
}
.checkout-client-info:hover {
  background: var(--customer-paper);
  border-color: rgba(107, 32, 43, 0.25);
  box-shadow: 0 12px 28px rgba(128, 24, 18, 0.08);
}
.stripe-border {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 4px;
  border-radius: 0 0 20px 20px;
  background: repeating-linear-gradient(
    45deg,
    var(--customer-wine),
    var(--customer-wine) 15px,
    transparent 15px,
    transparent 25px,
    #f1ed12 25px,
    #f1ed12 40px,
    transparent 40px,
    transparent 50px
  );
}
.client-icon {
  color: var(--customer-wine);
  margin-top: 2px;
}
.client-details {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.client-name-phone {
  font-family: "Montserrat", sans-serif;
  font-weight: 800;
  font-size: 15px;
  color: #222833;
}
.client-name-phone span:last-child {
  color: #5c626e;
  font-weight: 500;
  margin-left: 6px;
}
.client-address-text {
  font-size: 13px;
  color: #5c626e;
  line-height: 1.45;
}

/*
  The saved address, itemised. Two columns of label/value so the customer can
  scan each part a courier will read instead of one run-on line.
*/
.client-address-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px 14px;
  margin: 2px 0 0;
  padding: 8px 10px;
  border: 1px solid rgba(107, 32, 43, 0.14);
  border-radius: 10px;
  background: rgba(107, 32, 43, 0.03);
}
.client-address-grid[hidden] {
  display: none;
}
.client-address-row {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.client-address-row dt {
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #96909a;
}
.client-address-row dd {
  margin: 0;
  font-size: 12.5px;
  font-weight: 700;
  color: #222833;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
/* A part the customer still has to fill in before a delivery can go out. */
.client-address-row.is-missing dd {
  color: var(--customer-wine);
  font-weight: 800;
}
.client-address-alert {
  margin: 0;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.4;
  color: var(--customer-wine);
  background: rgba(107, 32, 43, 0.07);
  border: 1px solid rgba(107, 32, 43, 0.2);
  border-radius: 8px;
  padding: 6px 9px;
}
.client-address-alert[hidden] {
  display: none;
}
/* Same bubble, informational tone: used for the pickup notice, which is not an
   error the customer has to fix. */
.client-address-alert.is-info {
  color: #1b5e20;
  background: rgba(46, 125, 50, 0.08);
  border-color: rgba(46, 125, 50, 0.25);
}
.client-dept-role {
  display: flex;
  gap: 8px;
  align-items: center;
  font-size: 11px;
  font-weight: 700;
  margin-top: 2px;
}
.badge-role {
  background: rgba(46, 125, 50, 0.1);
  color: #2e7d32;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid rgba(46, 125, 50, 0.2);
}
.gray-badge {
  background: rgba(107, 32, 43, 0.08);
  color: var(--customer-wine);
  border: 1px solid rgba(107, 32, 43, 0.14);
  border-radius: 999px;
}
.client-chevron {
  color: var(--customer-wine);
  padding-top: 20px;
}

.checkout-section {
  background: rgba(247, 242, 236, 0.9);
  border: 1px solid rgba(107, 32, 43, 0.12);
  border-radius: 20px;
  padding: 20px;
  box-shadow: 0 8px 20px rgba(61, 35, 28, 0.04);
}
.checkout-section-title {
  font-family: "Montserrat", sans-serif;
  font-size: 15px;
  font-weight: 800;
  margin-bottom: 15px;
  color: var(--customer-wine);
}
.checkout-product-card {
  display: flex;
  gap: 15px;
}
.checkout-product-card img {
  width: 80px;
  height: 80px;
  object-fit: cover;
  border-radius: var(--ux-card-radius);
  border: 1px solid rgba(107, 32, 43, 0.1);
}
.checkout-product-details {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.checkout-product-details h4 {
  font-size: 14px;
  font-weight: 700;
  color: #222833;
  margin-bottom: 5px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.product-variant {
  font-size: 12px;
  color: #5c626e;
  background: rgba(107, 32, 43, 0.06);
  border: 1px solid rgba(107, 32, 43, 0.1);
  padding: 2px 10px;
  border-radius: 999px;
  width: fit-content;
  margin-bottom: 10px;
  font-weight: 600;
}
.product-price-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.c-price {
  color: var(--customer-wine);
  font-size: 16px;
  font-weight: 800;
}

/* TikTok Qty Selector */
.qty-selector {
  display: flex;
  align-items: center;
  border: 1px solid rgba(107, 32, 43, 0.16);
  border-radius: 10px;
  overflow: hidden;
  height: 32px;
}
.qty-btn {
  background: rgba(107, 32, 43, 0.06);
  border: none;
  width: 32px;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 16px;
  color: var(--customer-wine);
  cursor: pointer;
  transition: all 0.15s ease;
  font-weight: 800;
}

.qty-btn:hover {
  background: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
}

.qty-btn:active {
  transform: scale(0.94);
}
.qty-selector input {
  width: 42px;
  height: 100%;
  border: none;
  border-left: 1px solid rgba(107, 32, 43, 0.12);
  border-right: 1px solid rgba(107, 32, 43, 0.12);
  text-align: center;
  font-size: 13px;
  font-weight: 800;
  color: #222833;
  outline: none;
  background: var(--customer-paper);
}
.qty-selector input::-webkit-outer-spin-button,
.qty-selector input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.checkout-stock-notice {
  text-align: right;
  font-size: 11px;
  color: #6d7480;
  margin-top: 8px;
}

/* ── Cart checkout — individual editable product rows in Order summary ── */
.checkout-cart-items-list {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.checkout-cart-item {
  display: flex;
  gap: 15px;
  padding-bottom: 14px;
  border-bottom: 1px solid rgba(107, 32, 43, 0.08);
}
.checkout-cart-item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}
.checkout-cart-item img {
  width: 70px;
  height: 70px;
  object-fit: cover;
  border-radius: 12px;
  border: 1px solid rgba(107, 32, 43, 0.1);
  flex-shrink: 0;
  background: var(--customer-paper);
}
.checkout-cart-item .checkout-cart-item-details {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-width: 0;
}
.checkout-cart-item .checkout-cart-item-details h4 {
  font-size: 13px;
  font-weight: 700;
  color: #222833;
  margin: 0 0 4px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.checkout-cart-item .checkout-cart-item-meta {
  font-size: 11px;
  color: #6d7480;
  margin-bottom: 8px;
}
.checkout-cart-item .product-price-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.checkout-cart-item .c-price {
  font-size: 15px;
}

/* Clickable thumbnails — Order summary + Shopping cart open the image preview. */
#checkoutSingleProductCard img,
#checkoutCartItemsList .checkout-cart-item img,
#cartItemsContainer .cart-item-card .cart-item-img img {
  cursor: zoom-in;
  transition:
    transform 0.26s ease,
    box-shadow 0.26s ease,
    border-color 0.26s ease;
}

#checkoutSingleProductCard img:hover,
#checkoutCartItemsList .checkout-cart-item img:hover,
#cartItemsContainer .cart-item-card .cart-item-img img:hover {
  transform: scale(1.04);
  border-color: rgba(107, 32, 43, 0.55);
  box-shadow: 0 6px 16px rgba(128, 24, 18, 0.18);
}

@media (prefers-reduced-motion: reduce) {
  #checkoutSingleProductCard img,
  #checkoutCartItemsList .checkout-cart-item img,
  #cartItemsContainer .cart-item-card .cart-item-img img {
    transition: none;
  }
  #checkoutSingleProductCard img:hover,
  #checkoutCartItemsList .checkout-cart-item img:hover,
  #cartItemsContainer .cart-item-card .cart-item-img img:hover {
    transform: none;
  }
}

/* Protection Upsell */
.checkout-protection-upsell {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
  margin-top: 15px;
  background: rgba(247, 242, 236, 0.8);
  border: 1px solid rgba(107, 32, 43, 0.12);
  border-radius: 14px;
}
.upsell-left {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: #343b49;
  font-weight: 600;
}
.upsell-left svg {
  color: var(--customer-wine);
}
.upsell-right {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  font-weight: 800;
  color: #222833;
}
.upsell-right input {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: var(--customer-wine);
}

.c-total-row {
  display: flex;
  justify-content: space-between;
  font-size: 14px;
  color: #343b49;
  margin-bottom: 12px;
}
.c-grand-total {
  font-weight: 800;
  color: var(--customer-wine);
  font-size: 17px;
  margin-top: 15px;
  padding-top: 15px;
  border-top: 1px dashed rgba(107, 32, 43, 0.14);
}
.c-payment-method {
  margin-top: 20px;
}
.c-payment-method label {
  display: block;
  font-size: 13px;
  color: #222833;
  margin-bottom: 8px;
  font-weight: 700;
}
.payment-select {
  width: 100%;
  padding: 12px 14px;
  border-radius: 14px;
  border: 1px solid rgba(107, 32, 43, 0.14);
  background: rgba(255, 254, 250, 0.9);
  font-size: 14px;
  font-weight: 700;
  color: #222833;
  outline: none;
  transition: all 0.2s ease;
}
.payment-select:focus {
  border-color: rgba(107, 32, 43, 0.64);
  box-shadow: 0 0 0 4px rgba(158, 20, 20, 0.08);
}

/* --- Pickup vs delivery choice --- */
.c-fulfillment-options {
  display: grid;
  gap: 10px;
}
.c-fulfillment-option {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 12px 14px;
  border-radius: 14px;
  border: 1px solid rgba(107, 32, 43, 0.14);
  background: rgba(255, 254, 250, 0.9);
  cursor: pointer;
  transition:
    border-color 0.2s ease,
    background 0.2s ease,
    box-shadow 0.2s ease;
}
.c-fulfillment-option:has(input:checked) {
  border-color: rgba(107, 32, 43, 0.64);
  background: rgba(107, 32, 43, 0.05);
  box-shadow: 0 0 0 4px rgba(158, 20, 20, 0.07);
}
/* Locked by the payment method, so it reads as information, not a choice. */
.c-fulfillment-option:has(input:disabled) {
  cursor: default;
  opacity: 0.55;
}
.c-fulfillment-option:has(input:checked):has(input:disabled) {
  opacity: 1;
}
.c-fulfillment-option input {
  margin-top: 3px;
  accent-color: var(--customer-wine);
  flex-shrink: 0;
}
.c-fulfillment-copy {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.c-fulfillment-copy strong {
  font-size: 13.5px;
  font-weight: 800;
  color: #222833;
}
.c-fulfillment-copy small {
  font-size: 11.5px;
  color: #5c626e;
  line-height: 1.45;
}
.c-fulfillment-note {
  margin: 10px 0 0;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.45;
  color: #6d5b1e;
  background: rgba(214, 158, 46, 0.12);
  border: 1px solid rgba(214, 158, 46, 0.28);
  border-radius: 10px;
  padding: 8px 10px;
}
.c-fulfillment-note[hidden],
.c-fulfillment-note:empty {
  display: none;
}

/* --- GCash payment step ---
   Sits outside .checkout-form, so the field/label/error styling that block
   scopes to itself has to be restated here rather than inherited. */
.gcash-pay-section[hidden] {
  display: none;
}
.gcash-amount-line {
  margin: 0 0 12px;
  font-size: 12.5px;
  color: #5c626e;
  line-height: 1.5;
}
.gcash-amount-line strong {
  font-size: 15px;
  font-weight: 900;
  color: var(--customer-wine);
}
/* Placing the order is free and the money can follow, so this says so before
   the reference field is reached - otherwise an empty field reads as a blocker. */
.gcash-paylater-note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0 0 12px;
  padding: 8px 10px;
  border-radius: 10px;
  border: 1px solid rgba(0, 122, 255, 0.22);
  background: rgba(0, 122, 255, 0.07);
  font-size: 11.5px;
  line-height: 1.45;
  color: #2c4a6b;
}
.gcash-paylater-note[hidden] {
  display: none;
}
.gcash-paylater-note i {
  margin-top: 1px;
  color: #0a72c4;
}
.gcash-paylater-note strong {
  font-weight: 800;
  color: #1d3a57;
}
.gcash-account-card {
  display: grid;
  gap: 8px;
  padding: 12px 14px;
  border-radius: 14px;
  border: 1px solid rgba(107, 32, 43, 0.14);
  background: rgba(255, 254, 250, 0.9);
}
.gcash-account-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.gcash-account-label {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #7a808c;
  min-width: 96px;
}
.gcash-account-value {
  font-size: 14px;
  font-weight: 800;
  color: #222833;
  word-break: break-word;
}
.gcash-copy-btn {
  margin-left: auto;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid rgba(107, 32, 43, 0.24);
  background: rgba(107, 32, 43, 0.06);
  color: var(--customer-wine);
  font-family: "Montserrat", sans-serif;
  font-size: 11px;
  font-weight: 800;
  cursor: pointer;
  transition:
    background 0.2s ease,
    border-color 0.2s ease;
}
.gcash-copy-btn:hover {
  background: rgba(107, 32, 43, 0.12);
  border-color: rgba(107, 32, 43, 0.4);
}
.gcash-pay-methods {
  margin-top: 14px;
}
.gcash-qr-block[hidden],
.gcash-mobile-block[hidden] {
  display: none;
}
.gcash-qr-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
.gcash-qr-image {
  width: 100%;
  max-width: 230px;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  padding: 10px;
  border-radius: 16px;
  border: 1px solid rgba(107, 32, 43, 0.14);
  background: var(--customer-paper);
}
.gcash-qr-save {
  font-size: 11.5px;
  font-weight: 800;
  color: var(--customer-wine);
  text-decoration: underline;
}
.gcash-mobile-block {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.gcash-open-app-btn {
  width: 100%;
  padding: 14px 18px;
  border-radius: 999px;
  border: none;
  /* GCash's own brand blue, so the button reads as "this opens GCash". */
  background: #0075f6;
  color: var(--customer-paper-sink);
  font-family: "Montserrat", sans-serif;
  font-size: 13.5px;
  font-weight: 800;
  cursor: pointer;
  box-shadow: 0 10px 20px rgba(0, 117, 246, 0.24);
  transition:
    filter 0.2s ease,
    transform 0.15s ease;
}
.gcash-open-app-btn:hover {
  filter: brightness(1.06);
}
.gcash-open-app-btn:active {
  transform: translateY(1px);
}
.gcash-open-app-hint {
  margin: 0;
  font-size: 11.5px;
  line-height: 1.45;
  color: #5c626e;
  text-align: center;
}
.gcash-open-app-hint:empty {
  display: none;
}
.gcash-steps {
  margin: 14px 0 16px;
  padding-left: 20px;
  display: grid;
  gap: 5px;
}
.gcash-steps:empty {
  display: none;
}
.gcash-steps[hidden] {
  display: none;
}
.gcash-steps li {
  font-size: 12px;
  line-height: 1.5;
  color: #5c626e;
}
.gcash-steps li strong {
  color: #343b49;
  font-weight: 800;
}
.gcash-reference-group {
  position: relative;
  margin: 0;
}
.gcash-reference-group label {
  display: block;
  font-size: 12px;
  font-weight: 800;
  color: #343b49;
  margin-bottom: 8px;
  letter-spacing: 0.04em;
}
.gcash-reference-group .req-mark {
  color: var(--customer-wine);
  font-weight: 900;
}
/* GCash may be paid after checkout, so the field is asked for rather than
   demanded. The marker says so at a glance instead of relying on the help
   text underneath being read. */
.gcash-reference-group .opt-mark {
  color: #8a8f9a;
  font-weight: 700;
  text-transform: none;
  letter-spacing: 0;
}
.gcash-reference-group input {
  letter-spacing: 0.08em;
}
.gcash-reference-help {
  display: block;
  margin-top: 7px;
  font-size: 11px;
  line-height: 1.45;
  color: #7a808c;
}
.gcash-reference-group.has-error .c-input {
  border-color: var(--customer-danger);
  box-shadow: 0 0 0 3px rgba(191, 27, 27, 0.14);
  background-color: #fffafa;
}
.gcash-reference-group.has-error .checkout-field-error-bubble {
  opacity: 1;
}
/* Shown only when staff have not saved the GCash details yet, so the customer
   is told to pick another method instead of guessing where to send money. */
.gcash-unconfigured-note {
  margin: 12px 0 0;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.45;
  color: #6d5b1e;
  background: rgba(214, 158, 46, 0.12);
  border: 1px solid rgba(214, 158, 46, 0.28);
  border-radius: 10px;
  padding: 8px 10px;
}
.gcash-unconfigured-note[hidden],
.gcash-unconfigured-note:empty {
  display: none;
}

/* --- Two-up form rows (barangay/city, province/postal) --- */
.checkout-form .form-row-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 12px;
}
@media (max-width: 480px) {
  .checkout-form .form-row-2 {
    grid-template-columns: 1fr;
  }
  .client-address-grid {
    grid-template-columns: 1fr;
  }
}
/* Marks a field the order cannot be placed without. */
.checkout-form .req-mark {
  color: var(--customer-wine);
  font-weight: 900;
}

.c-terms-box {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 15px 20px;
  background: transparent;
}
.c-terms-box input {
  margin-top: 4px;
  cursor: pointer;
  accent-color: var(--customer-wine);
}
.c-terms-box label {
  font-size: 12px;
  color: #5c626e;
  line-height: 1.45;
  cursor: pointer;
}

/* --- Fixed Footer --- */
.shop-modal-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18px 24px;
  background: rgba(247, 242, 236, 0.7);
  border-top: 1px solid rgba(107, 32, 43, 0.08);
  flex-shrink: 0;
}
.footer-total-display {
  display: flex;
  align-items: center;
  gap: 8px;
}
.footer-total-display span:first-child {
  font-size: 13px;
  color: #343b49;
  font-weight: 700;
}
.highlight-total {
  font-family: "Montserrat", sans-serif;
  font-size: 19px !important;
  font-weight: 900;
  color: var(--customer-wine) !important;
}
.btn-place-order {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: "Montserrat", sans-serif;
  background: var(--customer-wine);
  color: var(--customer-paper-sink);
  border: 2px solid var(--customer-wine);
  padding: 14px 28px;
  font-weight: 800;
  font-size: 14px;
  line-height: 1;
  border-radius: 999px;
  cursor: pointer;
  box-shadow: 0 6px 15px rgba(176, 28, 28, 0.2);
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color 0.2s ease,
    border-color 0.2s ease,
    color 0.2s ease,
    box-shadow 0.1s ease,
    transform 0.1s ease;
}

.btn-place-order:not(.delete-btn):hover:not(:disabled),
.btn-place-order:not(.delete-btn):focus-visible:not(:disabled) {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  box-shadow: 0 8px 20px rgba(128, 24, 18, 0.28);
  transform: none;
}

.btn-place-order:not(.delete-btn):active:not(:disabled) {
  transform: scale(0.97);
  box-shadow: 0 2px 5px rgba(176, 28, 28, 0.2);
}

.btn-place-order:focus-visible {
  outline: 2px solid rgba(107, 32, 43, 0.42);
  outline-offset: 2px;
}

.btn-place-order:not(.delete-btn):disabled {
  background: #eeeeee;
  border-color: #cccccc;
  color: #999999;
  box-shadow: none;
  cursor: not-allowed;
}

.cart-edit-btn {
  background: rgba(247, 242, 236, 0.9) !important;
  border: 1px solid rgba(107, 32, 43, 0.2) !important;
  border-radius: 999px !important;
  padding: 8px 16px !important;
  color: var(--customer-wine) !important;
  font-size: 13px !important;
  font-weight: 800 !important;
  line-height: 1;
  transition: all 0.2s ease;
}

.cart-edit-btn:hover {
  background: var(--customer-wine-hover) !important;
  color: var(--customer-paper-sink) !important;
  box-shadow: 0 8px 16px rgba(158, 20, 20, 0.16);
}

.cart-edit-btn:active {
  transform: scale(0.95);
}

.address-edit-toggle {
  min-width: 68px;
  justify-content: center;
}

#cartDeleteBtn:hover {
  background: var(--customer-wine-hover) !important;
  border-color: var(--customer-wine-hover) !important;
  color: var(--customer-paper-sink) !important;
}

#cartDeleteBtn:active {
  transform: scale(0.96);
}

.shop-modal-box button:focus-visible,
.shop-modal-box input:focus-visible,
.shop-modal-box select:focus-visible,
.shop-modal-box textarea:focus-visible {
  outline: 2px solid rgba(107, 32, 43, 0.35);
  outline-offset: 2px;
}

/* --- 2. ADDRESS SELECTION MODAL STYLES --- */
.address-selection-box .shop-modal-body {
  padding: 16px;
  background: transparent;
}
.add-address-row {
  display: flex;
  align-items: center;
  padding: 18px 22px;
  background: rgba(247, 242, 236, 0.9);
  border: 1px solid rgba(107, 32, 43, 0.12);
  border-radius: 0;
  margin-bottom: 12px;
  cursor: pointer;
  box-shadow: 0 8px 20px rgba(61, 35, 28, 0.04);
  transition: all 0.2s ease;
}
.add-address-row:hover {
  background: var(--customer-paper);
  border-color: rgba(107, 32, 43, 0.25);
  box-shadow: 0 12px 28px rgba(128, 24, 18, 0.08);
}
.add-address-row svg {
  margin-right: 12px;
  color: var(--customer-wine);
}
.add-address-row span.add-text {
  flex-grow: 1;
  font-size: 15px;
  font-weight: 800;
  color: #222833;
}
.add-address-row span.chevron-right {
  color: var(--customer-wine);
  font-weight: bold;
  font-size: 18px;
}

.address-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.address-item {
  background: rgba(247, 242, 236, 0.9);
  border: 1px solid rgba(107, 32, 43, 0.12);
  border-radius: 0;
  padding: 20px;
  display: flex;
  justify-content: space-between;
  cursor: pointer;
  box-shadow: 0 8px 20px rgba(61, 35, 28, 0.04);
  transition: all 0.2s ease;
}
.address-item:hover {
  background: var(--customer-paper);
  border-color: rgba(107, 32, 43, 0.25);
  box-shadow: 0 12px 28px rgba(128, 24, 18, 0.08);
}
.address-item-left {
  flex-grow: 1;
  padding-right: 15px;
}
.address-name-row {
  font-size: 15px;
  font-weight: 800;
  color: #222833;
  margin-bottom: 8px;
}
.address-name-row .a-phone {
  font-weight: 500;
  color: #5c626e;
  margin-left: 8px;
}
.a-address-text {
  font-size: 13px;
  color: #5c626e;
  line-height: 1.45;
  margin-bottom: 10px;
}
.a-badge.default-badge {
  background: rgba(107, 32, 43, 0.08);
  border: 1px solid rgba(107, 32, 43, 0.14);
  color: var(--customer-wine);
  font-size: 11px;
  padding: 3px 10px;
  border-radius: 999px;
  font-weight: 700;
}
/* Flags a saved address that cannot be shipped to yet, so the customer notices
   it in the list instead of only at checkout. */
.a-badge.incomplete-badge {
  background: rgba(198, 124, 0, 0.1);
  border: 1px solid rgba(198, 124, 0, 0.22);
  color: var(--customer-wine);
  font-size: 11px;
  padding: 3px 10px;
  border-radius: 999px;
  font-weight: 800;
  display: inline-block;
  margin-top: 6px;
}
.edit-address-btn {
  background: rgba(247, 242, 236, 0.9);
  border: 1px solid rgba(107, 32, 43, 0.25);
  border-radius: 999px;
  padding: 6px 14px;
  color: var(--customer-wine);
  font-size: 12px;
  font-weight: 800;
  cursor: pointer;
  transition: all 0.2s ease;
  height: fit-content;
}
.edit-address-btn:hover {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
}

.edit-address-btn:active {
  transform: scale(0.96);
}

.address-item.selected {
  background: #fff7f7;
  box-shadow: inset 0 0 0 1px #f0c9c9;
}

.address-item.select-mode {
  cursor: default;
}

.address-edit-selector {
  display: none;
  align-items: center;
  margin-right: 10px;
  flex-shrink: 0;
}

.address-item.select-mode .address-edit-selector {
  display: flex;
}

.address-item.select-mode .address-item-right {
  display: none;
}

.address-item-main {
  display: flex;
  align-items: flex-start;
  width: 100%;
}

.delete-address-inline {
  display: none;
  background: var(--customer-paper);
  border: 1px solid #f0bcbc;
  border-radius: 999px;
  padding: 4px 10px;
  color: var(--customer-wine);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition:
    background-color 0.2s ease,
    color 0.2s ease,
    border-color 0.2s ease,
    transform 0.08s ease;
}

.address-item.select-mode .delete-address-inline {
  display: inline-flex;
  align-self: center;
}

.delete-address-inline:hover {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
}

.delete-address-inline:active {
  transform: scale(0.96);
}

.address-selection-footer {
  gap: 10px;
}

.address-selection-footer .address-delete-actions {
  margin-left: auto;
  gap: 8px;
}

#deleteSelectedAddressBtn:hover,
#deleteAllAddressBtn:hover {
  background: var(--customer-wine-hover) !important;
  border-color: var(--customer-wine-hover) !important;
  color: var(--customer-paper-sink) !important;
}

#deleteSelectedAddressBtn:active,
#deleteAllAddressBtn:active {
  transform: scale(0.96);
}

/* --- 3. EDIT INFO FORM STYLES --- */
.edit-info-box .shop-modal-body {
  padding: 0;
  background: transparent;
}
.edit-info-guide {
  display: flex;
  align-items: center;
  gap: 15px;
  background: rgba(247, 242, 236, 0.8);
  padding: 16px 24px;
  border-bottom: 1px solid rgba(107, 32, 43, 0.08);
}
.edit-info-guide img {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  object-fit: cover;
  border: 1px solid rgba(107, 32, 43, 0.1);
}
.guide-text {
  display: flex;
  flex-direction: column;
  font-size: 12px;
}
.guide-text span {
  color: #6d7480;
}
.guide-text strong {
  color: #222833;
  font-weight: 800;
  margin-top: 3px;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.checkout-form {
  display: flex;
  flex-direction: column;
  padding: 24px;
}
.checkout-form .form-group {
  margin-bottom: 20px;
  position: relative;
}
.checkout-form .form-group label {
  display: block;
  font-size: 12px;
  font-weight: 800;
  color: #343b49;
  margin-bottom: 8px;
  letter-spacing: 0.04em;
}
.c-input {
  width: 100%;
  padding: 14px 18px;
  background: rgba(255, 254, 250, 0.86);
  border: 1px solid rgba(107, 32, 43, 0.14);
  border-radius: 18px;
  font-family: "Montserrat", sans-serif;
  font-size: 14px;
  color: #222833;
  outline: none;
  box-shadow:
    inset 0 1px 0 rgba(253, 250, 246, 0.9),
    0 8px 18px rgba(72, 27, 22, 0.04);
  transition: all 0.2s ease;
}
.c-input:focus {
  border-color: rgba(107, 32, 43, 0.64);
  background: var(--customer-paper);
  box-shadow:
    0 0 0 4px rgba(158, 20, 20, 0.08),
    0 14px 28px rgba(72, 27, 22, 0.09);
}

/* The address selects share `.c-input` with the text fields. These two rules are
   all the extra they need: a pointer, and a muted look while the step above them
   has not been picked yet. */
select.c-input {
  cursor: pointer;
}
select.c-input:disabled {
  background: rgba(240, 236, 232, 0.7);
  color: #8b8b8b;
  cursor: not-allowed;
  box-shadow: none;
}

/* Quiet helper line under a field — used by the auto-filled postal code. */
.checkout-form .c-field-hint {
  display: block;
  margin-top: 6px;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.35;
  color: #6b7280;
  letter-spacing: 0.01em;
}

.checkout-form .form-group.has-error .c-input {
  border-color: var(--customer-danger);
  box-shadow: 0 0 0 3px rgba(191, 27, 27, 0.14);
  background-color: #fffafa;
}

.checkout-form .form-group.has-error .phone-input-group {
  border-color: var(--customer-danger);
  box-shadow: 0 0 0 3px rgba(191, 27, 27, 0.14);
  background-color: #fffafa;
}

.checkout-form .form-group.has-error .phone-prefix {
  border-right-color: var(--customer-danger);
}

.checkout-field-error-bubble {
  position: absolute;
  right: 0;
  top: -8px;
  transform: translateY(-100%);
  max-width: 290px;
  background: var(--customer-danger);
  color: var(--customer-paper-sink);
  font-size: 12px;
  line-height: 1.35;
  font-weight: 600;
  padding: 8px 10px;
  border-radius: 10px;
  box-shadow: 0 10px 18px rgba(43, 43, 49, 0.2);
  z-index: 20;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.16s ease;
}

.checkout-field-error-bubble::after {
  content: "";
  position: absolute;
  right: 18px;
  bottom: -7px;
  width: 14px;
  height: 14px;
  background: var(--customer-danger);
  transform: rotate(45deg);
}

.checkout-form .form-group.has-error .checkout-field-error-bubble {
  opacity: 1;
}

@media (max-width: 768px) {
  .checkout-field-error-bubble {
    left: 0;
    right: auto;
    top: calc(100% + 8px);
    transform: none;
    max-width: 100%;
  }

  .checkout-field-error-bubble::after {
    left: 16px;
    right: auto;
    top: -7px;
    bottom: auto;
  }
}
.c-textarea {
  resize: vertical;
  min-height: 80px;
  line-height: 1.5;
}

/* TikTok Style Map Confirm Box */
.map-confirmation-box {
  border: 1px solid #e0e0e0;
  border-radius: var(--ux-card-radius);
  overflow: hidden;
  background: #fafafa;
  margin-top: 5px;
}
.map-header {
  padding: 10px 15px;
  font-size: 13px;
  color: #333;
  display: flex;
  align-items: center;
  gap: 8px;
  border-bottom: 1px solid #e0e0e0;
}

.phone-input-group {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  background: transparent;
  border: 1px solid #d9d9d9;
  border-radius: 8px;
  overflow: hidden;
}
.phone-prefix {
  display: flex;
  align-items: center;
  white-space: nowrap;
  flex-shrink: 0;
  min-width: max-content;
  padding: 12px 15px;
  background: transparent;
  font-weight: 400;
  font-size: 14px;
  color: #111;
  border-right: 1px solid #d9d9d9;
}
.phone-input-group .c-input {
  width: auto;
  flex: 1 1 auto;
  border: none;
  border-radius: 0;
  min-width: 0;
  padding: 12px;
}

/* Custom Radio Grid */
.radio-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-top: 10px;
}
.radio-container {
  display: flex;
  align-items: center;
  font-size: 13px;
  cursor: pointer;
  position: relative;
  padding-left: 25px;
  user-select: none;
  color: #333;
}
.radio-container input {
  position: absolute;
  opacity: 0;
  cursor: pointer;
  height: 0;
  width: 0;
}
.checkmark {
  position: absolute;
  top: -1px;
  left: 0;
  height: 18px;
  width: 18px;
  background-color: var(--customer-paper);
  border-radius: 50%;
  border: 1px solid #ccc;
}
.radio-container input:checked ~ .checkmark {
  background-color: var(--customer-wine);
  border-color: var(--customer-wine);
}
.checkmark:after {
  content: "";
  position: absolute;
  display: none;
}
.radio-container input:checked ~ .checkmark:after {
  display: block;
}
.radio-container .checkmark:after {
  top: 5px;
  left: 5px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--customer-paper);
}

/* Toggle Switch (iOS Style) */
.c-switch-group {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 15px;
  border-top: 1px solid #eaeaea;
  margin-bottom: 0;
}
.switch-text strong {
  display: block;
  font-size: 14px;
  color: #111;
  margin-bottom: 4px;
  font-weight: 600;
}
.switch-text p {
  font-size: 11px;
  color: #888;
  max-width: 85%;
  line-height: 1.4;
}

.toggle-switch {
  position: relative;
  display: inline-block;
  width: 46px;
  height: 24px;
  flex-shrink: 0;
}
.toggle-switch input {
  opacity: 0;
  width: 0;
  height: 0;
}
.toggle-slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  transition: 0.4s;
  border-radius: 34px;
}
.toggle-slider:before {
  position: absolute;
  content: "";
  height: 18px;
  width: 18px;
  left: 3px;
  bottom: 3px;
  background-color: var(--customer-paper);
  transition: 0.4s;
  border-radius: 50%;
}
input:checked + .toggle-slider {
  background-color: #00d084;
}
input:checked + .toggle-slider:before {
  transform: translateX(22px);
}

/* =========================================
   SHOPPING CART MODAL STYLES
   ========================================= */
/* Slower slide up animation for the cart */
.cart-modal-box {
  transform: translateY(50vh);
  transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}
#cartModal {
  z-index: 10002;
} /* Sits above standard overlays */

.cart-header-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}
.cart-short-address {
  display: flex;
  align-items: center;
  gap: 4px;
}

/* TikTok Style Round Checkboxes */
.cart-checkbox-container {
  display: flex;
  align-items: center;
  position: relative;
  padding-left: 28px;
  cursor: pointer;
  user-select: none;
  min-height: 20px;
}
.cart-checkbox-container input {
  position: absolute;
  opacity: 0;
  cursor: pointer;
  height: 0;
  width: 0;
}
.cart-checkmark {
  position: absolute;
  top: 50%;
  left: 0;
  transform: translateY(-50%);
  height: 20px;
  width: 20px;
  background-color: var(--customer-paper);
  border-radius: 50%;
  border: 1px solid #ccc;
  transition: all 0.2s ease;
}
.cart-checkbox-container input:checked ~ .cart-checkmark {
  background-color: var(--customer-wine);
  border-color: var(--customer-wine);
}
.cart-checkmark:after {
  content: "";
  position: absolute;
  display: none;
  left: 6px;
  top: 3px;
  width: 4px;
  height: 8px;
  border: solid var(--customer-paper);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.cart-checkbox-container input:checked ~ .cart-checkmark:after {
  display: block;
}

/* Cart Product Cards */
.cart-item-card {
  display: flex;
  align-items: center;
  padding: 15px 20px;
  background: var(--customer-paper);
  margin-bottom: 8px;
}
.cart-item-img {
  width: 75px;
  height: 75px;
  margin-left: 15px;
  margin-right: 15px;
  flex-shrink: 0;
}
.cart-item-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid #eaeaea;
}
.cart-item-details {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 75px;
}
.cart-item-details h4 {
  font-size: 13px;
  font-weight: 600;
  color: #111;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-top: 2px;
}
.cart-item-bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.cart-checkmark:after {
  content: "";
  position: absolute;
  display: none;
  left: 6px;
  top: 3px;
  width: 4px;
  height: 8px;
  border: solid var(--customer-paper);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.cart-checkbox-container input:checked ~ .cart-checkmark:after {
  display: block;
}

/* Cart Product Cards */
.cart-item-card {
  display: flex;
  align-items: center;
  padding: 15px 20px;
  background: var(--customer-paper);
  margin-bottom: 8px;
}
.cart-item-img {
  width: 75px;
  height: 75px;
  margin-left: 15px;
  margin-right: 15px;
  flex-shrink: 0;
}
.cart-item-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid #eaeaea;
}
.cart-item-details {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 75px;
}
.cart-item-details h4 {
  font-size: 13px;
  font-weight: 600;
  color: #111;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-top: 2px;
}
.cart-item-bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* =========================================
   APPOINTMENT FLOW OVERLAY & UI (HOMEPAGE)
   ========================================= */
.apt-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  /* All five steps share the reference maroon gradient. Keep it opaque so the
     heading and progress labels stay readable above the page underneath. */
  background: var(--customer-modal-stage);
  z-index: 20000;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.3s ease,
    visibility 0.3s ease;
  overflow-y: auto;
}
.apt-overlay.show-modal {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.apt-container {
  width: 100%;
  max-width: 1120px;
  padding: 30px 5%;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

/* Header with < Back Button */
.apt-header-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 10px;
  margin-bottom: 30px;
  /* One hairline instead of 30px of empty space doing the same job: it separates
     the title from the step rail without adding another box. */
  padding-bottom: 18px;
  border-bottom: 1px solid rgba(247, 242, 236, 0.14);
}
.apt-main-title {
  font-family: "Montserrat", sans-serif;
  font-size: clamp(26px, 4vw, 38px);
  /* 900 + a -0.03em squeeze + a black text-shadow was three effects competing on
     one line of type. 800 with an open letterspace and no shadow is the same
     word, read faster. */
  font-weight: 800;
  color: var(--customer-paper-sink);
  text-align: center;
  flex-grow: 1;
  letter-spacing: 0.01em;
}
.apt-back-btn {
  /* Flat, not glass. The <=900px perf arm near the end of this file used to strip
     `backdrop-filter` from this button, so the blur only ever rendered on desktop
     and the two viewports disagreed. This is the colour the blur was faking; the
     arm no longer names this button at all. */
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.22);
  color: #ffffff;
  cursor: pointer;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    background-color 0.2s ease,
    border-color 0.2s ease,
    color 0.2s ease,
    transform 0.16s ease;
}
.apt-back-btn:hover {
  background: #f1ed12;
  color: #2d2a12;
  border-color: #f1ed12;
  transform: none;
}
.apt-back-btn:active {
  transform: scale(0.97);
}

/* Progress Bar */
.apt-progress-wrapper {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 35px;
  position: relative;
  background: rgba(45, 12, 12, 0.2);
  padding: 16px 24px;
  /* 8px, not a 999px pill. A full-width strip with pill ends reads as a giant
     chip; a rectangle with the same corner as every card in the flow reads as
     part of the page. This is the whole radius-collapse in one line. */
  border-radius: var(--apt-radius);
  border: 1px solid rgba(247, 242, 236, 0.14);
}
.apt-line {
  flex-grow: 1;
  height: 3px;
  background: rgba(247, 242, 236, 0.22);
  margin-top: 25px;
  transition: background-color 0.24s ease;
}
.apt-step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  z-index: 2;
  width: 90px;
}
.step-label {
  color: rgba(247, 242, 236, 0.68);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.apt-step span:last-child {
  color: rgba(247, 242, 236, 0.86);
  font-size: 12px;
  font-weight: 700;
  text-align: center;
}
.apt-icon {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(247, 242, 236, 0.1);
  color: rgba(247, 242, 236, 0.62);
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1.5px solid rgba(247, 242, 236, 0.3);
  /* Named properties and a plain ease: the old `all` + overshoot curve made the
     circle spring past its size every time the step changed, which is exactly
     the jitter the rail is meant not to have. */
  transition:
    background-color 0.24s ease,
    border-color 0.24s ease,
    color 0.24s ease,
    box-shadow 0.24s ease;
  font-size: 18px;
}
.apt-step.active .step-label {
  color: #f1ed12;
  opacity: 1;
}
/* The three real rail states live in the §8 block at the end of this file
   (`.is-done` / `.is-current` / neither). This older `.active` rule stays only
   for the label colour above; the circle it used to paint is handled there. */

/* Content Sections */
.apt-content-section {
  display: none;
  flex-grow: 1;
  flex-direction: column;
}
.apt-content-section.active {
  display: flex;
  animation: fadeInApt 0.4s ease;
}
@keyframes fadeInApt {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.apt-card {
  /* Solid warm paper, not a two-stop translucent gradient behind a 16px blur.
     The blur never survived below 900px anyway (the perf arm strips it), so the
     card looked like two different things on two devices. Warm paper is what the
     gradient was approximating, and it is the same paper the success dialog that
     ends this flow is printed on. Pure white is not in this palette. */
  background: var(--customer-paper);
  border: 1px solid var(--apt-line-warm);
  border-radius: var(--apt-radius);
  padding: 32px;
  box-shadow: 0 22px 54px rgba(27, 4, 4, 0.28);
  margin-bottom: 24px;
}
.apt-reminders-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-bottom: 20px;
}
.apt-reminders-grid .apt-card {
  margin-bottom: 0;
  font-size: 15px;
  color: var(--apt-body);
  line-height: 1.5;
}

.apt-footer-actions {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  gap: 15px;
  padding-bottom: 40px;
}

/* Synchronized Button Styles */
.apt-btn {
  font-family: "Montserrat", sans-serif;
  padding: 16px 42px;
  font-size: 15px;
  font-weight: 800;
  /* 8px, the same corner `.apt-card` and every panel in the flow carries. A
     button that repeats its card's radius reads as part of that card; a pill
     inside an 8px card reads as a control borrowed from somewhere else. This
     is the site's one button shape now — hero CTAs, View All, the dialog
     family, the dropdown, Announcement, all of appointment steps 1-5. */
  border-radius: var(--apt-radius, 8px);
  cursor: pointer;
  /* Warm depth rather than neutral black, so the shadow belongs to the maroon
     stage it falls on. */
  box-shadow: 0 10px 22px rgba(27, 4, 4, 0.22);
  /* Named properties, not `all`: the <=900px perf arm no longer has to rewrite
     this declaration, and nothing unexpected (width, padding, radius) can ever
     animate here. */
  transition:
    background-color 0.22s ease,
    background 0.22s ease,
    border-color 0.22s ease,
    color 0.22s ease,
    box-shadow 0.22s ease,
    transform 0.16s ease;
}

.apt-btn:active {
  transform: scale(0.97);
}

/* Proceed Button (Yellow/Gold Gradient).
   `-blue` is historical — this button has been gold for as long as the flow has
   had this palette. The name is load-bearing in main.html and both nested
   dialogs, so it stays; only the paint is described here. The dead `-solid` and
   `-green` aliases have been dropped from these two lists. */

/* Flat gold, maroon ink — the step-1 "I Understand, Proceed" pill is one of the
   two buttons the owner pointed at as the reference for the whole customer site.
   No gradient, and the hover shadow repeats the resting one so nothing lifts. */
.apt-btn-blue {
  background: #eef224; /* solid flat yellow — no gradient */
  color: #3d0808; /* dark maroon ink */
  border: none;
  box-shadow: 0 10px 22px rgba(128, 116, 14, 0.24);
}

.apt-btn-blue:hover {
  background: #c8cc00; /* darker yellow on hover */
  color: #3d0808;
  box-shadow: 0 10px 22px rgba(128, 116, 14, 0.24);
  transform: none;
}

/* Back/Cancel Button (Glass Outline) */
.apt-btn-back,
.apt-btn-outline {
  background: rgba(247, 242, 236, 0.12);
  color: #f7f2ec;
  border: 1.5px solid rgba(247, 242, 236, 0.52);
}

.apt-btn-back:hover,
.apt-btn-outline:hover {
  background: #f7f2ec; /* cream fill — not pure white */
  border-color: #f7f2ec;
  color: #3d0808;
  transform: none;
  box-shadow: 0 10px 22px rgba(27, 4, 4, 0.22);
}

.apt-btn-cancel {
  background: var(--customer-wine);
  color: #f7f2ec;
  border: none;
}

.apt-btn-cancel:hover {
  background: #3d0808;
  color: #f7f2ec;
  transform: none;
}

/* Form Grid */
.apt-form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 20px;
}
.apt-input-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
  position: relative;
}
/* `.apt-input-group label` was declared twice in this file — 14px/#333/600 here
   and 13px/#444/700 in the enhanced-steps layer below, which won. One
   declaration now, in the enhanced-steps layer, so the field labels have a
   single source of truth.

   The legacy `.apt-upload-btn` (a #4caf50 green pill), the whole first-generation
   `.calendar-layout` / `.calendar-grid-box` / `.cal-row` / `.cal-date` / `.dots`
   calendar, its duplicate `.leg-item`, and the `.apt-review-card` /
   `.apt-complete-card` / `.review-grid` / `.r-label` / `.r-value` review cards
   were all deleted here: none of those class names appears in main.html or
   main.js any more. That removed the last `#4caf50` and the only `#e0b0ff` in
   the stylesheet. */

/* Nested Modals */
.apt-nested-modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%; /* Changed from 100vw */
  height: 100%;
  /* Shadowed at desktop by the shared scrim rule at :17464 and on phones by the
     perf arm, so this value only ever paints if a future nested modal appears
     without an id in either list. Warm anyway: a neutral black is not in this
     palette, and a fallback that contradicts the ladder is a trap for whoever
     adds that modal. */
  background: var(--ux-dlg-scrim);
  z-index: 25000;
  display: flex;
  justify-content: center;
  align-items: center;
  opacity: 0;
  visibility: hidden;
  transition: 0.3s ease;
}
.apt-nested-modal.show-modal {
  opacity: 1;
  visibility: visible;
}
.apt-nested-box {
  background: var(--customer-paper);
  width: 90%;
  max-width: 500px;
  border-radius: var(--ux-dlg-radius);
  padding: 40px 30px;
  position: relative;
  border: 4px solid var(--customer-wine);
}
.nested-icon {
  position: absolute;
  top: -30px;
  left: 50%;
  transform: translateX(-50%);
  width: 60px;
  height: 60px;
  background: #8caba3;
  color: var(--customer-paper-sink);
  font-size: 35px;
  font-weight: bold;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  border: 4px solid var(--customer-paper);
}
.nested-icon.brown-icon {
  background: #c6a27a;
}
.apt-nested-box h3 {
  text-align: center;
  margin-bottom: 20px;
  font-weight: 800;
}
.apt-nested-box p {
  font-size: 14px;
  line-height: 1.6;
  color: #333;
  text-align: justify;
}
.nested-actions {
  display: flex;
  justify-content: center;
  gap: 15px;
  margin-top: 30px;
}

/* `.apt-btn-outline-brown`, `.calendar-layout`, `.apt-complete-card` and
   `.complete-right` were the last four references to the deleted
   first-generation flow; none of them appears in any page or script. */
@media (max-width: 768px) {
  .apt-reminders-grid,
  .apt-form-grid {
    grid-template-columns: 1fr;
    flex-direction: column;
  }
  .apt-input-group[style] {
    grid-column: span 1 !important;
    grid-row: span 1 !important;
  }
  .apt-progress-wrapper span {
    display: none;
  }
}

/* --- Cleaned Up Responsive Adjustments --- */

@media (max-width: 1400px) {
  .service-card {
    width: calc(33.333% - 27px);
  } /* 3 per row */
}

@media (max-width: 1100px) {
  .hero-title {
    font-size: 50px;
  }
  .hero-graphic {
    max-width: 500px;
  }
  .about-container {
    gap: 40px;
    flex-direction: column;
    text-align: center;
  }
  .about-content-left {
    padding-right: 0;
  }
  .about-content-right {
    justify-content: center;
    margin-top: 40px;
  }
  .section-title {
    font-size: 42px;
  }
}

@media (max-width: 1024px) {
  .vision-container,
  .mission-container {
    width: 95%;
    gap: 40px;
  }

  .service-card {
    width: calc(50% - 20px);
  } /* 2 per row */

  .services-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 768px) {
  .site-header {
    flex-direction: column;
    padding-bottom: 20px;
    position: relative;
  }
  .main-nav ul {
    margin: 20px 0;
    gap: 15px;
    flex-wrap: wrap;
    justify-content: center;
  }
  .hero-container,
  .about-container {
    flex-direction: column;
    text-align: center;
    padding: 50px 0;
  }
  .hero-content-left,
  .about-content-left {
    padding-right: 0;
    margin-bottom: 50px;
  }
  .hero-title {
    font-size: 40px;
  }
  .hero-graphic {
    max-width: 400px;
  }
  .features-card {
    padding: 30px;
    column-gap: 30px;
  }

  /* Vision & Mission Mobile Adjustments */
  .vision-container,
  .mission-container {
    flex-direction: column;
    text-align: center;
    width: 100%;
  }

  .mission-container {
    flex-direction: column;
  }

  .vision-content-left {
    order: 2;
    margin-top: 30px;
  }
  .vision-content-right {
    order: 1;
  }

  .vm-title {
    font-size: 38px;
  }
  .vm-text {
    font-size: 18px;
  }

  .landscape-carousel {
    height: 420px;
  }
  .landscape-carousel .carousel-item {
    width: 300px;
    height: 350px;
  }
  .landscape-card .card-img-holder {
    aspect-ratio: 1 / 1;
    height: auto;
  }

  .service-card {
    width: 100%;
  } /* 1 per row */

  .services-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
  }

  .modal-header,
  .modal-scroll-area,
  .modal-actions {
    padding-left: 25px;
    padding-right: 25px;
  }

  /* Footer Mobile Adjustments */
  .footer-container {
    flex-direction: column;
    gap: 30px;
  }
  .footer-col {
    width: 100%;
  }

  .header-right-actions {
    position: absolute;
    top: 20px;
    right: 5%;
    gap: 15px;
  }

  .shop-modal-box {
    max-width: 100%;
    height: 100vh;
    border-radius: 0;
    transform: translateX(100vw);
  }
  .shop-modal-overlay.show-modal .shop-modal-box {
    transform: translateX(0);
  }
}

/* Extra small phones */
@media (max-width: 480px) {
  .shop-grid {
    grid-template-columns: 1fr;
    gap: 20px;
  }
  .services-grid {
    grid-template-columns: 1fr;
    gap: 16px;
  }
}

/* =========================================
   NEW REAL-TIME CALENDAR STYLES
   ========================================= */

.apt-calendar-wrapper {
  display: flex;
  gap: 28px;
  margin-top: 20px;
  flex-wrap: wrap;
}

/* Solid white on a cream hairline, and no shadow at all. These two are panels
   *inside* `.apt-card`, which is itself a shadowed card standing on the maroon
   stage — a shadow here made it three layers of depth for one screen, which is
   what "busy" actually looks like. The hairline is enough to say "separate
   surface". Their radius is owned by the fluid layer further down. */
.apt-calendar-left {
  flex: 2;
  min-width: 300px;
  background: var(--customer-paper);
  border: 1px solid var(--apt-line);
  border-radius: 20px;
  padding: 24px;
}

.apt-time-right {
  flex: 1;
  min-width: 250px;
  background: var(--customer-paper);
  border: 1px solid var(--apt-line);
  border-radius: 20px;
  padding: 24px;
  display: flex;
  flex-direction: column;
}

/* Calendar Navigation */
.cal-navigation {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.cal-navigation h4 {
  font-family: "Montserrat", sans-serif;
  font-size: 18px;
  font-weight: 800;
  color: var(--customer-wine);
  margin: 0;
}

.cal-navigation button {
  background: rgba(107, 32, 43, 0.08);
  border: 1px solid rgba(107, 32, 43, 0.16);
  border-radius: 50%;
  width: 38px;
  height: 38px;
  cursor: pointer;
  font-weight: bold;
  color: var(--customer-wine);
  transition:
    background-color 0.2s ease,
    border-color 0.2s ease,
    color 0.2s ease,
    box-shadow 0.2s ease;
}

/* Calendar Grid */
.cal-days-header {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  text-align: center;
  margin-bottom: 12px;
}

.cal-days-header span {
  font-size: 12px;
  font-weight: 800;
  color: var(--apt-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.cal-days-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 8px;
  margin-bottom: 20px;
}

/* Transparent, not near-white. A month of 30 filled tiles on a white panel is
   30 competing rectangles; with the fill dropped, only the days that have
   something to say (a slot, a note, being picked) carry any colour, and the rest
   reads as ruled paper. The border is what keeps the grid legible. */
.cal-day-cell {
  height: 50px;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  border-radius: 12px;
  font-size: 15px;
  font-weight: 700;
  color: var(--apt-body);
  cursor: pointer;
  border: 1px solid var(--apt-line-warm);
  overflow: hidden;
  background-color: transparent;
}

/* Hover for cells, slots and nav buttons is owned by the shared interaction
   layer further down this file (search "SHARED BUTTON INTERACTIONS") — it fills
   maroon and lightens the glyph, which is the site's darker-only hover. The
   duplicate hover rules that used to sit here were dead. */

/* Flat maroon, matching the selected time slot exactly. These two used to be
   different reds — a gradient here, #b01c1c there — so the date you picked and
   the slot you picked did not look like the same decision.
   The `!important`s are pre-existing and load-bearing: the hover rule in the
   interaction layer is more specific than this one. */
.cal-day-cell.selected {
  background: var(--apt-head) !important;
  color: var(--customer-paper-sink) !important;
  border-color: transparent !important;
  box-shadow: none;
}

/* One disabled treatment, derived from --apt-body at low alpha so no new
   neutral enters the file. Replaces #aaa on black-at-3%/6%. */
.cal-day-cell.disabled,
.cal-day-cell.unavailable {
  color: rgba(75, 85, 99, 0.45);
  background-color: rgba(75, 85, 99, 0.05);
  cursor: not-allowed;
  border-color: transparent;
}

/* The AM/PM/full dot on a day cell. `.cal-day-indicator` and
   `.indicator-marker` used to live here as a second, unused indicator system —
   both were absent from main.html and main.js and are gone. */
.cal-day-cell::after {
  content: "";
  position: absolute;
  bottom: 3px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: none;
}

/* The unfilled half is `--apt-line`, and the legend below now uses the same
   value. It used to be #ddd here and #fff in the legend, so the key did not
   match the thing it was explaining — the one bug in this block that a visitor
   could actually be misled by. */
.cal-day-cell.has-am::after {
  display: block;
  /* Top half shaded */
  background: linear-gradient(to bottom, var(--customer-wine-light) 50%, var(--apt-line) 50%);
  border: 1px solid var(--customer-wine);
}

.cal-day-cell.has-pm::after {
  display: block;
  /* Bottom half shaded */
  background: linear-gradient(to bottom, var(--apt-line) 50%, var(--customer-wine-light) 50%);
  border: 1px solid var(--customer-wine);
}

.cal-day-cell.has-full::after {
  display: block;
  background: var(--customer-wine);
}

/* Tooltip. Darkest maroon rather than #333: it is the only remaining place in
   the flow where a floating black box appeared over warm paper. */
.cal-day-cell[title]:hover::before {
  content: attr(title);
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  background: #3d0808;
  color: var(--customer-paper-sink);
  padding: 5px 10px;
  border-radius: var(--apt-radius-sm);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  z-index: 10;
  pointer-events: none;
}

/* Time Slots Right Panel */
.time-slots-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 15px;
}

/* The day's notice is literally the success card's note panel — `#fffbed` on
   `#eadc9a` — so a caution here and a reference number there are the same kind
   of object. The left rule is thinner and switches to the interactive red,
   because 4px of #8b0000 read as an error banner for something that is usually
   just an opening-hours note. */
.date-note-card {
  display: none;
  margin: 6px 0 10px;
  padding: 10px 12px;
  border: 1px solid var(--apt-panel-edge);
  border-left: 3px solid var(--customer-wine);
  border-radius: var(--apt-radius);
  background: var(--apt-panel);
  color: var(--apt-body);
  max-width: 100%;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.date-note-title {
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--customer-wine);
  margin-bottom: 6px;
}

.date-note-list {
  margin: 0;
  padding-left: 16px;
  display: grid;
  gap: 4px;
  font-size: 0.78rem;
  line-height: 1.45;
}

.time-slot-btn {
  padding: 12px;
  border: 1px solid var(--apt-line);
  border-radius: var(--apt-radius);
  background: var(--customer-paper);
  cursor: pointer;
  text-align: left;
  font-size: 15px;
  font-weight: 700;
  font-family: "Montserrat", sans-serif;
  color: var(--apt-body);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
}

/* Flat maroon, the same value as a selected day cell. */
.time-slot-btn.selected {
  background-color: var(--customer-wine);
  color: var(--customer-paper-sink);
  border-color: var(--customer-wine);
}

.time-slot-btn.disabled {
  background-color: rgba(75, 85, 99, 0.05);
  color: rgba(75, 85, 99, 0.45);
  cursor: not-allowed;
  border-color: transparent;
}

/* A small cream AM/PM pill instead of loose 12px text. Keeps its class name —
   main.js builds the element. The colour pair is `.success-reference span`. */
.time-slot-label {
  flex: none;
  padding: 3px 7px;
  border-radius: 999px;
  background: var(--apt-panel);
  color: var(--apt-gold-label);
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1.2;
}

/* Inverted inside a selected or hovered slot, where the panel colour would
   disappear into the maroon fill. */
.time-slot-btn.selected .time-slot-label,
.time-slot-btn:hover:not(.disabled) .time-slot-label {
  background: rgba(247, 242, 236, 0.16);
  color: var(--apt-gold-soft);
}

/* Legend Styles */
.cal-legend {
  display: flex;
  gap: 15px;
  flex-wrap: wrap;
  margin-top: 15px;
  padding-top: 15px;
  border-top: 1px solid var(--apt-line);
}

.leg-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--apt-muted);
}

.leg-circle {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 1px solid var(--apt-line);
}

/* These four now match the day-cell indicators they explain, value for value. */
.leg-am {
  background: linear-gradient(to bottom, var(--customer-wine-light) 50%, var(--apt-line) 50%);
  border-color: var(--customer-wine);
}
.leg-pm {
  background: linear-gradient(to bottom, var(--apt-line) 50%, var(--customer-wine-light) 50%);
  border-color: var(--customer-wine);
}
.leg-full {
  background: var(--customer-wine);
  border-color: var(--customer-wine);
}
.leg-unavailable {
  width: 12px;
  height: 12px;
  background: rgba(75, 85, 99, 0.14);
  border-radius: 4px;
}

/* =========================================
   ENHANCED APPOINTMENT STEPS (1, 2, 4, 5)
   ========================================= */

/* --- Step 1: Reminders (Enhanced) --- */

/* One cream hairline, not a 2px grey slab. `--apt-line` is the same #f0e8c8 the
   success card rules its footer with, so a section head here and a section head
   there are the same line. */
.apt-card-header {
  border-bottom: 1px solid var(--apt-line);
  padding-bottom: 15px;
  margin-bottom: 20px;
}

/* Maroon, not the brighter #b01c1c: #b01c1c is the site's *interactive* red
   (focus rings, link hovers, the danger bubble). Headings are #5f0d0d, which is
   what every dialog title on the site already uses.

   No gold accent bar here, even though the flow could carry one — §8's
   one-accent rule is what keeps this minimal. There is exactly one section head
   in Step 1 and three more in Step 2; a gold marker on each would mean five
   gold things on screen and the current step circle would stop meaning
   "you are here". The icon and the weight do the work instead. */
.apt-card-header h3 {
  font-family: "Montserrat", sans-serif;
  font-size: 20px;
  color: var(--customer-wine);
  font-weight: 700;
  letter-spacing: 0.01em;
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Barely-there warm paper on a cream hairline. The old #fdfdfd on #eaeaea was
   two cold greys doing the same job in a warm palette. */
.apt-reminder-item {
  display: flex;
  gap: 15px;
  background: #fffdf7;
  border: 1px solid var(--apt-line);
  padding: 20px;
  border-radius: var(--apt-radius);
  /* Colour only. `transform` and `box-shadow` are gone from this list because
     the hover below no longer touches either. */
  transition: border-color 0.2s ease;
  height: 100%;
}

/* The lift is deleted, not softened. The standing rule on this site is "no
   uplift hover, darker colour only", and the shared no-lift guard further down
   this file only zeroes `transform` on `button`s — so this `div` was the one
   surface still rising under the pointer. Now the edge simply warms. */
.apt-reminder-item:hover {
  border-color: var(--apt-panel-edge);
}

/* A solid maroon numeral disc. Deliberately not gold: gold belongs to the
   current step circle and the primary button, and nowhere else. */
.apt-reminder-icon {
  min-width: 40px;
  height: 40px;
  background-color: var(--apt-head);
  color: var(--apt-strip);
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 17px;
  font-weight: 800;
}

.apt-reminder-content h4 {
  font-size: 16px;
  font-weight: 700;
  margin-bottom: 10px;
  color: var(--customer-wine);
}

.apt-reminder-content p,
.apt-reminder-content ol,
.apt-reminder-content ul {
  font-size: 14px;
  color: var(--apt-body);
  line-height: 1.6;
}

/* Was two inline styles on the <ol> and the <ul> in main.html. Same values,
   now in the stylesheet where they can be maintained. */
.apt-reminder-list {
  margin-top: 10px;
}

.apt-reminder-list--disc {
  list-style: disc;
  margin-left: 15px;
}

.apt-reminder-list li {
  margin-bottom: 5px;
  position: relative;
  padding-left: 5px;
}

/* --- Step 2: Form (Enhanced) --- */

/* The single biggest change in the flow. These were three loud 16px maroon
   headings stacked down the form, each one competing with the card's own title;
   they are now quiet uppercase eyebrows — the same device the success card uses
   for "REFERENCE NUMBER". The form reads as one object with three labelled
   regions instead of three forms in a row. */
.apt-form-header {
  grid-column: span 3;
  margin-bottom: 15px;
  margin-top: 10px;
  border-bottom: 1px solid var(--apt-line);
  padding-bottom: 10px;
}

.apt-form-header h4 {
  font-family: "Montserrat", sans-serif;
  font-size: 12.5px;
  font-weight: 800;
  color: var(--customer-wine);
  text-transform: uppercase;
  letter-spacing: 0.09em;
}

/* One label rule for the whole flow. There used to be two — 14px/#333/600 in
   the base layer and 13px/#444/700 here — so the effective style depended on
   which one a reader happened to find. The base one is deleted; this is it. */
.apt-input-group label {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--apt-muted);
  letter-spacing: 0.02em;
  margin-bottom: 6px;
  display: block;
}

/* Named properties instead of `all`. This rule is global (it lives in the
   appointment section but `.c-input` is the site's input class), so the list
   covers every property the focus and error states below actually change. */
.c-input {
  transition:
    border-color 0.3s ease,
    background-color 0.3s ease,
    box-shadow 0.3s ease,
    color 0.3s ease;
}

.c-input:focus {
  border-color: var(--customer-wine);
  box-shadow: 0 0 0 3px rgba(176, 28, 28, 0.1);
  background-color: var(--customer-paper);
}

/* One red on the site. #d32f2f was a fourth off-palette colour that only ever
   appeared when something went wrong — the worst possible moment to introduce a
   hue the visitor has not seen anywhere else. */
.apt-input-group.has-error .c-input {
  border-color: var(--apt-danger);
  box-shadow: 0 0 0 3px rgba(191, 27, 27, 0.14);
  background-color: #fffafa;
}

.apt-field-error-bubble {
  position: absolute;
  right: 0;
  top: 26px;
  transform: translateY(-100%);
  max-width: 290px;
  background: var(--apt-danger);
  color: var(--customer-paper-sink);
  font-size: 12px;
  line-height: 1.35;
  font-weight: 600;
  padding: 8px 10px;
  border-radius: var(--apt-radius-sm);
  box-shadow: 0 10px 18px rgba(27, 4, 4, 0.22);
  z-index: 20;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.16s ease;
}

/* The arrow keeps its `::after` and the bubble keeps its class name — main.js
   builds both, so neither can be renamed. */
.apt-field-error-bubble::after {
  content: "";
  position: absolute;
  right: 18px;
  bottom: -7px;
  width: 14px;
  height: 14px;
  background: var(--apt-danger);
  transform: rotate(45deg);
}

.apt-input-group.has-error .apt-field-error-bubble {
  opacity: 1;
}

.apt-fixed-scroll-textarea {
  resize: none;
  min-height: 88px;
  max-height: 88px;
  overflow-y: auto;
}

/* File Upload Style */

/* A thinner, warmer dash on warm paper. 2px dashed #ccc on #fafafa was the
   loudest neutral in the flow and it framed an empty box. */
.file-upload-wrapper {
  position: relative;
  width: 100%;
  height: 100px;
  border: 1.5px dashed rgba(107, 32, 43, 0.22);
  border-radius: var(--apt-radius);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: #fffdf7;
  transition:
    border-color 0.2s ease,
    background-color 0.2s ease;
  cursor: pointer;
}

.file-upload-wrapper:hover {
  border-color: var(--customer-wine-hover);
  background: var(--customer-paper);
}

.file-upload-icon {
  font-size: 24px;
  color: var(--apt-muted);
  margin-bottom: 5px;
}

.file-upload-text {
  font-size: 12px;
  color: var(--apt-muted);
}

/* Was an inline `margin-top: 10px` on the wrapper in main.html. */
.file-upload-field {
  margin-top: 10px;
}

/* Was four inline properties on the <small>, including a #7a7a7a that existed
   nowhere else in the file. */
.file-upload-name {
  font-size: 11px;
  color: var(--apt-muted);
  margin-top: 4px;
  text-align: center;
}

/* Was five inline properties on the <input type="file">. The input covers the
   whole dashed box so the entire panel is the hit target — that behaviour is
   unchanged, it is only expressed in CSS now. */
.file-upload-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

/* --- Step 4 & 5: one ticket, two states ---------------------------------- */

/* Step 4 is the draft and Step 5 is the issued receipt, and they are the same
   object: same card, same band head, same rows, same labels, same note strip.
   Only the corner chip and Step 5's QR rail differ, so each state is one class
   (`.ticket-chip--draft` / `--issued`, §8.5) instead of the ~15 inline styles
   Step 5 used to carry. */
.ticket-container {
  position: relative;
  max-width: 800px;
  margin: 0 auto;
  overflow: hidden;
  border: 1px solid var(--apt-line);
  border-radius: var(--apt-radius);
  background-color: var(--customer-paper);
  /* Warm, not black: this card is what the success dialog opens on top of, and
     that dialog's whole depth family is rgba(27, 4, 4, …). */
  box-shadow: 0 22px 54px rgba(27, 4, 4, 0.18);
}

/* The approved success-card band, byte for byte (main.css:6004) — including its
   soft corner ring — because the dialog carrying that band fires the moment
   this receipt is finished. Meeting the same head twice is what makes the two
   read as one object instead of two screens that share a red. */
.ticket-header {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 14px;
  overflow: hidden;
  padding: 24px 30px;
  background: linear-gradient(135deg, #3d0808 0%, var(--customer-wine-hover) 52%, var(--customer-wine) 100%);
  color: var(--customer-paper-sink);
}

.ticket-header::after {
  position: absolute;
  right: -45px;
  bottom: -105px;
  width: 220px;
  height: 220px;
  content: "";
  border: 1px solid rgba(241, 237, 18, 0.26);
  border-radius: 50%;
  box-shadow: 0 0 0 26px rgba(241, 237, 18, 0.06);
  pointer-events: none;
}

/* The ring is decorative and paints after the children, so the copy is lifted
   over it rather than the ring being pushed behind the band's background. */
.ticket-header > * {
  position: relative;
  z-index: 1;
}

.ticket-body {
  padding: 30px;
  background: var(--customer-paper);
}

/* Step 5 only: the details grid and the QR rail side by side. */
.ticket-body--split {
  display: flex;
  gap: 20px;
  align-items: stretch;
}

/* Auto-fit rather than a fixed column count, so one rule serves Step 4's
   two-up rows and Step 5's single-item rows with no row surgery, and collapses
   on a phone without a media query. */
.ticket-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr));
  margin-bottom: 20px;
  border-bottom: 1px solid var(--apt-line);
  padding-bottom: 15px;
}

.ticket-row:last-child {
  border-bottom: none;
  margin-bottom: 0;
  padding-bottom: 0;
}

/* Long emails and addresses shrink their track instead of blowing it out. */
.ticket-column {
  min-width: 0;
}

/* The success card's own field label (main.css:6078): gold-brown, 800, wide. */
.t-label {
  margin-bottom: 5px;
  color: var(--apt-gold-label);
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.11em;
  line-height: 1.3;
  text-transform: uppercase;
}

.t-value {
  color: var(--apt-body);
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.6;
}

.t-value.highlight {
  color: var(--customer-wine);
  font-weight: 800;
}

/* Step 5 Specifics */
.success-modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%; /* Changed from 100vw to 100% to prevent scrollbars */
  height: 100%; /* Changed from 100vh to 100% for consistency */
  /* Same story as `.apt-nested-modal` above: fully shadowed by :6025's
     `--ux-dlg-scrim`, kept warm so the fallback agrees with the ladder. */
  background: var(--ux-dlg-scrim);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 25000; /* Highest priority */
  opacity: 0;
  visibility: hidden;
  transition: all 0.4s ease;
}

.success-modal-overlay.active {
  opacity: 1;
  visibility: visible;
}

.success-card {
  background: var(--customer-paper);
  width: 400px;
  padding: 40px 30px;
  border-radius: var(--ux-dlg-radius);
  text-align: center;
  transform: scale(0.8);
  transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.success-modal-overlay.active .success-card {
  transform: scale(1);
}

.success-icon {
  width: 80px;
  height: 80px;
  background: #4caf50;
  color: var(--customer-paper-sink);
  border-radius: 50%;
  margin: 0 auto 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 40px;
  box-shadow: 0 10px 20px rgba(76, 175, 80, 0.3);
}

.success-title {
  font-family: "Montserrat", sans-serif;
  font-size: 24px;
  font-weight: 800;
  color: var(--apt-head);
  margin-bottom: 10px;
}

.success-desc {
  font-size: 15px;
  color: #666;
  margin-bottom: 30px;
  line-height: 1.5;
}

.success-card .apt-btn {
  min-height: 50px;
}

.success-card .apt-btn-outline {
  background-color: var(--customer-paper);
  color: var(--customer-wine);
  border: 2px solid var(--customer-wine);
}

.success-card .apt-btn-outline:hover {
  background-color: #fff5f5;
  color: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
}

/* ================================================================
   APPOINTMENT FLOW — SHARED BUTTON INTERACTIONS & SUCCESS MODAL
   Applies the same clear hover and pressed feedback across Steps 1–5.
   ================================================================ */
.apt-overlay button:not(:disabled),
.apt-nested-modal button:not(:disabled),
.success-modal-overlay button:not(:disabled),
.cal-day-cell:not(.disabled):not(.unavailable) {
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color 0.2s ease,
    background 0.2s ease,
    border-color 0.2s ease,
    color 0.2s ease,
    box-shadow 0.2s ease,
    transform 0.16s ease;
}

.apt-overlay button:not(:disabled):hover,
.apt-nested-modal button:not(:disabled):hover,
.success-modal-overlay button:not(:disabled):hover {
  transform: none;
}

.apt-overlay button:not(:disabled):active,
.apt-nested-modal button:not(:disabled):active,
.success-modal-overlay button:not(:disabled):active,
.cal-day-cell:not(.disabled):not(.unavailable):active {
  transform: scale(0.97);
  box-shadow: 0 5px 12px rgba(45, 12, 12, 0.2);
}

.apt-overlay button:focus-visible,
.apt-nested-modal button:focus-visible,
.success-modal-overlay button:focus-visible,
.cal-day-cell:not(.disabled):not(.unavailable):focus-visible {
  outline: 2px solid rgba(107, 32, 43, 0.45);
  outline-offset: 3px;
}

/* Main proceed and confirmation controls */
.apt-btn-blue:hover {
  background: #c8cc00; /* darker yellow — no gradient */
  color: #3d0808;
  box-shadow: 0 10px 22px rgba(128, 116, 14, 0.24);
}

/* Back, receipt, and outline controls switch to cream fill. */
.apt-btn-back:hover,
.apt-btn-outline:hover {
  background: #f7f2ec; /* cream — not pure white */
  border-color: #f7f2ec;
  color: #3d0808;
  box-shadow: 0 10px 22px rgba(95, 13, 13, 0.26);
}

.apt-btn-cancel:hover {
  background: #3d0808;
  box-shadow: 0 10px 22px rgba(61, 8, 8, 0.26);
}

/* Step 3 schedule controls */
.cal-navigation button:hover {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  box-shadow: 0 8px 18px rgba(95, 13, 13, 0.24);
}

.cal-day-cell:hover:not(.disabled):not(.unavailable) {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  box-shadow: 0 8px 16px rgba(95, 13, 13, 0.2);
}

.cal-day-cell.selected:hover {
  background: #3d0808 !important;
  border-color: #3d0808;
}

.time-slot-btn:hover:not(.disabled) {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  box-shadow: 0 8px 18px rgba(95, 13, 13, 0.22);
}

.time-slot-btn.selected:hover {
  background: #3d0808;
  border-color: #3d0808;
}

.time-slot-btn.disabled:hover {
  transform: none;
  box-shadow: none;
}

/* Step 5 — solid, customer-site-aligned confirmation modal */
.success-modal-overlay {
  background: var(--ux-dlg-scrim);
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
  padding: 24px;
}

.success-card {
  width: min(100%, 460px);
  padding: 0;
  overflow: hidden;
  text-align: left;
  border: 1px solid rgba(241, 237, 18, 0.72);
  border-radius: var(--ux-dlg-radius);
  background: var(--customer-paper);
  box-shadow: 0 28px 70px rgba(27, 4, 4, 0.5);
  transform: translateY(24px) scale(0.96);
  transition: transform 0.32s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.success-modal-overlay.active .success-card {
  transform: translateY(0) scale(1);
}

.success-card__header {
  position: relative;
  overflow: hidden;
  padding: 32px 34px 30px;
  background: linear-gradient(135deg, #3d0808 0%, var(--customer-wine-hover) 52%, var(--customer-wine) 100%);
  color: var(--customer-paper-sink);
}

.success-card__header::after {
  position: absolute;
  right: -45px;
  bottom: -105px;
  width: 220px;
  height: 220px;
  content: "";
  border: 1px solid rgba(241, 237, 18, 0.26);
  border-radius: 50%;
  box-shadow: 0 0 0 26px rgba(241, 237, 18, 0.06);
}

.success-icon {
  position: relative;
  z-index: 1;
  width: 56px;
  height: 56px;
  margin: 0 0 18px;
  border: 3px solid rgba(247, 242, 236, 0.42);
  background: #f1ed12;
  color: var(--customer-wine);
  font-size: 29px;
  font-weight: 800;
  box-shadow: 0 10px 20px rgba(45, 12, 12, 0.22);
}

.success-eyebrow {
  position: relative;
  z-index: 1;
  margin: 0 0 6px;
  color: #f5ef8e;
  font-family: "Montserrat", sans-serif;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.success-title {
  position: relative;
  z-index: 1;
  margin: 0;
  color: var(--customer-paper-sink);
  font-size: clamp(22px, 5vw, 27px);
  line-height: 1.22;
}

.success-card__body {
  padding: 28px 34px 24px;
}

.success-desc {
  margin: 0;
  color: #4b5563;
  font-size: 14px;
  line-height: 1.65;
}

.success-reference {
  display: grid;
  justify-items: center;
  gap: 5px;
  margin: 22px 0 18px;
  padding: 15px 17px;
  border: 1px solid #eadc9a;
  border-radius: 12px;
  background: #fffbed;
  text-align: center;
}

.success-reference span {
  color: #77610d;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}

.success-reference strong {
  color: var(--customer-wine);
  font-family: "Montserrat", sans-serif;
  font-size: clamp(17px, 4vw, 20px);
  letter-spacing: 0.04em;
  overflow-wrap: anywhere;
}

.success-note {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  margin: 0;
  color: #6b7280;
  font-size: 12px;
  line-height: 1.5;
}

.success-note i {
  margin-top: 2px;
  color: var(--customer-wine);
}

.success-card__footer {
  padding: 0 34px 32px;
}

.success-card__footer .apt-btn {
  display: flex;
  width: 100%;
  min-height: 51px;
  justify-content: center;
  align-items: center;
  gap: 9px;
  text-decoration: none;
}

.success-card__footer .apt-btn span {
  text-decoration: none;
}

@media (max-width: 480px) {
  .success-modal-overlay {
    padding: 16px;
  }

  .success-card__header,
  .success-card__body {
    padding-right: 24px;
    padding-left: 24px;
  }

  .success-card__footer {
    padding: 0 24px 24px;
  }
}

/* Product Ratings & Footer Styles */
.product-rating {
  cursor: default;
  margin-bottom: 8px;
  font-size: 14px;
  color: #555;
}

.stars {
  color: #ffc107; /* Yellow stars */
  letter-spacing: 2px;
}

.rating-text {
  margin-left: 5px;
  color: #777;
  font-size: 13px;
}

.product-footer {
  margin-top: 15px;
  padding-top: 15px;
  border-top: 1px solid #eee;
  text-align: center;
}

.view-info-btn {
  background: none;
  border: none;
  color: var(--customer-wine);
  font-weight: 600;
  cursor: pointer;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  transition: opacity 0.2s;
}

.view-info-btn:hover {
  opacity: 0.8;
  text-decoration: underline;
}

/* =========================================
   LANDING PAGE ENHANCEMENT OVERRIDES
   ========================================= */

.hero-section {
  background:
    radial-gradient(
      circle at 80% 18%,
    rgba(247, 242, 236, 0.26) 0%,
      transparent 42%
    ),
    linear-gradient(145deg, var(--customer-wine, #6b202b) 0%, var(--customer-wine-light, #b01c1c) 44%, var(--customer-wine-light, #b01c1c) 100%);
}

.hero-section::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(45, 12, 12, 0.08), rgba(45, 12, 12, 0.18));
  pointer-events: none;
}

.hero-container {
  position: relative;
  z-index: 1;
}

.hero-title {
  letter-spacing: 0.8px;
}

.hero-research-line {
  display: inline-block;
  white-space: nowrap;
}

.hero-graphic {
  padding: 18px;
  border: 3px solid rgba(247, 242, 236, 0.28);
}

.about-section,
.vision-section,
.mission-section,
.services-preview-section {
  position: relative;
}

/* A card in mid-gesture has to be able to leave its own section.
   ---------------------------------------------------------------------------
   The four sections above are positioned siblings with no z-index, so they
   paint in document order and Our Mission covers Our Vision. A Vision card
   thrown downwards travels `dy * 4`, which is far enough to cross the border,
   and it was being painted *behind* the next section — the card's own
   `z-index: 6` cannot help, because `.vision-content-left` is a stacking
   context (`will-change: transform, opacity`, just below).

   So the fix is on the ancestor: main.js toggles this class on the enclosing
   section for the length of the gesture only. 5 beats a sibling's `auto` and
   stays far below `.site-header`'s sticky 100 and the modals' 9999, so a photo
   in flight can never cover the navbar. It is removed again the moment the card
   is handed back to the slot system, so normal stacking is the resting state. */
.vision-section.vm-card-aloft,
.mission-section.vm-card-aloft {
  z-index: 5;
}

.about-section {
  background: linear-gradient(180deg, var(--customer-paper) 0%, #fff7f7 100%);
}

/* `will-change: transform, opacity` used to be declared here on ten selectors.
   It was removed: seven of them are scroll-reveal targets that already receive
   it from `.reveal-on-scroll` and — crucially — have it *released* again by
   `.reveal-on-scroll.reveal-settled { will-change: auto }` once the reveal has
   played. The other three (`.services-container`, `.footer-col`,
   `.footer-bottom`) are not reveal targets at all, so they never animate and
   this rule was pinning six permanent compositor layers per page for the whole
   visit. `will-change` has no visual effect, so nothing here is a design
   change. */

.about-content-right {
  justify-content: center;
}

.about-video-holder {
  width: 100%;
  max-width: 560px;
  height: 460px;
  border-radius: var(--ux-card-radius);
  overflow: hidden;
  position: relative;
  /* One shadow, matching the three content slabs. The pair this replaces —
     `0 25px 60px rgba(139,0,0,.2)` over `0 6px 18px rgba(0,0,0,.12)` — put a
     60px maroon bloom around the one element on the page that is already the
     darkest thing in its band, so the video read as lit from behind. */
  box-shadow: 0 10px 26px rgba(65, 16, 16, 0.06);
  border: 1px solid var(--apt-line-warm);
  /* Not a panel fill: this is the letterbox behind a 16:9 clip in a 560×460
     box, so it wants to be darker than the video's own darkest frame. */
  background: #2c0000;
  cursor: pointer;
}

.about-preview-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Desktop only. A CSS `filter` on a <video> disqualifies it from Android's
   zero-copy hardware overlay path: every decoded 1080p frame has to be uploaded
   as a GL texture and run through a shader instead. That is a lot of per-frame
   GPU work to buy a 4% saturation / 5% contrast nudge, so phones get the clip
   unfiltered and hardware-composited. */
@media (min-width: 901px) {
  .about-preview-video {
    filter: saturate(1.04) contrast(1.05);
  }
}

.about-video-control {
  position: absolute;
  bottom: 20px;
  right: 20px;
  width: 56px;
  height: 56px;
  border: none;
  border-radius: 50%;
  background: var(--customer-wine);
  color: #eef224;
  font-size: 24px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 10px 22px rgba(45, 12, 12, 0.3);
  cursor: pointer;
  transition:
    transform 0.2s ease,
    background-color 0.2s ease;
}

/* Darker fill only, then a press. `scale(1.06)` on hover was the last growth
   hover left on a home-page control; the fill was already darkening on its own,
   so the growth was carrying no information the colour did not. `transform`
   stays in the transition list above for the press below. */
.about-video-control:hover {
  background: var(--customer-wine-hover);
}

.about-video-control:active {
  transform: scale(0.97);
  background: var(--customer-wine-hover);
}

.about-video-control::before {
  content: "";
  display: block;
}

.about-video-control.is-paused::before {
  width: 0;
  height: 0;
  margin-left: 4px;
  border-top: 11px solid transparent;
  border-bottom: 11px solid transparent;
  border-left: 17px solid currentColor;
}

.about-video-control.is-playing::before {
  width: 7px;
  height: 22px;
  border-radius: 1px;
  background: currentColor;
  box-shadow: 12px 0 currentColor;
  transform: translateX(-6px);
}

.about-video-modal {
  position: fixed;
  inset: 0;
  background: var(--ux-dlg-scrim-media);
  z-index: 22000;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 28px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.25s ease,
    visibility 0.25s ease;
}

.about-video-modal.show-video-modal {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.about-video-modal-box {
  width: min(1100px, 95vw);
  border-radius: var(--ux-dlg-radius);
  overflow: hidden;
  /* The letterbox behind the video. Pure #000 was the only true black left on a
     home-page surface; --customer-ink-strong is the near-black from the owner's
     reference and reads warmer against the maroon scrim. */
  background: var(--customer-ink-strong);
  box-shadow: 0 20px 50px rgba(45, 12, 12, 0.45);
}

.about-full-video {
  width: 100%;
  max-height: 82vh;
  display: block;
  background: var(--customer-ink-strong);
}

.about-video-close {
  position: absolute;
  top: 18px;
  right: 22px;
  width: 44px;
  height: 44px;
  border: none;
  border-radius: 50%;
  background: var(--customer-wine);
  color: #eef224;
  font-size: 30px;
  line-height: 1;
  cursor: pointer;
}

/* =========================================
   CONTACT PAGE STYLES
   ========================================= */

.contact-page-body {
  background:
    radial-gradient(
      circle at 8% 10%,
      rgba(241, 237, 18, 0.18),
      transparent 22rem
    ),
    radial-gradient(
      circle at 90% 18%,
      rgba(107, 32, 43, 0.12),
      transparent 24rem
    ),
    linear-gradient(135deg, #fffaf0 0%, #f5f7f2 46%, #fffdf8 100%);
}

.contact-main-section {
  padding: 60px 5% 80px;
}

.contact-page-container {
  max-width: 1300px;
  margin: 0 auto;
}

.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1.1fr;
  gap: 32px;
}

.contact-info-card,
.contact-form-card {
  background: linear-gradient(
    135deg,
    rgba(247, 242, 236, 0.94),
    rgba(255, 248, 238, 0.88)
  );
  border: 1px solid rgba(107, 32, 43, 0.14);
  border-radius: var(--ux-card-radius);
  padding: 40px;
  box-shadow:
    0 24px 60px rgba(61, 35, 28, 0.1),
    inset 0 1px 0 rgba(247, 242, 236, 0.95);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

.contact-title,
.contact-subtitle {
  font-family: "Montserrat", sans-serif;
  color: var(--customer-wine);
  margin: 0 0 14px;
  letter-spacing: -0.035em;
}

.contact-title {
  font-size: clamp(30px, 4vw, 42px);
  font-weight: 900;
}

.contact-subtitle {
  font-size: clamp(24px, 3vw, 32px);
  font-weight: 800;
}

.contact-lead {
  color: #5c626e;
  font-size: 16px;
  line-height: 1.7;
  margin-bottom: 28px;
}

.contact-links-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.contact-links-list li {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 16px 18px;
  border-radius: 18px;
  border: 1px solid rgba(107, 32, 43, 0.12);
  background: rgba(247, 242, 236, 0.9);
  box-shadow: 0 6px 18px rgba(61, 35, 28, 0.04);
  transition: all 0.22s ease;
}

.contact-links-list li:hover {
  background: var(--customer-paper);
  border-color: rgba(107, 32, 43, 0.25);
  box-shadow: 0 12px 28px rgba(128, 24, 18, 0.08);
}

.contact-link-icon {
  color: var(--customer-wine);
  display: inline-flex;
  margin-top: 2px;
}

.contact-link-text {
  color: #222833;
  text-decoration: none;
  font-size: 15px;
  line-height: 1.5;
  font-weight: 600;
  transition: color 0.2s ease;
}

.contact-link-text:hover {
  color: var(--customer-wine-hover);
  text-decoration: underline;
}

.contact-form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}

.contact-field-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.contact-field-group label {
  font-size: 12px;
  font-weight: 800;
  color: #343b49;
  letter-spacing: 0.04em;
}

.contact-input {
  width: 100%;
  border: 1px solid rgba(107, 32, 43, 0.14);
  border-radius: 18px;
  background: rgba(255, 254, 250, 0.86);
  padding: 14px 18px;
  outline: none;
  font-size: 14px;
  font-family: "Montserrat", sans-serif;
  color: #222833;
  box-shadow:
    inset 0 1px 0 rgba(247, 242, 236, 0.9),
    0 8px 18px rgba(72, 27, 22, 0.04);
  transition: all 0.2s ease;
}

.contact-input:focus {
  border-color: rgba(107, 32, 43, 0.64);
  background: var(--customer-paper);
  box-shadow:
    0 0 0 4px rgba(158, 20, 20, 0.08),
    0 14px 28px rgba(72, 27, 22, 0.09);
}

.contact-textarea {
  resize: vertical;
  min-height: 170px;
}

.full-width {
  grid-column: 1 / -1;
}

.contact-form-actions {
  display: flex;
  justify-content: flex-end;
}

/* The last gradient button on the customer site. It carried a three-stop
   maroon→#c68317 ramp, an 18px radius and a shadow that grew on hover — three
   things the owner ruled out in one sentence. Now the same recipe as the two hero
   CTAs: flat fill, the card's 8px corner, hover darkens the fill only and repeats
   the resting shadow verbatim, press scales. `background-image: none` is spelled
   out so `--customer-wash` can never reach a button. */
.contact-submit-btn {
  border: none;
  background-color: var(--customer-wine);
  background-image: none;
  color: var(--customer-paper-sink, #f7f2ec);
  font-family: "Montserrat", sans-serif;
  font-size: 15px;
  font-weight: 800;
  padding: 16px 36px;
  border-radius: var(--apt-radius, 8px);
  cursor: pointer;
  box-shadow: 0 10px 22px rgba(128, 24, 18, 0.2);
  transition:
    background-color 0.2s ease,
    box-shadow 0.2s ease,
    transform 0.1s ease;
}

.contact-submit-btn:hover {
  background-color: #3d0808;
  background-image: none;
  box-shadow: 0 10px 22px rgba(128, 24, 18, 0.2);
  transform: none;
}

.contact-submit-btn:active {
  transform: scale(0.97);
}

.contact-submit-btn:focus-visible {
  outline: 3px solid rgba(241, 237, 18, 0.55);
  outline-offset: 2px;
}

.contact-submit-btn.is-loading {
  opacity: 0.85;
  cursor: wait;
  pointer-events: none;
}

.contact-submit-btn > .fmrc-load-inline {
  --fmrc-inline-size: 18px;
  vertical-align: middle;
  margin-right: 8px;
}

.vision-section {
  background: var(--customer-paper);
}

.mission-section {
  background: linear-gradient(180deg, #fff9f9 0%, #fff4f4 100%);
}

.vision-img,
.mission-img {
  border: 1px solid rgba(107, 32, 43, 0.15);
}

.vm-title {
  text-shadow: 0 4px 16px rgba(176, 28, 28, 0.08);
}

.services-preview-section {
  background: linear-gradient(180deg, var(--customer-paper) 0%, #fff8f8 100%);
}

.services-preview-section .section-title {
  letter-spacing: 1.2px;
}

.landscape-card {
  border: 1px solid rgba(107, 32, 43, 0.08);
  box-shadow: 0 18px 34px rgba(176, 28, 28, 0.1);
}

.site-footer {
  background: linear-gradient(140deg, var(--customer-wine) 0%, var(--customer-wine) 48%, var(--customer-wine) 100%);
  border-top: 4px solid #eef224;
  margin-bottom: 0;
  padding-bottom: 0;
}

.footer-container {
  gap: 45px;
}

.footer-heading {
  letter-spacing: 0.5px;
}

.footer-menu a,
.footer-link,
.footer-text,
.contact-list li,
.footer-desc {
  opacity: 0.95;
}

.footer-bottom {
  padding-bottom: 20px;
}

/* --- Scroll Reveal Animation ---
   `--reveal-delay` is written by main.js: when a batch of blocks crosses the
   viewport they are sorted by their on-screen top and handed 0ms, 90ms, 180ms…
   so a stacked phone section lifts one block at a time instead of the whole
   section arriving in a single frame. `ease` was also doing the animation no
   favours at 0.8s — a decelerating curve reads as smooth at 0.7s and keeps a
   staggered run from feeling long. */
.reveal-on-scroll {
  opacity: 0;
  transform: translateY(26px);
  transition:
    opacity 0.7s cubic-bezier(0.22, 0.61, 0.36, 1),
    transform 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}

/* `none`, not `translateY(0)`: any transform value keeps the element a
   containing block for fixed-position descendants, and `.about-content-right`
   holds `.about-video-modal` (position: fixed). Resting at `none` hands the
   viewport back. */
.reveal-on-scroll.show-reveal {
  opacity: 1;
  transform: none;
}

/* Dropped once the lift has played: `will-change` on a dozen sections keeps
   compositor layers alive for the life of the page for no benefit. */
.reveal-on-scroll.reveal-settled {
  will-change: auto;
  transition-delay: 0ms;
}

/* Direction variants. The default reveal rises from below; these three let a
   section enter from a named edge instead, which is what gives Vision (left),
   Mission (right) and What We Offer (bottom) three distinct entrances.

   `:not(.show-reveal)` is load-bearing, not decoration. Without it a variant
   would be `.reveal-on-scroll.reveal-from-left` — (0,2,0), exactly the same
   weight as `.reveal-on-scroll.show-reveal` above — and whichever came last in
   the file would win, so the block would either never move or never arrive.
   Qualifying it takes the variant to (0,3,0) for the resting state only, and
   the `transform: none` of `.show-reveal` still applies once the class lands,
   regardless of source order. */
/* The offset is a fraction of the page gutter because a fixed one does not fit a
   phone. Measured at a 394px viewport, an un-revealed Mission block rests 37.7px
   clear of the right edge — the section's `--ux-gutter` (16.5px at 4.2vw) plus the
   container's own 20px — so the old flat 56px pushed it 18.3px *past* the
   viewport, and Vision pushed the same distance past the left. A transform does
   not change layout but it does add visual overflow, which is why the home page
   could be panned sideways to an empty strip until a block had been revealed:
   exactly the "sometimes" in the owner's report, since the overflow disappears
   the moment `.show-reveal` lands.

   `--ux-gutter` is the right basis rather than a vw of my own, because the gutter
   *is* what produces the slack: every one of these blocks sits inside a section
   padded by exactly that token, so 0.6 of it can never reach the edge no matter
   how the token is redefined later. That matters at the 280px band, where
   responsive.css:450 drops the gutter to 7px and `.vision-container` carries no
   padding at all — slack there is 7.8px, and a 3.6vw rule would still have
   overflowed by 6.2px while 0.6 of the gutter lands at 4.2px. Resolved widths:
   4.2px at 280, 9.9px at 394, 22.7px at 900, 34.4px at 1366, 43.2px at 1714 and
   up. `.reveal-from-bottom` keeps its flat 64px: vertical overflow costs nothing
   on a page that already scrolls that way. */
.reveal-on-scroll.reveal-from-left:not(.show-reveal) {
  transform: translate3d(calc(-0.6 * var(--ux-gutter)), 0, 0);
}

.reveal-on-scroll.reveal-from-right:not(.show-reveal) {
  transform: translate3d(calc(0.6 * var(--ux-gutter)), 0, 0);
}

.reveal-on-scroll.reveal-from-bottom:not(.show-reveal) {
  transform: translate3d(0, 64px, 0);
}

/* Reduced motion: show everything, animate nothing. The direction variants have
   to be named here too — each is (0,3,0), so the plain `.reveal-on-scroll`
   reset below cannot reach them and a block would sit permanently 56px off to
   one side with no transition to bring it back. */
@media (prefers-reduced-motion: reduce) {
  .reveal-on-scroll,
  .reveal-on-scroll.show-reveal,
  .reveal-on-scroll.reveal-from-left:not(.show-reveal),
  .reveal-on-scroll.reveal-from-right:not(.show-reveal),
  .reveal-on-scroll.reveal-from-bottom:not(.show-reveal) {
    opacity: 1;
    transform: none;
    transition: none;
    will-change: auto;
  }
}

@media (max-width: 1100px) {
  .about-video-holder {
    height: 400px;
  }
}

@media (max-width: 768px) {
  .about-video-holder {
    max-width: 100%;
    height: 320px;
  }

  .about-video-control {
    width: 50px;
    height: 50px;
    font-size: 20px;
    bottom: 14px;
    right: 14px;
  }

  .about-video-close {
    top: 10px;
    right: 12px;
  }

  .contact-main-section {
    padding: 35px 5% 55px;
  }

  .contact-grid {
    grid-template-columns: 1fr;
  }

  .contact-info-card,
  .contact-form-card {
    padding: 24px;
  }

  .contact-title {
    font-size: 30px;
  }

  .contact-subtitle {
    font-size: 25px;
  }

  .contact-form-grid {
    grid-template-columns: 1fr;
  }

  .contact-form-actions {
    justify-content: stretch;
  }

  .contact-submit-btn {
    width: 100%;
  }

  .hero-section {
    min-height: calc(100vh - 70px);
  }

  .site-footer {
    border-top-width: 3px;
  }
}

/* =========================================
   MOBILE SIDEBAR NAV + RESPONSIVE OVERRIDES
   ========================================= */

.mobile-menu-toggle {
  display: none;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--customer-paper-edge);
  background: var(--customer-paper);
  cursor: pointer;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 5px;
  transition:
    background-color 0.25s ease,
    transform 0.1s ease,
    border-color 0.25s ease;
}

.mobile-menu-toggle span {
  width: 20px;
  height: 2.2px;
  border-radius: 2px;
  background: #222;
  transition:
    transform 0.25s ease,
    opacity 0.25s ease;
}

.mobile-menu-toggle:hover {
  background: #f1f1f1;
  border-color: #cfcfcf;
}

.mobile-menu-toggle:active {
  transform: scale(0.96);
}

.mobile-menu-toggle.is-open span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}

.mobile-menu-toggle.is-open span:nth-child(2) {
  opacity: 0;
}

.mobile-menu-toggle.is-open span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

.sidebar-backdrop {
  position: fixed;
  inset: 0;
  /* The one scrim the desktop sweep could never reach, because the sidebar only
     exists at phone widths: it was a neutral rgba(20, 20, 20, …) veil behind a
     3px blur, while every dialog on the site scrims with `--ux-dlg-scrim`. Same
     token now, and the blur is gone rather than raised to the dialogs' 8px — a
     full-viewport `backdrop-filter` is exactly the per-frame cost the phone pass
     was spent removing, and at 0.55 alpha the veil no longer needs it. */
  background: var(--ux-dlg-scrim);
  z-index: 11000;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.25s ease,
    visibility 0.25s ease;
}

.mobile-sidebar {
  position: fixed;
  top: 0;
  left: 0;
  width: min(88vw, 340px);
  height: 100dvh;
  background: var(--customer-paper);
  z-index: 11010;
  transform: translateX(-105%);
  transition: transform 0.28s ease;
  box-shadow: 10px 0 35px rgba(45, 12, 12, 0.22);
  display: flex;
  flex-direction: column;
}

.mobile-sidebar.open {
  transform: translateX(0);
}

.sidebar-backdrop.show {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.sidebar-header {
  display: grid;
  grid-template-columns: 44px 1fr;
  align-items: center;
  gap: 10px;
  padding: 14px 14px 12px;
  border-bottom: 1px solid #ececec;
}

.sidebar-close-btn {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--customer-paper-edge, #efe6da);
  background: var(--customer-paper, #fdfaf6);
  color: var(--customer-wine);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  transition:
    background-color 0.25s ease,
    transform 0.1s ease,
    border-color 0.25s ease;
}

.sidebar-close-btn:hover {
  background: var(--apt-panel, #fffbed);
  border-color: var(--apt-panel-edge, #eadc9a);
}

.sidebar-close-btn:active {
  transform: scale(0.96);
}

.sidebar-logo-container {
  display: flex;
  align-items: center;
  text-decoration: none;
  min-width: 0;
}

.sidebar-logo-container .header-emblem {
  height: 36px;
  margin-right: 10px;
}

.sidebar-logo-container .logo-text {
  max-width: 230px;
}

.sidebar-logo-container .logo-title {
  font-size: 12px;
}

.sidebar-logo-container .logo-subtitle {
  font-size: 9px;
}

.sidebar-nav {
  padding: 16px 12px 20px;
  overflow-y: auto;
}

.sidebar-nav ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.sidebar-nav .nav-link {
  display: block;
  width: 100%;
  padding: 12px 12px;
  /* The drawer is the phone's navbar, so its rows sit on the same radius ladder
     as everything else the round touched — 10px was the last stray value left in
     the header chrome. */
  border-radius: var(--apt-radius);
  pointer-events: auto;
}

.sidebar-nav .nav-link:hover,
.sidebar-nav .nav-link.active {
  background: #fbecec;
  color: var(--customer-wine-hover);
}

body.sidebar-open {
  overflow: hidden !important;
}

@media (max-width: 900px) {
  .mobile-menu-toggle {
    display: inline-flex;
    flex-shrink: 0;
  }

  .site-header {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    padding: 12px 4%;
  }

  .main-nav {
    display: none;
  }

  .site-header .logo-container {
    display: flex;
    align-items: center;
    margin-right: auto;
    margin-left: 2px;
    min-width: 0;
    flex: 1;
  }

  .site-header .header-emblem {
    height: 40px;
    margin-right: 10px;
  }

  .site-header .logo-text {
    max-width: 210px;
    line-height: 1.05;
  }

  .site-header .logo-title {
    font-size: 11px;
    letter-spacing: 0.3px;
  }

  .site-header .logo-subtitle {
    font-size: 8px;
    letter-spacing: 0.4px;
  }

  .header-right-actions {
    display: flex;
    align-items: center;
    position: static !important;
    top: auto !important;
    right: auto !important;
    margin-left: 0;
    gap: 10px;
    flex-shrink: 0;
  }

  .hero-section {
    min-height: calc(100vh - 70px);
    padding: 16px 5% 42px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }

  .hero-container {
    flex-direction: column;
    justify-content: center;
    align-items: center;
    max-width: 100%;
    gap: 0;
    text-align: center;
  }

  .hero-content-left {
    width: 100%;
    padding-right: 0;
    margin-bottom: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    order: 2;
  }

  .hero-content-right {
    order: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    margin-bottom: 14px;
  }

  .hero-graphic {
    width: clamp(130px, 34vw, 180px);
    max-width: 180px;
    padding: 8px;
    border-width: 2px;
  }

  .hero-title {
    font-size: clamp(30px, 8.2vw, 42px);
    line-height: 1.2;
    margin-bottom: 16px;
  }

  .hero-buttons {
    width: 100%;
    max-width: 380px;
    flex-wrap: nowrap;
    justify-content: center;
    gap: 10px;
  }

  .btn-browse,
  .btn-appointment {
    flex: 1;
    padding: 12px 10px;
    font-size: 13px;
    border-radius: var(--apt-radius, 8px);
    white-space: nowrap;
  }

  .scroll-indicator {
    position: static;
    left: auto;
    bottom: auto;
    transform: none;
    margin: 18px auto 0;
    width: fit-content;
    animation: bounceY 2s infinite;
  }

  .scroll-icon {
    margin-top: 5px;
  }

  .footer-container {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "brand brand"
      "quick hours"
      "contact contact";
    gap: 22px;
  }

  .footer-container .footer-col:nth-child(1) {
    grid-area: brand;
  }

  .footer-container .footer-col:nth-child(2) {
    grid-area: quick;
  }

  .footer-container .footer-col:nth-child(3) {
    grid-area: hours;
  }

  .footer-container .footer-col:nth-child(4) {
    grid-area: contact;
  }

  .footer-heading {
    margin-bottom: 14px;
    font-size: 19px;
  }

  .apt-container {
    max-width: 100%;
    padding: 12px 4% 18px;
  }

  .apt-header-top {
    margin-top: 4px;
    margin-bottom: 18px;
    gap: 8px;
  }

  .apt-main-title {
    font-size: 25px;
  }

  .apt-progress-wrapper {
    overflow-x: auto;
    gap: 8px;
    padding-bottom: 8px;
  }

  .apt-line {
    min-width: 26px;
    margin-top: 34px;
  }

  .apt-step {
    min-width: 72px;
  }

  .apt-icon {
    width: 42px;
    height: 42px;
  }

  .apt-card {
    padding: 18px;
  }

  .apt-form-grid {
    grid-template-columns: 1fr !important;
    gap: 14px;
  }

  .apt-form-header {
    grid-column: span 1;
  }

  .apt-calendar-wrapper {
    flex-direction: column;
    gap: 16px;
  }

  .apt-calendar-left,
  .apt-time-right {
    min-width: 0;
    width: 100%;
  }

  .ticket-body {
    padding: 18px;
  }

  .ticket-row {
    flex-direction: column;
    gap: 8px;
  }

  .apt-footer-actions {
    flex-direction: column-reverse;
    gap: 10px;
    padding-bottom: 22px;
  }

  .apt-btn {
    width: 100%;
  }
}

@media (max-width: 420px) {
  .site-header .logo-text {
    max-width: 168px;
  }

  .site-header .logo-title {
    font-size: 10px;
  }

  .site-header .logo-subtitle {
    font-size: 7px;
    letter-spacing: 0.28px;
  }

  .site-header .header-emblem {
    height: 35px;
    margin-right: 8px;
  }

  .hero-title {
    font-size: clamp(25px, 7.8vw, 32px);
  }

  .hero-buttons {
    max-width: 100%;
  }

  .btn-browse,
  .btn-appointment {
    font-size: 12px;
    padding: 11px 8px;
  }
}

@keyframes bounceY {
  0%,
  20%,
  50%,
  80%,
  100% {
    transform: translateY(0);
  }
  40% {
    transform: translateY(-8px);
  }
  60% {
    transform: translateY(-4px);
  }
}

/* =========================================
   MOBILE CONTENT SCALE TUNING (RESPONSIVE ONLY)
   ========================================= */

@media (max-width: 900px) {
  .about-section,
  .vision-section,
  .mission-section,
  .services-preview-section {
    padding-top: 64px;
    padding-bottom: 64px;
  }

  .section-title {
    font-size: clamp(34px, 7vw, 46px);
    margin-bottom: 22px;
  }

  .section-text {
    font-size: 17px;
    line-height: 1.75;
  }

  .vm-title {
    font-size: clamp(32px, 6.5vw, 44px);
    margin-bottom: 16px;
  }

  .vm-text {
    font-size: 20px;
    line-height: 1.65;
  }

  .vision-img,
  .mission-img {
    max-width: 600px;
  }

  .landscape-carousel {
    height: 460px;
  }

  .landscape-carousel .carousel-item {
    width: 330px;
    height: 385px;
  }

  .landscape-card .card-img-holder {
    height: 190px;
  }

  .card-title {
    font-size: 22px;
  }

  .card-desc {
    font-size: 16px;
    line-height: 1.65;
  }

  .view-all-btn {
    font-size: 17px;
    padding: 16px 44px;
  }

  .products-toolbar {
    padding-top: 18px;
    padding-bottom: 18px;
  }

  .toolbar-search .search-input,
  .category-select,
  .search-input {
    font-size: 16px;
  }

  .carousel-wrapper {
    height: 540px;
  }

  .carousel-item {
    width: 300px;
    height: 430px;
  }

  .shop-grid {
    gap: 20px;
  }

  .product-img-wrapper {
    height: 230px;
  }

  .product-name {
    font-size: 18px;
  }

  .product-price {
    font-size: 24px;
  }

  .stock-text,
  .rating-count,
  .rating-score,
  .code-value,
  .code-label {
    font-size: 13px;
  }

  .action-btn {
    font-size: 12px;
    padding: 12px 10px;
  }

  .contact-title {
    font-size: clamp(34px, 6.4vw, 42px);
  }

  .contact-subtitle {
    font-size: clamp(30px, 5.8vw, 36px);
  }

  .contact-lead {
    font-size: 17px;
  }

  .contact-link-text,
  .contact-input,
  .contact-field-group label {
    font-size: 16px;
  }

  .contact-submit-btn {
    font-size: 16px;
    padding: 14px 30px;
  }

  .site-footer {
    padding-top: 56px;
  }

  .footer-brand {
    font-size: 28px;
  }

  .footer-heading {
    font-size: 22px;
  }

  .footer-menu a,
  .footer-link,
  .footer-text,
  .footer-desc,
  .contact-list li {
    font-size: 17px;
    line-height: 1.6;
  }

  .apt-main-title {
    font-size: 30px;
  }

  .apt-card {
    padding: 24px;
  }

  .apt-card-header h3 {
    font-size: 22px;
  }

  .apt-reminder-content h4 {
    font-size: 18px;
  }

  .apt-reminder-content p,
  .apt-reminder-content ol,
  .apt-reminder-content ul,
  .apt-reminder-list li {
    font-size: 15px;
    line-height: 1.65;
  }

  .apt-form-header h4 {
    font-size: 17px;
  }

  .apt-input-group label,
  .c-input,
  .t-value,
  .t-label,
  .time-slot-btn,
  .cal-days-header span,
  .leg-item,
  #selectedDateDisplay,
  #slotCounter,
  .calendar-header-text p {
    font-size: 15px;
  }

  .calendar-header-text h3,
  #calMonthYear {
    font-size: 22px;
  }

  .cal-day-cell {
    height: 54px;
    font-size: 16px;
  }

  .apt-btn {
    font-size: 16px;
    padding: 14px 22px;
  }

  .ticket-header h3 {
    font-size: 26px !important;
  }
}

@media (max-width: 768px) {
  .about-section,
  .vision-section,
  .mission-section,
  .services-preview-section {
    padding-top: 52px;
    padding-bottom: 52px;
  }

  .section-title {
    font-size: clamp(30px, 8vw, 38px);
  }

  .section-text {
    font-size: 16px;
  }

  .vm-title {
    font-size: clamp(28px, 7.5vw, 34px);
  }

  .vm-text {
    font-size: 18px;
  }

  .landscape-carousel {
    height: 430px;
  }

  .landscape-carousel .carousel-item {
    width: 315px;
    height: 365px;
  }

  .card-title {
    font-size: 20px;
  }

  .card-desc {
    font-size: 15px;
  }

  .view-all-btn {
    font-size: 16px;
    padding: 15px 36px;
  }

  .products-toolbar {
    margin-bottom: 20px;
  }

  .toolbar-container {
    gap: 12px;
  }

  .toolbar-search,
  .category-dropdown-box {
    border-radius: 12px;
  }

  .shop-section {
    padding-bottom: 60px;
  }

  .product-name {
    font-size: 17px;
  }

  .product-price {
    font-size: 22px;
  }

  .action-btn {
    font-size: 11.8px;
  }

  .contact-info-card,
  .contact-form-card {
    padding: 26px;
  }

  .contact-title {
    font-size: 32px;
  }

  .contact-subtitle {
    font-size: 28px;
  }

  .contact-lead,
  .contact-link-text,
  .contact-input {
    font-size: 15px;
  }

  .site-footer {
    padding-top: 48px;
  }

  .footer-brand {
    font-size: 24px;
  }

  .footer-heading {
    font-size: 20px;
  }

  .footer-menu a,
  .footer-link,
  .footer-text,
  .footer-desc,
  .contact-list li {
    font-size: 15px;
  }

  .apt-main-title {
    font-size: 27px;
  }

  .apt-card {
    padding: 20px;
  }

  .apt-card-header h3 {
    font-size: 20px;
  }

  .apt-reminder-content h4 {
    font-size: 17px;
  }

  .apt-input-group label,
  .c-input,
  .time-slot-btn,
  .cal-day-cell,
  .calendar-header-text p,
  .t-value {
    font-size: 14px;
  }

  .calendar-header-text h3,
  #calMonthYear {
    font-size: 20px;
  }

  .apt-btn {
    font-size: 15px;
    padding: 13px 18px;
  }
}

/* =========================================
   RESPONSIVE FIXES: STICKY HEADER + APT STEPS
   ========================================= */

@media (max-width: 900px) {
  .site-header {
    position: sticky !important;
    top: 0;
    z-index: 12000;
  }

  body.modal-open-state .site-header {
    position: relative !important;
    top: auto !important;
    z-index: 10 !important;
  }

  .apt-progress-wrapper {
    overflow-x: visible !important;
    gap: 4px;
    padding-bottom: 0;
    justify-content: space-between;
  }

  .apt-step {
    min-width: 0;
    width: 56px;
    gap: 6px;
  }

  .apt-line {
    min-width: 8px;
    margin-top: 30px;
  }

  .step-label {
    display: block;
    font-size: 9px;
    letter-spacing: 0.7px;
    line-height: 1.1;
  }

  .apt-step span:last-child {
    display: block;
    font-size: 10px;
    line-height: 1.2;
    margin-top: 2px;
    white-space: normal;
  }

  .apt-icon {
    width: 38px;
    height: 38px;
    border-width: 2px;
  }

  .apt-icon svg {
    width: 18px;
    height: 18px;
  }
}

@media (max-width: 480px) {
  .apt-step {
    width: 52px;
  }

  .apt-line {
    min-width: 6px;
  }

  .step-label {
    font-size: 8px;
  }

  .apt-step span:last-child {
    font-size: 9px;
  }
}
/* Phase 2: Customer Profile UX */
.user-profile {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 1px solid #d7dde6;
  background: var(--customer-paper);
  display: grid;
  place-items: center;
  position: relative;
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(16, 24, 40, 0.08);
  transition:
    background-color 0.2s ease,
    border-color 0.2s ease,
    box-shadow 0.2s ease,
    transform 0.09s ease;
}

.user-profile:hover {
  background: #f8fafc;
  border-color: #bec8d8;
  box-shadow: 0 8px 22px rgba(16, 24, 40, 0.16);
}

.user-profile > svg {
  width: 36px;
  height: 36px;
}

.user-initial-badge {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 2px solid var(--customer-wine);
  color: var(--customer-wine);
  background: #fdf6f6;
  display: grid;
  place-items: center;
  font-size: 16px;
  font-weight: 700;
  text-transform: uppercase;
}

.profile-popup {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  background-color: var(--customer-paper);
  box-shadow: 0 24px 45px rgba(16, 24, 40, 0.2);
  border-radius: 14px;
  width: 300px;
  padding: 14px;
  z-index: 100;
  border: 1px solid #d7e0eb;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(6px) scale(0.985);
  transition:
    opacity 0.2s ease,
    visibility 0.2s ease,
    transform 0.2s ease;
  font-family: inherit;
}
.profile-popup::before {
  content: "";
  position: absolute;
  top: -10px;
  right: 16px;
  width: 18px;
  height: 18px;
  border-left: 1px solid #d7e0eb;
  border-top: 1px solid #d7e0eb;
  background: var(--customer-paper);
  transform: rotate(45deg);
}
.profile-popup.show {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0) scale(1);
}
.popup-header {
  text-align: left;
  margin-bottom: 10px;
}
.popup-profile-row {
  display: flex;
  align-items: center;
  gap: 14px;
}

/* =====================================================================
   Customer product reviews
   ===================================================================== */
.modal-actions {
  align-items: center;
}

.reviews-btn {
  margin-right: auto;
  background: rgba(107, 32, 43, 0.06);
  border-color: rgba(107, 32, 43, 0.2);
  color: var(--customer-wine);
  gap: 8px;
}

.reviews-btn:hover:not(:disabled),
.reviews-btn:focus-visible:not(:disabled) {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  transform: none;
}

.reviews-btn-count {
  min-width: 22px;
  padding: 2px 6px;
  border-radius: 999px;
  background: rgba(107, 32, 43, 0.12);
  font-size: 0.72rem;
  line-height: 1.2;
}

.reviews-btn:hover .reviews-btn-count,
.reviews-btn:focus-visible .reviews-btn-count {
  background: rgba(247, 242, 236, 0.18);
}

.customer-reviews-overlay {
  z-index: 21010;
  padding: 16px;
}

.customer-reviews-box {
  width: min(820px, 100%);
  max-height: min(92vh, calc(100dvh - 24px));
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: linear-gradient(
    135deg,
    rgba(247, 242, 236, 0.99),
    rgba(255, 248, 238, 0.98)
  );
  border: 1px solid rgba(107, 32, 43, 0.16);
  border-radius: 28px;
  box-shadow: 0 35px 90px rgba(45, 12, 12, 0.28);
  transform: translateY(20px);
  transition: transform 0.25s ease;
}

.modal-overlay.show-modal .customer-reviews-box {
  transform: translateY(0);
}

.customer-reviews-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  padding: 24px 28px 16px;
  border-bottom: 1px solid rgba(107, 32, 43, 0.1);
}

.customer-reviews-eyebrow {
  margin: 0 0 4px;
  color: var(--customer-wine);
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.customer-reviews-title {
  margin: 0;
  color: var(--customer-wine);
  font-family: "Montserrat", sans-serif;
  font-size: clamp(1.35rem, 3vw, 2rem);
  font-weight: 900;
}

.customer-reviews-product {
  margin: 5px 0 0;
  color: #6b7280;
  font-size: 0.85rem;
  font-weight: 600;
}

.customer-reviews-summary {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 16px 28px 4px;
  color: #6b7280;
  font-size: 0.82rem;
}

.customer-reviews-summary strong {
  color: var(--customer-wine);
  font-size: 1.55rem;
  line-height: 1;
}

.customer-reviews-summary-stars,
.customer-review-star.filled {
  color: #f1b400;
  letter-spacing: 0.04em;
}

.customer-reviews-filters {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 12px 28px 14px;
  scrollbar-width: thin;
}
/* ── Product card rating row (real review averages) ─────────────────────────── */
.shop-card .product-rating-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  margin: 0 0 10px;
  padding: 6px 8px;
  border: 1px solid rgba(107, 32, 43, 0.14);
  border-radius: var(--ux-card-radius);
  background: rgba(247, 242, 236, 0.6);
  font-family: "Montserrat", sans-serif;
  cursor: pointer;
  transition:
    border-color 0.18s ease,
    background 0.18s ease;
}

.shop-card .product-rating-row:hover,
.shop-card .product-rating-row:focus-visible {
  border-color: rgba(107, 32, 43, 0.4);
  background: rgba(255, 248, 238, 0.95);
}

.shop-card .product-rating-row .rating-stars {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

.product-star {
  position: relative;
  display: inline-block;
  color: #d7d2cc;
  font-size: 15px;
  line-height: 1;
}

.product-star.filled {
  color: #f1b400;
}

/* Half star: paint the left half gold with a clipped overlay. */
.product-star.half::before {
  content: "★";
  position: absolute;
  inset: 0;
  width: 50%;
  overflow: hidden;
  color: #f1b400;
}

.customer-review-filter {
  flex: 0 0 auto;
  min-height: 34px;
  padding: 7px 12px;
  border: 1px solid rgba(107, 32, 43, 0.16);
  border-radius: 999px;
  background: var(--customer-paper);
  color: #5f636d;
  cursor: pointer;
  font:
    700 0.75rem/1 "Montserrat",
    sans-serif;
  transition:
    background-color 0.18s ease,
    border-color 0.18s ease,
    color 0.18s ease;
}

.customer-review-filter:hover,
.customer-review-filter.active {
  border-color: var(--customer-wine-hover);
  background: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
}

.customer-review-filter span {
  color: #f1b400;
}

.customer-review-filter.active span {
  color: #ffe27a;
}

.customer-reviews-status {
  min-height: 20px;
  padding: 0 28px;
  color: var(--customer-wine);
  font-size: 0.76rem;
}

.customer-reviews-list {
  min-height: 120px;
  padding: 0 28px 20px;
  overflow-y: auto;
}

.customer-review-card {
  padding: 18px 0;
  border-bottom: 1px solid rgba(107, 32, 43, 0.12);
}

.customer-review-card-head,
.customer-review-meta,
.customer-review-card-footer {
  display: flex;
  align-items: center;
}

.customer-review-card-head {
  gap: 10px;
}

.customer-review-avatar {
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  flex: 0 0 36px;
  border-radius: 50%;
  background: #ffe2e2;
  color: var(--customer-wine);
  font:
    800 0.9rem/1 "Montserrat",
    sans-serif;
}

.customer-review-author strong {
  color: #242a34;
  font-size: 0.85rem;
}

.customer-review-meta {
  gap: 8px;
  margin-top: 4px;
  color: #8a8f99;
  font-size: 0.72rem;
}

.customer-review-stars {
  display: inline-flex;
  gap: 1px;
  font-size: 0.9rem;
}

.customer-review-star {
  color: #d4d6da;
}

.customer-review-feedback {
  margin: 14px 0 12px;
  color: #353b46;
  font-size: 0.86rem;
  line-height: 1.65;
  white-space: pre-wrap;
}

.customer-review-feedback.muted {
  color: #969ba5;
  font-style: italic;
}

.customer-review-media {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin: 10px 0 14px;
}

.customer-review-media-item {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 1 / 0.86;
  padding: 0;
  object-fit: cover;
  overflow: hidden;
  border: 1px solid rgba(107, 32, 43, 0.12);
  border-radius: 14px;
  background: #f4eeee;
  cursor: pointer;
  transition:
    border-color 0.2s ease,
    transform 0.2s ease,
    box-shadow 0.2s ease;
}

.customer-review-media-item:hover,
.customer-review-media-item:focus-visible {
  border-color: rgba(107, 32, 43, 0.55);
  transform: translateY(-2px);
  box-shadow: 0 10px 24px rgba(105, 52, 42, 0.18);
}

.customer-review-media-item > img,
.customer-review-media-item > video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

.customer-review-media-play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(15, 23, 42, 0.32);
  color: var(--customer-paper-sink);
  font-size: 1.6rem;
  pointer-events: none;
}

/* A thumbnail whose file failed to load: hide the broken glyph and show a
   neutral marker. The tile stays clickable so the viewer can explain the error
   and offer "Open in new tab". */
.customer-review-media-item.is-media-error > img,
.customer-review-media-item.is-media-error > video {
  visibility: hidden;
}

.customer-review-media-item.is-media-error {
  border-style: dashed;
  border-color: rgba(107, 32, 43, 0.35);
  background: #faf1f1;
}

.customer-review-media-item.is-media-error::after {
  content: "Unavailable";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Montserrat", sans-serif;
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: rgba(107, 32, 43, 0.62);
  pointer-events: none;
}

.customer-review-reply {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin: 12px 0;
  padding: 9px 12px;
  border-left: 3px solid var(--customer-wine);
  border-radius: 0 8px 8px 0;
  background: #fff2f2;
  color: var(--customer-wine);
  font-size: 0.76rem;
  line-height: 1.45;
}

.customer-review-reply strong {
  color: var(--customer-wine);
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.customer-review-card-footer {
  justify-content: space-between;
  gap: 12px;
  color: #9398a2;
  font-size: 0.72rem;
}

.customer-review-like {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 9px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: transparent;
  color: #7e858f;
  cursor: pointer;
  font:
    700 0.78rem/1 "Montserrat",
    sans-serif;
  transition:
    background-color 0.18s ease,
    border-color 0.18s ease,
    color 0.18s ease;
}

.customer-review-like:hover:not(:disabled) {
  border-color: rgba(107, 32, 43, 0.18);
  background: #fff0f0;
  color: var(--customer-wine-hover);
}

.customer-review-like.is-liked {
  border-color: rgba(107, 32, 43, 0.18);
  background: #ffe5e5;
  color: var(--customer-wine);
  animation: customer-review-like-pop 0.24s ease;
}

.customer-review-like:disabled {
  cursor: wait;
  opacity: 0.6;
}

@keyframes customer-review-like-pop {
  50% {
    transform: scale(1.12);
  }
}

.customer-reviews-load-more {
  align-self: center;
  margin: 0 28px 20px;
  padding: 10px 16px;
  border: 1px solid rgba(107, 32, 43, 0.24);
  border-radius: 999px;
  background: var(--customer-paper);
  color: var(--customer-wine);
  cursor: pointer;
  font:
    800 0.78rem/1 "Montserrat",
    sans-serif;
}

.customer-reviews-load-more:hover:not(:disabled) {
  background: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
}

.customer-reviews-load-more:disabled {
  cursor: wait;
  opacity: 0.65;
}

.customer-reviews-empty,
.customer-reviews-loading {
  display: flex;
  min-height: 160px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  color: #7d838d;
  text-align: center;
}

.customer-reviews-empty i {
  color: var(--customer-wine);
  font-size: 1.6rem;
}

.customer-reviews-empty strong {
  color: var(--customer-wine);
  font-size: 0.9rem;
}

@media (max-width: 680px) {
  .reviews-btn {
    flex: 1 1 100%;
    margin-right: 0;
  }

  .customer-reviews-header,
  .customer-reviews-summary,
  .customer-reviews-filters,
  .customer-reviews-list {
    padding-left: 18px;
    padding-right: 18px;
  }

  .customer-reviews-box {
    border-radius: 20px;
  }

  .customer-reviews-load-more {
    margin-left: 18px;
    margin-right: 18px;
  }
}
.popup-profile-icon {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  border: 2px solid var(--primary-color, var(--customer-wine));
  background-color: #f8e8e8;
  color: var(--customer-wine);
  font-weight: 700;
  font-size: 1rem;
  text-transform: uppercase;
  flex-shrink: 0;
}
.popup-profile-meta {
  min-width: 0;
  flex: 1;
  display: flex;
  align-items: center;
}
.popup-identity {
  font-size: 0.83rem;
  font-weight: 600;
  color: #1f2937;
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.guest-profile-popup .popup-identity {
  font-weight: 800;
  color: var(--customer-wine);
  letter-spacing: 0.02em;
}
.popup-role {
  display: inline-block;
  background-color: #f8e8e8;
  color: var(--customer-wine);
  font-size: 0.72rem;
  font-weight: 600;
  padding: 4px 8px;
  border-radius: 999px;
}
.profile-popup hr {
  border: 0;
  border-top: 1px solid var(--apt-line);
  margin: 10px 0 12px;
}
/* The `!important`s here are pre-existing and are edited in place rather than
   out-shouted from a later block: two competing `!important` borders on the same
   selector would leave the winner decided by source order, which is exactly the
   fragility this file has been paying for elsewhere. */
.profile-popup-link {
  display: flex !important;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-decoration: none;
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--apt-body);
  padding: 9px 10px;
  border-radius: var(--apt-radius-sm);
  background: var(--customer-paper);
  border: 1px solid var(--apt-line) !important;
  transition:
    background-color 0.2s ease,
    color 0.2s ease,
    border-color 0.2s ease;
  font-family: inherit;
  cursor: pointer;
  margin-block: 2px;
}

.profile-popup-link + .profile-popup-link {
  margin-top: 8px;
}
.profile-popup-link:hover {
  background: var(--apt-panel);
  color: var(--customer-wine-hover);
  border-color: var(--apt-panel-edge) !important;
}

.profile-popup-link:active {
  transform: scale(0.97);
}

.profile-popup-link i {
  color: var(--customer-wine);
}

.btn-admin {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1px solid var(--customer-wine);
  background-color: var(--customer-wine);
  color: var(--customer-paper-sink, #f7f2ec);
  border-radius: var(--apt-radius, 8px);
  padding: 8px 14px;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  transition:
    background-color 0.25s ease,
    color 0.25s ease,
    border-color 0.25s ease,
    transform 0.08s ease;
}

.btn-admin:hover {
  background-color: #3d0808;
  border-color: #3d0808;
}

.btn-admin:active {
  transform: scale(0.97);
}

.btn-secondary {
  background-color: var(--customer-paper, #fdfaf6);
  color: var(--customer-wine);
}

.btn-secondary:hover {
  color: var(--customer-paper-sink, #f7f2ec);
}

.admin-system-popup {
  position: fixed;
  inset: 0;
  z-index: 1000005;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 18px;
}

.admin-system-popup.show {
  display: flex;
}

.admin-system-popup__backdrop {
  position: absolute;
  inset: 0;
  background: var(--ux-dlg-scrim);
  backdrop-filter: blur(2px);
}

.admin-system-popup__card {
  position: relative;
  width: min(420px, 96vw);
  background: var(--customer-paper);
  border-radius: var(--ux-dlg-radius);
  border: 1px solid #dce4ee;
  box-shadow: 0 24px 40px rgba(45, 12, 12, 0.24);
  padding: 18px;
}

.admin-system-popup__card,
.admin-system-popup__title,
.admin-system-popup__message,
.admin-system-popup__actions button {
  font-family: "Montserrat", sans-serif;
}

.admin-system-popup__title {
  color: var(--customer-wine);
  margin: 0;
  font-size: 1rem;
}

.admin-system-popup__message {
  margin: 0;
  color: #364152;
  font-size: 0.88rem;
  line-height: 1.45;
}

.admin-system-popup__separator {
  border: 0;
  border-top: 1px solid #e8edf4;
  margin: 10px 0;
}

.admin-system-popup__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.admin-system-popup__actions:not(.is-confirm) #customerSystemPopupCancel {
  display: none;
}

.customer-orders-overlay {
  position: fixed;
  inset: 0;
  z-index: 165;
  display: flex;
  justify-content: flex-end;
  align-items: stretch;
  background: var(--ux-dlg-scrim);
  backdrop-filter: blur(2px);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.2s ease,
    visibility 0.2s ease;
}

.customer-orders-overlay.show {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.customer-orders-overlay.closing {
  opacity: 0;
}

.customer-orders-modal {
  font-family: "Montserrat", sans-serif;
  width: min(760px, 96vw);
  height: 100%;
  position: relative;
  background: var(--customer-paper);
  border-left: 1px solid #dbe2ed;
  box-shadow: -24px 0 42px rgba(15, 23, 42, 0.22);
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  transform: translateX(100%);
  transition: transform 0.24s ease;
}

.customer-orders-modal button,
.customer-orders-modal h2,
.customer-orders-modal h3,
.customer-orders-modal h4,
.customer-orders-modal p,
.customer-orders-modal span,
.customer-orders-modal strong {
  font-family: "Montserrat", sans-serif;
}

.customer-orders-overlay.show .customer-orders-modal {
  transform: translateX(0);
}

.customer-orders-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.customer-orders-title {
  margin: 0;
  color: #1f2937;
  font-size: 1.32rem;
  font-weight: 800;
  letter-spacing: 0.01em;
}

.customer-orders-subtitle {
  margin: 4px 0 0;
  color: #667085;
  font-size: 0.84rem;
  font-weight: 500;
  line-height: 1.45;
}

.customer-orders-close {
  border: 1px solid #d5deea;
  background: #fff;
  color: #334155;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition:
    background-color 0.2s ease,
    border-color 0.2s ease,
    color 0.2s ease,
    transform 0.08s ease;
}

.customer-orders-close:hover {
  background: #fef2f2;
  border-color: #efb9b9;
  color: var(--customer-wine-hover);
}

.customer-orders-close:active {
  transform: scale(0.95);
}

.customer-orders-tabs {
  display: flex;
  gap: 9px;
  overflow-x: auto;
  padding-bottom: 4px;
  scrollbar-width: thin;
}

.customer-orders-tabs::-webkit-scrollbar {
  height: 6px;
}

.customer-orders-tabs::-webkit-scrollbar-thumb {
  background: #cfd8e3;
  border-radius: 999px;
}

.customer-orders-tab {
  border: 1px solid #d6deea;
  background: #f8fafc;
  color: #334155;
  border-radius: 999px;
  padding: 8px 13px;
  font-size: 0.79rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  white-space: nowrap;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition:
    background-color 0.2s ease,
    color 0.2s ease,
    border-color 0.2s ease,
    transform 0.08s ease;
}

.customer-orders-tab:hover {
  background: #eef2f7;
}

.customer-orders-tab.active {
  background: var(--customer-wine);
  border-color: var(--customer-wine);
  color: var(--customer-paper-sink);
}

.customer-orders-tab:active {
  transform: scale(0.97);
}

.customer-orders-tab-count {
  min-width: 19px;
  height: 19px;
  border-radius: 999px;
  background: rgba(247, 242, 236, 0.24);
  display: inline-grid;
  place-items: center;
  font-size: 0.7rem;
  font-weight: 800;
}

.customer-orders-viewport {
  flex: 1;
  min-height: 0;
  border: 1px solid #dde5f1;
  border-radius: 12px;
  background: #f8fafc;
  overflow: hidden;
}

.customer-orders-track {
  display: flex;
  width: 100%;
  height: 100%;
  transition: transform 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.customer-orders-panel {
  flex: 0 0 100%;
  max-width: 100%;
  min-height: 100%;
  overflow-y: auto;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.customer-orders-panel::-webkit-scrollbar {
  width: 7px;
}

.customer-orders-panel::-webkit-scrollbar-thumb {
  background: #c7d0dd;
  border-radius: 999px;
}

.customer-order-card {
  background: var(--customer-paper);
  border: 1px solid #dee5f0;
  border-radius: 12px;
  padding: 12px;
  display: grid;
  grid-template-columns: 74px 1fr auto;
  gap: 12px;
  align-items: center;
}

.customer-order-thumb {
  width: 74px;
  height: 74px;
  border-radius: 10px;
  border: 1px solid #e5ebf4;
  overflow: hidden;
  background: var(--customer-paper);
}

.customer-order-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.customer-order-main h4 {
  margin: 0;
  color: #1f2937;
  font-size: 0.94rem;
  font-weight: 700;
  line-height: 1.4;
}

.customer-order-meta {
  margin: 4px 0 0;
  color: #64748b;
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.4;
}

.customer-order-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 7px;
}

.customer-order-status {
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 0.71rem;
  font-weight: 700;
  border: 1px solid transparent;
}

.customer-order-status.status-to-pay {
  background: #e8f1ff;
  color: #2055c6;
  border-color: #c5d8ff;
}
/* Same stage, different truth: the reference is in and FMRC is checking it. */
.customer-order-status.status-to-pay.is-review {
  background: #f1f3f8;
  color: #545f72;
  border-color: #d6dbe6;
}
/* Past the deadline. Nothing cancels automatically, so this warns rather than
   declaring the order dead. */
.customer-order-status.status-to-pay.is-overdue {
  background: #fff2e3;
  color: var(--customer-wine);
  border-color: #f4d0a2;
}

.customer-order-status.status-to-ship {
  background: #fff4db;
  color: #9a6700;
  border-color: #f0d89c;
}

.customer-order-status.status-to-receive {
  background: #e9fbf9;
  color: #0f766e;
  border-color: #b8eee7;
}

.customer-order-status.status-completed {
  background: #e7f5e9;
  color: #2e7d32;
  border-color: #b7e0be;
}

.customer-order-status.status-rejected {
  background: #fde8e8;
  color: var(--customer-wine);
  border-color: #f4b6b6;
}

/* Cancelled reads as closed, not failed: the customer asked for it, so it is
   grey rather than the red FMRC uses when it turns an order down. */
.customer-order-status.status-cancelled {
  background: #eef0f4;
  color: #5b6472;
  border-color: #d5dae3;
}

/* A request that staff have not answered yet. Amber because the order is still
   alive - a decline puts it straight back into its old stage. */
.customer-order-status.status-cancel-pending {
  background: #fff4db;
  color: var(--customer-wine);
  border-color: #f0d89c;
}

.customer-order-price {
  color: var(--customer-wine);
  font-size: 0.96rem;
  font-weight: 800;
}

.customer-order-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* The action buttons live on their own row inside the card so a completed order
   (Order Details + Rate Product + Buy Again + Return / Refund) can wrap freely
   instead of squeezing the title column and overflowing the modal. */
.customer-order-card > .customer-order-actions {
  grid-column: 1 / -1;
  justify-content: flex-end;
  padding-top: 10px;
  border-top: 1px dashed #e2e8f0;
}

.customer-order-detail-btn {
  border: 1px solid #d8e1ec;
  background: var(--customer-paper);
  color: #334155;
  border-radius: 8px;
  padding: 6px 11px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition:
    background-color 0.2s ease,
    color 0.2s ease,
    border-color 0.2s ease,
    transform 0.08s ease;
}

.customer-order-detail-btn:hover {
  background: #fef2f2;
  color: var(--customer-wine-hover);
  border-color: #e4c5c5;
}

.customer-order-detail-btn:active {
  transform: scale(0.97);
}

.customer-order-detail-modal {
  position: absolute;
  inset: 14px;
  z-index: 4;
  border: 1px solid #d9e2ee;
  border-radius: 12px;
  background: var(--customer-paper);
  box-shadow: 0 18px 34px rgba(15, 23, 42, 0.18);
  display: none;
  flex-direction: column;
}

.customer-order-detail-modal.show {
  display: flex;
}

.customer-order-detail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  border-bottom: 1px solid #e5ebf3;
  padding: 14px;
}

.customer-order-detail-head h3 {
  margin: 0;
  color: #1f2937;
  font-size: 1rem;
  font-weight: 800;
}

.customer-order-detail-content {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 14px;
  display: grid;
  gap: 12px;
}

.customer-order-detail-summary {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.customer-order-detail-chip {
  border: 1px solid #e0e8f2;
  border-radius: 10px;
  background: #f8fafc;
  padding: 9px 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.customer-order-detail-chip span {
  color: #64748b;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.customer-order-detail-chip strong {
  color: #1f2937;
  font-size: 0.83rem;
}

.customer-order-detail-items,
.customer-order-detail-fulfillment,
.customer-order-detail-logistics,
.customer-order-detail-map-wrap,
.customer-order-detail-timeline {
  border: 1px solid #e1e8f2;
  border-radius: 11px;
  background: var(--customer-paper);
  padding: 12px;
}

/* Pickup / delivery block of the order detail modal: the exact address parts a
   courier would use, itemised so the customer can proof-read them. */
.customer-order-detail-fulfillment h4 {
  margin: 0;
  color: #1f2937;
  font-size: 0.84rem;
  font-weight: 800;
}

.customer-order-fulfillment-mode {
  margin: 7px 0 0;
  color: var(--customer-wine);
  font-size: 0.78rem;
}

.customer-order-fulfillment-grid {
  margin: 9px 0 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 7px 12px;
}

.customer-order-fulfillment-row {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.customer-order-fulfillment-row dt {
  color: #64748b;
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.customer-order-fulfillment-row dd {
  margin: 0;
  color: #1f2937;
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1.35;
  overflow-wrap: anywhere;
}

@media (max-width: 480px) {
  .customer-order-fulfillment-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

.customer-order-detail-items h4 {
  margin: 0 0 10px;
  color: #1f2937;
  font-size: 0.84rem;
  font-weight: 800;
}

.customer-order-detail-items-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.customer-order-detail-item {
  display: flex;
  align-items: center;
  gap: 12px;
  border: 1px solid #eef2f7;
  border-radius: 10px;

  background: #f8fafc;
  padding: 9px 10px;
}

.customer-order-detail-item img {
  width: 46px;
  height: 46px;
  border-radius: 8px;
  object-fit: cover;
  background: var(--customer-paper);
  border: 1px solid #e2e8f0;
  flex-shrink: 0;
}

.customer-order-detail-item-info {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.customer-order-detail-item-info strong {
  color: #1f2937;
  font-size: 0.82rem;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
}

.customer-order-detail-item-info span {
  color: #64748b;
  font-size: 0.75rem;
  font-weight: 600;
}

.customer-order-detail-logistics h4,
.customer-order-detail-map-wrap h4,
.customer-order-detail-timeline h4 {
  margin: 0;
  color: #1f2937;
  font-size: 0.84rem;
  font-weight: 800;
}

.customer-order-detail-logistics p {
  margin: 7px 0 0;
  color: #475569;
  font-size: 0.78rem;
  line-height: 1.45;
}

.customer-order-logistics-link {
  margin-top: 8px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  text-decoration: none;
  color: var(--customer-wine);
  font-size: 0.76rem;
  font-weight: 700;
}

/* The parcel link is the whole point of the courier block - one click and the
   checkpoints are on screen, waybill already filled in - so it is dressed as a
   button instead of as body text. It sits on its own line because a secondary
   link may follow it, and two inline-flex anchors would otherwise touch. */
.customer-order-detail-logistics
  .customer-order-logistics-link:not(.customer-order-logistics-link--ghost) {
  padding: 8px 15px;
  border-radius: 999px;
  background: var(--customer-wine);
  color: var(--customer-paper-sink);
  box-shadow: 0 3px 10px rgba(143, 17, 17, 0.22);
  transition:
    background 0.16s ease,
    transform 0.16s ease;
}

.customer-order-detail-logistics
  .customer-order-logistics-link:not(.customer-order-logistics-link--ghost):hover {
  background: var(--customer-wine-hover);
  transform: translateY(-1px);
}

/* The courier's own page. It needs the number pasted into a form, so it is the
   long way round to the same information and is styled to say so. */
.customer-order-logistics-link--ghost {
  color: #64748b;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.customer-order-logistics-link--ghost:hover {
  color: #334155;
}

/* Pill first, courier link beside it. Both are inline-flex, so on a narrow
   phone the second one simply wraps to the next line. */
.customer-order-detail-logistics
  .customer-order-logistics-link
  + .customer-order-logistics-link {
  margin-left: 12px;
}

.customer-order-logistics-note {
  margin-top: 8px;
  color: #64748b;
  font-size: 0.74rem;
}

/* Waybill number: read off the screen and retyped into the courier's own
   tracking box, so it gets a monospace face and a copy button. */
.customer-order-waybill {
  margin-top: 8px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.customer-order-waybill-label {
  color: #64748b;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.customer-order-waybill-no {
  padding: 4px 8px;
  border-radius: 6px;
  background: #f1f5f9;
  color: #0f172a;
  font-family: "Courier New", monospace;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  user-select: all;
}

.customer-order-waybill-copy {
  padding: 4px 10px;
  border: 1px solid #cbd5e1;
  border-radius: 999px;
  background: var(--customer-paper);
  color: #334155;
  font-size: 0.72rem;
  font-weight: 700;
  cursor: pointer;
}

.customer-order-waybill-copy:hover {
  border-color: var(--customer-wine-hover);
  color: var(--customer-wine-hover);
}

.customer-order-map-frame {
  margin-top: 9px;
  width: 100%;
  min-height: 205px;
  border: 1px solid #d9e3ee;
  border-radius: 10px;
}

.customer-order-map-actions {
  margin-top: 7px;
}

.customer-order-map-actions a {
  color: var(--customer-wine);
  text-decoration: none;
  font-size: 0.74rem;
  font-weight: 700;
}

.customer-order-map-empty {
  margin-top: 9px;
  border: 1px dashed #d6e1ec;
  border-radius: 10px;
  background: #f8fafc;
  min-height: 115px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  color: #64748b;
  text-align: center;
  font-size: 0.74rem;
  padding: 10px;
}

.customer-order-map-empty i {
  color: var(--customer-wine);
}

.customer-order-timeline-list {
  margin-top: 8px;
  display: grid;
  gap: 10px;
}

.customer-order-timeline-item {
  display: grid;
  grid-template-columns: 14px 1fr;
  gap: 9px;
}

.customer-order-timeline-dot {
  width: 10px;
  height: 10px;
  border-radius: 999px;
  background: var(--customer-wine);
  margin-top: 5px;
}

.customer-order-timeline-body {
  border: 1px solid #e2e9f2;
  border-radius: 9px;
  background: #f8fafc;
  padding: 9px;
}

.customer-order-timeline-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}

.customer-order-timeline-top strong {
  color: #1f2937;
  font-size: 0.78rem;
}

.customer-order-timeline-top span {
  color: #64748b;
  font-size: 0.71rem;
  text-align: right;
}

.customer-order-timeline-body p {
  margin: 6px 0 0;
  color: #4b5563;
  font-size: 0.74rem;
  line-height: 1.4;
}

.customer-order-timeline-meta {
  margin-top: 6px;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.customer-order-timeline-meta span {
  border: 1px solid #d8e3ef;
  background: var(--customer-paper);
  color: #475569;
  border-radius: 999px;
  padding: 3px 8px;
  font-size: 0.68rem;
  font-weight: 700;
}

.customer-order-timeline-empty {
  margin: 8px 0 0;
  color: #64748b;
  font-size: 0.75rem;
}

.customer-orders-empty {
  min-height: 250px;
  border: 1px dashed #d8e1ec;
  border-radius: 12px;
  background: var(--customer-paper);
  color: #6b7480;
  font-size: 0.86rem;
  font-weight: 600;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  line-height: 1.4;
}

.customer-orders-empty i {
  color: #8f99a8;
  font-size: 1.1rem;
}

/* Recovery link inside an empty state - currently only the expired-session one,
   which needs a way back to the login page from inside the drawer. */
.customer-orders-empty-action {
  margin-top: 2px;
  padding: 7px 16px;
  border-radius: 8px;
  background: var(--customer-wine);
  color: var(--customer-paper-sink);
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  text-decoration: none;
}

.customer-orders-empty-action:hover,
.customer-orders-empty-action:focus-visible {
  background: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  outline: none;
}

@media (max-width: 900px) {
  .customer-orders-modal {
    width: 100vw;
    padding: 14px;
  }

  .customer-orders-title {
    font-size: 1.12rem;
  }

  .customer-orders-subtitle {
    font-size: 0.77rem;
  }

  .customer-order-card {
    grid-template-columns: 64px 1fr;
    padding: 10px;
    gap: 10px;
  }

  .customer-order-thumb {
    width: 64px;
    height: 64px;
  }

  .customer-order-side {
    grid-column: 1 / -1;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    border-top: 1px dashed #e2e8f0;
    padding-top: 8px;
  }

  /* The side strip above already opens the card footer, so the button row does
     not need a second dashed rule of its own. */
  .customer-order-card > .customer-order-actions {
    border-top: none;
    padding-top: 0;
  }

  .customer-order-detail-modal {
    inset: 8px;
  }

  .customer-order-detail-summary {
    grid-template-columns: 1fr;
  }

  .customer-order-map-frame {
    min-height: 165px;
  }
}

.guest-popup-copy {
  font-size: 0.8rem;
  color: #4b5563;
  line-height: 1.45;
  margin: 2px 0 12px;
}

.guest-auth-stack {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.guest-auth-or {
  text-align: center;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #9ca3af;
}

/* The two buttons at the foot of the signed-out menu. Same two shapes the
   dialogs use — one filled action, one ghost beside it — so the menu's foot and
   a dialog's foot are the same control in a smaller frame. The filled one is
   maroon rather than gold: the band above it already spends the accent twice (the
   badge and the ring), and the signed-in menu's own filled pill is maroon too. */
.guest-auth-btn {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-height: var(--ux-tap);
  border-radius: var(--apt-radius, 8px);
  text-decoration: none;
  font-size: 14px;
  font-weight: 800;
  transition:
    background-color 0.18s ease,
    color 0.18s ease,
    border-color 0.18s ease,
    transform 0.08s ease;
}

/* The dropdown's primary action is the same primary action as everywhere else, so
   it wears the same pill: `--customer-gold` on `--customer-primary-strong`, the
   recipe at :17900. It used to be a maroon fill with cream ink, which meant the
   one button labelled "Sign In" looked like two different controls depending on
   whether the customer reached it from the header dropdown or from the guest
   access dialog. Gold here is still inside "one accent, one place" — the badge
   above it is the panel's only other gold, exactly as in the dialogs. */
.guest-auth-login {
  background-color: var(--customer-wine);
  /* `none`, spelled out: buttons opt out of `--customer-wash`. This was the last
     gradient left on any control on the page - 53 of the 54 buttons measured flat
     and this one did not - and "remove all the gradient color in all buttons" does
     not carve out an exception for a subtle one. */
  background-image: none;
  color: var(--customer-paper-sink);
  /* The border matches the fill rather than sitting on it as a ring: the dialog
     primary has no border at all, and the 1px is only kept here so this pill and
     the ghost below it resolve to the same box. */
  border: 1px solid var(--customer-wine);
  box-shadow: 0 10px 22px rgba(128, 116, 14, 0.24);
}

/* The ghost half of the same pair, and the same recipe the dialog ghost uses at
   :17966 — fill, ink and hairline already matched; the shadow did not. The pill
   above it carries its `0 10px 22px` verbatim from the dialog primary, so a
   shadowless secondary made the dropdown's own two buttons disagree with each
   other before it ever disagreed with the dialog. 8% alpha is barely visible on
   its own; the point is that both pills resolve to the same box. */
.guest-auth-signup {
  background: var(--customer-paper);
  color: var(--customer-wine);
  border: 1.5px solid rgba(107, 32, 43, 0.32);
  box-shadow: 0 6px 16px rgba(95, 13, 13, 0.08);
}

.guest-access-modal {
  position: fixed;
  inset: 0;
  z-index: 30010;
  display: flex;
  justify-content: center;
  align-items: center;
  /* Was a slate scrim plus a 3px blur - the blur was the last live
     `backdrop-filter` on a home-page overlay, and the hue matched nothing. */
  background: var(--ux-dlg-scrim);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.22s ease,
    visibility 0.22s ease;
  padding: 16px;
}

.guest-access-modal.show {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.guest-access-card {
  width: 100%;
  max-width: 430px;
  background: var(--customer-paper, #fdfaf6);
  border-radius: var(--apt-radius, 8px);
  border: 1px solid var(--customer-paper-edge, #efe6da);
  box-shadow: 0 22px 48px rgba(45, 12, 12, 0.24);
  padding: 22px;
  position: relative;
  font-family: "Montserrat", sans-serif;
  transform: translateY(8px) scale(0.985);
  transition: transform 0.22s ease;
}

.guest-access-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid var(--customer-paper-edge, #efe6da);
  background: var(--customer-paper, #fdfaf6);
  color: var(--apt-body, #4b5563);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition:
    background-color 0.2s ease,
    border-color 0.2s ease,
    color 0.2s ease,
    transform 0.08s ease;
}

.guest-access-close:hover {
  background: var(--apt-panel, #fffbed);
  border-color: var(--apt-panel-edge, #eadc9a);
  color: var(--apt-head, var(--customer-wine-hover));
}

.guest-access-close:active {
  transform: scale(0.95);
}

.guest-access-modal.show .guest-access-card {
  transform: translateY(0) scale(1);
}

.guest-access-title {
  margin: 2px 38px 0 0;
  color: var(--customer-wine);
  font-size: 1.15rem;
  font-weight: 900;
  letter-spacing: 0.02em;
  text-shadow: 0 8px 22px rgba(168, 15, 15, 0.16);
}

.guest-access-copy {
  margin: 10px 0 18px;
  color: #4b5563;
  font-size: 0.88rem;
  line-height: 1.55;
  font-weight: 500;
}

.guest-access-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.guest-access-btn {
  flex: 1;
  min-width: 120px;
  min-height: 44px;
  border-radius: var(--apt-radius, 8px);
  text-decoration: none;
  font-size: 0.83rem;
  font-weight: 700;
  font-family: "Montserrat", sans-serif;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid transparent;
  cursor: pointer;
  transition:
    background-color 0.2s ease,
    color 0.2s ease,
    border-color 0.2s ease,
    transform 0.08s ease,
    box-shadow 0.2s ease;
}

.guest-access-btn:active {
  transform: scale(0.97);
}

.guest-access-btn.login {
  background: var(--customer-wine);
  border-color: var(--customer-wine);
  color: var(--customer-paper-sink, #f7f2ec);
}

.guest-access-btn.login:hover {
  background: #3d0808;
  border-color: #3d0808;
  box-shadow: 0 8px 18px rgba(95, 13, 13, 0.18);
}

.guest-access-btn.signup {
  background: var(--customer-paper, #fdfaf6);
  border-color: rgba(107, 32, 43, 0.32);
  color: var(--customer-wine);
}

.guest-access-btn.signup:hover {
  background: #f2dede;
  border-color: var(--customer-wine-hover);
  color: var(--customer-wine-hover);
}

.guest-access-btn.close {
  background: var(--customer-paper, #fdfaf6);
  border-color: var(--customer-paper-edge, #efe6da);
  color: var(--apt-body, #4b5563);
}

.guest-access-btn.close:hover {
  background: var(--apt-panel, #fffbed);
  border-color: var(--apt-panel-edge, #eadc9a);
}

.popup-logout {
  display: flex;
  align-items: center;
  gap: 4px;
  width: 100%;
  font-size: 0.85rem;
  padding: 9px 10px;
  margin-top: 12px;
  justify-content: center;
  background: var(--customer-wine);
  color: var(--customer-paper-sink);
  border: none;
  border-radius: var(--ux-dlg-radius, 8px);
  cursor: pointer;
  font-weight: 600;
  transition:
    background-color 0.25s ease,
    color 0.25s ease,
    border-color 0.25s ease,
    transform 0.08s ease,
    box-shadow 0.2s ease;
}
.popup-logout:hover {
  background-color: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  border-color: var(--customer-wine-hover);
  box-shadow: 0 6px 14px rgba(128, 0, 0, 0.18);
}
.popup-logout:active {
  transform: scale(0.97);
}

.popup-logout i {
  margin-right: 0;
}

.customer-modal-overlay {
  position: fixed;
  inset: 0;
  /* `inset: 0` alone sizes this to the fixed containing block, which on iOS is
     the large viewport — measured 853.6px tall against an 812px screen here. The
     card is centred inside it, so it sat ~40px low and its foot (Change
     password) went under the Safari toolbar with no way to scroll to it. Pinning
     the height to the *dynamic* viewport centres the card in what is visible;
     `max-width: 100vw` is the horizontal twin, stopping the same containing
     block from making the overlay wider than the screen. */
  height: 100vh;
  height: 100dvh;
  max-width: 100vw;
  background: var(--ux-dlg-scrim);
  backdrop-filter: blur(3px);
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 16px;
  /* A card taller than the viewport has to stay reachable. `margin-block: auto`
     on the card is what keeps a centred flex item from clipping its own top once
     this scrolls — the same pairing responsive.css already uses in the
     short-screen band. */
  overflow-y: auto;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.2s ease,
    visibility 0.2s ease;
  z-index: 150;
}

.customer-modal-overlay.show {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.customer-modal-overlay.closing {
  opacity: 0;
}

/* Pairs with the overlay's `overflow-y: auto`: auto side margins let an
   over-tall card scroll from its true top instead of having it clipped by the
   centring, which is what a plain centred flex item does. Direct child only, so
   nothing nested inside a card is affected. Not on the shared `.ux-dlg__card`
   rule, because the orders drawer is `align-items: stretch` and an auto margin
   there would collapse it to its content height. */
.customer-modal-overlay > .ux-dlg__card,
.customer-modal-overlay > .customer-modal {
  margin-block: auto;
}

.customer-modal {
  position: relative;
  font-family: inherit;
  width: 100%;
  max-width: 520px;
  border-radius: 18px;
  border: 1px solid #dde5f1;
  background: var(--customer-paper);
  box-shadow: 0 30px 55px rgba(45, 12, 12, 0.26);
  padding: 35px 40px;
  transform: translateY(8px) scale(0.985);
  transition:
    transform 0.2s ease,
    opacity 0.2s ease;
}

.customer-modal-overlay.show .customer-modal {
  position: relative;
  font-family: inherit;
  width: 100%;
  max-width: 520px;
  border-radius: 18px;
  border: 1px solid #dde5f1;
  background: var(--customer-paper);
  box-shadow: 0 30px 55px rgba(45, 12, 12, 0.26);
  padding: 35px 40px;
  transform: translateY(8px) scale(0.985);
  transition:
    transform 0.2s ease,
    opacity 0.2s ease;
}

.customer-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 15px;
}

.customer-modal-title {
  margin: 0;
  color: #111827;
  font-size: 1.22rem;
}

.customer-modal-close {
  position: absolute;
  top: 16px;
  right: 16px;
  border: none;
  background: #f2f5fa;
  color: #374151;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}

.customer-modal-close:hover {
  background: #f8e8e8;
  color: var(--customer-wine-hover);
}

.customer-card {
  background: #f8fafc;
  border: 1px solid #dbe3ef;
  border-radius: 12px;
  padding: 12px;
  margin-bottom: 14px;
}

.customer-card p {
  margin: 0 0 6px;
  font-size: 0.92rem;
  color: #2f3341;
}

.customer-card p:last-child {
  margin-bottom: 0;
}

.customer-form-title {
  margin: 0 0 10px;
  font-size: 1rem;
  color: #1f2937;
}

/* Change-password fields. These four classes exist only inside the
   Change/Set Password dialog (main.js:7649+), so aligning them with the
   appointment flow's input recipe reaches nothing else: cream hairline, 8px
   radius, maroon focus ring. The cold blue-greys they used to carry —
   `#d1dae8`, `#d1d5db`, `#94a3b8`, `#64748b` — were the last of them on any
   customer surface. */
.customer-field {
  margin-bottom: 12px;
}

.customer-field label {
  display: block;
  margin-bottom: 5px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--apt-body);
}

.customer-field input {
  font-family: inherit;
  width: 100%;
  border: 1px solid var(--apt-line);
  border-radius: var(--apt-radius);
  min-height: var(--ux-tap);
  padding: 0 12px;
  font-size: 0.92rem;
  color: var(--apt-body);
  background: var(--customer-paper);
}

.customer-field input:focus {
  outline: none;
  border-color: var(--apt-danger);
  box-shadow: 0 0 0 3px rgba(176, 28, 28, 0.12);
}

.customer-msg {
  display: none;
  margin-bottom: 10px;
  font-size: 0.85rem;
  font-weight: 600;
}

.customer-btn {
  font-family: inherit;
  width: 100%;
  border: 1px solid var(--customer-wine);
  border-radius: var(--apt-radius, 8px);
  min-height: 44px;
  background: var(--customer-wine);
  color: var(--customer-paper-sink);
  font-weight: 700;
  cursor: pointer;
  transition:
    background-color 0.2s ease,
    border-color 0.2s ease,
    transform 0.08s ease;
}

.customer-btn:hover {
  background: #3d0808;
  border-color: #3d0808;
}

.customer-btn:active {
  transform: scale(0.98);
}

.global-loader-overlay {
  position: fixed;
  inset: 0;
  /* The curtain reads as the page dimming, so it has to be the paper colour,
     not white. */
  background: rgba(253, 250, 246, 0.86);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 10000;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.2s ease;
}

.global-loader-overlay.active {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.status-modal {
  position: fixed;
  inset: 0;
  z-index: 10001;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  padding: 18px;
  transition: opacity 0.2s ease;
}

.status-modal.show {
  opacity: 1;
  visibility: visible;
}

.status-box {
  /* Was #121824 on #fff - a cold slate chip with pure-white type, the one
     surface on the page that spoke neither maroon nor cream. */
  background: #3d0808;
  color: var(--customer-paper-sink);
  padding: 12px 16px;
  border-radius: var(--ux-dlg-radius);
  font-size: 13px;
  font-weight: 600;
  box-shadow: 0 10px 28px rgba(45, 12, 12, 0.25);
  transform: translateY(8px);
  transition: transform 0.2s ease;
}

.status-modal.show .status-box {
  transform: translateY(0);
}

/* Logout Spacing Fix for Admin/Cashier */
.logout-btn i {
  margin-right: 8px;
}
.password-wrapper {
  position: relative;
  display: flex;
  align-items: center;
}
.password-wrapper input {
  width: 100%;
  padding: 10px 44px 10px 14px;
  box-sizing: border-box;
  font-size: 13.5px;
  font-family: inherit;
  border-radius: var(--apt-radius);
  border: 1px solid var(--apt-line);
  color: var(--apt-body);
  background: var(--customer-paper);
}
.password-wrapper input:focus {
  outline: none;
  border-color: var(--apt-danger);
  box-shadow: 0 0 0 3px rgba(176, 28, 28, 0.12);
}
.password-wrapper input::placeholder {
  font-size: 12px;
  font-weight: 400;
  color: var(--apt-muted);
  letter-spacing: 0.01em;
}
.toggle-pass {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--apt-muted);
  display: grid;
  place-items: center;
  padding: 4px;
  transition: color 0.2s ease;
}
.toggle-pass:hover,
.toggle-pass.active {
  color: var(--customer-wine-hover);
}
.toggle-pass svg {
  width: 20px;
  height: 20px;
}

/* ===== Pay Now Button (GCash placed, money not sent yet) =====
   GCash blue rather than the FMRC maroon, so the one card action that leaves
   for another app is not mistaken for an ordinary order control. */
.customer-order-pay-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 20px;
  background: linear-gradient(135deg, #0a5fd6 0%, #1d8bf1 100%);
  color: var(--customer-paper-sink);
  border: none;
  border-radius: 14px;
  font-family: "Montserrat", sans-serif;
  font-size: 0.82rem;
  font-weight: 800;
  cursor: pointer;
  /* No drop shadow. A coloured glow around this one button read as a highlight
     ring the rest of the card never uses, and it followed the button through
     every state. Depth comes from the gradient alone; the feedback comes from
     the fill getting darker, the same as every other button on the site. */
  transition: background 0.2s ease;
  margin-top: 8px;
}
.customer-order-pay-btn:hover {
  background: linear-gradient(135deg, #084ead 0%, #0a5fd6 100%);
}
.customer-order-pay-btn:active {
  background: linear-gradient(135deg, #063d8c 0%, #084ead 100%);
}
.customer-order-pay-btn:disabled {
  opacity: 0.55;
  pointer-events: none;
}
/* Past the deadline. Amber, not red: the payment is still accepted, and a red
   button next to "overdue" reads as a dead end. */
.customer-order-pay-btn.is-overdue {
  background: linear-gradient(135deg, var(--customer-wine) 0%, #d97706 100%);
}
.customer-order-pay-btn.is-overdue:hover {
  background: linear-gradient(135deg, var(--customer-wine-hover) 0%, var(--customer-wine-hover) 100%);
}
.customer-order-pay-btn.is-overdue:active {
  background: linear-gradient(135deg, var(--customer-wine-hover) 0%, var(--customer-wine-hover) 100%);
}
/* Claim submitted, staff not finished. Still clickable so a mistyped reference
   can be corrected, but it must not look like an outstanding task. */
.customer-order-pay-btn.is-review {
  background: #f4f6fa;
  color: #4a5464;
  border: 1px solid rgba(74, 84, 100, 0.22);
  font-weight: 700;
}
.customer-order-pay-btn.is-review:hover {
  background: #e9edf4;
}
.customer-order-pay-btn.is-review:active {
  background: #dde3ed;
}

/* ===== Order Received Button ===== */
.customer-order-received-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 20px;
  background: linear-gradient(135deg, #15803d 0%, #16a34a 100%);
  color: var(--customer-paper-sink);
  border: none;
  border-radius: 14px;
  font-family: "Montserrat", sans-serif;
  font-size: 0.82rem;
  font-weight: 800;
  cursor: pointer;
  box-shadow: 0 8px 20px rgba(22, 163, 74, 0.25);
  transition: all 0.2s ease;
  margin-top: 8px;
}
.customer-order-received-btn:hover {
  background: linear-gradient(135deg, #11632e 0%, #15803d 100%);
  box-shadow: 0 12px 26px rgba(22, 163, 74, 0.32);
  transform: none;
}
.customer-order-received-btn:active {
  transform: scale(0.97);
}
.customer-order-received-btn:disabled {
  opacity: 0.55;
  pointer-events: none;
}

/* ===== Rate Product Button ===== */
.customer-rate-product-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 20px;
  background: linear-gradient(135deg, #d97706 0%, #f59e0b 100%);
  color: var(--customer-paper-sink);
  border: none;
  border-radius: 14px;
  font-family: "Montserrat", sans-serif;
  font-size: 0.82rem;
  font-weight: 800;
  cursor: pointer;
  box-shadow: 0 8px 20px rgba(245, 158, 11, 0.25);
  transition: all 0.2s ease;
  margin-top: 8px;
}
.customer-rate-product-btn:hover {
  background: linear-gradient(135deg, var(--customer-wine-hover) 0%, #d97706 100%);
  box-shadow: 0 12px 26px rgba(245, 158, 11, 0.32);
  transform: none;
}
.customer-rate-product-btn:active {
  transform: scale(0.97);
}
.customer-rate-product-btn.rated {
  background: #6b7280;
  cursor: default;
  box-shadow: none;
}

/* ===== To Rate / My Ratings Panel ===== */
.customer-torate-wrap {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.customer-torate-section {
  padding: 0 0 8px;
}
.customer-torate-section-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px 10px;
  border-bottom: 1px solid #f0f0f0;
}
.customer-torate-section-head h3 {
  font-size: 0.95rem;
  font-weight: 700;
  color: #1a202c;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 6px;
}
.customer-torate-section-head h3 i {
  color: #f59e0b;
}
.customer-torate-badge {
  background: #f59e0b;
  color: var(--customer-paper-sink);
  font-size: 0.72rem;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 20px;
  min-width: 22px;
  text-align: center;
}
.customer-torate-badge.alt {
  background: #6b7280;
}
.customer-torate-list {
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* To Rate card */
.customer-torate-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid #f5f5f5;
  transition: background 0.15s;
}
.customer-torate-card:hover {
  background: #fafafa;
}
.customer-torate-main {
  flex: 1;
  min-width: 0;
}
.customer-torate-main h4 {
  font-size: 0.88rem;
  font-weight: 600;
  color: #1a202c;
  margin: 0 0 3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.customer-order-item-names {
  margin: 0 0 3px;
  overflow: hidden;
  color: #8a909a;
  font-size: 0.72rem;
  line-height: 1.35;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.customer-torate-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
  flex-shrink: 0;
}

/* Rated card */
.customer-rated-card {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid #f5f5f5;
  transition: background 0.15s;
}
.customer-rated-card:hover {
  background: #fafafa;
}
.customer-rated-main {
  flex: 1;
  min-width: 0;
}
.customer-rated-main h4 {
  font-size: 0.88rem;
  font-weight: 600;
  color: #1a202c;
  margin: 0 0 3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.customer-rated-main .customer-order-item-names {
  margin-bottom: 4px;
}
.customer-rated-stars {
  display: flex;
  align-items: center;
  gap: 3px;
  margin: 4px 0;
}
.customer-rating-star-display {
  font-size: 1.1rem;
  color: #d1d5db;
}
.customer-rating-star-display.filled {
  color: #f59e0b;
}
.customer-rated-score {
  font-size: 0.78rem;
  font-weight: 700;
  color: #f59e0b;
  margin-left: 4px;
}
.customer-rated-feedback {
  font-size: 0.8rem;
  color: #6b7280;
  margin: 2px 0 0;
  font-style: italic;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.customer-rated-feedback.muted {
  color: #9ca3af;
  font-style: normal;
}

/* Admin reply box inside My Ratings */
.customer-rated-admin-reply {
  margin-top: 6px;
  padding: 7px 10px;
  background: #f0fdf4;
  border-left: 3px solid #16a34a;
  border-radius: 0 6px 6px 0;
  font-size: 0.76rem;
  color: #15803d;
  line-height: 1.45;
  display: flex;
  align-items: flex-start;
  gap: 6px;
}
.customer-rated-admin-reply i {
  margin-top: 2px;
  flex-shrink: 0;
  font-size: 0.7rem;
  color: #16a34a;
}
.customer-rated-admin-reply strong {
  color: #15803d;
  margin-right: 4px;
}

.customer-rated-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
  flex-shrink: 0;
}

/* Rate Now / Edit Rating button */
.customer-order-rate-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px 14px;
  border-radius: 6px;
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
  border: none;
  background: #f59e0b;
  color: var(--customer-paper-sink);
  transition:
    background 0.18s,
    transform 0.1s;
  white-space: nowrap;
}
.customer-order-rate-btn:hover {
  background: #d97706;
}
.customer-order-rate-btn:active {
  transform: scale(0.97);
}
.customer-order-rate-btn.ghost {
  background: transparent;
  color: #6b7280;
  border: 1px solid #d1d5db;
}
.customer-order-rate-btn.ghost:hover {
  background: #f3f4f6;
  color: #374151;
}

/* ===== Buy Again ===== */
/* Same box metrics as `.customer-order-detail-btn` so the actions row stays
   even; the brand maroon marks it as the primary follow-up action. */
.customer-order-buy-again-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 1px solid #e4c5c5;
  background: #fef2f2;
  color: var(--customer-wine);
  border-radius: 8px;
  padding: 6px 11px;
  font-family: "Montserrat", sans-serif;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color 0.2s ease,
    color 0.2s ease,
    border-color 0.2s ease,
    transform 0.08s ease;
}

.customer-order-buy-again-btn:hover {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
}

.customer-order-buy-again-btn:active {
  transform: scale(0.97);
}

.customer-order-buy-again-btn i {
  font-size: 0.68rem;
}

/* Multi-item orders pick one product first — `#checkoutModal` is single-product. */
.customer-buy-again-card {
  max-width: 520px;
}

.customer-buy-again-list {
  padding: 8px 24px 18px;
}

.customer-buy-again-option {
  gap: 12px;
}

.customer-buy-again-option .customer-order-detail-item-info {
  flex: 1 1 auto;
}

.customer-buy-again-option .customer-buy-again-pick {
  flex-shrink: 0;
  background: var(--customer-wine);
}

.customer-buy-again-option .customer-buy-again-pick:hover {
  background: var(--customer-wine-hover);
}

.customer-buy-again-card .customer-rating-actions {
  grid-template-columns: minmax(0, 1fr);
}

@media (max-width: 560px) {
  /* Match the narrow gutter the rating shell switches to at this width. */
  .customer-buy-again-list {
    padding: 8px 14px 18px;
  }
}

@media (max-width: 480px) {
  .customer-buy-again-option {
    flex-wrap: wrap;
  }

  .customer-buy-again-option .customer-buy-again-pick {
    width: 100%;
  }
}

/* Compact empty state inside sections */
.customer-orders-empty.compact {
  padding: 20px 18px;
  font-size: 0.82rem;
}
.customer-orders-empty.compact i {
  font-size: 1.4rem;
}

/* Back button for Change Password & sub-modals. Keeps the `-pill` class name —
   main.js builds the element — but takes the card's 8px corner like every other
   button on the site. */
.customer-modal-back-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border-radius: var(--apt-radius-sm, 6px);
  background: rgba(150, 52, 73, 0.08);
  color: var(--customer-wine);
  border: 1px solid rgba(150, 52, 73, 0.16);
  font-family: "Montserrat", sans-serif;
  font-size: 13px;
  font-weight: 800;
  cursor: pointer;
  transition: all 0.2s ease;
}

.customer-modal-back-pill:hover {
  background: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  border-color: var(--customer-wine-hover);
  transform: none;
}

.customer-modal-back-pill:active {
  transform: scale(0.97);
}

/* ===== Rating Modal Overlay ===== */
.customer-rating-overlay {
  position: fixed;
  inset: 0;
  background: var(--ux-dlg-scrim);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  opacity: 0;
  pointer-events: none;
  padding: 16px;
  transition: opacity 0.2s ease;
}
.customer-rating-overlay.show {
  opacity: 1;
  pointer-events: all;
}
.customer-rating-card {
  background:
    radial-gradient(
      circle at 95% 0%,
      rgba(241, 237, 18, 0.18),
      transparent 14rem
    ),
    linear-gradient(
      135deg,
      rgba(247, 242, 236, 0.98),
      rgba(255, 248, 238, 0.95)
    );
  border: 1px solid rgba(107, 32, 43, 0.16);
  border-radius: 28px;
  padding: 28px 24px 24px;
  width: 100%;
  max-width: 440px;
  box-shadow: 0 30px 80px rgba(45, 12, 12, 0.35);
  display: flex;
  flex-direction: column;
  gap: 14px;
  backdrop-filter: blur(20px);
}
.customer-rating-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.customer-rating-head h3 {
  font-family: "Montserrat", sans-serif;
  font-size: 1.2rem;
  font-weight: 900;
  color: var(--customer-wine-hover);
  margin: 0;
}
.customer-rating-product-name {
  font-size: 0.88rem;
  color: #6b7280;
  margin: 0;
  font-weight: 600;
}
.customer-rating-stars {
  display: flex;
  gap: 6px;
  justify-content: center;
}
.rating-star-large {
  background: none;
  border: none;
  font-size: 2.2rem;
  color: #d1d5db;
  cursor: pointer;
  padding: 0 2px;
  transition:
    color 0.15s ease,
    transform 0.1s ease;
  line-height: 1;
}
.rating-star-large.filled {
  color: #f59e0b;
}
.rating-star-large:hover {
  transform: scale(1.15);
}
.customer-rating-score-label {
  text-align: center;
  font-family: "Montserrat", sans-serif;
  font-size: 0.9rem;
  font-weight: 800;
  color: var(--customer-wine);
  margin: 0;
}
.customer-rating-feedback {
  width: 100%;
  border: 1px solid rgba(107, 32, 43, 0.14);
  background: rgba(247, 242, 236, 0.92);
  border-radius: 14px;
  padding: 12px;
  font-family: "Montserrat", sans-serif;
  font-size: 0.85rem;
  color: #222833;
  resize: none;
  outline: none;
  box-sizing: border-box;
  transition:
    border-color 0.2s ease,
    box-shadow 0.2s ease;
}
.customer-rating-feedback:focus {
  border-color: var(--customer-wine);
  box-shadow: 0 0 0 3px rgba(133, 19, 19, 0.12);
}
.customer-rating-char-count {
  text-align: right;
  font-size: 0.72rem;
  color: #9ca3af;
  margin-top: -8px;
  font-weight: 600;
}
.customer-rating-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}
.customer-rating-cancel-btn {
  width: 100%;
  min-width: 0;
  min-height: 42px;
  padding: 10px 20px;
  border: 1px solid rgba(107, 32, 43, 0.16);
  border-radius: 14px;
  background: rgba(247, 242, 236, 0.9);
  color: var(--customer-wine);
  font-family: "Montserrat", sans-serif;
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.2s ease;
}
.customer-rating-cancel-btn:hover {
  background: var(--customer-paper);
  border-color: var(--customer-wine-hover);
  transform: none;
}
.customer-rating-cancel-btn:active {
  transform: scale(0.97);
}

/* Submit Rating must match its Cancel sibling exactly. `.btn-place-order`
   supplies the red fill but also a 999px pill, a 2px border and 14px type, so
   the box metrics are pinned here with a two-class selector that outranks it. */
.customer-rating-actions .customer-rating-submit-btn {
  width: 100%;
  min-width: 0;
  min-height: 42px;
  box-sizing: border-box;
  padding: 10px 20px;
  border: 1px solid var(--customer-wine);
  border-radius: 14px;
  gap: 9px;
  font-family: "Montserrat", sans-serif;
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1;
}

.customer-rating-submit-btn:hover:not(:disabled),
.customer-rating-submit-btn:focus-visible:not(:disabled) {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  box-shadow: 0 8px 20px rgba(128, 24, 18, 0.28);
  transform: none;
}

.customer-rating-submit-btn:active:not(:disabled) {
  transform: scale(0.97);
  box-shadow: 0 2px 5px rgba(176, 28, 28, 0.2);
}

.customer-rating-submit-btn:disabled {
  opacity: 0.72;
  pointer-events: none;
}

.customer-rating-submit-btn.is-loading:disabled {
  background: var(--customer-wine);
  border-color: var(--customer-wine);
  color: var(--customer-paper-sink);
  cursor: wait;
  opacity: 0.9;
}

.customer-rating-submit-spinner {
  --fmrc-inline-size: 15px;
  display: none;
  width: 15px;
  height: 15px;
  flex: 0 0 15px;
}

.customer-rating-submit-btn.is-loading .customer-rating-submit-spinner {
  display: inline-block;
}

/* ===== Product-by-product review form ===== */
.customer-rating-overlay {
  align-items: center;
  padding: 12px;
}

.customer-rating-card {
  width: min(700px, 100%);
  max-height: min(94vh, calc(100dvh - 20px));
  overflow: hidden;
  padding: 0;
  gap: 0;
  border-radius: 24px;
  background: linear-gradient(145deg, var(--customer-paper), #fff8f4);
}

.customer-rating-head {
  position: relative;
  z-index: 2;
  flex: 0 0 auto;
  padding: 20px 24px 12px;
  border-bottom: 1px solid rgba(150, 52, 73, 0.1);
  background: rgba(255, 253, 251, 0.98);
}

.customer-rating-eyebrow {
  margin: 0 0 3px;
  color: var(--customer-wine);
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}

.customer-rating-head h3 {
  margin: 0;
  color: var(--customer-wine-hover);
  font-size: 1.18rem;
}

.customer-rating-product-name {
  margin: 0;
  padding: 12px 24px 4px;
  color: #737984;
  font-size: 0.8rem;
  font-weight: 600;
}

.customer-rating-body {
  flex: 1 1 auto;
  min-height: 0;
  margin-right: 6px;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-color: rgba(107, 32, 43, 0.48) transparent;
  scrollbar-gutter: stable;
  scrollbar-width: thin;
}

.customer-rating-body::-webkit-scrollbar {
  width: 7px;
}

.customer-rating-body::-webkit-scrollbar-track {
  background: transparent;
}

.customer-rating-body::-webkit-scrollbar-thumb {
  border: 2px solid transparent;
  border-radius: 999px;
  background: rgba(107, 32, 43, 0.52);
  background-clip: padding-box;
}

.customer-rating-body::-webkit-scrollbar-thumb:hover {
  background: rgba(107, 32, 43, 0.72);
  background-clip: padding-box;
}

.customer-rating-items {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 10px 24px 18px;
}

.customer-rating-loading,
.customer-rating-empty {
  min-height: 230px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 24px;
  border: 1px solid rgba(107, 32, 43, 0.1);
  border-radius: 16px;
  background:
    radial-gradient(
      circle at 90% 10%,
      rgba(241, 237, 18, 0.13),
      transparent 92px
    ),
    rgba(247, 242, 236, 0.76);
  color: #737984;
}

.customer-rating-loading-mark {
  --fmrc-inline-size: 48px;
  position: relative;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  flex: 0 0 48px;
}

.customer-rating-loading-copy {
  display: grid;
  gap: 4px;
}

.customer-rating-loading-copy strong,
.customer-rating-empty strong {
  color: var(--customer-wine);
  font-size: 0.82rem;
  font-weight: 850;
}

.customer-rating-loading-copy > span,
.customer-rating-empty > span {
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.45;
}

.customer-rating-empty {
  flex-direction: column;
  gap: 6px;
  text-align: center;
}

.customer-rating-empty i {
  margin-bottom: 4px;
  color: var(--customer-wine);
  font-size: 1.45rem;
}

.customer-rating-item {
  padding: 14px;
  border: 1px solid rgba(107, 32, 43, 0.12);
  border-radius: 16px;
  background: rgba(247, 242, 236, 0.82);
}

.customer-rating-item-head {
  display: flex;
  align-items: center;
  gap: 10px;
}

.customer-rating-item-image,
.customer-rating-item-placeholder {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  flex: 0 0 48px;
  overflow: hidden;
  border: 1px solid rgba(107, 32, 43, 0.14);
  border-radius: 12px;
  background: #fff4f0;
  color: var(--customer-wine);
}

.customer-rating-item-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.customer-rating-item-copy {
  min-width: 0;
}

.customer-rating-item-copy h4 {
  margin: 0;
  overflow: hidden;
  color: #262c36;
  font-size: 0.88rem;
  font-weight: 800;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.customer-rating-item-copy p {
  margin: 3px 0 0;
  color: #9297a0;
  font-size: 0.7rem;
}

.customer-rating-item .customer-rating-stars {
  justify-content: flex-start;
  gap: 4px;
  margin-top: 12px;
}

.customer-rating-item .rating-star-large {
  padding: 0 1px;
  font-size: 2rem;
}

.customer-rating-item .customer-rating-score-label {
  min-height: 18px;
  margin: 5px 0 12px;
  text-align: left;
  color: var(--customer-wine);
  font-size: 0.82rem;
}

.customer-rating-field-label {
  display: block;
  margin-bottom: 6px;
  color: #363c47;
  font-size: 0.76rem;
  font-weight: 800;
}

.customer-rating-field-label span {
  color: #959aa3;
  font-weight: 600;
}

.customer-rating-item .customer-rating-feedback {
  min-height: 96px;
  padding: 10px 12px;
  border-radius: 10px;
  background: #f6f4f4;
  font-size: 0.8rem;
}

.customer-rating-item .customer-rating-char-count {
  margin: 4px 2px 12px 0;
  font-size: 0.68rem;
}

.customer-rating-media-field {
  margin-top: 4px;
}

.customer-rating-upload {
  min-height: 42px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  border: 1px dashed rgba(107, 32, 43, 0.34);
  border-radius: 10px;
  background: #fffafa;
  color: var(--customer-wine);
  cursor: pointer;
  font-size: 0.76rem;
  font-weight: 800;
  transition:
    background-color 0.18s ease,
    border-color 0.18s ease;
}

.customer-rating-upload:hover {
  border-color: var(--customer-wine-hover);
  background: #fff0f0;
}

.customer-rating-media-preview {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 8px;
}

.customer-rating-media-thumb {
  position: relative;
  width: 70px;
  height: 70px;
  overflow: hidden;
  border: 1px solid rgba(107, 32, 43, 0.12);
  border-radius: 9px;
  background: #f2eeee;
}

.customer-rating-media-thumb img,
.customer-rating-media-thumb video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.customer-rating-media-thumb small {
  position: absolute;
  right: 2px;
  bottom: 2px;
  left: 2px;
  overflow: hidden;
  padding: 2px 3px;
  border-radius: 4px;
  background: rgba(43, 43, 49, 0.58);
  color: var(--customer-paper-sink);
  font-size: 0.48rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.customer-rating-media-thumb button {
  position: absolute;
  top: 3px;
  right: 3px;
  width: 19px;
  height: 19px;
  border: 0;
  border-radius: 50%;
  background: rgba(107, 32, 43, 0.88);
  color: var(--customer-paper-sink);
  cursor: pointer;
  font-size: 0.8rem;
  line-height: 1;
}

.customer-rating-media-thumb:not(.is-new) button {
  display: none;
}

.customer-rating-anonymous {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  color: #515762;
  cursor: pointer;
  font-size: 0.76rem;
}

.customer-rating-anonymous input {
  width: 16px;
  height: 16px;
  accent-color: var(--customer-wine);
}

.customer-rating-actions {
  position: relative;
  z-index: 2;
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
  gap: 10px;
  padding: 14px 24px max(14px, env(safe-area-inset-bottom));
  border-top: 1px solid rgba(107, 32, 43, 0.1);
  background: rgba(255, 250, 247, 0.96);
  backdrop-filter: blur(12px);
}

.customer-rating-actions .customer-rating-cancel-btn,
.customer-rating-actions .customer-rating-submit-btn {
  min-height: 42px;
  border-radius: 11px;
}

.customer-rating-submit-btn {
  border: 1px solid var(--customer-wine);
  background: var(--customer-wine);
  color: var(--customer-paper-sink);
  cursor: pointer;
  font-family: "Montserrat", sans-serif;
  font-size: 0.8rem;
  font-weight: 800;
}

.customer-rating-submit-btn:hover:not(:disabled) {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  transform: none;
}

.customer-rating-submit-btn:disabled {
  cursor: wait;
  opacity: 0.7;
}

.customer-rating-discard-overlay {
  position: fixed;
  inset: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: var(--ux-dlg-scrim);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease;
}

.customer-rating-discard-overlay.show {
  opacity: 1;
  pointer-events: auto;
}

.customer-rating-discard-card {
  width: min(390px, 100%);
  padding: 22px;
  border: 1px solid rgba(107, 32, 43, 0.14);
  border-radius: 18px;
  background: var(--customer-paper);
  box-shadow: 0 24px 60px rgba(45, 12, 12, 0.25);
  text-align: center;
}

.customer-rating-discard-icon {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  margin: 0 auto 10px;
  border-radius: 50%;
  background: #fff3dd;
  color: var(--customer-wine);
}

.customer-rating-discard-card h3 {
  margin: 0;
  color: var(--customer-wine);
  font-size: 1.05rem;
}

.customer-rating-discard-card p {
  margin: 8px 0 18px;
  color: #737984;
  font-size: 0.8rem;
  line-height: 1.5;
}

.customer-rating-discard-actions {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 0.7fr);
  gap: 9px;
}

.customer-rating-discard-actions .customer-rating-cancel-btn,
.customer-rating-discard-actions .customer-rating-submit-btn {
  min-height: 40px;
  padding: 8px 10px;
  border-radius: 10px;
  font-size: 0.72rem;
}

@media (max-width: 560px) {
  .customer-rating-card {
    max-height: calc(100dvh - 10px);
    border-radius: 18px;
  }

  .customer-rating-head,
  .customer-rating-product-name,
  .customer-rating-items,
  .customer-rating-actions {
    padding-left: 14px;
    padding-right: 14px;
  }

  .customer-rating-actions,
  .customer-rating-discard-actions {
    grid-template-columns: 1fr;
  }

  .customer-rating-body {
    margin-right: 4px;
  }

  .customer-rating-loading,
  .customer-rating-empty {
    min-height: 190px;
    padding: 18px 14px;
  }
}

/* ===== Order Received — Rate Prompt Toast ===== */
.customer-rate-prompt-popup {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 99999;
  max-width: 350px;
  width: calc(100vw - 48px);
  background: linear-gradient(
    135deg,
    rgba(247, 242, 236, 0.98),
    rgba(255, 248, 238, 0.95)
  );
  border: 1px solid rgba(107, 32, 43, 0.16);
  border-radius: var(--ux-dlg-radius);
  box-shadow: 0 20px 50px rgba(45, 12, 12, 0.22);
  backdrop-filter: blur(16px);
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity 0.3s ease,
    transform 0.3s ease;
  pointer-events: none;
}
.customer-rate-prompt-popup.show {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.customer-rate-prompt-inner {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 14px 16px;
}
.customer-rate-prompt-icon {
  font-size: 1.4rem;
  line-height: 1;
  flex-shrink: 0;
}
.customer-rate-prompt-text {
  flex: 1;
  min-width: 0;
}
.customer-rate-prompt-text strong {
  display: block;
  font-size: 0.85rem;
  font-weight: 700;
  color: #1a202c;
  margin-bottom: 3px;
}
.customer-rate-prompt-text p {
  margin: 0;
  font-size: 0.78rem;
  color: #4b5563;
  line-height: 1.4;
}
.customer-rate-prompt-link {
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--customer-wine);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.customer-rate-prompt-link:hover {
  color: var(--customer-wine-hover);
}
.customer-rate-prompt-close {
  background: none;
  border: none;
  padding: 0;
  font-size: 1.1rem;
  line-height: 1;
  color: #9ca3af;
  cursor: pointer;
  flex-shrink: 0;
  margin-top: -2px;
}
.customer-rate-prompt-close:hover {
  color: #374151;
}

/* =========================================================
   Returns & Refunds
   Nothing new is invented here: the pills follow the
   `.customer-order-status.status-*` palette style, the buttons
   reuse `.customer-order-detail-btn` metrics, and the request
   modal borrows the rating modal shell wholesale.
   ========================================================= */

/* ── Status pills ─────────────────────────────────────────── */
.customer-return-status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 0.71rem;
  font-weight: 700;
  border: 1px solid transparent;
  white-space: nowrap;
}

.customer-return-status i {
  font-size: 0.66rem;
}

.customer-return-status.status-requested {
  background: #fff4db;
  color: #9a6700;
  border-color: #f0d89c;
}

.customer-return-status.status-approved {
  background: #e8f1ff;
  color: #2055c6;
  border-color: #c5d8ff;
}

.customer-return-status.status-in-transit {
  background: #eef2ff;
  color: #4338ca;
  border-color: #c7d2fe;
}

.customer-return-status.status-received {
  background: #e9fbf9;
  color: #0f766e;
  border-color: #b8eee7;
}

.customer-return-status.status-processing {
  background: #f3e8ff;
  color: #6d28d9;
  border-color: #ddd0fb;
}

.customer-return-status.status-refunded {
  background: #e7f5e9;
  color: #2e7d32;
  border-color: #b7e0be;
}

.customer-return-status.status-rejected {
  background: #fde8e8;
  color: var(--customer-wine);
  border-color: #f4b6b6;
}

.customer-return-status.status-cancelled {
  background: #f1f5f9;
  color: #475569;
  border-color: #dbe3ec;
}

/* ── Return rows in the Returns tab ───────────────────────── */
.customer-return-card .customer-order-actions {
  flex-wrap: wrap;
  justify-content: flex-end;
}

.customer-return-latest {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 4px 0 0;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--customer-wine);
}

.customer-return-latest i {
  font-size: 0.66rem;
}

.customer-return-amount-caption {
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #94a3b8;
}

.customer-return-note {
  margin: 0 0 10px;
  font-size: 0.74rem;
  line-height: 1.5;
  color: #64748b;
}

/* ── Entry-point buttons on completed order rows ───────────── */
/* Same box metrics as `.customer-order-detail-btn`; the maroon fill marks
   the return request as the primary action of the two. */
.customer-order-return-btn,
.customer-order-return-view-btn,
.customer-order-return-cancel-btn,
.customer-order-return-ship-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 1px solid #d8e1ec;
  background: var(--customer-paper);
  color: #334155;
  border-radius: 8px;
  padding: 6px 11px;
  font-family: "Montserrat", sans-serif;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color 0.2s ease,
    color 0.2s ease,
    border-color 0.2s ease,
    transform 0.08s ease;
}

.customer-order-return-btn i,
.customer-order-return-view-btn i,
.customer-order-return-ship-btn i {
  font-size: 0.68rem;
}

.customer-order-return-btn:hover,
.customer-order-return-view-btn:hover,
.customer-order-return-cancel-btn:hover {
  background: #fef2f2;
  color: var(--customer-wine-hover);
  border-color: #e4c5c5;
}

.customer-order-return-btn:active,
.customer-order-return-view-btn:active,
.customer-order-return-cancel-btn:active,
.customer-order-return-ship-btn:active {
  transform: scale(0.97);
}

/* Ineligible orders keep the button visible so it can explain itself. */
.customer-order-return-btn.is-blocked {
  background: #f8fafc;
  color: #94a3b8;
  border-color: #e2e8f0;
}

.customer-order-return-btn.is-blocked:hover {
  background: #f1f5f9;
  color: #64748b;
  border-color: #dbe3ec;
}

/* Sending the item back is the customer's next required step. */
.customer-order-return-ship-btn {
  background: var(--customer-wine);
  border-color: var(--customer-wine);
  color: var(--customer-paper-sink);
}

.customer-order-return-ship-btn:hover {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
}

.customer-order-return-cancel-btn:disabled,
.customer-order-return-ship-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}

.customer-return-detail-actions {
  margin: 0 0 14px;
  justify-content: flex-start;
  flex-wrap: wrap;
}

/* ── Return detail modal blocks ────────────────────────────── */
.customer-return-evidence-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: 8px;
  padding: 4px 0 2px;
}

.customer-return-evidence-item {
  position: relative;
  display: block;
  overflow: hidden;
  border: 1px solid #e5ebf3;
  border-radius: 10px;
  background: #f8fafc;
  aspect-ratio: 1 / 1;
  text-decoration: none;
  transition:
    border-color 0.2s ease,
    box-shadow 0.2s ease,
    transform 0.08s ease;
}

.customer-return-evidence-item:hover {
  border-color: #e4c5c5;
  box-shadow: 0 8px 18px rgba(143, 17, 17, 0.14);
}

.customer-return-evidence-item:active {
  transform: scale(0.97);
}

.customer-return-evidence-item img,
.customer-return-evidence-item video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.customer-return-evidence-item span {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 3px 0;
  background: rgba(15, 23, 42, 0.62);
  color: var(--customer-paper-sink);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.customer-return-notes .customer-return-note-row {
  border-left: 3px solid #e5ebf3;
  padding: 2px 0 2px 10px;
  margin-bottom: 10px;
}

.customer-return-note-row:last-child {
  margin-bottom: 0;
}

.customer-return-note-row > span {
  display: block;
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #94a3b8;
}

.customer-return-note-row p {
  margin: 3px 0 0;
  font-size: 0.78rem;
  line-height: 1.5;
  color: #334155;
  white-space: pre-line;
}

/* The store's own decision is the one note the customer must not miss. */
.customer-return-notes .customer-return-note-row.is-store {
  border-left-color: var(--customer-wine);
  background: #fef2f2;
  border-radius: 0 8px 8px 0;
  padding: 8px 10px;
}

.customer-return-receipt {
  border-color: #b7e0be;
  background: #f2fbf4;
}

.customer-return-receipt h4 {
  color: #2e7d32;
}

/* ── Return request modal ─────────────────────────────────── */
/* The rating modal pads inside each item card; this form pads the body once
   so its plain fields line up with that same 24px gutter. */
.customer-return-request-card {
  max-width: 560px;
}

.customer-return-request-card .customer-rating-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 4px 24px 20px;
}

/* The body is a scrolling flex column, so its children are shrinkable by
   default. A textarea's automatic minimum size is zero, so the moment the form
   grows taller than the card the note fields collapse to their padding. Pinning
   every field to its natural height keeps them intact and lets the body scroll
   instead. */
.customer-return-request-card .customer-rating-body > *,
.customer-return-form-card .customer-rating-body > * {
  flex: 0 0 auto;
}

.customer-return-request-card .customer-rating-feedback,
.customer-return-form-card .customer-rating-feedback {
  min-height: 72px;
}

.customer-return-request-card .customer-rating-product-name {
  padding: 8px 0 2px;
}

.customer-return-request-card .customer-rating-field-label {
  margin: 12px 0 6px;
}

.customer-return-window-note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  border: 1px solid #f0d89c;
  border-radius: 10px;
  background: #fffaeb;
  padding: 9px 11px;
  color: #8a6100;
  font-size: 0.74rem;
  font-weight: 600;
  line-height: 1.45;
}

.customer-return-window-note i {
  margin-top: 2px;
}

.customer-return-pick-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.customer-return-pick {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  border: 1px solid #eef2f7;
  border-radius: 10px;
  background: #f8fafc;
  padding: 9px 11px;
  transition:
    background-color 0.2s ease,
    border-color 0.2s ease;
}

.customer-return-pick.is-selected {
  background: #fef2f2;
  border-color: #e4c5c5;
}

.customer-return-pick.is-disabled {
  opacity: 0.55;
}

.customer-return-pick-check {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  flex: 1 1 auto;
  min-width: 0;
  cursor: pointer;
}

.customer-return-pick.is-disabled .customer-return-pick-check {
  cursor: not-allowed;
}

.customer-return-pick-check input[type="checkbox"] {
  margin-top: 3px;
  width: 15px;
  height: 15px;
  accent-color: var(--customer-wine);
  cursor: inherit;
  flex-shrink: 0;
}

.customer-return-pick-copy {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.customer-return-pick-copy strong {
  color: #1f2937;
  font-size: 0.8rem;
  font-weight: 800;
  overflow-wrap: anywhere;
}

.customer-return-pick-copy span {
  color: #6b7280;
  font-size: 0.71rem;
  font-weight: 600;
}

.customer-return-qty {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  border: 1px solid #d8e1ec;
  border-radius: 999px;
  background: var(--customer-paper);
  padding: 2px;
  flex-shrink: 0;
}

.customer-return-qty button {
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 999px;
  background: transparent;
  color: var(--customer-wine);
  font-size: 0.86rem;
  font-weight: 800;
  line-height: 1;
  cursor: pointer;
  transition:
    background-color 0.2s ease,
    color 0.2s ease,
    transform 0.08s ease;
}

.customer-return-qty button:hover:not(:disabled) {
  background: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
}

.customer-return-qty button:active:not(:disabled) {
  transform: scale(0.92);
}

.customer-return-qty button:disabled {
  color: #cbd5e1;
  cursor: not-allowed;
}

.customer-return-qty span {
  min-width: 20px;
  text-align: center;
  font-size: 0.78rem;
  font-weight: 800;
  color: #1f2937;
}

.customer-return-select {
  width: 100%;
  border: 1px solid rgba(107, 32, 43, 0.14);
  border-radius: 10px;
  background: rgba(247, 242, 236, 0.92);
  padding: 10px 12px;
  font-family: "Montserrat", sans-serif;
  font-size: 0.82rem;
  font-weight: 600;
  color: #222833;
  outline: none;
  cursor: pointer;
  transition:
    border-color 0.2s ease,
    box-shadow 0.2s ease;
}

.customer-return-select:focus {
  border-color: var(--customer-wine);
  box-shadow: 0 0 0 3px rgba(133, 19, 19, 0.12);
}

.customer-return-resolution {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.customer-return-resolution-option {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 1px solid #d8e1ec;
  border-radius: 999px;
  background: var(--customer-paper);
  padding: 7px 13px;
  font-size: 0.75rem;
  font-weight: 700;
  color: #334155;
  cursor: pointer;
  transition:
    background-color 0.2s ease,
    color 0.2s ease,
    border-color 0.2s ease,
    transform 0.08s ease;
}

.customer-return-resolution-option:hover {
  background: #eef2f7;
}

.customer-return-resolution-option:active {
  transform: scale(0.97);
}

.customer-return-resolution-option.is-active {
  background: var(--customer-wine);
  border-color: var(--customer-wine);
  color: var(--customer-paper-sink);
}

.customer-return-resolution-option input {
  accent-color: var(--customer-paper-sink);
  width: 14px;
  height: 14px;
  cursor: pointer;
}

.customer-return-estimate {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 14px;
  border: 1px solid #e4c5c5;
  border-radius: 12px;
  background: #fef2f2;
  padding: 11px 13px;
}

.customer-return-estimate span {
  color: #6b7280;
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.customer-return-estimate strong {
  color: var(--customer-wine);
  font-size: 1.02rem;
  font-weight: 800;
}

.customer-return-fineprint {
  margin: 8px 0 0;
  color: #94a3b8;
  font-size: 0.71rem;
  font-weight: 600;
  line-height: 1.5;
}

/* ── "Item shipped back" courier form ─────────────────────── */
.customer-return-form-card {
  max-width: 460px;
}

.customer-return-form-card .customer-rating-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 4px 24px 20px;
}

.customer-return-form-card .customer-rating-product-name {
  padding: 8px 0 4px;
}

.customer-return-form-card .customer-rating-field-label {
  margin: 10px 0 6px;
}

.customer-return-input {
  width: 100%;
  border: 1px solid rgba(107, 32, 43, 0.14);
  border-radius: 10px;
  background: rgba(247, 242, 236, 0.92);
  padding: 10px 12px;
  font-family: "Montserrat", sans-serif;
  font-size: 0.84rem;
  color: #222833;
  outline: none;
  transition:
    border-color 0.2s ease,
    box-shadow 0.2s ease;
}

.customer-return-input:focus {
  border-color: var(--customer-wine);
  box-shadow: 0 0 0 3px rgba(133, 19, 19, 0.12);
}

.customer-return-input.has-error {
  border-color: var(--customer-danger);
  box-shadow: 0 0 0 3px rgba(183, 28, 28, 0.12);
}

/* ── GCash "pay after checkout" panel ─────────────────────────
   Opened from a To Pay card. Reuses the rating overlay shell for every
   animation, and only restates what is specific to paying: the amount, the
   destination, and the reference field. */
.customer-gcash-card {
  max-width: 480px;
}

.customer-gcash-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 4px 24px 20px;
}

/* The one number a mistyped payment turns on, so it is the largest thing here. */
.cgc-amount {
  border: 1px solid rgba(13, 110, 231, 0.22);
  background: linear-gradient(135deg, #f3f8ff 0%, #eaf2ff 100%);
  border-radius: 14px;
  padding: 12px 14px;
}

.cgc-amount-label {
  display: block;
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #5a7196;
}

.cgc-amount-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 2px;
}

.cgc-amount-value {
  font-size: 1.5rem;
  font-weight: 900;
  color: #0a4ea8;
  letter-spacing: -0.01em;
}

.cgc-copy-btn {
  border: 1px solid rgba(13, 110, 231, 0.32);
  background: var(--customer-paper);
  color: #0a4ea8;
  border-radius: 999px;
  padding: 5px 13px;
  font-family: "Montserrat", sans-serif;
  font-size: 0.68rem;
  font-weight: 800;
  cursor: pointer;
  transition: all 0.18s ease;
  white-space: nowrap;
}

.cgc-copy-btn:hover {
  background: #eaf2ff;
}

/* Deadline. Amber, never red: nothing is cancelled automatically, so this is a
   prompt and not a threat. */
.cgc-deadline {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0;
  padding: 9px 11px;
  border-radius: 10px;
  border: 1px solid rgba(214, 158, 46, 0.3);
  background: rgba(214, 158, 46, 0.1);
  font-size: 0.73rem;
  line-height: 1.5;
  font-weight: 700;
  color: #6d5b1e;
}

.cgc-deadline.is-overdue {
  border-color: rgba(107, 32, 43, 0.34);
  background: rgba(107, 32, 43, 0.1);
  color: var(--customer-wine);
}

/* Shown instead of the deadline once a reference is in. */
.cgc-review {
  border: 1px solid rgba(74, 84, 100, 0.2);
  background: #f6f8fb;
  border-radius: 12px;
  padding: 11px 13px;
}

.cgc-review-title {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0 0 5px;
  font-size: 0.79rem;
  font-weight: 800;
  color: #2f3846;
}

.cgc-review-body {
  margin: 0;
  font-size: 0.73rem;
  line-height: 1.55;
  color: #5b6473;
}

.cgc-review-proof {
  display: inline-block;
  margin-top: 7px;
  font-size: 0.72rem;
  font-weight: 800;
  color: #0a4ea8;
  text-decoration: underline;
}

/* Where the money goes. */
.cgc-account {
  display: grid;
  gap: 8px;
  padding: 11px 13px;
  border-radius: 12px;
  border: 1px solid rgba(107, 32, 43, 0.14);
  background: rgba(255, 254, 250, 0.92);
}

.cgc-account-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.cgc-account-label {
  min-width: 96px;
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #7a808c;
}

.cgc-account-value {
  font-size: 0.86rem;
  font-weight: 800;
  color: #222833;
  letter-spacing: 0.03em;
}

/* The QR is the centre's own uploaded image - it cannot be generated from a
   phone number, because a QR Ph payload is issued to the merchant. */
.cgc-qr {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
}

.cgc-qr-img {
  width: 190px;
  max-width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
  border-radius: 12px;
  border: 1px solid rgba(107, 32, 43, 0.14);
  background: var(--customer-paper);
  padding: 8px;
}

.cgc-qr-save {
  font-size: 0.7rem;
  font-weight: 800;
  color: #0a4ea8;
  text-decoration: underline;
}

.cgc-openapp {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.cgc-openapp-btn {
  width: 100%;
  padding: 11px 18px;
  border: none;
  border-radius: 12px;
  background: linear-gradient(135deg, #0a5fd6 0%, #1d8bf1 100%);
  color: var(--customer-paper-sink);
  font-family: "Montserrat", sans-serif;
  font-size: 0.82rem;
  font-weight: 800;
  cursor: pointer;
  box-shadow: 0 8px 18px rgba(13, 110, 231, 0.24);
}

.cgc-openapp-hint {
  margin: 0;
  font-size: 0.7rem;
  line-height: 1.45;
  color: #7a808c;
}

.cgc-steps {
  margin: 0;
  padding-left: 20px;
  display: grid;
  gap: 6px;
  font-size: 0.74rem;
  line-height: 1.55;
  color: #4d5563;
}

.cgc-steps strong {
  font-weight: 800;
  color: #222833;
}

.cgc-unavailable {
  margin: 0;
  padding: 9px 11px;
  border-radius: 10px;
  border: 1px solid rgba(214, 158, 46, 0.3);
  background: rgba(214, 158, 46, 0.1);
  font-size: 0.73rem;
  font-weight: 700;
  line-height: 1.5;
  color: #6d5b1e;
}

.cgc-field {
  display: flex;
  flex-direction: column;
}

.cgc-field .customer-rating-field-label {
  margin: 0 0 6px;
}

.cgc-field .customer-rating-field-label span {
  font-weight: 700;
  color: #8a8f9a;
  text-transform: none;
  letter-spacing: 0;
}

.cgc-req {
  color: var(--customer-wine);
  font-weight: 900;
}

.cgc-ref-input {
  letter-spacing: 0.1em;
  font-weight: 700;
}

.cgc-error {
  margin: 6px 0 0;
  font-size: 0.71rem;
  font-weight: 700;
  line-height: 1.45;
  color: var(--customer-danger);
}

.cgc-error[hidden] {
  display: none;
}

/* The dashed box is styled here, but the control inside it is drawn by the
   browser, so it arrived as a grey "Choose File" that matched nothing else on
   the site. Both pseudo-elements are needed: Firefox and current Chromium
   understand ::file-selector-button, older WebKit only knows its own prefixed
   name, and neither engine accepts a selector list containing the other's — so
   the two blocks are duplicated on purpose rather than comma-joined. */
.cgc-file-input {
  width: 100%;
  font-family: "Montserrat", sans-serif;
  font-size: 0.74rem;
  color: #4d5563;
  padding: 8px 10px;
  border: 1px dashed rgba(107, 32, 43, 0.28);
  border-radius: 10px;
  background: rgba(247, 242, 236, 0.9);
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease;
}

.cgc-file-input:hover {
  border-color: var(--customer-wine-hover);
  background: var(--customer-paper);
}

.cgc-file-input::file-selector-button {
  margin-right: 10px;
  padding: 7px 14px;
  border: none;
  border-radius: 8px;
  background: linear-gradient(135deg, var(--customer-wine) 0%, var(--customer-wine) 100%);
  color: var(--customer-paper-sink);
  font-family: "Montserrat", sans-serif;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: background 0.2s ease;
}

.cgc-file-input::file-selector-button:hover {
  background: linear-gradient(135deg, var(--customer-wine-hover) 0%, var(--customer-wine-hover) 100%);
}

.cgc-file-input::file-selector-button:active {
  background: linear-gradient(135deg, var(--customer-wine-hover) 0%, var(--customer-wine-hover) 100%);
}

.cgc-file-input::-webkit-file-upload-button {
  margin-right: 10px;
  padding: 7px 14px;
  border: none;
  border-radius: 8px;
  background: linear-gradient(135deg, var(--customer-wine) 0%, var(--customer-wine) 100%);
  color: var(--customer-paper-sink);
  font-family: "Montserrat", sans-serif;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: background 0.2s ease;
}

.cgc-file-input::-webkit-file-upload-button:hover {
  background: linear-gradient(135deg, var(--customer-wine-hover) 0%, var(--customer-wine-hover) 100%);
}

.cgc-file-input::-webkit-file-upload-button:active {
  background: linear-gradient(135deg, var(--customer-wine-hover) 0%, var(--customer-wine-hover) 100%);
}

.cgc-file-name {
  margin: 6px 0 0;
  font-size: 0.7rem;
  font-weight: 700;
  color: #15803d;
}

.cgc-file-name[hidden] {
  display: none;
}

/* The panel records a claim, not a payment. Saying so here is what keeps the
   customer from reading a submitted reference as a settled order. */
.cgc-honesty {
  margin: 0;
  font-size: 0.69rem;
  line-height: 1.5;
  color: #8a8f9a;
}

@media (max-width: 560px) {
  .customer-gcash-body {
    padding: 4px 14px 20px;
  }

  .cgc-amount-value {
    font-size: 1.3rem;
  }

  .cgc-account-label {
    min-width: 84px;
  }
}

/* ── Customer-initiated cancellation ──────────────────────────
   Shopee and Lazada both settle on the same shape: one sheet, a radio list of
   pre-written reasons, one confirm button. The list is server-supplied, so
   nothing here assumes a fixed number of options. */

/* A cancelled card stays in the list as history. Draining the colour is what
   stops it competing with the live orders above it. */
.customer-order-card.is-cancelled {
  background: #fbfbfc;
  border-color: #e2e6ed;
}

.customer-order-card.is-cancelled .customer-order-thumb img {
  filter: grayscale(0.55);
  opacity: 0.85;
}

.customer-order-cancel-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border-radius: 999px;
  padding: 6px 13px;
  font-family: "Montserrat", sans-serif;
  font-size: 0.72rem;
  font-weight: 700;
  cursor: pointer;
  border: 1px solid #e0c3c3;
  background: var(--customer-paper);
  color: var(--customer-wine);
  transition:
    background 0.18s ease,
    border-color 0.18s ease,
    color 0.18s ease;
}

.customer-order-cancel-btn:hover {
  background: #fdf1f1;
  border-color: #d59a9a;
  color: var(--customer-wine-hover);
}

/* The pending variant is a status, not an action - it opens an explanation
   instead of a form, so it must not look pressable in the same way. */
.customer-order-cancel-btn.is-pending {
  border-color: #f0d89c;
  background: #fff8e8;
  color: var(--customer-wine);
  cursor: help;
}

.customer-order-cancel-btn.is-pending:hover {
  background: #fff2d6;
  border-color: #e6c777;
  color: var(--customer-wine-hover);
}

/* One band under the order meta that says what happened and who owes what.
   Three variants, all the same geometry so the card height barely moves. */
.customer-order-cancel-band {
  display: flex;
  align-items: flex-start;
  gap: 7px;
  margin: 6px 0 0;
  padding: 7px 9px;
  border: 1px solid transparent;
  border-radius: 9px;
  font-size: 0.69rem;
  font-weight: 600;
  line-height: 1.5;
}

.customer-order-cancel-band i {
  flex-shrink: 0;
  margin-top: 2px;
  font-size: 0.78rem;
}

.customer-order-cancel-band strong {
  font-weight: 800;
}

.customer-order-cancel-band.is-cancelled {
  background: #f4f5f8;
  border-color: #e0e4ec;
  color: #59616f;
}

.customer-order-cancel-band.is-pending {
  background: #fff8e8;
  border-color: #f2e0b4;
  color: var(--customer-wine);
}

/* Declined is informational, not an error: the order carried on as normal. */
.customer-order-cancel-band.is-declined {
  background: #eef4ff;
  border-color: #cfdefb;
  color: #2d5395;
}

/* Same three states, told at length inside the detail modal. */
.customer-order-cancel-detail {
  border: 1px solid transparent;
  border-radius: 12px;
  padding: 12px 14px;
  margin: 0 0 14px;
}

.customer-order-cancel-detail h4 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 6px;
  font-size: 0.82rem;
  font-weight: 800;
}

.customer-order-cancel-detail p {
  margin: 0 0 5px;
  font-size: 0.73rem;
  font-weight: 600;
  line-height: 1.55;
}

.customer-order-cancel-detail p:last-child {
  margin-bottom: 0;
}

/* The customer's own words, and any staff note, set apart from FMRC's copy so
   it is obvious which is which. */
.customer-order-cancel-detail-note {
  padding: 7px 10px;
  border-radius: 8px;
  background: rgba(247, 242, 236, 0.72);
  font-style: italic;
}

.customer-order-cancel-detail.is-cancelled {
  background: #f4f5f8;
  border-color: #e0e4ec;
  color: #59616f;
}

.customer-order-cancel-detail.is-pending {
  background: #fff8e8;
  border-color: #f2e0b4;
  color: var(--customer-wine);
}

.customer-order-cancel-detail.is-declined {
  background: #eef4ff;
  border-color: #cfdefb;
  color: #2d5395;
}

/* The sheet. Reuses the rating overlay shell for every animation, so only what
   is specific to picking a reason is restated.

   The shell's width rule is `(1,3,0)` and lives further down this file, so it
   has to be out-specified rather than merely restated - naming both the rating
   and the cancel classes takes this to `(1,5,0)`. A radio list reads better
   narrow than the 560px the rating card wants. */
:is(.ux-dlg, #aptPrivacyModal).customer-rating-overlay.customer-cancel-overlay
  .customer-rating-card.customer-cancel-card.ux-dlg__card {
  width: min(100%, 460px);
  max-width: min(100%, 460px);
  /* Fixed, not content-driven. The shell only caps the height, so picking "Other
     reason" reveals the detail box and the whole dialog jumps taller under the
     customer's cursor - the radio they just clicked slides out from under it.
     Pinning the height hands that growth to `.customer-rating-body`, which
     already scrolls, and focusing the textarea pulls it into view. The viewport
     term keeps a short screen from overflowing; there the value is the same one
     the shell's max-height would have produced anyway. */
  height: min(calc(100dvh - 28px), 640px);
}

.customer-cancel-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 4px 24px 20px;
}

/* The body is the scroller, so nothing inside it may shrink instead of
   overflowing. Left shrinkable, `.ccx-reasons` - which is `overflow: hidden` for
   its rounded corners - was squashed from 435px to 26px the moment the detail
   box appeared, clipping nine of the ten reasons with no scrollbar anywhere,
   because a child that shrinks never overflows its parent. */
.customer-cancel-body > * {
  flex: 0 0 auto;
}

.ccx-subtitle {
  margin: 3px 0 0;
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.5;
  color: #6b7280;
}

/* Says what the button will actually do. On a paid order this is the only place
   the by-hand refund is spelled out before the customer commits. */
.ccx-notice {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0;
  padding: 9px 11px;
  border: 1px solid #f2e0b4;
  border-radius: 10px;
  background: #fff8e8;
  font-size: 0.71rem;
  font-weight: 600;
  line-height: 1.55;
  color: var(--customer-wine);
}

.ccx-notice i {
  flex-shrink: 0;
  margin-top: 2px;
  font-size: 0.82rem;
}

.ccx-reasons {
  display: flex;
  flex-direction: column;
  gap: 2px;
  border: 1px solid #e3e8f0;
  border-radius: 12px;
  overflow: hidden;
  background: var(--customer-paper);
}

.ccx-reason {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 13px;
  cursor: pointer;
  border-bottom: 1px solid #eef1f6;
  transition: background 0.15s ease;
}

.ccx-reason:last-child {
  border-bottom: 0;
}

.ccx-reason:hover {
  background: #f7f9fc;
}

/* The native radio is hidden rather than removed so the group stays keyboard
   and screen-reader operable; `.ccx-reason-mark` is only its picture. */
.ccx-reason input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.ccx-reason-mark {
  flex-shrink: 0;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  border: 2px solid #c3cbd8;
  background: var(--customer-paper);
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}

.ccx-reason input[type="radio"]:checked ~ .ccx-reason-mark {
  border-color: var(--customer-wine);
  box-shadow: inset 0 0 0 3.5px var(--customer-paper), inset 0 0 0 9px #8f1111;
}

.ccx-reason input[type="radio"]:focus-visible ~ .ccx-reason-mark {
  outline: 2px solid var(--customer-wine);
  outline-offset: 2px;
}

.ccx-reason-label {
  font-size: 0.76rem;
  font-weight: 600;
  line-height: 1.4;
  color: #3b4252;
}

.ccx-reason input[type="radio"]:checked ~ .ccx-reason-label {
  font-weight: 800;
  color: var(--customer-wine);
}

/* Only shown for the reason that needs it, so it never asks for typing the
   customer does not owe. */
.ccx-detail[hidden] {
  display: none;
}

.ccx-detail-input {
  resize: vertical;
  min-height: 66px;
}

.ccx-error {
  margin: 0;
  font-size: 0.71rem;
  font-weight: 700;
  line-height: 1.45;
  color: var(--customer-danger);
}

.ccx-error[hidden] {
  display: none;
}

@media (max-width: 560px) {
  .customer-cancel-body {
    padding: 4px 14px 20px;
  }

  .ccx-reason {
    padding: 12px 11px;
  }
}


/* ── Returns toast ────────────────────────────────────────── */
/* `.customer-return-toast` deliberately adds no rules: it inherits every
   metric and animation from `.customer-rate-prompt-popup`. The class exists
   only so the returns toast can be targeted in future without a refactor. */

@media (max-width: 560px) {
  .customer-return-pick {
    flex-wrap: wrap;
  }

  .customer-return-qty {
    margin-left: auto;
  }

  .customer-return-card .customer-order-side {
    align-items: flex-start;
  }

  /* The rating shell already drops its own gutters to 14px here; the two return
     forms override the body padding, so they need the same narrow gutter. */
  .customer-return-request-card .customer-rating-body,
  .customer-return-form-card .customer-rating-body {
    padding: 4px 14px 20px;
  }

  /* Thumb-sized stepper and remove buttons instead of mouse-sized ones. */
  .customer-return-qty button {
    width: 30px;
    height: 30px;
    font-size: 0.94rem;
  }

  .customer-return-qty span {
    min-width: 24px;
  }

  .customer-return-request-card .customer-rating-media-thumb button {
    width: 22px;
    height: 22px;
  }

  /* Two even columns read better than ragged pills once the row can only hold
     one and a half of them. */
  .customer-return-resolution {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .customer-return-resolution-option {
    justify-content: center;
    padding: 9px 10px;
  }

  .customer-return-estimate {
    flex-wrap: wrap;
  }

  .customer-return-evidence-grid {
    grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
  }
}

@media (max-width: 480px) {
  /* Action rows become an even 2-up grid so every button clears a 34px tap
     target instead of shrinking to its label; nowrap labels are released so a
     long one wraps inside its own cell, and a trailing odd button spans the row.
     Flex wrapping was ragged here because the nowrap labels differ in width. */
  .customer-order-card > .customer-order-actions,
  .customer-return-detail-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: stretch;
  }

  .customer-order-card > .customer-order-actions > button,
  .customer-return-detail-actions > button {
    min-height: 34px;
    padding: 6px 8px;
    white-space: normal;
    line-height: 1.25;
    text-align: center;
  }

  .customer-order-card
    > .customer-order-actions
    > button:last-child:nth-child(odd),
  .customer-return-detail-actions > button:last-child:nth-child(odd) {
    grid-column: 1 / -1;
  }
}

@media (max-width: 400px) {
  .customer-return-resolution {
    grid-template-columns: 1fr;
  }

  .customer-return-estimate strong {
    font-size: 0.96rem;
  }

  .customer-return-evidence-grid {
    grid-template-columns: repeat(auto-fill, minmax(68px, 1fr));
  }

  .customer-return-notes .customer-return-note-row.is-store {
    padding: 8px;
  }
}

/* =========================================================
   Customer-facing final visual refresh (CSS-only)
   Scope: shared header/footer, home sections, customer menu,
   account modal, orders drawer, and guest login/signup prompts.
   ========================================================= */
:root {
  --customer-primary: var(--customer-wine);
  --customer-primary-strong: var(--customer-wine-hover);
  --customer-primary-soft: var(--customer-wine-soft);
  --customer-red: var(--customer-wine);
  --customer-gold: #f1ed12;
  --customer-ink: #1f2937;
  --customer-muted: #667085;
  --customer-line: #eadede;
  --customer-panel: rgba(253, 250, 246, 0.94);
  --customer-shadow: 0 22px 58px rgba(65, 16, 16, 0.13);

  /* ---- The paper ladder (§9.3) -------------------------------------------
     The customer pages carry no solid #ffffff and no solid #000 any more. Two
     warm neutrals do the whole job, both taken from the reference shots:

       --customer-paper       raised material — the header, every card, slab,
                              dialog and popup. The old #ffffff.
       --customer-paper-sink  the field those cards sit on, and the type colour
                              on top of anything maroon. The old #ffffff text.

     They are two steps of one hue, so a paper card on a sink band separates by
     tone alone and needs no shadow to be legible. `--customer-ink-strong` is
     the near-black from the reference: black enough to anchor a heading, warm
     enough that it never reads as #000 next to the cream. */
  --customer-paper: #fdfaf6;
  --customer-paper-sink: #f7f2ec;
  --customer-paper-edge: #efe6da;
  --customer-ink-strong: #2b2b31;

  /* Deep maroon from the reference swatch, with darker hover/press shades.
     Validation red is separate from the brand color. */
  --customer-wine: #6b202b;
  --customer-wine-hover: #511721;
  --customer-wine-active: #45141c;
  --customer-wine-light: #b01c1c;
  --customer-wine-soft: #f5e8e9;
  --customer-danger: #bf1b1b;
  --customer-danger-soft: rgba(191, 27, 27, 0.14);
  --customer-wine-line: rgba(247, 242, 236, 0.16);
  /* The one gradient the minimalism pass keeps: a ±10%/7% diagonal wash, not a
     colour ramp. Two properties do two jobs — `background-color` carries the hue
     and `background-image` carries this — so a maroon surface gets the depth the
     older design had while its hue stays a single token that a hover can swap in
     one line. Because the hue lives in `background-color`, every existing
     `transition: background-color` keeps easing; a real multi-stop gradient is a
     `background-image` and would have snapped instead.

     One wash for the footer and the avatar discs, so they read as the same
     material. Dark end first, light end last, which is the direction the old
     three-stop footer ran (#3f0707 → #9e1414). 135deg is the angle already used
     by `--ux-dlg-band`. Buttons opted out in §9.3: the owner's reference pills
     are flat, and a wash on a button is a gradient by any other name. The light
     stop is the cream, not white — 7% of pure white over maroon still reads
     faintly blue-grey, and this token is the last place white survived in the
     palette layer. */
  --customer-wash: linear-gradient(
    135deg,
    rgba(45, 12, 12, 0.1) 0%,
    rgba(247, 242, 236, 0.07) 100%
  );
}

body {
  color: var(--customer-ink);
  background:
    radial-gradient(
      circle at 9% 0%,
      rgba(241, 237, 18, 0.12),
      transparent 23rem
    ),
    radial-gradient(
      circle at 92% 12%,
      rgba(107, 32, 43, 0.09),
      transparent 22rem
    ),
    var(--customer-paper-sink);
}

/* Shared customer navigation.

   Opaque at every width, on purpose. This rule and the base `.site-header` at
   the top of the file are both (0,1,0), so whichever lands later wins — this
   one did, which is why the bar used to be `rgba(255,255,255,.9)` + a blur and
   the page scrolled visibly underneath it. The phone pass in §7 had already
   replaced that with the flat white below, and its own note records why the
   swap is lossless: 0.9 alpha over the white page *is* this colour at rest, so
   nothing changes visually except that the hero and the About slab stop
   bleeding through. Promoting it to all widths also retires what §7 calls the
   single largest paint cost on the site.

   The shadow is two hairlines rather than one 36px bloom: a sticky bar needs to
   read as an edge, not as a floating card. */
.site-header {
  padding: 12px clamp(18px, 5vw, 72px);
  min-height: 76px; /* keep equal to --ux-header-h */
  background: var(--customer-paper);
  border-bottom: 1px solid rgba(107, 32, 43, 0.1);
  box-shadow:
    0 1px 0 rgba(176, 28, 28, 0.1),
    0 2px 6px rgba(58, 18, 18, 0.06);
}

.logo-container {
  gap: 13px;
}

.header-emblem {
  height: 48px;
  margin-right: 0;
}

.logo-title {
  color: var(--customer-wine);
  letter-spacing: 0.04em;
}

.logo-subtitle {
  color: var(--customer-wine);
  letter-spacing: 0.12em;
}

.main-nav ul {
  align-items: center;
  gap: clamp(14px, 2.6vw, 34px);
}

.nav-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 38px;
  padding: 8px 4px;
  color: var(--customer-ink);
  font-size: 15px;
  font-weight: 750;
  letter-spacing: 0.01em;
}

/* Solid maroon, not the old maroon→gold gradient: gold is spent on the hero CTA
   and the footer heading rules, and a two-stop bar 2px tall reads as a smudge
   anyway. The scaleX/opacity pair stays — it is the active indicator, it is
   compositor-only, and it is not a hover lift. */
.nav-link::after {
  content: "";
  position: absolute;
  left: 4px;
  right: 4px;
  bottom: 3px;
  height: 2px;
  border-radius: 999px;
  background: var(--customer-primary);
  opacity: 0;
  transform: scaleX(0.35);
  transform-origin: center;
  transition:
    opacity 0.2s ease,
    transform 0.2s ease;
}

.nav-link:hover,
.nav-link.active {
  color: var(--customer-wine-hover);
}

.nav-link:hover::after,
.nav-link.active::after {
  opacity: 1;
  transform: scaleX(1);
}

.header-right-actions {
  align-items: center;
  gap: 12px;
}

.user-profile {
  display: inline-grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border: 1px solid rgba(107, 32, 43, 0.18);
  background: var(--customer-paper);
  box-shadow: 0 10px 24px rgba(65, 16, 16, 0.1);
}

.user-profile:hover {
  border-color: rgba(107, 32, 43, 0.32);
  background: var(--customer-primary-soft);
  box-shadow: 0 10px 24px rgba(65, 16, 16, 0.1);
}

.user-initial-badge {
  border-color: rgba(107, 32, 43, 0.32);
  color: var(--customer-wine);
  background: var(--customer-primary-soft);
}

/* Home hero */
.hero-section {
  isolation: isolate;
  overflow: hidden;
  min-height: calc(100vh - 76px);
  padding: clamp(54px, 7vw, 92px) clamp(18px, 5vw, 72px);
  background:
    radial-gradient(
      circle at 78% 18%,
      rgba(241, 237, 18, 0.28),
      transparent 14rem
    ),
    radial-gradient(
      circle at 14% 20%,
      rgba(247, 242, 236, 0.18),
      transparent 18rem
    ),
    linear-gradient(130deg, var(--customer-wine-hover, #4f0909) 0%, var(--customer-wine, #8b0000) 42%, var(--customer-wine-light, #c33425) 100%);
}

/* The hero's own background is written inline by `applyHeroBackground()` from
   the `hero_bg_type` site setting, so it is the owner's to choose and CSS must
   not fight it. What used to sit *on top* of it — a 42px white grid at .08 alpha
   masked across the diagonal, and a 620px translucent blob bleeding off the
   bottom-right — is gone: the same two decorations were deleted from the footer,
   and a hero whose background is configurable is the last place to hard-code a
   second pattern over it.

   `content: none` is deliberate and not the same as deleting the rule: an
   earlier `.hero-section::after` (:6225) paints a full-bleed
   `rgba(0,0,0,.08)→.18` scrim, and the blob rule removed from here was the only
   thing that had been overriding it into a corner shape. Dropping this block
   outright would have *revealed* that scrim and quietly darkened whatever
   background the owner picked. */
.hero-section::after {
  content: none;
}

.hero-container {
  max-width: 1280px;
  gap: clamp(28px, 5vw, 72px);
}

.hero-content-left {
  max-width: 720px;
  padding-right: 0;
}

.hero-title {
  margin-bottom: 34px;
  font-size: clamp(38px, 6.3vw, 74px);
  line-height: 1.05;
  letter-spacing: -0.045em;
  /* Kept, but tight. The background behind this text is owner-configurable and
     can be light, so the shadow is doing contrast work — it just does not need
     a 42px bloom to do it. Warm-tinted rather than pure black: every shadow on
     a customer surface now sits on the maroon side of neutral. */
  text-shadow: 0 2px 10px rgba(45, 12, 12, 0.32);
}

.hero-buttons {
  gap: 14px;
}

.btn-browse,
.btn-appointment {
  min-height: 56px;
  border-radius: var(--apt-radius, 8px);
  padding: 15px 32px;
  letter-spacing: 0.01em;
  box-shadow: 0 8px 18px rgba(30, 10, 10, 0.18);
}

/* Gold here is accent #1 of the two the page is allowed. Hover darkens the fill
   and repeats the resting shadow verbatim; the press scale is the only motion.

   These two buttons are the reference the owner pointed at for every other
   button on the customer site: flat fill, the card's own 8px radius, maroon or
   cream ink, no gradient anywhere. §9.3 propagates exactly this recipe
   outward. */
.btn-browse {
  background: #eef224; /* solid yellow */
  border-color: #eef224;
  color: #3d0808; /* dark maroon ink */
}

.btn-browse:hover {
  background: #c8cc00; /* darker yellow */
  border-color: #c8cc00;
  color: #3d0808;
  box-shadow: 0 8px 18px rgba(30, 10, 10, 0.18);
}

.btn-appointment {
  background: rgba(247, 242, 236, 0.14);
  border-color: rgba(247, 242, 236, 0.82);
  color: #f7f2ec;
}

.btn-appointment:hover {
  background: #f7f2ec; /* cream — not pure white */
  border-color: #f7f2ec;
  color: #3d0808; /* dark maroon text */
  box-shadow: 0 8px 18px rgba(30, 10, 10, 0.18);
}

.btn-browse:active,
.btn-appointment:active {
  transform: scale(0.97);
}

.btn-browse:focus-visible,
.btn-appointment:focus-visible {
  outline: 3px solid rgba(241, 237, 18, 0.55);
  outline-offset: 3px;
}

.hero-graphic {
  width: min(38vw, 470px);
  height: auto;
  border-radius: 50%;
  padding: 16px;
  background: var(--customer-paper);
  border: 4px solid rgba(247, 242, 236, 0.6);
  box-shadow: 0 14px 34px rgba(35, 8, 8, 0.26);
  transition: border-color 0.4s ease;
  cursor: pointer;
  animation: heroLogoBreathe 4.5s ease-in-out infinite alternate;
}

/* The old hover set `transform: scale(1.05) rotate(1.5deg)`, which never once
   applied — a running animation outranks a normal declaration on the same
   property, so `heroLogoBreathe` owned `transform` the whole time. Hover is the
   ring colour now, which is what it could actually affect. */
.hero-graphic:hover {
  border-color: rgba(241, 237, 18, 0.8);
}

/* Same motion the owner sees today, kept to the frame: the translate/scale track
   is unchanged. The three-layer box-shadow that used to be interpolated
   alongside it is gone — shadow is painted, not composited, so it was
   re-rasterising this element every frame for the life of the page in exchange
   for a glow that no longer exists at rest. */
@keyframes heroLogoBreathe {
  0% {
    transform: translateY(0px) scale(1);
  }
  100% {
    transform: translateY(-6px) scale(1.015);
  }
}

.scroll-indicator {
  color: rgba(247, 242, 236, 0.85);
}

/* Home content sections.

   The bands used to carry two radial washes each — a gold one and a maroon one
   over a warm off-white — mirrored between neighbours. Three tints and two
   gradients per band is what made the page read as a different product from the
   appointment flow, so the rhythm is now a plain alternation of the two page
   surfaces the paper ladder defines: `--customer-paper` (raised) and
   `--customer-paper-sink` (the field). No gradient, no solid white, and the
   gold is spent on the hero CTA and the footer heading rules instead.

   Paddings are untouched: they set where each block crosses the reveal
   observer's threshold, and the owner asked for those entrances to stay. */
.about-section,
.mission-section {
  background: var(--customer-paper);
  padding: 80px 5%;
}

.vision-section,
.services-preview-section {
  background: var(--customer-paper-sink);
  padding: 80px 5%;
}

/* One comma-grouped rule on purpose — a partial edit here is the documented way
   to leave the old 32px/blurred look alive on whichever sibling was missed.
   Paper on both bands: against the sink band the card separates by tone, and
   against a paper band the warm hairline is what draws the edge. */
.about-container,
.vision-container,
.mission-container {
  max-width: 1240px;
  background: var(--customer-paper);
  border: 1px solid var(--apt-line-warm);
  border-radius: var(--apt-radius);
  padding: clamp(24px, 3.4vw, 44px);
  box-shadow: 0 10px 26px rgba(65, 16, 16, 0.06);
}

.section-title,
.vm-title,
.services-main-title,
.services-preview-section .section-title {
  color: var(--customer-wine);
  letter-spacing: -0.035em;
  font-weight: 900;
}

/* `#4b5260` was three units off `--apt-body` — two greys nobody can tell apart
   is drift, not a decision. */
.section-text,
.vm-text {
  color: var(--apt-body);
  line-height: 1.75;
}

.features-card {
  border: 1px solid var(--apt-line-warm);
  border-radius: var(--ux-card-radius);
  background: var(--customer-paper);
  box-shadow: 0 8px 20px rgba(61, 35, 28, 0.06);
}

.feature-item {
  padding: 18px 14px;
  border-radius: var(--apt-radius-sm);
  transition: background-color 0.22s ease;
}

.feature-item:hover {
  background: var(--apt-panel);
}

.see-more-link {
  color: var(--customer-wine);
}

/* Hover changes the border only. The old rule grew the shadow from 42px to
   52px, which is the "uplift" read the owner asked to be rid of. */
.landscape-card,
.service-card {
  border: 1px solid var(--apt-line-warm);
  box-shadow: 0 8px 20px rgba(65, 16, 16, 0.06);
}

.landscape-card:hover,
.service-card:hover {
  border-color: rgba(107, 32, 43, 0.25);
  box-shadow: 0 8px 20px rgba(65, 16, 16, 0.06);
}

/* Flat maroon, no wash. The wash is a gradient by any other name and the owner
   ruled gradients out of every button; the two hero buttons are the reference
   and both are flat. The resting shadow is repeated on hover verbatim: a shadow
   that grows is read as the element lifting, which is the one motion ruled out.
   Only the fill darkens, and because the hue is a `background-color` that
   darkening is still a single eased property. */
.view-all-btn {
  border-radius: var(--apt-radius, 8px);
  background-color: var(--customer-wine);
  background-image: none;
  border-color: transparent;
  color: var(--customer-paper-sink);
  box-shadow: 0 6px 16px rgba(128, 24, 18, 0.18);
  transition:
    background-color 0.2s ease,
    box-shadow 0.2s ease;
}

.view-all-btn:hover {
  background-color: #3d0808;
  color: var(--customer-paper-sink);
  box-shadow: 0 6px 16px rgba(128, 24, 18, 0.18);
}

.view-all-btn:active {
  transform: scale(0.97);
}

.view-all-btn:focus-visible {
  outline: 3px solid rgba(241, 237, 18, 0.55);
  outline-offset: 2px;
}

/* Shared footer.

   Four decorations used to stack here: a gold radial at 16% 0%, a three-stop
   maroon diagonal, a 38px white grid overlay at .06 alpha, and a drop shadow
   under each logo. Under "one accent, one place" that is four things competing
   for the role of accent, and the accent that should win is the gold rule under
   each heading — which is kept.

   The fill is `--customer-primary` — the brand maroon this footer has been since
   :712, the `theme-color` every customer page ships, and the same tone the
   gradient it replaces spent 48% of its length on. An earlier pass flattened it
   to `#3d0808` instead, on the reasoning that the darkest stop of a gradient is
   the safest single value to pick out of it; over a full-width band that read as
   near-black and the owner rightly called it unprofessional. The three maroons
   are a ladder, not interchangeable shades: `--customer-primary` (#8b0000) is a
   resting surface, `--customer-primary-strong` (#5f0d0d) is type and button
   rest, and #3d0808 is a *pressed or hovered* state only. Nothing at rest on
   this page should be wearing a hover colour.

   `--customer-wash` puts a hint of the old diagonal back over that flat maroon —
   one gradient, two stops, ±10% and 7%, no radial and no grid.

   §9.3 update — the band is `--customer-wine` (#6d2233) now, not
   `--customer-primary` (#8b0000). Same family, a step towards red-violet and a
   step down in saturation: the gold heading rules and the cream type both gain
   contrast against it instead of sinking, which is what "pleasing and fresh"
   asks for on a band this large. The ladder rule is unchanged — hover and press
   still come from #3d0808, and nothing at rest wears a hover colour. */
.site-footer {
  position: relative;
  overflow: hidden;
  background-color: var(--customer-wine);
  background-image:
    radial-gradient(circle at 16% 0%, rgba(241, 237, 18, 0.16), transparent 18rem),
    linear-gradient(145deg, #3f0707 0%, #7a0000 48%, #9e1414 100%);
  /* Overriding the 4px `#eef224` slab from the base rule at :6688. Three gold
     rules under three headings plus a gold bar spanning the whole footer is the
     accent spent four times; the heading rules are the ones that mark structure,
     so they are what stays. The footer already separates from the band above it
     by the largest tone step on the page. */
  border-top: none;
}

/* Subtle engineering grid from the reference footer; no layout changes. */
.site-footer::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(247, 242, 236, 0.06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(247, 242, 236, 0.06) 1px, transparent 1px);
  background-size: 38px 38px;
  opacity: 0.55;
  pointer-events: none;
}

.footer-container,
.footer-bottom {
  position: relative;
  z-index: 1;
}

.footer-container {
  display: grid;
  /* minmax(0, …) floors, not 260px/180px. The old floors summed to 800px plus
     three gaps, so between 901px (where the two-column phone layout stops
     applying) and ~1010px the four tracks were wider than the container and
     the contact column spilled past the clip edge — measured 938px against a
     917px viewport on a 932x430 landscape iPhone, with the address text cut
     off. Above 1010px there was free space to distribute, so the fr ratios
     resolve exactly as before and desktop is unchanged. */
  grid-template-columns: minmax(0, 1.45fr) repeat(3, minmax(0, 1fr));
  gap: clamp(28px, 4vw, 58px);
}

.footer-logo {
  box-shadow: none;
}

.footer-heading {
  position: relative;
  padding-bottom: 11px;
}

.footer-heading::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 42px;
  height: 3px;
  border-radius: 999px;
  background: var(--customer-gold);
}

.footer-menu a,
.footer-link {
  display: inline-flex;
  color: rgba(247, 242, 236, 0.88);
}

.footer-menu a:hover,
.footer-link:hover {
  color: var(--customer-gold);
}

/* A hairline under every link row, per the owner's reference footer.

   The rule is carried by the `li`, not by the `a`: an inline-flex anchor is only
   as wide as its own text, so a border there would have drawn five ragged
   underlines instead of one aligned column of separators. `:last-child` opts out
   so a list never ends on a dangling rule, and the padding is what keeps the
   line clear of the descenders — the existing `margin-bottom` at :15268 then
   spaces the next row off that line.

   `.footer-container`'s grid, gaps and minmax(0, …) floors are untouched: the
   landscape-iPhone overflow recorded there is still the reason they exist. */
.footer-menu li,
.contact-list li {
  padding-bottom: 9px;
  border-bottom: 1px solid var(--customer-wine-line);
}

.footer-menu li:last-child,
.contact-list li:last-child {
  padding-bottom: 0;
  border-bottom: 0;
}

/* Business Hours has no list to divide, so its two lines get the same treatment
   by hand — otherwise that one column reads as the odd one out. */
.footer-col .footer-text {
  padding-bottom: 9px;
  border-bottom: 1px solid var(--customer-wine-line);
}

.footer-col .footer-text:last-of-type {
  padding-bottom: 0;
  border-bottom: 0;
}

.footer-line {
  background: var(--customer-wine-line);
}

.footer-bottom p {
  color: rgba(247, 242, 236, 0.74);
}

/* Profile dropdown.

   A menu is not a hero. This one was carrying a 28px radius, a cream diagonal
   gradient, a 70px bloom, an inset highlight line and a 20px backdrop blur — one
   panel spending more on presentation than the page it sits over. It is now a
   plain paper sheet on one hairline with one shadow, which is also what makes it
   read as the same object as the dialogs it opens. */
.profile-popup {
  width: min(390px, calc(100vw - 32px));
  padding: 14px;
  border: 1px solid var(--apt-line-warm);
  border-radius: var(--apt-radius);
  background: var(--customer-paper);
  box-shadow: 0 14px 34px rgba(45, 12, 12, 0.16);
}

.profile-popup::before {
  border-color: var(--apt-line-warm);
  background: var(--customer-paper);
}

.popup-profile-icon {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  /* Was `…#9e1414 52%, #c68317 100%` — that third stop is an orange that exists
     nowhere else in the palette, so the avatar was quietly introducing a fourth
     brand colour. One maroon plus the shared wash keeps the dimension the ramp
     was there for without the extra hue. Not a button, so the wash stays. */
  background-color: var(--customer-primary-strong);
  background-image: var(--customer-wash);
  color: var(--customer-paper-sink);
  font-family: "Montserrat", sans-serif;
  font-size: 20px;
  font-weight: 900;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  box-shadow: none;
  flex-shrink: 0;
}

.popup-profile-meta {
  min-width: 0;
  flex: 1;
}

.popup-identity {
  width: 100%;
  min-width: 0;
  font-family: "Montserrat", sans-serif;
  font-weight: 800;
  color: var(--customer-wine);
  font-size: 15px;
  line-height: 1.35;
  margin: 0;
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  overflow-wrap: anywhere;
  word-break: normal;
}

.popup-identity.is-long {
  font-size: 13px;
}

.popup-identity.is-very-long {
  font-size: 12px;
}

/* A menu row, not an action button: it keeps the panel's own 6px so it reads as
   a list item inside the popup. The two hero pills are the reference for things
   that *do* something (Log Out below is one); rows that navigate are not. */
.profile-popup-link {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: var(--ux-tap);
  padding: 12px 14px;
  border-radius: var(--apt-radius-sm);
  background: var(--customer-paper);
  border: 1px solid var(--apt-line) !important;
  color: var(--apt-body);
  font-family: "Montserrat", sans-serif;
  font-size: 15px;
  font-weight: 700;
  text-decoration: none;
  margin-bottom: 8px;
  box-shadow: none;
  /* Was `all 0.2s ease`, which also put a 200ms ramp on the press scale below
     and made the click feel late. */
  transition:
    background-color 0.18s ease,
    border-color 0.18s ease,
    color 0.18s ease;
}

.profile-popup-link i {
  color: var(--customer-wine);
  font-size: 16px;
}

.profile-popup-link:hover {
  background: var(--apt-panel);
  border-color: var(--apt-panel-edge) !important;
  color: var(--customer-wine-hover);
  transform: none;
}

.profile-popup-link:active {
  transform: scale(0.97);
}

/* Same fill, same shadow, same radius as `.ux-dlg__btn--danger`, so the row that
   asks to log out and the button that confirms it are visibly one control. Flat
   #a51919 now, not a 180deg ramp: no button on the customer site carries a
   gradient any more. */
.popup-logout {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 51px;
  padding: 15px 20px;
  border-radius: var(--ux-dlg-radius, 8px);
  background: var(--customer-wine);
  color: var(--customer-paper-sink);
  font-family: "Montserrat", sans-serif;
  font-size: 14.5px;
  font-weight: 800;
  border: none;
  cursor: pointer;
  box-shadow: 0 12px 24px rgba(133, 19, 19, 0.32);
  transition:
    background 0.16s ease,
    transform 0.1s ease;
  margin-top: 12px;
}

.popup-logout:hover {
  background: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  box-shadow: 0 12px 24px rgba(133, 19, 19, 0.32);
  transform: none;
}

.popup-logout:active {
  background: var(--customer-wine-hover);
  box-shadow: 0 12px 24px rgba(133, 19, 19, 0.32);
  transform: scale(0.97);
}

.popup-logout:focus-visible {
  outline: 3px solid rgba(241, 237, 18, 0.55);
  outline-offset: 2px;
}

/* Change Password / Set Password triggers. Both live inside a `ux-dlg__foot`,
   so the gold `--ux-dlg__btn--primary` recipe at (0,3,0) already owns their
   fill, radius, height and press. Only the geometry the shell does not set is
   kept here; the maroon fill and 18px radius that used to sit in this rule were
   already dead, and leaving dead declarations behind is how a file starts lying
   about what it ships. */
.change-password-trigger-btn,
.change-password-submit-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

/* Guest login/signup prompts: darker fill on hover, scale on press, and the
   resting shadow repeated verbatim so nothing lifts. `#d9d20d` is the same darker
   gold the dialog primary uses, so the dropdown pill and the dialog pill now
   darken to the identical value. `background-color`, not the shorthand — the
   shorthand is what would have reset `background-image`, and it stays split even
   though the wash is gone from :9585 so the two declarations keep matching.
   `.guest-access-btn` rides along for completeness only — the guest access
   dialog gives those two anchors `ux-dlg__btn--primary` / `--ghost`, and those
   (0,3,0) rules win over everything here; since :9585 moved to gold, the loser
   and the winner finally agree. */
.guest-auth-login:hover,
.guest-access-btn.login:hover {
  background-color: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  box-shadow: 0 10px 22px rgba(128, 116, 14, 0.24);
}

.guest-auth-login:active,
.guest-access-btn.login:active {
  background-color: var(--customer-wine-active);
  border-color: var(--customer-wine-active);
  transform: scale(0.97);
}

/* `#f2dede` and the shadow repeated verbatim are the dialog ghost's own hover at
   :17973; the hairline darkens to the solid maroon there too, so it does here.
   The border was the last thing that still separated the two — it used to hold
   at 32% alpha while the dialog's went solid, which on a 1.5px edge is a visible
   difference between two buttons that share every other value. */
.guest-auth-signup:hover,
.guest-access-btn.signup:hover {
  background: #f2dede;
  border-color: var(--customer-wine-hover);
  color: var(--customer-wine-hover);
  box-shadow: 0 6px 16px rgba(95, 13, 13, 0.08);
}

/* `:active` repeats the hover look on purpose: a finger never produces `:hover`,
   so without this a tap on a phone would darken nothing and only scale. */
.guest-auth-signup:active,
.guest-access-btn.signup:active {
  background: #f2dede;
  border-color: var(--customer-wine-hover);
  color: var(--customer-wine-hover);
  box-shadow: 0 6px 16px rgba(95, 13, 13, 0.08);
  transform: scale(0.97);
}

.guest-auth-btn:active,
.guest-access-btn:active {
  transform: scale(0.97);
}

/* Maroon ring, not the gold one: both of these sit on the white card, where gold
   at 55% alpha is very nearly invisible. */
.guest-auth-btn:focus-visible {
  outline: 3px solid rgba(107, 32, 43, 0.45);
  outline-offset: 2px;
}

.guest-access-card {
  border-radius: var(--apt-radius);
  border-color: var(--apt-line-warm);
  color: var(--customer-wine);
}

/* My Account modal */
.customer-modal-overlay {
  background: var(--ux-dlg-scrim);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

/* Every declaration this rule used to carry — the 32px radius, the white→cream
   diagonal over a gold radial, the double shadow, the 580px cap — was already
   dead: `main.js` builds this section as `.customer-modal.ux-dlg__card`, and the
   shell's `:is(.ux-dlg, …) .ux-dlg__card` selector is (1,2,0) against this rule's
   (0,3,0). Only the 20px backdrop blur was still live, on a card that is fully
   opaque — a blur behind an opaque surface is pure cost with nothing to show for
   it. Keeping a dead block around is how a stylesheet starts lying about what it
   ships, so what is left is the one thing not already set upstream. */
.customer-modal,
.customer-modal-overlay.show .customer-modal {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.customer-modal-overlay.show .customer-modal {
  transform: translateY(0) scale(1);
}

.customer-modal-title {
  color: var(--customer-wine-hover);
  font-family: "Montserrat", sans-serif;
  font-weight: 900;
  letter-spacing: -0.035em;
}

.customer-modal-close,
.guest-access-close,
.customer-orders-close {
  border-radius: 50%;
  background: rgba(150, 52, 73, 0.08);
  color: var(--customer-wine);
  border: 1px solid rgba(150, 52, 73, 0.16);
  transition: all 0.2s ease;
}

.customer-modal-close:hover,
.guest-access-close:hover,
.customer-orders-close:hover {
  background: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  border-color: var(--customer-wine-hover);
}

/* My Account body. The dialog shell (head, badge, eyebrow, close, footer pill)
   already comes from `ux-dlg`; this is the panel inside it, which was still
   speaking the old language. An inset panel inside a dialog needs tone, not
   elevation — the dialog is already the elevated thing — so the shadow goes and
   the cream fill does the separating. */
.customer-card {
  border: 1px solid var(--apt-panel-edge);
  border-radius: var(--apt-radius);
  background: var(--apt-panel);
  box-shadow: none;
  padding: 16px;
}

.profile-header-avatar {
  display: flex;
  align-items: center;
  gap: 18px;
  padding-bottom: 18px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--apt-line);
}

.user-avatar-initial {
  width: 54px;
  height: 54px;
  border-radius: 50%;
  /* Same off-palette `#c68317` third stop as the dropdown avatar had, and the
     same replacement: one maroon under the shared wash. */
  background-color: var(--customer-primary-strong);
  background-image: var(--customer-wash);
  color: var(--customer-paper-sink);
  font-family: "Montserrat", sans-serif;
  font-size: 24px;
  font-weight: 900;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: none;
  border: 2px solid var(--customer-paper);
  flex-shrink: 0;
}

.user-avatar-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.user-meta-name {
  font-family: "Montserrat", sans-serif;
  font-size: 20px;
  font-weight: 800;
  color: var(--customer-wine);
  margin: 0;
}

.user-meta-email {
  font-size: 14px;
  color: var(--apt-muted);
  font-weight: 600;
}

.profile-details-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
}

.profile-detail-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 14px;
  padding: 12px 14px;
  border-radius: var(--apt-radius-sm);
  background: var(--customer-paper);
  border: 1px solid var(--apt-line);
}

/* The same label voice as the appointment review rows: small, uppercase, and in
   the gold-ink label colour rather than a second grey. */
.detail-label {
  font-size: 11px;
  font-weight: 800;
  color: var(--apt-gold-label);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.detail-val {
  font-size: 14px;
  font-weight: 700;
  color: var(--apt-body);
  text-align: right;
  overflow-wrap: anywhere;
}

/* My Orders drawer */
.customer-orders-overlay {
  background: var(--ux-dlg-scrim);
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
}

.customer-orders-modal {
  width: min(790px, 96vw);
  padding: 24px;
  border-left: 1px solid rgba(107, 32, 43, 0.12);
  background:
    radial-gradient(
      circle at 100% 0%,
      rgba(241, 237, 18, 0.13),
      transparent 15rem
    ),
    linear-gradient(180deg, var(--customer-paper) 0%, #fffafa 100%);
  box-shadow: -30px 0 70px rgba(15, 23, 42, 0.26);
}

.customer-orders-title {
  color: var(--customer-primary);
  font-weight: 900;
}

.customer-orders-tabs {
  padding: 6px;
  border: 1px solid rgba(107, 32, 43, 0.1);
  border-radius: 999px;
  background: #fff6f6;
}

.customer-orders-tab {
  border-color: transparent;
  background: transparent;
}

.customer-orders-tab:hover {
  background: rgba(247, 242, 236, 0.82);
}

.customer-orders-tab.active {
  background: linear-gradient(135deg, var(--customer-primary), var(--customer-wine-light));
  border-color: transparent;
  box-shadow: 0 10px 22px rgba(128, 0, 0, 0.18);
}

.customer-orders-viewport,
.customer-order-card,
.customer-order-detail-modal,
.customer-order-detail-chip,
.customer-order-detail-items,
.customer-order-detail-fulfillment,
.customer-order-detail-logistics,
.customer-order-detail-map-wrap,
.customer-order-detail-timeline {
  border-color: rgba(107, 32, 43, 0.1);
}

.customer-orders-viewport {
  border-radius: 18px;
  background: #fff8f8;
}

.customer-order-card {
  border-radius: 16px;
  box-shadow: 0 12px 28px rgba(65, 16, 16, 0.06);
  transition:
    transform 0.18s ease,
    box-shadow 0.18s ease,
    border-color 0.18s ease;
}

.customer-order-card:hover {
  transform: translateY(-1px);
  border-color: rgba(107, 32, 43, 0.2);
  box-shadow: 0 18px 34px rgba(65, 16, 16, 0.1);
}

.customer-order-price,
.customer-order-logistics-link,
.customer-order-map-actions a {
  color: var(--customer-wine);
}

.customer-orders-empty {
  border-color: rgba(107, 32, 43, 0.15);
  background: var(--customer-paper);
}

@media (max-width: 900px) {
  .site-header {
    min-height: 70px;
    padding: 10px 14px;
  }

  .hero-section {
    min-height: calc(100vh - 70px);
    padding: 44px 18px 70px;
  }

  .hero-container {
    text-align: center;
  }

  .hero-content-left {
    max-width: 100%;
  }

  .hero-graphic {
    width: min(78vw, 440px);
  }

  .footer-container {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "brand brand"
      "quick hours"
      "contact contact";
  }

  .customer-orders-modal {
    width: 100vw;
    padding: 16px;
  }

  .customer-orders-tabs {
    border-radius: 18px;
  }
}

@media (max-width: 560px) {
  .hero-buttons {
    width: 100%;
    flex-direction: column;
  }

  .btn-browse,
  .btn-appointment {
    width: 100%;
    padding-inline: 18px;
  }

  /* Two columns all the way down. The single-column fallback that used to live
     here stacked all four blocks, which is what made the footer 893px tall at
     390px wide and 915px at 320px — taller than the phone screen holding it.
     minmax(0, 1fr) lets Quick Links and Business Hours keep sharing a row even
     when the text is wider than the track. */
  .footer-container {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-areas:
      "brand brand"
      "quick hours"
      "contact contact";
  }

  .customer-modal,
  .customer-modal-overlay.show .customer-modal {
    padding: 24px 18px;
    border-radius: 24px;
    width: min(94vw, 480px);
  }
}

@media (max-width: 768px) {
  .services-grid,
  .shop-grid,
  .contact-grid {
    grid-template-columns: 1fr !important;
    gap: 20px !important;
  }

  .about-container,
  .vision-container,
  .mission-container {
    padding: 28px 20px;
    border-radius: 24px;
  }

  .products-toolbar .toolbar-container {
    flex-direction: column;
    gap: 12px;
  }

  .contact-form-grid {
    grid-template-columns: 1fr;
    gap: 14px;
  }

  .lightbox-box {
    padding: 16px;
    border-radius: var(--ux-dlg-radius);
  }

  .lightbox-box img {
    max-width: 92vw;
    max-height: 60vh;
  }

  .lightbox-box video {
    max-width: 92vw;
    max-height: 60vh;
    width: 92vw;
  }

  .lightbox-close-btn {
    top: -10px;
    right: -10px;
    width: 36px;
    height: 36px;
    font-size: 20px;
  }
}

@media (max-width: 480px) {
  .hero-title {
    font-size: 32px !important;
  }

  .contact-title {
    font-size: 28px !important;
  }

  .contact-subtitle {
    font-size: 22px !important;
  }

  .apt-card,
  .contact-info-card,
  .contact-form-card {
    padding: 22px 16px !important;
    border-radius: var(--ux-card-radius) !important;
  }
}

/* Appointment controls: solid colors with simple hover and press feedback. */
#appointmentFlow button:not(:disabled),
#aptPrivacyModal button:not(:disabled),
#aptConfirmModal button:not(:disabled),
#aptLeaveConfirmModal button:not(:disabled),
#orderSuccessModal button:not(:disabled),
#successAppointmentModal button:not(:disabled) {
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color 0.15s ease,
    border-color 0.15s ease,
    color 0.15s ease,
    transform 0.1s ease;
}

#appointmentFlow .apt-btn,
#aptPrivacyModal .apt-btn,
#aptConfirmModal .apt-btn,
#aptLeaveConfirmModal .apt-btn,
#orderSuccessModal .apt-btn,
#successAppointmentModal .apt-btn,
#appointmentFlow button:not(:disabled):hover,
#aptPrivacyModal button:not(:disabled):hover,
#aptConfirmModal button:not(:disabled):hover,
#orderSuccessModal button:not(:disabled):hover,
#successAppointmentModal button:not(:disabled):hover,
#appointmentFlow button:not(:disabled):active,
#aptPrivacyModal button:not(:disabled):active,
#aptConfirmModal button:not(:disabled):active,
#aptLeaveConfirmModal button:not(:disabled):active,
#orderSuccessModal button:not(:disabled):active,
#successAppointmentModal button:not(:disabled):active {
  box-shadow: none;
}

#appointmentFlow button:not(:disabled):hover,
#aptPrivacyModal button:not(:disabled):hover,
#aptConfirmModal button:not(:disabled):hover,
#aptLeaveConfirmModal button:not(:disabled):hover,
#orderSuccessModal button:not(:disabled):hover,
#successAppointmentModal button:not(:disabled):hover {
  transform: none;
}

#appointmentFlow button:not(:disabled):active,
#aptPrivacyModal button:not(:disabled):active,
#aptConfirmModal button:not(:disabled):active,
#aptLeaveConfirmModal button:not(:disabled):active,
#orderSuccessModal button:not(:disabled):active,
#successAppointmentModal button:not(:disabled):active {
  transform: scale(0.97);
}

#appointmentFlow .apt-btn-blue,
#aptPrivacyModal .apt-btn-blue,
#aptConfirmModal .apt-btn-blue,
#aptLeaveConfirmModal .apt-btn-blue,
#orderSuccessModal .apt-btn-blue,
#successAppointmentModal .apt-btn-blue {
  background: #eef224; /* solid flat yellow — no gradient */
  background-image: none;
  border: 1px solid #eef224;
  color: #3d0808; /* dark maroon ink */
}

#appointmentFlow .apt-btn-blue:hover,
#aptPrivacyModal .apt-btn-blue:hover,
#aptConfirmModal .apt-btn-blue:hover,
#aptLeaveConfirmModal .apt-btn-blue:hover,
#orderSuccessModal .apt-btn-blue:hover,
#successAppointmentModal .apt-btn-blue:hover {
  background: #c8cc00; /* darker yellow — no gradient */
  background-image: none;
  border-color: #c8cc00;
  color: #3d0808;
}

#appointmentFlow .apt-btn-blue:active,
#aptPrivacyModal .apt-btn-blue:active,
#aptConfirmModal .apt-btn-blue:active,
#aptLeaveConfirmModal .apt-btn-blue:active,
#orderSuccessModal .apt-btn-blue:active,
#successAppointmentModal .apt-btn-blue:active {
  background: #b0b400; /* even darker yellow on press */
  background-image: none;
  border-color: #b0b400;
  color: #3d0808;
}

/* Back buttons stay outlined against the maroon appointment background. */
#appointmentFlow .apt-back-btn,
#appointmentFlow .apt-btn-back {
  background: rgba(45, 5, 5, 0.2);
  background-image: none;
  border: 2px solid rgba(247, 242, 236, 0.8);
  color: #f7f2ec;
  box-shadow: none;
}

#appointmentFlow .apt-back-btn:hover,
#appointmentFlow .apt-btn-back:hover {
  background: #f7f2ec; /* cream fill — not pure white */
  background-image: none;
  border-color: #f7f2ec;
  color: #3d0808; /* dark maroon text */
}

#appointmentFlow .apt-back-btn:active,
#appointmentFlow .apt-btn-back:active {
  background: #efe6da; /* slightly darker cream on press */
  background-image: none;
  border-color: #efe6da;
  color: #3d0808;
}

#appointmentFlow .apt-btn-outline {
  box-shadow: none;
}

#appointmentFlow .apt-btn-outline:hover,
#appointmentFlow .apt-btn-outline:active {
  background: #f7f2ec; /* cream fill — not pure white */
  background-image: none;
  border-color: #f7f2ec;
  color: #3d0808;
}

#aptPrivacyModal .apt-btn-cancel,
#aptConfirmModal .apt-btn-cancel,
#aptLeaveConfirmModal .apt-btn-cancel {
  background: var(--customer-wine);
  background-image: none;
  border: 1px solid var(--customer-wine);
}

#aptPrivacyModal .apt-btn-cancel:hover,
#aptConfirmModal .apt-btn-cancel:hover,
#aptLeaveConfirmModal .apt-btn-cancel:hover {
  background: #3d0808;
  background-image: none;
  border-color: #3d0808;
}

#aptPrivacyModal .apt-btn-cancel:active,
#aptConfirmModal .apt-btn-cancel:active,
#aptLeaveConfirmModal .apt-btn-cancel:active {
  background: #2c0505;
  background-image: none;
  border-color: #2c0505;
}

/* Keep the customer announcement bell level on hover on every page. */
.announcement-bell:hover {
  transform: none;
}

/* Branded guest account access in the shared customer navbar. */
.user-profile.guest-profile-host,
.user-profile.guest-profile-host:hover {
  display: block;
  width: auto;
  min-width: 0;
  height: auto;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.guest-sign-in-trigger {
  position: relative;
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) 8px;
  align-items: center;
  column-gap: 8px;
  width: 128px;
  min-width: 128px;
  height: 46px;
  padding: 5px 10px 5px 6px;
  overflow: hidden;
  /* The signed-out twin of the avatar button, so it is built from the three
     things the rest of the site now uses: one paper surface, one maroon
     hairline (the popup's own), one small shadow. What went: a three-stop cream
     gradient, an inset white top line, a 22px bloom, and a `::before` ring in
     rgba(198,131,23,…) — an orange that exists nowhere else in the palette,
     the same fourth-brand-colour leak the avatar had. */
  border: 1px solid rgba(107, 32, 43, 0.16);
  border-radius: var(--apt-radius);
  background: var(--customer-paper);
  color: var(--customer-wine);
  box-shadow: 0 2px 6px rgba(45, 12, 12, 0.08);
  cursor: pointer;
  font-family: "Montserrat", sans-serif;
  isolation: isolate;
  /* `box-shadow` is off the list because the shadow no longer changes in any
     state — the fill is the whole hover. */
  transition:
    background-color 0.18s ease,
    border-color 0.18s ease,
    color 0.18s ease,
    transform 0.08s ease;
}

.guest-sign-in-mark {
  position: relative;
  display: grid;
  width: 34px;
  height: 34px;
  place-items: center;
  border: 0;
  border-radius: var(--apt-radius-sm);
  background: var(--apt-head);
  color: var(--customer-paper-sink);
  box-shadow: none;
  font-size: 0.78rem;
  transition:
    background-color 0.18s ease,
    color 0.18s ease;
}

.guest-sign-in-status {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 10px;
  height: 10px;
  border: 2px solid var(--customer-paper);
  border-radius: 50%;
  background: var(--customer-gold);
  box-shadow: none;
}

.guest-sign-in-copy {
  display: grid;
  min-width: 0;
  gap: 2px;
  text-align: left;
}

.guest-sign-in-kicker,
.guest-sign-in-label {
  display: block;
  overflow: hidden;
  line-height: 1;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.guest-sign-in-kicker {
  color: var(--apt-muted);
  font-size: 0.46rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.guest-sign-in-label {
  color: var(--customer-wine);
  font-size: 0.78rem;
  font-weight: 900;
  letter-spacing: -0.02em;
}

.guest-sign-in-chevron {
  color: var(--apt-muted);
  font-size: 0.56rem;
  transition: transform 0.18s ease;
}

/* Darker fill only — the shadow is repeated verbatim so the control never
   appears to lift. */
.guest-sign-in-trigger:hover,
.guest-sign-in-trigger.is-open {
  border-color: var(--customer-primary-strong);
  background: var(--customer-primary-strong);
  color: var(--customer-paper-sink);
  box-shadow: 0 2px 6px rgba(45, 12, 12, 0.08);
  transform: none;
}

.guest-sign-in-trigger:hover .guest-sign-in-mark,
.guest-sign-in-trigger.is-open .guest-sign-in-mark {
  background: rgba(247, 242, 236, 0.14);
  color: var(--customer-paper-sink);
}

.guest-sign-in-trigger:hover .guest-sign-in-kicker,
.guest-sign-in-trigger.is-open .guest-sign-in-kicker {
  color: var(--apt-gold-eyebrow);
}

.guest-sign-in-trigger:hover .guest-sign-in-label,
.guest-sign-in-trigger:hover .guest-sign-in-chevron,
.guest-sign-in-trigger.is-open .guest-sign-in-label,
.guest-sign-in-trigger.is-open .guest-sign-in-chevron {
  color: var(--customer-paper-sink);
}

.guest-sign-in-trigger.is-open .guest-sign-in-chevron {
  transform: rotate(180deg);
}

.guest-sign-in-trigger:active {
  border-color: #3d0808;
  background: #3d0808;
  transform: scale(0.97);
}

/* A ring, not a second shadow. Maroon rather than the gold used elsewhere
   because this control rests on the white navbar, where the gold ring is very
   nearly invisible — the same reason the signed-in menu rows focus in maroon. */
.guest-sign-in-trigger:focus-visible {
  outline: 3px solid rgba(107, 32, 43, 0.45);
  outline-offset: 2px;
}

/* -- The signed-out dropdown ----------------------------------------------
   Same object as the signed-in menu in a different state, so it carries the
   same shell: the dialog band across the top, the same faint ring in it, the
   same badge, the same caret, one hairline, one shadow — and now the same
   344px width, which is why this is scoped through `.user-profile` the way the
   signed-in rule is. At (0,3,0) it beats both the `.profile-popup,
   .guest-profile-popup { width: min(390px, …) }` pair further down this file and
   responsive.css's single-class arms, while the phone block's
   `#guestProfilePopup` rules still win on padding.
   It keeps a padded body (blurb, two benefit chips, two buttons) where the
   signed-in menu is full-bleed rows, and 17px is the gutter §8 gave every
   dropdown part. What went: a cream diagonal wash on the card, a gold radial
   burst in the band, and an 11px-radius language that matched nothing else. */
.user-profile .profile-popup.guest-profile-popup {
  width: min(344px, calc(100vw - 24px));
  max-width: calc(100vw - 24px);
  padding: 17px;
  border-color: rgba(107, 32, 43, 0.16);
  border-radius: var(--ux-dlg-radius);
  background: var(--customer-paper);
  box-shadow:
    0 26px 60px rgba(45, 12, 12, 0.26),
    0 2px 6px rgba(45, 12, 12, 0.08);
}

/* The caret is cut by the shared rule in the navbar-menu block below, which
   now covers both states — nothing left to set here. */

.guest-popup-header {
  position: relative;
  margin: -17px -17px 15px;
  padding: 15px 17px 16px;
  overflow: hidden;
  border-radius: 7px 7px 0 0;
  background: var(--ux-dlg-band);
}

/* The same faint ring the dialog bands and the signed-in menu carry, at the
   same numbers — this is the one decoration the band is allowed. */
.guest-popup-header::after {
  content: "";
  position: absolute;
  right: -34px;
  bottom: -72px;
  width: 132px;
  height: 132px;
  border: 1px solid rgba(241, 237, 18, 0.24);
  border-radius: 50%;
  box-shadow: 0 0 0 16px rgba(241, 237, 18, 0.05);
  pointer-events: none;
}

/* No `.guest-popup-icon` rule here on purpose: the badge is now the one gold
   disc `.profile-popup .popup-profile-icon` paints for both dropdowns, so the
   signed-out and signed-in menus cannot drift apart. It used to override it to a
   translucent white square with a gold-tinted ring. */

.guest-popup-meta {
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}

.guest-popup-eyebrow {
  color: var(--ux-dlg-eyebrow);
  font-size: 0.58rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.guest-profile-popup .popup-identity {
  color: var(--customer-paper-sink);
  font-size: 0.9rem;
  font-weight: 850;
}

.guest-profile-popup .guest-popup-copy {
  margin: 0 0 12px;
  color: var(--apt-body);
  font-size: 0.78rem;
  line-height: 1.55;
}

.guest-popup-benefits {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 14px;
}

/* The same cream panel on the same cream edge every inset block in the
   appointment flow and My Account uses. Was rgba(255,247,232,…) on an orange
   hairline with brown ink — three values off the palette in one chip. */
.guest-popup-benefits span {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 6px;
  padding: 8px 9px;
  border: 1px solid var(--apt-panel-edge);
  border-radius: var(--apt-radius-sm);
  background: var(--apt-panel);
  color: var(--apt-body);
  font-size: 0.66rem;
  font-weight: 750;
  line-height: 1.25;
}

.guest-popup-benefits i {
  flex-shrink: 0;
  color: var(--customer-wine);
  font-size: 0.72rem;
}

.guest-profile-popup .guest-auth-stack {
  gap: 10px;
}

/* Everything these four rules used to set — a 14px radius, an 850 weight, a
   lighter maroon fill, a cold grey hover — is now the shared `.guest-auth-*`
   recipe, so only the dropdown's own side padding is left. */
.guest-profile-popup .guest-auth-btn {
  padding: 0 18px;
}

.guest-auth-separator {
  display: flex;
  align-items: center;
  gap: 9px;
  color: var(--apt-muted);
  font-size: 0.61rem;
  font-weight: 750;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.guest-auth-separator::before,
.guest-auth-separator::after {
  content: "";
  height: 1px;
  flex: 1;
  background: var(--apt-line);
}

@media (max-width: 1120px) and (min-width: 901px) {
  .guest-sign-in-trigger {
    grid-template-columns: 30px minmax(0, 1fr) 7px;
    column-gap: 6px;
    width: 108px;
    min-width: 108px;
    padding-inline: 5px 8px;
  }

  .guest-sign-in-mark {
    width: 30px;
    height: 30px;
  }

  .guest-sign-in-kicker {
    display: none;
  }
}

@media (max-width: 900px) {
  .guest-sign-in-trigger {
    grid-template-columns: 28px minmax(0, 1fr);
    column-gap: 6px;
    width: 84px;
    min-width: 84px;
    height: 44px;
    padding: 5px 8px 5px 5px;
    border-radius: var(--apt-radius);
  }

  .guest-sign-in-mark {
    width: 28px;
    height: 28px;
    border-radius: 9px;
    font-size: 0.7rem;
  }

  .guest-sign-in-status {
    width: 9px;
    height: 9px;
  }

  .guest-sign-in-kicker,
  .guest-sign-in-chevron {
    display: none;
  }

  .guest-sign-in-label {
    font-size: 0.68rem;
  }
}

@media (max-width: 560px) {
  .guest-sign-in-trigger {
    grid-template-columns: 1fr;
    width: 64px;
    min-width: 64px;
    height: 42px;
    padding: 0 8px;
  }

  .guest-sign-in-mark {
    display: none;
  }

  .guest-sign-in-copy {
    text-align: center;
  }

  .guest-sign-in-label {
    font-size: 0.66rem;
  }
}

@media (max-width: 380px) {
  .guest-sign-in-trigger {
    width: 58px;
    min-width: 58px;
    padding-inline: 5px;
  }

  .guest-sign-in-label {
    font-size: 0.62rem;
  }

  .guest-popup-benefits {
    grid-template-columns: 1fr;
  }
}

@media (prefers-reduced-motion: reduce) {
  .guest-sign-in-trigger,
  .guest-sign-in-mark,
  .guest-sign-in-chevron {
    transition-duration: 1ms;
  }
}

/* Realtime services loading state and compact product-card actions. */
.services-load-error {
  grid-column: 1 / -1;
  padding: 50px 20px;
  color: #6d7480;
  font-weight: 700;
  text-align: center;
}

.products-page-body .product-actions {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(3px, 0.6vw, 8px);
}

.products-page-body .product-actions .action-btn {
  width: 100%;
  min-width: 0;
  min-height: 40px;
  gap: clamp(2px, 0.3vw, 4px);
  padding: 9px clamp(3px, 0.55vw, 7px);
  font-size: clamp(8.5px, 0.7vw, 11px);
  letter-spacing: 0;
}

.products-page-body .product-actions .action-btn > svg {
  width: clamp(11px, 0.9vw, 14px);
  height: clamp(11px, 0.9vw, 14px);
  flex: 0 0 auto;
}

.products-page-body .action-btn-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Clean up old duplicate badge rules */
.announcement-bell__badge[hidden] {
  display: none !important;
}

@media (max-width: 480px) {
  .products-page-body .product-actions {
    padding: 8px 7px;
    gap: 3px;
  }

  .products-page-body .product-actions .action-btn {
    min-height: 38px;
    gap: 3px;
    padding-inline: 3px;
    font-size: clamp(8px, 2.25vw, 9.5px);
  }

  .products-page-body .product-actions .action-btn > svg {
    width: 12px;
    height: 12px;
  }
}

/* =================================================================
   UNIVERSAL RESPONSIVE + COMFORT LAYER — CUSTOMER WEBSITE
   Home / Services / Products / Contact / Appointment flow.
   Goal: usable and polished from 126px up to 7680px wide, with
   mobile-first spacing, safe-area awareness, comfortable tap
   targets and zero horizontal overflow.
   This block is intentionally LAST so it resolves older conflicts.
   ================================================================= */

:root {
  --ux-gutter: clamp(12px, 4.2vw, 72px);
  --ux-gap: clamp(12px, 2.2vw, 28px);
  /* Content cards share the dialog radius so the pointy language is the same
     whether you are looking at a modal or a service card. Flat, not a clamp:
     a viewport-scaled radius is exactly the curve this pass removes. */
  --ux-card-radius: 8px;
  --ux-tap: 44px;
  --ux-safe-l: env(safe-area-inset-left, 0px);
  --ux-safe-r: env(safe-area-inset-right, 0px);
  --ux-safe-t: env(safe-area-inset-top, 0px);
  --ux-safe-b: env(safe-area-inset-bottom, 0px);
  --ux-header-h: 76px;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

html,
body {
  max-width: 100%;
}

/* Keep the existing body-level guard (it propagates to the viewport,
   so the sticky header keeps working) instead of clipping on <html>. */
body {
  overflow-x: hidden;
  min-height: 100vh;
  min-height: 100dvh;
}

img,
svg,
video,
canvas,
iframe,
table {
  max-width: 100%;
}

img,
video {
  height: auto;
}

/* Long unbreakable strings (emails, addresses, codes) must never
   push the layout sideways. */
.footer-link,
.footer-desc,
.footer-text,
.contact-link-text,
.contact-lead,
.section-text,
.vm-text,
.card-desc,
.card-title,
.product-name,
.modal-desc,
.t-value,
.customer-order-detail-item-info strong,
.announcement-modal__message {
  overflow-wrap: break-word;
  word-break: break-word;
}

/* ---- Fluidise the few remaining fixed-width offenders ---------- */
.service-card,
.services-grid .service-card {
  min-width: 0;
}

.apt-calendar-left,
.apt-time-right {
  min-width: 0;
}

.footer-col {
  min-width: 0;
}

.success-card {
  width: min(400px, calc(100vw - 32px));
  max-width: min(400px, calc(100vw - 32px));
}

.profile-popup,
.guest-profile-popup {
  width: min(390px, calc(100vw - 32px));
  max-width: calc(100vw - 32px);
}

/* The homepage "What we offer" carousel and the services carousel
   share the same classes; keep both fully fluid. */
.carousel-item {
  width: min(320px, calc(100vw - 92px));
  height: clamp(320px, 88vw, 450px);
}

.landscape-carousel {
  height: clamp(300px, 76vw, 400px);
}

.landscape-carousel .carousel-item {
  width: min(450px, calc(100vw - 92px));
  height: clamp(240px, 62vw, 320px);
}

.landscape-card .card-img-holder {
  height: clamp(120px, 32vw, 170px);
}

.carousel-wrapper {
  height: clamp(360px, 96vw, 550px);
  max-width: min(1200px, 100%);
}

.landscape-carousel.carousel-wrapper {
  height: clamp(300px, 76vw, 400px);
}

/* Product + service grids auto-fit at every viewport instead of
   hard-coded column counts. `auto-fill` keeps card proportions
   consistent even when only one or two items are returned. */
.shop-grid {
  grid-template-columns: repeat(
    auto-fill,
    minmax(min(100%, 280px), 1fr)
  ) !important;
  gap: var(--ux-gap) !important;
}

.services-grid {
  grid-template-columns: repeat(
    auto-fill,
    minmax(min(100%, 300px), 1fr)
  ) !important;
  gap: var(--ux-gap) !important;
}

/* Full-bleed viewport units are unreliable on mobile browsers. */
.hero-section {
  min-height: calc(100dvh - var(--ux-header-h));
}

.apt-container {
  min-height: 100dvh;
}

/* ux-layer-A-end */

/* ---------------------------------------------------------------
   1. HEADER / NAVIGATION — comfortable and stable on every width
   --------------------------------------------------------------- */
.site-header {
  gap: clamp(8px, 1.6vw, 20px);
  padding-left: max(var(--ux-gutter), var(--ux-safe-l));
  padding-right: max(var(--ux-gutter), var(--ux-safe-r));
  padding-top: max(10px, var(--ux-safe-t));
  padding-bottom: 10px;
}

.logo-container {
  min-width: 0;
  flex: 0 1 auto;
}

/* Older blocks in this file target `.site-header .logo-*` (two
   classes), so the responsive brand sizing must match that
   specificity to take effect below 900px. */
.site-header .logo-text {
  min-width: 0;
  max-width: min(420px, 46vw);
}

.site-header .header-emblem {
  height: clamp(28px, 6.4vw, 48px);
  flex: 0 0 auto;
}

.site-header .logo-title {
  font-size: clamp(9px, 1.55vw, 16px);
  letter-spacing: 0.3px;
}

.site-header .logo-subtitle {
  font-size: clamp(6.5px, 1vw, 10px);
  letter-spacing: 0.4px;
}

.header-right-actions {
  flex: 0 0 auto;
  gap: clamp(6px, 1.2vw, 12px);
}

/* Every interactive control in the chrome respects a comfortable
   touch size while still shrinking gracefully. The two-class
   selectors also outrank the products page's inline <style> block,
   which is parsed after main.css. */
.header-right-actions .cart-icon-container,
.header-right-actions .announcement-bell,
.header-right-actions .user-profile,
.site-header .mobile-menu-toggle,
.sidebar-header .sidebar-close-btn {
  flex: 0 0 auto;
  min-width: clamp(38px, 8.6vw, 46px);
  min-height: clamp(38px, 8.6vw, 46px);
}

.header-right-actions .cart-icon-container {
  position: relative;
  display: inline-grid;
  place-items: center;
  color: var(--customer-wine);
  /* Same box as the announcement bell below. Both badges are pinned to
     top/right -2px, so matching box sizes is what keeps the cart counter and
     the announcement counter at exactly the same height. */
  width: clamp(38px, 8.6vw, 42px);
  height: clamp(38px, 8.6vw, 42px);
}

.header-right-actions .cart-icon-container svg {
  width: clamp(22px, 5.4vw, 28px);
  height: clamp(22px, 5.4vw, 28px);
}

.header-right-actions .user-profile > svg {
  width: clamp(28px, 6.6vw, 36px);
  height: clamp(28px, 6.6vw, 36px);
}

.header-right-actions .announcement-bell {
  width: clamp(38px, 8.6vw, 42px);
  height: clamp(38px, 8.6vw, 42px);
  margin-right: 0;
}

/* Mobile drawer: comfortable rows, safe-area padding, no clipping. */
.mobile-sidebar {
  width: min(88vw, 340px);
  max-width: 340px;
  padding-bottom: var(--ux-safe-b);
}

.sidebar-header {
  padding-top: max(14px, var(--ux-safe-t));
}

.sidebar-nav {
  flex: 1;
  padding-bottom: calc(24px + var(--ux-safe-b));
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

.sidebar-nav .nav-link {
  min-height: var(--ux-tap);
  display: flex;
  align-items: center;
  font-size: 15px;
}

.sidebar-nav .nav-link::after {
  display: none;
}

/* ---------------------------------------------------------------
   2. SECTION RHYTHM — one shared fluid gutter everywhere
   --------------------------------------------------------------- */
.hero-section,
.about-section,
.vision-section,
.mission-section,
.services-preview-section,
.services-list-section,
.services-top-bar,
.products-toolbar,
.shop-section,
.contact-main-section,
.site-footer {
  padding-left: max(var(--ux-gutter), var(--ux-safe-l));
  padding-right: max(var(--ux-gutter), var(--ux-safe-r));
}

.about-section,
.vision-section,
.mission-section,
.services-preview-section {
  padding-top: clamp(40px, 7vw, 90px);
  padding-bottom: clamp(40px, 7vw, 90px);
}

.services-list-section {
  padding-top: clamp(24px, 4vw, 40px);
  padding-bottom: clamp(48px, 8vw, 95px);
}

.contact-main-section {
  padding-top: clamp(24px, 4.6vw, 60px);
  padding-bottom: clamp(40px, 7vw, 80px);
}

.shop-section {
  padding-bottom: clamp(40px, 7vw, 80px);
}

.about-container,
.vision-container,
.mission-container {
  width: 100%;
  gap: clamp(22px, 5vw, 80px);
}

.section-title {
  font-size: clamp(26px, 5.2vw, 55px);
  margin-bottom: clamp(14px, 2.4vw, 30px);
}

.section-text {
  font-size: clamp(14px, 1.55vw, 18px);
  margin-bottom: clamp(14px, 1.8vw, 25px);
}

.vm-title {
  font-size: clamp(24px, 4.6vw, 48px);
  margin-bottom: clamp(12px, 2vw, 25px);
}

.vm-text {
  font-size: clamp(15px, 2vw, 22px);
}

/* Long body copy is far easier to read left-aligned on phones. */
@media (max-width: 720px) {
  .section-text,
  .card-desc,
  .services-grid .card-desc {
    text-align: left;
  }
}

/* ux-layer-B-end */

/* ---------------------------------------------------------------
   3. HERO — balanced stacking, readable type, thumb-friendly CTAs
   --------------------------------------------------------------- */
.hero-section {
  padding-top: clamp(32px, 6vw, 92px);
  padding-bottom: clamp(40px, 6vw, 92px);
}

.hero-container {
  gap: clamp(20px, 4vw, 72px);
}

.hero-title {
  font-size: clamp(24px, 5.6vw, 74px);
  margin-bottom: clamp(18px, 3vw, 34px);
}

.hero-buttons {
  gap: clamp(10px, 1.6vw, 14px);
}

.btn-browse,
.btn-appointment {
  min-height: clamp(44px, 9vw, 56px);
  padding: clamp(11px, 1.6vw, 15px) clamp(16px, 2.6vw, 32px);
  font-size: clamp(13px, 1.5vw, 18px);
}

.hero-graphic {
  width: min(38vw, 470px);
  padding: clamp(8px, 1.4vw, 16px);
  border-width: clamp(3px, 0.7vw, 8px);
}

.scroll-indicator {
  font-size: clamp(11px, 1.3vw, 14px);
}

/* ---------------------------------------------------------------
   4. CARDS, CAROUSEL & TOOLBARS
   --------------------------------------------------------------- */
.services-list-header {
  margin-bottom: clamp(20px, 3.4vw, 36px);
}

.services-list-header h2 {
  font-size: clamp(1.4rem, 4.6vw, 2.8rem);
}

.services-list-header p {
  font-size: clamp(0.86rem, 1.5vw, 1.05rem);
}

.services-grid .card-content {
  padding: clamp(14px, 2.2vw, 22px);
  gap: clamp(8px, 1.2vw, 12px);
}

.services-grid .card-title {
  font-size: clamp(1rem, 1.9vw, 1.16rem);
}

.services-grid .card-desc {
  font-size: clamp(0.83rem, 1.4vw, 0.91rem);
}

.service-card-footer {
  flex-wrap: wrap;
  gap: clamp(8px, 1.4vw, 14px);
}

.services-grid .details-btn {
  min-height: 34px;
}

.carousel-btn {
  width: clamp(38px, 8vw, 50px);
  height: clamp(38px, 8vw, 50px);
}

.carousel-btn svg {
  width: clamp(17px, 3.6vw, 24px);
  height: clamp(17px, 3.6vw, 24px);
}

.prev-btn {
  left: clamp(-2px, 0.6vw, 10px);
}

.next-btn {
  right: clamp(-2px, 0.6vw, 10px);
}

.view-all-btn {
  min-height: var(--ux-tap);
  padding: clamp(12px, 1.6vw, 16px) clamp(22px, 3.4vw, 44px);
  font-size: clamp(13px, 1.5vw, 17px);
}

/* Search + filters: comfortable row on desktop, stacked on phones.
   NOTE: the legacy <=768px rule switches `.toolbar-container` to
   `flex-direction: column`, so flex-basis on its children would be
   read as a HEIGHT. Size them with width/max-width instead. */
.toolbar-container {
  gap: clamp(10px, 1.6vw, 20px);
}

.toolbar-search {
  min-width: 0;
  width: 100%;
  max-width: 460px;
  padding: clamp(9px, 1.4vw, 12px) clamp(14px, 2vw, 22px);
  min-height: var(--ux-tap);
}

.toolbar-search .search-input,
.category-select {
  min-height: 24px;
  /* 16px prevents iOS Safari from zooming when a field is focused. */
  font-size: max(16px, 0.95rem);
}

.toolbar-actions {
  min-width: 0;
  gap: clamp(8px, 1.4vw, 15px);
}

.category-dropdown-box {
  flex: 1 1 140px;
  min-width: 0;
  display: flex;
  align-items: center;
  min-height: var(--ux-tap);
  padding: clamp(6px, 1vw, 10px) clamp(12px, 1.8vw, 18px);
}

.category-select {
  width: 100%;
}

@media (max-width: 768px) {
  .toolbar-container {
    align-items: stretch;
  }

  .toolbar-search {
    max-width: 100%;
  }

  .toolbar-actions {
    width: 100%;
  }
}

/* Product cards */
.product-info {
  padding: clamp(13px, 2vw, 22px);
}

.product-name {
  font-size: clamp(13.5px, 1.6vw, 16px);
}

.product-price {
  font-size: clamp(17px, 2.4vw, 22px);
}

.product-actions {
  padding: clamp(9px, 1.4vw, 14px);
  gap: clamp(4px, 0.8vw, 8px);
}

.action-btn {
  min-height: clamp(38px, 8vw, 42px);
}

/* ux-layer-C-end */

/* ---------------------------------------------------------------
   5. CONTACT PAGE, FORMS & FOOTER
   --------------------------------------------------------------- */
.contact-grid {
  gap: var(--ux-gap);
}

.contact-info-card,
.contact-form-card {
  padding: clamp(18px, 3.2vw, 40px);
  border-radius: var(--ux-card-radius);
}

.contact-title {
  font-size: clamp(24px, 4.6vw, 42px);
}

.contact-subtitle {
  font-size: clamp(20px, 3.6vw, 32px);
}

.contact-lead {
  font-size: clamp(14px, 1.6vw, 16px);
}

.contact-links-list {
  gap: clamp(10px, 1.6vw, 16px);
}

.contact-links-list li {
  padding: clamp(12px, 1.8vw, 18px);
  border-radius: clamp(12px, 1.8vw, 18px);
}

.contact-link-text {
  font-size: clamp(13.5px, 1.5vw, 15px);
}

.contact-form-grid {
  gap: clamp(12px, 1.8vw, 20px);
}

/* All text inputs across the customer site use >=16px so mobile
   browsers never auto-zoom on focus. */
.contact-input,
.c-input,
.search-input,
input[type="text"],
input[type="email"],
input[type="tel"],
input[type="password"],
input[type="number"],
input[type="search"],
input[type="date"],
select,
textarea {
  font-size: max(16px, 0.95rem);
}

.contact-input {
  min-height: var(--ux-tap);
  padding: clamp(11px, 1.5vw, 14px) clamp(13px, 1.8vw, 18px);
  border-radius: clamp(12px, 1.8vw, 18px);
}

.contact-textarea {
  min-height: clamp(120px, 26vw, 190px);
  resize: vertical;
}

.contact-submit-btn {
  min-height: var(--ux-tap);
  padding: clamp(12px, 1.8vw, 16px) clamp(20px, 3.4vw, 36px);
  font-size: clamp(13.5px, 1.5vw, 15px);
  border-radius: var(--apt-radius, 8px);
}

.consent-label {
  line-height: 1.5;
}

.consent-label input[type="checkbox"] {
  width: 18px;
  height: 18px;
}

/* Footer */
.site-footer {
  padding-top: clamp(36px, 6vw, 60px);
  padding-bottom: calc(20px + var(--ux-safe-b));
}

.footer-container {
  gap: clamp(22px, 3.6vw, 45px);
  margin-bottom: clamp(22px, 3.4vw, 40px);
}

.footer-logo {
  height: clamp(38px, 8vw, 50px);
}

.footer-brand {
  font-size: clamp(18px, 3vw, 26px);
}

.footer-heading {
  font-size: clamp(16px, 2.2vw, 22px);
  margin-bottom: clamp(12px, 2vw, 25px);
}

.footer-desc,
.footer-text,
.footer-menu a,
.footer-link,
.contact-list li {
  font-size: clamp(13.5px, 1.5vw, 16px);
}

.footer-menu li,
.contact-list li {
  margin-bottom: clamp(9px, 1.4vw, 15px);
}

.footer-menu a,
.footer-link {
  display: inline-block;
  min-height: 26px;
  padding-block: 2px;
}

.footer-bottom p {
  font-size: clamp(11.5px, 1.2vw, 14px);
  line-height: 1.55;
}

/* ---------------------------------------------------------------
   6. OVERLAYS, MODALS, DRAWERS — never taller than the viewport
   --------------------------------------------------------------- */
.modal-overlay,
.shop-modal-overlay,
.customer-modal-overlay,
.customer-orders-overlay,
.guest-access-modal,
.success-modal-overlay,
.apt-nested-modal,
.about-video-modal {
  padding: clamp(10px, 2.4vw, 24px);
  padding-top: max(clamp(10px, 2.4vw, 24px), var(--ux-safe-t));
  padding-bottom: max(clamp(10px, 2.4vw, 24px), var(--ux-safe-b));
  overscroll-behavior: contain;
}

.modal-box {
  max-height: min(90vh, calc(100dvh - 24px));
  border-radius: clamp(16px, 2.6vw, 32px);
}

.modal-header {
  padding: clamp(16px, 2.6vw, 28px) clamp(16px, 3vw, 36px)
    clamp(12px, 1.8vw, 18px);
}

.modal-title {
  font-size: clamp(18px, 3vw, 30px);
}

.modal-scroll-area {
  padding: clamp(16px, 2.6vw, 28px) clamp(16px, 3vw, 36px);
  -webkit-overflow-scrolling: touch;
}

/* Service-details modal internals */
.modal-desc {
  font-size: clamp(13.5px, 1.6vw, 16px);
}

.modal-subtitle {
  font-size: clamp(16px, 2.2vw, 20px);
}

.modal-columns {
  flex-wrap: wrap;
  gap: clamp(16px, 3vw, 40px);
}

.modal-col {
  flex: 1 1 min(100%, 240px);
  min-width: 0;
}

.modal-list {
  font-size: clamp(13.5px, 1.5vw, 15px);
}

.modal-actions {
  gap: clamp(10px, 1.8vw, 18px);
  padding: clamp(14px, 2.4vw, 22px) clamp(16px, 3vw, 36px);
  padding-bottom: max(clamp(14px, 2.4vw, 22px), var(--ux-safe-b));
}

.modal-btn {
  min-height: var(--ux-tap);
  flex: 1 1 auto;
  max-width: 100%;
  padding: clamp(12px, 1.8vw, 14px) clamp(18px, 3vw, 32px);
  font-size: clamp(13px, 1.5vw, 15px);
}

@media (min-width: 561px) {
  .modal-btn {
    flex: 0 1 auto;
  }
}

.feature-chips {
  gap: clamp(7px, 1.2vw, 10px);
  margin-bottom: clamp(18px, 3vw, 30px);
}

.chip {
  padding: 7px clamp(12px, 2vw, 18px);
  font-size: clamp(11.5px, 1.3vw, 13px);
}

.close-modal-btn,
.lightbox-close-btn,
.customer-modal-close,
.customer-orders-close,
.guest-access-close,
.about-video-close,
.forgot-close {
  min-width: var(--ux-tap);
  min-height: var(--ux-tap);
}

.modal-img-holder {
  height: clamp(150px, 42vw, 250px);
}

.lightbox-box {
  max-width: min(94vw, 1100px);
  max-height: min(88vh, calc(100dvh - 24px));
  padding: clamp(12px, 2vw, 24px);
}

.lightbox-box img {
  max-width: min(86vw, 1000px);
  max-height: min(64vh, calc(100dvh - 160px));
}

.lightbox-box video {
  max-width: min(86vw, 1000px);
  max-height: min(64vh, calc(100dvh - 160px));
  width: min(86vw, 1000px);
}

.shop-modal-box {
  height: min(85vh, calc(100dvh - 24px));
  max-width: min(520px, 100%);
  border-radius: clamp(16px, 2.6vw, 32px);
}

/* The checkout/cart drawer becomes a full-screen sheet at <=768px
   (legacy rule), so the overlay must not add padding there. */
@media (max-width: 768px) {
  .shop-modal-overlay {
    padding: 0;
  }

  .shop-modal-box {
    width: 100%;
    max-width: 100%;
    height: 100dvh;
    border-radius: 0;
  }

  .shop-modal-header {
    padding-top: max(18px, var(--ux-safe-t));
  }

  .shop-modal-footer {
    padding-bottom: max(16px, var(--ux-safe-b));
  }
}

.customer-orders-modal,
.customer-modal {
  max-height: min(92vh, calc(100dvh - 20px));
}

.about-video-modal-box {
  width: min(1100px, 94vw);
}

.about-full-video {
  max-height: min(82vh, calc(100dvh - 90px));
}

.about-video-holder {
  height: clamp(190px, 54vw, 460px);
}

.announcement-modal {
  padding: clamp(12px, 3vw, 22px);
}

.announcement-modal__card {
  max-height: min(90vh, calc(100dvh - 24px));
  overflow-y: auto;
}

/* ux-layer-D-end */

/* ---------------------------------------------------------------
   7. APPOINTMENT FLOW (5 steps) — the most form-heavy screen
   --------------------------------------------------------------- */
.apt-overlay {
  padding-top: var(--ux-safe-t);
  padding-bottom: var(--ux-safe-b);
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* The inline padding reads from the `--apt-pad-*` pair declared in §8.6, so the
   gutter and the safe-area inset resolve in one place — including at <=280px,
   where responsive.css redefines `--ux-gutter` to 7px and both sides follow at
   once. The safe-area insets used to be crossed here — `--ux-safe-l` sat in the
   shorthand's right slot — which put a notch's left inset on the right edge in
   landscape. §8.9 trims the block padding above 900px; the fluid inline values
   are correct at every width and are left alone. */
.apt-container {
  padding: clamp(14px, 2.6vw, 30px) var(--apt-pad-r) clamp(24px, 3vw, 30px)
    var(--apt-pad-l);
}

.apt-header-top {
  gap: clamp(8px, 1.6vw, 14px);
  margin-bottom: clamp(16px, 2.6vw, 30px);
}

.apt-back-btn {
  flex: 0 0 auto;
  width: var(--ux-tap);
  height: var(--ux-tap);
}

.apt-back-btn svg {
  width: clamp(20px, 4.6vw, 30px);
  height: clamp(20px, 4.6vw, 30px);
}

.apt-main-title {
  /* Both ends moved. The old 17px floor was the mobile complaint — at 393px the
     page title rendered smaller than its own body copy. The old 38px ceiling was
     half of the PC scroll: a 38px title carries a 47px line box, and trimming it
     to 30px is the single largest saving available above the fold. 5vw reaches
     the 30px ceiling at 600px, so tablets and up read one consistent size. */
  font-size: clamp(20px, 5vw, 30px);
}

.apt-progress-wrapper {
  gap: clamp(2px, 0.8vw, 10px);
  padding: clamp(10px, 1.8vw, 16px) clamp(8px, 2vw, 24px);
  margin-bottom: clamp(18px, 3vw, 35px);
  /* Flat 8px at every width. This layer is top-level and therefore the winning
     one for radii, so the pill has to die here — the base rule further up is
     only readable, not effective. */
  border-radius: var(--apt-radius);
}

.apt-step {
  width: clamp(46px, 12vw, 90px);
  gap: clamp(4px, 0.8vw, 8px);
}

.apt-icon {
  width: clamp(32px, 9vw, 48px);
  height: clamp(32px, 9vw, 48px);
}

.apt-icon svg {
  width: clamp(16px, 4.4vw, 24px);
  height: clamp(16px, 4.4vw, 24px);
}

.step-label {
  font-size: clamp(7px, 1.5vw, 11px);
}

.apt-step span:last-child {
  font-size: clamp(8px, 1.7vw, 12px);
  line-height: 1.2;
}

.apt-line {
  min-width: 6px;
  margin-top: clamp(22px, 5.4vw, 25px);
}

.apt-card {
  padding: clamp(14px, 2.6vw, 30px);
  border-radius: var(--ux-card-radius);
}

.apt-card-header h3 {
  font-size: clamp(15px, 2.4vw, 20px);
  gap: 8px;
}

.apt-reminders-grid {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: clamp(12px, 2vw, 20px);
}

.apt-reminder-item {
  padding: clamp(13px, 2.2vw, 20px);
  gap: clamp(10px, 1.6vw, 15px);
}

.apt-reminder-icon {
  /* 40px cap, down from 45. A numeral disc is a marker, not a button, and at
     45px it was the same size as the rail's own step circles. */
  min-width: clamp(32px, 7.4vw, 40px);
  width: clamp(32px, 7.4vw, 40px);
  height: clamp(32px, 7.4vw, 40px);
  font-size: clamp(14px, 3vw, 17px);
}

.apt-reminder-content h4 {
  font-size: clamp(14px, 2vw, 16px);
}

.apt-reminder-content p,
.apt-reminder-content ol,
.apt-reminder-content ul,
.apt-reminder-list li {
  font-size: clamp(12.5px, 1.6vw, 14px);
}

/* Form grid: 3 columns on desktop, 2 on tablets, 1 on phones.
   The `!important` is required to beat the older mobile override. */
@media (min-width: 641px) and (max-width: 900px) {
  .apt-form-grid {
    grid-template-columns: 1fr 1fr !important;
  }
}

.apt-form-grid {
  gap: clamp(12px, 1.8vw, 20px);
}

/* Section headings and the wide fields (email / notes) are declared
   with inline `grid-column: span 2|3` in the markup. Below 901px the
   grid has fewer than three tracks, so those spans would create
   implicit columns and overflow — pin them to the full row instead. */
@media (max-width: 900px) {
  .apt-form-header,
  .apt-form-grid > .apt-input-group[style*="span 3"],
  .apt-form-grid > .apt-input-group[style*="span 2"] {
    grid-column: 1 / -1 !important;
  }
}

.apt-input-group label {
  font-size: clamp(11.5px, 1.4vw, 12.5px);
}

/* Declared in this layer because two older arms (≤900px and ≤768px) re-size
   `.apt-form-header h4` at the same specificity and would otherwise put the
   17px heading back on every tablet and phone. The eyebrow has to hold at every
   width or Step 2 reads as three forms again below 900px. */
.apt-form-header h4 {
  font-size: clamp(11px, 1.4vw, 12.5px);
}

.c-input {
  min-height: var(--ux-tap);
}

.apt-footer-actions {
  flex-wrap: wrap;
  gap: clamp(10px, 1.6vw, 15px);
  /* Was an inline `margin-top: 20px` on Steps 4 and 5 only, so the button row
     sat tight under the card on Steps 1-3 and loose on 4-5. One value, all five
     steps. */
  margin-top: clamp(14px, 2.2vw, 20px);
  padding-bottom: calc(clamp(8px, 2vw, 20px) + var(--ux-safe-b));
}

.apt-btn {
  min-height: var(--ux-tap);
  padding: clamp(12px, 1.6vw, 14px) clamp(18px, 3vw, 40px);
  font-size: clamp(13px, 1.5vw, 16px);
}

/* Calendar + slots stack fluidly instead of relying on fixed mins. */
.apt-calendar-wrapper {
  gap: clamp(14px, 2.4vw, 28px);
}

.apt-calendar-left {
  flex: 1 1 320px;
}

.apt-time-right {
  flex: 1 1 240px;
}

.apt-calendar-left,
.apt-time-right {
  padding: clamp(14px, 2.2vw, 24px);
  /* Flat 8px, matching the card that contains them and the cells inside them.
     This is the winning layer for radii, so the 20px in the calendar block
     above is only documentation. */
  border-radius: var(--apt-radius);
}

.cal-navigation button {
  width: var(--ux-tap);
  height: var(--ux-tap);
  font-size: 16px;
}

.cal-days-grid {
  gap: clamp(3px, 0.9vw, 8px);
}

.cal-day-cell {
  height: auto;
  aspect-ratio: 1;
  min-height: clamp(30px, 9.6vw, 54px);
  /* Flat 8px. A month of 12px-rounded tiles reads as a grid of pills; the same
     corner as every other surface in the flow reads as ruled paper. */
  border-radius: var(--apt-radius);
  font-size: clamp(11px, 2.5vw, 16px);
}

.cal-days-header span {
  font-size: clamp(9px, 2vw, 12px);
}

.cal-legend {
  gap: clamp(8px, 1.6vw, 15px);
}

.leg-item {
  font-size: clamp(10.5px, 1.5vw, 14px);
  margin-bottom: 0;
}

.time-slot-btn {
  min-height: var(--ux-tap);
  padding: clamp(10px, 1.6vw, 12px);
  font-size: clamp(13px, 1.6vw, 15px);
}

.file-upload-wrapper {
  height: clamp(84px, 20vw, 100px);
}

/* Preview / receipt tickets */

/* `width` and not just `max-width`. `.apt-content-section` is a column flexbox,
   and the card's own `margin: 0 auto` (5716) suppresses the stretch a column
   flex item would otherwise get — so without a stated width the ticket sizes to
   fit-content. That was survivable while `.ticket-row` was a wrapping flexbox,
   whose max-content is the sum of its columns; now that the row is an `auto-fit`
   grid its max-content is one track wide, and the whole 800px card would collapse
   to about 340px on a desktop. Stating the width removes the dependency on what
   the rows happen to measure, and the 800px cap from 5715 comes back with it. */
.ticket-container {
  width: 100%;
  max-width: 800px;
}

.ticket-header {
  flex-wrap: wrap;
  gap: 10px;
  padding: clamp(16px, 2.6vw, 24px) clamp(16px, 2.8vw, 30px);
}

/* The `!important` here existed only to beat an inline `font-size: 24px` on both
   ticket headings. The inline is gone, so this is a plain declaration again. */
.ticket-no {
  font-size: clamp(17px, 3.2vw, 22px);
}

.ticket-body {
  padding: clamp(16px, 2.8vw, 30px);
}

.ticket-row {
  gap: clamp(10px, 1.8vw, 20px);
}

.t-label {
  font-size: clamp(10px, 1.2vw, 10.5px);
}

.t-value {
  font-size: clamp(13px, 1.6vw, 14.5px);
}

.success-card {
  padding: clamp(24px, 4.6vw, 40px) clamp(18px, 3.4vw, 30px);
  border-radius: var(--ux-dlg-radius);
  max-height: min(92vh, calc(100dvh - 24px));
  overflow-y: auto;
}

.success-icon {
  width: clamp(56px, 15vw, 80px);
  height: clamp(56px, 15vw, 80px);
  font-size: clamp(28px, 7.4vw, 40px);
}

.success-title {
  font-size: clamp(18px, 3.2vw, 24px);
}

.success-desc {
  font-size: clamp(13px, 1.6vw, 15px);
  margin-bottom: clamp(18px, 3vw, 30px);
}

/* ux-layer-E-end */

/* Step 5 receipt: below this width the QR stops being a rail beside the details
   and becomes a footer under them.

   Class-based now that neither of those divs is inline-styled, which is also
   what let every `!important` in this block go: `.ticket-body--split` needed one
   to beat an inline `display: flex`, and the QR column needed three to beat its
   own inline width, border and padding. The details grid needs no arm at any
   width — `.ticket-grid`'s auto-fit tracks (§8.5) drop from two columns to one
   by themselves, which is what the deleted 440px arm used to force. */
@media (max-width: 760px) {
  .ticket-body--split {
    flex-direction: column;
    gap: 16px;
  }

  #officialReceiptCard .ticket-qr {
    width: 100%;
    max-width: 220px;
    margin: 0 auto;
    padding-left: 0;
    padding-top: 16px;
    border-left: 0;
    border-top: 1px solid var(--apt-line);
  }
}

/* `.ticket-row` needs no narrow-screen arm either, for the same reason. */

/* ---------------------------------------------------------------
   8. BREAKPOINTS
   --------------------------------------------------------------- */

/* --- Tablet & below: hide desktop nav, expose the drawer -------- */
@media (max-width: 900px) {
  :root {
    --ux-header-h: 68px;
  }

  .site-header {
    min-height: 68px;
  }

  .main-nav {
    display: none;
  }

  .mobile-menu-toggle {
    display: inline-flex;
  }

  .hero-container {
    flex-direction: column;
    text-align: center;
  }

  .hero-content-right {
    order: 1;
  }

  .hero-content-left {
    order: 2;
    width: 100%;
    max-width: 100%;
    padding-right: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  .hero-graphic {
    width: min(52vw, 260px);
  }

  .hero-buttons {
    width: 100%;
    max-width: 420px;
    justify-content: center;
  }

  .btn-browse,
  .btn-appointment {
    flex: 1 1 150px;
  }

  .about-container,
  .vision-container,
  .mission-container {
    flex-direction: column;
    width: 100%;
    max-width: 100%;
    text-align: center;
  }

  .about-content-left,
  .about-content-right {
    padding-right: 0;
    width: 100%;
    justify-content: center;
  }

  .vision-content-left {
    order: 2;
  }

  .vision-content-right {
    order: 1;
  }

  /* Stacked, the photo columns are the cross axis, and the container's
     `align-items: center` sizes them to their content — which is nothing at all
     while a deck is still waiting for its photo, so the placeholder card had no
     box to paint in and collapsed to 0x0. Width comes from the container
     instead, exactly as `.about-content-*` above already takes it. What the
     photo does with that width is unchanged: `.vm-deck--vision` still caps at
     550px and `.blob-wrapper` at 480px, so nothing moves once it lands. */
  .vision-content-left,
  .mission-content-right {
    width: 100%;
  }

  .about-video-holder,
  .vision-img,
  .blob-wrapper,
  /* The deck is the box now, so it needs the centring the bare photo had. */
  .vm-deck--vision {
    margin-inline: auto;
  }

  .contact-grid {
    grid-template-columns: 1fr;
  }

  /* Consent + submit stack so the button is never squeezed.
     Both elements carry inline flex styles, hence the !important. */
  .contact-form-actions {
    flex-direction: column !important;
    align-items: stretch !important;
  }

  .contact-form-actions .consent-group {
    flex: 0 0 auto !important;
    width: 100%;
  }

  .contact-form-actions .contact-submit-btn {
    width: 100%;
    align-self: stretch !important;
  }
}

/* --- Phones ---------------------------------------------------- */
@media (max-width: 640px) {
  .footer-container {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "brand brand"
      "quick hours"
      "contact contact";
  }

  .footer-container .footer-col:nth-child(1) {
    grid-area: brand;
  }
  .footer-container .footer-col:nth-child(2) {
    grid-area: quick;
  }
  .footer-container .footer-col:nth-child(3) {
    grid-area: hours;
  }
  .footer-container .footer-col:nth-child(4) {
    grid-area: contact;
  }

  .apt-calendar-wrapper {
    flex-direction: column;
  }

  .apt-calendar-left,
  .apt-time-right {
    flex: 1 1 auto;
    width: 100%;
  }

  /* Primary action first (bottom-most = most reachable) */
  .apt-footer-actions {
    flex-direction: column-reverse;
  }

  .apt-btn {
    width: 100%;
  }

  .promotion-spotlight-card {
    flex-direction: column !important;
    text-align: center;
    padding: 15px 16px !important;
  }
}

/* --- Neutralise legacy `!important` type sizes at <=480px -------
   Older blocks in this file lock hero/contact sizes with
   `!important`, which breaks 240–400px devices. Re-declare them
   fluidly here (this layer is last, so these win). */
@media (max-width: 480px) {
  .hero-title {
    font-size: clamp(22px, 7.4vw, 32px) !important;
    line-height: 1.2;
  }

  .contact-title {
    font-size: clamp(21px, 6.6vw, 28px) !important;
  }

  .contact-subtitle {
    font-size: clamp(18px, 5.4vw, 22px) !important;
  }

  .apt-card,
  .contact-info-card,
  .contact-form-card {
    padding: clamp(14px, 4.4vw, 22px) clamp(12px, 3.6vw, 16px) !important;
    border-radius: var(--ux-card-radius) !important;
  }

  .apt-form-grid {
    grid-template-columns: 1fr !important;
  }
}

/* --- Small phones (360px and under) ---------------------------- */
@media (max-width: 400px) {
  .site-header .logo-text {
    max-width: 54vw;
  }

  .hero-buttons {
    flex-direction: column;
  }

  .btn-browse,
  .btn-appointment {
    width: 100%;
    flex: 1 1 auto;
  }

  /* Still two columns at 400px and under — see the note in the 560px block. */
  .footer-container {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-areas:
      "brand brand"
      "quick hours"
      "contact contact";
  }

  .cal-legend {
    gap: 6px 10px;
  }

  /* One celebration emoji is enough on a narrow banner. */
  .promotion-spotlight-card .spotlight-celebration-icon.right {
    display: none !important;
  }
}

/* ux-layer-F-end */

/* --- Ultra-narrow devices (smartwatch / 240–320px viewports) ---- */
@media (max-width: 340px) {
  :root {
    --ux-gutter: 10px;
    --ux-gap: 10px;
    --ux-tap: 40px;
  }

  .site-header {
    gap: 6px;
  }

  .logo-subtitle {
    display: none;
  }

  .site-header .logo-title {
    font-size: 9.5px;
    line-height: 1.15;
  }

  /* Keep every action reachable — only the brand text gives up room. */
  .site-header .logo-text {
    max-width: 40vw;
  }

  .header-right-actions {
    gap: 4px;
  }

  /* Two-class selectors so these also beat the products page's
     inline <style> block, which loads after main.css. */
  .header-right-actions .cart-icon-container,
  .header-right-actions .announcement-bell,
  .header-right-actions .user-profile,
  .site-header .mobile-menu-toggle {
    min-width: 36px;
    min-height: 36px;
    width: 36px;
    height: 36px;
  }

  .header-right-actions .cart-icon-container svg,
  .header-right-actions .announcement-bell i,
  .header-right-actions .user-profile > svg {
    width: 19px;
    height: 19px;
    font-size: 15px;
  }

  .hero-title {
    font-size: 21px !important;
    line-height: 1.22;
  }

  .contact-title {
    font-size: 20px !important;
  }

  .contact-subtitle {
    font-size: 17px !important;
  }

  .contact-info-card,
  .contact-form-card,
  .apt-card {
    padding: 16px 12px !important;
    border-radius: var(--ux-card-radius) !important;
  }

  .hero-graphic {
    width: min(58vw, 150px);
  }

  .scroll-indicator {
    display: none;
  }

  .section-title,
  .vm-title {
    font-size: 21px;
  }

  .services-list-header h2 {
    font-size: 1.25rem;
  }

  .product-actions {
    grid-template-columns: 1fr !important;
  }

  .action-btn {
    font-size: 11px !important;
  }

  .products-page-body .action-btn-label {
    white-space: normal;
  }

  /* Steps become a swipeable strip rather than crushing to nothing. */
  .apt-progress-wrapper {
    overflow-x: auto !important;
    justify-content: flex-start;
    scrollbar-width: none;
  }

  .apt-progress-wrapper::-webkit-scrollbar {
    display: none;
  }

  .apt-step {
    width: 52px;
    flex: 0 0 auto;
  }

  .apt-line {
    flex: 0 0 12px;
    min-width: 12px;
  }

  .cal-legend {
    display: grid;
    grid-template-columns: 1fr;
    gap: 6px;
  }
}

/* --- Mid-range desktops / small laptops (901–1150px) ------------
   The desktop nav is visible here alongside the full brand lockup,
   so tighten spacing to stop the header from wrapping. */
@media (min-width: 901px) and (max-width: 1150px) {
  .site-header {
    gap: 10px;
  }

  .site-header .logo-text {
    max-width: min(250px, 26vw);
  }

  .site-header .logo-title {
    font-size: 12.5px;
  }

  .site-header .logo-subtitle {
    font-size: 7.5px;
  }

  .site-header .header-emblem {
    height: 40px;
  }

  .main-nav ul {
    gap: 16px;
  }

  .nav-link {
    font-size: 13.5px;
  }
}

.nav-link {
  white-space: nowrap;
}

/* --- Very small heights / landscape phones ---------------------- */
@media (max-height: 460px) and (orientation: landscape) {
  .hero-section {
    min-height: auto;
    padding-top: clamp(24px, 6vh, 48px);
    padding-bottom: clamp(24px, 6vh, 48px);
  }

  .hero-container {
    flex-direction: row;
    text-align: left;
  }

  .hero-content-left {
    align-items: flex-start;
    order: 1;
  }

  .hero-content-right {
    order: 2;
  }

  .hero-graphic {
    width: min(34vw, 190px);
  }

  .scroll-indicator {
    display: none;
  }

  .mobile-sidebar,
  .sidebar-nav {
    overflow-y: auto;
  }

  .apt-container {
    min-height: auto;
  }
}

/* --- Large desktops: cap measure, keep content centred ---------- */
@media (min-width: 1600px) {
  .hero-container,
  .about-container,
  .footer-container,
  .footer-bottom,
  .services-container,
  .toolbar-container,
  .shop-grid,
  .contact-page-container {
    max-width: 1520px;
    margin-inline: auto;
  }

  .vision-container,
  .mission-container {
    max-width: 1360px;
  }

  .apt-container {
    max-width: 1240px;
  }
}

@media (min-width: 2200px) {
  :root {
    --ux-gutter: clamp(72px, 6vw, 200px);
  }

  .hero-container,
  .about-container,
  .footer-container,
  .footer-bottom,
  .services-container,
  .toolbar-container,
  .shop-grid,
  .contact-page-container {
    max-width: 1760px;
  }

  .shop-grid {
    grid-template-columns: repeat(
      auto-fill,
      minmax(min(100%, 300px), 1fr)
    ) !important;
  }

  .services-grid {
    grid-template-columns: repeat(
      auto-fill,
      minmax(min(100%, 330px), 1fr)
    ) !important;
  }

  .hero-title {
    font-size: clamp(58px, 3.4vw, 86px);
  }

  .section-text,
  .contact-lead {
    font-size: clamp(18px, 0.95vw, 21px);
  }
}

/* --- Touch devices: no sticky :hover artefacts ------------------ */
@media (hover: none) {
  .service-card:hover,
  .shop-card:hover,
  .contact-links-list li:hover,
  .apt-reminder-item:hover,
  .hero-graphic:hover {
    transform: none;
  }

  .hero-graphic {
    animation: none;
  }
}

/* --- Respect reduced-motion preferences ------------------------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- Visible keyboard focus everywhere -------------------------
   A hint of the brand red, never a thick amber ring. Links, buttons and
   custom widgets get a slim maroon outline; fields get an even lighter
   one because they already tint their own border and halo red on focus
   (see .c-input:focus / .contact-input:focus), so the two read as a
   single delicate red edge. */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid rgba(107, 32, 43, 0.42);
  outline-offset: 2px;
}

input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 1px solid rgba(107, 32, 43, 0.45);
  outline-offset: 3px;
}

/* ------------------------------------------------------------------
   CUSTOMER PORTAL MODAL FINISH
   Shared by Home, Services, Products, and Contact customer pages.
   ------------------------------------------------------------------ */

/* The orders surface is a true edge-to-edge drawer. The shared UX layer
   above adds breathing room to ordinary dialogs, but that inset creates a
   visible strip beside this full-height panel. */
.customer-orders-overlay {
  inset: 0;
  width: 100%;
  /* Same property twice, never `min-height` as the fallback. iOS reports 100vh
     as the *large* viewport (toolbars hidden) and 100dvh as what is actually on
     screen, so `min-height: 100vh` beside `height: 100dvh` did not degrade — it
     overrode, growing this overlay ~80px past the bottom of the screen. The
     drawer is `height: 100%` of it and the order-detail sheet is `inset: 0`
     inside that, so all three lost their bottom edge at once, and the
     `overflow: hidden` below made the strip unreachable rather than merely
     scrolled off. Chrome desktop never showed it: there 100vh == 100dvh. */
  height: 100vh;
  height: 100dvh;
  /* A fixed `inset: 0` box is sized by the fixed containing block, which is not
     always the visible viewport. Capping at 100vw means the drawer can never be
     wider than the layout viewport, and is a no-op wherever the two agree. */
  max-width: 100vw;
  padding: 0 !important;
  overflow: hidden;
  align-items: stretch;
  background: var(--ux-dlg-scrim);
}

.customer-orders-modal {
  /* 100vw as a third bound for the same reason as the overlay's max-width. */
  width: min(820px, 100%, 100vw);
  max-width: 100%;
  /* No height pair here: the `#customerOrdersModal.ux-dlg .customer-orders-modal
     .ux-dlg__card` rule further down (1,3,0) already sets `height: 100%;
     min-height: 0`, so the drawer follows the overlay fixed above. */
  max-height: none;
  padding: max(20px, env(safe-area-inset-top))
    max(20px, env(safe-area-inset-right)) max(20px, env(safe-area-inset-bottom))
    max(20px, env(safe-area-inset-left));
  border: 0;
  border-left: 1px solid rgba(107, 32, 43, 0.16);
  border-radius: 0;
  background:
    radial-gradient(
      circle at 100% 0,
      rgba(241, 237, 18, 0.16),
      transparent 18rem
    ),
    linear-gradient(180deg, var(--customer-paper) 0%, #fffafa 100%);
  box-shadow: -30px 0 78px rgba(15, 23, 42, 0.3);
  gap: 18px;
  overflow: hidden;
}

.customer-orders-head {
  flex: 0 0 auto;
  align-items: center;
  padding: 4px 0 18px;
  border-bottom: 1px solid rgba(150, 52, 73, 0.12);
}

/* My Orders is the only head with a four-line copy stack: eyebrow, title,
   subtitle and the live sync status. Centred against all four lines the badge
   drifts down beside the subtitle, so it spans just the first two rows and
   centres against the eyebrow + title pair — the part the eye reads as the
   heading. Scoped through the overlay id to clear the shell's (1,2,0) badge
   rule; the copy is a flat run of children (no wrapper) so that rows 1 and 2
   really are those two lines at every breakpoint. */
#customerOrdersModal.ux-dlg .ux-dlg__card .customer-orders-head .ux-dlg__badge {
  grid-row: 1 / span 2;
}

.customer-orders-title {
  font-size: clamp(1.2rem, 2.3vw, 1.65rem);
  letter-spacing: -0.02em;
}

.customer-orders-subtitle {
  max-width: 46ch;
  margin-top: 6px;
  font-size: 0.8rem;
}

.customer-orders-sync-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 9px 0 0;
  color: #64748b;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1.25;
}

.customer-orders-sync-dot {
  width: 7px;
  height: 7px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: #94a3b8;
}

.customer-orders-sync-status.is-syncing .customer-orders-sync-dot {
  width: 18px;
  height: 18px;
  background: none;
}

.customer-orders-sync-dot > .fmrc-load-inline {
  --fmrc-inline-size: 18px;
}

.customer-orders-sync-status:not(.is-syncing) .customer-orders-sync-dot > .fmrc-load-inline {
  display: none;
}

.customer-orders-sync-status.is-live {
  color: #18723a;
}

.customer-orders-sync-status.is-live .customer-orders-sync-dot {
  background: #22a447;
  box-shadow: 0 0 0 3px rgba(34, 164, 71, 0.12);
}

.customer-orders-sync-status.is-offline {
  color: var(--customer-wine);
}

.customer-orders-sync-status.is-offline .customer-orders-sync-dot {
  background: #d97706;
}

.customer-orders-close {
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  border-color: rgba(150, 52, 73, 0.18);
  border-radius: 12px;
  background: #fff8f8;
  color: var(--customer-wine);
}

.customer-orders-close:hover {
  border-color: var(--customer-wine-hover);
  background: var(--customer-wine-hover);
  color: #ffffff;
}

.customer-orders-tabs {
  flex: 0 0 auto;
  gap: 6px;
  padding: 5px;
  border: 1px solid rgba(107, 32, 43, 0.12);
  border-radius: 15px;
  background: rgba(255, 246, 246, 0.9);
  scrollbar-width: none;
}

.customer-orders-tabs::-webkit-scrollbar {
  display: none;
}

.customer-orders-tab {
  min-height: 40px;
  padding: 8px 12px;
  border-color: transparent;
  border-radius: 10px;
  background: transparent;
}

.customer-orders-tab:hover {
  border-color: var(--customer-wine-hover);
  background: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
}

.customer-orders-tab.active {
  background: linear-gradient(135deg, var(--customer-wine), var(--customer-wine-light));
  border-color: transparent;
  box-shadow: 0 8px 18px rgba(128, 0, 0, 0.2);
}

.customer-orders-viewport {
  flex: 1 1 auto;
  min-height: 0;
  border-radius: 18px;
  background: rgba(255, 248, 248, 0.92);
  box-shadow: inset 0 1px 0 rgba(247, 242, 236, 0.8);
}

.customer-orders-panel {
  padding: 16px;
}

.customer-order-card {
  border-radius: 14px;
  padding: 14px;
  box-shadow: 0 10px 24px rgba(65, 16, 16, 0.06);
}

.customer-order-card:hover {
  transform: none;
  border-color: rgba(107, 32, 43, 0.28);
  background: #fffdfd;
  box-shadow: 0 14px 28px rgba(65, 16, 16, 0.1);
}

.customer-order-thumb img,
.customer-order-detail-item img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition:
    opacity 0.18s ease,
    transform 0.2s ease;
}

.customer-order-thumb img.is-loading,
.customer-order-detail-item img.is-loading {
  opacity: 0.2;
}

.customer-order-image-trigger {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
  border: 0;
  border-radius: inherit;
  background: linear-gradient(145deg, #fffafa, #f8eaea);
  color: var(--customer-wine);
  cursor: zoom-in;
  -webkit-tap-highlight-color: transparent;
}

.customer-order-detail-image-trigger {
  width: 46px;
  height: 46px;
  flex: 0 0 46px;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
}

.customer-order-image-trigger:hover img,
.customer-order-image-trigger:focus-visible img {
  transform: scale(1.04);
}

.customer-order-image-trigger:active img {
  transform: scale(0.98);
}

.customer-order-image-trigger:focus-visible {
  outline: 2px solid rgba(107, 32, 43, 0.42);
  outline-offset: 2px;
}

.customer-order-image-trigger[aria-disabled="true"] {
  cursor: default;
}

.customer-order-image-loading,
.customer-order-image-expand,
.customer-order-image-unavailable {
  position: absolute;
  display: grid;
  place-items: center;
  pointer-events: none;
  transition: opacity 0.18s ease;
}

.customer-order-image-loading {
  inset: 0;
  color: var(--customer-wine);
  font-size: 1rem;
  opacity: 0;
}

.customer-order-image-trigger.is-loading .customer-order-image-loading {
  opacity: 1;
}

.customer-order-image-trigger:not(.is-loading) .customer-order-image-loading {
  display: none;
}

.customer-order-image-expand {
  right: 5px;
  bottom: 5px;
  width: 24px;
  height: 24px;
  border: 1px solid rgba(247, 242, 236, 0.86);
  border-radius: 50%;
  background: rgba(107, 32, 43, 0.9);
  color: var(--customer-paper-sink);
  box-shadow: 0 4px 10px rgba(45, 12, 12, 0.26);
  font-size: 0.67rem;
  opacity: 0;
}

.customer-order-image-trigger.is-ready .customer-order-image-expand {
  opacity: 1;
}

.customer-order-image-trigger.is-unavailable .customer-order-image-expand,
.customer-order-image-trigger.is-unavailable .customer-order-image-loading {
  opacity: 0;
}

.customer-order-image-unavailable {
  inset: 0;
  color: rgba(107, 32, 43, 0.58);
  font-size: 1.1rem;
  opacity: 0;
}

.customer-order-image-trigger.is-unavailable .customer-order-image-unavailable {
  opacity: 1;
}

.customer-order-image-lightbox {
  z-index: 30040;
}

.customer-order-lightbox-box {
  width: min(760px, 92vw);
}

.customer-order-lightbox-media {
  position: relative;
  display: grid;
  width: 100%;
  min-height: min(58vh, 520px);
  place-items: center;
  overflow: hidden;
  border-radius: var(--ux-dlg-radius-sm);
  background: linear-gradient(145deg, var(--customer-paper), #fff7f4);
}

.customer-order-lightbox-image {
  grid-area: 1 / 1;
  opacity: 0;
}

.customer-order-image-lightbox.is-loading .customer-order-lightbox-image[src] {
  opacity: 0.32;
}

.customer-order-image-lightbox.is-ready .customer-order-lightbox-image {
  opacity: 1;
}

.customer-order-lightbox-loading {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  color: var(--customer-wine);
  font-family: "Montserrat", sans-serif;
  font-size: 0.88rem;
  font-weight: 800;
  transition: opacity 0.18s ease;
}

.customer-order-image-lightbox.is-ready .customer-order-lightbox-loading {
  opacity: 0;
  pointer-events: none;
}

.customer-order-image-lightbox.is-ready .customer-order-lightbox-loading > .fmrc-load-inline,
.customer-order-image-lightbox.has-error .customer-order-lightbox-loading > .fmrc-load-inline {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .customer-order-image-trigger img {
    transition: opacity 0.18s ease;
  }

  /* The swipe carousel jumps straight to the next panel instead of sliding. The
     drag itself still tracks the finger — that is direct manipulation, not
     decoration — but nothing animates once the finger lifts. */
  .customer-orders-track {
    transition: none;
  }
}

.customer-order-detail-modal {
  inset: 0;
  border: 0;
  border-radius: 0;
  background: #fffafa;
  box-shadow: 0 0 42px rgba(15, 23, 42, 0.2);
}

.customer-order-detail-head {
  padding: 18px 20px;
  border-bottom-color: rgba(150, 52, 73, 0.12);
  background: #ffffff;
}

.customer-order-detail-content {
  padding: 18px;
}

/* A confirmation popup should feel deliberate and centered, with clear
   hierarchy and controls that remain comfortable on small screens. */
#aptConfirmModal,
#aptLeaveConfirmModal {
  padding: max(16px, env(safe-area-inset-top))
    max(16px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom))
    max(16px, env(safe-area-inset-left));
  background: var(--ux-dlg-scrim);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

#aptConfirmModal .apt-nested-box,
#aptLeaveConfirmModal .apt-nested-box {
  width: min(100%, 440px);
  max-width: 440px;
  padding: 32px clamp(22px, 5vw, 36px) 30px;
  border: 1px solid rgba(107, 32, 43, 0.14);
  border-top: 1px solid rgba(107, 32, 43, 0.14);
  border-radius: var(--ux-dlg-radius);
  background: var(--customer-paper);
  box-shadow: 0 28px 70px rgba(27, 4, 4, 0.38);
  text-align: center;
}

#aptConfirmModal .nested-icon,
#aptLeaveConfirmModal .nested-icon {
  position: static;
  width: 62px;
  height: 62px;
  margin: 0 auto 18px;
  transform: none;
  border: 6px solid #fff8d2;
  background: #f1ed12;
  color: var(--customer-wine);
  font-size: 28px;
  box-shadow: 0 10px 22px rgba(139, 131, 5, 0.2);
}

#aptConfirmModal .apt-nested-box h3,
#aptLeaveConfirmModal .apt-nested-box h3 {
  margin: 0 0 10px;
  color: var(--customer-wine);
  font-size: clamp(20px, 4vw, 24px);
  line-height: 1.2;
}

#aptConfirmModal .apt-nested-box p,
#aptLeaveConfirmModal .apt-nested-box p {
  max-width: 30ch;
  margin: 0 auto;
  color: #5c6470;
  font-size: 14px;
  line-height: 1.6;
  text-align: center;
}

#aptConfirmModal .nested-actions,
#aptLeaveConfirmModal .nested-actions {
  justify-content: center;
  gap: 12px;
  margin-top: 25px;
}

#aptConfirmModal .nested-actions .apt-btn,
#aptLeaveConfirmModal .nested-actions .apt-btn {
  min-width: 132px;
}

/* The success dialog is a compact, scroll-safe confirmation card rather than
   a loose block with competing padding rules from the legacy layers. */
.success-modal-overlay {
  inset: 0;
  width: 100%;
  /* Same-property dvh fallback — see `.customer-orders-overlay` for why
     `min-height: 100vh` here was overriding rather than degrading. */
  height: 100vh;
  height: 100dvh;
  max-width: 100vw;
  padding: max(16px, env(safe-area-inset-top))
    max(16px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom))
    max(16px, env(safe-area-inset-left));
  overflow-y: auto;
  background: var(--ux-dlg-scrim);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.success-card {
  width: min(100%, 520px);
  max-width: 520px;
  max-height: min(
    720px,
    calc(100dvh - 32px - env(safe-area-inset-top) - env(safe-area-inset-bottom))
  );
  min-height: 0;
  padding: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  border: 1px solid rgba(241, 237, 18, 0.6);
  border-radius: var(--ux-dlg-radius);
  background: var(--customer-paper);
  box-shadow: 0 30px 78px rgba(27, 4, 4, 0.5);
}

.success-card__header {
  padding: clamp(26px, 5vw, 36px) clamp(24px, 6vw, 38px) 30px;
}

.success-icon {
  display: grid;
  place-items: center;
  width: 60px;
  height: 60px;
  margin-bottom: 17px;
  font-size: 30px;
}

.success-card__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 28px clamp(24px, 6vw, 38px) 24px;
}

.success-desc {
  max-width: 50ch;
}

/* The reference-code panel is an inset panel inside a dialog, so it takes tone
   and a hairline, not elevation: the `inset 0 1px 0 rgba(255, 255, 255, .8)` top
   line it used to carry was a cool white edge sitting on warm cream, and it was
   the last one of those left on any appointment surface. `12px` was also the last
   stray radius in this dialog — every other panel inside a `ux-dlg` is on the
   `--apt-radius-sm` rung. */
.success-reference {
  border: 1px solid #eadc9a;
  border-radius: var(--apt-radius-sm);
  box-shadow: none;
}

.success-card__footer {
  flex: 0 0 auto;
  padding: 18px clamp(24px, 6vw, 38px) max(26px, env(safe-area-inset-bottom));
  border-top: 1px solid #f0e8c8;
  background: #fffdf4;
}

@media (max-width: 560px) {
  .customer-orders-modal {
    padding: max(16px, env(safe-area-inset-top))
      max(14px, env(safe-area-inset-right))
      max(16px, env(safe-area-inset-bottom))
      max(14px, env(safe-area-inset-left));
    gap: 13px;
  }

  .customer-orders-head {
    padding-bottom: 14px;
  }

  .customer-orders-subtitle {
    font-size: 0.74rem;
  }

  .customer-orders-viewport {
    border-radius: 14px;
  }

  .customer-orders-panel {
    padding: 10px;
  }

  .customer-order-detail-head,
  .customer-order-detail-content {
    padding: 14px;
  }

  #aptConfirmModal .nested-actions,
  #aptLeaveConfirmModal .nested-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  #aptConfirmModal .nested-actions .apt-btn,
  #aptLeaveConfirmModal .nested-actions .apt-btn {
    min-width: 0;
    width: 100%;
  }

  .success-card {
    width: 100%;
    max-height: calc(
      100dvh - 24px - env(safe-area-inset-top) - env(safe-area-inset-bottom)
    );
    border-radius: var(--ux-dlg-radius);
  }

  .success-card__header {
    padding: 26px 24px 28px;
  }

  .success-card__body {
    padding: 24px 24px 20px;
  }

  .success-card__footer {
    padding: 16px 24px max(22px, env(safe-area-inset-bottom));
  }
}

/* ==========================================================================
   Hero SDG strip — up to 8 round badges under the hero CTAs (4 + 4).
   Plate, ring, glow, hover easing and click shrink are all borrowed from
   .hero-graphic / .btn-browse so the band reads as part of the same hero.
   ========================================================================== */
.hero-sdg-strip {
  --sdg-gap: clamp(6px, 1.1vw, 14px);
  /* Deliberately generous: the badges read as their own band rather than a
     third row of controls hanging off the CTA pills. */
  margin-top: clamp(28px, 4.6vw, 58px);
  width: min(100%, 430px);
}

.hero-sdg-strip[hidden] {
  display: none;
}

/* Caption sits *under* the circles, so its margin is on top, and it starts on
   the same left edge as the badges above it. */
.hero-sdg-caption {
  margin: clamp(10px, 1.5vw, 16px) 0 0;
  font-family: "Montserrat", "Poppins", sans-serif;
  font-size: clamp(9px, 1vw, 11.5px);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(247, 242, 236, 0.84);
  text-align: left;
  line-height: 1.45;
}

.hero-sdg-caption[hidden] {
  display: none;
}

.hero-sdg-rows {
  display: flex;
  flex-direction: column;
  gap: var(--sdg-gap);
}

/* Two rows rather than one 4-column grid: a partial second row (e.g. 5 badges
   = 4 + 1) then keeps the same left edge instead of leaving a hole. The band
   fills from the left so its first badge lines up with the hero title and the
   Browse Products pill, the way the copy column reads everywhere else. */
.hero-sdg-row {
  display: flex;
  justify-content: flex-start;
  gap: var(--sdg-gap);
  list-style: none;
  margin: 0;
  padding: 0;
}

.hero-sdg-item {
  flex: 0 0 calc((100% - 3 * var(--sdg-gap)) / 4);
  max-width: 78px;
  min-width: 0;
}

/* One plate, one hairline, one shadow.

   What was here: a two-stop white→cream gradient under a `blur(10px)`, a
   translucent white ring, and three shadow layers — a 26px drop, a 14px gold
   glow and an inset white line — growing on hover to 40px / 26px / 18px while
   the badge rose 4px and scaled 1.08. Eight decorated circles is a lot of
   decoration for a row of logos, and the gold glow was a third simultaneous
   accent next to the Browse pill and the footer rules.

   The hairline is `--apt-line-warm` rather than the white ring it replaces
   because the hero background is owner-configurable (`hero_bg_type`): on the
   dark maroon default a white ring on a white plate is invisible and the plate
   itself carries the contrast, but on a light hero the plate needs an edge, and
   a warm maroon hairline is the one the rest of the page already uses. */
.hero-sdg-btn {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  padding: 3px;
  border-radius: 50%;
  overflow: hidden;
  cursor: pointer;
  font-family: "Montserrat", sans-serif;
  color: var(--customer-wine);
  background: var(--customer-paper);
  border: 2px solid var(--apt-line-warm);
  box-shadow: 0 8px 18px rgba(35, 8, 8, 0.22);
  transition:
    border-color 0.2s ease,
    transform 0.2s ease;
  /* `backwards`, not `both`. A filling animation's value beats every normal
     declaration in the cascade, so with `both` the 100% keyframe's
     `translateY(0) scale(1)` was permanently overriding `:active` — the press
     below could never render, and neither could the lift this rule used to
     declare on hover. `backwards` still fills the pre-start frame (which is
     what stops a flash of un-popped badges) and then hands `transform` back to
     the cascade; the base transform is `none`, which is exactly what the 100%
     keyframe resolves to, so nothing moves. */
  animation: sdgPopIn 0.5s cubic-bezier(0.25, 0.8, 0.25, 1) backwards;
  animation-delay: calc(var(--sdg-i, 0) * 60ms);
}

/* Edge only — the same hover the service cards use. A white plate holding a
   fixed colour logo has no fill to darken, so the border is where the state
   goes, and the resting shadow is repeated verbatim so nothing appears to
   lift. */
.hero-sdg-btn:hover {
  border-color: rgba(150, 52, 73, 0.25);
  box-shadow: 0 8px 18px rgba(35, 8, 8, 0.22);
}

.hero-sdg-btn:active {
  transform: scale(0.97);
}

/* The badges sit on the maroon hero, so the focus ring is a light rose
   rather than the deep maroon used elsewhere — same red family, but it
   still reads against the dark gradient. */
.hero-sdg-btn:focus-visible {
  outline: 2px solid rgba(255, 214, 214, 0.9);
  outline-offset: 3px;
}

.hero-sdg-img {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  pointer-events: none;
}

@keyframes sdgPopIn {
  0% {
    opacity: 0;
    transform: translateY(10px) scale(0.86);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero-sdg-btn {
    animation: none;
    transition: none;
  }

  /* Hover no longer moves anything, so the only motion left to suppress is the
     press. Kept on both selectors: a pointer that is down is also over. */
  .hero-sdg-btn:hover,
  .hero-sdg-btn:active {
    transform: none;
  }
}

/* Which edge the band aligns to — it follows the copy column rather than
   picking its own: flush left wherever the title and CTA pills are (the default
   row hero, and the height-starved landscape heroes that rebuild that row), and
   centred only where the column itself is centred (the stacked hero at 900px
   and below). The landscape exceptions come last so they win inside the stacked
   rule's range. */
@media (max-width: 900px) {
  .hero-sdg-row {
    justify-content: center;
  }

  .hero-sdg-caption {
    text-align: center;
  }
}

@media (max-height: 460px) and (orientation: landscape) {
  .hero-sdg-row {
    justify-content: flex-start;
  }

  .hero-sdg-caption {
    text-align: left;
  }
}

@media (min-width: 320px) and (max-width: 720px) and (max-height: 520px) {
  .hero-sdg-row {
    justify-content: flex-start;
  }

  .hero-sdg-caption {
    text-align: left;
  }
}

/* SDG detail modal (built by main.js on the shared .admin-system-popup shell) */
.sdg-detail-modal__img {
  width: 96px;
  height: 96px;
  margin: 0 auto 14px;
  border-radius: 50%;
  padding: 4px;
  object-fit: cover;
  background: linear-gradient(
    135deg,
    rgba(247, 242, 236, 0.96),
    rgba(255, 248, 238, 0.92)
  );
  border: 2px solid rgba(107, 32, 43, 0.18);
  box-shadow: 0 10px 24px rgba(35, 8, 8, 0.18);
  display: block;
}

/* ==========================================================================
   Hero rhythm — the hero runs past the fold so the SDG band is the first
   thing a scroll reveals, not the About section.
   ========================================================================== */
.hero-section {
  /* The slice of hero below the fold: it carries the SDG badges plus the
     empty space under them, taking the section to roughly 125% of a screen.
     The floor is what a short desktop needs for the badge band and the cue at
     the foot of the section to clear each other. */
  --hero-tail: clamp(190px, 25dvh, 300px);
  min-height: calc(100dvh - var(--ux-header-h) + var(--hero-tail));
}

/* Growing the section on its own would re-centre its contents and drag the
   title down with them. Mirroring that growth as a bottom margin on the
   centred container keeps the title/logo pair exactly where it sat in a 100vh
   hero and puts every new pixel underneath the badges instead. */
.hero-container {
  margin-bottom: var(--hero-tail);
}

/* The cue belongs at the foot of the section — under the badge band and the
   empty space below it — rather than on the fold line, where it read as a
   marker sitting beside the badges. `bottom` is measured from
   .hero-section's own edge, which is now a tail below the fold, so no tail
   term is needed; left: 50% + translateX(-50%) from the base rule keeps it
   horizontally centred. */
.hero-section .scroll-indicator {
  bottom: clamp(22px, 3vh, 34px);
}

@media (max-width: 900px) {
  .hero-section {
    /* The stacked hero already runs well past the fold on its own, so it needs
       far less of a tail to keep the badges clear of the About section. */
    --hero-tail: clamp(90px, 15dvh, 170px);
  }

  /* The cue leaves absolute positioning at this width and rejoins the flow, so
     the container's tail margin lands between the copy and the cue — which puts
     the cue at the foot of the section exactly as it is above. Its own margins
     stay at the base `18px auto 0`, so the group's total height is unchanged and
     the title/logo pair keeps its position. */
}

/* ==========================================================================
   Hero SDG band — pinned out of the copy column.

   The badges used to sit in the copy column's flow, so their height stretched
   the column, the flex row re-centred it, and a script then nudged the whole
   column back down to put the title on the logo's mid-line. Between them the
   title, the CTA pills and the logo lost the top of the hero screen and the
   badge band ended up sliced by the fold.

   Taking the band out of flow at the side-by-side widths fixes both ends: the
   column measures the title and the pills only, so the row centres the
   title/logo pair on its own with no script, and the band keeps the exact
   place it already occupied — the title's left edge, in the hero's below-fold
   tail — because `top: 100%` measures from the column's own bottom edge. The
   offset is what used to be the band's `margin-top` plus the nudge the script
   was adding, so the badges do not move.

   `position: relative` on the column is deliberate: .reveal-on-scroll gives it
   a transform, which would make it the containing block anyway, but only once
   main.js has run — pinning it here makes the band's reference box the same
   before and after that.

   Below 901px the hero stacks and the band goes back to being a normal block
   under the pills, where the copy column is centred and full width.
   ========================================================================== */
@media (min-width: 901px) {
  .hero-content-left {
    position: relative;
  }

  .hero-sdg-strip {
    position: absolute;
    top: 100%;
    /* The band's own margin, plus exactly what the column lost by shedding it:
       the row re-centres the shorter column by half the height of the block
       between the title and the band, i.e. half of the title's margin plus the
       CTA pills. Both terms are the live tokens from those rules, so the
       badges land on the pixel they were on before and stay there if either
       one is ever retuned. */
    margin-top: calc(
      clamp(28px, 4.6vw, 58px) + (clamp(18px, 3vw, 34px) + clamp(44px, 9vw, 56px)) / 2
    );
    /* 100% is the column's width here, so the 430px cap still decides. */
    width: min(100%, 430px);
  }
}

/* ==========================================================================
   Brand logo holders — the navbar emblem, the hero graphic and the two footer
   marks are all admin-uploadable, so each one gets a holder with a locked
   shape. Only `aspect-ratio` and `object-fit` do the shaping here: every
   responsive override sets a single axis (height for the emblem and the footer
   marks, width for the hero graphic), so the ratio derives the other axis and
   all existing sizes carry over untouched. `contain` keeps a portrait or
   landscape upload whole inside the holder instead of letting it stretch the
   header or turn a circle into an ellipse.
   ========================================================================== */

/* Square framing only — the emblem sits directly on the header with no plate
   and no hairline, so an uploaded mark with a transparent background reads as
   part of the chrome instead of being boxed in. */
.header-emblem {
  aspect-ratio: 1;
  width: auto;
  object-fit: contain;
  padding: 0;
  background: none;
  border: 0;
}

@media (max-width: 900px) {
  /* Nothing to inset now that the plate is gone; kept so the mobile emblem
     keeps its own square ratio if a future rule sets a width instead. */
  .header-emblem {
    padding: 0;
  }
}

/* Fixed circle. `width: auto` plus the ratio turns the existing height into a
   diameter, so a wide upload no longer flattens the circle into an ellipse. */
.footer-logo {
  aspect-ratio: 1;
  width: auto;
  object-fit: contain;
}

/* Fixed circle. Width is the axis every breakpoint sets for the hero graphic,
   so the ratio derives the height and the ring stays perfectly round whatever
   the uploaded artwork's proportions are. */
.hero-graphic {
  aspect-ratio: 1;
  height: auto;
  object-fit: contain;
}

/* The "Account Tip" popover that nudges Google-signed-in customers to set a
   password used to be styled here in its own 2100-era language. It now wears the
   shared `ux-dlg` skin, so its rules had to move *below* that system — see
   "ACCOUNT TIP POPOVER" at the end of this file. Nothing is left here on purpose:
   a rule at this height in the file could not beat `:is(.ux-dlg, …) .ux-dlg__card
   .part`, which is (1,2,0). */

/* Cloudflare Turnstile stays collapsed until the backend keys are enabled. */
.fmrc-turnstile-slot {
  display: flex;
  min-height: 65px;
  margin: 12px auto;
  justify-content: center;
  align-items: center;
}

.fmrc-turnstile-slot[hidden] {
  display: none;
}

/* ============================================================================
   UNIFIED CUSTOMER DIALOG SYSTEM ("ux-dlg")
   Every customer pop-up now wears the same skin as the appointment/order
   success cards: a maroon gradient band carrying a yellow badge, an uppercase
   eyebrow and a white title, a white scrollable body, and a cream footer strip
   of pill buttons. Declared last in the file so it beats the legacy dialog
   layers above; the `:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal)` prefix
   lifts every rule to id-level specificity so the older id-scoped appointment
   overrides cannot leak back through.
   ========================================================================== */
:root {
  --ux-dlg-band: linear-gradient(135deg, #3d0808 0%, #5f0d0d 52%, #851313 100%);
  --ux-dlg-badge: #f1ed12;
  --ux-dlg-badge-ink: var(--customer-wine-hover);
  --ux-dlg-eyebrow: #f5ef8e;
  --ux-dlg-radius: 8px;
  --ux-dlg-radius-sm: 6px;
  --ux-dlg-edge: rgba(241, 237, 18, 0.6);
  --ux-dlg-shadow: 0 30px 78px rgba(27, 4, 4, 0.5);
  /* Match the neutral backdrop behind the action loader. Media and phone
     confirmations retain their stronger dimming with the same cool hue. */
  --ux-dlg-scrim: rgba(15, 23, 42, 0.55);
  --ux-dlg-scrim-media: rgba(15, 23, 42, 0.82);
  --ux-dlg-scrim-dense: rgba(15, 23, 42, 0.72);
  --customer-modal-stage:
    radial-gradient(circle at 85% 15%, rgba(241, 237, 18, 0.14), transparent 19rem),
    radial-gradient(circle at 15% 85%, rgba(158, 20, 20, 0.18), transparent 21rem),
    linear-gradient(135deg, #3d0808 0%, #5f0d0d 45%, #851313 100%);
  --ux-dlg-foot-bg: #fffdf4;
  --ux-dlg-foot-line: #f0e8c8;
  --ux-dlg-pad-x: clamp(22px, 5.6vw, 34px);
  --ux-dlg-text: #4b5563;
  --ux-dlg-maroon: #5f0d0d;
}

/* -- Scrims: one glass treatment for every dialog layer -------------------- */
.ux-dlg__backdrop,
.guest-access-modal,
.customer-modal-overlay,
.customer-rating-overlay,
.customer-rating-discard-overlay,
.customer-orders-overlay,
#aptPrivacyModal.apt-nested-modal,
#aptConfirmModal.apt-nested-modal,
#aptLeaveConfirmModal.apt-nested-modal {
  background: var(--ux-dlg-scrim);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.ux-dlg__backdrop {
  position: absolute;
  inset: 0;
}

/* -- Overlay gutters (safe-area aware, never a display rule) --------------- */
.guest-access-modal,
.customer-modal-overlay,
.customer-rating-overlay,
.customer-rating-discard-overlay,
.customer-orders-overlay,
.ux-dlg--standalone,
#aptPrivacyModal.apt-nested-modal,
#aptConfirmModal.apt-nested-modal,
#aptLeaveConfirmModal.apt-nested-modal {
  padding: max(14px, env(safe-area-inset-top)) max(14px, env(safe-area-inset-right))
    max(14px, env(safe-area-inset-bottom)) max(14px, env(safe-area-inset-left));
}

/* -- Standalone overlay (logout confirm builds its own root) ---------------
   Deliberately transparent: this root always contains a `.ux-dlg__backdrop`
   child, which already paints the shared scrim and blur. Painting the scrim
   here as well stacked two 0.8 veils (0.96 effective) and blurred twice, which
   made Confirm Logout markedly darker than every other dialog. */
.ux-dlg--standalone {
  position: fixed;
  inset: 0;
  /* Third `position: fixed; inset: 0` dialog root on this page, given the same
     dynamic-viewport pin as `.customer-modal-overlay` and
     `.customer-orders-overlay` so it cannot outgrow the visible screen. */
  height: 100vh;
  height: 100dvh;
  max-width: 100vw;
  z-index: 100000;
  display: none;
  align-items: center;
  justify-content: center;
  background: transparent;
  opacity: 0;
  transition: opacity 0.22s ease;
}

.ux-dlg--standalone.show {
  opacity: 1;
}

.ux-dlg--standalone .ux-dlg__card {
  transform: translateY(16px) scale(0.975);
  transition: transform 0.26s cubic-bezier(0.22, 1, 0.36, 1);
}

.ux-dlg--standalone.show .ux-dlg__card {
  transform: none;
}

/* -- The card shell -------------------------------------------------------- */
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(100%, 520px);
  max-width: min(100%, 520px);
  min-width: 0;
  min-height: 0;
  /* The 30px is the overlay's own gutter pair; the insets are what a notched
     phone takes off the top and bottom of the dynamic viewport. Without them the
     cap allowed a card that, plus its gutters, was taller than the screen — the
     same allowance `.success-card` already makes above. */
  max-height: min(
    760px,
    calc(
      100dvh - 30px - env(safe-area-inset-top) - env(safe-area-inset-bottom)
    )
  );
  padding: 0;
  overflow: hidden;
  text-align: left;
  background: var(--customer-paper);
  border: 1px solid var(--ux-dlg-edge);
  border-radius: var(--ux-dlg-radius);
  box-shadow: var(--ux-dlg-shadow);
}

/* -- Head: the maroon band ------------------------------------------------- */
/* Two columns: the badge on the left, every line of copy on the right. The band
   is a grid rather than a flex row because the copy is a variable number of
   siblings: eyebrow, title, and sometimes a subtitle, a product line or a live
   status line, with no shared wrapper to flex against. The
   column gap is carried by the badge's own right margin, not `column-gap`, so a
   head with no badge collapses column 1 to zero and keeps its original indent. */
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__head {
  position: relative;
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0;
  overflow: hidden;
  margin: 0;
  padding: clamp(15px, 3.2vw, 19px) var(--ux-dlg-pad-x) 15px;
  padding-right: max(64px, var(--ux-dlg-pad-x));
  background: var(--ux-dlg-band);
  border: 0;
  border-radius: 0;
  text-align: left;
}

/* Sized and pulled down for the shorter band: a top arc in the lower-right
   corner rather than a wash across the whole band. */
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__head::after {
  content: "";
  position: absolute;
  right: -38px;
  bottom: -105px;
  width: 170px;
  height: 170px;
  border: 1px solid rgba(241, 237, 18, 0.26);
  border-radius: 50%;
  box-shadow: 0 0 0 26px rgba(241, 237, 18, 0.06);
  pointer-events: none;
}

/* Lift every band child above the decorative ring drawn by ::after, and stack
   the copy in the second column. The badge is excluded because this selector is
   one class more specific than the badge's own rule and would otherwise drag it
   out of column 1. The close button and the back pill are excluded too, but for
   a different reason: an absolutely positioned grid child with an explicit
   column is inset from *that column's* edge, which would drag both controls 64px
   in from the corner they are anchored to. */
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__head > * {
  position: relative;
  z-index: 1;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal)
  .ux-dlg__card
  .ux-dlg__head
  > *:not(.ux-dlg__close, .ux-dlg__back, .ux-dlg__badge, .ux-dlg__figure) {
  grid-column: 2;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__head > :is(.ux-dlg__close, .ux-dlg__back) {
  grid-column: auto;
  grid-row: auto;
}

/* `span 99` is deliberate: the copy occupies as many implicit rows as the dialog
   happens to have lines, and the badge has to span all of them for
   `align-self: center` to centre it against the whole text block. `gap: 0` above
   is what keeps the surplus empty rows free. */
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__badge {
  position: relative;
  z-index: 1;
  inset: auto;
  grid-column: 1;
  grid-row: 1 / span 99;
  align-self: center;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  min-width: 0;
  margin: 0 14px 0 0;
  padding: 0;
  transform: none;
  border-radius: 50%;
  border: 2px solid rgba(247, 242, 236, 0.45);
  background: var(--ux-dlg-badge);
  color: var(--ux-dlg-badge-ink);
  box-shadow: 0 8px 18px rgba(45, 12, 12, 0.26);
  font-size: 19px;
  line-height: 1;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__badge i {
  font-size: inherit;
  color: inherit;
  margin: 0;
}

/* `text-align` and `max-width` are restated here for the same reason the title
   restates them: legacy per-dialog rules target the band's paragraphs directly
   (`#aptConfirmModal .apt-nested-box p` centres them inside 30ch), and a
   directly matched declaration beats the head's inherited `text-align: left`. */
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__eyebrow {
  position: relative;
  z-index: 1;
  margin: 0 0 3px;
  padding: 0;
  max-width: none;
  text-align: left;
  color: var(--ux-dlg-eyebrow);
  font-family: "Montserrat", "Poppins", sans-serif;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  line-height: 1.3;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__title {
  position: relative;
  z-index: 1;
  margin: 0;
  padding: 0;
  color: var(--customer-paper-sink);
  font-family: "Poppins", "Segoe UI", sans-serif;
  font-size: clamp(17px, 3.6vw, 21px);
  font-weight: 800;
  line-height: 1.24;
  letter-spacing: 0.1px;
  text-align: left;
  text-transform: none;
  max-width: none;
}

/* -- Figure head (SDG detail) --------------------------------------------- */
/* The one head that opts out of the icon-left grid: its "badge" is a full-width
   SDG plate, not a 44px circle, so it stays a centred stack. */
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__head--figure {
  display: block;
  text-align: center;
  padding-right: var(--ux-dlg-pad-x);
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__head--figure .ux-dlg__eyebrow,
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__head--figure .ux-dlg__title {
  text-align: center;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__figure {
  position: relative;
  z-index: 1;
  display: block;
  width: auto;
  max-width: 190px;
  max-height: 150px;
  margin: 0 auto 16px;
  border-radius: var(--ux-dlg-radius-sm);
  background: rgba(247, 242, 236, 0.14);
  box-shadow: 0 12px 26px rgba(45, 12, 12, 0.3);
  object-fit: contain;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__figure:not([src]),
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__figure[src=""] {
  display: none;
}

/* -- Secondary lines that ride on the band -------------------------------- */
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__head .customer-orders-subtitle {
  margin: 6px 0 0;
  color: rgba(247, 242, 236, 0.84);
  font-size: 13px;
  line-height: 1.45;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__head .customer-orders-sync-status {
  margin: 10px 0 0;
  padding: 5px 11px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border-radius: 999px;
  border: 1px solid rgba(241, 237, 18, 0.34);
  background: rgba(45, 12, 12, 0.3);
  color: var(--ux-dlg-eyebrow);
  font-size: 11.5px;
  font-weight: 700;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__head .customer-orders-sync-dot {
  background: var(--ux-dlg-badge);
  box-shadow: 0 0 0 3px rgba(241, 237, 18, 0.2);
}

/* -- Close (×) and Back controls ------------------------------------------- */
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__close {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 3;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  /* `min-height` has to be reset too, not just `min-width`: the tap-target rule
     for `.guest-access-close` / `.customer-modal-close` / `.customer-orders-close`
     sets `min-height: var(--ux-tap)` (44px), and a min-height always beats the
     `height` above regardless of specificity — the circle rendered as a 36x44
     ellipse until this line existed. */
  min-width: 0;
  min-height: 0;
  margin: 0;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(247, 242, 236, 0.34);
  background: rgba(247, 242, 236, 0.14);
  color: var(--customer-paper-sink);
  font-size: 20px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease, transform 0.2s ease;
}

/* Hover is a colour change only — no lift, no spin. The press keeps a small
   scale so a tap still reads as a click. */
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__close:hover {
  background: rgba(247, 242, 236, 0.34);
  border-color: rgba(247, 242, 236, 0.62);
  color: var(--customer-paper-sink);
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__close:active {
  transform: scale(0.94);
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__back {
  position: static;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  width: auto;
  margin: 0 0 14px;
  padding: 7px 14px 7px 11px;
  border-radius: var(--apt-radius-sm, 6px);
  border: 1px solid rgba(247, 242, 236, 0.32);
  background: rgba(247, 242, 236, 0.12);
  color: var(--customer-paper-sink);
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__back:hover {
  background: rgba(247, 242, 236, 0.34);
  border-color: rgba(247, 242, 236, 0.62);
  color: var(--customer-paper-sink);
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__back:active {
  transform: scale(0.96);
}

/* -- Body ------------------------------------------------------------------ */
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  padding: 24px var(--ux-dlg-pad-x) 22px;
  background: var(--customer-paper);
  text-align: left;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__text {
  margin: 0;
  max-width: none;
  color: var(--ux-dlg-text);
  font-size: 14.5px;
  line-height: 1.62;
  text-align: left;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__text + * {
  margin-top: 16px;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__note {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 0 0 18px;
  padding: 13px 15px;
  border: 1px solid #eadc9a;
  border-radius: var(--ux-dlg-radius-sm);
  background: #fffbed;
  color: #6b5a24;
  font-size: 13px;
  line-height: 1.55;
  text-align: left;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__note i {
  flex: 0 0 auto;
  margin-top: 1px;
  color: var(--customer-wine);
  font-size: 15px;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__note strong {
  color: var(--customer-wine);
  font-weight: 800;
}

/* -- Footer strip ---------------------------------------------------------- */
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__foot {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: stretch;
  justify-content: stretch;
  gap: 10px;
  margin: 0;
  padding: 16px var(--ux-dlg-pad-x) max(18px, env(safe-area-inset-bottom));
  border: 0;
  border-top: 1px solid var(--ux-dlg-foot-line);
  border-radius: 0;
  background: var(--ux-dlg-foot-bg);
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__foot.is-confirm {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr);
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal)
  .ux-dlg__card
  .ux-dlg__foot:not(.is-confirm)
  #customerSystemPopupCancel {
  display: none;
}

/* -- Action buttons -------------------------------------------------------- */
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-width: 0;
  margin: 0;
  padding: 15px 20px;
  min-height: 51px;
  border: 0;
  /* The card's own corner. `.ux-dlg__card` is `var(--ux-dlg-radius)`, so the
     footer buttons repeat it and the dialog reads as one object instead of a
     square card with two pills glued to the bottom. This single declaration is
     what carries the shape to My Account, Change Password, Logout,
     Announcement, the SDG detail popup and both appointment dialogs. */
  border-radius: var(--ux-dlg-radius);
  font-family: "Montserrat", "Poppins", sans-serif;
  font-size: 14.5px;
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: 0.2px;
  text-align: center;
  text-decoration: none;
  text-transform: none;
  cursor: pointer;
  transition: transform 0.18s ease, box-shadow 0.18s ease, filter 0.18s ease,
    background 0.18s ease, color 0.18s ease;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__btn--primary:not(.apt-btn-blue) {
  background: var(--customer-wine);
  color: var(--customer-paper-sink);
  box-shadow: 0 10px 22px rgba(128, 116, 14, 0.24);
}

/* Hover darkens the fill and nothing else — no lift, no shadow growth. The
   only motion is the press scale below. */
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__btn--primary:not(.apt-btn-blue):hover {
  background: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  /* Repeating the resting shadow pins it: `.btn-place-order` and
     `.customer-rating-submit-btn` (both carried by the submit pills) swap in a
     smaller maroon-tinted hover shadow, which read as the button moving. */
  box-shadow: 0 10px 22px rgba(128, 116, 14, 0.24);
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__btn--ghost {
  background: var(--customer-paper);
  color: var(--customer-wine);
  border: 1.5px solid rgba(107, 32, 43, 0.32);
  box-shadow: 0 6px 16px rgba(95, 13, 13, 0.08);
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__btn--ghost:hover {
  background: #f2dede;
  border-color: var(--customer-wine-hover);
  color: var(--customer-wine-hover);
  box-shadow: 0 6px 16px rgba(95, 13, 13, 0.08);
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__btn--danger {
  background: var(--customer-wine);
  color: var(--customer-paper-sink);
  box-shadow: 0 12px 24px rgba(133, 19, 19, 0.32);
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__btn--danger:hover {
  background: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  box-shadow: 0 12px 24px rgba(133, 19, 19, 0.32);
}

/* No hover lift anywhere in the shell. Legacy `translateY(-2px)` hovers on
   `.apt-btn`, `.modal-btn` and friends still match inside these dialogs, so
   they are cancelled here — hover is colour only. The matching `:active` list
   below repeats the same selector shapes so the press scale still wins on
   source order while a pressed button is also hovered. */
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__btn:hover,
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__foot button:hover,
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__foot a:hover,
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__head button:hover {
  transform: none;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__btn:active,
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__foot button:active,
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__foot a:active,
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__head button:active {
  transform: scale(0.97);
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__btn:focus-visible {
  outline: 3px solid rgba(241, 237, 18, 0.55);
  outline-offset: 2px;
}

:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__btn:disabled {
  opacity: 0.62;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

/* ---------------------------------------------------------------------------
   Per-dialog reconciliation with the legacy layers
   ------------------------------------------------------------------------- */

/* My Orders stays the full-height right-hand drawer customers already know —
   only the skin is shared with the other dialogs. Everything that has to clear
   the (1,2,0) card shell above is scoped through the overlay id.
   The overlay's own `padding: 0 !important` and `align-items: stretch` already
   come from the edge-to-edge drawer block further up, so they are not repeated. */
#customerOrdersModal.ux-dlg {
  justify-content: flex-end;
}

#customerOrdersModal.ux-dlg .customer-orders-modal.ux-dlg__card {
  width: min(880px, 100%);
  max-width: 100%;
  height: 100%;
  min-height: 0;
  max-height: none;
  gap: 0;
  border: 0;
  /* Square on every side at every width: the drawer is anchored to the right
     edge, so a rounded left side read as a floating panel rather than a sheet.
     The shadow alone now separates it from the page. */
  border-radius: 0;
  background: var(--customer-paper);
  box-shadow: -30px 0 78px rgba(27, 4, 4, 0.5);
  transform: translateX(100%);
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}

#customerOrdersModal.ux-dlg.show .customer-orders-modal.ux-dlg__card {
  transform: none;
}

/* Eight status chips on strictly one line at every width. Wrapping used to be
   the safety valve, but a second row pushed the panels down and made the strip
   read as two controls, so the row now scrolls horizontally instead. The
   scrollbar is hidden on every engine and `setActivePanel` in main.js keeps the
   active chip centred, which is what makes a hidden scrollbar navigable. */
#customerOrdersModal.ux-dlg .ux-dlg__card > .customer-orders-tabs {
  flex: 0 0 auto;
  flex-wrap: nowrap;
  gap: 5px;
  margin: 16px var(--ux-dlg-pad-x) 0;
  padding: 5px;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

#customerOrdersModal.ux-dlg .ux-dlg__card > .customer-orders-tabs::-webkit-scrollbar {
  display: none;
}

#customerOrdersModal.ux-dlg .ux-dlg__card > .customer-orders-tabs .customer-orders-tab {
  flex: 0 0 auto;
  min-height: 38px;
  padding: 8px 11px;
  font-size: 0.76rem;
  white-space: nowrap;
  scroll-snap-align: start;
}

/* The panels own the vertical scroll, so hand the browser `pan-y` and keep the
   horizontal axis for the swipe handler in main.js. */
#customerOrdersModal.ux-dlg .ux-dlg__card > .customer-orders-viewport {
  margin: 14px var(--ux-dlg-pad-x) max(18px, env(safe-area-inset-bottom));
  touch-action: pan-y;
}

/* Sync pill states have to stay legible on the maroon band.
   Scoped through `#customerOrdersModal` on purpose: the shared pill rules near
   the top of this layer are written as
   `:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__head …`, and
   `:is()` takes the specificity of its most specific argument, so those sit at
   (1,2,0) and beat any plain-class rule here. Adding the id lifts these to
   (1,5,0) so "live" can actually render green instead of the yellow badge. */
#customerOrdersModal.ux-dlg .ux-dlg__head .customer-orders-sync-status.is-live {
  border-color: rgba(87, 224, 127, 0.4);
  background: rgba(87, 224, 127, 0.14);
  color: #c8f7d6;
}

#customerOrdersModal.ux-dlg
  .ux-dlg__head
  .customer-orders-sync-status.is-live
  .customer-orders-sync-dot {
  background: #57e07f;
  box-shadow: 0 0 0 3px rgba(87, 224, 127, 0.22);
}

#customerOrdersModal.ux-dlg .ux-dlg__head .customer-orders-sync-status.is-syncing {
  border-color: rgba(87, 224, 127, 0.28);
  color: #d8f8e4;
}

#customerOrdersModal.ux-dlg
  .ux-dlg__head
  .customer-orders-sync-status.is-syncing
  .customer-orders-sync-dot {
  background: none;
  box-shadow: none;
}

#customerOrdersModal.ux-dlg .ux-dlg__head .customer-orders-sync-status.is-offline {
  border-color: rgba(255, 180, 87, 0.38);
  color: #ffdcae;
}

#customerOrdersModal.ux-dlg
  .ux-dlg__head
  .customer-orders-sync-status.is-offline
  .customer-orders-sync-dot {
  background: #ffb457;
  box-shadow: 0 0 0 3px rgba(255, 180, 87, 0.2);
}

/* Order detail is a sheet *inside* the orders drawer, so it keeps its own
   absolute positioning and stays hidden until `.show` is added. Scoped through
   both ids: the generic card shell is (1,2,0) and would otherwise force
   `position: relative; display: flex` and leave the sheet permanently open in
   the drawer's flow. */
#customerOrdersModal.ux-dlg #customerOrderDetailModal.ux-dlg__card {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: none;
  width: auto;
  max-width: none;
  height: auto;
  max-height: none;
  border: 0;
  border-radius: 0;
  box-shadow: 0 0 42px rgba(27, 4, 4, 0.28);
}

#customerOrdersModal.ux-dlg #customerOrderDetailModal.ux-dlg__card.show {
  display: flex;
}

:is(.ux-dlg) .customer-order-detail-modal.ux-dlg__card > .customer-order-detail-content {
  padding: 20px clamp(18px, 4.6vw, 26px) max(22px, env(safe-area-inset-bottom));
  background: #fffafa;
}

/* Rating / return / buy-again cards: the shared body needs its own gutters now
   that the card itself has no padding. */
:is(.ux-dlg) .ux-dlg__card > .customer-rating-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 22px var(--ux-dlg-pad-x) 20px;
  background: var(--customer-paper);
}

/* Rate / return / buy-again all carry `.customer-rating-card`, and the discard
   confirm is the small one. Same specificity lever as above — as class-only
   rules these lost to the (1,2,0) shell and every one of them rendered at the
   shell's 520px instead of its own width. */
:is(.ux-dlg, #aptPrivacyModal).customer-rating-overlay .customer-rating-card.ux-dlg__card {
  width: min(100%, 560px);
  max-width: min(100%, 560px);
  max-height: min(860px, calc(100dvh - 28px));
  gap: 0;
}

:is(.ux-dlg, #aptPrivacyModal).customer-rating-discard-overlay
  .customer-rating-discard-card.ux-dlg__card {
  width: min(100%, 420px);
  max-width: min(100%, 420px);
}

/* Product-info / service-details modals: wider content cards on the same
   shell, with the hairline dividers dropped now that the band and the cream
   action strip provide the separation. */
.modal-overlay.ux-dlg {
  background: var(--ux-dlg-scrim);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

/* The `:is(.ux-dlg, #aptPrivacyModal)` prefix is a specificity lever, nothing
   else: it lifts this rule to (1,3,0) so the intended content width clears the
   (1,2,0) card shell. Without it every `.modal-box` dialog — product details,
   service details — silently rendered at the shell's 520px default. */
:is(.ux-dlg, #aptPrivacyModal).modal-overlay .modal-box.ux-dlg__card {
  width: min(750px, 100%);
  max-width: min(750px, 100%);
  max-height: min(92vh, calc(100dvh - 24px));
}

/* Product details is the one `.modal-box` dialog with a two-column body, so it
   gets the extra width on a laptop canvas and never scrolls sideways. */
#productInfoModal.ux-dlg .modal-box.ux-dlg__card {
  width: min(940px, 100%);
  max-width: min(940px, 100%);
  max-height: min(94vh, calc(100dvh - 24px));
}

.modal-overlay.ux-dlg .ux-dlg__card > .modal-divider {
  display: none;
}

.modal-overlay.ux-dlg .ux-dlg__card > .modal-scroll-area {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  background: var(--customer-paper);
}

.modal-overlay.ux-dlg .ux-dlg__card > .modal-actions {
  flex: 0 0 auto;
  border-top: 1px solid var(--ux-dlg-foot-line);
  background: var(--ux-dlg-foot-bg);
}

/* Customer reviews: the widest card of the set, children already carry their
   own 28px gutters so only the frame needs restating. */
/* Customer feedback: the widest card of the set — a rating summary, seven
   filter chips and a media grid all want the room. Scoped through the id so it
   clears the (1,2,0) shell. */
#customerReviewsModal.ux-dlg .customer-reviews-box.ux-dlg__card {
  width: min(1040px, 100%);
  max-width: min(1040px, 100%);
  max-height: min(94vh, calc(100dvh - 24px));
}

.customer-reviews-overlay.ux-dlg .ux-dlg__head .customer-reviews-product {
  margin: 6px 0 0;
  color: rgba(247, 242, 236, 0.82);
  font-size: 0.85rem;
  font-weight: 600;
}

.customer-reviews-overlay.ux-dlg .ux-dlg__card > .customer-reviews-list {
  background: var(--customer-paper);
}

/* Cart / checkout / address sheets keep their single-row header layout (a back
   arrow, a centered title, one trailing control) but wear the same band. */
.shop-modal-overlay {
  background: var(--ux-dlg-scrim);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.shop-modal-box {
  border: 1px solid var(--ux-dlg-edge);
  border-radius: var(--ux-dlg-radius);
  box-shadow: var(--ux-dlg-shadow);
  background: var(--customer-paper);
}

/* Below 768px these five sheets have always gone edge to edge — a full-screen
   panel with rounded corners just wastes the corners and shows a sliver of scrim
   behind them. The rule above is a plain class selector declared after the
   legacy `@media (max-width: 768px)` block further up, so it was winning on
   phones by source order alone; this puts the full-bleed treatment back. */
@media (max-width: 768px) {
  .shop-modal-box {
    border: 0;
    border-radius: 0;
  }
}

.shop-modal-box > .shop-modal-header {
  position: relative;
  overflow: hidden;
  padding: 16px 20px;
  border-bottom: 0;
  background: var(--ux-dlg-band);
}

.shop-modal-box > .shop-modal-header::after {
  content: "";
  position: absolute;
  right: -60px;
  bottom: -120px;
  width: 200px;
  height: 200px;
  border: 1px solid rgba(241, 237, 18, 0.24);
  border-radius: 50%;
  box-shadow: 0 0 0 24px rgba(241, 237, 18, 0.05);
  pointer-events: none;
}

.shop-modal-box > .shop-modal-header > * {
  position: relative;
  z-index: 1;
}

.shop-modal-header .shop-modal-title {
  color: #ffffff;
}

.shop-modal-header .cart-short-address {
  color: rgba(255, 255, 255, 0.82);
}

.shop-modal-header .back-shop-modal,
.shop-modal-header .trash-btn {
  border: 1px solid rgba(255, 255, 255, 0.32);
  background: rgba(255, 255, 255, 0.14);
  color: #ffffff;
}

.shop-modal-header .back-shop-modal:hover,
.shop-modal-header .trash-btn:hover {
  border-color: rgba(255, 255, 255, 0.6);
  background: rgba(255, 255, 255, 0.34);
  color: #ffffff;
}

.shop-modal-box > .shop-modal-footer {
  border-top: 1px solid var(--ux-dlg-foot-line);
  background: var(--ux-dlg-foot-bg);
}

/* -- `hidden` stays hidden -------------------------------------------------
   The shell sets `display` on badges, figures and pill buttons, which would
   otherwise out-specify the UA `[hidden]` rule and reveal controls the scripts
   keep collapsed (the announcement Next/View Details buttons, empty states).
   Declared last in this section so it wins on source order. */
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card [hidden] {
  display: none;
}

/* -- Announcement dialog ---------------------------------------------------
   The overlay keeps the customer scrim. The card, footer navigation and actions
   use announcement-card.css, shared with the Admin/Staff preview. */
.announcement-modal.ux-dlg {
  padding: max(14px, env(safe-area-inset-top))
    max(14px, env(safe-area-inset-right))
    max(14px, env(safe-area-inset-bottom))
    max(14px, env(safe-area-inset-left));
  /* The runtime sheet centres this overlay with `place-items`, which leaves the
     implicit column content-sized — the card's `width: min(100%, 520px)` would
     then resolve its percentage against its own text and collapse to about
     290px. A full-width track gives the percentage something definite to
     resolve against, and `justify-items: center` still centres the card. */
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  background: var(--ux-dlg-scrim);
  backdrop-filter: blur(8px);
}

/* Announcement card contents are shared with Admin/Staff in announcement-card.css. */

/* ---------------------------------------------------------------------------
   Follow-up pass: drawer, wide content cards, tighter account band, solid
   profile menu. Everything here is scoped through a dialog id so it clears the
   (1,2,0) `:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card`
   shell — a class-only override, however long, loses to it because ids are
   compared before classes.
   ------------------------------------------------------------------------- */

/* -- My Account / Account security: a little wider ------------------------- */
/* The squished band, the 44px badge and the tighter eyebrow/title sizes these
   two dialogs used to set for themselves are now the shared defaults, so only
   the extra width and the relocated Back pill are left here. */
#customerProfileModal.ux-dlg .customer-modal.ux-dlg__card,
#customerPasswordModal.ux-dlg .customer-modal.ux-dlg__card {
  width: min(100%, 640px);
  max-width: min(100%, 640px);
}

/* Back sits in the close button's slot — same 14px inset, same 36px height — so
   Account security's control lines up with My Account's X when the two dialogs
   swap. The head then reserves the pill's width instead of the X's. */
#customerPasswordModal.ux-dlg .ux-dlg__card .ux-dlg__head {
  padding-right: max(104px, var(--ux-dlg-pad-x));
}

#customerPasswordModal.ux-dlg .ux-dlg__card .ux-dlg__back {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 3;
  height: 36px;
  min-height: 36px;
  margin: 0;
  padding: 0 14px 0 11px;
}

/* -- Product details: two columns once the card is wide ------------------- */
/* At 940px a single stacked column left the 250px image as a grey letterbox and
   ran body text past 100 characters a line, so the body splits: image parked in
   a sticky left rail, copy and lists in the right. Below 900px it stays the
   original stack. */
@media (min-width: 900px) {
  #productInfoModal.ux-dlg .ux-dlg__card > .modal-scroll-area {
    display: grid;
    grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
    column-gap: clamp(24px, 3vw, 36px);
    align-content: start;
  }

  #productInfoModal.ux-dlg .modal-scroll-area > .modal-img-holder {
    grid-column: 1;
    grid-row: 1 / span 4;
    position: sticky;
    top: 0;
    height: 300px;
    margin-bottom: 0;
  }

  #productInfoModal.ux-dlg .modal-scroll-area > :not(.modal-img-holder) {
    grid-column: 2;
  }

  #productInfoModal.ux-dlg .modal-scroll-area > .modal-columns:last-child {
    margin-bottom: 0;
  }
}

/* -- Customer feedback: nothing scrolls sideways on a laptop -------------- */
/* The seven rating filters were a `overflow-x: auto` strip. With the card at
   1040px they fit on one line; `wrap` keeps that true if a label grows. */
#customerReviewsModal.ux-dlg .ux-dlg__card > .customer-reviews-filters {
  flex-wrap: wrap;
  overflow: visible;
}

@media (min-width: 900px) {
  /* Three `1fr` tracks would blow each review photo up to ~300px on the wide
     card. Fixed 150px tracks keep the grid a thumbnail strip that wraps. */
  #customerReviewsModal.ux-dlg .customer-reviews-list .customer-review-media {
    grid-template-columns: repeat(auto-fill, minmax(0, 150px));
  }
}

/* -- Mobile: the drawer goes edge to edge ---------------------------------- */
/* The square corners and the scrolling chip strip now apply at every width, so
   the only thing left for phones is letting the sheet span the full viewport. */
@media (max-width: 960px) {
  #customerOrdersModal.ux-dlg .customer-orders-modal.ux-dlg__card {
    width: 100%;
  }
}

/* -- Navbar profile menu: one solid card, same language as the dialogs -----
   Built once in main.js and appended to `.user-profile`, so the four customer
   pages share this markup — styling it here is what makes them identical.
   Selectors are scoped through `.user-profile` / `.profile-popup` (two classes)
   because responsive.css loads after this file and its single-class small-screen
   rules would otherwise put the old padding and radius back.
   No translucency and no `backdrop-filter`: the card is opaque so text never
   sits on whatever is scrolling underneath.
   `:not(.guest-profile-popup)` keeps the signed-out variant out of this: it is
   the same element with a different body (blurb, benefits, two auth buttons)
   and it already carries its own band header, which these gutters would fight. */
.user-profile .profile-popup:not(.guest-profile-popup) {
  width: min(344px, calc(100vw - 24px));
  max-width: calc(100vw - 24px);
  display: flex;
  flex-direction: column;
  padding: 0;
  /* Cream shows through around the logout button, which is what gives the menu
     the same footer strip every dialog has. The rows paint themselves white. */
  background: var(--ux-dlg-foot-bg);
  border: 1px solid rgba(107, 32, 43, 0.16);
  border-radius: var(--ux-dlg-radius);
  box-shadow:
    0 26px 60px rgba(45, 12, 12, 0.26),
    0 2px 6px rgba(45, 12, 12, 0.08);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* The pointer has to match whatever it points out of — the band, not the body.
   Both states of the menu now open with a band on top, so both get it. */
.user-profile .profile-popup:not(.guest-profile-popup)::before,
.user-profile .profile-popup.guest-profile-popup::before {
  right: 18px;
  width: 16px;
  height: 16px;
  border-left-color: rgba(107, 32, 43, 0.16);
  border-top-color: rgba(107, 32, 43, 0.16);
  background: var(--customer-wine-hover);
}

.profile-popup:not(.guest-profile-popup) .popup-header {
  position: relative;
  overflow: hidden;
  margin: 0;
  padding: 15px 17px 16px;
  background: var(--ux-dlg-band);
  border-radius: 7px 7px 0 0;
}

/* Same faint ring the dialog bands carry, scaled to a dropdown. */
.profile-popup:not(.guest-profile-popup) .popup-header::after {
  content: "";
  position: absolute;
  right: -34px;
  bottom: -72px;
  width: 132px;
  height: 132px;
  border: 1px solid rgba(241, 237, 18, 0.24);
  border-radius: 50%;
  box-shadow: 0 0 0 16px rgba(241, 237, 18, 0.05);
  pointer-events: none;
}

.profile-popup .popup-profile-row {
  position: relative;
  z-index: 1;
  align-items: center;
  gap: 12px;
}

/* One badge for both states of the menu — the signed-out card used to paint its
   own translucent square here, which was the only thing making the two
   dropdowns look like different objects. */
.profile-popup .popup-profile-icon {
  width: 42px;
  height: 42px;
  border: 2px solid rgba(247, 242, 236, 0.45);
  background: var(--ux-dlg-badge);
  color: var(--ux-dlg-badge-ink);
  font-size: 18px;
  box-shadow: 0 8px 18px rgba(45, 12, 12, 0.26);
}

.profile-popup .popup-identity {
  color: var(--customer-paper-sink);
  font-size: 15px;
}

.profile-popup .popup-identity.is-long {
  font-size: 13.5px;
}

.profile-popup .popup-identity.is-very-long {
  font-size: 12.5px;
}

/* Full-bleed rows instead of stacked cards: fewer edges, easier to scan. The
   legacy border is `!important`, so undoing it has to be too. */
.profile-popup .profile-popup-link {
  gap: 12px;
  min-height: 52px;
  margin: 0;
  padding: 13px 17px;
  background: var(--customer-paper);
  border: 0 !important;
  border-radius: 0;
  box-shadow: none;
  color: var(--apt-body);
  font-size: 14.5px;
  transition:
    background-color 0.18s ease,
    color 0.18s ease;
}

.profile-popup .profile-popup-link + .profile-popup-link {
  border-top: 1px solid rgba(107, 32, 43, 0.08) !important;
}

.profile-popup .profile-popup-link i {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border-radius: 10px;
  background: rgba(107, 32, 43, 0.08);
  color: var(--customer-wine);
  font-size: 14px;
  transition: background-color 0.18s ease;
}

/* Border chevron rather than an icon font: nothing to load, and it inherits the
   row's colour transition. */
.profile-popup .profile-popup-link::after {
  content: "";
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  margin-left: auto;
  border-right: 2px solid rgba(107, 32, 43, 0.32);
  border-bottom: 2px solid rgba(107, 32, 43, 0.32);
  transform: rotate(-45deg);
  /* `transform` is out of the transition list because nothing transforms it any
     more — see the hover rule below. */
  transition: border-color 0.18s ease;
}

.profile-popup .profile-popup-link:hover,
.profile-popup .profile-popup-link:focus-visible {
  background: #fff6f6;
  color: var(--customer-wine-hover);
  transform: none;
}

.profile-popup .profile-popup-link:hover i,
.profile-popup .profile-popup-link:focus-visible i {
  background: rgba(107, 32, 43, 0.16);
}

/* Colour only. The chevron used to slide `translateX(2px)` on hover, which is a
   small thing but still the row moving on hover, and "no uplift hover animation,
   only darker colour hover and click animation" does not carve out an exception
   for a decorative child. It darkens to the row's own maroon instead, which is
   what the rest of the row does. */
.profile-popup .profile-popup-link:hover::after,
.profile-popup .profile-popup-link:focus-visible::after {
  border-color: var(--customer-wine-hover);
}

/* A full-bleed row that scales shows the card behind it on every edge, so these
   press with colour while the pill below keeps the shared press scale. */
.profile-popup .profile-popup-link:active {
  background: #fdeaea;
  transform: none;
}

.profile-popup .profile-popup-link:focus-visible {
  outline: 2px solid rgba(107, 32, 43, 0.45);
  outline-offset: -2px;
}

/* The rule above the logout is the footer boundary; the cream comes from the
   card itself. */
.profile-popup hr {
  margin: 0;
  border: 0;
  border-top: 1px solid var(--ux-dlg-foot-line);
}

/* 8px, not the 12px this used to carry: every filled action on the customer site
   takes its card's own corner now — hero CTAs, View All, dialog buttons, the
   signed-out menu's two — and a lone 12px in the one place the two dropdowns sit
   side by side in a user's memory was the last shape that matched nothing. */
.profile-popup .popup-logout {
  width: auto;
  min-height: 44px;
  margin: 12px 14px 14px;
  padding: 12px 16px;
  border-radius: var(--ux-dlg-radius, 8px);
  font-size: 14px;
}

@media (max-width: 420px) {
  /* `calc(100vw - 32px)`, not `- 16px`: the card is anchored `right: 6px` on a
     host that itself sits a gutter in from the right edge, so the space between
     that anchor and the left edge of the screen is `100vw - 6 - gutter`, not
     `100vw`. Measured at 320px, where `- 16px` resolved to 304px inside 299px of
     room and put the card's left edge exactly on 0 with nothing to spare. The
     wider inset costs nothing above 352px, where the 320px ceiling wins anyway. */
  .user-profile .profile-popup:not(.guest-profile-popup),
  .user-profile .profile-popup.guest-profile-popup {
    width: min(320px, calc(100vw - 32px));
    max-width: calc(100vw - 32px);
  }

  .profile-popup:not(.guest-profile-popup) .popup-header {
    padding: 13px 14px 14px;
  }

  .profile-popup .profile-popup-link {
    min-height: 48px;
    padding: 12px 14px;
    font-size: 13.5px;
  }

  .profile-popup .popup-logout {
    margin: 10px 12px 12px;
    font-size: 13.5px;
  }
}

/* ===========================================================================
   PHONE OVERLAY STACKING — the navbar is never on top of an open overlay
   ---------------------------------------------------------------------------
   Below 901px `.site-header` climbs to z-index 12000 (see the @media block at
   ~line 7550) so the sticky navbar wins against page decoration. Every
   full-screen customer surface, though, was authored *below* that number:

     .sidebar-backdrop        11000
     .mobile-sidebar          11010
     .announcement-modal      10050   (injected by customer-announcements.js)
     .customer-modal-overlay    150   (My Account, Set/Change Password)

   so on a phone the navbar painted over the drawer and stayed clickable — with
   the drawer open, a hit test at (100, 30) returned the header logo, not the
   drawer, and the profile popup could sit on top of My Account. This block
   lifts those four surfaces into one band above the header and makes the header
   inert while any of them owns the screen. main.css is shared by all four
   customer pages, so it applies site-wide.
   ========================================================================= */
@media (max-width: 900px) {
  .sidebar-backdrop {
    z-index: 12200;
  }

  .mobile-sidebar {
    z-index: 12210;
  }

  /* Doubled class on purpose: customer-announcements.js injects
     `.announcement-modal { z-index: 10050 }` in a <style> element that lands
     after this stylesheet, so an equal-specificity rule here would lose on
     source order. */
  .announcement-modal.announcement-modal {
    z-index: 12220;
  }

  .customer-modal-overlay {
    z-index: 12230;
  }

  /* Not clickable while an overlay is open. One selector per rule so an engine
     that chokes on any of them cannot invalidate the rest. Every closing
     affordance lives inside the overlay itself (the drawer's own X, the scrim,
     Escape), so nothing becomes unreachable. */
  body.sidebar-open .site-header {
    pointer-events: none;
  }

  body.fmrc-announcement-open .site-header {
    pointer-events: none;
  }
}

@media (max-width: 900px) {
  /* My Account sets no body class, and the header is its sibling, so `:has()`
     is the only way to reach it. Progressive enhancement — where `:has()` is
     unsupported the raised z-index above still covers the navbar with the
     modal's own full-screen scrim. */
  body:has(.customer-modal-overlay.show) .site-header {
    pointer-events: none;
  }
}

/* ===========================================================================
   OUR MISSION — the blob reserve is gone with the blobs
   ---------------------------------------------------------------------------
   `.blob-wrapper` used to carry `margin-bottom: 62px` here. It was not spacing:
   it reserved room for the overhang of `.blob-wrapper::before` (5% of the
   wrapper's height) and `::after` (12%), which otherwise cleared the bottom
   border of `.mission-container` by 35px at 1265px, 55px at 753px and 13px at
   375px. A flat length rather than a percentage, because the columns are
   `flex: 1` items whose height comes from the automatic minimum size, and
   percentage margins count as zero in that intrinsic pass.

   Both pseudo-elements were removed by request (see the note beside
   `.blob-wrapper` earlier in this file), so nothing hangs below the wrapper any
   more and the reserve is now just 62px of dead space at the bottom of the card.
   Deleted rather than zeroed, so nobody has to wonder what it was holding open.
   The phone twin in responsive.css went the same way.
   ========================================================================= */

/* UXDLG-APPEND-8 */

/* ===========================================================================
   APPOINTMENT FLOW — PHONE / SMALL-TABLET PERFORMANCE PASS (<=900px)
   ---------------------------------------------------------------------------
   Steps 1-5 felt sluggish on real phones. Measured causes inside
   `#appointmentFlow`, all of them paint cost rather than script cost:

     * nine live `backdrop-filter` surfaces (the back button, the progress
       pill, three `.apt-card`s and the four ghost footer buttons) stacked over
       an `overflow-y: auto` container — every scroll frame re-blurs each one;
     * the overlay background resolving to 28 comma-separated gradient parts
       (two radials over a linear);
     * `.apt-card`'s `0 25px 60px` shadow, re-rasterised at that blur radius;
     * `fadeInApt` animating opacity *and* a 20px translate on that whole
       blurred, shadowed card on every step change;
     * `transition: all` on the controls, so any repaint is a candidate for a
       full-property interpolation.

   This arm has since shrunk, and on purpose. The FMRC-minimalism pass (§8 at the
   end of this file) removed all four appointment `backdrop-filter`s outright and
   flattened `.apt-card` to solid white at every width, so six of the names this
   group used to carry — `.apt-back-btn`, `.apt-progress-wrapper`, `.apt-card`,
   `.apt-btn-back`, `.apt-btn-outline`, `.apt-btn-outline-brown` — had nothing
   left to switch off, and the three "slightly stronger alpha" stand-ins that
   compensated for the missing blur were making a phone render the flow in
   different colours from a desktop. Both are gone. What remains below is only
   what still differs on a phone by design.

   The four modal surfaces still blur on purpose at desktop width, so they are
   the only names left in the group.

   Deliberately NOT using `will-change` here — it would pin permanent
   compositing layers for the whole overlay and cost more memory than it saves.
   ========================================================================= */
@media (max-width: 900px) {
  .apt-nested-modal,
  #aptPrivacyModal.apt-nested-modal,
  #aptConfirmModal.apt-nested-modal,
  .success-modal-overlay {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  /* These phone dialogs omit blur, so retain stronger neutral dimming. The
     appointment stage itself keeps its reference gradient at every width. */
  .apt-nested-modal,
  #aptPrivacyModal.apt-nested-modal,
  #aptConfirmModal.apt-nested-modal,
  .success-modal-overlay {
    background: var(--ux-dlg-scrim-dense);
  }

  /* `.apt-card` is solid warm paper at every width now, so the opaque phone-only
     gradient that used to stand in for two translucent stops is gone. Only the
     shadow stays overridden: the base card's `0 22px 54px` blur radius is real
     paint cost on a phone, and this shorter one reads the same at arm's length.
     The inset white top line the old gradient was paired with is gone too — the
     base rule at :4728 carries a single flat shadow and no inset line, so
     keeping one here drew a hairline on phones that desktop never had. */
  .apt-card {
    box-shadow: 0 8px 20px rgba(45, 12, 12, 0.18);
  }

  /* Opacity only, and short: translating the card meant re-rasterising its
     shadow on every frame of the step change. */
  .apt-content-section.active {
    animation: aptFadeFlat 0.18s ease;
  }

  /* `.apt-btn` names its properties at every width now (§8's pass replaced the
     old `transition: all`), so this is no longer a fix — it is a deliberate
     narrowing. The base list also transitions `background` and `box-shadow`;
     interpolating `.apt-btn-blue`'s gold gradient and re-rasterising a shadow
     are the two most expensive things a phone can be asked to do on a tap, and
     letting both snap instead costs nothing anyone can see on a touch screen. */
  .apt-btn {
    transition:
      background-color 0.15s ease,
      border-color 0.15s ease,
      color 0.15s ease,
      transform 0.1s ease;
  }

  .apt-back-btn,
  .cal-navigation button,
  .time-slot-btn,
  .cal-day-cell {
    transition:
      background-color 0.15s ease,
      border-color 0.15s ease,
      color 0.15s ease;
  }

  .apt-icon {
    transition:
      background-color 0.2s ease,
      border-color 0.2s ease,
      color 0.2s ease,
      transform 0.2s ease;
  }

  .apt-overlay .c-input,
  .apt-nested-modal .c-input {
    transition:
      border-color 0.15s ease,
      background-color 0.15s ease,
      box-shadow 0.15s ease;
  }

  .file-upload-wrapper {
    transition:
      border-color 0.15s ease,
      background-color 0.15s ease;
  }

  .apt-nested-modal,
  .success-modal-overlay {
    transition:
      opacity 0.24s ease,
      visibility 0.24s ease;
  }
}

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

@media (prefers-reduced-motion: reduce) {
  .apt-content-section.active {
    animation: none;
  }
}

/* ==========================================================================
   VISION / MISSION IMAGE DECKS ("vm-deck")
   --------------------------------------------------------------------------
   Both sections used to hold exactly one <img>. They now hold a deck of up to
   ten, managed from Website Management -> Home in either portal, with two
   different gestures: Vision cards are dragged aside and vanish, Mission cards
   are clicked and shuffle to the back.

   Two rules govern everything below.

   1. A site with no gallery configured must render byte-identically to before.
      That is why the stacking geometry is gated behind `.has-stack`, which
      main.js only adds once it has more than one image to show. Until then the
      deck is a transparent wrapper and the single image keeps its own natural
      height, its own `max-width` and every rule that has ever targeted
      `.vision-img` / `.mission-img`.
   2. The first card keeps `id="visionImgEl"` / `id="missionImgEl"` and its
      original class, so the legacy single-image applier and all the existing
      sizing layers keep working untouched.

   This block sits at the end of the file on purpose: the Vision/Mission sizing
   is spread over five earlier layers (541-644, 6540, 7215, 12864, 14591), and
   the stacked variants have to win against all of them without resorting to
   `!important`.
   ========================================================================== */

.vm-deck {
  position: relative;
  width: 100%;
  /* No `margin-inline: auto`: `.vision-img` was left-aligned in its 570px column
     and `.blob-wrapper` already centres itself, so centring here would nudge the
     Vision photo 10px right on an unconfigured site. */
  /* Vertical scrolling always belongs to the page. The drag handler only claims
     a gesture once it has travelled far enough sideways to be unambiguous. */
  touch-action: pan-y;
}

.vm-deck--vision {
  max-width: 550px;
}

/* Mission's image is `height: 100%` of the square `.blob-wrapper`, so the deck
   and its cards have to pass that height straight through or the photo collapses.
   `z-index: 2` is inherited from what `.mission-img` carried on its own. It no
   longer has anything to sit above — the two decorative blobs it used to cover
   are gone — but it is kept because `.vm-deck` is positioned, so the z-index
   makes the stack its own stacking context and the cards' 0-3 and 6 stay private
   to the deck instead of competing with the rest of the section. */
.vm-deck--mission {
  z-index: 2;
  height: 100%;
}

.vm-deck--mission .vm-deck__card {
  height: 100%;
}

/* Unstacked, the card is a plain pass-through: no positioning, no clipping, so
   the image inside behaves exactly as it did as a bare <img>. */
.vm-deck__card {
  position: relative;
  display: block;
}

/* -- First-paint placeholder ------------------------------------------------
   Both photos are admin-uploaded base64 in site_settings, so the markup ships
   its <img> with no `src` and the deck carries `.is-loading` instead: a hard
   coded /images/pic1.jpg used to flash on every load until
   /api/site-settings answered. `.is-empty` is the settled twin — a site with no
   photo configured (or an API that never answers) lands there rather than
   holding a placeholder forever. Both retain the neutral card surface; the
   shared logo appears only while the image is loading.

   The state lives on the deck, never on the card: vmResetToFirstCard() rewrites
   `card.className` wholesale, so a class on the card would not survive a
   gallery rebuild. */
.vm-deck.is-loading .vm-deck__card > img,
.vm-deck.is-empty .vm-deck__card > img {
  display: none;
}

.vm-deck.is-loading::after,
.vm-deck.is-empty::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: #f3f4f6;
  border: 1px solid rgba(107, 32, 43, 0.15);
}

/* Keep the About video card in place while its configured video loads, or
   when no video is configured, using the same surface as Mission and Vision. */
.about-video-holder.is-loading,
.about-video-holder.is-empty {
  background: #f3f4f6;
  border: 1px solid rgba(107, 32, 43, 0.15);
  cursor: default;
}

.about-video-holder.is-loading > .about-preview-video,
.about-video-holder.is-empty > .about-preview-video,
.about-video-holder.is-loading > .about-video-control,
.about-video-holder.is-empty > .about-video-control {
  display: none;
}

.vm-deck__loading,
.about-video-loading {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 1;
  place-items: center;
  pointer-events: none;
}

.vm-deck.is-loading > .vm-deck__loading,
.about-video-holder.is-loading > .about-video-loading {
  display: grid;
}

/* Vision has no wrapper to take its height from — `.vision-img` was the element
   that decided it — so the ratio has to live here. 16/10 is what both
   `.vm-deck.has-stack` above and `.vision-img` in the phone band already use. */
.vm-deck--vision.is-loading,
.vm-deck--vision.is-empty {
  aspect-ratio: 16 / 10;
  max-width: 550px;
}

.vm-deck--vision.is-loading::after,
.vm-deck--vision.is-empty::after {
  border-radius: 12px;
  box-shadow: 0 10px 30px rgba(45, 12, 12, 0.1);
}

/* Mission already has height: the deck is `height: 100%` of the square
   `.blob-wrapper`. Only the silhouette is copied across, from `.mission-img`. */
.vm-deck--mission.is-loading::after,
.vm-deck--mission.is-empty::after {
  border-radius: 50% 50% 40% 60% / 60% 40% 60% 40%;
  box-shadow: inset 0 0 20px rgba(45, 12, 12, 0.1);
}

/* -- Stacked ---------------------------------------------------------------- */

/* A stack needs one shared box, because ten uploads of ten different shapes
   cannot take turns being the element that decides the section's height. The
   ratios match what the phone layer already picked for each image, so nothing
   about the shipped mobile pass has to be re-tuned. */
.vm-deck.has-stack {
  aspect-ratio: 16 / 10;
}

.vm-deck--mission.has-stack {
  aspect-ratio: 1;
}

.vm-deck.has-stack .vm-deck__card {
  position: absolute;
  inset: 0;
  margin: 0;
  transform-origin: 50% 85%;
  transition:
    transform 0.42s cubic-bezier(0.22, 0.61, 0.36, 1),
    opacity 0.42s ease,
    filter 0.42s ease;
  will-change: transform, opacity;
}

/* One card stays in the flow. Both columns are `flex: 1 1 0%`, so their width is
   negotiated from what they contain: lift *every* card out of the flow and the
   Mission column's min-content drops to zero, the text column takes the whole
   row, and `.blob-wrapper` resolves to 0x0 — the photo disappears at tablet
   widths. Keeping the first card in the flow reproduces exactly the intrinsic
   contribution the bare <img> used to make, and it also means a deck that is
   left holding a single image can never collapse. The other cards are absolute
   and pinned to `inset: 0`, so they overlay this one precisely; transforms do
   not affect layout, so slot geometry is unchanged either way. */
.vm-deck.has-stack .vm-deck__card:first-child {
  position: relative;
  height: 100%;
}

.vm-deck.has-stack .vm-deck__card > img {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  margin: 0;
  object-fit: cover;
}

/* -- The card is the shape, not just the photo -------------------------------
   The silhouette has always lived on the <img>: `.mission-img`'s four-value
   `border-radius` and `.vision-img`'s 12px. The card wrapping it was a plain
   rectangle, which is invisible until the card paints something of its own —
   and the shuffle and the peek both do, via `box-shadow`. A shadow follows its
   element's `border-radius`, so a square card cast a hard rectangular halo
   around an organic photo: the square edge visible mid-shuffle.

   Giving the card the same radius fixes every state at once (lift, tuck, peek,
   drag, fling) because card and photo are the identical box here — `inset: 0`
   with `width/height: 100%` — so the two curves coincide exactly. `overflow:
   hidden` makes the card's own shape authoritative rather than relying on the
   photo to mask itself.

   Deliberately NOT `filter: drop-shadow()`, which would also follow the alpha
   shape: `.is-tucking` already animates `filter: brightness()` on this same
   element, and one `filter` cannot hold both without the two fighting.

   Scoped to `.has-stack` so an unconfigured section still renders exactly as it
   did before the decks existed (rule 1 at the top of this block). */
.vm-deck--vision.has-stack .vm-deck__card {
  border-radius: 12px;
  overflow: hidden;
}

.vm-deck--mission.has-stack .vm-deck__card {
  border-radius: 50% 50% 40% 60% / 60% 40% 60% 40%;
  overflow: hidden;
}

/* -- Slot geometry ----------------------------------------------------------
   main.js writes `data-slot` on every card: 0 is the one you can touch, 1 and 2
   peek out behind it to the left, and everything deeper is parked invisibly in
   slot 2's position so promoting it costs no layout. Exactly three cards paint
   however many are in the gallery.

   Left rather than right: Vision's photo sits in the left column and Mission's
   blob leans right, so a left-hand fan keeps both fans inside the section
   instead of pushing them at the body text. */
.vm-deck.has-stack .vm-deck__card[data-slot="0"] {
  z-index: 3;
  transform: none;
  filter: none;
  opacity: 1;
}

.vm-deck.has-stack .vm-deck__card[data-slot="1"] {
  z-index: 2;
  transform: translate(-11px, 8px) rotate(-3deg) scale(0.955);
  filter: brightness(0.94);
  opacity: 1;
}

.vm-deck.has-stack .vm-deck__card[data-slot="2"] {
  z-index: 1;
  transform: translate(-22px, 16px) rotate(-6deg) scale(0.915);
  filter: brightness(0.88);
  opacity: 1;
}

.vm-deck.has-stack .vm-deck__card[data-slot="hidden"] {
  z-index: 0;
  transform: translate(-22px, 16px) rotate(-6deg) scale(0.915);
  filter: brightness(0.88);
  opacity: 0;
  pointer-events: none;
}

/* The card currently in mid-gesture is taken out of the slot system entirely —
   deliberately no transform, filter or opacity here, so the inline values script
   is writing frame by frame are the only thing positioning it. It sits above the
   whole deck while it travels; `.is-tucking` below reclaims the z-index once the
   Mission card is supposed to slide behind. */
.vm-deck.has-stack .vm-deck__card[data-slot="flying"] {
  z-index: 6;
}

/* Photos are the drag target, so the browser's own image-drag and the text
   selection a fast swipe would otherwise start both have to go. */
.vm-deck.has-stack .vm-deck__card img {
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
}

/* -- Vision: grab, drag, vanish --------------------------------------------- */

.vm-deck--vision.has-stack .vm-deck__card[data-slot="0"] {
  cursor: grab;
}

/* The press itself is the affordance: the card shrinks a little, which is what
   opens the gap that lets the next photo behind it be seen. */
.vm-deck--vision.has-stack.is-peeking .vm-deck__card[data-slot="0"] {
  transform: scale(0.955);
  cursor: grabbing;
  box-shadow: 0 18px 44px rgba(45, 12, 12, 0.22);
}

.vm-deck--vision.has-stack.is-peeking .vm-deck__card[data-slot="1"] {
  transform: translate(-6px, 4px) rotate(-1.6deg) scale(0.985);
  filter: brightness(0.98);
}

.vm-deck--vision.has-stack.is-peeking .vm-deck__card[data-slot="2"] {
  transform: translate(-15px, 11px) rotate(-4deg) scale(0.94);
  filter: brightness(0.93);
}

/* While a finger is down the transform is written frame by frame from script,
   so the transition has to be out of the way or every move would lag 420ms
   behind the pointer. */
.vm-deck__card.is-dragging {
  transition: none !important;
  cursor: grabbing;
}

/* The fling. Distance, rotation and direction are inline (they depend on the
   gesture); only the curve and what fades belong in CSS. */
.vm-deck__card.is-vanishing {
  transition:
    transform 0.46s cubic-bezier(0.2, 0.7, 0.3, 1),
    opacity 0.46s ease-in,
    filter 0.46s ease-in;
  opacity: 0;
  filter: blur(6px);
  pointer-events: none;
}

/* -- Mission: the shuffle ---------------------------------------------------
   Three beats, driven by script because the z-index has to change halfway
   through: lift the card clear of the deck, carry it back to the deepest slot,
   then drop it in. Swapping z-index at the midpoint is what makes it read as
   going *behind* the others rather than sliding under them from the start. */

.vm-deck--mission.has-stack .vm-deck__card[data-slot="0"] {
  cursor: pointer;
}

/* Beat 1: lift clear of the deck — and clear of the card the deck sits in.
   The old value was `translateY(-26px)`, which could never read as breaking out:
   `.mission-container` carries 48px of its own padding, so a 26px rise did not
   even reach the card's inner edge. -72px plus the 1.06 scale about a 50% 85%
   origin puts the top of the photo roughly 48px above the container's border,
   which is the "you can break it" the redesign asked for, and still lands well
   inside the section's own 40-90px padding. `.vm-card-aloft` (see the
   `.vision-section` note earlier in this file) is what lets it paint there.

   The shadow is warm rather than neutral black — it is now blob-shaped, because
   the card carries the silhouette, so it reads as the photo's own cast shadow
   against the cream card. It is on the transition so it grows with the lift
   instead of appearing in one frame.

   0.19s must stay at or below the lift/tuck midpoint in main.js's
   `vmWireShuffle` (200ms), or the tuck would interrupt a lift still in flight. */
.vm-deck--mission.has-stack .vm-deck__card.is-lifting {
  z-index: 6;
  transform: translateY(-72px) scale(1.06) rotate(-2.5deg);
  transition:
    transform 0.19s cubic-bezier(0.34, 1.4, 0.64, 1),
    box-shadow 0.19s ease;
  box-shadow: 0 34px 58px rgba(59, 12, 12, 0.3);
}

/* Below 768px the two columns stack, so the photo sits directly under the
   Mission copy and a desktop-sized breakout would rise through the paragraph
   rather than through the card's own padding. Here the only clearance is
   `.mission-container`'s own gap, measured from the glyph box of the copy's last
   line down to the photo: 39px at 700px wide, 28px at 481px, 21px at 375px.
   A lift raises the card's box by `translate + (scale - 1) * height * 0.85`
   (the deck's transform-origin is 50% 85%) plus about `width * sin(angle) / 2`
   for the rotation, so every part of the transform has to stay small here. The
   shadow shrinks with it: at `0 34px 58px` its blur reached 24px above the card,
   which on a phone is most of the gap. The <=480px band, where the clearance is
   tightest, retunes the transform once more in responsive.css. */
@media (max-width: 768px) {
  .vm-deck--mission.has-stack .vm-deck__card.is-lifting {
    transform: translateY(-14px) scale(1.015) rotate(-1.2deg);
    box-shadow: 0 16px 22px rgba(59, 12, 12, 0.26);
  }
}

.vm-deck--mission.has-stack .vm-deck__card.is-tucking {
  z-index: 0;
  transform: translate(-22px, 16px) rotate(-6deg) scale(0.915);
  filter: brightness(0.88);
  transition:
    transform 0.23s cubic-bezier(0.4, 0, 0.6, 1),
    filter 0.23s ease;
}

/* One frame with transitions off, used the moment a gesture finishes so the card
   that just left can be handed back to the slot system without animating all the
   way home from wherever the fling threw it. */
.vm-deck.is-settling .vm-deck__card {
  transition: none !important;
}

/* -- The hint ---------------------------------------------------------------
   Only shown once a gallery actually exists — a single-photo section has
   nothing to drag, and inviting the visitor to try would be a dead end. */
.vm-deck__hint {
  display: none;
  margin: 14px 0 0;
  color: #8b6f6f;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.2px;
  text-align: center;
}

.vm-deck.has-stack ~ .vm-deck__hint {
  display: block;
}

.vm-deck__hint i {
  margin-right: 5px;
  color: var(--customer-wine);
}

/* -- Reduced motion ---------------------------------------------------------
   The decks stay usable: cards still advance, they just cross-fade instead of
   flying, lifting or blurring. The hint is dropped because the gesture it
   advertises no longer has a visible payoff. */
@media (prefers-reduced-motion: reduce) {
  .vm-deck.has-stack .vm-deck__card,
  .vm-deck--mission.has-stack .vm-deck__card.is-lifting,
  .vm-deck--mission.has-stack .vm-deck__card.is-tucking {
    transition: opacity 0.2s ease;
  }

  /* Neutralise the peek by pinning each card back to its own resting slot,
     rather than to a shared value — slot 2 sits deeper than slot 1. */
  .vm-deck--vision.has-stack.is-peeking .vm-deck__card[data-slot="0"] {
    transform: none;
  }

  .vm-deck--vision.has-stack.is-peeking .vm-deck__card[data-slot="1"] {
    transform: translate(-11px, 8px) rotate(-3deg) scale(0.955);
    filter: brightness(0.94);
  }

  .vm-deck--vision.has-stack.is-peeking .vm-deck__card[data-slot="2"] {
    transform: translate(-22px, 16px) rotate(-6deg) scale(0.915);
    filter: brightness(0.88);
  }

  .vm-deck--mission.has-stack .vm-deck__card.is-lifting {
    transform: none;
  }

  .vm-deck__card.is-vanishing {
    transition: opacity 0.2s ease;
    filter: none;
  }

  .vm-deck.has-stack ~ .vm-deck__hint {
    display: none;
  }
}

/* ==========================================================================
   WHAT WE OFFER — stacked entrance, no card uplift, clickable artwork
   --------------------------------------------------------------------------
   Three separate asks, all scoped to #services-preview so the Services page's
   own grid and carousel keep behaving exactly as they do today.
   ========================================================================== */

/* -- 1. The stacked entrance ------------------------------------------------
   While `.is-stacked` is on the wrapper every item is pinned to the active
   card's position, so the section arrives as one card. Removing the class lets
   `.carousel-item`'s pre-existing 0.6s transform transition carry prev/next
   outward to the left and right at the same time — no keyframes needed.

   The id is load-bearing: `.carousel-item.active` is (0,2,0), so a class-only
   override would lose to it no matter where it sat in the file. */
#services-preview .carousel-wrapper.is-stacked .carousel-item {
  transform: translateX(0) scale(0.86);
  opacity: 1;
}

/* -- 2. No uplift on hover --------------------------------------------------
   Site rule: buttons and cards darken and react to the click, they never lift.
   `.service-card:hover` is (0,2,0) and `.landscape-card` inherits it, so the
   kill has to be (1,2,0). The red glow and border stay. */
#services-preview .landscape-card:hover {
  transform: none;
}

/* -- 3. Artwork behaves like the Services page's ---------------------------
   The carousel holder now carries `.service-image-trigger`, which brings
   `cursor: zoom-in` and the shared delegated click handler with it. Two
   deliberate exclusions:

   - no Preview pill, and therefore no scrim. `.service-image-trigger::after`
     exists only to make that pill legible; without the pill it would just
     darken the bottom half of every offer image.
   - `object-fit` is left alone. `.card-img-holder img` is later in the file at
     equal specificity, so it keeps `contain` and service artwork is not newly
     cropped. Only the hover timing is pinned, so the zoom matches the Services
     page's 0.45s instead of the carousel's 0.5s. */
#services-preview .landscape-card .service-image-trigger::after {
  content: none;
}

#services-preview .card-img-holder.service-image-trigger img {
  transition: transform 0.45s ease;
}

/* ==========================================================================
   ACCOUNT TIP POPOVER — the profile dropdown's sibling
   --------------------------------------------------------------------------
   `#googlePwdFloatingCard`, built by `showGooglePasswordTip()` in main.js, is
   the nudge that asks a Google-signed-in customer to set a password. It used to
   carry its own chrome (16px radius, pink hairline, 290px) two elements below a
   profile dropdown that had already been migrated to `ux-dlg`. It is now that
   dropdown's sibling: same 344px width, same 8px radius, same maroon band, same
   cream footer strip, same paired shadow, same arrow.

   Two structural rules, both deliberate:

   1. Every selector here carries the id AND the card class, so each part rule is
      (1,3,0) and outranks the system's own `:is(.ux-dlg, #aptPrivacyModal,
      #aptConfirmModal) .ux-dlg__card .part`, which is (1,2,0) — id-level despite
      looking like three classes. Source order alone would be too fragile.
   2. There is not one `@media` block in this section, and there must never be.
      The tip's visibility is DATA-gated (a Google account with no password of its
      own) and never width-gated; it belongs on a 1440px laptop exactly as much as
      on a phone. Scoping the root through `.user-profile` as well means a
      single-class rule in responsive.css — which loads after this file — cannot
      re-hide or re-shrink it either.
   ========================================================================== */

.user-profile #googlePwdFloatingCard.google-pwd-floating-card {
  /* Anchored under the avatar, not centred over the page: this is a passing
     suggestion, so it must not take the screen hostage. */
  position: absolute;
  top: calc(100% + 14px);
  right: 0;
  z-index: 2100;
  /* Stated explicitly so no future layout rule can collapse it. */
  display: block;
  width: min(344px, calc(100vw - 24px));
  max-width: calc(100vw - 24px);
  /* The root is now a bare anchor — the card inside paints all the chrome. */
  padding: 0;
  background: none;
  border: 0;
  text-align: left;
  pointer-events: auto;
  /* Gutter for every shared part. The system default is clamp(22px, 5.6vw, 34px),
     sized for a 520px dialog; 17px is what the dropdown uses and what a 344px
     popover can afford. */
  --ux-dlg-pad-x: 17px;
  animation: googleCardFadeIn 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.user-profile #googlePwdFloatingCard.google-pwd-floating-card.fade-out {
  animation: googleCardFadeOut 0.3s ease forwards;
  pointer-events: none;
}

@keyframes googleCardFadeIn {
  0% {
    opacity: 0;
    transform: translateY(-8px) scale(0.95);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes googleCardFadeOut {
  0% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
  100% {
    opacity: 0;
    transform: translateY(-8px) scale(0.95);
  }
}

/* The pointer belongs to the root, not the card: the card is `overflow: hidden`
   and would clip it. Same geometry and the same maroon as the dropdown's, because
   an arrow has to match the surface it points out of — here that is the band. */
.user-profile #googlePwdFloatingCard.google-pwd-floating-card::before {
  content: "";
  position: absolute;
  top: -10px;
  right: 18px;
  width: 16px;
  height: 16px;
  background: var(--customer-wine-hover);
  border-top: 1px solid rgba(107, 32, 43, 0.16);
  border-left: 1px solid rgba(107, 32, 43, 0.16);
  transform: rotate(45deg);
}

/* The card: the dropdown's exact border, radius and paired shadow. `max-height`
   is released because a popover this small never scrolls, and the system's
   `min(760px, 100dvh - 30px)` would otherwise make the body a scroll container. */
#googlePwdFloatingCard .google-pwd-card.ux-dlg__card {
  width: 100%;
  max-width: 100%;
  max-height: none;
  border: 1px solid rgba(107, 32, 43, 0.16);
  border-radius: var(--ux-dlg-radius);
  box-shadow:
    0 26px 60px rgba(45, 12, 12, 0.26),
    0 2px 6px rgba(45, 12, 12, 0.08);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* Band: tighter than a dialog's, and only as much right padding as the smaller
   close button actually needs (the system reserves 64px for a 36px control). */
#googlePwdFloatingCard .google-pwd-card .ux-dlg__head {
  padding: 14px 17px;
  padding-right: 54px;
}

/* The decorative ring scaled to a band a third the height. */
#googlePwdFloatingCard .google-pwd-card .ux-dlg__head::after {
  right: -30px;
  bottom: -84px;
  width: 130px;
  height: 130px;
  box-shadow: 0 0 0 18px rgba(241, 237, 18, 0.05);
}

/* 34px rather than 44px — one notch under the dropdown's 42px avatar, which is
   the right hierarchy: the avatar identifies you, this only annotates. */
#googlePwdFloatingCard .google-pwd-card .ux-dlg__badge {
  width: 34px;
  height: 34px;
  margin-right: 12px;
  font-size: 15px;
  box-shadow: 0 6px 14px rgba(45, 12, 12, 0.22);
}

#googlePwdFloatingCard .google-pwd-card .ux-dlg__eyebrow {
  margin-bottom: 2px;
  font-size: 9.5px;
  letter-spacing: 0.12em;
}

/* The dialog title is `clamp(17px, 3.6vw, 21px)`, which on a laptop resolves to
   21px and would wrap this headline over three lines inside 344px. */
#googlePwdFloatingCard .google-pwd-card .ux-dlg__title {
  font-size: 15.5px;
  line-height: 1.3;
}

/* 34px rather than the system's 36px: one notch down for a popover, and still on
   the 34px tap floor the rest of this file holds to, so no responsive layer has
   to reach in and re-float it. The head reserves 54px on the right, which clears
   a 34px button sitting 10px in. */
#googlePwdFloatingCard .google-pwd-card .ux-dlg__close {
  top: 10px;
  right: 10px;
  width: 34px;
  height: 34px;
  font-size: 18px;
}

/* `overflow: visible` because there is nothing to scroll — three lines of copy.
   Leaving it `auto` would give the popover an inner scrollbar gutter on Windows. */
#googlePwdFloatingCard .google-pwd-card .ux-dlg__body {
  padding: 15px 17px 14px;
  overflow: visible;
}

#googlePwdFloatingCard .google-pwd-card .ux-dlg__text {
  font-size: 13px;
  line-height: 1.55;
}

/* Cream footer strip, same as the dropdown's logout row. The system reserves
   `max(18px, env(safe-area-inset-bottom))` at the bottom for sheets that sit on
   the screen edge; an anchored popover never does. */
#googlePwdFloatingCard .google-pwd-card .ux-dlg__foot {
  gap: 8px;
  padding: 12px 17px 13px;
}

/* The pills keep their shape, colours, colour-only hover and press scale from the
   system — only the scale changes, because 51px tall and 14.5px type would put
   "Set Password" over two lines in a 167px grid track. */
#googlePwdFloatingCard .google-pwd-card .ux-dlg__btn {
  gap: 6px;
  min-height: 44px;
  padding: 12px 14px;
  font-size: 13px;
  letter-spacing: 0.1px;
}

#googlePwdFloatingCard .google-pwd-card .ux-dlg__btn i {
  font-size: 11px;
}

/* ===========================================================================
   CUSTOMER SITE — PHONE / SMALL-TABLET SCROLL PERFORMANCE PASS (<=900px)
   ---------------------------------------------------------------------------
   A 120Hz phone was rendering the customer pages at 40-50 fps. The frame
   budget on that panel is 8.3ms, not 16.7ms, so effects that merely look
   expensive at 60Hz miss the deadline outright. Measured causes, all of them
   per-frame GPU/paint cost rather than script cost:

     * `.site-header` is sticky, translucent and `backdrop-filter: blur(16px)`
       across the full viewport width. Page content changes behind it on every
       scroll frame, so the GPU re-samples the backdrop, re-runs a ~42
       device-px kernel over ~214k device px, blends, then re-rasterises a 36px
       shadow — 120 times a second. This is the single largest cost on the site.
       FIXED AT SOURCE in §9: the opaque recipe below is now what `.site-header`
       declares at every width (:12839), so the two header rules in this block
       are redundant no-ops kept only because deleting them would change which
       declaration wins on a page this pass is not re-measuring.
     * fifteen more live `backdrop-filter` surfaces in the default scroll path,
       two of which repeat per card (`.service-card`, `.shop-card`), so a full
       products grid puts a dozen simultaneous 16px blurs on screen.
     * `.carousel-track { perspective: 1000px }` promoting every carousel item
       to its own layer for the whole visit, for depth no phone state renders.
     * service skeletons formerly animating background-position. Their shimmer
       now uses transform, with fewer placeholder cards rendered on phones.

   Desktop keeps the frosted-glass design untouched: everything below is inside
   the media query. (No longer true of the header — §9 made that one opaque at
   every width because the owner could see the page through it.)

   Note on the fills. For every surface except the two named further down, the
   backdrop is a *static* section gradient — nothing moves behind it — and
   blurring a smooth gradient returns the same gradient, so dropping the blur
   is a visual no-op and the existing translucent fills are left exactly as
   they are. Only the two surfaces whose backdrop genuinely changes get a
   tuned substitute:
     * `.site-header` — sticky, so real content scrolls under it. It becomes
       opaque white, which is what the 0.9 alpha already resolved to at rest
       and also lets the browser skip painting everything behind it.
     * `.service-image-preview-label` — sits over a photograph, where the blur
       was doing real work for legibility, so its alpha goes 0.64 -> 0.78.

   `.customer-rate-prompt-popup` is a third surface with a genuinely moving
   backdrop — it is `position: fixed`, so the page really does scroll behind it
   — but its own fill is a 0.98/0.95 white gradient, which hides the blur almost
   entirely. It is in the list below and needs no substitute.

   Several of these selectors are declared in groups, and the whole group has to
   be named here or the blur simply survives on the siblings:
   `.about-container` and `.vision-container` share their rule with
   `.mission-container` (:13045), and `.contact-info-card` shares its rule with
   `.contact-form-card` (:6404).

   Deliberately NOT using `will-change` here — it would pin permanent
   compositing layers on elements that never animate, which is the very
   problem the `main.css` reveal system releases on settle.
   ========================================================================= */
@media (max-width: 900px) {
  .site-header,
  .hero-graphic,
  .about-container,
  .vision-container,
  .mission-container,
  .features-card,
  .services-top-bar,
  .services-grid .service-card,
  .products-toolbar,
  .shop-card,
  .contact-info-card,
  .contact-form-card,
  .btn-appointment,
  .hero-sdg-btn,
  .service-image-preview-label,
  .customer-rate-prompt-popup {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  /* Opaque, and a hairline instead of a 36px blur radius re-rasterised across
     the whole viewport width every frame. At 0.08 alpha that shadow was not
     visible; the hairline keeps the separation from the page.

     `--customer-paper`, not `#ffffff`: this arm predates the paper ladder, so it
     was quietly handing phones the one solid white surface the palette rule
     removed everywhere else. Desktop read rgb(253, 250, 246) and anything at or
     below 900px read rgb(255, 255, 255) — the same header in two different
     colours depending on the viewport. */
  .site-header {
    background: var(--customer-paper);
    box-shadow:
      0 1px 0 rgba(176, 28, 28, 0.1),
      0 2px 6px rgba(58, 18, 18, 0.06);
  }

  /* Over a photo the blur was carrying the legibility, so return it as alpha. */
  .service-image-preview-label {
    background: rgba(41, 14, 11, 0.78);
  }

  /* The badge's phone-only shadow trim used to live here (two layers instead of
     three). The home-page minimalism round took the desktop rule itself down to
     one `0 8px 18px` layer on a solid white plate, so this override would only
     have put the inset white line back on phones. Its entry in the
     `backdrop-filter: none` list above stays — a cheap no-op now that the base
     rule no longer declares a blur, and one less thing to get wrong if the base
     rule is ever revisited. */

  /* Glass CTA on the hero: the hero backdrop is a smooth gradient, so the
     12px blur contributed nothing. A hair more alpha keeps the same weight.
     `rgba(247, 242, 236, …)`, not white: same alpha, but the tint is the paper
     colour, so the phone CTA is the same warm veil the desktop rule paints
     instead of a cool one. */
  .btn-appointment {
    background: rgba(247, 242, 236, 0.12);
  }

  /* No phone item state uses depth — `.carousel-item` is translateX + scale +
     opacity only — so the 3D context was promoting every item to its own
     layer for the whole visit and rendering no perspective at all. */
  .carousel-track {
    perspective: none;
  }
}

/* ===========================================================================
   CUSTOMER SITE — PHONE GESTURE COST: VISION / MISSION DECK (<=900px)
   ---------------------------------------------------------------------------
   Follow-up to the scroll pass above. Dragging a photo aside in "Our Vision"
   still stuttered on the 120Hz phone, and only sometimes — which is two
   separate problems: a fixed per-frame cost at the two *ends* of the gesture,
   and a one-off cost the first time each photo is actually shown.

   The drag itself was already correct: `.vm-deck__card.is-dragging` kills the
   transition and the move handler writes nothing but a compositable
   `transform`. What was expensive sat on either side of it:

     * `.is-vanishing` animates `filter: blur(6px)` for 460ms on the largest
       element in the section (up to 550x344 CSS px, ~910x569 device px at this
       DPR) while that same element is translating up to 4x the drag distance,
       rotating, and scaling to 0.7. A blur is a separable multi-tap kernel, and
       an *animated* radius means no frame's raster can be reused — while the
       layer's raster scale is changing every frame too. This is the single
       largest cost in the gesture, and it lands on the frames right after the
       finger lifts, which is where a stutter is most visible.
     * the press fires a burst on the gesture's very first frame: three
       simultaneous `transform` + `filter: brightness()` transitions plus a
       `box-shadow: 0 18px 44px` that is neither compositable nor in the
       transition list, so it is a one-frame full repaint of the biggest element
       plus a ~62px growth of its layer bounds. Exactly where the drag felt like
       it "caught". Dropping `.is-peeking` on release repaints it a second time.
     * `will-change: transform, opacity` is unconditional on every card. Ten
       photos per deck across two decks is 20 permanently pinned compositor
       layers on the device with the least GPU memory, and the cards parked at
       `data-slot="hidden"` are `opacity: 0` and cannot move, so those pins buy
       nothing whatsoever.

   Desktop is untouched — everything is inside the media queries — and the
   per-slot `brightness()` *values* are left alone at every width, so a deck at
   rest renders identically. Only the easing of those values is dropped, so the
   depth shading snaps in one frame instead of tweening for 420ms.

   The two transition-list rewrites are gated on `prefers-reduced-motion:
   no-preference` on purpose: the reduce arm earlier in this file sets both of
   these rules to a plain 0.2s opacity fade at the same specificity, and a
   later-but-equal rule would silently take that away from phone users who asked
   for less motion. `filter: none` is safe to state unconditionally because the
   reduce arm asks for exactly that.

   `responsive.css` loads after this file but declares only `aspect-ratio` and
   `transform` on the deck — never `transition`, `filter`, `box-shadow` or
   `will-change` — so nothing below can be undone downstream.

   The JS half of this fix is in `home-page/main.js`: cloned deck images now
   carry `decoding="async"` and are decoded up front instead of having their
   first base64 decode land mid-throw, and a touch drag damps its vertical
   component so a diagonal swipe cannot move the card with the finger *and*
   with the page's own permitted `pan-y` scroll.
   ========================================================================= */
@media (max-width: 900px) {
  /* Fly away and fade, but do not blur. Same call the `prefers-reduced-motion`
     arm above already makes on this very rule. */
  .vm-deck__card.is-vanishing {
    filter: none;
  }

  /* Same press affordance, ~60% less repainted area and layer-bounds growth. */
  .vm-deck--vision.has-stack.is-peeking .vm-deck__card[data-slot="0"] {
    box-shadow: 0 8px 18px rgba(43, 43, 49, 0.18);
  }

  /* A hidden card is `opacity: 0` and cannot move, so pinning a layer for it is
     pure GPU memory. Takes the two decks from 20 pinned layers down to 6. The
     compositor promotes a card the moment it is actually given a transition. */
  .vm-deck.has-stack .vm-deck__card[data-slot="hidden"] {
    will-change: auto;
  }
}

@media (max-width: 900px) and (prefers-reduced-motion: no-preference) {
  /* `filter` out of the vanish transition list, so the throw is transform +
     opacity only. Both remaining properties are compositable. */
  .vm-deck__card.is-vanishing {
    transition:
      transform 0.46s cubic-bezier(0.2, 0.7, 0.3, 1),
      opacity 0.46s ease-in;
  }

  /* `filter` out of the base transition list. The per-slot `brightness()`
     values are untouched, so the stack looks the same at rest — the depth
     shading just arrives in one frame instead of easing for 420ms. */
  .vm-deck.has-stack .vm-deck__card {
    transition:
      transform 0.42s cubic-bezier(0.22, 0.61, 0.36, 1),
      opacity 0.42s ease;
  }
}

/* =============================================================================
   §8  APPOINTMENT — FMRC MINIMALISM
   =============================================================================

   The five-step appointment flow was the last surface on the customer site
   still speaking the site's *first* visual language: nine unrelated greys, four
   off-palette accents, and every radius from 4px to 999px on screen at once.

   Everything below finishes it in the language the rest of the site already
   speaks — the one the owner already approved on the success dialog that fires
   the instant Step 5 submits (`.success-card`, and the `--ux-dlg-*` tokens at
   the top of the dialog system). That card is a white slab with a gold hairline
   edge, a maroon band head carrying a pale-gold eyebrow, a cream note panel and
   a cream footer strip. Step 5 and the dialog that follows it now share those
   exact values, so the handoff between them is invisible.

   Because of that, this whole section introduces **no new colour and no new
   font**. Every hex below is already somewhere else in this file.

   The one rule that turns "a lot of nice colours" into minimalism:

       ONE ACCENT, ONE PLACE.

   Gold is allowed on exactly two things at any given moment — the *current*
   step circle and the primary button. Everything else on screen is maroon,
   cream or ink. Finished steps are maroon, not gold. Reminder numerals are
   maroon, not gold. Selected days are maroon, not gold. That is the whole
   trick, and it is why the eye always knows where it is.

   This section is last in the file on purpose: it is the winning layer for the
   states it introduces, so nothing here needs `!important` — and nothing here
   has it. If a rule below ever seems to need one, the value belongs in the
   block that owns it (the base appointment layer, the calendar layer, or the
   top-level fluid layer that owns every size and radius) rather than here.
   ============================================================================= */

/* --- §8.1  The ladder ------------------------------------------------------ */

/* Seventeen names, every one of them a value that already existed in the repo.
   Declared on :root rather than on `#appointmentFlow` because three rules in
   the base appointment layer (`.apt-progress-wrapper`, `.apt-card`, and the
   reminder grid's copy colour) reference them from outside this section. Custom
   properties do not care about source order, only about inheritance, so
   declaring them here at the end of the file is correct. */
:root {
  /* Surfaces. 8px is `--ux-card-radius` and `--ux-dlg-radius`; 6px is
     `--ux-dlg-radius-sm`. Buttons are exempt — the site's pill
     (`.ux-dlg__btn`, `.apt-btn`) is a deliberate, separate shape. */
  --apt-radius: 8px;
  --apt-radius-sm: 6px;

  /* Ink. Three levels, and only three: heading, body, muted. This replaces the
     nine greys (#333 #444 #555 #666 #888 #aaa #ccc #ddd #eaeaea) and the two
     rival slates the flow used to mix. */
  --apt-head: var(--customer-wine);
  --apt-body: #4b5563; /* = --ux-dlg-text  */
  --apt-muted: #6d7480;

  /* Lines. The cream hairline is the success card's footer rule; the warm one
     is what separates a white card from the maroon stage behind it. */
  --apt-line: #f0e8c8; /* = --ux-dlg-foot-line */
  --apt-line-warm: rgba(107, 32, 43, 0.1);

  /* Panels. Byte-for-byte `.success-reference` and `.success-card__footer`. */
  --apt-panel: #fffbed;
  --apt-panel-edge: #eadc9a;
  --apt-strip: #fffdf4; /* = --ux-dlg-foot-bg */

  /* Gold, and the four inks that are legible on or beside it. */
  --apt-gold: #f1ed12;
  --apt-gold-ink: #5f0d0d;
  --apt-gold-soft: #fff8d2;
  --apt-gold-eyebrow: #f5ef8e; /* = --ux-dlg-eyebrow */
  --apt-gold-label: #77610d; /* = .success-reference span */

  /* One red on the whole site. Replaces #d32f2f here and #b3261e in
     responsive.css. */
  --apt-danger: var(--customer-danger);
}

/* --- §8.2  The progress rail ---------------------------------------------- */

/* Three states, and the difference between them is legible at a glance from
   across a desk:

       done      solid maroon disc, white check
       current   gold disc, dark ink, one soft ring
       upcoming  hairline outline on near-nothing, dimmed

   Before this, `main.js` wrote `icon.style.background = "#4caf50"` onto every
   circle at every step change. Inline styles beat stylesheets, so the gold
   active state this file has carried since the beginning had literally never
   rendered — and because the test was `index < stepNumber`, the step you were
   *on* and every step you had *finished* painted identically. The rail could
   not tell you where you were. The JS now toggles `.is-done` / `.is-current`
   and writes no inline style at all, so the three rules below are the only
   thing painting it.

   No `scale()` anywhere. Growing the current circle is what made the strip
   shudder as it scroll-snapped on a phone, and a rail that changes size is the
   opposite of minimal. Colour alone carries the state. */

/* Finished. Maroon, never gold — see the one-accent rule at the top of §8. */
.apt-step.is-done .apt-icon {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  box-shadow: none;
}

/* The check replaces the step's own glyph rather than being added beside it, so
   no markup in main.html changes and no icon has to be swapped by script. */
.apt-step.is-done .apt-icon svg {
  display: none;
}

.apt-step.is-done .apt-icon::after {
  content: "✓";
  font-size: 1.05em;
  font-weight: 800;
  line-height: 1;
}

/* Where you are. The only gold circle on screen, and — with the primary button
   — one of only two gold things anywhere in the flow. The ring is a flat
   4px spread rather than the 30px bloom this rule used to carry: a bloom on a
   dark field reads as a glow effect, a ring reads as a marker. */
.apt-step.is-current .apt-icon {
  background: var(--apt-gold);
  border-color: var(--apt-gold);
  /* Dark olive-ink, already in the file as the badge ink family: gold needs a
     near-black to stay legible, and pure black would look like a hole. */
  color: #2d2a12;
  box-shadow: 0 0 0 4px rgba(241, 237, 18, 0.18);
}

/* Not yet. Dimming the whole step — label, circle and caption together — is
   what makes the finished/current pair read as "ahead of" the rest, without
   adding a fourth colour to the strip. */
.apt-step:not(.is-done):not(.is-current) {
  opacity: 0.62;
}

/* The connector fills behind you as you go. Sibling order in the markup is
   step → line → step, so the adjacent-sibling combinator is enough and no
   `:has()` (or JS) is needed. */
.apt-step.is-done + .apt-line {
  background: var(--customer-wine-hover);
}

/* --- §8.3  Inputs, scoped ------------------------------------------------- */

/* `.c-input` is shared with the contact form, the profile modal and checkout, so
   its 18px base radius is not this task's to change — flattening it globally
   would silently restyle three other pages. Scoped to the flow instead, which
   is the only place the radius collapse has been agreed.
   (The same one-liner can be promoted site-wide in the home-page round.)

   `#222833` goes with it: it is the last of the cold neutrals, and inside this
   flow every other piece of body copy is already `--apt-body`. */
#appointmentFlow .c-input,
.apt-nested-modal .c-input {
  border-radius: var(--apt-radius);
  color: var(--apt-body);
}

/* --- §8.4  Step 3 loose copy ---------------------------------------------- */

/* Four inline properties off the wrapper and three off the counter. The
   counter's `display:none` stays inline because main.js toggles it, and
   `#maxLimitMsg`'s does too for the same reason — everything else that was
   inline is here. */
.slot-counter-wrapper {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

#slotCounter {
  font-size: 13px;
  font-weight: 600;
  color: var(--apt-muted);
}

/* main.js writes this element's colour inline on every call (`showSlotMessage`),
   so a `color` here would never apply — the two call-site literals are the
   palette values `#b01c1c` for a real conflict and `#77610d` for the reminder.
   Everything else about the line is styled here. */
#maxLimitMsg {
  font-size: 12px;
  font-weight: 700;
  line-height: 1.45;
  margin-top: 10px;
}

/* --- §8.5  The ticket head, the details grid, the QR rail, the note ------- */

/* Every class below replaces an inline style. Step 5 carried about fifteen of
   them, which is why it and Step 4 had drifted into two different objects: the
   same heading was 24px in one and 24px-then-16px in the other, the same
   schedule value was 18px maroon here and 16px near-black there, and the status
   chip was translucent white in one place and #4caf50 in the other. */

.ticket-eyebrow {
  display: block;
  color: var(--apt-gold-eyebrow);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.13em;
  line-height: 1.3;
  text-transform: uppercase;
}

.ticket-no {
  margin: 5px 0 0;
  color: var(--customer-paper-sink);
  font-weight: 800;
  line-height: 1.2;
}

/* Two states, one shape. Draft is quiet — a label on glass, because nothing has
   happened yet. Issued is the gold badge on maroon ink, exactly the pairing the
   success dialog's own badge uses (--ux-dlg-badge on --ux-dlg-badge-ink). That
   retires #4caf50 from the customer site.

   This does not break §8's one-accent rule: both live on the maroon band, where
   pale gold and gold *are* the band's own accent family — the success dialog
   sets a #f5ef8e eyebrow and an #f1ed12 badge on this very gradient. The band is
   one place. */
.ticket-chip {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.1em;
  line-height: 1.4;
  text-transform: uppercase;
  white-space: nowrap;
}

.ticket-chip--draft {
  background: rgba(247, 242, 236, 0.16);
  color: var(--apt-gold-soft);
  box-shadow: inset 0 0 0 1px rgba(247, 242, 236, 0.26);
}

.ticket-chip--issued {
  background: var(--apt-gold);
  color: var(--customer-wine);
}

/* Step 5's details, formerly an inline `grid-template-columns: 1fr 1fr` that
   needed two media-query overrides to survive a phone. 190px is chosen so the
   tracks fall to one column at roughly the same width the deleted 440px arm
   used to force it. */
.ticket-grid {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  align-content: start;
  gap: 14px;
}

/* Inside the grid, `gap` already does the job `.ticket-row`'s own margin does
   for Step 4's stacked rows — keeping both put 34px between every field. */
.ticket-grid > .ticket-row {
  margin-bottom: 0;
}

.ticket-qr {
  display: flex;
  width: 150px;
  flex: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding-left: 20px;
  border-left: 1px solid var(--apt-line);
  text-align: center;
}

/* Keeps its missing `src` on purpose — see the comment on the element itself. */
.ticket-qr__img {
  display: block;
  width: 100%;
  height: auto;
  mix-blend-mode: multiply;
}

.ticket-qr__caption {
  color: var(--apt-muted);
  font-size: 10px;
  font-weight: 600;
  line-height: 1.4;
}

/* The site's link rule: underlined, darker on hover and darker again on press,
   never a lift. */
.ticket-qr__link {
  color: var(--customer-wine);
  font-size: 10px;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color 0.18s ease;
}

.ticket-qr__link:hover {
  color: var(--customer-wine-hover);
}

.ticket-qr__link:active {
  color: var(--customer-wine-hover);
}

/* Byte for byte the success card's footer strip (main.css:16796) — #fffdf4 on a
   #f0e8c8 hairline. Step 5 ends on the same strip the dialog that follows it
   opens on. */
.ticket-note {
  padding: 15px 25px;
  border-top: 1px solid var(--apt-line);
  background: var(--apt-strip);
  color: var(--apt-body);
  font-size: 12px;
  line-height: 1.6;
}

.ticket-note strong {
  color: var(--customer-wine);
  font-weight: 800;
}

/* The one value on the ticket that is allowed to be bigger than its neighbours:
   the schedule. Step 4 set it inline at 18px and Step 5 at 16px in near-black,
   so the same field looked like two different fields. */
.t-value--lead {
  color: var(--customer-wine);
  font-size: clamp(15px, 2.2vw, 17px);
  font-weight: 800;
}

/* Notes read as secondary, not as an aside — italic in a data grid is noise. */
.t-value--note {
  color: var(--apt-muted);
  font-style: normal;
}

/* --- §8.6  The header bar -------------------------------------------------- */

/* The title sits ON the stage, not on a bar of its own.

   Two earlier attempts were both wrong for the same reason — they gave the header
   a fill. responsive.css:114 gave it a three-stop gradient whose bottom 22% was
   fully transparent, so card text scrolled up *into* the title; replacing that
   with one flat #3d0808 fixed the fade but drew a hard-edged dark rectangle
   across a stage that is a 135deg gradient (main.css:4522) — flat and dark on the
   left, #851313 and light on the right, so the band matched the field it sat on
   in exactly one place and read as a separate slab everywhere else.

   No fill at all is the only thing that blends at every pixel of a gradient: the
   background *is* the background. That also makes the fade structurally
   impossible rather than merely overridden — with no fill there is nothing for
   content to show through, so the header no longer needs to be sticky to hide it
   (responsive.css no longer sets `position: sticky`), and static at every width
   means the two viewports finally agree. The 1px rgba(255,255,255,.14) bottom
   border already on main.css:4560 is the only separator, and a hairline over a
   gradient blends where a filled box cannot.

   Dropping the fill also retires the bleed: with nothing to paint there is
   nothing to bleed, so the negative-margin pair is gone too. The two padding
   tokens stay — `.apt-container` in the fluid layer is their only consumer now,
   and at <=280px `--ux-gutter` becomes 7px for both at once.

   `--apt-dot` is the step circle's diameter and `--apt-rail-top` the offset that
   puts `.apt-line` through its centre; both are re-declared per band in §8.9. */
#appointmentFlow {
  --apt-pad-l: max(var(--ux-gutter), var(--ux-safe-l));
  --apt-pad-r: max(var(--ux-gutter), var(--ux-safe-r));
  --apt-dot: clamp(32px, 9vw, 48px);
  /* Measured, not guessed: the "STEP n" line box is 12.8px at its 11px clamp
     ceiling, and the gap is the same `clamp(4px, 0.8vw, 8px)` the fluid layer
     puts on `.apt-step`, restated here so the offset tracks it exactly instead of
     drifting at the band's floor. Only the >=901px arm consumes it. */
  --apt-lbl: calc(12.8px + clamp(4px, 0.8vw, 8px));
  --apt-rail-top: calc(var(--apt-dot) / 2 - 1.5px);
}

#appointmentFlow .apt-header-top {
  background: none;
}

/* --- §8.7  Footer actions on one row -------------------------------------- */

/* The owner sees "2 lines per button" on a phone: that is the *pair* stacking,
   not a label wrapping. Two rules stack it — main.css:7267 (<=900px) and
   main.css:15840 (<=640px), both `column-reverse` + `.apt-btn { width: 100% }`.
   §8 is the last layer in the file, so a plain rule wins both ties on source
   order and no `!important` is needed anywhere here.

   341px is the floor because 360px Androids and every modern iPhone
   (375/390/393/402/414/430) must sit on one row, while <=340px is this site's
   established very-small band. At 375px the widest row (Step 5, "Download
   Receipt" + "Finish Transaction") measured 340.4px against 343.5px of content
   width before this block — it fit by 3px, i.e. by luck. The type and padding
   trim below takes it to ~309px, which is headroom.

   Scoped to `.apt-footer-actions .apt-btn` on purpose: the five `.apt-btn`s
   *outside* the footer (main.html:1352 and the nested-dialog buttons at
   1390/1397/1429/1436) keep their full-width stacking. `padding-inline` is a
   longhand, so it overrides only the inline sides of the fluid layer's `padding`
   shorthand at 15519 — the block padding and `min-height: var(--ux-tap)` (the
   44px tap target) survive intact. */
@media (min-width: 341px) and (max-width: 900px) {
  .apt-footer-actions {
    flex-direction: row;
    flex-wrap: nowrap;
    gap: 8px;
  }

  .apt-footer-actions .apt-btn {
    flex: 1 1 0;
    min-width: 0;
    width: auto;
    white-space: nowrap;
    padding-inline: clamp(10px, 3.2vw, 18px);
    font-size: clamp(12px, 3.4vw, 13px);
  }
}

/* Below the floor, labels may wrap again — at 280px and under, responsive.css:589
   turns the row into a grid and a nowrap label would be the thing that overflows. */
@media (max-width: 340px) {
  .apt-footer-actions .apt-btn {
    white-space: normal;
  }
}

/* Every footer pair sits side by side, so both halves have to be the same height,
   and before this rule none of them were. `#appointmentFlow .apt-btn-back` takes a
   2px border (main.css:13963) while `.apt-btn-blue` takes 1px (13928) and
   `.apt-btn-outline` — Step 5's "Download Receipt" — takes 1px too, which measured
   47.2px against 45.6px: a 1.6px step between two touching buttons. Matching the
   width is the fix that changes nothing else, because each border keeps the colour
   it already had. Scoped inside `#appointmentFlow` (1,1,0 — the same weight as
   13928, won on source order), so `#aptPrivacyModal`, `#aptConfirmModal` and
   `#successAppointmentModal`, which all live outside the overlay, are untouched. */
#appointmentFlow .apt-btn-blue,
#appointmentFlow .apt-btn-outline {
  border-width: 2px;
}

/* --- §8.8  Locked buttons look locked -------------------------------------- */

/* No disabled styling for `.apt-btn` existed anywhere in the file, so while the
   submit was in flight the button still read as a live gold CTA that simply
   ignored taps. `.apt-overlay button:not(:disabled)` (main.css:5904) already
   withholds the hover and press states; this supplies the only thing missing,
   which is the resting appearance. */
#appointmentFlow .apt-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* --- §8.9  One rail at every width, and a flow that fits a laptop ---------- */

/* Three defects lived in the step rail, and all three came from the same cause:
   its geometry was hand-tuned five separate times (main.css 7227/7735/7772,
   responsive.css 395/442, the fluid layer 15433) with no shared measurement, so
   no two bands agreed.

   1. The connector missed the circle it connects. `.apt-line` was offset with a
      literal `margin-top` per band while the circle's diameter was clamped
      fluidly, so the two could only line up at the one width each literal was
      typed at. Measured: -19.5px at 1536px, +2.5px at 768px, +5.8px at 393px.
   2. The captions were unreadable on a phone — 7.86px at 393px, tuned down until
      "Appointment" fit one line, which is the wrong thing to optimise. And
      between 641px and 768px `.apt-progress-wrapper span` (main.css:4923) hid
      them outright, so a tablet showed five unlabelled circles.
   3. "STEP n" was visible from 769px to 900px and hidden below 768px purely
      because one selector had a `:last-child` and the other did not.

   The fix is to declare the geometry once and derive from it. `--apt-dot` is the
   circle's diameter, `--apt-rail-top` the offset that puts the 3px line through
   its centre, and `--apt-lbl` the height the "STEP n" line adds above the circle
   when it is shown (an 11px uppercase line box measures 14px, plus the step's
   8px column gap). One `.apt-icon` rule and one `.apt-line` rule read those
   tokens, so re-pointing a band is a token change, not a re-tune. */

#appointmentFlow .apt-icon {
  width: var(--apt-dot);
  height: var(--apt-dot);
}

#appointmentFlow .apt-line {
  margin-top: var(--apt-rail-top);
}

/* The caption is the only thing naming a step below 901px, so it is never
   hidden. This is the rule that ends the 641-768px blackout. */
#appointmentFlow .apt-step span:last-child {
  display: block;
}

/* Two states, both written down. Below 901px the caption carries the step and
   "STEP n" would only repeat the number already inside the circle. */
@media (max-width: 900px) {
  #appointmentFlow .apt-step .step-label {
    display: none;
  }
}

/* Phones: legibility first, one line second.

   Five captions side by side at 393px leave ~52px per step. "Appointment" needs
   ~72px at 10px and ~52px only at 7.4px — so no font size a person can read on a
   phone fits it on one line, and the band had been solving that by shrinking the
   type to 7.86px. Two readable lines beat one unreadable one, so the caption
   floor goes up to 9px and the four long words get a soft hyphen in main.html:
   they break as "Appoint-/ment" rather than wherever `overflow-wrap: anywhere`
   happens to land.

   The connectors grow with the same trade. At `clamp(4px, 1.6vw, 10px)` they
   were 6.3px hairlines that read as dashes; `3vw` gives 11.8px at 393px and
   still leaves the steps ~3.6px of slack over the widest wrapped fragment
   ("Complet-", ~49px at 10.2px). */
@media (max-width: 640px) {
  #appointmentFlow {
    --apt-dot: clamp(36px, 10.4vw, 44px);
  }

  #appointmentFlow .apt-line {
    flex: 0 0 clamp(8px, 3vw, 16px);
    min-width: 8px;
  }

  #appointmentFlow .apt-step span:last-child {
    font-size: clamp(9px, 2.6vw, 11px);
    line-height: 1.15;
  }
}

/* Below 340px the strip becomes a swipeable rail (main.css:16041), so the steps
   take a fixed basis again (responsive.css:432) and the connector has to stop
   flexing with the viewport or it eats the scroll width. */
@media (max-width: 340px) {
  #appointmentFlow .apt-line {
    flex: 0 0 12px;
    min-width: 12px;
  }
}

/* 280px and under is the site's ultra-narrow band; responsive.css sizes the
   circle to 30px there, which is now a token value like every other. */
@media (max-width: 280px) {
  #appointmentFlow {
    --apt-dot: 30px;
  }
}

/* Laptops: make Step 1 fit the screen it opens on.

   The owner's complaint is that the flow scrolls on a PC. It does, and only just:
   at 1536x748 — a 1080p Windows laptop at the default 125% scaling, which is the
   single most common desktop viewport there is — the five stacked boxes needed
   ~810px against 748px of `min-height: 100vh`. Nothing was oversized on its own;
   the flow was simply spaced for a 950px-tall monitor and never re-checked
   against a shorter one, so every gap was ~30px and six of them together were
   the overflow.

   Each value below is the same element's spacing taken down one step, not a
   redesign: the flow reads the same, it just stops asking for a scrollbar to
   show a single step. Steps with genuinely tall content (Step 2's form, Step 3's
   calendar) still scroll, which is correct — that is content, not chrome.

   `--apt-rail-top` gains `--apt-lbl` here because this is the only band where
   "STEP n" sits above the circle and pushes it down. */
@media (min-width: 901px) {
  #appointmentFlow {
    --apt-dot: 44px;
    --apt-rail-top: calc(var(--apt-lbl) + var(--apt-dot) / 2 - 1.5px);
  }

  #appointmentFlow .apt-container {
    padding-block: 14px 16px;
  }

  #appointmentFlow .apt-header-top {
    margin-top: 0;
    margin-bottom: 12px;
    padding-bottom: 12px;
  }

  /* The rail is the one box that must not touch the card under it: it is a
     translucent dark panel and the card is white paper, so at 10px the two read
     as one stacked object. 18px is not a new number — it is what the rail
     already leaves below itself at every width under 901px, so a phone and a PC
     now show the same gap here. Measured with Step 1 open, the flow still asks
     for no scrollbar at either laptop case this arm was tuned against: content
     ends at 629px of 658 at 1366x658, and 669px of 700 at 903x700. */
  #appointmentFlow .apt-progress-wrapper {
    padding-block: 8px;
    margin-bottom: 18px;
  }

  /* The card keeps a generous 24px of paper — every pixel above came out of the
     gaps between boxes, not out of the box a person is reading. */
  #appointmentFlow .apt-card {
    padding: 24px;
    margin-bottom: 14px;
  }

  #appointmentFlow .apt-footer-actions {
    margin-top: 12px;
    padding-bottom: 10px;
  }
}

/* --- §8.10  The stage reaches the real right edge --------------------------- */

/* The owner's screenshot shows a pale band down the right of the whole screen.
   It is not a card, a shadow or an overflow: it is the scrollbar gutter, and
   nothing the page can paint was ever inside it.

   Measured at an emulated 1907x950 with the flow open: the viewport is 1907,
   but `html`'s box is 1892, `body` is 1892, and `.apt-overlay` — `position:
   fixed; width: 100%` (main.css:4512) — resolves to 1892 as well, because
   `html { scrollbar-gutter: stable }` (main.css:14) permanently reserves ~15px
   and a fixed box is laid out in the initial containing block, which excludes
   it. `elementFromPoint` returns null across x=1893..1906: no element paints
   there at all, so what shows through is the canvas, which is body's
   `#fffdf9`. On a display at 125% scaling — the owner's, dpr 1.25 — those 15
   CSS px land as ~19 device px of cream beside a maroon stage.

   `100vw` is not the fix, and this is the measurement that matters most:
   with the gutter reserved, `100vw`, `100dvw`, `100svw` and `100lvw` all
   resolve to 1892.2. Viewport units shrink with the gutter in Chrome, so every
   one of them lands the overlay in exactly the same place it already is. A
   pseudo-element bleed or a flat slab behind the strip is worse still — the
   stage is a *gradient*, so any flat fill matches it at one scanline and reads
   as a seam everywhere else, which is the correction the owner already made
   once about the header.

   So the gutter is released for the one overlay that covers the entire screen,
   and `overflow: hidden` comes with it for two reasons. It is what guarantees
   no scrollbar can render in the space just released — and it closes a real
   bug: `body.style.overflow = "hidden"` never shortened body's box (still 4558
   tall here), so the document behind an open modal stayed scrollable and its
   scrollbar stayed draggable. Scoped with `:has()` to this overlay only,
   because the reserved gutter is what stops the page reflowing 15px under the
   site's translucent dialogs — the appointment stage is opaque and full-bleed,
   so it is the only one that can afford to give the gutter back. */
html:has(#appointmentFlow.show-modal) {
  overflow: hidden;
  scrollbar-gutter: auto;
}

/* With the stage now ending at the true viewport edge, its own scrollbar ends
   there too — and Chrome's default is a white track with a grey thumb, which
   would put the same pale band back on Steps 2 and 3 the moment their content
   is taller than the screen. This is the `.customer-rating-body` recipe
   (main.css:10806-10836) in the stage's own palette: transparent track, one
   translucent white thumb. `stable` keeps the gutter reserved *inside* the
   overlay, where the maroon paints under it, so the card stack sits in exactly
   the same place on a step that scrolls and a step that does not. */
#appointmentFlow {
  scrollbar-color: rgba(247, 242, 236, 0.3) transparent;
  scrollbar-gutter: stable;
  scrollbar-width: thin;
}

#appointmentFlow::-webkit-scrollbar {
  width: 7px;
}

#appointmentFlow::-webkit-scrollbar-track {
  background: transparent;
}

#appointmentFlow::-webkit-scrollbar-thumb {
  border: 2px solid transparent;
  border-radius: 999px;
  background: rgba(247, 242, 236, 0.32);
  background-clip: padding-box;
}

#appointmentFlow::-webkit-scrollbar-thumb:hover {
  background: rgba(247, 242, 236, 0.52);
  background-clip: padding-box;
}

/* =============================================================================
   §9  HOME PAGE — FMRC MINIMALISM
   =============================================================================

   With §8 done, the home page was the loudest surface left on the customer site.
   It still spoke the site's *first* visual language: 28-32px radii, translucent
   cream gradients, 60-70px bloom shadows, seventeen live `backdrop-filter`
   surfaces, a gold radial wash plus a 38px white grid overlay stacked on the
   footer, and two body greys three units apart (`#4b5260` here against
   `#4b5563` in the appointment tokens).

   The rule is §8's, unchanged:

       ONE ACCENT, ONE PLACE.

   On this page gold is spent on exactly two things — the Browse Products pill in
   the hero, and the 42x3 rule under each footer heading. Everything else is
   maroon, cream or ink. Per band: one surface, one hairline, at most one soft
   shadow, `--apt-radius` / `--apt-radius-sm`, pills only on buttons, and hover
   is a darker fill with `:active { scale(0.97) }` as the only motion.

   WHERE THIS SECTION IS. Almost nowhere — and that is deliberate. Unlike §8,
   which introduced its own states and could own them from the end of the file,
   every home-page value already had a home: the customer refresh block at
   :12819, the fluid `--ux-*` layer at :14581, the dropdown authority at :18302,
   and four `.site-header` / `.site-footer` arms in `responsive.css`. Restating
   those values in a trailing layer would have doubled each one and guaranteed
   the two copies drift. So the round was applied *in place*, rule by rule, and
   what follows is the record of it rather than a rule set. The two references to
   "§9" earlier in this file (:19479 and :19495, in the phone-performance banner)
   point here.

   NO NEW FONT, NO NEW COLOUR, and one new token — `--customer-wash` at :12819,
   added at the owner's request after the first pass read as too flat. Every hex
   the round introduced was already in the file.
   ============================================================================= */

/* --- §9.1  The maroon ladder ----------------------------------------------- */

/* Three maroons, and they are a ladder, not interchangeable shades:

     --customer-primary        #8b0000   a resting surface (the footer band)
     --customer-primary-strong #5f0d0d   type, and a button at rest (= --apt-head)
     #3d0808                             hovered or pressed, and nothing else

   The first pass flattened the footer to `#3d0808` on the reasoning that the
   darkest stop of the gradient it replaced was the safest single value to pick
   out of it. Across a full-width band that read as near-black, and the owner
   was right to call it unprofessional: nothing at rest should wear a hover
   colour. `--customer-wash` then puts a hint of the old diagonal back over the
   flat maroon — a ±10%/7% alpha overlay carried in `background-image` while
   `background-color` keeps the hue, so one wash serves the footer, the maroon
   buttons and the avatar discs, every existing `transition: background-color`
   keeps easing, and a hover stays a one-line colour swap. The trap that comes
   with it: a `background:` shorthand anywhere on a washed selector silently
   drops the wash, so those hovers use `background-color`. */

/* --- §9.2  Where the plan was overruled ------------------------------------ */

/* Four places, all for the same reason — the plan was written against the page
   as it reads with the default hero, and three of these surfaces sit on a
   background the *owner* controls (`hero_bg_type`, written inline by
   `applyHeroBackground()` at main.js:14250; CSS cannot see it and must not
   fight it).

   1. The footer is `--customer-primary`, not the planned `#3d0808` — the owner's
      correction above.
   2. Gradients were to be deleted outright; one shared alpha wash returns on
      maroon-family fills only. White and cream paper stays flat.
   3. `.scroll-indicator` (:397, :13142) keeps white at .82 rather than moving to
      `--apt-head`, and the SDG badge ring is a warm hairline rather than a white
      one: on the dark maroon default a maroon indicator would be invisible, and
      on a light hero a white ring on a white plate would be. Both values work
      either way round.
   4. `sdgPopIn` was changed from `both` to `backwards` (:17012). A filling
      animation outranks every normal declaration, so the badges' `:active` press
      could never render — the press the owner asked for was being swallowed by
      the entrance he asked to keep. `backwards` still fills the pre-start frame,
      and the base transform already equals the 100% keyframe.

   PRESERVED, untouched, and verified after the fact: the reveal-on-scroll system
   (main.js:601, main.css:6745) and the `--ux-gutter: clamp(12px, 4.2vw, 72px)`
   its horizontal offsets are derived from; `.is-stacked` and the What We Offer
   carousel; the `.vm-deck` drag gesture; `bounce`; `heroLogoBreathe`; the
   `.footer-container` `minmax(0, ...)` floors at :13305; every `applySettings()`
   element id; and every line of JavaScript on the page — this round wrote none.

   "Verified after the fact" is literal: the reveal block at :6745-:6831 was
   diffed against HEAD line by line and came back byte-identical, and no changed
   line in either stylesheet touches a declaration inside any system named above
   — the only diff hunks that mention them are these comments. */

/* --- §9.3  The paper ladder — white is not in this palette ------------------ */

/* The owner's second brief: "DONT PUT SOLID WHITE OR BLACK IN FONT COLORS, OR
   BACKGROUND COLORS OR ANY COLORS, JUST USE COLORS THAT I SEND TO YOU." Five
   reference screenshots came with it, and two of them are the whole rule: a warm
   off-white field, and a near-black-but-not-black heading on it.

   So `#ffffff` and `#000000` are retired from every surface this page renders,
   and three warm neutrals declared at :12831 stand in for them:

     --customer-paper      #fdfaf6   raised material — header, cards, slabs,
                                     dialog cards, popups, the mobile sidebar
     --customer-paper-sink #f7f2ec   the field those sit on, and the type colour
                                     on anything maroon (so it is both the page
                                     background and every "white" letter)
     --customer-paper-edge #efe6da   the neutral warm hairline
     --customer-ink-strong #2b2b31   the near-black from the screenshot

   Two papers rather than one is the whole trick: a card can separate from its
   band by tone alone, which is what lets the shadows shrink to one soft layer.
   Black shadows went with the white — every `rgba(0, 0, 0, a)` on this page is
   now `rgba(45, 12, 12, a)`, the same warm depth family §8 uses.

   Scoped, as asked, to what the home page paints. `main.css` is shared by all
   four customer pages, so the sweep was built from the other direction: every
   element *actually rendering* on the page whose computed background or colour
   resolved to pure white or black (157 hits, ~70 unique signatures), then a
   CSSOM rule-walker per hit to find which rule was winning. That is what caught
   `.profile-popup .profile-popup-link` — a (0,2,0) override two earlier edits
   had missed while both were editing the (0,1,0) rule below it. Literals that
   only paint on the products, services or contact pages were left alone. */

/* --- §9.4  Every dialog reaches the real right edge ------------------------- */

/* §8.10 solved this for the appointment stage and then argued the fix could not
   be generalised: "the reserved gutter is what stops the page reflowing 15px
   under the site's translucent dialogs — the appointment stage is opaque and
   full-bleed, so it is the only one that can afford to give the gutter back."
   The owner has now sent the same screenshot again, this time with My Account
   open, so that trade was called wrong. A permanent 15px band of cream beside
   every dialog is a defect the user sees and reports; a 15px reflow of already
   blurred, 55%-dimmed content, happening in the same frame as the scrim fades
   in, is one nobody has mentioned in four rounds of looking at the appointment
   flow — which runs this exact rule.

   Nothing else on the shelf works. Viewport units are measured out: with the
   gutter reserved, `100vw`, `100dvw`, `100svw` and `100lvw` all resolve to the
   *reduced* width, so an overlay sized in any of them lands exactly where it
   already is. Painting into the gutter is impossible by spec — the scrollport is
   the padding box minus the gutter, so page content is clipped out of it, and
   the only thing that reaches the strip is the canvas background. Recolouring
   that canvas is the one no-reflow option, and it fails on its own terms: the
   scrim is 55% ink over a *blurred* page, so its rendered colour runs from
   near-slate over the cream bands to near-maroon over the hero, and any single
   flat strip colour matches it on one scanline and seams on every other.

   The hook is the scroll-lock itself rather than a list of dialog classes.
   Every one of the ~19 open paths in main.js does `document.body.style.overflow
   = "hidden"`, and the two that use a class instead are named here. Keying on
   that means the gutter is released *exactly* while the scrollbar is gone — the
   two are the same event, so they can never drift, no future dialog has to
   remember to opt in, and the release lands after the 180ms close animation has
   finished restoring it rather than at the start of the fade-out. Both spellings
   of the inline serialisation are listed as cheap insurance.

   The dialog hooks on the end of the list are for the layers that never locked
   the body at all. `body.modal-open-state` is not mine — main.js:529-553 keeps
   it in sync with its own `headerBlockingSelectors` registry of sixteen
   full-screen layers (product/service/cart/checkout/lightbox/about-video/
   success/orders) via a MutationObserver, so borrowing it means a new overlay
   added to that array gets the gutter release for free. `.ux-dlg.show` picks up
   the two that are in neither list: `showLogoutConfirmModal()` (main.js:13807)
   and `showCustomerPopup()`'s `.admin-system-popup.ux-dlg` (main.js:184). The
   logout one is the case that forced this arm — it only toggles `.show`, so
   until now the page behind the logout confirm was still scrollable *and* still
   showed the band. For these two, `overflow: hidden` here *is* the scroll lock,
   which is why this rule is worth more than its original brief.

   `.show` leaves at the *start* of a fade-out, so on its own it would hand the
   15px back while the scrim was still half-opaque — the exact reflow this whole
   mechanism exists to prevent. The body-locking dialogs above are immune (their
   inline style is restored after the 180ms close). The logout modal gets the
   same protection from its inline `display`: main.js:13864 writes `display:
   flex` on open and only clears it to `none` 220ms after `.show` goes, so that
   attribute substring is precisely its open-through-fade-out window. The system
   popup has no equivalent latch and releases on `.show`; its fade is short and
   it is an informational Okay dialog, so the residual shift is acceptable there.

   Deliberately absent: `.status-modal.show` (main.css:10036 — an `align-items:
   flex-end`, `pointer-events: none` toast, not a modal; locking for it would
   shift the page 15px on every save confirmation), `.profile-popup.show`,
   `.guest-sign-in-trigger.is-open` and `.customer-rate-prompt-popup.show` (all
   anchored popovers, page stays scrollable), and `.global-loader-overlay.active`
   (would reflow the page during first paint). */
html:has(> body[style*="overflow: hidden"]),
html:has(> body[style*="overflow:hidden"]),
html:has(> body.sidebar-open),
html:has(> body.fmrc-announcement-open),
html:has(> body.modal-open-state),
html:has(.ux-dlg.show),
html:has(.ux-dlg--standalone[style*="display: flex"]) {
  overflow: hidden;
  scrollbar-gutter: auto;
}

/* `.customer-modal-overlay` (My Account, Change Password) is the one overlay on
   the site that scrolls itself, so with the gutter released its own scrollbar
   now lands on the true viewport edge — and Chrome's default track is white,
   which would put the band straight back on a tall dialog. Same recipe as
   `#appointmentFlow`, in cream: transparent track, one translucent thumb. No
   `scrollbar-gutter` here on purpose — a dialog that fits should stay centred in
   the viewport, not sit 7.5px left of centre for a scrollbar it never shows. */
.customer-modal-overlay {
  scrollbar-color: rgba(247, 242, 236, 0.32) transparent;
  scrollbar-width: thin;
}

.customer-modal-overlay::-webkit-scrollbar {
  width: 7px;
}

.customer-modal-overlay::-webkit-scrollbar-track {
  background: transparent;
}

.customer-modal-overlay::-webkit-scrollbar-thumb {
  border: 2px solid transparent;
  border-radius: 999px;
  background: rgba(247, 242, 236, 0.34);
  background-clip: padding-box;
}

.customer-modal-overlay::-webkit-scrollbar-thumb:hover {
  background: rgba(247, 242, 236, 0.54);
  background-clip: padding-box;
}

/* My Orders polish: compact sync status, raised counts and shared actions. */
#customerOrdersModal.ux-dlg .customer-orders-head > .customer-orders-sync-status {
  width: fit-content;
  flex: 0 0 auto;
  align-self: flex-start;
}

#customerOrdersModal.ux-dlg .customer-orders-modal.ux-dlg__card > .customer-orders-tabs {
  padding: 15px 5px 5px;
  border-color: var(--customer-paper-edge);
  border-radius: 10px;
  background: var(--customer-paper-sink);
}

#customerOrdersModal.ux-dlg .customer-orders-modal.ux-dlg__card > .customer-orders-tabs .customer-orders-tab {
  position: relative;
  justify-content: center;
  min-height: 42px;
  padding: 10px 12px;
  border: 1px solid transparent;
  border-radius: 7px;
  background: var(--customer-paper);
  color: var(--customer-wine);
  line-height: 1.2;
  box-shadow: none;
}

#customerOrdersModal.ux-dlg .customer-orders-modal.ux-dlg__card > .customer-orders-tabs .customer-orders-tab:hover {
  border-color: var(--customer-wine);
  background: var(--customer-paper-edge);
  color: var(--customer-wine);
  transform: none;
  box-shadow: none;
}

#customerOrdersModal.ux-dlg .customer-orders-modal.ux-dlg__card > .customer-orders-tabs .customer-orders-tab.active {
  border-color: var(--customer-wine);
  background: var(--customer-wine);
  color: var(--customer-paper-sink);
  box-shadow: none;
}

#customerOrdersModal.ux-dlg .customer-orders-tab .customer-orders-tab-count {
  position: absolute;
  top: -11px;
  right: 5px;
  min-width: 22px;
  height: 22px;
  padding: 0 5px;
  border: 2px solid var(--customer-paper-sink);
  border-radius: 999px;
  background: var(--customer-wine);
  color: var(--customer-paper-sink);
  font-size: 10px;
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

#customerOrdersModal.ux-dlg .customer-orders-tab .customer-orders-tab-count.is-empty {
  background: var(--customer-paper-edge);
  color: var(--customer-wine);
}

#customerOrdersModal.ux-dlg .customer-orders-tab.active .customer-orders-tab-count {
  background: var(--customer-paper-edge);
  color: var(--customer-wine);
}

#customerOrdersModal.ux-dlg .customer-orders-tabs .customer-orders-tab:focus-visible {
  outline: 2px solid var(--customer-wine);
  outline-offset: 2px;
}

/* Counts sit above the labels, leaving all eight desktop labels in one row. */
@media (min-width: 769px) {
  #customerOrdersModal.ux-dlg .customer-orders-modal.ux-dlg__card > .customer-orders-tabs {
    display: grid;
    grid-template-columns: repeat(8, minmax(0, 1fr));
    gap: 5px;
    overflow: visible;
    scroll-snap-type: none;
  }

  #customerOrdersModal.ux-dlg .customer-orders-modal.ux-dlg__card > .customer-orders-tabs .customer-orders-tab {
    width: 100%;
    min-width: 0;
    padding: 10px 3px;
    font-size: 0.73rem;
    letter-spacing: 0;
    scroll-snap-align: none;
  }
}

/* The phone strip still scrolls; leave clearance so its badges are not clipped. */
@media (max-width: 768px) {
  #customerOrdersModal.ux-dlg .customer-orders-modal.ux-dlg__card > #customerOrdersTabs.customer-orders-tabs {
    padding-top: 15px;
  }
}

/* One rectangular action recipe for cards and the order-related subdialogs.
   Header close buttons, image previews and rating stars keep their own shapes. */
:is(#customerOrdersModal, .customer-rating-overlay).ux-dlg .ux-dlg__card :is(
  .customer-order-actions > button,
  .customer-return-detail-actions > button,
  .customer-order-rate-btn,
  .customer-order-logistics-link,
  .customer-order-map-actions > a,
  .customer-order-waybill-copy,
  .customer-orders-empty-action,
  .ux-dlg__foot .ux-dlg__btn,
  .cgc-copy-btn,
  .cgc-qr-save,
  .cgc-openapp-btn,
  .cgc-review-proof,
  .customer-rating-upload
),
body:has(#customerOrdersModal.show) #customerSystemPopup.ux-dlg .ux-dlg__card .ux-dlg__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-width: 0;
  min-height: 42px;
  padding: 10px 14px;
  border: 1px solid var(--orders-action-border, var(--customer-wine));
  border-radius: 8px;
  background: var(--orders-action-bg, var(--customer-paper));
  color: var(--orders-action-color, var(--customer-wine));
  font-family: "Montserrat", "Poppins", sans-serif;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: 0;
  text-align: center;
  text-decoration: none;
  white-space: normal;
  box-shadow: none;
  filter: none;
  cursor: pointer;
  transition: background-color 0.16s ease, border-color 0.16s ease,
    color 0.16s ease, transform 0.1s ease;
}

:is(#customerOrdersModal, .customer-rating-overlay).ux-dlg .ux-dlg__card :is(
  .customer-order-pay-btn:not(.is-review),
  .customer-order-received-btn,
  .customer-order-rate-btn:not(.ghost),
  .customer-order-buy-again-btn,
  .customer-order-return-ship-btn,
  .ux-dlg__btn--primary,
  .ux-dlg__btn--danger,
  .cgc-openapp-btn
),
body:has(#customerOrdersModal.show) #customerSystemPopup.ux-dlg .ux-dlg__card :is(.ux-dlg__btn--primary, .ux-dlg__btn--danger) {
  --orders-action-bg: var(--customer-wine);
  --orders-action-color: var(--customer-paper-sink);
  --orders-action-hover-bg: var(--customer-wine-hover);
  --orders-action-hover-color: var(--customer-paper-sink);
}

:is(#customerOrdersModal, .customer-rating-overlay).ux-dlg .ux-dlg__card :is(
  .customer-order-actions > button,
  .customer-return-detail-actions > button,
  .customer-order-rate-btn,
  .customer-order-logistics-link,
  .customer-order-map-actions > a,
  .customer-order-waybill-copy,
  .customer-orders-empty-action,
  .ux-dlg__foot .ux-dlg__btn,
  .cgc-copy-btn,
  .cgc-qr-save,
  .cgc-openapp-btn,
  .cgc-review-proof,
  .customer-rating-upload
):hover:not(:disabled),
body:has(#customerOrdersModal.show) #customerSystemPopup.ux-dlg .ux-dlg__card .ux-dlg__btn:hover:not(:disabled) {
  border-color: var(--orders-action-border, var(--customer-wine));
  background: var(--orders-action-hover-bg, var(--customer-paper-edge));
  color: var(--orders-action-hover-color, var(--customer-wine));
  transform: none;
  box-shadow: none;
  filter: none;
}

:is(#customerOrdersModal, .customer-rating-overlay).ux-dlg .ux-dlg__card :is(
  .customer-order-actions > button,
  .customer-return-detail-actions > button,
  .customer-order-rate-btn,
  .customer-order-logistics-link,
  .customer-order-map-actions > a,
  .customer-order-waybill-copy,
  .customer-orders-empty-action,
  .ux-dlg__foot .ux-dlg__btn,
  .cgc-copy-btn,
  .cgc-qr-save,
  .cgc-openapp-btn,
  .cgc-review-proof,
  .customer-rating-upload
):active:not(:disabled),
body:has(#customerOrdersModal.show) #customerSystemPopup.ux-dlg .ux-dlg__card .ux-dlg__btn:active:not(:disabled),
#customerOrdersModal.ux-dlg .customer-orders-tabs .customer-orders-tab:active {
  transform: scale(0.98);
  box-shadow: none;
}

:is(#customerOrdersModal, .customer-rating-overlay).ux-dlg .ux-dlg__card :is(button, a):not(.ux-dlg__head *):focus-visible,
body:has(#customerOrdersModal.show) #customerSystemPopup.ux-dlg .ux-dlg__card .ux-dlg__btn:focus-visible {
  outline: 2px solid var(--customer-wine);
  outline-offset: 3px;
}

:is(#customerOrdersModal, .customer-rating-overlay).ux-dlg .ux-dlg__card button:disabled,
body:has(#customerOrdersModal.show) #customerSystemPopup.ux-dlg .ux-dlg__card .ux-dlg__btn:disabled {
  opacity: 0.58;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

#customerOrdersModal .customer-order-pay-btn.is-review,
#customerOrdersModal .customer-order-cancel-btn.is-pending,
#customerOrdersModal .customer-order-return-btn.is-blocked {
  --orders-action-bg: var(--customer-paper-sink);
  --orders-action-border: var(--customer-paper-edge);
  --orders-action-color: var(--customer-ink-strong);
  --orders-action-hover-bg: var(--customer-paper-edge);
  --orders-action-hover-color: var(--customer-ink-strong);
}

/* Compact utility controls share the palette and squared corners. */
.customer-rating-overlay.ux-dlg .customer-return-qty {
  border-color: var(--customer-paper-edge);
  border-radius: 8px;
  background: var(--customer-paper);
}

.customer-rating-overlay.ux-dlg .customer-return-qty button {
  width: 32px;
  height: 32px;
  border-radius: 5px;
  color: var(--customer-wine);
}

.customer-rating-overlay.ux-dlg .customer-return-qty button:hover:not(:disabled) {
  background: var(--customer-wine);
  color: var(--customer-paper-sink);
  transform: none;
}

.customer-rating-overlay.ux-dlg .customer-rating-media-thumb.is-new button {
  width: 26px;
  height: 26px;
  border-radius: 5px;
  background: var(--customer-wine);
  color: var(--customer-paper-sink);
}

.customer-rating-overlay.ux-dlg .customer-rating-media-thumb.is-new button:hover {
  background: var(--customer-wine-hover);
  transform: none;
}

/* Reference button palette: yellow primary, cream secondary, in-place press.
   Browse Products and apt-btn-blue use solid yellow; outlined buttons hover
   to cream (#f7f2ec), never pure white. No gradient anywhere. */
.hero-buttons .btn-browse:not(:disabled) {
  background: #eef224;
  border-color: #eef224;
  color: #3d0808;
  box-shadow: none;
  transition: background-color 0.18s ease, border-color 0.18s ease,
    color 0.18s ease, transform 0.1s ease;
}

.hero-buttons .btn-appointment:not(:disabled) {
  background: rgba(247, 242, 236, 0.14);
  border-color: rgba(247, 242, 236, 0.82);
  color: #f7f2ec;
  box-shadow: none;
  transition: background-color 0.18s ease, border-color 0.18s ease,
    color 0.18s ease, transform 0.1s ease;
}

:is(#appointmentFlow, #aptPrivacyModal, #aptConfirmModal, #aptLeaveConfirmModal, #orderSuccessModal, #successAppointmentModal) .apt-btn-blue:not(:disabled),
:is(#btnGoToPrivacy, #aptNextBtn, #aptNextBtnStep3, #aptSubmitBtn, #aptFinishBtn, #acceptPrivacyBtn, #acceptConfirmBtn, #acceptLeaveAptBtn):not(:disabled),
.apt-btn-blue:not(:disabled) {
  background: #eef224;
  border-color: #eef224;
  color: #3d0808;
  box-shadow: none;
  transition: background-color 0.18s ease, border-color 0.18s ease,
    color 0.18s ease, transform 0.1s ease;
}

.view-all-btn:not(:disabled),
.guest-auth-login:not(:disabled),
.guest-access-btn.login:not(:disabled),
:is(.ux-dlg, #aptPrivacyModal, #aptConfirmModal) .ux-dlg__card .ux-dlg__btn--primary:not(.apt-btn-blue):not(:disabled) {
  background: var(--customer-wine);
  border-color: var(--customer-wine);
  color: var(--customer-paper-sink);
  box-shadow: none;
  transition: background-color 0.18s ease, border-color 0.18s ease,
    color 0.18s ease, transform 0.1s ease;
}

.btn-browse:hover:not(:disabled) {
  background: #c8cc00;
  border-color: #c8cc00;
  color: #3d0808;
  transform: none;
  box-shadow: none;
}

.btn-appointment:hover:not(:disabled) {
  background: #f7f2ec;
  border-color: #f7f2ec;
  color: #3d0808;
  transform: none;
  box-shadow: none;
}

:is(#appointmentFlow, #aptPrivacyModal, #aptConfirmModal, #aptLeaveConfirmModal, #orderSuccessModal, #successAppointmentModal) .apt-btn-blue:hover:not(:disabled),
:is(#btnGoToPrivacy, #aptNextBtn, #aptNextBtnStep3, #aptSubmitBtn, #aptFinishBtn, #acceptPrivacyBtn, #acceptConfirmBtn, #acceptLeaveAptBtn):hover:not(:disabled),
:is(.apt-btn-blue):hover:not(:disabled) {
  background: #c8cc00 !important;
  border-color: #c8cc00 !important;
  color: #3d0808 !important;
  transform: none;
  box-shadow: none;
}

:is(.view-all-btn, .guest-auth-login, .guest-access-btn.login, .ux-dlg__btn--primary:not(.apt-btn-blue)):hover:not(:disabled) {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  transform: none;
  box-shadow: none;
}

:is(#appointmentFlow, #aptPrivacyModal, #aptConfirmModal, #aptLeaveConfirmModal, #orderSuccessModal, #successAppointmentModal) .apt-btn-blue:active:not(:disabled),
:is(#btnGoToPrivacy, #aptNextBtn, #aptNextBtnStep3, #aptSubmitBtn, #aptFinishBtn, #acceptPrivacyBtn, #acceptConfirmBtn, #acceptLeaveAptBtn):active:not(:disabled),
.btn-browse:active:not(:disabled),
.apt-btn-blue:active:not(:disabled) {
  background: #b0b400 !important;
  border-color: #b0b400 !important;
  color: #3d0808 !important;
  transform: scale(0.97);
  box-shadow: none;
}

.btn-appointment:active:not(:disabled) {
  background: #efe6da;
  border-color: #efe6da;
  color: #3d0808;
  transform: scale(0.97);
  box-shadow: none;
}

:is(.view-all-btn, .guest-auth-login, .guest-access-btn.login, .ux-dlg__btn--primary:not(.apt-btn-blue)):active:not(:disabled) {
  background: var(--customer-wine-active);
  border-color: var(--customer-wine-active);
  transform: scale(0.97);
  box-shadow: none;
}

/* These modal actions must override the shared primary resting fill above. */
#announcementModal.ux-dlg .ux-dlg__card #announcementModalClose:is(:hover, :focus-visible):not(:disabled),
#guestAccessModal.ux-dlg .ux-dlg__card .guest-access-btn.login:is(:hover, :focus-visible):not(:disabled) {
  background: var(--customer-wine-hover);
  border-color: var(--customer-wine-hover);
  color: var(--customer-paper-sink);
  transform: none;
  box-shadow: none;
}

#announcementModal.ux-dlg .ux-dlg__card #announcementModalClose:active:not(:disabled),
#guestAccessModal.ux-dlg .ux-dlg__card .guest-access-btn.login:active:not(:disabled) {
  background: var(--customer-wine-active);
  border-color: var(--customer-wine-active);
  transform: scale(0.97);
  box-shadow: none;
}

/* Keep the same press feedback on the existing product and form actions. */
:is(.action-btn, .modal-btn, .btn-place-order, .contact-submit-btn, .apt-btn, .ux-dlg__btn):active:not(:disabled):not(.disabled) {
  transform: scale(0.97);
}

@media (prefers-reduced-motion: reduce) {
  :is(.btn-browse, .btn-appointment, .view-all-btn, .guest-auth-login, .guest-access-btn, .action-btn, .modal-btn, .btn-place-order, .contact-submit-btn, .apt-btn, .ux-dlg__btn) {
    transition-duration: 0.01ms !important;
  }
}

.customer-rate-prompt-popup .customer-rate-prompt-link {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  margin-top: 5px;
  padding: 6px 10px;
  border: 1px solid var(--customer-wine);
  border-radius: 8px;
  background: var(--customer-paper);
  color: var(--customer-wine);
  text-decoration: none;
  transition: background-color 0.16s ease, color 0.16s ease;
}

.customer-rate-prompt-popup .customer-rate-prompt-link:hover {
  background: var(--customer-paper-edge);
  color: var(--customer-wine-hover);
  transform: none;
}
