Replaced direct DOM manipulation of live dashboard elements with a dedicated, off-screen template canvas (.export-canvas).
Cloned active .progress-card elements into an isolated container (.export-cards-holder), ensuring the on-screen UI remains completely untouched and non-flickering during image generation.
Moved aspect ratio, high-resolution dimensions (600x600), padding, and font-scaling rules directly into CSS for clean separation of concerns.
Error Fixes & Cleanup
Fixed ReferenceError caused by leftover references to targetContainer and stampEl inside initExportImageFeature.
Updated html2canvas target from main dashboard container to the temporary canvasEl.
Streamlined fallback DOM cleanup logic inside the try...catch block to guarantee off-screen elements are properly garbage collected.
Integrated html2canvas library to enable one-click PNG image export of the active progress dashboard.
Added an “Export as Image” button inside the custom sidebar menu with dedicated styling.
Handled theme-aware background rendering by dynamically querying computed global CSS variables (--bg-app).
DOM Template & Dynamic Watermark
Refactored dynamic watermark creation using the HTML <template> element (#export-watermark-template), cleanly separating DOM structure from JavaScript execution logic.
Configured dynamic timestamps using now.toLocaleString() to inject real-time snapshot dates and times into exported images.
Added ignoreElements filtering in html2canvas to prevent unchecked/hidden .progress-card elements from creating top/bottom visual gaps in exported images.
Bug Fixes & Refactor
Fixed a TypeError on insertBefore/appendChild by referencing clone.firstElementChild to extract the correct Element Node from DocumentFragment.
Resolved HTML/JS ID typos (export-watermark-template) and method call mismatches to ensure reliable script execution.
Integrated URL Hash (#year,month,...) and localStorage synchronization into time-progress.js to preserve users’ toggle preferences across reloads and shares.
Added a hashchange event listener to ensure UI check states dynamically update when users use browser navigation (Back/Forward).
Centralized Layout Share Event
Refactored the #share-menu-btn event listener into BaseLayout.astro, eliminating duplicate share logic across individual tool pages.
Leveraged document.title dynamically to provide clean, contextual titles for native Web Share API and clipboard copy fallbacks.
Ported the standalone Time Progress Bar tool into the Astro layout system using designated slots (#head, #header-content, #custom-menu, and #main-content).
Converted hardcoded hex colors into semantic global theme CSS variables (--accent-color, --component-bg-standard, --text-heading), ensuring native support for Dark and Light mode toggling.
Replaced the dropdown filter with sidebar multi-select checkboxes for custom control over visible time progress units.
JavaScript Modular Refactoring & Bug Fixes
Decoupled single-script logic into dedicated, single-responsibility functions (initSidebarToggles, calculateTimeProgress, updateTicksUI, updateProgressCardUI, and updateSingleCardUI).
Resolved JavaScript syntax errors, including missing function keywords, JS Automatic Semicolon Insertion (ASI) line-break issues on return statements, and uncalled Date method parentheses.
Streamlined animation frame rendering by passing structured data from math calculations directly into UI updater functions.
Devlog 24: Color Architecture Refactoring with Design Tokens
Two-Tier CSS Variables
Global Tokens: Extracted hardcoded hex colors into primitive color names inside global.css.
Theme Tokens: Created a semantic layer mapping elements like –bg-app and –accent-color directly to global tokens.
Clean Codebase Update
Component Styles: Replaced absolute colors across the layout, dashboard hub, countdown, and clock templates with var() variables.
Script Alignment: Updated dynamic checkmark colors in JavaScript to read –accent-color instead of raw hex values.
Future Scope: The design is now fully abstracted, meaning light mode implementation will only require token swapping without editing individual component code.
I built an English Lexicon Explorer Slack bot. Instead of making generic toy commands (like random jokes or dog memes), I wanted to create a high-performance, developer-focused utility. It’s hosted 24/7 on Hack Club Nest and aggregates deep linguistic data from multiple databases simultaneously.
Features
Prompt
/bot-word <word>
Quick dictionary definitions, phonetic pronunciations, and real-world usage examples.
/bot-thesaurus <word>
Deep synonyms, antonyms, consonant (derived) words, and cognitive associations.
/bot-etymology <word>
Traces historical origins (like Latin and Greek roots) from Wiktionary.
/bot-help
Clean command directory.
Beautiful Block Kit UI
Formatted with structured columns, dividers, and clean styling instead of plain text.
WHAT I LEARNT?
How to set up and manage a systemd background service on Hack Club Nest.
Resolving asynchronous concurrency in Node.js using Promise.all to fetch from multiple APIs concurrently.
Formatting structured layout cards using Slack Block Kit.
Designing clear, modular Slash Commands without cluttering the workspace.
/bot-word: Focuses strictly on dictionary definitions, phonetic pronunciations, and usage examples.
/bot-thesaurus: Focuses entirely on finding synonyms, antonyms, consonant words, and cognitive associations.
/bot-etymology: Digs deep into the history of the word, extracting origin stories and morphological roots.
100% Pure English codebase: Cleaned out all Chinese comments, console outputs, and Slack UI block elements. The entire codebase is now completely English, making it look much more professional and standard.
Cleaned Up Slack UI: Removed old legacy commands (like /bot-ask and /bot-dog) from the Slack Developer Console, keeping our workspace pristine and completely collision-free!
Devlog #2: Pivoting to a Hardcore Lexicon Explorer
🛠️ What I Did
Killed the Fluff: Stripped out /bot-ask, /bot-dog, and /bot-joke to keep the bot super focused.
Multi-API Aggregation: Configured the bot to query the Free Dictionary API (Wiktionary) and the Datamuse API simultaneously using asynchronous Promise.all in Node.js.
Built 3 Custom Modes:
all: Standard definitions, phonetic symbols, and real-world usage examples.
thesaurus: Deep dive into synonyms, antonyms, and derived/consonant words.
etymology: Traces the historical roots and origin stories of words (like Latin and Greek prefixes/suffixes).
Polished UI with Slack Block Kit: Instead of sending plain text, the bot now formats queries into beautiful, structured layouts with columns and dividers.
I expanded TickTock from a single timer into a multi-tool station (Hub)! This time, I built a beautiful, highly customizable Digital Clock. It was a huge challenge for me to handle standard browser behaviors, especially turning a single-page SPA into a structured Astro website with a homepage and sub-pages. It took lots of testing, but I feel so proud when everything finally aligned perfectly.
Features
⭐Homepage Hub Dashboard
Live Countdown
Customizable Countdown
Full mode / Days mode
Change Target Date
Edit Event Title
⭐Digital Clock
⭐12-hour / 24-hour format
⭐3 Font styles (Sans, Serif, Mono)
⭐Fullscreen mode (Header/Footer kept!)
⭐Smooth breathing colon animation
automatically save in localStorage & url#
Lightweight
⭐means new features of the previous ship
WHAT I LEARNT?
A lot of new things about Astro and NodeJS
How to structure routes for multiple tools (Refactoring files)
Advanced CSS (using global variables to adjust layout gaps dynamicly)
REPLIES
Thank you so much for the 115 stardust and the amazing feedback! I read every single review from Ship #2, and they helped me make this update so much better.
1. ABOUT MORE FEATURES
Many suggested adding more tools or events. I turned the website into a Hub and built the Digital Clock as our second official tool!
2. ABOUT THE SCREENSHOT IN README
Two reviewers mentioned adding screenshots. I’ve updated the README with fresh screenshots so people skimming through can see the UI instantly.
Devlog 23: Global Branding Relocation and Logo Navigation
Moving Title Label to BaseLayout
Unifying the brand and improving UX
Header Linkification: Refactored the main title-label (“TickTock”) out of individual page templates and integrated it directly into the global BaseLayout.astro.
Back-to-Home UX: Wrapped the brand title in an <a> tag. Now, clicking the brand logo on any sub-tool instantly routes the user back to the home dashboard Hub, offering an intuitive, web-app-like navigation experience.
Devlog 22: F11-Equivalent Fullscreen via Root Element
Standardizing Fullscreen to document.documentElement
Fixing disappearing layout elements
The Pitfall: Previously, calling requestFullscreen() on the individual #clock-screen container caused the browser to isolate it from the DOM layout. This triggered default browser styling which rendered a pitch-black backdrop, and completely hid crucial layout parts like the header, footer, and side menu buttons.
The Solution: We shifted the fullscreen API target from the sub-container directly to document.documentElement (the global <html> node). This aligns the button’s behavior perfectly with standard keyboard F11 fullscreen events.
The Result: All global UI elements (header, footer, navigation) now scale smoothly and remain perfectly visible and interactive without any layout shifts or z-index clashing.
Devlog 21: Architecture Normalization and Layout Fine-Tuning
Directory Restructuring & Future-Proofing
Preparing for scalability
Digital Clock Renaming: To prevent future routing conflicts as the project scales, we successfully renamed clock.js to digital-clock.js and adjusted the main page path to /src/pages/digital-clock/. This cleanly isolates this feature from upcoming modules like World Clock or Pomodoro Timer.
Dependency Clean-up: Updated all asset paths and module script injections across the hub, fully standardizing the multi-tool routing structure under the /TickTock/ basePath.
Layout Fixes with Global CSS Variables
Resolving invalid CSS properties via JS injection
Replacing Non-Standard Styles: Fixed a crucial layout issue where arbitrary if(...) conditions inside CSS were breaking colon component constraints.
Dynamic Width Injection: Migrated the layout parameters directly into digital-clock.js using the standard document.documentElement.style.setProperty API. The .colon element now seamlessly reads the responsive --clock-colon-width CSS variable, adapting perfectly across Sans, Serif, and Mono configurations without any jumping side effects.
Persistent settings: The clock now remembers your favorite layout. Your choice of time format (12/24h) and font style is instantly saved directly to your browser’s local storage.
URL sync: We linked these settings directly to the URL hash (like #12hr&mono). When you refresh or load the page, your exact preferred theme loads up right away.
Smart Sharing and Hub Integration
Spreading the time and completing the hub
Dynamic sharing: Added a share button that grabs your exact custom clock URL. It uses the Web Share API when available, and easily falls back to copying the link to your clipboard with a smooth checkmark animation on success.
Connecting the dashboard: Linked the completed clock page to our homepage hub grid and updated the site layout, officially making TickTock a multi-tool station.
Problem: The clock header needed to show the full current date (e.g., “Sunday, July 12, 2026”) dynamically without taxing browser performance or importing heavy external date libraries.
Solution: Added a #date-label placeholder to the template and used the native JavaScript toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }) inside the main runtime loop to render lightweight, perfectly formatted timestamps on every update.
Creating Fluid Visual Oscillations via Math.sin()
Problem: Traditional blinking colons look rigid and distracting, failing to deliver a premium, organic feel for an active time-management tool.
Solution: Avoided simple CSS toggles and leveraged a true trigonometric formula inside a requestAnimationFrame loop. By mapping high-precision timestamps through Math.sin(), the opacity gracefully curves between 0.2 and 1.0, producing a perfectly smooth, wave-like breathing animation.
Binding Custom Display and Layout Controls
Problem: The interface required instant controls for 12/24-hour formats, font adjustments, and a standalone full-screen view while managing layout side effects.
Solution: Wired up event listeners to modify global runtime states and inline CSS font families on the fly. Integrated the HTML5 Fullscreen API onto the #clock-screen element, backed by a global fullscreenchange listener to seamlessly catch manual ESC escapes and keep the toggle button states perfectly in sync.