/* ============================================================
   site.css: shared interaction layer (Oct 2026 audit)
   Linked AFTER each page's inline <style>, so equal-specificity
   rules here win. Pages keep their own layout CSS; this file adds
   the things every page should share: tokens, focus, states,
   micro-interactions, page transitions, consent bar, a11y helpers.
   Motion: transform/opacity/colour only; every move has a
   prefers-reduced-motion fallback.
============================================================ */

/* ---------- Tokens ---------- */
:root {
  /* contrast: #5C5C5C was 2.91:1 on #0D0D0D; #858585 is 5.27:1 */
  --grey-2: #858585;
  --grey-deco: #5C5C5C;          /* the old value, for non-text decoration only */
  --line-3: rgba(255,255,255,.18);
  --accent-hover: #D6FF33;
  --accent-press: #B8EF00;
  --error: #FF6B5B;

  --dur-press: 120ms;
  --dur-hover: 180ms;
  --dur-move: 320ms;
  --dur-media: 600ms;
  --dur-reveal: 720ms;
  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --ease-expo: cubic-bezier(.16, 1, .3, 1);
  --ease-in-out: cubic-bezier(.65, 0, .35, 1);
  --ease-in: cubic-bezier(.55, 0, 1, .45);
}

html {
  color-scheme: dark;
  -webkit-tap-highlight-color: transparent;
  scroll-behavior: auto;
}
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
a, button, [role="tab"] { touch-action: manipulation; }
::selection { background: var(--accent); color: var(--bg); }

/* One left edge: nav and page heroes share the section gutter (was 96px vs 80px) */
nav { padding-left: var(--pad); padding-right: var(--pad); }

/* ---------- Accessibility helpers ---------- */
.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: 16px; top: -64px; z-index: 600;
  padding: 12px 18px; background: var(--accent); color: var(--bg);
  font: 700 12px/1 'Source Sans 3', sans-serif; letter-spacing: .14em; text-transform: uppercase;
  text-decoration: none; transition: top var(--dur-hover) var(--ease-out);
}
.skip-link:focus { top: 16px; }
main:focus, #main:focus { outline: none; }

:where(a, button, input, select, textarea, summary, [role="tab"], [tabindex]:not([tabindex="-1"])):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
/* white ring where the fill is lime */
.hero-btn-primary:focus-visible, .nav-cta:focus-visible, .cs-btn-primary:focus-visible,
.btn--primary:focus-visible, .form-submit:focus-visible, .cs-livelink:focus-visible,
.jr-live-link:focus-visible, .consent__btn:focus-visible { outline-color: var(--white); }

/* Headings promoted from <div> keep their old look.
   :where() = zero specificity, so any page rule that already styles h1-h3 still wins. */
:where(h1, h2, h3) { font: inherit; margin: 0; }

/* Numbers that change or align */
.stat-num, .cs-stat-num, .cs-result-num, .filter-count, .project-num, .glance-grid dd { font-variant-numeric: tabular-nums; }

/* Big type wraps nicely */
.cs-lead, .project-title, .cs-hero-title, .cs-next-title, .page-title { text-wrap: balance; }
p { text-wrap: pretty; }

/* ---------- Nav links: underline wipe + current page ---------- */
.nav-links a {
  position: relative;
  transition: color var(--dur-hover) var(--ease-out);
}
.nav-links a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -6px; height: 1px;
  background: currentColor; transform: scaleX(0); transform-origin: right center;
  transition: transform var(--dur-move) var(--ease-out);
}
@media (hover: hover) {
  .nav-links a:hover { color: var(--white); }
  .nav-links a:hover::after { transform: scaleX(1); transform-origin: left center; }
}
.nav-links a:focus-visible::after { transform: scaleX(1); }
.nav-links a[aria-current="page"] { color: var(--white); }
.nav-links a[aria-current="page"]::after { transform: scaleX(1); background: var(--accent); }
nav.nav-open .nav-links a::after { display: none; }
@media (max-width: 640px) {
  /* the full title lives in each page's hero; keep the mobile nav on one line */
  .nav-role { display: none; }
  .nav-links a { display: inline-block; padding-top: 12px; padding-bottom: 12px; }
}

.nav-identity { transition: opacity var(--dur-hover) var(--ease-out); }
.nav-logo { transition: transform var(--dur-move) var(--ease-expo); }
@media (hover: hover) {
  .nav-identity:hover .nav-logo { transform: rotate(-8deg); }
}
.nav-role { color: var(--cyan); }

.nav-back, .nav-cta { transition: color var(--dur-hover) var(--ease-out), background-color var(--dur-hover) var(--ease-out); }
@media (hover: hover) { .nav-back:hover { color: var(--white); } }

/* ---------- Buttons: roll label, nudge arrow, press ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 44px; padding: 0 24px;
  font: 700 11px/1 'Source Sans 3', sans-serif; letter-spacing: .14em; text-transform: uppercase;
  text-decoration: none; white-space: nowrap; cursor: pointer;
  border: 1px solid transparent; border-radius: 0; background: none;
}
.btn--primary { background: var(--accent); color: var(--bg); }
.btn--secondary { color: var(--white); border-color: var(--line-3); }
.btn--ghost { color: var(--grey-1); padding: 0 4px; min-height: 44px; }

.btn, .hero-btn-primary, .hero-btn-secondary, .nav-cta, .cs-btn-primary, .cs-btn-secondary, .form-submit {
  transition:
    background-color var(--dur-hover) var(--ease-out),
    border-color var(--dur-hover) var(--ease-out),
    color var(--dur-hover) var(--ease-out),
    transform var(--dur-press) var(--ease-out);
}
.roll { display: inline-grid; overflow: hidden; line-height: 1.25; vertical-align: top; }
.roll > span { grid-area: 1 / 1; transition: transform var(--dur-move) var(--ease-expo); }
.roll > span + span { transform: translateY(105%); }
.btn-arrow { display: inline-block; font-family: sans-serif; transition: transform var(--dur-move) var(--ease-expo); }

@media (hover: hover) {
  :is(.btn, .hero-btn-primary, .hero-btn-secondary, .nav-cta, .cs-btn-primary, .cs-btn-secondary):hover .roll > span:first-child { transform: translateY(-105%); }
  :is(.btn, .hero-btn-primary, .hero-btn-secondary, .nav-cta, .cs-btn-primary, .cs-btn-secondary):hover .roll > span + span { transform: translateY(0); }
  :is(.btn, .cs-btn-primary, .cs-btn-secondary):hover .btn-arrow { transform: translateX(4px); }
  .btn--primary:hover, .hero-btn-primary:hover, .nav-cta:hover, .cs-btn-primary:hover { background: var(--accent-hover); }
  .btn--secondary:hover, .cs-btn-secondary:hover { border-color: var(--white); color: var(--white); background: var(--bg-3); }
  .hero-btn-secondary:hover { background: rgba(200,255,0,.08); }
  .btn--ghost:hover { color: var(--white); }
}
.btn:active, .hero-btn-primary:active, .hero-btn-secondary:active, .nav-cta:active,
.cs-btn-primary:active, .cs-btn-secondary:active { transform: scale(.97); }
.btn--primary:active, .hero-btn-primary:active, .nav-cta:active, .cs-btn-primary:active { background: var(--accent-press); }

/* Text links with an arrow (View all work →) */
.projects-link { transition: color var(--dur-hover) var(--ease-out); }
.projects-link::after { transition: transform var(--dur-move) var(--ease-expo); }
@media (hover: hover) {
  .projects-link:hover { color: var(--white); }
  .projects-link:hover::after { transform: translateX(4px); }
}

/* ---------- Project cards (home + work): rule draws, lift, arrow passes ---------- */
.project-card { position: relative; isolation: isolate; transition: background-color var(--dur-hover) var(--ease-out); }
.project-card::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px; z-index: 10;
  background: var(--accent); opacity: 1;
  transform: scaleX(0); transform-origin: left center;
  transition: transform var(--dur-media) var(--ease-expo);
}
.project-card.coming-soon::before { display: none; }
.project-thumb { transition: transform 900ms var(--ease-expo), opacity var(--dur-move) var(--ease-out); }
.project-arrow-btn { overflow: hidden; transition: border-color var(--dur-hover) var(--ease-out), color var(--dur-hover) var(--ease-out); }
.project-arrow-btn > span { display: inline-block; }
@keyframes arrow-pass {
  0% { transform: translateX(0); }
  45% { transform: translateX(170%); }
  46% { transform: translateX(-170%); }
  100% { transform: translateX(0); }
}
@media (hover: hover) {
  .project-card:not(.coming-soon):hover { background: var(--bg-3); }
  .project-card:not(.coming-soon):hover::before { transform: scaleX(1); }
  .project-card:not(.coming-soon):hover .project-thumb { transform: scale(1.035); }
  .project-card:not(.coming-soon):hover .project-arrow-btn { border-color: var(--accent); color: var(--accent); }
  .project-card:not(.coming-soon):hover .project-arrow-btn > span { animation: arrow-pass 520ms var(--ease-expo); }
  .projects-grid:has(.project-card:not(.coming-soon):hover) .project-card:not(:hover):not(.coming-soon) .project-thumb { opacity: .55; }
}
.project-card:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.project-card:focus-visible::before { transform: scaleX(1); }
.project-card:focus-visible .project-thumb { transform: scale(1.035); }
.project-card:focus-visible .project-arrow-btn { border-color: var(--accent); color: var(--accent); }
.project-card:active { transform: translateY(1px); }

/* Cursor label on cards (fine pointers only; built by site.js) */
.cursor-tag {
  position: fixed; left: 0; top: 0; z-index: 400; pointer-events: none;
  padding: 9px 13px; background: var(--white); color: var(--bg);
  font: 700 11px/1 'Source Sans 3', sans-serif; letter-spacing: .14em; text-transform: uppercase;
  translate: var(--x, -200px) var(--y, -200px); scale: .6; opacity: 0;
  transition: scale var(--dur-hover) var(--ease-out), opacity var(--dur-hover) var(--ease-out);
}
.cursor-tag.is-on { scale: 1; opacity: 1; }

/* ---------- Email CTA + copy button ---------- */
.cta-email { position: relative; transition: color var(--dur-hover) var(--ease-out); }
.cta-email::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: var(--accent); transform: scaleX(0); transform-origin: right center;
  transition: transform var(--dur-media) var(--ease-expo);
}
@media (hover: hover) { .cta-email:hover::after { transform: scaleX(1); transform-origin: left center; } }
.cta-email:focus-visible::after { transform: scaleX(1); }

.cta-email-wrap { display: inline-flex; align-items: center; gap: 8px; }
.copy-btn {
  display: inline-flex; align-items: center; min-height: 32px; padding: 0 10px; margin-left: 4px;
  background: none; border: 1px solid var(--line-3); color: var(--grey-1); cursor: pointer;
  font: 700 10px/1 'Source Sans 3', sans-serif; letter-spacing: .14em; text-transform: uppercase;
  transition: color var(--dur-hover) var(--ease-out), border-color var(--dur-hover) var(--ease-out), background-color var(--dur-hover) var(--ease-out);
  vertical-align: middle;
}
@media (hover: hover) { .copy-btn:hover { color: var(--white); border-color: var(--white); } }
.copy-btn.is-done { color: var(--bg); background: var(--accent); border-color: var(--accent); }

/* ---------- "Hiring?" line: end of case studies and work ---------- */
.hire-line {
  display: flex; align-items: center; flex-wrap: wrap; gap: 12px 16px;
  margin-top: 40px; padding-top: 28px; border-top: 1px solid var(--line);
}
.hire-line__q {
  font: 700 17px/1.3 'Source Sans 3', sans-serif; letter-spacing: -.01em; color: var(--white);
  margin-right: 8px;
}
.hire-line__note { flex-basis: 100%; font: 400 14px/1.5 'Source Sans 3', sans-serif; color: var(--grey-1); }

/* ---------- Footer links (every page) ---------- */
.footer-links a, .cs-footer-links a, footer a, .footer-btn {
  text-decoration: underline 1px transparent; text-underline-offset: 5px;
  transition: color var(--dur-hover) var(--ease-out), text-decoration-color var(--dur-hover) var(--ease-out);
}
@media (hover: hover) {
  .footer-links a:hover, .cs-footer-links a:hover, footer a:hover, .footer-btn:hover { color: var(--white); text-decoration-color: var(--line-3); }
}
.footer-btn {
  background: none; border: 0; padding: 0; cursor: pointer; color: var(--cyan);
  font: 400 10px/1.4 'Source Sans 3', sans-serif; letter-spacing: .16em; text-transform: uppercase;
}
@media (pointer: coarse) {
  .footer-links a, .cs-footer-links a, .footer-btn { display: inline-flex; align-items: center; min-height: 44px; }
}
.footer-mark { color: var(--grey-deco); }

/* ---------- Case study: next project + reading progress ---------- */
.cs-next-title, .cs-next-project a { transition: color var(--dur-hover) var(--ease-out), transform var(--dur-move) var(--ease-expo); }
@media (hover: hover) {
  .cs-next-project a:hover .cs-next-title, .cs-next-title:hover { transform: translateX(-4px); }
}
.cs-progress {
  position: fixed; inset: 0 0 auto 0; height: 2px; z-index: 300;
  background: var(--accent); transform-origin: left center; transform: scaleX(0);
  pointer-events: none;
}
@supports (animation-timeline: scroll()) {
  .cs-progress { animation: cs-progress linear both; animation-timeline: scroll(root); }
  @keyframes cs-progress { to { transform: scaleX(1); } }
}
@supports not (animation-timeline: scroll()) {
  .cs-progress { display: none; }
}

/* ---------- Filters + tabs ---------- */
.filter-btn { transition: color var(--dur-hover) var(--ease-out), background-color var(--dur-hover) var(--ease-out); }
.filter-btn:not(.active):not([aria-pressed="true"]) { color: var(--grey-1); }
@media (hover: hover) { .filter-btn:not(.active):hover { color: var(--white); } }
@media (max-width: 640px) {
  .filter-btn { min-height: 44px; font-size: 11px; }
}
.cs-tab-num, .cs-tab-count { color: var(--grey-2); }

/* ---------- Availability dot: a ping, not a pulse ---------- */
.avail-dot, .hero-status-dot { position: relative; }
.avail-dot::after, .hero-status-dot::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  border: 1px solid var(--accent); opacity: 0;
  animation: wb-ping 2.4s var(--ease-out) infinite;
}
@keyframes wb-ping { from { transform: scale(1); opacity: .7; } to { transform: scale(2.8); opacity: 0; } }

/* ---------- Marquee: pausable by keyboard too ---------- */
.logos-marquee:focus-within .logos-track { animation-play-state: paused; }
html.motion-paused .logos-track,
html.motion-paused .avail-dot::after,
html.motion-paused .hero-status-dot::after { animation-play-state: paused; }

/* ---------- Mobile sticky actions (built by site.js) ---------- */
.sticky-cta {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 350;
  display: none; gap: 8px; padding: 10px var(--pad) calc(10px + env(safe-area-inset-bottom));
  background: rgba(13,13,13,.94); border-top: 1px solid var(--line-2);
  transform: translateY(110%); transition: transform var(--dur-move) var(--ease-expo);
}
.sticky-cta .btn { flex: 1; }
@media (max-width: 640px) {
  .sticky-cta { display: flex; }
  .sticky-cta.is-on { transform: translateY(0); }
  html.consent-open .sticky-cta { transform: translateY(110%); }
}

/* ---------- Consent bar ---------- */
.consent {
  position: fixed; left: 24px; bottom: 24px; z-index: 500;
  width: min(440px, calc(100vw - 48px));
  padding: 16px 18px; background: #141414; border: 1px solid var(--line-2);
  color: var(--grey-1);
  opacity: 0; transform: translateY(16px);
  transition: opacity var(--dur-move) var(--ease-out), transform var(--dur-move) var(--ease-expo);
}
.consent.is-open { opacity: 1; transform: none; }
.consent:focus { outline: none; }
.consent__text { font: 400 14px/1.5 'Source Sans 3', sans-serif; margin: 0 0 12px; }
.consent__text a { color: var(--white); text-underline-offset: 3px; }
.consent__actions { display: flex; gap: 10px; flex-wrap: wrap; }
.consent__btn {
  flex: 1 1 120px; min-height: 40px; padding: 0 16px; cursor: pointer;
  background: transparent; color: var(--white); border: 1px solid var(--line-3); border-radius: 0;
  font: 700 11px/1 'Source Sans 3', sans-serif; letter-spacing: .14em; text-transform: uppercase;
  transition: border-color var(--dur-hover) var(--ease-out), background-color var(--dur-hover) var(--ease-out), transform var(--dur-press) var(--ease-out);
}
@media (hover: hover) { .consent__btn:hover { border-color: var(--white); background: var(--bg-3); } }
.consent__btn:active { transform: scale(.97); }
@media (max-width: 640px) {
  .consent { left: 12px; right: 12px; bottom: 12px; width: auto; }
}

/* ---------- Motion toggle ---------- */
.motion-toggle {
  display: inline-flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 2px;
  background: none; border: 0; cursor: pointer; color: var(--cyan);
  font: 400 11px/1 'Source Sans 3', sans-serif; letter-spacing: .16em; text-transform: uppercase;
  transition: color var(--dur-hover) var(--ease-out);
}
.motion-toggle::before {
  content: ""; width: 32px; height: 1px; background: var(--grey-deco);
  transition: width var(--dur-move) var(--ease-expo), background-color var(--dur-hover) var(--ease-out);
}
@media (hover: hover) {
  .motion-toggle:hover { color: var(--white); }
  .motion-toggle:hover::before { width: 44px; background: var(--accent); }
}

/* ---------- Reveal: print + failsafe ---------- */
@media print {
  .js .cs-section-body > *, .js .cs-cover, .js .cs-spread, .reveal, [data-reveal] { opacity: 1 !important; transform: none !important; translate: none !important; }
  .consent, .sticky-cta, .cursor-tag, .cs-progress, .skip-link { display: none !important; }
}
.js [data-reveal] {
  opacity: 0; translate: 0 22px;
  transition: opacity var(--dur-reveal) var(--ease-expo), translate var(--dur-reveal) var(--ease-expo);
  transition-delay: calc(min(var(--i, 0), 5) * 70ms);
}
.js [data-reveal].reveal-in { opacity: 1; translate: none; }
/* If site.js never runs (it adds .site-ready on <html>), nothing stays hidden: show everything after 2.5s */
html.js:not(.site-ready) [data-reveal]:not(.reveal-in) { animation: wb-reveal-failsafe 0s 2.5s forwards; }
@keyframes wb-reveal-failsafe { to { opacity: 1; translate: none; } }

/* ---------- Page transitions (cross-document View Transitions) ---------- */
@view-transition { navigation: auto; }
nav { view-transition-name: site-nav; }
::view-transition-group(site-nav) { animation-duration: 0s; }
::view-transition-old(root) { animation: vt-out 180ms var(--ease-in) both; }
::view-transition-new(root) { animation: vt-in 460ms var(--ease-expo) 60ms both; }
@keyframes vt-out { to { opacity: 0; } }
@keyframes vt-in { from { opacity: 0; transform: translateY(14px); } }

/* ---------- Reduced motion: state changes stay, travel stops ---------- */
@media (prefers-reduced-motion: reduce) {
  .roll > span + span { display: none; }
  :is(.btn, .hero-btn-primary, .hero-btn-secondary, .nav-cta, .cs-btn-primary, .cs-btn-secondary):hover .roll > span:first-child { transform: none; }
  .btn:active, .hero-btn-primary:active, .hero-btn-secondary:active, .nav-cta:active,
  .cs-btn-primary:active, .cs-btn-secondary:active, .project-card:active, .consent__btn:active { transform: none; }
  .nav-links a::after, .cta-email::after, .project-card::before { transition: none; }
  .project-card:hover .project-thumb, .project-card:focus-visible .project-thumb { transform: none !important; }
  .project-card:hover .project-arrow-btn > span { animation: none !important; }
  .avail-dot::after, .hero-status-dot::after { animation: none; opacity: 0; }
  .avail-dot, .cs-panel.active { animation: none !important; }
  .nav-logo, .btn-arrow, .projects-link::after { transition: none; transform: none !important; }
  .js [data-reveal] { opacity: 1; translate: none; transition: none; }
  .sticky-cta, .consent { transition: none; }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}
