diff --git a/packages/cli/src/services/insight/generators/DataProcessor.ts b/packages/cli/src/services/insight/generators/DataProcessor.ts index 162ed5a54..768d92fd1 100644 --- a/packages/cli/src/services/insight/generators/DataProcessor.ts +++ b/packages/cli/src/services/insight/generators/DataProcessor.ts @@ -6,6 +6,7 @@ import fs from 'fs/promises'; import path from 'path'; +import { read as readJsonlFile } from '@qwen-code/qwen-code-core'; import type { InsightData, HeatMapData, @@ -13,33 +14,7 @@ import type { AchievementData, StreakData, } from '../types/StaticInsightTypes.js'; - -// Define ChatRecord interface locally to avoid import issues -interface ChatRecord { - uuid: string; - parentUuid: string | null; - sessionId: string; - timestamp: string; - usageMetadata?: { - promptTokenCount?: number; - candidatesTokenCount?: number; - totalTokenCount?: number; - }; -} - -// Simple JSONL reader function -async function readJsonlFile(filePath: string): Promise { - try { - const content = await fs.readFile(filePath, 'utf-8'); - return content - .split('\n') - .filter((line) => line.trim()) - .map((line) => JSON.parse(line) as T); - } catch (error) { - console.error(`Error reading JSONL file ${filePath}:`, error); - return []; - } -} +import type { ChatRecord } from '@qwen-code/qwen-code-core'; export class DataProcessor { // Helper function to format date as YYYY-MM-DD diff --git a/packages/cli/src/services/insight/templates/styles/base.css b/packages/cli/src/services/insight/templates/styles/base.css index 563f3a72f..7a1a37219 100644 --- a/packages/cli/src/services/insight/templates/styles/base.css +++ b/packages/cli/src/services/insight/templates/styles/base.css @@ -1,290 +1,610 @@ /* Tailwind CSS Base Styles extracted from index-CV6J1oXz.css */ -*, :before, :after, ::backdrop { - --tw-border-spacing-x: 0; - --tw-border-spacing-y: 0; - --tw-translate-x: 0; - --tw-translate-y: 0; - --tw-rotate: 0; - --tw-skew-x: 0; - --tw-skew-y: 0; - --tw-scale-x: 1; - --tw-scale-y: 1; - --tw-pan-x: ; - --tw-pan-y: ; - --tw-pinch-zoom: ; - --tw-scroll-snap-strictness: proximity; - --tw-gradient-from-position: ; - --tw-gradient-via-position: ; - --tw-gradient-to-position: ; - --tw-ordinal: ; - --tw-slashed-zero: ; - --tw-numeric-figure: ; - --tw-numeric-spacing: ; - --tw-numeric-fraction: ; - --tw-ring-inset: ; - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: #3b82f680; - --tw-ring-offset-shadow: 0 0 #0000; - --tw-ring-shadow: 0 0 #0000; - --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; - --tw-blur: ; - --tw-brightness: ; - --tw-contrast: ; - --tw-grayscale: ; - --tw-hue-rotate: ; - --tw-invert: ; - --tw-saturate: ; - --tw-sepia: ; - --tw-drop-shadow: ; - --tw-backdrop-blur: ; - --tw-backdrop-brightness: ; - --tw-backdrop-contrast: ; - --tw-backdrop-grayscale: ; - --tw-backdrop-hue-rotate: ; - --tw-backdrop-invert: ; - --tw-backdrop-opacity: ; - --tw-backdrop-saturate: ; - --tw-backdrop-sepia: ; - --tw-contain-size: ; - --tw-contain-layout: ; - --tw-contain-paint: ; - --tw-contain-style: ; +*, +:before, +:after, +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: #3b82f680; + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; } -*, :before, :after { - box-sizing: border-box; - border: 0 solid #e5e7eb; +*, +:before, +:after { + box-sizing: border-box; + border: 0 solid #e5e7eb; } -:before, :after { - --tw-content: ""; +:before, +:after { + --tw-content: ""; } -html, :host { - -webkit-text-size-adjust: 100%; - tab-size: 4; - font-feature-settings: normal; - font-variation-settings: normal; - -webkit-tap-highlight-color: transparent; - font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - line-height: 1.5; +html, +:host { + -webkit-text-size-adjust: 100%; + tab-size: 4; + font-feature-settings: normal; + font-variation-settings: normal; + -webkit-tap-highlight-color: transparent; + font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + line-height: 1.5; } body { - line-height: inherit; - margin: 0; - background-image: linear-gradient(to bottom right, var(--tw-gradient-stops)); - --tw-gradient-from: #f8fafc var(--tw-gradient-from-position); - --tw-gradient-to: #f1f5f9 var(--tw-gradient-to-position); - --tw-gradient-stops: var(--tw-gradient-from), #fff var(--tw-gradient-via-position), var(--tw-gradient-to); - --tw-text-opacity: 1; - min-height: 100vh; - color: rgb(15 23 42 / var(--tw-text-opacity, 1)); - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + line-height: inherit; + margin: 0; + background-image: linear-gradient(to bottom right, var(--tw-gradient-stops)); + --tw-gradient-from: #f8fafc var(--tw-gradient-from-position); + --tw-gradient-to: #f1f5f9 var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), #fff var(--tw-gradient-via-position), var(--tw-gradient-to); + --tw-text-opacity: 1; + min-height: 100vh; + color: rgb(15 23 42 / var(--tw-text-opacity, 1)); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } /* Glass Card Effect */ .glass-card { - --tw-border-opacity: 1; - border-width: 1px; - border-color: rgb(226 232 240 / var(--tw-border-opacity, 1)); - --tw-shadow: 0 10px 40px #0f172a14; - --tw-shadow-colored: 0 10px 40px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); - --tw-backdrop-blur: blur(8px); - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); - background-color: #ffffff99; - border-radius: 1rem; + --tw-border-opacity: 1; + border-width: 1px; + border-color: rgb(226 232 240 / var(--tw-border-opacity, 1)); + --tw-shadow: 0 10px 40px #0f172a14; + --tw-shadow-colored: 0 10px 40px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + --tw-backdrop-blur: blur(8px); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + background-color: #ffffff99; + border-radius: 1rem; } /* Utility Classes */ -.col-span-2 { grid-column: span 2 / span 2; } -.mx-auto { margin-left: auto; margin-right: auto; } -.mb-8 { margin-bottom: 2rem; } -.ml-2 { margin-left: 0.5rem; } -.mt-1 { margin-top: 0.25rem; } -.mt-2 { margin-top: 0.5rem; } -.mt-4 { margin-top: 1rem; } -.mt-6 { margin-top: 1.5rem; } -.block { display: block; } -.flex { display: flex; } -.inline-flex { display: inline-flex; } -.grid { display: grid; } -.h-56 { height: 14rem; } -.h-full { height: 100%; } -.min-h-screen { min-height: 100vh; } -.w-full { width: 100%; } -.min-w-\[720px\] { min-width: 720px; } -.max-w-6xl { max-width: 72rem; } -.grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } -.grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } -.flex-col { flex-direction: column; } -.items-start { align-items: flex-start; } -.items-center { align-items: center; } -.justify-center { justify-content: center; } -.justify-between { justify-content: space-between; } -.gap-1 { gap: 0.25rem; } -.gap-2 { gap: 0.5rem; } -.gap-3 { gap: 0.75rem; } -.gap-4 { gap: 1rem; } - -.space-y-3 > :not([hidden]) ~ :not([hidden]) { - --tw-space-y-reverse: 0; - margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); +.col-span-2 { + grid-column: span 2 / span 2; } -.space-y-4 > :not([hidden]) ~ :not([hidden]) { - --tw-space-y-reverse: 0; - margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); - margin-bottom: calc(1rem * var(--tw-space-y-reverse)); +.mx-auto { + margin-left: auto; + margin-right: auto; } -.divide-y > :not([hidden]) ~ :not([hidden]) { - --tw-divide-y-reverse: 0; - border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse))); - border-bottom-width: calc(1px * var(--tw-divide-y-reverse)); +.mb-8 { + margin-bottom: 2rem; } -.divide-slate-200 > :not([hidden]) ~ :not([hidden]) { - --tw-divide-opacity: 1; - border-color: rgb(226 232 240 / var(--tw-divide-opacity, 1)); +.ml-2 { + margin-left: 0.5rem; } -.overflow-x-auto { overflow-x: auto; } -.rounded-full { border-radius: 9999px; } -.rounded-xl { border-radius: 1.25rem; } -.border { border-width: 1px; } -.border-slate-100 { --tw-border-opacity: 1; border-color: rgb(241 245 249 / var(--tw-border-opacity, 1)); } -.bg-emerald-50 { --tw-bg-opacity: 1; background-color: rgb(236 253 245 / var(--tw-bg-opacity, 1)); } -.bg-slate-100 { --tw-bg-opacity: 1; background-color: rgb(241 245 249 / var(--tw-bg-opacity, 1)); } -.bg-slate-50 { --tw-bg-opacity: 1; background-color: rgb(248 250 252 / var(--tw-bg-opacity, 1)); } -.bg-slate-900 { --tw-bg-opacity: 1; background-color: rgb(15 23 42 / var(--tw-bg-opacity, 1)); } -.bg-white\/70 { background-color: #ffffff73; } -.bg-gradient-to-br { background-image: linear-gradient(to bottom right, var(--tw-gradient-stops)); } -.from-slate-50 { --tw-gradient-from: #f8fafc var(--tw-gradient-from-position); --tw-gradient-to: #f8fafc00 var(--tw-gradient-to-position); --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); } -.via-white { --tw-gradient-to: #ffffff00 var(--tw-gradient-to-position); --tw-gradient-stops: var(--tw-gradient-from), #ffffff var(--tw-gradient-via-position), var(--tw-gradient-to); } -.to-slate-100 { --tw-gradient-to: #f1f5f9 var(--tw-gradient-to-position); } +.mt-1 { + margin-top: 0.25rem; +} -.p-4 { padding: 1rem; } -.p-6 { padding: 1.5rem; } -.px-3 { padding-left: 0.75rem; padding-right: 0.75rem; } -.px-4 { padding-left: 1rem; padding-right: 1rem; } -.px-5 { padding-left: 1.25rem; padding-right: 1.25rem; } -.px-6 { padding-left: 1.5rem; padding-right: 1.5rem; } -.px-8 { padding-left: 2rem; padding-right: 2rem; } -.py-1 { padding-top: 0.25rem; padding-bottom: 0.25rem; } -.py-10 { padding-top: 2.5rem; padding-bottom: 2.5rem; } -.py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; } -.py-3 { padding-top: 0.75rem; padding-bottom: 0.75rem; } -.py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem; } +.mt-2 { + margin-top: 0.5rem; +} -.text-left { text-align: left; } -.text-center { text-align: center; } -.text-2xl { font-size: 1.5rem; line-height: 2rem; } -.text-3xl { font-size: 1.875rem; line-height: 2.25rem; } -.text-4xl { font-size: 2.25rem; line-height: 2.5rem; } -.text-base { font-size: 1rem; line-height: 1.5rem; } -.text-lg { font-size: 1.125rem; line-height: 1.75rem; } -.text-sm { font-size: 0.875rem; line-height: 1.25rem; } -.text-xl { font-size: 1.25rem; line-height: 1.75rem; } -.text-xs { font-size: 0.75rem; line-height: 1rem; } +.mt-4 { + margin-top: 1rem; +} -.font-bold { font-weight: 700; } -.font-medium { font-weight: 500; } -.font-semibold { font-weight: 600; } -.uppercase { text-transform: uppercase; } -.tracking-\[0\.2em\] { letter-spacing: 0.2em; } -.tracking-tight { letter-spacing: -0.025em; } -.tracking-wide { letter-spacing: 0.025em; } +.mt-6 { + margin-top: 1.5rem; +} -.text-emerald-700 { --tw-text-opacity: 1; color: rgb(4 120 87 / var(--tw-text-opacity, 1)); } -.text-rose-700 { --tw-text-opacity: 1; color: rgb(190 18 60 / var(--tw-text-opacity, 1)); } -.text-slate-200 { --tw-text-opacity: 1; color: rgb(226 232 240 / var(--tw-text-opacity, 1)); } -.text-slate-400 { --tw-text-opacity: 1; color: rgb(148 163 184 / var(--tw-text-opacity, 1)); } -.text-slate-500 { --tw-text-opacity: 1; color: rgb(100 116 139 / var(--tw-text-opacity, 1)); } -.text-slate-600 { --tw-text-opacity: 1; color: rgb(71 85 105 / var(--tw-text-opacity, 1)); } -.text-slate-700 { --tw-text-opacity: 1; color: rgb(51 65 85 / var(--tw-text-opacity, 1)); } -.text-slate-900 { --tw-text-opacity: 1; color: rgb(15 23 42 / var(--tw-text-opacity, 1)); } -.text-white { --tw-text-opacity: 1; color: rgb(255 255 255 / var(--tw-text-opacity, 1)); } +.block { + display: block; +} -.shadow-inner { --tw-shadow: inset 0 2px 4px 0 #0000000d; --tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } -.shadow-soft { --tw-shadow: 0 10px 40px #0f172a14; --tw-shadow-colored: 0 10px 40px var(--tw-shadow-color); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } -.shadow-slate-100 { --tw-shadow-color: #f1f5f9; --tw-shadow: var(--tw-shadow-colored); } +.flex { + display: flex; +} + +.inline-flex { + display: inline-flex; +} + +.grid { + display: grid; +} + +.h-56 { + height: 14rem; +} + +.h-full { + height: 100%; +} + +.min-h-screen { + min-height: 100vh; +} + +.w-full { + width: 100%; +} + +.min-w-\[720px\] { + min-width: 720px; +} + +.max-w-6xl { + max-width: 72rem; +} + +.grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +.flex-col { + flex-direction: column; +} + +.items-start { + align-items: flex-start; +} + +.items-center { + align-items: center; +} + +.justify-center { + justify-content: center; +} + +.justify-between { + justify-content: space-between; +} + +.gap-1 { + gap: 0.25rem; +} + +.gap-2 { + gap: 0.5rem; +} + +.gap-3 { + gap: 0.75rem; +} + +.gap-4 { + gap: 1rem; +} + +.space-y-3> :not([hidden])~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); +} + +.space-y-4> :not([hidden])~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1rem * var(--tw-space-y-reverse)); +} + +.divide-y> :not([hidden])~ :not([hidden]) { + --tw-divide-y-reverse: 0; + border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse))); + border-bottom-width: calc(1px * var(--tw-divide-y-reverse)); +} + +.divide-slate-200> :not([hidden])~ :not([hidden]) { + --tw-divide-opacity: 1; + border-color: rgb(226 232 240 / var(--tw-divide-opacity, 1)); +} + +.overflow-x-auto { + overflow-x: auto; +} + +.rounded-full { + border-radius: 9999px; +} + +.rounded-xl { + border-radius: 1.25rem; +} + +.border { + border-width: 1px; +} + +.border-slate-100 { + --tw-border-opacity: 1; + border-color: rgb(241 245 249 / var(--tw-border-opacity, 1)); +} + +.bg-emerald-50 { + --tw-bg-opacity: 1; + background-color: rgb(236 253 245 / var(--tw-bg-opacity, 1)); +} + +.bg-slate-100 { + --tw-bg-opacity: 1; + background-color: rgb(241 245 249 / var(--tw-bg-opacity, 1)); +} + +.bg-slate-50 { + --tw-bg-opacity: 1; + background-color: rgb(248 250 252 / var(--tw-bg-opacity, 1)); +} + +.bg-slate-900 { + --tw-bg-opacity: 1; + background-color: rgb(15 23 42 / var(--tw-bg-opacity, 1)); +} + +.bg-white\/70 { + background-color: #ffffff73; +} + +.bg-gradient-to-br { + background-image: linear-gradient(to bottom right, var(--tw-gradient-stops)); +} + +.from-slate-50 { + --tw-gradient-from: #f8fafc var(--tw-gradient-from-position); + --tw-gradient-to: #f8fafc00 var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} + +.via-white { + --tw-gradient-to: #ffffff00 var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), #ffffff var(--tw-gradient-via-position), var(--tw-gradient-to); +} + +.to-slate-100 { + --tw-gradient-to: #f1f5f9 var(--tw-gradient-to-position); +} + +.p-4 { + padding: 1rem; +} + +.p-6 { + padding: 1.5rem; +} + +.px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; +} + +.px-4 { + padding-left: 1rem; + padding-right: 1rem; +} + +.px-5 { + padding-left: 1.25rem; + padding-right: 1.25rem; +} + +.px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; +} + +.px-8 { + padding-left: 2rem; + padding-right: 2rem; +} + +.py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + +.py-10 { + padding-top: 2.5rem; + padding-bottom: 2.5rem; +} + +.py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.py-3 { + padding-top: 0.75rem; + padding-bottom: 0.75rem; +} + +.py-6 { + padding-top: 1.5rem; + padding-bottom: 1.5rem; +} + +.text-left { + text-align: left; +} + +.text-center { + text-align: center; +} + +.text-2xl { + font-size: 1.5rem; + line-height: 2rem; +} + +.text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; +} + +.text-4xl { + font-size: 2.25rem; + line-height: 2.5rem; +} + +.text-base { + font-size: 1rem; + line-height: 1.5rem; +} + +.text-lg { + font-size: 1.125rem; + line-height: 1.75rem; +} + +.text-sm { + font-size: 0.875rem; + line-height: 1.25rem; +} + +.text-xl { + font-size: 1.25rem; + line-height: 1.75rem; +} + +.text-xs { + font-size: 0.75rem; + line-height: 1rem; +} + +.font-bold { + font-weight: 700; +} + +.font-medium { + font-weight: 500; +} + +.font-semibold { + font-weight: 600; +} + +.uppercase { + text-transform: uppercase; +} + +.tracking-\[0\.2em\] { + letter-spacing: 0.2em; +} + +.tracking-tight { + letter-spacing: -0.025em; +} + +.tracking-wide { + letter-spacing: 0.025em; +} + +.text-emerald-700 { + --tw-text-opacity: 1; + color: rgb(4 120 87 / var(--tw-text-opacity, 1)); +} + +.text-rose-700 { + --tw-text-opacity: 1; + color: rgb(190 18 60 / var(--tw-text-opacity, 1)); +} + +.text-slate-200 { + --tw-text-opacity: 1; + color: rgb(226 232 240 / var(--tw-text-opacity, 1)); +} + +.text-slate-400 { + --tw-text-opacity: 1; + color: rgb(148 163 184 / var(--tw-text-opacity, 1)); +} + +.text-slate-500 { + --tw-text-opacity: 1; + color: rgb(100 116 139 / var(--tw-text-opacity, 1)); +} + +.text-slate-600 { + --tw-text-opacity: 1; + color: rgb(71 85 105 / var(--tw-text-opacity, 1)); +} + +.text-slate-700 { + --tw-text-opacity: 1; + color: rgb(51 65 85 / var(--tw-text-opacity, 1)); +} + +.text-slate-900 { + --tw-text-opacity: 1; + color: rgb(15 23 42 / var(--tw-text-opacity, 1)); +} + +.text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity, 1)); +} + +.shadow-inner { + --tw-shadow: inset 0 2px 4px 0 #0000000d; + --tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-soft { + --tw-shadow: 0 10px 40px #0f172a14; + --tw-shadow-colored: 0 10px 40px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-slate-100 { + --tw-shadow-color: #f1f5f9; + --tw-shadow: var(--tw-shadow-colored); +} .transition { - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-duration: 0.15s; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 0.15s; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); } .hover\:-translate-y-\[1px\]:hover { - --tw-translate-y: -1px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + --tw-translate-y: -1px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } .hover\:shadow-lg:hover { - --tw-shadow: 0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a; - --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + --tw-shadow: 0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a; + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } -.focus-visible\:outline:focus-visible { outline-style: solid; } -.focus-visible\:outline-2:focus-visible { outline-width: 2px; } -.focus-visible\:outline-offset-2:focus-visible { outline-offset: 2px; } -.focus-visible\:outline-slate-400:focus-visible { outline-color: #94a3b8; } +.focus-visible\:outline:focus-visible { + outline-style: solid; +} + +.focus-visible\:outline-2:focus-visible { + outline-width: 2px; +} + +.focus-visible\:outline-offset-2:focus-visible { + outline-offset: 2px; +} + +.focus-visible\:outline-slate-400:focus-visible { + outline-color: #94a3b8; +} .active\:translate-y-\[1px\]:active { - --tw-translate-y: 1px; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + --tw-translate-y: 1px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } .group:hover .group-hover\:translate-x-0\.5 { - --tw-translate-x: 0.125rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + --tw-translate-x: 0.125rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } @media (min-width: 768px) { - .md\:mt-6 { margin-top: 1.5rem; } - .md\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } - .md\:gap-6 { gap: 1.5rem; } - .md\:py-12 { padding-top: 3rem; padding-bottom: 3rem; } - .md\:text-4xl { font-size: 2.25rem; line-height: 2.5rem; } + .md\:mt-6 { + margin-top: 1.5rem; + } + + .md\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .md\:gap-6 { + gap: 1.5rem; + } + + .md\:py-12 { + padding-top: 3rem; + padding-bottom: 3rem; + } + + .md\:text-4xl { + font-size: 2.25rem; + line-height: 2.5rem; + } } /* Heat map specific styles */ .heatmap-container { - width: 100%; - overflow-x: auto; + width: 100%; + overflow-x: auto; } .heatmap-svg { - min-width: 720px; + min-width: 720px; } .heatmap-day { - cursor: pointer; + cursor: pointer; } .heatmap-day:hover { - stroke: #00000024; - stroke-width: 1px; + stroke: #00000024; + stroke-width: 1px; } .heatmap-legend { - display: flex; - align-items: center; - gap: 4px; - font-size: 12px; - color: #64748b; - margin-top: 8px; + display: flex; + align-items: center; + gap: 4px; + font-size: 12px; + color: #64748b; + margin-top: 8px; } .heatmap-legend-item { - width: 10px; - height: 10px; - border-radius: 2px; + width: 10px; + height: 10px; + border-radius: 2px; } \ No newline at end of file