/* =====================================================================
   Shared interactive components. Patterns adapted from 21st.dev-style
   React components and rebuilt in plain CSS/JS: shiny button, spotlight
   tiles, blur-fade reveal, animated step tabs with progress, gallery.
   ===================================================================== */

/* ---------- Shiny button (sheen sweep) ---------- */
.btn--shine { position: relative; overflow: hidden; isolation: isolate; }
.btn--shine::after {
  content: ''; position: absolute; top: -40%; bottom: -40%; left: -30%; width: 40%;
  background: linear-gradient(100deg, transparent 0%, rgb(255 255 255 / 0.55) 50%, transparent 100%);
  transform: translateX(-160%) skewX(-18deg);
  animation: shine 4.5s ease-in-out 1.2s infinite;
  pointer-events: none;
}
@keyframes shine {
  0% { transform: translateX(-160%) skewX(-18deg); }
  35%, 100% { transform: translateX(520%) skewX(-18deg); }
}

/* ---------- Rise-and-fade reveal on scroll ----------
   This used to blur from 6px as well. A blur transition on something the size of the
   product grid means the browser re-blurs that whole area every frame for 0.7s, which
   is the one thing on the page that could still stutter on a slow machine. The lift
   and the fade read the same and cost nothing: opacity and transform only. */
.reveal {
  opacity: 0; transform: translateY(18px) scale(0.985);
  transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1), transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: calc(var(--i, 0) * 90ms);
}
.is-in > .reveal, .no-observer .reveal { opacity: 1; transform: none; }

/* ---------- Spotlight tiles ("Good to know") ---------- */
.know { padding-block: clamp(3rem, 7vw, 5.5rem); }
.tiles { list-style: none; margin: 0; padding: 0; display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.tile {
  --mx: 50%; --my: 50%;
  position: relative; isolation: isolate; overflow: hidden;
  display: grid; gap: 0.6rem; align-content: start;
  padding: 1.4rem;
  border: 1px solid var(--border); border-radius: var(--radius-card);
  background: var(--surface);
  transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.3s ease;
}
.tile::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: radial-gradient(260px circle at var(--mx) var(--my), color-mix(in srgb, var(--accent) 22%, transparent), transparent 65%);
  opacity: 0; transition: opacity 0.35s ease;
}
.tile:hover { transform: translateY(-4px); border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.tile:hover::before { opacity: 1; }
.tile__icon {
  display: grid; place-items: center; width: 46px; height: 46px; border-radius: 12px;
  background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent);
}
.tile__icon svg { width: 26px; height: 26px; }
.tile:hover .tile__icon svg { animation: icon-wiggle 0.7s cubic-bezier(0.34, 1.56, 0.64, 1); }
.tile--drive:hover .tile__icon svg { animation: icon-drive 0.8s cubic-bezier(0.34, 1.56, 0.64, 1); }
.tile--spin:hover .tile__icon svg { animation: icon-spin 0.7s cubic-bezier(0.34, 1.56, 0.64, 1); }
.tile--swing:hover .tile__icon svg { animation: icon-swing 0.8s ease-in-out; transform-origin: 30% 20%; }
@keyframes icon-wiggle { 0%, 100% { transform: none; } 30% { transform: scale(1.15) rotate(-8deg); } 60% { transform: scale(1.05) rotate(6deg); } }
@keyframes icon-drive { 0% { transform: translateX(-12px); opacity: 0.4; } 100% { transform: none; opacity: 1; } }
@keyframes icon-spin { to { transform: rotate(-360deg); } }
@keyframes icon-swing { 0%, 100% { transform: rotate(0); } 25% { transform: rotate(-16deg); } 60% { transform: rotate(10deg); } }
.tile h3 { font-size: 1.15rem; }
.tile p { color: var(--muted); font-size: 0.98rem; }
.tile a { color: var(--accent); font-weight: 700; }

/* ---------- Product gallery ---------- */
.gallery { display: grid; gap: 0.75rem; justify-items: center; width: 100%; }
.gallery__main { position: relative; width: min(100%, 440px); aspect-ratio: 5 / 4; }
.gallery__main img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; object-position: center;
  opacity: 0; transform: scale(0.98);
  transition: opacity 0.45s ease, transform 0.45s ease;
  filter: drop-shadow(0 22px 34px rgb(0 0 0 / 0.35));
}
.gallery__main img.is-current { opacity: 1; transform: none; animation: float 6s ease-in-out infinite; }
.gallery__thumbs { display: flex; gap: 0.5rem; list-style: none; padding: 0; margin: 0; }
.gallery__thumb {
  width: 64px; height: 64px; padding: 4px;
  border: 2px solid var(--border); border-radius: 12px; background: var(--surface);
  transition: border-color 0.25s ease, transform 0.25s ease;
}
.gallery__thumb:hover { transform: translateY(-2px); }
.gallery__thumb img { width: 100%; height: 100%; object-fit: cover; border-radius: 8px; }
.gallery__thumb[aria-pressed="true"] { border-color: var(--accent); }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  .btn--shine::after { display: none; }
  .gallery__main img.is-current { animation: none; }
}


/* ---------- Photos on product pages ---------- */
.product-art.is-photo { filter: drop-shadow(0 26px 40px rgb(0 0 0 / 0.5)); }
.gallery--compact { justify-items: start; }
.gallery--compact .gallery__main { width: min(100%, 360px); aspect-ratio: 1; }
.gallery--compact .gallery__thumb { width: 52px; height: 52px; }
.offer .gallery { margin-bottom: 0.25rem; }

/* ---------- Small notes under panels ---------- */
.page-note { margin-top: 1.5rem; }
.checkout { display: grid; gap: 1rem; margin-top: 0.5rem; }
.checkout .form-status { margin: 0; }

/* ---------- Season collection grid ---------- */
.catalog-grid { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fill, minmax(min(100%, 258px), 1fr)); }
.catalog-card {
  display: grid; gap: 0.85rem; align-content: start;
  padding: clamp(1.1rem, 2.4vw, 1.5rem);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-card);
  transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.3s ease;
}
.catalog-card:hover { transform: translateY(-4px); border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
/* The picture is pinned inside its own box so it can never spill onto the title.
   A percentage height on a centred grid item did not resolve and the image rendered
   197px tall inside a 172px box, overlapping the name underneath. */
.catalog-card__media { position: relative; height: clamp(130px, 17vw, 172px); border-radius: var(--radius-input); }
.catalog-card__media img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; object-position: center bottom;
  filter: drop-shadow(0 14px 22px rgb(0 0 0 / 0.45));
  animation: card-bob 7s ease-in-out infinite; animation-delay: calc(var(--i, 0) * -0.9s);
}
@keyframes card-bob {
  0%, 100% { transform: translateY(0) rotate(-0.5deg); }
  50%      { transform: translateY(-6px) rotate(0.5deg); }
}
.catalog-card:hover .catalog-card__media img { animation-play-state: paused; }
.catalog-card__body { display: grid; gap: 0.6rem; }
/* Legibility. The name and the description were both set small and the description sat
   in muted grey, which made a grid of seven products hard to read at a glance. The name
   is bigger and tighter, the description is full-size body text in the main text colour
   rather than the muted one, and the price is calmer so it stops shouting over the name. */
.catalog-card__title {
  font-size: clamp(1.3rem, 1.1rem + 0.6vw, 1.6rem);
  line-height: 1.2;
  letter-spacing: -0.005em;
}
.catalog-card__summary {
  color: var(--text); font-size: 1rem; line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* inside a card the price is one line of information among several, not the headline
   it is on a product page, so it is brought down to sit with the name */
.catalog-card .price__amount { font-size: clamp(1.5rem, 1.25rem + 0.7vw, 1.85rem); }
.catalog-card .price__note { font-size: 0.94rem; }
.catalog-card .price__fine { font-size: 0.82rem; opacity: 0.85; }
.catalog-card .price { gap: 0.25rem 0.5rem; }
/* The two buttons came to 290.6px inside a 289px card, so they wrapped onto separate
   lines and made every card 50px taller than it needed to be. Trimming the side padding
   inside cards puts them back on one row with room to spare; they still wrap on narrow
   phones, where stacked is the right answer anyway. */
.catalog-card__actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.catalog-card__actions .btn { padding-inline: 1.05rem; }
.hero--compact { padding-bottom: clamp(1.5rem, 4vw, 2.5rem); }
.hero--compact .hero__copy { max-width: 60ch; }
@media (prefers-reduced-motion: reduce) { .catalog-card__media img { animation: none; } }

/* ---------- Tiles stay alive without the mouse: slow float, passing light, idle icons ---------- */
.tile { animation: tile-float 7s ease-in-out infinite; animation-delay: calc(var(--i, 0) * -1.6s); }
@keyframes tile-float { 0%, 100% { translate: 0 0; } 50% { translate: 0 -6px; } }
.tile::after {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(115deg, transparent 42%, rgb(255 255 255 / 0.10) 50%, transparent 58%);
  transform: translateX(-130%);
  animation: tile-sheen 9s ease-in-out infinite; animation-delay: calc(var(--i, 0) * 1.4s + 1.5s);
}
@keyframes tile-sheen { 0% { transform: translateX(-130%); } 22% { transform: translateX(130%); } 100% { transform: translateX(130%); } }
/* The glow used to be an animated box-shadow. A shadow cannot be composited, so all
   twelve icons repainted on every frame for ever -- the single most expensive thing on
   the page. It is now a ring drawn once in an ::after and pulsed with opacity and
   scale, which the compositor handles with no repainting at all. */
.tile__icon { position: relative; }
.tile__icon::after {
  content: ''; position: absolute; inset: -6px; border-radius: inherit; pointer-events: none;
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 14%, transparent);
  opacity: 0;
  animation: icon-glow 4s ease-in-out infinite; animation-delay: calc(var(--i, 0) * -0.9s);
}
@keyframes icon-glow {
  0%, 100% { opacity: 0;   transform: scale(0.88); }
  50%      { opacity: 1;   transform: scale(1); }
}
.tile__icon svg { animation: icon-idle 6s ease-in-out infinite; animation-delay: calc(var(--i, 0) * -1.3s); }
@keyframes icon-idle {
  0%, 78%, 100% { transform: none; }
  84% { transform: translateY(-4px) rotate(-7deg); }
  90% { transform: translateY(0) rotate(6deg); }
  95% { transform: translateY(-2px) rotate(0); }
}
.tile--drive .tile__icon svg { animation-name: icon-idle-drive; }
@keyframes icon-idle-drive { 0%, 78%, 100% { transform: none; } 84% { transform: translateX(-6px); } 92% { transform: translateX(5px); } }
.tile--spin .tile__icon svg { animation-name: icon-idle-spin; }
@keyframes icon-idle-spin { 0%, 78%, 100% { transform: rotate(0); } 96% { transform: rotate(-360deg); } }
.tile--swing .tile__icon svg { animation-name: icon-idle-swing; transform-origin: 30% 20%; }
@keyframes icon-idle-swing { 0%, 78%, 100% { transform: rotate(0); } 84% { transform: rotate(-16deg); } 90% { transform: rotate(10deg); } 95% { transform: rotate(-4deg); } }
@media (prefers-reduced-motion: reduce) {
  .tile, .tile::after, .tile__icon, .tile__icon svg { animation: none; }
}

/* ---------- "A closer look" photo pair ---------- */
.views { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }
.view-card {
  display: grid; gap: 0.85rem;
  padding: clamp(1rem, 3vw, 1.5rem);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-card);
  transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.3s ease;
}
.view-card:hover { transform: translateY(-4px); border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.view-card img { width: 100%; height: auto; border-radius: var(--radius-input); }
.view-card p { color: var(--muted); font-size: 0.98rem; }

/* ---------- Deal and sample flags on product cards ---------- */
.catalog-card__media { position: relative; }
.catalog-card__flag, .catalog-card__sample {
  position: absolute; top: 0.25rem; padding: 0.25rem 0.6rem;
  border-radius: var(--radius-pill); font-size: 0.78rem; font-weight: 800;
  letter-spacing: 0.03em; white-space: nowrap;
}
.catalog-card__flag { left: 0.25rem; background: var(--red); color: #fff; }
.catalog-card__sample { right: 0.25rem; background: var(--bg-2); color: var(--muted); border: 1px solid var(--border); }
.catalog-card__was { color: var(--muted); font-size: 1rem; }

/* The card title is a real link whose ::after covers the whole card, so the picture
   and the empty space are clickable too without nesting a link around the button. */
.catalog-card { position: relative; }
.catalog-card__link { color: inherit; text-decoration: none; }
.catalog-card__link::after { content: ''; position: absolute; inset: 0; border-radius: var(--radius-card); }
.catalog-card__link:hover { color: var(--accent); }
.catalog-card:focus-within { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.catalog-card__link:focus-visible { outline: none; }
.catalog-card:has(.catalog-card__link:focus-visible) { outline: 3px solid var(--focus); outline-offset: 3px; }
/* the buttons must sit above that covering layer or they stop being clickable */
.catalog-card__actions { position: relative; z-index: 1; }
