@font-face {
  font-family: 'WF Visual Sans';
  src: url('https://dhygzobemt712.cloudfront.net/Fonts/VF/WFVisualSansVF.woff2') format('woff2');
  font-weight: 100 300;
  font-style: normal;
  font-display: swap;
}

:root {
  font-family: 'WF Visual Sans', sans-serif;
  font-size: 18px;

  --primary-color: #E91E63;
  --primary-dark-color: #ff80ab;
  --secondary-color: #000;
  --tertiary-color: #fff;
  --background-color: #fff;
  --border-color: #00000070;
  --svg-color: #000;

  /* Semantic tokens */
  --nav-bg: #00000061;
  --highlight: #E91E63;
  --btn-hover: #E91E63;
  --selection-bg: #E91E63;
  --selection-text: #000;
  --footer-copyright: #E91E63;
  --glass-bg: rgba(255, 255, 255, 0.08);  /* frosted-glass panel fill (nav, scroll mouse, expandable) */
  --nav-shadow: 0 0 0 0.6px var(--border-color),
                0 5px 15px rgba(0, 0, 0, 0.12);  /* nav pill box-shadow; dark mode drops the outer shadow */
  --slider-control-bg: #fff;               /* slider button & dot default fill */

  /* Polaroid collage */
  --polaroid-frame-bg: #efefef;
  --polaroid-shadow: 0 3px 12px rgba(0, 0, 0, 0.10), 0 1px 4px rgba(0, 0, 0, 0.06);
  --polaroid-shadow-hover: 0 10px 28px rgba(0, 0, 0, 0.16), 0 2px 6px rgba(0, 0, 0, 0.08);

  /* Z-index scale */
  --z-background: 0;
  --z-content: 100;
  --z-header: 200;
  --z-buttons: 300;
  --z-overlay: 400;
  --z-sidebar: 500;
  --z-nav: 600;
  --z-hamburger: 700;
  --z-modal: 1000;

  /* Easing tokens */
  --ease-out-quart: cubic-bezier(0.165, 0.84, 0.44, 1);
  --ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1);
}

/* Dark mode */
.dark-mode {
  --primary-color: #ff4081;
  --primary-dark-color: #ff4081;
  --secondary-color: #fff;
  --tertiary-color: #1c1c1c;
  --border-color: #ffffff80;
  --background-color: #141414;
  --svg-color: #6d6d6d;
  --footer-copyright: #353535;

  --nav-bg: #ffffff61;
  --highlight: #ff4081;
  --btn-hover: #ff4081;
  --selection-bg: #ff4081;
  --selection-text: #000;

  --glass-bg: rgba(0, 0, 0, 0.08);
  --nav-shadow: 0 0 0 0.6px var(--border-color);
  --slider-control-bg: var(--tertiary-color);

  --polaroid-frame-bg: #1e1e1e;
  --polaroid-shadow: 0 3px 12px rgba(0, 0, 0, 0.45), 0 1px 4px rgba(0, 0, 0, 0.25);
  --polaroid-shadow-hover: 0 10px 28px rgba(0, 0, 0, 0.55), 0 2px 6px rgba(0, 0, 0, 0.3);

  background-color: var(--background-color);
}

/* Prevent horizontal overflow site-wide */
html,
body {
  width: 100%;
  max-width: 100%;
  overflow-x: hidden;
  position: relative;
}

/* Text selection highlight color */
::-moz-selection {
  color: var(--selection-text);
  background: var(--selection-bg);
}

::selection {
  color: var(--selection-text);
  background: var(--selection-bg);
}

@keyframes push-in-animation {
  0%, 100% { transform: none; }
  15% { transform: scale(0.75); }
  30% { transform: scale(1.1); }
}

@keyframes push-left-animation {
  0% { opacity: 0; transform: translateX(30px); }
  15% { opacity: 1; transform: translateX(-10px); }
  100% { opacity: 1; transform: none; }
}

@keyframes push-right-animation {
  0% { opacity: 1; transform: none; }
  20% { opacity: 1; transform: translateX(-10px); }
  55%, 100% { opacity: 0; transform: translateX(30px); }
}

/* transform: translateY replaces top animation (D→S: compositor-only, no layout) */
@keyframes mouse-scroll {
  0%   { transform: translateY(0);    opacity: 1; }
  80%  {                              opacity: 1; }
  100% { transform: translateY(10px); opacity: 0; }
}

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

@keyframes modalContentIn {
  from { opacity: 0; transform: scale(0.96); }
  to   { opacity: 1; transform: scale(1); }
}

/* -----------------------------------------------
   Utility Classes
   Reusable helpers used across multiple components.
   ----------------------------------------------- */

/* Prevents CSS transitions — used by JS when setting initial element positions */
.no-transition {
  transition: none !important;
}

/* Scroll-triggered fade-in animation (JS adds .visible / .hidden) */
.fade-in {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.4s var(--ease-out-quint), transform 0.4s var(--ease-out-quint);
}

.fade-in.visible {
  opacity: 1;
  transform: translateY(0);
}

.fade-in.hidden {
  opacity: 0;
  transform: translateY(16px);
}

/* Full-width page wrapper */
.container {
  width: 100%;
  margin-left: auto;
  margin-right: auto;
  box-sizing: border-box;
  overflow-x: hidden;
}

/* Accent-colored inline text */
.highlight-pink {
  color: var(--primary-color);
  font-weight: 600;
}

/* -----------------------------------------------
   Typography — Body Section
   .body-section is shared across h1–h3, p, a, and
   <section> elements. Element qualifiers are
   intentional — each element type gets distinct sizing.
   ----------------------------------------------- */

/* Shared z-index lift for all .body-section elements */
.body-section {
  position: relative;
  z-index: var(--z-content);
}

/* Common text styles for body-section headings, paragraphs, links */
h1.body-section,
h2.body-section,
h3.body-section,
p.body-section,
a.body-section {
  color: var(--secondary-color);
  text-align: left;
  line-height: 2.2rem;
  box-sizing: content-box;
}

h1.body-section {
  line-height: clamp(2rem, 5vw, 3rem);
  font-size: clamp(1.8rem, 5vw, 3rem);
  font-weight: 800;
  padding-bottom: 1rem;
}

h2.body-section {
  font-size: clamp(1.5rem, 4vw, 2.2rem);
  font-weight: 700;
}

h3.body-section {
  font-size: clamp(1.1rem, 3vw, 1.35rem);
  font-weight: 600;
}

p.body-section {
  font-size: 1rem;
  font-weight: 400;
}

/* -----------------------------------------------
   Layout — Hero Background
   Two overlapping images swap via opacity for dark/light mode.
   Default shows dark-bg to avoid white flash before JS loads.
   ----------------------------------------------- */

.bg-container {
  position: absolute;
  left: 55%;
  top: 8%;
  width: 100%;
  height: 60vh;
  z-index: var(--z-background);
}

.bg-image {
  position: absolute;
  object-fit: cover;
  height: 100%;
  max-height: 100vh;
  left: 0;
  transform: scale(1);
  transform-origin: center center;
  z-index: var(--z-background);
}

/* Default state: dark bg visible, light bg hidden (prevents white flash) */
.dark-bg { opacity: 1; }
.light-bg { opacity: 0; }

/* Light mode: swap background visibility */
body:not(.dark-mode) .dark-bg { opacity: 0; }
body:not(.dark-mode) .light-bg { opacity: 1; }

/* -----------------------------------------------
   Layout — Content Sections
   ----------------------------------------------- */

/* Centered flex container for each content area */
.body-content {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  padding-bottom: 0;
}

/* First viewport hero area — taller with bottom padding for scroll room */
.body-content--firstviewport {
  min-height: 85vh;
  padding-bottom: 8.5rem;
}

/* Max-width text column within content sections */
section.body-section {
  max-width: min(39rem, 100% - 2rem);
  margin: 0 auto;
  padding: 0 clamp(1rem, 4vw, 2rem);
  box-sizing: border-box;
  align-items: flex-start;
  text-align: left;
}

/* Prevent double-tap zoom on all interactive elements */
a, button,
.button, .nav-link, .social-button, .expand-trigger,
.hamburger, .slider button, .dot, .modal-close,
.polaroid-card, .grid-item img {
  touch-action: manipulation;
}

/* -----------------------------------------------
   Nav Block
   Frosted-glass pill nav, centered-fixed at top.
   Uses --glass-bg and --nav-shadow tokens so
   dark/light theming needs zero overrides here.
   ----------------------------------------------- */

.nav-container {
  position: relative;
}

.sticky-nav {
  display: flex;
  position: fixed;
  top: 1rem;
  left: 50%;
  transform: translateX(-50%);
  background-color: var(--glass-bg);
  box-shadow: var(--nav-shadow);
  backdrop-filter: url(#frosted);
  -webkit-backdrop-filter: blur(8px);
  border-radius: 3rem;
  padding: 0.5rem 0.7rem;
  align-items: center;
  justify-content: center;
  flex-wrap: nowrap;
  z-index: var(--z-nav);
  cursor: pointer;
}

.nav-link {
  color: var(--secondary-color);
  text-decoration: none;
  font-weight: 400;
  font-size: 1rem;
  transition: color 0.2s ease, background-color 0.2s ease;
  padding: 0.5rem 1rem;
  border-radius: 2rem;
  display: inline-block;
  touch-action: manipulation;
}

@media (hover: hover) and (pointer: fine) {
  .nav-link:hover {
    color: var(--primary-color);
    background-color: rgba(233, 30, 99, 0.1);
  }
}

/* When theme toggle sits inside nav — circular, no text padding */
.nav-link.theme-btn {
  padding: 0;
  width: 60px;
  height: 60px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 0;
  line-height: 1;
  border-radius: 50%;
}

/* -----------------------------------------------
   Hamburger Block
   Mobile menu toggle — hidden on desktop,
   shown at ≤768px via media query.
   ----------------------------------------------- */

.hamburger {
  display: none;
  cursor: pointer;
  z-index: var(--z-hamburger);
  position: fixed;
  top: 1rem;
  left: 1rem;
  padding: 10px;
  touch-action: manipulation;
}

@media (hover: hover) and (pointer: fine) {
  .hamburger:hover svg {
    fill: var(--primary-color);
  }
}

/* Targets both <svg class="hamburger-icon"> and any svg child */
.hamburger svg {
  width: 2rem;
  height: 2rem;
  fill: var(--secondary-color);
  transition: fill 0.2s ease;
}

/* -----------------------------------------------
   Sidebar Block
   Full-screen mobile nav panel, slides in from right.
   Layered above .overlay (z-sidebar > z-overlay).
   ----------------------------------------------- */

.menu-sidebar {
  position: fixed;
  top: 0;
  right: 0;
  width: 100%;
  height: 100vh;
  background-color: var(--background-color);
  transform: translateX(100%);
  will-change: transform;
  backdrop-filter: url(#frosted);
  -webkit-backdrop-filter: blur(10px);
  z-index: var(--z-sidebar);
  transition: transform 0.45s var(--ease-out-quart);
  display: none;
}

.menu-sidebar.active {
  transform: translateX(0);
}

.sidebar-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  cursor: pointer;
  z-index: var(--z-hamburger);
  padding: 10px;
  transition: transform 0.2s var(--ease-out-quart);
  touch-action: manipulation;
}

.sidebar-close svg {
  width: 2.5rem;
  height: 2.5rem;
  fill: var(--secondary-color);
  transition: fill 0.2s ease;
}

@media (hover: hover) and (pointer: fine) {
  .sidebar-close:hover {
    transform: scale(1.1);
  }

  .sidebar-close:hover svg {
    fill: var(--primary-color);
  }
}

.sidebar-header {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  padding: 1.5rem;
}

.sidebar-links {
  display: flex;
  flex-direction: column;
  padding: 2rem;
  gap: 2.5rem;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

.sidebar-link {
  color: var(--secondary-color);
  text-decoration: none;
  font-size: clamp(1.5rem, 4vw, 2rem);
  font-weight: 600;
  text-align: center;
  justify-content: center;
  transition: 0.2s ease;
  position: relative;
  z-index: var(--z-buttons);
  width: 100%;
  padding: 1rem 0;
}

/* Larger theme toggle when rendered inside sidebar */
.sidebar-links .theme-btn {
  height: 80px;
  width: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.sidebar-link:hover {
  color: var(--primary-color);
}

/* Translucent backdrop behind open sidebar */
.overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: var(--z-overlay);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1),
              visibility 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

.overlay.active {
  opacity: 1;
  visibility: visible;
}

/* -----------------------------------------------
   Theme Toggle Block
   Dark/light mode switch icon.
   Renders inside both nav (desktop) and sidebar (mobile).
   JS toggles .dark-mode on body; icon swap is pure CSS.
   ----------------------------------------------- */

.theme-btn {
  position: relative;
  height: 60px;
  width: 60px;
  padding: 0;
  margin: 0;
  transition: color 0.2s ease;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: var(--z-nav);
  line-height: 1;
  flex-shrink: 0;
}

.theme-icon {
  transition: fill 0.3s ease;
  fill: var(--secondary-color);
  width: 30px;
  height: 30px;
  display: block;
  flex-shrink: 0;
  margin: auto;
  padding: 0;
  position: relative;
}

@media (hover: hover) and (pointer: fine) {
  .theme-icon:hover {
    fill: var(--primary-color);
  }
}

/* Show moon icon by default; swap to sun icon in dark mode */
.light-icon { display: none; }
.dark-mode .dark-icon { display: none; }
.dark-mode .light-icon { display: block; }

/* -----------------------------------------------
   Header Block
   ----------------------------------------------- */

.header-link {
  position: relative;
  transition: opacity 1s 0.5s;
  box-sizing: border-box;
  display: flex;
  justify-content: flex-end;
  z-index: var(--z-header);
}

.header-img {
  position: relative;
  z-index: 2;
  cursor: pointer;
  height: 4rem;
  width: 4rem;
  object-fit: cover;
  object-position: center;
  margin: 0 auto;
  flex: 0 0 auto;
}

/* -----------------------------------------------
   Button Block — RSVP CTA
   Pill-shaped link button with frosted-glass border.
   On hover: scales up, fills with primary color,
   reveals 5 floating letter images (J-e-s-u-s)
   that scatter outward via absolute positioning.
   ----------------------------------------------- */

.button {
  color: var(--primary-color);
  text-decoration: none;
  box-shadow: 0 0 0 0.6px var(--border-color);
  backdrop-filter: url(#frosted);
  -webkit-backdrop-filter: blur(10px);
  padding: 1rem 2rem;
  border-radius: 3rem;
  margin: 2rem 0;
  transition: color 0.4s, background-color 0.4s, box-shadow 0.4s;
  display: inline-block;
  text-align: center;
  height: auto;
  width: auto;
  position: relative;
  /* will-change removed: GSAP manages this dynamically during hover/tap tweens */
}

/* Glow pseudo-element behind button — fades in on hover */
.button::after {
  content: '';
  width: 100%;
  height: 100%;
  background: var(--primary-color);
  position: absolute;
  left: 0;
  top: 0;
  right: auto;
  margin: 0;
  border-radius: 3rem;
  filter: blur(12px);
  z-index: -1;
  opacity: 0;
  transition: opacity 0.4s;
}

/* Button label text stays above floating images */
.button-text {
  position: relative;
  z-index: 10;
}

/* Floating letter images — hidden by default, revealed on hover */
.button img {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  margin: auto;
  pointer-events: none;
  transition: opacity 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
              transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
  opacity: 0;
}

/* Each letter: unique size, rotation, and hover offset */
.button__J  { width: 3rem; transform: translate(-1.5rem, -1rem) rotate(10deg);  filter: blur(0.2px); }
.button__e  { width: 3rem; transform: translate(-1.5rem, -1rem) rotate(5deg);   filter: blur(0.2px); }
.button__s  { width: 2rem; transform: translate(-2rem, -1rem) rotate(-20deg);   filter: blur(0.2px); }
.button__u  { width: 2rem; transform: translate(-2rem, -1rem) rotate(-10deg);   filter: blur(0.2px); }
.button__s2 { width: 4rem; transform: translate(-1.5rem, -1rem) rotate(10deg);  filter: blur(0.2px); }

/* Hover: all button hover effects gated to pointer:fine — prevents sticky
   hover-on-tap on touch devices (iOS/Android keep :hover after touch lift) */
@media (hover: hover) and (pointer: fine) {
  .button:hover::after { opacity: 1; }

  .button:hover {
    color: var(--secondary-color);
    background-color: var(--btn-hover);
  }

  .button:hover img { opacity: 1; }

  /* Hover: scatter letters outward from center */
  .button:hover .button__J  { transform: translate(-4.5rem, -0.5rem) scale(1.2); }
  .button:hover .button__e  { transform: translate(-3rem, -2.5rem) scale(1.2); }
  .button:hover .button__s  { transform: translate(-1.2rem, 0.1rem) scale(1.2); }
  .button:hover .button__u  { transform: translate(-0.5rem, -2.5rem) scale(1.2); }
  .button:hover .button__s2 { transform: translate(0.5rem, -1.5rem) scale(1.2); }
}

/* Touch press: scale-down tap feedback — no hover on touch devices */
@media (hover: none) {
  .button:active {
    color: var(--secondary-color);
    background-color: var(--btn-hover);
  }
}

/* -----------------------------------------------
   Social Button Block (BEM)
   Icon with reveal-on-hover colored background and label.
   Used in header (Instagram link) and footer (social links).
   ----------------------------------------------- */

.social-button {
  font-size: 1rem;
  line-height: 1;
  text-align: center;
  position: relative;
  cursor: pointer;
  box-sizing: border-box;
  background-color: transparent;
  outline: none;
  text-decoration: none;
  display: inline-block;
  width: 8rem;
  padding: 2rem 0;
  margin: 0;
  height: auto;
  /* CSS-driven press state — GSAP no longer manages social-button transforms */
  transition: transform 150ms cubic-bezier(0.215, 0.61, 0.355, 1);
}

/* Gate hover rules: prevents phantom triggers on touch-tap */
@media (hover: hover) and (pointer: fine) {
  .social-button:hover .social-button--background { opacity: 1; }
  .social-button:hover .social-button--label {
    opacity: 1;
    color: #000;
    transform: translateY(0);
  }
}

/* Full-size colored backdrop, hidden until hover/active */
.social-button--background {
  background-color: var(--primary-color);
  position: absolute;
  z-index: 1;
  cursor: pointer;
  /* 200ms ease-out: matches Emil's 150–250ms micro-interaction range */
  transition: opacity 200ms ease-out;
  box-sizing: border-box;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
}

/* Label text below icon — hidden at rest, shown immediately on hover */
.social-button--label {
  color: var(--tertiary-color);
  text-align: center;
  justify-content: center;
  position: relative;
  z-index: 2;
  cursor: pointer;
  box-sizing: border-box;
  margin-top: 1.5rem;
  opacity: 0;
  font-size: 0.8rem;
  transform: translateY(4px);
}

/* Header social button sits on the page background — label must follow secondary color
   so it reads correctly in both light (black) and dark (white) mode */
.header-link .social-button--label {
  color: var(--secondary-color);
}

/* -----------------------------------------------
   Scroll Mouse Block
   Animated scroll-down indicator at left edge of hero.
   Uses --glass-bg for theme-aware inner background.
   Hidden at ≤768px (see media queries).
   ----------------------------------------------- */

.scroll-mouse-container {
  position: absolute;
  top: 50vh;
  left: 2%;
  width: 60px;
  height: 1rem;
  margin-left: -30px;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: opacity 0.3s ease;
  z-index: var(--z-content);
}

.scroll-mouse-container .scroll-mouse-inner {
  width: 30px;
  height: 50px;
  position: relative;
  border-radius: 34px;
  background-color: var(--glass-bg);
  box-shadow: 0 0 0 0.6px var(--border-color);
}

.scroll-mouse-container .scroll-mouse-inner .scroll-mouse-wheel {
  position: absolute;
  top: 10%;
  left: 50%;
  width: 12px;
  height: 12px;
  margin-left: -6px;
  border-radius: 50%;
  background-color: var(--secondary-color);
  animation: mouse-scroll 0.9s infinite;
}

@media (prefers-reduced-motion: reduce) {
  .scroll-mouse-container .scroll-mouse-inner .scroll-mouse-wheel {
    animation: none;
  }
}

/* -----------------------------------------------
   Image Grid Block
   Responsive CSS Grid galleries for event photos.
   Two aspect ratios share a common base layout —
   only --row-heights differs between variants.
   Columns adjust from 4→2 at ≤768px (media queries).
   ----------------------------------------------- */

/* Shared grid base for both 5:4 and 16:9 galleries */
.image-grid,
.image-grid-span {
  --gap: 0.125rem;
  --num-cols: 4;
  box-sizing: border-box;
  display: grid;
  grid-template-columns: repeat(var(--num-cols), 1fr);
  grid-auto-rows: var(--row-heights);
  gap: var(--gap);
  padding: 0 0 clamp(2rem, 5vw, 5rem);
  margin: 0;
  width: 100%;
  max-width: 100%;
  overflow: hidden;
}

/* 5:4 portrait ratio — group photos */
.image-grid {
  --row-heights: calc((100vw / var(--num-cols)) * 4 / 5);
  /* will-change removed: .image-grid does not animate; permanent layer wastes GPU memory */
}

/* 16:9 landscape ratio — wide/panoramic shots */
.image-grid-span {
  --row-heights: calc((100vw / var(--num-cols)) * 9 / 16);
}

/* Grid Item — individual photo/video cell */
.grid-item {
  position: relative;
  overflow: hidden;
  width: 100%;
  box-sizing: border-box;
}

.image-grid .grid-item,
.image-grid-span .grid-item {
  width: 100%;
  height: 100%;
}

.grid-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  cursor: pointer;
  transition: transform 0.3s ease;
  content-visibility: auto;
}

/* Force iframes (Vimeo embeds) to fill their grid cell */
.grid-item iframe {
  width: 100% !important;
  height: 100% !important;
  max-width: 100%;
  border: 0;
}

/* Span helpers — let items occupy multiple grid tracks */
.image-grid-col-2 { grid-column: span 2; }
.image-grid-row-2 { grid-row: span 2; }

/* -----------------------------------------------
   Polaroid Collage Grid Block
   Polaroid-style photo cards with white frames,
   subtle shadows, and organic rotation.
   3-col desktop → 1-col mobile.
   ----------------------------------------------- */

/* Grid container — 80% width, tight gap for scattered overlap */
.polaroid-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0rem;
  padding: 1rem 0 clamp(2rem, 5vw, 5rem);
  width: 80%;
  max-width: 80%;
  margin: 0 auto;
  overflow: visible;
}

/* Card wrapper — rotation + hover transitions */
.polaroid-card {
  position: relative;
  transition: transform 0.3s cubic-bezier(0.23, 1, 0.32, 1),
              z-index 0s 0.3s;
  cursor: pointer;
  border-radius: 5px;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.24);
  margin: 1rem;
}

/* Repeating rotation + offset pattern — scattered, overlapping look */
.polaroid-card:nth-child(6n+1) { transform: rotate(-3.5deg) translate(-4px, 2px); }
.polaroid-card:nth-child(6n+2) { transform: rotate(2.8deg) translate(3px, -3px); }
.polaroid-card:nth-child(6n+3) { transform: rotate(-1.5deg) translate(-2px, 5px); }
.polaroid-card:nth-child(6n+4) { transform: rotate(4deg) translate(5px, -1px); }
.polaroid-card:nth-child(6n+5) { transform: rotate(-2.5deg) translate(-3px, 4px); }
.polaroid-card:nth-child(6n+6) { transform: rotate(1.8deg) translate(2px, -4px); }

/* Hover: straighten and lift */
.polaroid-card.hover,
.polaroid-card.show-info {
  transform: rotate(0deg);
  z-index: 2;
  /* transition: transform 0.3s cubic-bezier(0.23, 1, 0.32, 1),
              z-index 0s; */
}

@media (hover: hover) and (pointer: fine) {
  .polaroid-card:hover {
    transform: rotate(0deg);
    z-index: 2;
  }
}

/* Polaroid frame — white border, rounded corners, soft shadow */
.polaroid-frame {
  position: relative;
  background: var(--polaroid-frame-bg);
  padding: 0.5rem;
  border-radius: 5px;
  box-shadow: var(--polaroid-shadow);
  overflow: hidden;
  transition: box-shadow 0.3s cubic-bezier(0.23, 1, 0.32, 1);
}

.polaroid-card:hover .polaroid-frame,
.polaroid-card.hover .polaroid-frame,
.polaroid-card.show-info .polaroid-frame {
  box-shadow: var(--polaroid-shadow-hover);
}

/* Image inside frame — default 5:4 ratio */
.polaroid-frame > img {
  width: 100%;
  aspect-ratio: 5 / 4;
  object-fit: cover;
  display: block;
  border-radius: 5px;
  content-visibility: auto;
}

/* Subtle zoom on hover — disabled */
/* .polaroid-card:hover .polaroid-frame > img,
.polaroid-card.hover .polaroid-frame > img,
.polaroid-card.show-info .polaroid-frame > img {
  transform: scale(1.03);
} */

/* 16:9 wide variant */
.polaroid-grid--wide .polaroid-frame > img {
  aspect-ratio: 16 / 9;
}

/* -----------------------------------------------
   Grid Hover Overlay
   Directional animated info overlay on grid images.
   JS adds .hover (mouse) or .show-info (touch)
   to .grid-item. Text elements receive a directional
   translate offset from JS for enter/leave effects
   (inspired by Hakim El Hattab).
   ----------------------------------------------- */

/* Dark overlay panel — hidden by default */
.grid-item-info {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  width: 100%;
  height: 100%;
  padding: 1.5em;
  z-index: 2;
  color: rgba(255, 255, 255, 0.9);
  text-align: left;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  font-size: 0.9em;
  opacity: 0;
  background-color: rgba(17, 17, 17, 0.85);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  visibility: hidden;
  transition: visibility 0.3s cubic-bezier(0.23, 1, 0.32, 1),
              opacity 0.3s cubic-bezier(0.23, 1, 0.32, 1);
  cursor: pointer;
}

/* Overlay text — directional transform is set/animated by JS */
.grid-item-info p {
  position: relative;
  z-index: 2;
  opacity: 0;
  margin: 0;
  transition: opacity 0.3s cubic-bezier(0.23, 1, 0.32, 1),
              transform 0.3s cubic-bezier(0.23, 1, 0.32, 1);
}

.grid-item-info p:first-child {
  font-size: 1em;
  font-weight: 600;
  margin-bottom: 0.3em;
  color: #fff;
}

.grid-item-info p {
  font-size: 1em;
  font-weight: 400;
  color: rgba(255, 255, 255, 0.8);
}

/* Active state — shared by mouse hover (.hover) and touch tap (.show-info) */
.grid-item.hover .grid-item-info,
.grid-item.show-info .grid-item-info {
  visibility: visible;
  opacity: 1;
}

.grid-item.hover .grid-item-info p,
.grid-item.show-info .grid-item-info p {
  opacity: 1;
}

/* Staggered text reveal — subtitle enters 50ms after title (mouse only) */
.grid-item.hover .grid-item-info p {
  transition-delay: 0.05s;
}

/* Touch devices: reset directional transform (no cursor direction to track) */
.grid-item.show-info .grid-item-info p {
  transform: none;
}

/* Subtle zoom on active image — excludes polaroid cards */
.grid-item:not(.polaroid-card).hover img,
.grid-item:not(.polaroid-card).show-info img {
  transform: scale(1.05);
}

/* -----------------------------------------------
   Modal Block
   Fullscreen image viewer with blurred backdrop.
   Opens when user clicks a grid image to show
   full-resolution version (loaded from data-src).
   ----------------------------------------------- */

.modal {
  display: none;
  position: fixed;
  z-index: var(--z-modal);
  left: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
  overflow: auto;
  background-color: #00000083;
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
}

.modal.show {
  display: flex;
  justify-content: center;
  align-items: center;
  animation: fadeIn 0.25s var(--ease-out-quart);
}

.modal.show .modal-content {
  animation: modalContentIn 0.25s var(--ease-out-quart);
}

.modal-content {
  position: relative;
  margin: auto;
  max-width: 90%;
  max-height: 90vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.modal-close {
  position: fixed;
  top: 1.25rem;
  right: 1.25rem;
  width: 40px;
  height: 40px;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  border-radius: 50%;
  background: none;
  box-shadow: 0 0 0 0.6px var(--border-color);
  transition: background-color 0.3s ease, box-shadow 0.3s ease;
}

@media (hover: hover) and (pointer: fine) {
  .modal-close:hover {
    background-color: var(--primary-color);
    box-shadow: 0 0 0 0.6px var(--primary-color);
  }
}

.modal-close svg {
  fill: var(--secondary-color);
  width: 24px;
  height: 24px;
  transition: fill 0.3s ease;
}

.modal-img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 80vh;
  object-fit: contain;
}

/* -----------------------------------------------
   Slider Block
   Poster carousel with prev/next buttons and dot indicators.
   Uses --slider-control-bg token for dark/light theming
   of buttons and dots — no dark-mode overrides needed.
   ----------------------------------------------- */

.slider {
  position: relative;
  max-width: min(600px, 100% - 2rem);
  margin: 0 auto;
  padding-top: clamp(1.5rem, 4vw, 3rem);
  padding-bottom: clamp(2rem, 5vw, 5rem);
  overflow: visible;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
}

.slides {
  width: 100%;
  aspect-ratio: 1545/2000;
  position: relative;
  display: flex;
  border-radius: 0.2rem;
  overflow: hidden;
}

/* Slide images stack absolutely; only .active is visible */
.slider img {
  width: 100%;
  height: fit-content;
  flex-shrink: 0;
  object-fit: contain;
  border: var(--border-color) solid 0.6px;
  border-radius: 0.2rem;
  box-sizing: border-box;
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
  pointer-events: none;
}

.slider img.active {
  opacity: 1;
  pointer-events: auto;
  z-index: 1;
}

/* Circular prev/next buttons — positioned outside slider edges */
.slider button {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background-color: var(--slider-control-bg);
  border: 0.6px solid var(--border-color);
  color: var(--secondary-color);
  font-size: 1.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 5;
  transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
  padding: 0;
}

@media (hover: hover) and (pointer: fine) {
  .slider button:hover {
    background-color: var(--primary-color);
    border-color: var(--primary-color);
  }
}

.slider button svg {
  fill: var(--secondary-color);
}

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

/* Dot indicators — centered below slider content */
.dots {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.75rem;
  z-index: 10;
}

.dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background-color: var(--slider-control-bg);
  border: 1px solid var(--border-color);
  cursor: pointer;
  transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

/* Active state — primary color fill */
.dot.active {
  background-color: var(--primary-color);
  border-color: var(--primary-color);
}

.dot.active {
  transform: scale(1.2);
}

@media (hover: hover) and (pointer: fine) {
  .dot:hover {
    background-color: var(--primary-color);
    border-color: var(--primary-color);
  }
}

/* -----------------------------------------------
   Expandable Block — Accordion Q&A
   Clicking .expand-trigger toggles .active on
   .expand-list-item, revealing .expand-target-short
   via animated max-height. Uses --glass-bg token
   so dark/light theming needs zero overrides.
   ----------------------------------------------- */

.expand-list {
  width: 100%;
  max-width: 800px;
  padding-left: 0;
  margin-left: 0;
}

.expand-list-item {
  position: relative;
  margin-bottom: 1rem;
  list-style-type: none;
  border-radius: 0.2rem;
}

/* Override default 🌸 list bullet */
.expand-list-item::before {
  display: none;
}

/* Trigger bar — clickable header with +++ / −−− indicator */
.expand-trigger {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 0.9rem 0.7rem;
  cursor: pointer;
  color: var(--secondary-color);
  font-weight: 600;
  font-size: 1.1rem;
  transition: background-color 0.3s ease, box-shadow 0.3s ease;
  background-color: var(--glass-bg);
  box-shadow: 0 0 0 0.6px var(--border-color);
  border-radius: 0.2rem;
  overflow: hidden;
  min-height: 3.5rem;
  line-height: 1.4;
}

/* Open state: square off bottom corners to join with content panel */
.expand-list-item.active .expand-trigger {
  border-radius: 0.2rem 0.2rem 0 0;
}

/* Expand/collapse text icon */
.expand-trigger::after {
  content: '+++';
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1;
  transition: transform 0.3s ease;
  flex-shrink: 0;
}

.expand-list-item.active .expand-trigger::after {
  content: '−−−';
  transform: rotate(0deg);
}

/* Label wrapper inside trigger */
.anchor-label {
  flex: 1;
  padding: 0 0.6rem;
  display: flex;
  align-items: center;
  justify-content: flex-start;
}

.anchor-label h3 {
  width: 100%;
  margin: 0;
  align-items: center;
}

/* Hover highlight — fills trigger with primary color */
.anchor-background {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  opacity: 0;
  transition: opacity 0.3s ease;
  margin: 0;
  padding: 0;
}

@media (hover: hover) and (pointer: fine) {
  .expand-list-item:hover .anchor-background {
    opacity: 1;
    transition: 0.4s ease;
    background-color: var(--primary-color);
    color: var(--secondary-color);
  }
}

/* Expandable content panel — animated open/close via max-height */
.expand-target-short {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.5s cubic-bezier(0, 1, 0, 1), padding 0.3s ease;
  background-color: var(--glass-bg);
  box-shadow: 0 0 0 0.6px var(--border-color);
  border-radius: 0 0 0.2rem 0.2rem;
  padding: 0 1.5rem;
  opacity: 0;
  box-sizing: border-box;
}

.expand-list-item.active .expand-target-short {
  max-height: 1000px;
  padding: 1rem 1.5rem;
  transition: max-height 0.5s cubic-bezier(0, 0, 1, 0),
              padding 0.3s ease,
              opacity 0.1s ease;
  border-bottom-left-radius: 0.2rem;
  border-bottom-right-radius: 0.2rem;
  opacity: 1;
  box-shadow: 0 0 0 0.6px var(--border-color);
  clip-path: inset(0 -100px -100px -100px);
}

/* -----------------------------------------------
   Download Link
   ----------------------------------------------- */

.download-link {
  color: var(--primary-color);
  text-decoration: none;
  display: inline-block;
  position: relative;
}

.download-link:hover {
  text-decoration: underline;
}

/* -----------------------------------------------
   Footer Block
   Diagonal-topped section with SVG polygon background,
   contact info, and social media links.
   ----------------------------------------------- */

.footer-container {
  position: relative;
  margin-top: 3rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  overflow: hidden;
}

/* SVG polygon fills background with a responsive diagonal top edge */
.footer-background {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}

.footer-background svg {
  display: block;
  width: 100%;
  height: 100%;
  max-height: 100%;
  /* Responsive clip-path: diagonal angle flattens as viewport narrows */
  clip-path: polygon(
    0 clamp(5%, calc(2% + (10vw - 48px) / 10), 12%),
    100% 0,
    100% 100%,
    0 100%
  );
}

/* Footer content wrapper — wraps to column on mobile */
.footer-content {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: flex-start;
  flex-direction: row;
  position: relative;
  padding-top: clamp(4rem, 10vw, 8rem);
  width: 100%;
  max-width: min(66.67rem, 100% - 2rem);
  margin: 0 auto;
  z-index: 1;
  gap: clamp(1rem, 3vw, 2rem);
}

.footer-section {
  flex: 1;
}

section.footer-section {
  margin: 0 auto 1rem clamp(1rem, 3vw, 2rem);
  max-width: min(600px, 100%);
  text-align: left;
  padding: clamp(0.5rem, 2vw, 1rem);
  width: 100%;
  min-width: min(300px, 100%);
}

/* Footer text — white on dark background (merged from two duplicate selectors) */
.footer-section,
li.footer-section,
ul.contact-info {
  color: #fff;
  text-align: left;
  box-sizing: content-box;
  list-style-type: none;
  padding-left: 0;
  max-width: 90%;
}

/* Cherry blossom bullet for contact list items */
ul li::before {
  content: "🌸";
}

h1.footer-section {
  line-height: clamp(2rem, 5vw, 3rem);
  font-size: clamp(1.8rem, 5vw, 3rem);
  font-weight: 800;
  padding-bottom: 1rem;
}

p.footer-section {
  font-size: 1rem;
  font-weight: 400;
  line-height: 2.2;
  margin-bottom: 1rem;
}

ul.contact-info li {
  font-size: 1rem;
  margin-bottom: 1.1rem;
  font-weight: 400;
  line-height: 1.6;
}

.footer-section a {
  color: var(--primary-dark-color);
  text-decoration: none;
  font-size: 1rem;
  font-weight: 500;
}

.footer-section a:hover {
  text-decoration: underline;
}

.footer-link {
  position: relative;
  transition: opacity 1s 0.5s;
  box-sizing: border-box;
  display: flex;
}

.footer-img {
  position: relative;
  z-index: 2;
  height: 4rem;
  width: 4rem;
  text-align: center;
  transition: filter 0.3s ease;
}

/* Social link row in footer */
.social-buttons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0;
  margin-top: auto;
  padding: clamp(1rem, 3vw, 2rem) 0;
}

/* Footer-specific hover — gated to pointer:fine devices only */
@media (hover: hover) and (pointer: fine) {
  .social-button:hover .social-button--label {
    opacity: 1;
    color: #000;
    transform: translateY(0);
  }

  .social-button:hover .footer-img {
    filter: invert(1);
  }
}

/* -----------------------------------------------
   Made With Love Block (BEM)
   Copyright bar pinned to bottom of footer.
   ----------------------------------------------- */

.madewithlove-bar {
  position: relative;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 0.5rem 1rem;
  background-color: var(--footer-copyright);
  z-index: 2;
}

/* Merged from two duplicate selectors — removed invalid max-width: auto */
.madewithlove-bar--text {
  color: #fff;
  font-size: 0.9rem;
  text-decoration: none;
  width: 100%;
  text-align: center;
}

.madewithlove-bar--text a:hover {
  text-decoration: underline;
}

.madewithlove-bar--link {
  color: #fff;
}

/* -----------------------------------------------
   Responsive Breakpoints
   1024px — increase footer top padding for diagonal
   768px  — mobile layout (hamburger, 2-col grid)
   480px  — fine-tune mobile spacing
   ----------------------------------------------- */

@media screen and (max-width: 1024px) {
  .footer-content {
    padding-top: clamp(8rem, 15vw, 12rem);
  }
}

@media screen and (max-width: 768px) {
  /* Switch nav: hide desktop pill, show hamburger + sidebar */
  .sticky-nav { display: none; }
  .hamburger { display: block; }
  .menu-sidebar { display: block; }

  /* Grid: single column on mobile — one image at a time */
  .image-grid,
  .image-grid-span {
    --num-cols: 1;
  }

  /* Reset multi-track spans so no item overflows the 1-col grid */
  .image-grid-col-2 { grid-column: span 1; }
  .image-grid-row-2 { grid-row:    span 1; }

  /* Footer: stack vertically with more top padding */
  .footer-content {
    flex-direction: column;
    align-items: center;
    padding-top: 10rem;
  }

  section.footer-section {
    margin: 0 auto 1rem auto;
    text-align: left;
    align-items: flex-start;
  }

  .footer-section,
  li.footer-section,
  ul.contact-info {
    text-align: left;
  }

  /* Hero: shorter viewport on tablets */
  .body-content--firstviewport {
    min-height: 70vh;
    padding-bottom: 4rem;
  }

  /* Hide scroll indicator on small screens */
  .scroll-mouse-container { display: none; }

  /* Hide slider arrows on touch-sized screens */
  .slider .prev-btn,
  .slider .next-btn {
    display: none !important;
  }

  /* Hide floating letter images — no hover on touch */
  .button img { display: none; }

  /* Social buttons: show label always on mobile for navigation clarity.
     Background stays hidden at rest; flashes brand color on :active press.
     Label is always visible — users need to know what the icons link to. */
  .social-button--background {
    display: block;
    opacity: 0;
    transition: opacity 150ms ease-out;
  }

  .social-button--label {
    display: block;
    opacity: 1;
    /* Cancel the desktop slide-up offset so label sits in natural position */
    transform: none;
    /* Footer background is always dark — white text reads in both modes.
       .header-link .social-button--label overrides this for the header context. */
    color: #fff;
  }

  /* Header sits on page background; override the white to follow secondary color
     (black in light mode, white in dark mode) so the label is always legible */
  .header-link .social-button--label {
    color: var(--secondary-color);
  }

  /* Clean press state: scale-down + brand color flash on touch */
  .social-button:active {
    transform: scale(0.92);
  }

  .social-button:active .social-button--background {
    opacity: 1;
  }

  .social-button:active .social-button--label {
    color: var(--secondary-color);
  }

  /* Polaroid grid: single column, centered, keep rotation */
  .polaroid-grid {
    grid-template-columns: 1fr;
    gap: 2rem;
    max-width: 400px;
    margin: 0 auto;
    justify-items: center;
  }
}

@media screen and (max-width: 480px) {
  /* Grid: 1-col (inherits from 768px breakpoint — kept for explicit intent) */
  .image-grid,
  .image-grid-span {
    --num-cols: 1;
  }

  /* Extra footer padding for shallower SVG diagonal on narrow screens */
  .footer-content {
    padding-top: 13rem;
  }
}

/* -----------------------------------------------
   Reduced Motion
   Disable all animations for users who prefer less motion.
   ----------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .fade-in {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .fade-in.hidden {
    opacity: 0;
    transform: none;
  }

  .scroll-mouse-container .scroll-mouse-wheel {
    animation: none;
  }
}
