:root {
  --duration-stagger: 40ms;
  --duration-micro: 80ms;
  --duration-quick: 150ms;
  --duration-fast: 250ms;
  --duration-medium: 350ms;
  --duration-slow: 400ms;
  --duration-very-slow: 500ms;
  --ease-smooth-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: ease-in-out;
  --ease-out: ease-out;
  --distance-medium: 12px;
  --blur-medium: 3px;
  --stagger-dur: 500ms;
  --stagger-distance: 12px;
  --stagger-stagger: 40ms;
  --stagger-blur: 3px;
  --stagger-ease: var(--ease-smooth-out);
  --tabs-dur: 250ms;
  --tabs-ease: var(--ease-smooth-out);
  --tabs-text-muted: #777;
  --tabs-text-active: #111;
  --tabs-bar-bg: #f1f1f1;
  --tabs-pill-bg: #fff;
  --shake-distance: 6px;
  --shake-overshoot: 4px;
  --shake-dur-a: 80ms;
  --shake-dur-b: 60ms;
  --shake-ease: var(--ease-smooth-out);
  --revert-hold: 3000ms;
  --revert-dur: 280ms;
  --check-opacity-dur: 500ms;
  --check-rotate-dur: 500ms;
  --check-rotate-from: 80deg;
  --check-bob-dur: 500ms;
  --check-y-amount: 12px;
  --check-blur-dur: 500ms;
  --check-blur-from: 8px;
  --check-path-dur: 500ms;
  --check-path-delay: 80ms;
  --check-ease-out: var(--ease-smooth-out);
  --check-ease-opacity: var(--ease-smooth-out);
  --check-ease-rotate: var(--ease-smooth-out);
  --check-ease-bob: var(--ease-smooth-out);
  --check-ease-path: var(--ease-smooth-out);
  --learn-shift: 2px;
  --learn-spread: 8deg;
  --learn-in: 350ms;
  --learn-out: 250ms;
  --learn-ease: var(--ease-smooth-out);
  --tilt-perspective: 1000px;
  --tilt-return: 500ms;
  --tilt-return-ease: var(--ease-smooth-out);
  --tilt-follow: 250ms;
  --tilt-follow-ease: var(--ease-smooth-out);
  --tilt-glare-opacity: 0.28;
  --tilt-glare-fade: 300ms;
  --tilt-glare-ease: var(--ease-smooth-out);
  --icon-swap-dur: 250ms;
  --icon-swap-blur: 2px;
  --icon-swap-start-scale: 0.25;
  --icon-swap-ease: ease-in-out;
  --acc-expand: 250ms;
  --acc-collapse: 250ms;
  --acc-chevron: 250ms;
  --acc-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --toast-open: 350ms;
  --toast-close: 250ms;
  --toast-distance: 16px;
  --toast-blur: 2px;
  --toast-scale: 0.97;
  --toast-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --tt-in-dur: 150ms;
  --tt-out-dur: 50ms;
  --tt-scale: 0.98;
  --tt-delay: 80ms;
  --tt-in-ease: ease-out;
  --tt-out-ease: ease-out;
  --tt-bg: #ffffff;
  --tt-fg: #2f2f2f;
  --digit-dur: 500ms;
  --digit-distance: 8px;
  --digit-stagger: 70ms;
  --digit-blur: 2px;
  --digit-ease: cubic-bezier(0.34, 1.45, 0.64, 1);
  --digit-dir-x: 0;
  --digit-dir-y: 1;
  --toggle-dur: 350ms;
  --toggle-travel: 14.66px;
  --toggle-ov1: 1px;
  --toggle-ov2: 0px;
  --toggle-track: 0ms;
  --toggle-ease: cubic-bezier(0.34, 1.35, 0.64, 1);
}

html {
  scroll-behavior: smooth;
}

.t-stagger-line {
  display: block;
}

section#headline h1 > .t-stagger-line {
  color: #000;
}

.t-stagger.js-ready:not(.is-shown) .t-stagger-line {
  opacity: 0;
  transform: translateY(var(--stagger-distance));
  filter: blur(var(--stagger-blur));
}

.t-stagger.js-ready .t-stagger-line {
  transition:
    opacity var(--stagger-dur) var(--stagger-ease),
    transform var(--stagger-dur) var(--stagger-ease),
    filter var(--stagger-dur) var(--stagger-ease);
}

.t-stagger.js-ready .t-stagger-line--2 {
  transition-delay: var(--stagger-stagger);
}

.t-stagger.is-shown .t-stagger-line {
  opacity: 1;
  transform: translateY(0);
  filter: none;
}

.reveal {
  transition:
    opacity var(--duration-very-slow) var(--ease-smooth-out),
    transform var(--duration-very-slow) var(--ease-smooth-out);
}

.reveal.is-pending {
  opacity: 0;
  transform: translateY(16px);
}

.reveal.is-in {
  opacity: 1;
  transform: translateY(0);
}

nav a {
  position: relative;
  transition: color var(--duration-fast) var(--ease-smooth-out);
}

nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -4px;
  height: 2px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--duration-fast) var(--ease-smooth-out);
}

nav a:hover::after,
nav a:focus-visible::after {
  transform: scaleX(1);
}

#work a img {
  transition:
    border-color var(--duration-fast) var(--ease-smooth-out),
    transform var(--duration-fast) var(--ease-smooth-out);
}

#work a:hover img,
#work a:focus-visible img {
  transform: scale(1.02);
}

#work a:active img {
  transform: scale(0.97);
}

#articles li a {
  transition: border-color var(--duration-fast) var(--ease-smooth-out);
}

.social a {
  transition:
    color var(--duration-fast) var(--ease-smooth-out),
    transform var(--duration-quick) var(--ease-smooth-out);
}

.social a:hover {
  transform: translateY(-2px);
}

.t-tabs {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 3px;
  border-radius: 48px;
  background: var(--tabs-bar-bg);
  margin-top: 24px;
}

.t-tab {
  position: relative;
  appearance: none;
  border: 0;
  background: transparent;
  height: 36px;
  padding: 0 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  color: var(--tabs-text-muted);
  cursor: pointer;
  border-radius: 48px;
  z-index: 1;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  transition: color var(--tabs-dur) var(--tabs-ease);
}

.t-tab:not([aria-selected="true"]):hover,
.t-tab[aria-selected="true"] {
  color: var(--tabs-text-active);
}

.t-tabs-pill {
  position: absolute;
  top: 3px;
  bottom: 3px;
  left: 0;
  height: auto;
  width: 0;
  background: var(--tabs-pill-bg);
  border-radius: 48px;
  transform: translateX(0);
  transition:
    transform var(--tabs-dur) var(--tabs-ease),
    width var(--tabs-dur) var(--tabs-ease);
  will-change: transform, width;
  z-index: 0;
  pointer-events: none;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}

.t-input-wrap {
  display: contents;
}

.t-input {
  transition: border-color 150ms ease-out;
}

.t-input.is-error {
  border-color: #c0392b !important;
}

form .t-error-msg {
  color: #c0392b;
  text-align: right;
}

.t-error-msg {
  opacity: 0;
  visibility: hidden;
  margin: 0.2rem 0 0.6rem;
  color: #c0392b;
  font-size: 0.9rem;
  transition:
    opacity var(--revert-dur) ease-out,
    visibility 0s linear var(--revert-dur);
}

.t-input-wrap.is-error .t-error-msg {
  opacity: 1;
  visibility: visible;
  transition:
    opacity var(--revert-dur) ease-out,
    visibility 0s linear 0s;
}

.t-input.is-shaking {
  animation: t-input-shake calc(var(--shake-dur-a) * 2 + var(--shake-dur-b) * 2) linear;
}

@keyframes t-input-shake {
  0% { transform: translateX(0); animation-timing-function: var(--shake-ease); }
  28.57% { transform: translateX(var(--shake-distance)); animation-timing-function: var(--shake-ease); }
  57.14% { transform: translateX(calc(var(--shake-distance) * -1)); animation-timing-function: var(--shake-ease); }
  78.57% { transform: translateX(var(--shake-overshoot)); animation-timing-function: var(--shake-ease); }
  100% { transform: translateX(0); }
}

.t-success-check {
  display: inline-block;
  margin-left: 10px;
  vertical-align: middle;
  transform-origin: center;
  opacity: 0;
}

.t-success-check svg {
  display: block;
  overflow: visible;
  width: 1.5rem;
  height: 1.5rem;
  color: #111;
}

.send-btn .t-success-check {
  position: relative;
  top: 2px;
}

.t-success-check svg path {
  stroke-dasharray: 24;
  stroke-dashoffset: 24;
}

.t-success-check[data-state="in"] {
  animation:
    t-check-fade var(--check-opacity-dur) var(--check-ease-opacity) forwards,
    t-check-rotate var(--check-rotate-dur) var(--check-ease-rotate) forwards,
    t-check-blur var(--check-blur-dur) var(--check-ease-out) forwards,
    t-check-bob var(--check-bob-dur) var(--check-ease-bob) forwards;
}

.t-success-check[data-state="in"] svg path {
  animation: t-check-draw var(--check-path-dur) var(--check-ease-path) var(--check-path-delay) forwards;
}

@keyframes t-check-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes t-check-rotate {
  from { transform: rotate(var(--check-rotate-from)); }
  to { transform: rotate(0deg); }
}
@keyframes t-check-blur {
  from { filter: blur(var(--check-blur-from)); }
  to { filter: blur(0); }
}
@keyframes t-check-bob {
  from { translate: 0 var(--check-y-amount); }
  to { translate: 0 0; }
}
@keyframes t-check-draw { to { stroke-dashoffset: 0; } }

.t-learn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.t-learn-chevron {
  display: inline-flex;
  transform: translateX(0);
  transition: transform var(--learn-out) var(--learn-ease);
}

.t-learn-arm {
  transform-box: view-box;
  transform-origin: 10px 8px;
  vector-effect: non-scaling-stroke;
  transition: transform var(--learn-out) var(--learn-ease);
}

.t-learn:hover .t-learn-chevron {
  transform: translateX(var(--learn-shift));
  transition-duration: var(--learn-in);
}

.t-learn:hover .t-learn-arm {
  transition-duration: var(--learn-in);
}

.t-learn:hover .t-learn-arm-top {
  transform: rotate(var(--learn-spread));
}

.t-learn:hover .t-learn-arm-bot {
  transform: rotate(calc(var(--learn-spread) * -1));
}

.t-tilt {
  touch-action: pan-y;
}

.t-tilt-card {
  position: relative;
  display: block;
  overflow: hidden;
  transform:
    perspective(var(--tilt-perspective))
    rotateX(var(--tilt-rx, 0deg))
    rotateY(var(--tilt-ry, 0deg));
  transform-style: preserve-3d;
  transition: transform var(--tilt-return) var(--tilt-return-ease);
  will-change: transform;
}
.g-demo .t-tilt-card {
  border-radius: 18px;
}
.g-now-logo.t-tilt-card {
  display: grid;
  border-radius: 24px;
}
.g-about-photo.t-tilt-card {
  border-radius: 24px;
}
.projects .item .t-tilt-card,
.g-project .t-tilt-card {
  border-radius: 18px;
}

.t-tilt-card.is-tilting {
  transition: transform var(--tilt-follow) var(--tilt-follow-ease);
}

.t-tilt-glare {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: screen;
  background:
    radial-gradient(circle 95px at var(--tilt-gx, 50%) var(--tilt-gy, 50%),
      rgba(255, 255, 255, 0.48), rgba(255, 255, 255, 0.06) 52%, rgba(255, 255, 255, 0) 84%);
  transition: opacity var(--tilt-glare-fade) var(--tilt-glare-ease);
}

.t-tilt.is-hover .t-tilt-glare {
  opacity: var(--tilt-glare-opacity);
}

.t-icon-swap {
  position: relative;
  display: inline-grid;
}
.t-icon-swap .t-icon {
  grid-area: 1 / 1;
  transition:
    opacity var(--icon-swap-dur) var(--icon-swap-ease),
    filter var(--icon-swap-dur) var(--icon-swap-ease),
    transform var(--icon-swap-dur) var(--icon-swap-ease);
  will-change: opacity, filter, transform;
}
.t-icon-swap[data-state="a"] .t-icon[data-icon="a"],
.t-icon-swap[data-state="b"] .t-icon[data-icon="b"] {
  opacity: 1;
  filter: blur(0);
  transform: scale(1);
}
.t-icon-swap[data-state="a"] .t-icon[data-icon="b"],
.t-icon-swap[data-state="b"] .t-icon[data-icon="a"] {
  opacity: 0;
  filter: blur(var(--icon-swap-blur));
  transform: scale(var(--icon-swap-start-scale));
}

.t-acc-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--acc-collapse) var(--acc-ease);
}
.t-acc[data-open="true"] .t-acc-panel {
  grid-template-rows: 1fr;
  transition: grid-template-rows var(--acc-expand) var(--acc-ease);
}
.t-acc-panel-inner {
  overflow: hidden;
  opacity: 0;
  filter: blur(2px);
  transition:
    opacity var(--acc-collapse) var(--acc-ease),
    filter var(--acc-collapse) var(--acc-ease);
}
.t-acc[data-open="true"] .t-acc-panel-inner {
  opacity: 1;
  filter: blur(0);
  transition:
    opacity var(--acc-expand) var(--acc-ease),
    filter var(--acc-expand) var(--acc-ease);
}
.t-acc-chevron {
  display: inline-flex;
  transform: scaleY(1);
  transform-origin: center;
  transition: transform var(--acc-chevron) var(--acc-ease);
}
.t-acc-chevron path { vector-effect: non-scaling-stroke; }
.t-acc[data-open="true"] .t-acc-chevron {
  transform: scaleY(-1);
}

.t-toast {
  opacity: 0;
  transform: translateY(var(--toast-distance)) scale(var(--toast-scale));
  filter: blur(var(--toast-blur));
  will-change: transform, opacity, filter;
  pointer-events: none;
  transition:
    opacity var(--toast-close) var(--toast-ease),
    transform var(--toast-close) var(--toast-ease),
    filter var(--toast-close) var(--toast-ease);
}
.t-toast.is-open {
  opacity: 1;
  transform: translateY(0) scale(1);
  filter: blur(0);
  pointer-events: auto;
  transition:
    opacity var(--toast-open) var(--toast-ease),
    transform var(--toast-open) var(--toast-ease),
    filter var(--toast-open) var(--toast-ease);
}

.t-tt-wrap {
  position: relative;
  display: inline-block;
}
.t-tt {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translate(-50%, 0) scale(var(--tt-scale));
  transform-origin: 50% 100%;
  padding: 8px 12px;
  border-radius: 8px;
  background: var(--tt-bg);
  color: var(--tt-fg);
  white-space: nowrap;
  font-size: 0.8rem;
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.06),
    0 2px 6px 0 rgba(0, 0, 0, 0.05),
    0 4px 42px 0 rgba(0, 0, 0, 0.06);
  opacity: 0;
  pointer-events: none;
  transition:
    opacity var(--tt-out-dur) var(--tt-out-ease),
    transform var(--tt-out-dur) var(--tt-out-ease);
}
.t-tt-wrap:hover .t-tt,
.t-tt-trigger:focus-visible + .t-tt {
  opacity: 1;
  transform: translate(-50%, 0) scale(1);
  transition-duration: var(--tt-in-dur);
  transition-timing-function: var(--tt-in-ease);
  transition-delay: var(--tt-delay);
}

@keyframes t-digit-pop-in {
  0% {
    transform: translate(
      calc(var(--digit-distance) * var(--digit-dir-x)),
      calc(var(--digit-distance) * var(--digit-dir-y))
    );
    opacity: 0;
    filter: blur(var(--digit-blur));
  }
  100% { transform: translate(0, 0); opacity: 1; filter: blur(0); }
}
.t-digit-group {
  display: inline-flex;
  align-items: baseline;
}
.t-digit {
  display: inline-block;
  will-change: transform, opacity, filter;
}
.t-digit-group.is-animating .t-digit {
  animation: t-digit-pop-in var(--digit-dur) var(--digit-ease) both;
}
.t-digit-group.is-animating .t-digit[data-stagger="1"] {
  animation-delay: var(--digit-stagger);
}
.t-digit-group.is-animating .t-digit[data-stagger="2"] {
  animation-delay: calc(var(--digit-stagger) * 2);
}

.t-toggle { transition: background var(--toggle-track) var(--toggle-ease); }
.t-toggle-thumb { translate: 0 0; will-change: translate; }
.t-toggle[data-on="true"] .t-toggle-thumb { translate: var(--toggle-travel) 0; }
.t-toggle.is-init[data-on="true"] .t-toggle-thumb { animation: t-toggle-on var(--toggle-dur) var(--toggle-ease) both; }
.t-toggle.is-init[data-on="false"] .t-toggle-thumb { animation: t-toggle-off var(--toggle-dur) var(--toggle-ease) both; }
@keyframes t-toggle-on {
  0% { translate: 0 0; }
  55% { translate: calc(var(--toggle-travel) + var(--toggle-ov1)) 0; }
  80% { translate: calc(var(--toggle-travel) - var(--toggle-ov2)) 0; }
  100% { translate: var(--toggle-travel) 0; }
}
@keyframes t-toggle-off {
  0% { translate: var(--toggle-travel) 0; }
  55% { translate: calc(0px - var(--toggle-ov1)) 0; }
  80% { translate: var(--toggle-ov2) 0; }
  100% { translate: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .t-stagger-line,
  .reveal,
  .t-tabs-pill,
  .t-tab,
  nav a,
  nav a::after,
  #work a img,
  #articles li a,
  .social a,
  .t-learn-chevron,
  .t-learn-arm,
  .t-tilt-card,
  .t-icon-swap .t-icon,
  .t-acc-panel,
  .t-acc-panel-inner,
  .t-acc-chevron,
  .t-toast,
  .t-tt {
    transition: none !important;
    transform: none !important;
    filter: none !important;
  }
  .t-input { animation: none !important; transform: none !important; }
  .t-success-check { animation: none !important; }
  .t-success-check[data-state="in"] { opacity: 1; }
  .t-success-check[data-state="in"] svg path {
    animation: none !important;
    stroke-dashoffset: 0 !important;
  }
  .t-digit-group .t-digit { animation: none !important; }
  .t-toggle-thumb { animation: none !important; }
}
