/* ==========================================================================
   Components — reusable patterns: buttons, framed imagery, tags, torn edges,
   accordion mechanics, marquee, form fields, meta table
   ========================================================================== */

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */
.btn {
  --btn-py: var(--sp-5);
  --btn-px: var(--sp-5);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4em;
  font-family: var(--font-body);
  font-size: var(--fs-lg);
  font-weight: 400;
  line-height: 1;
  padding: var(--btn-py) var(--btn-px);
  border-radius: var(--r-xl);   /* 20px — same radius as the card system */
  transition:
    transform var(--dur-2) var(--ease-out),
    background-color var(--dur-2) var(--ease-out),
    box-shadow var(--dur-2) var(--ease-out),
    border-color var(--dur-2) var(--ease-out);
}
.btn > span[aria-hidden] { transition: transform var(--dur-2) var(--ease-out); }
@media (hover: hover) {
  .btn:hover { transform: translateY(-2px); }
  .btn:hover > span[aria-hidden] { transform: translateX(3px); }
}
.btn:active { transform: translateY(0) scale(0.99); transition-duration: var(--dur-1); }

/* glass CTA — frosted mint fill, no stroke (matches the site's clean rounded language) */
.btn--glass {
  color: var(--c-white);
  /* dark scrim under the mint tint guarantees WCAG AA contrast for the white
     label no matter how bright the photo behind it is (glass look unchanged) */
  background:
    linear-gradient(rgba(8, 9, 11, 0.6), rgba(8, 9, 11, 0.6)),
    rgba(0, 255, 188, 0.2);
  -webkit-backdrop-filter: blur(22px);
  backdrop-filter: blur(22px);
  box-shadow: 0 10px 30px -14px rgba(0, 0, 0, 0.5);
}
.btn--glass:hover {
  background:
    linear-gradient(rgba(8, 9, 11, 0.5), rgba(8, 9, 11, 0.5)),
    rgba(0, 255, 188, 0.34);
  box-shadow: 0 0 0 4px var(--c-mint-15), 0 12px 32px -12px rgba(0, 255, 188, 0.5);
}
.btn--glass:focus-visible { outline-offset: 5px; }

/* solid dark — form submit */
.btn--solid {
  width: 100%;
  color: var(--c-white);
  background: var(--c-ink-2);
  font-weight: 700;
  font-size: var(--fs-body);
  padding-block: var(--sp-4);
}
.btn--solid:hover { background: #000; box-shadow: var(--shadow-soft); }
.btn--solid:active { background: #111; }
.btn--solid[aria-busy="true"] { opacity: 0.72; pointer-events: none; }

/* --------------------------------------------------------------------------
   Framed imagery — rough hand-drawn mint frame + optional tilt
   Double offset outline reads as a sketched border; fully scalable.
   -------------------------------------------------------------------------- */
.frame {
  position: relative;
  display: block;
  border-radius: 18px;   /* photos sit clean — no stroke */
}
.frame > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 18px;
}
/* solid-mint UI recipe for framed media that isn't a "photo in a frame" */
.frame--solid-edge {
  border-width: var(--bw-thin);
  border-image: var(--brush-ui);
}

/* tilt variants — preserved from the Figma scattered imagery */
.frame--tilt-a { transform: rotate(-2.2deg); }
.frame--tilt-b { transform: rotate(2deg); }
.frame--tilt-sm { transform: rotate(-0.6deg); }

@media (hover: hover) {
  .frame { transition: transform var(--dur-3) var(--ease-out), border-color var(--dur-2) var(--ease-out); }
}

/* --------------------------------------------------------------------------
   Tags / pills
   -------------------------------------------------------------------------- */
.tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}
.tag {
  font-size: var(--fs-3xs);
  font-weight: 500;
  line-height: 1;
  color: var(--c-tag-ink);
  background: var(--c-white);
  padding: 0.5rem 0.875rem;
  border-radius: var(--r-pill);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Torn-paper section edges
   Built with a CSS clip-path polygon on a coloured bar — cheap, responsive,
   keeps the "torn" idea at any width.
   -------------------------------------------------------------------------- */
.edge {
  position: absolute;
  left: -2px;
  right: -2px;
  z-index: 3;
  pointer-events: none;
  background-repeat: no-repeat;
  background-size: 100% 100%;
}
/* white counter-tear at the hero bottom (hero → philosophy) */
.edge--torn-bottom {
  height: 22px;
  bottom: -6px;
  background-image: var(--torn-hero);
}

/* --------------------------------------------------------------------------
   Accordion mechanics (shared by Services + FAQ)
   Panels animate height via grid-template-rows 0fr -> 1fr (no JS measuring).
   -------------------------------------------------------------------------- */
/* JS sets an explicit pixel height to animate, then `auto` once open — this is
   more robust than transitioning grid-template-rows between fr units. */
[data-accordion-panel] {
  overflow: hidden;
  height: 0;
  transition: height var(--dur-3) var(--ease-in-out);
  will-change: height;
}
[data-accordion-panel] > * {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out);
}
[data-accordion-item].is-open [data-accordion-panel] > * {
  opacity: 1;
  transform: none;
  transition-delay: 90ms;
}
[data-accordion-panel][hidden] { display: none; }

/* no-JS / pre-hydration fallback: open items just show their panel */
html:not(.js-ready) [data-accordion-item].is-open [data-accordion-panel] { height: auto; }
html:not(.js-ready) [data-accordion-panel] > *,
[data-accordion-item].is-open [data-accordion-panel] > * { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  [data-accordion-panel] { transition: none; }
  [data-accordion-panel] > * { transition: none; }
}

/* --------------------------------------------------------------------------
   Marquee
   -------------------------------------------------------------------------- */
.marquee {
  position: relative;
  overflow: hidden;
  background: var(--c-banner);
  padding-block: clamp(1.75rem, 1.25rem + 1.5vw, 2.5rem);
  /* scale needs real margin, not just enough to cover the rotated bounding
     box — the torn-edge clip-path's corner notches eat into that margin,
     so a small compensation (1.06) still left visible gaps (and clipped
     text) at the left/right ends on every breakpoint. Verified empirically
     live: 1.06 gapped, 1.15 fully covers with room to spare. */
  transform: rotate(-3.6deg) scale(1.15);
  transform-origin: center;
  margin-block: clamp(3rem, 1.5rem + 6vw, 6rem);
  /* torn top + bottom edges — consistent with the deckled section transitions */
  clip-path: polygon(
    0.00% 2.4px, 3.85% 6.3px, 7.69% 5.0px, 11.54% 2.0px, 15.38% 1.9px, 19.23% 6.1px, 23.08% 2.5px, 26.92% 1.4px, 30.77% 2.9px, 34.62% 3.8px, 38.46% 0.8px, 42.31% 3.8px, 46.15% 6.6px, 50.00% 3.6px, 53.85% 2.0px, 57.69% 4.3px, 61.54% 5.7px, 65.38% 2.6px, 69.23% 0.7px, 73.08% 6.5px, 76.92% 4.1px, 80.77% 1.8px, 84.62% 3.4px, 88.46% 4.6px, 92.31% 2.9px, 96.15% 3.3px, 100.00% 6.7px,
    100.00% calc(100% - 6.6px), 96.15% calc(100% - 4.3px), 92.31% calc(100% - 2.4px), 88.46% calc(100% - 7.2px), 84.62% calc(100% - 2.6px), 80.77% calc(100% - 0.9px), 76.92% calc(100% - 7.4px), 73.08% calc(100% - 3.0px), 69.23% calc(100% - 0.6px), 65.38% calc(100% - 7.1px), 61.54% calc(100% - 3.9px), 57.69% calc(100% - 2.9px), 53.85% calc(100% - 2.7px), 50.00% calc(100% - 0.5px), 46.15% calc(100% - 3.0px), 42.31% calc(100% - 2.7px), 38.46% calc(100% - 1.9px), 34.62% calc(100% - 2.1px), 30.77% calc(100% - 3.9px), 26.92% calc(100% - 0.1px), 23.08% calc(100% - 4.8px), 19.23% calc(100% - 1.8px), 15.38% calc(100% - 0.4px), 11.54% calc(100% - 6.2px), 7.69% calc(100% - 3.4px), 3.85% calc(100% - 3.3px), 0.00% calc(100% - 2.8px)
  );
}
/* seamless infinite loop: track holds two identical groups, shift exactly -50% */
.marquee__track {
  display: flex;
  width: max-content;
  animation: marquee-scroll 32s linear infinite;
}
.marquee__group {
  display: flex;
  flex: none;
  gap: 2.2rem;
  padding-right: 2.2rem;   /* keep the gap consistent across the seam */
}
.marquee__item {
  font-family: var(--font-display);
  font-size: var(--fs-marquee);
  color: var(--c-white);
  white-space: nowrap;
  letter-spacing: var(--tracking-display);
}
.marquee__sep {
  margin-left: 0.75rem;
  color: var(--c-mint);
  font-size: 0.62em;
  font-weight: 400;
  vertical-align: 0.18em;
}
.marquee:hover .marquee__track { animation-play-state: paused; }

@keyframes marquee-scroll {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
  .marquee { transform: rotate(-3.6deg) scale(1.15); }
}

/* --------------------------------------------------------------------------
   Filmstrip — an auto-scrolling horizontal photo strip that's also a real
   scroll container: initFilmstrips() in main.js drives scrollLeft on a
   rAF loop for the auto-scroll (two identical groups, seamless loop at the
   halfway point), and pauses it whenever the reader touches, drags or
   hovers the strip, so native touch-swipe and mouse-drag both work as
   ordinary scrolling rather than fighting the animation.
   -------------------------------------------------------------------------- */
.filmstrip {
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  cursor: grab;
}
.filmstrip::-webkit-scrollbar { display: none; }
.filmstrip.is-dragging { cursor: grabbing; }
.filmstrip__track {
  display: flex;
  width: max-content;
}
.filmstrip__group {
  display: flex;
  flex: none;
  align-items: flex-start;
  gap: var(--sp-5);
  padding-right: var(--sp-5);
}
.filmstrip figure { margin: 0; flex: none; }
.filmstrip img {
  display: block;
  width: 100%;
  border-radius: var(--r-xl);
  object-fit: cover;
  -webkit-user-drag: none;
  user-select: none;
}
.filmstrip figcaption {
  margin-top: var(--sp-3);
  font-family: var(--font-body);
  font-size: var(--fs-2xs);
  color: var(--c-grey-mid);
  text-align: center;
}
@media (prefers-reduced-motion: reduce) {
  .filmstrip__group[aria-hidden] { display: none; }
}

/* --------------------------------------------------------------------------
   Brush divider — VERITE BACKWARD + QUARTER_TAPER · #B8B8BD · 4px
   -------------------------------------------------------------------------- */
.brush-rule,
hr.brush-rule {
  border: 0;
  height: 12px;
  background: var(--brush-divider) repeat-x;
  background-size: 320px 12px;
  opacity: 0.75;
}

/* --------------------------------------------------------------------------
   Meta table (FAQ aside)
   -------------------------------------------------------------------------- */
.meta-table { display: flex; flex-direction: column; }
.meta-row {
  position: relative;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  padding-block: var(--sp-4);
}
.meta-row:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -6px;
  height: 12px;
  background: var(--brush-divider) repeat-x;
  background-size: 300px 12px;
  opacity: 0.6;
}
.meta-row dt {
  font-size: var(--fs-3xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
  color: var(--c-grey-mid);
}
.meta-row dd {
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--c-ink);
  text-align: right;
}

/* --------------------------------------------------------------------------
   Generic icon sizing
   -------------------------------------------------------------------------- */
.icon { display: inline-block; flex: none; vertical-align: middle; }
.icon--arrow { width: 14px; height: 14px; }
.icon--check { width: 16px; height: 16px; color: var(--c-mint); }

/* --------------------------------------------------------------------------
   Back-to-top — a small, quiet wayfinding aid for the site's long single-
   scroll pages. Clear of copy (bottom-right corner), hidden until the
   reader has actually scrolled, never competes with the nav or CTAs.
   -------------------------------------------------------------------------- */
.scroll-top {
  position: fixed;
  right: var(--sp-5);
  bottom: var(--sp-5);
  z-index: var(--z-nav);
  width: 42px;
  height: 42px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: var(--c-ink-2);
  color: var(--c-white);
  box-shadow: var(--shadow-soft);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out), visibility 0s linear var(--dur-2);
}
.scroll-top.is-visible {
  opacity: 0.85;
  visibility: visible;
  transform: translateY(0);
  transition: opacity var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out);
}
.scroll-top:hover, .scroll-top:focus-visible { opacity: 1; transform: translateY(-2px); }
.scroll-top:active { transform: scale(0.95); }
.scroll-top svg { width: 16px; height: 16px; }
@media (prefers-reduced-motion: reduce) {
  .scroll-top { transition: none; }
}

/* --------------------------------------------------------------------------
   Breadcrumbs — case studies and Studio project pages, so a reader who
   lands one level deep can step back to the exact parent they came from
   (the "Home" crumb is repointed at document.referrer by initCrumbBack()
   in main.js) as well as to the section above that.
   -------------------------------------------------------------------------- */
.crumbs {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4em;
  list-style: none;
  padding: 0;
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--c-grey-mid);
}
.crumbs a {
  color: inherit;
  text-decoration: none;
  opacity: 0.75;
  transition: opacity var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out);
}
.crumbs a:hover, .crumbs a:focus-visible { opacity: 1; }
.crumbs [aria-current="page"] { color: var(--c-ink); }
.crumbs__sep { opacity: 0.45; }
