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.
* **`/bot-thesaurus `**
> Deep synonyms, antonyms, consonant (derived) words, and cognitive associations.
* **`/bot-etymology `**
> 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.
## WHAT I MADE/THINK?
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.
Problem: The dashboard needed a simple button to share the current hub URL, but running browser APIs directly could break Astro’s static site generation (SSG) compiler.
Solution: Added an inline <script is:inline> block to the index page. This bypasses the server-side build process and safely binds the sharing and clipboard logic only when the page loads in the user’s browser.
Goal: Transformed TickTock from a single countdown page into a comprehensive time-management utility hub powered by Astro.
Implementation: Created a main dashboard page (src/pages/index.astro) to serve as the gateway for current and future time tools, using a shared layout for a consistent user experience.
Adding Future Roadmap and Project Documentation
Goal: Wrote a complete README.md to document the new project architecture, local testing steps, and automated GitHub Pages deployment.
Future Vision: Updated the repository roadmap to announce upcoming tools built for the Hack Club Stardance event, including a Pomodoro Timer, World Clock Board, Minimalist Timer, and Time Progress Bars.
Problem: The card icons shrank and deformed when the screen size changed.
Solution: Added flex-shrink: 0; to the icon class to force them to keep their correct size.
Cards Stacking Vertically
Problem: The tool cards unexpectedly stacked into a narrow, single column right in the middle of the screen. Even though there was plenty of empty space on both sides of the desktop browser, the grid refused to expand horizontally and display the cards side-by-side.
Troubleshooting:
The grid’s layout formula was correctly set to repeat(auto-fit, minmax(250px, 1fr)), which should have allowed multiple columns.
However, the parent container (.home-container) was set to display: flex with align-items: center. In a vertical Flexbox layout, this alignment forces child elements like the grid to shrink to their absolute minimum width based on content, instead of filling the screen.
To make matters worse, a strict max-width: 300px; was hardcoded onto the .tool-grid. Since two cards plus their gaps required at least 525px to sit side-by-side, the 300px restriction made it mathematically impossible for the browser to create a second column.
Solution:
Removed the restrictive max-width: 300px; from the grid and replaced it with a generous max-width: 1200px; to allow proper breathing room on large screens.
Added width: 100%; to the grid class, forcing the grid container to break out of the Flexbox compression and stretch completely across the parent container.
This allowed the responsive auto-fit engine to finally see the available width and cleanly arrange the cards into multiple columns.
Fixing Grid Spacing and Syntax Errors
Layout Breaking Off-Screen
Problem: The grid expanded past the screen edges and cut off the card content.
Solution: Added box-sizing: border-box; to the main container so that padding is counted inside the total width.
Broken Units and Side Scrollbars
Problem: An annoying horizontal scrollbar appeared at the bottom of the page.
Solution: Fixed a typo where width: 100sww; was written instead of 100svw, and added body { margin: 0; } to clear default browser spaces.