/* ===================================================================
   David Vallejo — site
   Flight-deck minimal: deep charcoal, white type, greys and hairlines.
   DIN-style condensed caps for headings and controls, monospace for
   data. Panels are square, framed in a thin steel-blue line. Colour is
   kept to two blues: steel blue for buttons and panel frames, and one
   light blue for markers, highlights, selections and hovers.
   Shared by the home page and the Apps page.
   =================================================================== */

:root {
  /* Surfaces */
  --paper: #16171b;   /* deep charcoal — softer than pure black */
  --panel: #1d1f24;   /* panels sit one step lighter */
  --ink: #f4f4f5;
  --ink-2: #b4b4bb;
  --ink-3: #7d7d86;
  --line: rgba(255, 255, 255, .12);
  --line-strong: rgba(255, 255, 255, .26);

  /* Splashes of colour, each with one job:
     steel blue — actions (the solid buttons) and panel frames
     light blue — everything else: section markers, the status light,
                  the hero greeting and role, selections, hovers */
  --btn: #1d4863;        /* steel blue, behind white text */
  --btn-hover: #25597a;
  --light-blue: #70b6e3; /* the site's one light blue */
  --marker: var(--light-blue);  /* section markers, set in italic */
  --blue: var(--light-blue);    /* selections, hovers, highlights */
  --on-blue: #06121c;    /* text on blue fills (white is too faint there) */
  --signal: var(--light-blue);       /* status light */
  --hero-accent: var(--light-blue);  /* "Hi, I'm" and "Web Developer & Designer" */

  /* Type */
  --display: "Barlow Condensed", "Barlow", "Arial Narrow", sans-serif;
  --body: "Barlow", system-ui, -apple-system, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --radius: 0px;
  --wrap: 1160px;
  --gutter: clamp(16px, 4vw, 32px);
  --ease: cubic-bezier(.22, 1, .36, 1);

  /* Tokens the chat widget expects */
  --color-primary: #33363d;
  --color-primary-rgb: 51, 54, 61;
  --color-text: var(--ink);
  --color-text-secondary: var(--ink-3);
  --color-bg-secondary: #1d1f24;
  --color-border: var(--line);
  --color-surface: #1d1f24;
  --radius-xl: 4px;
  --shadow-md: 0 4px 16px rgba(0, 0, 0, .6);
}

*, *::before, *::after { box-sizing: border-box; }

/* Anchors land below the sticky header, not under it */
html {
  scroll-behavior: smooth;
  scroll-padding-top: 69px; /* header height + its 1px border */
}

/* Sections that start flush (no top padding) get a little air too */
#skills, #experience { scroll-margin-top: 24px; }

body {
  margin: 0;
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* A faint engineering grid behind the top of the page, fading out */
body::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1100px;
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(255, 255, 255, .035) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .035) 1px, transparent 1px);
  background-size: 96px 96px;
  background-position: center top;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
}

/* On the home page site.js redraws that grid on a canvas (see "background
   lattice") so it can glow like the logo and its squares can turn over in
   3D; same place, same fade. */
.has-lattice body::before { display: none; }
.lattice {
  position: absolute;
  inset: 0 0 auto;
  width: 100%;
  height: 1100px;
  z-index: -1;
  pointer-events: none;
  filter:
    drop-shadow(0 0 2px rgba(112, 182, 227, .95))
    drop-shadow(0 0 7px rgba(112, 182, 227, .6))
    drop-shadow(0 0 16px rgba(112, 182, 227, .35));
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
}

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

::selection { background: rgba(112, 182, 227, .35); }

/* ---- scrollbar: graphite on black ---------------------------------- */

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--paper); }
::-webkit-scrollbar-thumb {
  background: #45474f;
  border: 2px solid var(--paper);
}
::-webkit-scrollbar-thumb:hover { background: #5d5f68; }
::-webkit-scrollbar-corner { background: var(--paper); }

@supports not selector(::-webkit-scrollbar) {
  html { scrollbar-color: #45474f var(--paper); }
}

:focus-visible {
  outline: 1px solid var(--blue);
  outline-offset: 3px;
}

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* ---- type ---------------------------------------------------------- */

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .02em;
  line-height: 1;
  margin: 0;
}

p { margin: 0; }

/* Monospace label: section numbers, captions, data */
.eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* Formerly a colour gradient; now simply full-strength white */
.gradient-text { color: var(--ink); }

/* Lit like the logo in the nav */
.glow-text {
  color: var(--dv-logo, #eaf6ff);
  text-shadow:
    0 0 2px rgba(var(--dv-glow, 112, 182, 227), .95),
    0 0 7px rgba(var(--dv-glow, 112, 182, 227), .6),
    0 0 16px rgba(var(--dv-glow, 112, 182, 227), .35);
}

/* ---- buttons: rectangular, caps, invert on hover ------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6em;
  padding: 14px 26px;
  border: 1px solid transparent;
  border-radius: 0;
  font: 600 13px/1 var(--body);
  letter-spacing: .16em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background .25s, border-color .25s, color .25s, transform .25s var(--ease);
  white-space: nowrap;
}

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

.btn-solid {
  background: var(--btn);
  border-color: var(--btn);
  color: #fff;
}
.btn-solid:hover { background: var(--btn-hover); border-color: var(--btn-hover); }

.btn-ghost {
  border-color: rgba(255, 255, 255, .5);
  background: transparent;
  color: #fff;
}
.btn-ghost:hover { background: #fff; border-color: #fff; color: #000; }

.btn-sm { padding: 11px 18px; font-size: 12px; }

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

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(22, 23, 27, .86);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--light-blue);
}

.site-header .wrap {
  display: flex;
  align-items: center;
  gap: 28px;
  height: 68px;
}

.brand { display: inline-flex; line-height: 0; flex: none; }

/* Logo → stats, read out like telemetry */
.header-stats {
  display: flex;
  align-items: center;
  gap: 24px;
  margin: 0;
  padding: 0 0 0 28px;
  list-style: none;
  border-left: 1px solid var(--line);
  height: 28px;
}

.header-stats li {
  display: flex;
  align-items: baseline;
  gap: 7px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-3);
  white-space: nowrap;
}

.header-stats strong {
  font-family: var(--display);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--light-blue);
}

.header-links {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;
}

.header-links a:not(.btn) {
  position: relative;
  padding: 8px 12px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-2);
  text-decoration: none;
  transition: color .2s;
}

.header-links a:not(.btn):hover { color: #fff; }
.header-links a[aria-current="page"] { color: var(--blue); }

/* Hover line: unfurls from the centre of the word out to both edges,
   and draws back in on the way out. Stays drawn under the current page. */
.header-links a:not(.btn)::after {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;      /* matches the link's side padding: spans the word */
  bottom: 1px;
  height: 1.5px;
  background: var(--light-blue);
  box-shadow: 0 0 8px rgba(112, 182, 227, .55);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform .45s var(--ease);
}

.header-links a:not(.btn):hover::after,
.header-links a:not(.btn):focus-visible::after,
.header-links a[aria-current="page"]::after { transform: scaleX(1); }

.header-links .btn { margin-left: 10px; }

@media (max-width: 1060px) {
  .header-stats { display: none; }
}

/* Phones and tablets: the section links move to the bottom tab bar,
   leaving the logo and "Book a call" up top */
@media (max-width: 860px) {
  .header-links a:not(.btn) { display: none; }
}

/* ---- mobile tab bar --------------------------------------------------
   Pinned to the bottom centre on phones and tablets, in thumb reach.
   The current section's icon lights up; scrolling down settles the bar
   into a compact state and scrolling up brings it back to full size. */

.mobile-nav {
  --mnav-h: 56px;
  --mnav-bottom: calc(16px + env(safe-area-inset-bottom));
  display: none;
  position: fixed;
  left: 50%;
  bottom: var(--mnav-bottom);
  z-index: 1050;
  align-items: center;
  gap: 2px;
  height: var(--mnav-h);
  max-width: calc(100% - 24px);
  padding: 6px;
  border: 1px solid var(--dv-logo, #eaf6ff);
  background: rgba(29, 31, 36, .94);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  /* the logo's glow, around the whole bar */
  box-shadow:
    0 0 2px rgba(var(--dv-glow, 112, 182, 227), .95),
    0 0 7px rgba(var(--dv-glow, 112, 182, 227), .6),
    0 0 16px rgba(var(--dv-glow, 112, 182, 227), .35),
    0 12px 40px -12px rgba(0, 0, 0, .9);
  transform: translateX(-50%);
  transition: transform .4s var(--ease), opacity .4s ease;
  animation: mnavIn .7s var(--ease) backwards;
}

.mobile-nav.is-compact {
  transform: translateX(-50%) scale(.9);
  opacity: .9;
}

.mobile-nav-item {
  display: grid;
  place-items: center;
  width: 44px;
  height: 42px;
  color: var(--ink-3);
  font-size: 17px;
  text-decoration: none;
  transition: color .25s, background .25s, transform .25s var(--ease);
}

.mobile-nav-item:hover { color: #fff; }
.mobile-nav-item:active { transform: scale(.9); }

.mobile-nav-item.active {
  background: none;
  color: var(--dv-logo, #eaf6ff);
  filter:
    drop-shadow(0 0 2px rgba(var(--dv-glow, 112, 182, 227), .95))
    drop-shadow(0 0 7px rgba(var(--dv-glow, 112, 182, 227), .6));
}

@keyframes mnavIn {
  from { opacity: 0; transform: translateX(-50%) translateY(24px); }
  to   { opacity: 1; transform: translateX(-50%); }
}

@media (max-width: 860px) {
  .mobile-nav { display: flex; }

  /* Room at the end of the page so the bar never covers the footer */
  body { padding-bottom: calc(88px + env(safe-area-inset-bottom)); }

  /* Lift the chat button (and its panel) to sit just above the bar */
  .mobile-nav ~ #chatWidget .chat-bubble {
    bottom: calc(16px + 56px + 12px + env(safe-area-inset-bottom));
  }
  .mobile-nav ~ #chatWidget .chat-panel {
    bottom: calc(16px + 56px + 12px + 62px + env(safe-area-inset-bottom));
  }
}

@media (max-width: 380px) {
  .mobile-nav-item { width: 40px; }
}

/* ---- chat widget, in the site's monochrome -------------------------- */

#chatWidget .chat-bubble {
  background: #fff;
  color: #000;
  animation: chatGlow 3s ease-in-out infinite;
}

@keyframes chatGlow {
  0%, 100% { box-shadow: 0 6px 24px rgba(0, 0, 0, .6), 0 0 0 0 rgba(255, 255, 255, .16); }
  50%      { box-shadow: 0 6px 24px rgba(0, 0, 0, .6), 0 0 26px 4px rgba(255, 255, 255, .22); }
}
#chatWidget .chat-bubble.active { background: #33363d; color: #fff; }
#chatWidget .chat-header-avatar i { color: #fff; }
#chatWidget .chat-suggestion-btn:hover { border-color: #fff; color: #fff; background: rgba(255, 255, 255, .06); }

/* ---- sections ------------------------------------------------------ */

.section { padding: clamp(64px, 10vw, 120px) 0; }

.section-head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 44px;
}

.section-head .eyebrow,
.skills-panel .eyebrow { margin-bottom: 14px; }

/* Numbered section markers ("01 — Work"): sky blue, italic */
.section-head .eyebrow,
.skills-panel .eyebrow,
.booking-copy .eyebrow,
.page-head .eyebrow {
  color: var(--marker);
  font-style: italic;
}

.section-head h2 { font-size: clamp(40px, 5.4vw, 64px); }
.section-head p { color: var(--ink-3); margin-top: 14px; max-width: 46ch; }

.rule {
  height: 1px;
  border: 0;
  margin: 0;
  background: var(--line);
}

.text-link {
  font-family: var(--body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #fff;
  text-decoration: none;
  white-space: nowrap;
  border-bottom: 1px solid var(--blue);
  padding-bottom: 4px;
  transition: color .2s;
}
.text-link:hover { color: var(--blue); }

/* ---- panels --------------------------------------------------------
   Square, a step lighter than the page, framed in a thin steel-blue
   line — the same colour as the buttons. */

.card {
  position: relative;
  border: 1px solid var(--light-blue);
  padding: clamp(24px, 3.4vw, 40px);
  background: #1d1f24e6; /* the panel colour, a touch see-through over the lattice */
}

/* ---- intro bento: hero + about | profile --------------------------- */

.intro { padding-top: clamp(32px, 6vw, 64px); }

.bento {
  display: grid;
  grid-template-columns: 1.45fr 1fr;
  grid-template-areas:
    "hero  profile"
    "about profile";
  gap: 16px;
}

.bento-hero { grid-area: hero; }
.bento-about { grid-area: about; }
.bento-profile { grid-area: profile; }

.bento-hero {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 360px;
  overflow: hidden;
}

/* Status light: a blue dot with a soft ring that swells out and fades */
.status {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  align-self: flex-start;
  margin-bottom: 30px;
  padding: 7px 12px;
  border: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-2);
}

.status-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--signal);
  box-shadow: 0 0 0 0 rgba(112, 182, 227, .6);
  animation: statusPulse 2.4s ease-out infinite;
}

@keyframes statusPulse {
  0%   { box-shadow: 0 0 0 0 rgba(112, 182, 227, .6); }
  70%  { box-shadow: 0 0 0 8px rgba(112, 182, 227, 0); }
  100% { box-shadow: 0 0 0 0 rgba(112, 182, 227, 0); }
}

/* "Hey! I'm" above the name, lit like the logo in the nav */
.bento-hero .eyebrow {
  margin-bottom: -8px;
  margin-left: 8px;
  color: var(--dv-logo, #eaf6ff);
  font-size: larger;
  text-shadow:
    0 0 2px rgba(var(--dv-glow, 112, 182, 227), .95),
    0 0 7px rgba(var(--dv-glow, 112, 182, 227), .6),
    0 0 16px rgba(var(--dv-glow, 112, 182, 227), .35);
}

.bento-hero h1 {
  font-size: clamp(76px, 11vw, 148px);
  font-weight: 700;
  letter-spacing: .01em;
  line-height: .86;
}

.hero-role {
  margin-top: 8px;
  margin-left: 6px;
  font-family: var(--mono);
  font-size: clamp(12px, 1.3vw, 20px);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--hero-accent);
}

.hero-lede {
  margin-top: 20px;
  max-width: 48ch;
  color: var(--ink-3);
}

.bento-about h2 {
  font-size: 26px;
  margin-bottom: 16px;
}

.bento-about p { color: var(--ink-2); }
.bento-about p + p { margin-top: 12px; }

.facts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  margin: 24px 0 0;
  padding: 18px 0 0;
  list-style: none;
  border-top: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.facts i { color: var(--ink-2); margin-right: 8px; }

.bento-profile {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.portrait {
  position: relative;
  width: min(220px, 62%);
  aspect-ratio: 1;
  margin: 8px 0 28px;
}

.portrait img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: 1px solid var(--line-strong);
}

.tagline {
  font-family: var(--display);
  font-size: clamp(24px, 2.5vw, 30px);
  font-weight: 600;
  line-height: 1.08;
  text-transform: uppercase;
  letter-spacing: .02em;
  color: var(--ink-2);
  max-width: 17ch;
}

.profile-lines {
  width: 100%;
  margin: 26px 0 28px;
  padding: 0;
  list-style: none;
  text-align: left;
}

.profile-lines li {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 11px 0;
  border-top: 1px solid var(--line);
  font-size: 15px;
}

.profile-lines li:last-child { border-bottom: 1px solid var(--line); }
.profile-lines span {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding-top: 3px;
}
.profile-lines b { font-weight: 500; text-align: right; }

.profile-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-top: auto;
}

/* ---- hero entrance -------------------------------------------------
   logo-intro.js adds .hero-wait while the intro covers the page, then
   .hero-go as it lifts: the two left cards rise from below, and the
   profile card glides in from the right 0.3s later. A long expo-out
   curve gives the soft, settling finish. */

.hero-wait .bento > .card { opacity: 0; }

.hero-go .bento-hero,
.hero-go .bento-about {
  animation: heroRise 1.2s cubic-bezier(.16, 1, .3, 1) both;
}

/* A breath behind the hero card so the pair reads as one smooth wave */
.hero-go .bento-about { animation-delay: .08s; }

.hero-go .bento-profile {
  animation: heroFromRight 1.2s cubic-bezier(.16, 1, .3, 1) .3s both;
}

@keyframes heroRise {
  from { opacity: 0; transform: translateY(70px); }
  to   { opacity: 1; transform: none; }
}

@keyframes heroFromRight {
  from { opacity: 0; transform: translateX(90px); }
  to   { opacity: 1; transform: none; }
}

/* Stats move into the page on small screens, where the header drops them */
.mobile-stats {
  display: none;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--line);
  background: var(--line);
}

.mobile-stats li {
  padding: 16px 18px;
  background: var(--panel);
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.mobile-stats strong {
  display: block;
  margin-bottom: 4px;
  font-family: var(--display);
  font-size: 30px;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--ink);
}

@media (max-width: 1060px) {
  .mobile-stats { display: grid; }
}

@media (max-width: 860px) {
  .bento {
    grid-template-columns: 1fr;
    grid-template-areas: "hero" "profile" "about";
  }
  .bento-hero { min-height: 0; }
}

/* ---- work orbit: squares that slide in from the right (site.js), then ride a
   wave and shift on hover -------------------------------------------- */

.orbit {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin: 0;
  padding: 24px 0 8px;
  list-style: none;
}

.orbit li { flex: 1 1 0; min-width: 0; }

.orbit a {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  text-decoration: none;
  text-align: center;
  transition: transform .5s var(--ease);
}

/* The resting wave: alternate squares sit high and low */
.orbit li:nth-child(odd)  a { transform: translateY(-18px); }
.orbit li:nth-child(even) a { transform: translateY(18px); }

/* On hover the whole row flips the wave, and the hovered one lifts */
.orbit:hover li:nth-child(odd)  a { transform: translateY(14px); }
.orbit:hover li:nth-child(even) a { transform: translateY(-14px); }
.orbit li a:hover,
.orbit li a:focus-visible { transform: translateY(-30px) !important; }

.orbit-dot {
  position: relative;
  overflow: hidden;   /* keeps the glare inside the square */
  display: grid;
  place-items: center;
  width: clamp(64px, 8vw, 96px);
  aspect-ratio: 1;
  border: 1px solid var(--light-blue);
  background: var(--paper);
  font-size: clamp(19px, 2.2vw, 24px);
  color: #a4b7c4;
  transition: border-color .3s, background .3s, color .3s, box-shadow .3s;
}

.orbit a:hover .orbit-dot,
.orbit a:focus-visible .orbit-dot {
  /* Lit like the logo: near-white, with a light-blue halo */
  border-color: #eaf6ff;
  background: #eaf6ff;
  color: var(--on-blue);
  box-shadow:
    0 0 6px rgba(112, 182, 227, .95),
    0 0 20px rgba(112, 182, 227, .7),
    0 0 46px rgba(112, 182, 227, .4);
}

/* Glare: every 3s a soft diagonal shine sweeps across each square from
   right to left. The sweep itself takes ~0.9s; the rest of the cycle is
   rest. Staggered so the light travels down the row right to left,
   rightmost square first. A hovered square skips it. */
.orbit-dot::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg,
    transparent 30%,
    rgba(255, 255, 255, .06) 42%,
    rgba(255, 255, 255, .32) 50%,
    rgba(255, 255, 255, .06) 58%,
    transparent 70%);
  transform: translateX(130%);
  animation: orbitGlare 3s ease-in-out infinite;
  pointer-events: none;
}

.orbit li:nth-last-child(2) .orbit-dot::after { animation-delay: .12s; }
.orbit li:nth-last-child(3) .orbit-dot::after { animation-delay: .24s; }
.orbit li:nth-last-child(4) .orbit-dot::after { animation-delay: .36s; }
.orbit li:nth-last-child(5) .orbit-dot::after { animation-delay: .48s; }
.orbit li:nth-last-child(6) .orbit-dot::after { animation-delay: .60s; }
.orbit li:nth-last-child(7) .orbit-dot::after { animation-delay: .72s; }

.orbit a:hover .orbit-dot::after,
.orbit a:focus-visible .orbit-dot::after { opacity: 0; }

@keyframes orbitGlare {
  0%        { transform: translateX(130%); }
  30%, 100% { transform: translateX(-130%); }
}

.orbit-name {
  font-family: var(--display);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  line-height: 1.15;
  color: var(--ink);
}

.orbit-kind {
  display: block;
  margin-top: 4px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* Phones: an even two-up grid of tiles, no wave. An odd one out at the end
   takes the full row. */
@media (max-width: 760px) {
  .orbit {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    padding: 8px 0 0;
  }
  .orbit li { display: flex; }
  .orbit li:last-child:nth-child(odd) { grid-column: 1 / -1; }

  .orbit li:nth-child(n) a,
  .orbit:hover li:nth-child(n) a,
  .orbit li:nth-child(n) a:hover,
  .orbit li:nth-child(n) a:focus-visible { transform: none !important; }

  .orbit a {
    flex: 1;
    justify-content: center;
    gap: 12px;
    padding: 20px 10px 18px;
    border: 1px solid var(--light-blue);
    background: #1d1f24e6;
    transition: border-color .3s, box-shadow .3s;
  }
  .orbit a:active {
    border-color: #eaf6ff;
    box-shadow:
      0 0 6px rgba(112, 182, 227, .95),
      0 0 20px rgba(112, 182, 227, .5);
  }
  /* The tile is the box; the icon sits in it bare, not in a box of its own */
  .orbit-dot {
    width: auto;
    aspect-ratio: auto;
    overflow: visible;
    border: 0;
    background: none;
    font-size: 26px;
    color: var(--light-blue);
  }
  .orbit-dot::after { display: none; }
  .orbit a:hover .orbit-dot,
  .orbit a:focus-visible .orbit-dot { background: none; box-shadow: none; color: #eaf6ff; }
  .orbit-name { font-size: 15px; }
  .hover-hint { display: none; }   /* nothing to hover on a phone */
}

/* ---- skills -------------------------------------------------------- */

/* One hair-thin string behind the skills card, glowing like the logo (drawn by site.js): the
   canvas spans the page and reaches a little past the section. */
#skills { position: relative; }
#skills > .wrap { position: relative; z-index: 1; }
.beams {
  position: absolute;
  left: 0;
  top: -30px;
  width: 100%;
  height: calc(100% + 60px);
  z-index: 0;
  pointer-events: none;
  filter:
    drop-shadow(0 0 2px rgba(112, 182, 227, .95))
    drop-shadow(0 0 7px rgba(112, 182, 227, .6))
    drop-shadow(0 0 16px rgba(112, 182, 227, .35));
}

.skills-panel { position: relative; }

.skills-panel h2 {
  font-size: clamp(40px, 5.4vw, 64px);
  margin-bottom: 40px;
}

.skills-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 36px 40px;
}

.skills-grid h3 {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .18em;
  color: var(--blue);
  padding-bottom: 10px;
  margin-bottom: 12px;
  border-bottom: 1px solid var(--line);
}

.skills-grid ul {
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--ink-2);
  font-size: 16px;
}

.skills-grid li { padding: 3px 0; }

@media (max-width: 860px) { .skills-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .skills-grid { grid-template-columns: 1fr; } }

/* ---- experience ---------------------------------------------------- */

/* Jobs scroll inside a fixed frame. Each job is a panel strapped by a
   harness of light (three straps, drawn by site.js) to the year it was
   last worked, which glows to its right. The rail at the far right is
   the frame's scrollbar. Without scrolling (phones, no JS) every job
   stays lit; once the frame scrolls (.is-live) only the job in focus is. */

.jobs-rig {
  --glow: 112, 182, 227; /* --light-blue, as r, g, b */
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
}

.jobs {
  position: relative;
  margin: 0;
  padding: 28px 30px 28px 0;
  list-style: none;
  display: grid;
  gap: 22px;
  height: clamp(380px, 62vh, 500px);
  overflow-y: auto;
  overscroll-behavior: auto;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(#0000, #000 28px, #000 calc(100% - 28px), #0000);
          mask-image: linear-gradient(#0000, #000 28px, #000 calc(100% - 28px), #0000);
}
.jobs::-webkit-scrollbar { display: none; }
.jobs:focus-visible { outline: 1px solid var(--blue); outline-offset: 4px; }

.job {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(48px, 10vw, 132px) auto;
  align-items: stretch;
}

.job-body {
  position: relative;
  padding: 24px 28px 26px;
  background: var(--panel);
  border: 1px solid rgba(var(--glow), .5);
  box-shadow: inset 0 0 28px -14px rgba(var(--glow), .55);
  transition: border-color .5s ease, box-shadow .5s ease, opacity .5s ease;
}

/* The buckle: a bar of light on the edge the straps clip to */
.job-body::after {
  content: "";
  position: absolute;
  top: 10px;
  bottom: 10px;
  right: -2px;
  width: 3px;
  background: var(--blue);
  box-shadow: 0 0 10px rgba(var(--glow), .9), 0 0 22px rgba(var(--glow), .5);
  transition: opacity .5s ease;
}

.job-when {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 10px;
}

.job h3 { font-size: 28px; }
.job-at {
  margin-top: 8px;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--blue);
}
.job p { color: var(--ink-3); margin-top: 12px; max-width: 64ch; }

/* Harness: site.js draws the straps to the box's real size */
.job-harness { position: relative; transition: opacity .5s ease; }
.job-harness svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  filter: drop-shadow(0 0 3px rgba(var(--glow), .9)) drop-shadow(0 0 9px rgba(var(--glow), .45));
}
.strap { fill: none; stroke: rgba(var(--glow), .55); stroke-width: 1.25; }
.strap-pulse {
  fill: none;
  stroke: #eaf6ff;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-dasharray: .16 .84;
  stroke-dashoffset: .16;
  animation: strapPulse 2.6s linear infinite;
}
.strap-pulse:nth-of-type(4) { animation-delay: -.85s; }
.strap-pulse:nth-of-type(6) { animation-delay: -1.7s; }
.strap-clip { fill: var(--blue); }
.strap-ring { fill: var(--paper); stroke: var(--blue); stroke-width: 1.5; }

@keyframes strapPulse {
  to { stroke-dashoffset: -.84; }
}

/* The year last worked, lit by the harness */
.job-year {
  position: relative;
  align-self: center;
  padding-left: 12px;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(34px, 5.4vw, 60px);
  line-height: 1;
  letter-spacing: .02em;
  font-variant-numeric: tabular-nums;
  color: #eaf6ff;
  text-shadow:
    0 0 6px rgba(var(--glow), .95),
    0 0 22px rgba(var(--glow), .6),
    0 0 54px rgba(var(--glow), .35);
  animation: yearBreathe 3.6s ease-in-out infinite;
  transition: color .5s ease, text-shadow .5s ease;
}

.job-year-tag {
  position: absolute;
  top: calc(100% + 8px);
  left: 14px;
  font-family: var(--mono);
  font-weight: 400;
  font-size: 10.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-3);
  text-shadow: none;
  white-space: nowrap;
}
.job-year-tag.is-now { color: var(--blue); }

@keyframes yearBreathe {
  50% {
    text-shadow:
      0 0 9px rgba(var(--glow), 1),
      0 0 32px rgba(var(--glow), .8),
      0 0 76px rgba(var(--glow), .5);
  }
}

/* Out of focus: the harness goes slack and the year drops to an outline */
.jobs-rig.is-live .job:not(.is-active) .job-body {
  border-color: var(--line);
  box-shadow: none;
  opacity: .62;
}
.jobs-rig.is-live .job:not(.is-active) .job-body::after { opacity: 0; }
.jobs-rig.is-live .job:not(.is-active) .job-harness { opacity: .22; }
.jobs-rig.is-live .job:not(.is-active) .strap-pulse { display: none; }
.jobs-rig.is-live .job:not(.is-active) .job-year {
  color: transparent;
  -webkit-text-stroke: 1px var(--line-strong);
  text-shadow: none;
  animation: none;
}

/* The scrollbar: a hairline track with a thumb of light */
.jobs-rail {
  display: none;
  position: relative;
  width: 16px;
  margin: 28px 0;
  cursor: grab;
  touch-action: none;
}
.jobs-rig.is-live .jobs-rail { display: block; }
.jobs-rail:active { cursor: grabbing; }
.jobs-rail::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 1px;
  background: var(--line-strong);
}
.jobs-thumb {
  position: absolute;
  top: 0;
  left: calc(50% - 2px);
  width: 4px;
  height: 40px;
  background: #eaf6ff;
  box-shadow: 0 0 8px rgba(var(--glow), 1), 0 0 22px rgba(var(--glow), .7), 0 0 44px rgba(var(--glow), .4);
  will-change: transform;
}

/* Phones: no inner scrolling — the whole list shows, fully lit */
@media (max-width: 640px) {
  .jobs {
    height: auto;
    overflow: visible;
    padding: 0 0 18px;
    -webkit-mask-image: none;
            mask-image: none;
  }
  .job { grid-template-columns: minmax(0, 1fr) 30px auto; }
  .job-body { padding: 20px 18px 22px; }
  .job h3 { font-size: 24px; }
  .job-year { padding-left: 8px; }
  .job-year-tag { left: 9px; font-size: 9.5px; }
}

/* ---- calendar: schedule a 15, 30 or 60-minute video call ----------- */

.booking {
  display: grid;
  grid-template-columns: 1fr 1.25fr;
  gap: clamp(28px, 5vw, 64px);
  align-items: start;
}

.booking-copy .eyebrow { margin-bottom: 14px; }
.booking-copy h2 { font-size: clamp(40px, 5.4vw, 64px); }
.booking-copy > p { color: var(--ink-3); margin-top: 18px; max-width: 40ch; }

/* Call length: 15 / 30 / 60 min */
.durations {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 28px;
}

.durations > .fa-clock {
  margin-right: 6px;
  color: var(--ink-3);
}

.duration {
  padding: 9px 14px;
  border: 1px solid var(--line-strong);
  background: transparent;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  cursor: pointer;
  transition: border-color .2s, color .2s, background .2s;
}

.duration:hover { border-color: var(--blue); color: #fff; }

.duration[aria-pressed="true"] {
  border-color: var(--blue);
  background: var(--blue);
  color: var(--on-blue);
}

.contact-lines {
  margin: 34px 0 0;
  padding: 0;
  list-style: none;
}

.contact-lines li { padding: 12px 0; border-top: 1px solid var(--line); font-size: 16px; }
.contact-lines li:last-child { border-bottom: 1px solid var(--line); }
.contact-lines a { color: var(--ink-2); text-decoration: none; }
.contact-lines a:hover { color: var(--blue); }
.contact-lines i { width: 24px; color: var(--ink-3); }

.socials { display: flex; gap: 8px; margin-top: 22px; }

.socials a {
  display: grid;
  place-items: center;
  width: 40px; height: 40px;
  border: 1px solid var(--line-strong);
  color: var(--ink-2);
  text-decoration: none;
  transition: color .2s, border-color .2s, background .2s;
}
.socials a:hover { color: var(--on-blue); background: var(--blue); border-color: var(--blue); }

.cal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 18px;
}

.cal-head h3 { font-size: 22px; letter-spacing: .06em; }

.cal-nav { display: flex; gap: 6px; }

.cal-nav button {
  width: 34px; height: 34px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
}
.cal-nav button:disabled { opacity: .3; cursor: default; }
.cal-nav button:not(:disabled):hover { border-color: var(--blue); color: var(--blue); }

.cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
  text-align: center;
}

.cal-dow {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding-bottom: 8px;
}

.cal-day {
  aspect-ratio: 1;
  max-height: 46px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-3);
  font: 500 15px/1 var(--body);
  opacity: .35;
}

.cal-day.is-open {
  opacity: 1;
  color: var(--ink);
  border-color: var(--line);
  cursor: pointer;
  transition: border-color .2s, background .2s, color .2s;
}

.cal-day.is-open:hover { border-color: var(--blue); }

.cal-day.is-selected {
  background: var(--blue);
  border-color: var(--blue);
  color: var(--on-blue);
}

.slots-label {
  margin: 22px 0 10px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.slots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: 6px;
}

.slot {
  padding: 11px 0;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink);
  font: 500 14px/1 var(--mono);
  cursor: pointer;
  transition: border-color .2s, background .2s, color .2s;
}

.slot:hover { border-color: var(--blue); }
.slot[aria-pressed="true"] { background: var(--blue); border-color: var(--blue); color: var(--on-blue); }

.book-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 16px;
  margin-top: 22px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
}

.book-summary { flex: 1 1 200px; font-size: 15px; color: var(--ink-2); }
.book-row .btn[aria-disabled="true"] { opacity: .35; pointer-events: none; }
.book-alt { width: 100%; font-size: 14px; color: var(--ink-3); }
.book-alt a { color: var(--blue); }

@media (max-width: 860px) {
  .booking { grid-template-columns: 1fr; }
}

/* ---- footer -------------------------------------------------------- */

.site-footer {
  padding: 40px 0;
  border-top: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.footer-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.footer-row nav { display: flex; flex-wrap: wrap; gap: 6px 24px; }
.footer-row nav a { color: var(--ink-3); text-decoration: none; }
.footer-row nav a:hover { color: #fff; }

/* ---- Apps page ----------------------------------------------------- */

.page-head { padding: clamp(48px, 8vw, 96px) 0 36px; }
.page-head .eyebrow { margin-bottom: 14px; }
.page-head h1 { font-size: clamp(64px, 10vw, 128px); font-weight: 700; line-height: .88; letter-spacing: .01em; }
.page-head p { margin-top: 18px; color: var(--ink-3); max-width: 52ch; }

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 34px;
}

.filter-btn {
  padding: 10px 16px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink-2);
  font: 600 12px/1 var(--body);
  letter-spacing: .16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: all .2s;
}

.filter-btn:hover { color: #fff; border-color: var(--blue); }
.filter-btn.active { background: var(--blue); border-color: var(--blue); color: var(--on-blue); }

.apps-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  padding-bottom: 24px;
}

.app-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 30px;
  text-decoration: none;
  transition: transform .4s var(--ease), box-shadow .3s;
}

/* Hover: the panel lifts and its frame brightens and glows */
.app-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 0 0 1px var(--btn-hover), 0 14px 34px -14px rgba(37, 89, 122, .7);
}

.app-icon {
  display: grid;
  place-items: center;
  width: 48px; height: 48px;
  margin-bottom: 26px;
  border: 1px solid var(--line-strong);
  color: var(--ink-2);
  font-size: 18px;
  transition: background .3s, color .3s, border-color .3s;
}

.app-card:hover .app-icon { background: var(--blue); border-color: var(--blue); color: var(--on-blue); }

.app-card h3 { font-size: 28px; }
.app-card .orbit-kind { margin: 0 0 10px; }
.app-card p { margin-top: 12px; color: var(--ink-3); font-size: 16px; }

.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: auto;
  padding-top: 22px;
}

.tags span {
  padding: 4px 9px;
  border: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.app-card[hidden] { display: none; }

/* Cards start off to the right; clip at the screen edge so they never
   cause a sideways scrollbar while flying in */
.apps-section { overflow-x: clip; }

/* Cards fly in from the right, one after another, as they come into view.
   A keyframe animation (fill: backwards) rather than a transition, so once
   it ends the card is back to its own styles and the hover lift still works. */
.js-fly .app-card:not(.is-flown) { opacity: 0; }

.app-card.is-flown {
  animation: flyIn .9s var(--ease) backwards;
  animation-delay: var(--fly-delay, 0ms);
}

@keyframes flyIn {
  from {
    opacity: 0;
    transform: translateX(120px);
  }
  60% { opacity: 1; }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (max-width: 960px) { .apps-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .apps-grid { grid-template-columns: 1fr; } }

/* Arcade, now on the Apps page */
.arcade-screen {
  margin-top: 28px;
  aspect-ratio: 16 / 10;
  border: 1px solid var(--line-strong);
  overflow: hidden;
  background: #000;
}

.arcade-screen iframe { width: 100%; height: 100%; border: 0; display: block; }

.key {
  display: inline-block;
  padding: 1px 7px;
  border: 1px solid var(--line-strong);
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-2);
}

/* ---- the way on to Apps: a big word and a fat arrow, lit like the logo.
   It waits off to the right, out of sight, and site.js pops it out
   (.is-out) once the footer has been on screen for two seconds. */

.apps-cta-row {
  position: fixed;
  right: max(var(--gutter), calc((100vw - var(--wrap)) / 2 + var(--gutter)));
  bottom: 112px; /* clear of the footer and the chat button */
  z-index: 40;
  opacity: 0;
  visibility: hidden;
  transform: translateX(60px) scale(.82);
  transform-origin: right center;
  transition: opacity .3s ease, transform .3s ease, visibility 0s linear .3s;
}

.apps-cta-row.is-out {
  opacity: 1;
  visibility: visible;
  transform: none;
  /* a springy arrival: it overshoots a touch, then settles */
  transition: opacity .25s ease, transform .55s cubic-bezier(.34, 1.56, .64, 1), visibility 0s;
}

.apps-cta {
  display: inline-flex;
  align-items: center;
  gap: .22em;
  font-family: "Barlow", system-ui, sans-serif;
  font-weight: 800;
  font-size: clamp(64px, 11vw, 100px);
  line-height: .9;
  letter-spacing: .01em;
  text-transform: uppercase;
  text-decoration: none;
  color: #eaf6ff;
  /* The logo's glow, sized up for letters this big */
  filter:
    drop-shadow(0 0 4px rgba(112, 182, 227, .95))
    drop-shadow(0 0 16px rgba(112, 182, 227, .6))
    drop-shadow(0 0 38px rgba(112, 182, 227, .35));
  transition: filter .35s ease;
}

.apps-cta-arrow {
  height: .72em;
  width: auto;
  fill: currentColor;
  transition: transform .45s var(--ease);
}

.apps-cta:hover,
.apps-cta:focus-visible {
  outline: none;
  filter:
    drop-shadow(0 0 6px rgba(112, 182, 227, 1))
    drop-shadow(0 0 24px rgba(112, 182, 227, .8))
    drop-shadow(0 0 60px rgba(112, 182, 227, .5));
}
.apps-cta:hover .apps-cta-arrow,
.apps-cta:focus-visible .apps-cta-arrow { transform: translateX(.14em); }

/* ---- Apps page: the scroll-down cue. Vertical, lit like the logo, it
   waits past the left edge and site.js slides it out (.is-out). */

.scroll-cue {
  position: fixed;
  left: clamp(10px, 2vw, 34px);
  top: 50%;
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .4em;
  padding: 10px 6px;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: "Barlow", system-ui, sans-serif;
  font-weight: 800;
  font-size: clamp(26px, 3.2vw, 44px);
  line-height: 1;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #eaf6ff;
  filter:
    drop-shadow(0 0 3px rgba(112, 182, 227, .95))
    drop-shadow(0 0 10px rgba(112, 182, 227, .6))
    drop-shadow(0 0 24px rgba(112, 182, 227, .35));
  opacity: 0;
  visibility: hidden;
  transform: translate(-140%, -50%);
  transition: opacity .3s ease, transform .3s ease, visibility 0s linear .3s, filter .35s ease;
}

.scroll-cue.is-out {
  opacity: 1;
  visibility: visible;
  transform: translate(0, -50%);
  transition: opacity .25s ease, transform .6s cubic-bezier(.34, 1.56, .64, 1), visibility 0s, filter .35s ease;
}

/* The words run down the page, top to bottom */
.scroll-cue span { writing-mode: vertical-rl; white-space: nowrap; }

.scroll-cue svg { width: .78em; height: auto; fill: currentColor; transition: transform .45s var(--ease); }

.scroll-cue:hover,
.scroll-cue:focus-visible {
  outline: none;
  filter:
    drop-shadow(0 0 5px rgba(112, 182, 227, 1))
    drop-shadow(0 0 16px rgba(112, 182, 227, .8))
    drop-shadow(0 0 40px rgba(112, 182, 227, .5));
}
.scroll-cue:hover svg, .scroll-cue:focus-visible svg { transform: translateY(.18em); }

/* No room beside the content on narrow screens */
@media (max-width: 760px) { .scroll-cue { display: none; } }

/* ---- reveal on scroll ---------------------------------------------- */

.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .8s ease, transform .8s var(--ease);
}

.reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .status-dot, #chatWidget .chat-bubble { animation: none; }
  .header-links a:not(.btn)::after { transition: none; }
  .btn:hover { transform: none; }
  .apps-cta, .apps-cta-arrow, .apps-cta-row, .apps-cta-row.is-out { transition: none; }
  .apps-cta-row { transform: none; }
  .scroll-cue, .scroll-cue.is-out, .scroll-cue svg { transition: none; }
  .apps-cta:hover .apps-cta-arrow { transform: none; }
  .orbit a, .orbit-dot, .app-card, .app-icon { transition: none; }
  .orbit-dot::after { animation: none; display: none; }
  .mobile-nav { animation: none; transition: none; }
  .app-card.is-flown { animation: none; }
  .js-fly .app-card:not(.is-flown) { opacity: 1; }
  .strap-pulse { animation: none; display: none; }
  .job-year { animation: none; }
  .job-body, .job-body::after, .job-harness, .job-year { transition: none; }
}
