Skip to content

Commit af2dac7

Browse files
feat: status message 'Label Takeover' in ring overlay
When SP Status is active (e.g., 'BRB', 'AFK', custom message): - Session label text (e.g., 'FOCUS') is replaced with the status message - Label color changes to warm amber (#f59e0b) with a gentle 2.5s pulse - Stats and next-up banner auto-hide (not relevant during AFK) - Timer continues running normally — viewers see progress - When status clears, label smoothly transitions back to session name CSS: - New .status-active class on .session-label with amber glow - New @Keyframes pulse-status (opacity 1→0.6→1) - letter-spacing transitions from 5px→3px for visual distinction - text-transform: none (preserves original message casing) - Customizable via --sp-status-color (default: #f59e0b amber) Also includes: docs/faq.md line-ending normalization (CRLF→LF) Tests: 104/104 passed
1 parent 5690f01 commit af2dac7

1 file changed

Lines changed: 48 additions & 25 deletions

File tree

‎timer_overlay.html‎

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,24 @@
176176
text-transform: uppercase;
177177
letter-spacing: 5px;
178178
color: var(--text-secondary);
179-
transition: color 0.6s ease, text-shadow 0.6s ease;
179+
transition: color 0.6s ease, text-shadow 0.6s ease, letter-spacing 0.4s ease;
180180
text-shadow: 0 1px 8px rgba(0, 0, 0, 0.5);
181181
margin-top: 6px;
182182
}
183183

184+
/* ── Status takeover — label becomes status message ── */
185+
.session-label.status-active {
186+
color: var(--sp-status-color, #f59e0b);
187+
text-shadow: 0 0 16px rgba(245, 158, 11, 0.4), 0 1px 8px rgba(0, 0, 0, 0.5);
188+
letter-spacing: 3px;
189+
text-transform: none;
190+
animation: pulse-status 2.5s ease-in-out infinite;
191+
}
192+
@keyframes pulse-status {
193+
0%, 100% { opacity: 1; }
194+
50% { opacity: 0.6; }
195+
}
196+
184197
.stats {
185198
font-size: var(--sp-stats-size, 1rem);
186199
font-weight: 500;
@@ -606,38 +619,48 @@
606619
while (trackerGroup.firstChild) trackerGroup.removeChild(trackerGroup.firstChild);
607620
}
608621

609-
if (!SHOW_STATS) {
622+
// Status takeover: when status is active, replace the label
623+
const statusActive = SHOW_STATUS && status_active && status_message;
624+
625+
if (statusActive) {
626+
// Takeover: label shows status message, stats & next hide
627+
labelEl.textContent = status_message;
628+
labelEl.classList.add('status-active');
610629
statsEl.textContent = '';
611-
} else if (mode === 'pomodoro' && (is_running || completed_focus_sessions > 0)) {
612-
let stat = `${completed_focus_sessions}/${goal_sessions}`;
613-
if (total_focus_seconds > 0) stat += ` · ${formatDuration(total_focus_seconds)}`;
614-
statsEl.textContent = stat;
615-
} else if (mode === 'custom' && custom_segment_count > 0) {
616-
statsEl.textContent = `${custom_segment_index || 1}/${custom_segment_count}`;
617-
} else if (mode === 'stopwatch' && total_focus_seconds > 0) {
618-
statsEl.textContent = formatDuration(total_focus_seconds);
630+
nextBanner.classList.remove('visible');
619631
} else {
620-
statsEl.textContent = '';
621-
}
632+
labelEl.classList.remove('status-active');
633+
634+
if (!SHOW_STATS) {
635+
statsEl.textContent = '';
636+
} else if (mode === 'pomodoro' && (is_running || completed_focus_sessions > 0)) {
637+
let stat = `${completed_focus_sessions}/${goal_sessions}`;
638+
if (total_focus_seconds > 0) stat += ` · ${formatDuration(total_focus_seconds)}`;
639+
statsEl.textContent = stat;
640+
} else if (mode === 'custom' && custom_segment_count > 0) {
641+
statsEl.textContent = `${custom_segment_index || 1}/${custom_segment_count}`;
642+
} else if (mode === 'stopwatch' && total_focus_seconds > 0) {
643+
statsEl.textContent = formatDuration(total_focus_seconds);
644+
} else {
645+
statsEl.textContent = '';
646+
}
622647

623-
if (SHOW_NEXT && is_running && !overtime) {
624-
let nextText = '';
625-
if (next_session_type) nextText = `Next: ${next_session_type}`;
626-
if (ends_at) nextText += nextText ? ` · ${ends_at}` : `Ends ${ends_at}`;
627-
if (nextText) {
628-
nextBanner.textContent = nextText;
629-
nextBanner.classList.add('visible');
648+
if (SHOW_NEXT && is_running && !overtime) {
649+
let nextText = '';
650+
if (next_session_type) nextText = `Next: ${next_session_type}`;
651+
if (ends_at) nextText += nextText ? ` · ${ends_at}` : `Ends ${ends_at}`;
652+
if (nextText) {
653+
nextBanner.textContent = nextText;
654+
nextBanner.classList.add('visible');
655+
} else {
656+
nextBanner.classList.remove('visible');
657+
}
630658
} else {
631659
nextBanner.classList.remove('visible');
632660
}
633-
} else {
634-
nextBanner.classList.remove('visible');
635661
}
636662

637-
if (SHOW_STATUS && status_active && status_message) {
638-
infoLineEl.textContent = status_message;
639-
infoLineEl.classList.add('visible');
640-
} else if (SHOW_CHAT && chat_status_line) {
663+
if (!statusActive && SHOW_CHAT && chat_status_line) {
641664
infoLineEl.textContent = chat_status_line;
642665
infoLineEl.classList.add('visible');
643666
} else {

0 commit comments

Comments
 (0)