Last active
June 16, 2025 06:26
-
-
Save foeken/cd809018e6caf846d174f656bb30109c to your computer and use it in GitHub Desktop.
Tana CSS (mar16)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/zsh | |
# Required parameters: | |
# @raycast.schemaVersion 1 | |
# @raycast.title Tana Custom CSS Patch | |
# @raycast.mode compact | |
# Optional parameters: | |
# @raycast.icon 🚧 | |
# @raycast.packageName Tana | |
# Documentation: | |
# @raycast.author dreetje | |
# @raycast.authorURL https://raycast.com/dreetje | |
# @raycast.description Patches Tana app by embedding custom CSS directly | |
# ============================================================================ | |
# CONFIGURATION - Edit these values to customize the CSS injection | |
# ============================================================================ | |
# Option 1: Use CSS from a URL (set USE_INLINE_CSS=false) | |
CSS_URL="https://gist.githubusercontent.com/foeken/cd809018e6caf846d174f656bb30109c/raw/313e673744ad85205351ce0d6a32a75d14f27120/tana.css" | |
# Option 2: Use inline CSS (set USE_INLINE_CSS=true and paste your CSS below) | |
USE_INLINE_CSS=false | |
# Paste your CSS here (between the quotes) if using inline CSS: | |
INLINE_CSS=' | |
/* Example CSS - replace with your own */ | |
body { | |
font-family: '\''IBM Plex Sans'\''; | |
-webkit-font-smoothing: subpixel-antialiased; | |
font-size: 14.5px !important; | |
} | |
' | |
# ============================================================================ | |
# SCRIPT LOGIC - Do not modify below this line unless you know what you're doing | |
# ============================================================================ | |
TANA_PRELOAD_PATH="/Applications/Tana.app/Contents/Resources/app/build/preload.js" | |
# Check if Tana app exists | |
if [ ! -f "$TANA_PRELOAD_PATH" ]; then | |
echo "Tana app not found" | |
exit 1 | |
fi | |
# Check if already patched and handle re-patching | |
if grep -q "TANA_CUSTOM_CSS_INJECTED" "$TANA_PRELOAD_PATH"; then | |
# Check if backup exists | |
if [ ! -f "$TANA_PRELOAD_PATH.backup" ]; then | |
echo "No backup found - cannot safely update" | |
exit 1 | |
fi | |
# Restore from backup first | |
cp "$TANA_PRELOAD_PATH.backup" "$TANA_PRELOAD_PATH" | |
fi | |
# Get CSS content based on configuration | |
if [ "$USE_INLINE_CSS" = true ]; then | |
CSS_CONTENT="$INLINE_CSS" | |
CSS_SOURCE="inline CSS from script" | |
else | |
# Download CSS with proper error handling | |
HTTP_RESPONSE=$(curl -s -w "HTTPSTATUS:%{http_code}" "$CSS_URL") | |
HTTP_STATUS=$(echo "$HTTP_RESPONSE" | tr -d '\n' | sed -E 's/.*HTTPSTATUS:([0-9]{3})$/\1/') | |
CSS_CONTENT=$(echo "$HTTP_RESPONSE" | sed -E 's/HTTPSTATUS:[0-9]{3}$//') | |
# Check for HTTP errors or empty content | |
if [ "$HTTP_STATUS" -lt 200 ] || [ "$HTTP_STATUS" -ge 300 ] || [ -z "$CSS_CONTENT" ]; then | |
echo "Failed to download CSS" | |
exit 1 | |
fi | |
CSS_SOURCE="$CSS_URL" | |
fi | |
# Create a backup (only if one doesn't exist) | |
if [ ! -f "$TANA_PRELOAD_PATH.backup" ]; then | |
cp "$TANA_PRELOAD_PATH" "$TANA_PRELOAD_PATH.backup" | |
fi | |
# Escape the CSS content for JavaScript string | |
CSS_ESCAPED=$(echo "$CSS_CONTENT" | sed 's/\\/\\\\/g' | sed "s/'/\\\\'/g" | sed 's/"/\\"/g' | tr '\n' ' ') | |
# The code to inject with embedded CSS | |
INJECTION_CODE=" | |
// TANA_CUSTOM_CSS_INJECTED - DO NOT REMOVE THIS MARKER | |
document.onreadystatechange = async (event) => { | |
if (document.readyState == \"complete\") { | |
try { | |
const css = \`$CSS_ESCAPED\`; | |
var styleSheet = document.createElement(\"style\"); | |
styleSheet.innerText = css; | |
document.head.appendChild(styleSheet); | |
console.log('Tana custom CSS applied successfully'); | |
} catch (err) { | |
console.error('Failed to apply custom CSS:', err); | |
} | |
} | |
};" | |
# Add the code to the end of the file | |
echo "$INJECTION_CODE" >> "$TANA_PRELOAD_PATH" | |
# Check if Tana is running and quit it | |
if pgrep -f "Tana" > /dev/null; then | |
osascript -e 'tell application "Tana" to quit' | |
sleep 1 | |
fi | |
# Start Tana again | |
open -a "Tana" | |
echo "Custom CSS applied successfully" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Create a draggable region at the top of the window */ | |
body::before { | |
content: ''; | |
position: fixed; | |
top: 0; | |
left: 0; | |
right: 0; | |
height: 15px; | |
-webkit-app-region: drag; | |
z-index: 1000; | |
pointer-events: none; | |
} | |
body { | |
font-family: 'IBM Plex Sans'; | |
-webkit-font-smoothing: subpixel-antialiased; | |
font-size: 14.5px !important; | |
} | |
/*img.inlineavatar { | |
margin-right: 0.1em; | |
}*/ | |
mark { | |
background-color: hsla(51, 98%, 81%, .69); | |
} | |
/* Hide related content if it's a search node that returns no results */ | |
/* | |
div[class*="WidgetPanel-module_container"]:has( | |
div[class*="Message-module_subtle"][class*="Message-module_smaller"] | |
) { | |
display: none !important; | |
}*/ | |
/* progress bars */ | |
div[style*="background-color: rgb(76, 175, 80)"] { | |
background-color: var(--templateColor) !important; | |
opacity: 0.5; | |
} | |
div[style*="background-color: var(--colorUIStroke)"] { | |
opacity: 0.5; | |
} | |
/* Brighten colors of icons when selected in picker to combat for blue background */ | |
div[data-selected] img { | |
filter: brightness(200%); | |
} | |
/* Grayscale and Hide icons in sidebar */ | |
.UnifiedSidebar-module_main__vPzV5 .NodeAsDrilldownElement-module_icon__tpAP0 { | |
filter: grayscale(100%) brightness(70%); | |
display: none; | |
} | |
/* Reduce colors of dates, icons, and links in checked todos */ | |
.itemdone-checkbox .inlineelement.inlinerefnode, .itemdone-checkbox .inlineelement.inlinerefdate, .itemdone-checkbox a { | |
filter: grayscale(70%); | |
} | |
/* Darken icons on hover (same as text) */ | |
.inlinecontent.hastemplate:hover .inlineavatar{ | |
filter: brightness(70%); | |
} | |
/* Quotes and block-quotes */ | |
:has(span[data-tag="quote"]):not(.expandedNodeContent) > .listContentItem, | |
:has(span[data-tag="block-quote"]):not(.expandedNodeContent) > .listContentItem { | |
background-color: var(--colorReferenceMentionBackground); | |
border-left: 5px solid var(--colorUIStroke); | |
border-left-width: 3px; | |
border-radius: 3px; | |
padding: 8px 14px; | |
} | |
/* New Zettel */ | |
.NodeAsListElement-module_main__kwj8T .listContentItem:has(span[data-tag="literature-note"]) { | |
margin-bottom: 3px; | |
} | |
.listContentItem:has(span[data-tag="literature-note"]) { | |
color: #5f2552a1; | |
font-style: italic; | |
} | |
:has(span[data-tag="literature-note"]):not(.expandedNodeContent) > .listContentItem { | |
background-color: #f4ebf373; | |
border-left: 5px solid #b2459aa1; | |
border-left-width: 3px; | |
border-radius: 3px; | |
padding: 8px 14px; | |
} | |
.isDarkMode :has(span[data-tag="literature-note"]):not(.expandedNodeContent) > .listContentItem { | |
background-color: #38173087; | |
color: #c772b4d6; | |
border-left: 5px solid #722e6382; | |
} | |
div[data-panel-content="true"] .listContentItem:has(span[data-tag="missing-zettel"]) .editable { | |
color: #D78B37 !important; | |
} | |
div[data-panel-content="true"] .listContentItem:has(span[data-tag="zettel"]) .editable { | |
color: #58814F !important; | |
} | |
/* Sections */ | |
.listContentItem:has(span[data-tag="highlights-section"]) .editable { | |
background-color: #F2BD1D !important; | |
} | |
.listContentItem:has(span[data-tag="zettel-section"]) .editable { | |
background-color: #8D6343 !important; | |
} | |
.listContentItem:has(span[data-tag="nedap-section"]) .editable { | |
background-color: #12537A !important; | |
} | |
.listContentItem:has(span[data-tag="work-section"]) .editable { | |
background-color: #12537A !important; | |
} | |
.listContentItem:has(span[data-tag="journal-section"]) .editable { | |
background-color: #73A867 !important; | |
} | |
.listContentItem:has(span[data-tag="中文-section"]) .editable { | |
background-color: #FEA443 !important; | |
} | |
.listContentItem:has(span[data-tag="metrics-section"]) .editable { | |
background-color: #565656 !important; | |
} | |
.listContentItem:has(span[data-tag="spotlight-section"]) .editable { | |
background-color: #FEA443 !important; | |
} | |
div[data-tag-name="spotlight-section"] .OutlinerItem-module_typeWrapper__ai0zS { | |
display: none; | |
} | |
.listContentItem:has(span[data-tag="personal-section"]) .editable { | |
background-color: #1E86C7 !important; | |
} | |
.listContentItem:has(span[data-tag="inbox-section-old"]) .editable { | |
background-color: #D95F69 !important; | |
} | |
.listContentItem:has(span[data-tag="literature-notes"]) .editable { | |
background-color: #8F3B7B !important; | |
} | |
.listContentItem:has(span[data-tag="fleeting-notes"]) .editable { | |
background-color: #DB86C7 !important; | |
} | |
.listContentItem:has(span[data-tag="zettel-notes"]) .editable { | |
background-color: #73A867 !important; | |
} | |
.listContentItem:has(span[data-tag="scratchpad-section"]) .editable { | |
background-color: #565656 !important; | |
} | |
.listContentItem:has(span[data-tag="highlights-section"]) .editable, | |
.listContentItem:has(span[data-tag="zettel-section"]) .editable, | |
.listContentItem:has(span[data-tag="nedap-section"]) .editable, | |
.listContentItem:has(span[data-tag="work-section"]) .editable, | |
.listContentItem:has(span[data-tag="journal-section"]) .editable, | |
.listContentItem:has(span[data-tag="中文-section"]) .editable, | |
.listContentItem:has(span[data-tag="spotlight-section"]) .editable, | |
.listContentItem:has(span[data-tag="personal-section"]) .editable, | |
.listContentItem:has(span[data-tag="inbox-section-old"]) .editable, | |
.listContentItem:has(span[data-tag="scratchpad-section"]) .editable, | |
.listContentItem:has(span[data-tag="metrics-section"]) .editable, | |
.listContentItem:has(span[data-tag="literature-notes"]) .editable, | |
.listContentItem:has(span[data-tag="zettel-notes"]) .editable, | |
.listContentItem:has(span[data-tag="fleeting-notes"]) .editable { | |
padding: 3px 7px; | |
line-height: 1.8em; | |
border-radius: 3px; | |
color: white; | |
border: none; | |
margin-right: 2px; | |
} | |
.listContentItem:has(span[data-tag="highlights-section"]) .inlineelement, | |
.listContentItem:has(span[data-tag="zettel-section"]) .inlineelement, | |
.listContentItem:has(span[data-tag="personal-section"]) .inlineelement, | |
.listContentItem:has(span[data-tag="journal-section"]) .inlineelement, | |
.listContentItem:has(span[data-tag="inbox-section-old"]) .inlineelement, | |
.listContentItem:has(span[data-tag="scratchpad-section"]) .inlineelement, | |
.listContentItem:has(span[data-tag="metrics-section"]) .inlineelement, | |
.listContentItem:has(span[data-tag="中文-section"]) .inlineelement, | |
.listContentItem:has(span[data-tag="spotlight-section"]) .inlineelement, | |
.listContentItem:has(span[data-tag="work-section"]) .inlineelement, | |
.listContentItem:has(span[data-tag="nedap-section"]) .inlineelement { | |
background: inherit !important; | |
color: white; | |
border: none; | |
} | |
/* Low opacity tags */ | |
.listContentItem span[data-tag="zettel"], | |
.listContentItem span[data-tag="missing"], | |
.listContentItem span[data-tag="highlights-section"], | |
.listContentItem span[data-tag="zettel-section"], | |
.listContentItem span[data-tag="personal-section"], | |
.listContentItem span[data-tag="nedap-section"], | |
.listContentItem span[data-tag="work-section"], | |
.listContentItem span[data-tag="journal-section"], | |
.listContentItem span[data-tag="inbox-section-old"], | |
.listContentItem span[data-tag="scratchpad-section"], | |
.listContentItem span[data-tag="中文-section"], | |
.listContentItem span[data-tag="spotlight-section"], | |
.listContentItem span[data-tag="metrics-section"], | |
.listContentItem span[data-tag="literature-notes"], | |
.listContentItem span[data-tag="zettel-notes"], | |
.listContentItem span[data-tag="fleeting-notes"] { | |
opacity: 0.4 | |
} | |
.listContentItem:hover span[data-tag="zettel"], | |
.listContentItem:hover span[data-tag="missing"], | |
.listContentItem:hover span[data-tag="highlights-section"], | |
.listContentItem:hover span[data-tag="zettel-section"], | |
.listContentItem:hover span[data-tag="personal-section"], | |
.listContentItem:hover span[data-tag="nedap-section"], | |
.listContentItem:hover span[data-tag="work-section"], | |
.listContentItem:hover span[data-tag="journal-section"], | |
.listContentItem:hover span[data-tag="inbox-section-old"], | |
.listContentItem:hover span[data-tag="scratchpad-section"], | |
.listContentItem:hover span[data-tag="metrics-section"], | |
.listContentItem:hover span[data-tag="中文-section"], | |
.listContentItem:hover span[data-tag="spotlight-section"], | |
.listContentItem:hover span[data-tag="literature-notes"], | |
.listContentItem:hover span[data-tag="zettel-notes"], | |
.listContentItem:hover span[data-tag="fleeting-notes"] { | |
opacity: 1 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment