/* ==========================================================================
   TAL BARAK FILMS — Design tokens & base
   ========================================================================== */

:root {
  /* Color */
  --bg: #0a0a0c;
  --bg-elevated: #131316;
  --bg-elevated-2: #1c1c20;
  --fg: #f5f4f0;
  --fg-muted: #a3a3ac;
  /* Lightened from #6b6b74 — that value was ~3.75:1 against --bg, failing
     WCAG 2.0 AA (4.5:1) for the normal-size text it's used on (stat
     captions, footer headings). #8a8a92 measures ~5.8:1. */
  --fg-faint: #8a8a92;
  --primary: #9dc183;
  --primary-hover: #b4d69a;
  --primary-fg: #0a0a0c;
  --accent: #e3c99b;
  --accent-fg: #0a0a0c;
  --border: rgba(245, 244, 240, 0.1);
  --border-strong: rgba(245, 244, 240, 0.2);
  --card: #131316;
  --overlay-scrim: rgba(10, 10, 12, 0.72);

  /* Radius */
  --radius-sm: 6px;
  --radius-md: 14px;
  --radius-lg: 24px;
  --radius-full: 999px;

  /* Motion */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast: 150ms;
  --dur-base: 250ms;
  --dur-slow: 400ms;

  /* Spacing (4/8 rhythm) */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;
  --space-10: 140px;

  /* Type */
  --font-display: "Rubik", "Segoe UI", sans-serif;
  --font-body: "Heebo", "Segoe UI", sans-serif;

  --fs-hero: clamp(2.5rem, 3vw + 1.75rem, 6rem);
  --fs-h1: clamp(2.25rem, 2.4vw + 1.5rem, 4rem);
  --fs-h2: clamp(1.75rem, 1.6vw + 1.25rem, 2.75rem);
  --fs-h3: clamp(1.25rem, 0.8vw + 1rem, 1.625rem);
  --fs-lead: clamp(1.0625rem, 0.4vw + 1rem, 1.375rem);
  --fs-body: 1rem;
  --fs-sm: 0.875rem;
  --fs-xs: 0.75rem;

  --container: 1600px;

  color-scheme: dark;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: auto;
}

html.has-lenis {
  scroll-behavior: auto;
}

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  min-height: 100dvh;
}

img,
video {
  max-width: 100%;
  display: block;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}

ul {
  list-style: none;
}

svg {
  display: block;
  flex-shrink: 0;
}

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-5);
}

@media (min-width: 768px) {
  .container {
    padding-inline: var(--space-7);
  }
}

section {
  position: relative;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Skip link */
.skip-link {
  position: fixed;
  top: -100%;
  inset-inline-start: var(--space-4);
  z-index: 1000;
  background: var(--accent);
  color: var(--accent-fg);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-sm);
  font-weight: 600;
  transition: top var(--dur-base) var(--ease-out);
}

.skip-link:focus-visible {
  top: var(--space-4);
}

/* Focus states */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* ==========================================================================
   Typography
   ========================================================================== */

h1,
h2,
h3,
h4,
.font-display {
  font-family: var(--font-display);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.01em;
}

[dir="rtl"] h1,
[dir="rtl"] h2,
[dir="rtl"] h3,
[dir="rtl"] h4,
[dir="rtl"] .font-display {
  letter-spacing: 0;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--fg-muted);
}

[dir="rtl"] .eyebrow {
  letter-spacing: 0.02em;
}

.eyebrow::before {
  content: "";
  width: 22px;
  height: 2px;
  background: var(--primary);
  flex-shrink: 0;
}

.lead {
  font-size: var(--fs-lead);
  color: var(--fg-muted);
  max-width: 46ch;
}

.text-accent {
  color: var(--accent);
}

.text-primary {
  color: var(--primary);
}

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-6);
  border-radius: var(--radius-full);
  font-weight: 700;
  font-size: var(--fs-sm);
  letter-spacing: 0.02em;
  min-height: 48px;
  white-space: nowrap;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-out),
    background-color var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out);
}

.btn-primary {
  background: var(--primary);
  color: var(--primary-fg);
}

.btn-primary:hover {
  background: var(--primary-hover);
  transform: translateY(-2px);
}

.btn-outline {
  background: transparent;
  border: 1.5px solid var(--border-strong);
  color: var(--fg);
}

.btn-outline:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: translateY(-2px);
}

.btn-ghost {
  background: transparent;
  color: var(--fg);
  padding-inline: var(--space-3);
}

.btn-ghost:hover {
  color: var(--accent);
}

.btn svg {
  width: 18px;
  height: 18px;
  transition: transform var(--dur-base) var(--ease-out);
}

[dir="rtl"] .btn svg.icon-arrow {
  transform: scaleX(-1);
}

.btn:hover svg.icon-arrow {
  transform: translateX(4px);
}

[dir="rtl"] .btn:hover svg.icon-arrow {
  transform: scaleX(-1) translateX(4px);
}

/* ==========================================================================
   Header / Nav
   ========================================================================== */

.site-header {
  position: fixed;
  top: 0;
  inset-inline: 0;
  z-index: 100;
  padding-block: var(--space-4);
  transition: background-color var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    padding-block var(--dur-base) var(--ease-out);
  border-bottom: 1px solid transparent;
}

.site-header.is-scrolled {
  background: rgba(10, 10, 12, 0.78);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  border-bottom-color: var(--border);
  padding-block: var(--space-3);
}

.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
}

/* The header row now spans the same widened --container as the page
   sections below it, so the brand sits at the new, further-out edge — but
   the CTA on the other end should stay exactly where it was before that
   change. Since justify-content:space-between pins both ends to the row's
   own edges, pulling just the CTA back means giving it an inward margin
   equal to how much further out this row's edge now sits compared to the
   old 1360px cap (min() mirrors .container's own width-clamping so this
   stays correct at every viewport, not just the widest ones). */
.site-header .nav-actions {
  margin-inline-end: calc((min(100vw, var(--container)) - min(100vw, 1360px)) / 2);
}

.brand {
  position: relative;
  width: fit-content;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1.25rem;
  letter-spacing: -0.02em;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  transition: opacity var(--dur-base) var(--ease-out);
}

.brand::after {
  content: "";
  position: absolute;
  bottom: -4px;
  inset-inline-start: 0;
  width: 0;
  height: 1.5px;
  background: var(--accent);
  transition: width var(--dur-base) var(--ease-out);
}

.brand:hover {
  opacity: 0.8;
}

.brand:hover::after {
  width: 100%;
}

.brand .brand-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--primary);
  box-shadow: 0 0 0 4px rgba(157, 193, 131, 0.18);
}

.nav-links {
  display: none;
  align-items: center;
  gap: var(--space-6);
  font-size: var(--fs-sm);
  font-weight: 600;
}

.nav-links a {
  position: relative;
  padding-block: var(--space-1);
  color: var(--fg-muted);
  transition: color var(--dur-base) var(--ease-out);
}

.nav-links a::after {
  content: "";
  position: absolute;
  bottom: -2px;
  inset-inline-start: 0;
  width: 0;
  height: 1.5px;
  background: var(--accent);
  transition: width var(--dur-base) var(--ease-out);
}

.nav-links a:hover {
  color: var(--fg);
}

.nav-links a:hover::after {
  width: 100%;
}

.nav-links a.is-current,
.mobile-nav a.is-current {
  color: var(--fg);
}

.nav-links a.is-current::after {
  width: 100%;
  background: var(--primary);
}

.nav-link-accent {
  color: var(--accent) !important;
  padding: 6px 14px !important;
  border: 1px solid rgba(227, 201, 155, 0.35);
  border-radius: var(--radius-full);
}

.nav-link-accent::after {
  display: none;
}

.nav-link-accent:hover {
  border-color: var(--accent);
  background: rgba(227, 201, 155, 0.08);
}

.hero-wedding-link {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--fg-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color var(--dur-base) var(--ease-out);
}

.hero-wedding-link:hover {
  color: var(--accent);
}

.nav-actions {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.nav-cta {
  display: none;
}

.nav-burger {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  align-items: center;
}

.nav-burger span {
  width: 22px;
  height: 2px;
  background: var(--fg);
  border-radius: 2px;
  transition: transform var(--dur-base) var(--ease-out), opacity var(--dur-base) var(--ease-out);
}

.nav-burger[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}

.nav-burger[aria-expanded="true"] span:nth-child(2) {
  opacity: 0;
}

.nav-burger[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

@media (min-width: 1024px) {
  .nav-links {
    display: flex;
  }
  .nav-cta {
    display: inline-flex;
  }
  .nav-burger {
    display: none;
  }
}

/* Mobile nav drawer */
.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--space-8) var(--space-6);
  transform: translateY(-100%);
  transition: transform var(--dur-slow) var(--ease-in-out);
}

.mobile-nav.is-open {
  transform: translateY(0);
}

.mobile-nav ul {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.mobile-nav a {
  font-family: var(--font-display);
  font-size: clamp(2rem, 8vw, 3rem);
  font-weight: 800;
}

.mobile-nav-footer {
  margin-top: var(--space-8);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  align-items: flex-start;
}

[dir="rtl"] .mobile-nav-footer {
  align-items: flex-end;
}

@media (min-width: 1024px) {
  .mobile-nav {
    display: none;
  }
}

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
  position: relative;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding-top: calc(var(--space-9) + 64px);
  padding-bottom: var(--space-8);
  overflow: hidden;
}

.hero-media {
  position: absolute;
  inset: 0;
  z-index: -2;
  overflow: hidden;
}

.hero-bg {
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 90% at 18% 0%, #24120d 0%, var(--bg) 55%),
    linear-gradient(180deg, var(--bg) 0%, #0a0a0c 100%);
}

.hero-bg::before,
.hero-bg::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: 0.35;
  will-change: transform;
}

.hero-bg::before {
  width: 46vw;
  height: 46vw;
  background: var(--primary);
  top: -12%;
  inset-inline-end: -10%;
}

.hero-bg::after {
  width: 34vw;
  height: 34vw;
  background: var(--accent);
  bottom: -14%;
  inset-inline-start: -8%;
  opacity: 0.14;
}

.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 700ms var(--ease-out);
}

.hero-video.is-visible {
  opacity: 1;
}

.hero-grain {
  position: absolute;
  inset: 0;
  opacity: 0.5;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.35'/></svg>");
}

.hero-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(10, 10, 12, 0.55) 0%, rgba(10, 10, 12, 0.32) 38%, rgba(10, 10, 12, 0.82) 100%);
}

.hero-media-toggle {
  position: absolute;
  z-index: 5;
  bottom: var(--space-7);
  inset-inline-end: var(--space-5);
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: rgba(10, 10, 12, 0.55);
  backdrop-filter: blur(10px);
  border: 1px solid var(--border-strong);
  display: none;
  align-items: center;
  justify-content: center;
  color: var(--fg);
  transition: background-color var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}

.hero-media-toggle.is-ready {
  display: flex;
}

.hero-media-toggle:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
}

.hero-media-toggle svg {
  width: 18px;
  height: 18px;
}

/* The global `svg { display: block }` reset outranks the UA [hidden] rule's
   plain-type-selector-losing specificity fight in practice, so both icons
   stayed visibly stacked on top of each other regardless of which one JS
   marked hidden — the toggle looked like it never changed state. */
.hero-media-toggle svg[hidden] {
  display: none;
}

.hero-media-toggle .icon-play {
  margin-inline-start: 2px;
}

.hero-top {
  display: flex;
  justify-content: flex-end;
  align-items: flex-start;
  margin-bottom: var(--space-7);
}

.hero-tagline {
  margin-top: var(--space-4);
  font-size: var(--fs-sm);
  max-width: 56ch;
}

.hero-scroll-cue {
  display: none;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--fg-muted);
}

.hero-scroll-cue .scroll-line {
  width: 1px;
  height: 40px;
  background: linear-gradient(var(--fg-muted), transparent);
  position: relative;
  overflow: hidden;
}

.hero-scroll-cue .scroll-line::after {
  content: "";
  position: absolute;
  top: -40px;
  inset-inline: 0;
  height: 40px;
  background: linear-gradient(var(--accent), transparent);
  animation: scrollcue 2.2s ease-in-out infinite;
}

@keyframes scrollcue {
  0% {
    top: -40px;
  }
  60%,
  100% {
    top: 40px;
  }
}

@media (min-width: 768px) {
  .hero-scroll-cue {
    display: flex;
  }
}

.hero-title {
  font-size: var(--fs-hero);
  text-transform: uppercase;
  overflow: hidden;
}

.hero-title .line {
  display: block;
  overflow: hidden;
  padding-bottom: 0.08em;
}

.hero-title .line span {
  display: block;
  will-change: transform;
}

.hero-title .line.accent-line span {
  color: var(--primary);
  -webkit-text-stroke: 0;
}

.hero-sub {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6);
  align-items: flex-end;
  justify-content: space-between;
  margin-top: var(--space-6);
  border-top: 1px solid var(--border);
  padding-top: var(--space-5);
}

.hero-sub .lead {
  max-width: 42ch;
}

.hero-meta {
  display: flex;
  gap: var(--space-6);
  flex-wrap: wrap;
}

.hero-meta div {
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--fg-faint);
}

.hero-meta strong {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-body);
  color: var(--fg);
  text-transform: none;
  letter-spacing: 0;
  margin-top: 4px;
}

/* ==========================================================================
   Marquee (clients strip)
   ========================================================================== */

.marquee-section {
  border-block: 1px solid var(--border);
  padding-block: var(--space-6);
  overflow: hidden;
}

.marquee-track {
  display: flex;
  width: max-content;
  gap: var(--space-9);
  will-change: transform;
  --marquee-end: -50%;
  animation: marquee 28s linear infinite;
}

[dir="rtl"] .marquee-track {
  --marquee-end: 50%;
}

.marquee-section:hover .marquee-track {
  animation-play-state: paused;
}

@keyframes marquee {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(var(--marquee-end));
  }
}

.marquee-track span {
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 2vw, 1.75rem);
  font-weight: 700;
  color: var(--fg-faint);
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: var(--space-9);
}

.marquee-track span::after {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--primary);
  display: inline-block;
  margin-inline-start: var(--space-9);
}

/* ==========================================================================
   Section heading
   ========================================================================== */

.section {
  padding-block: var(--space-9);
}

/* The 96px desktop top padding is deliberate breathing room under the fixed
   header, but on a mobile viewport it reads as a big empty gap before the
   heading — most noticeable right after an in-page nav link jumps you to
   the section's own top edge, since the JS scroll offset only accounts for
   the header height, not whatever padding the section adds on top of that. */
@media (max-width: 640px) {
  .section {
    padding-top: var(--space-5);
    padding-bottom: var(--space-7);
  }
}

.vertical-wall-section {
  padding-bottom: var(--space-8);
}

.section-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-end;
  gap: var(--space-5);
  margin-bottom: var(--space-7);
}

.section-head h2 {
  font-size: var(--fs-h1);
  text-transform: uppercase;
  max-width: 16ch;
}

/* ==========================================================================
   Portfolio grid
   ========================================================================== */

.portfolio-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-5);
}

@media (min-width: 768px) {
  .portfolio-grid {
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-6);
  }
  .portfolio-grid .portfolio-card:nth-child(4n + 1) {
    grid-column: span 4;
  }
  .portfolio-grid .portfolio-card:nth-child(4n + 2),
  .portfolio-grid .portfolio-card:nth-child(4n + 3) {
    grid-column: span 2;
  }
  .portfolio-grid .portfolio-card:nth-child(4n + 4) {
    grid-column: span 4;
  }
}

.portfolio-card {
  grid-column: span 2;
  position: relative;
  border-radius: var(--radius-md);
  overflow: hidden;
  cursor: pointer;
  isolation: isolate;
  /* Without this, a touch-and-hold on mobile is claimed by the browser's
     own long-press gesture (text selection / "save image" callout menu)
     before our long-press-to-preview JS ever gets a chance to react —
     that's the text-selection cursor showing up instead of the preview
     playing. */
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* Portfolio carousel (main site) — one real project per slide, cinematic
   16:9 media regardless of the grid's aspect-ratio rules above. */
.portfolio-carousel-track {
  position: relative;
  overflow: hidden;
}

.portfolio-carousel-slides {
  display: flex;
  transition: transform var(--dur-slow) var(--ease-in-out);
}

[dir="rtl"] .portfolio-carousel-slides {
  flex-direction: row-reverse;
}

.portfolio-carousel-slide {
  flex: 0 0 100%;
}

.portfolio-carousel-slide .card-media {
  aspect-ratio: 16 / 9;
}

/* Real video thumbnail (poster) that plays a muted preview on hover */
.card-preview-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Full-height click zones on each side of the carousel media for prev/next —
   always clickable, arrow fades in on hover so it doesn't clutter the
   thumbnail at rest. */
.portfolio-side-nav {
  position: absolute;
  inset-block: 0;
  width: 64px;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #f5f4f0;
  background: transparent;
  transition: background-color var(--dur-base) var(--ease-out);
}

@media (max-width: 640px) {
  .portfolio-side-nav {
    width: 48px;
  }
}

/* Physical left/right (not logical inline-start/end) — the slide animation
   always moves in a fixed physical direction (prev enters from the left,
   next from the right, matching goToPortfolioSlide's transform math), so
   the arrows must stay on their physical sides in RTL too, or clicking
   "the left one" would visually pull content in from the right. */
.portfolio-side-nav.prev {
  left: 0;
}

.portfolio-side-nav.next {
  right: 0;
}

.portfolio-side-nav:hover,
.portfolio-side-nav:focus-visible {
  background: linear-gradient(90deg, rgba(0, 0, 0, 0.35), transparent);
}

.portfolio-side-nav.next:hover,
.portfolio-side-nav.next:focus-visible {
  background: linear-gradient(270deg, rgba(0, 0, 0, 0.35), transparent);
}

.portfolio-side-nav svg {
  width: 22px;
  height: 22px;
  opacity: 0;
  transform: scale(0.85);
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}

.portfolio-side-nav:hover svg,
.portfolio-side-nav:focus-visible svg {
  opacity: 1;
  transform: scale(1);
}

.card-media {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
}

@media (min-width: 768px) {
  /* Scoped to .portfolio-grid (only the wedding page's static 2-card
     magazine layout) — this used to be a bare .portfolio-card selector,
     which meant nth-child(1) matched ANY single-card wrapper reused
     elsewhere (portfolio.html's video wall and vertical carousel both hit
     this exact bug: every card is nth-child(1) within its own wrapper). */
  .portfolio-grid .portfolio-card:nth-child(4n + 1) .card-media,
  .portfolio-grid .portfolio-card:nth-child(4n + 4) .card-media {
    aspect-ratio: 16 / 9;
  }
}

.media-frame {
  position: absolute;
  inset: 0;
  transition: transform var(--dur-slow) var(--ease-out);
}

.portfolio-card:hover .media-frame {
  transform: scale(1.06);
}

.media-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.28'/></svg>");
  mix-blend-mode: overlay;
  opacity: 0.6;
}

.media-frame.tone-1 { background: linear-gradient(145deg, #3a1710, #0a0a0c 65%); }
.media-frame.tone-2 { background: linear-gradient(145deg, #1a2b12, #0a0a0c 65%); }
.media-frame.tone-3 { background: linear-gradient(145deg, #2a1233, #0a0a0c 65%); }
.media-frame.tone-4 { background: linear-gradient(145deg, #123028, #0a0a0c 65%); }
.media-frame.tone-5 { background: linear-gradient(145deg, #332312, #0a0a0c 65%); }
.media-frame.tone-6 { background: linear-gradient(145deg, #1c1f36, #0a0a0c 65%); }

.card-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.05) 55%);
}

.card-play {
  position: absolute;
  top: 50%;
  inset-inline-start: 50%;
  transform: translate(-50%, -50%) scale(0.85);
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background: transparent;
  border: 1.5px solid #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}

/* The triangle path below has its centroid (not bounding box) at the
   viewBox center (12,12): vertices (9,5), (19,12), (9,19) average to
   exactly (12,12). A bbox-centered triangle looks left-heavy — its flat
   edge is solid ink while its tip is empty space, so the eye reads the
   bbox-centered version as off-center. Centroid-centering matches how the
   shape actually looks balanced, with no margin hack needed either way. */
.card-play svg {
  width: 20px;
  height: 20px;
  fill: #fff;
}

.portfolio-card:hover .card-play,
.portfolio-card:focus-visible .card-play {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

.card-info {
  position: absolute;
  bottom: 0;
  inset-inline: 0;
  padding: var(--space-5);
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: var(--space-3);
}

.card-info h3 {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: var(--fs-body);
  font-weight: 800;
  text-transform: uppercase;
}

.card-title-kicker {
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--fg-muted);
}

.card-title-main {
  font-size: var(--fs-body);
  font-weight: 800;
  color: var(--fg);
}

.card-info .tag {
  font-size: var(--fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--accent);
  white-space: nowrap;
}

/* ==========================================================================
   Portfolio header + intro (portfolio.html) — the header here is
   deliberately minimal (logo + 2 in-page links + a WhatsApp CTA, no links
   back to the main site), so unlike the main site's header it never needs
   to collapse into a burger/mobile-nav — nav-links and nav-cta just stay
   visible at every width.
   ========================================================================== */

.portfolio-header .nav-links {
  display: flex;
}

.portfolio-header .nav-cta {
  display: inline-flex;
  padding: var(--space-3) var(--space-5);
  min-height: 40px;
}

/* At narrow widths the full wordmark + 2 links + CTA don't fit on one row
   (unlike the main site's header, which collapses to a burger instead) —
   wrap into two rows, logo on its own line, with a taller fixed-header
   clearance to match. */
@media (max-width: 640px) {
  .portfolio-header {
    padding-block: var(--space-3);
  }

  .portfolio-header .nav-inner {
    flex-wrap: wrap;
    justify-content: center;
    row-gap: var(--space-3);
  }

  .portfolio-header .brand {
    order: -1;
    width: 100%;
    justify-content: center;
    font-size: 1.05rem;
  }

  .portfolio-header .nav-cta {
    padding: var(--space-2) var(--space-4);
    min-height: auto;
    font-size: var(--fs-xs);
  }

  .portfolio-intro {
    padding-top: calc(var(--space-8) + 108px);
  }
}

.portfolio-intro {
  padding-top: calc(var(--space-8) + 64px);
  padding-bottom: var(--space-7);
}

.portfolio-intro .hero-tagline {
  max-width: none;
  white-space: nowrap;
}

@media (max-width: 640px) {
  .portfolio-intro .hero-tagline {
    white-space: normal;
  }
}

/* ==========================================================================
   Video wall (portfolio.html) — every real project tiled edge-to-edge.
   Reuses .portfolio-card and its children as-is (hover-preview + lightbox
   JS already targets that class generically), just in a dedicated
   full-bleed grid instead of the carousel/magazine layouts used elsewhere.
   ========================================================================== */

.video-wall-section {
  padding-top: 0;
}

.video-wall-section .section-head {
  padding-top: var(--space-8);
  margin-bottom: var(--space-6);
}

.video-wall-section .section-head h2,
.vertical-wall-section .section-head h2 {
  font-size: var(--fs-h2);
}

/* No hover play-icon on this page — the poster-to-video swap on hover is
   affordance enough, and it's a cleaner look for a dense video wall. */
#videoWall .card-play,
.vertical-wall .card-play {
  display: none;
}

.video-wall {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 2px;
}

/* #videoWall (id specificity) deliberately overrides the .portfolio-card
   nth-child span rules further up this file — those are unscoped and meant
   for .portfolio-grid's magazine layout, but their bare-class selector
   would otherwise leak into any page reusing .portfolio-card. */
#videoWall .portfolio-card {
  grid-column: span 1;
  border-radius: 0;
}

.video-wall .card-media {
  aspect-ratio: 4 / 5;
}

@media (min-width: 768px) {
  .video-wall-section {
    min-height: 100dvh;
    padding-bottom: 0;
    display: flex;
    flex-direction: column;
  }

  .video-wall {
    flex: 1;
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: repeat(3, minmax(220px, 1fr));
  }

  .video-wall .card-media {
    aspect-ratio: auto;
    height: 100%;
  }
}

/* Vertical-format carousel (portfolio.html) — 9:16 reels/social cuts,
   separate from the landscape video wall above. One row, same
   side-nav-arrow + dots navigation pattern as the main site's portfolio
   carousel, but each slide is narrower than the track so the neighboring
   slides peek in on both sides — with 9 real reels there's almost always a
   real video peeking on each side, not empty space. */
.vertical-carousel-track {
  position: relative;
  overflow: hidden;
}

.vertical-carousel-slides {
  display: flex;
  gap: var(--space-4);
  transition: transform var(--dur-slow) var(--ease-in-out);
}

[dir="rtl"] .vertical-carousel-slides {
  flex-direction: row-reverse;
}

/* Sized off the viewport (with a cap matching the old container-relative
   size) rather than the track's own width, so widening the track to full
   bleed below reveals more peeking neighbors instead of enlarging each
   card. */
.vertical-carousel-slide {
  flex: 0 0 auto;
  width: calc(66vw - 32px);
}

.vertical-wall .card-media {
  aspect-ratio: 9 / 16;
}

@media (min-width: 640px) {
  .vertical-carousel-slide {
    width: min(38vw, 572px);
  }
}

@media (min-width: 1024px) {
  .vertical-carousel-slide {
    width: min(22vw, 331px);
  }
}

/* Category tag hidden on portfolio.html's grids — title only. The
   attribute is still read from data-tag-en/he for the lightbox's own tag
   display, this just hides the card-info's visible copy. */
#videoWall .card-info .tag,
.vertical-wall .card-info .tag {
  display: none;
}

/* ==========================================================================
   Lightbox modal
   ========================================================================== */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  background: rgba(6, 6, 7, 0.9);
  backdrop-filter: blur(10px);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-out);
}

.lightbox.is-open {
  opacity: 1;
  pointer-events: auto;
}

.lightbox-panel {
  width: min(100%, 960px);
  transform: translateY(24px) scale(0.98);
  opacity: 0;
  transition: transform var(--dur-slow) var(--ease-out), opacity var(--dur-slow) var(--ease-out);
}

.lightbox.is-open .lightbox-panel {
  transform: translateY(0) scale(1);
  opacity: 1;
}

.lightbox-media {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-md);
  overflow: hidden;
}

/* Reels opened from the vertical carousel are 9:16 — size the panel by
   height (not the usual fixed width) so a portrait video reads as a tall
   player instead of a 16:9 frame with the actual footage letterboxed
   inside it. */
.lightbox-panel.is-vertical {
  width: min(90vw, calc(80vh * 9 / 16));
}

.lightbox-media.is-vertical {
  aspect-ratio: 9 / 16;
}

.lightbox-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: var(--space-5);
  gap: var(--space-4);
}

.lightbox-info h3 {
  font-size: var(--fs-h3);
  text-transform: uppercase;
}

.lightbox-close {
  position: absolute;
  top: var(--space-5);
  inset-inline-end: var(--space-5);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}

.lightbox-close:hover {
  background: var(--fg);
  color: var(--bg);
  transform: rotate(90deg);
}

.lightbox-close svg {
  width: 18px;
  height: 18px;
}

.lightbox-note {
  font-size: var(--fs-xs);
  color: var(--fg-faint);
  text-align: center;
  padding-top: var(--space-5);
}

/* Lightbox video (real playback once a file exists; hidden otherwise —
   falls back to the .media-frame gradient + .lightbox-note link) */
.lightbox-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: none;
}

.lightbox-video.is-active {
  display: block;
}

.lightbox-media.is-video-mode .media-frame,
.lightbox-media.is-video-mode .card-scrim {
  display: none;
}

/* ==========================================================================
   About / Services
   ========================================================================== */

.about-grid {
  display: grid;
  gap: var(--space-8);
}

@media (min-width: 1024px) {
  .about-grid {
    grid-template-columns: 0.9fr 1.1fr;
    align-items: start;
  }
}

.about-portrait {
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: linear-gradient(160deg, #241014, var(--bg) 70%);
}

.about-portrait::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.3'/></svg>");
  mix-blend-mode: overlay;
}

.about-badge {
  position: absolute;
  bottom: var(--space-5);
  inset-inline-start: var(--space-5);
  background: rgba(10, 10, 12, 0.6);
  backdrop-filter: blur(10px);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
}

.about-badge strong {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  color: var(--accent);
}

.about-badge span {
  font-size: var(--fs-xs);
  color: var(--fg-muted);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.about-copy p {
  color: var(--fg-muted);
  margin-bottom: var(--space-4);
  max-width: 62ch;
}

/* Main site's about-copy is no longer paired with a portrait column (see
   .about-byline below instead), so cap its own width for a comfortable
   editorial measure — scoped to when it's a direct child of .container so
   this doesn't affect the wedding page's still-two-column about-grid. */
.container > .about-copy {
  max-width: 760px;
}

.about-byline {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.about-avatar {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  border: 2px solid var(--border-strong);
}

.about-byline strong {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-body);
  font-weight: 700;
}

.about-byline span {
  display: block;
  font-size: var(--fs-sm);
  color: var(--fg-muted);
}

.about-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-5);
  margin-top: var(--space-7);
  padding-top: var(--space-6);
  border-top: 1px solid var(--border);
}

/* portfolio.html only: its about-stats sits in its own .container, a
   sibling of the copy block rather than nested inside .about-copy (see
   .about-divider below, a full-bleed sibling of both containers) — so the
   divider supplies the line and the top gap instead of this rule doing it. */
.container > .about-stats {
  max-width: 760px;
  margin-top: 0;
  padding-top: var(--space-8);
  border-top: none;
}

.about-divider {
  margin-top: var(--space-9);
  border-top: 1px solid var(--border);
}

.about-stats div strong {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-h1);
  color: var(--fg);
}

.about-stats div span {
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--fg-faint);
}

@media (max-width: 480px) {
  .about-stats {
    gap: var(--space-3);
  }

  .about-stats div strong {
    font-size: 1.75rem;
  }
}

/* Services */
.services-list {
  display: grid;
  gap: var(--space-4);
  margin-top: var(--space-8);
}

.service-card {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  padding: var(--space-6);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  transition: border-color var(--dur-base) var(--ease-out), background-color var(--dur-base) var(--ease-out);
}

@media (min-width: 768px) {
  .service-card {
    grid-template-columns: auto 1fr auto;
    align-items: center;
  }
}

.service-card:hover {
  border-color: var(--border-strong);
  background: var(--bg-elevated);
}

.service-card.is-featured {
  border-color: var(--primary);
  background: linear-gradient(120deg, rgba(157, 193, 131, 0.08), transparent 60%);
}

.service-num {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  color: var(--fg-faint);
}

.service-card.is-featured .service-num {
  color: var(--primary);
}

.service-body h3 {
  font-size: var(--fs-h3);
  margin-bottom: var(--space-2);
}

.service-body p {
  color: var(--fg-muted);
  max-width: 52ch;
}

.service-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.service-tags span {
  font-size: var(--fs-xs);
  padding: 4px 10px;
  border-radius: var(--radius-full);
  border: 1px solid var(--border-strong);
  color: var(--fg-muted);
}

.service-price {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  white-space: nowrap;
  text-align: end;
}

.service-price span {
  display: block;
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 400;
  color: var(--fg-faint);
  text-transform: uppercase;
}

/* ==========================================================================
   Testimonials
   ========================================================================== */

.testimonial-wrap {
  position: relative;
}

.testimonial-track {
  overflow: hidden;
}

.testimonial-slides {
  display: flex;
  transition: transform var(--dur-slow) var(--ease-in-out);
}

[dir="rtl"] .testimonial-slides {
  flex-direction: row-reverse;
}

.testimonial-slide {
  flex: 0 0 100%;
  padding-inline-end: var(--space-6);
}

.testimonial-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-8);
  background: var(--bg-elevated);
}

.testimonial-quote-icon {
  width: 36px;
  height: 36px;
  color: var(--primary);
  margin-bottom: var(--space-5);
}

.testimonial-text {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--fs-h3);
  line-height: 1.4;
  max-width: 60ch;
  margin-bottom: var(--space-6);
}

.testimonial-person {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.testimonial-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: linear-gradient(140deg, var(--primary), var(--accent));
  flex-shrink: 0;
}

.testimonial-person strong {
  display: block;
  font-size: var(--fs-body);
}

.testimonial-person span {
  font-size: var(--fs-sm);
  color: var(--fg-faint);
}

.testimonial-controls {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: var(--space-6);
}

/* Portfolio carousel controls are dots-only now (prev/next moved to the
   full-height .portfolio-side-nav zones), so center rather than space-between. */
.portfolio-controls {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: var(--space-6);
}

.testimonial-controls.is-hidden,
.portfolio-controls.is-hidden {
  display: none;
}

.testimonial-dots,
.portfolio-dots {
  display: flex;
  gap: var(--space-2);
}

/* Keep dot order matching the slides' physical order (forced LTR-consistent
   above, same reasoning as the arrows) — without this, Hebrew's natural
   flex reversal would put dot 1 on the right while slide 1 is still
   physically on the left, so the dots would appear to move backwards. */
[dir="rtl"] .portfolio-dots {
  flex-direction: row-reverse;
}

/* The vertical reel carousel's dots use the same row-reverse as the rule
   above (not a plain `row` override) — the carousel physically moves
   right-to-left (next reel peeks in from the right), so for the dot
   immediately right of the active one to correctly represent that
   right-peeking reel (and the one to its left to represent the
   left-peeking reel), dot order has to increase moving rightward, same
   direction as the slides themselves. */

.testimonial-dots button,
.portfolio-dots button {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--border-strong);
  transition: background-color var(--dur-base) var(--ease-out), width var(--dur-base) var(--ease-out);
}

.testimonial-dots button.is-active,
.portfolio-dots button.is-active {
  background: var(--accent);
  width: 24px;
  border-radius: var(--radius-full);
}

.testimonial-nav {
  display: flex;
  gap: var(--space-3);
}

.testimonial-nav button {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color var(--dur-base) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}

.testimonial-nav button:hover {
  background: var(--fg);
  color: var(--bg);
}

.testimonial-nav button:active {
  transform: scale(0.94);
}

.testimonial-nav svg {
  width: 18px;
  height: 18px;
}

[dir="rtl"] .testimonial-nav svg {
  transform: scaleX(-1);
}

/* Client logo strip */
.clients-strip {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-5);
  margin-top: var(--space-8);
}

@media (min-width: 768px) {
  .clients-strip {
    grid-template-columns: repeat(4, 1fr);
  }
}

.client-logo {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-6) var(--space-4);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-body);
  color: var(--fg-faint);
  text-align: center;
  transition: color var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
}

.client-logo:hover {
  color: var(--fg);
  border-color: var(--border-strong);
}

/* Real logo files come with their own brand colors (often dark wordmarks
   meant for light backgrounds), so they sit on a light card instead of
   inheriting the dark card treatment above — keeps every logo legible
   regardless of its own palette. */
.client-logo.is-image {
  background: #f5f4f0;
  border-color: transparent;
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}

.client-logo.is-image img {
  max-width: 100%;
  max-height: 34px;
  object-fit: contain;
  display: block;
}

.client-logo.is-image:hover {
  border-color: transparent;
  transform: translateY(-2px);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.25);
}

/* ==========================================================================
   Contact
   ========================================================================== */

.contact-section {
  background: var(--bg-elevated);
  border-radius: var(--radius-lg);
  margin-inline: var(--space-5);
  padding: var(--space-8) var(--space-5);
  overflow: hidden;
  position: relative;
}

@media (min-width: 768px) {
  .contact-section {
    margin-inline: var(--space-7);
    padding: var(--space-9);
  }
}

.contact-grid {
  display: grid;
  gap: var(--space-8);
  position: relative;
}

@media (min-width: 1024px) {
  .contact-grid {
    grid-template-columns: 1fr 1fr;
  }
}

.contact-info h2 {
  font-size: var(--fs-h1);
  text-transform: uppercase;
  margin-bottom: var(--space-5);
}

.contact-channels {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-top: var(--space-6);
}

.contact-channel {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  transition: border-color var(--dur-base) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}

.contact-channel:hover {
  border-color: var(--accent);
  transform: translateX(4px);
}

[dir="rtl"] .contact-channel:hover {
  transform: translateX(-4px);
}

.contact-channel .icon-wrap {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.contact-channel svg {
  width: 20px;
  height: 20px;
  color: var(--accent);
}

.contact-channel strong {
  display: block;
  font-size: var(--fs-body);
}

.contact-channel span {
  font-size: var(--fs-sm);
  color: var(--fg-faint);
}

/* Form */
.contact-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.form-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
}

@media (min-width: 640px) {
  .form-row.two-col {
    grid-template-columns: 1fr 1fr;
  }
}

.field {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.field label {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--fg-muted);
}

.field .required {
  color: var(--primary);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: var(--space-4);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  min-height: 48px;
  transition: border-color var(--dur-base) var(--ease-out);
}

.field textarea {
  min-height: 120px;
  resize: vertical;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--accent);
}

.field-help {
  font-size: var(--fs-xs);
  color: var(--fg-faint);
}

.field-error {
  font-size: var(--fs-xs);
  color: var(--primary);
  display: none;
}

.field.has-error input,
.field.has-error textarea {
  border-color: var(--primary);
}

.field.has-error .field-error {
  display: block;
}

.form-status {
  font-size: var(--fs-sm);
  padding: var(--space-4);
  border-radius: var(--radius-sm);
  background: rgba(227, 201, 155, 0.1);
  color: var(--accent);
  display: none;
}

.form-status.is-visible {
  display: block;
}

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer {
  padding-block: var(--space-8) var(--space-6);
}

.footer-top {
  display: grid;
  gap: var(--space-8);
  padding-bottom: var(--space-8);
  border-bottom: 1px solid var(--border);
}

@media (min-width: 1024px) {
  .footer-top {
    grid-template-columns: 1.4fr 0.6fr 0.6fr;
  }
}

.footer-brand p {
  color: var(--fg-muted);
  max-width: 34ch;
  margin-top: var(--space-4);
}

.footer-col h4 {
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--fg-faint);
  margin-bottom: var(--space-4);
}

.footer-col ul {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.footer-col a {
  color: var(--fg-muted);
  transition: color var(--dur-base) var(--ease-out);
}

.footer-col a.footer-contact-link {
  color: var(--fg);
}

.footer-col a:hover {
  color: var(--accent);
}

.footer-social {
  display: flex;
  gap: var(--space-3);
}

.footer-social a {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color var(--dur-base) var(--ease-out), color var(--dur-base) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}

.footer-social a:hover {
  background: var(--accent);
  color: var(--accent-fg);
  transform: translateY(-3px);
}

.footer-social svg {
  width: 17px;
  height: 17px;
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-4);
  padding-top: var(--space-6);
  font-size: var(--fs-xs);
  color: var(--fg-faint);
}

.back-to-top {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: 700;
  color: var(--fg-muted);
  transition: color var(--dur-base) var(--ease-out);
}

.back-to-top:hover {
  color: var(--accent);
}

.back-to-top svg {
  width: 16px;
  height: 16px;
}

/* ==========================================================================
   Reveal / motion utility classes (driven by GSAP, CSS = no-JS fallback)
   ========================================================================== */

[data-reveal] {
  opacity: 1;
}

.js-ready [data-reveal] {
  opacity: 0;
}

.no-js [data-reveal] {
  opacity: 1 !important;
}

/* Custom cursor (desktop pointer only) */
.cursor-dot {
  position: fixed;
  top: 0;
  left: 0;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  pointer-events: none;
  z-index: 300;
  transform: translate(-50%, -50%);
  mix-blend-mode: difference;
  display: none;
}

.cursor-ring {
  position: fixed;
  top: 0;
  left: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--fg);
  pointer-events: none;
  z-index: 300;
  transform: translate(-50%, -50%);
  transition: width var(--dur-base) var(--ease-out), height var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out), opacity var(--dur-base) var(--ease-out);
  display: none;
}

@media (hover: hover) and (pointer: fine) {
  .cursor-dot,
  .cursor-ring {
    display: block;
  }
}

.cursor-ring.is-active {
  width: 64px;
  height: 64px;
  border-color: var(--accent);
}

/* Preloader */
.preloader {
  position: fixed;
  inset: 0;
  z-index: 500;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-5);
  transition: opacity var(--dur-slow) var(--ease-out), visibility var(--dur-slow) var(--ease-out);
}

.preloader.is-hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.preloader-word {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(1.5rem, 5vw, 2.5rem);
  letter-spacing: 0.02em;
  white-space: nowrap;
  /* No per-letter reveal animation here (unlike .hero-title's .line masks),
     so this overflow:hidden was serving no purpose — except clipping the
     right edge on mobile during the brief window before the real web font
     loads, when the browser substitutes a fallback font whose metrics are
     wider at the same font-size/weight. Letting it render slightly wide for
     a moment (self-corrects once the font loads) beats cutting it off. */
}

.preloader-bar {
  width: 200px;
  height: 2px;
  background: var(--border-strong);
  overflow: hidden;
  border-radius: var(--radius-full);
}

.preloader-bar span {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--primary);
}

/* ==========================================================================
   Reduced motion
   ========================================================================== */

@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;
  }

  .marquee-track {
    animation: none;
  }

  .js-ready [data-reveal] {
    opacity: 1;
  }
}

/* ==========================================================================
   RTL fine-tuning
   ========================================================================== */

[dir="rtl"] .eyebrow::before {
  order: 2;
}

[dir="rtl"] .hero-meta {
  text-align: right;
}

[dir="rtl"] .about-stats {
  text-align: center;
}
