@import url('https://fonts.googleapis.com/css2?family=Big+Shoulders+Display:wght@700;800;900&family=Work+Sans:wght@400;500;600;700&display=swap');

:root {
  --pra-black: #000000;
  --pra-surface-1: #0B0D12;
  --pra-surface-2: #14161D;
  --pra-cream: #F5F2EC;
  --pra-hairline: rgba(255, 255, 255, 0.08);
  --pra-white: #FFFFFF;
  --pra-blue-300: #B2B9E2;
  --pra-blue-400: #7985CD;
  --pra-blue-500: #3F51B7;
  --pra-blue-600: #36459C;
  --pra-whatsapp: #25D366;
  --pra-whatsapp-dark: #1DA851;

  /* Stronger, more intentional easing than the browser defaults */
  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);
}

* {
  -webkit-tap-highlight-color: transparent;
}

html {
  scroll-behavior: smooth;
}

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

body {
  background: var(--pra-black);
  color: var(--pra-white);
  font-family: 'Work Sans', sans-serif;
  line-height: 1.7;
  position: relative;
}

/* Themed browser surfaces: the parts a design system usually forgets to draw */
::selection {
  background: var(--pra-blue-500);
  color: var(--pra-white);
}
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-track {
  background: var(--pra-black);
}
::-webkit-scrollbar-thumb {
  background: var(--pra-blue-600);
  border-radius: 999px;
  border: 2px solid var(--pra-black);
}
::-webkit-scrollbar-thumb:hover {
  background: var(--pra-blue-500);
}

.font-display {
  font-family: 'Big Shoulders Display', sans-serif;
  letter-spacing: -0.03em;
  line-height: 0.95;
}

/* Grain texture overlay, sits above black sections without affecting layout */
.grain-overlay {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.035;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Chrome-trim divider: signature hairline used instead of a plain border */
.chrome-trim {
  height: 1px;
  border: none;
  background: linear-gradient(90deg, transparent, var(--pra-blue-400), transparent);
  opacity: 0.6;
}
.chrome-trim.on-light {
  background: linear-gradient(90deg, transparent, var(--pra-blue-600), transparent);
  opacity: 0.35;
}

/* Paint-sheen sweep: signature hover motif for pill buttons.
   The sweep itself only triggers on real hover (fine pointer) so it never
   gets stuck "on" after a tap on touch devices; focus-visible still
   triggers it for keyboard users on any device. */
.sheen {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  transition: background-color 200ms var(--ease-out-strong),
    border-color 200ms var(--ease-out-strong),
    transform 150ms var(--ease-out-strong);
}
.sheen:active {
  transform: scale(0.97);
}
.sheen::after {
  content: "";
  position: absolute;
  top: -60%;
  left: -30%;
  width: 35%;
  height: 220%;
  background: linear-gradient(115deg, transparent, rgba(255, 255, 255, 0.4), transparent);
  transform: translateX(-40%) rotate(10deg);
  opacity: 0;
  transition: transform 0.7s var(--ease-out-strong), opacity 0.3s ease;
  pointer-events: none;
  z-index: 1;
}
.sheen:focus-visible::after {
  transform: translateX(340%) rotate(10deg);
  opacity: 1;
}
@media (hover: hover) and (pointer: fine) {
  .sheen:hover::after {
    transform: translateX(340%) rotate(10deg);
    opacity: 1;
  }
}
@media (prefers-reduced-motion: reduce) {
  .sheen::after {
    display: none;
  }
}

/* Focus visibility, applied everywhere interactive */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--pra-blue-400);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Header: always solid/dark (logo requires a dark background at all times);
   the scrolled state only adds depth via blur + a stronger shadow */
#site-header {
  background: rgba(11, 13, 18, 0.98);
  border-bottom: 1px solid var(--pra-hairline);
  transition: box-shadow 300ms var(--ease-out-strong);
}
#site-header.is-scrolled {
  backdrop-filter: blur(10px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45), 0 1px 3px rgba(63, 81, 183, 0.25);
}
#nav-toggle {
  transition: transform 150ms var(--ease-out-strong);
}
#nav-toggle:active {
  transform: scale(0.9);
}

/* Mobile nav panel: grid-rows reveal (no fixed max-height guess, no layout-thrash workaround).
   Scoped below `lg` so it never fights the `lg:hidden` utility that fully removes the panel on desktop. */
@media (max-width: 1023.98px) {
  #mobile-nav {
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    transition: grid-template-rows 350ms var(--ease-in-out-strong), opacity 200ms var(--ease-out-strong);
  }
  #mobile-nav > nav {
    overflow: hidden;
    min-height: 0;
  }
  #mobile-nav.is-open {
    grid-template-rows: 1fr;
    opacity: 1;
  }
}

/* Floating contact pill (mobile only): Call and WhatsApp at equal weight */
.contact-float {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 40;
  display: flex;
  gap: 2px;
  padding: 4px;
  border-radius: 999px;
  background: var(--pra-surface-2);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(63, 81, 183, 0.3);
}
.contact-float > a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 999px;
  color: var(--pra-white);
  transition: background-color 200ms var(--ease-out-strong), transform 150ms var(--ease-out-strong);
}
.contact-float > a:active {
  transform: scale(0.9);
}
.contact-float .call-btn {
  background: var(--pra-blue-500);
}
.contact-float .call-btn:hover,
.contact-float .call-btn:focus-visible {
  background: var(--pra-blue-600);
}
.contact-float .whatsapp-btn {
  background: var(--pra-whatsapp);
}
.contact-float .whatsapp-btn:hover,
.contact-float .whatsapp-btn:focus-visible {
  background: var(--pra-whatsapp-dark);
}

/* Honest empty state for gallery items still awaiting real photos */
.coming-soon-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  text-align: center;
  color: rgba(255, 255, 255, 0.5);
}

/* Reviews carousel. align-items: flex-start keeps each card sized to its own
   content instead of every slide stretching to match the longest review. */
.reviews-track {
  display: flex;
  align-items: flex-start;
  transition: transform 450ms var(--ease-out-strong);
}
.reviews-slide {
  flex: 0 0 100%;
}
.review-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--pra-hairline);
  transition: background-color 200ms var(--ease-out-strong), transform 200ms var(--ease-out-strong);
}
.review-dot.is-active {
  background: var(--pra-blue-400);
  transform: scale(1.25);
}
.review-arrow {
  transition: border-color 200ms var(--ease-out-strong), transform 150ms var(--ease-out-strong);
}
.review-arrow:active {
  transform: scale(0.9);
}

/* Before/after gallery hover swap */
.ba-frame {
  position: relative;
  overflow: hidden;
}
.ba-frame img {
  transition: opacity 300ms ease;
}
.ba-frame .ba-after {
  position: absolute;
  inset: 0;
  opacity: 0;
}
@media (hover: hover) and (pointer: fine) {
  /* :focus-visible, not :focus-within - a mouse click also focuses the tile
     (it carries tabindex="0"), and focus would then keep it stuck on "after"
     after the pointer left, which reads as "hover stopped working".
     :focus-visible only matches keyboard focus, so tabbing still reveals. */
  .ba-frame:hover .ba-after,
  .ba-frame:focus-visible .ba-after {
    opacity: 1;
  }
}
.ba-frame.is-revealed .ba-after {
  opacity: 1;
}

/* Job tiles. The whole tile is one button so the photos are reachable by
   keyboard and announce themselves as openable, not just decorative. */
.job-tile {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0;
  color: inherit;
  cursor: pointer;
}
.job-shot {
  display: block;
  position: relative;
}
.job-shot img {
  display: block;
  transition: transform 400ms var(--ease-out-strong);
}
@media (hover: hover) and (pointer: fine) {
  .job-tile:hover .job-shot img { transform: scale(1.03); }
  .job-tile:hover { border-color: rgba(121, 133, 205, 0.4); }
}
.job-tile:focus-visible {
  outline: 2px solid var(--pra-blue-400);
  outline-offset: 3px;
}
/* Photo count, the affordance that there's more inside. */
.job-count {
  position: absolute;
  top: 0.625rem;
  right: 0.625rem;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.25rem 0.5rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(6px);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1;
}
.job-count svg { width: 0.875rem; height: 0.875rem; }
.job-meta { display: block; padding: 0.75rem 1rem 0.9rem; }
.job-name {
  display: block;
  font-family: 'Big Shoulders Display', sans-serif;
  font-weight: 800;
  font-size: 1.125rem;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  color: var(--pra-white);
}
.job-work {
  display: block;
  font-size: 0.875rem;
  color: rgba(255, 255, 255, 0.55);
}

/* Photo viewer. The strip of slides is a scroll-snap track, so a swipe on a
   phone is just the browser's own scrolling - nothing to intercept - and the
   arrows and dots scroll that same track. */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  /* Near-solid: at 94% the cream title band behind still read through as a
     visible stripe. The blur mops up anything the alpha leaves. */
  background: rgba(0, 0, 0, 0.97);
  backdrop-filter: blur(8px);
  animation: lb-in 180ms var(--ease-out-strong);
}
@keyframes lb-in { from { opacity: 0; } to { opacity: 1; } }
body.lb-open { overflow: hidden; }

.lb-track {
  grid-column: 1 / -1;
  grid-row: 1;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 100%;
  height: 100dvh;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.lb-track::-webkit-scrollbar { display: none; }
.lb-slide {
  scroll-snap-align: center;
  display: grid;
  place-items: center;
  padding: 1rem;
}
/* The library mixes 4:3 landscape with 3:4 portrait, so every photo is capped
   to the same box and centred - which lands them all on the same height on a
   wide screen, so nothing jumps as you swipe.
   The cap has to be in viewport units, not percentages: as a stretched grid
   item the slide's height is indefinite, so `max-height: 100%` resolved to
   none and portrait shots rendered at full natural size, hanging metres off
   the bottom of the screen. The 12rem allows for the close button above and
   the caption and dots below, so the photo can never slide under them. */
.lb-slide img {
  display: block;
  width: auto;
  height: auto;
  max-width: min(90vw, 880px);
  max-height: min(calc(100dvh - 12rem), 620px);
  border-radius: 4px;
}

.lb-close,
.lb-arrow {
  grid-row: 1;
  z-index: 1;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  transition: background 200ms var(--ease-out-strong);
}
.lb-close:hover,
.lb-arrow:hover { background: rgba(255, 255, 255, 0.22); }
.lb-close:focus-visible,
.lb-arrow:focus-visible,
.lb-dot:focus-visible {
  outline: 2px solid var(--pra-blue-400);
  outline-offset: 3px;
}
.lb-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 2.75rem;
  height: 2.75rem;
}
.lb-close svg { width: 1.35rem; height: 1.35rem; }
.lb-arrow {
  width: 3rem;
  height: 3rem;
  margin: 0 0.75rem;
}
.lb-arrow svg { width: 1.5rem; height: 1.5rem; }
.lb-prev { grid-column: 1; }
.lb-next { grid-column: 3; }
/* On a phone you swipe, so the arrows only get in the way. */
@media (max-width: 767px) {
  .lb-arrow { display: none; }
}

.lb-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: grid;
  justify-items: center;
  gap: 0.75rem;
  padding: 1.25rem 1rem 1.75rem;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.75), transparent);
  pointer-events: none;
}
.lb-title {
  font-size: 0.875rem;
  color: rgba(255, 255, 255, 0.8);
  text-align: center;
}
.lb-dots {
  display: flex;
  gap: 0.5rem;
  pointer-events: auto;
}
.lb-dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.3);
  transition: background 200ms var(--ease-out-strong), transform 200ms var(--ease-out-strong);
}
.lb-dot.is-current {
  background: #fff;
  transform: scale(1.25);
}

/* Hairline card border, elevated surface pattern.
   Cards lift on hover (fine pointer only) and settle slightly on press,
   giving them real weight instead of sitting flat on the page. */
.card-elevated {
  background: var(--pra-surface-1);
  border: 1px solid var(--pra-hairline);
  transition: transform 220ms var(--ease-out-strong),
    box-shadow 220ms var(--ease-out-strong),
    border-color 220ms var(--ease-out-strong);
}
@media (hover: hover) and (pointer: fine) {
  a.card-elevated:hover {
    transform: translateY(-4px);
    border-color: rgba(121, 133, 205, 0.4);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(63, 81, 183, 0.35);
  }
}
a.card-elevated:active {
  transform: translateY(-1px) scale(0.99);
}

/* Scroll reveal: content settles into place once, the first time it
   enters view. Skipped entirely for reduced-motion users. */
[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 550ms var(--ease-out-strong), transform 550ms var(--ease-out-strong);
}
[data-reveal].is-visible {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
