/* ==========================================================================
   TradeForm — design tokens + bespoke utilities
   (Tailwind's utility classes are compiled locally into
   assets/css/tailwind.min.css and enqueued in functions.php; everything
   here is the custom, non-Tailwind layer that the original app defined
   via @theme / @utility in src/styles.css)
   ========================================================================== */

:root {
  --background: #0F172A;
  --surface: #16213A;
  --surface-2: #1C2942;
  --foreground: #FFFFFF;
  --muted: #263349;
  --muted-foreground: #CBD5E1;
  --accent: #14B8A6;
  --accent-foreground: #0B1220;
  --border: rgba(255, 255, 255, 0.08);
  --hairline: rgba(255, 255, 255, 0.12);
  --radius: 0.25rem;

  --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
  --font-display: "Fraunces", "Times New Roman", serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;
}

* {
  border-color: var(--border);
}

html {
  scroll-behavior: smooth;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

body {
  background: var(--background);
  color: var(--foreground);
  font-family: var(--font-sans);
  font-feature-settings: "ss01", "cv11";
  overflow-x: hidden;
}

::selection {
  background: var(--accent);
  color: var(--accent-foreground);
}

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

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

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

/* ---------- layout ---------- */

.container-editorial {
  width: 100%;
  max-width: 96rem;
  margin-inline: auto;
  padding-inline: 1.5rem;
}
@media (min-width: 768px) {
  .container-editorial { padding-inline: 3rem; }
}
@media (min-width: 1280px) {
  .container-editorial { padding-inline: 5rem; }
}

/* ---------- typography ---------- */

.display {
  font-family: var(--font-display);
  font-weight: 300;
  letter-spacing: -0.03em;
  line-height: 0.92;
  /* Fraunces (italic, light weight) has tall ascenders/descenders relative
     to a sub-1 line-height box. They only get visibly cropped where a
     parent constrains overflow (see the padded reveal mask on
     .reveal-heading .word below, and the removal of the redundant
     per-section `overflow-x-hidden` utility in the templates -- html/body
     already clip horizontal overflow document-wide, so a section-level
     `overflow-x-hidden` only ever added an unwanted implicit
     `overflow-y: auto`, per the CSS overflow spec's used-value fixup for
     mismatched axes; see BUILD-INSTRUCTIONS.txt). In normal flow this
     element must stay overflow-visible so nothing here clips it. */
  overflow: visible;
}

.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted-foreground);
}

.hairline {
  height: 1px;
  background: var(--hairline);
  width: 100%;
  display: block;
}

.ink-link {
  position: relative;
  display: inline-block;
}
.ink-link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform-origin: right;
  transform: scaleX(0);
  transition: transform 0.6s cubic-bezier(.77, 0, .18, 1);
}
.ink-link:hover::after {
  transform-origin: left;
  transform: scaleX(1);
}

/* ---------- animation ---------- */

@keyframes rise {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

.rise-in {
  animation: rise 1.1s cubic-bezier(.19, 1, .22, 1) both;
}
.fade-in-slow {
  animation: fade 1.6s ease-out both;
}
.marquee-track {
  animation: marquee 40s linear infinite;
}

/* ---------- scroll reveal (JS-driven, see main.js) ---------- */

.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 1s ease, transform 1.1s cubic-bezier(.19, 1, .22, 1);
}
.reveal.is-shown {
  opacity: 1;
  transform: translateY(0);
}

.reveal-heading .word {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  /* Padded inner mask: the word wrapper still clips for the slide-up reveal,
     but it is now taller/wider than the line box itself, so Fraunces'
     italic ascenders/descenders and the slanted right edge of italic
     glyphs sit inside the mask instead of getting cropped by it. The
     matching negative margin cancels the padding back out so the word's
     footprint, baseline and spacing in the heading are unchanged.
     transform: translateY(110%) below is a percentage of the inner span's
     OWN box, not this wrapper, so enlarging the wrapper does not change
     the reveal animation's travel distance. */
  padding-block: 0.22em;
  margin-block: -0.22em;
  padding-inline: 0.2em 0.3em;
  margin-inline: -0.2em -0.05em;
}
.reveal-heading .word > span {
  display: inline-block;
  will-change: transform;
  transform: translateY(110%);
  opacity: 0;
  transition: transform 1.05s cubic-bezier(.19, 1, .22, 1), opacity 1s ease;
}
.reveal-heading.is-shown .word > span {
  transform: translateY(0);
  opacity: 1;
}

/* Desktop/laptop: Fraunces glyphs like the lowercase "j" (and italic
   overhangs) have a larger left side-bearing at big display sizes than
   the mobile mask padding covers. Widen the inner reveal mask a touch
   at >=768px only, and cancel the extra footprint with matching negative
   margins so the heading's position, line breaks and spacing are visually
   unchanged. Mobile keeps the existing values. */
@media (min-width: 768px) {
  .reveal-heading .word {
    padding-inline: 0.32em 0.4em;
    margin-inline: -0.32em -0.1em;
  }
}

[data-parallax] {
  will-change: transform;
}

/* ---------- header ---------- */

.site-header {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: 50;
  transition: all 0.5s;
}
.site-header.is-scrolled {
  backdrop-filter: blur(12px);
  background: rgba(15, 23, 42, 0.8);
  border-bottom: 1px solid var(--hairline);
}

.mobile-drawer {
  --tf-header-h: 4.5rem;
  position: fixed;
  top: var(--tf-header-h);
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  background: var(--background);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s ease;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  height: calc(100vh - var(--tf-header-h));
  height: calc(100dvh - var(--tf-header-h));
  padding-bottom: env(safe-area-inset-bottom);
}
.mobile-drawer.is-open {
  opacity: 1;
  pointer-events: auto;
}
.mobile-drawer-inner {
  padding-top: 1.25rem;
  padding-bottom: calc(2.5rem + env(safe-area-inset-bottom));
}
.mobile-nav-list { display: flex; flex-direction: column; list-style: none; margin: 0; padding: 0; }
.mobile-nav-item { border-top: 1px solid var(--hairline); }
.mobile-nav-item:last-child { border-bottom: 1px solid var(--hairline); }
.mobile-nav-link {
  display: flex; align-items: center; justify-content: space-between;
  width: 100%; padding: 1.25rem 0; min-height: 3.25rem;
  font-family: var(--font-display, "Fraunces", serif);
  font-size: 1.75rem; line-height: 1.1;
  color: var(--foreground); background: transparent; border: 0;
  text-align: left; cursor: pointer; transition: opacity 0.4s ease;
}
.mobile-nav-link:hover { opacity: 0.75; }
.mobile-nav-indicator {
  position: relative; display: inline-block; width: 14px; height: 14px;
  flex: 0 0 auto; margin-left: 1rem; opacity: 0.7;
}
.mobile-nav-indicator-bar {
  position: absolute; top: 50%; left: 0; width: 100%; height: 1px;
  background: currentColor; transform: translateY(-50%);
  transition: transform 0.4s ease, opacity 0.4s ease;
}
.mobile-nav-indicator-bar--v { transform: translateY(-50%) rotate(90deg); }
.mobile-nav-toggle[aria-expanded="true"] .mobile-nav-indicator-bar--v {
  transform: translateY(-50%) rotate(0deg); opacity: 0;
}
.mobile-services-panel {
  overflow: hidden; height: 0; opacity: 0;
  transition: height 0.45s cubic-bezier(.19,1,.22,1), opacity 0.35s ease;
}
.mobile-services-panel[hidden] { display: block; }
.mobile-services-panel.is-open { opacity: 1; }
.mobile-services-list { list-style: none; margin: 0; padding: 0 0 1rem 1rem; display: flex; flex-direction: column; }
.mobile-services-link {
  display: block; padding: 0.65rem 0;
  font-size: 0.95rem; letter-spacing: 0.01em;
  color: var(--muted-foreground); transition: color 0.3s ease;
}
.mobile-services-link:hover { color: var(--foreground); }
body.menu-open { overflow: hidden; touch-action: none; }

.services-dropdown {
  position: absolute;
  left: 50%;
  top: 100%;
  transform: translate(-50%, -6px);
  padding-top: 1rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 400ms ease, transform 500ms cubic-bezier(.19, 1, .22, 1);
}
.services-dropdown.is-open {
  opacity: 1;
  pointer-events: auto;
  transform: translate(-50%, 0);
}

.burger-line {
  display: block;
  height: 1px;
  background: var(--foreground);
  transition: all 0.5s;
}

/* ---------------------------------------------------------------------
   Case study template — scoped additions (prefixed `cs-`)
   Only used by single-project.php; does not affect any other page.
   ------------------------------------------------------------------- */

/* cinematic hero / section image reveal */
.cs-reveal-img {
	clip-path: inset(0 0 0 0);
	overflow: hidden;
}
.cs-reveal-img img,
.cs-reveal-img video {
	transform: scale(1.08);
	opacity: 0;
	transition: transform 1.6s cubic-bezier(.19,1,.22,1), opacity 1.2s ease;
}
.cs-reveal-img.is-shown img,
.cs-reveal-img.is-shown video {
	transform: scale(1);
	opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
	.cs-reveal-img img,
	.cs-reveal-img video {
		transition: opacity 0.4s ease;
		transform: none;
	}
}

/* editorial metadata row (Project Snapshot) — thin rules, no boxes */
.cs-meta-row {
	border-top: 1px solid var(--hairline);
	padding-top: 1.25rem;
}

/* design-system swatches */
.cs-swatch {
	aspect-ratio: 1 / 1;
	border: 1px solid var(--hairline);
}

/* next-project full-bleed transition */
.cs-next-project {
	position: relative;
	display: block;
	overflow: hidden;
}
.cs-next-project img {
	transition: transform 1.8s cubic-bezier(.19,1,.22,1), filter 1.2s ease;
	filter: grayscale(0.3) brightness(0.55);
}
.cs-next-project:hover img {
	transform: scale(1.06);
	filter: grayscale(0) brightness(0.5);
}
.cs-next-project .cs-next-arrow {
	transition: transform 0.6s cubic-bezier(.19,1,.22,1);
}
.cs-next-project:hover .cs-next-arrow {
	transform: translateX(0.5rem);
}

/* mobile: keep the cinematic reveal but shorten distance/duration a touch */
@media (max-width: 767px) {
	.cs-reveal-img img,
	.cs-reveal-img video {
		transform: scale(1.04);
	}
}

/* ---------- misc ---------- */

.divide-hairline > * + * {
  border-top: 1px solid var(--hairline);
}

/* ---------- accessibility / quality floor ---------- */

a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 4px;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .rise-in,
  .fade-in-slow,
  .marquee-track,
  .reveal,
  .reveal-heading .word > span {
    animation: none !important;
    transition: none !important;
    opacity: 1 !important;
    transform: none !important;
  }

  [data-parallax] {
    transform: none !important;
  }
}

/* ---------- page transitions (progressive enhancement) ---------- */
/* No-op in browsers without support; adds a soft cross-fade between
   pages in browsers that do, in place of a hard cut. */
@view-transition {
  navigation: auto;
}
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}

/* ---------- animated "read" links (work/project grid hover) ---------- */

.read-link {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
}
.read-link .read-link__label {
  position: relative;
  overflow: hidden;
}
.read-link .read-link__label::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform-origin: right;
  transform: scaleX(0);
  transition: transform 0.5s cubic-bezier(.19, 1, .22, 1);
}
.group:hover .read-link .read-link__label::after,
.read-link:hover .read-link__label::after {
  transform-origin: left;
  transform: scaleX(1);
}
.read-link .read-link__arrow {
  display: inline-block;
  transition: transform 0.5s cubic-bezier(.19, 1, .22, 1);
}
.group:hover .read-link .read-link__arrow,
.read-link:hover .read-link__arrow {
  transform: translateX(0.4rem);
}

/* ---------------------------------------------------------------------
   Custom accessible <select> replacement — contact form (v1.5.2)
   Styled to match the header Services dropdown: dark navy translucent
   panel, subtle glassmorphism, brand-teal hover / active state.
   ------------------------------------------------------------------- */
.tf-select { position: relative; width: 100%; }

/* Keep the native select in the DOM so Fluent Forms / AJAX submission
   and validation continue to see it, but visually remove it. */
.tf-select__native {
  position: absolute !important;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  pointer-events: none;
  border: 0;
  padding: 0;
  margin: 0;
  clip: rect(0 0 0 0);
}

.tf-select__button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  width: 100%;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  color: var(--foreground);
  font-size: 1.125rem;
  line-height: 1.4;
  text-align: left;
  cursor: pointer;
  min-height: 44px; /* comfortable tap target */
}
@media (min-width: 768px) {
  .tf-select__button { font-size: 1.25rem; }
}
.tf-select__button:focus { outline: none; }
.tf-select__button:focus-visible {
  outline: 2px solid #14B8A6;
  outline-offset: 4px;
}

.tf-select__label.is-placeholder {
  color: color-mix(in oklab, var(--muted-foreground) 70%, transparent);
}

.tf-select__caret {
  display: inline-block;
  font-size: 0.85em;
  color: var(--muted-foreground);
  transition: transform 200ms ease, color 200ms ease;
}
.tf-select.is-open .tf-select__caret {
  transform: rotate(180deg);
  color: #14B8A6;
}

/* The listbox itself — glassmorphic dark navy panel. */
.tf-select__list {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + 8px);
  z-index: 60;
  margin: 0;
  padding: 6px;
  list-style: none;
  max-height: min(320px, 60vh);
  overflow-y: auto;
  background: color-mix(in oklab, var(--background) 82%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid color-mix(in oklab, var(--foreground) 12%, transparent);
  border-radius: 2px;
  box-shadow:
    0 12px 40px -12px rgba(0, 0, 0, 0.6),
    0 2px 8px -2px rgba(0, 0, 0, 0.35);
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  transition: opacity 180ms ease, transform 220ms cubic-bezier(.19, 1, .22, 1);
}
.tf-select.is-open .tf-select__list {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.tf-select.is-up .tf-select__list {
  top: auto;
  bottom: calc(100% + 8px);
  transform: translateY(4px);
}
.tf-select.is-open.is-up .tf-select__list {
  transform: translateY(0);
}

.tf-select__option {
  padding: 0.7rem 0.85rem;
  color: var(--foreground);
  font-size: 1rem;
  line-height: 1.35;
  border-radius: 2px;
  cursor: pointer;
  user-select: none;
  transition: background-color 140ms ease, color 140ms ease;
  min-height: 40px;
  display: flex;
  align-items: center;
}
.tf-select__option[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
}
.tf-select__option.is-selected {
  color: #14B8A6;
}
.tf-select__option.is-active,
.tf-select__option:hover {
  background-color: color-mix(in oklab, #14B8A6 18%, transparent);
  color: var(--foreground);
}
.tf-select__option.is-active.is-selected,
.tf-select__option:hover.is-selected {
  color: #14B8A6;
}

/* Mobile: keep menu within viewport and prevent iOS zoom-on-focus. */
@media (max-width: 640px) {
  .tf-select__button { font-size: 16px; }
  .tf-select__list { max-height: 55vh; }
}
