  body {
    min-height: max(884px, 100dvh);
  }
  html { scroll-behavior: smooth; }
  ::selection { background: #1d1b20; color: #fdf7ff; }

  /* Scroll-reveal */
  .reveal {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1);
  }
  .reveal.is-visible { opacity: 1; transform: none; }

  /* View transition */
  .view-enter { animation: viewIn .45s cubic-bezier(.16,1,.3,1) both; }
  @keyframes viewIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

  /* Product grid item fade when filtered */
  .p-card { animation: cardIn .45s cubic-bezier(.16,1,.3,1) both; }
  @keyframes cardIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

  @media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    .reveal, .view-enter, .p-card { opacity: 1 !important; transform: none !important; animation: none !important; transition: none !important; }
  }
  

/* ------------------------------ Carousel ------------------------------
   Native scroll-snap. Works without JavaScript (becomes a horizontal
   scroll strip); JS only adds the arrows and the pagination dots. */
.carousel {
  display: flex;
  gap: 24px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding-bottom: 2px;
}
.carousel::-webkit-scrollbar { display: none; }

.carousel > * {
  scroll-snap-align: start;
  flex: 0 0 86%;
}
@media (min-width: 640px) { .carousel > * { flex-basis: 48%; } }
@media (min-width: 1024px) { .carousel > * { flex-basis: 31.5%; } }

.carousel-dot {
  width: 24px;
  height: 3px;
  background: #cbc4d2;
  transition: background-color .3s ease, width .3s ease;
}
.carousel-dot[aria-current="true"] { background: #1d1b20; width: 40px; }

.carousel-btn:disabled { opacity: .3; cursor: default; }

/* Gentle float, borrowed as a hover accent rather than a constant motion */
@media (prefers-reduced-motion: no-preference) {
  .float-hover { transition: transform .5s cubic-bezier(.16,1,.3,1); }
  .float-hover:hover { transform: translateY(-6px); }
}

/* --------------------------- Soft depth ---------------------------
   DESIGN.md permits one exception to the flat rule: a subtle, highly
   diffused shadow on hover or selection. Used sparingly on cards. */
.lift { transition: box-shadow .4s ease, border-color .3s ease; }
.lift:hover { box-shadow: 0 4px 20px rgba(0, 0, 0, .05); }

@media (prefers-reduced-motion: reduce) {
  .lift, .float-hover { transition: none; }
  .lift:hover, .float-hover:hover { box-shadow: none; transform: none; }
}

/* --------------------------- Display figures ---------------------------
   Playfair Display ships old-style figures by default: 6 and 8 rise above
   the cap line while 3, 4, 5, 7 and 9 drop below the baseline. That reads
   beautifully in running text but makes large statistics look uneven, so
   the serif face is switched to lining figures wherever it is used. */
.font-brand-serif {
  font-variant-numeric: lining-nums;
  font-feature-settings: "lnum" 1;
}

/* Visually hidden but read by screen readers */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* =====================================================================
   Softened surface treatment

   The original design system called for sharp corners and no shadows.
   That call has been reversed deliberately: rounded corners and diffused
   elevation now define the card language across the site.
   ===================================================================== */
:root {
  --r-card: 16px;
  --r-media: 14px;
  --r-btn: 10px;
  --shadow-rest: 0 1px 2px rgba(29, 27, 32, .04), 0 6px 20px rgba(29, 27, 32, .05);
  --shadow-hover: 0 2px 6px rgba(29, 27, 32, .06), 0 18px 44px rgba(29, 27, 32, .11);
}

.card {
  border-radius: var(--r-card);
  box-shadow: var(--shadow-rest);
  transition: box-shadow .35s ease, transform .35s cubic-bezier(.16, 1, .3, 1), border-color .3s ease;
}
.card:hover { box-shadow: var(--shadow-hover); transform: translateY(-4px); }

/* Cards that should glow without floating (map panel, contact column) */
.card-static { border-radius: var(--r-card); box-shadow: var(--shadow-rest); }

.media { border-radius: var(--r-media); overflow: hidden; }

/* Buttons, inputs and chips pick up a smaller radius */
.btn-r { border-radius: var(--r-btn); }
.chip-r { border-radius: 999px; }

/* Soft depth for the sticky header once the page scrolls */
header.is-stuck { box-shadow: 0 1px 0 rgba(29, 27, 32, .06), 0 8px 24px rgba(29, 27, 32, .06); }

@media (prefers-reduced-motion: reduce) {
  .card { transition: none; }
  .card:hover { transform: none; }
}

/* ------------------------- Touch targets -------------------------
   The pagination dots are deliberately thin, so the tappable area is
   grown invisibly around them instead of enlarging the bar itself. */
.carousel-dot { position: relative; }
.carousel-dot::after {
  content: '';
  position: absolute;
  inset: -21px -4px;
}

/* Comfortable minimum hit area on touch screens */
@media (max-width: 767px) {
  .tap { min-height: 44px; min-width: 44px; }
  .tap-row { min-height: 48px; }
}

/* --------------------------- Video play button ---------------------------
   Sits over a photograph, so it carries its own shadow to stay legible
   whatever is behind it, and the triangle is filled rather than outlined. */
.play-btn {
  box-shadow: 0 10px 34px rgba(0, 0, 0, .38), 0 2px 6px rgba(0, 0, 0, .22);
}
.play-btn .material-symbols-outlined {
  font-variation-settings: 'FILL' 1, 'wght' 500;
}

/* ---------------------- Product angle switcher ----------------------
   Every model is photographed from several sides. The grid card stacks
   those frames and lets the viewer step through them in place, so
   comparing two models no longer means opening and closing each one.

   Without JavaScript the controls stay hidden and the card keeps the
   single lead photograph it always had; app.js marks a card .shots-ready
   once the switcher is wired up. */
.shot-frame {
  opacity: 0;
  transition: opacity .45s ease, transform .7s cubic-bezier(.16, 1, .3, 1);
}
.shot-frame.is-current { opacity: 1; }

.shot-ctl { display: none; }
.shots-ready .shot-ctl { display: flex; }
.shots-ready [data-shot-count] { display: none; }

/* Arrows stay out of the way until the card is hovered or focused.
   Touch screens have no hover state, so there they are always shown. */
.shot-nav {
  opacity: 0;
  box-shadow: 0 1px 2px rgba(29, 27, 32, .12), 0 4px 12px rgba(29, 27, 32, .10);
  transition: opacity .25s ease, background-color .25s ease;
}
.p-card:hover .shot-nav,
.shot-nav:focus-visible { opacity: 1; }
@media (hover: none) { .shot-nav { opacity: 1; } }

.shot-dot {
  width: 16px;
  height: 3px;
  border-radius: 999px;
  background: #cbc4d2;
  transition: background-color .3s ease, width .3s ease;
}
.shot-dot[aria-current="true"] { background: #1d1b20; width: 26px; }

/* The bars are deliberately thin, so the tappable area is grown around
   them rather than the bar itself being enlarged. */
.shot-dot { position: relative; }
.shot-dot::after { content: ''; position: absolute; inset: -14px -3px; }

@media (prefers-reduced-motion: reduce) {
  .shot-frame, .shot-nav, .shot-dot { transition: none; }
}
