Can I use @Input and @Output on my tab pages?

I think that would be a perfect fit. Sample code for this idiom is here.

Yes. Depending on how much other stuff is going on, you could split it into a separate service or even just let them live together in one. You would just add something like so wherever you choose to do it:

export interface Skill {
  id: string;
  name: string;
  category: string;
  apparatus: Apparatus;
  favored?: boolean;
}
 
export interface Routine {
  skills: Skill[];
  // maybe other stuff here
}

class RoutineService {
  private routine$ = new BehaviorSubject<Routine | null>(null);
  watchRoutine(): Observable<Routine | null> {
    return this.routine$;
  }
  addToRoutine(skill: Skill): void {
    let nr: Routine = cloneDeep(this.routine$.value) || {skills: []};
    nr.skills.push(skill);
    this.routine$.next(nr);
  }
}

cloneDeep comes from lodash - it’s not strictly necessary, and you could do something similar with Object.assign or probably several other libraries like immutable.js (which I’ve never used). The point of it is to avoid any unwanted aliasing - if some other part of the app is holding on to a reference to a Routine or its array of Skills, it can be disconcerting and very hard to track/diagnose what happens when things magically change out from under it. This has historically also been a point of easy confusion for Angular’s change detection, so unless it’s burdensomely heavy to do so, I have simply gotten in the habit of defaulting my business-level objects to immutable and cloning them before modifying their internals.