diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index bf5a26c..b0b6804 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -27,6 +27,7 @@ jobs: with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} prompt: "/review" + use_sticky_comment: "true" claude_args: "--max-turns 5 --allowedTools 'Bash(gh:*)'" # Interactive: respond to @claude mentions in comments diff --git a/README.md b/README.md index a2c6139..414af50 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,20 @@ A Next.js-based sandbox for exploring visual design systems, widgets, and intera ## Experiments +### Day at a Glance + +**February 12, 2026** + +[![Day at a Glance](./public/screenshots/day-at-a-glance.png)](https://www.joshcoolman.com/day-at-a-glance) + +Time-aware workday timeline with a dynamic now-line that tracks real time. Features a 9am-5pm schedule with colored event bars that partially fill as the hour progresses -- gray above the now-line, color below. Past events auto-dim. Built with CSS grid, inline linear-gradient for the fill effect, and 60-second interval updates. + +**Tags:** CSS Grid - Timeline - Dynamic State - Dark Theme + +**[View Live →](https://www.joshcoolman.com/day-at-a-glance) | [View Code →](https://github.com/joshcoolman-smc/sandbox/tree/main/app/day-at-a-glance)** + +--- + ### Sourcing Image **February 11, 2026** @@ -104,20 +118,6 @@ Interactive brand guidelines with live color and typography customization. Featu --- -### A Day in the life... - -**February 2, 2026** - -[![Day at a Glance](./public/screenshots/day-at-a-glance.png)](https://www.joshcoolman.com/day-at-a-glance) - -Clean 3-column CSS grid timeline with colored sidebar bars, SVG icons, and a subtle "now" indicator line that shows through semi-transparent event cards. Features split color bars for past/upcoming visualization and continuous horizontal hour lines. - -**Tags:** CSS Grid • Timeline • Z-Index Layering • Dark Theme - -**[View Live →](https://www.joshcoolman.com/day-at-a-glance) | [View Code →](https://github.com/joshcoolman-smc/sandbox/tree/main/app/day-at-a-glance)** - ---- - ### Blend **February 2, 2026** diff --git a/app/day-at-a-glance/page.tsx b/app/day-at-a-glance/page.tsx index 0ed6c58..3659a18 100644 --- a/app/day-at-a-glance/page.tsx +++ b/app/day-at-a-glance/page.tsx @@ -1,20 +1,161 @@ 'use client'; -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import './styles.css'; +const COLOR_MAP: Record = { + blue: '#3b82f6', + purple: '#a855f7', + yellow: '#f59e0b', + pink: '#ec4899', + green: '#22c55e', + teal: '#14b8a6', + orange: '#f97316', + indigo: '#6366f1', +}; + +const events = [ + { + hour: 9, + title: 'Team Standup', + time: '09:00 – 10:00 (1 hr)', + color: 'blue', + icon: ( + + + + + + + ), + }, + { + hour: 10, + title: 'Deep Work', + time: '10:00 – 11:00 (1 hr)', + color: 'purple', + icon: ( + + + + + ), + }, + { + hour: 11, + title: 'Sprint Planning', + time: '11:00 – 12:00 (1 hr)', + color: 'indigo', + icon: ( + + + + + ), + }, + { + hour: 12, + title: 'Lunch Break', + time: '12:00 – 13:00 (1 hr)', + color: 'yellow', + icon: ( + + + + + ), + }, + { + hour: 13, + title: 'Design Review', + time: '13:00 – 14:00 (1 hr)', + color: 'pink', + icon: ( + + + + + + ), + }, + { + hour: 14, + title: 'Documentation', + time: '14:00 – 15:00 (1 hr)', + color: 'orange', + icon: ( + + + + + + + ), + }, + { + hour: 15, + title: 'Client Call', + time: '15:00 – 16:00 (1 hr)', + color: 'green', + icon: ( + + + + ), + }, + { + hour: 16, + title: 'Code Review', + time: '16:00 – 17:00 (1 hr)', + color: 'teal', + icon: ( + + + + + ), + }, +]; + export default function DayAtAGlance() { - const [checkboxes, setCheckboxes] = useState>({ - 0: true, - 1: false, - 2: false, - 3: false - }); + const [checkboxes, setCheckboxes] = useState>({}); + const [nowPosition, setNowPosition] = useState(null); + const [currentHour, setCurrentHour] = useState(-1); + const [currentMinute, setCurrentMinute] = useState(0); + const [todayDate, setTodayDate] = useState(''); + + useEffect(() => { + const updateTime = () => { + const now = new Date(); + const hour = now.getHours(); + const minute = now.getMinutes(); + setCurrentHour(hour); + setCurrentMinute(minute); + + if (hour >= 9 && hour < 17) { + setNowPosition((hour - 9) * 100 + (minute / 60) * 100 + 2); + } else { + setNowPosition(null); + } + }; + + setTodayDate( + new Date().toLocaleDateString('en-US', { + weekday: 'long', + month: 'short', + day: 'numeric', + }) + ); + + updateTime(); + const interval = setInterval(updateTime, 60000); + return () => clearInterval(interval); + }, []); const toggleCheckbox = (index: number) => { setCheckboxes(prev => ({ ...prev, - [index]: !prev[index] + [index]: !prev[index], })); }; @@ -23,113 +164,63 @@ export default function DayAtAGlance() {

Your day at
a glance

Easily view your scheduled time blocks
in a clean and efficient timeline format.

+ {todayDate &&

{todayDate}

}
-
-
- 07 -
-
-
- - - - -
-
-
-
-
-
Morning Workout
-
07:00 – 08:00 (1 hr)
-
-
toggleCheckbox(0)} - /> -
-
-
+ {events.map((event, i) => { + const isPast = event.hour < currentHour; + const isCurrent = event.hour === currentHour; + const fillPct = Math.round((currentMinute / 60) * 100); + const hex = COLOR_MAP[event.color] || '#444'; -
-
- 08 -
-
-
- - - -
-
-
-
-
-
Shower
-
08:00 – 09:00 (1 hr)
-
-
toggleCheckbox(1)} - /> -
-
-
- -
+ const barStyle = isCurrent + ? { + background: `linear-gradient(to bottom, rgba(68, 68, 68, 0.95) ${fillPct}%, ${hex} ${fillPct}%)`, + } + : undefined; -
-
- 09 -
-
-
- - - - -
-
-
-
-
-
Breakfast
-
09:00 – 10:00 (1 hr)
+ return ( +
+
+ {String(event.hour).padStart(2, '0')}
-
toggleCheckbox(2)} - /> -
-
-
- -
-
- 10 -
-
-
- - - - -
-
-
-
-
-
Check Email
-
10:00 – 11:00 (1 hr)
+
+
+ {event.icon} +
+
+
+
+
+
{event.title}
+
{event.time}
+
+
toggleCheckbox(i)} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + toggleCheckbox(i); + } + }} + /> +
-
toggleCheckbox(3)} - />
-
-
+ ); + })} + + {nowPosition !== null && ( +
+ )}
); diff --git a/app/day-at-a-glance/styles.css b/app/day-at-a-glance/styles.css index c257fd8..cfd1c2a 100644 --- a/app/day-at-a-glance/styles.css +++ b/app/day-at-a-glance/styles.css @@ -38,6 +38,15 @@ h1 { line-height: 1.5; } +.today-date { + font-size: 14px; + font-weight: 500; + color: #666; + margin-top: 12px; + letter-spacing: 0.5px; + text-transform: uppercase; +} + .timeline { position: relative; display: grid; @@ -124,27 +133,44 @@ h1 { color: #888; } -.event-bar.shower { +.event-bar.blue { background: #3b82f6; color: #fff; } -.event-bar.breakfast { +.event-bar.purple { + background: #a855f7; + color: #fff; +} + +.event-bar.yellow { background: #f59e0b; color: #fff; } -.event-bar.email { - background: #a855f7; +.event-bar.pink { + background: #ec4899; color: #fff; } -.event-bar.split { - background: linear-gradient(to bottom, rgba(68, 68, 68, 0.85) 50%, var(--bar-color) 50%); +.event-bar.green { + background: #22c55e; + color: #fff; } -.event-bar.split.shower { - --bar-color: #3b82f6; +.event-bar.teal { + background: #14b8a6; + color: #fff; +} + +.event-bar.orange { + background: #f97316; + color: #fff; +} + +.event-bar.indigo { + background: #6366f1; + color: #fff; } .card-col { @@ -189,6 +215,10 @@ h1 { color: #888; } +.hour-row.past .hour-num { + color: #333; +} + .event-time { font-size: 13px; color: #666; @@ -222,8 +252,21 @@ h1 { } .checkbox.blue { border-color: #3b82f6; } +.checkbox.blue.checked { background: #3b82f6; border-color: #3b82f6; } .checkbox.yellow { border-color: #f59e0b; } +.checkbox.yellow.checked { background: #f59e0b; border-color: #f59e0b; } .checkbox.purple { border-color: #a855f7; } +.checkbox.purple.checked { background: #a855f7; border-color: #a855f7; } +.checkbox.pink { border-color: #ec4899; } +.checkbox.pink.checked { background: #ec4899; border-color: #ec4899; } +.checkbox.green { border-color: #22c55e; } +.checkbox.green.checked { background: #22c55e; border-color: #22c55e; } +.checkbox.teal { border-color: #14b8a6; } +.checkbox.teal.checked { background: #14b8a6; border-color: #14b8a6; } +.checkbox.orange { border-color: #f97316; } +.checkbox.orange.checked { background: #f97316; border-color: #f97316; } +.checkbox.indigo { border-color: #6366f1; } +.checkbox.indigo.checked { background: #6366f1; border-color: #6366f1; } .now-line { position: absolute; @@ -235,15 +278,6 @@ h1 { pointer-events: none; } -.now-time { - position: absolute; - left: 0; - top: -7px; - font-size: 11px; - font-weight: 600; - color: #ff6b6b; - white-space: nowrap; -} @media (max-width: 640px) { body { diff --git a/app/design-experiments/page.tsx b/app/design-experiments/page.tsx index c95e4b1..7b807ad 100644 --- a/app/design-experiments/page.tsx +++ b/app/design-experiments/page.tsx @@ -68,6 +68,14 @@ export default function Home() { }, []) const experiments: Experiment[] = [ + { + slug: 'day-at-a-glance', + date: 'February 12, 2026', + title: 'Day at a Glance', + description: 'Time-aware workday timeline with dynamic now-line that tracks real time. Features 9am-5pm schedule with colored event bars that partially fill as the hour progresses -- gray above the now-line, color below. Past events auto-dim. Built with CSS grid, inline linear-gradient for the fill effect, and 60-second interval updates.', + screenshot: '/screenshots/day-at-a-glance.png', + tags: ['CSS Grid', 'Timeline', 'Dynamic State', 'Dark Theme'] + }, { slug: 'sourcing-image', date: 'February 11, 2026', @@ -132,14 +140,6 @@ export default function Home() { screenshot: '/screenshots/spec-sheet.png', tags: ['Typography', 'Font Pairings', 'Dark/Light Mode', 'Type Specimen'] }, - { - slug: 'day-at-a-glance', - date: 'February 2, 2026', - title: 'Day at a Glance', - description: 'Clean 3-column CSS grid timeline with colored sidebar bars, SVG icons, and a subtle "now" indicator line that shows through semi-transparent event cards. Features split color bars for past/upcoming visualization.', - screenshot: '/screenshots/day-at-a-glance.png', - tags: ['CSS Grid', 'Timeline', 'Z-Index Layering', 'Dark Theme'] - }, { slug: 'blend', date: 'February 2, 2026', diff --git a/docs/01-progress.md b/docs/01-progress.md index 5297dc7..d1b85fc 100644 --- a/docs/01-progress.md +++ b/docs/01-progress.md @@ -4,6 +4,17 @@ This file tracks major changes and milestones in the project. --- +### Day at a Glance: time-aware enhancement + +**Date:** 2026-02-12 +**Issue:** #9 - Day at a Glance: time-aware enhancement with dynamic now-line + +Rebuilt the Day at a Glance experiment with a full 9am-5pm workday schedule, dynamic now-line that tracks real time, and a partial color fill effect on the current hour's event bar. Added accessibility for checkboxes and fixed hydration mismatch. + +**Key files:** `app/day-at-a-glance/page.tsx`, `app/day-at-a-glance/styles.css` + +--- + ### Write-post skill and TypeScript cleanup **Date:** 2026-02-12