Repository: SwitchbackTech/compass (ts)

Issue:
Add `f` shortcut to edit header note
### Feature Description
As a user, when I press the `f` key, I want to start editing the header note, so that I can change it easily.

I also want to edit it from the `META` + `k` shortcut, so I can edit the header note when I forget what the shortcut is

Make it easier to edit the header note with a shortcut or command palette action.

`f` key should be used, as it's related to the work 'focus', which is used as in placeholder text for the header note. The `f` is also where the left index finger is located on US keyboards, which makes it very easy to press.

<img width="1915" alt="Image" src="https://github.com/user-attachments/assets/7b9e0d52-7dca-47e2-8964-f550164104d6" />

<img width="1706" alt="Image" src="https://github.com/user-attachments/assets/668a80b5-badc-4522-ad9c-a83dfd01aabb" />

### Use Case

This'll make it easier to edit the note frequently 

### Additional Context

Acceptance Criteria
- [ ] Tooltip renders when hovering over header note
- [ ] Shortcut works on all major browsers and operating systems
- [ ] Shortcut is added as an action to command palette.

Pull request description:
Feat(add f shortcut to edit header note)
# What Does This PR do?

This PR adds the  `f` shortcut to edit header note

## Description
Closes #420 

## Manual Test
https://github.com/user-attachments/assets/020ffe8a-6c0d-45bb-9ba7-c2679acadfb4

- [x] Tooltip renders when hovering over header note
- [x] Shortcut works on all major browsers and operating systems
- [x] Shortcut is added as an action to command palette.

Patch:
diff --git a/packages/web/src/ducks/events/selectors/view.selectors.ts b/packages/web/src/ducks/events/selectors/view.selectors.ts
index e18f2f74..07b94225 100644
--- a/packages/web/src/ducks/events/selectors/view.selectors.ts
+++ b/packages/web/src/ducks/events/selectors/view.selectors.ts
@@ -4,3 +4,6 @@ export const selectDatesInView = (state: RootState) => state.view.dates;
 export const selectIsSidebarOpen = (state: RootState) =>
   state.view.sidebar.isOpen;
 export const selectSidebarTab = (state: RootState) => state.view.sidebar.tab;
+
+export const selectHeaderNoteFocus = (state: RootState) =>
+  state.view.header.note.focus;
diff --git a/packages/web/src/ducks/events/slices/view.slice.ts b/packages/web/src/ducks/events/slices/view.slice.ts
index dc5cf46c..6c0c70fb 100644
--- a/packages/web/src/ducks/events/slices/view.slice.ts
+++ b/packages/web/src/ducks/events/slices/view.slice.ts
@@ -11,6 +11,11 @@ interface State_View {
     tab: "monthWidget" | "tasks";
     isOpen: boolean;
   };
+  header: {
+    note: {
+      focus: boolean;
+    };
+  };
 }
 
 interface Action_DatesChange extends Action {
@@ -21,12 +26,17 @@ interface Action_SidebarViewChange extends Action {
   payload: State_View["sidebar"]["tab"];
 }
 
+interface Action_FocusHeaderNoteChange extends Action {
+  payload: State_View["header"]["note"]["focus"];
+}
+
 const initialState: State_View = {
   dates: {
     start: dayjs().format(),
     end: dayjs().endOf("week").format(),
   },
   sidebar: { tab: "tasks", isOpen: true },
+  header: { note: { focus: false } },
 };
 
 export const viewSlice = createSlice({
@@ -42,6 +52,9 @@ export const viewSlice = createSlice({
     updateSidebarTab: (state, action: Action_SidebarViewChange) => {
       state.sidebar.tab = action.payload;
     },
+    focusHeaderNote: (state, action: Action_FocusHeaderNoteChange) => {
+      state.header.note.focus = action?.payload ?? !state.header.note.focus;
+    },
   },
 });
 
diff --git a/packages/web/src/views/Calendar/components/Header/Header.tsx b/packages/web/src/views/Calendar/components/Header/Header.tsx
index 8f4c3692..55618cd8 100644
--- a/packages/web/src/views/Calendar/components/Header/Header.tsx
+++ b/packages/web/src/views/Calendar/components/Header/Header.tsx
@@ -1,5 +1,5 @@
 import dayjs, { Dayjs } from "dayjs";
-import React, { FC } from "react";
+import React, { FC, useRef } from "react";
 import { theme } from "@web/common/styles/theme";
 import { getCalendarHeadingLabel } from "@web/common/utils/web.date.util";
 import { AlignItems } from "@web/components/Flex/styled";
@@ -11,6 +11,7 @@ import { viewSlice } from "@web/ducks/events/slices/view.slice";
 import { useAppDispatch, useAppSelector } from "@web/store/store.hooks";
 import { RootProps } from "../../calendarView.types";
 import { Util_Scroll } from "../../hooks/grid/useScroll";
+import { useFocusHotkey } from "../../hooks/shortcuts/useFocusHotkey";
 import { WeekProps } from "../../hooks/useWeek";
 import { TodayButton } from "../TodayButton";
 import { DayLabels } from "./DayLabels";
@@ -49,6 +50,10 @@ export const Header: FC<Props> = ({ scrollUtil, today, weekProps }) => {
     scrollToNow();
   };
 
+  const headerNoteRef = useRef<HTMLDivElement>(null);
+
+  useFocusHotkey(() => headerNoteRef.current?.focus(), [headerNoteRef]);
+
   return (
     <>
       <StyledHeaderRow alignItems={AlignItems.BASELINE}>
@@ -67,7 +72,7 @@ export const Header: FC<Props> = ({ scrollUtil, today, weekProps }) => {
             />
           </TooltipWrapper>
         </StyledLeftGroup>
-        <HeaderNote />
+        <HeaderNote ref={headerNoteRef} />
         <StyledRightGroup>
           <StyledHeaderLabel aria-level={1} role="heading">
             <Text size="xl">{headerLabel}</Text>
diff --git a/packages/web/src/views/Calendar/components/Header/HeaderNote/HeaderNote.tsx b/packages/web/src/views/Calendar/components/Header/HeaderNote/HeaderNote.tsx
index 9c5229e4..0dc0cd05 100644
--- a/packages/web/src/views/Calendar/components/Header/HeaderNote/HeaderNote.tsx
+++ b/packages/web/src/views/Calendar/components/Header/HeaderNote/HeaderNote.tsx
@@ -1,8 +1,18 @@
-import { useEffect, useRef, useState } from "react";
-import React from "react";
+import React, {
+  ForwardedRef,
+  forwardRef,
+  useEffect,
+  useImperativeHandle,
+  useRef,
+  useState,
+} from "react";
 import { STORAGE_KEYS } from "@web/common/constants/storage.constants";
 import { ID_HEADER_NOTE_INPUT } from "@web/common/constants/web.constants";
 import { theme } from "@web/common/styles/theme";
+import { TooltipWrapper } from "@web/components/Tooltip/TooltipWrapper";
+import { selectHeaderNoteFocus } from "@web/ducks/events/selectors/view.selectors";
+import { viewSlice } from "@web/ducks/events/slices/view.slice";
+import { useAppDispatch, useAppSelector } from "@web/store/store.hooks";
 import { generateHandDrawnUnderline } from "./header-note.util";
 import {
   StyledCharCounter,
@@ -21,87 +31,82 @@ type CursorPosition = {
   endOffset: number;
 };
 
-export const HeaderNote = () => {
-  const [note, setNote] = useState("");
-  const [isEditing, setIsEditing] = useState(false);
-
-  const [showUnderline, setShowUnderline] = useState(false);
-  const [showPlaceholderUnderline, setShowPlaceholderUnderline] =
-    useState(false);
-  const [underlinePath, setUnderlinePath] = useState("");
-  const [placeholderUnderlinePath, setPlaceholderUnderlinePath] = useState("");
-  const focusRef = useRef<HTMLDivElement>(null);
-  const focusWrapperRef = useRef<HTMLDivElement>(null);
-  const placeholderRef = useRef<HTMLDivElement>(null);
-  const cursorPositionRef = useRef<CursorPosition | null>(null);
-
-  // Helper functions to save and restore cursor position
-  const saveCursorPosition = () => {
-    const selection = window.getSelection();
-    if (!selection || selection.rangeCount === 0 || !focusRef.current) return;
-
-    const range = selection.getRangeAt(0);
-    if (focusRef.current.contains(range.commonAncestorContainer)) {
-      cursorPositionRef.current = {
-        startOffset: range.startOffset,
-        endOffset: range.endOffset,
-      };
-    }
-  };
-
-  const restoreCursorPosition = () => {
-    if (!cursorPositionRef.current || !focusRef.current) return;
-
-    const selection = window.getSelection();
-    if (!selection) return;
-
-    try {
-      const range = document.createRange();
-      const textNode = focusRef.current.firstChild || focusRef.current;
-
-      // Ensure offsets are within the valid range
-      const textLength = textNode.textContent?.length || 0;
-      const startOffset = Math.min(
-        cursorPositionRef.current.startOffset,
-        textLength,
-      );
-      const endOffset = Math.min(
-        cursorPositionRef.current.endOffset,
-        textLength,
-      );
-
-      range.setStart(textNode, startOffset);
-      range.setEnd(textNode, endOffset);
-
-      selection.removeAllRanges();
-      selection.addRange(range);
-    } catch (e) {
-      console.error("Failed to restore cursor position", e);
-    }
-  };
-
-  // Load from localStorage on mount
-  useEffect(() => {
-    const savedNote = localStorage.getItem(STORAGE_KEYS.HEADER_NOTE);
-    if (savedNote !== null) {
-      setNote(savedNote);
-    }
-  }, []);
-
-  // Generate underline paths when components mount or resize
-  useEffect(() => {
-    if (focusWrapperRef.current) {
-      const width = focusWrapperRef.current.offsetWidth;
-      setUnderlinePath(generateHandDrawnUnderline(width));
-    }
-
-    if (placeholderRef.current) {
-      const width = placeholderRef.current.offsetWidth;
-      setPlaceholderUnderlinePath(generateHandDrawnUnderline(width));
-    }
-
-    // Add resize listener
-    const handleResize = () => {
+export const HeaderNote = forwardRef(
+  (
+    _: unknown,
+    headerNoteRef: ForwardedRef<{ focus: HTMLDivElement["focus"] }>,
+  ) => {
+    const focusHeaderNote = useAppSelector(selectHeaderNoteFocus);
+    const dispatch = useAppDispatch();
+    const [note, setNote] = useState("");
+    const [isEditing, setIsEditing] = useState(false);
+
+    const [showUnderline, setShowUnderline] = useState(false);
+    const [showPlaceholderUnderline, setShowPlaceholderUnderline] =
+      useState(false);
+    const [underlinePath, setUnderlinePath] = useState("");
+    const [placeholderUnderlinePath, setPlaceholderUnderlinePath] =
+      useState("");
+    const focusRef = useRef<HTMLDivElement>(null);
+    const focusWrapperRef = useRef<HTMLDivElement>(null);
+    const placeholderRef = useRef<HTMLDivElement>(null);
+    const cursorPositionRef = useRef<CursorPosition | null>(null);
+
+    // Helper functions to save and restore cursor position
+    const saveCursorPosition = () => {
+      const selection = window.getSelection();
+      if (!selection || selection.rangeCount === 0 || !focusRef.current) return;
+
+      const range = selection.getRangeAt(0);
+      if (focusRef.current.contains(range.commonAncestorContainer)) {
+        cursorPositionRef.current = {
+          startOffset: range.startOffset,
+          endOffset: range.endOffset,
+        };
+      }
+    };
+
+    const restoreCursorPosition = () => {
+      if (!cursorPositionRef.current || !focusRef.current) return;
+
+      const selection = window.getSelection();
+      if (!selection) return;
+
+      try {
+        const range = document.createRange();
+        const textNode = focusRef.current.firstChild || focusRef.current;
+
+        // Ensure offsets are within the valid range
+        const textLength = textNode.textContent?.length || 0;
+        const startOffset = Math.min(
+          cursorPositionRef.current.startOffset,
+          textLength,
+        );
+        const endOffset = Math.min(
+          cursorPositionRef.current.endOffset,
+          textLength,
+        );
+
+        range.setStart(textNode, startOffset);
+        range.setEnd(textNode, endOffset);
+
+        selection.removeAllRanges();
+        selection.addRange(range);
+      } catch (e) {
+        console.error("Failed to restore cursor position", e);
+      }
+    };
+
+    // Load from localStorage on mount
+    useEffect(() => {
+      const savedNote = localStorage.getItem(STORAGE_KEYS.HEADER_NOTE);
+      if (savedNote !== null) {
+        setNote(savedNote);
+      }
+    }, []);
+
+    // Generate underline paths when components mount or resize
+    useEffect(() => {
       if (focusWrapperRef.current) {
         const width = focusWrapperRef.current.offsetWidth;
         setUnderlinePath(generateHandDrawnUnderline(width));
@@ -111,250 +116,291 @@ export const HeaderNote = () => {
         const width = placeholderRef.current.offsetWidth;
         setPlaceholderUnderlinePath(generateHandDrawnUnderline(width));
       }
+
+      // Add resize listener
+      const handleResize = () => {
+        if (focusWrapperRef.current) {
+          const width = focusWrapperRef.current.offsetWidth;
+          setUnderlinePath(generateHandDrawnUnderline(width));
+        }
+
+        if (placeholderRef.current) {
+          const width = placeholderRef.current.offsetWidth;
+          setPlaceholderUnderlinePath(generateHandDrawnUnderline(width));
+        }
+      };
+
+      window.addEventListener("resize", handleResize);
+      return () => window.removeEventListener("resize", handleResize);
+    }, [note, isEditing]);
+
+    // Regenerate underline on hover for a dynamic effect
+    const handleMouseEnter = () => {
+      if (focusWrapperRef.current) {
+        const width = focusWrapperRef.current.offsetWidth;
+        setUnderlinePath(generateHandDrawnUnderline(width));
+        setShowUnderline(true);
+      }
     };
 
-    window.addEventListener("resize", handleResize);
-    return () => window.removeEventListener("resize", handleResize);
-  }, [note, isEditing]);
-
-  // Regenerate underline on hover for a dynamic effect
-  const handleMouseEnter = () => {
-    if (focusWrapperRef.current) {
-      const width = focusWrapperRef.current.offsetWidth;
-      setUnderlinePath(generateHandDrawnUnderline(width));
-      setShowUnderline(true);
-    }
-  };
-
-  const handlePlaceholderMouseEnter = () => {
-    if (placeholderRef.current) {
-      const width = placeholderRef.current.offsetWidth;
-      setPlaceholderUnderlinePath(generateHandDrawnUnderline(width));
-      setShowPlaceholderUnderline(true);
-    }
-  };
-
-  // Effect for initial focus when editing starts
-  useEffect(() => {
-    if (isEditing && focusRef.current) {
-      // Only set content when first entering edit mode
-      if (focusRef.current.textContent !== note) {
-        focusRef.current.textContent = note;
+    const handlePlaceholderMouseEnter = () => {
+      if (placeholderRef.current) {
+        const width = placeholderRef.current.offsetWidth;
+        setPlaceholderUnderlinePath(generateHandDrawnUnderline(width));
+        setShowPlaceholderUnderline(true);
       }
-      focusRef.current.focus();
+    };
 
-      // Only place cursor at the end when first entering edit mode
-      if (!cursorPositionRef.current) {
-        const range = document.createRange();
-        const sel = window.getSelection();
-        range.selectNodeContents(focusRef.current);
-        range.collapse(false);
-        sel?.removeAllRanges();
-        sel?.addRange(range);
-      } else {
-        // Restore previously saved cursor position
-        restoreCursorPosition();
+    // Effect for initial focus when editing starts
+    useEffect(() => {
+      if (isEditing && focusRef.current) {
+        // Only set content when first entering edit mode
+        if (focusRef.current.textContent !== note) {
+          focusRef.current.textContent = note;
+        }
+        focusRef.current.focus();
+
+        // Only place cursor at the end when first entering edit mode
+        if (!cursorPositionRef.current) {
+          const range = document.createRange();
+          const sel = window.getSelection();
+          range.selectNodeContents(focusRef.current);
+          range.collapse(false);
+          sel?.removeAllRanges();
+          sel?.addRange(range);
+        } else {
+          // Restore previously saved cursor position
+          restoreCursorPosition();
+        }
       }
-    }
-  }, [isEditing]);
-
-  // Effect to sync note content after state updates
-  useEffect(() => {
-    if (
-      isEditing &&
-      focusRef.current &&
-      focusRef.current.textContent !== note
-    ) {
-      // Remember cursor position
-      saveCursorPosition();
+    }, [isEditing]);
+
+    // Effect to sync note content after state updates
+    useEffect(() => {
+      if (
+        isEditing &&
+        focusRef.current &&
+        focusRef.current.textContent !== note
+      ) {
+        // Remember cursor position
+        saveCursorPosition();
+
+        // Update text content only if it's different
+        if (focusRef.current.textContent !== note) {
+          focusRef.current.textContent = note;
+        }
 
-      // Update text content only if it's different
-      if (focusRef.current.textContent !== note) {
-        focusRef.current.textContent = note;
+        // Restore cursor position
+        setTimeout(restoreCursorPosition, 0);
       }
+    }, [note, isEditing]);
+
+    // Effect to handle ESC key
+    useEffect(() => {
+      const handleEscKey = (e: KeyboardEvent) => {
+        if (e.key === "Escape" && isEditing) {
+          setIsEditing(false);
+          // Save to localStorage on ESC
+          if (focusRef.current) {
+            const value = focusRef.current.textContent || "";
+            setNote(value);
+            localStorage.setItem(STORAGE_KEYS.HEADER_NOTE, value);
+          }
+        }
+      };
 
-      // Restore cursor position
-      setTimeout(restoreCursorPosition, 0);
-    }
-  }, [note, isEditing]);
+      window.addEventListener("keydown", handleEscKey);
+      return () => {
+        window.removeEventListener("keydown", handleEscKey);
+      };
+    }, [isEditing]);
 
-  // Effect to handle ESC key
-  useEffect(() => {
-    const handleEscKey = (e: KeyboardEvent) => {
-      if (e.key === "Escape" && isEditing) {
-        setIsEditing(false);
-        // Save to localStorage on ESC
-        if (focusRef.current) {
-          const value = focusRef.current.textContent || "";
-          setNote(value);
-          localStorage.setItem(STORAGE_KEYS.HEADER_NOTE, value);
-        }
+    const handleNoteClick = () => {
+      cursorPositionRef.current = null; // Reset cursor position
+      setIsEditing(true);
+    };
+
+    useImperativeHandle(headerNoteRef, () => ({ focus: handleNoteClick }), [
+      handleNoteClick,
+    ]);
+
+    useEffect(() => {
+      if (focusHeaderNote) handleNoteClick();
+
+      dispatch(viewSlice.actions.focusHeaderNote(false));
+    }, [focusHeaderNote]);
+
+    const handleNoteBlur = () => {
+      setIsEditing(false);
+      // Save to localStorage on blur
+      if (focusRef.current) {
+        const value = focusRef.current.textContent || "";
+        setNote(value);
+        localStorage.setItem(STORAGE_KEYS.HEADER_NOTE, value);
       }
     };
 
-    window.addEventListener("keydown", handleEscKey);
-    return () => {
-      window.removeEventListener("keydown", handleEscKey);
+    const handleNoteKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
+      if (e.key === "Enter") {
+        e.preventDefault();
+        setIsEditing(false);
+        // Save to localStorage on ENTER
+        const latestValue = e.currentTarget.textContent || "";
+        setNote(latestValue);
+        localStorage.setItem(STORAGE_KEYS.HEADER_NOTE, latestValue);
+      }
     };
-  }, [isEditing]);
-
-  const handleNoteClick = () => {
-    cursorPositionRef.current = null; // Reset cursor position
-    setIsEditing(true);
-  };
-
-  const handleNoteBlur = () => {
-    setIsEditing(false);
-    // Save to localStorage on blur
-    if (focusRef.current) {
-      const value = focusRef.current.textContent || "";
-      setNote(value);
-      localStorage.setItem(STORAGE_KEYS.HEADER_NOTE, value);
-    }
-  };
-
-  const handleNoteKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
-    if (e.key === "Enter") {
-      e.preventDefault();
-      setIsEditing(false);
-      // Save to localStorage on ENTER
-      const latestValue = e.currentTarget.textContent || "";
-      setNote(latestValue);
-      localStorage.setItem(STORAGE_KEYS.HEADER_NOTE, latestValue);
-    }
-  };
-
-  const handleNoteChange = (e: React.FormEvent<HTMLDivElement>) => {
-    const newText = e.currentTarget.textContent || "";
-
-    // Save cursor position before updating state
-    saveCursorPosition();
-
-    // Limit text length
-    if (newText.length <= MAX_NOTE_CHARS) {
-      setNote(newText);
-    } else {
-      // If text is too long, truncate it and update the DOM element
-      const truncated = newText.substring(0, MAX_NOTE_CHARS);
-      setNote(truncated);
-
-      // Only manually update DOM and cursor if truncation happened
-      if (newText !== truncated) {
-        e.currentTarget.textContent = truncated;
-
-        // Place cursor at the end after truncating
-        const range = document.createRange();
-        const sel = window.getSelection();
-        if (sel) {
-          range.selectNodeContents(e.currentTarget);
-          range.collapse(false);
-          sel.removeAllRanges();
-          sel.addRange(range);
-
-          // Update saved cursor position
-          cursorPositionRef.current = {
-            startOffset: truncated.length,
-            endOffset: truncated.length,
-          };
+
+    const handleNoteChange = (e: React.FormEvent<HTMLDivElement>) => {
+      const newText = e.currentTarget.textContent || "";
+
+      // Save cursor position before updating state
+      saveCursorPosition();
+
+      // Limit text length
+      if (newText.length <= MAX_NOTE_CHARS) {
+        setNote(newText);
+      } else {
+        // If text is too long, truncate it and update the DOM element
+        const truncated = newText.substring(0, MAX_NOTE_CHARS);
+        setNote(truncated);
+
+        // Only manually update DOM and cursor if truncation happened
+        if (newText !== truncated) {
+          e.currentTarget.textContent = truncated;
+
+          // Place cursor at the end after truncating
+          const range = document.createRange();
+          const sel = window.getSelection();
+          if (sel) {
+            range.selectNodeContents(e.currentTarget);
+            range.collapse(false);
+            sel.removeAllRanges();
+            sel.addRange(range);
+
+            // Update saved cursor position
+            cursorPositionRef.current = {
+              startOffset: truncated.length,
+              endOffset: truncated.length,
+            };
+          }
         }
       }
-    }
-  };
-
-  return (
-    <StyledNoteContainer>
-      {isEditing ? (
-        <>
-          <StyledNoteWrapper ref={focusWrapperRef}>
-            <StyledNoteText
-              id={ID_HEADER_NOTE_INPUT}
-              ref={focusRef}
-              contentEditable
-              suppressContentEditableWarning
-              isEditing={true}
-              textLength={note.length}
-              onBlur={handleNoteBlur}
-              onKeyDown={handleNoteKeyDown}
-              onInput={handleNoteChange}
-            />
-          </StyledNoteWrapper>
-          <StyledCharCounter isNearLimit={note.length > MAX_NOTE_CHARS * 0.8}>
-            {note.length}/{MAX_NOTE_CHARS}
-          </StyledCharCounter>
-        </>
-      ) : note ? (
-        <StyledNoteWrapper
-          ref={focusWrapperRef}
-          onMouseEnter={handleMouseEnter}
-          onMouseLeave={() => setShowUnderline(false)}
-        >
-          <StyledNoteText
-            isEditing={false}
-            textLength={note.length}
-            onClick={handleNoteClick}
+    };
+
+    return (
+      <StyledNoteContainer>
+        {isEditing ? (
+          <>
+            <StyledNoteWrapper ref={focusWrapperRef}>
+              <StyledNoteText
+                id={ID_HEADER_NOTE_INPUT}
+                ref={focusRef}
+                contentEditable
+                suppressContentEditableWarning
+                isEditing={true}
+                textLength={note.length}
+                onBlur={handleNoteBlur}
+                onKeyDown={handleNoteKeyDown}
+                onInput={handleNoteChange}
+              />
+            </StyledNoteWrapper>
+            <StyledCharCounter isNearLimit={note.length > MAX_NOTE_CHARS * 0.8}>
+              {note.length}/{MAX_NOTE_CHARS}
+            </StyledCharCounter>
+          </>
+        ) : note ? (
+          <TooltipWrapper
+            description="Edit Focus Note"
+            onClick={() => {}}
+            shortcut="F"
           >
-            {note}
-          </StyledNoteText>
-          <StyledUnderline isVisible={showUnderline} preserveAspectRatio="none">
-            <defs>
-              <linearGradient
-                id="underlineGradient"
-                x1="0%"
-                y1="0%"
-                x2="100%"
-                y2="0%"
+            <StyledNoteWrapper
+              ref={focusWrapperRef}
+              onMouseEnter={handleMouseEnter}
+              onMouseLeave={() => setShowUnderline(false)}
+            >
+              <StyledNoteText
+                isEditing={false}
+                textLength={note.length}
+                onClick={handleNoteClick}
+                className="header-note-text"
               >
-                <stop
-                  offset="0%"
-                  stopColor={theme.color.gradient.accentLight.start}
-                />
-                <stop
-                  offset="100%"
-                  stopColor={theme.color.gradient.accentLight.end}
-                />
-              </linearGradient>
-            </defs>
-            <path d={underlinePath} stroke="url(#underlineGradient)" />
-          </StyledUnderline>
-        </StyledNoteWrapper>
-      ) : (
-        <StyledNoteWrapper
-          ref={placeholderRef}
-          onMouseEnter={handlePlaceholderMouseEnter}
-          onMouseLeave={() => setShowPlaceholderUnderline(false)}
-        >
-          <StyledNotePlaceholder onClick={handleNoteClick}>
-            Click to add your focus
-          </StyledNotePlaceholder>
-          <StyledPlaceholderUnderline
-            isVisible={showPlaceholderUnderline}
-            preserveAspectRatio="none"
+                {note}
+              </StyledNoteText>
+              <StyledUnderline
+                isVisible={showUnderline}
+                preserveAspectRatio="none"
+              >
+                <defs>
+                  <linearGradient
+                    id="underlineGradient"
+                    x1="0%"
+                    y1="0%"
+                    x2="100%"
+                    y2="0%"
+                  >
+                    <stop
+                      offset="0%"
+                      stopColor={theme.color.gradient.accentLight.start}
+                    />
+                    <stop
+                      offset="100%"
+                      stopColor={theme.color.gradient.accentLight.end}
+                    />
+                  </linearGradient>
+                </defs>
+                <path d={underlinePath} stroke="url(#underlineGradient)" />
+              </StyledUnderline>
+            </StyledNoteWrapper>
+          </TooltipWrapper>
+        ) : (
+          <TooltipWrapper
+            description="Edit Focus Note"
+            onClick={() => {}}
+            shortcut="F"
           >
-            <defs>
-              <linearGradient
-                id="placeholderUnderlineGradient"
-                x1="0%"
-                y1="0%"
-                x2="100%"
-                y2="0%"
+            <StyledNoteWrapper
+              ref={placeholderRef}
+              onMouseEnter={handlePlaceholderMouseEnter}
+              onMouseLeave={() => setShowPlaceholderUnderline(false)}
+            >
+              <StyledNotePlaceholder onClick={handleNoteClick}>
+                Click to add your focus
+              </StyledNotePlaceholder>
+              <StyledPlaceholderUnderline
+                isVisible={showPlaceholderUnderline}
+                preserveAspectRatio="none"
               >
-                <stop
-                  offset="0%"
-                  stopColor={theme.color.gradient.accentLight.start}
-                />
-                <stop
-                  offset="100%"
-                  stopColor={theme.color.gradient.accentLight.end}
+                <defs>
+                  <linearGradient
+                    id="placeholderUnderlineGradient"
+                    x1="0%"
+                    y1="0%"
+                    x2="100%"
+                    y2="0%"
+                  >
+                    <stop
+                      offset="0%"
+                      stopColor={theme.color.gradient.accentLight.start}
+                    />
+                    <stop
+                      offset="100%"
+                      stopColor={theme.color.gradient.accentLight.end}
+                    />
+                  </linearGradient>
+                </defs>
+                <path
+                  d={placeholderUnderlinePath}
+                  stroke="url(#placeholderUnderlineGradient)"
                 />
-              </linearGradient>
-            </defs>
-            <path
-              d={placeholderUnderlinePath}
-              stroke="url(#placeholderUnderlineGradient)"
-            />
-          </StyledPlaceholderUnderline>
-        </StyledNoteWrapper>
-      )}
-    </StyledNoteContainer>
-  );
-};
+              </StyledPlaceholderUnderline>
+            </StyledNoteWrapper>
+          </TooltipWrapper>
+        )}
+      </StyledNoteContainer>
+    );
+  },
+);
+
+HeaderNote.displayName = "HeaderNote";
diff --git a/packages/web/src/views/Calendar/hooks/shortcuts/useFocusHotkey.ts b/packages/web/src/views/Calendar/hooks/shortcuts/useFocusHotkey.ts
new file mode 100644
index 00000000..85231f6f
--- /dev/null
+++ b/packages/web/src/views/Calendar/hooks/shortcuts/useFocusHotkey.ts
@@ -0,0 +1,12 @@
+import { useHotkeys } from "react-hotkeys-hook";
+
+export const useFocusHotkey = (
+  callback: () => void,
+  dependencies: unknown[] = [],
+) =>
+  useHotkeys(
+    "F",
+    callback,
+    { description: "focus", preventDefault: true },
+    dependencies,
+  );
diff --git a/packages/web/src/views/CmdPalette/CmdPalette.tsx b/packages/web/src/views/CmdPalette/CmdPalette.tsx
index 8725dec3..530e3437 100644
--- a/packages/web/src/views/CmdPalette/CmdPalette.tsx
+++ b/packages/web/src/views/CmdPalette/CmdPalette.tsx
@@ -13,8 +13,10 @@ import {
 import { Categories_Event } from "@core/types/event.types";
 import { ROOT_ROUTES } from "@web/common/constants/routes";
 import { isEventFormOpen } from "@web/common/utils";
-import { createAlldayDraft } from "@web/common/utils/draft/draft.util";
-import { createTimedDraft } from "@web/common/utils/draft/draft.util";
+import {
+  createAlldayDraft,
+  createTimedDraft,
+} from "@web/common/utils/draft/draft.util";
 import { createSomedayDraft } from "@web/common/utils/draft/someday.draft.util";
 import { onEventTargetVisibility } from "@web/common/utils/event-target-visibility.util";
 import {
@@ -22,6 +24,7 @@ import {
   selectIsAtWeeklyLimit,
 } from "@web/ducks/events/selectors/someday.selectors";
 import { draftSlice } from "@web/ducks/events/slices/draft.slice";
+import { viewSlice } from "@web/ducks/events/slices/view.slice";
 import { selectIsCmdPaletteOpen } from "@web/ducks/settings/selectors/settings.selectors";
 import { settingsSlice } from "@web/ducks/settings/slices/settings.slice";
 import { useAppDispatch, useAppSelector } from "@web/store/store.hooks";
@@ -127,6 +130,14 @@ const CmdPalette = ({
               handleCreateSomedayDraft(Categories_Event.SOMEDAY_MONTH),
             ),
           },
+          {
+            id: "edit-focus-note",
+            children: `Edit Focus Note [f]`,
+            icon: "PencilSquareIcon",
+            onClick: onEventTargetVisibility(() =>
+              dispatch(viewSlice.actions.focusHeaderNote(true)),
+            ),
+          },
           {
             id: "today",
             children: `Go to Today (${today.format("dddd, MMMM D")}) [t]`,


Test patch:
diff --git a/packages/web/src/__tests__/__mocks__/state/state.weekEvents.ts b/packages/web/src/__tests__/__mocks__/state/state.weekEvents.ts
index 3284c33f..1eaca767 100644
--- a/packages/web/src/__tests__/__mocks__/state/state.weekEvents.ts
+++ b/packages/web/src/__tests__/__mocks__/state/state.weekEvents.ts
@@ -68,5 +68,10 @@ export const preloadedState: InitialReduxState = {
       tab: "tasks",
       isOpen: true,
     },
+    header: {
+      note: {
+        focus: false,
+      },
+    },
   },
 };
diff --git a/packages/web/src/views/Calendar/Calendar.form.test.tsx b/packages/web/src/views/Calendar/Calendar.form.test.tsx
index 5783a2b7..052f86d0 100644
--- a/packages/web/src/views/Calendar/Calendar.form.test.tsx
+++ b/packages/web/src/views/Calendar/Calendar.form.test.tsx
@@ -76,4 +76,40 @@ describe("Event Form", () => {
       );
     });
   });
+
+  describe("HeaderNote", () => {
+    it("it should be focused when the 'f' keyboard shortcut is used", async () => {
+      const { container } = render(<CalendarView />, { state: preloadedState });
+
+      const focusNotePlaceholder = screen.getByText("Click to add your focus");
+
+      expect(focusNotePlaceholder).toBeInTheDocument();
+
+      await act(async () => userEvent.keyboard("f"));
+
+      const focusNoteInput = container.querySelector('[id="headerNoteInput"]');
+
+      expect(focusNoteInput).toHaveFocus();
+    });
+
+    it.skip("it should be focused when the 'edit focus' btn is clicked in the command palette", async () => {
+      const { container } = render(<CalendarView />, { state: preloadedState });
+
+      const focusNotePlaceholder = screen.getByText("Click to add your focus");
+
+      expect(focusNotePlaceholder).toBeInTheDocument();
+
+      await act(async () => userEvent.keyboard("{Meta>}k{/Meta}"));
+
+      const cmdPaletteEditBtn = screen.getByText("Edit Focus Note [f]");
+
+      expect(cmdPaletteEditBtn).toBeInTheDocument();
+
+      await act(async () => userEvent.click(cmdPaletteEditBtn!));
+
+      const focusNoteInput = container.querySelector('[id="headerNoteInput"]');
+
+      expect(focusNoteInput).toHaveFocus();
+    });
+  });
 });