html { scroll-behavior: smooth; }
body { font-family: "Manrope", sans-serif; }
h1,h2,h3,h4,h5,h6 { text-wrap: balance; }
::-webkit-scrollbar { width: 4px; }
::-webkit-scrollbar-track { background: #C8DAE6; }
::-webkit-scrollbar-thumb { background: #4A6A79; border-radius: 99px; }

/* Drawer */
#mob-drawer { transform: translateX(100%); transition: transform .36s cubic-bezier(.32,0,.2,1); }
#mob-drawer.open { transform: translateX(0); }
#drawer-overlay { opacity: 0; pointer-events: none; transition: opacity .32s ease; }
#drawer-overlay.open { opacity: 1; pointer-events: all; }

/* Search */
#search-overlay { transform: translateY(-100%); transition: transform .32s cubic-bezier(.32,0,.2,1); }
#search-overlay.open { transform: translateY(0); }

/* Marquee */
@keyframes marquee { 0%{transform:translateX(0)} 100%{transform:translateX(-50%)} }
.marquee-track { animation: marquee 32s linear infinite; }
.marquee-wrap:hover .marquee-track { animation-play-state: paused; }

/* Sticky project overlap */
.proj-wrap { position: sticky; }
.proj-wrap-1 { top: 72px; }
.proj-wrap-2 { top: 84px; }
.proj-wrap-3 { top: 96px; }
.proj-wrap-4 { top: 108px; }

/* Reveal */
.reveal { opacity: 0; transform: translateY(20px); transition: opacity .55s ease, transform .55s ease; }
.reveal.visible { opacity: 1; transform: translateY(0); }

/* Proj card */
.proj-card { aspect-ratio: 16/9; transform-origin: center top; will-change: transform, opacity; }

/* Pulse dot */
@keyframes pulse { 0%,100%{opacity:1;transform:scale(1)} 50%{opacity:.5;transform:scale(.75)} }
.pulse-dot { animation: pulse 2s infinite; }

/* ── HERO VARIANTS ── */
.heroA-pulse, .heroB-pulse, .heroC-pulse, .heroFinal-pulse { animation: pulse 2s infinite; }
.heroA-video, .heroC-video { transition: opacity .6s ease; }
.heroB-video { transition: opacity 1s ease; }
.heroA-video.is-ready, .heroB-video.is-ready, .heroC-video.is-ready { opacity: 1; }

/* ── 404 ANIMATIONS ── */
@keyframes float { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-14px)} }
.float-1 { animation: float 5s ease-in-out infinite; }
.float-2 { animation: float 6.5s ease-in-out infinite; animation-delay: .6s; }
.float-3 { animation: float 4.2s ease-in-out infinite; animation-delay: 1.1s; }

/* FAQ Accordion (site-wide pattern: .faq-item / .faq-btn / .faq-body / .faq-arrow, driven by main.js) */
.faq-body { max-height: 0; overflow: hidden; transition: max-height .35s ease; }
.faq-arrow { transition: transform .3s ease; }
.faq-item.faq-open .faq-arrow { transform: rotate(45deg); }

/* ── POLISH: CTA buttons ──
   Note: timing comes from each element's own Tailwind `transition-*` utility class
   (added alongside .btn-cta in markup) so it never fights the .reveal scroll-in
   transition on elements that carry both classes — these rules only add the
   hover/focus END STATE, not a competing `transition:` shorthand. */
.btn-cta:hover { transform: translateY(-1px) scale(1.015); }
.btn-cta:active { transform: translateY(0) scale(0.99); }
.btn-cta:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(200,218,230,.5); }

/* ── POLISH: static info cards (non-clickable, but still get a bit of life on hover) ── */
.info-card:hover { transform: translateY(-3px); box-shadow: 0 14px 32px -20px rgba(41,56,75,.35); }

/* ── POLISH: image reveal zoom (deep dives, editorial image blocks) ── */
.img-zoom { overflow: hidden; }
.img-zoom img { transition: transform .7s cubic-bezier(.16,1,.3,1); }
.img-zoom:hover img { transform: scale(1.06); }

/* ── WHATSAPP FLOATING BUTTON ── */
@keyframes wa-pulse-ring { 0%{box-shadow:0 0 0 0 rgba(37,211,102,.45)} 100%{box-shadow:0 0 0 14px rgba(37,211,102,0)} }
.whatsapp-fab { animation: wa-pulse-ring 2.4s ease-out infinite; }
.whatsapp-fab:hover { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) { .whatsapp-fab { animation: none; } }

/* ── PROOF GALLERY SLIDER ── */
.scrollbar-hide { scrollbar-width: none; -ms-overflow-style: none; }
.scrollbar-hide::-webkit-scrollbar { display: none; }
.proof-slider { cursor: grab; scroll-behavior: smooth; }
.proof-slider.is-dragging { cursor: grabbing; scroll-behavior: auto; }
.proof-slider.is-dragging .proof-slide { pointer-events: none; }
.proof-fade { transition: opacity .25s ease; }
.proof-fade.is-hidden { opacity: 0; }

/* ── STAGGERED REVEAL DELAYS ──
   The house rule is no style="" attributes in markup, so the per-card
   transition delays that used to be inline are these classes instead.
   Templates pick one with gs_delay_class( $index ). */
.gs-d-0 { transition-delay: 0ms; }
.gs-d-1 { transition-delay: 60ms; }
.gs-d-2 { transition-delay: 120ms; }
.gs-d-3 { transition-delay: 180ms; }
.gs-d-4 { transition-delay: 240ms; }
.gs-d-5 { transition-delay: 300ms; }
.gs-d-6 { transition-delay: 360ms; }
.gs-d-7 { transition-delay: 420ms; }
.gs-d-8 { transition-delay: 480ms; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  [class*="gs-d-"] { transition-delay: 0ms; }
}

/* ── FAQ: always-open variant (was an inline max-height) ── */
.faq-body--open { max-height: none; }

/* ── EDITOR CONTENT (page.php, index.php, single posts) ──
   Moved out of the per-template <style> blocks so it is cached with the
   stylesheet instead of being re-sent inside every page body. */
.gs-prose h1,
.gs-prose h2,
.gs-prose h3,
.gs-prose h4,
.gs-prose h5,
.gs-prose h6 {
  color: #29384b;
  font-weight: 800;
  margin-top: 2rem;
  margin-bottom: 1rem;
  line-height: 1.25;
}
.gs-prose h1 { font-size: clamp(1.75rem, 4vw, 2.25rem); }
.gs-prose h2 { font-size: clamp(1.5rem, 3.5vw, 1.875rem); }
.gs-prose h3 { font-size: clamp(1.25rem, 3vw, 1.5rem); }
.gs-prose h4 { font-size: 1.125rem; }
.gs-prose p {
  color: rgba(41, 56, 75, 0.8);
  line-height: 1.8;
  margin-bottom: 1.25rem;
}
.gs-prose ul { list-style: disc; margin-left: 1.5rem; margin-bottom: 1.25rem; }
.gs-prose ol { list-style: decimal; margin-left: 1.5rem; margin-bottom: 1.25rem; }
.gs-prose li { margin-bottom: 0.5rem; color: rgba(41, 56, 75, 0.8); }
.gs-prose a { color: #4a6a79; text-decoration: underline; font-weight: 600; }
.gs-prose a:hover { color: #29384b; }
.gs-prose blockquote {
  border-left: 3px solid #c8dae6;
  padding-left: 1.25rem;
  margin: 1.5rem 0;
  font-style: italic;
  color: rgba(41, 56, 75, 0.75);
}
.gs-prose img { border-radius: 1rem; margin: 1.5rem 0; height: auto; }
.gs-prose table { width: 100%; border-collapse: collapse; margin: 1.5rem 0; font-size: 0.9rem; }
.gs-prose th,
.gs-prose td { border: 1px solid #c8dae6; padding: 0.6rem 0.8rem; text-align: left; }
.gs-prose th { background: #f3f0eb; font-weight: 700; color: #29384b; }
.gs-prose code {
  background: #f3f0eb;
  border-radius: 0.35rem;
  padding: 0.1rem 0.35rem;
  font-size: 0.875em;
}
.gs-prose pre {
  background: #29384b;
  color: #f3f0eb;
  border-radius: 1rem;
  padding: 1.1rem 1.25rem;
  overflow-x: auto;
  margin: 1.5rem 0;
}
.gs-prose pre code { background: transparent; padding: 0; color: inherit; }

/* ── PAGINATION (search.php, index.php) ── */
.gs-pagination .nav-links { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.gs-pagination a,
.gs-pagination span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.5rem;
  height: 2.5rem;
  padding: 0 0.75rem;
  border-radius: 0.5rem;
  font-size: 0.875rem;
  font-weight: 800;
  transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
}
.gs-pagination .page-numbers { background: #fff; border: 1px solid #c8dae6; color: #29384b; }
.gs-pagination .page-numbers:hover { border-color: #4a6a79; color: #4a6a79; }
.gs-pagination .page-numbers.current { background: #29384b; border-color: #29384b; color: #fff; }
.gs-pagination .screen-reader-text {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ── CONTACT FORM ── */

/* Honeypot. Hidden from people and from screen readers, still submitted by a
   bot that fills every input it finds. Not display:none, because some bots
   skip those. */
.gs-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.gs-field-invalid {
  border-color: #dc2626 !important;
  box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.12);
}

.gs-form-error { margin-top: -0.25rem; }

.gs-form-submit[disabled] { cursor: not-allowed; opacity: 0.6; }

/* ── ACCESSIBILITY: visible focus for keyboard users ── */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid #4a6a79;
  outline-offset: 2px;
}

/* ── VIDEO REELS ──
   9:16 cards in a horizontal snap-scroller. Every card reserves its exact
   aspect ratio before anything loads, so promoting a reel from poster to
   video causes no layout shift at all. */

.gs-reels {
  /* Explicit list reset: the markup is a <ul> for semantics, and relying on
     Tailwind's preflight to strip the markers breaks the moment the CDN is
     swapped for a compiled build with preflight disabled. */
  list-style: none;
  margin: 0;
  padding-left: 0.25rem;
  scroll-padding-inline: 0.25rem;
}

.gs-reels > li { list-style: none; }

.gs-reel { width: clamp(13rem, 62vw, 17rem); }

@media (min-width: 640px) { .gs-reel { width: 15rem; } }
@media (min-width: 1024px) { .gs-reel { width: 16rem; } }

.gs-reel__frame {
  position: relative;
  aspect-ratio: 9 / 16;
  width: 100%;
  overflow: hidden;
  border-radius: 1.25rem;
  background: #29384b;
  border: 1px solid rgba(200, 218, 230, 0.6);
  box-shadow: 0 10px 30px -22px rgba(41, 56, 75, 0.6);
  isolation: isolate;
}

/* The poster is a real <img>, so it gets srcset and native lazy loading.
   It sits above the video until the video can genuinely paint a frame, which
   is what prevents the flash of black on slow connections. */
.gs-reel__poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 2;
  transition: opacity 0.45s ease;
}

.gs-reel__poster--empty {
  display: block;
  background: linear-gradient(140deg, #29384b 0%, #4a6a79 100%);
}

.gs-reel__frame.is-ready .gs-reel__poster { opacity: 0; }

.gs-reel__video,
.gs-reel__iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  border: 0;
  display: block;
}

.gs-reel__video { object-fit: cover; background: #29384b; }

/* Play badge: visible while the card is idle, gone once it is playing. */
.gs-reel__play {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  transition: opacity 0.3s ease;
}

.gs-reel__play-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  color: #29384b;
  box-shadow: 0 6px 20px -6px rgba(0, 0, 0, 0.45);
  transition: transform 0.2s ease, background 0.2s ease;
}

.gs-reel__play-icon svg { width: 1.3rem; height: 1.3rem; margin-left: 0.15rem; }

.gs-reel__play:hover .gs-reel__play-icon { transform: scale(1.08); background: #fff; }

.gs-reel__frame.is-loading .gs-reel__play,
.gs-reel__frame.is-playing .gs-reel__play {
  opacity: 0;
  pointer-events: none;
}

/* Buffering spinner, shown only between promotion and first frame. */
.gs-reel__spinner {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 4;
  width: 2rem;
  height: 2rem;
  margin: -1rem 0 0 -1rem;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.28);
  border-top-color: #fff;
  opacity: 0;
  pointer-events: none;
  animation: gs-reel-spin 0.8s linear infinite;
}

.gs-reel__frame.is-loading .gs-reel__spinner { opacity: 1; }

@keyframes gs-reel-spin { to { transform: rotate(360deg); } }

.gs-reel__badge {
  position: absolute;
  top: 0.6rem;
  left: 0.6rem;
  z-index: 3;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: rgba(41, 56, 75, 0.72);
  backdrop-filter: blur(4px);
  color: #fff;
  font-size: 0.55rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.gs-reel__frame.is-playing .gs-reel__badge { opacity: 0; }

/* A video that failed to load keeps its poster and shows the play button
   again, so the card is never a dead black rectangle. */
.gs-reel__frame.is-failed .gs-reel__poster { opacity: 1; }
.gs-reel__frame.is-failed .gs-reel__play { opacity: 1; pointer-events: auto; }

.gs-reel__meta { margin-top: 0.7rem; }

.gs-reel__title {
  font-size: 0.82rem;
  font-weight: 800;
  line-height: 1.35;
}

.gs-reel__caption {
  margin-top: 0.15rem;
  font-size: 0.72rem;
  font-weight: 500;
  line-height: 1.5;
}

.gs-reels-fade { transition: opacity 0.25s ease; }
.gs-reels-fade.is-hidden { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .gs-reel__spinner { animation: none; }
  .gs-reel__poster { transition: none; }
}
