Files
claude-use-extension/styles.css
Carlos Narro 6e5f589156 Rehidratar Date al cargar caché y refresh no-destructivo
Bug raíz del click-no-abre-overlay: chrome.storage serializa con JSON,
los Date (sessionStartTime, sessionEndTime, estimatedEndDate) volvían
como strings ISO, y createWeeklyTracker llamaba .toLocaleDateString
en un string. rehydrateDates los devuelve a Date al cargar.

Mejoras adicionales:
- showOverlayError ya no destruye el panel si hay tracker visible:
  saca un aviso temporal en el header (auto-oculta a los 7s).
- DOM en el aviso construido con textContent, no innerHTML, para
  cerrar la puerta a XSS aunque el msg sea hardcodeado.
- Limpieza del andamio [CUT-DIAG] usado para encontrar el bug;
  __claudeUsageTracker se queda expuesto para depuración futura.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-04 14:45:00 +02:00

702 lines
13 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Claude Usage Tracker Extension Styles */
.claude-usage-tracker-container {
margin-top: 16px;
padding: 16px;
background: rgba(255, 255, 255, 0.05);
border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.claude-usage-tracker-title {
font-size: 14px;
font-weight: 600;
color: var(--text-100, #e5e5e5);
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 8px;
}
.claude-usage-tracker-title svg {
width: 16px;
height: 16px;
}
/* Weekly Progress Bar */
.weekly-progress-container {
display: flex;
gap: 4px;
height: 32px;
margin-bottom: 8px;
}
.day-segment {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
}
.day-bar {
width: 100%;
height: 20px;
background: rgba(255, 255, 255, 0.05);
border-radius: 4px;
position: relative;
overflow: hidden;
}
.day-bar-bg {
position: absolute;
top: 0;
left: 0;
height: 100%;
background: rgba(255, 255, 255, 0.1);
border-radius: 4px;
}
.day-bar-fill {
position: absolute;
top: 0;
left: 0;
height: 100%;
border-radius: 4px;
transition: width 0.3s ease;
}
.day-segment.future .day-bar {
opacity: 0.4;
}
/* Offset para el día de reinicio (hueco al principio) */
.day-bar-offset {
position: absolute;
top: 0;
left: 0;
height: 100%;
background: repeating-linear-gradient(
-45deg,
rgba(50, 50, 50, 0.8),
rgba(50, 50, 50, 0.8) 3px,
rgba(30, 30, 30, 0.8) 3px,
rgba(30, 30, 30, 0.8) 6px
);
border-radius: 4px 0 0 4px;
z-index: 2;
}
.day-segment.reset-day-start .day-label {
color: #10b981;
}
.day-segment.reset-day-end .day-label {
color: #f59e0b;
}
.day-bar-offset.end {
left: auto;
right: 0;
border-radius: 0 4px 4px 0;
}
.day-bar-fill.under-budget {
background: linear-gradient(90deg, #10b981, #34d399);
}
.day-bar-fill.on-track {
background: linear-gradient(90deg, #f59e0b, #fbbf24);
}
.day-bar-fill.over-budget {
background: linear-gradient(90deg, #ef4444, #f87171);
}
.day-label {
font-size: 10px;
color: var(--text-400, #a3a3a3);
margin-top: 4px;
text-transform: uppercase;
}
.day-segment.today .day-label {
color: var(--accent-main-100, #f97316);
font-weight: 600;
}
.day-segment.today .day-bar {
border: 1px solid var(--accent-main-100, #f97316);
}
/* Daily Target Line */
.daily-target-line {
position: absolute;
top: 0;
height: 100%;
width: 2px;
background: rgba(255, 255, 255, 0.5);
z-index: 1;
}
/* Info Row */
.usage-info-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 12px;
padding-top: 12px;
border-top: 1px solid rgba(255, 255, 255, 0.1);
}
.usage-stat {
display: flex;
flex-direction: column;
align-items: center;
}
.usage-stat-label {
font-size: 10px;
color: var(--text-400, #a3a3a3);
text-transform: uppercase;
margin-bottom: 4px;
}
.usage-stat-value {
font-size: 14px;
font-weight: 600;
color: var(--text-100, #e5e5e5);
}
.usage-stat-value.good {
color: #10b981;
}
.usage-stat-value.warning {
color: #f59e0b;
}
.usage-stat-value.danger {
color: #ef4444;
}
/* Session Info */
.session-info-container {
margin-top: 16px;
padding: 12px;
background: rgba(255, 255, 255, 0.03);
border-radius: 8px;
border: 1px solid rgba(255, 255, 255, 0.08);
}
.session-info-title {
font-size: 12px;
font-weight: 600;
color: var(--text-200, #d4d4d4);
margin-bottom: 8px;
display: flex;
align-items: center;
gap: 6px;
}
.session-info-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
}
.session-info-item {
display: flex;
flex-direction: column;
}
.session-info-label {
font-size: 10px;
color: var(--text-400, #a3a3a3);
margin-bottom: 2px;
}
.session-info-value {
font-size: 13px;
font-weight: 500;
color: var(--text-100, #e5e5e5);
}
.session-reset-text {
margin-top: 8px;
font-size: 11px;
color: var(--text-400, #a3a3a3);
font-style: italic;
}
/* Tooltip */
.day-tooltip {
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.9);
color: white;
padding: 6px 10px;
border-radius: 6px;
font-size: 11px;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity 0.2s;
z-index: 100;
margin-bottom: 4px;
}
.day-segment:hover .day-tooltip {
opacity: 1;
}
/* Reset Info */
.reset-info {
display: flex;
align-items: center;
gap: 6px;
font-size: 11px;
color: var(--text-400, #a3a3a3);
margin-top: 8px;
}
.reset-info svg {
width: 14px;
height: 14px;
}
/* Progress summary */
.progress-summary {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 13px;
color: var(--text-200, #d4d4d4);
margin-top: 12px;
padding: 12px 16px;
background: rgba(255, 255, 255, 0.03);
border-radius: 8px;
border: 1px solid rgba(255, 255, 255, 0.08);
}
.progress-ideal {
display: flex;
align-items: center;
gap: 6px;
font-weight: 600;
font-size: 14px;
}
.progress-ideal-indicator {
width: 10px;
height: 10px;
border-radius: 50%;
box-shadow: 0 0 6px currentColor;
}
.progress-ideal-indicator.perfect {
background: #06b6d4;
box-shadow: 0 0 8px #06b6d4;
}
.progress-ideal-indicator.good {
background: #10b981;
box-shadow: 0 0 8px #10b981;
}
.progress-ideal-indicator.warning {
background: #f59e0b;
box-shadow: 0 0 8px #f59e0b;
}
.progress-ideal-indicator.danger {
background: #ef4444;
box-shadow: 0 0 8px #ef4444;
}
.progress-summary .usage-values {
display: flex;
gap: 16px;
font-size: 14px;
}
.progress-summary .usage-value {
display: flex;
flex-direction: column;
align-items: center;
}
.progress-summary .usage-value-label {
font-size: 10px;
color: var(--text-400, #a3a3a3);
text-transform: uppercase;
margin-bottom: 2px;
}
.progress-summary .usage-value-number {
font-size: 18px;
font-weight: 700;
}
.progress-summary .usage-value-number.used {
color: var(--text-100, #f5f5f5);
}
.progress-summary .usage-value-number.ideal {
color: var(--text-300, #a3a3a3);
}
.progress-summary .usage-value-number.under {
color: #10b981;
}
.progress-summary .usage-value-number.over {
color: #ef4444;
}
/* Estimated end date */
.estimated-end {
display: flex;
align-items: center;
gap: 8px;
margin-top: 12px;
padding: 10px 14px;
background: rgba(16, 185, 129, 0.1);
border: 1px solid rgba(16, 185, 129, 0.3);
border-radius: 8px;
font-size: 13px;
}
.estimated-end.warning {
background: rgba(239, 68, 68, 0.1);
border-color: rgba(239, 68, 68, 0.3);
}
.estimated-end-label {
color: var(--text-300, #a3a3a3);
}
.estimated-end-date {
font-weight: 600;
color: var(--text-100, #f5f5f5);
text-transform: capitalize;
}
.estimated-end-time {
color: var(--text-200, #d4d4d4);
font-weight: 500;
}
.estimated-end-hours {
color: #ef4444;
font-size: 12px;
font-weight: 500;
}
/* Session sliders */
.session-sliders {
display: flex;
flex-direction: column;
gap: 8px;
margin: 12px 0;
padding: 12px;
background: rgba(0, 0, 0, 0.2);
border-radius: 8px;
}
.session-slider-row {
display: flex;
align-items: center;
gap: 10px;
}
.session-slider-label {
font-size: 12px;
color: var(--text-300, #a3a3a3);
width: 70px;
flex-shrink: 0;
}
.session-slider-track {
flex: 1;
height: 8px;
background: rgba(255, 255, 255, 0.1);
border-radius: 4px;
position: relative;
overflow: visible;
}
.session-slider-fill {
height: 100%;
border-radius: 4px;
transition: width 0.3s ease;
}
.session-slider-fill.time {
background: linear-gradient(90deg, #3b82f6, #60a5fa);
}
.session-slider-fill.usage.good {
background: linear-gradient(90deg, #10b981, #34d399);
}
.session-slider-fill.usage.over {
background: linear-gradient(90deg, #f59e0b, #fbbf24);
}
.session-slider-marker {
position: absolute;
top: -3px;
width: 3px;
height: 14px;
background: white;
border-radius: 2px;
transform: translateX(-50%);
box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);
}
.session-slider-value {
font-size: 12px;
font-weight: 600;
color: var(--text-200, #d4d4d4);
width: 35px;
text-align: right;
flex-shrink: 0;
}
/* Boost 2× indicator */
.boost-indicator {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 14px;
border-radius: 8px;
margin-bottom: 12px;
font-size: 13px;
}
.boost-indicator.active {
background: linear-gradient(135deg, rgba(16, 185, 129, 0.15), rgba(6, 182, 212, 0.15));
border: 1px solid rgba(16, 185, 129, 0.4);
}
.boost-indicator.inactive {
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.1);
}
.boost-badge {
font-weight: 700;
font-size: 14px;
padding: 2px 8px;
border-radius: 4px;
}
.boost-indicator.active .boost-badge {
background: linear-gradient(135deg, #10b981, #06b6d4);
color: white;
animation: boost-pulse 2s ease-in-out infinite;
}
.boost-indicator.inactive .boost-badge {
background: rgba(255, 255, 255, 0.1);
color: var(--text-300, #a3a3a3);
}
@keyframes boost-pulse {
0%, 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.4); }
50% { box-shadow: 0 0 8px 2px rgba(16, 185, 129, 0.3); }
}
.boost-text {
font-weight: 600;
color: var(--text-100, #f5f5f5);
}
.boost-indicator.inactive .boost-text {
color: var(--text-300, #a3a3a3);
}
.boost-next {
margin-left: auto;
color: var(--text-300, #a3a3a3);
font-size: 12px;
}
/* ===========================================================================
Floating button (FAB) — visible en todas las páginas de claude.ai
=========================================================================== */
.claude-usage-tracker-fab {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 999998;
display: flex;
align-items: center;
gap: 8px;
padding: 10px 14px;
background: rgba(20, 20, 22, 0.92);
color: #f5f5f5;
border: 1px solid rgba(255, 255, 255, 0.12);
border-radius: 999px;
font-family: inherit;
font-size: 13px;
font-weight: 600;
cursor: pointer;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
transition: transform 0.15s ease, box-shadow 0.2s ease, opacity 0.2s ease;
}
.claude-usage-tracker-fab:hover {
transform: translateY(-1px);
box-shadow: 0 6px 22px rgba(0, 0, 0, 0.55);
border-color: rgba(255, 255, 255, 0.22);
}
.claude-usage-tracker-fab:active {
transform: translateY(0);
}
.claude-usage-tracker-fab--hidden {
display: none !important;
}
.claude-usage-tracker-fab-icon {
font-size: 16px;
line-height: 1;
}
.claude-usage-tracker-fab-text {
font-variant-numeric: tabular-nums;
letter-spacing: 0.01em;
}
/* ===========================================================================
Overlay propio — abierto al click del FAB
=========================================================================== */
.claude-usage-tracker-overlay {
position: fixed;
inset: 0;
z-index: 999999;
background: rgba(0, 0, 0, 0.55);
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
display: flex;
align-items: flex-start;
justify-content: center;
padding: 60px 16px 40px;
overflow-y: auto;
animation: claude-tracker-fade-in 0.15s ease;
}
@keyframes claude-tracker-fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
.claude-usage-tracker-overlay-panel {
width: 100%;
max-width: 720px;
background: #1a1a1d;
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 14px;
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.6);
padding: 16px 20px 20px;
color: #f5f5f5;
font-family: inherit;
}
.claude-usage-tracker-overlay-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 12px;
padding-bottom: 12px;
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
flex-wrap: wrap;
}
.claude-usage-tracker-overlay-age {
font-size: 12px;
color: var(--text-400, #a3a3a3);
font-style: italic;
}
.claude-usage-tracker-overlay-actions {
display: flex;
gap: 8px;
margin-left: auto;
align-items: center;
}
.claude-usage-tracker-overlay-refresh,
.claude-usage-tracker-overlay-close {
background: rgba(255, 255, 255, 0.06);
color: #f5f5f5;
border: 1px solid rgba(255, 255, 255, 0.12);
border-radius: 8px;
padding: 6px 12px;
font-size: 12px;
font-weight: 500;
cursor: pointer;
font-family: inherit;
transition: background 0.15s ease, border-color 0.15s ease;
}
.claude-usage-tracker-overlay-refresh:hover,
.claude-usage-tracker-overlay-close:hover {
background: rgba(255, 255, 255, 0.12);
border-color: rgba(255, 255, 255, 0.22);
}
.claude-usage-tracker-overlay-close {
padding: 6px 10px;
}
.claude-usage-tracker-overlay-spinner {
font-size: 12px;
color: #06b6d4;
font-style: italic;
margin-left: 8px;
animation: claude-tracker-spin-pulse 1.2s ease-in-out infinite;
}
.claude-usage-tracker-overlay-notice {
width: 100%;
margin-top: 8px;
padding: 6px 10px;
background: rgba(245, 158, 11, 0.12);
border: 1px solid rgba(245, 158, 11, 0.35);
border-radius: 6px;
font-size: 12px;
color: #f59e0b;
animation: claude-tracker-fade-in 0.2s ease;
}
@keyframes claude-tracker-spin-pulse {
0%, 100% { opacity: 0.6; }
50% { opacity: 1; }
}
.claude-usage-tracker-overlay-body {
min-height: 80px;
}
.claude-usage-tracker-overlay-empty {
padding: 40px 16px;
text-align: center;
color: var(--text-300, #a3a3a3);
font-size: 14px;
}
/* Cuando el tracker se inyecta dentro de nuestro overlay, ya está dentro de un
contenedor con padding/borde; quitamos su margen superior para que pegue. */
.claude-usage-tracker-overlay-body .claude-usage-tracker-container {
margin-top: 0;
}